Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/netbsd-2-0]: src/sys/dev/ic Pull up revision 1.174 (requested by bouyer ...
details: https://anonhg.NetBSD.org/src/rev/bdfdf2cc68d5
branches: netbsd-2-0
changeset: 561169:bdfdf2cc68d5
user: tron <tron%NetBSD.org@localhost>
date: Sat May 29 14:08:18 2004 +0000
description:
Pull up revision 1.174 (requested by bouyer in ticket #397):
In wdcprobe1(), protect the register writability test with splbio().
What we do here seems to trigger interrupts on some pcmcia adapters, which
cause the kernel to hang.
Add some WDCDEBUG_PRINT((), DEBUG_PROBE).
Avoid touching registers of nonexistent drives, once we know which drive is
or is not here.
This makes the "IBM PCMCIA Portable CD-ROM Drive" (external CD drive with
PCMCIA adapter) work.
diffstat:
sys/dev/ic/wdc.c | 249 +++++++++++++++++++++++++++++++++++++++---------------
1 files changed, 180 insertions(+), 69 deletions(-)
diffs (truncated from 335 to 300 lines):
diff -r eef7ca349df7 -r bdfdf2cc68d5 sys/dev/ic/wdc.c
--- a/sys/dev/ic/wdc.c Sat May 29 14:06:01 2004 +0000
+++ b/sys/dev/ic/wdc.c Sat May 29 14:08:18 2004 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: wdc.c,v 1.172.2.1 2004/05/29 14:05:54 tron Exp $ */
+/* $NetBSD: wdc.c,v 1.172.2.2 2004/05/29 14:08:18 tron Exp $ */
/*
* Copyright (c) 1998, 2001, 2003 Manuel Bouyer. All rights reserved.
@@ -70,7 +70,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: wdc.c,v 1.172.2.1 2004/05/29 14:05:54 tron Exp $");
+__KERNEL_RCSID(0, "$NetBSD: wdc.c,v 1.172.2.2 2004/05/29 14:08:18 tron Exp $");
#ifndef WDCDEBUG
#define WDCDEBUG
@@ -204,21 +204,25 @@
/* for ATA/OLD drives, wait for DRDY, 3s timeout */
for (i = 0; i < mstohz(3000); i++) {
- if (wdc != NULL && (wdc->cap & WDC_CAPABILITY_SELECT))
- wdc->select(chp,0);
- bus_space_write_1(chp->cmd_iot, chp->cmd_iohs[wd_sdh], 0,
- WDSD_IBM);
- delay(10); /* 400ns delay */
- st0 = bus_space_read_1(chp->cmd_iot,
- chp->cmd_iohs[wd_status], 0);
+ if (chp->ch_drive[0].drive_flags & (DRIVE_ATA|DRIVE_OLD)) {
+ if (wdc != NULL && (wdc->cap & WDC_CAPABILITY_SELECT))
+ wdc->select(chp,0);
+ bus_space_write_1(chp->cmd_iot, chp->cmd_iohs[wd_sdh],
+ 0, WDSD_IBM);
+ delay(10); /* 400ns delay */
+ st0 = bus_space_read_1(chp->cmd_iot,
+ chp->cmd_iohs[wd_status], 0);
+ }
- if (wdc != NULL && (wdc->cap & WDC_CAPABILITY_SELECT))
- wdc->select(chp,1);
- bus_space_write_1(chp->cmd_iot, chp->cmd_iohs[wd_sdh], 0,
- WDSD_IBM | 0x10);
- delay(10); /* 400ns delay */
- st1 = bus_space_read_1(chp->cmd_iot,
- chp->cmd_iohs[wd_status], 0);
+ if (chp->ch_drive[1].drive_flags & (DRIVE_ATA|DRIVE_OLD)) {
+ if (wdc != NULL && (wdc->cap & WDC_CAPABILITY_SELECT))
+ wdc->select(chp,1);
+ bus_space_write_1(chp->cmd_iot, chp->cmd_iohs[wd_sdh],
+ 0, WDSD_IBM | 0x10);
+ delay(10); /* 400ns delay */
+ st1 = bus_space_read_1(chp->cmd_iot,
+ chp->cmd_iohs[wd_status], 0);
+ }
if (((chp->ch_drive[0].drive_flags & (DRIVE_ATA|DRIVE_OLD))
== 0 ||
@@ -487,6 +491,7 @@
* Sanity check to see if the wdc channel responds at all.
*/
+ s = splbio();
if (wdc == NULL ||
(wdc->cap & WDC_CAPABILITY_NO_EXTRA_RESETS) == 0) {
@@ -524,27 +529,67 @@
0, WDSD_IBM);
bus_space_write_1(chp->cmd_iot,
chp->cmd_iohs[wd_cyl_lo], 0, 0x02);
- if (bus_space_read_1(chp->cmd_iot,
- chp->cmd_iohs[wd_cyl_lo], 0) != 0x02)
+ cl = bus_space_read_1(chp->cmd_iot,
+ chp->cmd_iohs[wd_cyl_lo], 0);
+ if (cl != 0x02) {
+ WDCDEBUG_PRINT(("%s:%d drive 0 wd_cyl_lo: "
+ "got 0x%x != 0x02\n",
+ wdc != NULL ?
+ wdc->sc_dev.dv_xname : "wdcprobe",
+ chp->ch_channel, cl),
+ DEBUG_PROBE);
ret_value &= ~0x01;
+ }
bus_space_write_1(chp->cmd_iot,
chp->cmd_iohs[wd_cyl_lo], 0, 0x01);
- if (bus_space_read_1(chp->cmd_iot,
- chp->cmd_iohs[wd_cyl_lo], 0) != 0x01)
+ cl = bus_space_read_1(chp->cmd_iot,
+ chp->cmd_iohs[wd_cyl_lo], 0);
+ if (cl != 0x01) {
+ WDCDEBUG_PRINT(("%s:%d drive 0 wd_cyl_lo: "
+ "got 0x%x != 0x01\n",
+ wdc != NULL ?
+ wdc->sc_dev.dv_xname : "wdcprobe",
+ chp->ch_channel, cl),
+ DEBUG_PROBE);
ret_value &= ~0x01;
+ }
bus_space_write_1(chp->cmd_iot,
chp->cmd_iohs[wd_sector], 0, 0x01);
- if (bus_space_read_1(chp->cmd_iot,
- chp->cmd_iohs[wd_sector], 0) != 0x01)
+ cl = bus_space_read_1(chp->cmd_iot,
+ chp->cmd_iohs[wd_sector], 0);
+ if (cl != 0x01) {
+ WDCDEBUG_PRINT(("%s:%d drive 0 wd_sector: "
+ "got 0x%x != 0x01\n",
+ wdc != NULL ?
+ wdc->sc_dev.dv_xname : "wdcprobe",
+ chp->ch_channel, cl),
+ DEBUG_PROBE);
ret_value &= ~0x01;
+ }
bus_space_write_1(chp->cmd_iot,
chp->cmd_iohs[wd_sector], 0, 0x02);
- if (bus_space_read_1(chp->cmd_iot,
- chp->cmd_iohs[wd_sector], 0) != 0x02)
+ cl = bus_space_read_1(chp->cmd_iot,
+ chp->cmd_iohs[wd_sector], 0);
+ if (cl != 0x02) {
+ WDCDEBUG_PRINT(("%s:%d drive 0 wd_sector: "
+ "got 0x%x != 0x02\n",
+ wdc != NULL ?
+ wdc->sc_dev.dv_xname : "wdcprobe",
+ chp->ch_channel, cl),
+ DEBUG_PROBE);
ret_value &= ~0x01;
- if (bus_space_read_1(chp->cmd_iot,
- chp->cmd_iohs[wd_cyl_lo], 0) != 0x01)
+ }
+ cl = bus_space_read_1(chp->cmd_iot,
+ chp->cmd_iohs[wd_cyl_lo], 0);
+ if (cl != 0x01) {
+ WDCDEBUG_PRINT(("%s:%d drive 0 wd_cyl_lo(2): "
+ "got 0x%x != 0x01\n",
+ wdc != NULL ?
+ wdc->sc_dev.dv_xname : "wdcprobe",
+ chp->ch_channel, cl),
+ DEBUG_PROBE);
ret_value &= ~0x01;
+ }
}
/* Register writability test, drive 1. */
if (ret_value & 0x02) {
@@ -554,40 +599,102 @@
0, WDSD_IBM | 0x10);
bus_space_write_1(chp->cmd_iot,
chp->cmd_iohs[wd_cyl_lo], 0, 0x02);
- if (bus_space_read_1(chp->cmd_iot,
- chp->cmd_iohs[wd_cyl_lo], 0) != 0x02)
+ cl = bus_space_read_1(chp->cmd_iot,
+ chp->cmd_iohs[wd_cyl_lo], 0);
+ if (cl != 0x02) {
+ WDCDEBUG_PRINT(("%s:%d drive 1 wd_cyl_lo: "
+ "got 0x%x != 0x02\n",
+ wdc != NULL ?
+ wdc->sc_dev.dv_xname : "wdcprobe",
+ chp->ch_channel, cl),
+ DEBUG_PROBE);
ret_value &= ~0x02;
+ }
bus_space_write_1(chp->cmd_iot,
chp->cmd_iohs[wd_cyl_lo], 0, 0x01);
- if (bus_space_read_1(chp->cmd_iot,
- chp->cmd_iohs[wd_cyl_lo], 0) != 0x01)
+ cl = bus_space_read_1(chp->cmd_iot,
+ chp->cmd_iohs[wd_cyl_lo], 0);
+ if (cl != 0x01) {
+ WDCDEBUG_PRINT(("%s:%d drive 1 wd_cyl_lo: "
+ "got 0x%x != 0x01\n",
+ wdc != NULL ?
+ wdc->sc_dev.dv_xname : "wdcprobe",
+ chp->ch_channel, cl),
+ DEBUG_PROBE);
ret_value &= ~0x02;
+ }
bus_space_write_1(chp->cmd_iot,
chp->cmd_iohs[wd_sector], 0, 0x01);
- if (bus_space_read_1(chp->cmd_iot,
- chp->cmd_iohs[wd_sector], 0) != 0x01)
+ cl = bus_space_read_1(chp->cmd_iot,
+ chp->cmd_iohs[wd_sector], 0);
+ if (cl != 0x01) {
+ WDCDEBUG_PRINT(("%s:%d drive 1 wd_sector: "
+ "got 0x%x != 0x01\n",
+ wdc != NULL ?
+ wdc->sc_dev.dv_xname : "wdcprobe",
+ chp->ch_channel, cl),
+ DEBUG_PROBE);
ret_value &= ~0x02;
+ }
bus_space_write_1(chp->cmd_iot,
chp->cmd_iohs[wd_sector], 0, 0x02);
- if (bus_space_read_1(chp->cmd_iot,
- chp->cmd_iohs[wd_sector], 0) != 0x02)
+ cl = bus_space_read_1(chp->cmd_iot,
+ chp->cmd_iohs[wd_sector], 0);
+ if (cl != 0x02) {
+ WDCDEBUG_PRINT(("%s:%d drive 1 wd_sector: "
+ "got 0x%x != 0x02\n",
+ wdc != NULL ?
+ wdc->sc_dev.dv_xname : "wdcprobe",
+ chp->ch_channel, cl),
+ DEBUG_PROBE);
ret_value &= ~0x02;
- if (bus_space_read_1(chp->cmd_iot,
- chp->cmd_iohs[wd_cyl_lo], 0) != 0x01)
+ }
+ cl = bus_space_read_1(chp->cmd_iot,
+ chp->cmd_iohs[wd_cyl_lo], 0);
+ if (cl != 0x01) {
+ WDCDEBUG_PRINT(("%s:%d drive 1 wd_cyl_lo(2): "
+ "got 0x%x != 0x01\n",
+ wdc != NULL ?
+ wdc->sc_dev.dv_xname : "wdcprobe",
+ chp->ch_channel, cl),
+ DEBUG_PROBE);
ret_value &= ~0x02;
+ }
}
- if (ret_value == 0)
+ if (ret_value == 0) {
+ splx(s);
return 0;
+ }
}
- s = splbio();
+
+ /*
+ * reset bus. Also send an ATAPI_RESET to devices, in case there are
+ * ATAPI device out there which don't react to the bus reset
+ */
+ if (ret_value & 0x01) {
+ if (wdc != NULL && (wdc->cap & WDC_CAPABILITY_SELECT))
+ wdc->select(chp,0);
+ bus_space_write_1(chp->cmd_iot, chp->cmd_iohs[wd_sdh],
+ 0, WDSD_IBM);
+ bus_space_write_1(chp->cmd_iot, chp->cmd_iohs[wd_command], 0,
+ ATAPI_SOFT_RESET);
+ }
+ if (ret_value & 0x02) {
+ if (wdc != NULL && (wdc->cap & WDC_CAPABILITY_SELECT))
+ wdc->select(chp,0);
+ bus_space_write_1(chp->cmd_iot, chp->cmd_iohs[wd_sdh],
+ 0, WDSD_IBM | 0x10);
+ bus_space_write_1(chp->cmd_iot, chp->cmd_iohs[wd_command], 0,
+ ATAPI_SOFT_RESET);
+ }
if (wdc != NULL && (wdc->cap & WDC_CAPABILITY_SELECT))
wdc->select(chp,0);
- /* assert SRST, wait for reset to complete */
bus_space_write_1(chp->cmd_iot, chp->cmd_iohs[wd_sdh], 0, WDSD_IBM);
delay(10); /* 400ns delay */
+ /* assert SRST, wait for reset to complete */
bus_space_write_1(chp->ctl_iot, chp->ctl_ioh, wd_aux_ctlr,
WDCTL_RST | WDCTL_IDS | WDCTL_4BIT);
DELAY(1000);
@@ -926,40 +1033,44 @@
nloop = WDC_RESET_WAIT * hz / 1000;
/* wait for BSY to deassert */
for (timeout = 0; timeout < nloop; timeout++) {
- if (wdc && wdc->cap & WDC_CAPABILITY_SELECT)
- wdc->select(chp,0);
- bus_space_write_1(chp->cmd_iot, chp->cmd_iohs[wd_sdh], 0,
- WDSD_IBM); /* master */
- delay(10);
- st0 = bus_space_read_1(chp->cmd_iot,
- chp->cmd_iohs[wd_status], 0);
+ if ((drv_mask & 0x01) != 0) {
+ if (wdc && wdc->cap & WDC_CAPABILITY_SELECT)
+ wdc->select(chp,0);
+ bus_space_write_1(chp->cmd_iot, chp->cmd_iohs[wd_sdh],
+ 0, WDSD_IBM); /* master */
+ delay(10);
+ st0 = bus_space_read_1(chp->cmd_iot,
+ chp->cmd_iohs[wd_status], 0);
#ifdef WDCDEBUG
- sc0 = bus_space_read_1(chp->cmd_iot,
- chp->cmd_iohs[wd_seccnt], 0);
- sn0 = bus_space_read_1(chp->cmd_iot,
- chp->cmd_iohs[wd_sector], 0);
- cl0 = bus_space_read_1(chp->cmd_iot,
- chp->cmd_iohs[wd_cyl_lo], 0);
- ch0 = bus_space_read_1(chp->cmd_iot,
- chp->cmd_iohs[wd_cyl_hi], 0);
+ sc0 = bus_space_read_1(chp->cmd_iot,
+ chp->cmd_iohs[wd_seccnt], 0);
+ sn0 = bus_space_read_1(chp->cmd_iot,
+ chp->cmd_iohs[wd_sector], 0);
+ cl0 = bus_space_read_1(chp->cmd_iot,
+ chp->cmd_iohs[wd_cyl_lo], 0);
+ ch0 = bus_space_read_1(chp->cmd_iot,
+ chp->cmd_iohs[wd_cyl_hi], 0);
#endif
- if (wdc && wdc->cap & WDC_CAPABILITY_SELECT)
- wdc->select(chp,1);
- bus_space_write_1(chp->cmd_iot, chp->cmd_iohs[wd_sdh], 0,
Home |
Main Index |
Thread Index |
Old Index