xref: /spdk/lib/scsi/port.c (revision fecffda6ecf8853b82edccde429b68252f0a62c5)
1 /*   SPDX-License-Identifier: BSD-3-Clause
2  *   Copyright (C) 2008-2012 Daisuke Aoyama <aoyama@peach.ne.jp>.
3  *   Copyright (C) 2016 Intel Corporation.
4  *   All rights reserved.
5  */
6 
7 #include "scsi_internal.h"
8 
9 #include "spdk/endian.h"
10 
11 struct spdk_scsi_port *
12 spdk_scsi_port_create(uint64_t id, uint16_t index, const char *name)
13 {
14 	struct spdk_scsi_port *port;
15 
16 	port = calloc(1, sizeof(struct spdk_scsi_port));
17 
18 	if (!port) {
19 		return NULL;
20 	}
21 
22 	if (scsi_port_construct(port, id, index, name) != 0) {
23 		spdk_scsi_port_free(&port);
24 		return NULL;
25 	}
26 
27 	return port;
28 }
29 
30 void
31 spdk_scsi_port_free(struct spdk_scsi_port **pport)
32 {
33 	struct spdk_scsi_port *port;
34 
35 	if (!pport) {
36 		return;
37 	}
38 
39 	port = *pport;
40 	*pport = NULL;
41 	free(port);
42 }
43 
44 int
45 scsi_port_construct(struct spdk_scsi_port *port, uint64_t id, uint16_t index,
46 		    const char *name)
47 {
48 	if (strlen(name) >= sizeof(port->name)) {
49 		SPDK_ERRLOG("port name too long\n");
50 		return -1;
51 	}
52 
53 	port->is_used = 1;
54 	port->id = id;
55 	port->index = index;
56 	snprintf(port->name, sizeof(port->name), "%s", name);
57 	return 0;
58 }
59 
60 void
61 scsi_port_destruct(struct spdk_scsi_port *port)
62 {
63 	memset(port, 0, sizeof(struct spdk_scsi_port));
64 }
65 
66 const char *
67 spdk_scsi_port_get_name(const struct spdk_scsi_port *port)
68 {
69 	return port->name;
70 }
71 
72 /*
73  * spc3r23 7.5.4.6 iSCSI initiator port TransportID,
74  * using code format 0x01.
75  */
76 void
77 spdk_scsi_port_set_iscsi_transport_id(struct spdk_scsi_port *port, char *iscsi_name,
78 				      uint64_t isid)
79 {
80 	struct spdk_scsi_iscsi_transport_id *data;
81 	uint32_t len;
82 	char *name;
83 
84 	memset(port->transport_id, 0, sizeof(port->transport_id));
85 	port->transport_id_len = 0;
86 
87 	data = (struct spdk_scsi_iscsi_transport_id *)port->transport_id;
88 
89 	data->protocol_id = (uint8_t)SPDK_SPC_PROTOCOL_IDENTIFIER_ISCSI;
90 	data->format = 0x1;
91 
92 	name = data->name;
93 	len = snprintf(name, SPDK_SCSI_MAX_TRANSPORT_ID_LENGTH - sizeof(*data),
94 		       "%s,i,0x%12.12" PRIx64, iscsi_name, isid);
95 	do {
96 		name[len++] = '\0';
97 	} while (len & 3);
98 
99 	if (len < 20) {
100 		SPDK_ERRLOG("The length of Transport ID should >= 20 bytes\n");
101 		return;
102 	}
103 
104 	to_be16(&data->additional_len, len);
105 	port->transport_id_len = len + sizeof(*data);
106 }
107