summary refs log tree commit diff stats
path: root/hw/ide/core.c
diff options
context:
space:
mode:
authorJohn Snow <jsnow@redhat.com>2014-10-01 14:19:27 -0400
committerStefan Hajnoczi <stefanha@redhat.com>2014-10-03 10:30:33 +0100
commitd8f94e1bb275ab6a14a15220fd6afd0d04324aeb (patch)
treeb24bbaf0487f1288af282314c817c53ff3a06bed /hw/ide/core.c
parent1602651833c081e32366c9e534ad72e4287840c5 (diff)
downloadfocaccia-qemu-d8f94e1bb275ab6a14a15220fd6afd0d04324aeb.tar.gz
focaccia-qemu-d8f94e1bb275ab6a14a15220fd6afd0d04324aeb.zip
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>
Diffstat (limited to 'hw/ide/core.c')
-rw-r--r--hw/ide/core.c22
1 files changed, 17 insertions, 5 deletions
diff --git a/hw/ide/core.c b/hw/ide/core.c
index 190700ac74..ae85428864 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -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);
     }
 }