uboot/drivers/usb/gadget/epautoconf.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * epautoconf.c -- endpoint autoconfiguration for usb gadget drivers
   4 *
   5 * Copyright (C) 2004 David Brownell
   6 *
   7 * Ported to U-Boot by: Thomas Smits <ts.smits@gmail.com> and
   8 *                      Remy Bohmer <linux@bohmer.net>
   9 */
  10
  11#include <common.h>
  12#include <linux/usb/ch9.h>
  13#include <linux/errno.h>
  14#include <linux/usb/gadget.h>
  15#include <asm/unaligned.h>
  16#include "gadget_chips.h"
  17
  18#define isdigit(c)      ('0' <= (c) && (c) <= '9')
  19
  20/* we must assign addresses for configurable endpoints (like net2280) */
  21static unsigned epnum;
  22
  23/* #define MANY_ENDPOINTS */
  24#ifdef MANY_ENDPOINTS
  25/* more than 15 configurable endpoints */
  26static unsigned in_epnum;
  27#endif
  28
  29
  30/*
  31 * This should work with endpoints from controller drivers sharing the
  32 * same endpoint naming convention.  By example:
  33 *
  34 *      - ep1, ep2, ... address is fixed, not direction or type
  35 *      - ep1in, ep2out, ... address and direction are fixed, not type
  36 *      - ep1-bulk, ep2-bulk, ... address and type are fixed, not direction
  37 *      - ep1in-bulk, ep2out-iso, ... all three are fixed
  38 *      - ep-* ... no functionality restrictions
  39 *
  40 * Type suffixes are "-bulk", "-iso", or "-int".  Numbers are decimal.
  41 * Less common restrictions are implied by gadget_is_*().
  42 *
  43 * NOTE:  each endpoint is unidirectional, as specified by its USB
  44 * descriptor; and isn't specific to a configuration or altsetting.
  45 */
  46static int ep_matches(
  47        struct usb_gadget               *gadget,
  48        struct usb_ep                   *ep,
  49        struct usb_endpoint_descriptor  *desc
  50)
  51{
  52        u8              type;
  53        const char      *tmp;
  54        u16             max;
  55
  56        /* endpoint already claimed? */
  57        if (NULL != ep->driver_data)
  58                return 0;
  59
  60        /* only support ep0 for portable CONTROL traffic */
  61        type = desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
  62        if (USB_ENDPOINT_XFER_CONTROL == type)
  63                return 0;
  64
  65        /* some other naming convention */
  66        if ('e' != ep->name[0])
  67                return 0;
  68
  69        /* type-restriction:  "-iso", "-bulk", or "-int".
  70         * direction-restriction:  "in", "out".
  71         */
  72        if ('-' != ep->name[2]) {
  73                tmp = strrchr(ep->name, '-');
  74                if (tmp) {
  75                        switch (type) {
  76                        case USB_ENDPOINT_XFER_INT:
  77                                /* bulk endpoints handle interrupt transfers,
  78                                 * except the toggle-quirky iso-synch kind
  79                                 */
  80                                if ('s' == tmp[2])      /* == "-iso" */
  81                                        return 0;
  82                                break;
  83                        case USB_ENDPOINT_XFER_BULK:
  84                                if ('b' != tmp[1])      /* != "-bulk" */
  85                                        return 0;
  86                                break;
  87                        case USB_ENDPOINT_XFER_ISOC:
  88                                if ('s' != tmp[2])      /* != "-iso" */
  89                                        return 0;
  90                        }
  91                } else {
  92                        tmp = ep->name + strlen(ep->name);
  93                }
  94
  95                /* direction-restriction:  "..in-..", "out-.." */
  96                tmp--;
  97                if (!isdigit(*tmp)) {
  98                        if (desc->bEndpointAddress & USB_DIR_IN) {
  99                                if ('n' != *tmp)
 100                                        return 0;
 101                        } else {
 102                                if ('t' != *tmp)
 103                                        return 0;
 104                        }
 105                }
 106        }
 107
 108        /* endpoint maxpacket size is an input parameter, except for bulk
 109         * where it's an output parameter representing the full speed limit.
 110         * the usb spec fixes high speed bulk maxpacket at 512 bytes.
 111         */
 112        max = 0x7ff & le16_to_cpu(get_unaligned(&desc->wMaxPacketSize));
 113        switch (type) {
 114        case USB_ENDPOINT_XFER_INT:
 115                /* INT:  limit 64 bytes full speed, 1024 high speed */
 116                if (!gadget->is_dualspeed && max > 64)
 117                        return 0;
 118                /* FALLTHROUGH */
 119
 120        case USB_ENDPOINT_XFER_ISOC:
 121                /* ISO:  limit 1023 bytes full speed, 1024 high speed */
 122                if (ep->maxpacket < max)
 123                        return 0;
 124                if (!gadget->is_dualspeed && max > 1023)
 125                        return 0;
 126
 127                /* BOTH:  "high bandwidth" works only at high speed */
 128                if ((get_unaligned(&desc->wMaxPacketSize) &
 129                                        __constant_cpu_to_le16(3<<11))) {
 130                        if (!gadget->is_dualspeed)
 131                                return 0;
 132                        /* configure your hardware with enough buffering!! */
 133                }
 134                break;
 135        }
 136
 137        /* MATCH!! */
 138
 139        /* report address */
 140        if (isdigit(ep->name[2])) {
 141                u8      num = dectoul(&ep->name[2], NULL);
 142                desc->bEndpointAddress |= num;
 143#ifdef  MANY_ENDPOINTS
 144        } else if (desc->bEndpointAddress & USB_DIR_IN) {
 145                if (++in_epnum > 15)
 146                        return 0;
 147                desc->bEndpointAddress = USB_DIR_IN | in_epnum;
 148#endif
 149        } else {
 150                if (++epnum > 15)
 151                        return 0;
 152                desc->bEndpointAddress |= epnum;
 153        }
 154
 155        /* report (variable) full speed bulk maxpacket */
 156        if (USB_ENDPOINT_XFER_BULK == type) {
 157                int size = ep->maxpacket;
 158
 159                /* min() doesn't work on bitfields with gcc-3.5 */
 160                if (size > 64)
 161                        size = 64;
 162                put_unaligned(cpu_to_le16(size), &desc->wMaxPacketSize);
 163        }
 164
 165        if (gadget->ops->ep_conf)
 166                return gadget->ops->ep_conf(gadget, ep, desc);
 167
 168        return 1;
 169}
 170
 171static struct usb_ep *
 172find_ep(struct usb_gadget *gadget, const char *name)
 173{
 174        struct usb_ep   *ep;
 175
 176        list_for_each_entry(ep, &gadget->ep_list, ep_list) {
 177                if (0 == strcmp(ep->name, name))
 178                        return ep;
 179        }
 180        return NULL;
 181}
 182
 183/**
 184 * usb_ep_autoconfig - choose an endpoint matching the descriptor
 185 * @gadget: The device to which the endpoint must belong.
 186 * @desc: Endpoint descriptor, with endpoint direction and transfer mode
 187 *      initialized.  For periodic transfers, the maximum packet
 188 *      size must also be initialized.  This is modified on success.
 189 *
 190 * By choosing an endpoint to use with the specified descriptor, this
 191 * routine simplifies writing gadget drivers that work with multiple
 192 * USB device controllers.  The endpoint would be passed later to
 193 * usb_ep_enable(), along with some descriptor.
 194 *
 195 * That second descriptor won't always be the same as the first one.
 196 * For example, isochronous endpoints can be autoconfigured for high
 197 * bandwidth, and then used in several lower bandwidth altsettings.
 198 * Also, high and full speed descriptors will be different.
 199 *
 200 * Be sure to examine and test the results of autoconfiguration on your
 201 * hardware.  This code may not make the best choices about how to use the
 202 * USB controller, and it can't know all the restrictions that may apply.
 203 * Some combinations of driver and hardware won't be able to autoconfigure.
 204 *
 205 * On success, this returns an un-claimed usb_ep, and modifies the endpoint
 206 * descriptor bEndpointAddress.  For bulk endpoints, the wMaxPacket value
 207 * is initialized as if the endpoint were used at full speed.  To prevent
 208 * the endpoint from being returned by a later autoconfig call, claim it
 209 * by assigning ep->driver_data to some non-null value.
 210 *
 211 * On failure, this returns a null endpoint descriptor.
 212 */
 213struct usb_ep *usb_ep_autoconfig(
 214        struct usb_gadget               *gadget,
 215        struct usb_endpoint_descriptor  *desc
 216)
 217{
 218        struct usb_ep   *ep = NULL;
 219        u8              type;
 220
 221        type = desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
 222
 223        /* First, apply chip-specific "best usage" knowledge.
 224         * This might make a good usb_gadget_ops hook ...
 225         */
 226        if (gadget_is_net2280(gadget) && type == USB_ENDPOINT_XFER_INT) {
 227                /* ep-e, ep-f are PIO with only 64 byte fifos */
 228                ep = find_ep(gadget, "ep-e");
 229                if (ep && ep_matches(gadget, ep, desc))
 230                        return ep;
 231                ep = find_ep(gadget, "ep-f");
 232                if (ep && ep_matches(gadget, ep, desc))
 233                        return ep;
 234
 235        } else if (gadget_is_goku(gadget)) {
 236                if (USB_ENDPOINT_XFER_INT == type) {
 237                        /* single buffering is enough */
 238                        ep = find_ep(gadget, "ep3-bulk");
 239                        if (ep && ep_matches(gadget, ep, desc))
 240                                return ep;
 241                } else if (USB_ENDPOINT_XFER_BULK == type
 242                                && (USB_DIR_IN & desc->bEndpointAddress)) {
 243                        /* DMA may be available */
 244                        ep = find_ep(gadget, "ep2-bulk");
 245                        if (ep && ep_matches(gadget, ep, desc))
 246                                return ep;
 247                }
 248
 249        } else if (gadget_is_sh(gadget) && USB_ENDPOINT_XFER_INT == type) {
 250                /* single buffering is enough; maybe 8 byte fifo is too */
 251                ep = find_ep(gadget, "ep3in-bulk");
 252                if (ep && ep_matches(gadget, ep, desc))
 253                        return ep;
 254
 255        } else if (gadget_is_mq11xx(gadget) && USB_ENDPOINT_XFER_INT == type) {
 256                ep = find_ep(gadget, "ep1-bulk");
 257                if (ep && ep_matches(gadget, ep, desc))
 258                        return ep;
 259#ifndef CONFIG_SPL_BUILD
 260        } else if (gadget_is_dwc3(gadget)) {
 261                const char *name = NULL;
 262                /*
 263                 * First try standard, common configuration: ep1in-bulk,
 264                 * ep2out-bulk, ep3in-int to match other udc drivers to avoid
 265                 * confusion in already deployed software (endpoint numbers
 266                 * hardcoded in userspace software/drivers)
 267                 */
 268                if ((desc->bEndpointAddress & USB_DIR_IN) &&
 269                    type == USB_ENDPOINT_XFER_BULK)
 270                        name = "ep1in";
 271                else if ((desc->bEndpointAddress & USB_DIR_IN) == 0 &&
 272                         type == USB_ENDPOINT_XFER_BULK)
 273                        name = "ep2out";
 274                else if ((desc->bEndpointAddress & USB_DIR_IN) &&
 275                         type == USB_ENDPOINT_XFER_INT)
 276                        name = "ep3in";
 277
 278                if (name)
 279                        ep = find_ep(gadget, name);
 280                if (ep && ep_matches(gadget, ep, desc))
 281                        return ep;
 282#endif
 283        }
 284
 285        if (gadget->ops->match_ep)
 286                ep = gadget->ops->match_ep(gadget, desc, NULL);
 287
 288        /* Second, look at endpoints until an unclaimed one looks usable */
 289        list_for_each_entry(ep, &gadget->ep_list, ep_list) {
 290                if (ep_matches(gadget, ep, desc))
 291                        return ep;
 292        }
 293
 294        /* Fail */
 295        return NULL;
 296}
 297
 298/**
 299 * usb_ep_autoconfig_reset - reset endpoint autoconfig state
 300 * @gadget: device for which autoconfig state will be reset
 301 *
 302 * Use this for devices where one configuration may need to assign
 303 * endpoint resources very differently from the next one.  It clears
 304 * state such as ep->driver_data and the record of assigned endpoints
 305 * used by usb_ep_autoconfig().
 306 */
 307void usb_ep_autoconfig_reset(struct usb_gadget *gadget)
 308{
 309        struct usb_ep   *ep;
 310
 311        list_for_each_entry(ep, &gadget->ep_list, ep_list) {
 312                ep->driver_data = NULL;
 313        }
 314#ifdef  MANY_ENDPOINTS
 315        in_epnum = 0;
 316#endif
 317        epnum = 0;
 318}
 319