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