diff options
-rw-r--r-- | drivers/scsi/sata_mv.c | 17 |
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 | */ |
1304 | static void mv_err_intr(struct ata_port *ap) | 1305 | static 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 | /** |