xref: /illumos-gate/usr/src/uts/common/sys/usb/usbai.h (revision 7c478bd9)
1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * CDDL HEADER START
3*7c478bd9Sstevel@tonic-gate  *
4*7c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*7c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*7c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*7c478bd9Sstevel@tonic-gate  * with the License.
8*7c478bd9Sstevel@tonic-gate  *
9*7c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*7c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*7c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*7c478bd9Sstevel@tonic-gate  * and limitations under the License.
13*7c478bd9Sstevel@tonic-gate  *
14*7c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*7c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*7c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*7c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*7c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*7c478bd9Sstevel@tonic-gate  *
20*7c478bd9Sstevel@tonic-gate  * CDDL HEADER END
21*7c478bd9Sstevel@tonic-gate  *
22*7c478bd9Sstevel@tonic-gate  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
23*7c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
24*7c478bd9Sstevel@tonic-gate  */
25*7c478bd9Sstevel@tonic-gate 
26*7c478bd9Sstevel@tonic-gate #ifndef	_SYS_USB_USBAI_H
27*7c478bd9Sstevel@tonic-gate #define	_SYS_USB_USBAI_H
28*7c478bd9Sstevel@tonic-gate 
29*7c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
30*7c478bd9Sstevel@tonic-gate 
31*7c478bd9Sstevel@tonic-gate #ifdef	__cplusplus
32*7c478bd9Sstevel@tonic-gate extern "C" {
33*7c478bd9Sstevel@tonic-gate #endif
34*7c478bd9Sstevel@tonic-gate 
35*7c478bd9Sstevel@tonic-gate /* This header file is for USBA2.0 */
36*7c478bd9Sstevel@tonic-gate #define	USBA_MAJOR_VER 2
37*7c478bd9Sstevel@tonic-gate #define	USBA_MINOR_VER 0
38*7c478bd9Sstevel@tonic-gate 
39*7c478bd9Sstevel@tonic-gate /*
40*7c478bd9Sstevel@tonic-gate  * USBAI: Interfaces Between USBA and Client Driver
41*7c478bd9Sstevel@tonic-gate  *
42*7c478bd9Sstevel@tonic-gate  *
43*7c478bd9Sstevel@tonic-gate  * Universal USB device state management :
44*7c478bd9Sstevel@tonic-gate  *
45*7c478bd9Sstevel@tonic-gate  *	PWRED_DWN---<3----4>--ONLINE---<2-----1>-DISCONNECTED
46*7c478bd9Sstevel@tonic-gate  *	    |			 ^		     |
47*7c478bd9Sstevel@tonic-gate  *	    |			 6		     |
48*7c478bd9Sstevel@tonic-gate  *	    |			 |		     |
49*7c478bd9Sstevel@tonic-gate  *	    |			 5		     |
50*7c478bd9Sstevel@tonic-gate  *	    |			 v		     |
51*7c478bd9Sstevel@tonic-gate  *	    +----5>----------SUSPENDED----<5----7>---+
52*7c478bd9Sstevel@tonic-gate  *
53*7c478bd9Sstevel@tonic-gate  *	1 = Device Unplug
54*7c478bd9Sstevel@tonic-gate  *	2 = Original Device reconnected
55*7c478bd9Sstevel@tonic-gate  *	3 = Device idles for time T & transitions to low power state
56*7c478bd9Sstevel@tonic-gate  *	4 = Remote wakeup by device OR Application kicking off IO to device
57*7c478bd9Sstevel@tonic-gate  *	5 = Notification to save state prior to DDI_SUSPEND
58*7c478bd9Sstevel@tonic-gate  *	6 = Notification to restore state after DDI_RESUME with correct device
59*7c478bd9Sstevel@tonic-gate  *	7 = Notification to restore state after DDI_RESUME with device
60*7c478bd9Sstevel@tonic-gate  *	    disconnected or a wrong device
61*7c478bd9Sstevel@tonic-gate  *
62*7c478bd9Sstevel@tonic-gate  *	NOTE: device states 0x80 to 0xff are device specific and can be
63*7c478bd9Sstevel@tonic-gate  *		used by client drivers
64*7c478bd9Sstevel@tonic-gate  */
65*7c478bd9Sstevel@tonic-gate #define	USB_DEV_ONLINE		1	/* device is online */
66*7c478bd9Sstevel@tonic-gate #define	USB_DEV_DISCONNECTED	2	/* indicates disconnect */
67*7c478bd9Sstevel@tonic-gate #define	USB_DEV_SUSPENDED	3	/* DDI_SUSPEND operation */
68*7c478bd9Sstevel@tonic-gate #define	USB_DEV_PWRED_DOWN	4	/* indicates power off state */
69*7c478bd9Sstevel@tonic-gate 
70*7c478bd9Sstevel@tonic-gate 
71*7c478bd9Sstevel@tonic-gate /*
72*7c478bd9Sstevel@tonic-gate  * ***************************************************************************
73*7c478bd9Sstevel@tonic-gate  * USBA error and status definitions
74*7c478bd9Sstevel@tonic-gate  * ***************************************************************************
75*7c478bd9Sstevel@tonic-gate  */
76*7c478bd9Sstevel@tonic-gate 
77*7c478bd9Sstevel@tonic-gate 
78*7c478bd9Sstevel@tonic-gate /*
79*7c478bd9Sstevel@tonic-gate  * USBA function return values
80*7c478bd9Sstevel@tonic-gate  */
81*7c478bd9Sstevel@tonic-gate #define	USB_SUCCESS		0	/* call success			  */
82*7c478bd9Sstevel@tonic-gate #define	USB_FAILURE		-1	/* unspecified USBA or HCD error  */
83*7c478bd9Sstevel@tonic-gate #define	USB_NO_RESOURCES	-2	/* no resources available	  */
84*7c478bd9Sstevel@tonic-gate #define	USB_NO_BANDWIDTH	-3	/* no bandwidth available	  */
85*7c478bd9Sstevel@tonic-gate #define	USB_NOT_SUPPORTED	-4	/* function not supported by HCD  */
86*7c478bd9Sstevel@tonic-gate #define	USB_PIPE_ERROR		-5	/* error occured on the pipe	  */
87*7c478bd9Sstevel@tonic-gate #define	USB_INVALID_PIPE	-6	/* pipe handle passed is invalid  */
88*7c478bd9Sstevel@tonic-gate #define	USB_NO_FRAME_NUMBER	-7	/* frame No or ASAP not specified */
89*7c478bd9Sstevel@tonic-gate #define	USB_INVALID_START_FRAME	-8	/* starting USB frame not valid	  */
90*7c478bd9Sstevel@tonic-gate #define	USB_HC_HARDWARE_ERROR	-9	/* usb host controller error	  */
91*7c478bd9Sstevel@tonic-gate #define	USB_INVALID_REQUEST	-10	/* request had invalid values	  */
92*7c478bd9Sstevel@tonic-gate #define	USB_INVALID_CONTEXT	-11	/* sleep flag in interrupt context */
93*7c478bd9Sstevel@tonic-gate #define	USB_INVALID_VERSION	-12	/* invalid version specified	  */
94*7c478bd9Sstevel@tonic-gate #define	USB_INVALID_ARGS	-13	/* invalid func args specified	  */
95*7c478bd9Sstevel@tonic-gate #define	USB_INVALID_PERM	-14	/* privileged operation		  */
96*7c478bd9Sstevel@tonic-gate #define	USB_BUSY		-15	/* busy condition		  */
97*7c478bd9Sstevel@tonic-gate 
98*7c478bd9Sstevel@tonic-gate 
99*7c478bd9Sstevel@tonic-gate /*
100*7c478bd9Sstevel@tonic-gate  * USB request completion flags, more than one may be set.
101*7c478bd9Sstevel@tonic-gate  * The following flags are returned after a recovery action by
102*7c478bd9Sstevel@tonic-gate  * HCD or USBA (autoclearing) or callbacks from pipe_close,
103*7c478bd9Sstevel@tonic-gate  * abort, reset, or stop polling.  More than one may be set.
104*7c478bd9Sstevel@tonic-gate  *
105*7c478bd9Sstevel@tonic-gate  * For sync requests, the client should check the request structure
106*7c478bd9Sstevel@tonic-gate  * for this flag to determine what has happened.
107*7c478bd9Sstevel@tonic-gate  *
108*7c478bd9Sstevel@tonic-gate  * All callbacks are queued to preserve order.	Note that if a normal callback
109*7c478bd9Sstevel@tonic-gate  * uses a kernel thread, order is not guaranteed since each callback may use
110*7c478bd9Sstevel@tonic-gate  * its own thread.  The next request will be submitted to the
111*7c478bd9Sstevel@tonic-gate  * HCD after the threads exits.
112*7c478bd9Sstevel@tonic-gate  *
113*7c478bd9Sstevel@tonic-gate  * Exception callbacks using a kernel thread may do auto clearing and no
114*7c478bd9Sstevel@tonic-gate  * new request will be started until this thread has completed its work.
115*7c478bd9Sstevel@tonic-gate  */
116*7c478bd9Sstevel@tonic-gate typedef enum {
117*7c478bd9Sstevel@tonic-gate 	USB_CB_NO_INFO		= 0x00, /* no exception */
118*7c478bd9Sstevel@tonic-gate 	USB_CB_STALL_CLEARED	= 0x01,	/* func stall cleared */
119*7c478bd9Sstevel@tonic-gate 	USB_CB_FUNCTIONAL_STALL	= 0x02,	/* func stall occurred */
120*7c478bd9Sstevel@tonic-gate 	USB_CB_PROTOCOL_STALL	= 0x04,	/* protocal stall occurred */
121*7c478bd9Sstevel@tonic-gate 	USB_CB_RESET_PIPE	= 0x10, /* pipe was reset */
122*7c478bd9Sstevel@tonic-gate 	USB_CB_ASYNC_REQ_FAILED = 0x80, /* thread couldn't be started */
123*7c478bd9Sstevel@tonic-gate 	USB_CB_NO_RESOURCES	= 0x100, /* no resources */
124*7c478bd9Sstevel@tonic-gate 	USB_CB_SUBMIT_FAILED	= 0x200, /* req was queued then submitted */
125*7c478bd9Sstevel@tonic-gate 					/* to HCD which rejected it */
126*7c478bd9Sstevel@tonic-gate 	USB_CB_INTR_CONTEXT	= 0x400 /* Callback is in interrupt context. */
127*7c478bd9Sstevel@tonic-gate } usb_cb_flags_t;
128*7c478bd9Sstevel@tonic-gate 
129*7c478bd9Sstevel@tonic-gate 
130*7c478bd9Sstevel@tonic-gate /*
131*7c478bd9Sstevel@tonic-gate  * completion reason
132*7c478bd9Sstevel@tonic-gate  *
133*7c478bd9Sstevel@tonic-gate  * Set by HCD; only one can be set.
134*7c478bd9Sstevel@tonic-gate  */
135*7c478bd9Sstevel@tonic-gate typedef enum {
136*7c478bd9Sstevel@tonic-gate 	USB_CR_OK		= 0,	/* no errors detected		*/
137*7c478bd9Sstevel@tonic-gate 	USB_CR_CRC		= 1,	/* crc error detected		*/
138*7c478bd9Sstevel@tonic-gate 	USB_CR_BITSTUFFING	= 2,	/* bit stuffing violation	*/
139*7c478bd9Sstevel@tonic-gate 	USB_CR_DATA_TOGGLE_MM	= 3,	/* d/t PID did not match	*/
140*7c478bd9Sstevel@tonic-gate 	USB_CR_STALL		= 4,	/* e/p returned stall PID	*/
141*7c478bd9Sstevel@tonic-gate 	USB_CR_DEV_NOT_RESP	= 5,	/* device not responding	*/
142*7c478bd9Sstevel@tonic-gate 	USB_CR_PID_CHECKFAILURE = 6,	/* check bits on PID failed	*/
143*7c478bd9Sstevel@tonic-gate 	USB_CR_UNEXP_PID	= 7,	/* receive PID was not valid	*/
144*7c478bd9Sstevel@tonic-gate 	USB_CR_DATA_OVERRUN	= 8,	/* data size exceeded		*/
145*7c478bd9Sstevel@tonic-gate 	USB_CR_DATA_UNDERRUN	= 9,	/* less data received		*/
146*7c478bd9Sstevel@tonic-gate 	USB_CR_BUFFER_OVERRUN	= 10,	/* memory write can't keep up	*/
147*7c478bd9Sstevel@tonic-gate 	USB_CR_BUFFER_UNDERRUN	= 11,	/* buffer underrun		*/
148*7c478bd9Sstevel@tonic-gate 	USB_CR_TIMEOUT		= 12,	/* command timed out		*/
149*7c478bd9Sstevel@tonic-gate 	USB_CR_NOT_ACCESSED	= 13,	/* Not accessed by hardware	*/
150*7c478bd9Sstevel@tonic-gate 	USB_CR_NO_RESOURCES	= 14,	/* no resources			*/
151*7c478bd9Sstevel@tonic-gate 	USB_CR_UNSPECIFIED_ERR	= 15,	/* unspecified usba or hcd err	*/
152*7c478bd9Sstevel@tonic-gate 	USB_CR_STOPPED_POLLING	= 16,	/* intr/isoc IN polling stopped	*/
153*7c478bd9Sstevel@tonic-gate 	USB_CR_PIPE_CLOSING	= 17,	/* intr/isoc IN pipe closed	*/
154*7c478bd9Sstevel@tonic-gate 	USB_CR_PIPE_RESET	= 18,	/* intr/isoc IN pipe reset	*/
155*7c478bd9Sstevel@tonic-gate 	USB_CR_NOT_SUPPORTED	= 19,	/* command not supported	*/
156*7c478bd9Sstevel@tonic-gate 	USB_CR_FLUSHED		= 20,	/* this request was flushed	*/
157*7c478bd9Sstevel@tonic-gate 	USB_CR_HC_HARDWARE_ERR	= 21	/* usb host controller error	*/
158*7c478bd9Sstevel@tonic-gate } usb_cr_t;
159*7c478bd9Sstevel@tonic-gate 
160*7c478bd9Sstevel@tonic-gate 
161*7c478bd9Sstevel@tonic-gate /*
162*7c478bd9Sstevel@tonic-gate  * ***************************************************************************
163*7c478bd9Sstevel@tonic-gate  * General definitions, used all over
164*7c478bd9Sstevel@tonic-gate  * ***************************************************************************
165*7c478bd9Sstevel@tonic-gate  *
166*7c478bd9Sstevel@tonic-gate  *	A pipe handle is returned by usb_pipe_open() on success for
167*7c478bd9Sstevel@tonic-gate  *	all pipes except the default pipe which is accessed from
168*7c478bd9Sstevel@tonic-gate  *	the registration structure.  Placed here as forward referenced by
169*7c478bd9Sstevel@tonic-gate  *	usb_client_dev_data_t below.
170*7c478bd9Sstevel@tonic-gate  *
171*7c478bd9Sstevel@tonic-gate  *	The pipe_handle is opaque to the client driver.
172*7c478bd9Sstevel@tonic-gate  */
173*7c478bd9Sstevel@tonic-gate typedef	struct usb_pipe_handle	*usb_pipe_handle_t;
174*7c478bd9Sstevel@tonic-gate 
175*7c478bd9Sstevel@tonic-gate /*
176*7c478bd9Sstevel@tonic-gate  * General opaque pointer.
177*7c478bd9Sstevel@tonic-gate  */
178*7c478bd9Sstevel@tonic-gate typedef struct usb_opaque *usb_opaque_t;
179*7c478bd9Sstevel@tonic-gate 
180*7c478bd9Sstevel@tonic-gate 
181*7c478bd9Sstevel@tonic-gate /*
182*7c478bd9Sstevel@tonic-gate  * USB flags argument to USBA interfaces
183*7c478bd9Sstevel@tonic-gate  */
184*7c478bd9Sstevel@tonic-gate typedef enum {
185*7c478bd9Sstevel@tonic-gate 	/* do not block until resources are available */
186*7c478bd9Sstevel@tonic-gate 	USB_FLAGS_NOSLEEP		= 0x0000,
187*7c478bd9Sstevel@tonic-gate 	/* block until resources are available */
188*7c478bd9Sstevel@tonic-gate 	USB_FLAGS_SLEEP			= 0x0100,
189*7c478bd9Sstevel@tonic-gate 	/* reserved */
190*7c478bd9Sstevel@tonic-gate 	USB_FLAGS_RESERVED		= 0xFE00
191*7c478bd9Sstevel@tonic-gate } usb_flags_t;
192*7c478bd9Sstevel@tonic-gate 
193*7c478bd9Sstevel@tonic-gate 
194*7c478bd9Sstevel@tonic-gate /*
195*7c478bd9Sstevel@tonic-gate  * ***************************************************************************
196*7c478bd9Sstevel@tonic-gate  * Descriptor definitions (from USB 2.0 specification, chapter 9)
197*7c478bd9Sstevel@tonic-gate  * ***************************************************************************
198*7c478bd9Sstevel@tonic-gate  */
199*7c478bd9Sstevel@tonic-gate 
200*7c478bd9Sstevel@tonic-gate 
201*7c478bd9Sstevel@tonic-gate /*
202*7c478bd9Sstevel@tonic-gate  * USB Descriptor Management
203*7c478bd9Sstevel@tonic-gate  *
204*7c478bd9Sstevel@tonic-gate  * Standard USB descriptors:
205*7c478bd9Sstevel@tonic-gate  *
206*7c478bd9Sstevel@tonic-gate  * USB devices present their configuration information in response to
207*7c478bd9Sstevel@tonic-gate  * a GET_DESCRIPTOR request in a form which is little-endian and,
208*7c478bd9Sstevel@tonic-gate  * for multibyte integers, unaligned.  It is also position-dependent,
209*7c478bd9Sstevel@tonic-gate  * which makes non-sequential access to particular interface or
210*7c478bd9Sstevel@tonic-gate  * endpoint data inconvenient.
211*7c478bd9Sstevel@tonic-gate  * A GET_DESCRIPTOR request may yield a chunk of data that contains
212*7c478bd9Sstevel@tonic-gate  * multiple descriptor types.  For example, a GET_DESCRIPTOR request
213*7c478bd9Sstevel@tonic-gate  * for a CONFIGURATION descriptor could return the configuration
214*7c478bd9Sstevel@tonic-gate  * descriptor followed by an interface descriptor and the relevant
215*7c478bd9Sstevel@tonic-gate  * endpoint descriptors.
216*7c478bd9Sstevel@tonic-gate  *
217*7c478bd9Sstevel@tonic-gate  * usb_get_dev_data() interface provides an easy way to get all
218*7c478bd9Sstevel@tonic-gate  * the descriptors and avoids parsing standard descriptors by each
219*7c478bd9Sstevel@tonic-gate  * client driver
220*7c478bd9Sstevel@tonic-gate  *
221*7c478bd9Sstevel@tonic-gate  * usb_dev_descr:
222*7c478bd9Sstevel@tonic-gate  *	usb device descriptor, refer to	USB 2.0/9.6.1,
223*7c478bd9Sstevel@tonic-gate  */
224*7c478bd9Sstevel@tonic-gate typedef struct usb_dev_descr {
225*7c478bd9Sstevel@tonic-gate 	uint8_t		bLength;	/* descriptor size		*/
226*7c478bd9Sstevel@tonic-gate 	uint8_t		bDescriptorType; /* set to DEVICE		*/
227*7c478bd9Sstevel@tonic-gate 	uint16_t	bcdUSB;		/* USB spec rel. number	in bcd	*/
228*7c478bd9Sstevel@tonic-gate 	uint8_t		bDeviceClass;	/* class code			*/
229*7c478bd9Sstevel@tonic-gate 	uint8_t		bDeviceSubClass; /* sub	class code		*/
230*7c478bd9Sstevel@tonic-gate 	uint8_t		bDeviceProtocol; /* protocol code		*/
231*7c478bd9Sstevel@tonic-gate 	uint8_t		bMaxPacketSize0; /* max	pkt size of e/p	0	*/
232*7c478bd9Sstevel@tonic-gate 	uint16_t	idVendor;	/* vendor ID			*/
233*7c478bd9Sstevel@tonic-gate 	uint16_t	idProduct;	/* product ID			*/
234*7c478bd9Sstevel@tonic-gate 	uint16_t	bcdDevice;	/* device release number in bcd	*/
235*7c478bd9Sstevel@tonic-gate 	uint8_t		iManufacturer;	/* manufacturing string		*/
236*7c478bd9Sstevel@tonic-gate 	uint8_t		iProduct;	/* product string		*/
237*7c478bd9Sstevel@tonic-gate 	uint8_t		iSerialNumber;	/* serial number string index	*/
238*7c478bd9Sstevel@tonic-gate 	uint8_t		bNumConfigurations; /* #configs for device	*/
239*7c478bd9Sstevel@tonic-gate } usb_dev_descr_t;
240*7c478bd9Sstevel@tonic-gate 
241*7c478bd9Sstevel@tonic-gate 
242*7c478bd9Sstevel@tonic-gate /*
243*7c478bd9Sstevel@tonic-gate  * USB Device Qualifier Descriptor
244*7c478bd9Sstevel@tonic-gate  *
245*7c478bd9Sstevel@tonic-gate  * The device_qualifier descriptor describes information about a High
246*7c478bd9Sstevel@tonic-gate  * speed capable device that would change if the device were operating
247*7c478bd9Sstevel@tonic-gate  * at other (Full) speed. Example: if the device is currently operating
248*7c478bd9Sstevel@tonic-gate  * at Full-speed, the device_qualifier returns information about how if
249*7c478bd9Sstevel@tonic-gate  * would operate at high-speed and vice-versa.
250*7c478bd9Sstevel@tonic-gate  *
251*7c478bd9Sstevel@tonic-gate  * usb_dev_qlf_descr:
252*7c478bd9Sstevel@tonic-gate  *
253*7c478bd9Sstevel@tonic-gate  *	usb device qualifier descriptor, refer to USB 2.0/9.6.2
254*7c478bd9Sstevel@tonic-gate  */
255*7c478bd9Sstevel@tonic-gate typedef struct usb_dev_qlf_descr {
256*7c478bd9Sstevel@tonic-gate 	uint8_t		bLength;	/* descriptor size		*/
257*7c478bd9Sstevel@tonic-gate 	uint8_t		bDescriptorType; /* set to DEVICE		*/
258*7c478bd9Sstevel@tonic-gate 	uint16_t	bcdUSB;		/* USB spec rel. number	in bcd	*/
259*7c478bd9Sstevel@tonic-gate 	uint8_t		bDeviceClass;	/* class code			*/
260*7c478bd9Sstevel@tonic-gate 	uint8_t		bDeviceSubClass; /* sub	class code		*/
261*7c478bd9Sstevel@tonic-gate 	uint8_t		bDeviceProtocol; /* protocol code		*/
262*7c478bd9Sstevel@tonic-gate 	uint8_t		bMaxPacketSize0; /* max	pkt size of e/p	0	*/
263*7c478bd9Sstevel@tonic-gate 	uint8_t		bNumConfigurations; /* #configs for device	*/
264*7c478bd9Sstevel@tonic-gate 	uint8_t		bReserved;	/* reserved field		*/
265*7c478bd9Sstevel@tonic-gate } usb_dev_qlf_descr_t;
266*7c478bd9Sstevel@tonic-gate 
267*7c478bd9Sstevel@tonic-gate 
268*7c478bd9Sstevel@tonic-gate /*
269*7c478bd9Sstevel@tonic-gate  * usb_cfg_descr:
270*7c478bd9Sstevel@tonic-gate  *	usb configuration descriptor, refer to USB 2.0/9.6.3
271*7c478bd9Sstevel@tonic-gate  */
272*7c478bd9Sstevel@tonic-gate typedef struct usb_cfg_descr {
273*7c478bd9Sstevel@tonic-gate 	uint8_t		bLength;	/* descriptor size		*/
274*7c478bd9Sstevel@tonic-gate 	uint8_t		bDescriptorType; /* set to CONFIGURATION	*/
275*7c478bd9Sstevel@tonic-gate 	uint16_t	wTotalLength;	/* total length of data returned */
276*7c478bd9Sstevel@tonic-gate 	uint8_t		bNumInterfaces;	/* # interfaces	in config	*/
277*7c478bd9Sstevel@tonic-gate 	uint8_t		bConfigurationValue; /* arg for SetConfiguration */
278*7c478bd9Sstevel@tonic-gate 	uint8_t		iConfiguration;	/* configuration string		*/
279*7c478bd9Sstevel@tonic-gate 	uint8_t		bmAttributes;	/* config characteristics	*/
280*7c478bd9Sstevel@tonic-gate 	uint8_t		bMaxPower;	/* max pwr consumption		*/
281*7c478bd9Sstevel@tonic-gate } usb_cfg_descr_t;
282*7c478bd9Sstevel@tonic-gate 
283*7c478bd9Sstevel@tonic-gate /*
284*7c478bd9Sstevel@tonic-gate  * Default configuration index setting for devices with multiple
285*7c478bd9Sstevel@tonic-gate  * configurations. Note the distinction between config index and config
286*7c478bd9Sstevel@tonic-gate  * number
287*7c478bd9Sstevel@tonic-gate  */
288*7c478bd9Sstevel@tonic-gate #define	USB_DEV_DEFAULT_CONFIG_INDEX	0
289*7c478bd9Sstevel@tonic-gate 
290*7c478bd9Sstevel@tonic-gate /*
291*7c478bd9Sstevel@tonic-gate  * bmAttribute values for Configuration Descriptor
292*7c478bd9Sstevel@tonic-gate  */
293*7c478bd9Sstevel@tonic-gate #define	USB_CFG_ATTR_SELFPWR		0x40
294*7c478bd9Sstevel@tonic-gate #define	USB_CFG_ATTR_REMOTE_WAKEUP	0x20
295*7c478bd9Sstevel@tonic-gate 
296*7c478bd9Sstevel@tonic-gate 
297*7c478bd9Sstevel@tonic-gate /*
298*7c478bd9Sstevel@tonic-gate  * USB Other Speed Configuration Descriptor
299*7c478bd9Sstevel@tonic-gate  *
300*7c478bd9Sstevel@tonic-gate  * The other_speed_configuration descriptor describes a configuration of
301*7c478bd9Sstevel@tonic-gate  * a High speed capable device if it were operating at its other possible
302*7c478bd9Sstevel@tonic-gate  * (Full) speed and vice-versa.
303*7c478bd9Sstevel@tonic-gate  *
304*7c478bd9Sstevel@tonic-gate  * usb_other_speed_cfg_descr:
305*7c478bd9Sstevel@tonic-gate  *	usb other speed configuration descriptor, refer to USB 2.0/9.6.4
306*7c478bd9Sstevel@tonic-gate  */
307*7c478bd9Sstevel@tonic-gate typedef struct usb_other_speed_cfg_descr {
308*7c478bd9Sstevel@tonic-gate 	uint8_t		bLength;	/* descriptor size		*/
309*7c478bd9Sstevel@tonic-gate 	uint8_t		bDescriptorType; /* set to CONFIGURATION	*/
310*7c478bd9Sstevel@tonic-gate 	uint16_t	wTotalLength;	/* total length of data returned */
311*7c478bd9Sstevel@tonic-gate 	uint8_t		bNumInterfaces;	/* # interfaces	in config	*/
312*7c478bd9Sstevel@tonic-gate 	uint8_t		bConfigurationValue; /* arg for SetConfiguration */
313*7c478bd9Sstevel@tonic-gate 	uint8_t		iConfiguration;	/* configuration string		*/
314*7c478bd9Sstevel@tonic-gate 	uint8_t		bmAttributes;	/* config characteristics	*/
315*7c478bd9Sstevel@tonic-gate 	uint8_t		bMaxPower;	/* max pwr consumption		*/
316*7c478bd9Sstevel@tonic-gate } usb_other_speed_cfg_descr_t;
317*7c478bd9Sstevel@tonic-gate 
318*7c478bd9Sstevel@tonic-gate 
319*7c478bd9Sstevel@tonic-gate /*
320*7c478bd9Sstevel@tonic-gate  * usb_if_descr:
321*7c478bd9Sstevel@tonic-gate  *	usb interface descriptor, refer	to USB 2.0/9.6.5
322*7c478bd9Sstevel@tonic-gate  */
323*7c478bd9Sstevel@tonic-gate typedef  struct usb_if_descr {
324*7c478bd9Sstevel@tonic-gate 	uint8_t		bLength;		/* descriptor size	*/
325*7c478bd9Sstevel@tonic-gate 	uint8_t		bDescriptorType;	/* set to INTERFACE	*/
326*7c478bd9Sstevel@tonic-gate 	uint8_t		bInterfaceNumber;	/* interface number	*/
327*7c478bd9Sstevel@tonic-gate 	uint8_t		bAlternateSetting;	/* alt. interface number */
328*7c478bd9Sstevel@tonic-gate 	uint8_t		bNumEndpoints;		/* # of endpoints	*/
329*7c478bd9Sstevel@tonic-gate 	uint8_t		bInterfaceClass;	/* class code		*/
330*7c478bd9Sstevel@tonic-gate 	uint8_t		bInterfaceSubClass;	/* sub class code	*/
331*7c478bd9Sstevel@tonic-gate 	uint8_t		bInterfaceProtocol;	/* protocol code	*/
332*7c478bd9Sstevel@tonic-gate 	uint8_t		iInterface;		/* description string	*/
333*7c478bd9Sstevel@tonic-gate } usb_if_descr_t;
334*7c478bd9Sstevel@tonic-gate 
335*7c478bd9Sstevel@tonic-gate 
336*7c478bd9Sstevel@tonic-gate /*
337*7c478bd9Sstevel@tonic-gate  * usb_ep_descr:
338*7c478bd9Sstevel@tonic-gate  *	usb endpoint descriptor, refer to USB 2.0/9.6.6
339*7c478bd9Sstevel@tonic-gate  */
340*7c478bd9Sstevel@tonic-gate typedef struct usb_ep_descr {
341*7c478bd9Sstevel@tonic-gate 	uint8_t		bLength;		/* descriptor size	*/
342*7c478bd9Sstevel@tonic-gate 	uint8_t		bDescriptorType;	/* set to ENDPOINT	*/
343*7c478bd9Sstevel@tonic-gate 	uint8_t		bEndpointAddress;	/* address of this e/p */
344*7c478bd9Sstevel@tonic-gate 	uint8_t		bmAttributes;		/* transfer type	*/
345*7c478bd9Sstevel@tonic-gate 	uint16_t	wMaxPacketSize;		/* maximum packet size	*/
346*7c478bd9Sstevel@tonic-gate 	uint8_t		bInterval;		/* e/p polling interval */
347*7c478bd9Sstevel@tonic-gate } usb_ep_descr_t;
348*7c478bd9Sstevel@tonic-gate 
349*7c478bd9Sstevel@tonic-gate /*
350*7c478bd9Sstevel@tonic-gate  * bEndpointAddress masks
351*7c478bd9Sstevel@tonic-gate  */
352*7c478bd9Sstevel@tonic-gate #define	USB_EP_NUM_MASK		0x0F		/* endpoint number mask */
353*7c478bd9Sstevel@tonic-gate #define	USB_EP_DIR_MASK		0x80		/* direction mask */
354*7c478bd9Sstevel@tonic-gate #define	USB_EP_DIR_OUT		0x00		/* OUT endpoint */
355*7c478bd9Sstevel@tonic-gate #define	USB_EP_DIR_IN		0x80		/* IN endpoint */
356*7c478bd9Sstevel@tonic-gate 
357*7c478bd9Sstevel@tonic-gate /*
358*7c478bd9Sstevel@tonic-gate  * bmAttribute transfer types for endpoints
359*7c478bd9Sstevel@tonic-gate  */
360*7c478bd9Sstevel@tonic-gate #define	USB_EP_ATTR_MASK	0x03		/* transfer type mask */
361*7c478bd9Sstevel@tonic-gate #define	USB_EP_ATTR_CONTROL	0x00		/* control transfer */
362*7c478bd9Sstevel@tonic-gate #define	USB_EP_ATTR_ISOCH	0x01		/* isochronous transfer */
363*7c478bd9Sstevel@tonic-gate #define	USB_EP_ATTR_BULK	0x02		/* bulk transfer */
364*7c478bd9Sstevel@tonic-gate #define	USB_EP_ATTR_INTR	0x03		/* interrupt transfer */
365*7c478bd9Sstevel@tonic-gate 
366*7c478bd9Sstevel@tonic-gate /*
367*7c478bd9Sstevel@tonic-gate  * bmAttribute synchronization types for endpoints (isochronous only)
368*7c478bd9Sstevel@tonic-gate  */
369*7c478bd9Sstevel@tonic-gate #define	USB_EP_SYNC_MASK	0x0C		/* synchronization mask */
370*7c478bd9Sstevel@tonic-gate #define	USB_EP_SYNC_NONE	0x00		/* no synchronization */
371*7c478bd9Sstevel@tonic-gate #define	USB_EP_SYNC_ASYNC	0x04		/* asynchronous */
372*7c478bd9Sstevel@tonic-gate #define	USB_EP_SYNC_ADPT	0x08		/* adaptive */
373*7c478bd9Sstevel@tonic-gate #define	USB_EP_SYNC_SYNC	0x0C		/* synchronous */
374*7c478bd9Sstevel@tonic-gate 
375*7c478bd9Sstevel@tonic-gate /*
376*7c478bd9Sstevel@tonic-gate  * bmAttribute synchronization feedback types for endpoints (isochronous only)
377*7c478bd9Sstevel@tonic-gate  */
378*7c478bd9Sstevel@tonic-gate #define	USB_EP_USAGE_MASK	0x30		/* sync feedback mask */
379*7c478bd9Sstevel@tonic-gate #define	USB_EP_USAGE_DATA	0x00		/* data endpoint */
380*7c478bd9Sstevel@tonic-gate #define	USB_EP_USAGE_FEED	0x10		/* feedback endpoint */
381*7c478bd9Sstevel@tonic-gate #define	USB_EP_USAGE_IMPL	0x20		/* implicit feedback endpoint */
382*7c478bd9Sstevel@tonic-gate 
383*7c478bd9Sstevel@tonic-gate /*
384*7c478bd9Sstevel@tonic-gate  * wMaxPacketSize values for endpoints (isoch and interrupt, high speed only)
385*7c478bd9Sstevel@tonic-gate  */
386*7c478bd9Sstevel@tonic-gate #define	USB_EP_MAX_PKTSZ_MASK	0x03FF		/* Mask for packetsize bits */
387*7c478bd9Sstevel@tonic-gate #define	USB_EP_MAX_XACTS_MASK	0x0C00		/* Max Transactns/microframe */
388*7c478bd9Sstevel@tonic-gate #define	USB_EP_MAX_XACTS_SHIFT	10		/* Above is 10 bits from end */
389*7c478bd9Sstevel@tonic-gate 
390*7c478bd9Sstevel@tonic-gate /*
391*7c478bd9Sstevel@tonic-gate  * Ranges for endpoint parameter values.
392*7c478bd9Sstevel@tonic-gate  */
393*7c478bd9Sstevel@tonic-gate 
394*7c478bd9Sstevel@tonic-gate /* Min and Max NAK rates for high sped control endpoints. */
395*7c478bd9Sstevel@tonic-gate #define	USB_EP_MIN_HIGH_CONTROL_INTRVL	0
396*7c478bd9Sstevel@tonic-gate #define	USB_EP_MAX_HIGH_CONTROL_INTRVL	255
397*7c478bd9Sstevel@tonic-gate 
398*7c478bd9Sstevel@tonic-gate /* Min and Max NAK rates for high speed bulk endpoints. */
399*7c478bd9Sstevel@tonic-gate #define	USB_EP_MIN_HIGH_BULK_INTRVL	0
400*7c478bd9Sstevel@tonic-gate #define	USB_EP_MAX_HIGH_BULK_INTRVL	255
401*7c478bd9Sstevel@tonic-gate 
402*7c478bd9Sstevel@tonic-gate /* Min and Max polling intervals for low, full speed interrupt endpoints. */
403*7c478bd9Sstevel@tonic-gate #define	USB_EP_MIN_LOW_INTR_INTRVL	1
404*7c478bd9Sstevel@tonic-gate #define	USB_EP_MAX_LOW_INTR_INTRVL	255
405*7c478bd9Sstevel@tonic-gate #define	USB_EP_MIN_FULL_INTR_INTRVL	1
406*7c478bd9Sstevel@tonic-gate #define	USB_EP_MAX_FULL_INTR_INTRVL	255
407*7c478bd9Sstevel@tonic-gate 
408*7c478bd9Sstevel@tonic-gate /*
409*7c478bd9Sstevel@tonic-gate  * Min and Max polling intervals for high speed interrupt endpoints, and for
410*7c478bd9Sstevel@tonic-gate  * isochronous endpoints.
411*7c478bd9Sstevel@tonic-gate  * Note that the interval is 2**(value-1).  See Section 9.6.6 of USB 2.0 spec.
412*7c478bd9Sstevel@tonic-gate  */
413*7c478bd9Sstevel@tonic-gate #define	USB_EP_MIN_HIGH_INTR_INTRVL	1
414*7c478bd9Sstevel@tonic-gate #define	USB_EP_MAX_HIGH_INTR_INTRVL	16
415*7c478bd9Sstevel@tonic-gate #define	USB_EP_MIN_FULL_ISOCH_INTRVL	1
416*7c478bd9Sstevel@tonic-gate #define	USB_EP_MAX_FULL_ISOCH_INTRVL	16
417*7c478bd9Sstevel@tonic-gate #define	USB_EP_MIN_HIGH_ISOCH_INTRVL	1
418*7c478bd9Sstevel@tonic-gate #define	USB_EP_MAX_HIGH_ISOCH_INTRVL	16
419*7c478bd9Sstevel@tonic-gate 
420*7c478bd9Sstevel@tonic-gate /*
421*7c478bd9Sstevel@tonic-gate  * usb_string_descr:
422*7c478bd9Sstevel@tonic-gate  *	usb string descriptor, refer to	 USB 2.0/9.6.7
423*7c478bd9Sstevel@tonic-gate  */
424*7c478bd9Sstevel@tonic-gate typedef struct usb_string_descr {
425*7c478bd9Sstevel@tonic-gate 	uint8_t		bLength;		/* descr size */
426*7c478bd9Sstevel@tonic-gate 	uint8_t		bDescriptorType;	/* set to STRING */
427*7c478bd9Sstevel@tonic-gate 	uint8_t		bString[1];		/* variable length unicode */
428*7c478bd9Sstevel@tonic-gate 						/* encoded string	*/
429*7c478bd9Sstevel@tonic-gate } usb_string_descr_t;
430*7c478bd9Sstevel@tonic-gate 
431*7c478bd9Sstevel@tonic-gate #define	USB_MAXSTRINGLEN	255		/* max string descr length */
432*7c478bd9Sstevel@tonic-gate 
433*7c478bd9Sstevel@tonic-gate 
434*7c478bd9Sstevel@tonic-gate /*
435*7c478bd9Sstevel@tonic-gate  * ***************************************************************************
436*7c478bd9Sstevel@tonic-gate  * Client driver registration with USBA
437*7c478bd9Sstevel@tonic-gate  * ***************************************************************************
438*7c478bd9Sstevel@tonic-gate  *
439*7c478bd9Sstevel@tonic-gate  *	The client registers with USBA during attach in two steps
440*7c478bd9Sstevel@tonic-gate  *	using usb_client_attach() and usb_get_dev_data(). On completion, the
441*7c478bd9Sstevel@tonic-gate  *	registration data has been initialized.  Most data items are
442*7c478bd9Sstevel@tonic-gate  *	straightforward.  Among the items returned in the data is the tree of
443*7c478bd9Sstevel@tonic-gate  *	parsed descriptors, in dev_cfg;	 the number of configurations parsed,
444*7c478bd9Sstevel@tonic-gate  *	in dev_n_cfg; a pointer to the current configuration in the tree,
445*7c478bd9Sstevel@tonic-gate  *	in dev_curr_cfg; the index of the first valid interface in the
446*7c478bd9Sstevel@tonic-gate  *	tree, in dev_curr_if, and a parse level that accurately reflects what
447*7c478bd9Sstevel@tonic-gate  *	is in the tree, in dev_parse_level.
448*7c478bd9Sstevel@tonic-gate  */
449*7c478bd9Sstevel@tonic-gate 
450*7c478bd9Sstevel@tonic-gate 
451*7c478bd9Sstevel@tonic-gate /*
452*7c478bd9Sstevel@tonic-gate  * ***************************************************************************
453*7c478bd9Sstevel@tonic-gate  * Data structures used in the configuration tree
454*7c478bd9Sstevel@tonic-gate  * ***************************************************************************
455*7c478bd9Sstevel@tonic-gate  */
456*7c478bd9Sstevel@tonic-gate 
457*7c478bd9Sstevel@tonic-gate /*
458*7c478bd9Sstevel@tonic-gate  * Tree data structure for each configuration in the tree
459*7c478bd9Sstevel@tonic-gate  */
460*7c478bd9Sstevel@tonic-gate typedef struct usb_cfg_data {
461*7c478bd9Sstevel@tonic-gate 	struct usb_cfg_descr	cfg_descr;	/* parsed config descr */
462*7c478bd9Sstevel@tonic-gate 	struct usb_if_data	*cfg_if;	/* interfaces for this cfg */
463*7c478bd9Sstevel@tonic-gate 						/* indexed by interface num */
464*7c478bd9Sstevel@tonic-gate 	struct usb_cvs_data	*cfg_cvs;	/* class/vendor specific */
465*7c478bd9Sstevel@tonic-gate 						/* descrs mod/extend cfg */
466*7c478bd9Sstevel@tonic-gate 	char			*cfg_str;	/* string descriptor */
467*7c478bd9Sstevel@tonic-gate 	uint_t			cfg_n_if;	/* #elements in cfg_if[] */
468*7c478bd9Sstevel@tonic-gate 	uint_t			cfg_n_cvs;	/* #elements in cfg_cvs[] */
469*7c478bd9Sstevel@tonic-gate 	uint_t			cfg_strsize;	/* size of string descr */
470*7c478bd9Sstevel@tonic-gate } usb_cfg_data_t;
471*7c478bd9Sstevel@tonic-gate 
472*7c478bd9Sstevel@tonic-gate 
473*7c478bd9Sstevel@tonic-gate /*
474*7c478bd9Sstevel@tonic-gate  * Tree data structure for each alternate interface set
475*7c478bd9Sstevel@tonic-gate  * in each represented configuration
476*7c478bd9Sstevel@tonic-gate  */
477*7c478bd9Sstevel@tonic-gate typedef struct usb_if_data {
478*7c478bd9Sstevel@tonic-gate 	struct usb_alt_if_data	*if_alt;	/* sparse array of alts */
479*7c478bd9Sstevel@tonic-gate 						/* indexed by alt setting */
480*7c478bd9Sstevel@tonic-gate 	uint_t			if_n_alt;	/* #elements in if_alt[] */
481*7c478bd9Sstevel@tonic-gate } usb_if_data_t;
482*7c478bd9Sstevel@tonic-gate 
483*7c478bd9Sstevel@tonic-gate 
484*7c478bd9Sstevel@tonic-gate /*
485*7c478bd9Sstevel@tonic-gate  * Tree data structure for each alternate of each alternate interface set
486*7c478bd9Sstevel@tonic-gate  */
487*7c478bd9Sstevel@tonic-gate typedef struct usb_alt_if_data {
488*7c478bd9Sstevel@tonic-gate 	usb_if_descr_t		altif_descr;	/* parsed alternate if descr */
489*7c478bd9Sstevel@tonic-gate 	struct usb_ep_data	*altif_ep;	/* endpts for alt if */
490*7c478bd9Sstevel@tonic-gate 						/* (not a sparse array */
491*7c478bd9Sstevel@tonic-gate 	struct usb_cvs_data	*altif_cvs;	/* cvs for this alt if */
492*7c478bd9Sstevel@tonic-gate 	char			*altif_str;	/* string descriptor */
493*7c478bd9Sstevel@tonic-gate 	uint_t			altif_n_ep;	/* #elements in altif_ep[] */
494*7c478bd9Sstevel@tonic-gate 	uint_t			altif_n_cvs;	/* #elements in  altif_cvs[] */
495*7c478bd9Sstevel@tonic-gate 	uint_t			altif_strsize;	/* size of string descr */
496*7c478bd9Sstevel@tonic-gate } usb_alt_if_data_t;
497*7c478bd9Sstevel@tonic-gate 
498*7c478bd9Sstevel@tonic-gate 
499*7c478bd9Sstevel@tonic-gate /*
500*7c478bd9Sstevel@tonic-gate  * Tree data structure for each endpoint of each alternate
501*7c478bd9Sstevel@tonic-gate  */
502*7c478bd9Sstevel@tonic-gate typedef struct usb_ep_data {
503*7c478bd9Sstevel@tonic-gate 	usb_ep_descr_t		ep_descr;	/* endpoint descriptor */
504*7c478bd9Sstevel@tonic-gate 	struct usb_cvs_data	*ep_cvs;	/* cv mod/extending this ep */
505*7c478bd9Sstevel@tonic-gate 	uint_t			ep_n_cvs;	/* #elements in ep_cvs[] */
506*7c478bd9Sstevel@tonic-gate } usb_ep_data_t;
507*7c478bd9Sstevel@tonic-gate 
508*7c478bd9Sstevel@tonic-gate 
509*7c478bd9Sstevel@tonic-gate /*
510*7c478bd9Sstevel@tonic-gate  * Tree data structure for each class/vendor specific descriptor
511*7c478bd9Sstevel@tonic-gate  */
512*7c478bd9Sstevel@tonic-gate typedef struct usb_cvs_data {
513*7c478bd9Sstevel@tonic-gate 	uchar_t			*cvs_buf;	/* raw data of cvs descr */
514*7c478bd9Sstevel@tonic-gate 	uint_t			cvs_buf_len;	/* cvs_buf size */
515*7c478bd9Sstevel@tonic-gate } usb_cvs_data_t;
516*7c478bd9Sstevel@tonic-gate 
517*7c478bd9Sstevel@tonic-gate 
518*7c478bd9Sstevel@tonic-gate /*
519*7c478bd9Sstevel@tonic-gate  *	Parse_level determines the extent to which the tree is built, the amount
520*7c478bd9Sstevel@tonic-gate  *	of parsing usb_client_attach() is to do.  It has the following values:
521*7c478bd9Sstevel@tonic-gate  *
522*7c478bd9Sstevel@tonic-gate  *	USB_PARSE_LVL_NONE - Build no tree.  dev_n_cfg will return 0, dev_cfg
523*7c478bd9Sstevel@tonic-gate  *			     will return NULL, the dev_curr_xxx fields will be
524*7c478bd9Sstevel@tonic-gate  *			     invalid.
525*7c478bd9Sstevel@tonic-gate  *	USB_PARSE_LVL_IF   - Parse configured interface only, if configuration#
526*7c478bd9Sstevel@tonic-gate  *			     and interface properties are set (as when different
527*7c478bd9Sstevel@tonic-gate  *			     interfaces are viewed by the OS as different device
528*7c478bd9Sstevel@tonic-gate  *			     instances). If an OS device instance is set up to
529*7c478bd9Sstevel@tonic-gate  *			     represent an entire physical device, this works
530*7c478bd9Sstevel@tonic-gate  *			     like USB_PARSE_LVL_ALL.
531*7c478bd9Sstevel@tonic-gate  *	USB_PARSE_LVL_CFG  - Parse entire configuration of configured interface
532*7c478bd9Sstevel@tonic-gate  *			     only.  This is like USB_PARSE_LVL_IF except entire
533*7c478bd9Sstevel@tonic-gate  *			     configuration is returned.
534*7c478bd9Sstevel@tonic-gate  *	USB_PARSE_LVL_ALL  - Parse entire device (all configurations), even
535*7c478bd9Sstevel@tonic-gate  *			     when driver is bound to a single interface of a
536*7c478bd9Sstevel@tonic-gate  *			     single configuration.
537*7c478bd9Sstevel@tonic-gate  */
538*7c478bd9Sstevel@tonic-gate typedef enum {
539*7c478bd9Sstevel@tonic-gate 	USB_PARSE_LVL_NONE		= 0,
540*7c478bd9Sstevel@tonic-gate 	USB_PARSE_LVL_IF		= 1,
541*7c478bd9Sstevel@tonic-gate 	USB_PARSE_LVL_CFG		= 2,
542*7c478bd9Sstevel@tonic-gate 	USB_PARSE_LVL_ALL		= 3
543*7c478bd9Sstevel@tonic-gate } usb_reg_parse_lvl_t;
544*7c478bd9Sstevel@tonic-gate 
545*7c478bd9Sstevel@tonic-gate 
546*7c478bd9Sstevel@tonic-gate /*
547*7c478bd9Sstevel@tonic-gate  * Registration data returned by usb_get_dev_data().  Configuration tree roots
548*7c478bd9Sstevel@tonic-gate  * are returned in dev_cfg array.
549*7c478bd9Sstevel@tonic-gate  */
550*7c478bd9Sstevel@tonic-gate typedef struct usb_client_dev_data {
551*7c478bd9Sstevel@tonic-gate 	usb_pipe_handle_t	dev_default_ph;	/* default pipe handle */
552*7c478bd9Sstevel@tonic-gate 	ddi_iblock_cookie_t	dev_iblock_cookie; /* for mutex_init's */
553*7c478bd9Sstevel@tonic-gate 	struct usb_dev_descr	*dev_descr;	/* cooked device descriptor */
554*7c478bd9Sstevel@tonic-gate 	char			*dev_mfg;	/* manufacturing ID */
555*7c478bd9Sstevel@tonic-gate 	char			*dev_product;	/* product ID */
556*7c478bd9Sstevel@tonic-gate 	char			*dev_serial;	/* serial number */
557*7c478bd9Sstevel@tonic-gate 	usb_reg_parse_lvl_t	dev_parse_level; /* USB_PARSE_LVL_* flag */
558*7c478bd9Sstevel@tonic-gate 	struct usb_cfg_data	*dev_cfg;	/* configs for this device */
559*7c478bd9Sstevel@tonic-gate 						/* indexed by config index */
560*7c478bd9Sstevel@tonic-gate 	uint_t			dev_n_cfg;	/* #elements in dev_cfg[] */
561*7c478bd9Sstevel@tonic-gate 	struct usb_cfg_data	*dev_curr_cfg;	/* current cfg */
562*7c478bd9Sstevel@tonic-gate 	int			dev_curr_if;	/* current interface number */
563*7c478bd9Sstevel@tonic-gate } usb_client_dev_data_t;
564*7c478bd9Sstevel@tonic-gate 
565*7c478bd9Sstevel@tonic-gate 
566*7c478bd9Sstevel@tonic-gate /*
567*7c478bd9Sstevel@tonic-gate  * ***************************************************************************
568*7c478bd9Sstevel@tonic-gate  * Device configuration descriptor tree functions
569*7c478bd9Sstevel@tonic-gate  * ***************************************************************************
570*7c478bd9Sstevel@tonic-gate  */
571*7c478bd9Sstevel@tonic-gate 
572*7c478bd9Sstevel@tonic-gate /*
573*7c478bd9Sstevel@tonic-gate  * usb_get_dev_data:
574*7c478bd9Sstevel@tonic-gate  *	returns initialized registration data. 	Most data items are clear.
575*7c478bd9Sstevel@tonic-gate  *	Among the items returned is the tree ofparsed descriptors in dev_cfg;
576*7c478bd9Sstevel@tonic-gate  *	and the number of configurations parsed in dev_n_cfg.
577*7c478bd9Sstevel@tonic-gate  *
578*7c478bd9Sstevel@tonic-gate  * Arguments:
579*7c478bd9Sstevel@tonic-gate  *	dip		- pointer to devinfo node of the client
580*7c478bd9Sstevel@tonic-gate  *	dev_data	- return registration data at this address
581*7c478bd9Sstevel@tonic-gate  *	parse_level	- See above
582*7c478bd9Sstevel@tonic-gate  *	flags		- None used
583*7c478bd9Sstevel@tonic-gate  *
584*7c478bd9Sstevel@tonic-gate  * Return Values:
585*7c478bd9Sstevel@tonic-gate  *	USB_SUCCESS		- usb_register_client succeeded
586*7c478bd9Sstevel@tonic-gate  *	USB_INVALID_ARGS	- received null dip or reg argument
587*7c478bd9Sstevel@tonic-gate  *	USB_INVALID_CONTEXT	- called with sleep from callback context
588*7c478bd9Sstevel@tonic-gate  *	USB_FAILURE		- bad descriptor info or other internal failure
589*7c478bd9Sstevel@tonic-gate  *
590*7c478bd9Sstevel@tonic-gate  * Notes:
591*7c478bd9Sstevel@tonic-gate  * 	1) The non-standard USB descriptors are returned in RAW format.
592*7c478bd9Sstevel@tonic-gate  *
593*7c478bd9Sstevel@tonic-gate  *	2) The registration data is unshared. Each client receives its own copy.
594*7c478bd9Sstevel@tonic-gate  *	(The default control pipe may be shared, even though its tree
595*7c478bd9Sstevel@tonic-gate  *	description will be unique per device.)
596*7c478bd9Sstevel@tonic-gate  *
597*7c478bd9Sstevel@tonic-gate  */
598*7c478bd9Sstevel@tonic-gate int usb_get_dev_data(
599*7c478bd9Sstevel@tonic-gate 	dev_info_t			*dip,
600*7c478bd9Sstevel@tonic-gate 	usb_client_dev_data_t		**dev_data,
601*7c478bd9Sstevel@tonic-gate 	usb_reg_parse_lvl_t		parse_level,
602*7c478bd9Sstevel@tonic-gate 	usb_flags_t			flags);
603*7c478bd9Sstevel@tonic-gate 
604*7c478bd9Sstevel@tonic-gate /*
605*7c478bd9Sstevel@tonic-gate  * usb_free_dev_data:
606*7c478bd9Sstevel@tonic-gate  * undoes what usb_get_dev_data() set up.  It releases
607*7c478bd9Sstevel@tonic-gate  * memory for all strings, descriptors, and trees set up by usb_get_dev_data().
608*7c478bd9Sstevel@tonic-gate  *
609*7c478bd9Sstevel@tonic-gate  * Arguments:
610*7c478bd9Sstevel@tonic-gate  *	dip		- pointer to devinfo node of the client
611*7c478bd9Sstevel@tonic-gate  *	dev_data	- pointer to registration data containing the tree.
612*7c478bd9Sstevel@tonic-gate  */
613*7c478bd9Sstevel@tonic-gate void usb_free_dev_data(
614*7c478bd9Sstevel@tonic-gate 	dev_info_t			*dip,
615*7c478bd9Sstevel@tonic-gate 	usb_client_dev_data_t		*dev_data);
616*7c478bd9Sstevel@tonic-gate 
617*7c478bd9Sstevel@tonic-gate /*
618*7c478bd9Sstevel@tonic-gate  * usb_free_descr_tree:
619*7c478bd9Sstevel@tonic-gate  *	Take down the configuration tree while leaving the rest	of the
620*7c478bd9Sstevel@tonic-gate  *	registration intact.  This can be used, for example, after attach has
621*7c478bd9Sstevel@tonic-gate  *	copied any descriptors it needs from the tree, but the rest of the
622*7c478bd9Sstevel@tonic-gate  *	registration data needs to remain intact.
623*7c478bd9Sstevel@tonic-gate  *
624*7c478bd9Sstevel@tonic-gate  *	The following usb_client_dev_data_t fields will be modified:
625*7c478bd9Sstevel@tonic-gate  *		dev_cfg will be NULL
626*7c478bd9Sstevel@tonic-gate  *		dev_n_cfg will be 0
627*7c478bd9Sstevel@tonic-gate  *		dev_curr_cfg_ndx and dev_curr_if will be invalid
628*7c478bd9Sstevel@tonic-gate  *		dev_parse_level will be USB_REG_DESCR_NONE
629*7c478bd9Sstevel@tonic-gate  *
630*7c478bd9Sstevel@tonic-gate  * Arguments:
631*7c478bd9Sstevel@tonic-gate  *	dip		- pointer to devinfo node of the client
632*7c478bd9Sstevel@tonic-gate  *	dev_data	- pointer to registration data containing the tree.
633*7c478bd9Sstevel@tonic-gate  */
634*7c478bd9Sstevel@tonic-gate void usb_free_descr_tree(
635*7c478bd9Sstevel@tonic-gate 	dev_info_t			*dip,
636*7c478bd9Sstevel@tonic-gate 	usb_client_dev_data_t		*dev_data);
637*7c478bd9Sstevel@tonic-gate 
638*7c478bd9Sstevel@tonic-gate 
639*7c478bd9Sstevel@tonic-gate /*
640*7c478bd9Sstevel@tonic-gate  * usb_print_descr_tree:
641*7c478bd9Sstevel@tonic-gate  *	Dump to the screen a descriptor tree as returned by
642*7c478bd9Sstevel@tonic-gate  *	usbai_register_client.
643*7c478bd9Sstevel@tonic-gate  *
644*7c478bd9Sstevel@tonic-gate  * Arguments:
645*7c478bd9Sstevel@tonic-gate  *	dip		- pointer to devinfo of the client
646*7c478bd9Sstevel@tonic-gate  *	dev_data	- pointer to registration area containing the tree
647*7c478bd9Sstevel@tonic-gate  *
648*7c478bd9Sstevel@tonic-gate  * Returns:
649*7c478bd9Sstevel@tonic-gate  *	USB_SUCCESS		- tree successfully dumped
650*7c478bd9Sstevel@tonic-gate  *	USB_INVALID_CONTEXT	- called from callback context
651*7c478bd9Sstevel@tonic-gate  *	USB_INVALID_ARGS	- bad arguments given
652*7c478bd9Sstevel@tonic-gate  */
653*7c478bd9Sstevel@tonic-gate int usb_print_descr_tree(
654*7c478bd9Sstevel@tonic-gate 	dev_info_t		*dip,
655*7c478bd9Sstevel@tonic-gate 	usb_client_dev_data_t	*dev_data);
656*7c478bd9Sstevel@tonic-gate 
657*7c478bd9Sstevel@tonic-gate 
658*7c478bd9Sstevel@tonic-gate /*
659*7c478bd9Sstevel@tonic-gate  * ***************************************************************************
660*7c478bd9Sstevel@tonic-gate  * Registration and versioning
661*7c478bd9Sstevel@tonic-gate  * ***************************************************************************
662*7c478bd9Sstevel@tonic-gate  */
663*7c478bd9Sstevel@tonic-gate 
664*7c478bd9Sstevel@tonic-gate 
665*7c478bd9Sstevel@tonic-gate /*
666*7c478bd9Sstevel@tonic-gate  * USBA client drivers are required to define USBDRV_MAJOR_VER
667*7c478bd9Sstevel@tonic-gate  * USBDRV_MINOR_VER and pass USBDRV_VERSION as the version
668*7c478bd9Sstevel@tonic-gate  * number to usb_client_attach
669*7c478bd9Sstevel@tonic-gate  */
670*7c478bd9Sstevel@tonic-gate #if !defined(USBA_MAJOR_VER) || !defined(USBA_MINOR_VER)
671*7c478bd9Sstevel@tonic-gate #error incorrect USBA header
672*7c478bd9Sstevel@tonic-gate #endif
673*7c478bd9Sstevel@tonic-gate 
674*7c478bd9Sstevel@tonic-gate /*
675*7c478bd9Sstevel@tonic-gate  * Driver major version must be the same as USBA major version, and
676*7c478bd9Sstevel@tonic-gate  * driver minor version must be <= USBA minor version
677*7c478bd9Sstevel@tonic-gate  */
678*7c478bd9Sstevel@tonic-gate #if !defined(USBA_FRAMEWORK)
679*7c478bd9Sstevel@tonic-gate #if defined(USBDRV_MAJOR_VER) && defined(USBDRV_MINOR_VER)
680*7c478bd9Sstevel@tonic-gate 
681*7c478bd9Sstevel@tonic-gate #if (USBDRV_MAJOR_VER != USBA_MAJOR_VER)
682*7c478bd9Sstevel@tonic-gate #error USBA and driver major versions do not match
683*7c478bd9Sstevel@tonic-gate #endif
684*7c478bd9Sstevel@tonic-gate #if (USBDRV_MINOR_VER > USBA_MINOR_VER)
685*7c478bd9Sstevel@tonic-gate #error USBA and driver minor versions do not match
686*7c478bd9Sstevel@tonic-gate #endif
687*7c478bd9Sstevel@tonic-gate 
688*7c478bd9Sstevel@tonic-gate #endif
689*7c478bd9Sstevel@tonic-gate #endif
690*7c478bd9Sstevel@tonic-gate 
691*7c478bd9Sstevel@tonic-gate #define	USBA_MAKE_VER(major, minor) ((major) << 8 | (minor))
692*7c478bd9Sstevel@tonic-gate #define	USBA_GET_MAJOR(ver) ((ver) >> 8)
693*7c478bd9Sstevel@tonic-gate #define	USBA_GET_MINOR(ver) ((ver) & 0xff)
694*7c478bd9Sstevel@tonic-gate 
695*7c478bd9Sstevel@tonic-gate #define	USBDRV_VERSION	USBA_MAKE_VER(USBDRV_MAJOR_VER, USBDRV_MINOR_VER)
696*7c478bd9Sstevel@tonic-gate 
697*7c478bd9Sstevel@tonic-gate 
698*7c478bd9Sstevel@tonic-gate /*
699*7c478bd9Sstevel@tonic-gate  * usb_client_attach:
700*7c478bd9Sstevel@tonic-gate  *
701*7c478bd9Sstevel@tonic-gate  * Arguments:
702*7c478bd9Sstevel@tonic-gate  *	dip		- pointer to devinfo node of the client
703*7c478bd9Sstevel@tonic-gate  *	version 	- USBA registration version number
704*7c478bd9Sstevel@tonic-gate  *	flags		- None used
705*7c478bd9Sstevel@tonic-gate  *
706*7c478bd9Sstevel@tonic-gate  * Return Values:
707*7c478bd9Sstevel@tonic-gate  *	USB_SUCCESS		- attach succeeded
708*7c478bd9Sstevel@tonic-gate  *	USB_INVALID_ARGS	- received null dip or reg argument
709*7c478bd9Sstevel@tonic-gate  *	USB_INVALID_CONTEXT	- called with sleep from callback context
710*7c478bd9Sstevel@tonic-gate  *				  or not at attach time
711*7c478bd9Sstevel@tonic-gate  *	USB_INVALID_VERSION	- version argument is incorrect.
712*7c478bd9Sstevel@tonic-gate  *	USB_FAILURE		- other internal failure
713*7c478bd9Sstevel@tonic-gate  */
714*7c478bd9Sstevel@tonic-gate int usb_client_attach(
715*7c478bd9Sstevel@tonic-gate 	dev_info_t			*dip,
716*7c478bd9Sstevel@tonic-gate 	uint_t				version,
717*7c478bd9Sstevel@tonic-gate 	usb_flags_t			flags);
718*7c478bd9Sstevel@tonic-gate 
719*7c478bd9Sstevel@tonic-gate /*
720*7c478bd9Sstevel@tonic-gate  * usb_client_detach:
721*7c478bd9Sstevel@tonic-gate  *
722*7c478bd9Sstevel@tonic-gate  * Arguments:
723*7c478bd9Sstevel@tonic-gate  *	dip		- pointer to devinfo node of the client
724*7c478bd9Sstevel@tonic-gate  *	dev_data	- pointer to data to free. may be NULL
725*7c478bd9Sstevel@tonic-gate  */
726*7c478bd9Sstevel@tonic-gate void usb_client_detach(
727*7c478bd9Sstevel@tonic-gate 	dev_info_t			*dip,
728*7c478bd9Sstevel@tonic-gate 	struct usb_client_dev_data	*dev_data);
729*7c478bd9Sstevel@tonic-gate 
730*7c478bd9Sstevel@tonic-gate /*
731*7c478bd9Sstevel@tonic-gate  * ***************************************************************************
732*7c478bd9Sstevel@tonic-gate  * Functions for parsing / retrieving data from the descriptor tree
733*7c478bd9Sstevel@tonic-gate  * ***************************************************************************
734*7c478bd9Sstevel@tonic-gate  */
735*7c478bd9Sstevel@tonic-gate 
736*7c478bd9Sstevel@tonic-gate /*
737*7c478bd9Sstevel@tonic-gate  * Function for unpacking any kind of little endian data, usually desriptors
738*7c478bd9Sstevel@tonic-gate  *
739*7c478bd9Sstevel@tonic-gate  * Arguments:
740*7c478bd9Sstevel@tonic-gate  *	format		- string indicating the format in c, s, w, eg. "2c4ws"
741*7c478bd9Sstevel@tonic-gate  *			  which describes 2 bytes, 4 int, one short.
742*7c478bd9Sstevel@tonic-gate  *			  The number prefix parses the number of items of
743*7c478bd9Sstevel@tonic-gate  *			  the following type.
744*7c478bd9Sstevel@tonic-gate  *	data		- pointer to the LE data buffer
745*7c478bd9Sstevel@tonic-gate  *	datalen		- length of the data
746*7c478bd9Sstevel@tonic-gate  *	structure	- pointer to return structure where the unpacked data
747*7c478bd9Sstevel@tonic-gate  *			  will be written
748*7c478bd9Sstevel@tonic-gate  *	structlen	- length of the return structure
749*7c478bd9Sstevel@tonic-gate  *
750*7c478bd9Sstevel@tonic-gate  * return value:
751*7c478bd9Sstevel@tonic-gate  *	total number of bytes of the original data that was unpacked
752*7c478bd9Sstevel@tonic-gate  *	or USB_PARSE_ERROR
753*7c478bd9Sstevel@tonic-gate  */
754*7c478bd9Sstevel@tonic-gate #define	USB_PARSE_ERROR	0
755*7c478bd9Sstevel@tonic-gate 
756*7c478bd9Sstevel@tonic-gate size_t usb_parse_data(
757*7c478bd9Sstevel@tonic-gate 	char			*format,
758*7c478bd9Sstevel@tonic-gate 	uchar_t 		*data,
759*7c478bd9Sstevel@tonic-gate 	size_t			datalen,
760*7c478bd9Sstevel@tonic-gate 	void			*structure,
761*7c478bd9Sstevel@tonic-gate 	size_t			structlen);
762*7c478bd9Sstevel@tonic-gate 
763*7c478bd9Sstevel@tonic-gate /*
764*7c478bd9Sstevel@tonic-gate  * usb_lookup_ep_data:
765*7c478bd9Sstevel@tonic-gate  *	Function to get specific endpoint data
766*7c478bd9Sstevel@tonic-gate  *	This function will not access the device.
767*7c478bd9Sstevel@tonic-gate  *
768*7c478bd9Sstevel@tonic-gate  * Arguments:
769*7c478bd9Sstevel@tonic-gate  *	dip		- pointer to dev info
770*7c478bd9Sstevel@tonic-gate  *	dev_datap	- pointer to registration data
771*7c478bd9Sstevel@tonic-gate  *	interface	- requested interface
772*7c478bd9Sstevel@tonic-gate  *	alternate	- requested alternate
773*7c478bd9Sstevel@tonic-gate  *	skip		- number of endpoints which match the requested type and
774*7c478bd9Sstevel@tonic-gate  *			  direction to skip before finding one to retrieve
775*7c478bd9Sstevel@tonic-gate  *	type		- endpoint type
776*7c478bd9Sstevel@tonic-gate  *	direction	- endpoint direction: USB_EP_DIR_IN/OUT or none
777*7c478bd9Sstevel@tonic-gate  *
778*7c478bd9Sstevel@tonic-gate  * Return Values:
779*7c478bd9Sstevel@tonic-gate  *	NULL or an endpoint data pointer
780*7c478bd9Sstevel@tonic-gate  */
781*7c478bd9Sstevel@tonic-gate usb_ep_data_t *usb_lookup_ep_data(
782*7c478bd9Sstevel@tonic-gate 	dev_info_t		*dip,
783*7c478bd9Sstevel@tonic-gate 	usb_client_dev_data_t	*dev_datap,
784*7c478bd9Sstevel@tonic-gate 	uint_t			interface,
785*7c478bd9Sstevel@tonic-gate 	uint_t			alternate,
786*7c478bd9Sstevel@tonic-gate 	uint_t			skip,
787*7c478bd9Sstevel@tonic-gate 	uint_t			type,
788*7c478bd9Sstevel@tonic-gate 	uint_t			direction);
789*7c478bd9Sstevel@tonic-gate 
790*7c478bd9Sstevel@tonic-gate 
791*7c478bd9Sstevel@tonic-gate /* Language ID for string descriptors. */
792*7c478bd9Sstevel@tonic-gate #define	USB_LANG_ID		0x0409		/* English, US */
793*7c478bd9Sstevel@tonic-gate 
794*7c478bd9Sstevel@tonic-gate /*
795*7c478bd9Sstevel@tonic-gate  * usb_get_string_descr:
796*7c478bd9Sstevel@tonic-gate  *	Reads the string descriptor.  This function access the device and
797*7c478bd9Sstevel@tonic-gate  *	blocks.
798*7c478bd9Sstevel@tonic-gate  *
799*7c478bd9Sstevel@tonic-gate  * Arguments:
800*7c478bd9Sstevel@tonic-gate  *	dip		- pointer to devinfo of the client.
801*7c478bd9Sstevel@tonic-gate  *	langid		- LANGID to read different LOCALEs.
802*7c478bd9Sstevel@tonic-gate  *	index		- index to the string.
803*7c478bd9Sstevel@tonic-gate  *	buf		- user provided buffer for string descriptor.
804*7c478bd9Sstevel@tonic-gate  *	buflen		- user provided length of the buffer.
805*7c478bd9Sstevel@tonic-gate  *
806*7c478bd9Sstevel@tonic-gate  * Return Values:
807*7c478bd9Sstevel@tonic-gate  *	USB_SUCCESS	- descriptor is valid.
808*7c478bd9Sstevel@tonic-gate  *	USB_FAILURE	- full descriptor could not be retrieved.
809*7c478bd9Sstevel@tonic-gate  */
810*7c478bd9Sstevel@tonic-gate int usb_get_string_descr(
811*7c478bd9Sstevel@tonic-gate 	dev_info_t		*dip,
812*7c478bd9Sstevel@tonic-gate 	uint16_t		langid,
813*7c478bd9Sstevel@tonic-gate 	uint8_t			index,
814*7c478bd9Sstevel@tonic-gate 	char			*buf,
815*7c478bd9Sstevel@tonic-gate 	size_t			buflen);
816*7c478bd9Sstevel@tonic-gate 
817*7c478bd9Sstevel@tonic-gate 
818*7c478bd9Sstevel@tonic-gate /*
819*7c478bd9Sstevel@tonic-gate  * ***************************************************************************
820*7c478bd9Sstevel@tonic-gate  * Addressing utility functions
821*7c478bd9Sstevel@tonic-gate  * ***************************************************************************
822*7c478bd9Sstevel@tonic-gate  */
823*7c478bd9Sstevel@tonic-gate 
824*7c478bd9Sstevel@tonic-gate /*
825*7c478bd9Sstevel@tonic-gate  * usb_get_addr returns the current usb address, mostly for debugging
826*7c478bd9Sstevel@tonic-gate  * purposes. The address may change after hotremove/insert.
827*7c478bd9Sstevel@tonic-gate  * This address will not change on a disconnect/reconnect of open device.
828*7c478bd9Sstevel@tonic-gate  */
829*7c478bd9Sstevel@tonic-gate int usb_get_addr(dev_info_t *dip);
830*7c478bd9Sstevel@tonic-gate 
831*7c478bd9Sstevel@tonic-gate 
832*7c478bd9Sstevel@tonic-gate /*
833*7c478bd9Sstevel@tonic-gate  * usb_get_if_number returns USB_COMBINED_NODE or USB_DEVICE_NODE
834*7c478bd9Sstevel@tonic-gate  * if the driver is responsible for the entire device.
835*7c478bd9Sstevel@tonic-gate  * Otherwise it returns the interface number.
836*7c478bd9Sstevel@tonic-gate  */
837*7c478bd9Sstevel@tonic-gate #define	USB_COMBINED_NODE	-1
838*7c478bd9Sstevel@tonic-gate #define	USB_DEVICE_NODE		-2
839*7c478bd9Sstevel@tonic-gate 
840*7c478bd9Sstevel@tonic-gate int usb_get_if_number(
841*7c478bd9Sstevel@tonic-gate 	dev_info_t		*dip);
842*7c478bd9Sstevel@tonic-gate 
843*7c478bd9Sstevel@tonic-gate boolean_t usb_owns_device(
844*7c478bd9Sstevel@tonic-gate 	dev_info_t		*dip);
845*7c478bd9Sstevel@tonic-gate 
846*7c478bd9Sstevel@tonic-gate 
847*7c478bd9Sstevel@tonic-gate /*
848*7c478bd9Sstevel@tonic-gate  * ***************************************************************************
849*7c478bd9Sstevel@tonic-gate  * Pipe	Management definitions and functions
850*7c478bd9Sstevel@tonic-gate  * ***************************************************************************
851*7c478bd9Sstevel@tonic-gate  */
852*7c478bd9Sstevel@tonic-gate 
853*7c478bd9Sstevel@tonic-gate 
854*7c478bd9Sstevel@tonic-gate /*
855*7c478bd9Sstevel@tonic-gate  *
856*7c478bd9Sstevel@tonic-gate  * usb_pipe_state:
857*7c478bd9Sstevel@tonic-gate  *
858*7c478bd9Sstevel@tonic-gate  * PIPE_STATE_IDLE:
859*7c478bd9Sstevel@tonic-gate  *	The pipe's policy is set, but the pipe currently isn't transferring
860*7c478bd9Sstevel@tonic-gate  *	data.
861*7c478bd9Sstevel@tonic-gate  *
862*7c478bd9Sstevel@tonic-gate  * PIPE_STATE_ACTIVE:
863*7c478bd9Sstevel@tonic-gate  *	The pipe's policy has been set, and the pipe is able to transmit data.
864*7c478bd9Sstevel@tonic-gate  *	When a control or bulk pipe is opened, the pipe's state is
865*7c478bd9Sstevel@tonic-gate  *	automatically set to PIPE_STATE_ACTIVE.  For an interrupt or
866*7c478bd9Sstevel@tonic-gate  *	isochronous pipe, the pipe state becomes PIPE_STATE_ACTIVE once
867*7c478bd9Sstevel@tonic-gate  *	the polling on the pipe has been initiated.
868*7c478bd9Sstevel@tonic-gate  *
869*7c478bd9Sstevel@tonic-gate  * PIPE_STATE_ERROR:
870*7c478bd9Sstevel@tonic-gate  *	The device has generated a error on the pipe.  The client driver
871*7c478bd9Sstevel@tonic-gate  *	must call usb_pipe_reset() to clear any leftover state that's associated
872*7c478bd9Sstevel@tonic-gate  *	with the pipe, clear the data toggle, and reset the state of the pipe.
873*7c478bd9Sstevel@tonic-gate  *
874*7c478bd9Sstevel@tonic-gate  *	Calling usb_pipe_reset() on a control or bulk pipe resets the state to
875*7c478bd9Sstevel@tonic-gate  *	PIPE_STATE_ACTIVE.  Calling usb_pipe_reset() on an interrupt or
876*7c478bd9Sstevel@tonic-gate  *	isochronous pipe, resets the state to PIPE_STATE_IDLE.
877*7c478bd9Sstevel@tonic-gate  *
878*7c478bd9Sstevel@tonic-gate  * State Diagram for Bulk/Control
879*7c478bd9Sstevel@tonic-gate  *
880*7c478bd9Sstevel@tonic-gate  *			+-<--normal completion------------------<-------^
881*7c478bd9Sstevel@tonic-gate  *			|						|
882*7c478bd9Sstevel@tonic-gate  *			V						|
883*7c478bd9Sstevel@tonic-gate  * usb_pipe_open-->[PIPE_STATE_IDLE]-usb_pipe_*_xfer->[PIPE_STATE_ACTIVE]
884*7c478bd9Sstevel@tonic-gate  *			^						|
885*7c478bd9Sstevel@tonic-gate  *			|						v
886*7c478bd9Sstevel@tonic-gate  *			- usb_pipe_reset<-[PIPE_STATE_ERROR]<-device error
887*7c478bd9Sstevel@tonic-gate  *
888*7c478bd9Sstevel@tonic-gate  * State Diagram for Interrupt/Isochronous IN
889*7c478bd9Sstevel@tonic-gate  *
890*7c478bd9Sstevel@tonic-gate  *			+-<--usb_pipe_stop_isoc/intr_polling----<-------^
891*7c478bd9Sstevel@tonic-gate  *			|						|
892*7c478bd9Sstevel@tonic-gate  *			V						|
893*7c478bd9Sstevel@tonic-gate  * usb_pipe_open-->[PIPE_STATE_IDLE]-usb_pipe_*_xfer->[PIPE_STATE_ACTIVE]
894*7c478bd9Sstevel@tonic-gate  *			^						|
895*7c478bd9Sstevel@tonic-gate  *			|						v
896*7c478bd9Sstevel@tonic-gate  *			+ usb_pipe_reset<-[PIPE_STATE_ERROR]<-device error
897*7c478bd9Sstevel@tonic-gate  *
898*7c478bd9Sstevel@tonic-gate  * State Diagram for Interrupt/Isochronous OUT
899*7c478bd9Sstevel@tonic-gate  *
900*7c478bd9Sstevel@tonic-gate  *			+-<--normal completion------------------<-------^
901*7c478bd9Sstevel@tonic-gate  *			|						|
902*7c478bd9Sstevel@tonic-gate  *			V						|
903*7c478bd9Sstevel@tonic-gate  * usb_pipe_open-->[PIPE_STATE_IDLE]-usb_pipe_*_xfer->[PIPE_STATE_ACTIVE]
904*7c478bd9Sstevel@tonic-gate  *			^						|
905*7c478bd9Sstevel@tonic-gate  *			|						v
906*7c478bd9Sstevel@tonic-gate  *			+ usb_pipe_reset<-[PIPE_STATE_ERROR]<-device error
907*7c478bd9Sstevel@tonic-gate  *
908*7c478bd9Sstevel@tonic-gate  *
909*7c478bd9Sstevel@tonic-gate  * The following table indicates which operations are allowed with each
910*7c478bd9Sstevel@tonic-gate  * pipe state:
911*7c478bd9Sstevel@tonic-gate  *
912*7c478bd9Sstevel@tonic-gate  * -------------------------------------------------------------------------+
913*7c478bd9Sstevel@tonic-gate  * ctrl/bulk	| idle	| active     | error  | sync closing | async closing|
914*7c478bd9Sstevel@tonic-gate  * -------------------------------------------------------------------------+
915*7c478bd9Sstevel@tonic-gate  * pipe xfer	|  OK	|queue (USBA)| reject | reject	     | reject	    |
916*7c478bd9Sstevel@tonic-gate  * pipe reset	| no-op | OK	     |	OK    | reject	     | reject	    |
917*7c478bd9Sstevel@tonic-gate  * pipe close	|  OK	| wait&close |	OK    | no-op	     | no-op	    |
918*7c478bd9Sstevel@tonic-gate  * -------------------------------------------------------------------------+
919*7c478bd9Sstevel@tonic-gate  *
920*7c478bd9Sstevel@tonic-gate  * -------------------------------------------------------------------------+
921*7c478bd9Sstevel@tonic-gate  * intr/isoc IN | idle	| active     | error  | sync closing | async closing|
922*7c478bd9Sstevel@tonic-gate  * -------------------------------------------------------------------------+
923*7c478bd9Sstevel@tonic-gate  * pipe xfer	|  OK	| reject     | reject | reject	     | reject	    |
924*7c478bd9Sstevel@tonic-gate  * pipe stoppoll| no-op | OK	     | no-op  | reject	     | reject	    |
925*7c478bd9Sstevel@tonic-gate  * pipe reset	| no-op | OK	     |	OK    | reject	     | reject	    |
926*7c478bd9Sstevel@tonic-gate  * pipe close	|  OK	| wait&close |	OK    | no-op	     | no-op	    |
927*7c478bd9Sstevel@tonic-gate  * -------------------------------------------------------------------------+
928*7c478bd9Sstevel@tonic-gate  *
929*7c478bd9Sstevel@tonic-gate  * -------------------------------------------------------------------------+
930*7c478bd9Sstevel@tonic-gate  * intr/isoc OUT| idle	| active     | error  | sync closing | async closing|
931*7c478bd9Sstevel@tonic-gate  * -------------------------------------------------------------------------+
932*7c478bd9Sstevel@tonic-gate  * pipe xfer	|  OK	|queue (HCD) | reject | reject	     | reject	    |
933*7c478bd9Sstevel@tonic-gate  * pipe stoppoll| reject| reject     | reject | reject	     | reject	    |
934*7c478bd9Sstevel@tonic-gate  * pipe reset	| no-op | OK	     |	OK    | reject	     | reject	    |
935*7c478bd9Sstevel@tonic-gate  * pipe close	|  OK	| wait&close |	OK    | no-op	     | no-op	    |
936*7c478bd9Sstevel@tonic-gate  * -------------------------------------------------------------------------+
937*7c478bd9Sstevel@tonic-gate  */
938*7c478bd9Sstevel@tonic-gate typedef enum {
939*7c478bd9Sstevel@tonic-gate 	USB_PIPE_STATE_CLOSED		= 0,
940*7c478bd9Sstevel@tonic-gate 	USB_PIPE_STATE_IDLE		= 1,
941*7c478bd9Sstevel@tonic-gate 	USB_PIPE_STATE_ACTIVE		= 2,
942*7c478bd9Sstevel@tonic-gate 	USB_PIPE_STATE_ERROR		= 3,
943*7c478bd9Sstevel@tonic-gate 	USB_PIPE_STATE_CLOSING		= 4
944*7c478bd9Sstevel@tonic-gate } usb_pipe_state_t;
945*7c478bd9Sstevel@tonic-gate 
946*7c478bd9Sstevel@tonic-gate 
947*7c478bd9Sstevel@tonic-gate /*
948*7c478bd9Sstevel@tonic-gate  * pipe state control:
949*7c478bd9Sstevel@tonic-gate  *
950*7c478bd9Sstevel@tonic-gate  * return values:
951*7c478bd9Sstevel@tonic-gate  *	USB_SUCCESS	 - success
952*7c478bd9Sstevel@tonic-gate  *	USB_FAILURE	 - unspecified failure
953*7c478bd9Sstevel@tonic-gate  */
954*7c478bd9Sstevel@tonic-gate int usb_pipe_get_state(
955*7c478bd9Sstevel@tonic-gate 	usb_pipe_handle_t	pipe_handle,
956*7c478bd9Sstevel@tonic-gate 	usb_pipe_state_t	*pipe_state,
957*7c478bd9Sstevel@tonic-gate 	usb_flags_t		flags);
958*7c478bd9Sstevel@tonic-gate 
959*7c478bd9Sstevel@tonic-gate 
960*7c478bd9Sstevel@tonic-gate /*
961*7c478bd9Sstevel@tonic-gate  * usb_pipe_policy
962*7c478bd9Sstevel@tonic-gate  *
963*7c478bd9Sstevel@tonic-gate  *	Pipe policy specifies how a pipe to an endpoint	should be used
964*7c478bd9Sstevel@tonic-gate  *	by the client driver and the HCD.
965*7c478bd9Sstevel@tonic-gate  */
966*7c478bd9Sstevel@tonic-gate typedef struct usb_pipe_policy {
967*7c478bd9Sstevel@tonic-gate 	/*
968*7c478bd9Sstevel@tonic-gate 	 * This is a hint indicating how many asynchronous operations
969*7c478bd9Sstevel@tonic-gate 	 * requiring a kernel thread will be concurrently active.
970*7c478bd9Sstevel@tonic-gate 	 * Allow at least one for synch exception callback handling
971*7c478bd9Sstevel@tonic-gate 	 * and another for asynchronous closing of pipes.
972*7c478bd9Sstevel@tonic-gate 	 */
973*7c478bd9Sstevel@tonic-gate 	uchar_t		pp_max_async_reqs;
974*7c478bd9Sstevel@tonic-gate } usb_pipe_policy_t;
975*7c478bd9Sstevel@tonic-gate 
976*7c478bd9Sstevel@tonic-gate 
977*7c478bd9Sstevel@tonic-gate /*
978*7c478bd9Sstevel@tonic-gate  * usb_pipe_open():
979*7c478bd9Sstevel@tonic-gate  *
980*7c478bd9Sstevel@tonic-gate  * Before using any pipe including the default pipe, it must be opened.
981*7c478bd9Sstevel@tonic-gate  * On success, a pipe handle is returned for use in other usb_pipe_*()
982*7c478bd9Sstevel@tonic-gate  * functions.
983*7c478bd9Sstevel@tonic-gate  *
984*7c478bd9Sstevel@tonic-gate  * The default pipe can only be opened by the hub driver.
985*7c478bd9Sstevel@tonic-gate  *
986*7c478bd9Sstevel@tonic-gate  * For isochronous and interrupt pipes, bandwidth has been allocated and
987*7c478bd9Sstevel@tonic-gate  * guaranteed.
988*7c478bd9Sstevel@tonic-gate  *
989*7c478bd9Sstevel@tonic-gate  * Only the default pipe can be shared.  All other control pipes are
990*7c478bd9Sstevel@tonic-gate  * excusively opened by default.  A pipe policy and endpoint descriptor
991*7c478bd9Sstevel@tonic-gate  * must always be provided except for default pipe.
992*7c478bd9Sstevel@tonic-gate  *
993*7c478bd9Sstevel@tonic-gate  * Arguments:
994*7c478bd9Sstevel@tonic-gate  *	dip		- devinfo ptr.
995*7c478bd9Sstevel@tonic-gate  *	ep		- endpoint descriptor pointer.
996*7c478bd9Sstevel@tonic-gate  *	pipe_policy	- pointer to pipe policy which provides hints on how
997*7c478bd9Sstevel@tonic-gate  *			  the pipe will be used.
998*7c478bd9Sstevel@tonic-gate  *	flags		- USB_FLAGS_SLEEP wait for resources to become
999*7c478bd9Sstevel@tonic-gate  *			  available.
1000*7c478bd9Sstevel@tonic-gate  *	pipe_handle	- a pipe handle pointer.  on a successful open,
1001*7c478bd9Sstevel@tonic-gate  *			  a pipe_handle is returned in this pointer.
1002*7c478bd9Sstevel@tonic-gate  *
1003*7c478bd9Sstevel@tonic-gate  * Return values:
1004*7c478bd9Sstevel@tonic-gate  *	USB_SUCCESS	 - open succeeded.
1005*7c478bd9Sstevel@tonic-gate  *	USB_FAILURE	 - unspecified open failure or pipe is already open.
1006*7c478bd9Sstevel@tonic-gate  *	USB_NO_RESOURCES - no resources were available to complete the open.
1007*7c478bd9Sstevel@tonic-gate  *	USB_NO_BANDWIDTH - no bandwidth available (isoc/intr pipes).
1008*7c478bd9Sstevel@tonic-gate  *	USB_*		 - refer to list of all possible return values in
1009*7c478bd9Sstevel@tonic-gate  *			   this file
1010*7c478bd9Sstevel@tonic-gate  */
1011*7c478bd9Sstevel@tonic-gate int usb_pipe_open(
1012*7c478bd9Sstevel@tonic-gate 	dev_info_t		*dip,
1013*7c478bd9Sstevel@tonic-gate 	usb_ep_descr_t		*ep,
1014*7c478bd9Sstevel@tonic-gate 	usb_pipe_policy_t	*pipe_policy,
1015*7c478bd9Sstevel@tonic-gate 	usb_flags_t		flags,
1016*7c478bd9Sstevel@tonic-gate 	usb_pipe_handle_t	*pipe_handle);
1017*7c478bd9Sstevel@tonic-gate 
1018*7c478bd9Sstevel@tonic-gate 
1019*7c478bd9Sstevel@tonic-gate /*
1020*7c478bd9Sstevel@tonic-gate  * usb_pipe_close():
1021*7c478bd9Sstevel@tonic-gate  *
1022*7c478bd9Sstevel@tonic-gate  * Closes the pipe, releases resources and frees the pipe_handle.
1023*7c478bd9Sstevel@tonic-gate  * Automatic polling, if active,  will be terminated.
1024*7c478bd9Sstevel@tonic-gate  *
1025*7c478bd9Sstevel@tonic-gate  * Arguments:
1026*7c478bd9Sstevel@tonic-gate  *	dip		- devinfo ptr.
1027*7c478bd9Sstevel@tonic-gate  *	pipe_handle	- pipe handle.
1028*7c478bd9Sstevel@tonic-gate  *	flags		- USB_FLAGS_SLEEP:
1029*7c478bd9Sstevel@tonic-gate  *				wait for resources, pipe
1030*7c478bd9Sstevel@tonic-gate  *				to become free, and all callbacks completed.
1031*7c478bd9Sstevel@tonic-gate  *	cb		- If USB_FLAGS_SLEEP has not been specified, a
1032*7c478bd9Sstevel@tonic-gate  *			  callback will be performed.
1033*7c478bd9Sstevel@tonic-gate  *	cb_arg		- the 2nd argument of the callback. Note that the
1034*7c478bd9Sstevel@tonic-gate  *			  pipehandle will be zeroed and therefore not passed.
1035*7c478bd9Sstevel@tonic-gate  *
1036*7c478bd9Sstevel@tonic-gate  * Notes:
1037*7c478bd9Sstevel@tonic-gate  *
1038*7c478bd9Sstevel@tonic-gate  * Pipe close always succeeds regardless whether USB_FLAGS_SLEEP has been
1039*7c478bd9Sstevel@tonic-gate  * specified or not.  An async close will always succeed if the hint in the
1040*7c478bd9Sstevel@tonic-gate  * pipe policy has been correct about the max number of async requests
1041*7c478bd9Sstevel@tonic-gate  * required.
1042*7c478bd9Sstevel@tonic-gate  * In the unlikely event that no async requests can be queued, this
1043*7c478bd9Sstevel@tonic-gate  * function will continue retrying before returning
1044*7c478bd9Sstevel@tonic-gate  *
1045*7c478bd9Sstevel@tonic-gate  * USBA prevents the client from submitting subsequent requests to a pipe
1046*7c478bd9Sstevel@tonic-gate  * that is being closed.
1047*7c478bd9Sstevel@tonic-gate  * Additional usb_pipe_close() requests on the same pipe causes USBA to
1048*7c478bd9Sstevel@tonic-gate  * wait for the previous close(s) to complete.
1049*7c478bd9Sstevel@tonic-gate  *
1050*7c478bd9Sstevel@tonic-gate  * The pipe will not be destroyed until all activity on the pipe has
1051*7c478bd9Sstevel@tonic-gate  * been drained, including outstanding request callbacks, async requests,
1052*7c478bd9Sstevel@tonic-gate  * and other usb_pipe_*() calls.
1053*7c478bd9Sstevel@tonic-gate  *
1054*7c478bd9Sstevel@tonic-gate  * Calling usb_pipe_close() from a deferred callback (in kernel context)
1055*7c478bd9Sstevel@tonic-gate  * with USB_FLAGS_SLEEP set, will cause deadlock
1056*7c478bd9Sstevel@tonic-gate  */
1057*7c478bd9Sstevel@tonic-gate void usb_pipe_close(
1058*7c478bd9Sstevel@tonic-gate 	dev_info_t		*dip,
1059*7c478bd9Sstevel@tonic-gate 	usb_pipe_handle_t	pipe_handle,
1060*7c478bd9Sstevel@tonic-gate 	usb_flags_t		flags,
1061*7c478bd9Sstevel@tonic-gate 	void			(*cb)(
1062*7c478bd9Sstevel@tonic-gate 				    usb_pipe_handle_t	ph,
1063*7c478bd9Sstevel@tonic-gate 				    usb_opaque_t	arg,	/* cb arg */
1064*7c478bd9Sstevel@tonic-gate 				    int			rval,
1065*7c478bd9Sstevel@tonic-gate 				    usb_cb_flags_t	flags),
1066*7c478bd9Sstevel@tonic-gate 	usb_opaque_t		cb_arg);
1067*7c478bd9Sstevel@tonic-gate 
1068*7c478bd9Sstevel@tonic-gate 
1069*7c478bd9Sstevel@tonic-gate /*
1070*7c478bd9Sstevel@tonic-gate  * usb_pipe_drain_reqs
1071*7c478bd9Sstevel@tonic-gate  *	this function blocks until there are no more requests
1072*7c478bd9Sstevel@tonic-gate  *	owned by this dip on the pipe
1073*7c478bd9Sstevel@tonic-gate  *
1074*7c478bd9Sstevel@tonic-gate  * Arguments:
1075*7c478bd9Sstevel@tonic-gate  *	dip		- devinfo pointer
1076*7c478bd9Sstevel@tonic-gate  *	pipe_handle	- opaque pipe handle
1077*7c478bd9Sstevel@tonic-gate  *	timeout 	- timeout in seconds
1078*7c478bd9Sstevel@tonic-gate  *	flags		- USB_FLAGS_SLEEP:
1079*7c478bd9Sstevel@tonic-gate  *				wait for completion.
1080*7c478bd9Sstevel@tonic-gate  *	cb		- if USB_FLAGS_SLEEP has not been specified
1081*7c478bd9Sstevel@tonic-gate  *			  this callback function will be called on
1082*7c478bd9Sstevel@tonic-gate  *			  completion. This callback may be NULL
1083*7c478bd9Sstevel@tonic-gate  *			  and no notification of completion will then
1084*7c478bd9Sstevel@tonic-gate  *			  be provided.
1085*7c478bd9Sstevel@tonic-gate  *	cb_arg		- 2nd argument to callback function.
1086*7c478bd9Sstevel@tonic-gate  *
1087*7c478bd9Sstevel@tonic-gate  * callback and callback_arg should be NULL if USB_FLAGS_SLEEP has
1088*7c478bd9Sstevel@tonic-gate  * been specified
1089*7c478bd9Sstevel@tonic-gate  *
1090*7c478bd9Sstevel@tonic-gate  * Returns:
1091*7c478bd9Sstevel@tonic-gate  *	USB_SUCCESS	- pipe successfully reset or request queued
1092*7c478bd9Sstevel@tonic-gate  *	USB_FAILURE	- timeout
1093*7c478bd9Sstevel@tonic-gate  *	USB_INVALID_PIPE - pipe is invalid or already closed
1094*7c478bd9Sstevel@tonic-gate  *	USB_INVALID_CONTEXT - called from interrupt context
1095*7c478bd9Sstevel@tonic-gate  *	USB_INVALID_ARGS - invalid arguments
1096*7c478bd9Sstevel@tonic-gate  *	USB_*		- refer to return values defines in this file
1097*7c478bd9Sstevel@tonic-gate  */
1098*7c478bd9Sstevel@tonic-gate int usb_pipe_drain_reqs(
1099*7c478bd9Sstevel@tonic-gate 	dev_info_t		*dip,
1100*7c478bd9Sstevel@tonic-gate 	usb_pipe_handle_t	pipe_handle,
1101*7c478bd9Sstevel@tonic-gate 	uint_t			time,
1102*7c478bd9Sstevel@tonic-gate 	usb_flags_t		flags,
1103*7c478bd9Sstevel@tonic-gate 	void			(*cb)(
1104*7c478bd9Sstevel@tonic-gate 				    usb_pipe_handle_t	ph,
1105*7c478bd9Sstevel@tonic-gate 				    usb_opaque_t	arg,	/* cb arg */
1106*7c478bd9Sstevel@tonic-gate 				    int			rval,
1107*7c478bd9Sstevel@tonic-gate 				    usb_cb_flags_t	flags),
1108*7c478bd9Sstevel@tonic-gate 	usb_opaque_t		cb_arg);
1109*7c478bd9Sstevel@tonic-gate 
1110*7c478bd9Sstevel@tonic-gate 
1111*7c478bd9Sstevel@tonic-gate /*
1112*7c478bd9Sstevel@tonic-gate  * Resetting a pipe: Refer to USB 2.0/10.5.2.2
1113*7c478bd9Sstevel@tonic-gate  *	The pipe's requests are retired and the pipe is cleared.  The host state
1114*7c478bd9Sstevel@tonic-gate  *	is moved to active. If the reflected endpoint state needs to be changed,
1115*7c478bd9Sstevel@tonic-gate  *	that must be explicitly requested by the client driver.  The reset
1116*7c478bd9Sstevel@tonic-gate  *	completes after all request callbacks have been completed.
1117*7c478bd9Sstevel@tonic-gate  *
1118*7c478bd9Sstevel@tonic-gate  * Arguments:
1119*7c478bd9Sstevel@tonic-gate  *	dip		- devinfo pointer.
1120*7c478bd9Sstevel@tonic-gate  *	pipe_handle	- pipe handle.
1121*7c478bd9Sstevel@tonic-gate  *	flags		- USB_FLAGS_SLEEP:
1122*7c478bd9Sstevel@tonic-gate  *				wait for completion.
1123*7c478bd9Sstevel@tonic-gate  *	cb		- if USB_FLAGS_SLEEP has not been specified
1124*7c478bd9Sstevel@tonic-gate  *			  this callback function will be called on
1125*7c478bd9Sstevel@tonic-gate  *			  completion. This callback may be NULL
1126*7c478bd9Sstevel@tonic-gate  *			  and no notification of completion will then
1127*7c478bd9Sstevel@tonic-gate  *			  be provided.
1128*7c478bd9Sstevel@tonic-gate  *	cb_arg		- 2nd argument to callback function.
1129*7c478bd9Sstevel@tonic-gate  *
1130*7c478bd9Sstevel@tonic-gate  * callback and callback_arg should be NULL if USB_FLAGS_SLEEP has
1131*7c478bd9Sstevel@tonic-gate  * been specified
1132*7c478bd9Sstevel@tonic-gate  *
1133*7c478bd9Sstevel@tonic-gate  * Note: Completion notification may be *before* all async request threads
1134*7c478bd9Sstevel@tonic-gate  *	have completed but *after* all immediate callbacks have completed.
1135*7c478bd9Sstevel@tonic-gate  */
1136*7c478bd9Sstevel@tonic-gate void usb_pipe_reset(
1137*7c478bd9Sstevel@tonic-gate 	dev_info_t		*dip,
1138*7c478bd9Sstevel@tonic-gate 	usb_pipe_handle_t	pipe_handle,
1139*7c478bd9Sstevel@tonic-gate 	usb_flags_t		usb_flags,
1140*7c478bd9Sstevel@tonic-gate 	void			(*cb)(
1141*7c478bd9Sstevel@tonic-gate 					usb_pipe_handle_t ph,
1142*7c478bd9Sstevel@tonic-gate 					usb_opaque_t	arg,
1143*7c478bd9Sstevel@tonic-gate 					int		rval,
1144*7c478bd9Sstevel@tonic-gate 					usb_cb_flags_t	flags),
1145*7c478bd9Sstevel@tonic-gate 	usb_opaque_t		cb_arg);
1146*7c478bd9Sstevel@tonic-gate 
1147*7c478bd9Sstevel@tonic-gate 
1148*7c478bd9Sstevel@tonic-gate /*
1149*7c478bd9Sstevel@tonic-gate  * The client driver can store a private data pointer in the
1150*7c478bd9Sstevel@tonic-gate  * pipe_handle.
1151*7c478bd9Sstevel@tonic-gate  *
1152*7c478bd9Sstevel@tonic-gate  * return values:
1153*7c478bd9Sstevel@tonic-gate  *	USB_SUCCESS	 - success
1154*7c478bd9Sstevel@tonic-gate  *	USB_FAILURE	 - unspecified failure
1155*7c478bd9Sstevel@tonic-gate  */
1156*7c478bd9Sstevel@tonic-gate int usb_pipe_set_private(
1157*7c478bd9Sstevel@tonic-gate 	usb_pipe_handle_t	pipe_handle,
1158*7c478bd9Sstevel@tonic-gate 	usb_opaque_t		data);
1159*7c478bd9Sstevel@tonic-gate 
1160*7c478bd9Sstevel@tonic-gate 
1161*7c478bd9Sstevel@tonic-gate usb_opaque_t usb_pipe_get_private(
1162*7c478bd9Sstevel@tonic-gate 	usb_pipe_handle_t	pipe_handle);
1163*7c478bd9Sstevel@tonic-gate 
1164*7c478bd9Sstevel@tonic-gate 
1165*7c478bd9Sstevel@tonic-gate /*
1166*7c478bd9Sstevel@tonic-gate  * ***************************************************************************
1167*7c478bd9Sstevel@tonic-gate  * Transfer request definitions and functions
1168*7c478bd9Sstevel@tonic-gate  * ***************************************************************************
1169*7c478bd9Sstevel@tonic-gate  */
1170*7c478bd9Sstevel@tonic-gate 
1171*7c478bd9Sstevel@tonic-gate 
1172*7c478bd9Sstevel@tonic-gate /*
1173*7c478bd9Sstevel@tonic-gate  * USB xfer request attributes.
1174*7c478bd9Sstevel@tonic-gate  * Set by the client driver, more than one may be set
1175*7c478bd9Sstevel@tonic-gate  *
1176*7c478bd9Sstevel@tonic-gate  * SHORT_XFER_OK if less data is transferred than specified, no error is
1177*7c478bd9Sstevel@tonic-gate  *		returned.
1178*7c478bd9Sstevel@tonic-gate  * AUTOCLEARING	if there is an exception, the pipe will be reset first
1179*7c478bd9Sstevel@tonic-gate  *		and a functional stall cleared before a callback is done.
1180*7c478bd9Sstevel@tonic-gate  * PIPE_RESET	if there is an exception, the pipe will be reset only
1181*7c478bd9Sstevel@tonic-gate  * ONE_XFER	polling will automatically stop on the first callback.
1182*7c478bd9Sstevel@tonic-gate  * ISOC_START_FRAME use startframe specified.
1183*7c478bd9Sstevel@tonic-gate  * USB_ATTRS_ISOC_XFER_ASAP let the host controller decide on the first
1184*7c478bd9Sstevel@tonic-gate  *		available frame.
1185*7c478bd9Sstevel@tonic-gate  *
1186*7c478bd9Sstevel@tonic-gate  * USB_ATTRS_ISOC_START_FRAME and USB_ATTRS_ISOC_XFER_ASAP are mutually
1187*7c478bd9Sstevel@tonic-gate  * exclusive
1188*7c478bd9Sstevel@tonic-gate  *
1189*7c478bd9Sstevel@tonic-gate  * combinations of flag and attributes:
1190*7c478bd9Sstevel@tonic-gate  *
1191*7c478bd9Sstevel@tonic-gate  * usb_flags	usb_req_attrs			semantics
1192*7c478bd9Sstevel@tonic-gate  * ---------------------------------------------------------
1193*7c478bd9Sstevel@tonic-gate  * SLEEP	USB_ATTRS_SHORT_XFER_OK		legal for IN pipes
1194*7c478bd9Sstevel@tonic-gate  * SLEEP	USB_ATTRS_AUTOCLEARING		legal
1195*7c478bd9Sstevel@tonic-gate  * SLEEP	USB_ATTRS_PIPE_RESET		legal
1196*7c478bd9Sstevel@tonic-gate  * SLEEP	USB_ATTRS_ONE_XFER		legal for interrupt IN pipes
1197*7c478bd9Sstevel@tonic-gate  * SLEEP	USB_ATTRS_ISOC_START_FRAME	illegal
1198*7c478bd9Sstevel@tonic-gate  * SLEEP	USB_ATTRS_ISOC_XFER_ASAP	illegal
1199*7c478bd9Sstevel@tonic-gate  *
1200*7c478bd9Sstevel@tonic-gate  * noSLEEP	USB_ATTRS_SHORT_XFER_OK		legal for all IN pipes
1201*7c478bd9Sstevel@tonic-gate  * noSLEEP	USB_ATTRS_AUTOCLEARING		legal
1202*7c478bd9Sstevel@tonic-gate  * noSLEEP	USB_ATTRS_PIPE_RESET		legal
1203*7c478bd9Sstevel@tonic-gate  * noSLEEP	USB_ATTRS_ONE_XFER		legal
1204*7c478bd9Sstevel@tonic-gate  * noSLEEP	USB_ATTRS_ISOC_START_FRAME	legal
1205*7c478bd9Sstevel@tonic-gate  * noSLEEP	USB_ATTRS_ISOC_XFER_ASAP	legal
1206*7c478bd9Sstevel@tonic-gate  */
1207*7c478bd9Sstevel@tonic-gate typedef enum {
1208*7c478bd9Sstevel@tonic-gate 	USB_ATTRS_NONE			= 0,
1209*7c478bd9Sstevel@tonic-gate 
1210*7c478bd9Sstevel@tonic-gate 	/* only ctrl/bulk/intr IN pipes */
1211*7c478bd9Sstevel@tonic-gate 	USB_ATTRS_SHORT_XFER_OK		= 0x01,	/* short data xfer is ok */
1212*7c478bd9Sstevel@tonic-gate 	USB_ATTRS_PIPE_RESET		= 0x02,	/* reset pipe only on exc */
1213*7c478bd9Sstevel@tonic-gate 	USB_ATTRS_AUTOCLEARING		= 0x12, /* autoclear STALLs */
1214*7c478bd9Sstevel@tonic-gate 
1215*7c478bd9Sstevel@tonic-gate 	/* intr pipes only: one poll with data */
1216*7c478bd9Sstevel@tonic-gate 	USB_ATTRS_ONE_XFER		= 0x100,
1217*7c478bd9Sstevel@tonic-gate 
1218*7c478bd9Sstevel@tonic-gate 	/* only for isoch pipe */
1219*7c478bd9Sstevel@tonic-gate 	USB_ATTRS_ISOC_START_FRAME	= 0x200, /* Starting frame# specified */
1220*7c478bd9Sstevel@tonic-gate 	USB_ATTRS_ISOC_XFER_ASAP	= 0x400	/* HCD decides START_FRAME#  */
1221*7c478bd9Sstevel@tonic-gate } usb_req_attrs_t;
1222*7c478bd9Sstevel@tonic-gate 
1223*7c478bd9Sstevel@tonic-gate 
1224*7c478bd9Sstevel@tonic-gate /*
1225*7c478bd9Sstevel@tonic-gate  * Note: client drivers are required to provide data buffers (mblks) for most
1226*7c478bd9Sstevel@tonic-gate  * requests
1227*7c478bd9Sstevel@tonic-gate  *			IN		OUT
1228*7c478bd9Sstevel@tonic-gate  * ctlr request		if wLength > 0	if wLength > 0
1229*7c478bd9Sstevel@tonic-gate  * bulk request		yes		yes
1230*7c478bd9Sstevel@tonic-gate  * intr request		no		yes
1231*7c478bd9Sstevel@tonic-gate  * isoc request		no		yes
1232*7c478bd9Sstevel@tonic-gate  */
1233*7c478bd9Sstevel@tonic-gate 
1234*7c478bd9Sstevel@tonic-gate /*
1235*7c478bd9Sstevel@tonic-gate  * ===========================================================================
1236*7c478bd9Sstevel@tonic-gate  * USB control request management
1237*7c478bd9Sstevel@tonic-gate  * ===========================================================================
1238*7c478bd9Sstevel@tonic-gate  */
1239*7c478bd9Sstevel@tonic-gate 
1240*7c478bd9Sstevel@tonic-gate /*
1241*7c478bd9Sstevel@tonic-gate  * A client driver allocates and uses the usb_ctrl_req_t for all control
1242*7c478bd9Sstevel@tonic-gate  * pipe requests.
1243*7c478bd9Sstevel@tonic-gate  *
1244*7c478bd9Sstevel@tonic-gate  * Direction of the xfer will be determined based on the bmRequestType.
1245*7c478bd9Sstevel@tonic-gate  *
1246*7c478bd9Sstevel@tonic-gate  * NULL callbacks are permitted, timeout = 0 indicates infinite timeout.
1247*7c478bd9Sstevel@tonic-gate  * All timeouts are in seconds.
1248*7c478bd9Sstevel@tonic-gate  *
1249*7c478bd9Sstevel@tonic-gate  * All fields are initialized by client except for data on IN request
1250*7c478bd9Sstevel@tonic-gate  * in which case the client is responsible for deallocating.
1251*7c478bd9Sstevel@tonic-gate  *
1252*7c478bd9Sstevel@tonic-gate  * Control requests may be reused.  The client driver is responsible
1253*7c478bd9Sstevel@tonic-gate  * for reinitializing some fields, eg data read/write pointers.
1254*7c478bd9Sstevel@tonic-gate  *
1255*7c478bd9Sstevel@tonic-gate  * Control requests can be queued.
1256*7c478bd9Sstevel@tonic-gate  */
1257*7c478bd9Sstevel@tonic-gate typedef struct usb_ctrl_req {
1258*7c478bd9Sstevel@tonic-gate 	uint8_t		ctrl_bmRequestType; /* characteristics of request */
1259*7c478bd9Sstevel@tonic-gate 	uint8_t		ctrl_bRequest;	/* specific request		*/
1260*7c478bd9Sstevel@tonic-gate 	uint16_t	ctrl_wValue;	/* varies according to request	*/
1261*7c478bd9Sstevel@tonic-gate 	uint16_t	ctrl_wIndex;	/* index or offset		*/
1262*7c478bd9Sstevel@tonic-gate 	uint16_t	ctrl_wLength;	/* number of bytes to xfer	*/
1263*7c478bd9Sstevel@tonic-gate 
1264*7c478bd9Sstevel@tonic-gate 	mblk_t		*ctrl_data;	/* the data for the data phase	*/
1265*7c478bd9Sstevel@tonic-gate 					/* IN: allocated by HCD		*/
1266*7c478bd9Sstevel@tonic-gate 					/* OUT: allocated by client	*/
1267*7c478bd9Sstevel@tonic-gate 	uint_t		ctrl_timeout;	/* how long before HCD retires req */
1268*7c478bd9Sstevel@tonic-gate 	usb_opaque_t	ctrl_client_private; /* for client private info	*/
1269*7c478bd9Sstevel@tonic-gate 	usb_req_attrs_t ctrl_attributes; /* attributes for this req */
1270*7c478bd9Sstevel@tonic-gate 
1271*7c478bd9Sstevel@tonic-gate 	/*
1272*7c478bd9Sstevel@tonic-gate 	 * callback function for control pipe requests
1273*7c478bd9Sstevel@tonic-gate 	 *
1274*7c478bd9Sstevel@tonic-gate 	 * a normal callback will be done upon:
1275*7c478bd9Sstevel@tonic-gate 	 *	- successful completion of a control pipe request
1276*7c478bd9Sstevel@tonic-gate 	 *
1277*7c478bd9Sstevel@tonic-gate 	 * callback arguments are:
1278*7c478bd9Sstevel@tonic-gate 	 *	- the pipe_handle
1279*7c478bd9Sstevel@tonic-gate 	 *	- usb_ctrl_req_t pointer
1280*7c478bd9Sstevel@tonic-gate 	 */
1281*7c478bd9Sstevel@tonic-gate 	void		(*ctrl_cb)(usb_pipe_handle_t ph,
1282*7c478bd9Sstevel@tonic-gate 				struct usb_ctrl_req *req);
1283*7c478bd9Sstevel@tonic-gate 
1284*7c478bd9Sstevel@tonic-gate 	/*
1285*7c478bd9Sstevel@tonic-gate 	 * exception callback function for control pipe
1286*7c478bd9Sstevel@tonic-gate 	 *
1287*7c478bd9Sstevel@tonic-gate 	 * a exception callback will be done upon:
1288*7c478bd9Sstevel@tonic-gate 	 *	- an exception/error (all types)
1289*7c478bd9Sstevel@tonic-gate 	 *	- partial xfer of data unless SHORT_XFER_OK has been set
1290*7c478bd9Sstevel@tonic-gate 	 *
1291*7c478bd9Sstevel@tonic-gate 	 * callback arguments are:
1292*7c478bd9Sstevel@tonic-gate 	 *	- the pipe_handle
1293*7c478bd9Sstevel@tonic-gate 	 *	- usb_ctrl_req_t pointer
1294*7c478bd9Sstevel@tonic-gate 	 *
1295*7c478bd9Sstevel@tonic-gate 	 * if USB_ATTRS_AUTOCLEARING was set, autoclearing will be attempted
1296*7c478bd9Sstevel@tonic-gate 	 * and usb_cb_flags_t in usb_ctrl_req may indicate what was done
1297*7c478bd9Sstevel@tonic-gate 	 */
1298*7c478bd9Sstevel@tonic-gate 	void		(*ctrl_exc_cb)(usb_pipe_handle_t ph,
1299*7c478bd9Sstevel@tonic-gate 				struct usb_ctrl_req *req);
1300*7c478bd9Sstevel@tonic-gate 
1301*7c478bd9Sstevel@tonic-gate 	/* set by USBA/HCD on completion */
1302*7c478bd9Sstevel@tonic-gate 	usb_cr_t	ctrl_completion_reason;	/* set by HCD */
1303*7c478bd9Sstevel@tonic-gate 	usb_cb_flags_t	ctrl_cb_flags;  /* Callback context / handling flgs */
1304*7c478bd9Sstevel@tonic-gate } usb_ctrl_req_t;
1305*7c478bd9Sstevel@tonic-gate 
1306*7c478bd9Sstevel@tonic-gate 
1307*7c478bd9Sstevel@tonic-gate /*
1308*7c478bd9Sstevel@tonic-gate  * In the setup packet, the descriptor type is passed in the high byte of the
1309*7c478bd9Sstevel@tonic-gate  * wValue field.
1310*7c478bd9Sstevel@tonic-gate  * descriptor types:
1311*7c478bd9Sstevel@tonic-gate  */
1312*7c478bd9Sstevel@tonic-gate #define	USB_DESCR_TYPE_SETUP_DEV		0x0100
1313*7c478bd9Sstevel@tonic-gate #define	USB_DESCR_TYPE_SETUP_CFG		0x0200
1314*7c478bd9Sstevel@tonic-gate #define	USB_DESCR_TYPE_SETUP_STRING		0x0300
1315*7c478bd9Sstevel@tonic-gate #define	USB_DESCR_TYPE_SETUP_IF			0x0400
1316*7c478bd9Sstevel@tonic-gate #define	USB_DESCR_TYPE_SETUP_EP			0x0500
1317*7c478bd9Sstevel@tonic-gate #define	USB_DESCR_TYPE_SETUP_DEV_QLF		0x0600
1318*7c478bd9Sstevel@tonic-gate #define	USB_DESCR_TYPE_SETUP_OTHER_SPEED_CFG	0x0700
1319*7c478bd9Sstevel@tonic-gate #define	USB_DESCR_TYPE_SETUP_IF_PWR		0x0800
1320*7c478bd9Sstevel@tonic-gate 
1321*7c478bd9Sstevel@tonic-gate #define	USB_DESCR_TYPE_DEV			0x01
1322*7c478bd9Sstevel@tonic-gate #define	USB_DESCR_TYPE_CFG			0x02
1323*7c478bd9Sstevel@tonic-gate #define	USB_DESCR_TYPE_STRING			0x03
1324*7c478bd9Sstevel@tonic-gate #define	USB_DESCR_TYPE_IF			0x04
1325*7c478bd9Sstevel@tonic-gate #define	USB_DESCR_TYPE_EP			0x05
1326*7c478bd9Sstevel@tonic-gate #define	USB_DESCR_TYPE_DEV_QLF			0x06
1327*7c478bd9Sstevel@tonic-gate #define	USB_DESCR_TYPE_OTHER_SPEED_CFG		0x07
1328*7c478bd9Sstevel@tonic-gate #define	USB_DESCR_TYPE_IF_PWR			0x08
1329*7c478bd9Sstevel@tonic-gate 
1330*7c478bd9Sstevel@tonic-gate /*
1331*7c478bd9Sstevel@tonic-gate  * device request type
1332*7c478bd9Sstevel@tonic-gate  */
1333*7c478bd9Sstevel@tonic-gate #define	USB_DEV_REQ_HOST_TO_DEV		0x00
1334*7c478bd9Sstevel@tonic-gate #define	USB_DEV_REQ_DEV_TO_HOST		0x80
1335*7c478bd9Sstevel@tonic-gate #define	USB_DEV_REQ_DIR_MASK		0x80
1336*7c478bd9Sstevel@tonic-gate 
1337*7c478bd9Sstevel@tonic-gate #define	USB_DEV_REQ_TYPE_STANDARD	0x00
1338*7c478bd9Sstevel@tonic-gate #define	USB_DEV_REQ_TYPE_CLASS		0x20
1339*7c478bd9Sstevel@tonic-gate #define	USB_DEV_REQ_TYPE_VENDOR		0x40
1340*7c478bd9Sstevel@tonic-gate #define	USB_DEV_REQ_TYPE_MASK		0x60
1341*7c478bd9Sstevel@tonic-gate 
1342*7c478bd9Sstevel@tonic-gate #define	USB_DEV_REQ_RCPT_DEV		0x00
1343*7c478bd9Sstevel@tonic-gate #define	USB_DEV_REQ_RCPT_IF		0x01
1344*7c478bd9Sstevel@tonic-gate #define	USB_DEV_REQ_RCPT_EP		0x02
1345*7c478bd9Sstevel@tonic-gate #define	USB_DEV_REQ_RCPT_OTHER		0x03
1346*7c478bd9Sstevel@tonic-gate #define	USB_DEV_REQ_RCPT_MASK		0x03
1347*7c478bd9Sstevel@tonic-gate 
1348*7c478bd9Sstevel@tonic-gate /*
1349*7c478bd9Sstevel@tonic-gate  * device request
1350*7c478bd9Sstevel@tonic-gate  */
1351*7c478bd9Sstevel@tonic-gate #define	USB_REQ_GET_STATUS		0x00
1352*7c478bd9Sstevel@tonic-gate #define	USB_REQ_CLEAR_FEATURE		0x01
1353*7c478bd9Sstevel@tonic-gate #define	USB_REQ_SET_FEATURE		0x03
1354*7c478bd9Sstevel@tonic-gate #define	USB_REQ_SET_ADDRESS		0x05
1355*7c478bd9Sstevel@tonic-gate #define	USB_REQ_GET_DESCR		0x06
1356*7c478bd9Sstevel@tonic-gate #define	USB_REQ_SET_DESCR		0x07
1357*7c478bd9Sstevel@tonic-gate #define	USB_REQ_GET_CFG			0x08
1358*7c478bd9Sstevel@tonic-gate #define	USB_REQ_SET_CFG			0x09
1359*7c478bd9Sstevel@tonic-gate #define	USB_REQ_GET_IF			0x0a
1360*7c478bd9Sstevel@tonic-gate #define	USB_REQ_SET_IF			0x0b
1361*7c478bd9Sstevel@tonic-gate #define	USB_REQ_SYNC_FRAME		0x0c
1362*7c478bd9Sstevel@tonic-gate 
1363*7c478bd9Sstevel@tonic-gate /* language ID for string descriptors */
1364*7c478bd9Sstevel@tonic-gate #define	USB_LANG_ID			0x0409
1365*7c478bd9Sstevel@tonic-gate 
1366*7c478bd9Sstevel@tonic-gate /*
1367*7c478bd9Sstevel@tonic-gate  * Standard Feature Selectors
1368*7c478bd9Sstevel@tonic-gate  */
1369*7c478bd9Sstevel@tonic-gate #define	USB_EP_HALT			0x0000
1370*7c478bd9Sstevel@tonic-gate #define	USB_DEV_REMOTE_WAKEUP		0x0001
1371*7c478bd9Sstevel@tonic-gate #define	USB_DEV_TEST_MODE		0x0002
1372*7c478bd9Sstevel@tonic-gate 
1373*7c478bd9Sstevel@tonic-gate 
1374*7c478bd9Sstevel@tonic-gate /*
1375*7c478bd9Sstevel@tonic-gate  * Allocate usb control request
1376*7c478bd9Sstevel@tonic-gate  *
1377*7c478bd9Sstevel@tonic-gate  * Arguments:
1378*7c478bd9Sstevel@tonic-gate  *	dip	- dev_info pointer of the client driver
1379*7c478bd9Sstevel@tonic-gate  *	len	- length of "data" for this control request.
1380*7c478bd9Sstevel@tonic-gate  *		  if 0, no mblk is alloc'ed
1381*7c478bd9Sstevel@tonic-gate  *	flags	- USB_FLAGS_SLEEP: Sleep if resources are not available
1382*7c478bd9Sstevel@tonic-gate  *
1383*7c478bd9Sstevel@tonic-gate  * Return Values:
1384*7c478bd9Sstevel@tonic-gate  *	usb_ctrl_req_t pointer on success, NULL on failure
1385*7c478bd9Sstevel@tonic-gate  *
1386*7c478bd9Sstevel@tonic-gate  * Implementation NOTE: the dip allows checking on detach for memory leaks
1387*7c478bd9Sstevel@tonic-gate  */
1388*7c478bd9Sstevel@tonic-gate usb_ctrl_req_t *usb_alloc_ctrl_req(
1389*7c478bd9Sstevel@tonic-gate 	dev_info_t		*dip,
1390*7c478bd9Sstevel@tonic-gate 	size_t			len,
1391*7c478bd9Sstevel@tonic-gate 	usb_flags_t		flags);
1392*7c478bd9Sstevel@tonic-gate 
1393*7c478bd9Sstevel@tonic-gate 
1394*7c478bd9Sstevel@tonic-gate /*
1395*7c478bd9Sstevel@tonic-gate  * free USB control request
1396*7c478bd9Sstevel@tonic-gate  */
1397*7c478bd9Sstevel@tonic-gate void usb_free_ctrl_req(
1398*7c478bd9Sstevel@tonic-gate 	usb_ctrl_req_t	*reqp);
1399*7c478bd9Sstevel@tonic-gate 
1400*7c478bd9Sstevel@tonic-gate 
1401*7c478bd9Sstevel@tonic-gate /*
1402*7c478bd9Sstevel@tonic-gate  * usb_pipe_ctrl_xfer();
1403*7c478bd9Sstevel@tonic-gate  *	Client driver calls this function to issue the control
1404*7c478bd9Sstevel@tonic-gate  *	request to the USBA which will queue or transport it to the device
1405*7c478bd9Sstevel@tonic-gate  *
1406*7c478bd9Sstevel@tonic-gate  * Arguments:
1407*7c478bd9Sstevel@tonic-gate  *	pipe_handle	- control pipe pipehandle (obtained via usb_pipe_open()
1408*7c478bd9Sstevel@tonic-gate  *	reqp		- pointer to control request
1409*7c478bd9Sstevel@tonic-gate  *	flags		- USB_FLAGS_SLEEP:
1410*7c478bd9Sstevel@tonic-gate  *				wait for the request to complete
1411*7c478bd9Sstevel@tonic-gate  *
1412*7c478bd9Sstevel@tonic-gate  * Return values:
1413*7c478bd9Sstevel@tonic-gate  *	USB_SUCCESS	- successfully queued (no sleep) or successfully
1414*7c478bd9Sstevel@tonic-gate  *			  completed (with sleep specified)
1415*7c478bd9Sstevel@tonic-gate  *	USB_FAILURE	- failure
1416*7c478bd9Sstevel@tonic-gate  *	USB_NO_RESOURCES - no resources
1417*7c478bd9Sstevel@tonic-gate  */
1418*7c478bd9Sstevel@tonic-gate int usb_pipe_ctrl_xfer(usb_pipe_handle_t pipe_handle,
1419*7c478bd9Sstevel@tonic-gate 	usb_ctrl_req_t	*reqp,
1420*7c478bd9Sstevel@tonic-gate 	usb_flags_t		flags);
1421*7c478bd9Sstevel@tonic-gate 
1422*7c478bd9Sstevel@tonic-gate 
1423*7c478bd9Sstevel@tonic-gate /*
1424*7c478bd9Sstevel@tonic-gate  * ---------------------------------------------------------------------------
1425*7c478bd9Sstevel@tonic-gate  * Wrapper function which allocates and deallocates a request structure, and
1426*7c478bd9Sstevel@tonic-gate  * performs a control transfer.
1427*7c478bd9Sstevel@tonic-gate  * ---------------------------------------------------------------------------
1428*7c478bd9Sstevel@tonic-gate  */
1429*7c478bd9Sstevel@tonic-gate 
1430*7c478bd9Sstevel@tonic-gate /*
1431*7c478bd9Sstevel@tonic-gate  * Setup arguments for usb_pipe_ctrl_xfer_wait:
1432*7c478bd9Sstevel@tonic-gate  *
1433*7c478bd9Sstevel@tonic-gate  *	bmRequestType	- characteristics of request
1434*7c478bd9Sstevel@tonic-gate  *	bRequest	- specific request
1435*7c478bd9Sstevel@tonic-gate  *	wValue		- varies according to request
1436*7c478bd9Sstevel@tonic-gate  *	wIndex		- index or offset
1437*7c478bd9Sstevel@tonic-gate  *	wLength		- number of bytes to xfer
1438*7c478bd9Sstevel@tonic-gate  *	attrs		- required request attributes
1439*7c478bd9Sstevel@tonic-gate  *	data		- pointer to pointer to data
1440*7c478bd9Sstevel@tonic-gate  *				IN: HCD will allocate data
1441*7c478bd9Sstevel@tonic-gate  *				OUT: clients driver allocates data
1442*7c478bd9Sstevel@tonic-gate  */
1443*7c478bd9Sstevel@tonic-gate typedef struct usb_ctrl_setup {
1444*7c478bd9Sstevel@tonic-gate 	uchar_t		bmRequestType;
1445*7c478bd9Sstevel@tonic-gate 	uchar_t		bRequest;
1446*7c478bd9Sstevel@tonic-gate 	uint16_t	wValue;
1447*7c478bd9Sstevel@tonic-gate 	uint16_t	wIndex;
1448*7c478bd9Sstevel@tonic-gate 	uint16_t	wLength;
1449*7c478bd9Sstevel@tonic-gate 	usb_req_attrs_t	attrs;
1450*7c478bd9Sstevel@tonic-gate } usb_ctrl_setup_t;
1451*7c478bd9Sstevel@tonic-gate 
1452*7c478bd9Sstevel@tonic-gate 
1453*7c478bd9Sstevel@tonic-gate /*
1454*7c478bd9Sstevel@tonic-gate  * usb_pipe_ctrl_xfer_wait():
1455*7c478bd9Sstevel@tonic-gate  *	for simple synchronous control transactions this wrapper function
1456*7c478bd9Sstevel@tonic-gate  *	will perform the allocation, xfer, and deallocation.
1457*7c478bd9Sstevel@tonic-gate  *	USB_ATTRS_AUTOCLEARING will be enabled
1458*7c478bd9Sstevel@tonic-gate  *
1459*7c478bd9Sstevel@tonic-gate  * Arguments:
1460*7c478bd9Sstevel@tonic-gate  *	pipe_handle	- control pipe pipehandle (obtained via usb_pipe_open())
1461*7c478bd9Sstevel@tonic-gate  *	setup		- contains pointer to client's devinfo,
1462*7c478bd9Sstevel@tonic-gate  *			  setup descriptor params, attributes and data
1463*7c478bd9Sstevel@tonic-gate  *	completion_reason - completion status.
1464*7c478bd9Sstevel@tonic-gate  *	cb_flags	- request completions flags.
1465*7c478bd9Sstevel@tonic-gate  *	flags		- none.
1466*7c478bd9Sstevel@tonic-gate  *
1467*7c478bd9Sstevel@tonic-gate  * Return Values:
1468*7c478bd9Sstevel@tonic-gate  *	USB_SUCCESS	- request successfully executed.
1469*7c478bd9Sstevel@tonic-gate  *	USB_FAILURE	- request failed.
1470*7c478bd9Sstevel@tonic-gate  *	USB_*		- refer to list of all possible return values in
1471*7c478bd9Sstevel@tonic-gate  *			  this file
1472*7c478bd9Sstevel@tonic-gate  *
1473*7c478bd9Sstevel@tonic-gate  * NOTES:
1474*7c478bd9Sstevel@tonic-gate  * - in the case of failure, the client should check completion_reason and
1475*7c478bd9Sstevel@tonic-gate  *   and cb_flags and determine further recovery action
1476*7c478bd9Sstevel@tonic-gate  * - the client should check data and if non-zero, free the data on
1477*7c478bd9Sstevel@tonic-gate  *   completion
1478*7c478bd9Sstevel@tonic-gate  */
1479*7c478bd9Sstevel@tonic-gate int usb_pipe_ctrl_xfer_wait(
1480*7c478bd9Sstevel@tonic-gate 	usb_pipe_handle_t	pipe_handle,
1481*7c478bd9Sstevel@tonic-gate 	usb_ctrl_setup_t	*setup,
1482*7c478bd9Sstevel@tonic-gate 	mblk_t			**data,
1483*7c478bd9Sstevel@tonic-gate 	usb_cr_t		*completion_reason,
1484*7c478bd9Sstevel@tonic-gate 	usb_cb_flags_t		*cb_flags,
1485*7c478bd9Sstevel@tonic-gate 	usb_flags_t		flags);
1486*7c478bd9Sstevel@tonic-gate 
1487*7c478bd9Sstevel@tonic-gate 
1488*7c478bd9Sstevel@tonic-gate /*
1489*7c478bd9Sstevel@tonic-gate  * ---------------------------------------------------------------------------
1490*7c478bd9Sstevel@tonic-gate  * Some utility defines and wrapper functions for standard control requests.
1491*7c478bd9Sstevel@tonic-gate  * ---------------------------------------------------------------------------
1492*7c478bd9Sstevel@tonic-gate  */
1493*7c478bd9Sstevel@tonic-gate 
1494*7c478bd9Sstevel@tonic-gate /*
1495*7c478bd9Sstevel@tonic-gate  *
1496*7c478bd9Sstevel@tonic-gate  * Status bits returned by a usb_get_status().
1497*7c478bd9Sstevel@tonic-gate  */
1498*7c478bd9Sstevel@tonic-gate #define	USB_DEV_SLF_PWRD_STATUS	1	/* Supports Self Power	 */
1499*7c478bd9Sstevel@tonic-gate #define	USB_DEV_RWAKEUP_STATUS	2	/* Remote Wakeup Enabled */
1500*7c478bd9Sstevel@tonic-gate #define	USB_EP_HALT_STATUS	1	/* Endpoint is Halted	 */
1501*7c478bd9Sstevel@tonic-gate #define	USB_IF_STATUS		0	/* Interface Status is 0 */
1502*7c478bd9Sstevel@tonic-gate 
1503*7c478bd9Sstevel@tonic-gate /* length of data returned by USB_REQ_GET_STATUS */
1504*7c478bd9Sstevel@tonic-gate #define	USB_GET_STATUS_LEN		2
1505*7c478bd9Sstevel@tonic-gate 
1506*7c478bd9Sstevel@tonic-gate /*
1507*7c478bd9Sstevel@tonic-gate  * wrapper function returning status of device, interface, or endpoint
1508*7c478bd9Sstevel@tonic-gate  *
1509*7c478bd9Sstevel@tonic-gate  * Arguments:
1510*7c478bd9Sstevel@tonic-gate  *	dip		- devinfo pointer.
1511*7c478bd9Sstevel@tonic-gate  *	ph		- pipe handle
1512*7c478bd9Sstevel@tonic-gate  *	type		- bmRequestType to be used
1513*7c478bd9Sstevel@tonic-gate  *	what		- 0 for device, otherwise interface or ep number
1514*7c478bd9Sstevel@tonic-gate  *	status		- pointer to returned status.
1515*7c478bd9Sstevel@tonic-gate  *	flags		- USB_FLAGS_SLEEP (mandatory)
1516*7c478bd9Sstevel@tonic-gate  *
1517*7c478bd9Sstevel@tonic-gate  * Return Values:
1518*7c478bd9Sstevel@tonic-gate  *	valid usb_status_t	or USB_FAILURE
1519*7c478bd9Sstevel@tonic-gate  *
1520*7c478bd9Sstevel@tonic-gate  */
1521*7c478bd9Sstevel@tonic-gate int usb_get_status(
1522*7c478bd9Sstevel@tonic-gate 	dev_info_t		*dip,
1523*7c478bd9Sstevel@tonic-gate 	usb_pipe_handle_t	ph,
1524*7c478bd9Sstevel@tonic-gate 	uint_t			type,	/* bmRequestType */
1525*7c478bd9Sstevel@tonic-gate 	uint_t			what,	/* 0, interface, endpoint number */
1526*7c478bd9Sstevel@tonic-gate 	uint16_t		*status,
1527*7c478bd9Sstevel@tonic-gate 	usb_flags_t		flags);
1528*7c478bd9Sstevel@tonic-gate 
1529*7c478bd9Sstevel@tonic-gate 
1530*7c478bd9Sstevel@tonic-gate /*
1531*7c478bd9Sstevel@tonic-gate  * function for clearing feature of device, interface, or endpoint
1532*7c478bd9Sstevel@tonic-gate  *
1533*7c478bd9Sstevel@tonic-gate  * Arguments:
1534*7c478bd9Sstevel@tonic-gate  *	dip		- devinfo pointer.
1535*7c478bd9Sstevel@tonic-gate  *	type		- bmRequestType to be used
1536*7c478bd9Sstevel@tonic-gate  *	feature		- feature to be cleared
1537*7c478bd9Sstevel@tonic-gate  *	what		- 0 for device, otherwise interface or ep number
1538*7c478bd9Sstevel@tonic-gate  *	flags		- USB_FLAGS_SLEEP (mandatory)
1539*7c478bd9Sstevel@tonic-gate  *	cb		- if USB_FLAGS_SLEEP has not been specified
1540*7c478bd9Sstevel@tonic-gate  *			  this callback function will be called on
1541*7c478bd9Sstevel@tonic-gate  *			  completion. This callback may be NULL
1542*7c478bd9Sstevel@tonic-gate  *			  and no notification of completion will then
1543*7c478bd9Sstevel@tonic-gate  *			  be provided.
1544*7c478bd9Sstevel@tonic-gate  *	cb_arg		- 2nd argument to callback function.
1545*7c478bd9Sstevel@tonic-gate  *
1546*7c478bd9Sstevel@tonic-gate  * Return Values:
1547*7c478bd9Sstevel@tonic-gate  *	USB_SUCCESS	clearing feature succeeded
1548*7c478bd9Sstevel@tonic-gate  *	USB_FAILURE	clearing feature failed
1549*7c478bd9Sstevel@tonic-gate  *	USB_*		refer to list of all possible return values in
1550*7c478bd9Sstevel@tonic-gate  *			this file
1551*7c478bd9Sstevel@tonic-gate  */
1552*7c478bd9Sstevel@tonic-gate int usb_clr_feature(
1553*7c478bd9Sstevel@tonic-gate 	dev_info_t		*dip,
1554*7c478bd9Sstevel@tonic-gate 	uint_t			type,	/* bmRequestType */
1555*7c478bd9Sstevel@tonic-gate 	uint_t			feature,
1556*7c478bd9Sstevel@tonic-gate 	uint_t			what,	/* 0, interface, endpoint number */
1557*7c478bd9Sstevel@tonic-gate 	usb_flags_t		flags,
1558*7c478bd9Sstevel@tonic-gate 	void			(*cb)(
1559*7c478bd9Sstevel@tonic-gate 					usb_pipe_handle_t ph,
1560*7c478bd9Sstevel@tonic-gate 					usb_opaque_t	arg,
1561*7c478bd9Sstevel@tonic-gate 					int		rval,
1562*7c478bd9Sstevel@tonic-gate 					usb_cb_flags_t	flags),
1563*7c478bd9Sstevel@tonic-gate 	usb_opaque_t		cb_arg);
1564*7c478bd9Sstevel@tonic-gate 
1565*7c478bd9Sstevel@tonic-gate 
1566*7c478bd9Sstevel@tonic-gate /*
1567*7c478bd9Sstevel@tonic-gate  * usb_set_cfg():
1568*7c478bd9Sstevel@tonic-gate  *	Sets the configuration.  Use this function with caution as
1569*7c478bd9Sstevel@tonic-gate  *	the framework is normally responsible for configuration changes.
1570*7c478bd9Sstevel@tonic-gate  *	Changing configuration will fail if pipes are still open or
1571*7c478bd9Sstevel@tonic-gate  *	when invoked from a driver bound to an interface on a composite
1572*7c478bd9Sstevel@tonic-gate  *	device. This function access the device and blocks.
1573*7c478bd9Sstevel@tonic-gate  *
1574*7c478bd9Sstevel@tonic-gate  * Arguments:
1575*7c478bd9Sstevel@tonic-gate  *	dip		- devinfo pointer.
1576*7c478bd9Sstevel@tonic-gate  *	cfg_index	- Index of configuration to set.  Corresponds to
1577*7c478bd9Sstevel@tonic-gate  *			  index in the usb_client_dev_data_t tree of
1578*7c478bd9Sstevel@tonic-gate  *			  configurations.  See usb_client_dev_data_t(9F).
1579*7c478bd9Sstevel@tonic-gate  *	usb_flags	- USB_FLAGS_SLEEP:
1580*7c478bd9Sstevel@tonic-gate  *				wait for completion.
1581*7c478bd9Sstevel@tonic-gate  *	cb		- if USB_FLAGS_SLEEP has not been specified
1582*7c478bd9Sstevel@tonic-gate  *			  this callback function will be called on
1583*7c478bd9Sstevel@tonic-gate  *			  completion. This callback may be NULL
1584*7c478bd9Sstevel@tonic-gate  *			  and no notification of completion will then
1585*7c478bd9Sstevel@tonic-gate  *			  be provided.
1586*7c478bd9Sstevel@tonic-gate  *	cb_arg		- 2nd argument to callback function.
1587*7c478bd9Sstevel@tonic-gate  *
1588*7c478bd9Sstevel@tonic-gate  * callback and callback_arg should be NULL if USB_FLAGS_SLEEP has
1589*7c478bd9Sstevel@tonic-gate  * been specified
1590*7c478bd9Sstevel@tonic-gate  *
1591*7c478bd9Sstevel@tonic-gate  * Return Values:
1592*7c478bd9Sstevel@tonic-gate  *	USB_SUCCESS:	new configuration was set or async request
1593*7c478bd9Sstevel@tonic-gate  *			submitted successfully.
1594*7c478bd9Sstevel@tonic-gate  *	USB_FAILURE:	new configuration could not be set because
1595*7c478bd9Sstevel@tonic-gate  *			it may been illegal configuration or this
1596*7c478bd9Sstevel@tonic-gate  *			caller was not allowed to change configs or
1597*7c478bd9Sstevel@tonic-gate  *			pipes were still open or async request
1598*7c478bd9Sstevel@tonic-gate  *			could not be submitted.
1599*7c478bd9Sstevel@tonic-gate  *	USB_*		refer to list of all possible return values in
1600*7c478bd9Sstevel@tonic-gate  *			this file
1601*7c478bd9Sstevel@tonic-gate  *
1602*7c478bd9Sstevel@tonic-gate  * the pipe handle argument in the callback will be the default pipe handle
1603*7c478bd9Sstevel@tonic-gate  */
1604*7c478bd9Sstevel@tonic-gate int usb_set_cfg(
1605*7c478bd9Sstevel@tonic-gate 	dev_info_t		*dip,
1606*7c478bd9Sstevel@tonic-gate 	uint_t			cfg_index,
1607*7c478bd9Sstevel@tonic-gate 	usb_flags_t		usb_flags,
1608*7c478bd9Sstevel@tonic-gate 	void			(*cb)(
1609*7c478bd9Sstevel@tonic-gate 					usb_pipe_handle_t ph,
1610*7c478bd9Sstevel@tonic-gate 					usb_opaque_t	arg,
1611*7c478bd9Sstevel@tonic-gate 					int		rval,
1612*7c478bd9Sstevel@tonic-gate 					usb_cb_flags_t	flags),
1613*7c478bd9Sstevel@tonic-gate 	usb_opaque_t		cb_arg);
1614*7c478bd9Sstevel@tonic-gate 
1615*7c478bd9Sstevel@tonic-gate 
1616*7c478bd9Sstevel@tonic-gate /*
1617*7c478bd9Sstevel@tonic-gate  * usb_get_cfg:
1618*7c478bd9Sstevel@tonic-gate  *	dip		- pointer to devinfo node
1619*7c478bd9Sstevel@tonic-gate  *	cfgval		- pointer to cfgval
1620*7c478bd9Sstevel@tonic-gate  *	usb_flags	- none, will always block
1621*7c478bd9Sstevel@tonic-gate  *
1622*7c478bd9Sstevel@tonic-gate  * return values:
1623*7c478bd9Sstevel@tonic-gate  *	USB_SUCCESS	- current cfg value is returned to cfgval
1624*7c478bd9Sstevel@tonic-gate  *	USB_*		- refer to list of all possible return values in
1625*7c478bd9Sstevel@tonic-gate  *			  this file
1626*7c478bd9Sstevel@tonic-gate  */
1627*7c478bd9Sstevel@tonic-gate int usb_get_cfg(
1628*7c478bd9Sstevel@tonic-gate 	dev_info_t		*dip,
1629*7c478bd9Sstevel@tonic-gate 	uint_t			*cfgval,
1630*7c478bd9Sstevel@tonic-gate 	usb_flags_t		usb_flags);
1631*7c478bd9Sstevel@tonic-gate 
1632*7c478bd9Sstevel@tonic-gate 
1633*7c478bd9Sstevel@tonic-gate /*
1634*7c478bd9Sstevel@tonic-gate  * The following functions set or get the alternate interface
1635*7c478bd9Sstevel@tonic-gate  * setting.
1636*7c478bd9Sstevel@tonic-gate  *
1637*7c478bd9Sstevel@tonic-gate  * usb_set_alt_if:
1638*7c478bd9Sstevel@tonic-gate  *	dip		- pointer to devinfo node
1639*7c478bd9Sstevel@tonic-gate  *	interface	- interface
1640*7c478bd9Sstevel@tonic-gate  *	alt_number	- alternate to set to
1641*7c478bd9Sstevel@tonic-gate  *	usb_flags	- USB_FLAGS_SLEEP:
1642*7c478bd9Sstevel@tonic-gate  *				wait for completion.
1643*7c478bd9Sstevel@tonic-gate  *	cb		- if USB_FLAGS_SLEEP has not been specified
1644*7c478bd9Sstevel@tonic-gate  *			  this callback function will be called on
1645*7c478bd9Sstevel@tonic-gate  *			  completion. This callback may be NULL
1646*7c478bd9Sstevel@tonic-gate  *			  and no notification of completion will then
1647*7c478bd9Sstevel@tonic-gate  *			  be provided.
1648*7c478bd9Sstevel@tonic-gate  *	cb_arg		- 2nd argument to callback function.
1649*7c478bd9Sstevel@tonic-gate  *
1650*7c478bd9Sstevel@tonic-gate  * callback and callback_arg should be NULL if USB_FLAGS_SLEEP has
1651*7c478bd9Sstevel@tonic-gate  * been specified
1652*7c478bd9Sstevel@tonic-gate  *
1653*7c478bd9Sstevel@tonic-gate  * the pipe handle argument in the callback will be the default pipe handle
1654*7c478bd9Sstevel@tonic-gate  *
1655*7c478bd9Sstevel@tonic-gate  * return values:
1656*7c478bd9Sstevel@tonic-gate  *	USB_SUCCESS:	alternate was set or async request was
1657*7c478bd9Sstevel@tonic-gate  *			submitted.
1658*7c478bd9Sstevel@tonic-gate  *	USB_FAILURE:	alternate could not be set because pipes
1659*7c478bd9Sstevel@tonic-gate  *			were still open or some access error occurred
1660*7c478bd9Sstevel@tonic-gate  *			or an invalid alt if value was passed or
1661*7c478bd9Sstevel@tonic-gate  *			async request could not be submitted
1662*7c478bd9Sstevel@tonic-gate  *	USB_INVALID_PERM the driver does not own the device or the interface
1663*7c478bd9Sstevel@tonic-gate  *	USB_*		refer to list of all possible return values in
1664*7c478bd9Sstevel@tonic-gate  *			this file
1665*7c478bd9Sstevel@tonic-gate  */
1666*7c478bd9Sstevel@tonic-gate int usb_set_alt_if(
1667*7c478bd9Sstevel@tonic-gate 	dev_info_t		*dip,
1668*7c478bd9Sstevel@tonic-gate 	uint_t			interface,
1669*7c478bd9Sstevel@tonic-gate 	uint_t			alt_number,
1670*7c478bd9Sstevel@tonic-gate 	usb_flags_t		usb_flags,
1671*7c478bd9Sstevel@tonic-gate 	void			(*cb)(
1672*7c478bd9Sstevel@tonic-gate 					usb_pipe_handle_t ph,
1673*7c478bd9Sstevel@tonic-gate 					usb_opaque_t	arg,
1674*7c478bd9Sstevel@tonic-gate 					int		rval,
1675*7c478bd9Sstevel@tonic-gate 					usb_cb_flags_t	flags),
1676*7c478bd9Sstevel@tonic-gate 	usb_opaque_t		cb_arg);
1677*7c478bd9Sstevel@tonic-gate 
1678*7c478bd9Sstevel@tonic-gate 
1679*7c478bd9Sstevel@tonic-gate 
1680*7c478bd9Sstevel@tonic-gate /* flags must be USB_FLAGS_SLEEP, and this function will block */
1681*7c478bd9Sstevel@tonic-gate int usb_get_alt_if(
1682*7c478bd9Sstevel@tonic-gate 	dev_info_t		*dip,
1683*7c478bd9Sstevel@tonic-gate 	uint_t			if_number,
1684*7c478bd9Sstevel@tonic-gate 	uint_t			*alt_number,
1685*7c478bd9Sstevel@tonic-gate 	usb_flags_t		flags);
1686*7c478bd9Sstevel@tonic-gate 
1687*7c478bd9Sstevel@tonic-gate 
1688*7c478bd9Sstevel@tonic-gate /*
1689*7c478bd9Sstevel@tonic-gate  * ===========================================================================
1690*7c478bd9Sstevel@tonic-gate  * USB bulk request management
1691*7c478bd9Sstevel@tonic-gate  * ===========================================================================
1692*7c478bd9Sstevel@tonic-gate  */
1693*7c478bd9Sstevel@tonic-gate 
1694*7c478bd9Sstevel@tonic-gate /*
1695*7c478bd9Sstevel@tonic-gate  * A client driver allocates/uses the usb_bulk_req_t for bulk pipe xfers.
1696*7c478bd9Sstevel@tonic-gate  *
1697*7c478bd9Sstevel@tonic-gate  * NOTES:
1698*7c478bd9Sstevel@tonic-gate  * - bulk pipe sharing is not supported
1699*7c478bd9Sstevel@tonic-gate  * - semantics of combinations of flag and attributes:
1700*7c478bd9Sstevel@tonic-gate  *
1701*7c478bd9Sstevel@tonic-gate  * flags     Type  attributes	data	timeout semantics
1702*7c478bd9Sstevel@tonic-gate  * ----------------------------------------------------------------
1703*7c478bd9Sstevel@tonic-gate  *  x	      x    x		== NULL    x	   illegal
1704*7c478bd9Sstevel@tonic-gate  *
1705*7c478bd9Sstevel@tonic-gate  * no sleep  IN    x		!= NULL    0	   fill buffer, no timeout
1706*7c478bd9Sstevel@tonic-gate  *						   callback when xfer-len has
1707*7c478bd9Sstevel@tonic-gate  *						   been xferred
1708*7c478bd9Sstevel@tonic-gate  * no sleep  IN    x		!= NULL    > 0	   fill buffer, with timeout
1709*7c478bd9Sstevel@tonic-gate  *						   callback when xfer-len has
1710*7c478bd9Sstevel@tonic-gate  *						   been xferred
1711*7c478bd9Sstevel@tonic-gate  *
1712*7c478bd9Sstevel@tonic-gate  * sleep     IN    x		!= NULL    0	   fill buffer, no timeout
1713*7c478bd9Sstevel@tonic-gate  *						   unblock when xfer-len has
1714*7c478bd9Sstevel@tonic-gate  *						   been xferred
1715*7c478bd9Sstevel@tonic-gate  *						   no callback
1716*7c478bd9Sstevel@tonic-gate  * sleep     IN    x		!= NULL    > 0	   fill buffer, with timeout
1717*7c478bd9Sstevel@tonic-gate  *						   unblock when xfer-len has
1718*7c478bd9Sstevel@tonic-gate  *						   been xferred or timeout
1719*7c478bd9Sstevel@tonic-gate  *						   no callback
1720*7c478bd9Sstevel@tonic-gate  *
1721*7c478bd9Sstevel@tonic-gate  *  X	     OUT SHORT_XFER_OK	  x	   x	   illegal
1722*7c478bd9Sstevel@tonic-gate  *
1723*7c478bd9Sstevel@tonic-gate  * no sleep  OUT   x		!= NULL    0	   empty buffer, no timeout
1724*7c478bd9Sstevel@tonic-gate  *						   callback when xfer-len has
1725*7c478bd9Sstevel@tonic-gate  *						   been xferred
1726*7c478bd9Sstevel@tonic-gate  * no sleep  OUT   x		!= NULL    > 0	   empty buffer, with timeout
1727*7c478bd9Sstevel@tonic-gate  *						   callback when xfer-len has
1728*7c478bd9Sstevel@tonic-gate  *						   been xferred or timeout
1729*7c478bd9Sstevel@tonic-gate  *
1730*7c478bd9Sstevel@tonic-gate  * sleep     OUT   x		!= NULL    0	   empty buffer, no timeout
1731*7c478bd9Sstevel@tonic-gate  *						   unblock when xfer-len has
1732*7c478bd9Sstevel@tonic-gate  *						   been xferred
1733*7c478bd9Sstevel@tonic-gate  *						   no callback
1734*7c478bd9Sstevel@tonic-gate  * sleep     OUT   x		!= NULL    > 0	   empty buffer, with timeout
1735*7c478bd9Sstevel@tonic-gate  *						   unblock when xfer-len has
1736*7c478bd9Sstevel@tonic-gate  *						   been xferred or timeout
1737*7c478bd9Sstevel@tonic-gate  *						   no callback
1738*7c478bd9Sstevel@tonic-gate  *
1739*7c478bd9Sstevel@tonic-gate  * - bulk_len and bulk_data must be > 0.  SHORT_XFER_OK is not applicable.
1740*7c478bd9Sstevel@tonic-gate  *
1741*7c478bd9Sstevel@tonic-gate  * - multiple bulk requests can be queued
1742*7c478bd9Sstevel@tonic-gate  *
1743*7c478bd9Sstevel@tonic-gate  * - Splitting large Bulk xfer:
1744*7c478bd9Sstevel@tonic-gate  * The HCD driver, due to internal constraints, can only do a limited size bulk
1745*7c478bd9Sstevel@tonic-gate  * data xfer per request.  The current limitations are 32K for UHCI and 128K
1746*7c478bd9Sstevel@tonic-gate  * for OHCI.  So, a client driver may first determine this limitation (by
1747*7c478bd9Sstevel@tonic-gate  * calling the USBA interface usb_pipe_bulk_transfer_size()); and restrict
1748*7c478bd9Sstevel@tonic-gate  * itself to doing xfers in multiples of this fixed size.  This forces a client
1749*7c478bd9Sstevel@tonic-gate  * driver to do data xfers in a loop for a large request, splitting it into
1750*7c478bd9Sstevel@tonic-gate  * multiple chunks of fixed size.
1751*7c478bd9Sstevel@tonic-gate  */
1752*7c478bd9Sstevel@tonic-gate typedef struct usb_bulk_req {
1753*7c478bd9Sstevel@tonic-gate 	uint_t		bulk_len;	/* number of bytes to xfer	*/
1754*7c478bd9Sstevel@tonic-gate 	mblk_t		*bulk_data;	/* the data for the data phase	*/
1755*7c478bd9Sstevel@tonic-gate 					/* IN: allocated by HCD		*/
1756*7c478bd9Sstevel@tonic-gate 					/* OUT: allocated by client	*/
1757*7c478bd9Sstevel@tonic-gate 	uint_t		bulk_timeout;	/* xfer timeout value in secs	*/
1758*7c478bd9Sstevel@tonic-gate 	usb_opaque_t	bulk_client_private; /* Client specific information */
1759*7c478bd9Sstevel@tonic-gate 	usb_req_attrs_t bulk_attributes; /* xfer-attributes	*/
1760*7c478bd9Sstevel@tonic-gate 
1761*7c478bd9Sstevel@tonic-gate 	/* Normal Callback function (For synch xfers) */
1762*7c478bd9Sstevel@tonic-gate 	void		(*bulk_cb)(usb_pipe_handle_t ph,
1763*7c478bd9Sstevel@tonic-gate 				struct usb_bulk_req *req);
1764*7c478bd9Sstevel@tonic-gate 
1765*7c478bd9Sstevel@tonic-gate 	/* Exception Callback function (For asynch xfers) */
1766*7c478bd9Sstevel@tonic-gate 	void		(*bulk_exc_cb)(usb_pipe_handle_t ph,
1767*7c478bd9Sstevel@tonic-gate 				struct usb_bulk_req *req);
1768*7c478bd9Sstevel@tonic-gate 
1769*7c478bd9Sstevel@tonic-gate 	/* set by USBA/HCD on completion */
1770*7c478bd9Sstevel@tonic-gate 	usb_cr_t	bulk_completion_reason;	/* set by HCD		*/
1771*7c478bd9Sstevel@tonic-gate 	usb_cb_flags_t	bulk_cb_flags;  /* Callback context / handling flgs */
1772*7c478bd9Sstevel@tonic-gate } usb_bulk_req_t;
1773*7c478bd9Sstevel@tonic-gate 
1774*7c478bd9Sstevel@tonic-gate 
1775*7c478bd9Sstevel@tonic-gate /*
1776*7c478bd9Sstevel@tonic-gate  * Allocate/free usb bulk request
1777*7c478bd9Sstevel@tonic-gate  *
1778*7c478bd9Sstevel@tonic-gate  * Arguments:
1779*7c478bd9Sstevel@tonic-gate  *	dip		- pointer to dev_info_t of the client driver
1780*7c478bd9Sstevel@tonic-gate  *	len		- 0 or length of mblk to be allocated
1781*7c478bd9Sstevel@tonic-gate  *	flags		- USB_FLAGS_SLEEP:
1782*7c478bd9Sstevel@tonic-gate  *				wait for resources
1783*7c478bd9Sstevel@tonic-gate  *
1784*7c478bd9Sstevel@tonic-gate  * Return Values:
1785*7c478bd9Sstevel@tonic-gate  *	usb_bulk_req_t on success, NULL on failure
1786*7c478bd9Sstevel@tonic-gate  */
1787*7c478bd9Sstevel@tonic-gate usb_bulk_req_t *usb_alloc_bulk_req(
1788*7c478bd9Sstevel@tonic-gate 	dev_info_t		*dip,
1789*7c478bd9Sstevel@tonic-gate 	size_t			len,
1790*7c478bd9Sstevel@tonic-gate 	usb_flags_t		flags);
1791*7c478bd9Sstevel@tonic-gate 
1792*7c478bd9Sstevel@tonic-gate 
1793*7c478bd9Sstevel@tonic-gate void usb_free_bulk_req(
1794*7c478bd9Sstevel@tonic-gate 	usb_bulk_req_t	*reqp);
1795*7c478bd9Sstevel@tonic-gate 
1796*7c478bd9Sstevel@tonic-gate 
1797*7c478bd9Sstevel@tonic-gate /*
1798*7c478bd9Sstevel@tonic-gate  * usb_pipe_bulk_xfer():
1799*7c478bd9Sstevel@tonic-gate  *
1800*7c478bd9Sstevel@tonic-gate  * Client drivers call this function to issue the bulk xfer to the USBA
1801*7c478bd9Sstevel@tonic-gate  * which will queue or transfer it to the device
1802*7c478bd9Sstevel@tonic-gate  *
1803*7c478bd9Sstevel@tonic-gate  * Arguments:
1804*7c478bd9Sstevel@tonic-gate  *	pipe_handle	- bulk pipe handle (obtained via usb_pipe_open()
1805*7c478bd9Sstevel@tonic-gate  *	reqp		- pointer to bulk data xfer request (IN or OUT)
1806*7c478bd9Sstevel@tonic-gate  *	flags		- USB_FLAGS_SLEEP:
1807*7c478bd9Sstevel@tonic-gate  *				wait for the request to complete
1808*7c478bd9Sstevel@tonic-gate  *
1809*7c478bd9Sstevel@tonic-gate  * Return Values:
1810*7c478bd9Sstevel@tonic-gate  *	USB_SUCCESS	- success
1811*7c478bd9Sstevel@tonic-gate  *	USB_FAILURE	- unspecified failure
1812*7c478bd9Sstevel@tonic-gate  *	USB_NO_RESOURCES - no resources
1813*7c478bd9Sstevel@tonic-gate  *
1814*7c478bd9Sstevel@tonic-gate  */
1815*7c478bd9Sstevel@tonic-gate int usb_pipe_bulk_xfer(
1816*7c478bd9Sstevel@tonic-gate 	usb_pipe_handle_t	pipe_handle,
1817*7c478bd9Sstevel@tonic-gate 	usb_bulk_req_t		*reqp,
1818*7c478bd9Sstevel@tonic-gate 	usb_flags_t		flags);
1819*7c478bd9Sstevel@tonic-gate 
1820*7c478bd9Sstevel@tonic-gate /* Get maximum bulk transfer size */
1821*7c478bd9Sstevel@tonic-gate int usb_pipe_get_max_bulk_transfer_size(
1822*7c478bd9Sstevel@tonic-gate 	dev_info_t		*dip,
1823*7c478bd9Sstevel@tonic-gate 	size_t			*size);
1824*7c478bd9Sstevel@tonic-gate 
1825*7c478bd9Sstevel@tonic-gate 
1826*7c478bd9Sstevel@tonic-gate /*
1827*7c478bd9Sstevel@tonic-gate  * ===========================================================================
1828*7c478bd9Sstevel@tonic-gate  * USB interrupt pipe request management
1829*7c478bd9Sstevel@tonic-gate  * ===========================================================================
1830*7c478bd9Sstevel@tonic-gate  */
1831*7c478bd9Sstevel@tonic-gate 
1832*7c478bd9Sstevel@tonic-gate /*
1833*7c478bd9Sstevel@tonic-gate  * A client driver allocates and uses the usb_intr_req_t for
1834*7c478bd9Sstevel@tonic-gate  * all interrupt pipe transfers.
1835*7c478bd9Sstevel@tonic-gate  *
1836*7c478bd9Sstevel@tonic-gate  * USB_FLAGS_SLEEP indicates here just to wait for resources except
1837*7c478bd9Sstevel@tonic-gate  * for ONE_XFER where we also wait for completion
1838*7c478bd9Sstevel@tonic-gate  *
1839*7c478bd9Sstevel@tonic-gate  * semantics flags and attribute combinations:
1840*7c478bd9Sstevel@tonic-gate  *
1841*7c478bd9Sstevel@tonic-gate  * Notes:
1842*7c478bd9Sstevel@tonic-gate  * none attributes indicates neither ONE_XFER nor SHORT_XFER_OK
1843*7c478bd9Sstevel@tonic-gate  *
1844*7c478bd9Sstevel@tonic-gate  * flags     Type  attributes	   data    timeout semantics
1845*7c478bd9Sstevel@tonic-gate  * ----------------------------------------------------------------
1846*7c478bd9Sstevel@tonic-gate  *  x	     IN      x		   != NULL  x	    illegal
1847*7c478bd9Sstevel@tonic-gate  *  x	     IN   ONE_XFER=0	   x	   !=0	    illegal
1848*7c478bd9Sstevel@tonic-gate  *
1849*7c478bd9Sstevel@tonic-gate  *  x	     IN   ONE_XFER=0	   NULL     0	   continuous polling,
1850*7c478bd9Sstevel@tonic-gate  *						   many callbacks
1851*7c478bd9Sstevel@tonic-gate  *						   request is returned on
1852*7c478bd9Sstevel@tonic-gate  *						   stop polling
1853*7c478bd9Sstevel@tonic-gate  *
1854*7c478bd9Sstevel@tonic-gate  * no sleep  IN   ONE_XFER	   NULL     0	   one time poll, no timeout,
1855*7c478bd9Sstevel@tonic-gate  *						   one callback
1856*7c478bd9Sstevel@tonic-gate  * no sleep  IN   ONE_XFER	   NULL    !=0	   one time poll, with
1857*7c478bd9Sstevel@tonic-gate  *						   timeout, one callback
1858*7c478bd9Sstevel@tonic-gate  *
1859*7c478bd9Sstevel@tonic-gate  * sleep     IN   ONE_XFER	   NULL     0	   one time poll, no timeout,
1860*7c478bd9Sstevel@tonic-gate  *						   no callback,
1861*7c478bd9Sstevel@tonic-gate  *						   block for completion
1862*7c478bd9Sstevel@tonic-gate  * sleep     IN   ONE_XFER	   NULL    !=0	   one time poll, with timeout,
1863*7c478bd9Sstevel@tonic-gate  *						   no callback
1864*7c478bd9Sstevel@tonic-gate  *						   block for completion
1865*7c478bd9Sstevel@tonic-gate  *
1866*7c478bd9Sstevel@tonic-gate  *  x	     OUT     x		   NULL    x	   illegal
1867*7c478bd9Sstevel@tonic-gate  *  x	     OUT  ONE_XFER	   x	   x	   illegal
1868*7c478bd9Sstevel@tonic-gate  *  x	     OUT  SHORT_XFER_OK    x	   x	   illegal
1869*7c478bd9Sstevel@tonic-gate  *
1870*7c478bd9Sstevel@tonic-gate  *  x	     OUT   none		   != NULL 0	   xfer until data exhausted,
1871*7c478bd9Sstevel@tonic-gate  *						   no timeout,	one callback
1872*7c478bd9Sstevel@tonic-gate  *  x	     OUT   none		   != NULL !=0	   xfer until data exhausted,
1873*7c478bd9Sstevel@tonic-gate  *						   with timeout, one callback
1874*7c478bd9Sstevel@tonic-gate  *
1875*7c478bd9Sstevel@tonic-gate  * - Reads (IN):
1876*7c478bd9Sstevel@tonic-gate  *
1877*7c478bd9Sstevel@tonic-gate  * The client driver does *not* provide a data buffer.
1878*7c478bd9Sstevel@tonic-gate  * By default, a READ request would mean continuous polling for data IN. The
1879*7c478bd9Sstevel@tonic-gate  * HCD typically reads "wMaxPacketSize" amount of 'periodic data'. A client
1880*7c478bd9Sstevel@tonic-gate  * driver may force the HCD to read instead intr_len
1881*7c478bd9Sstevel@tonic-gate  * amount of 'periodic data' (See section 1).
1882*7c478bd9Sstevel@tonic-gate  *
1883*7c478bd9Sstevel@tonic-gate  * The HCD issues a callback to the client after each polling interval if
1884*7c478bd9Sstevel@tonic-gate  * it has read in some data. Note that the amount of data read IN is either
1885*7c478bd9Sstevel@tonic-gate  * intr_len or 'wMaxPacketSize' in length.
1886*7c478bd9Sstevel@tonic-gate  *
1887*7c478bd9Sstevel@tonic-gate  * Normally, the HCD keeps polling interrupt pipe forever even if there is
1888*7c478bd9Sstevel@tonic-gate  * no data to be read IN.  A client driver may stop this polling by
1889*7c478bd9Sstevel@tonic-gate  * calling usb_pipe_stop_intr_polling().
1890*7c478bd9Sstevel@tonic-gate  *
1891*7c478bd9Sstevel@tonic-gate  * If a client driver chooses to pass USB_ATTRS_ONE_XFER as
1892*7c478bd9Sstevel@tonic-gate  * 'xfer_attributes' the HCD will poll for data until some data is received.
1893*7c478bd9Sstevel@tonic-gate  * HCD reads in the data and does a callback and stops polling for any more
1894*7c478bd9Sstevel@tonic-gate  * data.  In this case, the client driver need not explicitly call
1895*7c478bd9Sstevel@tonic-gate  * usb_pipe_stop_intr_polling().
1896*7c478bd9Sstevel@tonic-gate  *
1897*7c478bd9Sstevel@tonic-gate  * When continuous polling is stopped, the original request is returned with
1898*7c478bd9Sstevel@tonic-gate  * USB_CR_STOPPED_POLLING.
1899*7c478bd9Sstevel@tonic-gate  *
1900*7c478bd9Sstevel@tonic-gate  * - Writes (OUT):
1901*7c478bd9Sstevel@tonic-gate  *
1902*7c478bd9Sstevel@tonic-gate  * A client driver provides the data buffer, and data, needed for intr write.
1903*7c478bd9Sstevel@tonic-gate  * There is no continuous write mode, a la  read (See previous section).
1904*7c478bd9Sstevel@tonic-gate  * The USB_ATTRS_ONE_XFER attribute is illegal.
1905*7c478bd9Sstevel@tonic-gate  * By default USBA keeps writing intr data until the provided data buffer
1906*7c478bd9Sstevel@tonic-gate  * has been written out. The HCD does ONE callback to the client driver.
1907*7c478bd9Sstevel@tonic-gate  * Queueing is supported.
1908*7c478bd9Sstevel@tonic-gate  * Max size is 8k
1909*7c478bd9Sstevel@tonic-gate  */
1910*7c478bd9Sstevel@tonic-gate typedef struct usb_intr_req {
1911*7c478bd9Sstevel@tonic-gate 	uint_t		intr_len;	/* OUT: size of total xfer */
1912*7c478bd9Sstevel@tonic-gate 					/* IN : packet size */
1913*7c478bd9Sstevel@tonic-gate 	mblk_t		*intr_data;	/* the data for the data phase	*/
1914*7c478bd9Sstevel@tonic-gate 					/* IN: allocated by HCD		*/
1915*7c478bd9Sstevel@tonic-gate 					/* OUT: allocated by client	*/
1916*7c478bd9Sstevel@tonic-gate 	usb_opaque_t	intr_client_private; /* Client specific information  */
1917*7c478bd9Sstevel@tonic-gate 	uint_t		intr_timeout;	/* only with ONE TIME POLL, in secs */
1918*7c478bd9Sstevel@tonic-gate 	usb_req_attrs_t	intr_attributes;
1919*7c478bd9Sstevel@tonic-gate 
1920*7c478bd9Sstevel@tonic-gate 	/* Normal callback function (For synch transfers) */
1921*7c478bd9Sstevel@tonic-gate 	void		(*intr_cb)(usb_pipe_handle_t ph,
1922*7c478bd9Sstevel@tonic-gate 				struct usb_intr_req *req);
1923*7c478bd9Sstevel@tonic-gate 
1924*7c478bd9Sstevel@tonic-gate 	/* Exception callback function (For asynch transfers) */
1925*7c478bd9Sstevel@tonic-gate 	void		(*intr_exc_cb)(usb_pipe_handle_t ph,
1926*7c478bd9Sstevel@tonic-gate 				struct usb_intr_req *req);
1927*7c478bd9Sstevel@tonic-gate 
1928*7c478bd9Sstevel@tonic-gate 	/* set by USBA/HCD on completion */
1929*7c478bd9Sstevel@tonic-gate 	usb_cr_t	intr_completion_reason;	/* set by HCD */
1930*7c478bd9Sstevel@tonic-gate 	usb_cb_flags_t	intr_cb_flags;  /* Callback context / handling flgs */
1931*7c478bd9Sstevel@tonic-gate } usb_intr_req_t;
1932*7c478bd9Sstevel@tonic-gate 
1933*7c478bd9Sstevel@tonic-gate 
1934*7c478bd9Sstevel@tonic-gate /*
1935*7c478bd9Sstevel@tonic-gate  * Allocate/free usb interrupt pipe request
1936*7c478bd9Sstevel@tonic-gate  *
1937*7c478bd9Sstevel@tonic-gate  * Arguments:
1938*7c478bd9Sstevel@tonic-gate  *	dip		- pointer to dev_info_t of the client driver
1939*7c478bd9Sstevel@tonic-gate  *	reqp		- pointer to request structure
1940*7c478bd9Sstevel@tonic-gate  *	len		- 0 or length of mblk for this interrupt request
1941*7c478bd9Sstevel@tonic-gate  *	flags		- USB_FLAGS_SLEEP:
1942*7c478bd9Sstevel@tonic-gate  *				Sleep if resources are not available
1943*7c478bd9Sstevel@tonic-gate  *
1944*7c478bd9Sstevel@tonic-gate  * Return Values:
1945*7c478bd9Sstevel@tonic-gate  *	usb_intr_req_t on success, NULL on failure
1946*7c478bd9Sstevel@tonic-gate  */
1947*7c478bd9Sstevel@tonic-gate usb_intr_req_t *usb_alloc_intr_req(
1948*7c478bd9Sstevel@tonic-gate 	dev_info_t		*dip,
1949*7c478bd9Sstevel@tonic-gate 	size_t			len,
1950*7c478bd9Sstevel@tonic-gate 	usb_flags_t		flags);
1951*7c478bd9Sstevel@tonic-gate 
1952*7c478bd9Sstevel@tonic-gate 
1953*7c478bd9Sstevel@tonic-gate void usb_free_intr_req(
1954*7c478bd9Sstevel@tonic-gate 	usb_intr_req_t	*reqp);
1955*7c478bd9Sstevel@tonic-gate 
1956*7c478bd9Sstevel@tonic-gate 
1957*7c478bd9Sstevel@tonic-gate /*
1958*7c478bd9Sstevel@tonic-gate  * usb_pipe_intr_xfer():
1959*7c478bd9Sstevel@tonic-gate  *
1960*7c478bd9Sstevel@tonic-gate  * Client drivers call this function to issue the intr xfer to USBA/HCD
1961*7c478bd9Sstevel@tonic-gate  * which starts polling the device
1962*7c478bd9Sstevel@tonic-gate  *
1963*7c478bd9Sstevel@tonic-gate  * Arguments:
1964*7c478bd9Sstevel@tonic-gate  *	pipe_handle	- interrupt pipe handle (obtained via usb_pipe_open()
1965*7c478bd9Sstevel@tonic-gate  *	reqp		- pointer tothe interrupt pipe xfer request (IN or OUT)
1966*7c478bd9Sstevel@tonic-gate  *	flags		- USB_FLAGS_SLEEP:
1967*7c478bd9Sstevel@tonic-gate  *				wait for resources to be available
1968*7c478bd9Sstevel@tonic-gate  *
1969*7c478bd9Sstevel@tonic-gate  * return values:
1970*7c478bd9Sstevel@tonic-gate  *	USB_SUCCESS	- success
1971*7c478bd9Sstevel@tonic-gate  *	USB_FAILURE	- unspecified failure
1972*7c478bd9Sstevel@tonic-gate  *	USB_NO_RESOURCES  - no resources
1973*7c478bd9Sstevel@tonic-gate  *
1974*7c478bd9Sstevel@tonic-gate  * NOTE: start polling on an IN pipe that is already being polled is a NOP.
1975*7c478bd9Sstevel@tonic-gate  *	 We don't queue requests on OUT pipe
1976*7c478bd9Sstevel@tonic-gate  */
1977*7c478bd9Sstevel@tonic-gate int usb_pipe_intr_xfer(
1978*7c478bd9Sstevel@tonic-gate 	usb_pipe_handle_t	pipe_handle,
1979*7c478bd9Sstevel@tonic-gate 	usb_intr_req_t		*req,
1980*7c478bd9Sstevel@tonic-gate 	usb_flags_t		flags);
1981*7c478bd9Sstevel@tonic-gate 
1982*7c478bd9Sstevel@tonic-gate 
1983*7c478bd9Sstevel@tonic-gate /*
1984*7c478bd9Sstevel@tonic-gate  * usb_pipe_stop_intr_polling():
1985*7c478bd9Sstevel@tonic-gate  *
1986*7c478bd9Sstevel@tonic-gate  * Client drivers call this function to stop the automatic data-in/out transfers
1987*7c478bd9Sstevel@tonic-gate  * without closing the pipe.
1988*7c478bd9Sstevel@tonic-gate  *
1989*7c478bd9Sstevel@tonic-gate  * If USB_FLAGS_SLEEP  has been specified then this function will block until
1990*7c478bd9Sstevel@tonic-gate  * polling has been stopped and all callbacks completed. If USB_FLAGS_SLEEP
1991*7c478bd9Sstevel@tonic-gate  * has NOT been specified then polling is terminated when the original
1992*7c478bd9Sstevel@tonic-gate  * request that started the polling has been returned with
1993*7c478bd9Sstevel@tonic-gate  * USB_CR_STOPPED_POLLING
1994*7c478bd9Sstevel@tonic-gate  *
1995*7c478bd9Sstevel@tonic-gate  * Stop polling should never fail.
1996*7c478bd9Sstevel@tonic-gate  *
1997*7c478bd9Sstevel@tonic-gate  * Args:-
1998*7c478bd9Sstevel@tonic-gate  *	pipe_handle	- interrupt pipe handle (obtained via usb_pipe_open()).
1999*7c478bd9Sstevel@tonic-gate  *	flags		- USB_FLAGS_SLEEP:
2000*7c478bd9Sstevel@tonic-gate  *				wait for the resources to be available.
2001*7c478bd9Sstevel@tonic-gate  */
2002*7c478bd9Sstevel@tonic-gate void usb_pipe_stop_intr_polling(
2003*7c478bd9Sstevel@tonic-gate 	usb_pipe_handle_t	pipe_handle,
2004*7c478bd9Sstevel@tonic-gate 	usb_flags_t		flags);
2005*7c478bd9Sstevel@tonic-gate 
2006*7c478bd9Sstevel@tonic-gate 
2007*7c478bd9Sstevel@tonic-gate /*
2008*7c478bd9Sstevel@tonic-gate  * ===========================================================================
2009*7c478bd9Sstevel@tonic-gate  * USB isochronous xfer management
2010*7c478bd9Sstevel@tonic-gate  * ===========================================================================
2011*7c478bd9Sstevel@tonic-gate  */
2012*7c478bd9Sstevel@tonic-gate 
2013*7c478bd9Sstevel@tonic-gate /*
2014*7c478bd9Sstevel@tonic-gate  * The usb frame number is an absolute number since boot and incremented
2015*7c478bd9Sstevel@tonic-gate  * every 1 ms.
2016*7c478bd9Sstevel@tonic-gate  */
2017*7c478bd9Sstevel@tonic-gate typedef	uint64_t	usb_frame_number_t;
2018*7c478bd9Sstevel@tonic-gate 
2019*7c478bd9Sstevel@tonic-gate /*
2020*7c478bd9Sstevel@tonic-gate  * USB ischronous packet descriptor
2021*7c478bd9Sstevel@tonic-gate  *
2022*7c478bd9Sstevel@tonic-gate  * An array of structures of type usb_isoc_pkt_descr_t must be allocated and
2023*7c478bd9Sstevel@tonic-gate  * initialized by the client driver using usb_alloc_isoc_req(). The client
2024*7c478bd9Sstevel@tonic-gate  * driver must set isoc_pkt_length in each packet descriptor before submitting
2025*7c478bd9Sstevel@tonic-gate  * the request.
2026*7c478bd9Sstevel@tonic-gate  */
2027*7c478bd9Sstevel@tonic-gate typedef struct usb_isoc_pkt_descr {
2028*7c478bd9Sstevel@tonic-gate 	/*
2029*7c478bd9Sstevel@tonic-gate 	 * Set by the client driver, for all isochronous requests, to the
2030*7c478bd9Sstevel@tonic-gate 	 * number of bytes to transfer in a frame.
2031*7c478bd9Sstevel@tonic-gate 	 */
2032*7c478bd9Sstevel@tonic-gate 	ushort_t	isoc_pkt_length;
2033*7c478bd9Sstevel@tonic-gate 
2034*7c478bd9Sstevel@tonic-gate 	/*
2035*7c478bd9Sstevel@tonic-gate 	 * Set by HCD to actual number of bytes sent/received in frame.
2036*7c478bd9Sstevel@tonic-gate 	 */
2037*7c478bd9Sstevel@tonic-gate 	ushort_t	isoc_pkt_actual_length;
2038*7c478bd9Sstevel@tonic-gate 
2039*7c478bd9Sstevel@tonic-gate 	/*
2040*7c478bd9Sstevel@tonic-gate 	 * Per frame status set by HCD both for the isochronous IN and OUT
2041*7c478bd9Sstevel@tonic-gate 	 * requests.  If any status is non-zero then isoc_error_count in the
2042*7c478bd9Sstevel@tonic-gate 	 * isoc_req will be non-zero.
2043*7c478bd9Sstevel@tonic-gate 	 */
2044*7c478bd9Sstevel@tonic-gate 	usb_cr_t	isoc_pkt_status;
2045*7c478bd9Sstevel@tonic-gate } usb_isoc_pkt_descr_t;
2046*7c478bd9Sstevel@tonic-gate 
2047*7c478bd9Sstevel@tonic-gate 
2048*7c478bd9Sstevel@tonic-gate /*
2049*7c478bd9Sstevel@tonic-gate  * USB isochronous request
2050*7c478bd9Sstevel@tonic-gate  *
2051*7c478bd9Sstevel@tonic-gate  * The client driver allocates the usb_isoc_req_t before sending an
2052*7c478bd9Sstevel@tonic-gate  * isochronous requests.
2053*7c478bd9Sstevel@tonic-gate  *
2054*7c478bd9Sstevel@tonic-gate  * USB_FLAGS_SLEEP indicates here just to wait for resources but not
2055*7c478bd9Sstevel@tonic-gate  * to wait for completion
2056*7c478bd9Sstevel@tonic-gate  *
2057*7c478bd9Sstevel@tonic-gate  * Semantics of various combinations for data xfers:
2058*7c478bd9Sstevel@tonic-gate  *
2059*7c478bd9Sstevel@tonic-gate  * Note: attributes considered in this table are ONE_XFER, START_FRAME,
2060*7c478bd9Sstevel@tonic-gate  *	XFER_ASAP, SHORT_XFER
2061*7c478bd9Sstevel@tonic-gate  *
2062*7c478bd9Sstevel@tonic-gate  *
2063*7c478bd9Sstevel@tonic-gate  * flags     Type  attributes		   data    semantics
2064*7c478bd9Sstevel@tonic-gate  * ---------------------------------------------------------------------
2065*7c478bd9Sstevel@tonic-gate  * x	     x	   x			NULL	   illegal
2066*7c478bd9Sstevel@tonic-gate  *
2067*7c478bd9Sstevel@tonic-gate  * x	     x	   ONE_XFER		 x	   illegal
2068*7c478bd9Sstevel@tonic-gate  *
2069*7c478bd9Sstevel@tonic-gate  * x	     IN    x			!=NULL	   continuous polling,
2070*7c478bd9Sstevel@tonic-gate  *						   many callbacks
2071*7c478bd9Sstevel@tonic-gate  *
2072*7c478bd9Sstevel@tonic-gate  * x	     IN    ISOC_START_FRAME	!=NULL	   invalid if Current_frame# >
2073*7c478bd9Sstevel@tonic-gate  *						   "isoc_frame_no"
2074*7c478bd9Sstevel@tonic-gate  * x	     IN    ISOC_XFER_ASAP	!=NULL	   "isoc_frame_no" ignored.
2075*7c478bd9Sstevel@tonic-gate  *						   HCD determines when to
2076*7c478bd9Sstevel@tonic-gate  *						   insert xfer
2077*7c478bd9Sstevel@tonic-gate  *
2078*7c478bd9Sstevel@tonic-gate  * x	     OUT   ONE_XFER		x	   illegal
2079*7c478bd9Sstevel@tonic-gate  * x	     OUT   SHORT_XFER_OK	x	   illegal
2080*7c478bd9Sstevel@tonic-gate  *
2081*7c478bd9Sstevel@tonic-gate  * x	     OUT   ISOC_START_FRAME	!=NULL	   invalid if Current_frame# >
2082*7c478bd9Sstevel@tonic-gate  *						   "isoc_frame_no"
2083*7c478bd9Sstevel@tonic-gate  * x	     OUT   ISOC_XFER_ASAP	!=NULL	   "isoc_frame_no" ignored.
2084*7c478bd9Sstevel@tonic-gate  *						    HCD determines when to
2085*7c478bd9Sstevel@tonic-gate  *						   insert xfer
2086*7c478bd9Sstevel@tonic-gate  */
2087*7c478bd9Sstevel@tonic-gate typedef struct usb_isoc_req {
2088*7c478bd9Sstevel@tonic-gate 	/*
2089*7c478bd9Sstevel@tonic-gate 	 * Starting frame number will be set by the client driver in which
2090*7c478bd9Sstevel@tonic-gate 	 * to begin this request. This frame number is used to synchronize
2091*7c478bd9Sstevel@tonic-gate 	 * requests queued to different isochronous pipes. The frame number
2092*7c478bd9Sstevel@tonic-gate 	 * is optional and client driver can skip starting frame number by
2093*7c478bd9Sstevel@tonic-gate 	 * setting USB_ISOC_ATTRS_ASAP. In this case, HCD will decide starting
2094*7c478bd9Sstevel@tonic-gate 	 * frame number for this isochronous request.  If this field is 0,
2095*7c478bd9Sstevel@tonic-gate 	 * then this indicates an invalid frame number.
2096*7c478bd9Sstevel@tonic-gate 	 */
2097*7c478bd9Sstevel@tonic-gate 	usb_frame_number_t	isoc_frame_no;
2098*7c478bd9Sstevel@tonic-gate 
2099*7c478bd9Sstevel@tonic-gate 	/*
2100*7c478bd9Sstevel@tonic-gate 	 * Number and length of isochronous data packets.
2101*7c478bd9Sstevel@tonic-gate 	 * The first field is set by client  driver and may not exceed
2102*7c478bd9Sstevel@tonic-gate 	 * the maximum number of entries in the usb isochronous packet
2103*7c478bd9Sstevel@tonic-gate 	 * descriptors.
2104*7c478bd9Sstevel@tonic-gate 	 */
2105*7c478bd9Sstevel@tonic-gate 	ushort_t		isoc_pkts_count;
2106*7c478bd9Sstevel@tonic-gate 	ushort_t		isoc_pkts_length;
2107*7c478bd9Sstevel@tonic-gate 
2108*7c478bd9Sstevel@tonic-gate 	/*
2109*7c478bd9Sstevel@tonic-gate 	 * This field will be set by HCD and this field indicates the number
2110*7c478bd9Sstevel@tonic-gate 	 * of packets that completed with errors.
2111*7c478bd9Sstevel@tonic-gate 	 */
2112*7c478bd9Sstevel@tonic-gate 	ushort_t		isoc_error_count;
2113*7c478bd9Sstevel@tonic-gate 
2114*7c478bd9Sstevel@tonic-gate 	/*
2115*7c478bd9Sstevel@tonic-gate 	 * Attributes specific to particular usb isochronous request.
2116*7c478bd9Sstevel@tonic-gate 	 * Supported values are: USB_ATTRS_ISOC_START_FRAME,
2117*7c478bd9Sstevel@tonic-gate 	 * USB_ATTRS_ISOC_XFER_ASAP.
2118*7c478bd9Sstevel@tonic-gate 	 */
2119*7c478bd9Sstevel@tonic-gate 	usb_req_attrs_t 	isoc_attributes;
2120*7c478bd9Sstevel@tonic-gate 
2121*7c478bd9Sstevel@tonic-gate 	/*
2122*7c478bd9Sstevel@tonic-gate 	 * Isochronous OUT:
2123*7c478bd9Sstevel@tonic-gate 	 *	allocated and set by client driver, freed and zeroed by HCD
2124*7c478bd9Sstevel@tonic-gate 	 *	on successful completion
2125*7c478bd9Sstevel@tonic-gate 	 * Isochronous IN:
2126*7c478bd9Sstevel@tonic-gate 	 *	allocated and set by HCD, freed by client driver
2127*7c478bd9Sstevel@tonic-gate 	 */
2128*7c478bd9Sstevel@tonic-gate 	mblk_t			*isoc_data;
2129*7c478bd9Sstevel@tonic-gate 
2130*7c478bd9Sstevel@tonic-gate 	/*
2131*7c478bd9Sstevel@tonic-gate 	 * The client driver specific private information.
2132*7c478bd9Sstevel@tonic-gate 	 */
2133*7c478bd9Sstevel@tonic-gate 	usb_opaque_t		isoc_client_private;
2134*7c478bd9Sstevel@tonic-gate 
2135*7c478bd9Sstevel@tonic-gate 	/*
2136*7c478bd9Sstevel@tonic-gate 	 * Isochronous OUT:
2137*7c478bd9Sstevel@tonic-gate 	 *	must be allocated & initialized by client driver
2138*7c478bd9Sstevel@tonic-gate 	 * Isochronous IN:
2139*7c478bd9Sstevel@tonic-gate 	 *	must be allocated by client driver
2140*7c478bd9Sstevel@tonic-gate 	 */
2141*7c478bd9Sstevel@tonic-gate 	struct usb_isoc_pkt_descr *isoc_pkt_descr;
2142*7c478bd9Sstevel@tonic-gate 
2143*7c478bd9Sstevel@tonic-gate 	/* Normal callback function (For synch transfers) */
2144*7c478bd9Sstevel@tonic-gate 	void			(*isoc_cb)(usb_pipe_handle_t ph,
2145*7c478bd9Sstevel@tonic-gate 					struct usb_isoc_req *req);
2146*7c478bd9Sstevel@tonic-gate 
2147*7c478bd9Sstevel@tonic-gate 	/* Exception callback function (For asynch transfers) */
2148*7c478bd9Sstevel@tonic-gate 	void			(*isoc_exc_cb)(usb_pipe_handle_t ph,
2149*7c478bd9Sstevel@tonic-gate 					struct usb_isoc_req *req);
2150*7c478bd9Sstevel@tonic-gate 
2151*7c478bd9Sstevel@tonic-gate 	/* set by USBA/HCD on completion */
2152*7c478bd9Sstevel@tonic-gate 	usb_cr_t		isoc_completion_reason;	/* set by HCD */
2153*7c478bd9Sstevel@tonic-gate 					/* Callback context / handling flgs */
2154*7c478bd9Sstevel@tonic-gate 	usb_cb_flags_t		isoc_cb_flags;
2155*7c478bd9Sstevel@tonic-gate } usb_isoc_req_t;
2156*7c478bd9Sstevel@tonic-gate 
2157*7c478bd9Sstevel@tonic-gate 
2158*7c478bd9Sstevel@tonic-gate /*
2159*7c478bd9Sstevel@tonic-gate  * Allocate/free usb isochronous resources
2160*7c478bd9Sstevel@tonic-gate  *
2161*7c478bd9Sstevel@tonic-gate  * isoc_pkts_count must be > 0
2162*7c478bd9Sstevel@tonic-gate  *
2163*7c478bd9Sstevel@tonic-gate  * Arguments:
2164*7c478bd9Sstevel@tonic-gate  *	dip		- client driver's devinfo pointer
2165*7c478bd9Sstevel@tonic-gate  *	isoc_pkts_count - number of pkts required
2166*7c478bd9Sstevel@tonic-gate  *	len		- 0 or size of mblk to allocate
2167*7c478bd9Sstevel@tonic-gate  *	flags		- USB_FLAGS_SLEEP:
2168*7c478bd9Sstevel@tonic-gate  *				wait for resources
2169*7c478bd9Sstevel@tonic-gate  *
2170*7c478bd9Sstevel@tonic-gate  * Return Values:
2171*7c478bd9Sstevel@tonic-gate  *	usb_isoc_req pointer or NULL
2172*7c478bd9Sstevel@tonic-gate  */
2173*7c478bd9Sstevel@tonic-gate usb_isoc_req_t *usb_alloc_isoc_req(
2174*7c478bd9Sstevel@tonic-gate 	dev_info_t		*dip,
2175*7c478bd9Sstevel@tonic-gate 	uint_t			isoc_pkts_count,
2176*7c478bd9Sstevel@tonic-gate 	size_t			len,
2177*7c478bd9Sstevel@tonic-gate 	usb_flags_t		flags);
2178*7c478bd9Sstevel@tonic-gate 
2179*7c478bd9Sstevel@tonic-gate void	usb_free_isoc_req(
2180*7c478bd9Sstevel@tonic-gate 	usb_isoc_req_t		*usb_isoc_req);
2181*7c478bd9Sstevel@tonic-gate 
2182*7c478bd9Sstevel@tonic-gate /*
2183*7c478bd9Sstevel@tonic-gate  * Returns current usb frame number.
2184*7c478bd9Sstevel@tonic-gate  */
2185*7c478bd9Sstevel@tonic-gate usb_frame_number_t usb_get_current_frame_number(
2186*7c478bd9Sstevel@tonic-gate 	dev_info_t		*dip);
2187*7c478bd9Sstevel@tonic-gate 
2188*7c478bd9Sstevel@tonic-gate /*
2189*7c478bd9Sstevel@tonic-gate  * Get maximum isochronous packets per usb isochronous request
2190*7c478bd9Sstevel@tonic-gate  */
2191*7c478bd9Sstevel@tonic-gate uint_t usb_get_max_pkts_per_isoc_request(
2192*7c478bd9Sstevel@tonic-gate 	dev_info_t		*dip);
2193*7c478bd9Sstevel@tonic-gate 
2194*7c478bd9Sstevel@tonic-gate /*
2195*7c478bd9Sstevel@tonic-gate  * usb_pipe_isoc_xfer()
2196*7c478bd9Sstevel@tonic-gate  *
2197*7c478bd9Sstevel@tonic-gate  * Client drivers call this to issue the isoch xfer (IN and OUT) to the USBA
2198*7c478bd9Sstevel@tonic-gate  * which starts polling the device.
2199*7c478bd9Sstevel@tonic-gate  *
2200*7c478bd9Sstevel@tonic-gate  * Arguments:
2201*7c478bd9Sstevel@tonic-gate  *	pipe_handle	- isoc pipe handle (obtained via usb_pipe_open().
2202*7c478bd9Sstevel@tonic-gate  *	reqp		- pointer to the isochronous pipe IN xfer request
2203*7c478bd9Sstevel@tonic-gate  *			  allocated by the client driver.
2204*7c478bd9Sstevel@tonic-gate  *	flags		- USB_FLAGS_SLEEP:
2205*7c478bd9Sstevel@tonic-gate  *				wait for the resources to be available.
2206*7c478bd9Sstevel@tonic-gate  *
2207*7c478bd9Sstevel@tonic-gate  * return values:
2208*7c478bd9Sstevel@tonic-gate  *	USB_SUCCESS	- success.
2209*7c478bd9Sstevel@tonic-gate  *	USB_FAILURE	- unspecified failure.
2210*7c478bd9Sstevel@tonic-gate  *	USB_NO_RESOURCES  - no resources.
2211*7c478bd9Sstevel@tonic-gate  *	USB_NO_FRAME_NUMBER - START_FRAME, ASAP flags not specified.
2212*7c478bd9Sstevel@tonic-gate  *	USB_INVALID_START_FRAME	- Starting USB frame number invalid.
2213*7c478bd9Sstevel@tonic-gate  *
2214*7c478bd9Sstevel@tonic-gate  * Notes:
2215*7c478bd9Sstevel@tonic-gate  * - usb_pipe_isoc_xfer on an IN pipe that is already being polled is a NOP.
2216*7c478bd9Sstevel@tonic-gate  * - requests can be queued on an OUT pipe.
2217*7c478bd9Sstevel@tonic-gate  */
2218*7c478bd9Sstevel@tonic-gate int usb_pipe_isoc_xfer(
2219*7c478bd9Sstevel@tonic-gate 	usb_pipe_handle_t	pipe_handle,
2220*7c478bd9Sstevel@tonic-gate 	usb_isoc_req_t		*reqp,
2221*7c478bd9Sstevel@tonic-gate 	usb_flags_t		flags);
2222*7c478bd9Sstevel@tonic-gate 
2223*7c478bd9Sstevel@tonic-gate /*
2224*7c478bd9Sstevel@tonic-gate  * usb_pipe_stop_isoc_polling():
2225*7c478bd9Sstevel@tonic-gate  *
2226*7c478bd9Sstevel@tonic-gate  * Client drivers call this function to stop the automatic data-in/out
2227*7c478bd9Sstevel@tonic-gate  * transfers without closing the isoc pipe.
2228*7c478bd9Sstevel@tonic-gate  *
2229*7c478bd9Sstevel@tonic-gate  * If USB_FLAGS_SLEEP  has been specified then this function will block until
2230*7c478bd9Sstevel@tonic-gate  * polling has been stopped and all callbacks completed. If USB_FLAGS_SLEEP
2231*7c478bd9Sstevel@tonic-gate  * has NOT been specified then polling is terminated when the original
2232*7c478bd9Sstevel@tonic-gate  * request that started the polling has been returned with
2233*7c478bd9Sstevel@tonic-gate  * USB_CR_STOPPED_POLLING
2234*7c478bd9Sstevel@tonic-gate  *
2235*7c478bd9Sstevel@tonic-gate  * Stop polling should never fail.
2236*7c478bd9Sstevel@tonic-gate  *
2237*7c478bd9Sstevel@tonic-gate  * Arguments:
2238*7c478bd9Sstevel@tonic-gate  *	pipe_handle	- isoc pipe handle (obtained via usb_pipe_open().
2239*7c478bd9Sstevel@tonic-gate  *	flags		- USB_FLAGS_SLEEP:
2240*7c478bd9Sstevel@tonic-gate  *				wait for polling to be stopped and all
2241*7c478bd9Sstevel@tonic-gate  *				callbacks completed.
2242*7c478bd9Sstevel@tonic-gate  */
2243*7c478bd9Sstevel@tonic-gate void usb_pipe_stop_isoc_polling(
2244*7c478bd9Sstevel@tonic-gate 	usb_pipe_handle_t	pipe_handle,
2245*7c478bd9Sstevel@tonic-gate 	usb_flags_t		flags);
2246*7c478bd9Sstevel@tonic-gate 
2247*7c478bd9Sstevel@tonic-gate /*
2248*7c478bd9Sstevel@tonic-gate  * ***************************************************************************
2249*7c478bd9Sstevel@tonic-gate  * USB device power management:
2250*7c478bd9Sstevel@tonic-gate  * ***************************************************************************
2251*7c478bd9Sstevel@tonic-gate  */
2252*7c478bd9Sstevel@tonic-gate 
2253*7c478bd9Sstevel@tonic-gate /*
2254*7c478bd9Sstevel@tonic-gate  *
2255*7c478bd9Sstevel@tonic-gate  * As any usb device will have a max of 4 possible power states
2256*7c478bd9Sstevel@tonic-gate  * the #define	for them are provided below with mapping to the
2257*7c478bd9Sstevel@tonic-gate  * corresponding OS power levels.
2258*7c478bd9Sstevel@tonic-gate  */
2259*7c478bd9Sstevel@tonic-gate #define	USB_DEV_PWR_D0		USB_DEV_OS_FULL_PWR
2260*7c478bd9Sstevel@tonic-gate #define	USB_DEV_PWR_D1		5
2261*7c478bd9Sstevel@tonic-gate #define	USB_DEV_PWR_D2		6
2262*7c478bd9Sstevel@tonic-gate #define	USB_DEV_PWR_D3		USB_DEV_OS_PWR_OFF
2263*7c478bd9Sstevel@tonic-gate 
2264*7c478bd9Sstevel@tonic-gate #define	USB_DEV_OS_PWR_0	0
2265*7c478bd9Sstevel@tonic-gate #define	USB_DEV_OS_PWR_1	1
2266*7c478bd9Sstevel@tonic-gate #define	USB_DEV_OS_PWR_2	2
2267*7c478bd9Sstevel@tonic-gate #define	USB_DEV_OS_PWR_3	3
2268*7c478bd9Sstevel@tonic-gate #define	USB_DEV_OS_PWR_OFF	USB_DEV_OS_PWR_0
2269*7c478bd9Sstevel@tonic-gate #define	USB_DEV_OS_FULL_PWR	USB_DEV_OS_PWR_3
2270*7c478bd9Sstevel@tonic-gate 
2271*7c478bd9Sstevel@tonic-gate /* Bit Masks for Power States */
2272*7c478bd9Sstevel@tonic-gate #define	USB_DEV_OS_PWRMASK_D0	1
2273*7c478bd9Sstevel@tonic-gate #define	USB_DEV_OS_PWRMASK_D1	2
2274*7c478bd9Sstevel@tonic-gate #define	USB_DEV_OS_PWRMASK_D2	4
2275*7c478bd9Sstevel@tonic-gate #define	USB_DEV_OS_PWRMASK_D3	8
2276*7c478bd9Sstevel@tonic-gate 
2277*7c478bd9Sstevel@tonic-gate /* conversion for OS to Dx levels */
2278*7c478bd9Sstevel@tonic-gate #define	USB_DEV_OS_PWR2USB_PWR(l)	(USB_DEV_OS_FULL_PWR - (l))
2279*7c478bd9Sstevel@tonic-gate 
2280*7c478bd9Sstevel@tonic-gate /* from OS level to Dx mask */
2281*7c478bd9Sstevel@tonic-gate #define	USB_DEV_PWRMASK(l)	(1 << (USB_DEV_OS_FULL_PWR - (l)))
2282*7c478bd9Sstevel@tonic-gate 
2283*7c478bd9Sstevel@tonic-gate /* Macro to check valid power level */
2284*7c478bd9Sstevel@tonic-gate #define	USB_DEV_PWRSTATE_OK(state, level) \
2285*7c478bd9Sstevel@tonic-gate 		(((state) & USB_DEV_PWRMASK((level))) == 0)
2286*7c478bd9Sstevel@tonic-gate 
2287*7c478bd9Sstevel@tonic-gate int usb_handle_remote_wakeup(
2288*7c478bd9Sstevel@tonic-gate 	dev_info_t	*dip,
2289*7c478bd9Sstevel@tonic-gate 	int		cmd);
2290*7c478bd9Sstevel@tonic-gate 
2291*7c478bd9Sstevel@tonic-gate /* argument to usb_handle_remote wakeup function */
2292*7c478bd9Sstevel@tonic-gate #define	USB_REMOTE_WAKEUP_ENABLE	1
2293*7c478bd9Sstevel@tonic-gate #define	USB_REMOTE_WAKEUP_DISABLE	2
2294*7c478bd9Sstevel@tonic-gate 
2295*7c478bd9Sstevel@tonic-gate int usb_create_pm_components(
2296*7c478bd9Sstevel@tonic-gate 	dev_info_t	*dip,
2297*7c478bd9Sstevel@tonic-gate 	uint_t		*pwrstates);
2298*7c478bd9Sstevel@tonic-gate 
2299*7c478bd9Sstevel@tonic-gate /*
2300*7c478bd9Sstevel@tonic-gate  * ***************************************************************************
2301*7c478bd9Sstevel@tonic-gate  * System event registration
2302*7c478bd9Sstevel@tonic-gate  * ***************************************************************************
2303*7c478bd9Sstevel@tonic-gate  */
2304*7c478bd9Sstevel@tonic-gate 
2305*7c478bd9Sstevel@tonic-gate /* Functions for registering hotplug callback functions. */
2306*7c478bd9Sstevel@tonic-gate 
2307*7c478bd9Sstevel@tonic-gate int usb_register_hotplug_cbs(
2308*7c478bd9Sstevel@tonic-gate 	dev_info_t	*dip,
2309*7c478bd9Sstevel@tonic-gate 	int		(*disconnect_event_handler)(dev_info_t *dip),
2310*7c478bd9Sstevel@tonic-gate 	int		(*reconnect_event_handler)(dev_info_t *dip));
2311*7c478bd9Sstevel@tonic-gate 
2312*7c478bd9Sstevel@tonic-gate void usb_unregister_hotplug_cbs(dev_info_t *dip);
2313*7c478bd9Sstevel@tonic-gate 
2314*7c478bd9Sstevel@tonic-gate 
2315*7c478bd9Sstevel@tonic-gate /*
2316*7c478bd9Sstevel@tonic-gate  * ***************************************************************************
2317*7c478bd9Sstevel@tonic-gate  * USB Device and interface class, subclass and protocol codes
2318*7c478bd9Sstevel@tonic-gate  * ***************************************************************************
2319*7c478bd9Sstevel@tonic-gate  */
2320*7c478bd9Sstevel@tonic-gate 
2321*7c478bd9Sstevel@tonic-gate /*
2322*7c478bd9Sstevel@tonic-gate  * Available device and interface class codes.
2323*7c478bd9Sstevel@tonic-gate  * Those which are device class codes are noted.
2324*7c478bd9Sstevel@tonic-gate  */
2325*7c478bd9Sstevel@tonic-gate 
2326*7c478bd9Sstevel@tonic-gate #define	USB_CLASS_AUDIO		1
2327*7c478bd9Sstevel@tonic-gate #define	USB_CLASS_COMM		2	/* Communication device class and */
2328*7c478bd9Sstevel@tonic-gate #define	USB_CLASS_CDC_CTRL	2	/* CDC-control iface class, also 2 */
2329*7c478bd9Sstevel@tonic-gate #define	USB_CLASS_HID		3
2330*7c478bd9Sstevel@tonic-gate #define	USB_CLASS_PHYSICAL	5
2331*7c478bd9Sstevel@tonic-gate #define	USB_CLASS_PRINTER	7
2332*7c478bd9Sstevel@tonic-gate #define	USB_CLASS_MASS_STORAGE	8
2333*7c478bd9Sstevel@tonic-gate #define	USB_CLASS_HUB		9	/* Device class */
2334*7c478bd9Sstevel@tonic-gate #define	USB_CLASS_CDC_DATA	10
2335*7c478bd9Sstevel@tonic-gate #define	USB_CLASS_CCID		11
2336*7c478bd9Sstevel@tonic-gate #define	USB_CLASS_SECURITY	13
2337*7c478bd9Sstevel@tonic-gate #define	USB_CLASS_DIAG		220	/* Device class */
2338*7c478bd9Sstevel@tonic-gate #define	USB_CLASS_WIRELESS	224	/* Device class */
2339*7c478bd9Sstevel@tonic-gate #define	USB_CLASS_MISC		239	/* Device class */
2340*7c478bd9Sstevel@tonic-gate #define	USB_CLASS_APP		254
2341*7c478bd9Sstevel@tonic-gate #define	USB_CLASS_VENDOR_SPEC	255	/* Device class */
2342*7c478bd9Sstevel@tonic-gate 
2343*7c478bd9Sstevel@tonic-gate #define	USB_CLASS_PER_INTERFACE	0	/* Class info is at interface level */
2344*7c478bd9Sstevel@tonic-gate 
2345*7c478bd9Sstevel@tonic-gate /* Audio subclass. */
2346*7c478bd9Sstevel@tonic-gate #define	USB_SUBCLS_AUD_CONTROL		0x01
2347*7c478bd9Sstevel@tonic-gate #define	USB_SUBCLS_AUD_STREAMING	0x02
2348*7c478bd9Sstevel@tonic-gate #define	USB_SUBCLS_AUD_MIDI_STREAMING	0x03
2349*7c478bd9Sstevel@tonic-gate 
2350*7c478bd9Sstevel@tonic-gate /* Comms  subclass. */
2351*7c478bd9Sstevel@tonic-gate #define	USB_SUBCLS_CDCC_DIRECT_LINE	0x01
2352*7c478bd9Sstevel@tonic-gate #define	USB_SUBCLS_CDCC_ABSTRCT_CTRL	0x02
2353*7c478bd9Sstevel@tonic-gate #define	USB_SUBCLS_CDCC_PHONE_CTRL	0x03
2354*7c478bd9Sstevel@tonic-gate #define	USB_SUBCLS_CDCC_MULTCNL_ISDN	0x04
2355*7c478bd9Sstevel@tonic-gate #define	USB_SUBCLS_CDCC_ISDN		0x05
2356*7c478bd9Sstevel@tonic-gate #define	USB_SUBCLS_CDCC_ETHERNET	0x06
2357*7c478bd9Sstevel@tonic-gate #define	USB_SUBCLS_CDCC_ATM_NETWORK	0x07
2358*7c478bd9Sstevel@tonic-gate 
2359*7c478bd9Sstevel@tonic-gate /* HID subclass and protocols. */
2360*7c478bd9Sstevel@tonic-gate #define	USB_SUBCLS_HID_1		1
2361*7c478bd9Sstevel@tonic-gate 
2362*7c478bd9Sstevel@tonic-gate #define	USB_PROTO_HID_KEYBOARD		0x01	/* legacy keyboard */
2363*7c478bd9Sstevel@tonic-gate #define	USB_PROTO_HID_MOUSE		0x02	/* legacy mouse */
2364*7c478bd9Sstevel@tonic-gate 
2365*7c478bd9Sstevel@tonic-gate /* Printer subclass and protocols. */
2366*7c478bd9Sstevel@tonic-gate #define	USB_SUBCLS_PRINTER_1		1
2367*7c478bd9Sstevel@tonic-gate 
2368*7c478bd9Sstevel@tonic-gate #define	USB_PROTO_PRINTER_UNI		0x01	/* Unidirectional interface */
2369*7c478bd9Sstevel@tonic-gate #define	USB_PROTO_PRINTER_BI		0x02	/* Bidirectional interface */
2370*7c478bd9Sstevel@tonic-gate 
2371*7c478bd9Sstevel@tonic-gate /* Mass storage subclasses and protocols. */
2372*7c478bd9Sstevel@tonic-gate #define	USB_SUBCLS_MS_RBC_T10		0x1	/* flash */
2373*7c478bd9Sstevel@tonic-gate #define	USB_SUBCLS_MS_SFF8020I		0x2	/* CD-ROM */
2374*7c478bd9Sstevel@tonic-gate #define	USB_SUBCLS_MS_QIC_157		0x3	/* tape */
2375*7c478bd9Sstevel@tonic-gate #define	USB_SUBCLS_MS_UFI		0x4	/* USB Floppy Disk Drive   */
2376*7c478bd9Sstevel@tonic-gate #define	USB_SUBCLS_MS_SFF8070I		0x5	/* floppy */
2377*7c478bd9Sstevel@tonic-gate #define	USB_SUBCLS_MS_SCSI		0x6	/* transparent scsi */
2378*7c478bd9Sstevel@tonic-gate 
2379*7c478bd9Sstevel@tonic-gate #define	USB_PROTO_MS_CBI_WC		0x00	/* USB CBI Proto w/cmp intr */
2380*7c478bd9Sstevel@tonic-gate #define	USB_PROTO_MS_CBI		0x01    /* USB CBI Protocol */
2381*7c478bd9Sstevel@tonic-gate #define	USB_PROTO_MS_ISD_1999_SILICN	0x02    /* ZIP Protocol */
2382*7c478bd9Sstevel@tonic-gate #define	USB_PROTO_MS_BULK_ONLY		0x50    /* USB Bulk Only Protocol */
2383*7c478bd9Sstevel@tonic-gate 
2384*7c478bd9Sstevel@tonic-gate /* Application subclasses. */
2385*7c478bd9Sstevel@tonic-gate #define	USB_SUBCLS_APP_FIRMWARE		0x01	/* app spec f/w subclass */
2386*7c478bd9Sstevel@tonic-gate #define	USB_SUBCLS_APP_IRDA		0x02	/* app spec IrDa subclass */
2387*7c478bd9Sstevel@tonic-gate #define	USB_SUBCLS_APP_TEST		0x03	/* app spec test subclass */
2388*7c478bd9Sstevel@tonic-gate 
2389*7c478bd9Sstevel@tonic-gate 
2390*7c478bd9Sstevel@tonic-gate 
2391*7c478bd9Sstevel@tonic-gate #ifdef __cplusplus
2392*7c478bd9Sstevel@tonic-gate }
2393*7c478bd9Sstevel@tonic-gate #endif
2394*7c478bd9Sstevel@tonic-gate 
2395*7c478bd9Sstevel@tonic-gate #endif /* _SYS_USB_USBAI_H */
2396