From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:56722) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1a9KN2-0004UQ-GW for qemu-devel@nongnu.org; Wed, 16 Dec 2015 17:16:29 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1a9KN1-00085e-BX for qemu-devel@nongnu.org; Wed, 16 Dec 2015 17:16:28 -0500 From: John Snow Date: Wed, 16 Dec 2015 17:16:12 -0500 Message-Id: <1450304177-3935-7-git-send-email-jsnow@redhat.com> In-Reply-To: <1450304177-3935-1-git-send-email-jsnow@redhat.com> References: <1450304177-3935-1-git-send-email-jsnow@redhat.com> Subject: [Qemu-devel] [PATCH v3 06/11] fdc: do not call revalidate on eject List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-block@nongnu.org Cc: kwolf@redhat.com, John Snow , armbru@redhat.com, qemu-devel@nongnu.org Currently, fd_revalidate is called in two different places, with two different expectations of behavior: (1) On initialization, as a routine to help pick the drive type and initial geometries as a side-effect of the pick_geometry routine (2) On insert/eject, which either sets the geometries to a default value or chooses new geometries based on the inserted diskette. Break this nonsense apart by creating a new function dedicated towards picking the drive type on initialization. This has a few results: (1) fd_revalidate does not get called on boot anymore for drives with no diskette. (2) pick_geometry will actually get called twice if we have a diskette inserted, but this is harmless. (Once for the drive type, and once as part of the media callback.) Signed-off-by: John Snow --- hw/block/fdc.c | 36 +++++++++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/hw/block/fdc.c b/hw/block/fdc.c index b587de8..e752758 100644 --- a/hw/block/fdc.c +++ b/hw/block/fdc.c @@ -167,6 +167,7 @@ static void fd_init(FDrive *drv) drv->disk = FLOPPY_DRIVE_TYPE_NONE; drv->last_sect = 0; drv->max_track = 0; + drv->ro = true; } #define NUM_SIDES(drv) ((drv)->flags & FDISK_DBL_SIDES ? 2 : 1) @@ -249,13 +250,21 @@ static void fd_recalibrate(FDrive *drv) fd_seek(drv, 0, 0, 1, 1); } -static void pick_geometry(FDrive *drv) +/** + * Determine geometry based on inserted diskette. + */ +static bool pick_geometry(FDrive *drv) { BlockBackend *blk = drv->blk; const FDFormat *parse; uint64_t nb_sectors, size; int i, first_match, match; + /* We can only pick a geometry if we have a diskette. */ + if (!drv->media_inserted) { + return false; + } + blk_get_geometry(blk, &nb_sectors); match = -1; first_match = -1; @@ -293,8 +302,7 @@ static void pick_geometry(FDrive *drv) } drv->max_track = parse->max_track; drv->last_sect = parse->last_sect; - drv->drive = parse->drive; - drv->disk = drv->media_inserted ? parse->drive : FLOPPY_DRIVE_TYPE_NONE; + drv->disk = parse->drive; drv->media_rate = parse->rate; if (drv->media_inserted) { @@ -303,6 +311,14 @@ static void pick_geometry(FDrive *drv) drv->max_track, drv->last_sect, drv->ro ? "ro" : "rw"); } + return true; +} + +static void pick_drive_type(FDrive *drv) +{ + if (pick_geometry(drv)) { + drv->drive = drv->disk; + } } /* Revalidate a disk drive after a disk change */ @@ -311,15 +327,18 @@ static void fd_revalidate(FDrive *drv) FLOPPY_DPRINTF("revalidate\n"); if (drv->blk != NULL) { drv->ro = blk_is_read_only(drv->blk); - pick_geometry(drv); if (!drv->media_inserted) { FLOPPY_DPRINTF("No disk in drive\n"); + drv->disk = FLOPPY_DRIVE_TYPE_NONE; + } else { + pick_geometry(drv); } } else { FLOPPY_DPRINTF("No drive connected\n"); drv->last_sect = 0; drv->max_track = 0; drv->flags &= ~FDISK_DBL_SIDES; + drv->disk = FLOPPY_DRIVE_TYPE_NONE; } } @@ -2196,9 +2215,11 @@ static void fdctrl_change_cb(void *opaque, bool load) FDrive *drive = opaque; drive->media_inserted = load && drive->blk && blk_is_inserted(drive->blk); - drive->media_changed = 1; - fd_revalidate(drive); + + if (load) { + fd_revalidate(drive); + } } static bool fdctrl_is_tray_open(void *opaque) @@ -2234,13 +2255,14 @@ static void fdctrl_connect_drives(FDCtrl *fdctrl, Error **errp) } fd_init(drive); - fdctrl_change_cb(drive, 0); if (drive->blk) { blk_set_dev_ops(drive->blk, &fdctrl_block_ops, drive); drive->media_inserted = blk_is_inserted(drive->blk); + pick_drive_type(drive); } else { drive->drive = FLOPPY_DRIVE_TYPE_NONE; } + fdctrl_change_cb(drive, drive->media_inserted); } } -- 2.4.3