summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@linux.intel.com>2010-07-01 18:10:22 -0700
committerH. Peter Anvin <hpa@linux.intel.com>2010-07-01 18:10:22 -0700
commitcda890603aef72cbc571ff932a32fc1813070a50 (patch)
treecfc003c6a36dc5d1594aab5a808b8e3987445354
parent754e947d3fce9d85776bfe5aaeac903b63169a87 (diff)
downloadsyslinux-cda890603aef72cbc571ff932a32fc1813070a50.tar.gz
syslinux-cda890603aef72cbc571ff932a32fc1813070a50.tar.xz
syslinux-cda890603aef72cbc571ff932a32fc1813070a50.zip
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@linux.intel.com>
-rw-r--r--core/fs/diskio.c14
1 files changed, 13 insertions, 1 deletions
diff --git a/core/fs/diskio.c b/core/fs/diskio.c
index fb53109e..d4901c3d 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) {