qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH v2 4/6] ide: Update ide_drive_get to be HBA agnostic


From: John Snow
Subject: [Qemu-devel] [PATCH v2 4/6] ide: Update ide_drive_get to be HBA agnostic
Date: Mon, 29 Sep 2014 12:47:16 -0400

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 <address@hidden>
---
 blockdev.c                |  9 +++++++++
 hw/alpha/dp264.c          |  2 +-
 hw/i386/pc_piix.c         |  2 +-
 hw/ide/core.c             | 21 +++++++++++++++------
 hw/mips/mips_fulong2e.c   |  2 +-
 hw/mips/mips_malta.c      |  2 +-
 hw/mips/mips_r4k.c        |  2 +-
 hw/ppc/mac_newworld.c     |  2 +-
 hw/ppc/mac_oldworld.c     |  2 +-
 hw/ppc/prep.c             |  2 +-
 hw/sparc64/sun4u.c        |  2 +-
 include/sysemu/blockdev.h |  1 +
 12 files changed, 34 insertions(+), 15 deletions(-)

diff --git a/blockdev.c b/blockdev.c
index 9b05f1b..ffaad39 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -135,6 +135,15 @@ void blockdev_auto_del(BlockDriverState *bs)
     }
 }
 
+int drive_get_max_devs(BlockInterfaceType type)
+{
+    if (type >= IF_IDE && type < IF_COUNT) {
+        return if_max_devs[type];
+    }
+
+    return 0;
+}
+
 static int drive_index_to_bus_id(BlockInterfaceType type, int index)
 {
     int max_devs = if_max_devs[type];
diff --git a/hw/alpha/dp264.c b/hw/alpha/dp264.c
index b178a03..ab61bb6 100644
--- a/hw/alpha/dp264.c
+++ b/hw/alpha/dp264.c
@@ -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, MAX_IDE_BUS * MAX_IDE_DEVS);
 
         pci_cmd646_ide_init(pci_bus, hd, 0);
     }
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 103d756..2760c81 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -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, MAX_IDE_BUS * MAX_IDE_DEVS);
     if (pci_enabled) {
         PCIDevice *dev;
         if (xen_enabled()) {
diff --git a/hw/ide/core.c b/hw/ide/core.c
index 190700a..e7c1050 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -2558,16 +2558,25 @@ 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 n_buses = n / drive_get_max_devs(IF_IDE);
 
-    if (drive_get_max_bus(IF_IDE) >= max_bus) {
-        fprintf(stderr, "qemu: too many IDE bus: %d\n", max_bus);
-        exit(1);
+    /* 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 (drive_get_max_devs(IF_IDE) * num_real_buses),
+     * We will stop looking for drives prematurely instead of overfilling
+     * the array. */
+
+    if (highest_bus > n_buses) {
+        error_report("Warning: Too many IDE buses defined (%d > %d)",
+                     highest_bus, n_buses);
     }
 
-    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);
     }
+
 }
diff --git a/hw/mips/mips_fulong2e.c b/hw/mips/mips_fulong2e.c
index be286da..0239438 100644
--- a/hw/mips/mips_fulong2e.c
+++ b/hw/mips/mips_fulong2e.c
@@ -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, MAX_IDE_BUS * MAX_IDE_DEVS);
 
     isa_bus = vt82c686b_init(pci_bus, PCI_DEVFN(FULONG2E_VIA_SLOT, 0));
     if (!isa_bus) {
diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c
index 2d87de9..e19a125 100644
--- a/hw/mips/mips_malta.c
+++ b/hw/mips/mips_malta.c
@@ -1147,7 +1147,7 @@ void mips_malta_init(MachineState *machine)
     pci_bus = gt64120_register(isa_irq);
 
     /* Southbridge */
-    ide_drive_get(hd, MAX_IDE_BUS);
+    ide_drive_get(hd, MAX_IDE_BUS * MAX_IDE_DEVS);
 
     piix4_devfn = piix4_init(pci_bus, &isa_bus, 80);
 
diff --git a/hw/mips/mips_r4k.c b/hw/mips/mips_r4k.c
index e219766..0d6f7ed 100644
--- a/hw/mips/mips_r4k.c
+++ b/hw/mips/mips_r4k.c
@@ -294,7 +294,7 @@ void mips_r4k_init(MachineState *machine)
     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, MAX_IDE_BUS * MAX_IDE_DEVS);
     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],
diff --git a/hw/ppc/mac_newworld.c b/hw/ppc/mac_newworld.c
index 1626db4..d291fee 100644
--- a/hw/ppc/mac_newworld.c
+++ b/hw/ppc/mac_newworld.c
@@ -400,7 +400,7 @@ static void ppc_core99_init(MachineState *machine)
     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, MAX_IDE_BUS * MAX_IDE_DEVS);
 
     macio_ide = MACIO_IDE(object_resolve_path_component(OBJECT(macio),
                                                         "ide[0]"));
diff --git a/hw/ppc/mac_oldworld.c b/hw/ppc/mac_oldworld.c
index be9a194..9dd7940 100644
--- a/hw/ppc/mac_oldworld.c
+++ b/hw/ppc/mac_oldworld.c
@@ -278,7 +278,7 @@ static void ppc_heathrow_init(MachineState *machine)
         pci_nic_init_nofail(&nd_table[i], pci_bus, "ne2k_pci", NULL);
 
 
-    ide_drive_get(hd, MAX_IDE_BUS);
+    ide_drive_get(hd, MAX_IDE_BUS * MAX_IDE_DEVS);
 
     macio = pci_create(pci_bus, -1, TYPE_OLDWORLD_MACIO);
     dev = DEVICE(macio);
diff --git a/hw/ppc/prep.c b/hw/ppc/prep.c
index f0ef1af..3e87cf9 100644
--- a/hw/ppc/prep.c
+++ b/hw/ppc/prep.c
@@ -519,7 +519,7 @@ static void ppc_prep_init(MachineState *machine)
         }
     }
 
-    ide_drive_get(hd, MAX_IDE_BUS);
+    ide_drive_get(hd, MAX_IDE_BUS * MAX_IDE_DEVS);
     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],
diff --git a/hw/sparc64/sun4u.c b/hw/sparc64/sun4u.c
index 9c77e18..c1b84bc 100644
--- a/hw/sparc64/sun4u.c
+++ b/hw/sparc64/sun4u.c
@@ -864,7 +864,7 @@ static void sun4uv_init(MemoryRegion *address_space_mem,
     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, MAX_IDE_BUS * MAX_IDE_DEVS);
 
     pci_cmd646_ide_init(pci_bus, hd, 1);
 
diff --git a/include/sysemu/blockdev.h b/include/sysemu/blockdev.h
index f23d495..81ec4fb 100644
--- a/include/sysemu/blockdev.h
+++ b/include/sysemu/blockdev.h
@@ -52,6 +52,7 @@ DriveInfo *drive_get(BlockInterfaceType type, int bus, int 
unit);
 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);
 
-- 
1.9.3




reply via email to

[Prev in Thread] Current Thread [Next in Thread]