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
This commit is contained in:
Joerg Wunsch 2002-05-14 21:28:45 +00:00
parent 35213a76a9
commit a2642c4d67
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=96611
2 changed files with 56 additions and 84 deletions

View file

@ -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;
int i, j, step;
/* 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)
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 */

View file

@ -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;
int i, j, step;
/* 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)
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 */