mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-24 21:54:01 +00:00
Integrate USB gadget layer and USB CDC driver layer
Derived from Linux kernel 2.6.27 Signed-off-by: Thomas Smits <ts.smits@gmail.com> Signed-off-by: Remy Bohmer <linux@bohmer.net>
This commit is contained in:
parent
70fccb3f24
commit
23cd138503
10 changed files with 4425 additions and 2 deletions
|
@ -25,6 +25,7 @@ include $(TOPDIR)/config.mk
|
|||
|
||||
LIB := $(obj)libusb_gadget.a
|
||||
|
||||
# Devices not related to the new gadget layer depend on CONFIG_USB_DEVICE
|
||||
ifdef CONFIG_USB_DEVICE
|
||||
COBJS-y += core.o
|
||||
COBJS-y += ep0.o
|
||||
|
@ -34,6 +35,8 @@ COBJS-$(CONFIG_MPC885_FAMILY) += mpc8xx_udc.o
|
|||
COBJS-$(CONFIG_PXA27X) += pxa27x_udc.o
|
||||
COBJS-$(CONFIG_SPEARUDC) += spr_udc.o
|
||||
endif
|
||||
# new USB gadget layer dependencies
|
||||
COBJS-$(CONFIG_USB_ETHER) += ether.o epautoconf.o config.o usbstring.o
|
||||
|
||||
COBJS := $(COBJS-y)
|
||||
SRCS := $(COBJS:.o=.c)
|
||||
|
|
119
drivers/usb/gadget/config.c
Normal file
119
drivers/usb/gadget/config.c
Normal file
|
@ -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;
|
||||
}
|
||||
|
306
drivers/usb/gadget/epautoconf.c
Normal file
306
drivers/usb/gadget/epautoconf.c
Normal file
|
@ -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;
|
||||
}
|
||||
|
1947
drivers/usb/gadget/ether.c
Normal file
1947
drivers/usb/gadget/ether.c
Normal file
File diff suppressed because it is too large
Load diff
219
drivers/usb/gadget/gadget_chips.h
Normal file
219
drivers/usb/gadget/gadget_chips.h
Normal file
|
@ -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;
|
||||
}
|
134
drivers/usb/gadget/usbstring.c
Normal file
134
drivers/usb/gadget/usbstring.c
Normal file
|
@ -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];
|
||||
}
|
||||
|
224
include/linux/usb/cdc.h
Normal file
224
include/linux/usb/cdc.h
Normal file
|
@ -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));
|
||||
|
587
include/linux/usb/ch9.h
Normal file
587
include/linux/usb/ch9.h
Normal file
|
@ -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 */
|
871
include/linux/usb/gadget.h
Normal file
871
include/linux/usb/gadget.h
Normal file
|
@ -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 */
|
|
@ -125,8 +125,10 @@ extern int eth_getenv_enetaddr(char *name, uchar *enetaddr);
|
|||
extern int eth_setenv_enetaddr(char *name, const uchar *enetaddr);
|
||||
extern int eth_getenv_enetaddr_by_index(int index, uchar *enetaddr);
|
||||
|
||||
extern int usb_eth_initialize(bd_t *bi);
|
||||
extern int eth_init(bd_t *bis); /* Initialize the device */
|
||||
extern int eth_send(volatile void *packet, int length); /* Send a packet */
|
||||
|
||||
#ifdef CONFIG_API
|
||||
extern int eth_receive(volatile void *packet, int length); /* Receive a packet*/
|
||||
#endif
|
||||
|
@ -481,7 +483,18 @@ static inline int is_multicast_ether_addr(const u8 *addr)
|
|||
return (0x01 & addr[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* is_broadcast_ether_addr - Determine if the Ethernet address is broadcast
|
||||
* @addr: Pointer to a six-byte array containing the Ethernet address
|
||||
*
|
||||
* Return true if the address is the broadcast address.
|
||||
*/
|
||||
static inline int is_broadcast_ether_addr(const u8 *addr)
|
||||
{
|
||||
return (addr[0] & addr[1] & addr[2] & addr[3] & addr[4] & addr[5]) == 0xff;
|
||||
}
|
||||
|
||||
/*
|
||||
* is_valid_ether_addr - Determine if the given Ethernet address is valid
|
||||
* @addr: Pointer to a six-byte array containing the Ethernet address
|
||||
*
|
||||
|
@ -490,7 +503,7 @@ static inline int is_multicast_ether_addr(const u8 *addr)
|
|||
*
|
||||
* Return true if the address is valid.
|
||||
*/
|
||||
static inline int is_valid_ether_addr(const u8 * addr)
|
||||
static inline int is_valid_ether_addr(const u8 *addr)
|
||||
{
|
||||
/* FF:FF:FF:FF:FF:FF is a multicast address so we don't need to
|
||||
* explicitly check for it here. */
|
||||
|
|
Loading…
Reference in a new issue