aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/fdc
diff options
context:
space:
mode:
authorJung-uk Kim <jkim@FreeBSD.org>2006-07-06 21:12:18 +0000
committerJung-uk Kim <jkim@FreeBSD.org>2006-07-06 21:12:18 +0000
commit50d99d1a52d3bc87a4897cc87db950960060e35e (patch)
tree5f5c8e0ac7c41fc6eb82da090f253cdb4051c7b4 /sys/dev/fdc
parent65ee602e0c3162bfa7f314843595cce1f1a8c6e5 (diff)
downloadsrc-50d99d1a52d3bc87a4897cc87db950960060e35e.tar.gz
src-50d99d1a52d3bc87a4897cc87db950960060e35e.zip
Enhanced floppy controllers have Data Rate Select Register (DSR) at 0x3f4.
Use it to reset controller and to select data rate. According to Intel 80277AA datasheet, software reset behaves the same as DOR reset except that it is self clearing. National Semiconductor PC8477B datasheet says the same. As a side effect, we no longer use Configuration Control Register (CCR) at 0x3f7 for these controllers, which is often missing in modern hardware.
Notes
Notes: svn path=/head/; revision=160137
Diffstat (limited to 'sys/dev/fdc')
-rw-r--r--sys/dev/fdc/fdc.c32
1 files changed, 24 insertions, 8 deletions
diff --git a/sys/dev/fdc/fdc.c b/sys/dev/fdc/fdc.c
index feaa17451d88..2bfd4c371d65 100644
--- a/sys/dev/fdc/fdc.c
+++ b/sys/dev/fdc/fdc.c
@@ -191,6 +191,7 @@ static struct fd_type *fd_native_types[] = {
#define FDO_MOEN3 0x80 /* motor enable drive 3 */
#define FDSTS 4 /* NEC 765 Main Status Register (R) */
+#define FDDSR 4 /* Data Rate Select Register (W) */
#define FDDATA 5 /* NEC 765 Data Register (R/W) */
#define FDCTL 7 /* Control Register (W) */
@@ -344,6 +345,13 @@ fdsts_rd(struct fdc_data *fdc)
}
static void
+fddsr_wr(struct fdc_data *fdc, u_int8_t v)
+{
+
+ fdregwr(fdc, FDDSR, v);
+}
+
+static void
fddata_wr(struct fdc_data *fdc, u_int8_t v)
{
@@ -494,13 +502,18 @@ fdc_reset(struct fdc_data *fdc)
{
int i, r[10];
- /* Try a reset, keep motor on */
- fdout_wr(fdc, fdc->fdout & ~(FDO_FRST|FDO_FDMAEN));
- DELAY(100);
- /* enable FDC, but defer interrupts a moment */
- fdout_wr(fdc, fdc->fdout & ~FDO_FDMAEN);
- DELAY(100);
- fdout_wr(fdc, fdc->fdout);
+ if (fdc->fdct == FDC_ENHANCED) {
+ /* Try a software reset, default precomp, and 500 kb/s */
+ fddsr_wr(fdc, I8207X_DSR_SR);
+ } else {
+ /* Try a hardware reset, keep motor on */
+ fdout_wr(fdc, fdc->fdout & ~(FDO_FRST|FDO_FDMAEN));
+ DELAY(100);
+ /* enable FDC, but defer interrupts a moment */
+ fdout_wr(fdc, fdc->fdout & ~FDO_FDMAEN);
+ DELAY(100);
+ fdout_wr(fdc, fdc->fdout);
+ }
/* XXX after a reset, silently believe the FDC will accept commands */
if (fdc_cmd(fdc, 3, NE7CMD_SPECIFY, spec1, spec2, 0))
@@ -804,7 +817,10 @@ fdc_worker(struct fdc_data *fdc)
/* Select drive, setup params */
fd_select(fd);
- fdctl_wr(fdc, fd->ft->trans);
+ if (fdc->fdct == FDC_ENHANCED)
+ fddsr_wr(fdc, fd->ft->trans);
+ else
+ fdctl_wr(fdc, fd->ft->trans);
if (bp->bio_cmd & BIO_PROBE) {