QEMU supports firmware names for all devices in the QEMU tree but some architectures expect some parts of firmware path names in different format.
This introduces a firmware-pathname-change interface definition. If some machines needs to redefine the firmware path format, it has to add a child object to the /machine object with the "machine-fw-path" interface defines. Signed-off-by: Alexey Kardashevskiy <a...@ozlabs.ru> --- Changes: v3: * QEMUMachine callback is replaced with an interface so the @current_machine symbol is no more required --- hw/core/qdev.c | 35 ++++++++++++++++++++++++++++++++++- include/hw/qdev-core.h | 15 +++++++++++++++ 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/hw/core/qdev.c b/hw/core/qdev.c index e374a93..4675d68 100644 --- a/hw/core/qdev.c +++ b/hw/core/qdev.c @@ -497,6 +497,36 @@ static char *bus_get_fw_dev_path(BusState *bus, DeviceState *dev) return NULL; } +typedef struct FWPathInterfaceSearch { + BusState *bus; + DeviceState *dev; + char *ret; +} FWPathInterfaceSearch; + +static int qdev_machine_try_get_fwpath(Object *o, void *opaque) +{ + FWPathInterfaceSearch *p = opaque; + ObjectClass *oc = object_get_class(o); + MachineFWPathClass *c = (MachineFWPathClass *) + object_class_dynamic_cast(oc, TYPE_MACHINE_FWPATH); + + if (c && c->get_fw_dev_path) { + p->ret = c->get_fw_dev_path(p->bus, p->dev); + return 1; + } + + return 0; +} + +static char *machine_get_fw_dev_path(BusState *bus, DeviceState *dev) +{ + FWPathInterfaceSearch p = { bus, dev, NULL }; + + object_child_foreach(qdev_get_machine(), qdev_machine_try_get_fwpath, &p); + + return p.ret; +} + static int qdev_get_fw_dev_path_helper(DeviceState *dev, char *p, int size) { int l = 0; @@ -504,7 +534,10 @@ static int qdev_get_fw_dev_path_helper(DeviceState *dev, char *p, int size) if (dev && dev->parent_bus) { char *d; l = qdev_get_fw_dev_path_helper(dev->parent_bus->parent, p, size); - d = bus_get_fw_dev_path(dev->parent_bus, dev); + d = machine_get_fw_dev_path(dev->parent_bus, dev); + if (!d) { + d = bus_get_fw_dev_path(dev->parent_bus, dev); + } if (d) { l += snprintf(p + l, size - l, "%s", d); g_free(d); diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h index f2043a6..49892fb 100644 --- a/include/hw/qdev-core.h +++ b/include/hw/qdev-core.h @@ -307,4 +307,19 @@ extern int qdev_hotplug; char *qdev_get_dev_path(DeviceState *dev); +/* + * Definition of a "get firmware patch" interface + */ +#define TYPE_MACHINE_FWPATH "machine-fw-path" + +#define MACHINE_FWPATH_CLASS(klass) \ + OBJECT_CLASS_CHECK(MachineFWPathClass, (klass), TYPE_MACHINE_FWPATH) + +typedef struct MachineFWPathClass { + /* private */ + InterfaceClass parent; + /* public */ + char *(*get_fw_dev_path)(BusState *bus, DeviceState *dev); +} MachineFWPathClass; + #endif -- 1.8.4.rc4