From 4a1dbddc19009a289f8f5a41c5fa74fcaba9ca58 Mon Sep 17 00:00:00 2001 From: Alexander Yurchenko Date: Sun, 26 Oct 2003 14:29:48 +0000 Subject: 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@. --- sys/dev/ic/wdc.c | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) (limited to 'sys/dev/ic/wdc.c') 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; -- cgit v1.2.3