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