diff options
author | Alexander Yurchenko <grange@cvs.openbsd.org> | 2003-10-26 14:29:48 +0000 |
---|---|---|
committer | Alexander Yurchenko <grange@cvs.openbsd.org> | 2003-10-26 14:29:48 +0000 |
commit | 4a1dbddc19009a289f8f5a41c5fa74fcaba9ca58 (patch) | |
tree | b6669eb1d071fc58d65e3f41757e3a093d113970 /sys/dev/ic | |
parent | 3a26d7a904f25fa8f508f274fcbb8dd3f04d38bd (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@.
Diffstat (limited to 'sys/dev/ic')
-rw-r--r-- | sys/dev/ic/wdc.c | 24 |
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; |