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