]>
Commit | Line | Data |
---|---|---|
00e5a55c BS |
1 | From: Jamie Wellnitz <jamie.wellnitz@emulex.com> |
2 | Subject: Update lpfc to 8.2.8.7 | |
3 | References: bnc#420767 | |
4 | ||
5 | This patch updates the SLES 11 inbox lpfc driver 8.2.8.7, which fixes several | |
6 | issues we've found in testing on SLES 11 Beta. | |
7 | ||
8 | * Changed version number to 8.2.8.7 | |
9 | * Fixed system lockup problem when HBA is in MSI-X mode (CR 85802, 85441) | |
10 | * Fixed slow vport deletes | |
11 | * Fixed locking issue when lpfc_ioctl_send_mgmt_cmd fails to allocate buffer | |
12 | * Changed mdelay to msleep in the ioctl path (CR 85606) | |
13 | * Fixed a discovery issue (CR 85714) | |
14 | * Extended Error Handling (EEH) support on IBM PowerPC P6 platform (CR 85671) | |
15 | * Fix allocation of HBQs should not be done in interrupt context (CR 84717) | |
16 | * Fixed loopback tests not working if auth enabled but auth service not | |
17 | available (CR 85334) | |
18 | * Changed version number to 8.2.8.6 | |
19 | * Fix memory leaks in netlink send code | |
20 | * Fixed fail-to-enable INTx when auth is enabled but auth service is not | |
21 | running (CR 85162) | |
22 | * Fix build warning of uninitialized variable in lpfc_enable_intr | |
23 | * Fix crash when running latency test (CR 85257) | |
24 | * Fixed missing CNA attribute for sysfs (CR 85265) | |
25 | * Fixed false overrun failure for menlo commands that are less than the command | |
26 | header size (CR 85168) | |
27 | * Fixed mbuf leak when lpfc_pci_probe_one hit an error exit in SLI-2 mode | |
28 | * Fix memory leak with dump mailbox completion | |
29 | * Fix bpl size to reflect the correct buffer's size | |
30 | * Fixed lpfc install problem for SLES 11 Beta2 (CR 84623) | |
31 | * Fix driver online notification to come after port is added to auth list | |
32 | * Added active interrupt test and automatic fallback for enabling | |
33 | MSI/MSI-X/INTx (CR 84266) | |
34 | * Fixed NULL pointer dereference in lpfc_prep_els_iocb (CR 84470) | |
35 | * Fixed time out handling in the worker thread (CR 84540) | |
36 | * Changed version number to 8.2.8.5 | |
37 | * Small cleanup to match upstream 8.2.8 changes | |
38 | * Fix bug with Interrupt Enable Block support (CR 84106) | |
39 | * Applied pci_max_read fix from 8.2.0.x driver series (CR 84414) | |
40 | * Added support for hps bit (CR 84425 84428) | |
41 | ||
42 | Signed-off-by: Jamie Wellnitz <jamie.wellnitz@emulex.com> | |
43 | Signed-off-by: Hannes Reinecke <hare@suse.de> | |
44 | ||
45 | diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h | |
46 | index 7508dea..7bb7971 100644 | |
47 | --- a/drivers/scsi/lpfc/lpfc.h | |
48 | +++ b/drivers/scsi/lpfc/lpfc.h | |
49 | @@ -73,6 +73,9 @@ struct lpfc_sli2_slim; | |
50 | /* Number of MSI-X vectors the driver uses */ | |
51 | #define LPFC_MSIX_VECTORS 2 | |
52 | ||
53 | +/* Active interrupt test threshold */ | |
54 | +#define LPFC_INTR_THRESHOLD 1 | |
55 | + | |
56 | /* lpfc wait event data ready flag */ | |
57 | #define LPFC_DATA_READY (1<<0) | |
58 | ||
59 | @@ -629,6 +632,7 @@ struct lpfc_hba { | |
60 | uint32_t cfg_hba_queue_depth; | |
61 | uint32_t cfg_enable_hba_reset; | |
62 | uint32_t cfg_enable_hba_heartbeat; | |
63 | + uint32_t cfg_pci_max_read; | |
64 | ||
65 | lpfc_vpd_t vpd; /* vital product data */ | |
66 | ||
67 | @@ -718,6 +722,8 @@ struct lpfc_hba { | |
68 | ||
69 | struct fc_host_statistics link_stats; | |
70 | enum intr_type_t intr_type; | |
71 | + uint32_t intr_mode; | |
72 | +#define LPFC_INTR_ERROR 0xFFFFFFFF | |
73 | struct msix_entry msix_entries[LPFC_MSIX_VECTORS]; | |
74 | struct lpfcdfc_host *dfc_host; | |
75 | ||
76 | diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c | |
77 | index 1069491..2140408 100644 | |
78 | --- a/drivers/scsi/lpfc/lpfc_attr.c | |
79 | +++ b/drivers/scsi/lpfc/lpfc_attr.c | |
80 | @@ -42,6 +42,7 @@ | |
81 | #include "lpfc_crtn.h" | |
82 | #include "lpfc_vport.h" | |
83 | #include "lpfc_auth_access.h" | |
84 | +#include "lpfc_security.h" | |
85 | ||
86 | #define LPFC_DEF_DEVLOSS_TMO 30 | |
87 | #define LPFC_MIN_DEVLOSS_TMO 1 | |
88 | @@ -3100,6 +3101,27 @@ LPFC_ATTR_R(enable_hba_heartbeat, 1, 0, 1, "Enable HBA Heartbeat."); | |
89 | */ | |
90 | LPFC_ATTR_R(sg_seg_cnt, LPFC_DEFAULT_SG_SEG_CNT, LPFC_DEFAULT_SG_SEG_CNT, | |
91 | LPFC_MAX_SG_SEG_CNT, "Max Scatter Gather Segment Count"); | |
92 | +/* | |
93 | + * lpfc_pci_max_read: Maximum DMA read byte count. This parameter can have | |
94 | + * values 512, 1024, 2048, 4096. Default value is 2048. | |
95 | + */ | |
96 | +static int lpfc_pci_max_read = 2048; | |
97 | +module_param(lpfc_pci_max_read, int, 0); | |
98 | +MODULE_PARM_DESC(lpfc_pci_max_read, | |
99 | + "Maximum DMA read byte count. Allowed values:" | |
100 | + " 512,1024,2048,4096."); | |
101 | +static int | |
102 | +lpfc_pci_max_read_init(struct lpfc_hba *phba, int val) | |
103 | +{ | |
104 | + phba->cfg_pci_max_read = 2048; | |
105 | + if ((val == 512) || (val == 1024) || (val == 2048) || (val == 4096)) | |
106 | + phba->cfg_pci_max_read = val; | |
107 | + return 0; | |
108 | +} | |
109 | + | |
110 | +lpfc_param_show(pci_max_read) | |
111 | +static DEVICE_ATTR(lpfc_pci_max_read, S_IRUGO, | |
112 | + lpfc_pci_max_read_show, NULL); | |
113 | ||
114 | struct device_attribute *lpfc_hba_attrs[] = { | |
115 | &dev_attr_info, | |
116 | @@ -3136,6 +3158,7 @@ struct device_attribute *lpfc_hba_attrs[] = { | |
117 | &dev_attr_lpfc_fdmi_on, | |
118 | &dev_attr_lpfc_max_luns, | |
119 | &dev_attr_lpfc_enable_npiv, | |
120 | + &dev_attr_lpfc_pci_max_read, | |
121 | &dev_attr_nport_evt_cnt, | |
122 | &dev_attr_board_mode, | |
123 | &dev_attr_max_vpi, | |
124 | @@ -4176,12 +4199,22 @@ lpfc_alloc_sysfs_attr(struct lpfc_vport *vport) | |
125 | if (error) | |
126 | goto out_remove_ctlreg_attr; | |
127 | ||
128 | + error = sysfs_create_bin_file(&shost->shost_dev.kobj, | |
129 | + &sysfs_menlo_attr); | |
130 | + if (error) | |
131 | + goto out_remove_menlo_attr; | |
132 | + | |
133 | + | |
134 | return 0; | |
135 | out_remove_ctlreg_attr: | |
136 | sysfs_remove_bin_file(&shost->shost_dev.kobj, &sysfs_ctlreg_attr); | |
137 | out_remove_stat_attr: | |
138 | sysfs_remove_bin_file(&shost->shost_dev.kobj, | |
139 | &sysfs_drvr_stat_data_attr); | |
140 | +out_remove_menlo_attr: | |
141 | + sysfs_remove_bin_file(&shost->shost_dev.kobj, | |
142 | + &sysfs_menlo_attr); | |
143 | + | |
144 | out: | |
145 | return error; | |
146 | } | |
147 | @@ -4269,6 +4302,13 @@ lpfc_get_host_port_state(struct Scsi_Host *shost) | |
148 | if (vport->fc_flag & FC_OFFLINE_MODE) | |
149 | fc_host_port_state(shost) = FC_PORTSTATE_OFFLINE; | |
150 | else { | |
151 | + if ((vport->cfg_enable_auth) && | |
152 | + (lpfc_security_service_state == SECURITY_OFFLINE)) { | |
153 | + fc_host_port_state(shost) = FC_PORTSTATE_ERROR; | |
154 | + spin_unlock_irq(shost->host_lock); | |
155 | + return; | |
156 | + } | |
157 | + | |
158 | switch (phba->link_state) { | |
159 | case LPFC_LINK_UNKNOWN: | |
160 | case LPFC_LINK_DOWN: | |
161 | @@ -4837,6 +4877,7 @@ lpfc_get_cfgparam(struct lpfc_hba *phba) | |
162 | lpfc_link_speed_init(phba, lpfc_link_speed); | |
163 | lpfc_poll_tmo_init(phba, lpfc_poll_tmo); | |
164 | lpfc_enable_npiv_init(phba, lpfc_enable_npiv); | |
165 | + lpfc_pci_max_read_init(phba, lpfc_pci_max_read); | |
166 | lpfc_use_msi_init(phba, lpfc_use_msi); | |
167 | lpfc_enable_hba_reset_init(phba, lpfc_enable_hba_reset); | |
168 | lpfc_enable_hba_heartbeat_init(phba, lpfc_enable_hba_heartbeat); | |
169 | diff --git a/drivers/scsi/lpfc/lpfc_auth_access.c b/drivers/scsi/lpfc/lpfc_auth_access.c | |
170 | index 7481eb0..9f48c59 100644 | |
171 | --- a/drivers/scsi/lpfc/lpfc_auth_access.c | |
172 | +++ b/drivers/scsi/lpfc/lpfc_auth_access.c | |
173 | @@ -1,7 +1,7 @@ | |
174 | /******************************************************************* | |
175 | * This file is part of the Emulex Linux Device Driver for * | |
176 | * Fibre Channel Host Bus Adapters. * | |
177 | - * Copyright (C) 2006-2007 Emulex. All rights reserved. * | |
178 | + * Copyright (C) 2006-2008 Emulex. All rights reserved. * | |
179 | * EMULEX and SLI are trademarks of Emulex. * | |
180 | * www.emulex.com * | |
181 | * * | |
182 | @@ -213,10 +213,11 @@ lpfc_fc_sc_request(struct lpfc_vport *vport, | |
183 | fc_sc_req->tran_id = seq; | |
184 | ||
185 | len = sizeof(struct fc_nl_sc_message) + auth_req_len; | |
186 | - fc_nl_sc_msg = kzalloc(sizeof(struct fc_nl_sc_message) + auth_req_len, | |
187 | - GFP_KERNEL); | |
188 | - if (!fc_nl_sc_msg) | |
189 | + fc_nl_sc_msg = kzalloc(len, GFP_KERNEL); | |
190 | + if (!fc_nl_sc_msg) { | |
191 | + kfree(fc_sc_req); | |
192 | return -ENOMEM; | |
193 | + } | |
194 | fc_nl_sc_msg->msgtype = msg_type; | |
195 | fc_nl_sc_msg->data_len = auth_req_len; | |
196 | memcpy(fc_nl_sc_msg->data, auth_req, auth_req_len); | |
197 | @@ -228,6 +229,7 @@ lpfc_fc_sc_request(struct lpfc_vport *vport, | |
198 | scsi_nl_send_vendor_msg(fc_service_pid, shost->host_no, | |
199 | (SCSI_NL_VID_TYPE_PCI | PCI_VENDOR_ID_EMULEX), | |
200 | (char *) fc_nl_sc_msg, len); | |
201 | + kfree(fc_nl_sc_msg); | |
202 | lpfc_fc_sc_add_timer(fc_sc_req, FC_SC_REQ_TIMEOUT, | |
203 | lpfc_fc_sc_req_times_out); | |
204 | return 0; | |
205 | diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h | |
206 | index 380acef..cedbfea 100644 | |
207 | --- a/drivers/scsi/lpfc/lpfc_crtn.h | |
208 | +++ b/drivers/scsi/lpfc/lpfc_crtn.h | |
209 | @@ -43,6 +43,7 @@ void lpfc_read_config(struct lpfc_hba *, LPFC_MBOXQ_t *); | |
210 | void lpfc_read_lnk_stat(struct lpfc_hba *, LPFC_MBOXQ_t *); | |
211 | int lpfc_reg_login(struct lpfc_hba *, uint16_t, uint32_t, uint8_t *, | |
212 | LPFC_MBOXQ_t *, uint32_t); | |
213 | +void lpfc_set_var(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t, uint32_t); | |
214 | void lpfc_unreg_login(struct lpfc_hba *, uint16_t, uint32_t, LPFC_MBOXQ_t *); | |
215 | void lpfc_unreg_did(struct lpfc_hba *, uint16_t, uint32_t, LPFC_MBOXQ_t *); | |
216 | void lpfc_reg_vpi(struct lpfc_hba *, uint16_t, uint32_t, LPFC_MBOXQ_t *); | |
217 | @@ -166,6 +167,8 @@ void lpfc_offline(struct lpfc_hba *); | |
218 | ||
219 | int lpfc_sli_setup(struct lpfc_hba *); | |
220 | int lpfc_sli_queue_setup(struct lpfc_hba *); | |
221 | +int lpfc_sli_set_dma_length(struct lpfc_hba *, uint32_t); | |
222 | + | |
223 | ||
224 | void lpfc_handle_eratt(struct lpfc_hba *); | |
225 | void lpfc_handle_latt(struct lpfc_hba *); | |
226 | diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c | |
227 | index 7fecdbb..896c7b0 100644 | |
228 | --- a/drivers/scsi/lpfc/lpfc_ct.c | |
229 | +++ b/drivers/scsi/lpfc/lpfc_ct.c | |
230 | @@ -560,18 +560,25 @@ lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |
231 | irsp->ulpStatus, irsp->un.ulpWord[4], vport->fc_ns_retry); | |
232 | ||
233 | /* Don't bother processing response if vport is being torn down. */ | |
234 | - if (vport->load_flag & FC_UNLOADING) | |
235 | + if (vport->load_flag & FC_UNLOADING) { | |
236 | + if (vport->fc_flag & FC_RSCN_MODE) | |
237 | + lpfc_els_flush_rscn(vport); | |
238 | goto out; | |
239 | + } | |
240 | ||
241 | if (lpfc_els_chk_latt(vport)) { | |
242 | lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, | |
243 | "0216 Link event during NS query\n"); | |
244 | + if (vport->fc_flag & FC_RSCN_MODE) | |
245 | + lpfc_els_flush_rscn(vport); | |
246 | lpfc_vport_set_state(vport, FC_VPORT_FAILED); | |
247 | goto out; | |
248 | } | |
249 | if (lpfc_error_lost_link(irsp)) { | |
250 | lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, | |
251 | "0226 NS query failed due to link event\n"); | |
252 | + if (vport->fc_flag & FC_RSCN_MODE) | |
253 | + lpfc_els_flush_rscn(vport); | |
254 | goto out; | |
255 | } | |
256 | if (irsp->ulpStatus) { | |
257 | @@ -587,6 +594,8 @@ lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |
258 | if (rc == 0) | |
259 | goto out; | |
260 | } | |
261 | + if (vport->fc_flag & FC_RSCN_MODE) | |
262 | + lpfc_els_flush_rscn(vport); | |
263 | lpfc_vport_set_state(vport, FC_VPORT_FAILED); | |
264 | lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, | |
265 | "0257 GID_FT Query error: 0x%x 0x%x\n", | |
266 | diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c | |
267 | index 3f58a4b..69f92e8 100644 | |
268 | --- a/drivers/scsi/lpfc/lpfc_els.c | |
269 | +++ b/drivers/scsi/lpfc/lpfc_els.c | |
270 | @@ -278,7 +278,8 @@ lpfc_prep_els_iocb(struct lpfc_vport *vport, uint8_t expectRsp, | |
271 | return elsiocb; | |
272 | ||
273 | els_iocb_free_pbuf_exit: | |
274 | - lpfc_mbuf_free(phba, prsp->virt, prsp->phys); | |
275 | + if (expectRsp) | |
276 | + lpfc_mbuf_free(phba, prsp->virt, prsp->phys); | |
277 | kfree(pbuflist); | |
278 | ||
279 | els_iocb_free_prsp_exit: | |
280 | @@ -943,6 +944,10 @@ lpfc_initial_flogi(struct lpfc_vport *vport) | |
281 | struct lpfc_hba *phba = vport->phba; | |
282 | struct lpfc_nodelist *ndlp; | |
283 | ||
284 | + if ((vport->cfg_enable_auth) && | |
285 | + (lpfc_security_service_state == SECURITY_OFFLINE)) | |
286 | + return 1; | |
287 | + | |
288 | vport->port_state = LPFC_FLOGI; | |
289 | lpfc_set_disctmo(vport); | |
290 | ||
291 | @@ -4985,10 +4990,6 @@ lpfc_els_timeout_handler(struct lpfc_vport *vport) | |
292 | uint32_t timeout; | |
293 | uint32_t remote_ID = 0xffffffff; | |
294 | ||
295 | - /* If the timer is already canceled do nothing */ | |
296 | - if ((vport->work_port_events & WORKER_ELS_TMO) == 0) { | |
297 | - return; | |
298 | - } | |
299 | spin_lock_irq(&phba->hbalock); | |
300 | timeout = (uint32_t)(phba->fc_ratov << 1); | |
301 | ||
302 | diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c | |
303 | index 358e9de..f02c2bb 100644 | |
304 | --- a/drivers/scsi/lpfc/lpfc_hbadisc.c | |
305 | +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c | |
306 | @@ -39,6 +39,7 @@ | |
307 | #include "lpfc_crtn.h" | |
308 | #include "lpfc_vport.h" | |
309 | #include "lpfc_debugfs.h" | |
310 | +#include "lpfc_security.h" | |
311 | ||
312 | /* AlpaArray for assignment of scsid for scan-down and bind_method */ | |
313 | static uint8_t lpfcAlpaArray[] = { | |
314 | @@ -1008,9 +1009,12 @@ lpfc_mbx_cmpl_local_config_link(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |
315 | /* Start discovery by sending a FLOGI. port_state is identically | |
316 | * LPFC_FLOGI while waiting for FLOGI cmpl | |
317 | */ | |
318 | - if (vport->port_state != LPFC_FLOGI) { | |
319 | + if ((vport->cfg_enable_auth) && | |
320 | + (lpfc_security_service_state == SECURITY_OFFLINE)) | |
321 | + lpfc_issue_clear_la(phba, vport); | |
322 | + else if (vport->port_state != LPFC_FLOGI) | |
323 | lpfc_initial_flogi(vport); | |
324 | - } | |
325 | + | |
326 | return; | |
327 | ||
328 | out: | |
329 | diff --git a/drivers/scsi/lpfc/lpfc_hw.h b/drivers/scsi/lpfc/lpfc_hw.h | |
330 | index c77d49e..f9a42f6 100644 | |
331 | --- a/drivers/scsi/lpfc/lpfc_hw.h | |
332 | +++ b/drivers/scsi/lpfc/lpfc_hw.h | |
333 | @@ -2370,6 +2370,14 @@ typedef struct { | |
334 | uint32_t rsvd1; | |
335 | } CLEAR_LA_VAR; | |
336 | ||
337 | +/* Structure for MB Command SET_SLIM (33) */ | |
338 | +/* Values needed to set MAX_DMA_LENGTH parameter */ | |
339 | +#define SLIM_VAR_MAX_DMA_LENGTH 0x100506 | |
340 | +#define SLIM_VAL_MAX_DMA_512 0x0 | |
341 | +#define SLIM_VAL_MAX_DMA_1024 0x1 | |
342 | +#define SLIM_VAL_MAX_DMA_2048 0x2 | |
343 | +#define SLIM_VAL_MAX_DMA_4096 0x3 | |
344 | + | |
345 | /* Structure for MB Command DUMP */ | |
346 | ||
347 | typedef struct { | |
348 | @@ -2621,10 +2629,17 @@ typedef struct { | |
349 | ||
350 | uint32_t pcbLow; /* bit 31:0 of memory based port config block */ | |
351 | uint32_t pcbHigh; /* bit 63:32 of memory based port config block */ | |
352 | - uint32_t hbainit[6]; | |
353 | + uint32_t hbainit[5]; | |
354 | +#ifdef __BIG_ENDIAN_BITFIELD | |
355 | + uint32_t hps : 1; /* bit 31 word9 Host Pointer in slim */ | |
356 | + uint32_t rsvd : 31; /* least significant 31 bits of word 9 */ | |
357 | +#else /* __LITTLE_ENDIAN */ | |
358 | + uint32_t rsvd : 31; /* least significant 31 bits of word 9 */ | |
359 | + uint32_t hps : 1; /* bit 31 word9 Host Pointer in slim */ | |
360 | +#endif | |
361 | ||
362 | #ifdef __BIG_ENDIAN_BITFIELD | |
363 | - uint32_t rsvd : 24; /* Reserved */ | |
364 | + uint32_t rsvd1 : 24; /* Reserved */ | |
365 | uint32_t cmv : 1; /* Configure Max VPIs */ | |
366 | uint32_t ccrp : 1; /* Config Command Ring Polling */ | |
367 | uint32_t csah : 1; /* Configure Synchronous Abort Handling */ | |
368 | @@ -2642,7 +2657,7 @@ typedef struct { | |
369 | uint32_t csah : 1; /* Configure Synchronous Abort Handling */ | |
370 | uint32_t ccrp : 1; /* Config Command Ring Polling */ | |
371 | uint32_t cmv : 1; /* Configure Max VPIs */ | |
372 | - uint32_t rsvd : 24; /* Reserved */ | |
373 | + uint32_t rsvd1 : 24; /* Reserved */ | |
374 | #endif | |
375 | #ifdef __BIG_ENDIAN_BITFIELD | |
376 | uint32_t rsvd2 : 24; /* Reserved */ | |
377 | diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c | |
378 | index c151651..4032bda 100644 | |
379 | --- a/drivers/scsi/lpfc/lpfc_init.c | |
380 | +++ b/drivers/scsi/lpfc/lpfc_init.c | |
381 | @@ -290,8 +290,10 @@ lpfc_dump_wakeup_param_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq) | |
382 | /* character array used for decoding dist type. */ | |
383 | char dist_char[] = "nabx"; | |
384 | ||
385 | - if (pmboxq->mb.mbxStatus != MBX_SUCCESS) | |
386 | + if (pmboxq->mb.mbxStatus != MBX_SUCCESS) { | |
387 | + mempool_free(pmboxq, phba->mbox_mem_pool); | |
388 | return; | |
389 | + } | |
390 | ||
391 | prg = (struct prog_id *) &prog_id_word; | |
392 | ||
393 | @@ -309,6 +311,7 @@ lpfc_dump_wakeup_param_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq) | |
394 | sprintf(phba->OptionROMVersion, "%d.%d%d%c%d", | |
395 | prg->ver, prg->rev, prg->lev, | |
396 | dist, prg->num); | |
397 | + mempool_free(pmboxq, phba->mbox_mem_pool); | |
398 | return; | |
399 | } | |
400 | ||
401 | @@ -521,22 +524,46 @@ lpfc_config_port_post(struct lpfc_hba *phba) | |
402 | /* Set up error attention (ERATT) polling timer */ | |
403 | mod_timer(&phba->eratt_poll, jiffies + HZ * LPFC_ERATT_POLL_INTERVAL); | |
404 | ||
405 | + /* Use the existing MBOX buffer, it will be freed in mbox compl */ | |
406 | + lpfc_config_async(phba, pmb, LPFC_ELS_RING); | |
407 | + pmb->mbox_cmpl = lpfc_config_async_cmpl; | |
408 | + pmb->vport = phba->pport; | |
409 | + rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT); | |
410 | + if ((rc != MBX_BUSY) && (rc != MBX_SUCCESS)) { | |
411 | + lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | |
412 | + "0456 Adapter failed to issue " | |
413 | + "ASYNCEVT_ENABLE mbox status x%x \n.", rc); | |
414 | + mempool_free(pmb, phba->mbox_mem_pool); | |
415 | + } | |
416 | + | |
417 | + /* Allocate new MBOX buffer, it will be freed in mbox compl */ | |
418 | + pmb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | |
419 | + lpfc_dump_wakeup_param(phba, pmb); | |
420 | + pmb->mbox_cmpl = lpfc_dump_wakeup_param_cmpl; | |
421 | + pmb->vport = phba->pport; | |
422 | + rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT); | |
423 | + if ((rc != MBX_BUSY) && (rc != MBX_SUCCESS)) { | |
424 | + lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | |
425 | + "0435 Adapter failed to get Option " | |
426 | + "ROM version status x%x\n.", rc); | |
427 | + mempool_free(pmb, phba->mbox_mem_pool); | |
428 | + } | |
429 | + | |
430 | if (vport->cfg_enable_auth) { | |
431 | if (lpfc_security_service_state == SECURITY_OFFLINE) { | |
432 | lpfc_printf_log(vport->phba, KERN_ERR, LOG_SECURITY, | |
433 | "1000 Authentication is enabled but " | |
434 | "authentication service is not running\n"); | |
435 | vport->auth.auth_mode = FC_AUTHMODE_UNKNOWN; | |
436 | - phba->link_state = LPFC_HBA_ERROR; | |
437 | - mempool_free(pmb, phba->mbox_mem_pool); | |
438 | - return 0; | |
439 | } | |
440 | } | |
441 | ||
442 | + /* Allocate new MBOX buffer, will be freed in mbox compl */ | |
443 | + pmb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | |
444 | lpfc_init_link(phba, pmb, phba->cfg_topology, phba->cfg_link_speed); | |
445 | pmb->mbox_cmpl = lpfc_sli_def_mbox_cmpl; | |
446 | rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT); | |
447 | - if (rc != MBX_SUCCESS) { | |
448 | + if ((rc != MBX_BUSY) && (rc != MBX_SUCCESS)) { | |
449 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | |
450 | "0454 Adapter failed to init, mbxCmd x%x " | |
451 | "INIT_LINK, mbxStatus x%x\n", | |
452 | @@ -550,40 +577,9 @@ lpfc_config_port_post(struct lpfc_hba *phba) | |
453 | readl(phba->HAregaddr); /* flush */ | |
454 | ||
455 | phba->link_state = LPFC_HBA_ERROR; | |
456 | - if (rc != MBX_BUSY) | |
457 | - mempool_free(pmb, phba->mbox_mem_pool); | |
458 | - return -EIO; | |
459 | - } | |
460 | - /* MBOX buffer will be freed in mbox compl */ | |
461 | - pmb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | |
462 | - lpfc_config_async(phba, pmb, LPFC_ELS_RING); | |
463 | - pmb->mbox_cmpl = lpfc_config_async_cmpl; | |
464 | - pmb->vport = phba->pport; | |
465 | - rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT); | |
466 | - | |
467 | - if ((rc != MBX_BUSY) && (rc != MBX_SUCCESS)) { | |
468 | - lpfc_printf_log(phba, | |
469 | - KERN_ERR, | |
470 | - LOG_INIT, | |
471 | - "0456 Adapter failed to issue " | |
472 | - "ASYNCEVT_ENABLE mbox status x%x \n.", | |
473 | - rc); | |
474 | - mempool_free(pmb, phba->mbox_mem_pool); | |
475 | - } | |
476 | - | |
477 | - /* Get Option rom version */ | |
478 | - pmb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | |
479 | - lpfc_dump_wakeup_param(phba, pmb); | |
480 | - pmb->mbox_cmpl = lpfc_dump_wakeup_param_cmpl; | |
481 | - pmb->vport = phba->pport; | |
482 | - rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT); | |
483 | - | |
484 | - if ((rc != MBX_BUSY) && (rc != MBX_SUCCESS)) { | |
485 | - lpfc_printf_log(phba, KERN_ERR, LOG_INIT, "0435 Adapter failed " | |
486 | - "to get Option ROM version status x%x\n.", rc); | |
487 | mempool_free(pmb, phba->mbox_mem_pool); | |
488 | + return -EIO; | |
489 | } | |
490 | - | |
491 | return 0; | |
492 | } | |
493 | ||
494 | @@ -788,11 +784,6 @@ lpfc_hb_timeout_handler(struct lpfc_hba *phba) | |
495 | return; | |
496 | ||
497 | spin_lock_irq(&phba->pport->work_port_lock); | |
498 | - /* If the timer is already canceled do nothing */ | |
499 | - if (!(phba->pport->work_port_events & WORKER_HB_TMO)) { | |
500 | - spin_unlock_irq(&phba->pport->work_port_lock); | |
501 | - return; | |
502 | - } | |
503 | ||
504 | if (time_after(phba->last_completion_time + LPFC_HB_MBOX_INTERVAL * HZ, | |
505 | jiffies)) { | |
506 | @@ -2307,6 +2298,51 @@ void lpfc_host_attrib_init(struct Scsi_Host *shost) | |
507 | } | |
508 | ||
509 | /** | |
510 | + * lpfc_setup_max_dma_length: Check the host's chipset and adjust HBA's | |
511 | + * max DMA length. | |
512 | + * @phba: pointer to lpfc hba data structure. | |
513 | + * | |
514 | + * This routine is invoked to test the machines chipsets. Some of Emulex's | |
515 | + * HBA models expose bugs in these chipsets. To work around these bugs we | |
516 | + * tell the HBA to use a smaller maxium DMA length. | |
517 | + * This routine is only called during module init. The DMA length is passed | |
518 | + * to the driver as a module parameter(lpfc_pci_max_read). | |
519 | + * | |
520 | + * return: NONE. | |
521 | + **/ | |
522 | +void | |
523 | +lpfc_setup_max_dma_length(struct lpfc_hba *phba) | |
524 | +{ | |
525 | + struct pci_dev *pdev = phba->pcidev; | |
526 | + struct pci_bus *bus = pdev->bus; | |
527 | + uint8_t rev; | |
528 | + | |
529 | + while (bus) { | |
530 | + /* | |
531 | + * 0x7450 == PCI_DEVICE_ID_AMD_8131_BRIDGE for 2.6 kernels | |
532 | + * 0x7450 == PCI_DEVICE_ID_AMD_8131_APIC for 2.4 kernels | |
533 | + */ | |
534 | + if (bus->self && | |
535 | + (bus->self->vendor == PCI_VENDOR_ID_AMD) && | |
536 | + (bus->self->device == 0x7450)) { | |
537 | + pci_read_config_byte(bus->self, 0x08, &rev); | |
538 | + if (rev == 0x13) { | |
539 | + /* | |
540 | + * If set a value in module paramter, | |
541 | + * use that value. | |
542 | + */ | |
543 | + if (phba->cfg_pci_max_read == 2048) | |
544 | + phba->cfg_pci_max_read = 1024; | |
545 | + return; | |
546 | + } | |
547 | + } | |
548 | + bus = bus->parent; | |
549 | + } | |
550 | + return; | |
551 | +} | |
552 | + | |
553 | + | |
554 | +/** | |
555 | * lpfc_enable_msix: Enable MSI-X interrupt mode. | |
556 | * @phba: pointer to lpfc hba data structure. | |
557 | * | |
558 | @@ -2340,8 +2376,7 @@ lpfc_enable_msix(struct lpfc_hba *phba) | |
559 | ARRAY_SIZE(phba->msix_entries)); | |
560 | if (rc) { | |
561 | lpfc_printf_log(phba, KERN_INFO, LOG_INIT, | |
562 | - "0420 Enable MSI-X failed (%d), continuing " | |
563 | - "with MSI\n", rc); | |
564 | + "0420 PCI enable MSI-X failed (%d)\n", rc); | |
565 | goto msi_fail_out; | |
566 | } else | |
567 | for (i = 0; i < LPFC_MSIX_VECTORS; i++) | |
568 | @@ -2358,9 +2393,9 @@ lpfc_enable_msix(struct lpfc_hba *phba) | |
569 | rc = request_irq(phba->msix_entries[0].vector, &lpfc_sp_intr_handler, | |
570 | IRQF_SHARED, LPFC_SP_DRIVER_HANDLER_NAME, phba); | |
571 | if (rc) { | |
572 | - lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | |
573 | + lpfc_printf_log(phba, KERN_WARNING, LOG_INIT, | |
574 | "0421 MSI-X slow-path request_irq failed " | |
575 | - "(%d), continuing with MSI\n", rc); | |
576 | + "(%d)\n", rc); | |
577 | goto msi_fail_out; | |
578 | } | |
579 | ||
580 | @@ -2369,9 +2404,9 @@ lpfc_enable_msix(struct lpfc_hba *phba) | |
581 | IRQF_SHARED, LPFC_FP_DRIVER_HANDLER_NAME, phba); | |
582 | ||
583 | if (rc) { | |
584 | - lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | |
585 | + lpfc_printf_log(phba, KERN_WARNING, LOG_INIT, | |
586 | "0429 MSI-X fast-path request_irq failed " | |
587 | - "(%d), continuing with MSI\n", rc); | |
588 | + "(%d)\n", rc); | |
589 | goto irq_fail_out; | |
590 | } | |
591 | ||
592 | @@ -2392,7 +2427,7 @@ lpfc_enable_msix(struct lpfc_hba *phba) | |
593 | goto mbx_fail_out; | |
594 | rc = lpfc_sli_issue_mbox(phba, pmb, MBX_POLL); | |
595 | if (rc != MBX_SUCCESS) { | |
596 | - lpfc_printf_log(phba, KERN_ERR, LOG_MBOX, | |
597 | + lpfc_printf_log(phba, KERN_WARNING, LOG_MBOX, | |
598 | "0351 Config MSI mailbox command failed, " | |
599 | "mbxCmd x%x, mbxStatus x%x\n", | |
600 | pmb->mb.mbxCommand, pmb->mb.mbxStatus); | |
601 | @@ -2441,6 +2476,111 @@ lpfc_disable_msix(struct lpfc_hba *phba) | |
602 | } | |
603 | ||
604 | /** | |
605 | + * lpfc_enable_msi: Enable MSI interrupt mode. | |
606 | + * @phba: pointer to lpfc hba data structure. | |
607 | + * | |
608 | + * This routine is invoked to enable the MSI interrupt mode. The kernel | |
609 | + * function pci_enable_msi() is called to enable the MSI vector. The | |
610 | + * device driver is responsible for calling the request_irq() to register | |
611 | + * MSI vector with a interrupt the handler, which is done in this function. | |
612 | + * | |
613 | + * Return codes | |
614 | + * 0 - sucessful | |
615 | + * other values - error | |
616 | + */ | |
617 | +static int | |
618 | +lpfc_enable_msi(struct lpfc_hba *phba) | |
619 | +{ | |
620 | + int rc; | |
621 | + | |
622 | + rc = pci_enable_msi(phba->pcidev); | |
623 | + if (!rc) | |
624 | + lpfc_printf_log(phba, KERN_INFO, LOG_INIT, | |
625 | + "0462 PCI enable MSI mode success.\n"); | |
626 | + else { | |
627 | + lpfc_printf_log(phba, KERN_INFO, LOG_INIT, | |
628 | + "0471 PCI enable MSI mode failed (%d)\n", rc); | |
629 | + return rc; | |
630 | + } | |
631 | + | |
632 | + rc = request_irq(phba->pcidev->irq, lpfc_intr_handler, | |
633 | + IRQF_SHARED, LPFC_DRIVER_NAME, phba); | |
634 | + if (rc) { | |
635 | + pci_disable_msi(phba->pcidev); | |
636 | + lpfc_printf_log(phba, KERN_WARNING, LOG_INIT, | |
637 | + "0478 MSI request_irq failed (%d)\n", rc); | |
638 | + } | |
639 | + return rc; | |
640 | +} | |
641 | + | |
642 | +/** | |
643 | + * lpfc_disable_msi: Disable MSI interrupt mode. | |
644 | + * @phba: pointer to lpfc hba data structure. | |
645 | + * | |
646 | + * This routine is invoked to disable the MSI interrupt mode. The driver | |
647 | + * calls free_irq() on MSI vector it has done request_irq() on before | |
648 | + * calling pci_disable_msi(). Failure to do so results in a BUG_ON() and | |
649 | + * a device will be left with MSI enabled and leaks its vector. | |
650 | + */ | |
651 | + | |
652 | +static void | |
653 | +lpfc_disable_msi(struct lpfc_hba *phba) | |
654 | +{ | |
655 | + free_irq(phba->pcidev->irq, phba); | |
656 | + pci_disable_msi(phba->pcidev); | |
657 | + return; | |
658 | +} | |
659 | + | |
660 | +/** | |
661 | + * lpfc_log_intr_mode: Log the active interrupt mode | |
662 | + * @phba: pointer to lpfc hba data structure. | |
663 | + * @intr_mode: active interrupt mode adopted. | |
664 | + * | |
665 | + * This routine it invoked to log the currently used active interrupt mode | |
666 | + * to the device. | |
667 | + */ | |
668 | +static void | |
669 | +lpfc_log_intr_mode(struct lpfc_hba *phba, uint32_t intr_mode) | |
670 | +{ | |
671 | + switch (intr_mode) { | |
672 | + case 0: | |
673 | + lpfc_printf_log(phba, KERN_INFO, LOG_INIT, | |
674 | + "0470 Enable INTx interrupt mode.\n"); | |
675 | + break; | |
676 | + case 1: | |
677 | + lpfc_printf_log(phba, KERN_INFO, LOG_INIT, | |
678 | + "0481 Enabled MSI interrupt mode.\n"); | |
679 | + break; | |
680 | + case 2: | |
681 | + lpfc_printf_log(phba, KERN_INFO, LOG_INIT, | |
682 | + "0480 Enabled MSI-X interrupt mode.\n"); | |
683 | + break; | |
684 | + default: | |
685 | + lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | |
686 | + "0482 Illegal interrupt mode.\n"); | |
687 | + break; | |
688 | + } | |
689 | + return; | |
690 | +} | |
691 | + | |
692 | +static void | |
693 | +lpfc_stop_port(struct lpfc_hba *phba) | |
694 | +{ | |
695 | + /* Clear all interrupt enable conditions */ | |
696 | + writel(0, phba->HCregaddr); | |
697 | + readl(phba->HCregaddr); /* flush */ | |
698 | + /* Clear all pending interrupts */ | |
699 | + writel(0xffffffff, phba->HAregaddr); | |
700 | + readl(phba->HAregaddr); /* flush */ | |
701 | + | |
702 | + /* Reset some HBA SLI setup states */ | |
703 | + lpfc_stop_phba_timers(phba); | |
704 | + phba->pport->work_port_events = 0; | |
705 | + | |
706 | + return; | |
707 | +} | |
708 | + | |
709 | +/** | |
710 | * lpfc_enable_intr: Enable device interrupt. | |
711 | * @phba: pointer to lpfc hba data structure. | |
712 | * | |
713 | @@ -2454,60 +2594,47 @@ lpfc_disable_msix(struct lpfc_hba *phba) | |
714 | * 0 - sucessful | |
715 | * other values - error | |
716 | **/ | |
717 | -static int | |
718 | -lpfc_enable_intr(struct lpfc_hba *phba) | |
719 | +static uint32_t | |
720 | +lpfc_enable_intr(struct lpfc_hba *phba, uint32_t cfg_mode) | |
721 | { | |
722 | - int retval = 0; | |
723 | - | |
724 | - /* Starting point of configuring interrupt method */ | |
725 | - phba->intr_type = NONE; | |
726 | + uint32_t intr_mode = LPFC_INTR_ERROR; | |
727 | + int retval; | |
728 | ||
729 | - if (phba->cfg_use_msi == 2) { | |
730 | + if (cfg_mode == 2) { | |
731 | /* Need to issue conf_port mbox cmd before conf_msi mbox cmd */ | |
732 | retval = lpfc_sli_config_port(phba, 3); | |
733 | - if (retval) | |
734 | - lpfc_printf_log(phba, KERN_INFO, LOG_INIT, | |
735 | - "0478 Firmware not capable of SLI 3 mode.\n"); | |
736 | - else { | |
737 | - lpfc_printf_log(phba, KERN_INFO, LOG_INIT, | |
738 | - "0479 Firmware capable of SLI 3 mode.\n"); | |
739 | + if (!retval) { | |
740 | /* Now, try to enable MSI-X interrupt mode */ | |
741 | retval = lpfc_enable_msix(phba); | |
742 | if (!retval) { | |
743 | + /* Indicate initialization to MSI-X mode */ | |
744 | phba->intr_type = MSIX; | |
745 | - lpfc_printf_log(phba, KERN_INFO, LOG_INIT, | |
746 | - "0480 enable MSI-X mode.\n"); | |
747 | + intr_mode = 2; | |
748 | } | |
749 | } | |
750 | } | |
751 | ||
752 | /* Fallback to MSI if MSI-X initialization failed */ | |
753 | - if (phba->cfg_use_msi >= 1 && phba->intr_type == NONE) { | |
754 | - retval = pci_enable_msi(phba->pcidev); | |
755 | + if (cfg_mode >= 1 && phba->intr_type == NONE) { | |
756 | + retval = lpfc_enable_msi(phba); | |
757 | if (!retval) { | |
758 | + /* Indicate initialization to MSI mode */ | |
759 | phba->intr_type = MSI; | |
760 | - lpfc_printf_log(phba, KERN_INFO, LOG_INIT, | |
761 | - "0481 enable MSI mode.\n"); | |
762 | - } else | |
763 | - lpfc_printf_log(phba, KERN_INFO, LOG_INIT, | |
764 | - "0470 enable IRQ mode.\n"); | |
765 | + intr_mode = 1; | |
766 | + } | |
767 | } | |
768 | ||
769 | - /* MSI-X is the only case the doesn't need to call request_irq */ | |
770 | - if (phba->intr_type != MSIX) { | |
771 | + /* Fallback to INTx if both MSI-X/MSI initalization failed */ | |
772 | + if (phba->intr_type == NONE) { | |
773 | retval = request_irq(phba->pcidev->irq, lpfc_intr_handler, | |
774 | IRQF_SHARED, LPFC_DRIVER_NAME, phba); | |
775 | - if (retval) { | |
776 | - if (phba->intr_type == MSI) | |
777 | - pci_disable_msi(phba->pcidev); | |
778 | - lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | |
779 | - "0471 Enable interrupt handler " | |
780 | - "failed\n"); | |
781 | - } else if (phba->intr_type != MSI) | |
782 | + if (!retval) { | |
783 | + /* Indicate initialization to INTx mode */ | |
784 | phba->intr_type = INTx; | |
785 | + intr_mode = 0; | |
786 | + } | |
787 | } | |
788 | - | |
789 | - return retval; | |
790 | + return intr_mode; | |
791 | } | |
792 | ||
793 | /** | |
794 | @@ -2522,13 +2649,18 @@ lpfc_enable_intr(struct lpfc_hba *phba) | |
795 | static void | |
796 | lpfc_disable_intr(struct lpfc_hba *phba) | |
797 | { | |
798 | + /* Disable the currently initialized interrupt mode */ | |
799 | if (phba->intr_type == MSIX) | |
800 | lpfc_disable_msix(phba); | |
801 | - else { | |
802 | + else if (phba->intr_type == MSI) | |
803 | + lpfc_disable_msi(phba); | |
804 | + else if (phba->intr_type == INTx) | |
805 | free_irq(phba->pcidev->irq, phba); | |
806 | - if (phba->intr_type == MSI) | |
807 | - pci_disable_msi(phba->pcidev); | |
808 | - } | |
809 | + | |
810 | + /* Reset interrupt management states */ | |
811 | + phba->intr_type = NONE; | |
812 | + phba->sli.slistat.sli_intr = 0; | |
813 | + | |
814 | return; | |
815 | } | |
816 | ||
817 | @@ -2562,6 +2694,7 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) | |
818 | int error = -ENODEV, retval; | |
819 | int i, hbq_count; | |
820 | uint16_t iotag; | |
821 | + uint32_t cfg_mode, intr_mode; | |
822 | int bars = pci_select_bars(pdev, IORESOURCE_MEM); | |
823 | struct lpfc_adapter_event_header adapter_event; | |
824 | ||
825 | @@ -2593,6 +2726,9 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) | |
826 | * establish the host. | |
827 | */ | |
828 | lpfc_get_cfgparam(phba); | |
829 | + /* Check if we need to change the DMA length */ | |
830 | + lpfc_setup_max_dma_length(phba); | |
831 | + | |
832 | phba->max_vpi = lpfc_hba_max_vpi(phba->pcidev->device); | |
833 | ||
834 | /* Initialize timers used by driver */ | |
835 | @@ -2615,6 +2751,7 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) | |
836 | phba->eratt_poll.data = (unsigned long) phba; | |
837 | ||
838 | pci_set_master(pdev); | |
839 | + pci_save_state(pdev); | |
840 | pci_try_set_mwi(pdev); | |
841 | ||
842 | if (pci_set_dma_mask(phba->pcidev, DMA_64BIT_MASK) != 0) | |
843 | @@ -2769,9 +2906,6 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) | |
844 | ||
845 | if ((lpfc_get_security_enabled)(shost)) { | |
846 | unsigned long flags; | |
847 | - /* Triggers fcauthd to register if it is running */ | |
848 | - fc_host_post_event(shost, fc_get_event_number(), | |
849 | - FCH_EVT_PORT_ONLINE, shost->host_no); | |
850 | spin_lock_irqsave(&fc_security_user_lock, flags); | |
851 | list_add_tail(&vport->sc_users, &fc_security_user_list); | |
852 | spin_unlock_irqrestore(&fc_security_user_lock, flags); | |
853 | @@ -2779,6 +2913,9 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) | |
854 | lpfc_fc_queue_security_work(vport, | |
855 | &vport->sc_online_work); | |
856 | } | |
857 | + /* Triggers fcauthd to register if it is running */ | |
858 | + fc_host_post_event(shost, fc_get_event_number(), | |
859 | + FCH_EVT_PORT_ONLINE, shost->host_no); | |
860 | } | |
861 | phba->pport = vport; | |
862 | lpfc_debugfs_initialize(vport); | |
863 | @@ -2791,34 +2928,66 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) | |
864 | phba->HSregaddr = phba->ctrl_regs_memmap_p + HS_REG_OFFSET; | |
865 | phba->HCregaddr = phba->ctrl_regs_memmap_p + HC_REG_OFFSET; | |
866 | ||
867 | - /* Configure and enable interrupt */ | |
868 | - error = lpfc_enable_intr(phba); | |
869 | - if (error) { | |
870 | - lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | |
871 | - "0426 Failed to enable interrupt.\n"); | |
872 | - goto out_destroy_port; | |
873 | - } | |
874 | - | |
875 | + /* Confiugre sysfs attributes */ | |
876 | phba->dfc_host = lpfcdfc_host_add(pdev, shost, phba); | |
877 | if (!phba->dfc_host) { | |
878 | lpfc_printf_log(phba, KERN_ERR, LOG_LIBDFC, | |
879 | "1201 Failed to allocate dfc_host \n"); | |
880 | error = -ENOMEM; | |
881 | - goto out_free_irq; | |
882 | + goto out_destroy_port; | |
883 | } | |
884 | ||
885 | if (lpfc_alloc_sysfs_attr(vport)) { | |
886 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | |
887 | "1476 Failed to allocate sysfs attr\n"); | |
888 | error = -ENOMEM; | |
889 | - goto out_free_irq; | |
890 | + goto out_del_dfc_host; | |
891 | } | |
892 | ||
893 | - if (lpfc_sli_hba_setup(phba)) { | |
894 | - lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | |
895 | - "1477 Failed to set up hba\n"); | |
896 | - error = -ENODEV; | |
897 | - goto out_remove_device; | |
898 | + cfg_mode = phba->cfg_use_msi; | |
899 | + while (true) { | |
900 | + /* Configure and enable interrupt */ | |
901 | + intr_mode = lpfc_enable_intr(phba, cfg_mode); | |
902 | + if (intr_mode == LPFC_INTR_ERROR) { | |
903 | + lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | |
904 | + "0426 Failed to enable interrupt.\n"); | |
905 | + goto out_free_sysfs_attr; | |
906 | + } | |
907 | + /* HBA SLI setup */ | |
908 | + if (lpfc_sli_hba_setup(phba)) { | |
909 | + lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | |
910 | + "1477 Failed to set up hba\n"); | |
911 | + error = -ENODEV; | |
912 | + goto out_remove_device; | |
913 | + } | |
914 | + | |
915 | + /* Wait 50ms for the interrupts of previous mailbox commands */ | |
916 | + msleep(50); | |
917 | + /* Check active interrupts received */ | |
918 | + if (phba->sli.slistat.sli_intr > LPFC_INTR_THRESHOLD) { | |
919 | + /* Log the current active interrupt mode */ | |
920 | + phba->intr_mode = intr_mode; | |
921 | + lpfc_log_intr_mode(phba, intr_mode); | |
922 | + break; | |
923 | + } else { | |
924 | + lpfc_printf_log(phba, KERN_INFO, LOG_INIT, | |
925 | + "0451 Configure interrupt mode (%d) " | |
926 | + "failed active interrupt test.\n", | |
927 | + intr_mode); | |
928 | + if (intr_mode == 0) { | |
929 | + lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | |
930 | + "0479 Failed to enable " | |
931 | + "interrupt.\n"); | |
932 | + error = -ENODEV; | |
933 | + goto out_remove_device; | |
934 | + } | |
935 | + /* Stop HBA SLI setups */ | |
936 | + lpfc_stop_port(phba); | |
937 | + /* Disable the current interrupt mode */ | |
938 | + lpfc_disable_intr(phba); | |
939 | + /* Try next level of interrupt mode */ | |
940 | + cfg_mode = --intr_mode; | |
941 | + } | |
942 | } | |
943 | ||
944 | /* | |
945 | @@ -2850,16 +3019,19 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) | |
946 | return 0; | |
947 | ||
948 | out_remove_device: | |
949 | - lpfc_free_sysfs_attr(vport); | |
950 | spin_lock_irq(shost->host_lock); | |
951 | vport->load_flag |= FC_UNLOADING; | |
952 | spin_unlock_irq(shost->host_lock); | |
953 | -out_free_irq: | |
954 | - if (phba->dfc_host) | |
955 | - lpfcdfc_host_del(phba->dfc_host); | |
956 | lpfc_stop_phba_timers(phba); | |
957 | phba->pport->work_port_events = 0; | |
958 | lpfc_disable_intr(phba); | |
959 | + lpfc_sli_hba_down(phba); | |
960 | + lpfc_sli_brdrestart(phba); | |
961 | +out_free_sysfs_attr: | |
962 | + lpfc_free_sysfs_attr(vport); | |
963 | +out_del_dfc_host: | |
964 | + if (phba->dfc_host) | |
965 | + lpfcdfc_host_del(phba->dfc_host); | |
966 | out_destroy_port: | |
967 | destroy_port(vport); | |
968 | out_kthread_stop: | |
969 | @@ -3051,6 +3223,7 @@ lpfc_pci_resume_one(struct pci_dev *pdev) | |
970 | { | |
971 | struct Scsi_Host *shost = pci_get_drvdata(pdev); | |
972 | struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba; | |
973 | + uint32_t intr_mode; | |
974 | int error; | |
975 | ||
976 | lpfc_printf_log(phba, KERN_INFO, LOG_INIT, | |
977 | @@ -3073,19 +3246,22 @@ lpfc_pci_resume_one(struct pci_dev *pdev) | |
978 | return error; | |
979 | } | |
980 | ||
981 | - /* Enable interrupt from device */ | |
982 | - error = lpfc_enable_intr(phba); | |
983 | - if (error) { | |
984 | + /* Configure and enable interrupt */ | |
985 | + intr_mode = lpfc_enable_intr(phba, phba->intr_mode); | |
986 | + if (intr_mode == LPFC_INTR_ERROR) { | |
987 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | |
988 | - "0430 PM resume Failed to enable interrupt: " | |
989 | - "error=x%x.\n", error); | |
990 | - return error; | |
991 | - } | |
992 | + "0430 PM resume Failed to enable interrupt\n"); | |
993 | + return -EIO; | |
994 | + } else | |
995 | + phba->intr_mode = intr_mode; | |
996 | ||
997 | /* Restart HBA and bring it online */ | |
998 | lpfc_sli_brdrestart(phba); | |
999 | lpfc_online(phba); | |
1000 | ||
1001 | + /* Log the current active interrupt mode */ | |
1002 | + lpfc_log_intr_mode(phba, phba->intr_mode); | |
1003 | + | |
1004 | return 0; | |
1005 | } | |
1006 | ||
1007 | @@ -3161,7 +3337,7 @@ static pci_ers_result_t lpfc_io_slot_reset(struct pci_dev *pdev) | |
1008 | struct Scsi_Host *shost = pci_get_drvdata(pdev); | |
1009 | struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba; | |
1010 | struct lpfc_sli *psli = &phba->sli; | |
1011 | - int error; | |
1012 | + uint32_t intr_mode; | |
1013 | ||
1014 | dev_printk(KERN_INFO, &pdev->dev, "recovering from a slot reset.\n"); | |
1015 | if (pci_enable_device_mem(pdev)) { | |
1016 | @@ -3170,25 +3346,31 @@ static pci_ers_result_t lpfc_io_slot_reset(struct pci_dev *pdev) | |
1017 | return PCI_ERS_RESULT_DISCONNECT; | |
1018 | } | |
1019 | ||
1020 | - pci_set_master(pdev); | |
1021 | + pci_restore_state(pdev); | |
1022 | + if (pdev->is_busmaster) | |
1023 | + pci_set_master(pdev); | |
1024 | ||
1025 | spin_lock_irq(&phba->hbalock); | |
1026 | psli->sli_flag &= ~LPFC_SLI2_ACTIVE; | |
1027 | spin_unlock_irq(&phba->hbalock); | |
1028 | ||
1029 | - /* Enable configured interrupt method */ | |
1030 | - error = lpfc_enable_intr(phba); | |
1031 | - if (error) { | |
1032 | + /* Configure and enable interrupt */ | |
1033 | + intr_mode = lpfc_enable_intr(phba, phba->intr_mode); | |
1034 | + if (intr_mode == LPFC_INTR_ERROR) { | |
1035 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | |
1036 | "0427 Cannot re-enable interrupt after " | |
1037 | "slot reset.\n"); | |
1038 | return PCI_ERS_RESULT_DISCONNECT; | |
1039 | - } | |
1040 | + } else | |
1041 | + phba->intr_mode = intr_mode; | |
1042 | ||
1043 | /* Take device offline; this will perform cleanup */ | |
1044 | lpfc_offline(phba); | |
1045 | lpfc_sli_brdrestart(phba); | |
1046 | ||
1047 | + /* Log the current active interrupt mode */ | |
1048 | + lpfc_log_intr_mode(phba, phba->intr_mode); | |
1049 | + | |
1050 | return PCI_ERS_RESULT_RECOVERED; | |
1051 | } | |
1052 | ||
1053 | diff --git a/drivers/scsi/lpfc/lpfc_ioctl.c b/drivers/scsi/lpfc/lpfc_ioctl.c | |
1054 | index e80d157..127b47b 100644 | |
1055 | --- a/drivers/scsi/lpfc/lpfc_ioctl.c | |
1056 | +++ b/drivers/scsi/lpfc/lpfc_ioctl.c | |
1057 | @@ -162,7 +162,7 @@ lpfc_ioctl_hba_rnid(struct lpfc_hba * phba, | |
1058 | for (i0 = 0; | |
1059 | i0 < 10 && (pndl->nlp_flag & NLP_ELS_SND_MASK) == NLP_RNID_SND; | |
1060 | i0++) { | |
1061 | - mdelay(1000); | |
1062 | + msleep(1000); | |
1063 | } | |
1064 | ||
1065 | if (i0 == 10) { | |
1066 | @@ -731,7 +731,6 @@ lpfc_ioctl_send_mgmt_cmd(struct lpfc_hba * phba, | |
1067 | outdmp = dfc_cmd_data_alloc(phba, NULL, bpl, snsbfrcnt); | |
1068 | if (!outdmp) { | |
1069 | rc = ENOMEM; | |
1070 | - spin_lock_irq(shost->host_lock); | |
1071 | goto send_mgmt_cmd_free_indmp; | |
1072 | } | |
1073 | ||
1074 | @@ -1104,7 +1103,7 @@ lpfc_ioctl_loopback_mode(struct lpfc_hba *phba, | |
1075 | if (i++ > 500) /* wait up to 5 seconds */ | |
1076 | break; | |
1077 | ||
1078 | - mdelay(10); | |
1079 | + msleep(10); | |
1080 | } | |
1081 | ||
1082 | memset((void *)pmboxq, 0, sizeof (LPFC_MBOXQ_t)); | |
1083 | diff --git a/drivers/scsi/lpfc/lpfc_mbox.c b/drivers/scsi/lpfc/lpfc_mbox.c | |
1084 | index f0ab456..84619ed 100644 | |
1085 | --- a/drivers/scsi/lpfc/lpfc_mbox.c | |
1086 | +++ b/drivers/scsi/lpfc/lpfc_mbox.c | |
1087 | @@ -835,6 +835,40 @@ lpfc_config_pcb_setup(struct lpfc_hba * phba) | |
1088 | } | |
1089 | ||
1090 | /** | |
1091 | + * lpfc_set_var: Prepare a mailbox command to write slim. | |
1092 | + * @phba: pointer to lpfc hba data structure. | |
1093 | + * @pmb: pointer to the driver internal queue element for mailbox command. | |
1094 | + * @addr: This the set variable number that identifies the variable. | |
1095 | + * @value:The value that we are setting the parameter to. | |
1096 | + * | |
1097 | + * The routine just sets the addr and value in the set variable mailbox | |
1098 | + * command structure. | |
1099 | + * returns: NONE. | |
1100 | + **/ | |
1101 | +void | |
1102 | +lpfc_set_var(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb, uint32_t addr, | |
1103 | + uint32_t value) | |
1104 | +{ | |
1105 | + MAILBOX_t *mb; | |
1106 | + | |
1107 | + mb = &pmb->mb; | |
1108 | + memset(pmb, 0, sizeof(LPFC_MBOXQ_t)); | |
1109 | + | |
1110 | + /* | |
1111 | + * Always turn on DELAYED ABTS for ELS timeouts | |
1112 | + */ | |
1113 | + if ((addr == 0x052198) && (value == 0)) | |
1114 | + value = 1; | |
1115 | + | |
1116 | + mb->un.varWords[0] = addr; | |
1117 | + mb->un.varWords[1] = value; | |
1118 | + | |
1119 | + mb->mbxCommand = MBX_SET_VARIABLE; | |
1120 | + mb->mbxOwner = OWN_HOST; | |
1121 | + return; | |
1122 | +} | |
1123 | + | |
1124 | +/** | |
1125 | * lpfc_read_rev: Prepare a mailbox command for reading HBA revision. | |
1126 | * @phba: pointer to lpfc hba data structure. | |
1127 | * @pmb: pointer to the driver internal queue element for mailbox command. | |
1128 | @@ -1093,6 +1127,9 @@ lpfc_config_port(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |
1129 | mb->un.varCfgPort.pcbLow = putPaddrLow(pdma_addr); | |
1130 | mb->un.varCfgPort.pcbHigh = putPaddrHigh(pdma_addr); | |
1131 | ||
1132 | + /* Always Host Group Pointer is in SLIM */ | |
1133 | + mb->un.varCfgPort.hps = 1; | |
1134 | + | |
1135 | /* If HBA supports SLI=3 ask for it */ | |
1136 | ||
1137 | if (phba->sli_rev == 3 && phba->vpd.sli3Feat.cerbm) { | |
1138 | @@ -1195,16 +1232,11 @@ lpfc_config_port(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |
1139 | sizeof(*phba->host_gp)); | |
1140 | } | |
1141 | ||
1142 | - /* Setup Port Group ring pointer */ | |
1143 | - if (phba->sli3_options & LPFC_SLI3_INB_ENABLED) { | |
1144 | - pgp_offset = offsetof(struct lpfc_sli2_slim, | |
1145 | - mbx.us.s3_inb_pgp.port); | |
1146 | - phba->hbq_get = phba->mbox->us.s3_inb_pgp.hbq_get; | |
1147 | - } else if (phba->sli_rev == 3) { | |
1148 | + /* Setup Port Group offset */ | |
1149 | + if (phba->sli_rev == 3) | |
1150 | pgp_offset = offsetof(struct lpfc_sli2_slim, | |
1151 | mbx.us.s3_pgp.port); | |
1152 | - phba->hbq_get = phba->mbox->us.s3_pgp.hbq_get; | |
1153 | - } else | |
1154 | + else | |
1155 | pgp_offset = offsetof(struct lpfc_sli2_slim, mbx.us.s2.port); | |
1156 | pdma_addr = phba->slim2p.phys + pgp_offset; | |
1157 | phba->pcb->pgpAddrHigh = putPaddrHigh(pdma_addr); | |
1158 | diff --git a/drivers/scsi/lpfc/lpfc_menlo.c b/drivers/scsi/lpfc/lpfc_menlo.c | |
1159 | index aa36c16..4f3b332 100644 | |
1160 | --- a/drivers/scsi/lpfc/lpfc_menlo.c | |
1161 | +++ b/drivers/scsi/lpfc/lpfc_menlo.c | |
1162 | @@ -289,19 +289,16 @@ static void | |
1163 | sysfs_menlo_idle(struct lpfc_hba *phba, | |
1164 | struct lpfc_sysfs_menlo *sysfs_menlo) | |
1165 | { | |
1166 | - struct Scsi_Host *shost = lpfc_shost_from_vport(phba->pport); | |
1167 | ||
1168 | spin_lock_irq(&phba->hbalock); | |
1169 | list_del_init(&sysfs_menlo->list); | |
1170 | spin_unlock_irq(&phba->hbalock); | |
1171 | - spin_lock_irq(shost->host_lock); | |
1172 | ||
1173 | if (sysfs_menlo->cr.cmdiocbq) | |
1174 | sysfs_menlo_genreq_free(phba, &sysfs_menlo->cr); | |
1175 | if (sysfs_menlo->cx.cmdiocbq) | |
1176 | sysfs_menlo_genreq_free(phba, &sysfs_menlo->cx); | |
1177 | ||
1178 | - spin_unlock_irq(shost->host_lock); | |
1179 | kfree(sysfs_menlo); | |
1180 | } | |
1181 | ||
1182 | @@ -543,14 +540,15 @@ lpfc_menlo_write(struct lpfc_hba *phba, | |
1183 | } | |
1184 | ||
1185 | if ((count + sysfs_menlo->cr.offset) > sysfs_menlo->cmdhdr.cmdsize) { | |
1186 | - if ( sysfs_menlo->cmdhdr.cmdsize != 4) { | |
1187 | - lpfc_printf_log(phba, KERN_ERR, LOG_LIBDFC, | |
1188 | + if (sysfs_menlo->cmdhdr.cmdsize >= | |
1189 | + sizeof(struct lpfc_sysfs_menlo_hdr)) { | |
1190 | + lpfc_printf_log(phba, KERN_ERR, LOG_LIBDFC, | |
1191 | "1213 FCoE cmd overflow: off %d + cnt %d > cmdsz %d\n", | |
1192 | - (int)sysfs_menlo->cr.offset, | |
1193 | - (int)count, | |
1194 | - (int)sysfs_menlo->cmdhdr.cmdsize); | |
1195 | - sysfs_menlo_idle(phba, sysfs_menlo); | |
1196 | - return -ERANGE; | |
1197 | + (int)sysfs_menlo->cr.offset, | |
1198 | + (int)count, | |
1199 | + (int)sysfs_menlo->cmdhdr.cmdsize); | |
1200 | + sysfs_menlo_idle(phba, sysfs_menlo); | |
1201 | + return -ERANGE; | |
1202 | } | |
1203 | } | |
1204 | ||
1205 | diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c | |
1206 | index 0c25d97..8f548ad 100644 | |
1207 | --- a/drivers/scsi/lpfc/lpfc_nportdisc.c | |
1208 | +++ b/drivers/scsi/lpfc/lpfc_nportdisc.c | |
1209 | @@ -1929,10 +1929,10 @@ lpfc_device_recov_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | |
1210 | if (vport->fc_flag & FC_RSCN_DEFERRED) | |
1211 | return ndlp->nlp_state; | |
1212 | ||
1213 | + lpfc_cancel_retry_delay_tmo(vport, ndlp); | |
1214 | spin_lock_irq(shost->host_lock); | |
1215 | ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC); | |
1216 | spin_unlock_irq(shost->host_lock); | |
1217 | - lpfc_cancel_retry_delay_tmo(vport, ndlp); | |
1218 | return ndlp->nlp_state; | |
1219 | } | |
1220 | ||
1221 | diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c | |
1222 | index daf400e..38a7faf 100644 | |
1223 | --- a/drivers/scsi/lpfc/lpfc_scsi.c | |
1224 | +++ b/drivers/scsi/lpfc/lpfc_scsi.c | |
1225 | @@ -65,6 +65,8 @@ lpfc_update_stats(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd) | |
1226 | if (cmd->result) | |
1227 | return; | |
1228 | ||
1229 | + latency = jiffies_to_msecs((long)jiffies - (long)lpfc_cmd->start_time); | |
1230 | + | |
1231 | spin_lock_irqsave(shost->host_lock, flags); | |
1232 | if (!vport->stat_data_enabled || | |
1233 | vport->stat_data_blocked || | |
1234 | @@ -73,13 +75,15 @@ lpfc_update_stats(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd) | |
1235 | spin_unlock_irqrestore(shost->host_lock, flags); | |
1236 | return; | |
1237 | } | |
1238 | - latency = jiffies_to_msecs(jiffies - lpfc_cmd->start_time); | |
1239 | ||
1240 | if (phba->bucket_type == LPFC_LINEAR_BUCKET) { | |
1241 | i = (latency + phba->bucket_step - 1 - phba->bucket_base)/ | |
1242 | phba->bucket_step; | |
1243 | - if (i >= LPFC_MAX_BUCKET_COUNT) | |
1244 | - i = LPFC_MAX_BUCKET_COUNT; | |
1245 | + /* check array subscript bounds */ | |
1246 | + if (i < 0) | |
1247 | + i = 0; | |
1248 | + else if (i >= LPFC_MAX_BUCKET_COUNT) | |
1249 | + i = LPFC_MAX_BUCKET_COUNT - 1; | |
1250 | } else { | |
1251 | for (i = 0; i < LPFC_MAX_BUCKET_COUNT-1; i++) | |
1252 | if (latency <= (phba->bucket_base + | |
1253 | @@ -413,14 +417,14 @@ lpfc_new_scsi_buf(struct lpfc_vport *vport) | |
1254 | bpl[0].addrLow = le32_to_cpu(putPaddrLow(pdma_phys_fcp_cmd)); | |
1255 | bpl[0].tus.f.bdeSize = sizeof(struct fcp_cmnd); | |
1256 | bpl[0].tus.f.bdeFlags = BUFF_TYPE_BDE_64; | |
1257 | - bpl[0].tus.w = le32_to_cpu(bpl->tus.w); | |
1258 | + bpl[0].tus.w = le32_to_cpu(bpl[0].tus.w); | |
1259 | ||
1260 | /* Setup the physical region for the FCP RSP */ | |
1261 | bpl[1].addrHigh = le32_to_cpu(putPaddrHigh(pdma_phys_fcp_rsp)); | |
1262 | bpl[1].addrLow = le32_to_cpu(putPaddrLow(pdma_phys_fcp_rsp)); | |
1263 | bpl[1].tus.f.bdeSize = sizeof(struct fcp_rsp); | |
1264 | bpl[1].tus.f.bdeFlags = BUFF_TYPE_BDE_64; | |
1265 | - bpl[1].tus.w = le32_to_cpu(bpl->tus.w); | |
1266 | + bpl[1].tus.w = le32_to_cpu(bpl[1].tus.w); | |
1267 | ||
1268 | /* | |
1269 | * Since the IOCB for the FCP I/O is built into this lpfc_scsi_buf, | |
1270 | @@ -920,7 +924,7 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, | |
1271 | if (!pnode || !NLP_CHK_NODE_ACT(pnode) | |
1272 | || (pnode->nlp_state != NLP_STE_MAPPED_NODE)) | |
1273 | cmd->result = ScsiResult(DID_TRANSPORT_DISRUPTED, | |
1274 | - SAM_STAT_BUSY); | |
1275 | + SAM_STAT_BUSY); | |
1276 | } else { | |
1277 | cmd->result = ScsiResult(DID_OK, 0); | |
1278 | } | |
1279 | diff --git a/drivers/scsi/lpfc/lpfc_security.c b/drivers/scsi/lpfc/lpfc_security.c | |
1280 | index c0fbe56..3d2a8c8 100644 | |
1281 | --- a/drivers/scsi/lpfc/lpfc_security.c | |
1282 | +++ b/drivers/scsi/lpfc/lpfc_security.c | |
1283 | @@ -45,8 +45,7 @@ lpfc_security_service_online(struct Scsi_Host *shost) | |
1284 | ||
1285 | lpfc_security_service_state = SECURITY_ONLINE; | |
1286 | if (vport->cfg_enable_auth && | |
1287 | - vport->auth.auth_mode == FC_AUTHMODE_UNKNOWN && | |
1288 | - vport->phba->link_state == LPFC_HBA_ERROR) | |
1289 | + vport->auth.auth_mode == FC_AUTHMODE_UNKNOWN) | |
1290 | lpfc_selective_reset(vport->phba); | |
1291 | } | |
1292 | ||
1293 | diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c | |
1294 | index ac78493..5838e41 100644 | |
1295 | --- a/drivers/scsi/lpfc/lpfc_sli.c | |
1296 | +++ b/drivers/scsi/lpfc/lpfc_sli.c | |
1297 | @@ -1262,68 +1262,6 @@ lpfc_sli_handle_mb_event(struct lpfc_hba *phba) | |
1298 | } | |
1299 | ||
1300 | /** | |
1301 | - * lpfc_sli_replace_hbqbuff: Replace the HBQ buffer with a new buffer. | |
1302 | - * @phba: Pointer to HBA context object. | |
1303 | - * @tag: Tag for the HBQ buffer. | |
1304 | - * | |
1305 | - * This function is called from unsolicited event handler code path to get the | |
1306 | - * HBQ buffer associated with an unsolicited iocb. This function is called with | |
1307 | - * no lock held. It returns the buffer associated with the given tag and posts | |
1308 | - * another buffer to the firmware. Note that the new buffer must be allocated | |
1309 | - * before taking the hbalock and that the hba lock must be held until it is | |
1310 | - * finished with the hbq entry swap. | |
1311 | - **/ | |
1312 | -static struct lpfc_dmabuf * | |
1313 | -lpfc_sli_replace_hbqbuff(struct lpfc_hba *phba, uint32_t tag) | |
1314 | -{ | |
1315 | - struct hbq_dmabuf *hbq_entry, *new_hbq_entry; | |
1316 | - uint32_t hbqno; | |
1317 | - void *virt; /* virtual address ptr */ | |
1318 | - dma_addr_t phys; /* mapped address */ | |
1319 | - unsigned long flags; | |
1320 | - | |
1321 | - hbqno = tag >> 16; | |
1322 | - new_hbq_entry = (phba->hbqs[hbqno].hbq_alloc_buffer)(phba); | |
1323 | - /* Check whether HBQ is still in use */ | |
1324 | - spin_lock_irqsave(&phba->hbalock, flags); | |
1325 | - if (!phba->hbq_in_use) { | |
1326 | - if (new_hbq_entry) | |
1327 | - (phba->hbqs[hbqno].hbq_free_buffer)(phba, | |
1328 | - new_hbq_entry); | |
1329 | - spin_unlock_irqrestore(&phba->hbalock, flags); | |
1330 | - return NULL; | |
1331 | - } | |
1332 | - | |
1333 | - hbq_entry = lpfc_sli_hbqbuf_find(phba, tag); | |
1334 | - if (hbq_entry == NULL) { | |
1335 | - if (new_hbq_entry) | |
1336 | - (phba->hbqs[hbqno].hbq_free_buffer)(phba, | |
1337 | - new_hbq_entry); | |
1338 | - spin_unlock_irqrestore(&phba->hbalock, flags); | |
1339 | - return NULL; | |
1340 | - } | |
1341 | - list_del(&hbq_entry->dbuf.list); | |
1342 | - | |
1343 | - if (new_hbq_entry == NULL) { | |
1344 | - list_add_tail(&hbq_entry->dbuf.list, &phba->hbqbuf_in_list); | |
1345 | - spin_unlock_irqrestore(&phba->hbalock, flags); | |
1346 | - return &hbq_entry->dbuf; | |
1347 | - } | |
1348 | - new_hbq_entry->tag = -1; | |
1349 | - phys = new_hbq_entry->dbuf.phys; | |
1350 | - virt = new_hbq_entry->dbuf.virt; | |
1351 | - new_hbq_entry->dbuf.phys = hbq_entry->dbuf.phys; | |
1352 | - new_hbq_entry->dbuf.virt = hbq_entry->dbuf.virt; | |
1353 | - hbq_entry->dbuf.phys = phys; | |
1354 | - hbq_entry->dbuf.virt = virt; | |
1355 | - lpfc_sli_free_hbq(phba, hbq_entry); | |
1356 | - list_add_tail(&new_hbq_entry->dbuf.list, &phba->hbqbuf_in_list); | |
1357 | - spin_unlock_irqrestore(&phba->hbalock, flags); | |
1358 | - | |
1359 | - return &new_hbq_entry->dbuf; | |
1360 | -} | |
1361 | - | |
1362 | -/** | |
1363 | * lpfc_sli_get_buff: Get the buffer associated with the buffer tag. | |
1364 | * @phba: Pointer to HBA context object. | |
1365 | * @pring: Pointer to driver SLI ring object. | |
1366 | @@ -1337,13 +1275,17 @@ lpfc_sli_replace_hbqbuff(struct lpfc_hba *phba, uint32_t tag) | |
1367 | **/ | |
1368 | static struct lpfc_dmabuf * | |
1369 | lpfc_sli_get_buff(struct lpfc_hba *phba, | |
1370 | - struct lpfc_sli_ring *pring, | |
1371 | - uint32_t tag) | |
1372 | + struct lpfc_sli_ring *pring, | |
1373 | + uint32_t tag) | |
1374 | { | |
1375 | + struct hbq_dmabuf *hbq_entry; | |
1376 | + | |
1377 | if (tag & QUE_BUFTAG_BIT) | |
1378 | return lpfc_sli_ring_taggedbuf_get(phba, pring, tag); | |
1379 | - else | |
1380 | - return lpfc_sli_replace_hbqbuff(phba, tag); | |
1381 | + hbq_entry = lpfc_sli_hbqbuf_find(phba, tag); | |
1382 | + if (!hbq_entry) | |
1383 | + return NULL; | |
1384 | + return &hbq_entry->dbuf; | |
1385 | } | |
1386 | ||
1387 | ||
1388 | @@ -1375,8 +1317,6 @@ lpfc_sli_process_unsol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |
1389 | match = 0; | |
1390 | irsp = &(saveq->iocb); | |
1391 | ||
1392 | - if (irsp->ulpStatus == IOSTAT_NEED_BUFFER) | |
1393 | - return 1; | |
1394 | if (irsp->ulpCommand == CMD_ASYNC_STATUS) { | |
1395 | if (pring->lpfc_sli_rcv_async_status) | |
1396 | pring->lpfc_sli_rcv_async_status(phba, pring, saveq); | |
1397 | @@ -2776,6 +2716,86 @@ lpfc_sli_brdreset(struct lpfc_hba *phba) | |
1398 | } | |
1399 | ||
1400 | /** | |
1401 | + * lpfc_sli_set_dma_length: Set the HBA's max DMA length. | |
1402 | + * @phba: Pointer to HBA context object. | |
1403 | + * @polling: flag that indicates if interrupts are enabled. | |
1404 | + * | |
1405 | + * This function sets the HBA's max dma length by issuing a set variable | |
1406 | + * mailbox command. The dma length is taking from the cfg_pci_max_read | |
1407 | + * configuration parameter. This parameter is passed as a module parameter | |
1408 | + * during the driver load. If the HBA does not support this set variable | |
1409 | + * mbox command the failure status will reset the cfg_pci_max_read to the | |
1410 | + * default(2048). | |
1411 | + * If interrupts are not enabled yet then the polling flag = 1 should be | |
1412 | + * be used so that the right mailbox routine is called. | |
1413 | + * This function returns 0 for success, non 0 returned for failure. | |
1414 | + **/ | |
1415 | +int | |
1416 | +lpfc_sli_set_dma_length(struct lpfc_hba *phba, uint32_t polling) | |
1417 | +{ | |
1418 | + uint32_t dma_length; | |
1419 | + LPFC_MBOXQ_t *mbox; | |
1420 | + int ret = 0; | |
1421 | + | |
1422 | + switch (phba->cfg_pci_max_read) { | |
1423 | + case 512: | |
1424 | + dma_length = SLIM_VAL_MAX_DMA_512; | |
1425 | + break; | |
1426 | + case 1024: | |
1427 | + dma_length = SLIM_VAL_MAX_DMA_1024; | |
1428 | + break; | |
1429 | + case 2048: | |
1430 | + dma_length = SLIM_VAL_MAX_DMA_2048; | |
1431 | + break; | |
1432 | + case 4096: | |
1433 | + dma_length = SLIM_VAL_MAX_DMA_4096; | |
1434 | + break; | |
1435 | + default: | |
1436 | + return -EINVAL; | |
1437 | + } | |
1438 | + | |
1439 | + mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | |
1440 | + if (!mbox) | |
1441 | + goto failed; | |
1442 | + | |
1443 | + lpfc_set_var(phba, mbox, SLIM_VAR_MAX_DMA_LENGTH, dma_length); | |
1444 | + | |
1445 | + if (polling) | |
1446 | + ret = lpfc_sli_issue_mbox(phba, mbox, MBX_POLL); | |
1447 | + else | |
1448 | + ret = lpfc_sli_issue_mbox_wait(phba, mbox, | |
1449 | + LPFC_MBOX_TMO * 2); | |
1450 | + | |
1451 | + if (ret != MBX_SUCCESS) { | |
1452 | + if (mbox->mb.mbxStatus != MBXERR_UNKNOWN_CMD) | |
1453 | + lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | |
1454 | + "%d:0443 Adapter failed to set maximum" | |
1455 | + " DMA length mbxStatus x%x \n", | |
1456 | + phba->brd_no, mbox->mb.mbxStatus); | |
1457 | + else | |
1458 | + lpfc_printf_log(phba, KERN_INFO, LOG_INIT, | |
1459 | + "%d:0447 Adapter failed to set maximum" | |
1460 | + " DMA length mbxStatus x%x \n", | |
1461 | + phba->brd_no, mbox->mb.mbxStatus); | |
1462 | + goto failed; | |
1463 | + } | |
1464 | + | |
1465 | + mempool_free(mbox, phba->mbox_mem_pool); | |
1466 | + return 0; | |
1467 | + | |
1468 | +failed: | |
1469 | + /* If mailbox command failed, reset the value to default value */ | |
1470 | + phba->cfg_pci_max_read = 2048; | |
1471 | + if (ret == MBX_TIMEOUT) { | |
1472 | + mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl; | |
1473 | + return -EPERM; | |
1474 | + } else if (mbox) { | |
1475 | + mempool_free(mbox, phba->mbox_mem_pool); | |
1476 | + return -EPERM; | |
1477 | + } else | |
1478 | + return -ENOMEM; | |
1479 | +} | |
1480 | +/** | |
1481 | * lpfc_sli_brdrestart: Restart the HBA. | |
1482 | * @phba: Pointer to HBA context object. | |
1483 | * | |
1484 | @@ -3140,17 +3160,20 @@ lpfc_sli_config_port(struct lpfc_hba *phba, int sli_mode) | |
1485 | phba->sli3_options |= LPFC_SLI3_CRP_ENABLED; | |
1486 | if (pmb->mb.un.varCfgPort.ginb) { | |
1487 | phba->sli3_options |= LPFC_SLI3_INB_ENABLED; | |
1488 | + phba->hbq_get = phba->mbox->us.s3_inb_pgp.hbq_get; | |
1489 | phba->port_gp = phba->mbox->us.s3_inb_pgp.port; | |
1490 | phba->inb_ha_copy = &phba->mbox->us.s3_inb_pgp.ha_copy; | |
1491 | phba->inb_counter = &phba->mbox->us.s3_inb_pgp.counter; | |
1492 | phba->inb_last_counter = | |
1493 | phba->mbox->us.s3_inb_pgp.counter; | |
1494 | } else { | |
1495 | + phba->hbq_get = phba->mbox->us.s3_pgp.hbq_get; | |
1496 | phba->port_gp = phba->mbox->us.s3_pgp.port; | |
1497 | phba->inb_ha_copy = NULL; | |
1498 | phba->inb_counter = NULL; | |
1499 | } | |
1500 | } else { | |
1501 | + phba->hbq_get = NULL; | |
1502 | phba->port_gp = phba->mbox->us.s2.port; | |
1503 | phba->inb_ha_copy = NULL; | |
1504 | phba->inb_counter = NULL; | |
1505 | @@ -3226,6 +3249,9 @@ lpfc_sli_hba_setup(struct lpfc_hba *phba) | |
1506 | lpfc_printf_log(phba, KERN_INFO, LOG_INIT, | |
1507 | "0444 Firmware in SLI %x mode. Max_vpi %d\n", | |
1508 | phba->sli_rev, phba->max_vpi); | |
1509 | + | |
1510 | + lpfc_sli_set_dma_length(phba, 1); | |
1511 | + | |
1512 | rc = lpfc_sli_ring_map(phba); | |
1513 | ||
1514 | if (rc) | |
1515 | @@ -3301,10 +3327,6 @@ lpfc_mbox_timeout_handler(struct lpfc_hba *phba) | |
1516 | struct lpfc_sli *psli = &phba->sli; | |
1517 | struct lpfc_sli_ring *pring; | |
1518 | ||
1519 | - if (!(phba->pport->work_port_events & WORKER_MBOX_TMO)) { | |
1520 | - return; | |
1521 | - } | |
1522 | - | |
1523 | /* Mbox cmd <mbxCommand> timeout */ | |
1524 | lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_SLI, | |
1525 | "0310 Mailbox command x%x timeout Data: x%x x%x x%p\n", | |
1526 | @@ -5275,6 +5297,7 @@ lpfc_sp_intr_handler(int irq, void *dev_id) | |
1527 | uint32_t ha_copy; | |
1528 | uint32_t work_ha_copy; | |
1529 | unsigned long status; | |
1530 | + unsigned long iflag; | |
1531 | uint32_t control; | |
1532 | ||
1533 | MAILBOX_t *mbox, *pmbox; | |
1534 | @@ -5307,7 +5330,7 @@ lpfc_sp_intr_handler(int irq, void *dev_id) | |
1535 | if (unlikely(phba->link_state < LPFC_LINK_DOWN)) | |
1536 | return IRQ_NONE; | |
1537 | /* Need to read HA REG for slow-path events */ | |
1538 | - spin_lock(&phba->hbalock); | |
1539 | + spin_lock_irqsave(&phba->hbalock, iflag); | |
1540 | ha_copy = readl(phba->HAregaddr); | |
1541 | /* If somebody is waiting to handle an eratt don't process it | |
1542 | * here. The brdkill function will do this. | |
1543 | @@ -5327,7 +5350,7 @@ lpfc_sp_intr_handler(int irq, void *dev_id) | |
1544 | writel((ha_copy & (HA_MBATT | HA_R2_CLR_MSK)), | |
1545 | phba->HAregaddr); | |
1546 | readl(phba->HAregaddr); /* flush */ | |
1547 | - spin_unlock(&phba->hbalock); | |
1548 | + spin_unlock_irqrestore(&phba->hbalock, iflag); | |
1549 | } else | |
1550 | ha_copy = phba->ha_copy; | |
1551 | ||
1552 | @@ -5340,13 +5363,13 @@ lpfc_sp_intr_handler(int irq, void *dev_id) | |
1553 | * Turn off Link Attention interrupts | |
1554 | * until CLEAR_LA done | |
1555 | */ | |
1556 | - spin_lock(&phba->hbalock); | |
1557 | + spin_lock_irqsave(&phba->hbalock, iflag); | |
1558 | phba->sli.sli_flag &= ~LPFC_PROCESS_LA; | |
1559 | control = readl(phba->HCregaddr); | |
1560 | control &= ~HC_LAINT_ENA; | |
1561 | writel(control, phba->HCregaddr); | |
1562 | readl(phba->HCregaddr); /* flush */ | |
1563 | - spin_unlock(&phba->hbalock); | |
1564 | + spin_unlock_irqrestore(&phba->hbalock, iflag); | |
1565 | } | |
1566 | else | |
1567 | work_ha_copy &= ~HA_LATT; | |
1568 | @@ -5361,7 +5384,7 @@ lpfc_sp_intr_handler(int irq, void *dev_id) | |
1569 | (HA_RXMASK << (4*LPFC_ELS_RING))); | |
1570 | status >>= (4*LPFC_ELS_RING); | |
1571 | if (status & HA_RXMASK) { | |
1572 | - spin_lock(&phba->hbalock); | |
1573 | + spin_lock_irqsave(&phba->hbalock, iflag); | |
1574 | control = readl(phba->HCregaddr); | |
1575 | ||
1576 | lpfc_debugfs_slow_ring_trc(phba, | |
1577 | @@ -5390,10 +5413,10 @@ lpfc_sp_intr_handler(int irq, void *dev_id) | |
1578 | (uint32_t)((unsigned long) | |
1579 | &phba->work_waitq)); | |
1580 | } | |
1581 | - spin_unlock(&phba->hbalock); | |
1582 | + spin_unlock_irqrestore(&phba->hbalock, iflag); | |
1583 | } | |
1584 | } | |
1585 | - spin_lock(&phba->hbalock); | |
1586 | + spin_lock_irqsave(&phba->hbalock, iflag); | |
1587 | if (work_ha_copy & HA_ERATT) | |
1588 | lpfc_sli_read_hs(phba); | |
1589 | if ((work_ha_copy & HA_MBATT) && (phba->sli.mbox_active)) { | |
1590 | @@ -5405,7 +5428,7 @@ lpfc_sp_intr_handler(int irq, void *dev_id) | |
1591 | /* First check out the status word */ | |
1592 | lpfc_sli_pcimem_bcopy(mbox, pmbox, sizeof(uint32_t)); | |
1593 | if (pmbox->mbxOwner != OWN_HOST) { | |
1594 | - spin_unlock(&phba->hbalock); | |
1595 | + spin_unlock_irqrestore(&phba->hbalock, iflag); | |
1596 | /* | |
1597 | * Stray Mailbox Interrupt, mbxCommand <cmd> | |
1598 | * mbxStatus <status> | |
1599 | @@ -5422,7 +5445,7 @@ lpfc_sp_intr_handler(int irq, void *dev_id) | |
1600 | work_ha_copy &= ~HA_MBATT; | |
1601 | } else { | |
1602 | phba->sli.mbox_active = NULL; | |
1603 | - spin_unlock(&phba->hbalock); | |
1604 | + spin_unlock_irqrestore(&phba->hbalock, iflag); | |
1605 | phba->last_completion_time = jiffies; | |
1606 | del_timer(&phba->sli.mbox_tmo); | |
1607 | if (pmb->mbox_cmpl) { | |
1608 | @@ -5480,14 +5503,18 @@ lpfc_sp_intr_handler(int irq, void *dev_id) | |
1609 | goto send_current_mbox; | |
1610 | } | |
1611 | } | |
1612 | - spin_lock(&phba->pport->work_port_lock); | |
1613 | + spin_lock_irqsave( | |
1614 | + &phba->pport->work_port_lock, | |
1615 | + iflag); | |
1616 | phba->pport->work_port_events &= | |
1617 | ~WORKER_MBOX_TMO; | |
1618 | - spin_unlock(&phba->pport->work_port_lock); | |
1619 | + spin_unlock_irqrestore( | |
1620 | + &phba->pport->work_port_lock, | |
1621 | + iflag); | |
1622 | lpfc_mbox_cmpl_put(phba, pmb); | |
1623 | } | |
1624 | } else | |
1625 | - spin_unlock(&phba->hbalock); | |
1626 | + spin_unlock_irqrestore(&phba->hbalock, iflag); | |
1627 | ||
1628 | if ((work_ha_copy & HA_MBATT) && | |
1629 | (phba->sli.mbox_active == NULL)) { | |
1630 | @@ -5503,9 +5530,9 @@ send_current_mbox: | |
1631 | "MBX_SUCCESS"); | |
1632 | } | |
1633 | ||
1634 | - spin_lock(&phba->hbalock); | |
1635 | + spin_lock_irqsave(&phba->hbalock, iflag); | |
1636 | phba->work_ha |= work_ha_copy; | |
1637 | - spin_unlock(&phba->hbalock); | |
1638 | + spin_unlock_irqrestore(&phba->hbalock, iflag); | |
1639 | lpfc_worker_wake_up(phba); | |
1640 | } | |
1641 | return IRQ_HANDLED; | |
1642 | @@ -5537,6 +5564,7 @@ lpfc_fp_intr_handler(int irq, void *dev_id) | |
1643 | struct lpfc_hba *phba; | |
1644 | uint32_t ha_copy; | |
1645 | unsigned long status; | |
1646 | + unsigned long iflag; | |
1647 | ||
1648 | /* Get the driver's phba structure from the dev_id and | |
1649 | * assume the HBA is not interrupting. | |
1650 | @@ -5562,11 +5590,11 @@ lpfc_fp_intr_handler(int irq, void *dev_id) | |
1651 | /* Need to read HA REG for FCP ring and other ring events */ | |
1652 | ha_copy = readl(phba->HAregaddr); | |
1653 | /* Clear up only attention source related to fast-path */ | |
1654 | - spin_lock(&phba->hbalock); | |
1655 | + spin_lock_irqsave(&phba->hbalock, iflag); | |
1656 | writel((ha_copy & (HA_R0_CLR_MSK | HA_R1_CLR_MSK)), | |
1657 | phba->HAregaddr); | |
1658 | readl(phba->HAregaddr); /* flush */ | |
1659 | - spin_unlock(&phba->hbalock); | |
1660 | + spin_unlock_irqrestore(&phba->hbalock, iflag); | |
1661 | } else | |
1662 | ha_copy = phba->ha_copy; | |
1663 | ||
1664 | diff --git a/drivers/scsi/lpfc/lpfc_version.h b/drivers/scsi/lpfc/lpfc_version.h | |
1665 | index 57b559a..16626a5 100644 | |
1666 | --- a/drivers/scsi/lpfc/lpfc_version.h | |
1667 | +++ b/drivers/scsi/lpfc/lpfc_version.h | |
1668 | @@ -18,7 +18,7 @@ | |
1669 | * included with this package. * | |
1670 | *******************************************************************/ | |
1671 | ||
1672 | -#define LPFC_DRIVER_VERSION "8.2.8.4" | |
1673 | +#define LPFC_DRIVER_VERSION "8.2.8.7" | |
1674 | ||
1675 | #define LPFC_DRIVER_NAME "lpfc" | |
1676 | #define LPFC_SP_DRIVER_HANDLER_NAME "lpfc:sp" |