[Top][All Lists]
[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