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