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@xxxxxxxxxx> Cc: Alan Cox <alan@xxxxxxxxxxxxxxxxxxx> Cc: Mark Lord <liml@xxxxxx> --- Revised per Alan, Mark and Tejun's comments. Tested ok with the Seagate STT8000A tape drive. Patch against the libata-dev tree. diff -Nrup 00_libata-dev/drivers/ata/libata-core.c 01_ide_tape_stuck_err/drivers/ata/libata-core.c --- 00_libata-dev/drivers/ata/libata-core.c 2007-11-14 10:08:36.000000000 +0800 +++ 01_ide_tape_stuck_err/drivers/ata/libata-core.c 2007-11-14 11:20:31.000000000 +0800 @@ -5490,11 +5490,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). diff -Nrup 00_libata-dev/include/linux/libata.h 01_ide_tape_stuck_err/include/linux/libata.h --- 00_libata-dev/include/linux/libata.h 2007-11-14 10:08:59.000000000 +0800 +++ 01_ide_tape_stuck_err/include/linux/libata.h 2007-11-14 11:19:32.000000000 +0800 @@ -340,6 +340,7 @@ enum { ATA_HORKAGE_HPA_SIZE = (1 << 6), /* native size off by one */ ATA_HORKAGE_IPM = (1 << 7), /* Link PM problems */ ATA_HORKAGE_IVB = (1 << 8), /* cbl det validity bit bugs */ + ATA_HORKAGE_STUCK_ERR = (1 << 9), /* stuck ERR on next PACKET */ /* DMA mask for user DMA control: User visible values; DO NOT renumber */ - To unsubscribe from this list: send the line "unsubscribe linux-ide" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html