Skip to content

Commit 30d335d

Browse files
kraxelAnthony Liguori
authored andcommitted
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 <[email protected]> Signed-off-by: Anthony Liguori <[email protected]>
1 parent 5b684b5 commit 30d335d

File tree

1 file changed

+34
-10
lines changed

1 file changed

+34
-10
lines changed

hw/pci-hotplug.c

Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,33 @@ static PCIDevice *qemu_pci_hot_add_nic(Monitor *mon,
6161
return pci_nic_init(&nd_table[ret], "rtl8139", devaddr);
6262
}
6363

64+
static int scsi_hot_add(DeviceState *adapter, DriveInfo *dinfo, int printinfo)
65+
{
66+
SCSIBus *scsibus;
67+
SCSIDevice *scsidev;
68+
69+
scsibus = DO_UPCAST(SCSIBus, qbus, QLIST_FIRST(&adapter->child_bus));
70+
if (!scsibus || strcmp(scsibus->qbus.info->name, "SCSI") != 0) {
71+
qemu_error("Device is not a SCSI adapter\n");
72+
return -1;
73+
}
74+
75+
/*
76+
* drive_init() tries to find a default for dinfo->unit. Doesn't
77+
* work at all for hotplug though as we assign the device to a
78+
* specific bus instead of the first bus with spare scsi ids.
79+
*
80+
* Ditch the calculated value and reload from option string (if
81+
* specified).
82+
*/
83+
dinfo->unit = qemu_opt_get_number(dinfo->opts, "unit", -1);
84+
scsidev = scsi_bus_legacy_add_drive(scsibus, dinfo, dinfo->unit);
85+
86+
if (printinfo)
87+
qemu_error("OK bus %d, unit %d\n", scsibus->busnr, scsidev->id);
88+
return 0;
89+
}
90+
6491
void drive_hot_add(Monitor *mon, const QDict *qdict)
6592
{
6693
int dom, pci_bus;
@@ -70,7 +97,6 @@ void drive_hot_add(Monitor *mon, const QDict *qdict)
7097
DriveInfo *dinfo = NULL;
7198
const char *pci_addr = qdict_get_str(qdict, "pci_addr");
7299
const char *opts = qdict_get_str(qdict, "opts");
73-
BusState *scsibus;
74100

75101
dinfo = add_init_drive(opts);
76102
if (!dinfo)
@@ -92,12 +118,9 @@ void drive_hot_add(Monitor *mon, const QDict *qdict)
92118
monitor_printf(mon, "no pci device with address %s\n", pci_addr);
93119
goto err;
94120
}
95-
scsibus = QLIST_FIRST(&dev->qdev.child_bus);
96-
scsi_bus_legacy_add_drive(DO_UPCAST(SCSIBus, qbus, scsibus),
97-
dinfo, dinfo->unit);
98-
monitor_printf(mon, "OK bus %d, unit %d\n",
99-
dinfo->bus,
100-
dinfo->unit);
121+
if (scsi_hot_add(&dev->qdev, dinfo, 1) != 0) {
122+
goto err;
123+
}
101124
break;
102125
case IF_NONE:
103126
monitor_printf(mon, "OK\n");
@@ -167,9 +190,10 @@ static PCIDevice *qemu_pci_hot_add_storage(Monitor *mon,
167190
if (qdev_init(&dev->qdev) < 0)
168191
dev = NULL;
169192
if (dev) {
170-
BusState *scsibus = QLIST_FIRST(&dev->qdev.child_bus);
171-
scsi_bus_legacy_add_drive(DO_UPCAST(SCSIBus, qbus, scsibus),
172-
dinfo, dinfo->unit);
193+
if (scsi_hot_add(&dev->qdev, dinfo, 0) != 0) {
194+
qdev_unplug(&dev->qdev);
195+
dev = NULL;
196+
}
173197
}
174198
break;
175199
case IF_VIRTIO:

0 commit comments

Comments
 (0)