diff --git a/include/spdk/scsi.h b/include/spdk/scsi.h index 6ecea307e..93068f5c7 100644 --- a/include/spdk/scsi.h +++ b/include/spdk/scsi.h @@ -61,6 +61,7 @@ extern "C" { #define SPDK_SCSI_DEV_MAX_NAME 255 #define SPDK_SCSI_PORT_MAX_NAME_LENGTH 255 +#define SPDK_SCSI_MAX_TRANSPORT_ID_LENGTH 255 enum spdk_scsi_data_dir { SPDK_SCSI_DIR_NONE = 0, @@ -510,6 +511,16 @@ int spdk_scsi_lun_allocate_io_channel(struct spdk_scsi_desc *desc); */ void spdk_scsi_lun_free_io_channel(struct spdk_scsi_desc *desc); + +/** + * Set iSCSI Initiator port TransportID + * + * \param port SCSI initiator port. + * \param iscsi_name Initiator name. + * \param isid Session ID. + */ +void spdk_scsi_port_set_iscsi_transport_id(struct spdk_scsi_port *port, + char *iscsi_name, uint64_t isid); #ifdef __cplusplus } #endif diff --git a/include/spdk/scsi_spec.h b/include/spdk/scsi_spec.h index f0670b72c..4559e9657 100644 --- a/include/spdk/scsi_spec.h +++ b/include/spdk/scsi_spec.h @@ -485,6 +485,17 @@ struct spdk_scsi_port_desc { uint8_t tgt_desc[]; }; +/* iSCSI initiator port TransportID header */ +struct spdk_scsi_iscsi_transport_id { + uint8_t protocol_id : 4; + uint8_t reserved1 : 2; + uint8_t format : 2; + uint8_t reserved2; + uint16_t additional_len; + uint8_t name[]; +}; +SPDK_STATIC_ASSERT(sizeof(struct spdk_scsi_iscsi_transport_id) == 4, "Incorrect size"); + /* SCSI UNMAP block descriptor */ struct spdk_scsi_unmap_bdesc { /* UNMAP LOGICAL BLOCK ADDRESS */ diff --git a/lib/iscsi/iscsi.c b/lib/iscsi/iscsi.c index 83ea286b1..e07bda17c 100644 --- a/lib/iscsi/iscsi.c +++ b/lib/iscsi/iscsi.c @@ -1522,6 +1522,10 @@ spdk_iscsi_op_login_set_conn_info(struct spdk_iscsi_conn *conn, 0, initiator_port_name); conn->sess->isid = spdk_iscsi_get_isid(rsph->isid); conn->sess->target = target; + /* Initiator port TransportID */ + spdk_scsi_port_set_iscsi_transport_id(conn->sess->initiator_port, + conn->initiator_name, + conn->sess->isid); /* Discovery sessions will not have a target. */ if (target != NULL) { diff --git a/lib/scsi/port.c b/lib/scsi/port.c index 70d720049..93d71b5ad 100644 --- a/lib/scsi/port.c +++ b/lib/scsi/port.c @@ -34,6 +34,8 @@ #include "scsi_internal.h" +#include "spdk/endian.h" + struct spdk_scsi_port * spdk_scsi_port_create(uint64_t id, uint16_t index, const char *name) { @@ -94,3 +96,39 @@ spdk_scsi_port_get_name(const struct spdk_scsi_port *port) { return port->name; } + +/* + * spc3r23 7.5.4.6 iSCSI initiator port TransportID, + * using code format 0x01. + */ +void +spdk_scsi_port_set_iscsi_transport_id(struct spdk_scsi_port *port, char *iscsi_name, + uint64_t isid) +{ + struct spdk_scsi_iscsi_transport_id *data; + uint32_t len; + char *name; + + memset(port->transport_id, 0, sizeof(port->transport_id)); + port->transport_id_len = 0; + + data = (struct spdk_scsi_iscsi_transport_id *)port->transport_id; + + data->protocol_id = (uint8_t)SPDK_SPC_PROTOCOL_IDENTIFIER_ISCSI; + data->format = 0x1; + + name = data->name; + len = snprintf(name, SPDK_SCSI_MAX_TRANSPORT_ID_LENGTH - sizeof(*data), + "%s,i,0x%12.12" PRIx64, iscsi_name, isid); + do { + name[len++] = '\0'; + } while (len & 3); + + if (len < 20) { + SPDK_ERRLOG("The length of Transport ID should >= 20 bytes\n"); + return; + } + + to_be16(&data->additional_len, len); + port->transport_id_len = len + sizeof(*data); +} diff --git a/lib/scsi/scsi_internal.h b/lib/scsi/scsi_internal.h index 85caf7621..9f5e6d73b 100644 --- a/lib/scsi/scsi_internal.h +++ b/lib/scsi/scsi_internal.h @@ -54,6 +54,8 @@ struct spdk_scsi_port { uint8_t is_used; uint64_t id; uint16_t index; + uint16_t transport_id_len; + char transport_id[SPDK_SCSI_MAX_TRANSPORT_ID_LENGTH]; char name[SPDK_SCSI_PORT_MAX_NAME_LENGTH]; };