Commit d8f94e1b authored by John Snow's avatar John Snow Committed by Stefan Hajnoczi
Browse files

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: default avatarJohn Snow <jsnow@redhat.com>
Reviewed-by: default avatarMarkus Armbruster <armbru@redhat.com>
Reviewed-by: default avatarMichael S. Tsirkin <mst@redhat.com>
Message-id: 1412187569-23452-5-git-send-email-jsnow@redhat.com
Signed-off-by: default avatarStefan Hajnoczi <stefanha@redhat.com>
parent 16026518
Loading
Loading
Loading
Loading
+17 −0
Original line number Diff line number Diff line
@@ -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)
{
    int max_devs = if_max_devs[type];
+1 −1
Original line number Diff line number Diff line
@@ -97,7 +97,7 @@ static void clipper_init(MachineState *machine)
    /* 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);
    }
+1 −1
Original line number Diff line number Diff line
@@ -239,7 +239,7 @@ static void pc_init1(MachineState *machine,

    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()) {
+17 −5
Original line number Diff line number Diff line
@@ -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 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);
    }
}
+1 −1
Original line number Diff line number Diff line
@@ -350,7 +350,7 @@ static void mips_fulong2e_init(MachineState *machine)
    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) {
Loading