lpfc_vport.c 23.8 KB
Newer Older
1 2 3
/*******************************************************************
 * This file is part of the Emulex Linux Device Driver for         *
 * Fibre Channel Host Bus Adapters.                                *
4
 * Copyright (C) 2017-2021 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.                        *
J
James Smart 已提交
8
 * www.broadcom.com                                                *
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
 * Portions Copyright (C) 2004-2005 Christoph Hellwig              *
 *                                                                 *
 * This program is free software; you can redistribute it and/or   *
 * modify it under the terms of version 2 of the GNU General       *
 * Public License as published by the Free Software Foundation.    *
 * This program is distributed in the hope that it will be useful. *
 * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND          *
 * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,  *
 * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT, ARE      *
 * DISCLAIMED, EXCEPT TO THE EXTENT THAT SUCH DISCLAIMERS ARE HELD *
 * TO BE LEGALLY INVALID.  See the GNU General Public License for  *
 * more details, a copy of which can be found in the file COPYING  *
 * included with this package.                                     *
 *******************************************************************/

#include <linux/blkdev.h>
#include <linux/delay.h>
#include <linux/dma-mapping.h>
#include <linux/idr.h>
#include <linux/interrupt.h>
#include <linux/kthread.h>
#include <linux/pci.h>
31
#include <linux/slab.h>
32
#include <linux/spinlock.h>
33
#include <linux/sched/signal.h>
34 35 36 37 38

#include <scsi/scsi.h>
#include <scsi/scsi_device.h>
#include <scsi/scsi_host.h>
#include <scsi/scsi_transport_fc.h>
J
James Smart 已提交
39

40
#include "lpfc_hw4.h"
41 42
#include "lpfc_hw.h"
#include "lpfc_sli.h"
43
#include "lpfc_sli4.h"
44
#include "lpfc_nl.h"
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
#include "lpfc_disc.h"
#include "lpfc_scsi.h"
#include "lpfc.h"
#include "lpfc_logmsg.h"
#include "lpfc_crtn.h"
#include "lpfc_version.h"
#include "lpfc_vport.h"

inline void lpfc_vport_set_state(struct lpfc_vport *vport,
				 enum fc_vport_state new_state)
{
	struct fc_vport *fc_vport = vport->fc_vport;

	if (fc_vport) {
		/*
		 * When the transport defines fc_vport_set state we will replace
		 * this code with the following line
		 */
		/* fc_vport_set_state(fc_vport, new_state); */
		if (new_state != FC_VPORT_INITIALIZING)
			fc_vport->vport_last_state = fc_vport->vport_state;
		fc_vport->vport_state = new_state;
	}

	/* for all the error states we will set the invternal state to FAILED */
	switch (new_state) {
	case FC_VPORT_NO_FABRIC_SUPP:
	case FC_VPORT_NO_FABRIC_RSCS:
	case FC_VPORT_FABRIC_LOGOUT:
	case FC_VPORT_FABRIC_REJ_WWN:
	case FC_VPORT_FAILED:
		vport->port_state = LPFC_VPORT_FAILED;
		break;
	case FC_VPORT_LINKDOWN:
		vport->port_state = LPFC_VPORT_UNKNOWN;
		break;
	default:
		/* do nothing */
		break;
	}
}

87
int
88 89
lpfc_alloc_vpi(struct lpfc_hba *phba)
{
90
	unsigned long vpi;
91 92

	spin_lock_irq(&phba->hbalock);
J
James Smart 已提交
93 94
	/* Start at bit 1 because vpi zero is reserved for the physical port */
	vpi = find_next_zero_bit(phba->vpi_bmask, (phba->max_vpi + 1), 1);
95 96 97 98
	if (vpi > phba->max_vpi)
		vpi = 0;
	else
		set_bit(vpi, phba->vpi_bmask);
99 100
	if (phba->sli_rev == LPFC_SLI_REV4)
		phba->sli4_hba.max_cfg_param.vpi_used++;
101 102 103 104 105 106 107
	spin_unlock_irq(&phba->hbalock);
	return vpi;
}

static void
lpfc_free_vpi(struct lpfc_hba *phba, int vpi)
{
108 109
	if (vpi == 0)
		return;
110 111
	spin_lock_irq(&phba->hbalock);
	clear_bit(vpi, phba->vpi_bmask);
112 113
	if (phba->sli_rev == LPFC_SLI_REV4)
		phba->sli4_hba.max_cfg_param.vpi_used--;
114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
	spin_unlock_irq(&phba->hbalock);
}

static int
lpfc_vport_sparm(struct lpfc_hba *phba, struct lpfc_vport *vport)
{
	LPFC_MBOXQ_t *pmb;
	MAILBOX_t *mb;
	struct lpfc_dmabuf *mp;
	int  rc;

	pmb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
	if (!pmb) {
		return -ENOMEM;
	}
129
	mb = &pmb->u.mb;
130

131 132 133 134 135 136
	rc = lpfc_read_sparam(phba, pmb, vport->vpi);
	if (rc) {
		mempool_free(pmb, phba->mbox_mem_pool);
		return -ENOMEM;
	}

137 138 139 140
	/*
	 * Grab buffer pointer and clear context1 so we can use
	 * lpfc_sli_issue_box_wait
	 */
141 142
	mp = (struct lpfc_dmabuf *)pmb->ctx_buf;
	pmb->ctx_buf = NULL;
143 144 145 146

	pmb->vport = vport;
	rc = lpfc_sli_issue_mbox_wait(phba, pmb, phba->fc_ratov * 2);
	if (rc != MBX_SUCCESS) {
147
		if (signal_pending(current)) {
148
			lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
149 150 151 152 153 154 155 156
					 "1830 Signal aborted mbxCmd x%x\n",
					 mb->mbxCommand);
			lpfc_mbuf_free(phba, mp->virt, mp->phys);
			kfree(mp);
			if (rc != MBX_TIMEOUT)
				mempool_free(pmb, phba->mbox_mem_pool);
			return -EINTR;
		} else {
157
			lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
158 159 160 161 162 163 164 165 166
					 "1818 VPort failed init, mbxCmd x%x "
					 "READ_SPARM mbxStatus x%x, rc = x%x\n",
					 mb->mbxCommand, mb->mbxStatus, rc);
			lpfc_mbuf_free(phba, mp->virt, mp->phys);
			kfree(mp);
			if (rc != MBX_TIMEOUT)
				mempool_free(pmb, phba->mbox_mem_pool);
			return -EIO;
		}
167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192
	}

	memcpy(&vport->fc_sparam, mp->virt, sizeof (struct serv_parm));
	memcpy(&vport->fc_nodename, &vport->fc_sparam.nodeName,
	       sizeof (struct lpfc_name));
	memcpy(&vport->fc_portname, &vport->fc_sparam.portName,
	       sizeof (struct lpfc_name));

	lpfc_mbuf_free(phba, mp->virt, mp->phys);
	kfree(mp);
	mempool_free(pmb, phba->mbox_mem_pool);

	return 0;
}

static int
lpfc_valid_wwn_format(struct lpfc_hba *phba, struct lpfc_name *wwn,
		      const char *name_type)
{
				/* ensure that IEEE format 1 addresses
				 * contain zeros in bits 59-48
				 */
	if (!((wwn->u.wwn[0] >> 4) == 1 &&
	      ((wwn->u.wwn[0] & 0xf) != 0 || (wwn->u.wwn[1] & 0xf) != 0)))
		return 1;

193
	lpfc_printf_log(phba, KERN_ERR, LOG_VPORT,
194
			"1822 Invalid %s: %02x:%02x:%02x:%02x:"
195
			"%02x:%02x:%02x:%02x\n",
196
			name_type,
197 198 199 200 201 202 203 204 205 206 207
			wwn->u.wwn[0], wwn->u.wwn[1],
			wwn->u.wwn[2], wwn->u.wwn[3],
			wwn->u.wwn[4], wwn->u.wwn[5],
			wwn->u.wwn[6], wwn->u.wwn[7]);
	return 0;
}

static int
lpfc_unique_wwpn(struct lpfc_hba *phba, struct lpfc_vport *new_vport)
{
	struct lpfc_vport *vport;
208
	unsigned long flags;
209

210
	spin_lock_irqsave(&phba->port_list_lock, flags);
211 212 213 214 215
	list_for_each_entry(vport, &phba->port_list, listentry) {
		if (vport == new_vport)
			continue;
		/* If they match, return not unique */
		if (memcmp(&vport->fc_sparam.portName,
216 217
			   &new_vport->fc_sparam.portName,
			   sizeof(struct lpfc_name)) == 0) {
218
			spin_unlock_irqrestore(&phba->port_list_lock, flags);
219
			return 0;
220
		}
221
	}
222
	spin_unlock_irqrestore(&phba->port_list_lock, flags);
223 224 225
	return 1;
}

226
/**
227
 * lpfc_discovery_wait - Wait for driver discovery to quiesce
228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263
 * @vport: The virtual port for which this call is being executed.
 *
 * This driver calls this routine specifically from lpfc_vport_delete
 * to enforce a synchronous execution of vport
 * delete relative to discovery activities.  The
 * lpfc_vport_delete routine should not return until it
 * can reasonably guarantee that discovery has quiesced.
 * Post FDISC LOGO, the driver must wait until its SAN teardown is
 * complete and all resources recovered before allowing
 * cleanup.
 *
 * This routine does not require any locks held.
 **/
static void lpfc_discovery_wait(struct lpfc_vport *vport)
{
	struct lpfc_hba *phba = vport->phba;
	uint32_t wait_flags = 0;
	unsigned long wait_time_max;
	unsigned long start_time;

	wait_flags = FC_RSCN_MODE | FC_RSCN_DISCOVERY | FC_NLP_MORE |
		     FC_RSCN_DEFERRED | FC_NDISC_ACTIVE | FC_DISC_TMO;

	/*
	 * The time constraint on this loop is a balance between the
	 * fabric RA_TOV value and dev_loss tmo.  The driver's
	 * devloss_tmo is 10 giving this loop a 3x multiplier minimally.
	 */
	wait_time_max = msecs_to_jiffies(((phba->fc_ratov * 3) + 3) * 1000);
	wait_time_max += jiffies;
	start_time = jiffies;
	while (time_before(jiffies, wait_time_max)) {
		if ((vport->num_disc_nodes > 0)    ||
		    (vport->fc_flag & wait_flags)  ||
		    ((vport->port_state > LPFC_VPORT_FAILED) &&
		     (vport->port_state < LPFC_VPORT_READY))) {
264
			lpfc_printf_vlog(vport, KERN_INFO, LOG_VPORT,
265
					"1833 Vport discovery quiesce Wait:"
266
					" state x%x fc_flags x%x"
267 268
					" num_nodes x%x, waiting 1000 msecs"
					" total wait msecs x%x\n",
269 270
					vport->port_state, vport->fc_flag,
					vport->num_disc_nodes,
271 272 273 274
					jiffies_to_msecs(jiffies - start_time));
			msleep(1000);
		} else {
			/* Base case.  Wait variants satisfied.  Break out */
275
			lpfc_printf_vlog(vport, KERN_INFO, LOG_VPORT,
276
					 "1834 Vport discovery quiesced:"
277
					 " state x%x fc_flags x%x"
278
					 " wait msecs x%x\n",
279
					 vport->port_state, vport->fc_flag,
280 281 282 283 284 285 286
					 jiffies_to_msecs(jiffies
						- start_time));
			break;
		}
	}

	if (time_after(jiffies, wait_time_max))
287 288 289 290 291
		lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
				 "1835 Vport discovery quiesce failed:"
				 " state x%x fc_flags x%x wait msecs x%x\n",
				 vport->port_state, vport->fc_flag,
				 jiffies_to_msecs(jiffies - start_time));
292 293
}

294 295 296 297
int
lpfc_vport_create(struct fc_vport *fc_vport, bool disable)
{
	struct lpfc_nodelist *ndlp;
298 299
	struct Scsi_Host *shost = fc_vport->shost;
	struct lpfc_vport *pport = (struct lpfc_vport *) shost->hostdata;
300 301 302 303 304
	struct lpfc_hba   *phba = pport->phba;
	struct lpfc_vport *vport = NULL;
	int instance;
	int vpi;
	int rc = VPORT_ERROR;
305
	int status;
306

307
	if ((phba->sli_rev < 3) || !(phba->cfg_enable_npiv)) {
308
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
309
				"1808 Create VPORT failed: "
310
				"NPIV is not enabled: SLImode:%d\n",
311
				phba->sli_rev);
312 313 314 315
		rc = VPORT_INVAL;
		goto error_out;
	}

316 317
	/* NPIV is not supported if HBA has NVME Target enabled */
	if (phba->nvmet_support) {
318
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
319
				"3189 Create VPORT failed: "
320
				"NPIV is not supported on NVME Target\n");
321 322 323 324
		rc = VPORT_INVAL;
		goto error_out;
	}

325 326
	vpi = lpfc_alloc_vpi(phba);
	if (vpi == 0) {
327
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
328
				"1809 Create VPORT failed: "
329
				"Max VPORTs (%d) exceeded\n",
330
				phba->max_vpi);
331 332 333 334 335 336
		rc = VPORT_NORESOURCES;
		goto error_out;
	}

	/* Assign an unused board number */
	if ((instance = lpfc_get_instance()) < 0) {
337
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
338 339
				"1810 Create VPORT failed: Cannot get "
				"instance number\n");
340 341 342 343 344
		lpfc_free_vpi(phba, vpi);
		rc = VPORT_NORESOURCES;
		goto error_out;
	}

345
	vport = lpfc_create_port(phba, instance, &fc_vport->dev);
346
	if (!vport) {
347
		lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
348
				"1811 Create VPORT failed: vpi x%x\n", vpi);
349 350 351 352 353 354
		lpfc_free_vpi(phba, vpi);
		rc = VPORT_NORESOURCES;
		goto error_out;
	}

	vport->vpi = vpi;
J
James Smart 已提交
355 356
	lpfc_debugfs_initialize(vport);

357 358
	if ((status = lpfc_vport_sparm(phba, vport))) {
		if (status == -EINTR) {
359
			lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
360 361 362
					 "1831 Create VPORT Interrupted.\n");
			rc = VPORT_ERROR;
		} else {
363
			lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
364 365 366 367
					 "1813 Create VPORT failed. "
					 "Cannot get sparam\n");
			rc = VPORT_NORESOURCES;
		}
368 369 370 371 372
		lpfc_free_vpi(phba, vpi);
		destroy_port(vport);
		goto error_out;
	}

373 374
	u64_to_wwn(fc_vport->node_name, vport->fc_nodename.u.wwn);
	u64_to_wwn(fc_vport->port_name, vport->fc_portname.u.wwn);
375 376 377 378 379 380

	memcpy(&vport->fc_sparam.portName, vport->fc_portname.u.wwn, 8);
	memcpy(&vport->fc_sparam.nodeName, vport->fc_nodename.u.wwn, 8);

	if (!lpfc_valid_wwn_format(phba, &vport->fc_sparam.nodeName, "WWNN") ||
	    !lpfc_valid_wwn_format(phba, &vport->fc_sparam.portName, "WWPN")) {
381
		lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
382 383
				 "1821 Create VPORT failed. "
				 "Invalid WWN format\n");
384 385 386 387 388 389 390
		lpfc_free_vpi(phba, vpi);
		destroy_port(vport);
		rc = VPORT_INVAL;
		goto error_out;
	}

	if (!lpfc_unique_wwpn(phba, vport)) {
391
		lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
392 393
				 "1823 Create VPORT failed. "
				 "Duplicate WWN on HBA\n");
394 395 396 397 398 399
		lpfc_free_vpi(phba, vpi);
		destroy_port(vport);
		rc = VPORT_INVAL;
		goto error_out;
	}

400 401 402
	/* Create binary sysfs attribute for vport */
	lpfc_alloc_sysfs_attr(vport);

403 404 405
	/* Set the DFT_LUN_Q_DEPTH accordingly */
	vport->cfg_lun_queue_depth  = phba->pport->cfg_lun_queue_depth;

406 407 408
	/* Only the physical port can support NVME for now */
	vport->cfg_enable_fc4_type = LPFC_ENABLE_FCP;

409 410 411
	*(struct lpfc_vport **)fc_vport->dd_data = vport;
	vport->fc_vport = fc_vport;

412 413
	/* At this point we are fully registered with SCSI Layer.  */
	vport->load_flag |= FC_ALLOW_FDMI;
414 415
	if (phba->cfg_enable_SmartSAN ||
	    (phba->cfg_fdmi_on == LPFC_FDMI_SUPPORT)) {
416 417 418 419 420
		/* Setup appropriate attribute masks */
		vport->fdmi_hba_mask = phba->pport->fdmi_hba_mask;
		vport->fdmi_port_mask = phba->pport->fdmi_port_mask;
	}

421 422 423 424 425
	/*
	 * In SLI4, the vpi must be activated before it can be used
	 * by the port.
	 */
	if ((phba->sli_rev == LPFC_SLI_REV4) &&
426 427
	    (pport->fc_flag & FC_VFI_REGISTERED)) {
		rc = lpfc_sli4_init_vpi(vport);
428
		if (rc) {
429
			lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446
					"1838 Failed to INIT_VPI on vpi %d "
					"status %d\n", vpi, rc);
			rc = VPORT_NORESOURCES;
			lpfc_free_vpi(phba, vpi);
			goto error_out;
		}
	} else if (phba->sli_rev == LPFC_SLI_REV4) {
		/*
		 * Driver cannot INIT_VPI now. Set the flags to
		 * init_vpi when reg_vfi complete.
		 */
		vport->fc_flag |= FC_VPORT_NEEDS_INIT_VPI;
		lpfc_vport_set_state(vport, FC_VPORT_LINKDOWN);
		rc = VPORT_OK;
		goto out;
	}

447
	if ((phba->link_state < LPFC_LINK_UP) ||
448
	    (pport->port_state < LPFC_FABRIC_CFG_LINK) ||
449
	    (phba->fc_topology == LPFC_TOPOLOGY_LOOP)) {
450 451 452 453 454 455
		lpfc_vport_set_state(vport, FC_VPORT_LINKDOWN);
		rc = VPORT_OK;
		goto out;
	}

	if (disable) {
456
		lpfc_vport_set_state(vport, FC_VPORT_DISABLED);
457 458 459 460 461 462 463 464
		rc = VPORT_OK;
		goto out;
	}

	/* Use the Physical nodes Fabric NDLP to determine if the link is
	 * up and ready to FDISC.
	 */
	ndlp = lpfc_findnode_did(phba->pport, Fabric_DID);
465
	if (ndlp &&
466
	    ndlp->nlp_state == NLP_STE_UNMAPPED_NODE) {
J
James Smart 已提交
467 468 469 470 471
		if (phba->link_flag & LS_NPIV_FAB_SUPPORTED) {
			lpfc_set_disctmo(vport);
			lpfc_initial_fdisc(vport);
		} else {
			lpfc_vport_set_state(vport, FC_VPORT_NO_FABRIC_SUPP);
472
			lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
473
					 "0262 No NPIV Fabric support\n");
J
James Smart 已提交
474
		}
475 476 477 478 479 480
	} else {
		lpfc_vport_set_state(vport, FC_VPORT_FAILED);
	}
	rc = VPORT_OK;

out:
481
	lpfc_printf_vlog(vport, KERN_ERR, LOG_VPORT,
482
			 "1825 Vport Created.\n");
483 484 485 486 487
	lpfc_host_attrib_init(lpfc_shost_from_vport(vport));
error_out:
	return rc;
}

J
James Smart 已提交
488
static int
489 490 491 492 493 494
disable_vport(struct fc_vport *fc_vport)
{
	struct lpfc_vport *vport = *(struct lpfc_vport **)fc_vport->dd_data;
	struct lpfc_hba   *phba = vport->phba;
	struct lpfc_nodelist *ndlp = NULL, *next_ndlp = NULL;
	long timeout;
495
	struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
496 497

	ndlp = lpfc_findnode_did(vport, Fabric_DID);
498
	if (ndlp && phba->link_state >= LPFC_LINK_UP) {
499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526
		vport->unreg_vpi_cmpl = VPORT_INVAL;
		timeout = msecs_to_jiffies(phba->fc_ratov * 2000);
		if (!lpfc_issue_els_npiv_logo(vport, ndlp))
			while (vport->unreg_vpi_cmpl == VPORT_INVAL && timeout)
				timeout = schedule_timeout(timeout);
	}

	lpfc_sli_host_down(vport);

	/* Mark all nodes for discovery so we can remove them by
	 * calling lpfc_cleanup_rpis(vport, 1)
	 */
	list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) {
		if (ndlp->nlp_state == NLP_STE_UNUSED_NODE)
			continue;
		lpfc_disc_state_machine(vport, ndlp, NULL,
					NLP_EVT_DEVICE_RECOVERY);
	}
	lpfc_cleanup_rpis(vport, 1);

	lpfc_stop_vport_timers(vport);
	lpfc_unreg_all_rpis(vport);
	lpfc_unreg_default_rpis(vport);
	/*
	 * Completion of unreg_vpi (lpfc_mbx_cmpl_unreg_vpi) does the
	 * scsi_host_put() to release the vport.
	 */
	lpfc_mbx_unreg_vpi(vport);
527 528 529 530 531
	if (phba->sli_rev == LPFC_SLI_REV4) {
		spin_lock_irq(shost->host_lock);
		vport->fc_flag |= FC_VPORT_NEEDS_INIT_VPI;
		spin_unlock_irq(shost->host_lock);
	}
532 533

	lpfc_vport_set_state(vport, FC_VPORT_DISABLED);
534
	lpfc_printf_vlog(vport, KERN_ERR, LOG_VPORT,
535
			 "1826 Vport Disabled.\n");
536 537 538
	return VPORT_OK;
}

J
James Smart 已提交
539
static int
540 541 542 543 544
enable_vport(struct fc_vport *fc_vport)
{
	struct lpfc_vport *vport = *(struct lpfc_vport **)fc_vport->dd_data;
	struct lpfc_hba   *phba = vport->phba;
	struct lpfc_nodelist *ndlp = NULL;
545
	struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
546 547

	if ((phba->link_state < LPFC_LINK_UP) ||
548
	    (phba->fc_topology == LPFC_TOPOLOGY_LOOP)) {
549 550 551 552
		lpfc_vport_set_state(vport, FC_VPORT_LINKDOWN);
		return VPORT_OK;
	}

553
	spin_lock_irq(shost->host_lock);
554
	vport->load_flag |= FC_LOADING;
555 556 557 558 559 560
	if (vport->fc_flag & FC_VPORT_NEEDS_INIT_VPI) {
		spin_unlock_irq(shost->host_lock);
		lpfc_issue_init_vpi(vport);
		goto out;
	}

561
	vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI;
562
	spin_unlock_irq(shost->host_lock);
563 564 565 566 567

	/* Use the Physical nodes Fabric NDLP to determine if the link is
	 * up and ready to FDISC.
	 */
	ndlp = lpfc_findnode_did(phba->pport, Fabric_DID);
568
	if (ndlp && ndlp->nlp_state == NLP_STE_UNMAPPED_NODE) {
J
James Smart 已提交
569 570 571 572 573
		if (phba->link_flag & LS_NPIV_FAB_SUPPORTED) {
			lpfc_set_disctmo(vport);
			lpfc_initial_fdisc(vport);
		} else {
			lpfc_vport_set_state(vport, FC_VPORT_NO_FABRIC_SUPP);
574
			lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
575
					 "0264 No NPIV Fabric support\n");
J
James Smart 已提交
576
		}
577 578 579
	} else {
		lpfc_vport_set_state(vport, FC_VPORT_FAILED);
	}
580 581

out:
582
	lpfc_printf_vlog(vport, KERN_ERR, LOG_VPORT,
583
			 "1827 Vport Enabled.\n");
584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600
	return VPORT_OK;
}

int
lpfc_vport_disable(struct fc_vport *fc_vport, bool disable)
{
	if (disable)
		return disable_vport(fc_vport);
	else
		return enable_vport(fc_vport);
}

int
lpfc_vport_delete(struct fc_vport *fc_vport)
{
	struct lpfc_nodelist *ndlp = NULL;
	struct lpfc_vport *vport = *(struct lpfc_vport **)fc_vport->dd_data;
J
James Smart 已提交
601
	struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
602
	struct lpfc_hba  *phba = vport->phba;
603 604
	long timeout;

605
	if (vport->port_type == LPFC_PHYSICAL_PORT) {
606
		lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
607 608 609 610
				 "1812 vport_delete failed: Cannot delete "
				 "physical host\n");
		return VPORT_ERROR;
	}
611 612 613 614

	/* If the vport is a static vport fail the deletion. */
	if ((vport->vport_flag & STATIC_VPORT) &&
		!(phba->pport->load_flag & FC_UNLOADING)) {
615
		lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
616 617 618 619
				 "1837 vport_delete failed: Cannot delete "
				 "static vport.\n");
		return VPORT_ERROR;
	}
620

621 622 623
	spin_lock_irq(&phba->hbalock);
	vport->load_flag |= FC_UNLOADING;
	spin_unlock_irq(&phba->hbalock);
624

625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640
	/*
	 * If we are not unloading the driver then prevent the vport_delete
	 * from happening until after this vport's discovery is finished.
	 */
	if (!(phba->pport->load_flag & FC_UNLOADING)) {
		int check_count = 0;
		while (check_count < ((phba->fc_ratov * 3) + 3) &&
		       vport->port_state > LPFC_VPORT_FAILED &&
		       vport->port_state < LPFC_VPORT_READY) {
			check_count++;
			msleep(1000);
		}
		if (vport->port_state > LPFC_VPORT_FAILED &&
		    vport->port_state < LPFC_VPORT_READY)
			return -EAGAIN;
	}
641

642
	/*
643 644 645 646
	 * Take early refcount for outstanding I/O requests we schedule during
	 * delete processing for unreg_vpi.  Always keep this before
	 * scsi_remove_host() as we can no longer obtain a reference through
	 * scsi_host_get() after scsi_host_remove as shost is set to SHOST_DEL.
647
	 */
648
	if (!scsi_host_get(shost))
649
		return VPORT_INVAL;
650

651
	lpfc_free_sysfs_attr(vport);
J
James Smart 已提交
652
	lpfc_debugfs_terminate(vport);
653

654
	/* Remove FC host to break driver binding. */
J
James Smart 已提交
655
	fc_remove_host(shost);
656
	scsi_remove_host(shost);
657

658 659 660
	/* Send the DA_ID and Fabric LOGO to cleanup Nameserver entries. */
	ndlp = lpfc_findnode_did(vport, Fabric_DID);
	if (!ndlp)
661 662
		goto skip_logo;

663
	if (ndlp && ndlp->nlp_state == NLP_STE_UNMAPPED_NODE &&
664
	    phba->link_state >= LPFC_LINK_UP &&
665
	    phba->fc_topology != LPFC_TOPOLOGY_LOOP) {
J
James Smart 已提交
666
		if (vport->cfg_enable_da_id) {
667
			/* Send DA_ID and wait for a completion. */
J
James Smart 已提交
668 669 670 671 672 673 674 675
			timeout = msecs_to_jiffies(phba->fc_ratov * 2000);
			if (!lpfc_ns_cmd(vport, SLI_CTNS_DA_ID, 0, 0))
				while (vport->ct_flags && timeout)
					timeout = schedule_timeout(timeout);
			else
				lpfc_printf_log(vport->phba, KERN_WARNING,
						LOG_VPORT,
						"1829 CT command failed to "
676
						"delete objects on fabric\n");
J
James Smart 已提交
677
		}
678 679 680 681 682 683

		/*
		 * If the vpi is not registered, then a valid FDISC doesn't
		 * exist and there is no need for a ELS LOGO.  Just cleanup
		 * the ndlp.
		 */
684
		if (!(vport->vpi_state & LPFC_VPI_REGISTERED))
685
			goto skip_logo;
686

687 688 689 690
		/* Issue a Fabric LOGO to cleanup fabric resources. */
		ndlp = lpfc_findnode_did(vport, Fabric_DID);
		if (!ndlp)
			goto skip_logo;
691 692 693 694 695 696 697
		vport->unreg_vpi_cmpl = VPORT_INVAL;
		timeout = msecs_to_jiffies(phba->fc_ratov * 2000);
		if (!lpfc_issue_els_npiv_logo(vport, ndlp))
			while (vport->unreg_vpi_cmpl == VPORT_INVAL && timeout)
				timeout = schedule_timeout(timeout);
	}

698 699 700
	if (!(phba->pport->load_flag & FC_UNLOADING))
		lpfc_discovery_wait(vport);

701
skip_logo:
702

703
	lpfc_cleanup(vport);
704 705

	/* Remove scsi host now.  The nodes are cleaned up. */
706 707
	lpfc_sli_host_down(vport);
	lpfc_stop_vport_timers(vport);
708 709

	if (!(phba->pport->load_flag & FC_UNLOADING)) {
710
		lpfc_unreg_all_rpis(vport);
711 712 713 714 715
		lpfc_unreg_default_rpis(vport);
		/*
		 * Completion of unreg_vpi (lpfc_mbx_cmpl_unreg_vpi)
		 * does the scsi_host_put() to release the vport.
		 */
J
James Smart 已提交
716 717
		if (!(vport->vpi_state & LPFC_VPI_REGISTERED) ||
				lpfc_mbx_unreg_vpi(vport))
718
			scsi_host_put(shost);
719
	} else {
720
		scsi_host_put(shost);
721
	}
722 723 724

	lpfc_free_vpi(phba, vport->vpi);
	vport->work_port_events = 0;
725
	spin_lock_irq(&phba->port_list_lock);
726
	list_del_init(&vport->listentry);
727
	spin_unlock_irq(&phba->port_list_lock);
728
	lpfc_printf_vlog(vport, KERN_ERR, LOG_VPORT,
729
			 "1828 Vport Deleted.\n");
730
	scsi_host_put(shost);
731
	return VPORT_OK;
732 733
}

734 735 736 737 738 739
struct lpfc_vport **
lpfc_create_vport_work_array(struct lpfc_hba *phba)
{
	struct lpfc_vport *port_iterator;
	struct lpfc_vport **vports;
	int index = 0;
K
Kees Cook 已提交
740
	vports = kcalloc(phba->max_vports + 1, sizeof(struct lpfc_vport *),
741 742 743
			 GFP_KERNEL);
	if (vports == NULL)
		return NULL;
744
	spin_lock_irq(&phba->port_list_lock);
745
	list_for_each_entry(port_iterator, &phba->port_list, listentry) {
746 747
		if (port_iterator->load_flag & FC_UNLOADING)
			continue;
748
		if (!scsi_host_get(lpfc_shost_from_vport(port_iterator))) {
749 750
			lpfc_printf_vlog(port_iterator, KERN_ERR,
					 LOG_TRACE_EVENT,
751 752
					 "1801 Create vport work array FAILED: "
					 "cannot do scsi_host_get\n");
753
			continue;
754
		}
755 756
		vports[index++] = port_iterator;
	}
757
	spin_unlock_irq(&phba->port_list_lock);
758 759 760 761
	return vports;
}

void
762
lpfc_destroy_vport_work_array(struct lpfc_hba *phba, struct lpfc_vport **vports)
763 764 765 766
{
	int i;
	if (vports == NULL)
		return;
J
James Smart 已提交
767
	for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++)
768 769 770
		scsi_host_put(lpfc_shost_from_vport(vports[i]));
	kfree(vports);
}
771 772 773


/**
774
 * lpfc_vport_reset_stat_data - Reset the statistical data for the vport
775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793
 * @vport: Pointer to vport object.
 *
 * This function resets the statistical data for the vport. This function
 * is called with the host_lock held
 **/
void
lpfc_vport_reset_stat_data(struct lpfc_vport *vport)
{
	struct lpfc_nodelist *ndlp = NULL, *next_ndlp = NULL;

	list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) {
		if (ndlp->lat_data)
			memset(ndlp->lat_data, 0, LPFC_MAX_BUCKET_COUNT *
				sizeof(struct lpfc_scsicmd_bkt));
	}
}


/**
794
 * lpfc_alloc_bucket - Allocate data buffer required for statistical data
795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815
 * @vport: Pointer to vport object.
 *
 * This function allocates data buffer required for all the FC
 * nodes of the vport to collect statistical data.
 **/
void
lpfc_alloc_bucket(struct lpfc_vport *vport)
{
	struct lpfc_nodelist *ndlp = NULL, *next_ndlp = NULL;

	list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) {

		kfree(ndlp->lat_data);
		ndlp->lat_data = NULL;

		if (ndlp->nlp_state == NLP_STE_MAPPED_NODE) {
			ndlp->lat_data = kcalloc(LPFC_MAX_BUCKET_COUNT,
					 sizeof(struct lpfc_scsicmd_bkt),
					 GFP_ATOMIC);

			if (!ndlp->lat_data)
816 817
				lpfc_printf_vlog(vport, KERN_ERR,
					LOG_TRACE_EVENT,
818 819 820 821 822 823 824 825
					"0287 lpfc_alloc_bucket failed to "
					"allocate statistical data buffer DID "
					"0x%x\n", ndlp->nlp_DID);
		}
	}
}

/**
826
 * lpfc_free_bucket - Free data buffer required for statistical data
827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842
 * @vport: Pointer to vport object.
 *
 * Th function frees statistical data buffer of all the FC
 * nodes of the vport.
 **/
void
lpfc_free_bucket(struct lpfc_vport *vport)
{
	struct lpfc_nodelist *ndlp = NULL, *next_ndlp = NULL;

	list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) {

		kfree(ndlp->lat_data);
		ndlp->lat_data = NULL;
	}
}