Commit 623b57b3 authored by Albert Lee's avatar Albert Lee Committed by Jeff Garzik

[libata] PIO error handling improvement

Tested burning CD-RW with libata-dev-2.6 and cdrecord:
1. ATAPI DMA mode - tested OK
2. ATAPI PIO mode - test failed when cdrecord finishes burning and issues MODE_SELECT to the device.

 After checking the log, it showed that MODE_SELECT caused ata_pio_complete() to return error.
However, the error is not handled by ata_pio_task().

Attached please find the patch for ata_pio_task() error handling for your review.
(The patch is against the libata-dev-2.6 tree. )

Changes in the patch:
1. End the PIO task when PIO_ST_IDLE state is entered
2. End the PIO task after PIO_ST_TMOUT and PIO_ST_ERR state handled by ata_pio_error()
3. Remove the first "if" statement to handle the error condition returned from 
   ata_pio_block(), ata_pio_complete() and ata_pio_poll().

Change #2 is not so necessary since ata_pio_error() will put the cmd to  PIO_ST_IDLE state
after the error condition is handled. The change just saves a function call to queue_work().

Tested OK on on my machine with pdc20275 and ASUS CD-RW drive.
Signed-off-by: default avatarAlbert Lee <albertcc@tw.ibm.com>
parent 652f8d65
...@@ -2369,6 +2369,9 @@ static void ata_pio_task(void *_data) ...@@ -2369,6 +2369,9 @@ static void ata_pio_task(void *_data)
unsigned long timeout = 0; unsigned long timeout = 0;
switch (ap->pio_task_state) { switch (ap->pio_task_state) {
case PIO_ST_IDLE:
return;
case PIO_ST: case PIO_ST:
ata_pio_block(ap); ata_pio_block(ap);
break; break;
...@@ -2385,18 +2388,14 @@ static void ata_pio_task(void *_data) ...@@ -2385,18 +2388,14 @@ static void ata_pio_task(void *_data)
case PIO_ST_TMOUT: case PIO_ST_TMOUT:
case PIO_ST_ERR: case PIO_ST_ERR:
ata_pio_error(ap); ata_pio_error(ap);
break; return;
} }
if ((ap->pio_task_state != PIO_ST_IDLE) &&
(ap->pio_task_state != PIO_ST_TMOUT) &&
(ap->pio_task_state != PIO_ST_ERR)) {
if (timeout) if (timeout)
queue_delayed_work(ata_wq, &ap->pio_task, queue_delayed_work(ata_wq, &ap->pio_task,
timeout); timeout);
else else
queue_work(ata_wq, &ap->pio_task); queue_work(ata_wq, &ap->pio_task);
}
} }
static void atapi_request_sense(struct ata_port *ap, struct ata_device *dev, static void atapi_request_sense(struct ata_port *ap, struct ata_device *dev,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment