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:
parent
35213a76a9
commit
a2642c4d67
@ -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 */
|
||||
|
70
sys/isa/fd.c
70
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;
|
||||
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 */
|
||||
|
Loading…
Reference in New Issue
Block a user