diff options
author | tegge <tegge@FreeBSD.org> | 1997-09-17 20:16:17 +0000 |
---|---|---|
committer | tegge <tegge@FreeBSD.org> | 1997-09-17 20:16:17 +0000 |
commit | dc9fb7214712036d21e7066d05c5ddd251d1ddd4 (patch) | |
tree | d31b0e1d07074e4cc05262b9aec7fe4824e6974d /sys/dev/fdc | |
parent | 52f8c412b881dd0c998297025bb3d13b9a7157d8 (diff) | |
download | FreeBSD-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.c | 57 |
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); } /****************************************************************************/ |