aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSeokmann Ju <seokmann.ju@qlogic.com>2009-03-24 12:08:18 -0400
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2009-04-03 10:22:53 -0400
commitb9b12f73dff15915914f51bbff7620f5dd49b3de (patch)
tree870f134a8d3c2bfe35dc112be6f1d43b2e32d8e6
parent6749ce362d38b47bd4669ccc0cafcc0014bff6e9 (diff)
[SCSI] qla2xxx: Correct several PCI-EEH issues.
In addition to checking for potentially unnecessary iomem readX()/writeX() operations, a pci_channel_io_perm_failure should not trigger a full internal removal. Found during additional testing with pSeries blade systems. Signed-off-by: Seokmann Ju <seokmann.ju@qlogic.com> Signed-off-by: Andrew Vasquez <andrew.vasquez@qlogic.com> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
-rw-r--r--drivers/scsi/qla2xxx/qla_attr.c9
-rw-r--r--drivers/scsi/qla2xxx/qla_mbx.c3
-rw-r--r--drivers/scsi/qla2xxx/qla_os.c9
3 files changed, 18 insertions, 3 deletions
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c
index 15573f6dc36b..b09993a06576 100644
--- a/drivers/scsi/qla2xxx/qla_attr.c
+++ b/drivers/scsi/qla2xxx/qla_attr.c
@@ -1282,7 +1282,10 @@ qla2x00_dev_loss_tmo_callbk(struct fc_rport *rport)
1282 if (!fcport) 1282 if (!fcport)
1283 return; 1283 return;
1284 1284
1285 qla2x00_abort_fcport_cmds(fcport); 1285 if (unlikely(pci_channel_offline(fcport->vha->hw->pdev)))
1286 qla2x00_abort_all_cmds(fcport->vha, DID_NO_CONNECT << 16);
1287 else
1288 qla2x00_abort_fcport_cmds(fcport);
1286 1289
1287 /* 1290 /*
1288 * Transport has effectively 'deleted' the rport, clear 1291 * Transport has effectively 'deleted' the rport, clear
@@ -1302,6 +1305,10 @@ qla2x00_terminate_rport_io(struct fc_rport *rport)
1302 if (!fcport) 1305 if (!fcport)
1303 return; 1306 return;
1304 1307
1308 if (unlikely(pci_channel_offline(fcport->vha->hw->pdev))) {
1309 qla2x00_abort_all_cmds(fcport->vha, DID_NO_CONNECT << 16);
1310 return;
1311 }
1305 /* 1312 /*
1306 * At this point all fcport's software-states are cleared. Perform any 1313 * At this point all fcport's software-states are cleared. Perform any
1307 * final cleanup of firmware resources (PCBs and XCBs). 1314 * final cleanup of firmware resources (PCBs and XCBs).
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c
index 951537e30294..e67c1660bf46 100644
--- a/drivers/scsi/qla2xxx/qla_mbx.c
+++ b/drivers/scsi/qla2xxx/qla_mbx.c
@@ -45,6 +45,9 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
45 struct qla_hw_data *ha = vha->hw; 45 struct qla_hw_data *ha = vha->hw;
46 scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev); 46 scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
47 47
48 if (ha->pdev->error_state > pci_channel_io_frozen)
49 return QLA_FUNCTION_TIMEOUT;
50
48 reg = ha->iobase; 51 reg = ha->iobase;
49 io_lock_on = base_vha->flags.init_done; 52 io_lock_on = base_vha->flags.init_done;
50 53
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 7e038e4107a5..efe29924e058 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -407,7 +407,10 @@ qla2xxx_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
407 int rval; 407 int rval;
408 408
409 if (unlikely(pci_channel_offline(ha->pdev))) { 409 if (unlikely(pci_channel_offline(ha->pdev))) {
410 cmd->result = DID_REQUEUE << 16; 410 if (ha->pdev->error_state == pci_channel_io_frozen)
411 cmd->result = DID_REQUEUE << 16;
412 else
413 cmd->result = DID_NO_CONNECT << 16;
411 goto qc24_fail_command; 414 goto qc24_fail_command;
412 } 415 }
413 416
@@ -2990,6 +2993,8 @@ qla2x00_release_firmware(void)
2990static pci_ers_result_t 2993static pci_ers_result_t
2991qla2xxx_pci_error_detected(struct pci_dev *pdev, pci_channel_state_t state) 2994qla2xxx_pci_error_detected(struct pci_dev *pdev, pci_channel_state_t state)
2992{ 2995{
2996 scsi_qla_host_t *base_vha = pci_get_drvdata(pdev);
2997
2993 switch (state) { 2998 switch (state) {
2994 case pci_channel_io_normal: 2999 case pci_channel_io_normal:
2995 return PCI_ERS_RESULT_CAN_RECOVER; 3000 return PCI_ERS_RESULT_CAN_RECOVER;
@@ -2997,7 +3002,7 @@ qla2xxx_pci_error_detected(struct pci_dev *pdev, pci_channel_state_t state)
2997 pci_disable_device(pdev); 3002 pci_disable_device(pdev);
2998 return PCI_ERS_RESULT_NEED_RESET; 3003 return PCI_ERS_RESULT_NEED_RESET;
2999 case pci_channel_io_perm_failure: 3004 case pci_channel_io_perm_failure:
3000 qla2x00_remove_one(pdev); 3005 qla2x00_abort_all_cmds(base_vha, DID_NO_CONNECT << 16);
3001 return PCI_ERS_RESULT_DISCONNECT; 3006 return PCI_ERS_RESULT_DISCONNECT;
3002 } 3007 }
3003 return PCI_ERS_RESULT_NEED_RESET; 3008 return PCI_ERS_RESULT_NEED_RESET;