linux/drivers/usb/gadget/cdc2.c
<<
>>
Prefs
   1/*
   2 * cdc2.c -- CDC Composite driver, with ECM and ACM support
   3 *
   4 * Copyright (C) 2008 David Brownell
   5 * Copyright (C) 2008 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#include <linux/kernel.h>
  14#include <linux/utsname.h>
  15#include <linux/module.h>
  16
  17#include "u_ether.h"
  18#include "u_serial.h"
  19
  20
  21#define DRIVER_DESC             "CDC Composite Gadget"
  22#define DRIVER_VERSION          "King Kamehameha Day 2008"
  23
  24/*-------------------------------------------------------------------------*/
  25
  26/* DO NOT REUSE THESE IDs with a protocol-incompatible driver!!  Ever!!
  27 * Instead:  allocate your own, using normal USB-IF procedures.
  28 */
  29
  30/* Thanks to NetChip Technologies for donating this product ID.
  31 * It's for devices with only this composite CDC configuration.
  32 */
  33#define CDC_VENDOR_NUM          0x0525  /* NetChip */
  34#define CDC_PRODUCT_NUM         0xa4aa  /* CDC Composite: ECM + ACM */
  35
  36/*-------------------------------------------------------------------------*/
  37
  38/*
  39 * Kbuild is not very cooperative with respect to linking separately
  40 * compiled library objects into one module.  So for now we won't use
  41 * separate compilation ... ensuring init/exit sections work to shrink
  42 * the runtime footprint, and giving us at least some parts of what
  43 * a "gcc --combine ... part1.c part2.c part3.c ... " build would.
  44 */
  45
  46#include "composite.c"
  47#include "usbstring.c"
  48#include "config.c"
  49#include "epautoconf.c"
  50#include "u_serial.c"
  51#include "f_acm.c"
  52#include "f_ecm.c"
  53#include "u_ether.c"
  54
  55/*-------------------------------------------------------------------------*/
  56
  57static struct usb_device_descriptor device_desc = {
  58        .bLength =              sizeof device_desc,
  59        .bDescriptorType =      USB_DT_DEVICE,
  60
  61        .bcdUSB =               cpu_to_le16(0x0200),
  62
  63        .bDeviceClass =         USB_CLASS_COMM,
  64        .bDeviceSubClass =      0,
  65        .bDeviceProtocol =      0,
  66        /* .bMaxPacketSize0 = f(hardware) */
  67
  68        /* Vendor and product id can be overridden by module parameters.  */
  69        .idVendor =             cpu_to_le16(CDC_VENDOR_NUM),
  70        .idProduct =            cpu_to_le16(CDC_PRODUCT_NUM),
  71        /* .bcdDevice = f(hardware) */
  72        /* .iManufacturer = DYNAMIC */
  73        /* .iProduct = DYNAMIC */
  74        /* NO SERIAL NUMBER */
  75        .bNumConfigurations =   1,
  76};
  77
  78static struct usb_otg_descriptor otg_descriptor = {
  79        .bLength =              sizeof otg_descriptor,
  80        .bDescriptorType =      USB_DT_OTG,
  81
  82        /* REVISIT SRP-only hardware is possible, although
  83         * it would not be called "OTG" ...
  84         */
  85        .bmAttributes =         USB_OTG_SRP | USB_OTG_HNP,
  86};
  87
  88static const struct usb_descriptor_header *otg_desc[] = {
  89        (struct usb_descriptor_header *) &otg_descriptor,
  90        NULL,
  91};
  92
  93
  94/* string IDs are assigned dynamically */
  95
  96#define STRING_MANUFACTURER_IDX         0
  97#define STRING_PRODUCT_IDX              1
  98
  99static char manufacturer[50];
 100
 101static struct usb_string strings_dev[] = {
 102        [STRING_MANUFACTURER_IDX].s = manufacturer,
 103        [STRING_PRODUCT_IDX].s = DRIVER_DESC,
 104        {  } /* end of list */
 105};
 106
 107static struct usb_gadget_strings stringtab_dev = {
 108        .language       = 0x0409,       /* en-us */
 109        .strings        = strings_dev,
 110};
 111
 112static struct usb_gadget_strings *dev_strings[] = {
 113        &stringtab_dev,
 114        NULL,
 115};
 116
 117static u8 hostaddr[ETH_ALEN];
 118
 119/*-------------------------------------------------------------------------*/
 120
 121/*
 122 * We _always_ have both CDC ECM and CDC ACM functions.
 123 */
 124static int __init cdc_do_config(struct usb_configuration *c)
 125{
 126        int     status;
 127
 128        if (gadget_is_otg(c->cdev->gadget)) {
 129                c->descriptors = otg_desc;
 130                c->bmAttributes |= USB_CONFIG_ATT_WAKEUP;
 131        }
 132
 133        status = ecm_bind_config(c, hostaddr);
 134        if (status < 0)
 135                return status;
 136
 137        status = acm_bind_config(c, 0);
 138        if (status < 0)
 139                return status;
 140
 141        return 0;
 142}
 143
 144static struct usb_configuration cdc_config_driver = {
 145        .label                  = "CDC Composite (ECM + ACM)",
 146        .bConfigurationValue    = 1,
 147        /* .iConfiguration = DYNAMIC */
 148        .bmAttributes           = USB_CONFIG_ATT_SELFPOWER,
 149};
 150
 151/*-------------------------------------------------------------------------*/
 152
 153static int __init cdc_bind(struct usb_composite_dev *cdev)
 154{
 155        int                     gcnum;
 156        struct usb_gadget       *gadget = cdev->gadget;
 157        int                     status;
 158
 159        if (!can_support_ecm(cdev->gadget)) {
 160                dev_err(&gadget->dev, "controller '%s' not usable\n",
 161                                gadget->name);
 162                return -EINVAL;
 163        }
 164
 165        /* set up network link layer */
 166        status = gether_setup(cdev->gadget, hostaddr);
 167        if (status < 0)
 168                return status;
 169
 170        /* set up serial link layer */
 171        status = gserial_setup(cdev->gadget, 1);
 172        if (status < 0)
 173                goto fail0;
 174
 175        gcnum = usb_gadget_controller_number(gadget);
 176        if (gcnum >= 0)
 177                device_desc.bcdDevice = cpu_to_le16(0x0300 | gcnum);
 178        else {
 179                /* We assume that can_support_ecm() tells the truth;
 180                 * but if the controller isn't recognized at all then
 181                 * that assumption is a bit more likely to be wrong.
 182                 */
 183                WARNING(cdev, "controller '%s' not recognized; trying %s\n",
 184                                gadget->name,
 185                                cdc_config_driver.label);
 186                device_desc.bcdDevice =
 187                        cpu_to_le16(0x0300 | 0x0099);
 188        }
 189
 190
 191        /* Allocate string descriptor numbers ... note that string
 192         * contents can be overridden by the composite_dev glue.
 193         */
 194
 195        /* device descriptor strings: manufacturer, product */
 196        snprintf(manufacturer, sizeof manufacturer, "%s %s with %s",
 197                init_utsname()->sysname, init_utsname()->release,
 198                gadget->name);
 199        status = usb_string_id(cdev);
 200        if (status < 0)
 201                goto fail1;
 202        strings_dev[STRING_MANUFACTURER_IDX].id = status;
 203        device_desc.iManufacturer = status;
 204
 205        status = usb_string_id(cdev);
 206        if (status < 0)
 207                goto fail1;
 208        strings_dev[STRING_PRODUCT_IDX].id = status;
 209        device_desc.iProduct = status;
 210
 211        /* register our configuration */
 212        status = usb_add_config(cdev, &cdc_config_driver, cdc_do_config);
 213        if (status < 0)
 214                goto fail1;
 215
 216        dev_info(&gadget->dev, "%s, version: " DRIVER_VERSION "\n",
 217                        DRIVER_DESC);
 218
 219        return 0;
 220
 221fail1:
 222        gserial_cleanup();
 223fail0:
 224        gether_cleanup();
 225        return status;
 226}
 227
 228static int __exit cdc_unbind(struct usb_composite_dev *cdev)
 229{
 230        gserial_cleanup();
 231        gether_cleanup();
 232        return 0;
 233}
 234
 235static struct usb_composite_driver cdc_driver = {
 236        .name           = "g_cdc",
 237        .dev            = &device_desc,
 238        .strings        = dev_strings,
 239        .max_speed      = USB_SPEED_HIGH,
 240        .unbind         = __exit_p(cdc_unbind),
 241};
 242
 243MODULE_DESCRIPTION(DRIVER_DESC);
 244MODULE_AUTHOR("David Brownell");
 245MODULE_LICENSE("GPL");
 246
 247static int __init init(void)
 248{
 249        return usb_composite_probe(&cdc_driver, cdc_bind);
 250}
 251module_init(init);
 252
 253static void __exit cleanup(void)
 254{
 255        usb_composite_unregister(&cdc_driver);
 256}
 257module_exit(cleanup);
 258