From d66c374f58a74f98ce6f747c02bb4a2489c77ffd Mon Sep 17 00:00:00 2001 From: Tor Egge Date: Wed, 17 Sep 1997 20:16:17 +0000 Subject: [PATCH] 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) --- sys/dev/fdc/fdc.c | 57 +++++++++++++++++++++++++++++++++++++++- sys/dev/ic/nec765.h | 3 ++- sys/i386/isa/fd.c | 57 +++++++++++++++++++++++++++++++++++++++- sys/i386/isa/fdc.h | 3 ++- sys/i386/isa/ic/nec765.h | 3 ++- sys/isa/fd.c | 57 +++++++++++++++++++++++++++++++++++++++- sys/isa/fdc.h | 3 ++- sys/isa/ic/nec765.h | 3 ++- 8 files changed, 178 insertions(+), 8 deletions(-) diff --git a/sys/dev/fdc/fdc.c b/sys/dev/fdc/fdc.c index 99c4d21c9e38..85305f4d7018 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); } /****************************************************************************/ diff --git a/sys/dev/ic/nec765.h b/sys/dev/ic/nec765.h index 7af3c21b2725..3a5561888e87 100644 --- a/sys/dev/ic/nec765.h +++ b/sys/dev/ic/nec765.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * from: @(#)nec765.h 7.1 (Berkeley) 5/9/91 - * $Id$ + * $Id: nec765.h,v 1.6 1997/02/22 09:38:04 peter Exp $ */ /* @@ -126,6 +126,7 @@ */ #define NE7CMD_VERSION 0x10 /* version (ok for all controllers) */ +#define I8207X_CONFIGURE 0x13 /* configure enhanced features */ /* * "specify" definitions diff --git a/sys/i386/isa/fd.c b/sys/i386/isa/fd.c index 99c4d21c9e38..85305f4d7018 100644 --- a/sys/i386/isa/fd.c +++ b/sys/i386/isa/fd.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); } /****************************************************************************/ diff --git a/sys/i386/isa/fdc.h b/sys/i386/isa/fdc.h index 99b33bb90f36..34d7011a94a9 100644 --- a/sys/i386/isa/fdc.h +++ b/sys/i386/isa/fdc.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * from: @(#)fd.c 7.4 (Berkeley) 5/25/91 - * $Id$ + * $Id: fdc.h,v 1.8 1997/02/22 09:36:10 peter Exp $ * */ @@ -54,6 +54,7 @@ struct fdc_data #define FDC_HASFTAPE 0x02 #define FDC_TAPE_BUSY 0x04 #define FDC_STAT_VALID 0x08 +#define FDC_HAS_FIFO 0x10 struct fd_data *fd; int fdu; /* the active drive */ int state; diff --git a/sys/i386/isa/ic/nec765.h b/sys/i386/isa/ic/nec765.h index 7af3c21b2725..3a5561888e87 100644 --- a/sys/i386/isa/ic/nec765.h +++ b/sys/i386/isa/ic/nec765.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * from: @(#)nec765.h 7.1 (Berkeley) 5/9/91 - * $Id$ + * $Id: nec765.h,v 1.6 1997/02/22 09:38:04 peter Exp $ */ /* @@ -126,6 +126,7 @@ */ #define NE7CMD_VERSION 0x10 /* version (ok for all controllers) */ +#define I8207X_CONFIGURE 0x13 /* configure enhanced features */ /* * "specify" definitions diff --git a/sys/isa/fd.c b/sys/isa/fd.c index 99c4d21c9e38..85305f4d7018 100644 --- a/sys/isa/fd.c +++ b/sys/isa/fd.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); } /****************************************************************************/ diff --git a/sys/isa/fdc.h b/sys/isa/fdc.h index 99b33bb90f36..34d7011a94a9 100644 --- a/sys/isa/fdc.h +++ b/sys/isa/fdc.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * from: @(#)fd.c 7.4 (Berkeley) 5/25/91 - * $Id$ + * $Id: fdc.h,v 1.8 1997/02/22 09:36:10 peter Exp $ * */ @@ -54,6 +54,7 @@ struct fdc_data #define FDC_HASFTAPE 0x02 #define FDC_TAPE_BUSY 0x04 #define FDC_STAT_VALID 0x08 +#define FDC_HAS_FIFO 0x10 struct fd_data *fd; int fdu; /* the active drive */ int state; diff --git a/sys/isa/ic/nec765.h b/sys/isa/ic/nec765.h index 7af3c21b2725..3a5561888e87 100644 --- a/sys/isa/ic/nec765.h +++ b/sys/isa/ic/nec765.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * from: @(#)nec765.h 7.1 (Berkeley) 5/9/91 - * $Id$ + * $Id: nec765.h,v 1.6 1997/02/22 09:38:04 peter Exp $ */ /* @@ -126,6 +126,7 @@ */ #define NE7CMD_VERSION 0x10 /* version (ok for all controllers) */ +#define I8207X_CONFIGURE 0x13 /* configure enhanced features */ /* * "specify" definitions