lpfc_hbadisc.c 78.2 KB
Newer Older
已提交
1 2
/*******************************************************************
 * This file is part of the Emulex Linux Device Driver for         *
3
 * Fibre Channel Host Bus Adapters.                                *
4
 * Copyright (C) 2004-2007 Emulex.  All rights reserved.           *
5
 * EMULEX and SLI are trademarks of Emulex.                        *
已提交
6
 * www.emulex.com                                                  *
7
 * Portions Copyright (C) 2004-2005 Christoph Hellwig              *
已提交
8 9
 *                                                                 *
 * This program is free software; you can redistribute it and/or   *
10 11 12 13 14 15 16 17 18 19
 * 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.                                     *
已提交
20 21 22 23 24 25 26
 *******************************************************************/

#include <linux/blkdev.h>
#include <linux/pci.h>
#include <linux/kthread.h>
#include <linux/interrupt.h>

27
#include <scsi/scsi.h>
已提交
28 29 30 31 32 33 34 35 36 37 38
#include <scsi/scsi_device.h>
#include <scsi/scsi_host.h>
#include <scsi/scsi_transport_fc.h>

#include "lpfc_hw.h"
#include "lpfc_disc.h"
#include "lpfc_sli.h"
#include "lpfc_scsi.h"
#include "lpfc.h"
#include "lpfc_logmsg.h"
#include "lpfc_crtn.h"
39
#include "lpfc_vport.h"
J
James Smart 已提交
40
#include "lpfc_debugfs.h"
已提交
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58

/* AlpaArray for assignment of scsid for scan-down and bind_method */
static uint8_t lpfcAlpaArray[] = {
	0xEF, 0xE8, 0xE4, 0xE2, 0xE1, 0xE0, 0xDC, 0xDA, 0xD9, 0xD6,
	0xD5, 0xD4, 0xD3, 0xD2, 0xD1, 0xCE, 0xCD, 0xCC, 0xCB, 0xCA,
	0xC9, 0xC7, 0xC6, 0xC5, 0xC3, 0xBC, 0xBA, 0xB9, 0xB6, 0xB5,
	0xB4, 0xB3, 0xB2, 0xB1, 0xAE, 0xAD, 0xAC, 0xAB, 0xAA, 0xA9,
	0xA7, 0xA6, 0xA5, 0xA3, 0x9F, 0x9E, 0x9D, 0x9B, 0x98, 0x97,
	0x90, 0x8F, 0x88, 0x84, 0x82, 0x81, 0x80, 0x7C, 0x7A, 0x79,
	0x76, 0x75, 0x74, 0x73, 0x72, 0x71, 0x6E, 0x6D, 0x6C, 0x6B,
	0x6A, 0x69, 0x67, 0x66, 0x65, 0x63, 0x5C, 0x5A, 0x59, 0x56,
	0x55, 0x54, 0x53, 0x52, 0x51, 0x4E, 0x4D, 0x4C, 0x4B, 0x4A,
	0x49, 0x47, 0x46, 0x45, 0x43, 0x3C, 0x3A, 0x39, 0x36, 0x35,
	0x34, 0x33, 0x32, 0x31, 0x2E, 0x2D, 0x2C, 0x2B, 0x2A, 0x29,
	0x27, 0x26, 0x25, 0x23, 0x1F, 0x1E, 0x1D, 0x1B, 0x18, 0x17,
	0x10, 0x0F, 0x08, 0x04, 0x02, 0x01
};

J
James Smart 已提交
59
static void lpfc_disc_timeout_handler(struct lpfc_vport *);
A
Adrian Bunk 已提交
60
static void lpfc_disc_flush_list(struct lpfc_vport *vport);
已提交
61

62 63
void
lpfc_terminate_rport_io(struct fc_rport *rport)
已提交
64
{
65 66 67
	struct lpfc_rport_data *rdata;
	struct lpfc_nodelist * ndlp;
	struct lpfc_hba *phba;
已提交
68

69 70 71 72 73 74 75 76
	rdata = rport->dd_data;
	ndlp = rdata->pnode;

	if (!ndlp) {
		if (rport->roles & FC_RPORT_ROLE_FCP_TARGET)
			printk(KERN_ERR "Cannot find remote node"
			" to terminate I/O Data x%x\n",
			rport->port_id);
已提交
77 78 79
		return;
	}

J
James Smart 已提交
80
	phba  = ndlp->vport->phba;
81

J
James Smart 已提交
82 83 84 85
	lpfc_debugfs_disc_trc(ndlp->vport, LPFC_DISC_TRC_RPORT,
		"rport terminate: sid:x%x did:x%x flg:x%x",
		ndlp->nlp_sid, ndlp->nlp_DID, ndlp->nlp_flag);

86
	if (ndlp->nlp_sid != NLP_NO_SID) {
87 88 89
		lpfc_sli_abort_iocb(ndlp->vport,
			&phba->sli.ring[phba->sli.fcp_ring],
			ndlp->nlp_sid, 0, LPFC_CTX_TGT);
90 91
	}

92 93 94 95 96 97
	/*
	 * A device is normally blocked for rediscovery and unblocked when
	 * devloss timeout happens.  In case a vport is removed or driver
	 * unloaded before devloss timeout happens, we need to unblock here.
	 */
	scsi_target_unblock(&rport->dev);
98 99 100 101 102 103 104 105 106 107 108
	return;
}

/*
 * This function will be called when dev_loss_tmo fire.
 */
void
lpfc_dev_loss_tmo_callbk(struct fc_rport *rport)
{
	struct lpfc_rport_data *rdata;
	struct lpfc_nodelist * ndlp;
J
James Smart 已提交
109
	struct lpfc_vport *vport;
J
James Smart 已提交
110 111
	struct lpfc_hba   *phba;
	struct lpfc_work_evt *evtp;
112 113
	int  put_node;
	int  put_rport;
114 115 116

	rdata = rport->dd_data;
	ndlp = rdata->pnode;
117

118
	if (!ndlp) {
119
		if (rport->scsi_target_id != -1) {
120
			printk(KERN_ERR "Cannot find remote node"
121 122 123
				" for rport in dev_loss_tmo_callbk x%x\n",
				rport->port_id);
		}
124 125 126
		return;
	}

J
James Smart 已提交
127 128 129 130 131 132 133
	vport = ndlp->vport;
	phba  = vport->phba;

	lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_RPORT,
		"rport devlosscb: sid:x%x did:x%x flg:x%x",
		ndlp->nlp_sid, ndlp->nlp_DID, ndlp->nlp_flag);

134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
	/* Don't defer this if we are in the process of deleting the vport
	 * or unloading the driver. The unload will cleanup the node
	 * appropriately we just need to cleanup the ndlp rport info here.
	 */
	if (vport->load_flag & FC_UNLOADING) {
		put_node = rdata->pnode != NULL;
		put_rport = ndlp->rport != NULL;
		rdata->pnode = NULL;
		ndlp->rport = NULL;
		if (put_node)
			lpfc_nlp_put(ndlp);
		if (put_rport)
			put_device(&rport->dev);
		return;
	}

	if (ndlp->nlp_state == NLP_STE_MAPPED_NODE)
		return;

J
James Smart 已提交
153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173
	evtp = &ndlp->dev_loss_evt;

	if (!list_empty(&evtp->evt_listp))
		return;

	spin_lock_irq(&phba->hbalock);
	evtp->evt_arg1  = ndlp;
	evtp->evt       = LPFC_EVT_DEV_LOSS;
	list_add_tail(&evtp->evt_listp, &phba->work_list);
	if (phba->work_wait)
		wake_up(phba->work_wait);

	spin_unlock_irq(&phba->hbalock);

	return;
}

/*
 * This function is called from the worker thread when dev_loss_tmo
 * expire.
 */
A
Adrian Bunk 已提交
174
static void
J
James Smart 已提交
175 176 177 178 179 180 181
lpfc_dev_loss_tmo_handler(struct lpfc_nodelist *ndlp)
{
	struct lpfc_rport_data *rdata;
	struct fc_rport   *rport;
	struct lpfc_vport *vport;
	struct lpfc_hba   *phba;
	uint8_t *name;
182 183
	int  put_node;
	int  put_rport;
J
James Smart 已提交
184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199
	int warn_on = 0;

	rport = ndlp->rport;

	if (!rport)
		return;

	rdata = rport->dd_data;
	name = (uint8_t *) &ndlp->nlp_portname;
	vport = ndlp->vport;
	phba  = vport->phba;

	lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_RPORT,
		"rport devlosstmo:did:x%x type:x%x id:x%x",
		ndlp->nlp_DID, ndlp->nlp_type, rport->scsi_target_id);

200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216
	/* Don't defer this if we are in the process of deleting the vport
	 * or unloading the driver. The unload will cleanup the node
	 * appropriately we just need to cleanup the ndlp rport info here.
	 */
	if (vport->load_flag & FC_UNLOADING) {
		put_node = rdata->pnode != NULL;
		put_rport = ndlp->rport != NULL;
		rdata->pnode = NULL;
		ndlp->rport = NULL;
		if (put_node)
			lpfc_nlp_put(ndlp);
		if (put_rport)
			put_device(&rport->dev);
		return;
	}

	if (ndlp->nlp_state == NLP_STE_MAPPED_NODE)
J
James Smart 已提交
217 218
		return;

219 220 221 222 223 224 225 226 227 228
	if (ndlp->nlp_type & NLP_FABRIC) {
		/* We will clean up these Nodes in linkup */
		put_node = rdata->pnode != NULL;
		put_rport = ndlp->rport != NULL;
		rdata->pnode = NULL;
		ndlp->rport = NULL;
		if (put_node)
			lpfc_nlp_put(ndlp);
		if (put_rport)
			put_device(&rport->dev);
229
		return;
230
	}
231

已提交
232
	if (ndlp->nlp_sid != NLP_NO_SID) {
233
		warn_on = 1;
已提交
234
		/* flush the target */
235 236
		lpfc_sli_abort_iocb(vport, &phba->sli.ring[phba->sli.fcp_ring],
				    ndlp->nlp_sid, 0, LPFC_CTX_TGT);
已提交
237
	}
J
James Smart 已提交
238
	if (vport->load_flag & FC_UNLOADING)
239 240
		warn_on = 0;

241
	if (warn_on) {
242 243 244 245 246 247 248 249
		lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY,
				 "0203 Devloss timeout on "
				 "WWPN %x:%x:%x:%x:%x:%x:%x:%x "
				 "NPort x%x Data: x%x x%x x%x\n",
				 *name, *(name+1), *(name+2), *(name+3),
				 *(name+4), *(name+5), *(name+6), *(name+7),
				 ndlp->nlp_DID, ndlp->nlp_flag,
				 ndlp->nlp_state, ndlp->nlp_rpi);
250
	} else {
251 252 253 254 255 256 257 258
		lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
				 "0204 Devloss timeout on "
				 "WWPN %x:%x:%x:%x:%x:%x:%x:%x "
				 "NPort x%x Data: x%x x%x x%x\n",
				 *name, *(name+1), *(name+2), *(name+3),
				 *(name+4), *(name+5), *(name+6), *(name+7),
				 ndlp->nlp_DID, ndlp->nlp_flag,
				 ndlp->nlp_state, ndlp->nlp_rpi);
259 260
	}

261 262 263 264 265 266 267 268 269
	put_node = rdata->pnode != NULL;
	put_rport = ndlp->rport != NULL;
	rdata->pnode = NULL;
	ndlp->rport = NULL;
	if (put_node)
		lpfc_nlp_put(ndlp);
	if (put_rport)
		put_device(&rport->dev);

J
James Smart 已提交
270
	if (!(vport->load_flag & FC_UNLOADING) &&
271
	    !(ndlp->nlp_flag & NLP_DELAY_TMO) &&
272
	    !(ndlp->nlp_flag & NLP_NPR_2B_DISC) &&
273
	    (ndlp->nlp_state != NLP_STE_UNMAPPED_NODE)) {
J
James Smart 已提交
274
		lpfc_disc_state_machine(vport, ndlp, NULL, NLP_EVT_DEVICE_RM);
275
	}
276
}
277

278 279 280 281 282

void
lpfc_worker_wake_up(struct lpfc_hba *phba)
{
	wake_up(phba->work_wait);
已提交
283 284 285 286
	return;
}

static void
J
James Smart 已提交
287
lpfc_work_list_done(struct lpfc_hba *phba)
已提交
288 289 290 291 292
{
	struct lpfc_work_evt  *evtp = NULL;
	struct lpfc_nodelist  *ndlp;
	int free_evt;

J
James Smart 已提交
293 294
	spin_lock_irq(&phba->hbalock);
	while (!list_empty(&phba->work_list)) {
已提交
295 296
		list_remove_head((&phba->work_list), evtp, typeof(*evtp),
				 evt_listp);
J
James Smart 已提交
297
		spin_unlock_irq(&phba->hbalock);
已提交
298
		free_evt = 1;
299
		switch (evtp->evt) {
已提交
300
		case LPFC_EVT_ELS_RETRY:
J
James Smart 已提交
301
			ndlp = (struct lpfc_nodelist *) (evtp->evt_arg1);
已提交
302
			lpfc_els_retry_delay_handler(ndlp);
303
			free_evt = 0; /* evt is part of ndlp */
已提交
304
			break;
J
James Smart 已提交
305 306 307 308 309 310 311
		case LPFC_EVT_DEV_LOSS:
			ndlp = (struct lpfc_nodelist *)(evtp->evt_arg1);
			lpfc_nlp_get(ndlp);
			lpfc_dev_loss_tmo_handler(ndlp);
			free_evt = 0;
			lpfc_nlp_put(ndlp);
			break;
已提交
312
		case LPFC_EVT_ONLINE:
J
James Smart 已提交
313 314
			if (phba->link_state < LPFC_LINK_DOWN)
				*(int *) (evtp->evt_arg1) = lpfc_online(phba);
315
			else
J
James Smart 已提交
316
				*(int *) (evtp->evt_arg1) = 0;
已提交
317 318
			complete((struct completion *)(evtp->evt_arg2));
			break;
319
		case LPFC_EVT_OFFLINE_PREP:
J
James Smart 已提交
320
			if (phba->link_state >= LPFC_LINK_DOWN)
321 322 323 324 325 326
				lpfc_offline_prep(phba);
			*(int *)(evtp->evt_arg1) = 0;
			complete((struct completion *)(evtp->evt_arg2));
			break;
		case LPFC_EVT_OFFLINE:
			lpfc_offline(phba);
327 328
			lpfc_sli_brdrestart(phba);
			*(int *)(evtp->evt_arg1) =
329 330
				lpfc_sli_brdready(phba, HS_FFRDY | HS_MBRDY);
			lpfc_unblock_mgmt_io(phba);
331 332 333
			complete((struct completion *)(evtp->evt_arg2));
			break;
		case LPFC_EVT_WARM_START:
334
			lpfc_offline(phba);
335
			lpfc_reset_barrier(phba);
336 337 338 339
			lpfc_sli_brdreset(phba);
			lpfc_hba_down_post(phba);
			*(int *)(evtp->evt_arg1) =
				lpfc_sli_brdready(phba, HS_MBRDY);
340
			lpfc_unblock_mgmt_io(phba);
341 342 343
			complete((struct completion *)(evtp->evt_arg2));
			break;
		case LPFC_EVT_KILL:
344
			lpfc_offline(phba);
345
			*(int *)(evtp->evt_arg1)
J
James Smart 已提交
346 347
				= (phba->pport->stopped)
				        ? 0 : lpfc_sli_brdkill(phba);
348
			lpfc_unblock_mgmt_io(phba);
已提交
349 350 351 352 353
			complete((struct completion *)(evtp->evt_arg2));
			break;
		}
		if (free_evt)
			kfree(evtp);
J
James Smart 已提交
354
		spin_lock_irq(&phba->hbalock);
已提交
355
	}
J
James Smart 已提交
356
	spin_unlock_irq(&phba->hbalock);
已提交
357 358 359

}

J
James Smart 已提交
360
static void
J
James Smart 已提交
361
lpfc_work_done(struct lpfc_hba *phba)
已提交
362 363
{
	struct lpfc_sli_ring *pring;
J
James Smart 已提交
364
	uint32_t ha_copy, status, control, work_port_events;
365
	struct lpfc_vport **vports;
366
	struct lpfc_vport *vport;
367
	int i;
已提交
368

J
James Smart 已提交
369
	spin_lock_irq(&phba->hbalock);
已提交
370 371
	ha_copy = phba->work_ha;
	phba->work_ha = 0;
J
James Smart 已提交
372
	spin_unlock_irq(&phba->hbalock);
已提交
373

374
	if (ha_copy & HA_ERATT)
已提交
375 376
		lpfc_handle_eratt(phba);

377
	if (ha_copy & HA_MBATT)
已提交
378 379
		lpfc_sli_handle_mb_event(phba);

380
	if (ha_copy & HA_LATT)
已提交
381
		lpfc_handle_latt(phba);
382 383
	vports = lpfc_create_vport_work_array(phba);
	if (vports != NULL)
384 385 386 387 388 389 390 391 392 393 394 395
		for(i = 0; i < LPFC_MAX_VPORTS; i++) {
			/*
			 * We could have no vports in array if unloading, so if
			 * this happens then just use the pport
			 */
			if (vports[i] == NULL && i == 0)
				vport = phba->pport;
			else
				vport = vports[i];
			if (vport == NULL)
				break;
			work_port_events = vport->work_port_events;
396
			if (work_port_events & WORKER_DISC_TMO)
397
				lpfc_disc_timeout_handler(vport);
398
			if (work_port_events & WORKER_ELS_TMO)
399
				lpfc_els_timeout_handler(vport);
400 401 402 403 404 405 406
			if (work_port_events & WORKER_HB_TMO)
				lpfc_hb_timeout_handler(phba);
			if (work_port_events & WORKER_MBOX_TMO)
				lpfc_mbox_timeout_handler(phba);
			if (work_port_events & WORKER_FABRIC_BLOCK_TMO)
				lpfc_unblock_fabric_iocbs(phba);
			if (work_port_events & WORKER_FDMI_TMO)
407
				lpfc_fdmi_timeout_handler(vport);
408 409 410 411
			if (work_port_events & WORKER_RAMP_DOWN_QUEUE)
				lpfc_ramp_down_queue_handler(phba);
			if (work_port_events & WORKER_RAMP_UP_QUEUE)
				lpfc_ramp_up_queue_handler(phba);
412 413 414
			spin_lock_irq(&vport->work_port_lock);
			vport->work_port_events &= ~work_port_events;
			spin_unlock_irq(&vport->work_port_lock);
415
		}
416
	lpfc_destroy_vport_work_array(vports);
已提交
417

J
James Smart 已提交
418 419 420 421 422
	pring = &phba->sli.ring[LPFC_ELS_RING];
	status = (ha_copy & (HA_RXMASK  << (4*LPFC_ELS_RING)));
	status >>= (4*LPFC_ELS_RING);
	if ((status & HA_RXMASK)
		|| (pring->flag & LPFC_DEFERRED_RING_EVENT)) {
423
		if (pring->flag & LPFC_STOP_IOCB_EVENT) {
J
James Smart 已提交
424 425 426 427 428 429 430 431 432 433 434 435 436
			pring->flag |= LPFC_DEFERRED_RING_EVENT;
		} else {
			lpfc_sli_handle_slow_ring_event(phba, pring,
							(status &
							 HA_RXMASK));
			pring->flag &= ~LPFC_DEFERRED_RING_EVENT;
		}
		/*
		 * Turn on Ring interrupts
		 */
		spin_lock_irq(&phba->hbalock);
		control = readl(phba->HCregaddr);
		if (!(control & (HC_R0INT_ENA << LPFC_ELS_RING))) {
437 438 439 440
			lpfc_debugfs_slow_ring_trc(phba,
				"WRK Enable ring: cntl:x%x hacopy:x%x",
				control, ha_copy, 0);

J
James Smart 已提交
441
			control |= (HC_R0INT_ENA << LPFC_ELS_RING);
已提交
442 443 444
			writel(control, phba->HCregaddr);
			readl(phba->HCregaddr); /* flush */
		}
445 446 447 448 449
		else {
			lpfc_debugfs_slow_ring_trc(phba,
				"WRK Ring ok:     cntl:x%x hacopy:x%x",
				control, ha_copy, 0);
		}
J
James Smart 已提交
450
		spin_unlock_irq(&phba->hbalock);
已提交
451
	}
J
James Smart 已提交
452
	lpfc_work_list_done(phba);
已提交
453 454 455
}

static int
J
James Smart 已提交
456 457
check_work_wait_done(struct lpfc_hba *phba)
{
458
	struct lpfc_vport *vport;
459
	struct lpfc_sli_ring *pring = &phba->sli.ring[LPFC_ELS_RING];
J
James Smart 已提交
460
	int rc = 0;
461

J
James Smart 已提交
462
	spin_lock_irq(&phba->hbalock);
463 464 465
	list_for_each_entry(vport, &phba->port_list, listentry) {
		if (vport->work_port_events) {
			rc = 1;
466
			break;
467 468
		}
	}
469 470
	if (rc || phba->work_ha || (!list_empty(&phba->work_list)) ||
	    kthread_should_stop() || pring->flag & LPFC_DEFERRED_RING_EVENT) {
J
James Smart 已提交
471
		rc = 1;
472
		phba->work_found++;
473
	} else
474
		phba->work_found = 0;
J
James Smart 已提交
475 476
	spin_unlock_irq(&phba->hbalock);
	return rc;
已提交
477 478
}

479

已提交
480 481 482 483 484
int
lpfc_do_work(void *p)
{
	struct lpfc_hba *phba = p;
	int rc;
485
	DECLARE_WAIT_QUEUE_HEAD_ONSTACK(work_waitq);
已提交
486 487 488

	set_user_nice(current, -20);
	phba->work_wait = &work_waitq;
489
	phba->work_found = 0;
已提交
490 491 492 493

	while (1) {

		rc = wait_event_interruptible(work_waitq,
494 495
					      check_work_wait_done(phba));

已提交
496 497 498 499 500 501 502
		BUG_ON(rc);

		if (kthread_should_stop())
			break;

		lpfc_work_done(phba);

503 504 505 506 507 508 509 510 511 512 513
		/* If there is alot of slow ring work, like during link up
		 * check_work_wait_done() may cause this thread to not give
		 * up the CPU for very long periods of time. This may cause
		 * soft lockups or other problems. To avoid these situations
		 * give up the CPU here after LPFC_MAX_WORKER_ITERATION
		 * consecutive iterations.
		 */
		if (phba->work_found >= LPFC_MAX_WORKER_ITERATION) {
			phba->work_found = 0;
			schedule();
		}
已提交
514 515 516 517 518 519 520 521 522 523 524
	}
	phba->work_wait = NULL;
	return 0;
}

/*
 * This is only called to handle FC worker events. Since this a rare
 * occurance, we allocate a struct lpfc_work_evt structure here instead of
 * embedding it in the IOCB.
 */
int
J
James Smart 已提交
525
lpfc_workq_post_event(struct lpfc_hba *phba, void *arg1, void *arg2,
已提交
526 527 528
		      uint32_t evt)
{
	struct lpfc_work_evt  *evtp;
529
	unsigned long flags;
已提交
530 531 532 533 534

	/*
	 * All Mailbox completions and LPFC_ELS_RING rcv ring IOCB events will
	 * be queued to worker thread for processing
	 */
535
	evtp = kmalloc(sizeof(struct lpfc_work_evt), GFP_ATOMIC);
已提交
536 537 538 539 540 541 542
	if (!evtp)
		return 0;

	evtp->evt_arg1  = arg1;
	evtp->evt_arg2  = arg2;
	evtp->evt       = evt;

543
	spin_lock_irqsave(&phba->hbalock, flags);
544
	list_add_tail(&evtp->evt_listp, &phba->work_list);
已提交
545
	if (phba->work_wait)
546
		lpfc_worker_wake_up(phba);
547
	spin_unlock_irqrestore(&phba->hbalock, flags);
已提交
548 549 550 551

	return 1;
}

552 553 554 555 556 557 558 559 560 561 562
void
lpfc_cleanup_rpis(struct lpfc_vport *vport, int remove)
{
	struct lpfc_hba  *phba = vport->phba;
	struct lpfc_nodelist *ndlp, *next_ndlp;
	int  rc;

	list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) {
		if (ndlp->nlp_state == NLP_STE_UNUSED_NODE)
			continue;

563 564 565
		if ((phba->sli3_options & LPFC_SLI3_VPORT_TEARDOWN) ||
			((vport->port_type == LPFC_NPIV_PORT) &&
			(ndlp->nlp_DID == NameServer_DID)))
566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581
			lpfc_unreg_rpi(vport, ndlp);

		/* Leave Fabric nodes alone on link down */
		if (!remove && ndlp->nlp_type & NLP_FABRIC)
			continue;
		rc = lpfc_disc_state_machine(vport, ndlp, NULL,
					     remove
					     ? NLP_EVT_DEVICE_RM
					     : NLP_EVT_DEVICE_RECOVERY);
	}
	if (phba->sli3_options & LPFC_SLI3_VPORT_TEARDOWN) {
		lpfc_mbx_unreg_vpi(vport);
		vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI;
	}
}

582
void
583
lpfc_port_link_failure(struct lpfc_vport *vport)
584 585 586 587 588 589 590 591 592 593 594 595 596
{
	/* Cleanup any outstanding RSCN activity */
	lpfc_els_flush_rscn(vport);

	/* Cleanup any outstanding ELS commands */
	lpfc_els_flush_cmd(vport);

	lpfc_cleanup_rpis(vport, 0);

	/* Turn off discovery timer if its running */
	lpfc_can_disctmo(vport);
}

597 598 599 600 601 602 603 604 605 606 607 608 609 610 611
static void
lpfc_linkdown_port(struct lpfc_vport *vport)
{
	struct Scsi_Host  *shost = lpfc_shost_from_vport(vport);

	fc_host_post_event(shost, fc_get_event_number(), FCH_EVT_LINKDOWN, 0);

	lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
		"Link Down:       state:x%x rtry:x%x flg:x%x",
		vport->port_state, vport->fc_ns_retry, vport->fc_flag);

	lpfc_port_link_failure(vport);

}

已提交
612
int
613
lpfc_linkdown(struct lpfc_hba *phba)
已提交
614
{
J
James Smart 已提交
615 616
	struct lpfc_vport *vport = phba->pport;
	struct Scsi_Host  *shost = lpfc_shost_from_vport(vport);
617
	struct lpfc_vport **vports;
618
	LPFC_MBOXQ_t          *mb;
619
	int i;
已提交
620

J
James Smart 已提交
621 622
	if (phba->link_state == LPFC_LINK_DOWN) {
		return 0;
623
	}
J
James Smart 已提交
624
	spin_lock_irq(&phba->hbalock);
625
	if (phba->link_state > LPFC_LINK_DOWN) {
J
James Smart 已提交
626
		phba->link_state = LPFC_LINK_DOWN;
627 628
		phba->pport->fc_flag &= ~FC_LBIT;
	}
J
James Smart 已提交
629
	spin_unlock_irq(&phba->hbalock);
630 631 632 633 634 635 636
	vports = lpfc_create_vport_work_array(phba);
	if (vports != NULL)
		for(i = 0; i < LPFC_MAX_VPORTS && vports[i] != NULL; i++) {
			/* Issue a LINK DOWN event to all nodes */
			lpfc_linkdown_port(vports[i]);
		}
	lpfc_destroy_vport_work_array(vports);
已提交
637
	/* Clean up any firmware default rpi's */
J
James Smart 已提交
638 639
	mb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
	if (mb) {
640
		lpfc_unreg_did(phba, 0xffff, 0xffffffff, mb);
641
		mb->vport = vport;
J
James Smart 已提交
642
		mb->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
643
		if (lpfc_sli_issue_mbox(phba, mb, MBX_NOWAIT)
已提交
644
		    == MBX_NOT_FINISHED) {
J
James Smart 已提交
645
			mempool_free(mb, phba->mbox_mem_pool);
已提交
646 647 648 649
		}
	}

	/* Setup myDID for link up if we are in pt2pt mode */
650 651
	if (phba->pport->fc_flag & FC_PT2PT) {
		phba->pport->fc_myDID = 0;
J
James Smart 已提交
652 653
		mb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
		if (mb) {
已提交
654
			lpfc_config_link(phba, mb);
655
			mb->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
656
			mb->vport = vport;
657
			if (lpfc_sli_issue_mbox(phba, mb, MBX_NOWAIT)
已提交
658
			    == MBX_NOT_FINISHED) {
J
James Smart 已提交
659
				mempool_free(mb, phba->mbox_mem_pool);
已提交
660 661
			}
		}
J
James Smart 已提交
662
		spin_lock_irq(shost->host_lock);
663
		phba->pport->fc_flag &= ~(FC_PT2PT | FC_PT2PT_PLOGI);
J
James Smart 已提交
664
		spin_unlock_irq(shost->host_lock);
已提交
665
	}
J
James Smart 已提交
666

667 668
	return 0;
}
已提交
669

670 671 672 673
static void
lpfc_linkup_cleanup_nodes(struct lpfc_vport *vport)
{
	struct lpfc_nodelist *ndlp;
已提交
674

675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692
	list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) {
		if (ndlp->nlp_state == NLP_STE_UNUSED_NODE)
			continue;

		if (ndlp->nlp_type & NLP_FABRIC) {
				/* On Linkup its safe to clean up the ndlp
				 * from Fabric connections.
				 */
			if (ndlp->nlp_DID != Fabric_DID)
				lpfc_unreg_rpi(vport, ndlp);
			lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
		} else if (!(ndlp->nlp_flag & NLP_NPR_ADISC)) {
				/* Fail outstanding IO now since device is
				 * marked for PLOGI.
				 */
			lpfc_unreg_rpi(vport, ndlp);
		}
	}
已提交
693 694
}

695 696
static void
lpfc_linkup_port(struct lpfc_vport *vport)
已提交
697
{
698 699 700 701 702 703
	struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
	struct lpfc_hba  *phba = vport->phba;

	if ((vport->load_flag & FC_UNLOADING) != 0)
		return;

J
James Smart 已提交
704 705 706 707
	lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
		"Link Up:         top:x%x speed:x%x flg:x%x",
		phba->fc_topology, phba->fc_linkspeed, phba->link_flag);

708 709 710 711
	/* If NPIV is not enabled, only bring the physical port up */
	if (!(phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) &&
		(vport != phba->pport))
		return;
已提交
712

J
James Smart 已提交
713
	fc_host_post_event(shost, fc_get_event_number(), FCH_EVT_LINKUP, 0);
714

J
James Smart 已提交
715 716 717 718 719 720
	spin_lock_irq(shost->host_lock);
	vport->fc_flag &= ~(FC_PT2PT | FC_PT2PT_PLOGI | FC_ABORT_DISCOVERY |
			    FC_RSCN_MODE | FC_NLP_MORE | FC_RSCN_DISCOVERY);
	vport->fc_flag |= FC_NDISC_ACTIVE;
	vport->fc_ns_retry = 0;
	spin_unlock_irq(shost->host_lock);
已提交
721

722 723
	if (vport->fc_flag & FC_LBIT)
		lpfc_linkup_cleanup_nodes(vport);
已提交
724

725 726 727 728 729
}

static int
lpfc_linkup(struct lpfc_hba *phba)
{
730 731
	struct lpfc_vport **vports;
	int i;
732 733 734 735 736 737 738

	phba->link_state = LPFC_LINK_UP;

	/* Unblock fabric iocbs if they are blocked */
	clear_bit(FABRIC_COMANDS_BLOCKED, &phba->bit_flags);
	del_timer_sync(&phba->fabric_block_timer);

739 740 741 742 743
	vports = lpfc_create_vport_work_array(phba);
	if (vports != NULL)
		for(i = 0; i < LPFC_MAX_VPORTS && vports[i] != NULL; i++)
			lpfc_linkup_port(vports[i]);
	lpfc_destroy_vport_work_array(vports);
744 745
	if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED)
		lpfc_issue_clear_la(phba, phba->pport);
已提交
746 747 748 749 750 751 752 753 754 755

	return 0;
}

/*
 * This routine handles processing a CLEAR_LA mailbox
 * command upon completion. It is setup in the LPFC_MBOXQ
 * as the completion routine when the command is
 * handed off to the SLI layer.
 */
A
Adrian Bunk 已提交
756
static void
J
James Smart 已提交
757
lpfc_mbx_cmpl_clear_la(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
已提交
758
{
J
James Smart 已提交
759 760 761 762
	struct lpfc_vport *vport = pmb->vport;
	struct Scsi_Host  *shost = lpfc_shost_from_vport(vport);
	struct lpfc_sli   *psli = &phba->sli;
	MAILBOX_t *mb = &pmb->mb;
已提交
763 764 765
	uint32_t control;

	/* Since we don't do discovery right now, turn these off here */
766
	psli->ring[psli->extra_ring].flag &= ~LPFC_STOP_IOCB_EVENT;
已提交
767 768 769 770 771
	psli->ring[psli->fcp_ring].flag &= ~LPFC_STOP_IOCB_EVENT;
	psli->ring[psli->next_ring].flag &= ~LPFC_STOP_IOCB_EVENT;

	/* Check for error */
	if ((mb->mbxStatus) && (mb->mbxStatus != 0x1601)) {
772
		/* CLEAR_LA mbox error <mbxStatus> state <hba_state> */
773 774 775 776
		lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX,
				 "0320 CLEAR_LA mbxStatus error x%x hba "
				 "state x%x\n",
				 mb->mbxStatus, vport->port_state);
J
James Smart 已提交
777
		phba->link_state = LPFC_HBA_ERROR;
已提交
778 779 780
		goto out;
	}

781 782 783 784 785 786 787 788 789 790 791
	if (vport->port_type == LPFC_PHYSICAL_PORT)
		phba->link_state = LPFC_HBA_READY;

	spin_lock_irq(&phba->hbalock);
	psli->sli_flag |= LPFC_PROCESS_LA;
	control = readl(phba->HCregaddr);
	control |= HC_LAINT_ENA;
	writel(control, phba->HCregaddr);
	readl(phba->HCregaddr); /* flush */
	spin_unlock_irq(&phba->hbalock);
	return;
已提交
792

J
James Smart 已提交
793 794 795 796
	vport->num_disc_nodes = 0;
	/* go thru NPR nodes and issue ELS PLOGIs */
	if (vport->fc_npr_cnt)
		lpfc_els_disc_plogi(vport);
已提交
797

J
James Smart 已提交
798 799 800 801
	if (!vport->num_disc_nodes) {
		spin_lock_irq(shost->host_lock);
		vport->fc_flag &= ~FC_NDISC_ACTIVE;
		spin_unlock_irq(shost->host_lock);
已提交
802 803
	}

J
James Smart 已提交
804
	vport->port_state = LPFC_VPORT_READY;
已提交
805 806 807

out:
	/* Device Discovery completes */
808 809
	lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
			 "0225 Device Discovery completes\n");
J
James Smart 已提交
810
	mempool_free(pmb, phba->mbox_mem_pool);
已提交
811

J
James Smart 已提交
812 813 814
	spin_lock_irq(shost->host_lock);
	vport->fc_flag &= ~(FC_ABORT_DISCOVERY | FC_ESTABLISH_LINK);
	spin_unlock_irq(shost->host_lock);
已提交
815 816 817

	del_timer_sync(&phba->fc_estabtmo);

J
James Smart 已提交
818
	lpfc_can_disctmo(vport);
已提交
819 820

	/* turn on Link Attention interrupts */
J
James Smart 已提交
821 822

	spin_lock_irq(&phba->hbalock);
已提交
823 824 825 826 827
	psli->sli_flag |= LPFC_PROCESS_LA;
	control = readl(phba->HCregaddr);
	control |= HC_LAINT_ENA;
	writel(control, phba->HCregaddr);
	readl(phba->HCregaddr); /* flush */
J
James Smart 已提交
828
	spin_unlock_irq(&phba->hbalock);
已提交
829 830 831 832

	return;
}

J
James Smart 已提交
833

已提交
834
static void
835
lpfc_mbx_cmpl_local_config_link(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
已提交
836
{
J
James Smart 已提交
837
	struct lpfc_vport *vport = pmb->vport;
已提交
838

839
	if (pmb->mb.mbxStatus)
已提交
840 841
		goto out;

842 843 844
	mempool_free(pmb, phba->mbox_mem_pool);

	if (phba->fc_topology == TOPOLOGY_LOOP &&
J
James Smart 已提交
845 846
	    vport->fc_flag & FC_PUBLIC_LOOP &&
	    !(vport->fc_flag & FC_LBIT)) {
847
			/* Need to wait for FAN - use discovery timer
J
James Smart 已提交
848
			 * for timeout.  port_state is identically
849 850
			 * LPFC_LOCAL_CFG_LINK while waiting for FAN
			 */
J
James Smart 已提交
851
			lpfc_set_disctmo(vport);
852
			return;
853
	}
已提交
854

J
James Smart 已提交
855
	/* Start discovery by sending a FLOGI. port_state is identically
856 857
	 * LPFC_FLOGI while waiting for FLOGI cmpl
	 */
858 859 860
	if (vport->port_state != LPFC_FLOGI) {
		lpfc_initial_flogi(vport);
	}
861
	return;
已提交
862 863

out:
864 865 866 867
	lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX,
			 "0306 CONFIG_LINK mbxStatus error x%x "
			 "HBA state x%x\n",
			 pmb->mb.mbxStatus, vport->port_state);
868
	mempool_free(pmb, phba->mbox_mem_pool);
869

870
	lpfc_linkdown(phba);
871

872 873 874
	lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY,
			 "0200 CONFIG_LINK bad hba state x%x\n",
			 vport->port_state);
已提交
875

876
	lpfc_issue_clear_la(phba, vport);
已提交
877 878 879 880
	return;
}

static void
J
James Smart 已提交
881
lpfc_mbx_cmpl_read_sparam(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
已提交
882 883 884
{
	MAILBOX_t *mb = &pmb->mb;
	struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *) pmb->context1;
J
James Smart 已提交
885
	struct lpfc_vport  *vport = pmb->vport;
已提交
886 887 888 889 890


	/* Check for error */
	if (mb->mbxStatus) {
		/* READ_SPARAM mbox error <mbxStatus> state <hba_state> */
891 892 893 894
		lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX,
				 "0319 READ_SPARAM mbxStatus error x%x "
				 "hba state x%x>\n",
				 mb->mbxStatus, vport->port_state);
已提交
895 896 897 898
		lpfc_linkdown(phba);
		goto out;
	}

J
James Smart 已提交
899
	memcpy((uint8_t *) &vport->fc_sparam, (uint8_t *) mp->virt,
已提交
900
	       sizeof (struct serv_parm));
901
	if (phba->cfg_soft_wwnn)
J
James Smart 已提交
902 903
		u64_to_wwn(phba->cfg_soft_wwnn,
			   vport->fc_sparam.nodeName.u.wwn);
904
	if (phba->cfg_soft_wwpn)
J
James Smart 已提交
905 906
		u64_to_wwn(phba->cfg_soft_wwpn,
			   vport->fc_sparam.portName.u.wwn);
907 908 909 910 911 912 913 914 915
	memcpy(&vport->fc_nodename, &vport->fc_sparam.nodeName,
	       sizeof(vport->fc_nodename));
	memcpy(&vport->fc_portname, &vport->fc_sparam.portName,
	       sizeof(vport->fc_portname));
	if (vport->port_type == LPFC_PHYSICAL_PORT) {
		memcpy(&phba->wwnn, &vport->fc_nodename, sizeof(phba->wwnn));
		memcpy(&phba->wwpn, &vport->fc_portname, sizeof(phba->wwnn));
	}

已提交
916 917
	lpfc_mbuf_free(phba, mp->virt, mp->phys);
	kfree(mp);
J
James Smart 已提交
918
	mempool_free(pmb, phba->mbox_mem_pool);
已提交
919 920 921 922 923 924
	return;

out:
	pmb->context1 = NULL;
	lpfc_mbuf_free(phba, mp->virt, mp->phys);
	kfree(mp);
925 926
	lpfc_issue_clear_la(phba, vport);
	mempool_free(pmb, phba->mbox_mem_pool);
已提交
927 928 929 930
	return;
}

static void
931
lpfc_mbx_process_link_up(struct lpfc_hba *phba, READ_LA_VAR *la)
已提交
932
{
933
	struct lpfc_vport *vport = phba->pport;
已提交
934
	LPFC_MBOXQ_t *sparam_mbox, *cfglink_mbox;
J
James Smart 已提交
935
	int i;
936 937 938
	struct lpfc_dmabuf *mp;
	int rc;

已提交
939 940 941
	sparam_mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
	cfglink_mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);

942
	spin_lock_irq(&phba->hbalock);
943
	switch (la->UlnkSpeed) {
944 945 946 947 948 949 950 951 952 953 954 955 956 957 958
	case LA_1GHZ_LINK:
		phba->fc_linkspeed = LA_1GHZ_LINK;
		break;
	case LA_2GHZ_LINK:
		phba->fc_linkspeed = LA_2GHZ_LINK;
		break;
	case LA_4GHZ_LINK:
		phba->fc_linkspeed = LA_4GHZ_LINK;
		break;
	case LA_8GHZ_LINK:
		phba->fc_linkspeed = LA_8GHZ_LINK;
		break;
	default:
		phba->fc_linkspeed = LA_UNKNW_LINK;
		break;
已提交
959 960 961
	}

	phba->fc_topology = la->topology;
962
	phba->link_flag &= ~LS_NPIV_FAB_SUPPORTED;
已提交
963 964

	if (phba->fc_topology == TOPOLOGY_LOOP) {
965
		phba->sli3_options &= ~LPFC_SLI3_NPIV_ENABLED;
已提交
966

967
				/* Get Loop Map information */
已提交
968
		if (la->il)
J
James Smart 已提交
969
			vport->fc_flag |= FC_LBIT;
已提交
970

J
James Smart 已提交
971
		vport->fc_myDID = la->granted_AL_PA;
已提交
972 973 974 975 976
		i = la->un.lilpBde64.tus.f.bdeSize;

		if (i == 0) {
			phba->alpa_map[0] = 0;
		} else {
977
			if (vport->cfg_log_verbose & LOG_LINK_EVENT) {
已提交
978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000
				int numalpa, j, k;
				union {
					uint8_t pamap[16];
					struct {
						uint32_t wd1;
						uint32_t wd2;
						uint32_t wd3;
						uint32_t wd4;
					} pa;
				} un;
				numalpa = phba->alpa_map[0];
				j = 0;
				while (j < numalpa) {
					memset(un.pamap, 0, 16);
					for (k = 1; j < numalpa; k++) {
						un.pamap[k - 1] =
							phba->alpa_map[j + 1];
						j++;
						if (k == 16)
							break;
					}
					/* Link Up Event ALPA map */
					lpfc_printf_log(phba,
1001 1002
							KERN_WARNING,
							LOG_LINK_EVENT,
1003
							"1304 Link Up Event "
1004 1005 1006 1007
							"ALPA map Data: x%x "
							"x%x x%x x%x\n",
							un.pa.wd1, un.pa.wd2,
							un.pa.wd3, un.pa.wd4);
已提交
1008 1009 1010 1011
				}
			}
		}
	} else {
1012
		if (!(phba->sli3_options & LPFC_SLI3_NPIV_ENABLED)) {
1013
			if (phba->max_vpi && phba->cfg_enable_npiv &&
1014 1015 1016
			   (phba->sli_rev == 3))
				phba->sli3_options |= LPFC_SLI3_NPIV_ENABLED;
		}
J
James Smart 已提交
1017 1018
		vport->fc_myDID = phba->fc_pref_DID;
		vport->fc_flag |= FC_LBIT;
已提交
1019
	}
1020
	spin_unlock_irq(&phba->hbalock);
已提交
1021 1022 1023

	lpfc_linkup(phba);
	if (sparam_mbox) {
1024
		lpfc_read_sparam(phba, sparam_mbox, 0);
J
James Smart 已提交
1025
		sparam_mbox->vport = vport;
已提交
1026
		sparam_mbox->mbox_cmpl = lpfc_mbx_cmpl_read_sparam;
1027
		rc = lpfc_sli_issue_mbox(phba, sparam_mbox, MBX_NOWAIT);
1028 1029 1030 1031 1032 1033 1034
		if (rc == MBX_NOT_FINISHED) {
			mp = (struct lpfc_dmabuf *) sparam_mbox->context1;
			lpfc_mbuf_free(phba, mp->virt, mp->phys);
			kfree(mp);
			mempool_free(sparam_mbox, phba->mbox_mem_pool);
			if (cfglink_mbox)
				mempool_free(cfglink_mbox, phba->mbox_mem_pool);
1035
			goto out;
1036
		}
已提交
1037 1038 1039
	}

	if (cfglink_mbox) {
J
James Smart 已提交
1040
		vport->port_state = LPFC_LOCAL_CFG_LINK;
已提交
1041
		lpfc_config_link(phba, cfglink_mbox);
J
James Smart 已提交
1042
		cfglink_mbox->vport = vport;
1043
		cfglink_mbox->mbox_cmpl = lpfc_mbx_cmpl_local_config_link;
1044
		rc = lpfc_sli_issue_mbox(phba, cfglink_mbox, MBX_NOWAIT);
1045 1046 1047
		if (rc != MBX_NOT_FINISHED)
			return;
		mempool_free(cfglink_mbox, phba->mbox_mem_pool);
已提交
1048
	}
1049 1050
out:
	lpfc_vport_set_state(vport, FC_VPORT_FAILED);
1051 1052 1053
	lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX,
			 "0263 Discovery Mailbox error: state: 0x%x : %p %p\n",
			 vport->port_state, sparam_mbox, cfglink_mbox);
1054 1055
	lpfc_issue_clear_la(phba, vport);
	return;
已提交
1056 1057 1058
}

static void
J
James Smart 已提交
1059 1060
lpfc_mbx_issue_link_down(struct lpfc_hba *phba)
{
已提交
1061 1062 1063 1064 1065 1066
	uint32_t control;
	struct lpfc_sli *psli = &phba->sli;

	lpfc_linkdown(phba);

	/* turn on Link Attention interrupts - no CLEAR_LA needed */
J
James Smart 已提交
1067
	spin_lock_irq(&phba->hbalock);
已提交
1068 1069 1070 1071 1072
	psli->sli_flag |= LPFC_PROCESS_LA;
	control = readl(phba->HCregaddr);
	control |= HC_LAINT_ENA;
	writel(control, phba->HCregaddr);
	readl(phba->HCregaddr); /* flush */
J
James Smart 已提交
1073
	spin_unlock_irq(&phba->hbalock);
已提交
1074 1075 1076 1077 1078 1079 1080 1081 1082
}

/*
 * This routine handles processing a READ_LA mailbox
 * command upon completion. It is setup in the LPFC_MBOXQ
 * as the completion routine when the command is
 * handed off to the SLI layer.
 */
void
J
James Smart 已提交
1083
lpfc_mbx_cmpl_read_la(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
已提交
1084
{
J
James Smart 已提交
1085 1086
	struct lpfc_vport *vport = pmb->vport;
	struct Scsi_Host  *shost = lpfc_shost_from_vport(vport);
已提交
1087 1088 1089 1090 1091 1092
	READ_LA_VAR *la;
	MAILBOX_t *mb = &pmb->mb;
	struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *) (pmb->context1);

	/* Check for error */
	if (mb->mbxStatus) {
1093
		lpfc_printf_log(phba, KERN_INFO, LOG_LINK_EVENT,
1094 1095
				"1307 READ_LA mbox error x%x state x%x\n",
				mb->mbxStatus, vport->port_state);
已提交
1096
		lpfc_mbx_issue_link_down(phba);
J
James Smart 已提交
1097
		phba->link_state = LPFC_HBA_ERROR;
已提交
1098 1099 1100 1101 1102 1103 1104
		goto lpfc_mbx_cmpl_read_la_free_mbuf;
	}

	la = (READ_LA_VAR *) & pmb->mb.un.varReadLA;

	memcpy(&phba->alpa_map[0], mp->virt, 128);

J
James Smart 已提交
1105
	spin_lock_irq(shost->host_lock);
1106
	if (la->pb)
J
James Smart 已提交
1107
		vport->fc_flag |= FC_BYPASSED_MODE;
1108
	else
J
James Smart 已提交
1109 1110
		vport->fc_flag &= ~FC_BYPASSED_MODE;
	spin_unlock_irq(shost->host_lock);
1111

已提交
1112
	if (((phba->fc_eventTag + 1) < la->eventTag) ||
1113
	    (phba->fc_eventTag == la->eventTag)) {
已提交
1114
		phba->fc_stat.LinkMultiEvent++;
J
James Smart 已提交
1115
		if (la->attType == AT_LINK_UP)
已提交
1116 1117
			if (phba->fc_eventTag != 0)
				lpfc_linkdown(phba);
1118
	}
已提交
1119 1120 1121 1122 1123

	phba->fc_eventTag = la->eventTag;

	if (la->attType == AT_LINK_UP) {
		phba->fc_stat.LinkUp++;
J
James Smart 已提交
1124
		if (phba->link_flag & LS_LOOPBACK_MODE) {
1125
			lpfc_printf_log(phba, KERN_INFO, LOG_LINK_EVENT,
1126 1127 1128 1129 1130
					"1306 Link Up Event in loop back mode "
					"x%x received Data: x%x x%x x%x x%x\n",
					la->eventTag, phba->fc_eventTag,
					la->granted_AL_PA, la->UlnkSpeed,
					phba->alpa_map[0]);
1131 1132
		} else {
			lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT,
1133 1134 1135 1136 1137
					"1303 Link Up Event x%x received "
					"Data: x%x x%x x%x x%x\n",
					la->eventTag, phba->fc_eventTag,
					la->granted_AL_PA, la->UlnkSpeed,
					phba->alpa_map[0]);
1138
		}
1139
		lpfc_mbx_process_link_up(phba, la);
已提交
1140 1141 1142
	} else {
		phba->fc_stat.LinkDown++;
		lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT,
1143
				"1305 Link Down Event x%x received "
已提交
1144
				"Data: x%x x%x x%x\n",
1145
				la->eventTag, phba->fc_eventTag,
J
James Smart 已提交
1146
				phba->pport->port_state, vport->fc_flag);
已提交
1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163
		lpfc_mbx_issue_link_down(phba);
	}

lpfc_mbx_cmpl_read_la_free_mbuf:
	lpfc_mbuf_free(phba, mp->virt, mp->phys);
	kfree(mp);
	mempool_free(pmb, phba->mbox_mem_pool);
	return;
}

/*
 * This routine handles processing a REG_LOGIN mailbox
 * command upon completion. It is setup in the LPFC_MBOXQ
 * as the completion routine when the command is
 * handed off to the SLI layer.
 */
void
J
James Smart 已提交
1164
lpfc_mbx_cmpl_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
已提交
1165
{
J
James Smart 已提交
1166
	struct lpfc_vport  *vport = pmb->vport;
1167
	struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *) (pmb->context1);
J
James Smart 已提交
1168
	struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) pmb->context2;
已提交
1169 1170 1171 1172

	pmb->context1 = NULL;

	/* Good status, call state machine */
J
James Smart 已提交
1173
	lpfc_disc_state_machine(vport, ndlp, pmb, NLP_EVT_CMPL_REG_LOGIN);
已提交
1174 1175
	lpfc_mbuf_free(phba, mp->virt, mp->phys);
	kfree(mp);
J
James Smart 已提交
1176
	mempool_free(pmb, phba->mbox_mem_pool);
1177
	lpfc_nlp_put(ndlp);
已提交
1178 1179 1180 1181

	return;
}

1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192
static void
lpfc_mbx_cmpl_unreg_vpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
{
	MAILBOX_t *mb = &pmb->mb;
	struct lpfc_vport *vport = pmb->vport;
	struct Scsi_Host  *shost = lpfc_shost_from_vport(vport);

	switch (mb->mbxStatus) {
	case 0x0011:
	case 0x0020:
	case 0x9700:
1193 1194 1195
		lpfc_printf_vlog(vport, KERN_INFO, LOG_NODE,
				 "0911 cmpl_unreg_vpi, mb status = 0x%x\n",
				 mb->mbxStatus);
1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221
		break;
	}
	vport->unreg_vpi_cmpl = VPORT_OK;
	mempool_free(pmb, phba->mbox_mem_pool);
	/*
	 * This shost reference might have been taken at the beginning of
	 * lpfc_vport_delete()
	 */
	if (vport->load_flag & FC_UNLOADING)
		scsi_host_put(shost);
}

void
lpfc_mbx_unreg_vpi(struct lpfc_vport *vport)
{
	struct lpfc_hba  *phba = vport->phba;
	LPFC_MBOXQ_t *mbox;
	int rc;

	mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
	if (!mbox)
		return;

	lpfc_unreg_vpi(phba, vport->vpi, mbox);
	mbox->vport = vport;
	mbox->mbox_cmpl = lpfc_mbx_cmpl_unreg_vpi;
1222
	rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT);
1223
	if (rc == MBX_NOT_FINISHED) {
1224 1225
		lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX | LOG_VPORT,
				 "1800 Could not issue unreg_vpi\n");
1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241
		mempool_free(mbox, phba->mbox_mem_pool);
		vport->unreg_vpi_cmpl = VPORT_ERROR;
	}
}

static void
lpfc_mbx_cmpl_reg_vpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
{
	struct lpfc_vport *vport = pmb->vport;
	struct Scsi_Host  *shost = lpfc_shost_from_vport(vport);
	MAILBOX_t *mb = &pmb->mb;

	switch (mb->mbxStatus) {
	case 0x0011:
	case 0x9601:
	case 0x9602:
1242 1243 1244
		lpfc_printf_vlog(vport, KERN_INFO, LOG_NODE,
				 "0912 cmpl_reg_vpi, mb status = 0x%x\n",
				 mb->mbxStatus);
1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270
		lpfc_vport_set_state(vport, FC_VPORT_FAILED);
		spin_lock_irq(shost->host_lock);
		vport->fc_flag &= ~(FC_FABRIC | FC_PUBLIC_LOOP);
		spin_unlock_irq(shost->host_lock);
		vport->fc_myDID = 0;
		goto out;
	}

	vport->num_disc_nodes = 0;
	/* go thru NPR list and issue ELS PLOGIs */
	if (vport->fc_npr_cnt)
		lpfc_els_disc_plogi(vport);

	if (!vport->num_disc_nodes) {
		spin_lock_irq(shost->host_lock);
		vport->fc_flag &= ~FC_NDISC_ACTIVE;
		spin_unlock_irq(shost->host_lock);
		lpfc_can_disctmo(vport);
	}
	vport->port_state = LPFC_VPORT_READY;

out:
	mempool_free(pmb, phba->mbox_mem_pool);
	return;
}

已提交
1271 1272 1273 1274 1275 1276 1277
/*
 * This routine handles processing a Fabric REG_LOGIN mailbox
 * command upon completion. It is setup in the LPFC_MBOXQ
 * as the completion routine when the command is
 * handed off to the SLI layer.
 */
void
J
James Smart 已提交
1278
lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
已提交
1279
{
1280
	struct lpfc_vport *vport = pmb->vport;
J
James Smart 已提交
1281 1282
	MAILBOX_t *mb = &pmb->mb;
	struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *) (pmb->context1);
1283
	struct lpfc_nodelist *ndlp;
1284 1285
	struct lpfc_vport **vports;
	int i;
已提交
1286

1287
	ndlp = (struct lpfc_nodelist *) pmb->context2;
1288 1289
	pmb->context1 = NULL;
	pmb->context2 = NULL;
已提交
1290 1291 1292
	if (mb->mbxStatus) {
		lpfc_mbuf_free(phba, mp->virt, mp->phys);
		kfree(mp);
1293 1294
		mempool_free(pmb, phba->mbox_mem_pool);
		lpfc_nlp_put(ndlp);
已提交
1295

1296 1297 1298 1299 1300 1301 1302 1303 1304 1305
		if (phba->fc_topology == TOPOLOGY_LOOP) {
			/* FLOGI failed, use loop map to make discovery list */
			lpfc_disc_list_loopmap(vport);

			/* Start discovery */
			lpfc_disc_start(vport);
			return;
		}

		lpfc_vport_set_state(vport, FC_VPORT_FAILED);
1306 1307 1308
		lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX,
				 "0258 Register Fabric login error: 0x%x\n",
				 mb->mbxStatus);
已提交
1309 1310 1311 1312 1313
		return;
	}

	ndlp->nlp_rpi = mb->un.varWords[0];
	ndlp->nlp_type |= NLP_FABRIC;
J
James Smart 已提交
1314
	lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE);
已提交
1315

1316 1317
	lpfc_nlp_put(ndlp);	/* Drop the reference from the mbox */

J
James Smart 已提交
1318
	if (vport->port_state == LPFC_FABRIC_CFG_LINK) {
1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331
		vports = lpfc_create_vport_work_array(phba);
		if (vports != NULL)
			for(i = 0;
			    i < LPFC_MAX_VPORTS && vports[i] != NULL;
			    i++) {
				if (vports[i]->port_type == LPFC_PHYSICAL_PORT)
					continue;
				if (phba->link_flag & LS_NPIV_FAB_SUPPORTED)
					lpfc_initial_fdisc(vports[i]);
				else if (phba->sli3_options &
						LPFC_SLI3_NPIV_ENABLED) {
					lpfc_vport_set_state(vports[i],
						FC_VPORT_NO_FABRIC_SUPP);
1332 1333 1334 1335
					lpfc_printf_vlog(vport, KERN_ERR,
							 LOG_ELS,
							"0259 No NPIV "
							"Fabric support\n");
1336
				}
已提交
1337
			}
1338
		lpfc_destroy_vport_work_array(vports);
1339
		lpfc_do_scr_ns_plogi(phba, vport);
已提交
1340 1341 1342 1343
	}

	lpfc_mbuf_free(phba, mp->virt, mp->phys);
	kfree(mp);
1344
	mempool_free(pmb, phba->mbox_mem_pool);
已提交
1345 1346 1347 1348 1349 1350 1351 1352 1353 1354
	return;
}

/*
 * This routine handles processing a NameServer REG_LOGIN mailbox
 * command upon completion. It is setup in the LPFC_MBOXQ
 * as the completion routine when the command is
 * handed off to the SLI layer.
 */
void
J
James Smart 已提交
1355
lpfc_mbx_cmpl_ns_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
已提交
1356
{
J
James Smart 已提交
1357 1358 1359 1360
	MAILBOX_t *mb = &pmb->mb;
	struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *) (pmb->context1);
	struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) pmb->context2;
	struct lpfc_vport *vport = pmb->vport;
已提交
1361 1362

	if (mb->mbxStatus) {
1363
out:
1364
		lpfc_nlp_put(ndlp);
已提交
1365 1366
		lpfc_mbuf_free(phba, mp->virt, mp->phys);
		kfree(mp);
1367
		mempool_free(pmb, phba->mbox_mem_pool);
1368 1369 1370

		/* If no other thread is using the ndlp, free it */
		lpfc_nlp_not_used(ndlp);
已提交
1371

1372 1373 1374 1375 1376 1377
		if (phba->fc_topology == TOPOLOGY_LOOP) {
			/*
			 * RegLogin failed, use loop map to make discovery
			 * list
			 */
			lpfc_disc_list_loopmap(vport);
已提交
1378

1379 1380 1381 1382 1383
			/* Start discovery */
			lpfc_disc_start(vport);
			return;
		}
		lpfc_vport_set_state(vport, FC_VPORT_FAILED);
1384 1385 1386
		lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
				 "0260 Register NameServer error: 0x%x\n",
				 mb->mbxStatus);
已提交
1387 1388 1389 1390 1391 1392 1393
		return;
	}

	pmb->context1 = NULL;

	ndlp->nlp_rpi = mb->un.varWords[0];
	ndlp->nlp_type |= NLP_FABRIC;
J
James Smart 已提交
1394
	lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE);
已提交
1395

J
James Smart 已提交
1396 1397
	if (vport->port_state < LPFC_VPORT_READY) {
		/* Link up discovery requires Fabric registration. */
1398 1399 1400 1401 1402 1403 1404 1405
		lpfc_ns_cmd(vport, SLI_CTNS_RFF_ID, 0, 0); /* Do this first! */
		lpfc_ns_cmd(vport, SLI_CTNS_RNN_ID, 0, 0);
		lpfc_ns_cmd(vport, SLI_CTNS_RSNN_NN, 0, 0);
		lpfc_ns_cmd(vport, SLI_CTNS_RSPN_ID, 0, 0);
		lpfc_ns_cmd(vport, SLI_CTNS_RFT_ID, 0, 0);

		/* Issue SCR just before NameServer GID_FT Query */
		lpfc_issue_els_scr(vport, SCR_DID, 0);
已提交
1406 1407
	}

J
James Smart 已提交
1408
	vport->fc_ns_retry = 0;
已提交
1409
	/* Good status, issue CT Request to NameServer */
1410
	if (lpfc_ns_cmd(vport, SLI_CTNS_GID_FT, 0, 0)) {
已提交
1411
		/* Cannot issue NameServer Query, so finish up discovery */
1412
		goto out;
已提交
1413 1414
	}

1415
	lpfc_nlp_put(ndlp);
已提交
1416 1417
	lpfc_mbuf_free(phba, mp->virt, mp->phys);
	kfree(mp);
J
James Smart 已提交
1418
	mempool_free(pmb, phba->mbox_mem_pool);
已提交
1419 1420 1421 1422 1423

	return;
}

static void
J
James Smart 已提交
1424
lpfc_register_remote_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
已提交
1425
{
J
James Smart 已提交
1426 1427
	struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
	struct fc_rport  *rport;
已提交
1428 1429
	struct lpfc_rport_data *rdata;
	struct fc_rport_identifiers rport_ids;
J
James Smart 已提交
1430
	struct lpfc_hba  *phba = vport->phba;
已提交
1431 1432

	/* Remote port has reappeared. Re-register w/ FC transport */
A
Andrew Morton 已提交
1433 1434
	rport_ids.node_name = wwn_to_u64(ndlp->nlp_nodename.u.wwn);
	rport_ids.port_name = wwn_to_u64(ndlp->nlp_portname.u.wwn);
已提交
1435 1436 1437
	rport_ids.port_id = ndlp->nlp_DID;
	rport_ids.roles = FC_RPORT_ROLE_UNKNOWN;

1438 1439 1440 1441 1442 1443 1444 1445
	/*
	 * We leave our node pointer in rport->dd_data when we unregister a
	 * FCP target port.  But fc_remote_port_add zeros the space to which
	 * rport->dd_data points.  So, if we're reusing a previously
	 * registered port, drop the reference that we took the last time we
	 * registered the port.
	 */
	if (ndlp->rport && ndlp->rport->dd_data &&
1446
	    ((struct lpfc_rport_data *) ndlp->rport->dd_data)->pnode == ndlp) {
1447 1448
		lpfc_nlp_put(ndlp);
	}
J
James Smart 已提交
1449 1450 1451 1452 1453

	lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_RPORT,
		"rport add:       did:x%x flg:x%x type x%x",
		ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_type);

J
James Smart 已提交
1454
	ndlp->rport = rport = fc_remote_port_add(shost, 0, &rport_ids);
1455
	if (!rport || !get_device(&rport->dev)) {
已提交
1456 1457 1458 1459 1460 1461 1462 1463 1464
		dev_printk(KERN_WARNING, &phba->pcidev->dev,
			   "Warning: fc_remote_port_add failed\n");
		return;
	}

	/* initialize static port data */
	rport->maxframe_size = ndlp->nlp_maxframe;
	rport->supported_classes = ndlp->nlp_class_sup;
	rdata = rport->dd_data;
1465
	rdata->pnode = lpfc_nlp_get(ndlp);
1466 1467 1468 1469 1470 1471 1472 1473 1474 1475

	if (ndlp->nlp_type & NLP_FCP_TARGET)
		rport_ids.roles |= FC_RPORT_ROLE_FCP_TARGET;
	if (ndlp->nlp_type & NLP_FCP_INITIATOR)
		rport_ids.roles |= FC_RPORT_ROLE_FCP_INITIATOR;


	if (rport_ids.roles !=  FC_RPORT_ROLE_UNKNOWN)
		fc_remote_port_rolechg(rport, rport_ids.roles);

1476
	if ((rport->scsi_target_id != -1) &&
1477
	    (rport->scsi_target_id < LPFC_MAX_TARGET)) {
1478 1479
		ndlp->nlp_sid = rport->scsi_target_id;
	}
1480 1481 1482 1483
	return;
}

static void
J
James Smart 已提交
1484
lpfc_unregister_remote_port(struct lpfc_nodelist *ndlp)
1485 1486
{
	struct fc_rport *rport = ndlp->rport;
1487

J
James Smart 已提交
1488 1489 1490 1491
	lpfc_debugfs_disc_trc(ndlp->vport, LPFC_DISC_TRC_RPORT,
		"rport delete:    did:x%x flg:x%x type x%x",
		ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_type);

1492
	fc_remote_port_delete(rport);
已提交
1493 1494 1495 1496

	return;
}

1497
static void
J
James Smart 已提交
1498
lpfc_nlp_counters(struct lpfc_vport *vport, int state, int count)
已提交
1499
{
J
James Smart 已提交
1500 1501 1502
	struct Scsi_Host *shost = lpfc_shost_from_vport(vport);

	spin_lock_irq(shost->host_lock);
1503 1504
	switch (state) {
	case NLP_STE_UNUSED_NODE:
J
James Smart 已提交
1505
		vport->fc_unused_cnt += count;
1506 1507
		break;
	case NLP_STE_PLOGI_ISSUE:
J
James Smart 已提交
1508
		vport->fc_plogi_cnt += count;
1509 1510
		break;
	case NLP_STE_ADISC_ISSUE:
J
James Smart 已提交
1511
		vport->fc_adisc_cnt += count;
已提交
1512
		break;
1513
	case NLP_STE_REG_LOGIN_ISSUE:
J
James Smart 已提交
1514
		vport->fc_reglogin_cnt += count;
1515 1516
		break;
	case NLP_STE_PRLI_ISSUE:
J
James Smart 已提交
1517
		vport->fc_prli_cnt += count;
1518 1519
		break;
	case NLP_STE_UNMAPPED_NODE:
J
James Smart 已提交
1520
		vport->fc_unmap_cnt += count;
1521 1522
		break;
	case NLP_STE_MAPPED_NODE:
J
James Smart 已提交
1523
		vport->fc_map_cnt += count;
1524 1525
		break;
	case NLP_STE_NPR_NODE:
J
James Smart 已提交
1526
		vport->fc_npr_cnt += count;
1527 1528
		break;
	}
J
James Smart 已提交
1529
	spin_unlock_irq(shost->host_lock);
1530
}
1531

1532
static void
J
James Smart 已提交
1533
lpfc_nlp_state_cleanup(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
1534 1535
		       int old_state, int new_state)
{
J
James Smart 已提交
1536 1537
	struct Scsi_Host *shost = lpfc_shost_from_vport(vport);

1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550
	if (new_state == NLP_STE_UNMAPPED_NODE) {
		ndlp->nlp_type &= ~(NLP_FCP_TARGET | NLP_FCP_INITIATOR);
		ndlp->nlp_flag &= ~NLP_NODEV_REMOVE;
		ndlp->nlp_type |= NLP_FC_NODE;
	}
	if (new_state == NLP_STE_MAPPED_NODE)
		ndlp->nlp_flag &= ~NLP_NODEV_REMOVE;
	if (new_state == NLP_STE_NPR_NODE)
		ndlp->nlp_flag &= ~NLP_RCV_PLOGI;

	/* Transport interface */
	if (ndlp->rport && (old_state == NLP_STE_MAPPED_NODE ||
			    old_state == NLP_STE_UNMAPPED_NODE)) {
J
James Smart 已提交
1551 1552
		vport->phba->nport_event_cnt++;
		lpfc_unregister_remote_port(ndlp);
1553
	}
已提交
1554

1555 1556
	if (new_state ==  NLP_STE_MAPPED_NODE ||
	    new_state == NLP_STE_UNMAPPED_NODE) {
J
James Smart 已提交
1557
		vport->phba->nport_event_cnt++;
J
James Smart 已提交
1558 1559 1560 1561 1562 1563
		/*
		 * Tell the fc transport about the port, if we haven't
		 * already. If we have, and it's a scsi entity, be
		 * sure to unblock any attached scsi devices
		 */
		lpfc_register_remote_port(vport, ndlp);
1564
	}
J
James Smart 已提交
1565 1566 1567 1568 1569 1570
	/*
	 * if we added to Mapped list, but the remote port
	 * registration failed or assigned a target id outside
	 * our presentable range - move the node to the
	 * Unmapped List
	 */
1571 1572 1573 1574
	if (new_state == NLP_STE_MAPPED_NODE &&
	    (!ndlp->rport ||
	     ndlp->rport->scsi_target_id == -1 ||
	     ndlp->rport->scsi_target_id >= LPFC_MAX_TARGET)) {
J
James Smart 已提交
1575
		spin_lock_irq(shost->host_lock);
1576
		ndlp->nlp_flag |= NLP_TGT_NO_SCSIID;
J
James Smart 已提交
1577 1578
		spin_unlock_irq(shost->host_lock);
		lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE);
已提交
1579
	}
1580 1581
}

1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595
static char *
lpfc_nlp_state_name(char *buffer, size_t size, int state)
{
	static char *states[] = {
		[NLP_STE_UNUSED_NODE] = "UNUSED",
		[NLP_STE_PLOGI_ISSUE] = "PLOGI",
		[NLP_STE_ADISC_ISSUE] = "ADISC",
		[NLP_STE_REG_LOGIN_ISSUE] = "REGLOGIN",
		[NLP_STE_PRLI_ISSUE] = "PRLI",
		[NLP_STE_UNMAPPED_NODE] = "UNMAPPED",
		[NLP_STE_MAPPED_NODE] = "MAPPED",
		[NLP_STE_NPR_NODE] = "NPR",
	};

J
James Smart 已提交
1596
	if (state < NLP_STE_MAX_STATE && states[state])
1597 1598 1599 1600 1601 1602
		strlcpy(buffer, states[state], size);
	else
		snprintf(buffer, size, "unknown (%d)", state);
	return buffer;
}

1603
void
J
James Smart 已提交
1604 1605
lpfc_nlp_set_state(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
		   int state)
1606
{
J
James Smart 已提交
1607
	struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
1608
	int  old_state = ndlp->nlp_state;
1609
	char name1[16], name2[16];
1610

1611 1612 1613 1614 1615
	lpfc_printf_vlog(vport, KERN_INFO, LOG_NODE,
			 "0904 NPort state transition x%06x, %s -> %s\n",
			 ndlp->nlp_DID,
			 lpfc_nlp_state_name(name1, sizeof(name1), old_state),
			 lpfc_nlp_state_name(name2, sizeof(name2), state));
J
James Smart 已提交
1616 1617 1618 1619 1620

	lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_NODE,
		"node statechg    did:x%x old:%d ste:%d",
		ndlp->nlp_DID, old_state, state);

1621 1622 1623
	if (old_state == NLP_STE_NPR_NODE &&
	    (ndlp->nlp_flag & NLP_DELAY_TMO) != 0 &&
	    state != NLP_STE_NPR_NODE)
J
James Smart 已提交
1624
		lpfc_cancel_retry_delay_tmo(vport, ndlp);
1625 1626 1627 1628 1629
	if (old_state == NLP_STE_UNMAPPED_NODE) {
		ndlp->nlp_flag &= ~NLP_TGT_NO_SCSIID;
		ndlp->nlp_type &= ~NLP_FC_NODE;
	}

1630
	if (list_empty(&ndlp->nlp_listp)) {
J
James Smart 已提交
1631 1632 1633
		spin_lock_irq(shost->host_lock);
		list_add_tail(&ndlp->nlp_listp, &vport->fc_nodes);
		spin_unlock_irq(shost->host_lock);
1634
	} else if (old_state)
J
James Smart 已提交
1635
		lpfc_nlp_counters(vport, old_state, -1);
1636 1637

	ndlp->nlp_state = state;
J
James Smart 已提交
1638 1639
	lpfc_nlp_counters(vport, state, 1);
	lpfc_nlp_state_cleanup(vport, ndlp, old_state, state);
1640 1641 1642
}

void
J
James Smart 已提交
1643
lpfc_dequeue_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
1644
{
J
James Smart 已提交
1645 1646
	struct Scsi_Host *shost = lpfc_shost_from_vport(vport);

1647
	if ((ndlp->nlp_flag & NLP_DELAY_TMO) != 0)
J
James Smart 已提交
1648
		lpfc_cancel_retry_delay_tmo(vport, ndlp);
1649
	if (ndlp->nlp_state && !list_empty(&ndlp->nlp_listp))
J
James Smart 已提交
1650 1651
		lpfc_nlp_counters(vport, ndlp->nlp_state, -1);
	spin_lock_irq(shost->host_lock);
1652
	list_del_init(&ndlp->nlp_listp);
J
James Smart 已提交
1653
	spin_unlock_irq(shost->host_lock);
J
James Smart 已提交
1654 1655
	lpfc_nlp_state_cleanup(vport, ndlp, ndlp->nlp_state,
			       NLP_STE_UNUSED_NODE);
1656 1657 1658
}

void
J
James Smart 已提交
1659
lpfc_drop_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
1660
{
1661 1662 1663 1664 1665 1666 1667 1668
	/*
	 * Use of lpfc_drop_node and UNUSED list. lpfc_drop_node should
	 * be used if we wish to issue the "last" lpfc_nlp_put() to remove
	 * the ndlp from the vport.  The ndlp resides on the UNUSED list
	 * until ALL other outstanding threads have completed. Thus, if a
	 * ndlp is on the UNUSED list already, we should never do another
	 * lpfc_drop_node() on it.
	 */
1669
	lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNUSED_NODE);
1670
	lpfc_nlp_put(ndlp);
1671
	return;
已提交
1672 1673 1674 1675 1676 1677
}

/*
 * Start / ReStart rescue timer for Discovery / RSCN handling
 */
void
J
James Smart 已提交
1678
lpfc_set_disctmo(struct lpfc_vport *vport)
已提交
1679
{
J
James Smart 已提交
1680 1681
	struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
	struct lpfc_hba  *phba = vport->phba;
已提交
1682 1683
	uint32_t tmo;

J
James Smart 已提交
1684
	if (vport->port_state == LPFC_LOCAL_CFG_LINK) {
1685 1686 1687 1688 1689 1690 1691 1692
		/* For FAN, timeout should be greater then edtov */
		tmo = (((phba->fc_edtov + 999) / 1000) + 1);
	} else {
		/* Normal discovery timeout should be > then ELS/CT timeout
		 * FC spec states we need 3 * ratov for CT requests
		 */
		tmo = ((phba->fc_ratov * 3) + 3);
	}
已提交
1693

J
James Smart 已提交
1694 1695 1696 1697 1698 1699 1700

	if (!timer_pending(&vport->fc_disctmo)) {
		lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
			"set disc timer:  tmo:x%x state:x%x flg:x%x",
			tmo, vport->port_state, vport->fc_flag);
	}

J
James Smart 已提交
1701 1702 1703 1704
	mod_timer(&vport->fc_disctmo, jiffies + HZ * tmo);
	spin_lock_irq(shost->host_lock);
	vport->fc_flag |= FC_DISC_TMO;
	spin_unlock_irq(shost->host_lock);
已提交
1705 1706

	/* Start Discovery Timer state <hba_state> */
1707 1708 1709 1710 1711 1712
	lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
			 "0247 Start Discovery Timer state x%x "
			 "Data: x%x x%lx x%x x%x\n",
			 vport->port_state, tmo,
			 (unsigned long)&vport->fc_disctmo, vport->fc_plogi_cnt,
			 vport->fc_adisc_cnt);
已提交
1713 1714 1715 1716 1717 1718 1719 1720

	return;
}

/*
 * Cancel rescue timer for Discovery / RSCN handling
 */
int
J
James Smart 已提交
1721
lpfc_can_disctmo(struct lpfc_vport *vport)
已提交
1722
{
J
James Smart 已提交
1723 1724 1725
	struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
	unsigned long iflags;

J
James Smart 已提交
1726 1727 1728 1729
	lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
		"can disc timer:  state:x%x rtry:x%x flg:x%x",
		vport->port_state, vport->fc_ns_retry, vport->fc_flag);

已提交
1730
	/* Turn off discovery timer if its running */
J
James Smart 已提交
1731 1732 1733 1734 1735 1736 1737 1738
	if (vport->fc_flag & FC_DISC_TMO) {
		spin_lock_irqsave(shost->host_lock, iflags);
		vport->fc_flag &= ~FC_DISC_TMO;
		spin_unlock_irqrestore(shost->host_lock, iflags);
		del_timer_sync(&vport->fc_disctmo);
		spin_lock_irqsave(&vport->work_port_lock, iflags);
		vport->work_port_events &= ~WORKER_DISC_TMO;
		spin_unlock_irqrestore(&vport->work_port_lock, iflags);
已提交
1739 1740 1741
	}

	/* Cancel Discovery Timer state <hba_state> */
1742 1743 1744 1745 1746
	lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
			 "0248 Cancel Discovery Timer state x%x "
			 "Data: x%x x%x x%x\n",
			 vport->port_state, vport->fc_flag,
			 vport->fc_plogi_cnt, vport->fc_adisc_cnt);
1747
	return 0;
已提交
1748 1749 1750 1751 1752 1753 1754
}

/*
 * Check specified ring for outstanding IOCB on the SLI queue
 * Return true if iocb matches the specified nport
 */
int
J
James Smart 已提交
1755 1756 1757 1758
lpfc_check_sli_ndlp(struct lpfc_hba *phba,
		    struct lpfc_sli_ring *pring,
		    struct lpfc_iocbq *iocb,
		    struct lpfc_nodelist *ndlp)
已提交
1759
{
J
James Smart 已提交
1760 1761
	struct lpfc_sli *psli = &phba->sli;
	IOCB_t *icmd = &iocb->iocb;
1762 1763 1764 1765 1766
	struct lpfc_vport    *vport = ndlp->vport;

	if (iocb->vport != vport)
		return 0;

已提交
1767 1768 1769 1770
	if (pring->ringno == LPFC_ELS_RING) {
		switch (icmd->ulpCommand) {
		case CMD_GEN_REQUEST64_CR:
			if (icmd->ulpContext == (volatile ushort)ndlp->nlp_rpi)
1771
				return 1;
已提交
1772
		case CMD_ELS_REQUEST64_CR:
1773 1774
			if (icmd->un.elsreq64.remoteID == ndlp->nlp_DID)
				return 1;
已提交
1775 1776
		case CMD_XMIT_ELS_RSP64_CX:
			if (iocb->context1 == (uint8_t *) ndlp)
1777
				return 1;
已提交
1778
		}
1779
	} else if (pring->ringno == psli->extra_ring) {
已提交
1780 1781 1782 1783

	} else if (pring->ringno == psli->fcp_ring) {
		/* Skip match check if waiting to relogin to FCP target */
		if ((ndlp->nlp_type & NLP_FCP_TARGET) &&
1784
		    (ndlp->nlp_flag & NLP_DELAY_TMO)) {
1785
			return 0;
已提交
1786 1787
		}
		if (icmd->ulpContext == (volatile ushort)ndlp->nlp_rpi) {
1788
			return 1;
已提交
1789 1790 1791 1792
		}
	} else if (pring->ringno == psli->next_ring) {

	}
1793
	return 0;
已提交
1794 1795 1796 1797 1798 1799 1800
}

/*
 * Free resources / clean up outstanding I/Os
 * associated with nlp_rpi in the LPFC_NODELIST entry.
 */
static int
J
James Smart 已提交
1801
lpfc_no_rpi(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp)
已提交
1802
{
1803
	LIST_HEAD(completions);
已提交
1804 1805 1806 1807 1808 1809
	struct lpfc_sli *psli;
	struct lpfc_sli_ring *pring;
	struct lpfc_iocbq *iocb, *next_iocb;
	IOCB_t *icmd;
	uint32_t rpi, i;

1810 1811
	lpfc_fabric_abort_nport(ndlp);

已提交
1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822
	/*
	 * Everything that matches on txcmplq will be returned
	 * by firmware with a no rpi error.
	 */
	psli = &phba->sli;
	rpi = ndlp->nlp_rpi;
	if (rpi) {
		/* Now process each ring */
		for (i = 0; i < psli->num_rings; i++) {
			pring = &psli->ring[i];

J
James Smart 已提交
1823
			spin_lock_irq(&phba->hbalock);
已提交
1824
			list_for_each_entry_safe(iocb, next_iocb, &pring->txq,
J
James Smart 已提交
1825
						 list) {
已提交
1826 1827 1828 1829
				/*
				 * Check to see if iocb matches the nport we are
				 * looking for
				 */
1830 1831
				if ((lpfc_check_sli_ndlp(phba, pring, iocb,
							 ndlp))) {
已提交
1832 1833
					/* It matches, so deque and call compl
					   with an error */
1834 1835
					list_move_tail(&iocb->list,
						       &completions);
已提交
1836 1837 1838
					pring->txq_cnt--;
				}
			}
J
James Smart 已提交
1839
			spin_unlock_irq(&phba->hbalock);
已提交
1840 1841
		}
	}
1842 1843 1844

	while (!list_empty(&completions)) {
		iocb = list_get_first(&completions, struct lpfc_iocbq, list);
1845
		list_del_init(&iocb->list);
1846

J
James Smart 已提交
1847 1848 1849
		if (!iocb->iocb_cmpl)
			lpfc_sli_release_iocbq(phba, iocb);
		else {
1850 1851 1852
			icmd = &iocb->iocb;
			icmd->ulpStatus = IOSTAT_LOCAL_REJECT;
			icmd->un.ulpWord[4] = IOERR_SLI_ABORTED;
J
James Smart 已提交
1853 1854
			(iocb->iocb_cmpl)(phba, iocb, iocb);
		}
1855 1856
	}

1857
	return 0;
已提交
1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869
}

/*
 * Free rpi associated with LPFC_NODELIST entry.
 * This routine is called from lpfc_freenode(), when we are removing
 * a LPFC_NODELIST entry. It is also called if the driver initiates a
 * LOGO that completes successfully, and we are waiting to PLOGI back
 * to the remote NPort. In addition, it is called after we receive
 * and unsolicated ELS cmd, send back a rsp, the rsp completes and
 * we are waiting to PLOGI back to the remote NPort.
 */
int
J
James Smart 已提交
1870
lpfc_unreg_rpi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
已提交
1871
{
J
James Smart 已提交
1872 1873
	struct lpfc_hba *phba = vport->phba;
	LPFC_MBOXQ_t    *mbox;
已提交
1874 1875 1876
	int rc;

	if (ndlp->nlp_rpi) {
J
James Smart 已提交
1877 1878
		mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
		if (mbox) {
1879
			lpfc_unreg_login(phba, vport->vpi, ndlp->nlp_rpi, mbox);
1880
			mbox->vport = vport;
1881
			mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
1882
			rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT);
已提交
1883
			if (rc == MBX_NOT_FINISHED)
J
James Smart 已提交
1884
				mempool_free(mbox, phba->mbox_mem_pool);
已提交
1885 1886 1887 1888 1889 1890 1891 1892
		}
		lpfc_no_rpi(phba, ndlp);
		ndlp->nlp_rpi = 0;
		return 1;
	}
	return 0;
}

1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904
void
lpfc_unreg_all_rpis(struct lpfc_vport *vport)
{
	struct lpfc_hba  *phba  = vport->phba;
	LPFC_MBOXQ_t     *mbox;
	int rc;

	mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
	if (mbox) {
		lpfc_unreg_login(phba, vport->vpi, 0xffff, mbox);
		mbox->vport = vport;
		mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
1905
		rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT);
1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923
		if (rc == MBX_NOT_FINISHED) {
			mempool_free(mbox, phba->mbox_mem_pool);
		}
	}
}

void
lpfc_unreg_default_rpis(struct lpfc_vport *vport)
{
	struct lpfc_hba  *phba  = vport->phba;
	LPFC_MBOXQ_t     *mbox;
	int rc;

	mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
	if (mbox) {
		lpfc_unreg_did(phba, vport->vpi, 0xffffffff, mbox);
		mbox->vport = vport;
		mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
1924
		rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT);
1925
		if (rc == MBX_NOT_FINISHED) {
1926 1927 1928
			lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX | LOG_VPORT,
					 "1815 Could not issue "
					 "unreg_did (default rpis)\n");
1929 1930 1931 1932 1933
			mempool_free(mbox, phba->mbox_mem_pool);
		}
	}
}

已提交
1934 1935 1936 1937 1938
/*
 * Free resources associated with LPFC_NODELIST entry
 * so it can be freed.
 */
static int
J
James Smart 已提交
1939
lpfc_cleanup_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
已提交
1940
{
J
James Smart 已提交
1941 1942 1943
	struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
	struct lpfc_hba  *phba = vport->phba;
	LPFC_MBOXQ_t *mb, *nextmb;
已提交
1944 1945 1946
	struct lpfc_dmabuf *mp;

	/* Cleanup node for NPort <nlp_DID> */
1947 1948 1949 1950 1951
	lpfc_printf_vlog(vport, KERN_INFO, LOG_NODE,
			 "0900 Cleanup node for NPort x%x "
			 "Data: x%x x%x x%x\n",
			 ndlp->nlp_DID, ndlp->nlp_flag,
			 ndlp->nlp_state, ndlp->nlp_rpi);
J
James Smart 已提交
1952
	lpfc_dequeue_node(vport, ndlp);
已提交
1953 1954 1955 1956 1957 1958 1959 1960 1961

	/* cleanup any ndlp on mbox q waiting for reglogin cmpl */
	if ((mb = phba->sli.mbox_active)) {
		if ((mb->mb.mbxCommand == MBX_REG_LOGIN64) &&
		   (ndlp == (struct lpfc_nodelist *) mb->context2)) {
			mb->context2 = NULL;
			mb->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
		}
	}
J
James Smart 已提交
1962

J
James Smart 已提交
1963
	spin_lock_irq(&phba->hbalock);
已提交
1964 1965
	list_for_each_entry_safe(mb, nextmb, &phba->sli.mboxq, list) {
		if ((mb->mb.mbxCommand == MBX_REG_LOGIN64) &&
1966
		    (ndlp == (struct lpfc_nodelist *) mb->context2)) {
已提交
1967 1968
			mp = (struct lpfc_dmabuf *) (mb->context1);
			if (mp) {
J
James Smart 已提交
1969
				__lpfc_mbuf_free(phba, mp->virt, mp->phys);
已提交
1970 1971 1972 1973
				kfree(mp);
			}
			list_del(&mb->list);
			mempool_free(mb, phba->mbox_mem_pool);
1974
			lpfc_nlp_put(ndlp);
已提交
1975 1976
		}
	}
J
James Smart 已提交
1977
	spin_unlock_irq(&phba->hbalock);
已提交
1978

1979
	lpfc_els_abort(phba,ndlp);
J
James Smart 已提交
1980
	spin_lock_irq(shost->host_lock);
1981
	ndlp->nlp_flag &= ~NLP_DELAY_TMO;
J
James Smart 已提交
1982
	spin_unlock_irq(shost->host_lock);
已提交
1983

1984
	ndlp->nlp_last_elscmd = 0;
已提交
1985 1986 1987 1988
	del_timer_sync(&ndlp->nlp_delayfunc);

	if (!list_empty(&ndlp->els_retry_evt.evt_listp))
		list_del_init(&ndlp->els_retry_evt.evt_listp);
1989 1990
	if (!list_empty(&ndlp->dev_loss_evt.evt_listp))
		list_del_init(&ndlp->dev_loss_evt.evt_listp);
已提交
1991

J
James Smart 已提交
1992
	lpfc_unreg_rpi(vport, ndlp);
已提交
1993

1994
	return 0;
已提交
1995 1996 1997 1998 1999 2000 2001
}

/*
 * Check to see if we can free the nlp back to the freelist.
 * If we are in the middle of using the nlp in the discovery state
 * machine, defer the free till we reach the end of the state machine.
 */
2002
static void
J
James Smart 已提交
2003
lpfc_nlp_remove(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
已提交
2004
{
2005
	struct lpfc_hba  *phba = vport->phba;
2006
	struct lpfc_rport_data *rdata;
2007 2008
	LPFC_MBOXQ_t *mbox;
	int rc;
已提交
2009 2010

	if (ndlp->nlp_flag & NLP_DELAY_TMO) {
J
James Smart 已提交
2011
		lpfc_cancel_retry_delay_tmo(vport, ndlp);
已提交
2012 2013
	}

2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037
	if (ndlp->nlp_flag & NLP_DEFER_RM && !ndlp->nlp_rpi) {
		/* For this case we need to cleanup the default rpi
		 * allocated by the firmware.
		 */
		if ((mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL))
			!= NULL) {
			rc = lpfc_reg_login(phba, vport->vpi, ndlp->nlp_DID,
			    (uint8_t *) &vport->fc_sparam, mbox, 0);
			if (rc) {
				mempool_free(mbox, phba->mbox_mem_pool);
			}
			else {
				mbox->mbox_flag |= LPFC_MBX_IMED_UNREG;
				mbox->mbox_cmpl = lpfc_mbx_cmpl_dflt_rpi;
				mbox->vport = vport;
				mbox->context2 = 0;
				rc =lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT);
				if (rc == MBX_NOT_FINISHED) {
					mempool_free(mbox, phba->mbox_mem_pool);
				}
			}
		}
	}

J
James Smart 已提交
2038
	lpfc_cleanup_node(vport, ndlp);
2039

J
James Smart 已提交
2040
	/*
2041 2042 2043
	 * We can get here with a non-NULL ndlp->rport because when we
	 * unregister a rport we don't break the rport/node linkage.  So if we
	 * do, make sure we don't leaving any dangling pointers behind.
J
James Smart 已提交
2044
	 */
2045
	if (ndlp->rport) {
2046 2047 2048
		rdata = ndlp->rport->dd_data;
		rdata->pnode = NULL;
		ndlp->rport = NULL;
已提交
2049 2050 2051 2052
	}
}

static int
J
James Smart 已提交
2053 2054
lpfc_matchdid(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
	      uint32_t did)
已提交
2055
{
J
James Smart 已提交
2056
	D_ID mydid, ndlpdid, matchdid;
已提交
2057 2058

	if (did == Bcast_DID)
2059
		return 0;
已提交
2060 2061

	if (ndlp->nlp_DID == 0) {
2062
		return 0;
已提交
2063 2064 2065 2066
	}

	/* First check for Direct match */
	if (ndlp->nlp_DID == did)
2067
		return 1;
已提交
2068 2069

	/* Next check for area/domain identically equals 0 match */
J
James Smart 已提交
2070
	mydid.un.word = vport->fc_myDID;
已提交
2071
	if ((mydid.un.b.domain == 0) && (mydid.un.b.area == 0)) {
2072
		return 0;
已提交
2073 2074 2075 2076 2077 2078 2079 2080 2081 2082
	}

	matchdid.un.word = did;
	ndlpdid.un.word = ndlp->nlp_DID;
	if (matchdid.un.b.id == ndlpdid.un.b.id) {
		if ((mydid.un.b.domain == matchdid.un.b.domain) &&
		    (mydid.un.b.area == matchdid.un.b.area)) {
			if ((ndlpdid.un.b.domain == 0) &&
			    (ndlpdid.un.b.area == 0)) {
				if (ndlpdid.un.b.id)
2083
					return 1;
已提交
2084
			}
2085
			return 0;
已提交
2086 2087 2088 2089 2090 2091 2092 2093
		}

		matchdid.un.word = ndlp->nlp_DID;
		if ((mydid.un.b.domain == ndlpdid.un.b.domain) &&
		    (mydid.un.b.area == ndlpdid.un.b.area)) {
			if ((matchdid.un.b.domain == 0) &&
			    (matchdid.un.b.area == 0)) {
				if (matchdid.un.b.id)
2094
					return 1;
已提交
2095 2096 2097
			}
		}
	}
2098
	return 0;
已提交
2099 2100
}

2101
/* Search for a nodelist entry */
J
James Smart 已提交
2102 2103
static struct lpfc_nodelist *
__lpfc_findnode_did(struct lpfc_vport *vport, uint32_t did)
已提交
2104
{
J
James Smart 已提交
2105
	struct lpfc_nodelist *ndlp;
已提交
2106 2107
	uint32_t data1;

J
James Smart 已提交
2108 2109
	list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) {
		if (lpfc_matchdid(vport, ndlp, did)) {
2110 2111 2112 2113
			data1 = (((uint32_t) ndlp->nlp_state << 24) |
				 ((uint32_t) ndlp->nlp_xri << 16) |
				 ((uint32_t) ndlp->nlp_type << 8) |
				 ((uint32_t) ndlp->nlp_rpi & 0xff));
2114 2115 2116 2117 2118
			lpfc_printf_vlog(vport, KERN_INFO, LOG_NODE,
					 "0929 FIND node DID "
					 "Data: x%p x%x x%x x%x\n",
					 ndlp, ndlp->nlp_DID,
					 ndlp->nlp_flag, data1);
2119
			return ndlp;
已提交
2120 2121
		}
	}
2122

已提交
2123
	/* FIND node did <did> NOT FOUND */
2124 2125
	lpfc_printf_vlog(vport, KERN_INFO, LOG_NODE,
			 "0932 FIND node did x%x NOT FOUND.\n", did);
已提交
2126 2127 2128 2129
	return NULL;
}

struct lpfc_nodelist *
J
James Smart 已提交
2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142
lpfc_findnode_did(struct lpfc_vport *vport, uint32_t did)
{
	struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
	struct lpfc_nodelist *ndlp;

	spin_lock_irq(shost->host_lock);
	ndlp = __lpfc_findnode_did(vport, did);
	spin_unlock_irq(shost->host_lock);
	return ndlp;
}

struct lpfc_nodelist *
lpfc_setup_disc_node(struct lpfc_vport *vport, uint32_t did)
已提交
2143
{
J
James Smart 已提交
2144
	struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
已提交
2145 2146
	struct lpfc_nodelist *ndlp;

J
James Smart 已提交
2147
	ndlp = lpfc_findnode_did(vport, did);
2148
	if (!ndlp) {
J
James Smart 已提交
2149 2150
		if ((vport->fc_flag & FC_RSCN_MODE) != 0 &&
		    lpfc_rscn_payload_check(vport, did) == 0)
已提交
2151 2152
			return NULL;
		ndlp = (struct lpfc_nodelist *)
J
James Smart 已提交
2153
		     mempool_alloc(vport->phba->nlp_mem_pool, GFP_KERNEL);
已提交
2154 2155
		if (!ndlp)
			return NULL;
J
James Smart 已提交
2156 2157 2158
		lpfc_nlp_init(vport, ndlp, did);
		lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
		spin_lock_irq(shost->host_lock);
已提交
2159
		ndlp->nlp_flag |= NLP_NPR_2B_DISC;
J
James Smart 已提交
2160
		spin_unlock_irq(shost->host_lock);
已提交
2161 2162
		return ndlp;
	}
J
James Smart 已提交
2163 2164
	if (vport->fc_flag & FC_RSCN_MODE) {
		if (lpfc_rscn_payload_check(vport, did)) {
2165 2166 2167 2168 2169 2170
			/* If we've already recieved a PLOGI from this NPort
			 * we don't need to try to discover it again.
			 */
			if (ndlp->nlp_flag & NLP_RCV_PLOGI)
				return NULL;

J
James Smart 已提交
2171
			spin_lock_irq(shost->host_lock);
已提交
2172
			ndlp->nlp_flag |= NLP_NPR_2B_DISC;
J
James Smart 已提交
2173
			spin_unlock_irq(shost->host_lock);
2174 2175 2176 2177

			/* Since this node is marked for discovery,
			 * delay timeout is not needed.
			 */
2178
			if (ndlp->nlp_flag & NLP_DELAY_TMO)
J
James Smart 已提交
2179
				lpfc_cancel_retry_delay_tmo(vport, ndlp);
2180
		} else
已提交
2181
			ndlp = NULL;
2182
	} else {
2183 2184 2185 2186
		/* If we've already recieved a PLOGI from this NPort,
		 * or we are already in the process of discovery on it,
		 * we don't need to try to discover it again.
		 */
2187
		if (ndlp->nlp_state == NLP_STE_ADISC_ISSUE ||
2188 2189
		    ndlp->nlp_state == NLP_STE_PLOGI_ISSUE ||
		    ndlp->nlp_flag & NLP_RCV_PLOGI)
已提交
2190
			return NULL;
J
James Smart 已提交
2191 2192
		lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
		spin_lock_irq(shost->host_lock);
已提交
2193
		ndlp->nlp_flag |= NLP_NPR_2B_DISC;
J
James Smart 已提交
2194
		spin_unlock_irq(shost->host_lock);
已提交
2195 2196 2197 2198 2199 2200
	}
	return ndlp;
}

/* Build a list of nodes to discover based on the loopmap */
void
J
James Smart 已提交
2201
lpfc_disc_list_loopmap(struct lpfc_vport *vport)
已提交
2202
{
J
James Smart 已提交
2203
	struct lpfc_hba  *phba = vport->phba;
已提交
2204 2205 2206
	int j;
	uint32_t alpa, index;

J
James Smart 已提交
2207
	if (!lpfc_is_link_up(phba))
已提交
2208
		return;
J
James Smart 已提交
2209 2210

	if (phba->fc_topology != TOPOLOGY_LOOP)
已提交
2211 2212 2213 2214 2215 2216
		return;

	/* Check for loop map present or not */
	if (phba->alpa_map[0]) {
		for (j = 1; j <= phba->alpa_map[0]; j++) {
			alpa = phba->alpa_map[j];
J
James Smart 已提交
2217
			if (((vport->fc_myDID & 0xff) == alpa) || (alpa == 0))
已提交
2218
				continue;
J
James Smart 已提交
2219
			lpfc_setup_disc_node(vport, alpa);
已提交
2220 2221 2222 2223 2224 2225 2226
		}
	} else {
		/* No alpamap, so try all alpa's */
		for (j = 0; j < FC_MAXLOOP; j++) {
			/* If cfg_scan_down is set, start from highest
			 * ALPA (0xef) to lowest (0x1).
			 */
2227
			if (vport->cfg_scan_down)
已提交
2228 2229 2230 2231
				index = j;
			else
				index = FC_MAXLOOP - j - 1;
			alpa = lpfcAlpaArray[index];
J
James Smart 已提交
2232
			if ((vport->fc_myDID & 0xff) == alpa)
已提交
2233
				continue;
J
James Smart 已提交
2234
			lpfc_setup_disc_node(vport, alpa);
已提交
2235 2236 2237 2238 2239 2240
		}
	}
	return;
}

void
J
James Smart 已提交
2241
lpfc_issue_clear_la(struct lpfc_hba *phba, struct lpfc_vport *vport)
已提交
2242 2243
{
	LPFC_MBOXQ_t *mbox;
J
James Smart 已提交
2244 2245 2246 2247 2248 2249
	struct lpfc_sli *psli = &phba->sli;
	struct lpfc_sli_ring *extra_ring = &psli->ring[psli->extra_ring];
	struct lpfc_sli_ring *fcp_ring   = &psli->ring[psli->fcp_ring];
	struct lpfc_sli_ring *next_ring  = &psli->ring[psli->next_ring];
	int  rc;

2250 2251 2252 2253 2254 2255 2256 2257
	/*
	 * if it's not a physical port or if we already send
	 * clear_la then don't send it.
	 */
	if ((phba->link_state >= LPFC_CLEAR_LA) ||
	    (vport->port_type != LPFC_PHYSICAL_PORT))
		return;

J
James Smart 已提交
2258 2259 2260 2261 2262 2263
			/* Link up discovery */
	if ((mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL)) != NULL) {
		phba->link_state = LPFC_CLEAR_LA;
		lpfc_clear_la(phba, mbox);
		mbox->mbox_cmpl = lpfc_mbx_cmpl_clear_la;
		mbox->vport = vport;
2264
		rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT);
J
James Smart 已提交
2265 2266 2267 2268 2269 2270
		if (rc == MBX_NOT_FINISHED) {
			mempool_free(mbox, phba->mbox_mem_pool);
			lpfc_disc_flush_list(vport);
			extra_ring->flag &= ~LPFC_STOP_IOCB_EVENT;
			fcp_ring->flag &= ~LPFC_STOP_IOCB_EVENT;
			next_ring->flag &= ~LPFC_STOP_IOCB_EVENT;
2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286
			phba->link_state = LPFC_HBA_ERROR;
		}
	}
}

/* Reg_vpi to tell firmware to resume normal operations */
void
lpfc_issue_reg_vpi(struct lpfc_hba *phba, struct lpfc_vport *vport)
{
	LPFC_MBOXQ_t *regvpimbox;

	regvpimbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
	if (regvpimbox) {
		lpfc_reg_vpi(phba, vport->vpi, vport->fc_myDID, regvpimbox);
		regvpimbox->mbox_cmpl = lpfc_mbx_cmpl_reg_vpi;
		regvpimbox->vport = vport;
2287
		if (lpfc_sli_issue_mbox(phba, regvpimbox, MBX_NOWAIT)
2288 2289
					== MBX_NOT_FINISHED) {
			mempool_free(regvpimbox, phba->mbox_mem_pool);
J
James Smart 已提交
2290 2291 2292 2293 2294 2295 2296 2297 2298 2299
		}
	}
}

/* Start Link up / RSCN discovery on NPR nodes */
void
lpfc_disc_start(struct lpfc_vport *vport)
{
	struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
	struct lpfc_hba  *phba = vport->phba;
2300
	uint32_t num_sent;
已提交
2301
	uint32_t clear_la_pending;
2302
	int did_changed;
已提交
2303

J
James Smart 已提交
2304
	if (!lpfc_is_link_up(phba))
已提交
2305
		return;
J
James Smart 已提交
2306 2307

	if (phba->link_state == LPFC_CLEAR_LA)
已提交
2308 2309 2310 2311
		clear_la_pending = 1;
	else
		clear_la_pending = 0;

J
James Smart 已提交
2312 2313
	if (vport->port_state < LPFC_VPORT_READY)
		vport->port_state = LPFC_DISC_AUTH;
已提交
2314

J
James Smart 已提交
2315 2316 2317
	lpfc_set_disctmo(vport);

	if (vport->fc_prevDID == vport->fc_myDID)
已提交
2318
		did_changed = 0;
J
James Smart 已提交
2319
	else
已提交
2320
		did_changed = 1;
J
James Smart 已提交
2321 2322 2323

	vport->fc_prevDID = vport->fc_myDID;
	vport->num_disc_nodes = 0;
已提交
2324 2325

	/* Start Discovery state <hba_state> */
2326 2327 2328 2329 2330
	lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
			 "0202 Start Discovery hba state x%x "
			 "Data: x%x x%x x%x\n",
			 vport->port_state, vport->fc_flag, vport->fc_plogi_cnt,
			 vport->fc_adisc_cnt);
已提交
2331 2332

	/* First do ADISCs - if any */
J
James Smart 已提交
2333
	num_sent = lpfc_els_disc_adisc(vport);
已提交
2334 2335 2336 2337

	if (num_sent)
		return;

2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351
	/*
	 * For SLI3, cmpl_reg_vpi will set port_state to READY, and
	 * continue discovery.
	 */
	if ((phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) &&
	    !(vport->fc_flag & FC_RSCN_MODE)) {
		lpfc_issue_reg_vpi(phba, vport);
		return;
	}

	/*
	 * For SLI2, we need to set port_state to READY and continue
	 * discovery.
	 */
J
James Smart 已提交
2352
	if (vport->port_state < LPFC_VPORT_READY && !clear_la_pending) {
已提交
2353
		/* If we get here, there is nothing to ADISC */
2354
		if (vport->port_type == LPFC_PHYSICAL_PORT)
J
James Smart 已提交
2355 2356
			lpfc_issue_clear_la(phba, vport);

2357
		if (!(vport->fc_flag & FC_ABORT_DISCOVERY)) {
J
James Smart 已提交
2358 2359 2360 2361 2362 2363 2364 2365 2366
			vport->num_disc_nodes = 0;
			/* go thru NPR nodes and issue ELS PLOGIs */
			if (vport->fc_npr_cnt)
				lpfc_els_disc_plogi(vport);

			if (!vport->num_disc_nodes) {
				spin_lock_irq(shost->host_lock);
				vport->fc_flag &= ~FC_NDISC_ACTIVE;
				spin_unlock_irq(shost->host_lock);
2367
				lpfc_can_disctmo(vport);
已提交
2368 2369
			}
		}
2370
		vport->port_state = LPFC_VPORT_READY;
已提交
2371 2372
	} else {
		/* Next do PLOGIs - if any */
J
James Smart 已提交
2373
		num_sent = lpfc_els_disc_plogi(vport);
已提交
2374 2375 2376 2377

		if (num_sent)
			return;

J
James Smart 已提交
2378
		if (vport->fc_flag & FC_RSCN_MODE) {
已提交
2379 2380 2381
			/* Check to see if more RSCNs came in while we
			 * were processing this one.
			 */
J
James Smart 已提交
2382 2383 2384 2385 2386
			if ((vport->fc_rscn_id_cnt == 0) &&
			    (!(vport->fc_flag & FC_RSCN_DISCOVERY))) {
				spin_lock_irq(shost->host_lock);
				vport->fc_flag &= ~FC_RSCN_MODE;
				spin_unlock_irq(shost->host_lock);
2387
				lpfc_can_disctmo(vport);
2388
			} else
J
James Smart 已提交
2389
				lpfc_els_handle_rscn(vport);
已提交
2390 2391 2392 2393 2394 2395 2396 2397 2398 2399
		}
	}
	return;
}

/*
 *  Ignore completion for all IOCBs on tx and txcmpl queue for ELS
 *  ring the match the sppecified nodelist.
 */
static void
J
James Smart 已提交
2400
lpfc_free_tx(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp)
已提交
2401
{
2402
	LIST_HEAD(completions);
已提交
2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413
	struct lpfc_sli *psli;
	IOCB_t     *icmd;
	struct lpfc_iocbq    *iocb, *next_iocb;
	struct lpfc_sli_ring *pring;

	psli = &phba->sli;
	pring = &psli->ring[LPFC_ELS_RING];

	/* Error matching iocb on txq or txcmplq
	 * First check the txq.
	 */
J
James Smart 已提交
2414
	spin_lock_irq(&phba->hbalock);
已提交
2415 2416 2417 2418 2419 2420 2421 2422
	list_for_each_entry_safe(iocb, next_iocb, &pring->txq, list) {
		if (iocb->context1 != ndlp) {
			continue;
		}
		icmd = &iocb->iocb;
		if ((icmd->ulpCommand == CMD_ELS_REQUEST64_CR) ||
		    (icmd->ulpCommand == CMD_XMIT_ELS_RSP64_CX)) {

2423
			list_move_tail(&iocb->list, &completions);
已提交
2424 2425 2426 2427 2428 2429 2430 2431 2432 2433
			pring->txq_cnt--;
		}
	}

	/* Next check the txcmplq */
	list_for_each_entry_safe(iocb, next_iocb, &pring->txcmplq, list) {
		if (iocb->context1 != ndlp) {
			continue;
		}
		icmd = &iocb->iocb;
J
James Smart 已提交
2434 2435
		if (icmd->ulpCommand == CMD_ELS_REQUEST64_CR ||
		    icmd->ulpCommand == CMD_XMIT_ELS_RSP64_CX) {
2436 2437 2438
			lpfc_sli_issue_abort_iotag(phba, pring, iocb);
		}
	}
J
James Smart 已提交
2439
	spin_unlock_irq(&phba->hbalock);
已提交
2440

2441 2442
	while (!list_empty(&completions)) {
		iocb = list_get_first(&completions, struct lpfc_iocbq, list);
2443
		list_del_init(&iocb->list);
已提交
2444

J
James Smart 已提交
2445 2446 2447
		if (!iocb->iocb_cmpl)
			lpfc_sli_release_iocbq(phba, iocb);
		else {
2448 2449 2450 2451
			icmd = &iocb->iocb;
			icmd->ulpStatus = IOSTAT_LOCAL_REJECT;
			icmd->un.ulpWord[4] = IOERR_SLI_ABORTED;
			(iocb->iocb_cmpl) (phba, iocb, iocb);
J
James Smart 已提交
2452
		}
已提交
2453 2454 2455
	}
}

A
Adrian Bunk 已提交
2456
static void
J
James Smart 已提交
2457
lpfc_disc_flush_list(struct lpfc_vport *vport)
已提交
2458 2459
{
	struct lpfc_nodelist *ndlp, *next_ndlp;
J
James Smart 已提交
2460
	struct lpfc_hba *phba = vport->phba;
已提交
2461

J
James Smart 已提交
2462 2463
	if (vport->fc_plogi_cnt || vport->fc_adisc_cnt) {
		list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes,
2464 2465 2466 2467 2468
					 nlp_listp) {
			if (ndlp->nlp_state == NLP_STE_PLOGI_ISSUE ||
			    ndlp->nlp_state == NLP_STE_ADISC_ISSUE) {
				lpfc_free_tx(phba, ndlp);
			}
已提交
2469 2470 2471 2472
		}
	}
}

2473 2474 2475 2476 2477 2478 2479 2480
void
lpfc_cleanup_discovery_resources(struct lpfc_vport *vport)
{
	lpfc_els_flush_rscn(vport);
	lpfc_els_flush_cmd(vport);
	lpfc_disc_flush_list(vport);
}

已提交
2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498
/*****************************************************************************/
/*
 * NAME:     lpfc_disc_timeout
 *
 * FUNCTION: Fibre Channel driver discovery timeout routine.
 *
 * EXECUTION ENVIRONMENT: interrupt only
 *
 * CALLED FROM:
 *      Timer function
 *
 * RETURNS:
 *      none
 */
/*****************************************************************************/
void
lpfc_disc_timeout(unsigned long ptr)
{
J
James Smart 已提交
2499 2500
	struct lpfc_vport *vport = (struct lpfc_vport *) ptr;
	struct lpfc_hba   *phba = vport->phba;
已提交
2501 2502 2503 2504 2505
	unsigned long flags = 0;

	if (unlikely(!phba))
		return;

J
James Smart 已提交
2506 2507 2508 2509 2510
	if ((vport->work_port_events & WORKER_DISC_TMO) == 0) {
		spin_lock_irqsave(&vport->work_port_lock, flags);
		vport->work_port_events |= WORKER_DISC_TMO;
		spin_unlock_irqrestore(&vport->work_port_lock, flags);

2511
		spin_lock_irqsave(&phba->hbalock, flags);
已提交
2512
		if (phba->work_wait)
2513 2514
			lpfc_worker_wake_up(phba);
		spin_unlock_irqrestore(&phba->hbalock, flags);
已提交
2515 2516 2517 2518 2519
	}
	return;
}

static void
J
James Smart 已提交
2520
lpfc_disc_timeout_handler(struct lpfc_vport *vport)
已提交
2521
{
J
James Smart 已提交
2522 2523 2524
	struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
	struct lpfc_hba  *phba = vport->phba;
	struct lpfc_sli  *psli = &phba->sli;
2525
	struct lpfc_nodelist *ndlp, *next_ndlp;
2526
	LPFC_MBOXQ_t *initlinkmbox;
已提交
2527 2528
	int rc, clrlaerr = 0;

J
James Smart 已提交
2529
	if (!(vport->fc_flag & FC_DISC_TMO))
已提交
2530 2531
		return;

J
James Smart 已提交
2532 2533 2534
	spin_lock_irq(shost->host_lock);
	vport->fc_flag &= ~FC_DISC_TMO;
	spin_unlock_irq(shost->host_lock);
已提交
2535

J
James Smart 已提交
2536 2537 2538 2539
	lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
		"disc timeout:    state:x%x rtry:x%x flg:x%x",
		vport->port_state, vport->fc_ns_retry, vport->fc_flag);

J
James Smart 已提交
2540
	switch (vport->port_state) {
已提交
2541 2542

	case LPFC_LOCAL_CFG_LINK:
J
James Smart 已提交
2543 2544 2545 2546
	/* port_state is identically  LPFC_LOCAL_CFG_LINK while waiting for
	 * FAN
	 */
				/* FAN timeout */
2547 2548
		lpfc_printf_vlog(vport, KERN_WARNING, LOG_DISCOVERY,
				 "0221 FAN timeout\n");
2549
		/* Start discovery by sending FLOGI, clean up old rpis */
J
James Smart 已提交
2550
		list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes,
2551 2552 2553
					 nlp_listp) {
			if (ndlp->nlp_state != NLP_STE_NPR_NODE)
				continue;
2554 2555
			if (ndlp->nlp_type & NLP_FABRIC) {
				/* Clean up the ndlp on Fabric connections */
J
James Smart 已提交
2556
				lpfc_drop_node(vport, ndlp);
2557

2558
			} else if (!(ndlp->nlp_flag & NLP_NPR_ADISC)) {
2559 2560 2561
				/* Fail outstanding IO now since device
				 * is marked for PLOGI.
				 */
J
James Smart 已提交
2562
				lpfc_unreg_rpi(vport, ndlp);
2563 2564
			}
		}
2565 2566
		if (vport->port_state != LPFC_FLOGI) {
			lpfc_initial_flogi(vport);
2567
			return;
2568
		}
已提交
2569 2570
		break;

2571
	case LPFC_FDISC:
已提交
2572
	case LPFC_FLOGI:
J
James Smart 已提交
2573
	/* port_state is identically LPFC_FLOGI while waiting for FLOGI cmpl */
已提交
2574
		/* Initial FLOGI timeout */
2575 2576
		lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY,
				 "0222 Initial %s timeout\n",
2577
				 vport->vpi ? "FDISC" : "FLOGI");
已提交
2578 2579 2580 2581 2582 2583

		/* Assume no Fabric and go on with discovery.
		 * Check for outstanding ELS FLOGI to abort.
		 */

		/* FLOGI failed, so just use loop map to make discovery list */
J
James Smart 已提交
2584
		lpfc_disc_list_loopmap(vport);
已提交
2585 2586

		/* Start discovery */
J
James Smart 已提交
2587
		lpfc_disc_start(vport);
已提交
2588 2589 2590 2591 2592
		break;

	case LPFC_FABRIC_CFG_LINK:
	/* hba_state is identically LPFC_FABRIC_CFG_LINK while waiting for
	   NameServer login */
2593 2594 2595
		lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY,
				 "0223 Timeout while waiting for "
				 "NameServer login\n");
已提交
2596
		/* Next look for NameServer ndlp */
J
James Smart 已提交
2597
		ndlp = lpfc_findnode_did(vport, NameServer_DID);
已提交
2598
		if (ndlp)
2599 2600 2601 2602
			lpfc_els_abort(phba, ndlp);

		/* ReStart discovery */
		goto restart_disc;
已提交
2603 2604 2605

	case LPFC_NS_QRY:
	/* Check for wait for NameServer Rsp timeout */
2606 2607 2608 2609
		lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY,
				 "0224 NameServer Query timeout "
				 "Data: x%x x%x\n",
				 vport->fc_ns_retry, LPFC_MAX_NS_RETRY);
已提交
2610

2611 2612 2613 2614 2615 2616 2617
		if (vport->fc_ns_retry < LPFC_MAX_NS_RETRY) {
			/* Try it one more time */
			vport->fc_ns_retry++;
			rc = lpfc_ns_cmd(vport, SLI_CTNS_GID_FT,
					 vport->fc_ns_retry, 0);
			if (rc == 0)
				break;
已提交
2618
		}
2619
		vport->fc_ns_retry = 0;
已提交
2620

2621
restart_disc:
2622 2623 2624 2625 2626 2627 2628 2629 2630 2631
		/*
		 * Discovery is over.
		 * set port_state to PORT_READY if SLI2.
		 * cmpl_reg_vpi will set port_state to READY for SLI3.
		 */
		if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED)
			lpfc_issue_reg_vpi(phba, vport);
		else  {	/* NPIV Not enabled */
			lpfc_issue_clear_la(phba, vport);
			vport->port_state = LPFC_VPORT_READY;
已提交
2632 2633 2634 2635 2636
		}

		/* Setup and issue mailbox INITIALIZE LINK command */
		initlinkmbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
		if (!initlinkmbox) {
2637 2638 2639
			lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY,
					 "0206 Device Discovery "
					 "completion error\n");
J
James Smart 已提交
2640
			phba->link_state = LPFC_HBA_ERROR;
已提交
2641 2642 2643 2644 2645 2646 2647
			break;
		}

		lpfc_linkdown(phba);
		lpfc_init_link(phba, initlinkmbox, phba->cfg_topology,
			       phba->cfg_link_speed);
		initlinkmbox->mb.un.varInitLnk.lipsr_AL_PA = 0;
2648
		initlinkmbox->vport = vport;
2649
		initlinkmbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
2650
		rc = lpfc_sli_issue_mbox(phba, initlinkmbox, MBX_NOWAIT);
2651
		lpfc_set_loopback_flag(phba);
已提交
2652 2653 2654 2655 2656 2657 2658
		if (rc == MBX_NOT_FINISHED)
			mempool_free(initlinkmbox, phba->mbox_mem_pool);

		break;

	case LPFC_DISC_AUTH:
	/* Node Authentication timeout */
2659 2660
		lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY,
				 "0227 Node Authentication timeout\n");
J
James Smart 已提交
2661 2662
		lpfc_disc_flush_list(vport);

2663 2664 2665 2666 2667 2668 2669 2670 2671
		/*
		 * set port_state to PORT_READY if SLI2.
		 * cmpl_reg_vpi will set port_state to READY for SLI3.
		 */
		if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED)
			lpfc_issue_reg_vpi(phba, vport);
		else {	/* NPIV Not enabled */
			lpfc_issue_clear_la(phba, vport);
			vport->port_state = LPFC_VPORT_READY;
已提交
2672 2673 2674
		}
		break;

J
James Smart 已提交
2675 2676
	case LPFC_VPORT_READY:
		if (vport->fc_flag & FC_RSCN_MODE) {
2677 2678 2679 2680
			lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY,
					 "0231 RSCN timeout Data: x%x "
					 "x%x\n",
					 vport->fc_ns_retry, LPFC_MAX_NS_RETRY);
已提交
2681 2682

			/* Cleanup any outstanding ELS commands */
J
James Smart 已提交
2683
			lpfc_els_flush_cmd(vport);
已提交
2684

J
James Smart 已提交
2685 2686
			lpfc_els_flush_rscn(vport);
			lpfc_disc_flush_list(vport);
已提交
2687 2688
		}
		break;
J
James Smart 已提交
2689

2690
	default:
2691 2692 2693
		lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY,
				 "0229 Unexpected discovery timeout, "
				 "vport State x%x\n", vport->port_state);
J
James Smart 已提交
2694 2695 2696 2697 2698
		break;
	}

	switch (phba->link_state) {
	case LPFC_CLEAR_LA:
2699
				/* CLEAR LA timeout */
2700 2701
		lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY,
				 "0228 CLEAR LA timeout\n");
J
James Smart 已提交
2702 2703 2704 2705 2706 2707 2708 2709 2710 2711
		clrlaerr = 1;
		break;

	case LPFC_LINK_UNKNOWN:
	case LPFC_WARM_START:
	case LPFC_INIT_START:
	case LPFC_INIT_MBX_CMDS:
	case LPFC_LINK_DOWN:
	case LPFC_LINK_UP:
	case LPFC_HBA_ERROR:
2712 2713 2714
		lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY,
				 "0230 Unexpected timeout, hba link "
				 "state x%x\n", phba->link_state);
J
James Smart 已提交
2715 2716
		clrlaerr = 1;
		break;
2717 2718 2719

	case LPFC_HBA_READY:
		break;
已提交
2720 2721 2722
	}

	if (clrlaerr) {
J
James Smart 已提交
2723
		lpfc_disc_flush_list(vport);
2724
		psli->ring[(psli->extra_ring)].flag &= ~LPFC_STOP_IOCB_EVENT;
已提交
2725 2726
		psli->ring[(psli->fcp_ring)].flag &= ~LPFC_STOP_IOCB_EVENT;
		psli->ring[(psli->next_ring)].flag &= ~LPFC_STOP_IOCB_EVENT;
J
James Smart 已提交
2727
		vport->port_state = LPFC_VPORT_READY;
已提交
2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739
	}

	return;
}

/*
 * This routine handles processing a NameServer REG_LOGIN mailbox
 * command upon completion. It is setup in the LPFC_MBOXQ
 * as the completion routine when the command is
 * handed off to the SLI layer.
 */
void
J
James Smart 已提交
2740
lpfc_mbx_cmpl_fdmi_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
已提交
2741
{
J
James Smart 已提交
2742 2743 2744 2745
	MAILBOX_t *mb = &pmb->mb;
	struct lpfc_dmabuf   *mp = (struct lpfc_dmabuf *) (pmb->context1);
	struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) pmb->context2;
	struct lpfc_vport    *vport = pmb->vport;
已提交
2746 2747 2748 2749 2750

	pmb->context1 = NULL;

	ndlp->nlp_rpi = mb->un.varWords[0];
	ndlp->nlp_type |= NLP_FABRIC;
J
James Smart 已提交
2751
	lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE);
已提交
2752

J
James Smart 已提交
2753 2754 2755 2756
	/*
	 * Start issuing Fabric-Device Management Interface (FDMI) command to
	 * 0xfffffa (FDMI well known port) or Delay issuing FDMI command if
	 * fdmi-on=2 (supporting RPA/hostnmae)
已提交
2757
	 */
J
James Smart 已提交
2758

2759
	if (vport->cfg_fdmi_on == 1)
J
James Smart 已提交
2760 2761 2762
		lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_DHBA);
	else
		mod_timer(&vport->fc_fdmitmo, jiffies + HZ * 60);
已提交
2763

2764 2765
				/* Mailbox took a reference to the node */
	lpfc_nlp_put(ndlp);
已提交
2766 2767
	lpfc_mbuf_free(phba, mp->virt, mp->phys);
	kfree(mp);
2768
	mempool_free(pmb, phba->mbox_mem_pool);
已提交
2769 2770 2771 2772

	return;
}

2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787
static int
lpfc_filter_by_rpi(struct lpfc_nodelist *ndlp, void *param)
{
	uint16_t *rpi = param;

	return ndlp->nlp_rpi == *rpi;
}

static int
lpfc_filter_by_wwpn(struct lpfc_nodelist *ndlp, void *param)
{
	return memcmp(&ndlp->nlp_portname, param,
		      sizeof(ndlp->nlp_portname)) == 0;
}

A
Adrian Bunk 已提交
2788
static struct lpfc_nodelist *
J
James Smart 已提交
2789
__lpfc_find_node(struct lpfc_vport *vport, node_filter filter, void *param)
已提交
2790
{
2791
	struct lpfc_nodelist *ndlp;
已提交
2792

J
James Smart 已提交
2793
	list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) {
2794
		if (filter(ndlp, param))
2795 2796
			return ndlp;
	}
2797
	return NULL;
已提交
2798 2799
}

A
Adrian Bunk 已提交
2800
#if 0
2801 2802
/*
 * Search node lists for a remote port matching filter criteria
2803
 * Caller needs to hold host_lock before calling this routine.
2804 2805
 */
struct lpfc_nodelist *
J
James Smart 已提交
2806
lpfc_find_node(struct lpfc_vport *vport, node_filter filter, void *param)
2807
{
J
James Smart 已提交
2808
	struct Scsi_Host     *shost = lpfc_shost_from_vport(vport);
2809 2810
	struct lpfc_nodelist *ndlp;

J
James Smart 已提交
2811 2812 2813
	spin_lock_irq(shost->host_lock);
	ndlp = __lpfc_find_node(vport, filter, param);
	spin_unlock_irq(shost->host_lock);
2814 2815
	return ndlp;
}
A
Adrian Bunk 已提交
2816
#endif  /*  0  */
2817 2818 2819

/*
 * This routine looks up the ndlp lists for the given RPI. If rpi found it
J
James Smart 已提交
2820
 * returns the node list element pointer else return NULL.
2821 2822
 */
struct lpfc_nodelist *
J
James Smart 已提交
2823
__lpfc_findnode_rpi(struct lpfc_vport *vport, uint16_t rpi)
2824
{
J
James Smart 已提交
2825
	return __lpfc_find_node(vport, lpfc_filter_by_rpi, &rpi);
2826 2827
}

A
Adrian Bunk 已提交
2828
#if 0
2829
struct lpfc_nodelist *
J
James Smart 已提交
2830
lpfc_findnode_rpi(struct lpfc_vport *vport, uint16_t rpi)
2831
{
J
James Smart 已提交
2832
	struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
2833 2834
	struct lpfc_nodelist *ndlp;

J
James Smart 已提交
2835 2836 2837
	spin_lock_irq(shost->host_lock);
	ndlp = __lpfc_findnode_rpi(vport, rpi);
	spin_unlock_irq(shost->host_lock);
2838 2839
	return ndlp;
}
A
Adrian Bunk 已提交
2840
#endif  /*  0  */
2841

2842
/*
2843
 * This routine looks up the ndlp lists for the given WWPN. If WWPN found it
J
James Smart 已提交
2844
 * returns the node element list pointer else return NULL.
2845 2846
 */
struct lpfc_nodelist *
J
James Smart 已提交
2847
lpfc_findnode_wwpn(struct lpfc_vport *vport, struct lpfc_name *wwpn)
2848
{
J
James Smart 已提交
2849
	struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
2850 2851
	struct lpfc_nodelist *ndlp;

J
James Smart 已提交
2852 2853 2854
	spin_lock_irq(shost->host_lock);
	ndlp = __lpfc_find_node(vport, lpfc_filter_by_wwpn, wwpn);
	spin_unlock_irq(shost->host_lock);
J
James Smart 已提交
2855
	return ndlp;
2856 2857
}

已提交
2858
void
J
James Smart 已提交
2859 2860
lpfc_nlp_init(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
	      uint32_t did)
已提交
2861 2862 2863
{
	memset(ndlp, 0, sizeof (struct lpfc_nodelist));
	INIT_LIST_HEAD(&ndlp->els_retry_evt.evt_listp);
2864
	INIT_LIST_HEAD(&ndlp->dev_loss_evt.evt_listp);
已提交
2865 2866 2867 2868
	init_timer(&ndlp->nlp_delayfunc);
	ndlp->nlp_delayfunc.function = lpfc_els_retry_delay;
	ndlp->nlp_delayfunc.data = (unsigned long)ndlp;
	ndlp->nlp_DID = did;
J
James Smart 已提交
2869
	ndlp->vport = vport;
已提交
2870
	ndlp->nlp_sid = NLP_NO_SID;
2871
	INIT_LIST_HEAD(&ndlp->nlp_listp);
2872
	kref_init(&ndlp->kref);
J
James Smart 已提交
2873 2874 2875 2876 2877

	lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_NODE,
		"node init:       did:x%x",
		ndlp->nlp_DID, 0, 0);

已提交
2878 2879
	return;
}
2880

2881 2882 2883
/* This routine releases all resources associated with a specifc NPort's ndlp
 * and mempool_free's the nodelist.
 */
J
James Smart 已提交
2884
static void
2885 2886 2887 2888
lpfc_nlp_release(struct kref *kref)
{
	struct lpfc_nodelist *ndlp = container_of(kref, struct lpfc_nodelist,
						  kref);
J
James Smart 已提交
2889 2890 2891 2892 2893

	lpfc_debugfs_disc_trc(ndlp->vport, LPFC_DISC_TRC_NODE,
		"node release:    did:x%x flg:x%x type:x%x",
		ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_type);

J
James Smart 已提交
2894 2895
	lpfc_nlp_remove(ndlp->vport, ndlp);
	mempool_free(ndlp, ndlp->vport->phba->nlp_mem_pool);
2896 2897
}

2898 2899 2900 2901
/* This routine bumps the reference count for a ndlp structure to ensure
 * that one discovery thread won't free a ndlp while another discovery thread
 * is using it.
 */
2902 2903 2904
struct lpfc_nodelist *
lpfc_nlp_get(struct lpfc_nodelist *ndlp)
{
2905 2906 2907 2908 2909
	if (ndlp) {
		lpfc_debugfs_disc_trc(ndlp->vport, LPFC_DISC_TRC_NODE,
			"node get:        did:x%x flg:x%x refcnt:x%x",
			ndlp->nlp_DID, ndlp->nlp_flag,
			atomic_read(&ndlp->kref.refcount));
2910
		kref_get(&ndlp->kref);
2911
	}
2912 2913 2914
	return ndlp;
}

2915 2916 2917 2918

/* This routine decrements the reference count for a ndlp structure. If the
 * count goes to 0, this indicates the the associated nodelist should be freed.
 */
2919 2920 2921
int
lpfc_nlp_put(struct lpfc_nodelist *ndlp)
{
2922 2923 2924 2925 2926 2927
	if (ndlp) {
		lpfc_debugfs_disc_trc(ndlp->vport, LPFC_DISC_TRC_NODE,
		"node put:        did:x%x flg:x%x refcnt:x%x",
			ndlp->nlp_DID, ndlp->nlp_flag,
			atomic_read(&ndlp->kref.refcount));
	}
2928 2929
	return ndlp ? kref_put(&ndlp->kref, lpfc_nlp_release) : 0;
}
2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 2951

/* This routine free's the specified nodelist if it is not in use
 * by any other discovery thread. This routine returns 1 if the ndlp
 * is not being used by anyone and has been freed. A return value of
 * 0 indicates it is being used by another discovery thread and the
 * refcount is left unchanged.
 */
int
lpfc_nlp_not_used(struct lpfc_nodelist *ndlp)
{
	lpfc_debugfs_disc_trc(ndlp->vport, LPFC_DISC_TRC_NODE,
		"node not used:   did:x%x flg:x%x refcnt:x%x",
		ndlp->nlp_DID, ndlp->nlp_flag,
		atomic_read(&ndlp->kref.refcount));

	if (atomic_read(&ndlp->kref.refcount) == 1) {
		lpfc_nlp_put(ndlp);
		return 1;
	}
	return 0;
}