Print this page
    
NEX-3856 panic is occurred in module "fct" due to a NULL pointer dereference
Reviewed by: Rob Gittins <rob.gittins@nexenta.com>
Reviewed by: Steve Peng <steve.peng@nexenta.com>
NEX-3277 Panic of both nodes in failover time (FC clients)
        Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
        Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
NEX-2787 Multiple comstar / fibre channel / qlt threads stuck waiting on locks with a spinning interrupt thread
Reviewed by: Rob Gittins <rob.gittins@nexenta.com>
Approved by: Jean McCormack <jean.mccormack@nexenta.com>
    
      
        | Split | 
	Close | 
      
      | Expand all | 
      | Collapse all | 
    
    
          --- old/usr/src/uts/common/io/comstar/port/fct/fct_impl.h
          +++ new/usr/src/uts/common/io/comstar/port/fct/fct_impl.h
   1    1  /*
   2    2   * CDDL HEADER START
   3    3   *
   4    4   * The contents of this file are subject to the terms of the
   5    5   * Common Development and Distribution License (the "License").
   6    6   * You may not use this file except in compliance with the License.
   7    7   *
   8    8   * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9    9   * or http://www.opensolaris.org/os/licensing.
  10   10   * See the License for the specific language governing permissions
  11   11   * and limitations under the License.
  12   12   *
  
    | 
      ↓ open down ↓ | 
    12 lines elided | 
    
      ↑ open up ↑ | 
  
  13   13   * When distributing Covered Code, include this CDDL HEADER in each
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  /*
  22   22   * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
       23 + * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
  23   24   * Use is subject to license terms.
  24   25   */
  25   26  #ifndef _FCT_IMPL_H
  26   27  #define _FCT_IMPL_H
  27   28  
  28   29  #ifdef  __cplusplus
  29   30  extern "C" {
  30   31  #endif
  31   32  
  32   33  #define RSCN_OPTION_VERIFY      0x0001
  33   34  
  34   35  typedef enum fct_li_state {
  35   36          LI_STATE_DO_FLOGI = 0,  /* FLOGI handled by FCA */
  36   37          LI_STATE_FINI_TOPOLOGY, /* Finalize topology */
  37   38          LI_STATE_N2N_PLOGI,     /* In case of a N2N connection */
  38   39  
  39   40          LI_STATE_DO_FCLOGIN,    /* Login into 0xFFFFFD */
  40   41          LI_STATE_DO_SCR,        /* State change registration */
  41   42  
  42   43          LI_STATE_DO_NSLOGIN,    /* Login into 0xFFFFFC */
  43   44          LI_STATE_DO_RNN,        /* Register node name */
  44   45          LI_STATE_DO_RCS,        /* Register classes of service */
  45   46          LI_STATE_DO_RFT,        /* Register FC-4 types */
  46   47          LI_STATE_DO_RSPN,       /* Register symbolic port name */
  47   48          LI_STATE_DO_RSNN,       /* Register symbolic node name */
  48   49  
  49   50          LI_STATE_MAX            /* Not a real state */
  50   51  } fct_li_state_t;
  51   52  
  52   53  #define LI_STATE_START                  0
  53   54  #define LI_STATE_MASK                   0x3F
  54   55  /* Next state depends on the return value */
  55   56  #define LI_STATE_FLAG_CMD_RETCHECK      0x40
  56   57  /* Link init cmd is still outstanding */
  57   58  #define LI_STATE_FLAG_CMD_WAITING       0x80
  58   59  /* Flag to indicate that link info is not available yet */
  59   60  #define LI_STATE_FLAG_NO_LI_YET         0x100
  60   61  
  61   62  #define FCT_MAX_CACHED_CMDS     256
  62   63  #define USEC_ELS_TIMEOUT        (10 * 1000 * 1000)
  63   64  #define USEC_SOL_TIMEOUT        (10 * 1000 * 1000)
  64   65  #define USEC_DEREG_RP_TIMEOUT   (25 * 1000 * 1000)
  
    | 
      ↓ open down ↓ | 
    32 lines elided | 
    
      ↑ open up ↑ | 
  
  65   66  #define USEC_DEREG_RP_INTERVAL  (2 * 1000 * 1000)
  66   67  
  67   68  struct fct_i_cmd;
  68   69  typedef void (* fct_icmd_cb_t)(struct fct_i_cmd *icmd);
  69   70  typedef struct fct_i_cmd {
  70   71          fct_cmd_t               *icmd_cmd;
  71   72          uint32_t                 icmd_alloc_size;
  72   73          fct_struct_id_t          icmd_struct_id;
  73   74          uint32_t                 icmd_flags;
  74   75          clock_t                  icmd_start_time;
  75      -        struct fct_i_cmd        *icmd_next;     /* iport_abort_queue and irp */
       76 +        list_node_t             icmd_node;      /* iport_abort_queue and irp */
  76   77          struct fct_i_cmd        *icmd_solcmd_next;      /* iport_solcmd_queue */
  77   78          fct_icmd_cb_t            icmd_cb;
  78   79          void                    *icmd_cb_private;
  79   80  } fct_i_cmd_t;
  80   81  
  81   82  /*
  82   83   * icmd_flags
  83   84   */
  84   85  #define ICMD_SESSION_AFFECTING          0x0002
  85   86  #define ICMD_IN_IRP_QUEUE               0x0004
  86   87  #define ICMD_BEING_ABORTED              0x0008
  87   88  #define ICMD_KNOWN_TO_FCA               0x0020
  88   89  #define ICMD_FCA_ABORT_CALLED           0x0040
  89   90  #define ICMD_CMD_COMPLETE               0x0080
  90   91  #define ICMD_IN_TRANSITION              0x0100
  91   92  #define ICMD_ABTS_RECEIVED              0x0200
  92   93  #define ICMD_IMPLICIT                   0x0400
  93   94  #define ICMD_IMPLICIT_CMD_HAS_RESOURCE  0x0800
  94   95  /* High order are debug flags */
  95   96  #define ICMD_ELS_PROCESSING_STARTED     0x80000000
  96   97  
  97   98  /*
  98   99   * For solicited commands, there's only 3 states:
  99  100   * 1) it's new. We need send it to FCA. ICMD_SOLCMD_NEW is set
 100  101   * 2) it's running. We are waiting for completion.
 101  102   * 3) it's completed. We need free it. ICMD_CMD_COMPLETE is set
 102  103   * ICMD_SOLCMD_NEW and ICMD_CMD_COMPLETE should not be set in the same time
 103  104   */
 104  105  #define ICMD_IN_SOLCMD_QUEUE            0x010000
 105  106  #define ICMD_SOLCMD_NEW                 0x020000
 106  107  
 107  108  typedef struct fct_i_remote_port {
 108  109          fct_remote_port_t               *irp_rp;
  
    | 
      ↓ open down ↓ | 
    23 lines elided | 
    
      ↑ open up ↑ | 
  
 109  110          uint32_t                        irp_alloc_size;
 110  111          fct_struct_id_t                 irp_struct_id;
 111  112          krwlock_t                       irp_lock;
 112  113  
 113  114          /* For queueing to local port */
 114  115          struct fct_i_remote_port        *irp_next;
 115  116  
 116  117          /* For queueing to handle elses */
 117  118          struct fct_i_remote_port        *irp_discovery_next;
 118  119  
 119      -        fct_i_cmd_t                     *irp_els_list;
      120 +        list_t                          irp_els_list;
 120  121  
 121  122          /*
 122  123           * sa stands for session affecting, nsa is non session affecting.
 123  124           * The els counts only represent elses under progress not the ones
 124  125           * that are terminated. active_xchg_count covers everything including
 125  126           * the ones waiting to be terminated.
 126  127           */
 127  128          uint16_t                        irp_sa_elses_count;
 128  129          uint16_t                        irp_nsa_elses_count;
 129  130          uint16_t                        irp_fcp_xchg_count;
 130  131          uint16_t                        irp_nonfcp_xchg_count;
 131  132  
 132  133          uint32_t                        irp_flags;
 133  134          clock_t                         irp_deregister_timer;
 134  135          uint32_t                        irp_dereg_count;
 135  136  
 136  137          uint32_t                        irp_portid;
  
    | 
      ↓ open down ↓ | 
    7 lines elided | 
    
      ↑ open up ↑ | 
  
 137  138          uint8_t                         irp_id[24];
 138  139          uint32_t                        irp_rcvd_prli_params;
 139  140          uint32_t                        irp_sent_prli_params;
 140  141  
 141  142          /*
 142  143           * Most HBAs will only register symbolic node name instead of port name,
 143  144           * so we use SNN as session alias.
 144  145           */
 145  146          stmf_scsi_session_t             *irp_session;
 146  147          char                            *irp_snn;
      148 +        uint16_t                        irp_snn_len;
 147  149  
 148  150          /* items will be filled in ns cmd */
 149  151          uint8_t                         irp_fc4types[32]; /* FC-4 types */
 150  152          char                            *irp_spn;       /* port symbolic name */
      153 +        uint16_t                        irp_spn_len;
 151  154          uint32_t                        irp_cos;        /* class of service */
 152  155  
 153  156          uint32_t                        irp_rscn_counter;
 154  157  } fct_i_remote_port_t;
 155  158  
 156  159  /*
 157  160   * structure used for fct_rls_cb() callback private data
 158  161   */
 159  162  typedef struct fct_rls_cb_data {
 160  163          struct fct_port_link_status     *fct_link_status;
 161  164          fct_status_t                    fct_els_res;
 162  165  } fct_rls_cb_data_t;
 163  166  
 164  167  /*
 165  168   * irp flags
 166  169   */
 167  170  #define IRP_PLOGI_DONE                  0x0001
 168  171  #define IRP_PRLI_DONE                   0x0002
 169  172  #define IRP_IN_DISCOVERY_QUEUE          0x0004
 170  173  #define IRP_FCP_CLEANUP                 0x0008
 171  174  #define IRP_SESSION_CLEANUP             (IRP_FCP_CLEANUP | 0x0010)
 172  175  #define IRP_HANDLE_OPENED               0x0020
 173  176  #define IRP_SCSI_SESSION_STARTED        0x0040
 174  177  #define IRP_RSCN_QUEUED                 0x0080
 175  178  #define IRP_SOL_PLOGI_IN_PROGRESS       0x0100
 176  179  
 177  180  typedef struct fct_cmd_slot {
 178  181          fct_i_cmd_t             *slot_cmd;
 179  182          uint16_t                slot_no;
 180  183          uint16_t                slot_next;
 181  184          uint8_t                 slot_uniq_cntr;
 182  185  } fct_cmd_slot_t;
 183  186  #define FCT_SLOT_EOL            0xffff
 184  187  
 185  188  #define FCT_HASH_TABLE_SIZE             256
 186  189  #define FCT_LOOP_HASH(portid)           (portid & 0xff)
 187  190  #define FCT_FABRIC_HASH(portid)         (((portid & 0x1f00) | \
 188  191          ((portid & 0x70000)>>3)) >> 8)
 189  192  #define FCT_PORTID_HASH_FUNC(portid) \
 190  193          ((portid & 0xFFFF00)?FCT_FABRIC_HASH(portid):FCT_LOOP_HASH(portid))
 191  194  
 192  195  typedef struct fct_i_local_port {
 193  196          fct_local_port_t        *iport_port;
 194  197          uint32_t                iport_alloc_size;
 195  198          fct_struct_id_t         iport_struct_id;
 196  199  
 197  200          struct fct_i_local_port *iport_next;
 198  201          struct fct_i_local_port *iport_prev;
 199  202  
 200  203          char                    *iport_alias;
 201  204          char                    iport_alias_mem[16];
 202  205          uint8_t                 iport_id[24];   /* scsi_devid_desc_t */
 203  206          krwlock_t               iport_lock;
 204  207          uint32_t                iport_flags;
 205  208          uint16_t                iport_link_state;
 206  209          uint8_t                 iport_state:7,
 207  210              iport_state_not_acked:1;
 208  211          uint8_t                 iport_offline_prstate;
 209  212          struct fct_link_info    iport_link_info;
 210  213  
 211  214          fct_i_remote_port_t     **iport_rp_slots;
 212  215          fct_i_remote_port_t     **iport_rp_tb;
 213  216          uint32_t                iport_nrps_login; /* currently logged in */
 214  217          uint32_t                iport_nrps;     /* items in hash table */
 215  218          uint64_t                iport_last_change;
 216  219  
 217  220          /*
 218  221           * These variables are used to manage fct_cmd_t cache for SCSI traffic
 219  222           */
 220  223          /*
 221  224           * Total # of cmds allocated by the driver. Some of which are free
 222  225           * and sitting on iport_cached_cmdlist. And some are executing.
 223  226           */
 224  227          uint32_t                iport_total_alloced_ncmds;
  
    | 
      ↓ open down ↓ | 
    64 lines elided | 
    
      ↑ open up ↑ | 
  
 225  228  
 226  229          /*
 227  230           * Max active cmds in last interval (10 or 30 seconds)
 228  231           */
 229  232          uint32_t                iport_max_active_ncmds;
 230  233  
 231  234          /*
 232  235           * # of free cmds sitting on the iport_cached_cmdlist
 233  236           */
 234  237          uint32_t                iport_cached_ncmds;
 235      -        struct fct_i_cmd        *iport_cached_cmdlist;
      238 +        list_t                  iport_cached_cmdlist;
 236  239          kmutex_t                iport_cached_cmd_lock;
 237  240  
 238  241          /*
 239  242           * To release free cmds periodically
 240  243           */
 241  244          clock_t                 iport_cmdcheck_clock;
 242  245  
 243  246          uint16_t                iport_task_green_limit;
 244  247          uint16_t                iport_task_yellow_limit;
 245  248          uint16_t                iport_task_red_limit;
 246  249          /* cmd slots */
 247  250          uint16_t                iport_nslots_free;
 248  251  
 249  252          /* upper 16 bits is just a counter to avoid ABA issues */
 250  253          uint32_t                iport_next_free_slot;
 251  254  
 252  255          uint8_t                 iport_login_retry; /* for flogi and N2N plogi */
 253  256          uint8_t                 iport_link_old_topology;
  
    | 
      ↓ open down ↓ | 
    8 lines elided | 
    
      ↑ open up ↑ | 
  
 254  257          uint8_t                 iport_link_cleanup_retry;
 255  258          clock_t                 iport_li_cmd_timeout; /* for li state m/c */
 256  259          fct_cmd_slot_t          *iport_cmd_slots;
 257  260  
 258  261          /* worker thread data */
 259  262          ddi_taskq_t             *iport_worker_taskq;
 260  263          kmutex_t                iport_worker_lock;
 261  264          kcondvar_t              iport_worker_cv;
 262  265          struct fct_i_event      *iport_event_head;
 263  266          struct fct_i_event      *iport_event_tail;
 264      -        struct fct_i_cmd        *iport_abort_queue;
 265      -        struct fct_i_cmd        **iport_ppicmd_term;
      267 +        list_t                  iport_abort_queue;
      268 +        struct fct_i_cmd        *iport_ppicmd_term;
 266  269  
 267  270          /* link initialization */
 268  271          fct_status_t            iport_li_comp_status;
 269  272          enum fct_li_state       iport_li_state;
 270  273  
 271  274          /* solicited cmd link */
 272  275          struct fct_i_cmd        *iport_solcmd_queue;
 273  276  
 274  277          /* rpwe = remote port with pending els(es) */
 275  278          fct_i_remote_port_t     *iport_rpwe_head;
 276  279          fct_i_remote_port_t     *iport_rpwe_tail;
 277  280          kstat_t                 *iport_kstat_portstat;
 278  281          ksema_t                 iport_rls_sema;
 279  282          fct_rls_cb_data_t       iport_rls_cb_data;
 280  283  } fct_i_local_port_t;
 281  284  
 282  285  #define IPORT_FLOGI_DONE(iport) PORT_FLOGI_DONE(&(iport)->iport_link_info)
 283  286  
 284  287  /*
 285  288   * iport flags
 286  289   */
 287  290  #define IPORT_WORKER_RUNNING            0x0001
 288  291  #define IPORT_TERMINATE_WORKER          0x0002
 289  292  #define IPORT_WORKER_DOING_TIMEDWAIT    0x0004
 290  293  #define IPORT_WORKER_DOING_WAIT         0x0008
 291  294  #define IPORT_FLAG_PORT_OFFLINED        0x0010
 292  295  #define IPORT_ALLOW_UNSOL_FLOGI         0x0020
 293  296  
 294  297  #define IS_WORKER_SLEEPING(iport)       ((iport)->iport_flags & \
 295  298          (IPORT_WORKER_DOING_TIMEDWAIT | IPORT_WORKER_DOING_WAIT))
 296  299  
 297  300  /* Limits for scsi task load of local port */
 298  301  #define FCT_TASK_GREEN_LIMIT            80
 299  302  #define FCT_TASK_YELLOW_LIMIT           90
 300  303  #define FCT_TASK_RED_LIMIT              95
 301  304  
 302  305  typedef struct fct_i_event {
 303  306          struct fct_i_event      *event_next;
 304  307          int                     event_type;
 305  308  } fct_i_event_t;
 306  309  
 307  310  typedef enum { /* Seggested action values for discovery thread */
 308  311      DISC_ACTION_NO_WORK = 0,
 309  312      DISC_ACTION_RESCAN = 1,
 310  313      DISC_ACTION_DELAY_RESCAN = 2,
 311  314      DISC_ACTION_USE_SHORT_DELAY = 4
 312  315  } disc_action_t;
 313  316  
 314  317  /*
 315  318   * Local port state definitions
 316  319   * NOTE that every time there is a state change, the newly set bit suggests
 317  320   * the action. So far there are 3 actions S_PORT_CLEANUP, S_ADAPTER_FATAL
 318  321   * and S_INIT_LINK.
 319  322   */
 320  323  #define S_RCVD_LINK_DOWN        0x01
 321  324  #define S_RCVD_LINK_UP          0x02
 322  325  #define S_LINK_ONLINE           0x04
 323  326  #define S_INIT_LINK             0x08
 324  327  #define S_PORT_CLEANUP          0x10
 325  328  
 326  329  #define PORT_STATE_LINK_DOWN            0x00
 327  330  #define PORT_STATE_LINK_INIT_START      (S_RCVD_LINK_UP | S_LINK_ONLINE |\
 328  331      S_INIT_LINK)
 329  332  #define PORT_STATE_LINK_INIT_DONE       (S_LINK_ONLINE)
 330  333  #define PORT_STATE_LINK_UP_CLEANING     (S_RCVD_LINK_UP | S_PORT_CLEANUP)
 331  334  #define PORT_STATE_LINK_DOWN_CLEANING   (S_RCVD_LINK_DOWN | S_PORT_CLEANUP)
 332  335  
 333  336  /*
 334  337   * Internal events
 335  338   */
 336  339  #define FCT_I_EVENT_LINK_INIT_DONE      0x80
 337  340  #define FCT_I_EVENT_CLEANUP_POLL        0x81
 338  341  
 339  342  /*
 340  343   * Offline processing states, used by worker thread.
 341  344   */
 342  345  #define FCT_OPR_DONE                    0
 343  346  #define FCT_OPR_START                   1
 344  347  #define FCT_OPR_CMD_CLEANUP_WAIT        2
 345  348  #define FCT_OPR_INT_CLEANUP_WAIT        3
 346  349  
 347  350  /*
 348  351   * Check time
 349  352   */
 350  353  #define FCT_CMDLIST_CHECK_SECONDS       10
 351  354  
 352  355  /*
 353  356   * Define frequently used macros
 354  357   */
 355  358  #define ICMD_TO_CT(x_icmd)      \
 356  359          ((fct_sol_ct_t *)(x_icmd)->icmd_cmd->cmd_specific)
 357  360  
 358  361  #define ICMD_TO_ELS(x_icmd)     \
 359  362          ((fct_els_t *)(x_icmd)->icmd_cmd->cmd_specific)
 360  363  
 361  364  #define ICMD_TO_IPORT(x_icmd)   \
 362  365          ((fct_i_local_port_t *)(x_icmd)->icmd_cmd->cmd_port->port_fct_private)
 363  366  
 364  367  #define ICMD_TO_PORT(x_icmd)    \
 365  368          ((x_icmd)->icmd_cmd->cmd_port)
 366  369  
 367  370  #define ICMD_TO_IRP(x_icmd)     \
 368  371          ((fct_i_remote_port_t *)(x_icmd)->icmd_cmd->cmd_rp->rp_fct_private)
 369  372  
 370  373  #define CMD_TO_ICMD(x_cmd)      ((fct_i_cmd_t *)(x_cmd)->cmd_fct_private)
 371  374  
 372  375  #define RP_TO_IRP(x_rp)         ((fct_i_remote_port_t *)(x_rp)->rp_fct_private)
 373  376  
 374  377  #define PORT_TO_IPORT(x_port)   \
 375  378          ((fct_i_local_port_t *)(x_port)->port_fct_private)
 376  379  
 377  380  #define FCT_IS_ELS_ACC(x_icmd)  \
 378  381          (((x_icmd)->icmd_cmd->cmd_comp_status == FCT_SUCCESS) &&        \
 379  382          (ICMD_TO_ELS(x_icmd)->els_resp_payload[0] == ELS_OP_ACC))
 380  383  
 381  384  #define FCT_IS_CT_ACC(x_icmd)   \
 382  385          (((x_icmd)->icmd_cmd->cmd_comp_status == FCT_SUCCESS) &&        \
 383  386          (ICMD_TO_CT(x_icmd)->ct_resp_payload[8] == 0x80) &&\
 384  387          (ICMD_TO_CT(x_icmd)->ct_resp_payload[9] == 0x02))
 385  388  
 386  389  #define IPORT_IN_NS_TOPO(x_iport)       \
 387  390          ((x_iport)->iport_link_info.port_topology & PORT_TOPOLOGY_FABRIC_BIT)
 388  391  
 389  392  #define IS_LOGO_ELS(icmd)       \
 390  393          (ICMD_TO_ELS(icmd)->els_req_payload[0] == ELS_OP_LOGO)
 391  394  
 392  395  stmf_status_t fct_xfer_scsi_data(scsi_task_t *task,
 393  396      stmf_data_buf_t *dbuf, uint32_t ioflags);
 394  397  stmf_status_t fct_send_scsi_status(scsi_task_t *task, uint32_t ioflags);
 395  398  fct_i_remote_port_t *fct_portid_to_portptr(fct_i_local_port_t *iport,
 396  399      uint32_t portid);
 397  400  fct_i_remote_port_t *fct_lookup_irp_by_nodewwn(fct_i_local_port_t *iport,
 398  401      uint8_t *nodewwn);
 399  402  fct_i_remote_port_t *fct_lookup_irp_by_portwwn(fct_i_local_port_t *iport,
 400  403      uint8_t *portwwn);
 401  404  void fct_queue_rp(fct_i_local_port_t *iport, fct_i_remote_port_t *irp);
 402  405  void fct_deque_rp(fct_i_local_port_t *iport, fct_i_remote_port_t *irp);
 403  406  int fct_implicitly_logo_all(fct_i_local_port_t *iport, int force_implicit);
 404  407  void fct_post_implicit_logo(fct_cmd_t *cmd);
 405  408  void fct_rehash(fct_i_local_port_t *iport);
 406  409  uint8_t fct_local_port_cleanup_done(fct_i_local_port_t *iport);
 407  410  void fct_handle_rcvd_abts(fct_cmd_t *cmd);
 408  411  void fct_fill_abts_acc(fct_cmd_t *cmd);
 409  412  void fct_q_for_termination_lock_held(fct_i_local_port_t *iport,
 410  413      fct_i_cmd_t *icmd, fct_status_t s);
 411  414  disc_action_t fct_handle_port_offline(fct_i_local_port_t *iport);
 412  415  disc_action_t fct_cmd_terminator(fct_i_local_port_t *iport);
 413  416  void fct_cmd_free(fct_cmd_t *cmd);
 414  417  void fct_scsi_task_free(scsi_task_t *task);
 415  418  stmf_status_t fct_scsi_abort(stmf_local_port_t *lport, int abort_cmd,
 416  419      void *arg, uint32_t flags);
 417  420  stmf_status_t fct_info(uint32_t cmd, stmf_local_port_t *lport,
 418  421      void *arg, uint8_t *buf, uint32_t *bufsizep);
 419  422  void fct_event_handler(stmf_local_port_t *lport, int eventid,
 420  423      void *arg, uint32_t flags);
 421  424  uint16_t fct_alloc_cmd_slot(fct_i_local_port_t *iport, fct_cmd_t *cmd);
 422  425  void fct_post_to_discovery_queue(fct_i_local_port_t *iport,
 423  426      fct_i_remote_port_t *irp, fct_i_cmd_t *icmd);
 424  427  fct_cmd_t *fct_create_solct(fct_local_port_t *port, fct_remote_port_t *rp,
 425  428      uint16_t ctop, fct_icmd_cb_t icmdcb);
 426  429  fct_cmd_t *fct_create_solels(fct_local_port_t *port, fct_remote_port_t *rp,
 427  430      int implicit, uchar_t elsop, uint32_t wkdid, fct_icmd_cb_t icmdcb);
  
    | 
      ↓ open down ↓ | 
    152 lines elided | 
    
      ↑ open up ↑ | 
  
 428  431  void fct_handle_solct(fct_cmd_t *cmd);
 429  432  void fct_post_to_solcmd_queue(fct_local_port_t *port, fct_cmd_t *cmd);
 430  433  void fct_logo_cb(fct_i_cmd_t *icmd);
 431  434  void fct_link_init_cb(fct_i_cmd_t *icmd);
 432  435  void fct_gsnn_cb(fct_i_cmd_t *icmd);
 433  436  void fct_gcs_cb(fct_i_cmd_t *icmd);
 434  437  void fct_gft_cb(fct_i_cmd_t *icmd);
 435  438  void fct_gspn_cb(fct_i_cmd_t *icmd);
 436  439  void fct_rls_cb(fct_i_cmd_t *icmd);
 437  440  disc_action_t fct_process_link_init(fct_i_local_port_t *iport);
      441 +void fct_cmd_unlink_els(fct_i_remote_port_t *irp, fct_i_cmd_t *icmd);
 438  442  
 439  443  #ifdef  __cplusplus
 440  444  }
 441  445  #endif
 442  446  
 443  447  #endif /* _FCT_IMPL_H */
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX