diff options
author | Albert Lee <albertcc@tw.ibm.com> | 2006-03-25 04:45:49 -0500 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2006-03-29 17:21:53 -0500 |
commit | 6912ccd5a4a095d71fd7215ef2abea877c8fed6f (patch) | |
tree | e8381968de60c1e92e98b8c35b828ab1c44ca573 /drivers/scsi/libata-core.c | |
parent | e2cec77117a6e4fcbac2601e2f7b0b3f4f5a4c84 (diff) |
[PATCH] libata-dev: Minor fix for ata_hsm_move() to work with ata_host_intr()
Minor fix for ata_hsm_move() to work with ata_host_intr().
Changes:
- WARN_ON() and comment fix
- Make the HSM_ST_LAST device status checking more rigid.
- Treat unknown HSM state as BUG().
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.c | 24 |
1 files changed, 13 insertions, 11 deletions
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c index 7214530ac161..094c7907534a 100644 --- a/drivers/scsi/libata-core.c +++ b/drivers/scsi/libata-core.c | |||
@@ -3808,6 +3808,8 @@ static void ata_pio_error(struct ata_port *ap) | |||
3808 | static void ata_hsm_move(struct ata_port *ap, struct ata_queued_cmd *qc, | 3808 | static void ata_hsm_move(struct ata_port *ap, struct ata_queued_cmd *qc, |
3809 | u8 status) | 3809 | u8 status) |
3810 | { | 3810 | { |
3811 | WARN_ON((qc->flags & ATA_QCFLAG_ACTIVE) == 0); | ||
3812 | |||
3811 | /* check error */ | 3813 | /* check error */ |
3812 | if (unlikely(status & (ATA_ERR | ATA_DF))) { | 3814 | if (unlikely(status & (ATA_ERR | ATA_DF))) { |
3813 | qc->err_mask |= AC_ERR_DEV; | 3815 | qc->err_mask |= AC_ERR_DEV; |
@@ -3817,10 +3819,6 @@ static void ata_hsm_move(struct ata_port *ap, struct ata_queued_cmd *qc, | |||
3817 | fsm_start: | 3819 | fsm_start: |
3818 | switch (ap->hsm_task_state) { | 3820 | switch (ap->hsm_task_state) { |
3819 | case HSM_ST_FIRST: | 3821 | case HSM_ST_FIRST: |
3820 | /* Some pre-ATAPI-4 devices assert INTRQ | ||
3821 | * at this state when ready to receive CDB. | ||
3822 | */ | ||
3823 | |||
3824 | /* check device status */ | 3822 | /* check device status */ |
3825 | if (unlikely((status & (ATA_BUSY | ATA_DRQ)) != ATA_DRQ)) { | 3823 | if (unlikely((status & (ATA_BUSY | ATA_DRQ)) != ATA_DRQ)) { |
3826 | /* Wrong status. Let EH handle this */ | 3824 | /* Wrong status. Let EH handle this */ |
@@ -3873,9 +3871,8 @@ fsm_start: | |||
3873 | break; | 3871 | break; |
3874 | 3872 | ||
3875 | case HSM_ST_LAST: | 3873 | case HSM_ST_LAST: |
3876 | if (unlikely(status & ATA_DRQ)) { | 3874 | if (unlikely(!ata_ok(status))) { |
3877 | /* handle DRQ=1 as error */ | 3875 | qc->err_mask |= __ac_err_mask(status); |
3878 | qc->err_mask |= AC_ERR_HSM; | ||
3879 | ap->hsm_task_state = HSM_ST_ERR; | 3876 | ap->hsm_task_state = HSM_ST_ERR; |
3880 | goto fsm_start; | 3877 | goto fsm_start; |
3881 | } | 3878 | } |
@@ -3884,17 +3881,18 @@ fsm_start: | |||
3884 | DPRINTK("ata%u: command complete, drv_stat 0x%x\n", | 3881 | DPRINTK("ata%u: command complete, drv_stat 0x%x\n", |
3885 | ap->id, status); | 3882 | ap->id, status); |
3886 | 3883 | ||
3884 | WARN_ON(qc->err_mask); | ||
3885 | |||
3887 | ap->hsm_task_state = HSM_ST_IDLE; | 3886 | ap->hsm_task_state = HSM_ST_IDLE; |
3888 | 3887 | ||
3889 | /* complete taskfile transaction */ | 3888 | /* complete taskfile transaction */ |
3890 | qc->err_mask |= ac_err_mask(status); | ||
3891 | ata_qc_complete(qc); | 3889 | ata_qc_complete(qc); |
3892 | break; | 3890 | break; |
3893 | 3891 | ||
3894 | case HSM_ST_ERR: | 3892 | case HSM_ST_ERR: |
3895 | if (qc->tf.command != ATA_CMD_PACKET) | 3893 | if (qc->tf.command != ATA_CMD_PACKET) |
3896 | printk(KERN_ERR "ata%u: command error, drv_stat 0x%x host_stat 0x%x\n", | 3894 | printk(KERN_ERR "ata%u: command error, drv_stat 0x%x\n", |
3897 | ap->id, status, host_stat); | 3895 | ap->id, status); |
3898 | 3896 | ||
3899 | /* make sure qc->err_mask is available to | 3897 | /* make sure qc->err_mask is available to |
3900 | * know what's wrong and recover | 3898 | * know what's wrong and recover |
@@ -3905,7 +3903,7 @@ fsm_start: | |||
3905 | ata_qc_complete(qc); | 3903 | ata_qc_complete(qc); |
3906 | break; | 3904 | break; |
3907 | default: | 3905 | default: |
3908 | goto idle_irq; | 3906 | BUG(); |
3909 | } | 3907 | } |
3910 | 3908 | ||
3911 | } | 3909 | } |
@@ -4371,6 +4369,10 @@ inline unsigned int ata_host_intr (struct ata_port *ap, | |||
4371 | /* Check whether we are expecting interrupt in this state */ | 4369 | /* Check whether we are expecting interrupt in this state */ |
4372 | switch (ap->hsm_task_state) { | 4370 | switch (ap->hsm_task_state) { |
4373 | case HSM_ST_FIRST: | 4371 | case HSM_ST_FIRST: |
4372 | /* Some pre-ATAPI-4 devices assert INTRQ | ||
4373 | * at this state when ready to receive CDB. | ||
4374 | */ | ||
4375 | |||
4374 | /* Check the ATA_DFLAG_CDB_INTR flag is enough here. | 4376 | /* Check the ATA_DFLAG_CDB_INTR flag is enough here. |
4375 | * The flag was turned on only for atapi devices. | 4377 | * The flag was turned on only for atapi devices. |
4376 | * No need to check is_atapi_taskfile(&qc->tf) again. | 4378 | * No need to check is_atapi_taskfile(&qc->tf) again. |