iPXE
srp.c File Reference

SCSI RDMA Protocol. More...

#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <ipxe/scsi.h>
#include <ipxe/xfer.h>
#include <ipxe/features.h>
#include <ipxe/srp.h>

Go to the source code of this file.

Data Structures

struct  srp_device
 An SRP device. More...
struct  srp_command
 An SRP command. More...

Macros

#define SRP_MAX_I_T_IU_LEN   80
 Maximum length of any initiator-to-target IU that we will send.
#define EINFO_SRP_LOGIN_REJ(reason, desc)
#define EPERM_UNKNOWN    __einfo_error ( EINFO_EPERM_UNKNOWN )
#define EINFO_EPERM_UNKNOWN
#define EPERM_INSUFFICIENT_RESOURCES    __einfo_error ( EINFO_EPERM_INSUFFICIENT_RESOURCES )
#define EINFO_EPERM_INSUFFICIENT_RESOURCES
#define EPERM_BAD_MAX_I_T_IU_LEN    __einfo_error ( EINFO_EPERM_BAD_MAX_I_T_IU_LEN )
#define EINFO_EPERM_BAD_MAX_I_T_IU_LEN
#define EPERM_CANNOT_ASSOCIATE    __einfo_error ( EINFO_EPERM_CANNOT_ASSOCIATE )
#define EINFO_EPERM_CANNOT_ASSOCIATE
#define EPERM_UNSUPPORTED_BUFFER_FORMAT    __einfo_error ( EINFO_EPERM_UNSUPPORTED_BUFFER_FORMAT )
#define EINFO_EPERM_UNSUPPORTED_BUFFER_FORMAT
#define EPERM_NO_MULTIPLE_CHANNELS    __einfo_error ( EINFO_EPERM_NO_MULTIPLE_CHANNELS )
#define EINFO_EPERM_NO_MULTIPLE_CHANNELS
#define EPERM_NO_MORE_CHANNELS    __einfo_error ( EINFO_EPERM_NO_MORE_CHANNELS )
#define EINFO_EPERM_NO_MORE_CHANNELS
#define EPERM_LOGIN_REJ(reason_nibble)

Functions

 FILE_LICENCE (BSD2)
 FEATURE (FEATURE_PROTOCOL, "SRP", DHCP_EB_FEATURE_SRP, 1)
static struct srp_devicesrpdev_get (struct srp_device *srpdev)
 Get reference to SRP device.
static void srpdev_put (struct srp_device *srpdev)
 Drop reference to SRP device.
static struct srp_commandsrpcmd_get (struct srp_command *srpcmd)
 Get reference to SRP command.
static void srpcmd_put (struct srp_command *srpcmd)
 Drop reference to SRP command.
static void srpcmd_free (struct refcnt *refcnt)
 Free SRP command.
static void srpcmd_close (struct srp_command *srpcmd, int rc)
 Close SRP command.
static void srpdev_close (struct srp_device *srpdev, int rc)
 Close SRP device.
static struct srp_commandsrp_find_tag (struct srp_device *srpdev, uint32_t tag)
 Identify SRP command by tag.
static int srp_new_tag (struct srp_device *srpdev)
 Choose an SRP command tag.
static int srp_login (struct srp_device *srpdev, union srp_port_id *initiator, union srp_port_id *target, uint32_t tag)
 Transmit SRP login request.
static int srp_login_rsp (struct srp_device *srpdev, const void *data, size_t len)
 Receive SRP login response.
static int srp_login_rej (struct srp_device *srpdev, const void *data, size_t len)
 Receive SRP login rejection.
static int srp_cmd (struct srp_device *srpdev, struct scsi_cmd *command, uint32_t tag)
 Transmit SRP SCSI command.
static int srp_rsp (struct srp_device *srpdev, const void *data, size_t len)
 Receive SRP SCSI response.
static int srp_unrecognised (struct srp_device *srpdev, const void *data, size_t len)
 Receive SRP unrecognised response IU.
static int srpdev_scsi_command (struct srp_device *srpdev, struct interface *parent, struct scsi_cmd *command)
 Issue SRP SCSI command.
static int srpdev_deliver (struct srp_device *srpdev, struct io_buffer *iobuf, struct xfer_metadata *meta __unused)
 Receive data from SRP socket.
static size_t srpdev_window (struct srp_device *srpdev)
 Check SRP device flow-control window.
int srp_open (struct interface *block, struct interface *socket, union srp_port_id *initiator, union srp_port_id *target, uint32_t memory_handle, struct scsi_lun *lun)
 Open SRP device.

Variables

static struct interface_operation srpcmd_scsi_op []
 SRP command SCSI interface operations.
static struct interface_descriptor srpcmd_scsi_desc
 SRP command SCSI interface descriptor.
static struct interface_operation srpdev_socket_op []
 SRP device socket interface operations.
static struct interface_descriptor srpdev_socket_desc
 SRP device socket interface descriptor.
static struct interface_operation srpdev_scsi_op []
 SRP device SCSI interface operations.
static struct interface_descriptor srpdev_scsi_desc
 SRP device SCSI interface descriptor.

Detailed Description

SCSI RDMA Protocol.

Definition in file srp.c.

Macro Definition Documentation

◆ SRP_MAX_I_T_IU_LEN

#define SRP_MAX_I_T_IU_LEN   80

Maximum length of any initiator-to-target IU that we will send.

The longest IU is a SRP_CMD with no additional CDB and two direct data buffer descriptors, which comes to 80 bytes.

Definition at line 55 of file srp.c.

Referenced by srp_cmd(), and srp_login().

◆ EINFO_SRP_LOGIN_REJ

#define EINFO_SRP_LOGIN_REJ ( reason,
desc )
Value:
struct ena_llq_option desc
Descriptor counts.
Definition ena.h:9
#define __einfo_uniqify(einfo_base, uniq, desc)
Declare disambiguated error.
Definition errno.h:181
#define EINFO_EPERM
Definition errno.h:616
uint16_t reason
Rejection reason.
Definition ib_mad.h:9

Definition at line 58 of file srp.c.

58#define EINFO_SRP_LOGIN_REJ( reason, desc ) \
59 __einfo_uniqify ( EINFO_EPERM, ( (reason) & 0x0f ), desc )

◆ EPERM_UNKNOWN

#define EPERM_UNKNOWN    __einfo_error ( EINFO_EPERM_UNKNOWN )

Definition at line 60 of file srp.c.

60#define EPERM_UNKNOWN \
61 __einfo_error ( EINFO_EPERM_UNKNOWN )

◆ EINFO_EPERM_UNKNOWN

#define EINFO_EPERM_UNKNOWN
Value:
"Unable to establish RDMA channel, no reason specified" )
#define EINFO_SRP_LOGIN_REJ(reason, desc)
Definition srp.c:58
#define SRP_LOGIN_REJ_REASON_UNKNOWN
Unable to establish RDMA channel, no reason specified.
Definition srp.h:226

Definition at line 62 of file srp.c.

62#define EINFO_EPERM_UNKNOWN EINFO_SRP_LOGIN_REJ ( \
63 SRP_LOGIN_REJ_REASON_UNKNOWN, \
64 "Unable to establish RDMA channel, no reason specified" )

◆ EPERM_INSUFFICIENT_RESOURCES

#define EPERM_INSUFFICIENT_RESOURCES    __einfo_error ( EINFO_EPERM_INSUFFICIENT_RESOURCES )

Definition at line 65 of file srp.c.

65#define EPERM_INSUFFICIENT_RESOURCES \
66 __einfo_error ( EINFO_EPERM_INSUFFICIENT_RESOURCES )

◆ EINFO_EPERM_INSUFFICIENT_RESOURCES

#define EINFO_EPERM_INSUFFICIENT_RESOURCES
Value:
"Insufficient RDMA channel resources" )
#define SRP_LOGIN_REJ_REASON_INSUFFICIENT_RESOURCES
Insufficient RDMA channel resources.
Definition srp.h:229

Definition at line 67 of file srp.c.

67#define EINFO_EPERM_INSUFFICIENT_RESOURCES EINFO_SRP_LOGIN_REJ ( \
68 SRP_LOGIN_REJ_REASON_INSUFFICIENT_RESOURCES, \
69 "Insufficient RDMA channel resources" )

◆ EPERM_BAD_MAX_I_T_IU_LEN

#define EPERM_BAD_MAX_I_T_IU_LEN    __einfo_error ( EINFO_EPERM_BAD_MAX_I_T_IU_LEN )

Definition at line 70 of file srp.c.

70#define EPERM_BAD_MAX_I_T_IU_LEN \
71 __einfo_error ( EINFO_EPERM_BAD_MAX_I_T_IU_LEN )

◆ EINFO_EPERM_BAD_MAX_I_T_IU_LEN

#define EINFO_EPERM_BAD_MAX_I_T_IU_LEN
Value:
"Requested maximum initiator to target IU length value too large" )
#define SRP_LOGIN_REJ_REASON_BAD_MAX_I_T_IU_LEN
Requested maximum initiator to target IU length value too large.
Definition srp.h:232

Definition at line 72 of file srp.c.

72#define EINFO_EPERM_BAD_MAX_I_T_IU_LEN EINFO_SRP_LOGIN_REJ ( \
73 SRP_LOGIN_REJ_REASON_BAD_MAX_I_T_IU_LEN, \
74 "Requested maximum initiator to target IU length value too large" )

◆ EPERM_CANNOT_ASSOCIATE

#define EPERM_CANNOT_ASSOCIATE    __einfo_error ( EINFO_EPERM_CANNOT_ASSOCIATE )

Definition at line 75 of file srp.c.

75#define EPERM_CANNOT_ASSOCIATE \
76 __einfo_error ( EINFO_EPERM_CANNOT_ASSOCIATE )

◆ EINFO_EPERM_CANNOT_ASSOCIATE

#define EINFO_EPERM_CANNOT_ASSOCIATE
Value:
"Unable to associate RDMA channel with specified I_T nexus" )
#define SRP_LOGIN_REJ_REASON_CANNOT_ASSOCIATE
Unable to associate RDMA channel with specified I_T nexus.
Definition srp.h:235

Definition at line 77 of file srp.c.

77#define EINFO_EPERM_CANNOT_ASSOCIATE EINFO_SRP_LOGIN_REJ ( \
78 SRP_LOGIN_REJ_REASON_CANNOT_ASSOCIATE, \
79 "Unable to associate RDMA channel with specified I_T nexus" )

◆ EPERM_UNSUPPORTED_BUFFER_FORMAT

#define EPERM_UNSUPPORTED_BUFFER_FORMAT    __einfo_error ( EINFO_EPERM_UNSUPPORTED_BUFFER_FORMAT )

Definition at line 80 of file srp.c.

80#define EPERM_UNSUPPORTED_BUFFER_FORMAT \
81 __einfo_error ( EINFO_EPERM_UNSUPPORTED_BUFFER_FORMAT )

◆ EINFO_EPERM_UNSUPPORTED_BUFFER_FORMAT

#define EINFO_EPERM_UNSUPPORTED_BUFFER_FORMAT
Value:
"One or more requested data buffer descriptor formats not supported" )
#define SRP_LOGIN_REJ_REASON_UNSUPPORTED_BUFFER_FORMAT
One or more requested data buffer descriptor formats are not supported.
Definition srp.h:238

Definition at line 82 of file srp.c.

82#define EINFO_EPERM_UNSUPPORTED_BUFFER_FORMAT EINFO_SRP_LOGIN_REJ ( \
83 SRP_LOGIN_REJ_REASON_UNSUPPORTED_BUFFER_FORMAT, \
84 "One or more requested data buffer descriptor formats not supported" )

◆ EPERM_NO_MULTIPLE_CHANNELS

#define EPERM_NO_MULTIPLE_CHANNELS    __einfo_error ( EINFO_EPERM_NO_MULTIPLE_CHANNELS )

Definition at line 85 of file srp.c.

85#define EPERM_NO_MULTIPLE_CHANNELS \
86 __einfo_error ( EINFO_EPERM_NO_MULTIPLE_CHANNELS )

◆ EINFO_EPERM_NO_MULTIPLE_CHANNELS

#define EINFO_EPERM_NO_MULTIPLE_CHANNELS
Value:
"SRP target does not support multiple RDMA channels per I_T nexus" )
#define SRP_LOGIN_REJ_REASON_NO_MULTIPLE_CHANNELS
SRP target port does not support multiple RDMA channels per I_T nexus.
Definition srp.h:241

Definition at line 87 of file srp.c.

87#define EINFO_EPERM_NO_MULTIPLE_CHANNELS EINFO_SRP_LOGIN_REJ ( \
88 SRP_LOGIN_REJ_REASON_NO_MULTIPLE_CHANNELS, \
89 "SRP target does not support multiple RDMA channels per I_T nexus" )

◆ EPERM_NO_MORE_CHANNELS

#define EPERM_NO_MORE_CHANNELS    __einfo_error ( EINFO_EPERM_NO_MORE_CHANNELS )

Definition at line 90 of file srp.c.

90#define EPERM_NO_MORE_CHANNELS \
91 __einfo_error ( EINFO_EPERM_NO_MORE_CHANNELS )

◆ EINFO_EPERM_NO_MORE_CHANNELS

#define EINFO_EPERM_NO_MORE_CHANNELS
Value:
"RDMA channel limit reached for this initiator" )
#define SRP_LOGIN_REJ_REASON_NO_MORE_CHANNELS
RDMA channel limit reached for this initiator.
Definition srp.h:244

Definition at line 92 of file srp.c.

92#define EINFO_EPERM_NO_MORE_CHANNELS EINFO_SRP_LOGIN_REJ ( \
93 SRP_LOGIN_REJ_REASON_NO_MORE_CHANNELS, \
94 "RDMA channel limit reached for this initiator" )

◆ EPERM_LOGIN_REJ

#define EPERM_LOGIN_REJ ( reason_nibble)
Value:
EUNIQ ( EINFO_EPERM, (reason_nibble), EPERM_UNKNOWN, \
#define EUNIQ(einfo_base, uniq,...)
Disambiguate a base error based on non-constant information.
Definition errno.h:226
#define EPERM_UNSUPPORTED_BUFFER_FORMAT
Definition srp.c:80
#define EPERM_NO_MORE_CHANNELS
Definition srp.c:90
#define EPERM_CANNOT_ASSOCIATE
Definition srp.c:75
#define EPERM_NO_MULTIPLE_CHANNELS
Definition srp.c:85
#define EPERM_INSUFFICIENT_RESOURCES
Definition srp.c:65
#define EPERM_BAD_MAX_I_T_IU_LEN
Definition srp.c:70
#define EPERM_UNKNOWN
Definition srp.c:60

Definition at line 95 of file srp.c.

95#define EPERM_LOGIN_REJ( reason_nibble ) \
96 EUNIQ ( EINFO_EPERM, (reason_nibble), EPERM_UNKNOWN, \
97 EPERM_INSUFFICIENT_RESOURCES, EPERM_BAD_MAX_I_T_IU_LEN, \
98 EPERM_CANNOT_ASSOCIATE, EPERM_UNSUPPORTED_BUFFER_FORMAT, \
99 EPERM_NO_MULTIPLE_CHANNELS, EPERM_NO_MORE_CHANNELS )

Referenced by srp_login_rej().

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( BSD2 )

◆ FEATURE()

FEATURE ( FEATURE_PROTOCOL ,
"SRP" ,
DHCP_EB_FEATURE_SRP ,
1  )

◆ srpdev_get()

struct srp_device * srpdev_get ( struct srp_device * srpdev)
inlinestatic

Get reference to SRP device.

Parameters
srpdevSRP device
Return values
srpdevSRP device

Definition at line 142 of file srp.c.

142 {
143 ref_get ( &srpdev->refcnt );
144 return srpdev;
145}
#define ref_get(refcnt)
Get additional reference to object.
Definition refcnt.h:93
struct refcnt refcnt
Reference count.
Definition srp.c:104

References ref_get, and srp_device::refcnt.

Referenced by srpdev_scsi_command().

◆ srpdev_put()

void srpdev_put ( struct srp_device * srpdev)
inlinestatic

Drop reference to SRP device.

Parameters
srpdevSRP device

Definition at line 153 of file srp.c.

153 {
154 ref_put ( &srpdev->refcnt );
155}
#define ref_put(refcnt)
Drop reference to object.
Definition refcnt.h:107

References ref_put, and srp_device::refcnt.

Referenced by srpcmd_free().

◆ srpcmd_get()

struct srp_command * srpcmd_get ( struct srp_command * srpcmd)
inlinestatic

Get reference to SRP command.

Parameters
srpcmdSRP command
Return values
srpcmdSRP command

Definition at line 164 of file srp.c.

164 {
165 ref_get ( &srpcmd->refcnt );
166 return srpcmd;
167}
struct refcnt refcnt
Reference count.
Definition srp.c:123

References ref_get, and srp_command::refcnt.

Referenced by srp_rsp(), and srpdev_close().

◆ srpcmd_put()

void srpcmd_put ( struct srp_command * srpcmd)
inlinestatic

Drop reference to SRP command.

Parameters
srpcmdSRP command

Definition at line 175 of file srp.c.

175 {
176 ref_put ( &srpcmd->refcnt );
177}

References ref_put, and srp_command::refcnt.

Referenced by srp_rsp(), srpcmd_close(), and srpdev_close().

◆ srpcmd_free()

void srpcmd_free ( struct refcnt * refcnt)
static

Free SRP command.

Parameters
refcntReference count

Definition at line 184 of file srp.c.

184 {
185 struct srp_command *srpcmd =
187
188 assert ( list_empty ( &srpcmd->list ) );
189
190 srpdev_put ( srpcmd->srpdev );
191 free ( srpcmd );
192}
#define assert(condition)
Assert a condition at run-time.
Definition assert.h:50
#define list_empty(list)
Test whether a list is empty.
Definition list.h:137
static void(* free)(struct refcnt *refcnt))
Definition refcnt.h:55
static void srpdev_put(struct srp_device *srpdev)
Drop reference to SRP device.
Definition srp.c:153
#define container_of(ptr, type, field)
Get containing structure.
Definition stddef.h:36
A reference counter.
Definition refcnt.h:27
An SRP command.
Definition srp.c:121
struct list_head list
List of active commands.
Definition srp.c:127
struct srp_device * srpdev
SRP device.
Definition srp.c:125

References assert, container_of, free, srp_command::list, list_empty, srp_command::srpdev, and srpdev_put().

Referenced by srpdev_scsi_command().

◆ srpcmd_close()

void srpcmd_close ( struct srp_command * srpcmd,
int rc )
static

Close SRP command.

Parameters
srpcmdSRP command
rcReason for close

Definition at line 200 of file srp.c.

200 {
201 struct srp_device *srpdev = srpcmd->srpdev;
202
203 if ( rc != 0 ) {
204 DBGC ( srpdev, "SRP %p tag %08x closed: %s\n",
205 srpdev, srpcmd->tag, strerror ( rc ) );
206 }
207
208 /* Remove from list of commands */
209 if ( ! list_empty ( &srpcmd->list ) ) {
210 list_del ( &srpcmd->list );
211 INIT_LIST_HEAD ( &srpcmd->list );
212 srpcmd_put ( srpcmd );
213 }
214
215 /* Shut down interfaces */
216 intf_shutdown ( &srpcmd->scsi, rc );
217}
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
#define DBGC(...)
Definition compiler.h:505
void intf_shutdown(struct interface *intf, int rc)
Shut down an object interface.
Definition interface.c:279
#define list_del(list)
Delete an entry from a list.
Definition list.h:120
#define INIT_LIST_HEAD(list)
Initialise a list head.
Definition list.h:46
static void srpcmd_put(struct srp_command *srpcmd)
Drop reference to SRP command.
Definition srp.c:175
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79
struct interface scsi
SCSI command interface.
Definition srp.c:130
uint32_t tag
Command tag.
Definition srp.c:132
An SRP device.
Definition srp.c:102

References DBGC, INIT_LIST_HEAD, intf_shutdown(), srp_command::list, list_del, list_empty, rc, srp_command::scsi, srpcmd_put(), srp_command::srpdev, strerror(), and srp_command::tag.

Referenced by srp_rsp(), srpdev_close(), and srpdev_scsi_command().

◆ srpdev_close()

void srpdev_close ( struct srp_device * srpdev,
int rc )
static

Close SRP device.

Parameters
srpdevSRP device
rcReason for close

Definition at line 225 of file srp.c.

225 {
226 struct srp_command *srpcmd;
227 struct srp_command *tmp;
228
229 if ( rc != 0 ) {
230 DBGC ( srpdev, "SRP %p closed: %s\n",
231 srpdev, strerror ( rc ) );
232 }
233
234 /* Shut down interfaces */
237
238 /* Shut down any active commands */
240 srpcmd_get ( srpcmd );
241 srpcmd_close ( srpcmd, rc );
242 srpcmd_put ( srpcmd );
243 }
244}
unsigned long tmp
Definition linux_pci.h:65
#define list_for_each_entry_safe(pos, tmp, head, member)
Iterate over entries in a list, safe against deletion of the current entry.
Definition list.h:459
static struct srp_command * srpcmd_get(struct srp_command *srpcmd)
Get reference to SRP command.
Definition srp.c:164
static void srpcmd_close(struct srp_command *srpcmd, int rc)
Close SRP command.
Definition srp.c:200
struct interface socket
Underlying data transfer interface.
Definition srp.c:109
struct interface scsi
SCSI command issuing interface.
Definition srp.c:107
struct list_head commands
List of active commands.
Definition srp.c:117

References srp_device::commands, DBGC, intf_shutdown(), srp_command::list, list_for_each_entry_safe, rc, srp_device::scsi, srp_device::socket, srpcmd_close(), srpcmd_get(), srpcmd_put(), srp_command::srpdev, strerror(), and tmp.

Referenced by srp_open(), and srpdev_deliver().

◆ srp_find_tag()

struct srp_command * srp_find_tag ( struct srp_device * srpdev,
uint32_t tag )
static

Identify SRP command by tag.

Parameters
srpdevSRP device
tagCommand tag
Return values
srpcmdSRP command, or NULL

Definition at line 253 of file srp.c.

254 {
255 struct srp_command *srpcmd;
256
257 list_for_each_entry ( srpcmd, &srpdev->commands, list ) {
258 if ( srpcmd->tag == tag )
259 return srpcmd;
260 }
261 return NULL;
262}
#define NULL
NULL pointer (VOID *)
Definition Base.h:322
uint64_t tag
Identity tag.
Definition edd.h:1
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition list.h:432

References srp_device::commands, srp_command::list, list_for_each_entry, NULL, srp_command::srpdev, srp_command::tag, and tag.

Referenced by srp_new_tag(), and srp_rsp().

◆ srp_new_tag()

int srp_new_tag ( struct srp_device * srpdev)
static

Choose an SRP command tag.

Parameters
srpdevSRP device
Return values
tagNew tag, or negative error

Definition at line 270 of file srp.c.

270 {
271 static uint16_t tag_idx;
272 unsigned int i;
273
274 for ( i = 0 ; i < 65536 ; i++ ) {
275 tag_idx++;
276 if ( srp_find_tag ( srpdev, tag_idx ) == NULL )
277 return tag_idx;
278 }
279 return -EADDRINUSE;
280}
unsigned short uint16_t
Definition stdint.h:11
#define EADDRINUSE
Address already in use.
Definition errno.h:304
static struct srp_command * srp_find_tag(struct srp_device *srpdev, uint32_t tag)
Identify SRP command by tag.
Definition srp.c:253

References EADDRINUSE, NULL, srp_find_tag(), and srp_command::srpdev.

Referenced by srp_open(), and srpdev_scsi_command().

◆ srp_login()

int srp_login ( struct srp_device * srpdev,
union srp_port_id * initiator,
union srp_port_id * target,
uint32_t tag )
static

Transmit SRP login request.

Parameters
srpdevSRP device
initiatorInitiator port ID
targetTarget port ID
tagCommand tag
Return values
rcReturn status code

Definition at line 291 of file srp.c.

292 {
293 struct io_buffer *iobuf;
294 struct srp_login_req *login_req;
295 int rc;
296
297 /* Allocate I/O buffer */
298 iobuf = xfer_alloc_iob ( &srpdev->socket, sizeof ( *login_req ) );
299 if ( ! iobuf )
300 return -ENOMEM;
301
302 /* Construct login request IU */
303 login_req = iob_put ( iobuf, sizeof ( *login_req ) );
304 memset ( login_req, 0, sizeof ( *login_req ) );
305 login_req->type = SRP_LOGIN_REQ;
306 login_req->tag.dwords[0] = htonl ( SRP_TAG_MAGIC );
307 login_req->tag.dwords[1] = htonl ( tag );
308 login_req->max_i_t_iu_len = htonl ( SRP_MAX_I_T_IU_LEN );
310 memcpy ( &login_req->initiator, initiator,
311 sizeof ( login_req->initiator ) );
312 memcpy ( &login_req->target, target, sizeof ( login_req->target ) );
313
314 DBGC ( srpdev, "SRP %p tag %08x LOGIN_REQ:\n", srpdev, tag );
315 DBGC_HDA ( srpdev, 0, iobuf->data, iob_len ( iobuf ) );
316
317 /* Send login request IU */
318 if ( ( rc = xfer_deliver_iob ( &srpdev->socket, iobuf ) ) != 0 ) {
319 DBGC ( srpdev, "SRP %p tag %08x could not send LOGIN_REQ: "
320 "%s\n", srpdev, tag, strerror ( rc ) );
321 return rc;
322 }
323
324 return 0;
325}
#define DBGC_HDA(...)
Definition compiler.h:506
#define ENOMEM
Not enough space.
Definition errno.h:535
#define htonl(value)
Definition byteswap.h:134
void * memcpy(void *dest, const void *src, size_t len) __nonnull
void * memset(void *dest, int character, size_t len) __nonnull
#define iob_put(iobuf, len)
Definition iobuf.h:125
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition iobuf.h:160
#define SRP_MAX_I_T_IU_LEN
Maximum length of any initiator-to-target IU that we will send.
Definition srp.c:55
#define SRP_LOGIN_REQ
Type of an SRP login request.
Definition srp.h:96
#define SRP_TAG_MAGIC
SRP tag magic marker.
Definition srp.h:34
#define SRP_LOGIN_REQ_FMT_DDBD
Require direct data buffer descriptor format.
Definition srp.h:102
A persistent I/O buffer.
Definition iobuf.h:38
void * data
Start of data.
Definition iobuf.h:53
An SRP login request information unit.
Definition srp.h:60
union srp_port_id target
Target port identifier.
Definition srp.h:92
uint16_t required_buffer_formats
Required buffer formats.
Definition srp.h:79
union srp_port_id initiator
Initiator port identifier.
Definition srp.h:90
uint8_t type
Information unit type.
Definition srp.h:65
uint32_t max_i_t_iu_len
Requested maximum initiator to target IU length.
Definition srp.h:71
union srp_tag tag
Tag.
Definition srp.h:69
uint32_t dwords[2]
Definition srp.h:30
struct io_buffer * xfer_alloc_iob(struct interface *intf, size_t len)
Allocate I/O buffer.
Definition xfer.c:159
int xfer_deliver_iob(struct interface *intf, struct io_buffer *iobuf)
Deliver datagram as I/O buffer without metadata.
Definition xfer.c:256

References io_buffer::data, DBGC, DBGC_HDA, srp_tag::dwords, ENOMEM, htonl, srp_login_req::initiator, iob_len(), iob_put, srp_login_req::max_i_t_iu_len, memcpy(), memset(), rc, srp_login_req::required_buffer_formats, srp_device::socket, SRP_LOGIN_REQ, SRP_LOGIN_REQ_FMT_DDBD, SRP_MAX_I_T_IU_LEN, SRP_TAG_MAGIC, strerror(), srp_login_req::tag, tag, srp_login_req::target, srp_login_req::type, xfer_alloc_iob(), and xfer_deliver_iob().

Referenced by srp_open().

◆ srp_login_rsp()

int srp_login_rsp ( struct srp_device * srpdev,
const void * data,
size_t len )
static

Receive SRP login response.

Parameters
srpdevSRP device
dataSRP IU
lenLength of SRP IU
Return values
rcReturn status code

Definition at line 335 of file srp.c.

336 {
337 const struct srp_login_rsp *login_rsp = data;
338
339 /* Sanity check */
340 if ( len < sizeof ( *login_rsp ) ) {
341 DBGC ( srpdev, "SRP %p LOGIN_RSP too short (%zd bytes)\n",
342 srpdev, len );
343 return -EINVAL;
344 }
345 DBGC ( srpdev, "SRP %p tag %08x LOGIN_RSP:\n",
346 srpdev, ntohl ( login_rsp->tag.dwords[1] ) );
347 DBGC_HDA ( srpdev, 0, data, len );
348
349 /* Mark as logged in */
350 srpdev->logged_in = 1;
351 DBGC ( srpdev, "SRP %p logged in\n", srpdev );
352
353 /* Notify of window change */
354 xfer_window_changed ( &srpdev->scsi );
355
356 return 0;
357}
ring len
Length.
Definition dwmac.h:226
uint8_t data[48]
Additional event data.
Definition ena.h:11
#define EINVAL
Invalid argument.
Definition errno.h:429
#define ntohl(value)
Definition byteswap.h:135
int logged_in
Login completed successfully.
Definition srp.c:114
An SRP login response.
Definition srp.h:130
union srp_tag tag
Tag.
Definition srp.h:141
void xfer_window_changed(struct interface *intf)
Report change of flow control window.
Definition xfer.c:147

References data, DBGC, DBGC_HDA, srp_tag::dwords, EINVAL, len, srp_device::logged_in, ntohl, srp_device::scsi, srp_login_rsp::tag, and xfer_window_changed().

◆ srp_login_rej()

int srp_login_rej ( struct srp_device * srpdev,
const void * data,
size_t len )
static

Receive SRP login rejection.

Parameters
srpdevSRP device
dataSRP IU
lenLength of SRP IU
Return values
rcReturn status code

Definition at line 367 of file srp.c.

368 {
369 const struct srp_login_rej *login_rej = data;
371
372 /* Sanity check */
373 if ( len < sizeof ( *login_rej ) ) {
374 DBGC ( srpdev, "SRP %p LOGIN_REJ too short (%zd bytes)\n",
375 srpdev, len );
376 return -EINVAL;
377 }
378 reason = ntohl ( login_rej->reason );
379 DBGC ( srpdev, "SRP %p tag %08x LOGIN_REJ reason %08x:\n",
380 srpdev, ntohl ( login_rej->tag.dwords[1] ), reason );
381 DBGC_HDA ( srpdev, 0, data, len );
382
383 /* Login rejection always indicates an error */
385 -EPERM_LOGIN_REJ ( reason ) : -EACCES );
386}
unsigned int uint32_t
Definition stdint.h:12
#define EACCES
Permission denied.
Definition errno.h:299
#define EPERM_LOGIN_REJ(reason_nibble)
Definition srp.c:95
#define SRP_LOGIN_REJ_REASON_DEFINED(reason)
SRP login rejection reason is defined.
Definition srp.h:247
An SRP login rejection.
Definition srp.h:195
uint32_t reason
Reason.
Definition srp.h:207
union srp_tag tag
Tag.
Definition srp.h:209

References data, DBGC, DBGC_HDA, srp_tag::dwords, EACCES, EINVAL, EPERM_LOGIN_REJ, len, ntohl, reason, srp_login_rej::reason, SRP_LOGIN_REJ_REASON_DEFINED, and srp_login_rej::tag.

◆ srp_cmd()

int srp_cmd ( struct srp_device * srpdev,
struct scsi_cmd * command,
uint32_t tag )
static

Transmit SRP SCSI command.

Parameters
srpdevSRP device
commandSCSI command
tagCommand tag
Return values
rcReturn status code

Definition at line 396 of file srp.c.

398 {
399 struct io_buffer *iobuf;
400 struct srp_cmd *cmd;
401 struct srp_memory_descriptor *data_out;
402 struct srp_memory_descriptor *data_in;
403 int rc;
404
405 /* Sanity check */
406 if ( ! srpdev->logged_in ) {
407 DBGC ( srpdev, "SRP %p tag %08x cannot send CMD before "
408 "login completes\n", srpdev, tag );
409 return -EBUSY;
410 }
411
412 /* Allocate I/O buffer */
413 iobuf = xfer_alloc_iob ( &srpdev->socket, SRP_MAX_I_T_IU_LEN );
414 if ( ! iobuf )
415 return -ENOMEM;
416
417 /* Construct base portion */
418 cmd = iob_put ( iobuf, sizeof ( *cmd ) );
419 memset ( cmd, 0, sizeof ( *cmd ) );
420 cmd->type = SRP_CMD;
421 cmd->tag.dwords[0] = htonl ( SRP_TAG_MAGIC );
422 cmd->tag.dwords[1] = htonl ( tag );
423 memcpy ( &cmd->lun, &command->lun, sizeof ( cmd->lun ) );
424 memcpy ( &cmd->cdb, &command->cdb, sizeof ( cmd->cdb ) );
425
426 /* Construct data-out descriptor, if present */
427 if ( command->data_out ) {
428 cmd->data_buffer_formats |= SRP_CMD_DO_FMT_DIRECT;
429 data_out = iob_put ( iobuf, sizeof ( *data_out ) );
430 data_out->address =
431 cpu_to_be64 ( virt_to_phys ( command->data_out ) );
432 data_out->handle = ntohl ( srpdev->memory_handle );
433 data_out->len = ntohl ( command->data_out_len );
434 }
435
436 /* Construct data-in descriptor, if present */
437 if ( command->data_in ) {
438 cmd->data_buffer_formats |= SRP_CMD_DI_FMT_DIRECT;
439 data_in = iob_put ( iobuf, sizeof ( *data_in ) );
440 data_in->address =
441 cpu_to_be64 ( virt_to_phys ( command->data_in ) );
442 data_in->handle = ntohl ( srpdev->memory_handle );
443 data_in->len = ntohl ( command->data_in_len );
444 }
445
446 DBGC2 ( srpdev, "SRP %p tag %08x CMD " SCSI_CDB_FORMAT "\n",
447 srpdev, tag, SCSI_CDB_DATA ( cmd->cdb ) );
448
449 /* Send IU */
450 if ( ( rc = xfer_deliver_iob ( &srpdev->socket, iobuf ) ) != 0 ) {
451 DBGC ( srpdev, "SRP %p tag %08x could not send CMD: %s\n",
452 srpdev, tag, strerror ( rc ) );
453 return rc;
454 }
455
456 return 0;
457}
struct golan_eqe_cmd cmd
Definition CIB_PRM.h:1
#define DBGC2(...)
Definition compiler.h:522
#define EBUSY
Device or resource busy.
Definition errno.h:339
#define SCSI_CDB_DATA(cdb)
printf() parameters for dumping a scsi_cdb
Definition scsi.h:223
#define SCSI_CDB_FORMAT
printf() format for dumping a scsi_cdb
Definition scsi.h:219
#define cpu_to_be64(value)
Definition byteswap.h:112
#define SRP_CMD
Type of an SRP SCSI command.
Definition srp.h:461
#define SRP_CMD_DI_FMT_DIRECT
Direct data-in buffer format.
Definition srp.h:482
#define SRP_CMD_DO_FMT_DIRECT
Direct data-out buffer format.
Definition srp.h:473
A command-line command.
Definition command.h:10
An SRP SCSI command.
Definition srp.h:415
uint32_t memory_handle
RDMA memory handle.
Definition srp.c:112
An SRP memory descriptor.
Definition srp.h:500
uint64_t address
Virtual address.
Definition srp.h:502
uint32_t handle
Memory handle.
Definition srp.h:504
uint32_t len
Data length.
Definition srp.h:506

References srp_memory_descriptor::address, cmd, cpu_to_be64, DBGC, DBGC2, EBUSY, ENOMEM, srp_memory_descriptor::handle, htonl, iob_put, srp_memory_descriptor::len, srp_device::logged_in, memcpy(), srp_device::memory_handle, memset(), ntohl, rc, SCSI_CDB_DATA, SCSI_CDB_FORMAT, srp_device::socket, SRP_CMD, SRP_CMD_DI_FMT_DIRECT, SRP_CMD_DO_FMT_DIRECT, SRP_MAX_I_T_IU_LEN, SRP_TAG_MAGIC, strerror(), tag, xfer_alloc_iob(), and xfer_deliver_iob().

◆ srp_rsp()

int srp_rsp ( struct srp_device * srpdev,
const void * data,
size_t len )
static

Receive SRP SCSI response.

Parameters
srpdevSRP device
dataSRP IU
lenLength of SRP IU
Return values
rcReturns status code

Definition at line 467 of file srp.c.

468 {
469 const struct srp_rsp *rsp = data;
470 struct srp_command *srpcmd;
471 struct scsi_rsp response;
472 ssize_t data_out_residual_count;
473 ssize_t data_in_residual_count;
474
475 /* Sanity check */
476 if ( ( len < sizeof ( *rsp ) ) ||
477 ( len < ( sizeof ( *rsp ) +
479 srp_rsp_sense_data_len ( rsp ) ) ) ) {
480 DBGC ( srpdev, "SRP %p RSP too short (%zd bytes)\n",
481 srpdev, len );
482 return -EINVAL;
483 }
484 DBGC2 ( srpdev, "SRP %p tag %08x RSP stat %02x dores %08x dires "
485 "%08x valid %02x%s%s%s%s%s%s\n",
486 srpdev, ntohl ( rsp->tag.dwords[1] ), rsp->status,
487 ntohl ( rsp->data_out_residual_count ),
488 ntohl ( rsp->data_in_residual_count ), rsp->valid,
489 ( ( rsp->valid & SRP_RSP_VALID_DIUNDER ) ? " diunder" : "" ),
490 ( ( rsp->valid & SRP_RSP_VALID_DIOVER ) ? " diover" : "" ),
491 ( ( rsp->valid & SRP_RSP_VALID_DOUNDER ) ? " dounder" : "" ),
492 ( ( rsp->valid & SRP_RSP_VALID_DOOVER ) ? " doover" : "" ),
493 ( ( rsp->valid & SRP_RSP_VALID_SNSVALID ) ? " sns" : "" ),
494 ( ( rsp->valid & SRP_RSP_VALID_RSPVALID ) ? " rsp" : "" ) );
495
496 /* Identify command by tag */
497 srpcmd = srp_find_tag ( srpdev, ntohl ( rsp->tag.dwords[1] ) );
498 if ( ! srpcmd ) {
499 DBGC ( srpdev, "SRP %p tag %08x unrecognised RSP\n",
500 srpdev, ntohl ( rsp->tag.dwords[1] ) );
501 return -ENOENT;
502 }
503
504 /* Hold command reference for remainder of function */
505 srpcmd_get ( srpcmd );
506
507 /* Build SCSI response */
508 memset ( &response, 0, sizeof ( response ) );
509 response.status = rsp->status;
510 data_out_residual_count = ntohl ( rsp->data_out_residual_count );
511 data_in_residual_count = ntohl ( rsp->data_in_residual_count );
512 if ( rsp->valid & SRP_RSP_VALID_DOOVER ) {
513 response.overrun = data_out_residual_count;
514 } else if ( rsp->valid & SRP_RSP_VALID_DOUNDER ) {
515 response.overrun = -(data_out_residual_count);
516 } else if ( rsp->valid & SRP_RSP_VALID_DIOVER ) {
517 response.overrun = data_in_residual_count;
518 } else if ( rsp->valid & SRP_RSP_VALID_DIUNDER ) {
519 response.overrun = -(data_in_residual_count);
520 }
522 srp_rsp_sense_data_len ( rsp ), &response.sense );
523
524 /* Report SCSI response */
525 scsi_response ( &srpcmd->scsi, &response );
526
527 /* Close SCSI command */
528 srpcmd_close ( srpcmd, 0 );
529
530 /* Drop temporary command reference */
531 srpcmd_put ( srpcmd );
532
533 return 0;
534}
signed long ssize_t
Definition stdint.h:7
#define ENOENT
No such file or directory.
Definition errno.h:515
uint64_t rsp
Definition librm.h:18
void scsi_response(struct interface *intf, struct scsi_rsp *response)
Report SCSI response.
Definition scsi.c:207
void scsi_parse_sense(const void *data, size_t len, struct scsi_sns_descriptor *sense)
Parse SCSI sense data.
Definition scsi.c:147
#define SRP_RSP_VALID_DOOVER
Data-out residual count field is valid and represents an overflow.
Definition srp.h:574
#define SRP_RSP_VALID_SNSVALID
Sense data list length field is valid.
Definition srp.h:577
static const void * srp_rsp_sense_data(const struct srp_rsp *rsp)
Get sense data portion of SCSI response.
Definition srp.h:610
#define SRP_RSP_VALID_DOUNDER
Data-out residual count field is valid and represents an underflow.
Definition srp.h:571
#define SRP_RSP_VALID_RSPVALID
Response data list length field is valid.
Definition srp.h:580
#define SRP_RSP_VALID_DIOVER
Data-in residual count field is valid and represents an overflow.
Definition srp.h:568
static size_t srp_rsp_response_data_len(const struct srp_rsp *rsp)
Get length of response data portion of SCSI response.
Definition srp.h:599
#define SRP_RSP_VALID_DIUNDER
Data-in residual count field is valid and represents an underflow.
Definition srp.h:565
static size_t srp_rsp_sense_data_len(const struct srp_rsp *rsp)
Get length of sense data portion of SCSI response.
Definition srp.h:622
A SCSI response information unit.
Definition scsi.h:322
An SRP SCSI response.
Definition srp.h:517

References data, DBGC, DBGC2, EINVAL, ENOENT, len, memset(), ntohl, scsi_rsp::overrun, rsp, srp_command::scsi, scsi_parse_sense(), scsi_response(), scsi_rsp::sense, srp_find_tag(), srp_rsp_response_data_len(), srp_rsp_sense_data(), srp_rsp_sense_data_len(), SRP_RSP_VALID_DIOVER, SRP_RSP_VALID_DIUNDER, SRP_RSP_VALID_DOOVER, SRP_RSP_VALID_DOUNDER, SRP_RSP_VALID_RSPVALID, SRP_RSP_VALID_SNSVALID, srpcmd_close(), srpcmd_get(), srpcmd_put(), and scsi_rsp::status.

◆ srp_unrecognised()

int srp_unrecognised ( struct srp_device * srpdev,
const void * data,
size_t len )
static

Receive SRP unrecognised response IU.

Parameters
srpdevSRP device
dataSRP IU
lenLength of SRP IU
Return values
rcReturns status code

Definition at line 544 of file srp.c.

545 {
546 const struct srp_common *common = data;
547
548 DBGC ( srpdev, "SRP %p tag %08x unrecognised IU type %02x:\n",
549 srpdev, ntohl ( common->tag.dwords[1] ), common->type );
550 DBGC_HDA ( srpdev, 0, data, len );
551
552 return -ENOTSUP;
553}
#define ENOTSUP
Operation not supported.
Definition errno.h:590
struct ib_cm_common common
Definition ib_mad.h:0
SRP information unit common fields.
Definition srp.h:43

References common, data, DBGC, DBGC_HDA, ENOTSUP, len, and ntohl.

Referenced by srpdev_deliver().

◆ srpdev_scsi_command()

int srpdev_scsi_command ( struct srp_device * srpdev,
struct interface * parent,
struct scsi_cmd * command )
static

Issue SRP SCSI command.

Parameters
srpdevSRP device
parentParent interface
commandSCSI command
Return values
tagCommand tag, or negative error

Definition at line 572 of file srp.c.

574 {
575 struct srp_command *srpcmd;
576 int tag;
577 int rc;
578
579 /* Allocate command tag */
580 tag = srp_new_tag ( srpdev );
581 if ( tag < 0 ) {
582 rc = tag;
583 goto err_tag;
584 }
585
586 /* Allocate and initialise structure */
587 srpcmd = zalloc ( sizeof ( *srpcmd ) );
588 if ( ! srpcmd ) {
589 rc = -ENOMEM;
590 goto err_zalloc;
591 }
592 ref_init ( &srpcmd->refcnt, srpcmd_free );
593 intf_init ( &srpcmd->scsi, &srpcmd_scsi_desc, &srpcmd->refcnt );
594 srpcmd->srpdev = srpdev_get ( srpdev );
595 list_add ( &srpcmd->list, &srpdev->commands );
596 srpcmd->tag = tag;
597
598 /* Send command IU */
599 if ( ( rc = srp_cmd ( srpdev, command, srpcmd->tag ) ) != 0 )
600 goto err_cmd;
601
602 /* Attach to parent interface, leave reference with command
603 * list, and return.
604 */
605 intf_plug_plug ( &srpcmd->scsi, parent );
606 return srpcmd->tag;
607
608 err_cmd:
609 srpcmd_close ( srpcmd, rc );
610 err_zalloc:
611 err_tag:
612 return rc;
613}
void intf_plug_plug(struct interface *a, struct interface *b)
Plug two object interfaces together.
Definition interface.c:108
static void intf_init(struct interface *intf, struct interface_descriptor *desc, struct refcnt *refcnt)
Initialise an object interface.
Definition interface.h:204
#define list_add(new, head)
Add a new entry to the head of a list.
Definition list.h:70
void * zalloc(size_t size)
Allocate cleared memory.
Definition malloc.c:662
#define ref_init(refcnt, free)
Initialise a reference counter.
Definition refcnt.h:65
static struct srp_device * srpdev_get(struct srp_device *srpdev)
Get reference to SRP device.
Definition srp.c:142
static void srpcmd_free(struct refcnt *refcnt)
Free SRP command.
Definition srp.c:184
static int srp_new_tag(struct srp_device *srpdev)
Choose an SRP command tag.
Definition srp.c:270
static struct interface_descriptor srpcmd_scsi_desc
SRP command SCSI interface descriptor.
Definition srp.c:561

References srp_device::commands, ENOMEM, intf_init(), intf_plug_plug(), srp_command::list, list_add, rc, ref_init, srp_command::refcnt, srp_command::scsi, srp_new_tag(), srpcmd_close(), srpcmd_free(), srpcmd_scsi_desc, srp_command::srpdev, srpdev_get(), srp_command::tag, tag, and zalloc().

◆ srpdev_deliver()

int srpdev_deliver ( struct srp_device * srpdev,
struct io_buffer * iobuf,
struct xfer_metadata *meta __unused )
static

Receive data from SRP socket.

Parameters
srpdevSRP device
iobufDatagram I/O buffer
metaData transfer metadata
Return values
rcReturn status code

Definition at line 623 of file srp.c.

625 {
626 struct srp_common *common = iobuf->data;
627 int ( * type ) ( struct srp_device *srp, const void *data, size_t len );
628 int rc;
629
630 /* Sanity check */
631 if ( iob_len ( iobuf ) < sizeof ( *common ) ) {
632 DBGC ( srpdev, "SRP %p IU too short (%zd bytes)\n",
633 srpdev, iob_len ( iobuf ) );
634 rc = -EINVAL;
635 goto err;
636 }
637
638 /* Determine IU type */
639 switch ( common->type ) {
640 case SRP_LOGIN_RSP:
642 break;
643 case SRP_LOGIN_REJ:
645 break;
646 case SRP_RSP:
647 type = srp_rsp;
648 break;
649 default:
651 break;
652 }
653
654 /* Handle IU */
655 if ( ( rc = type ( srpdev, iobuf->data, iob_len ( iobuf ) ) ) != 0 )
656 goto err;
657
658 free_iob ( iobuf );
659 return 0;
660
661 err:
662 DBGC ( srpdev, "SRP %p closing due to received IU (%s):\n",
663 srpdev, strerror ( rc ) );
664 DBGC_HDA ( srpdev, 0, iobuf->data, iob_len ( iobuf ) );
665 free_iob ( iobuf );
666 srpdev_close ( srpdev, rc );
667 return rc;
668}
uint32_t type
Operating system type.
Definition ena.h:1
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition iobuf.c:153
static int srp_unrecognised(struct srp_device *srpdev, const void *data, size_t len)
Receive SRP unrecognised response IU.
Definition srp.c:544
static void srpdev_close(struct srp_device *srpdev, int rc)
Close SRP device.
Definition srp.c:225
#define SRP_LOGIN_REJ
Type of an SRP login rejection.
Definition srp.h:223
#define SRP_RSP
Type of an SRP SCSI response.
Definition srp.h:559
#define SRP_LOGIN_RSP
Type of an SRP login response.
Definition srp.h:164

References __unused, common, data, io_buffer::data, DBGC, DBGC_HDA, EINVAL, free_iob(), iob_len(), len, meta, rc, SRP_LOGIN_REJ, SRP_LOGIN_RSP, SRP_RSP, srp_unrecognised(), srpdev_close(), strerror(), and type.

◆ srpdev_window()

size_t srpdev_window ( struct srp_device * srpdev)
static

Check SRP device flow-control window.

Parameters
srpdevSRP device
Return values
lenLength of window

Definition at line 676 of file srp.c.

676 {
677 return ( srpdev->logged_in ? ~( ( size_t ) 0 ) : 0 );
678}

References srp_device::logged_in.

◆ srp_open()

int srp_open ( struct interface * block,
struct interface * socket,
union srp_port_id * initiator,
union srp_port_id * target,
uint32_t memory_handle,
struct scsi_lun * lun )

Open SRP device.

Parameters
blockBlock control interface
socketSocket interface
initiatorInitiator port ID
targetTarget port ID
memory_handleRDMA memory handle
lunSCSI LUN
Return values
rcReturn status code

Definition at line 713 of file srp.c.

715 {
716 struct srp_device *srpdev;
717 int tag;
718 int rc;
719
720 /* Allocate and initialise structure */
721 srpdev = zalloc ( sizeof ( *srpdev ) );
722 if ( ! srpdev ) {
723 rc = -ENOMEM;
724 goto err_zalloc;
725 }
726 ref_init ( &srpdev->refcnt, NULL );
727 intf_init ( &srpdev->scsi, &srpdev_scsi_desc, &srpdev->refcnt );
728 intf_init ( &srpdev->socket, &srpdev_socket_desc, &srpdev->refcnt );
729 INIT_LIST_HEAD ( &srpdev->commands );
731 DBGC ( srpdev, "SRP %p %08x%08x%08x%08x->%08x%08x%08x%08x\n", srpdev,
732 ntohl ( initiator->dwords[0] ), ntohl ( initiator->dwords[1] ),
733 ntohl ( initiator->dwords[2] ), ntohl ( initiator->dwords[3] ),
734 ntohl ( target->dwords[0] ), ntohl ( target->dwords[1] ),
735 ntohl ( target->dwords[2] ), ntohl ( target->dwords[3] ) );
736
737 /* Attach to socket interface and initiate login */
738 intf_plug_plug ( &srpdev->socket, socket );
739 tag = srp_new_tag ( srpdev );
740 assert ( tag >= 0 ); /* Cannot fail when no commands in progress */
741 if ( ( rc = srp_login ( srpdev, initiator, target, tag ) ) != 0 )
742 goto err_login;
743
744 /* Attach SCSI device to parent interface */
745 if ( ( rc = scsi_open ( block, &srpdev->scsi, lun ) ) != 0 ) {
746 DBGC ( srpdev, "SRP %p could not create SCSI device: %s\n",
747 srpdev, strerror ( rc ) );
748 goto err_scsi_open;
749 }
750
751 /* Mortalise self and return */
752 ref_put ( &srpdev->refcnt );
753 return 0;
754
755 err_scsi_open:
756 err_login:
757 srpdev_close ( srpdev, rc );
758 ref_put ( &srpdev->refcnt );
759 err_zalloc:
760 return rc;
761}
uint8_t lun
Logical Unit Number.
Definition edd.h:3
uint8_t block[3][8]
DES-encrypted blocks.
Definition mschapv2.h:1
int scsi_open(struct interface *block, struct interface *scsi, struct scsi_lun *lun)
Open SCSI device.
Definition scsi.c:985
static struct interface_descriptor srpdev_scsi_desc
SRP device SCSI interface descriptor.
Definition srp.c:699
static int srp_login(struct srp_device *srpdev, union srp_port_id *initiator, union srp_port_id *target, uint32_t tag)
Transmit SRP login request.
Definition srp.c:291
static struct interface_descriptor srpdev_socket_desc
SRP device socket interface descriptor.
Definition srp.c:687
uint32_t dwords[4]
Definition srp.h:39

References assert, block, srp_device::commands, DBGC, srp_port_id::dwords, ENOMEM, INIT_LIST_HEAD, intf_init(), intf_plug_plug(), lun, srp_device::memory_handle, ntohl, NULL, rc, ref_init, ref_put, srp_device::refcnt, srp_device::scsi, scsi_open(), srp_device::socket, srp_login(), srp_new_tag(), srpdev_close(), srpdev_scsi_desc, srpdev_socket_desc, strerror(), tag, and zalloc().

Referenced by ib_srp_open().

Variable Documentation

◆ srpcmd_scsi_op

struct interface_operation srpcmd_scsi_op[]
static
Initial value:
= {
}
void intf_close(struct interface *intf, int rc)
Close an object interface.
Definition interface.c:250
#define INTF_OP(op_type, object_type, op_func)
Define an object interface operation.
Definition interface.h:33

SRP command SCSI interface operations.

Definition at line 556 of file srp.c.

556 {
558};

◆ srpcmd_scsi_desc

struct interface_descriptor srpcmd_scsi_desc
static
Initial value:
=
#define INTF_DESC(object_type, intf, operations)
Define an object interface descriptor.
Definition interface.h:81
static struct interface_operation srpcmd_scsi_op[]
SRP command SCSI interface operations.
Definition srp.c:556

SRP command SCSI interface descriptor.

Definition at line 561 of file srp.c.

Referenced by srpdev_scsi_command().

◆ srpdev_socket_op

struct interface_operation srpdev_socket_op[]
static
Initial value:
= {
}
static int srpdev_deliver(struct srp_device *srpdev, struct io_buffer *iobuf, struct xfer_metadata *meta __unused)
Receive data from SRP socket.
Definition srp.c:623
int xfer_deliver(struct interface *intf, struct io_buffer *iobuf, struct xfer_metadata *meta)
Deliver datagram.
Definition xfer.c:195

SRP device socket interface operations.

Definition at line 681 of file srp.c.

681 {
684};

◆ srpdev_socket_desc

struct interface_descriptor srpdev_socket_desc
static
Initial value:
=
scsi )
#define INTF_DESC_PASSTHRU(object_type, intf, operations, passthru)
Define an object interface descriptor with pass-through interface.
Definition interface.h:98
static struct interface_operation srpdev_socket_op[]
SRP device socket interface operations.
Definition srp.c:681

SRP device socket interface descriptor.

Definition at line 687 of file srp.c.

Referenced by srp_open().

◆ srpdev_scsi_op

struct interface_operation srpdev_scsi_op[]
static
Initial value:
= {
}
static size_t srpdev_window(struct srp_device *srpdev)
Check SRP device flow-control window.
Definition srp.c:676
static int srpdev_scsi_command(struct srp_device *srpdev, struct interface *parent, struct scsi_cmd *command)
Issue SRP SCSI command.
Definition srp.c:572
A SCSI command.
Definition scsi.c:263
size_t xfer_window(struct interface *intf)
Check flow control window.
Definition xfer.c:117

SRP device SCSI interface operations.

Definition at line 692 of file srp.c.

◆ srpdev_scsi_desc

struct interface_descriptor srpdev_scsi_desc
static
Initial value:
=
INTF_DESC_PASSTHRU ( struct srp_device, scsi, srpdev_scsi_op, socket )
static struct interface_operation srpdev_scsi_op[]
SRP device SCSI interface operations.
Definition srp.c:692

SRP device SCSI interface descriptor.

Definition at line 699 of file srp.c.

Referenced by srp_open().