2006-09-30 05:06:49

by Joe Jin

[permalink] [raw]
Subject: [PATCH] libata: skip reset on bus not a device

Hi,

On my pc(Dell OptiPlex GX620), while boot up it by 2.6.18, the next
info always report:
===========================================
ata2: port is slow to respond, please be patient
ata2: port failed to respond (30 secs)
ata2: SRST failed (status 0xFF)
ata2: SRST failed (err_mask=0x100)
ata2: softreset failed, retrying in 5 secs
ata2: SRST failed (status 0xFF)
ata2: SRST failed (err_mask=0x100)
ata2: softreset failed, retrying in 5 secs
ata2: SRST failed (status 0xFF)
ata2: SRST failed (err_mask=0x100)
ata2: reset failed, giving up
===========================================

and follow is lspci output:
===========================================
00:00.0 Host bridge: Intel Corporation 945G/GZ/P/PL Express Memory
Controller Hub (rev 02)
Subsystem: Dell: Unknown device 01ad
Flags: bus master, fast devsel, latency 0
Capabilities: <available only to root>
00: 86 80 70 27 06 01 90 20 02 00 00 06 00 00 00 00
10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
20: 00 00 00 00 00 00 00 00 00 00 00 00 28 10 ad 01
30: 00 00 00 00 e0 00 00 00 00 00 00 00 00 00 00 00

00:01.0 PCI bridge: Intel Corporation 945G/GZ/P/PL Express PCI Express
Root Port (rev 02) (prog-if 00 [Normal decode])
Flags: bus master, fast devsel, latency 0
Bus: primary=00, secondary=01, subordinate=01, sec-latency=0
Memory behind bridge: fe900000-fe9fffff
Capabilities: <available only to root>
00: 86 80 71 27 07 05 10 00 02 00 04 06 10 00 01 00
10: 00 00 00 00 00 00 00 00 00 01 01 00 f0 00 00 00
20: 90 fe 90 fe f1 ff 01 00 00 00 00 00 00 00 00 00
30: 00 00 00 00 88 00 00 00 00 00 00 00 0b 01 02 00

00:02.0 VGA compatible controller: Intel Corporation 945G/GZ Express
Integrated Graphics Controller (rev 02) (prog-if 00 [VGA])
Subsystem: Dell: Unknown device 01ad
Flags: bus master, fast devsel, latency 0, IRQ 169
Memory at feb00000 (32-bit, non-prefetchable) [size=512K]
I/O ports at e898 [size=8]
Memory at e0000000 (32-bit, prefetchable) [size=256M]
Memory at feac0000 (32-bit, non-prefetchable) [size=256K]
Capabilities: <available only to root>
00: 86 80 72 27 07 00 90 00 02 00 00 03 00 00 80 00
10: 00 00 b0 fe 99 e8 00 00 08 00 00 e0 00 00 ac fe
20: 00 00 00 00 00 00 00 00 00 00 00 00 28 10 ad 01
30: 00 00 00 00 90 00 00 00 00 00 00 00 0b 01 00 00

00:02.1 Display controller: Intel Corporation 945G/GZ Express
Integrated Graphics Controller (rev 02)
Subsystem: Dell: Unknown device 01ad
Flags: bus master, fast devsel, latency 0
Memory at feb80000 (32-bit, non-prefetchable) [size=512K]
Capabilities: <available only to root>
00: 86 80 76 27 07 00 90 00 02 00 80 03 00 00 80 00
10: 00 00 b8 fe 00 00 00 00 00 00 00 00 00 00 00 00
20: 00 00 00 00 00 00 00 00 00 00 00 00 28 10 ad 01
30: 00 00 00 00 d0 00 00 00 00 00 00 00 00 00 00 00

00:1c.0 PCI bridge: Intel Corporation 82801G (ICH7 Family) PCI Express
Port 1 (rev 01) (prog-if 00 [Normal decode])
Flags: bus master, fast devsel, latency 0
Bus: primary=00, secondary=02, subordinate=02, sec-latency=0
Memory behind bridge: fe800000-fe8fffff
Capabilities: <available only to root>
00: 86 80 d0 27 07 05 10 00 01 00 04 06 10 00 81 00
10: 00 00 00 00 00 00 00 00 00 02 02 00 f0 00 00 20
20: 80 fe 80 fe f1 ff 01 00 00 00 00 00 00 00 00 00
30: 00 00 00 00 40 00 00 00 00 00 00 00 0b 01 02 00

00:1c.1 PCI bridge: Intel Corporation 82801G (ICH7 Family) PCI Express
Port 2 (rev 01) (prog-if 00 [Normal decode])
Flags: bus master, fast devsel, latency 0
Bus: primary=00, secondary=03, subordinate=03, sec-latency=0
Memory behind bridge: fe700000-fe7fffff
Capabilities: <available only to root>
00: 86 80 d2 27 07 05 10 00 01 00 04 06 10 00 81 00
10: 00 00 00 00 00 00 00 00 00 03 03 00 f0 00 00 20
20: 70 fe 70 fe f1 ff 01 00 00 00 00 00 00 00 00 00
30: 00 00 00 00 40 00 00 00 00 00 00 00 0a 02 02 00

00:1d.0 USB Controller: Intel Corporation 82801G (ICH7 Family) USB
UHCI #1 (rev 01) (prog-if 00 [UHCI])
Subsystem: Dell: Unknown device 01ad
Flags: bus master, medium devsel, latency 0, IRQ 233
I/O ports at ff80 [size=32]
00: 86 80 c8 27 05 00 80 02 01 00 03 0c 00 00 80 00
10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
20: 81 ff 00 00 00 00 00 00 00 00 00 00 28 10 ad 01
30: 00 00 00 00 00 00 00 00 00 00 00 00 09 01 00 00

00:1d.1 USB Controller: Intel Corporation 82801G (ICH7 Family) USB
UHCI #2 (rev 01) (prog-if 00 [UHCI])
Subsystem: Dell: Unknown device 01ad
Flags: bus master, medium devsel, latency 0, IRQ 50
I/O ports at ff60 [size=32]
00: 86 80 c9 27 05 00 80 02 01 00 03 0c 00 00 00 00
10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
20: 61 ff 00 00 00 00 00 00 00 00 00 00 28 10 ad 01
30: 00 00 00 00 00 00 00 00 00 00 00 00 05 02 00 00

00:1d.2 USB Controller: Intel Corporation 82801G (ICH7 Family) USB
UHCI #3 (rev 01) (prog-if 00 [UHCI])
Subsystem: Dell: Unknown device 01ad
Flags: bus master, medium devsel, latency 0, IRQ 58
I/O ports at ff40 [size=32]
00: 86 80 ca 27 05 00 80 02 01 00 03 0c 00 00 00 00
10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
20: 41 ff 00 00 00 00 00 00 00 00 00 00 28 10 ad 01
30: 00 00 00 00 00 00 00 00 00 00 00 00 03 03 00 00

00:1d.3 USB Controller: Intel Corporation 82801G (ICH7 Family) USB
UHCI #4 (rev 01) (prog-if 00 [UHCI])
Subsystem: Dell: Unknown device 01ad
Flags: bus master, medium devsel, latency 0, IRQ 225
I/O ports at ff20 [size=32]
00: 86 80 cb 27 05 00 80 02 01 00 03 0c 00 00 00 00
10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
20: 21 ff 00 00 00 00 00 00 00 00 00 00 28 10 ad 01
30: 00 00 00 00 00 00 00 00 00 00 00 00 0a 04 00 00

00:1d.7 USB Controller: Intel Corporation 82801G (ICH7 Family) USB2
EHCI Controller (rev 01) (prog-if 20 [EHCI])
Subsystem: Dell: Unknown device 01ad
Flags: bus master, medium devsel, latency 0, IRQ 233
Memory at ffa80800 (32-bit, non-prefetchable) [size=1K]
Capabilities: <available only to root>
00: 86 80 cc 27 06 01 90 02 01 20 03 0c 00 00 00 00
10: 00 08 a8 ff 00 00 00 00 00 00 00 00 00 00 00 00
20: 00 00 00 00 00 00 00 00 00 00 00 00 28 10 ad 01
30: 00 00 00 00 50 00 00 00 00 00 00 00 09 01 00 00

00:1e.0 PCI bridge: Intel Corporation 82801 PCI Bridge (rev e1)
(prog-if 01 [Subtractive decode])
Flags: bus master, fast devsel, latency 0
Bus: primary=00, secondary=04, subordinate=04, sec-latency=32
Capabilities: <available only to root>
00: 86 80 4e 24 07 01 10 00 e1 01 04 06 00 00 81 00
10: 00 00 00 00 00 00 00 00 00 04 04 20 f0 00 80 22
20: f0 ff 00 00 f1 ff 01 00 00 00 00 00 00 00 00 00
30: 00 00 00 00 50 00 00 00 00 00 00 00 00 00 02 00

00:1e.2 Multimedia audio controller: Intel Corporation 82801G (ICH7
Family) AC'97 Audio Controller (rev 01)
Subsystem: Dell: Unknown device 01ad
Flags: bus master, medium devsel, latency 0, IRQ 225
I/O ports at ec00 [size=256]
I/O ports at e8c0 [size=64]
Memory at feabfa00 (32-bit, non-prefetchable) [size=512]
Memory at feabf900 (32-bit, non-prefetchable) [size=256]
Capabilities: <available only to root>
00: 86 80 de 27 07 00 90 02 01 00 01 04 00 00 00 00
10: 01 ec 00 00 c1 e8 00 00 00 fa ab fe 00 f9 ab fe
20: 00 00 00 00 00 00 00 00 00 00 00 00 28 10 ad 01
30: 00 00 00 00 50 00 00 00 00 00 00 00 0a 01 00 00

00:1f.0 ISA bridge: Intel Corporation 82801GB/GR (ICH7 Family) LPC
Interface Bridge (rev 01)
Flags: bus master, medium devsel, latency 0
Capabilities: <available only to root>
00: 86 80 b8 27 07 01 10 02 01 00 01 06 00 00 80 00
10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
30: 00 00 00 00 e0 00 00 00 00 00 00 00 00 00 00 00

00:1f.1 IDE interface: Intel Corporation 82801G (ICH7 Family) IDE
Controller (rev 01) (prog-if 8a [Master SecP PriP])
Subsystem: Dell: Unknown device 01ad
Flags: bus master, medium devsel, latency 0, IRQ 169
I/O ports at <ignored>
I/O ports at <ignored>
I/O ports at <ignored>
I/O ports at <ignored>
I/O ports at ffa0 [size=16]
00: 86 80 df 27 05 00 88 02 01 8a 01 01 00 00 00 00
10: f1 01 00 00 f5 03 00 00 71 01 00 00 75 03 00 00
20: a1 ff 00 00 00 00 00 00 00 00 00 00 28 10 ad 01
30: 00 00 00 00 00 00 00 00 00 00 00 00 0b 01 00 00

00:1f.2 IDE interface: Intel Corporation 82801GB/GR/GH (ICH7 Family)
Serial ATA Storage Controller IDE (rev 01) (prog-if 8f [Master SecP
SecO PriP PriO])
Subsystem: Dell: Unknown device 01ad
Flags: bus master, 66Mhz, medium devsel, latency 0, IRQ 217
I/O ports at fe00 [size=8]
I/O ports at fe10 [size=4]
I/O ports at fe20 [size=8]
I/O ports at fe30 [size=4]
I/O ports at fea0 [size=16]
Capabilities: <available only to root>
00: 86 80 c0 27 07 00 b0 02 01 8f 01 01 00 00 00 00
10: 01 fe 00 00 11 fe 00 00 21 fe 00 00 31 fe 00 00
20: a1 fe 00 00 00 00 00 00 00 00 00 00 28 10 ad 01
30: 00 00 00 00 70 00 00 00 00 00 00 00 05 03 00 00

00:1f.3 SMBus: Intel Corporation 82801G (ICH7 Family) SMBus Controller (rev 01)
Subsystem: Dell: Unknown device 01ad
Flags: medium devsel, IRQ 177
I/O ports at e8a0 [size=32]
00: 86 80 da 27 01 01 80 02 01 00 05 0c 00 00 00 00
10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
20: a1 e8 00 00 00 00 00 00 00 00 00 00 28 10 ad 01
30: 00 00 00 00 00 00 00 00 00 00 00 00 0a 02 00 00

02:00.0 Ethernet controller: Broadcom Corporation NetXtreme BCM5751
Gigabit Ethernet PCI Express (rev 01)
Subsystem: Dell Optiplex GX620
Flags: bus master, fast devsel, latency 0, IRQ 169
Memory at fe8f0000 (64-bit, non-prefetchable) [size=64K]
Capabilities: <available only to root>
00: e4 14 77 16 06 00 10 00 01 00 00 02 10 00 00 00
10: 04 00 8f fe 00 00 00 00 00 00 00 00 00 00 00 00
20: 00 00 00 00 00 00 00 00 07 00 00 00 28 10 ad 01
30: 00 00 00 00 48 00 00 00 00 00 00 00 0b 01 00 00
===========================================

through traced the code, and found which caused it:
at scsi_eh_[port_no] kernel thread, it should reset the bus, before reset it,
it never check it if have a device. if it should skip it?
thanks

attachment is the patch

--
Regards,
Joe Jin


Attachments:
(No filename) (10.13 kB)
libata-core.patch (1.47 kB)
Download all attachments

2006-09-30 14:14:49

by Tejun Heo

[permalink] [raw]
Subject: Re: [PATCH] libata: skip reset on bus not a device

diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
index 427b73a..c8a1bc6 100644
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -2271,11 +2271,14 @@ static inline void ata_tf_to_host(struct
* Sleep until ATA Status register bit BSY clears,
* or a timeout occurs.
*
- * LOCKING: None.
+ * LOCKING:
+ * Kernel thread context (may sleep).
+ *
+ * RETURNS:
+ * 0 on success, -errno otherwise.
*/
-
-unsigned int ata_busy_sleep (struct ata_port *ap,
- unsigned long tmout_pat, unsigned long tmout)
+int ata_busy_sleep(struct ata_port *ap,
+ unsigned long tmout_pat, unsigned long tmout)
{
unsigned long timer_start, timeout;
u8 status;
@@ -2283,25 +2286,30 @@ unsigned int ata_busy_sleep (struct ata_
status = ata_busy_wait(ap, ATA_BUSY, 300);
timer_start = jiffies;
timeout = timer_start + tmout_pat;
- while ((status & ATA_BUSY) && (time_before(jiffies, timeout))) {
+ while (status != 0xff && (status & ATA_BUSY) &&
+ time_before(jiffies, timeout)) {
msleep(50);
status = ata_busy_wait(ap, ATA_BUSY, 3);
}

- if (status & ATA_BUSY)
+ if (status != 0xff && (status & ATA_BUSY))
ata_port_printk(ap, KERN_WARNING,
"port is slow to respond, please be patient\n");

timeout = timer_start + tmout;
- while ((status & ATA_BUSY) && (time_before(jiffies, timeout))) {
+ while (status != 0xff && (status & ATA_BUSY) &&
+ time_before(jiffies, timeout)) {
msleep(50);
status = ata_chk_status(ap);
}

+ if (status == 0xff)
+ return -ENODEV;
+
if (status & ATA_BUSY) {
ata_port_printk(ap, KERN_ERR, "port failed to respond "
"(%lu secs)\n", tmout / HZ);
- return 1;
+ return -EBUSY;
}

return 0;
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 66c3100..eb7d90f 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -702,9 +702,8 @@ extern int ata_host_set_suspend(struct a
pm_message_t mesg);
extern void ata_host_set_resume(struct ata_host_set *host_set);
extern int ata_ratelimit(void);
-extern unsigned int ata_busy_sleep(struct ata_port *ap,
- unsigned long timeout_pat,
- unsigned long timeout);
+extern int ata_busy_sleep(struct ata_port *ap,
+ unsigned long timeout_pat, unsigned long timeout);
extern void ata_port_queue_task(struct ata_port *ap, void (*fn)(void *),
void *data, unsigned long delay);
extern u32 ata_wait_register(void __iomem *reg, u32 mask, u32 val,
@@ -1019,7 +1018,7 @@ static inline u8 ata_busy_wait(struct at
udelay(10);
status = ata_chk_status(ap);
max--;
- } while ((status & bits) && (max > 0));
+ } while (status != 0xff && (status & bits) && (max > 0));

return status;
}
@@ -1040,7 +1039,7 @@ static inline u8 ata_wait_idle(struct at
{
u8 status = ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 1000);

- if (status & (ATA_BUSY | ATA_DRQ)) {
+ if (status != 0xff && (status & (ATA_BUSY | ATA_DRQ))) {
unsigned long l = ap->ioaddr.status_addr;
if (ata_msg_warn(ap))
printk(KERN_WARNING "ATA: abnormal status 0x%X on port 0x%lX\n",


Attachments:
patch (2.99 kB)

2006-10-01 01:49:10

by Joe Jin

[permalink] [raw]
Subject: Re: [PATCH] libata: skip reset on bus not a device

> # lspci -nvvvxxx -s 00:1f.

00:1f.0 Class 0601: 8086:27b8 (rev 01)
Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop-
ParErr- Stepping- SERR+ FastB2B-
Status: Cap+ 66Mhz- UDF- FastB2B- ParErr- DEVSEL=medium
>TAbort- <TAbort- <MAbort- >SERR- <PERR-
Latency: 0
Capabilities: <available only to root>
00: 86 80 b8 27 07 01 10 02 01 00 01 06 00 00 80 00
10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
30: 00 00 00 00 e0 00 00 00 00 00 00 00 00 00 00 00

00:1f.1 Class 0101: 8086:27df (rev 01) (prog-if 8a [Master SecP PriP])
Subsystem: 1028:01ad
Control: I/O+ Mem- BusMaster+ SpecCycle- MemWINV- VGASnoop-
ParErr- Stepping- SERR- FastB2B-
Status: Cap- 66Mhz- UDF- FastB2B+ ParErr- DEVSEL=medium
>TAbort- <TAbort- <MAbort- >SERR- <PERR-
Latency: 0
Interrupt: pin A routed to IRQ 169
Region 0: I/O ports at <ignored>
Region 1: I/O ports at <ignored>
Region 2: I/O ports at <ignored>
Region 3: I/O ports at <ignored>
Region 4: I/O ports at ffa0 [size=16]
00: 86 80 df 27 05 00 88 02 01 8a 01 01 00 00 00 00
10: f1 01 00 00 f5 03 00 00 71 01 00 00 75 03 00 00
20: a1 ff 00 00 00 00 00 00 00 00 00 00 28 10 ad 01
30: 00 00 00 00 00 00 00 00 00 00 00 00 0b 01 00 00

00:1f.2 Class 0101: 8086:27c0 (rev 01) (prog-if 8f [Master SecP SecO PriP PriO])
Subsystem: 1028:01ad
Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop-
ParErr- Stepping- SERR- FastB2B-
Status: Cap+ 66Mhz+ UDF- FastB2B+ ParErr- DEVSEL=medium
>TAbort- <TAbort- <MAbort- >SERR- <PERR-
Latency: 0
Interrupt: pin C routed to IRQ 217
Region 0: I/O ports at fe00 [size=8]
Region 1: I/O ports at fe10 [size=4]
Region 2: I/O ports at fe20 [size=8]
Region 3: I/O ports at fe30 [size=4]
Region 4: I/O ports at fea0 [size=16]
Capabilities: <available only to root>
00: 86 80 c0 27 07 00 b0 02 01 8f 01 01 00 00 00 00
10: 01 fe 00 00 11 fe 00 00 21 fe 00 00 31 fe 00 00
20: a1 fe 00 00 00 00 00 00 00 00 00 00 28 10 ad 01
30: 00 00 00 00 70 00 00 00 00 00 00 00 05 03 00 00

00:1f.3 Class 0c05: 8086:27da (rev 01)
Subsystem: 1028:01ad
Control: I/O+ Mem- BusMaster- SpecCycle- MemWINV- VGASnoop-
ParErr- Stepping- SERR+ FastB2B-
Status: Cap- 66Mhz- UDF- FastB2B+ ParErr- DEVSEL=medium
>TAbort- <TAbort- <MAbort- >SERR- <PERR-
Interrupt: pin B routed to IRQ 177
Region 4: I/O ports at e8a0 [size=32]
00: 86 80 da 27 01 01 80 02 01 00 05 0c 00 00 00 00
10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
20: a1 e8 00 00 00 00 00 00 00 00 00 00 28 10 ad 01
30: 00 00 00 00 00 00 00 00 00 00 00 00 0a 02 00 00

>
> Hmmm... Not really. The controller shouldn't report BSY for empty
> channel. There's a notable exception where PATA pins aren't properly
> pulled resulting in 0xff status on empty channels. IDE handles the case
> specially but libata doesn't yet. Can you try the attached patch?
>

it still occured after apply the patch :(

-Joe

2006-10-09 03:06:56

by Tejun Heo

[permalink] [raw]
Subject: Re: [PATCH] libata: skip reset on bus not a device

Joe Jin wrote:
> it still occured after apply the patch :(

SRST failure would have still occurred but 30sec timeout should have
gone. Can you post full dmesg?

Also, please test the patch in the following mail. You can use either
git or download the full kernel tarball to get the modified kernel.

http://article.gmane.org/gmane.linux.ide/13284

Thanks.

--
tejun

2006-10-09 06:54:33

by Joe Jin

[permalink] [raw]
Subject: Re: [PATCH] libata: skip reset on bus not a device

> SRST failure would have still occurred but 30sec timeout should have
> gone. Can you post full dmesg?

Yes it is.
attachment is the output of dmesg

>
> Also, please test the patch in the following mail. You can use either
> git or download the full kernel tarball to get the modified kernel.
>

Did the pathc against 2.6.19-rc1?
I have test it, but it have not any change and timeout also appeared :(

-Joe


Attachments:
(No filename) (412.00 B)
dmesg.tar.gz (7.72 kB)
Download all attachments

2006-10-09 07:00:47

by Tejun Heo

[permalink] [raw]
Subject: Re: [PATCH] libata: skip reset on bus not a device

Joe Jin wrote:
>> SRST failure would have still occurred but 30sec timeout should have
>> gone. Can you post full dmesg?
>
> Yes it is.
> attachment is the output of dmesg

Great.

>> Also, please test the patch in the following mail. You can use either
>> git or download the full kernel tarball to get the modified kernel.
>>
>
> Did the pathc against 2.6.19-rc1?
> I have test it, but it have not any change and timeout also appeared :(

It's against libata development tree. So, you downloaded the tar.gz and
tested it?

Thanks.

--
tejun

2006-10-09 07:07:10

by Tejun Heo

[permalink] [raw]
Subject: Re: [PATCH] libata: skip reset on bus not a device

On Mon, Oct 09, 2006 at 04:00:33PM +0900, Tejun Heo wrote:
> Joe Jin wrote:
> >>SRST failure would have still occurred but 30sec timeout should have
> >>gone. Can you post full dmesg?
> >
> >Yes it is.
> >attachment is the output of dmesg
>
> Great.
>
> >>Also, please test the patch in the following mail. You can use either
> >>git or download the full kernel tarball to get the modified kernel.
> >>
> >
> >Did the pathc against 2.6.19-rc1?
> >I have test it, but it have not any change and timeout also appeared :(
>
> It's against libata development tree. So, you downloaded the tar.gz and
> tested it?

And, one more thing to try. The following patch should fix your
problem. It's against v2.6.18.

diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
index 427b73a..3bc7f57 100644
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -2271,11 +2271,14 @@ static inline void ata_tf_to_host(struct
* Sleep until ATA Status register bit BSY clears,
* or a timeout occurs.
*
- * LOCKING: None.
+ * LOCKING:
+ * Kernel thread context (may sleep).
+ *
+ * RETURNS:
+ * 0 on success, -errno otherwise.
*/
-
-unsigned int ata_busy_sleep (struct ata_port *ap,
- unsigned long tmout_pat, unsigned long tmout)
+int ata_busy_sleep(struct ata_port *ap,
+ unsigned long tmout_pat, unsigned long tmout)
{
unsigned long timer_start, timeout;
u8 status;
@@ -2283,25 +2286,30 @@ unsigned int ata_busy_sleep (struct ata_
status = ata_busy_wait(ap, ATA_BUSY, 300);
timer_start = jiffies;
timeout = timer_start + tmout_pat;
- while ((status & ATA_BUSY) && (time_before(jiffies, timeout))) {
+ while (status != 0xff && (status & ATA_BUSY) &&
+ time_before(jiffies, timeout)) {
msleep(50);
status = ata_busy_wait(ap, ATA_BUSY, 3);
}

- if (status & ATA_BUSY)
+ if (status != 0xff && (status & ATA_BUSY))
ata_port_printk(ap, KERN_WARNING,
"port is slow to respond, please be patient\n");

timeout = timer_start + tmout;
- while ((status & ATA_BUSY) && (time_before(jiffies, timeout))) {
+ while (status != 0xff && (status & ATA_BUSY) &&
+ time_before(jiffies, timeout)) {
msleep(50);
status = ata_chk_status(ap);
}

+ if (status == 0xff)
+ return -ENODEV;
+
if (status & ATA_BUSY) {
ata_port_printk(ap, KERN_ERR, "port failed to respond "
"(%lu secs)\n", tmout / HZ);
- return 1;
+ return -EBUSY;
}

return 0;
@@ -2392,10 +2400,8 @@ static unsigned int ata_bus_softreset(st
* the bus shows 0xFF because the odd clown forgets the D7
* pulldown resistor.
*/
- if (ata_check_status(ap) == 0xFF) {
- ata_port_printk(ap, KERN_ERR, "SRST failed (status 0xFF)\n");
- return AC_ERR_OTHER;
- }
+ if (ata_check_status(ap) == 0xFF)
+ return 0;

ata_bus_post_reset(ap, devmask);

diff --git a/include/linux/libata.h b/include/linux/libata.h
index 66c3100..eb7d90f 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -702,9 +702,8 @@ extern int ata_host_set_suspend(struct a
pm_message_t mesg);
extern void ata_host_set_resume(struct ata_host_set *host_set);
extern int ata_ratelimit(void);
-extern unsigned int ata_busy_sleep(struct ata_port *ap,
- unsigned long timeout_pat,
- unsigned long timeout);
+extern int ata_busy_sleep(struct ata_port *ap,
+ unsigned long timeout_pat, unsigned long timeout);
extern void ata_port_queue_task(struct ata_port *ap, void (*fn)(void *),
void *data, unsigned long delay);
extern u32 ata_wait_register(void __iomem *reg, u32 mask, u32 val,
@@ -1019,7 +1018,7 @@ static inline u8 ata_busy_wait(struct at
udelay(10);
status = ata_chk_status(ap);
max--;
- } while ((status & bits) && (max > 0));
+ } while (status != 0xff && (status & bits) && (max > 0));

return status;
}
@@ -1040,7 +1039,7 @@ static inline u8 ata_wait_idle(struct at
{
u8 status = ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 1000);

- if (status & (ATA_BUSY | ATA_DRQ)) {
+ if (status != 0xff && (status & (ATA_BUSY | ATA_DRQ))) {
unsigned long l = ap->ioaddr.status_addr;
if (ata_msg_warn(ap))
printk(KERN_WARNING "ATA: abnormal status 0x%X on port 0x%lX\n",

2006-10-09 07:44:35

by Joe Jin

[permalink] [raw]
Subject: Re: [PATCH] libata: skip reset on bus not a device

> > It's against libata development tree. So, you downloaded the tar.gz and
> > tested it?

no, but at latest kernel 2.6.19-rc1 use the same tree as you said, and
it also can worked


>
> And, one more thing to try. The following patch should fix your
> problem. It's against v2.6.18.
>

while applied the patch, error info gone :)

A question: if the status register return 0xFF means the device not exist?
why not use ata_devchk()?

thanks

-Joe

2006-10-09 07:57:12

by Tejun Heo

[permalink] [raw]
Subject: Re: [PATCH] libata: skip reset on bus not a device

Joe Jin wrote:
>> > It's against libata development tree. So, you downloaded the tar.gz
>> and
>> > tested it?
>
> no, but at latest kernel 2.6.19-rc1 use the same tree as you said, and
> it also can worked

I see. It's irrelevant anyway.

>> And, one more thing to try. The following patch should fix your
>> problem. It's against v2.6.18.
>>
>
> while applied the patch, error info gone :)
>
> A question: if the status register return 0xFF means the device not exist?
> why not use ata_devchk()?

Many SATA controllers emulate TF registers and pass devchk even when no
device is attached. I don't know whether the two conditions can happen
together - 0xFF status is usually seen on PATA. Anyways, it's more
reliable to test 0xFF. Also, that's what driver/ide has been doing for
a long long time and we don't want to deviate from it if possible.

--
tejun

2006-10-17 23:13:24

by Jesse Brandeburg

[permalink] [raw]
Subject: Re: [PATCH] libata: skip reset on bus not a device

On 10/9/06, Tejun Heo <[email protected]> wrote:
> On Mon, Oct 09, 2006 at 04:00:33PM +0900, Tejun Heo wrote:
> > Joe Jin wrote:
> > >>SRST failure would have still occurred but 30sec timeout should have
> > >>gone. Can you post full dmesg?
> > >
> > >Yes it is.
> > >attachment is the output of dmesg
> >
> > Great.
> >
> > >>Also, please test the patch in the following mail. You can use either
> > >>git or download the full kernel tarball to get the modified kernel.
> > >>
> > >
> > >Did the pathc against 2.6.19-rc1?
> > >I have test it, but it have not any change and timeout also appeared :(
> >
> > It's against libata development tree. So, you downloaded the tar.gz and
> > tested it?
>
> And, one more thing to try. The following patch should fix your
> problem. It's against v2.6.18.
>
> diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
> index 427b73a..3bc7f57 100644
> --- a/drivers/scsi/libata-core.c
> +++ b/drivers/scsi/libata-core.c
> @@ -2271,11 +2271,14 @@ static inline void ata_tf_to_host(struct
> * Sleep until ATA Status register bit BSY clears,
> * or a timeout occurs.
> *
> - * LOCKING: None.
> + * LOCKING:
> + * Kernel thread context (may sleep).
> + *
> + * RETURNS:
> + * 0 on success, -errno otherwise.
> */
> -
> -unsigned int ata_busy_sleep (struct ata_port *ap,
> - unsigned long tmout_pat, unsigned long tmout)
> +int ata_busy_sleep(struct ata_port *ap,
> + unsigned long tmout_pat, unsigned long tmout)
> {
> unsigned long timer_start, timeout;
> u8 status;
> @@ -2283,25 +2286,30 @@ unsigned int ata_busy_sleep (struct ata_
> status = ata_busy_wait(ap, ATA_BUSY, 300);
> timer_start = jiffies;
> timeout = timer_start + tmout_pat;
> - while ((status & ATA_BUSY) && (time_before(jiffies, timeout))) {
> + while (status != 0xff && (status & ATA_BUSY) &&
> + time_before(jiffies, timeout)) {
> msleep(50);
> status = ata_busy_wait(ap, ATA_BUSY, 3);
> }
>
> - if (status & ATA_BUSY)
> + if (status != 0xff && (status & ATA_BUSY))
> ata_port_printk(ap, KERN_WARNING,
> "port is slow to respond, please be patient\n");
>
> timeout = timer_start + tmout;
> - while ((status & ATA_BUSY) && (time_before(jiffies, timeout))) {
> + while (status != 0xff && (status & ATA_BUSY) &&
> + time_before(jiffies, timeout)) {
> msleep(50);
> status = ata_chk_status(ap);
> }
>
> + if (status == 0xff)
> + return -ENODEV;
> +
> if (status & ATA_BUSY) {
> ata_port_printk(ap, KERN_ERR, "port failed to respond "
> "(%lu secs)\n", tmout / HZ);
> - return 1;
> + return -EBUSY;
> }
>
> return 0;
> @@ -2392,10 +2400,8 @@ static unsigned int ata_bus_softreset(st
> * the bus shows 0xFF because the odd clown forgets the D7
> * pulldown resistor.
> */
> - if (ata_check_status(ap) == 0xFF) {
> - ata_port_printk(ap, KERN_ERR, "SRST failed (status 0xFF)\n");
> - return AC_ERR_OTHER;
> - }
> + if (ata_check_status(ap) == 0xFF)
> + return 0;
>
> ata_bus_post_reset(ap, devmask);
>
> diff --git a/include/linux/libata.h b/include/linux/libata.h
> index 66c3100..eb7d90f 100644
> --- a/include/linux/libata.h
> +++ b/include/linux/libata.h
> @@ -702,9 +702,8 @@ extern int ata_host_set_suspend(struct a
> pm_message_t mesg);
> extern void ata_host_set_resume(struct ata_host_set *host_set);
> extern int ata_ratelimit(void);
> -extern unsigned int ata_busy_sleep(struct ata_port *ap,
> - unsigned long timeout_pat,
> - unsigned long timeout);
> +extern int ata_busy_sleep(struct ata_port *ap,
> + unsigned long timeout_pat, unsigned long timeout);
> extern void ata_port_queue_task(struct ata_port *ap, void (*fn)(void *),
> void *data, unsigned long delay);
> extern u32 ata_wait_register(void __iomem *reg, u32 mask, u32 val,
> @@ -1019,7 +1018,7 @@ static inline u8 ata_busy_wait(struct at
> udelay(10);
> status = ata_chk_status(ap);
> max--;
> - } while ((status & bits) && (max > 0));
> + } while (status != 0xff && (status & bits) && (max > 0));
>
> return status;
> }
> @@ -1040,7 +1039,7 @@ static inline u8 ata_wait_idle(struct at
> {
> u8 status = ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 1000);
>
> - if (status & (ATA_BUSY | ATA_DRQ)) {
> + if (status != 0xff && (status & (ATA_BUSY | ATA_DRQ))) {
> unsigned long l = ap->ioaddr.status_addr;
> if (ata_msg_warn(ap))
> printk(KERN_WARNING "ATA: abnormal status 0x%X on port 0x%lX\n",
>
> -

Is this patch going to go upstream? I've been testing 2.6.18 on a
couple different systems and seen the same issue. I haven't tested
the patch yet.

2006-10-18 16:24:49

by Tejun Heo

[permalink] [raw]
Subject: Re: [PATCH] libata: skip reset on bus not a device

Jesse Brandeburg wrote:
> Is this patch going to go upstream? I've been testing 2.6.18 on a
> couple different systems and seen the same issue. I haven't tested
> the patch yet.

The patch is pending review.

http://thread.gmane.org/gmane.linux.ide/13408/focus=13439

--
tejun