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