xref: /illumos-gate/usr/src/uts/common/sys/usb/usbai.h (revision 0d2006e4)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5b3001defSlg  * Common Development and Distribution License (the "License").
6b3001defSlg  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
20b3001defSlg  */
21b3001defSlg /*
22ff0e937bSRaymond Chen  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
237c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
24e2c88f0cSGarrett D'Amore  *
25e2c88f0cSGarrett D'Amore  * Copyright 2014 Garrett D'Amore <garrett@damore.org>
26*0d2006e4SRobert Mustacchi  * Copyright 2019 Joyent, Inc.
277c478bd9Sstevel@tonic-gate  */
287c478bd9Sstevel@tonic-gate 
297c478bd9Sstevel@tonic-gate #ifndef	_SYS_USB_USBAI_H
307c478bd9Sstevel@tonic-gate #define	_SYS_USB_USBAI_H
317c478bd9Sstevel@tonic-gate 
327c478bd9Sstevel@tonic-gate 
337c478bd9Sstevel@tonic-gate #ifdef	__cplusplus
347c478bd9Sstevel@tonic-gate extern "C" {
357c478bd9Sstevel@tonic-gate #endif
367c478bd9Sstevel@tonic-gate 
37993e3fafSRobert Mustacchi /* This header file is for USBA2.1 */
387c478bd9Sstevel@tonic-gate #define	USBA_MAJOR_VER 2
39993e3fafSRobert Mustacchi #define	USBA_MINOR_VER 1
407c478bd9Sstevel@tonic-gate 
417c478bd9Sstevel@tonic-gate /*
427c478bd9Sstevel@tonic-gate  * USBAI: Interfaces Between USBA and Client Driver
437c478bd9Sstevel@tonic-gate  *
447c478bd9Sstevel@tonic-gate  *
457c478bd9Sstevel@tonic-gate  * Universal USB device state management :
467c478bd9Sstevel@tonic-gate  *
477c478bd9Sstevel@tonic-gate  *	PWRED_DWN---<3----4>--ONLINE---<2-----1>-DISCONNECTED
487c478bd9Sstevel@tonic-gate  *	    |			 ^		     |
497c478bd9Sstevel@tonic-gate  *	    |			 6		     |
507c478bd9Sstevel@tonic-gate  *	    |			 |		     |
517c478bd9Sstevel@tonic-gate  *	    |			 5		     |
527c478bd9Sstevel@tonic-gate  *	    |			 v		     |
537c478bd9Sstevel@tonic-gate  *	    +----5>----------SUSPENDED----<5----7>---+
547c478bd9Sstevel@tonic-gate  *
557c478bd9Sstevel@tonic-gate  *	1 = Device Unplug
567c478bd9Sstevel@tonic-gate  *	2 = Original Device reconnected
577c478bd9Sstevel@tonic-gate  *	3 = Device idles for time T & transitions to low power state
587c478bd9Sstevel@tonic-gate  *	4 = Remote wakeup by device OR Application kicking off IO to device
597c478bd9Sstevel@tonic-gate  *	5 = Notification to save state prior to DDI_SUSPEND
607c478bd9Sstevel@tonic-gate  *	6 = Notification to restore state after DDI_RESUME with correct device
617c478bd9Sstevel@tonic-gate  *	7 = Notification to restore state after DDI_RESUME with device
627c478bd9Sstevel@tonic-gate  *	    disconnected or a wrong device
637c478bd9Sstevel@tonic-gate  *
647c478bd9Sstevel@tonic-gate  *	NOTE: device states 0x80 to 0xff are device specific and can be
657c478bd9Sstevel@tonic-gate  *		used by client drivers
667c478bd9Sstevel@tonic-gate  */
677c478bd9Sstevel@tonic-gate #define	USB_DEV_ONLINE		1	/* device is online */
687c478bd9Sstevel@tonic-gate #define	USB_DEV_DISCONNECTED	2	/* indicates disconnect */
697c478bd9Sstevel@tonic-gate #define	USB_DEV_SUSPENDED	3	/* DDI_SUSPEND operation */
707c478bd9Sstevel@tonic-gate #define	USB_DEV_PWRED_DOWN	4	/* indicates power off state */
717c478bd9Sstevel@tonic-gate 
727c478bd9Sstevel@tonic-gate 
737c478bd9Sstevel@tonic-gate /*
747c478bd9Sstevel@tonic-gate  * ***************************************************************************
757c478bd9Sstevel@tonic-gate  * USBA error and status definitions
767c478bd9Sstevel@tonic-gate  * ***************************************************************************
777c478bd9Sstevel@tonic-gate  */
787c478bd9Sstevel@tonic-gate 
797c478bd9Sstevel@tonic-gate 
807c478bd9Sstevel@tonic-gate /*
817c478bd9Sstevel@tonic-gate  * USBA function return values
827c478bd9Sstevel@tonic-gate  */
837c478bd9Sstevel@tonic-gate #define	USB_SUCCESS		0	/* call success			  */
847c478bd9Sstevel@tonic-gate #define	USB_FAILURE		-1	/* unspecified USBA or HCD error  */
857c478bd9Sstevel@tonic-gate #define	USB_NO_RESOURCES	-2	/* no resources available	  */
867c478bd9Sstevel@tonic-gate #define	USB_NO_BANDWIDTH	-3	/* no bandwidth available	  */
877c478bd9Sstevel@tonic-gate #define	USB_NOT_SUPPORTED	-4	/* function not supported by HCD  */
887c478bd9Sstevel@tonic-gate #define	USB_PIPE_ERROR		-5	/* error occured on the pipe	  */
897c478bd9Sstevel@tonic-gate #define	USB_INVALID_PIPE	-6	/* pipe handle passed is invalid  */
907c478bd9Sstevel@tonic-gate #define	USB_NO_FRAME_NUMBER	-7	/* frame No or ASAP not specified */
917c478bd9Sstevel@tonic-gate #define	USB_INVALID_START_FRAME	-8	/* starting USB frame not valid	  */
927c478bd9Sstevel@tonic-gate #define	USB_HC_HARDWARE_ERROR	-9	/* usb host controller error	  */
937c478bd9Sstevel@tonic-gate #define	USB_INVALID_REQUEST	-10	/* request had invalid values	  */
947c478bd9Sstevel@tonic-gate #define	USB_INVALID_CONTEXT	-11	/* sleep flag in interrupt context */
957c478bd9Sstevel@tonic-gate #define	USB_INVALID_VERSION	-12	/* invalid version specified	  */
967c478bd9Sstevel@tonic-gate #define	USB_INVALID_ARGS	-13	/* invalid func args specified	  */
977c478bd9Sstevel@tonic-gate #define	USB_INVALID_PERM	-14	/* privileged operation		  */
987c478bd9Sstevel@tonic-gate #define	USB_BUSY		-15	/* busy condition		  */
997c478bd9Sstevel@tonic-gate 
1007c478bd9Sstevel@tonic-gate 
1017c478bd9Sstevel@tonic-gate /*
1027c478bd9Sstevel@tonic-gate  * USB request completion flags, more than one may be set.
1037c478bd9Sstevel@tonic-gate  * The following flags are returned after a recovery action by
1047c478bd9Sstevel@tonic-gate  * HCD or USBA (autoclearing) or callbacks from pipe_close,
1057c478bd9Sstevel@tonic-gate  * abort, reset, or stop polling.  More than one may be set.
1067c478bd9Sstevel@tonic-gate  *
1077c478bd9Sstevel@tonic-gate  * For sync requests, the client should check the request structure
1087c478bd9Sstevel@tonic-gate  * for this flag to determine what has happened.
1097c478bd9Sstevel@tonic-gate  *
1107c478bd9Sstevel@tonic-gate  * All callbacks are queued to preserve order.	Note that if a normal callback
1117c478bd9Sstevel@tonic-gate  * uses a kernel thread, order is not guaranteed since each callback may use
1127c478bd9Sstevel@tonic-gate  * its own thread.  The next request will be submitted to the
1137c478bd9Sstevel@tonic-gate  * HCD after the threads exits.
1147c478bd9Sstevel@tonic-gate  *
1157c478bd9Sstevel@tonic-gate  * Exception callbacks using a kernel thread may do auto clearing and no
1167c478bd9Sstevel@tonic-gate  * new request will be started until this thread has completed its work.
1177c478bd9Sstevel@tonic-gate  */
1187c478bd9Sstevel@tonic-gate typedef enum {
1197c478bd9Sstevel@tonic-gate 	USB_CB_NO_INFO		= 0x00, /* no exception */
1207c478bd9Sstevel@tonic-gate 	USB_CB_STALL_CLEARED	= 0x01,	/* func stall cleared */
1217c478bd9Sstevel@tonic-gate 	USB_CB_FUNCTIONAL_STALL	= 0x02,	/* func stall occurred */
1227c478bd9Sstevel@tonic-gate 	USB_CB_PROTOCOL_STALL	= 0x04,	/* protocal stall occurred */
1237c478bd9Sstevel@tonic-gate 	USB_CB_RESET_PIPE	= 0x10, /* pipe was reset */
1247c478bd9Sstevel@tonic-gate 	USB_CB_ASYNC_REQ_FAILED = 0x80, /* thread couldn't be started */
1257c478bd9Sstevel@tonic-gate 	USB_CB_NO_RESOURCES	= 0x100, /* no resources */
1267c478bd9Sstevel@tonic-gate 	USB_CB_SUBMIT_FAILED	= 0x200, /* req was queued then submitted */
1277c478bd9Sstevel@tonic-gate 					/* to HCD which rejected it */
1287c478bd9Sstevel@tonic-gate 	USB_CB_INTR_CONTEXT	= 0x400 /* Callback is in interrupt context. */
1297c478bd9Sstevel@tonic-gate } usb_cb_flags_t;
1307c478bd9Sstevel@tonic-gate 
1317c478bd9Sstevel@tonic-gate 
1327c478bd9Sstevel@tonic-gate /*
1337c478bd9Sstevel@tonic-gate  * completion reason
1347c478bd9Sstevel@tonic-gate  *
1357c478bd9Sstevel@tonic-gate  * Set by HCD; only one can be set.
1367c478bd9Sstevel@tonic-gate  */
1377c478bd9Sstevel@tonic-gate typedef enum {
1387c478bd9Sstevel@tonic-gate 	USB_CR_OK		= 0,	/* no errors detected		*/
1397c478bd9Sstevel@tonic-gate 	USB_CR_CRC		= 1,	/* crc error detected		*/
1407c478bd9Sstevel@tonic-gate 	USB_CR_BITSTUFFING	= 2,	/* bit stuffing violation	*/
1417c478bd9Sstevel@tonic-gate 	USB_CR_DATA_TOGGLE_MM	= 3,	/* d/t PID did not match	*/
1427c478bd9Sstevel@tonic-gate 	USB_CR_STALL		= 4,	/* e/p returned stall PID	*/
1437c478bd9Sstevel@tonic-gate 	USB_CR_DEV_NOT_RESP	= 5,	/* device not responding	*/
1447c478bd9Sstevel@tonic-gate 	USB_CR_PID_CHECKFAILURE = 6,	/* check bits on PID failed	*/
1457c478bd9Sstevel@tonic-gate 	USB_CR_UNEXP_PID	= 7,	/* receive PID was not valid	*/
1467c478bd9Sstevel@tonic-gate 	USB_CR_DATA_OVERRUN	= 8,	/* data size exceeded		*/
1477c478bd9Sstevel@tonic-gate 	USB_CR_DATA_UNDERRUN	= 9,	/* less data received		*/
1487c478bd9Sstevel@tonic-gate 	USB_CR_BUFFER_OVERRUN	= 10,	/* memory write can't keep up	*/
1497c478bd9Sstevel@tonic-gate 	USB_CR_BUFFER_UNDERRUN	= 11,	/* buffer underrun		*/
1507c478bd9Sstevel@tonic-gate 	USB_CR_TIMEOUT		= 12,	/* command timed out		*/
1517c478bd9Sstevel@tonic-gate 	USB_CR_NOT_ACCESSED	= 13,	/* Not accessed by hardware	*/
1527c478bd9Sstevel@tonic-gate 	USB_CR_NO_RESOURCES	= 14,	/* no resources			*/
1537c478bd9Sstevel@tonic-gate 	USB_CR_UNSPECIFIED_ERR	= 15,	/* unspecified usba or hcd err	*/
1547c478bd9Sstevel@tonic-gate 	USB_CR_STOPPED_POLLING	= 16,	/* intr/isoc IN polling stopped	*/
1557c478bd9Sstevel@tonic-gate 	USB_CR_PIPE_CLOSING	= 17,	/* intr/isoc IN pipe closed	*/
1567c478bd9Sstevel@tonic-gate 	USB_CR_PIPE_RESET	= 18,	/* intr/isoc IN pipe reset	*/
1577c478bd9Sstevel@tonic-gate 	USB_CR_NOT_SUPPORTED	= 19,	/* command not supported	*/
1587c478bd9Sstevel@tonic-gate 	USB_CR_FLUSHED		= 20,	/* this request was flushed	*/
1597c478bd9Sstevel@tonic-gate 	USB_CR_HC_HARDWARE_ERR	= 21	/* usb host controller error	*/
1607c478bd9Sstevel@tonic-gate } usb_cr_t;
1617c478bd9Sstevel@tonic-gate 
1627c478bd9Sstevel@tonic-gate 
1637c478bd9Sstevel@tonic-gate /*
1647c478bd9Sstevel@tonic-gate  * ***************************************************************************
1657c478bd9Sstevel@tonic-gate  * General definitions, used all over
1667c478bd9Sstevel@tonic-gate  * ***************************************************************************
1677c478bd9Sstevel@tonic-gate  *
1687c478bd9Sstevel@tonic-gate  *	A pipe handle is returned by usb_pipe_open() on success for
1697c478bd9Sstevel@tonic-gate  *	all pipes except the default pipe which is accessed from
1707c478bd9Sstevel@tonic-gate  *	the registration structure.  Placed here as forward referenced by
1717c478bd9Sstevel@tonic-gate  *	usb_client_dev_data_t below.
1727c478bd9Sstevel@tonic-gate  *
1737c478bd9Sstevel@tonic-gate  *	The pipe_handle is opaque to the client driver.
1747c478bd9Sstevel@tonic-gate  */
1757c478bd9Sstevel@tonic-gate typedef	struct usb_pipe_handle	*usb_pipe_handle_t;
1767c478bd9Sstevel@tonic-gate 
1777c478bd9Sstevel@tonic-gate /*
1787c478bd9Sstevel@tonic-gate  * General opaque pointer.
1797c478bd9Sstevel@tonic-gate  */
1807c478bd9Sstevel@tonic-gate typedef struct usb_opaque *usb_opaque_t;
1817c478bd9Sstevel@tonic-gate 
1827c478bd9Sstevel@tonic-gate 
1837c478bd9Sstevel@tonic-gate /*
1847c478bd9Sstevel@tonic-gate  * USB flags argument to USBA interfaces
1857c478bd9Sstevel@tonic-gate  */
1867c478bd9Sstevel@tonic-gate typedef enum {
1877c478bd9Sstevel@tonic-gate 	/* do not block until resources are available */
1887c478bd9Sstevel@tonic-gate 	USB_FLAGS_NOSLEEP		= 0x0000,
1897c478bd9Sstevel@tonic-gate 	/* block until resources are available */
1907c478bd9Sstevel@tonic-gate 	USB_FLAGS_SLEEP			= 0x0100,
1917c478bd9Sstevel@tonic-gate 	/* reserved */
1927c478bd9Sstevel@tonic-gate 	USB_FLAGS_RESERVED		= 0xFE00
1937c478bd9Sstevel@tonic-gate } usb_flags_t;
1947c478bd9Sstevel@tonic-gate 
1957c478bd9Sstevel@tonic-gate 
1967c478bd9Sstevel@tonic-gate /*
1977c478bd9Sstevel@tonic-gate  * ***************************************************************************
198993e3fafSRobert Mustacchi  * Descriptor definitions (USB version and section noted with structure)
1997c478bd9Sstevel@tonic-gate  * ***************************************************************************
2007c478bd9Sstevel@tonic-gate  */
2017c478bd9Sstevel@tonic-gate 
2027c478bd9Sstevel@tonic-gate 
2037c478bd9Sstevel@tonic-gate /*
2047c478bd9Sstevel@tonic-gate  * USB Descriptor Management
2057c478bd9Sstevel@tonic-gate  *
2067c478bd9Sstevel@tonic-gate  * Standard USB descriptors:
2077c478bd9Sstevel@tonic-gate  *
2087c478bd9Sstevel@tonic-gate  * USB devices present their configuration information in response to
2097c478bd9Sstevel@tonic-gate  * a GET_DESCRIPTOR request in a form which is little-endian and,
2107c478bd9Sstevel@tonic-gate  * for multibyte integers, unaligned.  It is also position-dependent,
2117c478bd9Sstevel@tonic-gate  * which makes non-sequential access to particular interface or
2127c478bd9Sstevel@tonic-gate  * endpoint data inconvenient.
2137c478bd9Sstevel@tonic-gate  * A GET_DESCRIPTOR request may yield a chunk of data that contains
2147c478bd9Sstevel@tonic-gate  * multiple descriptor types.  For example, a GET_DESCRIPTOR request
2157c478bd9Sstevel@tonic-gate  * for a CONFIGURATION descriptor could return the configuration
2167c478bd9Sstevel@tonic-gate  * descriptor followed by an interface descriptor and the relevant
2177c478bd9Sstevel@tonic-gate  * endpoint descriptors.
2187c478bd9Sstevel@tonic-gate  *
2197c478bd9Sstevel@tonic-gate  * usb_get_dev_data() interface provides an easy way to get all
2207c478bd9Sstevel@tonic-gate  * the descriptors and avoids parsing standard descriptors by each
2217c478bd9Sstevel@tonic-gate  * client driver
2227c478bd9Sstevel@tonic-gate  *
2237c478bd9Sstevel@tonic-gate  * usb_dev_descr:
2247c478bd9Sstevel@tonic-gate  *	usb device descriptor, refer to	USB 2.0/9.6.1,
2257c478bd9Sstevel@tonic-gate  */
2267c478bd9Sstevel@tonic-gate typedef struct usb_dev_descr {
2277c478bd9Sstevel@tonic-gate 	uint8_t		bLength;	/* descriptor size		*/
2287c478bd9Sstevel@tonic-gate 	uint8_t		bDescriptorType; /* set to DEVICE		*/
2297c478bd9Sstevel@tonic-gate 	uint16_t	bcdUSB;		/* USB spec rel. number	in bcd	*/
2307c478bd9Sstevel@tonic-gate 	uint8_t		bDeviceClass;	/* class code			*/
2317c478bd9Sstevel@tonic-gate 	uint8_t		bDeviceSubClass; /* sub	class code		*/
2327c478bd9Sstevel@tonic-gate 	uint8_t		bDeviceProtocol; /* protocol code		*/
2337c478bd9Sstevel@tonic-gate 	uint8_t		bMaxPacketSize0; /* max	pkt size of e/p	0	*/
2347c478bd9Sstevel@tonic-gate 	uint16_t	idVendor;	/* vendor ID			*/
2357c478bd9Sstevel@tonic-gate 	uint16_t	idProduct;	/* product ID			*/
2367c478bd9Sstevel@tonic-gate 	uint16_t	bcdDevice;	/* device release number in bcd	*/
2377c478bd9Sstevel@tonic-gate 	uint8_t		iManufacturer;	/* manufacturing string		*/
2387c478bd9Sstevel@tonic-gate 	uint8_t		iProduct;	/* product string		*/
2397c478bd9Sstevel@tonic-gate 	uint8_t		iSerialNumber;	/* serial number string index	*/
2407c478bd9Sstevel@tonic-gate 	uint8_t		bNumConfigurations; /* #configs for device	*/
2417c478bd9Sstevel@tonic-gate } usb_dev_descr_t;
2427c478bd9Sstevel@tonic-gate 
2437c478bd9Sstevel@tonic-gate 
2447c478bd9Sstevel@tonic-gate /*
2457c478bd9Sstevel@tonic-gate  * USB Device Qualifier Descriptor
2467c478bd9Sstevel@tonic-gate  *
2477c478bd9Sstevel@tonic-gate  * The device_qualifier descriptor describes information about a High
2487c478bd9Sstevel@tonic-gate  * speed capable device that would change if the device were operating
2497c478bd9Sstevel@tonic-gate  * at other (Full) speed. Example: if the device is currently operating
2507c478bd9Sstevel@tonic-gate  * at Full-speed, the device_qualifier returns information about how if
2517c478bd9Sstevel@tonic-gate  * would operate at high-speed and vice-versa.
2527c478bd9Sstevel@tonic-gate  *
2537c478bd9Sstevel@tonic-gate  * usb_dev_qlf_descr:
2547c478bd9Sstevel@tonic-gate  *
2557c478bd9Sstevel@tonic-gate  *	usb device qualifier descriptor, refer to USB 2.0/9.6.2
2567c478bd9Sstevel@tonic-gate  */
2577c478bd9Sstevel@tonic-gate typedef struct usb_dev_qlf_descr {
2587c478bd9Sstevel@tonic-gate 	uint8_t		bLength;	/* descriptor size		*/
2597c478bd9Sstevel@tonic-gate 	uint8_t		bDescriptorType; /* set to DEVICE		*/
2607c478bd9Sstevel@tonic-gate 	uint16_t	bcdUSB;		/* USB spec rel. number	in bcd	*/
2617c478bd9Sstevel@tonic-gate 	uint8_t		bDeviceClass;	/* class code			*/
2627c478bd9Sstevel@tonic-gate 	uint8_t		bDeviceSubClass; /* sub	class code		*/
2637c478bd9Sstevel@tonic-gate 	uint8_t		bDeviceProtocol; /* protocol code		*/
2647c478bd9Sstevel@tonic-gate 	uint8_t		bMaxPacketSize0; /* max	pkt size of e/p	0	*/
2657c478bd9Sstevel@tonic-gate 	uint8_t		bNumConfigurations; /* #configs for device	*/
2667c478bd9Sstevel@tonic-gate 	uint8_t		bReserved;	/* reserved field		*/
2677c478bd9Sstevel@tonic-gate } usb_dev_qlf_descr_t;
2687c478bd9Sstevel@tonic-gate 
2697c478bd9Sstevel@tonic-gate 
2707c478bd9Sstevel@tonic-gate /*
2717c478bd9Sstevel@tonic-gate  * usb_cfg_descr:
2727c478bd9Sstevel@tonic-gate  *	usb configuration descriptor, refer to USB 2.0/9.6.3
2737c478bd9Sstevel@tonic-gate  */
2747c478bd9Sstevel@tonic-gate typedef struct usb_cfg_descr {
2757c478bd9Sstevel@tonic-gate 	uint8_t		bLength;	/* descriptor size		*/
2767c478bd9Sstevel@tonic-gate 	uint8_t		bDescriptorType; /* set to CONFIGURATION	*/
2777c478bd9Sstevel@tonic-gate 	uint16_t	wTotalLength;	/* total length of data returned */
2787c478bd9Sstevel@tonic-gate 	uint8_t		bNumInterfaces;	/* # interfaces	in config	*/
2797c478bd9Sstevel@tonic-gate 	uint8_t		bConfigurationValue; /* arg for SetConfiguration */
2807c478bd9Sstevel@tonic-gate 	uint8_t		iConfiguration;	/* configuration string		*/
2817c478bd9Sstevel@tonic-gate 	uint8_t		bmAttributes;	/* config characteristics	*/
2827c478bd9Sstevel@tonic-gate 	uint8_t		bMaxPower;	/* max pwr consumption		*/
2837c478bd9Sstevel@tonic-gate } usb_cfg_descr_t;
2847c478bd9Sstevel@tonic-gate 
2857c478bd9Sstevel@tonic-gate /*
2867c478bd9Sstevel@tonic-gate  * Default configuration index setting for devices with multiple
2877c478bd9Sstevel@tonic-gate  * configurations. Note the distinction between config index and config
2887c478bd9Sstevel@tonic-gate  * number
2897c478bd9Sstevel@tonic-gate  */
2907c478bd9Sstevel@tonic-gate #define	USB_DEV_DEFAULT_CONFIG_INDEX	0
2917c478bd9Sstevel@tonic-gate 
2927c478bd9Sstevel@tonic-gate /*
2937c478bd9Sstevel@tonic-gate  * bmAttribute values for Configuration Descriptor
2947c478bd9Sstevel@tonic-gate  */
2957c478bd9Sstevel@tonic-gate #define	USB_CFG_ATTR_SELFPWR		0x40
2967c478bd9Sstevel@tonic-gate #define	USB_CFG_ATTR_REMOTE_WAKEUP	0x20
297ff0e937bSRaymond Chen #define	USB_CFG_ATTR_BAT_PWR		0x10
2987c478bd9Sstevel@tonic-gate 
2997c478bd9Sstevel@tonic-gate /*
3007c478bd9Sstevel@tonic-gate  * USB Other Speed Configuration Descriptor
3017c478bd9Sstevel@tonic-gate  *
3027c478bd9Sstevel@tonic-gate  * The other_speed_configuration descriptor describes a configuration of
3037c478bd9Sstevel@tonic-gate  * a High speed capable device if it were operating at its other possible
3047c478bd9Sstevel@tonic-gate  * (Full) speed and vice-versa.
3057c478bd9Sstevel@tonic-gate  *
3067c478bd9Sstevel@tonic-gate  * usb_other_speed_cfg_descr:
3077c478bd9Sstevel@tonic-gate  *	usb other speed configuration descriptor, refer to USB 2.0/9.6.4
3087c478bd9Sstevel@tonic-gate  */
3097c478bd9Sstevel@tonic-gate typedef struct usb_other_speed_cfg_descr {
3107c478bd9Sstevel@tonic-gate 	uint8_t		bLength;	/* descriptor size		*/
3117c478bd9Sstevel@tonic-gate 	uint8_t		bDescriptorType; /* set to CONFIGURATION	*/
3127c478bd9Sstevel@tonic-gate 	uint16_t	wTotalLength;	/* total length of data returned */
3137c478bd9Sstevel@tonic-gate 	uint8_t		bNumInterfaces;	/* # interfaces	in config	*/
3147c478bd9Sstevel@tonic-gate 	uint8_t		bConfigurationValue; /* arg for SetConfiguration */
3157c478bd9Sstevel@tonic-gate 	uint8_t		iConfiguration;	/* configuration string		*/
3167c478bd9Sstevel@tonic-gate 	uint8_t		bmAttributes;	/* config characteristics	*/
3177c478bd9Sstevel@tonic-gate 	uint8_t		bMaxPower;	/* max pwr consumption		*/
3187c478bd9Sstevel@tonic-gate } usb_other_speed_cfg_descr_t;
3197c478bd9Sstevel@tonic-gate 
3207c478bd9Sstevel@tonic-gate 
321d73ae94eSgc /*
322d73ae94eSgc  * usb_ia_descr:
323d73ae94eSgc  *	usb interface association descriptor, refer to USB 2.0 ECN(IAD)
324d73ae94eSgc  */
325d73ae94eSgc typedef  struct usb_ia_descr {
326d73ae94eSgc 	uint8_t		bLength;		/* descriptor size	*/
327d73ae94eSgc 	uint8_t		bDescriptorType;	/* INTERFACE_ASSOCIATION */
328d73ae94eSgc 	uint8_t		bFirstInterface;	/* 1st interface number */
329d73ae94eSgc 	uint8_t		bInterfaceCount;	/* number of interfaces */
330d73ae94eSgc 	uint8_t		bFunctionClass;		/* class code		*/
331d73ae94eSgc 	uint8_t		bFunctionSubClass;	/* sub class code	*/
332d73ae94eSgc 	uint8_t		bFunctionProtocol;	/* protocol code	*/
333d73ae94eSgc 	uint8_t		iFunction;		/* description string	*/
334d73ae94eSgc } usb_ia_descr_t;
335d73ae94eSgc 
336d73ae94eSgc 
3377c478bd9Sstevel@tonic-gate /*
3387c478bd9Sstevel@tonic-gate  * usb_if_descr:
3397c478bd9Sstevel@tonic-gate  *	usb interface descriptor, refer	to USB 2.0/9.6.5
3407c478bd9Sstevel@tonic-gate  */
3417c478bd9Sstevel@tonic-gate typedef  struct usb_if_descr {
3427c478bd9Sstevel@tonic-gate 	uint8_t		bLength;		/* descriptor size	*/
3437c478bd9Sstevel@tonic-gate 	uint8_t		bDescriptorType;	/* set to INTERFACE	*/
3447c478bd9Sstevel@tonic-gate 	uint8_t		bInterfaceNumber;	/* interface number	*/
3457c478bd9Sstevel@tonic-gate 	uint8_t		bAlternateSetting;	/* alt. interface number */
3467c478bd9Sstevel@tonic-gate 	uint8_t		bNumEndpoints;		/* # of endpoints	*/
3477c478bd9Sstevel@tonic-gate 	uint8_t		bInterfaceClass;	/* class code		*/
3487c478bd9Sstevel@tonic-gate 	uint8_t		bInterfaceSubClass;	/* sub class code	*/
3497c478bd9Sstevel@tonic-gate 	uint8_t		bInterfaceProtocol;	/* protocol code	*/
3507c478bd9Sstevel@tonic-gate 	uint8_t		iInterface;		/* description string	*/
3517c478bd9Sstevel@tonic-gate } usb_if_descr_t;
3527c478bd9Sstevel@tonic-gate 
3537c478bd9Sstevel@tonic-gate 
3547c478bd9Sstevel@tonic-gate /*
3557c478bd9Sstevel@tonic-gate  * usb_ep_descr:
3567c478bd9Sstevel@tonic-gate  *	usb endpoint descriptor, refer to USB 2.0/9.6.6
3577c478bd9Sstevel@tonic-gate  */
3587c478bd9Sstevel@tonic-gate typedef struct usb_ep_descr {
3597c478bd9Sstevel@tonic-gate 	uint8_t		bLength;		/* descriptor size	*/
3607c478bd9Sstevel@tonic-gate 	uint8_t		bDescriptorType;	/* set to ENDPOINT	*/
3617c478bd9Sstevel@tonic-gate 	uint8_t		bEndpointAddress;	/* address of this e/p */
3627c478bd9Sstevel@tonic-gate 	uint8_t		bmAttributes;		/* transfer type	*/
3637c478bd9Sstevel@tonic-gate 	uint16_t	wMaxPacketSize;		/* maximum packet size	*/
3647c478bd9Sstevel@tonic-gate 	uint8_t		bInterval;		/* e/p polling interval */
3657c478bd9Sstevel@tonic-gate } usb_ep_descr_t;
3667c478bd9Sstevel@tonic-gate 
3677c478bd9Sstevel@tonic-gate /*
3687c478bd9Sstevel@tonic-gate  * bEndpointAddress masks
3697c478bd9Sstevel@tonic-gate  */
3707c478bd9Sstevel@tonic-gate #define	USB_EP_NUM_MASK		0x0F		/* endpoint number mask */
3717c478bd9Sstevel@tonic-gate #define	USB_EP_DIR_MASK		0x80		/* direction mask */
3727c478bd9Sstevel@tonic-gate #define	USB_EP_DIR_OUT		0x00		/* OUT endpoint */
3737c478bd9Sstevel@tonic-gate #define	USB_EP_DIR_IN		0x80		/* IN endpoint */
3747c478bd9Sstevel@tonic-gate 
3757c478bd9Sstevel@tonic-gate /*
3767c478bd9Sstevel@tonic-gate  * bmAttribute transfer types for endpoints
3777c478bd9Sstevel@tonic-gate  */
3787c478bd9Sstevel@tonic-gate #define	USB_EP_ATTR_MASK	0x03		/* transfer type mask */
3797c478bd9Sstevel@tonic-gate #define	USB_EP_ATTR_CONTROL	0x00		/* control transfer */
3807c478bd9Sstevel@tonic-gate #define	USB_EP_ATTR_ISOCH	0x01		/* isochronous transfer */
3817c478bd9Sstevel@tonic-gate #define	USB_EP_ATTR_BULK	0x02		/* bulk transfer */
3827c478bd9Sstevel@tonic-gate #define	USB_EP_ATTR_INTR	0x03		/* interrupt transfer */
3837c478bd9Sstevel@tonic-gate 
3847c478bd9Sstevel@tonic-gate /*
3857c478bd9Sstevel@tonic-gate  * bmAttribute synchronization types for endpoints (isochronous only)
3867c478bd9Sstevel@tonic-gate  */
3877c478bd9Sstevel@tonic-gate #define	USB_EP_SYNC_MASK	0x0C		/* synchronization mask */
3887c478bd9Sstevel@tonic-gate #define	USB_EP_SYNC_NONE	0x00		/* no synchronization */
3897c478bd9Sstevel@tonic-gate #define	USB_EP_SYNC_ASYNC	0x04		/* asynchronous */
3907c478bd9Sstevel@tonic-gate #define	USB_EP_SYNC_ADPT	0x08		/* adaptive */
3917c478bd9Sstevel@tonic-gate #define	USB_EP_SYNC_SYNC	0x0C		/* synchronous */
3927c478bd9Sstevel@tonic-gate 
3937c478bd9Sstevel@tonic-gate /*
3947c478bd9Sstevel@tonic-gate  * bmAttribute synchronization feedback types for endpoints (isochronous only)
3957c478bd9Sstevel@tonic-gate  */
3967c478bd9Sstevel@tonic-gate #define	USB_EP_USAGE_MASK	0x30		/* sync feedback mask */
3977c478bd9Sstevel@tonic-gate #define	USB_EP_USAGE_DATA	0x00		/* data endpoint */
3987c478bd9Sstevel@tonic-gate #define	USB_EP_USAGE_FEED	0x10		/* feedback endpoint */
3997c478bd9Sstevel@tonic-gate #define	USB_EP_USAGE_IMPL	0x20		/* implicit feedback endpoint */
4007c478bd9Sstevel@tonic-gate 
4017c478bd9Sstevel@tonic-gate /*
4027c478bd9Sstevel@tonic-gate  * wMaxPacketSize values for endpoints (isoch and interrupt, high speed only)
4037c478bd9Sstevel@tonic-gate  */
404993e3fafSRobert Mustacchi #define	USB_EP_MAX_PKTSZ_MASK	0x07FF		/* Mask for packetsize bits */
405993e3fafSRobert Mustacchi #define	USB_EP_MAX_XACTS_MASK	0x1800		/* Max Transactns/microframe */
406993e3fafSRobert Mustacchi #define	USB_EP_MAX_XACTS_SHIFT	11		/* Above is 10 bits from end */
4077c478bd9Sstevel@tonic-gate 
4087c478bd9Sstevel@tonic-gate /*
4097c478bd9Sstevel@tonic-gate  * Ranges for endpoint parameter values.
4107c478bd9Sstevel@tonic-gate  */
4117c478bd9Sstevel@tonic-gate 
4127c478bd9Sstevel@tonic-gate /* Min and Max NAK rates for high sped control endpoints. */
4137c478bd9Sstevel@tonic-gate #define	USB_EP_MIN_HIGH_CONTROL_INTRVL	0
4147c478bd9Sstevel@tonic-gate #define	USB_EP_MAX_HIGH_CONTROL_INTRVL	255
4157c478bd9Sstevel@tonic-gate 
4167c478bd9Sstevel@tonic-gate /* Min and Max NAK rates for high speed bulk endpoints. */
4177c478bd9Sstevel@tonic-gate #define	USB_EP_MIN_HIGH_BULK_INTRVL	0
4187c478bd9Sstevel@tonic-gate #define	USB_EP_MAX_HIGH_BULK_INTRVL	255
4197c478bd9Sstevel@tonic-gate 
4207c478bd9Sstevel@tonic-gate /* Min and Max polling intervals for low, full speed interrupt endpoints. */
4217c478bd9Sstevel@tonic-gate #define	USB_EP_MIN_LOW_INTR_INTRVL	1
4227c478bd9Sstevel@tonic-gate #define	USB_EP_MAX_LOW_INTR_INTRVL	255
4237c478bd9Sstevel@tonic-gate #define	USB_EP_MIN_FULL_INTR_INTRVL	1
4247c478bd9Sstevel@tonic-gate #define	USB_EP_MAX_FULL_INTR_INTRVL	255
4257c478bd9Sstevel@tonic-gate 
4267c478bd9Sstevel@tonic-gate /*
4277c478bd9Sstevel@tonic-gate  * Min and Max polling intervals for high speed interrupt endpoints, and for
4287c478bd9Sstevel@tonic-gate  * isochronous endpoints.
4297c478bd9Sstevel@tonic-gate  * Note that the interval is 2**(value-1).  See Section 9.6.6 of USB 2.0 spec.
4307c478bd9Sstevel@tonic-gate  */
4317c478bd9Sstevel@tonic-gate #define	USB_EP_MIN_HIGH_INTR_INTRVL	1
4327c478bd9Sstevel@tonic-gate #define	USB_EP_MAX_HIGH_INTR_INTRVL	16
4337c478bd9Sstevel@tonic-gate #define	USB_EP_MIN_FULL_ISOCH_INTRVL	1
4347c478bd9Sstevel@tonic-gate #define	USB_EP_MAX_FULL_ISOCH_INTRVL	16
4357c478bd9Sstevel@tonic-gate #define	USB_EP_MIN_HIGH_ISOCH_INTRVL	1
4367c478bd9Sstevel@tonic-gate #define	USB_EP_MAX_HIGH_ISOCH_INTRVL	16
4377c478bd9Sstevel@tonic-gate 
4387c478bd9Sstevel@tonic-gate /*
4397c478bd9Sstevel@tonic-gate  * usb_string_descr:
4407c478bd9Sstevel@tonic-gate  *	usb string descriptor, refer to	 USB 2.0/9.6.7
4417c478bd9Sstevel@tonic-gate  */
4427c478bd9Sstevel@tonic-gate typedef struct usb_string_descr {
4437c478bd9Sstevel@tonic-gate 	uint8_t		bLength;		/* descr size */
4447c478bd9Sstevel@tonic-gate 	uint8_t		bDescriptorType;	/* set to STRING */
4457c478bd9Sstevel@tonic-gate 	uint8_t		bString[1];		/* variable length unicode */
4467c478bd9Sstevel@tonic-gate 						/* encoded string	*/
4477c478bd9Sstevel@tonic-gate } usb_string_descr_t;
4487c478bd9Sstevel@tonic-gate 
4497c478bd9Sstevel@tonic-gate #define	USB_MAXSTRINGLEN	255		/* max string descr length */
4507c478bd9Sstevel@tonic-gate 
451993e3fafSRobert Mustacchi /*
452993e3fafSRobert Mustacchi  * usb_ep_ss_comp_descr:
453993e3fafSRobert Mustacchi  * 	USB SuperSpeed endpoints are required to return this descriptor along
454993e3fafSRobert Mustacchi  * 	with the general endpoint descriptor. Refer to USB 3.1/9.6.7.
455993e3fafSRobert Mustacchi  */
456993e3fafSRobert Mustacchi typedef struct usb_ep_ss_comp_descr {
457993e3fafSRobert Mustacchi 	uint8_t		bLength;		/* descriptor size */
458993e3fafSRobert Mustacchi 	uint8_t		bDescriptorType;	/* USB_DESCR_TYPE_SS_EP_COMP */
459993e3fafSRobert Mustacchi 	uint8_t		bMaxBurst;		/* max packets per burst */
460993e3fafSRobert Mustacchi 	uint8_t		bmAttributes;		/* more endpoint attributes */
461993e3fafSRobert Mustacchi 	uint16_t	wBytesPerInterval;	/* bytes per service interval */
462993e3fafSRobert Mustacchi } usb_ep_ss_comp_descr_t;
463993e3fafSRobert Mustacchi 
464993e3fafSRobert Mustacchi #define	USB_EP_SS_COMP_ISOC_MULT_MASK	0x03
465993e3fafSRobert Mustacchi 
4667c478bd9Sstevel@tonic-gate /*
4677c478bd9Sstevel@tonic-gate  * ***************************************************************************
4687c478bd9Sstevel@tonic-gate  * Client driver registration with USBA
4697c478bd9Sstevel@tonic-gate  * ***************************************************************************
4707c478bd9Sstevel@tonic-gate  *
4717c478bd9Sstevel@tonic-gate  *	The client registers with USBA during attach in two steps
4727c478bd9Sstevel@tonic-gate  *	using usb_client_attach() and usb_get_dev_data(). On completion, the
4737c478bd9Sstevel@tonic-gate  *	registration data has been initialized.  Most data items are
4747c478bd9Sstevel@tonic-gate  *	straightforward.  Among the items returned in the data is the tree of
4757c478bd9Sstevel@tonic-gate  *	parsed descriptors, in dev_cfg;	 the number of configurations parsed,
4767c478bd9Sstevel@tonic-gate  *	in dev_n_cfg; a pointer to the current configuration in the tree,
4777c478bd9Sstevel@tonic-gate  *	in dev_curr_cfg; the index of the first valid interface in the
4787c478bd9Sstevel@tonic-gate  *	tree, in dev_curr_if, and a parse level that accurately reflects what
4797c478bd9Sstevel@tonic-gate  *	is in the tree, in dev_parse_level.
4807c478bd9Sstevel@tonic-gate  */
4817c478bd9Sstevel@tonic-gate 
4827c478bd9Sstevel@tonic-gate 
4837c478bd9Sstevel@tonic-gate /*
4847c478bd9Sstevel@tonic-gate  * ***************************************************************************
4857c478bd9Sstevel@tonic-gate  * Data structures used in the configuration tree
4867c478bd9Sstevel@tonic-gate  * ***************************************************************************
4877c478bd9Sstevel@tonic-gate  */
4887c478bd9Sstevel@tonic-gate 
4897c478bd9Sstevel@tonic-gate /*
4907c478bd9Sstevel@tonic-gate  * Tree data structure for each configuration in the tree
4917c478bd9Sstevel@tonic-gate  */
4927c478bd9Sstevel@tonic-gate typedef struct usb_cfg_data {
4937c478bd9Sstevel@tonic-gate 	struct usb_cfg_descr	cfg_descr;	/* parsed config descr */
4947c478bd9Sstevel@tonic-gate 	struct usb_if_data	*cfg_if;	/* interfaces for this cfg */
4957c478bd9Sstevel@tonic-gate 						/* indexed by interface num */
4967c478bd9Sstevel@tonic-gate 	struct usb_cvs_data	*cfg_cvs;	/* class/vendor specific */
4977c478bd9Sstevel@tonic-gate 						/* descrs mod/extend cfg */
4987c478bd9Sstevel@tonic-gate 	char			*cfg_str;	/* string descriptor */
4997c478bd9Sstevel@tonic-gate 	uint_t			cfg_n_if;	/* #elements in cfg_if[] */
5007c478bd9Sstevel@tonic-gate 	uint_t			cfg_n_cvs;	/* #elements in cfg_cvs[] */
5017c478bd9Sstevel@tonic-gate 	uint_t			cfg_strsize;	/* size of string descr */
5027c478bd9Sstevel@tonic-gate } usb_cfg_data_t;
5037c478bd9Sstevel@tonic-gate 
5047c478bd9Sstevel@tonic-gate 
5057c478bd9Sstevel@tonic-gate /*
5067c478bd9Sstevel@tonic-gate  * Tree data structure for each alternate interface set
5077c478bd9Sstevel@tonic-gate  * in each represented configuration
5087c478bd9Sstevel@tonic-gate  */
5097c478bd9Sstevel@tonic-gate typedef struct usb_if_data {
5107c478bd9Sstevel@tonic-gate 	struct usb_alt_if_data	*if_alt;	/* sparse array of alts */
5117c478bd9Sstevel@tonic-gate 						/* indexed by alt setting */
5127c478bd9Sstevel@tonic-gate 	uint_t			if_n_alt;	/* #elements in if_alt[] */
5137c478bd9Sstevel@tonic-gate } usb_if_data_t;
5147c478bd9Sstevel@tonic-gate 
5157c478bd9Sstevel@tonic-gate 
5167c478bd9Sstevel@tonic-gate /*
5177c478bd9Sstevel@tonic-gate  * Tree data structure for each alternate of each alternate interface set
5187c478bd9Sstevel@tonic-gate  */
5197c478bd9Sstevel@tonic-gate typedef struct usb_alt_if_data {
5207c478bd9Sstevel@tonic-gate 	usb_if_descr_t		altif_descr;	/* parsed alternate if descr */
5217c478bd9Sstevel@tonic-gate 	struct usb_ep_data	*altif_ep;	/* endpts for alt if */
5227c478bd9Sstevel@tonic-gate 						/* (not a sparse array */
5237c478bd9Sstevel@tonic-gate 	struct usb_cvs_data	*altif_cvs;	/* cvs for this alt if */
5247c478bd9Sstevel@tonic-gate 	char			*altif_str;	/* string descriptor */
5257c478bd9Sstevel@tonic-gate 	uint_t			altif_n_ep;	/* #elements in altif_ep[] */
5267c478bd9Sstevel@tonic-gate 	uint_t			altif_n_cvs;	/* #elements in  altif_cvs[] */
5277c478bd9Sstevel@tonic-gate 	uint_t			altif_strsize;	/* size of string descr */
5287c478bd9Sstevel@tonic-gate } usb_alt_if_data_t;
5297c478bd9Sstevel@tonic-gate 
5307c478bd9Sstevel@tonic-gate 
5317c478bd9Sstevel@tonic-gate /*
5327c478bd9Sstevel@tonic-gate  * Tree data structure for each endpoint of each alternate
5337c478bd9Sstevel@tonic-gate  */
5347c478bd9Sstevel@tonic-gate typedef struct usb_ep_data {
5357c478bd9Sstevel@tonic-gate 	usb_ep_descr_t		ep_descr;	/* endpoint descriptor */
5367c478bd9Sstevel@tonic-gate 	struct usb_cvs_data	*ep_cvs;	/* cv mod/extending this ep */
5377c478bd9Sstevel@tonic-gate 	uint_t			ep_n_cvs;	/* #elements in ep_cvs[] */
538993e3fafSRobert Mustacchi 	boolean_t		ep_ss_valid;
539993e3fafSRobert Mustacchi 	usb_ep_ss_comp_descr_t	ep_ss_comp;	/* superspeed ep desc */
5407c478bd9Sstevel@tonic-gate } usb_ep_data_t;
5417c478bd9Sstevel@tonic-gate 
5427c478bd9Sstevel@tonic-gate 
5437c478bd9Sstevel@tonic-gate /*
5447c478bd9Sstevel@tonic-gate  * Tree data structure for each class/vendor specific descriptor
5457c478bd9Sstevel@tonic-gate  */
5467c478bd9Sstevel@tonic-gate typedef struct usb_cvs_data {
5477c478bd9Sstevel@tonic-gate 	uchar_t			*cvs_buf;	/* raw data of cvs descr */
5487c478bd9Sstevel@tonic-gate 	uint_t			cvs_buf_len;	/* cvs_buf size */
5497c478bd9Sstevel@tonic-gate } usb_cvs_data_t;
5507c478bd9Sstevel@tonic-gate 
5517c478bd9Sstevel@tonic-gate 
5527c478bd9Sstevel@tonic-gate /*
5537c478bd9Sstevel@tonic-gate  *	Parse_level determines the extent to which the tree is built, the amount
5547c478bd9Sstevel@tonic-gate  *	of parsing usb_client_attach() is to do.  It has the following values:
5557c478bd9Sstevel@tonic-gate  *
5567c478bd9Sstevel@tonic-gate  *	USB_PARSE_LVL_NONE - Build no tree.  dev_n_cfg will return 0, dev_cfg
5577c478bd9Sstevel@tonic-gate  *			     will return NULL, the dev_curr_xxx fields will be
5587c478bd9Sstevel@tonic-gate  *			     invalid.
5597c478bd9Sstevel@tonic-gate  *	USB_PARSE_LVL_IF   - Parse configured interface only, if configuration#
5607c478bd9Sstevel@tonic-gate  *			     and interface properties are set (as when different
5617c478bd9Sstevel@tonic-gate  *			     interfaces are viewed by the OS as different device
5627c478bd9Sstevel@tonic-gate  *			     instances). If an OS device instance is set up to
5637c478bd9Sstevel@tonic-gate  *			     represent an entire physical device, this works
5647c478bd9Sstevel@tonic-gate  *			     like USB_PARSE_LVL_ALL.
5657c478bd9Sstevel@tonic-gate  *	USB_PARSE_LVL_CFG  - Parse entire configuration of configured interface
5667c478bd9Sstevel@tonic-gate  *			     only.  This is like USB_PARSE_LVL_IF except entire
5677c478bd9Sstevel@tonic-gate  *			     configuration is returned.
5687c478bd9Sstevel@tonic-gate  *	USB_PARSE_LVL_ALL  - Parse entire device (all configurations), even
5697c478bd9Sstevel@tonic-gate  *			     when driver is bound to a single interface of a
5707c478bd9Sstevel@tonic-gate  *			     single configuration.
5717c478bd9Sstevel@tonic-gate  */
5727c478bd9Sstevel@tonic-gate typedef enum {
5737c478bd9Sstevel@tonic-gate 	USB_PARSE_LVL_NONE		= 0,
5747c478bd9Sstevel@tonic-gate 	USB_PARSE_LVL_IF		= 1,
5757c478bd9Sstevel@tonic-gate 	USB_PARSE_LVL_CFG		= 2,
5767c478bd9Sstevel@tonic-gate 	USB_PARSE_LVL_ALL		= 3
5777c478bd9Sstevel@tonic-gate } usb_reg_parse_lvl_t;
5787c478bd9Sstevel@tonic-gate 
5797c478bd9Sstevel@tonic-gate 
5807c478bd9Sstevel@tonic-gate /*
5817c478bd9Sstevel@tonic-gate  * Registration data returned by usb_get_dev_data().  Configuration tree roots
5827c478bd9Sstevel@tonic-gate  * are returned in dev_cfg array.
5837c478bd9Sstevel@tonic-gate  */
5847c478bd9Sstevel@tonic-gate typedef struct usb_client_dev_data {
5857c478bd9Sstevel@tonic-gate 	usb_pipe_handle_t	dev_default_ph;	/* default pipe handle */
5867c478bd9Sstevel@tonic-gate 	ddi_iblock_cookie_t	dev_iblock_cookie; /* for mutex_init's */
5877c478bd9Sstevel@tonic-gate 	struct usb_dev_descr	*dev_descr;	/* cooked device descriptor */
5887c478bd9Sstevel@tonic-gate 	char			*dev_mfg;	/* manufacturing ID */
5897c478bd9Sstevel@tonic-gate 	char			*dev_product;	/* product ID */
5907c478bd9Sstevel@tonic-gate 	char			*dev_serial;	/* serial number */
5917c478bd9Sstevel@tonic-gate 	usb_reg_parse_lvl_t	dev_parse_level; /* USB_PARSE_LVL_* flag */
5927c478bd9Sstevel@tonic-gate 	struct usb_cfg_data	*dev_cfg;	/* configs for this device */
5937c478bd9Sstevel@tonic-gate 						/* indexed by config index */
5947c478bd9Sstevel@tonic-gate 	uint_t			dev_n_cfg;	/* #elements in dev_cfg[] */
5957c478bd9Sstevel@tonic-gate 	struct usb_cfg_data	*dev_curr_cfg;	/* current cfg */
5967c478bd9Sstevel@tonic-gate 	int			dev_curr_if;	/* current interface number */
5977c478bd9Sstevel@tonic-gate } usb_client_dev_data_t;
5987c478bd9Sstevel@tonic-gate 
5997c478bd9Sstevel@tonic-gate 
6007c478bd9Sstevel@tonic-gate /*
6017c478bd9Sstevel@tonic-gate  * ***************************************************************************
6027c478bd9Sstevel@tonic-gate  * Device configuration descriptor tree functions
6037c478bd9Sstevel@tonic-gate  * ***************************************************************************
6047c478bd9Sstevel@tonic-gate  */
6057c478bd9Sstevel@tonic-gate 
6067c478bd9Sstevel@tonic-gate /*
6077c478bd9Sstevel@tonic-gate  * usb_get_dev_data:
6087c478bd9Sstevel@tonic-gate  *	returns initialized registration data. 	Most data items are clear.
6097c478bd9Sstevel@tonic-gate  *	Among the items returned is the tree ofparsed descriptors in dev_cfg;
6107c478bd9Sstevel@tonic-gate  *	and the number of configurations parsed in dev_n_cfg.
6117c478bd9Sstevel@tonic-gate  *
6127c478bd9Sstevel@tonic-gate  * Arguments:
6137c478bd9Sstevel@tonic-gate  *	dip		- pointer to devinfo node of the client
6147c478bd9Sstevel@tonic-gate  *	dev_data	- return registration data at this address
6157c478bd9Sstevel@tonic-gate  *	parse_level	- See above
6167c478bd9Sstevel@tonic-gate  *	flags		- None used
6177c478bd9Sstevel@tonic-gate  *
6187c478bd9Sstevel@tonic-gate  * Return Values:
6197c478bd9Sstevel@tonic-gate  *	USB_SUCCESS		- usb_register_client succeeded
6207c478bd9Sstevel@tonic-gate  *	USB_INVALID_ARGS	- received null dip or reg argument
6217c478bd9Sstevel@tonic-gate  *	USB_INVALID_CONTEXT	- called with sleep from callback context
6227c478bd9Sstevel@tonic-gate  *	USB_FAILURE		- bad descriptor info or other internal failure
6237c478bd9Sstevel@tonic-gate  *
6247c478bd9Sstevel@tonic-gate  * Notes:
6257c478bd9Sstevel@tonic-gate  * 	1) The non-standard USB descriptors are returned in RAW format.
6267c478bd9Sstevel@tonic-gate  *
6277c478bd9Sstevel@tonic-gate  *	2) The registration data is unshared. Each client receives its own copy.
6287c478bd9Sstevel@tonic-gate  *	(The default control pipe may be shared, even though its tree
6297c478bd9Sstevel@tonic-gate  *	description will be unique per device.)
6307c478bd9Sstevel@tonic-gate  *
6317c478bd9Sstevel@tonic-gate  */
6327c478bd9Sstevel@tonic-gate int usb_get_dev_data(
6337c478bd9Sstevel@tonic-gate 	dev_info_t			*dip,
6347c478bd9Sstevel@tonic-gate 	usb_client_dev_data_t		**dev_data,
6357c478bd9Sstevel@tonic-gate 	usb_reg_parse_lvl_t		parse_level,
6367c478bd9Sstevel@tonic-gate 	usb_flags_t			flags);
6377c478bd9Sstevel@tonic-gate 
6387c478bd9Sstevel@tonic-gate /*
6397c478bd9Sstevel@tonic-gate  * usb_free_dev_data:
6407c478bd9Sstevel@tonic-gate  * undoes what usb_get_dev_data() set up.  It releases
6417c478bd9Sstevel@tonic-gate  * memory for all strings, descriptors, and trees set up by usb_get_dev_data().
6427c478bd9Sstevel@tonic-gate  *
6437c478bd9Sstevel@tonic-gate  * Arguments:
6447c478bd9Sstevel@tonic-gate  *	dip		- pointer to devinfo node of the client
6457c478bd9Sstevel@tonic-gate  *	dev_data	- pointer to registration data containing the tree.
6467c478bd9Sstevel@tonic-gate  */
6477c478bd9Sstevel@tonic-gate void usb_free_dev_data(
6487c478bd9Sstevel@tonic-gate 	dev_info_t			*dip,
6497c478bd9Sstevel@tonic-gate 	usb_client_dev_data_t		*dev_data);
6507c478bd9Sstevel@tonic-gate 
6517c478bd9Sstevel@tonic-gate /*
6527c478bd9Sstevel@tonic-gate  * usb_free_descr_tree:
6537c478bd9Sstevel@tonic-gate  *	Take down the configuration tree while leaving the rest	of the
6547c478bd9Sstevel@tonic-gate  *	registration intact.  This can be used, for example, after attach has
6557c478bd9Sstevel@tonic-gate  *	copied any descriptors it needs from the tree, but the rest of the
6567c478bd9Sstevel@tonic-gate  *	registration data needs to remain intact.
6577c478bd9Sstevel@tonic-gate  *
6587c478bd9Sstevel@tonic-gate  *	The following usb_client_dev_data_t fields will be modified:
6597c478bd9Sstevel@tonic-gate  *		dev_cfg will be NULL
6607c478bd9Sstevel@tonic-gate  *		dev_n_cfg will be 0
6617c478bd9Sstevel@tonic-gate  *		dev_curr_cfg_ndx and dev_curr_if will be invalid
6627c478bd9Sstevel@tonic-gate  *		dev_parse_level will be USB_REG_DESCR_NONE
6637c478bd9Sstevel@tonic-gate  *
6647c478bd9Sstevel@tonic-gate  * Arguments:
6657c478bd9Sstevel@tonic-gate  *	dip		- pointer to devinfo node of the client
6667c478bd9Sstevel@tonic-gate  *	dev_data	- pointer to registration data containing the tree.
6677c478bd9Sstevel@tonic-gate  */
6687c478bd9Sstevel@tonic-gate void usb_free_descr_tree(
6697c478bd9Sstevel@tonic-gate 	dev_info_t			*dip,
6707c478bd9Sstevel@tonic-gate 	usb_client_dev_data_t		*dev_data);
6717c478bd9Sstevel@tonic-gate 
6727c478bd9Sstevel@tonic-gate 
6737c478bd9Sstevel@tonic-gate /*
6747c478bd9Sstevel@tonic-gate  * usb_print_descr_tree:
6757c478bd9Sstevel@tonic-gate  *	Dump to the screen a descriptor tree as returned by
6767c478bd9Sstevel@tonic-gate  *	usbai_register_client.
6777c478bd9Sstevel@tonic-gate  *
6787c478bd9Sstevel@tonic-gate  * Arguments:
6797c478bd9Sstevel@tonic-gate  *	dip		- pointer to devinfo of the client
6807c478bd9Sstevel@tonic-gate  *	dev_data	- pointer to registration area containing the tree
6817c478bd9Sstevel@tonic-gate  *
6827c478bd9Sstevel@tonic-gate  * Returns:
6837c478bd9Sstevel@tonic-gate  *	USB_SUCCESS		- tree successfully dumped
6847c478bd9Sstevel@tonic-gate  *	USB_INVALID_CONTEXT	- called from callback context
6857c478bd9Sstevel@tonic-gate  *	USB_INVALID_ARGS	- bad arguments given
6867c478bd9Sstevel@tonic-gate  */
6877c478bd9Sstevel@tonic-gate int usb_print_descr_tree(
6887c478bd9Sstevel@tonic-gate 	dev_info_t		*dip,
6897c478bd9Sstevel@tonic-gate 	usb_client_dev_data_t	*dev_data);
6907c478bd9Sstevel@tonic-gate 
6917c478bd9Sstevel@tonic-gate 
6927c478bd9Sstevel@tonic-gate /*
6937c478bd9Sstevel@tonic-gate  * ***************************************************************************
6947c478bd9Sstevel@tonic-gate  * Registration and versioning
6957c478bd9Sstevel@tonic-gate  * ***************************************************************************
6967c478bd9Sstevel@tonic-gate  */
6977c478bd9Sstevel@tonic-gate 
6987c478bd9Sstevel@tonic-gate 
6997c478bd9Sstevel@tonic-gate /*
7007c478bd9Sstevel@tonic-gate  * USBA client drivers are required to define USBDRV_MAJOR_VER
7017c478bd9Sstevel@tonic-gate  * USBDRV_MINOR_VER and pass USBDRV_VERSION as the version
7027c478bd9Sstevel@tonic-gate  * number to usb_client_attach
7037c478bd9Sstevel@tonic-gate  */
7047c478bd9Sstevel@tonic-gate #if !defined(USBA_MAJOR_VER) || !defined(USBA_MINOR_VER)
7057c478bd9Sstevel@tonic-gate #error incorrect USBA header
7067c478bd9Sstevel@tonic-gate #endif
7077c478bd9Sstevel@tonic-gate 
7087c478bd9Sstevel@tonic-gate /*
7097c478bd9Sstevel@tonic-gate  * Driver major version must be the same as USBA major version, and
7107c478bd9Sstevel@tonic-gate  * driver minor version must be <= USBA minor version
7117c478bd9Sstevel@tonic-gate  */
7127c478bd9Sstevel@tonic-gate #if !defined(USBA_FRAMEWORK)
7137c478bd9Sstevel@tonic-gate #if defined(USBDRV_MAJOR_VER) && defined(USBDRV_MINOR_VER)
7147c478bd9Sstevel@tonic-gate 
7157c478bd9Sstevel@tonic-gate #if (USBDRV_MAJOR_VER != USBA_MAJOR_VER)
7167c478bd9Sstevel@tonic-gate #error USBA and driver major versions do not match
7177c478bd9Sstevel@tonic-gate #endif
7187c478bd9Sstevel@tonic-gate #if (USBDRV_MINOR_VER > USBA_MINOR_VER)
7197c478bd9Sstevel@tonic-gate #error USBA and driver minor versions do not match
7207c478bd9Sstevel@tonic-gate #endif
7217c478bd9Sstevel@tonic-gate 
7227c478bd9Sstevel@tonic-gate #endif
7237c478bd9Sstevel@tonic-gate #endif
7247c478bd9Sstevel@tonic-gate 
7257c478bd9Sstevel@tonic-gate #define	USBA_MAKE_VER(major, minor) ((major) << 8 | (minor))
7267c478bd9Sstevel@tonic-gate #define	USBA_GET_MAJOR(ver) ((ver) >> 8)
7277c478bd9Sstevel@tonic-gate #define	USBA_GET_MINOR(ver) ((ver) & 0xff)
7287c478bd9Sstevel@tonic-gate 
7297c478bd9Sstevel@tonic-gate #define	USBDRV_VERSION	USBA_MAKE_VER(USBDRV_MAJOR_VER, USBDRV_MINOR_VER)
7307c478bd9Sstevel@tonic-gate 
7317c478bd9Sstevel@tonic-gate 
7327c478bd9Sstevel@tonic-gate /*
7337c478bd9Sstevel@tonic-gate  * usb_client_attach:
7347c478bd9Sstevel@tonic-gate  *
7357c478bd9Sstevel@tonic-gate  * Arguments:
7367c478bd9Sstevel@tonic-gate  *	dip		- pointer to devinfo node of the client
7377c478bd9Sstevel@tonic-gate  *	version 	- USBA registration version number
7387c478bd9Sstevel@tonic-gate  *	flags		- None used
7397c478bd9Sstevel@tonic-gate  *
7407c478bd9Sstevel@tonic-gate  * Return Values:
7417c478bd9Sstevel@tonic-gate  *	USB_SUCCESS		- attach succeeded
7427c478bd9Sstevel@tonic-gate  *	USB_INVALID_ARGS	- received null dip or reg argument
7437c478bd9Sstevel@tonic-gate  *	USB_INVALID_CONTEXT	- called with sleep from callback context
7447c478bd9Sstevel@tonic-gate  *				  or not at attach time
7457c478bd9Sstevel@tonic-gate  *	USB_INVALID_VERSION	- version argument is incorrect.
7467c478bd9Sstevel@tonic-gate  *	USB_FAILURE		- other internal failure
7477c478bd9Sstevel@tonic-gate  */
7487c478bd9Sstevel@tonic-gate int usb_client_attach(
7497c478bd9Sstevel@tonic-gate 	dev_info_t			*dip,
7507c478bd9Sstevel@tonic-gate 	uint_t				version,
7517c478bd9Sstevel@tonic-gate 	usb_flags_t			flags);
7527c478bd9Sstevel@tonic-gate 
7537c478bd9Sstevel@tonic-gate /*
7547c478bd9Sstevel@tonic-gate  * usb_client_detach:
7557c478bd9Sstevel@tonic-gate  *
7567c478bd9Sstevel@tonic-gate  * Arguments:
7577c478bd9Sstevel@tonic-gate  *	dip		- pointer to devinfo node of the client
7587c478bd9Sstevel@tonic-gate  *	dev_data	- pointer to data to free. may be NULL
7597c478bd9Sstevel@tonic-gate  */
7607c478bd9Sstevel@tonic-gate void usb_client_detach(
7617c478bd9Sstevel@tonic-gate 	dev_info_t			*dip,
7627c478bd9Sstevel@tonic-gate 	struct usb_client_dev_data	*dev_data);
7637c478bd9Sstevel@tonic-gate 
7647c478bd9Sstevel@tonic-gate /*
7657c478bd9Sstevel@tonic-gate  * ***************************************************************************
7667c478bd9Sstevel@tonic-gate  * Functions for parsing / retrieving data from the descriptor tree
7677c478bd9Sstevel@tonic-gate  * ***************************************************************************
7687c478bd9Sstevel@tonic-gate  */
7697c478bd9Sstevel@tonic-gate 
7707c478bd9Sstevel@tonic-gate /*
7717c478bd9Sstevel@tonic-gate  * Function for unpacking any kind of little endian data, usually desriptors
7727c478bd9Sstevel@tonic-gate  *
7737c478bd9Sstevel@tonic-gate  * Arguments:
7747c478bd9Sstevel@tonic-gate  *	format		- string indicating the format in c, s, w, eg. "2c4ws"
7757c478bd9Sstevel@tonic-gate  *			  which describes 2 bytes, 4 int, one short.
7767c478bd9Sstevel@tonic-gate  *			  The number prefix parses the number of items of
7777c478bd9Sstevel@tonic-gate  *			  the following type.
7787c478bd9Sstevel@tonic-gate  *	data		- pointer to the LE data buffer
7797c478bd9Sstevel@tonic-gate  *	datalen		- length of the data
7807c478bd9Sstevel@tonic-gate  *	structure	- pointer to return structure where the unpacked data
7817c478bd9Sstevel@tonic-gate  *			  will be written
7827c478bd9Sstevel@tonic-gate  *	structlen	- length of the return structure
7837c478bd9Sstevel@tonic-gate  *
7847c478bd9Sstevel@tonic-gate  * return value:
7857c478bd9Sstevel@tonic-gate  *	total number of bytes of the original data that was unpacked
7867c478bd9Sstevel@tonic-gate  *	or USB_PARSE_ERROR
7877c478bd9Sstevel@tonic-gate  */
7887c478bd9Sstevel@tonic-gate #define	USB_PARSE_ERROR	0
7897c478bd9Sstevel@tonic-gate 
7907c478bd9Sstevel@tonic-gate size_t usb_parse_data(
7917c478bd9Sstevel@tonic-gate 	char			*format,
792*0d2006e4SRobert Mustacchi 	const uchar_t 		*data,
7937c478bd9Sstevel@tonic-gate 	size_t			datalen,
7947c478bd9Sstevel@tonic-gate 	void			*structure,
7957c478bd9Sstevel@tonic-gate 	size_t			structlen);
7967c478bd9Sstevel@tonic-gate 
7977c478bd9Sstevel@tonic-gate /*
7987c478bd9Sstevel@tonic-gate  * usb_lookup_ep_data:
7997c478bd9Sstevel@tonic-gate  *	Function to get specific endpoint data
8007c478bd9Sstevel@tonic-gate  *	This function will not access the device.
8017c478bd9Sstevel@tonic-gate  *
8027c478bd9Sstevel@tonic-gate  * Arguments:
8037c478bd9Sstevel@tonic-gate  *	dip		- pointer to dev info
8047c478bd9Sstevel@tonic-gate  *	dev_datap	- pointer to registration data
8057c478bd9Sstevel@tonic-gate  *	interface	- requested interface
8067c478bd9Sstevel@tonic-gate  *	alternate	- requested alternate
8077c478bd9Sstevel@tonic-gate  *	skip		- number of endpoints which match the requested type and
8087c478bd9Sstevel@tonic-gate  *			  direction to skip before finding one to retrieve
8097c478bd9Sstevel@tonic-gate  *	type		- endpoint type
8107c478bd9Sstevel@tonic-gate  *	direction	- endpoint direction: USB_EP_DIR_IN/OUT or none
8117c478bd9Sstevel@tonic-gate  *
8127c478bd9Sstevel@tonic-gate  * Return Values:
8137c478bd9Sstevel@tonic-gate  *	NULL or an endpoint data pointer
8147c478bd9Sstevel@tonic-gate  */
8157c478bd9Sstevel@tonic-gate usb_ep_data_t *usb_lookup_ep_data(
8167c478bd9Sstevel@tonic-gate 	dev_info_t		*dip,
8177c478bd9Sstevel@tonic-gate 	usb_client_dev_data_t	*dev_datap,
8187c478bd9Sstevel@tonic-gate 	uint_t			interface,
8197c478bd9Sstevel@tonic-gate 	uint_t			alternate,
8207c478bd9Sstevel@tonic-gate 	uint_t			skip,
8217c478bd9Sstevel@tonic-gate 	uint_t			type,
8227c478bd9Sstevel@tonic-gate 	uint_t			direction);
8237c478bd9Sstevel@tonic-gate 
8247c478bd9Sstevel@tonic-gate 
8257c478bd9Sstevel@tonic-gate /* Language ID for string descriptors. */
8267c478bd9Sstevel@tonic-gate #define	USB_LANG_ID		0x0409		/* English, US */
8277c478bd9Sstevel@tonic-gate 
8287c478bd9Sstevel@tonic-gate /*
8297c478bd9Sstevel@tonic-gate  * usb_get_string_descr:
8307c478bd9Sstevel@tonic-gate  *	Reads the string descriptor.  This function access the device and
8317c478bd9Sstevel@tonic-gate  *	blocks.
8327c478bd9Sstevel@tonic-gate  *
8337c478bd9Sstevel@tonic-gate  * Arguments:
8347c478bd9Sstevel@tonic-gate  *	dip		- pointer to devinfo of the client.
8357c478bd9Sstevel@tonic-gate  *	langid		- LANGID to read different LOCALEs.
8367c478bd9Sstevel@tonic-gate  *	index		- index to the string.
8377c478bd9Sstevel@tonic-gate  *	buf		- user provided buffer for string descriptor.
8387c478bd9Sstevel@tonic-gate  *	buflen		- user provided length of the buffer.
8397c478bd9Sstevel@tonic-gate  *
8407c478bd9Sstevel@tonic-gate  * Return Values:
8417c478bd9Sstevel@tonic-gate  *	USB_SUCCESS	- descriptor is valid.
8427c478bd9Sstevel@tonic-gate  *	USB_FAILURE	- full descriptor could not be retrieved.
8437c478bd9Sstevel@tonic-gate  */
8447c478bd9Sstevel@tonic-gate int usb_get_string_descr(
8457c478bd9Sstevel@tonic-gate 	dev_info_t		*dip,
8467c478bd9Sstevel@tonic-gate 	uint16_t		langid,
8477c478bd9Sstevel@tonic-gate 	uint8_t			index,
8487c478bd9Sstevel@tonic-gate 	char			*buf,
8497c478bd9Sstevel@tonic-gate 	size_t			buflen);
8507c478bd9Sstevel@tonic-gate 
851993e3fafSRobert Mustacchi /*
852993e3fafSRobert Mustacchi  * With the advent of USB 3.x, several endpoint compantion descriptors have been
853993e3fafSRobert Mustacchi  * added. These provide additional information required by HCI drivers to
854993e3fafSRobert Mustacchi  * properly open and configure the pipes.
855993e3fafSRobert Mustacchi  */
856993e3fafSRobert Mustacchi 
857993e3fafSRobert Mustacchi /*
858993e3fafSRobert Mustacchi  * usb_ep_xdescr
859993e3fafSRobert Mustacchi  *
860993e3fafSRobert Mustacchi  * 	Versioned data structure that's used for usb_pipe_xopen() and should be
861993e3fafSRobert Mustacchi  * 	filled in by a call to usb_ep_xdescr_fill(). Drivers should always use
862993e3fafSRobert Mustacchi  * 	USB_EP_XDESCR_CURRENT_VERSION.
863993e3fafSRobert Mustacchi  */
864993e3fafSRobert Mustacchi 
865993e3fafSRobert Mustacchi #define	USB_EP_XDESCR_VERSION_ONE	1
866993e3fafSRobert Mustacchi #define	USB_EP_XDESCR_CURRENT_VERSION	USB_EP_XDESCR_VERSION_ONE
867993e3fafSRobert Mustacchi 
868993e3fafSRobert Mustacchi typedef enum usb_ep_xdescr_flags {
869993e3fafSRobert Mustacchi 	USB_EP_XFLAGS_SS_COMP	= (1 << 0)
870993e3fafSRobert Mustacchi } usb_ep_xdescr_flags_t;
871993e3fafSRobert Mustacchi 
872993e3fafSRobert Mustacchi typedef struct usb_ep_xdescr {
873993e3fafSRobert Mustacchi 	uint_t			uex_version;
874993e3fafSRobert Mustacchi 	usb_ep_xdescr_flags_t	uex_flags;
875993e3fafSRobert Mustacchi 	usb_ep_descr_t		uex_ep;
876993e3fafSRobert Mustacchi 	usb_ep_ss_comp_descr_t	uex_ep_ss;
877993e3fafSRobert Mustacchi } usb_ep_xdescr_t;
878993e3fafSRobert Mustacchi 
879993e3fafSRobert Mustacchi /*
880993e3fafSRobert Mustacchi  * usb_ep_xdescr_fill:
881993e3fafSRobert Mustacchi  *
882993e3fafSRobert Mustacchi  * Fills in the extended endpoint descriptor based on data from the
883993e3fafSRobert Mustacchi  * configuration tree.
884993e3fafSRobert Mustacchi  *
885993e3fafSRobert Mustacchi  * Arguments:
886993e3fafSRobert Mustacchi  * 	version		- Should be USB_EP_XDESCR_CURRENT_VERSION
887993e3fafSRobert Mustacchi  * 	dip		- devinfo pointer
888993e3fafSRobert Mustacchi  * 	ep_data		- endpoint data pointer
889993e3fafSRobert Mustacchi  * 	ep_xdesc	- An extended descriptor structure, filled upon
890993e3fafSRobert Mustacchi  *                        successful completion.
891993e3fafSRobert Mustacchi  *
892993e3fafSRobert Mustacchi  * Return values:
893993e3fafSRobert Mustacchi  *	USB_SUCCESS	 - filling data succeeded
894993e3fafSRobert Mustacchi  *	USB_INVALID_ARGS - invalid arguments
895993e3fafSRobert Mustacchi  */
896993e3fafSRobert Mustacchi int usb_ep_xdescr_fill(
897993e3fafSRobert Mustacchi 	uint_t 		version,
898993e3fafSRobert Mustacchi 	dev_info_t	*dip,
899993e3fafSRobert Mustacchi 	usb_ep_data_t	*ep_data,
900993e3fafSRobert Mustacchi 	usb_ep_xdescr_t	*ep_xdesc);
901993e3fafSRobert Mustacchi 
9027c478bd9Sstevel@tonic-gate 
9037c478bd9Sstevel@tonic-gate /*
9047c478bd9Sstevel@tonic-gate  * ***************************************************************************
9057c478bd9Sstevel@tonic-gate  * Addressing utility functions
9067c478bd9Sstevel@tonic-gate  * ***************************************************************************
9077c478bd9Sstevel@tonic-gate  */
9087c478bd9Sstevel@tonic-gate 
9097c478bd9Sstevel@tonic-gate /*
9107c478bd9Sstevel@tonic-gate  * usb_get_addr returns the current usb address, mostly for debugging
9117c478bd9Sstevel@tonic-gate  * purposes. The address may change after hotremove/insert.
9127c478bd9Sstevel@tonic-gate  * This address will not change on a disconnect/reconnect of open device.
9137c478bd9Sstevel@tonic-gate  */
9147c478bd9Sstevel@tonic-gate int usb_get_addr(dev_info_t *dip);
9157c478bd9Sstevel@tonic-gate 
9167c478bd9Sstevel@tonic-gate 
9177c478bd9Sstevel@tonic-gate /*
9187c478bd9Sstevel@tonic-gate  * usb_get_if_number returns USB_COMBINED_NODE or USB_DEVICE_NODE
9197c478bd9Sstevel@tonic-gate  * if the driver is responsible for the entire device.
9207c478bd9Sstevel@tonic-gate  * Otherwise it returns the interface number.
9217c478bd9Sstevel@tonic-gate  */
9227c478bd9Sstevel@tonic-gate #define	USB_COMBINED_NODE	-1
9237c478bd9Sstevel@tonic-gate #define	USB_DEVICE_NODE		-2
9247c478bd9Sstevel@tonic-gate 
9257c478bd9Sstevel@tonic-gate int usb_get_if_number(
9267c478bd9Sstevel@tonic-gate 	dev_info_t		*dip);
9277c478bd9Sstevel@tonic-gate 
9287c478bd9Sstevel@tonic-gate boolean_t usb_owns_device(
9297c478bd9Sstevel@tonic-gate 	dev_info_t		*dip);
9307c478bd9Sstevel@tonic-gate 
9317c478bd9Sstevel@tonic-gate 
9327c478bd9Sstevel@tonic-gate /*
9337c478bd9Sstevel@tonic-gate  * ***************************************************************************
9347c478bd9Sstevel@tonic-gate  * Pipe	Management definitions and functions
9357c478bd9Sstevel@tonic-gate  * ***************************************************************************
9367c478bd9Sstevel@tonic-gate  */
9377c478bd9Sstevel@tonic-gate 
9387c478bd9Sstevel@tonic-gate 
9397c478bd9Sstevel@tonic-gate /*
9407c478bd9Sstevel@tonic-gate  *
9417c478bd9Sstevel@tonic-gate  * usb_pipe_state:
9427c478bd9Sstevel@tonic-gate  *
9437c478bd9Sstevel@tonic-gate  * PIPE_STATE_IDLE:
9447c478bd9Sstevel@tonic-gate  *	The pipe's policy is set, but the pipe currently isn't transferring
9457c478bd9Sstevel@tonic-gate  *	data.
9467c478bd9Sstevel@tonic-gate  *
9477c478bd9Sstevel@tonic-gate  * PIPE_STATE_ACTIVE:
9487c478bd9Sstevel@tonic-gate  *	The pipe's policy has been set, and the pipe is able to transmit data.
9497c478bd9Sstevel@tonic-gate  *	When a control or bulk pipe is opened, the pipe's state is
9507c478bd9Sstevel@tonic-gate  *	automatically set to PIPE_STATE_ACTIVE.  For an interrupt or
9517c478bd9Sstevel@tonic-gate  *	isochronous pipe, the pipe state becomes PIPE_STATE_ACTIVE once
9527c478bd9Sstevel@tonic-gate  *	the polling on the pipe has been initiated.
9537c478bd9Sstevel@tonic-gate  *
9547c478bd9Sstevel@tonic-gate  * PIPE_STATE_ERROR:
9557c478bd9Sstevel@tonic-gate  *	The device has generated a error on the pipe.  The client driver
9567c478bd9Sstevel@tonic-gate  *	must call usb_pipe_reset() to clear any leftover state that's associated
9577c478bd9Sstevel@tonic-gate  *	with the pipe, clear the data toggle, and reset the state of the pipe.
9587c478bd9Sstevel@tonic-gate  *
9597c478bd9Sstevel@tonic-gate  *	Calling usb_pipe_reset() on a control or bulk pipe resets the state to
9607c478bd9Sstevel@tonic-gate  *	PIPE_STATE_ACTIVE.  Calling usb_pipe_reset() on an interrupt or
9617c478bd9Sstevel@tonic-gate  *	isochronous pipe, resets the state to PIPE_STATE_IDLE.
9627c478bd9Sstevel@tonic-gate  *
9637c478bd9Sstevel@tonic-gate  * State Diagram for Bulk/Control
9647c478bd9Sstevel@tonic-gate  *
9657c478bd9Sstevel@tonic-gate  *			+-<--normal completion------------------<-------^
9667c478bd9Sstevel@tonic-gate  *			|						|
9677c478bd9Sstevel@tonic-gate  *			V						|
9687c478bd9Sstevel@tonic-gate  * usb_pipe_open-->[PIPE_STATE_IDLE]-usb_pipe_*_xfer->[PIPE_STATE_ACTIVE]
9697c478bd9Sstevel@tonic-gate  *			^						|
9707c478bd9Sstevel@tonic-gate  *			|						v
9717c478bd9Sstevel@tonic-gate  *			- usb_pipe_reset<-[PIPE_STATE_ERROR]<-device error
9727c478bd9Sstevel@tonic-gate  *
9737c478bd9Sstevel@tonic-gate  * State Diagram for Interrupt/Isochronous IN
9747c478bd9Sstevel@tonic-gate  *
9757c478bd9Sstevel@tonic-gate  *			+-<--usb_pipe_stop_isoc/intr_polling----<-------^
9767c478bd9Sstevel@tonic-gate  *			|						|
9777c478bd9Sstevel@tonic-gate  *			V						|
9787c478bd9Sstevel@tonic-gate  * usb_pipe_open-->[PIPE_STATE_IDLE]-usb_pipe_*_xfer->[PIPE_STATE_ACTIVE]
9797c478bd9Sstevel@tonic-gate  *			^						|
9807c478bd9Sstevel@tonic-gate  *			|						v
9817c478bd9Sstevel@tonic-gate  *			+ usb_pipe_reset<-[PIPE_STATE_ERROR]<-device error
9827c478bd9Sstevel@tonic-gate  *
9837c478bd9Sstevel@tonic-gate  * State Diagram for Interrupt/Isochronous OUT
9847c478bd9Sstevel@tonic-gate  *
9857c478bd9Sstevel@tonic-gate  *			+-<--normal completion------------------<-------^
9867c478bd9Sstevel@tonic-gate  *			|						|
9877c478bd9Sstevel@tonic-gate  *			V						|
9887c478bd9Sstevel@tonic-gate  * usb_pipe_open-->[PIPE_STATE_IDLE]-usb_pipe_*_xfer->[PIPE_STATE_ACTIVE]
9897c478bd9Sstevel@tonic-gate  *			^						|
9907c478bd9Sstevel@tonic-gate  *			|						v
9917c478bd9Sstevel@tonic-gate  *			+ usb_pipe_reset<-[PIPE_STATE_ERROR]<-device error
9927c478bd9Sstevel@tonic-gate  *
9937c478bd9Sstevel@tonic-gate  *
9947c478bd9Sstevel@tonic-gate  * The following table indicates which operations are allowed with each
9957c478bd9Sstevel@tonic-gate  * pipe state:
9967c478bd9Sstevel@tonic-gate  *
9977c478bd9Sstevel@tonic-gate  * -------------------------------------------------------------------------+
9987c478bd9Sstevel@tonic-gate  * ctrl/bulk	| idle	| active     | error  | sync closing | async closing|
9997c478bd9Sstevel@tonic-gate  * -------------------------------------------------------------------------+
10007c478bd9Sstevel@tonic-gate  * pipe xfer	|  OK	|queue (USBA)| reject | reject	     | reject	    |
10017c478bd9Sstevel@tonic-gate  * pipe reset	| no-op | OK	     |	OK    | reject	     | reject	    |
10027c478bd9Sstevel@tonic-gate  * pipe close	|  OK	| wait&close |	OK    | no-op	     | no-op	    |
10037c478bd9Sstevel@tonic-gate  * -------------------------------------------------------------------------+
10047c478bd9Sstevel@tonic-gate  *
10057c478bd9Sstevel@tonic-gate  * -------------------------------------------------------------------------+
10067c478bd9Sstevel@tonic-gate  * intr/isoc IN | idle	| active     | error  | sync closing | async closing|
10077c478bd9Sstevel@tonic-gate  * -------------------------------------------------------------------------+
10087c478bd9Sstevel@tonic-gate  * pipe xfer	|  OK	| reject     | reject | reject	     | reject	    |
10097c478bd9Sstevel@tonic-gate  * pipe stoppoll| no-op | OK	     | no-op  | reject	     | reject	    |
10107c478bd9Sstevel@tonic-gate  * pipe reset	| no-op | OK	     |	OK    | reject	     | reject	    |
10117c478bd9Sstevel@tonic-gate  * pipe close	|  OK	| wait&close |	OK    | no-op	     | no-op	    |
10127c478bd9Sstevel@tonic-gate  * -------------------------------------------------------------------------+
10137c478bd9Sstevel@tonic-gate  *
10147c478bd9Sstevel@tonic-gate  * -------------------------------------------------------------------------+
10157c478bd9Sstevel@tonic-gate  * intr/isoc OUT| idle	| active     | error  | sync closing | async closing|
10167c478bd9Sstevel@tonic-gate  * -------------------------------------------------------------------------+
10177c478bd9Sstevel@tonic-gate  * pipe xfer	|  OK	|queue (HCD) | reject | reject	     | reject	    |
10187c478bd9Sstevel@tonic-gate  * pipe stoppoll| reject| reject     | reject | reject	     | reject	    |
10197c478bd9Sstevel@tonic-gate  * pipe reset	| no-op | OK	     |	OK    | reject	     | reject	    |
10207c478bd9Sstevel@tonic-gate  * pipe close	|  OK	| wait&close |	OK    | no-op	     | no-op	    |
10217c478bd9Sstevel@tonic-gate  * -------------------------------------------------------------------------+
10227c478bd9Sstevel@tonic-gate  */
10237c478bd9Sstevel@tonic-gate typedef enum {
10247c478bd9Sstevel@tonic-gate 	USB_PIPE_STATE_CLOSED		= 0,
10257c478bd9Sstevel@tonic-gate 	USB_PIPE_STATE_IDLE		= 1,
10267c478bd9Sstevel@tonic-gate 	USB_PIPE_STATE_ACTIVE		= 2,
10277c478bd9Sstevel@tonic-gate 	USB_PIPE_STATE_ERROR		= 3,
10287c478bd9Sstevel@tonic-gate 	USB_PIPE_STATE_CLOSING		= 4
10297c478bd9Sstevel@tonic-gate } usb_pipe_state_t;
10307c478bd9Sstevel@tonic-gate 
10317c478bd9Sstevel@tonic-gate 
10327c478bd9Sstevel@tonic-gate /*
10337c478bd9Sstevel@tonic-gate  * pipe state control:
10347c478bd9Sstevel@tonic-gate  *
10357c478bd9Sstevel@tonic-gate  * return values:
10367c478bd9Sstevel@tonic-gate  *	USB_SUCCESS	 - success
10377c478bd9Sstevel@tonic-gate  *	USB_FAILURE	 - unspecified failure
10387c478bd9Sstevel@tonic-gate  */
10397c478bd9Sstevel@tonic-gate int usb_pipe_get_state(
10407c478bd9Sstevel@tonic-gate 	usb_pipe_handle_t	pipe_handle,
10417c478bd9Sstevel@tonic-gate 	usb_pipe_state_t	*pipe_state,
10427c478bd9Sstevel@tonic-gate 	usb_flags_t		flags);
10437c478bd9Sstevel@tonic-gate 
10447c478bd9Sstevel@tonic-gate /*
10457c478bd9Sstevel@tonic-gate  * usb_pipe_policy
10467c478bd9Sstevel@tonic-gate  *
10477c478bd9Sstevel@tonic-gate  *	Pipe policy specifies how a pipe to an endpoint	should be used
10487c478bd9Sstevel@tonic-gate  *	by the client driver and the HCD.
10497c478bd9Sstevel@tonic-gate  */
10507c478bd9Sstevel@tonic-gate typedef struct usb_pipe_policy {
10517c478bd9Sstevel@tonic-gate 	/*
10527c478bd9Sstevel@tonic-gate 	 * This is a hint indicating how many asynchronous operations
10537c478bd9Sstevel@tonic-gate 	 * requiring a kernel thread will be concurrently active.
10547c478bd9Sstevel@tonic-gate 	 * Allow at least one for synch exception callback handling
10557c478bd9Sstevel@tonic-gate 	 * and another for asynchronous closing of pipes.
10567c478bd9Sstevel@tonic-gate 	 */
10577c478bd9Sstevel@tonic-gate 	uchar_t		pp_max_async_reqs;
10587c478bd9Sstevel@tonic-gate } usb_pipe_policy_t;
10597c478bd9Sstevel@tonic-gate 
10607c478bd9Sstevel@tonic-gate 
10617c478bd9Sstevel@tonic-gate /*
1062993e3fafSRobert Mustacchi  * usb_pipe_open() and usb_pipe_xopen():
10637c478bd9Sstevel@tonic-gate  *
10647c478bd9Sstevel@tonic-gate  * Before using any pipe including the default pipe, it must be opened.
10657c478bd9Sstevel@tonic-gate  * On success, a pipe handle is returned for use in other usb_pipe_*()
10667c478bd9Sstevel@tonic-gate  * functions.
10677c478bd9Sstevel@tonic-gate  *
10687c478bd9Sstevel@tonic-gate  * The default pipe can only be opened by the hub driver.
10697c478bd9Sstevel@tonic-gate  *
10707c478bd9Sstevel@tonic-gate  * For isochronous and interrupt pipes, bandwidth has been allocated and
10717c478bd9Sstevel@tonic-gate  * guaranteed.
10727c478bd9Sstevel@tonic-gate  *
10737c478bd9Sstevel@tonic-gate  * Only the default pipe can be shared.  All other control pipes are
10747c478bd9Sstevel@tonic-gate  * excusively opened by default.  A pipe policy and endpoint descriptor
10757c478bd9Sstevel@tonic-gate  * must always be provided except for default pipe.
10767c478bd9Sstevel@tonic-gate  *
1077993e3fafSRobert Mustacchi  * usb_pipe_open() only functions for USB 2.0 and older devices. For USB 3.0
1078993e3fafSRobert Mustacchi  * "SuperSpeed" devices, usb_pipe_xopen() must be used.
1079993e3fafSRobert Mustacchi  *
10807c478bd9Sstevel@tonic-gate  * Arguments:
10817c478bd9Sstevel@tonic-gate  *	dip		- devinfo ptr.
10827c478bd9Sstevel@tonic-gate  *	ep		- endpoint descriptor pointer.
10837c478bd9Sstevel@tonic-gate  *	pipe_policy	- pointer to pipe policy which provides hints on how
10847c478bd9Sstevel@tonic-gate  *			  the pipe will be used.
10857c478bd9Sstevel@tonic-gate  *	flags		- USB_FLAGS_SLEEP wait for resources to become
10867c478bd9Sstevel@tonic-gate  *			  available.
10877c478bd9Sstevel@tonic-gate  *	pipe_handle	- a pipe handle pointer.  on a successful open,
10887c478bd9Sstevel@tonic-gate  *			  a pipe_handle is returned in this pointer.
10897c478bd9Sstevel@tonic-gate  *
10907c478bd9Sstevel@tonic-gate  * Return values:
10917c478bd9Sstevel@tonic-gate  *	USB_SUCCESS	 - open succeeded.
10927c478bd9Sstevel@tonic-gate  *	USB_FAILURE	 - unspecified open failure or pipe is already open.
10937c478bd9Sstevel@tonic-gate  *	USB_NO_RESOURCES - no resources were available to complete the open.
10947c478bd9Sstevel@tonic-gate  *	USB_NO_BANDWIDTH - no bandwidth available (isoc/intr pipes).
1095993e3fafSRobert Mustacchi  *	USB_NOT_SUPPORTED - USB 3.0 or greater device
10967c478bd9Sstevel@tonic-gate  *	USB_*		 - refer to list of all possible return values in
10977c478bd9Sstevel@tonic-gate  *			   this file
10987c478bd9Sstevel@tonic-gate  */
10997c478bd9Sstevel@tonic-gate int usb_pipe_open(
11007c478bd9Sstevel@tonic-gate 	dev_info_t		*dip,
11017c478bd9Sstevel@tonic-gate 	usb_ep_descr_t		*ep,
11027c478bd9Sstevel@tonic-gate 	usb_pipe_policy_t	*pipe_policy,
11037c478bd9Sstevel@tonic-gate 	usb_flags_t		flags,
11047c478bd9Sstevel@tonic-gate 	usb_pipe_handle_t	*pipe_handle);
11057c478bd9Sstevel@tonic-gate 
1106993e3fafSRobert Mustacchi int usb_pipe_xopen(
1107993e3fafSRobert Mustacchi 	dev_info_t		*dip,
1108993e3fafSRobert Mustacchi 	usb_ep_xdescr_t		*ep_xdesc,
1109993e3fafSRobert Mustacchi 	usb_pipe_policy_t	*pipe_policy,
1110993e3fafSRobert Mustacchi 	usb_flags_t		flags,
1111993e3fafSRobert Mustacchi 	usb_pipe_handle_t	*pipe_handle);
1112993e3fafSRobert Mustacchi 
11137c478bd9Sstevel@tonic-gate 
11147c478bd9Sstevel@tonic-gate /*
11157c478bd9Sstevel@tonic-gate  * usb_pipe_close():
11167c478bd9Sstevel@tonic-gate  *
11177c478bd9Sstevel@tonic-gate  * Closes the pipe, releases resources and frees the pipe_handle.
11187c478bd9Sstevel@tonic-gate  * Automatic polling, if active,  will be terminated.
11197c478bd9Sstevel@tonic-gate  *
11207c478bd9Sstevel@tonic-gate  * Arguments:
11217c478bd9Sstevel@tonic-gate  *	dip		- devinfo ptr.
11227c478bd9Sstevel@tonic-gate  *	pipe_handle	- pipe handle.
11237c478bd9Sstevel@tonic-gate  *	flags		- USB_FLAGS_SLEEP:
11247c478bd9Sstevel@tonic-gate  *				wait for resources, pipe
11257c478bd9Sstevel@tonic-gate  *				to become free, and all callbacks completed.
11267c478bd9Sstevel@tonic-gate  *	cb		- If USB_FLAGS_SLEEP has not been specified, a
11277c478bd9Sstevel@tonic-gate  *			  callback will be performed.
11287c478bd9Sstevel@tonic-gate  *	cb_arg		- the 2nd argument of the callback. Note that the
11297c478bd9Sstevel@tonic-gate  *			  pipehandle will be zeroed and therefore not passed.
11307c478bd9Sstevel@tonic-gate  *
11317c478bd9Sstevel@tonic-gate  * Notes:
11327c478bd9Sstevel@tonic-gate  *
11337c478bd9Sstevel@tonic-gate  * Pipe close always succeeds regardless whether USB_FLAGS_SLEEP has been
11347c478bd9Sstevel@tonic-gate  * specified or not.  An async close will always succeed if the hint in the
11357c478bd9Sstevel@tonic-gate  * pipe policy has been correct about the max number of async requests
11367c478bd9Sstevel@tonic-gate  * required.
11377c478bd9Sstevel@tonic-gate  * In the unlikely event that no async requests can be queued, this
11387c478bd9Sstevel@tonic-gate  * function will continue retrying before returning