aboutsummaryrefslogtreecommitdiff
path: root/drivers/ata
diff options
context:
space:
mode:
authorAlbert Lee <albertcc@tw.ibm.com>2007-11-15 10:35:46 +0900
committerTejun Heo <htejun@gmail.com>2007-11-19 12:28:11 +0900
commit2d3b8eea7f2fbafd5d779cc92f7aedbd1ef575e9 (patch)
tree292cd6197c457defc3e07d02a663cabb3dceb253 /drivers/ata
parent21bef6dd2b419f28c8096a8e30ad86dcbff44c02 (diff)
libata: workaround DRQ=1 ERR=1 for ATAPI tape drives
After an error condition, some ATAPI tape drives set DRQ=1 together with ERR=1 when asking the host to transfer the CDB of the next packet command (i.e. request sense). This patch, a revised version of Alan/Mark's previous patch, adds ATA_HORKAGE_STUCK_ERR to workaround the problem by ignoring the ERR bit and proceed sending the CDB. Signed-off-by: Albert Lee <albertcc@tw.ibm.com> Cc: Alan Cox <alan@lxorguk.ukuu.org.uk> Cc: Mark Lord <liml@rtr.ca> Signed-off-by: Tejun Heo <htejun@gmail.com>
Diffstat (limited to 'drivers/ata')
-rw-r--r--drivers/ata/libata-core.c18
1 files changed, 13 insertions, 5 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 1584164e770..5478b4c6c6e 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -5415,11 +5415,19 @@ fsm_start:
* let the EH abort the command or reset the device.
*/
if (unlikely(status & (ATA_ERR | ATA_DF))) {
- ata_port_printk(ap, KERN_WARNING, "DRQ=1 with device "
- "error, dev_stat 0x%X\n", status);
- qc->err_mask |= AC_ERR_HSM;
- ap->hsm_task_state = HSM_ST_ERR;
- goto fsm_start;
+ /* Some ATAPI tape drives forget to clear the ERR bit
+ * when doing the next command (mostly request sense).
+ * We ignore ERR here to workaround and proceed sending
+ * the CDB.
+ */
+ if (!(qc->dev->horkage & ATA_HORKAGE_STUCK_ERR)) {
+ ata_port_printk(ap, KERN_WARNING,
+ "DRQ=1 with device error, "
+ "dev_stat 0x%X\n", status);
+ qc->err_mask |= AC_ERR_HSM;
+ ap->hsm_task_state = HSM_ST_ERR;
+ goto fsm_start;
+ }
}
/* Send the CDB (atapi) or the first data block (ata pio out).