Derived from Linux kernel 2.6.27 Signed-off-by: Thomas Smits <ts.smits@gmail.com> Signed-off-by: Remy Bohmer <linux@bohmer.net>master
parent
70fccb3f24
commit
23cd138503
@ -0,0 +1,119 @@ |
||||
/*
|
||||
* usb/gadget/config.c -- simplify building config descriptors |
||||
* |
||||
* Copyright (C) 2003 David Brownell |
||||
* |
||||
* This program is free software; you can redistribute it and/or modify |
||||
* it under the terms of the GNU General Public License as published by |
||||
* the Free Software Foundation; either version 2 of the License, or |
||||
* (at your option) any later version. |
||||
* |
||||
* This program is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU General Public License |
||||
* along with this program; if not, write to the Free Software |
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
||||
* |
||||
* Ported to U-boot by: Thomas Smits <ts.smits@gmail.com> and |
||||
* Remy Bohmer <linux@bohmer.net> |
||||
*/ |
||||
|
||||
#include <common.h> |
||||
#include <asm/errno.h> |
||||
#include <linux/list.h> |
||||
#include <linux/string.h> |
||||
|
||||
#include <linux/usb/ch9.h> |
||||
#include <linux/usb/gadget.h> |
||||
|
||||
|
||||
/**
|
||||
* usb_descriptor_fillbuf - fill buffer with descriptors |
||||
* @buf: Buffer to be filled |
||||
* @buflen: Size of buf |
||||
* @src: Array of descriptor pointers, terminated by null pointer. |
||||
* |
||||
* Copies descriptors into the buffer, returning the length or a |
||||
* negative error code if they can't all be copied. Useful when |
||||
* assembling descriptors for an associated set of interfaces used |
||||
* as part of configuring a composite device; or in other cases where |
||||
* sets of descriptors need to be marshaled. |
||||
*/ |
||||
int |
||||
usb_descriptor_fillbuf(void *buf, unsigned buflen, |
||||
const struct usb_descriptor_header **src) |
||||
{ |
||||
u8 *dest = buf; |
||||
|
||||
if (!src) |
||||
return -EINVAL; |
||||
|
||||
/* fill buffer from src[] until null descriptor ptr */ |
||||
for (; NULL != *src; src++) { |
||||
unsigned len = (*src)->bLength; |
||||
|
||||
if (len > buflen) |
||||
return -EINVAL; |
||||
memcpy(dest, *src, len); |
||||
buflen -= len; |
||||
dest += len; |
||||
} |
||||
return dest - (u8 *)buf; |
||||
} |
||||
|
||||
|
||||
/**
|
||||
* usb_gadget_config_buf - builts a complete configuration descriptor |
||||
* @config: Header for the descriptor, including characteristics such |
||||
* as power requirements and number of interfaces. |
||||
* @desc: Null-terminated vector of pointers to the descriptors (interface, |
||||
* endpoint, etc) defining all functions in this device configuration. |
||||
* @buf: Buffer for the resulting configuration descriptor. |
||||
* @length: Length of buffer. If this is not big enough to hold the |
||||
* entire configuration descriptor, an error code will be returned. |
||||
* |
||||
* This copies descriptors into the response buffer, building a descriptor |
||||
* for that configuration. It returns the buffer length or a negative |
||||
* status code. The config.wTotalLength field is set to match the length |
||||
* of the result, but other descriptor fields (including power usage and |
||||
* interface count) must be set by the caller. |
||||
* |
||||
* Gadget drivers could use this when constructing a config descriptor |
||||
* in response to USB_REQ_GET_DESCRIPTOR. They will need to patch the |
||||
* resulting bDescriptorType value if USB_DT_OTHER_SPEED_CONFIG is needed. |
||||
*/ |
||||
int usb_gadget_config_buf( |
||||
const struct usb_config_descriptor *config, |
||||
void *buf, |
||||
unsigned length, |
||||
const struct usb_descriptor_header **desc |
||||
) |
||||
{ |
||||
struct usb_config_descriptor *cp = buf; |
||||
int len; |
||||
|
||||
/* config descriptor first */ |
||||
if (length < USB_DT_CONFIG_SIZE || !desc) |
||||
return -EINVAL; |
||||
*cp = *config; |
||||
|
||||
/* then interface/endpoint/class/vendor/... */ |
||||
len = usb_descriptor_fillbuf(USB_DT_CONFIG_SIZE + (u8*)buf, |
||||
length - USB_DT_CONFIG_SIZE, desc); |
||||
if (len < 0) |
||||
return len; |
||||
len += USB_DT_CONFIG_SIZE; |
||||
if (len > 0xffff) |
||||
return -EINVAL; |
||||
|
||||
/* patch up the config descriptor */ |
||||
cp->bLength = USB_DT_CONFIG_SIZE; |
||||
cp->bDescriptorType = USB_DT_CONFIG; |
||||
cp->wTotalLength = cpu_to_le16(len); |
||||
cp->bmAttributes |= USB_CONFIG_ATT_ONE; |
||||
return len; |
||||
} |
||||
|
@ -0,0 +1,306 @@ |
||||
/*
|
||||
* epautoconf.c -- endpoint autoconfiguration for usb gadget drivers |
||||
* |
||||
* Copyright (C) 2004 David Brownell |
||||
* |
||||
* This program is free software; you can redistribute it and/or modify |
||||
* it under the terms of the GNU General Public License as published by |
||||
* the Free Software Foundation; either version 2 of the License, or |
||||
* (at your option) any later version. |
||||
* |
||||
* This program is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU General Public License |
||||
* along with this program; if not, write to the Free Software |
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
||||
* |
||||
* Ported to U-boot by: Thomas Smits <ts.smits@gmail.com> and |
||||
* Remy Bohmer <linux@bohmer.net> |
||||
*/ |
||||
|
||||
#include <common.h> |
||||
#include <linux/usb/ch9.h> |
||||
#include <asm/errno.h> |
||||
#include <linux/usb/gadget.h> |
||||
#include "gadget_chips.h" |
||||
|
||||
#define isdigit(c) ('0' <= (c) && (c) <= '9') |
||||
|
||||
/* we must assign addresses for configurable endpoints (like net2280) */ |
||||
static unsigned epnum; |
||||
|
||||
// #define MANY_ENDPOINTS
|
||||
#ifdef MANY_ENDPOINTS |
||||
/* more than 15 configurable endpoints */ |
||||
static unsigned in_epnum; |
||||
#endif |
||||
|
||||
|
||||
/*
|
||||
* This should work with endpoints from controller drivers sharing the |
||||
* same endpoint naming convention. By example: |
||||
* |
||||
* - ep1, ep2, ... address is fixed, not direction or type |
||||
* - ep1in, ep2out, ... address and direction are fixed, not type |
||||
* - ep1-bulk, ep2-bulk, ... address and type are fixed, not direction |
||||
* - ep1in-bulk, ep2out-iso, ... all three are fixed |
||||
* - ep-* ... no functionality restrictions |
||||
* |
||||
* Type suffixes are "-bulk", "-iso", or "-int". Numbers are decimal. |
||||
* Less common restrictions are implied by gadget_is_*(). |
||||
* |
||||
* NOTE: each endpoint is unidirectional, as specified by its USB |
||||
* descriptor; and isn't specific to a configuration or altsetting. |
||||
*/ |
||||
static int |
||||
ep_matches ( |
||||
struct usb_gadget *gadget, |
||||
struct usb_ep *ep, |
||||
struct usb_endpoint_descriptor *desc |
||||
) |
||||
{ |
||||
u8 type; |
||||
const char *tmp; |
||||
u16 max; |
||||
|
||||
/* endpoint already claimed? */ |
||||
if (NULL != ep->driver_data) |
||||
return 0; |
||||
|
||||
/* only support ep0 for portable CONTROL traffic */ |
||||
type = desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK; |
||||
if (USB_ENDPOINT_XFER_CONTROL == type) |
||||
return 0; |
||||
|
||||
/* some other naming convention */ |
||||
if ('e' != ep->name[0]) |
||||
return 0; |
||||
|
||||
/* type-restriction: "-iso", "-bulk", or "-int".
|
||||
* direction-restriction: "in", "out". |
||||
*/ |
||||
if ('-' != ep->name[2]) { |
||||
tmp = strrchr (ep->name, '-'); |
||||
if (tmp) { |
||||
switch (type) { |
||||
case USB_ENDPOINT_XFER_INT: |
||||
/* bulk endpoints handle interrupt transfers,
|
||||
* except the toggle-quirky iso-synch kind |
||||
*/ |
||||
if ('s' == tmp[2]) // == "-iso"
|
||||
return 0; |
||||
/* for now, avoid PXA "interrupt-in";
|
||||
* it's documented as never using DATA1. |
||||
*/ |
||||
if (gadget_is_pxa (gadget) |
||||
&& 'i' == tmp [1]) |
||||
return 0; |
||||
break; |
||||
case USB_ENDPOINT_XFER_BULK: |
||||
if ('b' != tmp[1]) // != "-bulk"
|
||||
return 0; |
||||
break; |
||||
case USB_ENDPOINT_XFER_ISOC: |
||||
if ('s' != tmp[2]) // != "-iso"
|
||||
return 0; |
||||
} |
||||
} else { |
||||
tmp = ep->name + strlen (ep->name); |
||||
} |
||||
|
||||
/* direction-restriction: "..in-..", "out-.." */ |
||||
tmp--; |
||||
if (!isdigit (*tmp)) { |
||||
if (desc->bEndpointAddress & USB_DIR_IN) { |
||||
if ('n' != *tmp) |
||||
return 0; |
||||
} else { |
||||
if ('t' != *tmp) |
||||
return 0; |
||||
} |
||||
} |
||||
} |
||||
|
||||
/* endpoint maxpacket size is an input parameter, except for bulk
|
||||
* where it's an output parameter representing the full speed limit. |
||||
* the usb spec fixes high speed bulk maxpacket at 512 bytes. |
||||
*/ |
||||
max = 0x7ff & le16_to_cpu(desc->wMaxPacketSize); |
||||
switch (type) { |
||||
case USB_ENDPOINT_XFER_INT: |
||||
/* INT: limit 64 bytes full speed, 1024 high speed */ |
||||
if (!gadget->is_dualspeed && max > 64) |
||||
return 0; |
||||
/* FALLTHROUGH */ |
||||
|
||||
case USB_ENDPOINT_XFER_ISOC: |
||||
/* ISO: limit 1023 bytes full speed, 1024 high speed */ |
||||
if (ep->maxpacket < max) |
||||
return 0; |
||||
if (!gadget->is_dualspeed && max > 1023) |
||||
return 0; |
||||
|
||||
/* BOTH: "high bandwidth" works only at high speed */ |
||||
if ((desc->wMaxPacketSize & __constant_cpu_to_le16(3<<11))) { |
||||
if (!gadget->is_dualspeed) |
||||
return 0; |
||||
/* configure your hardware with enough buffering!! */ |
||||
} |
||||
break; |
||||
} |
||||
|
||||
/* MATCH!! */ |
||||
|
||||
/* report address */ |
||||
if (isdigit (ep->name [2])) { |
||||
u8 num = simple_strtol (&ep->name [2], NULL, 10); |
||||
desc->bEndpointAddress |= num; |
||||
#ifdef MANY_ENDPOINTS |
||||
} else if (desc->bEndpointAddress & USB_DIR_IN) { |
||||
if (++in_epnum > 15) |
||||
return 0; |
||||
desc->bEndpointAddress = USB_DIR_IN | in_epnum; |
||||
#endif |
||||
} else { |
||||
if (++epnum > 15) |
||||
return 0; |
||||
desc->bEndpointAddress |= epnum; |
||||
} |
||||
|
||||
/* report (variable) full speed bulk maxpacket */ |
||||
if (USB_ENDPOINT_XFER_BULK == type) { |
||||
int size = ep->maxpacket; |
||||
|
||||
/* min() doesn't work on bitfields with gcc-3.5 */ |
||||
if (size > 64) |
||||
size = 64; |
||||
desc->wMaxPacketSize = cpu_to_le16(size); |
||||
} |
||||
return 1; |
||||
} |
||||
|
||||
static struct usb_ep * |
||||
find_ep (struct usb_gadget *gadget, const char *name) |
||||
{ |
||||
struct usb_ep *ep; |
||||
|
||||
list_for_each_entry (ep, &gadget->ep_list, ep_list) { |
||||
if (0 == strcmp (ep->name, name)) |
||||
return ep; |
||||
} |
||||
return NULL; |
||||
} |
||||
|
||||
/**
|
||||
* usb_ep_autoconfig - choose an endpoint matching the descriptor |
||||
* @gadget: The device to which the endpoint must belong. |
||||
* @desc: Endpoint descriptor, with endpoint direction and transfer mode |
||||
* initialized. For periodic transfers, the maximum packet |
||||
* size must also be initialized. This is modified on success. |
||||
* |
||||
* By choosing an endpoint to use with the specified descriptor, this |
||||
* routine simplifies writing gadget drivers that work with multiple |
||||
* USB device controllers. The endpoint would be passed later to |
||||
* usb_ep_enable(), along with some descriptor. |
||||
* |
||||
* That second descriptor won't always be the same as the first one. |
||||
* For example, isochronous endpoints can be autoconfigured for high |
||||
* bandwidth, and then used in several lower bandwidth altsettings. |
||||
* Also, high and full speed descriptors will be different. |
||||
* |
||||
* Be sure to examine and test the results of autoconfiguration on your |
||||
* hardware. This code may not make the best choices about how to use the |
||||
* USB controller, and it can't know all the restrictions that may apply. |
||||
* Some combinations of driver and hardware won't be able to autoconfigure. |
||||
* |
||||
* On success, this returns an un-claimed usb_ep, and modifies the endpoint |
||||
* descriptor bEndpointAddress. For bulk endpoints, the wMaxPacket value |
||||
* is initialized as if the endpoint were used at full speed. To prevent |
||||
* the endpoint from being returned by a later autoconfig call, claim it |
||||
* by assigning ep->driver_data to some non-null value. |
||||
* |
||||
* On failure, this returns a null endpoint descriptor. |
||||
*/ |
||||
struct usb_ep * usb_ep_autoconfig ( |
||||
struct usb_gadget *gadget, |
||||
struct usb_endpoint_descriptor *desc |
||||
) |
||||
{ |
||||
struct usb_ep *ep; |
||||
u8 type; |
||||
|
||||
type = desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK; |
||||
|
||||
/* First, apply chip-specific "best usage" knowledge.
|
||||
* This might make a good usb_gadget_ops hook ... |
||||
*/ |
||||
if (gadget_is_net2280 (gadget) && type == USB_ENDPOINT_XFER_INT) { |
||||
/* ep-e, ep-f are PIO with only 64 byte fifos */ |
||||
ep = find_ep (gadget, "ep-e"); |
||||
if (ep && ep_matches (gadget, ep, desc)) |
||||
return ep; |
||||
ep = find_ep (gadget, "ep-f"); |
||||
if (ep && ep_matches (gadget, ep, desc)) |
||||
return ep; |
||||
|
||||
} else if (gadget_is_goku (gadget)) { |
||||
if (USB_ENDPOINT_XFER_INT == type) { |
||||
/* single buffering is enough */ |
||||
ep = find_ep (gadget, "ep3-bulk"); |
||||
if (ep && ep_matches (gadget, ep, desc)) |
||||
return ep; |
||||
} else if (USB_ENDPOINT_XFER_BULK == type |
||||
&& (USB_DIR_IN & desc->bEndpointAddress)) { |
||||
/* DMA may be available */ |
||||
ep = find_ep (gadget, "ep2-bulk"); |
||||
if (ep && ep_matches (gadget, ep, desc)) |
||||
return ep; |
||||
} |
||||
|
||||
} else if (gadget_is_sh (gadget) && USB_ENDPOINT_XFER_INT == type) { |
||||
/* single buffering is enough; maybe 8 byte fifo is too */ |
||||
ep = find_ep (gadget, "ep3in-bulk"); |
||||
if (ep && ep_matches (gadget, ep, desc)) |
||||
return ep; |
||||
|
||||
} else if (gadget_is_mq11xx (gadget) && USB_ENDPOINT_XFER_INT == type) { |
||||
ep = find_ep (gadget, "ep1-bulk"); |
||||
if (ep && ep_matches (gadget, ep, desc)) |
||||
return ep; |
||||
} |
||||
|
||||
/* Second, look at endpoints until an unclaimed one looks usable */ |
||||
list_for_each_entry (ep, &gadget->ep_list, ep_list) { |
||||
if (ep_matches (gadget, ep, desc)) |
||||
return ep; |
||||
} |
||||
|
||||
/* Fail */ |
||||
return NULL; |
||||
} |
||||
|
||||
/**
|
||||
* usb_ep_autoconfig_reset - reset endpoint autoconfig state |
||||
* @gadget: device for which autoconfig state will be reset |
||||
* |
||||
* Use this for devices where one configuration may need to assign |
||||
* endpoint resources very differently from the next one. It clears |
||||
* state such as ep->driver_data and the record of assigned endpoints |
||||
* used by usb_ep_autoconfig(). |
||||
*/ |
||||
void usb_ep_autoconfig_reset (struct usb_gadget *gadget) |
||||
{ |
||||
struct usb_ep *ep; |
||||
|
||||
list_for_each_entry (ep, &gadget->ep_list, ep_list) { |
||||
ep->driver_data = NULL; |
||||
} |
||||
#ifdef MANY_ENDPOINTS |
||||
in_epnum = 0; |
||||
#endif |
||||
epnum = 0; |
||||
} |
||||
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,219 @@ |
||||
/*
|
||||
* USB device controllers have lots of quirks. Use these macros in |
||||
* gadget drivers or other code that needs to deal with them, and which |
||||
* autoconfigures instead of using early binding to the hardware. |
||||
* |
||||
* This SHOULD eventually work like the ARM mach_is_*() stuff, driven by |
||||
* some config file that gets updated as new hardware is supported. |
||||
* (And avoiding all runtime comparisons in typical one-choice configs!) |
||||
* |
||||
* NOTE: some of these controller drivers may not be available yet. |
||||
* Some are available on 2.4 kernels; several are available, but not |
||||
* yet pushed in the 2.6 mainline tree. |
||||
* |
||||
* Ported to U-boot by: Thomas Smits <ts.smits@gmail.com> and |
||||
* Remy Bohmer <linux@bohmer.net> |
||||
*/ |
||||
#ifdef CONFIG_USB_GADGET_NET2280 |
||||
#define gadget_is_net2280(g) !strcmp("net2280", (g)->name) |
||||
#else |
||||
#define gadget_is_net2280(g) 0 |
||||
#endif |
||||
|
||||
#ifdef CONFIG_USB_GADGET_AMD5536UDC |
||||
#define gadget_is_amd5536udc(g) !strcmp("amd5536udc", (g)->name) |
||||
#else |
||||
#define gadget_is_amd5536udc(g) 0 |
||||
#endif |
||||
|
||||
#ifdef CONFIG_USB_GADGET_DUMMY_HCD |
||||
#define gadget_is_dummy(g) !strcmp("dummy_udc", (g)->name) |
||||
#else |
||||
#define gadget_is_dummy(g) 0 |
||||
#endif |
||||
|
||||
#ifdef CONFIG_USB_GADGET_PXA2XX |
||||
#define gadget_is_pxa(g) !strcmp("pxa2xx_udc", (g)->name) |
||||
#else |
||||
#define gadget_is_pxa(g) 0 |
||||
#endif |
||||
|
||||
#ifdef CONFIG_USB_GADGET_GOKU |
||||
#define gadget_is_goku(g) !strcmp("goku_udc", (g)->name) |
||||
#else |
||||
#define gadget_is_goku(g) 0 |
||||
#endif |
||||
|
||||
/* SH3 UDC -- not yet ported 2.4 --> 2.6 */ |
||||
#ifdef CONFIG_USB_GADGET_SUPERH |
||||
#define gadget_is_sh(g) !strcmp("sh_udc", (g)->name) |
||||
#else |
||||
#define gadget_is_sh(g) 0 |
||||
#endif |
||||
|
||||
/* not yet stable on 2.6 (would help "original Zaurus") */ |
||||
#ifdef CONFIG_USB_GADGET_SA1100 |
||||
#define gadget_is_sa1100(g) !strcmp("sa1100_udc", (g)->name) |
||||
#else |
||||
#define gadget_is_sa1100(g) 0 |
||||
#endif |
||||
|
||||
#ifdef CONFIG_USB_GADGET_LH7A40X |
||||
#define gadget_is_lh7a40x(g) !strcmp("lh7a40x_udc", (g)->name) |
||||
#else |
||||
#define gadget_is_lh7a40x(g) 0 |
||||
#endif |
||||
|
||||
/* handhelds.org tree (?) */ |
||||
#ifdef CONFIG_USB_GADGET_MQ11XX |
||||
#define gadget_is_mq11xx(g) !strcmp("mq11xx_udc", (g)->name) |
||||
#else |
||||
#define gadget_is_mq11xx(g) 0 |
||||
#endif |
||||
|
||||
#ifdef CONFIG_USB_GADGET_OMAP |
||||
#define gadget_is_omap(g) !strcmp("omap_udc", (g)->name) |
||||
#else |
||||
#define gadget_is_omap(g) 0 |
||||
#endif |
||||
|
||||
/* not yet ported 2.4 --> 2.6 */ |
||||
#ifdef CONFIG_USB_GADGET_N9604 |
||||
#define gadget_is_n9604(g) !strcmp("n9604_udc", (g)->name) |
||||
#else |
||||
#define gadget_is_n9604(g) 0 |
||||
#endif |
||||
|
||||
/* various unstable versions available */ |
||||
#ifdef CONFIG_USB_GADGET_PXA27X |
||||
#define gadget_is_pxa27x(g) !strcmp("pxa27x_udc", (g)->name) |
||||
#else |
||||
#define gadget_is_pxa27x(g) 0 |
||||
#endif |
||||
|
||||
#ifdef CONFIG_USB_GADGET_ATMEL_USBA |
||||
#define gadget_is_atmel_usba(g) !strcmp("atmel_usba_udc", (g)->name) |
||||
#else |
||||
#define gadget_is_atmel_usba(g) 0 |
||||
#endif |
||||
|
||||
#ifdef CONFIG_USB_GADGET_S3C2410 |
||||
#define gadget_is_s3c2410(g) !strcmp("s3c2410_udc", (g)->name) |
||||
#else |
||||
#define gadget_is_s3c2410(g) 0 |
||||
#endif |
||||
|
||||
#ifdef CONFIG_USB_GADGET_AT91 |
||||
#define gadget_is_at91(g) !strcmp("at91_udc", (g)->name) |
||||
#else |
||||
#define gadget_is_at91(g) 0 |
||||
#endif |
||||
|
||||
/* status unclear */ |
||||
#ifdef CONFIG_USB_GADGET_IMX |
||||
#define gadget_is_imx(g) !strcmp("imx_udc", (g)->name) |
||||
#else |
||||
#define gadget_is_imx(g) 0 |
||||
#endif |
||||
|
||||
#ifdef CONFIG_USB_GADGET_FSL_USB2 |
||||
#define gadget_is_fsl_usb2(g) !strcmp("fsl-usb2-udc", (g)->name) |
||||
#else |
||||
#define gadget_is_fsl_usb2(g) 0 |
||||
#endif |
||||
|
||||
/* Mentor high speed function controller */ |
||||
/* from Montavista kernel (?) */ |
||||
#ifdef CONFIG_USB_GADGET_MUSBHSFC |
||||
#define gadget_is_musbhsfc(g) !strcmp("musbhsfc_udc", (g)->name) |
||||
#else |
||||
#define gadget_is_musbhsfc(g) 0 |
||||
#endif |
||||
|
||||
/* Mentor high speed "dual role" controller, in peripheral role */ |
||||
#ifdef CONFIG_USB_GADGET_MUSB_HDRC |
||||
#define gadget_is_musbhdrc(g) !strcmp("musb_hdrc", (g)->name) |
||||
#else |
||||
#define gadget_is_musbhdrc(g) 0 |
||||
#endif |
||||
|
||||
/* from Montavista kernel (?) */ |
||||
#ifdef CONFIG_USB_GADGET_MPC8272 |
||||
#define gadget_is_mpc8272(g) !strcmp("mpc8272_udc", (g)->name) |
||||
#else |
||||
#define gadget_is_mpc8272(g) 0 |
||||
#endif |
||||
|
||||
#ifdef CONFIG_USB_GADGET_M66592 |
||||
#define gadget_is_m66592(g) !strcmp("m66592_udc", (g)->name) |
||||
#else |
||||
#define gadget_is_m66592(g) 0 |
||||
#endif |
||||
|
||||
|
||||
// CONFIG_USB_GADGET_SX2
|
||||
// CONFIG_USB_GADGET_AU1X00
|
||||
// ...
|
||||
|
||||
|
||||
/**
|
||||
* usb_gadget_controller_number - support bcdDevice id convention |
||||
* @gadget: the controller being driven |
||||
* |
||||
* Return a 2-digit BCD value associated with the peripheral controller, |
||||
* suitable for use as part of a bcdDevice value, or a negative error code. |
||||
* |
||||
* NOTE: this convention is purely optional, and has no meaning in terms of |
||||
* any USB specification. If you want to use a different convention in your |
||||
* gadget driver firmware -- maybe a more formal revision ID -- feel free. |
||||
* |
||||
* Hosts see these bcdDevice numbers, and are allowed (but not encouraged!) |
||||
* to change their behavior accordingly. For example it might help avoiding |
||||
* some chip bug. |
||||
*/ |
||||
static inline int usb_gadget_controller_number(struct usb_gadget *gadget) |
||||
{ |
||||
if (gadget_is_net2280(gadget)) |
||||
return 0x01; |
||||
else if (gadget_is_dummy(gadget)) |
||||
return 0x02; |
||||
else if (gadget_is_pxa(gadget)) |
||||
return 0x03; |
||||
else if (gadget_is_sh(gadget)) |
||||
return 0x04; |
||||
else if (gadget_is_sa1100(gadget)) |
||||
return 0x05; |
||||
else if (gadget_is_goku(gadget)) |
||||
return 0x06; |
||||
else if (gadget_is_mq11xx(gadget)) |
||||
return 0x07; |
||||
else if (gadget_is_omap(gadget)) |
||||
return 0x08; |
||||
else if (gadget_is_lh7a40x(gadget)) |
||||
return 0x09; |
||||
else if (gadget_is_n9604(gadget)) |
||||
return 0x10; |
||||
else if (gadget_is_pxa27x(gadget)) |
||||
return 0x11; |
||||
else if (gadget_is_s3c2410(gadget)) |
||||
return 0x12; |
||||
else if (gadget_is_at91(gadget)) |
||||
return 0x13; |
||||
else if (gadget_is_imx(gadget)) |
||||
return 0x14; |
||||
else if (gadget_is_musbhsfc(gadget)) |
||||
return 0x15; |
||||
else if (gadget_is_musbhdrc(gadget)) |
||||
return 0x16; |
||||
else if (gadget_is_mpc8272(gadget)) |
||||
return 0x17; |
||||
else if (gadget_is_atmel_usba(gadget)) |
||||
return 0x18; |
||||
else if (gadget_is_fsl_usb2(gadget)) |
||||
return 0x19; |
||||
else if (gadget_is_amd5536udc(gadget)) |
||||
return 0x20; |
||||
else if (gadget_is_m66592(gadget)) |
||||
return 0x21; |
||||
return -ENOENT; |
||||
} |
@ -0,0 +1,134 @@ |
||||
/*
|
||||
* Copyright (C) 2003 David Brownell |
||||
* |
||||
* This program is free software; you can redistribute it and/or modify |
||||
* it under the terms of the GNU Lesser General Public License as published |
||||
* by the Free Software Foundation; either version 2.1 of the License, or |
||||
* (at your option) any later version. |
||||
* |
||||
* Ported to U-boot by: Thomas Smits <ts.smits@gmail.com> and |
||||
* Remy Bohmer <linux@bohmer.net> |
||||
*/ |
||||
|
||||
#include <common.h> |
||||
#include <asm/errno.h> |
||||
#include <linux/usb/ch9.h> |
||||
#include <linux/usb/gadget.h> |
||||
|
||||
#include <asm/unaligned.h> |
||||
|
||||
|
||||
static int utf8_to_utf16le(const char *s, __le16 *cp, unsigned len) |
||||
{ |
||||
int count = 0; |
||||
u8 c; |
||||
u16 uchar; |
||||
|
||||
/* this insists on correct encodings, though not minimal ones.
|
||||
* BUT it currently rejects legit 4-byte UTF-8 code points, |
||||
* which need surrogate pairs. (Unicode 3.1 can use them.) |
||||
*/ |
||||
while (len != 0 && (c = (u8) *s++) != 0) { |
||||
if ((c & 0x80)) { |
||||
// 2-byte sequence:
|
||||
// 00000yyyyyxxxxxx = 110yyyyy 10xxxxxx
|
||||
if ((c & 0xe0) == 0xc0) { |
||||
uchar = (c & 0x1f) << 6; |
||||
|
||||
c = (u8) *s++; |
||||
if ((c & 0xc0) != 0x80) |
||||
goto fail; |
||||
c &= 0x3f; |
||||
uchar |= c; |
||||
|
||||
// 3-byte sequence (most CJKV characters):
|
||||
// zzzzyyyyyyxxxxxx = 1110zzzz 10yyyyyy 10xxxxxx
|
||||
} else if ((c & 0xf0) == 0xe0) { |
||||
uchar = (c & 0x0f) << 12; |
||||
|
||||
c = (u8) *s++; |
||||
if ((c & 0xc0) != 0x80) |
||||
goto fail; |
||||
c &= 0x3f; |
||||
uchar |= c << 6; |
||||
|
||||
c = (u8) *s++; |
||||
if ((c & 0xc0) != 0x80) |
||||
goto fail; |
||||
c &= 0x3f; |
||||
uchar |= c; |
||||
|
||||
/* no bogus surrogates */ |
||||
if (0xd800 <= uchar && uchar <= 0xdfff) |
||||
goto fail; |
||||
|
||||
// 4-byte sequence (surrogate pairs, currently rare):
|
||||
// 11101110wwwwzzzzyy + 110111yyyyxxxxxx
|
||||
// = 11110uuu 10uuzzzz 10yyyyyy 10xxxxxx
|
||||
// (uuuuu = wwww + 1)
|
||||
// FIXME accept the surrogate code points (only)
|
||||
|
||||
} else |
||||
goto fail; |
||||
} else |
||||
uchar = c; |
||||
put_unaligned_le16(uchar, cp++); |
||||
count++; |
||||
len--; |
||||
} |
||||
return count; |
||||
fail: |
||||
return -1; |
||||
} |
||||
|
||||
|
||||
/**
|
||||
* usb_gadget_get_string - fill out a string descriptor |
||||
* @table: of c strings encoded using UTF-8 |
||||
* @id: string id, from low byte of wValue in get string descriptor |
||||
* @buf: at least 256 bytes |
||||
* |
||||
* Finds the UTF-8 string matching the ID, and converts it into a |
||||
* string descriptor in utf16-le. |
||||
* Returns length of descriptor (always even) or negative errno |
||||
* |
||||
* If your driver needs stings in multiple languages, you'll probably |
||||
* "switch (wIndex) { ... }" in your ep0 string descriptor logic, |
||||
* using this routine after choosing which set of UTF-8 strings to use. |
||||
* Note that US-ASCII is a strict subset of UTF-8; any string bytes with |
||||
* the eighth bit set will be multibyte UTF-8 characters, not ISO-8859/1 |
||||
* characters (which are also widely used in C strings). |
||||
*/ |
||||
int |
||||
usb_gadget_get_string (struct usb_gadget_strings *table, int id, u8 *buf) |
||||
{ |
||||
struct usb_string *s; |
||||
int len; |
||||
|
||||
/* descriptor 0 has the language id */ |
||||
if (id == 0) { |
||||
buf [0] = 4; |
||||
buf [1] = USB_DT_STRING; |
||||
buf [2] = (u8) table->language; |
||||
buf [3] = (u8) (table->language >> 8); |
||||
return 4; |
||||
} |
||||
for (s = table->strings; s && s->s; s++) |
||||
if (s->id == id) |
||||
break; |
||||
|
||||
/* unrecognized: stall. */ |
||||
if (!s || !s->s) |
||||
return -EINVAL; |
||||
|
||||
/* string descriptors have length, tag, then UTF16-LE text */ |
||||
len = min ((size_t) 126, strlen (s->s)); |
||||
memset (buf + 2, 0, 2 * len); /* zero all the bytes */ |
||||
len = utf8_to_utf16le(s->s, (__le16 *)&buf[2], len); |
||||
if (len < 0) |
||||
return -EINVAL; |
||||
buf [0] = (len + 1) * 2; |
||||
buf [1] = USB_DT_STRING; |
||||
return buf [0]; |
||||
} |
||||
|
@ -0,0 +1,224 @@ |
||||
/*
|
||||
* USB Communications Device Class (CDC) definitions |
||||
* |
||||
* CDC says how to talk to lots of different types of network adapters, |
||||
* notably ethernet adapters and various modems. It's used mostly with |
||||
* firmware based USB peripherals. |
||||
* |
||||
* Ported to U-boot by: Thomas Smits <ts.smits@gmail.com> and |
||||
* Remy Bohmer <linux@bohmer.net> |
||||
*/ |
||||
|
||||
|
||||
|
||||
#define USB_CDC_SUBCLASS_ACM 0x02 |
||||
#define USB_CDC_SUBCLASS_ETHERNET 0x06 |
||||
#define USB_CDC_SUBCLASS_WHCM 0x08 |
||||
#define USB_CDC_SUBCLASS_DMM 0x09 |
||||
#define USB_CDC_SUBCLASS_MDLM 0x0a |
||||
#define USB_CDC_SUBCLASS_OBEX 0x0b |
||||
|
||||
#define USB_CDC_PROTO_NONE 0 |
||||
|
||||
#define USB_CDC_ACM_PROTO_AT_V25TER 1 |
||||
#define USB_CDC_ACM_PROTO_AT_PCCA101 2 |
||||
#define USB_CDC_ACM_PROTO_AT_PCCA101_WAKE 3 |
||||
#define USB_CDC_ACM_PROTO_AT_GSM 4 |
||||
#define USB_CDC_ACM_PROTO_AT_3G 5 |
||||
#define USB_CDC_ACM_PROTO_AT_CDMA 6 |
||||
#define USB_CDC_ACM_PROTO_VENDOR 0xff |
||||
|
||||
/*-------------------------------------------------------------------------*/ |
||||
|
||||
/*
|
||||
* Class-Specific descriptors ... there are a couple dozen of them |
||||
*/ |
||||
|
||||
#define USB_CDC_HEADER_TYPE 0x00 /* header_desc */ |
||||
#define USB_CDC_CALL_MANAGEMENT_TYPE 0x01 /* call_mgmt_descriptor */ |
||||
#define USB_CDC_ACM_TYPE 0x02 /* acm_descriptor */ |
||||
#define USB_CDC_UNION_TYPE 0x06 /* union_desc */ |
||||
#define USB_CDC_COUNTRY_TYPE 0x07 |
||||
#define USB_CDC_NETWORK_TERMINAL_TYPE 0x0a /* network_terminal_desc */ |
||||
#define USB_CDC_ETHERNET_TYPE 0x0f /* ether_desc */ |
||||
#define USB_CDC_WHCM_TYPE 0x11 |
||||
#define USB_CDC_MDLM_TYPE 0x12 /* mdlm_desc */ |
||||
#define USB_CDC_MDLM_DETAIL_TYPE 0x13 /* mdlm_detail_desc */ |
||||
#define USB_CDC_DMM_TYPE 0x14 |
||||
#define USB_CDC_OBEX_TYPE 0x15 |
||||
|
||||
/* "Header Functional Descriptor" from CDC spec 5.2.3.1 */ |
||||
struct usb_cdc_header_desc { |
||||
__u8 bLength; |
||||
__u8 bDescriptorType; |
||||
__u8 bDescriptorSubType; |
||||
|
||||
__le16 bcdCDC; |
||||
} __attribute__ ((packed)); |
||||
|
||||
/* "Call Management Descriptor" from CDC spec 5.2.3.2 */ |
||||
struct usb_cdc_call_mgmt_descriptor { |
||||
__u8 bLength; |
||||
__u8 bDescriptorType; |
||||
__u8 bDescriptorSubType; |
||||
|
||||
__u8 bmCapabilities; |
||||
#define USB_CDC_CALL_MGMT_CAP_CALL_MGMT 0x01 |
||||
#define USB_CDC_CALL_MGMT_CAP_DATA_INTF 0x02 |
||||
|
||||
__u8 bDataInterface; |
||||
} __attribute__ ((packed)); |
||||
|
||||
/* "Abstract Control Management Descriptor" from CDC spec 5.2.3.3 */ |
||||
struct usb_cdc_acm_descriptor { |
||||
__u8 bLength; |
||||
__u8 bDescriptorType; |
||||
__u8 bDescriptorSubType; |
||||
|
||||
__u8 bmCapabilities; |
||||
} __attribute__ ((packed)); |
||||
|
||||
/* capabilities from 5.2.3.3 */ |
||||
|
||||
#define USB_CDC_COMM_FEATURE 0x01 |
||||
#define USB_CDC_CAP_LINE 0x02 |
||||
#define USB_CDC_CAP_BRK 0x04 |
||||
#define USB_CDC_CAP_NOTIFY 0x08 |
||||
|
||||
/* "Union Functional Descriptor" from CDC spec 5.2.3.8 */ |
||||
struct usb_cdc_union_desc { |
||||
__u8 bLength; |
||||
__u8 bDescriptorType; |
||||
__u8 bDescriptorSubType; |
||||
|
||||
__u8 bMasterInterface0; |
||||
__u8 bSlaveInterface0; |
||||
/* ... and there could be other slave interfaces */ |
||||
} __attribute__ ((packed)); |
||||
|
||||
/* "Country Selection Functional Descriptor" from CDC spec 5.2.3.9 */ |
||||
struct usb_cdc_country_functional_desc { |
||||
__u8 bLength; |
||||
__u8 bDescriptorType; |
||||
__u8 bDescriptorSubType; |
||||
|
||||
__u8 iCountryCodeRelDate; |
||||
__le16 wCountyCode0; |
||||
/* ... and there can be a lot of country codes */ |
||||
} __attribute__ ((packed)); |
||||
|
||||
/* "Network Channel Terminal Functional Descriptor" from CDC spec 5.2.3.11 */ |
||||
struct usb_cdc_network_terminal_desc { |
||||
__u8 bLength; |
||||
__u8 bDescriptorType; |
||||
__u8 bDescriptorSubType; |
||||
|
||||
__u8 bEntityId; |
||||
__u8 iName; |
||||
__u8 bChannelIndex; |
||||
__u8 bPhysicalInterface; |
||||
} __attribute__ ((packed)); |
||||
|
||||
/* "Ethernet Networking Functional Descriptor" from CDC spec 5.2.3.16 */ |
||||
struct usb_cdc_ether_desc { |
||||
__u8 bLength; |
||||
__u8 bDescriptorType; |
||||
__u8 bDescriptorSubType; |
||||
|
||||
__u8 iMACAddress; |
||||
__le32 bmEthernetStatistics; |
||||
__le16 wMaxSegmentSize; |
||||
__le16 wNumberMCFilters; |
||||
__u8 bNumberPowerFilters; |
||||
} __attribute__ ((packed)); |
||||
|
||||
/* "MDLM Functional Descriptor" from CDC WMC spec 6.7.2.3 */ |
||||
struct usb_cdc_mdlm_desc { |
||||
__u8 bLength; |
||||
__u8 bDescriptorType; |
||||
__u8 bDescriptorSubType; |
||||
|
||||
__le16 bcdVersion; |
||||
__u8 bGUID[16]; |
||||
} __attribute__ ((packed)); |
||||
|
||||
/* "MDLM Detail Functional Descriptor" from CDC WMC spec 6.7.2.4 */ |
||||
struct usb_cdc_mdlm_detail_desc { |
||||
__u8 bLength; |
||||
__u8 bDescriptorType; |
||||
__u8 bDescriptorSubType; |
||||
|
||||
/* type is associated with mdlm_desc.bGUID */ |
||||
__u8 bGuidDescriptorType; |
||||
__u8 bDetailData[0]; |
||||
} __attribute__ ((packed)); |
||||
|
||||
/*-------------------------------------------------------------------------*/ |
||||
|
||||
/*
|
||||
* Class-Specific Control Requests (6.2) |
||||
* |
||||
* section 3.6.2.1 table 4 has the ACM profile, for modems. |
||||
* section 3.8.2 table 10 has the ethernet profile. |
||||
*/ |
||||
|
||||
#define USB_CDC_SEND_ENCAPSULATED_COMMAND 0x00 |
||||
#define USB_CDC_GET_ENCAPSULATED_RESPONSE 0x01 |
||||
#define USB_CDC_REQ_SET_LINE_CODING 0x20 |
||||
#define USB_CDC_REQ_GET_LINE_CODING 0x21 |
||||
#define USB_CDC_REQ_SET_CONTROL_LINE_STATE 0x22 |
||||
#define USB_CDC_REQ_SEND_BREAK 0x23 |
||||
#define USB_CDC_SET_ETHERNET_MULTICAST_FILTERS 0x40 |
||||
#define USB_CDC_SET_ETHERNET_PM_PATTERN_FILTER 0x41 |
||||
#define USB_CDC_GET_ETHERNET_PM_PATTERN_FILTER 0x42 |
||||
#define USB_CDC_SET_ETHERNET_PACKET_FILTER 0x43 |
||||
#define USB_CDC_GET_ETHERNET_STATISTIC 0x44 |
||||
|
||||
/* Line Coding Structure from CDC spec 6.2.13 */ |
||||
struct usb_cdc_line_coding { |
||||
__le32 dwDTERate; |
||||
__u8 bCharFormat; |
||||
#define USB_CDC_1_STOP_BITS 0 |
||||
#define USB_CDC_1_5_STOP_BITS 1 |
||||
#define USB_CDC_2_STOP_BITS 2 |
||||
|
||||
__u8 bParityType; |
||||
#define USB_CDC_NO_PARITY 0 |
||||
#define USB_CDC_ODD_PARITY 1 |
||||
#define USB_CDC_EVEN_PARITY 2 |
||||
#define USB_CDC_MARK_PARITY 3 |
||||
#define USB_CDC_SPACE_PARITY 4 |
||||
|
||||
__u8 bDataBits; |
||||
} __attribute__ ((packed)); |
||||
|
||||
/* table 62; bits in multicast filter */ |
||||
#define USB_CDC_PACKET_TYPE_PROMISCUOUS (1 << 0) |
||||
#define USB_CDC_PACKET_TYPE_ALL_MULTICAST (1 << 1) /* no filter */ |
||||
#define USB_CDC_PACKET_TYPE_DIRECTED (1 << 2) |
||||
#define USB_CDC_PACKET_TYPE_BROADCAST (1 << 3) |
||||
#define USB_CDC_PACKET_TYPE_MULTICAST (1 << 4) /* filtered */ |
||||
|
||||
|
||||
/*-------------------------------------------------------------------------*/ |
||||
|
||||
/*
|
||||
* Class-Specific Notifications (6.3) sent by interrupt transfers |
||||
* |
||||
* section 3.8.2 table 11 of the CDC spec lists Ethernet notifications |
||||
* section 3.6.2.1 table 5 specifies ACM notifications |
||||
*/ |
||||
|
||||
#define USB_CDC_NOTIFY_NETWORK_CONNECTION 0x00 |
||||
#define USB_CDC_NOTIFY_RESPONSE_AVAILABLE 0x01 |
||||
#define USB_CDC_NOTIFY_SERIAL_STATE 0x20 |
||||
#define USB_CDC_NOTIFY_SPEED_CHANGE 0x2a |
||||
|
||||
struct usb_cdc_notification { |
||||
__u8 bmRequestType; |
||||
__u8 bNotificationType; |
||||
__le16 wValue; |
||||
__le16 wIndex; |
||||
__le16 wLength; |
||||
} __attribute__ ((packed)); |
||||
|
@ -0,0 +1,587 @@ |
||||
/*
|
||||
* This file holds USB constants and structures that are needed for |
||||
* USB device APIs. These are used by the USB device model, which is |
||||
* defined in chapter 9 of the USB 2.0 specification and in the |
||||
* Wireless USB 1.0 (spread around). Linux has several APIs in C that |
||||
* need these: |
||||
* |
||||
* - the master/host side Linux-USB kernel driver API; |
||||
* - the "usbfs" user space API; and |
||||
* - the Linux "gadget" slave/device/peripheral side driver API. |
||||
* |
||||
* USB 2.0 adds an additional "On The Go" (OTG) mode, which lets systems |
||||
* act either as a USB master/host or as a USB slave/device. That means |
||||
* the master and slave side APIs benefit from working well together. |
||||
* |
||||
* There's also "Wireless USB", using low power short range radios for |
||||
* peripheral interconnection but otherwise building on the USB framework. |
||||
* |
||||
* Note all descriptors are declared '__attribute__((packed))' so that: |
||||
* |
||||
* [a] they never get padded, either internally (USB spec writers |
||||
* probably handled that) or externally; |
||||
* |
||||
* [b] so that accessing bigger-than-a-bytes fields will never |
||||
* generate bus errors on any platform, even when the location of |
||||
* its descriptor inside a bundle isn't "naturally aligned", and |
||||
* |
||||
* [c] for consistency, removing all doubt even when it appears to |
||||
* someone that the two other points are non-issues for that |
||||
* particular descriptor type. |
||||
* |
||||
* Ported to U-boot by: Thomas Smits <ts.smits@gmail.com> and |
||||
* Remy Bohmer <linux@bohmer.net> |
||||
*/ |
||||
|
||||
#ifndef __LINUX_USB_CH9_H |
||||
#define __LINUX_USB_CH9_H |
||||
|
||||
#include <linux/types.h> /* __u8 etc */ |
||||
|
||||
/*-------------------------------------------------------------------------*/ |
||||
|
||||
/* CONTROL REQUEST SUPPORT */ |
||||
|
||||
/*
|
||||
* USB directions |
||||
* |
||||
* This bit flag is used in endpoint descriptors' bEndpointAddress field. |
||||
* It's also one of three fields in control requests bRequestType. |
||||
*/ |
||||
#define USB_DIR_OUT 0 /* to device */ |
||||
#define USB_DIR_IN 0x80 /* to host */ |
||||
|
||||
/*
|
||||
* USB types, the second of three bRequestType fields |
||||
*/ |
||||
#define USB_TYPE_MASK (0x03 << 5) |
||||
#define USB_TYPE_STANDARD (0x00 << 5) |
||||
#define USB_TYPE_CLASS (0x01 << 5) |
||||
#define USB_TYPE_VENDOR (0x02 << 5) |
||||
#define USB_TYPE_RESERVED (0x03 << 5) |
||||
|
||||
/*
|
||||
* USB recipients, the third of three bRequestType fields |
||||
*/ |
||||
#define USB_RECIP_MASK 0x1f |
||||
#define USB_RECIP_DEVICE 0x00 |
||||
#define USB_RECIP_INTERFACE 0x01 |
||||
#define USB_RECIP_ENDPOINT 0x02 |
||||
#define USB_RECIP_OTHER 0x03 |
||||
/* From Wireless USB 1.0 */ |
||||
#define USB_RECIP_PORT 0x04 |
||||
#define USB_RECIP_RPIPE 0x05 |
||||
|
||||
/*
|
||||
* Standard requests, for the bRequest field of a SETUP packet. |
||||
* |
||||
* These are qualified by the bRequestType field, so that for example |
||||
* TYPE_CLASS or TYPE_VENDOR specific feature flags could be retrieved |
||||
* by a GET_STATUS 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_DESCRIPTOR 0x06 |
||||
#define USB_REQ_SET_DESCRIPTOR 0x07 |
||||
#define USB_REQ_GET_CONFIGURATION 0x08 |
||||
#define USB_REQ_SET_CONFIGURATION 0x09 |
||||
#define USB_REQ_GET_INTERFACE 0x0A |
||||
#define USB_REQ_SET_INTERFACE 0x0B |
||||
#define USB_REQ_SYNCH_FRAME 0x0C |
||||
|
||||
#define USB_REQ_SET_ENCRYPTION 0x0D /* Wireless USB */ |
||||
#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 |
||||
|
||||
/*
|
||||
* USB feature flags are written using USB_REQ_{CLEAR,SET}_FEATURE, and |
||||
* are read as a bit array returned by USB_REQ_GET_STATUS. (So there |
||||
* are at most sixteen features of each type.) |
||||
*/ |
||||
#define USB_DEVICE_SELF_POWERED 0 /* (read only) */ |
||||
#define USB_DEVICE_REMOTE_WAKEUP 1 /* dev may initiate wakeup */ |
||||
#define USB_DEVICE_TEST_MODE 2 /* (wired high speed only) */ |
||||
#define USB_DEVICE_BATTERY 2 /* (wireless) */ |
||||
#define USB_DEVICE_B_HNP_ENABLE 3 /* (otg) dev may initiate HNP */ |
||||
#define USB_DEVICE_WUSB_DEVICE 3 /* (wireless)*/ |
||||
#define USB_DEVICE_A_HNP_SUPPORT 4 /* (otg) RH port supports HNP */ |
||||
#define USB_DEVICE_A_ALT_HNP_SUPPORT 5 /* (otg) other RH port does */ |
||||
#define USB_DEVICE_DEBUG_MODE 6 /* (special devices only) */ |
||||
|
||||
#define USB_ENDPOINT_HALT 0 /* IN/OUT will STALL */ |
||||
|
||||
|
||||
/**
|
||||
* struct usb_ctrlrequest - SETUP data for a USB device control request |
||||
* @bRequestType: matches the USB bmRequestType field |
||||
* @bRequest: matches the USB bRequest field |
||||
* @wValue: matches the USB wValue field (le16 byte order) |
||||
* @wIndex: matches the USB wIndex field (le16 byte order) |
||||
* @wLength: matches the USB wLength field (le16 byte order) |
||||
* |
||||
* This structure is used to send control requests to a USB device. It matches |
||||
* the different fields of the USB 2.0 Spec section 9.3, table 9-2. See the |
||||
* USB spec for a fuller description of the different fields, and what they are |
||||
* used for. |
||||
* |
||||
* Note that the driver for any interface can issue control requests. |
||||
* For most devices, interfaces don't coordinate with each other, so |
||||
* such requests may be made at any time. |
||||
*/ |
||||
#if defined(__BIG_ENDIAN) || defined(__ARMEB__) |
||||
#error (functionality not verified for big endian targets, todo...) |
||||
#endif |
||||
|
||||
struct usb_ctrlrequest { |
||||
__u8 bRequestType; |
||||
__u8 bRequest; |
||||
__le16 wValue; |
||||
__le16 wIndex; |
||||
__le16 wLength; |
||||
} __attribute__ ((packed)); |
||||
|
||||
/*-------------------------------------------------------------------------*/ |
||||
|
||||
/*
|
||||
* STANDARD DESCRIPTORS ... as returned by GET_DESCRIPTOR, or |
||||
* (rarely) accepted by SET_DESCRIPTOR. |
||||
* |
||||
* Note that all multi-byte values here are encoded in little endian |
||||
* byte order "on the wire". But when exposed through Linux-USB APIs, |
||||
* they've been converted to cpu byte order. |
||||
*/ |
||||
|
||||
/*
|
||||
* Descriptor types ... USB 2.0 spec table 9.5 |
||||
*/ |
||||
#define USB_DT_DEVICE 0x01 |
||||
#define USB_DT_CONFIG 0x02 |
||||
#define USB_DT_STRING 0x03 |
||||
#define USB_DT_INTERFACE 0x04 |
||||
#define USB_DT_ENDPOINT 0x05 |
||||
#define USB_DT_DEVICE_QUALIFIER 0x06 |
||||
#define USB_DT_OTHER_SPEED_CONFIG 0x07 |
||||
#define USB_DT_INTERFACE_POWER 0x08 |
||||
/* these are from a minor usb 2.0 revision (ECN) */ |
||||
#define USB_DT_OTG 0x09 |
||||
#define USB_DT_DEBUG 0x0a |
||||
#define USB_DT_INTERFACE_ASSOCIATION 0x0b |
||||
/* these are from the Wireless USB spec */ |
||||
#define USB_DT_SECURITY 0x0c |
||||
#define USB_DT_KEY 0x0d |
||||
#define USB_DT_ENCRYPTION_TYPE 0x0e |
||||
#define USB_DT_BOS 0x0f |
||||
#define USB_DT_DEVICE_CAPABILITY 0x10 |
||||
#define USB_DT_WIRELESS_ENDPOINT_COMP 0x11 |
||||
#define USB_DT_WIRE_ADAPTER 0x21 |
||||
#define USB_DT_RPIPE 0x22 |
||||
|
||||
/* Conventional codes for class-specific descriptors. The convention is
|
||||
* defined in the USB "Common Class" Spec (3.11). Individual class specs |
||||
* are authoritative for their usage, not the "common class" writeup. |
||||
*/ |
||||
#define USB_DT_CS_DEVICE (USB_TYPE_CLASS | USB_DT_DEVICE) |
||||
#define USB_DT_CS_CONFIG (USB_TYPE_CLASS | USB_DT_CONFIG) |
||||
#define USB_DT_CS_STRING (USB_TYPE_CLASS | USB_DT_STRING) |
||||
#define USB_DT_CS_INTERFACE (USB_TYPE_CLASS | USB_DT_INTERFACE) |
||||
#define USB_DT_CS_ENDPOINT (USB_TYPE_CLASS | USB_DT_ENDPOINT) |
||||
|
||||
/* All standard descriptors have these 2 fields at the beginning */ |
||||
struct usb_descriptor_header { |
||||
__u8 bLength; |
||||
__u8 bDescriptorType; |
||||
} __attribute__ ((packed)); |
||||
|
||||
|
||||
/*-------------------------------------------------------------------------*/ |
||||
|
||||
/* USB_DT_DEVICE: Device descriptor */ |
||||
struct usb_device_descriptor { |
||||
__u8 bLength; |
||||
__u8 bDescriptorType; |
||||
|
||||
__le16 bcdUSB; |
||||
__u8 bDeviceClass; |
||||
__u8 bDeviceSubClass; |
||||
__u8 bDeviceProtocol; |
||||
__u8 bMaxPacketSize0; |
||||
__le16 idVendor; |
||||
__le16 idProduct; |
||||
__le16 bcdDevice; |
||||
__u8 iManufacturer; |
||||
__u8 iProduct; |
||||
__u8 iSerialNumber; |
||||
__u8 bNumConfigurations; |
||||
} __attribute__ ((packed)); |
||||
|
||||
#define USB_DT_DEVICE_SIZE 18 |
||||
|
||||
|
||||
/*
|
||||
* Device and/or Interface Class codes |
||||
* as found in bDeviceClass or bInterfaceClass |
||||
* and defined by www.usb.org documents |
||||
*/ |
||||
#define USB_CLASS_PER_INTERFACE 0 /* for DeviceClass */ |
||||
#define USB_CLASS_AUDIO 1 |
||||
#define USB_CLASS_COMM 2 |
||||
#define USB_CLASS_HID 3 |
||||
#define USB_CLASS_PHYSICAL 5 |
||||
#define USB_CLASS_STILL_IMAGE 6 |
||||
#define USB_CLASS_PRINTER 7 |
||||
#define USB_CLASS_MASS_STORAGE 8 |
||||
#define USB_CLASS_HUB 9 |
||||
#define USB_CLASS_CDC_DATA 0x0a |
||||
#define USB_CLASS_CSCID 0x0b /* chip+ smart card */ |
||||
#define USB_CLASS_CONTENT_SEC 0x0d /* content security */ |
||||
#define USB_CLASS_VIDEO 0x0e |
||||
#define USB_CLASS_WIRELESS_CONTROLLER 0xe0 |
||||
#define USB_CLASS_MISC 0xef |
||||
#define USB_CLASS_APP_SPEC 0xfe |
||||
#define USB_CLASS_VENDOR_SPEC 0xff |
||||
|
||||
/*-------------------------------------------------------------------------*/ |
||||
|
||||
/* USB_DT_CONFIG: Configuration descriptor information.
|
||||
* |
||||
* USB_DT_OTHER_SPEED_CONFIG is the same descriptor, except that the |
||||
* descriptor type is different. Highspeed-capable devices can look |
||||
* different depending on what speed they're currently running. Only |
||||
* devices with a USB_DT_DEVICE_QUALIFIER have any OTHER_SPEED_CONFIG |
||||
* descriptors. |
||||
*/ |
||||
struct usb_config_descriptor { |
||||
__u8 bLength; |
||||
__u8 bDescriptorType; |
||||
|
||||
__le16 wTotalLength; |
||||
__u8 bNumInterfaces; |
||||
__u8 bConfigurationValue; |
||||
__u8 iConfiguration; |
||||
__u8 bmAttributes; |
||||
__u8 bMaxPower; |
||||
} __attribute__ ((packed)); |
||||
|
||||
#define USB_DT_CONFIG_SIZE 9 |
||||
|
||||
/* from config descriptor bmAttributes */ |
||||
#define USB_CONFIG_ATT_ONE (1 << 7) /* must be set */ |
||||
#define USB_CONFIG_ATT_SELFPOWER (1 << 6) /* self powered */ |
||||
#define USB_CONFIG_ATT_WAKEUP (1 << 5) /* can wakeup */ |
||||
#define USB_CONFIG_ATT_BATTERY (1 << 4) /* battery powered */ |
||||
|
||||
/*-------------------------------------------------------------------------*/ |
||||
|
||||
/* USB_DT_STRING: String descriptor */ |
||||
struct usb_string_descriptor { |
||||
__u8 bLength; |
||||
__u8 bDescriptorType; |
||||
|
||||
__le16 wData[1]; /* UTF-16LE encoded */ |
||||
} __attribute__ ((packed)); |
||||
|
||||
/* note that "string" zero is special, it holds language codes that
|
||||
* the device supports, not Unicode characters. |
||||
*/ |
||||
|
||||
/*-------------------------------------------------------------------------*/ |
||||
|
||||
/* USB_DT_INTERFACE: Interface descriptor */ |
||||
struct usb_interface_descriptor { |
||||
__u8 bLength; |
||||
__u8 bDescriptorType; |
||||
|
||||
__u8 bInterfaceNumber; |
||||
__u8 bAlternateSetting; |
||||
__u8 bNumEndpoints; |
||||
__u8 bInterfaceClass; |
||||
__u8 bInterfaceSubClass; |
||||
__u8 bInterfaceProtocol; |
||||
__u8 iInterface; |
||||
} __attribute__ ((packed)); |
||||
|
||||
#define USB_DT_INTERFACE_SIZE 9 |
||||
|
||||
/*-------------------------------------------------------------------------*/ |
||||
|
||||
/* USB_DT_ENDPOINT: Endpoint descriptor */ |
||||
struct usb_endpoint_descriptor { |
||||
__u8 bLength; |
||||
__u8 bDescriptorType; |
||||
|
||||
__u8 bEndpointAddress; |
||||
__u8 bmAttributes; |
||||
__le16 wMaxPacketSize; |
||||
__u8 bInterval; |
||||
|
||||
/* NOTE: these two are _only_ in audio endpoints. */ |
||||
/* use USB_DT_ENDPOINT*_SIZE in bLength, not sizeof. */ |
||||
__u8 bRefresh; |
||||
__u8 bSynchAddress; |
||||
} __attribute__ ((packed)); |
||||
|
||||
#define USB_DT_ENDPOINT_SIZE 7 |
||||
#define USB_DT_ENDPOINT_AUDIO_SIZE 9 /* Audio extension */ |
||||
|
||||
|
||||
/*
|
||||
* Endpoints |
||||
*/ |
||||
#define USB_ENDPOINT_NUMBER_MASK 0x0f /* in bEndpointAddress */ |
||||
#define USB_ENDPOINT_DIR_MASK 0x80 |
||||
|
||||
#define USB_ENDPOINT_XFERTYPE_MASK 0x03 /* in bmAttributes */ |
||||
#define USB_ENDPOINT_XFER_CONTROL 0 |
||||
#define USB_ENDPOINT_XFER_ISOC 1 |
||||
#define USB_ENDPOINT_XFER_BULK 2 |
||||
#define USB_ENDPOINT_XFER_INT 3 |
||||
#define USB_ENDPOINT_MAX_ADJUSTABLE 0x80 |
||||
|
||||
|
||||
/*-------------------------------------------------------------------------*/ |
||||
|
||||
/* USB_DT_DEVICE_QUALIFIER: Device Qualifier descriptor */ |
||||
struct usb_qualifier_descriptor { |
||||
__u8 bLength; |
||||
__u8 bDescriptorType; |
||||
|
||||
__le16 bcdUSB; |
||||
__u8 bDeviceClass; |
||||
__u8 bDeviceSubClass; |
||||
__u8 bDeviceProtocol; |
||||
__u8 bMaxPacketSize0; |
||||
__u8 bNumConfigurations; |
||||
__u8 bRESERVED; |
||||
} __attribute__ ((packed)); |
||||
|
||||
|
||||
/*-------------------------------------------------------------------------*/ |
||||
|
||||
/* USB_DT_OTG (from OTG 1.0a supplement) */ |
||||
struct usb_otg_descriptor { |
||||
__u8 bLength; |
||||
__u8 bDescriptorType; |
||||
|
||||
__u8 bmAttributes; /* support for HNP, SRP, etc */ |
||||
} __attribute__ ((packed)); |
||||
|
||||
/* from usb_otg_descriptor.bmAttributes */ |
||||
#define USB_OTG_SRP (1 << 0) |
||||
#define USB_OTG_HNP (1 << 1) /* swap host/device roles */ |
||||
|
||||
/*-------------------------------------------------------------------------*/ |
||||
|
||||
/* USB_DT_DEBUG: for special highspeed devices, replacing serial console */ |
||||
struct usb_debug_descriptor { |
||||
__u8 bLength; |
||||
__u8 bDescriptorType; |
||||
|
||||
/* bulk endpoints with 8 byte maxpacket */ |
||||
__u8 bDebugInEndpoint; |
||||
__u8 bDebugOutEndpoint; |
||||
} __attribute__((packed)); |
||||
|
||||
/*-------------------------------------------------------------------------*/ |
||||
|
||||
/* USB_DT_INTERFACE_ASSOCIATION: groups interfaces */ |
||||
struct usb_interface_assoc_descriptor { |
||||
__u8 bLength; |
||||
__u8 bDescriptorType; |
||||
|
||||
__u8 bFirstInterface; |
||||
__u8 bInterfaceCount; |
||||
__u8 bFunctionClass; |
||||
__u8 bFunctionSubClass; |
||||
__u8 bFunctionProtocol; |
||||
__u8 iFunction; |
||||
} __attribute__ ((packed)); |
||||
|
||||
|
||||
/*-------------------------------------------------------------------------*/ |
||||
|
||||
/* USB_DT_SECURITY: group of wireless security descriptors, including
|
||||
* encryption types available for setting up a CC/association. |
||||
*/ |
||||
struct usb_security_descriptor { |
||||
__u8 bLength; |
||||
__u8 bDescriptorType; |
||||
|
||||
__le16 wTotalLength; |
||||
__u8 bNumEncryptionTypes; |
||||
} __attribute__((packed)); |
||||
|
||||
/*-------------------------------------------------------------------------*/ |
||||
|
||||
/* USB_DT_KEY: used with {GET,SET}_SECURITY_DATA; only public keys
|
||||
* may be retrieved. |
||||
*/ |
||||
struct usb_key_descriptor { |
||||
__u8 bLength; |
||||
__u8 bDescriptorType; |
||||
|
||||
__u8 tTKID[3]; |
||||
__u8 bReserved; |
||||
__u8 bKeyData[0]; |
||||
} __attribute__((packed)); |
||||
|
||||
/*-------------------------------------------------------------------------*/ |
||||
|
||||
/* USB_DT_ENCRYPTION_TYPE: bundled in DT_SECURITY groups */ |
||||
struct usb_encryption_descriptor { |
||||
__u8 bLength; |
||||
__u8 bDescriptorType; |
||||
|
||||
__u8 bEncryptionType; |
||||
#define USB_ENC_TYPE_UNSECURE 0 |
||||
#define USB_ENC_TYPE_WIRED 1 /* non-wireless mode */ |
||||
#define USB_ENC_TYPE_CCM_1 2 /* aes128/cbc session */ |
||||
#define USB_ENC_TYPE_RSA_1 3 /* rsa3072/sha1 auth */ |
||||
__u8 bEncryptionValue; /* use in SET_ENCRYPTION */ |
||||
__u8 bAuthKeyIndex; |
||||
} __attribute__((packed)); |
||||
|
||||
|
||||
/*-------------------------------------------------------------------------*/ |
||||
|
||||
/* USB_DT_BOS: group of wireless capabilities */ |
||||
struct usb_bos_descriptor { |
||||
__u8 bLength; |
||||
__u8 bDescriptorType; |
||||
|
||||
__le16 wTotalLength; |
||||
__u8 bNumDeviceCaps; |
||||
} __attribute__((packed)); |
||||
|
||||
/*-------------------------------------------------------------------------*/ |
||||
|
||||
/* USB_DT_DEVICE_CAPABILITY: grouped with BOS */ |
||||
struct usb_dev_cap_header { |
||||
__u8 bLength; |
||||
__u8 bDescriptorType; |
||||
__u8 bDevCapabilityType; |
||||
} __attribute__((packed)); |
||||
|
||||
#define USB_CAP_TYPE_WIRELESS_USB 1 |
||||
|
||||
struct usb_wireless_cap_descriptor { /* Ultra Wide Band */ |
||||
__u8 bLength; |
||||
__u8 bDescriptorType; |
||||
__u8 bDevCapabilityType; |
||||
|
||||
__u8 bmAttributes; |
||||
#define USB_WIRELESS_P2P_DRD (1 << 1) |
||||
#define USB_WIRELESS_BEACON_MASK (3 << 2) |
||||
#define USB_WIRELESS_BEACON_SELF (1 << 2) |
||||
#define USB_WIRELESS_BEACON_DIRECTED (2 << 2) |
||||
#define USB_WIRELESS_BEACON_NONE (3 << 2) |
||||
__le16 wPHYRates; /* bit rates, Mbps */ |
||||
#define USB_WIRELESS_PHY_53 (1 << 0) /* always set */ |
||||
#define USB_WIRELESS_PHY_80 (1 << 1) |
||||
#define USB_WIRELESS_PHY_107 (1 << 2) /* always set */ |
||||
#define USB_WIRELESS_PHY_160 (1 << 3) |
||||
#define USB_WIRELESS_PHY_200 (1 << 4) /* always set */ |
||||
#define USB_WIRELESS_PHY_320 (1 << 5) |
||||
#define USB_WIRELESS_PHY_400 (1 << 6) |
||||
#define USB_WIRELESS_PHY_480 (1 << 7) |
||||
__u8 bmTFITXPowerInfo; /* TFI power levels */ |
||||
__u8 bmFFITXPowerInfo; /* FFI power levels */ |
||||
__le16 bmBandGroup; |
||||
__u8 bReserved; |
||||
} __attribute__((packed)); |
||||
|
||||
/*-------------------------------------------------------------------------*/ |
||||
|
||||
/* USB_DT_WIRELESS_ENDPOINT_COMP: companion descriptor associated with
|
||||
* each endpoint descriptor for a wireless device |
||||
*/ |
||||
struct usb_wireless_ep_comp_descriptor { |
||||
__u8 bLength; |
||||
__u8 bDescriptorType; |
||||
|
||||
__u8 bMaxBurst; |
||||
__u8 bMaxSequence; |
||||
__le16 wMaxStreamDelay; |
||||
__le16 wOverTheAirPacketSize; |
||||
__u8 bOverTheAirInterval; |
||||
__u8 bmCompAttributes; |
||||
#define USB_ENDPOINT_SWITCH_MASK 0x03 /* in bmCompAttributes */ |
||||
#define USB_ENDPOINT_SWITCH_NO 0 |
||||
#define USB_ENDPOINT_SWITCH_SWITCH 1 |
||||
#define USB_ENDPOINT_SWITCH_SCALE 2 |
||||
} __attribute__((packed)); |
||||
|
||||
/*-------------------------------------------------------------------------*/ |
||||
|
||||
/* USB_REQ_SET_HANDSHAKE is a four-way handshake used between a wireless
|
||||
* host and a device for connection set up, mutual authentication, and |
||||
* exchanging short lived session keys. The handshake depends on a CC. |
||||
*/ |
||||
struct usb_handshake { |
||||
__u8 bMessageNumber; |
||||
__u8 bStatus; |
||||
__u8 tTKID[3]; |
||||
__u8 bReserved; |
||||
__u8 CDID[16]; |
||||
__u8 nonce[16]; |
||||
__u8 MIC[8]; |
||||
} __attribute__((packed)); |
||||
|
||||
/*-------------------------------------------------------------------------*/ |
||||
|
||||
/* USB_REQ_SET_CONNECTION modifies or revokes a connection context (CC).
|
||||
* A CC may also be set up using non-wireless secure channels (including |
||||
* wired USB!), and some devices may support CCs with multiple hosts. |
||||
*/ |
||||
struct usb_connection_context { |
||||
__u8 CHID[16]; /* persistent host id */ |
||||
__u8 CDID[16]; /* device id (unique w/in host context) */ |
||||
__u8 CK[16]; /* connection key */ |
||||
} __attribute__((packed)); |
||||
|
||||
/*-------------------------------------------------------------------------*/ |
||||
|
||||
/* USB 2.0 defines three speeds, here's how Linux identifies them */ |
||||
|
||||
enum usb_device_speed { |
||||
USB_SPEED_UNKNOWN = 0, /* enumerating */ |
||||
USB_SPEED_LOW, USB_SPEED_FULL, /* usb 1.1 */ |
||||
USB_SPEED_HIGH, /* usb 2.0 */ |
||||
USB_SPEED_VARIABLE, /* wireless (usb 2.5) */ |
||||
}; |
||||
|
||||
enum usb_device_state { |
||||
/* NOTATTACHED isn't in the USB spec, and this state acts
|
||||
* the same as ATTACHED ... but it's clearer this way. |
||||
*/ |
||||
USB_STATE_NOTATTACHED = 0, |
||||
|
||||
/* chapter 9 and authentication (wireless) device states */ |
||||
USB_STATE_ATTACHED, |
||||
USB_STATE_POWERED, /* wired */ |
||||
USB_STATE_UNAUTHENTICATED, /* auth */ |
||||
USB_STATE_RECONNECTING, /* auth */ |
||||
USB_STATE_DEFAULT, /* limited function */ |
||||
USB_STATE_ADDRESS, |
||||
USB_STATE_CONFIGURED, /* most functions */ |
||||
|
||||
USB_STATE_SUSPENDED |
||||
|
||||
/* NOTE: there are actually four different SUSPENDED
|
||||
* states, returning to POWERED, DEFAULT, ADDRESS, or |
||||
* CONFIGURED respectively when SOF tokens flow again. |
||||
*/ |
||||
}; |
||||
|
||||
#endif /* __LINUX_USB_CH9_H */ |
@ -0,0 +1,871 @@ |
||||
/*
|
||||
* <linux/usb/gadget.h> |
||||
* |
||||
* We call the USB code inside a Linux-based peripheral device a "gadget" |
||||
* driver, except for the hardware-specific bus glue. One USB host can |
||||
* master many USB gadgets, but the gadgets are only slaved to one host. |
||||
* |
||||
* |
||||
* (C) Copyright 2002-2004 by David Brownell |
||||
* All Rights Reserved. |
||||
* |
||||
* This software is licensed under the GNU GPL version 2. |
||||
* |
||||
* Ported to U-boot by: Thomas Smits <ts.smits@gmail.com> and |
||||
* Remy Bohmer <linux@bohmer.net> |
||||
*/ |
||||
|
||||
#ifndef __LINUX_USB_GADGET_H |
||||
#define __LINUX_USB_GADGET_H |
||||
|
||||
#include <linux/list.h> |
||||
|
||||
struct usb_ep; |
||||
|
||||
/**
|
||||
* struct usb_request - describes one i/o request |
||||
* @buf: Buffer used for data. Always provide this; some controllers |
||||
* only use PIO, or don't use DMA for some endpoints. |
||||
* @dma: DMA address corresponding to 'buf'. If you don't set this |
||||
* field, and the usb controller needs one, it is responsible |
||||
* for mapping and unmapping the buffer. |
||||
* @length: Length of that data |
||||
* @no_interrupt: If true, hints that no completion irq is needed. |
||||
* Helpful sometimes with deep request queues that are handled |
||||
* directly by DMA controllers. |
||||
* @zero: If true, when writing data, makes the last packet be "short" |
||||
* by adding a zero length packet as needed; |
||||
* @short_not_ok: When reading data, makes short packets be |
||||
* treated as errors (queue stops advancing till cleanup). |
||||
* @complete: Function called when request completes, so this request and |
||||
* its buffer may be re-used. |
||||
* Reads terminate with a short packet, or when the buffer fills, |
||||
* whichever comes first. When writes terminate, some data bytes |
||||
* will usually still be in flight (often in a hardware fifo). |
||||
* Errors (for reads or writes) stop the queue from advancing |
||||
* until the completion function returns, so that any transfers |
||||
* invalidated by the error may first be dequeued. |
||||
* @context: For use by the completion callback |
||||
* @list: For use by the gadget driver. |
||||
* @status: Reports completion code, zero or a negative errno. |
||||
* Normally, faults block the transfer queue from advancing until |
||||
* the completion callback returns. |
||||
* Code "-ESHUTDOWN" indicates completion caused by device disconnect, |
||||
* or when the driver disabled the endpoint. |
||||
* @actual: Reports bytes transferred to/from the buffer. For reads (OUT |
||||
* transfers) this may be less than the requested length. If the |
||||
* short_not_ok flag is set, short reads are treated as errors |
||||
* even when status otherwise indicates successful completion. |
||||
* Note that for writes (IN transfers) some data bytes may still |
||||
* reside in a device-side FIFO when the request is reported as |
||||
* complete. |
||||
* |
||||
* These are allocated/freed through the endpoint they're used with. The |
||||
* hardware's driver can add extra per-request data to the memory it returns, |
||||
* which often avoids separate memory allocations (potential failures), |
||||
* later when the request is queued. |
||||
* |
||||
* Request flags affect request handling, such as whether a zero length |
||||
* packet is written (the "zero" flag), whether a short read should be |
||||
* treated as an error (blocking request queue advance, the "short_not_ok" |
||||
* flag), or hinting that an interrupt is not required (the "no_interrupt" |
||||
* flag, for use with deep request queues). |
||||
* |
||||
* Bulk endpoints can use any size buffers, and can also be used for interrupt |
||||
* transfers. interrupt-only endpoints can be much less functional. |
||||
*/ |
||||
// NOTE this is analagous to 'struct urb' on the host side,
|
||||
// except that it's thinner and promotes more pre-allocation.
|
||||
|
||||
struct usb_request { |
||||
void *buf; |
||||
unsigned length; |
||||
dma_addr_t dma; |
||||
|
||||
unsigned no_interrupt:1; |
||||
unsigned zero:1; |
||||
unsigned short_not_ok:1; |
||||
|
||||
void (*complete)(struct usb_ep *ep, |
||||
struct usb_request *req); |
||||
void *context; |
||||
struct list_head list; |
||||
|
||||
int status; |
||||
unsigned actual; |
||||
}; |
||||
|
||||
/*-------------------------------------------------------------------------*/ |
||||
|
||||
/* endpoint-specific parts of the api to the usb controller hardware.
|
||||
* unlike the urb model, (de)multiplexing layers are not required. |
||||
* (so this api could slash overhead if used on the host side...) |
||||
* |
||||
* note that device side usb controllers commonly differ in how many |
||||
* endpoints they support, as well as their capabilities. |
||||
*/ |
||||
struct usb_ep_ops { |
||||
int (*enable) (struct usb_ep *ep, |
||||
const struct usb_endpoint_descriptor *desc); |
||||
int (*disable) (struct usb_ep *ep); |
||||
|
||||
struct usb_request *(*alloc_request) (struct usb_ep *ep, |
||||
gfp_t gfp_flags); |
||||
void (*free_request) (struct usb_ep *ep, struct usb_request *req); |
||||
|
||||
int (*queue) (struct usb_ep *ep, struct usb_request *req, |
||||
gfp_t gfp_flags); |
||||
int (*dequeue) (struct usb_ep *ep, struct usb_request *req); |
||||
|
||||
int (*set_halt) (struct usb_ep *ep, int value); |
||||
int (*fifo_status) (struct usb_ep *ep); |
||||
void (*fifo_flush) (struct usb_ep *ep); |
||||
}; |
||||
|
||||
/**
|
||||
* struct usb_ep - device side representation of USB endpoint |
||||
* @name:identifier for the endpoint, such as "ep-a" or "ep9in-bulk" |
||||
* @ops: Function pointers used to access hardware-specific operations. |
||||
* @ep_list:the gadget's ep_list holds all of its endpoints |
||||
* @maxpacket:The maximum packet size used on this endpoint. The initial |
||||
* value can sometimes be reduced (hardware allowing), according to |
||||
* the endpoint descriptor used to configure the endpoint. |
||||
* @driver_data:for use by the gadget driver. all other fields are |
||||
* read-only to gadget drivers. |
||||
* |
||||
* the bus controller driver lists all the general purpose endpoints in |
||||
* gadget->ep_list. the control endpoint (gadget->ep0) is not in that list, |
||||
* and is accessed only in response to a driver setup() callback. |
||||
*/ |
||||
struct usb_ep { |
||||
void *driver_data; |
||||
const char *name; |
||||
const struct usb_ep_ops *ops; |
||||
struct list_head ep_list; |
||||
unsigned maxpacket:16; |
||||
}; |
||||
|
||||
/*-------------------------------------------------------------------------*/ |
||||
|
||||
/**
|
||||
* usb_ep_enable - configure endpoint, making it usable |
||||
* @ep:the endpoint being configured. may not be the endpoint named "ep0". |
||||
* drivers discover endpoints through the ep_list of a usb_gadget. |
||||
* @desc:descriptor for desired behavior. caller guarantees this pointer |
||||
* remains valid until the endpoint is disabled; the data byte order |
||||
* is little-endian (usb-standard). |
||||
* |
||||
* when configurations are set, or when interface settings change, the driver |
||||
* will enable or disable the relevant endpoints. while it is enabled, an |
||||
* endpoint may be used for i/o until the driver receives a disconnect() from |
||||
* the host or until the endpoint is disabled. |
||||
* |
||||
* the ep0 implementation (which calls this routine) must ensure that the |
||||
* hardware capabilities of each endpoint match the descriptor provided |
||||
* for it. for example, an endpoint named "ep2in-bulk" would be usable |
||||
* for interrupt transfers as well as bulk, but it likely couldn't be used |
||||
* for iso transfers or for endpoint 14. some endpoints are fully |
||||
* configurable, with more generic names like "ep-a". (remember that for |
||||
* USB, "in" means "towards the USB master".) |
||||
* |
||||
* returns zero, or a negative error code. |
||||
*/ |
||||
static inline int |
||||
usb_ep_enable (struct usb_ep *ep, const struct usb_endpoint_descriptor *desc) |
||||
{ |
||||
return ep->ops->enable (ep, desc); |
||||
} |
||||
|
||||
/**
|
||||
* usb_ep_disable - endpoint is no longer usable |
||||
* @ep:the endpoint being unconfigured. may not be the endpoint named "ep0". |
||||
* |
||||
* no other task may be using this endpoint when this is called. |
||||
* any pending and uncompleted requests will complete with status |
||||
* indicating disconnect (-ESHUTDOWN) before this call returns. |
||||
* gadget drivers must call usb_ep_enable() again before queueing |
||||
* requests to the endpoint. |
||||
* |
||||
* returns zero, or a negative error code. |
||||
*/ |
||||
static inline int |
||||
usb_ep_disable (struct usb_ep *ep) |
||||
{ |
||||
return ep->ops->disable (ep); |
||||
} |
||||
|
||||
/**
|
||||
* usb_ep_alloc_request - allocate a request object to use with this endpoint |
||||
* @ep:the endpoint to be used with with the request |
||||
* @gfp_flags:GFP_* flags to use |
||||
* |
||||
* Request objects must be allocated with this call, since they normally |
||||
* need controller-specific setup and may even need endpoint-specific |
||||
* resources such as allocation of DMA descriptors. |
||||
* Requests may be submitted with usb_ep_queue(), and receive a single |
||||
* completion callback. Free requests with usb_ep_free_request(), when |
||||
* they are no longer needed. |
||||
* |
||||
* Returns the request, or null if one could not be allocated. |
||||
*/ |
||||
static inline struct usb_request * |
||||
usb_ep_alloc_request (struct usb_ep *ep, gfp_t gfp_flags) |
||||
{ |
||||
return ep->ops->alloc_request (ep, gfp_flags); |
||||
} |
||||
|
||||
/**
|
||||
* usb_ep_free_request - frees a request object |
||||
* @ep:the endpoint associated with the request |
||||
* @req:the request being freed |
||||
* |
||||
* Reverses the effect of usb_ep_alloc_request(). |
||||
* Caller guarantees the request is not queued, and that it will |
||||
* no longer be requeued (or otherwise used). |
||||
*/ |
||||
static inline void |
||||
usb_ep_free_request (struct usb_ep *ep, struct usb_request *req) |
||||
{ |
||||
ep->ops->free_request (ep, req); |
||||
} |
||||
|
||||
/**
|
||||
* usb_ep_queue - queues (submits) an I/O request to an endpoint. |
||||
* @ep:the endpoint associated with the request |
||||
* @req:the request being submitted |
||||
* @gfp_flags: GFP_* flags to use in case the lower level driver couldn't |
||||
* pre-allocate all necessary memory with the request. |
||||
* |
||||
* This tells the device controller to perform the specified request through |
||||
* that endpoint (reading or writing a buffer). When the request completes, |
||||
* including being canceled by usb_ep_dequeue(), the request's completion |
||||
* routine is called to return the request to the driver. Any endpoint |
||||
* (except control endpoints like ep0) may have more than one transfer |
||||
* request queued; they complete in FIFO order. Once a gadget driver |
||||
* submits a request, that request may not be examined or modified until it |
||||
* is given back to that driver through the completion callback. |
||||
* |
||||
* Each request is turned into one or more packets. The controller driver |
||||
* never merges adjacent requests into the same packet. OUT transfers |
||||
* will sometimes use data that's already buffered in the hardware. |
||||
* Drivers can rely on the fact that the first byte of the request's buffer |
||||
* always corresponds to the first byte of some USB packet, for both |
||||
* IN and OUT transfers. |
||||
* |
||||
* Bulk endpoints can queue any amount of data; the transfer is packetized |
||||
* automatically. The last packet will be short if the request doesn't fill it |
||||
* out completely. Zero length packets (ZLPs) should be avoided in portable |
||||
* protocols since not all usb hardware can successfully handle zero length |
||||
* packets. (ZLPs may be explicitly written, and may be implicitly written if |
||||
* the request 'zero' flag is set.) Bulk endpoints may also be used |
||||
* for interrupt transfers; but the reverse is not true, and some endpoints |
||||
* won't support every interrupt transfer. (Such as 768 byte packets.) |
||||
* |
||||
* Interrupt-only endpoints are less functional than bulk endpoints, for |
||||
* example by not supporting queueing or not handling buffers that are |
||||
* larger than the endpoint's maxpacket size. They may also treat data |
||||
* toggle differently. |
||||
* |
||||
* Control endpoints ... after getting a setup() callback, the driver queues |
||||
* one response (even if it would be zero length). That enables the |
||||
* status ack, after transfering data as specified in the response. Setup |
||||
* functions may return negative error codes to generate protocol stalls. |
||||
* (Note that some USB device controllers disallow protocol stall responses |
||||
* in some cases.) When control responses are deferred (the response is |
||||
* written after the setup callback returns), then usb_ep_set_halt() may be |
||||
* used on ep0 to trigger protocol stalls. |
||||
* |
||||
* For periodic endpoints, like interrupt or isochronous ones, the usb host |
||||
* arranges to poll once per interval, and the gadget driver usually will |
||||
* have queued some data to transfer at that time. |
||||
* |
||||
* Returns zero, or a negative error code. Endpoints that are not enabled |
||||
* report errors; errors will also be |
||||
* reported when the usb peripheral is disconnected. |
||||
*/ |
||||
static inline int |
||||
usb_ep_queue (struct usb_ep *ep, struct usb_request *req, gfp_t gfp_flags) |
||||
{ |
||||
return ep->ops->queue (ep, req, gfp_flags); |
||||
} |
||||
|
||||
/**
|
||||
* usb_ep_dequeue - dequeues (cancels, unlinks) an I/O request from an endpoint |
||||
* @ep:the endpoint associated with the request |
||||
* @req:the request being canceled |
||||
* |
||||
* if the request is still active on the endpoint, it is dequeued and its |
||||
* completion routine is called (with status -ECONNRESET); else a negative |
||||
* error code is returned. |
||||
* |
||||
* note that some hardware can't clear out write fifos (to unlink the request |
||||
* at the head of the queue) except as part of disconnecting from usb. such |
||||
* restrictions prevent drivers from supporting configuration changes, |
||||
* even to configuration zero (a "chapter 9" requirement). |
||||
*/ |
||||
static inline int usb_ep_dequeue (struct usb_ep *ep, struct usb_request *req) |
||||
{ |
||||
return ep->ops->dequeue (ep, req); |
||||
} |
||||
|
||||
/**
|
||||
* usb_ep_set_halt - sets the endpoint halt feature. |
||||
* @ep: the non-isochronous endpoint being stalled |
||||
* |
||||
* Use this to stall an endpoint, perhaps as an error report. |
||||
* Except for control endpoints, |
||||
* the endpoint stays halted (will not stream any data) until the host |
||||
* clears this feature; drivers may need to empty the endpoint's request |
||||
* queue first, to make sure no inappropriate transfers happen. |
||||
* |
||||
* Note that while an endpoint CLEAR_FEATURE will be invisible to the |
||||
* gadget driver, a SET_INTERFACE will not be. To reset endpoints for the |
||||
* current altsetting, see usb_ep_clear_halt(). When switching altsettings, |
||||
* it's simplest to use usb_ep_enable() or usb_ep_disable() for the endpoints. |
||||
* |
||||
* Returns zero, or a negative error code. On success, this call sets |
||||
* underlying hardware state that blocks data transfers. |
||||
* Attempts to halt IN endpoints will fail (returning -EAGAIN) if any |
||||
* transfer requests are still queued, or if the controller hardware |
||||
* (usually a FIFO) still holds bytes that the host hasn't collected. |
||||
*/ |
||||
static inline int |
||||
usb_ep_set_halt (struct usb_ep *ep) |
||||
{ |
||||
return ep->ops->set_halt (ep, 1); |
||||
} |
||||
|
||||
/**
|
||||
* usb_ep_clear_halt - clears endpoint halt, and resets toggle |
||||
* @ep:the bulk or interrupt endpoint being reset |
||||
* |
||||
* Use this when responding to the standard usb "set interface" request, |
||||
* for endpoints that aren't reconfigured, after clearing any other state |
||||
* in the endpoint's i/o queue. |
||||
* |
||||
* Returns zero, or a negative error code. On success, this call clears |
||||
* the underlying hardware state reflecting endpoint halt and data toggle. |
||||
* Note that some hardware can't support this request (like pxa2xx_udc), |
||||
* and accordingly can't correctly implement interface altsettings. |
||||
*/ |
||||
static inline int |
||||
usb_ep_clear_halt (struct usb_ep *ep) |
||||
{ |
||||
return ep->ops->set_halt (ep, 0); |
||||
} |
||||
|
||||
/**
|
||||
* usb_ep_fifo_status - returns number of bytes in fifo, or error |
||||
* @ep: the endpoint whose fifo status is being checked. |
||||
* |
||||
* FIFO endpoints may have "unclaimed data" in them in certain cases, |
||||
* such as after aborted transfers. Hosts may not have collected all |
||||
* the IN data written by the gadget driver (and reported by a request |
||||
* completion). The gadget driver may not have collected all the data |
||||
* written OUT to it by the host. Drivers that need precise handling for |
||||
* fault reporting or recovery may need to use this call. |
||||
* |
||||
* This returns the number of such bytes in the fifo, or a negative |
||||
* errno if the endpoint doesn't use a FIFO or doesn't support such |
||||
* precise handling. |
||||
*/ |
||||
static inline int |
||||
usb_ep_fifo_status (struct usb_ep *ep) |
||||
{ |
||||
if (ep->ops->fifo_status) |
||||
return ep->ops->fifo_status (ep); |
||||
else |
||||
return -EOPNOTSUPP; |
||||
} |
||||
|
||||
/**
|
||||
* usb_ep_fifo_flush - flushes contents of a fifo |
||||
* @ep: the endpoint whose fifo is being flushed. |
||||
* |
||||
* This call may be used to flush the "unclaimed data" that may exist in |
||||
* an endpoint fifo after abnormal transaction terminations. The call |
||||
* must never be used except when endpoint is not being used for any |
||||
* protocol translation. |
||||
*/ |
||||
static inline void |
||||
usb_ep_fifo_flush (struct usb_ep *ep) |
||||
{ |
||||
if (ep->ops->fifo_flush) |
||||
ep->ops->fifo_flush (ep); |
||||
} |
||||
|
||||
|
||||
/*-------------------------------------------------------------------------*/ |
||||
|
||||
struct usb_gadget; |
||||
|
||||
/* the rest of the api to the controller hardware: device operations,
|
||||
* which don't involve endpoints (or i/o). |
||||
*/ |
||||
struct usb_gadget_ops { |
||||
int (*get_frame)(struct usb_gadget *); |
||||
int (*wakeup)(struct usb_gadget *); |
||||
int (*set_selfpowered) (struct usb_gadget *, int is_selfpowered); |
||||
int (*vbus_session) (struct usb_gadget *, int is_active); |
||||
int (*vbus_draw) (struct usb_gadget *, unsigned mA); |
||||
int (*pullup) (struct usb_gadget *, int is_on); |
||||
int (*ioctl)(struct usb_gadget *, |
||||
unsigned code, unsigned long param); |
||||
}; |
||||
|
||||
struct device { |
||||
void *driver_data; /* data private to the driver */ |
||||
}; |
||||
|
||||
/**
|
||||
* struct usb_gadget - represents a usb slave device |
||||
* @ops: Function pointers used to access hardware-specific operations. |
||||
* @ep0: Endpoint zero, used when reading or writing responses to |
||||
* driver setup() requests |
||||
* @ep_list: List of other endpoints supported by the device. |
||||
* @speed: Speed of current connection to USB host. |
||||
* @is_dualspeed: True if the controller supports both high and full speed |
||||
* operation. If it does, the gadget driver must also support both. |
||||
* @is_otg: True if the USB device port uses a Mini-AB jack, so that the |
||||
* gadget driver must provide a USB OTG descriptor. |
||||
* @is_a_peripheral: False unless is_otg, the "A" end of a USB cable |
||||
* is in the Mini-AB jack, and HNP has been used to switch roles |
||||
* so that the "A" device currently acts as A-Peripheral, not A-Host. |
||||
* @a_hnp_support: OTG device feature flag, indicating that the A-Host |
||||
* supports HNP at this port. |
||||
* @a_alt_hnp_support: OTG device feature flag, indicating that the A-Host |
||||
* only supports HNP on a different root port. |
||||
* @b_hnp_enable: OTG device feature flag, indicating that the A-Host |
||||
* enabled HNP support. |
||||
* @name: Identifies the controller hardware type. Used in diagnostics |
||||
* and sometimes configuration. |
||||
* @dev: Driver model state for this abstract device. |
||||
* |
||||
* Gadgets have a mostly-portable "gadget driver" implementing device |
||||
* functions, handling all usb configurations and interfaces. Gadget |
||||
* drivers talk to hardware-specific code indirectly, through ops vectors. |
||||
* That insulates the gadget driver from hardware details, and packages |
||||
* the hardware endpoints through generic i/o queues. The "usb_gadget" |
||||
* and "usb_ep" interfaces provide that insulation from the hardware. |
||||
* |
||||
* Except for the driver data, all fields in this structure are |
||||
* read-only to the gadget driver. That driver data is part of the |
||||
* "driver model" infrastructure in 2.6 (and later) kernels, and for |
||||
* earlier systems is grouped in a similar structure that's not known |
||||
* to the rest of the kernel. |
||||
* |
||||
* Values of the three OTG device feature flags are updated before the |
||||
* setup() call corresponding to USB_REQ_SET_CONFIGURATION, and before |
||||
* driver suspend() calls. They are valid only when is_otg, and when the |
||||
* device is acting as a B-Peripheral (so is_a_peripheral is false). |
||||
*/ |
||||
struct usb_gadget { |
||||
/* readonly to gadget driver */ |
||||
const struct usb_gadget_ops *ops; |
||||
struct usb_ep *ep0; |
||||
struct list_head ep_list; /* of usb_ep */ |
||||
enum usb_device_speed speed; |
||||
unsigned is_dualspeed:1; |
||||
unsigned is_otg:1; |
||||
unsigned is_a_peripheral:1; |
||||
unsigned b_hnp_enable:1; |
||||
unsigned a_hnp_support:1; |
||||
unsigned a_alt_hnp_support:1; |
||||
const char *name; |
||||
struct device dev; |
||||
}; |
||||
|
||||
static inline void set_gadget_data (struct usb_gadget *gadget, void *data) |
||||
{ |
||||
gadget->dev.driver_data = data; |
||||
} |
||||
|
||||
static inline void *get_gadget_data (struct usb_gadget *gadget) |
||||
{ |
||||
return gadget->dev.driver_data; |
||||
} |
||||
|
||||
/* iterates the non-control endpoints; 'tmp' is a struct usb_ep pointer */ |
||||
#define gadget_for_each_ep(tmp,gadget) \ |
||||
list_for_each_entry(tmp, &(gadget)->ep_list, ep_list) |
||||
|
||||
|
||||
/**
|
||||
* gadget_is_dualspeed - return true iff the hardware handles high speed |
||||
* @g: controller that might support both high and full speeds |
||||
*/ |
||||
static inline int gadget_is_dualspeed(struct usb_gadget *g) |
||||
{ |
||||
#ifdef CONFIG_USB_GADGET_DUALSPEED |
||||
/* runtime test would check "g->is_dualspeed" ... that might be
|
||||
* useful to work around hardware bugs, but is mostly pointless |
||||
*/ |
||||
return 1; |
||||
#else |
||||
return 0; |
||||
#endif |
||||
} |
||||
|
||||
/**
|
||||
* gadget_is_otg - return true iff the hardware is OTG-ready |
||||
* @g: controller that might have a Mini-AB connector |
||||
* |
||||
* This is a runtime test, since kernels with a USB-OTG stack sometimes |
||||
* run on boards which only have a Mini-B (or Mini-A) connector. |
||||
*/ |
||||
static inline int gadget_is_otg(struct usb_gadget *g) |
||||
{ |
||||
#ifdef CONFIG_USB_OTG |
||||
return g->is_otg; |
||||
#else |
||||
return 0; |
||||
#endif |
||||
} |
||||
|
||||
|
||||
/**
|
||||
* usb_gadget_frame_number - returns the current frame number |
||||
* @gadget: controller that reports the frame number |
||||
* |
||||
* Returns the usb frame number, normally eleven bits from a SOF packet, |
||||
* or negative errno if this device doesn't support this capability. |
||||
*/ |
||||
static inline int usb_gadget_frame_number (struct usb_gadget *gadget) |
||||
{ |
||||
return gadget->ops->get_frame (gadget); |
||||
} |
||||
|
||||
/**
|
||||
* usb_gadget_wakeup - tries to wake up the host connected to this gadget |
||||
* @gadget: controller used to wake up the host |
||||
* |
||||
* Returns zero on success, else negative error code if the hardware |
||||
* doesn't support such attempts, or its support has not been enabled |
||||
* by the usb host. Drivers must return device descriptors that report |
||||
* their ability to support this, or hosts won't enable it. |
||||
* |
||||
* This may also try to use SRP to wake the host and start enumeration, |
||||
* even if OTG isn't otherwise in use. OTG devices may also start |
||||
* remote wakeup even when hosts don't explicitly enable it. |
||||
*/ |
||||
static inline int usb_gadget_wakeup (struct usb_gadget *gadget) |
||||
{ |
||||
if (!gadget->ops->wakeup) |
||||
return -EOPNOTSUPP; |
||||
return gadget->ops->wakeup (gadget); |
||||
} |
||||
|
||||
/**
|
||||
* usb_gadget_set_selfpowered - sets the device selfpowered feature. |
||||
* @gadget:the device being declared as self-powered |
||||
* |
||||
* this affects the device status reported by the hardware driver |
||||
* to reflect that it now has a local power supply. |
||||
* |
||||
* returns zero on success, else negative errno. |
||||
*/ |
||||
static inline int |
||||
usb_gadget_set_selfpowered (struct usb_gadget *gadget) |
||||
{ |
||||
if (!gadget->ops->set_selfpowered) |
||||
return -EOPNOTSUPP; |
||||
return gadget->ops->set_selfpowered (gadget, 1); |
||||
} |
||||
|
||||
/**
|
||||
* usb_gadget_clear_selfpowered - clear the device selfpowered feature. |
||||
* @gadget:the device being declared as bus-powered |
||||
* |
||||
* this affects the device status reported by the hardware driver. |
||||
* some hardware may not support bus-powered operation, in which |
||||
* case this feature's value can never change. |
||||
* |
||||
* returns zero on success, else negative errno. |
||||
*/ |
||||
static inline int |
||||
usb_gadget_clear_selfpowered (struct usb_gadget *gadget) |
||||
{ |
||||
if (!gadget->ops->set_selfpowered) |
||||
return -EOPNOTSUPP; |
||||
return gadget->ops->set_selfpowered (gadget, 0); |
||||
} |
||||
|
||||
/**
|
||||
* usb_gadget_vbus_connect - Notify controller that VBUS is powered |
||||
* @gadget:The device which now has VBUS power. |
||||
* |
||||
* This call is used by a driver for an external transceiver (or GPIO) |
||||
* that detects a VBUS power session starting. Common responses include |
||||
* resuming the controller, activating the D+ (or D-) pullup to let the |
||||
* host detect that a USB device is attached, and starting to draw power |
||||
* (8mA or possibly more, especially after SET_CONFIGURATION). |
||||
* |
||||
* Returns zero on success, else negative errno. |
||||
*/ |
||||
static inline int |
||||
usb_gadget_vbus_connect(struct usb_gadget *gadget) |
||||
{ |
||||
if (!gadget->ops->vbus_session) |
||||
return -EOPNOTSUPP; |
||||
return gadget->ops->vbus_session (gadget, 1); |
||||
} |
||||
|
||||
/**
|
||||
* usb_gadget_vbus_draw - constrain controller's VBUS power usage |
||||
* @gadget:The device whose VBUS usage is being described |
||||
* @mA:How much current to draw, in milliAmperes. This should be twice |
||||
* the value listed in the configuration descriptor bMaxPower field. |
||||
* |
||||
* This call is used by gadget drivers during SET_CONFIGURATION calls, |
||||
* reporting how much power the device may consume. For example, this |
||||
* could affect how quickly batteries are recharged. |
||||
* |
||||
* Returns zero on success, else negative errno. |
||||
*/ |
||||
static inline int |
||||
usb_gadget_vbus_draw(struct usb_gadget *gadget, unsigned mA) |
||||
{ |
||||
if (!gadget->ops->vbus_draw) |
||||
return -EOPNOTSUPP; |
||||
return gadget->ops->vbus_draw (gadget, mA); |
||||
} |
||||
|
||||
/**
|
||||
* usb_gadget_vbus_disconnect - notify controller about VBUS session end |
||||
* @gadget:the device whose VBUS supply is being described |
||||
* |
||||
* This call is used by a driver for an external transceiver (or GPIO) |
||||
* that detects a VBUS power session ending. Common responses include |
||||
* reversing everything done in usb_gadget_vbus_connect(). |
||||
* |
||||
* Returns zero on success, else negative errno. |
||||
*/ |
||||
static inline int |
||||
usb_gadget_vbus_disconnect(struct usb_gadget *gadget) |
||||
{ |
||||
if (!gadget->ops->vbus_session) |
||||
return -EOPNOTSUPP; |
||||
return gadget->ops->vbus_session (gadget, 0); |
||||
} |
||||
|
||||
/**
|
||||
* usb_gadget_connect - software-controlled connect to USB host |
||||
* @gadget:the peripheral being connected |
||||
* |
||||
* Enables the D+ (or potentially D-) pullup. The host will start |
||||
* enumerating this gadget when the pullup is active and a VBUS session |
||||
* is active (the link is powered). This pullup is always enabled unless |
||||
* usb_gadget_disconnect() has been used to disable it. |
||||
* |
||||
* Returns zero on success, else negative errno. |
||||
*/ |
||||
static inline int |
||||
usb_gadget_connect (struct usb_gadget *gadget) |
||||
{ |
||||
if (!gadget->ops->pullup) |
||||
return -EOPNOTSUPP; |
||||
return gadget->ops->pullup (gadget, 1); |
||||
} |
||||
|
||||
/**
|
||||
* usb_gadget_disconnect - software-controlled disconnect from USB host |
||||
* @gadget:the peripheral being disconnected |
||||
* |
||||
* Disables the D+ (or potentially D-) pullup, which the host may see |
||||
* as a disconnect (when a VBUS session is active). Not all systems |
||||
* support software pullup controls. |
||||
* |
||||
* This routine may be used during the gadget driver bind() call to prevent |
||||
* the peripheral from ever being visible to the USB host, unless later |
||||
* usb_gadget_connect() is called. For example, user mode components may |
||||
* need to be activated before the system can talk to hosts. |
||||
* |
||||
* Returns zero on success, else negative errno. |
||||
*/ |
||||
static inline int |
||||
usb_gadget_disconnect (struct usb_gadget *gadget) |
||||
{ |
||||
if (!gadget->ops->pullup) |
||||
return -EOPNOTSUPP; |
||||
return gadget->ops->pullup (gadget, 0); |
||||
} |
||||
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------*/ |
||||
|
||||
/**
|
||||
* struct usb_gadget_driver - driver for usb 'slave' devices |
||||
* @speed: Highest speed the driver handles. |
||||
* @bind: Invoked when the driver is bound to a gadget, usually |
||||
* after registering the driver. |
||||
* At that point, ep0 is fully initialized, and ep_list holds |
||||
* the currently-available endpoints. |
||||
* Called in a context that permits sleeping. |
||||
* @setup: Invoked for ep0 control requests that aren't handled by |
||||
* the hardware level driver. Most calls must be handled by |
||||
* the gadget driver, including descriptor and configuration |
||||
* management. The 16 bit members of the setup data are in |
||||
* USB byte order. Called in_interrupt; this may not sleep. Driver |
||||
* queues a response to ep0, or returns negative to stall. |
||||
* @disconnect: Invoked after all transfers have been stopped, |
||||
* when the host is disconnected. May be called in_interrupt; this |
||||
* may not sleep. Some devices can't detect disconnect, so this might |
||||
* not be called except as part of controller shutdown. |
||||
* @unbind: Invoked when the driver is unbound from a gadget, |
||||
* usually from rmmod (after a disconnect is reported). |
||||
* Called in a context that permits sleeping. |
||||
* @suspend: Invoked on USB suspend. May be called in_interrupt. |
||||
* @resume: Invoked on USB resume. May be called in_interrupt. |
||||
* |
||||
* Devices are disabled till a gadget driver successfully bind()s, which |
||||
* means the driver will handle setup() requests needed to enumerate (and |
||||
* meet "chapter 9" requirements) then do some useful work. |
||||
* |
||||
* If gadget->is_otg is true, the gadget driver must provide an OTG |
||||
* descriptor during enumeration, or else fail the bind() call. In such |
||||
* cases, no USB traffic may flow until both bind() returns without |
||||
* having called usb_gadget_disconnect(), and the USB host stack has |
||||
* initialized. |
||||
* |
||||
* Drivers use hardware-specific knowledge to configure the usb hardware. |
||||
* endpoint addressing is only one of several hardware characteristics that |
||||
* are in descriptors the ep0 implementation returns from setup() calls. |
||||
* |
||||
* Except for ep0 implementation, most driver code shouldn't need change to |
||||
* run on top of different usb controllers. It'll use endpoints set up by |
||||
* that ep0 implementation. |
||||
* |
||||
* The usb controller driver handles a few standard usb requests. Those |
||||
* include set_address, and feature flags for devices, interfaces, and |
||||
* endpoints (the get_status, set_feature, and clear_feature requests). |
||||
* |
||||
* Accordingly, the driver's setup() callback must always implement all |
||||
* get_descriptor requests, returning at least a device descriptor and |
||||
* a configuration descriptor. Drivers must make sure the endpoint |
||||
* descriptors match any hardware constraints. Some hardware also constrains |
||||
* other descriptors. (The pxa250 allows only configurations 1, 2, or 3). |
||||
* |
||||
* The driver's setup() callback must also implement set_configuration, |
||||
* and should also implement set_interface, get_configuration, and |
||||
* get_interface. Setting a configuration (or interface) is where |
||||
* endpoints should be activated or (config 0) shut down. |
||||
* |
||||
* (Note that only the default control endpoint is supported. Neither |
||||
* hosts nor devices generally support control traffic except to ep0.) |
||||
* |
||||
* Most devices will ignore USB suspend/resume operations, and so will |
||||
* not provide those callbacks. However, some may need to change modes |
||||
* when the host is not longer directing those activities. For example, |
||||
* local controls (buttons, dials, etc) may need to be re-enabled since |
||||
* the (remote) host can't do that any longer; or an error state might |
||||
* be cleared, to make the device behave identically whether or not |
||||
* power is maintained. |
||||
*/ |
||||
struct usb_gadget_driver { |
||||
enum usb_device_speed speed; |
||||
int (*bind)(struct usb_gadget *); |
||||
void (*unbind)(struct usb_gadget *); |
||||
int (*setup)(struct usb_gadget *, |
||||
const struct usb_ctrlrequest *); |
||||
void (*disconnect)(struct usb_gadget *); |
||||
void (*suspend)(struct usb_gadget *); |
||||
void (*resume)(struct usb_gadget *); |
||||
}; |
||||
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------*/ |
||||
|
||||
/* driver modules register and unregister, as usual.
|
||||
* these calls must be made in a context that can sleep. |
||||
* |
||||
* these will usually be implemented directly by the hardware-dependent |
||||
* usb bus interface driver, which will only support a single driver. |
||||
*/ |
||||
|
||||
/**
|
||||
* usb_gadget_register_driver - register a gadget driver |
||||
* @driver:the driver being registered |
||||
* |
||||
* Call this in your gadget driver's module initialization function, |
||||
* to tell the underlying usb controller driver about your driver. |
||||
* The driver's bind() function will be called to bind it to a |
||||
* gadget before this registration call returns. It's expected that |
||||
* the bind() functions will be in init sections. |
||||
* This function must be called in a context that can sleep. |
||||
*/ |
||||
int usb_gadget_register_driver (struct usb_gadget_driver *driver); |
||||
|
||||
/**
|
||||
* usb_gadget_unregister_driver - unregister a gadget driver |
||||
* @driver:the driver being unregistered |
||||
* |
||||
* Call this in your gadget driver's module cleanup function, |
||||
* to tell the underlying usb controller that your driver is |
||||
* going away. If the controller is connected to a USB host, |
||||
* it will first disconnect(). The driver is also requested |
||||
* to unbind() and clean up any device state, before this procedure |
||||
* finally returns. It's expected that the unbind() functions |
||||
* will in in exit sections, so may not be linked in some kernels. |
||||
* This function must be called in a context that can sleep. |
||||
*/ |
||||
int usb_gadget_unregister_driver (struct usb_gadget_driver *driver); |
||||
|
||||
/*-------------------------------------------------------------------------*/ |
||||
|
||||
/* utility to simplify dealing with string descriptors */ |
||||
|
||||
/**
|
||||
* struct usb_string - wraps a C string and its USB id |
||||
* @id:the (nonzero) ID for this string |
||||
* @s:the string, in UTF-8 encoding |
||||
* |
||||
* If you're using usb_gadget_get_string(), use this to wrap a string |
||||
* together with its ID. |
||||
*/ |
||||
struct usb_string { |
||||
u8 id; |
||||
const char *s; |
||||
}; |
||||
|
||||
/**
|
||||
* struct usb_gadget_strings - a set of USB strings in a given language |
||||
* @language:identifies the strings' language (0x0409 for en-us) |
||||
* @strings:array of strings with their ids |
||||
* |
||||
* If you're using usb_gadget_get_string(), use this to wrap all the |
||||
* strings for a given language. |
||||
*/ |
||||
struct usb_gadget_strings { |
||||
u16 language; /* 0x0409 for en-us */ |
||||
struct usb_string *strings; |
||||
}; |
||||
|
||||
/* put descriptor for string with that id into buf (buflen >= 256) */ |
||||
int usb_gadget_get_string (struct usb_gadget_strings *table, int id, u8 *buf); |
||||
|
||||
/*-------------------------------------------------------------------------*/ |
||||
|
||||
/* utility to simplify managing config descriptors */ |
||||
|
||||
/* write vector of descriptors into buffer */ |
||||
int usb_descriptor_fillbuf(void *, unsigned, |
||||
const struct usb_descriptor_header **); |
||||
|
||||
/* build config descriptor from single descriptor vector */ |
||||
int usb_gadget_config_buf(const struct usb_config_descriptor *config, |
||||
void *buf, unsigned buflen, const struct usb_descriptor_header **desc); |
||||
|
||||
/*-------------------------------------------------------------------------*/ |
||||
|
||||
/* utility wrapping a simple endpoint selection policy */ |
||||
|
||||
extern struct usb_ep *usb_ep_autoconfig (struct usb_gadget *, |
||||
struct usb_endpoint_descriptor *); |
||||
|
||||
extern void usb_ep_autoconfig_reset (struct usb_gadget *); |
||||
|
||||
extern int usb_gadget_handle_interrupts(void); |
||||
|
||||
#endif /* __LINUX_USB_GADGET_H */ |
Loading…
Reference in new issue