aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/libfc
diff options
context:
space:
mode:
authorJoe Eykholt <jeykholt@cisco.com>2011-01-28 19:04:23 -0500
committerJames Bottomley <James.Bottomley@suse.de>2011-02-12 12:02:22 -0500
commit925cedae2b223d44d59a02df1b35902fc8bdd6d2 (patch)
tree4fe2398d8761fd967a3ade45265ac6ce46319e9e /drivers/scsi/libfc
parent70d53b046a6221e3ceb3bd8eaa807ef6a1c53762 (diff)
[SCSI] libfc: use PRLI hook to get parameters when sending outgoing PRLI
When sending an outgoing PRLI as an initiator, get the parameters from registered providers so that they all get a chance to decide on roles. The passive provider is called last, and could override the initiator role. Signed-off-by: Joe Eykholt <jeykholt@cisco.com> Signed-off-by: Robert Love <robert.w.love@intel.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/libfc')
-rw-r--r--drivers/scsi/libfc/fc_rport.c27
1 files changed, 24 insertions, 3 deletions
diff --git a/drivers/scsi/libfc/fc_rport.c b/drivers/scsi/libfc/fc_rport.c
index a92954c1f42..9ded6123ff6 100644
--- a/drivers/scsi/libfc/fc_rport.c
+++ b/drivers/scsi/libfc/fc_rport.c
@@ -961,6 +961,8 @@ static void fc_rport_prli_resp(struct fc_seq *sp, struct fc_frame *fp,
961 struct fc_els_prli prli; 961 struct fc_els_prli prli;
962 struct fc_els_spp spp; 962 struct fc_els_spp spp;
963 } *pp; 963 } *pp;
964 struct fc_els_spp temp_spp;
965 struct fc4_prov *prov;
964 u32 roles = FC_RPORT_ROLE_UNKNOWN; 966 u32 roles = FC_RPORT_ROLE_UNKNOWN;
965 u32 fcp_parm = 0; 967 u32 fcp_parm = 0;
966 u8 op; 968 u8 op;
@@ -1009,6 +1011,13 @@ static void fc_rport_prli_resp(struct fc_seq *sp, struct fc_frame *fp,
1009 if (fcp_parm & FCP_SPPF_RETRY) 1011 if (fcp_parm & FCP_SPPF_RETRY)
1010 rdata->flags |= FC_RP_FLAGS_RETRY; 1012 rdata->flags |= FC_RP_FLAGS_RETRY;
1011 1013
1014 prov = fc_passive_prov[FC_TYPE_FCP];
1015 if (prov) {
1016 memset(&temp_spp, 0, sizeof(temp_spp));
1017 prov->prli(rdata, pp->prli.prli_spp_len,
1018 &pp->spp, &temp_spp);
1019 }
1020
1012 rdata->supported_classes = FC_COS_CLASS3; 1021 rdata->supported_classes = FC_COS_CLASS3;
1013 if (fcp_parm & FCP_SPPF_INIT_FCN) 1022 if (fcp_parm & FCP_SPPF_INIT_FCN)
1014 roles |= FC_RPORT_ROLE_FCP_INITIATOR; 1023 roles |= FC_RPORT_ROLE_FCP_INITIATOR;
@@ -1045,6 +1054,7 @@ static void fc_rport_enter_prli(struct fc_rport_priv *rdata)
1045 struct fc_els_spp spp; 1054 struct fc_els_spp spp;
1046 } *pp; 1055 } *pp;
1047 struct fc_frame *fp; 1056 struct fc_frame *fp;
1057 struct fc4_prov *prov;
1048 1058
1049 /* 1059 /*
1050 * If the rport is one of the well known addresses 1060 * If the rport is one of the well known addresses
@@ -1066,9 +1076,20 @@ static void fc_rport_enter_prli(struct fc_rport_priv *rdata)
1066 return; 1076 return;
1067 } 1077 }
1068 1078
1069 if (!lport->tt.elsct_send(lport, rdata->ids.port_id, fp, ELS_PRLI, 1079 fc_prli_fill(lport, fp);
1070 fc_rport_prli_resp, rdata, 1080
1071 2 * lport->r_a_tov)) 1081 prov = fc_passive_prov[FC_TYPE_FCP];
1082 if (prov) {
1083 pp = fc_frame_payload_get(fp, sizeof(*pp));
1084 prov->prli(rdata, sizeof(pp->spp), NULL, &pp->spp);
1085 }
1086
1087 fc_fill_fc_hdr(fp, FC_RCTL_ELS_REQ, rdata->ids.port_id,
1088 fc_host_port_id(lport->host), FC_TYPE_ELS,
1089 FC_FC_FIRST_SEQ | FC_FC_END_SEQ | FC_FC_SEQ_INIT, 0);
1090
1091 if (!lport->tt.exch_seq_send(lport, fp, fc_rport_prli_resp,
1092 NULL, rdata, 2 * lport->r_a_tov))
1072 fc_rport_error_retry(rdata, NULL); 1093 fc_rport_error_retry(rdata, NULL);
1073 else 1094 else
1074 kref_get(&rdata->kref); 1095 kref_get(&rdata->kref);