QEMU Device (qdev) API Reference

The QEMU Device API

All modern devices should represented as a derived QOM class of TYPE_DEVICE. The device API introduces the additional methods of realize and unrealize to represent additional stages in a device objects life cycle.

Realization

Devices are constructed in two stages:

  1. object instantiation via object_initialize() and

  2. device realization via the DeviceState.realized property

The former may not fail (and must not abort or exit, since it is called during device introspection already), and the latter may return error information to the caller and must be re-entrant. Trivial field initializations should go into TypeInfo.instance_init. Operations depending on props static properties should go into realize. After successful realization, setting static properties will fail.

As an interim step, the DeviceState.realized property can also be set with qdev_realize(). In the future, devices will propagate this state change to their children and along busses they expose. The point in time will be deferred to machine creation, so that values set in realize will not be introspectable beforehand. Therefore devices must not create children during realize; they should initialize them via object_initialize() in their own TypeInfo.instance_init and forward the realization events appropriately.

Any type may override the realize and/or unrealize callbacks but needs to call the parent type’s implementation if keeping their functionality is desired. Refer to QOM documentation for further discussion and examples.

Note

Since TYPE_DEVICE doesn’t implement realize and unrealize, types derived directly from it need not call their parent’s realize and unrealize. For other types consult the documentation and implementation of the respective parent types.

Hiding a device

To hide a device, a DeviceListener function hide_device() needs to be registered. It can be used to defer adding a device and therefore hide it from the guest. The handler registering to this DeviceListener can save the QOpts passed to it for re-using it later. It must return if it wants the device to be hidden or visible. When the handler function decides the device shall be visible it will be added with qdev_device_add() and realized as any other device. Otherwise qdev_device_add() will return early without adding the device. The guest will not see a “hidden” device until it was marked visible and qdev_device_add called again.

struct DeviceClass

Definition:

struct DeviceClass {
    unsigned long categories[BITS_TO_LONGS(DEVICE_CATEGORY_MAX)];
    const char *fw_name;
    const char *desc;
    Property *props_;
    bool user_creatable;
    bool hotpluggable;
    DeviceReset reset;
    DeviceRealize realize;
    DeviceUnrealize unrealize;
    const VMStateDescription *vmsd;
    const char *bus_type;
};

Members

struct DeviceState

Definition:

struct DeviceState {
    char *id;
    char *canonical_path;
    bool realized;
    bool pending_deleted_event;
    int64_t pending_deleted_expires_ms;
    QDict *opts;
    int hotplugged;
    bool allow_unplug_during_migration;
    BusState *parent_bus;
    NamedGPIOListHead gpios;
    NamedClockListHead clocks;
    BusStateHead child_bus;
    int num_child_bus;
    int instance_id_alias;
    int alias_required_for_version;
    ResettableState reset;
    GSList *unplug_blockers;
    MemReentrancyGuard mem_reentrancy_guard;
};

Members

Description

This structure should not be accessed directly. We declare it here so that it can be embedded in individual device state structures.

struct BusState

Definition:

struct BusState {
    DeviceState *parent;
    char *name;
    HotplugHandler *hotplug_handler;
    int max_index;
    bool realized;
    bool full;
    int num_children;
    BusChildHead children;
    BusStateEntry sibling;
    ResettableState reset;
};

Members

type GlobalProperty

Description

An error is fatal for non-hotplugged devices, when the global is applied.

DeviceState *qdev_new(const char *name)

Parameters

const char *name

DeviceState *qdev_try_new(const char *name)

Parameters

const char *name

bool qdev_is_realized(DeviceState *dev)

Parameters

DeviceState *dev

bool qdev_realize(DeviceState *dev, BusState *bus, Error **errp)

Parameters

DeviceState *dev

bool qdev_realize_and_unref(DeviceState *dev, BusState *bus, Error **errp)

Parameters

DeviceState *dev

void qdev_unrealize(DeviceState *dev)

Parameters

DeviceState *dev

HotplugHandler *qdev_get_hotplug_handler(DeviceState *dev)

Parameters

DeviceState *dev

void qdev_add_unplug_blocker(DeviceState *dev, Error *reason)

Parameters

DeviceState *dev

void qdev_del_unplug_blocker(DeviceState *dev, Error *reason)

Parameters

DeviceState *dev

bool qdev_unplug_blocked(DeviceState *dev, Error **errp)

Parameters

DeviceState *dev

type GpioPolarity

Description

GPIO lines use either positive (active-high) logic, or negative (active-low) logic.

In active-high logic (GPIO_POLARITY_ACTIVE_HIGH), a pin is active when the voltage on the pin is high (relative to ground); whereas in active-low logic (GPIO_POLARITY_ACTIVE_LOW), a pin is active when the voltage on the pin is low (or grounded).

qemu_irq qdev_get_gpio_in(DeviceState *dev, int n)

Parameters

DeviceState *dev

qemu_irq qdev_get_gpio_in_named(DeviceState *dev, const char *name, int n)

Parameters

DeviceState *dev

void qdev_connect_gpio_out(DeviceState *dev, int n, qemu_irq pin)

Parameters

DeviceState *dev

void qdev_connect_gpio_out_named(DeviceState *dev, const char *name, int n, qemu_irq input_pin)

Parameters

DeviceState *dev

qemu_irq qdev_get_gpio_out_connector(DeviceState *dev, const char *name, int n)

Parameters

DeviceState *dev

qemu_irq qdev_intercept_gpio_out(DeviceState *dev, qemu_irq icpt, const char *name, int n)

Parameters

DeviceState *dev

void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n)

Parameters

DeviceState *dev

void qdev_init_gpio_out(DeviceState *dev, qemu_irq *pins, int n)

Parameters

DeviceState *dev

void qdev_init_gpio_out_named(DeviceState *dev, qemu_irq *pins, const char *name, int n)

Parameters

DeviceState *dev

void qdev_init_gpio_in_named_with_opaque(DeviceState *dev, qemu_irq_handler handler, void *opaque, const char *name, int n)

Parameters

DeviceState *dev

void qdev_init_gpio_in_named(DeviceState *dev, qemu_irq_handler handler, const char *name, int n)

Parameters

DeviceState *dev

void qdev_pass_gpios(DeviceState *dev, DeviceState *container, const char *name)

Parameters

DeviceState *dev

void device_cold_reset(DeviceState *dev)

Parameters

DeviceState *dev

void bus_cold_reset(BusState *bus)

Parameters

BusState *bus

bool device_is_in_reset(DeviceState *dev)

Parameters

DeviceState *dev

bool bus_is_in_reset(BusState *bus)

Parameters

BusState *bus

void device_class_set_props(DeviceClass *dc, Property *props)

Parameters

DeviceClass *dc

void device_class_set_parent_reset(DeviceClass *dc, DeviceReset dev_reset, DeviceReset *parent_reset)

Parameters

DeviceClass *dc

void device_class_set_parent_realize(DeviceClass *dc, DeviceRealize dev_realize, DeviceRealize *parent_realize)

Parameters

DeviceClass *dc

void device_class_set_parent_unrealize(DeviceClass *dc, DeviceUnrealize dev_unrealize, DeviceUnrealize *parent_unrealize)

Parameters

DeviceClass *dc

char *qdev_get_human_name(DeviceState *dev)

Parameters

DeviceState *dev

void qbus_mark_full(BusState *bus)

Parameters

BusState *bus

bool qdev_should_hide_device(const QDict *opts, bool from_json, Error **errp)

Parameters

const QDict *opts