1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27#include <linux/kernel.h>
28#include <linux/string.h>
29#include <linux/ctype.h>
30#include <linux/spinlock.h>
31#include <linux/export.h>
32#include <scsi/scsi.h>
33#include <scsi/scsi_cmnd.h>
34
35#include <target/target_core_base.h>
36#include <target/target_core_fabric.h>
37#include <target/target_core_configfs.h>
38
39#include "target_core_internal.h"
40#include "target_core_pr.h"
41
42
43
44
45u8 sas_get_fabric_proto_ident(struct se_portal_group *se_tpg)
46{
47
48
49
50
51 return 0x6;
52}
53EXPORT_SYMBOL(sas_get_fabric_proto_ident);
54
55u32 sas_get_pr_transport_id(
56 struct se_portal_group *se_tpg,
57 struct se_node_acl *se_nacl,
58 struct t10_pr_registration *pr_reg,
59 int *format_code,
60 unsigned char *buf)
61{
62 unsigned char *ptr;
63 int ret;
64
65
66
67
68 buf[0] = 0x06;
69
70
71
72
73 ptr = &se_nacl->initiatorname[4];
74
75 ret = hex2bin(&buf[4], ptr, 8);
76 if (ret < 0)
77 pr_debug("sas transport_id: invalid hex string\n");
78
79
80
81
82 return 24;
83}
84EXPORT_SYMBOL(sas_get_pr_transport_id);
85
86u32 sas_get_pr_transport_id_len(
87 struct se_portal_group *se_tpg,
88 struct se_node_acl *se_nacl,
89 struct t10_pr_registration *pr_reg,
90 int *format_code)
91{
92 *format_code = 0;
93
94
95
96
97
98
99 return 24;
100}
101EXPORT_SYMBOL(sas_get_pr_transport_id_len);
102
103
104
105
106
107char *sas_parse_pr_out_transport_id(
108 struct se_portal_group *se_tpg,
109 const char *buf,
110 u32 *out_tid_len,
111 char **port_nexus_ptr)
112{
113
114
115
116
117
118
119
120
121 *port_nexus_ptr = NULL;
122 *out_tid_len = 24;
123
124 return (char *)&buf[4];
125}
126EXPORT_SYMBOL(sas_parse_pr_out_transport_id);
127
128
129
130
131u8 fc_get_fabric_proto_ident(struct se_portal_group *se_tpg)
132{
133 return 0x0;
134}
135EXPORT_SYMBOL(fc_get_fabric_proto_ident);
136
137u32 fc_get_pr_transport_id_len(
138 struct se_portal_group *se_tpg,
139 struct se_node_acl *se_nacl,
140 struct t10_pr_registration *pr_reg,
141 int *format_code)
142{
143 *format_code = 0;
144
145
146
147 return 24;
148}
149EXPORT_SYMBOL(fc_get_pr_transport_id_len);
150
151u32 fc_get_pr_transport_id(
152 struct se_portal_group *se_tpg,
153 struct se_node_acl *se_nacl,
154 struct t10_pr_registration *pr_reg,
155 int *format_code,
156 unsigned char *buf)
157{
158 unsigned char *ptr;
159 int i, ret;
160 u32 off = 8;
161
162
163
164
165
166
167
168
169
170
171 ptr = &se_nacl->initiatorname[0];
172
173 for (i = 0; i < 24; ) {
174 if (!strncmp(&ptr[i], ":", 1)) {
175 i++;
176 continue;
177 }
178 ret = hex2bin(&buf[off++], &ptr[i], 1);
179 if (ret < 0)
180 pr_debug("fc transport_id: invalid hex string\n");
181 i += 2;
182 }
183
184
185
186 return 24;
187}
188EXPORT_SYMBOL(fc_get_pr_transport_id);
189
190char *fc_parse_pr_out_transport_id(
191 struct se_portal_group *se_tpg,
192 const char *buf,
193 u32 *out_tid_len,
194 char **port_nexus_ptr)
195{
196
197
198
199
200
201 *port_nexus_ptr = NULL;
202 *out_tid_len = 24;
203
204 return (char *)&buf[8];
205}
206EXPORT_SYMBOL(fc_parse_pr_out_transport_id);
207
208
209
210
211
212u8 iscsi_get_fabric_proto_ident(struct se_portal_group *se_tpg)
213{
214
215
216
217
218 return 0x5;
219}
220EXPORT_SYMBOL(iscsi_get_fabric_proto_ident);
221
222u32 iscsi_get_pr_transport_id(
223 struct se_portal_group *se_tpg,
224 struct se_node_acl *se_nacl,
225 struct t10_pr_registration *pr_reg,
226 int *format_code,
227 unsigned char *buf)
228{
229 u32 off = 4, padding = 0;
230 u16 len = 0;
231
232 spin_lock_irq(&se_nacl->nacl_sess_lock);
233
234
235
236 buf[0] = 0x05;
237
238
239
240
241
242
243
244
245
246
247
248 len = sprintf(&buf[off], "%s", se_nacl->initiatorname);
249
250
251
252 len++;
253
254
255
256
257
258
259
260
261 if ((*format_code == 1) && (pr_reg->isid_present_at_reg)) {
262
263
264
265
266 buf[0] |= 0x40;
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281 buf[off+len] = 0x2c; off++;
282 buf[off+len] = 0x69; off++;
283 buf[off+len] = 0x2c; off++;
284 buf[off+len] = 0x30; off++;
285 buf[off+len] = 0x78; off++;
286 len += 5;
287 buf[off+len] = pr_reg->pr_reg_isid[0]; off++;
288 buf[off+len] = pr_reg->pr_reg_isid[1]; off++;
289 buf[off+len] = pr_reg->pr_reg_isid[2]; off++;
290 buf[off+len] = pr_reg->pr_reg_isid[3]; off++;
291 buf[off+len] = pr_reg->pr_reg_isid[4]; off++;
292 buf[off+len] = pr_reg->pr_reg_isid[5]; off++;
293 buf[off+len] = '\0'; off++;
294 len += 7;
295 }
296 spin_unlock_irq(&se_nacl->nacl_sess_lock);
297
298
299
300
301
302 padding = ((-len) & 3);
303 if (padding != 0)
304 len += padding;
305
306 buf[2] = ((len >> 8) & 0xff);
307 buf[3] = (len & 0xff);
308
309
310
311
312 len += 4;
313
314 return len;
315}
316EXPORT_SYMBOL(iscsi_get_pr_transport_id);
317
318u32 iscsi_get_pr_transport_id_len(
319 struct se_portal_group *se_tpg,
320 struct se_node_acl *se_nacl,
321 struct t10_pr_registration *pr_reg,
322 int *format_code)
323{
324 u32 len = 0, padding = 0;
325
326 spin_lock_irq(&se_nacl->nacl_sess_lock);
327 len = strlen(se_nacl->initiatorname);
328
329
330
331 len++;
332
333
334
335
336
337
338
339 if (pr_reg->isid_present_at_reg) {
340 len += 5;
341 len += 7;
342 *format_code = 1;
343 } else
344 *format_code = 0;
345 spin_unlock_irq(&se_nacl->nacl_sess_lock);
346
347
348
349
350
351 padding = ((-len) & 3);
352 if (padding != 0)
353 len += padding;
354
355
356
357
358 len += 4;
359
360 return len;
361}
362EXPORT_SYMBOL(iscsi_get_pr_transport_id_len);
363
364char *iscsi_parse_pr_out_transport_id(
365 struct se_portal_group *se_tpg,
366 const char *buf,
367 u32 *out_tid_len,
368 char **port_nexus_ptr)
369{
370 char *p;
371 u32 tid_len, padding;
372 int i;
373 u16 add_len;
374 u8 format_code = (buf[0] & 0xc0);
375
376
377
378
379
380
381
382
383
384
385
386
387
388 if ((format_code != 0x00) && (format_code != 0x40)) {
389 pr_err("Illegal format code: 0x%02x for iSCSI"
390 " Initiator Transport ID\n", format_code);
391 return NULL;
392 }
393
394
395
396
397 if (out_tid_len != NULL) {
398 add_len = ((buf[2] >> 8) & 0xff);
399 add_len |= (buf[3] & 0xff);
400
401 tid_len = strlen(&buf[4]);
402 tid_len += 4;
403 tid_len += 1;
404 padding = ((-tid_len) & 3);
405 if (padding != 0)
406 tid_len += padding;
407
408 if ((add_len + 4) != tid_len) {
409 pr_debug("LIO-Target Extracted add_len: %hu "
410 "does not match calculated tid_len: %u,"
411 " using tid_len instead\n", add_len+4, tid_len);
412 *out_tid_len = tid_len;
413 } else
414 *out_tid_len = (add_len + 4);
415 }
416
417
418
419
420
421 if (format_code == 0x40) {
422 p = strstr(&buf[4], ",i,0x");
423 if (!p) {
424 pr_err("Unable to locate \",i,0x\" separator"
425 " for Initiator port identifier: %s\n",
426 &buf[4]);
427 return NULL;
428 }
429 *p = '\0';
430 p += 5;
431
432 *port_nexus_ptr = p;
433
434
435
436
437
438
439 for (i = 0; i < 12; i++) {
440 if (isdigit(*p)) {
441 p++;
442 continue;
443 }
444 *p = tolower(*p);
445 p++;
446 }
447 }
448
449 return (char *)&buf[4];
450}
451EXPORT_SYMBOL(iscsi_parse_pr_out_transport_id);
452