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
35 extern "C" {
36 #endif
37 
38 /*
39  * fc_devdata_t definitions
40  *
41  * See fc.h for TYPE field definitions
42  */
43 typedef int fc_devdata_t;
44 
45 /*
46  * fc_ioclass_t definitions.
47  */
48 typedef 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 
63 typedef 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  */
105 enum {
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  */
148 typedef void * fc_uc_cookie_t;
149 
150 /*
151  * fc_transport() iotype parameter
152  */
153 typedef 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  */
168 typedef 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  */
177 typedef 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 
183 typedef 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 
193 typedef 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