summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorjoerg <joerg@FreeBSD.org>2002-05-14 21:28:45 +0000
committerjoerg <joerg@FreeBSD.org>2002-05-14 21:28:45 +0000
commiteb68e3aae2dbda29ad3463cd0ad85dcb6ce4158a (patch)
tree51f028686ba3c93a5d8e5e52d9d0b0cca45efcb8 /sys
parent23566a2f802e0c60a2e0b37e17366f15377c6378 (diff)
downloadFreeBSD-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')
-rw-r--r--sys/dev/fdc/fdc.c72
-rw-r--r--sys/isa/fd.c72
2 files changed, 58 insertions, 86 deletions
diff --git a/sys/dev/fdc/fdc.c b/sys/dev/fdc/fdc.c
index 60fff67..5edc407 100644
--- a/sys/dev/fdc/fdc.c
+++ b/sys/dev/fdc/fdc.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 */
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 */
OpenPOWER on IntegriCloud