linux/drivers/usb/gadget/zero.c
<<
>>
Prefs
   1/*
   2 * zero.c -- Gadget Zero, for USB development
   3 *
   4 * Copyright (C) 2003-2008 David Brownell
   5 * Copyright (C) 2008 by Nokia Corporation
   6 *
   7 * This program is free software; you can redistribute it and/or modify
   8 * it under the terms of the GNU General Public License as published by
   9 * the Free Software Foundation; either version 2 of the License, or
  10 * (at your option) any later version.
  11 */
  12
  13
  14/*
  15 * Gadget Zero only needs two bulk endpoints, and is an example of how you
  16 * can write a hardware-agnostic gadget driver running inside a USB device.
  17 * Some hardware details are visible, but don't affect most of the driver.
  18 *
  19 * Use it with the Linux host/master side "usbtest" driver to get a basic
  20 * functional test of your device-side usb stack, or with "usb-skeleton".
  21 *
  22 * It supports two similar configurations.  One sinks whatever the usb host
  23 * writes, and in return sources zeroes.  The other loops whatever the host
  24 * writes back, so the host can read it.
  25 *
  26 * Many drivers will only have one configuration, letting them be much
  27 * simpler if they also don't support high speed operation (like this
  28 * driver does).
  29 *
  30 * Why is *this* driver using two configurations, rather than setting up
  31 * two interfaces with different functions?  To help verify that multiple
  32 * configuration infrastucture is working correctly; also, so that it can
  33 * work with low capability USB controllers without four bulk endpoints.
  34 */
  35
  36/*
  37 * driver assumes self-powered hardware, and
  38 * has no way for users to trigger remote wakeup.
  39 */
  40
  41/* #define VERBOSE_DEBUG */
  42
  43#include <linux/kernel.h>
  44#include <linux/slab.h>
  45#include <linux/utsname.h>
  46#include <linux/device.h>
  47
  48#include "g_zero.h"
  49#include "gadget_chips.h"
  50
  51
  52/*-------------------------------------------------------------------------*/
  53
  54/*
  55 * Kbuild is not very cooperative with respect to linking separately
  56 * compiled library objects into one module.  So for now we won't use
  57 * separate compilation ... ensuring init/exit sections work to shrink
  58 * the runtime footprint, and giving us at least some parts of what
  59 * a "gcc --combine ... part1.c part2.c part3.c ... " build would.
  60 */
  61#include "composite.c"
  62#include "usbstring.c"
  63#include "config.c"
  64#include "epautoconf.c"
  65
  66#include "f_sourcesink.c"
  67#include "f_loopback.c"
  68
  69/*-------------------------------------------------------------------------*/
  70
  71#define DRIVER_VERSION          "Cinco de Mayo 2008"
  72
  73static const char longname[] = "Gadget Zero";
  74
  75unsigned buflen = 4096;
  76module_param(buflen, uint, 0);
  77
  78/*
  79 * Normally the "loopback" configuration is second (index 1) so
  80 * it's not the default.  Here's where to change that order, to
  81 * work better with hosts where config changes are problematic or
  82 * controllers (like original superh) that only support one config.
  83 */
  84static int loopdefault = 0;
  85module_param(loopdefault, bool, S_IRUGO|S_IWUSR);
  86
  87/*-------------------------------------------------------------------------*/
  88
  89/* Thanks to NetChip Technologies for donating this product ID.
  90 *
  91 * DO NOT REUSE THESE IDs with a protocol-incompatible driver!!  Ever!!
  92 * Instead:  allocate your own, using normal USB-IF procedures.
  93 */
  94#ifndef CONFIG_USB_ZERO_HNPTEST
  95#define DRIVER_VENDOR_NUM       0x0525          /* NetChip */
  96#define DRIVER_PRODUCT_NUM      0xa4a0          /* Linux-USB "Gadget Zero" */
  97#define DEFAULT_AUTORESUME      0
  98#else
  99#define DRIVER_VENDOR_NUM       0x1a0a          /* OTG test device IDs */
 100#define DRIVER_PRODUCT_NUM      0xbadd
 101#define DEFAULT_AUTORESUME      5
 102#endif
 103
 104/* If the optional "autoresume" mode is enabled, it provides good
 105 * functional coverage for the "USBCV" test harness from USB-IF.
 106 * It's always set if OTG mode is enabled.
 107 */
 108unsigned autoresume = DEFAULT_AUTORESUME;
 109module_param(autoresume, uint, S_IRUGO);
 110MODULE_PARM_DESC(autoresume, "zero, or seconds before remote wakeup");
 111
 112/*-------------------------------------------------------------------------*/
 113
 114static struct usb_device_descriptor device_desc = {
 115        .bLength =              sizeof device_desc,
 116        .bDescriptorType =      USB_DT_DEVICE,
 117
 118        .bcdUSB =               cpu_to_le16(0x0200),
 119        .bDeviceClass =         USB_CLASS_VENDOR_SPEC,
 120
 121        .idVendor =             cpu_to_le16(DRIVER_VENDOR_NUM),
 122        .idProduct =            cpu_to_le16(DRIVER_PRODUCT_NUM),
 123        .bNumConfigurations =   2,
 124};
 125
 126#ifdef CONFIG_USB_OTG
 127static struct usb_otg_descriptor otg_descriptor = {
 128        .bLength =              sizeof otg_descriptor,
 129        .bDescriptorType =      USB_DT_OTG,
 130
 131        /* REVISIT SRP-only hardware is possible, although
 132         * it would not be called "OTG" ...
 133         */
 134        .bmAttributes =         USB_OTG_SRP | USB_OTG_HNP,
 135};
 136
 137const struct usb_descriptor_header *otg_desc[] = {
 138        (struct usb_descriptor_header *) &otg_descriptor,
 139        NULL,
 140};
 141#endif
 142
 143/* string IDs are assigned dynamically */
 144
 145#define STRING_MANUFACTURER_IDX         0
 146#define STRING_PRODUCT_IDX              1
 147#define STRING_SERIAL_IDX               2
 148
 149static char manufacturer[50];
 150
 151/* default serial number takes at least two packets */
 152static char serial[] = "0123456789.0123456789.0123456789";
 153
 154static struct usb_string strings_dev[] = {
 155        [STRING_MANUFACTURER_IDX].s = manufacturer,
 156        [STRING_PRODUCT_IDX].s = longname,
 157        [STRING_SERIAL_IDX].s = serial,
 158        {  }                    /* end of list */
 159};
 160
 161static struct usb_gadget_strings stringtab_dev = {
 162        .language       = 0x0409,       /* en-us */
 163        .strings        = strings_dev,
 164};
 165
 166static struct usb_gadget_strings *dev_strings[] = {
 167        &stringtab_dev,
 168        NULL,
 169};
 170
 171/*-------------------------------------------------------------------------*/
 172
 173struct usb_request *alloc_ep_req(struct usb_ep *ep)
 174{
 175        struct usb_request      *req;
 176
 177        req = usb_ep_alloc_request(ep, GFP_ATOMIC);
 178        if (req) {
 179                req->length = buflen;
 180                req->buf = kmalloc(buflen, GFP_ATOMIC);
 181                if (!req->buf) {
 182                        usb_ep_free_request(ep, req);
 183                        req = NULL;
 184                }
 185        }
 186        return req;
 187}
 188
 189void free_ep_req(struct usb_ep *ep, struct usb_request *req)
 190{
 191        kfree(req->buf);
 192        usb_ep_free_request(ep, req);
 193}
 194
 195static void disable_ep(struct usb_composite_dev *cdev, struct usb_ep *ep)
 196{
 197        int                     value;
 198
 199        if (ep->driver_data) {
 200                value = usb_ep_disable(ep);
 201                if (value < 0)
 202                        DBG(cdev, "disable %s --> %d\n",
 203                                        ep->name, value);
 204                ep->driver_data = NULL;
 205        }
 206}
 207
 208void disable_endpoints(struct usb_composite_dev *cdev,
 209                struct usb_ep *in, struct usb_ep *out)
 210{
 211        disable_ep(cdev, in);
 212        disable_ep(cdev, out);
 213}
 214
 215/*-------------------------------------------------------------------------*/
 216
 217static struct timer_list        autoresume_timer;
 218
 219static void zero_autoresume(unsigned long _c)
 220{
 221        struct usb_composite_dev        *cdev = (void *)_c;
 222        struct usb_gadget               *g = cdev->gadget;
 223
 224        /* unconfigured devices can't issue wakeups */
 225        if (!cdev->config)
 226                return;
 227
 228        /* Normally the host would be woken up for something
 229         * more significant than just a timer firing; likely
 230         * because of some direct user request.
 231         */
 232        if (g->speed != USB_SPEED_UNKNOWN) {
 233                int status = usb_gadget_wakeup(g);
 234                INFO(cdev, "%s --> %d\n", __func__, status);
 235        }
 236}
 237
 238static void zero_suspend(struct usb_composite_dev *cdev)
 239{
 240        if (cdev->gadget->speed == USB_SPEED_UNKNOWN)
 241                return;
 242
 243        if (autoresume) {
 244                mod_timer(&autoresume_timer, jiffies + (HZ * autoresume));
 245                DBG(cdev, "suspend, wakeup in %d seconds\n", autoresume);
 246        } else
 247                DBG(cdev, "%s\n", __func__);
 248}
 249
 250static void zero_resume(struct usb_composite_dev *cdev)
 251{
 252        DBG(cdev, "%s\n", __func__);
 253        del_timer(&autoresume_timer);
 254}
 255
 256/*-------------------------------------------------------------------------*/
 257
 258static int __init zero_bind(struct usb_composite_dev *cdev)
 259{
 260        int                     gcnum;
 261        struct usb_gadget       *gadget = cdev->gadget;
 262        int                     id;
 263
 264        /* Allocate string descriptor numbers ... note that string
 265         * contents can be overridden by the composite_dev glue.
 266         */
 267        id = usb_string_id(cdev);
 268        if (id < 0)
 269                return id;
 270        strings_dev[STRING_MANUFACTURER_IDX].id = id;
 271        device_desc.iManufacturer = id;
 272
 273        id = usb_string_id(cdev);
 274        if (id < 0)
 275                return id;
 276        strings_dev[STRING_PRODUCT_IDX].id = id;
 277        device_desc.iProduct = id;
 278
 279        id = usb_string_id(cdev);
 280        if (id < 0)
 281                return id;
 282        strings_dev[STRING_SERIAL_IDX].id = id;
 283        device_desc.iSerialNumber = id;
 284
 285        setup_timer(&autoresume_timer, zero_autoresume, (unsigned long) cdev);
 286
 287        /* Register primary, then secondary configuration.  Note that
 288         * SH3 only allows one config...
 289         */
 290        if (loopdefault) {
 291                loopback_add(cdev, autoresume != 0);
 292                sourcesink_add(cdev, autoresume != 0);
 293        } else {
 294                sourcesink_add(cdev, autoresume != 0);
 295                loopback_add(cdev, autoresume != 0);
 296        }
 297
 298        gcnum = usb_gadget_controller_number(gadget);
 299        if (gcnum >= 0)
 300                device_desc.bcdDevice = cpu_to_le16(0x0200 + gcnum);
 301        else {
 302                /* gadget zero is so simple (for now, no altsettings) that
 303                 * it SHOULD NOT have problems with bulk-capable hardware.
 304                 * so just warn about unrcognized controllers -- don't panic.
 305                 *
 306                 * things like configuration and altsetting numbering
 307                 * can need hardware-specific attention though.
 308                 */
 309                pr_warning("%s: controller '%s' not recognized\n",
 310                        longname, gadget->name);
 311                device_desc.bcdDevice = cpu_to_le16(0x9999);
 312        }
 313
 314
 315        INFO(cdev, "%s, version: " DRIVER_VERSION "\n", longname);
 316
 317        snprintf(manufacturer, sizeof manufacturer, "%s %s with %s",
 318                init_utsname()->sysname, init_utsname()->release,
 319                gadget->name);
 320
 321        return 0;
 322}
 323
 324static int zero_unbind(struct usb_composite_dev *cdev)
 325{
 326        del_timer_sync(&autoresume_timer);
 327        return 0;
 328}
 329
 330static struct usb_composite_driver zero_driver = {
 331        .name           = "zero",
 332        .dev            = &device_desc,
 333        .strings        = dev_strings,
 334        .max_speed      = USB_SPEED_SUPER,
 335        .unbind         = zero_unbind,
 336        .suspend        = zero_suspend,
 337        .resume         = zero_resume,
 338};
 339
 340MODULE_AUTHOR("David Brownell");
 341MODULE_LICENSE("GPL");
 342
 343static int __init init(void)
 344{
 345        return usb_composite_probe(&zero_driver, zero_bind);
 346}
 347module_init(init);
 348
 349static void __exit cleanup(void)
 350{
 351        usb_composite_unregister(&zero_driver);
 352}
 353module_exit(cleanup);
 354
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.