usr/src/uts/common/io/scsi/adapters/iscsi/iscsi.h
changeset 9162 b011b0287065
parent 8656 d00942080f9a
child 9201 d1e93b2ab63d
equal deleted inserted replaced
9161:7dca69f75d8e 9162:b011b0287065
    45 #include <sys/mdi_impldefs.h>
    45 #include <sys/mdi_impldefs.h>
    46 #include <sys/time.h>
    46 #include <sys/time.h>
    47 #include <sys/nvpair.h>
    47 #include <sys/nvpair.h>
    48 #include <sys/sdt.h>
    48 #include <sys/sdt.h>
    49 
    49 
       
    50 #include <sys/iscsi_protocol.h>
    50 #include <sys/scsi/adapters/iscsi_if.h>
    51 #include <sys/scsi/adapters/iscsi_if.h>
    51 #include <sys/iscsi_protocol.h>
       
    52 #include <iscsiAuthClient.h>
    52 #include <iscsiAuthClient.h>
    53 #include <iscsi_stats.h>
    53 #include <iscsi_stats.h>
    54 #include <iscsi_thread.h>
    54 #include <iscsi_thread.h>
       
    55 #include <sys/idm/idm.h>
       
    56 #include <sys/idm/idm_conn_sm.h>
    55 #include <nvfile.h>
    57 #include <nvfile.h>
    56 
    58 
    57 #ifndef MIN
    59 #ifndef MIN
    58 #define	MIN(a, b) ((a) < (b) ? (a) : (b))
    60 #define	MIN(a, b) ((a) < (b) ? (a) : (b))
    59 #endif
    61 #endif
    66 #define	FALSE 0
    68 #define	FALSE 0
    67 #endif
    69 #endif
    68 
    70 
    69 #define	LOGIN_PDU_BUFFER_SIZE	(16 * 1024)	/* move somewhere else */
    71 #define	LOGIN_PDU_BUFFER_SIZE	(16 * 1024)	/* move somewhere else */
    70 
    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 
    71 /*
    84 /*
    72  * Name Format of the different Task Queues
    85  * Name Format of the different Task Queues
    73  */
    86  */
    74 #define	ISCSI_SESS_IOTH_NAME_FORMAT		"io_thrd_%d.%d"
    87 #define	ISCSI_SESS_IOTH_NAME_FORMAT		"io_thrd_%d.%d"
    75 #define	ISCSI_SESS_WD_NAME_FORMAT		"wd_thrd_%d.%d"
    88 #define	ISCSI_SESS_WD_NAME_FORMAT		"wd_thrd_%d.%d"
    76 #define	ISCSI_SESS_LOGIN_TASKQ_NAME_FORMAT	"login_taskq_%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"
    77 #define	ISCSI_CONN_RXTH_NAME_FORMAT		"rx_thrd_%d.%d.%d"
    91 #define	ISCSI_CONN_RXTH_NAME_FORMAT		"rx_thrd_%d.%d.%d"
    78 #define	ISCSI_CONN_TXTH_NAME_FORMAT		"tx_thrd_%d.%d.%d"
    92 #define	ISCSI_CONN_TXTH_NAME_FORMAT		"tx_thrd_%d.%d.%d"
    79 
    93 
    80 /*
    94 /*
    81  * The iSCSI driver will not build scatter/gather lists (iovec) longer
    95  * The iSCSI driver will not build scatter/gather lists (iovec) longer
   173 	/* data received would have overflowed given buffer */
   187 	/* data received would have overflowed given buffer */
   174 	ISCSI_STATUS_DATA_OVERFLOW,
   188 	ISCSI_STATUS_DATA_OVERFLOW,
   175 	/* session/connection needs to shutdown */
   189 	/* session/connection needs to shutdown */
   176 	ISCSI_STATUS_SHUTDOWN,
   190 	ISCSI_STATUS_SHUTDOWN,
   177 	/* logical unit in use */
   191 	/* logical unit in use */
   178 	ISCSI_STATUS_BUSY
   192 	ISCSI_STATUS_BUSY,
       
   193 	/* Login on connection failed, retries exceeded */
       
   194 	ISCSI_STATUS_LOGIN_TIMED_OUT
   179 } iscsi_status_t;
   195 } iscsi_status_t;
   180 #define	ISCSI_SUCCESS(status) (status == ISCSI_STATUS_SUCCESS)
   196 #define	ISCSI_SUCCESS(status) (status == ISCSI_STATUS_SUCCESS)
   181 
   197 
   182 /* SNA32 check value used on increment of CmdSn values */
   198 /* SNA32 check value used on increment of CmdSn values */
   183 #define	ISCSI_SNA32_CHECK 2147483648UL /* 2**31 */
   199 #define	ISCSI_SNA32_CHECK 2147483648UL /* 2**31 */
   281  * These are all the iscsi_cmd types that we use to track our
   297  * These are all the iscsi_cmd types that we use to track our
   282  * commands between queues and actions.
   298  * commands between queues and actions.
   283  */
   299  */
   284 typedef enum iscsi_cmd_type {
   300 typedef enum iscsi_cmd_type {
   285 	ISCSI_CMD_TYPE_SCSI = 1,	/* scsi cmd */
   301 	ISCSI_CMD_TYPE_SCSI = 1,	/* scsi cmd */
   286 	ISCSI_CMD_TYPE_R2T,		/* r2t */
       
   287 	ISCSI_CMD_TYPE_NOP,		/* nop / ping */
   302 	ISCSI_CMD_TYPE_NOP,		/* nop / ping */
   288 	ISCSI_CMD_TYPE_ABORT,		/* abort */
   303 	ISCSI_CMD_TYPE_ABORT,		/* abort */
   289 	ISCSI_CMD_TYPE_RESET,		/* reset */
   304 	ISCSI_CMD_TYPE_RESET,		/* reset */
   290 	ISCSI_CMD_TYPE_LOGOUT,		/* logout */
   305 	ISCSI_CMD_TYPE_LOGOUT,		/* logout */
   291 	ISCSI_CMD_TYPE_LOGIN,		/* login */
   306 	ISCSI_CMD_TYPE_LOGIN,		/* login */
   294 
   309 
   295 /*
   310 /*
   296  * iscsi_cmd_state - (reference iscsi_cmd.c for state diagram)
   311  * iscsi_cmd_state - (reference iscsi_cmd.c for state diagram)
   297  */
   312  */
   298 typedef enum iscsi_cmd_state {
   313 typedef enum iscsi_cmd_state {
   299 	ISCSI_CMD_STATE_FREE,
   314 	ISCSI_CMD_STATE_FREE = 0,
   300 	ISCSI_CMD_STATE_PENDING,
   315 	ISCSI_CMD_STATE_PENDING,
   301 	ISCSI_CMD_STATE_ACTIVE,
   316 	ISCSI_CMD_STATE_ACTIVE,
   302 	ISCSI_CMD_STATE_ABORTING,
   317 	ISCSI_CMD_STATE_ABORTING,
   303 	ISCSI_CMD_STATE_COMPLETED
   318 	ISCSI_CMD_STATE_IDM_ABORTING,
       
   319 	ISCSI_CMD_STATE_COMPLETED,
       
   320 	ISCSI_CMD_STATE_MAX
   304 } iscsi_cmd_state_t;
   321 } iscsi_cmd_state_t;
   305 
   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 
   306 /*
   335 /*
   307  * iscsi command events
   336  * iscsi command events
   308  */
   337  */
   309 typedef enum iscsi_cmd_event {
   338 typedef enum iscsi_cmd_event {
   310 	ISCSI_CMD_EVENT_E1,
   339 	ISCSI_CMD_EVENT_E1 = 0,
   311 	ISCSI_CMD_EVENT_E2,
   340 	ISCSI_CMD_EVENT_E2,
   312 	ISCSI_CMD_EVENT_E3,
   341 	ISCSI_CMD_EVENT_E3,
   313 	ISCSI_CMD_EVENT_E4,
   342 	ISCSI_CMD_EVENT_E4,
   314 	ISCSI_CMD_EVENT_E6,
   343 	ISCSI_CMD_EVENT_E6,
   315 	ISCSI_CMD_EVENT_E7,
   344 	ISCSI_CMD_EVENT_E7,
   316 	ISCSI_CMD_EVENT_E8
   345 	ISCSI_CMD_EVENT_E8,
       
   346 	ISCSI_CMD_EVENT_E9,
       
   347 	ISCSI_CMD_EVENT_E10,
       
   348 	ISCSI_CMD_EVENT_MAX
   317 } iscsi_cmd_event_t;
   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
   318 
   365 
   319 /*
   366 /*
   320  * iscsi text command stages - these stages are used by iSCSI text
   367  * iscsi text command stages - these stages are used by iSCSI text
   321  * processing to manage long resonses.
   368  * processing to manage long resonses.
   322  */
   369  */
   323 typedef enum iscsi_cmd_text_stage {
   370 typedef enum iscsi_cmd_text_stage {
   324 	ISCSI_CMD_TEXT_INITIAL_REQ,
   371 	ISCSI_CMD_TEXT_INITIAL_REQ = 0,
   325 	ISCSI_CMD_TEXT_CONTINUATION,
   372 	ISCSI_CMD_TEXT_CONTINUATION,
   326 	ISCSI_CMD_TEXT_FINAL_RSP
   373 	ISCSI_CMD_TEXT_FINAL_RSP
   327 } iscsi_cmd_text_stage_t;
   374 } iscsi_cmd_text_stage_t;
   328 
   375 
   329 /*
   376 /*
   347 	iscsi_cmd_state_t	cmd_state;
   394 	iscsi_cmd_state_t	cmd_state;
   348 	iscsi_cmd_state_t	cmd_prev_state;
   395 	iscsi_cmd_state_t	cmd_prev_state;
   349 	clock_t			cmd_lbolt_pending;
   396 	clock_t			cmd_lbolt_pending;
   350 	clock_t			cmd_lbolt_active;
   397 	clock_t			cmd_lbolt_active;
   351 	clock_t			cmd_lbolt_aborting;
   398 	clock_t			cmd_lbolt_aborting;
       
   399 	clock_t			cmd_lbolt_idm_aborting;
   352 	clock_t			cmd_lbolt_timeout;
   400 	clock_t			cmd_lbolt_timeout;
   353 	uint8_t			cmd_misc_flags;
   401 	uint8_t			cmd_misc_flags;
       
   402 	idm_task_t		*cmd_itp;
   354 
   403 
   355 	union {
   404 	union {
   356 		/* ISCSI_CMD_TYPE_SCSI */
   405 		/* ISCSI_CMD_TYPE_SCSI */
   357 		struct {
   406 		struct {
       
   407 			idm_buf_t		*ibp_ibuf;
       
   408 			idm_buf_t		*ibp_obuf;
   358 			struct scsi_pkt		*pkt;
   409 			struct scsi_pkt		*pkt;
   359 			struct buf		*bp;
   410 			struct buf		*bp;
   360 			int			cmdlen;
   411 			int			cmdlen;
   361 			int			statuslen;
   412 			int			statuslen;
   362 			size_t			data_transferred;
   413 			size_t			data_transferred;
   441 	int			cmd_result;
   492 	int			cmd_result;
   442 	int			cmd_completed;
   493 	int			cmd_completed;
   443 	kmutex_t		cmd_mutex;
   494 	kmutex_t		cmd_mutex;
   444 	kcondvar_t		cmd_completion;
   495 	kcondvar_t		cmd_completion;
   445 
   496 
       
   497 	idm_pdu_t		cmd_pdu;
       
   498 
       
   499 	sm_audit_buf_t		cmd_state_audit;
   446 } iscsi_cmd_t;
   500 } iscsi_cmd_t;
   447 
   501 
   448 
   502 
   449 /*
   503 /*
   450  * iSCSI LUN Structure
   504  * iSCSI LUN Structure
   478 #define	ISCSI_LUN_STATE_INVALID	4		/* offline failed */
   532 #define	ISCSI_LUN_STATE_INVALID	4		/* offline failed */
   479 
   533 
   480 #define	ISCSI_LUN_CAP_RESET   0x01
   534 #define	ISCSI_LUN_CAP_RESET   0x01
   481 
   535 
   482 /*
   536 /*
   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  *
   537  *
   518  *
   538  *
   519  */
   539  */
   520 typedef struct iscsi_queue {
   540 typedef struct iscsi_queue {
   521 	iscsi_cmd_t	*head;
   541 	iscsi_cmd_t	*head;
   535 } iscsi_sockaddr_t;
   555 } iscsi_sockaddr_t;
   536 
   556 
   537 #define	SIZEOF_SOCKADDR(so)	((so)->sa_family == AF_INET ? \
   557 #define	SIZEOF_SOCKADDR(so)	((so)->sa_family == AF_INET ? \
   538 	sizeof (struct sockaddr_in) : sizeof (struct sockaddr_in6))
   558 	sizeof (struct sockaddr_in) : sizeof (struct sockaddr_in6))
   539 
   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 
   540 /*
   615 /*
   541  * iSCSI Connection Structure
   616  * iSCSI Connection Structure
   542  */
   617  */
   543 typedef struct iscsi_conn {
   618 typedef struct iscsi_conn {
   544 	uint32_t		conn_sig;
   619 	uint32_t		conn_sig;
   545 	struct iscsi_conn	*conn_next;	/* next conn on this sess. */
   620 	struct iscsi_conn	*conn_next;	/* next conn on this sess. */
   546 	struct iscsi_sess	*conn_sess;	/* parent sess. for conn. */
   621 	struct iscsi_sess	*conn_sess;	/* parent sess. for conn. */
   547 
   622 
   548 	iscsi_conn_state_t	conn_state;	/* cur. conn. driver state */
   623 	iscsi_conn_state_t	conn_state;	/* cur. conn. driver state */
   549 	iscsi_conn_state_t	conn_prev_state; /* prev. conn. driver state */
   624 	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 */
   625 	/* protects the session state and synchronizes the state machine */
   552 	kmutex_t		conn_state_mutex;
   626 	kmutex_t		conn_state_mutex;
   553 	kcondvar_t		conn_state_change;
   627 	kcondvar_t		conn_state_change;
   554 	boolean_t		conn_state_destroy;
   628 	boolean_t		conn_state_destroy;
   555 
   629 	boolean_t		conn_state_ffp;
   556 	void			*conn_socket;	/* kernel socket */
   630 	boolean_t		conn_state_idm_connected;
   557 
   631 	boolean_t		conn_async_logout;
   558 	/* base connection information */
   632 	ddi_taskq_t		*conn_cn_taskq;
       
   633 
       
   634 	idm_conn_t		*conn_ic;
       
   635 
       
   636 	/* base connection information, may have been redirected */
   559 	iscsi_sockaddr_t	conn_base_addr;
   637 	iscsi_sockaddr_t	conn_base_addr;
   560 
   638 
   561 	/* current connection information, may have been redirected */
   639 	/* current connection information, may have been redirected */
   562 	iscsi_sockaddr_t	conn_curr_addr;
   640 	iscsi_sockaddr_t	conn_curr_addr;
   563 
   641 
   564 	/* current connection information, may have been redirected */
       
   565 	boolean_t		conn_bound;
   642 	boolean_t		conn_bound;
   566 	iscsi_sockaddr_t	conn_bound_addr;
   643 	iscsi_sockaddr_t	conn_bound_addr;
   567 
   644 
   568 	uint32_t		conn_cid;	/* CID */
   645 	uint32_t		conn_cid;	/* CID */
   569 	uint32_t		conn_oid;	/* OID */
   646 	uint32_t		conn_oid;	/* OID */
   579 	 * are issues with these cmds the command may need aborted
   656 	 * are issues with these cmds the command may need aborted
   580 	 * depending on the command type, and must be put back into
   657 	 * depending on the command type, and must be put back into
   581 	 * the session's pending queue or aborted.
   658 	 * the session's pending queue or aborted.
   582 	 */
   659 	 */
   583 	iscsi_queue_t		conn_queue_active;
   660 	iscsi_queue_t		conn_queue_active;
       
   661 	iscsi_queue_t		conn_queue_idm_aborting;
   584 
   662 
   585 	/* lbolt from the last receive, used for nop processing */
   663 	/* lbolt from the last receive, used for nop processing */
   586 	clock_t			conn_rx_lbolt;
   664 	clock_t			conn_rx_lbolt;
   587 	clock_t			conn_nop_lbolt;
   665 	clock_t			conn_nop_lbolt;
   588 
   666 
   589 	iscsi_thread_t		*conn_rx_thread;
       
   590 	iscsi_thread_t		*conn_tx_thread;
   667 	iscsi_thread_t		*conn_tx_thread;
   591 
   668 
   592 	/*
   669 	/*
   593 	 * The expstatsn is the command status sn that is expected
   670 	 * The expstatsn is the command status sn that is expected
   594 	 * next from the target.  Command status is carried on a number
   671 	 * next from the target.  Command status is carried on a number
   606 	/* Statistics */
   683 	/* Statistics */
   607 	struct {
   684 	struct {
   608 		kstat_t			*ks;
   685 		kstat_t			*ks;
   609 		iscsi_conn_stats_t	ks_data;
   686 		iscsi_conn_stats_t	ks_data;
   610 	} stats;
   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;
   611 
   701 
   612 	/*
   702 	/*
   613 	 * login min and max identify the amount of time
   703 	 * login min and max identify the amount of time
   614 	 * in lbolt that iscsi_start_login() should attempt
   704 	 * in lbolt that iscsi_start_login() should attempt
   615 	 * to log into a target portal.  The login will
   705 	 * to log into a target portal.  The login will
   619 	 * are also altered by async commands received from
   709 	 * are also altered by async commands received from
   620 	 * the targetlogin.
   710 	 * the targetlogin.
   621 	 */
   711 	 */
   622 	clock_t			conn_login_min;
   712 	clock_t			conn_login_min;
   623 	clock_t			conn_login_max;
   713 	clock_t			conn_login_max;
       
   714 	sm_audit_buf_t		conn_state_audit;
   624 } iscsi_conn_t;
   715 } iscsi_conn_t;
   625 
   716 
   626 
   717 
   627 /*
   718 /*
   628  * iscsi_conn_state - (reference iscsi_sess.c for state diagram)
   719  * iscsi_sess_state - (reference iscsi_sess.c for state diagram)
   629  */
   720  */
   630 typedef enum iscsi_sess_state {
   721 typedef enum iscsi_sess_state {
   631 	ISCSI_SESS_STATE_FREE,
   722 	ISCSI_SESS_STATE_FREE = 0,
   632 	ISCSI_SESS_STATE_LOGGED_IN,
   723 	ISCSI_SESS_STATE_LOGGED_IN,
   633 	ISCSI_SESS_STATE_FAILED,
   724 	ISCSI_SESS_STATE_FAILED,
   634 	ISCSI_SESS_STATE_IN_FLUSH,
   725 	ISCSI_SESS_STATE_IN_FLUSH,
   635 	ISCSI_SESS_STATE_FLUSHED
   726 	ISCSI_SESS_STATE_FLUSHED,
       
   727 	ISCSI_SESS_STATE_MAX
   636 } iscsi_sess_state_t;
   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
   637 
   740 
   638 #define	ISCSI_SESS_STATE_FULL_FEATURE(state) \
   741 #define	ISCSI_SESS_STATE_FULL_FEATURE(state) \
   639 	((state == ISCSI_SESS_STATE_LOGGED_IN) || \
   742 	((state == ISCSI_SESS_STATE_LOGGED_IN) || \
   640 	(state == ISCSI_SESS_STATE_IN_FLUSH))
   743 	(state == ISCSI_SESS_STATE_IN_FLUSH))
   641 
   744 
   642 
   745 
   643 typedef enum iscsi_sess_event {
   746 typedef enum iscsi_sess_event {
   644 	ISCSI_SESS_EVENT_N1,
   747 	ISCSI_SESS_EVENT_N1 = 0,
   645 	ISCSI_SESS_EVENT_N3,
   748 	ISCSI_SESS_EVENT_N3,
   646 	ISCSI_SESS_EVENT_N5,
   749 	ISCSI_SESS_EVENT_N5,
   647 	ISCSI_SESS_EVENT_N6,
   750 	ISCSI_SESS_EVENT_N6,
   648 	ISCSI_SESS_EVENT_N7
   751 	ISCSI_SESS_EVENT_N7,
       
   752 	ISCSI_SESS_EVENT_MAX
   649 } iscsi_sess_event_t;
   753 } iscsi_sess_event_t;
   650 
   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 
   651 typedef enum iscsi_sess_type {
   766 typedef enum iscsi_sess_type {
   652 	ISCSI_SESS_TYPE_NORMAL,
   767 	ISCSI_SESS_TYPE_NORMAL = 0,
   653 	ISCSI_SESS_TYPE_DISCOVERY
   768 	ISCSI_SESS_TYPE_DISCOVERY
   654 } iscsi_sess_type_t;
   769 } iscsi_sess_type_t;
   655 
   770 
   656 #define	SESS_ABORT_TASK_MAX_THREADS	1
   771 #define	SESS_ABORT_TASK_MAX_THREADS	1
   657 
   772 
   839 
   954 
   840 	ddi_taskq_t		*sess_taskq;
   955 	ddi_taskq_t		*sess_taskq;
   841 
   956 
   842 	iscsi_thread_t		*sess_wd_thread;
   957 	iscsi_thread_t		*sess_wd_thread;
   843 
   958 
       
   959 	sm_audit_buf_t		sess_state_audit;
   844 } iscsi_sess_t;
   960 } iscsi_sess_t;
   845 
   961 
   846 /*
   962 /*
   847  * This structure will be used to store sessions to be online
   963  * This structure will be used to store sessions to be online
   848  * during normal login operation.
   964  * during normal login operation.
   849  */
   965  */
   850 typedef struct iscsi_sess_list {
   966 typedef struct iscsi_sess_list {
   851 	iscsi_sess_t		*session;
   967 	iscsi_sess_t		*session;
   852 	struct iscsi_sess_list	*next;
   968 	struct iscsi_sess_list	*next;
   853 } iscsi_sess_list_t;
   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;
   854 
   979 
   855 /*
   980 /*
   856  * iscsi_network
   981  * iscsi_network
   857  */
   982  */
   858 typedef struct iscsi_network {
   983 typedef struct iscsi_network {
   904  */
  1029  */
   905 typedef struct iscsi_hba {
  1030 typedef struct iscsi_hba {
   906 	uint32_t		hba_sig;
  1031 	uint32_t		hba_sig;
   907 	dev_info_t		*hba_dip;	/* dev info ptr */
  1032 	dev_info_t		*hba_dip;	/* dev info ptr */
   908 	scsi_hba_tran_t		*hba_tran;	/* scsi tran ptr */
  1033 	scsi_hba_tran_t		*hba_tran;	/* scsi tran ptr */
       
  1034 	ldi_ident_t		hba_li;
   909 
  1035 
   910 	struct iscsi_sess	*hba_sess_list;	/* sess. list for hba */
  1036 	struct iscsi_sess	*hba_sess_list;	/* sess. list for hba */
   911 	krwlock_t		hba_sess_list_rwlock; /* protect sess. list */
  1037 	krwlock_t		hba_sess_list_rwlock; /* protect sess. list */
   912 
  1038 
   913 	/* lbolt of the last time we received a config request */
  1039 	/* lbolt of the last time we received a config request */
   963  * +--------------------------------------------------------------------+
  1089  * +--------------------------------------------------------------------+
   964  * | iSCSI prototypes							|
  1090  * | iSCSI prototypes							|
   965  * +--------------------------------------------------------------------+
  1091  * +--------------------------------------------------------------------+
   966  */
  1092  */
   967 
  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 
   968 /* iscsi_io.c */
  1102 /* iscsi_io.c */
   969 int iscsi_sna_lte(uint32_t n1, uint32_t n2);
  1103 int iscsi_sna_lte(uint32_t n1, uint32_t n2);
   970 char *iscsi_get_next_text(char *data, int data_length, char *curr_text);
  1104 char *iscsi_get_next_text(char *data, int data_length, char *curr_text);
   971 
  1105 
   972 void iscsi_ic_thread(iscsi_thread_t *thread, void *arg);
  1106 void iscsi_ic_thread(iscsi_thread_t *thread, void *arg);
   973 void iscsi_tx_thread(iscsi_thread_t *thread, void *arg);
  1107 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);
  1108 void iscsi_wd_thread(iscsi_thread_t *thread, void *arg);
   976 
  1109 
   977 iscsi_status_t iscsi_tx_cmd(iscsi_sess_t *isp, iscsi_cmd_t *icmdp);
  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);
   978 
  1113 
   979 void iscsi_handle_abort(void *arg);
  1114 void iscsi_handle_abort(void *arg);
   980 iscsi_status_t iscsi_handle_reset(iscsi_sess_t *isp, int level,
  1115 iscsi_status_t iscsi_handle_reset(iscsi_sess_t *isp, int level,
   981     iscsi_lun_t *ilp);
  1116     iscsi_lun_t *ilp);
   982 iscsi_status_t iscsi_handle_logout(iscsi_conn_t *icp);
  1117 iscsi_status_t iscsi_handle_logout(iscsi_conn_t *icp);
   997 void iscsi_destroy_queue(iscsi_queue_t *queue);
  1132 void iscsi_destroy_queue(iscsi_queue_t *queue);
   998 void iscsi_enqueue_pending_cmd(iscsi_sess_t *isp, iscsi_cmd_t *icmdp);
  1133 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);
  1134 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);
  1135 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);
  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);
  1002 void iscsi_enqueue_completed_cmd(iscsi_sess_t *isp, iscsi_cmd_t *icmdp);
  1139 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 *);
  1140 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);
  1141 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 **,
  1142 void iscsi_enqueue_cmd_head(iscsi_cmd_t **, iscsi_cmd_t **,
  1006     iscsi_cmd_t *);
  1143     iscsi_cmd_t *);
  1007 
  1144 
  1008 /* iscsi_login.c */
  1145 /* iscsi_login.c */
  1009 iscsi_status_t iscsi_login_start(void *arg);
  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 
  1010 
  1152 
  1011 /* iscsi_stats.c */
  1153 /* iscsi_stats.c */
  1012 boolean_t iscsi_hba_kstat_init(struct iscsi_hba	*ihp);
  1154 boolean_t iscsi_hba_kstat_init(struct iscsi_hba	*ihp);
  1013 boolean_t iscsi_hba_kstat_term(struct iscsi_hba	*ihp);
  1155 boolean_t iscsi_hba_kstat_term(struct iscsi_hba	*ihp);
  1014 boolean_t iscsi_sess_kstat_init(struct iscsi_sess *isp);
  1156 boolean_t iscsi_sess_kstat_init(struct iscsi_sess *isp);
  1017 void iscsi_conn_kstat_term(struct iscsi_conn *icp);
  1159 void iscsi_conn_kstat_term(struct iscsi_conn *icp);
  1018 
  1160 
  1019 /* iscsi_net.c */
  1161 /* iscsi_net.c */
  1020 void iscsi_net_init();
  1162 void iscsi_net_init();
  1021 void iscsi_net_fini();
  1163 void iscsi_net_fini();
       
  1164 iscsi_status_t iscsi_net_interface();
  1022 
  1165 
  1023 /* iscsi_sess.c */
  1166 /* iscsi_sess.c */
  1024 iscsi_sess_t *iscsi_sess_create(iscsi_hba_t *ihp,
  1167 iscsi_sess_t *iscsi_sess_create(iscsi_hba_t *ihp,
  1025     iSCSIDiscoveryMethod_t method, struct sockaddr *addr_dsc,
  1168     iSCSIDiscoveryMethod_t method, struct sockaddr *addr_dsc,
  1026     char *target_name, int tpgt, uchar_t isid_lsb,
  1169     char *target_name, int tpgt, uchar_t isid_lsb,
  1029 int iscsi_sess_get(uint32_t oid, iscsi_hba_t *ihp, iscsi_sess_t **ispp);
  1172 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);
  1173 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);
  1174 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);
  1175 char *iscsi_sess_state_str(iscsi_sess_state_t state);
  1033 boolean_t iscsi_sess_set_auth(iscsi_sess_t *isp);
  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);
  1034 iscsi_status_t iscsi_sess_reserve_itt(iscsi_sess_t *isp, iscsi_cmd_t *icmdp);
  1179 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);
  1180 void iscsi_sess_release_itt(iscsi_sess_t *isp, iscsi_cmd_t *icmdp);
  1036 void iscsi_sess_redrive_io(iscsi_sess_t *isp);
  1181 void iscsi_sess_redrive_io(iscsi_sess_t *isp);
  1037 int iscsi_sess_get_by_target(uint32_t target_oid, iscsi_hba_t *ihp,
  1182 int iscsi_sess_get_by_target(uint32_t target_oid, iscsi_hba_t *ihp,
  1038 	iscsi_sess_t **ispp);
  1183 	iscsi_sess_t **ispp);
  1039 
  1184 
  1040 
  1185 
  1041 /* iscsi_conn.c */
  1186 /* iscsi_conn.c */
  1042 iscsi_status_t iscsi_conn_create(struct sockaddr *addr, iscsi_sess_t *isp,
  1187 iscsi_status_t iscsi_conn_create(struct sockaddr *addr, iscsi_sess_t *isp,
  1043     iscsi_conn_t **icpp);
  1188     iscsi_conn_t **icpp);
       
  1189 iscsi_status_t iscsi_conn_online(iscsi_conn_t *icp);
  1044 iscsi_status_t iscsi_conn_offline(iscsi_conn_t *icp);
  1190 iscsi_status_t iscsi_conn_offline(iscsi_conn_t *icp);
  1045 iscsi_status_t iscsi_conn_destroy(iscsi_conn_t *icp);
  1191 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);
  1192 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);
  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);
  1051 
  1198 
  1052 /* iscsi_lun.c */
  1199 /* iscsi_lun.c */
  1053 iscsi_status_t iscsi_lun_create(iscsi_sess_t *isp, uint16_t lun_num,
  1200 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);
  1201     uint8_t lun_addr_type, struct scsi_inquiry *inq, char *guid);
  1055 iscsi_status_t iscsi_lun_destroy(iscsi_hba_t *ihp,
  1202 iscsi_status_t iscsi_lun_destroy(iscsi_hba_t *ihp,