xref: /illumos-gate/usr/src/uts/common/sys/usb/usba/hcdi.h (revision 66582b606a8194f7f3ba5b3a3a6dca5b0d346361)
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 (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  *
25  * Copyright 2016 Joyent, Inc.
26  */
27 
28 #ifndef	_SYS_USB_HCDI_H
29 #define	_SYS_USB_HCDI_H
30 
31 
32 #ifdef	__cplusplus
33 extern "C" {
34 #endif
35 
36 #include <sys/usb/usba/genconsole.h>
37 #include <sys/usb/usba/usba_types.h>
38 
39 /*
40  * HCD ops structure
41  *
42  * - this structure defines all entry points into HCD
43  *
44  * - all client driver USBAI functions that require HCD
45  *   involvement go through this ops table
46  *
47  * - at HCD attach time, the HCD ops are passed to
48  *   to the USBA through usba_hcdi_attach()
49  *
50  * some of these ops implement the semantics of the corresponding
51  * USBAI interfaces. Refer to usbai.h for detailed description
52  */
53 #define	HCDI_OPS_VERSION_0 0
54 #define	HCDI_OPS_VERSION_1 1
55 #define	HCDI_OPS_VERSION_2 2
56 #define	HCDI_OPS_VERSION	HCDI_OPS_VERSION_2
57 
58 typedef struct usba_hcdi_ops {
59 	int	usba_hcdi_ops_version;	/* implementation version */
60 
61 	dev_info_t	*usba_hcdi_dip;	/* HCD's devinfo ptr */
62 
63 	/* can this hcd support pm? */
64 	int	(*usba_hcdi_pm_support)(dev_info_t *dip);
65 
66 	/*
67 	 * usba_hcdi_pipe_open:
68 	 *	implements the semantics of usb_pipe_open()
69 	 *	USBA allocate the pipe_handle which contains
70 	 *	pipe_policy and endpoint pointers
71 	 */
72 	int	(*usba_hcdi_pipe_open)(
73 		usba_pipe_handle_data_t	*pipe_handle,
74 		usb_flags_t		usb_flags);
75 
76 	/*
77 	 * close a pipe
78 	 */
79 	int	(*usba_hcdi_pipe_close)(
80 		usba_pipe_handle_data_t	*pipe_handle,
81 		usb_flags_t		usb_flags);
82 
83 	/*
84 	 * pipe management
85 	 */
86 	int	(*usba_hcdi_pipe_reset)(
87 		usba_pipe_handle_data_t	*pipe_handle,
88 		usb_flags_t		usb_flags);
89 
90 	/*
91 	 * pipe management
92 	 */
93 	void	(*usba_hcdi_pipe_reset_data_toggle)(
94 		usba_pipe_handle_data_t	*pipe_handle);
95 
96 	/*
97 	 * data transfer management
98 	 */
99 	int	(*usba_hcdi_pipe_ctrl_xfer)(
100 		usba_pipe_handle_data_t	*pipe_handle,
101 		usb_ctrl_req_t		*usb_ctrl_req,
102 		usb_flags_t		usb_flags);
103 
104 	/*
105 	 * get HCD limitation on bulk xfer at a time?
106 	 */
107 	int	(*usba_hcdi_bulk_transfer_size)(
108 		usba_device_t		*usba_device,
109 		size_t			*size);
110 
111 	/*
112 	 * do bulk read/write
113 	 */
114 	int	(*usba_hcdi_pipe_bulk_xfer)(
115 		usba_pipe_handle_data_t	*pipe_handle,
116 		usb_bulk_req_t		*usb_bulk_req,
117 		usb_flags_t		usb_flags);
118 
119 	/*
120 	 * do interrupt pipe read/write
121 	 */
122 	int	(*usba_hcdi_pipe_intr_xfer)(
123 		usba_pipe_handle_data_t	*pipe_handle,
124 		usb_intr_req_t		*usb_intr_req,
125 		usb_flags_t		usb_flags);
126 
127 	/*
128 	 * stop interrupt pipe polling
129 	 */
130 	int	(*usba_hcdi_pipe_stop_intr_polling)(
131 		usba_pipe_handle_data_t	*pipe_handle,
132 		usb_flags_t		usb_flags);
133 
134 	/*
135 	 * do isoch pipe read/write
136 	 */
137 	int	(*usba_hcdi_pipe_isoc_xfer)(
138 		usba_pipe_handle_data_t	*pipe_handle,
139 		usb_isoc_req_t		*usb_isoc_req,
140 		usb_flags_t		usb_flags);
141 
142 	/*
143 	 * stop isoc pipe polling
144 	 */
145 	int	(*usba_hcdi_pipe_stop_isoc_polling)(
146 		usba_pipe_handle_data_t	*pipe_handle,
147 		usb_flags_t		usb_flags);
148 
149 	/* utility isoc functions */
150 	int	(*usba_hcdi_get_current_frame_number)(
151 		usba_device_t		*usba_device,
152 		usb_frame_number_t	*frame_number);
153 
154 	int	(*usba_hcdi_get_max_isoc_pkts)(
155 		usba_device_t		*usba_device,
156 		uint_t			*max_isoc_pkts_per_request);
157 
158 	/*
159 	 * Initialize OBP support for input
160 	 */
161 	int	(*usba_hcdi_console_input_init)(
162 		usba_pipe_handle_data_t		*pipe_handle,
163 		uchar_t				**obp_buf,
164 		usb_console_info_impl_t		*console_input_info);
165 
166 	/*
167 	 * Free resources allocated by usba_hcdi_console_input_init
168 	 */
169 	int	(*usba_hcdi_console_input_fini)(
170 		usb_console_info_impl_t		*console_input_info);
171 
172 	/*
173 	 * Save controller state information
174 	 */
175 	int	(*usba_hcdi_console_input_enter)(
176 		usb_console_info_impl_t		*console_input_info);
177 
178 	/*
179 	 * Read character from controller
180 	 */
181 	int	(*usba_hcdi_console_read)(
182 		usb_console_info_impl_t		*console_input_info,
183 		uint_t				*num_characters);
184 
185 	/*
186 	 * Restore controller state information
187 	 */
188 	int	(*usba_hcdi_console_input_exit)(
189 		usb_console_info_impl_t		*console_input_info);
190 
191 
192 	/*
193 	 * VERSION 1 ops: support for polled output
194 	 */
195 	int	(*usba_hcdi_console_output_init)(
196 		usba_pipe_handle_data_t		*pipe_handle,
197 		usb_console_info_impl_t		*console_output_info);
198 
199 	int	(*usba_hcdi_console_output_fini)(
200 		usb_console_info_impl_t		*console_output_info);
201 
202 	int	(*usba_hcdi_console_output_enter)(
203 		usb_console_info_impl_t		*console_output_info);
204 
205 	int	(*usba_hcdi_console_write)(
206 		usb_console_info_impl_t		*console_output_info,
207 		uchar_t				*buf,
208 		uint_t				num_characters,
209 		uint_t				*num_characters_written);
210 
211 	int	(*usba_hcdi_console_output_exit)(
212 		usb_console_info_impl_t		*console_output_info);
213 
214 	/*
215 	 * VERSION 2 ops: support for device initialization
216 	 */
217 	int	(*usba_hcdi_device_init)(
218 		usba_device_t			*usba_device,
219 		usb_port_t			port,
220 		void				**);
221 
222 	void	(*usba_hcdi_device_fini)(
223 		usba_device_t			*usba_device,
224 		void				*);
225 
226 	int	(*usba_hcdi_device_address)(
227 		usba_device_t			*usba_device);
228 
229 	int	(*usba_hcdi_hub_update)(
230 		usba_device_t			*usba_device,
231 		uint8_t				nports,
232 		uint8_t				think_time);
233 } usba_hcdi_ops_t;
234 
235 
236 /*
237  * callback support:
238  *	this function handles all HCD callbacks as follows:
239  *	- USB_FLAGS_SLEEP determines whether the client driver made
240  *	  a synchronous or asynchronous USBAI call
241  *	- for synchronous calls, the args are copied into the pipe handle
242  *		and the sync cv of the pipe handle is signalled
243  *	- for async calls and completion_reason = 0, the normal callback
244  *		is invoked
245  *	- for async calls and completion_reason != 0, the exception
246  *		callback is invoked
247  */
248 void
249 usba_hcdi_cb(usba_pipe_handle_data_t	*ph,
250     usb_opaque_t		req,
251     usb_cr_t		completion_reason);
252 
253 /*
254  * function to duplicate a interrupt/isoc request (for HCD)
255  */
256 usb_intr_req_t	*usba_hcdi_dup_intr_req(dev_info_t *,
257 			usb_intr_req_t *, size_t, usb_flags_t);
258 usb_isoc_req_t	*usba_hcdi_dup_isoc_req(dev_info_t *,
259 			usb_isoc_req_t *, usb_flags_t);
260 
261 /* access to private member of requests */
262 usb_opaque_t	usba_hcdi_get_req_private(usb_opaque_t);
263 void		usba_hcdi_set_req_private(usb_opaque_t, usb_opaque_t);
264 usba_pipe_handle_data_t *
265 		usba_hcdi_get_ph_data(usba_device_t *, uint8_t);
266 
267 /* data toggle get and set */
268 uchar_t		usba_hcdi_get_data_toggle(usba_device_t *, uint8_t);
269 void 		usba_hcdi_set_data_toggle(usba_device_t *, uint8_t, uchar_t);
270 
271 /*
272  * HCD Nexus driver support:
273  */
274 
275 /*
276  * hcd_ops allocator/deallocator
277  *	USBA allocates the usba_hcdi_ops so we can easily handle
278  *	versioning
279  */
280 usba_hcdi_ops_t	*usba_alloc_hcdi_ops();
281 void		usba_free_hcdi_ops(usba_hcdi_ops_t *);
282 
283 /*
284  * Argument structure for usba_hcdi_register
285  */
286 typedef struct usba_hcdi_register_args {
287 	uint_t			usba_hcdi_register_version;
288 	dev_info_t		*usba_hcdi_register_dip;
289 	usba_hcdi_ops_t		*usba_hcdi_register_ops;
290 	ddi_dma_attr_t		*usba_hcdi_register_dma_attr;
291 	ddi_iblock_cookie_t	usba_hcdi_register_iblock_cookie;
292 } usba_hcdi_register_args_t;
293 
294 #define	HCDI_REGISTER_VERS_0		0
295 #define	HCDI_REGISTER_VERSION		HCDI_REGISTER_VERS_0
296 
297 
298 /*
299  * make	this instance known to USBA
300  *
301  * the HCD must initialize the hcdi_ops before calling this function
302  */
303 int	usba_hcdi_register(usba_hcdi_register_args_t *, uint_t);
304 
305 /*
306  * detach support
307  */
308 void	usba_hcdi_unregister(dev_info_t *);
309 
310 /*
311  * HCD device private storage
312  */
313 void	*usba_hcdi_get_device_private(usba_device_t *);
314 
315 /*
316  * Hotplug kstats named structure
317  *
318  * Number of types of USB transfers
319  */
320 #define	USB_N_COUNT_KSTATS	4
321 
322 typedef struct hcdi_hotplug_stats {
323 	struct kstat_named	hcdi_hotplug_total_success;
324 	struct kstat_named	hcdi_hotplug_success;
325 	struct kstat_named	hcdi_hotplug_total_failure;
326 	struct kstat_named	hcdi_hotplug_failure;
327 	struct kstat_named	hcdi_device_count;
328 } hcdi_hotplug_stats_t;
329 
330 /*
331  * USB error kstats named structure
332  */
333 typedef struct hcdi_error_stats {
334 	/* transport completion codes */
335 	struct kstat_named	cc_crc;
336 	struct kstat_named	cc_bitstuffing;
337 	struct kstat_named	cc_data_toggle_mm;
338 	struct kstat_named	cc_stall;
339 	struct kstat_named	cc_dev_not_resp;
340 	struct kstat_named	cc_pid_checkfailure;
341 	struct kstat_named	cc_unexp_pid;
342 	struct kstat_named	cc_data_overrun;
343 	struct kstat_named	cc_data_underrun;
344 	struct kstat_named	cc_buffer_overrun;
345 	struct kstat_named	cc_buffer_underrun;
346 	struct kstat_named	cc_timeout;
347 	struct kstat_named	cc_not_accessed;
348 	struct kstat_named	cc_no_resources;
349 	struct kstat_named	cc_unspecified_err;
350 	struct kstat_named	cc_stopped_polling;
351 	struct kstat_named	cc_pipe_closing;
352 	struct kstat_named	cc_pipe_reset;
353 	struct kstat_named	cc_not_supported;
354 	struct kstat_named	cc_flushed;
355 } hcdi_error_stats_t;
356 
357 /*
358  * hcdi kstat defines
359  * XXX this needs to be a function
360  */
361 #define	HCDI_HOTPLUG_STATS(hcdi)	((hcdi)->hcdi_hotplug_stats)
362 #define	HCDI_HOTPLUG_STATS_DATA(hcdi)	\
363 	((hcdi_hotplug_stats_t *)HCDI_HOTPLUG_STATS((hcdi))->ks_data)
364 
365 #define	HCDI_ERROR_STATS(hcdi)		((hcdi)->hcdi_error_stats)
366 #define	HCDI_ERROR_STATS_DATA(hcdi)	\
367 	((hcdi_error_stats_t *)HCDI_ERROR_STATS((hcdi))->ks_data)
368 
369 
370 /*
371  * The default timeout that should occur for non-periodic transfers if a timeout
372  * is not requested by a client driver. This is a time in seconds.
373  */
374 #define	HCDI_DEFAULT_TIMEOUT	5
375 
376 #ifdef __cplusplus
377 }
378 #endif
379 
380 #endif	/* _SYS_USB_HCDI_H */
381