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