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