qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v2 0/3] cleanup drive handling.
@ 2009-07-16  8:53 Gerd Hoffmann
  2009-07-16  8:53 ` [Qemu-devel] [PATCH v2 1/3] kill drives_table Gerd Hoffmann
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Gerd Hoffmann @ 2009-07-16  8:53 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

  Hi,

This patch series cleans up the drive handling in qemu.  It removes the
drives_table and (new in v2) also the drives_opt table and replaces them
with linked lists.  The silly table indexing stuff is gone.

It also adds the ability to name drives using id= (used to be name= in
v1, but for consistency with -device which uses id= too I've decided to
change it).

Future plans:

While qdev-ifying virtual disk drivers block/*.c) make them lookup the
BlockDriverState using the id.

cheers,
  Gerd

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [Qemu-devel] [PATCH v2 1/3] kill drives_table
  2009-07-16  8:53 [Qemu-devel] [PATCH v2 0/3] cleanup drive handling Gerd Hoffmann
@ 2009-07-16  8:53 ` Gerd Hoffmann
       [not found]   ` <m3d480hg02.fsf@neno.mitica>
  2009-07-16  8:53 ` [Qemu-devel] [PATCH v2 2/3] add support for drive ids Gerd Hoffmann
  2009-07-16  8:53 ` [Qemu-devel] [PATCH v2 3/3] kill drives_opt Gerd Hoffmann
  2 siblings, 1 reply; 6+ messages in thread
From: Gerd Hoffmann @ 2009-07-16  8:53 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

First step cleaning up the drives handling.  This one does nothing but
removing drives_table[], still it became seriously big.

drive_get_index() is gone and is replaced by drives_get() which hands
out DriveInfo pointers instead of a table index.  This needs adaption in
*tons* of places all over.

The drives are now maintained as linked list.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/device-hotplug.c           |   23 +++---
 hw/etraxfs.c                  |    5 +-
 hw/gumstix.c                  |   16 ++--
 hw/mainstone.c                |    9 +-
 hw/mips_jazz.c                |    7 +-
 hw/mips_malta.c               |   24 ++----
 hw/mips_r4k.c                 |   13 +--
 hw/musicpal.c                 |   10 +-
 hw/nand.c                     |    8 +-
 hw/omap1.c                    |    8 +-
 hw/omap2.c                    |    8 +-
 hw/omap_sx1.c                 |   10 +-
 hw/onenand.c                  |    6 +-
 hw/pc.c                       |   21 ++---
 hw/pci-hotplug.c              |   28 ++++---
 hw/petalogix_s3adsp1800_mmu.c |    5 +-
 hw/ppc405_boards.c            |   34 ++++----
 hw/ppc440_bamboo.c            |    5 +-
 hw/ppc_newworld.c             |    9 +--
 hw/ppc_oldworld.c             |   30 ++-----
 hw/ppc_prep.c                 |   16 +---
 hw/ppce500_mpc8544ds.c        |    5 +-
 hw/pxa2xx.c                   |   16 ++--
 hw/qdev.c                     |   17 ++---
 hw/r2d.c                      |    5 +-
 hw/spitz.c                    |    8 +-
 hw/sun4m.c                    |   16 ++--
 hw/sun4u.c                    |   18 ++---
 hw/tosa.c                     |    8 +-
 monitor.c                     |   12 ++-
 qemu-char.c                   |    2 +
 savevm.c                      |   32 ++++---
 sysemu.h                      |   13 ++--
 vl.c                          |  177 ++++++++++++++++++++---------------------
 34 files changed, 295 insertions(+), 329 deletions(-)

diff --git a/hw/device-hotplug.c b/hw/device-hotplug.c
index e178083..5257274 100644
--- a/hw/device-hotplug.c
+++ b/hw/device-hotplug.c
@@ -28,22 +28,23 @@
 #include "block_int.h"
 #include "sysemu.h"
 
-int add_init_drive(const char *opts)
+DriveInfo *add_init_drive(const char *opts)
 {
-    int drive_opt_idx, drive_idx;
-    int ret = -1;
+    int drive_opt_idx;
+    int fatal_error;
+    DriveInfo *dinfo;
 
     drive_opt_idx = drive_add(NULL, "%s", opts);
     if (!drive_opt_idx)
-        return ret;
+        return NULL;
 
-    drive_idx = drive_init(&drives_opt[drive_opt_idx], 0, current_machine);
-    if (drive_idx == -1) {
+    dinfo = drive_init(&drives_opt[drive_opt_idx], 0, current_machine, &fatal_error);
+    if (!dinfo) {
         drive_remove(drive_opt_idx);
-        return ret;
+        return NULL;
     }
 
-    return drive_idx;
+    return dinfo;
 }
 
 void destroy_nic(dev_match_fn *match_fn, void *arg)
@@ -64,11 +65,11 @@ void destroy_nic(dev_match_fn *match_fn, void *arg)
 
 void destroy_bdrvs(dev_match_fn *match_fn, void *arg)
 {
-    int i;
+    DriveInfo *dinfo;
     struct BlockDriverState *bs;
 
-    for (i = 0; i <= MAX_DRIVES; i++) {
-        bs = drives_table[i].bdrv;
+    TAILQ_FOREACH(dinfo, &drives, next) {
+        bs = dinfo->bdrv;
         if (bs) {
             if (bs->private && match_fn(bs->private, arg)) {
                 drive_uninit(bs);
diff --git a/hw/etraxfs.c b/hw/etraxfs.c
index 94cd6bc..de31cbc 100644
--- a/hw/etraxfs.c
+++ b/hw/etraxfs.c
@@ -55,6 +55,7 @@ void bareetraxfs_init (ram_addr_t ram_size,
     void *etraxfs_dmac;
     struct etraxfs_dma_client *eth[2] = {NULL, NULL};
     int kernel_size;
+    DriveInfo *dinfo;
     int i;
     ram_addr_t phys_ram;
     ram_addr_t phys_flash;
@@ -79,9 +80,9 @@ void bareetraxfs_init (ram_addr_t ram_size,
 
 
     phys_flash = qemu_ram_alloc(FLASH_SIZE);
-    i = drive_get_index(IF_PFLASH, 0, 0);
+    dinfo = drive_get(IF_PFLASH, 0, 0);
     pflash_cfi02_register(0x0, phys_flash,
-                          i != -1 ? drives_table[i].bdrv : NULL, (64 * 1024),
+                          dinfo ? dinfo->bdrv : NULL, (64 * 1024),
                           FLASH_SIZE >> 16,
                           1, 2, 0x0000, 0x0000, 0x0000, 0x0000,
                           0x555, 0x2aa);
diff --git a/hw/gumstix.c b/hw/gumstix.c
index 85b95ee..8fbf64c 100644
--- a/hw/gumstix.c
+++ b/hw/gumstix.c
@@ -47,22 +47,22 @@ static void connex_init(ram_addr_t ram_size,
                 const char *initrd_filename, const char *cpu_model)
 {
     PXA2xxState *cpu;
-    int index;
+    DriveInfo *dinfo;
 
     uint32_t connex_rom = 0x01000000;
     uint32_t connex_ram = 0x04000000;
 
     cpu = pxa255_init(connex_ram);
 
-    index = drive_get_index(IF_PFLASH, 0, 0);
-    if (index == -1) {
+    dinfo = drive_get(IF_PFLASH, 0, 0);
+    if (!dinfo) {
         fprintf(stderr, "A flash image must be given with the "
                 "'pflash' parameter\n");
         exit(1);
     }
 
     if (!pflash_cfi01_register(0x00000000, qemu_ram_alloc(connex_rom),
-            drives_table[index].bdrv, sector_len, connex_rom / sector_len,
+            dinfo->bdrv, sector_len, connex_rom / sector_len,
             2, 0, 0, 0, 0)) {
         fprintf(stderr, "qemu: Error registering flash memory.\n");
         exit(1);
@@ -81,22 +81,22 @@ static void verdex_init(ram_addr_t ram_size,
                 const char *initrd_filename, const char *cpu_model)
 {
     PXA2xxState *cpu;
-    int index;
+    DriveInfo *dinfo;
 
     uint32_t verdex_rom = 0x02000000;
     uint32_t verdex_ram = 0x10000000;
 
     cpu = pxa270_init(verdex_ram, cpu_model ?: "pxa270-c0");
 
-    index = drive_get_index(IF_PFLASH, 0, 0);
-    if (index == -1) {
+    dinfo = drive_get(IF_PFLASH, 0, 0);
+    if (!dinfo) {
         fprintf(stderr, "A flash image must be given with the "
                 "'pflash' parameter\n");
         exit(1);
     }
 
     if (!pflash_cfi01_register(0x00000000, qemu_ram_alloc(verdex_rom),
-            drives_table[index].bdrv, sector_len, verdex_rom / sector_len,
+            dinfo->bdrv, sector_len, verdex_rom / sector_len,
             2, 0, 0, 0, 0)) {
         fprintf(stderr, "qemu: Error registering flash memory.\n");
         exit(1);
diff --git a/hw/mainstone.c b/hw/mainstone.c
index 151ea0e..3e517f0 100644
--- a/hw/mainstone.c
+++ b/hw/mainstone.c
@@ -77,7 +77,8 @@ static void mainstone_common_init(ram_addr_t ram_size,
     target_phys_addr_t mainstone_flash_base[] = { MST_FLASH_0, MST_FLASH_1 };
     PXA2xxState *cpu;
     qemu_irq *mst_irq;
-    int i, index;
+    DriveInfo *dinfo;
+    int i;
 
     if (!cpu_model)
         cpu_model = "pxa270-c5";
@@ -92,8 +93,8 @@ static void mainstone_common_init(ram_addr_t ram_size,
 
     /* There are two 32MiB flash devices on the board */
     for (i = 0; i < 2; i ++) {
-        index = drive_get_index(IF_PFLASH, 0, i);
-        if (index == -1) {
+        dinfo = drive_get(IF_PFLASH, 0, i);
+        if (!dinfo) {
             fprintf(stderr, "Two flash images must be given with the "
                     "'pflash' parameter\n");
             exit(1);
@@ -101,7 +102,7 @@ static void mainstone_common_init(ram_addr_t ram_size,
 
         if (!pflash_cfi01_register(mainstone_flash_base[i],
                                 qemu_ram_alloc(MAINSTONE_FLASH),
-                                drives_table[index].bdrv, sector_len,
+                                dinfo->bdrv, sector_len,
                                 MAINSTONE_FLASH / sector_len, 4, 0, 0, 0, 0)) {
             fprintf(stderr, "qemu: Error registering flash memory.\n");
             exit(1);
diff --git a/hw/mips_jazz.c b/hw/mips_jazz.c
index 82cd385..e09a6b2 100644
--- a/hw/mips_jazz.c
+++ b/hw/mips_jazz.c
@@ -235,11 +235,8 @@ void mips_jazz_init (ram_addr_t ram_size,
         exit(1);
     }
     for (n = 0; n < MAX_FD; n++) {
-        int fd = drive_get_index(IF_FLOPPY, 0, n);
-        if (fd != -1)
-            fds[n] = drives_table[fd].bdrv;
-        else
-            fds[n] = NULL;
+        DriveInfo *dinfo = drive_get(IF_FLOPPY, 0, n);
+        fds[n] = dinfo ? dinfo->bdrv : NULL;
     }
     fdctrl_init(rc4030[1], 0, 1, 0x80003000, fds);
 
diff --git a/hw/mips_malta.c b/hw/mips_malta.c
index 853ec2b..fa03bdf 100644
--- a/hw/mips_malta.c
+++ b/hw/mips_malta.c
@@ -773,7 +773,7 @@ void mips_malta_init (ram_addr_t ram_size,
     uint8_t *eeprom_buf;
     i2c_bus *smbus;
     int i;
-    int index;
+    DriveInfo *dinfo;
     BlockDriverState *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
     BlockDriverState *fd[MAX_FD];
     int fl_idx = 0;
@@ -827,8 +827,8 @@ void mips_malta_init (ram_addr_t ram_size,
         env->CP0_Status &= ~((1 << CP0St_BEV) | (1 << CP0St_ERL));
         write_bootloader(env, qemu_get_ram_ptr(bios_offset), kernel_entry);
     } else {
-        index = drive_get_index(IF_PFLASH, 0, fl_idx);
-        if (index != -1) {
+        dinfo = drive_get(IF_PFLASH, 0, fl_idx);
+        if (dinfo) {
             /* Load firmware from flash. */
             bios_size = 0x400000;
             fl_sectors = bios_size >> 16;
@@ -836,10 +836,10 @@ void mips_malta_init (ram_addr_t ram_size,
             printf("Register parallel flash %d size " TARGET_FMT_lx " at "
                    "offset %08lx addr %08llx '%s' %x\n",
                    fl_idx, bios_size, bios_offset, 0x1e000000LL,
-                   bdrv_get_device_name(drives_table[index].bdrv), fl_sectors);
+                   bdrv_get_device_name(dinfo->bdrv), fl_sectors);
 #endif
             pflash_cfi01_register(0x1e000000LL, bios_offset,
-                                  drives_table[index].bdrv, 65536, fl_sectors,
+                                  dinfo->bdrv, 65536, fl_sectors,
                                   4, 0x0000, 0x0000, 0x0000, 0x0000);
             fl_idx++;
         } else {
@@ -898,11 +898,8 @@ void mips_malta_init (ram_addr_t ram_size,
     }
 
     for(i = 0; i < MAX_IDE_BUS * MAX_IDE_DEVS; i++) {
-        index = drive_get_index(IF_IDE, i / MAX_IDE_DEVS, i % MAX_IDE_DEVS);
-        if (index != -1)
-            hd[i] = drives_table[index].bdrv;
-        else
-            hd[i] = NULL;
+        dinfo = drive_get(IF_IDE, i / MAX_IDE_DEVS, i % MAX_IDE_DEVS);
+        hd[i] = dinfo ? dinfo->bdrv : NULL;
     }
 
     piix4_devfn = piix4_init(pci_bus, 80);
@@ -929,11 +926,8 @@ void mips_malta_init (ram_addr_t ram_size,
     if (parallel_hds[0])
         parallel_init(0x378, i8259[7], parallel_hds[0]);
     for(i = 0; i < MAX_FD; i++) {
-        index = drive_get_index(IF_FLOPPY, 0, i);
-       if (index != -1)
-           fd[i] = drives_table[index].bdrv;
-       else
-           fd[i] = NULL;
+        dinfo = drive_get(IF_FLOPPY, 0, i);
+        fd[i] = dinfo ? dinfo->bdrv : NULL;
     }
     floppy_controller = fdctrl_init(i8259[6], 2, 0, 0x3f0, fd);
 
diff --git a/hw/mips_r4k.c b/hw/mips_r4k.c
index 7f8af74..476612c 100644
--- a/hw/mips_r4k.c
+++ b/hw/mips_r4k.c
@@ -155,8 +155,8 @@ void mips_r4k_init (ram_addr_t ram_size,
     RTCState *rtc_state;
     int i;
     qemu_irq *i8259;
-    int index;
     BlockDriverState *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
+    DriveInfo *dinfo;
 
     /* init CPUs */
     if (cpu_model == NULL) {
@@ -208,11 +208,11 @@ void mips_r4k_init (ram_addr_t ram_size,
                                      bios_offset | IO_MEM_ROM);
 
         load_image_targphys(filename, 0x1fc00000, BIOS_SIZE);
-    } else if ((index = drive_get_index(IF_PFLASH, 0, 0)) > -1) {
+    } else if ((dinfo = drive_get(IF_PFLASH, 0, 0)) != NULL) {
         uint32_t mips_rom = 0x00400000;
         bios_offset = qemu_ram_alloc(mips_rom);
         if (!pflash_cfi01_register(0x1fc00000, bios_offset,
-            drives_table[index].bdrv, sector_len, mips_rom / sector_len,
+            dinfo->bdrv, sector_len, mips_rom / sector_len,
             4, 0, 0, 0, 0)) {
             fprintf(stderr, "qemu: Error registering flash memory.\n");
 	}
@@ -267,11 +267,8 @@ void mips_r4k_init (ram_addr_t ram_size,
     }
 
     for(i = 0; i < MAX_IDE_BUS * MAX_IDE_DEVS; i++) {
-        index = drive_get_index(IF_IDE, i / MAX_IDE_DEVS, i % MAX_IDE_DEVS);
-        if (index != -1)
-            hd[i] = drives_table[index].bdrv;
-        else
-            hd[i] = NULL;
+        dinfo = drive_get(IF_IDE, i / MAX_IDE_DEVS, i % MAX_IDE_DEVS);
+        hd[i] = dinfo ? dinfo->bdrv : NULL;
     }
 
     for(i = 0; i < MAX_IDE_BUS; i++)
diff --git a/hw/musicpal.c b/hw/musicpal.c
index 10be69b..bd659ee 100644
--- a/hw/musicpal.c
+++ b/hw/musicpal.c
@@ -1512,8 +1512,8 @@ static void musicpal_init(ram_addr_t ram_size,
     qemu_irq pic[32];
     DeviceState *dev;
     int i;
-    int index;
     unsigned long flash_size;
+    DriveInfo *dinfo;
 
     if (!cpu_model)
         cpu_model = "arm926";
@@ -1549,9 +1549,9 @@ static void musicpal_init(ram_addr_t ram_size,
                    serial_hds[1], 1);
 
     /* Register flash */
-    index = drive_get_index(IF_PFLASH, 0, 0);
-    if (index != -1) {
-        flash_size = bdrv_getlength(drives_table[index].bdrv);
+    dinfo = drive_get(IF_PFLASH, 0, 0);
+    if (dinfo) {
+        flash_size = bdrv_getlength(dinfo->bdrv);
         if (flash_size != 8*1024*1024 && flash_size != 16*1024*1024 &&
             flash_size != 32*1024*1024) {
             fprintf(stderr, "Invalid flash image size\n");
@@ -1564,7 +1564,7 @@ static void musicpal_init(ram_addr_t ram_size,
          * image is smaller than 32 MB.
          */
         pflash_cfi02_register(0-MP_FLASH_SIZE_MAX, qemu_ram_alloc(flash_size),
-                              drives_table[index].bdrv, 0x10000,
+                              dinfo->bdrv, 0x10000,
                               (flash_size + 0xffff) >> 16,
                               MP_FLASH_SIZE_MAX / flash_size,
                               2, 0x00BF, 0x236D, 0x0000, 0x0000,
diff --git a/hw/nand.c b/hw/nand.c
index 4ad77ec..37fd524 100644
--- a/hw/nand.c
+++ b/hw/nand.c
@@ -442,16 +442,16 @@ NANDFlashState *nand_init(int manf_id, int chip_id)
 {
     int pagesize;
     NANDFlashState *s;
-    int index;
+    DriveInfo *dinfo;
 
     if (nand_flash_ids[chip_id].size == 0) {
         hw_error("%s: Unsupported NAND chip ID.\n", __FUNCTION__);
     }
 
     s = (NANDFlashState *) qemu_mallocz(sizeof(NANDFlashState));
-    index = drive_get_index(IF_MTD, 0, 0);
-    if (index != -1)
-        s->bdrv = drives_table[index].bdrv;
+    dinfo = drive_get(IF_MTD, 0, 0);
+    if (dinfo)
+        s->bdrv = dinfo->bdrv;
     s->manf_id = manf_id;
     s->chip_id = chip_id;
     s->size = nand_flash_ids[s->chip_id].size << 20;
diff --git a/hw/omap1.c b/hw/omap1.c
index 5af2d9f..4f99c1c 100644
--- a/hw/omap1.c
+++ b/hw/omap1.c
@@ -4629,7 +4629,7 @@ struct omap_mpu_state_s *omap310_mpu_init(unsigned long sdram_size,
     ram_addr_t imif_base, emiff_base;
     qemu_irq *cpu_irq;
     qemu_irq dma_irqs[6];
-    int sdindex;
+    DriveInfo *dinfo;
 
     if (!core)
         core = "ti925t";
@@ -4741,12 +4741,12 @@ struct omap_mpu_state_s *omap310_mpu_init(unsigned long sdram_size,
     omap_dpll_init(&s->dpll[1], 0xfffed000, omap_findclk(s, "dpll2"));
     omap_dpll_init(&s->dpll[2], 0xfffed100, omap_findclk(s, "dpll3"));
 
-    sdindex = drive_get_index(IF_SD, 0, 0);
-    if (sdindex == -1) {
+    dinfo = drive_get(IF_SD, 0, 0);
+    if (!dinfo) {
         fprintf(stderr, "qemu: missing SecureDigital device\n");
         exit(1);
     }
-    s->mmc = omap_mmc_init(0xfffb7800, drives_table[sdindex].bdrv,
+    s->mmc = omap_mmc_init(0xfffb7800, dinfo->bdrv,
                     s->irq[1][OMAP_INT_OQN], &s->drq[OMAP_DMA_MMC_TX],
                     omap_findclk(s, "mmc_ck"));
 
diff --git a/hw/omap2.c b/hw/omap2.c
index f91d678..bf2f664 100644
--- a/hw/omap2.c
+++ b/hw/omap2.c
@@ -4497,7 +4497,7 @@ struct omap_mpu_state_s *omap2420_mpu_init(unsigned long sdram_size,
     qemu_irq *cpu_irq;
     qemu_irq dma_irqs[4];
     omap_clk gpio_clks[4];
-    int sdindex;
+    DriveInfo *dinfo;
     int i;
 
     /* Core */
@@ -4646,12 +4646,12 @@ struct omap_mpu_state_s *omap2420_mpu_init(unsigned long sdram_size,
     s->sdrc = omap_sdrc_init(0x68009000);
     s->gpmc = omap_gpmc_init(0x6800a000, s->irq[0][OMAP_INT_24XX_GPMC_IRQ]);
 
-    sdindex = drive_get_index(IF_SD, 0, 0);
-    if (sdindex == -1) {
+    dinfo = drive_get(IF_SD, 0, 0);
+    if (!dinfo) {
         fprintf(stderr, "qemu: missing SecureDigital device\n");
         exit(1);
     }
-    s->mmc = omap2_mmc_init(omap_l4tao(s->l4, 9), drives_table[sdindex].bdrv,
+    s->mmc = omap2_mmc_init(omap_l4tao(s->l4, 9), dinfo->bdrv,
                     s->irq[0][OMAP_INT_24XX_MMC_IRQ],
                     &s->drq[OMAP24XX_DMA_MMC1_TX],
                     omap_findclk(s, "mmc_fclk"), omap_findclk(s, "mmc_iclk"));
diff --git a/hw/omap_sx1.c b/hw/omap_sx1.c
index 0f6ed9e..cc91855 100644
--- a/hw/omap_sx1.c
+++ b/hw/omap_sx1.c
@@ -128,7 +128,7 @@ static void sx1_init(ram_addr_t ram_size,
     static uint32_t cs2val = 0x00001139;
     static uint32_t cs3val = 0x00001139;
     ram_addr_t phys_flash;
-    int index;
+    DriveInfo *dinfo;
     int fl_idx;
     uint32_t flash_size = flash0_size;
 
@@ -152,9 +152,9 @@ static void sx1_init(ram_addr_t ram_size,
 
     fl_idx = 0;
 
-    if ((index = drive_get_index(IF_PFLASH, 0, fl_idx)) > -1) {
+    if ((dinfo = drive_get(IF_PFLASH, 0, fl_idx)) != NULL) {
         if (!pflash_cfi01_register(OMAP_CS0_BASE, qemu_ram_alloc(flash_size),
-            drives_table[index].bdrv, sector_size, flash_size / sector_size,
+            dinfo->bdrv, sector_size, flash_size / sector_size,
             4, 0, 0, 0, 0)) {
             fprintf(stderr, "qemu: Error registering flash memory %d.\n",
                            fl_idx);
@@ -163,7 +163,7 @@ static void sx1_init(ram_addr_t ram_size,
     }
 
     if ((version == 1) &&
-            (index = drive_get_index(IF_PFLASH, 0, fl_idx)) > -1) {
+            (dinfo = drive_get(IF_PFLASH, 0, fl_idx)) != NULL) {
         cpu_register_physical_memory(OMAP_CS1_BASE, flash1_size,
                         (phys_flash = qemu_ram_alloc(flash1_size)) |
                         IO_MEM_ROM);
@@ -172,7 +172,7 @@ static void sx1_init(ram_addr_t ram_size,
                         OMAP_CS1_SIZE - flash1_size, io);
 
         if (!pflash_cfi01_register(OMAP_CS1_BASE, qemu_ram_alloc(flash1_size),
-            drives_table[index].bdrv, sector_size, flash1_size / sector_size,
+            dinfo->bdrv, sector_size, flash1_size / sector_size,
             4, 0, 0, 0, 0)) {
             fprintf(stderr, "qemu: Error registering flash memory %d.\n",
                            fl_idx);
diff --git a/hw/onenand.c b/hw/onenand.c
index 7388e7c..f8f2f05 100644
--- a/hw/onenand.c
+++ b/hw/onenand.c
@@ -619,7 +619,7 @@ static CPUWriteMemoryFunc *onenand_writefn[] = {
 void *onenand_init(uint32_t id, int regshift, qemu_irq irq)
 {
     OneNANDState *s = (OneNANDState *) qemu_mallocz(sizeof(*s));
-    int bdrv_index = drive_get_index(IF_MTD, 0, 0);
+    DriveInfo *dinfo = drive_get(IF_MTD, 0, 0);
     uint32_t size = 1 << (24 + ((id >> 12) & 7));
     void *ram;
 
@@ -633,11 +633,11 @@ void *onenand_init(uint32_t id, int regshift, qemu_irq irq)
     s->density_mask = (id & (1 << 11)) ? (1 << (6 + ((id >> 12) & 7))) : 0;
     s->iomemtype = cpu_register_io_memory(onenand_readfn,
                     onenand_writefn, s);
-    if (bdrv_index == -1)
+    if (!dinfo)
         s->image = memset(qemu_malloc(size + (size >> 5)),
                         0xff, size + (size >> 5));
     else
-        s->bdrv = drives_table[bdrv_index].bdrv;
+        s->bdrv = dinfo->bdrv;
     s->otp = memset(qemu_malloc((64 + 2) << PAGE_SHIFT),
                     0xff, (64 + 2) << PAGE_SHIFT);
     s->ram = qemu_ram_alloc(0xc000 << s->shift);
diff --git a/hw/pc.c b/hw/pc.c
index 553ba5c..204786a 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -1099,7 +1099,7 @@ static void pc_init1(ram_addr_t ram_size,
     CPUState *env;
     qemu_irq *cpu_irq;
     qemu_irq *i8259;
-    int index;
+    DriveInfo *dinfo;
     BlockDriverState *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
     BlockDriverState *fd[MAX_FD];
     int using_vga = cirrus_vga_enabled || std_vga_enabled || vmsvga_enabled;
@@ -1328,11 +1328,8 @@ static void pc_init1(ram_addr_t ram_size,
     }
 
     for(i = 0; i < MAX_IDE_BUS * MAX_IDE_DEVS; i++) {
-        index = drive_get_index(IF_IDE, i / MAX_IDE_DEVS, i % MAX_IDE_DEVS);
-	if (index != -1)
-	    hd[i] = drives_table[index].bdrv;
-	else
-	    hd[i] = NULL;
+        dinfo = drive_get(IF_IDE, i / MAX_IDE_DEVS, i % MAX_IDE_DEVS);
+        hd[i] = dinfo ? dinfo->bdrv : NULL;
     }
 
     if (pci_enabled) {
@@ -1351,11 +1348,8 @@ static void pc_init1(ram_addr_t ram_size,
 #endif
 
     for(i = 0; i < MAX_FD; i++) {
-        index = drive_get_index(IF_FLOPPY, 0, i);
-	if (index != -1)
-	    fd[i] = drives_table[index].bdrv;
-	else
-	    fd[i] = NULL;
+        dinfo = drive_get(IF_FLOPPY, 0, i);
+        fd[i] = dinfo ? dinfo->bdrv : NULL;
     }
     floppy_controller = fdctrl_init(i8259[6], 2, 0, 0x3f0, fd);
 
@@ -1396,12 +1390,11 @@ static void pc_init1(ram_addr_t ram_size,
 
     /* Add virtio block devices */
     if (pci_enabled) {
-        int index;
         int unit_id = 0;
 
-        while ((index = drive_get_index(IF_VIRTIO, 0, unit_id)) != -1) {
+        while ((dinfo = drive_get(IF_VIRTIO, 0, unit_id)) != NULL) {
             pci_dev = pci_create("virtio-blk-pci",
-                                 drives_table[index].devaddr);
+                                 dinfo->devaddr);
             qdev_init(&pci_dev->qdev);
             unit_id++;
         }
diff --git a/hw/pci-hotplug.c b/hw/pci-hotplug.c
index d0f2911..43675e2 100644
--- a/hw/pci-hotplug.c
+++ b/hw/pci-hotplug.c
@@ -52,9 +52,10 @@ void drive_hot_add(Monitor *mon, const char *pci_addr, const char *opts)
 {
     int dom, pci_bus;
     unsigned slot;
-    int drive_idx, type, bus;
+    int type, bus;
     int success = 0;
     PCIDevice *dev;
+    DriveInfo *dinfo;
 
     if (pci_read_devaddr(mon, pci_addr, &dom, &pci_bus, &slot)) {
         return;
@@ -66,21 +67,21 @@ void drive_hot_add(Monitor *mon, const char *pci_addr, const char *opts)
         return;
     }
 
-    drive_idx = add_init_drive(opts);
-    if (drive_idx < 0)
+    dinfo = add_init_drive(opts);
+    if (!dinfo)
         return;
-    if (drives_table[drive_idx].devaddr) {
+    if (dinfo->devaddr) {
         monitor_printf(mon, "Parameter addr not supported\n");
         return;
     }
-    type = drives_table[drive_idx].type;
+    type = dinfo->type;
     bus = drive_get_max_bus (type);
 
     switch (type) {
     case IF_SCSI:
         success = 1;
-        lsi_scsi_attach(&dev->qdev, drives_table[drive_idx].bdrv,
-                        drives_table[drive_idx].unit);
+        lsi_scsi_attach(&dev->qdev, dinfo->bdrv,
+                        dinfo->unit);
         break;
     default:
         monitor_printf(mon, "Can't hot-add drive to type %d\n", type);
@@ -88,8 +89,8 @@ void drive_hot_add(Monitor *mon, const char *pci_addr, const char *opts)
 
     if (success)
         monitor_printf(mon, "OK bus %d, unit %d\n",
-                       drives_table[drive_idx].bus,
-                       drives_table[drive_idx].unit);
+                       dinfo->bus,
+                       dinfo->unit);
     return;
 }
 
@@ -98,7 +99,8 @@ static PCIDevice *qemu_pci_hot_add_storage(Monitor *mon,
                                            const char *opts)
 {
     PCIDevice *dev;
-    int type = -1, drive_idx = -1;
+    DriveInfo *dinfo;
+    int type = -1;
     char buf[128];
 
     if (get_param_value(buf, sizeof(buf), "if", opts)) {
@@ -116,10 +118,10 @@ static PCIDevice *qemu_pci_hot_add_storage(Monitor *mon,
     }
 
     if (get_param_value(buf, sizeof(buf), "file", opts)) {
-        drive_idx = add_init_drive(opts);
-        if (drive_idx < 0)
+        dinfo = add_init_drive(opts);
+        if (!dinfo)
             return NULL;
-        if (drives_table[drive_idx].devaddr) {
+        if (dinfo->devaddr) {
             monitor_printf(mon, "Parameter addr not supported\n");
             return NULL;
         }
diff --git a/hw/petalogix_s3adsp1800_mmu.c b/hw/petalogix_s3adsp1800_mmu.c
index c2a196f..1a1cc0e 100644
--- a/hw/petalogix_s3adsp1800_mmu.c
+++ b/hw/petalogix_s3adsp1800_mmu.c
@@ -106,6 +106,7 @@ petalogix_s3adsp1800_init(ram_addr_t ram_size,
     DeviceState *dev;
     CPUState *env;
     int kernel_size;
+    DriveInfo *dinfo;
     int i;
     target_phys_addr_t ddr_base = 0x90000000;
     ram_addr_t phys_lmb_bram;
@@ -131,9 +132,9 @@ petalogix_s3adsp1800_init(ram_addr_t ram_size,
     cpu_register_physical_memory(ddr_base, ram_size, phys_ram | IO_MEM_RAM);
 
     phys_flash = qemu_ram_alloc(FLASH_SIZE);
-    i = drive_get_index(IF_PFLASH, 0, 0);
+    dinfo = drive_get(IF_PFLASH, 0, 0);
     pflash_cfi02_register(0xa0000000, phys_flash,
-                          i != -1 ? drives_table[i].bdrv : NULL, (64 * 1024),
+                          dinfo ? dinfo->bdrv : NULL, (64 * 1024),
                           FLASH_SIZE >> 16,
                           1, 1, 0x0000, 0x0000, 0x0000, 0x0000,
                           0x555, 0x2aa);
diff --git a/hw/ppc405_boards.c b/hw/ppc405_boards.c
index c9a1986..f2b4a84 100644
--- a/hw/ppc405_boards.c
+++ b/hw/ppc405_boards.c
@@ -188,7 +188,7 @@ static void ref405ep_init (ram_addr_t ram_size,
     int linux_boot;
     int fl_idx, fl_sectors, len;
     int ppc_boot_device = boot_device[0];
-    int index;
+    DriveInfo *dinfo;
 
     /* XXX: fix this */
     ram_bases[0] = qemu_ram_alloc(0x08000000);
@@ -215,19 +215,19 @@ static void ref405ep_init (ram_addr_t ram_size,
 #endif
     fl_idx = 0;
 #ifdef USE_FLASH_BIOS
-    index = drive_get_index(IF_PFLASH, 0, fl_idx);
-    if (index != -1) {
-        bios_size = bdrv_getlength(drives_table[index].bdrv);
+    dinfo = drive_get(IF_PFLASH, 0, fl_idx);
+    if (dinfo) {
+        bios_size = bdrv_getlength(dinfo->bdrv);
         bios_offset = qemu_ram_alloc(bios_size);
         fl_sectors = (bios_size + 65535) >> 16;
 #ifdef DEBUG_BOARD_INIT
         printf("Register parallel flash %d size " ADDRX " at offset %08lx "
                " addr " ADDRX " '%s' %d\n",
                fl_idx, bios_size, bios_offset, -bios_size,
-               bdrv_get_device_name(drives_table[index].bdrv), fl_sectors);
+               bdrv_get_device_name(dinfo->bdrv), fl_sectors);
 #endif
         pflash_cfi02_register((uint32_t)(-bios_size), bios_offset,
-                              drives_table[index].bdrv, 65536, fl_sectors, 1,
+                              dinfo->bdrv, 65536, fl_sectors, 1,
                               2, 0x0001, 0x22DA, 0x0000, 0x0000, 0x555, 0x2AA);
         fl_idx++;
     } else
@@ -509,7 +509,7 @@ static void taihu_405ep_init(ram_addr_t ram_size,
     int linux_boot;
     int fl_idx, fl_sectors;
     int ppc_boot_device = boot_device[0];
-    int index;
+    DriveInfo *dinfo;
 
     /* RAM is soldered to the board so the size cannot be changed */
     ram_bases[0] = qemu_ram_alloc(0x04000000);
@@ -528,9 +528,9 @@ static void taihu_405ep_init(ram_addr_t ram_size,
 #endif
     fl_idx = 0;
 #if defined(USE_FLASH_BIOS)
-    index = drive_get_index(IF_PFLASH, 0, fl_idx);
-    if (index != -1) {
-        bios_size = bdrv_getlength(drives_table[index].bdrv);
+    dinfo = drive_get(IF_PFLASH, 0, fl_idx);
+    if (dinfo) {
+        bios_size = bdrv_getlength(dinfo->bdrv);
         /* XXX: should check that size is 2MB */
         //        bios_size = 2 * 1024 * 1024;
         fl_sectors = (bios_size + 65535) >> 16;
@@ -539,10 +539,10 @@ static void taihu_405ep_init(ram_addr_t ram_size,
         printf("Register parallel flash %d size " ADDRX " at offset %08lx "
                " addr " ADDRX " '%s' %d\n",
                fl_idx, bios_size, bios_offset, -bios_size,
-               bdrv_get_device_name(drives_table[index].bdrv), fl_sectors);
+               bdrv_get_device_name(dinfo->bdrv), fl_sectors);
 #endif
         pflash_cfi02_register((uint32_t)(-bios_size), bios_offset,
-                              drives_table[index].bdrv, 65536, fl_sectors, 1,
+                              dinfo->bdrv, 65536, fl_sectors, 1,
                               4, 0x0001, 0x22DA, 0x0000, 0x0000, 0x555, 0x2AA);
         fl_idx++;
     } else
@@ -570,9 +570,9 @@ static void taihu_405ep_init(ram_addr_t ram_size,
                                      bios_size, bios_offset | IO_MEM_ROM);
     }
     /* Register Linux flash */
-    index = drive_get_index(IF_PFLASH, 0, fl_idx);
-    if (index != -1) {
-        bios_size = bdrv_getlength(drives_table[index].bdrv);
+    dinfo = drive_get(IF_PFLASH, 0, fl_idx);
+    if (dinfo) {
+        bios_size = bdrv_getlength(dinfo->bdrv);
         /* XXX: should check that size is 32MB */
         bios_size = 32 * 1024 * 1024;
         fl_sectors = (bios_size + 65535) >> 16;
@@ -580,11 +580,11 @@ static void taihu_405ep_init(ram_addr_t ram_size,
         printf("Register parallel flash %d size " ADDRX " at offset %08lx "
                " addr " ADDRX " '%s'\n",
                fl_idx, bios_size, bios_offset, (target_ulong)0xfc000000,
-               bdrv_get_device_name(drives_table[index].bdrv));
+               bdrv_get_device_name(dinfo->bdrv));
 #endif
         bios_offset = qemu_ram_alloc(bios_size);
         pflash_cfi02_register(0xfc000000, bios_offset,
-                              drives_table[index].bdrv, 65536, fl_sectors, 1,
+                              dinfo->bdrv, 65536, fl_sectors, 1,
                               4, 0x0001, 0x22DA, 0x0000, 0x0000, 0x555, 0x2AA);
         fl_idx++;
     }
diff --git a/hw/ppc440_bamboo.c b/hw/ppc440_bamboo.c
index d9ef3ec..624e15b 100644
--- a/hw/ppc440_bamboo.c
+++ b/hw/ppc440_bamboo.c
@@ -102,6 +102,7 @@ static void bamboo_init(ram_addr_t ram_size,
     target_ulong dt_base = 0;
     void *fdt;
     int i;
+    DriveInfo *dinfo;
 
     /* Setup CPU. */
     env = ppc440ep_init(&ram_size, &pcibus, pci_irq_nrs, 1, cpu_model);
@@ -110,8 +111,8 @@ static void bamboo_init(ram_addr_t ram_size,
         int unit_id = 0;
 
         /* Add virtio block devices. */
-        while ((i = drive_get_index(IF_VIRTIO, 0, unit_id)) != -1) {
-            pci_dev = pci_create("virtio-blk-pci", drives_table[i].devaddr);
+        while ((dinfo = drive_get(IF_VIRTIO, 0, unit_id)) != NULL) {
+            pci_dev = pci_create("virtio-blk-pci", dinfo->devaddr);
             qdev_init(&pci_dev->qdev);
             unit_id++;
         }
diff --git a/hw/ppc_newworld.c b/hw/ppc_newworld.c
index 4e5043c..caab74e 100644
--- a/hw/ppc_newworld.c
+++ b/hw/ppc_newworld.c
@@ -106,7 +106,7 @@ static void ppc_core99_init (ram_addr_t ram_size,
     qemu_irq *dummy_irq;
     int pic_mem_index, dbdma_mem_index, cuda_mem_index, escc_mem_index;
     int ppc_boot_device;
-    int index;
+    DriveInfo *dinfo;
     BlockDriverState *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
     void *fw_cfg;
     void *dbdma;
@@ -311,11 +311,8 @@ static void ppc_core99_init (ram_addr_t ram_size,
         exit(1);
     }
     for(i = 0; i < MAX_IDE_BUS * MAX_IDE_DEVS; i++) {
-        index = drive_get_index(IF_IDE, i / MAX_IDE_DEVS, i % MAX_IDE_DEVS);
-        if (index != -1)
-            hd[i] = drives_table[index].bdrv;
-        else
-            hd[i] = NULL;
+        dinfo = drive_get(IF_IDE, i / MAX_IDE_DEVS, i % MAX_IDE_DEVS);
+        hd[i] = dinfo ? dinfo->bdrv : NULL;
     }
     dbdma = DBDMA_init(&dbdma_mem_index);
     pci_cmd646_ide_init(pci_bus, hd, 0);
diff --git a/hw/ppc_oldworld.c b/hw/ppc_oldworld.c
index b26e407..388db31 100644
--- a/hw/ppc_oldworld.c
+++ b/hw/ppc_oldworld.c
@@ -135,7 +135,7 @@ static void ppc_heathrow_init (ram_addr_t ram_size,
     int escc_mem_index, ide_mem_index[2];
     uint16_t ppc_boot_device;
     BlockDriverState *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
-    int index;
+    DriveInfo *dinfo;
     void *fw_cfg;
     void *dbdma;
     uint8_t *vga_bios_ptr;
@@ -324,31 +324,19 @@ static void ppc_heathrow_init (ram_addr_t ram_size,
     }
 
     /* First IDE channel is a MAC IDE on the MacIO bus */
-    index = drive_get_index(IF_IDE, 0, 0);
-    if (index == -1)
-        hd[0] = NULL;
-    else
-        hd[0] =  drives_table[index].bdrv;
-    index = drive_get_index(IF_IDE, 0, 1);
-    if (index == -1)
-        hd[1] = NULL;
-    else
-        hd[1] =  drives_table[index].bdrv;
+    dinfo = drive_get(IF_IDE, 0, 0);
+    hd[0] = dinfo ? dinfo->bdrv : NULL;
+    dinfo = drive_get(IF_IDE, 0, 1);
+    hd[1] = dinfo ? dinfo->bdrv : NULL;
     dbdma = DBDMA_init(&dbdma_mem_index);
     ide_mem_index[0] = -1;
     ide_mem_index[1] = pmac_ide_init(hd, pic[0x0D], dbdma, 0x16, pic[0x02]);
 
     /* Second IDE channel is a CMD646 on the PCI bus */
-    index = drive_get_index(IF_IDE, 1, 0);
-    if (index == -1)
-        hd[0] = NULL;
-    else
-        hd[0] =  drives_table[index].bdrv;
-    index = drive_get_index(IF_IDE, 1, 1);
-    if (index == -1)
-        hd[1] = NULL;
-    else
-        hd[1] =  drives_table[index].bdrv;
+    dinfo = drive_get(IF_IDE, 1, 0);
+    hd[0] = dinfo ? dinfo->bdrv : NULL;
+    dinfo = drive_get(IF_IDE, 1, 1);
+    hd[1] = dinfo ? dinfo->bdrv : NULL;
     hd[3] = hd[2] = NULL;
     pci_cmd646_ide_init(pci_bus, hd, 0);
 
diff --git a/hw/ppc_prep.c b/hw/ppc_prep.c
index 7181181..27509c9 100644
--- a/hw/ppc_prep.c
+++ b/hw/ppc_prep.c
@@ -549,7 +549,7 @@ static void ppc_prep_init (ram_addr_t ram_size,
     PCIBus *pci_bus;
     qemu_irq *i8259;
     int ppc_boot_device;
-    int index;
+    DriveInfo *dinfo;
     BlockDriverState *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
     BlockDriverState *fd[MAX_FD];
 
@@ -690,11 +690,8 @@ static void ppc_prep_init (ram_addr_t ram_size,
     }
 
     for(i = 0; i < MAX_IDE_BUS * MAX_IDE_DEVS; i++) {
-        index = drive_get_index(IF_IDE, i / MAX_IDE_DEVS, i % MAX_IDE_DEVS);
-        if (index != -1)
-            hd[i] = drives_table[index].bdrv;
-        else
-            hd[i] = NULL;
+        dinfo = drive_get(IF_IDE, i / MAX_IDE_DEVS, i % MAX_IDE_DEVS);
+        hd[i] = dinfo ? dinfo->bdrv : NULL;
     }
 
     for(i = 0; i < MAX_IDE_BUS; i++) {
@@ -707,11 +704,8 @@ static void ppc_prep_init (ram_addr_t ram_size,
     //    SB16_init();
 
     for(i = 0; i < MAX_FD; i++) {
-        index = drive_get_index(IF_FLOPPY, 0, i);
-        if (index != -1)
-            fd[i] = drives_table[index].bdrv;
-        else
-            fd[i] = NULL;
+        dinfo = drive_get(IF_FLOPPY, 0, i);
+        fd[i] = dinfo ? dinfo->bdrv : NULL;
     }
     fdctrl_init(i8259[6], 2, 0, 0x3f0, fd);
 
diff --git a/hw/ppce500_mpc8544ds.c b/hw/ppce500_mpc8544ds.c
index c0e367d..04c6acd 100644
--- a/hw/ppce500_mpc8544ds.c
+++ b/hw/ppce500_mpc8544ds.c
@@ -172,6 +172,7 @@ static void mpc8544ds_init(ram_addr_t ram_size,
     unsigned int pci_irq_nrs[4] = {1, 2, 3, 4};
     qemu_irq *irqs, *mpic, *pci_irqs;
     SerialState * serial[2];
+    DriveInfo *dinfo;
 
     /* Setup CPU */
     env = cpu_ppc_init("e500v2_v30");
@@ -219,8 +220,8 @@ static void mpc8544ds_init(ram_addr_t ram_size,
         int unit_id = 0;
 
         /* Add virtio block devices. */
-        while ((i = drive_get_index(IF_VIRTIO, 0, unit_id)) != -1) {
-            pci_dev = pci_create("virtio-blk-pci", drives_table[i].devaddr);
+        while ((dinfo = drive_get(IF_VIRTIO, 0, unit_id)) != NULL) {
+            pci_dev = pci_create("virtio-blk-pci", dinfo->devaddr);
             qdev_init(&pci_dev->qdev);
             unit_id++;
         }
diff --git a/hw/pxa2xx.c b/hw/pxa2xx.c
index f2e98ff..28e9610 100644
--- a/hw/pxa2xx.c
+++ b/hw/pxa2xx.c
@@ -2034,7 +2034,7 @@ PXA2xxState *pxa270_init(unsigned int sdram_size, const char *revision)
 {
     PXA2xxState *s;
     int iomemtype, i;
-    int index;
+    DriveInfo *dinfo;
     s = (PXA2xxState *) qemu_mallocz(sizeof(PXA2xxState));
 
     if (revision && strncmp(revision, "pxa27", 5)) {
@@ -2066,12 +2066,12 @@ PXA2xxState *pxa270_init(unsigned int sdram_size, const char *revision)
 
     s->gpio = pxa2xx_gpio_init(0x40e00000, s->env, s->pic, 121);
 
-    index = drive_get_index(IF_SD, 0, 0);
-    if (index == -1) {
+    dinfo = drive_get(IF_SD, 0, 0);
+    if (!dinfo) {
         fprintf(stderr, "qemu: missing SecureDigital device\n");
         exit(1);
     }
-    s->mmc = pxa2xx_mmci_init(0x41100000, drives_table[index].bdrv,
+    s->mmc = pxa2xx_mmci_init(0x41100000, dinfo->bdrv,
                               s->pic[PXA2XX_PIC_MMC], s->dma);
 
     for (i = 0; pxa270_serial[i].io_base; i ++)
@@ -2153,7 +2153,7 @@ PXA2xxState *pxa255_init(unsigned int sdram_size)
 {
     PXA2xxState *s;
     int iomemtype, i;
-    int index;
+    DriveInfo *dinfo;
 
     s = (PXA2xxState *) qemu_mallocz(sizeof(PXA2xxState));
 
@@ -2178,12 +2178,12 @@ PXA2xxState *pxa255_init(unsigned int sdram_size)
 
     s->gpio = pxa2xx_gpio_init(0x40e00000, s->env, s->pic, 85);
 
-    index = drive_get_index(IF_SD, 0, 0);
-    if (index == -1) {
+    dinfo = drive_get(IF_SD, 0, 0);
+    if (!dinfo) {
         fprintf(stderr, "qemu: missing SecureDigital device\n");
         exit(1);
     }
-    s->mmc = pxa2xx_mmci_init(0x41100000, drives_table[index].bdrv,
+    s->mmc = pxa2xx_mmci_init(0x41100000, dinfo->bdrv,
                               s->pic[PXA2XX_PIC_MMC], s->dma);
 
     for (i = 0; pxa255_serial[i].io_base; i ++)
diff --git a/hw/qdev.c b/hw/qdev.c
index 83e98bf..8f02150 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -269,13 +269,10 @@ static int next_block_unit[IF_COUNT];
 BlockDriverState *qdev_init_bdrv(DeviceState *dev, BlockInterfaceType type)
 {
     int unit = next_block_unit[type]++;
-    int index;
+    DriveInfo *dinfo;
 
-    index = drive_get_index(type, 0, unit);
-    if (index == -1) {
-        return NULL;
-    }
-    return drives_table[index].bdrv;
+    dinfo = drive_get(type, 0, unit);
+    return dinfo ? dinfo->bdrv : NULL;
 }
 
 BusState *qdev_get_child_bus(DeviceState *dev, const char *name)
@@ -298,14 +295,14 @@ void scsi_bus_new(DeviceState *host, SCSIAttachFn attach)
 {
    int bus = next_scsi_bus++;
    int unit;
-   int index;
+   DriveInfo *dinfo;
 
    for (unit = 0; unit < MAX_SCSI_DEVS; unit++) {
-       index = drive_get_index(IF_SCSI, bus, unit);
-       if (index == -1) {
+       dinfo = drive_get(IF_SCSI, bus, unit);
+       if (!dinfo) {
            continue;
        }
-       attach(host, drives_table[index].bdrv, unit);
+       attach(host, dinfo->bdrv, unit);
    }
 }
 
diff --git a/hw/r2d.c b/hw/r2d.c
index 8ce6832..697bcb6 100644
--- a/hw/r2d.c
+++ b/hw/r2d.c
@@ -203,6 +203,7 @@ static void r2d_init(ram_addr_t ram_size,
     ram_addr_t sdram_addr;
     qemu_irq *irq;
     PCIBus *pci;
+    DriveInfo *dinfo;
     int i;
 
     if (!cpu_model)
@@ -225,9 +226,9 @@ static void r2d_init(ram_addr_t ram_size,
     sm501_init(0x10000000, SM501_VRAM_SIZE, irq[SM501], serial_hds[2]);
 
     /* onboard CF (True IDE mode, Master only). */
-    if ((i = drive_get_index(IF_IDE, 0, 0)) != -1)
+    if ((dinfo = drive_get(IF_IDE, 0, 0)) != NULL)
 	mmio_ide_init(0x14001000, 0x1400080c, irq[CF_IDE], 1,
-		      drives_table[i].bdrv, NULL);
+		      dinfo->bdrv, NULL);
 
     /* NIC: rtl8139 on-board, and 2 slots. */
     for (i = 0; i < nb_nics; i++)
diff --git a/hw/spitz.c b/hw/spitz.c
index d9ff85e..36bf534 100644
--- a/hw/spitz.c
+++ b/hw/spitz.c
@@ -744,13 +744,13 @@ static void spitz_ssp_attach(PXA2xxState *cpu)
 static void spitz_microdrive_attach(PXA2xxState *cpu, int slot)
 {
     PCMCIACardState *md;
-    int index;
     BlockDriverState *bs;
+    DriveInfo *dinfo;
 
-    index = drive_get_index(IF_IDE, 0, 0);
-    if (index == -1)
+    dinfo = drive_get(IF_IDE, 0, 0);
+    if (!dinfo)
         return;
-    bs = drives_table[index].bdrv;
+    bs = dinfo->bdrv;
     if (bdrv_is_inserted(bs) && !bdrv_is_removable(bs)) {
         md = dscm1xxxx_init(bs);
         pxa2xx_pcmcia_attach(cpu->pcmcia[slot], md);
diff --git a/hw/sun4m.c b/hw/sun4m.c
index f9ef298..d2ac648 100644
--- a/hw/sun4m.c
+++ b/hw/sun4m.c
@@ -442,8 +442,8 @@ static void sun4m_hw_init(const struct sun4m_hwdef *hwdef, ram_addr_t RAM_size,
     int ret;
     char *filename;
     BlockDriverState *fd[MAX_FD];
-    int drive_index;
     void *fw_cfg;
+    DriveInfo *dinfo;
 
     /* init CPUs */
     if (!cpu_model)
@@ -563,9 +563,9 @@ static void sun4m_hw_init(const struct sun4m_hwdef *hwdef, ram_addr_t RAM_size,
     if (hwdef->fd_base) {
         /* there is zero or one floppy drive */
         memset(fd, 0, sizeof(fd));
-        drive_index = drive_get_index(IF_FLOPPY, 0, 0);
-        if (drive_index != -1)
-            fd[0] = drives_table[drive_index].bdrv;
+        dinfo = drive_get(IF_FLOPPY, 0, 0);
+        if (dinfo)
+            fd[0] = dinfo->bdrv;
 
         sun4m_fdctrl_init(slavio_irq[hwdef->fd_irq], hwdef->fd_base, fd,
                           &fdc_tc);
@@ -1451,8 +1451,8 @@ static void sun4c_hw_init(const struct sun4c_hwdef *hwdef, ram_addr_t RAM_size,
     int ret;
     char *filename;
     BlockDriverState *fd[MAX_FD];
-    int drive_index;
     void *fw_cfg;
+    DriveInfo *dinfo;
 
     /* init CPU */
     if (!cpu_model)
@@ -1547,9 +1547,9 @@ static void sun4c_hw_init(const struct sun4c_hwdef *hwdef, ram_addr_t RAM_size,
     if (hwdef->fd_base != (target_phys_addr_t)-1) {
         /* there is zero or one floppy drive */
         memset(fd, 0, sizeof(fd));
-        drive_index = drive_get_index(IF_FLOPPY, 0, 0);
-        if (drive_index != -1)
-            fd[0] = drives_table[drive_index].bdrv;
+        dinfo = drive_get(IF_FLOPPY, 0, 0);
+        if (dinfo)
+            fd[0] = dinfo->bdrv;
 
         sun4m_fdctrl_init(slavio_irq[hwdef->fd_irq], hwdef->fd_base, fd,
                           &fdc_tc);
diff --git a/hw/sun4u.c b/hw/sun4u.c
index 9d2a7f5..1fba1a4 100644
--- a/hw/sun4u.c
+++ b/hw/sun4u.c
@@ -358,11 +358,11 @@ static void sun4uv_init(ram_addr_t RAM_size,
     PCIBus *pci_bus, *pci_bus2, *pci_bus3;
     QEMUBH *bh;
     qemu_irq *irq;
-    int drive_index;
     BlockDriverState *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
     BlockDriverState *fd[MAX_FD];
     void *fw_cfg;
     ResetData *reset_info;
+    DriveInfo *dinfo;
 
     linux_boot = (kernel_filename != NULL);
 
@@ -504,12 +504,9 @@ static void sun4uv_init(ram_addr_t RAM_size,
         exit(1);
     }
     for(i = 0; i < MAX_IDE_BUS * MAX_IDE_DEVS; i++) {
-        drive_index = drive_get_index(IF_IDE, i / MAX_IDE_DEVS,
-                                      i % MAX_IDE_DEVS);
-       if (drive_index != -1)
-           hd[i] = drives_table[drive_index].bdrv;
-       else
-           hd[i] = NULL;
+        dinfo = drive_get(IF_IDE, i / MAX_IDE_DEVS,
+                          i % MAX_IDE_DEVS);
+        hd[i] = dinfo ? dinfo->bdrv : NULL;
     }
 
     pci_cmd646_ide_init(pci_bus, hd, 1);
@@ -517,11 +514,8 @@ static void sun4uv_init(ram_addr_t RAM_size,
     /* FIXME: wire up interrupts.  */
     i8042_init(NULL/*1*/, NULL/*12*/, 0x60);
     for(i = 0; i < MAX_FD; i++) {
-        drive_index = drive_get_index(IF_FLOPPY, 0, i);
-       if (drive_index != -1)
-           fd[i] = drives_table[drive_index].bdrv;
-       else
-           fd[i] = NULL;
+        dinfo = drive_get(IF_FLOPPY, 0, i);
+        fd[i] = dinfo ? dinfo->bdrv : NULL;
     }
     floppy_controller = fdctrl_init(NULL/*6*/, 2, 0, 0x3f0, fd);
     nvram = m48t59_init(NULL/*8*/, 0, 0x0074, NVRAM_SIZE, 59);
diff --git a/hw/tosa.c b/hw/tosa.c
index b2d66f3..b932efc 100644
--- a/hw/tosa.c
+++ b/hw/tosa.c
@@ -49,13 +49,13 @@
 static void tosa_microdrive_attach(PXA2xxState *cpu)
 {
     PCMCIACardState *md;
-    int index;
     BlockDriverState *bs;
+    DriveInfo *dinfo;
 
-    index = drive_get_index(IF_IDE, 0, 0);
-    if (index == -1)
+    dinfo = drive_get(IF_IDE, 0, 0);
+    if (!dinfo)
         return;
-    bs = drives_table[index].bdrv;
+    bs = dinfo->bdrv;
     if (bdrv_is_inserted(bs) && !bdrv_is_removable(bs)) {
         md = dscm1xxxx_init(bs);
         pxa2xx_pcmcia_attach(cpu->pcmcia[0], md);
diff --git a/monitor.c b/monitor.c
index 342af32..4afb7d0 100644
--- a/monitor.c
+++ b/monitor.c
@@ -244,13 +244,15 @@ static void help_cmd(Monitor *mon, const char *name)
 
 static void do_commit(Monitor *mon, const char *device)
 {
-    int i, all_devices;
+    int all_devices;
+    DriveInfo *dinfo;
 
     all_devices = !strcmp(device, "all");
-    for (i = 0; i < nb_drives; i++) {
-            if (all_devices ||
-                !strcmp(bdrv_get_device_name(drives_table[i].bdrv), device))
-                bdrv_commit(drives_table[i].bdrv);
+    TAILQ_FOREACH(dinfo, &drives, next) {
+        if (!all_devices)
+            if (!strcmp(bdrv_get_device_name(dinfo->bdrv), device))
+                continue;
+        bdrv_commit(dinfo->bdrv);
     }
 }
 
diff --git a/qemu-char.c b/qemu-char.c
index 287e0cd..a7d8fb6 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -345,10 +345,12 @@ static int mux_proc_byte(CharDriverState *chr, MuxDriver *d, int ch)
             }
         case 's':
             {
+#if 0
                 int i;
                 for (i = 0; i < nb_drives; i++) {
                         bdrv_commit(drives_table[i].bdrv);
                 }
+#endif
             }
             break;
         case 'b':
diff --git a/savevm.c b/savevm.c
index 17da35a..dc05a48 100644
--- a/savevm.c
+++ b/savevm.c
@@ -1027,12 +1027,12 @@ static int bdrv_has_snapshot(BlockDriverState *bs)
 static BlockDriverState *get_bs_snapshots(void)
 {
     BlockDriverState *bs;
-    int i;
+    DriveInfo *dinfo;
 
     if (bs_snapshots)
         return bs_snapshots;
-    for(i = 0; i <= nb_drives; i++) {
-        bs = drives_table[i].bdrv;
+    TAILQ_FOREACH(dinfo, &drives, next) {
+        bs = dinfo->bdrv;
         if (bdrv_can_snapshot(bs))
             goto ok;
     }
@@ -1066,9 +1066,10 @@ static int bdrv_snapshot_find(BlockDriverState *bs, QEMUSnapshotInfo *sn_info,
 
 void do_savevm(Monitor *mon, const char *name)
 {
+    DriveInfo *dinfo;
     BlockDriverState *bs, *bs1;
     QEMUSnapshotInfo sn1, *sn = &sn1, old_sn1, *old_sn = &old_sn1;
-    int must_delete, ret, i;
+    int must_delete, ret;
     BlockDriverInfo bdi1, *bdi = &bdi1;
     QEMUFile *f;
     int saved_vm_running;
@@ -1141,8 +1142,8 @@ void do_savevm(Monitor *mon, const char *name)
 
     /* create the snapshots */
 
-    for(i = 0; i < nb_drives; i++) {
-        bs1 = drives_table[i].bdrv;
+    TAILQ_FOREACH(dinfo, &drives, next) {
+        bs1 = dinfo->bdrv;
         if (bdrv_has_snapshot(bs1)) {
             if (must_delete) {
                 ret = bdrv_snapshot_delete(bs1, old_sn->id_str);
@@ -1169,11 +1170,12 @@ void do_savevm(Monitor *mon, const char *name)
 
 void do_loadvm(Monitor *mon, const char *name)
 {
+    DriveInfo *dinfo;
     BlockDriverState *bs, *bs1;
     BlockDriverInfo bdi1, *bdi = &bdi1;
     QEMUSnapshotInfo sn;
     QEMUFile *f;
-    int i, ret;
+    int ret;
     int saved_vm_running;
 
     bs = get_bs_snapshots();
@@ -1188,8 +1190,8 @@ void do_loadvm(Monitor *mon, const char *name)
     saved_vm_running = vm_running;
     vm_stop(0);
 
-    for(i = 0; i <= nb_drives; i++) {
-        bs1 = drives_table[i].bdrv;
+    TAILQ_FOREACH(dinfo, &drives, next) {
+        bs1 = dinfo->bdrv;
         if (bdrv_has_snapshot(bs1)) {
             ret = bdrv_snapshot_goto(bs1, name);
             if (ret < 0) {
@@ -1247,8 +1249,9 @@ void do_loadvm(Monitor *mon, const char *name)
 
 void do_delvm(Monitor *mon, const char *name)
 {
+    DriveInfo *dinfo;
     BlockDriverState *bs, *bs1;
-    int i, ret;
+    int ret;
 
     bs = get_bs_snapshots();
     if (!bs) {
@@ -1256,8 +1259,8 @@ void do_delvm(Monitor *mon, const char *name)
         return;
     }
 
-    for(i = 0; i <= nb_drives; i++) {
-        bs1 = drives_table[i].bdrv;
+    TAILQ_FOREACH(dinfo, &drives, next) {
+        bs1 = dinfo->bdrv;
         if (bdrv_has_snapshot(bs1)) {
             ret = bdrv_snapshot_delete(bs1, name);
             if (ret < 0) {
@@ -1275,6 +1278,7 @@ void do_delvm(Monitor *mon, const char *name)
 
 void do_info_snapshots(Monitor *mon)
 {
+    DriveInfo *dinfo;
     BlockDriverState *bs, *bs1;
     QEMUSnapshotInfo *sn_tab, *sn;
     int nb_sns, i;
@@ -1286,8 +1290,8 @@ void do_info_snapshots(Monitor *mon)
         return;
     }
     monitor_printf(mon, "Snapshot devices:");
-    for(i = 0; i <= nb_drives; i++) {
-        bs1 = drives_table[i].bdrv;
+    TAILQ_FOREACH(dinfo, &drives, next) {
+        bs1 = dinfo->bdrv;
         if (bdrv_has_snapshot(bs1)) {
             if (bs == bs1)
                 monitor_printf(mon, " %s", bdrv_get_device_name(bs1));
diff --git a/sysemu.h b/sysemu.h
index 06dc4c6..36d6aaa 100644
--- a/sysemu.h
+++ b/sysemu.h
@@ -3,6 +3,7 @@
 /* Misc. things related to the system emulator.  */
 
 #include "qemu-common.h"
+#include "sys-queue.h"
 
 #ifdef _WIN32
 #include <windows.h>
@@ -163,20 +164,19 @@ typedef struct DriveInfo {
     BlockInterfaceType type;
     int bus;
     int unit;
-    int used;
     int drive_opt_idx;
     BlockInterfaceErrorAction onerror;
     char serial[BLOCK_SERIAL_STRLEN + 1];
+    TAILQ_ENTRY(DriveInfo) next;
 } DriveInfo;
 
 #define MAX_IDE_DEVS	2
 #define MAX_SCSI_DEVS	7
 #define MAX_DRIVES 32
 
-extern int nb_drives;
-extern DriveInfo drives_table[MAX_DRIVES+1];
+extern TAILQ_HEAD(drivelist, DriveInfo) drives;
 
-extern int drive_get_index(BlockInterfaceType type, int bus, int unit);
+extern DriveInfo *drive_get(BlockInterfaceType type, int bus, int unit);
 extern int drive_get_max_bus(BlockInterfaceType type);
 extern void drive_uninit(BlockDriverState *bdrv);
 extern void drive_remove(int index);
@@ -195,7 +195,8 @@ extern struct drive_opt drives_opt[MAX_DRIVES];
 extern int nb_drives_opt;
 
 extern int drive_add(const char *file, const char *fmt, ...);
-extern int drive_init(struct drive_opt *arg, int snapshot, void *machine);
+extern DriveInfo *drive_init(struct drive_opt *arg, int snapshot, void *machine,
+                             int *fatal_error);
 
 /* acpi */
 typedef void (*qemu_system_device_hot_add_t)(int pcibus, int slot, int state);
@@ -206,7 +207,7 @@ void qemu_system_device_hot_add(int pcibus, int slot, int state);
 
 typedef int (dev_match_fn)(void *dev_private, void *arg);
 
-int add_init_drive(const char *opts);
+DriveInfo *add_init_drive(const char *opts);
 void destroy_nic(dev_match_fn *match_fn, void *arg);
 void destroy_bdrvs(dev_match_fn *match_fn, void *arg);
 
diff --git a/vl.c b/vl.c
index 50665cf..4dae7ad 100644
--- a/vl.c
+++ b/vl.c
@@ -183,8 +183,7 @@ static const char *data_dir;
 const char *bios_name = NULL;
 /* Note: drives_table[MAX_DRIVES] is a dummy block driver if none available
    to store the VM snapshots */
-DriveInfo drives_table[MAX_DRIVES+1];
-int nb_drives;
+struct drivelist drives = TAILQ_HEAD_INITIALIZER(drives);
 enum vga_retrace_method vga_retrace_method = VGA_RETRACE_DUMB;
 static DisplayState *display_state;
 DisplayType display_type = DT_DEFAULT;
@@ -1878,19 +1877,6 @@ static int drive_opt_get_free_idx(void)
     return -1;
 }
 
-static int drive_get_free_idx(void)
-{
-    int index;
-
-    for (index = 0; index < MAX_DRIVES; index++)
-        if (!drives_table[index].used) {
-            drives_table[index].used = 1;
-            return index;
-        }
-
-    return -1;
-}
-
 int drive_add(const char *file, const char *fmt, ...)
 {
     va_list ap;
@@ -1917,54 +1903,56 @@ void drive_remove(int index)
     nb_drives_opt--;
 }
 
-int drive_get_index(BlockInterfaceType type, int bus, int unit)
+DriveInfo *drive_get(BlockInterfaceType type, int bus, int unit)
 {
-    int index;
+    DriveInfo *dinfo;
 
     /* seek interface, bus and unit */
 
-    for (index = 0; index < MAX_DRIVES; index++)
-        if (drives_table[index].type == type &&
-	    drives_table[index].bus == bus &&
-	    drives_table[index].unit == unit &&
-	    drives_table[index].used)
-        return index;
+    TAILQ_FOREACH(dinfo, &drives, next) {
+        if (dinfo->type == type &&
+	    dinfo->bus == bus &&
+	    dinfo->unit == unit)
+            return dinfo;
+    }
 
-    return -1;
+    return NULL;
 }
 
 int drive_get_max_bus(BlockInterfaceType type)
 {
     int max_bus;
-    int index;
+    DriveInfo *dinfo;
 
     max_bus = -1;
-    for (index = 0; index < nb_drives; index++) {
-        if(drives_table[index].type == type &&
-           drives_table[index].bus > max_bus)
-            max_bus = drives_table[index].bus;
+    TAILQ_FOREACH(dinfo, &drives, next) {
+        if(dinfo->type == type &&
+           dinfo->bus > max_bus)
+            max_bus = dinfo->bus;
     }
     return max_bus;
 }
 
 const char *drive_get_serial(BlockDriverState *bdrv)
 {
-    int index;
+    DriveInfo *dinfo;
 
-    for (index = 0; index < nb_drives; index++)
-        if (drives_table[index].bdrv == bdrv)
-            return drives_table[index].serial;
+    TAILQ_FOREACH(dinfo, &drives, next) {
+        if (dinfo->bdrv == bdrv)
+            return dinfo->serial;
+    }
 
     return "\0";
 }
 
 BlockInterfaceErrorAction drive_get_onerror(BlockDriverState *bdrv)
 {
-    int index;
+    DriveInfo *dinfo;
 
-    for (index = 0; index < nb_drives; index++)
-        if (drives_table[index].bdrv == bdrv)
-            return drives_table[index].onerror;
+    TAILQ_FOREACH(dinfo, &drives, next) {
+        if (dinfo->bdrv == bdrv)
+            return dinfo->onerror;
+    }
 
     return BLOCK_ERR_STOP_ENOSPC;
 }
@@ -1976,19 +1964,20 @@ static void bdrv_format_print(void *opaque, const char *name)
 
 void drive_uninit(BlockDriverState *bdrv)
 {
-    int i;
+    DriveInfo *dinfo;
 
-    for (i = 0; i < MAX_DRIVES; i++)
-        if (drives_table[i].bdrv == bdrv) {
-            drives_table[i].bdrv = NULL;
-            drives_table[i].used = 0;
-            drive_remove(drives_table[i].drive_opt_idx);
-            nb_drives--;
-            break;
-        }
+    TAILQ_FOREACH(dinfo, &drives, next) {
+        if (dinfo->bdrv != bdrv)
+            continue;
+        drive_remove(dinfo->drive_opt_idx);
+        TAILQ_REMOVE(&drives, dinfo, next);
+        qemu_free(dinfo);
+        break;
+    }
 }
 
-int drive_init(struct drive_opt *arg, int snapshot, void *opaque)
+DriveInfo *drive_init(struct drive_opt *arg, int snapshot, void *opaque,
+                      int *fatal_error)
 {
     char buf[128];
     char file[1024];
@@ -2007,7 +1996,7 @@ int drive_init(struct drive_opt *arg, int snapshot, void *opaque)
     int cache;
     int bdrv_flags, onerror;
     const char *devaddr;
-    int drives_table_idx;
+    DriveInfo *dinfo;
     char *str = arg->opt;
     static const char * const params[] = { "bus", "unit", "if", "index",
                                            "cyls", "heads", "secs", "trans",
@@ -2015,11 +2004,12 @@ int drive_init(struct drive_opt *arg, int snapshot, void *opaque)
                                            "cache", "format", "serial",
                                            "werror", "addr",
                                            NULL };
+    *fatal_error = 1;
 
     if (check_params(buf, sizeof(buf), params, str) < 0) {
          fprintf(stderr, "qemu: unknown parameter '%s' in '%s'\n",
                          buf, str);
-         return -1;
+         return NULL;
     }
 
     file[0] = 0;
@@ -2047,7 +2037,7 @@ int drive_init(struct drive_opt *arg, int snapshot, void *opaque)
         bus_id = strtol(buf, NULL, 0);
 	if (bus_id < 0) {
 	    fprintf(stderr, "qemu: '%s' invalid bus id\n", str);
-	    return -1;
+	    return NULL;
 	}
     }
 
@@ -2055,7 +2045,7 @@ int drive_init(struct drive_opt *arg, int snapshot, void *opaque)
         unit_id = strtol(buf, NULL, 0);
 	if (unit_id < 0) {
 	    fprintf(stderr, "qemu: '%s' invalid unit id\n", str);
-	    return -1;
+	    return NULL;
 	}
     }
 
@@ -2087,7 +2077,7 @@ int drive_init(struct drive_opt *arg, int snapshot, void *opaque)
             max_devs = 0;
 	} else {
             fprintf(stderr, "qemu: '%s' unsupported bus type '%s'\n", str, buf);
-            return -1;
+            return NULL;
 	}
     }
 
@@ -2095,7 +2085,7 @@ int drive_init(struct drive_opt *arg, int snapshot, void *opaque)
         index = strtol(buf, NULL, 0);
 	if (index < 0) {
 	    fprintf(stderr, "qemu: '%s' invalid index\n", str);
-	    return -1;
+	    return NULL;
 	}
     }
 
@@ -2114,15 +2104,15 @@ int drive_init(struct drive_opt *arg, int snapshot, void *opaque)
     if (cyls || heads || secs) {
         if (cyls < 1 || cyls > 16383) {
             fprintf(stderr, "qemu: '%s' invalid physical cyls number\n", str);
-	    return -1;
+	    return NULL;
 	}
         if (heads < 1 || heads > 16) {
             fprintf(stderr, "qemu: '%s' invalid physical heads number\n", str);
-	    return -1;
+	    return NULL;
 	}
         if (secs < 1 || secs > 63) {
             fprintf(stderr, "qemu: '%s' invalid physical secs number\n", str);
-	    return -1;
+	    return NULL;
 	}
     }
 
@@ -2131,7 +2121,7 @@ int drive_init(struct drive_opt *arg, int snapshot, void *opaque)
             fprintf(stderr,
                     "qemu: '%s' trans must be used with cyls,heads and secs\n",
                     str);
-            return -1;
+            return NULL;
         }
         if (!strcmp(buf, "none"))
             translation = BIOS_ATA_TRANSLATION_NONE;
@@ -2141,7 +2131,7 @@ int drive_init(struct drive_opt *arg, int snapshot, void *opaque)
             translation = BIOS_ATA_TRANSLATION_AUTO;
 	else {
             fprintf(stderr, "qemu: '%s' invalid translation type\n", str);
-	    return -1;
+	    return NULL;
 	}
     }
 
@@ -2152,12 +2142,12 @@ int drive_init(struct drive_opt *arg, int snapshot, void *opaque)
             if (cyls || secs || heads) {
                 fprintf(stderr,
                         "qemu: '%s' invalid physical CHS format\n", str);
-	        return -1;
+	        return NULL;
             }
 	    media = MEDIA_CDROM;
 	} else {
 	    fprintf(stderr, "qemu: '%s' invalid media\n", str);
-	    return -1;
+	    return NULL;
 	}
     }
 
@@ -2168,7 +2158,7 @@ int drive_init(struct drive_opt *arg, int snapshot, void *opaque)
 	    snapshot = 0;
 	else {
 	    fprintf(stderr, "qemu: '%s' invalid snapshot option\n", str);
-	    return -1;
+	    return NULL;
 	}
     }
 
@@ -2181,7 +2171,7 @@ int drive_init(struct drive_opt *arg, int snapshot, void *opaque)
             cache = 2;
         else {
            fprintf(stderr, "qemu: invalid cache option\n");
-           return -1;
+           return NULL;
         }
     }
 
@@ -2190,12 +2180,12 @@ int drive_init(struct drive_opt *arg, int snapshot, void *opaque)
             fprintf(stderr, "qemu: Supported formats:");
             bdrv_iterate_format(bdrv_format_print, NULL);
             fprintf(stderr, "\n");
-	    return -1;
+	    return NULL;
         }
         drv = bdrv_find_format(buf);
         if (!drv) {
             fprintf(stderr, "qemu: '%s' invalid format\n", buf);
-            return -1;
+            return NULL;
         }
     }
 
@@ -2211,7 +2201,7 @@ int drive_init(struct drive_opt *arg, int snapshot, void *opaque)
     if (get_param_value(buf, sizeof(serial), "werror", str)) {
         if (type != IF_IDE && type != IF_SCSI && type != IF_VIRTIO) {
             fprintf(stderr, "werror is no supported by this format\n");
-            return -1;
+            return NULL;
         }
         if (!strcmp(buf, "ignore"))
             onerror = BLOCK_ERR_IGNORE;
@@ -2223,7 +2213,7 @@ int drive_init(struct drive_opt *arg, int snapshot, void *opaque)
             onerror = BLOCK_ERR_REPORT;
         else {
             fprintf(stderr, "qemu: '%s' invalid write error action\n", buf);
-            return -1;
+            return NULL;
         }
     }
 
@@ -2231,7 +2221,7 @@ int drive_init(struct drive_opt *arg, int snapshot, void *opaque)
     if (get_param_value(buf, sizeof(buf), "addr", str)) {
         if (type != IF_VIRTIO) {
             fprintf(stderr, "addr is not supported by in '%s'\n", str);
-            return -1;
+            return NULL;
         }
         devaddr = strdup(buf);
     }
@@ -2242,7 +2232,7 @@ int drive_init(struct drive_opt *arg, int snapshot, void *opaque)
         if (bus_id != 0 || unit_id != -1) {
             fprintf(stderr,
                     "qemu: '%s' index cannot be used with bus and unit\n", str);
-            return -1;
+            return NULL;
         }
         if (max_devs == 0)
         {
@@ -2260,7 +2250,7 @@ int drive_init(struct drive_opt *arg, int snapshot, void *opaque)
 
     if (unit_id == -1) {
        unit_id = 0;
-       while (drive_get_index(type, bus_id, unit_id) != -1) {
+       while (drive_get(type, bus_id, unit_id) != NULL) {
            unit_id++;
            if (max_devs && unit_id >= max_devs) {
                unit_id -= max_devs;
@@ -2274,15 +2264,17 @@ int drive_init(struct drive_opt *arg, int snapshot, void *opaque)
     if (max_devs && unit_id >= max_devs) {
         fprintf(stderr, "qemu: '%s' unit %d too big (max is %d)\n",
                         str, unit_id, max_devs - 1);
-        return -1;
+        return NULL;
     }
 
     /*
      * ignore multiple definitions
      */
 
-    if (drive_get_index(type, bus_id, unit_id) != -1)
-        return -2;
+    if (drive_get(type, bus_id, unit_id) != NULL) {
+        *fatal_error = 0;
+        return NULL;
+    }
 
     /* init */
 
@@ -2295,16 +2287,16 @@ int drive_init(struct drive_opt *arg, int snapshot, void *opaque)
         snprintf(buf, sizeof(buf), "%s%s%i",
                  devname, mediastr, unit_id);
     bdrv = bdrv_new(buf);
-    drives_table_idx = drive_get_free_idx();
-    drives_table[drives_table_idx].bdrv = bdrv;
-    drives_table[drives_table_idx].devaddr = devaddr;
-    drives_table[drives_table_idx].type = type;
-    drives_table[drives_table_idx].bus = bus_id;
-    drives_table[drives_table_idx].unit = unit_id;
-    drives_table[drives_table_idx].onerror = onerror;
-    drives_table[drives_table_idx].drive_opt_idx = arg - drives_opt;
-    strncpy(drives_table[drives_table_idx].serial, serial, sizeof(serial));
-    nb_drives++;
+    dinfo = qemu_mallocz(sizeof(*dinfo));
+    dinfo->bdrv = bdrv;
+    dinfo->devaddr = devaddr;
+    dinfo->type = type;
+    dinfo->bus = bus_id;
+    dinfo->unit = unit_id;
+    dinfo->onerror = onerror;
+    dinfo->drive_opt_idx = arg - drives_opt;
+    strncpy(dinfo->serial, serial, sizeof(serial));
+    TAILQ_INSERT_TAIL(&drives, dinfo, next);
 
     switch(type) {
     case IF_IDE:
@@ -2335,8 +2327,10 @@ int drive_init(struct drive_opt *arg, int snapshot, void *opaque)
     case IF_COUNT:
         abort();
     }
-    if (!file[0])
-        return -2;
+    if (!file[0]) {
+        *fatal_error = 0;
+        return NULL;
+    }
     bdrv_flags = 0;
     if (snapshot) {
         bdrv_flags |= BDRV_O_SNAPSHOT;
@@ -2349,11 +2343,12 @@ int drive_init(struct drive_opt *arg, int snapshot, void *opaque)
     if (bdrv_open2(bdrv, file, bdrv_flags, drv) < 0) {
         fprintf(stderr, "qemu: could not open disk image %s\n",
                         file);
-        return -1;
+        return NULL;
     }
     if (bdrv_key_required(bdrv))
         autostart = 0;
-    return drives_table_idx;
+    *fatal_error = 0;
+    return dinfo;
 }
 
 static void numa_add(const char *optarg)
@@ -4872,7 +4867,6 @@ int main(int argc, char **argv, char **envp)
 
     nb_net_clients = 0;
     nb_bt_opts = 0;
-    nb_drives = 0;
     nb_drives_opt = 0;
     nb_numa_nodes = 0;
     hda_index = -1;
@@ -5735,9 +5729,12 @@ int main(int argc, char **argv, char **envp)
 
     /* open the virtual block devices */
 
-    for(i = 0; i < nb_drives_opt; i++)
-        if (drive_init(&drives_opt[i], snapshot, machine) == -1)
-	    exit(1);
+    for(i = 0; i < nb_drives_opt; i++) {
+        int fatal_error;
+        if (drive_init(&drives_opt[i], snapshot, machine, &fatal_error) == NULL)
+            if (fatal_error)
+                exit(1);
+    }
 
     register_savevm("timer", 0, 2, timer_save, timer_load, NULL);
     register_savevm_live("ram", 0, 3, ram_save_live, NULL, ram_load, NULL);
-- 
1.6.2.5

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [Qemu-devel] [PATCH v2 2/3] add support for drive ids.
  2009-07-16  8:53 [Qemu-devel] [PATCH v2 0/3] cleanup drive handling Gerd Hoffmann
  2009-07-16  8:53 ` [Qemu-devel] [PATCH v2 1/3] kill drives_table Gerd Hoffmann
@ 2009-07-16  8:53 ` Gerd Hoffmann
       [not found]   ` <m3ljmohgyk.fsf@neno.mitica>
  2009-07-16  8:53 ` [Qemu-devel] [PATCH v2 3/3] kill drives_opt Gerd Hoffmann
  2 siblings, 1 reply; 6+ messages in thread
From: Gerd Hoffmann @ 2009-07-16  8:53 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

-drive accepts the new id= now, allowing to explicitely name your
drives.  They will show up with that name in "info block" if specified,
otherwise the existing namimg scheme is used to autogenerate one.

There is also a new function to lookup drives by name.  Not used yet.
The plan is to link disk drivers and drives using the drive id instead
of passing around pointers to BlockDriveState.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 sysemu.h |    2 ++
 vl.c     |   50 ++++++++++++++++++++++++++++++++------------------
 2 files changed, 34 insertions(+), 18 deletions(-)

diff --git a/sysemu.h b/sysemu.h
index 36d6aaa..1f7532a 100644
--- a/sysemu.h
+++ b/sysemu.h
@@ -160,6 +160,7 @@ typedef enum {
 
 typedef struct DriveInfo {
     BlockDriverState *bdrv;
+    char *id;
     const char *devaddr;
     BlockInterfaceType type;
     int bus;
@@ -177,6 +178,7 @@ typedef struct DriveInfo {
 extern TAILQ_HEAD(drivelist, DriveInfo) drives;
 
 extern DriveInfo *drive_get(BlockInterfaceType type, int bus, int unit);
+extern DriveInfo *drive_get_by_id(char *id);
 extern int drive_get_max_bus(BlockInterfaceType type);
 extern void drive_uninit(BlockDriverState *bdrv);
 extern void drive_remove(int index);
diff --git a/vl.c b/vl.c
index 4dae7ad..fc321ae 100644
--- a/vl.c
+++ b/vl.c
@@ -1919,6 +1919,18 @@ DriveInfo *drive_get(BlockInterfaceType type, int bus, int unit)
     return NULL;
 }
 
+DriveInfo *drive_get_by_id(char *id)
+{
+    DriveInfo *dinfo;
+
+    TAILQ_FOREACH(dinfo, &drives, next) {
+        if (strcmp(id, dinfo->id))
+            continue;
+        return dinfo;
+    }
+    return NULL;
+}
+
 int drive_get_max_bus(BlockInterfaceType type)
 {
     int max_bus;
@@ -1988,7 +2000,6 @@ DriveInfo *drive_init(struct drive_opt *arg, int snapshot, void *opaque,
     enum { MEDIA_DISK, MEDIA_CDROM } media;
     int bus_id, unit_id;
     int cyls, heads, secs, translation;
-    BlockDriverState *bdrv;
     BlockDriver *drv = NULL;
     QEMUMachine *machine = opaque;
     int max_devs;
@@ -2002,7 +2013,7 @@ DriveInfo *drive_init(struct drive_opt *arg, int snapshot, void *opaque,
                                            "cyls", "heads", "secs", "trans",
                                            "media", "snapshot", "file",
                                            "cache", "format", "serial",
-                                           "werror", "addr",
+                                           "werror", "addr", "name",
                                            NULL };
     *fatal_error = 1;
 
@@ -2278,17 +2289,20 @@ DriveInfo *drive_init(struct drive_opt *arg, int snapshot, void *opaque,
 
     /* init */
 
-    if (type == IF_IDE || type == IF_SCSI)
-        mediastr = (media == MEDIA_CDROM) ? "-cd" : "-hd";
-    if (max_devs)
-        snprintf(buf, sizeof(buf), "%s%i%s%i",
-                 devname, bus_id, mediastr, unit_id);
-    else
-        snprintf(buf, sizeof(buf), "%s%s%i",
-                 devname, mediastr, unit_id);
-    bdrv = bdrv_new(buf);
     dinfo = qemu_mallocz(sizeof(*dinfo));
-    dinfo->bdrv = bdrv;
+    if (!get_param_value(buf, sizeof(buf), "id", str)) {
+        /* no name supplied -> create one */
+        if (type == IF_IDE || type == IF_SCSI)
+            mediastr = (media == MEDIA_CDROM) ? "-cd" : "-hd";
+        if (max_devs)
+            snprintf(buf, sizeof(buf), "%s%i%s%i",
+                     devname, bus_id, mediastr, unit_id);
+        else
+            snprintf(buf, sizeof(buf), "%s%s%i",
+                     devname, mediastr, unit_id);
+    }
+    dinfo->id = qemu_strdup(buf);
+    dinfo->bdrv = bdrv_new(dinfo->id);
     dinfo->devaddr = devaddr;
     dinfo->type = type;
     dinfo->bus = bus_id;
@@ -2305,12 +2319,12 @@ DriveInfo *drive_init(struct drive_opt *arg, int snapshot, void *opaque,
         switch(media) {
 	case MEDIA_DISK:
             if (cyls != 0) {
-                bdrv_set_geometry_hint(bdrv, cyls, heads, secs);
-                bdrv_set_translation_hint(bdrv, translation);
+                bdrv_set_geometry_hint(dinfo->bdrv, cyls, heads, secs);
+                bdrv_set_translation_hint(dinfo->bdrv, translation);
             }
 	    break;
 	case MEDIA_CDROM:
-            bdrv_set_type_hint(bdrv, BDRV_TYPE_CDROM);
+            bdrv_set_type_hint(dinfo->bdrv, BDRV_TYPE_CDROM);
 	    break;
 	}
         break;
@@ -2318,7 +2332,7 @@ DriveInfo *drive_init(struct drive_opt *arg, int snapshot, void *opaque,
         /* FIXME: This isn't really a floppy, but it's a reasonable
            approximation.  */
     case IF_FLOPPY:
-        bdrv_set_type_hint(bdrv, BDRV_TYPE_FLOPPY);
+        bdrv_set_type_hint(dinfo->bdrv, BDRV_TYPE_FLOPPY);
         break;
     case IF_PFLASH:
     case IF_MTD:
@@ -2340,12 +2354,12 @@ DriveInfo *drive_init(struct drive_opt *arg, int snapshot, void *opaque,
         bdrv_flags |= BDRV_O_NOCACHE;
     else if (cache == 2) /* write-back */
         bdrv_flags |= BDRV_O_CACHE_WB;
-    if (bdrv_open2(bdrv, file, bdrv_flags, drv) < 0) {
+    if (bdrv_open2(dinfo->bdrv, file, bdrv_flags, drv) < 0) {
         fprintf(stderr, "qemu: could not open disk image %s\n",
                         file);
         return NULL;
     }
-    if (bdrv_key_required(bdrv))
+    if (bdrv_key_required(dinfo->bdrv))
         autostart = 0;
     *fatal_error = 0;
     return dinfo;
-- 
1.6.2.5

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [Qemu-devel] [PATCH v2 3/3] kill drives_opt
  2009-07-16  8:53 [Qemu-devel] [PATCH v2 0/3] cleanup drive handling Gerd Hoffmann
  2009-07-16  8:53 ` [Qemu-devel] [PATCH v2 1/3] kill drives_table Gerd Hoffmann
  2009-07-16  8:53 ` [Qemu-devel] [PATCH v2 2/3] add support for drive ids Gerd Hoffmann
@ 2009-07-16  8:53 ` Gerd Hoffmann
  2 siblings, 0 replies; 6+ messages in thread
From: Gerd Hoffmann @ 2009-07-16  8:53 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

cleanup pretty simliar to the drives_table removal patch:
 - drop the table and make a linked list out of it.
 - pass around struct pointers instead of table indices.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/device-hotplug.c |   10 +++---
 sysemu.h            |   24 +++++++--------
 vl.c                |   79 +++++++++++++++++---------------------------------
 3 files changed, 43 insertions(+), 70 deletions(-)

diff --git a/hw/device-hotplug.c b/hw/device-hotplug.c
index 5257274..8f0dec8 100644
--- a/hw/device-hotplug.c
+++ b/hw/device-hotplug.c
@@ -30,17 +30,17 @@
 
 DriveInfo *add_init_drive(const char *opts)
 {
-    int drive_opt_idx;
     int fatal_error;
     DriveInfo *dinfo;
+    DriveOpt *dopt;
 
-    drive_opt_idx = drive_add(NULL, "%s", opts);
-    if (!drive_opt_idx)
+    dopt = drive_add(NULL, "%s", opts);
+    if (!dopt)
         return NULL;
 
-    dinfo = drive_init(&drives_opt[drive_opt_idx], 0, current_machine, &fatal_error);
+    dinfo = drive_init(dopt, 0, current_machine, &fatal_error);
     if (!dinfo) {
-        drive_remove(drive_opt_idx);
+        drive_remove(dopt);
         return NULL;
     }
 
diff --git a/sysemu.h b/sysemu.h
index 1f7532a..88a233b 100644
--- a/sysemu.h
+++ b/sysemu.h
@@ -158,6 +158,12 @@ typedef enum {
 
 #define BLOCK_SERIAL_STRLEN 20
 
+typedef struct DriveOpt {
+    const char *file;
+    char opt[1024];
+    TAILQ_ENTRY(DriveOpt) next;
+} DriveOpt;
+
 typedef struct DriveInfo {
     BlockDriverState *bdrv;
     char *id;
@@ -165,7 +171,7 @@ typedef struct DriveInfo {
     BlockInterfaceType type;
     int bus;
     int unit;
-    int drive_opt_idx;
+    DriveOpt *opt;
     BlockInterfaceErrorAction onerror;
     char serial[BLOCK_SERIAL_STRLEN + 1];
     TAILQ_ENTRY(DriveInfo) next;
@@ -176,28 +182,20 @@ typedef struct DriveInfo {
 #define MAX_DRIVES 32
 
 extern TAILQ_HEAD(drivelist, DriveInfo) drives;
+extern TAILQ_HEAD(driveoptlist, DriveOpt) driveopts;
 
 extern DriveInfo *drive_get(BlockInterfaceType type, int bus, int unit);
 extern DriveInfo *drive_get_by_id(char *id);
 extern int drive_get_max_bus(BlockInterfaceType type);
 extern void drive_uninit(BlockDriverState *bdrv);
-extern void drive_remove(int index);
+extern void drive_remove(DriveOpt *opt);
 extern const char *drive_get_serial(BlockDriverState *bdrv);
 extern BlockInterfaceErrorAction drive_get_onerror(BlockDriverState *bdrv);
 
 BlockDriverState *qdev_init_bdrv(DeviceState *dev, BlockInterfaceType type);
 
-struct drive_opt {
-    const char *file;
-    char opt[1024];
-    int used;
-};
-
-extern struct drive_opt drives_opt[MAX_DRIVES];
-extern int nb_drives_opt;
-
-extern int drive_add(const char *file, const char *fmt, ...);
-extern DriveInfo *drive_init(struct drive_opt *arg, int snapshot, void *machine,
+extern DriveOpt *drive_add(const char *file, const char *fmt, ...);
+extern DriveInfo *drive_init(DriveOpt *arg, int snapshot, void *machine,
                              int *fatal_error);
 
 /* acpi */
diff --git a/vl.c b/vl.c
index fc321ae..b3f5d9d 100644
--- a/vl.c
+++ b/vl.c
@@ -184,6 +184,7 @@ const char *bios_name = NULL;
 /* Note: drives_table[MAX_DRIVES] is a dummy block driver if none available
    to store the VM snapshots */
 struct drivelist drives = TAILQ_HEAD_INITIALIZER(drives);
+struct driveoptlist driveopts = TAILQ_HEAD_INITIALIZER(driveopts);
 enum vga_retrace_method vga_retrace_method = VGA_RETRACE_DUMB;
 static DisplayState *display_state;
 DisplayType display_type = DT_DEFAULT;
@@ -251,8 +252,6 @@ int alt_grab = 0;
 unsigned int nb_prom_envs = 0;
 const char *prom_envs[MAX_PROM_ENVS];
 #endif
-int nb_drives_opt;
-struct drive_opt drives_opt[MAX_DRIVES];
 
 int nb_numa_nodes;
 uint64_t node_mem[MAX_NODES];
@@ -1864,43 +1863,27 @@ static int bt_parse(const char *opt)
 #define MTD_ALIAS "if=mtd"
 #define SD_ALIAS "index=0,if=sd"
 
-static int drive_opt_get_free_idx(void)
-{
-    int index;
-
-    for (index = 0; index < MAX_DRIVES; index++)
-        if (!drives_opt[index].used) {
-            drives_opt[index].used = 1;
-            return index;
-        }
-
-    return -1;
-}
-
-int drive_add(const char *file, const char *fmt, ...)
+DriveOpt *drive_add(const char *file, const char *fmt, ...)
 {
     va_list ap;
-    int index = drive_opt_get_free_idx();
+    DriveOpt *dopt;
 
-    if (nb_drives_opt >= MAX_DRIVES || index == -1) {
-        fprintf(stderr, "qemu: too many drives\n");
-        return -1;
-    }
+    dopt = qemu_mallocz(sizeof(*dopt));
 
-    drives_opt[index].file = file;
+    dopt->file = file;
     va_start(ap, fmt);
-    vsnprintf(drives_opt[index].opt,
-              sizeof(drives_opt[0].opt), fmt, ap);
+    vsnprintf(dopt->opt,
+              sizeof(dopt->opt), fmt, ap);
     va_end(ap);
 
-    nb_drives_opt++;
-    return index;
+    TAILQ_INSERT_TAIL(&driveopts, dopt, next);
+    return dopt;
 }
 
-void drive_remove(int index)
+void drive_remove(DriveOpt *dopt)
 {
-    drives_opt[index].used = 0;
-    nb_drives_opt--;
+    TAILQ_REMOVE(&driveopts, dopt, next);
+    qemu_free(dopt);
 }
 
 DriveInfo *drive_get(BlockInterfaceType type, int bus, int unit)
@@ -1981,14 +1964,14 @@ void drive_uninit(BlockDriverState *bdrv)
     TAILQ_FOREACH(dinfo, &drives, next) {
         if (dinfo->bdrv != bdrv)
             continue;
-        drive_remove(dinfo->drive_opt_idx);
+        drive_remove(dinfo->opt);
         TAILQ_REMOVE(&drives, dinfo, next);
         qemu_free(dinfo);
         break;
     }
 }
 
-DriveInfo *drive_init(struct drive_opt *arg, int snapshot, void *opaque,
+DriveInfo *drive_init(DriveOpt *arg, int snapshot, void *opaque,
                       int *fatal_error)
 {
     char buf[128];
@@ -2308,7 +2291,7 @@ DriveInfo *drive_init(struct drive_opt *arg, int snapshot, void *opaque,
     dinfo->bus = bus_id;
     dinfo->unit = unit_id;
     dinfo->onerror = onerror;
-    dinfo->drive_opt_idx = arg - drives_opt;
+    dinfo->opt = arg;
     strncpy(dinfo->serial, serial, sizeof(serial));
     TAILQ_INSERT_TAIL(&drives, dinfo, next);
 
@@ -4782,7 +4765,7 @@ int main(int argc, char **argv, char **envp)
     int nb_net_clients;
     const char *bt_opts[MAX_BT_CMDLINE];
     int nb_bt_opts;
-    int hda_index;
+    DriveOpt *dopt, *hda_opt = NULL;
     int optind;
     const char *r, *optarg;
     CharDriverState *monitor_hd = NULL;
@@ -4881,9 +4864,7 @@ int main(int argc, char **argv, char **envp)
 
     nb_net_clients = 0;
     nb_bt_opts = 0;
-    nb_drives_opt = 0;
     nb_numa_nodes = 0;
-    hda_index = -1;
 
     nb_nics = 0;
 
@@ -4898,7 +4879,7 @@ int main(int argc, char **argv, char **envp)
             break;
         r = argv[optind];
         if (r[0] != '-') {
-	    hda_index = drive_add(argv[optind++], HD_ALIAS, 0);
+	    hda_opt = drive_add(argv[optind++], HD_ALIAS, 0);
         } else {
             const QEMUOption *popt;
 
@@ -4959,9 +4940,9 @@ int main(int argc, char **argv, char **envp)
                 break;
             case QEMU_OPTION_hda:
                 if (cyls == 0)
-                    hda_index = drive_add(optarg, HD_ALIAS, 0);
+                    hda_opt = drive_add(optarg, HD_ALIAS, 0);
                 else
-                    hda_index = drive_add(optarg, HD_ALIAS
+                    hda_opt = drive_add(optarg, HD_ALIAS
 			     ",cyls=%d,heads=%d,secs=%d%s",
                              0, cyls, heads, secs,
                              translation == BIOS_ATA_TRANSLATION_LBA ?
@@ -5023,9 +5004,9 @@ int main(int argc, char **argv, char **envp)
                         fprintf(stderr, "qemu: invalid physical CHS format\n");
                         exit(1);
                     }
-		    if (hda_index != -1)
-                        snprintf(drives_opt[hda_index].opt,
-                                 sizeof(drives_opt[hda_index].opt),
+		    if (hda_opt != NULL)
+                        snprintf(hda_opt->opt,
+                                 sizeof(hda_opt->opt),
                                  HD_ALIAS ",cyls=%d,heads=%d,secs=%d%s",
                                  0, cyls, heads, secs,
 			         translation == BIOS_ATA_TRANSLATION_LBA ?
@@ -5727,25 +5708,19 @@ int main(int argc, char **argv, char **envp)
     bdrv_init();
 
     /* we always create the cdrom drive, even if no disk is there */
-
-    if (nb_drives_opt < MAX_DRIVES)
-        drive_add(NULL, CDROM_ALIAS);
+    drive_add(NULL, CDROM_ALIAS);
 
     /* we always create at least one floppy */
-
-    if (nb_drives_opt < MAX_DRIVES)
-        drive_add(NULL, FD_ALIAS, 0);
+    drive_add(NULL, FD_ALIAS, 0);
 
     /* we always create one sd slot, even if no card is in it */
-
-    if (nb_drives_opt < MAX_DRIVES)
-        drive_add(NULL, SD_ALIAS);
+    drive_add(NULL, SD_ALIAS);
 
     /* open the virtual block devices */
 
-    for(i = 0; i < nb_drives_opt; i++) {
+    TAILQ_FOREACH(dopt, &driveopts, next) {
         int fatal_error;
-        if (drive_init(&drives_opt[i], snapshot, machine, &fatal_error) == NULL)
+        if (drive_init(dopt, snapshot, machine, &fatal_error) == NULL)
             if (fatal_error)
                 exit(1);
     }
-- 
1.6.2.5

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [Qemu-devel] Re: [PATCH v2 2/3] add support for drive ids.
       [not found]   ` <m3ljmohgyk.fsf@neno.mitica>
@ 2009-07-16 13:59     ` Gerd Hoffmann
  0 siblings, 0 replies; 6+ messages in thread
From: Gerd Hoffmann @ 2009-07-16 13:59 UTC (permalink / raw)
  To: Juan Quintela; +Cc: qemu-devel

On 07/16/09 15:53, Juan Quintela wrote:
> Gerd Hoffmann<kraxel@redhat.com>  wrote:
>> -drive accepts the new id= now, allowing to explicitely name your
>> drives.  They will show up with that name in "info block" if specified,
>> otherwise the existing namimg scheme is used to autogenerate one.
>>
>> There is also a new function to lookup drives by name.  Not used yet.
>> The plan is to link disk drivers and drives using the drive id instead
>> of passing around pointers to BlockDriveState.
>
> Confusing.  Stick with "id" or "name", but use the same everywhere?

Yep, noticed myself while continuing hacking.  I'll respin with a few 
more patches on top of that later today.

cheers,
   Gerd

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [Qemu-devel] Re: [PATCH v2 1/3] kill drives_table
       [not found]   ` <m3d480hg02.fsf@neno.mitica>
@ 2009-07-16 14:54     ` Gerd Hoffmann
  0 siblings, 0 replies; 6+ messages in thread
From: Gerd Hoffmann @ 2009-07-16 14:54 UTC (permalink / raw)
  To: Juan Quintela; +Cc: qemu-devel

On 07/16/09 16:14, Juan Quintela wrote:
> Gerd Hoffmann<kraxel@redhat.com>  wrote:
>> diff --git a/qemu-char.c b/qemu-char.c
>> index 287e0cd..a7d8fb6 100644
>> --- a/qemu-char.c
>> +++ b/qemu-char.c
>> @@ -345,10 +345,12 @@ static int mux_proc_byte(CharDriverState *chr, MuxDriver *d, int ch)
>>               }
>>           case 's':
>>               {
>> +#if 0
>>                   int i;
>>                   for (i = 0; i<  nb_drives; i++) {
>>                           bdrv_commit(drives_table[i].bdrv);
>>                   }
>> +#endif
>>               }
>>               break;
>>           case 'b':
>
> Why you didn't translate this one, you translate th erest of similar ones?

Not sure, probably just some leftover.
It certainly wasn't intended to make it into the final version of the 
patch, will fix.

cheers,
   Gerd

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2009-07-16 14:54 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-07-16  8:53 [Qemu-devel] [PATCH v2 0/3] cleanup drive handling Gerd Hoffmann
2009-07-16  8:53 ` [Qemu-devel] [PATCH v2 1/3] kill drives_table Gerd Hoffmann
     [not found]   ` <m3d480hg02.fsf@neno.mitica>
2009-07-16 14:54     ` [Qemu-devel] " Gerd Hoffmann
2009-07-16  8:53 ` [Qemu-devel] [PATCH v2 2/3] add support for drive ids Gerd Hoffmann
     [not found]   ` <m3ljmohgyk.fsf@neno.mitica>
2009-07-16 13:59     ` [Qemu-devel] " Gerd Hoffmann
2009-07-16  8:53 ` [Qemu-devel] [PATCH v2 3/3] kill drives_opt Gerd Hoffmann

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).