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