iPXE
Data Structures | Macros | Functions | Variables
fcp.c File Reference

Fibre Channel Protocol. More...

#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <stdio.h>
#include <assert.h>
#include <byteswap.h>
#include <ipxe/refcnt.h>
#include <ipxe/list.h>
#include <ipxe/interface.h>
#include <ipxe/xfer.h>
#include <ipxe/iobuf.h>
#include <ipxe/open.h>
#include <ipxe/process.h>
#include <ipxe/uri.h>
#include <ipxe/acpi.h>
#include <ipxe/scsi.h>
#include <ipxe/device.h>
#include <ipxe/edd.h>
#include <ipxe/fc.h>
#include <ipxe/fcels.h>
#include <ipxe/fcp.h>

Go to the source code of this file.

Data Structures

struct  fcp_device
 An FCP device. More...
 
struct  fcp_command
 An FCP command. More...
 

Macros

#define ERANGE_READ_DATA_ORDERING   __einfo_error ( EINFO_ERANGE_READ_DATA_ORDERING )
 
#define EINFO_ERANGE_READ_DATA_ORDERING   __einfo_uniqify ( EINFO_ERANGE, 0x01, "Read data out of order" )
 
#define ERANGE_READ_DATA_OVERRUN   __einfo_error ( EINFO_ERANGE_READ_DATA_OVERRUN )
 
#define EINFO_ERANGE_READ_DATA_OVERRUN   __einfo_uniqify ( EINFO_ERANGE, 0x02, "Read data overrun" )
 
#define ERANGE_WRITE_DATA_STUCK   __einfo_error ( EINFO_ERANGE_WRITE_DATA_STUCK )
 
#define EINFO_ERANGE_WRITE_DATA_STUCK   __einfo_uniqify ( EINFO_ERANGE, 0x03, "Write data stuck" )
 
#define ERANGE_WRITE_DATA_OVERRUN   __einfo_error ( EINFO_ERANGE_WRITE_DATA_OVERRUN )
 
#define EINFO_ERANGE_WRITE_DATA_OVERRUN   __einfo_uniqify ( EINFO_ERANGE, 0x04, "Write data overrun" )
 
#define ERANGE_DATA_UNDERRUN   __einfo_error ( EINFO_ERANGE_DATA_UNDERRUN )
 
#define EINFO_ERANGE_DATA_UNDERRUN   __einfo_uniqify ( EINFO_ERANGE, 0x05, "Data underrun" )
 

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 
static int fcp_prli_tx (struct fc_els *els)
 Transmit FCP PRLI. More...
 
static int fcp_prli_rx (struct fc_els *els, void *data, size_t len)
 Receive FCP PRLI. More...
 
static int fcp_prli_detect (struct fc_els *els, const void *data, size_t len)
 Detect FCP PRLI. More...
 
static struct fcp_devicefcpdev_get (struct fcp_device *fcpdev)
 Get reference to FCP device. More...
 
static void fcpdev_put (struct fcp_device *fcpdev)
 Drop reference to FCP device. More...
 
static struct fcp_commandfcpcmd_get (struct fcp_command *fcpcmd)
 Get reference to FCP command. More...
 
static void fcpcmd_put (struct fcp_command *fcpcmd)
 Drop reference to FCP command. More...
 
static void fcpcmd_start_send (struct fcp_command *fcpcmd, int(*send)(struct fcp_command *fcpcmd))
 Start FCP command sending. More...
 
static void fcpcmd_stop_send (struct fcp_command *fcpcmd)
 Stop FCP command sending. More...
 
static void fcpcmd_free (struct refcnt *refcnt)
 Free FCP command. More...
 
static void fcpcmd_close (struct fcp_command *fcpcmd, int rc)
 Close FCP command. More...
 
static void fcpcmd_close_err (struct fcp_command *fcpcmd, int rc)
 Close FCP command in error. More...
 
static int fcpcmd_send_cmnd (struct fcp_command *fcpcmd)
 Send FCP command IU. More...
 
static int fcpcmd_recv_rddata (struct fcp_command *fcpcmd, struct io_buffer *iobuf, struct xfer_metadata *meta)
 Handle FCP read data IU. More...
 
static int fcpcmd_send_wrdata (struct fcp_command *fcpcmd)
 Send FCP write data IU. More...
 
static int fcpcmd_recv_xfer_rdy (struct fcp_command *fcpcmd, struct io_buffer *iobuf, struct xfer_metadata *meta __unused)
 Handle FCP transfer ready IU. More...
 
static int fcpcmd_recv_rsp (struct fcp_command *fcpcmd, struct io_buffer *iobuf, struct xfer_metadata *meta __unused)
 Handle FCP response IU. More...
 
static int fcpcmd_recv_unknown (struct fcp_command *fcpcmd, struct io_buffer *iobuf, struct xfer_metadata *meta __unused)
 Handle unknown FCP IU. More...
 
static void fcpcmd_step (struct fcp_command *fcpcmd)
 Transmit FCP frame. More...
 
static int fcpcmd_deliver (struct fcp_command *fcpcmd, struct io_buffer *iobuf, struct xfer_metadata *meta)
 Receive FCP frame. More...
 
static int fcpdev_scsi_command (struct fcp_device *fcpdev, struct interface *parent, struct scsi_cmd *command)
 Issue FCP SCSI command. More...
 
static void fcpdev_close (struct fcp_device *fcpdev, int rc)
 Close FCP device. More...
 
static size_t fcpdev_window (struct fcp_device *fcpdev)
 Check FCP device flow-control window. More...
 
static int fcpdev_edd_describe (struct fcp_device *fcpdev, struct edd_interface_type *type, union edd_device_path *path)
 Describe FCP device using EDD. More...
 
static struct devicefcpdev_identify_device (struct fcp_device *fcpdev)
 Identify device underlying FCP device. More...
 
static void fcpdev_examine (struct fc_ulp_user *user)
 Examine FCP ULP link state. More...
 
static int fcpdev_open (struct interface *parent, struct fc_name *wwn, struct scsi_lun *lun)
 Open FCP device. More...
 
static int fcp_parse_uri (struct uri *uri, struct fc_name *wwn, struct scsi_lun *lun)
 Parse FCP URI. More...
 
static int fcp_open (struct interface *parent, struct uri *uri)
 Open FCP URI. More...
 

Variables

struct fc_els_prli_descriptor fcp_prli_descriptor __fc_els_prli_descriptor
 FCP PRLI descriptor. More...
 
struct fc_els_handler fcp_prli_handler __fc_els_handler
 FCP PRLI ELS handler. More...
 
static struct interface_operation fcpcmd_scsi_op []
 FCP command SCSI interface operations. More...
 
static struct interface_descriptor fcpcmd_scsi_desc
 FCP command SCSI interface descriptor. More...
 
static struct interface_operation fcpcmd_xchg_op []
 FCP command Fibre Channel exchange interface operations. More...
 
static struct interface_descriptor fcpcmd_xchg_desc
 FCP command Fibre Channel exchange interface descriptor. More...
 
static struct process_descriptor fcpcmd_process_desc
 FCP command process descriptor. More...
 
static struct interface_operation fcpdev_scsi_op []
 FCP device SCSI interface operations. More...
 
static struct interface_descriptor fcpdev_scsi_desc
 FCP device SCSI interface descriptor. More...
 
struct uri_opener fcp_uri_opener __uri_opener
 FCP URI opener. More...
 

Detailed Description

Fibre Channel Protocol.

Definition in file fcp.c.

Macro Definition Documentation

◆ ERANGE_READ_DATA_ORDERING

#define ERANGE_READ_DATA_ORDERING   __einfo_error ( EINFO_ERANGE_READ_DATA_ORDERING )

Definition at line 57 of file fcp.c.

◆ EINFO_ERANGE_READ_DATA_ORDERING

#define EINFO_ERANGE_READ_DATA_ORDERING   __einfo_uniqify ( EINFO_ERANGE, 0x01, "Read data out of order" )

Definition at line 59 of file fcp.c.

◆ ERANGE_READ_DATA_OVERRUN

#define ERANGE_READ_DATA_OVERRUN   __einfo_error ( EINFO_ERANGE_READ_DATA_OVERRUN )

Definition at line 61 of file fcp.c.

◆ EINFO_ERANGE_READ_DATA_OVERRUN

#define EINFO_ERANGE_READ_DATA_OVERRUN   __einfo_uniqify ( EINFO_ERANGE, 0x02, "Read data overrun" )

Definition at line 63 of file fcp.c.

◆ ERANGE_WRITE_DATA_STUCK

#define ERANGE_WRITE_DATA_STUCK   __einfo_error ( EINFO_ERANGE_WRITE_DATA_STUCK )

Definition at line 65 of file fcp.c.

◆ EINFO_ERANGE_WRITE_DATA_STUCK

#define EINFO_ERANGE_WRITE_DATA_STUCK   __einfo_uniqify ( EINFO_ERANGE, 0x03, "Write data stuck" )

Definition at line 67 of file fcp.c.

◆ ERANGE_WRITE_DATA_OVERRUN

#define ERANGE_WRITE_DATA_OVERRUN   __einfo_error ( EINFO_ERANGE_WRITE_DATA_OVERRUN )

Definition at line 69 of file fcp.c.

◆ EINFO_ERANGE_WRITE_DATA_OVERRUN

#define EINFO_ERANGE_WRITE_DATA_OVERRUN   __einfo_uniqify ( EINFO_ERANGE, 0x04, "Write data overrun" )

Definition at line 71 of file fcp.c.

◆ ERANGE_DATA_UNDERRUN

#define ERANGE_DATA_UNDERRUN   __einfo_error ( EINFO_ERANGE_DATA_UNDERRUN )

Definition at line 73 of file fcp.c.

◆ EINFO_ERANGE_DATA_UNDERRUN

#define EINFO_ERANGE_DATA_UNDERRUN   __einfo_uniqify ( EINFO_ERANGE, 0x05, "Data underrun" )

Definition at line 75 of file fcp.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )

◆ fcp_prli_tx()

static int fcp_prli_tx ( struct fc_els els)
static

Transmit FCP PRLI.

Parameters
elsFibre Channel ELS transaction
Return values
rcReturn status code

Definition at line 93 of file fcp.c.

93  {
95 
96  /* Build service parameter page */
97  memset ( &param, 0, sizeof ( param ) );
99 
100  return fc_els_prli_tx ( els, &fcp_prli_descriptor, &param );
101 }
#define FCP_PRLI_NO_READ_RDY
Read FCP_XFER_RDY disabled.
Definition: fcp.h:140
#define htonl(value)
Definition: byteswap.h:133
int fc_els_prli_tx(struct fc_els *els, struct fc_els_prli_descriptor *descriptor, void *param)
Transmit PRLI.
Definition: fcels.c:950
#define FCP_PRLI_INITIATOR
Has initiator functionality.
Definition: fcp.h:146
struct hv_monitor_parameter param[4][32]
Parameters.
Definition: hyperv.h:24
An FCP PRLI service parameter page.
Definition: fcp.h:131
void * memset(void *dest, int character, size_t len) __nonnull

References fc_els_prli_tx(), FCP_PRLI_INITIATOR, FCP_PRLI_NO_READ_RDY, htonl, memset(), and param.

◆ fcp_prli_rx()

static int fcp_prli_rx ( struct fc_els els,
void *  data,
size_t  len 
)
static

Receive FCP PRLI.

Parameters
elsFibre Channel ELS transaction
frameELS frame
lenLength of ELS frame
Return values
rcReturn status code

Definition at line 111 of file fcp.c.

111  {
112  return fc_els_prli_rx ( els, &fcp_prli_descriptor, data, len );
113 }
uint32_t len
Length.
Definition: ena.h:14
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12
int fc_els_prli_rx(struct fc_els *els, struct fc_els_prli_descriptor *descriptor, void *data, size_t len)
Receive PRLI.
Definition: fcels.c:1006

References data, fc_els_prli_rx(), and len.

◆ fcp_prli_detect()

static int fcp_prli_detect ( struct fc_els els,
const void *  data,
size_t  len 
)
static

Detect FCP PRLI.

Parameters
elsFibre Channel ELS transaction
dataELS frame
lenLength of ELS frame
Return values
rcReturn status code

Definition at line 123 of file fcp.c.

124  {
125  return fc_els_prli_detect ( els, &fcp_prli_descriptor, data, len );
126 }
int fc_els_prli_detect(struct fc_els *els __unused, struct fc_els_prli_descriptor *descriptor, const void *data, size_t len)
Detect PRLI.
Definition: fcels.c:1092
uint32_t len
Length.
Definition: ena.h:14
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12

References data, fc_els_prli_detect(), and len.

◆ fcpdev_get()

static struct fcp_device* fcpdev_get ( struct fcp_device fcpdev)
inlinestatic

Get reference to FCP device.

Parameters
fcpdevFCP device
Return values
fcpdevFCP device

Definition at line 204 of file fcp.c.

204  {
205  ref_get ( &fcpdev->refcnt );
206  return fcpdev;
207 }
struct refcnt refcnt
Reference count.
Definition: fcp.c:153
#define ref_get(refcnt)
Get additional reference to object.
Definition: refcnt.h:92

References ref_get, and fcp_device::refcnt.

Referenced by fcpdev_scsi_command().

◆ fcpdev_put()

static void fcpdev_put ( struct fcp_device fcpdev)
inlinestatic

Drop reference to FCP device.

Parameters
fcpdevFCP device

Definition at line 215 of file fcp.c.

215  {
216  ref_put ( &fcpdev->refcnt );
217 }
struct refcnt refcnt
Reference count.
Definition: fcp.c:153
#define ref_put(refcnt)
Drop reference to object.
Definition: refcnt.h:106

References ref_put, and fcp_device::refcnt.

Referenced by fcpcmd_free().

◆ fcpcmd_get()

static struct fcp_command* fcpcmd_get ( struct fcp_command fcpcmd)
inlinestatic

Get reference to FCP command.

Parameters
fcpcmdFCP command
Return values
fcpcmdFCP command

Definition at line 226 of file fcp.c.

226  {
227  ref_get ( &fcpcmd->refcnt );
228  return fcpcmd;
229 }
#define ref_get(refcnt)
Get additional reference to object.
Definition: refcnt.h:92
struct refcnt refcnt
Reference count.
Definition: fcp.c:170

References ref_get, and fcp_command::refcnt.

Referenced by fcpdev_close().

◆ fcpcmd_put()

static void fcpcmd_put ( struct fcp_command fcpcmd)
inlinestatic

Drop reference to FCP command.

Parameters
fcpcmdFCP command

Definition at line 237 of file fcp.c.

237  {
238  ref_put ( &fcpcmd->refcnt );
239 }
struct refcnt refcnt
Reference count.
Definition: fcp.c:170
#define ref_put(refcnt)
Drop reference to object.
Definition: refcnt.h:106

References ref_put, and fcp_command::refcnt.

Referenced by fcpdev_close().

◆ fcpcmd_start_send()

static void fcpcmd_start_send ( struct fcp_command fcpcmd,
int(*)(struct fcp_command *fcpcmd)  send 
)
inlinestatic

Start FCP command sending.

Parameters
fcpcmdFCP command
sendSend method

Definition at line 248 of file fcp.c.

249  {
250  fcpcmd->send = send;
251  process_add ( &fcpcmd->process );
252 }
struct process process
Send process.
Definition: fcp.c:180
void process_add(struct process *process)
Add process to process list.
Definition: process.c:59
int(* send)(struct fcp_command *fcpcmd)
Send current IU.
Definition: fcp.c:186
struct arbelprm_send_doorbell send
Definition: arbel.h:11

References fcp_command::process, process_add(), fcp_command::send, and send.

Referenced by fcpcmd_recv_xfer_rdy(), and fcpdev_scsi_command().

◆ fcpcmd_stop_send()

static void fcpcmd_stop_send ( struct fcp_command fcpcmd)
inlinestatic

Stop FCP command sending.

Parameters
fcpcmdFCP command

Definition at line 260 of file fcp.c.

260  {
261  process_del ( &fcpcmd->process );
262 }
struct process process
Send process.
Definition: fcp.c:180
void process_del(struct process *process)
Remove process from process list.
Definition: process.c:79

References fcp_command::process, and process_del().

Referenced by fcpcmd_close(), fcpcmd_send_cmnd(), and fcpcmd_send_wrdata().

◆ fcpcmd_free()

static void fcpcmd_free ( struct refcnt refcnt)
static

Free FCP command.

Parameters
refcntReference count

Definition at line 269 of file fcp.c.

269  {
270  struct fcp_command *fcpcmd =
271  container_of ( refcnt, struct fcp_command, refcnt );
272 
273  /* Remove from list of commands */
274  list_del ( &fcpcmd->list );
275  fcpdev_put ( fcpcmd->fcpdev );
276 
277  /* Free command */
278  free ( fcpcmd );
279 }
A reference counter.
Definition: refcnt.h:26
#define list_del(list)
Delete an entry from a list.
Definition: list.h:119
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
static void fcpdev_put(struct fcp_device *fcpdev)
Drop reference to FCP device.
Definition: fcp.c:215
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
struct list_head list
List of active commands.
Definition: fcp.c:174
An FCP command.
Definition: fcp.c:168
struct fcp_device * fcpdev
FCP SCSI device.
Definition: fcp.c:172

References container_of, fcp_command::fcpdev, fcpdev_put(), free, fcp_command::list, and list_del.

Referenced by fcpdev_scsi_command().

◆ fcpcmd_close()

static void fcpcmd_close ( struct fcp_command fcpcmd,
int  rc 
)
static

Close FCP command.

Parameters
fcpcmdFCP command
rcReason for close

Definition at line 287 of file fcp.c.

287  {
288  struct fcp_device *fcpdev = fcpcmd->fcpdev;
289 
290  if ( rc != 0 ) {
291  DBGC ( fcpdev, "FCP %p xchg %04x closed: %s\n",
292  fcpdev, fcpcmd->xchg_id, strerror ( rc ) );
293  }
294 
295  /* Stop sending */
296  fcpcmd_stop_send ( fcpcmd );
297 
298  /* Shut down interfaces */
299  intf_shutdown ( &fcpcmd->scsi, rc );
300  intf_shutdown ( &fcpcmd->xchg, rc );
301 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
void intf_shutdown(struct interface *intf, int rc)
Shut down an object interface.
Definition: interface.c:273
#define DBGC(...)
Definition: compiler.h:505
static void fcpcmd_stop_send(struct fcp_command *fcpcmd)
Stop FCP command sending.
Definition: fcp.c:260
struct interface scsi
SCSI command interface.
Definition: fcp.c:176
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
struct interface xchg
Fibre Channel exchange interface.
Definition: fcp.c:178
uint16_t xchg_id
Exchange ID.
Definition: fcp.c:194
struct fcp_device * fcpdev
FCP SCSI device.
Definition: fcp.c:172
An FCP device.
Definition: fcp.c:151

References DBGC, fcpcmd_stop_send(), fcp_command::fcpdev, intf_shutdown(), rc, fcp_command::scsi, strerror(), fcp_command::xchg, and fcp_command::xchg_id.

Referenced by fcpcmd_close_err(), fcpcmd_deliver(), fcpcmd_recv_rsp(), fcpcmd_step(), fcpdev_close(), and fcpdev_scsi_command().

◆ fcpcmd_close_err()

static void fcpcmd_close_err ( struct fcp_command fcpcmd,
int  rc 
)
static

Close FCP command in error.

Parameters
fcpcmdFCP command
rcReason for close

Definition at line 309 of file fcp.c.

309  {
310  if ( rc == 0 )
311  rc = -EPIPE;
312  fcpcmd_close ( fcpcmd, rc );
313 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define EPIPE
Broken pipe.
Definition: errno.h:619
static void fcpcmd_close(struct fcp_command *fcpcmd, int rc)
Close FCP command.
Definition: fcp.c:287

References EPIPE, fcpcmd_close(), and rc.

◆ fcpcmd_send_cmnd()

static int fcpcmd_send_cmnd ( struct fcp_command fcpcmd)
static

Send FCP command IU.

Parameters
fcpcmdFCP command
Return values
rcReturn status code

Definition at line 321 of file fcp.c.

321  {
322  struct fcp_device *fcpdev = fcpcmd->fcpdev;
323  struct scsi_cmd *command = &fcpcmd->command;
324  struct io_buffer *iobuf;
325  struct fcp_cmnd *cmnd;
326  struct xfer_metadata meta;
327  int rc;
328 
329  /* Sanity check */
330  if ( command->data_in_len && command->data_out_len ) {
331  DBGC ( fcpdev, "FCP %p xchg %04x cannot handle bidirectional "
332  "command\n", fcpdev, fcpcmd->xchg_id );
333  return -ENOTSUP;
334  }
335 
336  /* Allocate I/O buffer */
337  iobuf = xfer_alloc_iob ( &fcpcmd->xchg, sizeof ( *cmnd ) );
338  if ( ! iobuf ) {
339  DBGC ( fcpdev, "FCP %p xchg %04x cannot allocate command IU\n",
340  fcpdev, fcpcmd->xchg_id );
341  return -ENOMEM;
342  }
343 
344  /* Construct command IU frame */
345  cmnd = iob_put ( iobuf, sizeof ( *cmnd ) );
346  memset ( cmnd, 0, sizeof ( *cmnd ) );
347  memcpy ( &cmnd->lun, &command->lun, sizeof ( cmnd->lun ) );
348  assert ( ! ( command->data_in_len && command->data_out_len ) );
349  if ( command->data_in_len )
350  cmnd->dirn |= FCP_CMND_RDDATA;
351  if ( command->data_out_len )
352  cmnd->dirn |= FCP_CMND_WRDATA;
353  memcpy ( &cmnd->cdb, &fcpcmd->command.cdb, sizeof ( cmnd->cdb ) );
354  cmnd->len = htonl ( command->data_in_len + command->data_out_len );
355  memset ( &meta, 0, sizeof ( meta ) );
356  meta.flags = ( XFER_FL_CMD_STAT | XFER_FL_OVER );
357  DBGC2 ( fcpdev, "FCP %p xchg %04x CMND " SCSI_CDB_FORMAT " %04x\n",
358  fcpdev, fcpcmd->xchg_id, SCSI_CDB_DATA ( cmnd->cdb ),
359  ntohl ( cmnd->len ) );
360 
361  /* No further data to send within this IU */
362  fcpcmd_stop_send ( fcpcmd );
363 
364  /* Send command IU frame */
365  if ( ( rc = xfer_deliver ( &fcpcmd->xchg, iob_disown ( iobuf ),
366  &meta ) ) != 0 ) {
367  DBGC ( fcpdev, "FCP %p xchg %04x cannot deliver command IU: "
368  "%s\n", fcpdev, fcpcmd->xchg_id, strerror ( rc ) );
369  return rc;
370  }
371 
372  return 0;
373 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define iob_put(iobuf, len)
Definition: iobuf.h:116
Data transfer metadata.
Definition: xfer.h:22
A command-line command.
Definition: command.h:9
union scsi_cdb cdb
SCSI CDB.
Definition: fcp.h:31
An FCP command IU.
Definition: fcp.h:19
#define DBGC(...)
Definition: compiler.h:505
static void fcpcmd_stop_send(struct fcp_command *fcpcmd)
Stop FCP command sending.
Definition: fcp.c:260
#define ntohl(value)
Definition: byteswap.h:134
struct io_buffer * xfer_alloc_iob(struct interface *intf, size_t len)
Allocate I/O buffer.
Definition: xfer.c:157
union scsi_cdb cdb
CDB for this command.
Definition: scsi.h:253
#define htonl(value)
Definition: byteswap.h:133
#define ENOTSUP
Operation not supported.
Definition: errno.h:589
#define ENOMEM
Not enough space.
Definition: errno.h:534
#define iob_disown(iobuf)
Disown an I/O buffer.
Definition: iobuf.h:208
void * memcpy(void *dest, const void *src, size_t len) __nonnull
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
#define FCP_CMND_RDDATA
Command includes data-in.
Definition: fcp.h:40
struct scsi_lun lun
SCSI LUN.
Definition: fcp.h:21
int meta(WINDOW *, bool)
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
struct scsi_cmd command
SCSI command.
Definition: fcp.c:188
#define XFER_FL_CMD_STAT
Data content represents a command or status message.
Definition: xfer.h:60
int xfer_deliver(struct interface *intf, struct io_buffer *iobuf, struct xfer_metadata *meta)
Deliver datagram.
Definition: xfer.c:193
#define SCSI_CDB_DATA(cdb)
printf() parameters for dumping a scsi_cdb
Definition: scsi.h:223
struct interface xchg
Fibre Channel exchange interface.
Definition: fcp.c:178
uint16_t xchg_id
Exchange ID.
Definition: fcp.c:194
A SCSI command information unit.
Definition: scsi.h:249
#define SCSI_CDB_FORMAT
printf() format for dumping a scsi_cdb
Definition: scsi.h:219
#define DBGC2(...)
Definition: compiler.h:522
uint32_t len
Data length.
Definition: fcp.h:33
#define XFER_FL_OVER
Sender is relinquishing use of half-duplex channel.
Definition: xfer.h:50
#define FCP_CMND_WRDATA
Command includes data-out.
Definition: fcp.h:37
uint8_t dirn
Direction.
Definition: fcp.h:29
struct fcp_device * fcpdev
FCP SCSI device.
Definition: fcp.c:172
void * memset(void *dest, int character, size_t len) __nonnull
An FCP device.
Definition: fcp.c:151
A persistent I/O buffer.
Definition: iobuf.h:32

References assert(), scsi_cmd::cdb, fcp_cmnd::cdb, fcp_command::command, DBGC, DBGC2, fcp_cmnd::dirn, ENOMEM, ENOTSUP, FCP_CMND_RDDATA, FCP_CMND_WRDATA, fcpcmd_stop_send(), fcp_command::fcpdev, htonl, iob_disown, iob_put, fcp_cmnd::len, fcp_cmnd::lun, memcpy(), memset(), meta(), ntohl, rc, SCSI_CDB_DATA, SCSI_CDB_FORMAT, strerror(), fcp_command::xchg, fcp_command::xchg_id, xfer_alloc_iob(), xfer_deliver(), XFER_FL_CMD_STAT, and XFER_FL_OVER.

Referenced by fcpdev_scsi_command().

◆ fcpcmd_recv_rddata()

static int fcpcmd_recv_rddata ( struct fcp_command fcpcmd,
struct io_buffer iobuf,
struct xfer_metadata meta 
)
static

Handle FCP read data IU.

Parameters
fcpcmdFCP command
iobufI/O buffer
metaData transfer metadata
Return values
rcReturn status code

Definition at line 383 of file fcp.c.

385  {
386  struct fcp_device *fcpdev = fcpcmd->fcpdev;
387  struct scsi_cmd *command = &fcpcmd->command;
388  size_t offset = meta->offset;
389  size_t len = iob_len ( iobuf );
390  int rc;
391 
392  /* Sanity checks */
393  if ( ! ( meta->flags & XFER_FL_ABS_OFFSET ) ) {
394  DBGC ( fcpdev, "FCP %p xchg %04x read data missing offset\n",
395  fcpdev, fcpcmd->xchg_id );
397  goto done;
398  }
399  if ( offset != fcpcmd->offset ) {
400  DBGC ( fcpdev, "FCP %p xchg %04x read data out of order "
401  "(expected %zd, received %zd)\n",
402  fcpdev, fcpcmd->xchg_id, fcpcmd->offset, offset );
404  goto done;
405  }
406  if ( ( offset + len ) > command->data_in_len ) {
407  DBGC ( fcpdev, "FCP %p xchg %04x read data overrun (max %zd, "
408  "received %zd)\n", fcpdev, fcpcmd->xchg_id,
409  command->data_in_len, ( offset + len ) );
411  goto done;
412  }
413  DBGC2 ( fcpdev, "FCP %p xchg %04x RDDATA [%08zx,%08zx)\n",
414  fcpdev, fcpcmd->xchg_id, offset, ( offset + len ) );
415 
416  /* Copy to user buffer */
417  copy_to_user ( command->data_in, offset, iobuf->data, len );
418  fcpcmd->offset += len;
419  assert ( fcpcmd->offset <= command->data_in_len );
420 
421  rc = 0;
422  done:
423  free_iob ( iobuf );
424  return rc;
425 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define XFER_FL_ABS_OFFSET
Offset is absolute.
Definition: xfer.h:47
A command-line command.
Definition: command.h:9
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:145
#define DBGC(...)
Definition: compiler.h:505
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
static userptr_t size_t offset
Offset of the first segment within the content.
Definition: deflate.h:259
int meta(WINDOW *, bool)
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:151
static __always_inline void copy_to_user(userptr_t dest, off_t dest_off, const void *src, size_t len)
Copy data to user buffer.
Definition: uaccess.h:324
struct scsi_cmd command
SCSI command.
Definition: fcp.c:188
uint16_t xchg_id
Exchange ID.
Definition: fcp.c:194
#define ERANGE_READ_DATA_OVERRUN
Definition: fcp.c:61
size_t offset
Data offset within command.
Definition: fcp.c:190
A SCSI command information unit.
Definition: scsi.h:249
uint32_t len
Length.
Definition: ena.h:14
#define DBGC2(...)
Definition: compiler.h:522
void * data
Start of data.
Definition: iobuf.h:44
struct bofm_section_header done
Definition: bofm_test.c:46
struct fcp_device * fcpdev
FCP SCSI device.
Definition: fcp.c:172
#define ERANGE_READ_DATA_ORDERING
Definition: fcp.c:57
An FCP device.
Definition: fcp.c:151

References assert(), fcp_command::command, copy_to_user(), io_buffer::data, DBGC, DBGC2, done, ERANGE_READ_DATA_ORDERING, ERANGE_READ_DATA_OVERRUN, fcp_command::fcpdev, free_iob(), iob_len(), len, meta(), fcp_command::offset, offset, rc, fcp_command::xchg_id, and XFER_FL_ABS_OFFSET.

Referenced by fcpcmd_deliver().

◆ fcpcmd_send_wrdata()

static int fcpcmd_send_wrdata ( struct fcp_command fcpcmd)
static

Send FCP write data IU.

Parameters
fcpcmdFCP command
Return values
rcReturn status code

Definition at line 433 of file fcp.c.

433  {
434  struct fcp_device *fcpdev = fcpcmd->fcpdev;
435  struct scsi_cmd *command = &fcpcmd->command;
436  struct io_buffer *iobuf;
437  struct xfer_metadata meta;
438  size_t len;
439  int rc;
440 
441  /* Calculate length to be sent */
442  len = xfer_window ( &fcpcmd->xchg );
443  if ( len > fcpcmd->remaining )
444  len = fcpcmd->remaining;
445 
446  /* Sanity checks */
447  if ( len == 0 ) {
448  DBGC ( fcpdev, "FCP %p xchg %04x write data stuck\n",
449  fcpdev, fcpcmd->xchg_id );
450  return -ERANGE_WRITE_DATA_STUCK;
451  }
452  if ( ( fcpcmd->offset + len ) > command->data_out_len ) {
453  DBGC ( fcpdev, "FCP %p xchg %04x write data overrun (max %zd, "
454  "requested %zd)\n", fcpdev, fcpcmd->xchg_id,
455  command->data_out_len, ( fcpcmd->offset + len ) );
457  }
458 
459  /* Allocate I/O buffer */
460  iobuf = xfer_alloc_iob ( &fcpcmd->xchg, len );
461  if ( ! iobuf ) {
462  DBGC ( fcpdev, "FCP %p xchg %04x cannot allocate write data "
463  "IU for %zd bytes\n", fcpdev, fcpcmd->xchg_id, len );
464  return -ENOMEM;
465  }
466 
467  /* Construct data IU frame */
468  copy_from_user ( iob_put ( iobuf, len ), command->data_out,
469  fcpcmd->offset, len );
470  memset ( &meta, 0, sizeof ( meta ) );
472  meta.offset = fcpcmd->offset;
473  DBGC2 ( fcpdev, "FCP %p xchg %04x WRDATA [%08zx,%04zx)\n",
474  fcpdev, fcpcmd->xchg_id, fcpcmd->offset,
475  ( fcpcmd->offset + iob_len ( iobuf ) ) );
476 
477  /* Calculate amount of data remaining to be sent within this IU */
478  assert ( len <= fcpcmd->remaining );
479  fcpcmd->offset += len;
480  fcpcmd->remaining -= len;
481  assert ( fcpcmd->offset <= command->data_out_len );
482  if ( fcpcmd->remaining == 0 ) {
483  fcpcmd_stop_send ( fcpcmd );
484  meta.flags |= XFER_FL_OVER;
485  }
486 
487  /* Send data IU frame */
488  if ( ( rc = xfer_deliver ( &fcpcmd->xchg, iob_disown ( iobuf ),
489  &meta ) ) != 0 ) {
490  DBGC ( fcpdev, "FCP %p xchg %04x cannot deliver write data "
491  "IU: %s\n", fcpdev, fcpcmd->xchg_id, strerror ( rc ) );
492  return rc;
493  }
494 
495  return 0;
496 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define iob_put(iobuf, len)
Definition: iobuf.h:116
Data transfer metadata.
Definition: xfer.h:22
#define ERANGE_WRITE_DATA_OVERRUN
Definition: fcp.c:69
#define ERANGE_WRITE_DATA_STUCK
Definition: fcp.c:65
#define XFER_FL_ABS_OFFSET
Offset is absolute.
Definition: xfer.h:47
A command-line command.
Definition: command.h:9
static __always_inline void copy_from_user(void *dest, userptr_t src, off_t src_off, size_t len)
Copy data from user buffer.
Definition: uaccess.h:337
#define DBGC(...)
Definition: compiler.h:505
static void fcpcmd_stop_send(struct fcp_command *fcpcmd)
Stop FCP command sending.
Definition: fcp.c:260
struct io_buffer * xfer_alloc_iob(struct interface *intf, size_t len)
Allocate I/O buffer.
Definition: xfer.c:157
size_t xfer_window(struct interface *intf)
Check flow control window.
Definition: xfer.c:115
#define XFER_FL_RESPONSE
Data content is a response.
Definition: xfer.h:63
#define ENOMEM
Not enough space.
Definition: errno.h:534
#define iob_disown(iobuf)
Disown an I/O buffer.
Definition: iobuf.h:208
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
int meta(WINDOW *, bool)
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:151
struct scsi_cmd command
SCSI command.
Definition: fcp.c:188
int xfer_deliver(struct interface *intf, struct io_buffer *iobuf, struct xfer_metadata *meta)
Deliver datagram.
Definition: xfer.c:193
struct interface xchg
Fibre Channel exchange interface.
Definition: fcp.c:178
uint16_t xchg_id
Exchange ID.
Definition: fcp.c:194
size_t offset
Data offset within command.
Definition: fcp.c:190
A SCSI command information unit.
Definition: scsi.h:249
uint32_t len
Length.
Definition: ena.h:14
#define DBGC2(...)
Definition: compiler.h:522
size_t remaining
Length of data remaining to be sent within this IU.
Definition: fcp.c:192
#define XFER_FL_OVER
Sender is relinquishing use of half-duplex channel.
Definition: xfer.h:50
struct fcp_device * fcpdev
FCP SCSI device.
Definition: fcp.c:172
void * memset(void *dest, int character, size_t len) __nonnull
An FCP device.
Definition: fcp.c:151
A persistent I/O buffer.
Definition: iobuf.h:32

References assert(), fcp_command::command, copy_from_user(), DBGC, DBGC2, ENOMEM, ERANGE_WRITE_DATA_OVERRUN, ERANGE_WRITE_DATA_STUCK, fcpcmd_stop_send(), fcp_command::fcpdev, iob_disown, iob_len(), iob_put, len, memset(), meta(), fcp_command::offset, rc, fcp_command::remaining, strerror(), fcp_command::xchg, fcp_command::xchg_id, xfer_alloc_iob(), xfer_deliver(), XFER_FL_ABS_OFFSET, XFER_FL_OVER, XFER_FL_RESPONSE, and xfer_window().

Referenced by fcpcmd_recv_xfer_rdy().

◆ fcpcmd_recv_xfer_rdy()

static int fcpcmd_recv_xfer_rdy ( struct fcp_command fcpcmd,
struct io_buffer iobuf,
struct xfer_metadata *meta  __unused 
)
static

Handle FCP transfer ready IU.

Parameters
fcpcmdFCP command
iobufI/O buffer
metaData transfer metadata
Return values
rcReturn status code

Definition at line 506 of file fcp.c.

508  {
509  struct fcp_device *fcpdev = fcpcmd->fcpdev;
510  struct fcp_xfer_rdy *xfer_rdy = iobuf->data;
511  int rc;
512 
513  /* Sanity checks */
514  if ( iob_len ( iobuf ) != sizeof ( *xfer_rdy ) ) {
515  DBGC ( fcpdev, "FCP %p xchg %04x received invalid transfer "
516  "ready IU:\n", fcpdev, fcpcmd->xchg_id );
517  DBGC_HDA ( fcpdev, 0, iobuf->data, iob_len ( iobuf ) );
518  rc = -EPROTO;
519  goto done;
520  }
521  if ( ntohl ( xfer_rdy->offset ) != fcpcmd->offset ) {
522  /* We do not advertise out-of-order delivery */
523  DBGC ( fcpdev, "FCP %p xchg %04x cannot support out-of-order "
524  "delivery (expected %zd, requested %d)\n",
525  fcpdev, fcpcmd->xchg_id, fcpcmd->offset,
526  ntohl ( xfer_rdy->offset ) );
527  rc = -EPROTO;
528  goto done;
529  }
530  DBGC2 ( fcpdev, "FCP %p xchg %04x XFER_RDY [%08x,%08x)\n",
531  fcpdev, fcpcmd->xchg_id, ntohl ( xfer_rdy->offset ),
532  ( ntohl ( xfer_rdy->offset ) + ntohl ( xfer_rdy->len ) ) );
533 
534  /* Start sending requested data */
535  fcpcmd->remaining = ntohl ( xfer_rdy->len );
537 
538  rc = 0;
539  done:
540  free_iob ( iobuf );
541  return rc;
542 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
An FCP transfer ready IU.
Definition: fcp.h:46
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:145
#define DBGC(...)
Definition: compiler.h:505
#define ntohl(value)
Definition: byteswap.h:134
uint32_t offset
Relative offset of data.
Definition: fcp.h:48
static int fcpcmd_send_wrdata(struct fcp_command *fcpcmd)
Send FCP write data IU.
Definition: fcp.c:433
#define DBGC_HDA(...)
Definition: compiler.h:506
static void fcpcmd_start_send(struct fcp_command *fcpcmd, int(*send)(struct fcp_command *fcpcmd))
Start FCP command sending.
Definition: fcp.c:248
#define EPROTO
Protocol error.
Definition: errno.h:624
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:151
uint16_t xchg_id
Exchange ID.
Definition: fcp.c:194
size_t offset
Data offset within command.
Definition: fcp.c:190
#define DBGC2(...)
Definition: compiler.h:522
size_t remaining
Length of data remaining to be sent within this IU.
Definition: fcp.c:192
void * data
Start of data.
Definition: iobuf.h:44
uint32_t len
Burst length.
Definition: fcp.h:50
struct bofm_section_header done
Definition: bofm_test.c:46
struct fcp_device * fcpdev
FCP SCSI device.
Definition: fcp.c:172
An FCP device.
Definition: fcp.c:151

References io_buffer::data, DBGC, DBGC2, DBGC_HDA, done, EPROTO, fcpcmd_send_wrdata(), fcpcmd_start_send(), fcp_command::fcpdev, free_iob(), iob_len(), fcp_xfer_rdy::len, ntohl, fcp_xfer_rdy::offset, fcp_command::offset, rc, fcp_command::remaining, and fcp_command::xchg_id.

Referenced by fcpcmd_deliver().

◆ fcpcmd_recv_rsp()

static int fcpcmd_recv_rsp ( struct fcp_command fcpcmd,
struct io_buffer iobuf,
struct xfer_metadata *meta  __unused 
)
static

Handle FCP response IU.

Parameters
fcpcmdFCP command
iobufI/O buffer
metaData transfer metadata
Return values
rcReturn status code

Definition at line 552 of file fcp.c.

554  {
555  struct fcp_device *fcpdev = fcpcmd->fcpdev;
556  struct scsi_cmd *command = &fcpcmd->command;
557  struct fcp_rsp *rsp = iobuf->data;
558  struct scsi_rsp response;
559  int rc;
560 
561  /* Sanity check */
562  if ( ( iob_len ( iobuf ) < sizeof ( *rsp ) ) ||
563  ( iob_len ( iobuf ) < ( sizeof ( *rsp ) +
565  fcp_rsp_sense_data_len ( rsp ) ) ) ) {
566  DBGC ( fcpdev, "FCP %p xchg %04x received invalid response "
567  "IU:\n", fcpdev, fcpcmd->xchg_id );
568  DBGC_HDA ( fcpdev, 0, iobuf->data, iob_len ( iobuf ) );
569  rc = -EPROTO;
570  goto done;
571  }
572  DBGC2 ( fcpdev, "FCP %p xchg %04x RSP stat %02x resid %08x flags %02x"
573  "%s%s%s%s\n", fcpdev, fcpcmd->xchg_id, rsp->status,
574  ntohl ( rsp->residual ), rsp->flags,
575  ( ( rsp->flags & FCP_RSP_RESPONSE_LEN_VALID ) ? " resp" : "" ),
576  ( ( rsp->flags & FCP_RSP_SENSE_LEN_VALID ) ? " sense" : "" ),
577  ( ( rsp->flags & FCP_RSP_RESIDUAL_OVERRUN ) ? " over" : "" ),
578  ( ( rsp->flags & FCP_RSP_RESIDUAL_UNDERRUN ) ? " under" : "" ));
579  if ( fcp_rsp_response_data ( rsp ) ) {
580  DBGC2 ( fcpdev, "FCP %p xchg %04x response data:\n",
581  fcpdev, fcpcmd->xchg_id );
582  DBGC2_HDA ( fcpdev, 0, fcp_rsp_response_data ( rsp ),
584  }
585  if ( fcp_rsp_sense_data ( rsp ) ) {
586  DBGC2 ( fcpdev, "FCP %p xchg %04x sense data:\n",
587  fcpdev, fcpcmd->xchg_id );
588  DBGC2_HDA ( fcpdev, 0, fcp_rsp_sense_data ( rsp ),
590  }
591 
592  /* Check for locally-detected command underrun */
593  if ( ( rsp->status == 0 ) &&
594  ( fcpcmd->offset != ( command->data_in_len +
595  command->data_out_len ) ) ) {
596  DBGC ( fcpdev, "FCP %p xchg %04x data underrun (expected %zd, "
597  "got %zd)\n", fcpdev, fcpcmd->xchg_id,
598  ( command->data_in_len + command->data_out_len ),
599  fcpcmd->offset );
601  goto done;
602  }
603 
604  /* Build SCSI response */
605  memset ( &response, 0, sizeof ( response ) );
606  response.status = rsp->status;
607  if ( rsp->flags & ( FCP_RSP_RESIDUAL_OVERRUN |
609  response.overrun = ntohl ( rsp->residual );
610  if ( rsp->flags & FCP_RSP_RESIDUAL_UNDERRUN )
611  response.overrun = -response.overrun;
612  }
614  fcp_rsp_sense_data_len ( rsp ), &response.sense );
615 
616  /* Free buffer before sending response, to minimise
617  * out-of-memory errors.
618  */
619  free_iob ( iob_disown ( iobuf ) );
620 
621  /* Send SCSI response */
622  scsi_response ( &fcpcmd->scsi, &response );
623 
624  /* Terminate command */
625  fcpcmd_close ( fcpcmd, 0 );
626 
627  rc = 0;
628  done:
629  free_iob ( iobuf );
630  return rc;
631 }
void scsi_parse_sense(const void *data, size_t len, struct scsi_sns_descriptor *sense)
Parse SCSI sense data.
Definition: scsi.c:146
#define FCP_RSP_RESIDUAL_OVERRUN
Residual represents overrun.
Definition: fcp.h:80
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
A command-line command.
Definition: command.h:9
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:145
#define DBGC(...)
Definition: compiler.h:505
static void fcpcmd_close(struct fcp_command *fcpcmd, int rc)
Close FCP command.
Definition: fcp.c:287
#define ntohl(value)
Definition: byteswap.h:134
#define FCP_RSP_RESIDUAL_UNDERRUN
Residual represents underrun.
Definition: fcp.h:83
#define iob_disown(iobuf)
Disown an I/O buffer.
Definition: iobuf.h:208
static void * fcp_rsp_sense_data(struct fcp_rsp *rsp)
Get sense data portion of FCP response.
Definition: fcp.h:113
A SCSI response information unit.
Definition: scsi.h:322
#define DBGC_HDA(...)
Definition: compiler.h:506
static void * fcp_rsp_response_data(struct fcp_rsp *rsp)
Get response data portion of FCP response.
Definition: fcp.h:91
struct interface scsi
SCSI command interface.
Definition: fcp.c:176
#define EPROTO
Protocol error.
Definition: errno.h:624
#define DBGC2_HDA(...)
Definition: compiler.h:523
uint64_t rsp
Definition: librm.h:267
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:151
static size_t fcp_rsp_response_data_len(struct fcp_rsp *rsp)
Get length of response data portion of FCP response.
Definition: fcp.h:102
struct scsi_cmd command
SCSI command.
Definition: fcp.c:188
uint16_t xchg_id
Exchange ID.
Definition: fcp.c:194
#define FCP_RSP_RESPONSE_LEN_VALID
Response length field is valid.
Definition: fcp.h:74
size_t offset
Data offset within command.
Definition: fcp.c:190
void scsi_response(struct interface *intf, struct scsi_rsp *response)
Report SCSI response.
Definition: scsi.c:206
A SCSI command information unit.
Definition: scsi.h:249
#define DBGC2(...)
Definition: compiler.h:522
void * data
Start of data.
Definition: iobuf.h:44
#define ERANGE_DATA_UNDERRUN
Definition: fcp.c:73
#define FCP_RSP_SENSE_LEN_VALID
Sense length field is valid.
Definition: fcp.h:77
An FCP response IU.
Definition: fcp.h:56
struct bofm_section_header done
Definition: bofm_test.c:46
struct fcp_device * fcpdev
FCP SCSI device.
Definition: fcp.c:172
static size_t fcp_rsp_sense_data_len(struct fcp_rsp *rsp)
Get length of sense data portion of FCP response.
Definition: fcp.h:125
void * memset(void *dest, int character, size_t len) __nonnull
An FCP device.
Definition: fcp.c:151

References fcp_command::command, io_buffer::data, DBGC, DBGC2, DBGC2_HDA, DBGC_HDA, done, EPROTO, ERANGE_DATA_UNDERRUN, FCP_RSP_RESIDUAL_OVERRUN, FCP_RSP_RESIDUAL_UNDERRUN, fcp_rsp_response_data(), fcp_rsp_response_data_len(), FCP_RSP_RESPONSE_LEN_VALID, fcp_rsp_sense_data(), fcp_rsp_sense_data_len(), FCP_RSP_SENSE_LEN_VALID, fcpcmd_close(), fcp_command::fcpdev, free_iob(), iob_disown, iob_len(), memset(), ntohl, fcp_command::offset, scsi_rsp::overrun, rc, rsp, fcp_command::scsi, scsi_parse_sense(), scsi_response(), scsi_rsp::sense, scsi_rsp::status, and fcp_command::xchg_id.

Referenced by fcpcmd_deliver().

◆ fcpcmd_recv_unknown()

static int fcpcmd_recv_unknown ( struct fcp_command fcpcmd,
struct io_buffer iobuf,
struct xfer_metadata *meta  __unused 
)
static

Handle unknown FCP IU.

Parameters
fcpcmdFCP command
iobufI/O buffer
metaData transfer metadata
Return values
rcReturn status code

Definition at line 641 of file fcp.c.

643  {
644  struct fcp_device *fcpdev = fcpcmd->fcpdev;
645 
646  DBGC ( fcpdev, "FCP %p xchg %04x received unknown IU:\n",
647  fcpdev, fcpcmd->xchg_id );
648  DBGC_HDA ( fcpdev, 0, iobuf->data, iob_len ( iobuf ) );
649  free_iob ( iobuf );
650  return -EPROTO;
651 }
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:145
#define DBGC(...)
Definition: compiler.h:505
#define DBGC_HDA(...)
Definition: compiler.h:506
#define EPROTO
Protocol error.
Definition: errno.h:624
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:151
uint16_t xchg_id
Exchange ID.
Definition: fcp.c:194
void * data
Start of data.
Definition: iobuf.h:44
struct fcp_device * fcpdev
FCP SCSI device.
Definition: fcp.c:172
An FCP device.
Definition: fcp.c:151

References io_buffer::data, DBGC, DBGC_HDA, EPROTO, fcp_command::fcpdev, free_iob(), iob_len(), and fcp_command::xchg_id.

Referenced by fcpcmd_deliver().

◆ fcpcmd_step()

static void fcpcmd_step ( struct fcp_command fcpcmd)
static

Transmit FCP frame.

Parameters
fcpcmdFCP command

Definition at line 658 of file fcp.c.

658  {
659  int rc;
660 
661  /* Send the current IU */
662  if ( ( rc = fcpcmd->send ( fcpcmd ) ) != 0 ) {
663  /* Treat failure as a fatal error */
664  fcpcmd_close ( fcpcmd, rc );
665  }
666 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
static void fcpcmd_close(struct fcp_command *fcpcmd, int rc)
Close FCP command.
Definition: fcp.c:287
int(* send)(struct fcp_command *fcpcmd)
Send current IU.
Definition: fcp.c:186

References fcpcmd_close(), rc, and fcp_command::send.

◆ fcpcmd_deliver()

static int fcpcmd_deliver ( struct fcp_command fcpcmd,
struct io_buffer iobuf,
struct xfer_metadata meta 
)
static

Receive FCP frame.

Parameters
fcpcmdFCP command
iobufI/O buffer
metaData transfer metadata
Return values
rcReturn status code

Definition at line 676 of file fcp.c.

678  {
679  int ( * fcpcmd_recv ) ( struct fcp_command *fcpcmd,
680  struct io_buffer *iobuf,
681  struct xfer_metadata *meta );
682  int rc;
683 
684  /* Determine handler */
685  switch ( meta->flags & ( XFER_FL_CMD_STAT | XFER_FL_RESPONSE ) ) {
686  case ( XFER_FL_RESPONSE ) :
687  fcpcmd_recv = fcpcmd_recv_rddata;
688  break;
689  case ( XFER_FL_CMD_STAT ) :
690  fcpcmd_recv = fcpcmd_recv_xfer_rdy;
691  break;
693  fcpcmd_recv = fcpcmd_recv_rsp;
694  break;
695  default:
696  fcpcmd_recv = fcpcmd_recv_unknown;
697  break;
698  }
699 
700  /* Handle IU */
701  if ( ( rc = fcpcmd_recv ( fcpcmd, iob_disown ( iobuf ), meta ) ) != 0 ){
702  /* Treat any error as fatal to the command */
703  fcpcmd_close ( fcpcmd, rc );
704  }
705 
706  return rc;
707 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
Data transfer metadata.
Definition: xfer.h:22
static int fcpcmd_recv_unknown(struct fcp_command *fcpcmd, struct io_buffer *iobuf, struct xfer_metadata *meta __unused)
Handle unknown FCP IU.
Definition: fcp.c:641
static void fcpcmd_close(struct fcp_command *fcpcmd, int rc)
Close FCP command.
Definition: fcp.c:287
static int fcpcmd_recv_rsp(struct fcp_command *fcpcmd, struct io_buffer *iobuf, struct xfer_metadata *meta __unused)
Handle FCP response IU.
Definition: fcp.c:552
#define XFER_FL_RESPONSE
Data content is a response.
Definition: xfer.h:63
#define iob_disown(iobuf)
Disown an I/O buffer.
Definition: iobuf.h:208
static int fcpcmd_recv_rddata(struct fcp_command *fcpcmd, struct io_buffer *iobuf, struct xfer_metadata *meta)
Handle FCP read data IU.
Definition: fcp.c:383
int meta(WINDOW *, bool)
#define XFER_FL_CMD_STAT
Data content represents a command or status message.
Definition: xfer.h:60
static int fcpcmd_recv_xfer_rdy(struct fcp_command *fcpcmd, struct io_buffer *iobuf, struct xfer_metadata *meta __unused)
Handle FCP transfer ready IU.
Definition: fcp.c:506
An FCP command.
Definition: fcp.c:168
A persistent I/O buffer.
Definition: iobuf.h:32

References fcpcmd_close(), fcpcmd_recv_rddata(), fcpcmd_recv_rsp(), fcpcmd_recv_unknown(), fcpcmd_recv_xfer_rdy(), iob_disown, meta(), rc, XFER_FL_CMD_STAT, and XFER_FL_RESPONSE.

◆ fcpdev_scsi_command()

static int fcpdev_scsi_command ( struct fcp_device fcpdev,
struct interface parent,
struct scsi_cmd command 
)
static

Issue FCP SCSI command.

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

Definition at line 740 of file fcp.c.

742  {
743  struct fcp_prli_service_parameters *param = fcpdev->user.ulp->param;
744  struct fcp_command *fcpcmd;
745  int xchg_id;
746  int rc;
747 
748  /* Check link */
749  if ( ( rc = fcpdev->user.ulp->link.rc ) != 0 ) {
750  DBGC ( fcpdev, "FCP %p could not issue command while link is "
751  "down: %s\n", fcpdev, strerror ( rc ) );
752  goto err_link;
753  }
754 
755  /* Check target capability */
756  assert ( param != NULL );
757  assert ( fcpdev->user.ulp->param_len >= sizeof ( *param ) );
758  if ( ! ( param->flags & htonl ( FCP_PRLI_TARGET ) ) ) {
759  DBGC ( fcpdev, "FCP %p could not issue command: not a target\n",
760  fcpdev );
761  rc = -ENOTTY;
762  goto err_target;
763  }
764 
765  /* Allocate and initialise structure */
766  fcpcmd = zalloc ( sizeof ( *fcpcmd ) );
767  if ( ! fcpcmd ) {
768  rc = -ENOMEM;
769  goto err_zalloc;
770  }
771  ref_init ( &fcpcmd->refcnt, fcpcmd_free );
772  intf_init ( &fcpcmd->scsi, &fcpcmd_scsi_desc, &fcpcmd->refcnt );
773  intf_init ( &fcpcmd->xchg, &fcpcmd_xchg_desc, &fcpcmd->refcnt );
775  &fcpcmd->refcnt );
776  fcpcmd->fcpdev = fcpdev_get ( fcpdev );
777  list_add ( &fcpcmd->list, &fcpdev->fcpcmds );
778  memcpy ( &fcpcmd->command, command, sizeof ( fcpcmd->command ) );
779 
780  /* Create new exchange */
781  if ( ( xchg_id = fc_xchg_originate ( &fcpcmd->xchg,
782  fcpdev->user.ulp->peer->port,
783  &fcpdev->user.ulp->peer->port_id,
784  FC_TYPE_FCP ) ) < 0 ) {
785  rc = xchg_id;
786  DBGC ( fcpdev, "FCP %p could not create exchange: %s\n",
787  fcpdev, strerror ( rc ) );
788  goto err_xchg_originate;
789  }
790  fcpcmd->xchg_id = xchg_id;
791 
792  /* Start sending command IU */
794 
795  /* Attach to parent interface, mortalise self, and return */
796  intf_plug_plug ( &fcpcmd->scsi, parent );
797  ref_put ( &fcpcmd->refcnt );
798  return ( FCP_TAG_MAGIC | fcpcmd->xchg_id );
799 
800  err_xchg_originate:
801  fcpcmd_close ( fcpcmd, rc );
802  ref_put ( &fcpcmd->refcnt );
803  err_zalloc:
804  err_target:
805  err_link:
806  return rc;
807 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
struct fc_ulp * ulp
Fibre Channel upper layer protocol.
Definition: fc.h:455
int fc_xchg_originate(struct interface *parent, struct fc_port *port, struct fc_port_id *peer_port_id, unsigned int type)
Originate a new Fibre Channel exchange.
Definition: fc.c:728
struct process process
Send process.
Definition: fcp.c:180
#define list_add(new, head)
Add a new entry to the head of a list.
Definition: list.h:69
#define ref_init(refcnt, free)
Initialise a reference counter.
Definition: refcnt.h:64
A command-line command.
Definition: command.h:9
Fibre Channel Protocol.
Definition: fc.h:193
#define DBGC(...)
Definition: compiler.h:505
static int fcpcmd_send_cmnd(struct fcp_command *fcpcmd)
Send FCP command IU.
Definition: fcp.c:321
void intf_plug_plug(struct interface *a, struct interface *b)
Plug two object interfaces together.
Definition: interface.c:102
static void fcpcmd_close(struct fcp_command *fcpcmd, int rc)
Close FCP command.
Definition: fcp.c:287
static struct process_descriptor fcpcmd_process_desc
FCP command process descriptor.
Definition: fcp.c:729
struct fc_peer * peer
Fibre Channel peer.
Definition: fc.h:417
#define htonl(value)
Definition: byteswap.h:133
static void fcpcmd_free(struct refcnt *refcnt)
Free FCP command.
Definition: fcp.c:269
struct fc_port * port
Fibre Channel port, if known.
Definition: fc.h:354
#define ENOMEM
Not enough space.
Definition: errno.h:534
void * memcpy(void *dest, const void *src, size_t len) __nonnull
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
static struct interface_descriptor fcpcmd_xchg_desc
FCP command Fibre Channel exchange interface descriptor.
Definition: fcp.c:725
size_t param_len
Service parameter length.
Definition: fc.h:433
static void fcpcmd_start_send(struct fcp_command *fcpcmd, int(*send)(struct fcp_command *fcpcmd))
Start FCP command sending.
Definition: fcp.c:248
struct interface scsi
SCSI command interface.
Definition: fcp.c:176
static struct fcp_device * fcpdev_get(struct fcp_device *fcpdev)
Get reference to FCP device.
Definition: fcp.c:204
#define FCP_TAG_MAGIC
FCP tag magic marker.
Definition: fcp.h:43
struct fc_port_id port_id
Peer port ID, if known.
Definition: fc.h:356
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:624
void * param
Service parameters, if any.
Definition: fc.h:431
struct hv_monitor_parameter param[4][32]
Parameters.
Definition: hyperv.h:24
struct fc_link_state link
Link state monitor.
Definition: fc.h:427
struct scsi_cmd command
SCSI command.
Definition: fcp.c:188
struct interface xchg
Fibre Channel exchange interface.
Definition: fcp.c:178
uint16_t xchg_id
Exchange ID.
Definition: fcp.c:194
#define FCP_PRLI_TARGET
Has target functionality.
Definition: fcp.h:143
static void process_init_stopped(struct process *process, struct process_descriptor *desc, struct refcnt *refcnt)
Initialise process without adding to process list.
Definition: process.h:145
struct list_head list
List of active commands.
Definition: fcp.c:174
static struct interface_descriptor fcpcmd_scsi_desc
FCP command SCSI interface descriptor.
Definition: fcp.c:715
An FCP PRLI service parameter page.
Definition: fcp.h:131
#define ENOTTY
Inappropriate I/O control operation.
Definition: errno.h:594
struct refcnt refcnt
Reference count.
Definition: fcp.c:170
struct list_head fcpcmds
List of active commands.
Definition: fcp.c:159
struct fc_ulp_user user
Fibre Channel upper-layer protocol user.
Definition: fcp.c:155
static void intf_init(struct interface *intf, struct interface_descriptor *desc, struct refcnt *refcnt)
Initialise an object interface.
Definition: interface.h:173
An FCP command.
Definition: fcp.c:168
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
struct fcp_device * fcpdev
FCP SCSI device.
Definition: fcp.c:172
#define ref_put(refcnt)
Drop reference to object.
Definition: refcnt.h:106

References assert(), fcp_command::command, DBGC, ENOMEM, ENOTTY, FC_TYPE_FCP, fc_xchg_originate(), FCP_PRLI_TARGET, FCP_TAG_MAGIC, fcpcmd_close(), fcpcmd_free(), fcpcmd_process_desc, fcpcmd_scsi_desc, fcpcmd_send_cmnd(), fcpcmd_start_send(), fcpcmd_xchg_desc, fcp_device::fcpcmds, fcp_command::fcpdev, fcpdev_get(), htonl, intf_init(), intf_plug_plug(), fc_ulp::link, fcp_command::list, list_add, memcpy(), NULL, param, fc_ulp::param, fc_ulp::param_len, fc_ulp::peer, fc_peer::port, fc_peer::port_id, fcp_command::process, process_init_stopped(), fc_link_state::rc, rc, ref_init, ref_put, fcp_command::refcnt, fcp_command::scsi, strerror(), fc_ulp_user::ulp, fcp_device::user, fcp_command::xchg, fcp_command::xchg_id, and zalloc().

◆ fcpdev_close()

static void fcpdev_close ( struct fcp_device fcpdev,
int  rc 
)
static

Close FCP device.

Parameters
fcpdevFCP device
rcReason for close

Definition at line 815 of file fcp.c.

815  {
816  struct fcp_command *fcpcmd;
817  struct fcp_command *tmp;
818 
819  DBGC ( fcpdev, "FCP %p closed: %s\n", fcpdev, strerror ( rc ) );
820 
821  /* Shut down interfaces */
822  intf_shutdown ( &fcpdev->scsi, rc );
823 
824  /* Shut down any active commands */
826  fcpcmd_get ( fcpcmd );
827  fcpcmd_close ( fcpcmd, rc );
828  fcpcmd_put ( fcpcmd );
829  }
830 
831  /* Drop reference to ULP */
832  fc_ulp_detach ( &fcpdev->user );
833 }
void fc_ulp_detach(struct fc_ulp_user *user)
Detach Fibre Channel upper-layer protocol user.
Definition: fc.c:1625
static struct fcp_command * fcpcmd_get(struct fcp_command *fcpcmd)
Get reference to FCP command.
Definition: fcp.c:226
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
void intf_shutdown(struct interface *intf, int rc)
Shut down an object interface.
Definition: interface.c:273
#define DBGC(...)
Definition: compiler.h:505
static void fcpcmd_close(struct fcp_command *fcpcmd, int rc)
Close FCP command.
Definition: fcp.c:287
struct interface scsi
SCSI command issuing interface.
Definition: fcp.c:157
#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:447
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
uint8_t * tmp
Definition: entropy.h:156
struct list_head list
List of active commands.
Definition: fcp.c:174
static void fcpcmd_put(struct fcp_command *fcpcmd)
Drop reference to FCP command.
Definition: fcp.c:237
struct list_head fcpcmds
List of active commands.
Definition: fcp.c:159
struct fc_ulp_user user
Fibre Channel upper-layer protocol user.
Definition: fcp.c:155
An FCP command.
Definition: fcp.c:168
struct fcp_device * fcpdev
FCP SCSI device.
Definition: fcp.c:172

References DBGC, fc_ulp_detach(), fcpcmd_close(), fcpcmd_get(), fcpcmd_put(), fcp_device::fcpcmds, fcp_command::fcpdev, intf_shutdown(), fcp_command::list, list_for_each_entry_safe, rc, fcp_device::scsi, strerror(), tmp, and fcp_device::user.

Referenced by fcpdev_open().

◆ fcpdev_window()

static size_t fcpdev_window ( struct fcp_device fcpdev)
static

Check FCP device flow-control window.

Parameters
fcpdevFCP device
Return values
lenLength of window

Definition at line 841 of file fcp.c.

841  {
842  return ( fc_link_ok ( &fcpdev->user.ulp->link ) ?
843  ~( ( size_t ) 0 ) : 0 );
844 }
struct fc_ulp * ulp
Fibre Channel upper layer protocol.
Definition: fc.h:455
static int fc_link_ok(struct fc_link_state *link)
Check Fibre Channel link state.
Definition: fc.h:108
struct fc_link_state link
Link state monitor.
Definition: fc.h:427
struct fc_ulp_user user
Fibre Channel upper-layer protocol user.
Definition: fcp.c:155
struct fcp_device * fcpdev
FCP SCSI device.
Definition: fcp.c:172

References fc_link_ok(), fcp_command::fcpdev, fc_ulp::link, fc_ulp_user::ulp, and fcp_device::user.

◆ fcpdev_edd_describe()

static int fcpdev_edd_describe ( struct fcp_device fcpdev,
struct edd_interface_type type,
union edd_device_path path 
)
static

Describe FCP device using EDD.

Parameters
fcpdevFCP device
typeEDD interface type
pathEDD device path
Return values
rcReturn status code

Definition at line 854 of file fcp.c.

856  {
857  union {
858  struct fc_name fc;
859  uint64_t u64;
860  } wwn;
861  union {
862  struct scsi_lun scsi;
863  uint64_t u64;
864  } lun;
865 
867  memcpy ( &wwn.fc, &fcpdev->wwn, sizeof ( wwn.fc ) );
868  path->fibre.wwn = be64_to_cpu ( wwn.u64 );
869  memcpy ( &lun.scsi, &fcpdev->lun, sizeof ( lun.scsi ) );
870  path->fibre.lun = be64_to_cpu ( lun.u64 );
871  return 0;
872 }
#define EDD_INTF_TYPE_FIBRE
EDD Fibre Channel interface type.
Definition: edd.h:65
uint64_t wwn
WWN.
Definition: edd.h:131
u16 fc
802.11 Frame Control field
Definition: ieee80211.h:14
uint8_t type
Type.
Definition: ena.h:16
unsigned long long uint64_t
Definition: stdint.h:13
#define cpu_to_le64(value)
Definition: byteswap.h:108
void * memcpy(void *dest, const void *src, size_t len) __nonnull
uint64_t u64
Definition: stdint.h:25
uint8_t lun
Logical Unit Number.
Definition: edd.h:32
#define be64_to_cpu(value)
Definition: byteswap.h:117
struct fc_name wwn
Fibre Channel WWN (for boot firmware table)
Definition: fcp.c:162
uint8_t lun
Logical Unit Number.
Definition: edd.h:109
struct scsi_lun lun
SCSI LUN (for boot firmware table)
Definition: fcp.c:164
A Fibre Channel name.
Definition: fc.h:29
A SCSI LUN.
Definition: scsi.h:236
uint64_t wwn
WWN.
Definition: edd.h:30

References be64_to_cpu, cpu_to_le64, EDD_INTF_TYPE_FIBRE, fc, lun, edd_device_path::lun, fcp_device::lun, memcpy(), type, wwn, edd_device_path::wwn, and fcp_device::wwn.

◆ fcpdev_identify_device()

static struct device* fcpdev_identify_device ( struct fcp_device fcpdev)
static

Identify device underlying FCP device.

Parameters
fcpdevFCP device
Return values
deviceUnderlying device

Definition at line 880 of file fcp.c.

880  {
881 
882  /* We know the underlying device only if the link is up;
883  * otherwise we don't have a port to examine.
884  */
885  if ( ! fc_link_ok ( &fcpdev->user.ulp->link ) ) {
886  DBGC ( fcpdev, "FCP %p doesn't know underlying device "
887  "until link is up\n", fcpdev );
888  return NULL;
889  }
890 
891  /* Hand off to port's transport interface */
892  assert ( fcpdev->user.ulp->peer->port != NULL );
893  return identify_device ( &fcpdev->user.ulp->peer->port->transport );
894 }
struct fc_ulp * ulp
Fibre Channel upper layer protocol.
Definition: fc.h:455
#define DBGC(...)
Definition: compiler.h:505
struct fc_peer * peer
Fibre Channel peer.
Definition: fc.h:417
struct fc_port * port
Fibre Channel port, if known.
Definition: fc.h:354
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
static int fc_link_ok(struct fc_link_state *link)
Check Fibre Channel link state.
Definition: fc.h:108
struct fc_link_state link
Link state monitor.
Definition: fc.h:427
struct interface transport
Transport interface.
Definition: fc.h:261
struct device * identify_device(struct interface *intf)
Identify a device behind an interface.
Definition: device.c:125
struct fc_ulp_user user
Fibre Channel upper-layer protocol user.
Definition: fcp.c:155
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362

References assert(), DBGC, fc_link_ok(), identify_device(), fc_ulp::link, NULL, fc_ulp::peer, fc_peer::port, fc_port::transport, fc_ulp_user::ulp, and fcp_device::user.

◆ fcpdev_examine()

static void fcpdev_examine ( struct fc_ulp_user user)
static

Examine FCP ULP link state.

Parameters
userFibre Channel upper-layer protocol user

Definition at line 915 of file fcp.c.

915  {
916  struct fcp_device *fcpdev =
917  container_of ( user, struct fcp_device, user );
918 
919  if ( fc_link_ok ( &fcpdev->user.ulp->link ) ) {
920  DBGC ( fcpdev, "FCP %p link is up\n", fcpdev );
921  } else {
922  DBGC ( fcpdev, "FCP %p link is down: %s\n",
923  fcpdev, strerror ( fcpdev->user.ulp->link.rc ) );
924  }
925 
926  /* Notify SCSI layer of window change */
927  xfer_window_changed ( &fcpdev->scsi );
928 }
void xfer_window_changed(struct interface *intf)
Report change of flow control window.
Definition: xfer.c:145
struct fc_ulp * ulp
Fibre Channel upper layer protocol.
Definition: fc.h:455
#define DBGC(...)
Definition: compiler.h:505
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
struct ntlm_data user
User name.
Definition: ntlm.h:20
static int fc_link_ok(struct fc_link_state *link)
Check Fibre Channel link state.
Definition: fc.h:108
struct interface scsi
SCSI command issuing interface.
Definition: fcp.c:157
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
struct fc_link_state link
Link state monitor.
Definition: fc.h:427
struct fc_ulp_user user
Fibre Channel upper-layer protocol user.
Definition: fcp.c:155
An FCP device.
Definition: fcp.c:151

References container_of, DBGC, fc_link_ok(), fc_ulp::link, fc_link_state::rc, fcp_device::scsi, strerror(), fc_ulp_user::ulp, user, fcp_device::user, and xfer_window_changed().

Referenced by fcpdev_open().

◆ fcpdev_open()

static int fcpdev_open ( struct interface parent,
struct fc_name wwn,
struct scsi_lun lun 
)
static

Open FCP device.

Parameters
parentParent interface
wwnFibre Channel WWN
lunSCSI LUN
Return values
rcReturn status code

Definition at line 938 of file fcp.c.

939  {
940  struct fc_ulp *ulp;
941  struct fcp_device *fcpdev;
942  int rc;
943 
944  /* Get Fibre Channel ULP interface */
946  if ( ! ulp ) {
947  rc = -ENOMEM;
948  goto err_ulp_get;
949  }
950 
951  /* Allocate and initialise structure */
952  fcpdev = zalloc ( sizeof ( *fcpdev ) );
953  if ( ! fcpdev ) {
954  rc = -ENOMEM;
955  goto err_zalloc;
956  }
957  ref_init ( &fcpdev->refcnt, NULL );
958  intf_init ( &fcpdev->scsi, &fcpdev_scsi_desc, &fcpdev->refcnt );
959  INIT_LIST_HEAD ( &fcpdev->fcpcmds );
960  fc_ulp_user_init ( &fcpdev->user, fcpdev_examine, &fcpdev->refcnt );
961 
962  DBGC ( fcpdev, "FCP %p opened for %s\n", fcpdev, fc_ntoa ( wwn ) );
963 
964  /* Attach to Fibre Channel ULP */
965  fc_ulp_attach ( ulp, &fcpdev->user );
966 
967  /* Preserve parameters required for boot firmware table */
968  memcpy ( &fcpdev->wwn, wwn, sizeof ( fcpdev->wwn ) );
969  memcpy ( &fcpdev->lun, lun, sizeof ( fcpdev->lun ) );
970 
971  /* Attach SCSI device to parent interface */
972  if ( ( rc = scsi_open ( parent, &fcpdev->scsi, lun ) ) != 0 ) {
973  DBGC ( fcpdev, "FCP %p could not create SCSI device: %s\n",
974  fcpdev, strerror ( rc ) );
975  goto err_scsi_open;
976  }
977 
978  /* Drop temporary reference to ULP */
979  fc_ulp_put ( ulp );
980 
981  /* Mortalise self and return */
982  ref_put ( &fcpdev->refcnt );
983  return 0;
984 
985  err_scsi_open:
986  fcpdev_close ( fcpdev, rc );
987  ref_put ( &fcpdev->refcnt );
988  err_zalloc:
989  fc_ulp_put ( ulp );
990  err_ulp_get:
991  return rc;
992 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
static struct interface_descriptor fcpdev_scsi_desc
FCP device SCSI interface descriptor.
Definition: fcp.c:907
#define ref_init(refcnt, free)
Initialise a reference counter.
Definition: refcnt.h:64
Fibre Channel Protocol.
Definition: fc.h:193
#define DBGC(...)
Definition: compiler.h:505
const char * fc_ntoa(const struct fc_name *wwn)
Format Fibre Channel WWN.
Definition: fc.c:127
int scsi_open(struct interface *block, struct interface *scsi, struct scsi_lun *lun)
Open SCSI device.
Definition: scsi.c:980
struct refcnt refcnt
Reference count.
Definition: fcp.c:153
#define ENOMEM
Not enough space.
Definition: errno.h:534
void * memcpy(void *dest, const void *src, size_t len) __nonnull
void fc_ulp_attach(struct fc_ulp *ulp, struct fc_ulp_user *user)
Attach Fibre Channel upper-layer protocol user.
Definition: fc.c:1607
struct interface scsi
SCSI command issuing interface.
Definition: fcp.c:157
uint8_t lun
Logical Unit Number.
Definition: edd.h:32
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:624
struct fc_name wwn
Fibre Channel WWN (for boot firmware table)
Definition: fcp.c:162
struct scsi_lun lun
SCSI LUN (for boot firmware table)
Definition: fcp.c:164
#define INIT_LIST_HEAD(list)
Initialise a list head.
Definition: list.h:45
static void fc_ulp_put(struct fc_ulp *ulp)
Drop reference to Fibre Channel upper-layer protocol.
Definition: fc.h:485
static void fcpdev_examine(struct fc_ulp_user *user)
Examine FCP ULP link state.
Definition: fcp.c:915
struct list_head fcpcmds
List of active commands.
Definition: fcp.c:159
struct fc_ulp_user user
Fibre Channel upper-layer protocol user.
Definition: fcp.c:155
static void intf_init(struct interface *intf, struct interface_descriptor *desc, struct refcnt *refcnt)
Initialise an object interface.
Definition: interface.h:173
struct fc_ulp * fc_ulp_get_wwn_type(const struct fc_name *port_wwn, unsigned int type)
Get Fibre Channel upper-layer protocol by port name and type.
Definition: fc.c:1880
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
static void fc_ulp_user_init(struct fc_ulp_user *user, void(*examine)(struct fc_ulp_user *user), struct refcnt *refcnt)
Initialise Fibre Channel upper-layer protocol user.
Definition: fc.h:519
#define ref_put(refcnt)
Drop reference to object.
Definition: refcnt.h:106
A Fibre Channel upper-layer protocol.
Definition: fc.h:413
uint64_t wwn
WWN.
Definition: edd.h:30
An FCP device.
Definition: fcp.c:151
static void fcpdev_close(struct fcp_device *fcpdev, int rc)
Close FCP device.
Definition: fcp.c:815

References DBGC, ENOMEM, fc_ntoa(), FC_TYPE_FCP, fc_ulp_attach(), fc_ulp_get_wwn_type(), fc_ulp_put(), fc_ulp_user_init(), fcp_device::fcpcmds, fcpdev_close(), fcpdev_examine(), fcpdev_scsi_desc, INIT_LIST_HEAD, intf_init(), lun, fcp_device::lun, memcpy(), NULL, rc, ref_init, ref_put, fcp_device::refcnt, fcp_device::scsi, scsi_open(), strerror(), fcp_device::user, wwn, fcp_device::wwn, and zalloc().

Referenced by fcp_open().

◆ fcp_parse_uri()

static int fcp_parse_uri ( struct uri uri,
struct fc_name wwn,
struct scsi_lun lun 
)
static

Parse FCP URI.

Parameters
uriURI
Return values
wwnFibre Channel WWN
lunSCSI LUN
rcReturn status code

An FCP URI has the form "fcp:<wwn>:<lun>" or "fcp://<wwn>/<lun>"

Definition at line 1011 of file fcp.c.

1012  {
1013  char wwn_buf[ FC_NAME_STRLEN + 1 /* NUL */ ];
1014  const char *wwn_text;
1015  const char *lun_text;
1016  int rc;
1017 
1018  /* Extract WWN and LUN texts from URI */
1019  if ( uri->opaque ) {
1020  /* "fcp:<wwn>:<lun>" */
1021  if ( snprintf ( wwn_buf, sizeof ( wwn_buf ), "%s",
1022  uri->opaque ) < ( FC_NAME_STRLEN + 1 /* : */ ) )
1023  return -EINVAL;
1024  if ( uri->opaque[FC_NAME_STRLEN] != ':' )
1025  return -EINVAL;
1026  wwn_text = wwn_buf;
1027  lun_text = &uri->opaque[FC_NAME_STRLEN + 1];
1028  } else {
1029  /* If host exists, path must also exist */
1030  if ( ! ( uri->host && uri->path ) )
1031  return -EINVAL;
1032  if ( uri->path[0] != '/' )
1033  return -EINVAL;
1034  wwn_text = uri->host;
1035  lun_text = ( uri->path + 1 );
1036  }
1037 
1038  /* Parse WWN */
1039  if ( ( rc = fc_aton ( wwn_text, wwn ) ) != 0 )
1040  return rc;
1041 
1042  /* Parse LUN */
1043  if ( ( rc = scsi_parse_lun ( lun_text, lun ) ) != 0 )
1044  return rc;
1045 
1046  return 0;
1047 }
#define EINVAL
Invalid argument.
Definition: errno.h:428
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
int fc_aton(const char *wwn_text, struct fc_name *wwn)
Parse Fibre Channel WWN.
Definition: fc.c:144
int scsi_parse_lun(const char *lun_string, struct scsi_lun *lun)
Parse SCSI LUN.
Definition: scsi.c:117
const char * path
Path.
Definition: uri.h:66
uint8_t lun
Logical Unit Number.
Definition: edd.h:32
const char * host
Host name.
Definition: uri.h:62
const char * opaque
Opaque part.
Definition: uri.h:56
int snprintf(char *buf, size_t size, const char *fmt,...)
Write a formatted string to a buffer.
Definition: vsprintf.c:382
A Uniform Resource Identifier.
Definition: uri.h:50
#define FC_NAME_STRLEN
Length of Fibre Channel name text.
Definition: fc.h:34
uint64_t wwn
WWN.
Definition: edd.h:30

References EINVAL, fc_aton(), FC_NAME_STRLEN, uri::host, lun, uri::opaque, uri::path, rc, scsi_parse_lun(), snprintf(), and wwn.

Referenced by fcp_open().

◆ fcp_open()

static int fcp_open ( struct interface parent,
struct uri uri 
)
static

Open FCP URI.

Parameters
parentParent interface
uriURI
Return values
rcReturn status code

Definition at line 1056 of file fcp.c.

1056  {
1057  struct fc_name wwn;
1058  struct scsi_lun lun;
1059  int rc;
1060 
1061  /* Parse URI */
1062  if ( ( rc = fcp_parse_uri ( uri, &wwn, &lun ) ) != 0 )
1063  return rc;
1064 
1065  /* Open FCP device */
1066  if ( ( rc = fcpdev_open ( parent, &wwn, &lun ) ) != 0 )
1067  return rc;
1068 
1069  return 0;
1070 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
static int fcpdev_open(struct interface *parent, struct fc_name *wwn, struct scsi_lun *lun)
Open FCP device.
Definition: fcp.c:938
static int fcp_parse_uri(struct uri *uri, struct fc_name *wwn, struct scsi_lun *lun)
Parse FCP URI.
Definition: fcp.c:1011
uint8_t lun
Logical Unit Number.
Definition: edd.h:32
A Fibre Channel name.
Definition: fc.h:29
A Uniform Resource Identifier.
Definition: uri.h:50
A SCSI LUN.
Definition: scsi.h:236
uint64_t wwn
WWN.
Definition: edd.h:30

References fcp_parse_uri(), fcpdev_open(), lun, rc, and wwn.

Variable Documentation

◆ __fc_els_prli_descriptor

struct fc_els_prli_descriptor fcp_prli_descriptor __fc_els_prli_descriptor
Initial value:
= {
.type = FC_TYPE_FCP,
.param_len = sizeof ( struct fcp_prli_service_parameters ),
.handler = &fcp_prli_handler,
}
Fibre Channel Protocol.
Definition: fc.h:193
An FCP PRLI service parameter page.
Definition: fcp.h:131

FCP PRLI descriptor.

Definition at line 85 of file fcp.c.

◆ __fc_els_handler

struct fc_els_handler fcp_prli_handler __fc_els_handler
Initial value:
= {
.name = "PRLI-FCP",
.tx = fcp_prli_tx,
.rx = fcp_prli_rx,
.detect = fcp_prli_detect,
}
static int fcp_prli_rx(struct fc_els *els, void *data, size_t len)
Receive FCP PRLI.
Definition: fcp.c:111
static int fcp_prli_detect(struct fc_els *els, const void *data, size_t len)
Detect FCP PRLI.
Definition: fcp.c:123
static int fcp_prli_tx(struct fc_els *els)
Transmit FCP PRLI.
Definition: fcp.c:93

FCP PRLI ELS handler.

Definition at line 129 of file fcp.c.

◆ fcpcmd_scsi_op

struct interface_operation fcpcmd_scsi_op[]
static
Initial value:
= {
}
void intf_close(struct interface *intf, int rc)
Close an object interface.
Definition: interface.c:244
static void fcpcmd_close(struct fcp_command *fcpcmd, int rc)
Close FCP command.
Definition: fcp.c:287
#define INTF_OP(op_type, object_type, op_func)
Define an object interface operation.
Definition: interface.h:32
An FCP command.
Definition: fcp.c:168

FCP command SCSI interface operations.

Definition at line 710 of file fcp.c.

◆ fcpcmd_scsi_desc

struct interface_descriptor fcpcmd_scsi_desc
static
Initial value:
=
static struct interface_operation fcpcmd_scsi_op[]
FCP command SCSI interface operations.
Definition: fcp.c:710
#define INTF_DESC_PASSTHRU(object_type, intf, operations, passthru)
Define an object interface descriptor with pass-through interface.
Definition: interface.h:82
An FCP command.
Definition: fcp.c:168

FCP command SCSI interface descriptor.

Definition at line 715 of file fcp.c.

Referenced by fcpdev_scsi_command().

◆ fcpcmd_xchg_op

struct interface_operation fcpcmd_xchg_op[]
static
Initial value:
= {
}
void intf_close(struct interface *intf, int rc)
Close an object interface.
Definition: interface.c:244
static int fcpcmd_deliver(struct fcp_command *fcpcmd, struct io_buffer *iobuf, struct xfer_metadata *meta)
Receive FCP frame.
Definition: fcp.c:676
#define INTF_OP(op_type, object_type, op_func)
Define an object interface operation.
Definition: interface.h:32
int xfer_deliver(struct interface *intf, struct io_buffer *iobuf, struct xfer_metadata *meta)
Deliver datagram.
Definition: xfer.c:193
An FCP command.
Definition: fcp.c:168
static void fcpcmd_close_err(struct fcp_command *fcpcmd, int rc)
Close FCP command in error.
Definition: fcp.c:309

FCP command Fibre Channel exchange interface operations.

Definition at line 719 of file fcp.c.

◆ fcpcmd_xchg_desc

struct interface_descriptor fcpcmd_xchg_desc
static
Initial value:
=
static struct interface_operation fcpcmd_xchg_op[]
FCP command Fibre Channel exchange interface operations.
Definition: fcp.c:719
#define INTF_DESC_PASSTHRU(object_type, intf, operations, passthru)
Define an object interface descriptor with pass-through interface.
Definition: interface.h:82
An FCP command.
Definition: fcp.c:168

FCP command Fibre Channel exchange interface descriptor.

Definition at line 725 of file fcp.c.

Referenced by fcpdev_scsi_command().

◆ fcpcmd_process_desc

struct process_descriptor fcpcmd_process_desc
static
Initial value:
=
A process.
Definition: process.h:17
static void fcpcmd_step(struct fcp_command *fcpcmd)
Transmit FCP frame.
Definition: fcp.c:658
#define PROC_DESC(object_type, process, _step)
Define a process descriptor.
Definition: process.h:82
An FCP command.
Definition: fcp.c:168

FCP command process descriptor.

Definition at line 729 of file fcp.c.

Referenced by fcpdev_scsi_command().

◆ fcpdev_scsi_op

struct interface_operation fcpdev_scsi_op[]
static
Initial value:
= {
}
void intf_close(struct interface *intf, int rc)
Close an object interface.
Definition: interface.c:244
int edd_describe(struct interface *intf, struct edd_interface_type *type, union edd_device_path *path)
Describe a disk device using EDD.
Definition: edd.c:44
size_t xfer_window(struct interface *intf)
Check flow control window.
Definition: xfer.c:115
static int fcpdev_scsi_command(struct fcp_device *fcpdev, struct interface *parent, struct scsi_cmd *command)
Issue FCP SCSI command.
Definition: fcp.c:740
A SCSI command.
Definition: scsi.c:262
#define INTF_OP(op_type, object_type, op_func)
Define an object interface operation.
Definition: interface.h:32
static size_t fcpdev_window(struct fcp_device *fcpdev)
Check FCP device flow-control window.
Definition: fcp.c:841
static struct device * fcpdev_identify_device(struct fcp_device *fcpdev)
Identify device underlying FCP device.
Definition: fcp.c:880
struct device * identify_device(struct interface *intf)
Identify a device behind an interface.
Definition: device.c:125
static int fcpdev_edd_describe(struct fcp_device *fcpdev, struct edd_interface_type *type, union edd_device_path *path)
Describe FCP device using EDD.
Definition: fcp.c:854
An FCP device.
Definition: fcp.c:151
static void fcpdev_close(struct fcp_device *fcpdev, int rc)
Close FCP device.
Definition: fcp.c:815

FCP device SCSI interface operations.

Definition at line 897 of file fcp.c.

◆ fcpdev_scsi_desc

struct interface_descriptor fcpdev_scsi_desc
static
Initial value:
=
static struct interface_operation fcpdev_scsi_op[]
FCP device SCSI interface operations.
Definition: fcp.c:897
#define INTF_DESC(object_type, intf, operations)
Define an object interface descriptor.
Definition: interface.h:65
An FCP device.
Definition: fcp.c:151

FCP device SCSI interface descriptor.

Definition at line 907 of file fcp.c.

Referenced by fcpdev_open().

◆ __uri_opener

struct uri_opener fcp_uri_opener __uri_opener
Initial value:
= {
.scheme = "fcp",
.open = fcp_open,
}
static int fcp_open(struct interface *parent, struct uri *uri)
Open FCP URI.
Definition: fcp.c:1056

FCP URI opener.

Definition at line 1073 of file fcp.c.