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)
 FILE_SECBOOT (FORBIDDEN)
 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 56 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:224
#define EINFO_EPERM
Definition errno.h:659
uint16_t reason
Rejection reason.
Definition ib_mad.h:9

Definition at line 59 of file srp.c.

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

◆ EPERM_UNKNOWN

#define EPERM_UNKNOWN   __einfo_error ( EINFO_EPERM_UNKNOWN )

Definition at line 61 of file srp.c.

61#define EPERM_UNKNOWN \
62 __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:59
#define SRP_LOGIN_REJ_REASON_UNKNOWN
Unable to establish RDMA channel, no reason specified.
Definition srp.h:226

Definition at line 63 of file srp.c.

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

◆ EPERM_INSUFFICIENT_RESOURCES

#define EPERM_INSUFFICIENT_RESOURCES   __einfo_error ( EINFO_EPERM_INSUFFICIENT_RESOURCES )

Definition at line 66 of file srp.c.

66#define EPERM_INSUFFICIENT_RESOURCES \
67 __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 68 of file srp.c.

68#define EINFO_EPERM_INSUFFICIENT_RESOURCES EINFO_SRP_LOGIN_REJ ( \
69 SRP_LOGIN_REJ_REASON_INSUFFICIENT_RESOURCES, \
70 "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 71 of file srp.c.

71#define EPERM_BAD_MAX_I_T_IU_LEN \
72 __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 73 of file srp.c.

73#define EINFO_EPERM_BAD_MAX_I_T_IU_LEN EINFO_SRP_LOGIN_REJ ( \
74 SRP_LOGIN_REJ_REASON_BAD_MAX_I_T_IU_LEN, \
75 "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 76 of file srp.c.

76#define EPERM_CANNOT_ASSOCIATE \
77 __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 78 of file srp.c.

78#define EINFO_EPERM_CANNOT_ASSOCIATE EINFO_SRP_LOGIN_REJ ( \
79 SRP_LOGIN_REJ_REASON_CANNOT_ASSOCIATE, \
80 "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 81 of file srp.c.

81#define EPERM_UNSUPPORTED_BUFFER_FORMAT \
82 __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 83 of file srp.c.

83#define EINFO_EPERM_UNSUPPORTED_BUFFER_FORMAT EINFO_SRP_LOGIN_REJ ( \
84 SRP_LOGIN_REJ_REASON_UNSUPPORTED_BUFFER_FORMAT, \
85 "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 86 of file srp.c.

86#define EPERM_NO_MULTIPLE_CHANNELS \
87 __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 88 of file srp.c.

88#define EINFO_EPERM_NO_MULTIPLE_CHANNELS EINFO_SRP_LOGIN_REJ ( \
89 SRP_LOGIN_REJ_REASON_NO_MULTIPLE_CHANNELS, \
90 "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 91 of file srp.c.

91#define EPERM_NO_MORE_CHANNELS \
92 __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 93 of file srp.c.

93#define EINFO_EPERM_NO_MORE_CHANNELS EINFO_SRP_LOGIN_REJ ( \
94 SRP_LOGIN_REJ_REASON_NO_MORE_CHANNELS, \
95 "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:269
#define EPERM_UNSUPPORTED_BUFFER_FORMAT
Definition srp.c:81
#define EPERM_NO_MORE_CHANNELS
Definition srp.c:91
#define EPERM_CANNOT_ASSOCIATE
Definition srp.c:76
#define EPERM_NO_MULTIPLE_CHANNELS
Definition srp.c:86
#define EPERM_INSUFFICIENT_RESOURCES
Definition srp.c:66
#define EPERM_BAD_MAX_I_T_IU_LEN
Definition srp.c:71
#define EPERM_UNKNOWN
Definition srp.c:61

Definition at line 96 of file srp.c.

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

Referenced by srp_login_rej().

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( BSD2 )

◆ FILE_SECBOOT()

FILE_SECBOOT ( FORBIDDEN )

◆ 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 143 of file srp.c.

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

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 154 of file srp.c.

154 {
155 ref_put ( &srpdev->refcnt );
156}
#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 165 of file srp.c.

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

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 176 of file srp.c.

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

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 185 of file srp.c.

185 {
186 struct srp_command *srpcmd =
188
189 assert ( list_empty ( &srpcmd->list ) );
190
191 srpdev_put ( srpcmd->srpdev );
192 free ( srpcmd );
193}
#define assert(condition)
Assert a condition at run-time.
Definition assert.h:61
#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:154
#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:122
struct list_head list
List of active commands.
Definition srp.c:128
struct srp_device * srpdev
SRP device.
Definition srp.c:126

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 201 of file srp.c.

201 {
202 struct srp_device *srpdev = srpcmd->srpdev;
203
204 if ( rc != 0 ) {
205 DBGC ( srpdev, "SRP %p tag %08x closed: %s\n",
206 srpdev, srpcmd->tag, strerror ( rc ) );
207 }
208
209 /* Remove from list of commands */
210 if ( ! list_empty ( &srpcmd->list ) ) {
211 list_del ( &srpcmd->list );
212 INIT_LIST_HEAD ( &srpcmd->list );
213 srpcmd_put ( srpcmd );
214 }
215
216 /* Shut down interfaces */
217 intf_shutdown ( &srpcmd->scsi, rc );
218}
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
#define DBGC(...)
Definition compiler.h:530
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:176
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79
struct interface scsi
SCSI command interface.
Definition srp.c:131
uint32_t tag
Command tag.
Definition srp.c:133
An SRP device.
Definition srp.c:103

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 226 of file srp.c.

226 {
227 struct srp_command *srpcmd;
228 struct srp_command *tmp;
229
230 if ( rc != 0 ) {
231 DBGC ( srpdev, "SRP %p closed: %s\n",
232 srpdev, strerror ( rc ) );
233 }
234
235 /* Shut down interfaces */
238
239 /* Shut down any active commands */
241 srpcmd_get ( srpcmd );
242 srpcmd_close ( srpcmd, rc );
243 srpcmd_put ( srpcmd );
244 }
245}
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:165
static void srpcmd_close(struct srp_command *srpcmd, int rc)
Close SRP command.
Definition srp.c:201
struct interface socket
Underlying data transfer interface.
Definition srp.c:110
struct interface scsi
SCSI command issuing interface.
Definition srp.c:108
struct list_head commands
List of active commands.
Definition srp.c:118

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 254 of file srp.c.

255 {
256 struct srp_command *srpcmd;
257
258 list_for_each_entry ( srpcmd, &srpdev->commands, list ) {
259 if ( srpcmd->tag == tag )
260 return srpcmd;
261 }
262 return NULL;
263}
#define NULL
NULL pointer (VOID *).
Definition Base.h:321
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 271 of file srp.c.

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

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 292 of file srp.c.

293 {
294 struct io_buffer *iobuf;
295 struct srp_login_req *login_req;
296 int rc;
297
298 /* Allocate I/O buffer */
299 iobuf = xfer_alloc_iob ( &srpdev->socket, sizeof ( *login_req ) );
300 if ( ! iobuf )
301 return -ENOMEM;
302
303 /* Construct login request IU */
304 login_req = iob_put ( iobuf, sizeof ( *login_req ) );
305 memset ( login_req, 0, sizeof ( *login_req ) );
306 login_req->type = SRP_LOGIN_REQ;
307 login_req->tag.dwords[0] = htonl ( SRP_TAG_MAGIC );
308 login_req->tag.dwords[1] = htonl ( tag );
309 login_req->max_i_t_iu_len = htonl ( SRP_MAX_I_T_IU_LEN );
311 memcpy ( &login_req->initiator, initiator,
312 sizeof ( login_req->initiator ) );
313 memcpy ( &login_req->target, target, sizeof ( login_req->target ) );
314
315 DBGC ( srpdev, "SRP %p tag %08x LOGIN_REQ:\n", srpdev, tag );
316 DBGC_HDA ( srpdev, 0, iobuf->data, iob_len ( iobuf ) );
317
318 /* Send login request IU */
319 if ( ( rc = xfer_deliver_iob ( &srpdev->socket, iobuf ) ) != 0 ) {
320 DBGC ( srpdev, "SRP %p tag %08x could not send LOGIN_REQ: "
321 "%s\n", srpdev, tag, strerror ( rc ) );
322 return rc;
323 }
324
325 return 0;
326}
#define DBGC_HDA(...)
Definition compiler.h:531
#define ENOMEM
Not enough space.
Definition errno.h:578
#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:185
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition iobuf.h:220
#define SRP_MAX_I_T_IU_LEN
Maximum length of any initiator-to-target IU that we will send.
Definition srp.c:56
#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:98
void * data
Start of data.
Definition iobuf.h:113
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 336 of file srp.c.

337 {
338 const struct srp_login_rsp *login_rsp;
339
340 /* Sanity check */
341 if ( len < sizeof ( *login_rsp ) ) {
342 DBGC ( srpdev, "SRP %p LOGIN_RSP too short (%zd bytes)\n",
343 srpdev, len );
344 return -EINVAL;
345 }
346 login_rsp = data;
347 DBGC ( srpdev, "SRP %p tag %08x LOGIN_RSP:\n",
348 srpdev, ntohl ( login_rsp->tag.dwords[1] ) );
349 DBGC_HDA ( srpdev, 0, data, len );
350
351 /* Mark as logged in */
352 srpdev->logged_in = 1;
353 DBGC ( srpdev, "SRP %p logged in\n", srpdev );
354
355 /* Notify of window change */
356 xfer_window_changed ( &srpdev->scsi );
357
358 return 0;
359}
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:472
#define ntohl(value)
Definition byteswap.h:135
int logged_in
Login completed successfully.
Definition srp.c:115
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 369 of file srp.c.

370 {
371 const struct srp_login_rej *login_rej;
373
374 /* Sanity check */
375 if ( len < sizeof ( *login_rej ) ) {
376 DBGC ( srpdev, "SRP %p LOGIN_REJ too short (%zd bytes)\n",
377 srpdev, len );
378 return -EINVAL;
379 }
380 login_rej = data;
381 reason = ntohl ( login_rej->reason );
382 DBGC ( srpdev, "SRP %p tag %08x LOGIN_REJ reason %08x:\n",
383 srpdev, ntohl ( login_rej->tag.dwords[1] ), reason );
384 DBGC_HDA ( srpdev, 0, data, len );
385
386 /* Login rejection always indicates an error */
388 -EPERM_LOGIN_REJ ( reason ) : -EACCES );
389}
unsigned int uint32_t
Definition stdint.h:12
#define EACCES
Permission denied.
Definition errno.h:342
#define EPERM_LOGIN_REJ(reason_nibble)
Definition srp.c:96
#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 399 of file srp.c.

401 {
402 struct io_buffer *iobuf;
403 struct srp_cmd *cmd;
404 struct srp_memory_descriptor *data_out;
405 struct srp_memory_descriptor *data_in;
406 int rc;
407
408 /* Sanity check */
409 if ( ! srpdev->logged_in ) {
410 DBGC ( srpdev, "SRP %p tag %08x cannot send CMD before "
411 "login completes\n", srpdev, tag );
412 return -EBUSY;
413 }
414
415 /* Allocate I/O buffer */
416 iobuf = xfer_alloc_iob ( &srpdev->socket, SRP_MAX_I_T_IU_LEN );
417 if ( ! iobuf )
418 return -ENOMEM;
419
420 /* Construct base portion */
421 cmd = iob_put ( iobuf, sizeof ( *cmd ) );
422 memset ( cmd, 0, sizeof ( *cmd ) );
423 cmd->type = SRP_CMD;
424 cmd->tag.dwords[0] = htonl ( SRP_TAG_MAGIC );
425 cmd->tag.dwords[1] = htonl ( tag );
426 memcpy ( &cmd->lun, &command->lun, sizeof ( cmd->lun ) );
427 memcpy ( &cmd->cdb, &command->cdb, sizeof ( cmd->cdb ) );
428
429 /* Construct data-out descriptor, if present */
430 if ( command->data_out.len ) {
431 cmd->data_buffer_formats |= SRP_CMD_DO_FMT_DIRECT;
432 data_out = iob_put ( iobuf, sizeof ( *data_out ) );
433 data_out->address =
434 cpu_to_be64 ( virt_to_phys ( command->data_out.data ) );
435 data_out->handle = ntohl ( srpdev->memory_handle );
436 data_out->len = ntohl ( command->data_out.len );
437 }
438
439 /* Construct data-in descriptor, if present */
440 if ( command->data_in.len ) {
441 cmd->data_buffer_formats |= SRP_CMD_DI_FMT_DIRECT;
442 data_in = iob_put ( iobuf, sizeof ( *data_in ) );
443 data_in->address =
444 cpu_to_be64 ( virt_to_phys ( command->data_in.data ) );
445 data_in->handle = ntohl ( srpdev->memory_handle );
446 data_in->len = ntohl ( command->data_in.len );
447 }
448
449 DBGC2 ( srpdev, "SRP %p tag %08x CMD " SCSI_CDB_FORMAT "\n",
450 srpdev, tag, SCSI_CDB_DATA ( cmd->cdb ) );
451
452 /* Send IU */
453 if ( ( rc = xfer_deliver_iob ( &srpdev->socket, iobuf ) ) != 0 ) {
454 DBGC ( srpdev, "SRP %p tag %08x could not send CMD: %s\n",
455 srpdev, tag, strerror ( rc ) );
456 return rc;
457 }
458
459 return 0;
460}
struct golan_eqe_cmd cmd
Definition CIB_PRM.h:1
#define DBGC2(...)
Definition compiler.h:547
#define EBUSY
Device or resource busy.
Definition errno.h:382
#define SCSI_CDB_DATA(cdb)
printf() parameters for dumping a scsi_cdb
Definition scsi.h:224
#define SCSI_CDB_FORMAT
printf() format for dumping a scsi_cdb
Definition scsi.h:220
#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:113
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 470 of file srp.c.

471 {
472 const struct srp_rsp *rsp;
473 struct srp_command *srpcmd;
474 struct scsi_rsp response;
475 const void *response_data;
476 const void *sense_data;
477 size_t response_data_len;
478 size_t sense_data_len;
479 size_t remaining;
480 ssize_t data_out_residual_count;
481 ssize_t data_in_residual_count;
482
483 /* Parse response */
484 remaining = len;
485 if ( remaining < sizeof ( *rsp ) ) {
486 DBGC ( srpdev, "SRP %p RSP too short (%zd bytes)\n",
487 srpdev, len );
488 return -EINVAL;
489 }
490 rsp = data;
491 remaining -= sizeof ( *rsp );
492 DBGC2 ( srpdev, "SRP %p tag %08x RSP stat %02x dores %08x dires "
493 "%08x valid %02x%s%s%s%s%s%s\n",
494 srpdev, ntohl ( rsp->tag.dwords[1] ), rsp->status,
495 ntohl ( rsp->data_out_residual_count ),
496 ntohl ( rsp->data_in_residual_count ), rsp->valid,
497 ( ( rsp->valid & SRP_RSP_VALID_DIUNDER ) ? " diunder" : "" ),
498 ( ( rsp->valid & SRP_RSP_VALID_DIOVER ) ? " diover" : "" ),
499 ( ( rsp->valid & SRP_RSP_VALID_DOUNDER ) ? " dounder" : "" ),
500 ( ( rsp->valid & SRP_RSP_VALID_DOOVER ) ? " doover" : "" ),
501 ( ( rsp->valid & SRP_RSP_VALID_SNSVALID ) ? " sns" : "" ),
502 ( ( rsp->valid & SRP_RSP_VALID_RSPVALID ) ? " rsp" : "" ) );
503
504 /* Parse response data */
505 response_data_len = srp_rsp_response_data_len ( rsp );
506 if ( remaining < response_data_len ) {
507 DBGC ( srpdev, "SRP %p RSP overlength response data\n",
508 srpdev );
509 return -EINVAL;
510 }
511 response_data = srp_rsp_response_data ( rsp );
512 if ( response_data ) {
513 DBGC2 ( srpdev, "SRP %p response data:\n", srpdev );
514 DBGC2_HDA ( srpdev, 0, response_data, response_data_len );
515 }
516 remaining -= response_data_len;
517
518 /* Parse sense data */
519 sense_data_len = srp_rsp_sense_data_len ( rsp );
520 if ( remaining < sense_data_len ) {
521 DBGC ( srpdev, "SRP %p RSP overlength sense data\n",
522 srpdev );
523 return -EINVAL;
524 }
525 sense_data = srp_rsp_sense_data ( rsp );
526 if ( sense_data ) {
527 DBGC2 ( srpdev, "SRP %p sense data:\n", srpdev );
528 DBGC2_HDA ( srpdev, 0, sense_data, sense_data_len );
529 }
530 remaining -= sense_data_len;
531
532 /* Identify command by tag */
533 srpcmd = srp_find_tag ( srpdev, ntohl ( rsp->tag.dwords[1] ) );
534 if ( ! srpcmd ) {
535 DBGC ( srpdev, "SRP %p tag %08x unrecognised RSP\n",
536 srpdev, ntohl ( rsp->tag.dwords[1] ) );
537 return -ENOENT;
538 }
539
540 /* Hold command reference for remainder of function */
541 srpcmd_get ( srpcmd );
542
543 /* Build SCSI response */
544 memset ( &response, 0, sizeof ( response ) );
545 response.status = rsp->status;
546 data_out_residual_count = ntohl ( rsp->data_out_residual_count );
547 data_in_residual_count = ntohl ( rsp->data_in_residual_count );
548 if ( rsp->valid & SRP_RSP_VALID_DOOVER ) {
549 response.overrun = data_out_residual_count;
550 } else if ( rsp->valid & SRP_RSP_VALID_DOUNDER ) {
551 response.overrun = -(data_out_residual_count);
552 } else if ( rsp->valid & SRP_RSP_VALID_DIOVER ) {
553 response.overrun = data_in_residual_count;
554 } else if ( rsp->valid & SRP_RSP_VALID_DIUNDER ) {
555 response.overrun = -(data_in_residual_count);
556 }
557 scsi_parse_sense ( sense_data, sense_data_len, &response.sense );
558
559 /* Report SCSI response */
560 scsi_response ( &srpcmd->scsi, &response );
561
562 /* Close SCSI command */
563 srpcmd_close ( srpcmd, 0 );
564
565 /* Drop temporary command reference */
566 srpcmd_put ( srpcmd );
567
568 return 0;
569}
signed long ssize_t
Definition stdint.h:7
#define DBGC2_HDA(...)
Definition compiler.h:548
#define ENOENT
No such file or directory.
Definition errno.h:558
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 const void * srp_rsp_response_data(const struct srp_rsp *rsp)
Get response data portion of SCSI response.
Definition srp.h:588
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:313
An SRP SCSI response.
Definition srp.h:517

References data, DBGC, DBGC2, DBGC2_HDA, 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(), 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 579 of file srp.c.

580 {
581 const struct srp_common *common = data;
582
583 DBGC ( srpdev, "SRP %p tag %08x unrecognised IU type %02x:\n",
584 srpdev, ntohl ( common->tag.dwords[1] ), common->type );
585 DBGC_HDA ( srpdev, 0, data, len );
586
587 return -ENOTSUP;
588}
#define ENOTSUP
Operation not supported.
Definition errno.h:633
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 607 of file srp.c.

609 {
610 struct srp_command *srpcmd;
611 int tag;
612 int rc;
613
614 /* Allocate command tag */
615 tag = srp_new_tag ( srpdev );
616 if ( tag < 0 ) {
617 rc = tag;
618 goto err_tag;
619 }
620
621 /* Allocate and initialise structure */
622 srpcmd = zalloc ( sizeof ( *srpcmd ) );
623 if ( ! srpcmd ) {
624 rc = -ENOMEM;
625 goto err_zalloc;
626 }
627 ref_init ( &srpcmd->refcnt, srpcmd_free );
628 intf_init ( &srpcmd->scsi, &srpcmd_scsi_desc, &srpcmd->refcnt );
629 srpcmd->srpdev = srpdev_get ( srpdev );
630 list_add ( &srpcmd->list, &srpdev->commands );
631 srpcmd->tag = tag;
632
633 /* Send command IU */
634 if ( ( rc = srp_cmd ( srpdev, command, srpcmd->tag ) ) != 0 )
635 goto err_cmd;
636
637 /* Attach to parent interface, leave reference with command
638 * list, and return.
639 */
640 intf_plug_plug ( &srpcmd->scsi, parent );
641 return srpcmd->tag;
642
643 err_cmd:
644 srpcmd_close ( srpcmd, rc );
645 err_zalloc:
646 err_tag:
647 return rc;
648}
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:718
#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:143
static void srpcmd_free(struct refcnt *refcnt)
Free SRP command.
Definition srp.c:185
static int srp_new_tag(struct srp_device *srpdev)
Choose an SRP command tag.
Definition srp.c:271
static struct interface_descriptor srpcmd_scsi_desc
SRP command SCSI interface descriptor.
Definition srp.c:596

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 658 of file srp.c.

660 {
661 struct srp_common *common;
662 int ( * type ) ( struct srp_device *srp, const void *data, size_t len );
663 int rc;
664
665 /* Sanity check */
666 if ( iob_len ( iobuf ) < sizeof ( *common ) ) {
667 DBGC ( srpdev, "SRP %p IU too short (%zd bytes)\n",
668 srpdev, iob_len ( iobuf ) );
669 rc = -EINVAL;
670 goto err;
671 }
672 common = iobuf->data;
673
674 /* Determine IU type */
675 switch ( common->type ) {
676 case SRP_LOGIN_RSP:
678 break;
679 case SRP_LOGIN_REJ:
681 break;
682 case SRP_RSP:
683 type = srp_rsp;
684 break;
685 default:
687 break;
688 }
689
690 /* Handle IU */
691 if ( ( rc = type ( srpdev, iobuf->data, iob_len ( iobuf ) ) ) != 0 )
692 goto err;
693
694 free_iob ( iobuf );
695 return 0;
696
697 err:
698 DBGC ( srpdev, "SRP %p closing due to received IU (%s):\n",
699 srpdev, strerror ( rc ) );
700 DBGC_HDA ( srpdev, 0, iobuf->data, iob_len ( iobuf ) );
701 free_iob ( iobuf );
702 srpdev_close ( srpdev, rc );
703 return rc;
704}
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:579
static void srpdev_close(struct srp_device *srpdev, int rc)
Close SRP device.
Definition srp.c:226
#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 712 of file srp.c.

712 {
713 return ( srpdev->logged_in ? ~( ( size_t ) 0 ) : 0 );
714}

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 749 of file srp.c.

751 {
752 struct srp_device *srpdev;
753 int tag;
754 int rc;
755
756 /* Allocate and initialise structure */
757 srpdev = zalloc ( sizeof ( *srpdev ) );
758 if ( ! srpdev ) {
759 rc = -ENOMEM;
760 goto err_zalloc;
761 }
762 ref_init ( &srpdev->refcnt, NULL );
763 intf_init ( &srpdev->scsi, &srpdev_scsi_desc, &srpdev->refcnt );
764 intf_init ( &srpdev->socket, &srpdev_socket_desc, &srpdev->refcnt );
765 INIT_LIST_HEAD ( &srpdev->commands );
767 DBGC ( srpdev, "SRP %p %08x%08x%08x%08x->%08x%08x%08x%08x\n", srpdev,
768 ntohl ( initiator->dwords[0] ), ntohl ( initiator->dwords[1] ),
769 ntohl ( initiator->dwords[2] ), ntohl ( initiator->dwords[3] ),
770 ntohl ( target->dwords[0] ), ntohl ( target->dwords[1] ),
771 ntohl ( target->dwords[2] ), ntohl ( target->dwords[3] ) );
772
773 /* Attach to socket interface and initiate login */
774 intf_plug_plug ( &srpdev->socket, socket );
775 tag = srp_new_tag ( srpdev );
776 assert ( tag >= 0 ); /* Cannot fail when no commands in progress */
777 if ( ( rc = srp_login ( srpdev, initiator, target, tag ) ) != 0 )
778 goto err_login;
779
780 /* Attach SCSI device to parent interface */
781 if ( ( rc = scsi_open ( block, &srpdev->scsi, lun ) ) != 0 ) {
782 DBGC ( srpdev, "SRP %p could not create SCSI device: %s\n",
783 srpdev, strerror ( rc ) );
784 goto err_scsi_open;
785 }
786
787 /* Mortalise self and return */
788 ref_put ( &srpdev->refcnt );
789 return 0;
790
791 err_scsi_open:
792 err_login:
793 srpdev_close ( srpdev, rc );
794 ref_put ( &srpdev->refcnt );
795 err_zalloc:
796 return rc;
797}
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:987
static struct interface_descriptor srpdev_scsi_desc
SRP device SCSI interface descriptor.
Definition srp.c:735
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:292
static struct interface_descriptor srpdev_socket_desc
SRP device socket interface descriptor.
Definition srp.c:723
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 591 of file srp.c.

591 {
593};

◆ 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:591

SRP command SCSI interface descriptor.

Definition at line 596 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:658
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 717 of file srp.c.

717 {
720};

◆ 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:717

SRP device socket interface descriptor.

Definition at line 723 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:712
static int srpdev_scsi_command(struct srp_device *srpdev, struct interface *parent, struct scsi_cmd *command)
Issue SRP SCSI command.
Definition srp.c:607
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 728 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:728

SRP device SCSI interface descriptor.

Definition at line 735 of file srp.c.

Referenced by srp_open().