diff --git a/hw/qdev.c b/hw/qdev.c index 373ddfcae5..c7884d0e82 100644 --- a/hw/qdev.c +++ b/hw/qdev.c @@ -35,7 +35,7 @@ static int qdev_hotplug = 0; /* This is a nasty hack to allow passing a NULL bus to qdev_create. */ static BusState *main_system_bus; -static DeviceInfo *device_info_list; +DeviceInfo *device_info_list; static BusState *qbus_find_recursive(BusState *bus, const char *name, const BusInfo *info); diff --git a/hw/qdev.h b/hw/qdev.h index 9c8f9e2ece..41642ee8a9 100644 --- a/hw/qdev.h +++ b/hw/qdev.h @@ -141,6 +141,7 @@ struct DeviceInfo { BusInfo *bus_info; struct DeviceInfo *next; }; +extern DeviceInfo *device_info_list; void qdev_register(DeviceInfo *info); diff --git a/hw/usb-bus.c b/hw/usb-bus.c index 98987a1973..28b517f5da 100644 --- a/hw/usb-bus.c +++ b/hw/usb-bus.c @@ -252,3 +252,50 @@ void usb_info(Monitor *mon) } } +/* handle legacy -usbdevice cmd line option */ +USBDevice *usbdevice_create(const char *cmdline) +{ + USBBus *bus = usb_bus_find(-1 /* any */); + DeviceInfo *info; + USBDeviceInfo *usb; + char driver[32], *params; + int len; + + params = strchr(cmdline,':'); + if (params) { + params++; + len = params - cmdline; + if (len > sizeof(driver)) + len = sizeof(driver); + pstrcpy(driver, len, cmdline); + } else { + pstrcpy(driver, sizeof(driver), cmdline); + } + + for (info = device_info_list; info != NULL; info = info->next) { + if (info->bus_info != &usb_bus_info) + continue; + usb = DO_UPCAST(USBDeviceInfo, qdev, info); + if (usb->usbdevice_name == NULL) + continue; + if (strcmp(usb->usbdevice_name, driver) != 0) + continue; + break; + } + if (info == NULL) { +#if 0 + /* no error because some drivers are not converted (yet) */ + qemu_error("usbdevice %s not found\n", driver); +#endif + return NULL; + } + + if (!usb->usbdevice_init) { + if (params) { + qemu_error("usbdevice %s accepts no params\n", driver); + return NULL; + } + return usb_create_simple(bus, usb->qdev.name); + } + return usb->usbdevice_init(params); +} diff --git a/hw/usb.h b/hw/usb.h index be4fcf6d1b..62362a7da1 100644 --- a/hw/usb.h +++ b/hw/usb.h @@ -183,6 +183,10 @@ struct USBDeviceInfo { * Returns length or one of the USB_RET_ codes. */ int (*handle_data)(USBDevice *dev, USBPacket *p); + + /* handle legacy -usbdevice command line options */ + const char *usbdevice_name; + USBDevice *(*usbdevice_init)(const char *params); }; typedef void (*usb_attachfn)(USBPort *port, USBDevice *dev); @@ -309,6 +313,7 @@ void usb_qdev_register(USBDeviceInfo *info); void usb_qdev_register_many(USBDeviceInfo *info); USBDevice *usb_create(USBBus *bus, const char *name); USBDevice *usb_create_simple(USBBus *bus, const char *name); +USBDevice *usbdevice_create(const char *cmdline); void usb_register_port(USBBus *bus, USBPort *port, void *opaque, int index, usb_attachfn attach); void usb_unregister_port(USBBus *bus, USBPort *port); diff --git a/vl.c b/vl.c index ac9ff5251d..a58bc06412 100644 --- a/vl.c +++ b/vl.c @@ -2556,6 +2556,11 @@ static int usb_device_add(const char *devname, int is_hotplug) if (!usb_enabled) return -1; + /* drivers with .usbdevice_name entry in USBDeviceInfo */ + dev = usbdevice_create(devname); + if (dev) + goto done; + /* simple devices which don't need extra care */ for (i = 0; i < ARRAY_SIZE(usbdevs); i++) { if (strcmp(devname, usbdevs[i].name) != 0)