qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH] qdev: very first cut of scsi bus support.
@ 2009-06-10 13:59 Gerd Hoffmann
  2009-06-11 12:08 ` Paul Brook
  0 siblings, 1 reply; 3+ messages in thread
From: Gerd Hoffmann @ 2009-06-10 13:59 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann


Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 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 27d6703..bfd751e 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 f5b399c..5c76142 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -296,25 +296,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 fc93ee5..ff58503 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

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [Qemu-devel] [PATCH] qdev: very first cut of scsi bus support.
  2009-06-10 13:59 [Qemu-devel] [PATCH] qdev: very first cut of scsi bus support Gerd Hoffmann
@ 2009-06-11 12:08 ` Paul Brook
  2009-06-11 14:39   ` Gerd Hoffmann
  0 siblings, 1 reply; 3+ messages in thread
From: Paul Brook @ 2009-06-11 12:08 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

>Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>

I think you need to figure out how this interacts with scsi devices that are 
not attached to a parallel scsi interface (e.g. usb mass storage).

The current qemu scsi api exposes individual devices. The actual bus emulation 
is contained within the host adapter. My guess is that you may need an 
additional layer to separate the parallel scsi bus from actual scsi devices.

Paul

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [Qemu-devel] [PATCH] qdev: very first cut of scsi bus support.
  2009-06-11 12:08 ` Paul Brook
@ 2009-06-11 14:39   ` Gerd Hoffmann
  0 siblings, 0 replies; 3+ messages in thread
From: Gerd Hoffmann @ 2009-06-11 14:39 UTC (permalink / raw)
  To: Paul Brook; +Cc: qemu-devel

On 06/11/09 14:08, Paul Brook wrote:
>> Signed-off-by: Gerd Hoffmann<kraxel@redhat.com>
>
> I think you need to figure out how this interacts with scsi devices that are
> not attached to a parallel scsi interface (e.g. usb mass storage).

Yes, noticed that too.  Didn't investigate yet due to usb knowing 
nothing about qdev yet.

> The current qemu scsi api exposes individual devices. The actual bus emulation
> is contained within the host adapter. My guess is that you may need an
> additional layer to separate the parallel scsi bus from actual scsi devices.

And the guest <-> host (block) device linking needs a solution too.

cheers,
   Gerd

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2009-06-11 14:41 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-06-10 13:59 [Qemu-devel] [PATCH] qdev: very first cut of scsi bus support Gerd Hoffmann
2009-06-11 12:08 ` Paul Brook
2009-06-11 14:39   ` Gerd Hoffmann

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).