[PATCH][v3] sata_fsl: add workaround for data length mismatch on freescale V2 controller

Subsystems: libata subsystem (serial and parallel ata drivers), the rest

STALE5088d

5 messages, 4 authors, 2012-09-10 · open the first message on its own page

[PATCH][v3] sata_fsl: add workaround for data length mismatch on freescale V2 controller

From: Shaohui Xie <hidden>
Date: 2012-09-07 10:34:15

The freescale V2 SATA controller checks if the received data length matches
the programmed length 'ttl', if not, it assumes that this is an error.
In ATAPI, the 'ttl' is based on max allocation length and not the actual
data transfer length, controller will raise 'DLM' (Data length Mismatch)
error bit in Hstatus register. Along with 'DLM', DE (Device error) and
FE (fatal Error) bits are also set in Hstatus register, 'E' (Internal Error)
bit is set in Serror register and CE (Command Error) and DE (Device error)
registers have the corresponding bit set. In this condition, we need to
clear errors in following way: in the service routine, based on 'DLM' flag,
HCONTROL[27] operation clears Hstatus, CE and DE registers, clear Serror
register.

Signed-off-by: Shaohui Xie <redacted>
Signed-off-by: Anju Bhartiya <redacted>
---
changes for v3:
1. not using uppercase for variable names;
2. remove unnecessary parens;

changes for v2:
1. remove the using of quirk;
2. wrap errata codes in condition;

 drivers/ata/sata_fsl.c |   39 +++++++++++++++++++++++++++++++++++----
 1 files changed, 35 insertions(+), 4 deletions(-)
diff --git a/drivers/ata/sata_fsl.c b/drivers/ata/sata_fsl.c
index d6577b9..9fbab68 100644
--- a/drivers/ata/sata_fsl.c
+++ b/drivers/ata/sata_fsl.c
@@ -143,6 +143,7 @@ enum {
 	    FATAL_ERR_CRC_ERR_RX |
 	    FATAL_ERR_FIFO_OVRFL_TX | FATAL_ERR_FIFO_OVRFL_RX,
 
+	INT_ON_DATA_LENGTH_MISMATCH = (1 << 12),
 	INT_ON_FATAL_ERR = (1 << 5),
 	INT_ON_PHYRDY_CHG = (1 << 4),
 
@@ -1181,25 +1182,55 @@ static void sata_fsl_host_intr(struct ata_port *ap)
 	u32 hstatus, done_mask = 0;
 	struct ata_queued_cmd *qc;
 	u32 SError;
+	u32 tag;
+	u32 status_mask = INT_ON_ERROR;
 
 	hstatus = ioread32(hcr_base + HSTATUS);
 
 	sata_fsl_scr_read(&ap->link, SCR_ERROR, &SError);
 
+	/* Read command completed register */
+	done_mask = ioread32(hcr_base + CC);
+
+	/* Workaround for data length mismatch errata */
+	if (unlikely(hstatus & INT_ON_DATA_LENGTH_MISMATCH)) {
+		for (tag = 0; tag < ATA_MAX_QUEUE; tag++) {
+			qc = ata_qc_from_tag(ap, tag);
+			if (qc && ata_is_atapi(qc->tf.protocol)) {
+				u32 hcontrol;
+#define HCONTROL_CLEAR_ERROR	(1 << 27)
+				/* Set HControl[27] to clear error registers */
+				hcontrol = ioread32(hcr_base + HCONTROL);
+				iowrite32(hcontrol | HCONTROL_CLEAR_ERROR,
+						hcr_base + HCONTROL);
+
+				/* Clear HControl[27] */
+				iowrite32(hcontrol & ~HCONTROL_CLEAR_ERROR,
+						hcr_base + HCONTROL);
+
+				/* Clear SError[E] bit */
+				sata_fsl_scr_write(&ap->link, SCR_ERROR,
+						SError);
+
+				/* Ignore fatal error and device error */
+				status_mask &= ~(INT_ON_SINGL_DEVICE_ERR
+						| INT_ON_FATAL_ERR);
+				break;
+			}
+		}
+	}
+
 	if (unlikely(SError & 0xFFFF0000)) {
 		DPRINTK("serror @host_intr : 0x%x\n", SError);
 		sata_fsl_error_intr(ap);
 	}
 
-	if (unlikely(hstatus & INT_ON_ERROR)) {
+	if (unlikely(hstatus & status_mask)) {
 		DPRINTK("error interrupt!!\n");
 		sata_fsl_error_intr(ap);
 		return;
 	}
 
-	/* Read command completed register */
-	done_mask = ioread32(hcr_base + CC);
-
 	VPRINTK("Status of all queues :\n");
 	VPRINTK("done_mask/CC = 0x%x, CA = 0x%x, CE=0x%x,CQ=0x%x,apqa=0x%x\n",
 		done_mask,
-- 
1.6.4

Re: [PATCH][v3] sata_fsl: add workaround for data length mismatch on freescale V2 controller

From: Kumar Gala <hidden>
Date: 2012-09-07 12:38:07

On Sep 7, 2012, at 5:01 AM, Shaohui Xie wrote:
The freescale V2 SATA controller checks if the received data length =
matches
the programmed length 'ttl', if not, it assumes that this is an error.
In ATAPI, the 'ttl' is based on max allocation length and not the =
actual
data transfer length, controller will raise 'DLM' (Data length =
Mismatch)
error bit in Hstatus register. Along with 'DLM', DE (Device error) and
FE (fatal Error) bits are also set in Hstatus register, 'E' (Internal =
Error)
bit is set in Serror register and CE (Command Error) and DE (Device =
error)
registers have the corresponding bit set. In this condition, we need =
to
clear errors in following way: in the service routine, based on 'DLM' =
flag,
HCONTROL[27] operation clears Hstatus, CE and DE registers, clear =
Serror
quoted hunk
register.
=20
Signed-off-by: Shaohui Xie <redacted>
Signed-off-by: Anju Bhartiya <redacted>
---
changes for v3:
1. not using uppercase for variable names;
2. remove unnecessary parens;
=20
changes for v2:
1. remove the using of quirk;
2. wrap errata codes in condition;
=20
drivers/ata/sata_fsl.c |   39 +++++++++++++++++++++++++++++++++++----
1 files changed, 35 insertions(+), 4 deletions(-)
=20
diff --git a/drivers/ata/sata_fsl.c b/drivers/ata/sata_fsl.c
index d6577b9..9fbab68 100644
--- a/drivers/ata/sata_fsl.c
+++ b/drivers/ata/sata_fsl.c
@@ -143,6 +143,7 @@ enum {
	    FATAL_ERR_CRC_ERR_RX |
	    FATAL_ERR_FIFO_OVRFL_TX | FATAL_ERR_FIFO_OVRFL_RX,
=20
+	INT_ON_DATA_LENGTH_MISMATCH =3D (1 << 12),
	INT_ON_FATAL_ERR =3D (1 << 5),
	INT_ON_PHYRDY_CHG =3D (1 << 4),
=20
@@ -1181,25 +1182,55 @@ static void sata_fsl_host_intr(struct ata_port =
*ap)
	u32 hstatus, done_mask =3D 0;
	struct ata_queued_cmd *qc;
	u32 SError;
+	u32 tag;
+	u32 status_mask =3D INT_ON_ERROR;
=20
	hstatus =3D ioread32(hcr_base + HSTATUS);
=20
	sata_fsl_scr_read(&ap->link, SCR_ERROR, &SError);
=20
+	/* Read command completed register */
+	done_mask =3D ioread32(hcr_base + CC);
+
+	/* Workaround for data length mismatch errata */
+	if (unlikely(hstatus & INT_ON_DATA_LENGTH_MISMATCH)) {
+		for (tag =3D 0; tag < ATA_MAX_QUEUE; tag++) {
+			qc =3D ata_qc_from_tag(ap, tag);
+			if (qc && ata_is_atapi(qc->tf.protocol)) {
+				u32 hcontrol;
+#define HCONTROL_CLEAR_ERROR	(1 << 27)
shouldn't we have this #define be part of the enum that the other =
HCONTROL_ bits/flags are part of?
+				/* Set HControl[27] to clear error =
registers */
+				hcontrol =3D ioread32(hcr_base + =
HCONTROL);
+				iowrite32(hcontrol | =
HCONTROL_CLEAR_ERROR,
+						hcr_base + HCONTROL);
+
+				/* Clear HControl[27] */
+				iowrite32(hcontrol & =
~HCONTROL_CLEAR_ERROR,
+						hcr_base + HCONTROL);
+
+				/* Clear SError[E] bit */
+				sata_fsl_scr_write(&ap->link, SCR_ERROR,
+						SError);
+
+				/* Ignore fatal error and device error =
*/
+				status_mask &=3D =
~(INT_ON_SINGL_DEVICE_ERR
+						| INT_ON_FATAL_ERR);
+				break;
+			}
+		}
+	}
+
	if (unlikely(SError & 0xFFFF0000)) {
		DPRINTK("serror @host_intr : 0x%x\n", SError);
		sata_fsl_error_intr(ap);
	}
=20
-	if (unlikely(hstatus & INT_ON_ERROR)) {
+	if (unlikely(hstatus & status_mask)) {
		DPRINTK("error interrupt!!\n");
		sata_fsl_error_intr(ap);
		return;
	}
=20
-	/* Read command completed register */
-	done_mask =3D ioread32(hcr_base + CC);
-
	VPRINTK("Status of all queues :\n");
	VPRINTK("done_mask/CC =3D 0x%x, CA =3D 0x%x, =
CE=3D0x%x,CQ=3D0x%x,apqa=3D0x%x\n",
		done_mask,
--=20
1.6.4
=20
=20
--
To unsubscribe from this list: send the line "unsubscribe =
linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

RE: [PATCH][v3] sata_fsl: add workaround for data length mismatch on freescale V2 controller

From: Xie Shaohui-B21989 <hidden>
Date: 2012-09-10 02:53:53

quoted
+	/* Workaround for data length mismatch errata */
+	if (unlikely(hstatus & INT_ON_DATA_LENGTH_MISMATCH)) {
+		for (tag =3D 0; tag < ATA_MAX_QUEUE; tag++) {
+			qc =3D ata_qc_from_tag(ap, tag);
+			if (qc && ata_is_atapi(qc->tf.protocol)) {
+				u32 hcontrol;
+#define HCONTROL_CLEAR_ERROR	(1 << 27)
=20
shouldn't we have this #define be part of the enum that the other
HCONTROL_ bits/flags are part of?
[S.H] do you mean this?

#ifdef SATA_FSL_XXX_ERRATUAM
#define HCONTROL_CLEAR_ERROR	(1 << 27)
#endif

Then we need to decide where to put "#define SATA_FSL_XXX_ERRATUAM".

It's only a readable definition of a register bit which avoiding magic numb=
er.


Best Regards,=20
Shaohui Xie

Re: [PATCH][v3] sata_fsl: add workaround for data length mismatch on freescale V2 controller

From: Sergei Shtylyov <hidden>
Date: 2012-09-10 10:23:00

Hello.

On 10-09-2012 6:53, Xie Shaohui-B21989 wrote:
quoted
quoted
+	/* Workaround for data length mismatch errata */
+	if (unlikely(hstatus & INT_ON_DATA_LENGTH_MISMATCH)) {
+		for (tag = 0; tag < ATA_MAX_QUEUE; tag++) {
+			qc = ata_qc_from_tag(ap, tag);
+			if (qc && ata_is_atapi(qc->tf.protocol)) {
+				u32 hcontrol;
+#define HCONTROL_CLEAR_ERROR	(1 << 27)
quoted
shouldn't we have this #define be part of the enum that the other
HCONTROL_ bits/flags are part of?
[S.H] do you mean this?
    Apparently not. He said *enum*, not #define.
#ifdef SATA_FSL_XXX_ERRATUAM
    We don't need that at all.
#define HCONTROL_CLEAR_ERROR	(1 << 27)
#endif
MBR, Sergei

RE: [PATCH][v3] sata_fsl: add workaround for data length mismatch on freescale V2 controller

From: Xie Shaohui-B21989 <hidden>
Date: 2012-09-10 10:46:08

-----Original Message-----
From: Sergei Shtylyov [mailto:sshtylyov@mvista.com]
Sent: Monday, September 10, 2012 6:22 PM
To: Xie Shaohui-B21989
Cc: Kumar Gala; jgarzik@pobox.com; linux-ide@vger.kernel.org; linuxppc-
dev@lists.ozlabs.org; linux-kernel@vger.kernel.org; Bhartiya Anju-B07263
Subject: Re: [PATCH][v3] sata_fsl: add workaround for data length
mismatch on freescale V2 controller
=20
Hello.
=20
On 10-09-2012 6:53, Xie Shaohui-B21989 wrote:
=20
quoted
quoted
quoted
+	/* Workaround for data length mismatch errata */
+	if (unlikely(hstatus & INT_ON_DATA_LENGTH_MISMATCH)) {
+		for (tag =3D 0; tag < ATA_MAX_QUEUE; tag++) {
+			qc =3D ata_qc_from_tag(ap, tag);
+			if (qc && ata_is_atapi(qc->tf.protocol)) {
+				u32 hcontrol;
+#define HCONTROL_CLEAR_ERROR	(1 << 27)
=20
quoted
quoted
shouldn't we have this #define be part of the enum that the other
HCONTROL_ bits/flags are part of?
=20
quoted
[S.H] do you mean this?
=20
    Apparently not. He said *enum*, not #define.
[S.H] OK. Thank you for the clarification.


Best Regards,=20
Shaohui Xie
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help