aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/libata-core.c
diff options
context:
space:
mode:
authorAlbert Lee <albertcc@tw.ibm.com>2006-04-01 04:38:43 -0500
committerJeff Garzik <jeff@garzik.org>2006-04-01 14:29:21 -0500
commiteee6c32f5f114f9b9f2d94862f0dc0d3ff523864 (patch)
tree76cae31872925fd2e66aeab833fed6b293f9af2d /drivers/scsi/libata-core.c
parent6e07e16404deafadf45895a7d2aeb5feba53b479 (diff)
[PATCH] libata-dev: handle DRQ=1 ERR=1 (revised)
Handle DRQ=1 ERR=1 situation. Revised according to what IDE try_to_flush_leftover_data() does. Changes: - For ATA PIO writes and ATAPI devices, just stop the HSM and let EH handle it. - For ATA PIO reads, read only one block of junk data and then let EH handle it. Signed-off-by: Albert Lee <albertcc@tw.ibm.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/scsi/libata-core.c')
-rw-r--r--drivers/scsi/libata-core.c46
1 files changed, 32 insertions, 14 deletions
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
index 6fc25f60db97..da13deccc0e0 100644
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -3640,13 +3640,16 @@ fsm_start:
3640 3640
3641 /* Device should not ask for data transfer (DRQ=1) 3641 /* Device should not ask for data transfer (DRQ=1)
3642 * when it finds something wrong. 3642 * when it finds something wrong.
3643 * Anyway, we respect DRQ here and let HSM go on 3643 * We ignore DRQ here and stop the HSM by
3644 * without changing hsm_task_state to HSM_ST_ERR. 3644 * changing hsm_task_state to HSM_ST_ERR and
3645 * let the EH abort the command or reset the device.
3645 */ 3646 */
3646 if (unlikely(status & (ATA_ERR | ATA_DF))) { 3647 if (unlikely(status & (ATA_ERR | ATA_DF))) {
3647 printk(KERN_WARNING "ata%d: DRQ=1 with device error, dev_stat 0x%X\n", 3648 printk(KERN_WARNING "ata%d: DRQ=1 with device error, dev_stat 0x%X\n",
3648 ap->id, status); 3649 ap->id, status);
3649 qc->err_mask |= AC_ERR_DEV; 3650 qc->err_mask |= AC_ERR_DEV;
3651 ap->hsm_task_state = HSM_ST_ERR;
3652 goto fsm_start;
3650 } 3653 }
3651 3654
3652 /* Send the CDB (atapi) or the first data block (ata pio out). 3655 /* Send the CDB (atapi) or the first data block (ata pio out).
@@ -3693,13 +3696,16 @@ fsm_start:
3693 3696
3694 /* Device should not ask for data transfer (DRQ=1) 3697 /* Device should not ask for data transfer (DRQ=1)
3695 * when it finds something wrong. 3698 * when it finds something wrong.
3696 * Anyway, we respect DRQ here and let HSM go on 3699 * We ignore DRQ here and stop the HSM by
3697 * without changing hsm_task_state to HSM_ST_ERR. 3700 * changing hsm_task_state to HSM_ST_ERR and
3701 * let the EH abort the command or reset the device.
3698 */ 3702 */
3699 if (unlikely(status & (ATA_ERR | ATA_DF))) { 3703 if (unlikely(status & (ATA_ERR | ATA_DF))) {
3700 printk(KERN_WARNING "ata%d: DRQ=1 with device error, dev_stat 0x%X\n", 3704 printk(KERN_WARNING "ata%d: DRQ=1 with device error, dev_stat 0x%X\n",
3701 ap->id, status); 3705 ap->id, status);
3702 qc->err_mask |= AC_ERR_DEV; 3706 qc->err_mask |= AC_ERR_DEV;
3707 ap->hsm_task_state = HSM_ST_ERR;
3708 goto fsm_start;
3703 } 3709 }
3704 3710
3705 atapi_pio_bytes(qc); 3711 atapi_pio_bytes(qc);
@@ -3717,20 +3723,32 @@ fsm_start:
3717 goto fsm_start; 3723 goto fsm_start;
3718 } 3724 }
3719 3725
3720 /* Some devices may ask for data transfer (DRQ=1) 3726 /* For PIO reads, some devices may ask for
3721 * alone with ERR=1 for PIO reads. 3727 * data transfer (DRQ=1) alone with ERR=1.
3722 * We respect DRQ here and let HSM go on without 3728 * We respect DRQ here and transfer one
3723 * changing hsm_task_state to HSM_ST_ERR. 3729 * block of junk data before changing the
3730 * hsm_task_state to HSM_ST_ERR.
3731 *
3732 * For PIO writes, ERR=1 DRQ=1 doesn't make
3733 * sense since the data block has been
3734 * transferred to the device.
3724 */ 3735 */
3725 if (unlikely(status & (ATA_ERR | ATA_DF))) { 3736 if (unlikely(status & (ATA_ERR | ATA_DF))) {
3726 /* For writes, ERR=1 DRQ=1 doesn't make
3727 * sense since the data block has been
3728 * transferred to the device.
3729 */
3730 WARN_ON(qc->tf.flags & ATA_TFLAG_WRITE);
3731
3732 /* data might be corrputed */ 3737 /* data might be corrputed */
3733 qc->err_mask |= AC_ERR_DEV; 3738 qc->err_mask |= AC_ERR_DEV;
3739
3740 if (!(qc->tf.flags & ATA_TFLAG_WRITE)) {
3741 ata_pio_sectors(qc);
3742 ata_altstatus(ap);
3743 status = ata_wait_idle(ap);
3744 }
3745
3746 /* ata_pio_sectors() might change the
3747 * state to HSM_ST_LAST. so, the state
3748 * is changed after ata_pio_sectors().
3749 */
3750 ap->hsm_task_state = HSM_ST_ERR;
3751 goto fsm_start;
3734 } 3752 }
3735 3753
3736 ata_pio_sectors(qc); 3754 ata_pio_sectors(qc);