xref: /onnv-gate/usr/src/uts/common/io/scsi/adapters/iscsi/iscsi.h (revision 12161:1b0453703429)
17836SJohn.Forte@Sun.COM /*
27836SJohn.Forte@Sun.COM  * CDDL HEADER START
37836SJohn.Forte@Sun.COM  *
47836SJohn.Forte@Sun.COM  * The contents of this file are subject to the terms of the
57836SJohn.Forte@Sun.COM  * Common Development and Distribution License (the "License").
67836SJohn.Forte@Sun.COM  * You may not use this file except in compliance with the License.
77836SJohn.Forte@Sun.COM  *
87836SJohn.Forte@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97836SJohn.Forte@Sun.COM  * or http://www.opensolaris.org/os/licensing.
107836SJohn.Forte@Sun.COM  * See the License for the specific language governing permissions
117836SJohn.Forte@Sun.COM  * and limitations under the License.
127836SJohn.Forte@Sun.COM  *
137836SJohn.Forte@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
147836SJohn.Forte@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157836SJohn.Forte@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
167836SJohn.Forte@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
177836SJohn.Forte@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
187836SJohn.Forte@Sun.COM  *
197836SJohn.Forte@Sun.COM  * CDDL HEADER END
207836SJohn.Forte@Sun.COM  */
217836SJohn.Forte@Sun.COM /*
227836SJohn.Forte@Sun.COM  * Copyright 2000 by Cisco Systems, Inc.  All rights reserved.
23*12161SJack.Meng@Sun.COM  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
247836SJohn.Forte@Sun.COM  */
257836SJohn.Forte@Sun.COM 
267836SJohn.Forte@Sun.COM #ifndef _ISCSI_H
277836SJohn.Forte@Sun.COM #define	_ISCSI_H
287836SJohn.Forte@Sun.COM 
297836SJohn.Forte@Sun.COM /*
307836SJohn.Forte@Sun.COM  * Block comment which describes the contents of this file.
317836SJohn.Forte@Sun.COM  */
327836SJohn.Forte@Sun.COM 
337836SJohn.Forte@Sun.COM #ifdef __cplusplus
347836SJohn.Forte@Sun.COM extern "C" {
357836SJohn.Forte@Sun.COM #endif
367836SJohn.Forte@Sun.COM 
377836SJohn.Forte@Sun.COM #include <sys/scsi/scsi.h>
387836SJohn.Forte@Sun.COM #include <sys/ddi.h>
397836SJohn.Forte@Sun.COM #include <sys/sunddi.h>
407836SJohn.Forte@Sun.COM #include <sys/socket.h>
417836SJohn.Forte@Sun.COM #include <sys/kstat.h>
427836SJohn.Forte@Sun.COM #include <sys/sunddi.h>
437836SJohn.Forte@Sun.COM #include <sys/sunmdi.h>
447836SJohn.Forte@Sun.COM #include <sys/mdi_impldefs.h>
457836SJohn.Forte@Sun.COM #include <sys/time.h>
467836SJohn.Forte@Sun.COM #include <sys/nvpair.h>
477836SJohn.Forte@Sun.COM #include <sys/sdt.h>
487836SJohn.Forte@Sun.COM 
499162SPeter.Dunlap@Sun.COM #include <sys/iscsi_protocol.h>
507836SJohn.Forte@Sun.COM #include <sys/scsi/adapters/iscsi_if.h>
517836SJohn.Forte@Sun.COM #include <iscsiAuthClient.h>
527836SJohn.Forte@Sun.COM #include <iscsi_stats.h>
537836SJohn.Forte@Sun.COM #include <iscsi_thread.h>
549162SPeter.Dunlap@Sun.COM #include <sys/idm/idm.h>
559162SPeter.Dunlap@Sun.COM #include <sys/idm/idm_conn_sm.h>
567836SJohn.Forte@Sun.COM #include <nvfile.h>
577836SJohn.Forte@Sun.COM 
587836SJohn.Forte@Sun.COM #ifndef MIN
597836SJohn.Forte@Sun.COM #define	MIN(a, b) ((a) < (b) ? (a) : (b))
607836SJohn.Forte@Sun.COM #endif
617836SJohn.Forte@Sun.COM 
627836SJohn.Forte@Sun.COM #ifndef TRUE
637836SJohn.Forte@Sun.COM #define	TRUE 1
647836SJohn.Forte@Sun.COM #endif
657836SJohn.Forte@Sun.COM 
667836SJohn.Forte@Sun.COM #ifndef FALSE
677836SJohn.Forte@Sun.COM #define	FALSE 0
687836SJohn.Forte@Sun.COM #endif
697836SJohn.Forte@Sun.COM 
707836SJohn.Forte@Sun.COM #define	LOGIN_PDU_BUFFER_SIZE	(16 * 1024)	/* move somewhere else */
717836SJohn.Forte@Sun.COM 
729162SPeter.Dunlap@Sun.COM extern boolean_t iscsi_conn_logging;
739162SPeter.Dunlap@Sun.COM extern boolean_t iscsi_io_logging;
749162SPeter.Dunlap@Sun.COM extern boolean_t iscsi_login_logging;
759162SPeter.Dunlap@Sun.COM extern boolean_t iscsi_logging;
769162SPeter.Dunlap@Sun.COM extern boolean_t iscsi_sess_logging;
779162SPeter.Dunlap@Sun.COM #define	ISCSI_CONN_LOG	if (iscsi_conn_logging) cmn_err
789162SPeter.Dunlap@Sun.COM #define	ISCSI_IO_LOG	if (iscsi_io_logging) cmn_err
799162SPeter.Dunlap@Sun.COM #define	ISCSI_LOGIN_LOG	if (iscsi_login_logging) cmn_err
809162SPeter.Dunlap@Sun.COM #define	ISCSI_LOG	if (iscsi_logging) cmn_err
819162SPeter.Dunlap@Sun.COM #define	ISCSI_SESS_LOG	if (iscsi_sess_logging) cmn_err
829162SPeter.Dunlap@Sun.COM 
837836SJohn.Forte@Sun.COM /*
847836SJohn.Forte@Sun.COM  * Name Format of the different Task Queues
857836SJohn.Forte@Sun.COM  */
867836SJohn.Forte@Sun.COM #define	ISCSI_SESS_IOTH_NAME_FORMAT		"io_thrd_%d.%d"
877836SJohn.Forte@Sun.COM #define	ISCSI_SESS_WD_NAME_FORMAT		"wd_thrd_%d.%d"
887836SJohn.Forte@Sun.COM #define	ISCSI_SESS_LOGIN_TASKQ_NAME_FORMAT	"login_taskq_%d.%d"
89*12161SJack.Meng@Sun.COM #define	ISCSI_SESS_ENUM_TASKQ_NAME_FORMAT	"enum_taskq_%d.%d"
909162SPeter.Dunlap@Sun.COM #define	ISCSI_CONN_CN_TASKQ_NAME_FORMAT		"conn_cn_taskq_%d.%d.%d"
917836SJohn.Forte@Sun.COM #define	ISCSI_CONN_RXTH_NAME_FORMAT		"rx_thrd_%d.%d.%d"
927836SJohn.Forte@Sun.COM #define	ISCSI_CONN_TXTH_NAME_FORMAT		"tx_thrd_%d.%d.%d"
937836SJohn.Forte@Sun.COM 
947836SJohn.Forte@Sun.COM /*
957836SJohn.Forte@Sun.COM  * The iSCSI driver will not build scatter/gather lists (iovec) longer
967836SJohn.Forte@Sun.COM  * than the value defined here. Asserts have been include in the code
977836SJohn.Forte@Sun.COM  * to check.
987836SJohn.Forte@Sun.COM  */
997836SJohn.Forte@Sun.COM #define	ISCSI_MAX_IOVEC		5
1007836SJohn.Forte@Sun.COM 
1017836SJohn.Forte@Sun.COM #define	ISCSI_DEFAULT_MAX_STORM_DELAY		32
1027836SJohn.Forte@Sun.COM 
1037836SJohn.Forte@Sun.COM /*
1047836SJohn.Forte@Sun.COM  * The SNDBUF and RCVBUF size parameters for the sockets are just a
1057836SJohn.Forte@Sun.COM  * guess for the time being (I think it is the values used by CISCO
1067836SJohn.Forte@Sun.COM  * or UNH).  Testing will have to be done to figure * out the impact
1077836SJohn.Forte@Sun.COM  * of these values on performance.
1087836SJohn.Forte@Sun.COM  */
1097836SJohn.Forte@Sun.COM #define	ISCSI_SOCKET_SNDBUF_SIZE		(256 * 1024)
1107836SJohn.Forte@Sun.COM #define	ISCSI_SOCKET_RCVBUF_SIZE		(256 * 1024)
1117836SJohn.Forte@Sun.COM #define	ISCSI_TCP_NODELAY_DEFAULT		0
1127836SJohn.Forte@Sun.COM #define	ISCSI_TCP_CNOTIFY_THRESHOLD_DEFAULT	2000
1137836SJohn.Forte@Sun.COM #define	ISCSI_TCP_CABORT_THRESHOLD_DEFAULT	10000
1147836SJohn.Forte@Sun.COM #define	ISCSI_TCP_ABORT_THRESHOLD_DEFAULT	(30 * 1000) /* milliseconds */
1157836SJohn.Forte@Sun.COM #define	ISNS_TCP_ABORT_THRESHOLD_DEFAULT	(3 * 1000) /* milliseconds */
1167836SJohn.Forte@Sun.COM 
11710156SZhang.Yi@Sun.COM /* Default values for tunable parameters */
11810156SZhang.Yi@Sun.COM #define	ISCSI_DEFAULT_RX_TIMEOUT_VALUE		60
11910156SZhang.Yi@Sun.COM #define	ISCSI_DEFAULT_CONN_DEFAULT_LOGIN_MAX	180
12010156SZhang.Yi@Sun.COM #define	ISCSI_DEFAULT_LOGIN_POLLING_DELAY	60
1217836SJohn.Forte@Sun.COM 
1227836SJohn.Forte@Sun.COM /*
1237836SJohn.Forte@Sun.COM  * Convenient short hand defines
1247836SJohn.Forte@Sun.COM  */
1257836SJohn.Forte@Sun.COM #define	TARGET_PROP	"target"
1267836SJohn.Forte@Sun.COM #define	LUN_PROP	"lun"
1277836SJohn.Forte@Sun.COM #define	MDI_GUID	"wwn"
1287836SJohn.Forte@Sun.COM #define	NDI_GUID	"client-guid"
1297836SJohn.Forte@Sun.COM 
1307836SJohn.Forte@Sun.COM #define	ISCSI_SIG_CMD	0x11111111
1317836SJohn.Forte@Sun.COM #define	ISCSI_SIG_LUN	0x22222222
1327836SJohn.Forte@Sun.COM #define	ISCSI_SIG_CONN	0x33333333
1337836SJohn.Forte@Sun.COM #define	ISCSI_SIG_SESS	0x44444444
1347836SJohn.Forte@Sun.COM #define	ISCSI_SIG_HBA	0x55555555
1357836SJohn.Forte@Sun.COM 
1367836SJohn.Forte@Sun.COM #define	SENDTARGETS_DISCOVERY	"SENDTARGETS_DISCOVERY"
1377836SJohn.Forte@Sun.COM 
1387836SJohn.Forte@Sun.COM #define	ISCSI_LUN_MASK_MSB	0x00003f00
1397836SJohn.Forte@Sun.COM #define	ISCSI_LUN_MASK_LSB	0x000000ff
14011272SMilos.Muzik@Sun.COM #define	ISCSI_LUN_MASK		(ISCSI_LUN_MASK_MSB | ISCSI_LUN_MASK_LSB)
1417836SJohn.Forte@Sun.COM #define	ISCSI_LUN_BYTE_COPY(lun, report_lun_data) \
1427836SJohn.Forte@Sun.COM 	lun[0] = (report_lun_data & ISCSI_LUN_MASK_MSB) >> 8; \
1437836SJohn.Forte@Sun.COM 	lun[1] = (report_lun_data & ISCSI_LUN_MASK_LSB);
1447836SJohn.Forte@Sun.COM /*
1457836SJohn.Forte@Sun.COM  * Not defined by iSCSI, but used in the login code to
1467836SJohn.Forte@Sun.COM  * determine when to send the initial Login PDU
1477836SJohn.Forte@Sun.COM  */
1487836SJohn.Forte@Sun.COM #define	ISCSI_INITIAL_LOGIN_STAGE	-1
1497836SJohn.Forte@Sun.COM 
1507836SJohn.Forte@Sun.COM typedef enum iscsi_status {
1517836SJohn.Forte@Sun.COM 	/* Success */
1527836SJohn.Forte@Sun.COM 	ISCSI_STATUS_SUCCESS = 0,
1537836SJohn.Forte@Sun.COM 	/* Driver / Kernel / Code error */
1547836SJohn.Forte@Sun.COM 	ISCSI_STATUS_INTERNAL_ERROR,
1557836SJohn.Forte@Sun.COM 	/* ITT table is already full, unable to reserve slot */
1567836SJohn.Forte@Sun.COM 	ISCSI_STATUS_ITT_TABLE_FULL,
1577836SJohn.Forte@Sun.COM 	/* Login on connection failed */
1587836SJohn.Forte@Sun.COM 	ISCSI_STATUS_LOGIN_FAILED,
1597836SJohn.Forte@Sun.COM 	/* No connections are in the LOGGED_IN state */
1607836SJohn.Forte@Sun.COM 	ISCSI_STATUS_NO_CONN_LOGGED_IN,
1617836SJohn.Forte@Sun.COM 	/* TCP Transfer Error */
1627836SJohn.Forte@Sun.COM 	ISCSI_STATUS_TCP_TX_ERROR,
1637836SJohn.Forte@Sun.COM 	/* TCP Receive Error */
1647836SJohn.Forte@Sun.COM 	ISCSI_STATUS_TCP_RX_ERROR,
1657836SJohn.Forte@Sun.COM 	/* iSCSI packet RCV timeout */
1667836SJohn.Forte@Sun.COM 	ISCSI_STATUS_RX_TIMEOUT,
1677836SJohn.Forte@Sun.COM 	/* iSCSI Header Digest CRC error */
1687836SJohn.Forte@Sun.COM 	ISCSI_STATUS_HEADER_DIGEST_ERROR,
1697836SJohn.Forte@Sun.COM 	/* iSCSI Data Digest CRC error */
1707836SJohn.Forte@Sun.COM 	ISCSI_STATUS_DATA_DIGEST_ERROR,
1717836SJohn.Forte@Sun.COM 	/* kmem_alloc failure */
1727836SJohn.Forte@Sun.COM 	ISCSI_STATUS_ALLOC_FAILURE,
1737836SJohn.Forte@Sun.COM 	/* cmd (tran_abort/reset) failed */
1747836SJohn.Forte@Sun.COM 	ISCSI_STATUS_CMD_FAILED,
1757836SJohn.Forte@Sun.COM 	/* iSCSI protocol error */
1767836SJohn.Forte@Sun.COM 	ISCSI_STATUS_PROTOCOL_ERROR,
1777836SJohn.Forte@Sun.COM 	/* iSCSI protocol version mismatch */
1787836SJohn.Forte@Sun.COM 	ISCSI_STATUS_VERSION_MISMATCH,
1797836SJohn.Forte@Sun.COM 	/* iSCSI login negotiation failed */
1807836SJohn.Forte@Sun.COM 	ISCSI_STATUS_NEGO_FAIL,
1817836SJohn.Forte@Sun.COM 	/* iSCSI login authentication failed */
1827836SJohn.Forte@Sun.COM 	ISCSI_STATUS_AUTHENTICATION_FAILED,
1837836SJohn.Forte@Sun.COM 	/* iSCSI login redirection failed */
1847836SJohn.Forte@Sun.COM 	ISCSI_STATUS_REDIRECTION_FAILED,
1857836SJohn.Forte@Sun.COM 	/* iSCSI uscsi status failure */
1867836SJohn.Forte@Sun.COM 	ISCSI_STATUS_USCSI_FAILED,
1877836SJohn.Forte@Sun.COM 	/* data received would have overflowed given buffer */
1887836SJohn.Forte@Sun.COM 	ISCSI_STATUS_DATA_OVERFLOW,
1897836SJohn.Forte@Sun.COM 	/* session/connection needs to shutdown */
1907836SJohn.Forte@Sun.COM 	ISCSI_STATUS_SHUTDOWN,
1917836SJohn.Forte@Sun.COM 	/* logical unit in use */
1929162SPeter.Dunlap@Sun.COM 	ISCSI_STATUS_BUSY,
1939162SPeter.Dunlap@Sun.COM 	/* Login on connection failed, retries exceeded */
19412001SZhang.Yi@Sun.COM 	ISCSI_STATUS_LOGIN_TIMED_OUT,
19512001SZhang.Yi@Sun.COM 	/* iSCSI login tpgt negotiation failed */
19612001SZhang.Yi@Sun.COM 	ISCSI_STATUS_LOGIN_TPGT_NEGO_FAIL
1977836SJohn.Forte@Sun.COM } iscsi_status_t;
1987836SJohn.Forte@Sun.COM #define	ISCSI_SUCCESS(status) (status == ISCSI_STATUS_SUCCESS)
1997836SJohn.Forte@Sun.COM 
2007836SJohn.Forte@Sun.COM /* SNA32 check value used on increment of CmdSn values */
2017836SJohn.Forte@Sun.COM #define	ISCSI_SNA32_CHECK 2147483648UL /* 2**31 */
2027836SJohn.Forte@Sun.COM 
2037836SJohn.Forte@Sun.COM /*
2047836SJohn.Forte@Sun.COM  * This is the maximum number of commands that can be outstanding
2057836SJohn.Forte@Sun.COM  * on a iSCSI session at anyone point in time.
2067836SJohn.Forte@Sun.COM  */
2077836SJohn.Forte@Sun.COM #define	ISCSI_CMD_TABLE_SIZE		1024
2087836SJohn.Forte@Sun.COM 
2097836SJohn.Forte@Sun.COM /* Used on connections thread create of receiver thread */
2107836SJohn.Forte@Sun.COM extern pri_t minclsyspri;
2117836SJohn.Forte@Sun.COM 
2127836SJohn.Forte@Sun.COM /*
2137836SJohn.Forte@Sun.COM  * Callers of iscsid_config_one/all must hold this
2147836SJohn.Forte@Sun.COM  * semaphore across the calls.  Otherwise a ndi_devi_enter()
2157836SJohn.Forte@Sun.COM  * deadlock in the DDI layer may occur.
2167836SJohn.Forte@Sun.COM  */
2177836SJohn.Forte@Sun.COM extern ksema_t iscsid_config_semaphore;
2187836SJohn.Forte@Sun.COM 
2197836SJohn.Forte@Sun.COM extern kmutex_t iscsi_oid_mutex;
2207836SJohn.Forte@Sun.COM extern uint32_t iscsi_oid;
2217836SJohn.Forte@Sun.COM extern void *iscsi_state;
2227836SJohn.Forte@Sun.COM 
2237836SJohn.Forte@Sun.COM /*
2247836SJohn.Forte@Sun.COM  * NOP delay is used to send a iSCSI NOP (ie. ping) across the
2257836SJohn.Forte@Sun.COM  * wire to see if the target is still alive.  NOPs are only
2267836SJohn.Forte@Sun.COM  * sent when the RX thread hasn't received anything for the
2277836SJohn.Forte@Sun.COM  * below amount of time.
2287836SJohn.Forte@Sun.COM  */
2297836SJohn.Forte@Sun.COM #define	ISCSI_DEFAULT_NOP_DELAY			5 /* seconds */
2307836SJohn.Forte@Sun.COM extern int	iscsi_nop_delay;
2317836SJohn.Forte@Sun.COM /*
2327836SJohn.Forte@Sun.COM  * If we haven't received anything in a specified period of time
2337836SJohn.Forte@Sun.COM  * we will stop accepting IO via tran start.  This will enable
2347836SJohn.Forte@Sun.COM  * upper level drivers to see we might be having a problem and
2357836SJohn.Forte@Sun.COM  * in the case of scsi_vhci will start to route IO down a better
2367836SJohn.Forte@Sun.COM  * path.
2377836SJohn.Forte@Sun.COM  */
2387836SJohn.Forte@Sun.COM #define	ISCSI_DEFAULT_RX_WINDOW			20 /* seconds */
2397836SJohn.Forte@Sun.COM extern int	iscsi_rx_window;
2407836SJohn.Forte@Sun.COM /*
2417836SJohn.Forte@Sun.COM  * If we haven't received anything in a specified period of time
2427836SJohn.Forte@Sun.COM  * we will stop accepting IO via tran start.  This the max limit
2437836SJohn.Forte@Sun.COM  * when encountered we will start returning a fatal error.
2447836SJohn.Forte@Sun.COM  */
2457836SJohn.Forte@Sun.COM #define	ISCSI_DEFAULT_RX_MAX_WINDOW		180 /* seconds */
2467836SJohn.Forte@Sun.COM extern int	iscsi_rx_max_window;
2477836SJohn.Forte@Sun.COM 
2487836SJohn.Forte@Sun.COM /*
2498194SJack.Meng@Sun.COM  * During iscsi boot, if the boot session has been created, the
2508194SJack.Meng@Sun.COM  * initiator hasn't changed the boot lun to be online, we will wait
2518194SJack.Meng@Sun.COM  * 180s here for lun online by default.
2528194SJack.Meng@Sun.COM  */
2538194SJack.Meng@Sun.COM #define	ISCSI_BOOT_DEFAULT_MAX_DELAY		180 /* seconds */
2548194SJack.Meng@Sun.COM /*
2557836SJohn.Forte@Sun.COM  * +--------------------------------------------------------------------+
2567836SJohn.Forte@Sun.COM  * | iSCSI Driver Structures						|
2577836SJohn.Forte@Sun.COM  * +--------------------------------------------------------------------+
2587836SJohn.Forte@Sun.COM  */
2597836SJohn.Forte@Sun.COM 
2607836SJohn.Forte@Sun.COM /*
2617836SJohn.Forte@Sun.COM  * iSCSI Auth Information
2627836SJohn.Forte@Sun.COM  */
2637836SJohn.Forte@Sun.COM typedef struct iscsi_auth {
2647836SJohn.Forte@Sun.COM 	IscsiAuthStringBlock    auth_recv_string_block;
2657836SJohn.Forte@Sun.COM 	IscsiAuthStringBlock    auth_send_string_block;
2667836SJohn.Forte@Sun.COM 	IscsiAuthLargeBinary    auth_recv_binary_block;
2677836SJohn.Forte@Sun.COM 	IscsiAuthLargeBinary    auth_send_binary_block;
2687836SJohn.Forte@Sun.COM 	IscsiAuthClient		auth_client_block;
2697836SJohn.Forte@Sun.COM 	int			num_auth_buffers;
2707836SJohn.Forte@Sun.COM 	IscsiAuthBufferDesc	auth_buffers[5];
2717836SJohn.Forte@Sun.COM 
2727836SJohn.Forte@Sun.COM 	/*
2737836SJohn.Forte@Sun.COM 	 * To indicate if bi-directional authentication is enabled.
2747836SJohn.Forte@Sun.COM 	 * 0 means uni-directional authentication.
2757836SJohn.Forte@Sun.COM 	 * 1 means bi-directional authentication.
2767836SJohn.Forte@Sun.COM 	 */
2777836SJohn.Forte@Sun.COM 	int			bidirectional_auth;
2787836SJohn.Forte@Sun.COM 
2797836SJohn.Forte@Sun.COM 	/* Initiator's authentication information. */
2807836SJohn.Forte@Sun.COM 	char			username[iscsiAuthStringMaxLength];
2817836SJohn.Forte@Sun.COM 	uint8_t			password[iscsiAuthStringMaxLength];
2827836SJohn.Forte@Sun.COM 	int			password_length;
2837836SJohn.Forte@Sun.COM 
2847836SJohn.Forte@Sun.COM 	/* Target's authentication information. */
2857836SJohn.Forte@Sun.COM 	char			username_in[iscsiAuthStringMaxLength];
2867836SJohn.Forte@Sun.COM 	uint8_t			password_in[iscsiAuthStringMaxLength];
2877836SJohn.Forte@Sun.COM 	int			password_length_in;
2887836SJohn.Forte@Sun.COM } iscsi_auth_t;
2897836SJohn.Forte@Sun.COM 
2907836SJohn.Forte@Sun.COM /*
2917836SJohn.Forte@Sun.COM  * iSCSI Task
2927836SJohn.Forte@Sun.COM  */
2937836SJohn.Forte@Sun.COM typedef struct iscsi_task {
2947836SJohn.Forte@Sun.COM 	void			*t_arg;
2957836SJohn.Forte@Sun.COM 	boolean_t		t_blocking;
296*12161SJack.Meng@Sun.COM 	uint32_t		t_event_count;
2977836SJohn.Forte@Sun.COM } iscsi_task_t;
2987836SJohn.Forte@Sun.COM 
2997836SJohn.Forte@Sun.COM /*
3007836SJohn.Forte@Sun.COM  * These are all the iscsi_cmd types that we use to track our
3017836SJohn.Forte@Sun.COM  * commands between queues and actions.
3027836SJohn.Forte@Sun.COM  */
3037836SJohn.Forte@Sun.COM typedef enum iscsi_cmd_type {
3047836SJohn.Forte@Sun.COM 	ISCSI_CMD_TYPE_SCSI = 1,	/* scsi cmd */
3057836SJohn.Forte@Sun.COM 	ISCSI_CMD_TYPE_NOP,		/* nop / ping */
3067836SJohn.Forte@Sun.COM 	ISCSI_CMD_TYPE_ABORT,		/* abort */
3077836SJohn.Forte@Sun.COM 	ISCSI_CMD_TYPE_RESET,		/* reset */
3087836SJohn.Forte@Sun.COM 	ISCSI_CMD_TYPE_LOGOUT,		/* logout */
3097836SJohn.Forte@Sun.COM 	ISCSI_CMD_TYPE_LOGIN,		/* login */
3107836SJohn.Forte@Sun.COM 	ISCSI_CMD_TYPE_TEXT		/* text */
3117836SJohn.Forte@Sun.COM } iscsi_cmd_type_t;
3127836SJohn.Forte@Sun.COM 
3137836SJohn.Forte@Sun.COM /*
3147836SJohn.Forte@Sun.COM  * iscsi_cmd_state - (reference iscsi_cmd.c for state diagram)
3157836SJohn.Forte@Sun.COM  */
3167836SJohn.Forte@Sun.COM typedef enum iscsi_cmd_state {
3179162SPeter.Dunlap@Sun.COM 	ISCSI_CMD_STATE_FREE = 0,
3187836SJohn.Forte@Sun.COM 	ISCSI_CMD_STATE_PENDING,
3197836SJohn.Forte@Sun.COM 	ISCSI_CMD_STATE_ACTIVE,
3207836SJohn.Forte@Sun.COM 	ISCSI_CMD_STATE_ABORTING,
3219162SPeter.Dunlap@Sun.COM 	ISCSI_CMD_STATE_IDM_ABORTING,
3229162SPeter.Dunlap@Sun.COM 	ISCSI_CMD_STATE_COMPLETED,
3239162SPeter.Dunlap@Sun.COM 	ISCSI_CMD_STATE_MAX
3247836SJohn.Forte@Sun.COM } iscsi_cmd_state_t;
3257836SJohn.Forte@Sun.COM 
3269162SPeter.Dunlap@Sun.COM #ifdef ISCSI_CMD_SM_STRINGS
3279162SPeter.Dunlap@Sun.COM static const char *iscsi_cmd_state_names[ISCSI_CMD_STATE_MAX+1] = {
3289162SPeter.Dunlap@Sun.COM 	"ISCSI_CMD_STATE_FREE",
3299162SPeter.Dunlap@Sun.COM 	"ISCSI_CMD_STATE_PENDING",
3309162SPeter.Dunlap@Sun.COM 	"ISCSI_CMD_STATE_ACTIVE",
3319162SPeter.Dunlap@Sun.COM 	"ISCSI_CMD_STATE_ABORTING",
3329162SPeter.Dunlap@Sun.COM 	"ISCSI_CMD_STATE_IDM_ABORTING",
3339162SPeter.Dunlap@Sun.COM 	"ISCSI_CMD_STATE_COMPLETED",
3349162SPeter.Dunlap@Sun.COM 	"ISCSI_CMD_STATE_MAX"
3359162SPeter.Dunlap@Sun.COM };
3369162SPeter.Dunlap@Sun.COM #endif
3379162SPeter.Dunlap@Sun.COM 
3387836SJohn.Forte@Sun.COM /*
3397836SJohn.Forte@Sun.COM  * iscsi command events
3407836SJohn.Forte@Sun.COM  */
3417836SJohn.Forte@Sun.COM typedef enum iscsi_cmd_event {
3429162SPeter.Dunlap@Sun.COM 	ISCSI_CMD_EVENT_E1 = 0,
3437836SJohn.Forte@Sun.COM 	ISCSI_CMD_EVENT_E2,
3447836SJohn.Forte@Sun.COM 	ISCSI_CMD_EVENT_E3,
3457836SJohn.Forte@Sun.COM 	ISCSI_CMD_EVENT_E4,
3467836SJohn.Forte@Sun.COM 	ISCSI_CMD_EVENT_E6,
3477836SJohn.Forte@Sun.COM 	ISCSI_CMD_EVENT_E7,
3489162SPeter.Dunlap@Sun.COM 	ISCSI_CMD_EVENT_E8,
3499162SPeter.Dunlap@Sun.COM 	ISCSI_CMD_EVENT_E9,
3509162SPeter.Dunlap@Sun.COM 	ISCSI_CMD_EVENT_E10,
3519162SPeter.Dunlap@Sun.COM 	ISCSI_CMD_EVENT_MAX
3527836SJohn.Forte@Sun.COM } iscsi_cmd_event_t;
3537836SJohn.Forte@Sun.COM 
3549162SPeter.Dunlap@Sun.COM #ifdef ISCSI_CMD_SM_STRINGS
3559162SPeter.Dunlap@Sun.COM static const char *iscsi_cmd_event_names[ISCSI_CMD_EVENT_MAX+1] = {
3569162SPeter.Dunlap@Sun.COM 	"ISCSI_CMD_EVENT_E1",
3579162SPeter.Dunlap@Sun.COM 	"ISCSI_CMD_EVENT_E2",
3589162SPeter.Dunlap@Sun.COM 	"ISCSI_CMD_EVENT_E3",
3599162SPeter.Dunlap@Sun.COM 	"ISCSI_CMD_EVENT_E4",
3609162SPeter.Dunlap@Sun.COM 	"ISCSI_CMD_EVENT_E6",
3619162SPeter.Dunlap@Sun.COM 	"ISCSI_CMD_EVENT_E7",
3629162SPeter.Dunlap@Sun.COM 	"ISCSI_CMD_EVENT_E8",
3639162SPeter.Dunlap@Sun.COM 	"ISCSI_CMD_EVENT_E9",
3649162SPeter.Dunlap@Sun.COM 	"ISCSI_CMD_EVENT_E10",
3659162SPeter.Dunlap@Sun.COM 	"ISCSI_CMD_EVENT_MAX"
3669162SPeter.Dunlap@Sun.COM };
3679162SPeter.Dunlap@Sun.COM #endif
3689162SPeter.Dunlap@Sun.COM 
3697836SJohn.Forte@Sun.COM /*
3707836SJohn.Forte@Sun.COM  * iscsi text command stages - these stages are used by iSCSI text
3717836SJohn.Forte@Sun.COM  * processing to manage long resonses.
3727836SJohn.Forte@Sun.COM  */
3737836SJohn.Forte@Sun.COM typedef enum iscsi_cmd_text_stage {
3749162SPeter.Dunlap@Sun.COM 	ISCSI_CMD_TEXT_INITIAL_REQ = 0,
3757836SJohn.Forte@Sun.COM 	ISCSI_CMD_TEXT_CONTINUATION,
3767836SJohn.Forte@Sun.COM 	ISCSI_CMD_TEXT_FINAL_RSP
3777836SJohn.Forte@Sun.COM } iscsi_cmd_text_stage_t;
3787836SJohn.Forte@Sun.COM 
3797836SJohn.Forte@Sun.COM /*
3808231SJack.Meng@Sun.COM  * iscsi cmd misc flags - bitwise applicable
3818231SJack.Meng@Sun.COM  */
3828231SJack.Meng@Sun.COM #define	ISCSI_CMD_MISCFLAG_INTERNAL	0x1
3838231SJack.Meng@Sun.COM #define	ISCSI_CMD_MISCFLAG_FREE		0x2
3848231SJack.Meng@Sun.COM #define	ISCSI_CMD_MISCFLAG_STUCK	0x4
3858294SShengliang.Zhang@Sun.COM #define	ISCSI_CMD_MISCFLAG_XARQ 	0x8
3869780SBing.Zhao@Sun.COM #define	ISCSI_CMD_MISCFLAG_SENT		0x10
3879780SBing.Zhao@Sun.COM #define	ISCSI_CMD_MISCFLAG_FLUSH	0x20
3889780SBing.Zhao@Sun.COM 
3899780SBing.Zhao@Sun.COM /*
3909780SBing.Zhao@Sun.COM  * 1/2 of a 32 bit number, used for checking CmdSN
3919780SBing.Zhao@Sun.COM  * wrapped.
3929780SBing.Zhao@Sun.COM  */
3939780SBing.Zhao@Sun.COM #define	ISCSI_CMD_SN_WRAP		0x80000000
3949780SBing.Zhao@Sun.COM 
3959780SBing.Zhao@Sun.COM #define	ISCSI_CMD_PKT_STAT_INIT		0
3968231SJack.Meng@Sun.COM 
3978231SJack.Meng@Sun.COM /*
3987836SJohn.Forte@Sun.COM  * iSCSI cmd/pkt Structure
3997836SJohn.Forte@Sun.COM  */
4007836SJohn.Forte@Sun.COM typedef struct iscsi_cmd {
4017836SJohn.Forte@Sun.COM 	uint32_t		cmd_sig;
4027836SJohn.Forte@Sun.COM 	struct iscsi_cmd	*cmd_prev;
4037836SJohn.Forte@Sun.COM 	struct iscsi_cmd	*cmd_next;
4047836SJohn.Forte@Sun.COM 	struct iscsi_conn	*cmd_conn;
4057836SJohn.Forte@Sun.COM 
4067836SJohn.Forte@Sun.COM 	iscsi_cmd_type_t	cmd_type;
4077836SJohn.Forte@Sun.COM 	iscsi_cmd_state_t	cmd_state;
4087836SJohn.Forte@Sun.COM 	iscsi_cmd_state_t	cmd_prev_state;
4097836SJohn.Forte@Sun.COM 	clock_t			cmd_lbolt_pending;
4107836SJohn.Forte@Sun.COM 	clock_t			cmd_lbolt_active;
4117836SJohn.Forte@Sun.COM 	clock_t			cmd_lbolt_aborting;
4129162SPeter.Dunlap@Sun.COM 	clock_t			cmd_lbolt_idm_aborting;
4137836SJohn.Forte@Sun.COM 	clock_t			cmd_lbolt_timeout;
4148231SJack.Meng@Sun.COM 	uint8_t			cmd_misc_flags;
4159162SPeter.Dunlap@Sun.COM 	idm_task_t		*cmd_itp;
4167836SJohn.Forte@Sun.COM 
4177836SJohn.Forte@Sun.COM 	union {
4187836SJohn.Forte@Sun.COM 		/* ISCSI_CMD_TYPE_SCSI */
4197836SJohn.Forte@Sun.COM 		struct {
4209162SPeter.Dunlap@Sun.COM 			idm_buf_t		*ibp_ibuf;
4219162SPeter.Dunlap@Sun.COM 			idm_buf_t		*ibp_obuf;
4227836SJohn.Forte@Sun.COM 			struct scsi_pkt		*pkt;
4237836SJohn.Forte@Sun.COM 			struct buf		*bp;
4247836SJohn.Forte@Sun.COM 			int			cmdlen;
4257836SJohn.Forte@Sun.COM 			int			statuslen;
4267836SJohn.Forte@Sun.COM 			size_t			data_transferred;
4277836SJohn.Forte@Sun.COM 
4287836SJohn.Forte@Sun.COM 			uint32_t		lun;
4297836SJohn.Forte@Sun.COM 
4307836SJohn.Forte@Sun.COM 			/*
4317836SJohn.Forte@Sun.COM 			 * If SCSI_CMD_TYPE is in ABORTING_STATE
4327836SJohn.Forte@Sun.COM 			 * then the abort_icmdp field will be a pointer
4337836SJohn.Forte@Sun.COM 			 * to the abort command chasing this one.
4347836SJohn.Forte@Sun.COM 			 */
4357836SJohn.Forte@Sun.COM 			struct iscsi_cmd	*abort_icmdp;
4367836SJohn.Forte@Sun.COM 			/*
4377836SJohn.Forte@Sun.COM 			 * pointer to the r2t associated with this
4387836SJohn.Forte@Sun.COM 			 * command (if any)
4397836SJohn.Forte@Sun.COM 			 */
4407836SJohn.Forte@Sun.COM 			struct iscsi_cmd	*r2t_icmdp;
4418447SBing.Zhao@Sun.COM 			/*
4428447SBing.Zhao@Sun.COM 			 * It will be true if this command has
4438447SBing.Zhao@Sun.COM 			 * another R2T to handle.
4448447SBing.Zhao@Sun.COM 			 */
4458447SBing.Zhao@Sun.COM 			boolean_t		r2t_more;
4469780SBing.Zhao@Sun.COM 			/*
4479780SBing.Zhao@Sun.COM 			 * It is used to record pkt_statistics temporarily.
4489780SBing.Zhao@Sun.COM 			 */
4499780SBing.Zhao@Sun.COM 			uint_t			pkt_stat;
4507836SJohn.Forte@Sun.COM 		} scsi;
4517836SJohn.Forte@Sun.COM 		/* ISCSI_CMD_TYPE_ABORT */
4527836SJohn.Forte@Sun.COM 		struct {
4537836SJohn.Forte@Sun.COM 			/* pointer to original iscsi_cmd, for abort */
4547836SJohn.Forte@Sun.COM 			struct iscsi_cmd	*icmdp;
4557836SJohn.Forte@Sun.COM 		} abort;
4567836SJohn.Forte@Sun.COM 		/* ISCSI_CMD_TYPE_RESET */
4577836SJohn.Forte@Sun.COM 		struct {
4587836SJohn.Forte@Sun.COM 			int			level;
4599780SBing.Zhao@Sun.COM 			uint8_t			response;
4607836SJohn.Forte@Sun.COM 		} reset;
4617836SJohn.Forte@Sun.COM 		/* ISCSI_CMD_TYPE_NOP */
4627836SJohn.Forte@Sun.COM 		struct {
4637836SJohn.Forte@Sun.COM 			int rsvd;
4647836SJohn.Forte@Sun.COM 		} nop;
4657836SJohn.Forte@Sun.COM 		/* ISCSI_CMD_TYPE_R2T */
4667836SJohn.Forte@Sun.COM 		struct {
4677836SJohn.Forte@Sun.COM 			struct iscsi_cmd	*icmdp;
4687836SJohn.Forte@Sun.COM 			uint32_t		offset;
4697836SJohn.Forte@Sun.COM 			uint32_t		length;
4707836SJohn.Forte@Sun.COM 		} r2t;
4717836SJohn.Forte@Sun.COM 		/* ISCSI_CMD_TYPE_LOGIN */
4727836SJohn.Forte@Sun.COM 		struct {
4737836SJohn.Forte@Sun.COM 			int rvsd;
4747836SJohn.Forte@Sun.COM 		} login;
4757836SJohn.Forte@Sun.COM 		/* ISCSI_CMD_TYPE_LOGOUT */
4767836SJohn.Forte@Sun.COM 		struct {
4777836SJohn.Forte@Sun.COM 			int rsvd;
4787836SJohn.Forte@Sun.COM 		} logout;
4797836SJohn.Forte@Sun.COM 		/* ISCSI_CMD_TYPE_TEXT */
4807836SJohn.Forte@Sun.COM 		struct {
4817836SJohn.Forte@Sun.COM 			char			*buf;
4827836SJohn.Forte@Sun.COM 			int			buf_len;
4837836SJohn.Forte@Sun.COM 			uint32_t		offset;
4847836SJohn.Forte@Sun.COM 			uint32_t		data_len;
4857836SJohn.Forte@Sun.COM 			uint32_t		total_rx_len;
4867836SJohn.Forte@Sun.COM 			uint32_t		ttt;
4877836SJohn.Forte@Sun.COM 			uint8_t			lun[8];
4887836SJohn.Forte@Sun.COM 			iscsi_cmd_text_stage_t	stage;
4897836SJohn.Forte@Sun.COM 		} text;
4907836SJohn.Forte@Sun.COM 	} cmd_un;
4917836SJohn.Forte@Sun.COM 
4927836SJohn.Forte@Sun.COM 	struct iscsi_lun	*cmd_lun; /* associated lun */
4937836SJohn.Forte@Sun.COM 
4947836SJohn.Forte@Sun.COM 	uint32_t		cmd_itt;
4957836SJohn.Forte@Sun.COM 	uint32_t		cmd_ttt;
4967836SJohn.Forte@Sun.COM 
4977836SJohn.Forte@Sun.COM 	/*
4987836SJohn.Forte@Sun.COM 	 * If a data digest error is seem on a data pdu.  This flag
4997836SJohn.Forte@Sun.COM 	 * will get set.  We don't abort the cmd immediately because
5007836SJohn.Forte@Sun.COM 	 * we want to read in all the data to get it out of the
5017836SJohn.Forte@Sun.COM 	 * stream.  Once the completion for the cmd is received we
5027836SJohn.Forte@Sun.COM 	 * we will abort the cmd and state no sense data was available.
5037836SJohn.Forte@Sun.COM 	 */
5047836SJohn.Forte@Sun.COM 	boolean_t		cmd_crc_error_seen;
5057836SJohn.Forte@Sun.COM 
5067836SJohn.Forte@Sun.COM 	/*
5077836SJohn.Forte@Sun.COM 	 * Used to block and wake up caller until action is completed.
5087836SJohn.Forte@Sun.COM 	 * This is for ABORT, RESET, and PASSTHRU cmds.
5097836SJohn.Forte@Sun.COM 	 */
5107836SJohn.Forte@Sun.COM 	int			cmd_result;
5117836SJohn.Forte@Sun.COM 	int			cmd_completed;
5127836SJohn.Forte@Sun.COM 	kmutex_t		cmd_mutex;
5137836SJohn.Forte@Sun.COM 	kcondvar_t		cmd_completion;
5147836SJohn.Forte@Sun.COM 
5159162SPeter.Dunlap@Sun.COM 	idm_pdu_t		cmd_pdu;
5169162SPeter.Dunlap@Sun.COM 
5179162SPeter.Dunlap@Sun.COM 	sm_audit_buf_t		cmd_state_audit;
5189780SBing.Zhao@Sun.COM 
5199780SBing.Zhao@Sun.COM 	uint32_t		cmd_sn;
5207836SJohn.Forte@Sun.COM } iscsi_cmd_t;
5217836SJohn.Forte@Sun.COM 
5227836SJohn.Forte@Sun.COM 
5237836SJohn.Forte@Sun.COM /*
5247836SJohn.Forte@Sun.COM  * iSCSI LUN Structure
5257836SJohn.Forte@Sun.COM  */
5267836SJohn.Forte@Sun.COM typedef struct iscsi_lun {
5277836SJohn.Forte@Sun.COM 	uint32_t		lun_sig;
5287836SJohn.Forte@Sun.COM 	int			lun_state;
5297836SJohn.Forte@Sun.COM 
5307836SJohn.Forte@Sun.COM 	struct iscsi_lun	*lun_next;	/* next lun on this sess. */
5317836SJohn.Forte@Sun.COM 	struct iscsi_sess	*lun_sess;	/* parent sess. for lun */
5327836SJohn.Forte@Sun.COM 	dev_info_t		*lun_dip;
5337836SJohn.Forte@Sun.COM 	mdi_pathinfo_t		*lun_pip;
5347836SJohn.Forte@Sun.COM 
5357836SJohn.Forte@Sun.COM 	uint16_t		lun_num;	/* LUN */
5367836SJohn.Forte@Sun.COM 	uint8_t			lun_addr_type;	/* LUN addressing type */
5377836SJohn.Forte@Sun.COM 	uint32_t		lun_oid;	/* OID */
5387836SJohn.Forte@Sun.COM 	char			*lun_guid;	/* GUID */
5397836SJohn.Forte@Sun.COM 	int			lun_guid_size;	/* GUID allocation size */
5407836SJohn.Forte@Sun.COM 	char			*lun_addr;	/* sess,lun */
5417836SJohn.Forte@Sun.COM 	time_t			lun_time_online;
5427836SJohn.Forte@Sun.COM 
5437836SJohn.Forte@Sun.COM 	uchar_t			lun_cap;	/* bitmap of scsi caps */
5447836SJohn.Forte@Sun.COM 
5457836SJohn.Forte@Sun.COM 	uchar_t			lun_vid[ISCSI_INQ_VID_BUF_LEN];	/* Vendor ID */
5467836SJohn.Forte@Sun.COM 	uchar_t			lun_pid[ISCSI_INQ_PID_BUF_LEN];	/* Product ID */
5479371SBing.Zhao@Sun.COM 
5489371SBing.Zhao@Sun.COM 	uchar_t			lun_type;
5497836SJohn.Forte@Sun.COM } iscsi_lun_t;
5507836SJohn.Forte@Sun.COM 
5519780SBing.Zhao@Sun.COM #define	ISCSI_LUN_STATE_CLEAR	    0		/* used to clear all states */
5529780SBing.Zhao@Sun.COM #define	ISCSI_LUN_STATE_OFFLINE	    1
5539780SBing.Zhao@Sun.COM #define	ISCSI_LUN_STATE_ONLINE	    2
5549780SBing.Zhao@Sun.COM #define	ISCSI_LUN_STATE_INVALID	    4		/* offline failed */
5559780SBing.Zhao@Sun.COM #define	ISCSI_LUN_STATE_BUSY	    8		/* logic unit is in reset */
5567836SJohn.Forte@Sun.COM 
5579780SBing.Zhao@Sun.COM #define	ISCSI_LUN_CAP_RESET	    0x01
5589780SBing.Zhao@Sun.COM 
5599780SBing.Zhao@Sun.COM #define	ISCSI_SCSI_RESET_SENSE_CODE 0x29
560*12161SJack.Meng@Sun.COM #define	ISCSI_SCSI_LUNCHANGED_CODE	0x3f
561*12161SJack.Meng@Sun.COM 
562*12161SJack.Meng@Sun.COM #define	ISCSI_SCSI_LUNCHANGED_ASCQ	0x0e
5637836SJohn.Forte@Sun.COM 
5647836SJohn.Forte@Sun.COM /*
5657836SJohn.Forte@Sun.COM  *
5667836SJohn.Forte@Sun.COM  *
5677836SJohn.Forte@Sun.COM  */
5687836SJohn.Forte@Sun.COM typedef struct iscsi_queue {
5697836SJohn.Forte@Sun.COM 	iscsi_cmd_t	*head;
5707836SJohn.Forte@Sun.COM 	iscsi_cmd_t	*tail;
5717836SJohn.Forte@Sun.COM 	int		count;
5727836SJohn.Forte@Sun.COM 	kmutex_t	mutex;
5737836SJohn.Forte@Sun.COM } iscsi_queue_t;
5747836SJohn.Forte@Sun.COM 
5757836SJohn.Forte@Sun.COM #define	ISCSI_CONN_DEFAULT_LOGIN_MIN		0
5767836SJohn.Forte@Sun.COM #define	ISCSI_CONN_DEFAULT_LOGIN_REDIRECT	10
5777836SJohn.Forte@Sun.COM 
57810156SZhang.Yi@Sun.COM /* iSCSI tunable Parameters */
57910156SZhang.Yi@Sun.COM typedef struct iscsi_tunable_params {
58010156SZhang.Yi@Sun.COM 	int		recv_login_rsp_timeout;	/* range: 0 - 60*60 */
58110156SZhang.Yi@Sun.COM 	int		conn_login_max;		/* range: 0 - 60*60 */
58210156SZhang.Yi@Sun.COM 	int		polling_login_delay;	/* range: 0 - 60*60 */
58310156SZhang.Yi@Sun.COM } iscsi_tunable_params_t;
58410156SZhang.Yi@Sun.COM 
5857836SJohn.Forte@Sun.COM typedef union iscsi_sockaddr {
5867836SJohn.Forte@Sun.COM 	struct sockaddr		sin;
5877836SJohn.Forte@Sun.COM 	struct sockaddr_in	sin4;
5887836SJohn.Forte@Sun.COM 	struct sockaddr_in6	sin6;
5897836SJohn.Forte@Sun.COM } iscsi_sockaddr_t;
5907836SJohn.Forte@Sun.COM 
5917836SJohn.Forte@Sun.COM #define	SIZEOF_SOCKADDR(so)	((so)->sa_family == AF_INET ? \
5927836SJohn.Forte@Sun.COM 	sizeof (struct sockaddr_in) : sizeof (struct sockaddr_in6))
5937836SJohn.Forte@Sun.COM 
5949162SPeter.Dunlap@Sun.COM typedef enum {
5959162SPeter.Dunlap@Sun.COM 	LOGIN_START,
5969162SPeter.Dunlap@Sun.COM 	LOGIN_READY,
5979162SPeter.Dunlap@Sun.COM 	LOGIN_TX,
5989162SPeter.Dunlap@Sun.COM 	LOGIN_RX,
5999162SPeter.Dunlap@Sun.COM 	LOGIN_ERROR,
6009162SPeter.Dunlap@Sun.COM 	LOGIN_DONE,
6019162SPeter.Dunlap@Sun.COM 	LOGIN_FFP,
6029162SPeter.Dunlap@Sun.COM 	LOGIN_MAX
6039162SPeter.Dunlap@Sun.COM } iscsi_login_state_t;
6049162SPeter.Dunlap@Sun.COM 
6059162SPeter.Dunlap@Sun.COM #ifdef ISCSI_LOGIN_STATE_NAMES
6069162SPeter.Dunlap@Sun.COM static const char *iscsi_login_state_names[LOGIN_MAX+1] = {
6079162SPeter.Dunlap@Sun.COM 	"LOGIN_START",
6089162SPeter.Dunlap@Sun.COM 	"LOGIN_READY",
6099162SPeter.Dunlap@Sun.COM 	"LOGIN_TX",
6109162SPeter.Dunlap@Sun.COM 	"LOGIN_RX",
6119162SPeter.Dunlap@Sun.COM 	"LOGIN_ERROR",
6129162SPeter.Dunlap@Sun.COM 	"LOGIN_DONE",
6139162SPeter.Dunlap@Sun.COM 	"LOGIN_FFP",
6149162SPeter.Dunlap@Sun.COM 	"LOGIN_MAX"
6159162SPeter.Dunlap@Sun.COM };
6169162SPeter.Dunlap@Sun.COM #endif
6179162SPeter.Dunlap@Sun.COM 
6189162SPeter.Dunlap@Sun.COM /*
6199162SPeter.Dunlap@Sun.COM  * iscsi_conn_state
6209162SPeter.Dunlap@Sun.COM  */
6219162SPeter.Dunlap@Sun.COM typedef enum iscsi_conn_state {
6229162SPeter.Dunlap@Sun.COM 	ISCSI_CONN_STATE_UNDEFINED = 0,
6239162SPeter.Dunlap@Sun.COM 	ISCSI_CONN_STATE_FREE,
6249162SPeter.Dunlap@Sun.COM 	ISCSI_CONN_STATE_IN_LOGIN,
6259162SPeter.Dunlap@Sun.COM 	ISCSI_CONN_STATE_LOGGED_IN,
6269162SPeter.Dunlap@Sun.COM 	ISCSI_CONN_STATE_IN_LOGOUT,
6279162SPeter.Dunlap@Sun.COM 	ISCSI_CONN_STATE_FAILED,
6289162SPeter.Dunlap@Sun.COM 	ISCSI_CONN_STATE_POLLING,
6299162SPeter.Dunlap@Sun.COM 	ISCSI_CONN_STATE_MAX
6309162SPeter.Dunlap@Sun.COM } iscsi_conn_state_t;
6319162SPeter.Dunlap@Sun.COM 
6329162SPeter.Dunlap@Sun.COM #ifdef ISCSI_ICS_NAMES
6339162SPeter.Dunlap@Sun.COM static const char *iscsi_ics_name[ISCSI_CONN_STATE_MAX+1] = {
6349162SPeter.Dunlap@Sun.COM 	"ISCSI_CONN_STATE_UNDEFINED",
6359162SPeter.Dunlap@Sun.COM 	"ISCSI_CONN_STATE_FREE",
6369162SPeter.Dunlap@Sun.COM 	"ISCSI_CONN_STATE_IN_LOGIN",
6379162SPeter.Dunlap@Sun.COM 	"ISCSI_CONN_STATE_LOGGED_IN",
6389162SPeter.Dunlap@Sun.COM 	"ISCSI_CONN_STATE_IN_LOGOUT",
6399162SPeter.Dunlap@Sun.COM 	"ISCSI_CONN_STATE_FAILED",
6409162SPeter.Dunlap@Sun.COM 	"ISCSI_CONN_STATE_POLLING",
6419162SPeter.Dunlap@Sun.COM 	"ISCSI_CONN_STATE_MAX"
6429162SPeter.Dunlap@Sun.COM };
6439162SPeter.Dunlap@Sun.COM #endif
6449162SPeter.Dunlap@Sun.COM 
6459162SPeter.Dunlap@Sun.COM #define	ISCSI_CONN_STATE_FULL_FEATURE(state) \
6469162SPeter.Dunlap@Sun.COM 	((state == ISCSI_CONN_STATE_LOGGED_IN) || \
6479162SPeter.Dunlap@Sun.COM 	(state == ISCSI_CONN_STATE_IN_LOGOUT))
6489162SPeter.Dunlap@Sun.COM 
6497836SJohn.Forte@Sun.COM /*
6507836SJohn.Forte@Sun.COM  * iSCSI Connection Structure
6517836SJohn.Forte@Sun.COM  */
6527836SJohn.Forte@Sun.COM typedef struct iscsi_conn {
6537836SJohn.Forte@Sun.COM 	uint32_t		conn_sig;
6547836SJohn.Forte@Sun.COM 	struct iscsi_conn	*conn_next;	/* next conn on this sess. */
6557836SJohn.Forte@Sun.COM 	struct iscsi_sess	*conn_sess;	/* parent sess. for conn. */
6567836SJohn.Forte@Sun.COM 
6577836SJohn.Forte@Sun.COM 	iscsi_conn_state_t	conn_state;	/* cur. conn. driver state */
6587836SJohn.Forte@Sun.COM 	iscsi_conn_state_t	conn_prev_state; /* prev. conn. driver state */
6597836SJohn.Forte@Sun.COM 	/* protects the session state and synchronizes the state machine */
6607836SJohn.Forte@Sun.COM 	kmutex_t		conn_state_mutex;
6617836SJohn.Forte@Sun.COM 	kcondvar_t		conn_state_change;
6627836SJohn.Forte@Sun.COM 	boolean_t		conn_state_destroy;
6639162SPeter.Dunlap@Sun.COM 	boolean_t		conn_state_ffp;
6649162SPeter.Dunlap@Sun.COM 	boolean_t		conn_state_idm_connected;
6659162SPeter.Dunlap@Sun.COM 	boolean_t		conn_async_logout;
6669162SPeter.Dunlap@Sun.COM 	ddi_taskq_t		*conn_cn_taskq;
6677836SJohn.Forte@Sun.COM 
6689162SPeter.Dunlap@Sun.COM 	idm_conn_t		*conn_ic;
6697836SJohn.Forte@Sun.COM 
6709162SPeter.Dunlap@Sun.COM 	/* base connection information, may have been redirected */
6717836SJohn.Forte@Sun.COM 	iscsi_sockaddr_t	conn_base_addr;
6727836SJohn.Forte@Sun.COM 
6737836SJohn.Forte@Sun.COM 	/* current connection information, may have been redirected */
6747836SJohn.Forte@Sun.COM 	iscsi_sockaddr_t	conn_curr_addr;
6757836SJohn.Forte@Sun.COM 
6767836SJohn.Forte@Sun.COM 	boolean_t		conn_bound;
6777836SJohn.Forte@Sun.COM 	iscsi_sockaddr_t	conn_bound_addr;
6787836SJohn.Forte@Sun.COM 
6797836SJohn.Forte@Sun.COM 	uint32_t		conn_cid;	/* CID */
6807836SJohn.Forte@Sun.COM 	uint32_t		conn_oid;	/* OID */
6817836SJohn.Forte@Sun.COM 
6827836SJohn.Forte@Sun.COM 	int			conn_current_stage;	/* iSCSI login stage */
6837836SJohn.Forte@Sun.COM 	int			conn_next_stage;	/* iSCSI login stage */
6847836SJohn.Forte@Sun.COM 	int			conn_partial_response;
6857836SJohn.Forte@Sun.COM 
6867836SJohn.Forte@Sun.COM 	/*
6877836SJohn.Forte@Sun.COM 	 * The active queue contains iscsi_cmds that have already
6887836SJohn.Forte@Sun.COM 	 * been sent on this connection.  Any future responses to
6897836SJohn.Forte@Sun.COM 	 * these cmds require alligence to this connection.  If there
6907836SJohn.Forte@Sun.COM 	 * are issues with these cmds the command may need aborted
6917836SJohn.Forte@Sun.COM 	 * depending on the command type, and must be put back into
6927836SJohn.Forte@Sun.COM 	 * the session's pending queue or aborted.
6937836SJohn.Forte@Sun.COM 	 */
6947836SJohn.Forte@Sun.COM 	iscsi_queue_t		conn_queue_active;
6959162SPeter.Dunlap@Sun.COM 	iscsi_queue_t		conn_queue_idm_aborting;
6967836SJohn.Forte@Sun.COM 
6977836SJohn.Forte@Sun.COM 	/* lbolt from the last receive, used for nop processing */
6987836SJohn.Forte@Sun.COM 	clock_t			conn_rx_lbolt;
6997836SJohn.Forte@Sun.COM 	clock_t			conn_nop_lbolt;
7007836SJohn.Forte@Sun.COM 
7017836SJohn.Forte@Sun.COM 	iscsi_thread_t		*conn_tx_thread;
7027836SJohn.Forte@Sun.COM 
7037836SJohn.Forte@Sun.COM 	/*
7047836SJohn.Forte@Sun.COM 	 * The expstatsn is the command status sn that is expected
7057836SJohn.Forte@Sun.COM 	 * next from the target.  Command status is carried on a number
7067836SJohn.Forte@Sun.COM 	 * of iSCSI PDUs (ex.  SCSI Cmd Response, SCSI Data IN with
7077836SJohn.Forte@Sun.COM 	 * S-Bit set, ...), not all PDUs.  If our expstatsn is different
7087836SJohn.Forte@Sun.COM 	 * than the received statsn.  Something got out of sync we need to
7097836SJohn.Forte@Sun.COM 	 * recover.
7107836SJohn.Forte@Sun.COM 	 */
7117836SJohn.Forte@Sun.COM 	uint32_t		conn_expstatsn;
7127836SJohn.Forte@Sun.COM 	uint32_t		conn_laststatsn;
7137836SJohn.Forte@Sun.COM 
7147836SJohn.Forte@Sun.COM 	/* active login parameters */
7157836SJohn.Forte@Sun.COM 	iscsi_login_params_t	conn_params;
7167836SJohn.Forte@Sun.COM 
7177836SJohn.Forte@Sun.COM 	/* Statistics */
7187836SJohn.Forte@Sun.COM 	struct {
7197836SJohn.Forte@Sun.COM 		kstat_t			*ks;
7207836SJohn.Forte@Sun.COM 		iscsi_conn_stats_t	ks_data;
7217836SJohn.Forte@Sun.COM 	} stats;
7227836SJohn.Forte@Sun.COM 
7237836SJohn.Forte@Sun.COM 	/*
7249162SPeter.Dunlap@Sun.COM 	 * These fields are used to coordinate the asynchronous IDM
7259162SPeter.Dunlap@Sun.COM 	 * PDU operations with the synchronous login code.
7269162SPeter.Dunlap@Sun.COM 	 */
7279162SPeter.Dunlap@Sun.COM 	kmutex_t		conn_login_mutex;
7289162SPeter.Dunlap@Sun.COM 	kcondvar_t		conn_login_cv;
7299162SPeter.Dunlap@Sun.COM 	iscsi_login_state_t	conn_login_state;
7309162SPeter.Dunlap@Sun.COM 	iscsi_status_t		conn_login_status;
7319162SPeter.Dunlap@Sun.COM 	iscsi_hdr_t		conn_login_resp_hdr;
7329162SPeter.Dunlap@Sun.COM 	char			*conn_login_data;
7339162SPeter.Dunlap@Sun.COM 	int			conn_login_datalen;
7349162SPeter.Dunlap@Sun.COM 	int			conn_login_max_data_length;
7359162SPeter.Dunlap@Sun.COM 
7369162SPeter.Dunlap@Sun.COM 	/*
7377836SJohn.Forte@Sun.COM 	 * login min and max identify the amount of time
7387836SJohn.Forte@Sun.COM 	 * in lbolt that iscsi_start_login() should attempt
7397836SJohn.Forte@Sun.COM 	 * to log into a target portal.  The login will
7407836SJohn.Forte@Sun.COM 	 * delay until the min lbolt has been reached and
7417836SJohn.Forte@Sun.COM 	 * will end once max time has been reached.  These
7427836SJohn.Forte@Sun.COM 	 * values are normally set to the default but can
7437836SJohn.Forte@Sun.COM 	 * are also altered by async commands received from
7447836SJohn.Forte@Sun.COM 	 * the targetlogin.
7457836SJohn.Forte@Sun.COM 	 */
7467836SJohn.Forte@Sun.COM 	clock_t			conn_login_min;
7477836SJohn.Forte@Sun.COM 	clock_t			conn_login_max;
7489162SPeter.Dunlap@Sun.COM 	sm_audit_buf_t		conn_state_audit;
74910156SZhang.Yi@Sun.COM 
75010156SZhang.Yi@Sun.COM 	/* active tunable parameters */
75110156SZhang.Yi@Sun.COM 	iscsi_tunable_params_t	conn_tunable_params;
75210156SZhang.Yi@Sun.COM 	boolean_t		conn_timeout;
7537836SJohn.Forte@Sun.COM } iscsi_conn_t;
7547836SJohn.Forte@Sun.COM 
7557836SJohn.Forte@Sun.COM 
7567836SJohn.Forte@Sun.COM /*
7579162SPeter.Dunlap@Sun.COM  * iscsi_sess_state - (reference iscsi_sess.c for state diagram)
7587836SJohn.Forte@Sun.COM  */
7597836SJohn.Forte@Sun.COM typedef enum iscsi_sess_state {
7609162SPeter.Dunlap@Sun.COM 	ISCSI_SESS_STATE_FREE = 0,
7617836SJohn.Forte@Sun.COM 	ISCSI_SESS_STATE_LOGGED_IN,
7627836SJohn.Forte@Sun.COM 	ISCSI_SESS_STATE_FAILED,
7637836SJohn.Forte@Sun.COM 	ISCSI_SESS_STATE_IN_FLUSH,
7649162SPeter.Dunlap@Sun.COM 	ISCSI_SESS_STATE_FLUSHED,
7659162SPeter.Dunlap@Sun.COM 	ISCSI_SESS_STATE_MAX
7667836SJohn.Forte@Sun.COM } iscsi_sess_state_t;
7677836SJohn.Forte@Sun.COM 
7689162SPeter.Dunlap@Sun.COM #ifdef ISCSI_SESS_SM_STRINGS
7699162SPeter.Dunlap@Sun.COM static const char *iscsi_sess_state_names[ISCSI_SESS_STATE_MAX+1] = {
7709162SPeter.Dunlap@Sun.COM 	"ISCSI_SESS_STATE_FREE",
7719162SPeter.Dunlap@Sun.COM 	"ISCSI_SESS_STATE_LOGGED_IN",
7729162SPeter.Dunlap@Sun.COM 	"ISCSI_SESS_STATE_FAILED",
7739162SPeter.Dunlap@Sun.COM 	"ISCSI_SESS_STATE_IN_FLUSH",
7749162SPeter.Dunlap@Sun.COM 	"ISCSI_SESS_STATE_FLUSHED",
7759162SPeter.Dunlap@Sun.COM 	"ISCSI_SESS_STATE_MAX"
7769162SPeter.Dunlap@Sun.COM };
7779162SPeter.Dunlap@Sun.COM #endif
7789162SPeter.Dunlap@Sun.COM 
7797836SJohn.Forte@Sun.COM #define	ISCSI_SESS_STATE_FULL_FEATURE(state) \
7807836SJohn.Forte@Sun.COM 	((state == ISCSI_SESS_STATE_LOGGED_IN) || \
7817836SJohn.Forte@Sun.COM 	(state == ISCSI_SESS_STATE_IN_FLUSH))
7827836SJohn.Forte@Sun.COM 
7837836SJohn.Forte@Sun.COM 
7847836SJohn.Forte@Sun.COM typedef enum iscsi_sess_event {
7859162SPeter.Dunlap@Sun.COM 	ISCSI_SESS_EVENT_N1 = 0,
7867836SJohn.Forte@Sun.COM 	ISCSI_SESS_EVENT_N3,
7877836SJohn.Forte@Sun.COM 	ISCSI_SESS_EVENT_N5,
7887836SJohn.Forte@Sun.COM 	ISCSI_SESS_EVENT_N6,
7899162SPeter.Dunlap@Sun.COM 	ISCSI_SESS_EVENT_N7,
7909162SPeter.Dunlap@Sun.COM 	ISCSI_SESS_EVENT_MAX
7917836SJohn.Forte@Sun.COM } iscsi_sess_event_t;
7927836SJohn.Forte@Sun.COM 
7939162SPeter.Dunlap@Sun.COM #ifdef ISCSI_SESS_SM_STRINGS
7949162SPeter.Dunlap@Sun.COM static const char *iscsi_sess_event_names[ISCSI_SESS_EVENT_MAX+1] = {
7959162SPeter.Dunlap@Sun.COM 	"ISCSI_SESS_EVENT_N1",
7969162SPeter.Dunlap@Sun.COM 	"ISCSI_SESS_EVENT_N3",
7979162SPeter.Dunlap@Sun.COM 	"ISCSI_SESS_EVENT_N5",
7989162SPeter.Dunlap@Sun.COM 	"ISCSI_SESS_EVENT_N6",
7999162SPeter.Dunlap@Sun.COM 	"ISCSI_SESS_EVENT_N7",
8009162SPeter.Dunlap@Sun.COM 	"ISCSI_SESS_EVENT_MAX"
8019162SPeter.Dunlap@Sun.COM };
8029162SPeter.Dunlap@Sun.COM #endif
8039162SPeter.Dunlap@Sun.COM 
8047836SJohn.Forte@Sun.COM typedef enum iscsi_sess_type {
8059162SPeter.Dunlap@Sun.COM 	ISCSI_SESS_TYPE_NORMAL = 0,
8067836SJohn.Forte@Sun.COM 	ISCSI_SESS_TYPE_DISCOVERY
8077836SJohn.Forte@Sun.COM } iscsi_sess_type_t;
8087836SJohn.Forte@Sun.COM 
8097836SJohn.Forte@Sun.COM #define	SESS_ABORT_TASK_MAX_THREADS	1
8107836SJohn.Forte@Sun.COM 
8117836SJohn.Forte@Sun.COM /* Sun's initiator session ID */
8127836SJohn.Forte@Sun.COM #define	ISCSI_SUN_ISID_0    0x40    /* ISID - EN format */
8137836SJohn.Forte@Sun.COM #define	ISCSI_SUN_ISID_1    0x00    /* Sec B */
8147836SJohn.Forte@Sun.COM #define	ISCSI_SUN_ISID_2    0x00    /* Sec B */
8157836SJohn.Forte@Sun.COM #define	ISCSI_SUN_ISID_3    0x2A    /* Sec C - 42 = Sun's EN */
8167836SJohn.Forte@Sun.COM /*
8177836SJohn.Forte@Sun.COM  * defines 4-5 are the reserved values.  These reserved values
8187836SJohn.Forte@Sun.COM  * are used as the ISID for an initiator-port in MP-API and used
8197836SJohn.Forte@Sun.COM  * for the send targets discovery sessions.  Byte 5 is overridden
8207836SJohn.Forte@Sun.COM  * for full feature sessions.  The default values of byte 5 for a
8217836SJohn.Forte@Sun.COM  * full feature session is 0.  When MS/T is enabled with more than
8227836SJohn.Forte@Sun.COM  * one session this byte 5 will increment > 0 up to
8237836SJohn.Forte@Sun.COM  * ISCSI_MAX_CONFIG_SESSIONS.
8247836SJohn.Forte@Sun.COM  */
8257836SJohn.Forte@Sun.COM #define	ISCSI_SUN_ISID_4    0x00
8267836SJohn.Forte@Sun.COM #define	ISCSI_SUN_ISID_5    0xFF
8277836SJohn.Forte@Sun.COM 
8287836SJohn.Forte@Sun.COM #define	ISCSI_DEFAULT_SESS_BOUND	B_FALSE
8297836SJohn.Forte@Sun.COM #define	ISCSI_DEFAULT_SESS_NUM		1
8307836SJohn.Forte@Sun.COM 
831*12161SJack.Meng@Sun.COM typedef enum iscsi_enum_status {
832*12161SJack.Meng@Sun.COM 	ISCSI_SESS_ENUM_FREE		=	0,
833*12161SJack.Meng@Sun.COM 	ISCSI_SESS_ENUM_INPROG,
834*12161SJack.Meng@Sun.COM 	ISCSI_SESS_ENUM_DONE
835*12161SJack.Meng@Sun.COM } iscsi_enum_status_t;
836*12161SJack.Meng@Sun.COM 
837*12161SJack.Meng@Sun.COM typedef enum iscsi_enum_result {
838*12161SJack.Meng@Sun.COM 	ISCSI_SESS_ENUM_COMPLETE	=	0,
839*12161SJack.Meng@Sun.COM 	ISCSI_SESS_ENUM_PARTIAL,
840*12161SJack.Meng@Sun.COM 	ISCSI_SESS_ENUM_IOFAIL,
841*12161SJack.Meng@Sun.COM 	ISCSI_SESS_ENUM_SUBMITTED,
842*12161SJack.Meng@Sun.COM 	ISCSI_SESS_ENUM_SUBFAIL,
843*12161SJack.Meng@Sun.COM 	ISCSI_SESS_ENUM_GONE,
844*12161SJack.Meng@Sun.COM 	ISCSI_SESS_ENUM_TUR_FAIL
845*12161SJack.Meng@Sun.COM } iscsi_enum_result_t;
846*12161SJack.Meng@Sun.COM 
8477836SJohn.Forte@Sun.COM /*
8487836SJohn.Forte@Sun.COM  * iSCSI Session(Target) Structure
8497836SJohn.Forte@Sun.COM  */
8507836SJohn.Forte@Sun.COM typedef struct iscsi_sess {
8517836SJohn.Forte@Sun.COM 	uint32_t		sess_sig;
8527836SJohn.Forte@Sun.COM 
8537836SJohn.Forte@Sun.COM 	iscsi_sess_state_t	sess_state;
8547836SJohn.Forte@Sun.COM 	iscsi_sess_state_t	sess_prev_state;
8557836SJohn.Forte@Sun.COM 	clock_t			sess_state_lbolt;
8567836SJohn.Forte@Sun.COM 	/* protects the session state and synchronizes the state machine */
857*12161SJack.Meng@Sun.COM 	krwlock_t		sess_state_rwlock;
8587836SJohn.Forte@Sun.COM 
8597836SJohn.Forte@Sun.COM 	/*
8607836SJohn.Forte@Sun.COM 	 * Associated target OID.
8617836SJohn.Forte@Sun.COM 	 */
8627836SJohn.Forte@Sun.COM 	uint32_t		sess_target_oid;
8637836SJohn.Forte@Sun.COM 
8647836SJohn.Forte@Sun.COM 	/*
8657836SJohn.Forte@Sun.COM 	 * Session OID.  Used by IMA, interfaces and exported as
8667836SJohn.Forte@Sun.COM 	 * TARGET_PROP which is checked by the NDI.  In addition
8677836SJohn.Forte@Sun.COM 	 * this is used in our tran_lun_init function.
8687836SJohn.Forte@Sun.COM 	 */
8697836SJohn.Forte@Sun.COM 	uint32_t		sess_oid;
8707836SJohn.Forte@Sun.COM 
8717836SJohn.Forte@Sun.COM 	struct iscsi_sess	*sess_next;
8727836SJohn.Forte@Sun.COM 	struct iscsi_hba	*sess_hba;
8737836SJohn.Forte@Sun.COM 
8747836SJohn.Forte@Sun.COM 	/* list of all luns relating to session */
8757836SJohn.Forte@Sun.COM 	struct iscsi_lun	*sess_lun_list;
8767836SJohn.Forte@Sun.COM 	krwlock_t		sess_lun_list_rwlock;
8777836SJohn.Forte@Sun.COM 
8787836SJohn.Forte@Sun.COM 	/* list of all connections relating to session */
8797836SJohn.Forte@Sun.COM 	struct iscsi_conn	*sess_conn_list;
8807836SJohn.Forte@Sun.COM 	struct iscsi_conn	*sess_conn_list_last_ptr;
8817836SJohn.Forte@Sun.COM 	/* pointer to active connection in session */
8827836SJohn.Forte@Sun.COM 	struct iscsi_conn	*sess_conn_act;
8837836SJohn.Forte@Sun.COM 	krwlock_t		sess_conn_list_rwlock;
8847836SJohn.Forte@Sun.COM 
8857836SJohn.Forte@Sun.COM 	/* Connection ID for next connection to be added to session */
8867836SJohn.Forte@Sun.COM 	uint32_t		sess_conn_next_cid;
8877836SJohn.Forte@Sun.COM 
8887836SJohn.Forte@Sun.COM 	/*
8897836SJohn.Forte@Sun.COM 	 * last time any connection on this session received
8907836SJohn.Forte@Sun.COM 	 * data from the target.
8917836SJohn.Forte@Sun.COM 	 */
8927836SJohn.Forte@Sun.COM 	clock_t			sess_rx_lbolt;
8937836SJohn.Forte@Sun.COM 
8947836SJohn.Forte@Sun.COM 	clock_t			sess_failure_lbolt;
8957836SJohn.Forte@Sun.COM 
8967836SJohn.Forte@Sun.COM 	int			sess_storm_delay;
8977836SJohn.Forte@Sun.COM 
8987836SJohn.Forte@Sun.COM 	/*
8997836SJohn.Forte@Sun.COM 	 * sess_cmdsn_mutex protects the cmdsn and itt table/values
9007836SJohn.Forte@Sun.COM 	 * Cmdsn isn't that big of a problem yet since we only have
9017836SJohn.Forte@Sun.COM 	 * one connection but in the future we will need to ensure
9027836SJohn.Forte@Sun.COM 	 * this locking is working so keep the sequence numbers in
9037836SJohn.Forte@Sun.COM 	 * sync on the wire.
9047836SJohn.Forte@Sun.COM 	 *
9057836SJohn.Forte@Sun.COM 	 * We also use this lock to protect the ITT table and it's
9067836SJohn.Forte@Sun.COM 	 * values.  We need to make sure someone doesn't assign
9077836SJohn.Forte@Sun.COM 	 * a duplicate ITT value or cell to a command.  Also we
9087836SJohn.Forte@Sun.COM 	 * need to make sure when someone is looking up an ITT
9097836SJohn.Forte@Sun.COM 	 * that the command is still in that correct queue location.
9107836SJohn.Forte@Sun.COM 	 */
9117836SJohn.Forte@Sun.COM 	kmutex_t		sess_cmdsn_mutex;
9127836SJohn.Forte@Sun.COM 
9137836SJohn.Forte@Sun.COM 	/*
9147836SJohn.Forte@Sun.COM 	 * iSCSI command sequencing / windowing.  The next
9157836SJohn.Forte@Sun.COM 	 * command to be sent via the pending queue will
9167836SJohn.Forte@Sun.COM 	 * get the sess_cmdsn.  If the maxcmdsn is less
9177836SJohn.Forte@Sun.COM 	 * than the next cmdsn then the iSCSI window is
9187836SJohn.Forte@Sun.COM 	 * closed and this command cannot be sent yet.
9197836SJohn.Forte@Sun.COM 	 * Most iscsi cmd responses from the target carry
9207836SJohn.Forte@Sun.COM 	 * a new maxcmdsn.  If this new maxcmdsn is greater
9217836SJohn.Forte@Sun.COM 	 * than the sess_maxcmdsn we will update it's value
9227836SJohn.Forte@Sun.COM 	 * and set a timer to fire in one tick and reprocess
9237836SJohn.Forte@Sun.COM 	 * the pending queue.
9247836SJohn.Forte@Sun.COM 	 *
9257836SJohn.Forte@Sun.COM 	 * The expcmdsn.   Is the value the target expects
9267836SJohn.Forte@Sun.COM 	 * to be sent for my next cmdsn.  If the expcmdsn
9277836SJohn.Forte@Sun.COM 	 * and the cmdsn get out of sync this could denote
9287836SJohn.Forte@Sun.COM 	 * a communication problem.
9297836SJohn.Forte@Sun.COM 	 */
9307836SJohn.Forte@Sun.COM 	uint32_t		sess_cmdsn;
9317836SJohn.Forte@Sun.COM 	uint32_t		sess_expcmdsn;
9327836SJohn.Forte@Sun.COM 	uint32_t		sess_maxcmdsn;
9337836SJohn.Forte@Sun.COM 
9347836SJohn.Forte@Sun.COM 	/* Next Initiator Task Tag (ITT) to use */
9357836SJohn.Forte@Sun.COM 	uint32_t		sess_itt;
9367836SJohn.Forte@Sun.COM 	/*
9377836SJohn.Forte@Sun.COM 	 * The session iscsi_cmd table is used to a fast performance
9387836SJohn.Forte@Sun.COM 	 * lookup of an ITT to a iscsi_cmd when we receive an iSCSI
9397836SJohn.Forte@Sun.COM 	 * PDU from the wire.  To reserve a location in the sess_cmd_table
9407836SJohn.Forte@Sun.COM 	 * we try the sess_itt % ISCSI_CMD_TABLE_SIZE if this cmd table
9417836SJohn.Forte@Sun.COM 	 * cell is already full.  Then increament the sess_itt and
9427836SJohn.Forte@Sun.COM 	 * try to get the cell position again, repeat until an empty
9437836SJohn.Forte@Sun.COM 	 * cell is found.  Once an empty cell is found place your
9447836SJohn.Forte@Sun.COM 	 * scsi_cmd point into the cell to reserve the location.  This
9457836SJohn.Forte@Sun.COM 	 * selection process should be done while holding the session's
9467836SJohn.Forte@Sun.COM 	 * mutex.
9477836SJohn.Forte@Sun.COM 	 */
9487836SJohn.Forte@Sun.COM 	struct iscsi_cmd	*sess_cmd_table[ISCSI_CMD_TABLE_SIZE];
9497836SJohn.Forte@Sun.COM 	int			sess_cmd_table_count;
9507836SJohn.Forte@Sun.COM 
9517836SJohn.Forte@Sun.COM 	/*
9527836SJohn.Forte@Sun.COM 	 * The pending queue contains all iscsi_cmds that require an
9537836SJohn.Forte@Sun.COM 	 * open MaxCmdSn window to be put on the wire and haven't
9547836SJohn.Forte@Sun.COM 	 * been placed on the wire.  Once placed on the wire they
9557836SJohn.Forte@Sun.COM 	 * will be moved to a connections specific active queue.
9567836SJohn.Forte@Sun.COM 	 */
9577836SJohn.Forte@Sun.COM 	iscsi_queue_t		sess_queue_pending;
9587836SJohn.Forte@Sun.COM 
9597836SJohn.Forte@Sun.COM 	iscsi_error_t		sess_last_err;
9607836SJohn.Forte@Sun.COM 
9617836SJohn.Forte@Sun.COM 	iscsi_queue_t		sess_queue_completion;
9627836SJohn.Forte@Sun.COM 	/* configured login parameters */
9637836SJohn.Forte@Sun.COM 	iscsi_login_params_t	sess_params;
9647836SJohn.Forte@Sun.COM 
9657836SJohn.Forte@Sun.COM 	/* general iSCSI protocol/session info */
9667836SJohn.Forte@Sun.COM 	uchar_t			sess_name[ISCSI_MAX_NAME_LEN];
9677836SJohn.Forte@Sun.COM 	int			sess_name_length;
9687836SJohn.Forte@Sun.COM 	char			sess_alias[ISCSI_MAX_NAME_LEN];
9697836SJohn.Forte@Sun.COM 	int			sess_alias_length;
9707836SJohn.Forte@Sun.COM 	iSCSIDiscoveryMethod_t	sess_discovered_by;
9717836SJohn.Forte@Sun.COM 	iscsi_sockaddr_t	sess_discovered_addr;
9727836SJohn.Forte@Sun.COM 	uchar_t			sess_isid[ISCSI_ISID_LEN]; /* Session ID */
9737836SJohn.Forte@Sun.COM 	uint16_t		sess_tsid; /* Target ID */
9747836SJohn.Forte@Sun.COM 	/*
9757836SJohn.Forte@Sun.COM 	 * If the target portal group tag(TPGT) is equal to ISCSI_DEFAULT_TPGT
9767836SJohn.Forte@Sun.COM 	 * then the initiator will accept a successful login with any TPGT
9777836SJohn.Forte@Sun.COM 	 * specified by the target.  If a none default TPGT is configured
9787836SJohn.Forte@Sun.COM 	 * then we will only successfully accept a login with that matching
9797836SJohn.Forte@Sun.COM 	 * TPGT value.
9807836SJohn.Forte@Sun.COM 	 */
9817836SJohn.Forte@Sun.COM 	int			sess_tpgt_conf;
9827836SJohn.Forte@Sun.COM 	/* This field records the negotiated TPGT value, preserved for dtrace */
9837836SJohn.Forte@Sun.COM 	int			sess_tpgt_nego;
9847836SJohn.Forte@Sun.COM 
9857836SJohn.Forte@Sun.COM 	/*
9867836SJohn.Forte@Sun.COM 	 * Authentication information.
9877836SJohn.Forte@Sun.COM 	 *
9887836SJohn.Forte@Sun.COM 	 * DCW: Again IMA seems to take a session view at this
9897836SJohn.Forte@Sun.COM 	 * information.
9907836SJohn.Forte@Sun.COM 	 */
9917836SJohn.Forte@Sun.COM 	iscsi_auth_t		sess_auth;
9927836SJohn.Forte@Sun.COM 
9937836SJohn.Forte@Sun.COM 	/* Statistics */
9947836SJohn.Forte@Sun.COM 	struct {
9957836SJohn.Forte@Sun.COM 		kstat_t			*ks;
9967836SJohn.Forte@Sun.COM 		iscsi_sess_stats_t	ks_data;
9977836SJohn.Forte@Sun.COM 		kstat_t			*ks_io;
9987836SJohn.Forte@Sun.COM 		kstat_io_t		ks_io_data;
9997836SJohn.Forte@Sun.COM 		kmutex_t		ks_io_lock;
10007836SJohn.Forte@Sun.COM 	} stats;
10017836SJohn.Forte@Sun.COM 
10027836SJohn.Forte@Sun.COM 	iscsi_thread_t		*sess_ic_thread;
10037836SJohn.Forte@Sun.COM 	boolean_t		sess_window_open;
10048194SJack.Meng@Sun.COM 	boolean_t		sess_boot;
10057836SJohn.Forte@Sun.COM 	iscsi_sess_type_t	sess_type;
10067836SJohn.Forte@Sun.COM 
1007*12161SJack.Meng@Sun.COM 	ddi_taskq_t		*sess_login_taskq;
10087836SJohn.Forte@Sun.COM 
10097836SJohn.Forte@Sun.COM 	iscsi_thread_t		*sess_wd_thread;
10107836SJohn.Forte@Sun.COM 
10119162SPeter.Dunlap@Sun.COM 	sm_audit_buf_t		sess_state_audit;
10129780SBing.Zhao@Sun.COM 
10139780SBing.Zhao@Sun.COM 	kmutex_t		sess_reset_mutex;
10149780SBing.Zhao@Sun.COM 
10159780SBing.Zhao@Sun.COM 	boolean_t		sess_reset_in_progress;
101611424SJack.Meng@Sun.COM 
101711424SJack.Meng@Sun.COM 	boolean_t		sess_boot_nic_reset;
1018*12161SJack.Meng@Sun.COM 	kmutex_t		sess_enum_lock;
1019*12161SJack.Meng@Sun.COM 	kcondvar_t		sess_enum_cv;
1020*12161SJack.Meng@Sun.COM 	iscsi_enum_status_t	sess_enum_status;
1021*12161SJack.Meng@Sun.COM 	iscsi_enum_result_t	sess_enum_result;
1022*12161SJack.Meng@Sun.COM 	uint32_t		sess_enum_result_count;
1023*12161SJack.Meng@Sun.COM 	ddi_taskq_t		*sess_enum_taskq;
1024*12161SJack.Meng@Sun.COM 
1025*12161SJack.Meng@Sun.COM 	kmutex_t		sess_state_wmutex;
1026*12161SJack.Meng@Sun.COM 	kcondvar_t		sess_state_wcv;
1027*12161SJack.Meng@Sun.COM 	boolean_t		sess_state_hasw;
1028*12161SJack.Meng@Sun.COM 
1029*12161SJack.Meng@Sun.COM 	/* to accelerate the state change in case of new event */
1030*12161SJack.Meng@Sun.COM 	volatile uint32_t	sess_state_event_count;
10317836SJohn.Forte@Sun.COM } iscsi_sess_t;
10327836SJohn.Forte@Sun.COM 
10338488SBing.Zhao@Sun.COM /*
10348488SBing.Zhao@Sun.COM  * This structure will be used to store sessions to be online
10358488SBing.Zhao@Sun.COM  * during normal login operation.
10368488SBing.Zhao@Sun.COM  */
10378488SBing.Zhao@Sun.COM typedef struct iscsi_sess_list {
10388488SBing.Zhao@Sun.COM 	iscsi_sess_t		*session;
10398488SBing.Zhao@Sun.COM 	struct iscsi_sess_list	*next;
10408488SBing.Zhao@Sun.COM } iscsi_sess_list_t;
10417836SJohn.Forte@Sun.COM 
10427836SJohn.Forte@Sun.COM /*
10439162SPeter.Dunlap@Sun.COM  * iSCSI client notify task context for deferred IDM notifications processing
10449162SPeter.Dunlap@Sun.COM  */
10459162SPeter.Dunlap@Sun.COM typedef struct iscsi_cn_task {
10469162SPeter.Dunlap@Sun.COM 	idm_conn_t		*ct_ic;
10479162SPeter.Dunlap@Sun.COM 	idm_client_notify_t	ct_icn;
10489162SPeter.Dunlap@Sun.COM 	uintptr_t		ct_data;
10499162SPeter.Dunlap@Sun.COM } iscsi_cn_task_t;
10509162SPeter.Dunlap@Sun.COM 
10519162SPeter.Dunlap@Sun.COM /*
10527836SJohn.Forte@Sun.COM  * iscsi_network
10537836SJohn.Forte@Sun.COM  */
10547836SJohn.Forte@Sun.COM typedef struct iscsi_network {
10557836SJohn.Forte@Sun.COM 	void* (*socket)(int domain, int, int);
10567836SJohn.Forte@Sun.COM 	int (*bind)(void *, struct sockaddr *, int, int, int);
10577836SJohn.Forte@Sun.COM 	int (*connect)(void *, struct sockaddr *, int, int, int);
10587836SJohn.Forte@Sun.COM 	int (*listen)(void *, int);
10597836SJohn.Forte@Sun.COM 	void* (*accept)(void *, struct sockaddr *, int *);
10608348SEric.Yu@Sun.COM 	int (*getsockname)(void *, struct sockaddr *, socklen_t *);
10617836SJohn.Forte@Sun.COM 	int (*getsockopt)(void *, int, int, void *, int *, int);
10627836SJohn.Forte@Sun.COM 	int (*setsockopt)(void *, int, int, void *, int);
10637836SJohn.Forte@Sun.COM 	int (*shutdown)(void *, int);
10647836SJohn.Forte@Sun.COM 	void (*close)(void *);
10657836SJohn.Forte@Sun.COM 
10667836SJohn.Forte@Sun.COM 	size_t (*poll)(void *, clock_t);
10677836SJohn.Forte@Sun.COM 	size_t (*sendmsg)(void *, struct msghdr *);
10687836SJohn.Forte@Sun.COM 	size_t (*recvmsg)(void *, struct msghdr *, int);
10697836SJohn.Forte@Sun.COM 
10707836SJohn.Forte@Sun.COM 	iscsi_status_t (*sendpdu)(void *, iscsi_hdr_t *, char *, int);
10717836SJohn.Forte@Sun.COM 	iscsi_status_t (*recvdata)(void *, iscsi_hdr_t *, char *,
10727836SJohn.Forte@Sun.COM 	    int, int, int);
10737836SJohn.Forte@Sun.COM 	iscsi_status_t (*recvhdr)(void *, iscsi_hdr_t *, int, int, int);
10747836SJohn.Forte@Sun.COM 
10757836SJohn.Forte@Sun.COM 	struct {
10767836SJohn.Forte@Sun.COM 		int			sndbuf;
10777836SJohn.Forte@Sun.COM 		int			rcvbuf;
10787836SJohn.Forte@Sun.COM 		int			nodelay;
10797836SJohn.Forte@Sun.COM 		int			conn_notify_threshold;
10807836SJohn.Forte@Sun.COM 		int			conn_abort_threshold;
10817836SJohn.Forte@Sun.COM 		int			abort_threshold;
10827836SJohn.Forte@Sun.COM 	} tweaks;
10837836SJohn.Forte@Sun.COM } iscsi_network_t;
10847836SJohn.Forte@Sun.COM 
10857836SJohn.Forte@Sun.COM #define	ISCSI_NET_HEADER_DIGEST	0x00000001
10867836SJohn.Forte@Sun.COM #define	ISCSI_NET_DATA_DIGEST	0x00000002
10877836SJohn.Forte@Sun.COM 
10887836SJohn.Forte@Sun.COM extern iscsi_network_t *iscsi_net;
10897836SJohn.Forte@Sun.COM 
10907836SJohn.Forte@Sun.COM /*
10917836SJohn.Forte@Sun.COM  * If we get bus_config requests in less than 5 seconds
10927836SJohn.Forte@Sun.COM  * apart skip the name services re-discovery and just
10937836SJohn.Forte@Sun.COM  * complete the requested logins.  This protects against
10947836SJohn.Forte@Sun.COM  * bus_config storms from stale /dev links.
10957836SJohn.Forte@Sun.COM  */
10967836SJohn.Forte@Sun.COM #define	ISCSI_CONFIG_STORM_DELAY_DEFAULT    5
10977836SJohn.Forte@Sun.COM 
10987836SJohn.Forte@Sun.COM /*
10997836SJohn.Forte@Sun.COM  * iSCSI HBA Structure
11007836SJohn.Forte@Sun.COM  */
11017836SJohn.Forte@Sun.COM typedef struct iscsi_hba {
11027836SJohn.Forte@Sun.COM 	uint32_t		hba_sig;
11037836SJohn.Forte@Sun.COM 	dev_info_t		*hba_dip;	/* dev info ptr */
11047836SJohn.Forte@Sun.COM 	scsi_hba_tran_t		*hba_tran;	/* scsi tran ptr */
11059162SPeter.Dunlap@Sun.COM 	ldi_ident_t		hba_li;
11067836SJohn.Forte@Sun.COM 
11077836SJohn.Forte@Sun.COM 	struct iscsi_sess	*hba_sess_list;	/* sess. list for hba */
11087836SJohn.Forte@Sun.COM 	krwlock_t		hba_sess_list_rwlock; /* protect sess. list */
11097836SJohn.Forte@Sun.COM 
11107836SJohn.Forte@Sun.COM 	/* lbolt of the last time we received a config request */
11117836SJohn.Forte@Sun.COM 	clock_t			hba_config_lbolt;
11127836SJohn.Forte@Sun.COM 	/* current number of seconds to protect against bus config storms */
11137836SJohn.Forte@Sun.COM 	int			hba_config_storm_delay;
11147836SJohn.Forte@Sun.COM 
11157836SJohn.Forte@Sun.COM 	/* general iSCSI protocol hba/initiator info */
11167836SJohn.Forte@Sun.COM 	uchar_t			hba_name[ISCSI_MAX_NAME_LEN];
11177836SJohn.Forte@Sun.COM 	int			hba_name_length;
11187836SJohn.Forte@Sun.COM 	uchar_t			hba_alias[ISCSI_MAX_NAME_LEN];
11197836SJohn.Forte@Sun.COM 	int			hba_alias_length;
11207836SJohn.Forte@Sun.COM 
11217836SJohn.Forte@Sun.COM 	/* Default SessionID for HBA */
11227836SJohn.Forte@Sun.COM 	uchar_t			hba_isid[ISCSI_ISID_LEN];
11237836SJohn.Forte@Sun.COM 
11247836SJohn.Forte@Sun.COM 	/* Default HBA wide settings */
11257836SJohn.Forte@Sun.COM 	iscsi_login_params_t	hba_params;
11267836SJohn.Forte@Sun.COM 
11277836SJohn.Forte@Sun.COM 	/*
11287836SJohn.Forte@Sun.COM 	 * There's only one HBA and it's set to ISCSI_INITIATOR_OID
11297836SJohn.Forte@Sun.COM 	 * (value of 1) at the beginning of time.
11307836SJohn.Forte@Sun.COM 	 */
11317836SJohn.Forte@Sun.COM 	uint32_t		hba_oid;
11327836SJohn.Forte@Sun.COM 
11337836SJohn.Forte@Sun.COM 	/*
11347836SJohn.Forte@Sun.COM 	 * Keep track of which events have been sent. User daemons request
11357836SJohn.Forte@Sun.COM 	 * this information so they don't wait for events which they won't
11367836SJohn.Forte@Sun.COM 	 * see.
11377836SJohn.Forte@Sun.COM 	 */
11387836SJohn.Forte@Sun.COM 	kmutex_t		hba_discovery_events_mutex;
11397836SJohn.Forte@Sun.COM 	iSCSIDiscoveryMethod_t  hba_discovery_events;
11407836SJohn.Forte@Sun.COM 	boolean_t		hba_discovery_in_progress;
11417836SJohn.Forte@Sun.COM 
11427836SJohn.Forte@Sun.COM 	boolean_t		hba_mpxio_enabled; /* mpxio-enabled */
11439201SJack.Meng@Sun.COM 	/* if the persistent store is loaded */
11449201SJack.Meng@Sun.COM 	boolean_t		hba_persistent_loaded;
11457836SJohn.Forte@Sun.COM 
11467836SJohn.Forte@Sun.COM 	/*
11477836SJohn.Forte@Sun.COM 	 * Ensures only one SendTargets operation occurs at a time
11487836SJohn.Forte@Sun.COM 	 */
11497836SJohn.Forte@Sun.COM 	ksema_t			hba_sendtgts_semaphore;
11507836SJohn.Forte@Sun.COM 
11517836SJohn.Forte@Sun.COM 	/*
11527836SJohn.Forte@Sun.COM 	 * Statistics
11537836SJohn.Forte@Sun.COM 	 */
11547836SJohn.Forte@Sun.COM 	struct {
11557836SJohn.Forte@Sun.COM 		kstat_t			*ks;
11567836SJohn.Forte@Sun.COM 		iscsi_hba_stats_t	ks_data;
11577836SJohn.Forte@Sun.COM 	} stats;
11589201SJack.Meng@Sun.COM 
11599201SJack.Meng@Sun.COM 	/*
11609201SJack.Meng@Sun.COM 	 * track/control the service status and client
11619201SJack.Meng@Sun.COM 	 *
11629201SJack.Meng@Sun.COM 	 * service- service online ensures the operational of cli
11639201SJack.Meng@Sun.COM 	 *	  - and the availability of iSCSI discovery/devices
11649201SJack.Meng@Sun.COM 	 *	  - so obviously offline means the unusable of cli
11659201SJack.Meng@Sun.COM 	 *	  - , disabling of all discovery methods and to offline
11669201SJack.Meng@Sun.COM 	 *	  - all discovered devices
11679201SJack.Meng@Sun.COM 	 *
11689201SJack.Meng@Sun.COM 	 * client - here the client actually means 'exclusive client'
11699201SJack.Meng@Sun.COM 	 *	  - for operations these clients take may conflict
11709201SJack.Meng@Sun.COM 	 *	  - with the changing of service status and therefore
11719201SJack.Meng@Sun.COM 	 *	  - need to be exclusive
11729201SJack.Meng@Sun.COM 	 *
11739201SJack.Meng@Sun.COM 	 * The service has three status:
11749201SJack.Meng@Sun.COM 	 * 	ISCSI_SERVICE_ENABLED	 -	client is permitted to
11759201SJack.Meng@Sun.COM 	 *				 -	request service
11769201SJack.Meng@Sun.COM 	 *
11779201SJack.Meng@Sun.COM 	 *	ISCSI_SERVICE_DISABLED	 -	client is not permitted to
11789201SJack.Meng@Sun.COM 	 *				 -	request service
11799201SJack.Meng@Sun.COM 	 *
11809201SJack.Meng@Sun.COM 	 *	ISCSI_SERVICE_TRANSITION -	client must wait for
11819201SJack.Meng@Sun.COM 	 *				 -	one of above two statuses
11829201SJack.Meng@Sun.COM 	 *
11839201SJack.Meng@Sun.COM 	 * The hba_service_client_count tracks the number of
11849201SJack.Meng@Sun.COM 	 * current clients, it increases with new clients and decreases
11859201SJack.Meng@Sun.COM 	 * with leaving clients. It stops to increase once the
11869201SJack.Meng@Sun.COM 	 * ISCSI_SERVICE_TRANSITION is set, and causes later clients be
11879201SJack.Meng@Sun.COM 	 * blocked there.
11889201SJack.Meng@Sun.COM 	 *
11899201SJack.Meng@Sun.COM 	 * The status of the service can only be changed when the number
11909201SJack.Meng@Sun.COM 	 * of current clients reaches zero.
11919201SJack.Meng@Sun.COM 	 *
11929201SJack.Meng@Sun.COM 	 * Clients include:
11939201SJack.Meng@Sun.COM 	 *	iscsi_ioctl
11949201SJack.Meng@Sun.COM 	 *	iscsi_tran_bus_config
11959201SJack.Meng@Sun.COM 	 *	iscsi_tran_bus_unconfig
11969201SJack.Meng@Sun.COM 	 *	isns_scn_callback
11979201SJack.Meng@Sun.COM 	 */
11989201SJack.Meng@Sun.COM 	kmutex_t		hba_service_lock;
11999201SJack.Meng@Sun.COM 	kcondvar_t		hba_service_cv;
12009201SJack.Meng@Sun.COM 	uint32_t		hba_service_status;
12019201SJack.Meng@Sun.COM 	uint32_t		hba_service_client_count;
120210156SZhang.Yi@Sun.COM 
120310156SZhang.Yi@Sun.COM 	/* Default HBA tunable settings */
120410156SZhang.Yi@Sun.COM 	iscsi_tunable_params_t  hba_tunable_params;
120510185SJack.Meng@Sun.COM 	boolean_t		hba_service_status_overwrite;
12067836SJohn.Forte@Sun.COM } iscsi_hba_t;
12077836SJohn.Forte@Sun.COM 
12087836SJohn.Forte@Sun.COM /*
12097836SJohn.Forte@Sun.COM  * +--------------------------------------------------------------------+
12107836SJohn.Forte@Sun.COM  * | iSCSI prototypes							|
12117836SJohn.Forte@Sun.COM  * +--------------------------------------------------------------------+
12127836SJohn.Forte@Sun.COM  */
12137836SJohn.Forte@Sun.COM 
12149162SPeter.Dunlap@Sun.COM /* IDM client callback entry points */
12159162SPeter.Dunlap@Sun.COM idm_rx_pdu_cb_t iscsi_rx_scsi_rsp;
12169162SPeter.Dunlap@Sun.COM idm_rx_pdu_cb_t iscsi_rx_misc_pdu;
12179162SPeter.Dunlap@Sun.COM idm_rx_pdu_error_cb_t iscsi_rx_error_pdu;
12189162SPeter.Dunlap@Sun.COM idm_build_hdr_cb_t iscsi_build_hdr;
12199162SPeter.Dunlap@Sun.COM idm_task_cb_t iscsi_task_aborted;
12209162SPeter.Dunlap@Sun.COM idm_client_notify_cb_t iscsi_client_notify;
12219162SPeter.Dunlap@Sun.COM 
12227836SJohn.Forte@Sun.COM /* iscsi_io.c */
12237836SJohn.Forte@Sun.COM int iscsi_sna_lte(uint32_t n1, uint32_t n2);
12247836SJohn.Forte@Sun.COM char *iscsi_get_next_text(char *data, int data_length, char *curr_text);
12257836SJohn.Forte@Sun.COM 
12267836SJohn.Forte@Sun.COM void iscsi_ic_thread(iscsi_thread_t *thread, void *arg);
12277836SJohn.Forte@Sun.COM void iscsi_tx_thread(iscsi_thread_t *thread, void *arg);
12287836SJohn.Forte@Sun.COM void iscsi_wd_thread(iscsi_thread_t *thread, void *arg);
12297836SJohn.Forte@Sun.COM 
12307836SJohn.Forte@Sun.COM iscsi_status_t iscsi_tx_cmd(iscsi_sess_t *isp, iscsi_cmd_t *icmdp);
12317836SJohn.Forte@Sun.COM 
12329162SPeter.Dunlap@Sun.COM void iscsi_task_cleanup(int opcode, iscsi_cmd_t *icmdp);
12339162SPeter.Dunlap@Sun.COM 
12347836SJohn.Forte@Sun.COM void iscsi_handle_abort(void *arg);
12357836SJohn.Forte@Sun.COM iscsi_status_t iscsi_handle_reset(iscsi_sess_t *isp, int level,
12367836SJohn.Forte@Sun.COM     iscsi_lun_t *ilp);
12377836SJohn.Forte@Sun.COM iscsi_status_t iscsi_handle_logout(iscsi_conn_t *icp);
12387836SJohn.Forte@Sun.COM iscsi_status_t iscsi_handle_passthru(iscsi_sess_t *isp, uint16_t lun,
12397836SJohn.Forte@Sun.COM     struct uscsi_cmd *ucmdp);
12407836SJohn.Forte@Sun.COM iscsi_status_t iscsi_handle_text(iscsi_conn_t *icp,
12417836SJohn.Forte@Sun.COM     char *buf, uint32_t buf_len, uint32_t data_len, uint32_t *rx_data_len);
12427836SJohn.Forte@Sun.COM 
12437836SJohn.Forte@Sun.COM void iscsi_iodone(iscsi_sess_t *isp, iscsi_cmd_t *icmdp);
12447836SJohn.Forte@Sun.COM 
12457836SJohn.Forte@Sun.COM /* iscsi_crc.c */
12467836SJohn.Forte@Sun.COM uint32_t iscsi_crc32c(void *address, unsigned long length);
12477836SJohn.Forte@Sun.COM uint32_t iscsi_crc32c_continued(void *address, unsigned long length,
12487836SJohn.Forte@Sun.COM     uint32_t crc);
12497836SJohn.Forte@Sun.COM 
12507836SJohn.Forte@Sun.COM /* iscsi_queue.c */
12517836SJohn.Forte@Sun.COM void iscsi_init_queue(iscsi_queue_t *queue);
12527836SJohn.Forte@Sun.COM void iscsi_destroy_queue(iscsi_queue_t *queue);
12537836SJohn.Forte@Sun.COM void iscsi_enqueue_pending_cmd(iscsi_sess_t *isp, iscsi_cmd_t *icmdp);
12547836SJohn.Forte@Sun.COM void iscsi_dequeue_pending_cmd(iscsi_sess_t *isp, iscsi_cmd_t *icmdp);
12557836SJohn.Forte@Sun.COM void iscsi_enqueue_active_cmd(iscsi_conn_t *icp, iscsi_cmd_t *icmdp);
12567836SJohn.Forte@Sun.COM void iscsi_dequeue_active_cmd(iscsi_conn_t *icp, iscsi_cmd_t *icmdp);
12579162SPeter.Dunlap@Sun.COM void iscsi_enqueue_idm_aborting_cmd(iscsi_conn_t *icp, iscsi_cmd_t *icmdp);
12589162SPeter.Dunlap@Sun.COM void iscsi_dequeue_idm_aborting_cmd(iscsi_conn_t *icp, iscsi_cmd_t *icmdp);
12597836SJohn.Forte@Sun.COM void iscsi_enqueue_completed_cmd(iscsi_sess_t *isp, iscsi_cmd_t *icmdp);
12607836SJohn.Forte@Sun.COM iscsi_status_t iscsi_dequeue_cmd(iscsi_cmd_t **, iscsi_cmd_t **, iscsi_cmd_t *);
12617836SJohn.Forte@Sun.COM void iscsi_move_queue(iscsi_queue_t *src_queue, iscsi_queue_t *dst_queue);
12627836SJohn.Forte@Sun.COM void iscsi_enqueue_cmd_head(iscsi_cmd_t **, iscsi_cmd_t **,
12637836SJohn.Forte@Sun.COM     iscsi_cmd_t *);
12647836SJohn.Forte@Sun.COM 
12657836SJohn.Forte@Sun.COM /* iscsi_login.c */
12667836SJohn.Forte@Sun.COM iscsi_status_t iscsi_login_start(void *arg);
12679162SPeter.Dunlap@Sun.COM void iscsi_login_update_state(iscsi_conn_t *icp,
12689162SPeter.Dunlap@Sun.COM     iscsi_login_state_t next_state);
12699162SPeter.Dunlap@Sun.COM void iscsi_login_update_state_locked(iscsi_conn_t *icp,
12709162SPeter.Dunlap@Sun.COM     iscsi_login_state_t next_state);
12719162SPeter.Dunlap@Sun.COM 
12727836SJohn.Forte@Sun.COM 
12737836SJohn.Forte@Sun.COM /* iscsi_stats.c */
12747836SJohn.Forte@Sun.COM boolean_t iscsi_hba_kstat_init(struct iscsi_hba	*ihp);
12757836SJohn.Forte@Sun.COM boolean_t iscsi_hba_kstat_term(struct iscsi_hba	*ihp);
12767836SJohn.Forte@Sun.COM boolean_t iscsi_sess_kstat_init(struct iscsi_sess *isp);
12777836SJohn.Forte@Sun.COM boolean_t iscsi_sess_kstat_term(struct iscsi_sess *isp);
12787836SJohn.Forte@Sun.COM boolean_t iscsi_conn_kstat_init(struct iscsi_conn	*icp);
12797836SJohn.Forte@Sun.COM void iscsi_conn_kstat_term(struct iscsi_conn *icp);
12807836SJohn.Forte@Sun.COM 
12817836SJohn.Forte@Sun.COM /* iscsi_net.c */
12827836SJohn.Forte@Sun.COM void iscsi_net_init();
12837836SJohn.Forte@Sun.COM void iscsi_net_fini();
128411424SJack.Meng@Sun.COM iscsi_status_t iscsi_net_interface(boolean_t reset);
12857836SJohn.Forte@Sun.COM 
12867836SJohn.Forte@Sun.COM /* iscsi_sess.c */
12877836SJohn.Forte@Sun.COM iscsi_sess_t *iscsi_sess_create(iscsi_hba_t *ihp,
12887836SJohn.Forte@Sun.COM     iSCSIDiscoveryMethod_t method, struct sockaddr *addr_dsc,
12897836SJohn.Forte@Sun.COM     char *target_name, int tpgt, uchar_t isid_lsb,
12907836SJohn.Forte@Sun.COM     iscsi_sess_type_t type, uint32_t *oid);
12918488SBing.Zhao@Sun.COM void iscsi_sess_online(void *arg);
12927836SJohn.Forte@Sun.COM int iscsi_sess_get(uint32_t oid, iscsi_hba_t *ihp, iscsi_sess_t **ispp);
12937836SJohn.Forte@Sun.COM iscsi_status_t iscsi_sess_destroy(iscsi_sess_t *isp);
1294*12161SJack.Meng@Sun.COM void iscsi_sess_state_machine(iscsi_sess_t *isp, iscsi_sess_event_t event,
1295*12161SJack.Meng@Sun.COM     uint32_t event_count);
12967836SJohn.Forte@Sun.COM char *iscsi_sess_state_str(iscsi_sess_state_t state);
12977836SJohn.Forte@Sun.COM boolean_t iscsi_sess_set_auth(iscsi_sess_t *isp);
12989162SPeter.Dunlap@Sun.COM iscsi_status_t iscsi_sess_reserve_scsi_itt(iscsi_cmd_t *icmdp);
12999162SPeter.Dunlap@Sun.COM void iscsi_sess_release_scsi_itt(iscsi_cmd_t *icmdp);
13007836SJohn.Forte@Sun.COM iscsi_status_t iscsi_sess_reserve_itt(iscsi_sess_t *isp, iscsi_cmd_t *icmdp);
13017836SJohn.Forte@Sun.COM void iscsi_sess_release_itt(iscsi_sess_t *isp, iscsi_cmd_t *icmdp);
13027836SJohn.Forte@Sun.COM void iscsi_sess_redrive_io(iscsi_sess_t *isp);
13037836SJohn.Forte@Sun.COM int iscsi_sess_get_by_target(uint32_t target_oid, iscsi_hba_t *ihp,
1304*12161SJack.Meng@Sun.COM     iscsi_sess_t **ispp);
1305*12161SJack.Meng@Sun.COM iscsi_enum_result_t iscsi_sess_enum_request(iscsi_sess_t *isp,
1306*12161SJack.Meng@Sun.COM     boolean_t wait, uint32_t event_count);
1307*12161SJack.Meng@Sun.COM iscsi_enum_result_t iscsi_sess_enum_query(iscsi_sess_t *isp);
1308*12161SJack.Meng@Sun.COM void iscsi_sess_enter_state_zone(iscsi_sess_t *isp);
1309*12161SJack.Meng@Sun.COM void iscsi_sess_exit_state_zone(iscsi_sess_t *isp);
13107836SJohn.Forte@Sun.COM 
13117836SJohn.Forte@Sun.COM /* iscsi_conn.c */
13127836SJohn.Forte@Sun.COM iscsi_status_t iscsi_conn_create(struct sockaddr *addr, iscsi_sess_t *isp,
13137836SJohn.Forte@Sun.COM     iscsi_conn_t **icpp);
13149162SPeter.Dunlap@Sun.COM iscsi_status_t iscsi_conn_online(iscsi_conn_t *icp);
13157836SJohn.Forte@Sun.COM iscsi_status_t iscsi_conn_offline(iscsi_conn_t *icp);
13167836SJohn.Forte@Sun.COM iscsi_status_t iscsi_conn_destroy(iscsi_conn_t *icp);
13177836SJohn.Forte@Sun.COM void iscsi_conn_set_login_min_max(iscsi_conn_t *icp, int min, int max);
13187836SJohn.Forte@Sun.COM iscsi_status_t iscsi_conn_sync_params(iscsi_conn_t *icp);
13199162SPeter.Dunlap@Sun.COM void iscsi_conn_retry(iscsi_sess_t *isp, iscsi_conn_t *icp);
13209162SPeter.Dunlap@Sun.COM void iscsi_conn_update_state(iscsi_conn_t *icp, iscsi_conn_state_t next_state);
13219162SPeter.Dunlap@Sun.COM void iscsi_conn_update_state_locked(iscsi_conn_t *icp,
13229162SPeter.Dunlap@Sun.COM 			iscsi_conn_state_t next_state);
13237836SJohn.Forte@Sun.COM 
13247836SJohn.Forte@Sun.COM /* iscsi_lun.c */
13257836SJohn.Forte@Sun.COM iscsi_status_t iscsi_lun_create(iscsi_sess_t *isp, uint16_t lun_num,
13267836SJohn.Forte@Sun.COM     uint8_t lun_addr_type, struct scsi_inquiry *inq, char *guid);
13277836SJohn.Forte@Sun.COM iscsi_status_t iscsi_lun_destroy(iscsi_hba_t *ihp,
13287836SJohn.Forte@Sun.COM     iscsi_lun_t *ilp);
13297836SJohn.Forte@Sun.COM void iscsi_lun_online(iscsi_hba_t *ihp,
13307836SJohn.Forte@Sun.COM     iscsi_lun_t *ilp);
13317836SJohn.Forte@Sun.COM iscsi_status_t iscsi_lun_offline(iscsi_hba_t *ihp,
13327836SJohn.Forte@Sun.COM     iscsi_lun_t *ilp, boolean_t lun_free);
13337836SJohn.Forte@Sun.COM 
13347836SJohn.Forte@Sun.COM /* iscsi_cmd.c */
13357836SJohn.Forte@Sun.COM void iscsi_cmd_state_machine(iscsi_cmd_t *icmdp,
13367836SJohn.Forte@Sun.COM     iscsi_cmd_event_t event, void *arg);
13377836SJohn.Forte@Sun.COM iscsi_cmd_t	*iscsi_cmd_alloc(iscsi_conn_t *icp, int km_flags);
13387836SJohn.Forte@Sun.COM void		iscsi_cmd_free(iscsi_cmd_t *icmdp);
13397836SJohn.Forte@Sun.COM 
13407836SJohn.Forte@Sun.COM /* iscsi_ioctl.c */
13417836SJohn.Forte@Sun.COM void * iscsi_ioctl_copyin(caddr_t arg, int mode, size_t size);
13427836SJohn.Forte@Sun.COM int iscsi_ioctl_copyout(void *data, size_t size, caddr_t arg, int mode);
13437836SJohn.Forte@Sun.COM iscsi_conn_list_t *iscsi_ioctl_conn_oid_list_get_copyin(caddr_t, int);
13447836SJohn.Forte@Sun.COM int iscsi_ioctl_conn_oid_list_get_copyout(iscsi_conn_list_t *, caddr_t, int);
13457836SJohn.Forte@Sun.COM boolean_t iscsi_ioctl_conn_oid_list_get(iscsi_hba_t *ihp,
13467836SJohn.Forte@Sun.COM     iscsi_conn_list_t *cl);
13477836SJohn.Forte@Sun.COM boolean_t iscsi_ioctl_conn_props_get(iscsi_hba_t *ihp, iscsi_conn_props_t *cp);
13487836SJohn.Forte@Sun.COM int iscsi_ioctl_sendtgts_get(iscsi_hba_t *ihp, iscsi_sendtgts_list_t *stl);
13497836SJohn.Forte@Sun.COM int iscsi_target_prop_mod(iscsi_hba_t *, iscsi_property_t *, int cmd);
13507836SJohn.Forte@Sun.COM int iscsi_set_params(iscsi_param_set_t *, iscsi_hba_t *, boolean_t);
13517836SJohn.Forte@Sun.COM int iscsi_get_persisted_param(uchar_t *, iscsi_param_get_t *,
13527836SJohn.Forte@Sun.COM     iscsi_login_params_t *);
13537836SJohn.Forte@Sun.COM void iscsi_set_default_login_params(iscsi_login_params_t *params);
13547836SJohn.Forte@Sun.COM int iscsi_ioctl_get_config_sess(iscsi_hba_t *ihp,
13557836SJohn.Forte@Sun.COM     iscsi_config_sess_t *ics);
13567836SJohn.Forte@Sun.COM int iscsi_ioctl_set_config_sess(iscsi_hba_t *ihp,
13577836SJohn.Forte@Sun.COM     iscsi_config_sess_t *ics);
135810156SZhang.Yi@Sun.COM int iscsi_ioctl_set_tunable_param(iscsi_hba_t *ihp,
135910156SZhang.Yi@Sun.COM     iscsi_tunable_object_t *tpss);
13607836SJohn.Forte@Sun.COM /* ioctls  prototypes */
13617836SJohn.Forte@Sun.COM int iscsi_get_param(iscsi_login_params_t *params,
13627836SJohn.Forte@Sun.COM     boolean_t valid_flag,
13637836SJohn.Forte@Sun.COM     iscsi_param_get_t *ipgp);
13647836SJohn.Forte@Sun.COM 
13657836SJohn.Forte@Sun.COM /* iscsid.c */
13669201SJack.Meng@Sun.COM boolean_t iscsid_init(iscsi_hba_t *ihp);
13679201SJack.Meng@Sun.COM boolean_t iscsid_start(iscsi_hba_t *ihp);
13689201SJack.Meng@Sun.COM boolean_t iscsid_stop(iscsi_hba_t *ihp);
13697836SJohn.Forte@Sun.COM void iscsid_fini();
13707836SJohn.Forte@Sun.COM void iscsid_props(iSCSIDiscoveryProperties_t *props);
13717836SJohn.Forte@Sun.COM boolean_t iscsid_enable_discovery(iscsi_hba_t *ihp,
13727836SJohn.Forte@Sun.COM     iSCSIDiscoveryMethod_t idm, boolean_t poke);
13737836SJohn.Forte@Sun.COM boolean_t iscsid_disable_discovery(iscsi_hba_t *ihp,
13747836SJohn.Forte@Sun.COM     iSCSIDiscoveryMethod_t idm);
13757836SJohn.Forte@Sun.COM void iscsid_poke_discovery(iscsi_hba_t *ihp, iSCSIDiscoveryMethod_t method);
13767836SJohn.Forte@Sun.COM void iscsid_do_sendtgts(entry_t *discovery_addr);
13777836SJohn.Forte@Sun.COM void iscsid_do_isns_query_one_server(
13787836SJohn.Forte@Sun.COM     iscsi_hba_t *ihp, entry_t *isns_addr);
13797836SJohn.Forte@Sun.COM void iscsid_do_isns_query(iscsi_hba_t *ihp);
13807836SJohn.Forte@Sun.COM void iscsid_config_one(iscsi_hba_t *ihp,
13817836SJohn.Forte@Sun.COM     char *name, boolean_t protect);
13827836SJohn.Forte@Sun.COM void iscsid_config_all(iscsi_hba_t *ihp, boolean_t protect);
13837836SJohn.Forte@Sun.COM void iscsid_unconfig_one(iscsi_hba_t *ihp, char *name);
13847836SJohn.Forte@Sun.COM void iscsid_unconfig_all(iscsi_hba_t *ihp);
13857836SJohn.Forte@Sun.COM void isns_scn_callback(void *arg);
13867836SJohn.Forte@Sun.COM boolean_t iscsid_del(iscsi_hba_t *ihp, char *target_name,
13877836SJohn.Forte@Sun.COM     iSCSIDiscoveryMethod_t method, struct sockaddr *addr_dsc);
13887836SJohn.Forte@Sun.COM boolean_t iscsid_login_tgt(iscsi_hba_t *ihp, char *target_name,
13897836SJohn.Forte@Sun.COM     iSCSIDiscoveryMethod_t method, struct sockaddr *addr_dsc);
13907836SJohn.Forte@Sun.COM void iscsid_addr_to_sockaddr(int src_insize, void *src_addr, int src_port,
13917836SJohn.Forte@Sun.COM     struct sockaddr *dst_addr);
13929429SJack.Meng@Sun.COM void iscsid_set_default_initiator_node_settings(iscsi_hba_t *ihp,
13939429SJack.Meng@Sun.COM     boolean_t minimal);
13949429SJack.Meng@Sun.COM 
13959371SBing.Zhao@Sun.COM void iscsi_send_sysevent(iscsi_hba_t *ihp, char *eventcalss,
13969371SBing.Zhao@Sun.COM     char *subclass, nvlist_t *np);
13978194SJack.Meng@Sun.COM boolean_t iscsi_reconfig_boot_sess(iscsi_hba_t *ihp);
13988194SJack.Meng@Sun.COM boolean_t iscsi_chk_bootlun_mpxio(iscsi_hba_t *ihp);
13998194SJack.Meng@Sun.COM boolean_t iscsi_cmp_boot_ini_name(char *name);
14008194SJack.Meng@Sun.COM boolean_t iscsi_cmp_boot_tgt_name(char *name);
14019201SJack.Meng@Sun.COM boolean_t iscsi_client_request_service(iscsi_hba_t *ihp);
14029201SJack.Meng@Sun.COM void iscsi_client_release_service(iscsi_hba_t *ihp);
14037836SJohn.Forte@Sun.COM 
14047836SJohn.Forte@Sun.COM extern void bcopy(const void *s1, void *s2, size_t n);
14057836SJohn.Forte@Sun.COM extern void bzero(void *s, size_t n);
14067836SJohn.Forte@Sun.COM /*
14077836SJohn.Forte@Sun.COM  * Here we need a contract for inet_ntop() and inet_pton()
14087836SJohn.Forte@Sun.COM  * in uts/common/inet/ip/inet_ntop.c
14097836SJohn.Forte@Sun.COM  */
14107836SJohn.Forte@Sun.COM extern char *inet_ntop(int af, const void *addr, char *buf, int addrlen);
14117836SJohn.Forte@Sun.COM extern int inet_pton(int af, char *inp, void *outp);
14127836SJohn.Forte@Sun.COM 
14137836SJohn.Forte@Sun.COM #ifdef __cplusplus
14147836SJohn.Forte@Sun.COM }
14157836SJohn.Forte@Sun.COM #endif
14167836SJohn.Forte@Sun.COM 
14177836SJohn.Forte@Sun.COM #endif /* _ISCSI_H */
1418