| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Copyright(c) 2007 - 2008 Intel Corporation. All rights reserved. |
|---|
| 3 | | - * |
|---|
| 4 | | - * This program is free software; you can redistribute it and/or modify it |
|---|
| 5 | | - * under the terms and conditions of the GNU General Public License, |
|---|
| 6 | | - * version 2, as published by the Free Software Foundation. |
|---|
| 7 | | - * |
|---|
| 8 | | - * This program is distributed in the hope it will be useful, but WITHOUT |
|---|
| 9 | | - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|---|
| 10 | | - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
|---|
| 11 | | - * more details. |
|---|
| 12 | | - * |
|---|
| 13 | | - * You should have received a copy of the GNU General Public License along with |
|---|
| 14 | | - * this program; if not, write to the Free Software Foundation, Inc., |
|---|
| 15 | | - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. |
|---|
| 16 | 4 | * |
|---|
| 17 | 5 | * Maintained at www.Open-FCoE.org |
|---|
| 18 | 6 | */ |
|---|
| .. | .. |
|---|
| 133 | 121 | /** |
|---|
| 134 | 122 | * fc_rport_create() - Create a new remote port |
|---|
| 135 | 123 | * @lport: The local port this remote port will be associated with |
|---|
| 136 | | - * @ids: The identifiers for the new remote port |
|---|
| 124 | + * @port_id: The identifiers for the new remote port |
|---|
| 137 | 125 | * |
|---|
| 138 | 126 | * The remote port will start in the INIT state. |
|---|
| 139 | 127 | */ |
|---|
| .. | .. |
|---|
| 647 | 635 | fc_rport_enter_ready(rdata); |
|---|
| 648 | 636 | break; |
|---|
| 649 | 637 | case RPORT_ST_PRLI: |
|---|
| 638 | + fc_rport_enter_plogi(rdata); |
|---|
| 639 | + break; |
|---|
| 650 | 640 | case RPORT_ST_ADISC: |
|---|
| 651 | 641 | fc_rport_enter_logo(rdata); |
|---|
| 652 | 642 | break; |
|---|
| .. | .. |
|---|
| 865 | 855 | static void fc_rport_recv_flogi_req(struct fc_lport *lport, |
|---|
| 866 | 856 | struct fc_frame *rx_fp) |
|---|
| 867 | 857 | { |
|---|
| 868 | | - struct fc_disc *disc; |
|---|
| 869 | 858 | struct fc_els_flogi *flp; |
|---|
| 870 | 859 | struct fc_rport_priv *rdata; |
|---|
| 871 | 860 | struct fc_frame *fp = rx_fp; |
|---|
| .. | .. |
|---|
| 876 | 865 | |
|---|
| 877 | 866 | FC_RPORT_ID_DBG(lport, sid, "Received FLOGI request\n"); |
|---|
| 878 | 867 | |
|---|
| 879 | | - disc = &lport->disc; |
|---|
| 880 | 868 | if (!lport->point_to_multipoint) { |
|---|
| 881 | 869 | rjt_data.reason = ELS_RJT_UNSUP; |
|---|
| 882 | 870 | rjt_data.explan = ELS_EXPL_NONE; |
|---|
| .. | .. |
|---|
| 1043 | 1031 | struct fc_els_ls_rjt *rjt; |
|---|
| 1044 | 1032 | |
|---|
| 1045 | 1033 | rjt = fc_frame_payload_get(fp, sizeof(*rjt)); |
|---|
| 1046 | | - FC_RPORT_DBG(rdata, "PLOGI ELS rejected, reason %x expl %x\n", |
|---|
| 1047 | | - rjt->er_reason, rjt->er_explan); |
|---|
| 1034 | + if (!rjt) |
|---|
| 1035 | + FC_RPORT_DBG(rdata, "PLOGI bad response\n"); |
|---|
| 1036 | + else |
|---|
| 1037 | + FC_RPORT_DBG(rdata, "PLOGI ELS rejected, reason %x expl %x\n", |
|---|
| 1038 | + rjt->er_reason, rjt->er_explan); |
|---|
| 1048 | 1039 | fc_rport_error_retry(rdata, -FC_EX_ELS_RJT); |
|---|
| 1049 | 1040 | } |
|---|
| 1050 | 1041 | out: |
|---|
| .. | .. |
|---|
| 1163 | 1154 | op = fc_frame_payload_op(fp); |
|---|
| 1164 | 1155 | if (op == ELS_LS_ACC) { |
|---|
| 1165 | 1156 | pp = fc_frame_payload_get(fp, sizeof(*pp)); |
|---|
| 1166 | | - if (!pp) |
|---|
| 1157 | + if (!pp) { |
|---|
| 1158 | + fc_rport_error_retry(rdata, -FC_EX_SEQ_ERR); |
|---|
| 1167 | 1159 | goto out; |
|---|
| 1160 | + } |
|---|
| 1168 | 1161 | |
|---|
| 1169 | 1162 | resp_code = (pp->spp.spp_flags & FC_SPP_RESP_MASK); |
|---|
| 1170 | 1163 | FC_RPORT_DBG(rdata, "PRLI spp_flags = 0x%x spp_type 0x%x\n", |
|---|
| .. | .. |
|---|
| 1178 | 1171 | fc_rport_error_retry(rdata, -FC_EX_SEQ_ERR); |
|---|
| 1179 | 1172 | goto out; |
|---|
| 1180 | 1173 | } |
|---|
| 1181 | | - if (pp->prli.prli_spp_len < sizeof(pp->spp)) |
|---|
| 1174 | + if (pp->prli.prli_spp_len < sizeof(pp->spp)) { |
|---|
| 1175 | + fc_rport_error_retry(rdata, -FC_EX_SEQ_ERR); |
|---|
| 1182 | 1176 | goto out; |
|---|
| 1177 | + } |
|---|
| 1183 | 1178 | |
|---|
| 1184 | 1179 | fcp_parm = ntohl(pp->spp.spp_params); |
|---|
| 1185 | 1180 | if (fcp_parm & FCP_SPPF_RETRY) |
|---|
| .. | .. |
|---|
| 1219 | 1214 | |
|---|
| 1220 | 1215 | } else { |
|---|
| 1221 | 1216 | rjt = fc_frame_payload_get(fp, sizeof(*rjt)); |
|---|
| 1222 | | - FC_RPORT_DBG(rdata, "PRLI ELS rejected, reason %x expl %x\n", |
|---|
| 1223 | | - rjt->er_reason, rjt->er_explan); |
|---|
| 1217 | + if (!rjt) |
|---|
| 1218 | + FC_RPORT_DBG(rdata, "PRLI bad response\n"); |
|---|
| 1219 | + else { |
|---|
| 1220 | + FC_RPORT_DBG(rdata, "PRLI ELS rejected, reason %x expl %x\n", |
|---|
| 1221 | + rjt->er_reason, rjt->er_explan); |
|---|
| 1222 | + if (rjt->er_reason == ELS_RJT_UNAB && |
|---|
| 1223 | + rjt->er_explan == ELS_EXPL_PLOGI_REQD) { |
|---|
| 1224 | + fc_rport_enter_plogi(rdata); |
|---|
| 1225 | + goto out; |
|---|
| 1226 | + } |
|---|
| 1227 | + } |
|---|
| 1224 | 1228 | fc_rport_error_retry(rdata, FC_EX_ELS_RJT); |
|---|
| 1225 | 1229 | } |
|---|
| 1226 | 1230 | |
|---|
| .. | .. |
|---|
| 1444 | 1448 | * fc_rport_logo_resp() - Handler for logout (LOGO) responses |
|---|
| 1445 | 1449 | * @sp: The sequence the LOGO was on |
|---|
| 1446 | 1450 | * @fp: The LOGO response frame |
|---|
| 1447 | | - * @lport_arg: The local port |
|---|
| 1451 | + * @rdata_arg: The remote port |
|---|
| 1448 | 1452 | */ |
|---|
| 1449 | 1453 | static void fc_rport_logo_resp(struct fc_seq *sp, struct fc_frame *fp, |
|---|
| 1450 | 1454 | void *rdata_arg) |
|---|
| .. | .. |
|---|
| 1722 | 1726 | kref_put(&rdata->kref, fc_rport_destroy); |
|---|
| 1723 | 1727 | goto busy; |
|---|
| 1724 | 1728 | } |
|---|
| 1729 | + fallthrough; |
|---|
| 1725 | 1730 | default: |
|---|
| 1726 | 1731 | FC_RPORT_DBG(rdata, |
|---|
| 1727 | 1732 | "Reject ELS 0x%02x while in state %s\n", |
|---|