提交 a1af3734 编写于 作者: A Albert Lee 提交者: Jeff Garzik

[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: NAlbert Lee <albertcc@tw.ibm.com>
Signed-off-by: NJeff Garzik <jeff@garzik.org>
上级 bb5cb290
......@@ -3986,44 +3986,40 @@ static int ata_hsm_move(struct ata_port *ap, struct ata_queued_cmd *qc,
static void ata_pio_task(void *_data)
{
struct ata_port *ap = _data;
unsigned long timeout;
int has_next;
struct ata_queued_cmd *qc;
u8 status;
int poll_next;
fsm_start:
timeout = 0;
has_next = 1;
WARN_ON(ap->hsm_task_state == HSM_ST_IDLE);
switch (ap->hsm_task_state) {
case HSM_ST_FIRST:
has_next = ata_pio_first_block(ap);
break;
case HSM_ST:
ata_pio_block(ap);
break;
case HSM_ST_LAST:
has_next = ata_pio_complete(ap);
break;
case HSM_ST_POLL:
case HSM_ST_LAST_POLL:
timeout = ata_pio_poll(ap);
break;
case HSM_ST_TMOUT:
case HSM_ST_ERR:
ata_pio_error(ap);
return;
qc = ata_qc_from_tag(ap, ap->active_tag);
WARN_ON(qc == NULL);
default:
BUG();
return;
/*
* This is purely heuristic. This is a fast path.
* Sometimes when we enter, BSY will be cleared in
* a chk-status or two. If not, the drive is probably seeking
* or something. Snooze for a couple msecs, then
* chk-status again. If still busy, queue delayed work.
*/
status = ata_busy_wait(ap, ATA_BUSY, 5);
if (status & ATA_BUSY) {
msleep(2);
status = ata_busy_wait(ap, ATA_BUSY, 10);
if (status & ATA_BUSY) {
ata_port_queue_task(ap, ata_pio_task, ap, ATA_SHORT_PAUSE);
return;
}
}
if (timeout)
ata_port_queue_task(ap, ata_pio_task, ap, timeout);
else if (has_next)
/* move the HSM */
poll_next = ata_hsm_move(ap, qc, status, 1);
/* another command or interrupt handler
* may be running at this point.
*/
if (poll_next)
goto fsm_start;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册