]> git.ipfire.org Git - people/teissler/ipfire-2.x.git/blob - src/patches/suse-2.6.27.25/patches.drivers/lpfc-8.2.8.4-update
Updated xen patches taken from suse.
[people/teissler/ipfire-2.x.git] / src / patches / suse-2.6.27.25 / patches.drivers / lpfc-8.2.8.4-update
1 Subject: Update lpfc to 8.2.8.4
2 From: Hannes Reinecke <hare@suse.de>
3 Date: Tue Oct 7 13:50:11 2008 +0200:
4 References: bnc#420767
5
6 This patch updates the SLES 11 lpfc driver to 8.2.8.4 which has
7 the following changes:
8
9 * Changed version number to 8.2.8.4
10 * Added code to get option ROM version from HBA
11 * Added support for FC_REG_VPORTRSCN_EVENT
12 * Fix the authentication error when the initial authentication is rejected
13 * Add the lpfc_symbolic_name back into the scsi_host attributes
14 * Fix vport failed to create when link was down or in loop (CR 83339)
15 * Fix authentication failures always show up an generic errors (CR 74969)
16 * Fixed statistical data collection for virtual ports
17 * Support changes to vport's symbolic name
18 * Fix Vport created in disabled state doesn't have correct state
19 * Fix vport disable attribute missing
20 * Fix vport attributes by removing physical attributes
21
22 Signed-off-by: Jamie Wellnitz <jamie.wellnitz@emulex.com>
23 Signed-off-by: Hannes Reinecke <hare@suse.de>
24
25 diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h
26 index 10e1ac6..7508dea 100644
27 --- a/drivers/scsi/lpfc/lpfc.h
28 +++ b/drivers/scsi/lpfc/lpfc.h
29 @@ -328,6 +328,11 @@ enum auth_state {
30 LPFC_AUTH_UNKNOWN = 0,
31 LPFC_AUTH_SUCCESS = 1,
32 LPFC_AUTH_FAIL = 2,
33 + LPFC_AUTH_FAIL_ELS_TMO = 3,
34 + LPFC_AUTH_FAIL_TRANS_TMO = 4,
35 + LPFC_AUTH_FAIL_LS_RJT_GEN = 5,
36 + LPFC_AUTH_FAIL_LS_RJT_BUSY = 6,
37 + LPFC_AUTH_FAIL_AUTH_RJT = 7,
38 };
39 enum auth_msg_state {
40 LPFC_AUTH_NONE = 0,
41 @@ -463,8 +468,6 @@ struct lpfc_vport {
42 uint8_t load_flag;
43 #define FC_LOADING 0x1 /* HBA in process of loading drvr */
44 #define FC_UNLOADING 0x2 /* HBA in process of unloading drvr */
45 - char *vname; /* Application assigned name */
46 -
47 /* Fields used for accessing auth service */
48 struct lpfc_auth auth;
49 uint32_t sc_tran_id;
50 diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
51 index 8e94902..1069491 100644
52 --- a/drivers/scsi/lpfc/lpfc_attr.c
53 +++ b/drivers/scsi/lpfc/lpfc_attr.c
54 @@ -1107,6 +1107,17 @@ lpfc_auth_state_show(struct device *dev, struct device_attribute *attr,
55 return snprintf(buf, PAGE_SIZE, "Not Authenticated\n");
56 case LPFC_AUTH_FAIL:
57 return snprintf(buf, PAGE_SIZE, "Failed\n");
58 + case LPFC_AUTH_FAIL_ELS_TMO:
59 + return snprintf(buf, PAGE_SIZE, "Failed - ELS Timeout\n");
60 + case LPFC_AUTH_FAIL_TRANS_TMO:
61 + return snprintf(buf, PAGE_SIZE, "Failed - "
62 + "Transaction Timeout\n");
63 + case LPFC_AUTH_FAIL_LS_RJT_GEN:
64 + return snprintf(buf, PAGE_SIZE, "Failed - LS_RJT\n");
65 + case LPFC_AUTH_FAIL_LS_RJT_BUSY:
66 + return snprintf(buf, PAGE_SIZE, "Failed - LS_RJT Busy\n");
67 + case LPFC_AUTH_FAIL_AUTH_RJT:
68 + return snprintf(buf, PAGE_SIZE, "Failed - AUTH RJT\n");
69 case LPFC_AUTH_SUCCESS:
70 if (vport->auth.auth_msg_state == LPFC_AUTH_NEGOTIATE ||
71 vport->auth.auth_msg_state == LPFC_DHCHAP_CHALLENGE ||
72 @@ -1665,6 +1676,20 @@ static DEVICE_ATTR(auth_hash, S_IRUGO, lpfc_auth_hash_show, NULL);
73 static DEVICE_ATTR(auth_last, S_IRUGO, lpfc_auth_last_show, NULL);
74 static DEVICE_ATTR(auth_next, S_IRUGO, lpfc_auth_next_show, NULL);
75
76 +static ssize_t
77 +lpfc_symbolic_name_show(struct device *dev, struct device_attribute *attr,
78 + char *buf)
79 +{
80 + struct Scsi_Host *shost = class_to_shost(dev);
81 + struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
82 + int length;
83 + char symbname[256];
84 +
85 + length = lpfc_vport_symbolic_port_name(vport, symbname, 256);
86 + return snprintf(buf, PAGE_SIZE, "%s\n", symbname);
87 +}
88 +static DEVICE_ATTR(lpfc_symbolic_name, S_IRUGO, lpfc_symbolic_name_show, NULL);
89 +
90 static int
91 lpfc_parse_wwn(const char *ns, uint8_t *nm)
92 {
93 @@ -3134,6 +3159,7 @@ struct device_attribute *lpfc_hba_attrs[] = {
94 &dev_attr_auth_hash,
95 &dev_attr_auth_last,
96 &dev_attr_auth_next,
97 + &dev_attr_lpfc_symbolic_name,
98 &dev_attr_lpfc_soft_wwnn,
99 &dev_attr_lpfc_soft_wwpn,
100 &dev_attr_lpfc_soft_wwn_enable,
101 @@ -3171,7 +3197,7 @@ struct device_attribute *lpfc_vport_attrs[] = {
102 &dev_attr_auth_hash,
103 &dev_attr_auth_last,
104 &dev_attr_auth_next,
105 -
106 + &dev_attr_lpfc_symbolic_name,
107 &dev_attr_lpfc_max_scsicmpl_time,
108 &dev_attr_lpfc_stat_data_ctrl,
109 NULL,
110 @@ -4134,25 +4160,28 @@ lpfc_alloc_sysfs_attr(struct lpfc_vport *vport)
111 int error;
112
113 error = sysfs_create_bin_file(&shost->shost_dev.kobj,
114 - &sysfs_ctlreg_attr);
115 - if (error)
116 + &sysfs_drvr_stat_data_attr);
117 +
118 + /* Virtual ports do not need ctrl_reg and mbox */
119 + if (error || vport->port_type == LPFC_NPIV_PORT)
120 goto out;
121
122 error = sysfs_create_bin_file(&shost->shost_dev.kobj,
123 - &sysfs_mbox_attr);
124 + &sysfs_ctlreg_attr);
125 if (error)
126 - goto out_remove_ctlreg_attr;
127 + goto out_remove_stat_attr;
128
129 error = sysfs_create_bin_file(&shost->shost_dev.kobj,
130 - &sysfs_drvr_stat_data_attr);
131 + &sysfs_mbox_attr);
132 if (error)
133 - goto out_remove_mbox_attr;
134 + goto out_remove_ctlreg_attr;
135
136 return 0;
137 -out_remove_mbox_attr:
138 - sysfs_remove_bin_file(&shost->shost_dev.kobj, &sysfs_mbox_attr);
139 out_remove_ctlreg_attr:
140 sysfs_remove_bin_file(&shost->shost_dev.kobj, &sysfs_ctlreg_attr);
141 +out_remove_stat_attr:
142 + sysfs_remove_bin_file(&shost->shost_dev.kobj,
143 + &sysfs_drvr_stat_data_attr);
144 out:
145 return error;
146 }
147 @@ -4167,6 +4196,9 @@ lpfc_free_sysfs_attr(struct lpfc_vport *vport)
148 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
149 sysfs_remove_bin_file(&shost->shost_dev.kobj,
150 &sysfs_drvr_stat_data_attr);
151 + /* Virtual ports do not need ctrl_reg and mbox */
152 + if (vport->port_type == LPFC_NPIV_PORT)
153 + return;
154 sysfs_remove_bin_file(&shost->shost_dev.kobj, &sysfs_mbox_attr);
155 sysfs_remove_bin_file(&shost->shost_dev.kobj, &sysfs_ctlreg_attr);
156 sysfs_remove_bin_file(&shost->shost_dev.kobj, &sysfs_menlo_attr);
157 @@ -4645,6 +4677,23 @@ lpfc_show_rport_##field (struct device *dev, \
158 lpfc_rport_show_function(field, format_string, sz, ) \
159 static FC_RPORT_ATTR(field, S_IRUGO, lpfc_show_rport_##field, NULL)
160
161 +/**
162 + * lpfc_set_vport_symbolic_name: Set the vport's symbolic name.
163 + * @fc_vport: The fc_vport who's symbolic name has been changed.
164 + *
165 + * Description:
166 + * This function is called by the transport after the @fc_vport's symbolic name
167 + * has been changed. This function re-registers the symbolic name with the
168 + * switch to propogate the change into the fabric if the vport is active.
169 + **/
170 +static void
171 +lpfc_set_vport_symbolic_name(struct fc_vport *fc_vport)
172 +{
173 + struct lpfc_vport *vport = *(struct lpfc_vport **)fc_vport->dd_data;
174 +
175 + if (vport->port_state == LPFC_VPORT_READY)
176 + lpfc_ns_cmd(vport, SLI_CTNS_RSPN_ID, 0, 0);
177 +}
178
179 struct fc_function_template lpfc_transport_functions = {
180 /* fixed attributes the driver supports */
181 @@ -4654,6 +4703,7 @@ struct fc_function_template lpfc_transport_functions = {
182 .show_host_supported_fc4s = 1,
183 .show_host_supported_speeds = 1,
184 .show_host_maxframe_size = 1,
185 + .show_host_symbolic_name = 1,
186
187 /* dynamic attributes the driver supports */
188 .get_host_port_id = lpfc_get_host_port_id,
189 @@ -4703,6 +4753,10 @@ struct fc_function_template lpfc_transport_functions = {
190 .terminate_rport_io = lpfc_terminate_rport_io,
191
192 .dd_fcvport_size = sizeof(struct lpfc_vport *),
193 +
194 + .vport_disable = lpfc_vport_disable,
195 +
196 + .set_vport_symbolic_name = lpfc_set_vport_symbolic_name,
197 };
198
199 struct fc_function_template lpfc_vport_transport_functions = {
200 @@ -4713,6 +4767,7 @@ struct fc_function_template lpfc_vport_transport_functions = {
201 .show_host_supported_fc4s = 1,
202 .show_host_supported_speeds = 1,
203 .show_host_maxframe_size = 1,
204 + .show_host_symbolic_name = 1,
205
206 /* dynamic attributes the driver supports */
207 .get_host_port_id = lpfc_get_host_port_id,
208 @@ -4761,6 +4816,8 @@ struct fc_function_template lpfc_vport_transport_functions = {
209 .terminate_rport_io = lpfc_terminate_rport_io,
210
211 .vport_disable = lpfc_vport_disable,
212 +
213 + .set_vport_symbolic_name = lpfc_set_vport_symbolic_name,
214 };
215
216 /**
217 @@ -4788,6 +4845,7 @@ lpfc_get_cfgparam(struct lpfc_hba *phba)
218 phba->cfg_soft_wwpn = 0L;
219 lpfc_sg_seg_cnt_init(phba, lpfc_sg_seg_cnt);
220 /* Also reinitialize the host templates with new values. */
221 + lpfc_vport_template.sg_tablesize = phba->cfg_sg_seg_cnt;
222 lpfc_template.sg_tablesize = phba->cfg_sg_seg_cnt;
223 /*
224 * Since the sg_tablesize is module parameter, the sg_dma_buf_size
225 diff --git a/drivers/scsi/lpfc/lpfc_auth.c b/drivers/scsi/lpfc/lpfc_auth.c
226 index 6a5da93..7dc3600 100644
227 --- a/drivers/scsi/lpfc/lpfc_auth.c
228 +++ b/drivers/scsi/lpfc/lpfc_auth.c
229 @@ -179,9 +179,8 @@ lpfc_dhchap_authenticate(struct Scsi_Host *shost,
230 ndlp->nlp_DID);
231 lpfc_issue_els_auth_reject(vport, ndlp,
232 AUTH_ERR, AUTHENTICATION_FAILED);
233 - if (vport->auth.auth_state == LPFC_AUTH_SUCCESS) {
234 - lpfc_port_auth_failed(ndlp);
235 - }
236 + if (vport->auth.auth_state == LPFC_AUTH_SUCCESS)
237 + lpfc_port_auth_failed(ndlp, LPFC_AUTH_FAIL_AUTH_RJT);
238 }
239
240 kfree(rsp);
241 diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h
242 index a93c555..380acef 100644
243 --- a/drivers/scsi/lpfc/lpfc_crtn.h
244 +++ b/drivers/scsi/lpfc/lpfc_crtn.h
245 @@ -28,6 +28,7 @@ int lpfc_issue_els_auth_reject(struct lpfc_vport *vport,
246 struct lpfc_nodelist *ndlp,
247 uint8_t reason, uint8_t explanation);
248 void lpfc_dump_mem(struct lpfc_hba *, LPFC_MBOXQ_t *, uint16_t);
249 +void lpfc_dump_wakeup_param(struct lpfc_hba *, LPFC_MBOXQ_t *);
250 void lpfc_read_nv(struct lpfc_hba *, LPFC_MBOXQ_t *);
251 void lpfc_config_async(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t);
252
253 @@ -89,7 +90,7 @@ struct lpfc_nodelist *__lpfc_findnode_rpi(struct lpfc_vport *, uint16_t);
254 struct lpfc_nodelist *lpfc_findnode_wwnn(struct lpfc_vport *,
255 struct lpfc_name *);
256
257 -void lpfc_port_auth_failed(struct lpfc_nodelist *);
258 +void lpfc_port_auth_failed(struct lpfc_nodelist *, enum auth_state);
259 void lpfc_worker_wake_up(struct lpfc_hba *);
260 int lpfc_workq_post_event(struct lpfc_hba *, void *, void *, uint32_t);
261 int lpfc_do_work(void *);
262 @@ -272,6 +273,7 @@ void lpfc_free_sysfs_attr(struct lpfc_vport *);
263 extern struct device_attribute *lpfc_hba_attrs[];
264 extern struct device_attribute *lpfc_vport_attrs[];
265 extern struct scsi_host_template lpfc_template;
266 +extern struct scsi_host_template lpfc_vport_template;
267 extern struct fc_function_template lpfc_transport_functions;
268 extern struct fc_function_template lpfc_vport_transport_functions;
269 extern int lpfc_sli_mode;
270 diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c
271 index 26dae8b..7fecdbb 100644
272 --- a/drivers/scsi/lpfc/lpfc_ct.c
273 +++ b/drivers/scsi/lpfc/lpfc_ct.c
274 @@ -1008,8 +1008,10 @@ lpfc_vport_symbolic_port_name(struct lpfc_vport *vport, char *symbol,
275 if (n < size)
276 n += snprintf(symbol + n, size - n, " VPort-%d", vport->vpi);
277
278 - if (n < size && vport->vname)
279 - n += snprintf(symbol + n, size - n, " VName-%s", vport->vname);
280 + if (n < size &&
281 + strlen(vport->fc_vport->symbolic_name))
282 + n += snprintf(symbol + n, size - n, " VName-%s",
283 + vport->fc_vport->symbolic_name);
284 return n;
285 }
286
287 diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
288 index a95815e..3f58a4b 100644
289 --- a/drivers/scsi/lpfc/lpfc_els.c
290 +++ b/drivers/scsi/lpfc/lpfc_els.c
291 @@ -5347,7 +5347,7 @@ lpfc_els_rcv_auth_rjt(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
292 "1036 Authentication transaction reject - "
293 "re-auth request reason 0x%x exp 0x%x\n",
294 rjt->reason, rjt->explanation);
295 - lpfc_port_auth_failed(ndlp);
296 + lpfc_port_auth_failed(ndlp, LPFC_AUTH_FAIL_AUTH_RJT);
297 if (vport->auth.auth_msg_state == LPFC_DHCHAP_SUCCESS) {
298 /* start authentication */
299 lpfc_start_authentication(vport, ndlp);
300 @@ -5366,6 +5366,7 @@ lpfc_els_rcv_auth_rjt(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
301 "1057 Authentication transaction "
302 "reject. reason 0x%x exp 0x%x\n",
303 rjt->reason, rjt->explanation);
304 + lpfc_port_auth_failed(ndlp, LPFC_AUTH_FAIL_AUTH_RJT);
305 vport->auth.auth_msg_state = LPFC_AUTH_REJECT;
306 if (!(phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) &&
307 (phba->link_state != LPFC_CLEAR_LA)) {
308 @@ -7040,6 +7041,8 @@ lpfc_cmpl_els_auth(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
309 IOCB_t *irsp = &rspiocb->iocb;
310 struct lpfc_vport *vport = cmdiocb->vport;
311 struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) cmdiocb->context1;
312 + enum auth_state auth_state;
313 + struct ls_rjt stat;
314
315 /* Check to see if link went down during discovery */
316 if (lpfc_els_chk_latt(vport)) {
317 @@ -7049,9 +7052,19 @@ lpfc_cmpl_els_auth(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
318 }
319
320 if (irsp->ulpStatus) {
321 + auth_state = LPFC_AUTH_FAIL;
322 if (irsp->ulpStatus == IOSTAT_LS_RJT) {
323 + stat.un.lsRjtError = be32_to_cpu(irsp->un.ulpWord[4]);
324 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
325 "1043 Authentication LS_RJT\n");
326 + if (stat.un.b.lsRjtRsnCode == LSRJT_LOGICAL_BSY)
327 + auth_state = LPFC_AUTH_FAIL_LS_RJT_BUSY;
328 + else
329 + auth_state = LPFC_AUTH_FAIL_LS_RJT_GEN;
330 + } else if (irsp->ulpStatus == IOSTAT_LOCAL_REJECT &&
331 + (irsp->un.ulpWord[4] & 0xff) ==
332 + IOERR_SEQUENCE_TIMEOUT) {
333 + auth_state = LPFC_AUTH_FAIL_ELS_TMO;
334 }
335 /* Check for retry */
336 if (!lpfc_els_retry(phba, cmdiocb, rspiocb)) {
337 @@ -7063,7 +7076,7 @@ lpfc_cmpl_els_auth(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
338 }
339 if (vport->auth.auth_mode == FC_AUTHMODE_ACTIVE) {
340 lpfc_can_disctmo(vport);
341 - lpfc_port_auth_failed(ndlp);
342 + lpfc_port_auth_failed(ndlp, auth_state);
343 }
344 }
345 if (!(phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) &&
346 diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c
347 index 502a9a5..358e9de 100644
348 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c
349 +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
350 @@ -754,17 +754,18 @@ lpfc_linkdown_port(struct lpfc_vport *vport)
351 vport->port_state, vport->fc_ns_retry, vport->fc_flag);
352
353 lpfc_port_link_failure(vport);
354 -
355 - vport->auth.auth_state = LPFC_AUTH_UNKNOWN;
356 - vport->auth.auth_msg_state = LPFC_AUTH_NONE;
357 + if (vport->auth.auth_state < LPFC_AUTH_FAIL) {
358 + vport->auth.auth_state = LPFC_AUTH_UNKNOWN;
359 + vport->auth.auth_msg_state = LPFC_AUTH_NONE;
360 + }
361 }
362
363 void
364 -lpfc_port_auth_failed(struct lpfc_nodelist *ndlp)
365 +lpfc_port_auth_failed(struct lpfc_nodelist *ndlp, enum auth_state fail_state)
366 {
367 struct lpfc_vport *vport = ndlp->vport;
368
369 - vport->auth.auth_state = LPFC_AUTH_FAIL;
370 + vport->auth.auth_state = fail_state;
371 vport->auth.auth_msg_state = LPFC_AUTH_NONE;
372 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
373 if (ndlp->nlp_type & NLP_FABRIC) {
374 @@ -886,6 +887,8 @@ lpfc_linkup_port(struct lpfc_vport *vport)
375 if (vport->fc_flag & FC_LBIT)
376 lpfc_linkup_cleanup_nodes(vport);
377
378 + vport->auth.auth_state = LPFC_AUTH_UNKNOWN;
379 + vport->auth.auth_msg_state = LPFC_AUTH_NONE;
380 }
381
382 static int
383 diff --git a/drivers/scsi/lpfc/lpfc_hw.h b/drivers/scsi/lpfc/lpfc_hw.h
384 index 90d0c5a..c77d49e 100644
385 --- a/drivers/scsi/lpfc/lpfc_hw.h
386 +++ b/drivers/scsi/lpfc/lpfc_hw.h
387 @@ -2404,6 +2404,30 @@ typedef struct {
388 #define DMP_RSP_OFFSET 0x14 /* word 5 contains first word of rsp */
389 #define DMP_RSP_SIZE 0x6C /* maximum of 27 words of rsp data */
390
391 +#define WAKE_UP_PARMS_REGION_ID 4
392 +#define WAKE_UP_PARMS_WORD_SIZE 15
393 +
394 +/* Option rom version structure */
395 +struct prog_id {
396 +#ifdef __BIG_ENDIAN_BITFIELD
397 + uint8_t type;
398 + uint8_t id;
399 + uint32_t ver:4; /* Major Version */
400 + uint32_t rev:4; /* Revision */
401 + uint32_t lev:2; /* Level */
402 + uint32_t dist:2; /* Dist Type */
403 + uint32_t num:4; /* number after dist type */
404 +#else /* __LITTLE_ENDIAN_BITFIELD */
405 + uint32_t num:4; /* number after dist type */
406 + uint32_t dist:2; /* Dist Type */
407 + uint32_t lev:2; /* Level */
408 + uint32_t rev:4; /* Revision */
409 + uint32_t ver:4; /* Major Version */
410 + uint8_t id;
411 + uint8_t type;
412 +#endif
413 +};
414 +
415 /* Structure for MB Command UPDATE_CFG (0x1B) */
416
417 struct update_cfg_var {
418 diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
419 index c0ea4fc..c151651 100644
420 --- a/drivers/scsi/lpfc/lpfc_init.c
421 +++ b/drivers/scsi/lpfc/lpfc_init.c
422 @@ -271,6 +271,48 @@ lpfc_config_async_cmpl(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq)
423 }
424
425 /**
426 + * lpfc_dump_wakeup_param_cmpl: Completion handler for dump memory mailbox
427 + * command used for getting wake up parameters.
428 + * @phba: pointer to lpfc hba data structure.
429 + * @pmboxq: pointer to the driver internal queue element for mailbox command.
430 + *
431 + * This is the completion handler for dump mailbox command for getting
432 + * wake up parameters. When this command complete, the response contain
433 + * Option rom version of the HBA. This function translate the version number
434 + * into a human readable string and store it in OptionROMVersion.
435 + **/
436 +static void
437 +lpfc_dump_wakeup_param_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq)
438 +{
439 + struct prog_id *prg;
440 + uint32_t prog_id_word;
441 + char dist = ' ';
442 + /* character array used for decoding dist type. */
443 + char dist_char[] = "nabx";
444 +
445 + if (pmboxq->mb.mbxStatus != MBX_SUCCESS)
446 + return;
447 +
448 + prg = (struct prog_id *) &prog_id_word;
449 +
450 + /* word 7 contain option rom version */
451 + prog_id_word = pmboxq->mb.un.varWords[7];
452 +
453 + /* Decode the Option rom version word to a readable string */
454 + if (prg->dist < 4)
455 + dist = dist_char[prg->dist];
456 +
457 + if ((prg->dist == 3) && (prg->num == 0))
458 + sprintf(phba->OptionROMVersion, "%d.%d%d",
459 + prg->ver, prg->rev, prg->lev);
460 + else
461 + sprintf(phba->OptionROMVersion, "%d.%d%d%c%d",
462 + prg->ver, prg->rev, prg->lev,
463 + dist, prg->num);
464 + return;
465 +}
466 +
467 +/**
468 * lpfc_config_port_post: Perform lpfc initialization after config port.
469 * @phba: pointer to lpfc hba data structure.
470 *
471 @@ -528,6 +570,20 @@ lpfc_config_port_post(struct lpfc_hba *phba)
472 rc);
473 mempool_free(pmb, phba->mbox_mem_pool);
474 }
475 +
476 + /* Get Option rom version */
477 + pmb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
478 + lpfc_dump_wakeup_param(phba, pmb);
479 + pmb->mbox_cmpl = lpfc_dump_wakeup_param_cmpl;
480 + pmb->vport = phba->pport;
481 + rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT);
482 +
483 + if ((rc != MBX_BUSY) && (rc != MBX_SUCCESS)) {
484 + lpfc_printf_log(phba, KERN_ERR, LOG_INIT, "0435 Adapter failed "
485 + "to get Option ROM version status x%x\n.", rc);
486 + mempool_free(pmb, phba->mbox_mem_pool);
487 + }
488 +
489 return 0;
490 }
491
492 @@ -2014,7 +2070,12 @@ lpfc_create_port(struct lpfc_hba *phba, int instance, struct device *dev)
493 struct Scsi_Host *shost;
494 int error = 0;
495
496 - shost = scsi_host_alloc(&lpfc_template, sizeof(struct lpfc_vport));
497 + if (dev != &phba->pcidev->dev)
498 + shost = scsi_host_alloc(&lpfc_vport_template,
499 + sizeof(struct lpfc_vport));
500 + else
501 + shost = scsi_host_alloc(&lpfc_template,
502 + sizeof(struct lpfc_vport));
503 if (!shost)
504 goto out;
505
506 @@ -2097,8 +2158,6 @@ destroy_port(struct lpfc_vport *vport)
507 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
508 struct lpfc_hba *phba = vport->phba;
509
510 - kfree(vport->vname);
511 -
512 lpfc_debugfs_terminate(vport);
513 fc_remove_host(shost);
514 scsi_remove_host(shost);
515 @@ -2862,7 +2921,6 @@ lpfc_pci_remove_one(struct pci_dev *pdev)
516 vport->load_flag |= FC_UNLOADING;
517 spin_unlock_irq(&phba->hbalock);
518
519 - kfree(vport->vname);
520 lpfc_free_sysfs_attr(vport);
521
522 kthread_stop(phba->worker_thread);
523 diff --git a/drivers/scsi/lpfc/lpfc_mbox.c b/drivers/scsi/lpfc/lpfc_mbox.c
524 index 184fe62..f0ab456 100644
525 --- a/drivers/scsi/lpfc/lpfc_mbox.c
526 +++ b/drivers/scsi/lpfc/lpfc_mbox.c
527 @@ -77,6 +77,38 @@ lpfc_dump_mem(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb, uint16_t offset)
528 }
529
530 /**
531 + * lpfc_dump_mem: Prepare a mailbox command for retrieving wakeup params.
532 + * @phba: pointer to lpfc hba data structure.
533 + * @pmb: pointer to the driver internal queue element for mailbox command.
534 + * This function create a dump memory mailbox command to dump wake up
535 + * parameters.
536 + */
537 +void
538 +lpfc_dump_wakeup_param(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
539 +{
540 + MAILBOX_t *mb;
541 + void *ctx;
542 +
543 + mb = &pmb->mb;
544 + /* Save context so that we can restore after memset */
545 + ctx = pmb->context2;
546 +
547 + /* Setup to dump VPD region */
548 + memset(pmb, 0, sizeof(LPFC_MBOXQ_t));
549 + mb->mbxCommand = MBX_DUMP_MEMORY;
550 + mb->mbxOwner = OWN_HOST;
551 + mb->un.varDmp.cv = 1;
552 + mb->un.varDmp.type = DMP_NV_PARAMS;
553 + mb->un.varDmp.entry_index = 0;
554 + mb->un.varDmp.region_id = WAKE_UP_PARMS_REGION_ID;
555 + mb->un.varDmp.word_cnt = WAKE_UP_PARMS_WORD_SIZE;
556 + mb->un.varDmp.co = 0;
557 + mb->un.varDmp.resp_offset = 0;
558 + pmb->context2 = ctx;
559 + return;
560 +}
561 +
562 +/**
563 * lpfc_read_nv: Prepare a mailbox command for reading HBA's NVRAM param.
564 * @phba: pointer to lpfc hba data structure.
565 * @pmb: pointer to the driver internal queue element for mailbox command.
566 diff --git a/drivers/scsi/lpfc/lpfc_nl.h b/drivers/scsi/lpfc/lpfc_nl.h
567 index 991ad53..27d1a88 100644
568 --- a/drivers/scsi/lpfc/lpfc_nl.h
569 +++ b/drivers/scsi/lpfc/lpfc_nl.h
570 @@ -22,18 +22,20 @@
571 #define FC_REG_LINK_EVENT 0x0001 /* link up / down events */
572 #define FC_REG_RSCN_EVENT 0x0002 /* RSCN events */
573 #define FC_REG_CT_EVENT 0x0004 /* CT request events */
574 -#define FC_REG_DUMP_EVENT 0x0008 /* Dump events */
575 -#define FC_REG_TEMPERATURE_EVENT 0x0010 /* temperature events */
576 -#define FC_REG_ELS_EVENT 0x0020 /* lpfc els events */
577 -#define FC_REG_FABRIC_EVENT 0x0040 /* lpfc fabric events */
578 -#define FC_REG_SCSI_EVENT 0x0080 /* lpfc scsi events */
579 -#define FC_REG_BOARD_EVENT 0x0100 /* lpfc board events */
580 -#define FC_REG_ADAPTER_EVENT 0x0200 /* lpfc adapter events */
581 +#define FC_REG_DUMP_EVENT 0x0010 /* Dump events */
582 +#define FC_REG_TEMPERATURE_EVENT 0x0020 /* temperature events */
583 +#define FC_REG_VPORTRSCN_EVENT 0x0040 /* Vport RSCN events */
584 +#define FC_REG_ELS_EVENT 0x0080 /* lpfc els events */
585 +#define FC_REG_FABRIC_EVENT 0x0100 /* lpfc fabric events */
586 +#define FC_REG_SCSI_EVENT 0x0200 /* lpfc scsi events */
587 +#define FC_REG_BOARD_EVENT 0x0400 /* lpfc board events */
588 +#define FC_REG_ADAPTER_EVENT 0x0800 /* lpfc adapter events */
589 #define FC_REG_EVENT_MASK (FC_REG_LINK_EVENT | \
590 FC_REG_RSCN_EVENT | \
591 FC_REG_CT_EVENT | \
592 FC_REG_DUMP_EVENT | \
593 FC_REG_TEMPERATURE_EVENT | \
594 + FC_REG_VPORTRSCN_EVENT | \
595 FC_REG_ELS_EVENT | \
596 FC_REG_FABRIC_EVENT | \
597 FC_REG_SCSI_EVENT | \
598 diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
599 index a7ea952..fed32ff 100644
600 --- a/drivers/scsi/lpfc/lpfc_scsi.c
601 +++ b/drivers/scsi/lpfc/lpfc_scsi.c
602 @@ -1842,7 +1842,7 @@ struct scsi_host_template lpfc_template = {
603 .info = lpfc_info,
604 .queuecommand = lpfc_queuecommand,
605 .eh_abort_handler = lpfc_abort_handler,
606 - .eh_device_reset_handler= lpfc_device_reset_handler,
607 + .eh_device_reset_handler = lpfc_device_reset_handler,
608 .eh_bus_reset_handler = lpfc_bus_reset_handler,
609 .slave_alloc = lpfc_slave_alloc,
610 .slave_configure = lpfc_slave_configure,
611 @@ -1856,3 +1856,22 @@ struct scsi_host_template lpfc_template = {
612 .max_sectors = 0xFFFF,
613 };
614
615 +struct scsi_host_template lpfc_vport_template = {
616 + .module = THIS_MODULE,
617 + .name = LPFC_DRIVER_NAME,
618 + .info = lpfc_info,
619 + .queuecommand = lpfc_queuecommand,
620 + .eh_abort_handler = lpfc_abort_handler,
621 + .eh_device_reset_handler = lpfc_device_reset_handler,
622 + .eh_bus_reset_handler = lpfc_bus_reset_handler,
623 + .slave_alloc = lpfc_slave_alloc,
624 + .slave_configure = lpfc_slave_configure,
625 + .slave_destroy = lpfc_slave_destroy,
626 + .scan_finished = lpfc_scan_finished,
627 + .this_id = -1,
628 + .sg_tablesize = LPFC_DEFAULT_SG_SEG_CNT,
629 + .cmd_per_lun = LPFC_CMD_PER_LUN,
630 + .use_clustering = ENABLE_CLUSTERING,
631 + .shost_attrs = lpfc_vport_attrs,
632 + .max_sectors = 0xFFFF,
633 +};
634 diff --git a/drivers/scsi/lpfc/lpfc_security.c b/drivers/scsi/lpfc/lpfc_security.c
635 index d136f67..c0fbe56 100644
636 --- a/drivers/scsi/lpfc/lpfc_security.c
637 +++ b/drivers/scsi/lpfc/lpfc_security.c
638 @@ -263,7 +263,7 @@ lpfc_reauthentication_handler(struct lpfc_nodelist *ndlp)
639 lpfc_printf_vlog(vport, KERN_ERR, LOG_SECURITY,
640 "1029 Reauthentication Failure\n");
641 if (vport->auth.auth_state == LPFC_AUTH_SUCCESS)
642 - lpfc_port_auth_failed(ndlp);
643 + lpfc_port_auth_failed(ndlp, LPFC_AUTH_FAIL);
644 }
645 }
646
647 diff --git a/drivers/scsi/lpfc/lpfc_version.h b/drivers/scsi/lpfc/lpfc_version.h
648 index a42cef2..57b559a 100644
649 --- a/drivers/scsi/lpfc/lpfc_version.h
650 +++ b/drivers/scsi/lpfc/lpfc_version.h
651 @@ -18,7 +18,7 @@
652 * included with this package. *
653 *******************************************************************/
654
655 -#define LPFC_DRIVER_VERSION "8.2.8.3"
656 +#define LPFC_DRIVER_VERSION "8.2.8.4"
657
658 #define LPFC_DRIVER_NAME "lpfc"
659 #define LPFC_SP_DRIVER_HANDLER_NAME "lpfc:sp"
660 diff --git a/drivers/scsi/lpfc/lpfc_vport.c b/drivers/scsi/lpfc/lpfc_vport.c
661 index c3a3f6e..ae8256d 100644
662 --- a/drivers/scsi/lpfc/lpfc_vport.c
663 +++ b/drivers/scsi/lpfc/lpfc_vport.c
664 @@ -289,10 +289,8 @@ lpfc_vport_create(struct fc_vport *fc_vport, bool disable)
665 int vpi;
666 int rc = VPORT_ERROR;
667 int status;
668 - int size;
669
670 - if ((phba->sli_rev < 3) ||
671 - !(phba->sli3_options & LPFC_SLI3_NPIV_ENABLED)) {
672 + if ((phba->sli_rev < 3) || !(phba->cfg_enable_npiv)) {
673 lpfc_printf_log(phba, KERN_ERR, LOG_VPORT,
674 "1808 Create VPORT failed: "
675 "NPIV is not enabled: SLImode:%d\n",
676 @@ -352,20 +350,6 @@ lpfc_vport_create(struct fc_vport *fc_vport, bool disable)
677
678 memcpy(vport->fc_portname.u.wwn, vport->fc_sparam.portName.u.wwn, 8);
679 memcpy(vport->fc_nodename.u.wwn, vport->fc_sparam.nodeName.u.wwn, 8);
680 - size = strnlen(fc_vport->symbolic_name, LPFC_VNAME_LEN);
681 - if (size) {
682 - vport->vname = kzalloc(size+1, GFP_KERNEL);
683 - if (!vport->vname) {
684 - lpfc_printf_vlog(vport, KERN_ERR, LOG_VPORT,
685 - "1814 Create VPORT failed. "
686 - "vname allocation failed.\n");
687 - rc = VPORT_ERROR;
688 - lpfc_free_vpi(phba, vpi);
689 - destroy_port(vport);
690 - goto error_out;
691 - }
692 - memcpy(vport->vname, fc_vport->symbolic_name, size+1);
693 - }
694 if (fc_vport->node_name != 0)
695 u64_to_wwn(fc_vport->node_name, vport->fc_nodename.u.wwn);
696 if (fc_vport->port_name != 0)
697 @@ -410,6 +394,9 @@ lpfc_vport_create(struct fc_vport *fc_vport, bool disable)
698 }
699 }
700
701 + /* Create binary sysfs attribute for vport */
702 + lpfc_alloc_sysfs_attr(vport);
703 +
704 *(struct lpfc_vport **)fc_vport->dd_data = vport;
705 vport->fc_vport = fc_vport;
706
707 @@ -421,6 +408,7 @@ lpfc_vport_create(struct fc_vport *fc_vport, bool disable)
708 }
709
710 if (disable) {
711 + lpfc_vport_set_state(vport, FC_VPORT_DISABLED);
712 rc = VPORT_OK;
713 goto out;
714 }
715 @@ -603,7 +591,9 @@ lpfc_vport_delete(struct fc_vport *fc_vport)
716 spin_lock_irq(&phba->hbalock);
717 vport->load_flag |= FC_UNLOADING;
718 spin_unlock_irq(&phba->hbalock);
719 - kfree(vport->vname);
720 +
721 + lpfc_free_sysfs_attr(vport);
722 +
723 lpfc_debugfs_terminate(vport);
724
725 /* Remove FC host and then SCSI host with the vport */