xref: /illumos-gate/usr/src/uts/common/sys/usb/usba/usba_types.h (revision 5f82aa32fbc5dc2c59bca6ff315f44a4c4c9ea86)
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  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
22  * Use is subject to license terms.
23  *
24  * Copyright 2014 Garrett D'Amore <garrett@damore.org>
25  */
26 
27 #ifndef	_SYS_USB_USBA_USBA_TYPES_H
28 #define	_SYS_USB_USBA_USBA_TYPES_H
29 
30 
31 #include <sys/taskq.h>
32 #include <sys/usb/usba/usba_private.h>
33 #include <sys/usb/usba/usbai_private.h>
34 
35 #ifdef	__cplusplus
36 extern "C" {
37 #endif
38 
39 /* backup structure for opaque usb_pipe_handle_t */
40 typedef struct usba_ph_impl {
41 	kmutex_t			usba_ph_mutex;
42 	struct usba_pipe_handle_data	*usba_ph_data;	/* actual pipe handle */
43 	dev_info_t			*usba_ph_dip;	/* owner dip */
44 	usb_ep_descr_t			usba_ph_ep;	/* save ep descr */
45 	usb_pipe_policy_t		usba_ph_policy; /* saved pipe policy */
46 	uint_t				usba_ph_flags;
47 
48 	/*
49 	 * usba_ph_ref_count is a count of the number of
50 	 * concurrent activities on this pipe
51 	 */
52 	int				usba_ph_ref_count;
53 
54 	/* pipe state management */
55 	usb_pipe_state_t		usba_ph_state;
56 	int				usba_ph_state_changing;
57 } usba_ph_impl_t;
58 
59 _NOTE(MUTEX_PROTECTS_DATA(usba_ph_impl::usba_ph_mutex, usba_ph_impl))
60 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_ph_impl::usba_ph_data))
61 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_ph_impl::usba_ph_dip))
62 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_ph_impl::usba_ph_ep))
63 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_ph_impl::usba_ph_policy))
64 
65 /* for usba_ph_flags */
66 #define	USBA_PH_DATA_TOGGLE		0x01	/* mask for data toggle */
67 #define	USBA_PH_DATA_PERSISTENT 	0x02	/* persistent pipe */
68 
69 
70 /*
71  * usba_pipe_handle_data
72  *	allocated by USBA and used by USBA and HCD but opaque to
73  *	client driver
74  *
75  *	pipes can be shared but pipe_handles are unique
76  *
77  * p_hcd_private is a pointer to private data for HCD. This space
78  * is allocated and maintained by HCD
79  */
80 typedef struct	usba_pipe_handle_data {
81 	struct usba_ph_impl	*p_ph_impl;	/* backpointer to ph_impl */
82 
83 	/* For linking pipe requests on the pipe */
84 	usba_list_entry_t	p_queue;
85 
86 	/* shared usba_device structure */
87 	struct usba_device	*p_usba_device;	/* set on pipe open */
88 
89 	/*
90 	 * Pipe policy and endpoint descriptor for this pipe
91 	 *
92 	 * Both the basic and extended endpoints are kept around even though
93 	 * we're duplicating data as most of the HCI drivers are relying on the
94 	 * presence of p_ep.
95 	 */
96 	usb_pipe_policy_t	p_policy;	/* maintained by USBA */
97 	usb_ep_descr_t		p_ep;
98 	usb_ep_xdescr_t		p_xep;
99 
100 	/* passed during open. needed for reset etc. */
101 	dev_info_t		*p_dip;
102 
103 	/* access control */
104 	kmutex_t		p_mutex;   /* mutex protecting pipe handle */
105 
106 	/* per-pipe private data for HCD */
107 	usb_opaque_t		p_hcd_private;
108 
109 	/* per-pipe private data for client */
110 	usb_opaque_t		p_client_private;
111 
112 	/*
113 	 * p_req_count is the count of number requests active
114 	 * on this pipe
115 	 */
116 	int			p_req_count;
117 
118 	/* private use by USBA */
119 	usb_opaque_t		p_usba_private;
120 
121 	/*
122 	 * each pipe handle has its own taskq for callbacks and async reqs
123 	 * Note that this will not be used for normal callbacks if
124 	 * USB_FLAGS_SERIALIZED_CB is passed to usb_pipe_open().
125 	 */
126 	taskq_t			*p_taskq;
127 
128 	/* thread currently serving the queue */
129 	kthread_t		*p_thread_id;
130 
131 	/* cb queue serviced by taskq thread */
132 	usba_list_entry_t	p_cb_queue;
133 
134 	/* count for soft interrupts */
135 	uint_t			p_soft_intr;
136 
137 	/* flag for special things */
138 	uint_t			p_spec_flag;
139 
140 } usba_pipe_handle_data_t;
141 
142 #define	USBA_PH_FLAG_USE_SOFT_INTR	0x1
143 #define	USBA_PH_FLAG_TQ_SHARE		0x2	/* Shared TaskQ for callbacks */
144 
145 
146 
147 /* macro to get the endpoint descriptor */
148 #define	USBA_DEFAULT_PIPE_EP	0	/* ep 0 is default pipe */
149 #define	USBA_PH2ENDPOINT(ph)  (((usba_pipe_handle_data_t *)(ph))->p_ep)
150 
151 #define	USBA_PIPE_CLOSING(state) \
152 		(((state) == USB_PIPE_STATE_CLOSING) || \
153 		((state) == USB_PIPE_STATE_CLOSED))
154 
155 #define	USBA_IS_DEFAULT_PIPE(ph)  ((ph) == \
156 	(ph)->p_usba_device->usb_ph_list[USBA_DEFAULT_PIPE_EP].usba_ph_data)
157 
158 _NOTE(MUTEX_PROTECTS_DATA(usba_pipe_handle_data::p_mutex, \
159 	usba_pipe_handle_data))
160 
161 /* these should be really stable data */
162 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_pipe_handle_data::p_ph_impl))
163 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_pipe_handle_data::p_usba_device))
164 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_pipe_handle_data::p_hcd_private))
165 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_pipe_handle_data::p_client_private))
166 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_pipe_handle_data::p_ep))
167 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_pipe_handle_data::p_dip))
168 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_pipe_handle_data::p_taskq))
169 
170 
171 /*
172  * usb_addr:
173  *	This is	the USB	address	of a device
174  */
175 typedef	uchar_t usb_addr_t;
176 
177 #define	USBA_DEFAULT_ADDR	0
178 
179 /*
180  * number of endpoint per device, 16 IN and 16 OUT.
181  * this define is used for pipehandle list, pipe reserved list
182  * and pipe open count array.
183  * these lists are indexed by endpoint number * ((address & direction)? 2 : 1)
184  *
185  * We use a bit mask for exclusive open tracking and therefore
186  * USB_N_ENDPOINTS must be equal to the bit size of int.
187  *
188  */
189 #define	USBA_N_ENDPOINTS		32
190 
191 /*
192  * USB spec defines 4 different power states of any usb device.
193  * They are D0, D1, D2 & D3. So, we need a total of 5 pm-components
194  * 4 for power and 1 for name.
195  */
196 #define	USBA_N_PMCOMP		5
197 
198 /*
199  * usb port status
200  */
201 typedef uint8_t usb_port_status_t;
202 typedef uint16_t usb_port_t;
203 typedef uint32_t usb_port_mask_t;
204 
205 /*
206  * Note, faster speeds should always be in increasing values. Various parts of
207  * the stack use >= comparisons for things which are true for say anything equal
208  * to or greater than USB 2.0.
209  */
210 #define	USBA_LOW_SPEED_DEV	0x1
211 #define	USBA_FULL_SPEED_DEV	0x2
212 #define	USBA_HIGH_SPEED_DEV	0x3
213 #define	USBA_SUPER_SPEED_DEV	0x4
214 
215 /*
216  * NDI event is registered on a per-dip basis. usba_device can be
217  * shared by multiple dips, hence the following structure is
218  * need to keep per-dip event info.
219  */
220 typedef struct usba_evdata {
221 	struct usba_evdata	*ev_next;
222 	dev_info_t		*ev_dip;
223 
224 	/* NDI evetn service callback ids */
225 	ddi_callback_id_t	ev_rm_cb_id;
226 	ddi_callback_id_t	ev_ins_cb_id;
227 	ddi_callback_id_t	ev_suspend_cb_id;
228 	ddi_callback_id_t	ev_resume_cb_id;
229 } usba_evdata_t;
230 
231 /*
232  * a client may request dev_data multiple times (eg. for
233  * ugen support) so we need a linked list
234  */
235 typedef struct usb_client_dev_data_list {
236 	struct usb_client_dev_data_list *cddl_next;
237 	struct usb_client_dev_data_list *cddl_prev;
238 	dev_info_t			*cddl_dip;
239 	usb_client_dev_data_t		*cddl_dev_data;
240 	uint_t				cddl_ifno;
241 } usb_client_dev_data_list_t;
242 
243 /*
244  * This	structure uniquely identifies a USB device
245  * with all interfaces,	or just one interface of a USB device.
246  * usba_device is associated with a devinfo node
247  *
248  * This	structure is allocated and maintained by USBA and
249  * read-only for HCD
250  *
251  * There can be	multiple clients per device (multi-class
252  * device) in which case this structure is shared.
253  */
254 typedef struct usba_device {
255 	/* for linking all usba_devices on this bus */
256 	usba_list_entry_t	usb_device_list;
257 
258 	/* linked list of all pipe handles on this device per endpoint */
259 	struct usba_ph_impl	usb_ph_list[USBA_N_ENDPOINTS];
260 
261 	kmutex_t		usb_mutex;   /* protecting usba_device */
262 
263 	dev_info_t		*usb_dip;
264 
265 	struct usba_hcdi_ops	*usb_hcdi_ops;	/* ptr to HCD ops */
266 
267 	struct usba_hubdi	*usb_hubdi;
268 
269 	usb_addr_t		usb_addr;	/* usb address */
270 
271 	uchar_t			usb_no_cpr;	/* CPR? */
272 
273 	dev_info_t		*usb_root_hub_dip;
274 	struct hubd		*usb_root_hubd;	/* for HC or WA */
275 
276 	usb_dev_descr_t		*usb_dev_descr;	/* device descriptor */
277 
278 	uchar_t			*usb_cfg;	/* raw config descriptor */
279 	size_t			usb_cfg_length; /* length of raw descr */
280 
281 	char			*usb_mfg_str;	/* manufacturer string */
282 	char			*usb_product_str;	/* product string */
283 	char			*usb_serialno_str; /* serial number string */
284 	char			*usb_preferred_driver; /* user's choice */
285 
286 	usb_port_status_t	usb_port_status; /* usb hub port status */
287 	usb_port_t		usb_port;
288 
289 	/* To support split transactions */
290 	struct usba_device	*usb_hs_hub_usba_dev; /* HS hub usba device */
291 	usb_addr_t		usb_hs_hub_addr; /* High speed hub address */
292 	usb_port_t		usb_hs_hub_port; /* High speed hub port */
293 
294 	/* For high speed hub bandwidth allocation scheme */
295 	uint_t			usb_hs_hub_min_bandwidth;
296 	uint_t			usb_hs_hub_bandwidth[32];
297 
298 	/* store all config cloud here */
299 	uchar_t			**usb_cfg_array;
300 	uint_t			usb_cfg_array_length;
301 
302 	uint16_t		*usb_cfg_array_len;
303 	uint_t			usb_cfg_array_len_length;
304 
305 	uint_t			usb_cfg_value;
306 	uint_t			usb_active_cfg_ndx;
307 	char			**usb_cfg_str_descr;
308 	uchar_t			usb_n_cfgs;
309 	uchar_t			usb_n_ifs;
310 
311 	/*
312 	 * power drawn from hub, if > 0, the power has been
313 	 * subtracted from the parent hub's power budget
314 	 */
315 	uint16_t		usb_pwr_from_hub;
316 
317 	/* ref count, if > 0, this structure is in use */
318 	int			usb_ref_count;
319 
320 	/* list of requests allocated for this device, detects leaks */
321 	usba_list_entry_t	usb_allocated;		/* alloc'ed reqs list */
322 
323 	/* NDI event service cookies */
324 	ddi_eventcookie_t	rm_cookie;
325 	ddi_eventcookie_t	ins_cookie;
326 	ddi_eventcookie_t	suspend_cookie;
327 	ddi_eventcookie_t	resume_cookie;
328 
329 	/* linked list of callid (per-devinfo) */
330 	usba_evdata_t		*usb_evdata;
331 
332 	/* client cleanup checks */
333 	uchar_t			*usb_client_flags;
334 
335 	struct {
336 		dev_info_t *dip;
337 	}			*usb_client_attach_list;
338 
339 	usb_client_dev_data_list_t usb_client_dev_data_list;
340 
341 	struct {
342 		dev_info_t *dip;
343 		usb_event_t *ev_data;
344 	}			*usb_client_ev_cb_list;
345 
346 	/* Shared task queue implementation. */
347 	taskq_t			*usb_shared_taskq[USBA_N_ENDPOINTS];
348 	uchar_t			usb_shared_taskq_ref_count
349 						[USBA_N_ENDPOINTS];
350 
351 	/*
352 	 * Pointer to hub this is under. This is required for some HCDs to
353 	 * accurately set up the device. Note that some usba_device_t's are
354 	 * shared by multiple entries, so this is not strictly the parent
355 	 * device. This would come up if the usb_mid driver was on the scene.
356 	 * Importantly, this field is always read-only. While this is similar to
357 	 * the usb_hs_hub_usba_dev, it's always set, regardless if it's a high
358 	 * speed device or not.
359 	 */
360 	struct usba_device	*usb_parent_hub;
361 
362 	/*
363 	 * Private data for HCD drivers
364 	 */
365 	void			*usb_hcd_private;
366 } usba_device_t;
367 
368 #define	USBA_CLIENT_FLAG_SIZE		1
369 #define	USBA_CLIENT_FLAG_ATTACH		0x01
370 #define	USBA_CLIENT_FLAG_EV_CBS		0x02
371 #define	USBA_CLIENT_FLAG_DEV_DATA	0x04
372 
373 _NOTE(MUTEX_PROTECTS_DATA(usba_device::usb_mutex, usba_device))
374 _NOTE(MUTEX_PROTECTS_DATA(usba_device::usb_mutex, usba_evdata))
375 
376 _NOTE(SCHEME_PROTECTS_DATA("chg at attach only",
377 				usba_evdata::ev_rm_cb_id))
378 _NOTE(SCHEME_PROTECTS_DATA("chg at attach only",
379 				usba_evdata::ev_ins_cb_id))
380 _NOTE(SCHEME_PROTECTS_DATA("chg at attach only",
381 				usba_evdata::ev_suspend_cb_id))
382 _NOTE(SCHEME_PROTECTS_DATA("chg at attach only",
383 				usba_evdata::ev_resume_cb_id))
384 
385 /* this should be really stable data */
386 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_serialno_str))
387 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_root_hub_dip))
388 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_root_hubd))
389 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_product_str))
390 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_preferred_driver))
391 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_port))
392 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_n_ifs))
393 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_n_cfgs))
394 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_mfg_str))
395 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_dev_descr))
396 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_ph_list))
397 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_cfg_value))
398 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_cfg_str_descr))
399 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_cfg_length))
400 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_cfg_array))
401 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_cfg_array_len))
402 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_cfg_array_length))
403 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_cfg_array_len_length))
404 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_cfg))
405 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_hcdi_ops))
406 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_addr))
407 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_port_status))
408 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::rm_cookie))
409 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::ins_cookie))
410 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::suspend_cookie))
411 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::resume_cookie))
412 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_client_flags))
413 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_client_attach_list))
414 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_client_ev_cb_list))
415 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_dip))
416 _NOTE(SCHEME_PROTECTS_DATA("set at device creation",
417 					usba_device::usb_shared_taskq))
418 
419 _NOTE(SCHEME_PROTECTS_DATA("local use only",
420 				usb_key_descr::bDescriptorType))
421 _NOTE(SCHEME_PROTECTS_DATA("local use only",
422 				usb_key_descr::bLength))
423 /*
424  * serialization in drivers
425  */
426 typedef struct usba_serialization_impl {
427 	dev_info_t	*s_dip;
428 	kcondvar_t	s_cv;
429 	kmutex_t	s_mutex;
430 	kthread_t	*s_thread;
431 	int		s_count;
432 	uint_t		s_flag;
433 } usba_serialization_impl_t;
434 
435 _NOTE(SCHEME_PROTECTS_DATA("unshared private data",
436 				usba_serialization_impl))
437 
438 #ifdef	__cplusplus
439 }
440 #endif
441 
442 #endif	/* _SYS_USB_USBA_USBA_TYPES_H */
443