Print this page
    
NEX-3672 IDM module panics target when PDU has AHS length between 17 and 49
Reviewed by: Steve Peng <steve.peng@nexenta.com>
Reviewed by: Rob Gittins <rob.gittins@nexenta.com>
    
      
        | Split | 
	Close | 
      
      | Expand all | 
      | Collapse all | 
    
    
          --- old/usr/src/uts/common/sys/idm/idm_impl.h
          +++ new/usr/src/uts/common/sys/idm/idm_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   *
  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.
  
    | 
      ↓ open down ↓ | 
    14 lines elided | 
    
      ↑ open up ↑ | 
  
  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 (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  23   23   */
  24   24  /*
  25      - * Copyright 2014 Nexenta Systems, Inc.  All rights reserved.
       25 + * Copyright 2014-2015 Nexenta Systems, Inc.  All rights reserved.
  26   26   */
  27   27  
  28   28  #ifndef _IDM_IMPL_H_
  29   29  #define _IDM_IMPL_H_
  30   30  
  31   31  #ifdef  __cplusplus
  32   32  extern "C" {
  33   33  #endif
  34   34  
  35   35  #include <sys/avl.h>
  36   36  #include <sys/socket_impl.h>
  37   37  #include <sys/taskq_impl.h>
  38   38  
  39   39  /*
  40   40   * IDM lock order:
  41   41   *
  42   42   * idm_taskid_table_lock, idm_task_t.idt_mutex
  43   43   */
  44   44  
  45   45  #define CF_LOGIN_READY          0x00000001
  46   46  #define CF_INITIAL_LOGIN        0x00000002
  47   47  #define CF_ERROR                0x80000000
  48   48  
  49   49  typedef enum {
  50   50          CONN_TYPE_INI = 1,
  51   51          CONN_TYPE_TGT
  52   52  } idm_conn_type_t;
  53   53  
  54   54  /*
  55   55   * Watchdog interval in seconds
  56   56   */
  57   57  #define IDM_WD_INTERVAL                 5
  58   58  
  59   59  /*
  60   60   * Timeout period before the client "keepalive" callback is invoked in
  61   61   * seconds if the connection is idle.
  62   62   */
  63   63  #define IDM_TRANSPORT_KEEPALIVE_IDLE_TIMEOUT    20
  64   64  
  65   65  /*
  66   66   * Timeout period before a TRANSPORT_FAIL event is generated in seconds
  67   67   * if the connection is idle.
  68   68   */
  69   69  #define IDM_TRANSPORT_FAIL_IDLE_TIMEOUT 30
  70   70  
  71   71  /*
  72   72   * IDM reference count structure.  Audit code is shamelessly adapted
  73   73   * from CIFS server.
  74   74   */
  75   75  
  76   76  #define REFCNT_AUDIT_STACK_DEPTH        16
  77   77  #define REFCNT_AUDIT_BUF_MAX_REC        16
  78   78  
  79   79  typedef struct {
  80   80          uint32_t                anr_refcnt;
  81   81          int                     anr_depth;
  82   82          pc_t                    anr_stack[REFCNT_AUDIT_STACK_DEPTH];
  83   83  } refcnt_audit_record_t;
  84   84  
  85   85  typedef struct {
  86   86          int                     anb_index;
  87   87          int                     anb_max_index;
  88   88          refcnt_audit_record_t   anb_records[REFCNT_AUDIT_BUF_MAX_REC];
  89   89  } refcnt_audit_buf_t;
  90   90  
  91   91  #define REFCNT_AUDIT(_rf_) {                            \
  92   92          refcnt_audit_record_t   *anr;                   \
  93   93                                                          \
  94   94          anr = (_rf_)->ir_audit_buf.anb_records;         \
  95   95          anr += (_rf_)->ir_audit_buf.anb_index;          \
  96   96          (_rf_)->ir_audit_buf.anb_index++;               \
  97   97          (_rf_)->ir_audit_buf.anb_index &=               \
  98   98              (_rf_)->ir_audit_buf.anb_max_index;         \
  99   99          anr->anr_refcnt = (_rf_)->ir_refcnt;            \
 100  100          anr->anr_depth = getpcstack(anr->anr_stack,     \
 101  101              REFCNT_AUDIT_STACK_DEPTH);                  \
 102  102  }
 103  103  
 104  104  struct idm_refcnt_s;
 105  105  
 106  106  typedef void (idm_refcnt_cb_t)(void *ref_obj);
 107  107  
 108  108  typedef enum {
 109  109          REF_NOWAIT,
 110  110          REF_WAIT_SYNC,
 111  111          REF_WAIT_ASYNC
 112  112  } idm_refcnt_wait_t;
 113  113  
 114  114  typedef struct idm_refcnt_s {
 115  115          int                     ir_refcnt;
 116  116          void                    *ir_referenced_obj;
 117  117          idm_refcnt_wait_t       ir_waiting;
 118  118          kmutex_t                ir_mutex;
 119  119          kcondvar_t              ir_cv;
 120  120          idm_refcnt_cb_t         *ir_cb;
 121  121          refcnt_audit_buf_t      ir_audit_buf;
 122  122  } idm_refcnt_t;
 123  123  
 124  124  /*
 125  125   * connection parameters - These parameters would be populated at
 126  126   * connection create, or during key-value negotiation at login
 127  127   */
 128  128  typedef struct idm_conn_params_s {
 129  129          uint32_t                max_recv_dataseglen;
 130  130          uint32_t                max_xmit_dataseglen;
 131  131          uint32_t                conn_login_max;
 132  132          uint32_t                conn_login_interval;
 133  133          boolean_t               nonblock_socket;
 134  134  } idm_conn_param_t;
 135  135  
 136  136  typedef struct idm_svc_s {
 137  137          list_node_t             is_list_node;
 138  138          kmutex_t                is_mutex;
 139  139          kcondvar_t              is_cv;
 140  140          kmutex_t                is_count_mutex;
 141  141          kcondvar_t              is_count_cv;
 142  142          idm_refcnt_t            is_refcnt;
 143  143          int                     is_online;
 144  144          /* transport-specific service components */
 145  145          void                    *is_so_svc;
 146  146          void                    *is_iser_svc;
 147  147          idm_svc_req_t           is_svc_req;
 148  148  } idm_svc_t;
 149  149  
 150  150  #define ISCSI_MAX_TSIH_LEN      6       /* 0x%04x */
 151  151  #define ISCSI_MAX_ISID_LEN      ISCSI_ISID_LEN * 2
 152  152  
 153  153  typedef struct idm_conn_s {
 154  154          list_node_t             ic_list_node;
 155  155          void                    *ic_handle;
 156  156          idm_refcnt_t            ic_refcnt;
 157  157          idm_svc_t               *ic_svc_binding; /* Target conn. only */
 158  158          idm_sockaddr_t          ic_ini_dst_addr;
 159  159          struct sockaddr_storage ic_laddr;       /* conn local address */
 160  160          struct sockaddr_storage ic_raddr;       /* conn remote address */
 161  161  
 162  162          /*
 163  163           * the target_name, initiator_name, initiator session
 164  164           * identifier and target session identifying handle
 165  165           * are only used for target connections.
 166  166           */
 167  167          char                    ic_target_name[ISCSI_MAX_NAME_LEN + 1];
 168  168          char                    ic_initiator_name[ISCSI_MAX_NAME_LEN + 1];
 169  169          char                    ic_tsih[ISCSI_MAX_TSIH_LEN + 1];
 170  170          char                    ic_isid[ISCSI_MAX_ISID_LEN + 1];
 171  171          idm_conn_state_t        ic_state;
 172  172          idm_conn_state_t        ic_last_state;
 173  173          sm_audit_buf_t          ic_state_audit;
 174  174          kmutex_t                ic_state_mutex;
 175  175          kcondvar_t              ic_state_cv;
 176  176          uint32_t                ic_state_flags;
 177  177          timeout_id_t            ic_state_timeout;
 178  178          struct idm_conn_s       *ic_reinstate_conn; /* For conn reinst. */
 179  179          struct idm_conn_s       *ic_logout_conn; /* For other conn logout */
 180  180          taskq_t                 *ic_state_taskq;
 181  181          int                     ic_pdu_events;
 182  182          boolean_t               ic_login_info_valid;
 183  183          boolean_t               ic_rdma_extensions;
 184  184          uint16_t                ic_login_cid;
 185  185  
 186  186          kmutex_t                ic_mutex;
 187  187          kcondvar_t              ic_cv;
 188  188          idm_status_t            ic_conn_sm_status;
 189  189  
 190  190          boolean_t               ic_ffp;
 191  191          boolean_t               ic_keepalive;
 192  192          uint32_t                ic_internal_cid;
 193  193  
 194  194          uint32_t                ic_conn_flags;
 195  195          idm_conn_type_t         ic_conn_type;
 196  196          idm_conn_ops_t          ic_conn_ops;
 197  197          idm_transport_ops_t     *ic_transport_ops;
 198  198          idm_transport_type_t    ic_transport_type;
 199  199          int                     ic_transport_hdrlen;
 200  200          void                    *ic_transport_private;
 201  201          idm_conn_param_t        ic_conn_params;
 202  202          /*
 203  203           * Save client callback to interpose idm callback
 204  204           */
 205  205          idm_pdu_cb_t            *ic_client_callback;
 206  206          clock_t                 ic_timestamp;
 207  207  } idm_conn_t;
 208  208  
 209  209  #define IDM_CONN_HEADER_DIGEST  0x00000001
 210  210  #define IDM_CONN_DATA_DIGEST    0x00000002
 211  211  #define IDM_CONN_USE_SCOREBOARD 0x00000004
 212  212  
 213  213  #define IDM_CONN_ISINI(ICI_IC)  ((ICI_IC)->ic_conn_type == CONN_TYPE_INI)
 214  214  #define IDM_CONN_ISTGT(ICI_IC)  ((ICI_IC)->ic_conn_type == CONN_TYPE_TGT)
 215  215  
 216  216  /*
 217  217   * An IDM target task can transfer data using multiple buffers. The task
 218  218   * will maintain a list of buffers, and each buffer will contain the relative
 219  219   * offset of the transfer and a pointer to the next buffer in the list.
 220  220   *
 221  221   * Note on client private data:
 222  222   * idt_private is intended to be a pointer to some sort of client-
 223  223   * specific state.
 224  224   *
 225  225   * idt_client_handle is a more generic client-private piece of data that can
 226  226   * be used by the client for the express purpose of task lookup.  The driving
 227  227   * use case for this is for the client to store the initiator task tag for
 228  228   * a given task so that it may be more easily retrieved for task management.
 229  229   *
 230  230   * The key take away here is that clients should never call
 231  231   * idm_task_find_by_handle in the performance path.
 232  232   *
 233  233   * An initiator will require only one buffer per task, the offset will be 0.
 234  234   */
 235  235  
 236  236  typedef struct idm_task_s {
 237  237          idm_conn_t              *idt_ic;        /* Associated connection */
 238  238          /* connection type is in idt_ic->ic_conn_type */
 239  239          kmutex_t                idt_mutex;
 240  240          void                    *idt_private;   /* Client private data */
 241  241          uintptr_t               idt_client_handle;      /* Client private */
 242  242          uint32_t                idt_tt;         /* Task tag */
 243  243          uint32_t                idt_r2t_ttt;    /* R2T Target Task tag */
 244  244          idm_task_state_t        idt_state;
 245  245          idm_refcnt_t            idt_refcnt;
 246  246  
 247  247          /*
 248  248           * Statistics
 249  249           */
 250  250          int                     idt_tx_to_ini_start;
 251  251          int                     idt_tx_to_ini_done;
 252  252          int                     idt_rx_from_ini_start;
 253  253          int                     idt_rx_from_ini_done;
 254  254          int                     idt_tx_bytes;   /* IDM_CONN_USE_SCOREBOARD */
 255  255          int                     idt_rx_bytes;   /* IDM_CONN_USE_SCOREBOARD */
 256  256  
 257  257          uint32_t                idt_exp_datasn; /* expected datasn */
 258  258          uint32_t                idt_exp_rttsn;  /* expected rttsn */
 259  259          list_t                  idt_inbufv;     /* chunks of IN buffers */
 260  260          list_t                  idt_outbufv;    /* chunks of OUT buffers */
 261  261  
 262  262          /*
 263  263           * Transport header, which describes this tasks remote tagged buffer
 264  264           */
 265  265          int                     idt_transport_hdrlen;
 266  266          void                    *idt_transport_hdr;
 267  267          uint32_t                idt_flags;      /* phase collapse */
 268  268  } idm_task_t;
 269  269  
 270  270  int idm_task_constructor(void *task_void, void *arg, int flags);
 271  271  void idm_task_destructor(void *task_void, void *arg);
 272  272  
 273  273  #define IDM_TASKIDS_MAX         16384
 274  274  #define IDM_BUF_MAGIC           0x49425546      /* "IBUF" */
 275  275  
 276  276  #define IDM_TASK_PHASECOLLAPSE_REQ      0x00000001 /* request phase collapse */
 277  277  #define IDM_TASK_PHASECOLLAPSE_SUCCESS  0x00000002 /* phase collapse success */
 278  278  
 279  279  /* Protect with task mutex */
 280  280  typedef struct idm_buf_s {
 281  281          uint32_t        idb_magic;      /* "IBUF" */
 282  282  
 283  283          /*
 284  284           * Note: idm_tx_link *must* be the second element in the list for
 285  285           * proper TX PDU ordering.
 286  286           */
 287  287          list_node_t     idm_tx_link;    /* link in a list of TX objects */
 288  288  
 289  289          list_node_t     idb_buflink;    /* link in a multi-buffer data xfer */
 290  290          idm_conn_t      *idb_ic;        /* Associated connection */
 291  291          void            *idb_buf;       /* data */
 292  292          uint64_t        idb_buflen;     /* length of buffer */
 293  293          size_t          idb_bufoffset;  /* offset in a multi-buffer xfer */
 294  294          boolean_t       idb_bufalloc;  /* true if alloc'd in idm_buf_alloc */
 295  295          /*
 296  296           * DataPDUInOrder=Yes, so to track that the PDUs in a sequence are sent
 297  297           * in continuously increasing address order, check that offsets for a
 298  298           * single buffer xfer are in order.
 299  299           */
 300  300          uint32_t        idb_exp_offset;
 301  301          size_t          idb_xfer_len;   /* Current requested xfer len */
 302  302          void            *idb_buf_private; /* transport-specific buf handle */
 303  303          void            *idb_reg_private; /* transport-specific reg handle */
 304  304          void            *idb_bufptr; /* transport-specific bcopy pointer */
 305  305          boolean_t       idb_bufbcopy;   /* true if bcopy required */
 306  306  
 307  307          idm_buf_cb_t    *idb_buf_cb;    /* Data Completion Notify, tgt only */
 308  308          void            *idb_cb_arg;    /* Client private data */
 309  309          idm_task_t      *idb_task_binding;
 310  310          timespec_t      idb_xfer_start;
 311  311          timespec_t      idb_xfer_done;
 312  312          boolean_t       idb_in_transport;
 313  313          boolean_t       idb_tx_thread;          /* Sockets only */
 314  314          iscsi_hdr_t     idb_data_hdr_tmpl;      /* Sockets only */
 315  315          idm_status_t    idb_status;
 316  316  } idm_buf_t;
 317  317  
 318  318  typedef enum {
 319  319          BP_CHECK_QUICK,
 320  320          BP_CHECK_THOROUGH,
 321  321          BP_CHECK_ASSERT
 322  322  } idm_bufpat_check_type_t;
 323  323  
 324  324  #define BUFPAT_MATCH(bc_bufpat, bc_idb)                 \
 325  325          ((bufpat->bufpat_idb == bc_idb) &&              \
 326  326              (bufpat->bufpat_bufmagic == IDM_BUF_MAGIC))
 327  327  
 328  328  typedef struct idm_bufpat_s {
 329  329          void            *bufpat_idb;
 330  330          uint32_t        bufpat_bufmagic;
 331  331          uint32_t        bufpat_offset;
 332  332  } idm_bufpat_t;
 333  333  
 334  334  #define PDU_MAX_IOVLEN  12
 335  335  #define IDM_PDU_MAGIC   0x49504455      /* "IPDU" */
 336  336  
 337  337  typedef struct idm_pdu_s {
 338  338          uint32_t        isp_magic;      /* "IPDU" */
 339  339  
 340  340          /*
 341  341           * Internal - Order is vital.  idm_tx_link *must* be the second
 342  342           * element in this structure for proper TX PDU ordering.
 343  343           */
 344  344          list_node_t     idm_tx_link;
 345  345  
 346  346          list_node_t     isp_client_lnd;
 347  347  
 348  348          idm_conn_t      *isp_ic;        /* Must be set */
 349  349          iscsi_hdr_t     *isp_hdr;
 350  350          uint_t          isp_hdrlen;
 351  351          uint8_t         *isp_data;
 352  352          uint_t          isp_datalen;
 353  353  
 354  354          /* Transport header */
 355  355          void            *isp_transport_hdr;
 356  356          uint32_t        isp_transport_hdrlen;
 357  357          void            *isp_transport_private;
 358  358  
 359  359          /*
 360  360           * isp_data is used for sending SCSI status, NOP, text, scsi and
 361  361           * non-scsi data. Data is received using isp_iov and isp_iovlen
 362  362           * to support data over multiple buffers.
 363  363           */
 364  364          void            *isp_private;
 365  365          idm_pdu_cb_t    *isp_callback;
 366  366          idm_status_t    isp_status;
 367  367  
 368  368          /*
 369  369           * The following four elements are only used in
 370  370           * idm_sorecv_scsidata() currently.
 371  371           */
 372  372          struct iovec    isp_iov[PDU_MAX_IOVLEN];
 373  373          int             isp_iovlen;
 374  374          idm_buf_t       *isp_sorx_buf;
 375  375  
 376  376          /* Implementation data for idm_pdu_alloc and sorx PDU cache */
 377  377          uint32_t        isp_flags;
 378  378          uint_t          isp_hdrbuflen;
 379  379          uint_t          isp_databuflen;
 380  380          hrtime_t        isp_queue_time;
 381  381  
 382  382          /* Taskq dispatching state for deferred PDU */
 383  383          taskq_ent_t     isp_tqent;
 384  384  } idm_pdu_t;
 385  385  
 386  386  /*
 387  387   * This "generic" object is used when removing an item from the ic_tx_list
 388  388   * in order to determine whether it's an idm_pdu_t or an idm_buf_t
 389  389   */
 390  390  
 391  391  typedef struct {
 392  392          uint32_t        idm_tx_obj_magic;
 393  393          /*
 394  394           * idm_tx_link *must* be the second element in this structure.
 395  395           */
 396  396          list_node_t     idm_tx_link;
 397  397  } idm_tx_obj_t;
 398  398  
 399  399  
 400  400  #define IDM_PDU_OPCODE(PDU) \
 401  401          ((PDU)->isp_hdr->opcode & ISCSI_OPCODE_MASK)
  
    | 
      ↓ open down ↓ | 
    366 lines elided | 
    
      ↑ open up ↑ | 
  
 402  402  
 403  403  #define IDM_PDU_ALLOC           0x00000001
 404  404  #define IDM_PDU_ADDL_HDR        0x00000002
 405  405  #define IDM_PDU_ADDL_DATA       0x00000004
 406  406  #define IDM_PDU_LOGIN_TX        0x00000008
 407  407  #define IDM_PDU_SET_STATSN      0x00000010
 408  408  #define IDM_PDU_ADVANCE_STATSN  0x00000020
 409  409  
 410  410  #define OSD_EXT_CDB_AHSLEN      (200 - 15)
 411  411  #define BIDI_AHS_LENGTH         5
      412 +/*
      413 + * Additional Header Segment (AHS)
      414 + * AHS is only valid for SCSI Requests and contains SCSI CDB information
      415 + * which doesn't fit in the standard 16 byte area of the PDU. Commonly
      416 + * this only holds true for OSD device commands.
      417 + *
      418 + * IDM_SORX_CACHE_ASHLEN is the amount of memory which is preallocated in bytes.
      419 + * When used in the header the AHS length is stored as the number of 4-byte
      420 + * words; so IDM_SORX_WIRE_ASHLEN is IDM_SORX_CACHE_ASHLEN in words.
      421 + */
 412  422  #define IDM_SORX_CACHE_AHSLEN \
 413      -        (((OSD_EXT_CDB_AHSLEN + 3) + \
 414      -            (BIDI_AHS_LENGTH + 3)) / sizeof (uint32_t))
      423 +        ((OSD_EXT_CDB_AHSLEN + 3) + (BIDI_AHS_LENGTH + 3))
      424 +#define IDM_SORX_WIRE_AHSLEN (IDM_SORX_CACHE_AHSLEN / sizeof (uint32_t))
 415  425  #define IDM_SORX_CACHE_HDRLEN   (sizeof (iscsi_hdr_t) + IDM_SORX_CACHE_AHSLEN)
 416  426  
 417  427  /*
 418  428   * ID pool
 419  429   */
 420  430  
 421  431  #define IDM_IDPOOL_MAGIC        0x4944504C      /* IDPL */
 422  432  #define IDM_IDPOOL_MIN_SIZE     64      /* Number of IDs to begin with */
 423  433  #define IDM_IDPOOL_MAX_SIZE     64 * 1024
 424  434  
 425  435  typedef struct idm_idpool {
 426  436          uint32_t        id_magic;
 427  437          kmutex_t        id_mutex;
 428  438          uint8_t         *id_pool;
 429  439          uint32_t        id_size;
 430  440          uint8_t         id_bit;
 431  441          uint8_t         id_bit_idx;
 432  442          uint32_t        id_idx;
 433  443          uint32_t        id_idx_msk;
 434  444          uint32_t        id_free_counter;
 435  445          uint32_t        id_max_free_counter;
 436  446  } idm_idpool_t;
 437  447  
 438  448  /*
 439  449   * Global IDM state structure
 440  450   */
 441  451  typedef struct {
 442  452          kmutex_t        idm_global_mutex;
 443  453          taskq_t         *idm_global_taskq;
 444  454          kthread_t       *idm_wd_thread;
 445  455          kt_did_t        idm_wd_thread_did;
 446  456          boolean_t       idm_wd_thread_running;
 447  457          kcondvar_t      idm_wd_cv;
 448  458          list_t          idm_tgt_svc_list;
 449  459          kcondvar_t      idm_tgt_svc_cv;
 450  460          list_t          idm_tgt_conn_list;
 451  461          int             idm_tgt_conn_count;
 452  462          list_t          idm_ini_conn_list;
 453  463          kmem_cache_t    *idm_buf_cache;
 454  464          kmem_cache_t    *idm_task_cache;
 455  465          krwlock_t       idm_taskid_table_lock;
 456  466          idm_task_t      **idm_taskid_table;
 457  467          uint32_t        idm_taskid_next;
 458  468          uint32_t        idm_taskid_max;
 459  469          idm_idpool_t    idm_conn_id_pool;
 460  470          kmem_cache_t    *idm_sotx_pdu_cache;
 461  471          kmem_cache_t    *idm_sorx_pdu_cache;
 462  472          kmem_cache_t    *idm_so_128k_buf_cache;
 463  473  } idm_global_t;
 464  474  
 465  475  idm_global_t    idm; /* Global state */
 466  476  
 467  477  int
 468  478  idm_idpool_create(idm_idpool_t  *pool);
 469  479  
 470  480  void
 471  481  idm_idpool_destroy(idm_idpool_t *pool);
 472  482  
 473  483  int
 474  484  idm_idpool_alloc(idm_idpool_t *pool, uint16_t *id);
 475  485  
 476  486  void
 477  487  idm_idpool_free(idm_idpool_t *pool, uint16_t id);
 478  488  
 479  489  void
 480  490  idm_pdu_rx(idm_conn_t *ic, idm_pdu_t *pdu);
 481  491  
 482  492  void
 483  493  idm_pdu_tx_forward(idm_conn_t *ic, idm_pdu_t *pdu);
 484  494  
 485  495  boolean_t
 486  496  idm_pdu_rx_forward_ffp(idm_conn_t *ic, idm_pdu_t *pdu);
 487  497  
 488  498  void
 489  499  idm_pdu_rx_forward(idm_conn_t *ic, idm_pdu_t *pdu);
 490  500  
 491  501  void
 492  502  idm_pdu_tx_protocol_error(idm_conn_t *ic, idm_pdu_t *pdu);
 493  503  
 494  504  void
 495  505  idm_pdu_rx_protocol_error(idm_conn_t *ic, idm_pdu_t *pdu);
 496  506  
 497  507  void idm_parse_login_rsp(idm_conn_t *ic, idm_pdu_t *logout_req_pdu,
 498  508      boolean_t rx);
 499  509  
 500  510  void idm_parse_logout_req(idm_conn_t *ic, idm_pdu_t *logout_req_pdu,
 501  511      boolean_t rx);
 502  512  
 503  513  void idm_parse_logout_rsp(idm_conn_t *ic, idm_pdu_t *login_rsp_pdu,
 504  514      boolean_t rx);
 505  515  
 506  516  idm_status_t idm_svc_conn_create(idm_svc_t *is, idm_transport_type_t type,
 507  517      idm_conn_t **ic_result);
 508  518  
 509  519  void idm_svc_conn_destroy(idm_conn_t *ic);
 510  520  
 511  521  idm_status_t idm_ini_conn_finish(idm_conn_t *ic);
 512  522  
 513  523  idm_status_t idm_tgt_conn_finish(idm_conn_t *ic);
 514  524  
 515  525  idm_conn_t *idm_conn_create_common(idm_conn_type_t conn_type,
 516  526      idm_transport_type_t tt, idm_conn_ops_t *conn_ops);
 517  527  
 518  528  void idm_conn_destroy_common(idm_conn_t *ic);
 519  529  
 520  530  void idm_conn_close(idm_conn_t *ic);
 521  531  
 522  532  uint32_t idm_cid_alloc(void);
 523  533  
 524  534  void idm_cid_free(uint32_t cid);
 525  535  
 526  536  uint32_t idm_crc32c(void *address, unsigned long length);
 527  537  
 528  538  uint32_t idm_crc32c_continued(void *address, unsigned long length,
 529  539      uint32_t crc);
 530  540  
 531  541  void idm_listbuf_insert(list_t *lst, idm_buf_t *buf);
 532  542  
 533  543  idm_conn_t *idm_lookup_conn(uint8_t *isid, uint16_t tsih, uint16_t cid);
 534  544  
 535  545  #ifdef  __cplusplus
 536  546  }
 537  547  #endif
 538  548  
 539  549  #endif /* _IDM_IMPL_H_ */
  
    | 
      ↓ open down ↓ | 
    115 lines elided | 
    
      ↑ open up ↑ | 
  
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX