Subject: Re: kern/25659
To: None <refling@stanfordalumni.org, smb@research.att.com,>
From: Manuel Bouyer <bouyer@antioche.eu.org>
List: netbsd-bugs
Date: 06/11/2005 12:02:43
--VrqPEDrXMn8OVzN4
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
On Fri, Jun 10, 2005 at 08:12:02AM +0000, John Refling wrote:
> I have a pcmcia ide controller and drive
> package called "Data Disaster Recovery System
> for Notebooks" by ei, an Agate' company. This
> had the same symptom of never seeing the disk,
> until I applied the first patch above, and all
> worked well!
>
> This is in NetBSD/i386 ver 2.02.
Hi,
can you try the attached patches instead (one for 2.0, one for 3.0/current) ?
This should do the same thing as the patch in the PR, without busy-waiting.
--
Manuel Bouyer <bouyer@antioche.eu.org>
NetBSD: 26 ans d'experience feront toujours la difference
--
--VrqPEDrXMn8OVzN4
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename=diff20
Index: wdc.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/wdc.c,v
retrieving revision 1.172.2.7
diff -u -r1.172.2.7 wdc.c
--- wdc.c 17 Sep 2004 04:04:57 -0000 1.172.2.7
+++ wdc.c 10 Jun 2005 19:47:55 -0000
@@ -125,6 +125,13 @@
/* timeout for the control commands */
#define WDC_CTRL_DELAY 10000 /* 10s, for the recall command */
+/*
+ * timeout when waiting for BSY to deassert when probing.
+ * set to 5s. From the standards this could be up to 31, but we can't
+ * wait that much at boot time, and 5s seems to be enouth.
+ */
+#define WDC_PROBE_WAIT 5
+
struct pool wdc_xfer_pool;
#if NWD > 0
@@ -489,6 +496,8 @@
u_int8_t ret_value = 0x03;
u_int8_t drive;
int s;
+ int wdc_probe_count =
+ poll ? (WDC_PROBE_WAIT / WDCDELAY) : (WDC_PROBE_WAIT * hz);
/*
* Sanity check to see if the wdc channel responds at all.
@@ -497,24 +506,28 @@
s = splbio();
if (wdc == NULL ||
(wdc->cap & WDC_CAPABILITY_NO_EXTRA_RESETS) == 0) {
+ while (wdc_probe_count-- > 0) {
- if (wdc != NULL && (wdc->cap & WDC_CAPABILITY_SELECT))
- wdc->select(chp,0);
+ 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);
+ 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);
+ 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);
+ 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 ((st0 & WDCS_BSY) == 0)
+ break;
+ }
WDCDEBUG_PRINT(("%s:%d: before reset, st0=0x%x, st1=0x%x\n",
wdc != NULL ? wdc->sc_dev.dv_xname : "wdcprobe",
--VrqPEDrXMn8OVzN4
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename=diffcurrent
Index: wdc.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/wdc.c,v
retrieving revision 1.222
diff -u -r1.222 wdc.c
--- wdc.c 29 May 2005 22:10:28 -0000 1.222
+++ wdc.c 10 Jun 2005 19:52:25 -0000
@@ -119,6 +119,14 @@
/* timeout for the control commands */
#define WDC_CTRL_DELAY 10000 /* 10s, for the recall command */
+/*
+ * timeout when waiting for BSY to deassert when probing.
+ * set to 5s. From the standards this could be up to 31, but we can't
+ * wait that much at boot time, and 5s seems to be enouth.
+ */
+#define WDC_PROBE_WAIT 5
+
+
#if NWD > 0
extern const struct ata_bustype wdc_ata_bustype; /* in ata_wdc.c */
#else
@@ -403,6 +395,8 @@
u_int8_t ret_value = 0x03;
u_int8_t drive;
int s;
+ int wdc_probe_count =
+ poll ? (WDC_PROBE_WAIT / WDCDELAY) : (WDC_PROBE_WAIT * hz);
/*
* Sanity check to see if the wdc channel responds at all.
@@ -410,24 +404,27 @@
s = splbio();
if ((wdc->cap & WDC_CAPABILITY_NO_EXTRA_RESETS) == 0) {
+ while (wdc_probe_count-- > 0) {
+ if (wdc->select)
+ wdc->select(chp,0);
- if (wdc->select)
- wdc->select(chp,0);
-
- bus_space_write_1(wdr->cmd_iot, wdr->cmd_iohs[wd_sdh], 0,
- WDSD_IBM);
- delay(10); /* 400ns delay */
- st0 = bus_space_read_1(wdr->cmd_iot,
- wdr->cmd_iohs[wd_status], 0);
+ bus_space_write_1(wdr->cmd_iot, wdr->cmd_iohs[wd_sdh],
+ 0, WDSD_IBM);
+ delay(10); /* 400ns delay */
+ st0 = bus_space_read_1(wdr->cmd_iot,
+ wdr->cmd_iohs[wd_status], 0);
- if (wdc->select)
- wdc->select(chp,1);
+ if (wdc->select)
+ wdc->select(chp,1);
- bus_space_write_1(wdr->cmd_iot, wdr->cmd_iohs[wd_sdh], 0,
- WDSD_IBM | 0x10);
- delay(10); /* 400ns delay */
- st1 = bus_space_read_1(wdr->cmd_iot,
- wdr->cmd_iohs[wd_status], 0);
+ bus_space_write_1(wdr->cmd_iot, wdr->cmd_iohs[wd_sdh],
+ 0, WDSD_IBM | 0x10);
+ delay(10); /* 400ns delay */
+ st1 = bus_space_read_1(wdr->cmd_iot,
+ wdr->cmd_iohs[wd_status], 0);
+ if ((st0 & WDCS_BSY) == 0)
+ break;
+ }
ATADEBUG_PRINT(("%s:%d: before reset, st0=0x%x, st1=0x%x\n",
atac->atac_dev.dv_xname,
--VrqPEDrXMn8OVzN4--