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, Version 1.0 only
6 * (the "License").  You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22/*
23 * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
24 * Use is subject to license terms.
25 */
26
27#ifndef	_SYS_FC4_FC_TRANSPORT_H
28#define	_SYS_FC4_FC_TRANSPORT_H
29
30#pragma ident	"%Z%%M%	%I%	%E% SMI"
31
32#include <sys/fc4/fc.h>
33
34#ifdef	__cplusplus
35extern "C" {
36#endif
37
38/*
39 * fc_devdata_t definitions
40 *
41 * See fc.h for TYPE field definitions
42 */
43typedef int fc_devdata_t;
44
45/*
46 * fc_ioclass_t definitions.
47 */
48typedef enum {
49	FC_CLASS_OUTBOUND,
50	FC_CLASS_INBOUND,
51	FC_CLASS_SIMPLE,
52	FC_CLASS_IO_WRITE,
53	FC_CLASS_IO_READ,
54	FC_CLASS_OFFLINE,
55	FC_CLASS_UNSOLICITED
56} fc_ioclass_t;
57
58/*
59 * This data structure is used by a Fiber Channel Adaptor driver client to
60 * request a Fiber Channel transaction.
61 */
62
63typedef struct fc_packet {
64			/*
65			 * identifies which FC device
66			 *
67			 * In our case it is a pointer to the
68			 * port_status structure. This structure
69			 * contains the physical port (0 or 1).
70			 */
71	void		*fc_pkt_cookie;	/* identifies which FC device */
72
73	void		(*fc_pkt_comp)(struct fc_packet *);
74	void		*fc_pkt_private;
75	int32_t		fc_pkt_flags;		/* flags */
76	int32_t		fc_pkt_timeout;		/* Max time to complete */
77	fc_ioclass_t	fc_pkt_io_class;	/* fc io class */
78	fc_devdata_t	fc_pkt_io_devdata;	/* FC IO Device Data. */
79	fc_dataseg_t	*fc_pkt_cmd;		/* Outbound packet */
80	fc_dataseg_t	*fc_pkt_rsp;		/* Inbound  Packet */
81	fc_dataseg_t	**fc_pkt_datap;		/* List of Data Packets */
82
83	/*
84	 * SOC status from soc status field in Response que.
85	 */
86	unsigned int	fc_pkt_status;		/* SOC Status when complete */
87	int		fc_pkt_statistics;	/* not used */
88
89	fc_frame_header_t	*fc_frame_cmd,	/* used for command */
90				*fc_frame_resp;	/* used for response */
91
92	struct fc_packet	*fc_pkt_next,	/* Chain of FC packet reqs. */
93				*fc_pkt_prev;
94} fc_packet_t;
95
96/*
97 *	Fibre channel packet flags
98 */
99#define	FCFLAG_NOINTR		1	/* run this command without intr */
100#define	FCFLAG_COMPLETE		2	/* command has completed */
101
102/*
103 * fc_transport() return values
104 */
105enum {
106	FC_TRANSPORT_SUCCESS,		/* success */
107	FC_TRANSPORT_FAILURE,		/* failure */
108	FC_TRANSPORT_TIMEOUT,		/* timeout while polling */
109	FC_TRANSPORT_QFULL,		/* queue full */
110	FC_TRANSPORT_UNAVAIL		/* temp. unavailable, e.g., offline */
111};
112
113
114/*
115 * pkt_status return values
116 */
117#define	FC_STATUS_OK			0
118#define	FC_STATUS_P_RJT			2
119#define	FC_STATUS_F_RJT			3
120#define	FC_STATUS_P_BSY			4
121#define	FC_STATUS_F_BSY			5
122#define	FC_STATUS_ERR_OFFLINE		0x11
123#define	FC_STATUS_TIMEOUT		0x12
124#define	FC_STATUS_ERR_OVERRUN		0x13
125#define	FC_STATUS_UNKNOWN_CQ_TYPE	0x20
126#define	FC_STATUS_BAD_SEG_CNT		0x21
127#define	FC_STATUS_MAX_XCHG_EXCEEDED	0x22
128#define	FC_STATUS_BAD_XID		0x23
129#define	FC_STATUS_XCHG_BUSY		0x24
130#define	FC_STATUS_BAD_POOL_ID		0x25
131#define	FC_STATUS_INSUFFICIENT_CQES	0x26
132#define	FC_STATUS_ALLOC_FAIL		0x27
133#define	FC_STATUS_BAD_SID		0x28
134#define	FC_STATUS_NO_SEQ_INIT		0x29
135#define	FC_STATUS_ERROR			0x80
136#define	FC_STATUS_ONLINE_TIMEOUT	0x81
137/*
138 * additional pseudo-status codes for login
139 */
140#define	FC_STATUS_LOGIN_TIMEOUT		0x80000001u
141#define	FC_STATUS_CQFULL		0x80000002u
142#define	FC_STATUS_TRANSFAIL		0x80000003u
143#define	FC_STATUS_RESETFAIL		0x80000004u
144
145/*
146 * fc_uc_register() return values
147 */
148typedef void * fc_uc_cookie_t;
149
150/*
151 * fc_transport() iotype parameter
152 */
153typedef enum {
154	FC_TYPE_UNCATEGORIZED,
155	FC_TYPE_DATA,
156	FC_TYPE_UNSOL_CONTROL,
157	FC_TYPE_SOLICITED_CONTROL,
158	FC_TYPE_UNSOL_DATA,
159	FC_TYPE_XFER_RDY,
160	FC_TYPE_COMMAND,
161	FC_TYPE_RESPONSE
162} fc_iotype_t;
163
164
165/*
166 * fc_transport() sleep parameter
167 */
168typedef enum {
169	FC_SLEEP,			/* sleep on queue full */
170	FC_NOSLEEP			/* do not sleep on queue full */
171} fc_sleep_t;
172
173
174/*
175 * State changes related to the N-port interface communicated from below
176 */
177typedef enum {
178	FC_STATE_ONLINE,		/* port has gone online */
179	FC_STATE_OFFLINE,		/* port has gone offline */
180	FC_STATE_RESET			/* port reset, all cmds lost */
181} fc_statec_t;
182
183typedef void * fc_statec_cookie_t;
184
185/*
186 * This structure is allocated by Fiber Channel Adaptor at INITCHILD time,
187 * and is  communicated to the child by ddi_set_driver_private().
188 * It defines the vectors by which the child obtains soc
189 * driver services, and all other information the child
190 * may need about its parent.
191 */
192
193typedef struct fc_transport {
194	void			*fc_cookie;	/* Which FC dev. */
195	ddi_dma_lim_t		*fc_dmalimp;	/* FC ddi_dma_lim_t ptr. */
196	ddi_dma_attr_t		*fc_dma_attrp;	/* FC ddi_dma_attr_t ptr. */
197	ddi_iblock_cookie_t	fc_iblock;	/* iblock for mutexes */
198	kmutex_t		fc_mtx;		/* Locks for transport */
199	kcondvar_t		fc_cv;
200
201	/*
202	 * Transport a command across the interface.
203	 */
204	int		(*fc_transport)(
205				struct fc_packet	*fc,
206				fc_sleep_t		sleep);
207
208	/*
209	 * Reset the transport.
210	 */
211	int		(*fc_reset)(
212				struct fc_packet	*fc);
213
214	/*
215	 * Allocate an fc_packet structure.
216	 */
217	fc_packet_t	*(*fc_pkt_alloc)(
218				void			*cookie,
219				fc_sleep_t		sleep);
220
221	/*
222	 * Free an fc_packet structure.
223	 */
224	void		(*fc_pkt_free)(
225				void			*cookie,
226				struct fc_packet	*pkt);
227
228	/*
229	 * Register a routine to handle state changes on the interface
230	 *
231	 * The arg parameter, along with an fc_statec_t parameter, will
232	 * be passed to the callback routine on all state changes
233	 * after initialization.
234	 */
235	fc_statec_cookie_t
236			(*fc_statec_register)(
237			void	*cookie,
238			void	(*callback)(void *, fc_statec_t),
239			void	*arg);
240
241	/*
242	 * Unregister a routine to handle state changes
243	 */
244	void	(*fc_statec_unregister)(
245			void	*cookie,
246			fc_statec_cookie_t statec_cookie);
247
248	/*
249	 * Run the interface in polling mode.  This allows interface
250	 * state changes, etc. to be processed when system interrupts
251	 * are disabled.  This is used mostly for error recovery.
252	 * Too bad Fibre Channel doesn't have a common error policy for
253	 * all protocols so that we could do error recovery at
254	 * the lowest level instead of having kludges like this...
255	 */
256	void	(*fc_interface_poll)(
257			void	*cookie);
258
259	/*
260	 * Unsolicited Command Interface
261	 *
262	 * This interface operates with the presumption that the
263	 * higher level driver (child) will process unsolicited
264	 * commands that pertain to its protocol such as FCP or FCIP.
265	 */
266
267	/*
268	 * Register a callback to be called in the event of an
269	 * unsolicited command received by the soc for this child.
270	 * No information is passed regarding the event, just that
271	 * one occurred.  The arg parameter to passed to the
272	 * callback function as its parameter.
273	 */
274	fc_uc_cookie_t
275			(*fc_uc_register)(
276			void			*cookie,
277			fc_devdata_t		devdata,
278			void			(*callback)(void *),
279			void			*arg);
280
281	/*
282	 * Unregister a callback routine
283	 */
284	void	(*fc_uc_unregister)(
285			void			*cookie,
286			fc_uc_cookie_t		uc_cookie);
287
288	/*
289	 * Return information about the unsolicited command
290	 * event in pkt.  The pkt must be a fully allocated
291	 * fc_packet structure, with a valid cmd dataseg
292	 * pointer, in which the received cmd payload will
293	 * be placed.  The length of the allocated dataseg should
294	 * be greater than or equal to the length of the received
295	 * command payload, otherwise the entire command cannot
296	 * be copied into the data segment.  This function
297	 * returns -1 in the event of an error, or the
298	 * actual length of the received command payload.
299	 */
300	int	(*fc_uc_get_pkt)(
301			void			*cookie,
302			struct fc_packet	*pkt);
303
304} fc_transport_t;
305
306
307#ifdef	__cplusplus
308}
309#endif
310
311#endif	/* !_SYS_FC4_FC_TRANSPORT_H */
312