diff options
author | Constantine Sapuntzakis <csapuntz@cvs.openbsd.org> | 2000-01-12 17:14:03 +0000 |
---|---|---|
committer | Constantine Sapuntzakis <csapuntz@cvs.openbsd.org> | 2000-01-12 17:14:03 +0000 |
commit | 73f042400ef46e49cd6ab2644cb38f107a970a6a (patch) | |
tree | f66c778e8389624782ffca46833400a35dfdd2f5 | |
parent | 0f3b0d4771a006aa1e12d5c867fdb62d63d0feac (diff) |
For reasons beyond my comprehension, touching the sdh register too much
during probe causes the devices pain.
So, I don't do that any more. :-)
Also, try ATAPI_IDENTIFY_DEVICE a couple times. Seems to help with an
old NEC drive.
-rw-r--r-- | sys/dev/atapiscsi/atapiscsi.c | 61 |
1 files changed, 44 insertions, 17 deletions
diff --git a/sys/dev/atapiscsi/atapiscsi.c b/sys/dev/atapiscsi/atapiscsi.c index 36751488137..d888f693f1a 100644 --- a/sys/dev/atapiscsi/atapiscsi.c +++ b/sys/dev/atapiscsi/atapiscsi.c @@ -1,4 +1,4 @@ -/* $OpenBSD: atapiscsi.c,v 1.23 1999/12/19 22:57:52 csapuntz Exp $ */ +/* $OpenBSD: atapiscsi.c,v 1.24 2000/01/12 17:14:02 csapuntz Exp $ */ /* * This code is derived from code with the copyright below. @@ -267,6 +267,7 @@ atapiscsi_attach(parent, self, aux) drvp->drive_flags &= ~DRIVE_ATAPI; } + as->sc_adapterlink.scsibus = (u_int8_t)-1; config_found((struct device *)as, @@ -319,12 +320,6 @@ wdc_atapi_minphys (struct buf *bp) minphys(bp); } - -/* - * The scsi_cmd interface works as follows: - * - */ - int wdc_atapi_get_params(chp, drive, id) struct channel_softc *chp; @@ -333,6 +328,7 @@ wdc_atapi_get_params(chp, drive, id) { struct ata_drive_datas *drvp = &chp->ch_drive[drive]; struct wdc_command wdc_c; + int retries = 3; /* if no ATAPI device detected at wdc attach time, skip */ /* @@ -369,13 +365,22 @@ wdc_atapi_get_params(chp, drive, id) /* Some ATAPI devices need a bit more time after software reset. */ delay(5000); + + retry: if (ata_get_params(drvp, AT_POLL, id) != 0) { WDCDEBUG_PRINT(("wdc_atapi_get_params: ATAPI_IDENTIFY_DEVICE " - "failed for drive %s:%d:%d: error 0x%x\n", - chp->wdc->sc_dev.dv_xname, chp->channel, drive, - wdc_c.r_error), DEBUG_PROBE); + "failed for drive %s:%d:%d\n", + chp->wdc->sc_dev.dv_xname, chp->channel, drive), + DEBUG_PROBE); + + if (retries--) { + delay(100000); + goto retry; + } + return (-1); } + return (COMPLETE); } @@ -528,6 +533,17 @@ atapi_to_scsi_sense(xfer, flags) return (ret); } +int wdc_atapi_drive_selected __P((struct channel_softc *, int)); + +int +wdc_atapi_drive_selected(chp, drive) + struct channel_softc *chp; + int drive; +{ + u_int8_t reg = CHP_READ_REG(chp, wdr_sdh); + + return ((reg & 0x10) == (drive << 4)); +} enum atapi_context { ctxt_process = 0, @@ -1193,9 +1209,6 @@ wdc_atapi_intr_for_us(chp, xfer, timeout) WDCDEBUG_PRINT(("ATAPI_INTR\n"), DEBUG_INTR); - CHP_WRITE_REG(chp, wdr_sdh, WDSD_IBM | (xfer->drive << 4)); - DELAY (1); - wdc_atapi_update_status(chp); if (timeout) { @@ -1215,6 +1228,14 @@ wdc_atapi_intr_for_us(chp, xfer, timeout) if (chp->ch_status & WDCS_BSY) return (CONTINUE_POLL); + if (!wdc_atapi_drive_selected(chp, xfer->drive)) + { + CHP_WRITE_REG(chp, wdr_sdh, WDSD_IBM | (xfer->drive << 4)); + delay (1); + + return (CONTINUE_POLL); + } + if (as->protocol_phase != as_cmdout && (xfer->c_flags & C_MEDIA_ACCESS) && !(chp->ch_status & WDCS_DSC)) { @@ -1279,14 +1300,20 @@ wdc_atapi_ctrl(chp, xfer, timeout) } } - CHP_WRITE_REG(chp, wdr_sdh, WDSD_IBM | (xfer->drive << 4)); - delay (1); - wdc_atapi_update_status(chp); - + if (chp->ch_status & WDCS_BSY) return (CONTINUE_POLL); + if (!wdc_atapi_drive_selected(chp, xfer->drive)) + { + CHP_WRITE_REG(chp, wdr_sdh, WDSD_IBM | (xfer->drive << 4)); + delay (1); + + return (CONTINUE_POLL); + } + + xfer->claim_irq = 1; WDCDEBUG_PRINT(("wdc_atapi_ctrl %s:%d:%d state %d\n", |