aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGerd Hoffmann <kraxel@redhat.com>2009-10-26 15:56:45 +0100
committerAnthony Liguori <aliguori@us.ibm.com>2009-10-30 08:39:30 -0500
commit0958b4cc8f7889b61770690fa29a1201895cf581 (patch)
tree377a8fb798d1607f0c90d852b31465fd4db1f13e
parent51edd4e6b5a5dfbe168f21ff7cdc5d63e16c160b (diff)
usb core: use qdev for -usbdevice
This patchs adds infrastructure to handle -usbdevice via qdev callbacks. USBDeviceInfo gets a name field (for the -usbdevice driver name) and a callback for -usbdevice parameter parsing. The new usbdevice_create() function walks the qdev driver list and looks for a usb driver with a matching name. When a parameter parsing callback is present it is called, otherwise the device is created via usb_create_simple(). Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
-rw-r--r--hw/qdev.c2
-rw-r--r--hw/qdev.h1
-rw-r--r--hw/usb-bus.c47
-rw-r--r--hw/usb.h5
-rw-r--r--vl.c5
5 files changed, 59 insertions, 1 deletions
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)