[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>
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
index 4a61061..41f76b9 100644
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -3265,6 +3265,7 @@
 	/* 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 @@
 	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 @@
 
 			/* 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 @@
 	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 @@
 		/* 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 @@
 			/* 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 @@
 	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 @@
 		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: