qdev/usb: add usb bus support to qdev, convert drivers.

* Add USBBus.
 * Add USBDeviceInfo, move device callbacks here.
 * Add usb-qdev helper functions.
 * Switch drivers to qdev.

TODO:
 * make the rest of qemu aware of usb busses and kill the FIXMEs
   added by this patch.

Signed-off-by: Gerd Hoffmann <[email protected]>
Signed-off-by: Anthony Liguori <[email protected]>
diff --git a/usb-linux.c b/usb-linux.c
index 036b39b..7f6ca90 100644
--- a/usb-linux.c
+++ b/usb-linux.c
@@ -751,7 +751,7 @@
         s->remote_wakeup = 0;
         s->addr = 0;
         s->state = USB_STATE_DEFAULT;
-        s->handle_reset(s);
+        s->info->handle_reset(s);
         return 0;
     }
 
@@ -881,18 +881,19 @@
     return 0;
 }
 
+static int usb_host_initfn(USBDevice *dev)
+{
+    return 0;
+}
+
 static USBDevice *usb_host_device_open_addr(int bus_num, int addr, const char *prod_name)
 {
     int fd = -1, ret;
-    USBHostDevice *dev = NULL;
+    USBDevice *d = NULL;
+    USBHostDevice *dev;
     struct usbdevfs_connectinfo ci;
     char buf[1024];
 
-    dev = qemu_mallocz(sizeof(USBHostDevice));
-
-    dev->bus_num = bus_num;
-    dev->addr = addr;
-
     printf("husb: open device %d.%d\n", bus_num, addr);
 
     if (!usb_host_device_path) {
@@ -908,6 +909,12 @@
     }
     dprintf("husb: opened %s\n", buf);
 
+    d = usb_create_simple(NULL /* FIXME */, "USB Host Device");
+    dev = DO_UPCAST(USBHostDevice, dev, d);
+
+    dev->bus_num = bus_num;
+    dev->addr = addr;
+
     /* read the device description */
     dev->descr_len = read(fd, dev->descr, sizeof(dev->descr));
     if (dev->descr_len <= 0) {
@@ -925,7 +932,6 @@
     }
 #endif
 
-    dev->fd = fd;
 
     /* 
      * Initial configuration is -1 which makes us claim first 
@@ -953,10 +959,6 @@
     else
         dev->dev.speed = USB_SPEED_HIGH;
 
-    dev->dev.handle_packet  = usb_host_handle_packet;
-    dev->dev.handle_reset   = usb_host_handle_reset;
-    dev->dev.handle_destroy = usb_host_handle_destroy;
-
     if (!prod_name || prod_name[0] == '\0')
         snprintf(dev->dev.devname, sizeof(dev->dev.devname),
                  "host:%d.%d", bus_num, addr);
@@ -972,13 +974,32 @@
     return (USBDevice *) dev;
 
 fail:
-    if (dev)
-        qemu_free(dev);
-
-    close(fd);
+    if (d)
+        qdev_free(&d->qdev);
+    if (fd != -1)
+        close(fd);
     return NULL;
 }
 
+static struct USBDeviceInfo usb_host_dev_info = {
+    .qdev.name      = "USB Host Device",
+    .qdev.size      = sizeof(USBHostDevice),
+    .init           = usb_host_initfn,
+    .handle_packet  = usb_host_handle_packet,
+    .handle_reset   = usb_host_handle_reset,
+#if 0
+    .handle_control = usb_host_handle_control,
+    .handle_data    = usb_host_handle_data,
+#endif
+    .handle_destroy = usb_host_handle_destroy,
+};
+
+static void usb_host_register_devices(void)
+{
+    usb_qdev_register(&usb_host_dev_info);
+}
+device_init(usb_host_register_devices)
+
 static int usb_host_auto_add(const char *spec);
 static int usb_host_auto_del(const char *spec);