aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMauricio Faria de Oliveira <mauricfo@linux.vnet.ibm.com>2016-11-14 16:26:22 -0500
committerMartin K. Petersen <martin.petersen@oracle.com>2016-11-14 18:38:10 -0500
commitc733ab3512431436a26e0381829b45794cb13fb0 (patch)
tree8a462254a2f5e092fdc3c5294378a4755bb7d31d
parent18f6084a989ba1b38702f9af37a2e4049a924be6 (diff)
scsi: qla2xxx: do not abort all commands in the adapter during EEH recovery
The previous commit 1535aa75a3d8 ("qla2xxx: fix invalid DMA access after command aborts in PCI device remove") introduced a regression during an EEH recovery, since the change to the qla2x00_abort_all_cmds() function calls qla2xxx_eh_abort(), which verifies the EEH recovery condition but handles it heavy-handed. (commit a465537ad1a4 "qla2xxx: Disable the adapter and skip error recovery in case of register disconnect.") This problem warrants a more general/optimistic solution right into qla2xxx_eh_abort() (eg in case a real command abort arrives during EEH recovery, or if it takes long enough to trigger command aborts); but it's still worth to add a check to ensure the code added by the previous commit is correct and contained within its owner function. This commit just adds a 'if (!ha->flags.eeh_busy)' check around it. (ahem; a trivial fix for this -rc series; sorry for this oversight.) With it applied, both PCI device remove and EEH recovery works fine. Fixes: 1535aa75a3d8 ("scsi: qla2xxx: fix invalid DMA access after command aborts in PCI device remove") Signed-off-by: Mauricio Faria de Oliveira <mauricfo@linux.vnet.ibm.com> Acked-by: Himanshu Madhani <himanshu.madhani@cavium.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
-rw-r--r--drivers/scsi/qla2xxx/qla_os.c21
1 files changed, 13 insertions, 8 deletions
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 567fa080e261..56d6142852a5 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -1456,15 +1456,20 @@ qla2x00_abort_all_cmds(scsi_qla_host_t *vha, int res)
1456 for (cnt = 1; cnt < req->num_outstanding_cmds; cnt++) { 1456 for (cnt = 1; cnt < req->num_outstanding_cmds; cnt++) {
1457 sp = req->outstanding_cmds[cnt]; 1457 sp = req->outstanding_cmds[cnt];
1458 if (sp) { 1458 if (sp) {
1459 /* Get a reference to the sp and drop the lock. 1459 /* Don't abort commands in adapter during EEH
1460 * The reference ensures this sp->done() call 1460 * recovery as it's not accessible/responding.
1461 * - and not the call in qla2xxx_eh_abort() -
1462 * ends the SCSI command (with result 'res').
1463 */ 1461 */
1464 sp_get(sp); 1462 if (!ha->flags.eeh_busy) {
1465 spin_unlock_irqrestore(&ha->hardware_lock, flags); 1463 /* Get a reference to the sp and drop the lock.
1466 qla2xxx_eh_abort(GET_CMD_SP(sp)); 1464 * The reference ensures this sp->done() call
1467 spin_lock_irqsave(&ha->hardware_lock, flags); 1465 * - and not the call in qla2xxx_eh_abort() -
1466 * ends the SCSI command (with result 'res').
1467 */
1468 sp_get(sp);
1469 spin_unlock_irqrestore(&ha->hardware_lock, flags);
1470 qla2xxx_eh_abort(GET_CMD_SP(sp));
1471 spin_lock_irqsave(&ha->hardware_lock, flags);
1472 }
1468 req->outstanding_cmds[cnt] = NULL; 1473 req->outstanding_cmds[cnt] = NULL;
1469 sp->done(vha, sp, res); 1474 sp->done(vha, sp, res);
1470 } 1475 }