iPXE
fc.c File Reference

Fibre Channel. More...

#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <assert.h>
#include <byteswap.h>
#include <ipxe/refcnt.h>
#include <ipxe/list.h>
#include <ipxe/tables.h>
#include <ipxe/timer.h>
#include <ipxe/retry.h>
#include <ipxe/interface.h>
#include <ipxe/xfer.h>
#include <ipxe/iobuf.h>
#include <ipxe/fc.h>
#include <ipxe/fcels.h>
#include <ipxe/fcns.h>

Go to the source code of this file.

Data Structures

struct  fc_exchange
 A Fibre Channel exchange. More...

Macros

#define EUNKNOWN_LINK_STATUS   __einfo_error ( EINFO_EUNKNOWN_LINK_STATUS )
 Default link status code.
#define EINFO_EUNKNOWN_LINK_STATUS   __einfo_uniqify ( EINFO_EINPROGRESS, 0x01, "Unknown" )
#define FC_TIMEOUT   ( 1 * TICKS_PER_SEC )
 Fibre Channel timeout.

Enumerations

enum  fc_exchange_flags { FC_XCHG_ORIGINATOR = 0x0001 , FC_XCHG_SEQ_INITIATIVE = 0x0002 , FC_XCHG_SEQ_FIRST = 0x0004 }
 Fibre Channel exchange flags. More...

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 LIST_HEAD (fc_ports)
 List of Fibre Channel ports.
 LIST_HEAD (fc_peers)
 List of Fibre Channel peers.
const char * fc_id_ntoa (const struct fc_port_id *id)
 Format Fibre Channel port ID.
int fc_id_aton (const char *id_text, struct fc_port_id *id)
 Parse Fibre Channel port ID.
const char * fc_ntoa (const struct fc_name *wwn)
 Format Fibre Channel WWN.
int fc_aton (const char *wwn_text, struct fc_name *wwn)
 Parse Fibre Channel WWN.
struct sockaddrfc_fill_sockaddr (struct sockaddr_fc *sa_fc, struct fc_port_id *id)
 Fill Fibre Channel socket address.
static void fc_link_up (struct fc_link_state *link)
 Mark Fibre Channel link as up.
static void fc_link_err (struct fc_link_state *link, int rc)
 Mark Fibre Channel link as down.
static void fc_link_examine (struct fc_link_state *link)
 Examine Fibre Channel link state.
static void fc_link_expired (struct retry_timer *timer, int over __unused)
 Handle Fibre Channel link retry timer expiry.
static void fc_link_init (struct fc_link_state *link, void(*examine)(struct fc_link_state *link), struct refcnt *refcnt)
 Initialise Fibre Channel link state monitor.
static void fc_link_start (struct fc_link_state *link)
 Start monitoring Fibre Channel link state.
static void fc_link_stop (struct fc_link_state *link)
 Stop monitoring Fibre Channel link state.
static unsigned int fc_new_xchg_id (void)
 Create local Fibre Channel exchange identifier.
static unsigned int fc_new_seq_id (void)
 Create local Fibre Channel sequence identifier.
static void fc_xchg_free (struct refcnt *refcnt)
 Free Fibre Channel exchange.
static void fc_xchg_close (struct fc_exchange *xchg, int rc)
 Close Fibre Channel exchange.
static void fc_xchg_expired (struct retry_timer *timer, int over __unused)
 Handle exchange timeout.
static size_t fc_xchg_window (struct fc_exchange *xchg __unused)
 Check Fibre Channel exchange window.
static struct io_bufferfc_xchg_alloc_iob (struct fc_exchange *xchg, size_t len)
 Allocate Fibre Channel I/O buffer.
static int fc_xchg_tx (struct fc_exchange *xchg, struct io_buffer *iobuf, struct xfer_metadata *meta)
 Transmit data as part of a Fibre Channel exchange.
static int fc_xchg_rx (struct fc_exchange *xchg, struct io_buffer *iobuf, struct xfer_metadata *meta __unused)
 Receive data as part of a Fibre Channel exchange.
static struct fc_exchangefc_xchg_create (struct fc_port *port, struct fc_port_id *peer_port_id, unsigned int type)
 Create new Fibre Channel exchange.
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 struct fc_exchangefc_xchg_respond (struct fc_port *port, struct fc_frame_header *fchdr)
 Open a new responder Fibre Channel exchange.
static void fc_port_close (struct fc_port *port, int rc)
 Close Fibre Channel port.
static struct fc_exchangefc_port_demux (struct fc_port *port, unsigned int xchg_id)
 Identify Fibre Channel exchange by local exchange ID.
static int fc_port_deliver (struct fc_port *port, struct io_buffer *iobuf, struct xfer_metadata *meta)
 Handle received frame from Fibre Channel port.
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.
void fc_port_logout (struct fc_port *port, int rc)
 Log out Fibre Channel port.
static void fc_port_flogi_done (struct fc_port *port, int rc)
 Handle FLOGI completion.
static void fc_port_ns_plogi_done (struct fc_port *port, int rc)
 Handle name server PLOGI completion.
static void fc_port_examine (struct fc_link_state *link)
 Examine Fibre Channel port link state.
static void fc_port_window_changed (struct fc_port *port)
 Handle change of flow control window.
int fc_port_open (struct interface *transport, const struct fc_name *node_wwn, const struct fc_name *port_wwn, const char *name)
 Create Fibre Channel port.
struct fc_portfc_port_find (const char *name)
 Find Fibre Channel port by name.
static void fc_peer_close (struct fc_peer *peer, int rc)
 Close Fibre Channel peer.
static void fc_peer_increment (struct fc_peer *peer)
 Increment Fibre Channel peer active usage count.
static void fc_peer_decrement (struct fc_peer *peer)
 Decrement Fibre Channel peer active usage count.
int fc_peer_login (struct fc_peer *peer, struct fc_port *port, struct fc_port_id *port_id)
 Log in Fibre Channel peer.
void fc_peer_logout (struct fc_peer *peer, int rc)
 Log out Fibre Channel peer.
static void fc_peer_plogi_done (struct fc_peer *peer, int rc)
 Handle PLOGI completion.
static int fc_peer_plogi (struct fc_peer *peer, struct fc_port *port, struct fc_port_id *peer_port_id)
 Initiate PLOGI.
static void fc_peer_examine (struct fc_link_state *link)
 Examine Fibre Channel peer link state.
static struct fc_peerfc_peer_create (const struct fc_name *port_wwn)
 Create Fibre Channel peer.
struct fc_peerfc_peer_get_wwn (const struct fc_name *port_wwn)
 Get Fibre Channel peer by node name.
struct fc_peerfc_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 fc_ulp_free (struct refcnt *refcnt)
 Free Fibre Channel upper-layer protocol.
static void fc_ulp_close (struct fc_ulp *ulp, int rc)
 Close Fibre Channel upper-layer protocol.
void fc_ulp_attach (struct fc_ulp *ulp, struct fc_ulp_user *user)
 Attach Fibre Channel upper-layer protocol user.
void fc_ulp_detach (struct fc_ulp_user *user)
 Detach Fibre Channel upper-layer protocol user.
int fc_ulp_login (struct fc_ulp *ulp, const void *param, size_t param_len, int originated)
 Log in Fibre Channel upper-layer protocol.
void fc_ulp_logout (struct fc_ulp *ulp, int rc)
 Log out Fibre Channel upper-layer protocol.
static void fc_ulp_prli_done (struct fc_ulp *ulp, int rc)
 Handle PRLI completion.
static void fc_ulp_examine (struct fc_link_state *link)
 Examine Fibre Channel upper-layer protocol link state.
static struct fc_ulpfc_ulp_create (struct fc_peer *peer, unsigned int type)
 Create Fibre Channel upper-layer protocl.
static struct fc_ulpfc_ulp_get_type (struct fc_peer *peer, unsigned int type)
 Get Fibre Channel upper-layer protocol by peer and type.
struct fc_ulpfc_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 fc_ulpfc_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.
 REQUIRING_SYMBOL (fc_ports)
 REQUIRE_OBJECT (config_fc)

Variables

struct fc_port_id fc_empty_port_id = { .bytes = { 0x00, 0x00, 0x00 } }
 Unassigned port ID.
struct fc_port_id fc_f_port_id = { .bytes = { 0xff, 0xff, 0xfe } }
 F_Port contoller port ID.
struct fc_port_id fc_gs_port_id = { .bytes = { 0xff, 0xff, 0xfc } }
 Generic services port ID.
struct fc_port_id fc_ptp_low_port_id = { .bytes = { 0x01, 0x01, 0x01 } }
 Point-to-point low port ID.
struct fc_port_id fc_ptp_high_port_id = { .bytes = { 0x01, 0x01, 0x02 } }
 Point-to-point high port ID.
static const uint8_t fc_r_ctl_info_meta_flags [FC_R_CTL_INFO_MASK+1]
 Mapping from Fibre Channel routing control information to xfer metadata.
static struct interface_operation fc_xchg_ulp_op []
 Fibre Channel exchange ULP interface operations.
static struct interface_descriptor fc_xchg_ulp_desc
 Fibre Channel exchange ULP interface descriptor.
static struct interface_operation fc_port_transport_op []
 Fibre Channel port transport interface operations.
static struct interface_descriptor fc_port_transport_desc
 Fibre Channel port transport interface descriptor.
static struct interface_operation fc_port_flogi_op []
 Fibre Channel port FLOGI interface operations.
static struct interface_descriptor fc_port_flogi_desc
 Fibre Channel port FLOGI interface descriptor.
static struct interface_operation fc_port_ns_plogi_op []
 Fibre Channel port name server PLOGI interface operations.
static struct interface_descriptor fc_port_ns_plogi_desc
 Fibre Channel port name server PLOGI interface descriptor.
static struct interface_operation fc_peer_plogi_op []
 Fibre Channel peer PLOGI interface operations.
static struct interface_descriptor fc_peer_plogi_desc
 Fibre Channel peer PLOGI interface descriptor.
static struct interface_operation fc_ulp_prli_op []
 Fibre Channel upper-layer protocol PRLI interface operations.
static struct interface_descriptor fc_ulp_prli_desc
 Fibre Channel upper-layer protocol PRLI interface descriptor.

Detailed Description

Fibre Channel.

Definition in file fc.c.

Macro Definition Documentation

◆ EUNKNOWN_LINK_STATUS

#define EUNKNOWN_LINK_STATUS   __einfo_error ( EINFO_EUNKNOWN_LINK_STATUS )

Default link status code.

Definition at line 186 of file fc.c.

Referenced by alloc_netdev(), fc_link_err(), fc_link_init(), and netdev_link_down().

◆ EINFO_EUNKNOWN_LINK_STATUS

#define EINFO_EUNKNOWN_LINK_STATUS   __einfo_uniqify ( EINFO_EINPROGRESS, 0x01, "Unknown" )

Definition at line 187 of file fc.c.

187#define EINFO_EUNKNOWN_LINK_STATUS \
188 __einfo_uniqify ( EINFO_EINPROGRESS, 0x01, "Unknown" )

◆ FC_TIMEOUT

#define FC_TIMEOUT   ( 1 * TICKS_PER_SEC )

Fibre Channel timeout.

Definition at line 328 of file fc.c.

Referenced by fc_xchg_rx(), and fc_xchg_tx().

Enumeration Type Documentation

◆ fc_exchange_flags

Fibre Channel exchange flags.

Enumerator
FC_XCHG_ORIGINATOR 

We are the exchange originator.

FC_XCHG_SEQ_INITIATIVE 

We have the sequence initiative.

FC_XCHG_SEQ_FIRST 

This is the first sequence of the exchange.

Definition at line 318 of file fc.c.

318 {
319 /** We are the exchange originator */
320 FC_XCHG_ORIGINATOR = 0x0001,
321 /** We have the sequence initiative */
322 FC_XCHG_SEQ_INITIATIVE = 0x0002,
323 /** This is the first sequence of the exchange */
324 FC_XCHG_SEQ_FIRST = 0x0004,
325};
@ FC_XCHG_ORIGINATOR
We are the exchange originator.
Definition fc.c:320
@ FC_XCHG_SEQ_FIRST
This is the first sequence of the exchange.
Definition fc.c:324
@ FC_XCHG_SEQ_INITIATIVE
We have the sequence initiative.
Definition fc.c:322

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )

◆ LIST_HEAD() [1/2]

LIST_HEAD ( fc_ports )

List of Fibre Channel ports.

References fc_ports.

◆ LIST_HEAD() [2/2]

LIST_HEAD ( fc_peers )

List of Fibre Channel peers.

References fc_peers.

◆ fc_id_ntoa()

const char * fc_id_ntoa ( const struct fc_port_id * id)

Format Fibre Channel port ID.

Parameters
idFibre Channel port ID
Return values
id_textPort ID text

Definition at line 92 of file fc.c.

92 {
93 static char id_text[ FC_PORT_ID_STRLEN + 1 /* NUL */ ];
94
95 snprintf ( id_text, sizeof ( id_text ), "%02x.%02x.%02x",
96 id->bytes[0], id->bytes[1], id->bytes[2] );
97 return id_text;
98}
uint8_t id
Request identifier.
Definition ena.h:1
#define FC_PORT_ID_STRLEN
Length of Fibre Channel port identifier next.
Definition fc.h:43
int snprintf(char *buf, size_t size, const char *fmt,...)
Write a formatted string to a buffer.
Definition vsprintf.c:383

References FC_PORT_ID_STRLEN, id, and snprintf().

Referenced by fc_els_flogi_rx(), fc_els_logo_rx_request(), fc_els_plogi_rx(), fc_ns_query_deliver(), fc_peer_login(), fc_port_deliver(), fc_port_login(), fc_xchg_originate(), fc_xchg_respond(), fcels(), fcpeerstat(), and fcportstat().

◆ fc_id_aton()

int fc_id_aton ( const char * id_text,
struct fc_port_id * id )

Parse Fibre Channel port ID.

Parameters
id_textPort ID text
Return values
idFibre Channel port ID
rcReturn status code

Definition at line 107 of file fc.c.

107 {
108 char *ptr = ( ( char * ) id_text );
109 unsigned int i = 0;
110
111 while ( 1 ) {
112 id->bytes[i++] = strtoul ( ptr, &ptr, 16 );
113 if ( i == sizeof ( id->bytes ) )
114 return ( ( *ptr == '\0' ) ? 0 : -EINVAL );
115 if ( *ptr != '.' )
116 return -EINVAL;
117 ptr++;
118 }
119}
#define EINVAL
Invalid argument.
Definition errno.h:472
unsigned long strtoul(const char *string, char **endp, int base)
Convert string to numeric value.
Definition string.c:516

References EINVAL, id, and strtoul().

Referenced by parse_fc_port_id().

◆ fc_ntoa()

const char * fc_ntoa ( const struct fc_name * wwn)

Format Fibre Channel WWN.

Parameters
wwnFibre Channel WWN
Return values
wwn_textWWN text

Definition at line 127 of file fc.c.

127 {
128 static char wwn_text[ FC_NAME_STRLEN + 1 /* NUL */ ];
129
130 snprintf ( wwn_text, sizeof ( wwn_text ),
131 "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
132 wwn->bytes[0], wwn->bytes[1], wwn->bytes[2], wwn->bytes[3],
133 wwn->bytes[4], wwn->bytes[5], wwn->bytes[6], wwn->bytes[7] );
134 return wwn_text;
135}
uint64_t wwn
WWN.
Definition edd.h:1
#define FC_NAME_STRLEN
Length of Fibre Channel name text.
Definition fc.h:35

References FC_NAME_STRLEN, snprintf(), and wwn.

Referenced by fc_els_flogi_rx(), fc_els_logo_rx_request(), fc_els_plogi_rx(), fc_ns_query(), fc_ns_query_deliver(), fc_peer_close(), fc_peer_create(), fc_peer_examine(), fc_peer_login(), fc_peer_logout(), fc_peer_plogi(), fc_port_login(), fc_port_open(), fc_ulp_close(), fc_ulp_create(), fc_ulp_examine(), fc_ulp_login(), fc_ulp_logout(), fcoe_probe(), fcpdev_open(), fcpeerstat(), and fcportstat().

◆ fc_aton()

int fc_aton ( const char * wwn_text,
struct fc_name * wwn )

Parse Fibre Channel WWN.

Parameters
wwn_textWWN text
Return values
wwnFibre Channel WWN
rcReturn status code

Definition at line 144 of file fc.c.

144 {
145 char *ptr = ( ( char * ) wwn_text );
146 unsigned int i = 0;
147
148 while ( 1 ) {
149 wwn->bytes[i++] = strtoul ( ptr, &ptr, 16 );
150 if ( i == sizeof ( wwn->bytes ) )
151 return ( ( *ptr == '\0' ) ? 0 : -EINVAL );
152 if ( *ptr != ':' )
153 return -EINVAL;
154 ptr++;
155 }
156}

References EINVAL, strtoul(), and wwn.

Referenced by fcp_parse_uri().

◆ fc_fill_sockaddr()

struct sockaddr * fc_fill_sockaddr ( struct sockaddr_fc * sa_fc,
struct fc_port_id * id )

Fill Fibre Channel socket address.

Parameters
sa_fcFibre Channel socket address to fill in
idFibre Channel port ID
Return values
saSocket address

Definition at line 165 of file fc.c.

166 {
167 union {
168 struct sockaddr sa;
169 struct sockaddr_fc fc;
170 } *u = container_of ( sa_fc, typeof ( *u ), fc );
171
172 memset ( sa_fc, 0, sizeof ( *sa_fc ) );
173 sa_fc->sfc_family = AF_FC;
174 memcpy ( &sa_fc->sfc_port_id, id, sizeof ( sa_fc->sfc_port_id ) );
175 return &u->sa;
176}
typeof(acpi_finder=acpi_find)
ACPI table finder.
Definition acpi.c:48
union @104331263140136355135267063077374276003064103115 u
#define AF_FC
Fibre Channel addresses.
Definition socket.h:66
u16 fc
802.11 Frame Control field
Definition ieee80211.h:0
void * memcpy(void *dest, const void *src, size_t len) __nonnull
void * memset(void *dest, int character, size_t len) __nonnull
#define container_of(ptr, type, field)
Get containing structure.
Definition stddef.h:36
Fibre Channel socket address.
Definition fc.h:48
sa_family_t sfc_family
Socket address family (part of struct sockaddr).
Definition fc.h:53
struct fc_port_id sfc_port_id
Port ID.
Definition fc.h:55
Generalized socket address structure.
Definition socket.h:97
struct sockaddr sa
Definition syslog.c:57

References AF_FC, container_of, fc, memcpy(), memset(), sa, sockaddr_fc::sfc_family, sockaddr_fc::sfc_port_id, typeof(), and u.

Referenced by fc_els_tx(), and fc_xchg_rx().

◆ fc_link_up()

void fc_link_up ( struct fc_link_state * link)
static

Mark Fibre Channel link as up.

Parameters
linkFibre Channel link state monitor

Definition at line 195 of file fc.c.

195 {
196
197 /* Stop retry timer */
198 stop_timer ( &link->timer );
199
200 /* Record link state */
201 link->rc = 0;
202}
u32 link
Link to next descriptor.
Definition ar9003_mac.h:1
void stop_timer(struct retry_timer *timer)
Stop timer.
Definition retry.c:118

References link, and stop_timer().

Referenced by fc_peer_login(), fc_port_login(), and fc_ulp_login().

◆ fc_link_err()

void fc_link_err ( struct fc_link_state * link,
int rc )
static

Mark Fibre Channel link as down.

Parameters
linkFibre Channel link state monitor
rcLink state

Definition at line 210 of file fc.c.

210 {
211
212 /* Record link state */
213 if ( rc == 0 )
215 link->rc = rc;
216
217 /* Schedule another link examination */
219}
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
#define EUNKNOWN_LINK_STATUS
Default link status code.
Definition fc.c:186
#define FC_LINK_RETRY_DELAY
Delay between failed link-up attempts.
Definition fc.h:87
void start_timer_fixed(struct retry_timer *timer, unsigned long timeout)
Start timer with a specified timeout.
Definition retry.c:65

References EUNKNOWN_LINK_STATUS, FC_LINK_RETRY_DELAY, link, rc, and start_timer_fixed().

Referenced by fc_peer_logout(), fc_port_logout(), and fc_ulp_logout().

◆ fc_link_examine()

void fc_link_examine ( struct fc_link_state * link)
static

Examine Fibre Channel link state.

Parameters
linkFibre Channel link state monitor

Definition at line 226 of file fc.c.

226 {
227
228 link->examine ( link );
229}

References link.

Referenced by fc_link_expired(), fc_peer_login(), fc_peer_logout(), fc_port_login(), and fc_port_logout().

◆ fc_link_expired()

void fc_link_expired ( struct retry_timer * timer,
int over __unused )
static

Handle Fibre Channel link retry timer expiry.

Definition at line 234 of file fc.c.

234 {
235 struct fc_link_state *link =
237
238 /* Schedule another link examination */
240
241 /* Examine link */
243}
static void fc_link_examine(struct fc_link_state *link)
Examine Fibre Channel link state.
Definition fc.c:226
A timer.
Definition timer.h:29

References __unused, container_of, fc_link_examine(), FC_LINK_RETRY_DELAY, link, and start_timer_fixed().

Referenced by fc_link_init().

◆ fc_link_init()

void fc_link_init ( struct fc_link_state * link,
void(* examine )(struct fc_link_state *link),
struct refcnt * refcnt )
static

Initialise Fibre Channel link state monitor.

Parameters
linkFibre Channel link state monitor
examineExamine link state method
refcntReference counter

Definition at line 252 of file fc.c.

254 {
255
257 timer_init ( &link->timer, fc_link_expired, refcnt );
258 link->examine = examine;
259}
static void fc_link_expired(struct retry_timer *timer, int over __unused)
Handle Fibre Channel link retry timer expiry.
Definition fc.c:234
A reference counter.
Definition refcnt.h:27

References EUNKNOWN_LINK_STATUS, fc_link_state::examine, fc_link_expired(), and link.

Referenced by fc_peer_create(), fc_port_open(), and fc_ulp_create().

◆ fc_link_start()

void fc_link_start ( struct fc_link_state * link)
static

Start monitoring Fibre Channel link state.

Parameters
linkFibre Channel link state monitor

Definition at line 266 of file fc.c.

266 {
267 start_timer_nodelay ( &link->timer );
268}
static void start_timer_nodelay(struct retry_timer *timer)
Start timer with no delay.
Definition retry.h:100

References link, and start_timer_nodelay().

Referenced by fc_peer_create(), fc_port_window_changed(), fc_ulp_create(), and fc_ulp_login().

◆ fc_link_stop()

void fc_link_stop ( struct fc_link_state * link)
static

Stop monitoring Fibre Channel link state.

Parameters
linkFibre Channel link state monitor

Definition at line 275 of file fc.c.

275 {
276 stop_timer ( &link->timer );
277}

References link, and stop_timer().

Referenced by fc_peer_close(), fc_port_close(), fc_port_window_changed(), fc_ulp_close(), and fc_ulp_login().

◆ fc_new_xchg_id()

unsigned int fc_new_xchg_id ( void )
static

Create local Fibre Channel exchange identifier.

Return values
xchg_idLocal exchange ID

Definition at line 335 of file fc.c.

335 {
336 static uint16_t next_id = 0x0000;
337
338 /* We must avoid using FC_RX_ID_UNKNOWN (0xffff) */
339 next_id += 2;
340 return next_id;
341}
unsigned short uint16_t
Definition stdint.h:11

Referenced by fc_xchg_create().

◆ fc_new_seq_id()

unsigned int fc_new_seq_id ( void )
static

Create local Fibre Channel sequence identifier.

Return values
seq_idLocal sequence identifier

Definition at line 348 of file fc.c.

348 {
349 static uint8_t seq_id = 0x00;
350
351 return (++seq_id);
352}
unsigned char uint8_t
Definition stdint.h:10

Referenced by fc_xchg_create(), and fc_xchg_rx().

◆ fc_xchg_free()

void fc_xchg_free ( struct refcnt * refcnt)
static

Free Fibre Channel exchange.

Parameters
refcntReference count

Definition at line 359 of file fc.c.

359 {
360 struct fc_exchange *xchg =
362
363 assert ( ! timer_running ( &xchg->timer ) );
364 assert ( list_empty ( &xchg->list ) );
365
366 fc_port_put ( xchg->port );
367 free ( xchg );
368}
#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
#define list_empty(list)
Test whether a list is empty.
Definition list.h:137
static void(* free)(struct refcnt *refcnt))
Definition refcnt.h:55
A Fibre Channel exchange.
Definition fc.c:287
struct fc_port * port
Fibre Channel port.
Definition fc.c:291
struct retry_timer timer
Timeout timer.
Definition fc.c:311
struct list_head list
List of active exchanges within this port.
Definition fc.c:293

References assert, container_of, fc_port_put(), free, fc_exchange::list, list_empty, fc_exchange::port, and fc_exchange::timer.

Referenced by fc_xchg_create().

◆ fc_xchg_close()

void fc_xchg_close ( struct fc_exchange * xchg,
int rc )
static

Close Fibre Channel exchange.

Parameters
xchgFibre Channel exchange
rcReason for close

Definition at line 376 of file fc.c.

376 {
377 struct fc_port *port = xchg->port;
378
379 if ( rc != 0 ) {
380 DBGC2 ( port, "FCXCHG %s/%04x closed: %s\n",
381 port->name, xchg->xchg_id, strerror ( rc ) );
382 }
383
384 /* Stop timer */
385 stop_timer ( &xchg->timer );
386
387 /* If list still holds a reference, remove from list of open
388 * exchanges and drop list's reference.
389 */
390 if ( ! list_empty ( &xchg->list ) ) {
391 list_del ( &xchg->list );
392 INIT_LIST_HEAD ( &xchg->list );
393 ref_put ( &xchg->refcnt );
394 }
395
396 /* Shutdown interfaces */
397 intf_shutdown ( &xchg->ulp, rc );
398}
u8 port
Port number.
Definition CIB_PRM.h:3
#define DBGC2(...)
Definition compiler.h:547
void intf_shutdown(struct interface *intf, int rc)
Shut down an object interface.
Definition interface.c:279
#define list_del(list)
Delete an entry from a list.
Definition list.h:120
#define INIT_LIST_HEAD(list)
Initialise a list head.
Definition list.h:46
#define ref_put(refcnt)
Drop reference to object.
Definition refcnt.h:107
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79
struct refcnt refcnt
Reference count.
Definition fc.c:289
struct interface ulp
Upper-layer protocol interface.
Definition fc.c:314
uint16_t xchg_id
Local exchange ID.
Definition fc.c:302
A Fibre Channel port.
Definition fc.h:253

References DBGC2, INIT_LIST_HEAD, intf_shutdown(), fc_exchange::list, list_del, list_empty, fc_exchange::port, port, rc, ref_put, fc_exchange::refcnt, stop_timer(), strerror(), fc_exchange::timer, fc_exchange::ulp, and fc_exchange::xchg_id.

Referenced by fc_port_close(), fc_xchg_expired(), and fc_xchg_rx().

◆ fc_xchg_expired()

void fc_xchg_expired ( struct retry_timer * timer,
int over __unused )
static

Handle exchange timeout.

Parameters
timerTimeout timer
overFailure indicator

Definition at line 406 of file fc.c.

406 {
407 struct fc_exchange *xchg =
408 container_of ( timer, struct fc_exchange, timer );
409 struct fc_port *port = xchg->port;
410
411 DBGC ( port, "FCXCHG %s/%04x timed out\n", port->name, xchg->xchg_id );
412
413 /* Terminate the exchange */
414 fc_xchg_close ( xchg, -ETIMEDOUT );
415}
static void fc_xchg_close(struct fc_exchange *xchg, int rc)
Close Fibre Channel exchange.
Definition fc.c:376
#define DBGC(...)
Definition compiler.h:530
#define ETIMEDOUT
Connection timed out.
Definition errno.h:713

References __unused, container_of, DBGC, ETIMEDOUT, fc_xchg_close(), fc_exchange::port, port, and fc_exchange::xchg_id.

Referenced by fc_xchg_create().

◆ fc_xchg_window()

size_t fc_xchg_window ( struct fc_exchange *xchg __unused)
static

Check Fibre Channel exchange window.

Parameters
xchgFibre Channel exchange
Return values
lenLength opf window

Definition at line 423 of file fc.c.

423 {
424
425 /* We don't currently store the path MTU */
427}
#define FC_LOGIN_DEFAULT_MTU
Fibre Channel default MTU.
Definition fcels.h:169

References __unused, and FC_LOGIN_DEFAULT_MTU.

◆ fc_xchg_alloc_iob()

struct io_buffer * fc_xchg_alloc_iob ( struct fc_exchange * xchg,
size_t len )
static

Allocate Fibre Channel I/O buffer.

Parameters
xchgFibre Channel exchange
lenPayload length
Return values
iobufI/O buffer, or NULL

Definition at line 436 of file fc.c.

437 {
438 struct fc_port *port = xchg->port;
439 struct io_buffer *iobuf;
440
441 iobuf = xfer_alloc_iob ( &port->transport,
442 ( sizeof ( struct fc_frame_header ) + len ) );
443 if ( iobuf ) {
444 iob_reserve ( iobuf, sizeof ( struct fc_frame_header ) );
445 }
446 return iobuf;
447}
ring len
Length.
Definition dwmac.h:226
#define iob_reserve(iobuf, len)
Definition iobuf.h:132
A Fibre Channel Frame Header.
Definition fc.h:121
A persistent I/O buffer.
Definition iobuf.h:98
struct io_buffer * xfer_alloc_iob(struct interface *intf, size_t len)
Allocate I/O buffer.
Definition xfer.c:159

References iob_reserve, len, fc_exchange::port, port, and xfer_alloc_iob().

◆ fc_xchg_tx()

int fc_xchg_tx ( struct fc_exchange * xchg,
struct io_buffer * iobuf,
struct xfer_metadata * meta )
static

Transmit data as part of a Fibre Channel exchange.

Parameters
xchgFibre Channel exchange
iobufI/O buffer
metaData transfer metadata
Return values
rcReturn status code

Definition at line 457 of file fc.c.

458 {
459 struct fc_port *port = xchg->port;
460 struct sockaddr_fc *dest = ( ( struct sockaddr_fc * ) meta->dest );
461 struct fc_frame_header *fchdr;
462 unsigned int r_ctl;
463 unsigned int f_ctl_es;
464 int rc;
465
466 /* Sanity checks */
467 if ( ! ( xchg->flags & FC_XCHG_SEQ_INITIATIVE ) ) {
468 DBGC ( port, "FCXCHG %s/%04x cannot transmit while not "
469 "holding sequence initiative\n",
470 port->name, xchg->xchg_id );
471 rc = -EBUSY;
472 goto done;
473 }
474
475 /* Calculate routing control */
476 switch ( xchg->type ) {
477 case FC_TYPE_ELS:
479 if ( meta->flags & XFER_FL_RESPONSE ) {
481 } else {
483 }
484 break;
485 case FC_TYPE_CT:
487 if ( meta->flags & XFER_FL_RESPONSE ) {
489 } else {
491 }
492 break;
493 default:
495 switch ( meta->flags &
499 break;
500 case ( XFER_FL_CMD_STAT ):
502 break;
503 case ( XFER_FL_RESPONSE ):
505 break;
506 default:
508 break;
509 }
510 break;
511 }
512
513 /* Calculate exchange and sequence control */
514 f_ctl_es = 0;
515 if ( ! ( xchg->flags & FC_XCHG_ORIGINATOR ) )
517 if ( xchg->flags & FC_XCHG_SEQ_FIRST )
519 if ( meta->flags & XFER_FL_OUT )
521 if ( meta->flags & XFER_FL_OVER )
523
524 /* Create frame header */
525 fchdr = iob_push ( iobuf, sizeof ( *fchdr ) );
526 memset ( fchdr, 0, sizeof ( *fchdr ) );
527 fchdr->r_ctl = r_ctl;
528 memcpy ( &fchdr->d_id,
529 ( dest ? &dest->sfc_port_id : &xchg->peer_port_id ),
530 sizeof ( fchdr->d_id ) );
531 memcpy ( &fchdr->s_id, &port->port_id, sizeof ( fchdr->s_id ) );
532 fchdr->type = xchg->type;
533 fchdr->f_ctl_es = f_ctl_es;
534 fchdr->seq_id = xchg->seq_id;
535 fchdr->seq_cnt = htons ( xchg->seq_cnt++ );
536 fchdr->ox_id = htons ( ( xchg->flags & FC_XCHG_ORIGINATOR ) ?
537 xchg->xchg_id : xchg->peer_xchg_id );
538 fchdr->rx_id = htons ( ( xchg->flags & FC_XCHG_ORIGINATOR ) ?
539 xchg->peer_xchg_id : xchg->xchg_id );
540 if ( meta->flags & XFER_FL_ABS_OFFSET ) {
542 fchdr->parameter = htonl ( meta->offset );
543 }
544
545 /* Relinquish sequence initiative if applicable */
546 if ( meta->flags & XFER_FL_OVER ) {
548 xchg->seq_cnt = 0;
549 }
550
551 /* Reset timeout */
553
554 /* Deliver frame */
555 if ( ( rc = xfer_deliver_iob ( &port->transport,
556 iob_disown ( iobuf ) ) ) != 0 ) {
557 DBGC ( port, "FCXCHG %s/%04x cannot transmit: %s\n",
558 port->name, xchg->xchg_id, strerror ( rc ) );
559 goto done;
560 }
561
562 done:
563 free_iob ( iobuf );
564 return rc;
565}
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
struct bofm_section_header done
Definition bofm_test.c:46
uint8_t meta
Metadata flags.
Definition ena.h:3
#define FC_TIMEOUT
Fibre Channel timeout.
Definition fc.c:328
@ FC_R_CTL_DATA
Device Data.
Definition fc.h:162
@ FC_R_CTL_ELS
Extended Link Services.
Definition fc.h:163
@ FC_TYPE_CT
Common Transport.
Definition fc.h:195
@ FC_TYPE_ELS
Extended Link Service.
Definition fc.h:193
@ FC_R_CTL_UNSOL_DATA
Unsolicited Data.
Definition fc.h:181
@ FC_R_CTL_UNSOL_CTRL
Unsolicited Control.
Definition fc.h:179
@ FC_R_CTL_UNSOL_CMD
Unsolicited Command.
Definition fc.h:183
@ FC_R_CTL_SOL_DATA
Solicited Data.
Definition fc.h:178
@ FC_R_CTL_CMD_STAT
Command Status.
Definition fc.h:184
@ FC_R_CTL_SOL_CTRL
Solicited Control.
Definition fc.h:180
@ FC_F_CTL_ES_FIRST
First Sequence of Exchange.
Definition fc.h:202
@ FC_F_CTL_ES_END
Last Data Frame of Sequence.
Definition fc.h:204
@ FC_F_CTL_ES_TRANSFER
Transfer Sequence Initiative.
Definition fc.h:205
@ FC_F_CTL_ES_LAST
Last Sequence of Exchange.
Definition fc.h:203
@ FC_F_CTL_ES_RESPONDER
Responder of Exchange.
Definition fc.h:200
@ FC_F_CTL_MISC_REL_OFF
Relative Offset Present.
Definition fc.h:210
#define EBUSY
Device or resource busy.
Definition errno.h:382
#define htonl(value)
Definition byteswap.h:134
#define htons(value)
Definition byteswap.h:136
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition iobuf.c:153
#define iob_push(iobuf, len)
Definition iobuf.h:149
#define iob_disown(iobuf)
Disown an I/O buffer.
Definition iobuf.h:277
uint16_t seq_cnt
Active sequence count.
Definition fc.c:308
unsigned int type
Data structure type.
Definition fc.c:298
struct fc_port_id peer_port_id
Peer port ID.
Definition fc.c:296
uint16_t peer_xchg_id
Peer exchange ID.
Definition fc.c:304
unsigned int flags
Flags.
Definition fc.c:300
uint8_t seq_id
Active sequence ID.
Definition fc.c:306
uint8_t f_ctl_es
Frame control - exchange and sequence.
Definition fc.h:137
struct fc_port_id d_id
Destination ID.
Definition fc.h:129
uint16_t rx_id
Responder exchange ID.
Definition fc.h:151
uint8_t type
Data structure type.
Definition fc.h:135
uint8_t f_ctl_misc
Frame control - miscellaneous.
Definition fc.h:141
uint32_t parameter
Parameter.
Definition fc.h:157
uint8_t r_ctl
Routing control.
Definition fc.h:127
uint8_t seq_id
Sequence ID.
Definition fc.h:143
struct fc_port_id s_id
Source ID.
Definition fc.h:133
uint16_t seq_cnt
Sequence count.
Definition fc.h:147
uint16_t ox_id
Originator exchange ID.
Definition fc.h:149
int xfer_deliver_iob(struct interface *intf, struct io_buffer *iobuf)
Deliver datagram as I/O buffer without metadata.
Definition xfer.c:256
#define XFER_FL_ABS_OFFSET
Offset is absolute.
Definition xfer.h:48
#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_CMD_STAT
Data content represents a command or status message.
Definition xfer.h:61
#define XFER_FL_OUT
This is the final data transfer.
Definition xfer.h:54

References fc_frame_header::d_id, DBGC, dest, done, EBUSY, fc_frame_header::f_ctl_es, fc_frame_header::f_ctl_misc, FC_F_CTL_ES_END, FC_F_CTL_ES_FIRST, FC_F_CTL_ES_LAST, FC_F_CTL_ES_RESPONDER, FC_F_CTL_ES_TRANSFER, FC_F_CTL_MISC_REL_OFF, FC_R_CTL_CMD_STAT, FC_R_CTL_DATA, FC_R_CTL_ELS, FC_R_CTL_SOL_CTRL, FC_R_CTL_SOL_DATA, FC_R_CTL_UNSOL_CMD, FC_R_CTL_UNSOL_CTRL, FC_R_CTL_UNSOL_DATA, FC_TIMEOUT, FC_TYPE_CT, FC_TYPE_ELS, FC_XCHG_ORIGINATOR, FC_XCHG_SEQ_FIRST, FC_XCHG_SEQ_INITIATIVE, fc_exchange::flags, free_iob(), htonl, htons, iob_disown, iob_push, memcpy(), memset(), meta, fc_frame_header::ox_id, fc_frame_header::parameter, fc_exchange::peer_port_id, fc_exchange::peer_xchg_id, fc_exchange::port, port, fc_frame_header::r_ctl, rc, fc_frame_header::rx_id, fc_frame_header::s_id, fc_exchange::seq_cnt, fc_frame_header::seq_cnt, fc_exchange::seq_id, fc_frame_header::seq_id, start_timer_fixed(), strerror(), fc_exchange::timer, fc_exchange::type, fc_frame_header::type, fc_exchange::xchg_id, xfer_deliver_iob(), XFER_FL_ABS_OFFSET, XFER_FL_CMD_STAT, XFER_FL_OUT, XFER_FL_OVER, and XFER_FL_RESPONSE.

◆ fc_xchg_rx()

int fc_xchg_rx ( struct fc_exchange * xchg,
struct io_buffer * iobuf,
struct xfer_metadata *meta __unused )
static

Receive data as part of a Fibre Channel exchange.

Parameters
xchgFibre Channel exchange
iobufI/O buffer
metaData transfer metadata
Return values
rcReturn status code

Definition at line 587 of file fc.c.

588 {
589 struct fc_port *port = xchg->port;
590 struct fc_frame_header *fchdr = iobuf->data;
591 struct xfer_metadata fc_meta;
592 struct sockaddr_fc src;
593 struct sockaddr_fc dest;
594 int rc;
595
596 /* Record peer exchange ID */
597 xchg->peer_xchg_id =
598 ntohs ( ( fchdr->f_ctl_es & FC_F_CTL_ES_RESPONDER ) ?
599 fchdr->rx_id : fchdr->ox_id );
600
601 /* Sequence checks */
602 if ( xchg->flags & FC_XCHG_SEQ_INITIATIVE ) {
603 DBGC ( port, "FCXCHG %s/%04x received frame while holding "
604 "sequence initiative\n", port->name, xchg->xchg_id );
605 rc = -EBUSY;
606 goto done;
607 }
608 if ( ntohs ( fchdr->seq_cnt ) != xchg->seq_cnt ) {
609 DBGC ( port, "FCXCHG %s/%04x received out-of-order frame %d "
610 "(expected %d)\n", port->name, xchg->xchg_id,
611 ntohs ( fchdr->seq_cnt ), xchg->seq_cnt );
612 rc = -EPIPE;
613 goto done;
614 }
615 if ( xchg->seq_cnt == 0 )
616 xchg->seq_id = fchdr->seq_id;
617 xchg->seq_cnt++;
618 if ( fchdr->seq_id != xchg->seq_id ) {
619 DBGC ( port, "FCXCHG %s/%04x received frame for incorrect "
620 "sequence %02x (expected %02x)\n", port->name,
621 xchg->xchg_id, fchdr->seq_id, xchg->seq_id );
622 rc = -EPIPE;
623 goto done;
624 }
625
626 /* Check for end of sequence and transfer of sequence initiative */
627 if ( fchdr->f_ctl_es & FC_F_CTL_ES_END ) {
628 xchg->seq_cnt = 0;
629 if ( fchdr->f_ctl_es & FC_F_CTL_ES_TRANSFER ) {
631 xchg->seq_id = fc_new_seq_id();
632 }
633 }
634
635 /* Construct metadata */
636 memset ( &fc_meta, 0, sizeof ( fc_meta ) );
637 fc_meta.flags =
639 if ( fchdr->f_ctl_es & FC_F_CTL_ES_TRANSFER ) {
640 fc_meta.flags |= XFER_FL_OVER;
641 }
642 if ( ( fchdr->f_ctl_es & FC_F_CTL_ES_LAST ) &&
643 ( fchdr->f_ctl_es & FC_F_CTL_ES_END ) ) {
644 fc_meta.flags |= XFER_FL_OUT;
645 }
646 if ( fchdr->f_ctl_misc & FC_F_CTL_MISC_REL_OFF ) {
647 fc_meta.flags |= XFER_FL_ABS_OFFSET;
648 fc_meta.offset = ntohl ( fchdr->parameter );
649 }
650 fc_meta.src = fc_fill_sockaddr ( &src, &fchdr->s_id );
651 fc_meta.dest = fc_fill_sockaddr ( &dest, &fchdr->d_id );
652
653 /* Reset timeout */
655
656 /* Deliver via exchange's ULP interface */
657 iob_pull ( iobuf, sizeof ( *fchdr ) );
658 if ( ( rc = xfer_deliver ( &xchg->ulp, iob_disown ( iobuf ),
659 &fc_meta ) ) != 0 ) {
660 DBGC ( port, "FCXCHG %s/%04x cannot deliver frame: %s\n",
661 port->name, xchg->xchg_id, strerror ( rc ) );
662 goto done;
663 }
664
665 /* Close exchange if applicable */
666 if ( ( fchdr->f_ctl_es & FC_F_CTL_ES_LAST ) &&
667 ( fchdr->f_ctl_es & FC_F_CTL_ES_END ) ) {
668 fc_xchg_close ( xchg, 0 );
669 }
670
671 done:
672 free_iob ( iobuf );
673 return rc;
674}
static const void * src
Definition string.h:48
struct sockaddr * fc_fill_sockaddr(struct sockaddr_fc *sa_fc, struct fc_port_id *id)
Fill Fibre Channel socket address.
Definition fc.c:165
static const uint8_t fc_r_ctl_info_meta_flags[FC_R_CTL_INFO_MASK+1]
Mapping from Fibre Channel routing control information to xfer metadata.
Definition fc.c:568
static unsigned int fc_new_seq_id(void)
Create local Fibre Channel sequence identifier.
Definition fc.c:348
#define FC_R_CTL_INFO_MASK
Fibre Channel Routing Control Information mask.
Definition fc.h:188
#define EPIPE
Broken pipe.
Definition errno.h:663
#define ntohl(value)
Definition byteswap.h:135
#define ntohs(value)
Definition byteswap.h:137
#define iob_pull(iobuf, len)
Definition iobuf.h:167
void * data
Start of data.
Definition iobuf.h:113
Data transfer metadata.
Definition xfer.h:23
int xfer_deliver(struct interface *intf, struct io_buffer *iobuf, struct xfer_metadata *meta)
Deliver datagram.
Definition xfer.c:195

References __unused, fc_frame_header::d_id, io_buffer::data, DBGC, dest, xfer_metadata::dest, done, EBUSY, EPIPE, fc_frame_header::f_ctl_es, fc_frame_header::f_ctl_misc, FC_F_CTL_ES_END, FC_F_CTL_ES_LAST, FC_F_CTL_ES_RESPONDER, FC_F_CTL_ES_TRANSFER, FC_F_CTL_MISC_REL_OFF, fc_fill_sockaddr(), fc_new_seq_id(), FC_R_CTL_INFO_MASK, fc_r_ctl_info_meta_flags, FC_TIMEOUT, fc_xchg_close(), FC_XCHG_SEQ_INITIATIVE, fc_exchange::flags, xfer_metadata::flags, free_iob(), iob_disown, iob_pull, memset(), meta, ntohl, ntohs, xfer_metadata::offset, fc_frame_header::ox_id, fc_frame_header::parameter, fc_exchange::peer_xchg_id, fc_exchange::port, port, fc_frame_header::r_ctl, rc, fc_frame_header::rx_id, fc_frame_header::s_id, fc_exchange::seq_cnt, fc_frame_header::seq_cnt, fc_exchange::seq_id, fc_frame_header::seq_id, src, xfer_metadata::src, start_timer_fixed(), strerror(), fc_exchange::timer, fc_exchange::ulp, fc_exchange::xchg_id, xfer_deliver(), XFER_FL_ABS_OFFSET, XFER_FL_OUT, and XFER_FL_OVER.

Referenced by fc_port_deliver().

◆ fc_xchg_create()

struct fc_exchange * fc_xchg_create ( struct fc_port * port,
struct fc_port_id * peer_port_id,
unsigned int type )
static

Create new Fibre Channel exchange.

Parameters
portFibre Channel port
peer_port_idPeer port ID
Return values
xchgExchange, or NULL

Definition at line 695 of file fc.c.

697 {
698 struct fc_exchange *xchg;
699
700 /* Allocate and initialise structure */
701 xchg = zalloc ( sizeof ( *xchg ) );
702 if ( ! xchg )
703 return NULL;
704 ref_init ( &xchg->refcnt, fc_xchg_free );
705 intf_init ( &xchg->ulp, &fc_xchg_ulp_desc, &xchg->refcnt );
706 timer_init ( &xchg->timer, fc_xchg_expired, &xchg->refcnt );
707 xchg->port = fc_port_get ( port );
709 sizeof ( xchg->peer_port_id ) );
710 xchg->type = type;
711 xchg->xchg_id = fc_new_xchg_id();
713 xchg->seq_id = fc_new_seq_id();
714
715 /* Transfer reference to list of exchanges and return */
716 list_add ( &xchg->list, &port->xchgs );
717 return xchg;
718}
#define NULL
NULL pointer (VOID *).
Definition Base.h:321
uint32_t type
Operating system type.
Definition ena.h:1
static void fc_xchg_free(struct refcnt *refcnt)
Free Fibre Channel exchange.
Definition fc.c:359
static unsigned int fc_new_xchg_id(void)
Create local Fibre Channel exchange identifier.
Definition fc.c:335
static void fc_xchg_expired(struct retry_timer *timer, int over __unused)
Handle exchange timeout.
Definition fc.c:406
static struct interface_descriptor fc_xchg_ulp_desc
Fibre Channel exchange ULP interface descriptor.
Definition fc.c:685
#define FC_RX_ID_UNKNOWN
Responder exchange identifier used before first response.
Definition fc.h:214
static struct fc_port * fc_port_get(struct fc_port *port)
Get reference to Fibre Channel port.
Definition fc.h:305
static void intf_init(struct interface *intf, struct interface_descriptor *desc, struct refcnt *refcnt)
Initialise an object interface.
Definition interface.h:204
#define list_add(new, head)
Add a new entry to the head of a list.
Definition list.h:70
void * zalloc(size_t size)
Allocate cleared memory.
Definition malloc.c:718
#define ref_init(refcnt, free)
Initialise a reference counter.
Definition refcnt.h:65

References fc_new_seq_id(), fc_new_xchg_id(), fc_port_get(), FC_RX_ID_UNKNOWN, fc_xchg_expired(), fc_xchg_free(), fc_xchg_ulp_desc, intf_init(), fc_exchange::list, list_add, memcpy(), NULL, fc_exchange::peer_port_id, fc_exchange::peer_xchg_id, fc_exchange::port, port, ref_init, fc_exchange::refcnt, fc_exchange::seq_id, fc_exchange::timer, fc_exchange::type, type, fc_exchange::ulp, fc_exchange::xchg_id, and zalloc().

Referenced by fc_xchg_originate(), and fc_xchg_respond().

◆ fc_xchg_originate()

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.

Parameters
parentInterface to which to attach
portFibre Channel port
peer_port_idPeer port ID
Return values
xchg_idExchange ID, or negative error

Definition at line 728 of file fc.c.

729 {
730 struct fc_exchange *xchg;
731
732 /* Allocate and initialise structure */
734 if ( ! xchg )
735 return -ENOMEM;
738
739 DBGC2 ( port, "FCXCHG %s/%04x originating to %s (type %02x)\n",
740 port->name, xchg->xchg_id, fc_id_ntoa ( &xchg->peer_port_id ),
741 xchg->type );
742
743 /* Attach to parent interface and return */
744 intf_plug_plug ( &xchg->ulp, parent );
745 return xchg->xchg_id;
746}
static struct fc_exchange * fc_xchg_create(struct fc_port *port, struct fc_port_id *peer_port_id, unsigned int type)
Create new Fibre Channel exchange.
Definition fc.c:695
const char * fc_id_ntoa(const struct fc_port_id *id)
Format Fibre Channel port ID.
Definition fc.c:92
#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

References DBGC2, ENOMEM, fc_id_ntoa(), fc_xchg_create(), FC_XCHG_ORIGINATOR, FC_XCHG_SEQ_FIRST, FC_XCHG_SEQ_INITIATIVE, fc_exchange::flags, intf_plug_plug(), fc_exchange::peer_port_id, port, fc_exchange::type, type, fc_exchange::ulp, and fc_exchange::xchg_id.

Referenced by fc_els_step(), fc_ns_query_step(), and fcpdev_scsi_command().

◆ fc_xchg_respond()

struct fc_exchange * fc_xchg_respond ( struct fc_port * port,
struct fc_frame_header * fchdr )
static

Open a new responder Fibre Channel exchange.

Parameters
portFibre Channel port
fchdrFibre Channel frame header
Return values
xchgFibre Channel exchange, or NULL

Definition at line 755 of file fc.c.

756 {
757 struct fc_exchange *xchg;
758 struct fc_responder *responder;
759 unsigned int type = fchdr->type;
760 int rc;
761
762 /* Allocate and initialise structure */
763 xchg = fc_xchg_create ( port, &fchdr->s_id, type );
764 if ( ! xchg )
765 return NULL;
766 xchg->seq_id = fchdr->seq_id;
767
768 DBGC2 ( port, "FCXCHG %s/%04x responding to %s xchg %04x (type "
769 "%02x)\n", port->name, xchg->xchg_id,
770 fc_id_ntoa ( &xchg->peer_port_id ),
771 ntohs ( fchdr->ox_id ), xchg->type );
772
773 /* Find a responder, if any */
774 for_each_table_entry ( responder, FC_RESPONDERS ) {
775 if ( responder->type == type ) {
776 if ( ( rc = responder->respond ( &xchg->ulp, port,
777 &fchdr->d_id,
778 &fchdr->s_id ) ) !=0 ){
779 DBGC ( port, "FCXCHG %s/%04x could not "
780 "respond: %s\n", port->name,
781 xchg->xchg_id, strerror ( rc ) );
782 }
783 }
784 break;
785 }
786
787 /* We may or may not have a ULP attached at this point, but
788 * the exchange does exist.
789 */
790 return xchg;
791}
#define FC_RESPONDERS
Fibre Channel responder table.
Definition fc.h:240
A Fibre Channel responder.
Definition fc.h:223
unsigned int type
Type.
Definition fc.h:225
int(* respond)(struct interface *xchg, struct fc_port *port, struct fc_port_id *port_id, struct fc_port_id *peer_port_id)
Respond to exchange.
Definition fc.h:234
#define for_each_table_entry(pointer, table)
Iterate through all entries within a linker table.
Definition tables.h:386

References fc_frame_header::d_id, DBGC, DBGC2, fc_id_ntoa(), FC_RESPONDERS, fc_xchg_create(), for_each_table_entry, ntohs, NULL, fc_frame_header::ox_id, fc_exchange::peer_port_id, port, rc, fc_responder::respond, fc_frame_header::s_id, fc_exchange::seq_id, fc_frame_header::seq_id, strerror(), fc_exchange::type, fc_frame_header::type, fc_responder::type, type, fc_exchange::ulp, and fc_exchange::xchg_id.

Referenced by fc_port_deliver().

◆ fc_port_close()

void fc_port_close ( struct fc_port * port,
int rc )
static

Close Fibre Channel port.

Parameters
portFibre Channel port
rcReason for close

Definition at line 806 of file fc.c.

806 {
807 struct fc_exchange *xchg;
808 struct fc_exchange *tmp;
809
810 DBGC ( port, "FCPORT %s closed\n", port->name );
811
812 /* Log out port, if necessary */
813 if ( fc_link_ok ( &port->link ) )
815
816 /* Stop link monitor */
817 fc_link_stop ( &port->link );
818
819 /* Shut down interfaces */
820 intf_shutdown ( &port->transport, rc );
821 intf_shutdown ( &port->flogi, rc );
822 intf_shutdown ( &port->ns_plogi, rc );
823
824 /* Shut down any remaining exchanges */
825 list_for_each_entry_safe ( xchg, tmp, &port->xchgs, list )
826 fc_xchg_close ( xchg, rc );
827
828 /* Remove from list of ports */
829 list_del ( &port->list );
830 INIT_LIST_HEAD ( &port->list );
831}
static void fc_link_stop(struct fc_link_state *link)
Stop monitoring Fibre Channel link state.
Definition fc.c:275
void fc_port_logout(struct fc_port *port, int rc)
Log out Fibre Channel port.
Definition fc.c:1040
static int fc_link_ok(struct fc_link_state *link)
Check Fibre Channel link state.
Definition fc.h:109
unsigned long tmp
Definition linux_pci.h:65
#define list_for_each_entry_safe(pos, tmp, head, member)
Iterate over entries in a list, safe against deletion of the current entry.
Definition list.h:459

References DBGC, fc_link_ok(), fc_link_stop(), fc_port_logout(), fc_xchg_close(), INIT_LIST_HEAD, intf_shutdown(), fc_exchange::list, list_del, list_for_each_entry_safe, port, rc, and tmp.

◆ fc_port_demux()

struct fc_exchange * fc_port_demux ( struct fc_port * port,
unsigned int xchg_id )
static

Identify Fibre Channel exchange by local exchange ID.

Parameters
portFibre Channel port
xchg_idLocal exchange ID
Return values
xchgFibre Channel exchange, or NULL

Definition at line 840 of file fc.c.

841 {
842 struct fc_exchange *xchg;
843
844 list_for_each_entry ( xchg, &port->xchgs, list ) {
845 if ( xchg->xchg_id == xchg_id )
846 return xchg;
847 }
848 return NULL;
849}
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition list.h:432

References fc_exchange::list, list_for_each_entry, NULL, port, and fc_exchange::xchg_id.

Referenced by fc_port_deliver().

◆ fc_port_deliver()

int fc_port_deliver ( struct fc_port * port,
struct io_buffer * iobuf,
struct xfer_metadata * meta )
static

Handle received frame from Fibre Channel port.

Parameters
portFibre Channel port
iobufI/O buffer
metaData transfer metadata
Return values
rcReturn status code

Definition at line 859 of file fc.c.

860 {
861 struct fc_frame_header *fchdr;
862 unsigned int xchg_id;
863 struct fc_exchange *xchg;
864 int rc;
865
866 /* Sanity check */
867 if ( iob_len ( iobuf ) < sizeof ( *fchdr ) ) {
868 DBGC ( port, "FCPORT %s received underlength frame (%zd "
869 "bytes)\n", port->name, iob_len ( iobuf ) );
870 rc = -EINVAL;
871 goto err_sanity;
872 }
873 fchdr = iobuf->data;
874
875 /* Verify local port ID */
876 if ( ( memcmp ( &fchdr->d_id, &port->port_id,
877 sizeof ( fchdr->d_id ) ) != 0 ) &&
878 ( memcmp ( &fchdr->d_id, &fc_f_port_id,
879 sizeof ( fchdr->d_id ) ) != 0 ) &&
880 ( memcmp ( &port->port_id, &fc_empty_port_id,
881 sizeof ( port->port_id ) ) != 0 ) ) {
882 DBGC ( port, "FCPORT %s received frame for incorrect port ID "
883 "%s\n", port->name, fc_id_ntoa ( &fchdr->d_id ) );
884 rc = -ENOTCONN;
885 goto err_port_id;
886 }
887
888 /* Demultiplex amongst active exchanges */
890 fchdr->ox_id : fchdr->rx_id );
891 xchg = fc_port_demux ( port, xchg_id );
892
893 /* If we have no active exchange and this frame starts a new
894 * exchange, try to create a new responder exchange
895 */
896 if ( ( fchdr->f_ctl_es & FC_F_CTL_ES_FIRST ) &&
897 ( fchdr->seq_cnt == 0 ) ) {
898
899 /* Create new exchange */
900 xchg = fc_xchg_respond ( port, fchdr );
901 if ( ! xchg ) {
902 DBGC ( port, "FCPORT %s cannot create new exchange\n",
903 port->name );
904 rc = -ENOMEM;
905 goto err_respond;
906 }
907 }
908
909 /* Fail if no exchange exists */
910 if ( ! xchg ) {
911 DBGC ( port, "FCPORT %s xchg %04x unknown\n",
912 port->name, xchg_id );
913 rc = -ENOTCONN;
914 goto err_no_xchg;
915 }
916
917 /* Pass received frame to exchange */
918 ref_get ( &xchg->refcnt );
919 if ( ( rc = fc_xchg_rx ( xchg, iob_disown ( iobuf ), meta ) ) != 0 )
920 goto err_xchg_rx;
921
922 err_xchg_rx:
923 ref_put ( &xchg->refcnt );
924 err_no_xchg:
925 err_respond:
926 err_port_id:
927 err_sanity:
928 free_iob ( iobuf );
929 return rc;
930}
static struct fc_exchange * fc_xchg_respond(struct fc_port *port, struct fc_frame_header *fchdr)
Open a new responder Fibre Channel exchange.
Definition fc.c:755
struct fc_port_id fc_f_port_id
F_Port contoller port ID.
Definition fc.c:68
static int fc_xchg_rx(struct fc_exchange *xchg, struct io_buffer *iobuf, struct xfer_metadata *meta __unused)
Receive data as part of a Fibre Channel exchange.
Definition fc.c:587
struct fc_port_id fc_empty_port_id
Unassigned port ID.
Definition fc.c:65
static struct fc_exchange * fc_port_demux(struct fc_port *port, unsigned int xchg_id)
Identify Fibre Channel exchange by local exchange ID.
Definition fc.c:840
#define ENOTCONN
The socket is not connected.
Definition errno.h:613
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition iobuf.h:220
#define ref_get(refcnt)
Get additional reference to object.
Definition refcnt.h:93
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition string.c:115

References fc_frame_header::d_id, io_buffer::data, DBGC, EINVAL, ENOMEM, ENOTCONN, fc_frame_header::f_ctl_es, fc_empty_port_id, FC_F_CTL_ES_FIRST, FC_F_CTL_ES_RESPONDER, fc_f_port_id, fc_id_ntoa(), fc_port_demux(), fc_xchg_respond(), fc_xchg_rx(), free_iob(), iob_disown, iob_len(), memcmp(), meta, ntohs, fc_frame_header::ox_id, port, rc, ref_get, ref_put, fc_exchange::refcnt, fc_frame_header::rx_id, fc_frame_header::seq_cnt, and fc_exchange::xchg_id.

◆ fc_port_login()

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.

Parameters
portFibre Channel port
port_idLocal port ID
link_node_wwnLink node name
link_port_wwnLink port name
has_fabricLink is to a fabric
Return values
rcReturn status code

Definition at line 942 of file fc.c.

944 {
945 struct fc_peer *peer;
946 struct fc_peer *tmp;
947 int rc;
948
949 /* Perform implicit logout if logged in and details differ */
950 if ( fc_link_ok ( &port->link ) &&
951 ( ( ( !! ( port->flags & FC_PORT_HAS_FABRIC ) ) !=
952 ( !! has_fabric ) ) ||
953 ( memcmp ( &port->link_node_wwn, link_node_wwn,
954 sizeof ( port->link_node_wwn ) ) != 0 ) ||
955 ( memcmp ( &port->link_port_wwn, link_port_wwn,
956 sizeof ( port->link_port_wwn ) ) != 0 ) ||
957 ( has_fabric &&
958 ( memcmp ( &port->port_id, port_id,
959 sizeof ( port->port_id ) ) != 0 ) ) ) ) {
960 fc_port_logout ( port, 0 );
961 }
962
963 /* Log in, if applicable */
964 if ( ! fc_link_ok ( &port->link ) ) {
965
966 /* Record link port name */
967 memcpy ( &port->link_node_wwn, link_node_wwn,
968 sizeof ( port->link_node_wwn ) );
969 memcpy ( &port->link_port_wwn, link_port_wwn,
970 sizeof ( port->link_port_wwn ) );
971 DBGC ( port, "FCPORT %s logged in to %s",
972 port->name, fc_ntoa ( &port->link_node_wwn ) );
973 DBGC ( port, " port %s\n", fc_ntoa ( &port->link_port_wwn ) );
974
975 /* Calculate local (and possibly remote) port IDs */
976 if ( has_fabric ) {
977 port->flags |= FC_PORT_HAS_FABRIC;
978 memcpy ( &port->port_id, port_id,
979 sizeof ( port->port_id ) );
980 } else {
981 port->flags &= ~FC_PORT_HAS_FABRIC;
982 if ( memcmp ( &port->port_wwn, link_port_wwn,
983 sizeof ( port->port_wwn ) ) > 0 ) {
984 memcpy ( &port->port_id, &fc_ptp_high_port_id,
985 sizeof ( port->port_id ) );
986 memcpy ( &port->ptp_link_port_id,
988 sizeof ( port->ptp_link_port_id ) );
989 } else {
990 memcpy ( &port->port_id, &fc_ptp_low_port_id,
991 sizeof ( port->port_id ) );
992 memcpy ( &port->ptp_link_port_id,
994 sizeof ( port->ptp_link_port_id ) );
995 }
996 }
997 DBGC ( port, "FCPORT %s logged in via a %s, with local ID "
998 "%s\n", port->name,
999 ( ( port->flags & FC_PORT_HAS_FABRIC ) ?
1000 "fabric" : "point-to-point link" ),
1001 fc_id_ntoa ( &port->port_id ) );
1002 }
1003
1004 /* Log in to name server, if attached to a fabric */
1005 if ( has_fabric && ! ( port->flags & FC_PORT_HAS_NS ) ) {
1006
1007 DBGC ( port, "FCPORT %s attempting login to name server\n",
1008 port->name );
1009
1010 intf_restart ( &port->ns_plogi, -ECANCELED );
1011 if ( ( rc = fc_els_plogi ( &port->ns_plogi, port,
1012 &fc_gs_port_id ) ) != 0 ) {
1013 DBGC ( port, "FCPORT %s could not initiate name "
1014 "server PLOGI: %s\n",
1015 port->name, strerror ( rc ) );
1016 fc_port_logout ( port, rc );
1017 return rc;
1018 }
1019 }
1020
1021 /* Record login */
1022 fc_link_up ( &port->link );
1023
1024 /* Notify peers of link state change */
1026 fc_peer_get ( peer );
1027 fc_link_examine ( &peer->link );
1028 fc_peer_put ( peer );
1029 }
1030
1031 return 0;
1032}
struct fc_port_id fc_ptp_high_port_id
Point-to-point high port ID.
Definition fc.c:77
static void fc_link_up(struct fc_link_state *link)
Mark Fibre Channel link as up.
Definition fc.c:195
struct fc_port_id fc_ptp_low_port_id
Point-to-point low port ID.
Definition fc.c:74
const char * fc_ntoa(const struct fc_name *wwn)
Format Fibre Channel WWN.
Definition fc.c:127
struct fc_port_id fc_gs_port_id
Generic services port ID.
Definition fc.c:71
static void fc_peer_put(struct fc_peer *peer)
Drop reference to Fibre Channel peer.
Definition fc.h:391
@ FC_PORT_HAS_FABRIC
Port is attached to a fabric.
Definition fc.h:293
@ FC_PORT_HAS_NS
Port is logged in to a name server.
Definition fc.h:295
static struct fc_peer * fc_peer_get(struct fc_peer *peer)
Get reference to Fibre Channel peer.
Definition fc.h:380
struct list_head fc_peers
int fc_els_plogi(struct interface *parent, struct fc_port *port, struct fc_port_id *peer_port_id)
Create PLOGI request.
Definition fcels.c:736
#define ECANCELED
Operation canceled.
Definition errno.h:387
void intf_restart(struct interface *intf, int rc)
Shut down and restart an object interface.
Definition interface.c:344
struct mschapv2_challenge peer
Peer challenge.
Definition mschapv2.h:1
A Fibre Channel peer.
Definition fc.h:341
struct list_head list
List of all peers.
Definition fc.h:345
struct fc_port_id port_id
Peer port ID, if known.
Definition fc.h:357

References DBGC, ECANCELED, fc_els_plogi(), fc_gs_port_id, fc_id_ntoa(), fc_link_examine(), fc_link_ok(), fc_link_up(), fc_ntoa(), fc_peer_get(), fc_peer_put(), fc_peers, FC_PORT_HAS_FABRIC, FC_PORT_HAS_NS, fc_port_logout(), fc_ptp_high_port_id, fc_ptp_low_port_id, intf_restart(), fc_peer::list, list_for_each_entry_safe, memcmp(), memcpy(), peer, port, fc_peer::port_id, rc, strerror(), and tmp.

Referenced by fc_els_flogi_rx().

◆ fc_port_logout()

void fc_port_logout ( struct fc_port * port,
int rc )

Log out Fibre Channel port.

Parameters
portFibre Channel port
rcReason for logout

Definition at line 1040 of file fc.c.

1040 {
1041 struct fc_peer *peer;
1042 struct fc_peer *tmp;
1043
1044 DBGC ( port, "FCPORT %s logged out: %s\n",
1045 port->name, strerror ( rc ) );
1046
1047 /* Erase port details */
1048 memset ( &port->port_id, 0, sizeof ( port->port_id ) );
1049 port->flags = 0;
1050
1051 /* Record logout */
1052 fc_link_err ( &port->link, rc );
1053
1054 /* Notify peers of link state change */
1056 fc_peer_get ( peer );
1057 fc_link_examine ( &peer->link );
1058 fc_peer_put ( peer );
1059 }
1060}
static void fc_link_err(struct fc_link_state *link, int rc)
Mark Fibre Channel link as down.
Definition fc.c:210

References DBGC, fc_link_err(), fc_link_examine(), fc_peer_get(), fc_peer_put(), fc_peers, fc_peer::list, list_for_each_entry_safe, memset(), peer, port, rc, strerror(), and tmp.

Referenced by fc_els_logo_logout(), fc_port_close(), fc_port_examine(), fc_port_flogi_done(), fc_port_login(), and fc_port_window_changed().

◆ fc_port_flogi_done()

void fc_port_flogi_done ( struct fc_port * port,
int rc )
static

Handle FLOGI completion.

Parameters
portFibre Channel port
rcReason for completion

Definition at line 1068 of file fc.c.

1068 {
1069
1070 intf_restart ( &port->flogi, rc );
1071
1072 if ( rc != 0 )
1073 fc_port_logout ( port, rc );
1074}

References fc_port_logout(), intf_restart(), port, and rc.

◆ fc_port_ns_plogi_done()

void fc_port_ns_plogi_done ( struct fc_port * port,
int rc )
static

Handle name server PLOGI completion.

Parameters
portFibre Channel port
rcReason for completion

Definition at line 1082 of file fc.c.

1082 {
1083
1084 intf_restart ( &port->ns_plogi, rc );
1085
1086 if ( rc == 0 ) {
1087 port->flags |= FC_PORT_HAS_NS;
1088 DBGC ( port, "FCPORT %s logged in to name server\n",
1089 port->name );
1090 } else {
1091 DBGC ( port, "FCPORT %s could not log in to name server: %s\n",
1092 port->name, strerror ( rc ) );
1093 /* Absence of a name server is not a fatal error */
1094 }
1095}

References DBGC, FC_PORT_HAS_NS, intf_restart(), port, rc, and strerror().

◆ fc_port_examine()

void fc_port_examine ( struct fc_link_state * link)
static

Examine Fibre Channel port link state.

@ link Fibre Channel link state monitor

Definition at line 1102 of file fc.c.

1102 {
1103 struct fc_port *port = container_of ( link, struct fc_port, link );
1104 int rc;
1105
1106 /* Do nothing if already logged in */
1107 if ( fc_link_ok ( &port->link ) )
1108 return;
1109
1110 DBGC ( port, "FCPORT %s attempting login\n", port->name );
1111
1112 /* Try to create FLOGI ELS */
1113 intf_restart ( &port->flogi, -ECANCELED );
1114 if ( ( rc = fc_els_flogi ( &port->flogi, port ) ) != 0 ) {
1115 DBGC ( port, "FCPORT %s could not initiate FLOGI: %s\n",
1116 port->name, strerror ( rc ) );
1117 fc_port_logout ( port, rc );
1118 return;
1119 }
1120}
int fc_els_flogi(struct interface *parent, struct fc_port *port)
Create FLOGI request.
Definition fcels.c:583

References container_of, DBGC, ECANCELED, fc_els_flogi(), fc_link_ok(), fc_port_logout(), intf_restart(), link, port, rc, and strerror().

Referenced by fc_port_open().

◆ fc_port_window_changed()

void fc_port_window_changed ( struct fc_port * port)
static

Handle change of flow control window.

Parameters
portFibre Channel port

Definition at line 1127 of file fc.c.

1127 {
1128 size_t window;
1129
1130 /* Check if transport layer is ready */
1131 window = xfer_window ( &port->transport );
1132 if ( window > 0 ) {
1133
1134 /* Transport layer is ready. Start login if the link
1135 * is not already up.
1136 */
1137 if ( ! fc_link_ok ( &port->link ) )
1138 fc_link_start ( &port->link );
1139
1140 } else {
1141
1142 /* Transport layer is not ready. Log out port and
1143 * wait for transport layer before attempting log in
1144 * again.
1145 */
1147 fc_link_stop ( &port->link );
1148 }
1149}
static void fc_link_start(struct fc_link_state *link)
Start monitoring Fibre Channel link state.
Definition fc.c:266
size_t xfer_window(struct interface *intf)
Check flow control window.
Definition xfer.c:117

References ENOTCONN, fc_link_ok(), fc_link_start(), fc_link_stop(), fc_port_logout(), port, and xfer_window().

◆ fc_port_open()

int fc_port_open ( struct interface * transport,
const struct fc_name * node_wwn,
const struct fc_name * port_wwn,
const char * name )

Create Fibre Channel port.

Parameters
transportTransport interface
nodeFibre Channel node name
portFibre Channel port name
nameSymbolic port name
Return values
rcReturn status code

Definition at line 1190 of file fc.c.

1191 {
1192 struct fc_port *port;
1193
1194 /* Allocate and initialise structure */
1195 port = zalloc ( sizeof ( *port ) );
1196 if ( ! port )
1197 return -ENOMEM;
1198 ref_init ( &port->refcnt, NULL );
1199 intf_init ( &port->transport, &fc_port_transport_desc, &port->refcnt );
1200 fc_link_init ( &port->link, fc_port_examine, &port->refcnt );
1201 intf_init ( &port->flogi, &fc_port_flogi_desc, &port->refcnt );
1202 intf_init ( &port->ns_plogi, &fc_port_ns_plogi_desc, &port->refcnt );
1203 list_add_tail ( &port->list, &fc_ports );
1204 INIT_LIST_HEAD ( &port->xchgs );
1205 memcpy ( &port->node_wwn, node_wwn, sizeof ( port->node_wwn ) );
1206 memcpy ( &port->port_wwn, port_wwn, sizeof ( port->port_wwn ) );
1207 snprintf ( port->name, sizeof ( port->name ), "%s", name );
1208
1209 DBGC ( port, "FCPORT %s opened as %s",
1210 port->name, fc_ntoa ( &port->node_wwn ) );
1211 DBGC ( port, " port %s\n", fc_ntoa ( &port->port_wwn ) );
1212
1213 /* Attach to transport layer, mortalise self, and return */
1214 intf_plug_plug ( &port->transport, transport );
1215 ref_put ( &port->refcnt );
1216 return 0;
1217}
const char * name
Definition ath9k_hw.c:1986
static void fc_port_examine(struct fc_link_state *link)
Examine Fibre Channel port link state.
Definition fc.c:1102
static struct interface_descriptor fc_port_flogi_desc
Fibre Channel port FLOGI interface descriptor.
Definition fc.c:1169
static struct interface_descriptor fc_port_transport_desc
Fibre Channel port transport interface descriptor.
Definition fc.c:1160
static struct interface_descriptor fc_port_ns_plogi_desc
Fibre Channel port name server PLOGI interface descriptor.
Definition fc.c:1178
static void fc_link_init(struct fc_link_state *link, void(*examine)(struct fc_link_state *link), struct refcnt *refcnt)
Initialise Fibre Channel link state monitor.
Definition fc.c:252
struct list_head fc_ports
#define list_add_tail(new, head)
Add a new entry to the tail of a list.
Definition list.h:94
struct fc_name node_wwn
Node name.
Definition fc.h:264
struct fc_name port_wwn
Port name.
Definition fc.h:266
struct interface transport
Transport interface.
Definition fc.h:262

References DBGC, ENOMEM, fc_link_init(), fc_ntoa(), fc_port_examine(), fc_port_flogi_desc, fc_port_ns_plogi_desc, fc_port_transport_desc, fc_ports, INIT_LIST_HEAD, intf_init(), intf_plug_plug(), list_add_tail, memcpy(), name, fc_port::node_wwn, NULL, port, fc_port::port_wwn, ref_init, ref_put, snprintf(), fc_port::transport, and zalloc().

Referenced by fcoe_expired().

◆ fc_port_find()

struct fc_port * fc_port_find ( const char * name)

Find Fibre Channel port by name.

Parameters
nameFibre Channel port name
Return values
portFibre Channel port, or NULL

Definition at line 1225 of file fc.c.

1225 {
1226 struct fc_port *port;
1227
1229 if ( strcmp ( name, port->name ) == 0 )
1230 return port;
1231 }
1232 return NULL;
1233}
int strcmp(const char *first, const char *second)
Compare strings.
Definition string.c:174
struct list_head list
List of all ports.
Definition fc.h:257

References fc_ports, fc_port::list, list_for_each_entry, name, NULL, port, and strcmp().

Referenced by parse_fc_port().

◆ fc_peer_close()

void fc_peer_close ( struct fc_peer * peer,
int rc )
static

Close Fibre Channel peer.

Parameters
peerFibre Channel peer
rcReason for close

Definition at line 1248 of file fc.c.

1248 {
1249
1250 DBGC ( peer, "FCPEER %s closed: %s\n",
1251 fc_ntoa ( &peer->port_wwn ) , strerror ( rc ) );
1252
1253 /* Sanity check */
1254 assert ( list_empty ( &peer->ulps ) );
1255
1256 /* Stop link timer */
1257 fc_link_stop ( &peer->link );
1258
1259 /* Shut down interfaces */
1260 intf_shutdown ( &peer->plogi, rc );
1261
1262 /* Remove from list of peers */
1263 list_del ( &peer->list );
1264 INIT_LIST_HEAD ( &peer->list );
1265}

References assert, DBGC, fc_link_stop(), fc_ntoa(), INIT_LIST_HEAD, intf_shutdown(), list_del, list_empty, peer, rc, and strerror().

Referenced by fc_peer_logout().

◆ fc_peer_increment()

void fc_peer_increment ( struct fc_peer * peer)
static

Increment Fibre Channel peer active usage count.

Parameters
peerFibre Channel peer

Definition at line 1272 of file fc.c.

1272 {
1273
1274 /* Increment our usage count */
1275 peer->usage++;
1276}

References peer.

Referenced by fc_ulp_attach().

◆ fc_peer_decrement()

void fc_peer_decrement ( struct fc_peer * peer)
static

Decrement Fibre Channel peer active usage count.

Parameters
peerFibre Channel peer

Definition at line 1283 of file fc.c.

1283 {
1284
1285 /* Sanity check */
1286 assert ( peer->usage > 0 );
1287
1288 /* Decrement our usage count and log out if we reach zero */
1289 if ( --(peer->usage) == 0 )
1290 fc_peer_logout ( peer, 0 );
1291}
void fc_peer_logout(struct fc_peer *peer, int rc)
Log out Fibre Channel peer.
Definition fc.c:1348

References assert, fc_peer_logout(), and peer.

Referenced by fc_ulp_detach().

◆ fc_peer_login()

int fc_peer_login ( struct fc_peer * peer,
struct fc_port * port,
struct fc_port_id * port_id )

Log in Fibre Channel peer.

Parameters
peerFibre Channel peer
portFibre Channel port
port_idPort ID
Return values
rcReturn status code

Definition at line 1301 of file fc.c.

1302 {
1303 struct fc_ulp *ulp;
1304 struct fc_ulp *tmp;
1305
1306 /* Perform implicit logout if logged in and details differ */
1307 if ( fc_link_ok ( &peer->link ) &&
1308 ( ( peer->port != port ) ||
1309 ( memcmp ( &peer->port_id, port_id,
1310 sizeof ( peer->port_id ) ) !=0 ) ) ) {
1311 fc_peer_logout ( peer, 0 );
1312 }
1313
1314 /* Log in, if applicable */
1315 if ( ! fc_link_ok ( &peer->link ) ) {
1316
1317 /* Record peer details */
1318 assert ( peer->port == NULL );
1319 peer->port = fc_port_get ( port );
1320 memcpy ( &peer->port_id, port_id, sizeof ( peer->port_id ) );
1321 DBGC ( peer, "FCPEER %s logged in via %s as %s\n",
1322 fc_ntoa ( &peer->port_wwn ), peer->port->name,
1323 fc_id_ntoa ( &peer->port_id ) );
1324
1325 /* Add login reference */
1326 fc_peer_get ( peer );
1327 }
1328
1329 /* Record login */
1330 fc_link_up ( &peer->link );
1331
1332 /* Notify ULPs of link state change */
1333 list_for_each_entry_safe ( ulp, tmp, &peer->ulps, list ) {
1334 fc_ulp_get ( ulp );
1335 fc_link_examine ( &ulp->link );
1336 fc_ulp_put ( ulp );
1337 }
1338
1339 return 0;
1340}
static struct fc_ulp * fc_ulp_get(struct fc_ulp *ulp)
Get reference to Fibre Channel upper-layer protocol.
Definition fc.h:475
static void fc_ulp_put(struct fc_ulp *ulp)
Drop reference to Fibre Channel upper-layer protocol.
Definition fc.h:486
A Fibre Channel upper-layer protocol.
Definition fc.h:414
struct fc_link_state link
Link state monitor.
Definition fc.h:428
struct list_head list
List of upper-layer protocols.
Definition fc.h:420

References assert, DBGC, fc_id_ntoa(), fc_link_examine(), fc_link_ok(), fc_link_up(), fc_ntoa(), fc_peer_get(), fc_peer_logout(), fc_port_get(), fc_ulp_get(), fc_ulp_put(), fc_ulp::link, fc_ulp::list, list_for_each_entry_safe, memcmp(), memcpy(), NULL, peer, port, and tmp.

Referenced by fc_els_plogi_rx().

◆ fc_peer_logout()

void fc_peer_logout ( struct fc_peer * peer,
int rc )

Log out Fibre Channel peer.

Parameters
peerFibre Channel peer
rcReason for logout

Definition at line 1348 of file fc.c.

1348 {
1349 struct fc_ulp *ulp;
1350 struct fc_ulp *tmp;
1351
1352 DBGC ( peer, "FCPEER %s logged out: %s\n",
1353 fc_ntoa ( &peer->port_wwn ), strerror ( rc ) );
1354
1355 /* Drop login reference, if applicable */
1356 if ( fc_link_ok ( &peer->link ) )
1357 fc_peer_put ( peer );
1358
1359 /* Erase peer details */
1360 fc_port_put ( peer->port );
1361 peer->port = NULL;
1362
1363 /* Record logout */
1364 fc_link_err ( &peer->link, rc );
1365
1366 /* Notify ULPs of link state change */
1367 list_for_each_entry_safe ( ulp, tmp, &peer->ulps, list ) {
1368 fc_ulp_get ( ulp );
1369 fc_link_examine ( &ulp->link );
1370 fc_ulp_put ( ulp );
1371 }
1372
1373 /* Close peer if there are no active users */
1374 if ( peer->usage == 0 )
1375 fc_peer_close ( peer, rc );
1376}
static void fc_peer_close(struct fc_peer *peer, int rc)
Close Fibre Channel peer.
Definition fc.c:1248

References DBGC, fc_link_err(), fc_link_examine(), fc_link_ok(), fc_ntoa(), fc_peer_close(), fc_peer_put(), fc_port_put(), fc_ulp_get(), fc_ulp_put(), fc_ulp::link, fc_ulp::list, list_for_each_entry_safe, NULL, peer, rc, strerror(), and tmp.

Referenced by fc_els_logo_logout(), fc_peer_decrement(), fc_peer_examine(), fc_peer_login(), fc_peer_plogi(), and fc_peer_plogi_done().

◆ fc_peer_plogi_done()

void fc_peer_plogi_done ( struct fc_peer * peer,
int rc )
static

Handle PLOGI completion.

Parameters
peerFibre Channel peer
rcReason for completion

Definition at line 1384 of file fc.c.

1384 {
1385
1386 intf_restart ( &peer->plogi, rc );
1387
1388 if ( rc != 0 )
1389 fc_peer_logout ( peer, rc );
1390}

References fc_peer_logout(), intf_restart(), peer, and rc.

◆ fc_peer_plogi()

int fc_peer_plogi ( struct fc_peer * peer,
struct fc_port * port,
struct fc_port_id * peer_port_id )
static

Initiate PLOGI.

Parameters
peerFibre Channel peer
portFibre Channel port
peer_port_idPeer port ID
Return values
rcReturn status code

Definition at line 1400 of file fc.c.

1401 {
1402 int rc;
1403
1404 /* Try to create PLOGI ELS */
1405 intf_restart ( &peer->plogi, -ECANCELED );
1406 if ( ( rc = fc_els_plogi ( &peer->plogi, port, peer_port_id ) ) != 0 ) {
1407 DBGC ( peer, "FCPEER %s could not initiate PLOGI: %s\n",
1408 fc_ntoa ( &peer->port_wwn ), strerror ( rc ) );
1409 fc_peer_logout ( peer, rc );
1410 return rc;
1411 }
1412
1413 return 0;
1414}

References DBGC, ECANCELED, fc_els_plogi(), fc_ntoa(), fc_peer_logout(), intf_restart(), peer, port, rc, and strerror().

Referenced by fc_peer_examine().

◆ fc_peer_examine()

void fc_peer_examine ( struct fc_link_state * link)
static

Examine Fibre Channel peer link state.

@ link Fibre Channel link state monitor

Definition at line 1421 of file fc.c.

1421 {
1422 struct fc_peer *peer = container_of ( link, struct fc_peer, link );
1423 struct fc_port *port;
1424 int rc;
1425
1426 /* Check to see if underlying port link has gone down */
1427 if ( peer->port && ( ! fc_link_ok ( &peer->port->link ) ) ) {
1429 return;
1430 }
1431
1432 /* Do nothing if already logged in */
1433 if ( fc_link_ok ( &peer->link ) )
1434 return;
1435
1436 DBGC ( peer, "FCPEER %s attempting login\n",
1437 fc_ntoa ( &peer->port_wwn ) );
1438
1439 /* Sanity check */
1440 assert ( peer->port == NULL );
1441
1442 /* First, look for a port with the peer attached via a
1443 * point-to-point link.
1444 */
1446 if ( fc_link_ok ( &port->link ) &&
1447 ( ! ( port->flags & FC_PORT_HAS_FABRIC ) ) &&
1448 ( memcmp ( &peer->port_wwn, &port->link_port_wwn,
1449 sizeof ( peer->port_wwn ) ) == 0 ) ) {
1450 /* Use this peer port ID, and stop looking */
1451 fc_peer_plogi ( peer, port, &port->ptp_link_port_id );
1452 return;
1453 }
1454 }
1455
1456 /* If the peer is not directly attached, try initiating a name
1457 * server lookup on any suitable ports.
1458 */
1460 if ( fc_link_ok ( &port->link ) &&
1461 ( port->flags & FC_PORT_HAS_FABRIC ) &&
1462 ( port->flags & FC_PORT_HAS_NS ) ) {
1463 if ( ( rc = fc_ns_query ( peer, port,
1464 fc_peer_plogi ) ) != 0 ) {
1465 DBGC ( peer, "FCPEER %s could not attempt "
1466 "name server lookup on %s: %s\n",
1467 fc_ntoa ( &peer->port_wwn ), port->name,
1468 strerror ( rc ) );
1469 /* Non-fatal */
1470 }
1471 }
1472 }
1473}
static int fc_peer_plogi(struct fc_peer *peer, struct fc_port *port, struct fc_port_id *peer_port_id)
Initiate PLOGI.
Definition fc.c:1400
A Fibre Channel name server query.
Definition fcns.c:45

References assert, container_of, DBGC, ENOTCONN, fc_link_ok(), fc_ntoa(), fc_peer_logout(), fc_peer_plogi(), FC_PORT_HAS_FABRIC, FC_PORT_HAS_NS, fc_ports, link, fc_port::list, list_for_each_entry, memcmp(), NULL, peer, port, rc, and strerror().

Referenced by fc_peer_create().

◆ fc_peer_create()

struct fc_peer * fc_peer_create ( const struct fc_name * port_wwn)
static

Create Fibre Channel peer.

Parameters
port_wwnNode name
Return values
peerFibre Channel peer, or NULL

Definition at line 1490 of file fc.c.

1490 {
1491 struct fc_peer *peer;
1492
1493 /* Allocate and initialise structure */
1494 peer = zalloc ( sizeof ( *peer ) );
1495 if ( ! peer )
1496 return NULL;
1497 ref_init ( &peer->refcnt, NULL );
1498 fc_link_init ( &peer->link, fc_peer_examine, &peer->refcnt );
1499 intf_init ( &peer->plogi, &fc_peer_plogi_desc, &peer->refcnt );
1500 list_add_tail ( &peer->list, &fc_peers );
1501 memcpy ( &peer->port_wwn, port_wwn, sizeof ( peer->port_wwn ) );
1502 INIT_LIST_HEAD ( &peer->ulps );
1503
1504 /* Start link monitor */
1505 fc_link_start ( &peer->link );
1506
1507 DBGC ( peer, "FCPEER %s created\n", fc_ntoa ( &peer->port_wwn ) );
1508 return peer;
1509}
static struct interface_descriptor fc_peer_plogi_desc
Fibre Channel peer PLOGI interface descriptor.
Definition fc.c:1481
static void fc_peer_examine(struct fc_link_state *link)
Examine Fibre Channel peer link state.
Definition fc.c:1421
struct fc_name port_wwn
Port name.
Definition fc.h:348

References DBGC, fc_link_init(), fc_link_start(), fc_ntoa(), fc_peer_examine(), fc_peer_plogi_desc, fc_peers, INIT_LIST_HEAD, intf_init(), list_add_tail, memcpy(), NULL, peer, fc_peer::port_wwn, ref_init, and zalloc().

Referenced by fc_peer_get_wwn().

◆ fc_peer_get_wwn()

struct fc_peer * fc_peer_get_wwn ( const struct fc_name * port_wwn)

Get Fibre Channel peer by node name.

Parameters
port_wwnNode name
Return values
peerFibre Channel peer, or NULL

Definition at line 1517 of file fc.c.

1517 {
1518 struct fc_peer *peer;
1519
1520 /* Look for an existing peer */
1522 if ( memcmp ( &peer->port_wwn, port_wwn,
1523 sizeof ( peer->port_wwn ) ) == 0 )
1524 return fc_peer_get ( peer );
1525 }
1526
1527 /* Create a new peer */
1529 if ( ! peer )
1530 return NULL;
1531
1532 return peer;
1533}
static struct fc_peer * fc_peer_create(const struct fc_name *port_wwn)
Create Fibre Channel peer.
Definition fc.c:1490

References fc_peer_create(), fc_peer_get(), fc_peers, fc_peer::list, list_for_each_entry, memcmp(), NULL, peer, and fc_peer::port_wwn.

Referenced by fc_els_plogi_rx(), and fc_ulp_get_wwn_type().

◆ fc_peer_get_port_id()

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.

Parameters
portFibre Channel port
peer_port_idPeer port ID
Return values
peerFibre Channel peer, or NULL

Definition at line 1542 of file fc.c.

1543 {
1544 struct fc_peer *peer;
1545
1546 /* Look for an existing peer */
1548 if ( ( peer->port == port ) &&
1549 ( memcmp ( &peer->port_id, peer_port_id,
1550 sizeof ( peer->port_id ) ) == 0 ) )
1551 return fc_peer_get ( peer );
1552 }
1553
1554 /* Cannot create a new peer, since we have no port name to use */
1555 return NULL;
1556}

References fc_peer_get(), fc_peers, fc_peer::list, list_for_each_entry, memcmp(), NULL, peer, and port.

Referenced by fc_els_logo_logout(), and fc_ulp_get_port_id_type().

◆ fc_ulp_free()

void fc_ulp_free ( struct refcnt * refcnt)
static

Free Fibre Channel upper-layer protocol.

Parameters
refcntReference count

Definition at line 1570 of file fc.c.

1570 {
1571 struct fc_ulp *ulp = container_of ( refcnt, struct fc_ulp, refcnt );
1572
1573 fc_peer_put ( ulp->peer );
1574 free ( ulp );
1575}
struct fc_peer * peer
Fibre Channel peer.
Definition fc.h:418

References container_of, fc_peer_put(), free, and fc_ulp::peer.

Referenced by fc_ulp_create().

◆ fc_ulp_close()

void fc_ulp_close ( struct fc_ulp * ulp,
int rc )
static

Close Fibre Channel upper-layer protocol.

Parameters
ulpFibre Channel upper-layer protocol
rcReason for close

Definition at line 1583 of file fc.c.

1583 {
1584
1585 DBGC ( ulp, "FCULP %s/%02x closed: %s\n",
1586 fc_ntoa ( &ulp->peer->port_wwn ), ulp->type, strerror ( rc ) );
1587
1588 /* Sanity check */
1589 assert ( list_empty ( &ulp->users ) );
1590
1591 /* Stop link monitor */
1592 fc_link_stop ( &ulp->link );
1593
1594 /* Shut down interfaces */
1595 intf_shutdown ( &ulp->prli, rc );
1596
1597 /* Remove from list of ULPs */
1598 list_del ( &ulp->list );
1599 INIT_LIST_HEAD ( &ulp->list );
1600}
unsigned int type
Type.
Definition fc.h:423
struct list_head users
Active users of this upper-layer protocol.
Definition fc.h:444
struct interface prli
PRLI interface.
Definition fc.h:430

References assert, DBGC, fc_link_stop(), fc_ntoa(), INIT_LIST_HEAD, intf_shutdown(), fc_ulp::link, fc_ulp::list, list_del, list_empty, fc_ulp::peer, fc_peer::port_wwn, fc_ulp::prli, rc, strerror(), fc_ulp::type, and fc_ulp::users.

Referenced by fc_ulp_logout().

◆ fc_ulp_attach()

void fc_ulp_attach ( struct fc_ulp * ulp,
struct fc_ulp_user * user )

Attach Fibre Channel upper-layer protocol user.

Parameters
ulpFibre Channel upper-layer protocol
userFibre Channel upper-layer protocol user

Definition at line 1608 of file fc.c.

1608 {
1609
1610 /* Sanity check */
1611 assert ( user->ulp == NULL );
1612
1613 /* Increment peer's usage count */
1614 fc_peer_increment ( ulp->peer );
1615
1616 /* Attach user */
1617 user->ulp = fc_ulp_get ( ulp );
1618 list_add ( &user->list, &ulp->users );
1619}
static void fc_peer_increment(struct fc_peer *peer)
Increment Fibre Channel peer active usage count.
Definition fc.c:1272
struct list_head list
List of users.
Definition fc.h:458
struct fc_ulp * ulp
Fibre Channel upper layer protocol.
Definition fc.h:456

References assert, fc_peer_increment(), fc_ulp_get(), fc_ulp_user::list, list_add, NULL, fc_ulp::peer, fc_ulp_user::ulp, and fc_ulp::users.

Referenced by fcpdev_open().

◆ fc_ulp_detach()

void fc_ulp_detach ( struct fc_ulp_user * user)

Detach Fibre Channel upper-layer protocol user.

Parameters
userFibre Channel upper-layer protocol user

Definition at line 1626 of file fc.c.

1626 {
1627 struct fc_ulp *ulp = user->ulp;
1628
1629 /* Do nothing if not attached */
1630 if ( ! ulp )
1631 return;
1632
1633 /* Sanity checks */
1634 list_check_contains_entry ( user, &ulp->users, list );
1635
1636 /* Detach user and log out if no users remain */
1637 list_del ( &user->list );
1638 if ( list_empty ( &ulp->users ) )
1639 fc_ulp_logout ( ulp, 0 );
1640
1641 /* Decrement our peer's usage count */
1642 fc_peer_decrement ( ulp->peer );
1643
1644 /* Drop reference */
1645 user->ulp = NULL;
1646 fc_ulp_put ( ulp );
1647}
static void fc_peer_decrement(struct fc_peer *peer)
Decrement Fibre Channel peer active usage count.
Definition fc.c:1283
void fc_ulp_logout(struct fc_ulp *ulp, int rc)
Log out Fibre Channel upper-layer protocol.
Definition fc.c:1728
#define list_check_contains_entry(entry, head, member)
Check list contains a specified entry.
Definition list.h:550

References fc_peer_decrement(), fc_ulp_logout(), fc_ulp_put(), fc_ulp::list, fc_ulp_user::list, list_check_contains_entry, list_del, list_empty, NULL, fc_ulp::peer, fc_ulp_user::ulp, and fc_ulp::users.

Referenced by fcpdev_close().

◆ fc_ulp_login()

int fc_ulp_login ( struct fc_ulp * ulp,
const void * param,
size_t param_len,
int originated )

Log in Fibre Channel upper-layer protocol.

Parameters
ulpFibre Channel upper-layer protocol
paramService parameters
param_lenLength of service parameters
originatedLogin was originated by us
Return values
rcReturn status code

Definition at line 1658 of file fc.c.

1659 {
1660 struct fc_ulp_user *user;
1661 struct fc_ulp_user *tmp;
1662
1663 /* Perform implicit logout if logged in and service parameters differ */
1664 if ( fc_link_ok ( &ulp->link ) &&
1665 ( ( ulp->param_len != param_len ) ||
1666 ( memcmp ( ulp->param, param, ulp->param_len ) != 0 ) ) ) {
1667 fc_ulp_logout ( ulp, 0 );
1668 }
1669
1670 /* Work around a bug in some versions of the Linux Fibre
1671 * Channel stack, which fail to fully initialise image pairs
1672 * established via a PRLI originated by the Linux stack
1673 * itself.
1674 */
1675 if ( originated )
1677 if ( ! ( ulp->flags & FC_ULP_ORIGINATED_LOGIN_OK ) ) {
1678 DBGC ( ulp, "FCULP %s/%02x sending extra PRLI to work around "
1679 "Linux bug\n",
1680 fc_ntoa ( &ulp->peer->port_wwn ), ulp->type );
1681 fc_link_stop ( &ulp->link );
1682 fc_link_start ( &ulp->link );
1683 return 0;
1684 }
1685
1686 /* Log in, if applicable */
1687 if ( ! fc_link_ok ( &ulp->link ) ) {
1688
1689 /* Record service parameters */
1690 assert ( ulp->param == NULL );
1691 assert ( ulp->param_len == 0 );
1692 ulp->param = malloc ( param_len );
1693 if ( ! ulp->param ) {
1694 DBGC ( ulp, "FCULP %s/%02x could not record "
1695 "parameters\n",
1696 fc_ntoa ( &ulp->peer->port_wwn ), ulp->type );
1697 return -ENOMEM;
1698 }
1699 memcpy ( ulp->param, param, param_len );
1700 ulp->param_len = param_len;
1701 DBGC ( ulp, "FCULP %s/%02x logged in with parameters:\n",
1702 fc_ntoa ( &ulp->peer->port_wwn ), ulp->type );
1703 DBGC_HDA ( ulp, 0, ulp->param, ulp->param_len );
1704
1705 /* Add login reference */
1706 fc_ulp_get ( ulp );
1707 }
1708
1709 /* Record login */
1710 fc_link_up ( &ulp->link );
1711
1712 /* Notify users of link state change */
1713 list_for_each_entry_safe ( user, tmp, &ulp->users, list ) {
1714 fc_ulp_user_get ( user );
1715 user->examine ( user );
1716 fc_ulp_user_put ( user );
1717 }
1718
1719 return 0;
1720}
static void fc_ulp_user_put(struct fc_ulp_user *user)
Drop reference to Fibre Channel upper-layer protocol user.
Definition fc.h:508
@ FC_ULP_ORIGINATED_LOGIN_OK
A login originated by us has succeeded.
Definition fc.h:450
static struct fc_ulp_user * fc_ulp_user_get(struct fc_ulp_user *user)
Get reference to Fibre Channel upper-layer protocol user.
Definition fc.h:497
#define DBGC_HDA(...)
Definition compiler.h:531
struct hv_monitor_parameter param[4][32]
Parameters.
Definition hyperv.h:13
void * malloc(size_t size)
Allocate memory.
Definition malloc.c:677
A Fibre Channel upper-layer protocol user.
Definition fc.h:454
void(* examine)(struct fc_ulp_user *user)
Examine link state.
Definition fc.h:465
unsigned int flags
Flags.
Definition fc.h:425
size_t param_len
Service parameter length.
Definition fc.h:434
void * param
Service parameters, if any.
Definition fc.h:432

References assert, DBGC, DBGC_HDA, ENOMEM, fc_ulp_user::examine, fc_link_ok(), fc_link_start(), fc_link_stop(), fc_link_up(), fc_ntoa(), fc_ulp_get(), fc_ulp_logout(), FC_ULP_ORIGINATED_LOGIN_OK, fc_ulp_user_get(), fc_ulp_user_put(), fc_ulp::flags, fc_ulp::link, fc_ulp_user::list, list_for_each_entry_safe, malloc(), memcmp(), memcpy(), NULL, fc_ulp::param, param, fc_ulp::param_len, fc_ulp::peer, fc_peer::port_wwn, tmp, fc_ulp::type, fc_ulp_user::ulp, and fc_ulp::users.

Referenced by fc_els_prli_rx().

◆ fc_ulp_logout()

void fc_ulp_logout ( struct fc_ulp * ulp,
int rc )

Log out Fibre Channel upper-layer protocol.

Parameters
ulpFibre Channel upper-layer protocol
rcReason for logout

Definition at line 1728 of file fc.c.

1728 {
1729 struct fc_ulp_user *user;
1730 struct fc_ulp_user *tmp;
1731
1732 DBGC ( ulp, "FCULP %s/%02x logged out: %s\n",
1733 fc_ntoa ( &ulp->peer->port_wwn ), ulp->type, strerror ( rc ) );
1734
1735 /* Drop login reference, if applicable */
1736 if ( fc_link_ok ( &ulp->link ) )
1737 fc_ulp_put ( ulp );
1738
1739 /* Discard service parameters */
1740 free ( ulp->param );
1741 ulp->param = NULL;
1742 ulp->param_len = 0;
1743 ulp->flags = 0;
1744
1745 /* Record logout */
1746 fc_link_err ( &ulp->link, rc );
1747
1748 /* Notify users of link state change */
1749 list_for_each_entry_safe ( user, tmp, &ulp->users, list ) {
1750 fc_ulp_user_get ( user );
1751 user->examine ( user );
1752 fc_ulp_user_put ( user );
1753 }
1754
1755 /* Close ULP if there are no clients attached */
1756 if ( list_empty ( &ulp->users ) )
1757 fc_ulp_close ( ulp, rc );
1758}
static void fc_ulp_close(struct fc_ulp *ulp, int rc)
Close Fibre Channel upper-layer protocol.
Definition fc.c:1583

References DBGC, fc_ulp_user::examine, fc_link_err(), fc_link_ok(), fc_ntoa(), fc_ulp_close(), fc_ulp_put(), fc_ulp_user_get(), fc_ulp_user_put(), fc_ulp::flags, free, fc_ulp::link, fc_ulp_user::list, list_empty, list_for_each_entry_safe, NULL, fc_ulp::param, fc_ulp::param_len, fc_ulp::peer, fc_peer::port_wwn, rc, strerror(), tmp, fc_ulp::type, fc_ulp_user::ulp, and fc_ulp::users.

Referenced by fc_els_prli_rx(), fc_ulp_detach(), fc_ulp_examine(), fc_ulp_login(), and fc_ulp_prli_done().

◆ fc_ulp_prli_done()

void fc_ulp_prli_done ( struct fc_ulp * ulp,
int rc )
static

Handle PRLI completion.

Parameters
ulpFibre Channel upper-layer protocol
rcReason for completion

Definition at line 1766 of file fc.c.

1766 {
1767
1768 intf_restart ( &ulp->prli, rc );
1769
1770 if ( rc != 0 )
1771 fc_ulp_logout ( ulp, rc );
1772}

References fc_ulp_logout(), intf_restart(), fc_ulp::prli, rc, and fc_ulp_user::ulp.

◆ fc_ulp_examine()

void fc_ulp_examine ( struct fc_link_state * link)
static

Examine Fibre Channel upper-layer protocol link state.

@ link Fibre Channel link state monitor

Definition at line 1779 of file fc.c.

1779 {
1780 struct fc_ulp *ulp = container_of ( link, struct fc_ulp, link );
1781 int rc;
1782
1783 /* Check to see if underlying peer link has gone down */
1784 if ( ! fc_link_ok ( &ulp->peer->link ) ) {
1785 fc_ulp_logout ( ulp, -ENOTCONN );
1786 return;
1787 }
1788
1789 /* Do nothing if already logged in */
1790 if ( fc_link_ok ( &ulp->link ) &&
1792 return;
1793
1794 DBGC ( ulp, "FCULP %s/%02x attempting login\n",
1795 fc_ntoa ( &ulp->peer->port_wwn ), ulp->type );
1796
1797 /* Try to create PRLI ELS */
1798 intf_restart ( &ulp->prli, -ECANCELED );
1799 if ( ( rc = fc_els_prli ( &ulp->prli, ulp->peer->port,
1800 &ulp->peer->port_id, ulp->type ) ) != 0 ) {
1801 DBGC ( ulp, "FCULP %s/%02x could not initiate PRLI: %s\n",
1802 fc_ntoa ( &ulp->peer->port_wwn ), ulp->type,
1803 strerror ( rc ) );
1804 fc_ulp_logout ( ulp, rc );
1805 return;
1806 }
1807}
int fc_els_prli(struct interface *parent, struct fc_port *port, struct fc_port_id *peer_port_id, unsigned int type)
Create PRLI request.
Definition fcels.c:1130
struct fc_link_state link
Link state monitor.
Definition fc.h:351
struct fc_port * port
Fibre Channel port, if known.
Definition fc.h:355

References container_of, DBGC, ECANCELED, ENOTCONN, fc_els_prli(), fc_link_ok(), fc_ntoa(), fc_ulp_logout(), FC_ULP_ORIGINATED_LOGIN_OK, fc_ulp::flags, intf_restart(), fc_peer::link, fc_ulp::link, link, fc_ulp::peer, fc_peer::port, fc_peer::port_id, fc_peer::port_wwn, fc_ulp::prli, rc, strerror(), and fc_ulp::type.

Referenced by fc_ulp_create().

◆ fc_ulp_create()

struct fc_ulp * fc_ulp_create ( struct fc_peer * peer,
unsigned int type )
static

Create Fibre Channel upper-layer protocl.

Parameters
peerFibre Channel peer
typeType
Return values
ulpFibre Channel upper-layer protocol, or NULL

Definition at line 1825 of file fc.c.

1826 {
1827 struct fc_ulp *ulp;
1828
1829 /* Allocate and initialise structure */
1830 ulp = zalloc ( sizeof ( *ulp ) );
1831 if ( ! ulp )
1832 return NULL;
1833 ref_init ( &ulp->refcnt, fc_ulp_free );
1834 fc_link_init ( &ulp->link, fc_ulp_examine, &ulp->refcnt );
1835 intf_init ( &ulp->prli, &fc_ulp_prli_desc, &ulp->refcnt );
1836 ulp->peer = fc_peer_get ( peer );
1837 list_add_tail ( &ulp->list, &peer->ulps );
1838 ulp->type = type;
1839 INIT_LIST_HEAD ( &ulp->users );
1840
1841 /* Start link state monitor */
1842 fc_link_start ( &ulp->link );
1843
1844 DBGC ( ulp, "FCULP %s/%02x created\n",
1845 fc_ntoa ( &ulp->peer->port_wwn ), ulp->type );
1846 return ulp;
1847}
static struct interface_descriptor fc_ulp_prli_desc
Fibre Channel upper-layer protocol PRLI interface descriptor.
Definition fc.c:1815
static void fc_ulp_examine(struct fc_link_state *link)
Examine Fibre Channel upper-layer protocol link state.
Definition fc.c:1779
static void fc_ulp_free(struct refcnt *refcnt)
Free Fibre Channel upper-layer protocol.
Definition fc.c:1570
struct refcnt refcnt
Reference count.
Definition fc.h:416

References DBGC, fc_link_init(), fc_link_start(), fc_ntoa(), fc_peer_get(), fc_ulp_examine(), fc_ulp_free(), fc_ulp_prli_desc, INIT_LIST_HEAD, intf_init(), fc_ulp::link, fc_ulp::list, list_add_tail, NULL, fc_ulp::peer, peer, fc_peer::port_wwn, fc_ulp::prli, ref_init, fc_ulp::refcnt, fc_ulp::type, type, fc_ulp::users, and zalloc().

Referenced by fc_ulp_get_type().

◆ fc_ulp_get_type()

struct fc_ulp * fc_ulp_get_type ( struct fc_peer * peer,
unsigned int type )
static

Get Fibre Channel upper-layer protocol by peer and type.

Parameters
peerFibre Channel peer
typeType
Return values
ulpFibre Channel upper-layer protocol, or NULL

Definition at line 1856 of file fc.c.

1857 {
1858 struct fc_ulp *ulp;
1859
1860 /* Look for an existing ULP */
1861 list_for_each_entry ( ulp, &peer->ulps, list ) {
1862 if ( ulp->type == type )
1863 return fc_ulp_get ( ulp );
1864 }
1865
1866 /* Create a new ULP */
1867 ulp = fc_ulp_create ( peer, type );
1868 if ( ! ulp )
1869 return NULL;
1870
1871 return ulp;
1872}
static struct fc_ulp * fc_ulp_create(struct fc_peer *peer, unsigned int type)
Create Fibre Channel upper-layer protocl.
Definition fc.c:1825

References fc_ulp_create(), fc_ulp_get(), fc_ulp::list, list_for_each_entry, NULL, peer, fc_ulp::type, and type.

Referenced by fc_ulp_get_port_id_type(), and fc_ulp_get_wwn_type().

◆ fc_ulp_get_wwn_type()

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.

Parameters
port_wwnPort name
typeType
Return values
ulpFibre Channel upper-layer protocol, or NULL

Definition at line 1881 of file fc.c.

1882 {
1883 struct fc_ulp *ulp;
1884 struct fc_peer *peer;
1885
1886 /* Get peer */
1888 if ( ! peer )
1889 goto err_peer_get_wwn;
1890
1891 /* Get ULP */
1892 ulp = fc_ulp_get_type ( peer, type );
1893 if ( ! ulp )
1894 goto err_ulp_get_type;
1895
1896 /* Drop temporary reference to peer */
1897 fc_peer_put ( peer );
1898
1899 return ulp;
1900
1901 fc_ulp_put ( ulp );
1902 err_ulp_get_type:
1903 fc_peer_put ( peer );
1904 err_peer_get_wwn:
1905 return NULL;
1906}
struct fc_peer * fc_peer_get_wwn(const struct fc_name *port_wwn)
Get Fibre Channel peer by node name.
Definition fc.c:1517
static struct fc_ulp * fc_ulp_get_type(struct fc_peer *peer, unsigned int type)
Get Fibre Channel upper-layer protocol by peer and type.
Definition fc.c:1856

References fc_peer_get_wwn(), fc_peer_put(), fc_ulp_get_type(), fc_ulp_put(), NULL, peer, fc_peer::port_wwn, and type.

Referenced by fcpdev_open().

◆ fc_ulp_get_port_id_type()

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.

Parameters
portFibre Channel port
peer_port_idPeer port ID
typeType
Return values
ulpFibre Channel upper-layer protocol, or NULL

Definition at line 1916 of file fc.c.

1918 {
1919 struct fc_ulp *ulp;
1920 struct fc_peer *peer;
1921
1922 /* Get peer */
1923 peer = fc_peer_get_port_id ( port, peer_port_id );
1924 if ( ! peer )
1925 goto err_peer_get_wwn;
1926
1927 /* Get ULP */
1928 ulp = fc_ulp_get_type ( peer, type );
1929 if ( ! ulp )
1930 goto err_ulp_get_type;
1931
1932 /* Drop temporary reference to peer */
1933 fc_peer_put ( peer );
1934
1935 return ulp;
1936
1937 fc_ulp_put ( ulp );
1938 err_ulp_get_type:
1939 fc_peer_put ( peer );
1940 err_peer_get_wwn:
1941 return NULL;
1942}
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

References fc_peer_get_port_id(), fc_peer_put(), fc_ulp_get_type(), fc_ulp_put(), NULL, peer, port, and type.

Referenced by fc_els_prli_rx(), and fc_els_prli_tx().

◆ REQUIRING_SYMBOL()

REQUIRING_SYMBOL ( fc_ports )

References fc_ports.

◆ REQUIRE_OBJECT()

REQUIRE_OBJECT ( config_fc )

Variable Documentation

◆ fc_empty_port_id

struct fc_port_id fc_empty_port_id = { .bytes = { 0x00, 0x00, 0x00 } }

Unassigned port ID.

Definition at line 65 of file fc.c.

65{ .bytes = { 0x00, 0x00, 0x00 } };

Referenced by fc_port_deliver(), and fcels_exec().

◆ fc_f_port_id

struct fc_port_id fc_f_port_id = { .bytes = { 0xff, 0xff, 0xfe } }

F_Port contoller port ID.

Definition at line 68 of file fc.c.

68{ .bytes = { 0xff, 0xff, 0xfe } };

Referenced by fc_els_flogi(), fc_els_logo_logout(), fc_port_deliver(), and fcels_exec().

◆ fc_gs_port_id

struct fc_port_id fc_gs_port_id = { .bytes = { 0xff, 0xff, 0xfc } }

Generic services port ID.

Definition at line 71 of file fc.c.

71{ .bytes = { 0xff, 0xff, 0xfc } };

Referenced by fc_ns_query_step(), and fc_port_login().

◆ fc_ptp_low_port_id

struct fc_port_id fc_ptp_low_port_id = { .bytes = { 0x01, 0x01, 0x01 } }

Point-to-point low port ID.

Definition at line 74 of file fc.c.

74{ .bytes = { 0x01, 0x01, 0x01 } };

Referenced by fc_port_login().

◆ fc_ptp_high_port_id

struct fc_port_id fc_ptp_high_port_id = { .bytes = { 0x01, 0x01, 0x02 } }

Point-to-point high port ID.

Definition at line 77 of file fc.c.

77{ .bytes = { 0x01, 0x01, 0x02 } };

Referenced by fc_port_login().

◆ fc_r_ctl_info_meta_flags

const uint8_t fc_r_ctl_info_meta_flags[FC_R_CTL_INFO_MASK+1]
static
Initial value:

Mapping from Fibre Channel routing control information to xfer metadata.

Definition at line 568 of file fc.c.

Referenced by fc_xchg_rx().

◆ fc_xchg_ulp_op

struct interface_operation fc_xchg_ulp_op[]
static
Initial value:
= {
}
static size_t fc_xchg_window(struct fc_exchange *xchg __unused)
Check Fibre Channel exchange window.
Definition fc.c:423
static int fc_xchg_tx(struct fc_exchange *xchg, struct io_buffer *iobuf, struct xfer_metadata *meta)
Transmit data as part of a Fibre Channel exchange.
Definition fc.c:457
static struct io_buffer * fc_xchg_alloc_iob(struct fc_exchange *xchg, size_t len)
Allocate Fibre Channel I/O buffer.
Definition fc.c:436
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

Fibre Channel exchange ULP interface operations.

Definition at line 677 of file fc.c.

◆ fc_xchg_ulp_desc

struct interface_descriptor fc_xchg_ulp_desc
static
Initial value:
=
static struct interface_operation fc_xchg_ulp_op[]
Fibre Channel exchange ULP interface operations.
Definition fc.c:677
#define INTF_DESC(object_type, intf, operations)
Define an object interface descriptor.
Definition interface.h:81

Fibre Channel exchange ULP interface descriptor.

Definition at line 685 of file fc.c.

Referenced by fc_xchg_create().

◆ fc_port_transport_op

struct interface_operation fc_port_transport_op[]
static
Initial value:
= {
}
static int fc_port_deliver(struct fc_port *port, struct io_buffer *iobuf, struct xfer_metadata *meta)
Handle received frame from Fibre Channel port.
Definition fc.c:859
static void fc_port_window_changed(struct fc_port *port)
Handle change of flow control window.
Definition fc.c:1127
static void fc_port_close(struct fc_port *port, int rc)
Close Fibre Channel port.
Definition fc.c:806
void xfer_window_changed(struct interface *intf)
Report change of flow control window.
Definition xfer.c:147

Fibre Channel port transport interface operations.

Definition at line 1152 of file fc.c.

1152 {
1156 INTF_OP ( intf_close, struct fc_port *, fc_port_close ),
1157};

◆ fc_port_transport_desc

struct interface_descriptor fc_port_transport_desc
static
Initial value:
=
INTF_DESC ( struct fc_port, transport, fc_port_transport_op )
static struct interface_operation fc_port_transport_op[]
Fibre Channel port transport interface operations.
Definition fc.c:1152

Fibre Channel port transport interface descriptor.

Definition at line 1160 of file fc.c.

Referenced by fc_port_open().

◆ fc_port_flogi_op

struct interface_operation fc_port_flogi_op[]
static
Initial value:
= {
}
static void fc_port_flogi_done(struct fc_port *port, int rc)
Handle FLOGI completion.
Definition fc.c:1068

Fibre Channel port FLOGI interface operations.

Definition at line 1164 of file fc.c.

1164 {
1166};

◆ fc_port_flogi_desc

struct interface_descriptor fc_port_flogi_desc
static
Initial value:
=
static struct interface_operation fc_port_flogi_op[]
Fibre Channel port FLOGI interface operations.
Definition fc.c:1164

Fibre Channel port FLOGI interface descriptor.

Definition at line 1169 of file fc.c.

Referenced by fc_port_open().

◆ fc_port_ns_plogi_op

struct interface_operation fc_port_ns_plogi_op[]
static
Initial value:
= {
}
static void fc_port_ns_plogi_done(struct fc_port *port, int rc)
Handle name server PLOGI completion.
Definition fc.c:1082

Fibre Channel port name server PLOGI interface operations.

Definition at line 1173 of file fc.c.

1173 {
1175};

◆ fc_port_ns_plogi_desc

struct interface_descriptor fc_port_ns_plogi_desc
static
Initial value:
=
INTF_DESC ( struct fc_port, ns_plogi, fc_port_ns_plogi_op )
static struct interface_operation fc_port_ns_plogi_op[]
Fibre Channel port name server PLOGI interface operations.
Definition fc.c:1173

Fibre Channel port name server PLOGI interface descriptor.

Definition at line 1178 of file fc.c.

Referenced by fc_port_open().

◆ fc_peer_plogi_op

struct interface_operation fc_peer_plogi_op[]
static
Initial value:
= {
}
static void fc_peer_plogi_done(struct fc_peer *peer, int rc)
Handle PLOGI completion.
Definition fc.c:1384

Fibre Channel peer PLOGI interface operations.

Definition at line 1476 of file fc.c.

1476 {
1478};

◆ fc_peer_plogi_desc

struct interface_descriptor fc_peer_plogi_desc
static
Initial value:
=
static struct interface_operation fc_peer_plogi_op[]
Fibre Channel peer PLOGI interface operations.
Definition fc.c:1476

Fibre Channel peer PLOGI interface descriptor.

Definition at line 1481 of file fc.c.

Referenced by fc_peer_create().

◆ fc_ulp_prli_op

struct interface_operation fc_ulp_prli_op[]
static
Initial value:
= {
}
static void fc_ulp_prli_done(struct fc_ulp *ulp, int rc)
Handle PRLI completion.
Definition fc.c:1766

Fibre Channel upper-layer protocol PRLI interface operations.

Definition at line 1810 of file fc.c.

1810 {
1812};

◆ fc_ulp_prli_desc

struct interface_descriptor fc_ulp_prli_desc
static
Initial value:
=
INTF_DESC ( struct fc_ulp, prli, fc_ulp_prli_op )
static struct interface_operation fc_ulp_prli_op[]
Fibre Channel upper-layer protocol PRLI interface operations.
Definition fc.c:1810

Fibre Channel upper-layer protocol PRLI interface descriptor.

Definition at line 1815 of file fc.c.

Referenced by fc_ulp_create().