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