1fcf3ce44SJohn Forte /*
2fcf3ce44SJohn Forte  * CDDL HEADER START
3fcf3ce44SJohn Forte  *
4fcf3ce44SJohn Forte  * The contents of this file are subject to the terms of the
5fcf3ce44SJohn Forte  * Common Development and Distribution License (the "License").
6fcf3ce44SJohn Forte  * You may not use this file except in compliance with the License.
7fcf3ce44SJohn Forte  *
8fcf3ce44SJohn Forte  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9fcf3ce44SJohn Forte  * or http://www.opensolaris.org/os/licensing.
10fcf3ce44SJohn Forte  * See the License for the specific language governing permissions
11fcf3ce44SJohn Forte  * and limitations under the License.
12fcf3ce44SJohn Forte  *
13fcf3ce44SJohn Forte  * When distributing Covered Code, include this CDDL HEADER in each
14fcf3ce44SJohn Forte  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15fcf3ce44SJohn Forte  * If applicable, add the following below this CDDL HEADER, with the
16fcf3ce44SJohn Forte  * fields enclosed by brackets "[]" replaced with your own identifying
17fcf3ce44SJohn Forte  * information: Portions Copyright [yyyy] [name of copyright owner]
18fcf3ce44SJohn Forte  *
19fcf3ce44SJohn Forte  * CDDL HEADER END
20fcf3ce44SJohn Forte  */
21fcf3ce44SJohn Forte /*
22*c946facaSallan  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
23fcf3ce44SJohn Forte  * Use is subject to license terms.
24fcf3ce44SJohn Forte  */
25fcf3ce44SJohn Forte #ifndef	_FCT_IMPL_H
26fcf3ce44SJohn Forte #define	_FCT_IMPL_H
27fcf3ce44SJohn Forte 
28fcf3ce44SJohn Forte #ifdef	__cplusplus
29fcf3ce44SJohn Forte extern "C" {
30fcf3ce44SJohn Forte #endif
31fcf3ce44SJohn Forte 
32fcf3ce44SJohn Forte #define	RSCN_OPTION_VERIFY	0x0001
33fcf3ce44SJohn Forte 
34fcf3ce44SJohn Forte typedef enum fct_li_state {
35fcf3ce44SJohn Forte 	LI_STATE_DO_FLOGI = 0,	/* FLOGI handled by FCA */
36fcf3ce44SJohn Forte 	LI_STATE_FINI_TOPOLOGY,	/* Finalize topology */
37fcf3ce44SJohn Forte 	LI_STATE_N2N_PLOGI,	/* In case of a N2N connection */
38fcf3ce44SJohn Forte 
39fcf3ce44SJohn Forte 	LI_STATE_DO_FCLOGIN,	/* Login into 0xFFFFFD */
40fcf3ce44SJohn Forte 	LI_STATE_DO_SCR,	/* State change registration */
41fcf3ce44SJohn Forte 
42fcf3ce44SJohn Forte 	LI_STATE_DO_NSLOGIN,	/* Login into 0xFFFFFC */
43fcf3ce44SJohn Forte 	LI_STATE_DO_RNN,	/* Register node name */
44fcf3ce44SJohn Forte 	LI_STATE_DO_RCS,	/* Register classes of service */
45fcf3ce44SJohn Forte 	LI_STATE_DO_RFT,	/* Register FC-4 types */
46fcf3ce44SJohn Forte 	LI_STATE_DO_RSPN,	/* Register symbolic port name */
47fcf3ce44SJohn Forte 	LI_STATE_DO_RSNN,	/* Register symbolic node name */
48fcf3ce44SJohn Forte 
49fcf3ce44SJohn Forte 	LI_STATE_MAX		/* Not a real state */
50fcf3ce44SJohn Forte } fct_li_state_t;
51fcf3ce44SJohn Forte 
52fcf3ce44SJohn Forte #define	LI_STATE_START			0
53fcf3ce44SJohn Forte #define	LI_STATE_MASK			0x3F
54fcf3ce44SJohn Forte /* Next state depends on the return value */
55fcf3ce44SJohn Forte #define	LI_STATE_FLAG_CMD_RETCHECK	0x40
56fcf3ce44SJohn Forte /* Link init cmd is still outstanding */
57fcf3ce44SJohn Forte #define	LI_STATE_FLAG_CMD_WAITING	0x80
58fcf3ce44SJohn Forte /* Flag to indicate that link info is not available yet */
59fcf3ce44SJohn Forte #define	LI_STATE_FLAG_NO_LI_YET		0x100
60fcf3ce44SJohn Forte 
61fcf3ce44SJohn Forte #define	FCT_MAX_CACHED_CMDS	256
62fcf3ce44SJohn Forte #define	USEC_ELS_TIMEOUT	(10 * 1000 * 1000)
63fcf3ce44SJohn Forte #define	USEC_SOL_TIMEOUT	(10 * 1000 * 1000)
64fcf3ce44SJohn Forte #define	USEC_DEREG_RP_TIMEOUT	(25 * 1000 * 1000)
65fcf3ce44SJohn Forte #define	USEC_DEREG_RP_INTERVAL	(2 * 1000 * 1000)
66fcf3ce44SJohn Forte 
67fcf3ce44SJohn Forte struct fct_i_cmd;
68fcf3ce44SJohn Forte typedef void (* fct_icmd_cb_t)(struct fct_i_cmd *icmd);
69fcf3ce44SJohn Forte typedef struct fct_i_cmd {
70fcf3ce44SJohn Forte 	fct_cmd_t		*icmd_cmd;
71fcf3ce44SJohn Forte 	uint32_t		 icmd_alloc_size;
72fcf3ce44SJohn Forte 	fct_struct_id_t		 icmd_struct_id;
73fcf3ce44SJohn Forte 	uint32_t		 icmd_flags;
74fcf3ce44SJohn Forte 	clock_t			 icmd_start_time;
75fcf3ce44SJohn Forte 	struct fct_i_cmd	*icmd_next;	/* iport_abort_queue and irp */
76fcf3ce44SJohn Forte 	struct fct_i_cmd	*icmd_solcmd_next;	/* iport_solcmd_queue */
77fcf3ce44SJohn Forte 	fct_icmd_cb_t		 icmd_cb;
78fcf3ce44SJohn Forte 	void			*icmd_cb_private;
79fcf3ce44SJohn Forte } fct_i_cmd_t;
80fcf3ce44SJohn Forte 
81fcf3ce44SJohn Forte /*
82fcf3ce44SJohn Forte  * icmd_flags
83fcf3ce44SJohn Forte  */
84fcf3ce44SJohn Forte #define	ICMD_SESSION_AFFECTING		0x0002
85fcf3ce44SJohn Forte #define	ICMD_IN_IRP_QUEUE		0x0004
86fcf3ce44SJohn Forte #define	ICMD_BEING_ABORTED		0x0008
87fcf3ce44SJohn Forte #define	ICMD_KNOWN_TO_FCA		0x0020
88fcf3ce44SJohn Forte #define	ICMD_FCA_ABORT_CALLED		0x0040
89fcf3ce44SJohn Forte #define	ICMD_CMD_COMPLETE		0x0080
90fcf3ce44SJohn Forte #define	ICMD_IN_TRANSITION		0x0100
91fcf3ce44SJohn Forte #define	ICMD_ABTS_RECEIVED		0x0200
92fcf3ce44SJohn Forte #define	ICMD_IMPLICIT			0x0400
93fcf3ce44SJohn Forte #define	ICMD_IMPLICIT_CMD_HAS_RESOURCE	0x0800
94fcf3ce44SJohn Forte /* High order are debug flags */
95fcf3ce44SJohn Forte #define	ICMD_ELS_PROCESSING_STARTED	0x80000000
96fcf3ce44SJohn Forte 
97fcf3ce44SJohn Forte /*
98fcf3ce44SJohn Forte  * For solicited commands, there's only 3 states:
99fcf3ce44SJohn Forte  * 1) it's new. We need send it to FCA. ICMD_SOLCMD_NEW is set
100fcf3ce44SJohn Forte  * 2) it's running. We are waiting for completion.
101fcf3ce44SJohn Forte  * 3) it's completed. We need free it. ICMD_CMD_COMPLETE is set
102fcf3ce44SJohn Forte  * ICMD_SOLCMD_NEW and ICMD_CMD_COMPLETE should not be set in the same time
103fcf3ce44SJohn Forte  */
104fcf3ce44SJohn Forte #define	ICMD_IN_SOLCMD_QUEUE		0x010000
105fcf3ce44SJohn Forte #define	ICMD_SOLCMD_NEW			0x020000
106fcf3ce44SJohn Forte 
107fcf3ce44SJohn Forte typedef struct fct_i_remote_port {
108fcf3ce44SJohn Forte 	fct_remote_port_t		*irp_rp;
109fcf3ce44SJohn Forte 	uint32_t			irp_alloc_size;
110fcf3ce44SJohn Forte 	fct_struct_id_t			irp_struct_id;
111fcf3ce44SJohn Forte 	krwlock_t			irp_lock;
112fcf3ce44SJohn Forte 
113fcf3ce44SJohn Forte 	/* For queueing to local port */
114fcf3ce44SJohn Forte 	struct fct_i_remote_port	*irp_next;
115fcf3ce44SJohn Forte 
116fcf3ce44SJohn Forte 	/* For queueing to handle elses */
117fcf3ce44SJohn Forte 	struct fct_i_remote_port	*irp_discovery_next;
118fcf3ce44SJohn Forte 
119fcf3ce44SJohn Forte 	fct_i_cmd_t			*irp_els_list;
120fcf3ce44SJohn Forte 
121fcf3ce44SJohn Forte 	/*
122fcf3ce44SJohn Forte 	 * sa stands for session affecting, nsa is non session affecting.
123fcf3ce44SJohn Forte 	 * The els counts only represent elses under progress not the ones
124fcf3ce44SJohn Forte 	 * that are terminated. active_xchg_count covers everything including
125fcf3ce44SJohn Forte 	 * the ones waiting to be terminated.
126fcf3ce44SJohn Forte 	 */
127fcf3ce44SJohn Forte 	uint16_t			irp_sa_elses_count;
128fcf3ce44SJohn Forte 	uint16_t			irp_nsa_elses_count;
129fcf3ce44SJohn Forte 	uint16_t			irp_fcp_xchg_count;
130fcf3ce44SJohn Forte 	uint16_t			irp_nonfcp_xchg_count;
131fcf3ce44SJohn Forte 
132fcf3ce44SJohn Forte 	uint32_t			irp_flags;
133fcf3ce44SJohn Forte 	clock_t				irp_deregister_timer;
134fcf3ce44SJohn Forte 	uint32_t			irp_dereg_count;
135fcf3ce44SJohn Forte 
136fcf3ce44SJohn Forte 	uint32_t			irp_portid;
137fcf3ce44SJohn Forte 	uint8_t				irp_id[24];
138fcf3ce44SJohn Forte 	uint32_t			irp_rcvd_prli_params;
139fcf3ce44SJohn Forte 	uint32_t			irp_sent_prli_params;
140fcf3ce44SJohn Forte 
141fcf3ce44SJohn Forte 	/*
142fcf3ce44SJohn Forte 	 * Most HBAs will only register symbolic node name instead of port name,
143fcf3ce44SJohn Forte 	 * so we use SNN as session alias.
144fcf3ce44SJohn Forte 	 */
145fcf3ce44SJohn Forte 	stmf_scsi_session_t		*irp_session;
146fcf3ce44SJohn Forte 	char				*irp_snn;
147fcf3ce44SJohn Forte 
148fcf3ce44SJohn Forte 	/* items will be filled in ns cmd */
149fcf3ce44SJohn Forte 	uint8_t				irp_fc4types[32]; /* FC-4 types */
150fcf3ce44SJohn Forte 	char				*irp_spn;	/* port symbolic name */
151fcf3ce44SJohn Forte 	uint32_t			irp_cos;	/* class of service */
152fcf3ce44SJohn Forte 
153fcf3ce44SJohn Forte 	uint32_t			irp_rscn_counter;
154fcf3ce44SJohn Forte } fct_i_remote_port_t;
155fcf3ce44SJohn Forte 
156*c946facaSallan /*
157*c946facaSallan  * structure used for fct_rls_cb() callback private data
158*c946facaSallan  */
159*c946facaSallan typedef struct fct_rls_cb_data {
160*c946facaSallan 	struct fct_port_link_status	*fct_link_status;
161*c946facaSallan 	fct_status_t			fct_els_res;
162*c946facaSallan } fct_rls_cb_data_t;
163*c946facaSallan 
164fcf3ce44SJohn Forte /*
165fcf3ce44SJohn Forte  * irp flags
166fcf3ce44SJohn Forte  */
167fcf3ce44SJohn Forte #define	IRP_PLOGI_DONE			0x0001
168fcf3ce44SJohn Forte #define	IRP_PRLI_DONE			0x0002
169fcf3ce44SJohn Forte #define	IRP_IN_DISCOVERY_QUEUE		0x0004
170fcf3ce44SJohn Forte #define	IRP_FCP_CLEANUP			0x0008
171fcf3ce44SJohn Forte #define	IRP_SESSION_CLEANUP		(IRP_FCP_CLEANUP | 0x0010)
172fcf3ce44SJohn Forte #define	IRP_HANDLE_OPENED		0x0020
173fcf3ce44SJohn Forte #define	IRP_SCSI_SESSION_STARTED	0x0040
174fcf3ce44SJohn Forte #define	IRP_RSCN_QUEUED			0x0080
175fcf3ce44SJohn Forte #define	IRP_SOL_PLOGI_IN_PROGRESS	0x0100
176fcf3ce44SJohn Forte 
177fcf3ce44SJohn Forte typedef struct fct_cmd_slot {
178fcf3ce44SJohn Forte 	fct_i_cmd_t		*slot_cmd;
179fcf3ce44SJohn Forte 	uint16_t		slot_no;
180fcf3ce44SJohn Forte 	uint16_t		slot_next;
181fcf3ce44SJohn Forte 	uint8_t			slot_uniq_cntr;
182fcf3ce44SJohn Forte } fct_cmd_slot_t;
183fcf3ce44SJohn Forte #define	FCT_SLOT_EOL		0xffff
184fcf3ce44SJohn Forte 
185fcf3ce44SJohn Forte #define	FCT_HASH_TABLE_SIZE		256
186fcf3ce44SJohn Forte #define	FCT_LOOP_HASH(portid)		(portid & 0xff)
187fcf3ce44SJohn Forte #define	FCT_FABRIC_HASH(portid)		(((portid & 0x1f00) | \
188fcf3ce44SJohn Forte 	((portid & 0x70000)>>3)) >> 8)
189fcf3ce44SJohn Forte #define	FCT_PORTID_HASH_FUNC(portid) \
190fcf3ce44SJohn Forte 	((portid & 0xFFFF00)?FCT_FABRIC_HASH(portid):FCT_LOOP_HASH(portid))
191fcf3ce44SJohn Forte 
192fcf3ce44SJohn Forte typedef struct fct_i_local_port {
193fcf3ce44SJohn Forte 	fct_local_port_t	*iport_port;
194fcf3ce44SJohn Forte 	uint32_t		iport_alloc_size;
195fcf3ce44SJohn Forte 	fct_struct_id_t		iport_struct_id;
196fcf3ce44SJohn Forte 
197fcf3ce44SJohn Forte 	struct fct_i_local_port	*iport_next;
198fcf3ce44SJohn Forte 	struct fct_i_local_port	*iport_prev;
199fcf3ce44SJohn Forte 
200fcf3ce44SJohn Forte 	char			*iport_alias;
201fcf3ce44SJohn Forte 	char			iport_alias_mem[16];
202fcf3ce44SJohn Forte 	uint8_t			iport_id[24];	/* scsi_devid_desc_t */
203fcf3ce44SJohn Forte 	krwlock_t		iport_lock;
204fcf3ce44SJohn Forte 	uint32_t		iport_flags;
205fcf3ce44SJohn Forte 	uint16_t		iport_link_state;
206fcf3ce44SJohn Forte 	uint8_t			iport_state:7,
207fcf3ce44SJohn Forte 	    iport_state_not_acked:1;
208fcf3ce44SJohn Forte 	uint8_t			iport_offline_prstate;
209fcf3ce44SJohn Forte 	struct fct_link_info	iport_link_info;
210fcf3ce44SJohn Forte 
211fcf3ce44SJohn Forte 	fct_i_remote_port_t	**iport_rp_slots;
212fcf3ce44SJohn Forte 	fct_i_remote_port_t	**iport_rp_tb;
213fcf3ce44SJohn Forte 	uint32_t		iport_nrps_login; /* currently logged in */
214fcf3ce44SJohn Forte 	uint32_t		iport_nrps;	/* items in hash table */
215fcf3ce44SJohn Forte 	uint64_t		iport_last_change;
216fcf3ce44SJohn Forte 
217fcf3ce44SJohn Forte 	/*
218fcf3ce44SJohn Forte 	 * These variables are used to manage fct_cmd_t cache for SCSI traffic
219fcf3ce44SJohn Forte 	 */
220fcf3ce44SJohn Forte 	/*
221fcf3ce44SJohn Forte 	 * Total # of cmds allocated by the driver. Some of which are free
222fcf3ce44SJohn Forte 	 * and sitting on iport_cached_cmdlist. And some are executing.
223fcf3ce44SJohn Forte 	 */
224fcf3ce44SJohn Forte 	uint32_t		iport_total_alloced_ncmds;
225fcf3ce44SJohn Forte 
226fcf3ce44SJohn Forte 	/*
227fcf3ce44SJohn Forte 	 * Max active cmds in last interval (10 or 30 seconds)
228fcf3ce44SJohn Forte 	 */
229fcf3ce44SJohn Forte 	uint32_t		iport_max_active_ncmds;
230fcf3ce44SJohn Forte 
231fcf3ce44SJohn Forte 	/*
232fcf3ce44SJohn Forte 	 * # of free cmds sitting on the iport_cached_cmdlist
233fcf3ce44SJohn Forte 	 */
234fcf3ce44SJohn Forte 	uint32_t		iport_cached_ncmds;
235fcf3ce44SJohn Forte 	struct fct_i_cmd	*iport_cached_cmdlist;
236fcf3ce44SJohn Forte 	kmutex_t		iport_cached_cmd_lock;
237fcf3ce44SJohn Forte 
238fcf3ce44SJohn Forte 	/*
239fcf3ce44SJohn Forte 	 * To release free cmds periodically
240fcf3ce44SJohn Forte 	 */
241fcf3ce44SJohn Forte 	clock_t			iport_cmdcheck_clock;
242fcf3ce44SJohn Forte 
243fcf3ce44SJohn Forte 	uint16_t		iport_task_green_limit;
244fcf3ce44SJohn Forte 	uint16_t		iport_task_yellow_limit;
245fcf3ce44SJohn Forte 	uint16_t		iport_task_red_limit;
246fcf3ce44SJohn Forte 	/* cmd slots */
247fcf3ce44SJohn Forte 	uint16_t		iport_nslots_free;
248fcf3ce44SJohn Forte 
249fcf3ce44SJohn Forte 	/* upper 16 bits is just a counter to avoid ABA issues */
250fcf3ce44SJohn Forte 	uint32_t		iport_next_free_slot;
251fcf3ce44SJohn Forte 
252fcf3ce44SJohn Forte 	uint8_t			iport_login_retry; /* for flogi and N2N plogi */
253fcf3ce44SJohn Forte 	uint8_t			iport_link_old_topology;
254fcf3ce44SJohn Forte 	uint8_t			iport_link_cleanup_retry;
255fcf3ce44SJohn Forte 	clock_t			iport_li_cmd_timeout; /* for li state m/c */
256fcf3ce44SJohn Forte 	fct_cmd_slot_t		*iport_cmd_slots;
257fcf3ce44SJohn Forte 
258fcf3ce44SJohn Forte 	/* worker thread data */
259fcf3ce44SJohn Forte 	ddi_taskq_t		*iport_worker_taskq;
260fcf3ce44SJohn Forte 	kmutex_t		iport_worker_lock;
261fcf3ce44SJohn Forte 	kcondvar_t		iport_worker_cv;
262fcf3ce44SJohn Forte 	struct fct_i_event	*iport_event_head;
263fcf3ce44SJohn Forte 	struct fct_i_event	*iport_event_tail;
264fcf3ce44SJohn Forte 	struct fct_i_cmd	*iport_abort_queue;
265fcf3ce44SJohn Forte 	struct fct_i_cmd	**iport_ppicmd_term;
266fcf3ce44SJohn Forte 
267fcf3ce44SJohn Forte 	/* link initialization */
268fcf3ce44SJohn Forte 	fct_status_t		iport_li_comp_status;
269fcf3ce44SJohn Forte 	enum fct_li_state	iport_li_state;
270fcf3ce44SJohn Forte 
271fcf3ce44SJohn Forte 	/* solicited cmd link */
272fcf3ce44SJohn Forte 	struct fct_i_cmd	*iport_solcmd_queue;
273fcf3ce44SJohn Forte 
274fcf3ce44SJohn Forte 	/* rpwe = remote port with pending els(es) */
275fcf3ce44SJohn Forte 	fct_i_remote_port_t	*iport_rpwe_head;
276fcf3ce44SJohn Forte 	fct_i_remote_port_t	*iport_rpwe_tail;
277*c946facaSallan 	kstat_t			*iport_kstat_portstat;
278*c946facaSallan 	ksema_t			iport_rls_sema;
279*c946facaSallan 	fct_rls_cb_data_t	iport_rls_cb_data;
280fcf3ce44SJohn Forte } fct_i_local_port_t;
281fcf3ce44SJohn Forte 
282fcf3ce44SJohn Forte #define	IPORT_FLOGI_DONE(iport)	PORT_FLOGI_DONE(&(iport)->iport_link_info)
283fcf3ce44SJohn Forte 
284fcf3ce44SJohn Forte /*
285fcf3ce44SJohn Forte  * iport flags
286fcf3ce44SJohn Forte  */
287fcf3ce44SJohn Forte #define	IPORT_WORKER_RUNNING		0x0001
288fcf3ce44SJohn Forte #define	IPORT_TERMINATE_WORKER		0x0002
289fcf3ce44SJohn Forte #define	IPORT_WORKER_DOING_TIMEDWAIT	0x0004
290fcf3ce44SJohn Forte #define	IPORT_WORKER_DOING_WAIT		0x0008
291fcf3ce44SJohn Forte #define	IPORT_FLAG_PORT_OFFLINED	0x0010
292fcf3ce44SJohn Forte #define	IPORT_ALLOW_UNSOL_FLOGI		0x0020
293fcf3ce44SJohn Forte 
294fcf3ce44SJohn Forte #define	IS_WORKER_SLEEPING(iport)	((iport)->iport_flags & \
295fcf3ce44SJohn Forte 	(IPORT_WORKER_DOING_TIMEDWAIT | IPORT_WORKER_DOING_WAIT))
296fcf3ce44SJohn Forte 
297fcf3ce44SJohn Forte /* Limits for scsi task load of local port */
298fcf3ce44SJohn Forte #define	FCT_TASK_GREEN_LIMIT		80
299fcf3ce44SJohn Forte #define	FCT_TASK_YELLOW_LIMIT		90
300fcf3ce44SJohn Forte #define	FCT_TASK_RED_LIMIT		95
301fcf3ce44SJohn Forte 
302fcf3ce44SJohn Forte typedef struct fct_i_event {
303fcf3ce44SJohn Forte 	struct fct_i_event	*event_next;
304fcf3ce44SJohn Forte 	int			event_type;
305fcf3ce44SJohn Forte } fct_i_event_t;
306fcf3ce44SJohn Forte 
307fcf3ce44SJohn Forte typedef enum { /* Seggested action values for discovery thread */
308fcf3ce44SJohn Forte     DISC_ACTION_NO_WORK = 0,
309fcf3ce44SJohn Forte     DISC_ACTION_RESCAN = 1,
310fcf3ce44SJohn Forte     DISC_ACTION_DELAY_RESCAN = 2,
311fcf3ce44SJohn Forte     DISC_ACTION_USE_SHORT_DELAY = 4
312fcf3ce44SJohn Forte } disc_action_t;
313fcf3ce44SJohn Forte 
314fcf3ce44SJohn Forte /*
315fcf3ce44SJohn Forte  * Local port state definitions
316fcf3ce44SJohn Forte  * NOTE that every time there is a state change, the newly set bit suggests
317fcf3ce44SJohn Forte  * the action. So far there are 3 actions S_PORT_CLEANUP, S_ADAPTER_FATAL
318fcf3ce44SJohn Forte  * and S_INIT_LINK.
319fcf3ce44SJohn Forte  */
320fcf3ce44SJohn Forte #define	S_RCVD_LINK_DOWN	0x01
321fcf3ce44SJohn Forte #define	S_RCVD_LINK_UP		0x02
322fcf3ce44SJohn Forte #define	S_LINK_ONLINE		0x04
323fcf3ce44SJohn Forte #define	S_INIT_LINK		0x08
324fcf3ce44SJohn Forte #define	S_PORT_CLEANUP		0x10
325fcf3ce44SJohn Forte 
326fcf3ce44SJohn Forte #define	PORT_STATE_LINK_DOWN		0x00
327fcf3ce44SJohn Forte #define	PORT_STATE_LINK_INIT_START	(S_RCVD_LINK_UP | S_LINK_ONLINE |\
328fcf3ce44SJohn Forte     S_INIT_LINK)
329fcf3ce44SJohn Forte #define	PORT_STATE_LINK_INIT_DONE	(S_LINK_ONLINE)
330fcf3ce44SJohn Forte #define	PORT_STATE_LINK_UP_CLEANING	(S_RCVD_LINK_UP | S_PORT_CLEANUP)
331fcf3ce44SJohn Forte #define	PORT_STATE_LINK_DOWN_CLEANING	(S_RCVD_LINK_DOWN | S_PORT_CLEANUP)
332fcf3ce44SJohn Forte 
333fcf3ce44SJohn Forte /*
334fcf3ce44SJohn Forte  * Internal events
335fcf3ce44SJohn Forte  */
336fcf3ce44SJohn Forte #define	FCT_I_EVENT_LINK_INIT_DONE	0x80
337fcf3ce44SJohn Forte #define	FCT_I_EVENT_CLEANUP_POLL	0x81
338fcf3ce44SJohn Forte 
339fcf3ce44SJohn Forte /*
340fcf3ce44SJohn Forte  * Offline processing states, used by worker thread.
341fcf3ce44SJohn Forte  */
342fcf3ce44SJohn Forte #define	FCT_OPR_DONE			0
343fcf3ce44SJohn Forte #define	FCT_OPR_START			1
344fcf3ce44SJohn Forte #define	FCT_OPR_CMD_CLEANUP_WAIT	2
345fcf3ce44SJohn Forte #define	FCT_OPR_INT_CLEANUP_WAIT	3
346fcf3ce44SJohn Forte 
347fcf3ce44SJohn Forte /*
348fcf3ce44SJohn Forte  * Check time
349fcf3ce44SJohn Forte  */
350fcf3ce44SJohn Forte #define	FCT_CMDLIST_CHECK_SECONDS	10
351fcf3ce44SJohn Forte 
352fcf3ce44SJohn Forte /*
353fcf3ce44SJohn Forte  * Define frequently used macros
354fcf3ce44SJohn Forte  */
355fcf3ce44SJohn Forte #define	ICMD_TO_CT(x_icmd)	\
356fcf3ce44SJohn Forte 	((fct_sol_ct_t *)(x_icmd)->icmd_cmd->cmd_specific)
357fcf3ce44SJohn Forte 
358fcf3ce44SJohn Forte #define	ICMD_TO_ELS(x_icmd)	\
359fcf3ce44SJohn Forte 	((fct_els_t *)(x_icmd)->icmd_cmd->cmd_specific)
360fcf3ce44SJohn Forte 
361fcf3ce44SJohn Forte #define	ICMD_TO_IPORT(x_icmd)	\
362fcf3ce44SJohn Forte 	((fct_i_local_port_t *)(x_icmd)->icmd_cmd->cmd_port->port_fct_private)
363fcf3ce44SJohn Forte 
364fcf3ce44SJohn Forte #define	ICMD_TO_PORT(x_icmd)	\
365fcf3ce44SJohn Forte 	((x_icmd)->icmd_cmd->cmd_port)
366fcf3ce44SJohn Forte 
367fcf3ce44SJohn Forte #define	ICMD_TO_IRP(x_icmd)	\
368fcf3ce44SJohn Forte 	((fct_i_remote_port_t *)(x_icmd)->icmd_cmd->cmd_rp->rp_fct_private)
369fcf3ce44SJohn Forte 
370fcf3ce44SJohn Forte #define	CMD_TO_ICMD(x_cmd)	((fct_i_cmd_t *)(x_cmd)->cmd_fct_private)
371fcf3ce44SJohn Forte 
372fcf3ce44SJohn Forte #define	RP_TO_IRP(x_rp)		((fct_i_remote_port_t *)(x_rp)->rp_fct_private)
373fcf3ce44SJohn Forte 
374fcf3ce44SJohn Forte #define	PORT_TO_IPORT(x_port)	\
375fcf3ce44SJohn Forte 	((fct_i_local_port_t *)(x_port)->port_fct_private)
376fcf3ce44SJohn Forte 
377fcf3ce44SJohn Forte #define	FCT_IS_ELS_ACC(x_icmd)	\
378fcf3ce44SJohn Forte 	(((x_icmd)->icmd_cmd->cmd_comp_status == FCT_SUCCESS) &&	\
379fcf3ce44SJohn Forte 	(ICMD_TO_ELS(x_icmd)->els_resp_payload[0] == ELS_OP_ACC))
380fcf3ce44SJohn Forte 
381fcf3ce44SJohn Forte #define	FCT_IS_CT_ACC(x_icmd)	\
382fcf3ce44SJohn Forte 	(((x_icmd)->icmd_cmd->cmd_comp_status == FCT_SUCCESS) &&	\
383fcf3ce44SJohn Forte 	(ICMD_TO_CT(x_icmd)->ct_resp_payload[8] == 0x80) &&\
384fcf3ce44SJohn Forte 	(ICMD_TO_CT(x_icmd)->ct_resp_payload[9] == 0x02))
385fcf3ce44SJohn Forte 
386fcf3ce44SJohn Forte #define	IPORT_IN_NS_TOPO(x_iport)	\
387fcf3ce44SJohn Forte 	((x_iport)->iport_link_info.port_topology & PORT_TOPOLOGY_FABRIC_BIT)
388fcf3ce44SJohn Forte 
389fcf3ce44SJohn Forte #define	IS_LOGO_ELS(icmd)	\
390fcf3ce44SJohn Forte 	(ICMD_TO_ELS(icmd)->els_req_payload[0] == ELS_OP_LOGO)
391fcf3ce44SJohn Forte 
392fcf3ce44SJohn Forte stmf_status_t fct_xfer_scsi_data(scsi_task_t *task,
393fcf3ce44SJohn Forte     stmf_data_buf_t *dbuf, uint32_t ioflags);
394fcf3ce44SJohn Forte stmf_status_t fct_send_scsi_status(scsi_task_t *task, uint32_t ioflags);
395fcf3ce44SJohn Forte fct_i_remote_port_t *fct_portid_to_portptr(fct_i_local_port_t *iport,
396fcf3ce44SJohn Forte     uint32_t portid);
397fcf3ce44SJohn Forte fct_i_remote_port_t *fct_lookup_irp_by_nodewwn(fct_i_local_port_t *iport,
398fcf3ce44SJohn Forte     uint8_t *nodewwn);
399fcf3ce44SJohn Forte fct_i_remote_port_t *fct_lookup_irp_by_portwwn(fct_i_local_port_t *iport,
400fcf3ce44SJohn Forte     uint8_t *portwwn);
401fcf3ce44SJohn Forte void fct_queue_rp(fct_i_local_port_t *iport, fct_i_remote_port_t *irp);
402fcf3ce44SJohn Forte void fct_deque_rp(fct_i_local_port_t *iport, fct_i_remote_port_t *irp);
403fcf3ce44SJohn Forte int fct_implicitly_logo_all(fct_i_local_port_t *iport, int force_implicit);
404fcf3ce44SJohn Forte void fct_post_implicit_logo(fct_cmd_t *cmd);
405fcf3ce44SJohn Forte void fct_rehash(fct_i_local_port_t *iport);
406fcf3ce44SJohn Forte uint8_t fct_local_port_cleanup_done(fct_i_local_port_t *iport);
407fcf3ce44SJohn Forte void fct_handle_rcvd_abts(fct_cmd_t *cmd);
408fcf3ce44SJohn Forte void fct_fill_abts_acc(fct_cmd_t *cmd);
409fcf3ce44SJohn Forte void fct_q_for_termination_lock_held(fct_i_local_port_t *iport,
410fcf3ce44SJohn Forte     fct_i_cmd_t *icmd, fct_status_t s);
411fcf3ce44SJohn Forte disc_action_t fct_handle_port_offline(fct_i_local_port_t *iport);
412fcf3ce44SJohn Forte disc_action_t fct_cmd_terminator(fct_i_local_port_t *iport);
413fcf3ce44SJohn Forte void fct_cmd_free(fct_cmd_t *cmd);
414fcf3ce44SJohn Forte void fct_scsi_task_free(scsi_task_t *task);
415fcf3ce44SJohn Forte stmf_status_t fct_scsi_abort(stmf_local_port_t *lport, int abort_cmd,
416fcf3ce44SJohn Forte     void *arg, uint32_t flags);
417fcf3ce44SJohn Forte stmf_status_t fct_info(uint32_t cmd, stmf_local_port_t *lport,
418fcf3ce44SJohn Forte     void *arg, uint8_t *buf, uint32_t *bufsizep);
419fcf3ce44SJohn Forte void fct_event_handler(stmf_local_port_t *lport, int eventid,
420fcf3ce44SJohn Forte     void *arg, uint32_t flags);
421fcf3ce44SJohn Forte uint16_t fct_alloc_cmd_slot(fct_i_local_port_t *iport, fct_cmd_t *cmd);
422fcf3ce44SJohn Forte void fct_post_to_discovery_queue(fct_i_local_port_t *iport,
423fcf3ce44SJohn Forte     fct_i_remote_port_t *irp, fct_i_cmd_t *icmd);
424fcf3ce44SJohn Forte fct_cmd_t *fct_create_solct(fct_local_port_t *port, fct_remote_port_t *rp,
425fcf3ce44SJohn Forte     uint16_t ctop, fct_icmd_cb_t icmdcb);
426fcf3ce44SJohn Forte fct_cmd_t *fct_create_solels(fct_local_port_t *port, fct_remote_port_t *rp,
427fcf3ce44SJohn Forte     int implicit, uchar_t elsop, uint32_t wkdid, fct_icmd_cb_t icmdcb);
428fcf3ce44SJohn Forte void fct_handle_solct(fct_cmd_t *cmd);
429fcf3ce44SJohn Forte void fct_post_to_solcmd_queue(fct_local_port_t *port, fct_cmd_t *cmd);
430fcf3ce44SJohn Forte void fct_logo_cb(fct_i_cmd_t *icmd);
431fcf3ce44SJohn Forte void fct_link_init_cb(fct_i_cmd_t *icmd);
432fcf3ce44SJohn Forte void fct_gsnn_cb(fct_i_cmd_t *icmd);
433fcf3ce44SJohn Forte void fct_gcs_cb(fct_i_cmd_t *icmd);
434fcf3ce44SJohn Forte void fct_gft_cb(fct_i_cmd_t *icmd);
435fcf3ce44SJohn Forte void fct_gspn_cb(fct_i_cmd_t *icmd);
436*c946facaSallan void fct_rls_cb(fct_i_cmd_t *icmd);
437fcf3ce44SJohn Forte disc_action_t fct_process_link_init(fct_i_local_port_t *iport);
438fcf3ce44SJohn Forte 
439fcf3ce44SJohn Forte #ifdef	__cplusplus
440fcf3ce44SJohn Forte }
441fcf3ce44SJohn Forte #endif
442fcf3ce44SJohn Forte 
443fcf3ce44SJohn Forte #endif /* _FCT_IMPL_H */
444