46 #define FCELS_FMT "FCELS %s %s %s %s" 49 #define FCELS_ARGS( els ) \ 51 ( (els)->handler ? (els)->handler->name : "unknown ELS" ), \ 52 ( fc_els_is_request ( els ) ? "to" : "from" ), \ 53 fc_id_ntoa ( &(els)->peer_port_id ) 207 els->
handler = &fc_els_unknown_handler;
299 els =
zalloc (
sizeof ( *els ) );
400 memset ( &ls_rjt, 0,
sizeof ( ls_rjt ) );
405 return fc_els_tx ( els, &ls_rjt,
sizeof ( ls_rjt ) );
470 memset ( &flogi, 0,
sizeof ( flogi ) );
484 return fc_els_tx ( els, &flogi,
sizeof ( flogi ) );
501 if (
len <
sizeof ( *flogi ) ) {
524 &flogi->
port_wwn, has_fabric ) ) != 0 ) {
533 if ( ! has_fabric ) {
584 &fc_els_flogi_handler );
604 memset ( &plogi, 0,
sizeof ( plogi ) );
624 return fc_els_tx ( els, &plogi,
sizeof ( plogi ) );
668 goto err_peer_get_wwn;
737 &fc_els_plogi_handler );
757 memset ( &logo, 0,
sizeof ( logo ) );
764 return fc_els_tx ( els, &logo,
sizeof ( logo ) );
777 memset ( &logo, 0,
sizeof ( logo ) );
781 return fc_els_tx ( els, &logo,
sizeof ( logo ) );
795 sizeof ( *peer_port_id ) ) == 0 ) ||
797 sizeof ( *peer_port_id ) ) == 0 ) ) {
822 if (
len <
sizeof ( *logo ) ) {
915 &fc_els_logo_handler );
964 goto err_get_port_id_type;
970 prli.frame.page_len =
971 (
sizeof (
prli.frame.page ) +
sizeof (
prli.param ) );
973 prli.frame.page.type = descriptor->
type;
993 err_get_port_id_type:
1017 if (
len <
sizeof ( *
prli ) ) {
1033 goto err_get_port_id_type;
1038 DBGC ( els,
FCELS_FMT " received while peer link is down\n",
1047 sizeof (
prli->param ),
1078 err_get_port_id_type:
1094 const void *
data,
size_t len ) {
1105 if (
len <
sizeof ( *prli ) )
1109 if ( prli->frame.page.type != descriptor->
type )
1154 memset ( &rtv, 0,
sizeof ( rtv ) );
1159 return fc_els_tx ( els, &rtv,
sizeof ( rtv ) );
1228 #define FC_ECHO_MAGIC 0x69505845 1290 if ( (
len !=
sizeof ( *
echo ) ) ||
#define FC_LOGIN_DEFAULT_REL_OFFS
Default relative offset by info category.
int fc_els_request(struct interface *job, struct fc_port *port, struct fc_port_id *peer_port_id, struct fc_els_handler *handler)
Create ELS request.
#define FC_LOGIN_DEFAULT_E_D_TOV
Default E_D timeout value.
#define EINVAL
Invalid argument.
An object interface operation.
#define FC_LOGIN_CONTINUOUS_OFFSET
Continuously increasing relative offset.
Fibre Channel ELS frame common parameters.
struct fc_name port_wwn
Port name.
struct arbelprm_rc_send_wqe rc
void intf_close(struct interface *intf, int rc)
Close an object interface.
static int fc_els_plogi_tx(struct fc_els *els)
Transmit PLOGI.
static int fc_els_echo_rx(struct fc_els *els, void *data, size_t len)
Receive ECHO.
uint16_t mtu
Receive size.
void intf_shutdown(struct interface *intf, int rc)
Shut down an object interface.
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.
static int fc_els_respond(struct interface *xchg, struct fc_port *port, struct fc_port_id *port_id, struct fc_port_id *peer_port_id)
Create ELS response.
uint16_t version
Login version.
static struct fc_els_prli_descriptor * fc_els_prli_descriptor(unsigned int type)
Find PRLI descriptor.
size_t param_len
Service parameter length.
struct fc_login_common common
Common service parameters.
struct fc_responder fc_els_responder __fc_responder
Fibre Channel ELS responder.
static int fc_els_rtv_tx_response(struct fc_els *els)
Transmit RTV response.
int(* tx)(struct fc_els *els)
Transmit ELS frame.
int xfer_deliver_raw_meta(struct interface *intf, const void *data, size_t len, struct xfer_metadata *meta)
Deliver datagram as raw data.
struct fc_port_id ptp_link_port_id
Link port ID (for point-to-point links only)
const char * fc_id_ntoa(const struct fc_port_id *id)
Format Fibre Channel port ID.
A Fibre Channel RTV response frame.
#define ref_init(refcnt, free)
Initialise a reference counter.
static int fc_els_logo_detect(struct fc_els *els __unused, const void *data, size_t len __unused)
Detect LOGO.
struct fc_echo_frame_header echo
ECHO frame header.
A Fibre Channel RTV request frame.
A Fibre Channel extended link services handler.
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
uint32_t type
Operating system type.
struct fc_peer * fc_peer_get_wwn(const struct fc_name *port_wwn)
Get Fibre Channel peer by node name.
A Fibre Channel responder.
struct fc_port_id fc_f_port_id
F_Port contoller port ID.
static int fc_els_logo_rx_request(struct fc_els *els, void *data, size_t len)
Receive LOGO request.
struct fc_name node_wwn
Node name.
uint32_t e_d_tov
Error detection timeout value.
struct fc_els_handler * handler
ELS handler, if known.
static int fc_els_plogi_detect(struct fc_els *els __unused, const void *data, size_t len __unused)
Detect PLOGI.
int fc_port_login(struct fc_port *port, struct fc_port_id *port_id, const struct fc_name *link_node_wwn, const struct fc_name *link_port_wwn, int has_fabric)
Log in Fibre Channel port.
static int fc_els_unknown_tx_response(struct fc_els *els)
Transmit unknown ELS response.
Fibre Channel socket address.
void intf_plug_plug(struct interface *a, struct interface *b)
Plug two object interfaces together.
#define FC_LOGIN_CLASS_SEQUENTIAL
Sequential delivery requested.
#define FC_ECHO_MAGIC
ECHO magic marker.
static int fc_els_flogi_tx(struct fc_els *els)
Transmit FLOGI.
static void fc_port_put(struct fc_port *port)
Drop reference to Fibre Channel port.
#define EACCES
Permission denied.
#define FC_ELS_PRLI_DESCRIPTORS
Fibre Channel ELS PRLI descriptor table.
struct fc_els_handler * handler
Fibre Channel ELS handler.
const char * fc_ntoa(const struct fc_name *wwn)
Format Fibre Channel WWN.
#define PROC_DESC_ONCE(object_type, process, _step)
Define a process descriptor for a process that runs only once.
uint8_t command
ELS command code.
int fc_els_plogi(struct interface *parent, struct fc_port *port, struct fc_port_id *peer_port_id)
Create PLOGI request.
#define FCELS_FMT
Fibre Channel ELS transaction debug message format.
struct fc_port_id peer_port_id
Peer port ID.
static struct interface_operation fc_els_xchg_op[]
Fibre Channel ELS exchange interface operations.
static int fc_els_unknown_rx(struct fc_els *els, void *data, size_t len)
Receive unknown ELS.
struct fc_peer * peer
Fibre Channel peer.
void process_del(struct process *process)
Remove process from process list.
uint8_t reason
Reason code.
static void fc_els_close(struct fc_els *els, int rc)
Close Fibre Channel ELS transaction.
#define ENOTSUP
Operation not supported.
static struct fc_els_handler * fc_els_detect(struct fc_els *els, const void *data, size_t len)
Detect Fibre Channel ELS frame handler.
static int fc_els_logo_rx(struct fc_els *els, void *data, size_t len)
Receive LOGO.
Data transfer interfaces.
struct fc_port_id port_id
Local port ID.
static int fc_els_unknown_detect(struct fc_els *els __unused, const void *data __unused, size_t len __unused)
Detect unknown ELS.
int fc_els_tx(struct fc_els *els, const void *data, size_t len)
Transmit Fibre Channel ELS frame.
#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.
int fc_els_prli_tx(struct fc_els *els, struct fc_els_prli_descriptor *descriptor, void *param)
Transmit PRLI.
int fc_peer_login(struct fc_peer *peer, struct fc_port *port, struct fc_port_id *port_id)
Log in Fibre Channel peer.
#define ENOMEM
Not enough space.
int(* detect)(struct fc_els *els, const void *data, size_t len)
Detect ELS frame.
void * memcpy(void *dest, const void *src, size_t len) __nonnull
uint8_t command
ELS command code.
A Fibre Channel PRLI frame.
static int fc_els_echo_rx_request(struct fc_els *els, void *data, size_t len)
Receive ECHO request.
int fc_els_flogi(struct interface *parent, struct fc_port *port)
Create FLOGI request.
uint8_t command
ELS command code.
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
#define container_of(ptr, type, field)
Get containing structure.
A Fibre Channel port identifier.
struct interface xchg
Fibre Channel exchange.
#define FC_LOGIN_F_PORT
Forwarder port.
#define __unused
Declare a variable or data structure as unused.
static int fc_link_ok(struct fc_link_state *link)
Check Fibre Channel link state.
struct fc_link_state link
Link state monitor.
uint8_t max_seq_per_xchg
Maximum number of open sequences per exchange.
struct sockaddr * fc_fill_sockaddr(struct sockaddr_fc *sa_fc, struct fc_port_id *id)
Fill Fibre Channel socket address.
ELS transaction is a request.
int fc_els_prli(struct interface *parent, struct fc_port *port, struct fc_port_id *peer_port_id, unsigned int type)
Create PRLI request.
#define FC_PRLI_ESTABLISH
Establish image pair.
struct fc_port_id port_id
Port ID.
struct interface prli
PRLI interface.
struct refcnt refcnt
Reference count.
struct fc_login_class class3
Class 3 service parameters.
uint8_t command
ELS command code.
void process_add(struct process *process)
Add process to process list.
An object interface descriptor.
A Fibre Channel extended link services transaction.
static int fc_els_unknown_tx(struct fc_els *els __unused)
Transmit unknown ELS request.
char * strerror(int errno)
Retrieve string representation of error number.
struct fc_peer * fc_peer_get_port_id(struct fc_port *port, const struct fc_port_id *peer_port_id)
Get Fibre Channel peer by port ID.
static void(* free)(struct refcnt *refcnt))
static void fc_peer_put(struct fc_peer *peer)
Drop reference to Fibre Channel peer.
static int fc_els_flogi_detect(struct fc_els *els __unused, const void *data, size_t len __unused)
Detect FLOGI.
static struct process_descriptor fc_els_process_desc
Fibre Channel ELS process descriptor.
void * zalloc(size_t size)
Allocate cleared memory.
struct fc_name node_wwn
Node name.
struct fc_port * port
Fibre Channel port.
static int fc_els_plogi_rx(struct fc_els *els, void *data, size_t len)
Receive PLOGI.
struct fc_link_state link
Link state monitor.
void * param
Service parameters, if any.
static int fc_els_rtv_detect(struct fc_els *els __unused, const void *data, size_t len __unused)
Detect RTV.
static unsigned int fc_els_tx_command(struct fc_els *els, unsigned int request_command)
Calculate ELS command to transmit.
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.
#define INTF_OP(op_type, object_type, op_func)
Define an object interface operation.
struct fc_link_state link
Link state monitor.
#define FC_LOGIN_DEFAULT_MTU
Fibre Channel default MTU.
void fc_peer_logout(struct fc_peer *peer, int rc)
Log out Fibre Channel peer.
#define for_each_table_entry(pointer, table)
Iterate through all entries within a linker table.
uint32_t magic
Magic marker.
int xfer_deliver(struct interface *intf, struct io_buffer *iobuf, struct xfer_metadata *meta)
Deliver datagram.
int(* rx)(struct fc_els *els, void *data, size_t len)
Receive ELS frame.
struct interface job
Job control interface.
uint16_t credit
Buffer-to-buffer credit.
static void fc_els_step(struct fc_els *els)
Fibre Channel ELS process.
static void process_init_stopped(struct process *process, struct process_descriptor *desc, struct refcnt *refcnt)
Initialise process without adding to process list.
#define FCELS_ARGS(els)
Fibre Channel ELS transaction debug message arguments.
#define FC_ELS_HANDLERS
Fibre Channel ELS handler table.
static int fc_els_echo_detect(struct fc_els *els __unused, const void *data, size_t len __unused)
Detect ECHO.
A Fibre Channel LOGO response frame.
uint32_t e_d_tov
Error detection timeout value.
static int fc_els_logo_rx_response(struct fc_els *els, void *data __unused, size_t len __unused)
Receive LOGO response.
static int process_running(struct process *process)
Check if process is running.
uint8_t command
ELS command code.
int fc_ulp_login(struct fc_ulp *ulp, const void *param, size_t param_len, int originated)
Log in Fibre Channel upper-layer protocol.
static int fc_els_logo_tx_response(struct fc_els *els)
Transmit LOGO response.
static int fc_els_flogi_rx(struct fc_els *els, void *data, size_t len)
Receive FLOGI.
static struct fc_port * fc_port_get(struct fc_port *port)
Get reference to Fibre Channel port.
#define FC_LOGIN_DEFAULT_B2B
Fibre Channel default buffer-to-buffer credit.
struct interface plogi
PLOGI interface.
void fc_ulp_logout(struct fc_ulp *ulp, int rc)
Log out Fibre Channel upper-layer protocol.
static struct fc_els * fc_els_create(struct fc_port *port, struct fc_port_id *port_id, struct fc_port_id *peer_port_id)
Create ELS transaction.
#define INTF_DESC(object_type, intf, operations)
Define an object interface descriptor.
static int fc_els_logo_tx(struct fc_els *els)
Transmit LOGO request.
static int fc_els_is_request(struct fc_els *els)
Check if Fibre Channel ELS transaction is a request.
static int fc_els_echo_rx_response(struct fc_els *els, void *data, size_t len)
Receive ECHO response.
static struct interface_descriptor fc_els_job_desc
Fibre Channel ELS job control interface descriptor.
#define FC_LOGIN_DEFAULT_MAX_SEQ
Default maximum number of concurrent sequences.
uint8_t command
ELS command code.
A Fibre Channel LS_RJT frame.
void * data
Start of data.
#define EIO
Input/output error.
uint16_t mtu
Receive data field size.
struct fc_els_handler fc_els_unknown_handler __fc_els_handler
Unknown ELS handler.
static void fc_ulp_put(struct fc_ulp *ulp)
Drop reference to Fibre Channel upper-layer protocol.
if(len >=6 *4) __asm__ __volatile__("movsl" if(len >=5 *4) __asm__ __volatile__("movsl" if(len >=4 *4) __asm__ __volatile__("movsl" if(len >=3 *4) __asm__ __volatile__("movsl" if(len >=2 *4) __asm__ __volatile__("movsl" if(len >=1 *4) __asm__ __volatile__("movsl" if((len % 4) >=2) __asm__ __volatile__("movsw" if((len % 2) >=1) __asm__ __volatile__("movsb" return dest
uint8_t data[48]
Additional event data.
#define FC_PRLI_RESPONSE_SUCCESS
Request was executed successfully.
static int fc_els_rx(struct fc_els *els, struct io_buffer *iobuf, struct xfer_metadata *meta)
Receive Fibre Channel ELS frame.
struct fc_ulp * fc_ulp_get_port_id_type(struct fc_port *port, const struct fc_port_id *peer_port_id, unsigned int type)
Get Fibre Channel upper-layer protocol by port ID and type.
struct fc_name port_wwn
Port name.
#define FC_LOGIN_CLASS_VALID
Class valid.
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
#define XFER_FL_OVER
Sender is relinquishing use of half-duplex channel.
struct mschapv2_challenge peer
Peer challenge.
void fc_port_logout(struct fc_port *port, int rc)
Log out Fibre Channel port.
#define FC_LOGIN_VERSION
Fibre Channel default login version.
struct fc_login_common::@602::@603 plogi
static void fc_els_logo_logout(struct fc_els *els, struct fc_port_id *peer_port_id)
Log out individual peer or whole port as applicable.
int fc_els_prli_rx(struct fc_els *els, struct fc_els_prli_descriptor *descriptor, void *data, size_t len)
Receive PRLI.
struct process process
Request sending process.
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.
int fc_els_logo(struct interface *parent, struct fc_port *port, struct fc_port_id *peer_port_id)
Create LOGO request.
A Fibre Channel ELS PRLI descriptor.
struct fc_name port_wwn
Port name.
#define XFER_FL_OUT
This is the final data transfer.
uint16_t max_seq
Maximum number of concurrent sequences.
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
A Fibre Channel FLOGI/PLOGI frame.
#define NULL
NULL pointer (VOID *)
static void fc_els_free(struct refcnt *refcnt)
Free Fibre Channel ELS transaction.
static struct interface_operation fc_els_job_op[]
Fibre Channel ELS job control interface operations.
A Fibre Channel LOGO request frame.
struct bofm_section_header done
struct fc_port_id port_id
Local port ID.
static struct interface_descriptor fc_els_xchg_desc
Fibre Channel ELS exchange interface descriptor.
#define ref_put(refcnt)
Drop reference to object.
A Fibre Channel upper-layer protocol.
Fibre Channel Extended Link Services.
static int fc_els_rtv_rx(struct fc_els *els, void *data __unused, size_t len __unused)
Receive RTV.
union fc_login_common::@602 u
"Common"?!
void * memset(void *dest, int character, size_t len) __nonnull
static int fc_els_echo_tx(struct fc_els *els)
Transmit ECHO.