58 #define ERANGE_READ_DATA_ORDERING \ 59 __einfo_error ( EINFO_ERANGE_READ_DATA_ORDERING ) 60 #define EINFO_ERANGE_READ_DATA_ORDERING \ 61 __einfo_uniqify ( EINFO_ERANGE, 0x01, "Read data out of order" ) 62 #define ERANGE_READ_DATA_OVERRUN \ 63 __einfo_error ( EINFO_ERANGE_READ_DATA_OVERRUN ) 64 #define EINFO_ERANGE_READ_DATA_OVERRUN \ 65 __einfo_uniqify ( EINFO_ERANGE, 0x02, "Read data overrun" ) 66 #define ERANGE_WRITE_DATA_STUCK \ 67 __einfo_error ( EINFO_ERANGE_WRITE_DATA_STUCK ) 68 #define EINFO_ERANGE_WRITE_DATA_STUCK \ 69 __einfo_uniqify ( EINFO_ERANGE, 0x03, "Write data stuck" ) 70 #define ERANGE_WRITE_DATA_OVERRUN \ 71 __einfo_error ( EINFO_ERANGE_WRITE_DATA_OVERRUN ) 72 #define EINFO_ERANGE_WRITE_DATA_OVERRUN \ 73 __einfo_uniqify ( EINFO_ERANGE, 0x04, "Write data overrun" ) 74 #define ERANGE_DATA_UNDERRUN \ 75 __einfo_error ( EINFO_ERANGE_DATA_UNDERRUN ) 76 #define EINFO_ERANGE_DATA_UNDERRUN \ 77 __einfo_uniqify ( EINFO_ERANGE, 0x05, "Data underrun" ) 141 .handler = &fcp_prli_handler,
290 DBGC ( fcpdev,
"FCP %p xchg %04x closed: %s\n",
330 DBGC ( fcpdev,
"FCP %p xchg %04x cannot handle bidirectional " 331 "command\n", fcpdev, fcpcmd->
xchg_id );
338 DBGC ( fcpdev,
"FCP %p xchg %04x cannot allocate command IU\n",
344 cmnd =
iob_put ( iobuf,
sizeof ( *cmnd ) );
345 memset ( cmnd, 0,
sizeof ( *cmnd ) );
366 DBGC ( fcpdev,
"FCP %p xchg %04x cannot deliver command IU: " 393 DBGC ( fcpdev,
"FCP %p xchg %04x read data missing offset\n",
399 DBGC ( fcpdev,
"FCP %p xchg %04x read data out of order " 400 "(expected %zd, received %zd)\n",
406 DBGC ( fcpdev,
"FCP %p xchg %04x read data overrun (max %zd, " 407 "received %zd)\n", fcpdev, fcpcmd->
xchg_id,
412 DBGC2 ( fcpdev,
"FCP %p xchg %04x RDDATA [%08zx,%08zx)\n",
447 DBGC ( fcpdev,
"FCP %p xchg %04x write data stuck\n",
452 DBGC ( fcpdev,
"FCP %p xchg %04x write data overrun (max %zd, " 453 "requested %zd)\n", fcpdev, fcpcmd->
xchg_id,
461 DBGC ( fcpdev,
"FCP %p xchg %04x cannot allocate write data " 462 "IU for %zd bytes\n", fcpdev, fcpcmd->
xchg_id,
len );
472 DBGC2 ( fcpdev,
"FCP %p xchg %04x WRDATA [%08zx,%04zx)\n",
477 assert ( len <= fcpcmd->remaining );
489 DBGC ( fcpdev,
"FCP %p xchg %04x cannot deliver write data " 513 if (
iob_len ( iobuf ) !=
sizeof ( *xfer_rdy ) ) {
514 DBGC ( fcpdev,
"FCP %p xchg %04x received invalid transfer " 515 "ready IU:\n", fcpdev, fcpcmd->
xchg_id );
522 DBGC ( fcpdev,
"FCP %p xchg %04x cannot support out-of-order " 523 "delivery (expected %zd, requested %d)\n",
529 DBGC2 ( fcpdev,
"FCP %p xchg %04x XFER_RDY [%08x,%08x)\n",
561 if ( (
iob_len ( iobuf ) <
sizeof ( *
rsp ) ) ||
565 DBGC ( fcpdev,
"FCP %p xchg %04x received invalid response " 566 "IU:\n", fcpdev, fcpcmd->
xchg_id );
571 DBGC2 ( fcpdev,
"FCP %p xchg %04x RSP stat %02x resid %08x flags %02x" 572 "%s%s%s%s\n", fcpdev, fcpcmd->
xchg_id,
rsp->status,
579 DBGC2 ( fcpdev,
"FCP %p xchg %04x response data:\n",
585 DBGC2 ( fcpdev,
"FCP %p xchg %04x sense data:\n",
592 if ( (
rsp->status == 0 ) &&
595 DBGC ( fcpdev,
"FCP %p xchg %04x data underrun (expected %zd, " 596 "got %zd)\n", fcpdev, fcpcmd->
xchg_id,
604 memset ( &response, 0,
sizeof ( response ) );
645 DBGC ( fcpdev,
"FCP %p xchg %04x received unknown IU:\n",
661 if ( (
rc = fcpcmd->
send ( fcpcmd ) ) != 0 ) {
678 int ( * fcpcmd_recv ) (
struct fcp_command *fcpcmd,
749 DBGC (
fcpdev,
"FCP %p could not issue command while link is " 758 DBGC (
fcpdev,
"FCP %p could not issue command: not a target\n",
765 fcpcmd =
zalloc (
sizeof ( *fcpcmd ) );
785 DBGC (
fcpdev,
"FCP %p could not create exchange: %s\n",
787 goto err_xchg_originate;
842 ~( (
size_t ) 0 ) : 0 );
885 DBGC ( fcpdev,
"FCP %p doesn't know underlying device " 886 "until link is up\n", fcpdev );
932 DBGC ( fcpdev,
"FCP %p link is up\n", fcpdev );
934 DBGC ( fcpdev,
"FCP %p link is down: %s\n",
964 fcpdev =
zalloc (
sizeof ( *fcpdev ) );
974 DBGC ( fcpdev,
"FCP %p opened for %s\n", fcpdev,
fc_ntoa (
wwn ) );
985 DBGC ( fcpdev,
"FCP %p could not create SCSI device: %s\n",
1026 const char *wwn_text;
1027 const char *lun_text;
1033 if (
snprintf ( wwn_buf,
sizeof ( wwn_buf ),
"%s",
void scsi_parse_sense(const void *data, size_t len, struct scsi_sns_descriptor *sense)
Parse SCSI sense data.
void fc_ulp_detach(struct fc_ulp_user *user)
Detach Fibre Channel upper-layer protocol user.
static struct fcp_command * fcpcmd_get(struct fcp_command *fcpcmd)
Get reference to FCP command.
#define EINVAL
Invalid argument.
An object interface operation.
static struct interface_operation fcpdev_scsi_op[]
FCP device SCSI interface operations.
#define FCP_RSP_RESIDUAL_OVERRUN
Residual represents overrun.
struct arbelprm_rc_send_wqe rc
void xfer_window_changed(struct interface *intf)
Report change of flow control window.
static struct interface_descriptor fcpdev_scsi_desc
FCP device SCSI interface descriptor.
void intf_close(struct interface *intf, int rc)
Close an object interface.
#define iob_put(iobuf, len)
void intf_shutdown(struct interface *intf, int rc)
Shut down an object interface.
An FCP transfer ready IU.
struct fc_ulp * ulp
Fibre Channel upper layer protocol.
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.
#define ERANGE_WRITE_DATA_OVERRUN
#define EDD_INTF_TYPE_FIBRE
EDD Fibre Channel interface type.
int fc_aton(const char *wwn_text, struct fc_name *wwn)
Parse Fibre Channel WWN.
#define ERANGE_WRITE_DATA_STUCK
static int fcpcmd_deliver(struct fcp_command *fcpcmd, struct io_buffer *iobuf, struct xfer_metadata *meta)
Receive FCP frame.
struct process process
Send process.
#define list_add(new, head)
Add a new entry to the head of a list.
#define XFER_FL_ABS_OFFSET
Offset is absolute.
#define ref_init(refcnt, free)
Initialise a reference counter.
static int fcpdev_open(struct interface *parent, struct fc_name *wwn, struct scsi_lun *lun)
Open FCP device.
#define FCP_PRLI_NO_READ_RDY
Read FCP_XFER_RDY disabled.
A Fibre Channel extended link services handler.
u16 fc
802.11 Frame Control field
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
static struct interface_operation fcpcmd_xchg_op[]
FCP command Fibre Channel exchange interface operations.
uint32_t type
Operating system type.
#define EPIPE
Broken pipe.
union scsi_cdb cdb
SCSI CDB.
static __always_inline void copy_from_user(void *dest, userptr_t src, off_t src_off, size_t len)
Copy data from user buffer.
int edd_describe(struct interface *intf, struct edd_interface_type *type, union edd_device_path *path)
Describe a disk device using EDD.
static int fcp_parse_uri(struct uri *uri, struct fc_name *wwn, struct scsi_lun *lun)
Parse FCP URI.
static int fcpcmd_send_cmnd(struct fcp_command *fcpcmd)
Send FCP command IU.
static int fcpcmd_recv_unknown(struct fcp_command *fcpcmd, struct io_buffer *iobuf, struct xfer_metadata *meta __unused)
Handle unknown FCP IU.
void intf_plug_plug(struct interface *a, struct interface *b)
Plug two object interfaces together.
static void fcpcmd_close(struct fcp_command *fcpcmd, int rc)
Close FCP command.
unsigned long long uint64_t
static void fcpcmd_stop_send(struct fcp_command *fcpcmd)
Stop FCP command sending.
static struct process_descriptor fcpcmd_process_desc
FCP command process descriptor.
struct io_buffer * xfer_alloc_iob(struct interface *intf, size_t len)
Allocate I/O buffer.
#define cpu_to_le64(value)
const char * fc_ntoa(const struct fc_name *wwn)
Format Fibre Channel WWN.
This protocol can be used on any device handle to obtain generic path/location information concerning...
uint32_t offset
Relative offset of data.
union scsi_cdb cdb
CDB for this command.
int scsi_open(struct interface *block, struct interface *scsi, struct scsi_lun *lun)
Open SCSI device.
struct refcnt refcnt
Reference count.
Uniform Resource Identifiers.
struct fc_peer * peer
Fibre Channel peer.
void process_del(struct process *process)
Remove process from process list.
static int fcpcmd_send_wrdata(struct fcp_command *fcpcmd)
Send FCP write data IU.
size_t xfer_window(struct interface *intf)
Check flow control window.
struct fc_els_prli_descriptor fcp_prli_descriptor __fc_els_prli_descriptor
FCP PRLI descriptor.
struct fc_name wwn
Fibre Channel WWN.
#define FCP_RSP_RESIDUAL_UNDERRUN
Residual represents underrun.
static int fcpcmd_recv_rsp(struct fcp_command *fcpcmd, struct io_buffer *iobuf, struct xfer_metadata *meta __unused)
Handle FCP response IU.
#define ENOTSUP
Operation not supported.
A doubly-linked list entry (or list head)
Data transfer interfaces.
static void fcpcmd_free(struct refcnt *refcnt)
Free FCP command.
struct fc_port * port
Fibre Channel port, if known.
#define XFER_FL_RESPONSE
Data content is a response.
int fc_els_prli_detect(struct fc_els *els __unused, struct fc_els_prli_descriptor *descriptor, const void *data, size_t len)
Detect PRLI.
#define list_del(list)
Delete an entry from a list.
int fc_els_prli_tx(struct fc_els *els, struct fc_els_prli_descriptor *descriptor, void *param)
Transmit PRLI.
#define ENOMEM
Not enough space.
#define iob_disown(iobuf)
Disown an I/O buffer.
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
void * memcpy(void *dest, const void *src, size_t len) __nonnull
#define __unused
Declare a variable or data structure as unused.
static int fcpdev_scsi_command(struct fcp_device *fcpdev, struct interface *parent, struct scsi_cmd *command)
Issue FCP SCSI command.
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
#define container_of(ptr, type, field)
Get containing structure.
static int fcp_prli_rx(struct fc_els *els, void *data, size_t len)
Receive FCP PRLI.
void fc_ulp_attach(struct fc_ulp *ulp, struct fc_ulp_user *user)
Attach Fibre Channel upper-layer protocol user.
int scsi_parse_lun(const char *lun_string, struct scsi_lun *lun)
Parse SCSI LUN.
static void * fcp_rsp_sense_data(struct fcp_rsp *rsp)
Get sense data portion of FCP response.
A SCSI response information unit.
static struct interface_descriptor fcpcmd_xchg_desc
FCP command Fibre Channel exchange interface descriptor.
size_t param_len
Service parameter length.
static void fcpdev_put(struct fcp_device *fcpdev)
Drop reference to FCP device.
static int fc_link_ok(struct fc_link_state *link)
Check Fibre Channel link state.
#define FCP_CMND_RDDATA
Command includes data-in.
const char * path
Path (after URI decoding)
static void fcpcmd_start_send(struct fcp_command *fcpcmd, int(*send)(struct fcp_command *fcpcmd))
Start FCP command sending.
static void * fcp_rsp_response_data(struct fcp_rsp *rsp)
Get response data portion of FCP response.
const char * scheme
URI protocol name.
struct interface scsi
SCSI command interface.
struct interface scsi
SCSI command issuing interface.
static EFI_DEVICE_PATH_PROTOCOL * fcpdev_efi_describe(struct fcp_device *fcpdev)
Describe as an EFI device path.
struct fcp_description desc
Device description (for boot firmware table)
EFI_DEVICE_PATH_PROTOCOL * efi_fcp_path(struct fcp_description *desc)
Construct EFI device path for Fibre Channel device.
struct scsi_lun lun
SCSI LUN.
static struct fcp_device * fcpdev_get(struct fcp_device *fcpdev)
Get reference to FCP device.
uint8_t lun
Logical Unit Number.
#define FCP_TAG_MAGIC
FCP tag magic marker.
#define list_for_each_entry_safe(pos, tmp, head, member)
Iterate over entries in a list, safe against deletion of the current entry.
#define EPROTO
Protocol error.
static struct interface_operation fcpcmd_scsi_op[]
FCP command SCSI interface operations.
static int fcpcmd_recv_rddata(struct fcp_command *fcpcmd, struct io_buffer *iobuf, struct xfer_metadata *meta)
Handle FCP read data IU.
static int fcp_open(struct interface *parent, struct uri *uri)
Open FCP URI.
void process_add(struct process *process)
Add process to process list.
An object interface descriptor.
A Fibre Channel extended link services transaction.
struct fc_port_id port_id
Peer port ID, if known.
char * strerror(int errno)
Retrieve string representation of error number.
#define FCP_PRLI_INITIATOR
Has initiator functionality.
#define be64_to_cpu(value)
static void(* free)(struct refcnt *refcnt))
void * zalloc(size_t size)
Allocate cleared memory.
void * param
Service parameters, if any.
#define ref_get(refcnt)
Get additional reference to object.
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
struct hv_monitor_parameter param[4][32]
Parameters.
static size_t fcp_rsp_response_data_len(struct fcp_rsp *rsp)
Get length of response data portion of FCP response.
uint8_t status
SCSI status code.
#define INTF_OP(op_type, object_type, op_func)
Define an object interface operation.
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.
struct fc_link_state link
Link state monitor.
struct scsi_cmd command
SCSI command.
#define XFER_FL_CMD_STAT
Data content represents a command or status message.
int xfer_deliver(struct interface *intf, struct io_buffer *iobuf, struct xfer_metadata *meta)
Deliver datagram.
#define SCSI_CDB_DATA(cdb)
printf() parameters for dumping a scsi_cdb
Data transfer interface opening.
struct interface xchg
Fibre Channel exchange interface.
uint16_t xchg_id
Exchange ID.
A Fibre Channel upper-layer protocol user.
static size_t fcpdev_window(struct fcp_device *fcpdev)
Check FCP device flow-control window.
#define FCP_PRLI_TARGET
Has target functionality.
static void process_init_stopped(struct process *process, struct process_descriptor *desc, struct refcnt *refcnt)
Initialise process without adding to process list.
#define ERANGE_READ_DATA_OVERRUN
uint8_t lun
Logical Unit Number.
#define FCP_RSP_RESPONSE_LEN_VALID
Response length field is valid.
const char * host
Host name.
An FCP device description.
struct list_head list
List of active commands.
static int fcpcmd_recv_xfer_rdy(struct fcp_command *fcpcmd, struct io_buffer *iobuf, struct xfer_metadata *meta __unused)
Handle FCP transfer ready IU.
size_t offset
Data offset within command.
static void fcpcmd_step(struct fcp_command *fcpcmd)
Transmit FCP frame.
static int fcp_prli_detect(struct fc_els *els, const void *data, size_t len)
Detect FCP PRLI.
void scsi_response(struct interface *intf, struct scsi_rsp *response)
Report SCSI response.
A SCSI command information unit.
#define INIT_LIST_HEAD(list)
Initialise a list head.
#define INTF_DESC(object_type, intf, operations)
Define an object interface descriptor.
struct scsi_lun lun
SCSI LUN.
static int fcp_prli_tx(struct fc_els *els)
Transmit FCP PRLI.
static struct interface_descriptor fcpcmd_scsi_desc
FCP command SCSI interface descriptor.
EFI_DEVICE_PATH_PROTOCOL * efi_describe(struct interface *intf)
Describe object as an EFI device path.
#define SCSI_CDB_FORMAT
printf() format for dumping a scsi_cdb
static struct device * fcpdev_identify_device(struct fcp_device *fcpdev)
Identify device underlying FCP device.
An FCP PRLI service parameter page.
const char * opaque
Opaque part.
#define ENOTTY
Inappropriate I/O control operation.
struct refcnt refcnt
Reference count.
struct scsi_sns_descriptor sense
Autosense data (if any)
size_t remaining
Length of data remaining to be sent within this IU.
void * data
Start of data.
#define PROC_DESC(object_type, process, _step)
Define a process descriptor.
struct interface transport
Transport interface.
#define ERANGE_DATA_UNDERRUN
static void fc_ulp_put(struct fc_ulp *ulp)
Drop reference to Fibre Channel upper-layer protocol.
uint8_t data[48]
Additional event data.
static void fcpcmd_put(struct fcp_command *fcpcmd)
Drop reference to FCP command.
int snprintf(char *buf, size_t size, const char *fmt,...)
Write a formatted string to a buffer.
A Uniform Resource Identifier.
#define INTF_DESC_PASSTHRU(object_type, intf, operations, passthru)
Define an object interface descriptor with pass-through interface.
Enhanced Disk Drive specification.
uint16_t offset
Offset to command line.
#define XFER_FL_OVER
Sender is relinquishing use of half-duplex channel.
struct device * identify_device(struct interface *intf)
Identify a device behind an interface.
static void fcpdev_examine(struct fc_ulp_user *user)
Examine FCP ULP link state.
#define FCP_RSP_SENSE_LEN_VALID
Sense length field is valid.
struct list_head fcpcmds
List of active commands.
struct fc_ulp_user user
Fibre Channel upper-layer protocol user.
int(* send)(struct fcp_command *fcpcmd)
Send current IU.
int fc_els_prli_rx(struct fc_els *els, struct fc_els_prli_descriptor *descriptor, void *data, size_t len)
Receive PRLI.
struct fc_els_handler fcp_prli_handler __fc_els_handler
FCP PRLI ELS handler.
uint32_t len
Burst length.
#define FCP_CMND_WRDATA
Command includes data-out.
unsigned int type
Upper-layer protocol type.
static void intf_init(struct interface *intf, struct interface_descriptor *desc, struct refcnt *refcnt)
Initialise an object interface.
#define FC_NAME_STRLEN
Length of Fibre Channel name text.
A Fibre Channel ELS PRLI descriptor.
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.
struct uri_opener fcp_uri_opener __uri_opener
FCP URI opener.
static void fcpcmd_close_err(struct fcp_command *fcpcmd, int rc)
Close FCP command in error.
#define NULL
NULL pointer (VOID *)
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.
struct bofm_section_header done
ssize_t overrun
Data overrun (or negative underrun)
static int fcpdev_edd_describe(struct fcp_device *fcpdev, struct edd_interface_type *type, union edd_device_path *path)
Describe FCP device using EDD.
struct fcp_device * fcpdev
FCP SCSI device.
#define ref_put(refcnt)
Drop reference to object.
A Fibre Channel upper-layer protocol.
#define ERANGE_READ_DATA_ORDERING
static size_t fcp_rsp_sense_data_len(struct fcp_rsp *rsp)
Get length of sense data portion of FCP response.
Fibre Channel Extended Link Services.
void * memset(void *dest, int character, size_t len) __nonnull
struct arbelprm_send_doorbell send
static void fcpdev_close(struct fcp_device *fcpdev, int rc)
Close FCP device.