aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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,