aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/sata_mv.c17
1 files changed, 10 insertions, 7 deletions
diff --git a/drivers/scsi/sata_mv.c b/drivers/scsi/sata_mv.c
index d5fdcb9a8842..87f26cd60fae 100644
--- a/drivers/scsi/sata_mv.c
+++ b/drivers/scsi/sata_mv.c
@@ -1291,6 +1291,7 @@ static u8 mv_get_crpb_status(struct ata_port *ap)
1291/** 1291/**
1292 * mv_err_intr - Handle error interrupts on the port 1292 * mv_err_intr - Handle error interrupts on the port
1293 * @ap: ATA channel to manipulate 1293 * @ap: ATA channel to manipulate
1294 * @reset_allowed: bool: 0 == don't trigger from reset here
1294 * 1295 *
1295 * In most cases, just clear the interrupt and move on. However, 1296 * In most cases, just clear the interrupt and move on. However,
1296 * some cases require an eDMA reset, which is done right before 1297 * some cases require an eDMA reset, which is done right before
@@ -1301,7 +1302,7 @@ static u8 mv_get_crpb_status(struct ata_port *ap)
1301 * LOCKING: 1302 * LOCKING:
1302 * Inherited from caller. 1303 * Inherited from caller.
1303 */ 1304 */
1304static void mv_err_intr(struct ata_port *ap) 1305static void mv_err_intr(struct ata_port *ap, int reset_allowed)
1305{ 1306{
1306 void __iomem *port_mmio = mv_ap_base(ap); 1307 void __iomem *port_mmio = mv_ap_base(ap);
1307 u32 edma_err_cause, serr = 0; 1308 u32 edma_err_cause, serr = 0;
@@ -1323,9 +1324,8 @@ static void mv_err_intr(struct ata_port *ap)
1323 writelfl(0, port_mmio + EDMA_ERR_IRQ_CAUSE_OFS); 1324 writelfl(0, port_mmio + EDMA_ERR_IRQ_CAUSE_OFS);
1324 1325
1325 /* check for fatal here and recover if needed */ 1326 /* check for fatal here and recover if needed */
1326 if (EDMA_ERR_FATAL & edma_err_cause) { 1327 if (reset_allowed && (EDMA_ERR_FATAL & edma_err_cause))
1327 mv_stop_and_reset(ap); 1328 mv_stop_and_reset(ap);
1328 }
1329} 1329}
1330 1330
1331/** 1331/**
@@ -1406,7 +1406,7 @@ static void mv_host_intr(struct ata_host_set *host_set, u32 relevant,
1406 shift++; /* skip bit 8 in the HC Main IRQ reg */ 1406 shift++; /* skip bit 8 in the HC Main IRQ reg */
1407 } 1407 }
1408 if ((PORT0_ERR << shift) & relevant) { 1408 if ((PORT0_ERR << shift) & relevant) {
1409 mv_err_intr(ap); 1409 mv_err_intr(ap, 1);
1410 err_mask |= AC_ERR_OTHER; 1410 err_mask |= AC_ERR_OTHER;
1411 handled = 1; 1411 handled = 1;
1412 } 1412 }
@@ -2031,11 +2031,14 @@ static void mv_eng_timeout(struct ata_port *ap)
2031 ap->host_set->mmio_base, ap, qc, qc->scsicmd, 2031 ap->host_set->mmio_base, ap, qc, qc->scsicmd,
2032 &qc->scsicmd->cmnd); 2032 &qc->scsicmd->cmnd);
2033 2033
2034 mv_err_intr(ap); 2034 mv_err_intr(ap, 0);
2035 mv_stop_and_reset(ap); 2035 mv_stop_and_reset(ap);
2036 2036
2037 qc->err_mask |= AC_ERR_TIMEOUT; 2037 WARN_ON(!(qc->flags & ATA_QCFLAG_ACTIVE));
2038 ata_eh_qc_complete(qc); 2038 if (qc->flags & ATA_QCFLAG_ACTIVE) {
2039 qc->err_mask |= AC_ERR_TIMEOUT;
2040 ata_eh_qc_complete(qc);
2041 }
2039} 2042}
2040 2043
2041/** 2044/**