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

Variables

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

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 58 of file fcp.c.

58#define ERANGE_READ_DATA_ORDERING \
59 __einfo_error ( EINFO_ERANGE_READ_DATA_ORDERING )

Referenced by fcpcmd_recv_rddata().

◆ EINFO_ERANGE_READ_DATA_ORDERING

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

Definition at line 60 of file fcp.c.

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

◆ ERANGE_READ_DATA_OVERRUN

#define ERANGE_READ_DATA_OVERRUN   __einfo_error ( EINFO_ERANGE_READ_DATA_OVERRUN )

Definition at line 62 of file fcp.c.

62#define ERANGE_READ_DATA_OVERRUN \
63 __einfo_error ( EINFO_ERANGE_READ_DATA_OVERRUN )

◆ EINFO_ERANGE_READ_DATA_OVERRUN

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

Definition at line 64 of file fcp.c.

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

◆ ERANGE_WRITE_DATA_STUCK

#define ERANGE_WRITE_DATA_STUCK   __einfo_error ( EINFO_ERANGE_WRITE_DATA_STUCK )

Definition at line 66 of file fcp.c.

66#define ERANGE_WRITE_DATA_STUCK \
67 __einfo_error ( EINFO_ERANGE_WRITE_DATA_STUCK )

Referenced by fcpcmd_send_wrdata().

◆ EINFO_ERANGE_WRITE_DATA_STUCK

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

Definition at line 68 of file fcp.c.

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

◆ ERANGE_WRITE_DATA_OVERRUN

#define ERANGE_WRITE_DATA_OVERRUN   __einfo_error ( EINFO_ERANGE_WRITE_DATA_OVERRUN )

Definition at line 70 of file fcp.c.

70#define ERANGE_WRITE_DATA_OVERRUN \
71 __einfo_error ( EINFO_ERANGE_WRITE_DATA_OVERRUN )

◆ EINFO_ERANGE_WRITE_DATA_OVERRUN

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

Definition at line 72 of file fcp.c.

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

◆ ERANGE_DATA_UNDERRUN

#define ERANGE_DATA_UNDERRUN   __einfo_error ( EINFO_ERANGE_DATA_UNDERRUN )

Definition at line 74 of file fcp.c.

74#define ERANGE_DATA_UNDERRUN \
75 __einfo_error ( EINFO_ERANGE_DATA_UNDERRUN )

Referenced by fcpcmd_recv_rsp().

◆ EINFO_ERANGE_DATA_UNDERRUN

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

Definition at line 76 of file fcp.c.

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

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )

◆ fcp_prli_tx()

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 94 of file fcp.c.

94 {
96
97 /* Build service parameter page */
98 memset ( &param, 0, sizeof ( param ) );
100
101 return fc_els_prli_tx ( els, &fcp_prli_descriptor, &param );
102}
int fc_els_prli_tx(struct fc_els *els, struct fc_els_prli_descriptor *descriptor, void *param)
Transmit PRLI.
Definition fcels.c:954
#define FCP_PRLI_NO_READ_RDY
Read FCP_XFER_RDY disabled.
Definition fcp.h:141
#define FCP_PRLI_INITIATOR
Has initiator functionality.
Definition fcp.h:147
#define htonl(value)
Definition byteswap.h:134
struct hv_monitor_parameter param[4][32]
Parameters.
Definition hyperv.h:13
void * memset(void *dest, int character, size_t len) __nonnull
An FCP PRLI service parameter page.
Definition fcp.h:132

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

◆ fcp_prli_rx()

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 112 of file fcp.c.

112 {
113 return fc_els_prli_rx ( els, &fcp_prli_descriptor, data, len );
114}
ring len
Length.
Definition dwmac.h:226
uint8_t data[48]
Additional event data.
Definition ena.h:11
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:1010

References data, fc_els_prli_rx(), and len.

◆ fcp_prli_detect()

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 124 of file fcp.c.

125 {
126 return fc_els_prli_detect ( els, &fcp_prli_descriptor, data, len );
127}
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:1097

References data, fc_els_prli_detect(), and len.

◆ fcpdev_get()

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 203 of file fcp.c.

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

References ref_get, and fcp_device::refcnt.

Referenced by fcpdev_scsi_command().

◆ fcpdev_put()

void fcpdev_put ( struct fcp_device * fcpdev)
inlinestatic

Drop reference to FCP device.

Parameters
fcpdevFCP device

Definition at line 214 of file fcp.c.

214 {
215 ref_put ( &fcpdev->refcnt );
216}
#define ref_put(refcnt)
Drop reference to object.
Definition refcnt.h:107

References ref_put, and fcp_device::refcnt.

Referenced by fcpcmd_free().

◆ fcpcmd_get()

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 225 of file fcp.c.

225 {
226 ref_get ( &fcpcmd->refcnt );
227 return fcpcmd;
228}
struct refcnt refcnt
Reference count.
Definition fcp.c:169

References ref_get, and fcp_command::refcnt.

Referenced by fcpdev_close().

◆ fcpcmd_put()

void fcpcmd_put ( struct fcp_command * fcpcmd)
inlinestatic

Drop reference to FCP command.

Parameters
fcpcmdFCP command

Definition at line 236 of file fcp.c.

236 {
237 ref_put ( &fcpcmd->refcnt );
238}

References ref_put, and fcp_command::refcnt.

Referenced by fcpdev_close().

◆ fcpcmd_start_send()

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

Start FCP command sending.

Parameters
fcpcmdFCP command
sendSend method

Definition at line 247 of file fcp.c.

248 {
249 fcpcmd->send = send;
250 process_add ( &fcpcmd->process );
251}
struct arbelprm_send_doorbell send
Definition arbel.h:0
void process_add(struct process *process)
Add process to process list.
Definition process.c:60
int(* send)(struct fcp_command *fcpcmd)
Send current IU.
Definition fcp.c:185
struct process process
Send process.
Definition fcp.c:179

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

Referenced by fcpcmd_recv_xfer_rdy(), and fcpdev_scsi_command().

◆ fcpcmd_stop_send()

void fcpcmd_stop_send ( struct fcp_command * fcpcmd)
inlinestatic

Stop FCP command sending.

Parameters
fcpcmdFCP command

Definition at line 259 of file fcp.c.

259 {
260 process_del ( &fcpcmd->process );
261}
void process_del(struct process *process)
Remove process from process list.
Definition process.c:80

References fcp_command::process, and process_del().

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

◆ fcpcmd_free()

void fcpcmd_free ( struct refcnt * refcnt)
static

Free FCP command.

Parameters
refcntReference count

Definition at line 268 of file fcp.c.

268 {
269 struct fcp_command *fcpcmd =
271
272 /* Remove from list of commands */
273 list_del ( &fcpcmd->list );
274 fcpdev_put ( fcpcmd->fcpdev );
275
276 /* Free command */
277 free ( fcpcmd );
278}
static void fcpdev_put(struct fcp_device *fcpdev)
Drop reference to FCP device.
Definition fcp.c:214
#define list_del(list)
Delete an entry from a list.
Definition list.h:120
static void(* free)(struct refcnt *refcnt))
Definition refcnt.h:55
#define container_of(ptr, type, field)
Get containing structure.
Definition stddef.h:36
An FCP command.
Definition fcp.c:167
struct list_head list
List of active commands.
Definition fcp.c:173
struct fcp_device * fcpdev
FCP SCSI device.
Definition fcp.c:171
A reference counter.
Definition refcnt.h:27

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

Referenced by fcpdev_scsi_command().

◆ fcpcmd_close()

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

Close FCP command.

Parameters
fcpcmdFCP command
rcReason for close

Definition at line 286 of file fcp.c.

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

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()

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 308 of file fcp.c.

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

References EPIPE, fcpcmd_close(), and rc.

◆ fcpcmd_send_cmnd()

int fcpcmd_send_cmnd ( struct fcp_command * fcpcmd)
static

Send FCP command IU.

Parameters
fcpcmdFCP command
Return values
rcReturn status code

Definition at line 320 of file fcp.c.

320 {
321 struct fcp_device *fcpdev = fcpcmd->fcpdev;
322 struct scsi_cmd *command = &fcpcmd->command;
323 struct io_buffer *iobuf;
324 struct fcp_cmnd *cmnd;
325 struct xfer_metadata meta;
326 int rc;
327
328 /* Sanity check */
329 if ( command->data_in.len && command->data_out.len ) {
330 DBGC ( fcpdev, "FCP %p xchg %04x cannot handle bidirectional "
331 "command\n", fcpdev, fcpcmd->xchg_id );
332 return -ENOTSUP;
333 }
334
335 /* Allocate I/O buffer */
336 iobuf = xfer_alloc_iob ( &fcpcmd->xchg, sizeof ( *cmnd ) );
337 if ( ! iobuf ) {
338 DBGC ( fcpdev, "FCP %p xchg %04x cannot allocate command IU\n",
339 fcpdev, fcpcmd->xchg_id );
340 return -ENOMEM;
341 }
342
343 /* Construct command IU frame */
344 cmnd = iob_put ( iobuf, sizeof ( *cmnd ) );
345 memset ( cmnd, 0, sizeof ( *cmnd ) );
346 memcpy ( &cmnd->lun, &command->lun, sizeof ( cmnd->lun ) );
347 assert ( ! ( command->data_in.len && command->data_out.len ) );
348 if ( command->data_in.len )
349 cmnd->dirn |= FCP_CMND_RDDATA;
350 if ( command->data_out.len )
351 cmnd->dirn |= FCP_CMND_WRDATA;
352 memcpy ( &cmnd->cdb, &fcpcmd->command.cdb, sizeof ( cmnd->cdb ) );
353 cmnd->len = htonl ( command->data_in.len + command->data_out.len );
354 memset ( &meta, 0, sizeof ( meta ) );
355 meta.flags = ( XFER_FL_CMD_STAT | XFER_FL_OVER );
356 DBGC2 ( fcpdev, "FCP %p xchg %04x CMND " SCSI_CDB_FORMAT " %04x\n",
357 fcpdev, fcpcmd->xchg_id, SCSI_CDB_DATA ( cmnd->cdb ),
358 ntohl ( cmnd->len ) );
359
360 /* No further data to send within this IU */
361 fcpcmd_stop_send ( fcpcmd );
362
363 /* Send command IU frame */
364 if ( ( rc = xfer_deliver ( &fcpcmd->xchg, iob_disown ( iobuf ),
365 &meta ) ) != 0 ) {
366 DBGC ( fcpdev, "FCP %p xchg %04x cannot deliver command IU: "
367 "%s\n", fcpdev, fcpcmd->xchg_id, strerror ( rc ) );
368 return rc;
369 }
370
371 return 0;
372}
#define assert(condition)
Assert a condition at run-time.
Definition assert.h:61
uint8_t meta
Metadata flags.
Definition ena.h:3
#define FCP_CMND_WRDATA
Command includes data-out.
Definition fcp.h:38
#define FCP_CMND_RDDATA
Command includes data-in.
Definition fcp.h:41
#define DBGC2(...)
Definition compiler.h:547
#define ENOMEM
Not enough space.
Definition errno.h:578
#define ENOTSUP
Operation not supported.
Definition errno.h:633
#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 ntohl(value)
Definition byteswap.h:135
void * memcpy(void *dest, const void *src, size_t len) __nonnull
#define iob_put(iobuf, len)
Definition iobuf.h:185
#define iob_disown(iobuf)
Disown an I/O buffer.
Definition iobuf.h:277
A command-line command.
Definition command.h:10
An FCP command IU.
Definition fcp.h:20
uint32_t len
Data length.
Definition fcp.h:34
union scsi_cdb cdb
SCSI CDB.
Definition fcp.h:32
uint8_t dirn
Direction.
Definition fcp.h:30
struct scsi_lun lun
SCSI LUN.
Definition fcp.h:22
struct scsi_cmd command
SCSI command.
Definition fcp.c:187
A persistent I/O buffer.
Definition iobuf.h:98
A SCSI command information unit.
Definition scsi.h:250
union scsi_cdb cdb
CDB for this command.
Definition scsi.h:254
Data transfer metadata.
Definition xfer.h:23
int xfer_deliver(struct interface *intf, struct io_buffer *iobuf, struct xfer_metadata *meta)
Deliver datagram.
Definition xfer.c:195
struct io_buffer * xfer_alloc_iob(struct interface *intf, size_t len)
Allocate I/O buffer.
Definition xfer.c:159
#define XFER_FL_OVER
Sender is relinquishing use of half-duplex channel.
Definition xfer.h:51
#define XFER_FL_CMD_STAT
Data content represents a command or status message.
Definition xfer.h:61

References assert, fcp_cmnd::cdb, scsi_cmd::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()

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 382 of file fcp.c.

384 {
385 struct fcp_device *fcpdev = fcpcmd->fcpdev;
386 struct scsi_cmd *command = &fcpcmd->command;
387 size_t offset = meta->offset;
388 size_t len = iob_len ( iobuf );
389 int rc;
390
391 /* Sanity checks */
392 if ( ! ( meta->flags & XFER_FL_ABS_OFFSET ) ) {
393 DBGC ( fcpdev, "FCP %p xchg %04x read data missing offset\n",
394 fcpdev, fcpcmd->xchg_id );
396 goto done;
397 }
398 if ( offset != fcpcmd->offset ) {
399 DBGC ( fcpdev, "FCP %p xchg %04x read data out of order "
400 "(expected %zd, received %zd)\n",
401 fcpdev, fcpcmd->xchg_id, fcpcmd->offset, offset );
403 goto done;
404 }
405 DBGC2 ( fcpdev, "FCP %p xchg %04x RDDATA [%08zx,%08zx)\n",
406 fcpdev, fcpcmd->xchg_id, offset, ( offset + len ) );
407
408 /* Copy to user buffer */
409 if ( ( rc = xferbuf_write ( &command->data_in, offset,
410 iobuf->data, len ) ) != 0 ) {
411 DBGC ( fcpdev, "FCP %p xchg %04x buffer overrun: %s\n",
412 fcpdev, fcpcmd->xchg_id, strerror ( rc ) );
413 goto done;
414 }
415 fcpcmd->offset += len;
416 assert ( fcpcmd->offset <= command->data_in.len );
417
418 rc = 0;
419 done:
420 free_iob ( iobuf );
421 return rc;
422}
struct bofm_section_header done
Definition bofm_test.c:46
uint16_t offset
Offset to command line.
Definition bzimage.h:3
#define ERANGE_READ_DATA_ORDERING
Definition fcp.c:58
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition iobuf.c:153
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition iobuf.h:220
size_t offset
Data offset within command.
Definition fcp.c:189
void * data
Start of data.
Definition iobuf.h:113
#define XFER_FL_ABS_OFFSET
Offset is absolute.
Definition xfer.h:48
int xferbuf_write(struct xfer_buffer *xferbuf, size_t offset, const void *data, size_t len)
Write to data transfer buffer.
Definition xferbuf.c:133

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

Referenced by fcpcmd_deliver().

◆ fcpcmd_send_wrdata()

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 430 of file fcp.c.

430 {
431 struct fcp_device *fcpdev = fcpcmd->fcpdev;
432 struct scsi_cmd *command = &fcpcmd->command;
433 struct io_buffer *iobuf;
434 struct xfer_metadata meta;
435 size_t len;
436 int rc;
437
438 /* Calculate length to be sent */
439 len = xfer_window ( &fcpcmd->xchg );
440 if ( len > fcpcmd->remaining )
441 len = fcpcmd->remaining;
442
443 /* Sanity checks */
444 if ( len == 0 ) {
445 DBGC ( fcpdev, "FCP %p xchg %04x write data stuck\n",
446 fcpdev, fcpcmd->xchg_id );
448 goto err_sanity;
449 }
450
451 /* Allocate I/O buffer */
452 iobuf = xfer_alloc_iob ( &fcpcmd->xchg, len );
453 if ( ! iobuf ) {
454 DBGC ( fcpdev, "FCP %p xchg %04x cannot allocate write data "
455 "IU for %zd bytes\n", fcpdev, fcpcmd->xchg_id, len );
456 rc = -ENOMEM;
457 goto err_alloc;
458 }
459
460 /* Construct data IU frame */
461 if ( ( rc = xferbuf_read ( &command->data_out, fcpcmd->offset,
462 iob_put ( iobuf, len ), len ) ) != 0 )
463 goto err_read;
464 memset ( &meta, 0, sizeof ( meta ) );
466 meta.offset = fcpcmd->offset;
467 DBGC2 ( fcpdev, "FCP %p xchg %04x WRDATA [%08zx,%04zx)\n",
468 fcpdev, fcpcmd->xchg_id, fcpcmd->offset,
469 ( fcpcmd->offset + iob_len ( iobuf ) ) );
470
471 /* Calculate amount of data remaining to be sent within this IU */
472 assert ( len <= fcpcmd->remaining );
473 fcpcmd->offset += len;
474 fcpcmd->remaining -= len;
475 assert ( fcpcmd->offset <= command->data_out.len );
476 if ( fcpcmd->remaining == 0 ) {
477 fcpcmd_stop_send ( fcpcmd );
478 meta.flags |= XFER_FL_OVER;
479 }
480
481 /* Send data IU frame */
482 if ( ( rc = xfer_deliver ( &fcpcmd->xchg, iob_disown ( iobuf ),
483 &meta ) ) != 0 ) {
484 DBGC ( fcpdev, "FCP %p xchg %04x cannot deliver write data "
485 "IU: %s\n", fcpdev, fcpcmd->xchg_id, strerror ( rc ) );
486 goto err_deliver;
487 }
488
489 return 0;
490
491 err_deliver:
492 err_read:
493 free_iob ( iobuf );
494 err_alloc:
495 err_sanity:
496 return rc;
497}
#define ERANGE_WRITE_DATA_STUCK
Definition fcp.c:66
size_t remaining
Length of data remaining to be sent within this IU.
Definition fcp.c:191
size_t xfer_window(struct interface *intf)
Check flow control window.
Definition xfer.c:117
#define XFER_FL_RESPONSE
Data content is a response.
Definition xfer.h:64
int xferbuf_read(struct xfer_buffer *xferbuf, size_t offset, void *data, size_t len)
Read from data transfer buffer.
Definition xferbuf.c:166

References assert, fcp_command::command, DBGC, DBGC2, ENOMEM, ERANGE_WRITE_DATA_STUCK, fcpcmd_stop_send(), fcp_command::fcpdev, free_iob(), 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, xfer_window(), and xferbuf_read().

Referenced by fcpcmd_recv_xfer_rdy().

◆ fcpcmd_recv_xfer_rdy()

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 507 of file fcp.c.

509 {
510 struct fcp_device *fcpdev = fcpcmd->fcpdev;
511 struct fcp_xfer_rdy *xfer_rdy;
512 int rc;
513
514 /* Sanity checks */
515 if ( iob_len ( iobuf ) != sizeof ( *xfer_rdy ) ) {
516 DBGC ( fcpdev, "FCP %p xchg %04x received invalid transfer "
517 "ready IU:\n", fcpdev, fcpcmd->xchg_id );
518 DBGC_HDA ( fcpdev, 0, iobuf->data, iob_len ( iobuf ) );
519 rc = -EPROTO;
520 goto done;
521 }
522 xfer_rdy = iobuf->data;
523 if ( ntohl ( xfer_rdy->offset ) != fcpcmd->offset ) {
524 /* We do not advertise out-of-order delivery */
525 DBGC ( fcpdev, "FCP %p xchg %04x cannot support out-of-order "
526 "delivery (expected %zd, requested %d)\n",
527 fcpdev, fcpcmd->xchg_id, fcpcmd->offset,
528 ntohl ( xfer_rdy->offset ) );
529 rc = -EPROTO;
530 goto done;
531 }
532 DBGC2 ( fcpdev, "FCP %p xchg %04x XFER_RDY [%08x,%08x)\n",
533 fcpdev, fcpcmd->xchg_id, ntohl ( xfer_rdy->offset ),
534 ( ntohl ( xfer_rdy->offset ) + ntohl ( xfer_rdy->len ) ) );
535
536 /* Start sending requested data */
537 fcpcmd->remaining = ntohl ( xfer_rdy->len );
539
540 rc = 0;
541 done:
542 free_iob ( iobuf );
543 return rc;
544}
static int fcpcmd_send_wrdata(struct fcp_command *fcpcmd)
Send FCP write data IU.
Definition fcp.c:430
static void fcpcmd_start_send(struct fcp_command *fcpcmd, int(*send)(struct fcp_command *fcpcmd))
Start FCP command sending.
Definition fcp.c:247
#define DBGC_HDA(...)
Definition compiler.h:531
#define EPROTO
Protocol error.
Definition errno.h:668
An FCP transfer ready IU.
Definition fcp.h:47
uint32_t offset
Relative offset of data.
Definition fcp.h:49
uint32_t len
Burst length.
Definition fcp.h:51

References __unused, 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, meta, ntohl, fcp_command::offset, fcp_xfer_rdy::offset, rc, fcp_command::remaining, and fcp_command::xchg_id.

Referenced by fcpcmd_deliver().

◆ fcpcmd_recv_rsp()

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 554 of file fcp.c.

556 {
557 struct fcp_device *fcpdev = fcpcmd->fcpdev;
558 struct scsi_cmd *command = &fcpcmd->command;
559 struct fcp_rsp *rsp;
560 struct scsi_rsp response;
561 void *response_data;
562 void *sense_data;
563 size_t response_data_len;
564 size_t sense_data_len;
565 size_t remaining;
566 int rc;
567
568 /* Parse response */
569 remaining = iob_len ( iobuf );
570 if ( remaining < sizeof ( *rsp ) ) {
571 DBGC ( fcpdev, "FCP %p xchg %04x received invalid response "
572 "IU:\n", fcpdev, fcpcmd->xchg_id );
573 DBGC_HDA ( fcpdev, 0, iobuf->data, iob_len ( iobuf ) );
574 rc = -EPROTO;
575 goto done;
576 }
577 rsp = iobuf->data;
578 remaining -= sizeof ( *rsp );
579 DBGC2 ( fcpdev, "FCP %p xchg %04x RSP stat %02x resid %08x flags %02x"
580 "%s%s%s%s\n", fcpdev, fcpcmd->xchg_id, rsp->status,
581 ntohl ( rsp->residual ), rsp->flags,
582 ( ( rsp->flags & FCP_RSP_RESPONSE_LEN_VALID ) ? " resp" : "" ),
583 ( ( rsp->flags & FCP_RSP_SENSE_LEN_VALID ) ? " sense" : "" ),
584 ( ( rsp->flags & FCP_RSP_RESIDUAL_OVERRUN ) ? " over" : "" ),
585 ( ( rsp->flags & FCP_RSP_RESIDUAL_UNDERRUN ) ? " under" : ""));
586
587 /* Parse response data */
588 response_data_len = fcp_rsp_response_data_len ( rsp );
589 if ( remaining < response_data_len ) {
590 DBGC ( fcpdev, "FCP %p xchg %04x received overlength "
591 "response data:\n", fcpdev, fcpcmd->xchg_id );
592 DBGC_HDA ( fcpdev, 0, iobuf->data, iob_len ( iobuf ) );
593 rc = -EPROTO;
594 goto done;
595 }
596 response_data = fcp_rsp_response_data ( rsp );
597 if ( response_data ) {
598 DBGC2 ( fcpdev, "FCP %p xchg %04x response data:\n",
599 fcpdev, fcpcmd->xchg_id );
600 DBGC2_HDA ( fcpdev, 0, response_data, response_data_len );
601 }
602 remaining -= response_data_len;
603
604 /* Parse sense data */
605 sense_data_len = fcp_rsp_sense_data_len ( rsp );
606 if ( remaining < sense_data_len ) {
607 DBGC ( fcpdev, "FCP %p xchg %04x received overlength "
608 "sense data:\n", fcpdev, fcpcmd->xchg_id );
609 DBGC_HDA ( fcpdev, 0, iobuf->data, iob_len ( iobuf ) );
610 rc = -EPROTO;
611 goto done;
612 }
613 sense_data = fcp_rsp_sense_data ( rsp );
614 if ( sense_data ) {
615 DBGC2 ( fcpdev, "FCP %p xchg %04x sense data:\n",
616 fcpdev, fcpcmd->xchg_id );
617 DBGC2_HDA ( fcpdev, 0, sense_data, sense_data_len );
618 }
619 remaining -= sense_data_len;
620
621 /* Check for locally-detected command underrun */
622 if ( ( rsp->status == 0 ) &&
623 ( fcpcmd->offset != ( command->data_in.len +
624 command->data_out.len ) ) ) {
625 DBGC ( fcpdev, "FCP %p xchg %04x data underrun (expected %zd, "
626 "got %zd)\n", fcpdev, fcpcmd->xchg_id,
627 ( command->data_in.len + command->data_out.len ),
628 fcpcmd->offset );
630 goto done;
631 }
632
633 /* Build SCSI response */
634 memset ( &response, 0, sizeof ( response ) );
635 response.status = rsp->status;
636 if ( rsp->flags & ( FCP_RSP_RESIDUAL_OVERRUN |
638 response.overrun = ntohl ( rsp->residual );
639 if ( rsp->flags & FCP_RSP_RESIDUAL_UNDERRUN )
640 response.overrun = -response.overrun;
641 }
642 scsi_parse_sense ( sense_data, sense_data_len, &response.sense );
643
644 /* Free buffer before sending response, to minimise
645 * out-of-memory errors.
646 */
647 free_iob ( iob_disown ( iobuf ) );
648
649 /* Send SCSI response */
650 scsi_response ( &fcpcmd->scsi, &response );
651
652 /* Terminate command */
653 fcpcmd_close ( fcpcmd, 0 );
654
655 rc = 0;
656 done:
657 free_iob ( iobuf );
658 return rc;
659}
#define ERANGE_DATA_UNDERRUN
Definition fcp.c:74
#define FCP_RSP_RESIDUAL_OVERRUN
Residual represents overrun.
Definition fcp.h:81
#define FCP_RSP_RESPONSE_LEN_VALID
Response length field is valid.
Definition fcp.h:75
static size_t fcp_rsp_sense_data_len(struct fcp_rsp *rsp)
Get length of sense data portion of FCP response.
Definition fcp.h:126
#define FCP_RSP_SENSE_LEN_VALID
Sense length field is valid.
Definition fcp.h:78
static size_t fcp_rsp_response_data_len(struct fcp_rsp *rsp)
Get length of response data portion of FCP response.
Definition fcp.h:103
#define FCP_RSP_RESIDUAL_UNDERRUN
Residual represents underrun.
Definition fcp.h:84
static void * fcp_rsp_sense_data(struct fcp_rsp *rsp)
Get sense data portion of FCP response.
Definition fcp.h:114
static void * fcp_rsp_response_data(struct fcp_rsp *rsp)
Get response data portion of FCP response.
Definition fcp.h:92
#define DBGC2_HDA(...)
Definition compiler.h:548
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
An FCP response IU.
Definition fcp.h:57
A SCSI response information unit.
Definition scsi.h:313

References __unused, 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(), meta, 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()

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 669 of file fcp.c.

671 {
672 struct fcp_device *fcpdev = fcpcmd->fcpdev;
673
674 DBGC ( fcpdev, "FCP %p xchg %04x received unknown IU:\n",
675 fcpdev, fcpcmd->xchg_id );
676 DBGC_HDA ( fcpdev, 0, iobuf->data, iob_len ( iobuf ) );
677 free_iob ( iobuf );
678 return -EPROTO;
679}

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

Referenced by fcpcmd_deliver().

◆ fcpcmd_step()

void fcpcmd_step ( struct fcp_command * fcpcmd)
static

Transmit FCP frame.

Parameters
fcpcmdFCP command

Definition at line 686 of file fcp.c.

686 {
687 int rc;
688
689 /* Send the current IU */
690 if ( ( rc = fcpcmd->send ( fcpcmd ) ) != 0 ) {
691 /* Treat failure as a fatal error */
692 fcpcmd_close ( fcpcmd, rc );
693 }
694}

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

◆ fcpcmd_deliver()

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 704 of file fcp.c.

706 {
707 int ( * fcpcmd_recv ) ( struct fcp_command *fcpcmd,
708 struct io_buffer *iobuf,
709 struct xfer_metadata *meta );
710 int rc;
711
712 /* Determine handler */
713 switch ( meta->flags & ( XFER_FL_CMD_STAT | XFER_FL_RESPONSE ) ) {
714 case ( XFER_FL_RESPONSE ) :
715 fcpcmd_recv = fcpcmd_recv_rddata;
716 break;
717 case ( XFER_FL_CMD_STAT ) :
718 fcpcmd_recv = fcpcmd_recv_xfer_rdy;
719 break;
721 fcpcmd_recv = fcpcmd_recv_rsp;
722 break;
723 default:
724 fcpcmd_recv = fcpcmd_recv_unknown;
725 break;
726 }
727
728 /* Handle IU */
729 if ( ( rc = fcpcmd_recv ( fcpcmd, iob_disown ( iobuf ), meta ) ) != 0 ){
730 /* Treat any error as fatal to the command */
731 fcpcmd_close ( fcpcmd, rc );
732 }
733
734 return rc;
735}
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:554
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:507
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:669
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:382

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()

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 768 of file fcp.c.

770 {
772 struct fcp_command *fcpcmd;
773 int xchg_id;
774 int rc;
775
776 /* Check link */
777 if ( ( rc = fcpdev->user.ulp->link.rc ) != 0 ) {
778 DBGC ( fcpdev, "FCP %p could not issue command while link is "
779 "down: %s\n", fcpdev, strerror ( rc ) );
780 goto err_link;
781 }
782
783 /* Check target capability */
784 assert ( param != NULL );
785 assert ( fcpdev->user.ulp->param_len >= sizeof ( *param ) );
786 if ( ! ( param->flags & htonl ( FCP_PRLI_TARGET ) ) ) {
787 DBGC ( fcpdev, "FCP %p could not issue command: not a target\n",
788 fcpdev );
789 rc = -ENOTTY;
790 goto err_target;
791 }
792
793 /* Allocate and initialise structure */
794 fcpcmd = zalloc ( sizeof ( *fcpcmd ) );
795 if ( ! fcpcmd ) {
796 rc = -ENOMEM;
797 goto err_zalloc;
798 }
799 ref_init ( &fcpcmd->refcnt, fcpcmd_free );
800 intf_init ( &fcpcmd->scsi, &fcpcmd_scsi_desc, &fcpcmd->refcnt );
801 intf_init ( &fcpcmd->xchg, &fcpcmd_xchg_desc, &fcpcmd->refcnt );
803 &fcpcmd->refcnt );
804 fcpcmd->fcpdev = fcpdev_get ( fcpdev );
805 list_add ( &fcpcmd->list, &fcpdev->fcpcmds );
806 memcpy ( &fcpcmd->command, command, sizeof ( fcpcmd->command ) );
807
808 /* Create new exchange */
809 if ( ( xchg_id = fc_xchg_originate ( &fcpcmd->xchg,
812 FC_TYPE_FCP ) ) < 0 ) {
813 rc = xchg_id;
814 DBGC ( fcpdev, "FCP %p could not create exchange: %s\n",
815 fcpdev, strerror ( rc ) );
816 goto err_xchg_originate;
817 }
818 fcpcmd->xchg_id = xchg_id;
819
820 /* Start sending command IU */
822
823 /* Attach to parent interface, mortalise self, and return */
824 intf_plug_plug ( &fcpcmd->scsi, parent );
825 ref_put ( &fcpcmd->refcnt );
826 return ( FCP_TAG_MAGIC | fcpcmd->xchg_id );
827
828 err_xchg_originate:
829 fcpcmd_close ( fcpcmd, rc );
830 ref_put ( &fcpcmd->refcnt );
831 err_zalloc:
832 err_target:
833 err_link:
834 return rc;
835}
#define NULL
NULL pointer (VOID *).
Definition Base.h:321
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
@ FC_TYPE_FCP
Fibre Channel Protocol.
Definition fc.h:194
static int fcpcmd_send_cmnd(struct fcp_command *fcpcmd)
Send FCP command IU.
Definition fcp.c:320
static struct fcp_device * fcpdev_get(struct fcp_device *fcpdev)
Get reference to FCP device.
Definition fcp.c:203
static void fcpcmd_free(struct refcnt *refcnt)
Free FCP command.
Definition fcp.c:268
static struct process_descriptor fcpcmd_process_desc
FCP command process descriptor.
Definition fcp.c:757
static struct interface_descriptor fcpcmd_xchg_desc
FCP command Fibre Channel exchange interface descriptor.
Definition fcp.c:753
static struct interface_descriptor fcpcmd_scsi_desc
FCP command SCSI interface descriptor.
Definition fcp.c:743
#define FCP_PRLI_TARGET
Has target functionality.
Definition fcp.h:144
#define FCP_TAG_MAGIC
FCP tag magic marker.
Definition fcp.h:44
#define ENOTTY
Inappropriate I/O control operation.
Definition errno.h:638
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
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:146
#define ref_init(refcnt, free)
Initialise a reference counter.
Definition refcnt.h:65
struct fc_port * port
Fibre Channel port, if known.
Definition fc.h:355
struct fc_port_id port_id
Peer port ID, if known.
Definition fc.h:357
struct fc_ulp * ulp
Fibre Channel upper layer protocol.
Definition fc.h:456
size_t param_len
Service parameter length.
Definition fc.h:434
struct fc_peer * peer
Fibre Channel peer.
Definition fc.h:418
struct fc_link_state link
Link state monitor.
Definition fc.h:428
void * param
Service parameters, if any.
Definition fc.h:432
struct fc_ulp_user user
Fibre Channel upper-layer protocol user.
Definition fcp.c:156
struct list_head fcpcmds
List of active commands.
Definition fcp.c:160

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, fc_ulp::param, 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()

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

Close FCP device.

Parameters
fcpdevFCP device
rcReason for close

Definition at line 843 of file fcp.c.

843 {
844 struct fcp_command *fcpcmd;
845 struct fcp_command *tmp;
846
847 DBGC ( fcpdev, "FCP %p closed: %s\n", fcpdev, strerror ( rc ) );
848
849 /* Shut down interfaces */
851
852 /* Shut down any active commands */
854 fcpcmd_get ( fcpcmd );
855 fcpcmd_close ( fcpcmd, rc );
856 fcpcmd_put ( fcpcmd );
857 }
858
859 /* Drop reference to ULP */
861}
void fc_ulp_detach(struct fc_ulp_user *user)
Detach Fibre Channel upper-layer protocol user.
Definition fc.c:1626
static void fcpcmd_put(struct fcp_command *fcpcmd)
Drop reference to FCP command.
Definition fcp.c:236
static struct fcp_command * fcpcmd_get(struct fcp_command *fcpcmd)
Get reference to FCP command.
Definition fcp.c:225
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
struct interface scsi
SCSI command issuing interface.
Definition fcp.c:158

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()

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 869 of file fcp.c.

869 {
870 return ( fc_link_ok ( &fcpdev->user.ulp->link ) ?
871 ~( ( size_t ) 0 ) : 0 );
872}
static int fc_link_ok(struct fc_link_state *link)
Check Fibre Channel link state.
Definition fc.h:109

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

◆ fcpdev_edd_describe()

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 882 of file fcp.c.

884 {
885 union {
886 struct fc_name fc;
888 } wwn;
889 union {
890 struct scsi_lun scsi;
892 } lun;
893
895 memcpy ( &wwn.fc, &fcpdev->desc.wwn, sizeof ( wwn.fc ) );
896 path->fibre.wwn = be64_to_cpu ( wwn.u64 );
897 memcpy ( &lun.scsi, &fcpdev->desc.lun, sizeof ( lun.scsi ) );
898 path->fibre.lun = be64_to_cpu ( lun.u64 );
899 return 0;
900}
unsigned long long uint64_t
Definition stdint.h:13
uint8_t lun
Logical Unit Number.
Definition edd.h:3
uint64_t wwn
WWN.
Definition edd.h:1
#define EDD_INTF_TYPE_FIBRE
EDD Fibre Channel interface type.
Definition edd.h:66
uint32_t type
Operating system type.
Definition ena.h:1
u16 fc
802.11 Frame Control field
Definition ieee80211.h:0
#define cpu_to_le64(value)
Definition byteswap.h:109
#define be64_to_cpu(value)
Definition byteswap.h:118
uint64_t u64
Definition stdint.h:26
A Fibre Channel name.
Definition fc.h:30
struct fc_name wwn
Fibre Channel WWN.
Definition fcp.h:170
struct scsi_lun lun
SCSI LUN.
Definition fcp.h:172
struct fcp_description desc
Device description (for boot firmware table).
Definition fcp.c:163
uint8_t lun
Logical Unit Number.
Definition edd.h:110
uint64_t wwn
WWN.
Definition edd.h:132

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

◆ fcpdev_identify_device()

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 908 of file fcp.c.

908 {
909
910 /* We know the underlying device only if the link is up;
911 * otherwise we don't have a port to examine.
912 */
913 if ( ! fc_link_ok ( &fcpdev->user.ulp->link ) ) {
914 DBGC ( fcpdev, "FCP %p doesn't know underlying device "
915 "until link is up\n", fcpdev );
916 return NULL;
917 }
918
919 /* Hand off to port's transport interface */
920 assert ( fcpdev->user.ulp->peer->port != NULL );
921 return identify_device ( &fcpdev->user.ulp->peer->port->transport );
922}
struct device * identify_device(struct interface *intf)
Identify a device behind an interface.
Definition device.c:126
struct interface transport
Transport interface.
Definition fc.h:262

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_efi_describe()

EFI_DEVICE_PATH_PROTOCOL * fcpdev_efi_describe ( struct fcp_device * fcpdev)
static

Describe as an EFI device path.

Parameters
fcpFCP device
Return values
pathEFI device path, or NULL on error

Definition at line 931 of file fcp.c.

931 {
932
933 return efi_fcp_path ( &fcpdev->desc );
934}
EFI_DEVICE_PATH_PROTOCOL * efi_fcp_path(struct fcp_description *desc)
Construct EFI device path for Fibre Channel device.
Definition efi_path.c:645

References fcp_device::desc, and efi_fcp_path().

◆ fcpdev_examine()

void fcpdev_examine ( struct fc_ulp_user * user)
static

Examine FCP ULP link state.

Parameters
userFibre Channel upper-layer protocol user

Definition at line 956 of file fcp.c.

956 {
957 struct fcp_device *fcpdev =
958 container_of ( user, struct fcp_device, user );
959
960 if ( fc_link_ok ( &fcpdev->user.ulp->link ) ) {
961 DBGC ( fcpdev, "FCP %p link is up\n", fcpdev );
962 } else {
963 DBGC ( fcpdev, "FCP %p link is down: %s\n",
964 fcpdev, strerror ( fcpdev->user.ulp->link.rc ) );
965 }
966
967 /* Notify SCSI layer of window change */
968 xfer_window_changed ( &fcpdev->scsi );
969}
void xfer_window_changed(struct interface *intf)
Report change of flow control window.
Definition xfer.c:147

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

Referenced by fcpdev_open().

◆ fcpdev_open()

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 979 of file fcp.c.

980 {
981 struct fc_ulp *ulp;
982 struct fcp_device *fcpdev;
983 int rc;
984
985 /* Get Fibre Channel ULP interface */
987 if ( ! ulp ) {
988 rc = -ENOMEM;
989 goto err_ulp_get;
990 }
991
992 /* Allocate and initialise structure */
993 fcpdev = zalloc ( sizeof ( *fcpdev ) );
994 if ( ! fcpdev ) {
995 rc = -ENOMEM;
996 goto err_zalloc;
997 }
998 ref_init ( &fcpdev->refcnt, NULL );
999 intf_init ( &fcpdev->scsi, &fcpdev_scsi_desc, &fcpdev->refcnt );
1000 INIT_LIST_HEAD ( &fcpdev->fcpcmds );
1001 fc_ulp_user_init ( &fcpdev->user, fcpdev_examine, &fcpdev->refcnt );
1002
1003 DBGC ( fcpdev, "FCP %p opened for %s\n", fcpdev, fc_ntoa ( wwn ) );
1004
1005 /* Attach to Fibre Channel ULP */
1006 fc_ulp_attach ( ulp, &fcpdev->user );
1007
1008 /* Preserve parameters required for boot firmware table */
1009 memcpy ( &fcpdev->desc.wwn, wwn, sizeof ( fcpdev->desc.wwn ) );
1010 memcpy ( &fcpdev->desc.lun, lun, sizeof ( fcpdev->desc.lun ) );
1011
1012 /* Attach SCSI device to parent interface */
1013 if ( ( rc = scsi_open ( parent, &fcpdev->scsi, lun ) ) != 0 ) {
1014 DBGC ( fcpdev, "FCP %p could not create SCSI device: %s\n",
1015 fcpdev, strerror ( rc ) );
1016 goto err_scsi_open;
1017 }
1018
1019 /* Drop temporary reference to ULP */
1020 fc_ulp_put ( ulp );
1021
1022 /* Mortalise self and return */
1023 ref_put ( &fcpdev->refcnt );
1024 return 0;
1025
1026 err_scsi_open:
1027 fcpdev_close ( fcpdev, rc );
1028 ref_put ( &fcpdev->refcnt );
1029 err_zalloc:
1030 fc_ulp_put ( ulp );
1031 err_ulp_get:
1032 return rc;
1033}
void fc_ulp_attach(struct fc_ulp *ulp, struct fc_ulp_user *user)
Attach Fibre Channel upper-layer protocol user.
Definition fc.c:1608
const char * fc_ntoa(const struct fc_name *wwn)
Format Fibre Channel WWN.
Definition fc.c:127
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:1881
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:520
static void fc_ulp_put(struct fc_ulp *ulp)
Drop reference to Fibre Channel upper-layer protocol.
Definition fc.h:486
static struct interface_descriptor fcpdev_scsi_desc
FCP device SCSI interface descriptor.
Definition fcp.c:948
static void fcpdev_examine(struct fc_ulp_user *user)
Examine FCP ULP link state.
Definition fcp.c:956
static void fcpdev_close(struct fcp_device *fcpdev, int rc)
Close FCP device.
Definition fcp.c:843
#define INIT_LIST_HEAD(list)
Initialise a list head.
Definition list.h:46
int scsi_open(struct interface *block, struct interface *scsi, struct scsi_lun *lun)
Open SCSI device.
Definition scsi.c:987
A Fibre Channel upper-layer protocol.
Definition fc.h:414

References DBGC, fcp_device::desc, 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(), fcp_description::lun, lun, memcpy(), NULL, rc, ref_init, ref_put, fcp_device::refcnt, fcp_device::scsi, scsi_open(), strerror(), fcp_device::user, fcp_description::wwn, wwn, and zalloc().

Referenced by fcp_open().

◆ fcp_parse_uri()

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 1052 of file fcp.c.

1053 {
1054 char wwn_buf[ FC_NAME_STRLEN + 1 /* NUL */ ];
1055 const char *wwn_text;
1056 const char *lun_text;
1057 int rc;
1058
1059 /* Extract WWN and LUN texts from URI */
1060 if ( uri->opaque ) {
1061 /* "fcp:<wwn>:<lun>" */
1062 if ( snprintf ( wwn_buf, sizeof ( wwn_buf ), "%s",
1063 uri->opaque ) < ( FC_NAME_STRLEN + 1 /* : */ ) )
1064 return -EINVAL;
1065 if ( uri->opaque[FC_NAME_STRLEN] != ':' )
1066 return -EINVAL;
1067 wwn_text = wwn_buf;
1068 lun_text = &uri->opaque[FC_NAME_STRLEN + 1];
1069 } else {
1070 /* If host exists, path must also exist */
1071 if ( ! ( uri->host && uri->path ) )
1072 return -EINVAL;
1073 if ( uri->path[0] != '/' )
1074 return -EINVAL;
1075 wwn_text = uri->host;
1076 lun_text = ( uri->path + 1 );
1077 }
1078
1079 /* Parse WWN */
1080 if ( ( rc = fc_aton ( wwn_text, wwn ) ) != 0 )
1081 return rc;
1082
1083 /* Parse LUN */
1084 if ( ( rc = scsi_parse_lun ( lun_text, lun ) ) != 0 )
1085 return rc;
1086
1087 return 0;
1088}
int fc_aton(const char *wwn_text, struct fc_name *wwn)
Parse Fibre Channel WWN.
Definition fc.c:144
#define FC_NAME_STRLEN
Length of Fibre Channel name text.
Definition fc.h:35
#define EINVAL
Invalid argument.
Definition errno.h:472
int scsi_parse_lun(const char *lun_string, struct scsi_lun *lun)
Parse SCSI LUN.
Definition scsi.c:118
A Uniform Resource Identifier.
Definition uri.h:65
const char * path
Path (after URI decoding).
Definition uri.h:81
const char * host
Host name.
Definition uri.h:77
const char * opaque
Opaque part.
Definition uri.h:71
int snprintf(char *buf, size_t size, const char *fmt,...)
Write a formatted string to a buffer.
Definition vsprintf.c:383

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()

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 1097 of file fcp.c.

1097 {
1098 struct fc_name wwn;
1099 struct scsi_lun lun;
1100 int rc;
1101
1102 /* Parse URI */
1103 if ( ( rc = fcp_parse_uri ( uri, &wwn, &lun ) ) != 0 )
1104 return rc;
1105
1106 /* Open FCP device */
1107 if ( ( rc = fcpdev_open ( parent, &wwn, &lun ) ) != 0 )
1108 return rc;
1109
1110 return 0;
1111}
static int fcp_parse_uri(struct uri *uri, struct fc_name *wwn, struct scsi_lun *lun)
Parse FCP URI.
Definition fcp.c:1052
static int fcpdev_open(struct interface *parent, struct fc_name *wwn, struct scsi_lun *lun)
Open FCP device.
Definition fcp.c:979
A SCSI LUN.
Definition scsi.h:237

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,
}

FCP PRLI descriptor.

Definition at line 86 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_tx(struct fc_els *els)
Transmit FCP PRLI.
Definition fcp.c:94
static int fcp_prli_rx(struct fc_els *els, void *data, size_t len)
Receive FCP PRLI.
Definition fcp.c:112
static int fcp_prli_detect(struct fc_els *els, const void *data, size_t len)
Detect FCP PRLI.
Definition fcp.c:124

FCP PRLI ELS handler.

Definition at line 130 of file fcp.c.

130 {
131 .name = "PRLI-FCP",
132 .tx = fcp_prli_tx,
133 .rx = fcp_prli_rx,
134 .detect = fcp_prli_detect,
135};

◆ 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:250
#define INTF_OP(op_type, object_type, op_func)
Define an object interface operation.
Definition interface.h:33

FCP command SCSI interface operations.

Definition at line 738 of file fcp.c.

738 {
740};

◆ 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:738
#define INTF_DESC_PASSTHRU(object_type, intf, operations, passthru)
Define an object interface descriptor with pass-through interface.
Definition interface.h:98

FCP command SCSI interface descriptor.

Definition at line 743 of file fcp.c.

Referenced by fcpdev_scsi_command().

◆ fcpcmd_xchg_op

struct interface_operation fcpcmd_xchg_op[]
static
Initial value:
= {
}
static void fcpcmd_close_err(struct fcp_command *fcpcmd, int rc)
Close FCP command in error.
Definition fcp.c:308
static int fcpcmd_deliver(struct fcp_command *fcpcmd, struct io_buffer *iobuf, struct xfer_metadata *meta)
Receive FCP frame.
Definition fcp.c:704

FCP command Fibre Channel exchange interface operations.

Definition at line 747 of file fcp.c.

747 {
750};

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

FCP command Fibre Channel exchange interface descriptor.

Definition at line 753 of file fcp.c.

Referenced by fcpdev_scsi_command().

◆ fcpcmd_process_desc

struct process_descriptor fcpcmd_process_desc
static
Initial value:
=
static void fcpcmd_step(struct fcp_command *fcpcmd)
Transmit FCP frame.
Definition fcp.c:686
#define PROC_DESC(object_type, process, _step)
Define a process descriptor.
Definition process.h:83
A process.
Definition process.h:18

FCP command process descriptor.

Definition at line 757 of file fcp.c.

Referenced by fcpdev_scsi_command().

◆ fcpdev_scsi_op

struct interface_operation fcpdev_scsi_op[]
static
Initial value:
= {
}
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:45
EFI_DEVICE_PATH_PROTOCOL * efi_describe(struct interface *intf)
Describe object as an EFI device path.
Definition efi_path.c:949
static int fcpdev_scsi_command(struct fcp_device *fcpdev, struct interface *parent, struct scsi_cmd *command)
Issue FCP SCSI command.
Definition fcp.c:768
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:882
static EFI_DEVICE_PATH_PROTOCOL * fcpdev_efi_describe(struct fcp_device *fcpdev)
Describe as an EFI device path.
Definition fcp.c:931
static size_t fcpdev_window(struct fcp_device *fcpdev)
Check FCP device flow-control window.
Definition fcp.c:869
static struct device * fcpdev_identify_device(struct fcp_device *fcpdev)
Identify device underlying FCP device.
Definition fcp.c:908
#define EFI_INTF_OP
Definition efi.h:381
A SCSI command.
Definition scsi.c:263

FCP device SCSI interface operations.

Definition at line 937 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:937
#define INTF_DESC(object_type, intf, operations)
Define an object interface descriptor.
Definition interface.h:81

FCP device SCSI interface descriptor.

Definition at line 948 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:1097

FCP URI opener.

Definition at line 1114 of file fcp.c.

1114 {
1115 .scheme = "fcp",
1116 .open = fcp_open,
1117};