Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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