Skip to content

Commit c9866a5

Browse files
Chris LeechJames Bottomley
authored andcommitted
[SCSI] libfc: Register Symbolic Port Name (RSPN_ID)
Register the fc_host symbolic name as the symbolic port name with the fabric name server. Signed-off-by: Chris Leech <christopher.leech@intel.com> Signed-off-by: Robert Love <robert.w.love@intel.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
1 parent 5baa17c commit c9866a5

4 files changed

Lines changed: 112 additions & 0 deletions

File tree

drivers/scsi/libfc/fc_lport.c

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ static void fc_lport_enter_flogi(struct fc_lport *);
110110
static void fc_lport_enter_dns(struct fc_lport *);
111111
static void fc_lport_enter_rnn_id(struct fc_lport *);
112112
static void fc_lport_enter_rsnn_nn(struct fc_lport *);
113+
static void fc_lport_enter_rspn_id(struct fc_lport *);
113114
static void fc_lport_enter_rft_id(struct fc_lport *);
114115
static void fc_lport_enter_scr(struct fc_lport *);
115116
static void fc_lport_enter_ready(struct fc_lport *);
@@ -121,6 +122,7 @@ static const char *fc_lport_state_names[] = {
121122
[LPORT_ST_DNS] = "dNS",
122123
[LPORT_ST_RNN_ID] = "RNN_ID",
123124
[LPORT_ST_RSNN_NN] = "RSNN_NN",
125+
[LPORT_ST_RSPN_ID] = "RSPN_ID",
124126
[LPORT_ST_RFT_ID] = "RFT_ID",
125127
[LPORT_ST_SCR] = "SCR",
126128
[LPORT_ST_READY] = "Ready",
@@ -969,6 +971,7 @@ static void fc_lport_error(struct fc_lport *lport, struct fc_frame *fp)
969971
case LPORT_ST_RESET:
970972
case LPORT_ST_RNN_ID:
971973
case LPORT_ST_RSNN_NN:
974+
case LPORT_ST_RSPN_ID:
972975
case LPORT_ST_RFT_ID:
973976
case LPORT_ST_SCR:
974977
case LPORT_ST_DNS:
@@ -1035,6 +1038,59 @@ static void fc_lport_rft_id_resp(struct fc_seq *sp, struct fc_frame *fp,
10351038
mutex_unlock(&lport->lp_mutex);
10361039
}
10371040

1041+
/**
1042+
* fc_lport_rspn_id_resp() - Handle response to Register Symbolic Port Name
1043+
* by ID (RSPN_ID) request
1044+
* @sp: current sequence in RSPN_ID exchange
1045+
* @fp: response frame
1046+
* @lp_arg: Fibre Channel host port instance
1047+
*
1048+
* Locking Note: This function will be called without the lport lock
1049+
* held, but it will lock, call an _enter_* function or fc_lport_error
1050+
* and then unlock the lport.
1051+
*/
1052+
static void fc_lport_rspn_id_resp(struct fc_seq *sp, struct fc_frame *fp,
1053+
void *lp_arg)
1054+
{
1055+
struct fc_lport *lport = lp_arg;
1056+
struct fc_frame_header *fh;
1057+
struct fc_ct_hdr *ct;
1058+
1059+
FC_LPORT_DBG(lport, "Received a RSPN_ID %s\n", fc_els_resp_type(fp));
1060+
1061+
if (fp == ERR_PTR(-FC_EX_CLOSED))
1062+
return;
1063+
1064+
mutex_lock(&lport->lp_mutex);
1065+
1066+
if (lport->state != LPORT_ST_RSPN_ID) {
1067+
FC_LPORT_DBG(lport, "Received a RSPN_ID response, but in state "
1068+
"%s\n", fc_lport_state(lport));
1069+
if (IS_ERR(fp))
1070+
goto err;
1071+
goto out;
1072+
}
1073+
1074+
if (IS_ERR(fp)) {
1075+
fc_lport_error(lport, fp);
1076+
goto err;
1077+
}
1078+
1079+
fh = fc_frame_header_get(fp);
1080+
ct = fc_frame_payload_get(fp, sizeof(*ct));
1081+
if (fh && ct && fh->fh_type == FC_TYPE_CT &&
1082+
ct->ct_fs_type == FC_FST_DIR &&
1083+
ct->ct_fs_subtype == FC_NS_SUBTYPE &&
1084+
ntohs(ct->ct_cmd) == FC_FS_ACC)
1085+
fc_lport_enter_rspn_id(lport);
1086+
else
1087+
fc_lport_error(lport, fp);
1088+
1089+
out:
1090+
fc_frame_free(fp);
1091+
err:
1092+
mutex_unlock(&lport->lp_mutex);
1093+
}
10381094
/**
10391095
* fc_lport_rsnn_nn_resp() - Handle response to Register Symbolic Node Name
10401096
* by Node Name (RSNN_NN) request
@@ -1260,6 +1316,37 @@ static void fc_lport_enter_rft_id(struct fc_lport *lport)
12601316
fc_lport_error(lport, fp);
12611317
}
12621318

1319+
/**
1320+
* fc_rport_enter_rspn_id() - Register symbolic port name with the name server
1321+
* @lport: Fibre Channel local port to register
1322+
*
1323+
* Locking Note: The lport lock is expected to be held before calling
1324+
* this routine.
1325+
*/
1326+
static void fc_lport_enter_rspn_id(struct fc_lport *lport)
1327+
{
1328+
struct fc_frame *fp;
1329+
size_t len;
1330+
1331+
FC_LPORT_DBG(lport, "Entered RSPN_ID state from %s state\n",
1332+
fc_lport_state(lport));
1333+
1334+
fc_lport_state_enter(lport, LPORT_ST_RSPN_ID);
1335+
1336+
len = strnlen(fc_host_symbolic_name(lport->host), 255);
1337+
fp = fc_frame_alloc(lport, sizeof(struct fc_ct_hdr) +
1338+
sizeof(struct fc_ns_rspn) + len);
1339+
if (!fp) {
1340+
fc_lport_error(lport, fp);
1341+
return;
1342+
}
1343+
1344+
if (!lport->tt.elsct_send(lport, FC_FID_DIR_SERV, fp, FC_NS_RSPN_ID,
1345+
fc_lport_rspn_id_resp,
1346+
lport, lport->e_d_tov))
1347+
fc_lport_error(lport, fp);
1348+
}
1349+
12631350
/**
12641351
* fc_rport_enter_rsnn_nn() - Register symbolic node name with the name server
12651352
* @lport: Fibre Channel local port to register
@@ -1387,6 +1474,9 @@ static void fc_lport_timeout(struct work_struct *work)
13871474
case LPORT_ST_RSNN_NN:
13881475
fc_lport_enter_rsnn_nn(lport);
13891476
break;
1477+
case LPORT_ST_RSPN_ID:
1478+
fc_lport_enter_rspn_id(lport);
1479+
break;
13901480
case LPORT_ST_RFT_ID:
13911481
fc_lport_enter_rft_id(lport);
13921482
break;

include/scsi/fc/fc_ns.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ enum fc_ns_req {
4747
FC_NS_RFT_ID = 0x0217, /* reg FC4 type for ID */
4848
FC_NS_RPN_ID = 0x0212, /* reg port name for ID */
4949
FC_NS_RNN_ID = 0x0213, /* reg node name for ID */
50+
FC_NS_RSPN_ID = 0x0218, /* reg symbolic port name */
5051
FC_NS_RSNN_NN = 0x0239, /* reg symbolic node name */
5152
};
5253

@@ -166,4 +167,13 @@ struct fc_ns_rsnn {
166167
char fr_name[];
167168
} __attribute__((__packed__));
168169

170+
/*
171+
* RSPN_ID request - register symbolic port name
172+
*/
173+
struct fc_ns_rspn {
174+
struct fc_ns_fid fr_fid; /* port ID object */
175+
__u8 fr_name_len;
176+
char fr_name[];
177+
} __attribute__((__packed__));
178+
169179
#endif /* _FC_NS_H_ */

include/scsi/fc_encode.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ struct fc_ct_req {
3434
struct fc_ns_rft rft;
3535
struct fc_ns_fid fid;
3636
struct fc_ns_rsnn snn;
37+
struct fc_ns_rspn spn;
3738
} payload;
3839
};
3940

@@ -137,6 +138,16 @@ static inline int fc_ct_fill(struct fc_lport *lport,
137138
put_unaligned_be64(lport->wwnn, &ct->payload.rn.fr_wwn);
138139
break;
139140

141+
case FC_NS_RSPN_ID:
142+
ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rspn));
143+
hton24(ct->payload.spn.fr_fid.fp_fid,
144+
fc_host_port_id(lport->host));
145+
strncpy(ct->payload.spn.fr_name,
146+
fc_host_symbolic_name(lport->host), 255);
147+
ct->payload.spn.fr_name_len =
148+
strnlen(ct->payload.spn.fr_name, 255);
149+
break;
150+
140151
case FC_NS_RSNN_NN:
141152
ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rsnn));
142153
put_unaligned_be64(lport->wwnn, &ct->payload.snn.fr_wwn);

include/scsi/libfc.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ enum fc_lport_state {
6363
LPORT_ST_DNS,
6464
LPORT_ST_RNN_ID,
6565
LPORT_ST_RSNN_NN,
66+
LPORT_ST_RSPN_ID,
6667
LPORT_ST_RFT_ID,
6768
LPORT_ST_SCR,
6869
LPORT_ST_READY,

0 commit comments

Comments
 (0)