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:
object instantiation via object_initialize() and
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
Parameters
BusState *bus
-
bool device_is_in_reset(DeviceState *dev)
Parameters
DeviceState *dev
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
Parameters
BusState *bus
-
bool qdev_should_hide_device(const QDict *opts, bool from_json, Error **errp)
Parameters
const QDict *opts