aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/libata-core.c
diff options
context:
space:
mode:
authorAlbert Lee <albertcc@tw.ibm.com>2006-03-25 04:43:49 -0500
committerJeff Garzik <jeff@garzik.org>2006-03-29 17:21:53 -0500
commite2cec77117a6e4fcbac2601e2f7b0b3f4f5a4c84 (patch)
treed1cbdf9f959c7d4584bca1e850fa9719b61bc99d /drivers/scsi/libata-core.c
parent19d5d7309a928eb86f58b37165a2d501621ae3c0 (diff)
[PATCH] libata-dev: Move out the HSM code from ata_host_intr()
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>
Diffstat (limited to 'drivers/scsi/libata-core.c')
-rw-r--r--drivers/scsi/libata-core.c206
1 files changed, 106 insertions, 100 deletions
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
index 0eb75e2dc0e2..7214530ac161 100644
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -3805,6 +3805,111 @@ static void ata_pio_error(struct ata_port *ap)
3805 ata_poll_qc_complete(qc); 3805 ata_poll_qc_complete(qc);
3806} 3806}
3807 3807
3808static void ata_hsm_move(struct ata_port *ap, struct ata_queued_cmd *qc,
3809 u8 status)
3810{
3811 /* check error */
3812 if (unlikely(status & (ATA_ERR | ATA_DF))) {
3813 qc->err_mask |= AC_ERR_DEV;
3814 ap->hsm_task_state = HSM_ST_ERR;
3815 }
3816
3817fsm_start:
3818 switch (ap->hsm_task_state) {
3819 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 */
3825 if (unlikely((status & (ATA_BUSY | ATA_DRQ)) != ATA_DRQ)) {
3826 /* Wrong status. Let EH handle this */
3827 qc->err_mask |= AC_ERR_HSM;
3828 ap->hsm_task_state = HSM_ST_ERR;
3829 goto fsm_start;
3830 }
3831
3832 atapi_send_cdb(ap, qc);
3833
3834 break;
3835
3836 case HSM_ST:
3837 /* complete command or read/write the data register */
3838 if (qc->tf.protocol == ATA_PROT_ATAPI) {
3839 /* ATAPI PIO protocol */
3840 if ((status & ATA_DRQ) == 0) {
3841 /* no more data to transfer */
3842 ap->hsm_task_state = HSM_ST_LAST;
3843 goto fsm_start;
3844 }
3845
3846 atapi_pio_bytes(qc);
3847
3848 if (unlikely(ap->hsm_task_state == HSM_ST_ERR))
3849 /* bad ireason reported by device */
3850 goto fsm_start;
3851
3852 } else {
3853 /* ATA PIO protocol */
3854 if (unlikely((status & ATA_DRQ) == 0)) {
3855 /* handle BSY=0, DRQ=0 as error */
3856 qc->err_mask |= AC_ERR_HSM;
3857 ap->hsm_task_state = HSM_ST_ERR;
3858 goto fsm_start;
3859 }
3860
3861 ata_pio_sectors(qc);
3862
3863 if (ap->hsm_task_state == HSM_ST_LAST &&
3864 (!(qc->tf.flags & ATA_TFLAG_WRITE))) {
3865 /* all data read */
3866 ata_altstatus(ap);
3867 status = ata_chk_status(ap);
3868 goto fsm_start;
3869 }
3870 }
3871
3872 ata_altstatus(ap); /* flush */
3873 break;
3874
3875 case HSM_ST_LAST:
3876 if (unlikely(status & ATA_DRQ)) {
3877 /* handle DRQ=1 as error */
3878 qc->err_mask |= AC_ERR_HSM;
3879 ap->hsm_task_state = HSM_ST_ERR;
3880 goto fsm_start;
3881 }
3882
3883 /* no more data to transfer */
3884 DPRINTK("ata%u: command complete, drv_stat 0x%x\n",
3885 ap->id, status);
3886
3887 ap->hsm_task_state = HSM_ST_IDLE;
3888
3889 /* complete taskfile transaction */
3890 qc->err_mask |= ac_err_mask(status);
3891 ata_qc_complete(qc);
3892 break;
3893
3894 case HSM_ST_ERR:
3895 if (qc->tf.command != ATA_CMD_PACKET)
3896 printk(KERN_ERR "ata%u: command error, drv_stat 0x%x host_stat 0x%x\n",
3897 ap->id, status, host_stat);
3898
3899 /* make sure qc->err_mask is available to
3900 * know what's wrong and recover
3901 */
3902 WARN_ON(qc->err_mask == 0);
3903
3904 ap->hsm_task_state = HSM_ST_IDLE;
3905 ata_qc_complete(qc);
3906 break;
3907 default:
3908 goto idle_irq;
3909 }
3910
3911}
3912
3808static void ata_pio_task(void *_data) 3913static void ata_pio_task(void *_data)
3809{ 3914{
3810 struct ata_port *ap = _data; 3915 struct ata_port *ap = _data;
@@ -4316,106 +4421,7 @@ inline unsigned int ata_host_intr (struct ata_port *ap,
4316 /* ack bmdma irq events */ 4421 /* ack bmdma irq events */
4317 ap->ops->irq_clear(ap); 4422 ap->ops->irq_clear(ap);
4318 4423
4319 /* check error */ 4424 ata_hsm_move(ap, qc, status);
4320 if (unlikely(status & (ATA_ERR | ATA_DF))) {
4321 qc->err_mask |= AC_ERR_DEV;
4322 ap->hsm_task_state = HSM_ST_ERR;
4323 }
4324
4325fsm_start:
4326 switch (ap->hsm_task_state) {
4327 case HSM_ST_FIRST:
4328 /* Some pre-ATAPI-4 devices assert INTRQ
4329 * at this state when ready to receive CDB.
4330 */
4331
4332 /* check device status */
4333 if (unlikely((status & (ATA_BUSY | ATA_DRQ)) != ATA_DRQ)) {
4334 /* Wrong status. Let EH handle this */
4335 qc->err_mask |= AC_ERR_HSM;
4336 ap->hsm_task_state = HSM_ST_ERR;
4337 goto fsm_start;
4338 }
4339
4340 atapi_send_cdb(ap, qc);
4341
4342 break;
4343
4344 case HSM_ST:
4345 /* complete command or read/write the data register */
4346 if (qc->tf.protocol == ATA_PROT_ATAPI) {
4347 /* ATAPI PIO protocol */
4348 if ((status & ATA_DRQ) == 0) {
4349 /* no more data to transfer */
4350 ap->hsm_task_state = HSM_ST_LAST;
4351 goto fsm_start;
4352 }
4353
4354 atapi_pio_bytes(qc);
4355
4356 if (unlikely(ap->hsm_task_state == HSM_ST_ERR))
4357 /* bad ireason reported by device */
4358 goto fsm_start;
4359
4360 } else {
4361 /* ATA PIO protocol */
4362 if (unlikely((status & ATA_DRQ) == 0)) {
4363 /* handle BSY=0, DRQ=0 as error */
4364 qc->err_mask |= AC_ERR_HSM;
4365 ap->hsm_task_state = HSM_ST_ERR;
4366 goto fsm_start;
4367 }
4368
4369 ata_pio_sectors(qc);
4370
4371 if (ap->hsm_task_state == HSM_ST_LAST &&
4372 (!(qc->tf.flags & ATA_TFLAG_WRITE))) {
4373 /* all data read */
4374 ata_altstatus(ap);
4375 status = ata_chk_status(ap);
4376 goto fsm_start;
4377 }
4378 }
4379
4380 ata_altstatus(ap); /* flush */
4381 break;
4382
4383 case HSM_ST_LAST:
4384 if (unlikely(status & ATA_DRQ)) {
4385 /* handle DRQ=1 as error */
4386 qc->err_mask |= AC_ERR_HSM;
4387 ap->hsm_task_state = HSM_ST_ERR;
4388 goto fsm_start;
4389 }
4390
4391 /* no more data to transfer */
4392 DPRINTK("ata%u: command complete, drv_stat 0x%x\n",
4393 ap->id, status);
4394
4395 ap->hsm_task_state = HSM_ST_IDLE;
4396
4397 /* complete taskfile transaction */
4398 qc->err_mask |= ac_err_mask(status);
4399 ata_qc_complete(qc);
4400 break;
4401
4402 case HSM_ST_ERR:
4403 if (qc->tf.command != ATA_CMD_PACKET)
4404 printk(KERN_ERR "ata%u: command error, drv_stat 0x%x host_stat 0x%x\n",
4405 ap->id, status, host_stat);
4406
4407 /* make sure qc->err_mask is available to
4408 * know what's wrong and recover
4409 */
4410 WARN_ON(qc->err_mask == 0);
4411
4412 ap->hsm_task_state = HSM_ST_IDLE;
4413 ata_qc_complete(qc);
4414 break;
4415 default:
4416 goto idle_irq;
4417 }
4418
4419 return 1; /* irq handled */ 4425 return 1; /* irq handled */
4420 4426
4421idle_irq: 4427idle_irq: