aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoe Eykholt <jeykholt@cisco.com>2009-11-03 14:49:27 -0500
committerJames Bottomley <James.Bottomley@suse.de>2009-12-04 13:01:20 -0500
commitab593b187391bdd03ccad2968972a2e118a88cd4 (patch)
treef1fb209ae42b19c6e9065ae8db37776c1bb39558
parent78112e5558064cb4d2e355aed87b2036fcdfe3dd (diff)
[SCSI] libfc: register FC4 features with the FC switch
Customers and certification tests have pointed out that we don't show up on the switch management software as an initiator. On some MDS switches 'show fcns database' command shows libfc initiators as 'fcp' not 'fcp:init' like other initiators. On others switches, I think the switch gets the features by doing a PRLI, but it may be only certain models or under certain configurations. Fix this by registering our FC4 features with the RFF_ID CT request after local port login and after the RFT_ID. 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>
-rw-r--r--drivers/scsi/libfc/fc_lport.c12
-rw-r--r--include/scsi/fc/fc_fcp.h6
-rw-r--r--include/scsi/fc/fc_ns.h13
-rw-r--r--include/scsi/fc_encode.h12
-rw-r--r--include/scsi/libfc.h2
5 files changed, 43 insertions, 2 deletions
diff --git a/drivers/scsi/libfc/fc_lport.c b/drivers/scsi/libfc/fc_lport.c
index d3aec1959394..1bcc5e11d2c0 100644
--- a/drivers/scsi/libfc/fc_lport.c
+++ b/drivers/scsi/libfc/fc_lport.c
@@ -122,6 +122,7 @@ static const char *fc_lport_state_names[] = {
122 [LPORT_ST_RSNN_NN] = "RSNN_NN", 122 [LPORT_ST_RSNN_NN] = "RSNN_NN",
123 [LPORT_ST_RSPN_ID] = "RSPN_ID", 123 [LPORT_ST_RSPN_ID] = "RSPN_ID",
124 [LPORT_ST_RFT_ID] = "RFT_ID", 124 [LPORT_ST_RFT_ID] = "RFT_ID",
125 [LPORT_ST_RFF_ID] = "RFF_ID",
125 [LPORT_ST_SCR] = "SCR", 126 [LPORT_ST_SCR] = "SCR",
126 [LPORT_ST_READY] = "Ready", 127 [LPORT_ST_READY] = "Ready",
127 [LPORT_ST_LOGO] = "LOGO", 128 [LPORT_ST_LOGO] = "LOGO",
@@ -1034,6 +1035,7 @@ static void fc_lport_error(struct fc_lport *lport, struct fc_frame *fp)
1034 case LPORT_ST_RSNN_NN: 1035 case LPORT_ST_RSNN_NN:
1035 case LPORT_ST_RSPN_ID: 1036 case LPORT_ST_RSPN_ID:
1036 case LPORT_ST_RFT_ID: 1037 case LPORT_ST_RFT_ID:
1038 case LPORT_ST_RFF_ID:
1037 case LPORT_ST_SCR: 1039 case LPORT_ST_SCR:
1038 case LPORT_ST_DNS: 1040 case LPORT_ST_DNS:
1039 case LPORT_ST_FLOGI: 1041 case LPORT_ST_FLOGI:
@@ -1070,7 +1072,7 @@ static void fc_lport_ns_resp(struct fc_seq *sp, struct fc_frame *fp,
1070 1072
1071 mutex_lock(&lport->lp_mutex); 1073 mutex_lock(&lport->lp_mutex);
1072 1074
1073 if (lport->state < LPORT_ST_RNN_ID || lport->state > LPORT_ST_RFT_ID) { 1075 if (lport->state < LPORT_ST_RNN_ID || lport->state > LPORT_ST_RFF_ID) {
1074 FC_LPORT_DBG(lport, "Received a name server response, " 1076 FC_LPORT_DBG(lport, "Received a name server response, "
1075 "but in state %s\n", fc_lport_state(lport)); 1077 "but in state %s\n", fc_lport_state(lport));
1076 if (IS_ERR(fp)) 1078 if (IS_ERR(fp))
@@ -1101,6 +1103,9 @@ static void fc_lport_ns_resp(struct fc_seq *sp, struct fc_frame *fp,
1101 fc_lport_enter_ns(lport, LPORT_ST_RFT_ID); 1103 fc_lport_enter_ns(lport, LPORT_ST_RFT_ID);
1102 break; 1104 break;
1103 case LPORT_ST_RFT_ID: 1105 case LPORT_ST_RFT_ID:
1106 fc_lport_enter_ns(lport, LPORT_ST_RFF_ID);
1107 break;
1108 case LPORT_ST_RFF_ID:
1104 fc_lport_enter_scr(lport); 1109 fc_lport_enter_scr(lport);
1105 break; 1110 break;
1106 default: 1111 default:
@@ -1235,6 +1240,10 @@ static void fc_lport_enter_ns(struct fc_lport *lport, enum fc_lport_state state)
1235 cmd = FC_NS_RFT_ID; 1240 cmd = FC_NS_RFT_ID;
1236 size += sizeof(struct fc_ns_rft); 1241 size += sizeof(struct fc_ns_rft);
1237 break; 1242 break;
1243 case LPORT_ST_RFF_ID:
1244 cmd = FC_NS_RFF_ID;
1245 size += sizeof(struct fc_ns_rff_id);
1246 break;
1238 default: 1247 default:
1239 fc_lport_error(lport, NULL); 1248 fc_lport_error(lport, NULL);
1240 return; 1249 return;
@@ -1317,6 +1326,7 @@ static void fc_lport_timeout(struct work_struct *work)
1317 case LPORT_ST_RSNN_NN: 1326 case LPORT_ST_RSNN_NN:
1318 case LPORT_ST_RSPN_ID: 1327 case LPORT_ST_RSPN_ID:
1319 case LPORT_ST_RFT_ID: 1328 case LPORT_ST_RFT_ID:
1329 case LPORT_ST_RFF_ID:
1320 fc_lport_enter_ns(lport, lport->state); 1330 fc_lport_enter_ns(lport, lport->state);
1321 break; 1331 break;
1322 case LPORT_ST_SCR: 1332 case LPORT_ST_SCR:
diff --git a/include/scsi/fc/fc_fcp.h b/include/scsi/fc/fc_fcp.h
index 5d38f1989f37..29ecb0b02b09 100644
--- a/include/scsi/fc/fc_fcp.h
+++ b/include/scsi/fc/fc_fcp.h
@@ -196,4 +196,10 @@ struct fcp_srr {
196 __u8 srr_resvd2[3]; /* reserved */ 196 __u8 srr_resvd2[3]; /* reserved */
197}; 197};
198 198
199/*
200 * Feature bits in name server FC-4 Features object.
201 */
202#define FCP_FEAT_TARG (1 << 0) /* target function supported */
203#define FCP_FEAT_INIT (1 << 1) /* initiator function supported */
204
199#endif /* _FC_FCP_H_ */ 205#endif /* _FC_FCP_H_ */
diff --git a/include/scsi/fc/fc_ns.h b/include/scsi/fc/fc_ns.h
index f4d354eb26b9..e7d3ac497d7d 100644
--- a/include/scsi/fc/fc_ns.h
+++ b/include/scsi/fc/fc_ns.h
@@ -46,10 +46,11 @@ enum fc_ns_req {
46 FC_NS_GID_FT = 0x0171, /* get IDs by FC4 type */ 46 FC_NS_GID_FT = 0x0171, /* get IDs by FC4 type */
47 FC_NS_GPN_FT = 0x0172, /* get port names by FC4 type */ 47 FC_NS_GPN_FT = 0x0172, /* get port names by FC4 type */
48 FC_NS_GID_PT = 0x01a1, /* get IDs by port type */ 48 FC_NS_GID_PT = 0x01a1, /* get IDs by port type */
49 FC_NS_RFT_ID = 0x0217, /* reg FC4 type for ID */
50 FC_NS_RPN_ID = 0x0212, /* reg port name for ID */ 49 FC_NS_RPN_ID = 0x0212, /* reg port name for ID */
51 FC_NS_RNN_ID = 0x0213, /* reg node name for ID */ 50 FC_NS_RNN_ID = 0x0213, /* reg node name for ID */
51 FC_NS_RFT_ID = 0x0217, /* reg FC4 type for ID */
52 FC_NS_RSPN_ID = 0x0218, /* reg symbolic port name */ 52 FC_NS_RSPN_ID = 0x0218, /* reg symbolic port name */
53 FC_NS_RFF_ID = 0x021f, /* reg FC4 Features for ID */
53 FC_NS_RSNN_NN = 0x0239, /* reg symbolic node name */ 54 FC_NS_RSNN_NN = 0x0239, /* reg symbolic node name */
54}; 55};
55 56
@@ -178,4 +179,14 @@ struct fc_ns_rspn {
178 char fr_name[]; 179 char fr_name[];
179} __attribute__((__packed__)); 180} __attribute__((__packed__));
180 181
182/*
183 * RFF_ID request - register FC-4 Features for ID.
184 */
185struct fc_ns_rff_id {
186 struct fc_ns_fid fr_fid; /* port ID object */
187 __u8 fr_resvd[2];
188 __u8 fr_feat; /* FC-4 Feature bits */
189 __u8 fr_type; /* FC-4 type */
190} __attribute__((__packed__));
191
181#endif /* _FC_NS_H_ */ 192#endif /* _FC_NS_H_ */
diff --git a/include/scsi/fc_encode.h b/include/scsi/fc_encode.h
index ab2260cb149c..8eb0a0fc0a71 100644
--- a/include/scsi/fc_encode.h
+++ b/include/scsi/fc_encode.h
@@ -32,6 +32,7 @@ struct fc_ct_req {
32 struct fc_ns_gid_ft gid; 32 struct fc_ns_gid_ft gid;
33 struct fc_ns_rn_id rn; 33 struct fc_ns_rn_id rn;
34 struct fc_ns_rft rft; 34 struct fc_ns_rft rft;
35 struct fc_ns_rff_id rff;
35 struct fc_ns_fid fid; 36 struct fc_ns_fid fid;
36 struct fc_ns_rsnn snn; 37 struct fc_ns_rsnn snn;
37 struct fc_ns_rspn spn; 38 struct fc_ns_rspn spn;
@@ -131,6 +132,17 @@ static inline int fc_ct_fill(struct fc_lport *lport,
131 ct->payload.rft.fts = lport->fcts; 132 ct->payload.rft.fts = lport->fcts;
132 break; 133 break;
133 134
135 case FC_NS_RFF_ID:
136 ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rff_id));
137 hton24(ct->payload.rff.fr_fid.fp_fid,
138 fc_host_port_id(lport->host));
139 ct->payload.rff.fr_type = FC_TYPE_FCP;
140 if (lport->service_params & FCP_SPPF_INIT_FCN)
141 ct->payload.rff.fr_feat = FCP_FEAT_INIT;
142 if (lport->service_params & FCP_SPPF_TARG_FCN)
143 ct->payload.rff.fr_feat |= FCP_FEAT_TARG;
144 break;
145
134 case FC_NS_RNN_ID: 146 case FC_NS_RNN_ID:
135 ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rn_id)); 147 ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rn_id));
136 hton24(ct->payload.rn.fr_fid.fp_fid, 148 hton24(ct->payload.rn.fr_fid.fp_fid,
diff --git a/include/scsi/libfc.h b/include/scsi/libfc.h
index 67ce9fa1fee4..2936fbae41e4 100644
--- a/include/scsi/libfc.h
+++ b/include/scsi/libfc.h
@@ -62,6 +62,7 @@
62 * @LPORT_ST_DNS: Waiting for name server remote port to become ready 62 * @LPORT_ST_DNS: Waiting for name server remote port to become ready
63 * @LPORT_ST_RPN_ID: Register port name by ID (RPN_ID) sent 63 * @LPORT_ST_RPN_ID: Register port name by ID (RPN_ID) sent
64 * @LPORT_ST_RFT_ID: Register Fibre Channel types by ID (RFT_ID) sent 64 * @LPORT_ST_RFT_ID: Register Fibre Channel types by ID (RFT_ID) sent
65 * @LPORT_ST_RFF_ID: Register FC-4 Features by ID (RFF_ID) sent
65 * @LPORT_ST_SCR: State Change Register (SCR) sent 66 * @LPORT_ST_SCR: State Change Register (SCR) sent
66 * @LPORT_ST_READY: Ready for use 67 * @LPORT_ST_READY: Ready for use
67 * @LPORT_ST_LOGO: Local port logout (LOGO) sent 68 * @LPORT_ST_LOGO: Local port logout (LOGO) sent
@@ -75,6 +76,7 @@ enum fc_lport_state {
75 LPORT_ST_RSNN_NN, 76 LPORT_ST_RSNN_NN,
76 LPORT_ST_RSPN_ID, 77 LPORT_ST_RSPN_ID,
77 LPORT_ST_RFT_ID, 78 LPORT_ST_RFT_ID,
79 LPORT_ST_RFF_ID,
78 LPORT_ST_SCR, 80 LPORT_ST_SCR,
79 LPORT_ST_READY, 81 LPORT_ST_READY,
80 LPORT_ST_LOGO, 82 LPORT_ST_LOGO,