aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata
diff options
context:
space:
mode:
authorShaohui Xie <Shaohui.Xie@freescale.com>2012-09-10 22:48:53 -0400
committerJeff Garzik <jgarzik@redhat.com>2012-09-13 01:09:19 -0400
commit100f586bd0959fe0e52b8a0b8cb49a3df1c6b044 (patch)
tree8017ee731f9940ddb081883fb45e6fd9ee874aa2 /drivers/ata
parent65fe1f0f66a57380229a4ced844188103135f37b (diff)
sata_fsl: add workaround for data length mismatch on freescale V2 controller
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 <Shaohui.Xie@freescale.com> Signed-off-by: Anju Bhartiya <Anju.Bhartiya@freescale.com> Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'drivers/ata')
-rw-r--r--drivers/ata/sata_fsl.c39
1 files changed, 35 insertions, 4 deletions
diff --git a/drivers/ata/sata_fsl.c b/drivers/ata/sata_fsl.c
index d6577b93bee3..124b2c1d9c0b 100644
--- a/drivers/ata/sata_fsl.c
+++ b/drivers/ata/sata_fsl.c
@@ -123,6 +123,7 @@ enum {
123 ONLINE = (1 << 31), 123 ONLINE = (1 << 31),
124 GOING_OFFLINE = (1 << 30), 124 GOING_OFFLINE = (1 << 30),
125 BIST_ERR = (1 << 29), 125 BIST_ERR = (1 << 29),
126 CLEAR_ERROR = (1 << 27),
126 127
127 FATAL_ERR_HC_MASTER_ERR = (1 << 18), 128 FATAL_ERR_HC_MASTER_ERR = (1 << 18),
128 FATAL_ERR_PARITY_ERR_TX = (1 << 17), 129 FATAL_ERR_PARITY_ERR_TX = (1 << 17),
@@ -143,6 +144,7 @@ enum {
143 FATAL_ERR_CRC_ERR_RX | 144 FATAL_ERR_CRC_ERR_RX |
144 FATAL_ERR_FIFO_OVRFL_TX | FATAL_ERR_FIFO_OVRFL_RX, 145 FATAL_ERR_FIFO_OVRFL_TX | FATAL_ERR_FIFO_OVRFL_RX,
145 146
147 INT_ON_DATA_LENGTH_MISMATCH = (1 << 12),
146 INT_ON_FATAL_ERR = (1 << 5), 148 INT_ON_FATAL_ERR = (1 << 5),
147 INT_ON_PHYRDY_CHG = (1 << 4), 149 INT_ON_PHYRDY_CHG = (1 << 4),
148 150
@@ -1181,25 +1183,54 @@ static void sata_fsl_host_intr(struct ata_port *ap)
1181 u32 hstatus, done_mask = 0; 1183 u32 hstatus, done_mask = 0;
1182 struct ata_queued_cmd *qc; 1184 struct ata_queued_cmd *qc;
1183 u32 SError; 1185 u32 SError;
1186 u32 tag;
1187 u32 status_mask = INT_ON_ERROR;
1184 1188
1185 hstatus = ioread32(hcr_base + HSTATUS); 1189 hstatus = ioread32(hcr_base + HSTATUS);
1186 1190
1187 sata_fsl_scr_read(&ap->link, SCR_ERROR, &SError); 1191 sata_fsl_scr_read(&ap->link, SCR_ERROR, &SError);
1188 1192
1193 /* Read command completed register */
1194 done_mask = ioread32(hcr_base + CC);
1195
1196 /* Workaround for data length mismatch errata */
1197 if (unlikely(hstatus & INT_ON_DATA_LENGTH_MISMATCH)) {
1198 for (tag = 0; tag < ATA_MAX_QUEUE; tag++) {
1199 qc = ata_qc_from_tag(ap, tag);
1200 if (qc && ata_is_atapi(qc->tf.protocol)) {
1201 u32 hcontrol;
1202 /* Set HControl[27] to clear error registers */
1203 hcontrol = ioread32(hcr_base + HCONTROL);
1204 iowrite32(hcontrol | CLEAR_ERROR,
1205 hcr_base + HCONTROL);
1206
1207 /* Clear HControl[27] */
1208 iowrite32(hcontrol & ~CLEAR_ERROR,
1209 hcr_base + HCONTROL);
1210
1211 /* Clear SError[E] bit */
1212 sata_fsl_scr_write(&ap->link, SCR_ERROR,
1213 SError);
1214
1215 /* Ignore fatal error and device error */
1216 status_mask &= ~(INT_ON_SINGL_DEVICE_ERR
1217 | INT_ON_FATAL_ERR);
1218 break;
1219 }
1220 }
1221 }
1222
1189 if (unlikely(SError & 0xFFFF0000)) { 1223 if (unlikely(SError & 0xFFFF0000)) {
1190 DPRINTK("serror @host_intr : 0x%x\n", SError); 1224 DPRINTK("serror @host_intr : 0x%x\n", SError);
1191 sata_fsl_error_intr(ap); 1225 sata_fsl_error_intr(ap);
1192 } 1226 }
1193 1227
1194 if (unlikely(hstatus & INT_ON_ERROR)) { 1228 if (unlikely(hstatus & status_mask)) {
1195 DPRINTK("error interrupt!!\n"); 1229 DPRINTK("error interrupt!!\n");
1196 sata_fsl_error_intr(ap); 1230 sata_fsl_error_intr(ap);
1197 return; 1231 return;
1198 } 1232 }
1199 1233
1200 /* Read command completed register */
1201 done_mask = ioread32(hcr_base + CC);
1202
1203 VPRINTK("Status of all queues :\n"); 1234 VPRINTK("Status of all queues :\n");
1204 VPRINTK("done_mask/CC = 0x%x, CA = 0x%x, CE=0x%x,CQ=0x%x,apqa=0x%x\n", 1235 VPRINTK("done_mask/CC = 0x%x, CA = 0x%x, CE=0x%x,CQ=0x%x,apqa=0x%x\n",
1205 done_mask, 1236 done_mask,