summaryrefslogtreecommitdiffstats
path: root/sys/dev/fdc
diff options
context:
space:
mode:
authortegge <tegge@FreeBSD.org>1997-09-17 20:16:17 +0000
committertegge <tegge@FreeBSD.org>1997-09-17 20:16:17 +0000
commitdc9fb7214712036d21e7066d05c5ddd251d1ddd4 (patch)
treed31b0e1d07074e4cc05262b9aec7fe4824e6974d /sys/dev/fdc
parent52f8c412b881dd0c998297025bb3d13b9a7157d8 (diff)
downloadFreeBSD-src-dc9fb7214712036d21e7066d05c5ddd251d1ddd4.zip
FreeBSD-src-dc9fb7214712036d21e7066d05c5ddd251d1ddd4.tar.gz
Enable the FIFO on enhanced floppy controllers. This reduces the
number of dma overruns/underruns for systems under heavy dma load. As a side effect, broken enhanced floppy controllers that sometimes don't detect dma overruns/underruns will give less errors. Reviewed by: j@uriah.heep.sax.de (J Wunsch)
Diffstat (limited to 'sys/dev/fdc')
-rw-r--r--sys/dev/fdc/fdc.c57
1 files changed, 56 insertions, 1 deletions
diff --git a/sys/dev/fdc/fdc.c b/sys/dev/fdc/fdc.c
index 99c4d21..85305f4 100644
--- a/sys/dev/fdc/fdc.c
+++ b/sys/dev/fdc/fdc.c
@@ -43,7 +43,7 @@
* SUCH DAMAGE.
*
* from: @(#)fd.c 7.4 (Berkeley) 5/25/91
- * $Id: fd.c,v 1.100 1997/07/20 14:09:54 bde Exp $
+ * $Id: fd.c,v 1.101 1997/09/16 07:45:45 joerg Exp $
*
*/
@@ -220,6 +220,10 @@ static int fdstate(fdcu_t, fdc_p);
static int retrier(fdcu_t);
static int fdformat(dev_t, struct fd_formb *, struct proc *);
+static int enable_fifo(fdc_p fdc);
+
+static int fifo_threshold = 8; /* XXX: should be accessible via sysctl */
+
#define DEVIDLE 0
#define FINDWORK 1
@@ -343,6 +347,46 @@ fd_cmd(fdcu_t fdcu, int n_out, ...)
return 0;
}
+static int
+enable_fifo(fdc_p fdc)
+{
+ int i, j;
+
+ if ((fdc->flags & FDC_HAS_FIFO) == 0) {
+
+ /*
+ * XXX:
+ * Cannot use fd_cmd the normal way here, since
+ * this might be an invalid command. Thus we send the
+ * first byte, and check for an early turn of data directon.
+ */
+
+ if (out_fdc(fdc->fdcu, I8207X_CONFIGURE) < 0)
+ return fdc_err(fdc->fdcu, "Enable FIFO failed\n");
+
+ /* If command is invalid, return */
+ j = 100000;
+ while ((i = inb(fdc->baseport + FDSTS) & (NE7_DIO | NE7_RQM))
+ != NE7_RQM && j-- > 0)
+ if (i == (NE7_DIO | NE7_RQM)) {
+ fdc_reset(fdc);
+ return FD_FAILED;
+ }
+ if (j<0 ||
+ fd_cmd(fdc->fdcu, 3,
+ 0, (fifo_threshold - 1) & 0xf, 0, 0) < 0) {
+ fdc_reset(fdc);
+ return fdc_err(fdc->fdcu, "Enable FIFO failed\n");
+ }
+ fdc->flags |= FDC_HAS_FIFO;
+ return 0;
+ }
+ if (fd_cmd(fdc->fdcu, 4,
+ I8207X_CONFIGURE, 0, (fifo_threshold - 1) & 0xf, 0, 0) < 0)
+ return fdc_err(fdc->fdcu, "Re-enable FIFO failed\n");
+ return 0;
+}
+
static int
fd_sense_drive_status(fdc_p fdc, int *st3p)
{
@@ -572,6 +616,13 @@ fdattach(struct isa_device *dev)
fdc->fdct = FDC_UNKNOWN;
break;
}
+ if (fdc->fdct != FDC_NE765 &&
+ fdc->fdct != FDC_UNKNOWN &&
+ enable_fifo(fdc) == 0) {
+ printf("fdc%d: FIFO enabled", fdcu);
+ printf(", %d bytes threshold\n",
+ fifo_threshold);
+ }
}
if ((fd_cmd(fdcu, 2, NE7CMD_SENSED, fdsu, 1, &st3) == 0) &&
(st3 & NE7_ST3_T0)) {
@@ -772,6 +823,8 @@ set_motor(fdcu_t fdcu, int fdsu, int turnon)
(void)fd_cmd(fdcu, 3, NE7CMD_SPECIFY,
NE7_SPEC_1(3, 240), NE7_SPEC_2(2, 0),
0);
+ if (fdc_data[fdcu].flags & FDC_HAS_FIFO)
+ (void) enable_fifo(&fdc_data[fdcu]);
}
}
@@ -848,6 +901,8 @@ fdc_reset(fdc_p fdc)
(void)fd_cmd(fdcu, 3, NE7CMD_SPECIFY,
NE7_SPEC_1(3, 240), NE7_SPEC_2(2, 0),
0);
+ if (fdc->flags & FDC_HAS_FIFO)
+ (void) enable_fifo(fdc);
}
/****************************************************************************/
OpenPOWER on IntegriCloud