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: