diff options
Diffstat (limited to 'drivers/ata/libata-sff.c')
-rw-r--r-- | drivers/ata/libata-sff.c | 145 |
1 files changed, 121 insertions, 24 deletions
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index 3c2d2289f85e..c0908c225483 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c | |||
@@ -247,7 +247,7 @@ u8 ata_sff_check_status(struct ata_port *ap) | |||
247 | * LOCKING: | 247 | * LOCKING: |
248 | * Inherited from caller. | 248 | * Inherited from caller. |
249 | */ | 249 | */ |
250 | u8 ata_sff_altstatus(struct ata_port *ap) | 250 | static u8 ata_sff_altstatus(struct ata_port *ap) |
251 | { | 251 | { |
252 | if (ap->ops->sff_check_altstatus) | 252 | if (ap->ops->sff_check_altstatus) |
253 | return ap->ops->sff_check_altstatus(ap); | 253 | return ap->ops->sff_check_altstatus(ap); |
@@ -256,6 +256,93 @@ u8 ata_sff_altstatus(struct ata_port *ap) | |||
256 | } | 256 | } |
257 | 257 | ||
258 | /** | 258 | /** |
259 | * ata_sff_irq_status - Check if the device is busy | ||
260 | * @ap: port where the device is | ||
261 | * | ||
262 | * Determine if the port is currently busy. Uses altstatus | ||
263 | * if available in order to avoid clearing shared IRQ status | ||
264 | * when finding an IRQ source. Non ctl capable devices don't | ||
265 | * share interrupt lines fortunately for us. | ||
266 | * | ||
267 | * LOCKING: | ||
268 | * Inherited from caller. | ||
269 | */ | ||
270 | static u8 ata_sff_irq_status(struct ata_port *ap) | ||
271 | { | ||
272 | u8 status; | ||
273 | |||
274 | if (ap->ops->sff_check_altstatus || ap->ioaddr.altstatus_addr) { | ||
275 | status = ata_sff_altstatus(ap); | ||
276 | /* Not us: We are busy */ | ||
277 | if (status & ATA_BUSY) | ||
278 | return status; | ||
279 | } | ||
280 | /* Clear INTRQ latch */ | ||
281 | status = ap->ops->sff_check_status(ap); | ||
282 | return status; | ||
283 | } | ||
284 | |||
285 | /** | ||
286 | * ata_sff_sync - Flush writes | ||
287 | * @ap: Port to wait for. | ||
288 | * | ||
289 | * CAUTION: | ||
290 | * If we have an mmio device with no ctl and no altstatus | ||
291 | * method this will fail. No such devices are known to exist. | ||
292 | * | ||
293 | * LOCKING: | ||
294 | * Inherited from caller. | ||
295 | */ | ||
296 | |||
297 | static void ata_sff_sync(struct ata_port *ap) | ||
298 | { | ||
299 | if (ap->ops->sff_check_altstatus) | ||
300 | ap->ops->sff_check_altstatus(ap); | ||
301 | else if (ap->ioaddr.altstatus_addr) | ||
302 | ioread8(ap->ioaddr.altstatus_addr); | ||
303 | } | ||
304 | |||
305 | /** | ||
306 | * ata_sff_pause - Flush writes and wait 400nS | ||
307 | * @ap: Port to pause for. | ||
308 | * | ||
309 | * CAUTION: | ||
310 | * If we have an mmio device with no ctl and no altstatus | ||
311 | * method this will fail. No such devices are known to exist. | ||
312 | * | ||
313 | * LOCKING: | ||
314 | * Inherited from caller. | ||
315 | */ | ||
316 | |||
317 | void ata_sff_pause(struct ata_port *ap) | ||
318 | { | ||
319 | ata_sff_sync(ap); | ||
320 | ndelay(400); | ||
321 | } | ||
322 | |||
323 | /** | ||
324 | * ata_sff_dma_pause - Pause before commencing DMA | ||
325 | * @ap: Port to pause for. | ||
326 | * | ||
327 | * Perform I/O fencing and ensure sufficient cycle delays occur | ||
328 | * for the HDMA1:0 transition | ||
329 | */ | ||
330 | |||
331 | void ata_sff_dma_pause(struct ata_port *ap) | ||
332 | { | ||
333 | if (ap->ops->sff_check_altstatus || ap->ioaddr.altstatus_addr) { | ||
334 | /* An altstatus read will cause the needed delay without | ||
335 | messing up the IRQ status */ | ||
336 | ata_sff_altstatus(ap); | ||
337 | return; | ||
338 | } | ||
339 | /* There are no DMA controllers without ctl. BUG here to ensure | ||
340 | we never violate the HDMA1:0 transition timing and risk | ||
341 | corruption. */ | ||
342 | BUG(); | ||
343 | } | ||
344 | |||
345 | /** | ||
259 | * ata_sff_busy_sleep - sleep until BSY clears, or timeout | 346 | * ata_sff_busy_sleep - sleep until BSY clears, or timeout |
260 | * @ap: port containing status register to be polled | 347 | * @ap: port containing status register to be polled |
261 | * @tmout_pat: impatience timeout | 348 | * @tmout_pat: impatience timeout |
@@ -742,7 +829,7 @@ static void ata_pio_sectors(struct ata_queued_cmd *qc) | |||
742 | } else | 829 | } else |
743 | ata_pio_sector(qc); | 830 | ata_pio_sector(qc); |
744 | 831 | ||
745 | ata_sff_altstatus(qc->ap); /* flush */ | 832 | ata_sff_sync(qc->ap); /* flush */ |
746 | } | 833 | } |
747 | 834 | ||
748 | /** | 835 | /** |
@@ -763,8 +850,9 @@ static void atapi_send_cdb(struct ata_port *ap, struct ata_queued_cmd *qc) | |||
763 | WARN_ON(qc->dev->cdb_len < 12); | 850 | WARN_ON(qc->dev->cdb_len < 12); |
764 | 851 | ||
765 | ap->ops->sff_data_xfer(qc->dev, qc->cdb, qc->dev->cdb_len, 1); | 852 | ap->ops->sff_data_xfer(qc->dev, qc->cdb, qc->dev->cdb_len, 1); |
766 | ata_sff_altstatus(ap); /* flush */ | 853 | ata_sff_sync(ap); |
767 | 854 | /* FIXME: If the CDB is for DMA do we need to do the transition delay | |
855 | or is bmdma_start guaranteed to do it ? */ | ||
768 | switch (qc->tf.protocol) { | 856 | switch (qc->tf.protocol) { |
769 | case ATAPI_PROT_PIO: | 857 | case ATAPI_PROT_PIO: |
770 | ap->hsm_task_state = HSM_ST; | 858 | ap->hsm_task_state = HSM_ST; |
@@ -905,7 +993,7 @@ static void atapi_pio_bytes(struct ata_queued_cmd *qc) | |||
905 | 993 | ||
906 | if (unlikely(__atapi_pio_bytes(qc, bytes))) | 994 | if (unlikely(__atapi_pio_bytes(qc, bytes))) |
907 | goto err_out; | 995 | goto err_out; |
908 | ata_sff_altstatus(ap); /* flush */ | 996 | ata_sff_sync(ap); /* flush */ |
909 | 997 | ||
910 | return; | 998 | return; |
911 | 999 | ||
@@ -1006,6 +1094,7 @@ static void ata_hsm_qc_complete(struct ata_queued_cmd *qc, int in_wq) | |||
1006 | int ata_sff_hsm_move(struct ata_port *ap, struct ata_queued_cmd *qc, | 1094 | int ata_sff_hsm_move(struct ata_port *ap, struct ata_queued_cmd *qc, |
1007 | u8 status, int in_wq) | 1095 | u8 status, int in_wq) |
1008 | { | 1096 | { |
1097 | struct ata_eh_info *ehi = &ap->link.eh_info; | ||
1009 | unsigned long flags = 0; | 1098 | unsigned long flags = 0; |
1010 | int poll_next; | 1099 | int poll_next; |
1011 | 1100 | ||
@@ -1037,9 +1126,12 @@ fsm_start: | |||
1037 | if (likely(status & (ATA_ERR | ATA_DF))) | 1126 | if (likely(status & (ATA_ERR | ATA_DF))) |
1038 | /* device stops HSM for abort/error */ | 1127 | /* device stops HSM for abort/error */ |
1039 | qc->err_mask |= AC_ERR_DEV; | 1128 | qc->err_mask |= AC_ERR_DEV; |
1040 | else | 1129 | else { |
1041 | /* HSM violation. Let EH handle this */ | 1130 | /* HSM violation. Let EH handle this */ |
1131 | ata_ehi_push_desc(ehi, | ||
1132 | "ST_FIRST: !(DRQ|ERR|DF)"); | ||
1042 | qc->err_mask |= AC_ERR_HSM; | 1133 | qc->err_mask |= AC_ERR_HSM; |
1134 | } | ||
1043 | 1135 | ||
1044 | ap->hsm_task_state = HSM_ST_ERR; | 1136 | ap->hsm_task_state = HSM_ST_ERR; |
1045 | goto fsm_start; | 1137 | goto fsm_start; |
@@ -1058,9 +1150,9 @@ fsm_start: | |||
1058 | * the CDB. | 1150 | * the CDB. |
1059 | */ | 1151 | */ |
1060 | if (!(qc->dev->horkage & ATA_HORKAGE_STUCK_ERR)) { | 1152 | if (!(qc->dev->horkage & ATA_HORKAGE_STUCK_ERR)) { |
1061 | ata_port_printk(ap, KERN_WARNING, | 1153 | ata_ehi_push_desc(ehi, "ST_FIRST: " |
1062 | "DRQ=1 with device error, " | 1154 | "DRQ=1 with device error, " |
1063 | "dev_stat 0x%X\n", status); | 1155 | "dev_stat 0x%X", status); |
1064 | qc->err_mask |= AC_ERR_HSM; | 1156 | qc->err_mask |= AC_ERR_HSM; |
1065 | ap->hsm_task_state = HSM_ST_ERR; | 1157 | ap->hsm_task_state = HSM_ST_ERR; |
1066 | goto fsm_start; | 1158 | goto fsm_start; |
@@ -1117,9 +1209,9 @@ fsm_start: | |||
1117 | * let the EH abort the command or reset the device. | 1209 | * let the EH abort the command or reset the device. |
1118 | */ | 1210 | */ |
1119 | if (unlikely(status & (ATA_ERR | ATA_DF))) { | 1211 | if (unlikely(status & (ATA_ERR | ATA_DF))) { |
1120 | ata_port_printk(ap, KERN_WARNING, "DRQ=1 with " | 1212 | ata_ehi_push_desc(ehi, "ST-ATAPI: " |
1121 | "device error, dev_stat 0x%X\n", | 1213 | "DRQ=1 with device error, " |
1122 | status); | 1214 | "dev_stat 0x%X", status); |
1123 | qc->err_mask |= AC_ERR_HSM; | 1215 | qc->err_mask |= AC_ERR_HSM; |
1124 | ap->hsm_task_state = HSM_ST_ERR; | 1216 | ap->hsm_task_state = HSM_ST_ERR; |
1125 | goto fsm_start; | 1217 | goto fsm_start; |
@@ -1138,13 +1230,17 @@ fsm_start: | |||
1138 | if (likely(status & (ATA_ERR | ATA_DF))) | 1230 | if (likely(status & (ATA_ERR | ATA_DF))) |
1139 | /* device stops HSM for abort/error */ | 1231 | /* device stops HSM for abort/error */ |
1140 | qc->err_mask |= AC_ERR_DEV; | 1232 | qc->err_mask |= AC_ERR_DEV; |
1141 | else | 1233 | else { |
1142 | /* HSM violation. Let EH handle this. | 1234 | /* HSM violation. Let EH handle this. |
1143 | * Phantom devices also trigger this | 1235 | * Phantom devices also trigger this |
1144 | * condition. Mark hint. | 1236 | * condition. Mark hint. |
1145 | */ | 1237 | */ |
1238 | ata_ehi_push_desc(ehi, "ST-ATA: " | ||
1239 | "DRQ=1 with device error, " | ||
1240 | "dev_stat 0x%X", status); | ||
1146 | qc->err_mask |= AC_ERR_HSM | | 1241 | qc->err_mask |= AC_ERR_HSM | |
1147 | AC_ERR_NODEV_HINT; | 1242 | AC_ERR_NODEV_HINT; |
1243 | } | ||
1148 | 1244 | ||
1149 | ap->hsm_task_state = HSM_ST_ERR; | 1245 | ap->hsm_task_state = HSM_ST_ERR; |
1150 | goto fsm_start; | 1246 | goto fsm_start; |
@@ -1169,8 +1265,12 @@ fsm_start: | |||
1169 | status = ata_wait_idle(ap); | 1265 | status = ata_wait_idle(ap); |
1170 | } | 1266 | } |
1171 | 1267 | ||
1172 | if (status & (ATA_BUSY | ATA_DRQ)) | 1268 | if (status & (ATA_BUSY | ATA_DRQ)) { |
1269 | ata_ehi_push_desc(ehi, "ST-ATA: " | ||
1270 | "BUSY|DRQ persists on ERR|DF, " | ||
1271 | "dev_stat 0x%X", status); | ||
1173 | qc->err_mask |= AC_ERR_HSM; | 1272 | qc->err_mask |= AC_ERR_HSM; |
1273 | } | ||
1174 | 1274 | ||
1175 | /* ata_pio_sectors() might change the | 1275 | /* ata_pio_sectors() might change the |
1176 | * state to HSM_ST_LAST. so, the state | 1276 | * state to HSM_ST_LAST. so, the state |
@@ -1489,14 +1589,10 @@ inline unsigned int ata_sff_host_intr(struct ata_port *ap, | |||
1489 | goto idle_irq; | 1589 | goto idle_irq; |
1490 | } | 1590 | } |
1491 | 1591 | ||
1492 | /* check altstatus */ | ||
1493 | status = ata_sff_altstatus(ap); | ||
1494 | if (status & ATA_BUSY) | ||
1495 | goto idle_irq; | ||
1496 | 1592 | ||
1497 | /* check main status, clearing INTRQ */ | 1593 | /* check main status, clearing INTRQ if needed */ |
1498 | status = ap->ops->sff_check_status(ap); | 1594 | status = ata_sff_irq_status(ap); |
1499 | if (unlikely(status & ATA_BUSY)) | 1595 | if (status & ATA_BUSY) |
1500 | goto idle_irq; | 1596 | goto idle_irq; |
1501 | 1597 | ||
1502 | /* ack bmdma irq events */ | 1598 | /* ack bmdma irq events */ |
@@ -2030,7 +2126,7 @@ void ata_sff_error_handler(struct ata_port *ap) | |||
2030 | ap->ops->bmdma_stop(qc); | 2126 | ap->ops->bmdma_stop(qc); |
2031 | } | 2127 | } |
2032 | 2128 | ||
2033 | ata_sff_altstatus(ap); | 2129 | ata_sff_sync(ap); /* FIXME: We don't need this */ |
2034 | ap->ops->sff_check_status(ap); | 2130 | ap->ops->sff_check_status(ap); |
2035 | ap->ops->sff_irq_clear(ap); | 2131 | ap->ops->sff_irq_clear(ap); |
2036 | 2132 | ||
@@ -2203,7 +2299,7 @@ void ata_bmdma_stop(struct ata_queued_cmd *qc) | |||
2203 | mmio + ATA_DMA_CMD); | 2299 | mmio + ATA_DMA_CMD); |
2204 | 2300 | ||
2205 | /* one-PIO-cycle guaranteed wait, per spec, for HDMA1:0 transition */ | 2301 | /* one-PIO-cycle guaranteed wait, per spec, for HDMA1:0 transition */ |
2206 | ata_sff_altstatus(ap); /* dummy read */ | 2302 | ata_sff_dma_pause(ap); |
2207 | } | 2303 | } |
2208 | 2304 | ||
2209 | /** | 2305 | /** |
@@ -2722,7 +2818,8 @@ EXPORT_SYMBOL_GPL(ata_sff_qc_prep); | |||
2722 | EXPORT_SYMBOL_GPL(ata_sff_dumb_qc_prep); | 2818 | EXPORT_SYMBOL_GPL(ata_sff_dumb_qc_prep); |
2723 | EXPORT_SYMBOL_GPL(ata_sff_dev_select); | 2819 | EXPORT_SYMBOL_GPL(ata_sff_dev_select); |
2724 | EXPORT_SYMBOL_GPL(ata_sff_check_status); | 2820 | EXPORT_SYMBOL_GPL(ata_sff_check_status); |
2725 | EXPORT_SYMBOL_GPL(ata_sff_altstatus); | 2821 | EXPORT_SYMBOL_GPL(ata_sff_dma_pause); |
2822 | EXPORT_SYMBOL_GPL(ata_sff_pause); | ||
2726 | EXPORT_SYMBOL_GPL(ata_sff_busy_sleep); | 2823 | EXPORT_SYMBOL_GPL(ata_sff_busy_sleep); |
2727 | EXPORT_SYMBOL_GPL(ata_sff_wait_ready); | 2824 | EXPORT_SYMBOL_GPL(ata_sff_wait_ready); |
2728 | EXPORT_SYMBOL_GPL(ata_sff_tf_load); | 2825 | EXPORT_SYMBOL_GPL(ata_sff_tf_load); |