Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[SCSI] bfa: Add support for max target ports discovery

- Changes to avoid discovering NPIV port as remote port by the other
NPIV ports created on same physical port when all the NPIV ports are
part of the same zone in a fabric.
- Provided mechanism to support maximum number of target ports for a
given initiator port (physical port + NPIV ports) irrespective of the
way in which the initiator and target ports are zoned in the fabric.
- Introduced module_parameter max_rport_logins to restrict number of
remote ports discovery which includes target and initiator remote ports.

Signed-off-by: Vijaya Mohan Guvva <vmohan@brocade.com>
Signed-off-by: Krishna Gudipati <kgudipat@brocade.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>

authored by

Krishna Gudipati and committed by
James Bottomley
61ba4394 ce7242b8

+497 -178
+11 -1
drivers/scsi/bfa/bfa_fcpim.c
··· 1466 1466 bfa_itnim_get_ioprofile(struct bfa_itnim_s *itnim, 1467 1467 struct bfa_itnim_ioprofile_s *ioprofile) 1468 1468 { 1469 - struct bfa_fcpim_s *fcpim = BFA_FCPIM(itnim->bfa); 1469 + struct bfa_fcpim_s *fcpim; 1470 + 1471 + if (!itnim) 1472 + return BFA_STATUS_NO_FCPIM_NEXUS; 1473 + 1474 + fcpim = BFA_FCPIM(itnim->bfa); 1475 + 1470 1476 if (!fcpim->io_profile) 1471 1477 return BFA_STATUS_IOPROFILE_OFF; 1472 1478 ··· 1490 1484 bfa_itnim_clear_stats(struct bfa_itnim_s *itnim) 1491 1485 { 1492 1486 int j; 1487 + 1488 + if (!itnim) 1489 + return; 1490 + 1493 1491 memset(&itnim->stats, 0, sizeof(itnim->stats)); 1494 1492 memset(&itnim->ioprofile, 0, sizeof(itnim->ioprofile)); 1495 1493 for (j = 0; j < BFA_IOBUCKET_MAX; j++)
+6 -2
drivers/scsi/bfa/bfa_fcs.c
··· 76 76 fcs->bfa = bfa; 77 77 fcs->bfad = bfad; 78 78 fcs->min_cfg = min_cfg; 79 + fcs->num_rport_logins = 0; 79 80 80 81 bfa->fcs = BFA_TRUE; 81 82 fcbuild_init(); ··· 1385 1384 return; 1386 1385 } 1387 1386 } 1388 - bfa_trc(fabric->fcs, els_cmd->els_code); 1389 - bfa_fcs_lport_uf_recv(&fabric->bport, fchs, len); 1387 + 1388 + if (!bfa_fcs_fabric_is_switched(fabric)) 1389 + bfa_fcs_lport_uf_recv(&fabric->bport, fchs, len); 1390 + 1391 + bfa_trc(fabric->fcs, fchs->type); 1390 1392 } 1391 1393 1392 1394 /*
+24 -4
drivers/scsi/bfa/bfa_fcs.h
··· 64 64 #define BFA_FCS_RETRY_TIMEOUT 2000 65 65 #define BFA_FCS_MAX_NS_RETRIES 5 66 66 #define BFA_FCS_PID_IS_WKA(pid) ((bfa_ntoh3b(pid) > 0xFFF000) ? 1 : 0) 67 - 68 - 67 + #define BFA_FCS_MAX_RPORT_LOGINS 1024 69 68 70 69 struct bfa_fcs_lport_ns_s { 71 70 bfa_sm_t sm; /* state machine */ ··· 471 472 struct bfa_fcs_rport_s *bfa_fcs_rport_lookup_by_nwwn( 472 473 struct bfa_fcs_lport_s *port, wwn_t rnwwn); 473 474 void bfa_fcs_rport_set_del_timeout(u8 rport_tmo); 474 - 475 + void bfa_fcs_rport_set_max_logins(u32 max_logins); 475 476 void bfa_fcs_rport_uf_recv(struct bfa_fcs_rport_s *rport, 476 477 struct fchs_s *fchs, u16 len); 477 478 void bfa_fcs_rport_scn(struct bfa_fcs_rport_s *rport); ··· 605 606 struct bfa_fcs_itnim_s *bfa_fcs_itnim_create(struct bfa_fcs_rport_s *rport); 606 607 void bfa_fcs_itnim_delete(struct bfa_fcs_itnim_s *itnim); 607 608 void bfa_fcs_itnim_rport_offline(struct bfa_fcs_itnim_s *itnim); 608 - void bfa_fcs_itnim_rport_online(struct bfa_fcs_itnim_s *itnim); 609 + void bfa_fcs_itnim_brp_online(struct bfa_fcs_itnim_s *itnim); 609 610 bfa_status_t bfa_fcs_itnim_get_online_state(struct bfa_fcs_itnim_s *itnim); 610 611 void bfa_fcs_itnim_is_initiator(struct bfa_fcs_itnim_s *itnim); 611 612 void bfa_fcs_fcpim_uf_recv(struct bfa_fcs_itnim_s *itnim, ··· 689 690 struct bfa_fcs_stats_s stats; /* FCS statistics */ 690 691 struct bfa_wc_s wc; /* waiting counter */ 691 692 int fcs_aen_seq; 693 + u32 num_rport_logins; 692 694 }; 693 695 694 696 /* ··· 744 744 RPSM_EVENT_ADDRESS_DISC = 16, /* Need to Discover rport's PID */ 745 745 RPSM_EVENT_PRLO_RCVD = 17, /* PRLO from remote device */ 746 746 RPSM_EVENT_PLOGI_RETRY = 18, /* Retry PLOGI continuously */ 747 + RPSM_EVENT_FC4_FCS_ONLINE = 19, /*!< FC-4 FCS online complete */ 748 + }; 749 + 750 + /* 751 + * fcs_itnim_sm FCS itnim state machine events 752 + */ 753 + enum bfa_fcs_itnim_event { 754 + BFA_FCS_ITNIM_SM_FCS_ONLINE = 1, /* rport online event */ 755 + BFA_FCS_ITNIM_SM_OFFLINE = 2, /* rport offline */ 756 + BFA_FCS_ITNIM_SM_FRMSENT = 3, /* prli frame is sent */ 757 + BFA_FCS_ITNIM_SM_RSP_OK = 4, /* good response */ 758 + BFA_FCS_ITNIM_SM_RSP_ERROR = 5, /* error response */ 759 + BFA_FCS_ITNIM_SM_TIMEOUT = 6, /* delay timeout */ 760 + BFA_FCS_ITNIM_SM_HCB_OFFLINE = 7, /* BFA online callback */ 761 + BFA_FCS_ITNIM_SM_HCB_ONLINE = 8, /* BFA offline callback */ 762 + BFA_FCS_ITNIM_SM_INITIATOR = 9, /* rport is initiator */ 763 + BFA_FCS_ITNIM_SM_DELETE = 10, /* delete event from rport */ 764 + BFA_FCS_ITNIM_SM_PRLO = 11, /* delete event from rport */ 765 + BFA_FCS_ITNIM_SM_RSP_NOT_SUPP = 12, /* cmd not supported rsp */ 766 + BFA_FCS_ITNIM_SM_HAL_ONLINE = 13, /*!< bfa rport online event */ 747 767 }; 748 768 749 769 /*
+68 -56
drivers/scsi/bfa/bfa_fcs_fcpim.c
··· 40 40 static void bfa_fcs_itnim_aen_post(struct bfa_fcs_itnim_s *itnim, 41 41 enum bfa_itnim_aen_event event); 42 42 43 - /* 44 - * fcs_itnim_sm FCS itnim state machine events 45 - */ 46 - 47 - enum bfa_fcs_itnim_event { 48 - BFA_FCS_ITNIM_SM_ONLINE = 1, /* rport online event */ 49 - BFA_FCS_ITNIM_SM_OFFLINE = 2, /* rport offline */ 50 - BFA_FCS_ITNIM_SM_FRMSENT = 3, /* prli frame is sent */ 51 - BFA_FCS_ITNIM_SM_RSP_OK = 4, /* good response */ 52 - BFA_FCS_ITNIM_SM_RSP_ERROR = 5, /* error response */ 53 - BFA_FCS_ITNIM_SM_TIMEOUT = 6, /* delay timeout */ 54 - BFA_FCS_ITNIM_SM_HCB_OFFLINE = 7, /* BFA online callback */ 55 - BFA_FCS_ITNIM_SM_HCB_ONLINE = 8, /* BFA offline callback */ 56 - BFA_FCS_ITNIM_SM_INITIATOR = 9, /* rport is initiator */ 57 - BFA_FCS_ITNIM_SM_DELETE = 10, /* delete event from rport */ 58 - BFA_FCS_ITNIM_SM_PRLO = 11, /* delete event from rport */ 59 - BFA_FCS_ITNIM_SM_RSP_NOT_SUPP = 12, /* cmd not supported rsp */ 60 - }; 61 - 62 43 static void bfa_fcs_itnim_sm_offline(struct bfa_fcs_itnim_s *itnim, 63 44 enum bfa_fcs_itnim_event event); 64 45 static void bfa_fcs_itnim_sm_prli_send(struct bfa_fcs_itnim_s *itnim, ··· 50 69 enum bfa_fcs_itnim_event event); 51 70 static void bfa_fcs_itnim_sm_hcb_online(struct bfa_fcs_itnim_s *itnim, 52 71 enum bfa_fcs_itnim_event event); 72 + static void bfa_fcs_itnim_sm_hal_rport_online(struct bfa_fcs_itnim_s *itnim, 73 + enum bfa_fcs_itnim_event event); 53 74 static void bfa_fcs_itnim_sm_online(struct bfa_fcs_itnim_s *itnim, 54 75 enum bfa_fcs_itnim_event event); 55 76 static void bfa_fcs_itnim_sm_hcb_offline(struct bfa_fcs_itnim_s *itnim, ··· 82 99 bfa_trc(itnim->fcs, event); 83 100 84 101 switch (event) { 85 - case BFA_FCS_ITNIM_SM_ONLINE: 102 + case BFA_FCS_ITNIM_SM_FCS_ONLINE: 86 103 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_prli_send); 87 104 itnim->prli_retries = 0; 88 105 bfa_fcs_itnim_send_prli(itnim, NULL); ··· 121 138 case BFA_FCS_ITNIM_SM_INITIATOR: 122 139 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_initiator); 123 140 bfa_fcxp_walloc_cancel(itnim->fcs->bfa, &itnim->fcxp_wqe); 141 + bfa_sm_send_event(itnim->rport, RPSM_EVENT_FC4_FCS_ONLINE); 124 142 break; 125 143 126 144 case BFA_FCS_ITNIM_SM_OFFLINE: ··· 150 166 151 167 switch (event) { 152 168 case BFA_FCS_ITNIM_SM_RSP_OK: 153 - if (itnim->rport->scsi_function == BFA_RPORT_INITIATOR) { 169 + if (itnim->rport->scsi_function == BFA_RPORT_INITIATOR) 154 170 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_initiator); 155 - } else { 156 - bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_hcb_online); 157 - bfa_itnim_online(itnim->bfa_itnim, itnim->seq_rec); 158 - } 171 + else 172 + bfa_sm_set_state(itnim, 173 + bfa_fcs_itnim_sm_hal_rport_online); 174 + 175 + bfa_sm_send_event(itnim->rport, RPSM_EVENT_FC4_FCS_ONLINE); 159 176 break; 160 177 161 178 case BFA_FCS_ITNIM_SM_RSP_ERROR: ··· 179 194 case BFA_FCS_ITNIM_SM_INITIATOR: 180 195 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_initiator); 181 196 bfa_fcxp_discard(itnim->fcxp); 197 + bfa_sm_send_event(itnim->rport, RPSM_EVENT_FC4_FCS_ONLINE); 182 198 break; 183 199 184 200 case BFA_FCS_ITNIM_SM_DELETE: 185 201 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline); 186 202 bfa_fcxp_discard(itnim->fcxp); 203 + bfa_fcs_itnim_free(itnim); 204 + break; 205 + 206 + default: 207 + bfa_sm_fault(itnim->fcs, event); 208 + } 209 + } 210 + 211 + static void 212 + bfa_fcs_itnim_sm_hal_rport_online(struct bfa_fcs_itnim_s *itnim, 213 + enum bfa_fcs_itnim_event event) 214 + { 215 + bfa_trc(itnim->fcs, itnim->rport->pwwn); 216 + bfa_trc(itnim->fcs, event); 217 + 218 + switch (event) { 219 + case BFA_FCS_ITNIM_SM_HAL_ONLINE: 220 + if (!itnim->bfa_itnim) 221 + itnim->bfa_itnim = bfa_itnim_create(itnim->fcs->bfa, 222 + itnim->rport->bfa_rport, itnim); 223 + 224 + if (itnim->bfa_itnim) { 225 + bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_hcb_online); 226 + bfa_itnim_online(itnim->bfa_itnim, itnim->seq_rec); 227 + } else { 228 + bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline); 229 + bfa_sm_send_event(itnim->rport, RPSM_EVENT_DELETE); 230 + } 231 + 232 + break; 233 + 234 + case BFA_FCS_ITNIM_SM_OFFLINE: 235 + bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline); 236 + bfa_sm_send_event(itnim->rport, RPSM_EVENT_FC4_OFFLINE); 237 + break; 238 + 239 + case BFA_FCS_ITNIM_SM_DELETE: 240 + bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline); 187 241 bfa_fcs_itnim_free(itnim); 188 242 break; 189 243 ··· 262 238 case BFA_FCS_ITNIM_SM_INITIATOR: 263 239 bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_initiator); 264 240 bfa_timer_stop(&itnim->timer); 241 + bfa_sm_send_event(itnim->rport, RPSM_EVENT_FC4_FCS_ONLINE); 265 242 break; 266 243 267 244 case BFA_FCS_ITNIM_SM_DELETE: ··· 300 275 break; 301 276 302 277 case BFA_FCS_ITNIM_SM_OFFLINE: 303 - bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_offline); 278 + bfa_sm_set_state(itnim, bfa_fcs_itnim_sm_hcb_offline); 304 279 bfa_itnim_offline(itnim->bfa_itnim); 305 - bfa_sm_send_event(itnim->rport, RPSM_EVENT_FC4_OFFLINE); 306 280 break; 307 281 308 282 case BFA_FCS_ITNIM_SM_DELETE: ··· 396 372 bfa_sm_send_event(itnim->rport, RPSM_EVENT_FC4_OFFLINE); 397 373 break; 398 374 375 + /* 376 + * fcs_online is expected here for well known initiator ports 377 + */ 378 + case BFA_FCS_ITNIM_SM_FCS_ONLINE: 379 + bfa_sm_send_event(itnim->rport, RPSM_EVENT_FC4_FCS_ONLINE); 380 + break; 381 + 399 382 case BFA_FCS_ITNIM_SM_RSP_ERROR: 400 - case BFA_FCS_ITNIM_SM_ONLINE: 401 383 case BFA_FCS_ITNIM_SM_INITIATOR: 402 384 break; 403 385 ··· 514 484 if (prli_resp->parampage.servparams.initiator) { 515 485 bfa_trc(itnim->fcs, prli_resp->parampage.type); 516 486 itnim->rport->scsi_function = 517 - BFA_RPORT_INITIATOR; 487 + BFA_RPORT_INITIATOR; 518 488 itnim->stats.prli_rsp_acc++; 519 489 itnim->stats.initiator++; 520 490 bfa_sm_send_event(itnim, ··· 562 532 static void 563 533 bfa_fcs_itnim_free(struct bfa_fcs_itnim_s *itnim) 564 534 { 565 - bfa_itnim_delete(itnim->bfa_itnim); 535 + if (itnim->bfa_itnim) { 536 + bfa_itnim_delete(itnim->bfa_itnim); 537 + itnim->bfa_itnim = NULL; 538 + } 539 + 566 540 bfa_fcb_itnim_free(itnim->fcs->bfad, itnim->itnim_drv); 567 541 } 568 542 ··· 587 553 struct bfa_fcs_lport_s *port = rport->port; 588 554 struct bfa_fcs_itnim_s *itnim; 589 555 struct bfad_itnim_s *itnim_drv; 590 - struct bfa_itnim_s *bfa_itnim; 591 556 592 557 /* 593 558 * call bfad to allocate the itnim ··· 604 571 itnim->fcs = rport->fcs; 605 572 itnim->itnim_drv = itnim_drv; 606 573 607 - /* 608 - * call BFA to create the itnim 609 - */ 610 - bfa_itnim = 611 - bfa_itnim_create(port->fcs->bfa, rport->bfa_rport, itnim); 612 - 613 - if (bfa_itnim == NULL) { 614 - bfa_trc(port->fcs, rport->pwwn); 615 - bfa_fcb_itnim_free(port->fcs->bfad, itnim_drv); 616 - WARN_ON(1); 617 - return NULL; 618 - } 619 - 620 - itnim->bfa_itnim = bfa_itnim; 574 + itnim->bfa_itnim = NULL; 621 575 itnim->seq_rec = BFA_FALSE; 622 576 itnim->rec_support = BFA_FALSE; 623 577 itnim->conf_comp = BFA_FALSE; ··· 634 614 * Notification from rport that PLOGI is complete to initiate FC-4 session. 635 615 */ 636 616 void 637 - bfa_fcs_itnim_rport_online(struct bfa_fcs_itnim_s *itnim) 617 + bfa_fcs_itnim_brp_online(struct bfa_fcs_itnim_s *itnim) 638 618 { 639 619 itnim->stats.onlines++; 640 620 641 - if (!BFA_FCS_PID_IS_WKA(itnim->rport->pid)) { 642 - bfa_sm_send_event(itnim, BFA_FCS_ITNIM_SM_ONLINE); 643 - } else { 644 - /* 645 - * For well known addresses, we set the itnim to initiator 646 - * state 647 - */ 648 - itnim->stats.initiator++; 649 - bfa_sm_send_event(itnim, BFA_FCS_ITNIM_SM_INITIATOR); 650 - } 621 + if (!BFA_FCS_PID_IS_WKA(itnim->rport->pid)) 622 + bfa_sm_send_event(itnim, BFA_FCS_ITNIM_SM_HAL_ONLINE); 651 623 } 652 624 653 625 /*
+45 -1
drivers/scsi/bfa/bfa_fcs_lport.c
··· 4691 4691 struct fcgs_gidft_resp_s *gidft_entry; 4692 4692 struct bfa_fcs_rport_s *rport; 4693 4693 u32 ii; 4694 + struct bfa_fcs_fabric_s *fabric = port->fabric; 4695 + struct bfa_fcs_vport_s *vport; 4696 + struct list_head *qe; 4697 + u8 found = 0; 4694 4698 4695 4699 for (ii = 0; ii < n_pids; ii++) { 4696 4700 gidft_entry = (struct fcgs_gidft_resp_s *) &pid_buf[ii]; 4697 4701 4698 4702 if (gidft_entry->pid == port->pid) 4699 4703 continue; 4704 + 4705 + /* 4706 + * Ignore PID if it is of base port 4707 + * (Avoid vports discovering base port as remote port) 4708 + */ 4709 + if (gidft_entry->pid == fabric->bport.pid) 4710 + continue; 4711 + 4712 + /* 4713 + * Ignore PID if it is of vport created on the same base port 4714 + * (Avoid vport discovering every other vport created on the 4715 + * same port as remote port) 4716 + */ 4717 + list_for_each(qe, &fabric->vport_q) { 4718 + vport = (struct bfa_fcs_vport_s *) qe; 4719 + if (vport->lport.pid == gidft_entry->pid) 4720 + found = 1; 4721 + } 4722 + 4723 + if (found) { 4724 + found = 0; 4725 + continue; 4726 + } 4700 4727 4701 4728 /* 4702 4729 * Check if this rport already exists ··· 4792 4765 struct bfa_fcs_lport_ns_s *ns = BFA_FCS_GET_NS_FROM_PORT(port); 4793 4766 4794 4767 bfa_trc(port->fcs, port->pid); 4795 - bfa_sm_send_event(ns, NSSM_EVENT_NS_QUERY); 4768 + if (bfa_sm_cmp_state(ns, bfa_fcs_lport_ns_sm_online)) 4769 + bfa_sm_send_event(ns, NSSM_EVENT_NS_QUERY); 4796 4770 } 4797 4771 4798 4772 static void ··· 5211 5183 bfa_fcs_lport_scn_portid_rscn(struct bfa_fcs_lport_s *port, u32 rpid) 5212 5184 { 5213 5185 struct bfa_fcs_rport_s *rport; 5186 + struct bfa_fcs_fabric_s *fabric = port->fabric; 5187 + struct bfa_fcs_vport_s *vport; 5188 + struct list_head *qe; 5214 5189 5215 5190 bfa_trc(port->fcs, rpid); 5216 5191 5192 + /* 5193 + * Ignore PID if it is of base port or of vports created on the 5194 + * same base port. It is to avoid vports discovering base port or 5195 + * other vports created on same base port as remote port 5196 + */ 5197 + if (rpid == fabric->bport.pid) 5198 + return; 5199 + 5200 + list_for_each(qe, &fabric->vport_q) { 5201 + vport = (struct bfa_fcs_vport_s *) qe; 5202 + if (vport->lport.pid == rpid) 5203 + return; 5204 + } 5217 5205 /* 5218 5206 * If this is an unknown device, then it just came online. 5219 5207 * Otherwise let rport handle the RSCN event.
+317 -104
drivers/scsi/bfa/bfa_fcs_rport.c
··· 30 30 bfa_fcs_rport_del_timeout = BFA_FCS_RPORT_DEF_DEL_TIMEOUT * 1000; 31 31 /* In millisecs */ 32 32 /* 33 + * bfa_fcs_rport_max_logins is max count of bfa_fcs_rports 34 + * whereas DEF_CFG_NUM_RPORTS is max count of bfa_rports 35 + */ 36 + static u32 bfa_fcs_rport_max_logins = BFA_FCS_MAX_RPORT_LOGINS; 37 + 38 + /* 33 39 * forward declarations 34 40 */ 35 41 static struct bfa_fcs_rport_s *bfa_fcs_rport_alloc( 36 42 struct bfa_fcs_lport_s *port, wwn_t pwwn, u32 rpid); 37 43 static void bfa_fcs_rport_free(struct bfa_fcs_rport_s *rport); 38 44 static void bfa_fcs_rport_hal_online(struct bfa_fcs_rport_s *rport); 39 - static void bfa_fcs_rport_online_action(struct bfa_fcs_rport_s *rport); 40 - static void bfa_fcs_rport_offline_action(struct bfa_fcs_rport_s *rport); 45 + static void bfa_fcs_rport_fcs_online_action(struct bfa_fcs_rport_s *rport); 46 + static void bfa_fcs_rport_hal_online_action(struct bfa_fcs_rport_s *rport); 47 + static void bfa_fcs_rport_fcs_offline_action(struct bfa_fcs_rport_s *rport); 48 + static void bfa_fcs_rport_hal_offline_action(struct bfa_fcs_rport_s *rport); 41 49 static void bfa_fcs_rport_update(struct bfa_fcs_rport_s *rport, 42 50 struct fc_logi_s *plogi); 43 51 static void bfa_fcs_rport_timeout(void *arg); ··· 84 76 static void bfa_fcs_rport_process_adisc(struct bfa_fcs_rport_s *rport, 85 77 struct fchs_s *rx_fchs, u16 len); 86 78 static void bfa_fcs_rport_send_prlo_acc(struct bfa_fcs_rport_s *rport); 79 + static void bfa_fcs_rport_hal_offline(struct bfa_fcs_rport_s *rport); 87 80 88 81 static void bfa_fcs_rport_sm_uninit(struct bfa_fcs_rport_s *rport, 89 82 enum rport_event event); ··· 95 86 static void bfa_fcs_rport_sm_plogi_retry(struct bfa_fcs_rport_s *rport, 96 87 enum rport_event event); 97 88 static void bfa_fcs_rport_sm_plogi(struct bfa_fcs_rport_s *rport, 89 + enum rport_event event); 90 + static void bfa_fcs_rport_sm_fc4_fcs_online(struct bfa_fcs_rport_s *rport, 98 91 enum rport_event event); 99 92 static void bfa_fcs_rport_sm_hal_online(struct bfa_fcs_rport_s *rport, 100 93 enum rport_event event); ··· 134 123 enum rport_event event); 135 124 static void bfa_fcs_rport_sm_nsdisc_sent(struct bfa_fcs_rport_s *rport, 136 125 enum rport_event event); 126 + static void bfa_fcs_rport_sm_fc4_off_delete(struct bfa_fcs_rport_s *rport, 127 + enum rport_event event); 128 + static void bfa_fcs_rport_sm_delete_pending(struct bfa_fcs_rport_s *rport, 129 + enum rport_event event); 137 130 138 131 static struct bfa_sm_table_s rport_sm_table[] = { 139 132 {BFA_SM(bfa_fcs_rport_sm_uninit), BFA_RPORT_UNINIT}, ··· 145 130 {BFA_SM(bfa_fcs_rport_sm_plogiacc_sending), BFA_RPORT_ONLINE}, 146 131 {BFA_SM(bfa_fcs_rport_sm_plogi_retry), BFA_RPORT_PLOGI_RETRY}, 147 132 {BFA_SM(bfa_fcs_rport_sm_plogi), BFA_RPORT_PLOGI}, 133 + {BFA_SM(bfa_fcs_rport_sm_fc4_fcs_online), BFA_RPORT_ONLINE}, 148 134 {BFA_SM(bfa_fcs_rport_sm_hal_online), BFA_RPORT_ONLINE}, 149 135 {BFA_SM(bfa_fcs_rport_sm_online), BFA_RPORT_ONLINE}, 150 136 {BFA_SM(bfa_fcs_rport_sm_nsquery_sending), BFA_RPORT_NSQUERY}, ··· 183 167 break; 184 168 185 169 case RPSM_EVENT_PLOGI_RCVD: 186 - bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending); 187 - bfa_fcs_rport_send_plogiacc(rport, NULL); 170 + bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_fcs_online); 171 + bfa_fcs_rport_fcs_online_action(rport); 188 172 break; 189 173 190 174 case RPSM_EVENT_PLOGI_COMP: ··· 268 252 269 253 switch (event) { 270 254 case RPSM_EVENT_FCXP_SENT: 271 - bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online); 272 - bfa_fcs_rport_hal_online(rport); 255 + bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_fcs_online); 256 + bfa_fcs_rport_fcs_online_action(rport); 273 257 break; 274 258 275 259 case RPSM_EVENT_DELETE: ··· 364 348 break; 365 349 366 350 case RPSM_EVENT_PLOGI_COMP: 367 - bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online); 351 + bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_fcs_online); 368 352 bfa_timer_stop(&rport->timer); 369 - bfa_fcs_rport_hal_online(rport); 353 + bfa_fcs_rport_fcs_online_action(rport); 370 354 break; 371 355 372 356 default: ··· 386 370 387 371 switch (event) { 388 372 case RPSM_EVENT_ACCEPTED: 389 - bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online); 373 + bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_fcs_online); 390 374 rport->plogi_retries = 0; 391 - bfa_fcs_rport_hal_online(rport); 375 + bfa_fcs_rport_fcs_online_action(rport); 392 376 break; 393 377 394 378 case RPSM_EVENT_LOGO_RCVD: ··· 460 444 break; 461 445 462 446 case RPSM_EVENT_PLOGI_COMP: 463 - bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online); 447 + bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_fcs_online); 464 448 bfa_fcxp_discard(rport->fcxp); 465 - bfa_fcs_rport_hal_online(rport); 449 + bfa_fcs_rport_fcs_online_action(rport); 466 450 break; 467 451 468 452 default: 469 453 bfa_sm_fault(rport->fcs, event); 454 + } 455 + } 456 + 457 + /* 458 + * PLOGI is done. Await bfa_fcs_itnim to ascertain the scsi function 459 + */ 460 + static void 461 + bfa_fcs_rport_sm_fc4_fcs_online(struct bfa_fcs_rport_s *rport, 462 + enum rport_event event) 463 + { 464 + bfa_trc(rport->fcs, rport->pwwn); 465 + bfa_trc(rport->fcs, rport->pid); 466 + bfa_trc(rport->fcs, event); 467 + 468 + switch (event) { 469 + case RPSM_EVENT_FC4_FCS_ONLINE: 470 + if (rport->scsi_function == BFA_RPORT_INITIATOR) { 471 + if (!BFA_FCS_PID_IS_WKA(rport->pid)) 472 + bfa_fcs_rpf_rport_online(rport); 473 + bfa_sm_set_state(rport, bfa_fcs_rport_sm_online); 474 + break; 475 + } 476 + 477 + if (!rport->bfa_rport) 478 + rport->bfa_rport = 479 + bfa_rport_create(rport->fcs->bfa, rport); 480 + 481 + if (rport->bfa_rport) { 482 + bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online); 483 + bfa_fcs_rport_hal_online(rport); 484 + } else { 485 + bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend); 486 + bfa_fcs_rport_fcs_offline_action(rport); 487 + } 488 + break; 489 + 490 + case RPSM_EVENT_PLOGI_RCVD: 491 + bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline); 492 + rport->plogi_pending = BFA_TRUE; 493 + bfa_fcs_rport_fcs_offline_action(rport); 494 + break; 495 + 496 + case RPSM_EVENT_PLOGI_COMP: 497 + case RPSM_EVENT_LOGO_IMP: 498 + case RPSM_EVENT_ADDRESS_CHANGE: 499 + case RPSM_EVENT_SCN: 500 + bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline); 501 + bfa_fcs_rport_fcs_offline_action(rport); 502 + break; 503 + 504 + case RPSM_EVENT_LOGO_RCVD: 505 + case RPSM_EVENT_PRLO_RCVD: 506 + bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv); 507 + bfa_fcs_rport_fcs_offline_action(rport); 508 + break; 509 + 510 + case RPSM_EVENT_DELETE: 511 + bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend); 512 + bfa_fcs_rport_fcs_offline_action(rport); 513 + break; 514 + 515 + default: 516 + bfa_sm_fault(rport->fcs, event); 517 + break; 470 518 } 471 519 } 472 520 ··· 549 469 switch (event) { 550 470 case RPSM_EVENT_HCB_ONLINE: 551 471 bfa_sm_set_state(rport, bfa_fcs_rport_sm_online); 552 - bfa_fcs_rport_online_action(rport); 472 + bfa_fcs_rport_hal_online_action(rport); 553 473 break; 554 474 555 - case RPSM_EVENT_PRLO_RCVD: 556 475 case RPSM_EVENT_PLOGI_COMP: 557 476 break; 558 477 478 + case RPSM_EVENT_PRLO_RCVD: 559 479 case RPSM_EVENT_LOGO_RCVD: 560 - bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_logorcv); 561 - bfa_sm_send_event(rport->bfa_rport, BFA_RPORT_SM_OFFLINE); 480 + bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv); 481 + bfa_fcs_rport_fcs_offline_action(rport); 562 482 break; 563 483 484 + case RPSM_EVENT_SCN: 564 485 case RPSM_EVENT_LOGO_IMP: 565 486 case RPSM_EVENT_ADDRESS_CHANGE: 566 - bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_offline); 567 - bfa_sm_send_event(rport->bfa_rport, BFA_RPORT_SM_OFFLINE); 487 + bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline); 488 + bfa_fcs_rport_fcs_offline_action(rport); 568 489 break; 569 490 570 491 case RPSM_EVENT_PLOGI_RCVD: 571 492 rport->plogi_pending = BFA_TRUE; 572 - bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_offline); 573 - bfa_sm_send_event(rport->bfa_rport, BFA_RPORT_SM_OFFLINE); 493 + bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline); 494 + bfa_fcs_rport_fcs_offline_action(rport); 574 495 break; 575 496 576 497 case RPSM_EVENT_DELETE: 577 - bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_logosend); 578 - bfa_sm_send_event(rport->bfa_rport, BFA_RPORT_SM_OFFLINE); 579 - break; 580 - 581 - case RPSM_EVENT_SCN: 582 - /* 583 - * @todo 584 - * Ignore SCN - PLOGI just completed, FC-4 login should detect 585 - * device failures. 586 - */ 498 + bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend); 499 + bfa_fcs_rport_fcs_offline_action(rport); 587 500 break; 588 501 589 502 default: ··· 611 538 case RPSM_EVENT_LOGO_IMP: 612 539 case RPSM_EVENT_ADDRESS_CHANGE: 613 540 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline); 614 - bfa_fcs_rport_offline_action(rport); 541 + bfa_fcs_rport_hal_offline_action(rport); 615 542 break; 616 543 617 544 case RPSM_EVENT_DELETE: 618 545 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend); 619 - bfa_fcs_rport_offline_action(rport); 546 + bfa_fcs_rport_hal_offline_action(rport); 620 547 break; 621 548 622 549 case RPSM_EVENT_LOGO_RCVD: 623 550 case RPSM_EVENT_PRLO_RCVD: 624 551 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv); 625 - bfa_fcs_rport_offline_action(rport); 552 + bfa_fcs_rport_hal_offline_action(rport); 626 553 break; 627 554 628 555 case RPSM_EVENT_PLOGI_COMP: ··· 653 580 case RPSM_EVENT_DELETE: 654 581 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend); 655 582 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe); 656 - bfa_fcs_rport_offline_action(rport); 583 + bfa_fcs_rport_hal_offline_action(rport); 657 584 break; 658 585 659 586 case RPSM_EVENT_SCN: ··· 666 593 case RPSM_EVENT_PRLO_RCVD: 667 594 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv); 668 595 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe); 669 - bfa_fcs_rport_offline_action(rport); 596 + bfa_fcs_rport_hal_offline_action(rport); 670 597 break; 671 598 672 599 case RPSM_EVENT_LOGO_IMP: 673 - rport->pid = 0; 674 - bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline); 675 - bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe); 676 - bfa_timer_start(rport->fcs->bfa, &rport->timer, 677 - bfa_fcs_rport_timeout, rport, 678 - bfa_fcs_rport_del_timeout); 679 - break; 680 - 681 600 case RPSM_EVENT_PLOGI_RCVD: 682 601 case RPSM_EVENT_ADDRESS_CHANGE: 683 602 case RPSM_EVENT_PLOGI_COMP: 684 603 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline); 685 604 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe); 686 - bfa_fcs_rport_offline_action(rport); 605 + bfa_fcs_rport_hal_offline_action(rport); 687 606 break; 688 607 689 608 default: ··· 708 643 bfa_fcs_rport_send_nsdisc(rport, NULL); 709 644 } else { 710 645 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline); 711 - bfa_fcs_rport_offline_action(rport); 646 + bfa_fcs_rport_hal_offline_action(rport); 712 647 } 713 648 break; 714 649 715 650 case RPSM_EVENT_DELETE: 716 651 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend); 717 652 bfa_fcxp_discard(rport->fcxp); 718 - bfa_fcs_rport_offline_action(rport); 653 + bfa_fcs_rport_hal_offline_action(rport); 719 654 break; 720 655 721 656 case RPSM_EVENT_SCN: ··· 725 660 case RPSM_EVENT_PRLO_RCVD: 726 661 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv); 727 662 bfa_fcxp_discard(rport->fcxp); 728 - bfa_fcs_rport_offline_action(rport); 663 + bfa_fcs_rport_hal_offline_action(rport); 729 664 break; 730 665 731 666 case RPSM_EVENT_PLOGI_COMP: ··· 734 669 case RPSM_EVENT_LOGO_IMP: 735 670 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline); 736 671 bfa_fcxp_discard(rport->fcxp); 737 - bfa_fcs_rport_offline_action(rport); 672 + bfa_fcs_rport_hal_offline_action(rport); 738 673 break; 739 674 740 675 default: ··· 762 697 case RPSM_EVENT_DELETE: 763 698 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend); 764 699 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe); 765 - bfa_fcs_rport_offline_action(rport); 700 + bfa_fcs_rport_hal_offline_action(rport); 766 701 break; 767 702 768 703 case RPSM_EVENT_LOGO_IMP: 769 704 case RPSM_EVENT_ADDRESS_CHANGE: 770 705 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline); 771 706 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe); 772 - bfa_fcs_rport_offline_action(rport); 707 + bfa_fcs_rport_hal_offline_action(rport); 773 708 break; 774 709 775 710 case RPSM_EVENT_LOGO_RCVD: 776 711 case RPSM_EVENT_PRLO_RCVD: 777 712 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv); 778 713 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe); 779 - bfa_fcs_rport_offline_action(rport); 714 + bfa_fcs_rport_hal_offline_action(rport); 780 715 break; 781 716 782 717 case RPSM_EVENT_SCN: ··· 785 720 case RPSM_EVENT_PLOGI_RCVD: 786 721 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline); 787 722 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe); 788 - bfa_fcs_rport_offline_action(rport); 723 + bfa_fcs_rport_hal_offline_action(rport); 789 724 break; 790 725 791 726 default: ··· 822 757 case RPSM_EVENT_FAILED: 823 758 case RPSM_EVENT_ADDRESS_CHANGE: 824 759 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline); 825 - bfa_fcs_rport_offline_action(rport); 760 + bfa_fcs_rport_hal_offline_action(rport); 826 761 break; 827 762 828 763 case RPSM_EVENT_DELETE: 829 764 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend); 830 765 bfa_fcxp_discard(rport->fcxp); 831 - bfa_fcs_rport_offline_action(rport); 766 + bfa_fcs_rport_hal_offline_action(rport); 832 767 break; 833 768 834 769 case RPSM_EVENT_SCN: ··· 840 775 case RPSM_EVENT_LOGO_IMP: 841 776 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline); 842 777 bfa_fcxp_discard(rport->fcxp); 843 - bfa_fcs_rport_offline_action(rport); 778 + bfa_fcs_rport_hal_offline_action(rport); 844 779 break; 845 780 846 781 case RPSM_EVENT_LOGO_RCVD: 847 782 case RPSM_EVENT_PRLO_RCVD: 848 783 bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv); 849 784 bfa_fcxp_discard(rport->fcxp); 850 - bfa_fcs_rport_offline_action(rport); 785 + bfa_fcs_rport_hal_offline_action(rport); 851 786 break; 852 787 853 788 default: ··· 869 804 switch (event) { 870 805 case RPSM_EVENT_FC4_OFFLINE: 871 806 bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_logorcv); 872 - bfa_sm_send_event(rport->bfa_rport, BFA_RPORT_SM_OFFLINE); 807 + bfa_fcs_rport_hal_offline(rport); 873 808 break; 874 809 875 810 case RPSM_EVENT_DELETE: 876 - bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend); 811 + if (rport->pid && (rport->prlo == BFA_TRUE)) 812 + bfa_fcs_rport_send_prlo_acc(rport); 813 + if (rport->pid && (rport->prlo == BFA_FALSE)) 814 + bfa_fcs_rport_send_logo_acc(rport); 815 + 816 + bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_off_delete); 877 817 break; 878 818 819 + case RPSM_EVENT_HCB_ONLINE: 879 820 case RPSM_EVENT_LOGO_RCVD: 880 821 case RPSM_EVENT_PRLO_RCVD: 881 822 case RPSM_EVENT_ADDRESS_CHANGE: ··· 907 836 switch (event) { 908 837 case RPSM_EVENT_FC4_OFFLINE: 909 838 bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_logosend); 910 - bfa_sm_send_event(rport->bfa_rport, BFA_RPORT_SM_OFFLINE); 839 + bfa_fcs_rport_hal_offline(rport); 840 + break; 841 + 842 + case RPSM_EVENT_LOGO_RCVD: 843 + bfa_fcs_rport_send_logo_acc(rport); 844 + case RPSM_EVENT_PRLO_RCVD: 845 + if (rport->prlo == BFA_TRUE) 846 + bfa_fcs_rport_send_prlo_acc(rport); 847 + bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_off_delete); 848 + break; 849 + 850 + case RPSM_EVENT_HCB_ONLINE: 851 + case RPSM_EVENT_DELETE: 852 + /* Rport is being deleted */ 911 853 break; 912 854 913 855 default: ··· 942 858 switch (event) { 943 859 case RPSM_EVENT_FC4_OFFLINE: 944 860 bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_offline); 945 - bfa_sm_send_event(rport->bfa_rport, BFA_RPORT_SM_OFFLINE); 861 + bfa_fcs_rport_hal_offline(rport); 946 862 break; 947 863 864 + case RPSM_EVENT_LOGO_RCVD: 865 + /* 866 + * Rport is going offline. Just ack the logo 867 + */ 868 + bfa_fcs_rport_send_logo_acc(rport); 869 + break; 870 + 871 + case RPSM_EVENT_PRLO_RCVD: 872 + bfa_fcs_rport_send_prlo_acc(rport); 873 + break; 874 + 875 + case RPSM_EVENT_HCB_ONLINE: 948 876 case RPSM_EVENT_SCN: 949 877 case RPSM_EVENT_LOGO_IMP: 950 - case RPSM_EVENT_LOGO_RCVD: 951 - case RPSM_EVENT_PRLO_RCVD: 952 878 case RPSM_EVENT_ADDRESS_CHANGE: 953 879 /* 954 880 * rport is already going offline. ··· 1002 908 */ 1003 909 1004 910 case RPSM_EVENT_ADDRESS_CHANGE: 1005 - if (bfa_fcs_lport_is_online(rport->port)) { 1006 - if (bfa_fcs_fabric_is_switched(rport->port->fabric)) { 1007 - bfa_sm_set_state(rport, 1008 - bfa_fcs_rport_sm_nsdisc_sending); 1009 - rport->ns_retries = 0; 1010 - bfa_fcs_rport_send_nsdisc(rport, NULL); 1011 - } else { 1012 - bfa_sm_set_state(rport, 1013 - bfa_fcs_rport_sm_plogi_sending); 1014 - rport->plogi_retries = 0; 1015 - bfa_fcs_rport_send_plogi(rport, NULL); 1016 - } 1017 - } else { 911 + if (!bfa_fcs_lport_is_online(rport->port)) { 1018 912 rport->pid = 0; 1019 913 bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline); 1020 914 bfa_timer_start(rport->fcs->bfa, &rport->timer, 1021 915 bfa_fcs_rport_timeout, rport, 1022 916 bfa_fcs_rport_del_timeout); 917 + break; 918 + } 919 + if (bfa_fcs_fabric_is_switched(rport->port->fabric)) { 920 + bfa_sm_set_state(rport, 921 + bfa_fcs_rport_sm_nsdisc_sending); 922 + rport->ns_retries = 0; 923 + bfa_fcs_rport_send_nsdisc(rport, NULL); 924 + } else { 925 + bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_sending); 926 + rport->plogi_retries = 0; 927 + bfa_fcs_rport_send_plogi(rport, NULL); 1023 928 } 1024 929 break; 1025 930 ··· 1095 1002 break; 1096 1003 1097 1004 case RPSM_EVENT_DELETE: 1098 - bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_logosend); 1005 + bfa_sm_set_state(rport, bfa_fcs_rport_sm_delete_pending); 1006 + if (rport->pid && (rport->prlo == BFA_TRUE)) 1007 + bfa_fcs_rport_send_prlo_acc(rport); 1008 + if (rport->pid && (rport->prlo == BFA_FALSE)) 1009 + bfa_fcs_rport_send_logo_acc(rport); 1099 1010 break; 1100 1011 1101 1012 case RPSM_EVENT_LOGO_IMP: ··· 1138 1041 break; 1139 1042 1140 1043 case RPSM_EVENT_LOGO_RCVD: 1044 + bfa_fcs_rport_send_logo_acc(rport); 1141 1045 case RPSM_EVENT_PRLO_RCVD: 1046 + if (rport->prlo == BFA_TRUE) 1047 + bfa_fcs_rport_send_prlo_acc(rport); 1048 + 1049 + bfa_sm_set_state(rport, bfa_fcs_rport_sm_delete_pending); 1050 + break; 1051 + 1142 1052 case RPSM_EVENT_ADDRESS_CHANGE: 1143 1053 break; 1144 1054 ··· 1177 1073 break; 1178 1074 1179 1075 case RPSM_EVENT_LOGO_RCVD: 1076 + bfa_fcs_rport_send_logo_acc(rport); 1180 1077 case RPSM_EVENT_PRLO_RCVD: 1078 + if (rport->prlo == BFA_TRUE) 1079 + bfa_fcs_rport_send_prlo_acc(rport); 1080 + 1181 1081 bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit); 1182 1082 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe); 1183 1083 bfa_fcs_rport_free(rport); ··· 1235 1127 break; 1236 1128 1237 1129 case RPSM_EVENT_PLOGI_COMP: 1238 - bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online); 1130 + bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_fcs_online); 1239 1131 bfa_timer_stop(&rport->timer); 1240 - bfa_fcs_rport_hal_online(rport); 1132 + bfa_fcs_rport_fcs_online_action(rport); 1241 1133 break; 1242 1134 1243 1135 case RPSM_EVENT_PLOGI_SEND: ··· 1299 1191 break; 1300 1192 1301 1193 case RPSM_EVENT_PLOGI_COMP: 1302 - bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online); 1194 + bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_fcs_online); 1303 1195 bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe); 1304 - bfa_fcs_rport_hal_online(rport); 1196 + bfa_fcs_rport_fcs_online_action(rport); 1305 1197 break; 1306 1198 1307 1199 default: ··· 1363 1255 break; 1364 1256 1365 1257 case RPSM_EVENT_PLOGI_COMP: 1366 - bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online); 1258 + bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_fcs_online); 1367 1259 bfa_timer_stop(&rport->timer); 1368 - bfa_fcs_rport_hal_online(rport); 1260 + bfa_fcs_rport_fcs_online_action(rport); 1369 1261 break; 1370 1262 1371 1263 default: ··· 1453 1345 break; 1454 1346 1455 1347 case RPSM_EVENT_PLOGI_COMP: 1456 - bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online); 1348 + bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_fcs_online); 1457 1349 bfa_fcxp_discard(rport->fcxp); 1458 - bfa_fcs_rport_hal_online(rport); 1350 + bfa_fcs_rport_fcs_online_action(rport); 1459 1351 break; 1460 1352 1461 1353 default: ··· 1463 1355 } 1464 1356 } 1465 1357 1358 + /* 1359 + * Rport needs to be deleted 1360 + * waiting for ITNIM clean up to finish 1361 + */ 1362 + static void 1363 + bfa_fcs_rport_sm_fc4_off_delete(struct bfa_fcs_rport_s *rport, 1364 + enum rport_event event) 1365 + { 1366 + bfa_trc(rport->fcs, rport->pwwn); 1367 + bfa_trc(rport->fcs, rport->pid); 1368 + bfa_trc(rport->fcs, event); 1466 1369 1370 + switch (event) { 1371 + case RPSM_EVENT_FC4_OFFLINE: 1372 + bfa_sm_set_state(rport, bfa_fcs_rport_sm_delete_pending); 1373 + bfa_fcs_rport_hal_offline(rport); 1374 + break; 1375 + 1376 + case RPSM_EVENT_DELETE: 1377 + case RPSM_EVENT_PLOGI_RCVD: 1378 + /* Ignore these events */ 1379 + break; 1380 + 1381 + default: 1382 + bfa_sm_fault(rport->fcs, event); 1383 + break; 1384 + } 1385 + } 1386 + 1387 + /* 1388 + * RPort needs to be deleted 1389 + * waiting for BFA/FW to finish current processing 1390 + */ 1391 + static void 1392 + bfa_fcs_rport_sm_delete_pending(struct bfa_fcs_rport_s *rport, 1393 + enum rport_event event) 1394 + { 1395 + bfa_trc(rport->fcs, rport->pwwn); 1396 + bfa_trc(rport->fcs, rport->pid); 1397 + bfa_trc(rport->fcs, event); 1398 + 1399 + switch (event) { 1400 + case RPSM_EVENT_HCB_OFFLINE: 1401 + bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit); 1402 + bfa_fcs_rport_free(rport); 1403 + break; 1404 + 1405 + case RPSM_EVENT_DELETE: 1406 + case RPSM_EVENT_LOGO_IMP: 1407 + case RPSM_EVENT_PLOGI_RCVD: 1408 + /* Ignore these events */ 1409 + break; 1410 + 1411 + default: 1412 + bfa_sm_fault(rport->fcs, event); 1413 + } 1414 + } 1467 1415 1468 1416 /* 1469 1417 * fcs_rport_private FCS RPORT provate functions ··· 2128 1964 bfa_rport_online(rport->bfa_rport, &rport_info); 2129 1965 } 2130 1966 1967 + static void 1968 + bfa_fcs_rport_hal_offline(struct bfa_fcs_rport_s *rport) 1969 + { 1970 + if (rport->bfa_rport) 1971 + bfa_sm_send_event(rport->bfa_rport, BFA_RPORT_SM_OFFLINE); 1972 + else 1973 + bfa_cb_rport_offline(rport); 1974 + } 1975 + 2131 1976 static struct bfa_fcs_rport_s * 2132 1977 bfa_fcs_rport_alloc(struct bfa_fcs_lport_s *port, wwn_t pwwn, u32 rpid) 2133 1978 { ··· 2147 1974 /* 2148 1975 * allocate rport 2149 1976 */ 1977 + if (fcs->num_rport_logins >= bfa_fcs_rport_max_logins) { 1978 + bfa_trc(fcs, rpid); 1979 + return NULL; 1980 + } 1981 + 2150 1982 if (bfa_fcb_rport_alloc(fcs->bfad, &rport, &rport_drv) 2151 1983 != BFA_STATUS_OK) { 2152 1984 bfa_trc(fcs, rpid); ··· 2168 1990 rport->pwwn = pwwn; 2169 1991 rport->old_pid = 0; 2170 1992 2171 - /* 2172 - * allocate BFA rport 2173 - */ 2174 - rport->bfa_rport = bfa_rport_create(port->fcs->bfa, rport); 2175 - if (!rport->bfa_rport) { 2176 - bfa_trc(fcs, rpid); 2177 - kfree(rport_drv); 2178 - return NULL; 2179 - } 1993 + rport->bfa_rport = NULL; 2180 1994 2181 1995 /* 2182 1996 * allocate FC-4s ··· 2179 2009 rport->itnim = bfa_fcs_itnim_create(rport); 2180 2010 if (!rport->itnim) { 2181 2011 bfa_trc(fcs, rpid); 2182 - bfa_sm_send_event(rport->bfa_rport, 2183 - BFA_RPORT_SM_DELETE); 2184 2012 kfree(rport_drv); 2185 2013 return NULL; 2186 2014 } 2187 2015 } 2188 2016 2189 2017 bfa_fcs_lport_add_rport(port, rport); 2018 + fcs->num_rport_logins++; 2190 2019 2191 2020 bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit); 2192 2021 ··· 2201 2032 bfa_fcs_rport_free(struct bfa_fcs_rport_s *rport) 2202 2033 { 2203 2034 struct bfa_fcs_lport_s *port = rport->port; 2035 + struct bfa_fcs_s *fcs = port->fcs; 2204 2036 2205 2037 /* 2206 2038 * - delete FC-4s 2207 2039 * - delete BFA rport 2208 2040 * - remove from queue of rports 2209 2041 */ 2042 + rport->plogi_pending = BFA_FALSE; 2043 + 2210 2044 if (bfa_fcs_lport_is_initiator(port)) { 2211 2045 bfa_fcs_itnim_delete(rport->itnim); 2212 2046 if (rport->pid != 0 && !BFA_FCS_PID_IS_WKA(rport->pid)) 2213 2047 bfa_fcs_rpf_rport_offline(rport); 2214 2048 } 2215 2049 2216 - bfa_sm_send_event(rport->bfa_rport, BFA_RPORT_SM_DELETE); 2050 + if (rport->bfa_rport) { 2051 + bfa_sm_send_event(rport->bfa_rport, BFA_RPORT_SM_DELETE); 2052 + rport->bfa_rport = NULL; 2053 + } 2054 + 2217 2055 bfa_fcs_lport_del_rport(port, rport); 2056 + fcs->num_rport_logins--; 2218 2057 kfree(rport->rp_drv); 2219 2058 } 2220 2059 ··· 2256 2079 } 2257 2080 2258 2081 static void 2259 - bfa_fcs_rport_online_action(struct bfa_fcs_rport_s *rport) 2082 + bfa_fcs_rport_fcs_online_action(struct bfa_fcs_rport_s *rport) 2083 + { 2084 + if ((!rport->pid) || (!rport->pwwn)) { 2085 + bfa_trc(rport->fcs, rport->pid); 2086 + bfa_sm_fault(rport->fcs, rport->pid); 2087 + } 2088 + 2089 + bfa_sm_send_event(rport->itnim, BFA_FCS_ITNIM_SM_FCS_ONLINE); 2090 + } 2091 + 2092 + static void 2093 + bfa_fcs_rport_hal_online_action(struct bfa_fcs_rport_s *rport) 2260 2094 { 2261 2095 struct bfa_fcs_lport_s *port = rport->port; 2262 2096 struct bfad_s *bfad = (struct bfad_s *)port->fcs->bfad; ··· 2282 2094 } 2283 2095 2284 2096 if (bfa_fcs_lport_is_initiator(port)) { 2285 - bfa_fcs_itnim_rport_online(rport->itnim); 2097 + bfa_fcs_itnim_brp_online(rport->itnim); 2286 2098 if (!BFA_FCS_PID_IS_WKA(rport->pid)) 2287 2099 bfa_fcs_rpf_rport_online(rport); 2288 2100 }; ··· 2298 2110 } 2299 2111 2300 2112 static void 2301 - bfa_fcs_rport_offline_action(struct bfa_fcs_rport_s *rport) 2113 + bfa_fcs_rport_fcs_offline_action(struct bfa_fcs_rport_s *rport) 2114 + { 2115 + if (!BFA_FCS_PID_IS_WKA(rport->pid)) 2116 + bfa_fcs_rpf_rport_offline(rport); 2117 + 2118 + bfa_fcs_itnim_rport_offline(rport->itnim); 2119 + } 2120 + 2121 + static void 2122 + bfa_fcs_rport_hal_offline_action(struct bfa_fcs_rport_s *rport) 2302 2123 { 2303 2124 struct bfa_fcs_lport_s *port = rport->port; 2304 2125 struct bfad_s *bfad = (struct bfad_s *)port->fcs->bfad; 2305 2126 char lpwwn_buf[BFA_STRING_32]; 2306 2127 char rpwwn_buf[BFA_STRING_32]; 2307 2128 2129 + if (!rport->bfa_rport) { 2130 + bfa_fcs_rport_fcs_offline_action(rport); 2131 + return; 2132 + } 2133 + 2308 2134 rport->stats.offlines++; 2309 - rport->plogi_pending = BFA_FALSE; 2310 2135 2311 2136 wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port)); 2312 2137 wwn2str(rpwwn_buf, rport->pwwn); ··· 2548 2347 rport->stats.rscns++; 2549 2348 bfa_sm_send_event(rport, RPSM_EVENT_SCN); 2550 2349 } 2551 - 2552 2350 2553 2351 /* 2554 2352 * brief ··· 2790 2590 bfa_sm_send_event(rport, RPSM_EVENT_PRLO_RCVD); 2791 2591 } 2792 2592 2593 + /* 2594 + * Called by BFAD to set the max limit on number of bfa_fcs_rport allocation 2595 + * which limits number of concurrent logins to remote ports 2596 + */ 2597 + void 2598 + bfa_fcs_rport_set_max_logins(u32 max_logins) 2599 + { 2600 + if (max_logins > 0) 2601 + bfa_fcs_rport_max_logins = max_logins; 2602 + } 2603 + 2793 2604 void 2794 2605 bfa_fcs_rport_get_attr(struct bfa_fcs_rport_s *rport, 2795 2606 struct bfa_rport_attr_s *rport_attr) ··· 2824 2613 rport_attr->curr_speed = rport->rpf.rpsc_speed; 2825 2614 rport_attr->assigned_speed = rport->rpf.assigned_speed; 2826 2615 2827 - qos_attr.qos_priority = rport->bfa_rport->qos_attr.qos_priority; 2828 - qos_attr.qos_flow_id = 2829 - cpu_to_be32(rport->bfa_rport->qos_attr.qos_flow_id); 2616 + if (rport->bfa_rport) { 2617 + qos_attr.qos_priority = rport->bfa_rport->qos_attr.qos_priority; 2618 + qos_attr.qos_flow_id = 2619 + cpu_to_be32(rport->bfa_rport->qos_attr.qos_flow_id); 2620 + } 2830 2621 rport_attr->qos_attr = qos_attr; 2831 2622 2832 2623 rport_attr->trl_enforced = BFA_FALSE;
+9 -2
drivers/scsi/bfa/bfa_svc.c
··· 4275 4275 bfa_sm_set_state(rp, bfa_rport_sm_iocdisable); 4276 4276 break; 4277 4277 4278 + case BFA_RPORT_SM_OFFLINE: 4279 + bfa_rport_offline_cb(rp); 4280 + break; 4281 + 4278 4282 default: 4279 4283 bfa_stats(rp, sm_off_unexp); 4280 4284 bfa_sm_fault(rp->bfa, event); ··· 4395 4391 case BFA_RPORT_SM_HWFAIL: 4396 4392 bfa_stats(rp, sm_offp_hwf); 4397 4393 bfa_sm_set_state(rp, bfa_rport_sm_iocdisable); 4394 + bfa_rport_offline_cb(rp); 4398 4395 break; 4399 4396 4400 4397 default: ··· 4774 4769 WARN_ON(speed == 0); 4775 4770 WARN_ON(speed == BFA_PORT_SPEED_AUTO); 4776 4771 4777 - rport->rport_info.speed = speed; 4778 - bfa_sm_send_event(rport, BFA_RPORT_SM_SET_SPEED); 4772 + if (rport) { 4773 + rport->rport_info.speed = speed; 4774 + bfa_sm_send_event(rport, BFA_RPORT_SM_SET_SPEED); 4775 + } 4779 4776 } 4780 4777 4781 4778 /* Set Rport LUN Mask */
+4
drivers/scsi/bfa/bfad.c
··· 57 57 int bfa_debugfs_enable = 1; 58 58 int msix_disable_cb = 0, msix_disable_ct = 0; 59 59 int max_xfer_size = BFAD_MAX_SECTORS >> 1; 60 + int max_rport_logins = BFA_FCS_MAX_RPORT_LOGINS; 60 61 61 62 /* Firmware releated */ 62 63 u32 bfi_image_cb_size, bfi_image_ct_size, bfi_image_ct2_size; ··· 149 148 module_param(max_xfer_size, int, S_IRUGO | S_IWUSR); 150 149 MODULE_PARM_DESC(max_xfer_size, "default=32MB," 151 150 " Range[64k|128k|256k|512k|1024k|2048k]"); 151 + module_param(max_rport_logins, int, S_IRUGO | S_IWUSR); 152 + MODULE_PARM_DESC(max_rport_logins, "Max number of logins to initiator and target rports on a port (physical/logical), default=1024"); 152 153 153 154 static void 154 155 bfad_sm_uninit(struct bfad_s *bfad, enum bfad_sm_event event); ··· 1769 1766 1770 1767 bfa_auto_recover = ioc_auto_recover; 1771 1768 bfa_fcs_rport_set_del_timeout(rport_del_timeout); 1769 + bfa_fcs_rport_set_max_logins(max_rport_logins); 1772 1770 1773 1771 error = pci_register_driver(&bfad_pci_driver); 1774 1772 if (error) {
+13 -8
drivers/scsi/bfa/bfad_bsg.c
··· 677 677 678 678 memcpy((void *)&iocmd->stats, (void *)&fcs_rport->stats, 679 679 sizeof(struct bfa_rport_stats_s)); 680 - memcpy((void *)&iocmd->stats.hal_stats, 681 - (void *)&(bfa_fcs_rport_get_halrport(fcs_rport)->stats), 682 - sizeof(struct bfa_rport_hal_stats_s)); 680 + if (bfa_fcs_rport_get_halrport(fcs_rport)) { 681 + memcpy((void *)&iocmd->stats.hal_stats, 682 + (void *)&(bfa_fcs_rport_get_halrport(fcs_rport)->stats), 683 + sizeof(struct bfa_rport_hal_stats_s)); 684 + } 683 685 684 686 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 685 687 iocmd->status = BFA_STATUS_OK; ··· 717 715 718 716 memset((char *)&fcs_rport->stats, 0, sizeof(struct bfa_rport_stats_s)); 719 717 rport = bfa_fcs_rport_get_halrport(fcs_rport); 720 - memset(&rport->stats, 0, sizeof(rport->stats)); 718 + if (rport) 719 + memset(&rport->stats, 0, sizeof(rport->stats)); 721 720 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 722 721 iocmd->status = BFA_STATUS_OK; 723 722 out: ··· 753 750 fcs_rport->rpf.assigned_speed = iocmd->speed; 754 751 /* Set this speed in f/w only if the RPSC speed is not available */ 755 752 if (fcs_rport->rpf.rpsc_speed == BFA_PORT_SPEED_UNKNOWN) 756 - bfa_rport_speed(fcs_rport->bfa_rport, iocmd->speed); 753 + if (fcs_rport->bfa_rport) 754 + bfa_rport_speed(fcs_rport->bfa_rport, iocmd->speed); 757 755 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 758 756 iocmd->status = BFA_STATUS_OK; 759 757 out: ··· 1040 1036 iocmd->status = BFA_STATUS_UNKNOWN_RWWN; 1041 1037 else { 1042 1038 iocmd->status = BFA_STATUS_OK; 1043 - memcpy((void *)&iocmd->iostats, (void *) 1044 - &(bfa_fcs_itnim_get_halitn(itnim)->stats), 1045 - sizeof(struct bfa_itnim_iostats_s)); 1039 + if (bfa_fcs_itnim_get_halitn(itnim)) 1040 + memcpy((void *)&iocmd->iostats, (void *) 1041 + &(bfa_fcs_itnim_get_halitn(itnim)->stats), 1042 + sizeof(struct bfa_itnim_iostats_s)); 1046 1043 } 1047 1044 } 1048 1045 spin_unlock_irqrestore(&bfad->bfad_lock, flags);