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.13 494 lines 11 kB view raw
1/* 2 * g_ffs.c -- user mode file system API for USB composite function controllers 3 * 4 * Copyright (C) 2010 Samsung Electronics 5 * Author: Michal Nazarewicz <mina86@mina86.com> 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#define pr_fmt(fmt) "g_ffs: " fmt 14 15#include <linux/module.h> 16/* 17 * kbuild is not very cooperative with respect to linking separately 18 * compiled library objects into one module. So for now we won't use 19 * separate compilation ... ensuring init/exit sections work to shrink 20 * the runtime footprint, and giving us at least some parts of what 21 * a "gcc --combine ... part1.c part2.c part3.c ... " build would. 22 */ 23#if defined CONFIG_USB_FUNCTIONFS_ETH || defined CONFIG_USB_FUNCTIONFS_RNDIS 24# if defined USB_ETH_RNDIS 25# undef USB_ETH_RNDIS 26# endif 27# ifdef CONFIG_USB_FUNCTIONFS_RNDIS 28# define USB_ETH_RNDIS y 29# endif 30 31#define USBF_ECM_INCLUDED 32# include "f_ecm.c" 33#define USB_FSUBSET_INCLUDED 34# include "f_subset.c" 35# ifdef USB_ETH_RNDIS 36# define USB_FRNDIS_INCLUDED 37# include "f_rndis.c" 38# include "rndis.h" 39# endif 40# include "u_ether.h" 41 42static u8 gfs_host_mac[ETH_ALEN]; 43static struct eth_dev *the_dev; 44# ifdef CONFIG_USB_FUNCTIONFS_ETH 45static int eth_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN], 46 struct eth_dev *dev); 47# endif 48#else 49# define the_dev NULL 50# define gether_cleanup(dev) do { } while (0) 51# define gfs_host_mac NULL 52struct eth_dev; 53#endif 54 55#include "f_fs.c" 56 57#define DRIVER_NAME "g_ffs" 58#define DRIVER_DESC "USB Function Filesystem" 59#define DRIVER_VERSION "24 Aug 2004" 60 61MODULE_DESCRIPTION(DRIVER_DESC); 62MODULE_AUTHOR("Michal Nazarewicz"); 63MODULE_LICENSE("GPL"); 64 65#define GFS_VENDOR_ID 0x1d6b /* Linux Foundation */ 66#define GFS_PRODUCT_ID 0x0105 /* FunctionFS Gadget */ 67 68#define GFS_MAX_DEVS 10 69 70struct gfs_ffs_obj { 71 const char *name; 72 bool mounted; 73 bool desc_ready; 74 struct ffs_data *ffs_data; 75}; 76 77USB_GADGET_COMPOSITE_OPTIONS(); 78 79#if defined CONFIG_USB_FUNCTIONFS_ETH || defined CONFIG_USB_FUNCTIONFS_RNDIS 80USB_ETHERNET_MODULE_PARAMETERS(); 81#endif 82 83static struct usb_device_descriptor gfs_dev_desc = { 84 .bLength = sizeof gfs_dev_desc, 85 .bDescriptorType = USB_DT_DEVICE, 86 87 .bcdUSB = cpu_to_le16(0x0200), 88 .bDeviceClass = USB_CLASS_PER_INTERFACE, 89 90 .idVendor = cpu_to_le16(GFS_VENDOR_ID), 91 .idProduct = cpu_to_le16(GFS_PRODUCT_ID), 92}; 93 94static char *func_names[GFS_MAX_DEVS]; 95static unsigned int func_num; 96 97module_param_named(bDeviceClass, gfs_dev_desc.bDeviceClass, byte, 0644); 98MODULE_PARM_DESC(bDeviceClass, "USB Device class"); 99module_param_named(bDeviceSubClass, gfs_dev_desc.bDeviceSubClass, byte, 0644); 100MODULE_PARM_DESC(bDeviceSubClass, "USB Device subclass"); 101module_param_named(bDeviceProtocol, gfs_dev_desc.bDeviceProtocol, byte, 0644); 102MODULE_PARM_DESC(bDeviceProtocol, "USB Device protocol"); 103module_param_array_named(functions, func_names, charp, &func_num, 0); 104MODULE_PARM_DESC(functions, "USB Functions list"); 105 106static const struct usb_descriptor_header *gfs_otg_desc[] = { 107 (const struct usb_descriptor_header *) 108 &(const struct usb_otg_descriptor) { 109 .bLength = sizeof(struct usb_otg_descriptor), 110 .bDescriptorType = USB_DT_OTG, 111 112 /* 113 * REVISIT SRP-only hardware is possible, although 114 * it would not be called "OTG" ... 115 */ 116 .bmAttributes = USB_OTG_SRP | USB_OTG_HNP, 117 }, 118 119 NULL 120}; 121 122/* String IDs are assigned dynamically */ 123static struct usb_string gfs_strings[] = { 124 [USB_GADGET_MANUFACTURER_IDX].s = "", 125 [USB_GADGET_PRODUCT_IDX].s = DRIVER_DESC, 126 [USB_GADGET_SERIAL_IDX].s = "", 127#ifdef CONFIG_USB_FUNCTIONFS_RNDIS 128 { .s = "FunctionFS + RNDIS" }, 129#endif 130#ifdef CONFIG_USB_FUNCTIONFS_ETH 131 { .s = "FunctionFS + ECM" }, 132#endif 133#ifdef CONFIG_USB_FUNCTIONFS_GENERIC 134 { .s = "FunctionFS" }, 135#endif 136 { } /* end of list */ 137}; 138 139static struct usb_gadget_strings *gfs_dev_strings[] = { 140 &(struct usb_gadget_strings) { 141 .language = 0x0409, /* en-us */ 142 .strings = gfs_strings, 143 }, 144 NULL, 145}; 146 147struct gfs_configuration { 148 struct usb_configuration c; 149 int (*eth)(struct usb_configuration *c, u8 *ethaddr, 150 struct eth_dev *dev); 151} gfs_configurations[] = { 152#ifdef CONFIG_USB_FUNCTIONFS_RNDIS 153 { 154 .eth = rndis_bind_config, 155 }, 156#endif 157 158#ifdef CONFIG_USB_FUNCTIONFS_ETH 159 { 160 .eth = eth_bind_config, 161 }, 162#endif 163 164#ifdef CONFIG_USB_FUNCTIONFS_GENERIC 165 { 166 }, 167#endif 168}; 169 170static int gfs_bind(struct usb_composite_dev *cdev); 171static int gfs_unbind(struct usb_composite_dev *cdev); 172static int gfs_do_config(struct usb_configuration *c); 173 174static __refdata struct usb_composite_driver gfs_driver = { 175 .name = DRIVER_NAME, 176 .dev = &gfs_dev_desc, 177 .strings = gfs_dev_strings, 178 .max_speed = USB_SPEED_HIGH, 179 .bind = gfs_bind, 180 .unbind = gfs_unbind, 181}; 182 183static DEFINE_MUTEX(gfs_lock); 184static unsigned int missing_funcs; 185static bool gfs_ether_setup; 186static bool gfs_registered; 187static bool gfs_single_func; 188static struct gfs_ffs_obj *ffs_tab; 189 190static int __init gfs_init(void) 191{ 192 int i; 193 194 ENTER(); 195 196 if (!func_num) { 197 gfs_single_func = true; 198 func_num = 1; 199 } 200 201 ffs_tab = kcalloc(func_num, sizeof *ffs_tab, GFP_KERNEL); 202 if (!ffs_tab) 203 return -ENOMEM; 204 205 if (!gfs_single_func) 206 for (i = 0; i < func_num; i++) 207 ffs_tab[i].name = func_names[i]; 208 209 missing_funcs = func_num; 210 211 return functionfs_init(); 212} 213module_init(gfs_init); 214 215static void __exit gfs_exit(void) 216{ 217 ENTER(); 218 mutex_lock(&gfs_lock); 219 220 if (gfs_registered) 221 usb_composite_unregister(&gfs_driver); 222 gfs_registered = false; 223 224 functionfs_cleanup(); 225 226 mutex_unlock(&gfs_lock); 227 kfree(ffs_tab); 228} 229module_exit(gfs_exit); 230 231static struct gfs_ffs_obj *gfs_find_dev(const char *dev_name) 232{ 233 int i; 234 235 ENTER(); 236 237 if (gfs_single_func) 238 return &ffs_tab[0]; 239 240 for (i = 0; i < func_num; i++) 241 if (strcmp(ffs_tab[i].name, dev_name) == 0) 242 return &ffs_tab[i]; 243 244 return NULL; 245} 246 247static int functionfs_ready_callback(struct ffs_data *ffs) 248{ 249 struct gfs_ffs_obj *ffs_obj; 250 int ret; 251 252 ENTER(); 253 mutex_lock(&gfs_lock); 254 255 ffs_obj = ffs->private_data; 256 if (!ffs_obj) { 257 ret = -EINVAL; 258 goto done; 259 } 260 261 if (WARN_ON(ffs_obj->desc_ready)) { 262 ret = -EBUSY; 263 goto done; 264 } 265 ffs_obj->desc_ready = true; 266 ffs_obj->ffs_data = ffs; 267 268 if (--missing_funcs) { 269 ret = 0; 270 goto done; 271 } 272 273 if (gfs_registered) { 274 ret = -EBUSY; 275 goto done; 276 } 277 gfs_registered = true; 278 279 ret = usb_composite_probe(&gfs_driver); 280 if (unlikely(ret < 0)) 281 gfs_registered = false; 282 283done: 284 mutex_unlock(&gfs_lock); 285 return ret; 286} 287 288static void functionfs_closed_callback(struct ffs_data *ffs) 289{ 290 struct gfs_ffs_obj *ffs_obj; 291 292 ENTER(); 293 mutex_lock(&gfs_lock); 294 295 ffs_obj = ffs->private_data; 296 if (!ffs_obj) 297 goto done; 298 299 ffs_obj->desc_ready = false; 300 missing_funcs++; 301 302 if (gfs_registered) 303 usb_composite_unregister(&gfs_driver); 304 gfs_registered = false; 305 306done: 307 mutex_unlock(&gfs_lock); 308} 309 310static void *functionfs_acquire_dev_callback(const char *dev_name) 311{ 312 struct gfs_ffs_obj *ffs_dev; 313 314 ENTER(); 315 mutex_lock(&gfs_lock); 316 317 ffs_dev = gfs_find_dev(dev_name); 318 if (!ffs_dev) { 319 ffs_dev = ERR_PTR(-ENODEV); 320 goto done; 321 } 322 323 if (ffs_dev->mounted) { 324 ffs_dev = ERR_PTR(-EBUSY); 325 goto done; 326 } 327 ffs_dev->mounted = true; 328 329done: 330 mutex_unlock(&gfs_lock); 331 return ffs_dev; 332} 333 334static void functionfs_release_dev_callback(struct ffs_data *ffs_data) 335{ 336 struct gfs_ffs_obj *ffs_dev; 337 338 ENTER(); 339 mutex_lock(&gfs_lock); 340 341 ffs_dev = ffs_data->private_data; 342 if (ffs_dev) 343 ffs_dev->mounted = false; 344 345 mutex_unlock(&gfs_lock); 346} 347 348/* 349 * It is assumed that gfs_bind is called from a context where gfs_lock is held 350 */ 351static int gfs_bind(struct usb_composite_dev *cdev) 352{ 353 int ret, i; 354 355 ENTER(); 356 357 if (missing_funcs) 358 return -ENODEV; 359#if defined CONFIG_USB_FUNCTIONFS_ETH || defined CONFIG_USB_FUNCTIONFS_RNDIS 360 the_dev = gether_setup(cdev->gadget, dev_addr, host_addr, gfs_host_mac, 361 qmult); 362#endif 363 if (IS_ERR(the_dev)) { 364 ret = PTR_ERR(the_dev); 365 goto error_quick; 366 } 367 gfs_ether_setup = true; 368 369 ret = usb_string_ids_tab(cdev, gfs_strings); 370 if (unlikely(ret < 0)) 371 goto error; 372 gfs_dev_desc.iProduct = gfs_strings[USB_GADGET_PRODUCT_IDX].id; 373 374 for (i = func_num; i--; ) { 375 ret = functionfs_bind(ffs_tab[i].ffs_data, cdev); 376 if (unlikely(ret < 0)) { 377 while (++i < func_num) 378 functionfs_unbind(ffs_tab[i].ffs_data); 379 goto error; 380 } 381 } 382 383 for (i = 0; i < ARRAY_SIZE(gfs_configurations); ++i) { 384 struct gfs_configuration *c = gfs_configurations + i; 385 int sid = USB_GADGET_FIRST_AVAIL_IDX + i; 386 387 c->c.label = gfs_strings[sid].s; 388 c->c.iConfiguration = gfs_strings[sid].id; 389 c->c.bConfigurationValue = 1 + i; 390 c->c.bmAttributes = USB_CONFIG_ATT_SELFPOWER; 391 392 ret = usb_add_config(cdev, &c->c, gfs_do_config); 393 if (unlikely(ret < 0)) 394 goto error_unbind; 395 } 396 usb_composite_overwrite_options(cdev, &coverwrite); 397 return 0; 398 399error_unbind: 400 for (i = 0; i < func_num; i++) 401 functionfs_unbind(ffs_tab[i].ffs_data); 402error: 403 gether_cleanup(the_dev); 404error_quick: 405 gfs_ether_setup = false; 406 return ret; 407} 408 409/* 410 * It is assumed that gfs_unbind is called from a context where gfs_lock is held 411 */ 412static int gfs_unbind(struct usb_composite_dev *cdev) 413{ 414 int i; 415 416 ENTER(); 417 418 /* 419 * We may have been called in an error recovery from 420 * composite_bind() after gfs_unbind() failure so we need to 421 * check if gfs_ffs_data is not NULL since gfs_bind() handles 422 * all error recovery itself. I'd rather we werent called 423 * from composite on orror recovery, but what you're gonna 424 * do...? 425 */ 426 if (gfs_ether_setup) 427 gether_cleanup(the_dev); 428 gfs_ether_setup = false; 429 430 for (i = func_num; i--; ) 431 if (ffs_tab[i].ffs_data) 432 functionfs_unbind(ffs_tab[i].ffs_data); 433 434 return 0; 435} 436 437/* 438 * It is assumed that gfs_do_config is called from a context where 439 * gfs_lock is held 440 */ 441static int gfs_do_config(struct usb_configuration *c) 442{ 443 struct gfs_configuration *gc = 444 container_of(c, struct gfs_configuration, c); 445 int i; 446 int ret; 447 448 if (missing_funcs) 449 return -ENODEV; 450 451 if (gadget_is_otg(c->cdev->gadget)) { 452 c->descriptors = gfs_otg_desc; 453 c->bmAttributes |= USB_CONFIG_ATT_WAKEUP; 454 } 455 456 if (gc->eth) { 457 ret = gc->eth(c, gfs_host_mac, the_dev); 458 if (unlikely(ret < 0)) 459 return ret; 460 } 461 462 for (i = 0; i < func_num; i++) { 463 ret = functionfs_bind_config(c->cdev, c, ffs_tab[i].ffs_data); 464 if (unlikely(ret < 0)) 465 return ret; 466 } 467 468 /* 469 * After previous do_configs there may be some invalid 470 * pointers in c->interface array. This happens every time 471 * a user space function with fewer interfaces than a user 472 * space function that was run before the new one is run. The 473 * compasit's set_config() assumes that if there is no more 474 * then MAX_CONFIG_INTERFACES interfaces in a configuration 475 * then there is a NULL pointer after the last interface in 476 * c->interface array. We need to make sure this is true. 477 */ 478 if (c->next_interface_id < ARRAY_SIZE(c->interface)) 479 c->interface[c->next_interface_id] = NULL; 480 481 return 0; 482} 483 484#ifdef CONFIG_USB_FUNCTIONFS_ETH 485 486static int eth_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN], 487 struct eth_dev *dev) 488{ 489 return can_support_ecm(c->cdev->gadget) 490 ? ecm_bind_config(c, ethaddr, dev) 491 : geth_bind_config(c, ethaddr, dev); 492} 493 494#endif