Patchwork fdc: fix MAX_FD probelm

login
register
mail settings
Submitter 武田 =?ISO-2022-JP?B?IBskQj1TTGkbKEI=?=
Date Sept. 13, 2009, 10:07 a.m.
Message ID <200909131007.AA00106@YOUR-BD18D6DD63.m1.interq.or.jp>
Download mbox | patch
Permalink /patch/33547/
State Superseded
Headers show

Comments

武田 =?ISO-2022-JP?B?IBskQj1TTGkbKEI=?= - Sept. 13, 2009, 10:07 a.m.
Dear Stuart,

>On Sun, Sep 13, 2009 at 04:52:51AM +0900, 武田 俊也 wrote:
>> +    if (fdctrl->num_floppies == 4) {
>> +        fdctrl->fifo[2] = drv2(fdctrl)->track;
>> +        fdctrl->fifo[3] = drv3(fdctrl)->track;
>> +    } else {
>> +        fdctrl->fifo[2] = 0;
>> +        fdctrl->fifo[3] = 0;
>> +    }
>
>With real hardware, only a single drive might be connected, three drives
>might be connected, or possibly none at all.  I don't even see why you
>couldn't connect only drives 0 and 2 -- there could well be hardware
>worth emulating that does something like that, but I don't know...
>
>Perhaps something similar to the following should be used? :-
>
>    static inline int drive_attached(fdctrl_t *fdctrl, int drv) {
>        /* Assume that drives are attached contiguously,
>           starting with drive 0. */
>        return drv < fdctrl->num_floppies;
>    }
>
>And then:
>
>    fdctrl->fifo[0] = drive_attached(0) ? drv0(fdctrl)->track : 0;
>    fdctrl->fifo[1] = drive_attached(1) ? drv1(fdctrl)->track : 0;
>    fdctrl->fifo[2] = drive_attached(2) ? drv2(fdctrl)->track : 0;
>    fdctrl->fifo[3] = drive_attached(3) ? drv3(fdctrl)->track : 0;
>
>You would need to modify that to take account the remapping of drives
>performed by drv0(), drv1(), etc., though.
>
>I'd suggest something similar in other places that test num_floppies,
>although fdctrl_connect_drives() would of course be an exception.
>
>Arguably, there should be something in fdrive_t (or fdctrl_t) to
>indicate whether a particular drive is connected, but unfortunately the
>'drive' member of fdrive_t holds the value FDRIVE_DRV_NONE even if the
>drive exists, but no disk is inserted...

I see.

I added "connected" t fdrive_t to show physical drive is connected or not
and it is initialized in fdctrl_connect_drives().

This is new patch.
Stuart Brady - Sept. 13, 2009, 2:44 p.m.
On Sun, Sep 13, 2009 at 07:07:12PM +0900, 武田 俊也 wrote:
> I added "connected" t fdrive_t to show physical drive is connected or not
> and it is initialized in fdctrl_connect_drives().
> 
> This is new patch.

Neat. :-)

I'm still slightly concerned that for machines with MAX_PHYSICAL_DRIVES
set to 2, guests would see drives 2 and 3 as present, but with no disk
inserted.  Previously, though, I expect they would have been mirrors of
drives 0 and 1, which is obviously worse!

Cheers,
武田 =?ISO-2022-JP?B?IBskQj1TTGkbKEI=?= - Sept. 13, 2009, 3:42 p.m.
Dear Stuart and members,

>On Sun, Sep 13, 2009 at 07:07:12PM +0900, 武田 俊也 wrote:
>> I added "connected" t fdrive_t to show physical drive is connected or not
>> and it is initialized in fdctrl_connect_drives().
>> 
>> This is new patch.
>
>Neat. :-)
>
>I'm still slightly concerned that for machines with MAX_PHYSICAL_DRIVES
>set to 2, guests would see drives 2 and 3 as present, but with no disk
>inserted.  Previously, though, I expect they would have been mirrors of
>drives 0 and 1, which is obviously worse!

FD_DOR_SELMASK is not affected by MAX_PHYSICAL_DRIVES and is fixed to 3,
so I think drive 2 and 3 are not recognized as the mirror of 0 and 1.

Because MAX_PHYSICAL_DRIVES == 2, drives[2 or 3]->bs is always null,
but it may be same as drives[0 or 1] with no diskette inserted.

I don't know how PC/AT BIOS detects the physical drive existance.
In PC-98x1 family case, BIOS executes 4 recalib commands for each drives
and check the results of sence interrupt status commands to detect
which drives are connected and power-on.
(PC-98 BIOS also check the results of sence drive status command to
detect the diskette is inserted.)

If it is similar to PC/AT case, it is the problem of fdc commands.
Now fdrive_t has the flag "connected", so we needed to fix
the sence interrupt status command that it checks "connected" flag
and changes the results.
(We may need to fix other commands in the same way.)
But I need time to investigate the real fdc behaviors on my pc.

Well, I also think it is better the user can select the physical drive
number, not only 2 but 0, 1 and 3.
But it will require the large scale patch, for example the block and
qemu option commands.

In this patch, I hope I fix only the mirror problem of drive 2 and 3,
and add "connect" flag that will help specifying several physical
drive number in future.
And I hope other 2 itmes are for another patch.

If this patch is acceptable for commit, I will reimplement PC-09 patch
based on it and in this time I hope I can fix the sence interrupt status.

Thanks,
TAKEDA, toshiya

>Cheers,
>-- 
>Stuart Brady
>
Stuart Brady - Sept. 13, 2009, 5:13 p.m.
On Mon, Sep 14, 2009 at 12:42:32AM +0900, TAKEDA, toshiya wrote:
> Dear Stuart and members,
> 
> >I'm still slightly concerned that for machines with MAX_PHYSICAL_DRIVES
> >set to 2, guests would see drives 2 and 3 as present, but with no disk
> >inserted.  Previously, though, I expect they would have been mirrors of
> >drives 0 and 1, which is obviously worse!
> 
> FD_DOR_SELMASK is not affected by MAX_PHYSICAL_DRIVES and is fixed to 3,
> so I think drive 2 and 3 are not recognized as the mirror of 0 and 1.

Agreed.

(Just to clarify, my comment about mirrors of drives 2 and 3 was
referring to the old code, when FD_DOR_SELMASK was affected by MAX_FD.)

> Well, I also think it is better the user can select the physical drive
> number, not only 2 but 0, 1 and 3.
> But it will require the large scale patch, for example the block and
> qemu option commands.

The user should really be able to attach drives individually, and have
only drive 3 connected, if they want... but that's a separate problem.

> If this patch is acceptable for commit, I will reimplement PC-09 patch
> based on it and in this time I hope I can fix the sence interrupt status.

My only concern is that a guest OS might now reserve drive letters for
drives 2 and 3, whereas before, it might have ignored those drives
because it was not possible to select them.

In reality, it seems a greater concern that without this patch, a
guest OS might allow access to the mirrors of drives 0 and 1,
potentially causing filesystem corruption. :-(

Cheers,
Natalia Portillo - Sept. 15, 2009, 12:32 p.m.
There has never been autodetection.

I can check for it if you want in IBM PC original BIOS' source code.

When the user tried to access a drive, simply the BIOS said that the  
drive does not answer.

Newer BIOS started to do a seek to check if drive is present and  
working, on seek fail, drive fails.

But it is hardcoded, if you put in the BIOS configuration that there  
is a second drive and there is none, the BIOS will indeed do a seek,  
fail, indicate the drive fails, but inform the operating system, there  
is a second drive in the system.

You can just check in any modern BIOS, disconnect any floppy drive,  
select in BIOS you have a 5.25" drive (or the oldest it can) and A:  
will appear on Windows showing you exactly that drive.

El 13/09/2009, a las 16:42, TAKEDA, toshiya escribió:

> Dear Stuart and members,
>
>> On Sun, Sep 13, 2009 at 07:07:12PM +0900, 武田 俊也 wrote:
>>> I added "connected" t fdrive_t to show physical drive is connected  
>>> or not
>>> and it is initialized in fdctrl_connect_drives().
>>>
>>> This is new patch.
>>
>> Neat. :-)
>>
>> I'm still slightly concerned that for machines with  
>> MAX_PHYSICAL_DRIVES
>> set to 2, guests would see drives 2 and 3 as present, but with no  
>> disk
>> inserted.  Previously, though, I expect they would have been  
>> mirrors of
>> drives 0 and 1, which is obviously worse!
>
> FD_DOR_SELMASK is not affected by MAX_PHYSICAL_DRIVES and is fixed  
> to 3,
> so I think drive 2 and 3 are not recognized as the mirror of 0 and 1.
>
> Because MAX_PHYSICAL_DRIVES == 2, drives[2 or 3]->bs is always null,
> but it may be same as drives[0 or 1] with no diskette inserted.
>
> I don't know how PC/AT BIOS detects the physical drive existance.
> In PC-98x1 family case, BIOS executes 4 recalib commands for each  
> drives
> and check the results of sence interrupt status commands to detect
> which drives are connected and power-on.
> (PC-98 BIOS also check the results of sence drive status command to
> detect the diskette is inserted.)
>
> If it is similar to PC/AT case, it is the problem of fdc commands.
> Now fdrive_t has the flag "connected", so we needed to fix
> the sence interrupt status command that it checks "connected" flag
> and changes the results.
> (We may need to fix other commands in the same way.)
> But I need time to investigate the real fdc behaviors on my pc.
>
> Well, I also think it is better the user can select the physical drive
> number, not only 2 but 0, 1 and 3.
> But it will require the large scale patch, for example the block and
> qemu option commands.
>
> In this patch, I hope I fix only the mirror problem of drive 2 and 3,
> and add "connect" flag that will help specifying several physical
> drive number in future.
> And I hope other 2 itmes are for another patch.
>
> If this patch is acceptable for commit, I will reimplement PC-09 patch
> based on it and in this time I hope I can fix the sence interrupt  
> status.
>
> Thanks,
> TAKEDA, toshiya
>
>> Cheers,
>> -- 
>> Stuart Brady
>>
>
>
>
>
Natalia Portillo - Sept. 15, 2009, 12:35 p.m.
DOS and seems also Windows (no matter 9x or NT) checks in CMOS, and  
only two drives can be defined, so the mirroring problem will never  
arise (they will never try to access drives 2 or 3)
Dunno about BSD, UNIX and Linux.
Seems that OS/2 does the same.

That's in IBM PC world of course dunno about Sun's x86, NEC PC-98 or  
other x86 based archs.
Surely X-Box do not check even for a floppy disk (who knows)

El 13/09/2009, a las 18:13, Stuart Brady escribió:

> On Mon, Sep 14, 2009 at 12:42:32AM +0900, TAKEDA, toshiya wrote:
>> Dear Stuart and members,
>>
>>> I'm still slightly concerned that for machines with  
>>> MAX_PHYSICAL_DRIVES
>>> set to 2, guests would see drives 2 and 3 as present, but with no  
>>> disk
>>> inserted.  Previously, though, I expect they would have been  
>>> mirrors of
>>> drives 0 and 1, which is obviously worse!
>>
>> FD_DOR_SELMASK is not affected by MAX_PHYSICAL_DRIVES and is fixed  
>> to 3,
>> so I think drive 2 and 3 are not recognized as the mirror of 0 and 1.
>
> Agreed.
>
> (Just to clarify, my comment about mirrors of drives 2 and 3 was
> referring to the old code, when FD_DOR_SELMASK was affected by  
> MAX_FD.)
>
>> Well, I also think it is better the user can select the physical  
>> drive
>> number, not only 2 but 0, 1 and 3.
>> But it will require the large scale patch, for example the block and
>> qemu option commands.
>
> The user should really be able to attach drives individually, and have
> only drive 3 connected, if they want... but that's a separate problem.
>
>> If this patch is acceptable for commit, I will reimplement PC-09  
>> patch
>> based on it and in this time I hope I can fix the sence interrupt  
>> status.
>
> My only concern is that a guest OS might now reserve drive letters for
> drives 2 and 3, whereas before, it might have ignored those drives
> because it was not possible to select them.
>
> In reality, it seems a greater concern that without this patch, a
> guest OS might allow access to the mirrors of drives 0 and 1,
> potentially causing filesystem corruption. :-(
>
> Cheers,
> -- 
> Stuart Brady
>
>
>

Patch

diff --git a/qemu/hw/fdc.c b/qemu/hw/fdc.c
index 389d9e6..419d291 100644
--- a/qemu/hw/fdc.c
+++ b/qemu/hw/fdc.c
@@ -52,6 +52,15 @@ 
 /********************************************************/
 /* Floppy drive emulation                               */
 
+/* MAX_LOGICAL_FD determines the max drive number that Intel 82078 can control,
+   and it should be 4. (If MAX_LOGICAL_FD == 2, any attempt to select drive 2
+   results in drive 0 being selected,)
+   fdctrl->num_floppies determines the number of drives that may be connected
+   for the system and is usually initialized to MAX_PHYSICAL_FD, but it may be
+   initialized to other value if any system requires. */
+
+#define MAX_LOGICAL_FD 4
+
 #define GET_CUR_DRV(fdctrl) ((fdctrl)->cur_drv)
 #define SET_CUR_DRV(fdctrl, drive) ((fdctrl)->cur_drv = (drive))
 
@@ -83,6 +92,7 @@  typedef enum fdisk_flags_t {
 typedef struct fdrive_t {
     BlockDriverState *bs;
     /* Drive status */
+    uint8_t connected;
     fdrive_type_t drive;
     uint8_t perpendicular;    /* 2.88 MB access mode    */
     /* Position */
@@ -387,6 +397,7 @@  enum {
 };
 
 enum {
+    FD_SR0_NOTRDY   = 0x08,
     FD_SR0_EQPMT    = 0x10,
     FD_SR0_SEEK     = 0x20,
     FD_SR0_ABNTERM  = 0x40,
@@ -424,11 +435,7 @@  enum {
 };
 
 enum {
-#if MAX_FD == 4
     FD_DOR_SELMASK  = 0x03,
-#else
-    FD_DOR_SELMASK  = 0x01,
-#endif
     FD_DOR_nRESET   = 0x04,
     FD_DOR_DMAEN    = 0x08,
     FD_DOR_MOTEN0   = 0x10,
@@ -438,11 +445,7 @@  enum {
 };
 
 enum {
-#if MAX_FD == 4
     FD_TDR_BOOTSEL  = 0x0c,
-#else
-    FD_TDR_BOOTSEL  = 0x04,
-#endif
 };
 
 enum {
@@ -508,10 +511,10 @@  struct fdctrl_t {
     /* Power down config (also with status regB access mode */
     uint8_t pwrd;
     /* Sun4m quirks? */
-    int sun4m;
+    uint8_t sun4m;
     /* Floppy drives */
     uint8_t num_floppies;
-    fdrive_t drives[MAX_FD];
+    fdrive_t drives[MAX_LOGICAL_FD];
     int reset_sensei;
 };
 
@@ -632,10 +635,11 @@  static CPUWriteMemoryFunc * const fdctrl_mem_write_strict[3] = {
 
 static const VMStateDescription vmstate_fdrive = {
     .name = "fdrive",
-    .version_id = 1,
-    .minimum_version_id = 1,
-    .minimum_version_id_old = 1,
+    .version_id = 2,
+    .minimum_version_id = 2,
+    .minimum_version_id_old = 2,
     .fields      = (VMStateField []) {
+        VMSTATE_UINT8_EQUAL(connected, fdrive_t),
         VMSTATE_UINT8(head, fdrive_t),
         VMSTATE_UINT8(track, fdrive_t),
         VMSTATE_UINT8(sect, fdrive_t),
@@ -661,9 +665,9 @@  static int fdc_post_load(void *opaque)
 
 static const VMStateDescription vmstate_fdc = {
     .name = "fdc",
-    .version_id = 2,
-    .minimum_version_id = 2,
-    .minimum_version_id_old = 2,
+    .version_id = 3,
+    .minimum_version_id = 3,
+    .minimum_version_id_old = 3,
     .pre_save = fdc_pre_save,
     .post_load = fdc_post_load,
     .fields      = (VMStateField []) {
@@ -692,7 +696,7 @@  static const VMStateDescription vmstate_fdc = {
         VMSTATE_UINT8(lock, fdctrl_t),
         VMSTATE_UINT8(pwrd, fdctrl_t),
         VMSTATE_UINT8_EQUAL(num_floppies, fdctrl_t),
-        VMSTATE_STRUCT_ARRAY(drives, fdctrl_t, MAX_FD, 1,
+        VMSTATE_STRUCT_ARRAY(drives, fdctrl_t, MAX_LOGICAL_FD, 1,
                              vmstate_fdrive, fdrive_t),
         VMSTATE_END_OF_LIST()
     }
@@ -771,7 +775,7 @@  static void fdctrl_reset (fdctrl_t *fdctrl, int do_irq)
     fdctrl->data_len = 0;
     fdctrl->data_state = 0;
     fdctrl->data_dir = FD_DIR_WRITE;
-    for (i = 0; i < MAX_FD; i++)
+    for (i = 0; i < MAX_LOGICAL_FD; i++)
         fd_recalibrate(&fdctrl->drives[i]);
     fdctrl_reset_fifo(fdctrl);
     if (do_irq) {
@@ -793,7 +797,6 @@  static inline fdrive_t *drv1 (fdctrl_t *fdctrl)
         return &fdctrl->drives[0];
 }
 
-#if MAX_FD == 4
 static inline fdrive_t *drv2 (fdctrl_t *fdctrl)
 {
     if ((fdctrl->tdr & FD_TDR_BOOTSEL) < (2 << 2))
@@ -809,17 +812,14 @@  static inline fdrive_t *drv3 (fdctrl_t *fdctrl)
     else
         return &fdctrl->drives[2];
 }
-#endif
 
 static fdrive_t *get_cur_drv (fdctrl_t *fdctrl)
 {
     switch (fdctrl->cur_drv) {
         case 0: return drv0(fdctrl);
         case 1: return drv1(fdctrl);
-#if MAX_FD == 4
         case 2: return drv2(fdctrl);
         case 3: return drv3(fdctrl);
-#endif
         default: return NULL;
     }
 }
@@ -969,12 +969,10 @@  static uint32_t fdctrl_read_dir (fdctrl_t *fdctrl)
 {
     uint32_t retval = 0;
 
-    if (fdctrl_media_changed(drv0(fdctrl))
-     || fdctrl_media_changed(drv1(fdctrl))
-#if MAX_FD == 4
-     || fdctrl_media_changed(drv2(fdctrl))
-     || fdctrl_media_changed(drv3(fdctrl))
-#endif
+    if ((drv0(fdctrl)->connected && fdctrl_media_changed(drv0(fdctrl)))
+     || (drv1(fdctrl)->connected && fdctrl_media_changed(drv1(fdctrl)))
+     || (drv2(fdctrl)->connected && fdctrl_media_changed(drv2(fdctrl)))
+     || (drv3(fdctrl)->connected && fdctrl_media_changed(drv3(fdctrl)))
         )
         retval |= FD_DIR_DSKCHG;
     if (retval != 0)
@@ -1416,15 +1414,10 @@  static void fdctrl_handle_dumpreg (fdctrl_t *fdctrl, int direction)
     fdrive_t *cur_drv = get_cur_drv(fdctrl);
 
     /* Drives position */
-    fdctrl->fifo[0] = drv0(fdctrl)->track;
-    fdctrl->fifo[1] = drv1(fdctrl)->track;
-#if MAX_FD == 4
-    fdctrl->fifo[2] = drv2(fdctrl)->track;
-    fdctrl->fifo[3] = drv3(fdctrl)->track;
-#else
-    fdctrl->fifo[2] = 0;
-    fdctrl->fifo[3] = 0;
-#endif
+    fdctrl->fifo[0] = drv0(fdctrl)->connected ? drv0(fdctrl)->track : 0;
+    fdctrl->fifo[1] = drv1(fdctrl)->connected ? drv1(fdctrl)->track : 0;
+    fdctrl->fifo[2] = drv2(fdctrl)->connected ? drv2(fdctrl)->track : 0;
+    fdctrl->fifo[3] = drv3(fdctrl)->connected ? drv3(fdctrl)->track : 0;
     /* timers */
     fdctrl->fifo[4] = fdctrl->timer0;
     fdctrl->fifo[5] = (fdctrl->timer1 << 1) | (fdctrl->dor & FD_DOR_DMAEN ? 1 : 0);
@@ -1454,12 +1447,18 @@  static void fdctrl_handle_restore (fdctrl_t *fdctrl, int direction)
     fdrive_t *cur_drv = get_cur_drv(fdctrl);
 
     /* Drives position */
-    drv0(fdctrl)->track = fdctrl->fifo[3];
-    drv1(fdctrl)->track = fdctrl->fifo[4];
-#if MAX_FD == 4
-    drv2(fdctrl)->track = fdctrl->fifo[5];
-    drv3(fdctrl)->track = fdctrl->fifo[6];
-#endif
+    if(drv0(fdctrl)->connected) {
+        drv0(fdctrl)->track = fdctrl->fifo[3];
+    }
+    if(drv1(fdctrl)->connected) {
+        drv1(fdctrl)->track = fdctrl->fifo[4];
+    }
+    if(drv2(fdctrl)->connected) {
+        drv2(fdctrl)->track = fdctrl->fifo[5];
+    }
+    if(drv3(fdctrl)->connected) {
+        drv3(fdctrl)->track = fdctrl->fifo[6];
+    }
     /* timers */
     fdctrl->timer0 = fdctrl->fifo[7];
     fdctrl->timer1 = fdctrl->fifo[8];
@@ -1479,15 +1478,10 @@  static void fdctrl_handle_save (fdctrl_t *fdctrl, int direction)
     fdctrl->fifo[0] = 0;
     fdctrl->fifo[1] = 0;
     /* Drives position */
-    fdctrl->fifo[2] = drv0(fdctrl)->track;
-    fdctrl->fifo[3] = drv1(fdctrl)->track;
-#if MAX_FD == 4
-    fdctrl->fifo[4] = drv2(fdctrl)->track;
-    fdctrl->fifo[5] = drv3(fdctrl)->track;
-#else
-    fdctrl->fifo[4] = 0;
-    fdctrl->fifo[5] = 0;
-#endif
+    fdctrl->fifo[2] = drv0(fdctrl)->connected ? drv0(fdctrl)->track : 0;
+    fdctrl->fifo[3] = drv1(fdctrl)->connected ? drv1(fdctrl)->track : 0;
+    fdctrl->fifo[4] = drv2(fdctrl)->connected ? drv2(fdctrl)->track : 0;
+    fdctrl->fifo[5] = drv3(fdctrl)->connected ? drv3(fdctrl)->track : 0;
     /* timers */
     fdctrl->fifo[6] = fdctrl->timer0;
     fdctrl->fifo[7] = fdctrl->timer1;
@@ -1833,8 +1827,14 @@  static void fdctrl_connect_drives(fdctrl_t *fdctrl, BlockDriverState **fds)
 {
     unsigned int i;
 
-    for (i = 0; i < MAX_FD; i++) {
-        fd_init(&fdctrl->drives[i], fds[i]);
+    for (i = 0; i < MAX_LOGICAL_FD; i++) {
+        if (i < fdctrl->num_floppies) {
+            fdctrl->drives[i].connected = 1;
+            fd_init(&fdctrl->drives[i], fds[i]);
+        } else {
+            fdctrl->drives[i].connected = 0;
+            fd_init(&fdctrl->drives[i], NULL);
+        }
         fd_revalidate(&fdctrl->drives[i]);
     }
 }
@@ -1851,6 +1851,7 @@  fdctrl_t *fdctrl_init_isa(BlockDriverState **fds)
     fdctrl->dma_chann = dma_chann;
     DMA_register_channel(dma_chann, &fdctrl_transfer_handler, fdctrl);
 
+    fdctrl->num_floppies = MAX_PHYSICAL_FD;
     fdctrl_connect_drives(fdctrl, fds);
 
     return fdctrl;
@@ -1873,6 +1874,8 @@  fdctrl_t *fdctrl_init_sysbus(qemu_irq irq, int dma_chann,
 
     fdctrl->dma_chann = dma_chann;
     DMA_register_channel(dma_chann, &fdctrl_transfer_handler, fdctrl);
+
+    fdctrl->num_floppies = MAX_PHYSICAL_FD;
     fdctrl_connect_drives(fdctrl, fds);
 
     return fdctrl;
@@ -1895,6 +1898,7 @@  fdctrl_t *sun4m_fdctrl_init (qemu_irq irq, target_phys_addr_t io_base,
 
     fdctrl->dma_chann = -1;
 
+    fdctrl->num_floppies = MAX_PHYSICAL_FD;
     fdctrl_connect_drives(fdctrl, fds);
 
     return fdctrl;
@@ -1925,7 +1929,6 @@  static int fdctrl_init_common(fdctrl_t *fdctrl)
 
     fdctrl->version = 0x90; /* Intel 82078 controller */
     fdctrl->config = FD_CONFIG_EIS | FD_CONFIG_EFIFO; /* Implicit seek, polling & FIFO enabled */
-    fdctrl->num_floppies = MAX_FD;
 
     fdctrl_external_reset(fdctrl);
     vmstate_register(-1, &vmstate_fdc, fdctrl);
diff --git a/qemu/hw/fdc.h b/qemu/hw/fdc.h
index 1b81ec1..9614e20 100644
--- a/qemu/hw/fdc.h
+++ b/qemu/hw/fdc.h
@@ -1,5 +1,5 @@ 
 /* fdc.c */
-#define MAX_FD 2
+#define MAX_PHYSICAL_FD 2
 
 typedef struct fdctrl_t fdctrl_t;
 
diff --git a/qemu/hw/mips_jazz.c b/qemu/hw/mips_jazz.c
index d62a584..bdb7865 100644
--- a/qemu/hw/mips_jazz.c
+++ b/qemu/hw/mips_jazz.c
@@ -127,7 +127,7 @@  void mips_jazz_init (ram_addr_t ram_size,
     int s_rtc, s_dma_dummy;
     NICInfo *nd;
     PITState *pit;
-    BlockDriverState *fds[MAX_FD];
+    BlockDriverState *fds[MAX_PHYSICAL_FD];
     qemu_irq esp_reset;
     ram_addr_t ram_offset;
     ram_addr_t bios_offset;
@@ -230,11 +230,11 @@  void mips_jazz_init (ram_addr_t ram_size,
              rc4030[5], &esp_reset);
 
     /* Floppy */
-    if (drive_get_max_bus(IF_FLOPPY) >= MAX_FD) {
+    if (drive_get_max_bus(IF_FLOPPY) >= MAX_PHYSICAL_FD) {
         fprintf(stderr, "qemu: too many floppy drives\n");
         exit(1);
     }
-    for (n = 0; n < MAX_FD; n++) {
+    for (n = 0; n < MAX_PHYSICAL_FD; n++) {
         DriveInfo *dinfo = drive_get(IF_FLOPPY, 0, n);
         fds[n] = dinfo ? dinfo->bdrv : NULL;
     }
diff --git a/qemu/hw/mips_malta.c b/qemu/hw/mips_malta.c
index 25e32bf..579db1c 100644
--- a/qemu/hw/mips_malta.c
+++ b/qemu/hw/mips_malta.c
@@ -777,7 +777,7 @@  void mips_malta_init (ram_addr_t ram_size,
     int i;
     DriveInfo *dinfo;
     DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
-    BlockDriverState *fd[MAX_FD];
+    BlockDriverState *fd[MAX_PHYSICAL_FD];
     int fl_idx = 0;
     int fl_sectors = 0;
 
@@ -928,7 +928,7 @@  void mips_malta_init (ram_addr_t ram_size,
     serial_init(0x2f8, isa_reserve_irq(3), 115200, serial_hds[1]);
     if (parallel_hds[0])
         parallel_init(0x378, isa_reserve_irq(7), parallel_hds[0]);
-    for(i = 0; i < MAX_FD; i++) {
+    for(i = 0; i < MAX_PHYSICAL_FD; i++) {
         dinfo = drive_get(IF_FLOPPY, 0, i);
         fd[i] = dinfo ? dinfo->bdrv : NULL;
     }
diff --git a/qemu/hw/pc.c b/qemu/hw/pc.c
index d96d756..a4d05e6 100644
--- a/qemu/hw/pc.c
+++ b/qemu/hw/pc.c
@@ -1133,7 +1133,7 @@  static void pc_init1(ram_addr_t ram_size,
     IsaIrqState *isa_irq_state;
     DriveInfo *dinfo;
     DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
-    BlockDriverState *fd[MAX_FD];
+    BlockDriverState *fd[MAX_PHYSICAL_FD];
     int using_vga = cirrus_vga_enabled || std_vga_enabled || vmsvga_enabled;
     void *fw_cfg;
 
@@ -1379,7 +1379,7 @@  static void pc_init1(ram_addr_t ram_size,
     audio_init(pci_enabled ? pci_bus : NULL, isa_irq);
 #endif
 
-    for(i = 0; i < MAX_FD; i++) {
+    for(i = 0; i < MAX_PHYSICAL_FD; i++) {
         dinfo = drive_get(IF_FLOPPY, 0, i);
         fd[i] = dinfo ? dinfo->bdrv : NULL;
     }
diff --git a/qemu/hw/ppc_prep.c b/qemu/hw/ppc_prep.c
index 1930146..afea2e9 100644
--- a/qemu/hw/ppc_prep.c
+++ b/qemu/hw/ppc_prep.c
@@ -564,7 +564,7 @@  static void ppc_prep_init (ram_addr_t ram_size,
     int ppc_boot_device;
     DriveInfo *dinfo;
     DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
-    BlockDriverState *fd[MAX_FD];
+    BlockDriverState *fd[MAX_PHYSICAL_FD];
 
     sysctrl = qemu_mallocz(sizeof(sysctrl_t));
 
@@ -715,7 +715,7 @@  static void ppc_prep_init (ram_addr_t ram_size,
     DMA_init(1);
     //    SB16_init();
 
-    for(i = 0; i < MAX_FD; i++) {
+    for(i = 0; i < MAX_PHYSICAL_FD; i++) {
         dinfo = drive_get(IF_FLOPPY, 0, i);
         fd[i] = dinfo ? dinfo->bdrv : NULL;
     }
diff --git a/qemu/hw/sun4m.c b/qemu/hw/sun4m.c
index d970723..fc28036 100644
--- a/qemu/hw/sun4m.c
+++ b/qemu/hw/sun4m.c
@@ -747,7 +747,7 @@  static void sun4m_hw_init(const struct sun4m_hwdef *hwdef, ram_addr_t RAM_size,
     qemu_irq fdc_tc;
     qemu_irq *cpu_halt;
     unsigned long kernel_size;
-    BlockDriverState *fd[MAX_FD];
+    BlockDriverState *fd[MAX_PHYSICAL_FD];
     void *fw_cfg;
     DriveInfo *dinfo;
 
@@ -1551,7 +1551,7 @@  static void sun4c_hw_init(const struct sun4c_hwdef *hwdef, ram_addr_t RAM_size,
     qemu_irq esp_reset;
     qemu_irq fdc_tc;
     unsigned long kernel_size;
-    BlockDriverState *fd[MAX_FD];
+    BlockDriverState *fd[MAX_PHYSICAL_FD];
     void *fw_cfg;
     DeviceState *dev;
     unsigned int i;
diff --git a/qemu/hw/sun4u.c b/qemu/hw/sun4u.c
index ffda4cd..ac91d14 100644
--- a/qemu/hw/sun4u.c
+++ b/qemu/hw/sun4u.c
@@ -561,7 +561,7 @@  static void sun4uv_init(ram_addr_t RAM_size,
     PCIBus *pci_bus, *pci_bus2, *pci_bus3;
     qemu_irq *irq;
     DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
-    BlockDriverState *fd[MAX_FD];
+    BlockDriverState *fd[MAX_PHYSICAL_FD];
     void *fw_cfg;
     DriveInfo *dinfo;
 
@@ -618,7 +618,7 @@  static void sun4uv_init(ram_addr_t RAM_size,
     pci_cmd646_ide_init(pci_bus, hd, 1);
 
     isa_create_simple("i8042");
-    for(i = 0; i < MAX_FD; i++) {
+    for(i = 0; i < MAX_PHYSICAL_FD; i++) {
         dinfo = drive_get(IF_FLOPPY, 0, i);
         fd[i] = dinfo ? dinfo->bdrv : NULL;
     }