* [PATCH #upstream-fixes] libata: handle SEMB signature better
@ 2009-04-14 10:35 Tejun Heo
2009-04-14 12:12 ` Jeff Garzik
0 siblings, 1 reply; 7+ messages in thread
From: Tejun Heo @ 2009-04-14 10:35 UTC (permalink / raw)
To: Jeff Garzik, IDE/ATA development list, David Haun, liw,
jmcarranza
WDC WD1600JS-62MHB5 successfully hits the window between ATA/ATAPI-7
and Serial ATA II standards and reports 3c/c3 signature which now is
assigned to SEMB. Make ata_dev_classify() report ATA_DEV_SEMB on the
sig and let ata_dev_read_id() work around it by trying IDENTIFY once.
This fixes bko#11579.
Signed-off-by: Tejun Heo <tj@kernel.org>
Reported-by: David Haun <drhaun88@gmail.com>
Reported-by: Lars Wirzenius <liw@liw.fi>
Reported-by: Juan Manuel <jmcarranza@gmail.com>
--
drivers/ata/libata-core.c | 19 +++++++++++++++++--
1 file changed, 17 insertions(+), 2 deletions(-)
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 065507c..8f7d217 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -1231,6 +1231,9 @@ unsigned int ata_dev_classify(const struct ata_taskfile *tf)
*
* We follow the current spec and consider that 0x69/0x96
* identifies a port multiplier and 0x3c/0xc3 a SEMB device.
+ * Unfortunately, WDC WD1600JS-62MHB5 (a hard drive) reports
+ * SEMB signature. This is worked around in
+ * ata_dev_read_id().
*/
if ((tf->lbam == 0) && (tf->lbah == 0)) {
DPRINTK("found ATA device by sig\n");
@@ -1248,8 +1251,8 @@ unsigned int ata_dev_classify(const struct ata_taskfile *tf)
}
if ((tf->lbam == 0x3c) && (tf->lbah == 0xc3)) {
- printk(KERN_INFO "ata: SEMB device ignored\n");
- return ATA_DEV_SEMB_UNSUP; /* not yet */
+ DPRINTK("found SEMB device by sig (could be ATA device)\n");
+ return ATA_DEV_SEMB;
}
DPRINTK("unknown device\n");
@@ -2080,6 +2083,7 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class,
struct ata_taskfile tf;
unsigned int err_mask = 0;
const char *reason;
+ bool is_semb = class == ATA_DEV_SEMB;
int may_fallback = 1, tried_spinup = 0;
int rc;
@@ -2090,6 +2094,8 @@ retry:
ata_tf_init(dev, &tf);
switch (class) {
+ case ATA_DEV_SEMB:
+ class = ATA_DEV_ATA; /* some hard drives report SEMB sig */
case ATA_DEV_ATA:
tf.command = ATA_CMD_ID_ATA;
break;
@@ -2119,6 +2125,7 @@ retry:
else
err_mask = ata_do_dev_read_id(dev, &tf, id);
+ err_mask |= AC_ERR_DEV;
if (err_mask) {
if (err_mask & AC_ERR_NODEV_HINT) {
ata_dev_printk(dev, KERN_DEBUG,
@@ -2126,6 +2133,14 @@ retry:
return -ENOENT;
}
+ if (is_semb) {
+ ata_dev_printk(dev, KERN_INFO, "IDENTIFY failed on "
+ "device w/ SEMB sig, disabled\n");
+ /* SEMB is not supported yet */
+ *p_class = ATA_DEV_SEMB_UNSUP;
+ return 0;
+ }
+
if ((err_mask == AC_ERR_DEV) && (tf.feature & ATA_ABORTED)) {
/* Device or controller might have reported
* the wrong device class. Give a shot at the
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH #upstream-fixes] libata: handle SEMB signature better
2009-04-14 10:35 [PATCH #upstream-fixes] libata: handle SEMB signature better Tejun Heo
@ 2009-04-14 12:12 ` Jeff Garzik
2009-04-14 21:03 ` Tejun Heo
0 siblings, 1 reply; 7+ messages in thread
From: Jeff Garzik @ 2009-04-14 12:12 UTC (permalink / raw)
To: Tejun Heo; +Cc: IDE/ATA development list, David Haun, liw, jmcarranza
Tejun Heo wrote:
> WDC WD1600JS-62MHB5 successfully hits the window between ATA/ATAPI-7
> and Serial ATA II standards and reports 3c/c3 signature which now is
> assigned to SEMB. Make ata_dev_classify() report ATA_DEV_SEMB on the
> sig and let ata_dev_read_id() work around it by trying IDENTIFY once.
>
> This fixes bko#11579.
>
> Signed-off-by: Tejun Heo <tj@kernel.org>
> Reported-by: David Haun <drhaun88@gmail.com>
> Reported-by: Lars Wirzenius <liw@liw.fi>
> Reported-by: Juan Manuel <jmcarranza@gmail.com>
> --
> drivers/ata/libata-core.c | 19 +++++++++++++++++--
> 1 file changed, 17 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
> index 065507c..8f7d217 100644
> --- a/drivers/ata/libata-core.c
> +++ b/drivers/ata/libata-core.c
> @@ -1231,6 +1231,9 @@ unsigned int ata_dev_classify(const struct ata_taskfile *tf)
> *
> * We follow the current spec and consider that 0x69/0x96
> * identifies a port multiplier and 0x3c/0xc3 a SEMB device.
> + * Unfortunately, WDC WD1600JS-62MHB5 (a hard drive) reports
> + * SEMB signature. This is worked around in
> + * ata_dev_read_id().
> */
> if ((tf->lbam == 0) && (tf->lbah == 0)) {
> DPRINTK("found ATA device by sig\n");
> @@ -1248,8 +1251,8 @@ unsigned int ata_dev_classify(const struct ata_taskfile *tf)
> }
>
> if ((tf->lbam == 0x3c) && (tf->lbah == 0xc3)) {
> - printk(KERN_INFO "ata: SEMB device ignored\n");
> - return ATA_DEV_SEMB_UNSUP; /* not yet */
> + DPRINTK("found SEMB device by sig (could be ATA device)\n");
> + return ATA_DEV_SEMB;
> }
>
> DPRINTK("unknown device\n");
> @@ -2080,6 +2083,7 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class,
> struct ata_taskfile tf;
> unsigned int err_mask = 0;
> const char *reason;
> + bool is_semb = class == ATA_DEV_SEMB;
> int may_fallback = 1, tried_spinup = 0;
> int rc;
>
> @@ -2090,6 +2094,8 @@ retry:
> ata_tf_init(dev, &tf);
>
> switch (class) {
> + case ATA_DEV_SEMB:
> + class = ATA_DEV_ATA; /* some hard drives report SEMB sig */
> case ATA_DEV_ATA:
> tf.command = ATA_CMD_ID_ATA;
> break;
Why assign class now, as opposed to after IDENTIFY DEVICE succeeds / fails?
> @@ -2119,6 +2125,7 @@ retry:
> else
> err_mask = ata_do_dev_read_id(dev, &tf, id);
>
> + err_mask |= AC_ERR_DEV;
> if (err_mask) {
> if (err_mask & AC_ERR_NODEV_HINT) {
> ata_dev_printk(dev, KERN_DEBUG,
Why is err_mask being unconditionally set?
I would think this would make more sense:
if (!err_mask && class == ATA_DEV_SEMB)
class = ATA_DEV_ATA;
else if (err_mask) {
if (err_mask & AC_ERR_NODEV_HINT) {
...
Thanks,
Jeff
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH #upstream-fixes] libata: handle SEMB signature better
2009-04-14 12:12 ` Jeff Garzik
@ 2009-04-14 21:03 ` Tejun Heo
2009-04-14 21:08 ` Jeff Garzik
0 siblings, 1 reply; 7+ messages in thread
From: Tejun Heo @ 2009-04-14 21:03 UTC (permalink / raw)
To: Jeff Garzik; +Cc: IDE/ATA development list, David Haun, liw, jmcarranza
Hello, Jeff.
Jeff Garzik wrote:
>> switch (class) {
>> + case ATA_DEV_SEMB:
>> + class = ATA_DEV_ATA; /* some hard drives report SEMB sig */
>> case ATA_DEV_ATA:
>> tf.command = ATA_CMD_ID_ATA;
>> break;
>
> Why assign class now, as opposed to after IDENTIFY DEVICE succeeds / fails?
The class variable indicates which class the code is gonna try not the
one which is discovered, so it's more consistent to set it before
trying it out.
>
>> @@ -2119,6 +2125,7 @@ retry:
>> else
>> err_mask = ata_do_dev_read_id(dev, &tf, id);
>>
>> + err_mask |= AC_ERR_DEV;
>> if (err_mask) {
>> if (err_mask & AC_ERR_NODEV_HINT) {
>> ata_dev_printk(dev, KERN_DEBUG,
>
> Why is err_mask being unconditionally set?
Oh.. c**p, that's debug code I forgot to remove. Thanks for spotting
it. :-)
> I would think this would make more sense:
>
> if (!err_mask && class == ATA_DEV_SEMB)
> class = ATA_DEV_ATA;
> else if (err_mask) {
> if (err_mask & AC_ERR_NODEV_HINT) {
> ...
I made the code a fast exit path because I didn't know how an actual
SEMB device would respond to it. If the device timeouts IDENTIFYs,
retrying can be quite painful. ATA drives w/ SEMB signature being
extrmemely rare, I think it's better to trade their slight chance of
detection failure but then again it's not like we have a lot of SEMB
devices. What do you think?
Thanks.
--
tejun
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH #upstream-fixes] libata: handle SEMB signature better
2009-04-14 21:03 ` Tejun Heo
@ 2009-04-14 21:08 ` Jeff Garzik
2009-04-14 21:21 ` [PATCH UPDATED " Tejun Heo
0 siblings, 1 reply; 7+ messages in thread
From: Jeff Garzik @ 2009-04-14 21:08 UTC (permalink / raw)
To: Tejun Heo; +Cc: IDE/ATA development list, David Haun, liw, jmcarranza
Tejun Heo wrote:
> Hello, Jeff.
>
> Jeff Garzik wrote:
>>> switch (class) {
>>> + case ATA_DEV_SEMB:
>>> + class = ATA_DEV_ATA; /* some hard drives report SEMB sig */
>>> case ATA_DEV_ATA:
>>> tf.command = ATA_CMD_ID_ATA;
>>> break;
>> Why assign class now, as opposed to after IDENTIFY DEVICE succeeds / fails?
>
> The class variable indicates which class the code is gonna try not the
> one which is discovered, so it's more consistent to set it before
> trying it out.
>
>>> @@ -2119,6 +2125,7 @@ retry:
>>> else
>>> err_mask = ata_do_dev_read_id(dev, &tf, id);
>>>
>>> + err_mask |= AC_ERR_DEV;
>>> if (err_mask) {
>>> if (err_mask & AC_ERR_NODEV_HINT) {
>>> ata_dev_printk(dev, KERN_DEBUG,
>> Why is err_mask being unconditionally set?
>
> Oh.. c**p, that's debug code I forgot to remove. Thanks for spotting
> it. :-)
>
>> I would think this would make more sense:
>>
>> if (!err_mask && class == ATA_DEV_SEMB)
>> class = ATA_DEV_ATA;
>> else if (err_mask) {
>> if (err_mask & AC_ERR_NODEV_HINT) {
>> ...
>
> I made the code a fast exit path because I didn't know how an actual
> SEMB device would respond to it. If the device timeouts IDENTIFYs,
> retrying can be quite painful. ATA drives w/ SEMB signature being
> extrmemely rare, I think it's better to trade their slight chance of
> detection failure but then again it's not like we have a lot of SEMB
> devices. What do you think?
That's fine -- it is mainly the unconditional err_mask assignment that
confused me. I was trying to figure out the rest of the changes, in the
context of that variable assignment :)
Jeff
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH UPDATED #upstream-fixes] libata: handle SEMB signature better
2009-04-14 21:08 ` Jeff Garzik
@ 2009-04-14 21:21 ` Tejun Heo
2009-04-16 7:37 ` Borislav Petkov
2009-04-16 19:22 ` Jeff Garzik
0 siblings, 2 replies; 7+ messages in thread
From: Tejun Heo @ 2009-04-14 21:21 UTC (permalink / raw)
To: Jeff Garzik; +Cc: IDE/ATA development list, David Haun, liw, jmcarranza
WDC WD1600JS-62MHB5 successfully hits the window between ATA/ATAPI-7
and Serial ATA II standards and reports 3c/c3 signature which now is
assigned to SEMB. Make ata_dev_classify() report ATA_DEV_SEMB on the
sig and let ata_dev_read_id() work around it by trying IDENTIFY once.
This fixes bko#11579.
UPDATED: Jeff spotted stupid bug caused by lingering debug code.
Signed-off-by: Tejun Heo <tj@kernel.org>
Reported-by: David Haun <drhaun88@gmail.com>
Reported-by: Lars Wirzenius <liw@liw.fi>
Reported-by: Juan Manuel <jmcarranza@gmail.com>
---
drivers/ata/libata-core.c | 18 ++++++++++++++++--
1 file changed, 16 insertions(+), 2 deletions(-)
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 065507c..a61af38 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -1231,6 +1231,9 @@ unsigned int ata_dev_classify(const struct ata_taskfile *tf)
*
* We follow the current spec and consider that 0x69/0x96
* identifies a port multiplier and 0x3c/0xc3 a SEMB device.
+ * Unfortunately, WDC WD1600JS-62MHB5 (a hard drive) reports
+ * SEMB signature. This is worked around in
+ * ata_dev_read_id().
*/
if ((tf->lbam == 0) && (tf->lbah == 0)) {
DPRINTK("found ATA device by sig\n");
@@ -1248,8 +1251,8 @@ unsigned int ata_dev_classify(const struct ata_taskfile *tf)
}
if ((tf->lbam == 0x3c) && (tf->lbah == 0xc3)) {
- printk(KERN_INFO "ata: SEMB device ignored\n");
- return ATA_DEV_SEMB_UNSUP; /* not yet */
+ DPRINTK("found SEMB device by sig (could be ATA device)\n");
+ return ATA_DEV_SEMB;
}
DPRINTK("unknown device\n");
@@ -2080,6 +2083,7 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class,
struct ata_taskfile tf;
unsigned int err_mask = 0;
const char *reason;
+ bool is_semb = class == ATA_DEV_SEMB;
int may_fallback = 1, tried_spinup = 0;
int rc;
@@ -2090,6 +2094,8 @@ retry:
ata_tf_init(dev, &tf);
switch (class) {
+ case ATA_DEV_SEMB:
+ class = ATA_DEV_ATA; /* some hard drives report SEMB sig */
case ATA_DEV_ATA:
tf.command = ATA_CMD_ID_ATA;
break;
@@ -2126,6 +2132,14 @@ retry:
return -ENOENT;
}
+ if (is_semb) {
+ ata_dev_printk(dev, KERN_INFO, "IDENTIFY failed on "
+ "device w/ SEMB sig, disabled\n");
+ /* SEMB is not supported yet */
+ *p_class = ATA_DEV_SEMB_UNSUP;
+ return 0;
+ }
+
if ((err_mask == AC_ERR_DEV) && (tf.feature & ATA_ABORTED)) {
/* Device or controller might have reported
* the wrong device class. Give a shot at the
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH UPDATED #upstream-fixes] libata: handle SEMB signature better
2009-04-14 21:21 ` [PATCH UPDATED " Tejun Heo
@ 2009-04-16 7:37 ` Borislav Petkov
2009-04-16 19:22 ` Jeff Garzik
1 sibling, 0 replies; 7+ messages in thread
From: Borislav Petkov @ 2009-04-16 7:37 UTC (permalink / raw)
To: Tejun Heo
Cc: Jeff Garzik, IDE/ATA development list, David Haun, liw,
jmcarranza
Hi Tejun,
On Wed, Apr 15, 2009 at 06:21:10AM +0900, Tejun Heo wrote:
> WDC WD1600JS-62MHB5 successfully hits the window between ATA/ATAPI-7
> and Serial ATA II standards and reports 3c/c3 signature which now is
> assigned to SEMB. Make ata_dev_classify() report ATA_DEV_SEMB on the
> sig and let ata_dev_read_id() work around it by trying IDENTIFY once.
>
> This fixes bko#11579.
>
> UPDATED: Jeff spotted stupid bug caused by lingering debug code.
>
by the way, this patch fixes the problem here with a similar WDC which
reports the same signature 3c/c3 and gets ignored as a SEMB device
initially. With your patch it looks much better:
Apr 16 09:30:05 liondog kernel: ahci 0000:00:11.0: version 3.0
Apr 16 09:30:05 liondog kernel: ahci 0000:00:11.0: PCI INT A -> GSI 22 (level, low) -> IRQ 22
Apr 16 09:30:05 liondog kernel: ahci 0000:00:11.0: AHCI 0001.0100 32 slots 6 ports 3 Gbps 0x3f impl SATA mode
Apr 16 09:30:05 liondog kernel: ahci 0000:00:11.0: flags: 64bit ncq sntf ilck pm led clo pmp pio slum part
Apr 16 09:30:05 liondog kernel: scsi0 : ahci
Apr 16 09:30:05 liondog kernel: scsi1 : ahci
Apr 16 09:30:05 liondog kernel: scsi2 : ahci
Apr 16 09:30:05 liondog kernel: scsi3 : ahci
Apr 16 09:30:05 liondog kernel: scsi4 : ahci
Apr 16 09:30:05 liondog kernel: scsi5 : ahci
Apr 16 09:30:05 liondog kernel: ata1: SATA max UDMA/133 abar m1024@0xfe9ff800 port 0xfe9ff900 irq 22
Apr 16 09:30:05 liondog kernel: ata2: SATA max UDMA/133 abar m1024@0xfe9ff800 port 0xfe9ff980 irq 22
Apr 16 09:30:05 liondog kernel: ata3: SATA max UDMA/133 abar m1024@0xfe9ff800 port 0xfe9ffa00 irq 22
Apr 16 09:30:05 liondog kernel: ata4: SATA max UDMA/133 abar m1024@0xfe9ff800 port 0xfe9ffa80 irq 22
Apr 16 09:30:05 liondog kernel: ata5: SATA max UDMA/133 abar m1024@0xfe9ff800 port 0xfe9ffb00 irq 22
Apr 16 09:30:05 liondog kernel: ata6: SATA max UDMA/133 abar m1024@0xfe9ff800 port 0xfe9ffb80 irq 22
Apr 16 09:30:05 liondog kernel: ata1: SATA link down (SStatus 0 SControl 300)
Apr 16 09:30:05 liondog kernel: ata2: softreset failed (device not ready)
Apr 16 09:30:05 liondog kernel: ata2: failed due to HW bug, retry pmp=0
Apr 16 09:30:05 liondog kernel: ata2: SATA link up 3.0 Gbps (SStatus 123 SControl 300)
Apr 16 09:30:05 liondog kernel: ata2.00: ATA-8: WDC WD2500AAJS-62B4A0, 01.03A01, max UDMA/133
Apr 16 09:30:05 liondog kernel: ata2.00: 488397168 sectors, multi 16: LBA48 NCQ (depth 31/32)
Apr 16 09:30:05 liondog kernel: ata2.00: configured for UDMA/133
Thanks.
--
Regards/Gruss,
Boris.
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH UPDATED #upstream-fixes] libata: handle SEMB signature better
2009-04-14 21:21 ` [PATCH UPDATED " Tejun Heo
2009-04-16 7:37 ` Borislav Petkov
@ 2009-04-16 19:22 ` Jeff Garzik
1 sibling, 0 replies; 7+ messages in thread
From: Jeff Garzik @ 2009-04-16 19:22 UTC (permalink / raw)
To: Tejun Heo; +Cc: IDE/ATA development list, David Haun, liw, jmcarranza
Tejun Heo wrote:
> WDC WD1600JS-62MHB5 successfully hits the window between ATA/ATAPI-7
> and Serial ATA II standards and reports 3c/c3 signature which now is
> assigned to SEMB. Make ata_dev_classify() report ATA_DEV_SEMB on the
> sig and let ata_dev_read_id() work around it by trying IDENTIFY once.
>
> This fixes bko#11579.
>
> UPDATED: Jeff spotted stupid bug caused by lingering debug code.
>
> Signed-off-by: Tejun Heo <tj@kernel.org>
> Reported-by: David Haun <drhaun88@gmail.com>
> Reported-by: Lars Wirzenius <liw@liw.fi>
> Reported-by: Juan Manuel <jmcarranza@gmail.com>
> ---
> drivers/ata/libata-core.c | 18 ++++++++++++++++--
> 1 file changed, 16 insertions(+), 2 deletions(-)
applied
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2009-04-16 19:22 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-04-14 10:35 [PATCH #upstream-fixes] libata: handle SEMB signature better Tejun Heo
2009-04-14 12:12 ` Jeff Garzik
2009-04-14 21:03 ` Tejun Heo
2009-04-14 21:08 ` Jeff Garzik
2009-04-14 21:21 ` [PATCH UPDATED " Tejun Heo
2009-04-16 7:37 ` Borislav Petkov
2009-04-16 19:22 ` Jeff Garzik
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).