diff options
author | Albert Lee <albertcc@tw.ibm.com> | 2006-03-25 04:43:49 -0500 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2006-03-29 17:21:53 -0500 |
commit | e2cec77117a6e4fcbac2601e2f7b0b3f4f5a4c84 (patch) | |
tree | d1cbdf9f959c7d4584bca1e850fa9719b61bc99d /drivers/scsi/libata-core.c | |
parent | 19d5d7309a928eb86f58b37165a2d501621ae3c0 (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.c | 206 |
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 | ||
3808 | static 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 | |||
3817 | fsm_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 | |||
3808 | static void ata_pio_task(void *_data) | 3913 | static 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 | |||
4325 | fsm_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 | ||
4421 | idle_irq: | 4427 | idle_irq: |