diff options
author | James Smart <James.Smart@Emulex.Com> | 2008-08-24 21:49:00 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2008-10-13 09:28:53 -0400 |
commit | e59058c44025d71c9b7f260076a932935d3bba95 (patch) | |
tree | 36cd4b31ac3b130849c5ad4d2c0cef035a7389dd /drivers/scsi/lpfc/lpfc_els.c | |
parent | 4a27446f3e39b06c28d1c8e31d33a5340826ed5c (diff) |
[SCSI] lpfc 8.2.8 : Add kernel-doc function headers
Signed-off-by: James Smart <james.smart@emulex.com>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_els.c')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_els.c | 1345 |
1 files changed, 1340 insertions, 5 deletions
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index f54e0f7eaee3..43049b9d64c9 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c | |||
@@ -53,6 +53,28 @@ static void lpfc_register_new_vport(struct lpfc_hba *phba, | |||
53 | 53 | ||
54 | static int lpfc_max_els_tries = 3; | 54 | static int lpfc_max_els_tries = 3; |
55 | 55 | ||
56 | /** | ||
57 | * lpfc_els_chk_latt: Check host link attention event for a vport. | ||
58 | * @vport: pointer to a host virtual N_Port data structure. | ||
59 | * | ||
60 | * This routine checks whether there is an outstanding host link | ||
61 | * attention event during the discovery process with the @vport. It is done | ||
62 | * by reading the HBA's Host Attention (HA) register. If there is any host | ||
63 | * link attention events during this @vport's discovery process, the @vport | ||
64 | * shall be marked as FC_ABORT_DISCOVERY, a host link attention clear shall | ||
65 | * be issued if the link state is not already in host link cleared state, | ||
66 | * and a return code shall indicate whether the host link attention event | ||
67 | * had happened. | ||
68 | * | ||
69 | * Note that, if either the host link is in state LPFC_LINK_DOWN or @vport | ||
70 | * state in LPFC_VPORT_READY, the request for checking host link attention | ||
71 | * event will be ignored and a return code shall indicate no host link | ||
72 | * attention event had happened. | ||
73 | * | ||
74 | * Return codes | ||
75 | * 0 - no host link attention event happened | ||
76 | * 1 - host link attention event happened | ||
77 | **/ | ||
56 | int | 78 | int |
57 | lpfc_els_chk_latt(struct lpfc_vport *vport) | 79 | lpfc_els_chk_latt(struct lpfc_vport *vport) |
58 | { | 80 | { |
@@ -92,6 +114,34 @@ lpfc_els_chk_latt(struct lpfc_vport *vport) | |||
92 | return 1; | 114 | return 1; |
93 | } | 115 | } |
94 | 116 | ||
117 | /** | ||
118 | * lpfc_prep_els_iocb: Allocate and prepare a lpfc iocb data structure. | ||
119 | * @vport: pointer to a host virtual N_Port data structure. | ||
120 | * @expectRsp: flag indicating whether response is expected. | ||
121 | * @cmdSize: size of the ELS command. | ||
122 | * @retry: number of retries to the command IOCB when it fails. | ||
123 | * @ndlp: pointer to a node-list data structure. | ||
124 | * @did: destination identifier. | ||
125 | * @elscmd: the ELS command code. | ||
126 | * | ||
127 | * This routine is used for allocating a lpfc-IOCB data structure from | ||
128 | * the driver lpfc-IOCB free-list and prepare the IOCB with the parameters | ||
129 | * passed into the routine for discovery state machine to issue an Extended | ||
130 | * Link Service (ELS) commands. It is a generic lpfc-IOCB allocation | ||
131 | * and preparation routine that is used by all the discovery state machine | ||
132 | * routines and the ELS command-specific fields will be later set up by | ||
133 | * the individual discovery machine routines after calling this routine | ||
134 | * allocating and preparing a generic IOCB data structure. It fills in the | ||
135 | * Buffer Descriptor Entries (BDEs), allocates buffers for both command | ||
136 | * payload and response payload (if expected). The reference count on the | ||
137 | * ndlp is incremented by 1 and the reference to the ndlp is put into | ||
138 | * context1 of the IOCB data structure for this IOCB to hold the ndlp | ||
139 | * reference for the command's callback function to access later. | ||
140 | * | ||
141 | * Return code | ||
142 | * Pointer to the newly allocated/prepared els iocb data structure | ||
143 | * NULL - when els iocb data structure allocation/preparation failed | ||
144 | **/ | ||
95 | static struct lpfc_iocbq * | 145 | static struct lpfc_iocbq * |
96 | lpfc_prep_els_iocb(struct lpfc_vport *vport, uint8_t expectRsp, | 146 | lpfc_prep_els_iocb(struct lpfc_vport *vport, uint8_t expectRsp, |
97 | uint16_t cmdSize, uint8_t retry, | 147 | uint16_t cmdSize, uint8_t retry, |
@@ -233,6 +283,22 @@ els_iocb_free_pcmb_exit: | |||
233 | return NULL; | 283 | return NULL; |
234 | } | 284 | } |
235 | 285 | ||
286 | /** | ||
287 | * lpfc_issue_fabric_reglogin: Issue fabric registration login for a vport. | ||
288 | * @vport: pointer to a host virtual N_Port data structure. | ||
289 | * | ||
290 | * This routine issues a fabric registration login for a @vport. An | ||
291 | * active ndlp node with Fabric_DID must already exist for this @vport. | ||
292 | * The routine invokes two mailbox commands to carry out fabric registration | ||
293 | * login through the HBA firmware: the first mailbox command requests the | ||
294 | * HBA to perform link configuration for the @vport; and the second mailbox | ||
295 | * command requests the HBA to perform the actual fabric registration login | ||
296 | * with the @vport. | ||
297 | * | ||
298 | * Return code | ||
299 | * 0 - successfully issued fabric registration login for @vport | ||
300 | * -ENXIO -- failed to issue fabric registration login for @vport | ||
301 | **/ | ||
236 | static int | 302 | static int |
237 | lpfc_issue_fabric_reglogin(struct lpfc_vport *vport) | 303 | lpfc_issue_fabric_reglogin(struct lpfc_vport *vport) |
238 | { | 304 | { |
@@ -313,6 +379,26 @@ fail: | |||
313 | return -ENXIO; | 379 | return -ENXIO; |
314 | } | 380 | } |
315 | 381 | ||
382 | /** | ||
383 | * lpfc_cmpl_els_flogi_fabric: Completion function for flogi to a fabric port. | ||
384 | * @vport: pointer to a host virtual N_Port data structure. | ||
385 | * @ndlp: pointer to a node-list data structure. | ||
386 | * @sp: pointer to service parameter data structure. | ||
387 | * @irsp: pointer to the IOCB within the lpfc response IOCB. | ||
388 | * | ||
389 | * This routine is invoked by the lpfc_cmpl_els_flogi() completion callback | ||
390 | * function to handle the completion of a Fabric Login (FLOGI) into a fabric | ||
391 | * port in a fabric topology. It properly sets up the parameters to the @ndlp | ||
392 | * from the IOCB response. It also check the newly assigned N_Port ID to the | ||
393 | * @vport against the previously assigned N_Port ID. If it is different from | ||
394 | * the previously assigned Destination ID (DID), the lpfc_unreg_rpi() routine | ||
395 | * is invoked on all the remaining nodes with the @vport to unregister the | ||
396 | * Remote Port Indicators (RPIs). Finally, the lpfc_issue_fabric_reglogin() | ||
397 | * is invoked to register login to the fabric. | ||
398 | * | ||
399 | * Return code | ||
400 | * 0 - Success (currently, always return 0) | ||
401 | **/ | ||
316 | static int | 402 | static int |
317 | lpfc_cmpl_els_flogi_fabric(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | 403 | lpfc_cmpl_els_flogi_fabric(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
318 | struct serv_parm *sp, IOCB_t *irsp) | 404 | struct serv_parm *sp, IOCB_t *irsp) |
@@ -416,9 +502,26 @@ lpfc_cmpl_els_flogi_fabric(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | |||
416 | return 0; | 502 | return 0; |
417 | } | 503 | } |
418 | 504 | ||
419 | /* | 505 | /** |
420 | * We FLOGIed into an NPort, initiate pt2pt protocol | 506 | * lpfc_cmpl_els_flogi_nport: Completion function for flogi to an N_Port. |
421 | */ | 507 | * @vport: pointer to a host virtual N_Port data structure. |
508 | * @ndlp: pointer to a node-list data structure. | ||
509 | * @sp: pointer to service parameter data structure. | ||
510 | * | ||
511 | * This routine is invoked by the lpfc_cmpl_els_flogi() completion callback | ||
512 | * function to handle the completion of a Fabric Login (FLOGI) into an N_Port | ||
513 | * in a point-to-point topology. First, the @vport's N_Port Name is compared | ||
514 | * with the received N_Port Name: if the @vport's N_Port Name is greater than | ||
515 | * the received N_Port Name lexicographically, this node shall assign local | ||
516 | * N_Port ID (PT2PT_LocalID: 1) and remote N_Port ID (PT2PT_RemoteID: 2) and | ||
517 | * will send out Port Login (PLOGI) with the N_Port IDs assigned. Otherwise, | ||
518 | * this node shall just wait for the remote node to issue PLOGI and assign | ||
519 | * N_Port IDs. | ||
520 | * | ||
521 | * Return code | ||
522 | * 0 - Success | ||
523 | * -ENXIO - Fail | ||
524 | **/ | ||
422 | static int | 525 | static int |
423 | lpfc_cmpl_els_flogi_nport(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | 526 | lpfc_cmpl_els_flogi_nport(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
424 | struct serv_parm *sp) | 527 | struct serv_parm *sp) |
@@ -516,6 +619,29 @@ fail: | |||
516 | return -ENXIO; | 619 | return -ENXIO; |
517 | } | 620 | } |
518 | 621 | ||
622 | /** | ||
623 | * lpfc_cmpl_els_flogi: Completion callback function for flogi. | ||
624 | * @phba: pointer to lpfc hba data structure. | ||
625 | * @cmdiocb: pointer to lpfc command iocb data structure. | ||
626 | * @rspiocb: pointer to lpfc response iocb data structure. | ||
627 | * | ||
628 | * This routine is the top-level completion callback function for issuing | ||
629 | * a Fabric Login (FLOGI) command. If the response IOCB reported error, | ||
630 | * the lpfc_els_retry() routine shall be invoked to retry the FLOGI. If | ||
631 | * retry has been made (either immediately or delayed with lpfc_els_retry() | ||
632 | * returning 1), the command IOCB will be released and function returned. | ||
633 | * If the retry attempt has been given up (possibly reach the maximum | ||
634 | * number of retries), one additional decrement of ndlp reference shall be | ||
635 | * invoked before going out after releasing the command IOCB. This will | ||
636 | * actually release the remote node (Note, lpfc_els_free_iocb() will also | ||
637 | * invoke one decrement of ndlp reference count). If no error reported in | ||
638 | * the IOCB status, the command Port ID field is used to determine whether | ||
639 | * this is a point-to-point topology or a fabric topology: if the Port ID | ||
640 | * field is assigned, it is a fabric topology; otherwise, it is a | ||
641 | * point-to-point topology. The routine lpfc_cmpl_els_flogi_fabric() or | ||
642 | * lpfc_cmpl_els_flogi_nport() shall be invoked accordingly to handle the | ||
643 | * specific topology completion conditions. | ||
644 | **/ | ||
519 | static void | 645 | static void |
520 | lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | 646 | lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, |
521 | struct lpfc_iocbq *rspiocb) | 647 | struct lpfc_iocbq *rspiocb) |
@@ -618,6 +744,28 @@ out: | |||
618 | lpfc_els_free_iocb(phba, cmdiocb); | 744 | lpfc_els_free_iocb(phba, cmdiocb); |
619 | } | 745 | } |
620 | 746 | ||
747 | /** | ||
748 | * lpfc_issue_els_flogi: Issue an flogi iocb command for a vport. | ||
749 | * @vport: pointer to a host virtual N_Port data structure. | ||
750 | * @ndlp: pointer to a node-list data structure. | ||
751 | * @retry: number of retries to the command IOCB. | ||
752 | * | ||
753 | * This routine issues a Fabric Login (FLOGI) Request ELS command | ||
754 | * for a @vport. The initiator service parameters are put into the payload | ||
755 | * of the FLOGI Request IOCB and the top-level callback function pointer | ||
756 | * to lpfc_cmpl_els_flogi() routine is put to the IOCB completion callback | ||
757 | * function field. The lpfc_issue_fabric_iocb routine is invoked to send | ||
758 | * out FLOGI ELS command with one outstanding fabric IOCB at a time. | ||
759 | * | ||
760 | * Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp | ||
761 | * will be incremented by 1 for holding the ndlp and the reference to ndlp | ||
762 | * will be stored into the context1 field of the IOCB for the completion | ||
763 | * callback function to the FLOGI ELS command. | ||
764 | * | ||
765 | * Return code | ||
766 | * 0 - successfully issued flogi iocb for @vport | ||
767 | * 1 - failed to issue flogi iocb for @vport | ||
768 | **/ | ||
621 | static int | 769 | static int |
622 | lpfc_issue_els_flogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | 770 | lpfc_issue_els_flogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
623 | uint8_t retry) | 771 | uint8_t retry) |
@@ -694,6 +842,20 @@ lpfc_issue_els_flogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | |||
694 | return 0; | 842 | return 0; |
695 | } | 843 | } |
696 | 844 | ||
845 | /** | ||
846 | * lpfc_els_abort_flogi: Abort all outstanding flogi iocbs. | ||
847 | * @phba: pointer to lpfc hba data structure. | ||
848 | * | ||
849 | * This routine aborts all the outstanding Fabric Login (FLOGI) IOCBs | ||
850 | * with a @phba. This routine walks all the outstanding IOCBs on the txcmplq | ||
851 | * list and issues an abort IOCB commond on each outstanding IOCB that | ||
852 | * contains a active Fabric_DID ndlp. Note that this function is to issue | ||
853 | * the abort IOCB command on all the outstanding IOCBs, thus when this | ||
854 | * function returns, it does not guarantee all the IOCBs are actually aborted. | ||
855 | * | ||
856 | * Return code | ||
857 | * 0 - Sucessfully issued abort iocb on all outstanding flogis (Always 0) | ||
858 | **/ | ||
697 | int | 859 | int |
698 | lpfc_els_abort_flogi(struct lpfc_hba *phba) | 860 | lpfc_els_abort_flogi(struct lpfc_hba *phba) |
699 | { | 861 | { |
@@ -729,6 +891,22 @@ lpfc_els_abort_flogi(struct lpfc_hba *phba) | |||
729 | return 0; | 891 | return 0; |
730 | } | 892 | } |
731 | 893 | ||
894 | /** | ||
895 | * lpfc_initial_flogi: Issue an initial fabric login for a vport. | ||
896 | * @vport: pointer to a host virtual N_Port data structure. | ||
897 | * | ||
898 | * This routine issues an initial Fabric Login (FLOGI) for the @vport | ||
899 | * specified. It first searches the ndlp with the Fabric_DID (0xfffffe) from | ||
900 | * the @vport's ndlp list. If no such ndlp found, it will create an ndlp and | ||
901 | * put it into the @vport's ndlp list. If an inactive ndlp found on the list, | ||
902 | * it will just be enabled and made active. The lpfc_issue_els_flogi() routine | ||
903 | * is then invoked with the @vport and the ndlp to perform the FLOGI for the | ||
904 | * @vport. | ||
905 | * | ||
906 | * Return code | ||
907 | * 0 - failed to issue initial flogi for @vport | ||
908 | * 1 - successfully issued initial flogi for @vport | ||
909 | **/ | ||
732 | int | 910 | int |
733 | lpfc_initial_flogi(struct lpfc_vport *vport) | 911 | lpfc_initial_flogi(struct lpfc_vport *vport) |
734 | { | 912 | { |
@@ -764,6 +942,22 @@ lpfc_initial_flogi(struct lpfc_vport *vport) | |||
764 | return 1; | 942 | return 1; |
765 | } | 943 | } |
766 | 944 | ||
945 | /** | ||
946 | * lpfc_initial_fdisc: Issue an initial fabric discovery for a vport. | ||
947 | * @vport: pointer to a host virtual N_Port data structure. | ||
948 | * | ||
949 | * This routine issues an initial Fabric Discover (FDISC) for the @vport | ||
950 | * specified. It first searches the ndlp with the Fabric_DID (0xfffffe) from | ||
951 | * the @vport's ndlp list. If no such ndlp found, it will create an ndlp and | ||
952 | * put it into the @vport's ndlp list. If an inactive ndlp found on the list, | ||
953 | * it will just be enabled and made active. The lpfc_issue_els_fdisc() routine | ||
954 | * is then invoked with the @vport and the ndlp to perform the FDISC for the | ||
955 | * @vport. | ||
956 | * | ||
957 | * Return code | ||
958 | * 0 - failed to issue initial fdisc for @vport | ||
959 | * 1 - successfully issued initial fdisc for @vport | ||
960 | **/ | ||
767 | int | 961 | int |
768 | lpfc_initial_fdisc(struct lpfc_vport *vport) | 962 | lpfc_initial_fdisc(struct lpfc_vport *vport) |
769 | { | 963 | { |
@@ -797,6 +991,17 @@ lpfc_initial_fdisc(struct lpfc_vport *vport) | |||
797 | return 1; | 991 | return 1; |
798 | } | 992 | } |
799 | 993 | ||
994 | /** | ||
995 | * lpfc_more_plogi: Check and issue remaining plogis for a vport. | ||
996 | * @vport: pointer to a host virtual N_Port data structure. | ||
997 | * | ||
998 | * This routine checks whether there are more remaining Port Logins | ||
999 | * (PLOGI) to be issued for the @vport. If so, it will invoke the routine | ||
1000 | * lpfc_els_disc_plogi() to go through the Node Port Recovery (NPR) nodes | ||
1001 | * to issue ELS PLOGIs up to the configured discover threads with the | ||
1002 | * @vport (@vport->cfg_discovery_threads). The function also decrement | ||
1003 | * the @vport's num_disc_node by 1 if it is not already 0. | ||
1004 | **/ | ||
800 | void | 1005 | void |
801 | lpfc_more_plogi(struct lpfc_vport *vport) | 1006 | lpfc_more_plogi(struct lpfc_vport *vport) |
802 | { | 1007 | { |
@@ -819,6 +1024,37 @@ lpfc_more_plogi(struct lpfc_vport *vport) | |||
819 | return; | 1024 | return; |
820 | } | 1025 | } |
821 | 1026 | ||
1027 | /** | ||
1028 | * lpfc_plogi_confirm_nport: Confirm pologi wwpn matches stored ndlp. | ||
1029 | * @phba: pointer to lpfc hba data structure. | ||
1030 | * @prsp: pointer to response IOCB payload. | ||
1031 | * @ndlp: pointer to a node-list data structure. | ||
1032 | * | ||
1033 | * This routine checks and indicates whether the WWPN of an N_Port, retrieved | ||
1034 | * from a PLOGI, matches the WWPN that is stored in the @ndlp for that N_POrt. | ||
1035 | * The following cases are considered N_Port confirmed: | ||
1036 | * 1) The N_Port is a Fabric ndlp; 2) The @ndlp is on vport list and matches | ||
1037 | * the WWPN of the N_Port logged into; 3) The @ndlp is not on vport list but | ||
1038 | * it does not have WWPN assigned either. If the WWPN is confirmed, the | ||
1039 | * pointer to the @ndlp will be returned. If the WWPN is not confirmed: | ||
1040 | * 1) if there is a node on vport list other than the @ndlp with the same | ||
1041 | * WWPN of the N_Port PLOGI logged into, the lpfc_unreg_rpi() will be invoked | ||
1042 | * on that node to release the RPI associated with the node; 2) if there is | ||
1043 | * no node found on vport list with the same WWPN of the N_Port PLOGI logged | ||
1044 | * into, a new node shall be allocated (or activated). In either case, the | ||
1045 | * parameters of the @ndlp shall be copied to the new_ndlp, the @ndlp shall | ||
1046 | * be released and the new_ndlp shall be put on to the vport node list and | ||
1047 | * its pointer returned as the confirmed node. | ||
1048 | * | ||
1049 | * Note that before the @ndlp got "released", the keepDID from not-matching | ||
1050 | * or inactive "new_ndlp" on the vport node list is assigned to the nlp_DID | ||
1051 | * of the @ndlp. This is because the release of @ndlp is actually to put it | ||
1052 | * into an inactive state on the vport node list and the vport node list | ||
1053 | * management algorithm does not allow two node with a same DID. | ||
1054 | * | ||
1055 | * Return code | ||
1056 | * pointer to the PLOGI N_Port @ndlp | ||
1057 | **/ | ||
822 | static struct lpfc_nodelist * | 1058 | static struct lpfc_nodelist * |
823 | lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp, | 1059 | lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp, |
824 | struct lpfc_nodelist *ndlp) | 1060 | struct lpfc_nodelist *ndlp) |
@@ -922,6 +1158,17 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp, | |||
922 | return new_ndlp; | 1158 | return new_ndlp; |
923 | } | 1159 | } |
924 | 1160 | ||
1161 | /** | ||
1162 | * lpfc_end_rscn: Check and handle more rscn for a vport. | ||
1163 | * @vport: pointer to a host virtual N_Port data structure. | ||
1164 | * | ||
1165 | * This routine checks whether more Registration State Change | ||
1166 | * Notifications (RSCNs) came in while the discovery state machine was in | ||
1167 | * the FC_RSCN_MODE. If so, the lpfc_els_handle_rscn() routine will be | ||
1168 | * invoked to handle the additional RSCNs for the @vport. Otherwise, the | ||
1169 | * FC_RSCN_MODE bit will be cleared with the @vport to mark as the end of | ||
1170 | * handling the RSCNs. | ||
1171 | **/ | ||
925 | void | 1172 | void |
926 | lpfc_end_rscn(struct lpfc_vport *vport) | 1173 | lpfc_end_rscn(struct lpfc_vport *vport) |
927 | { | 1174 | { |
@@ -943,6 +1190,26 @@ lpfc_end_rscn(struct lpfc_vport *vport) | |||
943 | } | 1190 | } |
944 | } | 1191 | } |
945 | 1192 | ||
1193 | /** | ||
1194 | * lpfc_cmpl_els_plogi: Completion callback function for plogi. | ||
1195 | * @phba: pointer to lpfc hba data structure. | ||
1196 | * @cmdiocb: pointer to lpfc command iocb data structure. | ||
1197 | * @rspiocb: pointer to lpfc response iocb data structure. | ||
1198 | * | ||
1199 | * This routine is the completion callback function for issuing the Port | ||
1200 | * Login (PLOGI) command. For PLOGI completion, there must be an active | ||
1201 | * ndlp on the vport node list that matches the remote node ID from the | ||
1202 | * PLOGI reponse IOCB. If such ndlp does not exist, the PLOGI is simply | ||
1203 | * ignored and command IOCB released. The PLOGI response IOCB status is | ||
1204 | * checked for error conditons. If there is error status reported, PLOGI | ||
1205 | * retry shall be attempted by invoking the lpfc_els_retry() routine. | ||
1206 | * Otherwise, the lpfc_plogi_confirm_nport() routine shall be invoked on | ||
1207 | * the ndlp and the NLP_EVT_CMPL_PLOGI state to the Discover State Machine | ||
1208 | * (DSM) is set for this PLOGI completion. Finally, it checks whether | ||
1209 | * there are additional N_Port nodes with the vport that need to perform | ||
1210 | * PLOGI. If so, the lpfc_more_plogi() routine is invoked to issue addition | ||
1211 | * PLOGIs. | ||
1212 | **/ | ||
946 | static void | 1213 | static void |
947 | lpfc_cmpl_els_plogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | 1214 | lpfc_cmpl_els_plogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, |
948 | struct lpfc_iocbq *rspiocb) | 1215 | struct lpfc_iocbq *rspiocb) |
@@ -1048,6 +1315,27 @@ out: | |||
1048 | return; | 1315 | return; |
1049 | } | 1316 | } |
1050 | 1317 | ||
1318 | /** | ||
1319 | * lpfc_issue_els_plogi: Issue an plogi iocb command for a vport. | ||
1320 | * @vport: pointer to a host virtual N_Port data structure. | ||
1321 | * @did: destination port identifier. | ||
1322 | * @retry: number of retries to the command IOCB. | ||
1323 | * | ||
1324 | * This routine issues a Port Login (PLOGI) command to a remote N_Port | ||
1325 | * (with the @did) for a @vport. Before issuing a PLOGI to a remote N_Port, | ||
1326 | * the ndlp with the remote N_Port DID must exist on the @vport's ndlp list. | ||
1327 | * This routine constructs the proper feilds of the PLOGI IOCB and invokes | ||
1328 | * the lpfc_sli_issue_iocb() routine to send out PLOGI ELS command. | ||
1329 | * | ||
1330 | * Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp | ||
1331 | * will be incremented by 1 for holding the ndlp and the reference to ndlp | ||
1332 | * will be stored into the context1 field of the IOCB for the completion | ||
1333 | * callback function to the PLOGI ELS command. | ||
1334 | * | ||
1335 | * Return code | ||
1336 | * 0 - Successfully issued a plogi for @vport | ||
1337 | * 1 - failed to issue a plogi for @vport | ||
1338 | **/ | ||
1051 | int | 1339 | int |
1052 | lpfc_issue_els_plogi(struct lpfc_vport *vport, uint32_t did, uint8_t retry) | 1340 | lpfc_issue_els_plogi(struct lpfc_vport *vport, uint32_t did, uint8_t retry) |
1053 | { | 1341 | { |
@@ -1106,6 +1394,19 @@ lpfc_issue_els_plogi(struct lpfc_vport *vport, uint32_t did, uint8_t retry) | |||
1106 | return 0; | 1394 | return 0; |
1107 | } | 1395 | } |
1108 | 1396 | ||
1397 | /** | ||
1398 | * lpfc_cmpl_els_prli: Completion callback function for prli. | ||
1399 | * @phba: pointer to lpfc hba data structure. | ||
1400 | * @cmdiocb: pointer to lpfc command iocb data structure. | ||
1401 | * @rspiocb: pointer to lpfc response iocb data structure. | ||
1402 | * | ||
1403 | * This routine is the completion callback function for a Process Login | ||
1404 | * (PRLI) ELS command. The PRLI response IOCB status is checked for error | ||
1405 | * status. If there is error status reported, PRLI retry shall be attempted | ||
1406 | * by invoking the lpfc_els_retry() routine. Otherwise, the state | ||
1407 | * NLP_EVT_CMPL_PRLI is sent to the Discover State Machine (DSM) for this | ||
1408 | * ndlp to mark the PRLI completion. | ||
1409 | **/ | ||
1109 | static void | 1410 | static void |
1110 | lpfc_cmpl_els_prli(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | 1411 | lpfc_cmpl_els_prli(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, |
1111 | struct lpfc_iocbq *rspiocb) | 1412 | struct lpfc_iocbq *rspiocb) |
@@ -1164,6 +1465,27 @@ out: | |||
1164 | return; | 1465 | return; |
1165 | } | 1466 | } |
1166 | 1467 | ||
1468 | /** | ||
1469 | * lpfc_issue_els_prli: Issue a prli iocb command for a vport. | ||
1470 | * @vport: pointer to a host virtual N_Port data structure. | ||
1471 | * @ndlp: pointer to a node-list data structure. | ||
1472 | * @retry: number of retries to the command IOCB. | ||
1473 | * | ||
1474 | * This routine issues a Process Login (PRLI) ELS command for the | ||
1475 | * @vport. The PRLI service parameters are set up in the payload of the | ||
1476 | * PRLI Request command and the pointer to lpfc_cmpl_els_prli() routine | ||
1477 | * is put to the IOCB completion callback func field before invoking the | ||
1478 | * routine lpfc_sli_issue_iocb() to send out PRLI command. | ||
1479 | * | ||
1480 | * Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp | ||
1481 | * will be incremented by 1 for holding the ndlp and the reference to ndlp | ||
1482 | * will be stored into the context1 field of the IOCB for the completion | ||
1483 | * callback function to the PRLI ELS command. | ||
1484 | * | ||
1485 | * Return code | ||
1486 | * 0 - successfully issued prli iocb command for @vport | ||
1487 | * 1 - failed to issue prli iocb command for @vport | ||
1488 | **/ | ||
1167 | int | 1489 | int |
1168 | lpfc_issue_els_prli(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | 1490 | lpfc_issue_els_prli(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
1169 | uint8_t retry) | 1491 | uint8_t retry) |
@@ -1233,6 +1555,15 @@ lpfc_issue_els_prli(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | |||
1233 | return 0; | 1555 | return 0; |
1234 | } | 1556 | } |
1235 | 1557 | ||
1558 | /** | ||
1559 | * lpfc_more_adisc: Issue more adisc as needed. | ||
1560 | * @vport: pointer to a host virtual N_Port data structure. | ||
1561 | * | ||
1562 | * This routine determines whether there are more ndlps on a @vport | ||
1563 | * node list need to have Address Discover (ADISC) issued. If so, it will | ||
1564 | * invoke the lpfc_els_disc_adisc() routine to issue ADISC on the @vport's | ||
1565 | * remaining nodes which need to have ADISC sent. | ||
1566 | **/ | ||
1236 | void | 1567 | void |
1237 | lpfc_more_adisc(struct lpfc_vport *vport) | 1568 | lpfc_more_adisc(struct lpfc_vport *vport) |
1238 | { | 1569 | { |
@@ -1255,6 +1586,18 @@ lpfc_more_adisc(struct lpfc_vport *vport) | |||
1255 | return; | 1586 | return; |
1256 | } | 1587 | } |
1257 | 1588 | ||
1589 | /** | ||
1590 | * lpfc_rscn_disc: Perform rscn discovery for a vport. | ||
1591 | * @vport: pointer to a host virtual N_Port data structure. | ||
1592 | * | ||
1593 | * This routine performs Registration State Change Notification (RSCN) | ||
1594 | * discovery for a @vport. If the @vport's node port recovery count is not | ||
1595 | * zero, it will invoke the lpfc_els_disc_plogi() to perform PLOGI for all | ||
1596 | * the nodes that need recovery. If none of the PLOGI were needed through | ||
1597 | * the lpfc_els_disc_plogi() routine, the lpfc_end_rscn() routine shall be | ||
1598 | * invoked to check and handle possible more RSCN came in during the period | ||
1599 | * of processing the current ones. | ||
1600 | **/ | ||
1258 | static void | 1601 | static void |
1259 | lpfc_rscn_disc(struct lpfc_vport *vport) | 1602 | lpfc_rscn_disc(struct lpfc_vport *vport) |
1260 | { | 1603 | { |
@@ -1269,6 +1612,22 @@ lpfc_rscn_disc(struct lpfc_vport *vport) | |||
1269 | lpfc_end_rscn(vport); | 1612 | lpfc_end_rscn(vport); |
1270 | } | 1613 | } |
1271 | 1614 | ||
1615 | /** | ||
1616 | * lpfc_cmpl_els_adisc: Completion callback function for adisc. | ||
1617 | * @phba: pointer to lpfc hba data structure. | ||
1618 | * @cmdiocb: pointer to lpfc command iocb data structure. | ||
1619 | * @rspiocb: pointer to lpfc response iocb data structure. | ||
1620 | * | ||
1621 | * This routine is the completion function for issuing the Address Discover | ||
1622 | * (ADISC) command. It first checks to see whether link went down during | ||
1623 | * the discovery process. If so, the node will be marked as node port | ||
1624 | * recovery for issuing discover IOCB by the link attention handler and | ||
1625 | * exit. Otherwise, the response status is checked. If error was reported | ||
1626 | * in the response status, the ADISC command shall be retried by invoking | ||
1627 | * the lpfc_els_retry() routine. Otherwise, if no error was reported in | ||
1628 | * the response status, the state machine is invoked to set transition | ||
1629 | * with respect to NLP_EVT_CMPL_ADISC event. | ||
1630 | **/ | ||
1272 | static void | 1631 | static void |
1273 | lpfc_cmpl_els_adisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | 1632 | lpfc_cmpl_els_adisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, |
1274 | struct lpfc_iocbq *rspiocb) | 1633 | struct lpfc_iocbq *rspiocb) |
@@ -1384,6 +1743,26 @@ out: | |||
1384 | return; | 1743 | return; |
1385 | } | 1744 | } |
1386 | 1745 | ||
1746 | /** | ||
1747 | * lpfc_issue_els_adisc: Issue an address discover iocb to an node on a vport. | ||
1748 | * @vport: pointer to a virtual N_Port data structure. | ||
1749 | * @ndlp: pointer to a node-list data structure. | ||
1750 | * @retry: number of retries to the command IOCB. | ||
1751 | * | ||
1752 | * This routine issues an Address Discover (ADISC) for an @ndlp on a | ||
1753 | * @vport. It prepares the payload of the ADISC ELS command, updates the | ||
1754 | * and states of the ndlp, and invokes the lpfc_sli_issue_iocb() routine | ||
1755 | * to issue the ADISC ELS command. | ||
1756 | * | ||
1757 | * Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp | ||
1758 | * will be incremented by 1 for holding the ndlp and the reference to ndlp | ||
1759 | * will be stored into the context1 field of the IOCB for the completion | ||
1760 | * callback function to the ADISC ELS command. | ||
1761 | * | ||
1762 | * Return code | ||
1763 | * 0 - successfully issued adisc | ||
1764 | * 1 - failed to issue adisc | ||
1765 | **/ | ||
1387 | int | 1766 | int |
1388 | lpfc_issue_els_adisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | 1767 | lpfc_issue_els_adisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
1389 | uint8_t retry) | 1768 | uint8_t retry) |
@@ -1437,6 +1816,18 @@ lpfc_issue_els_adisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | |||
1437 | return 0; | 1816 | return 0; |
1438 | } | 1817 | } |
1439 | 1818 | ||
1819 | /** | ||
1820 | * lpfc_cmpl_els_logo: Completion callback function for logo. | ||
1821 | * @phba: pointer to lpfc hba data structure. | ||
1822 | * @cmdiocb: pointer to lpfc command iocb data structure. | ||
1823 | * @rspiocb: pointer to lpfc response iocb data structure. | ||
1824 | * | ||
1825 | * This routine is the completion function for issuing the ELS Logout (LOGO) | ||
1826 | * command. If no error status was reported from the LOGO response, the | ||
1827 | * state machine of the associated ndlp shall be invoked for transition with | ||
1828 | * respect to NLP_EVT_CMPL_LOGO event. Otherwise, if error status was reported, | ||
1829 | * the lpfc_els_retry() routine will be invoked to retry the LOGO command. | ||
1830 | **/ | ||
1440 | static void | 1831 | static void |
1441 | lpfc_cmpl_els_logo(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | 1832 | lpfc_cmpl_els_logo(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, |
1442 | struct lpfc_iocbq *rspiocb) | 1833 | struct lpfc_iocbq *rspiocb) |
@@ -1502,6 +1893,26 @@ out: | |||
1502 | return; | 1893 | return; |
1503 | } | 1894 | } |
1504 | 1895 | ||
1896 | /** | ||
1897 | * lpfc_issue_els_logo: Issue a logo to an node on a vport. | ||
1898 | * @vport: pointer to a virtual N_Port data structure. | ||
1899 | * @ndlp: pointer to a node-list data structure. | ||
1900 | * @retry: number of retries to the command IOCB. | ||
1901 | * | ||
1902 | * This routine constructs and issues an ELS Logout (LOGO) iocb command | ||
1903 | * to a remote node, referred by an @ndlp on a @vport. It constructs the | ||
1904 | * payload of the IOCB, properly sets up the @ndlp state, and invokes the | ||
1905 | * lpfc_sli_issue_iocb() routine to send out the LOGO ELS command. | ||
1906 | * | ||
1907 | * Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp | ||
1908 | * will be incremented by 1 for holding the ndlp and the reference to ndlp | ||
1909 | * will be stored into the context1 field of the IOCB for the completion | ||
1910 | * callback function to the LOGO ELS command. | ||
1911 | * | ||
1912 | * Return code | ||
1913 | * 0 - successfully issued logo | ||
1914 | * 1 - failed to issue logo | ||
1915 | **/ | ||
1505 | int | 1916 | int |
1506 | lpfc_issue_els_logo(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | 1917 | lpfc_issue_els_logo(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
1507 | uint8_t retry) | 1918 | uint8_t retry) |
@@ -1563,6 +1974,22 @@ lpfc_issue_els_logo(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | |||
1563 | return 0; | 1974 | return 0; |
1564 | } | 1975 | } |
1565 | 1976 | ||
1977 | /** | ||
1978 | * lpfc_cmpl_els_cmd: Completion callback function for generic els command. | ||
1979 | * @phba: pointer to lpfc hba data structure. | ||
1980 | * @cmdiocb: pointer to lpfc command iocb data structure. | ||
1981 | * @rspiocb: pointer to lpfc response iocb data structure. | ||
1982 | * | ||
1983 | * This routine is a generic completion callback function for ELS commands. | ||
1984 | * Specifically, it is the callback function which does not need to perform | ||
1985 | * any command specific operations. It is currently used by the ELS command | ||
1986 | * issuing routines for the ELS State Change Request (SCR), | ||
1987 | * lpfc_issue_els_scr(), and the ELS Fibre Channel Address Resolution | ||
1988 | * Protocol Response (FARPR) routine, lpfc_issue_els_farpr(). Other than | ||
1989 | * certain debug loggings, this callback function simply invokes the | ||
1990 | * lpfc_els_chk_latt() routine to check whether link went down during the | ||
1991 | * discovery process. | ||
1992 | **/ | ||
1566 | static void | 1993 | static void |
1567 | lpfc_cmpl_els_cmd(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | 1994 | lpfc_cmpl_els_cmd(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, |
1568 | struct lpfc_iocbq *rspiocb) | 1995 | struct lpfc_iocbq *rspiocb) |
@@ -1587,6 +2014,28 @@ lpfc_cmpl_els_cmd(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
1587 | return; | 2014 | return; |
1588 | } | 2015 | } |
1589 | 2016 | ||
2017 | /** | ||
2018 | * lpfc_issue_els_scr: Issue a scr to an node on a vport. | ||
2019 | * @vport: pointer to a host virtual N_Port data structure. | ||
2020 | * @nportid: N_Port identifier to the remote node. | ||
2021 | * @retry: number of retries to the command IOCB. | ||
2022 | * | ||
2023 | * This routine issues a State Change Request (SCR) to a fabric node | ||
2024 | * on a @vport. The remote node @nportid is passed into the function. It | ||
2025 | * first search the @vport node list to find the matching ndlp. If no such | ||
2026 | * ndlp is found, a new ndlp shall be created for this (SCR) purpose. An | ||
2027 | * IOCB is allocated, payload prepared, and the lpfc_sli_issue_iocb() | ||
2028 | * routine is invoked to send the SCR IOCB. | ||
2029 | * | ||
2030 | * Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp | ||
2031 | * will be incremented by 1 for holding the ndlp and the reference to ndlp | ||
2032 | * will be stored into the context1 field of the IOCB for the completion | ||
2033 | * callback function to the SCR ELS command. | ||
2034 | * | ||
2035 | * Return code | ||
2036 | * 0 - Successfully issued scr command | ||
2037 | * 1 - Failed to issue scr command | ||
2038 | **/ | ||
1590 | int | 2039 | int |
1591 | lpfc_issue_els_scr(struct lpfc_vport *vport, uint32_t nportid, uint8_t retry) | 2040 | lpfc_issue_els_scr(struct lpfc_vport *vport, uint32_t nportid, uint8_t retry) |
1592 | { | 2041 | { |
@@ -1659,6 +2108,28 @@ lpfc_issue_els_scr(struct lpfc_vport *vport, uint32_t nportid, uint8_t retry) | |||
1659 | return 0; | 2108 | return 0; |
1660 | } | 2109 | } |
1661 | 2110 | ||
2111 | /** | ||
2112 | * lpfc_issue_els_farpr: Issue a farp to an node on a vport. | ||
2113 | * @vport: pointer to a host virtual N_Port data structure. | ||
2114 | * @nportid: N_Port identifier to the remote node. | ||
2115 | * @retry: number of retries to the command IOCB. | ||
2116 | * | ||
2117 | * This routine issues a Fibre Channel Address Resolution Response | ||
2118 | * (FARPR) to a node on a vport. The remote node N_Port identifier (@nportid) | ||
2119 | * is passed into the function. It first search the @vport node list to find | ||
2120 | * the matching ndlp. If no such ndlp is found, a new ndlp shall be created | ||
2121 | * for this (FARPR) purpose. An IOCB is allocated, payload prepared, and the | ||
2122 | * lpfc_sli_issue_iocb() routine is invoked to send the FARPR ELS command. | ||
2123 | * | ||
2124 | * Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp | ||
2125 | * will be incremented by 1 for holding the ndlp and the reference to ndlp | ||
2126 | * will be stored into the context1 field of the IOCB for the completion | ||
2127 | * callback function to the PARPR ELS command. | ||
2128 | * | ||
2129 | * Return code | ||
2130 | * 0 - Successfully issued farpr command | ||
2131 | * 1 - Failed to issue farpr command | ||
2132 | **/ | ||
1662 | static int | 2133 | static int |
1663 | lpfc_issue_els_farpr(struct lpfc_vport *vport, uint32_t nportid, uint8_t retry) | 2134 | lpfc_issue_els_farpr(struct lpfc_vport *vport, uint32_t nportid, uint8_t retry) |
1664 | { | 2135 | { |
@@ -1748,6 +2219,18 @@ lpfc_issue_els_farpr(struct lpfc_vport *vport, uint32_t nportid, uint8_t retry) | |||
1748 | return 0; | 2219 | return 0; |
1749 | } | 2220 | } |
1750 | 2221 | ||
2222 | /** | ||
2223 | * lpfc_cancel_retry_delay_tmo: Cancel the timer with delayed iocb-cmd retry. | ||
2224 | * @vport: pointer to a host virtual N_Port data structure. | ||
2225 | * @nlp: pointer to a node-list data structure. | ||
2226 | * | ||
2227 | * This routine cancels the timer with a delayed IOCB-command retry for | ||
2228 | * a @vport's @ndlp. It stops the timer for the delayed function retrial and | ||
2229 | * removes the ELS retry event if it presents. In addition, if the | ||
2230 | * NLP_NPR_2B_DISC bit is set in the @nlp's nlp_flag bitmap, ADISC IOCB | ||
2231 | * commands are sent for the @vport's nodes that require issuing discovery | ||
2232 | * ADISC. | ||
2233 | **/ | ||
1751 | void | 2234 | void |
1752 | lpfc_cancel_retry_delay_tmo(struct lpfc_vport *vport, struct lpfc_nodelist *nlp) | 2235 | lpfc_cancel_retry_delay_tmo(struct lpfc_vport *vport, struct lpfc_nodelist *nlp) |
1753 | { | 2236 | { |
@@ -1794,6 +2277,20 @@ lpfc_cancel_retry_delay_tmo(struct lpfc_vport *vport, struct lpfc_nodelist *nlp) | |||
1794 | return; | 2277 | return; |
1795 | } | 2278 | } |
1796 | 2279 | ||
2280 | /** | ||
2281 | * lpfc_els_retry_delay: Timer function with a ndlp delayed function timer. | ||
2282 | * @ptr: holder for the pointer to the timer function associated data (ndlp). | ||
2283 | * | ||
2284 | * This routine is invoked by the ndlp delayed-function timer to check | ||
2285 | * whether there is any pending ELS retry event(s) with the node. If not, it | ||
2286 | * simply returns. Otherwise, if there is at least one ELS delayed event, it | ||
2287 | * adds the delayed events to the HBA work list and invokes the | ||
2288 | * lpfc_worker_wake_up() routine to wake up worker thread to process the | ||
2289 | * event. Note that lpfc_nlp_get() is called before posting the event to | ||
2290 | * the work list to hold reference count of ndlp so that it guarantees the | ||
2291 | * reference to ndlp will still be available when the worker thread gets | ||
2292 | * to the event associated with the ndlp. | ||
2293 | **/ | ||
1797 | void | 2294 | void |
1798 | lpfc_els_retry_delay(unsigned long ptr) | 2295 | lpfc_els_retry_delay(unsigned long ptr) |
1799 | { | 2296 | { |
@@ -1822,6 +2319,15 @@ lpfc_els_retry_delay(unsigned long ptr) | |||
1822 | return; | 2319 | return; |
1823 | } | 2320 | } |
1824 | 2321 | ||
2322 | /** | ||
2323 | * lpfc_els_retry_delay_handler: Work thread handler for ndlp delayed function. | ||
2324 | * @ndlp: pointer to a node-list data structure. | ||
2325 | * | ||
2326 | * This routine is the worker-thread handler for processing the @ndlp delayed | ||
2327 | * event(s), posted by the lpfc_els_retry_delay() routine. It simply retrieves | ||
2328 | * the last ELS command from the associated ndlp and invokes the proper ELS | ||
2329 | * function according to the delayed ELS command to retry the command. | ||
2330 | **/ | ||
1825 | void | 2331 | void |
1826 | lpfc_els_retry_delay_handler(struct lpfc_nodelist *ndlp) | 2332 | lpfc_els_retry_delay_handler(struct lpfc_nodelist *ndlp) |
1827 | { | 2333 | { |
@@ -1884,6 +2390,27 @@ lpfc_els_retry_delay_handler(struct lpfc_nodelist *ndlp) | |||
1884 | return; | 2390 | return; |
1885 | } | 2391 | } |
1886 | 2392 | ||
2393 | /** | ||
2394 | * lpfc_els_retry: Make retry decision on an els command iocb. | ||
2395 | * @phba: pointer to lpfc hba data structure. | ||
2396 | * @cmdiocb: pointer to lpfc command iocb data structure. | ||
2397 | * @rspiocb: pointer to lpfc response iocb data structure. | ||
2398 | * | ||
2399 | * This routine makes a retry decision on an ELS command IOCB, which has | ||
2400 | * failed. The following ELS IOCBs use this function for retrying the command | ||
2401 | * when previously issued command responsed with error status: FLOGI, PLOGI, | ||
2402 | * PRLI, ADISC, LOGO, and FDISC. Based on the ELS command type and the | ||
2403 | * returned error status, it makes the decision whether a retry shall be | ||
2404 | * issued for the command, and whether a retry shall be made immediately or | ||
2405 | * delayed. In the former case, the corresponding ELS command issuing-function | ||
2406 | * is called to retry the command. In the later case, the ELS command shall | ||
2407 | * be posted to the ndlp delayed event and delayed function timer set to the | ||
2408 | * ndlp for the delayed command issusing. | ||
2409 | * | ||
2410 | * Return code | ||
2411 | * 0 - No retry of els command is made | ||
2412 | * 1 - Immediate or delayed retry of els command is made | ||
2413 | **/ | ||
1887 | static int | 2414 | static int |
1888 | lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | 2415 | lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, |
1889 | struct lpfc_iocbq *rspiocb) | 2416 | struct lpfc_iocbq *rspiocb) |
@@ -2182,12 +2709,26 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
2182 | return 0; | 2709 | return 0; |
2183 | } | 2710 | } |
2184 | 2711 | ||
2712 | /** | ||
2713 | * lpfc_els_free_data: Free lpfc dma buffer and data structure with an iocb. | ||
2714 | * @phba: pointer to lpfc hba data structure. | ||
2715 | * @buf_ptr1: pointer to the lpfc DMA buffer data structure. | ||
2716 | * | ||
2717 | * This routine releases the lpfc DMA (Direct Memory Access) buffer(s) | ||
2718 | * associated with a command IOCB back to the lpfc DMA buffer pool. It first | ||
2719 | * checks to see whether there is a lpfc DMA buffer associated with the | ||
2720 | * response of the command IOCB. If so, it will be released before releasing | ||
2721 | * the lpfc DMA buffer associated with the IOCB itself. | ||
2722 | * | ||
2723 | * Return code | ||
2724 | * 0 - Successfully released lpfc DMA buffer (currently, always return 0) | ||
2725 | **/ | ||
2185 | static int | 2726 | static int |
2186 | lpfc_els_free_data(struct lpfc_hba *phba, struct lpfc_dmabuf *buf_ptr1) | 2727 | lpfc_els_free_data(struct lpfc_hba *phba, struct lpfc_dmabuf *buf_ptr1) |
2187 | { | 2728 | { |
2188 | struct lpfc_dmabuf *buf_ptr; | 2729 | struct lpfc_dmabuf *buf_ptr; |
2189 | 2730 | ||
2190 | /* Free the response before processing the command. */ | 2731 | /* Free the response before processing the command. */ |
2191 | if (!list_empty(&buf_ptr1->list)) { | 2732 | if (!list_empty(&buf_ptr1->list)) { |
2192 | list_remove_head(&buf_ptr1->list, buf_ptr, | 2733 | list_remove_head(&buf_ptr1->list, buf_ptr, |
2193 | struct lpfc_dmabuf, | 2734 | struct lpfc_dmabuf, |
@@ -2200,6 +2741,18 @@ lpfc_els_free_data(struct lpfc_hba *phba, struct lpfc_dmabuf *buf_ptr1) | |||
2200 | return 0; | 2741 | return 0; |
2201 | } | 2742 | } |
2202 | 2743 | ||
2744 | /** | ||
2745 | * lpfc_els_free_bpl: Free lpfc dma buffer and data structure with bpl. | ||
2746 | * @phba: pointer to lpfc hba data structure. | ||
2747 | * @buf_ptr: pointer to the lpfc dma buffer data structure. | ||
2748 | * | ||
2749 | * This routine releases the lpfc Direct Memory Access (DMA) buffer | ||
2750 | * associated with a Buffer Pointer List (BPL) back to the lpfc DMA buffer | ||
2751 | * pool. | ||
2752 | * | ||
2753 | * Return code | ||
2754 | * 0 - Successfully released lpfc DMA buffer (currently, always return 0) | ||
2755 | **/ | ||
2203 | static int | 2756 | static int |
2204 | lpfc_els_free_bpl(struct lpfc_hba *phba, struct lpfc_dmabuf *buf_ptr) | 2757 | lpfc_els_free_bpl(struct lpfc_hba *phba, struct lpfc_dmabuf *buf_ptr) |
2205 | { | 2758 | { |
@@ -2208,6 +2761,33 @@ lpfc_els_free_bpl(struct lpfc_hba *phba, struct lpfc_dmabuf *buf_ptr) | |||
2208 | return 0; | 2761 | return 0; |
2209 | } | 2762 | } |
2210 | 2763 | ||
2764 | /** | ||
2765 | * lpfc_els_free_iocb: Free a command iocb and its associated resources. | ||
2766 | * @phba: pointer to lpfc hba data structure. | ||
2767 | * @elsiocb: pointer to lpfc els command iocb data structure. | ||
2768 | * | ||
2769 | * This routine frees a command IOCB and its associated resources. The | ||
2770 | * command IOCB data structure contains the reference to various associated | ||
2771 | * resources, these fields must be set to NULL if the associated reference | ||
2772 | * not present: | ||
2773 | * context1 - reference to ndlp | ||
2774 | * context2 - reference to cmd | ||
2775 | * context2->next - reference to rsp | ||
2776 | * context3 - reference to bpl | ||
2777 | * | ||
2778 | * It first properly decrements the reference count held on ndlp for the | ||
2779 | * IOCB completion callback function. If LPFC_DELAY_MEM_FREE flag is not | ||
2780 | * set, it invokes the lpfc_els_free_data() routine to release the Direct | ||
2781 | * Memory Access (DMA) buffers associated with the IOCB. Otherwise, it | ||
2782 | * adds the DMA buffer the @phba data structure for the delayed release. | ||
2783 | * If reference to the Buffer Pointer List (BPL) is present, the | ||
2784 | * lpfc_els_free_bpl() routine is invoked to release the DMA memory | ||
2785 | * associated with BPL. Finally, the lpfc_sli_release_iocbq() routine is | ||
2786 | * invoked to release the IOCB data structure back to @phba IOCBQ list. | ||
2787 | * | ||
2788 | * Return code | ||
2789 | * 0 - Success (currently, always return 0) | ||
2790 | **/ | ||
2211 | int | 2791 | int |
2212 | lpfc_els_free_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *elsiocb) | 2792 | lpfc_els_free_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *elsiocb) |
2213 | { | 2793 | { |
@@ -2274,6 +2854,23 @@ lpfc_els_free_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *elsiocb) | |||
2274 | return 0; | 2854 | return 0; |
2275 | } | 2855 | } |
2276 | 2856 | ||
2857 | /** | ||
2858 | * lpfc_cmpl_els_logo_acc: Completion callback function to logo acc response. | ||
2859 | * @phba: pointer to lpfc hba data structure. | ||
2860 | * @cmdiocb: pointer to lpfc command iocb data structure. | ||
2861 | * @rspiocb: pointer to lpfc response iocb data structure. | ||
2862 | * | ||
2863 | * This routine is the completion callback function to the Logout (LOGO) | ||
2864 | * Accept (ACC) Response ELS command. This routine is invoked to indicate | ||
2865 | * the completion of the LOGO process. It invokes the lpfc_nlp_not_used() to | ||
2866 | * release the ndlp if it has the last reference remaining (reference count | ||
2867 | * is 1). If succeeded (meaning ndlp released), it sets the IOCB context1 | ||
2868 | * field to NULL to inform the following lpfc_els_free_iocb() routine no | ||
2869 | * ndlp reference count needs to be decremented. Otherwise, the ndlp | ||
2870 | * reference use-count shall be decremented by the lpfc_els_free_iocb() | ||
2871 | * routine. Finally, the lpfc_els_free_iocb() is invoked to release the | ||
2872 | * IOCB data structure. | ||
2873 | **/ | ||
2277 | static void | 2874 | static void |
2278 | lpfc_cmpl_els_logo_acc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | 2875 | lpfc_cmpl_els_logo_acc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, |
2279 | struct lpfc_iocbq *rspiocb) | 2876 | struct lpfc_iocbq *rspiocb) |
@@ -2311,6 +2908,19 @@ lpfc_cmpl_els_logo_acc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
2311 | return; | 2908 | return; |
2312 | } | 2909 | } |
2313 | 2910 | ||
2911 | /** | ||
2912 | * lpfc_mbx_cmpl_dflt_rpi: Completion callbk func for unreg dflt rpi mbox cmd. | ||
2913 | * @phba: pointer to lpfc hba data structure. | ||
2914 | * @pmb: pointer to the driver internal queue element for mailbox command. | ||
2915 | * | ||
2916 | * This routine is the completion callback function for unregister default | ||
2917 | * RPI (Remote Port Index) mailbox command to the @phba. It simply releases | ||
2918 | * the associated lpfc Direct Memory Access (DMA) buffer back to the pool and | ||
2919 | * decrements the ndlp reference count held for this completion callback | ||
2920 | * function. After that, it invokes the lpfc_nlp_not_used() to check | ||
2921 | * whether there is only one reference left on the ndlp. If so, it will | ||
2922 | * perform one more decrement and trigger the release of the ndlp. | ||
2923 | **/ | ||
2314 | void | 2924 | void |
2315 | lpfc_mbx_cmpl_dflt_rpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | 2925 | lpfc_mbx_cmpl_dflt_rpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) |
2316 | { | 2926 | { |
@@ -2332,6 +2942,22 @@ lpfc_mbx_cmpl_dflt_rpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
2332 | return; | 2942 | return; |
2333 | } | 2943 | } |
2334 | 2944 | ||
2945 | /** | ||
2946 | * lpfc_cmpl_els_rsp: Completion callback function for els response iocb cmd. | ||
2947 | * @phba: pointer to lpfc hba data structure. | ||
2948 | * @cmdiocb: pointer to lpfc command iocb data structure. | ||
2949 | * @rspiocb: pointer to lpfc response iocb data structure. | ||
2950 | * | ||
2951 | * This routine is the completion callback function for ELS Response IOCB | ||
2952 | * command. In normal case, this callback function just properly sets the | ||
2953 | * nlp_flag bitmap in the ndlp data structure, if the mbox command reference | ||
2954 | * field in the command IOCB is not NULL, the referred mailbox command will | ||
2955 | * be send out, and then invokes the lpfc_els_free_iocb() routine to release | ||
2956 | * the IOCB. Under error conditions, such as when a LS_RJT is returned or a | ||
2957 | * link down event occurred during the discovery, the lpfc_nlp_not_used() | ||
2958 | * routine shall be invoked trying to release the ndlp if no other threads | ||
2959 | * are currently referring it. | ||
2960 | **/ | ||
2335 | static void | 2961 | static void |
2336 | lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | 2962 | lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, |
2337 | struct lpfc_iocbq *rspiocb) | 2963 | struct lpfc_iocbq *rspiocb) |
@@ -2487,6 +3113,31 @@ out: | |||
2487 | return; | 3113 | return; |
2488 | } | 3114 | } |
2489 | 3115 | ||
3116 | /** | ||
3117 | * lpfc_els_rsp_acc: Prepare and issue an acc response iocb command. | ||
3118 | * @vport: pointer to a host virtual N_Port data structure. | ||
3119 | * @flag: the els command code to be accepted. | ||
3120 | * @oldiocb: pointer to the original lpfc command iocb data structure. | ||
3121 | * @ndlp: pointer to a node-list data structure. | ||
3122 | * @mbox: pointer to the driver internal queue element for mailbox command. | ||
3123 | * | ||
3124 | * This routine prepares and issues an Accept (ACC) response IOCB | ||
3125 | * command. It uses the @flag to properly set up the IOCB field for the | ||
3126 | * specific ACC response command to be issued and invokes the | ||
3127 | * lpfc_sli_issue_iocb() routine to send out ACC response IOCB. If a | ||
3128 | * @mbox pointer is passed in, it will be put into the context_un.mbox | ||
3129 | * field of the IOCB for the completion callback function to issue the | ||
3130 | * mailbox command to the HBA later when callback is invoked. | ||
3131 | * | ||
3132 | * Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp | ||
3133 | * will be incremented by 1 for holding the ndlp and the reference to ndlp | ||
3134 | * will be stored into the context1 field of the IOCB for the completion | ||
3135 | * callback function to the corresponding response ELS IOCB command. | ||
3136 | * | ||
3137 | * Return code | ||
3138 | * 0 - Successfully issued acc response | ||
3139 | * 1 - Failed to issue acc response | ||
3140 | **/ | ||
2490 | int | 3141 | int |
2491 | lpfc_els_rsp_acc(struct lpfc_vport *vport, uint32_t flag, | 3142 | lpfc_els_rsp_acc(struct lpfc_vport *vport, uint32_t flag, |
2492 | struct lpfc_iocbq *oldiocb, struct lpfc_nodelist *ndlp, | 3143 | struct lpfc_iocbq *oldiocb, struct lpfc_nodelist *ndlp, |
@@ -2601,6 +3252,28 @@ lpfc_els_rsp_acc(struct lpfc_vport *vport, uint32_t flag, | |||
2601 | return 0; | 3252 | return 0; |
2602 | } | 3253 | } |
2603 | 3254 | ||
3255 | /** | ||
3256 | * lpfc_els_rsp_reject: Propare and issue a rjt response iocb command. | ||
3257 | * @vport: pointer to a virtual N_Port data structure. | ||
3258 | * @rejectError: | ||
3259 | * @oldiocb: pointer to the original lpfc command iocb data structure. | ||
3260 | * @ndlp: pointer to a node-list data structure. | ||
3261 | * @mbox: pointer to the driver internal queue element for mailbox command. | ||
3262 | * | ||
3263 | * This routine prepares and issue an Reject (RJT) response IOCB | ||
3264 | * command. If a @mbox pointer is passed in, it will be put into the | ||
3265 | * context_un.mbox field of the IOCB for the completion callback function | ||
3266 | * to issue to the HBA later. | ||
3267 | * | ||
3268 | * Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp | ||
3269 | * will be incremented by 1 for holding the ndlp and the reference to ndlp | ||
3270 | * will be stored into the context1 field of the IOCB for the completion | ||
3271 | * callback function to the reject response ELS IOCB command. | ||
3272 | * | ||
3273 | * Return code | ||
3274 | * 0 - Successfully issued reject response | ||
3275 | * 1 - Failed to issue reject response | ||
3276 | **/ | ||
2604 | int | 3277 | int |
2605 | lpfc_els_rsp_reject(struct lpfc_vport *vport, uint32_t rejectError, | 3278 | lpfc_els_rsp_reject(struct lpfc_vport *vport, uint32_t rejectError, |
2606 | struct lpfc_iocbq *oldiocb, struct lpfc_nodelist *ndlp, | 3279 | struct lpfc_iocbq *oldiocb, struct lpfc_nodelist *ndlp, |
@@ -2660,6 +3333,25 @@ lpfc_els_rsp_reject(struct lpfc_vport *vport, uint32_t rejectError, | |||
2660 | return 0; | 3333 | return 0; |
2661 | } | 3334 | } |
2662 | 3335 | ||
3336 | /** | ||
3337 | * lpfc_els_rsp_adisc_acc: Prepare and issue acc response to adisc iocb cmd. | ||
3338 | * @vport: pointer to a virtual N_Port data structure. | ||
3339 | * @oldiocb: pointer to the original lpfc command iocb data structure. | ||
3340 | * @ndlp: pointer to a node-list data structure. | ||
3341 | * | ||
3342 | * This routine prepares and issues an Accept (ACC) response to Address | ||
3343 | * Discover (ADISC) ELS command. It simply prepares the payload of the IOCB | ||
3344 | * and invokes the lpfc_sli_issue_iocb() routine to send out the command. | ||
3345 | * | ||
3346 | * Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp | ||
3347 | * will be incremented by 1 for holding the ndlp and the reference to ndlp | ||
3348 | * will be stored into the context1 field of the IOCB for the completion | ||
3349 | * callback function to the ADISC Accept response ELS IOCB command. | ||
3350 | * | ||
3351 | * Return code | ||
3352 | * 0 - Successfully issued acc adisc response | ||
3353 | * 1 - Failed to issue adisc acc response | ||
3354 | **/ | ||
2663 | int | 3355 | int |
2664 | lpfc_els_rsp_adisc_acc(struct lpfc_vport *vport, struct lpfc_iocbq *oldiocb, | 3356 | lpfc_els_rsp_adisc_acc(struct lpfc_vport *vport, struct lpfc_iocbq *oldiocb, |
2665 | struct lpfc_nodelist *ndlp) | 3357 | struct lpfc_nodelist *ndlp) |
@@ -2716,6 +3408,25 @@ lpfc_els_rsp_adisc_acc(struct lpfc_vport *vport, struct lpfc_iocbq *oldiocb, | |||
2716 | return 0; | 3408 | return 0; |
2717 | } | 3409 | } |
2718 | 3410 | ||
3411 | /** | ||
3412 | * lpfc_els_rsp_prli_acc: Prepare and issue acc response to prli iocb cmd. | ||
3413 | * @vport: pointer to a virtual N_Port data structure. | ||
3414 | * @oldiocb: pointer to the original lpfc command iocb data structure. | ||
3415 | * @ndlp: pointer to a node-list data structure. | ||
3416 | * | ||
3417 | * This routine prepares and issues an Accept (ACC) response to Process | ||
3418 | * Login (PRLI) ELS command. It simply prepares the payload of the IOCB | ||
3419 | * and invokes the lpfc_sli_issue_iocb() routine to send out the command. | ||
3420 | * | ||
3421 | * Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp | ||
3422 | * will be incremented by 1 for holding the ndlp and the reference to ndlp | ||
3423 | * will be stored into the context1 field of the IOCB for the completion | ||
3424 | * callback function to the PRLI Accept response ELS IOCB command. | ||
3425 | * | ||
3426 | * Return code | ||
3427 | * 0 - Successfully issued acc prli response | ||
3428 | * 1 - Failed to issue acc prli response | ||
3429 | **/ | ||
2719 | int | 3430 | int |
2720 | lpfc_els_rsp_prli_acc(struct lpfc_vport *vport, struct lpfc_iocbq *oldiocb, | 3431 | lpfc_els_rsp_prli_acc(struct lpfc_vport *vport, struct lpfc_iocbq *oldiocb, |
2721 | struct lpfc_nodelist *ndlp) | 3432 | struct lpfc_nodelist *ndlp) |
@@ -2795,6 +3506,32 @@ lpfc_els_rsp_prli_acc(struct lpfc_vport *vport, struct lpfc_iocbq *oldiocb, | |||
2795 | return 0; | 3506 | return 0; |
2796 | } | 3507 | } |
2797 | 3508 | ||
3509 | /** | ||
3510 | * lpfc_els_rsp_rnid_acc: Issue rnid acc response iocb command. | ||
3511 | * @vport: pointer to a virtual N_Port data structure. | ||
3512 | * @format: rnid command format. | ||
3513 | * @oldiocb: pointer to the original lpfc command iocb data structure. | ||
3514 | * @ndlp: pointer to a node-list data structure. | ||
3515 | * | ||
3516 | * This routine issues a Request Node Identification Data (RNID) Accept | ||
3517 | * (ACC) response. It constructs the RNID ACC response command according to | ||
3518 | * the proper @format and then calls the lpfc_sli_issue_iocb() routine to | ||
3519 | * issue the response. Note that this command does not need to hold the ndlp | ||
3520 | * reference count for the callback. So, the ndlp reference count taken by | ||
3521 | * the lpfc_prep_els_iocb() routine is put back and the context1 field of | ||
3522 | * IOCB is set to NULL to indicate to the lpfc_els_free_iocb() routine that | ||
3523 | * there is no ndlp reference available. | ||
3524 | * | ||
3525 | * Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp | ||
3526 | * will be incremented by 1 for holding the ndlp and the reference to ndlp | ||
3527 | * will be stored into the context1 field of the IOCB for the completion | ||
3528 | * callback function. However, for the RNID Accept Response ELS command, | ||
3529 | * this is undone later by this routine after the IOCB is allocated. | ||
3530 | * | ||
3531 | * Return code | ||
3532 | * 0 - Successfully issued acc rnid response | ||
3533 | * 1 - Failed to issue acc rnid response | ||
3534 | **/ | ||
2798 | static int | 3535 | static int |
2799 | lpfc_els_rsp_rnid_acc(struct lpfc_vport *vport, uint8_t format, | 3536 | lpfc_els_rsp_rnid_acc(struct lpfc_vport *vport, uint8_t format, |
2800 | struct lpfc_iocbq *oldiocb, struct lpfc_nodelist *ndlp) | 3537 | struct lpfc_iocbq *oldiocb, struct lpfc_nodelist *ndlp) |
@@ -2875,6 +3612,25 @@ lpfc_els_rsp_rnid_acc(struct lpfc_vport *vport, uint8_t format, | |||
2875 | return 0; | 3612 | return 0; |
2876 | } | 3613 | } |
2877 | 3614 | ||
3615 | /** | ||
3616 | * lpfc_els_disc_adisc: Issue remaining adisc iocbs to npr nodes of a vport. | ||
3617 | * @vport: pointer to a host virtual N_Port data structure. | ||
3618 | * | ||
3619 | * This routine issues Address Discover (ADISC) ELS commands to those | ||
3620 | * N_Ports which are in node port recovery state and ADISC has not been issued | ||
3621 | * for the @vport. Each time an ELS ADISC IOCB is issued by invoking the | ||
3622 | * lpfc_issue_els_adisc() routine, the per @vport number of discover count | ||
3623 | * (num_disc_nodes) shall be incremented. If the num_disc_nodes reaches a | ||
3624 | * pre-configured threshold (cfg_discovery_threads), the @vport fc_flag will | ||
3625 | * be marked with FC_NLP_MORE bit and the process of issuing remaining ADISC | ||
3626 | * IOCBs quit for later pick up. On the other hand, after walking through | ||
3627 | * all the ndlps with the @vport and there is none ADISC IOCB issued, the | ||
3628 | * @vport fc_flag shall be cleared with FC_NLP_MORE bit indicating there is | ||
3629 | * no more ADISC need to be sent. | ||
3630 | * | ||
3631 | * Return code | ||
3632 | * The number of N_Ports with adisc issued. | ||
3633 | **/ | ||
2878 | int | 3634 | int |
2879 | lpfc_els_disc_adisc(struct lpfc_vport *vport) | 3635 | lpfc_els_disc_adisc(struct lpfc_vport *vport) |
2880 | { | 3636 | { |
@@ -2914,6 +3670,25 @@ lpfc_els_disc_adisc(struct lpfc_vport *vport) | |||
2914 | return sentadisc; | 3670 | return sentadisc; |
2915 | } | 3671 | } |
2916 | 3672 | ||
3673 | /** | ||
3674 | * lpfc_els_disc_plogi: Issue plogi for all npr nodes of a vport before adisc. | ||
3675 | * @vport: pointer to a host virtual N_Port data structure. | ||
3676 | * | ||
3677 | * This routine issues Port Login (PLOGI) ELS commands to all the N_Ports | ||
3678 | * which are in node port recovery state, with a @vport. Each time an ELS | ||
3679 | * ADISC PLOGI IOCB is issued by invoking the lpfc_issue_els_plogi() routine, | ||
3680 | * the per @vport number of discover count (num_disc_nodes) shall be | ||
3681 | * incremented. If the num_disc_nodes reaches a pre-configured threshold | ||
3682 | * (cfg_discovery_threads), the @vport fc_flag will be marked with FC_NLP_MORE | ||
3683 | * bit set and quit the process of issuing remaining ADISC PLOGIN IOCBs for | ||
3684 | * later pick up. On the other hand, after walking through all the ndlps with | ||
3685 | * the @vport and there is none ADISC PLOGI IOCB issued, the @vport fc_flag | ||
3686 | * shall be cleared with the FC_NLP_MORE bit indicating there is no more ADISC | ||
3687 | * PLOGI need to be sent. | ||
3688 | * | ||
3689 | * Return code | ||
3690 | * The number of N_Ports with plogi issued. | ||
3691 | **/ | ||
2917 | int | 3692 | int |
2918 | lpfc_els_disc_plogi(struct lpfc_vport *vport) | 3693 | lpfc_els_disc_plogi(struct lpfc_vport *vport) |
2919 | { | 3694 | { |
@@ -2954,6 +3729,15 @@ lpfc_els_disc_plogi(struct lpfc_vport *vport) | |||
2954 | return sentplogi; | 3729 | return sentplogi; |
2955 | } | 3730 | } |
2956 | 3731 | ||
3732 | /** | ||
3733 | * lpfc_els_flush_rscn: Clean up any rscn activities with a vport. | ||
3734 | * @vport: pointer to a host virtual N_Port data structure. | ||
3735 | * | ||
3736 | * This routine cleans up any Registration State Change Notification | ||
3737 | * (RSCN) activity with a @vport. Note that the fc_rscn_flush flag of the | ||
3738 | * @vport together with the host_lock is used to prevent multiple thread | ||
3739 | * trying to access the RSCN array on a same @vport at the same time. | ||
3740 | **/ | ||
2957 | void | 3741 | void |
2958 | lpfc_els_flush_rscn(struct lpfc_vport *vport) | 3742 | lpfc_els_flush_rscn(struct lpfc_vport *vport) |
2959 | { | 3743 | { |
@@ -2984,6 +3768,18 @@ lpfc_els_flush_rscn(struct lpfc_vport *vport) | |||
2984 | vport->fc_rscn_flush = 0; | 3768 | vport->fc_rscn_flush = 0; |
2985 | } | 3769 | } |
2986 | 3770 | ||
3771 | /** | ||
3772 | * lpfc_rscn_payload_check: Check whether there is a pending rscn to a did. | ||
3773 | * @vport: pointer to a host virtual N_Port data structure. | ||
3774 | * @did: remote destination port identifier. | ||
3775 | * | ||
3776 | * This routine checks whether there is any pending Registration State | ||
3777 | * Configuration Notification (RSCN) to a @did on @vport. | ||
3778 | * | ||
3779 | * Return code | ||
3780 | * None zero - The @did matched with a pending rscn | ||
3781 | * 0 - not able to match @did with a pending rscn | ||
3782 | **/ | ||
2987 | int | 3783 | int |
2988 | lpfc_rscn_payload_check(struct lpfc_vport *vport, uint32_t did) | 3784 | lpfc_rscn_payload_check(struct lpfc_vport *vport, uint32_t did) |
2989 | { | 3785 | { |
@@ -3053,6 +3849,17 @@ return_did_out: | |||
3053 | return did; | 3849 | return did; |
3054 | } | 3850 | } |
3055 | 3851 | ||
3852 | /** | ||
3853 | * lpfc_rscn_recovery_check: Send recovery event to vport nodes matching rscn | ||
3854 | * @vport: pointer to a host virtual N_Port data structure. | ||
3855 | * | ||
3856 | * This routine sends recovery (NLP_EVT_DEVICE_RECOVERY) event to the | ||
3857 | * state machine for a @vport's nodes that are with pending RSCN (Registration | ||
3858 | * State Change Notification). | ||
3859 | * | ||
3860 | * Return code | ||
3861 | * 0 - Successful (currently alway return 0) | ||
3862 | **/ | ||
3056 | static int | 3863 | static int |
3057 | lpfc_rscn_recovery_check(struct lpfc_vport *vport) | 3864 | lpfc_rscn_recovery_check(struct lpfc_vport *vport) |
3058 | { | 3865 | { |
@@ -3071,6 +3878,28 @@ lpfc_rscn_recovery_check(struct lpfc_vport *vport) | |||
3071 | return 0; | 3878 | return 0; |
3072 | } | 3879 | } |
3073 | 3880 | ||
3881 | /** | ||
3882 | * lpfc_els_rcv_rscn: Process an unsolicited rscn iocb. | ||
3883 | * @vport: pointer to a host virtual N_Port data structure. | ||
3884 | * @cmdiocb: pointer to lpfc command iocb data structure. | ||
3885 | * @ndlp: pointer to a node-list data structure. | ||
3886 | * | ||
3887 | * This routine processes an unsolicited RSCN (Registration State Change | ||
3888 | * Notification) IOCB. First, the payload of the unsolicited RSCN is walked | ||
3889 | * to invoke fc_host_post_event() routine to the FC transport layer. If the | ||
3890 | * discover state machine is about to begin discovery, it just accepts the | ||
3891 | * RSCN and the discovery process will satisfy the RSCN. If this RSCN only | ||
3892 | * contains N_Port IDs for other vports on this HBA, it just accepts the | ||
3893 | * RSCN and ignore processing it. If the state machine is in the recovery | ||
3894 | * state, the fc_rscn_id_list of this @vport is walked and the | ||
3895 | * lpfc_rscn_recovery_check() routine is invoked to send recovery event for | ||
3896 | * all nodes that match RSCN payload. Otherwise, the lpfc_els_handle_rscn() | ||
3897 | * routine is invoked to handle the RSCN event. | ||
3898 | * | ||
3899 | * Return code | ||
3900 | * 0 - Just sent the acc response | ||
3901 | * 1 - Sent the acc response and waited for name server completion | ||
3902 | **/ | ||
3074 | static int | 3903 | static int |
3075 | lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, | 3904 | lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, |
3076 | struct lpfc_nodelist *ndlp) | 3905 | struct lpfc_nodelist *ndlp) |
@@ -3241,6 +4070,22 @@ lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, | |||
3241 | return lpfc_els_handle_rscn(vport); | 4070 | return lpfc_els_handle_rscn(vport); |
3242 | } | 4071 | } |
3243 | 4072 | ||
4073 | /** | ||
4074 | * lpfc_els_handle_rscn: Handle rscn for a vport. | ||
4075 | * @vport: pointer to a host virtual N_Port data structure. | ||
4076 | * | ||
4077 | * This routine handles the Registration State Configuration Notification | ||
4078 | * (RSCN) for a @vport. If login to NameServer does not exist, a new ndlp shall | ||
4079 | * be created and a Port Login (PLOGI) to the NameServer is issued. Otherwise, | ||
4080 | * if the ndlp to NameServer exists, a Common Transport (CT) command to the | ||
4081 | * NameServer shall be issued. If CT command to the NameServer fails to be | ||
4082 | * issued, the lpfc_els_flush_rscn() routine shall be invoked to clean up any | ||
4083 | * RSCN activities with the @vport. | ||
4084 | * | ||
4085 | * Return code | ||
4086 | * 0 - Cleaned up rscn on the @vport | ||
4087 | * 1 - Wait for plogi to name server before proceed | ||
4088 | **/ | ||
3244 | int | 4089 | int |
3245 | lpfc_els_handle_rscn(struct lpfc_vport *vport) | 4090 | lpfc_els_handle_rscn(struct lpfc_vport *vport) |
3246 | { | 4091 | { |
@@ -3313,6 +4158,31 @@ lpfc_els_handle_rscn(struct lpfc_vport *vport) | |||
3313 | return 0; | 4158 | return 0; |
3314 | } | 4159 | } |
3315 | 4160 | ||
4161 | /** | ||
4162 | * lpfc_els_rcv_flogi: Process an unsolicited flogi iocb. | ||
4163 | * @vport: pointer to a host virtual N_Port data structure. | ||
4164 | * @cmdiocb: pointer to lpfc command iocb data structure. | ||
4165 | * @ndlp: pointer to a node-list data structure. | ||
4166 | * | ||
4167 | * This routine processes Fabric Login (FLOGI) IOCB received as an ELS | ||
4168 | * unsolicited event. An unsolicited FLOGI can be received in a point-to- | ||
4169 | * point topology. As an unsolicited FLOGI should not be received in a loop | ||
4170 | * mode, any unsolicited FLOGI received in loop mode shall be ignored. The | ||
4171 | * lpfc_check_sparm() routine is invoked to check the parameters in the | ||
4172 | * unsolicited FLOGI. If parameters validation failed, the routine | ||
4173 | * lpfc_els_rsp_reject() shall be called with reject reason code set to | ||
4174 | * LSEXP_SPARM_OPTIONS to reject the FLOGI. Otherwise, the Port WWN in the | ||
4175 | * FLOGI shall be compared with the Port WWN of the @vport to determine who | ||
4176 | * will initiate PLOGI. The higher lexicographical value party shall has | ||
4177 | * higher priority (as the winning port) and will initiate PLOGI and | ||
4178 | * communicate Port_IDs (Addresses) for both nodes in PLOGI. The result | ||
4179 | * of this will be marked in the @vport fc_flag field with FC_PT2PT_PLOGI | ||
4180 | * and then the lpfc_els_rsp_acc() routine is invoked to accept the FLOGI. | ||
4181 | * | ||
4182 | * Return code | ||
4183 | * 0 - Successfully processed the unsolicited flogi | ||
4184 | * 1 - Failed to process the unsolicited flogi | ||
4185 | **/ | ||
3316 | static int | 4186 | static int |
3317 | lpfc_els_rcv_flogi(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, | 4187 | lpfc_els_rcv_flogi(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, |
3318 | struct lpfc_nodelist *ndlp) | 4188 | struct lpfc_nodelist *ndlp) |
@@ -3402,6 +4272,22 @@ lpfc_els_rcv_flogi(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, | |||
3402 | return 0; | 4272 | return 0; |
3403 | } | 4273 | } |
3404 | 4274 | ||
4275 | /** | ||
4276 | * lpfc_els_rcv_rnid: Process an unsolicited rnid iocb. | ||
4277 | * @vport: pointer to a host virtual N_Port data structure. | ||
4278 | * @cmdiocb: pointer to lpfc command iocb data structure. | ||
4279 | * @ndlp: pointer to a node-list data structure. | ||
4280 | * | ||
4281 | * This routine processes Request Node Identification Data (RNID) IOCB | ||
4282 | * received as an ELS unsolicited event. Only when the RNID specified format | ||
4283 | * 0x0 or 0xDF (Topology Discovery Specific Node Identification Data) | ||
4284 | * present, this routine will invoke the lpfc_els_rsp_rnid_acc() routine to | ||
4285 | * Accept (ACC) the RNID ELS command. All the other RNID formats are | ||
4286 | * rejected by invoking the lpfc_els_rsp_reject() routine. | ||
4287 | * | ||
4288 | * Return code | ||
4289 | * 0 - Successfully processed rnid iocb (currently always return 0) | ||
4290 | **/ | ||
3405 | static int | 4291 | static int |
3406 | lpfc_els_rcv_rnid(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, | 4292 | lpfc_els_rcv_rnid(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, |
3407 | struct lpfc_nodelist *ndlp) | 4293 | struct lpfc_nodelist *ndlp) |
@@ -3441,6 +4327,19 @@ lpfc_els_rcv_rnid(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, | |||
3441 | return 0; | 4327 | return 0; |
3442 | } | 4328 | } |
3443 | 4329 | ||
4330 | /** | ||
4331 | * lpfc_els_rcv_lirr: Process an unsolicited lirr iocb. | ||
4332 | * @vport: pointer to a host virtual N_Port data structure. | ||
4333 | * @cmdiocb: pointer to lpfc command iocb data structure. | ||
4334 | * @ndlp: pointer to a node-list data structure. | ||
4335 | * | ||
4336 | * This routine processes a Link Incident Report Registration(LIRR) IOCB | ||
4337 | * received as an ELS unsolicited event. Currently, this function just invokes | ||
4338 | * the lpfc_els_rsp_reject() routine to reject the LIRR IOCB unconditionally. | ||
4339 | * | ||
4340 | * Return code | ||
4341 | * 0 - Successfully processed lirr iocb (currently always return 0) | ||
4342 | **/ | ||
3444 | static int | 4343 | static int |
3445 | lpfc_els_rcv_lirr(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, | 4344 | lpfc_els_rcv_lirr(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, |
3446 | struct lpfc_nodelist *ndlp) | 4345 | struct lpfc_nodelist *ndlp) |
@@ -3456,6 +4355,25 @@ lpfc_els_rcv_lirr(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, | |||
3456 | return 0; | 4355 | return 0; |
3457 | } | 4356 | } |
3458 | 4357 | ||
4358 | /** | ||
4359 | * lpfc_els_rsp_rps_acc: Completion callbk func for MBX_READ_LNK_STAT mbox cmd. | ||
4360 | * @phba: pointer to lpfc hba data structure. | ||
4361 | * @pmb: pointer to the driver internal queue element for mailbox command. | ||
4362 | * | ||
4363 | * This routine is the completion callback function for the MBX_READ_LNK_STAT | ||
4364 | * mailbox command. This callback function is to actually send the Accept | ||
4365 | * (ACC) response to a Read Port Status (RPS) unsolicited IOCB event. It | ||
4366 | * collects the link statistics from the completion of the MBX_READ_LNK_STAT | ||
4367 | * mailbox command, constructs the RPS response with the link statistics | ||
4368 | * collected, and then invokes the lpfc_sli_issue_iocb() routine to send ACC | ||
4369 | * response to the RPS. | ||
4370 | * | ||
4371 | * Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp | ||
4372 | * will be incremented by 1 for holding the ndlp and the reference to ndlp | ||
4373 | * will be stored into the context1 field of the IOCB for the completion | ||
4374 | * callback function to the RPS Accept Response ELS IOCB command. | ||
4375 | * | ||
4376 | **/ | ||
3459 | static void | 4377 | static void |
3460 | lpfc_els_rsp_rps_acc(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | 4378 | lpfc_els_rsp_rps_acc(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) |
3461 | { | 4379 | { |
@@ -3531,6 +4449,24 @@ lpfc_els_rsp_rps_acc(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
3531 | return; | 4449 | return; |
3532 | } | 4450 | } |
3533 | 4451 | ||
4452 | /** | ||
4453 | * lpfc_els_rcv_rps: Process an unsolicited rps iocb. | ||
4454 | * @vport: pointer to a host virtual N_Port data structure. | ||
4455 | * @cmdiocb: pointer to lpfc command iocb data structure. | ||
4456 | * @ndlp: pointer to a node-list data structure. | ||
4457 | * | ||
4458 | * This routine processes Read Port Status (RPS) IOCB received as an | ||
4459 | * ELS unsolicited event. It first checks the remote port state. If the | ||
4460 | * remote port is not in NLP_STE_UNMAPPED_NODE state or NLP_STE_MAPPED_NODE | ||
4461 | * state, it invokes the lpfc_els_rsp_reject() routine to send the reject | ||
4462 | * response. Otherwise, it issue the MBX_READ_LNK_STAT mailbox command | ||
4463 | * for reading the HBA link statistics. It is for the callback function, | ||
4464 | * lpfc_els_rsp_rps_acc(), set to the MBX_READ_LNK_STAT mailbox command | ||
4465 | * to actually sending out RPS Accept (ACC) response. | ||
4466 | * | ||
4467 | * Return codes | ||
4468 | * 0 - Successfully processed rps iocb (currently always return 0) | ||
4469 | **/ | ||
3534 | static int | 4470 | static int |
3535 | lpfc_els_rcv_rps(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, | 4471 | lpfc_els_rcv_rps(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, |
3536 | struct lpfc_nodelist *ndlp) | 4472 | struct lpfc_nodelist *ndlp) |
@@ -3592,6 +4528,25 @@ lpfc_els_rcv_rps(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, | |||
3592 | return 0; | 4528 | return 0; |
3593 | } | 4529 | } |
3594 | 4530 | ||
4531 | /** | ||
4532 | * lpfc_els_rsp_rpl_acc: Issue an accept rpl els command. | ||
4533 | * @vport: pointer to a host virtual N_Port data structure. | ||
4534 | * @cmdsize: size of the ELS command. | ||
4535 | * @oldiocb: pointer to the original lpfc command iocb data structure. | ||
4536 | * @ndlp: pointer to a node-list data structure. | ||
4537 | * | ||
4538 | * This routine issuees an Accept (ACC) Read Port List (RPL) ELS command. | ||
4539 | * It is to be called by the lpfc_els_rcv_rpl() routine to accept the RPL. | ||
4540 | * | ||
4541 | * Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp | ||
4542 | * will be incremented by 1 for holding the ndlp and the reference to ndlp | ||
4543 | * will be stored into the context1 field of the IOCB for the completion | ||
4544 | * callback function to the RPL Accept Response ELS command. | ||
4545 | * | ||
4546 | * Return code | ||
4547 | * 0 - Successfully issued ACC RPL ELS command | ||
4548 | * 1 - Failed to issue ACC RPL ELS command | ||
4549 | **/ | ||
3595 | static int | 4550 | static int |
3596 | lpfc_els_rsp_rpl_acc(struct lpfc_vport *vport, uint16_t cmdsize, | 4551 | lpfc_els_rsp_rpl_acc(struct lpfc_vport *vport, uint16_t cmdsize, |
3597 | struct lpfc_iocbq *oldiocb, struct lpfc_nodelist *ndlp) | 4552 | struct lpfc_iocbq *oldiocb, struct lpfc_nodelist *ndlp) |
@@ -3645,6 +4600,22 @@ lpfc_els_rsp_rpl_acc(struct lpfc_vport *vport, uint16_t cmdsize, | |||
3645 | return 0; | 4600 | return 0; |
3646 | } | 4601 | } |
3647 | 4602 | ||
4603 | /** | ||
4604 | * lpfc_els_rcv_rpl: Process an unsolicited rpl iocb. | ||
4605 | * @vport: pointer to a host virtual N_Port data structure. | ||
4606 | * @cmdiocb: pointer to lpfc command iocb data structure. | ||
4607 | * @ndlp: pointer to a node-list data structure. | ||
4608 | * | ||
4609 | * This routine processes Read Port List (RPL) IOCB received as an ELS | ||
4610 | * unsolicited event. It first checks the remote port state. If the remote | ||
4611 | * port is not in NLP_STE_UNMAPPED_NODE and NLP_STE_MAPPED_NODE states, it | ||
4612 | * invokes the lpfc_els_rsp_reject() routine to send reject response. | ||
4613 | * Otherwise, this routine then invokes the lpfc_els_rsp_rpl_acc() routine | ||
4614 | * to accept the RPL. | ||
4615 | * | ||
4616 | * Return code | ||
4617 | * 0 - Successfully processed rpl iocb (currently always return 0) | ||
4618 | **/ | ||
3648 | static int | 4619 | static int |
3649 | lpfc_els_rcv_rpl(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, | 4620 | lpfc_els_rcv_rpl(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, |
3650 | struct lpfc_nodelist *ndlp) | 4621 | struct lpfc_nodelist *ndlp) |
@@ -3685,6 +4656,30 @@ lpfc_els_rcv_rpl(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, | |||
3685 | return 0; | 4656 | return 0; |
3686 | } | 4657 | } |
3687 | 4658 | ||
4659 | /** | ||
4660 | * lpfc_els_rcv_farp: Process an unsolicited farp request els command. | ||
4661 | * @vport: pointer to a virtual N_Port data structure. | ||
4662 | * @cmdiocb: pointer to lpfc command iocb data structure. | ||
4663 | * @ndlp: pointer to a node-list data structure. | ||
4664 | * | ||
4665 | * This routine processes Fibre Channel Address Resolution Protocol | ||
4666 | * (FARP) Request IOCB received as an ELS unsolicited event. Currently, | ||
4667 | * the lpfc driver only supports matching on WWPN or WWNN for FARP. As such, | ||
4668 | * FARP_MATCH_PORT flag and FARP_MATCH_NODE flag are checked against the | ||
4669 | * Match Flag in the FARP request IOCB: if FARP_MATCH_PORT flag is set, the | ||
4670 | * remote PortName is compared against the FC PortName stored in the @vport | ||
4671 | * data structure; if FARP_MATCH_NODE flag is set, the remote NodeName is | ||
4672 | * compared against the FC NodeName stored in the @vport data structure. | ||
4673 | * If any of these matches and the FARP_REQUEST_FARPR flag is set in the | ||
4674 | * FARP request IOCB Response Flag, the lpfc_issue_els_farpr() routine is | ||
4675 | * invoked to send out FARP Response to the remote node. Before sending the | ||
4676 | * FARP Response, however, the FARP_REQUEST_PLOGI flag is check in the FARP | ||
4677 | * request IOCB Response Flag and, if it is set, the lpfc_issue_els_plogi() | ||
4678 | * routine is invoked to log into the remote port first. | ||
4679 | * | ||
4680 | * Return code | ||
4681 | * 0 - Either the FARP Match Mode not supported or successfully processed | ||
4682 | **/ | ||
3688 | static int | 4683 | static int |
3689 | lpfc_els_rcv_farp(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, | 4684 | lpfc_els_rcv_farp(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, |
3690 | struct lpfc_nodelist *ndlp) | 4685 | struct lpfc_nodelist *ndlp) |
@@ -3744,6 +4739,20 @@ lpfc_els_rcv_farp(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, | |||
3744 | return 0; | 4739 | return 0; |
3745 | } | 4740 | } |
3746 | 4741 | ||
4742 | /** | ||
4743 | * lpfc_els_rcv_farpr: Process an unsolicited farp response iocb. | ||
4744 | * @vport: pointer to a host virtual N_Port data structure. | ||
4745 | * @cmdiocb: pointer to lpfc command iocb data structure. | ||
4746 | * @ndlp: pointer to a node-list data structure. | ||
4747 | * | ||
4748 | * This routine processes Fibre Channel Address Resolution Protocol | ||
4749 | * Response (FARPR) IOCB received as an ELS unsolicited event. It simply | ||
4750 | * invokes the lpfc_els_rsp_acc() routine to the remote node to accept | ||
4751 | * the FARP response request. | ||
4752 | * | ||
4753 | * Return code | ||
4754 | * 0 - Successfully processed FARPR IOCB (currently always return 0) | ||
4755 | **/ | ||
3747 | static int | 4756 | static int |
3748 | lpfc_els_rcv_farpr(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, | 4757 | lpfc_els_rcv_farpr(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, |
3749 | struct lpfc_nodelist *ndlp) | 4758 | struct lpfc_nodelist *ndlp) |
@@ -3768,6 +4777,25 @@ lpfc_els_rcv_farpr(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, | |||
3768 | return 0; | 4777 | return 0; |
3769 | } | 4778 | } |
3770 | 4779 | ||
4780 | /** | ||
4781 | * lpfc_els_rcv_fan: Process an unsolicited fan iocb command. | ||
4782 | * @vport: pointer to a host virtual N_Port data structure. | ||
4783 | * @cmdiocb: pointer to lpfc command iocb data structure. | ||
4784 | * @fan_ndlp: pointer to a node-list data structure. | ||
4785 | * | ||
4786 | * This routine processes a Fabric Address Notification (FAN) IOCB | ||
4787 | * command received as an ELS unsolicited event. The FAN ELS command will | ||
4788 | * only be processed on a physical port (i.e., the @vport represents the | ||
4789 | * physical port). The fabric NodeName and PortName from the FAN IOCB are | ||
4790 | * compared against those in the phba data structure. If any of those is | ||
4791 | * different, the lpfc_initial_flogi() routine is invoked to initialize | ||
4792 | * Fabric Login (FLOGI) to the fabric to start the discover over. Otherwise, | ||
4793 | * if both of those are identical, the lpfc_issue_fabric_reglogin() routine | ||
4794 | * is invoked to register login to the fabric. | ||
4795 | * | ||
4796 | * Return code | ||
4797 | * 0 - Successfully processed fan iocb (currently always return 0). | ||
4798 | **/ | ||
3771 | static int | 4799 | static int |
3772 | lpfc_els_rcv_fan(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, | 4800 | lpfc_els_rcv_fan(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, |
3773 | struct lpfc_nodelist *fan_ndlp) | 4801 | struct lpfc_nodelist *fan_ndlp) |
@@ -3797,6 +4825,16 @@ lpfc_els_rcv_fan(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, | |||
3797 | return 0; | 4825 | return 0; |
3798 | } | 4826 | } |
3799 | 4827 | ||
4828 | /** | ||
4829 | * lpfc_els_timeout: Handler funciton to the els timer. | ||
4830 | * @ptr: holder for the timer function associated data. | ||
4831 | * | ||
4832 | * This routine is invoked by the ELS timer after timeout. It posts the ELS | ||
4833 | * timer timeout event by setting the WORKER_ELS_TMO bit to the work port | ||
4834 | * event bitmap and then invokes the lpfc_worker_wake_up() routine to wake | ||
4835 | * up the worker thread. It is for the worker thread to invoke the routine | ||
4836 | * lpfc_els_timeout_handler() to work on the posted event WORKER_ELS_TMO. | ||
4837 | **/ | ||
3800 | void | 4838 | void |
3801 | lpfc_els_timeout(unsigned long ptr) | 4839 | lpfc_els_timeout(unsigned long ptr) |
3802 | { | 4840 | { |
@@ -3816,6 +4854,15 @@ lpfc_els_timeout(unsigned long ptr) | |||
3816 | return; | 4854 | return; |
3817 | } | 4855 | } |
3818 | 4856 | ||
4857 | /** | ||
4858 | * lpfc_els_timeout_handler: Process an els timeout event. | ||
4859 | * @vport: pointer to a virtual N_Port data structure. | ||
4860 | * | ||
4861 | * This routine is the actual handler function that processes an ELS timeout | ||
4862 | * event. It walks the ELS ring to get and abort all the IOCBs (except the | ||
4863 | * ABORT/CLOSE/FARP/FARPR/FDISC), which are associated with the @vport by | ||
4864 | * invoking the lpfc_sli_issue_abort_iotag() routine. | ||
4865 | **/ | ||
3819 | void | 4866 | void |
3820 | lpfc_els_timeout_handler(struct lpfc_vport *vport) | 4867 | lpfc_els_timeout_handler(struct lpfc_vport *vport) |
3821 | { | 4868 | { |
@@ -3886,6 +4933,26 @@ lpfc_els_timeout_handler(struct lpfc_vport *vport) | |||
3886 | mod_timer(&vport->els_tmofunc, jiffies + HZ * timeout); | 4933 | mod_timer(&vport->els_tmofunc, jiffies + HZ * timeout); |
3887 | } | 4934 | } |
3888 | 4935 | ||
4936 | /** | ||
4937 | * lpfc_els_flush_cmd: Clean up the outstanding els commands to a vport. | ||
4938 | * @vport: pointer to a host virtual N_Port data structure. | ||
4939 | * | ||
4940 | * This routine is used to clean up all the outstanding ELS commands on a | ||
4941 | * @vport. It first aborts the @vport by invoking lpfc_fabric_abort_vport() | ||
4942 | * routine. After that, it walks the ELS transmit queue to remove all the | ||
4943 | * IOCBs with the @vport other than the QUE_RING and ABORT/CLOSE IOCBs. For | ||
4944 | * the IOCBs with a non-NULL completion callback function, the callback | ||
4945 | * function will be invoked with the status set to IOSTAT_LOCAL_REJECT and | ||
4946 | * un.ulpWord[4] set to IOERR_SLI_ABORTED. For IOCBs with a NULL completion | ||
4947 | * callback function, the IOCB will simply be released. Finally, it walks | ||
4948 | * the ELS transmit completion queue to issue an abort IOCB to any transmit | ||
4949 | * completion queue IOCB that is associated with the @vport and is not | ||
4950 | * an IOCB from libdfc (i.e., the management plane IOCBs that are not | ||
4951 | * part of the discovery state machine) out to HBA by invoking the | ||
4952 | * lpfc_sli_issue_abort_iotag() routine. Note that this function issues the | ||
4953 | * abort IOCB to any transmit completion queueed IOCB, it does not guarantee | ||
4954 | * the IOCBs are aborted when this function returns. | ||
4955 | **/ | ||
3889 | void | 4956 | void |
3890 | lpfc_els_flush_cmd(struct lpfc_vport *vport) | 4957 | lpfc_els_flush_cmd(struct lpfc_vport *vport) |
3891 | { | 4958 | { |
@@ -3948,6 +5015,23 @@ lpfc_els_flush_cmd(struct lpfc_vport *vport) | |||
3948 | return; | 5015 | return; |
3949 | } | 5016 | } |
3950 | 5017 | ||
5018 | /** | ||
5019 | * lpfc_els_flush_all_cmd: Clean up all the outstanding els commands to a HBA. | ||
5020 | * @phba: pointer to lpfc hba data structure. | ||
5021 | * | ||
5022 | * This routine is used to clean up all the outstanding ELS commands on a | ||
5023 | * @phba. It first aborts the @phba by invoking the lpfc_fabric_abort_hba() | ||
5024 | * routine. After that, it walks the ELS transmit queue to remove all the | ||
5025 | * IOCBs to the @phba other than the QUE_RING and ABORT/CLOSE IOCBs. For | ||
5026 | * the IOCBs with the completion callback function associated, the callback | ||
5027 | * function will be invoked with the status set to IOSTAT_LOCAL_REJECT and | ||
5028 | * un.ulpWord[4] set to IOERR_SLI_ABORTED. For IOCBs without the completion | ||
5029 | * callback function associated, the IOCB will simply be released. Finally, | ||
5030 | * it walks the ELS transmit completion queue to issue an abort IOCB to any | ||
5031 | * transmit completion queue IOCB that is not an IOCB from libdfc (i.e., the | ||
5032 | * management plane IOCBs that are not part of the discovery state machine) | ||
5033 | * out to HBA by invoking the lpfc_sli_issue_abort_iotag() routine. | ||
5034 | **/ | ||
3951 | void | 5035 | void |
3952 | lpfc_els_flush_all_cmd(struct lpfc_hba *phba) | 5036 | lpfc_els_flush_all_cmd(struct lpfc_hba *phba) |
3953 | { | 5037 | { |
@@ -3992,6 +5076,20 @@ lpfc_els_flush_all_cmd(struct lpfc_hba *phba) | |||
3992 | return; | 5076 | return; |
3993 | } | 5077 | } |
3994 | 5078 | ||
5079 | /** | ||
5080 | * lpfc_els_unsol_buffer: Process an unsolicited event data buffer. | ||
5081 | * @phba: pointer to lpfc hba data structure. | ||
5082 | * @pring: pointer to a SLI ring. | ||
5083 | * @vport: pointer to a host virtual N_Port data structure. | ||
5084 | * @elsiocb: pointer to lpfc els command iocb data structure. | ||
5085 | * | ||
5086 | * This routine is used for processing the IOCB associated with a unsolicited | ||
5087 | * event. It first determines whether there is an existing ndlp that matches | ||
5088 | * the DID from the unsolicited IOCB. If not, it will create a new one with | ||
5089 | * the DID from the unsolicited IOCB. The ELS command from the unsolicited | ||
5090 | * IOCB is then used to invoke the proper routine and to set up proper state | ||
5091 | * of the discovery state machine. | ||
5092 | **/ | ||
3995 | static void | 5093 | static void |
3996 | lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | 5094 | lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, |
3997 | struct lpfc_vport *vport, struct lpfc_iocbq *elsiocb) | 5095 | struct lpfc_vport *vport, struct lpfc_iocbq *elsiocb) |
@@ -4282,6 +5380,19 @@ dropit: | |||
4282 | phba->fc_stat.elsRcvDrop++; | 5380 | phba->fc_stat.elsRcvDrop++; |
4283 | } | 5381 | } |
4284 | 5382 | ||
5383 | /** | ||
5384 | * lpfc_find_vport_by_vpid: Find a vport on a HBA through vport identifier. | ||
5385 | * @phba: pointer to lpfc hba data structure. | ||
5386 | * @vpi: host virtual N_Port identifier. | ||
5387 | * | ||
5388 | * This routine finds a vport on a HBA (referred by @phba) through a | ||
5389 | * @vpi. The function walks the HBA's vport list and returns the address | ||
5390 | * of the vport with the matching @vpi. | ||
5391 | * | ||
5392 | * Return code | ||
5393 | * NULL - No vport with the matching @vpi found | ||
5394 | * Otherwise - Address to the vport with the matching @vpi. | ||
5395 | **/ | ||
4285 | static struct lpfc_vport * | 5396 | static struct lpfc_vport * |
4286 | lpfc_find_vport_by_vpid(struct lpfc_hba *phba, uint16_t vpi) | 5397 | lpfc_find_vport_by_vpid(struct lpfc_hba *phba, uint16_t vpi) |
4287 | { | 5398 | { |
@@ -4299,6 +5410,18 @@ lpfc_find_vport_by_vpid(struct lpfc_hba *phba, uint16_t vpi) | |||
4299 | return NULL; | 5410 | return NULL; |
4300 | } | 5411 | } |
4301 | 5412 | ||
5413 | /** | ||
5414 | * lpfc_els_unsol_event: Process an unsolicited event from an els sli ring. | ||
5415 | * @phba: pointer to lpfc hba data structure. | ||
5416 | * @pring: pointer to a SLI ring. | ||
5417 | * @elsiocb: pointer to lpfc els iocb data structure. | ||
5418 | * | ||
5419 | * This routine is used to process an unsolicited event received from a SLI | ||
5420 | * (Service Level Interface) ring. The actual processing of the data buffer | ||
5421 | * associated with the unsolicited event is done by invoking the routine | ||
5422 | * lpfc_els_unsol_buffer() after properly set up the iocb buffer from the | ||
5423 | * SLI ring on which the unsolicited event was received. | ||
5424 | **/ | ||
4302 | void | 5425 | void |
4303 | lpfc_els_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | 5426 | lpfc_els_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, |
4304 | struct lpfc_iocbq *elsiocb) | 5427 | struct lpfc_iocbq *elsiocb) |
@@ -4376,6 +5499,19 @@ lpfc_els_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
4376 | } | 5499 | } |
4377 | } | 5500 | } |
4378 | 5501 | ||
5502 | /** | ||
5503 | * lpfc_do_scr_ns_plogi: Issue a plogi to the name server for scr. | ||
5504 | * @phba: pointer to lpfc hba data structure. | ||
5505 | * @vport: pointer to a virtual N_Port data structure. | ||
5506 | * | ||
5507 | * This routine issues a Port Login (PLOGI) to the Name Server with | ||
5508 | * State Change Request (SCR) for a @vport. This routine will create an | ||
5509 | * ndlp for the Name Server associated to the @vport if such node does | ||
5510 | * not already exist. The PLOGI to Name Server is issued by invoking the | ||
5511 | * lpfc_issue_els_plogi() routine. If Fabric-Device Management Interface | ||
5512 | * (FDMI) is configured to the @vport, a FDMI node will be created and | ||
5513 | * the PLOGI to FDMI is issued by invoking lpfc_issue_els_plogi() routine. | ||
5514 | **/ | ||
4379 | void | 5515 | void |
4380 | lpfc_do_scr_ns_plogi(struct lpfc_hba *phba, struct lpfc_vport *vport) | 5516 | lpfc_do_scr_ns_plogi(struct lpfc_hba *phba, struct lpfc_vport *vport) |
4381 | { | 5517 | { |
@@ -4434,6 +5570,18 @@ lpfc_do_scr_ns_plogi(struct lpfc_hba *phba, struct lpfc_vport *vport) | |||
4434 | return; | 5570 | return; |
4435 | } | 5571 | } |
4436 | 5572 | ||
5573 | /** | ||
5574 | * lpfc_cmpl_reg_new_vport: Completion callback function to register new vport. | ||
5575 | * @phba: pointer to lpfc hba data structure. | ||
5576 | * @pmb: pointer to the driver internal queue element for mailbox command. | ||
5577 | * | ||
5578 | * This routine is the completion callback function to register new vport | ||
5579 | * mailbox command. If the new vport mailbox command completes successfully, | ||
5580 | * the fabric registration login shall be performed on physical port (the | ||
5581 | * new vport created is actually a physical port, with VPI 0) or the port | ||
5582 | * login to Name Server for State Change Request (SCR) will be performed | ||
5583 | * on virtual port (real virtual port, with VPI greater than 0). | ||
5584 | **/ | ||
4437 | static void | 5585 | static void |
4438 | lpfc_cmpl_reg_new_vport(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | 5586 | lpfc_cmpl_reg_new_vport(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) |
4439 | { | 5587 | { |
@@ -4491,6 +5639,15 @@ lpfc_cmpl_reg_new_vport(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
4491 | return; | 5639 | return; |
4492 | } | 5640 | } |
4493 | 5641 | ||
5642 | /** | ||
5643 | * lpfc_register_new_vport: Register a new vport with a HBA. | ||
5644 | * @phba: pointer to lpfc hba data structure. | ||
5645 | * @vport: pointer to a host virtual N_Port data structure. | ||
5646 | * @ndlp: pointer to a node-list data structure. | ||
5647 | * | ||
5648 | * This routine registers the @vport as a new virtual port with a HBA. | ||
5649 | * It is done through a registering vpi mailbox command. | ||
5650 | **/ | ||
4494 | static void | 5651 | static void |
4495 | lpfc_register_new_vport(struct lpfc_hba *phba, struct lpfc_vport *vport, | 5652 | lpfc_register_new_vport(struct lpfc_hba *phba, struct lpfc_vport *vport, |
4496 | struct lpfc_nodelist *ndlp) | 5653 | struct lpfc_nodelist *ndlp) |
@@ -4531,6 +5688,26 @@ mbox_err_exit: | |||
4531 | return; | 5688 | return; |
4532 | } | 5689 | } |
4533 | 5690 | ||
5691 | /** | ||
5692 | * lpfc_cmpl_els_fdisc: Completion function for fdisc iocb command. | ||
5693 | * @phba: pointer to lpfc hba data structure. | ||
5694 | * @cmdiocb: pointer to lpfc command iocb data structure. | ||
5695 | * @rspiocb: pointer to lpfc response iocb data structure. | ||
5696 | * | ||
5697 | * This routine is the completion callback function to a Fabric Discover | ||
5698 | * (FDISC) ELS command. Since all the FDISC ELS commands are issued | ||
5699 | * single threaded, each FDISC completion callback function will reset | ||
5700 | * the discovery timer for all vports such that the timers will not get | ||
5701 | * unnecessary timeout. The function checks the FDISC IOCB status. If error | ||
5702 | * detected, the vport will be set to FC_VPORT_FAILED state. Otherwise,the | ||
5703 | * vport will set to FC_VPORT_ACTIVE state. It then checks whether the DID | ||
5704 | * assigned to the vport has been changed with the completion of the FDISC | ||
5705 | * command. If so, both RPI (Remote Port Index) and VPI (Virtual Port Index) | ||
5706 | * are unregistered from the HBA, and then the lpfc_register_new_vport() | ||
5707 | * routine is invoked to register new vport with the HBA. Otherwise, the | ||
5708 | * lpfc_do_scr_ns_plogi() routine is invoked to issue a PLOGI to the Name | ||
5709 | * Server for State Change Request (SCR). | ||
5710 | **/ | ||
4534 | static void | 5711 | static void |
4535 | lpfc_cmpl_els_fdisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | 5712 | lpfc_cmpl_els_fdisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, |
4536 | struct lpfc_iocbq *rspiocb) | 5713 | struct lpfc_iocbq *rspiocb) |
@@ -4617,6 +5794,26 @@ out: | |||
4617 | lpfc_els_free_iocb(phba, cmdiocb); | 5794 | lpfc_els_free_iocb(phba, cmdiocb); |
4618 | } | 5795 | } |
4619 | 5796 | ||
5797 | /** | ||
5798 | * lpfc_issue_els_fdisc: Issue a fdisc iocb command. | ||
5799 | * @vport: pointer to a virtual N_Port data structure. | ||
5800 | * @ndlp: pointer to a node-list data structure. | ||
5801 | * @retry: number of retries to the command IOCB. | ||
5802 | * | ||
5803 | * This routine prepares and issues a Fabric Discover (FDISC) IOCB to | ||
5804 | * a remote node (@ndlp) off a @vport. It uses the lpfc_issue_fabric_iocb() | ||
5805 | * routine to issue the IOCB, which makes sure only one outstanding fabric | ||
5806 | * IOCB will be sent off HBA at any given time. | ||
5807 | * | ||
5808 | * Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp | ||
5809 | * will be incremented by 1 for holding the ndlp and the reference to ndlp | ||
5810 | * will be stored into the context1 field of the IOCB for the completion | ||
5811 | * callback function to the FDISC ELS command. | ||
5812 | * | ||
5813 | * Return code | ||
5814 | * 0 - Successfully issued fdisc iocb command | ||
5815 | * 1 - Failed to issue fdisc iocb command | ||
5816 | **/ | ||
4620 | static int | 5817 | static int |
4621 | lpfc_issue_els_fdisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | 5818 | lpfc_issue_els_fdisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
4622 | uint8_t retry) | 5819 | uint8_t retry) |
@@ -4691,6 +5888,20 @@ lpfc_issue_els_fdisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | |||
4691 | return 0; | 5888 | return 0; |
4692 | } | 5889 | } |
4693 | 5890 | ||
5891 | /** | ||
5892 | * lpfc_cmpl_els_npiv_logo: Completion function with vport logo. | ||
5893 | * @phba: pointer to lpfc hba data structure. | ||
5894 | * @cmdiocb: pointer to lpfc command iocb data structure. | ||
5895 | * @rspiocb: pointer to lpfc response iocb data structure. | ||
5896 | * | ||
5897 | * This routine is the completion callback function to the issuing of a LOGO | ||
5898 | * ELS command off a vport. It frees the command IOCB and then decrement the | ||
5899 | * reference count held on ndlp for this completion function, indicating that | ||
5900 | * the reference to the ndlp is no long needed. Note that the | ||
5901 | * lpfc_els_free_iocb() routine decrements the ndlp reference held for this | ||
5902 | * callback function and an additional explicit ndlp reference decrementation | ||
5903 | * will trigger the actual release of the ndlp. | ||
5904 | **/ | ||
4694 | static void | 5905 | static void |
4695 | lpfc_cmpl_els_npiv_logo(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | 5906 | lpfc_cmpl_els_npiv_logo(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, |
4696 | struct lpfc_iocbq *rspiocb) | 5907 | struct lpfc_iocbq *rspiocb) |
@@ -4712,6 +5923,22 @@ lpfc_cmpl_els_npiv_logo(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
4712 | lpfc_nlp_put(ndlp); | 5923 | lpfc_nlp_put(ndlp); |
4713 | } | 5924 | } |
4714 | 5925 | ||
5926 | /** | ||
5927 | * lpfc_issue_els_npiv_logo: Issue a logo off a vport. | ||
5928 | * @vport: pointer to a virtual N_Port data structure. | ||
5929 | * @ndlp: pointer to a node-list data structure. | ||
5930 | * | ||
5931 | * This routine issues a LOGO ELS command to an @ndlp off a @vport. | ||
5932 | * | ||
5933 | * Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp | ||
5934 | * will be incremented by 1 for holding the ndlp and the reference to ndlp | ||
5935 | * will be stored into the context1 field of the IOCB for the completion | ||
5936 | * callback function to the LOGO ELS command. | ||
5937 | * | ||
5938 | * Return codes | ||
5939 | * 0 - Successfully issued logo off the @vport | ||
5940 | * 1 - Failed to issue logo off the @vport | ||
5941 | **/ | ||
4715 | int | 5942 | int |
4716 | lpfc_issue_els_npiv_logo(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) | 5943 | lpfc_issue_els_npiv_logo(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) |
4717 | { | 5944 | { |
@@ -4757,6 +5984,17 @@ lpfc_issue_els_npiv_logo(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) | |||
4757 | return 0; | 5984 | return 0; |
4758 | } | 5985 | } |
4759 | 5986 | ||
5987 | /** | ||
5988 | * lpfc_fabric_block_timeout: Handler function to the fabric block timer. | ||
5989 | * @ptr: holder for the timer function associated data. | ||
5990 | * | ||
5991 | * This routine is invoked by the fabric iocb block timer after | ||
5992 | * timeout. It posts the fabric iocb block timeout event by setting the | ||
5993 | * WORKER_FABRIC_BLOCK_TMO bit to work port event bitmap and then invokes | ||
5994 | * lpfc_worker_wake_up() routine to wake up the worker thread. It is for | ||
5995 | * the worker thread to invoke the lpfc_unblock_fabric_iocbs() on the | ||
5996 | * posted event WORKER_FABRIC_BLOCK_TMO. | ||
5997 | **/ | ||
4760 | void | 5998 | void |
4761 | lpfc_fabric_block_timeout(unsigned long ptr) | 5999 | lpfc_fabric_block_timeout(unsigned long ptr) |
4762 | { | 6000 | { |
@@ -4775,6 +6013,16 @@ lpfc_fabric_block_timeout(unsigned long ptr) | |||
4775 | return; | 6013 | return; |
4776 | } | 6014 | } |
4777 | 6015 | ||
6016 | /** | ||
6017 | * lpfc_resume_fabric_iocbs: Issue a fabric iocb from driver internal list. | ||
6018 | * @phba: pointer to lpfc hba data structure. | ||
6019 | * | ||
6020 | * This routine issues one fabric iocb from the driver internal list to | ||
6021 | * the HBA. It first checks whether it's ready to issue one fabric iocb to | ||
6022 | * the HBA (whether there is no outstanding fabric iocb). If so, it shall | ||
6023 | * remove one pending fabric iocb from the driver internal list and invokes | ||
6024 | * lpfc_sli_issue_iocb() routine to send the fabric iocb to the HBA. | ||
6025 | **/ | ||
4778 | static void | 6026 | static void |
4779 | lpfc_resume_fabric_iocbs(struct lpfc_hba *phba) | 6027 | lpfc_resume_fabric_iocbs(struct lpfc_hba *phba) |
4780 | { | 6028 | { |
@@ -4824,6 +6072,15 @@ repeat: | |||
4824 | return; | 6072 | return; |
4825 | } | 6073 | } |
4826 | 6074 | ||
6075 | /** | ||
6076 | * lpfc_unblock_fabric_iocbs: Unblock issuing fabric iocb command. | ||
6077 | * @phba: pointer to lpfc hba data structure. | ||
6078 | * | ||
6079 | * This routine unblocks the issuing fabric iocb command. The function | ||
6080 | * will clear the fabric iocb block bit and then invoke the routine | ||
6081 | * lpfc_resume_fabric_iocbs() to issue one of the pending fabric iocb | ||
6082 | * from the driver internal fabric iocb list. | ||
6083 | **/ | ||
4827 | void | 6084 | void |
4828 | lpfc_unblock_fabric_iocbs(struct lpfc_hba *phba) | 6085 | lpfc_unblock_fabric_iocbs(struct lpfc_hba *phba) |
4829 | { | 6086 | { |
@@ -4833,6 +6090,15 @@ lpfc_unblock_fabric_iocbs(struct lpfc_hba *phba) | |||
4833 | return; | 6090 | return; |
4834 | } | 6091 | } |
4835 | 6092 | ||
6093 | /** | ||
6094 | * lpfc_block_fabric_iocbs: Block issuing fabric iocb command. | ||
6095 | * @phba: pointer to lpfc hba data structure. | ||
6096 | * | ||
6097 | * This routine blocks the issuing fabric iocb for a specified amount of | ||
6098 | * time (currently 100 ms). This is done by set the fabric iocb block bit | ||
6099 | * and set up a timeout timer for 100ms. When the block bit is set, no more | ||
6100 | * fabric iocb will be issued out of the HBA. | ||
6101 | **/ | ||
4836 | static void | 6102 | static void |
4837 | lpfc_block_fabric_iocbs(struct lpfc_hba *phba) | 6103 | lpfc_block_fabric_iocbs(struct lpfc_hba *phba) |
4838 | { | 6104 | { |
@@ -4846,6 +6112,19 @@ lpfc_block_fabric_iocbs(struct lpfc_hba *phba) | |||
4846 | return; | 6112 | return; |
4847 | } | 6113 | } |
4848 | 6114 | ||
6115 | /** | ||
6116 | * lpfc_cmpl_fabric_iocb: Completion callback function for fabric iocb. | ||
6117 | * @phba: pointer to lpfc hba data structure. | ||
6118 | * @cmdiocb: pointer to lpfc command iocb data structure. | ||
6119 | * @rspiocb: pointer to lpfc response iocb data structure. | ||
6120 | * | ||
6121 | * This routine is the callback function that is put to the fabric iocb's | ||
6122 | * callback function pointer (iocb->iocb_cmpl). The original iocb's callback | ||
6123 | * function pointer has been stored in iocb->fabric_iocb_cmpl. This callback | ||
6124 | * function first restores and invokes the original iocb's callback function | ||
6125 | * and then invokes the lpfc_resume_fabric_iocbs() routine to issue the next | ||
6126 | * fabric bound iocb from the driver internal fabric iocb list onto the wire. | ||
6127 | **/ | ||
4849 | static void | 6128 | static void |
4850 | lpfc_cmpl_fabric_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | 6129 | lpfc_cmpl_fabric_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, |
4851 | struct lpfc_iocbq *rspiocb) | 6130 | struct lpfc_iocbq *rspiocb) |
@@ -4892,6 +6171,30 @@ lpfc_cmpl_fabric_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
4892 | } | 6171 | } |
4893 | } | 6172 | } |
4894 | 6173 | ||
6174 | /** | ||
6175 | * lpfc_issue_fabric_iocb: Issue a fabric iocb command. | ||
6176 | * @phba: pointer to lpfc hba data structure. | ||
6177 | * @iocb: pointer to lpfc command iocb data structure. | ||
6178 | * | ||
6179 | * This routine is used as the top-level API for issuing a fabric iocb command | ||
6180 | * such as FLOGI and FDISC. To accommodate certain switch fabric, this driver | ||
6181 | * function makes sure that only one fabric bound iocb will be outstanding at | ||
6182 | * any given time. As such, this function will first check to see whether there | ||
6183 | * is already an outstanding fabric iocb on the wire. If so, it will put the | ||
6184 | * newly issued iocb onto the driver internal fabric iocb list, waiting to be | ||
6185 | * issued later. Otherwise, it will issue the iocb on the wire and update the | ||
6186 | * fabric iocb count it indicate that there is one fabric iocb on the wire. | ||
6187 | * | ||
6188 | * Note, this implementation has a potential sending out fabric IOCBs out of | ||
6189 | * order. The problem is caused by the construction of the "ready" boolen does | ||
6190 | * not include the condition that the internal fabric IOCB list is empty. As | ||
6191 | * such, it is possible a fabric IOCB issued by this routine might be "jump" | ||
6192 | * ahead of the fabric IOCBs in the internal list. | ||
6193 | * | ||
6194 | * Return code | ||
6195 | * IOCB_SUCCESS - either fabric iocb put on the list or issued successfully | ||
6196 | * IOCB_ERROR - failed to issue fabric iocb | ||
6197 | **/ | ||
4895 | static int | 6198 | static int |
4896 | lpfc_issue_fabric_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *iocb) | 6199 | lpfc_issue_fabric_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *iocb) |
4897 | { | 6200 | { |
@@ -4937,7 +6240,17 @@ lpfc_issue_fabric_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *iocb) | |||
4937 | return ret; | 6240 | return ret; |
4938 | } | 6241 | } |
4939 | 6242 | ||
4940 | 6243 | /** | |
6244 | * lpfc_fabric_abort_vport: Abort a vport's iocbs from driver fabric iocb list. | ||
6245 | * @vport: pointer to a virtual N_Port data structure. | ||
6246 | * | ||
6247 | * This routine aborts all the IOCBs associated with a @vport from the | ||
6248 | * driver internal fabric IOCB list. The list contains fabric IOCBs to be | ||
6249 | * issued to the ELS IOCB ring. This abort function walks the fabric IOCB | ||
6250 | * list, removes each IOCB associated with the @vport off the list, set the | ||
6251 | * status feild to IOSTAT_LOCAL_REJECT, and invokes the callback function | ||
6252 | * associated with the IOCB. | ||
6253 | **/ | ||
4941 | static void lpfc_fabric_abort_vport(struct lpfc_vport *vport) | 6254 | static void lpfc_fabric_abort_vport(struct lpfc_vport *vport) |
4942 | { | 6255 | { |
4943 | LIST_HEAD(completions); | 6256 | LIST_HEAD(completions); |
@@ -4967,6 +6280,17 @@ static void lpfc_fabric_abort_vport(struct lpfc_vport *vport) | |||
4967 | } | 6280 | } |
4968 | } | 6281 | } |
4969 | 6282 | ||
6283 | /** | ||
6284 | * lpfc_fabric_abort_nport: Abort a ndlp's iocbs from driver fabric iocb list. | ||
6285 | * @ndlp: pointer to a node-list data structure. | ||
6286 | * | ||
6287 | * This routine aborts all the IOCBs associated with an @ndlp from the | ||
6288 | * driver internal fabric IOCB list. The list contains fabric IOCBs to be | ||
6289 | * issued to the ELS IOCB ring. This abort function walks the fabric IOCB | ||
6290 | * list, removes each IOCB associated with the @ndlp off the list, set the | ||
6291 | * status feild to IOSTAT_LOCAL_REJECT, and invokes the callback function | ||
6292 | * associated with the IOCB. | ||
6293 | **/ | ||
4970 | void lpfc_fabric_abort_nport(struct lpfc_nodelist *ndlp) | 6294 | void lpfc_fabric_abort_nport(struct lpfc_nodelist *ndlp) |
4971 | { | 6295 | { |
4972 | LIST_HEAD(completions); | 6296 | LIST_HEAD(completions); |
@@ -4996,6 +6320,17 @@ void lpfc_fabric_abort_nport(struct lpfc_nodelist *ndlp) | |||
4996 | } | 6320 | } |
4997 | } | 6321 | } |
4998 | 6322 | ||
6323 | /** | ||
6324 | * lpfc_fabric_abort_hba: Abort all iocbs on driver fabric iocb list. | ||
6325 | * @phba: pointer to lpfc hba data structure. | ||
6326 | * | ||
6327 | * This routine aborts all the IOCBs currently on the driver internal | ||
6328 | * fabric IOCB list. The list contains fabric IOCBs to be issued to the ELS | ||
6329 | * IOCB ring. This function takes the entire IOCB list off the fabric IOCB | ||
6330 | * list, removes IOCBs off the list, set the status feild to | ||
6331 | * IOSTAT_LOCAL_REJECT, and invokes the callback function associated with | ||
6332 | * the IOCB. | ||
6333 | **/ | ||
4999 | void lpfc_fabric_abort_hba(struct lpfc_hba *phba) | 6334 | void lpfc_fabric_abort_hba(struct lpfc_hba *phba) |
5000 | { | 6335 | { |
5001 | LIST_HEAD(completions); | 6336 | LIST_HEAD(completions); |