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 2008 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
34 extern "C" {
35 #endif
36 
37 /* backup structure for opaque usb_pipe_handle_t */
38 typedef 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  */
78 typedef 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  */
166 typedef	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  */
192 typedef uint8_t usb_port_status_t;
193 typedef uint16_t usb_port_t;
194 typedef 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  */
205 typedef 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  */
220 typedef 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  * This	structure uniquely identifies a USB device
230  * with all interfaces,	or just one interface of a USB device.
231  * usba_device is associated with a devinfo node
232  *
233  * This	structure is allocated and maintained by USBA and
234  * read-only for HCD
235  *
236  * There can be	multiple clients per device (multi-class
237  * device) in which case this structure is shared.
238  */
239 typedef struct usba_device {
240 	/* for linking all usba_devices on this bus */
241 	usba_list_entry_t	usb_device_list;
242 
243 	/* linked list of all pipe handles on this device per endpoint */
244 	struct usba_ph_impl	usb_ph_list[USBA_N_ENDPOINTS];
245 
246 	kmutex_t		usb_mutex;   /* protecting usba_device */
247 
248 	dev_info_t		*usb_dip;
249 
250 	struct usba_hcdi_ops	*usb_hcdi_ops;	/* ptr to HCD ops */
251 
252 	struct usba_hubdi	*usb_hubdi;
253 
254 	usb_addr_t		usb_addr;	/* usb address */
255 
256 	uchar_t			usb_no_cpr;	/* CPR? */
257 
258 	dev_info_t		*usb_root_hub_dip;
259 	struct hubd		*usb_root_hubd;
260 
261 	usb_dev_descr_t		*usb_dev_descr;	/* device descriptor */
262 
263 	uchar_t			*usb_cfg;	/* raw config descriptor */
264 	size_t			usb_cfg_length; /* length of raw descr */
265 
266 	char			*usb_mfg_str;	/* manufacturer string */
267 	char			*usb_product_str;	/* product string */
268 	char			*usb_serialno_str; /* serial number string */
269 	char			*usb_preferred_driver; /* user's choice */
270 
271 	usb_port_status_t	usb_port_status; /* usb hub port status */
272 	usb_port_t		usb_port;
273 
274 	/* To support split transactions */
275 	struct usba_device	*usb_hs_hub_usba_dev; /* HS hub usba device */
276 	usb_addr_t		usb_hs_hub_addr; /* High speed hub address */
277 	usb_port_t		usb_hs_hub_port; /* High speed hub port */
278 
279 	/* For high speed hub bandwidth allocation scheme */
280 	uint_t			usb_hs_hub_min_bandwidth;
281 	uint_t			usb_hs_hub_bandwidth[32];
282 
283 	/* store all config cloud here */
284 	uchar_t			**usb_cfg_array;
285 	uint_t			usb_cfg_array_length;
286 
287 	uint16_t		*usb_cfg_array_len;
288 	uint_t			usb_cfg_array_len_length;
289 
290 	uint_t			usb_cfg_value;
291 	uint_t			usb_active_cfg_ndx;
292 	char			**usb_cfg_str_descr;
293 	uchar_t			usb_n_cfgs;
294 	uchar_t			usb_n_ifs;
295 
296 	/*
297 	 * power drawn from hub, if > 0, the power has been
298 	 * subtracted from the parent hub's power budget
299 	 */
300 	uint16_t		usb_pwr_from_hub;
301 
302 	/* ref count, if > 0, this structure is in use */
303 	int			usb_ref_count;
304 
305 	/* list of requests allocated for this device, detects leaks */
306 	usba_list_entry_t	usb_allocated;		/* alloc'ed reqs list */
307 
308 	/* NDI event service cookies */
309 	ddi_eventcookie_t	rm_cookie;
310 	ddi_eventcookie_t	ins_cookie;
311 	ddi_eventcookie_t	suspend_cookie;
312 	ddi_eventcookie_t	resume_cookie;
313 
314 	/* linked list of callid (per-devinfo) */
315 	usba_evdata_t		*usb_evdata;
316 
317 	/* client cleanup checks */
318 	uchar_t			*usb_client_flags;
319 
320 	struct {
321 		dev_info_t *dip;
322 	}			*usb_client_attach_list;
323 
324 	usb_client_dev_data_list_t usb_client_dev_data_list;
325 
326 	struct {
327 		dev_info_t *dip;
328 		usb_event_t *ev_data;
329 	}			*usb_client_ev_cb_list;
330 
331 	/* Shared task queue implementation. */
332 	taskq_t			*usb_shared_taskq[USBA_N_ENDPOINTS];
333 	uchar_t			usb_shared_taskq_ref_count
334 						[USBA_N_ENDPOINTS];
335 } usba_device_t;
336 
337 #define	USBA_CLIENT_FLAG_SIZE		1
338 #define	USBA_CLIENT_FLAG_ATTACH		0x01
339 #define	USBA_CLIENT_FLAG_EV_CBS		0x02
340 #define	USBA_CLIENT_FLAG_DEV_DATA	0x04
341 
342 _NOTE(MUTEX_PROTECTS_DATA(usba_device::usb_mutex, usba_device))
343 _NOTE(MUTEX_PROTECTS_DATA(usba_device::usb_mutex, usba_evdata))
344 
345 _NOTE(SCHEME_PROTECTS_DATA("chg at attach only",
346 				usba_evdata::ev_rm_cb_id))
347 _NOTE(SCHEME_PROTECTS_DATA("chg at attach only",
348 				usba_evdata::ev_ins_cb_id))
349 _NOTE(SCHEME_PROTECTS_DATA("chg at attach only",
350 				usba_evdata::ev_suspend_cb_id))
351 _NOTE(SCHEME_PROTECTS_DATA("chg at attach only",
352 				usba_evdata::ev_resume_cb_id))
353 
354 /* this should be really stable data */
355 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_serialno_str))
356 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_root_hub_dip))
357 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_root_hubd))
358 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_product_str))
359 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_preferred_driver))
360 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_port))
361 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_n_ifs))
362 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_n_cfgs))
363 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_mfg_str))
364 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_dev_descr))
365 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_ph_list))
366 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_cfg_value))
367 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_cfg_str_descr))
368 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_cfg_length))
369 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_cfg_array))
370 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_cfg_array_len))
371 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_cfg_array_length))
372 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_cfg_array_len_length))
373 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_cfg))
374 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_hcdi_ops))
375 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_addr))
376 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_port_status))
377 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::rm_cookie))
378 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::ins_cookie))
379 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::suspend_cookie))
380 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::resume_cookie))
381 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_client_flags))
382 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_client_attach_list))
383 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_client_ev_cb_list))
384 _NOTE(DATA_READABLE_WITHOUT_LOCK(usba_device::usb_dip))
385 _NOTE(SCHEME_PROTECTS_DATA("set at device creation",
386 					usba_device::usb_shared_taskq))
387 
388 /*
389  * serialization in drivers
390  */
391 typedef struct usba_serialization_impl {
392 	dev_info_t	*s_dip;
393 	kcondvar_t	s_cv;
394 	kmutex_t	s_mutex;
395 	kthread_t	*s_thread;
396 	int		s_count;
397 	uint_t		s_flag;
398 } usba_serialization_impl_t;
399 
400 _NOTE(SCHEME_PROTECTS_DATA("unshared private data",
401 				usba_serialization_impl))
402 
403 #ifdef	__cplusplus
404 }
405 #endif
406 
407 #endif	/* _SYS_USB_USBA_USBA_TYPES_H */
408