1 | /******************************************************************* |
2 | * This file is part of the Emulex Linux Device Driver for * |
3 | * Fibre Channel Host Bus Adapters. * |
4 | * Copyright (C) 2017-2024 Broadcom. All Rights Reserved. The term * |
5 | * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. * |
6 | * Copyright (C) 2004-2016 Emulex. All rights reserved. * |
7 | * EMULEX and SLI are trademarks of Emulex. * |
8 | * www.broadcom.com * |
9 | * Portions Copyright (C) 2004-2005 Christoph Hellwig * |
10 | * * |
11 | * This program is free software; you can redistribute it and/or * |
12 | * modify it under the terms of version 2 of the GNU General * |
13 | * Public License as published by the Free Software Foundation. * |
14 | * This program is distributed in the hope that it will be useful. * |
15 | * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND * |
16 | * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, * |
17 | * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT, ARE * |
18 | * DISCLAIMED, EXCEPT TO THE EXTENT THAT SUCH DISCLAIMERS ARE HELD * |
19 | * TO BE LEGALLY INVALID. See the GNU General Public License for * |
20 | * more details, a copy of which can be found in the file COPYING * |
21 | * included with this package. * |
22 | *******************************************************************/ |
23 | |
24 | #include <linux/blkdev.h> |
25 | #include <linux/delay.h> |
26 | #include <linux/dma-mapping.h> |
27 | #include <linux/idr.h> |
28 | #include <linux/interrupt.h> |
29 | #include <linux/kthread.h> |
30 | #include <linux/pci.h> |
31 | #include <linux/slab.h> |
32 | #include <linux/spinlock.h> |
33 | #include <linux/sched/signal.h> |
34 | |
35 | #include <scsi/scsi.h> |
36 | #include <scsi/scsi_device.h> |
37 | #include <scsi/scsi_host.h> |
38 | #include <scsi/scsi_transport_fc.h> |
39 | |
40 | #include "lpfc_hw4.h" |
41 | #include "lpfc_hw.h" |
42 | #include "lpfc_sli.h" |
43 | #include "lpfc_sli4.h" |
44 | #include "lpfc_nl.h" |
45 | #include "lpfc_disc.h" |
46 | #include "lpfc_scsi.h" |
47 | #include "lpfc.h" |
48 | #include "lpfc_logmsg.h" |
49 | #include "lpfc_crtn.h" |
50 | #include "lpfc_version.h" |
51 | #include "lpfc_vport.h" |
52 | |
53 | inline void lpfc_vport_set_state(struct lpfc_vport *vport, |
54 | enum fc_vport_state new_state) |
55 | { |
56 | struct fc_vport *fc_vport = vport->fc_vport; |
57 | |
58 | if (fc_vport) { |
59 | /* |
60 | * When the transport defines fc_vport_set state we will replace |
61 | * this code with the following line |
62 | */ |
63 | /* fc_vport_set_state(fc_vport, new_state); */ |
64 | if (new_state != FC_VPORT_INITIALIZING) |
65 | fc_vport->vport_last_state = fc_vport->vport_state; |
66 | fc_vport->vport_state = new_state; |
67 | } |
68 | |
69 | /* for all the error states we will set the invternal state to FAILED */ |
70 | switch (new_state) { |
71 | case FC_VPORT_NO_FABRIC_SUPP: |
72 | case FC_VPORT_NO_FABRIC_RSCS: |
73 | case FC_VPORT_FABRIC_LOGOUT: |
74 | case FC_VPORT_FABRIC_REJ_WWN: |
75 | case FC_VPORT_FAILED: |
76 | vport->port_state = LPFC_VPORT_FAILED; |
77 | break; |
78 | case FC_VPORT_LINKDOWN: |
79 | vport->port_state = LPFC_VPORT_UNKNOWN; |
80 | break; |
81 | default: |
82 | /* do nothing */ |
83 | break; |
84 | } |
85 | } |
86 | |
87 | int |
88 | lpfc_alloc_vpi(struct lpfc_hba *phba) |
89 | { |
90 | unsigned long vpi; |
91 | |
92 | spin_lock_irq(lock: &phba->hbalock); |
93 | /* Start at bit 1 because vpi zero is reserved for the physical port */ |
94 | vpi = find_next_zero_bit(addr: phba->vpi_bmask, size: (phba->max_vpi + 1), offset: 1); |
95 | if (vpi > phba->max_vpi) |
96 | vpi = 0; |
97 | else |
98 | set_bit(nr: vpi, addr: phba->vpi_bmask); |
99 | if (phba->sli_rev == LPFC_SLI_REV4) |
100 | phba->sli4_hba.max_cfg_param.vpi_used++; |
101 | spin_unlock_irq(lock: &phba->hbalock); |
102 | return vpi; |
103 | } |
104 | |
105 | static void |
106 | lpfc_free_vpi(struct lpfc_hba *phba, int vpi) |
107 | { |
108 | if (vpi == 0) |
109 | return; |
110 | spin_lock_irq(lock: &phba->hbalock); |
111 | clear_bit(nr: vpi, addr: phba->vpi_bmask); |
112 | if (phba->sli_rev == LPFC_SLI_REV4) |
113 | phba->sli4_hba.max_cfg_param.vpi_used--; |
114 | spin_unlock_irq(lock: &phba->hbalock); |
115 | } |
116 | |
117 | static int |
118 | lpfc_vport_sparm(struct lpfc_hba *phba, struct lpfc_vport *vport) |
119 | { |
120 | LPFC_MBOXQ_t *pmb; |
121 | MAILBOX_t *mb; |
122 | struct lpfc_dmabuf *mp; |
123 | int rc; |
124 | |
125 | pmb = mempool_alloc(pool: phba->mbox_mem_pool, GFP_KERNEL); |
126 | if (!pmb) { |
127 | return -ENOMEM; |
128 | } |
129 | mb = &pmb->u.mb; |
130 | |
131 | rc = lpfc_read_sparam(phba, pmb, vport->vpi); |
132 | if (rc) { |
133 | mempool_free(element: pmb, pool: phba->mbox_mem_pool); |
134 | return -ENOMEM; |
135 | } |
136 | |
137 | /* |
138 | * Wait for the read_sparams mailbox to complete. Driver needs |
139 | * this per vport to start the FDISC. If the mailbox fails, |
140 | * just cleanup and return an error unless the failure is a |
141 | * mailbox timeout. For MBX_TIMEOUT, allow the default |
142 | * mbox completion handler to take care of the cleanup. This |
143 | * is safe as the mailbox command isn't one that triggers |
144 | * another mailbox. |
145 | */ |
146 | pmb->vport = vport; |
147 | rc = lpfc_sli_issue_mbox_wait(phba, pmb, phba->fc_ratov * 2); |
148 | if (rc != MBX_SUCCESS) { |
149 | if (signal_pending(current)) { |
150 | lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT, |
151 | "1830 Signal aborted mbxCmd x%x\n" , |
152 | mb->mbxCommand); |
153 | if (rc != MBX_TIMEOUT) |
154 | lpfc_mbox_rsrc_cleanup(phba, mbox: pmb, |
155 | locked: MBOX_THD_UNLOCKED); |
156 | return -EINTR; |
157 | } else { |
158 | lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT, |
159 | "1818 VPort failed init, mbxCmd x%x " |
160 | "READ_SPARM mbxStatus x%x, rc = x%x\n" , |
161 | mb->mbxCommand, mb->mbxStatus, rc); |
162 | if (rc != MBX_TIMEOUT) |
163 | lpfc_mbox_rsrc_cleanup(phba, mbox: pmb, |
164 | locked: MBOX_THD_UNLOCKED); |
165 | return -EIO; |
166 | } |
167 | } |
168 | |
169 | mp = pmb->ctx_buf; |
170 | memcpy(&vport->fc_sparam, mp->virt, sizeof (struct serv_parm)); |
171 | memcpy(&vport->fc_nodename, &vport->fc_sparam.nodeName, |
172 | sizeof (struct lpfc_name)); |
173 | memcpy(&vport->fc_portname, &vport->fc_sparam.portName, |
174 | sizeof (struct lpfc_name)); |
175 | lpfc_mbox_rsrc_cleanup(phba, mbox: pmb, locked: MBOX_THD_UNLOCKED); |
176 | return 0; |
177 | } |
178 | |
179 | static int |
180 | lpfc_valid_wwn_format(struct lpfc_hba *phba, struct lpfc_name *wwn, |
181 | const char *name_type) |
182 | { |
183 | /* ensure that IEEE format 1 addresses |
184 | * contain zeros in bits 59-48 |
185 | */ |
186 | if (!((wwn->u.wwn[0] >> 4) == 1 && |
187 | ((wwn->u.wwn[0] & 0xf) != 0 || (wwn->u.wwn[1] & 0xf) != 0))) |
188 | return 1; |
189 | |
190 | lpfc_printf_log(phba, KERN_ERR, LOG_VPORT, |
191 | "1822 Invalid %s: %02x:%02x:%02x:%02x:" |
192 | "%02x:%02x:%02x:%02x\n" , |
193 | name_type, |
194 | wwn->u.wwn[0], wwn->u.wwn[1], |
195 | wwn->u.wwn[2], wwn->u.wwn[3], |
196 | wwn->u.wwn[4], wwn->u.wwn[5], |
197 | wwn->u.wwn[6], wwn->u.wwn[7]); |
198 | return 0; |
199 | } |
200 | |
201 | static int |
202 | lpfc_unique_wwpn(struct lpfc_hba *phba, struct lpfc_vport *new_vport) |
203 | { |
204 | struct lpfc_vport *vport; |
205 | unsigned long flags; |
206 | |
207 | spin_lock_irqsave(&phba->port_list_lock, flags); |
208 | list_for_each_entry(vport, &phba->port_list, listentry) { |
209 | if (vport == new_vport) |
210 | continue; |
211 | /* If they match, return not unique */ |
212 | if (memcmp(p: &vport->fc_sparam.portName, |
213 | q: &new_vport->fc_sparam.portName, |
214 | size: sizeof(struct lpfc_name)) == 0) { |
215 | spin_unlock_irqrestore(lock: &phba->port_list_lock, flags); |
216 | return 0; |
217 | } |
218 | } |
219 | spin_unlock_irqrestore(lock: &phba->port_list_lock, flags); |
220 | return 1; |
221 | } |
222 | |
223 | /** |
224 | * lpfc_discovery_wait - Wait for driver discovery to quiesce |
225 | * @vport: The virtual port for which this call is being executed. |
226 | * |
227 | * This driver calls this routine specifically from lpfc_vport_delete |
228 | * to enforce a synchronous execution of vport |
229 | * delete relative to discovery activities. The |
230 | * lpfc_vport_delete routine should not return until it |
231 | * can reasonably guarantee that discovery has quiesced. |
232 | * Post FDISC LOGO, the driver must wait until its SAN teardown is |
233 | * complete and all resources recovered before allowing |
234 | * cleanup. |
235 | * |
236 | * This routine does not require any locks held. |
237 | **/ |
238 | static void lpfc_discovery_wait(struct lpfc_vport *vport) |
239 | { |
240 | struct lpfc_hba *phba = vport->phba; |
241 | unsigned long wait_time_max; |
242 | unsigned long start_time; |
243 | |
244 | /* |
245 | * The time constraint on this loop is a balance between the |
246 | * fabric RA_TOV value and dev_loss tmo. The driver's |
247 | * devloss_tmo is 10 giving this loop a 3x multiplier minimally. |
248 | */ |
249 | wait_time_max = msecs_to_jiffies(m: ((phba->fc_ratov * 3) + 3) * 1000); |
250 | wait_time_max += jiffies; |
251 | start_time = jiffies; |
252 | while (time_before(jiffies, wait_time_max)) { |
253 | if ((vport->num_disc_nodes > 0) || |
254 | test_bit(FC_RSCN_MODE, &vport->fc_flag) || |
255 | test_bit(FC_RSCN_DISCOVERY, &vport->fc_flag) || |
256 | test_bit(FC_NLP_MORE, &vport->fc_flag) || |
257 | test_bit(FC_RSCN_DEFERRED, &vport->fc_flag) || |
258 | test_bit(FC_NDISC_ACTIVE, &vport->fc_flag) || |
259 | test_bit(FC_DISC_TMO, &vport->fc_flag) || |
260 | ((vport->port_state > LPFC_VPORT_FAILED) && |
261 | (vport->port_state < LPFC_VPORT_READY))) { |
262 | lpfc_printf_vlog(vport, KERN_INFO, LOG_VPORT, |
263 | "1833 Vport discovery quiesce Wait: " |
264 | "state x%x fc_flags x%lx " |
265 | "num_nodes x%x, waiting 1000 msecs " |
266 | "total wait msecs x%x\n" , |
267 | vport->port_state, vport->fc_flag, |
268 | vport->num_disc_nodes, |
269 | jiffies_to_msecs(jiffies - start_time)); |
270 | msleep(msecs: 1000); |
271 | } else { |
272 | /* Base case. Wait variants satisfied. Break out */ |
273 | lpfc_printf_vlog(vport, KERN_INFO, LOG_VPORT, |
274 | "1834 Vport discovery quiesced: " |
275 | "state x%x fc_flags x%lx " |
276 | "wait msecs x%x\n" , |
277 | vport->port_state, vport->fc_flag, |
278 | jiffies_to_msecs(jiffies |
279 | - start_time)); |
280 | break; |
281 | } |
282 | } |
283 | |
284 | if (time_after(jiffies, wait_time_max)) |
285 | lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT, |
286 | "1835 Vport discovery quiesce failed:" |
287 | " state x%x fc_flags x%lx wait msecs x%x\n" , |
288 | vport->port_state, vport->fc_flag, |
289 | jiffies_to_msecs(jiffies - start_time)); |
290 | } |
291 | |
292 | int |
293 | lpfc_vport_create(struct fc_vport *fc_vport, bool disable) |
294 | { |
295 | struct lpfc_nodelist *ndlp; |
296 | struct Scsi_Host *shost = fc_vport->shost; |
297 | struct lpfc_vport *pport = (struct lpfc_vport *) shost->hostdata; |
298 | struct lpfc_hba *phba = pport->phba; |
299 | struct lpfc_vport *vport = NULL; |
300 | int instance; |
301 | int vpi; |
302 | int rc = VPORT_ERROR; |
303 | int status; |
304 | |
305 | if ((phba->sli_rev < 3) || !(phba->cfg_enable_npiv)) { |
306 | lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT, |
307 | "1808 Create VPORT failed: " |
308 | "NPIV is not enabled: SLImode:%d\n" , |
309 | phba->sli_rev); |
310 | rc = VPORT_INVAL; |
311 | goto error_out; |
312 | } |
313 | |
314 | /* NPIV is not supported if HBA has NVME Target enabled */ |
315 | if (phba->nvmet_support) { |
316 | lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT, |
317 | "3189 Create VPORT failed: " |
318 | "NPIV is not supported on NVME Target\n" ); |
319 | rc = VPORT_INVAL; |
320 | goto error_out; |
321 | } |
322 | |
323 | vpi = lpfc_alloc_vpi(phba); |
324 | if (vpi == 0) { |
325 | lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT, |
326 | "1809 Create VPORT failed: " |
327 | "Max VPORTs (%d) exceeded\n" , |
328 | phba->max_vpi); |
329 | rc = VPORT_NORESOURCES; |
330 | goto error_out; |
331 | } |
332 | |
333 | /* Assign an unused board number */ |
334 | if ((instance = lpfc_get_instance()) < 0) { |
335 | lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT, |
336 | "1810 Create VPORT failed: Cannot get " |
337 | "instance number\n" ); |
338 | lpfc_free_vpi(phba, vpi); |
339 | rc = VPORT_NORESOURCES; |
340 | goto error_out; |
341 | } |
342 | |
343 | vport = lpfc_create_port(phba, instance, &fc_vport->dev); |
344 | if (!vport) { |
345 | lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT, |
346 | "1811 Create VPORT failed: vpi x%x\n" , vpi); |
347 | lpfc_free_vpi(phba, vpi); |
348 | rc = VPORT_NORESOURCES; |
349 | goto error_out; |
350 | } |
351 | |
352 | vport->vpi = vpi; |
353 | lpfc_debugfs_initialize(vport); |
354 | |
355 | if ((status = lpfc_vport_sparm(phba, vport))) { |
356 | if (status == -EINTR) { |
357 | lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT, |
358 | "1831 Create VPORT Interrupted.\n" ); |
359 | rc = VPORT_ERROR; |
360 | } else { |
361 | lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT, |
362 | "1813 Create VPORT failed. " |
363 | "Cannot get sparam\n" ); |
364 | rc = VPORT_NORESOURCES; |
365 | } |
366 | lpfc_free_vpi(phba, vpi); |
367 | destroy_port(vport); |
368 | goto error_out; |
369 | } |
370 | |
371 | u64_to_wwn(inm: fc_vport->node_name, wwn: vport->fc_nodename.u.wwn); |
372 | u64_to_wwn(inm: fc_vport->port_name, wwn: vport->fc_portname.u.wwn); |
373 | |
374 | memcpy(&vport->fc_sparam.portName, vport->fc_portname.u.wwn, 8); |
375 | memcpy(&vport->fc_sparam.nodeName, vport->fc_nodename.u.wwn, 8); |
376 | |
377 | if (!lpfc_valid_wwn_format(phba, wwn: &vport->fc_sparam.nodeName, name_type: "WWNN" ) || |
378 | !lpfc_valid_wwn_format(phba, wwn: &vport->fc_sparam.portName, name_type: "WWPN" )) { |
379 | lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT, |
380 | "1821 Create VPORT failed. " |
381 | "Invalid WWN format\n" ); |
382 | lpfc_free_vpi(phba, vpi); |
383 | destroy_port(vport); |
384 | rc = VPORT_INVAL; |
385 | goto error_out; |
386 | } |
387 | |
388 | if (!lpfc_unique_wwpn(phba, new_vport: vport)) { |
389 | lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT, |
390 | "1823 Create VPORT failed. " |
391 | "Duplicate WWN on HBA\n" ); |
392 | lpfc_free_vpi(phba, vpi); |
393 | destroy_port(vport); |
394 | rc = VPORT_INVAL; |
395 | goto error_out; |
396 | } |
397 | |
398 | /* Create binary sysfs attribute for vport */ |
399 | lpfc_alloc_sysfs_attr(vport); |
400 | |
401 | /* Set the DFT_LUN_Q_DEPTH accordingly */ |
402 | vport->cfg_lun_queue_depth = phba->pport->cfg_lun_queue_depth; |
403 | |
404 | /* Only the physical port can support NVME for now */ |
405 | vport->cfg_enable_fc4_type = LPFC_ENABLE_FCP; |
406 | |
407 | *(struct lpfc_vport **)fc_vport->dd_data = vport; |
408 | vport->fc_vport = fc_vport; |
409 | |
410 | /* At this point we are fully registered with SCSI Layer. */ |
411 | set_bit(nr: FC_ALLOW_FDMI, addr: &vport->load_flag); |
412 | if (phba->cfg_enable_SmartSAN || |
413 | (phba->cfg_fdmi_on == LPFC_FDMI_SUPPORT)) { |
414 | /* Setup appropriate attribute masks */ |
415 | vport->fdmi_hba_mask = phba->pport->fdmi_hba_mask; |
416 | vport->fdmi_port_mask = phba->pport->fdmi_port_mask; |
417 | } |
418 | |
419 | /* |
420 | * In SLI4, the vpi must be activated before it can be used |
421 | * by the port. |
422 | */ |
423 | if ((phba->sli_rev == LPFC_SLI_REV4) && |
424 | test_bit(FC_VFI_REGISTERED, &pport->fc_flag)) { |
425 | rc = lpfc_sli4_init_vpi(vport); |
426 | if (rc) { |
427 | lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT, |
428 | "1838 Failed to INIT_VPI on vpi %d " |
429 | "status %d\n" , vpi, rc); |
430 | rc = VPORT_NORESOURCES; |
431 | lpfc_free_vpi(phba, vpi); |
432 | goto error_out; |
433 | } |
434 | } else if (phba->sli_rev == LPFC_SLI_REV4) { |
435 | /* |
436 | * Driver cannot INIT_VPI now. Set the flags to |
437 | * init_vpi when reg_vfi complete. |
438 | */ |
439 | set_bit(nr: FC_VPORT_NEEDS_INIT_VPI, addr: &vport->fc_flag); |
440 | lpfc_vport_set_state(vport, new_state: FC_VPORT_LINKDOWN); |
441 | rc = VPORT_OK; |
442 | goto out; |
443 | } |
444 | |
445 | if ((phba->link_state < LPFC_LINK_UP) || |
446 | (pport->port_state < LPFC_FABRIC_CFG_LINK) || |
447 | (phba->fc_topology == LPFC_TOPOLOGY_LOOP)) { |
448 | lpfc_vport_set_state(vport, new_state: FC_VPORT_LINKDOWN); |
449 | rc = VPORT_OK; |
450 | goto out; |
451 | } |
452 | |
453 | if (disable) { |
454 | lpfc_vport_set_state(vport, new_state: FC_VPORT_DISABLED); |
455 | rc = VPORT_OK; |
456 | goto out; |
457 | } |
458 | |
459 | /* Use the Physical nodes Fabric NDLP to determine if the link is |
460 | * up and ready to FDISC. |
461 | */ |
462 | ndlp = lpfc_findnode_did(phba->pport, Fabric_DID); |
463 | if (ndlp && |
464 | ndlp->nlp_state == NLP_STE_UNMAPPED_NODE) { |
465 | if (phba->link_flag & LS_NPIV_FAB_SUPPORTED) { |
466 | lpfc_set_disctmo(vport); |
467 | lpfc_initial_fdisc(vport); |
468 | } else { |
469 | lpfc_vport_set_state(vport, new_state: FC_VPORT_NO_FABRIC_SUPP); |
470 | lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT, |
471 | "0262 No NPIV Fabric support\n" ); |
472 | } |
473 | } else { |
474 | lpfc_vport_set_state(vport, new_state: FC_VPORT_FAILED); |
475 | } |
476 | rc = VPORT_OK; |
477 | |
478 | out: |
479 | lpfc_printf_vlog(vport, KERN_ERR, LOG_VPORT, |
480 | "1825 Vport Created.\n" ); |
481 | lpfc_host_attrib_init(lpfc_shost_from_vport(vport)); |
482 | error_out: |
483 | return rc; |
484 | } |
485 | |
486 | static int |
487 | lpfc_send_npiv_logo(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) |
488 | { |
489 | int rc; |
490 | struct lpfc_hba *phba = vport->phba; |
491 | |
492 | DECLARE_WAIT_QUEUE_HEAD_ONSTACK(waitq); |
493 | |
494 | spin_lock_irq(lock: &ndlp->lock); |
495 | if (!(ndlp->save_flags & NLP_WAIT_FOR_LOGO) && |
496 | !ndlp->logo_waitq) { |
497 | ndlp->logo_waitq = &waitq; |
498 | ndlp->nlp_fcp_info &= ~NLP_FCP_2_DEVICE; |
499 | ndlp->nlp_flag |= NLP_ISSUE_LOGO; |
500 | ndlp->save_flags |= NLP_WAIT_FOR_LOGO; |
501 | } |
502 | spin_unlock_irq(lock: &ndlp->lock); |
503 | rc = lpfc_issue_els_npiv_logo(vport, ndlp); |
504 | if (!rc) { |
505 | wait_event_timeout(waitq, |
506 | (!(ndlp->save_flags & NLP_WAIT_FOR_LOGO)), |
507 | msecs_to_jiffies(phba->fc_ratov * 2000)); |
508 | |
509 | if (!(ndlp->save_flags & NLP_WAIT_FOR_LOGO)) |
510 | goto logo_cmpl; |
511 | /* LOGO wait failed. Correct status. */ |
512 | rc = -EINTR; |
513 | } else { |
514 | rc = -EIO; |
515 | } |
516 | |
517 | /* Error - clean up node flags. */ |
518 | spin_lock_irq(lock: &ndlp->lock); |
519 | ndlp->nlp_flag &= ~NLP_ISSUE_LOGO; |
520 | ndlp->save_flags &= ~NLP_WAIT_FOR_LOGO; |
521 | spin_unlock_irq(lock: &ndlp->lock); |
522 | |
523 | logo_cmpl: |
524 | lpfc_printf_vlog(vport, KERN_INFO, LOG_VPORT, |
525 | "1824 Issue LOGO completes with status %d\n" , |
526 | rc); |
527 | spin_lock_irq(lock: &ndlp->lock); |
528 | ndlp->logo_waitq = NULL; |
529 | spin_unlock_irq(lock: &ndlp->lock); |
530 | return rc; |
531 | } |
532 | |
533 | static int |
534 | disable_vport(struct fc_vport *fc_vport) |
535 | { |
536 | struct lpfc_vport *vport = *(struct lpfc_vport **)fc_vport->dd_data; |
537 | struct lpfc_hba *phba = vport->phba; |
538 | struct lpfc_nodelist *ndlp = NULL; |
539 | |
540 | /* Can't disable during an outstanding delete. */ |
541 | if (test_bit(FC_UNLOADING, &vport->load_flag)) |
542 | return 0; |
543 | |
544 | ndlp = lpfc_findnode_did(vport, Fabric_DID); |
545 | if (ndlp && phba->link_state >= LPFC_LINK_UP) |
546 | (void)lpfc_send_npiv_logo(vport, ndlp); |
547 | |
548 | lpfc_sli_host_down(vport); |
549 | lpfc_cleanup_rpis(vport, 0); |
550 | |
551 | lpfc_stop_vport_timers(vport); |
552 | lpfc_unreg_all_rpis(vport); |
553 | lpfc_unreg_default_rpis(vport); |
554 | /* |
555 | * Completion of unreg_vpi (lpfc_mbx_cmpl_unreg_vpi) does the |
556 | * scsi_host_put() to release the vport. |
557 | */ |
558 | lpfc_mbx_unreg_vpi(vport); |
559 | if (phba->sli_rev == LPFC_SLI_REV4) |
560 | set_bit(nr: FC_VPORT_NEEDS_INIT_VPI, addr: &vport->fc_flag); |
561 | |
562 | lpfc_vport_set_state(vport, new_state: FC_VPORT_DISABLED); |
563 | lpfc_printf_vlog(vport, KERN_ERR, LOG_VPORT, |
564 | "1826 Vport Disabled.\n" ); |
565 | return VPORT_OK; |
566 | } |
567 | |
568 | static int |
569 | enable_vport(struct fc_vport *fc_vport) |
570 | { |
571 | struct lpfc_vport *vport = *(struct lpfc_vport **)fc_vport->dd_data; |
572 | struct lpfc_hba *phba = vport->phba; |
573 | struct lpfc_nodelist *ndlp = NULL; |
574 | |
575 | if ((phba->link_state < LPFC_LINK_UP) || |
576 | (phba->fc_topology == LPFC_TOPOLOGY_LOOP)) { |
577 | lpfc_vport_set_state(vport, new_state: FC_VPORT_LINKDOWN); |
578 | return VPORT_OK; |
579 | } |
580 | |
581 | set_bit(nr: FC_LOADING, addr: &vport->load_flag); |
582 | if (test_bit(FC_VPORT_NEEDS_INIT_VPI, &vport->fc_flag)) { |
583 | lpfc_issue_init_vpi(vport); |
584 | goto out; |
585 | } |
586 | |
587 | set_bit(nr: FC_VPORT_NEEDS_REG_VPI, addr: &vport->fc_flag); |
588 | |
589 | /* Use the Physical nodes Fabric NDLP to determine if the link is |
590 | * up and ready to FDISC. |
591 | */ |
592 | ndlp = lpfc_findnode_did(phba->pport, Fabric_DID); |
593 | if (ndlp && ndlp->nlp_state == NLP_STE_UNMAPPED_NODE) { |
594 | if (phba->link_flag & LS_NPIV_FAB_SUPPORTED) { |
595 | lpfc_set_disctmo(vport); |
596 | lpfc_initial_fdisc(vport); |
597 | } else { |
598 | lpfc_vport_set_state(vport, new_state: FC_VPORT_NO_FABRIC_SUPP); |
599 | lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT, |
600 | "0264 No NPIV Fabric support\n" ); |
601 | } |
602 | } else { |
603 | lpfc_vport_set_state(vport, new_state: FC_VPORT_FAILED); |
604 | } |
605 | |
606 | out: |
607 | lpfc_printf_vlog(vport, KERN_ERR, LOG_VPORT, |
608 | "1827 Vport Enabled.\n" ); |
609 | return VPORT_OK; |
610 | } |
611 | |
612 | int |
613 | lpfc_vport_disable(struct fc_vport *fc_vport, bool disable) |
614 | { |
615 | if (disable) |
616 | return disable_vport(fc_vport); |
617 | else |
618 | return enable_vport(fc_vport); |
619 | } |
620 | |
621 | int |
622 | lpfc_vport_delete(struct fc_vport *fc_vport) |
623 | { |
624 | struct lpfc_nodelist *ndlp = NULL; |
625 | struct lpfc_vport *vport = *(struct lpfc_vport **)fc_vport->dd_data; |
626 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); |
627 | struct lpfc_hba *phba = vport->phba; |
628 | int rc; |
629 | |
630 | if (vport->port_type == LPFC_PHYSICAL_PORT) { |
631 | lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT, |
632 | "1812 vport_delete failed: Cannot delete " |
633 | "physical host\n" ); |
634 | return VPORT_ERROR; |
635 | } |
636 | |
637 | /* If the vport is a static vport fail the deletion. */ |
638 | if ((vport->vport_flag & STATIC_VPORT) && |
639 | !test_bit(FC_UNLOADING, &phba->pport->load_flag)) { |
640 | lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT, |
641 | "1837 vport_delete failed: Cannot delete " |
642 | "static vport.\n" ); |
643 | return VPORT_ERROR; |
644 | } |
645 | |
646 | set_bit(nr: FC_UNLOADING, addr: &vport->load_flag); |
647 | |
648 | /* |
649 | * If we are not unloading the driver then prevent the vport_delete |
650 | * from happening until after this vport's discovery is finished. |
651 | */ |
652 | if (!test_bit(FC_UNLOADING, &phba->pport->load_flag)) { |
653 | int check_count = 0; |
654 | while (check_count < ((phba->fc_ratov * 3) + 3) && |
655 | vport->port_state > LPFC_VPORT_FAILED && |
656 | vport->port_state < LPFC_VPORT_READY) { |
657 | check_count++; |
658 | msleep(msecs: 1000); |
659 | } |
660 | if (vport->port_state > LPFC_VPORT_FAILED && |
661 | vport->port_state < LPFC_VPORT_READY) |
662 | return -EAGAIN; |
663 | } |
664 | |
665 | /* |
666 | * Take early refcount for outstanding I/O requests we schedule during |
667 | * delete processing for unreg_vpi. Always keep this before |
668 | * scsi_remove_host() as we can no longer obtain a reference through |
669 | * scsi_host_get() after scsi_host_remove as shost is set to SHOST_DEL. |
670 | */ |
671 | if (!scsi_host_get(shost)) |
672 | return VPORT_INVAL; |
673 | |
674 | lpfc_free_sysfs_attr(vport); |
675 | lpfc_debugfs_terminate(vport); |
676 | |
677 | /* Send the DA_ID and Fabric LOGO to cleanup Nameserver entries. */ |
678 | ndlp = lpfc_findnode_did(vport, Fabric_DID); |
679 | if (!ndlp) |
680 | goto skip_logo; |
681 | |
682 | if (ndlp && ndlp->nlp_state == NLP_STE_UNMAPPED_NODE && |
683 | phba->link_state >= LPFC_LINK_UP && |
684 | phba->fc_topology != LPFC_TOPOLOGY_LOOP) { |
685 | if (vport->cfg_enable_da_id) { |
686 | /* Send DA_ID and wait for a completion. */ |
687 | rc = lpfc_ns_cmd(vport, SLI_CTNS_DA_ID, 0, 0); |
688 | if (rc) { |
689 | lpfc_printf_log(vport->phba, KERN_WARNING, |
690 | LOG_VPORT, |
691 | "1829 CT command failed to " |
692 | "delete objects on fabric, " |
693 | "rc %d\n" , rc); |
694 | } |
695 | } |
696 | |
697 | /* |
698 | * If the vpi is not registered, then a valid FDISC doesn't |
699 | * exist and there is no need for a ELS LOGO. Just cleanup |
700 | * the ndlp. |
701 | */ |
702 | if (!(vport->vpi_state & LPFC_VPI_REGISTERED)) |
703 | goto skip_logo; |
704 | |
705 | /* Issue a Fabric LOGO to cleanup fabric resources. */ |
706 | ndlp = lpfc_findnode_did(vport, Fabric_DID); |
707 | if (!ndlp) |
708 | goto skip_logo; |
709 | |
710 | rc = lpfc_send_npiv_logo(vport, ndlp); |
711 | if (rc) |
712 | goto skip_logo; |
713 | } |
714 | |
715 | if (!test_bit(FC_UNLOADING, &phba->pport->load_flag)) |
716 | lpfc_discovery_wait(vport); |
717 | |
718 | skip_logo: |
719 | |
720 | /* Remove FC host to break driver binding. */ |
721 | fc_remove_host(shost); |
722 | scsi_remove_host(shost); |
723 | |
724 | lpfc_cleanup(vport); |
725 | |
726 | /* Remove scsi host now. The nodes are cleaned up. */ |
727 | lpfc_sli_host_down(vport); |
728 | lpfc_stop_vport_timers(vport); |
729 | |
730 | if (!test_bit(FC_UNLOADING, &phba->pport->load_flag)) { |
731 | lpfc_unreg_all_rpis(vport); |
732 | lpfc_unreg_default_rpis(vport); |
733 | /* |
734 | * Completion of unreg_vpi (lpfc_mbx_cmpl_unreg_vpi) |
735 | * does the scsi_host_put() to release the vport. |
736 | */ |
737 | if (!(vport->vpi_state & LPFC_VPI_REGISTERED) || |
738 | lpfc_mbx_unreg_vpi(vport)) |
739 | scsi_host_put(t: shost); |
740 | } else { |
741 | scsi_host_put(t: shost); |
742 | } |
743 | |
744 | lpfc_free_vpi(phba, vpi: vport->vpi); |
745 | vport->work_port_events = 0; |
746 | spin_lock_irq(lock: &phba->port_list_lock); |
747 | list_del_init(entry: &vport->listentry); |
748 | spin_unlock_irq(lock: &phba->port_list_lock); |
749 | lpfc_printf_vlog(vport, KERN_ERR, LOG_VPORT, |
750 | "1828 Vport Deleted.\n" ); |
751 | scsi_host_put(t: shost); |
752 | return VPORT_OK; |
753 | } |
754 | |
755 | struct lpfc_vport ** |
756 | lpfc_create_vport_work_array(struct lpfc_hba *phba) |
757 | { |
758 | struct lpfc_vport *port_iterator; |
759 | struct lpfc_vport **vports; |
760 | int index = 0; |
761 | vports = kcalloc(n: phba->max_vports + 1, size: sizeof(struct lpfc_vport *), |
762 | GFP_KERNEL); |
763 | if (vports == NULL) |
764 | return NULL; |
765 | spin_lock_irq(lock: &phba->port_list_lock); |
766 | list_for_each_entry(port_iterator, &phba->port_list, listentry) { |
767 | if (test_bit(FC_UNLOADING, &port_iterator->load_flag)) |
768 | continue; |
769 | if (!scsi_host_get(lpfc_shost_from_vport(vport: port_iterator))) { |
770 | lpfc_printf_vlog(port_iterator, KERN_ERR, |
771 | LOG_TRACE_EVENT, |
772 | "1801 Create vport work array FAILED: " |
773 | "cannot do scsi_host_get\n" ); |
774 | continue; |
775 | } |
776 | vports[index++] = port_iterator; |
777 | } |
778 | spin_unlock_irq(lock: &phba->port_list_lock); |
779 | return vports; |
780 | } |
781 | |
782 | void |
783 | lpfc_destroy_vport_work_array(struct lpfc_hba *phba, struct lpfc_vport **vports) |
784 | { |
785 | int i; |
786 | if (vports == NULL) |
787 | return; |
788 | for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) |
789 | scsi_host_put(t: lpfc_shost_from_vport(vport: vports[i])); |
790 | kfree(objp: vports); |
791 | } |
792 | |
793 | |