summaryrefslogtreecommitdiffstats
path: root/sys/dev
diff options
context:
space:
mode:
authorjkim <jkim@FreeBSD.org>2006-07-06 21:12:18 +0000
committerjkim <jkim@FreeBSD.org>2006-07-06 21:12:18 +0000
commitc025122efb4887b6cf1e73d8e13340215ee870fa (patch)
tree5f5c8e0ac7c41fc6eb82da090f253cdb4051c7b4 /sys/dev
parent3f67fc0a689b5565e39164dca8f10f2a585b89ea (diff)
downloadFreeBSD-src-c025122efb4887b6cf1e73d8e13340215ee870fa.zip
FreeBSD-src-c025122efb4887b6cf1e73d8e13340215ee870fa.tar.gz
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.
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/fdc/fdc.c32
-rw-r--r--sys/dev/ic/nec765.h6
2 files changed, 30 insertions, 8 deletions
diff --git a/sys/dev/fdc/fdc.c b/sys/dev/fdc/fdc.c
index feaa174..2bfd4c3 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) {
diff --git a/sys/dev/ic/nec765.h b/sys/dev/ic/nec765.h
index 1e0561a..9851685 100644
--- a/sys/dev/ic/nec765.h
+++ b/sys/dev/ic/nec765.h
@@ -90,6 +90,12 @@
#define NE7_ST3_HD 0x04 /* upper head select */
#define NE7_ST3_US 0x03 /* unit select */
+/* Data Rate Select Register DSR (enhanced controller) */
+#define I8207X_DSR_SR 0x80 /* software reset */
+#define I8207X_DSR_LP 0x40 /* low power */
+#define I8207X_DSR_PS 0x1c /* precompensation select */
+#define I8207X_DSR_RS 0x03 /* data rate select */
+
/* Commands */
/*
* the top three bits -- where appropriate -- are set as follows:
OpenPOWER on IntegriCloud