Merged from sys/isa/fd.c revisions from 1.229 to 1.232.

This commit is contained in:
nyan 2002-05-14 12:30:52 +00:00
parent 6567706194
commit 348895a33a
2 changed files with 130 additions and 36 deletions

View File

@ -189,6 +189,8 @@ struct fdc_data
#endif #endif
}; };
#define BIO_FORMAT BIO_CMD2
typedef int fdu_t; typedef int fdu_t;
typedef int fdcu_t; typedef int fdcu_t;
typedef int fdsu_t; typedef int fdsu_t;
@ -234,6 +236,17 @@ FDC_ACCESSOR(fdunit, FDUNIT, int)
*/ */
#define FDC_DMAOV_MAX 25 #define FDC_DMAOV_MAX 25
/*
* Timeout value for the PIO loops to wait until the FDC main status
* register matches our expectations (request for master, direction
* bit). This is supposed to be a number of microseconds, although
* timing might actually not be very accurate.
*
* Timeouts of 100 msec are believed to be required for some broken
* (old) hardware.
*/
#define FDSTS_TIMEOUT 100000
/* /*
* Number of subdevices that can be used for different density types. * Number of subdevices that can be used for different density types.
* By now, the lower 6 bit of the minor number are reserved for this, * By now, the lower 6 bit of the minor number are reserved for this,
@ -251,7 +264,6 @@ FDC_ACCESSOR(fdunit, FDUNIT, int)
#endif #endif
#define BIO_RDSECTID BIO_CMD1 #define BIO_RDSECTID BIO_CMD1
#define BIO_FORMAT BIO_CMD2
/* /*
* List of native drive densities. Order must match enum fd_drivetype * List of native drive densities. Order must match enum fd_drivetype
@ -482,7 +494,9 @@ static void fdctl_wr_isa(fdc_p, u_int8_t);
#if NCARD > 0 #if NCARD > 0
static void fdctl_wr_pcmcia(fdc_p, u_int8_t); static void fdctl_wr_pcmcia(fdc_p, u_int8_t);
#endif #endif
#if 0
static u_int8_t fdin_rd(fdc_p); static u_int8_t fdin_rd(fdc_p);
#endif
#endif /* PC98 */ #endif /* PC98 */
static int fdc_err(struct fdc_data *, const char *); static int fdc_err(struct fdc_data *, const char *);
static int fd_cmd(struct fdc_data *, int, ...); static int fd_cmd(struct fdc_data *, int, ...);
@ -703,13 +717,15 @@ enable_fifo(fdc_p fdc)
return fdc_err(fdc, "Enable FIFO failed\n"); return fdc_err(fdc, "Enable FIFO failed\n");
/* If command is invalid, return */ /* If command is invalid, return */
j = 100000; j = FDSTS_TIMEOUT;
while ((i = fdsts_rd(fdc) & (NE7_DIO | NE7_RQM)) while ((i = fdsts_rd(fdc) & (NE7_DIO | NE7_RQM))
!= NE7_RQM && j-- > 0) != NE7_RQM && j-- > 0) {
if (i == (NE7_DIO | NE7_RQM)) { if (i == (NE7_DIO | NE7_RQM)) {
fdc_reset(fdc); fdc_reset(fdc);
return FD_FAILED; return FD_FAILED;
} }
DELAY(1);
}
if (j<0 || if (j<0 ||
fd_cmd(fdc, 3, fd_cmd(fdc, 3,
0, (fifo_threshold - 1) & 0xf, 0, 0) < 0) { 0, (fifo_threshold - 1) & 0xf, 0, 0) < 0) {
@ -1887,23 +1903,33 @@ fdc_reset(fdc_p fdc)
static int static int
fd_in(struct fdc_data *fdc, int *ptr) 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)) 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) if (i == NE7_RQM)
return fdc_err(fdc, "ready for output in input\n"); return (fdc_err(fdc, "ready for output in input\n"));
/*
* After (maybe) 1 msec of waiting, back off to larger
* stepping to get the timing more accurate.
*/
if (FDSTS_TIMEOUT - j > 1000) {
DELAY(1000);
j -= 999;
} else
DELAY(1);
}
if (j <= 0) if (j <= 0)
return fdc_err(fdc, bootverbose? "input ready timeout\n": 0); return (fdc_err(fdc, bootverbose? "input ready timeout\n": 0));
#ifdef FDC_DEBUG #ifdef FDC_DEBUG
i = fddata_rd(fdc); i = fddata_rd(fdc);
TRACE1("[FDDATA->0x%x]", (unsigned char)i); TRACE1("[FDDATA->0x%x]", (unsigned char)i);
*ptr = i; *ptr = i;
return 0; return (0);
#else /* !FDC_DEBUG */ #else /* !FDC_DEBUG */
i = fddata_rd(fdc); i = fddata_rd(fdc);
if (ptr) if (ptr)
*ptr = i; *ptr = i;
return 0; return (0);
#endif /* FDC_DEBUG */ #endif /* FDC_DEBUG */
} }
@ -1913,15 +1939,34 @@ out_fdc(struct fdc_data *fdc, int x)
int i; int i;
/* Check that the direction bit is set */ /* Check that the direction bit is set */
i = 100000; i = FDSTS_TIMEOUT;
while ((fdsts_rd(fdc) & NE7_DIO) && i-- > 0); while ((fdsts_rd(fdc) & NE7_DIO) && i-- > 0)
if (i <= 0) return fdc_err(fdc, "direction bit not set\n"); /*
* After (maybe) 1 msec of waiting, back off to larger
* stepping to get the timing more accurate.
*/
if (FDSTS_TIMEOUT - i > 1000) {
DELAY(1000);
i -= 999;
} else
DELAY(1);
if (i <= 0)
return (fdc_err(fdc, "direction bit not set\n"));
/* Check that the floppy controller is ready for a command */ /* Check that the floppy controller is ready for a command */
i = 100000; i = FDSTS_TIMEOUT;
while ((fdsts_rd(fdc) & NE7_RQM) == 0 && i-- > 0); while ((fdsts_rd(fdc) & NE7_RQM) == 0 && i-- > 0)
/*
* After (maybe) 1 msec of waiting, back off to larger
* stepping to get the timing more accurate.
*/
if (FDSTS_TIMEOUT - i > 1000) {
DELAY(1000);
i -= 999;
} else
DELAY(1);
if (i <= 0) if (i <= 0)
return fdc_err(fdc, bootverbose? "output ready timeout\n": 0); return (fdc_err(fdc, bootverbose? "output ready timeout\n": 0));
/* Send the command and return */ /* Send the command and return */
fddata_wr(fdc, x); fddata_wr(fdc, x);
@ -2332,12 +2377,14 @@ fdautoselect(dev_t dev)
fd->options = oopts; fd->options = oopts;
if (i == n) { if (i == n) {
device_printf(fd->dev, "autoselection failed\n"); if (bootverbose)
device_printf(fd->dev, "autoselection failed\n");
fd->ft = 0; fd->ft = 0;
return (EIO); return (EIO);
} else { } else {
device_printf(fd->dev, "autoselected %d KB medium\n", if (bootverbose)
fd->ft->size / 2); device_printf(fd->dev, "autoselected %d KB medium\n",
fd->ft->size / 2);
return (0); return (0);
} }
} }

View File

@ -189,6 +189,8 @@ struct fdc_data
#endif #endif
}; };
#define BIO_FORMAT BIO_CMD2
typedef int fdu_t; typedef int fdu_t;
typedef int fdcu_t; typedef int fdcu_t;
typedef int fdsu_t; typedef int fdsu_t;
@ -234,6 +236,17 @@ FDC_ACCESSOR(fdunit, FDUNIT, int)
*/ */
#define FDC_DMAOV_MAX 25 #define FDC_DMAOV_MAX 25
/*
* Timeout value for the PIO loops to wait until the FDC main status
* register matches our expectations (request for master, direction
* bit). This is supposed to be a number of microseconds, although
* timing might actually not be very accurate.
*
* Timeouts of 100 msec are believed to be required for some broken
* (old) hardware.
*/
#define FDSTS_TIMEOUT 100000
/* /*
* Number of subdevices that can be used for different density types. * Number of subdevices that can be used for different density types.
* By now, the lower 6 bit of the minor number are reserved for this, * By now, the lower 6 bit of the minor number are reserved for this,
@ -251,7 +264,6 @@ FDC_ACCESSOR(fdunit, FDUNIT, int)
#endif #endif
#define BIO_RDSECTID BIO_CMD1 #define BIO_RDSECTID BIO_CMD1
#define BIO_FORMAT BIO_CMD2
/* /*
* List of native drive densities. Order must match enum fd_drivetype * List of native drive densities. Order must match enum fd_drivetype
@ -482,7 +494,9 @@ static void fdctl_wr_isa(fdc_p, u_int8_t);
#if NCARD > 0 #if NCARD > 0
static void fdctl_wr_pcmcia(fdc_p, u_int8_t); static void fdctl_wr_pcmcia(fdc_p, u_int8_t);
#endif #endif
#if 0
static u_int8_t fdin_rd(fdc_p); static u_int8_t fdin_rd(fdc_p);
#endif
#endif /* PC98 */ #endif /* PC98 */
static int fdc_err(struct fdc_data *, const char *); static int fdc_err(struct fdc_data *, const char *);
static int fd_cmd(struct fdc_data *, int, ...); static int fd_cmd(struct fdc_data *, int, ...);
@ -703,13 +717,15 @@ enable_fifo(fdc_p fdc)
return fdc_err(fdc, "Enable FIFO failed\n"); return fdc_err(fdc, "Enable FIFO failed\n");
/* If command is invalid, return */ /* If command is invalid, return */
j = 100000; j = FDSTS_TIMEOUT;
while ((i = fdsts_rd(fdc) & (NE7_DIO | NE7_RQM)) while ((i = fdsts_rd(fdc) & (NE7_DIO | NE7_RQM))
!= NE7_RQM && j-- > 0) != NE7_RQM && j-- > 0) {
if (i == (NE7_DIO | NE7_RQM)) { if (i == (NE7_DIO | NE7_RQM)) {
fdc_reset(fdc); fdc_reset(fdc);
return FD_FAILED; return FD_FAILED;
} }
DELAY(1);
}
if (j<0 || if (j<0 ||
fd_cmd(fdc, 3, fd_cmd(fdc, 3,
0, (fifo_threshold - 1) & 0xf, 0, 0) < 0) { 0, (fifo_threshold - 1) & 0xf, 0, 0) < 0) {
@ -1887,23 +1903,33 @@ fdc_reset(fdc_p fdc)
static int static int
fd_in(struct fdc_data *fdc, int *ptr) 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)) 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) if (i == NE7_RQM)
return fdc_err(fdc, "ready for output in input\n"); return (fdc_err(fdc, "ready for output in input\n"));
/*
* After (maybe) 1 msec of waiting, back off to larger
* stepping to get the timing more accurate.
*/
if (FDSTS_TIMEOUT - j > 1000) {
DELAY(1000);
j -= 999;
} else
DELAY(1);
}
if (j <= 0) if (j <= 0)
return fdc_err(fdc, bootverbose? "input ready timeout\n": 0); return (fdc_err(fdc, bootverbose? "input ready timeout\n": 0));
#ifdef FDC_DEBUG #ifdef FDC_DEBUG
i = fddata_rd(fdc); i = fddata_rd(fdc);
TRACE1("[FDDATA->0x%x]", (unsigned char)i); TRACE1("[FDDATA->0x%x]", (unsigned char)i);
*ptr = i; *ptr = i;
return 0; return (0);
#else /* !FDC_DEBUG */ #else /* !FDC_DEBUG */
i = fddata_rd(fdc); i = fddata_rd(fdc);
if (ptr) if (ptr)
*ptr = i; *ptr = i;
return 0; return (0);
#endif /* FDC_DEBUG */ #endif /* FDC_DEBUG */
} }
@ -1913,15 +1939,34 @@ out_fdc(struct fdc_data *fdc, int x)
int i; int i;
/* Check that the direction bit is set */ /* Check that the direction bit is set */
i = 100000; i = FDSTS_TIMEOUT;
while ((fdsts_rd(fdc) & NE7_DIO) && i-- > 0); while ((fdsts_rd(fdc) & NE7_DIO) && i-- > 0)
if (i <= 0) return fdc_err(fdc, "direction bit not set\n"); /*
* After (maybe) 1 msec of waiting, back off to larger
* stepping to get the timing more accurate.
*/
if (FDSTS_TIMEOUT - i > 1000) {
DELAY(1000);
i -= 999;
} else
DELAY(1);
if (i <= 0)
return (fdc_err(fdc, "direction bit not set\n"));
/* Check that the floppy controller is ready for a command */ /* Check that the floppy controller is ready for a command */
i = 100000; i = FDSTS_TIMEOUT;
while ((fdsts_rd(fdc) & NE7_RQM) == 0 && i-- > 0); while ((fdsts_rd(fdc) & NE7_RQM) == 0 && i-- > 0)
/*
* After (maybe) 1 msec of waiting, back off to larger
* stepping to get the timing more accurate.
*/
if (FDSTS_TIMEOUT - i > 1000) {
DELAY(1000);
i -= 999;
} else
DELAY(1);
if (i <= 0) if (i <= 0)
return fdc_err(fdc, bootverbose? "output ready timeout\n": 0); return (fdc_err(fdc, bootverbose? "output ready timeout\n": 0));
/* Send the command and return */ /* Send the command and return */
fddata_wr(fdc, x); fddata_wr(fdc, x);
@ -2332,12 +2377,14 @@ fdautoselect(dev_t dev)
fd->options = oopts; fd->options = oopts;
if (i == n) { if (i == n) {
device_printf(fd->dev, "autoselection failed\n"); if (bootverbose)
device_printf(fd->dev, "autoselection failed\n");
fd->ft = 0; fd->ft = 0;
return (EIO); return (EIO);
} else { } else {
device_printf(fd->dev, "autoselected %d KB medium\n", if (bootverbose)
fd->ft->size / 2); device_printf(fd->dev, "autoselected %d KB medium\n",
fd->ft->size / 2);
return (0); return (0);
} }
} }