ide: Update ide_drive_get to be HBA agnostic
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 <jsnow@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Message-id: 1412187569-23452-5-git-send-email-jsnow@redhat.com Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
parent
1602651833
commit
d8f94e1bb2
17
blockdev.c
17
blockdev.c
@ -135,6 +135,23 @@ void blockdev_auto_del(BlockDriverState *bs)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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)
|
static int drive_index_to_bus_id(BlockInterfaceType type, int index)
|
||||||
{
|
{
|
||||||
int max_devs = if_max_devs[type];
|
int max_devs = if_max_devs[type];
|
||||||
|
@ -97,7 +97,7 @@ static void clipper_init(MachineState *machine)
|
|||||||
/* IDE disk setup. */
|
/* IDE disk setup. */
|
||||||
{
|
{
|
||||||
DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
|
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);
|
pci_cmd646_ide_init(pci_bus, hd, 0);
|
||||||
}
|
}
|
||||||
|
@ -239,7 +239,7 @@ static void pc_init1(MachineState *machine,
|
|||||||
|
|
||||||
pc_nic_init(isa_bus, pci_bus);
|
pc_nic_init(isa_bus, pci_bus);
|
||||||
|
|
||||||
ide_drive_get(hd, MAX_IDE_BUS);
|
ide_drive_get(hd, ARRAY_SIZE(hd));
|
||||||
if (pci_enabled) {
|
if (pci_enabled) {
|
||||||
PCIDevice *dev;
|
PCIDevice *dev;
|
||||||
if (xen_enabled()) {
|
if (xen_enabled()) {
|
||||||
|
@ -2558,16 +2558,28 @@ const VMStateDescription vmstate_ide_bus = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void ide_drive_get(DriveInfo **hd, int max_bus)
|
void ide_drive_get(DriveInfo **hd, int n)
|
||||||
{
|
{
|
||||||
int i;
|
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);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(i = 0; i < max_bus * MAX_IDE_DEVS; i++) {
|
for (i = 0; i < n; i++) {
|
||||||
hd[i] = drive_get(IF_IDE, i / MAX_IDE_DEVS, i % MAX_IDE_DEVS);
|
hd[i] = drive_get_by_index(IF_IDE, i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -350,7 +350,7 @@ static void mips_fulong2e_init(MachineState *machine)
|
|||||||
pci_bus = bonito_init((qemu_irq *)&(env->irq[2]));
|
pci_bus = bonito_init((qemu_irq *)&(env->irq[2]));
|
||||||
|
|
||||||
/* South bridge */
|
/* 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));
|
isa_bus = vt82c686b_init(pci_bus, PCI_DEVFN(FULONG2E_VIA_SLOT, 0));
|
||||||
if (!isa_bus) {
|
if (!isa_bus) {
|
||||||
|
@ -1147,7 +1147,7 @@ void mips_malta_init(MachineState *machine)
|
|||||||
pci_bus = gt64120_register(isa_irq);
|
pci_bus = gt64120_register(isa_irq);
|
||||||
|
|
||||||
/* Southbridge */
|
/* Southbridge */
|
||||||
ide_drive_get(hd, MAX_IDE_BUS);
|
ide_drive_get(hd, ARRAY_SIZE(hd));
|
||||||
|
|
||||||
piix4_devfn = piix4_init(pci_bus, &isa_bus, 80);
|
piix4_devfn = piix4_init(pci_bus, &isa_bus, 80);
|
||||||
|
|
||||||
|
@ -294,7 +294,7 @@ void mips_r4k_init(MachineState *machine)
|
|||||||
if (nd_table[0].used)
|
if (nd_table[0].used)
|
||||||
isa_ne2000_init(isa_bus, 0x300, 9, &nd_table[0]);
|
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++)
|
for(i = 0; i < MAX_IDE_BUS; i++)
|
||||||
isa_ide_init(isa_bus, ide_iobase[i], ide_iobase2[i], ide_irq[i],
|
isa_ide_init(isa_bus, ide_iobase[i], ide_iobase2[i], ide_irq[i],
|
||||||
hd[MAX_IDE_DEVS * i],
|
hd[MAX_IDE_DEVS * i],
|
||||||
|
@ -400,7 +400,7 @@ static void ppc_core99_init(MachineState *machine)
|
|||||||
macio_init(macio, pic_mem, escc_bar);
|
macio_init(macio, pic_mem, escc_bar);
|
||||||
|
|
||||||
/* We only emulate 2 out of 3 IDE controllers for now */
|
/* 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),
|
macio_ide = MACIO_IDE(object_resolve_path_component(OBJECT(macio),
|
||||||
"ide[0]"));
|
"ide[0]"));
|
||||||
|
@ -278,7 +278,7 @@ static void ppc_heathrow_init(MachineState *machine)
|
|||||||
pci_nic_init_nofail(&nd_table[i], pci_bus, "ne2k_pci", NULL);
|
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);
|
macio = pci_create(pci_bus, -1, TYPE_OLDWORLD_MACIO);
|
||||||
dev = DEVICE(macio);
|
dev = DEVICE(macio);
|
||||||
|
@ -519,7 +519,7 @@ static void ppc_prep_init(MachineState *machine)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ide_drive_get(hd, MAX_IDE_BUS);
|
ide_drive_get(hd, ARRAY_SIZE(hd));
|
||||||
for(i = 0; i < MAX_IDE_BUS; i++) {
|
for(i = 0; i < MAX_IDE_BUS; i++) {
|
||||||
isa_ide_init(isa_bus, ide_iobase[i], ide_iobase2[i], ide_irq[i],
|
isa_ide_init(isa_bus, ide_iobase[i], ide_iobase2[i], ide_irq[i],
|
||||||
hd[2 * i],
|
hd[2 * i],
|
||||||
|
@ -864,7 +864,7 @@ static void sun4uv_init(MemoryRegion *address_space_mem,
|
|||||||
for(i = 0; i < nb_nics; i++)
|
for(i = 0; i < nb_nics; i++)
|
||||||
pci_nic_init_nofail(&nd_table[i], pci_bus, "ne2k_pci", NULL);
|
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);
|
pci_cmd646_ide_init(pci_bus, hd, 1);
|
||||||
|
|
||||||
|
@ -52,6 +52,7 @@ DriveInfo *drive_get(BlockInterfaceType type, int bus, int unit);
|
|||||||
bool drive_check_orphaned(void);
|
bool drive_check_orphaned(void);
|
||||||
DriveInfo *drive_get_by_index(BlockInterfaceType type, int index);
|
DriveInfo *drive_get_by_index(BlockInterfaceType type, int index);
|
||||||
int drive_get_max_bus(BlockInterfaceType type);
|
int drive_get_max_bus(BlockInterfaceType type);
|
||||||
|
int drive_get_max_devs(BlockInterfaceType type);
|
||||||
DriveInfo *drive_get_next(BlockInterfaceType type);
|
DriveInfo *drive_get_next(BlockInterfaceType type);
|
||||||
DriveInfo *drive_get_by_blockdev(BlockDriverState *bs);
|
DriveInfo *drive_get_by_blockdev(BlockDriverState *bs);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user