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