linux/drivers/usb/gadget/config.c
<<
>>
Prefs
   1/*
   2 * usb/gadget/config.c -- simplify building config descriptors
   3 *
   4 * Copyright (C) 2003 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/errno.h>
  13#include <linux/slab.h>
  14#include <linux/kernel.h>
  15#include <linux/list.h>
  16#include <linux/string.h>
  17#include <linux/device.h>
  18
  19#include <linux/usb/ch9.h>
  20#include <linux/usb/gadget.h>
  21
  22
  23/**
  24 * usb_descriptor_fillbuf - fill buffer with descriptors
  25 * @buf: Buffer to be filled
  26 * @buflen: Size of buf
  27 * @src: Array of descriptor pointers, terminated by null pointer.
  28 *
  29 * Copies descriptors into the buffer, returning the length or a
  30 * negative error code if they can't all be copied.  Useful when
  31 * assembling descriptors for an associated set of interfaces used
  32 * as part of configuring a composite device; or in other cases where
  33 * sets of descriptors need to be marshaled.
  34 */
  35int
  36usb_descriptor_fillbuf(void *buf, unsigned buflen,
  37                const struct usb_descriptor_header **src)
  38{
  39        u8      *dest = buf;
  40
  41        if (!src)
  42                return -EINVAL;
  43
  44        /* fill buffer from src[] until null descriptor ptr */
  45        for (; NULL != *src; src++) {
  46                unsigned                len = (*src)->bLength;
  47
  48                if (len > buflen)
  49                        return -EINVAL;
  50                memcpy(dest, *src, len);
  51                buflen -= len;
  52                dest += len;
  53        }
  54        return dest - (u8 *)buf;
  55}
  56
  57
  58/**
  59 * usb_gadget_config_buf - builts a complete configuration descriptor
  60 * @config: Header for the descriptor, including characteristics such
  61 *      as power requirements and number of interfaces.
  62 * @desc: Null-terminated vector of pointers to the descriptors (interface,
  63 *      endpoint, etc) defining all functions in this device configuration.
  64 * @buf: Buffer for the resulting configuration descriptor.
  65 * @length: Length of buffer.  If this is not big enough to hold the
  66 *      entire configuration descriptor, an error code will be returned.
  67 *
  68 * This copies descriptors into the response buffer, building a descriptor
  69 * for that configuration.  It returns the buffer length or a negative
  70 * status code.  The config.wTotalLength field is set to match the length
  71 * of the result, but other descriptor fields (including power usage and
  72 * interface count) must be set by the caller.
  73 *
  74 * Gadget drivers could use this when constructing a config descriptor
  75 * in response to USB_REQ_GET_DESCRIPTOR.  They will need to patch the
  76 * resulting bDescriptorType value if USB_DT_OTHER_SPEED_CONFIG is needed.
  77 */
  78int usb_gadget_config_buf(
  79        const struct usb_config_descriptor      *config,
  80        void                                    *buf,
  81        unsigned                                length,
  82        const struct usb_descriptor_header      **desc
  83)
  84{
  85        struct usb_config_descriptor            *cp = buf;
  86        int                                     len;
  87
  88        /* config descriptor first */
  89        if (length < USB_DT_CONFIG_SIZE || !desc)
  90                return -EINVAL;
  91        *cp = *config;
  92
  93        /* then interface/endpoint/class/vendor/... */
  94        len = usb_descriptor_fillbuf(USB_DT_CONFIG_SIZE + (u8*)buf,
  95                        length - USB_DT_CONFIG_SIZE, desc);
  96        if (len < 0)
  97                return len;
  98        len += USB_DT_CONFIG_SIZE;
  99        if (len > 0xffff)
 100                return -EINVAL;
 101
 102        /* patch up the config descriptor */
 103        cp->bLength = USB_DT_CONFIG_SIZE;
 104        cp->bDescriptorType = USB_DT_CONFIG;
 105        cp->wTotalLength = cpu_to_le16(len);
 106        cp->bmAttributes |= USB_CONFIG_ATT_ONE;
 107        return len;
 108}
 109
 110/**
 111 * usb_copy_descriptors - copy a vector of USB descriptors
 112 * @src: null-terminated vector to copy
 113 * Context: initialization code, which may sleep
 114 *
 115 * This makes a copy of a vector of USB descriptors.  Its primary use
 116 * is to support usb_function objects which can have multiple copies,
 117 * each needing different descriptors.  Functions may have static
 118 * tables of descriptors, which are used as templates and customized
 119 * with identifiers (for interfaces, strings, endpoints, and more)
 120 * as needed by a given function instance.
 121 */
 122struct usb_descriptor_header **
 123usb_copy_descriptors(struct usb_descriptor_header **src)
 124{
 125        struct usb_descriptor_header **tmp;
 126        unsigned bytes;
 127        unsigned n_desc;
 128        void *mem;
 129        struct usb_descriptor_header **ret;
 130
 131        /* count descriptors and their sizes; then add vector size */
 132        for (bytes = 0, n_desc = 0, tmp = src; *tmp; tmp++, n_desc++)
 133                bytes += (*tmp)->bLength;
 134        bytes += (n_desc + 1) * sizeof(*tmp);
 135
 136        mem = kmalloc(bytes, GFP_KERNEL);
 137        if (!mem)
 138                return NULL;
 139
 140        /* fill in pointers starting at "tmp",
 141         * to descriptors copied starting at "mem";
 142         * and return "ret"
 143         */
 144        tmp = mem;
 145        ret = mem;
 146        mem += (n_desc + 1) * sizeof(*tmp);
 147        while (*src) {
 148                memcpy(mem, *src, (*src)->bLength);
 149                *tmp = mem;
 150                tmp++;
 151                mem += (*src)->bLength;
 152                src++;
 153        }
 154        *tmp = NULL;
 155
 156        return ret;
 157}
 158
 159