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)
This commit is contained in:
Tor Egge 1997-09-17 20:16:17 +00:00
parent 2f6456ee54
commit d66c374f58
8 changed files with 178 additions and 8 deletions

View File

@ -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);
}
/****************************************************************************/

View File

@ -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

View File

@ -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);
}
/****************************************************************************/

View File

@ -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;

View File

@ -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

View File

@ -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);
}
/****************************************************************************/

View File

@ -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;

View File

@ -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