From 9bc05c7f2c50aecb65627704a083b1235264e67b Mon Sep 17 00:00:00 2001 Message-Id: <9bc05c7f2c50aecb65627704a083b1235264e67b.1343915404.git.minovotn@redhat.com> In-Reply-To: <5b3bcf18e866636f24ca1c23eb94d5caf23c6dd6.1343915404.git.minovotn@redhat.com> References: <5b3bcf18e866636f24ca1c23eb94d5caf23c6dd6.1343915404.git.minovotn@redhat.com> From: Pavel Hrdina Date: Mon, 16 Jul 2012 16:14:52 +0200 Subject: [PATCH 3/7] fdc: fix media detection RH-Author: Pavel Hrdina Message-id: <516314236f780d28207de35c4b28d0b31ef8f6ca.1342446805.git.phrdina@redhat.com> Patchwork-id: 40340 O-Subject: [RHEL-6.4 qemu-kvm PATCH v6 3/6] fdc: fix media detection Bugzilla: 729244 RH-Acked-by: Laszlo Ersek RH-Acked-by: Miroslav Rezanina RH-Acked-by: Michal Novotny We have to set up 'media_changed' after guest start so floppy driver could detect that there is no media in drive. For this purpose we call 'fdctrl_change_cb' instead of 'fd_revalidate' in 'fdctrl_connect_drives'. 'fd_revalidate' is called inside 'fdctrl_change_cb'. We still have to set default drive geometry in 'fd_revalidate' even if there is no media in drive. When you try to open (windows) or mount (linux) floppy the driver tries to seek on track 1. Linux guest stuck in loop then kernel crashes and windows guest prints error message. Signed-off-by: Pavel Hrdina Signed-off-by: Kevin Wolf (cherry picked from commit cfb08fbafcd946341bdf14103293887763802697) --- hw/fdc.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) Signed-off-by: Michal Novotny --- hw/fdc.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/hw/fdc.c b/hw/fdc.c index 0858b76..8c5aa7f 100644 --- a/hw/fdc.c +++ b/hw/fdc.c @@ -243,7 +243,7 @@ static void fd_revalidate (fdrive_t *drv) int nb_heads, max_track, last_sect, ro; 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_geometry_hint(drv->bs, &nb_heads, &max_track, &last_sect); if (nb_heads != 0 && max_track != 0 && last_sect != 0) { @@ -280,8 +280,12 @@ static void fd_revalidate (fdrive_t *drv) max_track = parse->max_track; last_sect = parse->last_sect; drv->drive = parse->drive; - FLOPPY_DPRINTF("%s floppy disk (%d h %d t %d s) %s\n", parse->str, - nb_heads, max_track, last_sect, ro ? "ro" : "rw"); + if (bdrv_is_inserted(drv->bs)) { + FLOPPY_DPRINTF("%s floppy disk (%d h %d t %d s) %s\n", parse->str, + nb_heads, max_track, last_sect, ro ? "ro" : "rw"); + } else { + FLOPPY_DPRINTF("No disk in drive\n"); + } } if (nb_heads == 1) { drv->flags &= ~FDISK_DBL_SIDES; @@ -292,7 +296,7 @@ static void fd_revalidate (fdrive_t *drv) drv->last_sect = last_sect; drv->ro = ro; } else { - FLOPPY_DPRINTF("No disk in drive\n"); + FLOPPY_DPRINTF("No drive connected\n"); drv->last_sect = 0; drv->max_track = 0; drv->flags &= ~FDISK_DBL_SIDES; @@ -787,7 +791,7 @@ static void fdctrl_raise_irq (fdctrl_t *fdctrl, uint8_t status0) fdrive_t *cur_drv; /* A seek clears the disk change line (if a disk is inserted) */ cur_drv = get_cur_drv(fdctrl); - if (cur_drv->max_track) { + if (cur_drv->bs != NULL && bdrv_is_inserted(cur_drv->bs)) { cur_drv->media_changed = 0; } } @@ -1891,7 +1895,7 @@ static void fdctrl_connect_drives(fdctrl_t *fdctrl) drive = &fdctrl->drives[i]; fd_init(drive); - fd_revalidate(drive); + fdctrl_change_cb(drive, 0); if (drive->bs) { bdrv_set_dev_ops(drive->bs, &fdctrl_block_ops, drive); } -- 1.7.10.4