diff options
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_hbadisc.c')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_hbadisc.c | 735 |
1 files changed, 501 insertions, 234 deletions
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index 2445e399fd60..2359d0bfb734 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c | |||
@@ -525,6 +525,8 @@ lpfc_work_done(struct lpfc_hba *phba) | |||
525 | spin_unlock_irq(&phba->hbalock); | 525 | spin_unlock_irq(&phba->hbalock); |
526 | lpfc_sli_hbqbuf_add_hbqs(phba, LPFC_ELS_HBQ); | 526 | lpfc_sli_hbqbuf_add_hbqs(phba, LPFC_ELS_HBQ); |
527 | } | 527 | } |
528 | if (phba->fcf.fcf_flag & FCF_REDISC_EVT) | ||
529 | lpfc_sli4_fcf_redisc_event_proc(phba); | ||
528 | } | 530 | } |
529 | 531 | ||
530 | vports = lpfc_create_vport_work_array(phba); | 532 | vports = lpfc_create_vport_work_array(phba); |
@@ -706,6 +708,8 @@ lpfc_cleanup_rpis(struct lpfc_vport *vport, int remove) | |||
706 | void | 708 | void |
707 | lpfc_port_link_failure(struct lpfc_vport *vport) | 709 | lpfc_port_link_failure(struct lpfc_vport *vport) |
708 | { | 710 | { |
711 | lpfc_vport_set_state(vport, FC_VPORT_LINKDOWN); | ||
712 | |||
709 | /* Cleanup any outstanding received buffers */ | 713 | /* Cleanup any outstanding received buffers */ |
710 | lpfc_cleanup_rcv_buffers(vport); | 714 | lpfc_cleanup_rcv_buffers(vport); |
711 | 715 | ||
@@ -752,12 +756,14 @@ lpfc_linkdown(struct lpfc_hba *phba) | |||
752 | lpfc_scsi_dev_block(phba); | 756 | lpfc_scsi_dev_block(phba); |
753 | 757 | ||
754 | spin_lock_irq(&phba->hbalock); | 758 | spin_lock_irq(&phba->hbalock); |
755 | phba->fcf.fcf_flag &= ~(FCF_AVAILABLE | FCF_DISCOVERED); | 759 | phba->fcf.fcf_flag &= ~(FCF_AVAILABLE | FCF_SCAN_DONE); |
760 | spin_unlock_irq(&phba->hbalock); | ||
756 | if (phba->link_state > LPFC_LINK_DOWN) { | 761 | if (phba->link_state > LPFC_LINK_DOWN) { |
757 | phba->link_state = LPFC_LINK_DOWN; | 762 | phba->link_state = LPFC_LINK_DOWN; |
763 | spin_lock_irq(shost->host_lock); | ||
758 | phba->pport->fc_flag &= ~FC_LBIT; | 764 | phba->pport->fc_flag &= ~FC_LBIT; |
765 | spin_unlock_irq(shost->host_lock); | ||
759 | } | 766 | } |
760 | spin_unlock_irq(&phba->hbalock); | ||
761 | vports = lpfc_create_vport_work_array(phba); | 767 | vports = lpfc_create_vport_work_array(phba); |
762 | if (vports != NULL) | 768 | if (vports != NULL) |
763 | for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) { | 769 | for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) { |
@@ -1023,7 +1029,7 @@ lpfc_mbx_cmpl_reg_fcfi(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | |||
1023 | return; | 1029 | return; |
1024 | } | 1030 | } |
1025 | spin_lock_irqsave(&phba->hbalock, flags); | 1031 | spin_lock_irqsave(&phba->hbalock, flags); |
1026 | phba->fcf.fcf_flag |= (FCF_DISCOVERED | FCF_IN_USE); | 1032 | phba->fcf.fcf_flag |= (FCF_SCAN_DONE | FCF_IN_USE); |
1027 | phba->hba_flag &= ~FCF_DISC_INPROGRESS; | 1033 | phba->hba_flag &= ~FCF_DISC_INPROGRESS; |
1028 | spin_unlock_irqrestore(&phba->hbalock, flags); | 1034 | spin_unlock_irqrestore(&phba->hbalock, flags); |
1029 | if (vport->port_state != LPFC_FLOGI) | 1035 | if (vport->port_state != LPFC_FLOGI) |
@@ -1045,25 +1051,23 @@ lpfc_mbx_cmpl_reg_fcfi(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | |||
1045 | static uint32_t | 1051 | static uint32_t |
1046 | lpfc_fab_name_match(uint8_t *fab_name, struct fcf_record *new_fcf_record) | 1052 | lpfc_fab_name_match(uint8_t *fab_name, struct fcf_record *new_fcf_record) |
1047 | { | 1053 | { |
1048 | if ((fab_name[0] == | 1054 | if (fab_name[0] != bf_get(lpfc_fcf_record_fab_name_0, new_fcf_record)) |
1049 | bf_get(lpfc_fcf_record_fab_name_0, new_fcf_record)) && | 1055 | return 0; |
1050 | (fab_name[1] == | 1056 | if (fab_name[1] != bf_get(lpfc_fcf_record_fab_name_1, new_fcf_record)) |
1051 | bf_get(lpfc_fcf_record_fab_name_1, new_fcf_record)) && | 1057 | return 0; |
1052 | (fab_name[2] == | 1058 | if (fab_name[2] != bf_get(lpfc_fcf_record_fab_name_2, new_fcf_record)) |
1053 | bf_get(lpfc_fcf_record_fab_name_2, new_fcf_record)) && | ||
1054 | (fab_name[3] == | ||
1055 | bf_get(lpfc_fcf_record_fab_name_3, new_fcf_record)) && | ||
1056 | (fab_name[4] == | ||
1057 | bf_get(lpfc_fcf_record_fab_name_4, new_fcf_record)) && | ||
1058 | (fab_name[5] == | ||
1059 | bf_get(lpfc_fcf_record_fab_name_5, new_fcf_record)) && | ||
1060 | (fab_name[6] == | ||
1061 | bf_get(lpfc_fcf_record_fab_name_6, new_fcf_record)) && | ||
1062 | (fab_name[7] == | ||
1063 | bf_get(lpfc_fcf_record_fab_name_7, new_fcf_record))) | ||
1064 | return 1; | ||
1065 | else | ||
1066 | return 0; | 1059 | return 0; |
1060 | if (fab_name[3] != bf_get(lpfc_fcf_record_fab_name_3, new_fcf_record)) | ||
1061 | return 0; | ||
1062 | if (fab_name[4] != bf_get(lpfc_fcf_record_fab_name_4, new_fcf_record)) | ||
1063 | return 0; | ||
1064 | if (fab_name[5] != bf_get(lpfc_fcf_record_fab_name_5, new_fcf_record)) | ||
1065 | return 0; | ||
1066 | if (fab_name[6] != bf_get(lpfc_fcf_record_fab_name_6, new_fcf_record)) | ||
1067 | return 0; | ||
1068 | if (fab_name[7] != bf_get(lpfc_fcf_record_fab_name_7, new_fcf_record)) | ||
1069 | return 0; | ||
1070 | return 1; | ||
1067 | } | 1071 | } |
1068 | 1072 | ||
1069 | /** | 1073 | /** |
@@ -1078,30 +1082,28 @@ lpfc_fab_name_match(uint8_t *fab_name, struct fcf_record *new_fcf_record) | |||
1078 | static uint32_t | 1082 | static uint32_t |
1079 | lpfc_sw_name_match(uint8_t *sw_name, struct fcf_record *new_fcf_record) | 1083 | lpfc_sw_name_match(uint8_t *sw_name, struct fcf_record *new_fcf_record) |
1080 | { | 1084 | { |
1081 | if ((sw_name[0] == | 1085 | if (sw_name[0] != bf_get(lpfc_fcf_record_switch_name_0, new_fcf_record)) |
1082 | bf_get(lpfc_fcf_record_switch_name_0, new_fcf_record)) && | ||
1083 | (sw_name[1] == | ||
1084 | bf_get(lpfc_fcf_record_switch_name_1, new_fcf_record)) && | ||
1085 | (sw_name[2] == | ||
1086 | bf_get(lpfc_fcf_record_switch_name_2, new_fcf_record)) && | ||
1087 | (sw_name[3] == | ||
1088 | bf_get(lpfc_fcf_record_switch_name_3, new_fcf_record)) && | ||
1089 | (sw_name[4] == | ||
1090 | bf_get(lpfc_fcf_record_switch_name_4, new_fcf_record)) && | ||
1091 | (sw_name[5] == | ||
1092 | bf_get(lpfc_fcf_record_switch_name_5, new_fcf_record)) && | ||
1093 | (sw_name[6] == | ||
1094 | bf_get(lpfc_fcf_record_switch_name_6, new_fcf_record)) && | ||
1095 | (sw_name[7] == | ||
1096 | bf_get(lpfc_fcf_record_switch_name_7, new_fcf_record))) | ||
1097 | return 1; | ||
1098 | else | ||
1099 | return 0; | 1086 | return 0; |
1087 | if (sw_name[1] != bf_get(lpfc_fcf_record_switch_name_1, new_fcf_record)) | ||
1088 | return 0; | ||
1089 | if (sw_name[2] != bf_get(lpfc_fcf_record_switch_name_2, new_fcf_record)) | ||
1090 | return 0; | ||
1091 | if (sw_name[3] != bf_get(lpfc_fcf_record_switch_name_3, new_fcf_record)) | ||
1092 | return 0; | ||
1093 | if (sw_name[4] != bf_get(lpfc_fcf_record_switch_name_4, new_fcf_record)) | ||
1094 | return 0; | ||
1095 | if (sw_name[5] != bf_get(lpfc_fcf_record_switch_name_5, new_fcf_record)) | ||
1096 | return 0; | ||
1097 | if (sw_name[6] != bf_get(lpfc_fcf_record_switch_name_6, new_fcf_record)) | ||
1098 | return 0; | ||
1099 | if (sw_name[7] != bf_get(lpfc_fcf_record_switch_name_7, new_fcf_record)) | ||
1100 | return 0; | ||
1101 | return 1; | ||
1100 | } | 1102 | } |
1101 | 1103 | ||
1102 | /** | 1104 | /** |
1103 | * lpfc_mac_addr_match - Check if the fcf mac address match. | 1105 | * lpfc_mac_addr_match - Check if the fcf mac address match. |
1104 | * @phba: pointer to lpfc hba data structure. | 1106 | * @mac_addr: pointer to mac address. |
1105 | * @new_fcf_record: pointer to fcf record. | 1107 | * @new_fcf_record: pointer to fcf record. |
1106 | * | 1108 | * |
1107 | * This routine compare the fcf record's mac address with HBA's | 1109 | * This routine compare the fcf record's mac address with HBA's |
@@ -1109,85 +1111,115 @@ lpfc_sw_name_match(uint8_t *sw_name, struct fcf_record *new_fcf_record) | |||
1109 | * returns 1 else return 0. | 1111 | * returns 1 else return 0. |
1110 | **/ | 1112 | **/ |
1111 | static uint32_t | 1113 | static uint32_t |
1112 | lpfc_mac_addr_match(struct lpfc_hba *phba, struct fcf_record *new_fcf_record) | 1114 | lpfc_mac_addr_match(uint8_t *mac_addr, struct fcf_record *new_fcf_record) |
1113 | { | 1115 | { |
1114 | if ((phba->fcf.mac_addr[0] == | 1116 | if (mac_addr[0] != bf_get(lpfc_fcf_record_mac_0, new_fcf_record)) |
1115 | bf_get(lpfc_fcf_record_mac_0, new_fcf_record)) && | 1117 | return 0; |
1116 | (phba->fcf.mac_addr[1] == | 1118 | if (mac_addr[1] != bf_get(lpfc_fcf_record_mac_1, new_fcf_record)) |
1117 | bf_get(lpfc_fcf_record_mac_1, new_fcf_record)) && | 1119 | return 0; |
1118 | (phba->fcf.mac_addr[2] == | 1120 | if (mac_addr[2] != bf_get(lpfc_fcf_record_mac_2, new_fcf_record)) |
1119 | bf_get(lpfc_fcf_record_mac_2, new_fcf_record)) && | ||
1120 | (phba->fcf.mac_addr[3] == | ||
1121 | bf_get(lpfc_fcf_record_mac_3, new_fcf_record)) && | ||
1122 | (phba->fcf.mac_addr[4] == | ||
1123 | bf_get(lpfc_fcf_record_mac_4, new_fcf_record)) && | ||
1124 | (phba->fcf.mac_addr[5] == | ||
1125 | bf_get(lpfc_fcf_record_mac_5, new_fcf_record))) | ||
1126 | return 1; | ||
1127 | else | ||
1128 | return 0; | 1121 | return 0; |
1122 | if (mac_addr[3] != bf_get(lpfc_fcf_record_mac_3, new_fcf_record)) | ||
1123 | return 0; | ||
1124 | if (mac_addr[4] != bf_get(lpfc_fcf_record_mac_4, new_fcf_record)) | ||
1125 | return 0; | ||
1126 | if (mac_addr[5] != bf_get(lpfc_fcf_record_mac_5, new_fcf_record)) | ||
1127 | return 0; | ||
1128 | return 1; | ||
1129 | } | ||
1130 | |||
1131 | static bool | ||
1132 | lpfc_vlan_id_match(uint16_t curr_vlan_id, uint16_t new_vlan_id) | ||
1133 | { | ||
1134 | return (curr_vlan_id == new_vlan_id); | ||
1129 | } | 1135 | } |
1130 | 1136 | ||
1131 | /** | 1137 | /** |
1132 | * lpfc_copy_fcf_record - Copy fcf information to lpfc_hba. | 1138 | * lpfc_copy_fcf_record - Copy fcf information to lpfc_hba. |
1133 | * @phba: pointer to lpfc hba data structure. | 1139 | * @fcf: pointer to driver fcf record. |
1134 | * @new_fcf_record: pointer to fcf record. | 1140 | * @new_fcf_record: pointer to fcf record. |
1135 | * | 1141 | * |
1136 | * This routine copies the FCF information from the FCF | 1142 | * This routine copies the FCF information from the FCF |
1137 | * record to lpfc_hba data structure. | 1143 | * record to lpfc_hba data structure. |
1138 | **/ | 1144 | **/ |
1139 | static void | 1145 | static void |
1140 | lpfc_copy_fcf_record(struct lpfc_hba *phba, struct fcf_record *new_fcf_record) | 1146 | lpfc_copy_fcf_record(struct lpfc_fcf_rec *fcf_rec, |
1147 | struct fcf_record *new_fcf_record) | ||
1141 | { | 1148 | { |
1142 | phba->fcf.fabric_name[0] = | 1149 | /* Fabric name */ |
1150 | fcf_rec->fabric_name[0] = | ||
1143 | bf_get(lpfc_fcf_record_fab_name_0, new_fcf_record); | 1151 | bf_get(lpfc_fcf_record_fab_name_0, new_fcf_record); |
1144 | phba->fcf.fabric_name[1] = | 1152 | fcf_rec->fabric_name[1] = |
1145 | bf_get(lpfc_fcf_record_fab_name_1, new_fcf_record); | 1153 | bf_get(lpfc_fcf_record_fab_name_1, new_fcf_record); |
1146 | phba->fcf.fabric_name[2] = | 1154 | fcf_rec->fabric_name[2] = |
1147 | bf_get(lpfc_fcf_record_fab_name_2, new_fcf_record); | 1155 | bf_get(lpfc_fcf_record_fab_name_2, new_fcf_record); |
1148 | phba->fcf.fabric_name[3] = | 1156 | fcf_rec->fabric_name[3] = |
1149 | bf_get(lpfc_fcf_record_fab_name_3, new_fcf_record); | 1157 | bf_get(lpfc_fcf_record_fab_name_3, new_fcf_record); |
1150 | phba->fcf.fabric_name[4] = | 1158 | fcf_rec->fabric_name[4] = |
1151 | bf_get(lpfc_fcf_record_fab_name_4, new_fcf_record); | 1159 | bf_get(lpfc_fcf_record_fab_name_4, new_fcf_record); |
1152 | phba->fcf.fabric_name[5] = | 1160 | fcf_rec->fabric_name[5] = |
1153 | bf_get(lpfc_fcf_record_fab_name_5, new_fcf_record); | 1161 | bf_get(lpfc_fcf_record_fab_name_5, new_fcf_record); |
1154 | phba->fcf.fabric_name[6] = | 1162 | fcf_rec->fabric_name[6] = |
1155 | bf_get(lpfc_fcf_record_fab_name_6, new_fcf_record); | 1163 | bf_get(lpfc_fcf_record_fab_name_6, new_fcf_record); |
1156 | phba->fcf.fabric_name[7] = | 1164 | fcf_rec->fabric_name[7] = |
1157 | bf_get(lpfc_fcf_record_fab_name_7, new_fcf_record); | 1165 | bf_get(lpfc_fcf_record_fab_name_7, new_fcf_record); |
1158 | phba->fcf.mac_addr[0] = | 1166 | /* Mac address */ |
1159 | bf_get(lpfc_fcf_record_mac_0, new_fcf_record); | 1167 | fcf_rec->mac_addr[0] = bf_get(lpfc_fcf_record_mac_0, new_fcf_record); |
1160 | phba->fcf.mac_addr[1] = | 1168 | fcf_rec->mac_addr[1] = bf_get(lpfc_fcf_record_mac_1, new_fcf_record); |
1161 | bf_get(lpfc_fcf_record_mac_1, new_fcf_record); | 1169 | fcf_rec->mac_addr[2] = bf_get(lpfc_fcf_record_mac_2, new_fcf_record); |
1162 | phba->fcf.mac_addr[2] = | 1170 | fcf_rec->mac_addr[3] = bf_get(lpfc_fcf_record_mac_3, new_fcf_record); |
1163 | bf_get(lpfc_fcf_record_mac_2, new_fcf_record); | 1171 | fcf_rec->mac_addr[4] = bf_get(lpfc_fcf_record_mac_4, new_fcf_record); |
1164 | phba->fcf.mac_addr[3] = | 1172 | fcf_rec->mac_addr[5] = bf_get(lpfc_fcf_record_mac_5, new_fcf_record); |
1165 | bf_get(lpfc_fcf_record_mac_3, new_fcf_record); | 1173 | /* FCF record index */ |
1166 | phba->fcf.mac_addr[4] = | 1174 | fcf_rec->fcf_indx = bf_get(lpfc_fcf_record_fcf_index, new_fcf_record); |
1167 | bf_get(lpfc_fcf_record_mac_4, new_fcf_record); | 1175 | /* FCF record priority */ |
1168 | phba->fcf.mac_addr[5] = | 1176 | fcf_rec->priority = new_fcf_record->fip_priority; |
1169 | bf_get(lpfc_fcf_record_mac_5, new_fcf_record); | 1177 | /* Switch name */ |
1170 | phba->fcf.fcf_indx = bf_get(lpfc_fcf_record_fcf_index, new_fcf_record); | 1178 | fcf_rec->switch_name[0] = |
1171 | phba->fcf.priority = new_fcf_record->fip_priority; | ||
1172 | phba->fcf.switch_name[0] = | ||
1173 | bf_get(lpfc_fcf_record_switch_name_0, new_fcf_record); | 1179 | bf_get(lpfc_fcf_record_switch_name_0, new_fcf_record); |
1174 | phba->fcf.switch_name[1] = | 1180 | fcf_rec->switch_name[1] = |
1175 | bf_get(lpfc_fcf_record_switch_name_1, new_fcf_record); | 1181 | bf_get(lpfc_fcf_record_switch_name_1, new_fcf_record); |
1176 | phba->fcf.switch_name[2] = | 1182 | fcf_rec->switch_name[2] = |
1177 | bf_get(lpfc_fcf_record_switch_name_2, new_fcf_record); | 1183 | bf_get(lpfc_fcf_record_switch_name_2, new_fcf_record); |
1178 | phba->fcf.switch_name[3] = | 1184 | fcf_rec->switch_name[3] = |
1179 | bf_get(lpfc_fcf_record_switch_name_3, new_fcf_record); | 1185 | bf_get(lpfc_fcf_record_switch_name_3, new_fcf_record); |
1180 | phba->fcf.switch_name[4] = | 1186 | fcf_rec->switch_name[4] = |
1181 | bf_get(lpfc_fcf_record_switch_name_4, new_fcf_record); | 1187 | bf_get(lpfc_fcf_record_switch_name_4, new_fcf_record); |
1182 | phba->fcf.switch_name[5] = | 1188 | fcf_rec->switch_name[5] = |
1183 | bf_get(lpfc_fcf_record_switch_name_5, new_fcf_record); | 1189 | bf_get(lpfc_fcf_record_switch_name_5, new_fcf_record); |
1184 | phba->fcf.switch_name[6] = | 1190 | fcf_rec->switch_name[6] = |
1185 | bf_get(lpfc_fcf_record_switch_name_6, new_fcf_record); | 1191 | bf_get(lpfc_fcf_record_switch_name_6, new_fcf_record); |
1186 | phba->fcf.switch_name[7] = | 1192 | fcf_rec->switch_name[7] = |
1187 | bf_get(lpfc_fcf_record_switch_name_7, new_fcf_record); | 1193 | bf_get(lpfc_fcf_record_switch_name_7, new_fcf_record); |
1188 | } | 1194 | } |
1189 | 1195 | ||
1190 | /** | 1196 | /** |
1197 | * lpfc_update_fcf_record - Update driver fcf record | ||
1198 | * @phba: pointer to lpfc hba data structure. | ||
1199 | * @fcf_rec: pointer to driver fcf record. | ||
1200 | * @new_fcf_record: pointer to hba fcf record. | ||
1201 | * @addr_mode: address mode to be set to the driver fcf record. | ||
1202 | * @vlan_id: vlan tag to be set to the driver fcf record. | ||
1203 | * @flag: flag bits to be set to the driver fcf record. | ||
1204 | * | ||
1205 | * This routine updates the driver FCF record from the new HBA FCF record | ||
1206 | * together with the address mode, vlan_id, and other informations. This | ||
1207 | * routine is called with the host lock held. | ||
1208 | **/ | ||
1209 | static void | ||
1210 | __lpfc_update_fcf_record(struct lpfc_hba *phba, struct lpfc_fcf_rec *fcf_rec, | ||
1211 | struct fcf_record *new_fcf_record, uint32_t addr_mode, | ||
1212 | uint16_t vlan_id, uint32_t flag) | ||
1213 | { | ||
1214 | /* Copy the fields from the HBA's FCF record */ | ||
1215 | lpfc_copy_fcf_record(fcf_rec, new_fcf_record); | ||
1216 | /* Update other fields of driver FCF record */ | ||
1217 | fcf_rec->addr_mode = addr_mode; | ||
1218 | fcf_rec->vlan_id = vlan_id; | ||
1219 | fcf_rec->flag |= (flag | RECORD_VALID); | ||
1220 | } | ||
1221 | |||
1222 | /** | ||
1191 | * lpfc_register_fcf - Register the FCF with hba. | 1223 | * lpfc_register_fcf - Register the FCF with hba. |
1192 | * @phba: pointer to lpfc hba data structure. | 1224 | * @phba: pointer to lpfc hba data structure. |
1193 | * | 1225 | * |
@@ -1212,7 +1244,7 @@ lpfc_register_fcf(struct lpfc_hba *phba) | |||
1212 | 1244 | ||
1213 | /* The FCF is already registered, start discovery */ | 1245 | /* The FCF is already registered, start discovery */ |
1214 | if (phba->fcf.fcf_flag & FCF_REGISTERED) { | 1246 | if (phba->fcf.fcf_flag & FCF_REGISTERED) { |
1215 | phba->fcf.fcf_flag |= (FCF_DISCOVERED | FCF_IN_USE); | 1247 | phba->fcf.fcf_flag |= (FCF_SCAN_DONE | FCF_IN_USE); |
1216 | phba->hba_flag &= ~FCF_DISC_INPROGRESS; | 1248 | phba->hba_flag &= ~FCF_DISC_INPROGRESS; |
1217 | spin_unlock_irqrestore(&phba->hbalock, flags); | 1249 | spin_unlock_irqrestore(&phba->hbalock, flags); |
1218 | if (phba->pport->port_state != LPFC_FLOGI) | 1250 | if (phba->pport->port_state != LPFC_FLOGI) |
@@ -1250,6 +1282,7 @@ lpfc_register_fcf(struct lpfc_hba *phba) | |||
1250 | * @new_fcf_record: pointer to fcf record. | 1282 | * @new_fcf_record: pointer to fcf record. |
1251 | * @boot_flag: Indicates if this record used by boot bios. | 1283 | * @boot_flag: Indicates if this record used by boot bios. |
1252 | * @addr_mode: The address mode to be used by this FCF | 1284 | * @addr_mode: The address mode to be used by this FCF |
1285 | * @vlan_id: The vlan id to be used as vlan tagging by this FCF. | ||
1253 | * | 1286 | * |
1254 | * This routine compare the fcf record with connect list obtained from the | 1287 | * This routine compare the fcf record with connect list obtained from the |
1255 | * config region to decide if this FCF can be used for SAN discovery. It returns | 1288 | * config region to decide if this FCF can be used for SAN discovery. It returns |
@@ -1323,7 +1356,8 @@ lpfc_match_fcf_conn_list(struct lpfc_hba *phba, | |||
1323 | return 1; | 1356 | return 1; |
1324 | } | 1357 | } |
1325 | 1358 | ||
1326 | list_for_each_entry(conn_entry, &phba->fcf_conn_rec_list, list) { | 1359 | list_for_each_entry(conn_entry, |
1360 | &phba->fcf_conn_rec_list, list) { | ||
1327 | if (!(conn_entry->conn_rec.flags & FCFCNCT_VALID)) | 1361 | if (!(conn_entry->conn_rec.flags & FCFCNCT_VALID)) |
1328 | continue; | 1362 | continue; |
1329 | 1363 | ||
@@ -1470,6 +1504,7 @@ lpfc_check_pending_fcoe_event(struct lpfc_hba *phba, uint8_t unreg_fcf) | |||
1470 | */ | 1504 | */ |
1471 | spin_lock_irq(&phba->hbalock); | 1505 | spin_lock_irq(&phba->hbalock); |
1472 | phba->hba_flag &= ~FCF_DISC_INPROGRESS; | 1506 | phba->hba_flag &= ~FCF_DISC_INPROGRESS; |
1507 | phba->fcf.fcf_flag &= ~FCF_REDISC_FOV; | ||
1473 | spin_unlock_irq(&phba->hbalock); | 1508 | spin_unlock_irq(&phba->hbalock); |
1474 | } | 1509 | } |
1475 | 1510 | ||
@@ -1524,11 +1559,12 @@ lpfc_mbx_cmpl_read_fcf_record(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | |||
1524 | uint32_t shdr_status, shdr_add_status; | 1559 | uint32_t shdr_status, shdr_add_status; |
1525 | union lpfc_sli4_cfg_shdr *shdr; | 1560 | union lpfc_sli4_cfg_shdr *shdr; |
1526 | struct fcf_record *new_fcf_record; | 1561 | struct fcf_record *new_fcf_record; |
1527 | int rc; | ||
1528 | uint32_t boot_flag, addr_mode; | 1562 | uint32_t boot_flag, addr_mode; |
1529 | uint32_t next_fcf_index; | 1563 | uint32_t next_fcf_index; |
1530 | unsigned long flags; | 1564 | struct lpfc_fcf_rec *fcf_rec = NULL; |
1565 | unsigned long iflags; | ||
1531 | uint16_t vlan_id; | 1566 | uint16_t vlan_id; |
1567 | int rc; | ||
1532 | 1568 | ||
1533 | /* If there is pending FCoE event restart FCF table scan */ | 1569 | /* If there is pending FCoE event restart FCF table scan */ |
1534 | if (lpfc_check_pending_fcoe_event(phba, 0)) { | 1570 | if (lpfc_check_pending_fcoe_event(phba, 0)) { |
@@ -1583,9 +1619,8 @@ lpfc_mbx_cmpl_read_fcf_record(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | |||
1583 | sizeof(struct fcf_record)); | 1619 | sizeof(struct fcf_record)); |
1584 | bytep = virt_addr + sizeof(union lpfc_sli4_cfg_shdr); | 1620 | bytep = virt_addr + sizeof(union lpfc_sli4_cfg_shdr); |
1585 | 1621 | ||
1586 | rc = lpfc_match_fcf_conn_list(phba, new_fcf_record, | 1622 | rc = lpfc_match_fcf_conn_list(phba, new_fcf_record, &boot_flag, |
1587 | &boot_flag, &addr_mode, | 1623 | &addr_mode, &vlan_id); |
1588 | &vlan_id); | ||
1589 | /* | 1624 | /* |
1590 | * If the fcf record does not match with connect list entries | 1625 | * If the fcf record does not match with connect list entries |
1591 | * read the next entry. | 1626 | * read the next entry. |
@@ -1594,90 +1629,159 @@ lpfc_mbx_cmpl_read_fcf_record(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | |||
1594 | goto read_next_fcf; | 1629 | goto read_next_fcf; |
1595 | /* | 1630 | /* |
1596 | * If this is not the first FCF discovery of the HBA, use last | 1631 | * If this is not the first FCF discovery of the HBA, use last |
1597 | * FCF record for the discovery. | 1632 | * FCF record for the discovery. The condition that a rescan |
1633 | * matches the in-use FCF record: fabric name, switch name, mac | ||
1634 | * address, and vlan_id. | ||
1598 | */ | 1635 | */ |
1599 | spin_lock_irqsave(&phba->hbalock, flags); | 1636 | spin_lock_irqsave(&phba->hbalock, iflags); |
1600 | if (phba->fcf.fcf_flag & FCF_IN_USE) { | 1637 | if (phba->fcf.fcf_flag & FCF_IN_USE) { |
1601 | if (lpfc_fab_name_match(phba->fcf.fabric_name, | 1638 | if (lpfc_fab_name_match(phba->fcf.current_rec.fabric_name, |
1602 | new_fcf_record) && | 1639 | new_fcf_record) && |
1603 | lpfc_sw_name_match(phba->fcf.switch_name, | 1640 | lpfc_sw_name_match(phba->fcf.current_rec.switch_name, |
1604 | new_fcf_record) && | 1641 | new_fcf_record) && |
1605 | lpfc_mac_addr_match(phba, new_fcf_record)) { | 1642 | lpfc_mac_addr_match(phba->fcf.current_rec.mac_addr, |
1643 | new_fcf_record) && | ||
1644 | lpfc_vlan_id_match(phba->fcf.current_rec.vlan_id, | ||
1645 | vlan_id)) { | ||
1606 | phba->fcf.fcf_flag |= FCF_AVAILABLE; | 1646 | phba->fcf.fcf_flag |= FCF_AVAILABLE; |
1607 | spin_unlock_irqrestore(&phba->hbalock, flags); | 1647 | if (phba->fcf.fcf_flag & FCF_REDISC_PEND) |
1648 | /* Stop FCF redisc wait timer if pending */ | ||
1649 | __lpfc_sli4_stop_fcf_redisc_wait_timer(phba); | ||
1650 | else if (phba->fcf.fcf_flag & FCF_REDISC_FOV) | ||
1651 | /* If in fast failover, mark it's completed */ | ||
1652 | phba->fcf.fcf_flag &= ~FCF_REDISC_FOV; | ||
1653 | spin_unlock_irqrestore(&phba->hbalock, iflags); | ||
1608 | goto out; | 1654 | goto out; |
1609 | } | 1655 | } |
1610 | spin_unlock_irqrestore(&phba->hbalock, flags); | 1656 | /* |
1611 | goto read_next_fcf; | 1657 | * Read next FCF record from HBA searching for the matching |
1658 | * with in-use record only if not during the fast failover | ||
1659 | * period. In case of fast failover period, it shall try to | ||
1660 | * determine whether the FCF record just read should be the | ||
1661 | * next candidate. | ||
1662 | */ | ||
1663 | if (!(phba->fcf.fcf_flag & FCF_REDISC_FOV)) { | ||
1664 | spin_unlock_irqrestore(&phba->hbalock, iflags); | ||
1665 | goto read_next_fcf; | ||
1666 | } | ||
1612 | } | 1667 | } |
1668 | /* | ||
1669 | * Update on failover FCF record only if it's in FCF fast-failover | ||
1670 | * period; otherwise, update on current FCF record. | ||
1671 | */ | ||
1672 | if (phba->fcf.fcf_flag & FCF_REDISC_FOV) { | ||
1673 | /* Fast FCF failover only to the same fabric name */ | ||
1674 | if (lpfc_fab_name_match(phba->fcf.current_rec.fabric_name, | ||
1675 | new_fcf_record)) | ||
1676 | fcf_rec = &phba->fcf.failover_rec; | ||
1677 | else | ||
1678 | goto read_next_fcf; | ||
1679 | } else | ||
1680 | fcf_rec = &phba->fcf.current_rec; | ||
1681 | |||
1613 | if (phba->fcf.fcf_flag & FCF_AVAILABLE) { | 1682 | if (phba->fcf.fcf_flag & FCF_AVAILABLE) { |
1614 | /* | 1683 | /* |
1615 | * If the current FCF record does not have boot flag | 1684 | * If the driver FCF record does not have boot flag |
1616 | * set and new fcf record has boot flag set, use the | 1685 | * set and new hba fcf record has boot flag set, use |
1617 | * new fcf record. | 1686 | * the new hba fcf record. |
1618 | */ | 1687 | */ |
1619 | if (boot_flag && !(phba->fcf.fcf_flag & FCF_BOOT_ENABLE)) { | 1688 | if (boot_flag && !(fcf_rec->flag & BOOT_ENABLE)) { |
1620 | /* Use this FCF record */ | 1689 | /* Choose this FCF record */ |
1621 | lpfc_copy_fcf_record(phba, new_fcf_record); | 1690 | __lpfc_update_fcf_record(phba, fcf_rec, new_fcf_record, |
1622 | phba->fcf.addr_mode = addr_mode; | 1691 | addr_mode, vlan_id, BOOT_ENABLE); |
1623 | phba->fcf.fcf_flag |= FCF_BOOT_ENABLE; | 1692 | spin_unlock_irqrestore(&phba->hbalock, iflags); |
1624 | if (vlan_id != 0xFFFF) { | ||
1625 | phba->fcf.fcf_flag |= FCF_VALID_VLAN; | ||
1626 | phba->fcf.vlan_id = vlan_id; | ||
1627 | } | ||
1628 | spin_unlock_irqrestore(&phba->hbalock, flags); | ||
1629 | goto read_next_fcf; | 1693 | goto read_next_fcf; |
1630 | } | 1694 | } |
1631 | /* | 1695 | /* |
1632 | * If the current FCF record has boot flag set and the | 1696 | * If the driver FCF record has boot flag set and the |
1633 | * new FCF record does not have boot flag, read the next | 1697 | * new hba FCF record does not have boot flag, read |
1634 | * FCF record. | 1698 | * the next FCF record. |
1635 | */ | 1699 | */ |
1636 | if (!boot_flag && (phba->fcf.fcf_flag & FCF_BOOT_ENABLE)) { | 1700 | if (!boot_flag && (fcf_rec->flag & BOOT_ENABLE)) { |
1637 | spin_unlock_irqrestore(&phba->hbalock, flags); | 1701 | spin_unlock_irqrestore(&phba->hbalock, iflags); |
1638 | goto read_next_fcf; | 1702 | goto read_next_fcf; |
1639 | } | 1703 | } |
1640 | /* | 1704 | /* |
1641 | * If there is a record with lower priority value for | 1705 | * If the new hba FCF record has lower priority value |
1642 | * the current FCF, use that record. | 1706 | * than the driver FCF record, use the new record. |
1643 | */ | 1707 | */ |
1644 | if (lpfc_fab_name_match(phba->fcf.fabric_name, | 1708 | if (lpfc_fab_name_match(fcf_rec->fabric_name, new_fcf_record) && |
1645 | new_fcf_record) && | 1709 | (new_fcf_record->fip_priority < fcf_rec->priority)) { |
1646 | (new_fcf_record->fip_priority < phba->fcf.priority)) { | 1710 | /* Choose this FCF record */ |
1647 | /* Use this FCF record */ | 1711 | __lpfc_update_fcf_record(phba, fcf_rec, new_fcf_record, |
1648 | lpfc_copy_fcf_record(phba, new_fcf_record); | 1712 | addr_mode, vlan_id, 0); |
1649 | phba->fcf.addr_mode = addr_mode; | ||
1650 | if (vlan_id != 0xFFFF) { | ||
1651 | phba->fcf.fcf_flag |= FCF_VALID_VLAN; | ||
1652 | phba->fcf.vlan_id = vlan_id; | ||
1653 | } | ||
1654 | spin_unlock_irqrestore(&phba->hbalock, flags); | ||
1655 | goto read_next_fcf; | ||
1656 | } | 1713 | } |
1657 | spin_unlock_irqrestore(&phba->hbalock, flags); | 1714 | spin_unlock_irqrestore(&phba->hbalock, iflags); |
1658 | goto read_next_fcf; | 1715 | goto read_next_fcf; |
1659 | } | 1716 | } |
1660 | /* | 1717 | /* |
1661 | * This is the first available FCF record, use this | 1718 | * This is the first suitable FCF record, choose this record for |
1662 | * record. | 1719 | * initial best-fit FCF. |
1663 | */ | 1720 | */ |
1664 | lpfc_copy_fcf_record(phba, new_fcf_record); | 1721 | if (fcf_rec) { |
1665 | phba->fcf.addr_mode = addr_mode; | 1722 | __lpfc_update_fcf_record(phba, fcf_rec, new_fcf_record, |
1666 | if (boot_flag) | 1723 | addr_mode, vlan_id, (boot_flag ? |
1667 | phba->fcf.fcf_flag |= FCF_BOOT_ENABLE; | 1724 | BOOT_ENABLE : 0)); |
1668 | phba->fcf.fcf_flag |= FCF_AVAILABLE; | 1725 | phba->fcf.fcf_flag |= FCF_AVAILABLE; |
1669 | if (vlan_id != 0xFFFF) { | ||
1670 | phba->fcf.fcf_flag |= FCF_VALID_VLAN; | ||
1671 | phba->fcf.vlan_id = vlan_id; | ||
1672 | } | 1726 | } |
1673 | spin_unlock_irqrestore(&phba->hbalock, flags); | 1727 | spin_unlock_irqrestore(&phba->hbalock, iflags); |
1674 | goto read_next_fcf; | 1728 | goto read_next_fcf; |
1675 | 1729 | ||
1676 | read_next_fcf: | 1730 | read_next_fcf: |
1677 | lpfc_sli4_mbox_cmd_free(phba, mboxq); | 1731 | lpfc_sli4_mbox_cmd_free(phba, mboxq); |
1678 | if (next_fcf_index == LPFC_FCOE_FCF_NEXT_NONE || next_fcf_index == 0) | 1732 | if (next_fcf_index == LPFC_FCOE_FCF_NEXT_NONE || next_fcf_index == 0) { |
1679 | lpfc_register_fcf(phba); | 1733 | if (phba->fcf.fcf_flag & FCF_REDISC_FOV) { |
1680 | else | 1734 | /* |
1735 | * Case of FCF fast failover scan | ||
1736 | */ | ||
1737 | |||
1738 | /* | ||
1739 | * It has not found any suitable FCF record, cancel | ||
1740 | * FCF scan inprogress, and do nothing | ||
1741 | */ | ||
1742 | if (!(phba->fcf.failover_rec.flag & RECORD_VALID)) { | ||
1743 | spin_lock_irqsave(&phba->hbalock, iflags); | ||
1744 | phba->hba_flag &= ~FCF_DISC_INPROGRESS; | ||
1745 | spin_unlock_irqrestore(&phba->hbalock, iflags); | ||
1746 | return; | ||
1747 | } | ||
1748 | /* | ||
1749 | * It has found a suitable FCF record that is not | ||
1750 | * the same as in-use FCF record, unregister the | ||
1751 | * in-use FCF record, replace the in-use FCF record | ||
1752 | * with the new FCF record, mark FCF fast failover | ||
1753 | * completed, and then start register the new FCF | ||
1754 | * record. | ||
1755 | */ | ||
1756 | |||
1757 | /* unregister the current in-use FCF record */ | ||
1758 | lpfc_unregister_fcf(phba); | ||
1759 | /* replace in-use record with the new record */ | ||
1760 | memcpy(&phba->fcf.current_rec, | ||
1761 | &phba->fcf.failover_rec, | ||
1762 | sizeof(struct lpfc_fcf_rec)); | ||
1763 | /* mark the FCF fast failover completed */ | ||
1764 | spin_lock_irqsave(&phba->hbalock, iflags); | ||
1765 | phba->fcf.fcf_flag &= ~FCF_REDISC_FOV; | ||
1766 | spin_unlock_irqrestore(&phba->hbalock, iflags); | ||
1767 | /* Register to the new FCF record */ | ||
1768 | lpfc_register_fcf(phba); | ||
1769 | } else { | ||
1770 | /* | ||
1771 | * In case of transaction period to fast FCF failover, | ||
1772 | * do nothing when search to the end of the FCF table. | ||
1773 | */ | ||
1774 | if ((phba->fcf.fcf_flag & FCF_REDISC_EVT) || | ||
1775 | (phba->fcf.fcf_flag & FCF_REDISC_PEND)) | ||
1776 | return; | ||
1777 | /* | ||
1778 | * Otherwise, initial scan or post linkdown rescan, | ||
1779 | * register with the best fit FCF record found so | ||
1780 | * far through the scanning process. | ||
1781 | */ | ||
1782 | lpfc_register_fcf(phba); | ||
1783 | } | ||
1784 | } else | ||
1681 | lpfc_sli4_read_fcf_record(phba, next_fcf_index); | 1785 | lpfc_sli4_read_fcf_record(phba, next_fcf_index); |
1682 | return; | 1786 | return; |
1683 | 1787 | ||
@@ -1695,10 +1799,13 @@ out: | |||
1695 | * | 1799 | * |
1696 | * This function handles completion of init vpi mailbox command. | 1800 | * This function handles completion of init vpi mailbox command. |
1697 | */ | 1801 | */ |
1698 | static void | 1802 | void |
1699 | lpfc_init_vpi_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | 1803 | lpfc_init_vpi_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) |
1700 | { | 1804 | { |
1701 | struct lpfc_vport *vport = mboxq->vport; | 1805 | struct lpfc_vport *vport = mboxq->vport; |
1806 | struct lpfc_nodelist *ndlp; | ||
1807 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
1808 | |||
1702 | if (mboxq->u.mb.mbxStatus) { | 1809 | if (mboxq->u.mb.mbxStatus) { |
1703 | lpfc_printf_vlog(vport, KERN_ERR, | 1810 | lpfc_printf_vlog(vport, KERN_ERR, |
1704 | LOG_MBOX, | 1811 | LOG_MBOX, |
@@ -1708,9 +1815,23 @@ lpfc_init_vpi_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | |||
1708 | lpfc_vport_set_state(vport, FC_VPORT_FAILED); | 1815 | lpfc_vport_set_state(vport, FC_VPORT_FAILED); |
1709 | return; | 1816 | return; |
1710 | } | 1817 | } |
1711 | spin_lock_irq(&phba->hbalock); | 1818 | spin_lock_irq(shost->host_lock); |
1712 | vport->fc_flag &= ~FC_VPORT_NEEDS_INIT_VPI; | 1819 | vport->fc_flag &= ~FC_VPORT_NEEDS_INIT_VPI; |
1713 | spin_unlock_irq(&phba->hbalock); | 1820 | spin_unlock_irq(shost->host_lock); |
1821 | |||
1822 | /* If this port is physical port or FDISC is done, do reg_vpi */ | ||
1823 | if ((phba->pport == vport) || (vport->port_state == LPFC_FDISC)) { | ||
1824 | ndlp = lpfc_findnode_did(vport, Fabric_DID); | ||
1825 | if (!ndlp) | ||
1826 | lpfc_printf_vlog(vport, KERN_ERR, | ||
1827 | LOG_DISCOVERY, | ||
1828 | "2731 Cannot find fabric " | ||
1829 | "controller node\n"); | ||
1830 | else | ||
1831 | lpfc_register_new_vport(phba, vport, ndlp); | ||
1832 | mempool_free(mboxq, phba->mbox_mem_pool); | ||
1833 | return; | ||
1834 | } | ||
1714 | 1835 | ||
1715 | if (phba->link_flag & LS_NPIV_FAB_SUPPORTED) | 1836 | if (phba->link_flag & LS_NPIV_FAB_SUPPORTED) |
1716 | lpfc_initial_fdisc(vport); | 1837 | lpfc_initial_fdisc(vport); |
@@ -1719,10 +1840,42 @@ lpfc_init_vpi_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | |||
1719 | lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, | 1840 | lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, |
1720 | "2606 No NPIV Fabric support\n"); | 1841 | "2606 No NPIV Fabric support\n"); |
1721 | } | 1842 | } |
1843 | mempool_free(mboxq, phba->mbox_mem_pool); | ||
1722 | return; | 1844 | return; |
1723 | } | 1845 | } |
1724 | 1846 | ||
1725 | /** | 1847 | /** |
1848 | * lpfc_issue_init_vpi - Issue init_vpi mailbox command. | ||
1849 | * @vport: pointer to lpfc_vport data structure. | ||
1850 | * | ||
1851 | * This function issue a init_vpi mailbox command to initialize | ||
1852 | * VPI for the vport. | ||
1853 | */ | ||
1854 | void | ||
1855 | lpfc_issue_init_vpi(struct lpfc_vport *vport) | ||
1856 | { | ||
1857 | LPFC_MBOXQ_t *mboxq; | ||
1858 | int rc; | ||
1859 | |||
1860 | mboxq = mempool_alloc(vport->phba->mbox_mem_pool, GFP_KERNEL); | ||
1861 | if (!mboxq) { | ||
1862 | lpfc_printf_vlog(vport, KERN_ERR, | ||
1863 | LOG_MBOX, "2607 Failed to allocate " | ||
1864 | "init_vpi mailbox\n"); | ||
1865 | return; | ||
1866 | } | ||
1867 | lpfc_init_vpi(vport->phba, mboxq, vport->vpi); | ||
1868 | mboxq->vport = vport; | ||
1869 | mboxq->mbox_cmpl = lpfc_init_vpi_cmpl; | ||
1870 | rc = lpfc_sli_issue_mbox(vport->phba, mboxq, MBX_NOWAIT); | ||
1871 | if (rc == MBX_NOT_FINISHED) { | ||
1872 | lpfc_printf_vlog(vport, KERN_ERR, | ||
1873 | LOG_MBOX, "2608 Failed to issue init_vpi mailbox\n"); | ||
1874 | mempool_free(mboxq, vport->phba->mbox_mem_pool); | ||
1875 | } | ||
1876 | } | ||
1877 | |||
1878 | /** | ||
1726 | * lpfc_start_fdiscs - send fdiscs for each vports on this port. | 1879 | * lpfc_start_fdiscs - send fdiscs for each vports on this port. |
1727 | * @phba: pointer to lpfc hba data structure. | 1880 | * @phba: pointer to lpfc hba data structure. |
1728 | * | 1881 | * |
@@ -1734,8 +1887,6 @@ lpfc_start_fdiscs(struct lpfc_hba *phba) | |||
1734 | { | 1887 | { |
1735 | struct lpfc_vport **vports; | 1888 | struct lpfc_vport **vports; |
1736 | int i; | 1889 | int i; |
1737 | LPFC_MBOXQ_t *mboxq; | ||
1738 | int rc; | ||
1739 | 1890 | ||
1740 | vports = lpfc_create_vport_work_array(phba); | 1891 | vports = lpfc_create_vport_work_array(phba); |
1741 | if (vports != NULL) { | 1892 | if (vports != NULL) { |
@@ -1754,26 +1905,7 @@ lpfc_start_fdiscs(struct lpfc_hba *phba) | |||
1754 | continue; | 1905 | continue; |
1755 | } | 1906 | } |
1756 | if (vports[i]->fc_flag & FC_VPORT_NEEDS_INIT_VPI) { | 1907 | if (vports[i]->fc_flag & FC_VPORT_NEEDS_INIT_VPI) { |
1757 | mboxq = mempool_alloc(phba->mbox_mem_pool, | 1908 | lpfc_issue_init_vpi(vports[i]); |
1758 | GFP_KERNEL); | ||
1759 | if (!mboxq) { | ||
1760 | lpfc_printf_vlog(vports[i], KERN_ERR, | ||
1761 | LOG_MBOX, "2607 Failed to allocate " | ||
1762 | "init_vpi mailbox\n"); | ||
1763 | continue; | ||
1764 | } | ||
1765 | lpfc_init_vpi(phba, mboxq, vports[i]->vpi); | ||
1766 | mboxq->vport = vports[i]; | ||
1767 | mboxq->mbox_cmpl = lpfc_init_vpi_cmpl; | ||
1768 | rc = lpfc_sli_issue_mbox(phba, mboxq, | ||
1769 | MBX_NOWAIT); | ||
1770 | if (rc == MBX_NOT_FINISHED) { | ||
1771 | lpfc_printf_vlog(vports[i], KERN_ERR, | ||
1772 | LOG_MBOX, "2608 Failed to issue " | ||
1773 | "init_vpi mailbox\n"); | ||
1774 | mempool_free(mboxq, | ||
1775 | phba->mbox_mem_pool); | ||
1776 | } | ||
1777 | continue; | 1909 | continue; |
1778 | } | 1910 | } |
1779 | if (phba->link_flag & LS_NPIV_FAB_SUPPORTED) | 1911 | if (phba->link_flag & LS_NPIV_FAB_SUPPORTED) |
@@ -1796,6 +1928,7 @@ lpfc_mbx_cmpl_reg_vfi(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | |||
1796 | { | 1928 | { |
1797 | struct lpfc_dmabuf *dmabuf = mboxq->context1; | 1929 | struct lpfc_dmabuf *dmabuf = mboxq->context1; |
1798 | struct lpfc_vport *vport = mboxq->vport; | 1930 | struct lpfc_vport *vport = mboxq->vport; |
1931 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
1799 | 1932 | ||
1800 | if (mboxq->u.mb.mbxStatus) { | 1933 | if (mboxq->u.mb.mbxStatus) { |
1801 | lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX, | 1934 | lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX, |
@@ -1813,7 +1946,11 @@ lpfc_mbx_cmpl_reg_vfi(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | |||
1813 | goto fail_free_mem; | 1946 | goto fail_free_mem; |
1814 | } | 1947 | } |
1815 | /* The VPI is implicitly registered when the VFI is registered */ | 1948 | /* The VPI is implicitly registered when the VFI is registered */ |
1949 | spin_lock_irq(shost->host_lock); | ||
1816 | vport->vpi_state |= LPFC_VPI_REGISTERED; | 1950 | vport->vpi_state |= LPFC_VPI_REGISTERED; |
1951 | vport->fc_flag |= FC_VFI_REGISTERED; | ||
1952 | vport->fc_flag &= ~FC_VPORT_NEEDS_REG_VPI; | ||
1953 | spin_unlock_irq(shost->host_lock); | ||
1817 | 1954 | ||
1818 | if (vport->port_state == LPFC_FABRIC_CFG_LINK) { | 1955 | if (vport->port_state == LPFC_FABRIC_CFG_LINK) { |
1819 | lpfc_start_fdiscs(phba); | 1956 | lpfc_start_fdiscs(phba); |
@@ -2050,8 +2187,7 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, READ_LA_VAR *la) | |||
2050 | return; | 2187 | return; |
2051 | } | 2188 | } |
2052 | spin_unlock_irq(&phba->hbalock); | 2189 | spin_unlock_irq(&phba->hbalock); |
2053 | rc = lpfc_sli4_read_fcf_record(phba, | 2190 | rc = lpfc_sli4_read_fcf_record(phba, LPFC_FCOE_FCF_GET_FIRST); |
2054 | LPFC_FCOE_FCF_GET_FIRST); | ||
2055 | if (rc) | 2191 | if (rc) |
2056 | goto out; | 2192 | goto out; |
2057 | } | 2193 | } |
@@ -2139,10 +2275,12 @@ lpfc_mbx_cmpl_read_la(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
2139 | } | 2275 | } |
2140 | 2276 | ||
2141 | phba->fc_eventTag = la->eventTag; | 2277 | phba->fc_eventTag = la->eventTag; |
2278 | spin_lock_irq(&phba->hbalock); | ||
2142 | if (la->mm) | 2279 | if (la->mm) |
2143 | phba->sli.sli_flag |= LPFC_MENLO_MAINT; | 2280 | phba->sli.sli_flag |= LPFC_MENLO_MAINT; |
2144 | else | 2281 | else |
2145 | phba->sli.sli_flag &= ~LPFC_MENLO_MAINT; | 2282 | phba->sli.sli_flag &= ~LPFC_MENLO_MAINT; |
2283 | spin_unlock_irq(&phba->hbalock); | ||
2146 | 2284 | ||
2147 | phba->link_events++; | 2285 | phba->link_events++; |
2148 | if (la->attType == AT_LINK_UP && (!la->mm)) { | 2286 | if (la->attType == AT_LINK_UP && (!la->mm)) { |
@@ -2271,10 +2409,10 @@ lpfc_mbx_cmpl_unreg_vpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
2271 | mb->mbxStatus); | 2409 | mb->mbxStatus); |
2272 | break; | 2410 | break; |
2273 | } | 2411 | } |
2274 | spin_lock_irq(&phba->hbalock); | 2412 | spin_lock_irq(shost->host_lock); |
2275 | vport->vpi_state &= ~LPFC_VPI_REGISTERED; | 2413 | vport->vpi_state &= ~LPFC_VPI_REGISTERED; |
2276 | vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI; | 2414 | vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI; |
2277 | spin_unlock_irq(&phba->hbalock); | 2415 | spin_unlock_irq(shost->host_lock); |
2278 | vport->unreg_vpi_cmpl = VPORT_OK; | 2416 | vport->unreg_vpi_cmpl = VPORT_OK; |
2279 | mempool_free(pmb, phba->mbox_mem_pool); | 2417 | mempool_free(pmb, phba->mbox_mem_pool); |
2280 | /* | 2418 | /* |
@@ -2332,7 +2470,10 @@ lpfc_mbx_cmpl_reg_vpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
2332 | goto out; | 2470 | goto out; |
2333 | } | 2471 | } |
2334 | 2472 | ||
2473 | spin_lock_irq(shost->host_lock); | ||
2335 | vport->vpi_state |= LPFC_VPI_REGISTERED; | 2474 | vport->vpi_state |= LPFC_VPI_REGISTERED; |
2475 | vport->fc_flag &= ~FC_VPORT_NEEDS_REG_VPI; | ||
2476 | spin_unlock_irq(shost->host_lock); | ||
2336 | vport->num_disc_nodes = 0; | 2477 | vport->num_disc_nodes = 0; |
2337 | /* go thru NPR list and issue ELS PLOGIs */ | 2478 | /* go thru NPR list and issue ELS PLOGIs */ |
2338 | if (vport->fc_npr_cnt) | 2479 | if (vport->fc_npr_cnt) |
@@ -3218,6 +3359,34 @@ lpfc_unreg_rpi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) | |||
3218 | return 0; | 3359 | return 0; |
3219 | } | 3360 | } |
3220 | 3361 | ||
3362 | /** | ||
3363 | * lpfc_unreg_hba_rpis - Unregister rpis registered to the hba. | ||
3364 | * @phba: pointer to lpfc hba data structure. | ||
3365 | * | ||
3366 | * This routine is invoked to unregister all the currently registered RPIs | ||
3367 | * to the HBA. | ||
3368 | **/ | ||
3369 | void | ||
3370 | lpfc_unreg_hba_rpis(struct lpfc_hba *phba) | ||
3371 | { | ||
3372 | struct lpfc_vport **vports; | ||
3373 | struct lpfc_nodelist *ndlp; | ||
3374 | struct Scsi_Host *shost; | ||
3375 | int i; | ||
3376 | |||
3377 | vports = lpfc_create_vport_work_array(phba); | ||
3378 | for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) { | ||
3379 | shost = lpfc_shost_from_vport(vports[i]); | ||
3380 | spin_lock_irq(shost->host_lock); | ||
3381 | list_for_each_entry(ndlp, &vports[i]->fc_nodes, nlp_listp) { | ||
3382 | if (ndlp->nlp_flag & NLP_RPI_VALID) | ||
3383 | lpfc_unreg_rpi(vports[i], ndlp); | ||
3384 | } | ||
3385 | spin_unlock_irq(shost->host_lock); | ||
3386 | } | ||
3387 | lpfc_destroy_vport_work_array(phba, vports); | ||
3388 | } | ||
3389 | |||
3221 | void | 3390 | void |
3222 | lpfc_unreg_all_rpis(struct lpfc_vport *vport) | 3391 | lpfc_unreg_all_rpis(struct lpfc_vport *vport) |
3223 | { | 3392 | { |
@@ -4448,63 +4617,56 @@ lpfc_unregister_fcfi_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | |||
4448 | } | 4617 | } |
4449 | 4618 | ||
4450 | /** | 4619 | /** |
4451 | * lpfc_unregister_unused_fcf - Unregister FCF if all devices are disconnected. | 4620 | * lpfc_unregister_fcf_prep - Unregister fcf record preparation |
4452 | * @phba: Pointer to hba context object. | 4621 | * @phba: Pointer to hba context object. |
4453 | * | 4622 | * |
4454 | * This function check if there are any connected remote port for the FCF and | 4623 | * This function prepare the HBA for unregistering the currently registered |
4455 | * if all the devices are disconnected, this function unregister FCFI. | 4624 | * FCF from the HBA. It performs unregistering, in order, RPIs, VPIs, and |
4456 | * This function also tries to use another FCF for discovery. | 4625 | * VFIs. |
4457 | */ | 4626 | */ |
4458 | void | 4627 | int |
4459 | lpfc_unregister_unused_fcf(struct lpfc_hba *phba) | 4628 | lpfc_unregister_fcf_prep(struct lpfc_hba *phba) |
4460 | { | 4629 | { |
4461 | LPFC_MBOXQ_t *mbox; | 4630 | LPFC_MBOXQ_t *mbox; |
4462 | int rc; | ||
4463 | struct lpfc_vport **vports; | 4631 | struct lpfc_vport **vports; |
4464 | int i; | 4632 | struct lpfc_nodelist *ndlp; |
4465 | 4633 | struct Scsi_Host *shost; | |
4466 | spin_lock_irq(&phba->hbalock); | 4634 | int i, rc; |
4467 | /* | ||
4468 | * If HBA is not running in FIP mode or | ||
4469 | * If HBA does not support FCoE or | ||
4470 | * If FCF is not registered. | ||
4471 | * do nothing. | ||
4472 | */ | ||
4473 | if (!(phba->hba_flag & HBA_FCOE_SUPPORT) || | ||
4474 | !(phba->fcf.fcf_flag & FCF_REGISTERED) || | ||
4475 | (!(phba->hba_flag & HBA_FIP_SUPPORT))) { | ||
4476 | spin_unlock_irq(&phba->hbalock); | ||
4477 | return; | ||
4478 | } | ||
4479 | spin_unlock_irq(&phba->hbalock); | ||
4480 | 4635 | ||
4636 | /* Unregister RPIs */ | ||
4481 | if (lpfc_fcf_inuse(phba)) | 4637 | if (lpfc_fcf_inuse(phba)) |
4482 | return; | 4638 | lpfc_unreg_hba_rpis(phba); |
4483 | 4639 | ||
4484 | /* At this point, all discovery is aborted */ | 4640 | /* At this point, all discovery is aborted */ |
4485 | phba->pport->port_state = LPFC_VPORT_UNKNOWN; | 4641 | phba->pport->port_state = LPFC_VPORT_UNKNOWN; |
4486 | 4642 | ||
4487 | /* Unregister VPIs */ | 4643 | /* Unregister VPIs */ |
4488 | vports = lpfc_create_vport_work_array(phba); | 4644 | vports = lpfc_create_vport_work_array(phba); |
4489 | if (vports && | 4645 | if (vports && (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED)) |
4490 | (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED)) | ||
4491 | for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) { | 4646 | for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) { |
4647 | /* Stop FLOGI/FDISC retries */ | ||
4648 | ndlp = lpfc_findnode_did(vports[i], Fabric_DID); | ||
4649 | if (ndlp) | ||
4650 | lpfc_cancel_retry_delay_tmo(vports[i], ndlp); | ||
4492 | lpfc_mbx_unreg_vpi(vports[i]); | 4651 | lpfc_mbx_unreg_vpi(vports[i]); |
4493 | spin_lock_irq(&phba->hbalock); | 4652 | shost = lpfc_shost_from_vport(vports[i]); |
4653 | spin_lock_irq(shost->host_lock); | ||
4494 | vports[i]->fc_flag |= FC_VPORT_NEEDS_INIT_VPI; | 4654 | vports[i]->fc_flag |= FC_VPORT_NEEDS_INIT_VPI; |
4495 | vports[i]->vpi_state &= ~LPFC_VPI_REGISTERED; | 4655 | vports[i]->vpi_state &= ~LPFC_VPI_REGISTERED; |
4496 | spin_unlock_irq(&phba->hbalock); | 4656 | spin_unlock_irq(shost->host_lock); |
4497 | } | 4657 | } |
4498 | lpfc_destroy_vport_work_array(phba, vports); | 4658 | lpfc_destroy_vport_work_array(phba, vports); |
4499 | 4659 | ||
4660 | /* Cleanup any outstanding ELS commands */ | ||
4661 | lpfc_els_flush_all_cmd(phba); | ||
4662 | |||
4500 | /* Unregister VFI */ | 4663 | /* Unregister VFI */ |
4501 | mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | 4664 | mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
4502 | if (!mbox) { | 4665 | if (!mbox) { |
4503 | lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY|LOG_MBOX, | 4666 | lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY|LOG_MBOX, |
4504 | "2556 UNREG_VFI mbox allocation failed" | 4667 | "2556 UNREG_VFI mbox allocation failed" |
4505 | "HBA state x%x\n", | 4668 | "HBA state x%x\n", phba->pport->port_state); |
4506 | phba->pport->port_state); | 4669 | return -ENOMEM; |
4507 | return; | ||
4508 | } | 4670 | } |
4509 | 4671 | ||
4510 | lpfc_unreg_vfi(mbox, phba->pport); | 4672 | lpfc_unreg_vfi(mbox, phba->pport); |
@@ -4514,58 +4676,163 @@ lpfc_unregister_unused_fcf(struct lpfc_hba *phba) | |||
4514 | rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT); | 4676 | rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT); |
4515 | if (rc == MBX_NOT_FINISHED) { | 4677 | if (rc == MBX_NOT_FINISHED) { |
4516 | lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY|LOG_MBOX, | 4678 | lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY|LOG_MBOX, |
4517 | "2557 UNREG_VFI issue mbox failed rc x%x " | 4679 | "2557 UNREG_VFI issue mbox failed rc x%x " |
4518 | "HBA state x%x\n", | 4680 | "HBA state x%x\n", |
4519 | rc, phba->pport->port_state); | 4681 | rc, phba->pport->port_state); |
4520 | mempool_free(mbox, phba->mbox_mem_pool); | 4682 | mempool_free(mbox, phba->mbox_mem_pool); |
4521 | return; | 4683 | return -EIO; |
4522 | } | 4684 | } |
4523 | 4685 | ||
4524 | /* Unregister FCF */ | 4686 | shost = lpfc_shost_from_vport(phba->pport); |
4687 | spin_lock_irq(shost->host_lock); | ||
4688 | phba->pport->fc_flag &= ~FC_VFI_REGISTERED; | ||
4689 | spin_unlock_irq(shost->host_lock); | ||
4690 | |||
4691 | return 0; | ||
4692 | } | ||
4693 | |||
4694 | /** | ||
4695 | * lpfc_sli4_unregister_fcf - Unregister currently registered FCF record | ||
4696 | * @phba: Pointer to hba context object. | ||
4697 | * | ||
4698 | * This function issues synchronous unregister FCF mailbox command to HBA to | ||
4699 | * unregister the currently registered FCF record. The driver does not reset | ||
4700 | * the driver FCF usage state flags. | ||
4701 | * | ||
4702 | * Return 0 if successfully issued, none-zero otherwise. | ||
4703 | */ | ||
4704 | int | ||
4705 | lpfc_sli4_unregister_fcf(struct lpfc_hba *phba) | ||
4706 | { | ||
4707 | LPFC_MBOXQ_t *mbox; | ||
4708 | int rc; | ||
4709 | |||
4525 | mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | 4710 | mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
4526 | if (!mbox) { | 4711 | if (!mbox) { |
4527 | lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY|LOG_MBOX, | 4712 | lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY|LOG_MBOX, |
4528 | "2551 UNREG_FCFI mbox allocation failed" | 4713 | "2551 UNREG_FCFI mbox allocation failed" |
4529 | "HBA state x%x\n", | 4714 | "HBA state x%x\n", phba->pport->port_state); |
4530 | phba->pport->port_state); | 4715 | return -ENOMEM; |
4531 | return; | ||
4532 | } | 4716 | } |
4533 | |||
4534 | lpfc_unreg_fcfi(mbox, phba->fcf.fcfi); | 4717 | lpfc_unreg_fcfi(mbox, phba->fcf.fcfi); |
4535 | mbox->vport = phba->pport; | 4718 | mbox->vport = phba->pport; |
4536 | mbox->mbox_cmpl = lpfc_unregister_fcfi_cmpl; | 4719 | mbox->mbox_cmpl = lpfc_unregister_fcfi_cmpl; |
4537 | rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT); | 4720 | rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT); |
4538 | 4721 | ||
4539 | if (rc == MBX_NOT_FINISHED) { | 4722 | if (rc == MBX_NOT_FINISHED) { |
4540 | lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY|LOG_MBOX, | 4723 | lpfc_printf_log(phba, KERN_ERR, LOG_SLI, |
4541 | "2552 UNREG_FCFI issue mbox failed rc x%x " | 4724 | "2552 Unregister FCFI command failed rc x%x " |
4542 | "HBA state x%x\n", | 4725 | "HBA state x%x\n", |
4543 | rc, phba->pport->port_state); | 4726 | rc, phba->pport->port_state); |
4544 | mempool_free(mbox, phba->mbox_mem_pool); | 4727 | return -EINVAL; |
4728 | } | ||
4729 | return 0; | ||
4730 | } | ||
4731 | |||
4732 | /** | ||
4733 | * lpfc_unregister_fcf_rescan - Unregister currently registered fcf and rescan | ||
4734 | * @phba: Pointer to hba context object. | ||
4735 | * | ||
4736 | * This function unregisters the currently reigstered FCF. This function | ||
4737 | * also tries to find another FCF for discovery by rescan the HBA FCF table. | ||
4738 | */ | ||
4739 | void | ||
4740 | lpfc_unregister_fcf_rescan(struct lpfc_hba *phba) | ||
4741 | { | ||
4742 | int rc; | ||
4743 | |||
4744 | /* Preparation for unregistering fcf */ | ||
4745 | rc = lpfc_unregister_fcf_prep(phba); | ||
4746 | if (rc) { | ||
4747 | lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY, | ||
4748 | "2748 Failed to prepare for unregistering " | ||
4749 | "HBA's FCF record: rc=%d\n", rc); | ||
4545 | return; | 4750 | return; |
4546 | } | 4751 | } |
4547 | 4752 | ||
4548 | spin_lock_irq(&phba->hbalock); | 4753 | /* Now, unregister FCF record and reset HBA FCF state */ |
4549 | phba->fcf.fcf_flag &= ~(FCF_AVAILABLE | FCF_REGISTERED | | 4754 | rc = lpfc_sli4_unregister_fcf(phba); |
4550 | FCF_DISCOVERED | FCF_BOOT_ENABLE | FCF_IN_USE | | 4755 | if (rc) |
4551 | FCF_VALID_VLAN); | 4756 | return; |
4552 | spin_unlock_irq(&phba->hbalock); | 4757 | /* Reset HBA FCF states after successful unregister FCF */ |
4758 | phba->fcf.fcf_flag = 0; | ||
4553 | 4759 | ||
4554 | /* | 4760 | /* |
4555 | * If driver is not unloading, check if there is any other | 4761 | * If driver is not unloading, check if there is any other |
4556 | * FCF record that can be used for discovery. | 4762 | * FCF record that can be used for discovery. |
4557 | */ | 4763 | */ |
4558 | if ((phba->pport->load_flag & FC_UNLOADING) || | 4764 | if ((phba->pport->load_flag & FC_UNLOADING) || |
4559 | (phba->link_state < LPFC_LINK_UP)) | 4765 | (phba->link_state < LPFC_LINK_UP)) |
4560 | return; | 4766 | return; |
4561 | 4767 | ||
4562 | rc = lpfc_sli4_read_fcf_record(phba, LPFC_FCOE_FCF_GET_FIRST); | 4768 | rc = lpfc_sli4_read_fcf_record(phba, LPFC_FCOE_FCF_GET_FIRST); |
4563 | 4769 | ||
4564 | if (rc) | 4770 | if (rc) |
4565 | lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY|LOG_MBOX, | 4771 | lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY|LOG_MBOX, |
4566 | "2553 lpfc_unregister_unused_fcf failed to read FCF" | 4772 | "2553 lpfc_unregister_unused_fcf failed " |
4567 | " record HBA state x%x\n", | 4773 | "to read FCF record HBA state x%x\n", |
4568 | phba->pport->port_state); | 4774 | phba->pport->port_state); |
4775 | } | ||
4776 | |||
4777 | /** | ||
4778 | * lpfc_unregister_fcf - Unregister the currently registered fcf record | ||
4779 | * @phba: Pointer to hba context object. | ||
4780 | * | ||
4781 | * This function just unregisters the currently reigstered FCF. It does not | ||
4782 | * try to find another FCF for discovery. | ||
4783 | */ | ||
4784 | void | ||
4785 | lpfc_unregister_fcf(struct lpfc_hba *phba) | ||
4786 | { | ||
4787 | int rc; | ||
4788 | |||
4789 | /* Preparation for unregistering fcf */ | ||
4790 | rc = lpfc_unregister_fcf_prep(phba); | ||
4791 | if (rc) { | ||
4792 | lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY, | ||
4793 | "2749 Failed to prepare for unregistering " | ||
4794 | "HBA's FCF record: rc=%d\n", rc); | ||
4795 | return; | ||
4796 | } | ||
4797 | |||
4798 | /* Now, unregister FCF record and reset HBA FCF state */ | ||
4799 | rc = lpfc_sli4_unregister_fcf(phba); | ||
4800 | if (rc) | ||
4801 | return; | ||
4802 | /* Set proper HBA FCF states after successful unregister FCF */ | ||
4803 | spin_lock_irq(&phba->hbalock); | ||
4804 | phba->fcf.fcf_flag &= ~FCF_REGISTERED; | ||
4805 | spin_unlock_irq(&phba->hbalock); | ||
4806 | } | ||
4807 | |||
4808 | /** | ||
4809 | * lpfc_unregister_unused_fcf - Unregister FCF if all devices are disconnected. | ||
4810 | * @phba: Pointer to hba context object. | ||
4811 | * | ||
4812 | * This function check if there are any connected remote port for the FCF and | ||
4813 | * if all the devices are disconnected, this function unregister FCFI. | ||
4814 | * This function also tries to use another FCF for discovery. | ||
4815 | */ | ||
4816 | void | ||
4817 | lpfc_unregister_unused_fcf(struct lpfc_hba *phba) | ||
4818 | { | ||
4819 | /* | ||
4820 | * If HBA is not running in FIP mode or if HBA does not support | ||
4821 | * FCoE or if FCF is not registered, do nothing. | ||
4822 | */ | ||
4823 | spin_lock_irq(&phba->hbalock); | ||
4824 | if (!(phba->hba_flag & HBA_FCOE_SUPPORT) || | ||
4825 | !(phba->fcf.fcf_flag & FCF_REGISTERED) || | ||
4826 | !(phba->hba_flag & HBA_FIP_SUPPORT)) { | ||
4827 | spin_unlock_irq(&phba->hbalock); | ||
4828 | return; | ||
4829 | } | ||
4830 | spin_unlock_irq(&phba->hbalock); | ||
4831 | |||
4832 | if (lpfc_fcf_inuse(phba)) | ||
4833 | return; | ||
4834 | |||
4835 | lpfc_unregister_fcf_rescan(phba); | ||
4569 | } | 4836 | } |
4570 | 4837 | ||
4571 | /** | 4838 | /** |