diff options
author | Gerd Hoffmann <kraxel@redhat.com> | 2009-10-14 15:30:22 +0200 |
---|---|---|
committer | Anthony Liguori <aliguori@us.ibm.com> | 2009-10-27 12:28:42 -0500 |
commit | 30d335d68d93705eb346387c03bb6aca0f52454a (patch) | |
tree | a7e6b5212c847cd4e2c8e6fc1562ee16b8935a9f /hw/pci-hotplug.c | |
parent | 5b684b5a56e81f6f88234952fe8ed68010c36e19 (diff) |
hotplug: more fixes for scsi disk hotplug.
Changes:
- create common scsi_hot_add function for adding a scsi disk to
a adapter.
- Add sanity checks. You can't drive_add disks to the VGA any more.
- Ignore the unit value calculated by drive_init, add a comment
explaining why. Review the patch to find the details ;)
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Diffstat (limited to 'hw/pci-hotplug.c')
-rw-r--r-- | hw/pci-hotplug.c | 44 |
1 files changed, 34 insertions, 10 deletions
diff --git a/hw/pci-hotplug.c b/hw/pci-hotplug.c index 4eea60c8dd..8a125c90d8 100644 --- a/hw/pci-hotplug.c +++ b/hw/pci-hotplug.c @@ -61,6 +61,33 @@ static PCIDevice *qemu_pci_hot_add_nic(Monitor *mon, return pci_nic_init(&nd_table[ret], "rtl8139", devaddr); } +static int scsi_hot_add(DeviceState *adapter, DriveInfo *dinfo, int printinfo) +{ + SCSIBus *scsibus; + SCSIDevice *scsidev; + + scsibus = DO_UPCAST(SCSIBus, qbus, QLIST_FIRST(&adapter->child_bus)); + if (!scsibus || strcmp(scsibus->qbus.info->name, "SCSI") != 0) { + qemu_error("Device is not a SCSI adapter\n"); + return -1; + } + + /* + * drive_init() tries to find a default for dinfo->unit. Doesn't + * work at all for hotplug though as we assign the device to a + * specific bus instead of the first bus with spare scsi ids. + * + * Ditch the calculated value and reload from option string (if + * specified). + */ + dinfo->unit = qemu_opt_get_number(dinfo->opts, "unit", -1); + scsidev = scsi_bus_legacy_add_drive(scsibus, dinfo, dinfo->unit); + + if (printinfo) + qemu_error("OK bus %d, unit %d\n", scsibus->busnr, scsidev->id); + return 0; +} + void drive_hot_add(Monitor *mon, const QDict *qdict) { int dom, pci_bus; @@ -70,7 +97,6 @@ void drive_hot_add(Monitor *mon, const QDict *qdict) DriveInfo *dinfo = NULL; const char *pci_addr = qdict_get_str(qdict, "pci_addr"); const char *opts = qdict_get_str(qdict, "opts"); - BusState *scsibus; dinfo = add_init_drive(opts); if (!dinfo) @@ -92,12 +118,9 @@ void drive_hot_add(Monitor *mon, const QDict *qdict) monitor_printf(mon, "no pci device with address %s\n", pci_addr); goto err; } - scsibus = QLIST_FIRST(&dev->qdev.child_bus); - scsi_bus_legacy_add_drive(DO_UPCAST(SCSIBus, qbus, scsibus), - dinfo, dinfo->unit); - monitor_printf(mon, "OK bus %d, unit %d\n", - dinfo->bus, - dinfo->unit); + if (scsi_hot_add(&dev->qdev, dinfo, 1) != 0) { + goto err; + } break; case IF_NONE: monitor_printf(mon, "OK\n"); @@ -167,9 +190,10 @@ static PCIDevice *qemu_pci_hot_add_storage(Monitor *mon, if (qdev_init(&dev->qdev) < 0) dev = NULL; if (dev) { - BusState *scsibus = QLIST_FIRST(&dev->qdev.child_bus); - scsi_bus_legacy_add_drive(DO_UPCAST(SCSIBus, qbus, scsibus), - dinfo, dinfo->unit); + if (scsi_hot_add(&dev->qdev, dinfo, 0) != 0) { + qdev_unplug(&dev->qdev); + dev = NULL; + } } break; case IF_VIRTIO: |