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 *
spdk_scsi_port_create(uint64_t id,uint16_t index,const char * name)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
spdk_scsi_port_free(struct spdk_scsi_port ** pport)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
scsi_port_construct(struct spdk_scsi_port * port,uint64_t id,uint16_t index,const char * name)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
scsi_port_destruct(struct spdk_scsi_port * port)61 scsi_port_destruct(struct spdk_scsi_port *port)
62 {
63 memset(port, 0, sizeof(struct spdk_scsi_port));
64 }
65
66 const char *
spdk_scsi_port_get_name(const struct spdk_scsi_port * port)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
spdk_scsi_port_set_iscsi_transport_id(struct spdk_scsi_port * port,char * iscsi_name,uint64_t isid)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