1 /*******************************************************************
2 * This file is part of the Emulex Linux Device Driver for *
3 * Fibre Channel Host Bus Adapters. *
4 * Copyright (C) 2004-2005 Emulex. All rights reserved. *
5 * EMULEX and SLI are trademarks of Emulex. *
7 * Portions Copyright (C) 2004-2005 Christoph Hellwig *
9 * This program is free software; you can redistribute it and/or *
10 * modify it under the terms of version 2 of the GNU General *
11 * Public License as published by the Free Software Foundation. *
12 * This program is distributed in the hope that it will be useful. *
13 * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND *
14 * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, *
15 * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT, ARE *
16 * DISCLAIMED, EXCEPT TO THE EXTENT THAT SUCH DISCLAIMERS ARE HELD *
17 * TO BE LEGALLY INVALID. See the GNU General Public License for *
18 * more details, a copy of which can be found in the file COPYING *
19 * included with this package. *
20 *******************************************************************/
22 #include <linux/blkdev.h>
23 #include <linux/pci.h>
24 #include <linux/interrupt.h>
26 #include <scsi/scsi.h>
27 #include <scsi/scsi_device.h>
28 #include <scsi/scsi_host.h>
29 #include <scsi/scsi_transport_fc.h>
33 #include "lpfc_disc.h"
34 #include "lpfc_scsi.h"
36 #include "lpfc_logmsg.h"
37 #include "lpfc_crtn.h"
40 /* Called to verify a rcv'ed ADISC was intended for us. */
42 lpfc_check_adisc(struct lpfc_hba
* phba
, struct lpfc_nodelist
* ndlp
,
43 struct lpfc_name
* nn
, struct lpfc_name
* pn
)
45 /* Compare the ADISC rsp WWNN / WWPN matches our internal node
46 * table entry for that node.
48 if (memcmp(nn
, &ndlp
->nlp_nodename
, sizeof (struct lpfc_name
)) != 0)
51 if (memcmp(pn
, &ndlp
->nlp_portname
, sizeof (struct lpfc_name
)) != 0)
54 /* we match, return success */
59 lpfc_check_sparm(struct lpfc_hba
* phba
,
60 struct lpfc_nodelist
* ndlp
, struct serv_parm
* sp
,
63 volatile struct serv_parm
*hsp
= &phba
->fc_sparam
;
64 uint16_t hsp_value
, ssp_value
= 0;
67 * The receive data field size and buffer-to-buffer receive data field
68 * size entries are 16 bits but are represented as two 8-bit fields in
69 * the driver data structure to account for rsvd bits and other control
70 * bits. Reconstruct and compare the fields as a 16-bit values before
71 * correcting the byte values.
73 if (sp
->cls1
.classValid
) {
74 hsp_value
= (hsp
->cls1
.rcvDataSizeMsb
<< 8) |
75 hsp
->cls1
.rcvDataSizeLsb
;
76 ssp_value
= (sp
->cls1
.rcvDataSizeMsb
<< 8) |
77 sp
->cls1
.rcvDataSizeLsb
;
78 if (ssp_value
> hsp_value
) {
79 sp
->cls1
.rcvDataSizeLsb
= hsp
->cls1
.rcvDataSizeLsb
;
80 sp
->cls1
.rcvDataSizeMsb
= hsp
->cls1
.rcvDataSizeMsb
;
82 } else if (class == CLASS1
) {
86 if (sp
->cls2
.classValid
) {
87 hsp_value
= (hsp
->cls2
.rcvDataSizeMsb
<< 8) |
88 hsp
->cls2
.rcvDataSizeLsb
;
89 ssp_value
= (sp
->cls2
.rcvDataSizeMsb
<< 8) |
90 sp
->cls2
.rcvDataSizeLsb
;
91 if (ssp_value
> hsp_value
) {
92 sp
->cls2
.rcvDataSizeLsb
= hsp
->cls2
.rcvDataSizeLsb
;
93 sp
->cls2
.rcvDataSizeMsb
= hsp
->cls2
.rcvDataSizeMsb
;
95 } else if (class == CLASS2
) {
99 if (sp
->cls3
.classValid
) {
100 hsp_value
= (hsp
->cls3
.rcvDataSizeMsb
<< 8) |
101 hsp
->cls3
.rcvDataSizeLsb
;
102 ssp_value
= (sp
->cls3
.rcvDataSizeMsb
<< 8) |
103 sp
->cls3
.rcvDataSizeLsb
;
104 if (ssp_value
> hsp_value
) {
105 sp
->cls3
.rcvDataSizeLsb
= hsp
->cls3
.rcvDataSizeLsb
;
106 sp
->cls3
.rcvDataSizeMsb
= hsp
->cls3
.rcvDataSizeMsb
;
108 } else if (class == CLASS3
) {
113 * Preserve the upper four bits of the MSB from the PLOGI response.
114 * These bits contain the Buffer-to-Buffer State Change Number
115 * from the target and need to be passed to the FW.
117 hsp_value
= (hsp
->cmn
.bbRcvSizeMsb
<< 8) | hsp
->cmn
.bbRcvSizeLsb
;
118 ssp_value
= (sp
->cmn
.bbRcvSizeMsb
<< 8) | sp
->cmn
.bbRcvSizeLsb
;
119 if (ssp_value
> hsp_value
) {
120 sp
->cmn
.bbRcvSizeLsb
= hsp
->cmn
.bbRcvSizeLsb
;
121 sp
->cmn
.bbRcvSizeMsb
= (sp
->cmn
.bbRcvSizeMsb
& 0xF0) |
122 (hsp
->cmn
.bbRcvSizeMsb
& 0x0F);
125 memcpy(&ndlp
->nlp_nodename
, &sp
->nodeName
, sizeof (struct lpfc_name
));
126 memcpy(&ndlp
->nlp_portname
, &sp
->portName
, sizeof (struct lpfc_name
));
131 lpfc_check_elscmpl_iocb(struct lpfc_hba
* phba
,
132 struct lpfc_iocbq
*cmdiocb
,
133 struct lpfc_iocbq
*rspiocb
)
135 struct lpfc_dmabuf
*pcmd
, *prsp
;
140 irsp
= &rspiocb
->iocb
;
141 pcmd
= (struct lpfc_dmabuf
*) cmdiocb
->context2
;
143 /* For lpfc_els_abort, context2 could be zero'ed to delay
144 * freeing associated memory till after ABTS completes.
147 prsp
= list_get_first(&pcmd
->list
, struct lpfc_dmabuf
,
150 lp
= (uint32_t *) prsp
->virt
;
151 ptr
= (void *)((uint8_t *)lp
+ sizeof(uint32_t));
155 /* Force ulpStatus error since we are returning NULL ptr */
156 if (!(irsp
->ulpStatus
)) {
157 irsp
->ulpStatus
= IOSTAT_LOCAL_REJECT
;
158 irsp
->un
.ulpWord
[4] = IOERR_SLI_ABORTED
;
167 * Free resources / clean up outstanding I/Os
168 * associated with a LPFC_NODELIST entry. This
169 * routine effectively results in a "software abort".
172 lpfc_els_abort(struct lpfc_hba
* phba
, struct lpfc_nodelist
* ndlp
,
175 struct lpfc_sli
*psli
;
176 struct lpfc_sli_ring
*pring
;
177 struct lpfc_iocbq
*iocb
, *next_iocb
;
181 /* Abort outstanding I/O on NPort <nlp_DID> */
182 lpfc_printf_log(phba
, KERN_INFO
, LOG_DISCOVERY
,
183 "%d:0201 Abort outstanding I/O on NPort x%x "
184 "Data: x%x x%x x%x\n",
185 phba
->brd_no
, ndlp
->nlp_DID
, ndlp
->nlp_flag
,
186 ndlp
->nlp_state
, ndlp
->nlp_rpi
);
189 pring
= &psli
->ring
[LPFC_ELS_RING
];
191 /* First check the txq */
194 spin_lock_irq(phba
->host
->host_lock
);
195 list_for_each_entry_safe(iocb
, next_iocb
, &pring
->txq
, list
) {
196 /* Check to see if iocb matches the nport we are looking
198 if ((lpfc_check_sli_ndlp(phba
, pring
, iocb
, ndlp
))) {
200 /* It matches, so deque and call compl with an
202 list_del(&iocb
->list
);
204 if (iocb
->iocb_cmpl
) {
206 icmd
->ulpStatus
= IOSTAT_LOCAL_REJECT
;
207 icmd
->un
.ulpWord
[4] = IOERR_SLI_ABORTED
;
208 spin_unlock_irq(phba
->host
->host_lock
);
209 (iocb
->iocb_cmpl
) (phba
, iocb
, iocb
);
210 spin_lock_irq(phba
->host
->host_lock
);
212 lpfc_sli_release_iocbq(phba
, iocb
);
216 spin_unlock_irq(phba
->host
->host_lock
);
219 /* Everything on txcmplq will be returned by firmware
220 * with a no rpi / linkdown / abort error. For ring 0,
221 * ELS discovery, we want to get rid of it right here.
223 /* Next check the txcmplq */
226 spin_lock_irq(phba
->host
->host_lock
);
227 list_for_each_entry_safe(iocb
, next_iocb
, &pring
->txcmplq
,
229 /* Check to see if iocb matches the nport we are looking
231 if ((lpfc_check_sli_ndlp (phba
, pring
, iocb
, ndlp
))) {
233 /* It matches, so deque and call compl with an
235 list_del(&iocb
->list
);
236 pring
->txcmplq_cnt
--;
239 /* If the driver is completing an ELS
240 * command early, flush it out of the firmware.
243 (icmd
->ulpCommand
== CMD_ELS_REQUEST64_CR
) &&
244 (icmd
->un
.elsreq64
.bdl
.ulpIoTag32
)) {
245 lpfc_sli_issue_abort_iotag32(phba
,
248 if (iocb
->iocb_cmpl
) {
249 icmd
->ulpStatus
= IOSTAT_LOCAL_REJECT
;
250 icmd
->un
.ulpWord
[4] = IOERR_SLI_ABORTED
;
251 spin_unlock_irq(phba
->host
->host_lock
);
252 (iocb
->iocb_cmpl
) (phba
, iocb
, iocb
);
253 spin_lock_irq(phba
->host
->host_lock
);
255 lpfc_sli_release_iocbq(phba
, iocb
);
259 spin_unlock_irq(phba
->host
->host_lock
);
262 /* If we are delaying issuing an ELS command, cancel it */
263 if (ndlp
->nlp_flag
& NLP_DELAY_TMO
) {
264 ndlp
->nlp_flag
&= ~NLP_DELAY_TMO
;
265 del_timer_sync(&ndlp
->nlp_delayfunc
);
266 if (!list_empty(&ndlp
->els_retry_evt
.evt_listp
))
267 list_del_init(&ndlp
->els_retry_evt
.evt_listp
);
273 lpfc_rcv_plogi(struct lpfc_hba
* phba
,
274 struct lpfc_nodelist
* ndlp
,
275 struct lpfc_iocbq
*cmdiocb
)
277 struct lpfc_dmabuf
*pcmd
;
280 struct serv_parm
*sp
;
285 memset(&stat
, 0, sizeof (struct ls_rjt
));
286 if (phba
->hba_state
<= LPFC_FLOGI
) {
287 /* Before responding to PLOGI, check for pt2pt mode.
288 * If we are pt2pt, with an outstanding FLOGI, abort
289 * the FLOGI and resend it first.
291 if (phba
->fc_flag
& FC_PT2PT
) {
292 lpfc_els_abort_flogi(phba
);
293 if (!(phba
->fc_flag
& FC_PT2PT_PLOGI
)) {
294 /* If the other side is supposed to initiate
295 * the PLOGI anyway, just ACC it now and
296 * move on with discovery.
298 phba
->fc_edtov
= FF_DEF_EDTOV
;
299 phba
->fc_ratov
= FF_DEF_RATOV
;
300 /* Start discovery - this should just do
302 lpfc_disc_start(phba
);
305 lpfc_initial_flogi(phba
);
309 stat
.un
.b
.lsRjtRsnCode
= LSRJT_LOGICAL_BSY
;
310 stat
.un
.b
.lsRjtRsnCodeExp
= LSEXP_NOTHING_MORE
;
311 lpfc_els_rsp_reject(phba
, stat
.un
.lsRjtError
, cmdiocb
,
316 pcmd
= (struct lpfc_dmabuf
*) cmdiocb
->context2
;
317 lp
= (uint32_t *) pcmd
->virt
;
318 sp
= (struct serv_parm
*) ((uint8_t *) lp
+ sizeof (uint32_t));
319 if ((lpfc_check_sparm(phba
, ndlp
, sp
, CLASS3
) == 0)) {
320 /* Reject this request because invalid parameters */
321 stat
.un
.b
.lsRjtRsnCode
= LSRJT_UNABLE_TPC
;
322 stat
.un
.b
.lsRjtRsnCodeExp
= LSEXP_SPARM_OPTIONS
;
323 lpfc_els_rsp_reject(phba
, stat
.un
.lsRjtError
, cmdiocb
, ndlp
);
326 icmd
= &cmdiocb
->iocb
;
328 /* PLOGI chkparm OK */
329 lpfc_printf_log(phba
,
332 "%d:0114 PLOGI chkparm OK Data: x%x x%x x%x x%x\n",
334 ndlp
->nlp_DID
, ndlp
->nlp_state
, ndlp
->nlp_flag
,
337 if ((phba
->cfg_fcp_class
== 2) &&
338 (sp
->cls2
.classValid
)) {
339 ndlp
->nlp_fcp_info
|= CLASS2
;
341 ndlp
->nlp_fcp_info
|= CLASS3
;
343 ndlp
->nlp_class_sup
= 0;
344 if (sp
->cls1
.classValid
)
345 ndlp
->nlp_class_sup
|= FC_COS_CLASS1
;
346 if (sp
->cls2
.classValid
)
347 ndlp
->nlp_class_sup
|= FC_COS_CLASS2
;
348 if (sp
->cls3
.classValid
)
349 ndlp
->nlp_class_sup
|= FC_COS_CLASS3
;
350 if (sp
->cls4
.classValid
)
351 ndlp
->nlp_class_sup
|= FC_COS_CLASS4
;
353 ((sp
->cmn
.bbRcvSizeMsb
& 0x0F) << 8) | sp
->cmn
.bbRcvSizeLsb
;
355 /* no need to reg_login if we are already in one of these states */
356 switch(ndlp
->nlp_state
) {
357 case NLP_STE_NPR_NODE
:
358 if (!(ndlp
->nlp_flag
& NLP_NPR_ADISC
))
360 case NLP_STE_REG_LOGIN_ISSUE
:
361 case NLP_STE_PRLI_ISSUE
:
362 case NLP_STE_UNMAPPED_NODE
:
363 case NLP_STE_MAPPED_NODE
:
364 lpfc_els_rsp_acc(phba
, ELS_CMD_PLOGI
, cmdiocb
, ndlp
, NULL
, 0);
368 if ((phba
->fc_flag
& FC_PT2PT
)
369 && !(phba
->fc_flag
& FC_PT2PT_PLOGI
)) {
370 /* rcv'ed PLOGI decides what our NPortId will be */
371 phba
->fc_myDID
= icmd
->un
.rcvels
.parmRo
;
372 mbox
= mempool_alloc(phba
->mbox_mem_pool
, GFP_KERNEL
);
375 lpfc_config_link(phba
, mbox
);
376 mbox
->mbox_cmpl
= lpfc_sli_def_mbox_cmpl
;
377 rc
= lpfc_sli_issue_mbox
378 (phba
, mbox
, (MBX_NOWAIT
| MBX_STOP_IOCB
));
379 if (rc
== MBX_NOT_FINISHED
) {
380 mempool_free( mbox
, phba
->mbox_mem_pool
);
384 lpfc_can_disctmo(phba
);
386 mbox
= mempool_alloc(phba
->mbox_mem_pool
, GFP_KERNEL
);
390 if (lpfc_reg_login(phba
, icmd
->un
.rcvels
.remoteID
,
391 (uint8_t *) sp
, mbox
, 0)) {
392 mempool_free( mbox
, phba
->mbox_mem_pool
);
396 /* ACC PLOGI rsp command needs to execute first,
397 * queue this mbox command to be processed later.
399 mbox
->mbox_cmpl
= lpfc_mbx_cmpl_reg_login
;
400 mbox
->context2
= ndlp
;
401 ndlp
->nlp_flag
|= NLP_ACC_REGLOGIN
;
403 /* If there is an outstanding PLOGI issued, abort it before
404 * sending ACC rsp to PLOGI recieved.
406 if (ndlp
->nlp_state
== NLP_STE_PLOGI_ISSUE
) {
407 /* software abort outstanding PLOGI */
408 lpfc_els_abort(phba
, ndlp
, 1);
410 ndlp
->nlp_flag
|= NLP_RCV_PLOGI
;
411 lpfc_els_rsp_acc(phba
, ELS_CMD_PLOGI
, cmdiocb
, ndlp
, mbox
, 0);
415 stat
.un
.b
.lsRjtRsnCode
= LSRJT_UNABLE_TPC
;
416 stat
.un
.b
.lsRjtRsnCodeExp
= LSEXP_OUT_OF_RESOURCE
;
417 lpfc_els_rsp_reject(phba
, stat
.un
.lsRjtError
, cmdiocb
, ndlp
);
422 lpfc_rcv_padisc(struct lpfc_hba
* phba
,
423 struct lpfc_nodelist
* ndlp
,
424 struct lpfc_iocbq
*cmdiocb
)
426 struct lpfc_dmabuf
*pcmd
;
427 struct serv_parm
*sp
;
428 struct lpfc_name
*pnn
, *ppn
;
435 pcmd
= (struct lpfc_dmabuf
*) cmdiocb
->context2
;
436 lp
= (uint32_t *) pcmd
->virt
;
439 if (cmd
== ELS_CMD_ADISC
) {
441 pnn
= (struct lpfc_name
*) & ap
->nodeName
;
442 ppn
= (struct lpfc_name
*) & ap
->portName
;
444 sp
= (struct serv_parm
*) lp
;
445 pnn
= (struct lpfc_name
*) & sp
->nodeName
;
446 ppn
= (struct lpfc_name
*) & sp
->portName
;
449 icmd
= &cmdiocb
->iocb
;
450 if ((icmd
->ulpStatus
== 0) &&
451 (lpfc_check_adisc(phba
, ndlp
, pnn
, ppn
))) {
452 if (cmd
== ELS_CMD_ADISC
) {
453 lpfc_els_rsp_adisc_acc(phba
, cmdiocb
, ndlp
);
456 lpfc_els_rsp_acc(phba
, ELS_CMD_PLOGI
, cmdiocb
, ndlp
,
461 /* Reject this request because invalid parameters */
462 stat
.un
.b
.lsRjtRsvd0
= 0;
463 stat
.un
.b
.lsRjtRsnCode
= LSRJT_UNABLE_TPC
;
464 stat
.un
.b
.lsRjtRsnCodeExp
= LSEXP_SPARM_OPTIONS
;
465 stat
.un
.b
.vendorUnique
= 0;
466 lpfc_els_rsp_reject(phba
, stat
.un
.lsRjtError
, cmdiocb
, ndlp
);
468 ndlp
->nlp_last_elscmd
= (unsigned long)ELS_CMD_PLOGI
;
470 mod_timer(&ndlp
->nlp_delayfunc
, jiffies
+ HZ
);
472 spin_lock_irq(phba
->host
->host_lock
);
473 ndlp
->nlp_flag
|= NLP_DELAY_TMO
;
474 spin_unlock_irq(phba
->host
->host_lock
);
475 ndlp
->nlp_state
= NLP_STE_NPR_NODE
;
476 lpfc_nlp_list(phba
, ndlp
, NLP_NPR_LIST
);
481 lpfc_rcv_logo(struct lpfc_hba
* phba
,
482 struct lpfc_nodelist
* ndlp
,
483 struct lpfc_iocbq
*cmdiocb
)
485 /* Put ndlp on NPR list with 1 sec timeout for plogi, ACC logo */
486 /* Only call LOGO ACC for first LOGO, this avoids sending unnecessary
487 * PLOGIs during LOGO storms from a device.
489 ndlp
->nlp_flag
|= NLP_LOGO_ACC
;
490 lpfc_els_rsp_acc(phba
, ELS_CMD_ACC
, cmdiocb
, ndlp
, NULL
, 0);
492 if (!(ndlp
->nlp_type
& NLP_FABRIC
)) {
493 /* Only try to re-login if this is NOT a Fabric Node */
494 ndlp
->nlp_last_elscmd
= (unsigned long)ELS_CMD_PLOGI
;
495 mod_timer(&ndlp
->nlp_delayfunc
, jiffies
+ HZ
* 1);
496 spin_lock_irq(phba
->host
->host_lock
);
497 ndlp
->nlp_flag
|= NLP_DELAY_TMO
;
498 spin_unlock_irq(phba
->host
->host_lock
);
501 ndlp
->nlp_state
= NLP_STE_NPR_NODE
;
502 lpfc_nlp_list(phba
, ndlp
, NLP_NPR_LIST
);
504 ndlp
->nlp_flag
&= ~NLP_NPR_ADISC
;
505 /* The driver has to wait until the ACC completes before it continues
506 * processing the LOGO. The action will resume in
507 * lpfc_cmpl_els_logo_acc routine. Since part of processing includes an
508 * unreg_login, the driver waits so the ACC does not get aborted.
514 lpfc_rcv_prli(struct lpfc_hba
* phba
,
515 struct lpfc_nodelist
* ndlp
,
516 struct lpfc_iocbq
*cmdiocb
)
518 struct lpfc_dmabuf
*pcmd
;
521 struct fc_rport
*rport
= ndlp
->rport
;
524 pcmd
= (struct lpfc_dmabuf
*) cmdiocb
->context2
;
525 lp
= (uint32_t *) pcmd
->virt
;
526 npr
= (PRLI
*) ((uint8_t *) lp
+ sizeof (uint32_t));
528 ndlp
->nlp_type
&= ~(NLP_FCP_TARGET
| NLP_FCP_INITIATOR
);
529 ndlp
->nlp_fcp_info
&= ~NLP_FCP_2_DEVICE
;
530 if ((npr
->acceptRspCode
== PRLI_REQ_EXECUTED
) &&
531 (npr
->prliType
== PRLI_FCP_TYPE
)) {
532 if (npr
->initiatorFunc
)
533 ndlp
->nlp_type
|= NLP_FCP_INITIATOR
;
535 ndlp
->nlp_type
|= NLP_FCP_TARGET
;
537 ndlp
->nlp_fcp_info
|= NLP_FCP_2_DEVICE
;
540 /* We need to update the rport role values */
541 roles
= FC_RPORT_ROLE_UNKNOWN
;
542 if (ndlp
->nlp_type
& NLP_FCP_INITIATOR
)
543 roles
|= FC_RPORT_ROLE_FCP_INITIATOR
;
544 if (ndlp
->nlp_type
& NLP_FCP_TARGET
)
545 roles
|= FC_RPORT_ROLE_FCP_TARGET
;
546 fc_remote_port_rolechg(rport
, roles
);
551 lpfc_disc_set_adisc(struct lpfc_hba
* phba
,
552 struct lpfc_nodelist
* ndlp
)
554 /* Check config parameter use-adisc or FCP-2 */
555 if ((phba
->cfg_use_adisc
== 0) &&
556 !(phba
->fc_flag
& FC_RSCN_MODE
)) {
557 if (!(ndlp
->nlp_fcp_info
& NLP_FCP_2_DEVICE
))
560 spin_lock_irq(phba
->host
->host_lock
);
561 ndlp
->nlp_flag
|= NLP_NPR_ADISC
;
562 spin_unlock_irq(phba
->host
->host_lock
);
567 lpfc_disc_noop(struct lpfc_hba
* phba
,
568 struct lpfc_nodelist
* ndlp
, void *arg
, uint32_t evt
)
570 /* This routine does nothing, just return the current state */
571 return (ndlp
->nlp_state
);
575 lpfc_disc_illegal(struct lpfc_hba
* phba
,
576 struct lpfc_nodelist
* ndlp
, void *arg
, uint32_t evt
)
578 lpfc_printf_log(phba
,
581 "%d:0253 Illegal State Transition: node x%x event x%x, "
582 "state x%x Data: x%x x%x\n",
584 ndlp
->nlp_DID
, evt
, ndlp
->nlp_state
, ndlp
->nlp_rpi
,
586 return (ndlp
->nlp_state
);
589 /* Start of Discovery State Machine routines */
592 lpfc_rcv_plogi_unused_node(struct lpfc_hba
* phba
,
593 struct lpfc_nodelist
* ndlp
, void *arg
, uint32_t evt
)
595 struct lpfc_iocbq
*cmdiocb
;
597 cmdiocb
= (struct lpfc_iocbq
*) arg
;
599 if (lpfc_rcv_plogi(phba
, ndlp
, cmdiocb
)) {
600 ndlp
->nlp_state
= NLP_STE_UNUSED_NODE
;
601 lpfc_nlp_list(phba
, ndlp
, NLP_UNUSED_LIST
);
602 return (ndlp
->nlp_state
);
604 lpfc_nlp_list(phba
, ndlp
, NLP_NO_LIST
);
605 return (NLP_STE_FREED_NODE
);
609 lpfc_rcv_els_unused_node(struct lpfc_hba
* phba
,
610 struct lpfc_nodelist
* ndlp
, void *arg
, uint32_t evt
)
612 lpfc_issue_els_logo(phba
, ndlp
, 0);
613 lpfc_nlp_list(phba
, ndlp
, NLP_UNUSED_LIST
);
614 return (ndlp
->nlp_state
);
618 lpfc_rcv_logo_unused_node(struct lpfc_hba
* phba
,
619 struct lpfc_nodelist
* ndlp
, void *arg
, uint32_t evt
)
621 struct lpfc_iocbq
*cmdiocb
;
623 cmdiocb
= (struct lpfc_iocbq
*) arg
;
625 spin_lock_irq(phba
->host
->host_lock
);
626 ndlp
->nlp_flag
|= NLP_LOGO_ACC
;
627 spin_unlock_irq(phba
->host
->host_lock
);
628 lpfc_els_rsp_acc(phba
, ELS_CMD_ACC
, cmdiocb
, ndlp
, NULL
, 0);
629 lpfc_nlp_list(phba
, ndlp
, NLP_UNUSED_LIST
);
631 return (ndlp
->nlp_state
);
635 lpfc_cmpl_logo_unused_node(struct lpfc_hba
* phba
,
636 struct lpfc_nodelist
* ndlp
, void *arg
, uint32_t evt
)
638 lpfc_nlp_list(phba
, ndlp
, NLP_NO_LIST
);
639 return (NLP_STE_FREED_NODE
);
643 lpfc_device_rm_unused_node(struct lpfc_hba
* phba
,
644 struct lpfc_nodelist
* ndlp
, void *arg
, uint32_t evt
)
646 lpfc_nlp_list(phba
, ndlp
, NLP_NO_LIST
);
647 return (NLP_STE_FREED_NODE
);
651 lpfc_rcv_plogi_plogi_issue(struct lpfc_hba
* phba
, struct lpfc_nodelist
* ndlp
,
652 void *arg
, uint32_t evt
)
654 struct lpfc_iocbq
*cmdiocb
= arg
;
655 struct lpfc_dmabuf
*pcmd
;
656 struct serv_parm
*sp
;
661 pcmd
= (struct lpfc_dmabuf
*) cmdiocb
->context2
;
662 lp
= (uint32_t *) pcmd
->virt
;
663 sp
= (struct serv_parm
*) ((uint8_t *) lp
+ sizeof (uint32_t));
665 memset(&stat
, 0, sizeof (struct ls_rjt
));
667 /* For a PLOGI, we only accept if our portname is less
668 * than the remote portname.
670 phba
->fc_stat
.elsLogiCol
++;
671 port_cmp
= memcmp(&phba
->fc_portname
, &sp
->portName
,
672 sizeof (struct lpfc_name
));
675 /* Reject this request because the remote node will accept
677 stat
.un
.b
.lsRjtRsnCode
= LSRJT_UNABLE_TPC
;
678 stat
.un
.b
.lsRjtRsnCodeExp
= LSEXP_CMD_IN_PROGRESS
;
679 lpfc_els_rsp_reject(phba
, stat
.un
.lsRjtError
, cmdiocb
, ndlp
);
682 lpfc_rcv_plogi(phba
, ndlp
, cmdiocb
);
683 } /* if our portname was less */
685 return (ndlp
->nlp_state
);
689 lpfc_rcv_els_plogi_issue(struct lpfc_hba
* phba
,
690 struct lpfc_nodelist
* ndlp
, void *arg
, uint32_t evt
)
692 struct lpfc_iocbq
*cmdiocb
;
694 cmdiocb
= (struct lpfc_iocbq
*) arg
;
696 /* software abort outstanding PLOGI */
697 lpfc_els_abort(phba
, ndlp
, 1);
698 mod_timer(&ndlp
->nlp_delayfunc
, jiffies
+ HZ
* 1);
699 spin_lock_irq(phba
->host
->host_lock
);
700 ndlp
->nlp_flag
|= NLP_DELAY_TMO
;
701 spin_unlock_irq(phba
->host
->host_lock
);
703 if (evt
== NLP_EVT_RCV_LOGO
) {
704 lpfc_els_rsp_acc(phba
, ELS_CMD_ACC
, cmdiocb
, ndlp
, NULL
, 0);
707 lpfc_issue_els_logo(phba
, ndlp
, 0);
710 /* Put ndlp in npr list set plogi timer for 1 sec */
711 ndlp
->nlp_last_elscmd
= (unsigned long)ELS_CMD_PLOGI
;
712 ndlp
->nlp_state
= NLP_STE_NPR_NODE
;
713 lpfc_nlp_list(phba
, ndlp
, NLP_NPR_LIST
);
715 return (ndlp
->nlp_state
);
719 lpfc_cmpl_plogi_plogi_issue(struct lpfc_hba
* phba
,
720 struct lpfc_nodelist
* ndlp
, void *arg
,
723 struct lpfc_iocbq
*cmdiocb
, *rspiocb
;
724 struct lpfc_dmabuf
*pcmd
, *prsp
;
727 struct serv_parm
*sp
;
730 cmdiocb
= (struct lpfc_iocbq
*) arg
;
731 rspiocb
= cmdiocb
->context_un
.rsp_iocb
;
733 if (ndlp
->nlp_flag
& NLP_ACC_REGLOGIN
) {
734 return (ndlp
->nlp_state
);
737 irsp
= &rspiocb
->iocb
;
742 pcmd
= (struct lpfc_dmabuf
*) cmdiocb
->context2
;
744 prsp
= list_get_first(&pcmd
->list
,
747 lp
= (uint32_t *) prsp
->virt
;
749 sp
= (struct serv_parm
*) ((uint8_t *) lp
+ sizeof (uint32_t));
750 if (!lpfc_check_sparm(phba
, ndlp
, sp
, CLASS3
))
753 /* PLOGI chkparm OK */
754 lpfc_printf_log(phba
,
757 "%d:0121 PLOGI chkparm OK "
758 "Data: x%x x%x x%x x%x\n",
760 ndlp
->nlp_DID
, ndlp
->nlp_state
,
761 ndlp
->nlp_flag
, ndlp
->nlp_rpi
);
763 if ((phba
->cfg_fcp_class
== 2) &&
764 (sp
->cls2
.classValid
)) {
765 ndlp
->nlp_fcp_info
|= CLASS2
;
767 ndlp
->nlp_fcp_info
|= CLASS3
;
769 ndlp
->nlp_class_sup
= 0;
770 if (sp
->cls1
.classValid
)
771 ndlp
->nlp_class_sup
|= FC_COS_CLASS1
;
772 if (sp
->cls2
.classValid
)
773 ndlp
->nlp_class_sup
|= FC_COS_CLASS2
;
774 if (sp
->cls3
.classValid
)
775 ndlp
->nlp_class_sup
|= FC_COS_CLASS3
;
776 if (sp
->cls4
.classValid
)
777 ndlp
->nlp_class_sup
|= FC_COS_CLASS4
;
779 ((sp
->cmn
.bbRcvSizeMsb
& 0x0F) << 8) |
780 sp
->cmn
.bbRcvSizeLsb
;
782 if (!(mbox
= mempool_alloc(phba
->mbox_mem_pool
,
786 lpfc_unreg_rpi(phba
, ndlp
);
788 (phba
, irsp
->un
.elsreq64
.remoteID
,
789 (uint8_t *) sp
, mbox
, 0) == 0) {
790 /* set_slim mailbox command needs to
791 * execute first, queue this command to
792 * be processed later.
794 switch(ndlp
->nlp_DID
) {
797 lpfc_mbx_cmpl_ns_reg_login
;
801 lpfc_mbx_cmpl_fdmi_reg_login
;
805 lpfc_mbx_cmpl_reg_login
;
807 mbox
->context2
= ndlp
;
808 if (lpfc_sli_issue_mbox(phba
, mbox
,
809 (MBX_NOWAIT
| MBX_STOP_IOCB
))
810 != MBX_NOT_FINISHED
) {
812 NLP_STE_REG_LOGIN_ISSUE
;
813 lpfc_nlp_list(phba
, ndlp
,
815 return (ndlp
->nlp_state
);
817 mempool_free(mbox
, phba
->mbox_mem_pool
);
819 mempool_free(mbox
, phba
->mbox_mem_pool
);
824 /* Free this node since the driver cannot login or has the wrong
826 lpfc_nlp_list(phba
, ndlp
, NLP_NO_LIST
);
827 return (NLP_STE_FREED_NODE
);
831 lpfc_device_rm_plogi_issue(struct lpfc_hba
* phba
,
832 struct lpfc_nodelist
* ndlp
, void *arg
, uint32_t evt
)
834 /* software abort outstanding PLOGI */
835 lpfc_els_abort(phba
, ndlp
, 1);
837 lpfc_nlp_list(phba
, ndlp
, NLP_NO_LIST
);
838 return (NLP_STE_FREED_NODE
);
842 lpfc_device_recov_plogi_issue(struct lpfc_hba
* phba
,
843 struct lpfc_nodelist
* ndlp
, void *arg
,
846 /* software abort outstanding PLOGI */
847 lpfc_els_abort(phba
, ndlp
, 1);
849 ndlp
->nlp_state
= NLP_STE_NPR_NODE
;
850 lpfc_nlp_list(phba
, ndlp
, NLP_NPR_LIST
);
851 spin_lock_irq(phba
->host
->host_lock
);
852 ndlp
->nlp_flag
&= ~NLP_NPR_2B_DISC
;
853 spin_unlock_irq(phba
->host
->host_lock
);
855 return (ndlp
->nlp_state
);
859 lpfc_rcv_plogi_adisc_issue(struct lpfc_hba
* phba
,
860 struct lpfc_nodelist
* ndlp
, void *arg
,
863 struct lpfc_iocbq
*cmdiocb
;
865 /* software abort outstanding ADISC */
866 lpfc_els_abort(phba
, ndlp
, 1);
868 cmdiocb
= (struct lpfc_iocbq
*) arg
;
870 if (lpfc_rcv_plogi(phba
, ndlp
, cmdiocb
)) {
871 return (ndlp
->nlp_state
);
873 ndlp
->nlp_state
= NLP_STE_PLOGI_ISSUE
;
874 lpfc_nlp_list(phba
, ndlp
, NLP_PLOGI_LIST
);
875 lpfc_issue_els_plogi(phba
, ndlp
, 0);
877 return (ndlp
->nlp_state
);
881 lpfc_rcv_prli_adisc_issue(struct lpfc_hba
* phba
,
882 struct lpfc_nodelist
* ndlp
, void *arg
,
885 struct lpfc_iocbq
*cmdiocb
;
887 cmdiocb
= (struct lpfc_iocbq
*) arg
;
889 lpfc_els_rsp_prli_acc(phba
, cmdiocb
, ndlp
);
890 return (ndlp
->nlp_state
);
894 lpfc_rcv_logo_adisc_issue(struct lpfc_hba
* phba
,
895 struct lpfc_nodelist
* ndlp
, void *arg
,
898 struct lpfc_iocbq
*cmdiocb
;
900 cmdiocb
= (struct lpfc_iocbq
*) arg
;
902 /* software abort outstanding ADISC */
903 lpfc_els_abort(phba
, ndlp
, 0);
905 lpfc_rcv_logo(phba
, ndlp
, cmdiocb
);
906 return (ndlp
->nlp_state
);
910 lpfc_rcv_padisc_adisc_issue(struct lpfc_hba
* phba
,
911 struct lpfc_nodelist
* ndlp
, void *arg
,
914 struct lpfc_iocbq
*cmdiocb
;
916 cmdiocb
= (struct lpfc_iocbq
*) arg
;
918 lpfc_rcv_padisc(phba
, ndlp
, cmdiocb
);
919 return (ndlp
->nlp_state
);
923 lpfc_rcv_prlo_adisc_issue(struct lpfc_hba
* phba
,
924 struct lpfc_nodelist
* ndlp
, void *arg
,
927 struct lpfc_iocbq
*cmdiocb
;
929 cmdiocb
= (struct lpfc_iocbq
*) arg
;
931 /* Treat like rcv logo */
932 lpfc_rcv_logo(phba
, ndlp
, cmdiocb
);
933 return (ndlp
->nlp_state
);
937 lpfc_cmpl_adisc_adisc_issue(struct lpfc_hba
* phba
,
938 struct lpfc_nodelist
* ndlp
, void *arg
,
941 struct lpfc_iocbq
*cmdiocb
, *rspiocb
;
945 cmdiocb
= (struct lpfc_iocbq
*) arg
;
946 rspiocb
= cmdiocb
->context_un
.rsp_iocb
;
948 ap
= (ADISC
*)lpfc_check_elscmpl_iocb(phba
, cmdiocb
, rspiocb
);
949 irsp
= &rspiocb
->iocb
;
951 if ((irsp
->ulpStatus
) ||
952 (!lpfc_check_adisc(phba
, ndlp
, &ap
->nodeName
, &ap
->portName
))) {
953 ndlp
->nlp_last_elscmd
= (unsigned long)ELS_CMD_PLOGI
;
955 mod_timer(&ndlp
->nlp_delayfunc
, jiffies
+ HZ
);
956 spin_lock_irq(phba
->host
->host_lock
);
957 ndlp
->nlp_flag
|= NLP_DELAY_TMO
;
958 spin_unlock_irq(phba
->host
->host_lock
);
960 memset(&ndlp
->nlp_nodename
, 0, sizeof (struct lpfc_name
));
961 memset(&ndlp
->nlp_portname
, 0, sizeof (struct lpfc_name
));
963 ndlp
->nlp_state
= NLP_STE_NPR_NODE
;
964 lpfc_nlp_list(phba
, ndlp
, NLP_NPR_LIST
);
965 lpfc_unreg_rpi(phba
, ndlp
);
966 return (ndlp
->nlp_state
);
968 if (ndlp
->nlp_type
& NLP_FCP_TARGET
) {
969 ndlp
->nlp_state
= NLP_STE_MAPPED_NODE
;
970 lpfc_nlp_list(phba
, ndlp
, NLP_MAPPED_LIST
);
972 ndlp
->nlp_state
= NLP_STE_UNMAPPED_NODE
;
973 lpfc_nlp_list(phba
, ndlp
, NLP_UNMAPPED_LIST
);
975 return (ndlp
->nlp_state
);
979 lpfc_device_rm_adisc_issue(struct lpfc_hba
* phba
,
980 struct lpfc_nodelist
* ndlp
, void *arg
,
983 /* software abort outstanding ADISC */
984 lpfc_els_abort(phba
, ndlp
, 1);
986 lpfc_nlp_list(phba
, ndlp
, NLP_NO_LIST
);
987 return (NLP_STE_FREED_NODE
);
991 lpfc_device_recov_adisc_issue(struct lpfc_hba
* phba
,
992 struct lpfc_nodelist
* ndlp
, void *arg
,
995 /* software abort outstanding ADISC */
996 lpfc_els_abort(phba
, ndlp
, 1);
998 ndlp
->nlp_state
= NLP_STE_NPR_NODE
;
999 lpfc_nlp_list(phba
, ndlp
, NLP_NPR_LIST
);
1000 spin_lock_irq(phba
->host
->host_lock
);
1001 ndlp
->nlp_flag
&= ~NLP_NPR_2B_DISC
;
1002 spin_unlock_irq(phba
->host
->host_lock
);
1004 lpfc_disc_set_adisc(phba
, ndlp
);
1005 return (ndlp
->nlp_state
);
1009 lpfc_rcv_plogi_reglogin_issue(struct lpfc_hba
* phba
,
1010 struct lpfc_nodelist
* ndlp
, void *arg
,
1013 struct lpfc_iocbq
*cmdiocb
;
1015 cmdiocb
= (struct lpfc_iocbq
*) arg
;
1017 lpfc_rcv_plogi(phba
, ndlp
, cmdiocb
);
1018 return (ndlp
->nlp_state
);
1022 lpfc_rcv_prli_reglogin_issue(struct lpfc_hba
* phba
,
1023 struct lpfc_nodelist
* ndlp
, void *arg
,
1026 struct lpfc_iocbq
*cmdiocb
;
1028 cmdiocb
= (struct lpfc_iocbq
*) arg
;
1030 lpfc_els_rsp_prli_acc(phba
, cmdiocb
, ndlp
);
1031 return (ndlp
->nlp_state
);
1035 lpfc_rcv_logo_reglogin_issue(struct lpfc_hba
* phba
,
1036 struct lpfc_nodelist
* ndlp
, void *arg
,
1039 struct lpfc_iocbq
*cmdiocb
;
1041 cmdiocb
= (struct lpfc_iocbq
*) arg
;
1043 lpfc_rcv_logo(phba
, ndlp
, cmdiocb
);
1044 return (ndlp
->nlp_state
);
1048 lpfc_rcv_padisc_reglogin_issue(struct lpfc_hba
* phba
,
1049 struct lpfc_nodelist
* ndlp
, void *arg
,
1052 struct lpfc_iocbq
*cmdiocb
;
1054 cmdiocb
= (struct lpfc_iocbq
*) arg
;
1056 lpfc_rcv_padisc(phba
, ndlp
, cmdiocb
);
1057 return (ndlp
->nlp_state
);
1061 lpfc_rcv_prlo_reglogin_issue(struct lpfc_hba
* phba
,
1062 struct lpfc_nodelist
* ndlp
, void *arg
,
1065 struct lpfc_iocbq
*cmdiocb
;
1067 cmdiocb
= (struct lpfc_iocbq
*) arg
;
1068 lpfc_els_rsp_acc(phba
, ELS_CMD_ACC
, cmdiocb
, ndlp
, NULL
, 0);
1069 return (ndlp
->nlp_state
);
1073 lpfc_cmpl_reglogin_reglogin_issue(struct lpfc_hba
* phba
,
1074 struct lpfc_nodelist
* ndlp
,
1075 void *arg
, uint32_t evt
)
1081 pmb
= (LPFC_MBOXQ_t
*) arg
;
1083 did
= mb
->un
.varWords
[1];
1084 if (mb
->mbxStatus
) {
1085 /* RegLogin failed */
1086 lpfc_printf_log(phba
,
1089 "%d:0246 RegLogin failed Data: x%x x%x x%x\n",
1091 did
, mb
->mbxStatus
, phba
->hba_state
);
1093 mod_timer(&ndlp
->nlp_delayfunc
, jiffies
+ HZ
* 1);
1094 spin_lock_irq(phba
->host
->host_lock
);
1095 ndlp
->nlp_flag
|= NLP_DELAY_TMO
;
1096 spin_unlock_irq(phba
->host
->host_lock
);
1098 lpfc_issue_els_logo(phba
, ndlp
, 0);
1099 /* Put ndlp in npr list set plogi timer for 1 sec */
1100 ndlp
->nlp_last_elscmd
= (unsigned long)ELS_CMD_PLOGI
;
1101 ndlp
->nlp_state
= NLP_STE_NPR_NODE
;
1102 lpfc_nlp_list(phba
, ndlp
, NLP_NPR_LIST
);
1103 return (ndlp
->nlp_state
);
1106 ndlp
->nlp_rpi
= mb
->un
.varWords
[0];
1108 /* Only if we are not a fabric nport do we issue PRLI */
1109 if (!(ndlp
->nlp_type
& NLP_FABRIC
)) {
1110 ndlp
->nlp_state
= NLP_STE_PRLI_ISSUE
;
1111 lpfc_nlp_list(phba
, ndlp
, NLP_PRLI_LIST
);
1112 lpfc_issue_els_prli(phba
, ndlp
, 0);
1114 ndlp
->nlp_state
= NLP_STE_UNMAPPED_NODE
;
1115 lpfc_nlp_list(phba
, ndlp
, NLP_UNMAPPED_LIST
);
1117 return (ndlp
->nlp_state
);
1121 lpfc_device_rm_reglogin_issue(struct lpfc_hba
* phba
,
1122 struct lpfc_nodelist
* ndlp
, void *arg
,
1125 lpfc_nlp_list(phba
, ndlp
, NLP_NO_LIST
);
1126 return (NLP_STE_FREED_NODE
);
1130 lpfc_device_recov_reglogin_issue(struct lpfc_hba
* phba
,
1131 struct lpfc_nodelist
* ndlp
, void *arg
,
1134 ndlp
->nlp_state
= NLP_STE_NPR_NODE
;
1135 lpfc_nlp_list(phba
, ndlp
, NLP_NPR_LIST
);
1136 spin_lock_irq(phba
->host
->host_lock
);
1137 ndlp
->nlp_flag
&= ~NLP_NPR_2B_DISC
;
1138 spin_unlock_irq(phba
->host
->host_lock
);
1139 return (ndlp
->nlp_state
);
1143 lpfc_rcv_plogi_prli_issue(struct lpfc_hba
* phba
,
1144 struct lpfc_nodelist
* ndlp
, void *arg
, uint32_t evt
)
1146 struct lpfc_iocbq
*cmdiocb
;
1148 cmdiocb
= (struct lpfc_iocbq
*) arg
;
1150 lpfc_rcv_plogi(phba
, ndlp
, cmdiocb
);
1151 return (ndlp
->nlp_state
);
1155 lpfc_rcv_prli_prli_issue(struct lpfc_hba
* phba
,
1156 struct lpfc_nodelist
* ndlp
, void *arg
, uint32_t evt
)
1158 struct lpfc_iocbq
*cmdiocb
;
1160 cmdiocb
= (struct lpfc_iocbq
*) arg
;
1162 lpfc_els_rsp_prli_acc(phba
, cmdiocb
, ndlp
);
1163 return (ndlp
->nlp_state
);
1167 lpfc_rcv_logo_prli_issue(struct lpfc_hba
* phba
,
1168 struct lpfc_nodelist
* ndlp
, void *arg
, uint32_t evt
)
1170 struct lpfc_iocbq
*cmdiocb
;
1172 cmdiocb
= (struct lpfc_iocbq
*) arg
;
1174 /* Software abort outstanding PRLI before sending acc */
1175 lpfc_els_abort(phba
, ndlp
, 1);
1177 lpfc_rcv_logo(phba
, ndlp
, cmdiocb
);
1178 return (ndlp
->nlp_state
);
1182 lpfc_rcv_padisc_prli_issue(struct lpfc_hba
* phba
,
1183 struct lpfc_nodelist
* ndlp
, void *arg
, uint32_t evt
)
1185 struct lpfc_iocbq
*cmdiocb
;
1187 cmdiocb
= (struct lpfc_iocbq
*) arg
;
1189 lpfc_rcv_padisc(phba
, ndlp
, cmdiocb
);
1190 return (ndlp
->nlp_state
);
1193 /* This routine is envoked when we rcv a PRLO request from a nport
1194 * we are logged into. We should send back a PRLO rsp setting the
1196 * NEXT STATE = PRLI_ISSUE
1199 lpfc_rcv_prlo_prli_issue(struct lpfc_hba
* phba
,
1200 struct lpfc_nodelist
* ndlp
, void *arg
, uint32_t evt
)
1202 struct lpfc_iocbq
*cmdiocb
;
1204 cmdiocb
= (struct lpfc_iocbq
*) arg
;
1205 lpfc_els_rsp_acc(phba
, ELS_CMD_ACC
, cmdiocb
, ndlp
, NULL
, 0);
1206 return (ndlp
->nlp_state
);
1210 lpfc_cmpl_prli_prli_issue(struct lpfc_hba
* phba
,
1211 struct lpfc_nodelist
* ndlp
, void *arg
, uint32_t evt
)
1213 struct lpfc_iocbq
*cmdiocb
, *rspiocb
;
1217 cmdiocb
= (struct lpfc_iocbq
*) arg
;
1218 rspiocb
= cmdiocb
->context_un
.rsp_iocb
;
1219 npr
= (PRLI
*)lpfc_check_elscmpl_iocb(phba
, cmdiocb
, rspiocb
);
1221 irsp
= &rspiocb
->iocb
;
1222 if (irsp
->ulpStatus
) {
1223 ndlp
->nlp_state
= NLP_STE_UNMAPPED_NODE
;
1224 lpfc_nlp_list(phba
, ndlp
, NLP_UNMAPPED_LIST
);
1225 return (ndlp
->nlp_state
);
1228 /* Check out PRLI rsp */
1229 ndlp
->nlp_type
&= ~(NLP_FCP_TARGET
| NLP_FCP_INITIATOR
);
1230 ndlp
->nlp_fcp_info
&= ~NLP_FCP_2_DEVICE
;
1231 if ((npr
->acceptRspCode
== PRLI_REQ_EXECUTED
) &&
1232 (npr
->prliType
== PRLI_FCP_TYPE
)) {
1233 if (npr
->initiatorFunc
)
1234 ndlp
->nlp_type
|= NLP_FCP_INITIATOR
;
1235 if (npr
->targetFunc
)
1236 ndlp
->nlp_type
|= NLP_FCP_TARGET
;
1238 ndlp
->nlp_fcp_info
|= NLP_FCP_2_DEVICE
;
1241 ndlp
->nlp_state
= NLP_STE_MAPPED_NODE
;
1242 lpfc_nlp_list(phba
, ndlp
, NLP_MAPPED_LIST
);
1243 return (ndlp
->nlp_state
);
1246 /*! lpfc_device_rm_prli_issue
1257 * This routine is envoked when we a request to remove a nport we are in the
1258 * process of PRLIing. We should software abort outstanding prli, unreg
1259 * login, send a logout. We will change node state to UNUSED_NODE, put it
1260 * on plogi list so it can be freed when LOGO completes.
1264 lpfc_device_rm_prli_issue(struct lpfc_hba
* phba
,
1265 struct lpfc_nodelist
* ndlp
, void *arg
, uint32_t evt
)
1267 /* software abort outstanding PRLI */
1268 lpfc_els_abort(phba
, ndlp
, 1);
1270 lpfc_nlp_list(phba
, ndlp
, NLP_NO_LIST
);
1271 return (NLP_STE_FREED_NODE
);
1275 /*! lpfc_device_recov_prli_issue
1286 * The routine is envoked when the state of a device is unknown, like
1287 * during a link down. We should remove the nodelist entry from the
1288 * unmapped list, issue a UNREG_LOGIN, do a software abort of the
1289 * outstanding PRLI command, then free the node entry.
1292 lpfc_device_recov_prli_issue(struct lpfc_hba
* phba
,
1293 struct lpfc_nodelist
* ndlp
, void *arg
, uint32_t evt
)
1295 /* software abort outstanding PRLI */
1296 lpfc_els_abort(phba
, ndlp
, 1);
1298 ndlp
->nlp_state
= NLP_STE_NPR_NODE
;
1299 lpfc_nlp_list(phba
, ndlp
, NLP_NPR_LIST
);
1300 spin_lock_irq(phba
->host
->host_lock
);
1301 ndlp
->nlp_flag
&= ~NLP_NPR_2B_DISC
;
1302 spin_unlock_irq(phba
->host
->host_lock
);
1303 return (ndlp
->nlp_state
);
1307 lpfc_rcv_plogi_unmap_node(struct lpfc_hba
* phba
,
1308 struct lpfc_nodelist
* ndlp
, void *arg
, uint32_t evt
)
1310 struct lpfc_iocbq
*cmdiocb
;
1312 cmdiocb
= (struct lpfc_iocbq
*) arg
;
1314 lpfc_rcv_plogi(phba
, ndlp
, cmdiocb
);
1315 return (ndlp
->nlp_state
);
1319 lpfc_rcv_prli_unmap_node(struct lpfc_hba
* phba
,
1320 struct lpfc_nodelist
* ndlp
, void *arg
, uint32_t evt
)
1322 struct lpfc_iocbq
*cmdiocb
;
1324 cmdiocb
= (struct lpfc_iocbq
*) arg
;
1326 lpfc_rcv_prli(phba
, ndlp
, cmdiocb
);
1327 lpfc_els_rsp_prli_acc(phba
, cmdiocb
, ndlp
);
1328 return (ndlp
->nlp_state
);
1332 lpfc_rcv_logo_unmap_node(struct lpfc_hba
* phba
,
1333 struct lpfc_nodelist
* ndlp
, void *arg
, uint32_t evt
)
1335 struct lpfc_iocbq
*cmdiocb
;
1337 cmdiocb
= (struct lpfc_iocbq
*) arg
;
1339 lpfc_rcv_logo(phba
, ndlp
, cmdiocb
);
1340 return (ndlp
->nlp_state
);
1344 lpfc_rcv_padisc_unmap_node(struct lpfc_hba
* phba
,
1345 struct lpfc_nodelist
* ndlp
, void *arg
, uint32_t evt
)
1347 struct lpfc_iocbq
*cmdiocb
;
1349 cmdiocb
= (struct lpfc_iocbq
*) arg
;
1351 lpfc_rcv_padisc(phba
, ndlp
, cmdiocb
);
1352 return (ndlp
->nlp_state
);
1356 lpfc_rcv_prlo_unmap_node(struct lpfc_hba
* phba
,
1357 struct lpfc_nodelist
* ndlp
, void *arg
, uint32_t evt
)
1359 struct lpfc_iocbq
*cmdiocb
;
1361 cmdiocb
= (struct lpfc_iocbq
*) arg
;
1363 /* Treat like rcv logo */
1364 lpfc_rcv_logo(phba
, ndlp
, cmdiocb
);
1365 return (ndlp
->nlp_state
);
1369 lpfc_device_recov_unmap_node(struct lpfc_hba
* phba
,
1370 struct lpfc_nodelist
* ndlp
, void *arg
, uint32_t evt
)
1372 ndlp
->nlp_state
= NLP_STE_NPR_NODE
;
1373 lpfc_nlp_list(phba
, ndlp
, NLP_NPR_LIST
);
1374 ndlp
->nlp_flag
&= ~NLP_NPR_2B_DISC
;
1375 lpfc_disc_set_adisc(phba
, ndlp
);
1377 return (ndlp
->nlp_state
);
1381 lpfc_rcv_plogi_mapped_node(struct lpfc_hba
* phba
,
1382 struct lpfc_nodelist
* ndlp
, void *arg
, uint32_t evt
)
1384 struct lpfc_iocbq
*cmdiocb
;
1386 cmdiocb
= (struct lpfc_iocbq
*) arg
;
1388 lpfc_rcv_plogi(phba
, ndlp
, cmdiocb
);
1389 return (ndlp
->nlp_state
);
1393 lpfc_rcv_prli_mapped_node(struct lpfc_hba
* phba
,
1394 struct lpfc_nodelist
* ndlp
, void *arg
, uint32_t evt
)
1396 struct lpfc_iocbq
*cmdiocb
;
1398 cmdiocb
= (struct lpfc_iocbq
*) arg
;
1400 lpfc_els_rsp_prli_acc(phba
, cmdiocb
, ndlp
);
1401 return (ndlp
->nlp_state
);
1405 lpfc_rcv_logo_mapped_node(struct lpfc_hba
* phba
,
1406 struct lpfc_nodelist
* ndlp
, void *arg
, uint32_t evt
)
1408 struct lpfc_iocbq
*cmdiocb
;
1410 cmdiocb
= (struct lpfc_iocbq
*) arg
;
1412 lpfc_rcv_logo(phba
, ndlp
, cmdiocb
);
1413 return (ndlp
->nlp_state
);
1417 lpfc_rcv_padisc_mapped_node(struct lpfc_hba
* phba
,
1418 struct lpfc_nodelist
* ndlp
, void *arg
,
1421 struct lpfc_iocbq
*cmdiocb
;
1423 cmdiocb
= (struct lpfc_iocbq
*) arg
;
1425 lpfc_rcv_padisc(phba
, ndlp
, cmdiocb
);
1426 return (ndlp
->nlp_state
);
1430 lpfc_rcv_prlo_mapped_node(struct lpfc_hba
* phba
,
1431 struct lpfc_nodelist
* ndlp
, void *arg
, uint32_t evt
)
1433 struct lpfc_iocbq
*cmdiocb
;
1435 cmdiocb
= (struct lpfc_iocbq
*) arg
;
1437 /* flush the target */
1438 spin_lock_irq(phba
->host
->host_lock
);
1439 lpfc_sli_abort_iocb(phba
, &phba
->sli
.ring
[phba
->sli
.fcp_ring
],
1440 ndlp
->nlp_sid
, 0, 0, LPFC_CTX_TGT
);
1441 spin_unlock_irq(phba
->host
->host_lock
);
1443 /* Treat like rcv logo */
1444 lpfc_rcv_logo(phba
, ndlp
, cmdiocb
);
1445 return (ndlp
->nlp_state
);
1449 lpfc_device_recov_mapped_node(struct lpfc_hba
* phba
,
1450 struct lpfc_nodelist
* ndlp
, void *arg
,
1453 ndlp
->nlp_state
= NLP_STE_NPR_NODE
;
1454 lpfc_nlp_list(phba
, ndlp
, NLP_NPR_LIST
);
1455 spin_lock_irq(phba
->host
->host_lock
);
1456 ndlp
->nlp_flag
&= ~NLP_NPR_2B_DISC
;
1457 spin_unlock_irq(phba
->host
->host_lock
);
1458 lpfc_disc_set_adisc(phba
, ndlp
);
1459 return (ndlp
->nlp_state
);
1463 lpfc_rcv_plogi_npr_node(struct lpfc_hba
* phba
,
1464 struct lpfc_nodelist
* ndlp
, void *arg
,
1467 struct lpfc_iocbq
*cmdiocb
;
1469 cmdiocb
= (struct lpfc_iocbq
*) arg
;
1471 /* Ignore PLOGI if we have an outstanding LOGO */
1472 if (ndlp
->nlp_flag
& NLP_LOGO_SND
) {
1473 return (ndlp
->nlp_state
);
1476 if (lpfc_rcv_plogi(phba
, ndlp
, cmdiocb
)) {
1477 spin_lock_irq(phba
->host
->host_lock
);
1478 ndlp
->nlp_flag
&= ~(NLP_NPR_ADISC
| NLP_NPR_2B_DISC
);
1479 spin_unlock_irq(phba
->host
->host_lock
);
1480 return (ndlp
->nlp_state
);
1483 /* send PLOGI immediately, move to PLOGI issue state */
1484 if (!(ndlp
->nlp_flag
& NLP_DELAY_TMO
)) {
1485 ndlp
->nlp_state
= NLP_STE_PLOGI_ISSUE
;
1486 lpfc_nlp_list(phba
, ndlp
, NLP_PLOGI_LIST
);
1487 lpfc_issue_els_plogi(phba
, ndlp
, 0);
1489 return (ndlp
->nlp_state
);
1493 lpfc_rcv_prli_npr_node(struct lpfc_hba
* phba
,
1494 struct lpfc_nodelist
* ndlp
, void *arg
,
1497 struct lpfc_iocbq
*cmdiocb
;
1500 cmdiocb
= (struct lpfc_iocbq
*) arg
;
1502 memset(&stat
, 0, sizeof (struct ls_rjt
));
1503 stat
.un
.b
.lsRjtRsnCode
= LSRJT_UNABLE_TPC
;
1504 stat
.un
.b
.lsRjtRsnCodeExp
= LSEXP_NOTHING_MORE
;
1505 lpfc_els_rsp_reject(phba
, stat
.un
.lsRjtError
, cmdiocb
, ndlp
);
1507 if (!(ndlp
->nlp_flag
& NLP_DELAY_TMO
)) {
1508 if (ndlp
->nlp_flag
& NLP_NPR_ADISC
) {
1509 ndlp
->nlp_state
= NLP_STE_ADISC_ISSUE
;
1510 lpfc_nlp_list(phba
, ndlp
, NLP_ADISC_LIST
);
1511 lpfc_issue_els_adisc(phba
, ndlp
, 0);
1513 ndlp
->nlp_state
= NLP_STE_PLOGI_ISSUE
;
1514 lpfc_nlp_list(phba
, ndlp
, NLP_PLOGI_LIST
);
1515 lpfc_issue_els_plogi(phba
, ndlp
, 0);
1518 return (ndlp
->nlp_state
);
1522 lpfc_rcv_logo_npr_node(struct lpfc_hba
* phba
,
1523 struct lpfc_nodelist
* ndlp
, void *arg
,
1526 struct lpfc_iocbq
*cmdiocb
;
1528 cmdiocb
= (struct lpfc_iocbq
*) arg
;
1530 lpfc_rcv_logo(phba
, ndlp
, cmdiocb
);
1531 return (ndlp
->nlp_state
);
1535 lpfc_rcv_padisc_npr_node(struct lpfc_hba
* phba
,
1536 struct lpfc_nodelist
* ndlp
, void *arg
,
1539 struct lpfc_iocbq
*cmdiocb
;
1541 cmdiocb
= (struct lpfc_iocbq
*) arg
;
1543 lpfc_rcv_padisc(phba
, ndlp
, cmdiocb
);
1545 if (!(ndlp
->nlp_flag
& NLP_DELAY_TMO
)) {
1546 if (ndlp
->nlp_flag
& NLP_NPR_ADISC
) {
1547 ndlp
->nlp_state
= NLP_STE_ADISC_ISSUE
;
1548 lpfc_nlp_list(phba
, ndlp
, NLP_ADISC_LIST
);
1549 lpfc_issue_els_adisc(phba
, ndlp
, 0);
1551 ndlp
->nlp_state
= NLP_STE_PLOGI_ISSUE
;
1552 lpfc_nlp_list(phba
, ndlp
, NLP_PLOGI_LIST
);
1553 lpfc_issue_els_plogi(phba
, ndlp
, 0);
1556 return (ndlp
->nlp_state
);
1560 lpfc_rcv_prlo_npr_node(struct lpfc_hba
* phba
,
1561 struct lpfc_nodelist
* ndlp
, void *arg
,
1564 struct lpfc_iocbq
*cmdiocb
;
1566 cmdiocb
= (struct lpfc_iocbq
*) arg
;
1568 lpfc_els_rsp_acc(phba
, ELS_CMD_ACC
, cmdiocb
, ndlp
, NULL
, 0);
1570 if (ndlp
->nlp_flag
& NLP_DELAY_TMO
) {
1571 if (ndlp
->nlp_last_elscmd
== (unsigned long)ELS_CMD_PLOGI
) {
1572 return (ndlp
->nlp_state
);
1574 spin_lock_irq(phba
->host
->host_lock
);
1575 ndlp
->nlp_flag
&= ~NLP_DELAY_TMO
;
1576 spin_unlock_irq(phba
->host
->host_lock
);
1577 del_timer_sync(&ndlp
->nlp_delayfunc
);
1578 if (!list_empty(&ndlp
->els_retry_evt
.evt_listp
))
1579 list_del_init(&ndlp
->els_retry_evt
.evt_listp
);
1583 ndlp
->nlp_state
= NLP_STE_PLOGI_ISSUE
;
1584 lpfc_nlp_list(phba
, ndlp
, NLP_PLOGI_LIST
);
1585 lpfc_issue_els_plogi(phba
, ndlp
, 0);
1586 return (ndlp
->nlp_state
);
1590 lpfc_cmpl_logo_npr_node(struct lpfc_hba
* phba
,
1591 struct lpfc_nodelist
* ndlp
, void *arg
, uint32_t evt
)
1593 lpfc_unreg_rpi(phba
, ndlp
);
1594 /* This routine does nothing, just return the current state */
1595 return (ndlp
->nlp_state
);
1599 lpfc_cmpl_reglogin_npr_node(struct lpfc_hba
* phba
,
1600 struct lpfc_nodelist
* ndlp
, void *arg
,
1606 pmb
= (LPFC_MBOXQ_t
*) arg
;
1609 ndlp
->nlp_rpi
= mb
->un
.varWords
[0];
1611 return (ndlp
->nlp_state
);
1615 lpfc_device_rm_npr_node(struct lpfc_hba
* phba
,
1616 struct lpfc_nodelist
* ndlp
, void *arg
,
1619 lpfc_nlp_list(phba
, ndlp
, NLP_NO_LIST
);
1620 return (NLP_STE_FREED_NODE
);
1624 lpfc_device_recov_npr_node(struct lpfc_hba
* phba
,
1625 struct lpfc_nodelist
* ndlp
, void *arg
,
1628 spin_lock_irq(phba
->host
->host_lock
);
1629 ndlp
->nlp_flag
&= ~NLP_NPR_2B_DISC
;
1630 spin_unlock_irq(phba
->host
->host_lock
);
1631 return (ndlp
->nlp_state
);
1635 /* This next section defines the NPort Discovery State Machine */
1637 /* There are 4 different double linked lists nodelist entries can reside on.
1638 * The plogi list and adisc list are used when Link Up discovery or RSCN
1639 * processing is needed. Each list holds the nodes that we will send PLOGI
1640 * or ADISC on. These lists will keep track of what nodes will be effected
1641 * by an RSCN, or a Link Up (Typically, all nodes are effected on Link Up).
1642 * The unmapped_list will contain all nodes that we have successfully logged
1643 * into at the Fibre Channel level. The mapped_list will contain all nodes
1644 * that are mapped FCP targets.
1647 * The bind list is a list of undiscovered (potentially non-existent) nodes
1648 * that we have saved binding information on. This information is used when
1649 * nodes transition from the unmapped to the mapped list.
1651 /* For UNUSED_NODE state, the node has just been allocated .
1652 * For PLOGI_ISSUE and REG_LOGIN_ISSUE, the node is on
1653 * the PLOGI list. For REG_LOGIN_COMPL, the node is taken off the PLOGI list
1654 * and put on the unmapped list. For ADISC processing, the node is taken off
1655 * the ADISC list and placed on either the mapped or unmapped list (depending
1656 * on its previous state). Once on the unmapped list, a PRLI is issued and the
1657 * state changed to PRLI_ISSUE. When the PRLI completion occurs, the state is
1658 * changed to UNMAPPED_NODE. If the completion indicates a mapped
1659 * node, the node is taken off the unmapped list. The binding list is checked
1660 * for a valid binding, or a binding is automatically assigned. If binding
1661 * assignment is unsuccessful, the node is left on the unmapped list. If
1662 * binding assignment is successful, the associated binding list entry (if
1663 * any) is removed, and the node is placed on the mapped list.
1666 * For a Link Down, all nodes on the ADISC, PLOGI, unmapped or mapped
1667 * lists will receive a DEVICE_RECOVERY event. If the linkdown or nodev timers
1668 * expire, all effected nodes will receive a DEVICE_RM event.
1671 * For a Link Up or RSCN, all nodes will move from the mapped / unmapped lists
1672 * to either the ADISC or PLOGI list. After a Nameserver query or ALPA loopmap
1673 * check, additional nodes may be added or removed (via DEVICE_RM) to / from
1674 * the PLOGI or ADISC lists. Once the PLOGI and ADISC lists are populated,
1675 * we will first process the ADISC list. 32 entries are processed initially and
1676 * ADISC is initited for each one. Completions / Events for each node are
1677 * funnelled thru the state machine. As each node finishes ADISC processing, it
1678 * starts ADISC for any nodes waiting for ADISC processing. If no nodes are
1679 * waiting, and the ADISC list count is identically 0, then we are done. For
1680 * Link Up discovery, since all nodes on the PLOGI list are UNREG_LOGIN'ed, we
1681 * can issue a CLEAR_LA and reenable Link Events. Next we will process the PLOGI
1682 * list. 32 entries are processed initially and PLOGI is initited for each one.
1683 * Completions / Events for each node are funnelled thru the state machine. As
1684 * each node finishes PLOGI processing, it starts PLOGI for any nodes waiting
1685 * for PLOGI processing. If no nodes are waiting, and the PLOGI list count is
1686 * indentically 0, then we are done. We have now completed discovery / RSCN
1687 * handling. Upon completion, ALL nodes should be on either the mapped or
1691 static uint32_t (*lpfc_disc_action
[NLP_STE_MAX_STATE
* NLP_EVT_MAX_EVENT
])
1692 (struct lpfc_hba
*, struct lpfc_nodelist
*, void *, uint32_t) = {
1693 /* Action routine Event Current State */
1694 lpfc_rcv_plogi_unused_node
, /* RCV_PLOGI UNUSED_NODE */
1695 lpfc_rcv_els_unused_node
, /* RCV_PRLI */
1696 lpfc_rcv_logo_unused_node
, /* RCV_LOGO */
1697 lpfc_rcv_els_unused_node
, /* RCV_ADISC */
1698 lpfc_rcv_els_unused_node
, /* RCV_PDISC */
1699 lpfc_rcv_els_unused_node
, /* RCV_PRLO */
1700 lpfc_disc_illegal
, /* CMPL_PLOGI */
1701 lpfc_disc_illegal
, /* CMPL_PRLI */
1702 lpfc_cmpl_logo_unused_node
, /* CMPL_LOGO */
1703 lpfc_disc_illegal
, /* CMPL_ADISC */
1704 lpfc_disc_illegal
, /* CMPL_REG_LOGIN */
1705 lpfc_device_rm_unused_node
, /* DEVICE_RM */
1706 lpfc_disc_illegal
, /* DEVICE_RECOVERY */
1708 lpfc_rcv_plogi_plogi_issue
, /* RCV_PLOGI PLOGI_ISSUE */
1709 lpfc_rcv_els_plogi_issue
, /* RCV_PRLI */
1710 lpfc_rcv_els_plogi_issue
, /* RCV_LOGO */
1711 lpfc_rcv_els_plogi_issue
, /* RCV_ADISC */
1712 lpfc_rcv_els_plogi_issue
, /* RCV_PDISC */
1713 lpfc_rcv_els_plogi_issue
, /* RCV_PRLO */
1714 lpfc_cmpl_plogi_plogi_issue
, /* CMPL_PLOGI */
1715 lpfc_disc_illegal
, /* CMPL_PRLI */
1716 lpfc_disc_illegal
, /* CMPL_LOGO */
1717 lpfc_disc_illegal
, /* CMPL_ADISC */
1718 lpfc_disc_illegal
, /* CMPL_REG_LOGIN */
1719 lpfc_device_rm_plogi_issue
, /* DEVICE_RM */
1720 lpfc_device_recov_plogi_issue
, /* DEVICE_RECOVERY */
1722 lpfc_rcv_plogi_adisc_issue
, /* RCV_PLOGI ADISC_ISSUE */
1723 lpfc_rcv_prli_adisc_issue
, /* RCV_PRLI */
1724 lpfc_rcv_logo_adisc_issue
, /* RCV_LOGO */
1725 lpfc_rcv_padisc_adisc_issue
, /* RCV_ADISC */
1726 lpfc_rcv_padisc_adisc_issue
, /* RCV_PDISC */
1727 lpfc_rcv_prlo_adisc_issue
, /* RCV_PRLO */
1728 lpfc_disc_illegal
, /* CMPL_PLOGI */
1729 lpfc_disc_illegal
, /* CMPL_PRLI */
1730 lpfc_disc_illegal
, /* CMPL_LOGO */
1731 lpfc_cmpl_adisc_adisc_issue
, /* CMPL_ADISC */
1732 lpfc_disc_illegal
, /* CMPL_REG_LOGIN */
1733 lpfc_device_rm_adisc_issue
, /* DEVICE_RM */
1734 lpfc_device_recov_adisc_issue
, /* DEVICE_RECOVERY */
1736 lpfc_rcv_plogi_reglogin_issue
, /* RCV_PLOGI REG_LOGIN_ISSUE */
1737 lpfc_rcv_prli_reglogin_issue
, /* RCV_PLOGI */
1738 lpfc_rcv_logo_reglogin_issue
, /* RCV_LOGO */
1739 lpfc_rcv_padisc_reglogin_issue
, /* RCV_ADISC */
1740 lpfc_rcv_padisc_reglogin_issue
, /* RCV_PDISC */
1741 lpfc_rcv_prlo_reglogin_issue
, /* RCV_PRLO */
1742 lpfc_disc_illegal
, /* CMPL_PLOGI */
1743 lpfc_disc_illegal
, /* CMPL_PRLI */
1744 lpfc_disc_illegal
, /* CMPL_LOGO */
1745 lpfc_disc_illegal
, /* CMPL_ADISC */
1746 lpfc_cmpl_reglogin_reglogin_issue
,/* CMPL_REG_LOGIN */
1747 lpfc_device_rm_reglogin_issue
, /* DEVICE_RM */
1748 lpfc_device_recov_reglogin_issue
,/* DEVICE_RECOVERY */
1750 lpfc_rcv_plogi_prli_issue
, /* RCV_PLOGI PRLI_ISSUE */
1751 lpfc_rcv_prli_prli_issue
, /* RCV_PRLI */
1752 lpfc_rcv_logo_prli_issue
, /* RCV_LOGO */
1753 lpfc_rcv_padisc_prli_issue
, /* RCV_ADISC */
1754 lpfc_rcv_padisc_prli_issue
, /* RCV_PDISC */
1755 lpfc_rcv_prlo_prli_issue
, /* RCV_PRLO */
1756 lpfc_disc_illegal
, /* CMPL_PLOGI */
1757 lpfc_cmpl_prli_prli_issue
, /* CMPL_PRLI */
1758 lpfc_disc_illegal
, /* CMPL_LOGO */
1759 lpfc_disc_illegal
, /* CMPL_ADISC */
1760 lpfc_disc_illegal
, /* CMPL_REG_LOGIN */
1761 lpfc_device_rm_prli_issue
, /* DEVICE_RM */
1762 lpfc_device_recov_prli_issue
, /* DEVICE_RECOVERY */
1764 lpfc_rcv_plogi_unmap_node
, /* RCV_PLOGI UNMAPPED_NODE */
1765 lpfc_rcv_prli_unmap_node
, /* RCV_PRLI */
1766 lpfc_rcv_logo_unmap_node
, /* RCV_LOGO */
1767 lpfc_rcv_padisc_unmap_node
, /* RCV_ADISC */
1768 lpfc_rcv_padisc_unmap_node
, /* RCV_PDISC */
1769 lpfc_rcv_prlo_unmap_node
, /* RCV_PRLO */
1770 lpfc_disc_illegal
, /* CMPL_PLOGI */
1771 lpfc_disc_illegal
, /* CMPL_PRLI */
1772 lpfc_disc_illegal
, /* CMPL_LOGO */
1773 lpfc_disc_illegal
, /* CMPL_ADISC */
1774 lpfc_disc_illegal
, /* CMPL_REG_LOGIN */
1775 lpfc_disc_illegal
, /* DEVICE_RM */
1776 lpfc_device_recov_unmap_node
, /* DEVICE_RECOVERY */
1778 lpfc_rcv_plogi_mapped_node
, /* RCV_PLOGI MAPPED_NODE */
1779 lpfc_rcv_prli_mapped_node
, /* RCV_PRLI */
1780 lpfc_rcv_logo_mapped_node
, /* RCV_LOGO */
1781 lpfc_rcv_padisc_mapped_node
, /* RCV_ADISC */
1782 lpfc_rcv_padisc_mapped_node
, /* RCV_PDISC */
1783 lpfc_rcv_prlo_mapped_node
, /* RCV_PRLO */
1784 lpfc_disc_illegal
, /* CMPL_PLOGI */
1785 lpfc_disc_illegal
, /* CMPL_PRLI */
1786 lpfc_disc_illegal
, /* CMPL_LOGO */
1787 lpfc_disc_illegal
, /* CMPL_ADISC */
1788 lpfc_disc_illegal
, /* CMPL_REG_LOGIN */
1789 lpfc_disc_illegal
, /* DEVICE_RM */
1790 lpfc_device_recov_mapped_node
, /* DEVICE_RECOVERY */
1792 lpfc_rcv_plogi_npr_node
, /* RCV_PLOGI NPR_NODE */
1793 lpfc_rcv_prli_npr_node
, /* RCV_PRLI */
1794 lpfc_rcv_logo_npr_node
, /* RCV_LOGO */
1795 lpfc_rcv_padisc_npr_node
, /* RCV_ADISC */
1796 lpfc_rcv_padisc_npr_node
, /* RCV_PDISC */
1797 lpfc_rcv_prlo_npr_node
, /* RCV_PRLO */
1798 lpfc_disc_noop
, /* CMPL_PLOGI */
1799 lpfc_disc_noop
, /* CMPL_PRLI */
1800 lpfc_cmpl_logo_npr_node
, /* CMPL_LOGO */
1801 lpfc_disc_noop
, /* CMPL_ADISC */
1802 lpfc_cmpl_reglogin_npr_node
, /* CMPL_REG_LOGIN */
1803 lpfc_device_rm_npr_node
, /* DEVICE_RM */
1804 lpfc_device_recov_npr_node
, /* DEVICE_RECOVERY */
1808 lpfc_disc_state_machine(struct lpfc_hba
* phba
,
1809 struct lpfc_nodelist
* ndlp
, void *arg
, uint32_t evt
)
1811 uint32_t cur_state
, rc
;
1812 uint32_t(*func
) (struct lpfc_hba
*, struct lpfc_nodelist
*, void *,
1815 ndlp
->nlp_disc_refcnt
++;
1816 cur_state
= ndlp
->nlp_state
;
1818 /* DSM in event <evt> on NPort <nlp_DID> in state <cur_state> */
1819 lpfc_printf_log(phba
,
1822 "%d:0211 DSM in event x%x on NPort x%x in state %d "
1825 evt
, ndlp
->nlp_DID
, cur_state
, ndlp
->nlp_flag
);
1827 func
= lpfc_disc_action
[(cur_state
* NLP_EVT_MAX_EVENT
) + evt
];
1828 rc
= (func
) (phba
, ndlp
, arg
, evt
);
1830 /* DSM out state <rc> on NPort <nlp_DID> */
1831 lpfc_printf_log(phba
,
1834 "%d:0212 DSM out state %d on NPort x%x Data: x%x\n",
1836 rc
, ndlp
->nlp_DID
, ndlp
->nlp_flag
);
1838 ndlp
->nlp_disc_refcnt
--;
1840 /* Check to see if ndlp removal is deferred */
1841 if ((ndlp
->nlp_disc_refcnt
== 0)
1842 && (ndlp
->nlp_flag
& NLP_DELAY_REMOVE
)) {
1843 spin_lock_irq(phba
->host
->host_lock
);
1844 ndlp
->nlp_flag
&= ~NLP_DELAY_REMOVE
;
1845 spin_unlock_irq(phba
->host
->host_lock
);
1846 lpfc_nlp_remove(phba
, ndlp
);
1847 return (NLP_STE_FREED_NODE
);
1849 if (rc
== NLP_STE_FREED_NODE
)
1850 return (NLP_STE_FREED_NODE
);
1851 ndlp
->nlp_state
= rc
;