]>
Commit | Line | Data |
---|---|---|
2cb7cef9 BS |
1 | From: David Wagner <david.wagner@qlogic.com> |
2 | Subject: qla2xxx driver EEH unable to recover from injected PCI error | |
3 | References: bnc#442923 | |
4 | ||
5 | qla2xxx driver EEH unable to recover from injected PCI errror. | |
6 | Driver enters infinite EEH loop. | |
7 | With this patch the qla2xxx driver survives andy PCI error injection | |
8 | and properly terminates all commands. | |
9 | ||
10 | Signed-off-by: Hannes Reinecke <hare@suse.de> | |
11 | ||
12 | --- | |
13 | drivers/scsi/qla2xxx/qla_attr.c | 9 ++++++++- | |
14 | drivers/scsi/qla2xxx/qla_mbx.c | 3 +++ | |
15 | drivers/scsi/qla2xxx/qla_os.c | 14 +++++++++++--- | |
16 | drivers/scsi/qla2xxx/qla_version.h | 2 +- | |
17 | 4 files changed, 23 insertions(+), 5 deletions(-) | |
18 | ||
19 | --- a/drivers/scsi/qla2xxx/qla_attr.c | |
20 | +++ b/drivers/scsi/qla2xxx/qla_attr.c | |
21 | @@ -1286,7 +1286,10 @@ qla2x00_dev_loss_tmo_callbk(struct fc_rp | |
22 | if (!fcport) | |
23 | return; | |
24 | ||
25 | - qla2x00_abort_fcport_cmds(fcport); | |
26 | + if (unlikely(pci_channel_offline(fcport->ha->pdev))) | |
27 | + qla2x00_abort_all_cmds(fcport->ha, DID_NO_CONNECT << 16); | |
28 | + else | |
29 | + qla2x00_abort_fcport_cmds(fcport); | |
30 | ||
31 | /* | |
32 | * Transport has effectively 'deleted' the rport, clear | |
33 | @@ -1306,6 +1309,10 @@ qla2x00_terminate_rport_io(struct fc_rpo | |
34 | if (!fcport) | |
35 | return; | |
36 | ||
37 | + if (unlikely(pci_channel_offline(fcport->ha->pdev))) { | |
38 | + qla2x00_abort_all_cmds(fcport->ha, DID_NO_CONNECT << 16); | |
39 | + return; | |
40 | + } | |
41 | /* | |
42 | * At this point all fcport's software-states are cleared. Perform any | |
43 | * final cleanup of firmware resources (PCBs and XCBs). | |
44 | --- a/drivers/scsi/qla2xxx/qla_mbx.c | |
45 | +++ b/drivers/scsi/qla2xxx/qla_mbx.c | |
46 | @@ -44,6 +44,9 @@ qla2x00_mailbox_command(scsi_qla_host_t | |
47 | unsigned long wait_time; | |
48 | scsi_qla_host_t *ha = to_qla_parent(pvha); | |
49 | ||
50 | + if (ha->pdev->error_state == pci_channel_io_perm_failure) | |
51 | + return QLA_FUNCTION_TIMEOUT; | |
52 | + | |
53 | reg = ha->iobase; | |
54 | io_lock_on = ha->flags.init_done; | |
55 | ||
56 | --- a/drivers/scsi/qla2xxx/qla_os.c | |
57 | +++ b/drivers/scsi/qla2xxx/qla_os.c | |
58 | @@ -391,7 +391,10 @@ qla2x00_queuecommand(struct scsi_cmnd *c | |
59 | int rval; | |
60 | ||
61 | if (unlikely(pci_channel_offline(ha->pdev))) { | |
62 | - cmd->result = DID_REQUEUE << 16; | |
63 | + if (ha->pdev->error_state == pci_channel_io_frozen) | |
64 | + cmd->result = DID_REQUEUE << 16; | |
65 | + else | |
66 | + cmd->result = DID_NO_CONNECT << 16; | |
67 | goto qc_fail_command; | |
68 | } | |
69 | ||
70 | @@ -457,7 +460,10 @@ qla24xx_queuecommand(struct scsi_cmnd *c | |
71 | scsi_qla_host_t *pha = to_qla_parent(ha); | |
72 | ||
73 | if (unlikely(pci_channel_offline(pha->pdev))) { | |
74 | - cmd->result = DID_REQUEUE << 16; | |
75 | + if (ha->pdev->error_state == pci_channel_io_frozen) | |
76 | + cmd->result = DID_REQUEUE << 16; | |
77 | + else | |
78 | + cmd->result = DID_NO_CONNECT << 16; | |
79 | goto qc24_fail_command; | |
80 | } | |
81 | ||
82 | @@ -2762,6 +2768,8 @@ qla2x00_release_firmware(void) | |
83 | static pci_ers_result_t | |
84 | qla2xxx_pci_error_detected(struct pci_dev *pdev, pci_channel_state_t state) | |
85 | { | |
86 | + scsi_qla_host_t *ha = pci_get_drvdata(pdev); | |
87 | + | |
88 | switch (state) { | |
89 | case pci_channel_io_normal: | |
90 | return PCI_ERS_RESULT_CAN_RECOVER; | |
91 | @@ -2769,7 +2777,7 @@ qla2xxx_pci_error_detected(struct pci_de | |
92 | pci_disable_device(pdev); | |
93 | return PCI_ERS_RESULT_NEED_RESET; | |
94 | case pci_channel_io_perm_failure: | |
95 | - qla2x00_remove_one(pdev); | |
96 | + qla2x00_abort_all_cmds(ha, DID_NO_CONNECT << 16); | |
97 | return PCI_ERS_RESULT_DISCONNECT; | |
98 | } | |
99 | return PCI_ERS_RESULT_NEED_RESET; | |
100 | --- a/drivers/scsi/qla2xxx/qla_version.h | |
101 | +++ b/drivers/scsi/qla2xxx/qla_version.h | |
102 | @@ -7,7 +7,7 @@ | |
103 | /* | |
104 | * Driver version | |
105 | */ | |
106 | -#define QLA2XXX_VERSION "8.02.01.02.11.0-k9" | |
107 | +#define QLA2XXX_VERSION "8.02.01.03.11.0-k9" | |
108 | ||
109 | #define QLA_DRIVER_MAJOR_VER 8 | |
110 | #define QLA_DRIVER_MINOR_VER 2 |