summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorJason Downs <downsj@cvs.openbsd.org>1997-07-04 19:17:57 +0000
committerJason Downs <downsj@cvs.openbsd.org>1997-07-04 19:17:57 +0000
commitbcd6935cb01ba9cd0548025e8a64506dd9f7f1b0 (patch)
treee2668280e29c8dd61ab1fab8fc5269065119ddde /sys
parent6263de823eb88399a3f6073c492d8c166a77e10c (diff)
ASUS/Triton support, based on manuel's code (different, busified, should
still amount to the same thing, but I don't have such a board to test). Original log: date: 1997/06/16 13:43:57; author: bouyer; state: Exp; lines: +27 -11 Support pour la nouvelle Asustek TX97-E (avec le nouveau chip Triton).
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/isa/wdc.c41
1 files changed, 31 insertions, 10 deletions
diff --git a/sys/dev/isa/wdc.c b/sys/dev/isa/wdc.c
index 48094436200..69720b8d9cf 100644
--- a/sys/dev/isa/wdc.c
+++ b/sys/dev/isa/wdc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: wdc.c,v 1.19 1997/07/04 17:02:04 downsj Exp $ */
+/* $OpenBSD: wdc.c,v 1.20 1997/07/04 19:17:56 downsj Exp $ */
/* $NetBSD: wd.c,v 1.150 1996/05/12 23:54:03 mycroft Exp $ */
/*
@@ -100,6 +100,8 @@ struct cfdriver wdc_cd = {
NULL, "wdc", DV_DULL
};
+enum wdcreset_mode { WDCRESET_VERBOSE, WDCRESET_SILENT };
+
#if NWD > 0
int wdc_ata_intr __P((struct wdc_softc *,struct wdc_xfer *));
void wdc_ata_start __P((struct wdc_softc *,struct wdc_xfer *));
@@ -109,7 +111,7 @@ __inline static void u_int16_to_string __P((u_int16_t *, char *, size_t));
int wait_for_phase __P((struct wdc_softc *, int));
int wait_for_unphase __P((struct wdc_softc *, int));
void wdcstart __P((struct wdc_softc *));
-int wdcreset __P((struct wdc_softc *));
+int wdcreset __P((struct wdc_softc *, enum wdcreset_mode));
void wdcrestart __P((void *arg));
void wdcunwedge __P((struct wdc_softc *));
void wdctimeout __P((void *arg));
@@ -175,10 +177,20 @@ wdcprobe(parent, match, aux)
wdc->sc_flags |= WDCF_ONESLAVE;
}
- if (wdcreset(wdc) != 0) {
- delay(500000);
- if (wdcreset(wdc) != 0)
- goto nomatch;
+ if (wdcreset(wdc, WDCRESET_SILENT) != 0) {
+ /*
+ * if the reset failed,, there is no master. test for ATAPI
+ * signature on the salve device. If no ATAPI slave, wait 5s
+ * and retry a reset.
+ */
+ bus_space_write_1(iot, ioh, wd_sdh, WDSD_IBM | 0x10); /* slave */
+ if (bus_space_read_1(iot, ioh, wd_cyl_lo) != 0x14 ||
+ bus_space_read_1(iot, ioh, wd_cyl_hi) != 0xeb) {
+ delay(500000);
+ if (wdcreset(wdc, WDCRESET_SILENT) != 0)
+ goto nomatch;
+ }
+ wdc->sc_flags |= WDCF_ONESLAVE;
}
/* Select drive 0 or ATAPI slave device */
@@ -233,6 +245,8 @@ wdcattach(parent, self, aux)
#if NWD > 0
int drive;
#endif /* NWD */
+ bus_space_tag_t iot = wdc->sc_iot;
+ bus_space_handle_t ioh = wdc->sc_ioh;
TAILQ_INIT(&wdc->sc_xfer);
wdc->sc_drq = ia->ia_drq;
@@ -268,6 +282,12 @@ wdcattach(parent, self, aux)
* Attach standard IDE/ESDI/etc. disks to the controller.
*/
for (drive = 0; drive < 2; drive++) {
+ /* test for ATAPI signature on this drive */
+ bus_space_write_1(iot, ioh, wd_sdh, WDSD_IBM | (drive << 4));
+ if (bus_space_read_1(iot, ioh, wd_cyl_lo) == 0x14 &&
+ bus_space_read_1(iot, ioh, wd_cyl_hi) == 0xeb) {
+ continue;
+ }
/* controller active while autoconf */
wdc->sc_flags |= WDCF_ACTIVE;
@@ -1126,7 +1146,7 @@ wdc_atapi_get_params(ab_link, drive, id)
wdc->sc_flags |= WDCF_ACTIVE;
error = 1;
- (void)wdcreset(wdc);
+ (void)wdcreset(wdc, WDCRESET_VERBOSE);
if ((status = wdccommand((struct wd_link*)ab_link,
ATAPI_SOFT_RESET, drive, 0, 0, 0, 0)) != 0) {
#ifdef ATAPI_DEBUG
@@ -1543,8 +1563,9 @@ wdcintr(arg)
}
int
-wdcreset(wdc)
+wdcreset(wdc, mode)
struct wdc_softc *wdc;
+ enum wdcreset_mode mode;
{
bus_space_tag_t iot = wdc->sc_iot;
bus_space_handle_t ioh = wdc->sc_ioh;
@@ -1557,7 +1578,7 @@ wdcreset(wdc)
(void) bus_space_read_1(iot, ioh, wd_error);
bus_space_write_1(iot, ioh, wd_ctlr, WDCTL_4BIT);
- if (wait_for_unbusy(wdc) < 0) {
+ if ((wait_for_unbusy(wdc) < 0) && mode != WDCRESET_SILENT) {
printf("%s: reset failed\n", wdc->sc_dev.dv_xname);
return 1;
}
@@ -1596,7 +1617,7 @@ wdcunwedge(wdc)
untimeout(wdctimeout, wdc);
wdc->sc_flags &= ~WDCF_IRQ_WAIT;
- (void) wdcreset(wdc);
+ (void) wdcreset(wdc, WDCRESET_VERBOSE);
/* Schedule recalibrate for all drives on this controller. */
for (unit = 0; unit < 2; unit++) {