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 __ref 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 .bind = cdc_do_config, 155 .bConfigurationValue = 1, 156 /* .iConfiguration = DYNAMIC */ 157 .bmAttributes = USB_CONFIG_ATT_SELFPOWER, 158}; 159 160/*-------------------------------------------------------------------------*/ 161 162static int __ref cdc_bind(struct usb_composite_dev *cdev) 163{ 164 int gcnum; 165 struct usb_gadget *gadget = cdev->gadget; 166 int status; 167 168 if (!can_support_ecm(cdev->gadget)) { 169 dev_err(&gadget->dev, "controller '%s' not usable\n", 170 gadget->name); 171 return -EINVAL; 172 } 173 174 /* set up network link layer */ 175 status = gether_setup(cdev->gadget, hostaddr); 176 if (status < 0) 177 return status; 178 179 /* set up serial link layer */ 180 status = gserial_setup(cdev->gadget, 1); 181 if (status < 0) 182 goto fail0; 183 184 gcnum = usb_gadget_controller_number(gadget); 185 if (gcnum >= 0) 186 device_desc.bcdDevice = cpu_to_le16(0x0300 | gcnum); 187 else { 188 /* We assume that can_support_ecm() tells the truth; 189 * but if the controller isn't recognized at all then 190 * that assumption is a bit more likely to be wrong. 191 */ 192 WARNING(cdev, "controller '%s' not recognized; trying %s\n", 193 gadget->name, 194 cdc_config_driver.label); 195 device_desc.bcdDevice = 196 cpu_to_le16(0x0300 | 0x0099); 197 } 198 199 200 /* Allocate string descriptor numbers ... note that string 201 * contents can be overridden by the composite_dev glue. 202 */ 203 204 /* device descriptor strings: manufacturer, product */ 205 snprintf(manufacturer, sizeof manufacturer, "%s %s with %s", 206 init_utsname()->sysname, init_utsname()->release, 207 gadget->name); 208 status = usb_string_id(cdev); 209 if (status < 0) 210 goto fail1; 211 strings_dev[STRING_MANUFACTURER_IDX].id = status; 212 device_desc.iManufacturer = status; 213 214 status = usb_string_id(cdev); 215 if (status < 0) 216 goto fail1; 217 strings_dev[STRING_PRODUCT_IDX].id = status; 218 device_desc.iProduct = status; 219 220 /* register our configuration */ 221 status = usb_add_config(cdev, &cdc_config_driver); 222 if (status < 0) 223 goto fail1; 224 225 dev_info(&gadget->dev, "%s, version: " DRIVER_VERSION "\n", 226 DRIVER_DESC); 227 228 return 0; 229 230fail1: 231 gserial_cleanup(); 232fail0: 233 gether_cleanup(); 234 return status; 235} 236 237static int __exit cdc_unbind(struct usb_composite_dev *cdev) 238{ 239 gserial_cleanup(); 240 gether_cleanup(); 241 return 0; 242} 243 244static struct usb_composite_driver cdc_driver = { 245 .name = "g_cdc", 246 .dev = &device_desc, 247 .strings = dev_strings, 248 .bind = cdc_bind, 249 .unbind = __exit_p(cdc_unbind), 250}; 251 252MODULE_DESCRIPTION(DRIVER_DESC); 253MODULE_AUTHOR("David Brownell"); 254MODULE_LICENSE("GPL"); 255 256static int __init init(void) 257{ 258 return usb_composite_register(&cdc_driver); 259} 260module_init(init); 261 262static void __exit cleanup(void) 263{ 264 usb_composite_unregister(&cdc_driver); 265} 266module_exit(cleanup); 267