#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); } }