summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/sys/fc4/fc_transport.h
blob: bdb935fbdc0768a1d36c2554db1508e9f5410365 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */
/*
 * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 */

#ifndef	_SYS_FC4_FC_TRANSPORT_H
#define	_SYS_FC4_FC_TRANSPORT_H

#pragma ident	"%Z%%M%	%I%	%E% SMI"

#include <sys/fc4/fc.h>

#ifdef	__cplusplus
extern "C" {
#endif

/*
 * fc_devdata_t definitions
 *
 * See fc.h for TYPE field definitions
 */
typedef int fc_devdata_t;

/*
 * fc_ioclass_t definitions.
 */
typedef enum {
	FC_CLASS_OUTBOUND,
	FC_CLASS_INBOUND,
	FC_CLASS_SIMPLE,
	FC_CLASS_IO_WRITE,
	FC_CLASS_IO_READ,
	FC_CLASS_OFFLINE,
	FC_CLASS_UNSOLICITED
} fc_ioclass_t;

/*
 * This data structure is used by a Fiber Channel Adaptor driver client to
 * request a Fiber Channel transaction.
 */

typedef struct fc_packet {
			/*
			 * identifies which FC device
			 *
			 * In our case it is a pointer to the
			 * port_status structure. This structure
			 * contains the physical port (0 or 1).
			 */
	void		*fc_pkt_cookie;	/* identifies which FC device */

	void		(*fc_pkt_comp)(struct fc_packet *);
	void		*fc_pkt_private;
	int32_t		fc_pkt_flags;		/* flags */
	int32_t		fc_pkt_timeout;		/* Max time to complete */
	fc_ioclass_t	fc_pkt_io_class;	/* fc io class */
	fc_devdata_t	fc_pkt_io_devdata;	/* FC IO Device Data. */
	fc_dataseg_t	*fc_pkt_cmd;		/* Outbound packet */
	fc_dataseg_t	*fc_pkt_rsp;		/* Inbound  Packet */
	fc_dataseg_t	**fc_pkt_datap;		/* List of Data Packets */

	/*
	 * SOC status from soc status field in Response que.
	 */
	unsigned int	fc_pkt_status;		/* SOC Status when complete */
	int		fc_pkt_statistics;	/* not used */

	fc_frame_header_t	*fc_frame_cmd,	/* used for command */
				*fc_frame_resp;	/* used for response */

	struct fc_packet	*fc_pkt_next,	/* Chain of FC packet reqs. */
				*fc_pkt_prev;
} fc_packet_t;

/*
 *	Fibre channel packet flags
 */
#define	FCFLAG_NOINTR		1	/* run this command without intr */
#define	FCFLAG_COMPLETE		2	/* command has completed */

/*
 * fc_transport() return values
 */
enum {
	FC_TRANSPORT_SUCCESS,		/* success */
	FC_TRANSPORT_FAILURE,		/* failure */
	FC_TRANSPORT_TIMEOUT,		/* timeout while polling */
	FC_TRANSPORT_QFULL,		/* queue full */
	FC_TRANSPORT_UNAVAIL		/* temp. unavailable, e.g., offline */
};


/*
 * pkt_status return values
 */
#define	FC_STATUS_OK			0
#define	FC_STATUS_P_RJT			2
#define	FC_STATUS_F_RJT			3
#define	FC_STATUS_P_BSY			4
#define	FC_STATUS_F_BSY			5
#define	FC_STATUS_ERR_OFFLINE		0x11
#define	FC_STATUS_TIMEOUT		0x12
#define	FC_STATUS_ERR_OVERRUN		0x13
#define	FC_STATUS_UNKNOWN_CQ_TYPE	0x20
#define	FC_STATUS_BAD_SEG_CNT		0x21
#define	FC_STATUS_MAX_XCHG_EXCEEDED	0x22
#define	FC_STATUS_BAD_XID		0x23
#define	FC_STATUS_XCHG_BUSY		0x24
#define	FC_STATUS_BAD_POOL_ID		0x25
#define	FC_STATUS_INSUFFICIENT_CQES	0x26
#define	FC_STATUS_ALLOC_FAIL		0x27
#define	FC_STATUS_BAD_SID		0x28
#define	FC_STATUS_NO_SEQ_INIT		0x29
#define	FC_STATUS_ERROR			0x80
#define	FC_STATUS_ONLINE_TIMEOUT	0x81
/*
 * additional pseudo-status codes for login
 */
#define	FC_STATUS_LOGIN_TIMEOUT		0x80000001u
#define	FC_STATUS_CQFULL		0x80000002u
#define	FC_STATUS_TRANSFAIL		0x80000003u
#define	FC_STATUS_RESETFAIL		0x80000004u

/*
 * fc_uc_register() return values
 */
typedef void * fc_uc_cookie_t;

/*
 * fc_transport() iotype parameter
 */
typedef enum {
	FC_TYPE_UNCATEGORIZED,
	FC_TYPE_DATA,
	FC_TYPE_UNSOL_CONTROL,
	FC_TYPE_SOLICITED_CONTROL,
	FC_TYPE_UNSOL_DATA,
	FC_TYPE_XFER_RDY,
	FC_TYPE_COMMAND,
	FC_TYPE_RESPONSE
} fc_iotype_t;


/*
 * fc_transport() sleep parameter
 */
typedef enum {
	FC_SLEEP,			/* sleep on queue full */
	FC_NOSLEEP			/* do not sleep on queue full */
} fc_sleep_t;


/*
 * State changes related to the N-port interface communicated from below
 */
typedef enum {
	FC_STATE_ONLINE,		/* port has gone online */
	FC_STATE_OFFLINE,		/* port has gone offline */
	FC_STATE_RESET			/* port reset, all cmds lost */
} fc_statec_t;

typedef void * fc_statec_cookie_t;

/*
 * This structure is allocated by Fiber Channel Adaptor at INITCHILD time,
 * and is  communicated to the child by ddi_set_driver_private().
 * It defines the vectors by which the child obtains soc
 * driver services, and all other information the child
 * may need about its parent.
 */

typedef struct fc_transport {
	void			*fc_cookie;	/* Which FC dev. */
	ddi_dma_lim_t		*fc_dmalimp;	/* FC ddi_dma_lim_t ptr. */
	ddi_dma_attr_t		*fc_dma_attrp;	/* FC ddi_dma_attr_t ptr. */
	ddi_iblock_cookie_t	fc_iblock;	/* iblock for mutexes */
	kmutex_t		fc_mtx;		/* Locks for transport */
	kcondvar_t		fc_cv;

	/*
	 * Transport a command across the interface.
	 */
	int		(*fc_transport)(
				struct fc_packet	*fc,
				fc_sleep_t		sleep);

	/*
	 * Reset the transport.
	 */
	int		(*fc_reset)(
				struct fc_packet	*fc);

	/*
	 * Allocate an fc_packet structure.
	 */
	fc_packet_t	*(*fc_pkt_alloc)(
				void			*cookie,
				fc_sleep_t		sleep);

	/*
	 * Free an fc_packet structure.
	 */
	void		(*fc_pkt_free)(
				void			*cookie,
				struct fc_packet	*pkt);

	/*
	 * Register a routine to handle state changes on the interface
	 *
	 * The arg parameter, along with an fc_statec_t parameter, will
	 * be passed to the callback routine on all state changes
	 * after initialization.
	 */
	fc_statec_cookie_t
			(*fc_statec_register)(
			void	*cookie,
			void	(*callback)(void *, fc_statec_t),
			void	*arg);

	/*
	 * Unregister a routine to handle state changes
	 */
	void	(*fc_statec_unregister)(
			void	*cookie,
			fc_statec_cookie_t statec_cookie);

	/*
	 * Run the interface in polling mode.  This allows interface
	 * state changes, etc. to be processed when system interrupts
	 * are disabled.  This is used mostly for error recovery.
	 * Too bad Fibre Channel doesn't have a common error policy for
	 * all protocols so that we could do error recovery at
	 * the lowest level instead of having kludges like this...
	 */
	void	(*fc_interface_poll)(
			void	*cookie);

	/*
	 * Unsolicited Command Interface
	 *
	 * This interface operates with the presumption that the
	 * higher level driver (child) will process unsolicited
	 * commands that pertain to its protocol such as FCP or FCIP.
	 */

	/*
	 * Register a callback to be called in the event of an
	 * unsolicited command received by the soc for this child.
	 * No information is passed regarding the event, just that
	 * one occurred.  The arg parameter to passed to the
	 * callback function as its parameter.
	 */
	fc_uc_cookie_t
			(*fc_uc_register)(
			void			*cookie,
			fc_devdata_t		devdata,
			void			(*callback)(void *),
			void			*arg);

	/*
	 * Unregister a callback routine
	 */
	void	(*fc_uc_unregister)(
			void			*cookie,
			fc_uc_cookie_t		uc_cookie);

	/*
	 * Return information about the unsolicited command
	 * event in pkt.  The pkt must be a fully allocated
	 * fc_packet structure, with a valid cmd dataseg
	 * pointer, in which the received cmd payload will
	 * be placed.  The length of the allocated dataseg should
	 * be greater than or equal to the length of the received
	 * command payload, otherwise the entire command cannot
	 * be copied into the data segment.  This function
	 * returns -1 in the event of an error, or the
	 * actual length of the received command payload.
	 */
	int	(*fc_uc_get_pkt)(
			void			*cookie,
			struct fc_packet	*pkt);

} fc_transport_t;


#ifdef	__cplusplus
}
#endif

#endif	/* !_SYS_FC4_FC_TRANSPORT_H */