diff options
author | Albert Lee <albertcc@tw.ibm.com> | 2005-12-26 03:40:53 -0500 |
---|---|---|
committer | Jeff Garzik <jgarzik@pobox.com> | 2006-01-17 19:55:03 -0500 |
commit | a4f16610081001640ffe0314024bc31c10f69757 (patch) | |
tree | ed2586027ef02a9d195dd00e5c61ab1728afee24 /drivers/scsi/libata-core.c | |
parent | ea9b395fe20ac74be788f415af2622ac8f0c35c7 (diff) |
[PATCH] libata-dev: determine err_mask when error is found
Changes:
- Determine err_mask directly when an error is found.
- Remove "qc->err_mask |= __ac_err_mask(status);" in ata_host_intr()
Signed-off-by: Albert Lee <albertcc@tw.ibm.com>
============
Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
Diffstat (limited to 'drivers/scsi/libata-core.c')
-rw-r--r-- | drivers/scsi/libata-core.c | 21 |
1 files changed, 19 insertions, 2 deletions
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c index 4a61061d0bde..41f76b9bf992 100644 --- a/drivers/scsi/libata-core.c +++ b/drivers/scsi/libata-core.c | |||
@@ -3265,6 +3265,7 @@ static int ata_pio_first_block(struct ata_port *ap) | |||
3265 | /* sleep-wait for BSY to clear */ | 3265 | /* sleep-wait for BSY to clear */ |
3266 | DPRINTK("busy wait\n"); | 3266 | DPRINTK("busy wait\n"); |
3267 | if (ata_busy_sleep(ap, ATA_TMOUT_DATAOUT_QUICK, ATA_TMOUT_DATAOUT)) { | 3267 | if (ata_busy_sleep(ap, ATA_TMOUT_DATAOUT_QUICK, ATA_TMOUT_DATAOUT)) { |
3268 | qc->err_mask |= AC_ERR_ATA_BUS; | ||
3268 | ap->hsm_task_state = HSM_ST_TMOUT; | 3269 | ap->hsm_task_state = HSM_ST_TMOUT; |
3269 | goto err_out; | 3270 | goto err_out; |
3270 | } | 3271 | } |
@@ -3273,6 +3274,7 @@ static int ata_pio_first_block(struct ata_port *ap) | |||
3273 | status = ata_chk_status(ap); | 3274 | status = ata_chk_status(ap); |
3274 | if ((status & (ATA_BUSY | ATA_DRQ)) != ATA_DRQ) { | 3275 | if ((status & (ATA_BUSY | ATA_DRQ)) != ATA_DRQ) { |
3275 | /* device status error */ | 3276 | /* device status error */ |
3277 | qc->err_mask |= AC_ERR_ATA_BUS; | ||
3276 | ap->hsm_task_state = HSM_ST_ERR; | 3278 | ap->hsm_task_state = HSM_ST_ERR; |
3277 | goto err_out; | 3279 | goto err_out; |
3278 | } | 3280 | } |
@@ -4288,6 +4290,12 @@ inline unsigned int ata_host_intr (struct ata_port *ap, | |||
4288 | 4290 | ||
4289 | /* before we do anything else, clear DMA-Start bit */ | 4291 | /* before we do anything else, clear DMA-Start bit */ |
4290 | ap->ops->bmdma_stop(qc); | 4292 | ap->ops->bmdma_stop(qc); |
4293 | |||
4294 | if (unlikely(host_stat & ATA_DMA_ERR)) { | ||
4295 | /* error when transfering data to/from memory */ | ||
4296 | qc->err_mask |= AC_ERR_HOST_BUS; | ||
4297 | ap->hsm_task_state = HSM_ST_ERR; | ||
4298 | } | ||
4291 | } | 4299 | } |
4292 | break; | 4300 | break; |
4293 | case HSM_ST: | 4301 | case HSM_ST: |
@@ -4313,8 +4321,10 @@ inline unsigned int ata_host_intr (struct ata_port *ap, | |||
4313 | ap->ops->irq_clear(ap); | 4321 | ap->ops->irq_clear(ap); |
4314 | 4322 | ||
4315 | /* check error */ | 4323 | /* check error */ |
4316 | if (unlikely((status & ATA_ERR) || (host_stat & ATA_DMA_ERR))) | 4324 | if (unlikely(status & (ATA_ERR | ATA_DF))) { |
4325 | qc->err_mask |= AC_ERR_DEV; | ||
4317 | ap->hsm_task_state = HSM_ST_ERR; | 4326 | ap->hsm_task_state = HSM_ST_ERR; |
4327 | } | ||
4318 | 4328 | ||
4319 | fsm_start: | 4329 | fsm_start: |
4320 | switch (ap->hsm_task_state) { | 4330 | switch (ap->hsm_task_state) { |
@@ -4326,6 +4336,7 @@ fsm_start: | |||
4326 | /* check device status */ | 4336 | /* check device status */ |
4327 | if (unlikely((status & (ATA_BUSY | ATA_DRQ)) != ATA_DRQ)) { | 4337 | if (unlikely((status & (ATA_BUSY | ATA_DRQ)) != ATA_DRQ)) { |
4328 | /* Wrong status. Let EH handle this */ | 4338 | /* Wrong status. Let EH handle this */ |
4339 | qc->err_mask |= AC_ERR_ATA_BUS; | ||
4329 | ap->hsm_task_state = HSM_ST_ERR; | 4340 | ap->hsm_task_state = HSM_ST_ERR; |
4330 | goto fsm_start; | 4341 | goto fsm_start; |
4331 | } | 4342 | } |
@@ -4354,6 +4365,7 @@ fsm_start: | |||
4354 | /* ATA PIO protocol */ | 4365 | /* ATA PIO protocol */ |
4355 | if (unlikely((status & ATA_DRQ) == 0)) { | 4366 | if (unlikely((status & ATA_DRQ) == 0)) { |
4356 | /* handle BSY=0, DRQ=0 as error */ | 4367 | /* handle BSY=0, DRQ=0 as error */ |
4368 | qc->err_mask |= AC_ERR_ATA_BUS; | ||
4357 | ap->hsm_task_state = HSM_ST_ERR; | 4369 | ap->hsm_task_state = HSM_ST_ERR; |
4358 | goto fsm_start; | 4370 | goto fsm_start; |
4359 | } | 4371 | } |
@@ -4375,6 +4387,7 @@ fsm_start: | |||
4375 | case HSM_ST_LAST: | 4387 | case HSM_ST_LAST: |
4376 | if (unlikely(status & ATA_DRQ)) { | 4388 | if (unlikely(status & ATA_DRQ)) { |
4377 | /* handle DRQ=1 as error */ | 4389 | /* handle DRQ=1 as error */ |
4390 | qc->err_mask |= AC_ERR_ATA_BUS; | ||
4378 | ap->hsm_task_state = HSM_ST_ERR; | 4391 | ap->hsm_task_state = HSM_ST_ERR; |
4379 | goto fsm_start; | 4392 | goto fsm_start; |
4380 | } | 4393 | } |
@@ -4394,8 +4407,12 @@ fsm_start: | |||
4394 | printk(KERN_ERR "ata%u: command error, drv_stat 0x%x host_stat 0x%x\n", | 4407 | printk(KERN_ERR "ata%u: command error, drv_stat 0x%x host_stat 0x%x\n", |
4395 | ap->id, status, host_stat); | 4408 | ap->id, status, host_stat); |
4396 | 4409 | ||
4410 | /* make sure qc->err_mask is available to | ||
4411 | * know what's wrong and recover | ||
4412 | */ | ||
4413 | assert(qc->err_mask); | ||
4414 | |||
4397 | ap->hsm_task_state = HSM_ST_IDLE; | 4415 | ap->hsm_task_state = HSM_ST_IDLE; |
4398 | qc->err_mask |= __ac_err_mask(status); | ||
4399 | ata_qc_complete(qc); | 4416 | ata_qc_complete(qc); |
4400 | break; | 4417 | break; |
4401 | default: | 4418 | default: |