/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. * * Copyright 2014 Garrett D'Amore <garrett@damore.org> * Copyright 2019 Joyent, Inc. */ #ifndef _SYS_USB_USBAI_H #define _SYS_USB_USBAI_H #ifdef __cplusplus extern "C" { #endif /* This header file is for USBA2.1 */ #define USBA_MAJOR_VER 2 #define USBA_MINOR_VER 1 /* * USBAI: Interfaces Between USBA and Client Driver * * * Universal USB device state management : * * PWRED_DWN---<3----4>--ONLINE---<2-----1>-DISCONNECTED * | ^ | * | 6 | * | | | * | 5 | * | v | * +----5>----------SUSPENDED----<5----7>---+ * * 1 = Device Unplug * 2 = Original Device reconnected * 3 = Device idles for time T & transitions to low power state * 4 = Remote wakeup by device OR Application kicking off IO to device * 5 = Notification to save state prior to DDI_SUSPEND * 6 = Notification to restore state after DDI_RESUME with correct device * 7 = Notification to restore state after DDI_RESUME with device * disconnected or a wrong device * * NOTE: device states 0x80 to 0xff are device specific and can be * used by client drivers */ #define USB_DEV_ONLINE 1 /* device is online */ #define USB_DEV_DISCONNECTED 2 /* indicates disconnect */ #define USB_DEV_SUSPENDED 3 /* DDI_SUSPEND operation */ #define USB_DEV_PWRED_DOWN 4 /* indicates power off state */ /* * *************************************************************************** * USBA error and status definitions * *************************************************************************** */ /* * USBA function return values */ #define USB_SUCCESS 0 /* call success */ #define USB_FAILURE -1 /* unspecified USBA or HCD error */ #define USB_NO_RESOURCES -2 /* no resources available */ #define USB_NO_BANDWIDTH -3 /* no bandwidth available */ #define USB_NOT_SUPPORTED -4 /* function not supported by HCD */ #define USB_PIPE_ERROR -5 /* error occured on the pipe */ #define USB_INVALID_PIPE -6 /* pipe handle passed is invalid */ #define USB_NO_FRAME_NUMBER -7 /* frame No or ASAP not specified */ #define USB_INVALID_START_FRAME -8 /* starting USB frame not valid */ #define USB_HC_HARDWARE_ERROR -9 /* usb host controller error */ #define USB_INVALID_REQUEST -10 /* request had invalid values */ #define USB_INVALID_CONTEXT -11 /* sleep flag in interrupt context */ #define USB_INVALID_VERSION -12 /* invalid version specified */ #define USB_INVALID_ARGS -13 /* invalid func args specified */ #define USB_INVALID_PERM -14 /* privileged operation */ #define USB_BUSY -15 /* busy condition */ /* * USB request completion flags, more than one may be set. * The following flags are returned after a recovery action by * HCD or USBA (autoclearing) or callbacks from pipe_close, * abort, reset, or stop polling. More than one may be set. * * For sync requests, the client should check the request structure * for this flag to determine what has happened. * * All callbacks are queued to preserve order. Note that if a normal callback * uses a kernel thread, order is not guaranteed since each callback may use * its own thread. The next request will be submitted to the * HCD after the threads exits. * * Exception callbacks using a kernel thread may do auto clearing and no * new request will be started until this thread has completed its work. */ typedef enum { USB_CB_NO_INFO = 0x00, /* no exception */ USB_CB_STALL_CLEARED = 0x01, /* func stall cleared */ USB_CB_FUNCTIONAL_STALL = 0x02, /* func stall occurred */ USB_CB_PROTOCOL_STALL = 0x04, /* protocal stall occurred */ USB_CB_RESET_PIPE = 0x10, /* pipe was reset */ USB_CB_ASYNC_REQ_FAILED = 0x80, /* thread couldn't be started */ USB_CB_NO_RESOURCES = 0x100, /* no resources */ USB_CB_SUBMIT_FAILED = 0x200, /* req was queued then submitted */ /* to HCD which rejected it */ USB_CB_INTR_CONTEXT = 0x400 /* Callback is in interrupt context. */ } usb_cb_flags_t; /* * completion reason * * Set by HCD; only one can be set. */ typedef enum { USB_CR_OK = 0, /* no errors detected */ USB_CR_CRC = 1, /* crc error detected */ USB_CR_BITSTUFFING = 2, /* bit stuffing violation */ USB_CR_DATA_TOGGLE_MM = 3, /* d/t PID did not match */ USB_CR_STALL = 4, /* e/p returned stall PID */ USB_CR_DEV_NOT_RESP = 5, /* device not responding */ USB_CR_PID_CHECKFAILURE = 6, /* check bits on PID failed */ USB_CR_UNEXP_PID = 7, /* receive PID was not valid */ USB_CR_DATA_OVERRUN = 8, /* data size exceeded */ USB_CR_DATA_UNDERRUN = 9, /* less data received */ USB_CR_BUFFER_OVERRUN = 10, /* memory write can't keep up */ USB_CR_BUFFER_UNDERRUN = 11, /* buffer underrun */ USB_CR_TIMEOUT = 12, /* command timed out */ USB_CR_NOT_ACCESSED = 13, /* Not accessed by hardware */ USB_CR_NO_RESOURCES = 14, /* no resources */ USB_CR_UNSPECIFIED_ERR = 15, /* unspecified usba or hcd err */ USB_CR_STOPPED_POLLING = 16, /* intr/isoc IN polling stopped */ USB_CR_PIPE_CLOSING = 17, /* intr/isoc IN pipe closed */ USB_CR_PIPE_RESET = 18, /* intr/isoc IN pipe reset */ USB_CR_NOT_SUPPORTED = 19, /* command not supported */ USB_CR_FLUSHED = 20, /* this request was flushed */ USB_CR_HC_HARDWARE_ERR = 21 /* usb host controller error */ } usb_cr_t; /* * *************************************************************************** * General definitions, used all over * *************************************************************************** * * A pipe handle is returned by usb_pipe_open() on success for * all pipes except the default pipe which is accessed from * the registration structure. Placed here as forward referenced by * usb_client_dev_data_t below. * * The pipe_handle is opaque to the client driver. */ typedef struct usb_pipe_handle *usb_pipe_handle_t; /* * General opaque pointer. */ typedef struct usb_opaque *usb_opaque_t; /* * USB flags argument to USBA interfaces */ typedef enum { /* do not block until resources are available */ USB_FLAGS_NOSLEEP = 0x0000, /* block until resources are available */ USB_FLAGS_SLEEP = 0x0100, /* reserved */ USB_FLAGS_RESERVED = 0xFE00 } usb_flags_t; /* * *************************************************************************** * Descriptor definitions (USB version and section noted with structure) * *************************************************************************** */ /* * USB Descriptor Management * * Standard USB descriptors: * * USB devices present their configuration information in response to * a GET_DESCRIPTOR request in a form which is little-endian and, * for multibyte integers, unaligned. It is also position-dependent, * which makes non-sequential access to particular interface or * endpoint data inconvenient. * A GET_DESCRIPTOR request may yield a chunk of data that contains * multiple descriptor types. For example, a GET_DESCRIPTOR request * for a CONFIGURATION descriptor could return the configuration * descriptor followed by an interface descriptor and the relevant * endpoint descriptors. * * usb_get_dev_data() interface provides an easy way to get all * the descriptors and avoids parsing standard descriptors by each * client driver * * usb_dev_descr: * usb device descriptor, refer to USB 2.0/9.6.1, */ typedef struct usb_dev_descr { uint8_t bLength; /* descriptor size */ uint8_t bDescriptorType; /* set to DEVICE */ uint16_t bcdUSB; /* USB spec rel. number in bcd */ uint8_t bDeviceClass; /* class code */ uint8_t bDeviceSubClass; /* sub class code */ uint8_t bDeviceProtocol; /* protocol code */ uint8_t bMaxPacketSize0; /* max pkt size of e/p 0 */ uint16_t idVendor; /* vendor ID */ uint16_t idProduct; /* product ID */ uint16_t bcdDevice; /* device release number in bcd */ uint8_t iManufacturer; /* manufacturing string */ uint8_t iProduct; /* product string */ uint8_t iSerialNumber; /* serial number string index */ uint8_t bNumConfigurations; /* #configs for device */ } usb_dev_descr_t; /* * USB Device Qualifier Descriptor * * The device_qualifier descriptor describes information about a High * speed capable device that would change if the device were operating * at other (Full) speed. Example: if the device is currently operating * at Full-speed, the device_qualifier returns information about how if * would operate at high-speed and vice-versa. * * usb_dev_qlf_descr: * * usb device qualifier descriptor, refer to USB 2.0/9.6.2 */ typedef struct usb_dev_qlf_descr { uint8_t bLength; /* descriptor size */ uint8_t bDescriptorType; /* set to DEVICE */ uint16_t bcdUSB; /* USB spec rel. number in bcd */ uint8_t bDeviceClass; /* class code */ uint8_t bDeviceSubClass; /* sub class code */ uint8_t bDeviceProtocol; /* protocol code */ uint8_t bMaxPacketSize0; /* max pkt size of e/p 0 */ uint8_t bNumConfigurations; /* #configs for device */ uint8_t bReserved; /* reserved field */ } usb_dev_qlf_descr_t; /* * usb_cfg_descr: * usb configuration descriptor, refer to USB 2.0/9.6.3 */ typedef struct usb_cfg_descr { uint8_t bLength; /* descriptor size */ uint8_t bDescriptorType; /* set to CONFIGURATION */ uint16_t wTotalLength; /* total length of data returned */ uint8_t bNumInterfaces; /* # interfaces in config */ uint8_t bConfigurationValue; /* arg for SetConfiguration */ uint8_t iConfiguration; /* configuration string */ uint8_t bmAttributes; /* config characteristics */ uint8_t bMaxPower; /* max pwr consumption */ } usb_cfg_descr_t; /* * Default configuration index setting for devices with multiple * configurations. Note the distinction between config index and config * number */ #define USB_DEV_DEFAULT_CONFIG_INDEX 0 /* * bmAttribute values for Configuration Descriptor */ #define USB_CFG_ATTR_SELFPWR 0x40 #define USB_CFG_ATTR_REMOTE_WAKEUP 0x20 #define USB_CFG_ATTR_BAT_PWR 0x10 /* * USB Other Speed Configuration Descriptor * * The other_speed_configuration descriptor describes a configuration of * a High speed capable device if it were operating at its other possible * (Full) speed and vice-versa. * * usb_other_speed_cfg_descr: * usb other speed configuration descriptor, refer to USB 2.0/9.6.4 */ typedef struct usb_other_speed_cfg_descr { uint8_t bLength; /* descriptor size */ uint8_t bDescriptorType; /* set to CONFIGURATION */ uint16_t wTotalLength; /* total length of data returned */ uint8_t bNumInterfaces; /* # interfaces in config */ uint8_t bConfigurationValue; /* arg for SetConfiguration */ uint8_t iConfiguration; /* configuration string */ uint8_t bmAttributes; /* config characteristics */ uint8_t bMaxPower; /* max pwr consumption */ } usb_other_speed_cfg_descr_t; /* * usb_ia_descr: * usb interface association descriptor, refer to USB 2.0 ECN(IAD) */ typedef struct usb_ia_descr { uint8_t bLength; /* descriptor size */ uint8_t bDescriptorType; /* INTERFACE_ASSOCIATION */ uint8_t bFirstInterface; /* 1st interface number */ uint8_t bInterfaceCount; /* number of interfaces */ uint8_t bFunctionClass; /* class code */ uint8_t bFunctionSubClass; /* sub class code */ uint8_t bFunctionProtocol; /* protocol code */ uint8_t iFunction; /* description string */ } usb_ia_descr_t; /* * usb_if_descr: * usb interface descriptor, refer to USB 2.0/9.6.5 */ typedef struct usb_if_descr { uint8_t bLength; /* descriptor size */ uint8_t bDescriptorType; /* set to INTERFACE */ uint8_t bInterfaceNumber; /* interface number */ uint8_t bAlternateSetting; /* alt. interface number */ uint8_t bNumEndpoints; /* # of endpoints */ uint8_t bInterfaceClass; /* class code */ uint8_t bInterfaceSubClass; /* sub class code */ uint8_t bInterfaceProtocol; /* protocol code */ uint8_t iInterface; /* description string */ } usb_if_descr_t; /* * usb_ep_descr: * usb endpoint descriptor, refer to USB 2.0/9.6.6 */ typedef struct usb_ep_descr { uint8_t bLength; /* descriptor size */ uint8_t bDescriptorType; /* set to ENDPOINT */ uint8_t bEndpointAddress; /* address of this e/p */ uint8_t bmAttributes; /* transfer type */ uint16_t wMaxPacketSize; /* maximum packet size */ uint8_t bInterval; /* e/p polling interval */ } usb_ep_descr_t; /* * bEndpointAddress masks */ #define USB_EP_NUM_MASK 0x0F /* endpoint number mask */ #define USB_EP_DIR_MASK 0x80 /* direction mask */ #define USB_EP_DIR_OUT 0x00 /* OUT endpoint */ #define USB_EP_DIR_IN 0x80 /* IN endpoint */ /* * bmAttribute transfer types for endpoints */ #define USB_EP_ATTR_MASK 0x03 /* transfer type mask */ #define USB_EP_ATTR_CONTROL 0x00 /* control transfer */ #define USB_EP_ATTR_ISOCH 0x01 /* isochronous transfer */ #define USB_EP_ATTR_BULK 0x02 /* bulk transfer */ #define USB_EP_ATTR_INTR 0x03 /* interrupt transfer */ /* * bmAttribute synchronization types for endpoints (isochronous only) */ #define USB_EP_SYNC_MASK 0x0C /* synchronization mask */ #define USB_EP_SYNC_NONE 0x00 /* no synchronization */ #define USB_EP_SYNC_ASYNC 0x04 /* asynchronous */ #define USB_EP_SYNC_ADPT 0x08 /* adaptive */ #define USB_EP_SYNC_SYNC 0x0C /* synchronous */ /* * bmAttribute synchronization feedback types for endpoints (isochronous only) */ #define USB_EP_USAGE_MASK 0x30 /* sync feedback mask */ #define USB_EP_USAGE_DATA 0x00 /* data endpoint */ #define USB_EP_USAGE_FEED 0x10 /* feedback endpoint */ #define USB_EP_USAGE_IMPL 0x20 /* implicit feedback endpoint */ /* * wMaxPacketSize values for endpoints (isoch and interrupt, high speed only) */ #define USB_EP_MAX_PKTSZ_MASK 0x07FF /* Mask for packetsize bits */ #define USB_EP_MAX_XACTS_MASK 0x1800 /* Max Transactns/microframe */ #define USB_EP_MAX_XACTS_SHIFT 11 /* Above is 10 bits from end */ /* * Ranges for endpoint parameter values. */ /* Min and Max NAK rates for high sped control endpoints. */ #define USB_EP_MIN_HIGH_CONTROL_INTRVL 0 #define USB_EP_MAX_HIGH_CONTROL_INTRVL 255 /* Min and Max NAK rates for high speed bulk endpoints. */ #define USB_EP_MIN_HIGH_BULK_INTRVL 0 #define USB_EP_MAX_HIGH_BULK_INTRVL 255 /* Min and Max polling intervals for low, full speed interrupt endpoints. */ #define USB_EP_MIN_LOW_INTR_INTRVL 1 #define USB_EP_MAX_LOW_INTR_INTRVL 255 #define USB_EP_MIN_FULL_INTR_INTRVL 1 #define USB_EP_MAX_FULL_INTR_INTRVL 255 /* * Min and Max polling intervals for high speed interrupt endpoints, and for * isochronous endpoints. * Note that the interval is 2**(value-1). See Section 9.6.6 of USB 2.0 spec. */ #define USB_EP_MIN_HIGH_INTR_INTRVL 1 #define USB_EP_MAX_HIGH_INTR_INTRVL 16 #define USB_EP_MIN_FULL_ISOCH_INTRVL 1 #define USB_EP_MAX_FULL_ISOCH_INTRVL 16 #define USB_EP_MIN_HIGH_ISOCH_INTRVL 1 #define USB_EP_MAX_HIGH_ISOCH_INTRVL 16 /* * usb_string_descr: * usb string descriptor, refer to USB 2.0/9.6.7 */ typedef struct usb_string_descr { uint8_t bLength; /* descr size */ uint8_t bDescriptorType; /* set to STRING */ uint8_t bString[1]; /* variable length unicode */ /* encoded string */ } usb_string_descr_t; #define USB_MAXSTRINGLEN 255 /* max string descr length */ /* * usb_ep_ss_comp_descr: * USB SuperSpeed endpoints are required to return this descriptor along * with the general endpoint descriptor. Refer to USB 3.1/9.6.7. */ typedef struct usb_ep_ss_comp_descr { uint8_t bLength; /* descriptor size */ uint8_t bDescriptorType; /* USB_DESCR_TYPE_SS_EP_COMP */ uint8_t bMaxBurst; /* max packets per burst */ uint8_t bmAttributes; /* more endpoint attributes */ uint16_t wBytesPerInterval; /* bytes per service interval */ } usb_ep_ss_comp_descr_t; #define USB_EP_SS_COMP_ISOC_MULT_MASK 0x03 /* * *************************************************************************** * Client driver registration with USBA * *************************************************************************** * * The client registers with USBA during attach in two steps * using usb_client_attach() and usb_get_dev_data(). On completion, the * registration data has been initialized. Most data items are * straightforward. Among the items returned in the data is the tree of * parsed descriptors, in dev_cfg; the number of configurations parsed, * in dev_n_cfg; a pointer to the current configuration in the tree, * in dev_curr_cfg; the index of the first valid interface in the * tree, in dev_curr_if, and a parse level that accurately reflects what * is in the tree, in dev_parse_level. */ /* * *************************************************************************** * Data structures used in the configuration tree * *************************************************************************** */ /* * Tree data structure for each configuration in the tree */ typedef struct usb_cfg_data { struct usb_cfg_descr cfg_descr; /* parsed config descr */ struct usb_if_data *cfg_if; /* interfaces for this cfg */ /* indexed by interface num */ struct usb_cvs_data *cfg_cvs; /* class/vendor specific */ /* descrs mod/extend cfg */ char *cfg_str; /* string descriptor */ uint_t cfg_n_if; /* #elements in cfg_if[] */ uint_t cfg_n_cvs; /* #elements in cfg_cvs[] */ uint_t cfg_strsize; /* size of string descr */ } usb_cfg_data_t; /* * Tree data structure for each alternate interface set * in each represented configuration */ typedef struct usb_if_data { struct usb_alt_if_data *if_alt; /* sparse array of alts */ /* indexed by alt setting */ uint_t if_n_alt; /* #elements in if_alt[] */ } usb_if_data_t; /* * Tree data structure for each alternate of each alternate interface set */ typedef struct usb_alt_if_data { usb_if_descr_t altif_descr; /* parsed alternate if descr */ struct usb_ep_data *altif_ep; /* endpts for alt if */ /* (not a sparse array */ struct usb_cvs_data *altif_cvs; /* cvs for this alt if */ char *altif_str; /* string descriptor */ uint_t altif_n_ep; /* #elements in altif_ep[] */ uint_t altif_n_cvs; /* #elements in altif_cvs[] */ uint_t altif_strsize; /* size of string descr */ } usb_alt_if_data_t; /* * Tree data structure for each endpoint of each alternate */ typedef struct usb_ep_data { usb_ep_descr_t ep_descr; /* endpoint descriptor */ struct usb_cvs_data *ep_cvs; /* cv mod/extending this ep */ uint_t ep_n_cvs; /* #elements in ep_cvs[] */ boolean_t ep_ss_valid; usb_ep_ss_comp_descr_t ep_ss_comp; /* superspeed ep desc */ } usb_ep_data_t; /* * Tree data structure for each class/vendor specific descriptor */ typedef struct usb_cvs_data { uchar_t *cvs_buf; /* raw data of cvs descr */ uint_t cvs_buf_len; /* cvs_buf size */ } usb_cvs_data_t; /* * Parse_level determines the extent to which the tree is built, the amount * of parsing usb_client_attach() is to do. It has the following values: * * USB_PARSE_LVL_NONE - Build no tree. dev_n_cfg will return 0, dev_cfg * will return NULL, the dev_curr_xxx fields will be * invalid. * USB_PARSE_LVL_IF - Parse configured interface only, if configuration# * and interface properties are set (as when different * interfaces are viewed by the OS as different device * instances). If an OS device instance is set up to * represent an entire physical device, this works * like USB_PARSE_LVL_ALL. * USB_PARSE_LVL_CFG - Parse entire configuration of configured interface * only. This is like USB_PARSE_LVL_IF except entire * configuration is returned. * USB_PARSE_LVL_ALL - Parse entire device (all configurations), even * when driver is bound to a single interface of a * single configuration. */ typedef enum { USB_PARSE_LVL_NONE = 0, USB_PARSE_LVL_IF = 1, USB_PARSE_LVL_CFG = 2, USB_PARSE_LVL_ALL = 3 } usb_reg_parse_lvl_t; /* * Registration data returned by usb_get_dev_data(). Configuration tree roots * are returned in dev_cfg array. */ typedef struct usb_client_dev_data { usb_pipe_handle_t dev_default_ph; /* default pipe handle */ ddi_iblock_cookie_t dev_iblock_cookie; /* for mutex_init's */ struct usb_dev_descr *dev_descr; /* cooked device descriptor */ char *dev_mfg; /* manufacturing ID */ char *dev_product; /* product ID */ char *dev_serial; /* serial number */ usb_reg_parse_lvl_t dev_parse_level; /* USB_PARSE_LVL_* flag */ struct usb_cfg_data *dev_cfg; /* configs for this device */ /* indexed by config index */ uint_t dev_n_cfg; /* #elements in dev_cfg[] */ struct usb_cfg_data *dev_curr_cfg; /* current cfg */ int dev_curr_if; /* current interface number */ } usb_client_dev_data_t; /* * *************************************************************************** * Device configuration descriptor tree functions * *************************************************************************** */ /* * usb_get_dev_data: * returns initialized registration data. Most data items are clear. * Among the items returned is the tree ofparsed descriptors in dev_cfg; * and the number of configurations parsed in dev_n_cfg. * * Arguments: * dip - pointer to devinfo node of the client * dev_data - return registration data at this address * parse_level - See above * flags - None used * * Return Values: * USB_SUCCESS - usb_register_client succeeded * USB_INVALID_ARGS - received null dip or reg argument * USB_INVALID_CONTEXT - called with sleep from callback context * USB_FAILURE - bad descriptor info or other internal failure * * Notes: * 1) The non-standard USB descriptors are returned in RAW format. * * 2) The registration data is unshared. Each client receives its own copy. * (The default control pipe may be shared, even though its tree * description will be unique per device.) * */ int usb_get_dev_data( dev_info_t *dip, usb_client_dev_data_t **dev_data, usb_reg_parse_lvl_t parse_level, usb_flags_t flags); /* * usb_free_dev_data: * undoes what usb_get_dev_data() set up. It releases * memory for all strings, descriptors, and trees set up by usb_get_dev_data(). * * Arguments: * dip - pointer to devinfo node of the client * dev_data - pointer to registration data containing the tree. */ void usb_free_dev_data( dev_info_t *dip, usb_client_dev_data_t *dev_data); /* * usb_free_descr_tree: * Take down the configuration tree while leaving the rest of the * registration intact. This can be used, for example, after attach has * copied any descriptors it needs from the tree, but the rest of the * registration data needs to remain intact. * * The following usb_client_dev_data_t fields will be modified: * dev_cfg will be NULL * dev_n_cfg will be 0 * dev_curr_cfg_ndx and dev_curr_if will be invalid * dev_parse_level will be USB_REG_DESCR_NONE * * Arguments: * dip - pointer to devinfo node of the client * dev_data - pointer to registration data containing the tree. */ void usb_free_descr_tree( dev_info_t *dip, usb_client_dev_data_t *dev_data); /* * usb_print_descr_tree: * Dump to the screen a descriptor tree as returned by * usbai_register_client. * * Arguments: * dip - pointer to devinfo of the client * dev_data - pointer to registration area containing the tree * * Returns: * USB_SUCCESS - tree successfully dumped * USB_INVALID_CONTEXT - called from callback context * USB_INVALID_ARGS - bad arguments given */ int usb_print_descr_tree( dev_info_t *dip, usb_client_dev_data_t *dev_data); /* * *************************************************************************** * Registration and versioning * *************************************************************************** */ /* * USBA client drivers are required to define USBDRV_MAJOR_VER * USBDRV_MINOR_VER and pass USBDRV_VERSION as the version * number to usb_client_attach */ #if !defined(USBA_MAJOR_VER) || !defined(USBA_MINOR_VER) #error incorrect USBA header #endif /* * Driver major version must be the same as USBA major version, and * driver minor version must be <= USBA minor version */ #if !defined(USBA_FRAMEWORK) #if defined(USBDRV_MAJOR_VER) && defined(USBDRV_MINOR_VER) #if (USBDRV_MAJOR_VER != USBA_MAJOR_VER) #error USBA and driver major versions do not match #endif #if (USBDRV_MINOR_VER > USBA_MINOR_VER) #error USBA and driver minor versions do not match #endif #endif #endif #define USBA_MAKE_VER(major, minor) ((major) << 8 | (minor)) #define USBA_GET_MAJOR(ver) ((ver) >> 8) #define USBA_GET_MINOR(ver) ((ver) & 0xff) #define USBDRV_VERSION USBA_MAKE_VER(USBDRV_MAJOR_VER, USBDRV_MINOR_VER) /* * usb_client_attach: * * Arguments: * dip - pointer to devinfo node of the client * version - USBA registration version number * flags - None used * * Return Values: * USB_SUCCESS - attach succeeded * USB_INVALID_ARGS - received null dip or reg argument * USB_INVALID_CONTEXT - called with sleep from callback context * or not at attach time * USB_INVALID_VERSION - version argument is incorrect. * USB_FAILURE - other internal failure */ int usb_client_attach( dev_info_t *dip, uint_t version, usb_flags_t flags); /* * usb_client_detach: * * Arguments: * dip - pointer to devinfo node of the client * dev_data - pointer to data to free. may be NULL */ void usb_client_detach( dev_info_t *dip, struct usb_client_dev_data *dev_data); /* * *************************************************************************** * Functions for parsing / retrieving data from the descriptor tree * *************************************************************************** */ /* * Function for unpacking any kind of little endian data, usually desriptors * * Arguments: * format - string indicating the format in c, s, w, eg. "2c4ws" * which describes 2 bytes, 4 int, one short. * The number prefix parses the number of items of * the following type. * data - pointer to the LE data buffer * datalen - length of the data * structure - pointer to return structure where the unpacked data * will be written * structlen - length of the return structure * * return value: * total number of bytes of the original data that was unpacked * or USB_PARSE_ERROR */ #define USB_PARSE_ERROR 0 size_t usb_parse_data( char *format, const uchar_t *data, size_t datalen, void *structure, size_t structlen); /* * usb_lookup_ep_data: * Function to get specific endpoint data * This function will not access the device. * * Arguments: * dip - pointer to dev info * dev_datap - pointer to registration data * interface - requested interface * alternate - requested alternate * skip - number of endpoints which match the requested type and * direction to skip before finding one to retrieve * type - endpoint type * direction - endpoint direction: USB_EP_DIR_IN/OUT or none * * Return Values: * NULL or an endpoint data pointer */ usb_ep_data_t *usb_lookup_ep_data( dev_info_t *dip, usb_client_dev_data_t *dev_datap, uint_t interface, uint_t alternate, uint_t skip, uint_t type, uint_t direction); /* Language ID for string descriptors. */ #define USB_LANG_ID 0x0409 /* English, US */ /* * usb_get_string_descr: * Reads the string descriptor. This function access the device and * blocks. * * Arguments: * dip - pointer to devinfo of the client. * langid - LANGID to read different LOCALEs. * index - index to the string. * buf - user provided buffer for string descriptor. * buflen - user provided length of the buffer. * * Return Values: * USB_SUCCESS - descriptor is valid. * USB_FAILURE - full descriptor could not be retrieved. */ int usb_get_string_descr( dev_info_t *dip, uint16_t langid, uint8_t index, char *buf, size_t buflen); /* * With the advent of USB 3.x, several endpoint compantion descriptors have been * added. These provide additional information required by HCI drivers to * properly open and configure the pipes. */ /* * usb_ep_xdescr * * Versioned data structure that's used for usb_pipe_xopen() and should be * filled in by a call to usb_ep_xdescr_fill(). Drivers should always use * USB_EP_XDESCR_CURRENT_VERSION. */ #define USB_EP_XDESCR_VERSION_ONE 1 #define USB_EP_XDESCR_CURRENT_VERSION USB_EP_XDESCR_VERSION_ONE typedef enum usb_ep_xdescr_flags { USB_EP_XFLAGS_SS_COMP = (1 << 0) } usb_ep_xdescr_flags_t; typedef struct usb_ep_xdescr { uint_t uex_version; usb_ep_xdescr_flags_t uex_flags; usb_ep_descr_t uex_ep; usb_ep_ss_comp_descr_t uex_ep_ss; } usb_ep_xdescr_t; /* * usb_ep_xdescr_fill: * * Fills in the extended endpoint descriptor based on data from the * configuration tree. * * Arguments: * version - Should be USB_EP_XDESCR_CURRENT_VERSION * dip - devinfo pointer * ep_data - endpoint data pointer * ep_xdesc - An extended descriptor structure, filled upon * successful completion. * * Return values: * USB_SUCCESS - filling data succeeded * USB_INVALID_ARGS - invalid arguments */ int usb_ep_xdescr_fill( uint_t version, dev_info_t *dip, usb_ep_data_t *ep_data, usb_ep_xdescr_t *ep_xdesc); /* * *************************************************************************** * Addressing utility functions * *************************************************************************** */ /* * usb_get_addr returns the current usb address, mostly for debugging * purposes. The address may change after hotremove/insert. * This address will not change on a disconnect/reconnect of open device. */ int usb_get_addr(dev_info_t *dip); /* * usb_get_if_number returns USB_COMBINED_NODE or USB_DEVICE_NODE * if the driver is responsible for the entire device. * Otherwise it returns the interface number. */ #define USB_COMBINED_NODE -1 #define USB_DEVICE_NODE -2 int usb_get_if_number( dev_info_t *dip); boolean_t usb_owns_device( dev_info_t *dip); /* * *************************************************************************** * Pipe Management definitions and functions * *************************************************************************** */ /* * * usb_pipe_state: * * PIPE_STATE_IDLE: * The pipe's policy is set, but the pipe currently isn't transferring * data. * * PIPE_STATE_ACTIVE: * The pipe's policy has been set, and the pipe is able to transmit data. * When a control or bulk pipe is opened, the pipe's state is * automatically set to PIPE_STATE_ACTIVE. For an interrupt or * isochronous pipe, the pipe state becomes PIPE_STATE_ACTIVE once * the polling on the pipe has been initiated. * * PIPE_STATE_ERROR: * The device has generated a error on the pipe. The client driver * must call usb_pipe_reset() to clear any leftover state that's associated * with the pipe, clear the data toggle, and reset the state of the pipe. * * Calling usb_pipe_reset() on a control or bulk pipe resets the state to * PIPE_STATE_ACTIVE. Calling usb_pipe_reset() on an interrupt or * isochronous pipe, resets the state to PIPE_STATE_IDLE. * * State Diagram for Bulk/Control * * +-<--normal completion------------------<-------^ * | | * V | * usb_pipe_open-->[PIPE_STATE_IDLE]-usb_pipe_*_xfer->[PIPE_STATE_ACTIVE] * ^ | * | v * - usb_pipe_reset<-[PIPE_STATE_ERROR]<-device error * * State Diagram for Interrupt/Isochronous IN * * +-<--usb_pipe_stop_isoc/intr_polling----<-------^ * | | * V | * usb_pipe_open-->[PIPE_STATE_IDLE]-usb_pipe_*_xfer->[PIPE_STATE_ACTIVE] * ^ | * | v * + usb_pipe_reset<-[PIPE_STATE_ERROR]<-device error * * State Diagram for Interrupt/Isochronous OUT * * +-<--normal completion------------------<-------^ * | | * V | * usb_pipe_open-->[PIPE_STATE_IDLE]-usb_pipe_*_xfer->[PIPE_STATE_ACTIVE] * ^ | * | v * + usb_pipe_reset<-[PIPE_STATE_ERROR]<-device error * * * The following table indicates which operations are allowed with each * pipe state: * * -------------------------------------------------------------------------+ * ctrl/bulk | idle | active | error | sync closing | async closing| * -------------------------------------------------------------------------+ * pipe xfer | OK |queue (USBA)| reject | reject | reject | * pipe reset | no-op | OK | OK | reject | reject | * pipe close | OK | wait&close | OK | no-op | no-op | * -------------------------------------------------------------------------+ * * -------------------------------------------------------------------------+ * intr/isoc IN | idle | active | error | sync closing | async closing| * -------------------------------------------------------------------------+ * pipe xfer | OK | reject | reject | reject | reject | * pipe stoppoll| no-op | OK | no-op | reject | reject | * pipe reset | no-op | OK | OK | reject | reject | * pipe close | OK | wait&close | OK | no-op | no-op | * -------------------------------------------------------------------------+ * * -------------------------------------------------------------------------+ * intr/isoc OUT| idle | active | error | sync closing | async closing| * -------------------------------------------------------------------------+ * pipe xfer | OK |queue (HCD) | reject | reject | reject | * pipe stoppoll| reject| reject | reject | reject | reject | * pipe reset | no-op | OK | OK | reject | reject | * pipe close | OK | wait&close | OK | no-op | no-op | * -------------------------------------------------------------------------+ */ typedef enum { USB_PIPE_STATE_CLOSED = 0, USB_PIPE_STATE_IDLE = 1, USB_PIPE_STATE_ACTIVE = 2, USB_PIPE_STATE_ERROR = 3, USB_PIPE_STATE_CLOSING = 4 } usb_pipe_state_t; /* * pipe state control: * * return values: * USB_SUCCESS - success * USB_FAILURE - unspecified failure */ int usb_pipe_get_state( usb_pipe_handle_t pipe_handle, usb_pipe_state_t *pipe_state, usb_flags_t flags); /* * usb_pipe_policy * * Pipe policy specifies how a pipe to an endpoint should be used * by the client driver and the HCD. */ typedef struct usb_pipe_policy { /* * This is a hint indicating how many asynchronous operations * requiring a kernel thread will be concurrently active. * Allow at least one for synch exception callback handling * and another for asynchronous closing of pipes. */ uchar_t pp_max_async_reqs; } usb_pipe_policy_t; /* * usb_pipe_open() and usb_pipe_xopen(): * * Before using any pipe including the default pipe, it must be opened. * On success, a pipe handle is returned for use in other usb_pipe_*() * functions. * * The default pipe can only be opened by the hub driver. * * For isochronous and interrupt pipes, bandwidth has been allocated and * guaranteed. * * Only the default pipe can be shared. All other control pipes are * excusively opened by default. A pipe policy and endpoint descriptor * must always be provided except for default pipe. * * usb_pipe_open() only functions for USB 2.0 and older devices. For USB 3.0 * "SuperSpeed" devices, usb_pipe_xopen() must be used. * * Arguments: * dip - devinfo ptr. * ep - endpoint descriptor pointer. * pipe_policy - pointer to pipe policy which provides hints on how * the pipe will be used. * flags - USB_FLAGS_SLEEP wait for resources to become * available. * pipe_handle - a pipe handle pointer. on a successful open, * a pipe_handle is returned in this pointer. * * Return values: * USB_SUCCESS - open succeeded. * USB_FAILURE - unspecified open failure or pipe is already open. * USB_NO_RESOURCES - no resources were available to complete the open. * USB_NO_BANDWIDTH - no bandwidth available (isoc/intr pipes). * USB_NOT_SUPPORTED - USB 3.0 or greater device * USB_* - refer to list of all possible return values in * this file */ int usb_pipe_open( dev_info_t *dip, usb_ep_descr_t *ep, usb_pipe_policy_t *pipe_policy, usb_flags_t flags, usb_pipe_handle_t *pipe_handle); int usb_pipe_xopen( dev_info_t *dip, usb_ep_xdescr_t *ep_xdesc, usb_pipe_policy_t *pipe_policy, usb_flags_t flags, usb_pipe_handle_t *pipe_handle); /* * usb_pipe_close(): * * Closes the pipe, releases resources and frees the pipe_handle. * Automatic polling, if active, will be terminated. * * Arguments: * dip - devinfo ptr. * pipe_handle - pipe handle. * flags - USB_FLAGS_SLEEP: * wait for resources, pipe * to become free, and all callbacks completed. * cb - If USB_FLAGS_SLEEP has not been specified, a * callback will be performed. * cb_arg - the 2nd argument of the callback. Note that the * pipehandle will be zeroed and therefore not passed. * * Notes: * * Pipe close always succeeds regardless whether USB_FLAGS_SLEEP has been * specified or not. An async close will always succeed if the hint in the * pipe policy has been correct about the max number of async requests * required. * In the unlikely event that no async requests can be queued, this * function will continue retrying before returning * * USBA prevents the client from submitting subsequent requests to a pipe * that is being closed. * Additional usb_pipe_close() requests on the same pipe causes USBA to * wait for the previous close(s) to complete. * * The pipe will not be destroyed until all activity on the pipe has * been drained, including outstanding request callbacks, async requests, * and other usb_pipe_*() calls. * * Calling usb_pipe_close() from a deferred callback (in kernel context) * with USB_FLAGS_SLEEP set, will cause deadlock */ void usb_pipe_close( dev_info_t *dip, usb_pipe_handle_t pipe_handle, usb_flags_t flags, void (*cb)( usb_pipe_handle_t ph, usb_opaque_t arg, /* cb arg */ int rval, usb_cb_flags_t flags), usb_opaque_t cb_arg); /* * usb_pipe_drain_reqs * this function blocks until there are no more requests * owned by this dip on the pipe * * Arguments: * dip - devinfo pointer * pipe_handle - opaque pipe handle * timeout - timeout in seconds * flags - USB_FLAGS_SLEEP: * wait for completion. * cb - if USB_FLAGS_SLEEP has not been specified * this callback function will be called on * completion. This callback may be NULL * and no notification of completion will then * be provided. * cb_arg - 2nd argument to callback function. * * callback and callback_arg should be NULL if USB_FLAGS_SLEEP has * been specified * * Returns: * USB_SUCCESS - pipe successfully reset or request queued * USB_FAILURE - timeout * USB_INVALID_PIPE - pipe is invalid or already closed * USB_INVALID_CONTEXT - called from interrupt context * USB_INVALID_ARGS - invalid arguments * USB_* - refer to return values defines in this file */ int usb_pipe_drain_reqs( dev_info_t *dip, usb_pipe_handle_t pipe_handle, uint_t time, usb_flags_t flags, void (*cb)( usb_pipe_handle_t ph, usb_opaque_t arg, /* cb arg */ int rval, usb_cb_flags_t flags), usb_opaque_t cb_arg); /* * Resetting a pipe: Refer to USB 2.0/10.5.2.2 * The pipe's requests are retired and the pipe is cleared. The host state * is moved to active. If the reflected endpoint state needs to be changed, * that must be explicitly requested by the client driver. The reset * completes after all request callbacks have been completed. * * Arguments: * dip - devinfo pointer. * pipe_handle - pipe handle. * flags - USB_FLAGS_SLEEP: * wait for completion. * cb - if USB_FLAGS_SLEEP has not been specified * this callback function will be called on * completion. This callback may be NULL * and no notification of completion will then * be provided. * cb_arg - 2nd argument to callback function. * * callback and callback_arg should be NULL if USB_FLAGS_SLEEP has * been specified * * Note: Completion notification may be *before* all async request threads * have completed but *after* all immediate callbacks have completed. */ void usb_pipe_reset( dev_info_t *dip, usb_pipe_handle_t pipe_handle, usb_flags_t usb_flags, void (*cb)( usb_pipe_handle_t ph, usb_opaque_t arg, int rval, usb_cb_flags_t flags), usb_opaque_t cb_arg); /* * The client driver can store a private data pointer in the * pipe_handle. * * return values: * USB_SUCCESS - success * USB_FAILURE - unspecified failure */ int usb_pipe_set_private( usb_pipe_handle_t pipe_handle, usb_opaque_t data); usb_opaque_t usb_pipe_get_private( usb_pipe_handle_t pipe_handle); /* * *************************************************************************** * Transfer request definitions and functions * *************************************************************************** */ /* * USB xfer request attributes. * Set by the client driver, more than one may be set * * SHORT_XFER_OK if less data is transferred than specified, no error is * returned. * AUTOCLEARING if there is an exception, the pipe will be reset first * and a functional stall cleared before a callback is done. * PIPE_RESET if there is an exception, the pipe will be reset only * ONE_XFER polling will automatically stop on the first callback. * ISOC_START_FRAME use startframe specified. * USB_ATTRS_ISOC_XFER_ASAP let the host controller decide on the first * available frame. * * USB_ATTRS_ISOC_START_FRAME and USB_ATTRS_ISOC_XFER_ASAP are mutually * exclusive * * combinations of flag and attributes: * * usb_flags usb_req_attrs semantics * --------------------------------------------------------- * SLEEP USB_ATTRS_SHORT_XFER_OK legal for IN pipes * SLEEP USB_ATTRS_AUTOCLEARING legal * SLEEP USB_ATTRS_PIPE_RESET legal * SLEEP USB_ATTRS_ONE_XFER legal for interrupt IN pipes * SLEEP USB_ATTRS_ISOC_START_FRAME illegal * SLEEP USB_ATTRS_ISOC_XFER_ASAP illegal * * noSLEEP USB_ATTRS_SHORT_XFER_OK legal for all IN pipes * noSLEEP USB_ATTRS_AUTOCLEARING legal * noSLEEP USB_ATTRS_PIPE_RESET legal * noSLEEP USB_ATTRS_ONE_XFER legal * noSLEEP USB_ATTRS_ISOC_START_FRAME legal * noSLEEP USB_ATTRS_ISOC_XFER_ASAP legal */ typedef enum { USB_ATTRS_NONE = 0, /* only ctrl/bulk/intr IN pipes */ USB_ATTRS_SHORT_XFER_OK = 0x01, /* short data xfer is ok */ USB_ATTRS_PIPE_RESET = 0x02, /* reset pipe only on exc */ USB_ATTRS_AUTOCLEARING = 0x12, /* autoclear STALLs */ /* intr pipes only: one poll with data */ USB_ATTRS_ONE_XFER = 0x100, /* only for isoch pipe */ USB_ATTRS_ISOC_START_FRAME = 0x200, /* Starting frame# specified */ USB_ATTRS_ISOC_XFER_ASAP = 0x400 /* HCD decides START_FRAME# */ } usb_req_attrs_t; /* * Note: client drivers are required to provide data buffers (mblks) for most * requests * IN OUT * ctlr request if wLength > 0 if wLength > 0 * bulk request yes yes * intr request no yes * isoc request no yes */ /* * =========================================================================== * USB control request management * =========================================================================== */ /* * A client driver allocates and uses the usb_ctrl_req_t for all control * pipe requests. * * Direction of the xfer will be determined based on the bmRequestType. * * NULL callbacks are permitted, timeout = 0 indicates infinite timeout. * All timeouts are in seconds. * * All fields are initialized by client except for data on IN request * in which case the client is responsible for deallocating. * * Control requests may be reused. The client driver is responsible * for reinitializing some fields, eg data read/write pointers. * * Control requests can be queued. */ typedef struct usb_ctrl_req { uint8_t ctrl_bmRequestType; /* characteristics of request */ uint8_t ctrl_bRequest; /* specific request */ uint16_t ctrl_wValue; /* varies according to request */ uint16_t ctrl_wIndex; /* index or offset */ uint16_t ctrl_wLength; /* number of bytes to xfer */ mblk_t *ctrl_data; /* the data for the data phase */ /* IN: allocated by HCD */ /* OUT: allocated by client */ uint_t ctrl_timeout; /* how long before HCD retires req */ usb_opaque_t ctrl_client_private; /* for client private info */ usb_req_attrs_t ctrl_attributes; /* attributes for this req */ /* * callback function for control pipe requests * * a normal callback will be done upon: * - successful completion of a control pipe request * * callback arguments are: * - the pipe_handle * - usb_ctrl_req_t pointer */ void (*ctrl_cb)(usb_pipe_handle_t ph, struct usb_ctrl_req *req); /* * exception callback function for control pipe * * a exception callback will be done upon: * - an exception/error (all types) * - partial xfer of data unless SHORT_XFER_OK has been set * * callback arguments are: * - the pipe_handle * - usb_ctrl_req_t pointer * * if USB_ATTRS_AUTOCLEARING was set, autoclearing will be attempted * and usb_cb_flags_t in usb_ctrl_req may indicate what was done */ void (*ctrl_exc_cb)(usb_pipe_handle_t ph, struct usb_ctrl_req *req); /* set by USBA/HCD on completion */ usb_cr_t ctrl_completion_reason; /* set by HCD */ usb_cb_flags_t ctrl_cb_flags; /* Callback context / handling flgs */ } usb_ctrl_req_t; /* * In the setup packet, the descriptor type is passed in the high byte of the * wValue field. * descriptor types: */ #define USB_DESCR_TYPE_SETUP_DEV 0x0100 #define USB_DESCR_TYPE_SETUP_CFG 0x0200 #define USB_DESCR_TYPE_SETUP_STRING 0x0300 #define USB_DESCR_TYPE_SETUP_IF 0x0400 #define USB_DESCR_TYPE_SETUP_EP 0x0500 #define USB_DESCR_TYPE_SETUP_DEV_QLF 0x0600 #define USB_DESCR_TYPE_SETUP_OTHER_SPEED_CFG 0x0700 #define USB_DESCR_TYPE_SETUP_IF_PWR 0x0800 #define USB_DESCR_TYPE_DEV 0x01 #define USB_DESCR_TYPE_CFG 0x02 #define USB_DESCR_TYPE_STRING 0x03 #define USB_DESCR_TYPE_IF 0x04 #define USB_DESCR_TYPE_EP 0x05 #define USB_DESCR_TYPE_DEV_QLF 0x06 #define USB_DESCR_TYPE_OTHER_SPEED_CFG 0x07 #define USB_DESCR_TYPE_IF_PWR 0x08 #define USB_DESCR_TYPE_IA 0x0B #define USB_DESCR_TYPE_WA 0x21 #define USB_DESCR_TYPE_RPIPE 0x22 #define USB_DESCR_TYPE_HUB 0x29 /* Wireless USB extension, refer to WUSB 1.0/7.4 */ #define USB_DESCR_TYPE_SECURITY 0x0c #define USB_DESCR_TYPE_KEY 0x0d #define USB_DESCR_TYPE_ENCRYPTION 0x0e #define USB_DESCR_TYPE_BOS 0x0f #define USB_DESCR_TYPE_DEV_CAPABILITY 0x10 #define USB_DESCR_TYPE_WIRELESS_EP_COMP 0x11 #define USB_WA_DESCR_SIZE 14 #define USB_RPIPE_DESCR_SIZE 28 /* * USB 3.0 Super Speed specifics. See USB 3.1/9.4. */ #define USB_DESCR_TYPE_SS_HUB 0x2A #define USB_DESCR_TYPE_SS_EP_COMP 0x30 #define USB_DESCR_TYPE_SS_ISO_EP_COMP 0x31 /* * device request type */ #define USB_DEV_REQ_HOST_TO_DEV 0x00 #define USB_DEV_REQ_DEV_TO_HOST 0x80 #define USB_DEV_REQ_DIR_MASK 0x80 #define USB_DEV_REQ_TYPE_STANDARD 0x00 #define USB_DEV_REQ_TYPE_CLASS 0x20 #define USB_DEV_REQ_TYPE_VENDOR 0x40 #define USB_DEV_REQ_TYPE_MASK 0x60 #define USB_DEV_REQ_RCPT_DEV 0x00 #define USB_DEV_REQ_RCPT_IF 0x01 #define USB_DEV_REQ_RCPT_EP 0x02 #define USB_DEV_REQ_RCPT_OTHER 0x03 #define USB_DEV_REQ_RCPT_MASK 0x03 /* Wire adapter class extension for request recipient */ #define USB_DEV_REQ_RCPT_PORT 0x04 #define USB_DEV_REQ_RCPT_RPIPE 0x05 /* * device request */ #define USB_REQ_GET_STATUS 0x00 #define USB_REQ_CLEAR_FEATURE 0x01 #define USB_REQ_SET_FEATURE 0x03 #define USB_REQ_SET_ADDRESS 0x05 #define USB_REQ_GET_DESCR 0x06 #define USB_REQ_SET_DESCR 0x07 #define USB_REQ_GET_CFG 0x08 #define USB_REQ_SET_CFG 0x09 #define USB_REQ_GET_IF 0x0a #define USB_REQ_SET_IF 0x0b #define USB_REQ_SYNC_FRAME 0x0c /* Wireless USB extension, refer to WUSB 1.0/7.3.1 */ #define USB_REQ_SET_ENCRYPTION 0x0d #define USB_REQ_GET_ENCRYPTION 0x0e #define USB_REQ_RPIPE_ABORT 0x0e #define USB_REQ_SET_HANDSHAKE 0x0f #define USB_REQ_RPIPE_RESET 0x0f #define USB_REQ_GET_HANDSHAKE 0x10 #define USB_REQ_SET_CONNECTION 0x11 #define USB_REQ_SET_SECURITY_DATA 0x12 #define USB_REQ_GET_SECURITY_DATA 0x13 #define USB_REQ_SET_WUSB_DATA 0x14 #define USB_REQ_LOOPBACK_DATA_WRITE 0x15 #define USB_REQ_LOOPBACK_DATA_READ 0x16 #define USB_REQ_SET_INTERFACE_DS 0x17 /* language ID for string descriptors */ #define USB_LANG_ID 0x0409 /* * Standard Feature Selectors */ #define USB_EP_HALT 0x0000 #define USB_DEV_REMOTE_WAKEUP 0x0001 #define USB_DEV_TEST_MODE 0x0002 /* Wireless USB extension, refer to WUSB 1.0/7.3.1 */ #define USB_DEV_WUSB 0x0003 /* * Allocate usb control request * * Arguments: * dip - dev_info pointer of the client driver * len - length of "data" for this control request. * if 0, no mblk is alloc'ed * flags - USB_FLAGS_SLEEP: Sleep if resources are not available * * Return Values: * usb_ctrl_req_t pointer on success, NULL on failure * * Implementation NOTE: the dip allows checking on detach for memory leaks */ usb_ctrl_req_t *usb_alloc_ctrl_req( dev_info_t *dip, size_t len, usb_flags_t flags); /* * free USB control request */ void usb_free_ctrl_req( usb_ctrl_req_t *reqp); /* * usb_pipe_ctrl_xfer(); * Client driver calls this function to issue the control * request to the USBA which will queue or transport it to the device * * Arguments: * pipe_handle - control pipe pipehandle (obtained via usb_pipe_open() * reqp - pointer to control request * flags - USB_FLAGS_SLEEP: * wait for the request to complete * * Return values: * USB_SUCCESS - successfully queued (no sleep) or successfully * completed (with sleep specified) * USB_FAILURE - failure * USB_NO_RESOURCES - no resources */ int usb_pipe_ctrl_xfer(usb_pipe_handle_t pipe_handle, usb_ctrl_req_t *reqp, usb_flags_t flags); /* * --------------------------------------------------------------------------- * Wrapper function which allocates and deallocates a request structure, and * performs a control transfer. * --------------------------------------------------------------------------- */ /* * Setup arguments for usb_pipe_ctrl_xfer_wait: * * bmRequestType - characteristics of request * bRequest - specific request * wValue - varies according to request * wIndex - index or offset * wLength - number of bytes to xfer * attrs - required request attributes * data - pointer to pointer to data * IN: HCD will allocate data * OUT: clients driver allocates data */ typedef struct usb_ctrl_setup { uchar_t bmRequestType; uchar_t bRequest; uint16_t wValue; uint16_t wIndex; uint16_t wLength; usb_req_attrs_t attrs; } usb_ctrl_setup_t; /* * usb_pipe_ctrl_xfer_wait(): * for simple synchronous control transactions this wrapper function * will perform the allocation, xfer, and deallocation. * USB_ATTRS_AUTOCLEARING will be enabled * * Arguments: * pipe_handle - control pipe pipehandle (obtained via usb_pipe_open()) * setup - contains pointer to client's devinfo, * setup descriptor params, attributes and data * completion_reason - completion status. * cb_flags - request completions flags. * flags - none. * * Return Values: * USB_SUCCESS - request successfully executed. * USB_FAILURE - request failed. * USB_* - refer to list of all possible return values in * this file * * NOTES: * - in the case of failure, the client should check completion_reason and * and cb_flags and determine further recovery action * - the client should check data and if non-zero, free the data on * completion */ int usb_pipe_ctrl_xfer_wait( usb_pipe_handle_t pipe_handle, usb_ctrl_setup_t *setup, mblk_t **data, usb_cr_t *completion_reason, usb_cb_flags_t *cb_flags, usb_flags_t flags); /* * --------------------------------------------------------------------------- * Some utility defines and wrapper functions for standard control requests. * --------------------------------------------------------------------------- */ /* * USB STATUS request types and sizes. */ #define USB_GET_STATUS_STANDARD 0 #define USB_GET_STATUS_PTM 1 #define USB_GET_STATUS_LEN 2 #define USB_GET_STATUS_PTM_LEN 4 /* * Status bits returned by a usb_get_status() for a STATUS_STANDARD request. */ #define USB_DEV_SLF_PWRD_STATUS 1 /* Supports Self Power */ #define USB_DEV_RWAKEUP_STATUS 2 /* Remote Wakeup Enabled */ #define USB_DEV_BAT_PWRD_STATUS 4 /* Battery Powered */ #define USB_EP_HALT_STATUS 1 /* Endpoint is Halted */ #define USB_IF_STATUS 0 /* Interface Status is 0 */ /* * wrapper function returning status of device, interface, or endpoint * * Arguments: * dip - devinfo pointer. * ph - pipe handle * type - bmRequestType to be used * what - 0 for device, otherwise interface or ep number * status - pointer to returned status. * flags - USB_FLAGS_SLEEP (mandatory) * * Return Values: * valid usb_status_t or USB_FAILURE * */ int usb_get_status( dev_info_t *dip, usb_pipe_handle_t ph, uint_t type, /* bmRequestType */ uint_t what, /* 0, interface, endpoint number */ uint16_t *status, usb_flags_t flags); /* * function for clearing feature of device, interface, or endpoint * * Arguments: * dip - devinfo pointer. * type - bmRequestType to be used * feature - feature to be cleared * what - 0 for device, otherwise interface or ep number * flags - USB_FLAGS_SLEEP (mandatory) * cb - if USB_FLAGS_SLEEP has not been specified * this callback function will be called on * completion. This callback may be NULL * and no notification of completion will then * be provided. * cb_arg - 2nd argument to callback function. * * Return Values: * USB_SUCCESS clearing feature succeeded * USB_FAILURE clearing feature failed * USB_* refer to list of all possible return values in * this file */ int usb_clr_feature( dev_info_t *dip, uint_t type, /* bmRequestType */ uint_t feature, uint_t what, /* 0, interface, endpoint number */ usb_flags_t flags, void (*cb)( usb_pipe_handle_t ph, usb_opaque_t arg, int rval, usb_cb_flags_t flags), usb_opaque_t cb_arg); /* * usb_set_cfg(): * Sets the configuration. Use this function with caution as * the framework is normally responsible for configuration changes. * Changing configuration will fail if pipes are still open or * when invoked from a driver bound to an interface on a composite * device. This function access the device and blocks. * * Arguments: * dip - devinfo pointer. * cfg_index - Index of configuration to set. Corresponds to * index in the usb_client_dev_data_t tree of * configurations. See usb_client_dev_data_t(9F). * usb_flags - USB_FLAGS_SLEEP: * wait for completion. * cb - if USB_FLAGS_SLEEP has not been specified * this callback function will be called on * completion. This callback may be NULL * and no notification of completion will then * be provided. * cb_arg - 2nd argument to callback function. * * callback and callback_arg should be NULL if USB_FLAGS_SLEEP has * been specified * * Return Values: * USB_SUCCESS: new configuration was set or async request * submitted successfully. * USB_FAILURE: new configuration could not be set because * it may been illegal configuration or this * caller was not allowed to change configs or * pipes were still open or async request * could not be submitted. * USB_* refer to list of all possible return values in * this file * * the pipe handle argument in the callback will be the default pipe handle */ int usb_set_cfg( dev_info_t *dip, uint_t cfg_index, usb_flags_t usb_flags, void (*cb)( usb_pipe_handle_t ph, usb_opaque_t arg, int rval, usb_cb_flags_t flags), usb_opaque_t cb_arg); /* * usb_get_cfg: * dip - pointer to devinfo node * cfgval - pointer to cfgval * usb_flags - none, will always block * * return values: * USB_SUCCESS - current cfg value is returned to cfgval * USB_* - refer to list of all possible return values in * this file */ int usb_get_cfg( dev_info_t *dip, uint_t *cfgval, usb_flags_t usb_flags); /* * The following functions set or get the alternate interface * setting. * * usb_set_alt_if: * dip - pointer to devinfo node * interface - interface * alt_number - alternate to set to * usb_flags - USB_FLAGS_SLEEP: * wait for completion. * cb - if USB_FLAGS_SLEEP has not been specified * this callback function will be called on * completion. This callback may be NULL * and no notification of completion will then * be provided. * cb_arg - 2nd argument to callback function. * * callback and callback_arg should be NULL if USB_FLAGS_SLEEP has * been specified * * the pipe handle argument in the callback will be the default pipe handle * * return values: * USB_SUCCESS: alternate was set or async request was * submitted. * USB_FAILURE: alternate could not be set because pipes * were still open or some access error occurred * or an invalid alt if value was passed or * async request could not be submitted * USB_INVALID_PERM the driver does not own the device or the interface * USB_* refer to list of all possible return values in * this file */ int usb_set_alt_if( dev_info_t *dip, uint_t interface, uint_t alt_number, usb_flags_t usb_flags, void (*cb)( usb_pipe_handle_t ph, usb_opaque_t arg, int rval, usb_cb_flags_t flags), usb_opaque_t cb_arg); /* flags must be USB_FLAGS_SLEEP, and this function will block */ int usb_get_alt_if( dev_info_t *dip, uint_t if_number, uint_t *alt_number, usb_flags_t flags); /* * =========================================================================== * USB bulk request management * =========================================================================== */ /* * A client driver allocates/uses the usb_bulk_req_t for bulk pipe xfers. * * NOTES: * - bulk pipe sharing is not supported * - semantics of combinations of flag and attributes: * * flags Type attributes data timeout semantics * ---------------------------------------------------------------- * x x x == NULL x illegal * * no sleep IN x != NULL 0 fill buffer, no timeout * callback when xfer-len has * been xferred * no sleep IN x != NULL > 0 fill buffer, with timeout * callback when xfer-len has * been xferred * * sleep IN x != NULL 0 fill buffer, no timeout * unblock when xfer-len has * been xferred * no callback * sleep IN x != NULL > 0 fill buffer, with timeout * unblock when xfer-len has * been xferred or timeout * no callback * * X OUT SHORT_XFER_OK x x illegal * * no sleep OUT x != NULL 0 empty buffer, no timeout * callback when xfer-len has * been xferred * no sleep OUT x != NULL > 0 empty buffer, with timeout * callback when xfer-len has * been xferred or timeout * * sleep OUT x != NULL 0 empty buffer, no timeout * unblock when xfer-len has * been xferred * no callback * sleep OUT x != NULL > 0 empty buffer, with timeout * unblock when xfer-len has * been xferred or timeout * no callback * * - bulk_len and bulk_data must be > 0. SHORT_XFER_OK is not applicable. * * - multiple bulk requests can be queued * * - Splitting large Bulk xfer: * The HCD driver, due to internal constraints, can only do a limited size bulk * data xfer per request. The current limitations are 32K for UHCI and 128K * for OHCI. So, a client driver may first determine this limitation (by * calling the USBA interface usb_pipe_bulk_transfer_size()); and restrict * itself to doing xfers in multiples of this fixed size. This forces a client * driver to do data xfers in a loop for a large request, splitting it into * multiple chunks of fixed size. */ typedef struct usb_bulk_req { uint_t bulk_len; /* number of bytes to xfer */ mblk_t *bulk_data; /* the data for the data phase */ /* IN: allocated by HCD */ /* OUT: allocated by client */ uint_t bulk_timeout; /* xfer timeout value in secs */ usb_opaque_t bulk_client_private; /* Client specific information */ usb_req_attrs_t bulk_attributes; /* xfer-attributes */ /* Normal Callback function (For synch xfers) */ void (*bulk_cb)(usb_pipe_handle_t ph, struct usb_bulk_req *req); /* Exception Callback function (For asynch xfers) */ void (*bulk_exc_cb)(usb_pipe_handle_t ph, struct usb_bulk_req *req); /* set by USBA/HCD on completion */ usb_cr_t bulk_completion_reason; /* set by HCD */ usb_cb_flags_t bulk_cb_flags; /* Callback context / handling flgs */ } usb_bulk_req_t; /* * Allocate/free usb bulk request * * Arguments: * dip - pointer to dev_info_t of the client driver * len - 0 or length of mblk to be allocated * flags - USB_FLAGS_SLEEP: * wait for resources * * Return Values: * usb_bulk_req_t on success, NULL on failure */ usb_bulk_req_t *usb_alloc_bulk_req( dev_info_t *dip, size_t len, usb_flags_t flags); void usb_free_bulk_req( usb_bulk_req_t *reqp); /* * usb_pipe_bulk_xfer(): * * Client drivers call this function to issue the bulk xfer to the USBA * which will queue or transfer it to the device * * Arguments: * pipe_handle - bulk pipe handle (obtained via usb_pipe_open() * reqp - pointer to bulk data xfer request (IN or OUT) * flags - USB_FLAGS_SLEEP: * wait for the request to complete * * Return Values: * USB_SUCCESS - success * USB_FAILURE - unspecified failure * USB_NO_RESOURCES - no resources * */ int usb_pipe_bulk_xfer( usb_pipe_handle_t pipe_handle, usb_bulk_req_t *reqp, usb_flags_t flags); /* Get maximum bulk transfer size */ int usb_pipe_get_max_bulk_transfer_size( dev_info_t *dip, size_t *size); /* * =========================================================================== * USB interrupt pipe request management * =========================================================================== */ /* * A client driver allocates and uses the usb_intr_req_t for * all interrupt pipe transfers. * * USB_FLAGS_SLEEP indicates here just to wait for resources except * for ONE_XFER where we also wait for completion * * semantics flags and attribute combinations: * * Notes: * none attributes indicates neither ONE_XFER nor SHORT_XFER_OK * * flags Type attributes data timeout semantics * ---------------------------------------------------------------- * x IN x != NULL x illegal * x IN ONE_XFER=0 x !=0 illegal * * x IN ONE_XFER=0 NULL 0 continuous polling, * many callbacks * request is returned on * stop polling * * no sleep IN ONE_XFER NULL 0 one time poll, no timeout, * one callback * no sleep IN ONE_XFER NULL !=0 one time poll, with * timeout, one callback * * sleep IN ONE_XFER NULL 0 one time poll, no timeout, * no callback, * block for completion * sleep IN ONE_XFER NULL !=0 one time poll, with timeout, * no callback * block for completion * * x OUT x NULL x illegal * x OUT ONE_XFER x x illegal * x OUT SHORT_XFER_OK x x illegal * * x OUT none != NULL 0 xfer until data exhausted, * no timeout, one callback * x OUT none != NULL !=0 xfer until data exhausted, * with timeout, one callback * * - Reads (IN): * * The client driver does *not* provide a data buffer. * By default, a READ request would mean continuous polling for data IN. The * HCD typically reads "wMaxPacketSize" amount of 'periodic data'. A client * driver may force the HCD to read instead intr_len * amount of 'periodic data' (See section 1). * * The HCD issues a callback to the client after each polling interval if * it has read in some data. Note that the amount of data read IN is either * intr_len or 'wMaxPacketSize' in length. * * Normally, the HCD keeps polling interrupt pipe forever even if there is * no data to be read IN. A client driver may stop this polling by * calling usb_pipe_stop_intr_polling(). * * If a client driver chooses to pass USB_ATTRS_ONE_XFER as * 'xfer_attributes' the HCD will poll for data until some data is received. * HCD reads in the data and does a callback and stops polling for any more * data. In this case, the client driver need not explicitly call * usb_pipe_stop_intr_polling(). * * When continuous polling is stopped, the original request is returned with * USB_CR_STOPPED_POLLING. * * - Writes (OUT): * * A client driver provides the data buffer, and data, needed for intr write. * There is no continuous write mode, a la read (See previous section). * The USB_ATTRS_ONE_XFER attribute is illegal. * By default USBA keeps writing intr data until the provided data buffer * has been written out. The HCD does ONE callback to the client driver. * Queueing is supported. * Max size is 8k */ typedef struct usb_intr_req { uint_t intr_len; /* OUT: size of total xfer */ /* IN : packet size */ mblk_t *intr_data; /* the data for the data phase */ /* IN: allocated by HCD */ /* OUT: allocated by client */ usb_opaque_t intr_client_private; /* Client specific information */ uint_t intr_timeout; /* only with ONE TIME POLL, in secs */ usb_req_attrs_t intr_attributes; /* Normal callback function (For synch transfers) */ void (*intr_cb)(usb_pipe_handle_t ph, struct usb_intr_req *req); /* Exception callback function (For asynch transfers) */ void (*intr_exc_cb)(usb_pipe_handle_t ph, struct usb_intr_req *req); /* set by USBA/HCD on completion */ usb_cr_t intr_completion_reason; /* set by HCD */ usb_cb_flags_t intr_cb_flags; /* Callback context / handling flgs */ } usb_intr_req_t; /* * Allocate/free usb interrupt pipe request * * Arguments: * dip - pointer to dev_info_t of the client driver * reqp - pointer to request structure * len - 0 or length of mblk for this interrupt request * flags - USB_FLAGS_SLEEP: * Sleep if resources are not available * * Return Values: * usb_intr_req_t on success, NULL on failure */ usb_intr_req_t *usb_alloc_intr_req( dev_info_t *dip, size_t len, usb_flags_t flags); void usb_free_intr_req( usb_intr_req_t *reqp); /* * usb_pipe_intr_xfer(): * * Client drivers call this function to issue the intr xfer to USBA/HCD * which starts polling the device * * Arguments: * pipe_handle - interrupt pipe handle (obtained via usb_pipe_open() * reqp - pointer tothe interrupt pipe xfer request (IN or OUT) * flags - USB_FLAGS_SLEEP: * wait for resources to be available * * return values: * USB_SUCCESS - success * USB_FAILURE - unspecified failure * USB_NO_RESOURCES - no resources * * NOTE: start polling on an IN pipe that is already being polled is a NOP. * We don't queue requests on OUT pipe */ int usb_pipe_intr_xfer( usb_pipe_handle_t pipe_handle, usb_intr_req_t *req, usb_flags_t flags); /* * usb_pipe_stop_intr_polling(): * * Client drivers call this function to stop the automatic data-in/out transfers * without closing the pipe. * * If USB_FLAGS_SLEEP has been specified then this function will block until * polling has been stopped and all callbacks completed. If USB_FLAGS_SLEEP * has NOT been specified then polling is terminated when the original * request that started the polling has been returned with * USB_CR_STOPPED_POLLING * * Stop polling should never fail. * * Args:- * pipe_handle - interrupt pipe handle (obtained via usb_pipe_open()). * flags - USB_FLAGS_SLEEP: * wait for the resources to be available. */ void usb_pipe_stop_intr_polling( usb_pipe_handle_t pipe_handle, usb_flags_t flags); /* * =========================================================================== * USB isochronous xfer management * =========================================================================== */ /* * The usb frame number is an absolute number since boot and incremented * every 1 ms. */ typedef uint64_t usb_frame_number_t; /* * USB ischronous packet descriptor * * An array of structures of type usb_isoc_pkt_descr_t must be allocated and * initialized by the client driver using usb_alloc_isoc_req(). The client * driver must set isoc_pkt_length in each packet descriptor before submitting * the request. */ typedef struct usb_isoc_pkt_descr { /* * Set by the client driver, for all isochronous requests, to the * number of bytes to transfer in a frame. */ ushort_t isoc_pkt_length; /* * Set by HCD to actual number of bytes sent/received in frame. */ ushort_t isoc_pkt_actual_length; /* * Per frame status set by HCD both for the isochronous IN and OUT * requests. If any status is non-zero then isoc_error_count in the * isoc_req will be non-zero. */ usb_cr_t isoc_pkt_status; } usb_isoc_pkt_descr_t; /* * USB isochronous request * * The client driver allocates the usb_isoc_req_t before sending an * isochronous requests. * * USB_FLAGS_SLEEP indicates here just to wait for resources but not * to wait for completion * * Semantics of various combinations for data xfers: * * Note: attributes considered in this table are ONE_XFER, START_FRAME, * XFER_ASAP, SHORT_XFER * * * flags Type attributes data semantics * --------------------------------------------------------------------- * x x x NULL illegal * * x x ONE_XFER x illegal * * x IN x !=NULL continuous polling, * many callbacks * * x IN ISOC_START_FRAME !=NULL invalid if Current_frame# > * "isoc_frame_no" * x IN ISOC_XFER_ASAP !=NULL "isoc_frame_no" ignored. * HCD determines when to * insert xfer * * x OUT ONE_XFER x illegal * x OUT SHORT_XFER_OK x illegal * * x OUT ISOC_START_FRAME !=NULL invalid if Current_frame# > * "isoc_frame_no" * x OUT ISOC_XFER_ASAP !=NULL "isoc_frame_no" ignored. * HCD determines when to * insert xfer */ typedef struct usb_isoc_req { /* * Starting frame number will be set by the client driver in which * to begin this request. This frame number is used to synchronize * requests queued to different isochronous pipes. The frame number * is optional and client driver can skip starting frame number by * setting USB_ISOC_ATTRS_ASAP. In this case, HCD will decide starting * frame number for this isochronous request. If this field is 0, * then this indicates an invalid frame number. */ usb_frame_number_t isoc_frame_no; /* * Number of isochronous data packets. * The first field is set by client driver and may not exceed * the maximum number of entries in the usb isochronous packet * descriptors. */ ushort_t isoc_pkts_count; /* * The sum of all pkt lengths in the isoc request. Recommend to * set it to zero, so the sum of isoc_pkt_length in the * isoc_pkt_descr list will be used automatically and no check * will be apply to this element. */ ushort_t isoc_pkts_length; /* * This field will be set by HCD and this field indicates the number * of packets that completed with errors. */ ushort_t isoc_error_count; /* * Attributes specific to particular usb isochronous request. * Supported values are: USB_ATTRS_ISOC_START_FRAME, * USB_ATTRS_ISOC_XFER_ASAP. */ usb_req_attrs_t isoc_attributes; /* * Isochronous OUT: * allocated and set by client driver, freed and zeroed by HCD * on successful completion * Isochronous IN: * allocated and set by HCD, freed by client driver */ mblk_t *isoc_data; /* * The client driver specific private information. */ usb_opaque_t isoc_client_private; /* * Isochronous OUT: * must be allocated & initialized by client driver * Isochronous IN: * must be allocated by client driver */ struct usb_isoc_pkt_descr *isoc_pkt_descr; /* Normal callback function (For synch transfers) */ void (*isoc_cb)(usb_pipe_handle_t ph, struct usb_isoc_req *req); /* Exception callback function (For asynch transfers) */ void (*isoc_exc_cb)(usb_pipe_handle_t ph, struct usb_isoc_req *req); /* set by USBA/HCD on completion */ usb_cr_t isoc_completion_reason; /* set by HCD */ /* Callback context / handling flgs */ usb_cb_flags_t isoc_cb_flags; } usb_isoc_req_t; /* * Allocate/free usb isochronous resources * * isoc_pkts_count must be > 0 * * Arguments: * dip - client driver's devinfo pointer * isoc_pkts_count - number of pkts required * len - 0 or size of mblk to allocate * flags - USB_FLAGS_SLEEP: * wait for resources * * Return Values: * usb_isoc_req pointer or NULL */ usb_isoc_req_t *usb_alloc_isoc_req( dev_info_t *dip, uint_t isoc_pkts_count, size_t len, usb_flags_t flags); void usb_free_isoc_req( usb_isoc_req_t *usb_isoc_req); /* * Returns current usb frame number. */ usb_frame_number_t usb_get_current_frame_number( dev_info_t *dip); /* * Get maximum isochronous packets per usb isochronous request */ uint_t usb_get_max_pkts_per_isoc_request( dev_info_t *dip); /* * usb_pipe_isoc_xfer() * * Client drivers call this to issue the isoch xfer (IN and OUT) to the USBA * which starts polling the device. * * Arguments: * pipe_handle - isoc pipe handle (obtained via usb_pipe_open(). * reqp - pointer to the isochronous pipe IN xfer request * allocated by the client driver. * flags - USB_FLAGS_SLEEP: * wait for the resources to be available. * * return values: * USB_SUCCESS - success. * USB_FAILURE - unspecified failure. * USB_NO_RESOURCES - no resources. * USB_NO_FRAME_NUMBER - START_FRAME, ASAP flags not specified. * USB_INVALID_START_FRAME - Starting USB frame number invalid. * * Notes: * - usb_pipe_isoc_xfer on an IN pipe that is already being polled is a NOP. * - requests can be queued on an OUT pipe. */ int usb_pipe_isoc_xfer( usb_pipe_handle_t pipe_handle, usb_isoc_req_t *reqp, usb_flags_t flags); /* * usb_pipe_stop_isoc_polling(): * * Client drivers call this function to stop the automatic data-in/out * transfers without closing the isoc pipe. * * If USB_FLAGS_SLEEP has been specified then this function will block until * polling has been stopped and all callbacks completed. If USB_FLAGS_SLEEP * has NOT been specified then polling is terminated when the original * request that started the polling has been returned with * USB_CR_STOPPED_POLLING * * Stop polling should never fail. * * Arguments: * pipe_handle - isoc pipe handle (obtained via usb_pipe_open(). * flags - USB_FLAGS_SLEEP: * wait for polling to be stopped and all * callbacks completed. */ void usb_pipe_stop_isoc_polling( usb_pipe_handle_t pipe_handle, usb_flags_t flags); /* * *************************************************************************** * USB device power management: * *************************************************************************** */ /* * * As any usb device will have a max of 4 possible power states * the #define for them are provided below with mapping to the * corresponding OS power levels. */ #define USB_DEV_PWR_D0 USB_DEV_OS_FULL_PWR #define USB_DEV_PWR_D1 5 #define USB_DEV_PWR_D2 6 #define USB_DEV_PWR_D3 USB_DEV_OS_PWR_OFF #define USB_DEV_OS_PWR_0 0 #define USB_DEV_OS_PWR_1 1 #define USB_DEV_OS_PWR_2 2 #define USB_DEV_OS_PWR_3 3 #define USB_DEV_OS_PWR_OFF USB_DEV_OS_PWR_0 #define USB_DEV_OS_FULL_PWR USB_DEV_OS_PWR_3 /* Bit Masks for Power States */ #define USB_DEV_OS_PWRMASK_D0 1 #define USB_DEV_OS_PWRMASK_D1 2 #define USB_DEV_OS_PWRMASK_D2 4 #define USB_DEV_OS_PWRMASK_D3 8 /* conversion for OS to Dx levels */ #define USB_DEV_OS_PWR2USB_PWR(l) (USB_DEV_OS_FULL_PWR - (l)) /* from OS level to Dx mask */ #define USB_DEV_PWRMASK(l) (1 << (USB_DEV_OS_FULL_PWR - (l))) /* Macro to check valid power level */ #define USB_DEV_PWRSTATE_OK(state, level) \ (((state) & USB_DEV_PWRMASK((level))) == 0) int usb_handle_remote_wakeup( dev_info_t *dip, int cmd); /* argument to usb_handle_remote wakeup function */ #define USB_REMOTE_WAKEUP_ENABLE 1 #define USB_REMOTE_WAKEUP_DISABLE 2 int usb_create_pm_components( dev_info_t *dip, uint_t *pwrstates); /* * *************************************************************************** * System event registration * *************************************************************************** */ /* Functions for registering hotplug callback functions. */ int usb_register_hotplug_cbs( dev_info_t *dip, int (*disconnect_event_handler)(dev_info_t *dip), int (*reconnect_event_handler)(dev_info_t *dip)); void usb_unregister_hotplug_cbs(dev_info_t *dip); /* * Reset_level determines the extent to which the device is reset, * It has the following values: * * USB_RESET_LVL_REATTACH - The device is reset, the original driver is * detached and a new driver attaching process * is started according to the updated * compatible name. This reset level applies to * the firmware download with the descriptors * changing, or other situations in which the * device needs to be reenumerated. * * USB_RESET_LVL_DEFAULT - Default reset level. The device is reset, all * error status is cleared, the device state * machines and registers are also cleared and * need to be reinitialized in the driver. The * current driver remains attached. This reset * level applies to hardware error recovery, or * firmware download without descriptors * changing. */ typedef enum { USB_RESET_LVL_REATTACH = 0, USB_RESET_LVL_DEFAULT = 1 } usb_dev_reset_lvl_t; /* * usb_reset_device: * * Client drivers call this function to request hardware reset for themselves, * which may be required in some situations such as: * * 1) Some USB devices need the driver to upload firmware into devices' RAM * and initiate a hardware reset in order to activate the new firmware. * 2) Hardware reset may help drivers to recover devices from an error state * caused by physical or firmware defects. * * Arguments: * dip - pointer to devinfo of the client * reset_level - see above * * Return values: * USB_SUCCESS - With USB_RESET_LVL_DEFAULT: the device was reset * successfully. * - With USB_RESET_LVL_REATTACH: reenumeration was * started successfully or a previous reset is still * in progress. * USB_FAILURE - The state of the device's parent hub is invalid * (disconnected or suspended). * - Called when the driver being detached. * - The device failed to be reset with * USB_RESET_LVL_DEFAULT specified. * - Reenumeration failed to start up with * - USB_RESET_LVL_REATTACH specified. * USB_INVALID_ARGS - Invalid arguments. * USB_INVALID_PERM - The driver of the dip doesn't own entire device. * USB_BUSY - One or more pipes other than the default control * pipe are open on the device with * USB_RESET_LVL_DEFAULT specified. * USB_INVALID_CONTEXT - Called from interrupt context with * USB_RESET_LVL_DEFAULT specified. */ int usb_reset_device( dev_info_t *dip, usb_dev_reset_lvl_t reset_level); /* * ************************************************************************** * USB device driver registration and callback functions remaining * Contracted Project Private (for VirtualBox USB Device Capture) * ************************************************************************** */ /* * getting the device strings of manufacturer, product and serial number */ typedef struct usb_dev_str { char *usb_mfg; /* manufacturer string */ char *usb_product; /* product string */ char *usb_serialno; /* serial number string */ } usb_dev_str_t; /* * It is the callback function type for capture driver. * Arguments: * dev_descr - pointer to device descriptor * dev_str - pointer to device strings * path - pointer to device physical path * bus - USB bus address * port - USB port number * drv - capture driver name. * It is returned by the callback func. * Return Values: * USB_SUCCESS - VirtualBox will capture the device * USB_FAILURE - VirtualBox will not capture the device */ typedef int (*usb_dev_driver_callback_t)( usb_dev_descr_t *dev_descr, usb_dev_str_t *dev_str, char *path, int bus, int port, char **drv, void *reserved); /* * Register the callback function in the usba. * Argument: * dip - client driver's devinfo pointer * cb - callback function * * Return Values: * USB_SUCCESS - the registeration was successful * USB_FAILURE - the registeration failed */ int usb_register_dev_driver( dev_info_t *dip, usb_dev_driver_callback_t cb); /* * Unregister the callback function in the usba. */ void usb_unregister_dev_driver(dev_info_t *dip); /* * *************************************************************************** * USB Device and interface class, subclass and protocol codes * *************************************************************************** */ /* * Available device and interface class codes. * Those which are device class codes are noted. */ #define USB_CLASS_AUDIO 1 #define USB_CLASS_COMM 2 /* Communication device class and */ #define USB_CLASS_CDC_CTRL 2 /* CDC-control iface class, also 2 */ #define USB_CLASS_HID 3 #define USB_CLASS_PHYSICAL 5 #define USB_CLASS_IMAGE 6 #define USB_CLASS_PRINTER 7 #define USB_CLASS_MASS_STORAGE 8 #define USB_CLASS_HUB 9 /* Device class */ #define USB_CLASS_CDC_DATA 10 #define USB_CLASS_CCID 11 #define USB_CLASS_SECURITY 13 #define USB_CLASS_VIDEO 14 #define USB_CLASS_DIAG 220 /* Device class */ #define USB_CLASS_WIRELESS 224 #define USB_CLASS_MISC 239 /* Device class */ #define USB_CLASS_APP 254 #define USB_CLASS_VENDOR_SPEC 255 /* Device class */ #define USB_CLASS_PER_INTERFACE 0 /* Class info is at interface level */ /* Audio subclass. */ #define USB_SUBCLS_AUD_CONTROL 0x01 #define USB_SUBCLS_AUD_STREAMING 0x02 #define USB_SUBCLS_AUD_MIDI_STREAMING 0x03 /* Comms subclass. */ #define USB_SUBCLS_CDCC_DIRECT_LINE 0x01 #define USB_SUBCLS_CDCC_ABSTRCT_CTRL 0x02 #define USB_SUBCLS_CDCC_PHONE_CTRL 0x03 #define USB_SUBCLS_CDCC_MULTCNL_ISDN 0x04 #define USB_SUBCLS_CDCC_ISDN 0x05 #define USB_SUBCLS_CDCC_ETHERNET 0x06 #define USB_SUBCLS_CDCC_ATM_NETWORK 0x07 /* HID subclass and protocols. */ #define USB_SUBCLS_HID_1 1 #define USB_PROTO_HID_KEYBOARD 0x01 /* legacy keyboard */ #define USB_PROTO_HID_MOUSE 0x02 /* legacy mouse */ /* Printer subclass and protocols. */ #define USB_SUBCLS_PRINTER_1 1 #define USB_PROTO_PRINTER_UNI 0x01 /* Unidirectional interface */ #define USB_PROTO_PRINTER_BI 0x02 /* Bidirectional interface */ /* Mass storage subclasses and protocols. */ #define USB_SUBCLS_MS_RBC_T10 0x1 /* flash */ #define USB_SUBCLS_MS_SFF8020I 0x2 /* CD-ROM */ #define USB_SUBCLS_MS_QIC_157 0x3 /* tape */ #define USB_SUBCLS_MS_UFI 0x4 /* USB Floppy Disk Drive */ #define USB_SUBCLS_MS_SFF8070I 0x5 /* floppy */ #define USB_SUBCLS_MS_SCSI 0x6 /* transparent scsi */ #define USB_PROTO_MS_CBI_WC 0x00 /* USB CBI Proto w/cmp intr */ #define USB_PROTO_MS_CBI 0x01 /* USB CBI Protocol */ #define USB_PROTO_MS_ISD_1999_SILICN 0x02 /* ZIP Protocol */ #define USB_PROTO_MS_BULK_ONLY 0x50 /* USB Bulk Only Protocol */ /* Hub subclass and protocols */ #define USB_PROTO_HUB_FULL 0x00 /* Full Speed Protocol */ #define USB_PROTO_HUB_HIGH_STT 0x01 /* High Speed with STT */ #define USB_PROTO_HUB_HIGH_MTT 0x02 /* High Speed with MTT */ #define USB_PROTO_HUB_SUPER 0x03 /* SuperSpeed Protocol */ /* Application subclasses. */ #define USB_SUBCLS_APP_FIRMWARE 0x01 /* app spec f/w subclass */ #define USB_SUBCLS_APP_IRDA 0x02 /* app spec IrDa subclass */ #define USB_SUBCLS_APP_TEST 0x03 /* app spec test subclass */ /* Video subclasses */ #define USB_SUBCLS_VIDEO_CONTROL 0x01 /* video control */ #define USB_SUBCLS_VIDEO_STREAM 0x02 /* video stream */ #define USB_SUBCLS_VIDEO_COLLECTION 0x03 /* video interface collection */ /* Wireless controller subclasses and protocols, refer to WUSB 1.0 chapter 8 */ #define USB_SUBCLS_WUSB_1 0x01 /* RF controller */ #define USB_SUBCLS_WUSB_2 0x02 /* Wireless adapter */ #define USB_PROTO_WUSB_HWA 0x01 /* host wire adapter */ #define USB_PROTO_WUSB_DWA 0x02 /* device wire adapter */ #define USB_PROTO_WUSB_DWA_ISO 0x03 /* device wire adapter isoc */ #define USB_PROTO_WUSB_RC 0x02 /* UWB radio controller */ /* Association subclass and protocol, Association Model Supplement to WUSB1.0 */ #define USB_SUBCLS_CBAF 0x03 /* cable association */ #define USB_PROTO_CBAF 0x01 /* CBAF protocol */ /* Misc subclasses and protocols, refer to WUSB 1.0 chapter 8 */ #define USB_SUBCLS_MISC_COMMON 0x02 /* common class */ #define USB_PROTO_MISC_WA 0x02 /* multifunction wire adapter */ #ifdef __cplusplus } #endif #endif /* _SYS_USB_USBAI_H */