aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/libata-core.c60
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:
3986static void ata_pio_task(void *_data) 3986static 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
3992fsm_start: 3993fsm_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