diff options
| -rw-r--r-- | drivers/scsi/libata-core.c | 46 |
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); |
