diff options
author | joerg <joerg@FreeBSD.org> | 2002-05-14 21:28:45 +0000 |
---|---|---|
committer | joerg <joerg@FreeBSD.org> | 2002-05-14 21:28:45 +0000 |
commit | eb68e3aae2dbda29ad3463cd0ad85dcb6ce4158a (patch) | |
tree | 51f028686ba3c93a5d8e5e52d9d0b0cca45efcb8 /sys/isa | |
parent | 23566a2f802e0c60a2e0b37e17366f15377c6378 (diff) | |
download | FreeBSD-src-eb68e3aae2dbda29ad3463cd0ad85dcb6ce4158a.zip FreeBSD-src-eb68e3aae2dbda29ad3463cd0ad85dcb6ce4158a.tar.gz |
After some comments from bde, rewrite the loops to avoid turning the
previously used "micro-optimization" (count-down loop) into a
pessimization. Now the loops are written in the more natural count-up
form.
Also, while being there, i made the logic in out_fdc() similar to the
logic in in_fdc(). The old implementation was a bit bogus anyway
since it first tested the DIO bit and only afterwards the RQM bit.
However, according to the description of the i82077, the DIO bit is
only guaranteed to be valid once the RQM bit is set. Thus, the old
implementatoin would have had the chance to misbehave on a controller
that is implemented in accordance with the i82077 description (but is
not bug-for-bug compatible).
MFC after: 3 days
Diffstat (limited to 'sys/isa')
-rw-r--r-- | sys/isa/fd.c | 72 |
1 files changed, 29 insertions, 43 deletions
diff --git a/sys/isa/fd.c b/sys/isa/fd.c index 60fff67..5edc407 100644 --- a/sys/isa/fd.c +++ b/sys/isa/fd.c @@ -1482,26 +1482,29 @@ fdc_reset(fdc_p fdc) /* * FDC IO functions, take care of the main status register, timeout * in case the desired status bits are never set. + * + * These PIO loops initially start out with short delays between + * each iteration in the expectation that the required condition + * is usually met quickly, so it can be handled immediately. After + * about 1 ms, stepping is increased to achieve a better timing + * accuracy in the calls to DELAY(). */ static int fd_in(struct fdc_data *fdc, int *ptr) { - int i, j = FDSTS_TIMEOUT; - while ((i = fdsts_rd(fdc) & (NE7_DIO|NE7_RQM)) - != (NE7_DIO|NE7_RQM) && j-- > 0) { + int i, j, step; + + for (j = 0, step = 1; + (i = fdsts_rd(fdc) & (NE7_DIO|NE7_RQM)) != (NE7_DIO|NE7_RQM) && + j < FDSTS_TIMEOUT; + j += step) { if (i == NE7_RQM) return (fdc_err(fdc, "ready for output in input\n")); - /* - * After (maybe) 1 msec of waiting, back off to larger - * stepping to get the timing more accurate. - */ - if (FDSTS_TIMEOUT - j > 1000) { - DELAY(1000); - j -= 999; - } else - DELAY(1); + if (j == 1000) + step = 1000; + DELAY(step); } - if (j <= 0) + if (j >= FDSTS_TIMEOUT) return (fdc_err(fdc, bootverbose? "input ready timeout\n": 0)); #ifdef FDC_DEBUG i = fddata_rd(fdc); @@ -1519,36 +1522,19 @@ fd_in(struct fdc_data *fdc, int *ptr) int out_fdc(struct fdc_data *fdc, int x) { - int i; - - /* Check that the direction bit is set */ - i = FDSTS_TIMEOUT; - while ((fdsts_rd(fdc) & NE7_DIO) && i-- > 0) - /* - * After (maybe) 1 msec of waiting, back off to larger - * stepping to get the timing more accurate. - */ - if (FDSTS_TIMEOUT - i > 1000) { - DELAY(1000); - i -= 999; - } else - DELAY(1); - if (i <= 0) - return (fdc_err(fdc, "direction bit not set\n")); - - /* Check that the floppy controller is ready for a command */ - i = FDSTS_TIMEOUT; - while ((fdsts_rd(fdc) & NE7_RQM) == 0 && i-- > 0) - /* - * After (maybe) 1 msec of waiting, back off to larger - * stepping to get the timing more accurate. - */ - if (FDSTS_TIMEOUT - i > 1000) { - DELAY(1000); - i -= 999; - } else - DELAY(1); - if (i <= 0) + int i, j, step; + + for (j = 0, step = 1; + (i = fdsts_rd(fdc) & (NE7_DIO|NE7_RQM)) != NE7_RQM && + j < FDSTS_TIMEOUT; + j += step) { + if (i == (NE7_DIO|NE7_RQM)) + return (fdc_err(fdc, "ready for input in output\n")); + if (j == 1000) + step = 1000; + DELAY(step); + } + if (j >= FDSTS_TIMEOUT) return (fdc_err(fdc, bootverbose? "output ready timeout\n": 0)); /* Send the command and return */ |