From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1MF34Z-0007rr-5t for qemu-devel@nongnu.org; Fri, 12 Jun 2009 05:29:19 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1MF34U-0007qG-Jw for qemu-devel@nongnu.org; Fri, 12 Jun 2009 05:29:18 -0400 Received: from [199.232.76.173] (port=38062 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1MF34U-0007q9-Bx for qemu-devel@nongnu.org; Fri, 12 Jun 2009 05:29:14 -0400 Received: from mx2.redhat.com ([66.187.237.31]:60577) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1MF34T-0002Xq-ON for qemu-devel@nongnu.org; Fri, 12 Jun 2009 05:29:14 -0400 Received: from int-mx2.corp.redhat.com (int-mx2.corp.redhat.com [172.16.27.26]) by mx2.redhat.com (8.13.8/8.13.8) with ESMTP id n5C9TDXx024906 for ; Fri, 12 Jun 2009 05:29:13 -0400 From: Gerd Hoffmann Date: Fri, 12 Jun 2009 11:28:40 +0200 Message-Id: <1244798921-23262-4-git-send-email-kraxel@redhat.com> In-Reply-To: <1244798921-23262-1-git-send-email-kraxel@redhat.com> References: <1244798921-23262-1-git-send-email-kraxel@redhat.com> Subject: [Qemu-devel] [PATCH 3/4] qdev: very first cut of scsi bus support. List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Gerd Hoffmann Signed-off-by: Gerd Hoffmann --- 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