linux/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
   8#include <linux/kernel.h>
   9#include <linux/module.h>
  10#include <linux/types.h>
  11#include <linux/device.h>
  12
  13#include <linux/ctype.h>
  14#include <linux/string.h>
  15
  16#include <linux/usb/ch9.h>
  17#include <linux/usb/gadget.h>
  18
  19/**
  20 * usb_ep_autoconfig_ss() - choose an endpoint matching the ep
  21 * descriptor and ep companion descriptor
  22 * @gadget: The device to which the endpoint must belong.
  23 * @desc: Endpoint descriptor, with endpoint direction and transfer mode
  24 *    initialized.  For periodic transfers, the maximum packet
  25 *    size must also be initialized.  This is modified on
  26 *    success.
  27 * @ep_comp: Endpoint companion descriptor, with the required
  28 *    number of streams. Will be modified when the chosen EP
  29 *    supports a different number of streams.
  30 *
  31 * This routine replaces the usb_ep_autoconfig when needed
  32 * superspeed enhancments. If such enhancemnets are required,
  33 * the FD should call usb_ep_autoconfig_ss directly and provide
  34 * the additional ep_comp parameter.
  35 *
  36 * By choosing an endpoint to use with the specified descriptor,
  37 * this routine simplifies writing gadget drivers that work with
  38 * multiple USB device controllers.  The endpoint would be
  39 * passed later to usb_ep_enable(), along with some descriptor.
  40 *
  41 * That second descriptor won't always be the same as the first one.
  42 * For example, isochronous endpoints can be autoconfigured for high
  43 * bandwidth, and then used in several lower bandwidth altsettings.
  44 * Also, high and full speed descriptors will be different.
  45 *
  46 * Be sure to examine and test the results of autoconfiguration
  47 * on your hardware.  This code may not make the best choices
  48 * about how to use the USB controller, and it can't know all
  49 * the restrictions that may apply. Some combinations of driver
  50 * and hardware won't be able to autoconfigure.
  51 *
  52 * On success, this returns an claimed usb_ep, and modifies the endpoint
  53 * descriptor bEndpointAddress.  For bulk endpoints, the wMaxPacket value
  54 * is initialized as if the endpoint were used at full speed and
  55 * the bmAttribute field in the ep companion descriptor is
  56 * updated with the assigned number of streams if it is
  57 * different from the original value. To prevent the endpoint
  58 * from being returned by a later autoconfig call, claims it by
  59 * assigning ep->claimed to true.
  60 *
  61 * On failure, this returns a null endpoint descriptor.
  62 */
  63struct usb_ep *usb_ep_autoconfig_ss(
  64        struct usb_gadget               *gadget,
  65        struct usb_endpoint_descriptor  *desc,
  66        struct usb_ss_ep_comp_descriptor *ep_comp
  67)
  68{
  69        struct usb_ep   *ep;
  70        u8              type;
  71
  72        type = desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
  73
  74        if (gadget->ops->match_ep) {
  75                ep = gadget->ops->match_ep(gadget, desc, ep_comp);
  76                if (ep)
  77                        goto found_ep;
  78        }
  79
  80        /* Second, look at endpoints until an unclaimed one looks usable */
  81        list_for_each_entry (ep, &gadget->ep_list, ep_list) {
  82                if (usb_gadget_ep_match_desc(gadget, ep, desc, ep_comp))
  83                        goto found_ep;
  84        }
  85
  86        /* Fail */
  87        return NULL;
  88found_ep:
  89
  90        /*
  91         * If the protocol driver hasn't yet decided on wMaxPacketSize
  92         * and wants to know the maximum possible, provide the info.
  93         */
  94        if (desc->wMaxPacketSize == 0)
  95                desc->wMaxPacketSize = cpu_to_le16(ep->maxpacket_limit);
  96
  97        /* report address */
  98        desc->bEndpointAddress &= USB_DIR_IN;
  99        if (isdigit(ep->name[2])) {
 100                u8 num = simple_strtoul(&ep->name[2], NULL, 10);
 101                desc->bEndpointAddress |= num;
 102        } else if (desc->bEndpointAddress & USB_DIR_IN) {
 103                if (++gadget->in_epnum > 15)
 104                        return NULL;
 105                desc->bEndpointAddress = USB_DIR_IN | gadget->in_epnum;
 106        } else {
 107                if (++gadget->out_epnum > 15)
 108                        return NULL;
 109                desc->bEndpointAddress |= gadget->out_epnum;
 110        }
 111
 112        /* report (variable) full speed bulk maxpacket */
 113        if ((type == USB_ENDPOINT_XFER_BULK) && !ep_comp) {
 114                int size = ep->maxpacket_limit;
 115
 116                /* min() doesn't work on bitfields with gcc-3.5 */
 117                if (size > 64)
 118                        size = 64;
 119                desc->wMaxPacketSize = cpu_to_le16(size);
 120        }
 121
 122        ep->address = desc->bEndpointAddress;
 123        ep->desc = NULL;
 124        ep->comp_desc = NULL;
 125        ep->claimed = true;
 126        return ep;
 127}
 128EXPORT_SYMBOL_GPL(usb_ep_autoconfig_ss);
 129
 130/**
 131 * usb_ep_autoconfig() - choose an endpoint matching the
 132 * descriptor
 133 * @gadget: The device to which the endpoint must belong.
 134 * @desc: Endpoint descriptor, with endpoint direction and transfer mode
 135 *      initialized.  For periodic transfers, the maximum packet
 136 *      size must also be initialized.  This is modified on success.
 137 *
 138 * By choosing an endpoint to use with the specified descriptor, this
 139 * routine simplifies writing gadget drivers that work with multiple
 140 * USB device controllers.  The endpoint would be passed later to
 141 * usb_ep_enable(), along with some descriptor.
 142 *
 143 * That second descriptor won't always be the same as the first one.
 144 * For example, isochronous endpoints can be autoconfigured for high
 145 * bandwidth, and then used in several lower bandwidth altsettings.
 146 * Also, high and full speed descriptors will be different.
 147 *
 148 * Be sure to examine and test the results of autoconfiguration on your
 149 * hardware.  This code may not make the best choices about how to use the
 150 * USB controller, and it can't know all the restrictions that may apply.
 151 * Some combinations of driver and hardware won't be able to autoconfigure.
 152 *
 153 * On success, this returns an claimed usb_ep, and modifies the endpoint
 154 * descriptor bEndpointAddress.  For bulk endpoints, the wMaxPacket value
 155 * is initialized as if the endpoint were used at full speed.  To prevent
 156 * the endpoint from being returned by a later autoconfig call, claims it
 157 * by assigning ep->claimed to true.
 158 *
 159 * On failure, this returns a null endpoint descriptor.
 160 */
 161struct usb_ep *usb_ep_autoconfig(
 162        struct usb_gadget               *gadget,
 163        struct usb_endpoint_descriptor  *desc
 164)
 165{
 166        return usb_ep_autoconfig_ss(gadget, desc, NULL);
 167}
 168EXPORT_SYMBOL_GPL(usb_ep_autoconfig);
 169
 170/**
 171 * usb_ep_autoconfig_release - releases endpoint and set it to initial state
 172 * @ep: endpoint which should be released
 173 *
 174 * This function can be used during function bind for endpoints obtained
 175 * from usb_ep_autoconfig(). It unclaims endpoint claimed by
 176 * usb_ep_autoconfig() to make it available for other functions. Endpoint
 177 * which was released is no longer invalid and shouldn't be used in
 178 * context of function which released it.
 179 */
 180void usb_ep_autoconfig_release(struct usb_ep *ep)
 181{
 182        ep->claimed = false;
 183        ep->driver_data = NULL;
 184}
 185EXPORT_SYMBOL_GPL(usb_ep_autoconfig_release);
 186
 187/**
 188 * usb_ep_autoconfig_reset - reset endpoint autoconfig state
 189 * @gadget: device for which autoconfig state will be reset
 190 *
 191 * Use this for devices where one configuration may need to assign
 192 * endpoint resources very differently from the next one.  It clears
 193 * state such as ep->claimed and the record of assigned endpoints
 194 * used by usb_ep_autoconfig().
 195 */
 196void usb_ep_autoconfig_reset (struct usb_gadget *gadget)
 197{
 198        struct usb_ep   *ep;
 199
 200        list_for_each_entry (ep, &gadget->ep_list, ep_list) {
 201                ep->claimed = false;
 202                ep->driver_data = NULL;
 203        }
 204        gadget->in_epnum = 0;
 205        gadget->out_epnum = 0;
 206}
 207EXPORT_SYMBOL_GPL(usb_ep_autoconfig_reset);
 208