NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
kern/41926: [PATCH] probe failed for SATA drives in wdc_sataprobe()
>Number: 41926
>Category: kern
>Synopsis: [PATCH] probe failed for SATA drives in wdc_sataprobe()
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: kern-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Sun Aug 23 13:40:00 +0000 2009
>Originator: FUKAUMI Naoki
>Release: NetBSD 5.0_STABLE
>Organization:
FUKAUMI Naoki
>Environment:
Architecture: x86_64 / arm
Machine: amd64 / evbarm
>Description:
I found some SATA drives are not properly probed with some SATA
controllers. I have two machines, one has
> viaide1: NVIDIA nForce4 Serial ATA Controller (rev. 0xf3)
with
> cd0 at atapibus0 drive 0: <Optiarc DVD RW AD-7200S, , 1.21> cdrom
removable
and another has
> mvsata0 at gt0 offset 0x80000-0x87fff irq 29: Marvell Serial-ATA Host
Controller (SATAHC)
with
> wd0 at atabus1 drive 0: <ITGO Powered by www.polotek.cn>
(Marvell MV88F5182 SoC with 4GB SDHC Card via SD-SATA converter)
without patch, I get following error
> viaide1 channel 0: reset failed for drive 0
and these SATA drives are not attached.
another SATA drives are properly attached without patch.
>How-To-Repeat:
see above.
>Fix:
patch attached.
I replaced bus_space_{read,write}_2() with *_1(). I think it
should be OK...
Index: sys/dev/ic/wdc.c
===================================================================
RCS file: /home/fun/cvsroot/NetBSD/src/sys/dev/ic/wdc.c,v
retrieving revision 1.255.4.1
diff -u -p -r1.255.4.1 wdc.c
--- sys/dev/ic/wdc.c 20 Nov 2008 02:45:36 -0000 1.255.4.1
+++ sys/dev/ic/wdc.c 17 Aug 2009 18:16:31 -0000
@@ -209,7 +209,7 @@ void
wdc_sataprobe(struct ata_channel *chp)
{
struct wdc_regs *wdr = CHAN_TO_WDC_REGS(chp);
- uint16_t scnt, sn, cl, ch;
+ uint8_t st = 0, sc, sn, cl, ch;
int i, s;
/* XXX This should be done by other code. */
@@ -222,23 +222,34 @@ wdc_sataprobe(struct ata_channel *chp)
switch (sata_reset_interface(chp, wdr->sata_iot, wdr->sata_control,
wdr->sata_status)) {
case SStatus_DET_DEV:
- bus_space_write_1(wdr->cmd_iot, wdr->cmd_iohs[wd_sdh], 0,
- WDSD_IBM);
- delay(10); /* 400ns delay */
- scnt = bus_space_read_2(wdr->cmd_iot,
+ /* wait 5s for BSY to clear */
+ for (i = 0; i < WDC_PROBE_WAIT * hz; i++) {
+ bus_space_write_1(wdr->cmd_iot,
+ wdr->cmd_iohs[wd_sdh], 0, WDSD_IBM);
+ delay(10); /* 400ns delay */
+ st = bus_space_read_1(wdr->cmd_iot,
+ wdr->cmd_iohs[wd_status], 0);
+ if ((st & WDCS_BSY) == 0)
+ break;
+ tsleep(&chp, PRIBIO, "sataprb", 1);
+ }
+ if (i == WDC_PROBE_WAIT * hz)
+ aprint_error_dev(chp->ch_atac->atac_dev,
+ "BSY never cleared, status 0x%02x\n", st);
+ sc = bus_space_read_1(wdr->cmd_iot,
wdr->cmd_iohs[wd_seccnt], 0);
- sn = bus_space_read_2(wdr->cmd_iot,
+ sn = bus_space_read_1(wdr->cmd_iot,
wdr->cmd_iohs[wd_sector], 0);
- cl = bus_space_read_2(wdr->cmd_iot,
+ cl = bus_space_read_1(wdr->cmd_iot,
wdr->cmd_iohs[wd_cyl_lo], 0);
- ch = bus_space_read_2(wdr->cmd_iot,
+ ch = bus_space_read_1(wdr->cmd_iot,
wdr->cmd_iohs[wd_cyl_hi], 0);
- ATADEBUG_PRINT(("%s: port %d: scnt=0x%x sn=0x%x "
+ ATADEBUG_PRINT(("%s: port %d: sc=0x%x sn=0x%x "
"cl=0x%x ch=0x%x\n",
device_xname(chp->ch_atac->atac_dev), chp->ch_channel,
- scnt, sn, cl, ch), DEBUG_PROBE);
+ sc, sn, cl, ch), DEBUG_PROBE);
/*
- * scnt and sn are supposed to be 0x1 for ATAPI, but in some
+ * sc and sn are supposed to be 0x1 for ATAPI, but in some
* cases we get wrong values here, so ignore it.
*/
s = splbio();
Home |
Main Index |
Thread Index |
Old Index