aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/libfc/fc_rport.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/libfc/fc_rport.c')
-rw-r--r--drivers/scsi/libfc/fc_rport.c48
1 files changed, 48 insertions, 0 deletions
diff --git a/drivers/scsi/libfc/fc_rport.c b/drivers/scsi/libfc/fc_rport.c
index c33e25851082..03ea6748e7ee 100644
--- a/drivers/scsi/libfc/fc_rport.c
+++ b/drivers/scsi/libfc/fc_rport.c
@@ -1012,6 +1012,50 @@ static void fc_rport_enter_adisc(struct fc_rport_priv *rdata)
1012} 1012}
1013 1013
1014/** 1014/**
1015 * fc_rport_recv_adisc_req() - Handle incoming Address Discovery (ADISC) Request
1016 * @rdata: remote port private
1017 * @sp: current sequence in the ADISC exchange
1018 * @in_fp: ADISC request frame
1019 *
1020 * Locking Note: Called with the lport and rport locks held.
1021 */
1022static void fc_rport_recv_adisc_req(struct fc_rport_priv *rdata,
1023 struct fc_seq *sp, struct fc_frame *in_fp)
1024{
1025 struct fc_lport *lport = rdata->local_port;
1026 struct fc_frame *fp;
1027 struct fc_exch *ep = fc_seq_exch(sp);
1028 struct fc_els_adisc *adisc;
1029 struct fc_seq_els_data rjt_data;
1030 u32 f_ctl;
1031
1032 FC_RPORT_DBG(rdata, "Received ADISC request\n");
1033
1034 adisc = fc_frame_payload_get(in_fp, sizeof(*adisc));
1035 if (!adisc) {
1036 rjt_data.fp = NULL;
1037 rjt_data.reason = ELS_RJT_PROT;
1038 rjt_data.explan = ELS_EXPL_INV_LEN;
1039 lport->tt.seq_els_rsp_send(sp, ELS_LS_RJT, &rjt_data);
1040 goto drop;
1041 }
1042
1043 fp = fc_frame_alloc(lport, sizeof(*adisc));
1044 if (!fp)
1045 goto drop;
1046 fc_adisc_fill(lport, fp);
1047 adisc = fc_frame_payload_get(fp, sizeof(*adisc));
1048 adisc->adisc_cmd = ELS_LS_ACC;
1049 sp = lport->tt.seq_start_next(sp);
1050 f_ctl = FC_FC_EX_CTX | FC_FC_LAST_SEQ | FC_FC_END_SEQ | FC_FC_SEQ_INIT;
1051 fc_fill_fc_hdr(fp, FC_RCTL_ELS_REP, ep->did, ep->sid,
1052 FC_TYPE_ELS, f_ctl, 0);
1053 lport->tt.seq_send(lport, sp, fp);
1054drop:
1055 fc_frame_free(in_fp);
1056}
1057
1058/**
1015 * fc_rport_recv_els_req() - handle a validated ELS request. 1059 * fc_rport_recv_els_req() - handle a validated ELS request.
1016 * @lport: Fibre Channel local port 1060 * @lport: Fibre Channel local port
1017 * @sp: current sequence in the PLOGI exchange 1061 * @sp: current sequence in the PLOGI exchange
@@ -1062,6 +1106,9 @@ static void fc_rport_recv_els_req(struct fc_lport *lport,
1062 case ELS_PRLO: 1106 case ELS_PRLO:
1063 fc_rport_recv_prlo_req(rdata, sp, fp); 1107 fc_rport_recv_prlo_req(rdata, sp, fp);
1064 break; 1108 break;
1109 case ELS_ADISC:
1110 fc_rport_recv_adisc_req(rdata, sp, fp);
1111 break;
1065 case ELS_RRQ: 1112 case ELS_RRQ:
1066 els_data.fp = fp; 1113 els_data.fp = fp;
1067 lport->tt.seq_els_rsp_send(sp, ELS_RRQ, &els_data); 1114 lport->tt.seq_els_rsp_send(sp, ELS_RRQ, &els_data);
@@ -1111,6 +1158,7 @@ void fc_rport_recv_req(struct fc_seq *sp, struct fc_frame *fp,
1111 break; 1158 break;
1112 case ELS_PRLI: 1159 case ELS_PRLI:
1113 case ELS_PRLO: 1160 case ELS_PRLO:
1161 case ELS_ADISC:
1114 case ELS_RRQ: 1162 case ELS_RRQ:
1115 case ELS_REC: 1163 case ELS_REC:
1116 fc_rport_recv_els_req(lport, sp, fp); 1164 fc_rport_recv_els_req(lport, sp, fp);