[cc'ing Albert Lee. Hi!]
Vlad Codrea wrote:
>> Okay, now that you're on libata driver, it's easier for me to debug.
>> Can you apply the attached patch over 2.6.20 and report what the kernel
>> says? (the patch will apply with some noise, it's okay)
>
> I've applied your patch and recompiled the kernel, but the new dmesg
> (attached as dmesg_2.txt) doesn't seem to have changed much.
Hmmm.. that's weird, can you please try the attached patch?
Albert, can you take a look at this one? I'm pretty sure you know much
better about this than me. The whole thread can be read at...
http://thread.gmane.org/gmane.linux.ide/17052
Thanks.
--
tejun
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 14629a3..855d33a 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -4382,6 +4382,12 @@ static void ata_hsm_qc_complete(struct ata_queued_cmd *qc, int in_wq)
*/
qc = ata_qc_from_tag(ap, qc->tag);
if (qc) {
+ if ((qc->flags & ATA_QCFLAG_FAILED) ||
+ qc->err_mask)
+ ata_port_printk(ap, KERN_WARNING,
+ "hsm_qc_complete: "
+ "flags=0x%lx err_mask=0x%x\n",
+ qc->flags, qc->err_mask);
if (likely(!(qc->err_mask & AC_ERR_HSM))) {
ap->ops->irq_on(ap);
ata_qc_complete(qc);
@@ -4453,9 +4459,13 @@ fsm_start:
if (likely(status & (ATA_ERR | ATA_DF)))
/* device stops HSM for abort/error */
qc->err_mask |= AC_ERR_DEV;
- else
+ else {
/* HSM violation. Let EH handle this */
+ ata_port_printk(ap, KERN_WARNING,
+ "!DRQ on HSM_ST_FIRST (0x%x)\n",
+ status);
qc->err_mask |= AC_ERR_HSM;
+ }
ap->hsm_task_state = HSM_ST_ERR;
goto fsm_start;
@@ -4547,13 +4557,17 @@ fsm_start:
if (likely(status & (ATA_ERR | ATA_DF)))
/* device stops HSM for abort/error */
qc->err_mask |= AC_ERR_DEV;
- else
+ else {
+ ata_port_printk(ap, KERN_WARNING,
+ "!DRQ on HSM_ST (0x%x)\n",
+ status);
/* HSM violation. Let EH handle this.
* Phantom devices also trigger this
* condition. Mark hint.
*/
qc->err_mask |= AC_ERR_HSM |
AC_ERR_NODEV_HINT;
+ }
ap->hsm_task_state = HSM_ST_ERR;
goto fsm_start;
@@ -4579,8 +4593,12 @@ fsm_start:
status = ata_wait_idle(ap);
}
- if (status & (ATA_BUSY | ATA_DRQ))
+ if (status & (ATA_BUSY | ATA_DRQ)) {
+ ata_port_printk(ap, KERN_WARNING,
+ "BUSY|DRQ on ERR|DF (0x%x)\n",
+ status);
qc->err_mask |= AC_ERR_HSM;
+ }
/* ata_pio_sectors() might change the
* state to HSM_ST_LAST. so, the state
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
index 7349c3d..a956aaa 100644
--- a/drivers/ata/libata-eh.c
+++ b/drivers/ata/libata-eh.c
@@ -1146,6 +1146,8 @@ static unsigned int ata_eh_analyze_tf(struct ata_queued_cmd *qc,
u8 stat = tf->command, err = tf->feature;
if ((stat & (ATA_BUSY | ATA_DRQ | ATA_DRDY)) != ATA_DRDY) {
+ ata_dev_printk(qc->dev, KERN_WARNING,
+ "ata_eh_analyze_tf, AC_ERR_HSM, 0x%x\n", stat);
qc->err_mask |= AC_ERR_HSM;
return ATA_EH_SOFTRESET;
}