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--