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