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

* Add SCSIBus.
 * Add SCSIDeviceInfo, move device callbacks here.
 * add qdev/scsi helper functions.
 * convert drivers.

Adding scsi disks via -device works now, i.e. you can do:

 -drive id=sda,if=none,...
 -device lsi
 -device scsi-disk,drive=sda

legacy command lines (-drive if=scsi,...) continue to work.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
diff --git a/hw/usb-msd.c b/hw/usb-msd.c
index bc5150f..222689a 100644
--- a/hw/usb-msd.c
+++ b/hw/usb-msd.c
@@ -44,6 +44,7 @@
     uint32_t residue;
     uint32_t tag;
     BlockDriverState *bs;
+    SCSIBus *bus;
     SCSIDevice *scsi_dev;
     int result;
     /* For async completion.  */
@@ -150,9 +151,9 @@
     s->data_len -= len;
     if (s->scsi_len == 0) {
         if (s->mode == USB_MSDM_DATAIN) {
-            s->scsi_dev->read_data(s->scsi_dev, s->tag);
+            s->scsi_dev->info->read_data(s->scsi_dev, s->tag);
         } else if (s->mode == USB_MSDM_DATAOUT) {
-            s->scsi_dev->write_data(s->scsi_dev, s->tag);
+            s->scsi_dev->info->write_data(s->scsi_dev, s->tag);
         }
     }
 }
@@ -168,10 +169,10 @@
     memcpy(s->usb_buf, &csw, 13);
 }
 
-static void usb_msd_command_complete(void *opaque, int reason, uint32_t tag,
+static void usb_msd_command_complete(SCSIBus *bus, int reason, uint32_t tag,
                                      uint32_t arg)
 {
-    MSDState *s = (MSDState *)opaque;
+    MSDState *s = DO_UPCAST(MSDState, dev.qdev, bus->qbus.parent);
     USBPacket *p = s->packet;
 
     if (tag != s->tag) {
@@ -205,7 +206,7 @@
         return;
     }
     s->scsi_len = arg;
-    s->scsi_buf = s->scsi_dev->get_buf(s->scsi_dev, tag);
+    s->scsi_buf = s->scsi_dev->info->get_buf(s->scsi_dev, tag);
     if (p) {
         usb_msd_copy_data(s);
         if (s->usb_len == 0) {
@@ -343,7 +344,7 @@
 static void usb_msd_cancel_io(USBPacket *p, void *opaque)
 {
     MSDState *s = opaque;
-    s->scsi_dev->cancel_io(s->scsi_dev, s->tag);
+    s->scsi_dev->info->cancel_io(s->scsi_dev, s->tag);
     s->packet = NULL;
     s->scsi_len = 0;
 }
@@ -391,14 +392,14 @@
             DPRINTF("Command tag 0x%x flags %08x len %d data %d\n",
                     s->tag, cbw.flags, cbw.cmd_len, s->data_len);
             s->residue = 0;
-            s->scsi_dev->send_command(s->scsi_dev, s->tag, cbw.cmd, 0);
+            s->scsi_dev->info->send_command(s->scsi_dev, s->tag, cbw.cmd, 0);
             /* ??? Should check that USB and SCSI data transfer
                directions match.  */
             if (s->residue == 0) {
                 if (s->mode == USB_MSDM_DATAIN) {
-                    s->scsi_dev->read_data(s->scsi_dev, s->tag);
+                    s->scsi_dev->info->read_data(s->scsi_dev, s->tag);
                 } else if (s->mode == USB_MSDM_DATAOUT) {
-                    s->scsi_dev->write_data(s->scsi_dev, s->tag);
+                    s->scsi_dev->info->write_data(s->scsi_dev, s->tag);
                 }
             }
             ret = len;
@@ -509,7 +510,7 @@
 {
     MSDState *s = (MSDState *)dev;
 
-    s->scsi_dev->destroy(s->scsi_dev);
+    s->scsi_dev->info->destroy(s->scsi_dev);
     bdrv_delete(s->bs);
     qemu_free(s);
 }
@@ -567,7 +568,10 @@
     snprintf(s->dev.devname, sizeof(s->dev.devname), "QEMU USB MSD(%.16s)",
              filename);
 
-    s->scsi_dev = scsi_disk_init(bdrv, 0, usb_msd_command_complete, s);
+    s->bus = scsi_bus_new(&s->dev.qdev, 0, 1, usb_msd_command_complete);
+#if 0
+    s->scsi_dev = scsi_disk_init(s->bus, bdrv);
+#endif
     usb_msd_handle_reset((USBDevice *)s);
     return (USBDevice *)s;
 }