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