All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH/RFC] libata-dev: handle ERR=1 DRQ=1
@ 2006-03-21 11:39 Albert Lee
  2006-03-21 17:35 ` Jeff Garzik
  0 siblings, 1 reply; 11+ messages in thread
From: Albert Lee @ 2006-03-21 11:39 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: IDE Linux, Doug Maxey

handle ERR=1 DRQ=1 for PIO protocol

Signed-off-by: Albert Lee <albertcc@tw.ibm.com>
---

Some PIO read commands might set DRQ=1 alone with ERR=1.
Under such situation, the data block should be transferred even if err=1.

This patch adds extra logic to HSM_ST_ERR to handle the required
data transfer.

BTW, also found the following work in progress:
"Disable Data Transfer after Error Detection"
http://t13.org/docs2006/dt1825Lr3-DDT_TR.pdf
If this feature is turned on, then DRQ will be guaranteed 0 when ERR=1
which would simplify the PIO error handling.

Patch against the irq-pio branch.
Need your review and advice, thanks.

Albert


--- irq-pio-printk/drivers/scsi/libata-core.c	2006-03-21 17:55:35.000000000 +0800
+++ irq-pio-err/drivers/scsi/libata-core.c	2006-03-21 19:09:38.000000000 +0800
@@ -3684,6 +3684,46 @@ fsm_start:
 			printk(KERN_ERR "ata%u: command error, drv_stat 0x%x\n",
 			       ap->id, status);
 
+		/* handle ERR=1 DRQ=1 */
+		if ((status & ATA_ERR) && (status & ATA_DRQ)) {
+			/* ERR=1 DRQ=1 is only possible for reads (READ PIO
+			 * and READ MULTI, etc). For writes, DRQ=1 doesn't
+			 * make sense since the data block has been
+			 * transferred to the device.
+			 */
+			if ((qc->tf.protocol == ATA_PROT_PIO) &&
+			    !(qc->tf.flags & ATA_TFLAG_WRITE)) {
+				/* Transfer the corrupted data */
+				ata_pio_sectors(qc);
+
+				/* FIXME: contents of taskfile registers
+				 * undefined after the data xfer.
+				 * Maybe we should call ->tf_read()
+				 * and backup the taskfile somewhere?
+				 * Otherwise ata_gen_fixed_sense() won't
+				 * get needed information.
+				 */
+
+				/* FIXME: The spec said if "correctable"
+				 * data error, subsequent blocks will
+				 * be transferred. Isn't the command
+				 * stopped if ERR is set?
+				 */
+
+				ata_altstatus(ap); /* flush */
+				status = ata_chk_status(ap);
+
+				printk(KERN_ERR "ata%u: ERR=1 DRQ=1 error"
+				       " block transferred, drv_stat 0x%x\n",
+				       ap->id, status);
+			} else
+				/* Low possibility for other protocols
+				 * being ERR=1 DRQ=1. Maybe device error?
+				 */
+				printk(KERN_ERR "ata%u: ERR=1 DRQ=1\n",
+				       ap->id);
+		}
+
 		/* make sure qc->err_mask is available to
 		 * know what's wrong and recover
 		 */



^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2006-03-29 22:23 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-03-21 11:39 [PATCH/RFC] libata-dev: handle ERR=1 DRQ=1 Albert Lee
2006-03-21 17:35 ` Jeff Garzik
2006-03-21 17:43   ` Eric D. Mudama
2006-03-23  8:04     ` [PATCH 1/2] libata-dev: irq-pio minor fixes Albert Lee
2006-03-23  8:18       ` Jeff Garzik
2006-03-24 17:28       ` Jeff Garzik
2006-03-25 10:07         ` [PATCH 1/3] libata-dev: irq-pio minor fixes (respin) Albert Lee
2006-03-29 22:22           ` Jeff Garzik
2006-03-25 10:11         ` [PATCH 2/3] libata-dev: fix the device err check sequence (respin) Albert Lee
2006-03-25 10:18         ` [PATCH 3/3] libata-dev: wait idle after reading the last data block Albert Lee
2006-03-23  8:26   ` [PATCH/RFC 2/2] libata-dev: fix the device err check sequence Albert Lee

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.