Subject: kern/25659: pcmcia IDE drive not recognized because of power-on delay
To: None <gnats-bugs@gnats.NetBSD.org>
From: None <smb@research.att.com>
List: netbsd-bugs
Date: 05/21/2004 15:47:45
>Number:         25659
>Category:       kern
>Synopsis:       pcmcia IDE drive not recognized because of drive's power-on delay
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Fri May 21 19:53:00 UTC 2004
>Closed-Date:
>Last-Modified:
>Originator:     Steven M. Bellovin
>Release:        NetBSD 2.0_BETA
>Organization:
AT&T Labs Research
>Environment:
	
	
System: NetBSD berkshire.research.att.com 2.0_BETA NetBSD 2.0_BETA (BERKSHIRE) #8: Thu May 20 15:11:07 EDT 2004 smb@berkshire.research.att.com:/usr/src/sys/arch/i386/compile/BERKSHIRE i386
Architecture: i386
Machine: i386
>Description:
	When I connected an IDE drive to a PCMCIA controller, the
	controller was recognized, but not the drive.  Debugging output
	showed that both channels were showing BSY for a few seconds;
	apparently, the specs say that that can go on for 31 seconds.
>How-To-Repeat:
	Connect a drive to a controller, plug in, and wait.  If you
	wish, set wdcdebug_mask to 0x10 to see the status codes.
>Fix:
	Enclosed below is a patch to /sys/dev/ic/wdc.c.  It will repeat
	the drive poll a few times -- how many is settable at run-time
	via ddb -- with a one-second delay between tries.

Index: wdc.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/wdc.c,v
retrieving revision 1.172
diff -r1.172 wdc.c
476a477,478
> int wdc_delay_cnt = 5;
> 
484a487
> 	int bcnt;
493,494c496,501
< 		if (wdc != NULL && (wdc->cap & WDC_CAPABILITY_SELECT))
< 			wdc->select(chp,0);
---
> 		/* This loop is a hack; it should be a poll based on
> 		   timer interrupts.  --smb */
> 		bcnt = 0;
> 		do {
> 			if (wdc != NULL && (wdc->cap & WDC_CAPABILITY_SELECT))
> 				wdc->select(chp,0);
496,503c503,507
< 		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);
> 			delay(10);	/* 400ns delay */
> 			st0 = bus_space_read_1(chp->cmd_iot,
> 			    chp->cmd_iohs[wd_status], 0);
505,509c509,524
< 		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 (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 ((st0 & WDCS_BSY) == 0 && (st1 & WDCS_BSY) == 0)
> 				break;
> 			delay(1000000);
> 			WDCDEBUG_PRINT(("%s:%d: 'busy' set (0x%x,0x%x)\n",
> 			    wdc != NULL ? wdc->sc_dev.dv_xname : "wdcprobe",
> 			    chp->ch_channel, st0, st1), DEBUG_PROBE);
> 		} while (bcnt++ < wdc_delay_cnt);
>Release-Note:
>Audit-Trail:
>Unformatted: