Skip to contentSkip to conversation

libata PIO error handling fix

PATCH New Albert Lee 1 participant 1 message Dec 6, 2004

Subsystems (2)
lore
Share & tools
lore

Albert Lee

author
#0 lore raw

PATCH 1/1 libata PIO error handling fix

Hi, Jeff:

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

After checking the log, it shows that MODE_SELECT causes 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 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.

Albert

------------------------------------------------------------------------------------

drivers/scsi/libata-core.c 2004-12-02 18:57:48.719220063 +0800 renamed from drivers/scsi/libata-core.c 2004-11-30 12:52:28.000000000 +0800 +9 -10
diff -Nru libata-dev-2.6-ori/drivers/scsi/libata-core.c libata-dev-2.6/drivers/scsi/libata-core.c
@@ -2399,6 +2399,9 @@
  unsigned long timeout = 0;
 
  switch (ap->pio_task_state) {
+ case PIO_ST_IDLE:
+  return;
+
  case PIO_ST:
   ata_pio_block(ap);
   break;
@@ -2415,18 +2418,14 @@
  case PIO_ST_TMOUT:
  case PIO_ST_ERR:
   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)
-   queue_delayed_work(ata_wq, &ap->pio_task,
-        timeout);
-  else
-   queue_work(ata_wq, &ap->pio_task);
- }
+ if (timeout)
+  queue_delayed_work(ata_wq, &ap->pio_task,
+       timeout);
+ else
+  queue_work(ata_wq, &ap->pio_task);
 }
 
 static void atapi_request_sense(struct ata_port *ap, struct ata_device *dev,
drivers/scsi/libata-core.c +9 -10
diff -Nru libata-dev-2.6-ori/drivers/scsi/libata-core.c libata-dev-2.6/drivers/scsi/libata-core.c
@@ -2399,6 +2399,9 @@
 	unsigned long timeout = 0;
 
 	switch (ap->pio_task_state) {
+	case PIO_ST_IDLE:
+		return;
+
 	case PIO_ST:
 		ata_pio_block(ap);
 		break;
@@ -2415,18 +2418,14 @@
 	case PIO_ST_TMOUT:
 	case PIO_ST_ERR:
 		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)
-			queue_delayed_work(ata_wq, &ap->pio_task,
-					   timeout);
-		else
-			queue_work(ata_wq, &ap->pio_task);
-	}
+	if (timeout)
+		queue_delayed_work(ata_wq, &ap->pio_task,
+				   timeout);
+	else
+		queue_work(ata_wq, &ap->pio_task);
 }
 
 static void atapi_request_sense(struct ata_port *ap, struct ata_device *dev,
Dec  2 15:42:54 p4ht-s kernel: ata_scsi_dump_cdb: CDB (1:0,0,0) 35 00 00 00 00 00 00 00 00
Dec  2 15:42:54 p4ht-s kernel: ata_scsi_translate: ENTER
Dec  2 15:42:54 p4ht-s kernel: ata_dev_select: ENTER, ata1: device 0, wait 1
Dec  2 15:42:54 p4ht-s kernel: ata_tf_load_pio: feat 0x0 nsect 0x0 lba 0x0 0x0 0x20
Dec  2 15:42:54 p4ht-s kernel: ata_tf_load_pio: device 0xA0
Dec  2 15:42:54 p4ht-s kernel: ata_exec_command_pio: ata1: cmd 0xA0
Dec  2 15:42:54 p4ht-s kernel: ata_scsi_translate: EXIT
Dec  2 15:42:54 p4ht-s kernel: atapi_packet_task: busy wait
Dec  2 15:42:54 p4ht-s kernel: atapi_packet_task: send cdb
Dec  2 15:42:54 p4ht-s kernel: ata_host_intr: ata1: protocol 6 (dev_stat 0x50)
Dec  2 15:42:54 p4ht-s kernel: ata_qc_complete: EXIT
Dec  2 15:42:54 p4ht-s kernel: ata_scsi_dump_cdb: CDB (1:0,0,0) 00 00 00 00 00 00 00 00 00
Dec  2 15:42:54 p4ht-s kernel: ata_scsi_translate: ENTER
Dec  2 15:42:54 p4ht-s kernel: ata_dev_select: ENTER, ata1: device 0, wait 1
Dec  2 15:42:54 p4ht-s kernel: ata_tf_load_pio: feat 0x0 nsect 0x0 lba 0x0 0x0 0x20
Dec  2 15:42:54 p4ht-s kernel: ata_tf_load_pio: device 0xA0
Dec  2 15:42:54 p4ht-s kernel: ata_exec_command_pio: ata1: cmd 0xA0
Dec  2 15:42:54 p4ht-s kernel: ata_scsi_translate: EXIT
Dec  2 15:42:54 p4ht-s kernel: atapi_packet_task: busy wait
Dec  2 15:42:54 p4ht-s kernel: atapi_packet_task: send cdb
Dec  2 15:42:54 p4ht-s kernel: ata_host_intr: ata1: protocol 6 (dev_stat 0x50)
Dec  2 15:42:54 p4ht-s kernel: ata_qc_complete: EXIT
Dec  2 15:42:54 p4ht-s kernel: ata_scsi_dump_cdb: CDB (1:0,0,0) 55 10 00 00 00 00 00 00 10
Dec  2 15:42:54 p4ht-s kernel: ata_scsi_translate: ENTER
Dec  2 15:42:54 p4ht-s kernel: atapi_xlat: direction: write
Dec  2 15:42:54 p4ht-s kernel: ata_sg_setup: ENTER, ata1
Dec  2 15:42:54 p4ht-s kernel: ata_sg_setup: 1 sg elements mapped
Dec  2 15:42:54 p4ht-s kernel: ata_fill_sg: PRD[0] = (0x10922000, 0x10)
Dec  2 15:42:54 p4ht-s kernel: ata_dev_select: ENTER, ata1: device 0, wait 1
Dec  2 15:42:54 p4ht-s kernel: ata_tf_load_pio: feat 0x0 nsect 0x0 lba 0x0 0x0 0x20
Dec  2 15:42:54 p4ht-s kernel: ata_tf_load_pio: device 0xA0
Dec  2 15:42:54 p4ht-s kernel: ata_exec_command_pio: ata1: cmd 0xA0
Dec  2 15:42:54 p4ht-s kernel: ata_scsi_translate: EXIT
Dec  2 15:42:54 p4ht-s kernel: atapi_packet_task: busy wait
Dec  2 15:42:54 p4ht-s kernel: atapi_packet_task: send cdb
Dec  2 15:42:54 p4ht-s kernel: ata_pio_task: pio_task_state: 4
Dec  2 15:42:54 p4ht-s kernel: __atapi_pio_bytes: 16 bytes data write
Dec  2 15:42:54 p4ht-s kernel: ata_pio_task: Exit
Dec  2 15:42:54 p4ht-s kernel: ata_pio_task: pio_task_state: 5
Dec  2 15:42:54 p4ht-s kernel: ata_pio_complete: Enter
Dec  2 15:42:54 p4ht-s kernel: ata_pio_complete: Exit with dev error, drv_stat [51] 
                               <= ata_pio_task exits without handling error from ata_pio_complete
Dec  2 15:42:54 p4ht-s kernel: ata_pio_task: Exit