Pavel Hrdina <phrd...@redhat.com> writes:

> Hi,
> this is the patch to fix incorrect handling of IDE floppy drive controller 
> emulation
> when no media is present. If the guest is booted without a media then the 
> drive
> was not being emulated at all but this patch enables the emulation with no 
> media present.
>
> There was a bug in FDC emulation without media. Driver was not able to 
> recognize that
> there is no media in drive.
>
> This has been tested on both Fedora-16 x86_64 VM and Windows XP VM and the 
> behaviour
> is as expected, i.e. as follows:
>
> Linux guest (Fedora 16 x86_64) tries "mount /dev/fd0" and exit with error
> "mount: /dev/fd0 is not a valid block device" which is the same behavior like
> bare metal with real floppy device (you have to load floppy driver at first
> using e.g. "modprobe floppy" command).
>
> For Windows XP guest the Windows floppy driver is trying to seek the virtual 
> drive
> when you want to open it but driver successfully detect that there is no 
> media in drive
> and then it's asking user to insert floppy media in the drive.
>
> I also tested behavior of this patch if you start guest with "-nodefaults" 
> and both
> Windows and Linux guests detect only FDC but no drive.
>
> Pavel

As Andreas already pointed out, your commit message needs work.  Please
limit line length to 70 characters.

> This patch has been written with help of specifications from:
> http://www.ousob.com/ng/hardware/ngd127.php
> http://www.isdaman.com/alsos/hardware/fdc/floppy.htm
> http://wiki.osdev.org/Floppy_Disk_Controller
>
> Signed-off-by: Pavel Hrdina <phrd...@redhat.com>
> Signed-off-by: Michal Novotny <minov...@redhat.com>
> ---
>  hw/fdc.c |   14 ++++++++++----
>  hw/pc.c  |    3 ++-
>  2 files changed, 12 insertions(+), 5 deletions(-)
>
> diff --git a/hw/fdc.c b/hw/fdc.c
> index a0236b7..6791eff 100644
> --- a/hw/fdc.c
> +++ b/hw/fdc.c
> @@ -179,12 +179,14 @@ static void fd_revalidate(FDrive *drv)
>      FDriveRate rate;
>  
>      FLOPPY_DPRINTF("revalidate\n");
> -    if (drv->bs != NULL && bdrv_is_inserted(drv->bs)) {
> +    if (drv->bs != NULL) {
>          ro = bdrv_is_read_only(drv->bs);
>          bdrv_get_floppy_geometry_hint(drv->bs, &nb_heads, &max_track,
>                                        &last_sect, drv->drive, &drive, &rate);
> -        if (nb_heads != 0 && max_track != 0 && last_sect != 0) {
> -            FLOPPY_DPRINTF("User defined disk (%d %d %d)",
> +        if (!bdrv_is_inserted(drv->bs)) {
> +            FLOPPY_DPRINTF("No media in drive\n");
> +        } else if (nb_heads != 0 && max_track != 0 && last_sect != 0) {
> +            FLOPPY_DPRINTF("User defined disk (%d %d %d)\n",
>                             nb_heads - 1, max_track, last_sect);
>          } else {
>              FLOPPY_DPRINTF("Floppy disk (%d h %d t %d s) %s\n", nb_heads,
> @@ -201,11 +203,12 @@ static void fd_revalidate(FDrive *drv)
>          drv->drive = drive;
>          drv->media_rate = rate;
>      } else {
> -        FLOPPY_DPRINTF("No disk in drive\n");
> +        FLOPPY_DPRINTF("Drive disabled\n");
>          drv->last_sect = 0;
>          drv->max_track = 0;
>          drv->flags &= ~FDISK_DBL_SIDES;
>      }
> +
>  }
>  
>  /********************************************************/
> @@ -937,6 +940,9 @@ static int fdctrl_media_changed(FDrive *drv)
>  
>      if (!drv->bs)
>          return 0;
> +    /* This is needed for driver to detect there is no media in drive */
> +    if (!bdrv_is_inserted(drv->bs))
> +        return 1;
>      if (drv->media_changed) {
>          drv->media_changed = 0;
>          ret = 1;
> diff --git a/hw/pc.c b/hw/pc.c
> index 1f5aacb..29a604b 100644
> --- a/hw/pc.c
> +++ b/hw/pc.c
> @@ -382,7 +382,8 @@ void pc_cmos_init(ram_addr_t ram_size, ram_addr_t 
> above_4g_mem_size,
>      if (floppy) {
>          fdc_get_bs(fd, floppy);
>          for (i = 0; i < 2; i++) {
> -            if (fd[i] && bdrv_is_inserted(fd[i])) {
> +            /* If there is no media in a drive, we still have the drive 
> present */

This comment explains why you remove bdrv_is_inserted().  It makes no
sense once its gone.

> +            if (fd[i]) {
>                  bdrv_get_floppy_geometry_hint(fd[i], &nb_heads, &max_track,
>                                                &last_sect, FDRIVE_DRV_NONE,
>                                                &fd_type[i], &rate);

This fixes the CMOS floppy initialization bug I described elsewhere in
the thread, because bdrv_get_floppy_geometry_hint() picks FDRIVE_DRV_144
when its bs argument is empty.

Are you sure the patches to fdc.c are necessary to fix the bug you're
seeing?  To be honest, I doubt it.

Reply via email to