iPXE
fcels.c File Reference

Fibre Channel Extended Link Services. More...

#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <assert.h>
#include <byteswap.h>
#include <ipxe/interface.h>
#include <ipxe/xfer.h>
#include <ipxe/iobuf.h>
#include <ipxe/process.h>
#include <ipxe/fc.h>
#include <ipxe/fcels.h>

Go to the source code of this file.

Data Structures

struct  fc_echo_request_frame
 ECHO request data. More...

Macros

#define FCELS_FMT   "FCELS %s %s %s %s"
 Fibre Channel ELS transaction debug message format.
#define FCELS_ARGS(els)
 Fibre Channel ELS transaction debug message arguments.
#define FC_ECHO_MAGIC   0x69505845
 ECHO magic marker.

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
static void fc_els_free (struct refcnt *refcnt)
 Free Fibre Channel ELS transaction.
static void fc_els_close (struct fc_els *els, int rc)
 Close Fibre Channel ELS transaction.
static struct fc_els_handlerfc_els_detect (struct fc_els *els, const void *data, size_t len)
 Detect Fibre Channel ELS frame handler.
int fc_els_tx (struct fc_els *els, const void *data, size_t len)
 Transmit Fibre Channel ELS frame.
static int fc_els_rx (struct fc_els *els, struct io_buffer *iobuf, struct xfer_metadata *meta)
 Receive Fibre Channel ELS frame.
static void fc_els_step (struct fc_els *els)
 Fibre Channel ELS process.
static struct fc_elsfc_els_create (struct fc_port *port, struct fc_port_id *port_id, struct fc_port_id *peer_port_id)
 Create ELS transaction.
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.
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.
static int fc_els_unknown_tx (struct fc_els *els __unused)
 Transmit unknown ELS request.
static int fc_els_unknown_tx_response (struct fc_els *els)
 Transmit unknown ELS response.
static int fc_els_unknown_rx (struct fc_els *els, void *data, size_t len)
 Receive unknown ELS.
static int fc_els_unknown_detect (struct fc_els *els __unused, const void *data __unused, size_t len __unused)
 Detect unknown ELS.
static int fc_els_flogi_tx (struct fc_els *els)
 Transmit FLOGI.
static int fc_els_flogi_rx (struct fc_els *els, void *data, size_t len)
 Receive FLOGI.
static int fc_els_flogi_detect (struct fc_els *els __unused, const void *data, size_t len __unused)
 Detect FLOGI.
int fc_els_flogi (struct interface *parent, struct fc_port *port)
 Create FLOGI request.
static int fc_els_plogi_tx (struct fc_els *els)
 Transmit PLOGI.
static int fc_els_plogi_rx (struct fc_els *els, void *data, size_t len)
 Receive PLOGI.
static int fc_els_plogi_detect (struct fc_els *els __unused, const void *data, size_t len __unused)
 Detect PLOGI.
int fc_els_plogi (struct interface *parent, struct fc_port *port, struct fc_port_id *peer_port_id)
 Create PLOGI request.
static int fc_els_logo_tx (struct fc_els *els)
 Transmit LOGO request.
static int fc_els_logo_tx_response (struct fc_els *els)
 Transmit LOGO response.
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.
static int fc_els_logo_rx_request (struct fc_els *els, void *data, size_t len)
 Receive LOGO request.
static int fc_els_logo_rx_response (struct fc_els *els, void *data __unused, size_t len __unused)
 Receive LOGO response.
static int fc_els_logo_rx (struct fc_els *els, void *data, size_t len)
 Receive LOGO.
static int fc_els_logo_detect (struct fc_els *els __unused, const void *data, size_t len __unused)
 Detect LOGO.
int fc_els_logo (struct interface *parent, struct fc_port *port, struct fc_port_id *peer_port_id)
 Create LOGO request.
static struct fc_els_prli_descriptor * fc_els_prli_descriptor (unsigned int type)
 Find PRLI descriptor.
int fc_els_prli_tx (struct fc_els *els, struct fc_els_prli_descriptor *descriptor, void *param)
 Transmit PRLI.
int fc_els_prli_rx (struct fc_els *els, struct fc_els_prli_descriptor *descriptor, void *data, size_t len)
 Receive PRLI.
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 (struct interface *parent, struct fc_port *port, struct fc_port_id *peer_port_id, unsigned int type)
 Create PRLI request.
static int fc_els_rtv_tx_response (struct fc_els *els)
 Transmit RTV response.
static int fc_els_rtv_rx (struct fc_els *els, void *data __unused, size_t len __unused)
 Receive RTV.
static int fc_els_rtv_detect (struct fc_els *els __unused, const void *data, size_t len __unused)
 Detect RTV.
static int fc_els_echo_tx (struct fc_els *els)
 Transmit ECHO.
static int fc_els_echo_rx_request (struct fc_els *els, void *data, size_t len)
 Receive ECHO request.
static int fc_els_echo_rx_response (struct fc_els *els, void *data, size_t len)
 Receive ECHO response.
static int fc_els_echo_rx (struct fc_els *els, void *data, size_t len)
 Receive ECHO.
static int fc_els_echo_detect (struct fc_els *els __unused, const void *data, size_t len __unused)
 Detect ECHO.

Variables

struct fc_els_handler fc_els_unknown_handler __fc_els_handler
 Unknown ELS handler.
static struct interface_operation fc_els_xchg_op []
 Fibre Channel ELS exchange interface operations.
static struct interface_descriptor fc_els_xchg_desc
 Fibre Channel ELS exchange interface descriptor.
static struct interface_operation fc_els_job_op []
 Fibre Channel ELS job control interface operations.
static struct interface_descriptor fc_els_job_desc
 Fibre Channel ELS job control interface descriptor.
static struct process_descriptor fc_els_process_desc
 Fibre Channel ELS process descriptor.
struct fc_responder fc_els_responder __fc_responder
 Fibre Channel ELS responder.

Detailed Description

Fibre Channel Extended Link Services.

Definition in file fcels.c.

Macro Definition Documentation

◆ FCELS_FMT

#define FCELS_FMT   "FCELS %s %s %s %s"

◆ FCELS_ARGS

#define FCELS_ARGS ( els)
Value:
(els)->port->name, \
( (els)->handler ? (els)->handler->name : "unknown ELS" ), \
( fc_els_is_request ( els ) ? "to" : "from" ), \
fc_id_ntoa ( &(els)->peer_port_id )
u8 port
Port number.
Definition CIB_PRM.h:3
const char * fc_id_ntoa(const struct fc_port_id *id)
Format Fibre Channel port ID.
Definition fc.c:92
static int fc_els_is_request(struct fc_els *els)
Check if Fibre Channel ELS transaction is a request.
Definition fcels.h:409

Fibre Channel ELS transaction debug message arguments.

Definition at line 49 of file fcels.c.

49#define FCELS_ARGS( els ) \
50 (els)->port->name, \
51 ( (els)->handler ? (els)->handler->name : "unknown ELS" ), \
52 ( fc_els_is_request ( els ) ? "to" : "from" ), \
53 fc_id_ntoa ( &(els)->peer_port_id )

Referenced by fc_els_close(), fc_els_echo_rx_request(), fc_els_echo_rx_response(), fc_els_flogi_rx(), fc_els_logo_rx_request(), fc_els_plogi_rx(), fc_els_prli_rx(), fc_els_rtv_rx(), fc_els_rx(), fc_els_step(), fc_els_tx(), and fc_els_unknown_rx().

◆ FC_ECHO_MAGIC

#define FC_ECHO_MAGIC   0x69505845

ECHO magic marker.

Definition at line 1234 of file fcels.c.

Referenced by fc_els_echo_rx_response(), and fc_els_echo_tx().

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )

◆ fc_els_free()

void fc_els_free ( struct refcnt * refcnt)
static

Free Fibre Channel ELS transaction.

Parameters
refcntReference count

Definition at line 62 of file fcels.c.

62 {
63 struct fc_els *els = container_of ( refcnt, struct fc_els, refcnt );
64
65 assert ( ! process_running ( &els->process ) );
66 fc_port_put ( els->port );
67 free ( els );
68}
#define assert(condition)
Assert a condition at run-time.
Definition assert.h:61
static void fc_port_put(struct fc_port *port)
Drop reference to Fibre Channel port.
Definition fc.h:316
static int process_running(struct process *process)
Check if process is running.
Definition process.h:176
static void(* free)(struct refcnt *refcnt))
Definition refcnt.h:55
#define container_of(ptr, type, field)
Get containing structure.
Definition stddef.h:36
A Fibre Channel extended link services transaction.
Definition fcels.h:324
struct fc_port * port
Fibre Channel port.
Definition fcels.h:335
struct process process
Request sending process.
Definition fcels.h:332
A reference counter.
Definition refcnt.h:27

References assert, container_of, fc_port_put(), free, fc_els::port, fc_els::process, and process_running().

Referenced by fc_els_create().

◆ fc_els_close()

void fc_els_close ( struct fc_els * els,
int rc )
static

Close Fibre Channel ELS transaction.

Parameters
elsFibre Channel ELS transaction
rcReason for close

Definition at line 76 of file fcels.c.

76 {
77
78 if ( rc != 0 ) {
79 DBGC ( els, FCELS_FMT " complete (%s)\n",
80 FCELS_ARGS ( els ), strerror ( rc ) );
81 }
82
83 /* Stop process */
84 process_del ( &els->process );
85
86 /* Shut down interfaces */
87 intf_shutdown ( &els->xchg, rc );
88 intf_shutdown ( &els->job, rc );
89}
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
#define FCELS_FMT
Fibre Channel ELS transaction debug message format.
Definition fcels.c:46
#define FCELS_ARGS(els)
Fibre Channel ELS transaction debug message arguments.
Definition fcels.c:49
#define DBGC(...)
Definition compiler.h:530
void intf_shutdown(struct interface *intf, int rc)
Shut down an object interface.
Definition interface.c:279
void process_del(struct process *process)
Remove process from process list.
Definition process.c:80
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79
struct interface xchg
Fibre Channel exchange.
Definition fcels.h:330
struct interface job
Job control interface.
Definition fcels.h:328

References DBGC, FCELS_ARGS, FCELS_FMT, intf_shutdown(), fc_els::job, fc_els::process, process_del(), rc, strerror(), and fc_els::xchg.

Referenced by fc_els_rx(), and fc_els_step().

◆ fc_els_detect()

struct fc_els_handler * fc_els_detect ( struct fc_els * els,
const void * data,
size_t len )
static

Detect Fibre Channel ELS frame handler.

Parameters
elsFibre Channel ELS transaction
commandELS command code
Return values
handlerELS handler, or NULL

Definition at line 98 of file fcels.c.

100 {
101 const struct fc_els_frame_common *frame = data;
102 struct fc_els_handler *handler;
103 int rc;
104
105 /* Sanity check */
106 if ( len < sizeof ( *frame ) )
107 return NULL;
108
109 /* Try each handler in turn */
111 if ( ( rc = handler->detect ( els, data, len ) ) == 0 )
112 return handler;
113 }
114
115 return NULL;
116}
#define NULL
NULL pointer (VOID *).
Definition Base.h:321
ring len
Length.
Definition dwmac.h:226
uint8_t data[48]
Additional event data.
Definition ena.h:11
#define FC_ELS_HANDLERS
Fibre Channel ELS handler table.
Definition fcels.h:381
Fibre Channel ELS frame common parameters.
Definition fcels.h:23
A Fibre Channel extended link services handler.
Definition fcels.h:353
int(* detect)(struct fc_els *els, const void *data, size_t len)
Detect ELS frame.
Definition fcels.h:377
#define for_each_table_entry(pointer, table)
Iterate through all entries within a linker table.
Definition tables.h:386
unsigned long frame
Definition xengrant.h:180

References data, fc_els_handler::detect, FC_ELS_HANDLERS, for_each_table_entry, frame, len, NULL, and rc.

Referenced by fc_els_rx().

◆ fc_els_tx()

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

Transmit Fibre Channel ELS frame.

Parameters
elsFibre Channel ELS transaction
dataData to transmit
lenLength of data
Return values
rcReturn status code

Definition at line 126 of file fcels.c.

126 {
127 struct xfer_metadata meta;
128 struct sockaddr_fc dest;
129 int rc;
130
131 DBGC2 ( els, FCELS_FMT " transmitting:\n", FCELS_ARGS ( els ) );
132 DBGC2_HDA ( els, 0, data, len );
133
134 /* Construct metadata */
135 memset ( &meta, 0, sizeof ( meta ) );
136 meta.flags = ( fc_els_is_request ( els ) ?
138 meta.dest = fc_fill_sockaddr ( &dest, &els->peer_port_id );
139
140 /* Transmit frame */
141 if ( ( rc = xfer_deliver_raw_meta ( &els->xchg, data, len,
142 &meta ) ) != 0 ) {
143 DBGC ( els, FCELS_FMT " could not deliver frame: %s\n",
144 FCELS_ARGS ( els ), strerror ( rc ) );
145 return rc;
146 }
147
148 return 0;
149}
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" retur dest)
Definition string.h:151
uint8_t meta
Metadata flags.
Definition ena.h:3
struct sockaddr * fc_fill_sockaddr(struct sockaddr_fc *sa_fc, struct fc_port_id *id)
Fill Fibre Channel socket address.
Definition fc.c:165
#define DBGC2(...)
Definition compiler.h:547
#define DBGC2_HDA(...)
Definition compiler.h:548
void * memset(void *dest, int character, size_t len) __nonnull
struct fc_port_id peer_port_id
Peer port ID.
Definition fcels.h:339
Fibre Channel socket address.
Definition fc.h:48
Data transfer metadata.
Definition xfer.h:23
int xfer_deliver_raw_meta(struct interface *intf, const void *data, size_t len, struct xfer_metadata *meta)
Deliver datagram as raw data.
Definition xfer.c:269
#define XFER_FL_OVER
Sender is relinquishing use of half-duplex channel.
Definition xfer.h:51
#define XFER_FL_RESPONSE
Data content is a response.
Definition xfer.h:64
#define XFER_FL_OUT
This is the final data transfer.
Definition xfer.h:54

References data, DBGC, DBGC2, DBGC2_HDA, dest, fc_els_is_request(), fc_fill_sockaddr(), FCELS_ARGS, FCELS_FMT, len, memset(), meta, fc_els::peer_port_id, rc, strerror(), fc_els::xchg, xfer_deliver_raw_meta(), XFER_FL_OUT, XFER_FL_OVER, and XFER_FL_RESPONSE.

Referenced by fc_els_echo_rx_request(), fc_els_echo_tx(), fc_els_flogi_tx(), fc_els_logo_tx(), fc_els_logo_tx_response(), fc_els_plogi_tx(), fc_els_prli_tx(), fc_els_rtv_tx_response(), and fc_els_unknown_tx_response().

◆ fc_els_rx()

int fc_els_rx ( struct fc_els * els,
struct io_buffer * iobuf,
struct xfer_metadata * meta )
static

Receive Fibre Channel ELS frame.

Parameters
elsFibre Channel ELS transaction
iobufI/O buffer
metaData transfer metadata
Return values
rcReturn status code

Definition at line 159 of file fcels.c.

161 {
162 struct sockaddr_fc *src = ( ( struct sockaddr_fc * ) meta->src );
163 struct sockaddr_fc *dest = ( ( struct sockaddr_fc * ) meta->dest );
165 size_t len = iob_len ( iobuf );
166 int rc;
167
168 /* Sanity check */
169 if ( len < sizeof ( *frame ) ) {
170 DBGC ( els, FCELS_FMT " received underlength frame:\n",
171 FCELS_ARGS ( els ) );
172 DBGC_HDA ( els, 0, iobuf->data, len );
173 rc = -EINVAL;
174 goto done;
175 }
176 frame = iobuf->data;
177 if ( ! src ) {
178 DBGC ( els, FCELS_FMT " received frame missing source "
179 "address:\n", FCELS_ARGS ( els ) );
180 rc = -EINVAL;
181 goto done;
182 }
183 if ( ! dest ) {
184 DBGC ( els, FCELS_FMT " received frame missing destination "
185 "address:\n", FCELS_ARGS ( els ) );
186 rc = -EINVAL;
187 goto done;
188 }
189
190 /* Check for rejection responses */
191 if ( fc_els_is_request ( els ) &&
192 ( frame->command != FC_ELS_LS_ACC ) ) {
193 DBGC ( els, FCELS_FMT " rejected:\n", FCELS_ARGS ( els ) );
194 DBGC_HDA ( els, 0, frame, len );
195 rc = -EACCES;
196 goto done;
197 }
198
199 /* Update port IDs */
200 memcpy ( &els->port_id, &dest->sfc_port_id, sizeof ( els->port_id ) );
201 memcpy ( &els->peer_port_id, &src->sfc_port_id,
202 sizeof ( els->peer_port_id ) );
203
204 /* Determine handler, if necessary */
205 if ( ! els->handler )
206 els->handler = fc_els_detect ( els, frame, len );
207 if ( ! els->handler )
208 els->handler = &fc_els_unknown_handler;
209
210 DBGC2 ( els, FCELS_FMT " received:\n", FCELS_ARGS ( els ) );
211 DBGC2_HDA ( els, 0, frame, len );
212
213 /* Handle received frame */
214 if ( ( rc = els->handler->rx ( els, frame, len ) ) != 0 ) {
215 DBGC ( els, FCELS_FMT " could not handle received frame: "
216 "%s\n", FCELS_ARGS ( els ), strerror ( rc ) );
217 DBGC_HDA ( els, 0, frame, len );
218 goto done;
219 }
220
221 done:
222 /* Free I/O buffer */
223 free_iob ( iobuf );
224
225 /* Close transaction */
226 fc_els_close ( els, rc );
227
228 return rc;
229}
static const void * src
Definition string.h:48
struct bofm_section_header done
Definition bofm_test.c:46
static struct fc_els_handler * fc_els_detect(struct fc_els *els, const void *data, size_t len)
Detect Fibre Channel ELS frame handler.
Definition fcels.c:98
static void fc_els_close(struct fc_els *els, int rc)
Close Fibre Channel ELS transaction.
Definition fcels.c:76
@ FC_ELS_LS_ACC
Link Service Accept.
Definition fcels.h:33
#define DBGC_HDA(...)
Definition compiler.h:531
#define EINVAL
Invalid argument.
Definition errno.h:472
#define EACCES
Permission denied.
Definition errno.h:342
void * memcpy(void *dest, const void *src, size_t len) __nonnull
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
int(* rx)(struct fc_els *els, void *data, size_t len)
Receive ELS frame.
Definition fcels.h:369
struct fc_port_id port_id
Local port ID.
Definition fcels.h:337
struct fc_els_handler * handler
ELS handler, if known.
Definition fcels.h:341
void * data
Start of data.
Definition iobuf.h:113

References io_buffer::data, DBGC, DBGC2, DBGC2_HDA, DBGC_HDA, dest, done, EACCES, EINVAL, fc_els_close(), fc_els_detect(), fc_els_is_request(), FC_ELS_LS_ACC, FCELS_ARGS, FCELS_FMT, frame, free_iob(), fc_els::handler, iob_len(), len, memcpy(), meta, fc_els::peer_port_id, fc_els::port_id, rc, fc_els_handler::rx, src, and strerror().

◆ fc_els_step()

void fc_els_step ( struct fc_els * els)
static

Fibre Channel ELS process.

Parameters
elsFibre Channel ELS transaction

Definition at line 255 of file fcels.c.

255 {
256 int xchg_id;
257 int rc;
258
259 /* Sanity check */
260 assert ( fc_els_is_request ( els ) );
261
262 /* Create exchange */
263 if ( ( xchg_id = fc_xchg_originate ( &els->xchg, els->port,
264 &els->peer_port_id,
265 FC_TYPE_ELS ) ) < 0 ) {
266 rc = xchg_id;
267 DBGC ( els, FCELS_FMT " could not create exchange: %s\n",
268 FCELS_ARGS ( els ), strerror ( rc ) );
269 fc_els_close ( els, rc );
270 return;
271 }
272
273 /* Transmit request */
274 if ( ( rc = els->handler->tx ( els ) ) != 0 ) {
275 DBGC ( els, FCELS_FMT " could not transmit request: %s\n",
276 FCELS_ARGS ( els ), strerror ( rc ) );
277 fc_els_close ( els, rc );
278 return;
279 }
280}
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_ELS
Extended Link Service.
Definition fc.h:193
int(* tx)(struct fc_els *els)
Transmit ELS frame.
Definition fcels.h:361

References assert, DBGC, fc_els_close(), fc_els_is_request(), FC_TYPE_ELS, fc_xchg_originate(), FCELS_ARGS, FCELS_FMT, fc_els::handler, fc_els::peer_port_id, fc_els::port, rc, strerror(), fc_els_handler::tx, and fc_els::xchg.

◆ fc_els_create()

struct fc_els * fc_els_create ( struct fc_port * port,
struct fc_port_id * port_id,
struct fc_port_id * peer_port_id )
static

Create ELS transaction.

Parameters
portFibre Channel port
port_idLocal port ID
peer_port_idPeer port ID
Return values
elsFibre Channel ELS transaction, or NULL

Definition at line 294 of file fcels.c.

296 {
297 struct fc_els *els;
298
299 /* Allocate and initialise structure */
300 els = zalloc ( sizeof ( *els ) );
301 if ( ! els )
302 return NULL;
303 ref_init ( &els->refcnt, fc_els_free );
304 intf_init ( &els->job, &fc_els_job_desc, &els->refcnt );
305 intf_init ( &els->xchg, &fc_els_xchg_desc, &els->refcnt );
307 &els->refcnt );
308 els->port = fc_port_get ( port );
309 memcpy ( &els->port_id, port_id, sizeof ( els->port_id ) );
311 sizeof ( els->peer_port_id ) );
312 return els;
313}
static struct fc_port * fc_port_get(struct fc_port *port)
Get reference to Fibre Channel port.
Definition fc.h:305
static void fc_els_free(struct refcnt *refcnt)
Free Fibre Channel ELS transaction.
Definition fcels.c:62
static struct interface_descriptor fc_els_xchg_desc
Fibre Channel ELS exchange interface descriptor.
Definition fcels.c:238
static struct process_descriptor fc_els_process_desc
Fibre Channel ELS process descriptor.
Definition fcels.c:283
static struct interface_descriptor fc_els_job_desc
Fibre Channel ELS job control interface descriptor.
Definition fcels.c:247
static void intf_init(struct interface *intf, struct interface_descriptor *desc, struct refcnt *refcnt)
Initialise an object interface.
Definition interface.h:204
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 refcnt refcnt
Reference count.
Definition fcels.h:326

References fc_els_free(), fc_els_job_desc, fc_els_process_desc, fc_els_xchg_desc, fc_port_get(), intf_init(), fc_els::job, memcpy(), NULL, fc_els::peer_port_id, fc_els::port, port, fc_els::port_id, fc_els::process, process_init_stopped(), ref_init, fc_els::refcnt, fc_els::xchg, and zalloc().

Referenced by fc_els_request(), and fc_els_respond().

◆ fc_els_request()

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.

Parameters
jobParent job-control interface
portFibre Channel port
peer_port_idPeer port ID
handlerELS handler
Return values
rcReturn status code

Definition at line 324 of file fcels.c.

326 {
327 struct fc_els *els;
328
329 /* Allocate and initialise structure */
330 els = fc_els_create ( port, &port->port_id, peer_port_id );
331 if ( ! els )
332 return -ENOMEM;
333 els->handler = handler;
334 els->flags = FC_ELS_REQUEST;
335 process_add ( &els->process );
336
337 /* Attach to parent job interface, mortalise self, and return */
338 intf_plug_plug ( &els->job, job );
339 ref_put ( &els->refcnt );
340 return 0;
341}
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.
Definition fcels.c:294
@ FC_ELS_REQUEST
ELS transaction is a request.
Definition fcels.h:349
#define ENOMEM
Not enough space.
Definition errno.h:578
void intf_plug_plug(struct interface *a, struct interface *b)
Plug two object interfaces together.
Definition interface.c:108
void process_add(struct process *process)
Add process to process list.
Definition process.c:60
#define ref_put(refcnt)
Drop reference to object.
Definition refcnt.h:107
unsigned int flags
Flags.
Definition fcels.h:343

References ENOMEM, fc_els_create(), FC_ELS_REQUEST, fc_els::flags, fc_els::handler, intf_plug_plug(), fc_els::job, fc_els::peer_port_id, port, fc_els::process, process_add(), ref_put, and fc_els::refcnt.

Referenced by fc_els_flogi(), fc_els_logo(), fc_els_plogi(), fc_els_prli(), and fcels().

◆ fc_els_respond()

int fc_els_respond ( struct interface * xchg,
struct fc_port * port,
struct fc_port_id * port_id,
struct fc_port_id * peer_port_id )
static

Create ELS response.

Parameters
xchgExchange interface
portFibre Channel port
port_idLocal port ID
peer_port_idPeer port ID
Return values
rcReturn status code

Definition at line 352 of file fcels.c.

354 {
355 struct fc_els *els;
356
357 /* Allocate and initialise structure */
359 if ( ! els )
360 return -ENOMEM;
361
362 /* Attach to exchange interface, mortalise self, and return */
363 intf_plug_plug ( &els->xchg, xchg );
364 ref_put ( &els->refcnt );
365 return 0;
366}

References ENOMEM, fc_els_create(), intf_plug_plug(), fc_els::peer_port_id, port, fc_els::port_id, ref_put, fc_els::refcnt, and fc_els::xchg.

◆ fc_els_unknown_tx()

int fc_els_unknown_tx ( struct fc_els *els __unused)
static

Transmit unknown ELS request.

Parameters
elsFibre Channel ELS transaction
Return values
rcReturn status code

Definition at line 387 of file fcels.c.

387 {
388 return -ENOTSUP;
389}
#define ENOTSUP
Operation not supported.
Definition errno.h:633

References __unused, and ENOTSUP.

◆ fc_els_unknown_tx_response()

int fc_els_unknown_tx_response ( struct fc_els * els)
static

Transmit unknown ELS response.

Parameters
elsFibre Channel ELS transaction
Return values
rcReturn status code

Definition at line 397 of file fcels.c.

397 {
398 struct fc_ls_rjt_frame ls_rjt;
399
400 /* Construct LS_RJT */
401 memset ( &ls_rjt, 0, sizeof ( ls_rjt ) );
402 ls_rjt.command = FC_ELS_LS_RJT;
403 ls_rjt.reason = FC_ELS_RJT_UNSUPPORTED;
404
405 /* Transmit LS_RJT */
406 return fc_els_tx ( els, &ls_rjt, sizeof ( ls_rjt ) );
407}
int fc_els_tx(struct fc_els *els, const void *data, size_t len)
Transmit Fibre Channel ELS frame.
Definition fcels.c:126
@ FC_ELS_LS_RJT
Link Service Reject.
Definition fcels.h:32
@ FC_ELS_RJT_UNSUPPORTED
Command not supported.
Definition fcels.h:70
A Fibre Channel LS_RJT frame.
Definition fcels.h:44

References fc_ls_rjt_frame::command, FC_ELS_LS_RJT, FC_ELS_RJT_UNSUPPORTED, fc_els_tx(), memset(), and fc_ls_rjt_frame::reason.

Referenced by fc_els_unknown_rx().

◆ fc_els_unknown_rx()

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

Receive unknown ELS.

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

Definition at line 417 of file fcels.c.

417 {
418 int rc;
419
420 DBGC ( els, FCELS_FMT ":\n", FCELS_ARGS ( els ) );
421 DBGC_HDA ( els, 0, data, len );
422
423 /* Transmit response, if applicable */
424 if ( ! fc_els_is_request ( els ) ) {
425 if ( ( rc = fc_els_unknown_tx_response ( els ) ) != 0 )
426 return rc;
427 }
428
429 return 0;
430}
static int fc_els_unknown_tx_response(struct fc_els *els)
Transmit unknown ELS response.
Definition fcels.c:397

References data, DBGC, DBGC_HDA, fc_els_is_request(), fc_els_unknown_tx_response(), FCELS_ARGS, FCELS_FMT, len, and rc.

◆ fc_els_unknown_detect()

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

Detect unknown ELS.

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

Definition at line 440 of file fcels.c.

442 {
443 return -ENOTSUP;
444}

References __unused, data, ENOTSUP, and len.

◆ fc_els_flogi_tx()

int fc_els_flogi_tx ( struct fc_els * els)
static

Transmit FLOGI.

Parameters
elsFibre Channel ELS transaction
Return values
rcReturn status code

Definition at line 467 of file fcels.c.

467 {
468 struct fc_login_frame flogi;
469
470 /* Construct FLOGI */
471 memset ( &flogi, 0, sizeof ( flogi ) );
472 flogi.command = fc_els_tx_command ( els, FC_ELS_FLOGI );
473 flogi.common.version = htons ( FC_LOGIN_VERSION );
474 flogi.common.credit = htons ( FC_LOGIN_DEFAULT_B2B );
475 flogi.common.flags = htons ( FC_LOGIN_CONTINUOUS_OFFSET );
476 flogi.common.mtu = htons ( FC_LOGIN_DEFAULT_MTU );
477 memcpy ( &flogi.port_wwn, &els->port->port_wwn,
478 sizeof ( flogi.port_wwn ) );
479 memcpy ( &flogi.node_wwn, &els->port->node_wwn,
480 sizeof ( flogi.node_wwn ) );
481 flogi.class3.flags = htons ( FC_LOGIN_CLASS_VALID |
483
484 /* Transmit FLOGI */
485 return fc_els_tx ( els, &flogi, sizeof ( flogi ) );
486}
@ FC_ELS_FLOGI
Fabric Login.
Definition fcels.h:35
#define FC_LOGIN_CONTINUOUS_OFFSET
Continuously increasing relative offset.
Definition fcels.h:109
#define FC_LOGIN_CLASS_SEQUENTIAL
Sequential delivery requested.
Definition fcels.h:206
#define FC_LOGIN_VERSION
Fibre Channel default login version.
Definition fcels.h:103
#define FC_LOGIN_DEFAULT_MTU
Fibre Channel default MTU.
Definition fcels.h:169
#define FC_LOGIN_CLASS_VALID
Class valid.
Definition fcels.h:203
static unsigned int fc_els_tx_command(struct fc_els *els, unsigned int request_command)
Calculate ELS command to transmit.
Definition fcels.h:420
#define FC_LOGIN_DEFAULT_B2B
Fibre Channel default buffer-to-buffer credit.
Definition fcels.h:106
#define htons(value)
Definition byteswap.h:136
A Fibre Channel FLOGI/PLOGI frame.
Definition fcels.h:209
struct fc_name node_wwn
Node name.
Definition fc.h:264
struct fc_name port_wwn
Port name.
Definition fc.h:266

References fc_login_frame::class3, fc_login_frame::command, fc_login_frame::common, fc_login_common::credit, FC_ELS_FLOGI, fc_els_tx(), fc_els_tx_command(), FC_LOGIN_CLASS_SEQUENTIAL, FC_LOGIN_CLASS_VALID, FC_LOGIN_CONTINUOUS_OFFSET, FC_LOGIN_DEFAULT_B2B, FC_LOGIN_DEFAULT_MTU, FC_LOGIN_VERSION, fc_login_class::flags, fc_login_common::flags, htons, memcpy(), memset(), fc_login_common::mtu, fc_login_frame::node_wwn, fc_port::node_wwn, fc_els::port, fc_login_frame::port_wwn, fc_port::port_wwn, and fc_login_common::version.

Referenced by fc_els_flogi_rx().

◆ fc_els_flogi_rx()

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

Receive FLOGI.

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

Definition at line 496 of file fcels.c.

496 {
497 struct fc_login_frame *flogi;
498 int has_fabric;
499 int rc;
500
501 /* Sanity check */
502 if ( len < sizeof ( *flogi ) ) {
503 DBGC ( els, FCELS_FMT " received underlength frame:\n",
504 FCELS_ARGS ( els ) );
505 DBGC_HDA ( els, 0, data, len );
506 return -EINVAL;
507 }
508 flogi = data;
509
510 /* Extract parameters */
511 has_fabric = ( flogi->common.flags & htons ( FC_LOGIN_F_PORT ) );
512 DBGC ( els, FCELS_FMT " has node %s\n", FCELS_ARGS ( els ),
513 fc_ntoa ( &flogi->node_wwn ) );
514 DBGC ( els, FCELS_FMT " has port %s\n", FCELS_ARGS ( els ),
515 fc_ntoa ( &flogi->port_wwn ) );
516 if ( has_fabric ) {
517 DBGC ( els, FCELS_FMT " has fabric with", FCELS_ARGS ( els ) );
518 DBGC ( els, " local ID %s\n", fc_id_ntoa ( &els->port_id ) );
519 } else {
520 DBGC ( els, FCELS_FMT " has point-to-point link\n",
521 FCELS_ARGS ( els ) );
522 }
523
524 /* Log in port */
525 if ( ( rc = fc_port_login ( els->port, &els->port_id, &flogi->node_wwn,
526 &flogi->port_wwn, has_fabric ) ) != 0 ) {
527 DBGC ( els, FCELS_FMT " could not log in port: %s\n",
528 FCELS_ARGS ( els ), strerror ( rc ) );
529 return rc;
530 }
531
532 /* Send any responses to the newly-assigned peer port ID, if
533 * applicable.
534 */
535 if ( ! has_fabric ) {
537 sizeof ( els->peer_port_id ) );
538 }
539
540 /* Transmit response, if applicable */
541 if ( ! fc_els_is_request ( els ) ) {
542 if ( ( rc = fc_els_flogi_tx ( els ) ) != 0 )
543 return rc;
544 }
545
546 return 0;
547}
const char * fc_ntoa(const struct fc_name *wwn)
Format Fibre Channel WWN.
Definition fc.c:127
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.
Definition fc.c:942
static int fc_els_flogi_tx(struct fc_els *els)
Transmit FLOGI.
Definition fcels.c:467
#define FC_LOGIN_F_PORT
Forwarder port.
Definition fcels.h:130
uint16_t flags
Flags.
Definition fcels.h:82
struct fc_login_common common
Common service parameters.
Definition fcels.h:215
struct fc_name port_wwn
Port name.
Definition fcels.h:217
struct fc_name node_wwn
Node name.
Definition fcels.h:219
struct fc_port_id ptp_link_port_id
Link port ID (for point-to-point links only).
Definition fc.h:281

References fc_login_frame::common, data, DBGC, DBGC_HDA, EINVAL, fc_els_flogi_tx(), fc_els_is_request(), fc_id_ntoa(), FC_LOGIN_F_PORT, fc_ntoa(), fc_port_login(), FCELS_ARGS, FCELS_FMT, fc_login_common::flags, htons, len, memcpy(), fc_login_frame::node_wwn, fc_els::peer_port_id, fc_els::port, fc_els::port_id, fc_login_frame::port_wwn, fc_port::ptp_link_port_id, rc, and strerror().

◆ fc_els_flogi_detect()

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

Detect FLOGI.

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

Definition at line 557 of file fcels.c.

558 {
559 const struct fc_login_frame *flogi = data;
560
561 /* Check for FLOGI */
562 if ( flogi->command != FC_ELS_FLOGI )
563 return -EINVAL;
564
565 return 0;
566}
uint8_t command
ELS command code.
Definition fcels.h:211

References __unused, fc_login_frame::command, data, EINVAL, FC_ELS_FLOGI, and len.

◆ fc_els_flogi()

int fc_els_flogi ( struct interface * parent,
struct fc_port * port )

Create FLOGI request.

Parameters
parentParent interface
portFibre Channel port
Return values
rcReturn status code

Definition at line 583 of file fcels.c.

583 {
584
585 return fc_els_request ( parent, port, &fc_f_port_id,
586 &fc_els_flogi_handler );
587}
struct fc_port_id fc_f_port_id
F_Port contoller port ID.
Definition fc.c:68
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.
Definition fcels.c:324

References fc_els_request(), fc_f_port_id, and port.

Referenced by fc_port_examine().

◆ fc_els_plogi_tx()

int fc_els_plogi_tx ( struct fc_els * els)
static

Transmit PLOGI.

Parameters
elsFibre Channel ELS transaction
Return values
rcReturn status code

Definition at line 602 of file fcels.c.

602 {
603 struct fc_login_frame plogi;
604
605 /* Construct PLOGI */
606 memset ( &plogi, 0, sizeof ( plogi ) );
607 plogi.command = fc_els_tx_command ( els, FC_ELS_PLOGI );
608 plogi.common.version = htons ( FC_LOGIN_VERSION );
609 plogi.common.credit = htons ( FC_LOGIN_DEFAULT_B2B );
610 plogi.common.flags = htons ( FC_LOGIN_CONTINUOUS_OFFSET );
611 plogi.common.mtu = htons ( FC_LOGIN_DEFAULT_MTU );
612 plogi.common.u.plogi.max_seq = htons ( FC_LOGIN_DEFAULT_MAX_SEQ );
613 plogi.common.u.plogi.rel_offs = htons ( FC_LOGIN_DEFAULT_REL_OFFS );
614 plogi.common.e_d_tov = htonl ( FC_LOGIN_DEFAULT_E_D_TOV );
615 memcpy ( &plogi.port_wwn, &els->port->port_wwn,
616 sizeof ( plogi.port_wwn ) );
617 memcpy ( &plogi.node_wwn, &els->port->node_wwn,
618 sizeof ( plogi.node_wwn ) );
619 plogi.class3.flags = htons ( FC_LOGIN_CLASS_VALID |
621 plogi.class3.mtu = htons ( FC_LOGIN_DEFAULT_MTU );
622 plogi.class3.max_seq = htons ( FC_LOGIN_DEFAULT_MAX_SEQ );
623 plogi.class3.max_seq_per_xchg = 1;
624
625 /* Transmit PLOGI */
626 return fc_els_tx ( els, &plogi, sizeof ( plogi ) );
627}
@ FC_ELS_PLOGI
Port Login.
Definition fcels.h:34
#define FC_LOGIN_DEFAULT_REL_OFFS
Default relative offset by info category.
Definition fcels.h:175
#define FC_LOGIN_DEFAULT_E_D_TOV
Default E_D timeout value.
Definition fcels.h:178
#define FC_LOGIN_DEFAULT_MAX_SEQ
Default maximum number of concurrent sequences.
Definition fcels.h:172
#define htonl(value)
Definition byteswap.h:134

References fc_login_frame::class3, fc_login_frame::command, fc_login_frame::common, fc_login_common::credit, fc_login_common::e_d_tov, FC_ELS_PLOGI, fc_els_tx(), fc_els_tx_command(), FC_LOGIN_CLASS_SEQUENTIAL, FC_LOGIN_CLASS_VALID, FC_LOGIN_CONTINUOUS_OFFSET, FC_LOGIN_DEFAULT_B2B, FC_LOGIN_DEFAULT_E_D_TOV, FC_LOGIN_DEFAULT_MAX_SEQ, FC_LOGIN_DEFAULT_MTU, FC_LOGIN_DEFAULT_REL_OFFS, FC_LOGIN_VERSION, fc_login_class::flags, fc_login_common::flags, htonl, htons, fc_login_class::max_seq, fc_login_common::max_seq, fc_login_class::max_seq_per_xchg, memcpy(), memset(), fc_login_class::mtu, fc_login_common::mtu, fc_login_frame::node_wwn, fc_port::node_wwn, fc_login_common::plogi, fc_els::port, fc_login_frame::port_wwn, fc_port::port_wwn, fc_login_common::rel_offs, fc_login_common::u, and fc_login_common::version.

Referenced by fc_els_plogi_rx().

◆ fc_els_plogi_rx()

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

Receive PLOGI.

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

Definition at line 637 of file fcels.c.

637 {
638 struct fc_login_frame *plogi;
639 struct fc_peer *peer;
640 int rc;
641
642 /* Sanity checks */
643 if ( len < sizeof ( *plogi ) ) {
644 DBGC ( els, FCELS_FMT " received underlength frame:\n",
645 FCELS_ARGS ( els ) );
646 DBGC_HDA ( els, 0, data, len );
647 rc = -EINVAL;
648 goto err_sanity;
649 }
650 plogi = data;
651 if ( ! fc_link_ok ( &els->port->link ) ) {
652 DBGC ( els, FCELS_FMT " received while port link is down\n",
653 FCELS_ARGS ( els ) );
654 rc = -EINVAL;
655 goto err_sanity;
656 }
657
658 /* Extract parameters */
659 DBGC ( els, FCELS_FMT " has node %s\n", FCELS_ARGS ( els ),
660 fc_ntoa ( &plogi->node_wwn ) );
661 DBGC ( els, FCELS_FMT " has port %s as %s\n",
662 FCELS_ARGS ( els ), fc_ntoa ( &plogi->port_wwn ),
663 fc_id_ntoa ( &els->peer_port_id ) );
664
665 /* Get peer */
666 peer = fc_peer_get_wwn ( &plogi->port_wwn );
667 if ( ! peer ) {
668 DBGC ( els, FCELS_FMT " could not create peer\n",
669 FCELS_ARGS ( els ) );
670 rc = -ENOMEM;
671 goto err_peer_get_wwn;
672 }
673
674 /* Record login */
675 if ( ( rc = fc_peer_login ( peer, els->port,
676 &els->peer_port_id ) ) != 0 ) {
677 DBGC ( els, FCELS_FMT " could not log in peer: %s\n",
678 FCELS_ARGS ( els ), strerror ( rc ) );
679 goto err_login;
680 }
681
682 /* Transmit response, if applicable */
683 if ( ! fc_els_is_request ( els ) ) {
684 if ( ( rc = fc_els_plogi_tx ( els ) ) != 0 )
685 goto err_plogi_tx;
686 }
687
688 /* Drop temporary reference to peer */
689 fc_peer_put ( peer );
690
691 return 0;
692
693 err_plogi_tx:
694 err_login:
695 fc_peer_put ( peer );
696 err_peer_get_wwn:
697 err_sanity:
698 return rc;
699}
struct fc_peer * fc_peer_get_wwn(const struct fc_name *port_wwn)
Get Fibre Channel peer by node name.
Definition fc.c:1517
int fc_peer_login(struct fc_peer *peer, struct fc_port *port, struct fc_port_id *port_id)
Log in Fibre Channel peer.
Definition fc.c:1301
static void fc_peer_put(struct fc_peer *peer)
Drop reference to Fibre Channel peer.
Definition fc.h:391
static int fc_link_ok(struct fc_link_state *link)
Check Fibre Channel link state.
Definition fc.h:109
static int fc_els_plogi_tx(struct fc_els *els)
Transmit PLOGI.
Definition fcels.c:602
struct mschapv2_challenge peer
Peer challenge.
Definition mschapv2.h:1
A Fibre Channel peer.
Definition fc.h:341
struct interface plogi
PLOGI interface.
Definition fc.h:353
struct fc_link_state link
Link state monitor.
Definition fc.h:273

References data, DBGC, DBGC_HDA, EINVAL, ENOMEM, fc_els_is_request(), fc_els_plogi_tx(), fc_id_ntoa(), fc_link_ok(), fc_ntoa(), fc_peer_get_wwn(), fc_peer_login(), fc_peer_put(), FCELS_ARGS, FCELS_FMT, len, fc_port::link, peer, fc_els::peer_port_id, fc_peer::plogi, fc_els::port, rc, and strerror().

◆ fc_els_plogi_detect()

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

Detect PLOGI.

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

Definition at line 709 of file fcels.c.

710 {
711 const struct fc_login_frame *plogi = data;
712
713 /* Check for PLOGI */
714 if ( plogi->command != FC_ELS_PLOGI )
715 return -EINVAL;
716
717 return 0;
718}

References __unused, fc_login_frame::command, data, EINVAL, FC_ELS_PLOGI, and len.

◆ fc_els_plogi()

int fc_els_plogi ( struct interface * parent,
struct fc_port * port,
struct fc_port_id * peer_port_id )

Create PLOGI request.

Parameters
parentParent interface
portFibre Channel port
peer_port_idPeer port ID
Return values
rcReturn status code

Definition at line 736 of file fcels.c.

737 {
738
739 return fc_els_request ( parent, port, peer_port_id,
740 &fc_els_plogi_handler );
741}

References fc_els_request(), and port.

Referenced by fc_peer_plogi(), and fc_port_login().

◆ fc_els_logo_tx()

int fc_els_logo_tx ( struct fc_els * els)
static

Transmit LOGO request.

Parameters
elsFibre Channel ELS transaction
Return values
rcReturn status code

Definition at line 756 of file fcels.c.

756 {
757 struct fc_logout_request_frame logo;
758
759 /* Construct LOGO */
760 memset ( &logo, 0, sizeof ( logo ) );
761 logo.command = FC_ELS_LOGO;
762 memcpy ( &logo.port_id, &els->port->port_id, sizeof ( logo.port_id ) );
763 memcpy ( &logo.port_wwn, &els->port->port_wwn,
764 sizeof ( logo.port_wwn ) );
765
766 /* Transmit LOGO */
767 return fc_els_tx ( els, &logo, sizeof ( logo ) );
768}
@ FC_ELS_LOGO
Logout.
Definition fcels.h:36
A Fibre Channel LOGO request frame.
Definition fcels.h:233
struct fc_port_id port_id
Local port ID.
Definition fc.h:268

References fc_logout_request_frame::command, FC_ELS_LOGO, fc_els_tx(), memcpy(), memset(), fc_els::port, fc_logout_request_frame::port_id, fc_port::port_id, fc_logout_request_frame::port_wwn, and fc_port::port_wwn.

◆ fc_els_logo_tx_response()

int fc_els_logo_tx_response ( struct fc_els * els)
static

Transmit LOGO response.

Parameters
elsFibre Channel ELS transaction
Return values
rcReturn status code

Definition at line 776 of file fcels.c.

776 {
777 struct fc_logout_response_frame logo;
778
779 /* Construct LOGO */
780 memset ( &logo, 0, sizeof ( logo ) );
781 logo.command = FC_ELS_LS_ACC;
782
783 /* Transmit LOGO */
784 return fc_els_tx ( els, &logo, sizeof ( logo ) );
785}
A Fibre Channel LOGO response frame.
Definition fcels.h:245

References fc_logout_response_frame::command, FC_ELS_LS_ACC, fc_els_tx(), and memset().

Referenced by fc_els_logo_rx_request().

◆ fc_els_logo_logout()

void fc_els_logo_logout ( struct fc_els * els,
struct fc_port_id * peer_port_id )
static

Log out individual peer or whole port as applicable.

Parameters
elsFibre Channel ELS transaction
port_idPeer port ID

Definition at line 793 of file fcels.c.

794 {
795 struct fc_peer *peer;
796
797 if ( ( memcmp ( peer_port_id, &fc_f_port_id,
798 sizeof ( *peer_port_id ) ) == 0 ) ||
799 ( memcmp ( peer_port_id, &els->port->port_id,
800 sizeof ( *peer_port_id ) ) == 0 ) ) {
801 fc_port_logout ( els->port, 0 );
802 } else {
803 peer = fc_peer_get_port_id ( els->port, peer_port_id );
804 if ( peer ) {
805 fc_peer_logout ( peer, 0 );
806 fc_peer_put ( peer );
807 }
808 }
809}
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.
Definition fc.c:1542
void fc_peer_logout(struct fc_peer *peer, int rc)
Log out Fibre Channel peer.
Definition fc.c:1348
void fc_port_logout(struct fc_port *port, int rc)
Log out Fibre Channel port.
Definition fc.c:1040
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition string.c:115

References fc_f_port_id, fc_peer_get_port_id(), fc_peer_logout(), fc_peer_put(), fc_port_logout(), memcmp(), peer, fc_els::port, and fc_port::port_id.

Referenced by fc_els_logo_rx_request(), and fc_els_logo_rx_response().

◆ fc_els_logo_rx_request()

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

Receive LOGO request.

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

Definition at line 819 of file fcels.c.

820 {
821 struct fc_logout_request_frame *logo;
822 int rc;
823
824 /* Sanity check */
825 if ( len < sizeof ( *logo ) ) {
826 DBGC ( els, FCELS_FMT " received underlength frame:\n",
827 FCELS_ARGS ( els ) );
828 DBGC_HDA ( els, 0, data, len );
829 return -EINVAL;
830 }
831 logo = data;
832
833 DBGC ( els, FCELS_FMT " has port %s as %s\n", FCELS_ARGS ( els ),
834 fc_ntoa ( &logo->port_wwn ), fc_id_ntoa ( &logo->port_id ) );
835
836 /* Log out individual peer or whole port as applicable */
837 fc_els_logo_logout ( els, &logo->port_id );
838
839 /* Transmit repsonse */
840 if ( ( rc = fc_els_logo_tx_response ( els ) ) != 0 )
841 return rc;
842
843 return 0;
844}
static int fc_els_logo_tx_response(struct fc_els *els)
Transmit LOGO response.
Definition fcels.c:776
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.
Definition fcels.c:793
struct fc_name port_wwn
Port name.
Definition fcels.h:241
struct fc_port_id port_id
Port ID.
Definition fcels.h:239

References data, DBGC, DBGC_HDA, EINVAL, fc_els_logo_logout(), fc_els_logo_tx_response(), fc_id_ntoa(), fc_ntoa(), FCELS_ARGS, FCELS_FMT, len, fc_logout_request_frame::port_id, fc_logout_request_frame::port_wwn, and rc.

Referenced by fc_els_logo_rx().

◆ fc_els_logo_rx_response()

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

Receive LOGO response.

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

Definition at line 854 of file fcels.c.

855 {
856
857 /* Log out individual peer or whole port as applicable */
858 fc_els_logo_logout ( els, &els->peer_port_id );
859
860 return 0;
861}

References __unused, data, fc_els_logo_logout(), len, and fc_els::peer_port_id.

Referenced by fc_els_logo_rx().

◆ fc_els_logo_rx()

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

Receive LOGO.

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

Definition at line 871 of file fcels.c.

871 {
872
873 if ( fc_els_is_request ( els ) ) {
874 return fc_els_logo_rx_response ( els, data, len );
875 } else {
876 return fc_els_logo_rx_request ( els, data, len );
877 }
878}
static int fc_els_logo_rx_request(struct fc_els *els, void *data, size_t len)
Receive LOGO request.
Definition fcels.c:819
static int fc_els_logo_rx_response(struct fc_els *els, void *data __unused, size_t len __unused)
Receive LOGO response.
Definition fcels.c:854

References data, fc_els_is_request(), fc_els_logo_rx_request(), fc_els_logo_rx_response(), and len.

◆ fc_els_logo_detect()

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

Detect LOGO.

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

Definition at line 888 of file fcels.c.

889 {
890 const struct fc_logout_request_frame *logo = data;
891
892 /* Check for LOGO */
893 if ( logo->command != FC_ELS_LOGO )
894 return -EINVAL;
895
896 return 0;
897}
uint8_t command
ELS command code.
Definition fcels.h:235

References __unused, fc_logout_request_frame::command, data, EINVAL, FC_ELS_LOGO, and len.

◆ fc_els_logo()

int fc_els_logo ( struct interface * parent,
struct fc_port * port,
struct fc_port_id * peer_port_id )

Create LOGO request.

Parameters
parentParent interface
portFibre Channel port
peer_port_idPeer port ID
Return values
rcReturn status code

Definition at line 915 of file fcels.c.

916 {
917
918 return fc_els_request ( parent, port, peer_port_id,
919 &fc_els_logo_handler );
920}

References fc_els_request(), and port.

◆ fc_els_prli_descriptor()

struct fc_els_prli_descriptor * fc_els_prli_descriptor ( unsigned int type)
static

Find PRLI descriptor.

Parameters
typeUpper-layer protocol type
Return values
descriptorPRLI descriptor, or NULL

Definition at line 936 of file fcels.c.

936 {
937 struct fc_els_prli_descriptor *descriptor;
938
940 if ( descriptor->type == type )
941 return descriptor;
942 }
943 return NULL;
944}
uint32_t type
Operating system type.
Definition ena.h:1
#define FC_ELS_PRLI_DESCRIPTORS
Fibre Channel ELS PRLI descriptor table.
Definition fcels.h:397
A Fibre Channel ELS PRLI descriptor.
Definition fcels.h:387
unsigned int type
Upper-layer protocol type.
Definition fcels.h:389

References FC_ELS_PRLI_DESCRIPTORS, for_each_table_entry, NULL, fc_els_prli_descriptor::type, and type.

Referenced by fc_els_prli().

◆ fc_els_prli_tx()

int fc_els_prli_tx ( struct fc_els * els,
struct fc_els_prli_descriptor * descriptor,
void * param )

Transmit PRLI.

Parameters
elsFibre Channel ELS transaction
descriptorELS PRLI descriptor
paramService parameters
Return values
rcReturn status code

Definition at line 954 of file fcels.c.

955 {
956 struct {
957 struct fc_prli_frame frame;
958 uint8_t param[descriptor->param_len];
959 } __attribute__ (( packed )) prli;
960 struct fc_ulp *ulp;
961 int rc;
962
963 /* Get ULP */
964 ulp = fc_ulp_get_port_id_type ( els->port, &els->peer_port_id,
965 descriptor->type );
966 if ( ! ulp ) {
967 rc = -ENOMEM;
968 goto err_get_port_id_type;
969 }
970
971 /* Build frame for transmission */
972 memset ( &prli, 0, sizeof ( prli ) );
973 prli.frame.command = fc_els_tx_command ( els, FC_ELS_PRLI );
974 prli.frame.page_len =
975 ( sizeof ( prli.frame.page ) + sizeof ( prli.param ) );
976 prli.frame.len = htons ( sizeof ( prli ) );
977 prli.frame.page.type = descriptor->type;
978 if ( fc_els_is_request ( els ) ) {
979 prli.frame.page.flags |= htons ( FC_PRLI_ESTABLISH );
980 } else if ( fc_link_ok ( &ulp->link ) ) {
981 prli.frame.page.flags |= htons ( FC_PRLI_ESTABLISH |
983 }
984 memcpy ( &prli.param, param, sizeof ( prli.param ) );
985
986 /* Transmit frame */
987 if ( ( rc = fc_els_tx ( els, &prli, sizeof ( prli ) ) ) != 0 )
988 goto err_tx;
989
990 /* Drop temporary reference to ULP */
991 fc_ulp_put ( ulp );
992
993 return 0;
994
995 err_tx:
996 fc_ulp_put ( ulp );
997 err_get_port_id_type:
998 return rc;
999}
unsigned char uint8_t
Definition stdint.h:10
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.
Definition fc.c:1916
static void fc_ulp_put(struct fc_ulp *ulp)
Drop reference to Fibre Channel upper-layer protocol.
Definition fc.h:486
@ FC_ELS_PRLI
Process Login.
Definition fcels.h:39
#define FC_PRLI_RESPONSE_SUCCESS
Request was executed successfully.
Definition fcels.h:271
#define FC_PRLI_ESTABLISH
Establish image pair.
Definition fcels.h:265
#define __attribute__(x)
Definition compiler.h:10
struct hv_monitor_parameter param[4][32]
Parameters.
Definition hyperv.h:13
size_t param_len
Service parameter length.
Definition fcels.h:391
A Fibre Channel PRLI frame.
Definition fcels.h:274
A Fibre Channel upper-layer protocol.
Definition fc.h:414
struct interface prli
PRLI interface.
Definition fc.h:430
struct fc_link_state link
Link state monitor.
Definition fc.h:428

References __attribute__, ENOMEM, fc_els_is_request(), FC_ELS_PRLI, fc_els_tx(), fc_els_tx_command(), fc_link_ok(), FC_PRLI_ESTABLISH, FC_PRLI_RESPONSE_SUCCESS, fc_ulp_get_port_id_type(), fc_ulp_put(), frame, htons, fc_ulp::link, memcpy(), memset(), param, fc_els_prli_descriptor::param_len, fc_els::peer_port_id, fc_els::port, fc_ulp::prli, rc, and fc_els_prli_descriptor::type.

Referenced by fcp_prli_tx().

◆ fc_els_prli_rx()

int fc_els_prli_rx ( struct fc_els * els,
struct fc_els_prli_descriptor * descriptor,
void * data,
size_t len )

Receive PRLI.

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

Definition at line 1010 of file fcels.c.

1012 {
1013 struct {
1014 struct fc_prli_frame frame;
1015 uint8_t param[descriptor->param_len];
1016 } __attribute__ (( packed )) *prli;
1017 struct fc_ulp *ulp;
1018 int rc;
1019
1020 /* Sanity check */
1021 if ( len < sizeof ( *prli ) ) {
1022 DBGC ( els, FCELS_FMT " received underlength frame:\n",
1023 FCELS_ARGS ( els ) );
1024 DBGC_HDA ( els, 0, data, len );
1025 rc = -EINVAL;
1026 goto err_sanity;
1027 }
1028 prli = data;
1029
1030 DBGC ( els, FCELS_FMT " has parameters:\n", FCELS_ARGS ( els ) );
1031 DBGC_HDA ( els, 0, prli->param, sizeof ( prli->param ) );
1032
1033 /* Get ULP */
1034 ulp = fc_ulp_get_port_id_type ( els->port, &els->peer_port_id,
1035 descriptor->type );
1036 if ( ! ulp ) {
1037 rc = -ENOMEM;
1038 goto err_get_port_id_type;
1039 }
1040
1041 /* Sanity check */
1042 if ( ! fc_link_ok ( &ulp->peer->link ) ) {
1043 DBGC ( els, FCELS_FMT " received while peer link is down\n",
1044 FCELS_ARGS ( els ) );
1045 rc = -EINVAL;
1046 goto err_link;
1047 }
1048
1049 /* Log in ULP, if applicable */
1050 if ( prli->frame.page.flags & htons ( FC_PRLI_ESTABLISH ) ) {
1051 if ( ( rc = fc_ulp_login ( ulp, prli->param,
1052 sizeof ( prli->param ),
1053 fc_els_is_request ( els ) ) ) != 0 ){
1054 DBGC ( els, FCELS_FMT " could not log in ULP: %s\n",
1055 FCELS_ARGS ( els ), strerror ( rc ) );
1056 goto err_login;
1057 }
1058 } else {
1059 if ( fc_els_is_request ( els ) ) {
1060 fc_ulp_logout ( ulp, -EACCES );
1061 } else {
1062 /* This is just an information-gathering PRLI; do not
1063 * log in or out
1064 */
1065 }
1066 }
1067
1068 /* Transmit response, if applicable */
1069 if ( ! fc_els_is_request ( els ) ) {
1070 if ( ( rc = els->handler->tx ( els ) ) != 0 )
1071 goto err_tx;
1072 }
1073
1074 /* Drop temporary reference to ULP */
1075 fc_ulp_put ( ulp );
1076
1077 return 0;
1078
1079 err_tx:
1080 err_login:
1081 err_link:
1082 fc_ulp_put ( ulp );
1083 err_get_port_id_type:
1084 err_sanity:
1085 return rc;
1086}
void fc_ulp_logout(struct fc_ulp *ulp, int rc)
Log out Fibre Channel upper-layer protocol.
Definition fc.c:1728
int fc_ulp_login(struct fc_ulp *ulp, const void *param, size_t param_len, int originated)
Log in Fibre Channel upper-layer protocol.
Definition fc.c:1658
struct fc_link_state link
Link state monitor.
Definition fc.h:351
struct fc_peer * peer
Fibre Channel peer.
Definition fc.h:418

References __attribute__, data, DBGC, DBGC_HDA, EACCES, EINVAL, ENOMEM, fc_els_is_request(), fc_link_ok(), FC_PRLI_ESTABLISH, fc_ulp_get_port_id_type(), fc_ulp_login(), fc_ulp_logout(), fc_ulp_put(), FCELS_ARGS, FCELS_FMT, frame, fc_els::handler, htons, len, fc_peer::link, param, fc_els_prli_descriptor::param_len, fc_ulp::peer, fc_els::peer_port_id, fc_els::port, fc_ulp::prli, rc, strerror(), fc_els_handler::tx, and fc_els_prli_descriptor::type.

Referenced by fcp_prli_rx().

◆ fc_els_prli_detect()

int fc_els_prli_detect ( struct fc_els *els __unused,
struct fc_els_prli_descriptor * descriptor,
const void * data,
size_t len )

Detect PRLI.

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

Definition at line 1097 of file fcels.c.

1099 {
1100 const struct {
1101 struct fc_prli_frame frame;
1102 uint8_t param[descriptor->param_len];
1103 } __attribute__ (( packed )) *prli;
1104
1105 /* Check for sufficient length to contain service parameter page */
1106 if ( len < sizeof ( *prli ) )
1107 return -EINVAL;
1108 prli = data;
1109
1110 /* Check for PRLI */
1111 if ( prli->frame.command != FC_ELS_PRLI )
1112 return -EINVAL;
1113
1114 /* Check for upper-layer protocol type */
1115 if ( prli->frame.page.type != descriptor->type )
1116 return -EINVAL;
1117
1118 return 0;
1119}

References __attribute__, __unused, data, EINVAL, FC_ELS_PRLI, frame, len, param, fc_els_prli_descriptor::param_len, and fc_els_prli_descriptor::type.

Referenced by fcp_prli_detect().

◆ fc_els_prli()

int fc_els_prli ( struct interface * parent,
struct fc_port * port,
struct fc_port_id * peer_port_id,
unsigned int type )

Create PRLI request.

Parameters
parentParent interface
portFibre Channel port
peer_port_idPeer port ID
typeUpper-layer protocol type
Return values
rcReturn status code

Definition at line 1130 of file fcels.c.

1131 {
1132 struct fc_els_prli_descriptor *descriptor;
1133
1134 /* Find a PRLI descriptor */
1135 descriptor = fc_els_prli_descriptor ( type );
1136 if ( ! descriptor )
1137 return -ENOTSUP;
1138
1139 return fc_els_request ( parent, port, peer_port_id,
1140 descriptor->handler );
1141}
static struct fc_els_prli_descriptor * fc_els_prli_descriptor(unsigned int type)
Find PRLI descriptor.
Definition fcels.c:936
struct fc_els_handler * handler
Fibre Channel ELS handler.
Definition fcels.h:393

References ENOTSUP, fc_els_prli_descriptor(), fc_els_request(), fc_els_prli_descriptor::handler, port, and type.

Referenced by fc_ulp_examine().

◆ fc_els_rtv_tx_response()

int fc_els_rtv_tx_response ( struct fc_els * els)
static

Transmit RTV response.

Parameters
elsFibre Channel ELS transaction
Return values
rcReturn status code

Definition at line 1156 of file fcels.c.

1156 {
1157 struct fc_rtv_response_frame rtv;
1158
1159 /* Construct RTV */
1160 memset ( &rtv, 0, sizeof ( rtv ) );
1161 rtv.command = FC_ELS_LS_ACC;
1162 rtv.e_d_tov = htonl ( FC_LOGIN_DEFAULT_E_D_TOV );
1163
1164 /* Transmit RTV */
1165 return fc_els_tx ( els, &rtv, sizeof ( rtv ) );
1166}
A Fibre Channel RTV response frame.
Definition fcels.h:294

References fc_rtv_response_frame::command, fc_rtv_response_frame::e_d_tov, FC_ELS_LS_ACC, fc_els_tx(), FC_LOGIN_DEFAULT_E_D_TOV, htonl, and memset().

Referenced by fc_els_rtv_rx().

◆ fc_els_rtv_rx()

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

Receive RTV.

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

Definition at line 1176 of file fcels.c.

1177 {
1178 int rc;
1179
1180 DBGC ( els, FCELS_FMT "\n", FCELS_ARGS ( els ) );
1181
1182 /* Transmit response */
1183 if ( ! fc_els_is_request ( els ) ) {
1184 if ( ( rc = fc_els_rtv_tx_response ( els ) ) != 0 )
1185 return rc;
1186 }
1187
1188 return 0;
1189}
static int fc_els_rtv_tx_response(struct fc_els *els)
Transmit RTV response.
Definition fcels.c:1156

References __unused, data, DBGC, fc_els_is_request(), fc_els_rtv_tx_response(), FCELS_ARGS, FCELS_FMT, len, and rc.

◆ fc_els_rtv_detect()

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

Detect RTV.

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

Definition at line 1199 of file fcels.c.

1200 {
1201 const struct fc_rtv_request_frame *rtv = data;
1202
1203 /* Check for RTV */
1204 if ( rtv->command != FC_ELS_RTV )
1205 return -EINVAL;
1206
1207 return 0;
1208}
@ FC_ELS_RTV
Read Timeout Value.
Definition fcels.h:37
A Fibre Channel RTV request frame.
Definition fcels.h:286
uint8_t command
ELS command code.
Definition fcels.h:288

References __unused, fc_rtv_request_frame::command, data, EINVAL, FC_ELS_RTV, and len.

◆ fc_els_echo_tx()

int fc_els_echo_tx ( struct fc_els * els)
static

Transmit ECHO.

Parameters
elsFibre Channel ELS transaction
Return values
rcReturn status code

Definition at line 1242 of file fcels.c.

1242 {
1244
1245 /* Construct ECHO */
1246 memset ( &echo, 0, sizeof ( echo ) );
1247 echo.echo.command = FC_ELS_ECHO;
1248 echo.magic = htonl ( FC_ECHO_MAGIC );
1249
1250 /* Transmit ECHO */
1251 return fc_els_tx ( els, &echo, sizeof ( echo ) );
1252}
#define FC_ECHO_MAGIC
ECHO magic marker.
Definition fcels.c:1234
@ FC_ELS_ECHO
Echo.
Definition fcels.h:38
int echo(void)
Definition kb.c:133
ECHO request data.
Definition fcels.c:1226

References echo(), FC_ECHO_MAGIC, FC_ELS_ECHO, fc_els_tx(), htonl, and memset().

◆ fc_els_echo_rx_request()

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

Receive ECHO request.

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

Definition at line 1262 of file fcels.c.

1263 {
1264 struct {
1266 char payload[ len - sizeof ( struct fc_echo_frame_header ) ];
1267 } *echo = data;
1268 int rc;
1269
1270 DBGC ( els, FCELS_FMT "\n", FCELS_ARGS ( els ) );
1271
1272 /* Transmit response */
1273 echo->echo.command = FC_ELS_LS_ACC;
1274 if ( ( rc = fc_els_tx ( els, echo, sizeof ( *echo ) ) ) != 0 )
1275 return rc;
1276
1277 /* Nothing to do */
1278 return 0;
1279}
A Fibre Channel ECHO frame.
Definition fcels.h:316

References data, DBGC, echo(), FC_ELS_LS_ACC, fc_els_tx(), FCELS_ARGS, FCELS_FMT, len, and rc.

Referenced by fc_els_echo_rx().

◆ fc_els_echo_rx_response()

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

Receive ECHO response.

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

Definition at line 1289 of file fcels.c.

1290 {
1292
1293 DBGC ( els, FCELS_FMT "\n", FCELS_ARGS ( els ) );
1294
1295 /* Sanity check */
1296 if ( len != sizeof ( *echo ) ) {
1297 DBGC ( els, FCELS_FMT " received underlength echo response\n",
1298 FCELS_ARGS ( els ) );
1299 DBGC_HDA ( els, 0, data, len );
1300 return -EIO;
1301 }
1302 echo = data;
1303
1304 /* Check response is correct */
1305 if ( echo->magic != htonl ( FC_ECHO_MAGIC ) ) {
1306 DBGC ( els, FCELS_FMT " received bad echo response\n",
1307 FCELS_ARGS ( els ) );
1308 DBGC_HDA ( els, 0, data, len );
1309 return -EIO;
1310 }
1311
1312 return 0;
1313}
#define EIO
Input/output error.
Definition errno.h:477

References data, DBGC, DBGC_HDA, echo(), EIO, FC_ECHO_MAGIC, FCELS_ARGS, FCELS_FMT, htonl, and len.

Referenced by fc_els_echo_rx().

◆ fc_els_echo_rx()

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

Receive ECHO.

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

Definition at line 1323 of file fcels.c.

1323 {
1324
1325 if ( fc_els_is_request ( els ) ) {
1326 return fc_els_echo_rx_response ( els, data, len );
1327 } else {
1328 return fc_els_echo_rx_request ( els, data, len );
1329 }
1330}
static int fc_els_echo_rx_response(struct fc_els *els, void *data, size_t len)
Receive ECHO response.
Definition fcels.c:1289
static int fc_els_echo_rx_request(struct fc_els *els, void *data, size_t len)
Receive ECHO request.
Definition fcels.c:1262

References data, fc_els_echo_rx_request(), fc_els_echo_rx_response(), fc_els_is_request(), and len.

◆ fc_els_echo_detect()

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

Detect ECHO.

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

Definition at line 1340 of file fcels.c.

1341 {
1342 const struct fc_echo_frame_header *echo = data;
1343
1344 /* Check for ECHO */
1345 if ( echo->command != FC_ELS_ECHO )
1346 return -EINVAL;
1347
1348 return 0;
1349}

References __unused, data, echo(), EINVAL, FC_ELS_ECHO, and len.

Variable Documentation

◆ __fc_els_handler

struct fc_els_handler fc_els_echo_handler __fc_els_handler
Initial value:
= {
.name = "UNKNOWN",
}
static int fc_els_unknown_rx(struct fc_els *els, void *data, size_t len)
Receive unknown ELS.
Definition fcels.c:417
static int fc_els_unknown_tx(struct fc_els *els __unused)
Transmit unknown ELS request.
Definition fcels.c:387
static int fc_els_unknown_detect(struct fc_els *els __unused, const void *data __unused, size_t len __unused)
Detect unknown ELS.
Definition fcels.c:440

Unknown ELS handler.

ECHO ELS handler.

RTV ELS handler.

LOGO ELS handler.

PLOGI ELS handler.

FLOGI ELS handler.

Definition at line 55 of file fcels.c.

◆ fc_els_xchg_op

struct interface_operation fc_els_xchg_op[]
static
Initial value:
= {
}
static int fc_els_rx(struct fc_els *els, struct io_buffer *iobuf, struct xfer_metadata *meta)
Receive Fibre Channel ELS frame.
Definition fcels.c:159
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
int xfer_deliver(struct interface *intf, struct io_buffer *iobuf, struct xfer_metadata *meta)
Deliver datagram.
Definition xfer.c:195

Fibre Channel ELS exchange interface operations.

Definition at line 232 of file fcels.c.

232 {
233 INTF_OP ( xfer_deliver, struct fc_els *, fc_els_rx ),
234 INTF_OP ( intf_close, struct fc_els *, fc_els_close ),
235};

◆ fc_els_xchg_desc

struct interface_descriptor fc_els_xchg_desc
static
Initial value:
=
INTF_DESC ( struct fc_els, xchg, fc_els_xchg_op )
static struct interface_operation fc_els_xchg_op[]
Fibre Channel ELS exchange interface operations.
Definition fcels.c:232
#define INTF_DESC(object_type, intf, operations)
Define an object interface descriptor.
Definition interface.h:81

Fibre Channel ELS exchange interface descriptor.

Definition at line 238 of file fcels.c.

Referenced by fc_els_create().

◆ fc_els_job_op

struct interface_operation fc_els_job_op[]
static
Initial value:
= {
}

Fibre Channel ELS job control interface operations.

Definition at line 242 of file fcels.c.

242 {
243 INTF_OP ( intf_close, struct fc_els *, fc_els_close ),
244};

◆ fc_els_job_desc

struct interface_descriptor fc_els_job_desc
static
Initial value:
=
INTF_DESC ( struct fc_els, job, fc_els_job_op )
static struct interface_operation fc_els_job_op[]
Fibre Channel ELS job control interface operations.
Definition fcels.c:242

Fibre Channel ELS job control interface descriptor.

Definition at line 247 of file fcels.c.

Referenced by fc_els_create().

◆ fc_els_process_desc

struct process_descriptor fc_els_process_desc
static
Initial value:
=
static void fc_els_step(struct fc_els *els)
Fibre Channel ELS process.
Definition fcels.c:255
#define PROC_DESC_ONCE(object_type, process, _step)
Define a process descriptor for a process that runs only once.
Definition process.h:98
A process.
Definition process.h:18

Fibre Channel ELS process descriptor.

Definition at line 283 of file fcels.c.

Referenced by fc_els_create().

◆ __fc_responder

struct fc_responder fc_els_responder __fc_responder
Initial value:
= {
.type = FC_TYPE_ELS,
.respond = fc_els_respond,
}
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.
Definition fcels.c:352

Fibre Channel ELS responder.

Definition at line 369 of file fcels.c.

369 {
370 .type = FC_TYPE_ELS,
371 .respond = fc_els_respond,
372};