summaryrefslogtreecommitdiff
path: root/sys/dev/ic
diff options
context:
space:
mode:
authorConstantine Sapuntzakis <csapuntz@cvs.openbsd.org>1999-10-09 03:42:06 +0000
committerConstantine Sapuntzakis <csapuntz@cvs.openbsd.org>1999-10-09 03:42:06 +0000
commitacd5d55e740e3de51e4e63a4cf80566349e13a99 (patch)
tree32486c5f0a10e5103b98fbd2ab7eb49a1e62a6bb /sys/dev/ic
parentb045744877f18cf1bb06efce9045b8f79783b17e (diff)
wdc layer work:
Separate wdc_probe_caps into wdc_probe_caps and wdc_print_caps for more flexibility in printing capability information. Get rid of wdc_final_attach. Include name of device (e.g. cd0), if possible, on errors. atapiscsi layer work: Put a pointer to the SCSI device into ata_drive_datas' drv_softc field Simplify, simplify, simplify. Got rid of a bunch of fields in atapiscsi_softc Delay printing capabilities until we know the real device name (e.g. st0)
Diffstat (limited to 'sys/dev/ic')
-rw-r--r--sys/dev/ic/wdc.c148
-rw-r--r--sys/dev/ic/wdcvar.h10
2 files changed, 97 insertions, 61 deletions
diff --git a/sys/dev/ic/wdc.c b/sys/dev/ic/wdc.c
index de16826fa3c..270ebaff974 100644
--- a/sys/dev/ic/wdc.c
+++ b/sys/dev/ic/wdc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: wdc.c,v 1.9 1999/09/05 21:43:30 niklas Exp $ */
+/* $OpenBSD: wdc.c,v 1.10 1999/10/09 03:42:04 csapuntz Exp $ */
/* $NetBSD: wdc.c,v 1.68 1999/06/23 19:00:17 bouyer Exp $ */
@@ -127,6 +127,8 @@ int wdprint __P((void *, const char *));
#define DEBUG_STATUS 0x04
#define DEBUG_FUNCS 0x08
#define DEBUG_PROBE 0x10
+#define DEBUG_STATUSX 0x20
+
#ifdef WDCDEBUG
int wdcdebug_mask = 0;
int wdc_nxfer = 0;
@@ -290,11 +292,11 @@ wdcprobe(chp)
chp->wdc ? chp->wdc->sc_dev.dv_xname : "wdcprobe",
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 - or maybe it's the controller.
+ * This is a simplification of the test in the ATAPI
+ * spec since not all drives seem to set the other regs
+ * correctly.
*/
- if ((sc == 0x00 || sc == 0x01) && sn == 0x01 &&
- cl == 0x14 && ch == 0xeb) {
+ if (cl == 0x14 && ch == 0xeb) {
chp->ch_drive[drive].drive_flags |= DRIVE_ATAPI;
} else {
chp->ch_drive[drive].drive_flags |= DRIVE_ATA;
@@ -352,6 +354,9 @@ wdcattach(chp)
if ((chp->ch_drive[i].drive_flags & DRIVE) == 0)
continue;
+ if (i == 1 && ((chp->ch_drive[0].drive_flags & DRIVE) == 0))
+ chp->ch_flags |= WDCF_ONESLAVE;
+
/* Issue a IDENTIFY command, to try to detect slave ghost */
if (ata_get_params(&chp->ch_drive[i], AT_POLL, &params) ==
CMD_OK) {
@@ -454,8 +459,7 @@ wdcattach(chp)
aa_link.aa_channel = chp->channel;
aa_link.aa_openings = 1;
aa_link.aa_drv_data = &chp->ch_drive[i];
- if (config_found(&chp->wdc->sc_dev, (void *)&aa_link, wdprint))
- wdc_probe_caps(&chp->ch_drive[i]);
+ config_found(&chp->wdc->sc_dev, (void *)&aa_link, wdprint);
}
/*
@@ -495,15 +499,6 @@ wdcattach(chp)
#endif
}
-void
-wdc_final_attach(chp)
- struct channel_softc *chp;
-{
-#if NATAPISCSI > 0
- wdc_atapibus_final_attach(chp);
-#endif
-}
-
/*
* Start I/O on a controller, for the given channel.
* The first xfer may be not for our channel if the channel queues
@@ -723,8 +718,28 @@ wdcwait(chp, mask, bits, timeout)
timeout = timeout * 1000 / WDCDELAY; /* delay uses microseconds */
for (;;) {
+#ifdef TEST_ALTSTS
+ chp->ch_status = status =
+ bus_space_read_1(chp->ctl_iot, chp->ctl_ioh,
+ wd_aux_altsts);
+#else
chp->ch_status = status =
- bus_space_read_1(chp->cmd_iot, chp->cmd_ioh, wd_status);
+ bus_space_read_1(chp->cmd_iot, chp->cmd_ioh,
+ wd_status);
+#endif
+ if (status == 0xff && (chp->ch_flags & WDCF_ONESLAVE)) {
+ bus_space_write_1(chp->cmd_iot, chp->cmd_ioh, wd_sdh,
+ WDSD_IBM | 0x10);
+#ifdef TEST_ALTSTS
+ chp->ch_status = status =
+ bus_space_read_1(chp->ctl_iot, chp->ctl_ioh,
+ wd_aux_altsts);
+#else
+ chp->ch_status = status =
+ bus_space_read_1(chp->cmd_iot, chp->cmd_ioh,
+ wd_status);
+#endif
+ }
if ((status & WDCS_BSY) == 0 && (status & mask) == bits)
break;
if (++time > timeout) {
@@ -732,14 +747,22 @@ wdcwait(chp, mask, bits, timeout)
"error %x\n", status,
bus_space_read_1(chp->cmd_iot, chp->cmd_ioh,
wd_error)),
- DEBUG_STATUS);
+ DEBUG_STATUSX | DEBUG_STATUS);
return -1;
}
delay(WDCDELAY);
}
- if (status & WDCS_ERR)
+#ifdef TEST_ALTSTS
+ /* Acknowledge any pending interrupts */
+ bus_space_read_1(chp->cmd_iot, chp->cmd_ioh, wd_status);
+#endif
+ if (status & WDCS_ERR) {
chp->ch_error = bus_space_read_1(chp->cmd_iot, chp->cmd_ioh,
wd_error);
+ WDCDEBUG_PRINT(("wdcwait: error %x\n", chp->ch_error),
+ DEBUG_STATUSX | DEBUG_STATUS);
+ }
+
#ifdef WDCNDELAY_DEBUG
/* After autoconfig, there should be no long delays. */
if (!cold && time > WDCNDELAY_DEBUG) {
@@ -794,24 +817,20 @@ wdctimeout(arg)
* XXX this should be a controller-indep function
*/
void
-wdc_probe_caps(drvp)
+wdc_probe_caps(drvp, params)
struct ata_drive_datas *drvp;
+ struct ataparams *params;
{
- struct ataparams params, params2;
struct channel_softc *chp = drvp->chnl_softc;
struct device *drv_dev = drvp->drv_softc;
struct wdc_softc *wdc = chp->wdc;
int i, printed;
- char *sep = "";
int cf_flags;
- if (ata_get_params(drvp, AT_POLL, &params) != CMD_OK) {
- /* IDENTIFY failed. Can't tell more about the device */
- return;
- }
- printf("%s: ", drv_dev->dv_xname);
if ((wdc->cap & (WDC_CAPABILITY_DATA16 | WDC_CAPABILITY_DATA32)) ==
(WDC_CAPABILITY_DATA16 | WDC_CAPABILITY_DATA32)) {
+ struct ataparams params2;
+
/*
* Controller claims 16 and 32 bit transfers.
* Re-do an IDENTIFY with 32-bit transfers,
@@ -819,19 +838,16 @@ wdc_probe_caps(drvp)
*/
drvp->drive_flags |= DRIVE_CAP32;
ata_get_params(drvp, AT_POLL, &params2);
- if (bcmp(&params, &params2, sizeof(struct ataparams)) != 0) {
+ if (bcmp(params, &params2, sizeof(struct ataparams)) != 0) {
/* Not good. fall back to 16bits */
drvp->drive_flags &= ~DRIVE_CAP32;
- printf("16-bit");
- } else
- printf("32-bit");
- sep = ", ";
+ }
}
#if 0 /* Some ultra-DMA drives claims to only support ATA-3. sigh */
- if (params.atap_ata_major > 0x01 &&
- params.atap_ata_major != 0xffff) {
+ if (params->atap_ata_major > 0x01 &&
+ params->atap_ata_major != 0xffff) {
for (i = 14; i > 0; i--) {
- if (params.atap_ata_major & (1 << i)) {
+ if (params->atap_ata_major & (1 << i)) {
printf("%sATA version %d\n", sep, i);
drvp->ata_vers = i;
break;
@@ -847,8 +863,8 @@ wdc_probe_caps(drvp)
* It's not in the specs, but it seems that some drive
* returns 0xffff in atap_extensions when this field is invalid
*/
- if (params.atap_extensions != 0xffff &&
- (params.atap_extensions & WDC_EXT_MODES)) {
+ if (params->atap_extensions != 0xffff &&
+ (params->atap_extensions & WDC_EXT_MODES)) {
printed = 0;
/*
* XXX some drives report something wrong here (they claim to
@@ -857,10 +873,9 @@ wdc_probe_caps(drvp)
* If higther mode than 7 is found, abort.
*/
for (i = 7; i >= 0; i--) {
- if ((params.atap_piomode_supp & (1 << i)) == 0)
+ if ((params->atap_piomode_supp & (1 << i)) == 0)
continue;
if (i > 4) {
- printf("\n");
return;
}
@@ -875,8 +890,6 @@ wdc_probe_caps(drvp)
AT_POLL) != CMD_OK)
continue;
if (!printed) {
- printf("%ssupports PIO mode %d", sep, i + 3);
- sep = ", ";
printed = 1;
}
/*
@@ -895,13 +908,12 @@ wdc_probe_caps(drvp)
* We didn't find a valid PIO mode.
* Assume the values returned for DMA are buggy too
*/
- printf("\n");
return;
}
drvp->drive_flags |= DRIVE_MODE;
printed = 0;
for (i = 7; i >= 0; i--) {
- if ((params.atap_dmamode_supp & (1 << i)) == 0)
+ if ((params->atap_dmamode_supp & (1 << i)) == 0)
continue;
if ((wdc->cap & WDC_CAPABILITY_DMA) &&
(wdc->cap & WDC_CAPABILITY_MODE))
@@ -909,8 +921,6 @@ wdc_probe_caps(drvp)
!= CMD_OK)
continue;
if (!printed) {
- printf("%sDMA mode %d", sep, i);
- sep = ", ";
printed = 1;
}
if (wdc->cap & WDC_CAPABILITY_DMA) {
@@ -923,9 +933,9 @@ wdc_probe_caps(drvp)
}
break;
}
- if (params.atap_extensions & WDC_EXT_UDMA_MODES) {
+ if (params->atap_extensions & WDC_EXT_UDMA_MODES) {
for (i = 7; i >= 0; i--) {
- if ((params.atap_udmamode_supp & (1 << i))
+ if ((params->atap_udmamode_supp & (1 << i))
== 0)
continue;
if ((wdc->cap & WDC_CAPABILITY_MODE) &&
@@ -933,8 +943,6 @@ wdc_probe_caps(drvp)
if (ata_set_mode(drvp, 0x40 | i,
AT_POLL) != CMD_OK)
continue;
- printf("%sUltra-DMA mode %d", sep, i);
- sep = ", ";
if (wdc->cap & WDC_CAPABILITY_UDMA) {
if ((wdc->cap & WDC_CAPABILITY_MODE) &&
wdc->UDMA_cap < i)
@@ -947,7 +955,6 @@ wdc_probe_caps(drvp)
}
}
}
- printf("\n");
/* Try to guess ATA version here, if it didn't get reported */
if (drvp->ata_vers == 0) {
@@ -988,6 +995,32 @@ wdc_probe_caps(drvp)
}
}
+void
+wdc_print_caps(drvp)
+ struct ata_drive_datas *drvp;
+{
+ struct device *drv_dev = drvp->drv_softc;
+
+ printf("%s: can use ", drv_dev->dv_xname);
+
+ if (drvp->drive_flags & DRIVE_CAP32) {
+ printf("32-bit");
+ } else
+ printf("16-bit");
+
+ printf(", PIO mode %d", drvp->PIO_cap);
+
+ if (drvp->drive_flags & DRIVE_DMA) {
+ printf(", DMA mode %d", drvp->DMA_cap);
+ }
+
+ if (drvp->drive_flags & DRIVE_UDMA) {
+ printf(", Ultra-DMA mode %d", drvp->UDMA_cap);
+ }
+
+ printf("\n");
+}
+
/*
* downgrade the transfer mode of a drive after an error. return 1 if
* downgrade was possible, 0 otherwise.
@@ -1395,9 +1428,18 @@ __wdcerror(chp, msg)
if (xfer == NULL)
printf("%s:%d: %s\n", chp->wdc->sc_dev.dv_xname, chp->channel,
msg);
- else
- printf("%s:%d:%d: %s\n", chp->wdc->sc_dev.dv_xname,
- chp->channel, xfer->drive, msg);
+ else {
+ struct device *drv_dev = chp->ch_drive[xfer->drive].drv_softc;
+
+ if (drv_dev) {
+ printf("%s(%s:%d:%d): %s\n", drv_dev->dv_xname,
+ chp->wdc->sc_dev.dv_xname,
+ chp->channel, xfer->drive, msg);
+ } else {
+ printf("%s:%d:%d: %s\n", chp->wdc->sc_dev.dv_xname,
+ chp->channel, xfer->drive, msg);
+ }
+ }
}
/*
diff --git a/sys/dev/ic/wdcvar.h b/sys/dev/ic/wdcvar.h
index 9319311eb0b..46d60d93874 100644
--- a/sys/dev/ic/wdcvar.h
+++ b/sys/dev/ic/wdcvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: wdcvar.h,v 1.2 1999/07/22 02:54:06 csapuntz Exp $ */
+/* $OpenBSD: wdcvar.h,v 1.3 1999/10/09 03:42:04 csapuntz Exp $ */
/* $NetBSD: wdcvar.h,v 1.17 1999/04/11 20:50:29 bouyer Exp $ */
/*-
@@ -37,8 +37,6 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
-struct atapiscsi_softc;
-
#define WAITTIME (10 * hz) /* time to wait for a completion */
/* this is a lot for hard drives, but not for cdroms */
@@ -63,13 +61,12 @@ struct channel_softc { /* Per channel data */
int ch_flags;
#define WDCF_ACTIVE 0x01 /* channel is active */
#define WDCF_IRQ_WAIT 0x10 /* controller is waiting for irq */
+#define WDCF_ONESLAVE 0x20 /* slave-only channel */
u_int8_t ch_status; /* copy of status register */
u_int8_t ch_error; /* copy of error register */
/* per-drive infos */
struct ata_drive_datas ch_drive[2];
- struct atapiscsi_softc *ch_as;
-
/*
* channel queues. May be the same for all channels, if hw channels
* are not independants
@@ -159,7 +156,6 @@ struct wdc_xfer {
int wdcprobe __P((struct channel_softc *));
void wdcattach __P((struct channel_softc *));
-void wdc_final_attach __P((struct channel_softc *));
int wdcintr __P((void *));
void wdc_exec_xfer __P((struct channel_softc *, struct wdc_xfer *));
struct wdc_xfer *wdc_get_xfer __P((int)); /* int = WDC_NOSLEEP/CANSLEEP */
@@ -193,8 +189,6 @@ void wdc_delref __P((struct channel_softc *));
#define WDC_RESET_WAIT 31000
void wdc_atapibus_attach __P((struct channel_softc *));
-void wdc_atapibus_final_attach __P((struct channel_softc *));
-
int atapi_print __P((void *, const char *));
void wdc_disable_intr __P((struct channel_softc *));