diff options
| author | bouyer <bouyer@NetBSD.org> | 1999-04-11 20:50:28 +0000 |
|---|---|---|
| committer | bouyer <bouyer@NetBSD.org> | 1999-04-11 20:50:28 +0000 |
| commit | 503de51fdd68bdd5bc0b29429b42a37ecc61da0c (patch) | |
| tree | 5d4afd94c6f067a16130007c897ed2c6b1c514fc /sys/dev | |
| parent | bff1bef0062e252bbecc019f47db1e11d4b54d66 (diff) | |
Fix probe code for IDE devices:
- Don't rely on ATA signature: some ide controllers seems to not transmit it
properly (SIMIDE on arm32 machines). Instead, when we guess a drive is here
after reset, just mark it as ATA and OLD is it's not ATAPI.
- at attach time, use IDENTIFY to eliminate ghost from the probe. If the
drive had the old flag and IDENTIFY failed, issue a WDCC_RECAL command
to detect a pre-ATA disk. If IDENTIFY succeded, remove the OLD flag,
it's obviously not a pre-ATA disk.
- add a new controller flag, WDC_CAPABILITY_PREATA, used to shorcut parts
of the probe (not necessary, but makes the probe/attach faster). This is
only set by the ISA front-end, all other controllers supported can't have
pre-ATA drives attached.
The mechanism used are more or less the same as before, they have just been
reordered. Should solve port-arm32/7324 (waiting for feedback).
Diffstat (limited to 'sys/dev')
| -rw-r--r-- | sys/dev/ic/wdc.c | 105 | ||||
| -rw-r--r-- | sys/dev/ic/wdcvar.h | 3 | ||||
| -rw-r--r-- | sys/dev/isa/wdc_isa.c | 5 |
3 files changed, 52 insertions, 61 deletions
diff --git a/sys/dev/ic/wdc.c b/sys/dev/ic/wdc.c index 32b25b55ed3..82576e01f3d 100644 --- a/sys/dev/ic/wdc.c +++ b/sys/dev/ic/wdc.c @@ -1,4 +1,4 @@ -/* $NetBSD: wdc.c,v 1.66 1999/04/01 21:46:29 bouyer Exp $ */ +/* $NetBSD: wdc.c,v 1.67 1999/04/11 20:50:28 bouyer Exp $ */ /* @@ -231,9 +231,9 @@ wdcprobe(chp) /* * Test presence of drives. First test register signatures looking for - * ATAPI devices , then rescan and try an ATA command, in case it's an - * old drive. - * Fill in drive_flags accordingly + * ATAPI devices. If it's not an ATAPI and reset said there may be + * something here assume it's ATA or OLD. Ghost will be killed later in + * attach routine. */ for (drive = 0; drive < 2; drive++) { if ((ret_value & (0x01 << drive)) == 0) @@ -253,63 +253,16 @@ wdcprobe(chp) chp->channel, drive, sc, sn, cl, ch), DEBUG_PROBE); /* * sc is supposted to be 0x1 for ATAPI but at last one drive - * set it to 0x0. + * set it to 0x0 - or maybe it's the controller. */ if ((sc == 0x00 || sc == 0x01) && sn == 0x01 && cl == 0x14 && ch == 0xeb) { chp->ch_drive[drive].drive_flags |= DRIVE_ATAPI; - } else if (sc == 0x01 && sn == 0x01 && - cl == 0x00 && ch == 0x00) { - chp->ch_drive[drive].drive_flags |= DRIVE_ATA; - } - } - /* - * Maybe there's an old device, try to detect it if we didn't - * find a ATA or ATAPI device. - */ - if ((chp->ch_drive[0].drive_flags & DRIVE) != 0 || - (chp->ch_drive[1].drive_flags & DRIVE) != 0) - return (ret_value); - for (drive = 0; drive < 2; drive++) { - if ((ret_value & (0x01 << drive)) == 0) - continue; - bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_sdh, - WDSD_IBM | (drive << 4)); - delay(10); - /* - * Test registers writability (Error register not writable, - * but cyllo is), then try an ATA command. - */ - bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_error, 0x58); - bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_cyl_lo, 0xa5); - if (bus_space_read_1(chp->cmd_iot, chp->cmd_ioh, wd_error) == - 0x58 || - bus_space_read_1(chp->cmd_iot, chp->cmd_ioh, wd_cyl_lo) != - 0xa5) { - WDCDEBUG_PRINT(("%s:%d:%d: register writability " - "failed\n", - chp->wdc ? chp->wdc->sc_dev.dv_xname : "wdcprobe", - chp->channel, drive), DEBUG_PROBE); - ret_value &= ~(0x01 << drive); - continue; - } - if (wait_for_ready(chp, 10000) != 0) { - WDCDEBUG_PRINT(("%s:%d:%d: not ready\n", - chp->wdc ? chp->wdc->sc_dev.dv_xname : "wdcprobe", - chp->channel, drive), DEBUG_PROBE); - ret_value &= ~(0x01 << drive); - continue; - } - bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_command, - WDCC_RECAL); - if (wait_for_ready(chp, 10000) == 0) { - chp->ch_drive[drive].drive_flags |= - DRIVE_OLD; } else { - WDCDEBUG_PRINT(("%s:%d:%d: WDCC_RECAL failed\n", - chp->wdc ? chp->wdc->sc_dev.dv_xname : "wdcprobe", - chp->channel, drive), DEBUG_PROBE); - ret_value &= ~(0x01 << drive); + chp->ch_drive[drive].drive_flags |= DRIVE_ATA; + if (chp->wdc == NULL || + (chp->wdc->cap & WDC_CAPABILITY_PREATA) != 0) + chp->ch_drive[drive].drive_flags |= DRIVE_OLD; } } return (ret_value); @@ -351,12 +304,42 @@ wdcattach(chp) (WDC_CAPABILITY_DATA16 | WDC_CAPABILITY_DATA32)) == WDC_CAPABILITY_DATA32) chp->ch_drive[i].drive_flags |= DRIVE_CAP32; + if ((chp->ch_drive[i].drive_flags & DRIVE) == 0) + continue; /* Issue a IDENTIFY command, to try to detect slave ghost */ - if (ata_get_params(&chp->ch_drive[i], AT_POLL, ¶ms) != + if (ata_get_params(&chp->ch_drive[i], AT_POLL, ¶ms) == CMD_OK) { + /* If IDENTIFY succeded, this is not an OLD ctrl */ + chp->ch_drive[0].drive_flags &= ~DRIVE_OLD; + chp->ch_drive[1].drive_flags &= ~DRIVE_OLD; + } else { chp->ch_drive[i].drive_flags &= ~(DRIVE_ATA | DRIVE_ATAPI); + WDCDEBUG_PRINT(("%s:%d:%d: IDENTIFY failed\n", + chp->wdc->sc_dev.dv_xname, + chp->channel, i), DEBUG_PROBE); + if ((chp->ch_drive[i].drive_flags & DRIVE_OLD) == 0) + continue; + /* Pre-ATA drive ? */ + bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_sdh, + WDSD_IBM | (i << 4)); + delay(100); + if (wait_for_ready(chp, 10000) != 0) { + WDCDEBUG_PRINT(("%s:%d:%d: not ready\n", + chp->wdc->sc_dev.dv_xname, + chp->channel, i), DEBUG_PROBE); + chp->ch_drive[i].drive_flags &= ~DRIVE_OLD; + continue; + } + bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, + wd_command, WDCC_RECAL); + if (wait_for_ready(chp, 10000) != 0) { + WDCDEBUG_PRINT(("%s:%d:%d: WDCC_RECAL failed\n", + chp->wdc->sc_dev.dv_xname, + chp->channel, i), DEBUG_PROBE); + chp->ch_drive[i].drive_flags &= ~DRIVE_OLD; + } } } ctrl_flags = chp->wdc->sc_dev.dv_cfdata->cf_flags; @@ -366,6 +349,11 @@ wdcattach(chp) chp->ch_drive[0].drive_flags, chp->ch_drive[1].drive_flags), DEBUG_PROBE); + /* If no drives, abort here */ + if ((chp->ch_drive[0].drive_flags & DRIVE) == 0 && + (chp->ch_drive[1].drive_flags & DRIVE) == 0) + return; + /* * Attach an ATAPI bus, if needed. */ @@ -391,7 +379,8 @@ wdcattach(chp) } for (i = 0; i < 2; i++) { - if ((chp->ch_drive[i].drive_flags & DRIVE_ATA) == 0) { + if ((chp->ch_drive[i].drive_flags & + (DRIVE_ATA | DRIVE_OLD)) == 0) { continue; } memset(&aa_link, 0, sizeof(struct ata_atapi_attach)); diff --git a/sys/dev/ic/wdcvar.h b/sys/dev/ic/wdcvar.h index f5f0436e03a..96d19f39c9e 100644 --- a/sys/dev/ic/wdcvar.h +++ b/sys/dev/ic/wdcvar.h @@ -1,4 +1,4 @@ -/* $NetBSD: wdcvar.h,v 1.16 1999/04/01 21:46:30 bouyer Exp $ */ +/* $NetBSD: wdcvar.h,v 1.17 1999/04/11 20:50:29 bouyer Exp $ */ /*- * Copyright (c) 1998 The NetBSD Foundation, Inc. @@ -90,6 +90,7 @@ struct wdc_softc { /* Per controller state */ #define WDC_CAPABILITY_ATA_NOSTREAM 0x0040 /* Don't use stream funcs on ATA */ #define WDC_CAPABILITY_ATAPI_NOSTREAM 0x0080 /* Don't use stream f on ATAPI */ #define WDC_CAPABILITY_NO_EXTRA_RESETS 0x0100 /* only reset once */ +#define WDC_CAPABILITY_PREATA 0x0200 /* ctrl can be a pre-ata one */ u_int8_t PIO_cap; /* highest PIO mode supported */ u_int8_t DMA_cap; /* highest DMA mode supported */ u_int8_t UDMA_cap; /* highest UDMA mode supported */ diff --git a/sys/dev/isa/wdc_isa.c b/sys/dev/isa/wdc_isa.c index e9b88d1af04..93416805287 100644 --- a/sys/dev/isa/wdc_isa.c +++ b/sys/dev/isa/wdc_isa.c @@ -1,4 +1,4 @@ -/* $NetBSD: wdc_isa.c,v 1.13 1999/02/22 03:24:33 mycroft Exp $ */ +/* $NetBSD: wdc_isa.c,v 1.14 1999/04/11 20:50:29 bouyer Exp $ */ /*- * Copyright (c) 1998 The NetBSD Foundation, Inc. @@ -150,7 +150,8 @@ wdc_isa_attach(parent, self, aux) sc->sc_wdcdev.dma_finish = wdc_isa_dma_finish; wdc_isa_dma_setup(sc); } - sc->sc_wdcdev.cap |= WDC_CAPABILITY_DATA16 | WDC_CAPABILITY_DATA32; + sc->sc_wdcdev.cap |= WDC_CAPABILITY_DATA16 | WDC_CAPABILITY_DATA32 | + WDC_CAPABILITY_PREATA; sc->sc_wdcdev.PIO_cap = 0; sc->wdc_chanptr = &sc->wdc_channel; sc->sc_wdcdev.channels = &sc->wdc_chanptr; |
