[PATCH] libata-dev: Move out the HSM code from ata_host_intr()
authorAlbert Lee <albertcc@tw.ibm.com>
Sat, 25 Mar 2006 09:43:49 +0000 (17:43 +0800)
committerJeff Garzik <jeff@garzik.org>
Wed, 29 Mar 2006 22:21:53 +0000 (17:21 -0500)
Move out the irq-pio HSM code from ata_host_intr() to the new ata_hsm_move() function verbatim.

Signed-off-by: Albert Lee <albertcc@tw.ibm.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
drivers/scsi/libata-core.c

index 0eb75e2..7214530 100644 (file)
@@ -3805,6 +3805,111 @@ static void ata_pio_error(struct ata_port *ap)
        ata_poll_qc_complete(qc);
 }
 
+static void ata_hsm_move(struct ata_port *ap, struct ata_queued_cmd *qc,
+                        u8 status)
+{
+       /* check error */
+       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) {
+       case HSM_ST_FIRST:
+               /* Some pre-ATAPI-4 devices assert INTRQ
+                * at this state when ready to receive CDB.
+                */
+
+               /* check device status */
+               if (unlikely((status & (ATA_BUSY | ATA_DRQ)) != ATA_DRQ)) {
+                       /* Wrong status. Let EH handle this */
+                       qc->err_mask |= AC_ERR_HSM;
+                       ap->hsm_task_state = HSM_ST_ERR;
+                       goto fsm_start;
+               }
+
+               atapi_send_cdb(ap, qc);
+
+               break;
+
+       case HSM_ST:
+               /* complete command or read/write the data register */
+               if (qc->tf.protocol == ATA_PROT_ATAPI) {
+                       /* ATAPI PIO protocol */
+                       if ((status & ATA_DRQ) == 0) {
+                               /* no more data to transfer */
+                               ap->hsm_task_state = HSM_ST_LAST;
+                               goto fsm_start;
+                       }
+
+                       atapi_pio_bytes(qc);
+
+                       if (unlikely(ap->hsm_task_state == HSM_ST_ERR))
+                               /* bad ireason reported by device */
+                               goto fsm_start;
+
+               } else {
+                       /* ATA PIO protocol */
+                       if (unlikely((status & ATA_DRQ) == 0)) {
+                               /* handle BSY=0, DRQ=0 as error */
+                               qc->err_mask |= AC_ERR_HSM;
+                               ap->hsm_task_state = HSM_ST_ERR;
+                               goto fsm_start;
+                       }
+
+                       ata_pio_sectors(qc);
+
+                       if (ap->hsm_task_state == HSM_ST_LAST &&
+                           (!(qc->tf.flags & ATA_TFLAG_WRITE))) {
+                               /* all data read */
+                               ata_altstatus(ap);
+                               status = ata_chk_status(ap);
+                               goto fsm_start;
+                       }
+               }
+
+               ata_altstatus(ap); /* flush */
+               break;
+
+       case HSM_ST_LAST:
+               if (unlikely(status & ATA_DRQ)) {
+                       /* handle DRQ=1 as error */
+                       qc->err_mask |= AC_ERR_HSM;
+                       ap->hsm_task_state = HSM_ST_ERR;
+                       goto fsm_start;
+               }
+
+               /* no more data to transfer */
+               DPRINTK("ata%u: command complete, drv_stat 0x%x\n",
+                       ap->id, status);
+
+               ap->hsm_task_state = HSM_ST_IDLE;
+
+               /* complete taskfile transaction */
+               qc->err_mask |= ac_err_mask(status);
+               ata_qc_complete(qc);
+               break;
+
+       case HSM_ST_ERR:
+               if (qc->tf.command != ATA_CMD_PACKET)
+                       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
+                */
+               WARN_ON(qc->err_mask == 0);
+
+               ap->hsm_task_state = HSM_ST_IDLE;
+               ata_qc_complete(qc);
+               break;
+       default:
+               goto idle_irq;
+       }
+
+}
+
 static void ata_pio_task(void *_data)
 {
        struct ata_port *ap = _data;
@@ -4316,106 +4421,7 @@ inline unsigned int ata_host_intr (struct ata_port *ap,
        /* ack bmdma irq events */
        ap->ops->irq_clear(ap);
 
-       /* check error */
-       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) {
-       case HSM_ST_FIRST:
-               /* Some pre-ATAPI-4 devices assert INTRQ
-                * at this state when ready to receive CDB.
-                */
-
-               /* check device status */
-               if (unlikely((status & (ATA_BUSY | ATA_DRQ)) != ATA_DRQ)) {
-                       /* Wrong status. Let EH handle this */
-                       qc->err_mask |= AC_ERR_HSM;
-                       ap->hsm_task_state = HSM_ST_ERR;
-                       goto fsm_start;
-               }
-
-               atapi_send_cdb(ap, qc);
-
-               break;
-
-       case HSM_ST:
-               /* complete command or read/write the data register */
-               if (qc->tf.protocol == ATA_PROT_ATAPI) {
-                       /* ATAPI PIO protocol */
-                       if ((status & ATA_DRQ) == 0) {
-                               /* no more data to transfer */
-                               ap->hsm_task_state = HSM_ST_LAST;
-                               goto fsm_start;
-                       }
-
-                       atapi_pio_bytes(qc);
-
-                       if (unlikely(ap->hsm_task_state == HSM_ST_ERR))
-                               /* bad ireason reported by device */
-                               goto fsm_start;
-
-               } else {
-                       /* ATA PIO protocol */
-                       if (unlikely((status & ATA_DRQ) == 0)) {
-                               /* handle BSY=0, DRQ=0 as error */
-                               qc->err_mask |= AC_ERR_HSM;
-                               ap->hsm_task_state = HSM_ST_ERR;
-                               goto fsm_start;
-                       }
-
-                       ata_pio_sectors(qc);
-
-                       if (ap->hsm_task_state == HSM_ST_LAST &&
-                           (!(qc->tf.flags & ATA_TFLAG_WRITE))) {
-                               /* all data read */
-                               ata_altstatus(ap);
-                               status = ata_chk_status(ap);
-                               goto fsm_start;
-                       }
-               }
-
-               ata_altstatus(ap); /* flush */
-               break;
-
-       case HSM_ST_LAST:
-               if (unlikely(status & ATA_DRQ)) {
-                       /* handle DRQ=1 as error */
-                       qc->err_mask |= AC_ERR_HSM;
-                       ap->hsm_task_state = HSM_ST_ERR;
-                       goto fsm_start;
-               }
-
-               /* no more data to transfer */
-               DPRINTK("ata%u: command complete, drv_stat 0x%x\n",
-                       ap->id, status);
-
-               ap->hsm_task_state = HSM_ST_IDLE;
-
-               /* complete taskfile transaction */
-               qc->err_mask |= ac_err_mask(status);
-               ata_qc_complete(qc);
-               break;
-
-       case HSM_ST_ERR:
-               if (qc->tf.command != ATA_CMD_PACKET)
-                       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
-                */
-               WARN_ON(qc->err_mask == 0);
-
-               ap->hsm_task_state = HSM_ST_IDLE;
-               ata_qc_complete(qc);
-               break;
-       default:
-               goto idle_irq;
-       }
-
+       ata_hsm_move(ap, qc, status);
        return 1;       /* irq handled */
 
 idle_irq: