All of lore.kernel.org
 help / color / mirror / Atom feed
From: John Snow <jsnow@redhat.com>
To: qemu-block@nongnu.org
Cc: kwolf@redhat.com, John Snow <jsnow@redhat.com>,
	armbru@redhat.com, qemu-devel@nongnu.org
Subject: [Qemu-devel] [PATCH for-2.6 v2 08/10] fdc: rework pick_geometry
Date: Mon,  7 Dec 2015 18:34:33 -0500	[thread overview]
Message-ID: <1449531275-30362-9-git-send-email-jsnow@redhat.com> (raw)
In-Reply-To: <1449531275-30362-1-git-send-email-jsnow@redhat.com>

This one is the crazy one.

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.

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.

The old one is roughly:
 - If the size and type matches, choose it.
 - Fall back to the first geometry that matched our type.

The new one is:
 - If the size 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.

Signed-off-by: John Snow <jsnow@redhat.com>
---
 hw/block/fdc.c | 63 +++++++++++++++++++++++++++++++++++++---------------------
 1 file changed, 40 insertions(+), 23 deletions(-)

diff --git a/hw/block/fdc.c b/hw/block/fdc.c
index 12a2595..246bd83 100644
--- a/hw/block/fdc.c
+++ b/hw/block/fdc.c
@@ -132,7 +132,6 @@ static const FDFormat fd_formats[] = {
     { FLOPPY_DRIVE_TYPE_NONE, -1, -1, 0, 0, },
 };
 
-__attribute__((__unused__))
 static FDriveSize drive_size(FloppyDriveType drive)
 {
     switch (drive) {
@@ -287,45 +286,63 @@ static bool pick_geometry(FDrive *drv)
     BlockBackend *blk = 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 = drv->drive == FLOPPY_DRIVE_TYPE_AUTO;
 
     /* We can only pick a geometry if we have a diskette. */
     if (!drv->media_inserted) {
         return false;
     }
 
+    /* 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 number of sectors,
+     * (4) 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 = -1;
-    first_match = -1;
+    match = size_match = type_match = -1;
     for (i = 0; ; i++) {
         parse = &fd_formats[i];
         if (parse->drive == FLOPPY_DRIVE_TYPE_NONE) {
             break;
         }
-        if (drv->drive == parse->drive ||
-            drv->drive == FLOPPY_DRIVE_TYPE_AUTO) {
-            size = (parse->max_head + 1) * parse->max_track *
-                parse->last_sect;
-            if (nb_sectors == size) {
-                match = i;
-                break;
-            }
-            if (first_match == -1) {
-                first_match = i;
+        size = (parse->max_head + 1) * parse->max_track * parse->last_sect;
+        if (nb_sectors == size) {
+            if (magic || parse->drive == drv->drive) {
+                /* (1) perfect match */
+                goto out;
+            } else if (drive_size(parse->drive) == drive_size(drv->drive)) {
+                /* (2) physical size match */
+                match = (match == -1) ? i : match;
+            } else {
+                /* (3) nsectors match only */
+                size_match = (size_match == -1) ? i : size_match;
             }
+        } else if ((type_match == -1) &&
+                   ((parse->drive == drv->drive) ||
+                    (magic && (parse->drive == FDRIVE_AUTO_FALLBACK)))) {
+            /* (4) type matches, or type matches the autodetect default if we
+             *     are using the autodetect mechanism. */
+            type_match = i;
         }
     }
+
     if (match == -1) {
-        if (first_match == -1) {
-            /* No entry found: drive_type was NONE or we neglected to add any
-             * candidate geometries for our drive type into the fd_formats table
-             */
-            match = ARRAY_SIZE(fd_formats) - 1;
-        } else {
-            match = first_match;
-        }
-        parse = &fd_formats[match];
+        match = (size_match != -1) ? size_match : type_match;
+    }
+
+    if (match == -1) {
+        /* No entry found: drive_type was NONE or we neglected to add any
+         * candidate geometries for our drive type into the fd_formats table. */
+        match = ARRAY_SIZE(fd_formats) - 1;
     }
+    parse = &(fd_formats[match]);
 
  out:
     if (parse->max_head == 0) {
-- 
2.4.3

  parent reply	other threads:[~2015-12-07 23:34 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-12-07 23:34 [Qemu-devel] [PATCH for-2.6 v2 00/10] fdc: fix 2.88mb floppy diskette support John Snow
2015-12-07 23:34 ` [Qemu-devel] [PATCH for-2.6 v2 01/10] fdc: move pick_geometry John Snow
2015-12-15 21:51   ` Hervé Poussineau
2015-12-15 21:56     ` John Snow
2015-12-16 21:14     ` John Snow
2015-12-07 23:34 ` [Qemu-devel] [PATCH for-2.6 v2 02/10] fdc: refactor pick_geometry John Snow
2015-12-07 23:34 ` [Qemu-devel] [PATCH for-2.6 v2 03/10] fdc: add disk field John Snow
2015-12-07 23:34 ` [Qemu-devel] [PATCH for-2.6 v2 04/10] fdc: add default drive type option John Snow
2015-12-07 23:56   ` Eric Blake
2015-12-14 20:05     ` John Snow
2015-12-15 16:29       ` Eric Blake
2015-12-07 23:34 ` [Qemu-devel] [PATCH for-2.6 v2 05/10] fdc: do not call revalidate on eject John Snow
2015-12-07 23:34 ` [Qemu-devel] [PATCH for-2.6 v2 06/10] fdc: implement new drive type property John Snow
2015-12-07 23:34 ` [Qemu-devel] [PATCH for-2.6 v2 07/10] fdc: add physical disk sizes John Snow
2015-12-07 23:34 ` John Snow [this message]
2015-12-07 23:34 ` [Qemu-devel] [PATCH for-2.6 v2 09/10] qtest/fdc: Support for 2.88MB drives John Snow
2015-12-07 23:34 ` [Qemu-devel] [PATCH for-2.6 v2 10/10] fdc: change auto fallback drive to 288 John Snow

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1449531275-30362-9-git-send-email-jsnow@redhat.com \
    --to=jsnow@redhat.com \
    --cc=armbru@redhat.com \
    --cc=kwolf@redhat.com \
    --cc=qemu-block@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.