summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Yurchenko <grange@cvs.openbsd.org>2003-10-26 14:29:48 +0000
committerAlexander Yurchenko <grange@cvs.openbsd.org>2003-10-26 14:29:48 +0000
commit4a1dbddc19009a289f8f5a41c5fa74fcaba9ca58 (patch)
treeb6669eb1d071fc58d65e3f41757e3a093d113970
parent3a26d7a904f25fa8f508f274fcbb8dd3f04d38bd (diff)
Device reset improvements:
- put the reset protocol itself in the separate function __wdcdo_reset() so we don't need anymore to keep in sync two reset code paths; - change the reset protocol to something like FreeBSD and NetBSD do, this fixes slave ATA drive detect with weird ATAPI master (reported by fgsch@); Discussed with costa@. Tested by me, fgsch@, millert@, canacar@.
-rw-r--r--sys/dev/ic/wdc.c24
1 files changed, 15 insertions, 9 deletions
diff --git a/sys/dev/ic/wdc.c b/sys/dev/ic/wdc.c
index 1b983191af7..1ae60b22ab3 100644
--- a/sys/dev/ic/wdc.c
+++ b/sys/dev/ic/wdc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: wdc.c,v 1.70 2003/10/21 18:58:50 jmc Exp $ */
+/* $OpenBSD: wdc.c,v 1.71 2003/10/26 14:29:47 grange Exp $ */
/* $NetBSD: wdc.c,v 1.68 1999/06/23 19:00:17 bouyer Exp $ */
@@ -100,6 +100,7 @@
struct pool wdc_xfer_pool;
void __wdcerror(struct channel_softc *, char *);
+void __wdcdo_reset(struct channel_softc *);
int __wdcwait_reset(struct channel_softc *, int);
void __wdccommand_done(struct channel_softc *, struct wdc_xfer *);
void __wdccommand_start(struct channel_softc *, struct wdc_xfer *);
@@ -657,10 +658,7 @@ wdcprobe(chp)
}
/* reset the channel */
- CHP_WRITE_REG(chp,wdr_ctlr, WDCTL_RST | WDCTL_4BIT);
- delay(10);
- CHP_WRITE_REG(chp, wdr_ctlr, WDCTL_4BIT);
- delay(2000);
+ __wdcdo_reset(chp);
ret_value = __wdcwait_reset(chp, ret_value);
WDCDEBUG_PRINT(("%s:%d: after reset, ret_value=0x%d\n",
@@ -1033,10 +1031,7 @@ wdcreset(chp, verb)
if (!chp->_vtbl)
chp->_vtbl = &wdc_default_vtbl;
- CHP_WRITE_REG(chp, wdr_ctlr, WDCTL_RST | WDCTL_4BIT);
- delay(10);
- CHP_WRITE_REG(chp, wdr_ctlr, WDCTL_4BIT);
- delay(2000);
+ __wdcdo_reset(chp);
drv_mask1 = (chp->ch_drive[0].drive_flags & DRIVE) ? 0x01:0x00;
drv_mask1 |= (chp->ch_drive[1].drive_flags & DRIVE) ? 0x02:0x00;
@@ -1054,6 +1049,17 @@ wdcreset(chp, verb)
return (drv_mask1 != drv_mask2) ? 1 : 0;
}
+void
+__wdcdo_reset(struct channel_softc *chp)
+{
+ wdc_set_drive(chp, 0);
+ DELAY(10);
+ CHP_WRITE_REG(chp, wdr_ctlr, WDCTL_IDS | WDCTL_RST);
+ delay(10000);
+ CHP_WRITE_REG(chp, wdr_ctlr, WDCTL_IDS);
+ delay(10000);
+}
+
int
__wdcwait_reset(chp, drv_mask)
struct channel_softc *chp;