6f9d9c
From a6b957c3dbc67e674f457d6c9738076f47ad8bd9 Mon Sep 17 00:00:00 2001
6f9d9c
From: Kevin Wolf <kwolf@redhat.com>
6f9d9c
Date: Thu, 20 Oct 2011 16:37:26 +0200
6f9d9c
Subject: [PATCH] pc: Fix floppy drives with if=none
6f9d9c
6f9d9c
Commit 63ffb564 broke floppy devices specified on the command line like
6f9d9c
-drive file=...,if=none,id=floppy -global isa-fdc.driveA=floppy because it
6f9d9c
relies on drive_get() which works only with -fda/-drive if=floppy.
6f9d9c
6f9d9c
This patch resembles what we're already doing for IDE, i.e. remember the floppy
6f9d9c
device that was created and use that to extract the BlockDriverStates where
6f9d9c
needed.
6f9d9c
6f9d9c
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
6f9d9c
Reviewed-by: Markus Armbruster <armbru@redhat.com>
6f9d9c
---
6f9d9c
 hw/fdc.c     |   12 ++++++++++++
6f9d9c
 hw/fdc.h     |    9 +++++++--
6f9d9c
 hw/pc.c      |   25 ++++++++++++++-----------
6f9d9c
 hw/pc.h      |    3 ++-
6f9d9c
 hw/pc_piix.c |    5 +++--
6f9d9c
 5 files changed, 38 insertions(+), 16 deletions(-)
6f9d9c
6f9d9c
diff --git a/hw/fdc.c b/hw/fdc.c
6f9d9c
index ec99c78..4bd6abf 100644
6f9d9c
--- a/hw/fdc.c
6f9d9c
+++ b/hw/fdc.c
6f9d9c
@@ -1913,6 +1913,18 @@ static int sun4m_fdc_init1(SysBusDevice *dev)
6f9d9c
     return fdctrl_init_common(fdctrl);
6f9d9c
 }
6f9d9c
 
6f9d9c
+void fdc_get_bs(BlockDriverState *bs[], ISADevice *dev)
6f9d9c
+{
6f9d9c
+    FDCtrlISABus *isa = DO_UPCAST(FDCtrlISABus, busdev, dev);
6f9d9c
+    FDCtrl *fdctrl = &isa->state;
6f9d9c
+    int i;
6f9d9c
+
6f9d9c
+    for (i = 0; i < MAX_FD; i++) {
6f9d9c
+        bs[i] = fdctrl->drives[i].bs;
6f9d9c
+    }
6f9d9c
+}
6f9d9c
+
6f9d9c
+
6f9d9c
 static const VMStateDescription vmstate_isa_fdc ={
6f9d9c
     .name = "fdc",
6f9d9c
     .version_id = 2,
6f9d9c
diff --git a/hw/fdc.h b/hw/fdc.h
6f9d9c
index 09f73c6..506feb6 100644
6f9d9c
--- a/hw/fdc.h
6f9d9c
+++ b/hw/fdc.h
6f9d9c
@@ -7,14 +7,15 @@
6f9d9c
 /* fdc.c */
6f9d9c
 #define MAX_FD 2
6f9d9c
 
6f9d9c
-static inline void fdctrl_init_isa(DriveInfo **fds)
6f9d9c
+static inline ISADevice *fdctrl_init_isa(DriveInfo **fds)
6f9d9c
 {
6f9d9c
     ISADevice *dev;
6f9d9c
 
6f9d9c
     dev = isa_try_create("isa-fdc");
6f9d9c
     if (!dev) {
6f9d9c
-        return;
6f9d9c
+        return NULL;
6f9d9c
     }
6f9d9c
+
6f9d9c
     if (fds[0]) {
6f9d9c
         qdev_prop_set_drive_nofail(&dev->qdev, "driveA", fds[0]->bdrv);
6f9d9c
     }
6f9d9c
@@ -22,10 +23,14 @@ static inline void fdctrl_init_isa(DriveInfo **fds)
6f9d9c
         qdev_prop_set_drive_nofail(&dev->qdev, "driveB", fds[1]->bdrv);
6f9d9c
     }
6f9d9c
     qdev_init_nofail(&dev->qdev);
6f9d9c
+
6f9d9c
+    return dev;
6f9d9c
 }
6f9d9c
 
6f9d9c
 void fdctrl_init_sysbus(qemu_irq irq, int dma_chann,
6f9d9c
                         target_phys_addr_t mmio_base, DriveInfo **fds);
6f9d9c
 void sun4m_fdctrl_init(qemu_irq irq, target_phys_addr_t io_base,
6f9d9c
                        DriveInfo **fds, qemu_irq *fdc_tc);
6f9d9c
+void fdc_get_bs(BlockDriverState *bs[], ISADevice *dev);
6f9d9c
+
6f9d9c
 #endif
6f9d9c
diff --git a/hw/pc.c b/hw/pc.c
6f9d9c
index a3e8539..4903803 100644
6f9d9c
--- a/hw/pc.c
6f9d9c
+++ b/hw/pc.c
6f9d9c
@@ -333,12 +333,12 @@ static void pc_cmos_init_late(void *opaque)
6f9d9c
 
6f9d9c
 void pc_cmos_init(ram_addr_t ram_size, ram_addr_t above_4g_mem_size,
6f9d9c
                   const char *boot_device,
6f9d9c
-                  BusState *idebus0, BusState *idebus1,
6f9d9c
+                  ISADevice *floppy, BusState *idebus0, BusState *idebus1,
6f9d9c
                   ISADevice *s)
6f9d9c
 {
6f9d9c
     int val, nb, nb_heads, max_track, last_sect, i;
6f9d9c
     FDriveType fd_type[2];
6f9d9c
-    DriveInfo *fd[2];
6f9d9c
+    BlockDriverState *fd[MAX_FD];
6f9d9c
     static pc_cmos_init_late_arg arg;
6f9d9c
 
6f9d9c
     /* various important CMOS locations needed by PC/Bochs bios */
6f9d9c
@@ -380,14 +380,16 @@ void pc_cmos_init(ram_addr_t ram_size, ram_addr_t above_4g_mem_size,
6f9d9c
     }
6f9d9c
 
6f9d9c
     /* floppy type */
6f9d9c
-    for (i = 0; i < 2; i++) {
6f9d9c
-        fd[i] = drive_get(IF_FLOPPY, 0, i);
6f9d9c
-        if (fd[i] && bdrv_is_inserted(fd[i]->bdrv)) {
6f9d9c
-            bdrv_get_floppy_geometry_hint(fd[i]->bdrv, &nb_heads, &max_track,
6f9d9c
-                                          &last_sect, FDRIVE_DRV_NONE,
6f9d9c
-                                          &fd_type[i]);
6f9d9c
-        } else {
6f9d9c
-            fd_type[i] = FDRIVE_DRV_NONE;
6f9d9c
+    if (floppy) {
6f9d9c
+        fdc_get_bs(fd, floppy);
6f9d9c
+        for (i = 0; i < 2; i++) {
6f9d9c
+            if (fd[i] && bdrv_is_inserted(fd[i])) {
6f9d9c
+                bdrv_get_floppy_geometry_hint(fd[i], &nb_heads, &max_track,
6f9d9c
+                                              &last_sect, FDRIVE_DRV_NONE,
6f9d9c
+                                              &fd_type[i]);
6f9d9c
+            } else {
6f9d9c
+                fd_type[i] = FDRIVE_DRV_NONE;
6f9d9c
+            }
6f9d9c
         }
6f9d9c
     }
6f9d9c
     val = (cmos_get_fd_drive_type(fd_type[0]) << 4) |
6f9d9c
@@ -1092,6 +1094,7 @@ static void cpu_request_exit(void *opaque, int irq, int level)
6f9d9c
 
6f9d9c
 void pc_basic_device_init(qemu_irq *isa_irq,
6f9d9c
                           ISADevice **rtc_state,
6f9d9c
+                          ISADevice **floppy,
6f9d9c
                           bool no_vmport)
6f9d9c
 {
6f9d9c
     int i;
6f9d9c
@@ -1156,7 +1159,7 @@ void pc_basic_device_init(qemu_irq *isa_irq,
6f9d9c
     for(i = 0; i < MAX_FD; i++) {
6f9d9c
         fd[i] = drive_get(IF_FLOPPY, 0, i);
6f9d9c
     }
6f9d9c
-    fdctrl_init_isa(fd);
6f9d9c
+    *floppy = fdctrl_init_isa(fd);
6f9d9c
 }
6f9d9c
 
6f9d9c
 void pc_pci_device_init(PCIBus *pci_bus)
6f9d9c
diff --git a/hw/pc.h b/hw/pc.h
6f9d9c
index 6d5730b..24b7fe2 100644
6f9d9c
--- a/hw/pc.h
6f9d9c
+++ b/hw/pc.h
6f9d9c
@@ -138,11 +138,12 @@ qemu_irq *pc_allocate_cpu_irq(void);
6f9d9c
 void pc_vga_init(PCIBus *pci_bus);
6f9d9c
 void pc_basic_device_init(qemu_irq *isa_irq,
6f9d9c
                           ISADevice **rtc_state,
6f9d9c
+                          ISADevice **floppy,
6f9d9c
                           bool no_vmport);
6f9d9c
 void pc_init_ne2k_isa(NICInfo *nd);
6f9d9c
 void pc_cmos_init(ram_addr_t ram_size, ram_addr_t above_4g_mem_size,
6f9d9c
                   const char *boot_device,
6f9d9c
-                  BusState *ide0, BusState *ide1,
6f9d9c
+                  ISADevice *floppy, BusState *ide0, BusState *ide1,
6f9d9c
                   ISADevice *s);
6f9d9c
 void pc_pci_device_init(PCIBus *pci_bus);
6f9d9c
 
6f9d9c
diff --git a/hw/pc_piix.c b/hw/pc_piix.c
6f9d9c
index c5c16b4..a634860 100644
6f9d9c
--- a/hw/pc_piix.c
6f9d9c
+++ b/hw/pc_piix.c
6f9d9c
@@ -89,6 +89,7 @@ static void pc_init1(ram_addr_t ram_size,
6f9d9c
     DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
6f9d9c
     BusState *idebus[MAX_IDE_BUS];
6f9d9c
     ISADevice *rtc_state;
6f9d9c
+    ISADevice *floppy;
6f9d9c
 
6f9d9c
     global_cpu_model = cpu_model;
6f9d9c
 
6f9d9c
@@ -141,7 +142,7 @@ static void pc_init1(ram_addr_t ram_size,
6f9d9c
     }
6f9d9c
 
6f9d9c
     /* init basic PC hardware */
6f9d9c
-    pc_basic_device_init(isa_irq, &rtc_state, xen_enabled());
6f9d9c
+    pc_basic_device_init(isa_irq, &rtc_state, &floppy, xen_enabled());
6f9d9c
 
6f9d9c
     for(i = 0; i < nb_nics; i++) {
6f9d9c
         NICInfo *nd = &nd_table[i];
6f9d9c
@@ -170,7 +171,7 @@ static void pc_init1(ram_addr_t ram_size,
6f9d9c
     audio_init(isa_irq, pci_enabled ? pci_bus : NULL);
6f9d9c
 
6f9d9c
     pc_cmos_init(below_4g_mem_size, above_4g_mem_size, boot_device,
6f9d9c
-                 idebus[0], idebus[1], rtc_state);
6f9d9c
+                 floppy, idebus[0], idebus[1], rtc_state);
6f9d9c
 
6f9d9c
     if (pci_enabled && usb_enabled) {
6f9d9c
         usb_uhci_piix3_init(pci_bus, piix3_devfn + 2);
6f9d9c
-- 
6f9d9c
1.7.7.5
6f9d9c