]> err.no Git - linux-2.6/blob - drivers/scsi/lpfc/lpfc_nportdisc.c
9c159a8e6e8cd05274115461b4e11f36097bb63f
[linux-2.6] / drivers / scsi / lpfc / lpfc_nportdisc.c
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  * 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  *******************************************************************/
21
22 #include <linux/blkdev.h>
23 #include <linux/pci.h>
24 #include <linux/interrupt.h>
25
26 #include <scsi/scsi.h>
27 #include <scsi/scsi_device.h>
28 #include <scsi/scsi_host.h>
29 #include <scsi/scsi_transport_fc.h>
30
31 #include "lpfc_hw.h"
32 #include "lpfc_sli.h"
33 #include "lpfc_disc.h"
34 #include "lpfc_scsi.h"
35 #include "lpfc.h"
36 #include "lpfc_logmsg.h"
37 #include "lpfc_crtn.h"
38 #include "lpfc_vport.h"
39 #include "lpfc_debugfs.h"
40
41
42 /* Called to verify a rcv'ed ADISC was intended for us. */
43 static int
44 lpfc_check_adisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
45                  struct lpfc_name *nn, struct lpfc_name *pn)
46 {
47         /* Compare the ADISC rsp WWNN / WWPN matches our internal node
48          * table entry for that node.
49          */
50         if (memcmp(nn, &ndlp->nlp_nodename, sizeof (struct lpfc_name)))
51                 return 0;
52
53         if (memcmp(pn, &ndlp->nlp_portname, sizeof (struct lpfc_name)))
54                 return 0;
55
56         /* we match, return success */
57         return 1;
58 }
59
60 int
61 lpfc_check_sparm(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
62                  struct serv_parm * sp, uint32_t class)
63 {
64         volatile struct serv_parm *hsp = &vport->fc_sparam;
65         uint16_t hsp_value, ssp_value = 0;
66
67         /*
68          * The receive data field size and buffer-to-buffer receive data field
69          * size entries are 16 bits but are represented as two 8-bit fields in
70          * the driver data structure to account for rsvd bits and other control
71          * bits.  Reconstruct and compare the fields as a 16-bit values before
72          * correcting the byte values.
73          */
74         if (sp->cls1.classValid) {
75                 hsp_value = (hsp->cls1.rcvDataSizeMsb << 8) |
76                                 hsp->cls1.rcvDataSizeLsb;
77                 ssp_value = (sp->cls1.rcvDataSizeMsb << 8) |
78                                 sp->cls1.rcvDataSizeLsb;
79                 if (!ssp_value)
80                         goto bad_service_param;
81                 if (ssp_value > hsp_value) {
82                         sp->cls1.rcvDataSizeLsb = hsp->cls1.rcvDataSizeLsb;
83                         sp->cls1.rcvDataSizeMsb = hsp->cls1.rcvDataSizeMsb;
84                 }
85         } else if (class == CLASS1) {
86                 goto bad_service_param;
87         }
88
89         if (sp->cls2.classValid) {
90                 hsp_value = (hsp->cls2.rcvDataSizeMsb << 8) |
91                                 hsp->cls2.rcvDataSizeLsb;
92                 ssp_value = (sp->cls2.rcvDataSizeMsb << 8) |
93                                 sp->cls2.rcvDataSizeLsb;
94                 if (!ssp_value)
95                         goto bad_service_param;
96                 if (ssp_value > hsp_value) {
97                         sp->cls2.rcvDataSizeLsb = hsp->cls2.rcvDataSizeLsb;
98                         sp->cls2.rcvDataSizeMsb = hsp->cls2.rcvDataSizeMsb;
99                 }
100         } else if (class == CLASS2) {
101                 goto bad_service_param;
102         }
103
104         if (sp->cls3.classValid) {
105                 hsp_value = (hsp->cls3.rcvDataSizeMsb << 8) |
106                                 hsp->cls3.rcvDataSizeLsb;
107                 ssp_value = (sp->cls3.rcvDataSizeMsb << 8) |
108                                 sp->cls3.rcvDataSizeLsb;
109                 if (!ssp_value)
110                         goto bad_service_param;
111                 if (ssp_value > hsp_value) {
112                         sp->cls3.rcvDataSizeLsb = hsp->cls3.rcvDataSizeLsb;
113                         sp->cls3.rcvDataSizeMsb = hsp->cls3.rcvDataSizeMsb;
114                 }
115         } else if (class == CLASS3) {
116                 goto bad_service_param;
117         }
118
119         /*
120          * Preserve the upper four bits of the MSB from the PLOGI response.
121          * These bits contain the Buffer-to-Buffer State Change Number
122          * from the target and need to be passed to the FW.
123          */
124         hsp_value = (hsp->cmn.bbRcvSizeMsb << 8) | hsp->cmn.bbRcvSizeLsb;
125         ssp_value = (sp->cmn.bbRcvSizeMsb << 8) | sp->cmn.bbRcvSizeLsb;
126         if (ssp_value > hsp_value) {
127                 sp->cmn.bbRcvSizeLsb = hsp->cmn.bbRcvSizeLsb;
128                 sp->cmn.bbRcvSizeMsb = (sp->cmn.bbRcvSizeMsb & 0xF0) |
129                                        (hsp->cmn.bbRcvSizeMsb & 0x0F);
130         }
131
132         memcpy(&ndlp->nlp_nodename, &sp->nodeName, sizeof (struct lpfc_name));
133         memcpy(&ndlp->nlp_portname, &sp->portName, sizeof (struct lpfc_name));
134         return 1;
135 bad_service_param:
136         lpfc_printf_log(vport->phba, KERN_ERR, LOG_DISCOVERY,
137                         "%d (%d):0207 Device %x "
138                         "(%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x) sent "
139                         "invalid service parameters.  Ignoring device.\n",
140                         vport->phba->brd_no, ndlp->vport->vpi, ndlp->nlp_DID,
141                         sp->nodeName.u.wwn[0], sp->nodeName.u.wwn[1],
142                         sp->nodeName.u.wwn[2], sp->nodeName.u.wwn[3],
143                         sp->nodeName.u.wwn[4], sp->nodeName.u.wwn[5],
144                         sp->nodeName.u.wwn[6], sp->nodeName.u.wwn[7]);
145         return 0;
146 }
147
148 static void *
149 lpfc_check_elscmpl_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
150                         struct lpfc_iocbq *rspiocb)
151 {
152         struct lpfc_dmabuf *pcmd, *prsp;
153         uint32_t *lp;
154         void     *ptr = NULL;
155         IOCB_t   *irsp;
156
157         irsp = &rspiocb->iocb;
158         pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
159
160         /* For lpfc_els_abort, context2 could be zero'ed to delay
161          * freeing associated memory till after ABTS completes.
162          */
163         if (pcmd) {
164                 prsp =  list_get_first(&pcmd->list, struct lpfc_dmabuf,
165                                        list);
166                 if (prsp) {
167                         lp = (uint32_t *) prsp->virt;
168                         ptr = (void *)((uint8_t *)lp + sizeof(uint32_t));
169                 }
170         } else {
171                 /* Force ulpStatus error since we are returning NULL ptr */
172                 if (!(irsp->ulpStatus)) {
173                         irsp->ulpStatus = IOSTAT_LOCAL_REJECT;
174                         irsp->un.ulpWord[4] = IOERR_SLI_ABORTED;
175                 }
176                 ptr = NULL;
177         }
178         return ptr;
179 }
180
181
182 /*
183  * Free resources / clean up outstanding I/Os
184  * associated with a LPFC_NODELIST entry. This
185  * routine effectively results in a "software abort".
186  */
187 int
188 lpfc_els_abort(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp)
189 {
190         LIST_HEAD(completions);
191         struct lpfc_sli  *psli = &phba->sli;
192         struct lpfc_sli_ring *pring = &psli->ring[LPFC_ELS_RING];
193         struct lpfc_iocbq *iocb, *next_iocb;
194         IOCB_t *cmd;
195
196         /* Abort outstanding I/O on NPort <nlp_DID> */
197         lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY,
198                         "%d (%d):0205 Abort outstanding I/O on NPort x%x "
199                         "Data: x%x x%x x%x\n",
200                         phba->brd_no, ndlp->vport->vpi, ndlp->nlp_DID,
201                         ndlp->nlp_flag, ndlp->nlp_state, ndlp->nlp_rpi);
202
203         lpfc_fabric_abort_nport(ndlp);
204
205         /* First check the txq */
206         spin_lock_irq(&phba->hbalock);
207         list_for_each_entry_safe(iocb, next_iocb, &pring->txq, list) {
208                 /* Check to see if iocb matches the nport we are looking for */
209                 if (lpfc_check_sli_ndlp(phba, pring, iocb, ndlp)) {
210                         /* It matches, so deque and call compl with anp error */
211                         list_move_tail(&iocb->list, &completions);
212                         pring->txq_cnt--;
213                 }
214         }
215
216         /* Next check the txcmplq */
217         list_for_each_entry_safe(iocb, next_iocb, &pring->txcmplq, list) {
218                 /* Check to see if iocb matches the nport we are looking for */
219                 if (lpfc_check_sli_ndlp(phba, pring, iocb, ndlp)) {
220                         lpfc_sli_issue_abort_iotag(phba, pring, iocb);
221                 }
222         }
223         spin_unlock_irq(&phba->hbalock);
224
225         while (!list_empty(&completions)) {
226                 iocb = list_get_first(&completions, struct lpfc_iocbq, list);
227                 cmd = &iocb->iocb;
228                 list_del_init(&iocb->list);
229
230                 if (!iocb->iocb_cmpl)
231                         lpfc_sli_release_iocbq(phba, iocb);
232                 else {
233                         cmd->ulpStatus = IOSTAT_LOCAL_REJECT;
234                         cmd->un.ulpWord[4] = IOERR_SLI_ABORTED;
235                         (iocb->iocb_cmpl) (phba, iocb, iocb);
236                 }
237         }
238
239         /* If we are delaying issuing an ELS command, cancel it */
240         if (ndlp->nlp_flag & NLP_DELAY_TMO)
241                 lpfc_cancel_retry_delay_tmo(phba->pport, ndlp);
242         return 0;
243 }
244
245 static int
246 lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
247                struct lpfc_iocbq *cmdiocb)
248 {
249         struct Scsi_Host   *shost = lpfc_shost_from_vport(vport);
250         struct lpfc_hba    *phba = vport->phba;
251         struct lpfc_dmabuf *pcmd;
252         uint32_t *lp;
253         IOCB_t *icmd;
254         struct serv_parm *sp;
255         LPFC_MBOXQ_t *mbox;
256         struct ls_rjt stat;
257         int rc;
258
259         memset(&stat, 0, sizeof (struct ls_rjt));
260         if (vport->port_state <= LPFC_FLOGI) {
261                 /* Before responding to PLOGI, check for pt2pt mode.
262                  * If we are pt2pt, with an outstanding FLOGI, abort
263                  * the FLOGI and resend it first.
264                  */
265                 if (vport->fc_flag & FC_PT2PT) {
266                          lpfc_els_abort_flogi(phba);
267                         if (!(vport->fc_flag & FC_PT2PT_PLOGI)) {
268                                 /* If the other side is supposed to initiate
269                                  * the PLOGI anyway, just ACC it now and
270                                  * move on with discovery.
271                                  */
272                                 phba->fc_edtov = FF_DEF_EDTOV;
273                                 phba->fc_ratov = FF_DEF_RATOV;
274                                 /* Start discovery - this should just do
275                                    CLEAR_LA */
276                                 lpfc_disc_start(vport);
277                         } else
278                                 lpfc_initial_flogi(vport);
279                 } else {
280                         stat.un.b.lsRjtRsnCode = LSRJT_LOGICAL_BSY;
281                         stat.un.b.lsRjtRsnCodeExp = LSEXP_NOTHING_MORE;
282                         lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb,
283                                             ndlp, NULL);
284                         return 0;
285                 }
286         }
287         pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
288         lp = (uint32_t *) pcmd->virt;
289         sp = (struct serv_parm *) ((uint8_t *) lp + sizeof (uint32_t));
290         if ((lpfc_check_sparm(vport, ndlp, sp, CLASS3) == 0)) {
291                 /* Reject this request because invalid parameters */
292                 stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
293                 stat.un.b.lsRjtRsnCodeExp = LSEXP_SPARM_OPTIONS;
294                 lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp,
295                         NULL);
296                 return 0;
297         }
298         icmd = &cmdiocb->iocb;
299
300         /* PLOGI chkparm OK */
301         lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
302                         "%d (%d):0114 PLOGI chkparm OK Data: x%x x%x x%x x%x\n",
303                         phba->brd_no, vport->vpi,
304                         ndlp->nlp_DID, ndlp->nlp_state, ndlp->nlp_flag,
305                         ndlp->nlp_rpi);
306
307         if (vport->cfg_fcp_class == 2 && sp->cls2.classValid)
308                 ndlp->nlp_fcp_info |= CLASS2;
309         else
310                 ndlp->nlp_fcp_info |= CLASS3;
311
312         ndlp->nlp_class_sup = 0;
313         if (sp->cls1.classValid)
314                 ndlp->nlp_class_sup |= FC_COS_CLASS1;
315         if (sp->cls2.classValid)
316                 ndlp->nlp_class_sup |= FC_COS_CLASS2;
317         if (sp->cls3.classValid)
318                 ndlp->nlp_class_sup |= FC_COS_CLASS3;
319         if (sp->cls4.classValid)
320                 ndlp->nlp_class_sup |= FC_COS_CLASS4;
321         ndlp->nlp_maxframe =
322                 ((sp->cmn.bbRcvSizeMsb & 0x0F) << 8) | sp->cmn.bbRcvSizeLsb;
323
324         /* no need to reg_login if we are already in one of these states */
325         switch (ndlp->nlp_state) {
326         case  NLP_STE_NPR_NODE:
327                 if (!(ndlp->nlp_flag & NLP_NPR_ADISC))
328                         break;
329         case  NLP_STE_REG_LOGIN_ISSUE:
330         case  NLP_STE_PRLI_ISSUE:
331         case  NLP_STE_UNMAPPED_NODE:
332         case  NLP_STE_MAPPED_NODE:
333                 lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, cmdiocb, ndlp, NULL, 0);
334                 return 1;
335         }
336
337         if ((vport->fc_flag & FC_PT2PT) &&
338             !(vport->fc_flag & FC_PT2PT_PLOGI)) {
339                 /* rcv'ed PLOGI decides what our NPortId will be */
340                 vport->fc_myDID = icmd->un.rcvels.parmRo;
341                 mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
342                 if (mbox == NULL)
343                         goto out;
344                 lpfc_config_link(phba, mbox);
345                 mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
346                 mbox->vport = vport;
347                 rc = lpfc_sli_issue_mbox
348                         (phba, mbox, (MBX_NOWAIT | MBX_STOP_IOCB));
349                 if (rc == MBX_NOT_FINISHED) {
350                         mempool_free(mbox, phba->mbox_mem_pool);
351                         goto out;
352                 }
353
354                 lpfc_can_disctmo(vport);
355         }
356         mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
357         if (!mbox)
358                 goto out;
359
360         rc = lpfc_reg_login(phba, vport->vpi, icmd->un.rcvels.remoteID,
361                             (uint8_t *) sp, mbox, 0);
362         if (rc) {
363                 mempool_free(mbox, phba->mbox_mem_pool);
364                 goto out;
365         }
366
367         /* ACC PLOGI rsp command needs to execute first,
368          * queue this mbox command to be processed later.
369          */
370         mbox->mbox_cmpl = lpfc_mbx_cmpl_reg_login;
371         /*
372          * mbox->context2 = lpfc_nlp_get(ndlp) deferred until mailbox
373          * command issued in lpfc_cmpl_els_acc().
374          */
375         mbox->vport = vport;
376         spin_lock_irq(shost->host_lock);
377         ndlp->nlp_flag |= (NLP_ACC_REGLOGIN | NLP_RCV_PLOGI);
378         spin_unlock_irq(shost->host_lock);
379
380         /*
381          * If there is an outstanding PLOGI issued, abort it before
382          * sending ACC rsp for received PLOGI. If pending plogi
383          * is not canceled here, the plogi will be rejected by
384          * remote port and will be retried. On a configuration with
385          * single discovery thread, this will cause a huge delay in
386          * discovery. Also this will cause multiple state machines
387          * running in parallel for this node.
388          */
389         if (ndlp->nlp_state == NLP_STE_PLOGI_ISSUE) {
390                 /* software abort outstanding PLOGI */
391                 lpfc_els_abort(phba, ndlp);
392         }
393
394         if ((vport->port_type == LPFC_NPIV_PORT &&
395              vport->cfg_restrict_login)) {
396
397                 /* In order to preserve RPIs, we want to cleanup
398                  * the default RPI the firmware created to rcv
399                  * this ELS request. The only way to do this is
400                  * to register, then unregister the RPI.
401                  */
402                 spin_lock_irq(shost->host_lock);
403                 ndlp->nlp_flag |= NLP_RM_DFLT_RPI;
404                 spin_unlock_irq(shost->host_lock);
405                 stat.un.b.lsRjtRsnCode = LSRJT_INVALID_CMD;
406                 stat.un.b.lsRjtRsnCodeExp = LSEXP_NOTHING_MORE;
407                 lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb,
408                         ndlp, mbox);
409                 return 1;
410         }
411         lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, cmdiocb, ndlp, mbox, 0);
412         return 1;
413
414 out:
415         stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
416         stat.un.b.lsRjtRsnCodeExp = LSEXP_OUT_OF_RESOURCE;
417         lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp, NULL);
418         return 0;
419 }
420
421 static int
422 lpfc_rcv_padisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
423                 struct lpfc_iocbq *cmdiocb)
424 {
425         struct Scsi_Host   *shost = lpfc_shost_from_vport(vport);
426         struct lpfc_dmabuf *pcmd;
427         struct serv_parm   *sp;
428         struct lpfc_name   *pnn, *ppn;
429         struct ls_rjt stat;
430         ADISC *ap;
431         IOCB_t *icmd;
432         uint32_t *lp;
433         uint32_t cmd;
434
435         pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
436         lp = (uint32_t *) pcmd->virt;
437
438         cmd = *lp++;
439         if (cmd == ELS_CMD_ADISC) {
440                 ap = (ADISC *) lp;
441                 pnn = (struct lpfc_name *) & ap->nodeName;
442                 ppn = (struct lpfc_name *) & ap->portName;
443         } else {
444                 sp = (struct serv_parm *) lp;
445                 pnn = (struct lpfc_name *) & sp->nodeName;
446                 ppn = (struct lpfc_name *) & sp->portName;
447         }
448
449         icmd = &cmdiocb->iocb;
450         if (icmd->ulpStatus == 0 && lpfc_check_adisc(vport, ndlp, pnn, ppn)) {
451                 if (cmd == ELS_CMD_ADISC) {
452                         lpfc_els_rsp_adisc_acc(vport, cmdiocb, ndlp);
453                 } else {
454                         lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, cmdiocb, ndlp,
455                                          NULL, 0);
456                 }
457                 return 1;
458         }
459         /* Reject this request because invalid parameters */
460         stat.un.b.lsRjtRsvd0 = 0;
461         stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
462         stat.un.b.lsRjtRsnCodeExp = LSEXP_SPARM_OPTIONS;
463         stat.un.b.vendorUnique = 0;
464         lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp, NULL);
465
466         /* 1 sec timeout */
467         mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ);
468
469         spin_lock_irq(shost->host_lock);
470         ndlp->nlp_flag |= NLP_DELAY_TMO;
471         spin_unlock_irq(shost->host_lock);
472         ndlp->nlp_last_elscmd = ELS_CMD_PLOGI;
473         ndlp->nlp_prev_state = ndlp->nlp_state;
474         lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
475         return 0;
476 }
477
478 static int
479 lpfc_rcv_logo(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
480               struct lpfc_iocbq *cmdiocb, uint32_t els_cmd)
481 {
482         struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
483
484         /* Put ndlp in NPR state with 1 sec timeout for plogi, ACC logo */
485         /* Only call LOGO ACC for first LOGO, this avoids sending unnecessary
486          * PLOGIs during LOGO storms from a device.
487          */
488         spin_lock_irq(shost->host_lock);
489         ndlp->nlp_flag |= NLP_LOGO_ACC;
490         spin_unlock_irq(shost->host_lock);
491         if (els_cmd == ELS_CMD_PRLO)
492                 lpfc_els_rsp_acc(vport, ELS_CMD_PRLO, cmdiocb, ndlp, NULL, 0);
493         else
494                 lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0);
495
496         if (!(ndlp->nlp_type & NLP_FABRIC) ||
497             (ndlp->nlp_state == NLP_STE_ADISC_ISSUE)) {
498                 /* Only try to re-login if this is NOT a Fabric Node */
499                 mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ * 1);
500                 spin_lock_irq(shost->host_lock);
501                 ndlp->nlp_flag |= NLP_DELAY_TMO;
502                 spin_unlock_irq(shost->host_lock);
503
504                 ndlp->nlp_last_elscmd = ELS_CMD_PLOGI;
505                 ndlp->nlp_prev_state = ndlp->nlp_state;
506                 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
507         } else {
508                 ndlp->nlp_prev_state = ndlp->nlp_state;
509                 lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNUSED_NODE);
510         }
511
512         spin_lock_irq(shost->host_lock);
513         ndlp->nlp_flag &= ~NLP_NPR_ADISC;
514         spin_unlock_irq(shost->host_lock);
515         /* The driver has to wait until the ACC completes before it continues
516          * processing the LOGO.  The action will resume in
517          * lpfc_cmpl_els_logo_acc routine. Since part of processing includes an
518          * unreg_login, the driver waits so the ACC does not get aborted.
519          */
520         return 0;
521 }
522
523 static void
524 lpfc_rcv_prli(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
525               struct lpfc_iocbq *cmdiocb)
526 {
527         struct lpfc_dmabuf *pcmd;
528         uint32_t *lp;
529         PRLI *npr;
530         struct fc_rport *rport = ndlp->rport;
531         u32 roles;
532
533         pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
534         lp = (uint32_t *) pcmd->virt;
535         npr = (PRLI *) ((uint8_t *) lp + sizeof (uint32_t));
536
537         ndlp->nlp_type &= ~(NLP_FCP_TARGET | NLP_FCP_INITIATOR);
538         ndlp->nlp_fcp_info &= ~NLP_FCP_2_DEVICE;
539         if (npr->prliType == PRLI_FCP_TYPE) {
540                 if (npr->initiatorFunc)
541                         ndlp->nlp_type |= NLP_FCP_INITIATOR;
542                 if (npr->targetFunc)
543                         ndlp->nlp_type |= NLP_FCP_TARGET;
544                 if (npr->Retry)
545                         ndlp->nlp_fcp_info |= NLP_FCP_2_DEVICE;
546         }
547         if (rport) {
548                 /* We need to update the rport role values */
549                 roles = FC_RPORT_ROLE_UNKNOWN;
550                 if (ndlp->nlp_type & NLP_FCP_INITIATOR)
551                         roles |= FC_RPORT_ROLE_FCP_INITIATOR;
552                 if (ndlp->nlp_type & NLP_FCP_TARGET)
553                         roles |= FC_RPORT_ROLE_FCP_TARGET;
554
555                 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_RPORT,
556                         "rport rolechg:   role:x%x did:x%x flg:x%x",
557                         roles, ndlp->nlp_DID, ndlp->nlp_flag);
558
559                 fc_remote_port_rolechg(rport, roles);
560         }
561 }
562
563 static uint32_t
564 lpfc_disc_set_adisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
565 {
566         struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
567
568         /* Check config parameter use-adisc or FCP-2 */
569         if ((vport->cfg_use_adisc && (vport->fc_flag & FC_RSCN_MODE)) ||
570             ndlp->nlp_fcp_info & NLP_FCP_2_DEVICE) {
571                 spin_lock_irq(shost->host_lock);
572                 ndlp->nlp_flag |= NLP_NPR_ADISC;
573                 spin_unlock_irq(shost->host_lock);
574                 return 1;
575         }
576         ndlp->nlp_flag &= ~NLP_NPR_ADISC;
577         lpfc_unreg_rpi(vport, ndlp);
578         return 0;
579 }
580
581 static uint32_t
582 lpfc_disc_illegal(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
583                   void *arg, uint32_t evt)
584 {
585         lpfc_printf_log(vport->phba, KERN_ERR, LOG_DISCOVERY,
586                         "%d (%d):0253 Illegal State Transition: node x%x "
587                         "event x%x, state x%x Data: x%x x%x\n",
588                         vport->phba->brd_no, vport->vpi,
589                         ndlp->nlp_DID, evt, ndlp->nlp_state, ndlp->nlp_rpi,
590                         ndlp->nlp_flag);
591         return ndlp->nlp_state;
592 }
593
594 /* Start of Discovery State Machine routines */
595
596 static uint32_t
597 lpfc_rcv_plogi_unused_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
598                            void *arg, uint32_t evt)
599 {
600         struct lpfc_iocbq *cmdiocb;
601
602         cmdiocb = (struct lpfc_iocbq *) arg;
603
604         if (lpfc_rcv_plogi(vport, ndlp, cmdiocb)) {
605                 ndlp->nlp_prev_state = NLP_STE_UNUSED_NODE;
606                 lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNUSED_NODE);
607                 return ndlp->nlp_state;
608         }
609         lpfc_drop_node(vport, ndlp);
610         return NLP_STE_FREED_NODE;
611 }
612
613 static uint32_t
614 lpfc_rcv_els_unused_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
615                          void *arg, uint32_t evt)
616 {
617         lpfc_issue_els_logo(vport, ndlp, 0);
618         lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNUSED_NODE);
619         return ndlp->nlp_state;
620 }
621
622 static uint32_t
623 lpfc_rcv_logo_unused_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
624                           void *arg, uint32_t evt)
625 {
626         struct Scsi_Host  *shost = lpfc_shost_from_vport(vport);
627         struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
628
629         spin_lock_irq(shost->host_lock);
630         ndlp->nlp_flag |= NLP_LOGO_ACC;
631         spin_unlock_irq(shost->host_lock);
632         lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0);
633         lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNUSED_NODE);
634
635         return ndlp->nlp_state;
636 }
637
638 static uint32_t
639 lpfc_cmpl_logo_unused_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
640                            void *arg, uint32_t evt)
641 {
642         lpfc_drop_node(vport, ndlp);
643         return NLP_STE_FREED_NODE;
644 }
645
646 static uint32_t
647 lpfc_device_rm_unused_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
648                            void *arg, uint32_t evt)
649 {
650         lpfc_drop_node(vport, ndlp);
651         return NLP_STE_FREED_NODE;
652 }
653
654 static uint32_t
655 lpfc_rcv_plogi_plogi_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
656                            void *arg, uint32_t evt)
657 {
658         struct lpfc_hba   *phba = vport->phba;
659         struct lpfc_iocbq *cmdiocb = arg;
660         struct lpfc_dmabuf *pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
661         uint32_t *lp = (uint32_t *) pcmd->virt;
662         struct serv_parm *sp = (struct serv_parm *) (lp + 1);
663         struct ls_rjt stat;
664         int port_cmp;
665
666         memset(&stat, 0, sizeof (struct ls_rjt));
667
668         /* For a PLOGI, we only accept if our portname is less
669          * than the remote portname.
670          */
671         phba->fc_stat.elsLogiCol++;
672         port_cmp = memcmp(&vport->fc_portname, &sp->portName,
673                           sizeof(struct lpfc_name));
674
675         if (port_cmp >= 0) {
676                 /* Reject this request because the remote node will accept
677                    ours */
678                 stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
679                 stat.un.b.lsRjtRsnCodeExp = LSEXP_CMD_IN_PROGRESS;
680                 lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp,
681                         NULL);
682         } else {
683                 lpfc_rcv_plogi(vport, ndlp, cmdiocb);
684         } /* If our portname was less */
685
686         return ndlp->nlp_state;
687 }
688
689 static uint32_t
690 lpfc_rcv_prli_plogi_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
691                           void *arg, uint32_t evt)
692 {
693         struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
694         struct ls_rjt     stat;
695
696         memset(&stat, 0, sizeof (struct ls_rjt));
697         stat.un.b.lsRjtRsnCode = LSRJT_LOGICAL_BSY;
698         stat.un.b.lsRjtRsnCodeExp = LSEXP_NOTHING_MORE;
699         lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp, NULL);
700         return ndlp->nlp_state;
701 }
702
703 static uint32_t
704 lpfc_rcv_logo_plogi_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
705                           void *arg, uint32_t evt)
706 {
707         struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
708
709                                 /* software abort outstanding PLOGI */
710         lpfc_els_abort(vport->phba, ndlp);
711
712         lpfc_rcv_logo(vport, ndlp, cmdiocb, ELS_CMD_LOGO);
713         return ndlp->nlp_state;
714 }
715
716 static uint32_t
717 lpfc_rcv_els_plogi_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
718                          void *arg, uint32_t evt)
719 {
720         struct Scsi_Host  *shost = lpfc_shost_from_vport(vport);
721         struct lpfc_hba   *phba = vport->phba;
722         struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
723
724         /* software abort outstanding PLOGI */
725         lpfc_els_abort(phba, ndlp);
726
727         if (evt == NLP_EVT_RCV_LOGO) {
728                 lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0);
729         } else {
730                 lpfc_issue_els_logo(vport, ndlp, 0);
731         }
732
733         /* Put ndlp in npr state set plogi timer for 1 sec */
734         mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ * 1);
735         spin_lock_irq(shost->host_lock);
736         ndlp->nlp_flag |= NLP_DELAY_TMO;
737         spin_unlock_irq(shost->host_lock);
738         ndlp->nlp_last_elscmd = ELS_CMD_PLOGI;
739         ndlp->nlp_prev_state = NLP_STE_PLOGI_ISSUE;
740         lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
741
742         return ndlp->nlp_state;
743 }
744
745 static uint32_t
746 lpfc_cmpl_plogi_plogi_issue(struct lpfc_vport *vport,
747                             struct lpfc_nodelist *ndlp,
748                             void *arg,
749                             uint32_t evt)
750 {
751         struct lpfc_hba    *phba = vport->phba;
752         struct lpfc_iocbq  *cmdiocb, *rspiocb;
753         struct lpfc_dmabuf *pcmd, *prsp, *mp;
754         uint32_t *lp;
755         IOCB_t *irsp;
756         struct serv_parm *sp;
757         LPFC_MBOXQ_t *mbox;
758
759         cmdiocb = (struct lpfc_iocbq *) arg;
760         rspiocb = cmdiocb->context_un.rsp_iocb;
761
762         if (ndlp->nlp_flag & NLP_ACC_REGLOGIN) {
763                 /* Recovery from PLOGI collision logic */
764                 return ndlp->nlp_state;
765         }
766
767         irsp = &rspiocb->iocb;
768
769         if (irsp->ulpStatus)
770                 goto out;
771
772         pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
773
774         prsp = list_get_first(&pcmd->list, struct lpfc_dmabuf, list);
775
776         lp = (uint32_t *) prsp->virt;
777         sp = (struct serv_parm *) ((uint8_t *) lp + sizeof (uint32_t));
778         if (!lpfc_check_sparm(vport, ndlp, sp, CLASS3))
779                 goto out;
780
781         /* PLOGI chkparm OK */
782         lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
783                         "%d (%d):0121 PLOGI chkparm OK "
784                         "Data: x%x x%x x%x x%x\n",
785                         phba->brd_no, vport->vpi,
786                         ndlp->nlp_DID, ndlp->nlp_state,
787                         ndlp->nlp_flag, ndlp->nlp_rpi);
788
789         if (vport->cfg_fcp_class == 2 && (sp->cls2.classValid))
790                 ndlp->nlp_fcp_info |= CLASS2;
791         else
792                 ndlp->nlp_fcp_info |= CLASS3;
793
794         ndlp->nlp_class_sup = 0;
795         if (sp->cls1.classValid)
796                 ndlp->nlp_class_sup |= FC_COS_CLASS1;
797         if (sp->cls2.classValid)
798                 ndlp->nlp_class_sup |= FC_COS_CLASS2;
799         if (sp->cls3.classValid)
800                 ndlp->nlp_class_sup |= FC_COS_CLASS3;
801         if (sp->cls4.classValid)
802                 ndlp->nlp_class_sup |= FC_COS_CLASS4;
803         ndlp->nlp_maxframe =
804                 ((sp->cmn.bbRcvSizeMsb & 0x0F) << 8) | sp->cmn.bbRcvSizeLsb;
805
806         mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
807         if (!mbox) {
808                 lpfc_printf_log(phba, KERN_ERR, LOG_ELS,
809                         "%d (%d):0133 PLOGI: no memory for reg_login "
810                         "Data: x%x x%x x%x x%x\n",
811                         phba->brd_no, vport->vpi,
812                         ndlp->nlp_DID, ndlp->nlp_state,
813                         ndlp->nlp_flag, ndlp->nlp_rpi);
814                 goto out;
815         }
816
817         lpfc_unreg_rpi(vport, ndlp);
818
819         if (lpfc_reg_login(phba, vport->vpi, irsp->un.elsreq64.remoteID,
820                            (uint8_t *) sp, mbox, 0) == 0) {
821                 switch (ndlp->nlp_DID) {
822                 case NameServer_DID:
823                         mbox->mbox_cmpl = lpfc_mbx_cmpl_ns_reg_login;
824                         break;
825                 case FDMI_DID:
826                         mbox->mbox_cmpl = lpfc_mbx_cmpl_fdmi_reg_login;
827                         break;
828                 default:
829                         mbox->mbox_cmpl = lpfc_mbx_cmpl_reg_login;
830                 }
831                 mbox->context2 = lpfc_nlp_get(ndlp);
832                 mbox->vport = vport;
833                 if (lpfc_sli_issue_mbox(phba, mbox,
834                                         (MBX_NOWAIT | MBX_STOP_IOCB))
835                     != MBX_NOT_FINISHED) {
836                         lpfc_nlp_set_state(vport, ndlp,
837                                            NLP_STE_REG_LOGIN_ISSUE);
838                         return ndlp->nlp_state;
839                 }
840                 lpfc_nlp_put(ndlp);
841                 mp = (struct lpfc_dmabuf *) mbox->context1;
842                 lpfc_mbuf_free(phba, mp->virt, mp->phys);
843                 kfree(mp);
844                 mempool_free(mbox, phba->mbox_mem_pool);
845
846                 lpfc_printf_log(phba, KERN_ERR, LOG_ELS,
847                         "%d (%d):0134 PLOGI: cannot issue reg_login "
848                         "Data: x%x x%x x%x x%x\n",
849                         phba->brd_no, vport->vpi,
850                         ndlp->nlp_DID, ndlp->nlp_state,
851                         ndlp->nlp_flag, ndlp->nlp_rpi);
852         } else {
853                 mempool_free(mbox, phba->mbox_mem_pool);
854
855                 lpfc_printf_log(phba, KERN_ERR, LOG_ELS,
856                         "%d (%d):0135 PLOGI: cannot format reg_login "
857                         "Data: x%x x%x x%x x%x\n",
858                         phba->brd_no, vport->vpi,
859                         ndlp->nlp_DID, ndlp->nlp_state,
860                         ndlp->nlp_flag, ndlp->nlp_rpi);
861         }
862
863
864 out:
865         if (ndlp->nlp_DID == NameServer_DID) {
866                 lpfc_vport_set_state(vport, FC_VPORT_FAILED);
867                 lpfc_printf_log(phba, KERN_ERR, LOG_ELS,
868                         "%d (%d):0261 Cannot Register NameServer login\n",
869                         phba->brd_no, vport->vpi);
870         }
871
872         /* Free this node since the driver cannot login or has the wrong
873            sparm */
874         lpfc_drop_node(vport, ndlp);
875         return NLP_STE_FREED_NODE;
876 }
877
878 static uint32_t
879 lpfc_device_rm_plogi_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
880                            void *arg, uint32_t evt)
881 {
882         struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
883
884         if (ndlp->nlp_flag & NLP_NPR_2B_DISC) {
885                 spin_lock_irq(shost->host_lock);
886                 ndlp->nlp_flag |= NLP_NODEV_REMOVE;
887                 spin_unlock_irq(shost->host_lock);
888                 return ndlp->nlp_state;
889         } else {
890                 /* software abort outstanding PLOGI */
891                 lpfc_els_abort(vport->phba, ndlp);
892
893                 lpfc_drop_node(vport, ndlp);
894                 return NLP_STE_FREED_NODE;
895         }
896 }
897
898 static uint32_t
899 lpfc_device_recov_plogi_issue(struct lpfc_vport *vport,
900                               struct lpfc_nodelist *ndlp,
901                               void *arg,
902                               uint32_t evt)
903 {
904         struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
905         struct lpfc_hba  *phba = vport->phba;
906
907         /* Don't do anything that will mess up processing of the
908          * previous RSCN.
909          */
910         if (vport->fc_flag & FC_RSCN_DEFERRED)
911                 return ndlp->nlp_state;
912
913         /* software abort outstanding PLOGI */
914         lpfc_els_abort(phba, ndlp);
915
916         ndlp->nlp_prev_state = NLP_STE_PLOGI_ISSUE;
917         lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
918         spin_lock_irq(shost->host_lock);
919         ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC);
920         spin_unlock_irq(shost->host_lock);
921
922         return ndlp->nlp_state;
923 }
924
925 static uint32_t
926 lpfc_rcv_plogi_adisc_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
927                            void *arg, uint32_t evt)
928 {
929         struct lpfc_hba   *phba = vport->phba;
930         struct lpfc_iocbq *cmdiocb;
931
932         /* software abort outstanding ADISC */
933         lpfc_els_abort(phba, ndlp);
934
935         cmdiocb = (struct lpfc_iocbq *) arg;
936
937         if (lpfc_rcv_plogi(vport, ndlp, cmdiocb))
938                 return ndlp->nlp_state;
939
940         ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE;
941         lpfc_issue_els_plogi(vport, ndlp->nlp_DID, 0);
942         lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE);
943
944         return ndlp->nlp_state;
945 }
946
947 static uint32_t
948 lpfc_rcv_prli_adisc_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
949                           void *arg, uint32_t evt)
950 {
951         struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
952
953         lpfc_els_rsp_prli_acc(vport, cmdiocb, ndlp);
954         return ndlp->nlp_state;
955 }
956
957 static uint32_t
958 lpfc_rcv_logo_adisc_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
959                           void *arg, uint32_t evt)
960 {
961         struct lpfc_hba *phba = vport->phba;
962         struct lpfc_iocbq *cmdiocb;
963
964         cmdiocb = (struct lpfc_iocbq *) arg;
965
966         /* software abort outstanding ADISC */
967         lpfc_els_abort(phba, ndlp);
968
969         lpfc_rcv_logo(vport, ndlp, cmdiocb, ELS_CMD_LOGO);
970         return ndlp->nlp_state;
971 }
972
973 static uint32_t
974 lpfc_rcv_padisc_adisc_issue(struct lpfc_vport *vport,
975                             struct lpfc_nodelist *ndlp,
976                             void *arg, uint32_t evt)
977 {
978         struct lpfc_iocbq *cmdiocb;
979
980         cmdiocb = (struct lpfc_iocbq *) arg;
981
982         lpfc_rcv_padisc(vport, ndlp, cmdiocb);
983         return ndlp->nlp_state;
984 }
985
986 static uint32_t
987 lpfc_rcv_prlo_adisc_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
988                           void *arg, uint32_t evt)
989 {
990         struct lpfc_iocbq *cmdiocb;
991
992         cmdiocb = (struct lpfc_iocbq *) arg;
993
994         /* Treat like rcv logo */
995         lpfc_rcv_logo(vport, ndlp, cmdiocb, ELS_CMD_PRLO);
996         return ndlp->nlp_state;
997 }
998
999 static uint32_t
1000 lpfc_cmpl_adisc_adisc_issue(struct lpfc_vport *vport,
1001                             struct lpfc_nodelist *ndlp,
1002                             void *arg, uint32_t evt)
1003 {
1004         struct Scsi_Host  *shost = lpfc_shost_from_vport(vport);
1005         struct lpfc_hba   *phba = vport->phba;
1006         struct lpfc_iocbq *cmdiocb, *rspiocb;
1007         IOCB_t *irsp;
1008         ADISC *ap;
1009
1010         cmdiocb = (struct lpfc_iocbq *) arg;
1011         rspiocb = cmdiocb->context_un.rsp_iocb;
1012
1013         ap = (ADISC *)lpfc_check_elscmpl_iocb(phba, cmdiocb, rspiocb);
1014         irsp = &rspiocb->iocb;
1015
1016         if ((irsp->ulpStatus) ||
1017             (!lpfc_check_adisc(vport, ndlp, &ap->nodeName, &ap->portName))) {
1018                 /* 1 sec timeout */
1019                 mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ);
1020                 spin_lock_irq(shost->host_lock);
1021                 ndlp->nlp_flag |= NLP_DELAY_TMO;
1022                 spin_unlock_irq(shost->host_lock);
1023                 ndlp->nlp_last_elscmd = ELS_CMD_PLOGI;
1024
1025                 memset(&ndlp->nlp_nodename, 0, sizeof(struct lpfc_name));
1026                 memset(&ndlp->nlp_portname, 0, sizeof(struct lpfc_name));
1027
1028                 ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE;
1029                 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
1030                 lpfc_unreg_rpi(vport, ndlp);
1031                 return ndlp->nlp_state;
1032         }
1033
1034         if (ndlp->nlp_type & NLP_FCP_TARGET) {
1035                 ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE;
1036                 lpfc_nlp_set_state(vport, ndlp, NLP_STE_MAPPED_NODE);
1037         } else {
1038                 ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE;
1039                 lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE);
1040         }
1041         return ndlp->nlp_state;
1042 }
1043
1044 static uint32_t
1045 lpfc_device_rm_adisc_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
1046                            void *arg, uint32_t evt)
1047 {
1048         struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
1049
1050         if (ndlp->nlp_flag & NLP_NPR_2B_DISC) {
1051                 spin_lock_irq(shost->host_lock);
1052                 ndlp->nlp_flag |= NLP_NODEV_REMOVE;
1053                 spin_unlock_irq(shost->host_lock);
1054                 return ndlp->nlp_state;
1055         } else {
1056                 /* software abort outstanding ADISC */
1057                 lpfc_els_abort(vport->phba, ndlp);
1058
1059                 lpfc_drop_node(vport, ndlp);
1060                 return NLP_STE_FREED_NODE;
1061         }
1062 }
1063
1064 static uint32_t
1065 lpfc_device_recov_adisc_issue(struct lpfc_vport *vport,
1066                               struct lpfc_nodelist *ndlp,
1067                               void *arg,
1068                               uint32_t evt)
1069 {
1070         struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
1071         struct lpfc_hba  *phba = vport->phba;
1072
1073         /* Don't do anything that will mess up processing of the
1074          * previous RSCN.
1075          */
1076         if (vport->fc_flag & FC_RSCN_DEFERRED)
1077                 return ndlp->nlp_state;
1078
1079         /* software abort outstanding ADISC */
1080         lpfc_els_abort(phba, ndlp);
1081
1082         ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE;
1083         lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
1084         spin_lock_irq(shost->host_lock);
1085         ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC);
1086         spin_unlock_irq(shost->host_lock);
1087         lpfc_disc_set_adisc(vport, ndlp);
1088         return ndlp->nlp_state;
1089 }
1090
1091 static uint32_t
1092 lpfc_rcv_plogi_reglogin_issue(struct lpfc_vport *vport,
1093                               struct lpfc_nodelist *ndlp,
1094                               void *arg,
1095                               uint32_t evt)
1096 {
1097         struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
1098
1099         lpfc_rcv_plogi(vport, ndlp, cmdiocb);
1100         return ndlp->nlp_state;
1101 }
1102
1103 static uint32_t
1104 lpfc_rcv_prli_reglogin_issue(struct lpfc_vport *vport,
1105                              struct lpfc_nodelist *ndlp,
1106                              void *arg,
1107                              uint32_t evt)
1108 {
1109         struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
1110
1111         lpfc_els_rsp_prli_acc(vport, cmdiocb, ndlp);
1112         return ndlp->nlp_state;
1113 }
1114
1115 static uint32_t
1116 lpfc_rcv_logo_reglogin_issue(struct lpfc_vport *vport,
1117                              struct lpfc_nodelist *ndlp,
1118                              void *arg,
1119                              uint32_t evt)
1120 {
1121         struct lpfc_hba   *phba = vport->phba;
1122         struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
1123         LPFC_MBOXQ_t      *mb;
1124         LPFC_MBOXQ_t      *nextmb;
1125         struct lpfc_dmabuf *mp;
1126
1127         cmdiocb = (struct lpfc_iocbq *) arg;
1128
1129         /* cleanup any ndlp on mbox q waiting for reglogin cmpl */
1130         if ((mb = phba->sli.mbox_active)) {
1131                 if ((mb->mb.mbxCommand == MBX_REG_LOGIN64) &&
1132                    (ndlp == (struct lpfc_nodelist *) mb->context2)) {
1133                         lpfc_nlp_put(ndlp);
1134                         mb->context2 = NULL;
1135                         mb->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
1136                 }
1137         }
1138
1139         spin_lock_irq(&phba->hbalock);
1140         list_for_each_entry_safe(mb, nextmb, &phba->sli.mboxq, list) {
1141                 if ((mb->mb.mbxCommand == MBX_REG_LOGIN64) &&
1142                    (ndlp == (struct lpfc_nodelist *) mb->context2)) {
1143                         mp = (struct lpfc_dmabuf *) (mb->context1);
1144                         if (mp) {
1145                                 lpfc_mbuf_free(phba, mp->virt, mp->phys);
1146                                 kfree(mp);
1147                         }
1148                         lpfc_nlp_put(ndlp);
1149                         list_del(&mb->list);
1150                         mempool_free(mb, phba->mbox_mem_pool);
1151                 }
1152         }
1153         spin_unlock_irq(&phba->hbalock);
1154
1155         lpfc_rcv_logo(vport, ndlp, cmdiocb, ELS_CMD_LOGO);
1156         return ndlp->nlp_state;
1157 }
1158
1159 static uint32_t
1160 lpfc_rcv_padisc_reglogin_issue(struct lpfc_vport *vport,
1161                                struct lpfc_nodelist *ndlp,
1162                                void *arg,
1163                                uint32_t evt)
1164 {
1165         struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
1166
1167         lpfc_rcv_padisc(vport, ndlp, cmdiocb);
1168         return ndlp->nlp_state;
1169 }
1170
1171 static uint32_t
1172 lpfc_rcv_prlo_reglogin_issue(struct lpfc_vport *vport,
1173                              struct lpfc_nodelist *ndlp,
1174                              void *arg,
1175                              uint32_t evt)
1176 {
1177         struct lpfc_iocbq *cmdiocb;
1178
1179         cmdiocb = (struct lpfc_iocbq *) arg;
1180         lpfc_els_rsp_acc(vport, ELS_CMD_PRLO, cmdiocb, ndlp, NULL, 0);
1181         return ndlp->nlp_state;
1182 }
1183
1184 static uint32_t
1185 lpfc_cmpl_reglogin_reglogin_issue(struct lpfc_vport *vport,
1186                                   struct lpfc_nodelist *ndlp,
1187                                   void *arg,
1188                                   uint32_t evt)
1189 {
1190         struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
1191         struct lpfc_hba  *phba = vport->phba;
1192         LPFC_MBOXQ_t *pmb = (LPFC_MBOXQ_t *) arg;
1193         MAILBOX_t *mb = &pmb->mb;
1194         uint32_t did  = mb->un.varWords[1];
1195
1196         if (mb->mbxStatus) {
1197                 /* RegLogin failed */
1198                 lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY,
1199                                 "%d (%d):0246 RegLogin failed Data: x%x x%x "
1200                                 "x%x\n",
1201                                 phba->brd_no, vport->vpi,
1202                                 did, mb->mbxStatus, vport->port_state);
1203
1204                 /*
1205                  * If RegLogin failed due to lack of HBA resources do not
1206                  * retry discovery.
1207                  */
1208                 if (mb->mbxStatus == MBXERR_RPI_FULL) {
1209                         ndlp->nlp_prev_state = NLP_STE_UNUSED_NODE;
1210                         lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNUSED_NODE);
1211                         return ndlp->nlp_state;
1212                 }
1213
1214                 /* Put ndlp in npr state set plogi timer for 1 sec */
1215                 mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ * 1);
1216                 spin_lock_irq(shost->host_lock);
1217                 ndlp->nlp_flag |= NLP_DELAY_TMO;
1218                 spin_unlock_irq(shost->host_lock);
1219                 ndlp->nlp_last_elscmd = ELS_CMD_PLOGI;
1220
1221                 lpfc_issue_els_logo(vport, ndlp, 0);
1222                 ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE;
1223                 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
1224                 return ndlp->nlp_state;
1225         }
1226
1227         ndlp->nlp_rpi = mb->un.varWords[0];
1228
1229         /* Only if we are not a fabric nport do we issue PRLI */
1230         if (!(ndlp->nlp_type & NLP_FABRIC)) {
1231                 ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE;
1232                 lpfc_nlp_set_state(vport, ndlp, NLP_STE_PRLI_ISSUE);
1233                 lpfc_issue_els_prli(vport, ndlp, 0);
1234         } else {
1235                 ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE;
1236                 lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE);
1237         }
1238         return ndlp->nlp_state;
1239 }
1240
1241 static uint32_t
1242 lpfc_device_rm_reglogin_issue(struct lpfc_vport *vport,
1243                               struct lpfc_nodelist *ndlp,
1244                               void *arg,
1245                               uint32_t evt)
1246 {
1247         struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
1248
1249         if (ndlp->nlp_flag & NLP_NPR_2B_DISC) {
1250                 spin_lock_irq(shost->host_lock);
1251                 ndlp->nlp_flag |= NLP_NODEV_REMOVE;
1252                 spin_unlock_irq(shost->host_lock);
1253                 return ndlp->nlp_state;
1254         } else {
1255                 lpfc_drop_node(vport, ndlp);
1256                 return NLP_STE_FREED_NODE;
1257         }
1258 }
1259
1260 static uint32_t
1261 lpfc_device_recov_reglogin_issue(struct lpfc_vport *vport,
1262                                  struct lpfc_nodelist *ndlp,
1263                                  void *arg,
1264                                  uint32_t evt)
1265 {
1266         struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
1267
1268         /* Don't do anything that will mess up processing of the
1269          * previous RSCN.
1270          */
1271         if (vport->fc_flag & FC_RSCN_DEFERRED)
1272                 return ndlp->nlp_state;
1273
1274         ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE;
1275         lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
1276         spin_lock_irq(shost->host_lock);
1277         ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC);
1278         spin_unlock_irq(shost->host_lock);
1279         lpfc_disc_set_adisc(vport, ndlp);
1280         return ndlp->nlp_state;
1281 }
1282
1283 static uint32_t
1284 lpfc_rcv_plogi_prli_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
1285                           void *arg, uint32_t evt)
1286 {
1287         struct lpfc_iocbq *cmdiocb;
1288
1289         cmdiocb = (struct lpfc_iocbq *) arg;
1290
1291         lpfc_rcv_plogi(vport, ndlp, cmdiocb);
1292         return ndlp->nlp_state;
1293 }
1294
1295 static uint32_t
1296 lpfc_rcv_prli_prli_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
1297                          void *arg, uint32_t evt)
1298 {
1299         struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
1300
1301         lpfc_els_rsp_prli_acc(vport, cmdiocb, ndlp);
1302         return ndlp->nlp_state;
1303 }
1304
1305 static uint32_t
1306 lpfc_rcv_logo_prli_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
1307                          void *arg, uint32_t evt)
1308 {
1309         struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
1310
1311         /* Software abort outstanding PRLI before sending acc */
1312         lpfc_els_abort(vport->phba, ndlp);
1313
1314         lpfc_rcv_logo(vport, ndlp, cmdiocb, ELS_CMD_LOGO);
1315         return ndlp->nlp_state;
1316 }
1317
1318 static uint32_t
1319 lpfc_rcv_padisc_prli_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
1320                            void *arg, uint32_t evt)
1321 {
1322         struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
1323
1324         lpfc_rcv_padisc(vport, ndlp, cmdiocb);
1325         return ndlp->nlp_state;
1326 }
1327
1328 /* This routine is envoked when we rcv a PRLO request from a nport
1329  * we are logged into.  We should send back a PRLO rsp setting the
1330  * appropriate bits.
1331  * NEXT STATE = PRLI_ISSUE
1332  */
1333 static uint32_t
1334 lpfc_rcv_prlo_prli_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
1335                          void *arg, uint32_t evt)
1336 {
1337         struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
1338
1339         lpfc_els_rsp_acc(vport, ELS_CMD_PRLO, cmdiocb, ndlp, NULL, 0);
1340         return ndlp->nlp_state;
1341 }
1342
1343 static uint32_t
1344 lpfc_cmpl_prli_prli_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
1345                           void *arg, uint32_t evt)
1346 {
1347         struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
1348         struct lpfc_iocbq *cmdiocb, *rspiocb;
1349         struct lpfc_hba   *phba = vport->phba;
1350         IOCB_t *irsp;
1351         PRLI *npr;
1352
1353         cmdiocb = (struct lpfc_iocbq *) arg;
1354         rspiocb = cmdiocb->context_un.rsp_iocb;
1355         npr = (PRLI *)lpfc_check_elscmpl_iocb(phba, cmdiocb, rspiocb);
1356
1357         irsp = &rspiocb->iocb;
1358         if (irsp->ulpStatus) {
1359                 if ((vport->port_type == LPFC_NPIV_PORT) &&
1360                     vport->cfg_restrict_login) {
1361                         goto out;
1362                 }
1363                 ndlp->nlp_prev_state = NLP_STE_PRLI_ISSUE;
1364                 lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE);
1365                 return ndlp->nlp_state;
1366         }
1367
1368         /* Check out PRLI rsp */
1369         ndlp->nlp_type &= ~(NLP_FCP_TARGET | NLP_FCP_INITIATOR);
1370         ndlp->nlp_fcp_info &= ~NLP_FCP_2_DEVICE;
1371         if ((npr->acceptRspCode == PRLI_REQ_EXECUTED) &&
1372             (npr->prliType == PRLI_FCP_TYPE)) {
1373                 if (npr->initiatorFunc)
1374                         ndlp->nlp_type |= NLP_FCP_INITIATOR;
1375                 if (npr->targetFunc)
1376                         ndlp->nlp_type |= NLP_FCP_TARGET;
1377                 if (npr->Retry)
1378                         ndlp->nlp_fcp_info |= NLP_FCP_2_DEVICE;
1379         }
1380         if (!(ndlp->nlp_type & NLP_FCP_TARGET) &&
1381             (vport->port_type == LPFC_NPIV_PORT) &&
1382              vport->cfg_restrict_login) {
1383 out:
1384                 spin_lock_irq(shost->host_lock);
1385                 ndlp->nlp_flag |= NLP_TARGET_REMOVE;
1386                 spin_unlock_irq(shost->host_lock);
1387                 lpfc_issue_els_logo(vport, ndlp, 0);
1388
1389                 ndlp->nlp_prev_state = NLP_STE_PRLI_ISSUE;
1390                 lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNUSED_NODE);
1391                 return ndlp->nlp_state;
1392         }
1393
1394         ndlp->nlp_prev_state = NLP_STE_PRLI_ISSUE;
1395         if (ndlp->nlp_type & NLP_FCP_TARGET)
1396                 lpfc_nlp_set_state(vport, ndlp, NLP_STE_MAPPED_NODE);
1397         else
1398                 lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE);
1399         return ndlp->nlp_state;
1400 }
1401
1402 /*! lpfc_device_rm_prli_issue
1403  *
1404  * \pre
1405  * \post
1406  * \param   phba
1407  * \param   ndlp
1408  * \param   arg
1409  * \param   evt
1410  * \return  uint32_t
1411  *
1412  * \b Description:
1413  *    This routine is envoked when we a request to remove a nport we are in the
1414  *    process of PRLIing. We should software abort outstanding prli, unreg
1415  *    login, send a logout. We will change node state to UNUSED_NODE, put it
1416  *    on plogi list so it can be freed when LOGO completes.
1417  *
1418  */
1419
1420 static uint32_t
1421 lpfc_device_rm_prli_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
1422                           void *arg, uint32_t evt)
1423 {
1424         struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
1425
1426         if (ndlp->nlp_flag & NLP_NPR_2B_DISC) {
1427                 spin_lock_irq(shost->host_lock);
1428                 ndlp->nlp_flag |= NLP_NODEV_REMOVE;
1429                 spin_unlock_irq(shost->host_lock);
1430                 return ndlp->nlp_state;
1431         } else {
1432                 /* software abort outstanding PLOGI */
1433                 lpfc_els_abort(vport->phba, ndlp);
1434
1435                 lpfc_drop_node(vport, ndlp);
1436                 return NLP_STE_FREED_NODE;
1437         }
1438 }
1439
1440
1441 /*! lpfc_device_recov_prli_issue
1442  *
1443  * \pre
1444  * \post
1445  * \param   phba
1446  * \param   ndlp
1447  * \param   arg
1448  * \param   evt
1449  * \return  uint32_t
1450  *
1451  * \b Description:
1452  *    The routine is envoked when the state of a device is unknown, like
1453  *    during a link down. We should remove the nodelist entry from the
1454  *    unmapped list, issue a UNREG_LOGIN, do a software abort of the
1455  *    outstanding PRLI command, then free the node entry.
1456  */
1457 static uint32_t
1458 lpfc_device_recov_prli_issue(struct lpfc_vport *vport,
1459                              struct lpfc_nodelist *ndlp,
1460                              void *arg,
1461                              uint32_t evt)
1462 {
1463         struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
1464         struct lpfc_hba  *phba = vport->phba;
1465
1466         /* Don't do anything that will mess up processing of the
1467          * previous RSCN.
1468          */
1469         if (vport->fc_flag & FC_RSCN_DEFERRED)
1470                 return ndlp->nlp_state;
1471
1472         /* software abort outstanding PRLI */
1473         lpfc_els_abort(phba, ndlp);
1474
1475         ndlp->nlp_prev_state = NLP_STE_PRLI_ISSUE;
1476         lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
1477         spin_lock_irq(shost->host_lock);
1478         ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC);
1479         spin_unlock_irq(shost->host_lock);
1480         lpfc_disc_set_adisc(vport, ndlp);
1481         return ndlp->nlp_state;
1482 }
1483
1484 static uint32_t
1485 lpfc_rcv_plogi_unmap_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
1486                           void *arg, uint32_t evt)
1487 {
1488         struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
1489
1490         lpfc_rcv_plogi(vport, ndlp, cmdiocb);
1491         return ndlp->nlp_state;
1492 }
1493
1494 static uint32_t
1495 lpfc_rcv_prli_unmap_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
1496                          void *arg, uint32_t evt)
1497 {
1498         struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
1499
1500         lpfc_rcv_prli(vport, ndlp, cmdiocb);
1501         lpfc_els_rsp_prli_acc(vport, cmdiocb, ndlp);
1502         return ndlp->nlp_state;
1503 }
1504
1505 static uint32_t
1506 lpfc_rcv_logo_unmap_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
1507                          void *arg, uint32_t evt)
1508 {
1509         struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
1510
1511         lpfc_rcv_logo(vport, ndlp, cmdiocb, ELS_CMD_LOGO);
1512         return ndlp->nlp_state;
1513 }
1514
1515 static uint32_t
1516 lpfc_rcv_padisc_unmap_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
1517                            void *arg, uint32_t evt)
1518 {
1519         struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
1520
1521         lpfc_rcv_padisc(vport, ndlp, cmdiocb);
1522         return ndlp->nlp_state;
1523 }
1524
1525 static uint32_t
1526 lpfc_rcv_prlo_unmap_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
1527                          void *arg, uint32_t evt)
1528 {
1529         struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
1530
1531         lpfc_els_rsp_acc(vport, ELS_CMD_PRLO, cmdiocb, ndlp, NULL, 0);
1532         return ndlp->nlp_state;
1533 }
1534
1535 static uint32_t
1536 lpfc_device_recov_unmap_node(struct lpfc_vport *vport,
1537                              struct lpfc_nodelist *ndlp,
1538                              void *arg,
1539                              uint32_t evt)
1540 {
1541         struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
1542
1543         ndlp->nlp_prev_state = NLP_STE_UNMAPPED_NODE;
1544         lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
1545         spin_lock_irq(shost->host_lock);
1546         ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC);
1547         spin_unlock_irq(shost->host_lock);
1548         lpfc_disc_set_adisc(vport, ndlp);
1549
1550         return ndlp->nlp_state;
1551 }
1552
1553 static uint32_t
1554 lpfc_rcv_plogi_mapped_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
1555                            void *arg, uint32_t evt)
1556 {
1557         struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
1558
1559         lpfc_rcv_plogi(vport, ndlp, cmdiocb);
1560         return ndlp->nlp_state;
1561 }
1562
1563 static uint32_t
1564 lpfc_rcv_prli_mapped_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
1565                           void *arg, uint32_t evt)
1566 {
1567         struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
1568
1569         lpfc_els_rsp_prli_acc(vport, cmdiocb, ndlp);
1570         return ndlp->nlp_state;
1571 }
1572
1573 static uint32_t
1574 lpfc_rcv_logo_mapped_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
1575                           void *arg, uint32_t evt)
1576 {
1577         struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
1578
1579         lpfc_rcv_logo(vport, ndlp, cmdiocb, ELS_CMD_LOGO);
1580         return ndlp->nlp_state;
1581 }
1582
1583 static uint32_t
1584 lpfc_rcv_padisc_mapped_node(struct lpfc_vport *vport,
1585                             struct lpfc_nodelist *ndlp,
1586                             void *arg, uint32_t evt)
1587 {
1588         struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
1589
1590         lpfc_rcv_padisc(vport, ndlp, cmdiocb);
1591         return ndlp->nlp_state;
1592 }
1593
1594 static uint32_t
1595 lpfc_rcv_prlo_mapped_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
1596                           void *arg, uint32_t evt)
1597 {
1598         struct lpfc_hba  *phba = vport->phba;
1599         struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
1600
1601         /* flush the target */
1602         lpfc_sli_abort_iocb(phba, &phba->sli.ring[phba->sli.fcp_ring],
1603                             ndlp->nlp_sid, 0, 0, LPFC_CTX_TGT);
1604
1605         /* Treat like rcv logo */
1606         lpfc_rcv_logo(vport, ndlp, cmdiocb, ELS_CMD_PRLO);
1607         return ndlp->nlp_state;
1608 }
1609
1610 static uint32_t
1611 lpfc_device_recov_mapped_node(struct lpfc_vport *vport,
1612                               struct lpfc_nodelist *ndlp,
1613                               void *arg,
1614                               uint32_t evt)
1615 {
1616         struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
1617
1618         ndlp->nlp_prev_state = NLP_STE_MAPPED_NODE;
1619         lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
1620         spin_lock_irq(shost->host_lock);
1621         ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC);
1622         spin_unlock_irq(shost->host_lock);
1623         lpfc_disc_set_adisc(vport, ndlp);
1624         return ndlp->nlp_state;
1625 }
1626
1627 static uint32_t
1628 lpfc_rcv_plogi_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
1629                         void *arg, uint32_t evt)
1630 {
1631         struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
1632         struct lpfc_iocbq *cmdiocb  = (struct lpfc_iocbq *) arg;
1633
1634         /* Ignore PLOGI if we have an outstanding LOGO */
1635         if (ndlp->nlp_flag & (NLP_LOGO_SND | NLP_LOGO_ACC)) {
1636                 return ndlp->nlp_state;
1637         }
1638
1639         if (lpfc_rcv_plogi(vport, ndlp, cmdiocb)) {
1640                 spin_lock_irq(shost->host_lock);
1641                 ndlp->nlp_flag &= ~NLP_NPR_ADISC;
1642                 spin_unlock_irq(shost->host_lock);
1643                 return ndlp->nlp_state;
1644         }
1645
1646         /* send PLOGI immediately, move to PLOGI issue state */
1647         if (!(ndlp->nlp_flag & NLP_DELAY_TMO)) {
1648                 ndlp->nlp_prev_state = NLP_STE_NPR_NODE;
1649                 lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE);
1650                 lpfc_issue_els_plogi(vport, ndlp->nlp_DID, 0);
1651         }
1652
1653         return ndlp->nlp_state;
1654 }
1655
1656 static uint32_t
1657 lpfc_rcv_prli_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
1658                        void *arg, uint32_t evt)
1659 {
1660         struct Scsi_Host  *shost = lpfc_shost_from_vport(vport);
1661         struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
1662         struct ls_rjt     stat;
1663
1664         memset(&stat, 0, sizeof (struct ls_rjt));
1665         stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
1666         stat.un.b.lsRjtRsnCodeExp = LSEXP_NOTHING_MORE;
1667         lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp, NULL);
1668
1669         if (!(ndlp->nlp_flag & NLP_DELAY_TMO)) {
1670                 if (ndlp->nlp_flag & NLP_NPR_ADISC) {
1671                         spin_lock_irq(shost->host_lock);
1672                         ndlp->nlp_flag &= ~NLP_NPR_ADISC;
1673                         ndlp->nlp_prev_state = NLP_STE_NPR_NODE;
1674                         spin_unlock_irq(shost->host_lock);
1675                         lpfc_nlp_set_state(vport, ndlp, NLP_STE_ADISC_ISSUE);
1676                         lpfc_issue_els_adisc(vport, ndlp, 0);
1677                 } else {
1678                         ndlp->nlp_prev_state = NLP_STE_NPR_NODE;
1679                         lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE);
1680                         lpfc_issue_els_plogi(vport, ndlp->nlp_DID, 0);
1681                 }
1682         }
1683         return ndlp->nlp_state;
1684 }
1685
1686 static uint32_t
1687 lpfc_rcv_logo_npr_node(struct lpfc_vport *vport,  struct lpfc_nodelist *ndlp,
1688                        void *arg, uint32_t evt)
1689 {
1690         struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
1691
1692         lpfc_rcv_logo(vport, ndlp, cmdiocb, ELS_CMD_LOGO);
1693         return ndlp->nlp_state;
1694 }
1695
1696 static uint32_t
1697 lpfc_rcv_padisc_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
1698                          void *arg, uint32_t evt)
1699 {
1700         struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
1701
1702         lpfc_rcv_padisc(vport, ndlp, cmdiocb);
1703
1704         /*
1705          * Do not start discovery if discovery is about to start
1706          * or discovery in progress for this node. Starting discovery
1707          * here will affect the counting of discovery threads.
1708          */
1709         if (!(ndlp->nlp_flag & NLP_DELAY_TMO) &&
1710             !(ndlp->nlp_flag & NLP_NPR_2B_DISC)) {
1711                 if (ndlp->nlp_flag & NLP_NPR_ADISC) {
1712                         ndlp->nlp_flag &= ~NLP_NPR_ADISC;
1713                         ndlp->nlp_prev_state = NLP_STE_NPR_NODE;
1714                         lpfc_nlp_set_state(vport, ndlp, NLP_STE_ADISC_ISSUE);
1715                         lpfc_issue_els_adisc(vport, ndlp, 0);
1716                 } else {
1717                         ndlp->nlp_prev_state = NLP_STE_NPR_NODE;
1718                         lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE);
1719                         lpfc_issue_els_plogi(vport, ndlp->nlp_DID, 0);
1720                 }
1721         }
1722         return ndlp->nlp_state;
1723 }
1724
1725 static uint32_t
1726 lpfc_rcv_prlo_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
1727                        void *arg, uint32_t evt)
1728 {
1729         struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
1730         struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
1731
1732         spin_lock_irq(shost->host_lock);
1733         ndlp->nlp_flag |= NLP_LOGO_ACC;
1734         spin_unlock_irq(shost->host_lock);
1735
1736         lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0);
1737
1738         if ((ndlp->nlp_flag & NLP_DELAY_TMO) == 0) {
1739                 mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ * 1);
1740                 spin_lock_irq(shost->host_lock);
1741                 ndlp->nlp_flag |= NLP_DELAY_TMO;
1742                 ndlp->nlp_flag &= ~NLP_NPR_ADISC;
1743                 spin_unlock_irq(shost->host_lock);
1744                 ndlp->nlp_last_elscmd = ELS_CMD_PLOGI;
1745         } else {
1746                 spin_lock_irq(shost->host_lock);
1747                 ndlp->nlp_flag &= ~NLP_NPR_ADISC;
1748                 spin_unlock_irq(shost->host_lock);
1749         }
1750         return ndlp->nlp_state;
1751 }
1752
1753 static uint32_t
1754 lpfc_cmpl_plogi_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
1755                          void *arg, uint32_t evt)
1756 {
1757         struct lpfc_iocbq *cmdiocb, *rspiocb;
1758         IOCB_t *irsp;
1759
1760         cmdiocb = (struct lpfc_iocbq *) arg;
1761         rspiocb = cmdiocb->context_un.rsp_iocb;
1762
1763         irsp = &rspiocb->iocb;
1764         if (irsp->ulpStatus) {
1765                 lpfc_drop_node(vport, ndlp);
1766                 return NLP_STE_FREED_NODE;
1767         }
1768         return ndlp->nlp_state;
1769 }
1770
1771 static uint32_t
1772 lpfc_cmpl_prli_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
1773                         void *arg, uint32_t evt)
1774 {
1775         struct lpfc_iocbq *cmdiocb, *rspiocb;
1776         IOCB_t *irsp;
1777
1778         cmdiocb = (struct lpfc_iocbq *) arg;
1779         rspiocb = cmdiocb->context_un.rsp_iocb;
1780
1781         irsp = &rspiocb->iocb;
1782         if (irsp->ulpStatus && (ndlp->nlp_flag & NLP_NODEV_REMOVE)) {
1783                 lpfc_drop_node(vport, ndlp);
1784                 return NLP_STE_FREED_NODE;
1785         }
1786         return ndlp->nlp_state;
1787 }
1788
1789 static uint32_t
1790 lpfc_cmpl_logo_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
1791                         void *arg, uint32_t evt)
1792 {
1793         lpfc_unreg_rpi(vport, ndlp);
1794         /* This routine does nothing, just return the current state */
1795         return ndlp->nlp_state;
1796 }
1797
1798 static uint32_t
1799 lpfc_cmpl_adisc_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
1800                          void *arg, uint32_t evt)
1801 {
1802         struct lpfc_iocbq *cmdiocb, *rspiocb;
1803         IOCB_t *irsp;
1804
1805         cmdiocb = (struct lpfc_iocbq *) arg;
1806         rspiocb = cmdiocb->context_un.rsp_iocb;
1807
1808         irsp = &rspiocb->iocb;
1809         if (irsp->ulpStatus && (ndlp->nlp_flag & NLP_NODEV_REMOVE)) {
1810                 lpfc_drop_node(vport, ndlp);
1811                 return NLP_STE_FREED_NODE;
1812         }
1813         return ndlp->nlp_state;
1814 }
1815
1816 static uint32_t
1817 lpfc_cmpl_reglogin_npr_node(struct lpfc_vport *vport,
1818                             struct lpfc_nodelist *ndlp,
1819                             void *arg, uint32_t evt)
1820 {
1821         LPFC_MBOXQ_t *pmb = (LPFC_MBOXQ_t *) arg;
1822         MAILBOX_t    *mb = &pmb->mb;
1823
1824         if (!mb->mbxStatus)
1825                 ndlp->nlp_rpi = mb->un.varWords[0];
1826         else {
1827                 if (ndlp->nlp_flag & NLP_NODEV_REMOVE) {
1828                         lpfc_drop_node(vport, ndlp);
1829                         return NLP_STE_FREED_NODE;
1830                 }
1831         }
1832         return ndlp->nlp_state;
1833 }
1834
1835 static uint32_t
1836 lpfc_device_rm_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
1837                         void *arg, uint32_t evt)
1838 {
1839         struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
1840
1841         if (ndlp->nlp_flag & NLP_NPR_2B_DISC) {
1842                 spin_lock_irq(shost->host_lock);
1843                 ndlp->nlp_flag |= NLP_NODEV_REMOVE;
1844                 spin_unlock_irq(shost->host_lock);
1845                 return ndlp->nlp_state;
1846         }
1847         lpfc_drop_node(vport, ndlp);
1848         return NLP_STE_FREED_NODE;
1849 }
1850
1851 static uint32_t
1852 lpfc_device_recov_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
1853                            void *arg, uint32_t evt)
1854 {
1855         struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
1856
1857         /* Don't do anything that will mess up processing of the
1858          * previous RSCN.
1859          */
1860         if (vport->fc_flag & FC_RSCN_DEFERRED)
1861                 return ndlp->nlp_state;
1862
1863         spin_lock_irq(shost->host_lock);
1864         ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC);
1865         spin_unlock_irq(shost->host_lock);
1866         if (ndlp->nlp_flag & NLP_DELAY_TMO) {
1867                 lpfc_cancel_retry_delay_tmo(vport, ndlp);
1868         }
1869         return ndlp->nlp_state;
1870 }
1871
1872
1873 /* This next section defines the NPort Discovery State Machine */
1874
1875 /* There are 4 different double linked lists nodelist entries can reside on.
1876  * The plogi list and adisc list are used when Link Up discovery or RSCN
1877  * processing is needed. Each list holds the nodes that we will send PLOGI
1878  * or ADISC on. These lists will keep track of what nodes will be effected
1879  * by an RSCN, or a Link Up (Typically, all nodes are effected on Link Up).
1880  * The unmapped_list will contain all nodes that we have successfully logged
1881  * into at the Fibre Channel level. The mapped_list will contain all nodes
1882  * that are mapped FCP targets.
1883  */
1884 /*
1885  * The bind list is a list of undiscovered (potentially non-existent) nodes
1886  * that we have saved binding information on. This information is used when
1887  * nodes transition from the unmapped to the mapped list.
1888  */
1889 /* For UNUSED_NODE state, the node has just been allocated .
1890  * For PLOGI_ISSUE and REG_LOGIN_ISSUE, the node is on
1891  * the PLOGI list. For REG_LOGIN_COMPL, the node is taken off the PLOGI list
1892  * and put on the unmapped list. For ADISC processing, the node is taken off
1893  * the ADISC list and placed on either the mapped or unmapped list (depending
1894  * on its previous state). Once on the unmapped list, a PRLI is issued and the
1895  * state changed to PRLI_ISSUE. When the PRLI completion occurs, the state is
1896  * changed to UNMAPPED_NODE. If the completion indicates a mapped
1897  * node, the node is taken off the unmapped list. The binding list is checked
1898  * for a valid binding, or a binding is automatically assigned. If binding
1899  * assignment is unsuccessful, the node is left on the unmapped list. If
1900  * binding assignment is successful, the associated binding list entry (if
1901  * any) is removed, and the node is placed on the mapped list.
1902  */
1903 /*
1904  * For a Link Down, all nodes on the ADISC, PLOGI, unmapped or mapped
1905  * lists will receive a DEVICE_RECOVERY event. If the linkdown or devloss timers
1906  * expire, all effected nodes will receive a DEVICE_RM event.
1907  */
1908 /*
1909  * For a Link Up or RSCN, all nodes will move from the mapped / unmapped lists
1910  * to either the ADISC or PLOGI list.  After a Nameserver query or ALPA loopmap
1911  * check, additional nodes may be added or removed (via DEVICE_RM) to / from
1912  * the PLOGI or ADISC lists. Once the PLOGI and ADISC lists are populated,
1913  * we will first process the ADISC list.  32 entries are processed initially and
1914  * ADISC is initited for each one.  Completions / Events for each node are
1915  * funnelled thru the state machine.  As each node finishes ADISC processing, it
1916  * starts ADISC for any nodes waiting for ADISC processing. If no nodes are
1917  * waiting, and the ADISC list count is identically 0, then we are done. For
1918  * Link Up discovery, since all nodes on the PLOGI list are UNREG_LOGIN'ed, we
1919  * can issue a CLEAR_LA and reenable Link Events. Next we will process the PLOGI
1920  * list.  32 entries are processed initially and PLOGI is initited for each one.
1921  * Completions / Events for each node are funnelled thru the state machine.  As
1922  * each node finishes PLOGI processing, it starts PLOGI for any nodes waiting
1923  * for PLOGI processing. If no nodes are waiting, and the PLOGI list count is
1924  * indentically 0, then we are done. We have now completed discovery / RSCN
1925  * handling. Upon completion, ALL nodes should be on either the mapped or
1926  * unmapped lists.
1927  */
1928
1929 static uint32_t (*lpfc_disc_action[NLP_STE_MAX_STATE * NLP_EVT_MAX_EVENT])
1930      (struct lpfc_vport *, struct lpfc_nodelist *, void *, uint32_t) = {
1931         /* Action routine                  Event       Current State  */
1932         lpfc_rcv_plogi_unused_node,     /* RCV_PLOGI   UNUSED_NODE    */
1933         lpfc_rcv_els_unused_node,       /* RCV_PRLI        */
1934         lpfc_rcv_logo_unused_node,      /* RCV_LOGO        */
1935         lpfc_rcv_els_unused_node,       /* RCV_ADISC       */
1936         lpfc_rcv_els_unused_node,       /* RCV_PDISC       */
1937         lpfc_rcv_els_unused_node,       /* RCV_PRLO        */
1938         lpfc_disc_illegal,              /* CMPL_PLOGI      */
1939         lpfc_disc_illegal,              /* CMPL_PRLI       */
1940         lpfc_cmpl_logo_unused_node,     /* CMPL_LOGO       */
1941         lpfc_disc_illegal,              /* CMPL_ADISC      */
1942         lpfc_disc_illegal,              /* CMPL_REG_LOGIN  */
1943         lpfc_device_rm_unused_node,     /* DEVICE_RM       */
1944         lpfc_disc_illegal,              /* DEVICE_RECOVERY */
1945
1946         lpfc_rcv_plogi_plogi_issue,     /* RCV_PLOGI   PLOGI_ISSUE    */
1947         lpfc_rcv_prli_plogi_issue,      /* RCV_PRLI        */
1948         lpfc_rcv_logo_plogi_issue,      /* RCV_LOGO        */
1949         lpfc_rcv_els_plogi_issue,       /* RCV_ADISC       */
1950         lpfc_rcv_els_plogi_issue,       /* RCV_PDISC       */
1951         lpfc_rcv_els_plogi_issue,       /* RCV_PRLO        */
1952         lpfc_cmpl_plogi_plogi_issue,    /* CMPL_PLOGI      */
1953         lpfc_disc_illegal,              /* CMPL_PRLI       */
1954         lpfc_disc_illegal,              /* CMPL_LOGO       */
1955         lpfc_disc_illegal,              /* CMPL_ADISC      */
1956         lpfc_disc_illegal,              /* CMPL_REG_LOGIN  */
1957         lpfc_device_rm_plogi_issue,     /* DEVICE_RM       */
1958         lpfc_device_recov_plogi_issue,  /* DEVICE_RECOVERY */
1959
1960         lpfc_rcv_plogi_adisc_issue,     /* RCV_PLOGI   ADISC_ISSUE    */
1961         lpfc_rcv_prli_adisc_issue,      /* RCV_PRLI        */
1962         lpfc_rcv_logo_adisc_issue,      /* RCV_LOGO        */
1963         lpfc_rcv_padisc_adisc_issue,    /* RCV_ADISC       */
1964         lpfc_rcv_padisc_adisc_issue,    /* RCV_PDISC       */
1965         lpfc_rcv_prlo_adisc_issue,      /* RCV_PRLO        */
1966         lpfc_disc_illegal,              /* CMPL_PLOGI      */
1967         lpfc_disc_illegal,              /* CMPL_PRLI       */
1968         lpfc_disc_illegal,              /* CMPL_LOGO       */
1969         lpfc_cmpl_adisc_adisc_issue,    /* CMPL_ADISC      */
1970         lpfc_disc_illegal,              /* CMPL_REG_LOGIN  */
1971         lpfc_device_rm_adisc_issue,     /* DEVICE_RM       */
1972         lpfc_device_recov_adisc_issue,  /* DEVICE_RECOVERY */
1973
1974         lpfc_rcv_plogi_reglogin_issue,  /* RCV_PLOGI  REG_LOGIN_ISSUE */
1975         lpfc_rcv_prli_reglogin_issue,   /* RCV_PLOGI       */
1976         lpfc_rcv_logo_reglogin_issue,   /* RCV_LOGO        */
1977         lpfc_rcv_padisc_reglogin_issue, /* RCV_ADISC       */
1978         lpfc_rcv_padisc_reglogin_issue, /* RCV_PDISC       */
1979         lpfc_rcv_prlo_reglogin_issue,   /* RCV_PRLO        */
1980         lpfc_disc_illegal,              /* CMPL_PLOGI      */
1981         lpfc_disc_illegal,              /* CMPL_PRLI       */
1982         lpfc_disc_illegal,              /* CMPL_LOGO       */
1983         lpfc_disc_illegal,              /* CMPL_ADISC      */
1984         lpfc_cmpl_reglogin_reglogin_issue,/* CMPL_REG_LOGIN  */
1985         lpfc_device_rm_reglogin_issue,  /* DEVICE_RM       */
1986         lpfc_device_recov_reglogin_issue,/* DEVICE_RECOVERY */
1987
1988         lpfc_rcv_plogi_prli_issue,      /* RCV_PLOGI   PRLI_ISSUE     */
1989         lpfc_rcv_prli_prli_issue,       /* RCV_PRLI        */
1990         lpfc_rcv_logo_prli_issue,       /* RCV_LOGO        */
1991         lpfc_rcv_padisc_prli_issue,     /* RCV_ADISC       */
1992         lpfc_rcv_padisc_prli_issue,     /* RCV_PDISC       */
1993         lpfc_rcv_prlo_prli_issue,       /* RCV_PRLO        */
1994         lpfc_disc_illegal,              /* CMPL_PLOGI      */
1995         lpfc_cmpl_prli_prli_issue,      /* CMPL_PRLI       */
1996         lpfc_disc_illegal,              /* CMPL_LOGO       */
1997         lpfc_disc_illegal,              /* CMPL_ADISC      */
1998         lpfc_disc_illegal,              /* CMPL_REG_LOGIN  */
1999         lpfc_device_rm_prli_issue,      /* DEVICE_RM       */
2000         lpfc_device_recov_prli_issue,   /* DEVICE_RECOVERY */
2001
2002         lpfc_rcv_plogi_unmap_node,      /* RCV_PLOGI   UNMAPPED_NODE  */
2003         lpfc_rcv_prli_unmap_node,       /* RCV_PRLI        */
2004         lpfc_rcv_logo_unmap_node,       /* RCV_LOGO        */
2005         lpfc_rcv_padisc_unmap_node,     /* RCV_ADISC       */
2006         lpfc_rcv_padisc_unmap_node,     /* RCV_PDISC       */
2007         lpfc_rcv_prlo_unmap_node,       /* RCV_PRLO        */
2008         lpfc_disc_illegal,              /* CMPL_PLOGI      */
2009         lpfc_disc_illegal,              /* CMPL_PRLI       */
2010         lpfc_disc_illegal,              /* CMPL_LOGO       */
2011         lpfc_disc_illegal,              /* CMPL_ADISC      */
2012         lpfc_disc_illegal,              /* CMPL_REG_LOGIN  */
2013         lpfc_disc_illegal,              /* DEVICE_RM       */
2014         lpfc_device_recov_unmap_node,   /* DEVICE_RECOVERY */
2015
2016         lpfc_rcv_plogi_mapped_node,     /* RCV_PLOGI   MAPPED_NODE    */
2017         lpfc_rcv_prli_mapped_node,      /* RCV_PRLI        */
2018         lpfc_rcv_logo_mapped_node,      /* RCV_LOGO        */
2019         lpfc_rcv_padisc_mapped_node,    /* RCV_ADISC       */
2020         lpfc_rcv_padisc_mapped_node,    /* RCV_PDISC       */
2021         lpfc_rcv_prlo_mapped_node,      /* RCV_PRLO        */
2022         lpfc_disc_illegal,              /* CMPL_PLOGI      */
2023         lpfc_disc_illegal,              /* CMPL_PRLI       */
2024         lpfc_disc_illegal,              /* CMPL_LOGO       */
2025         lpfc_disc_illegal,              /* CMPL_ADISC      */
2026         lpfc_disc_illegal,              /* CMPL_REG_LOGIN  */
2027         lpfc_disc_illegal,              /* DEVICE_RM       */
2028         lpfc_device_recov_mapped_node,  /* DEVICE_RECOVERY */
2029
2030         lpfc_rcv_plogi_npr_node,        /* RCV_PLOGI   NPR_NODE    */
2031         lpfc_rcv_prli_npr_node,         /* RCV_PRLI        */
2032         lpfc_rcv_logo_npr_node,         /* RCV_LOGO        */
2033         lpfc_rcv_padisc_npr_node,       /* RCV_ADISC       */
2034         lpfc_rcv_padisc_npr_node,       /* RCV_PDISC       */
2035         lpfc_rcv_prlo_npr_node,         /* RCV_PRLO        */
2036         lpfc_cmpl_plogi_npr_node,       /* CMPL_PLOGI      */
2037         lpfc_cmpl_prli_npr_node,        /* CMPL_PRLI       */
2038         lpfc_cmpl_logo_npr_node,        /* CMPL_LOGO       */
2039         lpfc_cmpl_adisc_npr_node,       /* CMPL_ADISC      */
2040         lpfc_cmpl_reglogin_npr_node,    /* CMPL_REG_LOGIN  */
2041         lpfc_device_rm_npr_node,        /* DEVICE_RM       */
2042         lpfc_device_recov_npr_node,     /* DEVICE_RECOVERY */
2043 };
2044
2045 int
2046 lpfc_disc_state_machine(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2047                         void *arg, uint32_t evt)
2048 {
2049         struct lpfc_hba  *phba = vport->phba;
2050         uint32_t cur_state, rc;
2051         uint32_t(*func) (struct lpfc_vport *, struct lpfc_nodelist *, void *,
2052                          uint32_t);
2053
2054         lpfc_nlp_get(ndlp);
2055         cur_state = ndlp->nlp_state;
2056
2057         /* DSM in event <evt> on NPort <nlp_DID> in state <cur_state> */
2058         lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY,
2059                         "%d (%d):0211 DSM in event x%x on NPort x%x in "
2060                         "state %d Data: x%x\n",
2061                         phba->brd_no, vport->vpi,
2062                         evt, ndlp->nlp_DID, cur_state, ndlp->nlp_flag);
2063
2064         lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_DSM,
2065                  "DSM in:          evt:%d ste:%d did:x%x",
2066                 evt, cur_state, ndlp->nlp_DID);
2067
2068         func = lpfc_disc_action[(cur_state * NLP_EVT_MAX_EVENT) + evt];
2069         rc = (func) (vport, ndlp, arg, evt);
2070
2071         /* DSM out state <rc> on NPort <nlp_DID> */
2072         lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY,
2073                         "%d (%d):0212 DSM out state %d on NPort x%x "
2074                         "Data: x%x\n",
2075                         phba->brd_no, vport->vpi,
2076                         rc, ndlp->nlp_DID, ndlp->nlp_flag);
2077
2078         lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_DSM,
2079                  "DSM out:         ste:%d did:x%x flg:x%x",
2080                 rc, ndlp->nlp_DID, ndlp->nlp_flag);
2081
2082         lpfc_nlp_put(ndlp);
2083
2084         return rc;
2085 }