qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH 3/4] qdev: very first cut of scsi bus support.


From: Gerd Hoffmann
Subject: [Qemu-devel] [PATCH 3/4] qdev: very first cut of scsi bus support.
Date: Fri, 12 Jun 2009 11:28:40 +0200

Signed-off-by: Gerd Hoffmann <address@hidden>
---
 Makefile          |    2 +-
 hw/esp.c          |    8 ++++--
 hw/lsi53c895a.c   |    9 +++++--
 hw/qdev.c         |   19 ---------------
 hw/qdev.h         |    4 ---
 hw/scsi-bus.c     |   66 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 hw/scsi-disk.c    |   27 ++++++++++++++++++++-
 hw/scsi-disk.h    |   22 ++++++++++++++++-
 hw/scsi-generic.c |   24 +++++++++++++++++--
 hw/usb-msd.c      |    2 +-
 10 files changed, 145 insertions(+), 38 deletions(-)
 create mode 100644 hw/scsi-bus.c

diff --git a/Makefile b/Makefile
index 3177616..a1d8a76 100644
--- a/Makefile
+++ b/Makefile
@@ -98,7 +98,7 @@ OBJS+=i2c.o smbus.o smbus_eeprom.o max7310.o max111x.o 
wm8750.o
 OBJS+=ssd0303.o ssd0323.o ads7846.o stellaris_input.o twl92230.o
 OBJS+=tmp105.o lm832x.o eeprom93xx.o tsc2005.o
 OBJS+=scsi-disk.o cdrom.o
-OBJS+=scsi-generic.o
+OBJS+=scsi-generic.o scsi-bus.o
 OBJS+=usb.o usb-hub.o usb-$(HOST_USB).o usb-hid.o usb-msd.o usb-wacom.o
 OBJS+=usb-serial.o usb-net.o
 OBJS+=sd.o ssi-sd.o
diff --git a/hw/esp.c b/hw/esp.c
index ffb2225..cfb90a9 100644
--- a/hw/esp.c
+++ b/hw/esp.c
@@ -63,6 +63,7 @@ struct ESPState {
     uint8_t ti_buf[TI_BUFSZ];
     uint32_t sense;
     uint32_t dma;
+    SCSIBus *bus;
     SCSIDevice *scsi_dev[ESP_MAX_DEVS];
     SCSIDevice *current_dev;
     uint8_t cmdbuf[TI_BUFSZ];
@@ -640,9 +641,9 @@ static void esp_scsi_attach(DeviceState *host, 
BlockDriverState *bd, int id)
     }
     DPRINTF("Attaching block device %d\n", id);
     /* Command queueing is not implemented.  */
-    s->scsi_dev[id] = scsi_generic_init(bd, 0, esp_command_complete, s);
+    s->scsi_dev[id] = scsi_generic_init(s->bus, bd, 0, esp_command_complete, 
s);
     if (s->scsi_dev[id] == NULL)
-        s->scsi_dev[id] = scsi_disk_init(bd, 0, esp_command_complete, s);
+        s->scsi_dev[id] = scsi_disk_init(s->bus, bd, 0, esp_command_complete, 
s);
 }
 
 void esp_init(target_phys_addr_t espaddr, int it_shift,
@@ -686,7 +687,8 @@ static void esp_init1(SysBusDevice *dev)
 
     qdev_init_gpio_in(&dev->qdev, parent_esp_reset, 1);
 
-    scsi_bus_new(&dev->qdev, esp_scsi_attach);
+    s->bus = scsi_bus_new(&dev->qdev, esp_scsi_attach);
+    scsi_bus_attach_cmdline(s->bus);
 }
 
 static void esp_register_devices(void)
diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c
index 03cd763..c5d9275 100644
--- a/hw/lsi53c895a.c
+++ b/hw/lsi53c895a.c
@@ -12,6 +12,7 @@
 
 #include "hw.h"
 #include "pci.h"
+#include "scsi.h"
 #include "scsi-disk.h"
 #include "block_int.h"
 
@@ -190,6 +191,7 @@ typedef struct {
      * 2 if processing DMA from lsi_execute_script.
      * 3 if a DMA operation is in progress.  */
     int waiting;
+    SCSIBus *bus;
     SCSIDevice *scsi_dev[LSI_MAX_DEVS];
     SCSIDevice *current_dev;
     int current_lun;
@@ -1959,9 +1961,9 @@ void lsi_scsi_attach(DeviceState *host, BlockDriverState 
*bd, int id)
         s->scsi_dev[id]->destroy(s->scsi_dev[id]);
     }
     DPRINTF("Attaching block device %d\n", id);
-    s->scsi_dev[id] = scsi_generic_init(bd, 1, lsi_command_complete, s);
+    s->scsi_dev[id] = scsi_generic_init(s->bus, bd, 1, lsi_command_complete, 
s);
     if (s->scsi_dev[id] == NULL)
-        s->scsi_dev[id] = scsi_disk_init(bd, 1, lsi_command_complete, s);
+        s->scsi_dev[id] = scsi_disk_init(s->bus, bd, 1, lsi_command_complete, 
s);
     bd->private = &s->pci_dev;
 }
 
@@ -2016,7 +2018,8 @@ static void lsi_scsi_init(PCIDevice *dev)
 
     lsi_soft_reset(s);
 
-    scsi_bus_new(&dev->qdev, lsi_scsi_attach);
+    s->bus = scsi_bus_new(&dev->qdev, lsi_scsi_attach);
+    scsi_bus_attach_cmdline(s->bus);
 }
 
 static PCIDeviceInfo lsi_info = {
diff --git a/hw/qdev.c b/hw/qdev.c
index 93e417d..18f03ed 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -297,25 +297,6 @@ BusState *qdev_get_child_bus(DeviceState *dev, const char 
*name)
     return NULL;
 }
 
-static int next_scsi_bus;
-
-/* Create a scsi bus, and attach devices to it.  */
-/* TODO: Actually create a scsi bus for hotplug to use.  */
-void scsi_bus_new(DeviceState *host, SCSIAttachFn attach)
-{
-   int bus = next_scsi_bus++;
-   int unit;
-   int index;
-
-   for (unit = 0; unit < MAX_SCSI_DEVS; unit++) {
-       index = drive_get_index(IF_SCSI, bus, unit);
-       if (index == -1) {
-           continue;
-       }
-       attach(host, drives_table[index].bdrv, unit);
-   }
-}
-
 BusState *qbus_create(BusInfo *info, DeviceState *parent, const char *name)
 {
     BusState *bus;
diff --git a/hw/qdev.h b/hw/qdev.h
index 8b238d5..7f4236d 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -75,8 +75,6 @@ typedef struct {
 typedef struct DeviceInfo DeviceInfo;
 
 typedef void (*qdev_initfn)(DeviceState *dev, DeviceInfo *info);
-typedef void (*SCSIAttachFn)(DeviceState *host, BlockDriverState *bdrv,
-              int unit);
 
 struct DeviceInfo {
     const char *name;
@@ -95,8 +93,6 @@ void qdev_register(DeviceInfo *info);
 void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n);
 void qdev_init_gpio_out(DeviceState *dev, qemu_irq *pins, int n);
 
-void scsi_bus_new(DeviceState *host, SCSIAttachFn attach);
-
 CharDriverState *qdev_init_chardev(DeviceState *dev);
 
 BusState *qdev_get_parent_bus(DeviceState *dev);
diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
new file mode 100644
index 0000000..7743b22
--- /dev/null
+++ b/hw/scsi-bus.c
@@ -0,0 +1,66 @@
+#include "hw.h"
+#include "sysemu.h"
+#include "scsi-disk.h"
+#include "qdev.h"
+
+struct SCSIBus {
+    BusState qbus;
+    int busnr;
+    SCSIAttachFn attach;
+};
+
+static struct BusInfo scsi_bus_info = {
+    .name  = "SCSI",
+    .size  = sizeof(SCSIBus),
+};
+static int next_scsi_bus;
+
+/* Create a scsi bus, and attach devices to it.  */
+/* TODO: Actually create a scsi bus for hotplug to use.  */
+SCSIBus *scsi_bus_new(DeviceState *host, SCSIAttachFn attach)
+{
+    SCSIBus *bus;
+
+    bus = FROM_QBUS(SCSIBus, qbus_create(&scsi_bus_info, host, "scsi"));
+    bus->busnr = next_scsi_bus++;
+    bus->attach = attach;
+    return bus;
+}
+
+void scsi_bus_attach_cmdline(SCSIBus *bus)
+{
+    int unit;
+    int index;
+
+    for (unit = 0; unit < MAX_SCSI_DEVS; unit++) {
+        index = drive_get_index(IF_SCSI, bus->busnr, unit);
+        if (index == -1) {
+            continue;
+        }
+        bus->attach(bus->qbus.parent, drives_table[index].bdrv, unit);
+    }
+}
+
+static void scsi_qdev_init(DeviceState *qdev, DeviceInfo *base)
+{
+    SCSIDevice *dev = DO_UPCAST(SCSIDevice, qdev, qdev);
+    SCSIDeviceInfo *info = DO_UPCAST(SCSIDeviceInfo, qdev, base);
+
+    info->init(dev);
+}
+
+void scsi_qdev_register(SCSIDeviceInfo *info)
+{
+    info->qdev.bus_info = &scsi_bus_info;
+    info->qdev.init     = scsi_qdev_init;
+    qdev_register(&info->qdev);
+}
+
+SCSIDevice *scsi_create_simple(SCSIBus *bus, const char *name)
+{
+    DeviceState *dev;
+
+    dev = qdev_create(&bus->qbus, name);
+    qdev_init(dev);
+    return DO_UPCAST(SCSIDevice, qdev, dev);
+}
diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index a0485db..05e3db5 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -926,7 +926,7 @@ static void scsi_destroy(SCSIDevice *d)
     qemu_free(d);
 }
 
-SCSIDevice *scsi_disk_init(BlockDriverState *bdrv, int tcq,
+SCSIDevice *scsi_disk_init(SCSIBus *bus, BlockDriverState *bdrv, int tcq,
                            scsi_completionfn completion, void *opaque)
 {
     SCSIDevice *d;
@@ -953,7 +953,13 @@ SCSIDevice *scsi_disk_init(BlockDriverState *bdrv, int tcq,
     if (strlen(s->drive_serial_str) == 0)
         pstrcpy(s->drive_serial_str, sizeof(s->drive_serial_str), "0");
     qemu_add_vm_change_state_handler(scsi_dma_restart_cb, s);
-    d = (SCSIDevice *)qemu_mallocz(sizeof(SCSIDevice));
+
+    if (bus) {
+        d = scsi_create_simple(bus, "scsi-disk");
+    } else {
+        /* temporary until usb is qdev-ified */
+        d = (SCSIDevice *)qemu_mallocz(sizeof(SCSIDevice));
+    }
     d->state = s;
     d->destroy = scsi_destroy;
     d->send_command = scsi_send_command;
@@ -964,3 +970,20 @@ SCSIDevice *scsi_disk_init(BlockDriverState *bdrv, int tcq,
 
     return d;
 }
+
+static void scsi_disk_initfn(SCSIDevice *dev)
+{
+    /* TODO */
+}
+
+static SCSIDeviceInfo scsi_disk_info = {
+    .qdev.name = "scsi-disk",
+    .qdev.size = sizeof(SCSIDevice),
+    .init      = scsi_disk_initfn,
+};
+
+static void scsi_disk_register_devices(void)
+{
+    scsi_qdev_register(&scsi_disk_info);
+}
+device_init(scsi_disk_register_devices)
diff --git a/hw/scsi-disk.h b/hw/scsi-disk.h
index f42212b..666131f 100644
--- a/hw/scsi-disk.h
+++ b/hw/scsi-disk.h
@@ -1,12 +1,15 @@
 #ifndef SCSI_DISK_H
 #define SCSI_DISK_H
 
+#include "qdev.h"
+
 /* scsi-disk.c */
 enum scsi_reason {
     SCSI_REASON_DONE, /* Command complete.  */
     SCSI_REASON_DATA  /* Transfer complete, more data required.  */
 };
 
+typedef struct SCSIBus SCSIBus;
 typedef struct SCSIDeviceState SCSIDeviceState;
 typedef struct SCSIDevice SCSIDevice;
 typedef void (*scsi_completionfn)(void *opaque, int reason, uint32_t tag,
@@ -14,6 +17,7 @@ typedef void (*scsi_completionfn)(void *opaque, int reason, 
uint32_t tag,
 
 struct SCSIDevice
 {
+    DeviceState qdev;
     SCSIDeviceState *state;
     void (*destroy)(SCSIDevice *s);
     int32_t (*send_command)(SCSIDevice *s, uint32_t tag, uint8_t *buf,
@@ -24,13 +28,27 @@ struct SCSIDevice
     uint8_t *(*get_buf)(SCSIDevice *s, uint32_t tag);
 };
 
-SCSIDevice *scsi_disk_init(BlockDriverState *bdrv, int tcq,
+SCSIDevice *scsi_disk_init(SCSIBus *bus, BlockDriverState *bdrv, int tcq,
                            scsi_completionfn completion, void *opaque);
-SCSIDevice *scsi_generic_init(BlockDriverState *bdrv, int tcq,
+SCSIDevice *scsi_generic_init(SCSIBus *bus, BlockDriverState *bdrv, int tcq,
                            scsi_completionfn completion, void *opaque);
 
 /* cdrom.c */
 int cdrom_read_toc(int nb_sectors, uint8_t *buf, int msf, int start_track);
 int cdrom_read_toc_raw(int nb_sectors, uint8_t *buf, int msf, int session_num);
 
+/* scsi-bus.c */
+typedef void (*scsi_qdev_initfn)(SCSIDevice *dev);
+typedef struct {
+    DeviceInfo qdev;
+    scsi_qdev_initfn init;
+} SCSIDeviceInfo;
+
+typedef void (*SCSIAttachFn)(DeviceState *host, BlockDriverState *bdrv,
+              int unit);
+SCSIBus *scsi_bus_new(DeviceState *host, SCSIAttachFn attach);
+void scsi_bus_attach_cmdline(SCSIBus *bus);
+void scsi_qdev_register(SCSIDeviceInfo *info);
+SCSIDevice *scsi_create_simple(SCSIBus *bus, const char *name);
+
 #endif
diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c
index c827c04..022110f 100644
--- a/hw/scsi-generic.c
+++ b/hw/scsi-generic.c
@@ -17,7 +17,7 @@
 
 #ifndef __linux__
 
-SCSIDevice *scsi_generic_init(BlockDriverState *bdrv, int tcq,
+SCSIDevice *scsi_generic_init(SCSIBus *bus, BlockDriverState *bdrv, int tcq,
                               scsi_completionfn completion, void *opaque)
 {
     return NULL;
@@ -675,7 +675,7 @@ static void scsi_destroy(SCSIDevice *d)
     qemu_free(d);
 }
 
-SCSIDevice *scsi_generic_init(BlockDriverState *bdrv, int tcq,
+SCSIDevice *scsi_generic_init(SCSIBus *bus, BlockDriverState *bdrv, int tcq,
                               scsi_completionfn completion, void *opaque)
 {
     int sg_version;
@@ -730,7 +730,7 @@ SCSIDevice *scsi_generic_init(BlockDriverState *bdrv, int 
tcq,
 
     /* define function to manage device */
 
-    d = (SCSIDevice *)qemu_mallocz(sizeof(SCSIDevice));
+    d = scsi_create_simple(bus, "scsi-generic");
     d->state = s;
     d->destroy = scsi_destroy;
     d->send_command = scsi_send_command;
@@ -741,4 +741,22 @@ SCSIDevice *scsi_generic_init(BlockDriverState *bdrv, int 
tcq,
 
     return d;
 }
+
+static void scsi_generic_initfn(SCSIDevice *dev)
+{
+    /* TODO */
+}
+
+static SCSIDeviceInfo scsi_generic_info = {
+    .qdev.name = "scsi-generic",
+    .qdev.size = sizeof(SCSIDevice),
+    .init      = scsi_generic_initfn,
+};
+
+static void scsi_generic_register_devices(void)
+{
+    scsi_qdev_register(&scsi_generic_info);
+}
+device_init(scsi_generic_register_devices)
+
 #endif /* __linux__ */
diff --git a/hw/usb-msd.c b/hw/usb-msd.c
index 3a3eb4a..36872e3 100644
--- a/hw/usb-msd.c
+++ b/hw/usb-msd.c
@@ -566,7 +566,7 @@ USBDevice *usb_msd_init(const char *filename)
     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->scsi_dev = scsi_disk_init(NULL, bdrv, 0, usb_msd_command_complete, s);
     usb_msd_handle_reset((USBDevice *)s);
     return (USBDevice *)s;
  fail:
-- 
1.6.2.2





reply via email to

[Prev in Thread] Current Thread [Next in Thread]