145039663SJohn Forte /*
245039663SJohn Forte  * CDDL HEADER START
345039663SJohn Forte  *
445039663SJohn Forte  * The contents of this file are subject to the terms of the
545039663SJohn Forte  * Common Development and Distribution License (the "License").
645039663SJohn Forte  * You may not use this file except in compliance with the License.
745039663SJohn Forte  *
845039663SJohn Forte  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
945039663SJohn Forte  * or http://www.opensolaris.org/os/licensing.
1045039663SJohn Forte  * See the License for the specific language governing permissions
1145039663SJohn Forte  * and limitations under the License.
1245039663SJohn Forte  *
1345039663SJohn Forte  * When distributing Covered Code, include this CDDL HEADER in each
1445039663SJohn Forte  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1545039663SJohn Forte  * If applicable, add the following below this CDDL HEADER, with the
1645039663SJohn Forte  * fields enclosed by brackets "[]" replaced with your own identifying
1745039663SJohn Forte  * information: Portions Copyright [yyyy] [name of copyright owner]
1845039663SJohn Forte  *
1945039663SJohn Forte  * CDDL HEADER END
2045039663SJohn Forte  */
2145039663SJohn Forte /*
22*716c1805SNattuvetty Bhavyan  * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
2345039663SJohn Forte  */
2445039663SJohn Forte #ifndef _PPPT_H
2545039663SJohn Forte #define	_PPPT_H
2645039663SJohn Forte 
2745039663SJohn Forte #include <sys/pppt_ic_if.h>
2845039663SJohn Forte 
2945039663SJohn Forte #ifdef	__cplusplus
3045039663SJohn Forte extern "C" {
3145039663SJohn Forte #endif
3245039663SJohn Forte 
3345039663SJohn Forte #define	PPPT_GLOBAL_LOCK() mutex_enter(&pppt_global.global_lock)
3445039663SJohn Forte #define	PPPT_GLOBAL_UNLOCK() mutex_exit(&pppt_global.global_lock)
3545039663SJohn Forte 
3645039663SJohn Forte extern int pppt_logging;
3745039663SJohn Forte 
3845039663SJohn Forte #define	PPPT_LOG if (pppt_logging) cmn_err
3945039663SJohn Forte 
4045039663SJohn Forte #define	TGT_DEREG_RETRY_SECONDS	1
4145039663SJohn Forte 
4245039663SJohn Forte typedef enum {
4345039663SJohn Forte 	PPPT_STATUS_SUCCESS = 0,
4445039663SJohn Forte 	PPPT_STATUS_FAIL,
4545039663SJohn Forte 	PPPT_STATUS_ABORTED,
4645039663SJohn Forte 	PPPT_STATUS_DONE
4745039663SJohn Forte } pppt_status_t;
4845039663SJohn Forte 
4945039663SJohn Forte #define	PPPT_MODNAME "pppt"
5045039663SJohn Forte 
5145039663SJohn Forte /* Target states and events, update pppt_ts_name table whenever modified */
5245039663SJohn Forte typedef enum {
5345039663SJohn Forte 	TS_UNDEFINED = 0,
5445039663SJohn Forte 	TS_CREATED,
5545039663SJohn Forte 	TS_ONLINING,
5645039663SJohn Forte 	TS_ONLINE,
5745039663SJohn Forte 	TS_STMF_ONLINE,
5845039663SJohn Forte 	TS_DELETING_NEED_OFFLINE,
5945039663SJohn Forte 	TS_OFFLINING,
6045039663SJohn Forte 	TS_OFFLINE,
6145039663SJohn Forte 	TS_STMF_OFFLINE,
6245039663SJohn Forte 	TS_DELETING_STMF_DEREG,
6345039663SJohn Forte 	TS_DELETING_STMF_DEREG_FAIL,
6445039663SJohn Forte 	TS_DELETING,
6545039663SJohn Forte 	TS_MAX_STATE
6645039663SJohn Forte } pppt_tgt_state_t;
6745039663SJohn Forte 
6845039663SJohn Forte #ifdef PPPT_TGT_SM_STRINGS
6945039663SJohn Forte static const char *pppt_ts_name[TS_MAX_STATE+1] = {
7045039663SJohn Forte 	"TS_UNDEFINED",
7145039663SJohn Forte 	"TS_CREATED",
7245039663SJohn Forte 	"TS_ONLINING",
7345039663SJohn Forte 	"TS_ONLINE",
7445039663SJohn Forte 	"TS_STMF_ONLINE",
7545039663SJohn Forte 	"TS_DELETING_NEED_OFFLINE",
7645039663SJohn Forte 	"TS_OFFLINING",
7745039663SJohn Forte 	"TS_OFFLINE",
7845039663SJohn Forte 	"TS_STMF_OFFLINE",
7945039663SJohn Forte 	"TS_DELETING_STMF_DEREG",
8045039663SJohn Forte 	"TS_DELETING_STMF_DEREG_FAIL",
8145039663SJohn Forte 	"TS_DELETING",
8245039663SJohn Forte 	"TS_MAX_STATE"
8345039663SJohn Forte };
8445039663SJohn Forte #endif
8545039663SJohn Forte 
8645039663SJohn Forte typedef enum {
8745039663SJohn Forte 	TE_UNDEFINED = 0,
8845039663SJohn Forte 	TE_STMF_ONLINE_REQ,
8945039663SJohn Forte 	TE_ONLINE_SUCCESS,
9045039663SJohn Forte 	TE_ONLINE_FAIL,
9145039663SJohn Forte 	TE_STMF_ONLINE_COMPLETE_ACK,
9245039663SJohn Forte 	TE_STMF_OFFLINE_REQ,
9345039663SJohn Forte 	TE_OFFLINE_COMPLETE,
9445039663SJohn Forte 	TE_STMF_OFFLINE_COMPLETE_ACK,
9545039663SJohn Forte 	TE_DELETE,
9645039663SJohn Forte 	TE_STMF_DEREG_SUCCESS,
9745039663SJohn Forte 	TE_STMF_DEREG_FAIL,
9845039663SJohn Forte 	TE_STMF_DEREG_RETRY,
9945039663SJohn Forte 	TE_WAIT_REF_COMPLETE, /* XXX */
10045039663SJohn Forte 	TE_MAX_EVENT
10145039663SJohn Forte } pppt_tgt_event_t;
10245039663SJohn Forte 
10345039663SJohn Forte #ifdef PPPT_TGT_SM_STRINGS
10445039663SJohn Forte static const char *pppt_te_name[TE_MAX_EVENT+1] = {
10545039663SJohn Forte 	"TE_UNDEFINED",
10645039663SJohn Forte 	"TE_STMF_ONLINE_REQ",
10745039663SJohn Forte 	"TE_ONLINE_SUCCESS",
10845039663SJohn Forte 	"TE_ONLINE_FAIL",
10945039663SJohn Forte 	"TE_STMF_ONLINE_COMPLETE_ACK",
11045039663SJohn Forte 	"TE_STMF_OFFLINE_REQ",
11145039663SJohn Forte 	"TE_OFFLINE_COMPLETE",
11245039663SJohn Forte 	"TE_STMF_OFFLINE_COMPLETE_ACK",
11345039663SJohn Forte 	"TE_DELETE",
11445039663SJohn Forte 	"TE_STMF_DEREG_SUCCESS",
11545039663SJohn Forte 	"TE_STMF_DEREG_FAIL",
11645039663SJohn Forte 	"TE_STMF_DEREG_RETRY",
11745039663SJohn Forte 	"TE_WAIT_REF_COMPLETE",
11845039663SJohn Forte 	"TE_MAX_EVENT"
11945039663SJohn Forte };
12045039663SJohn Forte #endif
12145039663SJohn Forte 
12245039663SJohn Forte typedef struct pppt_tgt_s {
12345039663SJohn Forte 	kmutex_t		target_mutex;
12445039663SJohn Forte 	kcondvar_t		target_cv;
12545039663SJohn Forte 	avl_node_t		target_global_ln;
12645039663SJohn Forte 	scsi_devid_desc_t	*target_devid;
12745039663SJohn Forte 	stmf_local_port_t	*target_stmf_lport;
12845039663SJohn Forte 	avl_tree_t		target_sess_list;
12945039663SJohn Forte 
13045039663SJohn Forte 	/* Target state */
13145039663SJohn Forte 	boolean_t		target_sm_busy;
13245039663SJohn Forte 	boolean_t		target_deleting;
13345039663SJohn Forte 	pppt_tgt_state_t	target_state;
13445039663SJohn Forte 	pppt_tgt_state_t	target_last_state;
13545039663SJohn Forte 	int			target_refcount;
13645039663SJohn Forte 	list_t			target_events;
13745039663SJohn Forte } pppt_tgt_t;
13845039663SJohn Forte 
13945039663SJohn Forte typedef struct {
14045039663SJohn Forte 	struct pppt_tgt_s	*ps_target;
14145039663SJohn Forte 	uint64_t		ps_session_id;
14245039663SJohn Forte 	int			ps_refcnt;
14345039663SJohn Forte 	kmutex_t		ps_mutex;
14445039663SJohn Forte 	kcondvar_t		ps_cv;
14545039663SJohn Forte 	boolean_t		ps_closed;
14645039663SJohn Forte 	avl_node_t		ps_global_ln;
14745039663SJohn Forte 	avl_node_t		ps_target_ln;
14845039663SJohn Forte 	avl_tree_t		ps_task_list;
14945039663SJohn Forte 	stmf_scsi_session_t	*ps_stmf_sess;
15045039663SJohn Forte } pppt_sess_t;
15145039663SJohn Forte 
15245039663SJohn Forte typedef struct {
15345039663SJohn Forte 	stmf_data_buf_t		*pbuf_stmf_buf;
15445039663SJohn Forte 	boolean_t		pbuf_is_immed;
15545039663SJohn Forte 	stmf_ic_msg_t		*pbuf_immed_msg;
15645039663SJohn Forte } pppt_buf_t;
15745039663SJohn Forte 
15845039663SJohn Forte typedef enum {
15945039663SJohn Forte 	PTS_INIT = 0,
16045039663SJohn Forte 	PTS_ACTIVE,
16145039663SJohn Forte 	PTS_DONE,
16245039663SJohn Forte 	PTS_SENT_STATUS,
16345039663SJohn Forte 	PTS_ABORTED
16445039663SJohn Forte } pppt_task_state_t;
16545039663SJohn Forte 
16645039663SJohn Forte typedef struct {
16745039663SJohn Forte 	pppt_sess_t		*pt_sess;
16845039663SJohn Forte 	avl_node_t		pt_sess_ln;
16945039663SJohn Forte 	int			pt_refcnt;
17045039663SJohn Forte 	kmutex_t		pt_mutex;
17145039663SJohn Forte 	kcondvar_t		pt_cv;
17245039663SJohn Forte 	stmf_ic_msgid_t		pt_task_id;
17345039663SJohn Forte 	uint8_t			pt_lun_id[16];
17445039663SJohn Forte 	pppt_task_state_t	pt_state;
17545039663SJohn Forte 	scsi_task_t		*pt_stmf_task;
17645039663SJohn Forte 	pppt_buf_t		*pt_immed_data;
17745039663SJohn Forte 	pppt_buf_t		*pt_read_buf;
17845039663SJohn Forte 	stmf_ic_msgid_t		pt_read_xfer_msgid;
17945039663SJohn Forte } pppt_task_t;
18045039663SJohn Forte 
18145039663SJohn Forte /*
18245039663SJohn Forte  * Error statistics
18345039663SJohn Forte  */
18445039663SJohn Forte typedef struct {
18545039663SJohn Forte 	uint64_t		es_tgt_reg_svc_disabled;
18645039663SJohn Forte 	uint64_t		es_tgt_reg_duplicate;
18745039663SJohn Forte 	uint64_t		es_tgt_reg_create_fail;
18845039663SJohn Forte 	uint64_t		es_tgt_dereg_svc_disabled;
18945039663SJohn Forte 	uint64_t		es_tgt_dereg_not_found;
19045039663SJohn Forte 	uint64_t		es_sess_destroy_no_session;
19145039663SJohn Forte 	uint64_t		es_sess_lookup_no_session;
19245039663SJohn Forte 	uint64_t		es_sess_lookup_ident_mismatch;
19345039663SJohn Forte 	uint64_t		es_sess_lookup_bad_tgt_state;
19445039663SJohn Forte 	uint64_t		es_scmd_ptask_alloc_fail;
19545039663SJohn Forte 	uint64_t		es_scmd_sess_create_fail;
19645039663SJohn Forte 	uint64_t		es_scmd_stask_alloc_fail;
19745039663SJohn Forte 	uint64_t		es_scmd_dup_task_count;
19845039663SJohn Forte } pppt_error_stats_t;
19945039663SJohn Forte 
20045039663SJohn Forte #define	PPPT_INC_STAT(stat_field) \
20145039663SJohn Forte 	atomic_inc_64(&pppt_global.global_error_stats.stat_field);
20245039663SJohn Forte 
20345039663SJohn Forte /*
20445039663SJohn Forte  * State values for the iscsit service
20545039663SJohn Forte  */
20645039663SJohn Forte typedef enum {
20745039663SJohn Forte 	PSS_UNDEFINED = 0,
20845039663SJohn Forte 	PSS_DETACHED,
20945039663SJohn Forte 	PSS_DISABLED,
21045039663SJohn Forte 	PSS_ENABLING,
21145039663SJohn Forte 	PSS_ENABLED,
21245039663SJohn Forte 	PSS_BUSY,
21345039663SJohn Forte 	PSS_DISABLING
21445039663SJohn Forte } pppt_service_state_t;
21545039663SJohn Forte 
21645039663SJohn Forte 
21745039663SJohn Forte typedef struct {
21845039663SJohn Forte 	pppt_service_state_t	global_svc_state;
21945039663SJohn Forte 	dev_info_t		*global_dip;
22045039663SJohn Forte 	stmf_port_provider_t	*global_pp;
22145039663SJohn Forte 	stmf_dbuf_store_t	*global_dbuf_store;
22245039663SJohn Forte 	taskq_t			*global_dispatch_taskq;
22345039663SJohn Forte 	taskq_t			*global_sess_taskq;
22445039663SJohn Forte 	avl_tree_t		global_sess_list;
22545039663SJohn Forte 	avl_tree_t		global_target_list;
22645039663SJohn Forte 	kmutex_t		global_lock;
22745039663SJohn Forte 	door_handle_t		global_door;
22845039663SJohn Forte 	kmutex_t		global_door_lock;
22945039663SJohn Forte 	pppt_error_stats_t	global_error_stats;
23045039663SJohn Forte } pppt_global_t;
23145039663SJohn Forte 
23245039663SJohn Forte extern pppt_global_t pppt_global;
23345039663SJohn Forte 
23445039663SJohn Forte stmf_status_t pppt_lport_xfer_data(scsi_task_t *task, stmf_data_buf_t *dbuf,
23545039663SJohn Forte     uint32_t ioflags);
23645039663SJohn Forte 
23745039663SJohn Forte void pppt_xfer_read_complete(pppt_task_t *pppt_task, stmf_status_t status);
23845039663SJohn Forte 
23945039663SJohn Forte stmf_status_t pppt_lport_send_status(scsi_task_t *task, uint32_t ioflags);
24045039663SJohn Forte 
24145039663SJohn Forte void pppt_lport_task_free(scsi_task_t *task);
24245039663SJohn Forte 
24345039663SJohn Forte stmf_status_t pppt_lport_abort(stmf_local_port_t *lport, int abort_cmd,
24445039663SJohn Forte     void *arg, uint32_t flags);
24545039663SJohn Forte 
24645039663SJohn Forte void pppt_lport_ctl(stmf_local_port_t *lport, int cmd, void *arg);
24745039663SJohn Forte 
24845039663SJohn Forte pppt_sess_t *pppt_sess_lookup_locked(uint64_t session_id,
24945039663SJohn Forte     scsi_devid_desc_t *lport_devid,
250*716c1805SNattuvetty Bhavyan     stmf_remote_port_t *rport);
25145039663SJohn Forte 
25245039663SJohn Forte pppt_sess_t *pppt_sess_lookup_by_id_locked(uint64_t session_id);
25345039663SJohn Forte 
25445039663SJohn Forte pppt_sess_t *pppt_sess_lookup_create(scsi_devid_desc_t *lport_devid,
255*716c1805SNattuvetty Bhavyan     scsi_devid_desc_t *rport_devid, stmf_remote_port_t *rport,
256*716c1805SNattuvetty Bhavyan     uint64_t session_id, stmf_status_t *statusp);
25745039663SJohn Forte 
25845039663SJohn Forte void pppt_sess_rele(pppt_sess_t *sks);
25945039663SJohn Forte 
26045039663SJohn Forte void pppt_sess_rele_locked(pppt_sess_t *sks);
26145039663SJohn Forte 
26245039663SJohn Forte void pppt_sess_close_locked(pppt_sess_t *ps);
26345039663SJohn Forte 
26445039663SJohn Forte int pppt_sess_avl_compare_by_id(const void *void_sess1,
26545039663SJohn Forte     const void *void_sess2);
26645039663SJohn Forte 
26745039663SJohn Forte int pppt_sess_avl_compare_by_name(const void *void_sess1,
26845039663SJohn Forte     const void *void_sess2);
26945039663SJohn Forte 
27045039663SJohn Forte pppt_task_t *pppt_task_alloc(void);
27145039663SJohn Forte 
27245039663SJohn Forte void pppt_task_free(pppt_task_t *ptask);
27345039663SJohn Forte 
27445039663SJohn Forte pppt_status_t pppt_task_start(pppt_task_t *ptask);
27545039663SJohn Forte 
27645039663SJohn Forte pppt_status_t pppt_task_done(pppt_task_t *ptask);
27745039663SJohn Forte 
27845039663SJohn Forte pppt_task_t *pppt_task_lookup(stmf_ic_msgid_t msgid);
27945039663SJohn Forte 
28045039663SJohn Forte void pppt_msg_rx(stmf_ic_msg_t *msg);
28145039663SJohn Forte 
28245039663SJohn Forte void pppt_msg_tx_status(stmf_ic_msg_t *orig_msg, stmf_status_t status);
28345039663SJohn Forte 
28445039663SJohn Forte pppt_tgt_t *pppt_tgt_lookup(scsi_devid_desc_t *tgt_devid);
28545039663SJohn Forte 
28645039663SJohn Forte pppt_tgt_t *pppt_tgt_lookup_locked(scsi_devid_desc_t *tgt_devid);
28745039663SJohn Forte 
28845039663SJohn Forte pppt_tgt_t *pppt_tgt_create(stmf_ic_reg_port_msg_t *reg_port,
28945039663SJohn Forte     stmf_status_t *errcode);
29045039663SJohn Forte 
29145039663SJohn Forte void pppt_tgt_async_delete(pppt_tgt_t *tgt);
29245039663SJohn Forte 
29345039663SJohn Forte void pppt_tgt_destroy(pppt_tgt_t *tgt);
29445039663SJohn Forte 
29545039663SJohn Forte int pppt_tgt_avl_compare(const void *void_tgt1, const void *void_tgt2);
29645039663SJohn Forte 
29745039663SJohn Forte void pppt_tgt_sm_ctl(stmf_local_port_t *lport, int cmd, void *arg);
29845039663SJohn Forte 
29945039663SJohn Forte #ifdef	__cplusplus
30045039663SJohn Forte }
30145039663SJohn Forte #endif
30245039663SJohn Forte 
30345039663SJohn Forte #endif	/* _PPPT_H */
304