xemu/hw/scsi-bus.c
Gerd Hoffmann d52affa7f6 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>
2009-09-09 14:57:19 -05:00

94 lines
2.4 KiB
C

#include "hw.h"
#include "sysemu.h"
#include "scsi-disk.h"
#include "block.h"
#include "qdev.h"
static struct BusInfo scsi_bus_info = {
.name = "SCSI",
.size = sizeof(SCSIBus),
.props = (Property[]) {
DEFINE_PROP_UINT32("scsi-id", SCSIDevice, id, -1),
DEFINE_PROP_END_OF_LIST(),
},
};
static int next_scsi_bus;
/* Create a scsi bus, and attach devices to it. */
SCSIBus *scsi_bus_new(DeviceState *host, int tcq, int ndev,
scsi_completionfn complete)
{
SCSIBus *bus;
bus = FROM_QBUS(SCSIBus, qbus_create(&scsi_bus_info, host, NULL));
bus->busnr = next_scsi_bus++;
bus->tcq = tcq;
bus->ndev = ndev;
bus->complete = complete;
return bus;
}
static int scsi_qdev_init(DeviceState *qdev, DeviceInfo *base)
{
SCSIDevice *dev = DO_UPCAST(SCSIDevice, qdev, qdev);
SCSIDeviceInfo *info = DO_UPCAST(SCSIDeviceInfo, qdev, base);
SCSIBus *bus = DO_UPCAST(SCSIBus, qbus, dev->qdev.parent_bus);
if (dev->id == -1) {
for (dev->id = 0; dev->id < bus->ndev; dev->id++) {
if (bus->devs[dev->id] == NULL)
break;
}
}
if (dev->id >= bus->ndev) {
qemu_error("bad scsi device id: %d\n", dev->id);
goto err;
}
if (bus->devs[dev->id]) {
bus->devs[dev->id]->info->destroy(bus->devs[dev->id]);
}
bus->devs[dev->id] = dev;
dev->info = info;
return dev->info->init(dev);
err:
return -1;
}
void scsi_qdev_register(SCSIDeviceInfo *info)
{
info->qdev.bus_info = &scsi_bus_info;
info->qdev.init = scsi_qdev_init;
qdev_register(&info->qdev);
}
/* handle legacy '-drive if=scsi,...' cmd line args */
SCSIDevice *scsi_bus_legacy_add_drive(SCSIBus *bus, DriveInfo *dinfo, int unit)
{
const char *driver;
DeviceState *dev;
driver = bdrv_is_sg(dinfo->bdrv) ? "scsi-generic" : "scsi-disk";
dev = qdev_create(&bus->qbus, driver);
qdev_prop_set_uint32(dev, "scsi-id", unit);
qdev_prop_set_drive(dev, "drive", dinfo);
qdev_init(dev);
return DO_UPCAST(SCSIDevice, qdev, dev);
}
void scsi_bus_legacy_handle_cmdline(SCSIBus *bus)
{
DriveInfo *dinfo;
int unit;
for (unit = 0; unit < MAX_SCSI_DEVS; unit++) {
dinfo = drive_get(IF_SCSI, bus->busnr, unit);
if (dinfo == NULL) {
continue;
}
scsi_bus_legacy_add_drive(bus, dinfo, unit);
}
}