Print this page
    
NEX-3414 CLONE - Port 3339 iscsi/fs:5 causes panic on initiator
NEX-3419 CLONE - Run multi initiator sessions to a single target test can panic the initiator
Reviewed by: Steve Peng <steve.peng@nexenta.com>
4487 snoop can only work with 2GB files
Reviewed by: Jason King <jason.brian.king@gmail.com>
Reviewed by: Marcel Telka <marcel.telka@nexenta.com>
Reviewed by: Sebastien Roy <sebastien.roy@delphix.com>
Approved by: Garrett D'Amore <garrett@damore.org>
3105 Kernel inet_pton() implementation returns result in host byte order
Reviewed by: Garrett D'Amore <garrett@damore.org>
Reviewed by: Robert Mustacchi <rm@joyent.com>
    
      
        | Split | 
	Close | 
      
      | Expand all | 
      | Collapse all | 
    
    
          --- old/usr/src/uts/common/io/scsi/adapters/iscsi/iscsi.h
          +++ new/usr/src/uts/common/io/scsi/adapters/iscsi/iscsi.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  /*
  23   23   * Copyright 2000 by Cisco Systems, Inc.  All rights reserved.
  24   24   * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  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 _ISCSI_H
  29   29  #define _ISCSI_H
  30   30  
  31   31  /*
  32   32   * Block comment which describes the contents of this file.
  33   33   */
  34   34  
  35   35  #ifdef __cplusplus
  36   36  extern "C" {
  37   37  #endif
  38   38  
  39   39  #include <sys/scsi/scsi.h>
  40   40  #include <sys/ddi.h>
  41   41  #include <sys/sunddi.h>
  42   42  #include <sys/socket.h>
  43   43  #include <sys/kstat.h>
  44   44  #include <sys/sunddi.h>
  45   45  #include <sys/sunmdi.h>
  46   46  #include <sys/mdi_impldefs.h>
  47   47  #include <sys/time.h>
  48   48  #include <sys/nvpair.h>
  49   49  #include <sys/sdt.h>
  50   50  
  51   51  #include <sys/iscsi_protocol.h>
  52   52  #include <sys/scsi/adapters/iscsi_if.h>
  53   53  #include <iscsiAuthClient.h>
  54   54  #include <iscsi_stats.h>
  55   55  #include <iscsi_thread.h>
  56   56  #include <sys/idm/idm.h>
  57   57  #include <sys/idm/idm_conn_sm.h>
  58   58  #include <nvfile.h>
  59   59  #include <inet/ip.h>
  60   60  
  61   61  #ifndef MIN
  62   62  #define MIN(a, b) ((a) < (b) ? (a) : (b))
  63   63  #endif
  64   64  
  65   65  #ifndef TRUE
  66   66  #define TRUE 1
  67   67  #endif
  68   68  
  69   69  #ifndef FALSE
  70   70  #define FALSE 0
  71   71  #endif
  72   72  
  73   73  #define LOGIN_PDU_BUFFER_SIZE   (16 * 1024)     /* move somewhere else */
  74   74  
  75   75  extern boolean_t iscsi_conn_logging;
  76   76  extern boolean_t iscsi_io_logging;
  77   77  extern boolean_t iscsi_login_logging;
  78   78  extern boolean_t iscsi_logging;
  79   79  extern boolean_t iscsi_sess_logging;
  80   80  #define ISCSI_CONN_LOG  if (iscsi_conn_logging) cmn_err
  81   81  #define ISCSI_IO_LOG    if (iscsi_io_logging) cmn_err
  82   82  #define ISCSI_LOGIN_LOG if (iscsi_login_logging) cmn_err
  83   83  #define ISCSI_LOG       if (iscsi_logging) cmn_err
  84   84  #define ISCSI_SESS_LOG  if (iscsi_sess_logging) cmn_err
  85   85  
  86   86  /*
  87   87   * Name Format of the different Task Queues
  88   88   */
  89   89  #define ISCSI_SESS_IOTH_NAME_FORMAT             "io_thrd_%d.%d"
  90   90  #define ISCSI_SESS_WD_NAME_FORMAT               "wd_thrd_%d.%d"
  91   91  #define ISCSI_SESS_LOGIN_TASKQ_NAME_FORMAT      "login_taskq_%d.%d"
  92   92  #define ISCSI_SESS_ENUM_TASKQ_NAME_FORMAT       "enum_taskq_%d.%d"
  93   93  #define ISCSI_CONN_CN_TASKQ_NAME_FORMAT         "conn_cn_taskq_%d.%d.%d"
  94   94  #define ISCSI_CONN_RXTH_NAME_FORMAT             "rx_thrd_%d.%d.%d"
  95   95  #define ISCSI_CONN_TXTH_NAME_FORMAT             "tx_thrd_%d.%d.%d"
  96   96  
  97   97  /*
  98   98   * The iSCSI driver will not build scatter/gather lists (iovec) longer
  99   99   * than the value defined here. Asserts have been include in the code
 100  100   * to check.
 101  101   */
 102  102  #define ISCSI_MAX_IOVEC         5
 103  103  
 104  104  #define ISCSI_DEFAULT_MAX_STORM_DELAY           32
 105  105  
 106  106  /*
 107  107   * The SNDBUF and RCVBUF size parameters for the sockets are just a
 108  108   * guess for the time being (I think it is the values used by CISCO
 109  109   * or UNH).  Testing will have to be done to figure * out the impact
 110  110   * of these values on performance.
 111  111   */
 112  112  #define ISCSI_SOCKET_SNDBUF_SIZE                (256 * 1024)
 113  113  #define ISCSI_SOCKET_RCVBUF_SIZE                (256 * 1024)
 114  114  #define ISCSI_TCP_NODELAY_DEFAULT               0
 115  115  #define ISCSI_TCP_CNOTIFY_THRESHOLD_DEFAULT     2000
 116  116  #define ISCSI_TCP_CABORT_THRESHOLD_DEFAULT      10000
 117  117  #define ISCSI_TCP_ABORT_THRESHOLD_DEFAULT       (30 * 1000) /* milliseconds */
 118  118  #define ISNS_TCP_ABORT_THRESHOLD_DEFAULT        (3 * 1000) /* milliseconds */
 119  119  
 120  120  /* Default values for tunable parameters */
 121  121  #define ISCSI_DEFAULT_RX_TIMEOUT_VALUE          60
 122  122  #define ISCSI_DEFAULT_CONN_DEFAULT_LOGIN_MAX    180
 123  123  #define ISCSI_DEFAULT_LOGIN_POLLING_DELAY       60
 124  124  
 125  125  /*
 126  126   * Convenient short hand defines
 127  127   */
 128  128  #define TARGET_PROP     "target"
 129  129  #define LUN_PROP        "lun"
 130  130  #define MDI_GUID        "wwn"
 131  131  #define NDI_GUID        "client-guid"
 132  132  
 133  133  #define ISCSI_SIG_CMD   0x11111111
 134  134  #define ISCSI_SIG_LUN   0x22222222
 135  135  #define ISCSI_SIG_CONN  0x33333333
 136  136  #define ISCSI_SIG_SESS  0x44444444
 137  137  #define ISCSI_SIG_HBA   0x55555555
 138  138  
 139  139  #define SENDTARGETS_DISCOVERY   "SENDTARGETS_DISCOVERY"
 140  140  
 141  141  #define ISCSI_LUN_MASK_MSB      0x00003f00
 142  142  #define ISCSI_LUN_MASK_LSB      0x000000ff
 143  143  #define ISCSI_LUN_MASK          (ISCSI_LUN_MASK_MSB | ISCSI_LUN_MASK_LSB)
 144  144  #define ISCSI_LUN_BYTE_COPY(lun, report_lun_data) \
 145  145          lun[0] = (report_lun_data & ISCSI_LUN_MASK_MSB) >> 8; \
 146  146          lun[1] = (report_lun_data & ISCSI_LUN_MASK_LSB);
 147  147  /*
 148  148   * Not defined by iSCSI, but used in the login code to
 149  149   * determine when to send the initial Login PDU
 150  150   */
 151  151  #define ISCSI_INITIAL_LOGIN_STAGE       -1
 152  152  
 153  153  typedef enum iscsi_status {
 154  154          /* Success */
 155  155          ISCSI_STATUS_SUCCESS = 0,
 156  156          /* Driver / Kernel / Code error */
 157  157          ISCSI_STATUS_INTERNAL_ERROR,
 158  158          /* ITT table is already full, unable to reserve slot */
 159  159          ISCSI_STATUS_ITT_TABLE_FULL,
 160  160          /* Login on connection failed */
 161  161          ISCSI_STATUS_LOGIN_FAILED,
 162  162          /* No connections are in the LOGGED_IN state */
 163  163          ISCSI_STATUS_NO_CONN_LOGGED_IN,
 164  164          /* TCP Transfer Error */
 165  165          ISCSI_STATUS_TCP_TX_ERROR,
 166  166          /* TCP Receive Error */
 167  167          ISCSI_STATUS_TCP_RX_ERROR,
 168  168          /* iSCSI packet RCV timeout */
 169  169          ISCSI_STATUS_RX_TIMEOUT,
 170  170          /* iSCSI Header Digest CRC error */
 171  171          ISCSI_STATUS_HEADER_DIGEST_ERROR,
 172  172          /* iSCSI Data Digest CRC error */
 173  173          ISCSI_STATUS_DATA_DIGEST_ERROR,
 174  174          /* kmem_alloc failure */
 175  175          ISCSI_STATUS_ALLOC_FAILURE,
 176  176          /* cmd (tran_abort/reset) failed */
 177  177          ISCSI_STATUS_CMD_FAILED,
 178  178          /* iSCSI protocol error */
 179  179          ISCSI_STATUS_PROTOCOL_ERROR,
 180  180          /* iSCSI protocol version mismatch */
 181  181          ISCSI_STATUS_VERSION_MISMATCH,
 182  182          /* iSCSI login negotiation failed */
 183  183          ISCSI_STATUS_NEGO_FAIL,
 184  184          /* iSCSI login authentication failed */
 185  185          ISCSI_STATUS_AUTHENTICATION_FAILED,
 186  186          /* iSCSI login redirection failed */
 187  187          ISCSI_STATUS_REDIRECTION_FAILED,
 188  188          /* iSCSI uscsi status failure */
 189  189          ISCSI_STATUS_USCSI_FAILED,
 190  190          /* data received would have overflowed given buffer */
 191  191          ISCSI_STATUS_DATA_OVERFLOW,
 192  192          /* session/connection needs to shutdown */
 193  193          ISCSI_STATUS_SHUTDOWN,
 194  194          /* logical unit in use */
 195  195          ISCSI_STATUS_BUSY,
 196  196          /* Login on connection failed, retries exceeded */
 197  197          ISCSI_STATUS_LOGIN_TIMED_OUT,
 198  198          /* iSCSI login tpgt negotiation failed */
 199  199          ISCSI_STATUS_LOGIN_TPGT_NEGO_FAIL
 200  200  } iscsi_status_t;
 201  201  #define ISCSI_SUCCESS(status) (status == ISCSI_STATUS_SUCCESS)
 202  202  
 203  203  /* SNA32 check value used on increment of CmdSn values */
 204  204  #define ISCSI_SNA32_CHECK 2147483648UL /* 2**31 */
 205  205  
 206  206  /*
 207  207   * This is the maximum number of commands that can be outstanding
 208  208   * on a iSCSI session at anyone point in time.
 209  209   */
 210  210  #define ISCSI_CMD_TABLE_SIZE            1024
 211  211  
 212  212  /* Used on connections thread create of receiver thread */
 213  213  extern pri_t minclsyspri;
 214  214  
 215  215  /*
 216  216   * Callers of iscsid_config_one/all must hold this
 217  217   * semaphore across the calls.  Otherwise a ndi_devi_enter()
 218  218   * deadlock in the DDI layer may occur.
 219  219   */
 220  220  extern ksema_t iscsid_config_semaphore;
 221  221  
 222  222  extern kmutex_t iscsi_oid_mutex;
 223  223  extern uint32_t iscsi_oid;
 224  224  extern void *iscsi_state;
 225  225  
 226  226  /*
 227  227   * NOP delay is used to send a iSCSI NOP (ie. ping) across the
 228  228   * wire to see if the target is still alive.  NOPs are only
 229  229   * sent when the RX thread hasn't received anything for the
 230  230   * below amount of time.
 231  231   */
 232  232  #define ISCSI_DEFAULT_NOP_DELAY                 5 /* seconds */
 233  233  extern int      iscsi_nop_delay;
 234  234  /*
 235  235   * If we haven't received anything in a specified period of time
 236  236   * we will stop accepting IO via tran start.  This will enable
 237  237   * upper level drivers to see we might be having a problem and
 238  238   * in the case of scsi_vhci will start to route IO down a better
 239  239   * path.
 240  240   */
 241  241  #define ISCSI_DEFAULT_RX_WINDOW                 20 /* seconds */
 242  242  extern int      iscsi_rx_window;
 243  243  /*
 244  244   * If we haven't received anything in a specified period of time
 245  245   * we will stop accepting IO via tran start.  This the max limit
 246  246   * when encountered we will start returning a fatal error.
 247  247   */
 248  248  #define ISCSI_DEFAULT_RX_MAX_WINDOW             180 /* seconds */
 249  249  extern int      iscsi_rx_max_window;
 250  250  
 251  251  /*
 252  252   * During iscsi boot, if the boot session has been created, the
 253  253   * initiator hasn't changed the boot lun to be online, we will wait
 254  254   * 180s here for lun online by default.
 255  255   */
 256  256  #define ISCSI_BOOT_DEFAULT_MAX_DELAY            180 /* seconds */
 257  257  /*
 258  258   * +--------------------------------------------------------------------+
 259  259   * | iSCSI Driver Structures                                            |
 260  260   * +--------------------------------------------------------------------+
 261  261   */
 262  262  
 263  263  /*
 264  264   * iSCSI Auth Information
 265  265   */
 266  266  typedef struct iscsi_auth {
 267  267          IscsiAuthStringBlock    auth_recv_string_block;
 268  268          IscsiAuthStringBlock    auth_send_string_block;
 269  269          IscsiAuthLargeBinary    auth_recv_binary_block;
 270  270          IscsiAuthLargeBinary    auth_send_binary_block;
 271  271          IscsiAuthClient         auth_client_block;
 272  272          int                     num_auth_buffers;
 273  273          IscsiAuthBufferDesc     auth_buffers[5];
 274  274  
 275  275          /*
 276  276           * To indicate if bi-directional authentication is enabled.
 277  277           * 0 means uni-directional authentication.
 278  278           * 1 means bi-directional authentication.
 279  279           */
 280  280          int                     bidirectional_auth;
 281  281  
 282  282          /* Initiator's authentication information. */
 283  283          char                    username[iscsiAuthStringMaxLength];
 284  284          uint8_t                 password[iscsiAuthStringMaxLength];
 285  285          int                     password_length;
 286  286  
 287  287          /* Target's authentication information. */
 288  288          char                    username_in[iscsiAuthStringMaxLength];
 289  289          uint8_t                 password_in[iscsiAuthStringMaxLength];
 290  290          int                     password_length_in;
 291  291  } iscsi_auth_t;
 292  292  
 293  293  /*
 294  294   * iSCSI Task
 295  295   */
 296  296  typedef struct iscsi_task {
 297  297          void                    *t_arg;
 298  298          boolean_t               t_blocking;
 299  299          uint32_t                t_event_count;
 300  300  } iscsi_task_t;
 301  301  
 302  302  /*
 303  303   * These are all the iscsi_cmd types that we use to track our
 304  304   * commands between queues and actions.
 305  305   */
 306  306  typedef enum iscsi_cmd_type {
 307  307          ISCSI_CMD_TYPE_SCSI = 1,        /* scsi cmd */
 308  308          ISCSI_CMD_TYPE_NOP,             /* nop / ping */
 309  309          ISCSI_CMD_TYPE_ABORT,           /* abort */
 310  310          ISCSI_CMD_TYPE_RESET,           /* reset */
 311  311          ISCSI_CMD_TYPE_LOGOUT,          /* logout */
 312  312          ISCSI_CMD_TYPE_LOGIN,           /* login */
 313  313          ISCSI_CMD_TYPE_TEXT             /* text */
 314  314  } iscsi_cmd_type_t;
 315  315  
 316  316  /*
 317  317   * iscsi_cmd_state - (reference iscsi_cmd.c for state diagram)
 318  318   */
 319  319  typedef enum iscsi_cmd_state {
 320  320          ISCSI_CMD_STATE_FREE = 0,
 321  321          ISCSI_CMD_STATE_PENDING,
 322  322          ISCSI_CMD_STATE_ACTIVE,
 323  323          ISCSI_CMD_STATE_ABORTING,
 324  324          ISCSI_CMD_STATE_IDM_ABORTING,
 325  325          ISCSI_CMD_STATE_COMPLETED,
 326  326          ISCSI_CMD_STATE_MAX
 327  327  } iscsi_cmd_state_t;
 328  328  
 329  329  #ifdef ISCSI_CMD_SM_STRINGS
 330  330  static const char *iscsi_cmd_state_names[ISCSI_CMD_STATE_MAX+1] = {
 331  331          "ISCSI_CMD_STATE_FREE",
 332  332          "ISCSI_CMD_STATE_PENDING",
 333  333          "ISCSI_CMD_STATE_ACTIVE",
 334  334          "ISCSI_CMD_STATE_ABORTING",
 335  335          "ISCSI_CMD_STATE_IDM_ABORTING",
 336  336          "ISCSI_CMD_STATE_COMPLETED",
 337  337          "ISCSI_CMD_STATE_MAX"
 338  338  };
 339  339  #endif
 340  340  
 341  341  /*
 342  342   * iscsi command events
 343  343   */
 344  344  typedef enum iscsi_cmd_event {
 345  345          ISCSI_CMD_EVENT_E1 = 0,
 346  346          ISCSI_CMD_EVENT_E2,
 347  347          ISCSI_CMD_EVENT_E3,
 348  348          ISCSI_CMD_EVENT_E4,
 349  349          ISCSI_CMD_EVENT_E6,
 350  350          ISCSI_CMD_EVENT_E7,
 351  351          ISCSI_CMD_EVENT_E8,
 352  352          ISCSI_CMD_EVENT_E9,
 353  353          ISCSI_CMD_EVENT_E10,
 354  354          ISCSI_CMD_EVENT_MAX
 355  355  } iscsi_cmd_event_t;
 356  356  
 357  357  #ifdef ISCSI_CMD_SM_STRINGS
 358  358  static const char *iscsi_cmd_event_names[ISCSI_CMD_EVENT_MAX+1] = {
 359  359          "ISCSI_CMD_EVENT_E1",
 360  360          "ISCSI_CMD_EVENT_E2",
 361  361          "ISCSI_CMD_EVENT_E3",
 362  362          "ISCSI_CMD_EVENT_E4",
 363  363          "ISCSI_CMD_EVENT_E6",
 364  364          "ISCSI_CMD_EVENT_E7",
 365  365          "ISCSI_CMD_EVENT_E8",
 366  366          "ISCSI_CMD_EVENT_E9",
 367  367          "ISCSI_CMD_EVENT_E10",
 368  368          "ISCSI_CMD_EVENT_MAX"
 369  369  };
 370  370  #endif
 371  371  
 372  372  /*
 373  373   * iscsi text command stages - these stages are used by iSCSI text
 374  374   * processing to manage long resonses.
 375  375   */
 376  376  typedef enum iscsi_cmd_text_stage {
 377  377          ISCSI_CMD_TEXT_INITIAL_REQ = 0,
 378  378          ISCSI_CMD_TEXT_CONTINUATION,
 379  379          ISCSI_CMD_TEXT_FINAL_RSP
 380  380  } iscsi_cmd_text_stage_t;
 381  381  
 382  382  /*
 383  383   * iscsi cmd misc flags - bitwise applicable
 384  384   */
 385  385  #define ISCSI_CMD_MISCFLAG_INTERNAL     0x1
 386  386  #define ISCSI_CMD_MISCFLAG_FREE         0x2
 387  387  #define ISCSI_CMD_MISCFLAG_STUCK        0x4
 388  388  #define ISCSI_CMD_MISCFLAG_XARQ         0x8
 389  389  #define ISCSI_CMD_MISCFLAG_SENT         0x10
 390  390  #define ISCSI_CMD_MISCFLAG_FLUSH        0x20
 391  391  
 392  392  /*
 393  393   * 1/2 of a 32 bit number, used for checking CmdSN
 394  394   * wrapped.
 395  395   */
 396  396  #define ISCSI_CMD_SN_WRAP               0x80000000
 397  397  
 398  398  #define ISCSI_CMD_PKT_STAT_INIT         0
 399  399  
 400  400  /*
 401  401   * iSCSI cmd/pkt Structure
 402  402   */
 403  403  typedef struct iscsi_cmd {
 404  404          uint32_t                cmd_sig;
 405  405          struct iscsi_cmd        *cmd_prev;
 406  406          struct iscsi_cmd        *cmd_next;
 407  407          struct iscsi_conn       *cmd_conn;
 408  408  
 409  409          iscsi_cmd_type_t        cmd_type;
 410  410          iscsi_cmd_state_t       cmd_state;
 411  411          iscsi_cmd_state_t       cmd_prev_state;
 412  412          clock_t                 cmd_lbolt_pending;
 413  413          clock_t                 cmd_lbolt_active;
 414  414          clock_t                 cmd_lbolt_aborting;
 415  415          clock_t                 cmd_lbolt_idm_aborting;
 416  416          clock_t                 cmd_lbolt_timeout;
 417  417          uint8_t                 cmd_misc_flags;
 418  418          idm_task_t              *cmd_itp;
 419  419  
 420  420          union {
 421  421                  /* ISCSI_CMD_TYPE_SCSI */
 422  422                  struct {
 423  423                          idm_buf_t               *ibp_ibuf;
 424  424                          idm_buf_t               *ibp_obuf;
 425  425                          struct scsi_pkt         *pkt;
 426  426                          struct buf              *bp;
 427  427                          int                     cmdlen;
 428  428                          int                     statuslen;
 429  429                          size_t                  data_transferred;
 430  430  
 431  431                          uint32_t                lun;
 432  432  
 433  433                          /*
 434  434                           * If SCSI_CMD_TYPE is in ABORTING_STATE
 435  435                           * then the abort_icmdp field will be a pointer
 436  436                           * to the abort command chasing this one.
 437  437                           */
 438  438                          struct iscsi_cmd        *abort_icmdp;
 439  439                          /*
 440  440                           * pointer to the r2t associated with this
 441  441                           * command (if any)
 442  442                           */
 443  443                          struct iscsi_cmd        *r2t_icmdp;
 444  444                          /*
 445  445                           * It will be true if this command has
 446  446                           * another R2T to handle.
 447  447                           */
 448  448                          boolean_t               r2t_more;
 449  449                          /*
 450  450                           * It is used to record pkt_statistics temporarily.
 451  451                           */
 452  452                          uint_t                  pkt_stat;
 453  453                  } scsi;
 454  454                  /* ISCSI_CMD_TYPE_ABORT */
 455  455                  struct {
 456  456                          /* pointer to original iscsi_cmd, for abort */
 457  457                          struct iscsi_cmd        *icmdp;
 458  458                  } abort;
 459  459                  /* ISCSI_CMD_TYPE_RESET */
 460  460                  struct {
 461  461                          int                     level;
 462  462                          uint8_t                 response;
 463  463                  } reset;
 464  464                  /* ISCSI_CMD_TYPE_NOP */
 465  465                  struct {
 466  466                          int rsvd;
 467  467                  } nop;
 468  468                  /* ISCSI_CMD_TYPE_R2T */
 469  469                  struct {
 470  470                          struct iscsi_cmd        *icmdp;
 471  471                          uint32_t                offset;
 472  472                          uint32_t                length;
 473  473                  } r2t;
 474  474                  /* ISCSI_CMD_TYPE_LOGIN */
 475  475                  struct {
 476  476                          int rvsd;
 477  477                  } login;
 478  478                  /* ISCSI_CMD_TYPE_LOGOUT */
 479  479                  struct {
 480  480                          int rsvd;
 481  481                  } logout;
 482  482                  /* ISCSI_CMD_TYPE_TEXT */
 483  483                  struct {
 484  484                          char                    *buf;
 485  485                          int                     buf_len;
 486  486                          uint32_t                offset;
 487  487                          uint32_t                data_len;
 488  488                          uint32_t                total_rx_len;
 489  489                          uint32_t                ttt;
 490  490                          uint8_t                 lun[8];
 491  491                          iscsi_cmd_text_stage_t  stage;
 492  492                  } text;
 493  493          } cmd_un;
 494  494  
 495  495          struct iscsi_lun        *cmd_lun; /* associated lun */
 496  496  
 497  497          uint32_t                cmd_itt;
 498  498          uint32_t                cmd_ttt;
 499  499  
 500  500          /*
 501  501           * If a data digest error is seem on a data pdu.  This flag
 502  502           * will get set.  We don't abort the cmd immediately because
 503  503           * we want to read in all the data to get it out of the
 504  504           * stream.  Once the completion for the cmd is received we
 505  505           * we will abort the cmd and state no sense data was available.
 506  506           */
 507  507          boolean_t               cmd_crc_error_seen;
 508  508  
 509  509          /*
 510  510           * Used to block and wake up caller until action is completed.
 511  511           * This is for ABORT, RESET, and PASSTHRU cmds.
 512  512           */
 513  513          int                     cmd_result;
 514  514          int                     cmd_completed;
 515  515          kmutex_t                cmd_mutex;
 516  516          kcondvar_t              cmd_completion;
 517  517  
 518  518          idm_pdu_t               cmd_pdu;
 519  519  
 520  520          sm_audit_buf_t          cmd_state_audit;
 521  521  
 522  522          uint32_t                cmd_sn;
 523  523  } iscsi_cmd_t;
 524  524  
 525  525  
 526  526  /*
 527  527   * iSCSI LUN Structure
 528  528   */
 529  529  typedef struct iscsi_lun {
 530  530          uint32_t                lun_sig;
 531  531          int                     lun_state;
 532  532  
 533  533          struct iscsi_lun        *lun_next;      /* next lun on this sess. */
 534  534          struct iscsi_sess       *lun_sess;      /* parent sess. for lun */
 535  535          dev_info_t              *lun_dip;
 536  536          mdi_pathinfo_t          *lun_pip;
 537  537  
 538  538          uint16_t                lun_num;        /* LUN */
 539  539          uint8_t                 lun_addr_type;  /* LUN addressing type */
 540  540          uint32_t                lun_oid;        /* OID */
 541  541          char                    *lun_guid;      /* GUID */
  
    | 
      ↓ open down ↓ | 
    506 lines elided | 
    
      ↑ open up ↑ | 
  
 542  542          int                     lun_guid_size;  /* GUID allocation size */
 543  543          char                    *lun_addr;      /* sess,lun */
 544  544          time_t                  lun_time_online;
 545  545  
 546  546          uchar_t                 lun_cap;        /* bitmap of scsi caps */
 547  547  
 548  548          uchar_t                 lun_vid[ISCSI_INQ_VID_BUF_LEN]; /* Vendor ID */
 549  549          uchar_t                 lun_pid[ISCSI_INQ_PID_BUF_LEN]; /* Product ID */
 550  550  
 551  551          uchar_t                 lun_type;
      552 +        kmutex_t                lun_mutex;
      553 +        int                     lun_refcnt;
 552  554  } iscsi_lun_t;
 553  555  
 554  556  #define ISCSI_LUN_STATE_CLEAR       0           /* used to clear all states */
 555  557  #define ISCSI_LUN_STATE_OFFLINE     1
 556  558  #define ISCSI_LUN_STATE_ONLINE      2
 557  559  #define ISCSI_LUN_STATE_INVALID     4           /* offline failed */
 558  560  #define ISCSI_LUN_STATE_BUSY        8           /* logic unit is in reset */
 559  561  
 560  562  #define ISCSI_LUN_CAP_RESET         0x01
 561  563  
 562  564  #define ISCSI_SCSI_RESET_SENSE_CODE 0x29
 563  565  #define ISCSI_SCSI_LUNCHANGED_CODE      0x3f
 564  566  
 565  567  #define ISCSI_SCSI_LUNCHANGED_ASCQ      0x0e
 566  568  
 567  569  /*
 568  570   *
 569  571   *
 570  572   */
 571  573  typedef struct iscsi_queue {
 572  574          iscsi_cmd_t     *head;
 573  575          iscsi_cmd_t     *tail;
 574  576          int             count;
 575  577          kmutex_t        mutex;
 576  578  } iscsi_queue_t;
 577  579  
 578  580  #define ISCSI_CONN_DEFAULT_LOGIN_MIN            0
 579  581  #define ISCSI_CONN_DEFAULT_LOGIN_REDIRECT       10
 580  582  
 581  583  /* iSCSI tunable Parameters */
 582  584  typedef struct iscsi_tunable_params {
 583  585          int             recv_login_rsp_timeout; /* range: 0 - 60*60 */
 584  586          int             conn_login_max;         /* range: 0 - 60*60 */
 585  587          int             polling_login_delay;    /* range: 0 - 60*60 */
 586  588  } iscsi_tunable_params_t;
 587  589  
 588  590  typedef union iscsi_sockaddr {
 589  591          struct sockaddr         sin;
 590  592          struct sockaddr_in      sin4;
 591  593          struct sockaddr_in6     sin6;
 592  594  } iscsi_sockaddr_t;
 593  595  
 594  596  #define SIZEOF_SOCKADDR(so)     ((so)->sa_family == AF_INET ? \
 595  597          sizeof (struct sockaddr_in) : sizeof (struct sockaddr_in6))
 596  598  
 597  599  typedef enum {
 598  600          LOGIN_START,
 599  601          LOGIN_READY,
 600  602          LOGIN_TX,
 601  603          LOGIN_RX,
 602  604          LOGIN_ERROR,
 603  605          LOGIN_DONE,
 604  606          LOGIN_FFP,
 605  607          LOGIN_MAX
 606  608  } iscsi_login_state_t;
 607  609  
 608  610  #ifdef ISCSI_LOGIN_STATE_NAMES
 609  611  static const char *iscsi_login_state_names[LOGIN_MAX+1] = {
 610  612          "LOGIN_START",
 611  613          "LOGIN_READY",
 612  614          "LOGIN_TX",
 613  615          "LOGIN_RX",
 614  616          "LOGIN_ERROR",
 615  617          "LOGIN_DONE",
 616  618          "LOGIN_FFP",
 617  619          "LOGIN_MAX"
 618  620  };
 619  621  #endif
 620  622  
 621  623  /*
 622  624   * iscsi_conn_state
 623  625   */
 624  626  typedef enum iscsi_conn_state {
 625  627          ISCSI_CONN_STATE_UNDEFINED = 0,
 626  628          ISCSI_CONN_STATE_FREE,
 627  629          ISCSI_CONN_STATE_IN_LOGIN,
 628  630          ISCSI_CONN_STATE_LOGGED_IN,
 629  631          ISCSI_CONN_STATE_IN_LOGOUT,
 630  632          ISCSI_CONN_STATE_FAILED,
 631  633          ISCSI_CONN_STATE_POLLING,
 632  634          ISCSI_CONN_STATE_MAX
 633  635  } iscsi_conn_state_t;
 634  636  
 635  637  #ifdef ISCSI_ICS_NAMES
 636  638  static const char *iscsi_ics_name[ISCSI_CONN_STATE_MAX+1] = {
 637  639          "ISCSI_CONN_STATE_UNDEFINED",
 638  640          "ISCSI_CONN_STATE_FREE",
 639  641          "ISCSI_CONN_STATE_IN_LOGIN",
 640  642          "ISCSI_CONN_STATE_LOGGED_IN",
 641  643          "ISCSI_CONN_STATE_IN_LOGOUT",
 642  644          "ISCSI_CONN_STATE_FAILED",
 643  645          "ISCSI_CONN_STATE_POLLING",
 644  646          "ISCSI_CONN_STATE_MAX"
 645  647  };
 646  648  #endif
 647  649  
 648  650  #define ISCSI_CONN_STATE_FULL_FEATURE(state) \
 649  651          ((state == ISCSI_CONN_STATE_LOGGED_IN) || \
 650  652          (state == ISCSI_CONN_STATE_IN_LOGOUT))
 651  653  
 652  654  /*
 653  655   * iSCSI Connection Structure
 654  656   */
 655  657  typedef struct iscsi_conn {
 656  658          uint32_t                conn_sig;
 657  659          struct iscsi_conn       *conn_next;     /* next conn on this sess. */
 658  660          struct iscsi_sess       *conn_sess;     /* parent sess. for conn. */
 659  661  
 660  662          iscsi_conn_state_t      conn_state;     /* cur. conn. driver state */
 661  663          iscsi_conn_state_t      conn_prev_state; /* prev. conn. driver state */
 662  664          /* protects the session state and synchronizes the state machine */
 663  665          kmutex_t                conn_state_mutex;
 664  666          kcondvar_t              conn_state_change;
 665  667          boolean_t               conn_state_destroy;
 666  668          boolean_t               conn_state_ffp;
 667  669          boolean_t               conn_state_idm_connected;
 668  670          boolean_t               conn_async_logout;
 669  671          ddi_taskq_t             *conn_cn_taskq;
 670  672  
 671  673          idm_conn_t              *conn_ic;
 672  674  
 673  675          /* base connection information, may have been redirected */
 674  676          iscsi_sockaddr_t        conn_base_addr;
 675  677  
 676  678          /* current connection information, may have been redirected */
 677  679          iscsi_sockaddr_t        conn_curr_addr;
 678  680  
 679  681          boolean_t               conn_bound;
 680  682          iscsi_sockaddr_t        conn_bound_addr;
 681  683  
 682  684          uint32_t                conn_cid;       /* CID */
 683  685          uint32_t                conn_oid;       /* OID */
 684  686  
 685  687          int                     conn_current_stage;     /* iSCSI login stage */
 686  688          int                     conn_next_stage;        /* iSCSI login stage */
 687  689          int                     conn_partial_response;
 688  690  
 689  691          /*
 690  692           * The active queue contains iscsi_cmds that have already
 691  693           * been sent on this connection.  Any future responses to
 692  694           * these cmds require alligence to this connection.  If there
 693  695           * are issues with these cmds the command may need aborted
 694  696           * depending on the command type, and must be put back into
 695  697           * the session's pending queue or aborted.
 696  698           */
 697  699          iscsi_queue_t           conn_queue_active;
 698  700          iscsi_queue_t           conn_queue_idm_aborting;
 699  701  
 700  702          /* lbolt from the last receive, used for nop processing */
 701  703          clock_t                 conn_rx_lbolt;
 702  704          clock_t                 conn_nop_lbolt;
 703  705  
 704  706          iscsi_thread_t          *conn_tx_thread;
 705  707  
 706  708          /*
 707  709           * The expstatsn is the command status sn that is expected
 708  710           * next from the target.  Command status is carried on a number
 709  711           * of iSCSI PDUs (ex.  SCSI Cmd Response, SCSI Data IN with
 710  712           * S-Bit set, ...), not all PDUs.  If our expstatsn is different
 711  713           * than the received statsn.  Something got out of sync we need to
 712  714           * recover.
 713  715           */
 714  716          uint32_t                conn_expstatsn;
 715  717          uint32_t                conn_laststatsn;
 716  718  
 717  719          /* active login parameters */
 718  720          iscsi_login_params_t    conn_params;
 719  721  
 720  722          /* Statistics */
 721  723          struct {
 722  724                  kstat_t                 *ks;
 723  725                  iscsi_conn_stats_t      ks_data;
 724  726          } stats;
 725  727  
 726  728          /*
 727  729           * These fields are used to coordinate the asynchronous IDM
 728  730           * PDU operations with the synchronous login code.
 729  731           */
 730  732          kmutex_t                conn_login_mutex;
 731  733          kcondvar_t              conn_login_cv;
 732  734          iscsi_login_state_t     conn_login_state;
 733  735          iscsi_status_t          conn_login_status;
 734  736          iscsi_hdr_t             conn_login_resp_hdr;
 735  737          char                    *conn_login_data;
 736  738          int                     conn_login_datalen;
 737  739          int                     conn_login_max_data_length;
 738  740  
 739  741          /*
 740  742           * login min and max identify the amount of time
 741  743           * in lbolt that iscsi_start_login() should attempt
 742  744           * to log into a target portal.  The login will
 743  745           * delay until the min lbolt has been reached and
 744  746           * will end once max time has been reached.  These
 745  747           * values are normally set to the default but can
 746  748           * are also altered by async commands received from
 747  749           * the targetlogin.
 748  750           */
 749  751          clock_t                 conn_login_min;
 750  752          clock_t                 conn_login_max;
 751  753          sm_audit_buf_t          conn_state_audit;
 752  754  
 753  755          /* active tunable parameters */
 754  756          iscsi_tunable_params_t  conn_tunable_params;
 755  757          boolean_t               conn_timeout;
 756  758  } iscsi_conn_t;
 757  759  
 758  760  
 759  761  /*
 760  762   * iscsi_sess_state - (reference iscsi_sess.c for state diagram)
 761  763   */
 762  764  typedef enum iscsi_sess_state {
 763  765          ISCSI_SESS_STATE_FREE = 0,
 764  766          ISCSI_SESS_STATE_LOGGED_IN,
 765  767          ISCSI_SESS_STATE_FAILED,
 766  768          ISCSI_SESS_STATE_IN_FLUSH,
 767  769          ISCSI_SESS_STATE_FLUSHED,
 768  770          ISCSI_SESS_STATE_MAX
 769  771  } iscsi_sess_state_t;
 770  772  
 771  773  #ifdef ISCSI_SESS_SM_STRINGS
 772  774  static const char *iscsi_sess_state_names[ISCSI_SESS_STATE_MAX+1] = {
 773  775          "ISCSI_SESS_STATE_FREE",
 774  776          "ISCSI_SESS_STATE_LOGGED_IN",
 775  777          "ISCSI_SESS_STATE_FAILED",
 776  778          "ISCSI_SESS_STATE_IN_FLUSH",
 777  779          "ISCSI_SESS_STATE_FLUSHED",
 778  780          "ISCSI_SESS_STATE_MAX"
 779  781  };
 780  782  #endif
 781  783  
 782  784  #define ISCSI_SESS_STATE_FULL_FEATURE(state) \
 783  785          ((state == ISCSI_SESS_STATE_LOGGED_IN) || \
 784  786          (state == ISCSI_SESS_STATE_IN_FLUSH))
 785  787  
 786  788  
 787  789  typedef enum iscsi_sess_event {
 788  790          ISCSI_SESS_EVENT_N1 = 0,
 789  791          ISCSI_SESS_EVENT_N3,
 790  792          ISCSI_SESS_EVENT_N5,
 791  793          ISCSI_SESS_EVENT_N6,
 792  794          ISCSI_SESS_EVENT_N7,
 793  795          ISCSI_SESS_EVENT_MAX
 794  796  } iscsi_sess_event_t;
 795  797  
 796  798  #ifdef ISCSI_SESS_SM_STRINGS
 797  799  static const char *iscsi_sess_event_names[ISCSI_SESS_EVENT_MAX+1] = {
 798  800          "ISCSI_SESS_EVENT_N1",
 799  801          "ISCSI_SESS_EVENT_N3",
 800  802          "ISCSI_SESS_EVENT_N5",
 801  803          "ISCSI_SESS_EVENT_N6",
 802  804          "ISCSI_SESS_EVENT_N7",
 803  805          "ISCSI_SESS_EVENT_MAX"
 804  806  };
 805  807  #endif
 806  808  
 807  809  typedef enum iscsi_sess_type {
 808  810          ISCSI_SESS_TYPE_NORMAL = 0,
 809  811          ISCSI_SESS_TYPE_DISCOVERY
 810  812  } iscsi_sess_type_t;
 811  813  
 812  814  #define SESS_ABORT_TASK_MAX_THREADS     1
 813  815  
 814  816  /* Sun's initiator session ID */
 815  817  #define ISCSI_SUN_ISID_0    0x40    /* ISID - EN format */
 816  818  #define ISCSI_SUN_ISID_1    0x00    /* Sec B */
 817  819  #define ISCSI_SUN_ISID_2    0x00    /* Sec B */
 818  820  #define ISCSI_SUN_ISID_3    0x2A    /* Sec C - 42 = Sun's EN */
 819  821  /*
 820  822   * defines 4-5 are the reserved values.  These reserved values
 821  823   * are used as the ISID for an initiator-port in MP-API and used
 822  824   * for the send targets discovery sessions.  Byte 5 is overridden
 823  825   * for full feature sessions.  The default values of byte 5 for a
 824  826   * full feature session is 0.  When MS/T is enabled with more than
 825  827   * one session this byte 5 will increment > 0 up to
 826  828   * ISCSI_MAX_CONFIG_SESSIONS.
 827  829   */
 828  830  #define ISCSI_SUN_ISID_4    0x00
 829  831  #define ISCSI_SUN_ISID_5    0xFF
 830  832  
 831  833  #define ISCSI_DEFAULT_SESS_BOUND        B_FALSE
 832  834  #define ISCSI_DEFAULT_SESS_NUM          1
 833  835  
 834  836  typedef enum iscsi_enum_status {
 835  837          ISCSI_SESS_ENUM_FREE            =       0,
 836  838          ISCSI_SESS_ENUM_INPROG,
 837  839          ISCSI_SESS_ENUM_DONE
 838  840  } iscsi_enum_status_t;
 839  841  
 840  842  typedef enum iscsi_enum_result {
 841  843          ISCSI_SESS_ENUM_COMPLETE        =       0,
 842  844          ISCSI_SESS_ENUM_PARTIAL,
 843  845          ISCSI_SESS_ENUM_IOFAIL,
 844  846          ISCSI_SESS_ENUM_SUBMITTED,
 845  847          ISCSI_SESS_ENUM_SUBFAIL,
 846  848          ISCSI_SESS_ENUM_GONE,
 847  849          ISCSI_SESS_ENUM_TUR_FAIL
 848  850  } iscsi_enum_result_t;
 849  851  
 850  852  /*
 851  853   * iSCSI Session(Target) Structure
 852  854   */
 853  855  typedef struct iscsi_sess {
 854  856          uint32_t                sess_sig;
 855  857  
 856  858          iscsi_sess_state_t      sess_state;
 857  859          iscsi_sess_state_t      sess_prev_state;
 858  860          clock_t                 sess_state_lbolt;
 859  861          /* protects the session state and synchronizes the state machine */
 860  862          krwlock_t               sess_state_rwlock;
 861  863  
 862  864          /*
 863  865           * Associated target OID.
 864  866           */
 865  867          uint32_t                sess_target_oid;
 866  868  
 867  869          /*
 868  870           * Session OID.  Used by IMA, interfaces and exported as
 869  871           * TARGET_PROP which is checked by the NDI.  In addition
 870  872           * this is used in our tran_lun_init function.
 871  873           */
 872  874          uint32_t                sess_oid;
 873  875  
 874  876          struct iscsi_sess       *sess_next;
 875  877          struct iscsi_hba        *sess_hba;
 876  878  
 877  879          /* list of all luns relating to session */
 878  880          struct iscsi_lun        *sess_lun_list;
 879  881          krwlock_t               sess_lun_list_rwlock;
 880  882  
 881  883          /* list of all connections relating to session */
 882  884          struct iscsi_conn       *sess_conn_list;
 883  885          struct iscsi_conn       *sess_conn_list_last_ptr;
 884  886          /* pointer to active connection in session */
 885  887          struct iscsi_conn       *sess_conn_act;
 886  888          krwlock_t               sess_conn_list_rwlock;
 887  889  
 888  890          /* Connection ID for next connection to be added to session */
 889  891          uint32_t                sess_conn_next_cid;
 890  892  
 891  893          /*
 892  894           * last time any connection on this session received
 893  895           * data from the target.
 894  896           */
 895  897          clock_t                 sess_rx_lbolt;
 896  898  
 897  899          clock_t                 sess_failure_lbolt;
 898  900  
 899  901          int                     sess_storm_delay;
 900  902  
 901  903          /*
 902  904           * sess_cmdsn_mutex protects the cmdsn and itt table/values
 903  905           * Cmdsn isn't that big of a problem yet since we only have
 904  906           * one connection but in the future we will need to ensure
 905  907           * this locking is working so keep the sequence numbers in
 906  908           * sync on the wire.
 907  909           *
 908  910           * We also use this lock to protect the ITT table and it's
 909  911           * values.  We need to make sure someone doesn't assign
 910  912           * a duplicate ITT value or cell to a command.  Also we
 911  913           * need to make sure when someone is looking up an ITT
 912  914           * that the command is still in that correct queue location.
 913  915           */
 914  916          kmutex_t                sess_cmdsn_mutex;
 915  917  
 916  918          /*
 917  919           * iSCSI command sequencing / windowing.  The next
 918  920           * command to be sent via the pending queue will
 919  921           * get the sess_cmdsn.  If the maxcmdsn is less
 920  922           * than the next cmdsn then the iSCSI window is
 921  923           * closed and this command cannot be sent yet.
 922  924           * Most iscsi cmd responses from the target carry
 923  925           * a new maxcmdsn.  If this new maxcmdsn is greater
 924  926           * than the sess_maxcmdsn we will update it's value
 925  927           * and set a timer to fire in one tick and reprocess
 926  928           * the pending queue.
 927  929           *
 928  930           * The expcmdsn.   Is the value the target expects
 929  931           * to be sent for my next cmdsn.  If the expcmdsn
 930  932           * and the cmdsn get out of sync this could denote
 931  933           * a communication problem.
 932  934           */
 933  935          uint32_t                sess_cmdsn;
 934  936          uint32_t                sess_expcmdsn;
 935  937          uint32_t                sess_maxcmdsn;
 936  938  
 937  939          /* Next Initiator Task Tag (ITT) to use */
 938  940          uint32_t                sess_itt;
 939  941          /*
 940  942           * The session iscsi_cmd table is used to a fast performance
 941  943           * lookup of an ITT to a iscsi_cmd when we receive an iSCSI
 942  944           * PDU from the wire.  To reserve a location in the sess_cmd_table
 943  945           * we try the sess_itt % ISCSI_CMD_TABLE_SIZE if this cmd table
 944  946           * cell is already full.  Then increament the sess_itt and
 945  947           * try to get the cell position again, repeat until an empty
 946  948           * cell is found.  Once an empty cell is found place your
 947  949           * scsi_cmd point into the cell to reserve the location.  This
 948  950           * selection process should be done while holding the session's
 949  951           * mutex.
 950  952           */
 951  953          struct iscsi_cmd        *sess_cmd_table[ISCSI_CMD_TABLE_SIZE];
 952  954          int                     sess_cmd_table_count;
 953  955  
 954  956          /*
 955  957           * The pending queue contains all iscsi_cmds that require an
 956  958           * open MaxCmdSn window to be put on the wire and haven't
 957  959           * been placed on the wire.  Once placed on the wire they
 958  960           * will be moved to a connections specific active queue.
 959  961           */
 960  962          iscsi_queue_t           sess_queue_pending;
 961  963  
 962  964          iscsi_error_t           sess_last_err;
 963  965  
 964  966          iscsi_queue_t           sess_queue_completion;
 965  967          /* configured login parameters */
 966  968          iscsi_login_params_t    sess_params;
 967  969  
 968  970          /* general iSCSI protocol/session info */
 969  971          uchar_t                 sess_name[ISCSI_MAX_NAME_LEN];
 970  972          int                     sess_name_length;
 971  973          char                    sess_alias[ISCSI_MAX_NAME_LEN];
 972  974          int                     sess_alias_length;
 973  975          iSCSIDiscoveryMethod_t  sess_discovered_by;
 974  976          iscsi_sockaddr_t        sess_discovered_addr;
 975  977          uchar_t                 sess_isid[ISCSI_ISID_LEN]; /* Session ID */
 976  978          uint16_t                sess_tsid; /* Target ID */
 977  979          /*
 978  980           * If the target portal group tag(TPGT) is equal to ISCSI_DEFAULT_TPGT
 979  981           * then the initiator will accept a successful login with any TPGT
 980  982           * specified by the target.  If a none default TPGT is configured
 981  983           * then we will only successfully accept a login with that matching
 982  984           * TPGT value.
 983  985           */
 984  986          int                     sess_tpgt_conf;
 985  987          /* This field records the negotiated TPGT value, preserved for dtrace */
 986  988          int                     sess_tpgt_nego;
 987  989  
 988  990          /*
 989  991           * Authentication information.
 990  992           *
 991  993           * DCW: Again IMA seems to take a session view at this
 992  994           * information.
 993  995           */
 994  996          iscsi_auth_t            sess_auth;
 995  997  
 996  998          /* Statistics */
 997  999          struct {
 998 1000                  kstat_t                 *ks;
 999 1001                  iscsi_sess_stats_t      ks_data;
1000 1002                  kstat_t                 *ks_io;
1001 1003                  kstat_io_t              ks_io_data;
1002 1004                  kmutex_t                ks_io_lock;
1003 1005          } stats;
1004 1006  
1005 1007          iscsi_thread_t          *sess_ic_thread;
1006 1008          boolean_t               sess_window_open;
1007 1009          boolean_t               sess_boot;
1008 1010          iscsi_sess_type_t       sess_type;
1009 1011  
1010 1012          ddi_taskq_t             *sess_login_taskq;
1011 1013  
1012 1014          iscsi_thread_t          *sess_wd_thread;
1013 1015  
1014 1016          sm_audit_buf_t          sess_state_audit;
1015 1017  
1016 1018          kmutex_t                sess_reset_mutex;
1017 1019  
1018 1020          boolean_t               sess_reset_in_progress;
1019 1021  
1020 1022          boolean_t               sess_boot_nic_reset;
1021 1023          kmutex_t                sess_enum_lock;
1022 1024          kcondvar_t              sess_enum_cv;
1023 1025          iscsi_enum_status_t     sess_enum_status;
1024 1026          iscsi_enum_result_t     sess_enum_result;
1025 1027          uint32_t                sess_enum_result_count;
1026 1028          ddi_taskq_t             *sess_enum_taskq;
1027 1029  
1028 1030          kmutex_t                sess_state_wmutex;
1029 1031          kcondvar_t              sess_state_wcv;
1030 1032          boolean_t               sess_state_hasw;
1031 1033  
1032 1034          /* to accelerate the state change in case of new event */
1033 1035          volatile uint32_t       sess_state_event_count;
1034 1036  } iscsi_sess_t;
1035 1037  
1036 1038  /*
1037 1039   * This structure will be used to store sessions to be online
1038 1040   * during normal login operation.
1039 1041   */
1040 1042  typedef struct iscsi_sess_list {
1041 1043          iscsi_sess_t            *session;
1042 1044          struct iscsi_sess_list  *next;
1043 1045  } iscsi_sess_list_t;
1044 1046  
1045 1047  /*
1046 1048   * iSCSI client notify task context for deferred IDM notifications processing
1047 1049   */
1048 1050  typedef struct iscsi_cn_task {
1049 1051          idm_conn_t              *ct_ic;
1050 1052          idm_client_notify_t     ct_icn;
1051 1053          uintptr_t               ct_data;
1052 1054  } iscsi_cn_task_t;
1053 1055  
1054 1056  /*
1055 1057   * iscsi_network
1056 1058   */
1057 1059  typedef struct iscsi_network {
1058 1060          void* (*socket)(int domain, int, int);
1059 1061          int (*bind)(void *, struct sockaddr *, int, int, int);
1060 1062          int (*connect)(void *, struct sockaddr *, int, int, int);
1061 1063          int (*listen)(void *, int);
1062 1064          void* (*accept)(void *, struct sockaddr *, int *);
1063 1065          int (*getsockname)(void *, struct sockaddr *, socklen_t *);
1064 1066          int (*getsockopt)(void *, int, int, void *, int *, int);
1065 1067          int (*setsockopt)(void *, int, int, void *, int);
1066 1068          int (*shutdown)(void *, int);
1067 1069          void (*close)(void *);
1068 1070  
1069 1071          size_t (*poll)(void *, clock_t);
1070 1072          size_t (*sendmsg)(void *, struct msghdr *);
1071 1073          size_t (*recvmsg)(void *, struct msghdr *, int);
1072 1074  
1073 1075          iscsi_status_t (*sendpdu)(void *, iscsi_hdr_t *, char *, int);
1074 1076          iscsi_status_t (*recvdata)(void *, iscsi_hdr_t *, char *,
1075 1077              int, int, int);
1076 1078          iscsi_status_t (*recvhdr)(void *, iscsi_hdr_t *, int, int, int);
1077 1079  
1078 1080          struct {
1079 1081                  int                     sndbuf;
1080 1082                  int                     rcvbuf;
1081 1083                  int                     nodelay;
1082 1084                  int                     conn_notify_threshold;
1083 1085                  int                     conn_abort_threshold;
1084 1086                  int                     abort_threshold;
1085 1087          } tweaks;
1086 1088  } iscsi_network_t;
1087 1089  
1088 1090  #define ISCSI_NET_HEADER_DIGEST 0x00000001
1089 1091  #define ISCSI_NET_DATA_DIGEST   0x00000002
1090 1092  
1091 1093  extern iscsi_network_t *iscsi_net;
1092 1094  
1093 1095  /*
1094 1096   * If we get bus_config requests in less than 5 seconds
1095 1097   * apart skip the name services re-discovery and just
1096 1098   * complete the requested logins.  This protects against
1097 1099   * bus_config storms from stale /dev links.
1098 1100   */
1099 1101  #define ISCSI_CONFIG_STORM_DELAY_DEFAULT    5
1100 1102  
1101 1103  /*
1102 1104   * iSCSI HBA Structure
1103 1105   */
1104 1106  typedef struct iscsi_hba {
1105 1107          uint32_t                hba_sig;
1106 1108          dev_info_t              *hba_dip;       /* dev info ptr */
1107 1109          scsi_hba_tran_t         *hba_tran;      /* scsi tran ptr */
1108 1110          ldi_ident_t             hba_li;
1109 1111  
1110 1112          struct iscsi_sess       *hba_sess_list; /* sess. list for hba */
1111 1113          krwlock_t               hba_sess_list_rwlock; /* protect sess. list */
1112 1114  
1113 1115          /* lbolt of the last time we received a config request */
1114 1116          clock_t                 hba_config_lbolt;
1115 1117          /* current number of seconds to protect against bus config storms */
1116 1118          int                     hba_config_storm_delay;
1117 1119  
1118 1120          /* general iSCSI protocol hba/initiator info */
1119 1121          uchar_t                 hba_name[ISCSI_MAX_NAME_LEN];
1120 1122          int                     hba_name_length;
1121 1123          uchar_t                 hba_alias[ISCSI_MAX_NAME_LEN];
1122 1124          int                     hba_alias_length;
1123 1125  
1124 1126          /* Default SessionID for HBA */
1125 1127          uchar_t                 hba_isid[ISCSI_ISID_LEN];
1126 1128  
1127 1129          /* Default HBA wide settings */
1128 1130          iscsi_login_params_t    hba_params;
1129 1131  
1130 1132          /*
1131 1133           * There's only one HBA and it's set to ISCSI_INITIATOR_OID
1132 1134           * (value of 1) at the beginning of time.
1133 1135           */
1134 1136          uint32_t                hba_oid;
1135 1137  
1136 1138          /*
1137 1139           * Keep track of which events have been sent. User daemons request
1138 1140           * this information so they don't wait for events which they won't
1139 1141           * see.
1140 1142           */
1141 1143          kmutex_t                hba_discovery_events_mutex;
1142 1144          iSCSIDiscoveryMethod_t  hba_discovery_events;
1143 1145          boolean_t               hba_discovery_in_progress;
1144 1146  
1145 1147          boolean_t               hba_mpxio_enabled; /* mpxio-enabled */
1146 1148          /* if the persistent store is loaded */
1147 1149          boolean_t               hba_persistent_loaded;
1148 1150  
1149 1151          /*
1150 1152           * Ensures only one SendTargets operation occurs at a time
1151 1153           */
1152 1154          ksema_t                 hba_sendtgts_semaphore;
1153 1155  
1154 1156          /*
1155 1157           * Statistics
1156 1158           */
1157 1159          struct {
1158 1160                  kstat_t                 *ks;
1159 1161                  iscsi_hba_stats_t       ks_data;
1160 1162          } stats;
1161 1163  
1162 1164          /*
1163 1165           * track/control the service status and client
1164 1166           *
1165 1167           * service- service online ensures the operational of cli
1166 1168           *        - and the availability of iSCSI discovery/devices
1167 1169           *        - so obviously offline means the unusable of cli
1168 1170           *        - , disabling of all discovery methods and to offline
1169 1171           *        - all discovered devices
1170 1172           *
1171 1173           * client - here the client actually means 'exclusive client'
1172 1174           *        - for operations these clients take may conflict
1173 1175           *        - with the changing of service status and therefore
1174 1176           *        - need to be exclusive
1175 1177           *
1176 1178           * The service has three status:
1177 1179           *      ISCSI_SERVICE_ENABLED    -      client is permitted to
1178 1180           *                               -      request service
1179 1181           *
1180 1182           *      ISCSI_SERVICE_DISABLED   -      client is not permitted to
1181 1183           *                               -      request service
1182 1184           *
1183 1185           *      ISCSI_SERVICE_TRANSITION -      client must wait for
1184 1186           *                               -      one of above two statuses
1185 1187           *
1186 1188           * The hba_service_client_count tracks the number of
1187 1189           * current clients, it increases with new clients and decreases
1188 1190           * with leaving clients. It stops to increase once the
1189 1191           * ISCSI_SERVICE_TRANSITION is set, and causes later clients be
1190 1192           * blocked there.
1191 1193           *
1192 1194           * The status of the service can only be changed when the number
1193 1195           * of current clients reaches zero.
1194 1196           *
1195 1197           * Clients include:
1196 1198           *      iscsi_ioctl
1197 1199           *      iscsi_tran_bus_config
1198 1200           *      iscsi_tran_bus_unconfig
1199 1201           *      isns_scn_callback
1200 1202           */
1201 1203          kmutex_t                hba_service_lock;
1202 1204          kcondvar_t              hba_service_cv;
1203 1205          uint32_t                hba_service_status;
1204 1206          uint32_t                hba_service_client_count;
1205 1207  
1206 1208          /* Default HBA tunable settings */
1207 1209          iscsi_tunable_params_t  hba_tunable_params;
1208 1210          boolean_t               hba_service_status_overwrite;
1209 1211  } iscsi_hba_t;
1210 1212  
1211 1213  /*
1212 1214   * +--------------------------------------------------------------------+
1213 1215   * | iSCSI prototypes                                                   |
1214 1216   * +--------------------------------------------------------------------+
1215 1217   */
1216 1218  
1217 1219  /* IDM client callback entry points */
1218 1220  idm_rx_pdu_cb_t iscsi_rx_scsi_rsp;
1219 1221  idm_rx_pdu_cb_t iscsi_rx_misc_pdu;
1220 1222  idm_rx_pdu_error_cb_t iscsi_rx_error_pdu;
1221 1223  idm_build_hdr_cb_t iscsi_build_hdr;
1222 1224  idm_task_cb_t iscsi_task_aborted;
1223 1225  idm_client_notify_cb_t iscsi_client_notify;
1224 1226  
1225 1227  /* iscsi_io.c */
1226 1228  int iscsi_sna_lte(uint32_t n1, uint32_t n2);
1227 1229  char *iscsi_get_next_text(char *data, int data_length, char *curr_text);
1228 1230  
1229 1231  void iscsi_ic_thread(iscsi_thread_t *thread, void *arg);
1230 1232  void iscsi_tx_thread(iscsi_thread_t *thread, void *arg);
1231 1233  void iscsi_wd_thread(iscsi_thread_t *thread, void *arg);
1232 1234  
1233 1235  iscsi_status_t iscsi_tx_cmd(iscsi_sess_t *isp, iscsi_cmd_t *icmdp);
1234 1236  
1235 1237  void iscsi_task_cleanup(int opcode, iscsi_cmd_t *icmdp);
1236 1238  
1237 1239  void iscsi_handle_abort(void *arg);
1238 1240  iscsi_status_t iscsi_handle_reset(iscsi_sess_t *isp, int level,
1239 1241      iscsi_lun_t *ilp);
1240 1242  iscsi_status_t iscsi_handle_logout(iscsi_conn_t *icp);
1241 1243  iscsi_status_t iscsi_handle_passthru(iscsi_sess_t *isp, uint16_t lun,
1242 1244      struct uscsi_cmd *ucmdp);
1243 1245  iscsi_status_t iscsi_handle_text(iscsi_conn_t *icp,
1244 1246      char *buf, uint32_t buf_len, uint32_t data_len, uint32_t *rx_data_len);
1245 1247  
1246 1248  void iscsi_iodone(iscsi_sess_t *isp, iscsi_cmd_t *icmdp);
1247 1249  
1248 1250  /* iscsi_crc.c */
1249 1251  uint32_t iscsi_crc32c(void *address, unsigned long length);
1250 1252  uint32_t iscsi_crc32c_continued(void *address, unsigned long length,
1251 1253      uint32_t crc);
1252 1254  
1253 1255  /* iscsi_queue.c */
1254 1256  void iscsi_init_queue(iscsi_queue_t *queue);
1255 1257  void iscsi_destroy_queue(iscsi_queue_t *queue);
1256 1258  void iscsi_enqueue_pending_cmd(iscsi_sess_t *isp, iscsi_cmd_t *icmdp);
1257 1259  void iscsi_dequeue_pending_cmd(iscsi_sess_t *isp, iscsi_cmd_t *icmdp);
1258 1260  void iscsi_enqueue_active_cmd(iscsi_conn_t *icp, iscsi_cmd_t *icmdp);
1259 1261  void iscsi_dequeue_active_cmd(iscsi_conn_t *icp, iscsi_cmd_t *icmdp);
1260 1262  void iscsi_enqueue_idm_aborting_cmd(iscsi_conn_t *icp, iscsi_cmd_t *icmdp);
1261 1263  void iscsi_dequeue_idm_aborting_cmd(iscsi_conn_t *icp, iscsi_cmd_t *icmdp);
1262 1264  void iscsi_enqueue_completed_cmd(iscsi_sess_t *isp, iscsi_cmd_t *icmdp);
1263 1265  iscsi_status_t iscsi_dequeue_cmd(iscsi_cmd_t **, iscsi_cmd_t **, iscsi_cmd_t *);
1264 1266  void iscsi_move_queue(iscsi_queue_t *src_queue, iscsi_queue_t *dst_queue);
1265 1267  void iscsi_enqueue_cmd_head(iscsi_cmd_t **, iscsi_cmd_t **,
1266 1268      iscsi_cmd_t *);
1267 1269  
1268 1270  /* iscsi_login.c */
1269 1271  iscsi_status_t iscsi_login_start(void *arg);
1270 1272  void iscsi_login_update_state(iscsi_conn_t *icp,
1271 1273      iscsi_login_state_t next_state);
1272 1274  void iscsi_login_update_state_locked(iscsi_conn_t *icp,
1273 1275      iscsi_login_state_t next_state);
1274 1276  
1275 1277  
1276 1278  /* iscsi_stats.c */
1277 1279  boolean_t iscsi_hba_kstat_init(struct iscsi_hba *ihp);
1278 1280  boolean_t iscsi_hba_kstat_term(struct iscsi_hba *ihp);
1279 1281  boolean_t iscsi_sess_kstat_init(struct iscsi_sess *isp);
1280 1282  boolean_t iscsi_sess_kstat_term(struct iscsi_sess *isp);
1281 1283  boolean_t iscsi_conn_kstat_init(struct iscsi_conn       *icp);
1282 1284  void iscsi_conn_kstat_term(struct iscsi_conn *icp);
1283 1285  
1284 1286  /* iscsi_net.c */
1285 1287  void iscsi_net_init();
1286 1288  void iscsi_net_fini();
1287 1289  iscsi_status_t iscsi_net_interface(boolean_t reset);
1288 1290  
1289 1291  /* iscsi_sess.c */
1290 1292  iscsi_sess_t *iscsi_sess_create(iscsi_hba_t *ihp,
1291 1293      iSCSIDiscoveryMethod_t method, struct sockaddr *addr_dsc,
1292 1294      char *target_name, int tpgt, uchar_t isid_lsb,
1293 1295      iscsi_sess_type_t type, uint32_t *oid);
1294 1296  void iscsi_sess_online(void *arg);
1295 1297  int iscsi_sess_get(uint32_t oid, iscsi_hba_t *ihp, iscsi_sess_t **ispp);
1296 1298  iscsi_status_t iscsi_sess_destroy(iscsi_sess_t *isp);
1297 1299  void iscsi_sess_state_machine(iscsi_sess_t *isp, iscsi_sess_event_t event,
1298 1300      uint32_t event_count);
1299 1301  char *iscsi_sess_state_str(iscsi_sess_state_t state);
1300 1302  boolean_t iscsi_sess_set_auth(iscsi_sess_t *isp);
1301 1303  iscsi_status_t iscsi_sess_reserve_scsi_itt(iscsi_cmd_t *icmdp);
1302 1304  void iscsi_sess_release_scsi_itt(iscsi_cmd_t *icmdp);
1303 1305  iscsi_status_t iscsi_sess_reserve_itt(iscsi_sess_t *isp, iscsi_cmd_t *icmdp);
1304 1306  void iscsi_sess_release_itt(iscsi_sess_t *isp, iscsi_cmd_t *icmdp);
1305 1307  void iscsi_sess_redrive_io(iscsi_sess_t *isp);
1306 1308  int iscsi_sess_get_by_target(uint32_t target_oid, iscsi_hba_t *ihp,
1307 1309      iscsi_sess_t **ispp);
1308 1310  iscsi_enum_result_t iscsi_sess_enum_request(iscsi_sess_t *isp,
1309 1311      boolean_t wait, uint32_t event_count);
1310 1312  iscsi_enum_result_t iscsi_sess_enum_query(iscsi_sess_t *isp);
1311 1313  void iscsi_sess_enter_state_zone(iscsi_sess_t *isp);
1312 1314  void iscsi_sess_exit_state_zone(iscsi_sess_t *isp);
1313 1315  
1314 1316  /* iscsi_conn.c */
1315 1317  iscsi_status_t iscsi_conn_create(struct sockaddr *addr, iscsi_sess_t *isp,
1316 1318      iscsi_conn_t **icpp);
1317 1319  iscsi_status_t iscsi_conn_online(iscsi_conn_t *icp);
1318 1320  iscsi_status_t iscsi_conn_offline(iscsi_conn_t *icp);
1319 1321  iscsi_status_t iscsi_conn_destroy(iscsi_conn_t *icp);
  
    | 
      ↓ open down ↓ | 
    758 lines elided | 
    
      ↑ open up ↑ | 
  
1320 1322  void iscsi_conn_set_login_min_max(iscsi_conn_t *icp, int min, int max);
1321 1323  iscsi_status_t iscsi_conn_sync_params(iscsi_conn_t *icp);
1322 1324  void iscsi_conn_retry(iscsi_sess_t *isp, iscsi_conn_t *icp);
1323 1325  void iscsi_conn_update_state(iscsi_conn_t *icp, iscsi_conn_state_t next_state);
1324 1326  void iscsi_conn_update_state_locked(iscsi_conn_t *icp,
1325 1327                          iscsi_conn_state_t next_state);
1326 1328  
1327 1329  /* iscsi_lun.c */
1328 1330  iscsi_status_t iscsi_lun_create(iscsi_sess_t *isp, uint16_t lun_num,
1329 1331      uint8_t lun_addr_type, struct scsi_inquiry *inq, char *guid);
1330      -iscsi_status_t iscsi_lun_destroy(iscsi_hba_t *ihp,
1331      -    iscsi_lun_t *ilp);
     1332 +void iscsi_lun_hold(iscsi_lun_t *ilp);
     1333 +void iscsi_lun_rele(iscsi_lun_t *ilp);
     1334 +iscsi_status_t iscsi_lun_destroy(iscsi_hba_t *ihp, iscsi_lun_t *ilp);
1332 1335  void iscsi_lun_online(iscsi_hba_t *ihp,
1333 1336      iscsi_lun_t *ilp);
1334 1337  iscsi_status_t iscsi_lun_offline(iscsi_hba_t *ihp,
1335 1338      iscsi_lun_t *ilp, boolean_t lun_free);
1336 1339  
1337 1340  /* iscsi_cmd.c */
1338 1341  void iscsi_cmd_state_machine(iscsi_cmd_t *icmdp,
1339 1342      iscsi_cmd_event_t event, void *arg);
1340 1343  iscsi_cmd_t     *iscsi_cmd_alloc(iscsi_conn_t *icp, int km_flags);
1341 1344  void            iscsi_cmd_free(iscsi_cmd_t *icmdp);
1342 1345  
1343 1346  /* iscsi_ioctl.c */
1344 1347  void * iscsi_ioctl_copyin(caddr_t arg, int mode, size_t size);
1345 1348  int iscsi_ioctl_copyout(void *data, size_t size, caddr_t arg, int mode);
1346 1349  iscsi_conn_list_t *iscsi_ioctl_conn_oid_list_get_copyin(caddr_t, int);
1347 1350  int iscsi_ioctl_conn_oid_list_get_copyout(iscsi_conn_list_t *, caddr_t, int);
1348 1351  boolean_t iscsi_ioctl_conn_oid_list_get(iscsi_hba_t *ihp,
1349 1352      iscsi_conn_list_t *cl);
1350 1353  boolean_t iscsi_ioctl_conn_props_get(iscsi_hba_t *ihp, iscsi_conn_props_t *cp);
1351 1354  int iscsi_ioctl_sendtgts_get(iscsi_hba_t *ihp, iscsi_sendtgts_list_t *stl);
1352 1355  int iscsi_target_prop_mod(iscsi_hba_t *, iscsi_property_t *, int cmd);
1353 1356  int iscsi_set_params(iscsi_param_set_t *, iscsi_hba_t *, boolean_t);
1354 1357  int iscsi_get_persisted_param(uchar_t *, iscsi_param_get_t *,
1355 1358      iscsi_login_params_t *);
1356 1359  void iscsi_set_default_login_params(iscsi_login_params_t *params);
1357 1360  int iscsi_ioctl_get_config_sess(iscsi_hba_t *ihp,
1358 1361      iscsi_config_sess_t *ics);
1359 1362  int iscsi_ioctl_set_config_sess(iscsi_hba_t *ihp,
1360 1363      iscsi_config_sess_t *ics);
1361 1364  int iscsi_ioctl_set_tunable_param(iscsi_hba_t *ihp,
1362 1365      iscsi_tunable_object_t *tpss);
1363 1366  /* ioctls  prototypes */
1364 1367  int iscsi_get_param(iscsi_login_params_t *params,
1365 1368      boolean_t valid_flag,
1366 1369      iscsi_param_get_t *ipgp);
1367 1370  
1368 1371  /* iscsid.c */
1369 1372  boolean_t iscsid_init(iscsi_hba_t *ihp);
1370 1373  boolean_t iscsid_start(iscsi_hba_t *ihp);
1371 1374  boolean_t iscsid_stop(iscsi_hba_t *ihp);
1372 1375  void iscsid_fini();
1373 1376  void iscsid_props(iSCSIDiscoveryProperties_t *props);
1374 1377  boolean_t iscsid_enable_discovery(iscsi_hba_t *ihp,
1375 1378      iSCSIDiscoveryMethod_t idm, boolean_t poke);
1376 1379  boolean_t iscsid_disable_discovery(iscsi_hba_t *ihp,
1377 1380      iSCSIDiscoveryMethod_t idm);
1378 1381  void iscsid_poke_discovery(iscsi_hba_t *ihp, iSCSIDiscoveryMethod_t method);
1379 1382  void iscsid_do_sendtgts(entry_t *discovery_addr);
1380 1383  void iscsid_do_isns_query_one_server(
1381 1384      iscsi_hba_t *ihp, entry_t *isns_addr);
1382 1385  void iscsid_do_isns_query(iscsi_hba_t *ihp);
1383 1386  void iscsid_config_one(iscsi_hba_t *ihp,
1384 1387      char *name, boolean_t protect);
1385 1388  void iscsid_config_all(iscsi_hba_t *ihp, boolean_t protect);
1386 1389  void iscsid_unconfig_one(iscsi_hba_t *ihp, char *name);
1387 1390  void iscsid_unconfig_all(iscsi_hba_t *ihp);
1388 1391  void isns_scn_callback(void *arg);
1389 1392  boolean_t iscsid_del(iscsi_hba_t *ihp, char *target_name,
1390 1393      iSCSIDiscoveryMethod_t method, struct sockaddr *addr_dsc);
1391 1394  boolean_t iscsid_login_tgt(iscsi_hba_t *ihp, char *target_name,
1392 1395      iSCSIDiscoveryMethod_t method, struct sockaddr *addr_dsc);
1393 1396  void iscsid_addr_to_sockaddr(int src_insize, void *src_addr, int src_port,
1394 1397      struct sockaddr *dst_addr);
1395 1398  void iscsid_set_default_initiator_node_settings(iscsi_hba_t *ihp,
1396 1399      boolean_t minimal);
1397 1400  
1398 1401  void iscsi_send_sysevent(iscsi_hba_t *ihp, char *eventcalss,
1399 1402      char *subclass, nvlist_t *np);
1400 1403  boolean_t iscsi_reconfig_boot_sess(iscsi_hba_t *ihp);
1401 1404  boolean_t iscsi_chk_bootlun_mpxio(iscsi_hba_t *ihp);
1402 1405  boolean_t iscsi_cmp_boot_ini_name(char *name);
1403 1406  boolean_t iscsi_cmp_boot_tgt_name(char *name);
1404 1407  boolean_t iscsi_client_request_service(iscsi_hba_t *ihp);
1405 1408  void iscsi_client_release_service(iscsi_hba_t *ihp);
1406 1409  
1407 1410  extern void bcopy(const void *s1, void *s2, size_t n);
1408 1411  extern void bzero(void *s, size_t n);
1409 1412  
1410 1413  #ifdef __cplusplus
1411 1414  }
1412 1415  #endif
1413 1416  
1414 1417  #endif /* _ISCSI_H */
  
    | 
      ↓ open down ↓ | 
    73 lines elided | 
    
      ↑ open up ↑ | 
  
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX