diff options
author | Seokmann Ju <seokmann.ju@qlogic.com> | 2009-03-24 12:08:18 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2009-04-03 10:22:53 -0400 |
commit | b9b12f73dff15915914f51bbff7620f5dd49b3de (patch) | |
tree | 870f134a8d3c2bfe35dc112be6f1d43b2e32d8e6 | |
parent | 6749ce362d38b47bd4669ccc0cafcc0014bff6e9 (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.c | 9 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_mbx.c | 3 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_os.c | 9 |
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) | |||
2990 | static pci_ers_result_t | 2993 | static pci_ers_result_t |
2991 | qla2xxx_pci_error_detected(struct pci_dev *pdev, pci_channel_state_t state) | 2994 | qla2xxx_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; |