Instead of duplicating the logic for the if_ide
(bus,unit) mappings, rely on the blockdev layer
for managing those mappings for us, and use the
drive_get_by_index call instead.
This allows ide_drive_get to work for AHCI HBAs
as well, and can be used in the Q35 initialization.
Lastly, change the nature of the argument to
ide_drive_get so that represents the number of
total drives we can support, and not the total
number of buses. This will prevent array overflows
if the units-per-default-bus property ever needs
to be adjusted for compatibility reasons.
Signed-off-by: John Snow <[email protected]>
Reviewed-by: Markus Armbruster <[email protected]>
Reviewed-by: Michael S. Tsirkin <[email protected]>
Message-id:
1412187569[email protected]
Signed-off-by: Stefan Hajnoczi <[email protected]>
}
}
+/**
+ * Returns the current mapping of how many units per bus
+ * a particular interface can support.
+ *
+ * A positive integer indicates n units per bus.
+ * 0 implies the mapping has not been established.
+ * -1 indicates an invalid BlockInterfaceType was given.
+ */
+int drive_get_max_devs(BlockInterfaceType type)
+{
+ if (type >= IF_IDE && type < IF_COUNT) {
+ return if_max_devs[type];
+ }
+
+ return -1;
+}
+
static int drive_index_to_bus_id(BlockInterfaceType type, int index)
{
int max_devs = if_max_devs[type];
/* IDE disk setup. */
{
DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
- ide_drive_get(hd, MAX_IDE_BUS);
+ ide_drive_get(hd, ARRAY_SIZE(hd));
pci_cmd646_ide_init(pci_bus, hd, 0);
}
pc_nic_init(isa_bus, pci_bus);
- ide_drive_get(hd, MAX_IDE_BUS);
+ ide_drive_get(hd, ARRAY_SIZE(hd));
if (pci_enabled) {
PCIDevice *dev;
if (xen_enabled()) {
}
};
-void ide_drive_get(DriveInfo **hd, int max_bus)
+void ide_drive_get(DriveInfo **hd, int n)
{
int i;
+ int highest_bus = drive_get_max_bus(IF_IDE) + 1;
+ int max_devs = drive_get_max_devs(IF_IDE);
+ int n_buses = max_devs ? (n / max_devs) : n;
- if (drive_get_max_bus(IF_IDE) >= max_bus) {
- fprintf(stderr, "qemu: too many IDE bus: %d\n", max_bus);
+ /*
+ * Note: The number of actual buses available is not known.
+ * We compute this based on the size of the DriveInfo* array, n.
+ * If it is less than max_devs * <num_real_buses>,
+ * We will stop looking for drives prematurely instead of overfilling
+ * the array.
+ */
+
+ if (highest_bus > n_buses) {
+ error_report("Too many IDE buses defined (%d > %d)",
+ highest_bus, n_buses);
exit(1);
}
- for(i = 0; i < max_bus * MAX_IDE_DEVS; i++) {
- hd[i] = drive_get(IF_IDE, i / MAX_IDE_DEVS, i % MAX_IDE_DEVS);
+ for (i = 0; i < n; i++) {
+ hd[i] = drive_get_by_index(IF_IDE, i);
}
}
pci_bus = bonito_init((qemu_irq *)&(env->irq[2]));
/* South bridge */
- ide_drive_get(hd, MAX_IDE_BUS);
+ ide_drive_get(hd, ARRAY_SIZE(hd));
isa_bus = vt82c686b_init(pci_bus, PCI_DEVFN(FULONG2E_VIA_SLOT, 0));
if (!isa_bus) {
pci_bus = gt64120_register(isa_irq);
/* Southbridge */
- ide_drive_get(hd, MAX_IDE_BUS);
+ ide_drive_get(hd, ARRAY_SIZE(hd));
piix4_devfn = piix4_init(pci_bus, &isa_bus, 80);
if (nd_table[0].used)
isa_ne2000_init(isa_bus, 0x300, 9, &nd_table[0]);
- ide_drive_get(hd, MAX_IDE_BUS);
+ ide_drive_get(hd, ARRAY_SIZE(hd));
for(i = 0; i < MAX_IDE_BUS; i++)
isa_ide_init(isa_bus, ide_iobase[i], ide_iobase2[i], ide_irq[i],
hd[MAX_IDE_DEVS * i],
macio_init(macio, pic_mem, escc_bar);
/* We only emulate 2 out of 3 IDE controllers for now */
- ide_drive_get(hd, MAX_IDE_BUS);
+ ide_drive_get(hd, ARRAY_SIZE(hd));
macio_ide = MACIO_IDE(object_resolve_path_component(OBJECT(macio),
"ide[0]"));
pci_nic_init_nofail(&nd_table[i], pci_bus, "ne2k_pci", NULL);
- ide_drive_get(hd, MAX_IDE_BUS);
+ ide_drive_get(hd, ARRAY_SIZE(hd));
macio = pci_create(pci_bus, -1, TYPE_OLDWORLD_MACIO);
dev = DEVICE(macio);
}
}
- ide_drive_get(hd, MAX_IDE_BUS);
+ ide_drive_get(hd, ARRAY_SIZE(hd));
for(i = 0; i < MAX_IDE_BUS; i++) {
isa_ide_init(isa_bus, ide_iobase[i], ide_iobase2[i], ide_irq[i],
hd[2 * i],
for(i = 0; i < nb_nics; i++)
pci_nic_init_nofail(&nd_table[i], pci_bus, "ne2k_pci", NULL);
- ide_drive_get(hd, MAX_IDE_BUS);
+ ide_drive_get(hd, ARRAY_SIZE(hd));
pci_cmd646_ide_init(pci_bus, hd, 1);
bool drive_check_orphaned(void);
DriveInfo *drive_get_by_index(BlockInterfaceType type, int index);
int drive_get_max_bus(BlockInterfaceType type);
+int drive_get_max_devs(BlockInterfaceType type);
DriveInfo *drive_get_next(BlockInterfaceType type);
DriveInfo *drive_get_by_blockdev(BlockDriverState *bs);