diff options
author | Albert Lee <albertcc@tw.ibm.com> | 2006-03-25 04:50:15 -0500 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2006-03-29 17:21:54 -0500 |
commit | a1af37344f669d0fefa8c8a9e37eb6a7c086a2c2 (patch) | |
tree | 8a24383b850349d59917680700829d2ac25750b2 /drivers | |
parent | bb5cb290f095f17f88c912e3da35adf5b2d9500b (diff) |
[PATCH] libata-dev: Convert ata_pio_task() to use the new ata_hsm_move()
Convert ata_pio_task() to use the new ata_hsm_move().
Changes:
- refactor ata_pio_task() to poll device status register and
- call the new ata_hsm_move() when device indicates it is not BSY.
Signed-off-by: Albert Lee <albertcc@tw.ibm.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/scsi/libata-core.c | 60 |
1 files changed, 28 insertions, 32 deletions
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c index 33b39d3ce2d3..eeeeda0481a2 100644 --- a/drivers/scsi/libata-core.c +++ b/drivers/scsi/libata-core.c | |||
@@ -3986,44 +3986,40 @@ fsm_start: | |||
3986 | static void ata_pio_task(void *_data) | 3986 | static void ata_pio_task(void *_data) |
3987 | { | 3987 | { |
3988 | struct ata_port *ap = _data; | 3988 | struct ata_port *ap = _data; |
3989 | unsigned long timeout; | 3989 | struct ata_queued_cmd *qc; |
3990 | int has_next; | 3990 | u8 status; |
3991 | int poll_next; | ||
3991 | 3992 | ||
3992 | fsm_start: | 3993 | fsm_start: |
3993 | timeout = 0; | 3994 | WARN_ON(ap->hsm_task_state == HSM_ST_IDLE); |
3994 | has_next = 1; | ||
3995 | 3995 | ||
3996 | switch (ap->hsm_task_state) { | 3996 | qc = ata_qc_from_tag(ap, ap->active_tag); |
3997 | case HSM_ST_FIRST: | 3997 | WARN_ON(qc == NULL); |
3998 | has_next = ata_pio_first_block(ap); | ||
3999 | break; | ||
4000 | |||
4001 | case HSM_ST: | ||
4002 | ata_pio_block(ap); | ||
4003 | break; | ||
4004 | |||
4005 | case HSM_ST_LAST: | ||
4006 | has_next = ata_pio_complete(ap); | ||
4007 | break; | ||
4008 | |||
4009 | case HSM_ST_POLL: | ||
4010 | case HSM_ST_LAST_POLL: | ||
4011 | timeout = ata_pio_poll(ap); | ||
4012 | break; | ||
4013 | |||
4014 | case HSM_ST_TMOUT: | ||
4015 | case HSM_ST_ERR: | ||
4016 | ata_pio_error(ap); | ||
4017 | return; | ||
4018 | 3998 | ||
4019 | default: | 3999 | /* |
4020 | BUG(); | 4000 | * This is purely heuristic. This is a fast path. |
4021 | return; | 4001 | * Sometimes when we enter, BSY will be cleared in |
4002 | * a chk-status or two. If not, the drive is probably seeking | ||
4003 | * or something. Snooze for a couple msecs, then | ||
4004 | * chk-status again. If still busy, queue delayed work. | ||
4005 | */ | ||
4006 | status = ata_busy_wait(ap, ATA_BUSY, 5); | ||
4007 | if (status & ATA_BUSY) { | ||
4008 | msleep(2); | ||
4009 | status = ata_busy_wait(ap, ATA_BUSY, 10); | ||
4010 | if (status & ATA_BUSY) { | ||
4011 | ata_port_queue_task(ap, ata_pio_task, ap, ATA_SHORT_PAUSE); | ||
4012 | return; | ||
4013 | } | ||
4022 | } | 4014 | } |
4023 | 4015 | ||
4024 | if (timeout) | 4016 | /* move the HSM */ |
4025 | ata_port_queue_task(ap, ata_pio_task, ap, timeout); | 4017 | poll_next = ata_hsm_move(ap, qc, status, 1); |
4026 | else if (has_next) | 4018 | |
4019 | /* another command or interrupt handler | ||
4020 | * may be running at this point. | ||
4021 | */ | ||
4022 | if (poll_next) | ||
4027 | goto fsm_start; | 4023 | goto fsm_start; |
4028 | } | 4024 | } |
4029 | 4025 | ||