[syslinux:master] core, diskio: reset controller between EDD retries

syslinux-bot for H. Peter Anvin hpa at linux.intel.com
Thu Jul 1 18:12:02 PDT 2010


Commit-ID:  cda890603aef72cbc571ff932a32fc1813070a50
Gitweb:     http://syslinux.zytor.com/commit/cda890603aef72cbc571ff932a32fc1813070a50
Author:     H. Peter Anvin <hpa at linux.intel.com>
AuthorDate: Thu, 1 Jul 2010 18:10:22 -0700
Committer:  H. Peter Anvin <hpa at linux.intel.com>
CommitDate: Thu, 1 Jul 2010 18:10:22 -0700

core, diskio: reset controller between EDD retries

As documented in the old assembly code, reset the disk controller
between retries when using EDD.  We don't want to do that for CHS,
since a reset shuts down the floppy motor, and we might be suffering a
timeout.

Signed-off-by: H. Peter Anvin <hpa at linux.intel.com>


---
 core/fs/diskio.c |   14 +++++++++++++-
 1 files changed, 13 insertions(+), 1 deletions(-)

diff --git a/core/fs/diskio.c b/core/fs/diskio.c
index fb53109..d4901c3 100644
--- a/core/fs/diskio.c
+++ b/core/fs/diskio.c
@@ -127,7 +127,7 @@ static int edd_rdwr_sectors(struct disk *disk, void *buf,
     char *tptr;
     size_t chunk, freeseg;
     int sector_shift = disk->sector_shift;
-    com32sys_t ireg, oreg;
+    com32sys_t ireg, oreg, reset;
     size_t done = 0;
     size_t bytes;
     int retry;
@@ -139,6 +139,10 @@ static int edd_rdwr_sectors(struct disk *disk, void *buf,
     ireg.ds       = SEG(&pkt);
     ireg.esi.w[0] = OFFS(&pkt);
 
+    memset(&reset, 0, sizeof reset);
+
+    ireg.edx.b[0] = disk->disk_number;
+
     lba += disk->part_start;
     while (count) {
 	chunk = count;
@@ -186,6 +190,14 @@ static int edd_rdwr_sectors(struct disk *disk, void *buf,
 	    if (retry--)
 		continue;
 
+	    /*
+	     * Some systems seem to get "stuck" in an error state when
+	     * using EBIOS.  Doesn't happen when using CBIOS, which is
+	     * good, since some other systems get timeout failures
+	     * waiting for the floppy disk to spin up.
+	     */
+	    __intcall(0x13, &reset, NULL);
+
 	    /* For any starting value, this will always end with ..., 1, 0 */
 	    chunk >>= 1;
 	    if (chunk) {



More information about the Syslinux-commits mailing list