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