diff options
| author | Albert Lee <albertcc@tw.ibm.com> | 2005-12-26 11:40:53 +0300 |
|---|---|---|
| committer | Jeff Garzik <jgarzik@pobox.com> | 2006-01-18 03:55:03 +0300 |
| commit | a4f16610081001640ffe0314024bc31c10f69757 (patch) | |
| tree | ed2586027ef02a9d195dd00e5c61ab1728afee24 | |
| parent | ea9b395fe20ac74be788f415af2622ac8f0c35c7 (diff) | |
| download | linux-a4f16610081001640ffe0314024bc31c10f69757.tar.xz | |
[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>
| -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) /* sleep-wait for BSY to clear */ DPRINTK("busy wait\n"); if (ata_busy_sleep(ap, ATA_TMOUT_DATAOUT_QUICK, ATA_TMOUT_DATAOUT)) { + qc->err_mask |= AC_ERR_ATA_BUS; ap->hsm_task_state = HSM_ST_TMOUT; goto err_out; } @@ -3273,6 +3274,7 @@ static int ata_pio_first_block(struct ata_port *ap) status = ata_chk_status(ap); if ((status & (ATA_BUSY | ATA_DRQ)) != ATA_DRQ) { /* device status error */ + qc->err_mask |= AC_ERR_ATA_BUS; ap->hsm_task_state = HSM_ST_ERR; goto err_out; } @@ -4288,6 +4290,12 @@ inline unsigned int ata_host_intr (struct ata_port *ap, /* before we do anything else, clear DMA-Start bit */ ap->ops->bmdma_stop(qc); + + if (unlikely(host_stat & ATA_DMA_ERR)) { + /* error when transfering data to/from memory */ + qc->err_mask |= AC_ERR_HOST_BUS; + ap->hsm_task_state = HSM_ST_ERR; + } } break; case HSM_ST: @@ -4313,8 +4321,10 @@ inline unsigned int ata_host_intr (struct ata_port *ap, ap->ops->irq_clear(ap); /* check error */ - if (unlikely((status & ATA_ERR) || (host_stat & ATA_DMA_ERR))) + if (unlikely(status & (ATA_ERR | ATA_DF))) { + qc->err_mask |= AC_ERR_DEV; ap->hsm_task_state = HSM_ST_ERR; + } fsm_start: switch (ap->hsm_task_state) { @@ -4326,6 +4336,7 @@ fsm_start: /* check device status */ if (unlikely((status & (ATA_BUSY | ATA_DRQ)) != ATA_DRQ)) { /* Wrong status. Let EH handle this */ + qc->err_mask |= AC_ERR_ATA_BUS; ap->hsm_task_state = HSM_ST_ERR; goto fsm_start; } @@ -4354,6 +4365,7 @@ fsm_start: /* ATA PIO protocol */ if (unlikely((status & ATA_DRQ) == 0)) { /* handle BSY=0, DRQ=0 as error */ + qc->err_mask |= AC_ERR_ATA_BUS; ap->hsm_task_state = HSM_ST_ERR; goto fsm_start; } @@ -4375,6 +4387,7 @@ fsm_start: case HSM_ST_LAST: if (unlikely(status & ATA_DRQ)) { /* handle DRQ=1 as error */ + qc->err_mask |= AC_ERR_ATA_BUS; ap->hsm_task_state = HSM_ST_ERR; goto fsm_start; } @@ -4394,8 +4407,12 @@ fsm_start: printk(KERN_ERR "ata%u: command error, drv_stat 0x%x host_stat 0x%x\n", ap->id, status, host_stat); + /* make sure qc->err_mask is available to + * know what's wrong and recover + */ + assert(qc->err_mask); + ap->hsm_task_state = HSM_ST_IDLE; - qc->err_mask |= __ac_err_mask(status); ata_qc_complete(qc); break; default: |
