From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:36100) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aMinw-00079G-38 for qemu-devel@nongnu.org; Fri, 22 Jan 2016 15:59:37 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1aMinu-0005gn-Rz for qemu-devel@nongnu.org; Fri, 22 Jan 2016 15:59:36 -0500 References: <1453495865-9649-1-git-send-email-jsnow@redhat.com> <1453495865-9649-11-git-send-email-jsnow@redhat.com> From: John Snow Message-ID: <56A2982E.1060104@redhat.com> Date: Fri, 22 Jan 2016 15:59:26 -0500 MIME-Version: 1.0 In-Reply-To: <1453495865-9649-11-git-send-email-jsnow@redhat.com> Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: quoted-printable Subject: Re: [Qemu-devel] [PATCH v5 10/12] fdc: rework pick_geometry List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-block@nongnu.org Cc: kwolf@redhat.com, armbru@redhat.com, qemu-devel@nongnu.org On 01/22/2016 03:51 PM, John Snow wrote: > This one is the crazy one. >=20 > fd_revalidate currently uses pick_geometry to tell if the diskette > geometry has changed upon an eject/insert event, but it won't allow us > to insert a 1.44MB diskette into a 2.88MB drive. This is inflexible. >=20 > The new algorithm applies a new heuristic to guessing disk geometries > that allows us to switch diskette types as long as the physical size > matches before falling back to the old heuristic. >=20 > The old one is roughly: > - If the size (sectors) and type matches, choose it. > - Fall back to the first geometry that matched our type. >=20 > The new one is: > - If the size (sectors) and type matches, choose it. > - If the size (sectors) and physical size match, choose it. > - If the size (sectors) matches at all, choose it begrudgingly. > - Fall back to the first geometry that matched our type. >=20 Goofed and didn't update commit. Will change on PULL to omit the third line if the patch is otherwise OK. > Signed-off-by: John Snow > --- > hw/block/fdc.c | 72 ++++++++++++++++++++++++++++++++++++++++++--------= -------- > 1 file changed, 52 insertions(+), 20 deletions(-) >=20 > diff --git a/hw/block/fdc.c b/hw/block/fdc.c > index e51154b..6e0c5fc 100644 > --- a/hw/block/fdc.c > +++ b/hw/block/fdc.c > @@ -125,7 +125,6 @@ static const FDFormat fd_formats[] =3D { > { FLOPPY_DRIVE_TYPE_NONE, -1, -1, 0, 0, }, > }; > =20 > -__attribute__((__unused__)) > static FDriveSize drive_size(FloppyDriveType drive) > { > switch (drive) { > @@ -284,45 +283,78 @@ static int pick_geometry(FDrive *drv) > BlockBackend *blk =3D drv->blk; > const FDFormat *parse; > uint64_t nb_sectors, size; > - int i, first_match, match; > + int i; > + int match, size_match, type_match; > + bool magic =3D drv->drive =3D=3D FLOPPY_DRIVE_TYPE_AUTO; > =20 > /* We can only pick a geometry if we have a diskette. */ > if (!drv->media_inserted || drv->drive =3D=3D FLOPPY_DRIVE_TYPE_NO= NE) { > return -1; > } > =20 > + /* We need to determine the likely geometry of the inserted medium= . > + * In order of preference, we look for: > + * (1) The same drive type and number of sectors, > + * (2) The same diskette size and number of sectors, > + * (3) The same drive type. > + * > + * In all cases, matches that occur higher in the drive table will= take > + * precedence over matches that occur later in the table. > + */ > blk_get_geometry(blk, &nb_sectors); > - match =3D -1; > - first_match =3D -1; > + match =3D size_match =3D type_match =3D -1; > for (i =3D 0; ; i++) { > parse =3D &fd_formats[i]; > if (parse->drive =3D=3D FLOPPY_DRIVE_TYPE_NONE) { > break; > } > - if (drv->drive =3D=3D parse->drive || > - drv->drive =3D=3D FLOPPY_DRIVE_TYPE_AUTO) { > - size =3D (parse->max_head + 1) * parse->max_track * > - parse->last_sect; > - if (nb_sectors =3D=3D size) { > - match =3D i; > - break; > + size =3D (parse->max_head + 1) * parse->max_track * parse->las= t_sect; > + if (nb_sectors =3D=3D size) { > + if (magic || parse->drive =3D=3D drv->drive) { > + /* (1) perfect match -- nb_sectors and drive type */ > + goto out; > + } else if (drive_size(parse->drive) =3D=3D drive_size(drv-= >drive)) { > + /* (2) size match -- nb_sectors and physical medium si= ze */ > + match =3D (match =3D=3D -1) ? i : match; > + } else { > + /* This is suspicious -- Did the user misconfigure? */ > + size_match =3D (size_match =3D=3D -1) ? i : size_match= ; > } > - if (first_match =3D=3D -1) { > - first_match =3D i; > + } else if (type_match =3D=3D -1) { > + if ((parse->drive =3D=3D drv->drive) || > + (magic && (parse->drive =3D=3D get_fallback_drive_type= (drv)))) { > + /* (3) type match -- nb_sectors mismatch, but matches = the type > + * specified explicitly by the user, or matches th= e fallback > + * default type when using the drive autodetect me= chanism */ > + type_match =3D i; > } > } > } > + > + /* No exact match found */ > if (match =3D=3D -1) { > - if (first_match =3D=3D -1) { > - error_setg(&error_abort, "No candidate geometries present = in table " > - " for floppy drive type '%s'", > - FloppyDriveType_lookup[drv->drive]); > - } else { > - match =3D first_match; > + if (size_match !=3D -1) { > + parse =3D &fd_formats[size_match]; > + FLOPPY_DPRINTF("User requested floppy drive type '%s', " > + "but inserted medium appears to be a " > + "%d sector '%s' type\n", > + FloppyDriveType_lookup[drv->drive], > + nb_sectors, > + FloppyDriveType_lookup[parse->drive]); > } > - parse =3D &fd_formats[match]; > + match =3D type_match; > } > =20 > + /* No match of any kind found -- fd_format is misconfigured, abort= . */ > + if (match =3D=3D -1) { > + error_setg(&error_abort, "No candidate geometries present in t= able " > + " for floppy drive type '%s'", > + FloppyDriveType_lookup[drv->drive]); > + } > + > + parse =3D &(fd_formats[match]); > + > + out: > if (parse->max_head =3D=3D 0) { > drv->flags &=3D ~FDISK_DBL_SIDES; > } else { >=20 --=20 =97js