summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjoerg <joerg@FreeBSD.org>2002-05-10 17:56:39 +0000
committerjoerg <joerg@FreeBSD.org>2002-05-10 17:56:39 +0000
commit12e1531e597ce65a197e9c59592508b201d816fc (patch)
tree6af6bba858856050fb39fc2c4e116c47c1a61024
parent525421bc1cf839902073be43610463cdeec6e4ac (diff)
downloadFreeBSD-src-12e1531e597ce65a197e9c59592508b201d816fc.zip
FreeBSD-src-12e1531e597ce65a197e9c59592508b201d816fc.tar.gz
Change the PIO loops from a hard counter into a loop that calls DELAY()
in each cycle, with a tunable max cycle count defined in fdreg.h. This is said to fix the problem on some Compaq hardware (and perhaps on other machines using the Natsemi PC87317 chip) where the fdc(4) driver failed to operate at all. PR: kern/21397 Submitted by: Jung-uk Kim <jkim@niksun.com> MFC after: 3 days
-rw-r--r--sys/dev/fdc/fdc.c22
-rw-r--r--sys/dev/fdc/fdcreg.h12
-rw-r--r--sys/isa/fd.c22
-rw-r--r--sys/isa/fdreg.h12
4 files changed, 52 insertions, 16 deletions
diff --git a/sys/dev/fdc/fdc.c b/sys/dev/fdc/fdc.c
index 604fb8b..70fab4b 100644
--- a/sys/dev/fdc/fdc.c
+++ b/sys/dev/fdc/fdc.c
@@ -563,13 +563,15 @@ enable_fifo(fdc_p fdc)
return fdc_err(fdc, "Enable FIFO failed\n");
/* If command is invalid, return */
- j = 100000;
+ j = FDSTS_TIMEOUT;
while ((i = fdsts_rd(fdc) & (NE7_DIO | NE7_RQM))
- != NE7_RQM && j-- > 0)
+ != NE7_RQM && j-- > 0) {
if (i == (NE7_DIO | NE7_RQM)) {
fdc_reset(fdc);
return FD_FAILED;
}
+ DELAY(1);
+ }
if (j<0 ||
fd_cmd(fdc, 3,
0, (fifo_threshold - 1) & 0xf, 0, 0) < 0) {
@@ -1473,11 +1475,13 @@ fdc_reset(fdc_p fdc)
static int
fd_in(struct fdc_data *fdc, int *ptr)
{
- int i, j = 100000;
+ int i, j = FDSTS_TIMEOUT;
while ((i = fdsts_rd(fdc) & (NE7_DIO|NE7_RQM))
- != (NE7_DIO|NE7_RQM) && j-- > 0)
+ != (NE7_DIO|NE7_RQM) && j-- > 0) {
if (i == NE7_RQM)
return fdc_err(fdc, "ready for output in input\n");
+ DELAY(1);
+ }
if (j <= 0)
return fdc_err(fdc, bootverbose? "input ready timeout\n": 0);
#ifdef FDC_DEBUG
@@ -1499,13 +1503,15 @@ out_fdc(struct fdc_data *fdc, int x)
int i;
/* Check that the direction bit is set */
- i = 100000;
- while ((fdsts_rd(fdc) & NE7_DIO) && i-- > 0);
+ i = FDSTS_TIMEOUT;
+ while ((fdsts_rd(fdc) & NE7_DIO) && i-- > 0)
+ 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 = 100000;
- while ((fdsts_rd(fdc) & NE7_RQM) == 0 && i-- > 0);
+ i = FDSTS_TIMEOUT;
+ while ((fdsts_rd(fdc) & NE7_RQM) == 0 && i-- > 0)
+ DELAY(1);
if (i <= 0)
return fdc_err(fdc, bootverbose? "output ready timeout\n": 0);
diff --git a/sys/dev/fdc/fdcreg.h b/sys/dev/fdc/fdcreg.h
index c082668..893aefd 100644
--- a/sys/dev/fdc/fdcreg.h
+++ b/sys/dev/fdc/fdcreg.h
@@ -69,3 +69,15 @@
#define FDI_DCHG 0x80 /* diskette has been changed */
/* requires drive and motor being selected */
/* is cleared by any step pulse to drive */
+
+/*
+ * Timeout value for the PIO loops to wait until the FDC main status
+ * register matches our expextations (request for master, direction
+ * bit). This is the number of cycles to loop while waiting, with a
+ * 1-microsecond (in theory) DELAY() in each cycle. In particular on
+ * slower hardware, it could take a fair amount more to execute. Of
+ * course, as soon as the FDC main status register indicates the correct
+ * bits are set, the loop will terminate, so this is merely a safety
+ * measure to avoid looping forever in case of broken hardware.
+ */
+#define FDSTS_TIMEOUT 200
diff --git a/sys/isa/fd.c b/sys/isa/fd.c
index 604fb8b..70fab4b 100644
--- a/sys/isa/fd.c
+++ b/sys/isa/fd.c
@@ -563,13 +563,15 @@ enable_fifo(fdc_p fdc)
return fdc_err(fdc, "Enable FIFO failed\n");
/* If command is invalid, return */
- j = 100000;
+ j = FDSTS_TIMEOUT;
while ((i = fdsts_rd(fdc) & (NE7_DIO | NE7_RQM))
- != NE7_RQM && j-- > 0)
+ != NE7_RQM && j-- > 0) {
if (i == (NE7_DIO | NE7_RQM)) {
fdc_reset(fdc);
return FD_FAILED;
}
+ DELAY(1);
+ }
if (j<0 ||
fd_cmd(fdc, 3,
0, (fifo_threshold - 1) & 0xf, 0, 0) < 0) {
@@ -1473,11 +1475,13 @@ fdc_reset(fdc_p fdc)
static int
fd_in(struct fdc_data *fdc, int *ptr)
{
- int i, j = 100000;
+ int i, j = FDSTS_TIMEOUT;
while ((i = fdsts_rd(fdc) & (NE7_DIO|NE7_RQM))
- != (NE7_DIO|NE7_RQM) && j-- > 0)
+ != (NE7_DIO|NE7_RQM) && j-- > 0) {
if (i == NE7_RQM)
return fdc_err(fdc, "ready for output in input\n");
+ DELAY(1);
+ }
if (j <= 0)
return fdc_err(fdc, bootverbose? "input ready timeout\n": 0);
#ifdef FDC_DEBUG
@@ -1499,13 +1503,15 @@ out_fdc(struct fdc_data *fdc, int x)
int i;
/* Check that the direction bit is set */
- i = 100000;
- while ((fdsts_rd(fdc) & NE7_DIO) && i-- > 0);
+ i = FDSTS_TIMEOUT;
+ while ((fdsts_rd(fdc) & NE7_DIO) && i-- > 0)
+ 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 = 100000;
- while ((fdsts_rd(fdc) & NE7_RQM) == 0 && i-- > 0);
+ i = FDSTS_TIMEOUT;
+ while ((fdsts_rd(fdc) & NE7_RQM) == 0 && i-- > 0)
+ DELAY(1);
if (i <= 0)
return fdc_err(fdc, bootverbose? "output ready timeout\n": 0);
diff --git a/sys/isa/fdreg.h b/sys/isa/fdreg.h
index c082668..893aefd 100644
--- a/sys/isa/fdreg.h
+++ b/sys/isa/fdreg.h
@@ -69,3 +69,15 @@
#define FDI_DCHG 0x80 /* diskette has been changed */
/* requires drive and motor being selected */
/* is cleared by any step pulse to drive */
+
+/*
+ * Timeout value for the PIO loops to wait until the FDC main status
+ * register matches our expextations (request for master, direction
+ * bit). This is the number of cycles to loop while waiting, with a
+ * 1-microsecond (in theory) DELAY() in each cycle. In particular on
+ * slower hardware, it could take a fair amount more to execute. Of
+ * course, as soon as the FDC main status register indicates the correct
+ * bits are set, the loop will terminate, so this is merely a safety
+ * measure to avoid looping forever in case of broken hardware.
+ */
+#define FDSTS_TIMEOUT 200
OpenPOWER on IntegriCloud