iPXE
Data Structures | Macros | Enumerations | Functions | Variables
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. More...
 
#define EINFO_EUNKNOWN_LINK_STATUS   __einfo_uniqify ( EINFO_EINPROGRESS, 0x01, "Unknown" )
 
#define FC_TIMEOUT   ( 1 * TICKS_PER_SEC )
 Fibre Channel timeout. More...
 

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

Variables

struct fc_port_id fc_empty_port_id = { .bytes = { 0x00, 0x00, 0x00 } }
 Unassigned port ID. More...
 
struct fc_port_id fc_f_port_id = { .bytes = { 0xff, 0xff, 0xfe } }
 F_Port contoller port ID. More...
 
struct fc_port_id fc_gs_port_id = { .bytes = { 0xff, 0xff, 0xfc } }
 Generic services port ID. More...
 
struct fc_port_id fc_ptp_low_port_id = { .bytes = { 0x01, 0x01, 0x01 } }
 Point-to-point low port ID. More...
 
struct fc_port_id fc_ptp_high_port_id = { .bytes = { 0x01, 0x01, 0x02 } }
 Point-to-point high port ID. More...
 
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. More...
 
static struct interface_operation fc_xchg_ulp_op []
 Fibre Channel exchange ULP interface operations. More...
 
static struct interface_descriptor fc_xchg_ulp_desc
 Fibre Channel exchange ULP interface descriptor. More...
 
static struct interface_operation fc_port_transport_op []
 Fibre Channel port transport interface operations. More...
 
static struct interface_descriptor fc_port_transport_desc
 Fibre Channel port transport interface descriptor. More...
 
static struct interface_operation fc_port_flogi_op []
 Fibre Channel port FLOGI interface operations. More...
 
static struct interface_descriptor fc_port_flogi_desc
 Fibre Channel port FLOGI interface descriptor. More...
 
static struct interface_operation fc_port_ns_plogi_op []
 Fibre Channel port name server PLOGI interface operations. More...
 
static struct interface_descriptor fc_port_ns_plogi_desc
 Fibre Channel port name server PLOGI interface descriptor. More...
 
static struct interface_operation fc_peer_plogi_op []
 Fibre Channel peer PLOGI interface operations. More...
 
static struct interface_descriptor fc_peer_plogi_desc
 Fibre Channel peer PLOGI interface descriptor. More...
 
static struct interface_operation fc_ulp_prli_op []
 Fibre Channel upper-layer protocol PRLI interface operations. More...
 
static struct interface_descriptor fc_ulp_prli_desc
 Fibre Channel upper-layer protocol PRLI interface descriptor. More...
 

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.

◆ EINFO_EUNKNOWN_LINK_STATUS

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

Definition at line 187 of file fc.c.

◆ FC_TIMEOUT

#define FC_TIMEOUT   ( 1 * TICKS_PER_SEC )

Fibre Channel timeout.

Definition at line 328 of file fc.c.

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 };
We have the sequence initiative.
Definition: fc.c:322
We are the exchange originator.
Definition: fc.c:320
This is the first sequence of the exchange.
Definition: fc.c:324

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )

◆ LIST_HEAD() [1/2]

LIST_HEAD ( fc_ports  )

List of Fibre Channel ports.

◆ LIST_HEAD() [2/2]

LIST_HEAD ( fc_peers  )

List of Fibre Channel 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 }
#define FC_PORT_ID_STRLEN
Length of Fibre Channel port identifier next.
Definition: fc.h:42
uint8_t id
Request identifier.
Definition: ena.h:12
int snprintf(char *buf, size_t size, const char *fmt,...)
Write a formatted string to a buffer.
Definition: vsprintf.c:382

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:428
unsigned long strtoul(const char *string, char **endp, int base)
Convert string to numeric value.
Definition: string.c:441
uint8_t id
Request identifier.
Definition: ena.h:12

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 }
int snprintf(char *buf, size_t size, const char *fmt,...)
Write a formatted string to a buffer.
Definition: vsprintf.c:382
#define FC_NAME_STRLEN
Length of Fibre Channel name text.
Definition: fc.h:34
uint64_t wwn
WWN.
Definition: edd.h:30

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 }
#define EINVAL
Invalid argument.
Definition: errno.h:428
unsigned long strtoul(const char *string, char **endp, int base)
Convert string to numeric value.
Definition: string.c:441
uint64_t wwn
WWN.
Definition: edd.h:30

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 }
struct sockaddr sa
Definition: dns.c:68
u16 fc
802.11 Frame Control field
Definition: ieee80211.h:14
Fibre Channel socket address.
Definition: fc.h:47
struct fc_port_id sfc_port_id
Port ID.
Definition: fc.h:54
sa_family_t sfc_family
Socket address family (part of struct sockaddr)
Definition: fc.h:52
#define AF_FC
Fibre Channel addresses.
Definition: socket.h:65
void * memcpy(void *dest, const void *src, size_t len) __nonnull
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
Generalized socket address structure.
Definition: socket.h:96
union @16 u
void * memset(void *dest, int character, size_t len) __nonnull

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

Referenced by fc_els_tx(), and fc_xchg_rx().

◆ fc_link_up()

static 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:68
void stop_timer(struct retry_timer *timer)
Stop timer.
Definition: retry.c:117

References link, and stop_timer().

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

◆ fc_link_err()

static 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:14
#define FC_LINK_RETRY_DELAY
Delay between failed link-up attempts.
Definition: fc.h:86
#define EUNKNOWN_LINK_STATUS
Default link status code.
Definition: fc.c:186
u32 link
Link to next descriptor.
Definition: ar9003_mac.h:68
void start_timer_fixed(struct retry_timer *timer, unsigned long timeout)
Start timer with a specified timeout.
Definition: retry.c:64

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

static 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 }
u32 link
Link to next descriptor.
Definition: ar9003_mac.h:68

References link.

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

◆ fc_link_expired()

static 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 =
236  container_of ( timer, struct fc_link_state, timer );
237 
238  /* Schedule another link examination */
240 
241  /* Examine link */
242  fc_link_examine ( link );
243 }
#define FC_LINK_RETRY_DELAY
Delay between failed link-up attempts.
Definition: fc.h:86
static void fc_link_examine(struct fc_link_state *link)
Examine Fibre Channel link state.
Definition: fc.c:226
A timer.
Definition: timer.h:28
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
u32 link
Link to next descriptor.
Definition: ar9003_mac.h:68
void start_timer_fixed(struct retry_timer *timer, unsigned long timeout)
Start timer with a specified timeout.
Definition: retry.c:64

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

Referenced by fc_link_init().

◆ fc_link_init()

static void fc_link_init ( struct fc_link_state link,
void(*)(struct fc_link_state *link examine,
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 
256  link->rc = -EUNKNOWN_LINK_STATUS;
257  timer_init ( &link->timer, fc_link_expired, refcnt );
258  link->examine = examine;
259 }
#define EUNKNOWN_LINK_STATUS
Default link status code.
Definition: fc.c:186
A reference counter.
Definition: refcnt.h:26
u32 link
Link to next descriptor.
Definition: ar9003_mac.h:68
static void fc_link_expired(struct retry_timer *timer, int over __unused)
Handle Fibre Channel link retry timer expiry.
Definition: fc.c:234

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

static 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:99
u32 link
Link to next descriptor.
Definition: ar9003_mac.h:68

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

static 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 }
u32 link
Link to next descriptor.
Definition: ar9003_mac.h:68
void stop_timer(struct retry_timer *timer)
Stop timer.
Definition: retry.c:117

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

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

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

static 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 =
361  container_of ( refcnt, struct fc_exchange, refcnt );
362 
363  assert ( ! timer_running ( &xchg->timer ) );
364  assert ( list_empty ( &xchg->list ) );
365 
366  fc_port_put ( xchg->port );
367  free ( xchg );
368 }
static void fc_port_put(struct fc_port *port)
Drop reference to Fibre Channel port.
Definition: fc.h:315
A reference counter.
Definition: refcnt.h:26
#define list_empty(list)
Test whether a list is empty.
Definition: list.h:136
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
A Fibre Channel exchange.
Definition: fc.c:287
struct fc_port * port
Fibre Channel port.
Definition: fc.c:291
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
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()

static 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 }
struct interface ulp
Upper-layer protocol interface.
Definition: fc.c:314
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
void intf_shutdown(struct interface *intf, int rc)
Shut down an object interface.
Definition: interface.c:273
struct refcnt refcnt
Reference count.
Definition: fc.c:289
uint16_t xchg_id
Local exchange ID.
Definition: fc.c:302
A Fibre Channel port.
Definition: fc.h:252
#define list_empty(list)
Test whether a list is empty.
Definition: list.h:136
#define list_del(list)
Delete an entry from a list.
Definition: list.h:119
u8 port
Port number.
Definition: CIB_PRM.h:31
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
struct fc_port * port
Fibre Channel port.
Definition: fc.c:291
#define INIT_LIST_HEAD(list)
Initialise a list head.
Definition: list.h:45
void stop_timer(struct retry_timer *timer)
Stop timer.
Definition: retry.c:117
#define DBGC2(...)
Definition: compiler.h:522
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
#define ref_put(refcnt)
Drop reference to object.
Definition: refcnt.h:106

References DBGC2, INIT_LIST_HEAD, intf_shutdown(), fc_exchange::list, list_del, list_empty, port, fc_exchange::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()

static 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 }
#define DBGC(...)
Definition: compiler.h:505
uint16_t xchg_id
Local exchange ID.
Definition: fc.c:302
A Fibre Channel port.
Definition: fc.h:252
A timer.
Definition: timer.h:28
u8 port
Port number.
Definition: CIB_PRM.h:31
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
A Fibre Channel exchange.
Definition: fc.c:287
struct fc_port * port
Fibre Channel port.
Definition: fc.c:291
static void fc_xchg_close(struct fc_exchange *xchg, int rc)
Close Fibre Channel exchange.
Definition: fc.c:376
#define ETIMEDOUT
Connection timed out.
Definition: errno.h:669

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

Referenced by fc_xchg_create().

◆ fc_xchg_window()

static 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 */
426  return FC_LOGIN_DEFAULT_MTU;
427 }
#define FC_LOGIN_DEFAULT_MTU
Fibre Channel default MTU.
Definition: fcels.h:168

References FC_LOGIN_DEFAULT_MTU.

◆ fc_xchg_alloc_iob()

static 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 }
struct io_buffer * xfer_alloc_iob(struct interface *intf, size_t len)
Allocate I/O buffer.
Definition: xfer.c:157
A Fibre Channel port.
Definition: fc.h:252
u8 port
Port number.
Definition: CIB_PRM.h:31
struct fc_port * port
Fibre Channel port.
Definition: fc.c:291
#define iob_reserve(iobuf, len)
Definition: iobuf.h:63
uint32_t len
Length.
Definition: ena.h:14
A Fibre Channel Frame Header.
Definition: fc.h:120
A persistent I/O buffer.
Definition: iobuf.h:32

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

◆ fc_xchg_tx()

static 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 */
552  start_timer_fixed ( &xchg->timer, FC_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 }
unsigned int flags
Flags.
Definition: fc.c:300
Solicited Data.
Definition: fc.h:177
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
int xfer_deliver_iob(struct interface *intf, struct io_buffer *iobuf)
Deliver datagram as I/O buffer without metadata.
Definition: xfer.c:254
#define EBUSY
Device or resource busy.
Definition: errno.h:338
Last Sequence of Exchange.
Definition: fc.h:202
uint8_t seq_id
Active sequence ID.
Definition: fc.c:306
uint16_t seq_cnt
Sequence count.
Definition: fc.h:146
#define XFER_FL_ABS_OFFSET
Offset is absolute.
Definition: xfer.h:47
#define iob_push(iobuf, len)
Definition: iobuf.h:80
uint8_t seq_id
Sequence ID.
Definition: fc.h:142
unsigned int type
Data structure type.
Definition: fc.c:298
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:145
uint16_t seq_cnt
Active sequence count.
Definition: fc.c:308
#define DBGC(...)
Definition: compiler.h:505
Fibre Channel socket address.
Definition: fc.h:47
We have the sequence initiative.
Definition: fc.c:322
uint16_t xchg_id
Local exchange ID.
Definition: fc.c:302
Extended Link Services.
Definition: fc.h:162
uint8_t f_ctl_misc
Frame control - miscellaneous.
Definition: fc.h:140
Last Data Frame of Sequence.
Definition: fc.h:203
Unsolicited Control.
Definition: fc.h:178
We are the exchange originator.
Definition: fc.c:320
A Fibre Channel port.
Definition: fc.h:252
struct fc_port_id s_id
Source ID.
Definition: fc.h:132
#define htonl(value)
Definition: byteswap.h:133
Unsolicited Command.
Definition: fc.h:182
Extended Link Service.
Definition: fc.h:192
#define XFER_FL_RESPONSE
Data content is a response.
Definition: xfer.h:63
#define iob_disown(iobuf)
Disown an I/O buffer.
Definition: iobuf.h:208
void * memcpy(void *dest, const void *src, size_t len) __nonnull
u8 port
Port number.
Definition: CIB_PRM.h:31
struct fc_port_id peer_port_id
Peer port ID.
Definition: fc.c:296
Command Status.
Definition: fc.h:183
uint8_t type
Data structure type.
Definition: fc.h:134
Transfer Sequence Initiative.
Definition: fc.h:204
Unsolicited Data.
Definition: fc.h:180
This is the first sequence of the exchange.
Definition: fc.c:324
#define FC_TIMEOUT
Fibre Channel timeout.
Definition: fc.c:328
Solicited Control.
Definition: fc.h:179
static void * dest
Definition: strings.h:176
int meta(WINDOW *, bool)
Common Transport.
Definition: fc.h:194
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
struct fc_port * port
Fibre Channel port.
Definition: fc.c:291
uint8_t r_ctl
Routing control.
Definition: fc.h:126
uint16_t peer_xchg_id
Peer exchange ID.
Definition: fc.c:304
#define XFER_FL_CMD_STAT
Data content represents a command or status message.
Definition: xfer.h:60
Responder of Exchange.
Definition: fc.h:199
void start_timer_fixed(struct retry_timer *timer, unsigned long timeout)
Start timer with a specified timeout.
Definition: retry.c:64
uint8_t f_ctl_es
Frame control - exchange and sequence.
Definition: fc.h:136
Device Data.
Definition: fc.h:161
struct retry_timer timer
Timeout timer.
Definition: fc.c:311
struct fc_port_id d_id
Destination ID.
Definition: fc.h:128
#define XFER_FL_OVER
Sender is relinquishing use of half-duplex channel.
Definition: xfer.h:50
uint16_t ox_id
Originator exchange ID.
Definition: fc.h:148
Relative Offset Present.
Definition: fc.h:209
#define XFER_FL_OUT
This is the final data transfer.
Definition: xfer.h:53
First Sequence of Exchange.
Definition: fc.h:201
#define htons(value)
Definition: byteswap.h:135
struct bofm_section_header done
Definition: bofm_test.c:46
uint16_t rx_id
Responder exchange ID.
Definition: fc.h:150
uint32_t parameter
Parameter.
Definition: fc.h:156
A Fibre Channel Frame Header.
Definition: fc.h:120
void * memset(void *dest, int character, size_t len) __nonnull

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, port, fc_exchange::port, fc_frame_header::r_ctl, rc, fc_frame_header::rx_id, fc_frame_header::s_id, fc_frame_header::seq_cnt, fc_exchange::seq_cnt, fc_frame_header::seq_id, fc_exchange::seq_id, start_timer_fixed(), strerror(), fc_exchange::timer, fc_frame_header::type, fc_exchange::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()

static 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 ) {
630  xchg->flags |= FC_XCHG_SEQ_INITIATIVE;
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 */
654  start_timer_fixed ( &xchg->timer, FC_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 }
#define iob_pull(iobuf, len)
Definition: iobuf.h:98
struct interface ulp
Upper-layer protocol interface.
Definition: fc.c:314
unsigned int flags
Flags.
Definition: fc.c:300
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
Data transfer metadata.
Definition: xfer.h:22
#define EBUSY
Device or resource busy.
Definition: errno.h:338
Last Sequence of Exchange.
Definition: fc.h:202
uint8_t seq_id
Active sequence ID.
Definition: fc.c:306
uint16_t seq_cnt
Sequence count.
Definition: fc.h:146
#define XFER_FL_ABS_OFFSET
Offset is absolute.
Definition: xfer.h:47
uint8_t seq_id
Sequence ID.
Definition: fc.h:142
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:145
#define EPIPE
Broken pipe.
Definition: errno.h:619
uint16_t seq_cnt
Active sequence count.
Definition: fc.c:308
#define DBGC(...)
Definition: compiler.h:505
Fibre Channel socket address.
Definition: fc.h:47
We have the sequence initiative.
Definition: fc.c:322
#define ntohl(value)
Definition: byteswap.h:134
uint16_t xchg_id
Local exchange ID.
Definition: fc.c:302
#define ntohs(value)
Definition: byteswap.h:136
uint8_t f_ctl_misc
Frame control - miscellaneous.
Definition: fc.h:140
Last Data Frame of Sequence.
Definition: fc.h:203
A Fibre Channel port.
Definition: fc.h:252
struct fc_port_id s_id
Source ID.
Definition: fc.h:132
#define iob_disown(iobuf)
Disown an I/O buffer.
Definition: iobuf.h:208
u8 port
Port number.
Definition: CIB_PRM.h:31
struct sockaddr * fc_fill_sockaddr(struct sockaddr_fc *sa_fc, struct fc_port_id *id)
Fill Fibre Channel socket address.
Definition: fc.c:165
Transfer Sequence Initiative.
Definition: fc.h:204
#define FC_TIMEOUT
Fibre Channel timeout.
Definition: fc.c:328
static void * dest
Definition: strings.h:176
static __always_inline void off_t userptr_t src
Definition: efi_uaccess.h:66
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
struct fc_port * port
Fibre Channel port.
Definition: fc.c:291
#define FC_R_CTL_INFO_MASK
Fibre Channel Routing Control Information mask.
Definition: fc.h:187
uint8_t r_ctl
Routing control.
Definition: fc.h:126
static void fc_xchg_close(struct fc_exchange *xchg, int rc)
Close Fibre Channel exchange.
Definition: fc.c:376
uint16_t peer_xchg_id
Peer exchange ID.
Definition: fc.c:304
int xfer_deliver(struct interface *intf, struct io_buffer *iobuf, struct xfer_metadata *meta)
Deliver datagram.
Definition: xfer.c:193
Responder of Exchange.
Definition: fc.h:199
static unsigned int fc_new_seq_id(void)
Create local Fibre Channel sequence identifier.
Definition: fc.c:348
void start_timer_fixed(struct retry_timer *timer, unsigned long timeout)
Start timer with a specified timeout.
Definition: retry.c:64
uint8_t f_ctl_es
Frame control - exchange and sequence.
Definition: fc.h:136
void * data
Start of data.
Definition: iobuf.h:44
struct retry_timer timer
Timeout timer.
Definition: fc.c:311
struct fc_port_id d_id
Destination ID.
Definition: fc.h:128
#define XFER_FL_OVER
Sender is relinquishing use of half-duplex channel.
Definition: xfer.h:50
uint16_t ox_id
Originator exchange ID.
Definition: fc.h:148
Relative Offset Present.
Definition: fc.h:209
#define XFER_FL_OUT
This is the final data transfer.
Definition: xfer.h:53
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
struct bofm_section_header done
Definition: bofm_test.c:46
uint16_t rx_id
Responder exchange ID.
Definition: fc.h:150
uint32_t parameter
Parameter.
Definition: fc.h:156
A Fibre Channel Frame Header.
Definition: fc.h:120
void * memset(void *dest, int character, size_t len) __nonnull

References fc_frame_header::d_id, io_buffer::data, DBGC, xfer_metadata::dest, 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, xfer_metadata::flags, fc_exchange::flags, free_iob(), iob_disown, iob_pull, memset(), ntohl, ntohs, xfer_metadata::offset, fc_frame_header::ox_id, fc_frame_header::parameter, fc_exchange::peer_xchg_id, port, fc_exchange::port, fc_frame_header::r_ctl, rc, fc_frame_header::rx_id, fc_frame_header::s_id, fc_frame_header::seq_cnt, fc_exchange::seq_cnt, fc_frame_header::seq_id, fc_exchange::seq_id, xfer_metadata::src, 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()

static 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 );
708  memcpy ( &xchg->peer_port_id, peer_port_id,
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 }
struct interface ulp
Upper-layer protocol interface.
Definition: fc.c:314
static struct interface_descriptor fc_xchg_ulp_desc
Fibre Channel exchange ULP interface descriptor.
Definition: fc.c:685
uint8_t seq_id
Active sequence ID.
Definition: fc.c:306
static unsigned int fc_new_xchg_id(void)
Create local Fibre Channel exchange identifier.
Definition: fc.c:335
#define list_add(new, head)
Add a new entry to the head of a list.
Definition: list.h:69
#define ref_init(refcnt, free)
Initialise a reference counter.
Definition: refcnt.h:64
unsigned int type
Data structure type.
Definition: fc.c:298
struct refcnt refcnt
Reference count.
Definition: fc.c:289
uint8_t type
Type.
Definition: ena.h:16
uint16_t xchg_id
Local exchange ID.
Definition: fc.c:302
void * memcpy(void *dest, const void *src, size_t len) __nonnull
u8 port
Port number.
Definition: CIB_PRM.h:31
struct fc_port_id peer_port_id
Peer port ID.
Definition: fc.c:296
static void fc_xchg_free(struct refcnt *refcnt)
Free Fibre Channel exchange.
Definition: fc.c:359
A Fibre Channel exchange.
Definition: fc.c:287
struct fc_port * port
Fibre Channel port.
Definition: fc.c:291
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:624
uint16_t peer_xchg_id
Peer exchange ID.
Definition: fc.c:304
static unsigned int fc_new_seq_id(void)
Create local Fibre Channel sequence identifier.
Definition: fc.c:348
static struct fc_port * fc_port_get(struct fc_port *port)
Get reference to Fibre Channel port.
Definition: fc.h:304
#define FC_RX_ID_UNKNOWN
Responder exchange identifier used before first response.
Definition: fc.h:213
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
static void intf_init(struct interface *intf, struct interface_descriptor *desc, struct refcnt *refcnt)
Initialise an object interface.
Definition: interface.h:173
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
static void fc_xchg_expired(struct retry_timer *timer, int over __unused)
Handle exchange timeout.
Definition: fc.c:406

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, port, fc_exchange::port, ref_init, fc_exchange::refcnt, fc_exchange::seq_id, fc_exchange::timer, type, fc_exchange::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 */
733  xchg = fc_xchg_create ( port, peer_port_id, type );
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 }
struct interface ulp
Upper-layer protocol interface.
Definition: fc.c:314
unsigned int flags
Flags.
Definition: fc.c:300
const char * fc_id_ntoa(const struct fc_port_id *id)
Format Fibre Channel port ID.
Definition: fc.c:92
unsigned int type
Data structure type.
Definition: fc.c:298
uint8_t type
Type.
Definition: ena.h:16
void intf_plug_plug(struct interface *a, struct interface *b)
Plug two object interfaces together.
Definition: interface.c:102
We have the sequence initiative.
Definition: fc.c:322
uint16_t xchg_id
Local exchange ID.
Definition: fc.c:302
We are the exchange originator.
Definition: fc.c:320
#define ENOMEM
Not enough space.
Definition: errno.h:534
u8 port
Port number.
Definition: CIB_PRM.h:31
struct fc_port_id peer_port_id
Peer port ID.
Definition: fc.c:296
A Fibre Channel exchange.
Definition: fc.c:287
This is the first sequence of the exchange.
Definition: fc.c:324
#define DBGC2(...)
Definition: compiler.h:522
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

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, type, fc_exchange::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()

static 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 }
struct interface ulp
Upper-layer protocol interface.
Definition: fc.c:314
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
uint8_t seq_id
Active sequence ID.
Definition: fc.c:306
const char * fc_id_ntoa(const struct fc_port_id *id)
Format Fibre Channel port ID.
Definition: fc.c:92
uint8_t seq_id
Sequence ID.
Definition: fc.h:142
unsigned int type
Data structure type.
Definition: fc.c:298
unsigned int type
Type.
Definition: fc.h:224
uint8_t type
Type.
Definition: ena.h:16
A Fibre Channel responder.
Definition: fc.h:222
#define DBGC(...)
Definition: compiler.h:505
uint16_t xchg_id
Local exchange ID.
Definition: fc.c:302
#define ntohs(value)
Definition: byteswap.h:136
struct fc_port_id s_id
Source ID.
Definition: fc.h:132
#define FC_RESPONDERS
Fibre Channel responder table.
Definition: fc.h:239
u8 port
Port number.
Definition: CIB_PRM.h:31
struct fc_port_id peer_port_id
Peer port ID.
Definition: fc.c:296
uint8_t type
Data structure type.
Definition: fc.h:134
A Fibre Channel exchange.
Definition: fc.c:287
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:233
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
#define for_each_table_entry(pointer, table)
Iterate through all entries within a linker table.
Definition: tables.h:358
#define DBGC2(...)
Definition: compiler.h:522
struct fc_port_id d_id
Destination ID.
Definition: fc.h:128
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
uint16_t ox_id
Originator exchange ID.
Definition: fc.h:148
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362

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_frame_header::seq_id, fc_exchange::seq_id, strerror(), type, fc_frame_header::type, fc_responder::type, fc_exchange::type, fc_exchange::ulp, and fc_exchange::xchg_id.

Referenced by fc_port_deliver().

◆ fc_port_close()

static 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 ) )
814  fc_port_logout ( port, rc );
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 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
void intf_shutdown(struct interface *intf, int rc)
Shut down an object interface.
Definition: interface.c:273
#define DBGC(...)
Definition: compiler.h:505
#define list_del(list)
Delete an entry from a list.
Definition: list.h:119
u8 port
Port number.
Definition: CIB_PRM.h:31
static int fc_link_ok(struct fc_link_state *link)
Check Fibre Channel link state.
Definition: fc.h:108
A Fibre Channel exchange.
Definition: fc.c:287
#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:447
uint8_t * tmp
Definition: entropy.h:156
static void fc_xchg_close(struct fc_exchange *xchg, int rc)
Close Fibre Channel exchange.
Definition: fc.c:376
static void fc_link_stop(struct fc_link_state *link)
Stop monitoring Fibre Channel link state.
Definition: fc.c:275
#define INIT_LIST_HEAD(list)
Initialise a list head.
Definition: list.h:45
void fc_port_logout(struct fc_port *port, int rc)
Log out Fibre Channel port.
Definition: fc.c:1039
struct list_head list
List of active exchanges within this port.
Definition: fc.c:293

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

static 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 }
uint16_t xchg_id
Local exchange ID.
Definition: fc.c:302
u8 port
Port number.
Definition: CIB_PRM.h:31
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition: list.h:420
A Fibre Channel exchange.
Definition: fc.c:287
struct list_head list
List of active exchanges within this port.
Definition: fc.c:293
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362

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

Referenced by fc_port_deliver().

◆ fc_port_deliver()

static 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 = iobuf->data;
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 
874  /* Verify local port ID */
875  if ( ( memcmp ( &fchdr->d_id, &port->port_id,
876  sizeof ( fchdr->d_id ) ) != 0 ) &&
877  ( memcmp ( &fchdr->d_id, &fc_f_port_id,
878  sizeof ( fchdr->d_id ) ) != 0 ) &&
879  ( memcmp ( &port->port_id, &fc_empty_port_id,
880  sizeof ( port->port_id ) ) != 0 ) ) {
881  DBGC ( port, "FCPORT %s received frame for incorrect port ID "
882  "%s\n", port->name, fc_id_ntoa ( &fchdr->d_id ) );
883  rc = -ENOTCONN;
884  goto err_port_id;
885  }
886 
887  /* Demultiplex amongst active exchanges */
888  xchg_id = ntohs ( ( fchdr->f_ctl_es & FC_F_CTL_ES_RESPONDER ) ?
889  fchdr->ox_id : fchdr->rx_id );
890  xchg = fc_port_demux ( port, xchg_id );
891 
892  /* If we have no active exchange and this frame starts a new
893  * exchange, try to create a new responder exchange
894  */
895  if ( ( fchdr->f_ctl_es & FC_F_CTL_ES_FIRST ) &&
896  ( fchdr->seq_cnt == 0 ) ) {
897 
898  /* Create new exchange */
899  xchg = fc_xchg_respond ( port, fchdr );
900  if ( ! xchg ) {
901  DBGC ( port, "FCPORT %s cannot create new exchange\n",
902  port->name );
903  rc = -ENOMEM;
904  goto err_respond;
905  }
906  }
907 
908  /* Fail if no exchange exists */
909  if ( ! xchg ) {
910  DBGC ( port, "FCPORT %s xchg %04x unknown\n",
911  port->name, xchg_id );
912  rc = -ENOTCONN;
913  goto err_no_xchg;
914  }
915 
916  /* Pass received frame to exchange */
917  ref_get ( &xchg->refcnt );
918  if ( ( rc = fc_xchg_rx ( xchg, iob_disown ( iobuf ), meta ) ) != 0 )
919  goto err_xchg_rx;
920 
921  err_xchg_rx:
922  ref_put ( &xchg->refcnt );
923  err_no_xchg:
924  err_respond:
925  err_port_id:
926  err_sanity:
927  free_iob ( iobuf );
928  return rc;
929 }
#define EINVAL
Invalid argument.
Definition: errno.h:428
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
const char * fc_id_ntoa(const struct fc_port_id *id)
Format Fibre Channel port ID.
Definition: fc.c:92
uint16_t seq_cnt
Sequence count.
Definition: fc.h:146
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:145
struct refcnt refcnt
Reference count.
Definition: fc.c:289
struct fc_port_id fc_f_port_id
F_Port contoller port ID.
Definition: fc.c:68
#define DBGC(...)
Definition: compiler.h:505
uint16_t xchg_id
Local exchange ID.
Definition: fc.c:302
#define ntohs(value)
Definition: byteswap.h:136
#define ENOMEM
Not enough space.
Definition: errno.h:534
#define iob_disown(iobuf)
Disown an I/O buffer.
Definition: iobuf.h:208
u8 port
Port number.
Definition: CIB_PRM.h:31
A Fibre Channel exchange.
Definition: fc.c:287
int meta(WINDOW *, bool)
struct fc_port_id fc_empty_port_id
Unassigned port ID.
Definition: fc.c:65
#define ENOTCONN
The socket is not connected.
Definition: errno.h:569
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
#define ref_get(refcnt)
Get additional reference to object.
Definition: refcnt.h:92
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:151
Responder of Exchange.
Definition: fc.h:199
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
uint8_t f_ctl_es
Frame control - exchange and sequence.
Definition: fc.h:136
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
void * data
Start of data.
Definition: iobuf.h:44
struct fc_port_id d_id
Destination ID.
Definition: fc.h:128
uint16_t ox_id
Originator exchange ID.
Definition: fc.h:148
First Sequence of Exchange.
Definition: fc.h:201
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition: string.c:98
uint16_t rx_id
Responder exchange ID.
Definition: fc.h:150
#define ref_put(refcnt)
Drop reference to object.
Definition: refcnt.h:106
A Fibre Channel Frame Header.
Definition: fc.h:120

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 941 of file fc.c.

943  {
944  struct fc_peer *peer;
945  struct fc_peer *tmp;
946  int rc;
947 
948  /* Perform implicit logout if logged in and details differ */
949  if ( fc_link_ok ( &port->link ) &&
950  ( ( ( !! ( port->flags & FC_PORT_HAS_FABRIC ) ) !=
951  ( !! has_fabric ) ) ||
952  ( memcmp ( &port->link_node_wwn, link_node_wwn,
953  sizeof ( port->link_node_wwn ) ) != 0 ) ||
954  ( memcmp ( &port->link_port_wwn, link_port_wwn,
955  sizeof ( port->link_port_wwn ) ) != 0 ) ||
956  ( has_fabric &&
957  ( memcmp ( &port->port_id, port_id,
958  sizeof ( port->port_id ) ) != 0 ) ) ) ) {
959  fc_port_logout ( port, 0 );
960  }
961 
962  /* Log in, if applicable */
963  if ( ! fc_link_ok ( &port->link ) ) {
964 
965  /* Record link port name */
966  memcpy ( &port->link_node_wwn, link_node_wwn,
967  sizeof ( port->link_node_wwn ) );
968  memcpy ( &port->link_port_wwn, link_port_wwn,
969  sizeof ( port->link_port_wwn ) );
970  DBGC ( port, "FCPORT %s logged in to %s",
971  port->name, fc_ntoa ( &port->link_node_wwn ) );
972  DBGC ( port, " port %s\n", fc_ntoa ( &port->link_port_wwn ) );
973 
974  /* Calculate local (and possibly remote) port IDs */
975  if ( has_fabric ) {
976  port->flags |= FC_PORT_HAS_FABRIC;
977  memcpy ( &port->port_id, port_id,
978  sizeof ( port->port_id ) );
979  } else {
980  port->flags &= ~FC_PORT_HAS_FABRIC;
981  if ( memcmp ( &port->port_wwn, link_port_wwn,
982  sizeof ( port->port_wwn ) ) > 0 ) {
983  memcpy ( &port->port_id, &fc_ptp_high_port_id,
984  sizeof ( port->port_id ) );
985  memcpy ( &port->ptp_link_port_id,
987  sizeof ( port->ptp_link_port_id ) );
988  } else {
989  memcpy ( &port->port_id, &fc_ptp_low_port_id,
990  sizeof ( port->port_id ) );
991  memcpy ( &port->ptp_link_port_id,
993  sizeof ( port->ptp_link_port_id ) );
994  }
995  }
996  DBGC ( port, "FCPORT %s logged in via a %s, with local ID "
997  "%s\n", port->name,
998  ( ( port->flags & FC_PORT_HAS_FABRIC ) ?
999  "fabric" : "point-to-point link" ),
1000  fc_id_ntoa ( &port->port_id ) );
1001  }
1002 
1003  /* Log in to name server, if attached to a fabric */
1004  if ( has_fabric && ! ( port->flags & FC_PORT_HAS_NS ) ) {
1005 
1006  DBGC ( port, "FCPORT %s attempting login to name server\n",
1007  port->name );
1008 
1009  intf_restart ( &port->ns_plogi, -ECANCELED );
1010  if ( ( rc = fc_els_plogi ( &port->ns_plogi, port,
1011  &fc_gs_port_id ) ) != 0 ) {
1012  DBGC ( port, "FCPORT %s could not initiate name "
1013  "server PLOGI: %s\n",
1014  port->name, strerror ( rc ) );
1015  fc_port_logout ( port, rc );
1016  return rc;
1017  }
1018  }
1019 
1020  /* Record login */
1021  fc_link_up ( &port->link );
1022 
1023  /* Notify peers of link state change */
1024  list_for_each_entry_safe ( peer, tmp, &fc_peers, list ) {
1025  fc_peer_get ( peer );
1026  fc_link_examine ( &peer->link );
1027  fc_peer_put ( peer );
1028  }
1029 
1030  return 0;
1031 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
void intf_restart(struct interface *intf, int rc)
Shut down and restart an object interface.
Definition: interface.c:337
struct fc_port_id fc_ptp_high_port_id
Point-to-point high port ID.
Definition: fc.c:77
struct list_head fc_peers
const char * fc_id_ntoa(const struct fc_port_id *id)
Format Fibre Channel port ID.
Definition: fc.c:92
static void fc_link_examine(struct fc_link_state *link)
Examine Fibre Channel link state.
Definition: fc.c:226
struct fc_port_id fc_ptp_low_port_id
Point-to-point low port ID.
Definition: fc.c:74
#define DBGC(...)
Definition: compiler.h:505
const char * fc_ntoa(const struct fc_name *wwn)
Format Fibre Channel WWN.
Definition: fc.c:127
int fc_els_plogi(struct interface *parent, struct fc_port *port, struct fc_port_id *peer_port_id)
Create PLOGI request.
Definition: fcels.c:733
#define ECANCELED
Operation canceled.
Definition: errno.h:343
void * memcpy(void *dest, const void *src, size_t len) __nonnull
u8 port
Port number.
Definition: CIB_PRM.h:31
Port is attached to a fabric.
Definition: fc.h:292
static int fc_link_ok(struct fc_link_state *link)
Check Fibre Channel link state.
Definition: fc.h:108
struct fc_link_state link
Link state monitor.
Definition: fc.h:350
struct list_head list
List of all peers.
Definition: fc.h:344
#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:447
struct fc_port_id port_id
Peer port ID, if known.
Definition: fc.h:356
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
static void fc_peer_put(struct fc_peer *peer)
Drop reference to Fibre Channel peer.
Definition: fc.h:390
Port is logged in to a name server.
Definition: fc.h:294
uint8_t * tmp
Definition: entropy.h:156
static struct fc_peer * fc_peer_get(struct fc_peer *peer)
Get reference to Fibre Channel peer.
Definition: fc.h:379
A Fibre Channel peer.
Definition: fc.h:340
static void fc_link_up(struct fc_link_state *link)
Mark Fibre Channel link as up.
Definition: fc.c:195
void fc_port_logout(struct fc_port *port, int rc)
Log out Fibre Channel port.
Definition: fc.c:1039
struct fc_port_id fc_gs_port_id
Generic services port ID.
Definition: fc.c:71
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition: string.c:98

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::link, fc_peer::list, list_for_each_entry_safe, memcmp(), memcpy(), 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 1039 of file fc.c.

1039  {
1040  struct fc_peer *peer;
1041  struct fc_peer *tmp;
1042 
1043  DBGC ( port, "FCPORT %s logged out: %s\n",
1044  port->name, strerror ( rc ) );
1045 
1046  /* Erase port details */
1047  memset ( &port->port_id, 0, sizeof ( port->port_id ) );
1048  port->flags = 0;
1049 
1050  /* Record logout */
1051  fc_link_err ( &port->link, rc );
1052 
1053  /* Notify peers of link state change */
1054  list_for_each_entry_safe ( peer, tmp, &fc_peers, list ) {
1055  fc_peer_get ( peer );
1056  fc_link_examine ( &peer->link );
1057  fc_peer_put ( peer );
1058  }
1059 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
struct list_head fc_peers
static void fc_link_examine(struct fc_link_state *link)
Examine Fibre Channel link state.
Definition: fc.c:226
#define DBGC(...)
Definition: compiler.h:505
static void fc_link_err(struct fc_link_state *link, int rc)
Mark Fibre Channel link as down.
Definition: fc.c:210
u8 port
Port number.
Definition: CIB_PRM.h:31
struct fc_link_state link
Link state monitor.
Definition: fc.h:350
struct list_head list
List of all peers.
Definition: fc.h:344
#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:447
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
static void fc_peer_put(struct fc_peer *peer)
Drop reference to Fibre Channel peer.
Definition: fc.h:390
uint8_t * tmp
Definition: entropy.h:156
static struct fc_peer * fc_peer_get(struct fc_peer *peer)
Get reference to Fibre Channel peer.
Definition: fc.h:379
A Fibre Channel peer.
Definition: fc.h:340
void * memset(void *dest, int character, size_t len) __nonnull

References DBGC, fc_link_err(), fc_link_examine(), fc_peer_get(), fc_peer_put(), fc_peers, fc_peer::link, fc_peer::list, list_for_each_entry_safe, memset(), 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()

static 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 1067 of file fc.c.

1067  {
1068 
1069  intf_restart ( &port->flogi, rc );
1070 
1071  if ( rc != 0 )
1072  fc_port_logout ( port, rc );
1073 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
void intf_restart(struct interface *intf, int rc)
Shut down and restart an object interface.
Definition: interface.c:337
u8 port
Port number.
Definition: CIB_PRM.h:31
void fc_port_logout(struct fc_port *port, int rc)
Log out Fibre Channel port.
Definition: fc.c:1039

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

◆ fc_port_ns_plogi_done()

static 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 1081 of file fc.c.

1081  {
1082 
1083  intf_restart ( &port->ns_plogi, rc );
1084 
1085  if ( rc == 0 ) {
1086  port->flags |= FC_PORT_HAS_NS;
1087  DBGC ( port, "FCPORT %s logged in to name server\n",
1088  port->name );
1089  } else {
1090  DBGC ( port, "FCPORT %s could not log in to name server: %s\n",
1091  port->name, strerror ( rc ) );
1092  /* Absence of a name server is not a fatal error */
1093  }
1094 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
void intf_restart(struct interface *intf, int rc)
Shut down and restart an object interface.
Definition: interface.c:337
#define DBGC(...)
Definition: compiler.h:505
u8 port
Port number.
Definition: CIB_PRM.h:31
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
Port is logged in to a name server.
Definition: fc.h:294

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

◆ fc_port_examine()

static 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 1101 of file fc.c.

1101  {
1102  struct fc_port *port = container_of ( link, struct fc_port, link );
1103  int rc;
1104 
1105  /* Do nothing if already logged in */
1106  if ( fc_link_ok ( &port->link ) )
1107  return;
1108 
1109  DBGC ( port, "FCPORT %s attempting login\n", port->name );
1110 
1111  /* Try to create FLOGI ELS */
1112  intf_restart ( &port->flogi, -ECANCELED );
1113  if ( ( rc = fc_els_flogi ( &port->flogi, port ) ) != 0 ) {
1114  DBGC ( port, "FCPORT %s could not initiate FLOGI: %s\n",
1115  port->name, strerror ( rc ) );
1116  fc_port_logout ( port, rc );
1117  return;
1118  }
1119 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
void intf_restart(struct interface *intf, int rc)
Shut down and restart an object interface.
Definition: interface.c:337
#define DBGC(...)
Definition: compiler.h:505
A Fibre Channel port.
Definition: fc.h:252
#define ECANCELED
Operation canceled.
Definition: errno.h:343
u8 port
Port number.
Definition: CIB_PRM.h:31
int fc_els_flogi(struct interface *parent, struct fc_port *port)
Create FLOGI request.
Definition: fcels.c:581
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
static int fc_link_ok(struct fc_link_state *link)
Check Fibre Channel link state.
Definition: fc.h:108
u32 link
Link to next descriptor.
Definition: ar9003_mac.h:68
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
void fc_port_logout(struct fc_port *port, int rc)
Log out Fibre Channel port.
Definition: fc.c:1039

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

static void fc_port_window_changed ( struct fc_port port)
static

Handle change of flow control window.

Parameters
portFibre Channel port

Definition at line 1126 of file fc.c.

1126  {
1127  size_t window;
1128 
1129  /* Check if transport layer is ready */
1130  window = xfer_window ( &port->transport );
1131  if ( window > 0 ) {
1132 
1133  /* Transport layer is ready. Start login if the link
1134  * is not already up.
1135  */
1136  if ( ! fc_link_ok ( &port->link ) )
1137  fc_link_start ( &port->link );
1138 
1139  } else {
1140 
1141  /* Transport layer is not ready. Log out port and
1142  * wait for transport layer before attempting log in
1143  * again.
1144  */
1146  fc_link_stop ( &port->link );
1147  }
1148 }
size_t xfer_window(struct interface *intf)
Check flow control window.
Definition: xfer.c:115
u8 port
Port number.
Definition: CIB_PRM.h:31
static int fc_link_ok(struct fc_link_state *link)
Check Fibre Channel link state.
Definition: fc.h:108
#define ENOTCONN
The socket is not connected.
Definition: errno.h:569
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:1039
static void fc_link_start(struct fc_link_state *link)
Start monitoring Fibre Channel link state.
Definition: fc.c:266

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 1189 of file fc.c.

1190  {
1191  struct fc_port *port;
1192 
1193  /* Allocate and initialise structure */
1194  port = zalloc ( sizeof ( *port ) );
1195  if ( ! port )
1196  return -ENOMEM;
1197  ref_init ( &port->refcnt, NULL );
1198  intf_init ( &port->transport, &fc_port_transport_desc, &port->refcnt );
1199  fc_link_init ( &port->link, fc_port_examine, &port->refcnt );
1200  intf_init ( &port->flogi, &fc_port_flogi_desc, &port->refcnt );
1201  intf_init ( &port->ns_plogi, &fc_port_ns_plogi_desc, &port->refcnt );
1202  list_add_tail ( &port->list, &fc_ports );
1203  INIT_LIST_HEAD ( &port->xchgs );
1204  memcpy ( &port->node_wwn, node_wwn, sizeof ( port->node_wwn ) );
1205  memcpy ( &port->port_wwn, port_wwn, sizeof ( port->port_wwn ) );
1206  snprintf ( port->name, sizeof ( port->name ), "%s", name );
1207 
1208  DBGC ( port, "FCPORT %s opened as %s",
1209  port->name, fc_ntoa ( &port->node_wwn ) );
1210  DBGC ( port, " port %s\n", fc_ntoa ( &port->port_wwn ) );
1211 
1212  /* Attach to transport layer, mortalise self, and return */
1213  intf_plug_plug ( &port->transport, transport );
1214  ref_put ( &port->refcnt );
1215  return 0;
1216 }
struct fc_name port_wwn
Port name.
Definition: fc.h:265
static void fc_port_examine(struct fc_link_state *link)
Examine Fibre Channel port link state.
Definition: fc.c:1101
const char * name
Definition: ath9k_hw.c:1984
#define ref_init(refcnt, free)
Initialise a reference counter.
Definition: refcnt.h:64
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
#define DBGC(...)
Definition: compiler.h:505
struct fc_name node_wwn
Node name.
Definition: fc.h:263
void intf_plug_plug(struct interface *a, struct interface *b)
Plug two object interfaces together.
Definition: interface.c:102
const char * fc_ntoa(const struct fc_name *wwn)
Format Fibre Channel WWN.
Definition: fc.c:127
struct list_head fc_ports
A Fibre Channel port.
Definition: fc.h:252
#define ENOMEM
Not enough space.
Definition: errno.h:534
void * memcpy(void *dest, const void *src, size_t len) __nonnull
u8 port
Port number.
Definition: CIB_PRM.h:31
static struct interface_descriptor fc_port_flogi_desc
Fibre Channel port FLOGI interface descriptor.
Definition: fc.c:1168
#define list_add_tail(new, head)
Add a new entry to the tail of a list.
Definition: list.h:93
static struct interface_descriptor fc_port_ns_plogi_desc
Fibre Channel port name server PLOGI interface descriptor.
Definition: fc.c:1177
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:624
#define INIT_LIST_HEAD(list)
Initialise a list head.
Definition: list.h:45
struct interface transport
Transport interface.
Definition: fc.h:261
int snprintf(char *buf, size_t size, const char *fmt,...)
Write a formatted string to a buffer.
Definition: vsprintf.c:382
static void intf_init(struct interface *intf, struct interface_descriptor *desc, struct refcnt *refcnt)
Initialise an object interface.
Definition: interface.h:173
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
static struct interface_descriptor fc_port_transport_desc
Fibre Channel port transport interface descriptor.
Definition: fc.c:1159
#define ref_put(refcnt)
Drop reference to object.
Definition: refcnt.h:106

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 1224 of file fc.c.

1224  {
1225  struct fc_port *port;
1226 
1228  if ( strcmp ( name, port->name ) == 0 )
1229  return port;
1230  }
1231  return NULL;
1232 }
const char * name
Definition: ath9k_hw.c:1984
struct list_head list
List of all ports.
Definition: fc.h:256
struct list_head fc_ports
A Fibre Channel port.
Definition: fc.h:252
u8 port
Port number.
Definition: CIB_PRM.h:31
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition: list.h:420
int strcmp(const char *first, const char *second)
Compare strings.
Definition: string.c:157
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362

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

Referenced by parse_fc_port().

◆ fc_peer_close()

static 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 1247 of file fc.c.

1247  {
1248 
1249  DBGC ( peer, "FCPEER %s closed: %s\n",
1250  fc_ntoa ( &peer->port_wwn ) , strerror ( rc ) );
1251 
1252  /* Sanity check */
1253  assert ( list_empty ( &peer->ulps ) );
1254 
1255  /* Stop link timer */
1256  fc_link_stop ( &peer->link );
1257 
1258  /* Shut down interfaces */
1259  intf_shutdown ( &peer->plogi, rc );
1260 
1261  /* Remove from list of peers */
1262  list_del ( &peer->list );
1263  INIT_LIST_HEAD ( &peer->list );
1264 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
void intf_shutdown(struct interface *intf, int rc)
Shut down an object interface.
Definition: interface.c:273
#define DBGC(...)
Definition: compiler.h:505
const char * fc_ntoa(const struct fc_name *wwn)
Format Fibre Channel WWN.
Definition: fc.c:127
#define list_empty(list)
Test whether a list is empty.
Definition: list.h:136
#define list_del(list)
Delete an entry from a list.
Definition: list.h:119
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
struct list_head ulps
List of upper-layer protocols.
Definition: fc.h:359
struct fc_link_state link
Link state monitor.
Definition: fc.h:350
struct list_head list
List of all peers.
Definition: fc.h:344
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
struct fc_name port_wwn
Port name.
Definition: fc.h:347
static void fc_link_stop(struct fc_link_state *link)
Stop monitoring Fibre Channel link state.
Definition: fc.c:275
struct interface plogi
PLOGI interface.
Definition: fc.h:352
#define INIT_LIST_HEAD(list)
Initialise a list head.
Definition: list.h:45

References assert(), DBGC, fc_link_stop(), fc_ntoa(), INIT_LIST_HEAD, intf_shutdown(), fc_peer::link, fc_peer::list, list_del, list_empty, fc_peer::plogi, fc_peer::port_wwn, rc, strerror(), and fc_peer::ulps.

Referenced by fc_peer_logout().

◆ fc_peer_increment()

static void fc_peer_increment ( struct fc_peer peer)
static

Increment Fibre Channel peer active usage count.

Parameters
peerFibre Channel peer

Definition at line 1271 of file fc.c.

1271  {
1272 
1273  /* Increment our usage count */
1274  peer->usage++;
1275 }
unsigned int usage
Active usage count.
Definition: fc.h:369

References fc_peer::usage.

Referenced by fc_ulp_attach().

◆ fc_peer_decrement()

static void fc_peer_decrement ( struct fc_peer peer)
static

Decrement Fibre Channel peer active usage count.

Parameters
peerFibre Channel peer

Definition at line 1282 of file fc.c.

1282  {
1283 
1284  /* Sanity check */
1285  assert ( peer->usage > 0 );
1286 
1287  /* Decrement our usage count and log out if we reach zero */
1288  if ( --(peer->usage) == 0 )
1289  fc_peer_logout ( peer, 0 );
1290 }
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
unsigned int usage
Active usage count.
Definition: fc.h:369
void fc_peer_logout(struct fc_peer *peer, int rc)
Log out Fibre Channel peer.
Definition: fc.c:1347

References assert(), fc_peer_logout(), and fc_peer::usage.

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 1300 of file fc.c.

1301  {
1302  struct fc_ulp *ulp;
1303  struct fc_ulp *tmp;
1304 
1305  /* Perform implicit logout if logged in and details differ */
1306  if ( fc_link_ok ( &peer->link ) &&
1307  ( ( peer->port != port ) ||
1308  ( memcmp ( &peer->port_id, port_id,
1309  sizeof ( peer->port_id ) ) !=0 ) ) ) {
1310  fc_peer_logout ( peer, 0 );
1311  }
1312 
1313  /* Log in, if applicable */
1314  if ( ! fc_link_ok ( &peer->link ) ) {
1315 
1316  /* Record peer details */
1317  assert ( peer->port == NULL );
1318  peer->port = fc_port_get ( port );
1319  memcpy ( &peer->port_id, port_id, sizeof ( peer->port_id ) );
1320  DBGC ( peer, "FCPEER %s logged in via %s as %s\n",
1321  fc_ntoa ( &peer->port_wwn ), peer->port->name,
1322  fc_id_ntoa ( &peer->port_id ) );
1323 
1324  /* Add login reference */
1325  fc_peer_get ( peer );
1326  }
1327 
1328  /* Record login */
1329  fc_link_up ( &peer->link );
1330 
1331  /* Notify ULPs of link state change */
1332  list_for_each_entry_safe ( ulp, tmp, &peer->ulps, list ) {
1333  fc_ulp_get ( ulp );
1334  fc_link_examine ( &ulp->link );
1335  fc_ulp_put ( ulp );
1336  }
1337 
1338  return 0;
1339 }
char name[8]
Name of this port.
Definition: fc.h:258
const char * fc_id_ntoa(const struct fc_port_id *id)
Format Fibre Channel port ID.
Definition: fc.c:92
static void fc_link_examine(struct fc_link_state *link)
Examine Fibre Channel link state.
Definition: fc.c:226
#define DBGC(...)
Definition: compiler.h:505
struct list_head list
List of upper-layer protocols.
Definition: fc.h:419
const char * fc_ntoa(const struct fc_name *wwn)
Format Fibre Channel WWN.
Definition: fc.c:127
struct fc_peer * peer
Fibre Channel peer.
Definition: fc.h:417
struct fc_port * port
Fibre Channel port, if known.
Definition: fc.h:354
void * memcpy(void *dest, const void *src, size_t len) __nonnull
u8 port
Port number.
Definition: CIB_PRM.h:31
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
struct list_head ulps
List of upper-layer protocols.
Definition: fc.h:359
static int fc_link_ok(struct fc_link_state *link)
Check Fibre Channel link state.
Definition: fc.h:108
struct fc_link_state link
Link state monitor.
Definition: fc.h:350
#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:447
struct fc_port_id port_id
Peer port ID, if known.
Definition: fc.h:356
static struct fc_ulp * fc_ulp_get(struct fc_ulp *ulp)
Get reference to Fibre Channel upper-layer protocol.
Definition: fc.h:474
uint8_t * tmp
Definition: entropy.h:156
struct fc_link_state link
Link state monitor.
Definition: fc.h:427
void fc_peer_logout(struct fc_peer *peer, int rc)
Log out Fibre Channel peer.
Definition: fc.c:1347
struct fc_name port_wwn
Port name.
Definition: fc.h:347
static struct fc_peer * fc_peer_get(struct fc_peer *peer)
Get reference to Fibre Channel peer.
Definition: fc.h:379
static struct fc_port * fc_port_get(struct fc_port *port)
Get reference to Fibre Channel port.
Definition: fc.h:304
static void fc_link_up(struct fc_link_state *link)
Mark Fibre Channel link as up.
Definition: fc.c:195
static void fc_ulp_put(struct fc_ulp *ulp)
Drop reference to Fibre Channel upper-layer protocol.
Definition: fc.h:485
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition: string.c:98
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
A Fibre Channel upper-layer protocol.
Definition: fc.h:413

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_peer::link, fc_ulp::link, fc_ulp::list, list_for_each_entry_safe, memcmp(), memcpy(), fc_port::name, NULL, fc_ulp::peer, port, fc_peer::port, fc_peer::port_id, fc_peer::port_wwn, tmp, and fc_peer::ulps.

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 1347 of file fc.c.

1347  {
1348  struct fc_ulp *ulp;
1349  struct fc_ulp *tmp;
1350 
1351  DBGC ( peer, "FCPEER %s logged out: %s\n",
1352  fc_ntoa ( &peer->port_wwn ), strerror ( rc ) );
1353 
1354  /* Drop login reference, if applicable */
1355  if ( fc_link_ok ( &peer->link ) )
1356  fc_peer_put ( peer );
1357 
1358  /* Erase peer details */
1359  fc_port_put ( peer->port );
1360  peer->port = NULL;
1361 
1362  /* Record logout */
1363  fc_link_err ( &peer->link, rc );
1364 
1365  /* Notify ULPs of link state change */
1366  list_for_each_entry_safe ( ulp, tmp, &peer->ulps, list ) {
1367  fc_ulp_get ( ulp );
1368  fc_link_examine ( &ulp->link );
1369  fc_ulp_put ( ulp );
1370  }
1371 
1372  /* Close peer if there are no active users */
1373  if ( peer->usage == 0 )
1374  fc_peer_close ( peer, rc );
1375 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
static void fc_link_examine(struct fc_link_state *link)
Examine Fibre Channel link state.
Definition: fc.c:226
#define DBGC(...)
Definition: compiler.h:505
struct list_head list
List of upper-layer protocols.
Definition: fc.h:419
static void fc_port_put(struct fc_port *port)
Drop reference to Fibre Channel port.
Definition: fc.h:315
const char * fc_ntoa(const struct fc_name *wwn)
Format Fibre Channel WWN.
Definition: fc.c:127
static void fc_link_err(struct fc_link_state *link, int rc)
Mark Fibre Channel link as down.
Definition: fc.c:210
struct fc_peer * peer
Fibre Channel peer.
Definition: fc.h:417
struct fc_port * port
Fibre Channel port, if known.
Definition: fc.h:354
struct list_head ulps
List of upper-layer protocols.
Definition: fc.h:359
static int fc_link_ok(struct fc_link_state *link)
Check Fibre Channel link state.
Definition: fc.h:108
struct fc_link_state link
Link state monitor.
Definition: fc.h:350
unsigned int usage
Active usage count.
Definition: fc.h:369
#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:447
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
static void fc_peer_put(struct fc_peer *peer)
Drop reference to Fibre Channel peer.
Definition: fc.h:390
static struct fc_ulp * fc_ulp_get(struct fc_ulp *ulp)
Get reference to Fibre Channel upper-layer protocol.
Definition: fc.h:474
uint8_t * tmp
Definition: entropy.h:156
struct fc_link_state link
Link state monitor.
Definition: fc.h:427
struct fc_name port_wwn
Port name.
Definition: fc.h:347
static void fc_peer_close(struct fc_peer *peer, int rc)
Close Fibre Channel peer.
Definition: fc.c:1247
static void fc_ulp_put(struct fc_ulp *ulp)
Drop reference to Fibre Channel upper-layer protocol.
Definition: fc.h:485
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
A Fibre Channel upper-layer protocol.
Definition: fc.h:413

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_peer::link, fc_ulp::link, fc_ulp::list, list_for_each_entry_safe, NULL, fc_ulp::peer, fc_peer::port, fc_peer::port_wwn, rc, strerror(), tmp, fc_peer::ulps, and fc_peer::usage.

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

static 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 1383 of file fc.c.

1383  {
1384 
1385  intf_restart ( &peer->plogi, rc );
1386 
1387  if ( rc != 0 )
1388  fc_peer_logout ( peer, rc );
1389 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
void intf_restart(struct interface *intf, int rc)
Shut down and restart an object interface.
Definition: interface.c:337
struct fc_peer * peer
Fibre Channel peer.
Definition: fc.h:417
void fc_peer_logout(struct fc_peer *peer, int rc)
Log out Fibre Channel peer.
Definition: fc.c:1347
struct interface plogi
PLOGI interface.
Definition: fc.h:352

References fc_peer_logout(), intf_restart(), fc_ulp::peer, fc_peer::plogi, and rc.

◆ fc_peer_plogi()

static 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 1399 of file fc.c.

1400  {
1401  int rc;
1402 
1403  /* Try to create PLOGI ELS */
1404  intf_restart ( &peer->plogi, -ECANCELED );
1405  if ( ( rc = fc_els_plogi ( &peer->plogi, port, peer_port_id ) ) != 0 ) {
1406  DBGC ( peer, "FCPEER %s could not initiate PLOGI: %s\n",
1407  fc_ntoa ( &peer->port_wwn ), strerror ( rc ) );
1408  fc_peer_logout ( peer, rc );
1409  return rc;
1410  }
1411 
1412  return 0;
1413 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
void intf_restart(struct interface *intf, int rc)
Shut down and restart an object interface.
Definition: interface.c:337
#define DBGC(...)
Definition: compiler.h:505
const char * fc_ntoa(const struct fc_name *wwn)
Format Fibre Channel WWN.
Definition: fc.c:127
int fc_els_plogi(struct interface *parent, struct fc_port *port, struct fc_port_id *peer_port_id)
Create PLOGI request.
Definition: fcels.c:733
struct fc_peer * peer
Fibre Channel peer.
Definition: fc.h:417
#define ECANCELED
Operation canceled.
Definition: errno.h:343
u8 port
Port number.
Definition: CIB_PRM.h:31
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
void fc_peer_logout(struct fc_peer *peer, int rc)
Log out Fibre Channel peer.
Definition: fc.c:1347
struct fc_name port_wwn
Port name.
Definition: fc.h:347
struct interface plogi
PLOGI interface.
Definition: fc.h:352

References DBGC, ECANCELED, fc_els_plogi(), fc_ntoa(), fc_peer_logout(), intf_restart(), fc_ulp::peer, fc_peer::plogi, port, fc_peer::port_wwn, rc, and strerror().

Referenced by fc_peer_examine().

◆ fc_peer_examine()

static 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 1420 of file fc.c.

1420  {
1421  struct fc_peer *peer = container_of ( link, struct fc_peer, link );
1422  struct fc_port *port;
1423  int rc;
1424 
1425  /* Check to see if underlying port link has gone down */
1426  if ( peer->port && ( ! fc_link_ok ( &peer->port->link ) ) ) {
1427  fc_peer_logout ( peer, -ENOTCONN );
1428  return;
1429  }
1430 
1431  /* Do nothing if already logged in */
1432  if ( fc_link_ok ( &peer->link ) )
1433  return;
1434 
1435  DBGC ( peer, "FCPEER %s attempting login\n",
1436  fc_ntoa ( &peer->port_wwn ) );
1437 
1438  /* Sanity check */
1439  assert ( peer->port == NULL );
1440 
1441  /* First, look for a port with the peer attached via a
1442  * point-to-point link.
1443  */
1445  if ( fc_link_ok ( &port->link ) &&
1446  ( ! ( port->flags & FC_PORT_HAS_FABRIC ) ) &&
1447  ( memcmp ( &peer->port_wwn, &port->link_port_wwn,
1448  sizeof ( peer->port_wwn ) ) == 0 ) ) {
1449  /* Use this peer port ID, and stop looking */
1450  fc_peer_plogi ( peer, port, &port->ptp_link_port_id );
1451  return;
1452  }
1453  }
1454 
1455  /* If the peer is not directly attached, try initiating a name
1456  * server lookup on any suitable ports.
1457  */
1459  if ( fc_link_ok ( &port->link ) &&
1460  ( port->flags & FC_PORT_HAS_FABRIC ) &&
1461  ( port->flags & FC_PORT_HAS_NS ) ) {
1462  if ( ( rc = fc_ns_query ( peer, port,
1463  fc_peer_plogi ) ) != 0 ) {
1464  DBGC ( peer, "FCPEER %s could not attempt "
1465  "name server lookup on %s: %s\n",
1466  fc_ntoa ( &peer->port_wwn ), port->name,
1467  strerror ( rc ) );
1468  /* Non-fatal */
1469  }
1470  }
1471  }
1472 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
struct list_head list
List of all ports.
Definition: fc.h:256
A Fibre Channel name server query.
Definition: fcns.c:45
#define DBGC(...)
Definition: compiler.h:505
const char * fc_ntoa(const struct fc_name *wwn)
Format Fibre Channel WWN.
Definition: fc.c:127
struct list_head fc_ports
A Fibre Channel port.
Definition: fc.h:252
struct fc_port * port
Fibre Channel port, if known.
Definition: fc.h:354
u8 port
Port number.
Definition: CIB_PRM.h:31
Port is attached to a fabric.
Definition: fc.h:292
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition: list.h:420
static int fc_link_ok(struct fc_link_state *link)
Check Fibre Channel link state.
Definition: fc.h:108
struct fc_link_state link
Link state monitor.
Definition: fc.h:350
u32 link
Link to next descriptor.
Definition: ar9003_mac.h:68
#define ENOTCONN
The socket is not connected.
Definition: errno.h:569
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:1399
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
struct fc_link_state link
Link state monitor.
Definition: fc.h:272
Port is logged in to a name server.
Definition: fc.h:294
void fc_peer_logout(struct fc_peer *peer, int rc)
Log out Fibre Channel peer.
Definition: fc.c:1347
struct fc_name port_wwn
Port name.
Definition: fc.h:347
A Fibre Channel peer.
Definition: fc.h:340
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition: string.c:98
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362

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_peer::link, fc_port::link, fc_port::list, list_for_each_entry, memcmp(), NULL, port, fc_peer::port, fc_peer::port_wwn, rc, and strerror().

Referenced by fc_peer_create().

◆ fc_peer_create()

static 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 1489 of file fc.c.

1489  {
1490  struct fc_peer *peer;
1491 
1492  /* Allocate and initialise structure */
1493  peer = zalloc ( sizeof ( *peer ) );
1494  if ( ! peer )
1495  return NULL;
1496  ref_init ( &peer->refcnt, NULL );
1497  fc_link_init ( &peer->link, fc_peer_examine, &peer->refcnt );
1498  intf_init ( &peer->plogi, &fc_peer_plogi_desc, &peer->refcnt );
1499  list_add_tail ( &peer->list, &fc_peers );
1500  memcpy ( &peer->port_wwn, port_wwn, sizeof ( peer->port_wwn ) );
1501  INIT_LIST_HEAD ( &peer->ulps );
1502 
1503  /* Start link monitor */
1504  fc_link_start ( &peer->link );
1505 
1506  DBGC ( peer, "FCPEER %s created\n", fc_ntoa ( &peer->port_wwn ) );
1507  return peer;
1508 }
struct list_head fc_peers
#define ref_init(refcnt, free)
Initialise a reference counter.
Definition: refcnt.h:64
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
#define DBGC(...)
Definition: compiler.h:505
struct refcnt refcnt
Reference count.
Definition: fc.h:342
const char * fc_ntoa(const struct fc_name *wwn)
Format Fibre Channel WWN.
Definition: fc.c:127
static void fc_peer_examine(struct fc_link_state *link)
Examine Fibre Channel peer link state.
Definition: fc.c:1420
static struct interface_descriptor fc_peer_plogi_desc
Fibre Channel peer PLOGI interface descriptor.
Definition: fc.c:1480
void * memcpy(void *dest, const void *src, size_t len) __nonnull
struct list_head ulps
List of upper-layer protocols.
Definition: fc.h:359
#define list_add_tail(new, head)
Add a new entry to the tail of a list.
Definition: list.h:93
struct fc_link_state link
Link state monitor.
Definition: fc.h:350
struct list_head list
List of all peers.
Definition: fc.h:344
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:624
struct fc_name port_wwn
Port name.
Definition: fc.h:347
A Fibre Channel peer.
Definition: fc.h:340
struct interface plogi
PLOGI interface.
Definition: fc.h:352
#define INIT_LIST_HEAD(list)
Initialise a list head.
Definition: list.h:45
static void intf_init(struct interface *intf, struct interface_descriptor *desc, struct refcnt *refcnt)
Initialise an object interface.
Definition: interface.h:173
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
static void fc_link_start(struct fc_link_state *link)
Start monitoring Fibre Channel link state.
Definition: fc.c:266

References DBGC, fc_link_init(), fc_link_start(), fc_ntoa(), fc_peer_examine(), fc_peer_plogi_desc, fc_peers, INIT_LIST_HEAD, intf_init(), fc_peer::link, fc_peer::list, list_add_tail, memcpy(), NULL, fc_peer::plogi, fc_peer::port_wwn, ref_init, fc_peer::refcnt, fc_peer::ulps, 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 1516 of file fc.c.

1516  {
1517  struct fc_peer *peer;
1518 
1519  /* Look for an existing peer */
1520  list_for_each_entry ( peer, &fc_peers, list ) {
1521  if ( memcmp ( &peer->port_wwn, port_wwn,
1522  sizeof ( peer->port_wwn ) ) == 0 )
1523  return fc_peer_get ( peer );
1524  }
1525 
1526  /* Create a new peer */
1527  peer = fc_peer_create ( port_wwn );
1528  if ( ! peer )
1529  return NULL;
1530 
1531  return peer;
1532 }
struct list_head fc_peers
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition: list.h:420
struct list_head list
List of all peers.
Definition: fc.h:344
static struct fc_peer * fc_peer_create(const struct fc_name *port_wwn)
Create Fibre Channel peer.
Definition: fc.c:1489
struct fc_name port_wwn
Port name.
Definition: fc.h:347
static struct fc_peer * fc_peer_get(struct fc_peer *peer)
Get reference to Fibre Channel peer.
Definition: fc.h:379
A Fibre Channel peer.
Definition: fc.h:340
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition: string.c:98
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362

References fc_peer_create(), fc_peer_get(), fc_peers, fc_peer::list, list_for_each_entry, memcmp(), NULL, 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 1541 of file fc.c.

1542  {
1543  struct fc_peer *peer;
1544 
1545  /* Look for an existing peer */
1546  list_for_each_entry ( peer, &fc_peers, list ) {
1547  if ( ( peer->port == port ) &&
1548  ( memcmp ( &peer->port_id, peer_port_id,
1549  sizeof ( peer->port_id ) ) == 0 ) )
1550  return fc_peer_get ( peer );
1551  }
1552 
1553  /* Cannot create a new peer, since we have no port name to use */
1554  return NULL;
1555 }
struct list_head fc_peers
struct fc_port * port
Fibre Channel port, if known.
Definition: fc.h:354
u8 port
Port number.
Definition: CIB_PRM.h:31
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition: list.h:420
struct list_head list
List of all peers.
Definition: fc.h:344
struct fc_port_id port_id
Peer port ID, if known.
Definition: fc.h:356
static struct fc_peer * fc_peer_get(struct fc_peer *peer)
Get reference to Fibre Channel peer.
Definition: fc.h:379
A Fibre Channel peer.
Definition: fc.h:340
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition: string.c:98
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362

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

Referenced by fc_els_logo_logout(), and fc_ulp_get_port_id_type().

◆ fc_ulp_free()

static void fc_ulp_free ( struct refcnt refcnt)
static

Free Fibre Channel upper-layer protocol.

Parameters
refcntReference count

Definition at line 1569 of file fc.c.

1569  {
1570  struct fc_ulp *ulp = container_of ( refcnt, struct fc_ulp, refcnt );
1571 
1572  fc_peer_put ( ulp->peer );
1573  free ( ulp );
1574 }
struct fc_peer * peer
Fibre Channel peer.
Definition: fc.h:417
A reference counter.
Definition: refcnt.h:26
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
static void fc_peer_put(struct fc_peer *peer)
Drop reference to Fibre Channel peer.
Definition: fc.h:390
A Fibre Channel upper-layer protocol.
Definition: fc.h:413

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

Referenced by fc_ulp_create().

◆ fc_ulp_close()

static 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 1582 of file fc.c.

1582  {
1583 
1584  DBGC ( ulp, "FCULP %s/%02x closed: %s\n",
1585  fc_ntoa ( &ulp->peer->port_wwn ), ulp->type, strerror ( rc ) );
1586 
1587  /* Sanity check */
1588  assert ( list_empty ( &ulp->users ) );
1589 
1590  /* Stop link monitor */
1591  fc_link_stop ( &ulp->link );
1592 
1593  /* Shut down interfaces */
1594  intf_shutdown ( &ulp->prli, rc );
1595 
1596  /* Remove from list of ULPs */
1597  list_del ( &ulp->list );
1598  INIT_LIST_HEAD ( &ulp->list );
1599 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
void intf_shutdown(struct interface *intf, int rc)
Shut down an object interface.
Definition: interface.c:273
#define DBGC(...)
Definition: compiler.h:505
struct list_head list
List of upper-layer protocols.
Definition: fc.h:419
const char * fc_ntoa(const struct fc_name *wwn)
Format Fibre Channel WWN.
Definition: fc.c:127
struct fc_peer * peer
Fibre Channel peer.
Definition: fc.h:417
struct list_head users
Active users of this upper-layer protocol.
Definition: fc.h:443
#define list_empty(list)
Test whether a list is empty.
Definition: list.h:136
#define list_del(list)
Delete an entry from a list.
Definition: list.h:119
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
struct interface prli
PRLI interface.
Definition: fc.h:429
unsigned int type
Type.
Definition: fc.h:422
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
struct fc_link_state link
Link state monitor.
Definition: fc.h:427
struct fc_name port_wwn
Port name.
Definition: fc.h:347
static void fc_link_stop(struct fc_link_state *link)
Stop monitoring Fibre Channel link state.
Definition: fc.c:275
#define INIT_LIST_HEAD(list)
Initialise a list head.
Definition: list.h:45

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 1607 of file fc.c.

1607  {
1608 
1609  /* Sanity check */
1610  assert ( user->ulp == NULL );
1611 
1612  /* Increment peer's usage count */
1613  fc_peer_increment ( ulp->peer );
1614 
1615  /* Attach user */
1616  user->ulp = fc_ulp_get ( ulp );
1617  list_add ( &user->list, &ulp->users );
1618 }
#define list_add(new, head)
Add a new entry to the head of a list.
Definition: list.h:69
static void fc_peer_increment(struct fc_peer *peer)
Increment Fibre Channel peer active usage count.
Definition: fc.c:1271
struct fc_peer * peer
Fibre Channel peer.
Definition: fc.h:417
struct list_head users
Active users of this upper-layer protocol.
Definition: fc.h:443
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
struct ntlm_data user
User name.
Definition: ntlm.h:20
static struct fc_ulp * fc_ulp_get(struct fc_ulp *ulp)
Get reference to Fibre Channel upper-layer protocol.
Definition: fc.h:474
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362

References assert(), fc_peer_increment(), fc_ulp_get(), list_add, NULL, fc_ulp::peer, user, 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 1625 of file fc.c.

1625  {
1626  struct fc_ulp *ulp = user->ulp;
1627 
1628  /* Do nothing if not attached */
1629  if ( ! ulp )
1630  return;
1631 
1632  /* Sanity checks */
1634 
1635  /* Detach user and log out if no users remain */
1636  list_del ( &user->list );
1637  if ( list_empty ( &ulp->users ) )
1638  fc_ulp_logout ( ulp, 0 );
1639 
1640  /* Decrement our peer's usage count */
1641  fc_peer_decrement ( ulp->peer );
1642 
1643  /* Drop reference */
1644  user->ulp = NULL;
1645  fc_ulp_put ( ulp );
1646 }
static void fc_peer_decrement(struct fc_peer *peer)
Decrement Fibre Channel peer active usage count.
Definition: fc.c:1282
struct list_head list
List of upper-layer protocols.
Definition: fc.h:419
struct fc_peer * peer
Fibre Channel peer.
Definition: fc.h:417
struct list_head users
Active users of this upper-layer protocol.
Definition: fc.h:443
#define list_empty(list)
Test whether a list is empty.
Definition: list.h:136
#define list_del(list)
Delete an entry from a list.
Definition: list.h:119
struct ntlm_data user
User name.
Definition: ntlm.h:20
void fc_ulp_logout(struct fc_ulp *ulp, int rc)
Log out Fibre Channel upper-layer protocol.
Definition: fc.c:1727
static void fc_ulp_put(struct fc_ulp *ulp)
Drop reference to Fibre Channel upper-layer protocol.
Definition: fc.h:485
#define list_check_contains_entry(entry, head, member)
Check list contains a specified entry.
Definition: list.h:522
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
A Fibre Channel upper-layer protocol.
Definition: fc.h:413

References fc_peer_decrement(), fc_ulp_logout(), fc_ulp_put(), fc_ulp::list, list_check_contains_entry, list_del, list_empty, NULL, fc_ulp::peer, user, 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 1657 of file fc.c.

1658  {
1659  struct fc_ulp_user *user;
1660  struct fc_ulp_user *tmp;
1661 
1662  /* Perform implicit logout if logged in and service parameters differ */
1663  if ( fc_link_ok ( &ulp->link ) &&
1664  ( ( ulp->param_len != param_len ) ||
1665  ( memcmp ( ulp->param, param, ulp->param_len ) != 0 ) ) ) {
1666  fc_ulp_logout ( ulp, 0 );
1667  }
1668 
1669  /* Work around a bug in some versions of the Linux Fibre
1670  * Channel stack, which fail to fully initialise image pairs
1671  * established via a PRLI originated by the Linux stack
1672  * itself.
1673  */
1674  if ( originated )
1676  if ( ! ( ulp->flags & FC_ULP_ORIGINATED_LOGIN_OK ) ) {
1677  DBGC ( ulp, "FCULP %s/%02x sending extra PRLI to work around "
1678  "Linux bug\n",
1679  fc_ntoa ( &ulp->peer->port_wwn ), ulp->type );
1680  fc_link_stop ( &ulp->link );
1681  fc_link_start ( &ulp->link );
1682  return 0;
1683  }
1684 
1685  /* Log in, if applicable */
1686  if ( ! fc_link_ok ( &ulp->link ) ) {
1687 
1688  /* Record service parameters */
1689  assert ( ulp->param == NULL );
1690  assert ( ulp->param_len == 0 );
1691  ulp->param = malloc ( param_len );
1692  if ( ! ulp->param ) {
1693  DBGC ( ulp, "FCULP %s/%02x could not record "
1694  "parameters\n",
1695  fc_ntoa ( &ulp->peer->port_wwn ), ulp->type );
1696  return -ENOMEM;
1697  }
1698  memcpy ( ulp->param, param, param_len );
1699  ulp->param_len = param_len;
1700  DBGC ( ulp, "FCULP %s/%02x logged in with parameters:\n",
1701  fc_ntoa ( &ulp->peer->port_wwn ), ulp->type );
1702  DBGC_HDA ( ulp, 0, ulp->param, ulp->param_len );
1703 
1704  /* Add login reference */
1705  fc_ulp_get ( ulp );
1706  }
1707 
1708  /* Record login */
1709  fc_link_up ( &ulp->link );
1710 
1711  /* Notify users of link state change */
1713  fc_ulp_user_get ( user );
1714  user->examine ( user );
1715  fc_ulp_user_put ( user );
1716  }
1717 
1718  return 0;
1719 }
struct fc_ulp * ulp
Fibre Channel upper layer protocol.
Definition: fc.h:455
#define DBGC(...)
Definition: compiler.h:505
const char * fc_ntoa(const struct fc_name *wwn)
Format Fibre Channel WWN.
Definition: fc.c:127
struct fc_peer * peer
Fibre Channel peer.
Definition: fc.h:417
struct list_head users
Active users of this upper-layer protocol.
Definition: fc.h:443
struct list_head list
List of users.
Definition: fc.h:457
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:496
#define ENOMEM
Not enough space.
Definition: errno.h:534
void * memcpy(void *dest, const void *src, size_t len) __nonnull
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
struct ntlm_data user
User name.
Definition: ntlm.h:20
size_t param_len
Service parameter length.
Definition: fc.h:433
#define DBGC_HDA(...)
Definition: compiler.h:506
static int fc_link_ok(struct fc_link_state *link)
Check Fibre Channel link state.
Definition: fc.h:108
A login originated by us has succeeded.
Definition: fc.h:449
#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:447
unsigned int type
Type.
Definition: fc.h:422
void * param
Service parameters, if any.
Definition: fc.h:431
static struct fc_ulp * fc_ulp_get(struct fc_ulp *ulp)
Get reference to Fibre Channel upper-layer protocol.
Definition: fc.h:474
struct hv_monitor_parameter param[4][32]
Parameters.
Definition: hyperv.h:24
uint8_t * tmp
Definition: entropy.h:156
struct fc_link_state link
Link state monitor.
Definition: fc.h:427
struct fc_name port_wwn
Port name.
Definition: fc.h:347
static void fc_ulp_user_put(struct fc_ulp_user *user)
Drop reference to Fibre Channel upper-layer protocol user.
Definition: fc.h:507
A Fibre Channel upper-layer protocol user.
Definition: fc.h:453
void * malloc(size_t size)
Allocate memory.
Definition: malloc.c:583
static void fc_link_stop(struct fc_link_state *link)
Stop monitoring Fibre Channel link state.
Definition: fc.c:275
void fc_ulp_logout(struct fc_ulp *ulp, int rc)
Log out Fibre Channel upper-layer protocol.
Definition: fc.c:1727
static void fc_link_up(struct fc_link_state *link)
Mark Fibre Channel link as up.
Definition: fc.c:195
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition: string.c:98
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
unsigned int flags
Flags.
Definition: fc.h:424
static void fc_link_start(struct fc_link_state *link)
Start monitoring Fibre Channel link state.
Definition: fc.c:266

References assert(), DBGC, DBGC_HDA, ENOMEM, 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, param, fc_ulp::param, fc_ulp::param_len, fc_ulp::peer, fc_peer::port_wwn, tmp, fc_ulp::type, fc_ulp_user::ulp, user, 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 1727 of file fc.c.

1727  {
1728  struct fc_ulp_user *user;
1729  struct fc_ulp_user *tmp;
1730 
1731  DBGC ( ulp, "FCULP %s/%02x logged out: %s\n",
1732  fc_ntoa ( &ulp->peer->port_wwn ), ulp->type, strerror ( rc ) );
1733 
1734  /* Drop login reference, if applicable */
1735  if ( fc_link_ok ( &ulp->link ) )
1736  fc_ulp_put ( ulp );
1737 
1738  /* Discard service parameters */
1739  free ( ulp->param );
1740  ulp->param = NULL;
1741  ulp->param_len = 0;
1742  ulp->flags = 0;
1743 
1744  /* Record logout */
1745  fc_link_err ( &ulp->link, rc );
1746 
1747  /* Notify users of link state change */
1749  fc_ulp_user_get ( user );
1750  user->examine ( user );
1751  fc_ulp_user_put ( user );
1752  }
1753 
1754  /* Close ULP if there are no clients attached */
1755  if ( list_empty ( &ulp->users ) )
1756  fc_ulp_close ( ulp, rc );
1757 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
struct fc_ulp * ulp
Fibre Channel upper layer protocol.
Definition: fc.h:455
#define DBGC(...)
Definition: compiler.h:505
const char * fc_ntoa(const struct fc_name *wwn)
Format Fibre Channel WWN.
Definition: fc.c:127
static void fc_link_err(struct fc_link_state *link, int rc)
Mark Fibre Channel link as down.
Definition: fc.c:210
struct fc_peer * peer
Fibre Channel peer.
Definition: fc.h:417
struct list_head users
Active users of this upper-layer protocol.
Definition: fc.h:443
struct list_head list
List of users.
Definition: fc.h:457
#define list_empty(list)
Test whether a list is empty.
Definition: list.h:136
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:496
struct ntlm_data user
User name.
Definition: ntlm.h:20
size_t param_len
Service parameter length.
Definition: fc.h:433
static int fc_link_ok(struct fc_link_state *link)
Check Fibre Channel link state.
Definition: fc.h:108
#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:447
unsigned int type
Type.
Definition: fc.h:422
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
void * param
Service parameters, if any.
Definition: fc.h:431
uint8_t * tmp
Definition: entropy.h:156
struct fc_link_state link
Link state monitor.
Definition: fc.h:427
struct fc_name port_wwn
Port name.
Definition: fc.h:347
static void fc_ulp_user_put(struct fc_ulp_user *user)
Drop reference to Fibre Channel upper-layer protocol user.
Definition: fc.h:507
A Fibre Channel upper-layer protocol user.
Definition: fc.h:453
static void fc_ulp_put(struct fc_ulp *ulp)
Drop reference to Fibre Channel upper-layer protocol.
Definition: fc.h:485
static void fc_ulp_close(struct fc_ulp *ulp, int rc)
Close Fibre Channel upper-layer protocol.
Definition: fc.c:1582
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
unsigned int flags
Flags.
Definition: fc.h:424

References DBGC, 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, user, 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()

static 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 1765 of file fc.c.

1765  {
1766 
1767  intf_restart ( &ulp->prli, rc );
1768 
1769  if ( rc != 0 )
1770  fc_ulp_logout ( ulp, rc );
1771 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
void intf_restart(struct interface *intf, int rc)
Shut down and restart an object interface.
Definition: interface.c:337
struct fc_ulp * ulp
Fibre Channel upper layer protocol.
Definition: fc.h:455
struct interface prli
PRLI interface.
Definition: fc.h:429
void fc_ulp_logout(struct fc_ulp *ulp, int rc)
Log out Fibre Channel upper-layer protocol.
Definition: fc.c:1727

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

◆ fc_ulp_examine()

static 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 1778 of file fc.c.

1778  {
1779  struct fc_ulp *ulp = container_of ( link, struct fc_ulp, link );
1780  int rc;
1781 
1782  /* Check to see if underlying peer link has gone down */
1783  if ( ! fc_link_ok ( &ulp->peer->link ) ) {
1784  fc_ulp_logout ( ulp, -ENOTCONN );
1785  return;
1786  }
1787 
1788  /* Do nothing if already logged in */
1789  if ( fc_link_ok ( &ulp->link ) &&
1790  ( ulp->flags & FC_ULP_ORIGINATED_LOGIN_OK ) )
1791  return;
1792 
1793  DBGC ( ulp, "FCULP %s/%02x attempting login\n",
1794  fc_ntoa ( &ulp->peer->port_wwn ), ulp->type );
1795 
1796  /* Try to create PRLI ELS */
1797  intf_restart ( &ulp->prli, -ECANCELED );
1798  if ( ( rc = fc_els_prli ( &ulp->prli, ulp->peer->port,
1799  &ulp->peer->port_id, ulp->type ) ) != 0 ) {
1800  DBGC ( ulp, "FCULP %s/%02x could not initiate PRLI: %s\n",
1801  fc_ntoa ( &ulp->peer->port_wwn ), ulp->type,
1802  strerror ( rc ) );
1803  fc_ulp_logout ( ulp, rc );
1804  return;
1805  }
1806 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
void intf_restart(struct interface *intf, int rc)
Shut down and restart an object interface.
Definition: interface.c:337
#define DBGC(...)
Definition: compiler.h:505
const char * fc_ntoa(const struct fc_name *wwn)
Format Fibre Channel WWN.
Definition: fc.c:127
struct fc_peer * peer
Fibre Channel peer.
Definition: fc.h:417
#define ECANCELED
Operation canceled.
Definition: errno.h:343
struct fc_port * port
Fibre Channel port, if known.
Definition: fc.h:354
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
static int fc_link_ok(struct fc_link_state *link)
Check Fibre Channel link state.
Definition: fc.h:108
struct fc_link_state link
Link state monitor.
Definition: fc.h:350
A login originated by us has succeeded.
Definition: fc.h:449
u32 link
Link to next descriptor.
Definition: ar9003_mac.h:68
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:1124
struct interface prli
PRLI interface.
Definition: fc.h:429
unsigned int type
Type.
Definition: fc.h:422
#define ENOTCONN
The socket is not connected.
Definition: errno.h:569
struct fc_port_id port_id
Peer port ID, if known.
Definition: fc.h:356
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
struct fc_link_state link
Link state monitor.
Definition: fc.h:427
struct fc_name port_wwn
Port name.
Definition: fc.h:347
void fc_ulp_logout(struct fc_ulp *ulp, int rc)
Log out Fibre Channel upper-layer protocol.
Definition: fc.c:1727
unsigned int flags
Flags.
Definition: fc.h:424
A Fibre Channel upper-layer protocol.
Definition: fc.h:413

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

static 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 1824 of file fc.c.

1825  {
1826  struct fc_ulp *ulp;
1827 
1828  /* Allocate and initialise structure */
1829  ulp = zalloc ( sizeof ( *ulp ) );
1830  if ( ! ulp )
1831  return NULL;
1832  ref_init ( &ulp->refcnt, fc_ulp_free );
1833  fc_link_init ( &ulp->link, fc_ulp_examine, &ulp->refcnt );
1834  intf_init ( &ulp->prli, &fc_ulp_prli_desc, &ulp->refcnt );
1835  ulp->peer = fc_peer_get ( peer );
1836  list_add_tail ( &ulp->list, &peer->ulps );
1837  ulp->type = type;
1838  INIT_LIST_HEAD ( &ulp->users );
1839 
1840  /* Start link state monitor */
1841  fc_link_start ( &ulp->link );
1842 
1843  DBGC ( ulp, "FCULP %s/%02x created\n",
1844  fc_ntoa ( &ulp->peer->port_wwn ), ulp->type );
1845  return ulp;
1846 }
static void fc_ulp_free(struct refcnt *refcnt)
Free Fibre Channel upper-layer protocol.
Definition: fc.c:1569
#define ref_init(refcnt, free)
Initialise a reference counter.
Definition: refcnt.h:64
uint8_t type
Type.
Definition: ena.h:16
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
#define DBGC(...)
Definition: compiler.h:505
static struct interface_descriptor fc_ulp_prli_desc
Fibre Channel upper-layer protocol PRLI interface descriptor.
Definition: fc.c:1814
struct list_head list
List of upper-layer protocols.
Definition: fc.h:419
const char * fc_ntoa(const struct fc_name *wwn)
Format Fibre Channel WWN.
Definition: fc.c:127
struct fc_peer * peer
Fibre Channel peer.
Definition: fc.h:417
struct list_head users
Active users of this upper-layer protocol.
Definition: fc.h:443
struct list_head ulps
List of upper-layer protocols.
Definition: fc.h:359
#define list_add_tail(new, head)
Add a new entry to the tail of a list.
Definition: list.h:93
struct interface prli
PRLI interface.
Definition: fc.h:429
unsigned int type
Type.
Definition: fc.h:422
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:624
struct fc_link_state link
Link state monitor.
Definition: fc.h:427
struct fc_name port_wwn
Port name.
Definition: fc.h:347
static void fc_ulp_examine(struct fc_link_state *link)
Examine Fibre Channel upper-layer protocol link state.
Definition: fc.c:1778
static struct fc_peer * fc_peer_get(struct fc_peer *peer)
Get reference to Fibre Channel peer.
Definition: fc.h:379
struct refcnt refcnt
Reference count.
Definition: fc.h:415
#define INIT_LIST_HEAD(list)
Initialise a list head.
Definition: list.h:45
static void intf_init(struct interface *intf, struct interface_descriptor *desc, struct refcnt *refcnt)
Initialise an object interface.
Definition: interface.h:173
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
A Fibre Channel upper-layer protocol.
Definition: fc.h:413
static void fc_link_start(struct fc_link_state *link)
Start monitoring Fibre Channel link state.
Definition: fc.c:266

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, fc_peer::port_wwn, fc_ulp::prli, ref_init, fc_ulp::refcnt, type, fc_ulp::type, fc_peer::ulps, fc_ulp::users, and zalloc().

Referenced by fc_ulp_get_type().

◆ fc_ulp_get_type()

static 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 1855 of file fc.c.

1856  {
1857  struct fc_ulp *ulp;
1858 
1859  /* Look for an existing ULP */
1860  list_for_each_entry ( ulp, &peer->ulps, list ) {
1861  if ( ulp->type == type )
1862  return fc_ulp_get ( ulp );
1863  }
1864 
1865  /* Create a new ULP */
1866  ulp = fc_ulp_create ( peer, type );
1867  if ( ! ulp )
1868  return NULL;
1869 
1870  return ulp;
1871 }
uint8_t type
Type.
Definition: ena.h:16
struct list_head list
List of upper-layer protocols.
Definition: fc.h:419
struct fc_peer * peer
Fibre Channel peer.
Definition: fc.h:417
struct list_head ulps
List of upper-layer protocols.
Definition: fc.h:359
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition: list.h:420
unsigned int type
Type.
Definition: fc.h:422
static struct fc_ulp * fc_ulp_get(struct fc_ulp *ulp)
Get reference to Fibre Channel upper-layer protocol.
Definition: fc.h:474
static struct fc_ulp * fc_ulp_create(struct fc_peer *peer, unsigned int type)
Create Fibre Channel upper-layer protocl.
Definition: fc.c:1824
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
A Fibre Channel upper-layer protocol.
Definition: fc.h:413

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

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 1880 of file fc.c.

1881  {
1882  struct fc_ulp *ulp;
1883  struct fc_peer *peer;
1884 
1885  /* Get peer */
1886  peer = fc_peer_get_wwn ( port_wwn );
1887  if ( ! peer )
1888  goto err_peer_get_wwn;
1889 
1890  /* Get ULP */
1891  ulp = fc_ulp_get_type ( peer, type );
1892  if ( ! ulp )
1893  goto err_ulp_get_type;
1894 
1895  /* Drop temporary reference to peer */
1896  fc_peer_put ( peer );
1897 
1898  return ulp;
1899 
1900  fc_ulp_put ( ulp );
1901  err_ulp_get_type:
1902  fc_peer_put ( peer );
1903  err_peer_get_wwn:
1904  return NULL;
1905 }
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:1855
uint8_t type
Type.
Definition: ena.h:16
struct fc_peer * fc_peer_get_wwn(const struct fc_name *port_wwn)
Get Fibre Channel peer by node name.
Definition: fc.c:1516
static void fc_peer_put(struct fc_peer *peer)
Drop reference to Fibre Channel peer.
Definition: fc.h:390
struct fc_name port_wwn
Port name.
Definition: fc.h:347
A Fibre Channel peer.
Definition: fc.h:340
static void fc_ulp_put(struct fc_ulp *ulp)
Drop reference to Fibre Channel upper-layer protocol.
Definition: fc.h:485
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
A Fibre Channel upper-layer protocol.
Definition: fc.h:413

References fc_peer_get_wwn(), fc_peer_put(), fc_ulp_get_type(), fc_ulp_put(), NULL, 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 1915 of file fc.c.

1917  {
1918  struct fc_ulp *ulp;
1919  struct fc_peer *peer;
1920 
1921  /* Get peer */
1922  peer = fc_peer_get_port_id ( port, peer_port_id );
1923  if ( ! peer )
1924  goto err_peer_get_wwn;
1925 
1926  /* Get ULP */
1927  ulp = fc_ulp_get_type ( peer, type );
1928  if ( ! ulp )
1929  goto err_ulp_get_type;
1930 
1931  /* Drop temporary reference to peer */
1932  fc_peer_put ( peer );
1933 
1934  return ulp;
1935 
1936  fc_ulp_put ( ulp );
1937  err_ulp_get_type:
1938  fc_peer_put ( peer );
1939  err_peer_get_wwn:
1940  return NULL;
1941 }
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:1855
uint8_t type
Type.
Definition: ena.h:16
u8 port
Port number.
Definition: CIB_PRM.h:31
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:1541
static void fc_peer_put(struct fc_peer *peer)
Drop reference to Fibre Channel peer.
Definition: fc.h:390
A Fibre Channel peer.
Definition: fc.h:340
static void fc_ulp_put(struct fc_ulp *ulp)
Drop reference to Fibre Channel upper-layer protocol.
Definition: fc.h:485
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
A Fibre Channel upper-layer protocol.
Definition: fc.h:413

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

Referenced by fc_els_prli_rx(), and fc_els_prli_tx().

◆ REQUIRING_SYMBOL()

REQUIRING_SYMBOL ( 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.

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.

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.

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.

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.

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:
= {
[FC_R_CTL_UNCAT] = ( 0 ),
}
Solicited Data.
Definition: fc.h:177
Unsolicited Control.
Definition: fc.h:178
Unsolicited Command.
Definition: fc.h:182
#define XFER_FL_RESPONSE
Data content is a response.
Definition: xfer.h:63
Command Status.
Definition: fc.h:183
Unsolicited Data.
Definition: fc.h:180
Solicited Control.
Definition: fc.h:179
#define XFER_FL_CMD_STAT
Data content represents a command or status message.
Definition: xfer.h:60
Data Descriptor.
Definition: fc.h:181
Uncategorized.
Definition: fc.h:176

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:
= {
}
void intf_close(struct interface *intf, int rc)
Close an object interface.
Definition: interface.c:244
struct io_buffer * xfer_alloc_iob(struct interface *intf, size_t len)
Allocate I/O buffer.
Definition: xfer.c:157
size_t xfer_window(struct interface *intf)
Check flow control window.
Definition: xfer.c:115
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
A Fibre Channel exchange.
Definition: fc.c:287
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
static size_t fc_xchg_window(struct fc_exchange *xchg __unused)
Check Fibre Channel exchange window.
Definition: fc.c:423
#define INTF_OP(op_type, object_type, op_func)
Define an object interface operation.
Definition: interface.h:32
static void fc_xchg_close(struct fc_exchange *xchg, int rc)
Close Fibre Channel exchange.
Definition: fc.c:376
int xfer_deliver(struct interface *intf, struct io_buffer *iobuf, struct xfer_metadata *meta)
Deliver datagram.
Definition: xfer.c:193

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
A Fibre Channel exchange.
Definition: fc.c:287
#define INTF_DESC(object_type, intf, operations)
Define an object interface descriptor.
Definition: interface.h:65

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:
= {
}
void xfer_window_changed(struct interface *intf)
Report change of flow control window.
Definition: xfer.c:145
void intf_close(struct interface *intf, int rc)
Close an object interface.
Definition: interface.c:244
A Fibre Channel port.
Definition: fc.h:252
static void fc_port_close(struct fc_port *port, int rc)
Close Fibre Channel port.
Definition: fc.c:806
#define INTF_OP(op_type, object_type, op_func)
Define an object interface operation.
Definition: interface.h:32
int xfer_deliver(struct interface *intf, struct io_buffer *iobuf, struct xfer_metadata *meta)
Deliver datagram.
Definition: xfer.c:193
static void fc_port_window_changed(struct fc_port *port)
Handle change of flow control window.
Definition: fc.c:1126
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

Fibre Channel port transport interface operations.

Definition at line 1151 of file fc.c.

◆ 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:1151
A Fibre Channel port.
Definition: fc.h:252
#define INTF_DESC(object_type, intf, operations)
Define an object interface descriptor.
Definition: interface.h:65

Fibre Channel port transport interface descriptor.

Definition at line 1159 of file fc.c.

Referenced by fc_port_open().

◆ fc_port_flogi_op

struct interface_operation fc_port_flogi_op[]
static
Initial value:
= {
}
void intf_close(struct interface *intf, int rc)
Close an object interface.
Definition: interface.c:244
static void fc_port_flogi_done(struct fc_port *port, int rc)
Handle FLOGI completion.
Definition: fc.c:1067
A Fibre Channel port.
Definition: fc.h:252
#define INTF_OP(op_type, object_type, op_func)
Define an object interface operation.
Definition: interface.h:32

Fibre Channel port FLOGI interface operations.

Definition at line 1163 of file fc.c.

◆ fc_port_flogi_desc

struct interface_descriptor fc_port_flogi_desc
static
Initial value:
=
INTF_DESC ( struct fc_port, flogi, fc_port_flogi_op )
A Fibre Channel port.
Definition: fc.h:252
static struct interface_operation fc_port_flogi_op[]
Fibre Channel port FLOGI interface operations.
Definition: fc.c:1163
#define INTF_DESC(object_type, intf, operations)
Define an object interface descriptor.
Definition: interface.h:65

Fibre Channel port FLOGI interface descriptor.

Definition at line 1168 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:
= {
}
void intf_close(struct interface *intf, int rc)
Close an object interface.
Definition: interface.c:244
A Fibre Channel port.
Definition: fc.h:252
#define INTF_OP(op_type, object_type, op_func)
Define an object interface operation.
Definition: interface.h:32
static void fc_port_ns_plogi_done(struct fc_port *port, int rc)
Handle name server PLOGI completion.
Definition: fc.c:1081

Fibre Channel port name server PLOGI interface operations.

Definition at line 1172 of file fc.c.

◆ 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 )
A Fibre Channel port.
Definition: fc.h:252
static struct interface_operation fc_port_ns_plogi_op[]
Fibre Channel port name server PLOGI interface operations.
Definition: fc.c:1172
#define INTF_DESC(object_type, intf, operations)
Define an object interface descriptor.
Definition: interface.h:65

Fibre Channel port name server PLOGI interface descriptor.

Definition at line 1177 of file fc.c.

Referenced by fc_port_open().

◆ fc_peer_plogi_op

struct interface_operation fc_peer_plogi_op[]
static
Initial value:
= {
}
void intf_close(struct interface *intf, int rc)
Close an object interface.
Definition: interface.c:244
static void fc_peer_plogi_done(struct fc_peer *peer, int rc)
Handle PLOGI completion.
Definition: fc.c:1383
#define INTF_OP(op_type, object_type, op_func)
Define an object interface operation.
Definition: interface.h:32
A Fibre Channel peer.
Definition: fc.h:340

Fibre Channel peer PLOGI interface operations.

Definition at line 1475 of file fc.c.

◆ 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:1475
A Fibre Channel peer.
Definition: fc.h:340
struct interface plogi
PLOGI interface.
Definition: fc.h:352
#define INTF_DESC(object_type, intf, operations)
Define an object interface descriptor.
Definition: interface.h:65

Fibre Channel peer PLOGI interface descriptor.

Definition at line 1480 of file fc.c.

Referenced by fc_peer_create().

◆ fc_ulp_prli_op

struct interface_operation fc_ulp_prli_op[]
static
Initial value:
= {
}
void intf_close(struct interface *intf, int rc)
Close an object interface.
Definition: interface.c:244
#define INTF_OP(op_type, object_type, op_func)
Define an object interface operation.
Definition: interface.h:32
static void fc_ulp_prli_done(struct fc_ulp *ulp, int rc)
Handle PRLI completion.
Definition: fc.c:1765
A Fibre Channel upper-layer protocol.
Definition: fc.h:413

Fibre Channel upper-layer protocol PRLI interface operations.

Definition at line 1809 of file fc.c.

◆ 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:1809
#define INTF_DESC(object_type, intf, operations)
Define an object interface descriptor.
Definition: interface.h:65
A Fibre Channel upper-layer protocol.
Definition: fc.h:413

Fibre Channel upper-layer protocol PRLI interface descriptor.

Definition at line 1814 of file fc.c.

Referenced by fc_ulp_create().