summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorConstantine Sapuntzakis <csapuntz@cvs.openbsd.org>2000-07-20 07:40:34 +0000
committerConstantine Sapuntzakis <csapuntz@cvs.openbsd.org>2000-07-20 07:40:34 +0000
commit4102e47a146ec457668af3567e31fc3831116054 (patch)
tree36497063240b5984571224da233896a1b54548a6
parent3dc6d2b7b2aa9826763759e522e39385dda07520 (diff)
Fix to ATA detect. Some devices seem to be comatose after reset
(return 0x00 status persistently). Send them identify to wake them up. Flag value 0x10000 will enable probe messages for a channel/controller. When UKC supports setting flags, this will be useful debugging failing IDE detects without kernel recompiles.
-rw-r--r--sys/dev/ata/ata.c29
-rw-r--r--sys/dev/atapiscsi/atapiscsi.c16
-rw-r--r--sys/dev/ic/wdc.c36
-rw-r--r--sys/dev/ic/wdcvar.h5
4 files changed, 74 insertions, 12 deletions
diff --git a/sys/dev/ata/ata.c b/sys/dev/ata/ata.c
index 43925922e60..0f4eb3adea0 100644
--- a/sys/dev/ata/ata.c
+++ b/sys/dev/ata/ata.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ata.c,v 1.5 2000/04/07 11:22:46 niklas Exp $ */
+/* $OpenBSD: ata.c,v 1.6 2000/07/20 07:40:32 csapuntz Exp $ */
/* $NetBSD: ata.c,v 1.9 1999/04/15 09:41:09 bouyer Exp $ */
/*
* Copyright (c) 1998 Manuel Bouyer. All rights reserved.
@@ -38,9 +38,14 @@
#include <sys/device.h>
#include <sys/syslog.h>
-#include <dev/ic/wdcreg.h>
+#include <machine/bus.h>
+
#include <dev/ata/atareg.h>
#include <dev/ata/atavar.h>
+#include <dev/ic/wdcreg.h>
+#include <dev/ic/wdcvar.h>
+
+#define WDCDEBUG
#define DEBUG_FUNCS 0x08
#define DEBUG_PROBE 0x10
@@ -67,16 +72,18 @@ ata_get_params(drvp, flags, prms)
int i;
u_int16_t *p;
+ int try = 0;
WDCDEBUG_PRINT(("ata_get_parms\n"), DEBUG_FUNCS);
+ again:
bzero(tb, sizeof(tb));
bzero(prms, sizeof(struct ataparams));
bzero(&wdc_c, sizeof(struct wdc_command));
if (drvp->drive_flags & DRIVE_ATA) {
wdc_c.r_command = WDCC_IDENTIFY;
- wdc_c.r_st_bmask = WDCS_DRDY;
+ wdc_c.r_st_bmask = (try == 0) ? WDCS_DRDY : 0;
wdc_c.r_st_pmask = WDCS_DRQ;
wdc_c.timeout = 1000; /* 1s */
} else if (drvp->drive_flags & DRIVE_ATAPI) {
@@ -100,6 +107,22 @@ ata_get_params(drvp, flags, prms)
}
if (wdc_c.flags & (AT_ERROR | AT_TIMEOU | AT_DF)) {
+ struct channel_softc *chp = drvp->chnl_softc;
+
+ WDCDEBUG_PRINT(("IDENTIFY failed: 0x%x\n", wdc_c.flags)
+ , DEBUG_PROBE);
+
+ /* Andreas Gunnarsson reports a setup with a flash
+ disk where the ATA drive remains comatose until
+ it is sent a command */
+ if (try == 0 && (drvp->drive_flags & DRIVE_ATA) &&
+ (wdc_c.flags & AT_TIMEOU) &&
+ !(chp->ch_flags & WDCS_BSY)) {
+ WDCDEBUG_PRINT(("Retrying IDENTIFY\n"), DEBUG_PROBE);
+ try++;
+ goto again;
+ }
+
return CMD_ERR;
} else {
#if BYTE_ORDER == BIG_ENDIAN
diff --git a/sys/dev/atapiscsi/atapiscsi.c b/sys/dev/atapiscsi/atapiscsi.c
index 246a0ec2a43..62edec6abe1 100644
--- a/sys/dev/atapiscsi/atapiscsi.c
+++ b/sys/dev/atapiscsi/atapiscsi.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: atapiscsi.c,v 1.27 2000/06/30 06:56:24 art Exp $ */
+/* $OpenBSD: atapiscsi.c,v 1.28 2000/07/20 07:40:33 csapuntz Exp $ */
/*
* This code is derived from code with the copyright below.
@@ -68,6 +68,8 @@
#include <dev/atapiscsi/atapiconf.h>
+#define WDCDEBUG
+
#define DEBUG_INTR 0x01
#define DEBUG_XFERS 0x02
#define DEBUG_STATUS 0x04
@@ -77,7 +79,7 @@
#define DEBUG_POLL 0x40
#define DEBUG_ERRORS 0x80 /* Debug error handling code */
-#ifdef WDCDEBUG
+#if defined(WDCDEBUG)
int wdcdebug_atapi_mask = 0;
#define WDCDEBUG_PRINT(args, level) \
if (wdcdebug_atapi_mask & (level)) \
@@ -224,6 +226,11 @@ atapiscsi_attach(parent, self, aux)
printf("\n");
+#ifdef WDCDEBUG
+ if (chp->wdc->sc_dev.dv_cfdata->cf_flags & WDC_OPTION_PROBE_VERBOSE)
+ wdcdebug_atapi_mask |= DEBUG_PROBE;
+#endif
+
as->chp = chp;
as->sc_adapterlink.adapter_softc = as;
as->sc_adapterlink.adapter_target = 7;
@@ -295,6 +302,11 @@ atapiscsi_attach(parent, self, aux)
wdc_print_caps(drvp);
}
}
+
+#ifdef WDCDEBUG
+ if (chp->wdc->sc_dev.dv_cfdata->cf_flags & WDC_OPTION_PROBE_VERBOSE)
+ wdcdebug_atapi_mask &= ~DEBUG_PROBE;
+#endif
}
void
diff --git a/sys/dev/ic/wdc.c b/sys/dev/ic/wdc.c
index 44fcbda7bfc..0ba3621d019 100644
--- a/sys/dev/ic/wdc.c
+++ b/sys/dev/ic/wdc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: wdc.c,v 1.18 2000/06/30 01:03:41 art Exp $ */
+/* $OpenBSD: wdc.c,v 1.19 2000/07/20 07:40:32 csapuntz Exp $ */
/* $NetBSD: wdc.c,v 1.68 1999/06/23 19:00:17 bouyer Exp $ */
@@ -94,6 +94,8 @@
#include "atapiscsi.h"
+#define WDCDEBUG
+
#define WDCDELAY 100 /* 100 microseconds */
#define WDCNDELAY_RST (WDC_RESET_WAIT * 1000 / WDCDELAY)
#if 0
@@ -366,6 +368,10 @@ wdcprobe(chp)
if (!chp->_vtbl)
chp->_vtbl = &wdc_default_vtbl;
+#ifdef WDCDEBUG
+ if (chp->wdc->sc_dev.dv_cfdata->cf_flags & WDC_OPTION_PROBE_VERBOSE)
+ wdcdebug_mask |= DEBUG_PROBE;
+#endif
/*
* Sanity check to see if the wdc channel responds at all.
*/
@@ -422,15 +428,16 @@ wdcprobe(chp)
CHP_WRITE_REG(chp, wdr_sdh, WDSD_IBM | (drive << 4));
delay(10);
/* Save registers contents */
+ st0 = CHP_READ_REG(chp, wdr_status);
sc = CHP_READ_REG(chp, wdr_seccnt);
sn = CHP_READ_REG(chp, wdr_sector);
cl = CHP_READ_REG(chp, wdr_cyl_lo);
ch = CHP_READ_REG(chp, wdr_cyl_hi);
- WDCDEBUG_PRINT(("%s:%d:%d: after reset, sc=0x%x sn=0x%x "
+ WDCDEBUG_PRINT(("%s:%d:%d: after reset, st=0x%x, sc=0x%x sn=0x%x "
"cl=0x%x ch=0x%x\n",
chp->wdc ? chp->wdc->sc_dev.dv_xname : "wdcprobe",
- chp->channel, drive, sc, sn, cl, ch), DEBUG_PROBE);
+ chp->channel, drive, st0, sc, sn, cl, ch), DEBUG_PROBE);
/*
* This is a simplification of the test in the ATAPI
* spec since not all drives seem to set the other regs
@@ -445,6 +452,11 @@ wdcprobe(chp)
chp->ch_drive[drive].drive_flags |= DRIVE_OLD;
}
}
+
+#ifdef WDCDEBUG
+ if (chp->wdc->sc_dev.dv_cfdata->cf_flags & WDC_OPTION_PROBE_VERBOSE)
+ wdcdebug_mask &= ~DEBUG_PROBE;
+#endif
return (ret_value);
}
@@ -500,6 +512,11 @@ wdcattach(chp)
return;
}
+#ifdef WDCDEBUG
+ if (chp->wdc->sc_dev.dv_cfdata->cf_flags & WDC_OPTION_PROBE_VERBOSE)
+ wdcdebug_mask |= DEBUG_PROBE;
+#endif
+
/* init list only once */
if (inited == 0) {
LIST_INIT(&xfer_free_list);
@@ -581,7 +598,7 @@ wdcattach(chp)
/* If no drives, abort here */
if ((chp->ch_drive[0].drive_flags & DRIVE) == 0 &&
(chp->ch_drive[1].drive_flags & DRIVE) == 0)
- return;
+ goto exit;
/*
* Attach an ATAPI bus, if needed.
@@ -655,6 +672,13 @@ wdcattach(chp)
#ifndef __OpenBSD__
wdc_delref(chp);
#endif
+
+ exit:
+#ifdef WDCDEBUG
+ if (chp->wdc->sc_dev.dv_cfdata->cf_flags & WDC_OPTION_PROBE_VERBOSE)
+ wdcdebug_mask &= ~DEBUG_PROBE;
+#endif
+ return;
}
/*
@@ -1459,8 +1483,8 @@ __wdccommand_done(chp, xfer)
{
struct wdc_command *wdc_c = xfer->cmd;
- WDCDEBUG_PRINT(("__wdccommand_done %s:%d:%d\n",
- chp->wdc->sc_dev.dv_xname, chp->channel, xfer->drive), DEBUG_FUNCS);
+ WDCDEBUG_PRINT(("__wdccommand_done %s:%d:%d %02x\n",
+ chp->wdc->sc_dev.dv_xname, chp->channel, xfer->drive, chp->ch_status), DEBUG_FUNCS);
if (chp->ch_status & WDCS_DWF)
wdc_c->flags |= AT_DF;
if (chp->ch_status & WDCS_ERR) {
diff --git a/sys/dev/ic/wdcvar.h b/sys/dev/ic/wdcvar.h
index d0c41794354..bcfb55a1a08 100644
--- a/sys/dev/ic/wdcvar.h
+++ b/sys/dev/ic/wdcvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: wdcvar.h,v 1.9 2000/06/30 01:03:41 art Exp $ */
+/* $OpenBSD: wdcvar.h,v 1.10 2000/07/20 07:40:32 csapuntz Exp $ */
/* $NetBSD: wdcvar.h,v 1.17 1999/04/11 20:50:29 bouyer Exp $ */
/*-
@@ -48,6 +48,9 @@ struct channel_queue { /* per channel queue (may be shared) */
struct channel_softc_vtbl;
+
+#define WDC_OPTION_PROBE_VERBOSE 0x10000
+
struct channel_softc { /* Per channel data */
struct channel_softc_vtbl *_vtbl;