diff mbox

[v1,04/13] blockdev: Introduce IF_AHCI

Message ID 28d8437f9a206fbaddf8ac63ed59ccc7e0749937.1351561225.git.jbaron@redhat.com
State New
Headers show

Commit Message

Jason Baron Oct. 30, 2012, 2:11 a.m. UTC
From: Jason Baron <jbaron@redhat.com>

Introduce IF_AHCI so that q35 can differentiate between ide and ahci disks.
This allows q35 to specify its default disk type. It also allows q35 to
differentiate between ahci and ide disks, such that -drive if=ide does not
result in the creating of an ahci disk. This is important, since we don't want
to have the meaning of if=ide changing once q35 is introduced. Thus, its
important for this to be applied before we introduce q35.

This patch also adds:

1)

void ahci_drive_get(DriveInfo **hd, int bus, int nports);

To populate hd with with the drives on bus 'bus', with up to 'nports'.

2)

pci_ahci_create_devs(PCIDevice *pci_dev, DriveInfo **hd_table, int
table_size);

Which provides a convient way of attaching ahci drives to an
ahci controller.

3)

drive_get_max_unit(BlockInterfaceType type);

Allows q35 to error if too many units are specified.

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Jason Baron <jbaron@redhat.com>
---
 blockdev.c    |   19 ++++++++++++++++++-
 blockdev.h    |    2 ++
 hw/ide.h      |    1 +
 hw/ide/core.c |    9 +++++++++
 hw/ide/pci.c  |   19 +++++++++++++++++++
 hw/ide/pci.h  |    1 +
 6 files changed, 50 insertions(+), 1 deletions(-)
diff mbox

Patch

diff --git a/blockdev.c b/blockdev.c
index 2977e2f..e37d93d 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -33,6 +33,7 @@  static const char *const if_name[IF_COUNT] = {
     [IF_SD] = "sd",
     [IF_VIRTIO] = "virtio",
     [IF_XEN] = "xen",
+    [IF_AHCI] = "ahci",
 };
 
 static const int if_max_devs[IF_COUNT] = {
@@ -158,6 +159,21 @@  int drive_get_max_bus(BlockInterfaceType type)
     return max_bus;
 }
 
+int drive_get_max_unit(BlockInterfaceType type)
+{
+    int max_unit;
+    DriveInfo *dinfo;
+
+    max_unit = -1;
+    QTAILQ_FOREACH(dinfo, &drives, next) {
+        if (dinfo->type == type &&
+            dinfo->unit > max_unit) {
+             max_unit = dinfo->unit;
+        }
+    }
+    return max_unit;
+}
+
 /* Get a block device.  This should only be used for single-drive devices
    (e.g. SD/Floppy/MTD).  Multi-disk devices (scsi/ide) should use the
    appropriate bus.  */
@@ -518,7 +534,7 @@  DriveInfo *drive_init(QemuOpts *opts, BlockInterfaceType default_drive_if)
     } else {
         /* no id supplied -> create one */
         dinfo->id = g_malloc0(32);
-        if (type == IF_IDE || type == IF_SCSI)
+        if (type == IF_IDE || type == IF_SCSI || type == IF_AHCI)
             mediastr = (media == MEDIA_CDROM) ? "-cd" : "-hd";
         if (max_devs)
             snprintf(dinfo->id, 32, "%s%i%s%i",
@@ -550,6 +566,7 @@  DriveInfo *drive_init(QemuOpts *opts, BlockInterfaceType default_drive_if)
 
     switch(type) {
     case IF_IDE:
+    case IF_AHCI:
     case IF_SCSI:
     case IF_XEN:
     case IF_NONE:
diff --git a/blockdev.h b/blockdev.h
index 658380d..0c7985d 100644
--- a/blockdev.h
+++ b/blockdev.h
@@ -21,6 +21,7 @@  typedef enum {
     IF_DEFAULT = -1,            /* for use with drive_add() only */
     IF_NONE,
     IF_IDE, IF_SCSI, IF_FLOPPY, IF_PFLASH, IF_MTD, IF_SD, IF_VIRTIO, IF_XEN,
+    IF_AHCI,
     IF_COUNT
 } BlockInterfaceType;
 
@@ -63,6 +64,7 @@  static inline int get_default_drive_if(int default_drive_if)
 DriveInfo *drive_get(BlockInterfaceType type, int bus, int unit);
 DriveInfo *drive_get_by_index(BlockInterfaceType type, int index);
 int drive_get_max_bus(BlockInterfaceType type);
+int drive_get_max_unit(BlockInterfaceType type);
 DriveInfo *drive_get_next(BlockInterfaceType type);
 void drive_get_ref(DriveInfo *dinfo);
 void drive_put_ref(DriveInfo *dinfo);
diff --git a/hw/ide.h b/hw/ide.h
index add742c..6c43a57 100644
--- a/hw/ide.h
+++ b/hw/ide.h
@@ -35,5 +35,6 @@  int ide_get_bios_chs_trans(BusState *bus, int unit);
 
 /* ide/core.c */
 void ide_drive_get(DriveInfo **hd, int max_bus);
+void ahci_drive_get(DriveInfo **hd, int bus, int nports);
 
 #endif /* HW_IDE_H */
diff --git a/hw/ide/core.c b/hw/ide/core.c
index d683a8c..4a56517 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -2354,3 +2354,12 @@  void ide_drive_get(DriveInfo **hd, int max_bus)
         hd[i] = drive_get(IF_IDE, i / MAX_IDE_DEVS, i % MAX_IDE_DEVS);
     }
 }
+
+void ahci_drive_get(DriveInfo **hd, int bus, int nports)
+{
+    int i;
+
+    for (i = 0; i < nports; i++) {
+        hd[i] = drive_get(IF_AHCI, bus, i);
+    }
+}
diff --git a/hw/ide/pci.c b/hw/ide/pci.c
index bcdd70e..9218989 100644
--- a/hw/ide/pci.c
+++ b/hw/ide/pci.c
@@ -28,8 +28,10 @@ 
 #include <hw/isa.h>
 #include "block.h"
 #include "dma.h"
+#include "blockdev.h"
 
 #include <hw/ide/pci.h>
+#include <hw/ide/ahci.h>
 
 #define BMDMA_PAGE_SIZE 4096
 
@@ -504,6 +506,23 @@  void pci_ide_create_devs(PCIDevice *dev, DriveInfo **hd_table)
     }
 }
 
+void pci_ahci_create_devs(PCIDevice *pci_dev, DriveInfo **hd_table, int table_size)
+{
+    struct AHCIPCIState *dev = DO_UPCAST(struct AHCIPCIState, card, pci_dev);
+    int i;
+    DriveInfo *drive;
+
+    for (i = 0; i < table_size; i++) {
+        if (hd_table[i] == NULL) {
+            continue;
+        }
+        drive = hd_table[i];
+        assert(drive->type == IF_AHCI);
+        ide_create_drive(&dev->ahci.dev[i].port, 0,
+                         hd_table[i]);
+    }
+}
+
 static const struct IDEDMAOps bmdma_ops = {
     .start_dma = bmdma_start_dma,
     .start_transfer = bmdma_start_transfer,
diff --git a/hw/ide/pci.h b/hw/ide/pci.h
index a694e54..aa23f44 100644
--- a/hw/ide/pci.h
+++ b/hw/ide/pci.h
@@ -58,6 +58,7 @@  void bmdma_init(IDEBus *bus, BMDMAState *bm, PCIIDEState *d);
 void bmdma_cmd_writeb(BMDMAState *bm, uint32_t val);
 extern MemoryRegionOps bmdma_addr_ioport_ops;
 void pci_ide_create_devs(PCIDevice *dev, DriveInfo **hd_table);
+void pci_ahci_create_devs(PCIDevice *pci_dev, DriveInfo **hd_table, int table_size);
 
 extern const VMStateDescription vmstate_ide_pci;
 #endif