usb: gadget: FunctionFS: create utility file
[deliverable/linux.git] / drivers / usb / gadget / g_ffs.c
CommitLineData
5ab54cf7
MN
1/*
2 * g_ffs.c -- user mode file system API for USB composite function controllers
3 *
4 * Copyright (C) 2010 Samsung Electronics
54b8360f 5 * Author: Michal Nazarewicz <mina86@mina86.com>
5ab54cf7
MN
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.
5ab54cf7
MN
11 */
12
aa02f172
MN
13#define pr_fmt(fmt) "g_ffs: " fmt
14
c6c56008 15#include <linux/module.h>
c6c56008
MN
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 */
c6c56008 23#if defined CONFIG_USB_FUNCTIONFS_ETH || defined CONFIG_USB_FUNCTIONFS_RNDIS
85aec59f
AP
24#include <linux/netdevice.h>
25
c6c56008
MN
26# if defined USB_ETH_RNDIS
27# undef USB_ETH_RNDIS
28# endif
29# ifdef CONFIG_USB_FUNCTIONFS_RNDIS
30# define USB_ETH_RNDIS y
31# endif
32
f212ad4e 33# include "u_ecm.h"
85aec59f 34# include "u_gether.h"
c6c56008 35# ifdef USB_ETH_RNDIS
6e257b14 36# include "u_rndis.h"
cbbd14a9 37# include "rndis.h"
c6c56008 38# endif
f1a1823f 39# include "u_ether.h"
c6c56008 40
f212ad4e
AP
41USB_ETHERNET_MODULE_PARAMETERS();
42
f8dae531 43# ifdef CONFIG_USB_FUNCTIONFS_ETH
6e257b14 44static int eth_bind_config(struct usb_configuration *c);
f212ad4e
AP
45static struct usb_function_instance *fi_ecm;
46static struct usb_function *f_ecm;
85aec59f
AP
47static struct usb_function_instance *fi_geth;
48static struct usb_function *f_geth;
c6c56008 49# endif
6e257b14
AP
50# ifdef CONFIG_USB_FUNCTIONFS_RNDIS
51static int bind_rndis_config(struct usb_configuration *c);
52static struct usb_function_instance *fi_rndis;
53static struct usb_function *f_rndis;
54# endif
c6c56008
MN
55#endif
56
57#include "f_fs.c"
58
c6c56008
MN
59#define DRIVER_NAME "g_ffs"
60#define DRIVER_DESC "USB Function Filesystem"
61#define DRIVER_VERSION "24 Aug 2004"
62
63MODULE_DESCRIPTION(DRIVER_DESC);
64MODULE_AUTHOR("Michal Nazarewicz");
65MODULE_LICENSE("GPL");
66
fc19de61
MN
67#define GFS_VENDOR_ID 0x1d6b /* Linux Foundation */
68#define GFS_PRODUCT_ID 0x0105 /* FunctionFS Gadget */
c6c56008 69
581791f5
AP
70#define GFS_MAX_DEVS 10
71
7d16e8d3
SAS
72USB_GADGET_COMPOSITE_OPTIONS();
73
c6c56008
MN
74static struct usb_device_descriptor gfs_dev_desc = {
75 .bLength = sizeof gfs_dev_desc,
76 .bDescriptorType = USB_DT_DEVICE,
77
78 .bcdUSB = cpu_to_le16(0x0200),
79 .bDeviceClass = USB_CLASS_PER_INTERFACE,
80
fc19de61
MN
81 .idVendor = cpu_to_le16(GFS_VENDOR_ID),
82 .idProduct = cpu_to_le16(GFS_PRODUCT_ID),
c6c56008
MN
83};
84
581791f5
AP
85static char *func_names[GFS_MAX_DEVS];
86static unsigned int func_num;
87
fc19de61
MN
88module_param_named(bDeviceClass, gfs_dev_desc.bDeviceClass, byte, 0644);
89MODULE_PARM_DESC(bDeviceClass, "USB Device class");
90module_param_named(bDeviceSubClass, gfs_dev_desc.bDeviceSubClass, byte, 0644);
91MODULE_PARM_DESC(bDeviceSubClass, "USB Device subclass");
92module_param_named(bDeviceProtocol, gfs_dev_desc.bDeviceProtocol, byte, 0644);
93MODULE_PARM_DESC(bDeviceProtocol, "USB Device protocol");
581791f5
AP
94module_param_array_named(functions, func_names, charp, &func_num, 0);
95MODULE_PARM_DESC(functions, "USB Functions list");
c6c56008 96
c6c56008
MN
97static const struct usb_descriptor_header *gfs_otg_desc[] = {
98 (const struct usb_descriptor_header *)
99 &(const struct usb_otg_descriptor) {
100 .bLength = sizeof(struct usb_otg_descriptor),
101 .bDescriptorType = USB_DT_OTG,
102
fc19de61
MN
103 /*
104 * REVISIT SRP-only hardware is possible, although
105 * it would not be called "OTG" ...
106 */
c6c56008
MN
107 .bmAttributes = USB_OTG_SRP | USB_OTG_HNP,
108 },
109
110 NULL
111};
112
5ab54cf7 113/* String IDs are assigned dynamically */
c6c56008 114static struct usb_string gfs_strings[] = {
276e2e4f 115 [USB_GADGET_MANUFACTURER_IDX].s = "",
d33f74fc 116 [USB_GADGET_PRODUCT_IDX].s = DRIVER_DESC,
276e2e4f 117 [USB_GADGET_SERIAL_IDX].s = "",
c6c56008 118#ifdef CONFIG_USB_FUNCTIONFS_RNDIS
f8dae531 119 { .s = "FunctionFS + RNDIS" },
c6c56008
MN
120#endif
121#ifdef CONFIG_USB_FUNCTIONFS_ETH
f8dae531 122 { .s = "FunctionFS + ECM" },
c6c56008
MN
123#endif
124#ifdef CONFIG_USB_FUNCTIONFS_GENERIC
f8dae531 125 { .s = "FunctionFS" },
c6c56008
MN
126#endif
127 { } /* end of list */
128};
129
130static struct usb_gadget_strings *gfs_dev_strings[] = {
131 &(struct usb_gadget_strings) {
132 .language = 0x0409, /* en-us */
133 .strings = gfs_strings,
134 },
135 NULL,
136};
137
f8dae531
MN
138struct gfs_configuration {
139 struct usb_configuration c;
6e257b14 140 int (*eth)(struct usb_configuration *c);
f8dae531 141} gfs_configurations[] = {
c6c56008 142#ifdef CONFIG_USB_FUNCTIONFS_RNDIS
f8dae531 143 {
6e257b14 144 .eth = bind_rndis_config,
f8dae531 145 },
c6c56008
MN
146#endif
147
c6c56008 148#ifdef CONFIG_USB_FUNCTIONFS_ETH
f8dae531
MN
149 {
150 .eth = eth_bind_config,
151 },
c6c56008
MN
152#endif
153
c6c56008 154#ifdef CONFIG_USB_FUNCTIONFS_GENERIC
f8dae531
MN
155 {
156 },
c6c56008 157#endif
f8dae531 158};
c6c56008 159
c6c56008
MN
160static int gfs_bind(struct usb_composite_dev *cdev);
161static int gfs_unbind(struct usb_composite_dev *cdev);
f8dae531 162static int gfs_do_config(struct usb_configuration *c);
c6c56008 163
c2ec75c2 164static __refdata struct usb_composite_driver gfs_driver = {
fc19de61 165 .name = DRIVER_NAME,
c6c56008
MN
166 .dev = &gfs_dev_desc,
167 .strings = gfs_dev_strings,
35a0e0bf 168 .max_speed = USB_SPEED_HIGH,
03e42bd5 169 .bind = gfs_bind,
c6c56008
MN
170 .unbind = gfs_unbind,
171};
172
581791f5
AP
173static DEFINE_MUTEX(gfs_lock);
174static unsigned int missing_funcs;
581791f5
AP
175static bool gfs_registered;
176static bool gfs_single_func;
e72c39c0 177static struct ffs_dev *ffs_tab;
c6c56008 178
8545e603 179static int __init gfs_init(void)
c6c56008 180{
581791f5
AP
181 int i;
182
c6c56008
MN
183 ENTER();
184
581791f5
AP
185 if (!func_num) {
186 gfs_single_func = true;
187 func_num = 1;
188 }
189
190 ffs_tab = kcalloc(func_num, sizeof *ffs_tab, GFP_KERNEL);
191 if (!ffs_tab)
192 return -ENOMEM;
193
194 if (!gfs_single_func)
195 for (i = 0; i < func_num; i++)
196 ffs_tab[i].name = func_names[i];
197
198 missing_funcs = func_num;
199
c6c56008
MN
200 return functionfs_init();
201}
202module_init(gfs_init);
203
8545e603 204static void __exit gfs_exit(void)
c6c56008
MN
205{
206 ENTER();
581791f5 207 mutex_lock(&gfs_lock);
c6c56008 208
581791f5 209 if (gfs_registered)
c6c56008 210 usb_composite_unregister(&gfs_driver);
581791f5 211 gfs_registered = false;
c6c56008
MN
212
213 functionfs_cleanup();
581791f5
AP
214
215 mutex_unlock(&gfs_lock);
216 kfree(ffs_tab);
c6c56008
MN
217}
218module_exit(gfs_exit);
219
e72c39c0 220static struct ffs_dev *gfs_find_dev(const char *dev_name)
581791f5
AP
221{
222 int i;
223
224 ENTER();
225
226 if (gfs_single_func)
227 return &ffs_tab[0];
228
229 for (i = 0; i < func_num; i++)
230 if (strcmp(ffs_tab[i].name, dev_name) == 0)
231 return &ffs_tab[i];
232
233 return NULL;
234}
235
c6c56008
MN
236static int functionfs_ready_callback(struct ffs_data *ffs)
237{
e72c39c0 238 struct ffs_dev *ffs_obj;
c6c56008
MN
239 int ret;
240
241 ENTER();
581791f5
AP
242 mutex_lock(&gfs_lock);
243
244 ffs_obj = ffs->private_data;
245 if (!ffs_obj) {
246 ret = -EINVAL;
247 goto done;
248 }
249
250 if (WARN_ON(ffs_obj->desc_ready)) {
251 ret = -EBUSY;
252 goto done;
253 }
254 ffs_obj->desc_ready = true;
255 ffs_obj->ffs_data = ffs;
c6c56008 256
581791f5
AP
257 if (--missing_funcs) {
258 ret = 0;
259 goto done;
260 }
261
262 if (gfs_registered) {
263 ret = -EBUSY;
264 goto done;
265 }
266 gfs_registered = true;
c6c56008 267
03e42bd5 268 ret = usb_composite_probe(&gfs_driver);
c6c56008 269 if (unlikely(ret < 0))
581791f5
AP
270 gfs_registered = false;
271
272done:
273 mutex_unlock(&gfs_lock);
c6c56008
MN
274 return ret;
275}
276
277static void functionfs_closed_callback(struct ffs_data *ffs)
278{
e72c39c0 279 struct ffs_dev *ffs_obj;
581791f5 280
c6c56008 281 ENTER();
581791f5 282 mutex_lock(&gfs_lock);
c6c56008 283
581791f5
AP
284 ffs_obj = ffs->private_data;
285 if (!ffs_obj)
286 goto done;
287
288 ffs_obj->desc_ready = false;
289 missing_funcs++;
290
291 if (gfs_registered)
c6c56008 292 usb_composite_unregister(&gfs_driver);
581791f5
AP
293 gfs_registered = false;
294
295done:
296 mutex_unlock(&gfs_lock);
c6c56008
MN
297}
298
581791f5 299static void *functionfs_acquire_dev_callback(const char *dev_name)
c6c56008 300{
e72c39c0 301 struct ffs_dev *ffs_dev;
581791f5
AP
302
303 ENTER();
304 mutex_lock(&gfs_lock);
305
306 ffs_dev = gfs_find_dev(dev_name);
307 if (!ffs_dev) {
308 ffs_dev = ERR_PTR(-ENODEV);
309 goto done;
310 }
311
312 if (ffs_dev->mounted) {
313 ffs_dev = ERR_PTR(-EBUSY);
314 goto done;
315 }
316 ffs_dev->mounted = true;
317
318done:
319 mutex_unlock(&gfs_lock);
320 return ffs_dev;
c6c56008
MN
321}
322
581791f5
AP
323static void functionfs_release_dev_callback(struct ffs_data *ffs_data)
324{
e72c39c0 325 struct ffs_dev *ffs_dev;
581791f5
AP
326
327 ENTER();
328 mutex_lock(&gfs_lock);
329
330 ffs_dev = ffs_data->private_data;
331 if (ffs_dev)
332 ffs_dev->mounted = false;
333
334 mutex_unlock(&gfs_lock);
335}
336
337/*
338 * It is assumed that gfs_bind is called from a context where gfs_lock is held
339 */
c6c56008
MN
340static int gfs_bind(struct usb_composite_dev *cdev)
341{
6e257b14 342#if defined CONFIG_USB_FUNCTIONFS_ETH || defined CONFIG_USB_FUNCTIONFS_RNDIS
85aec59f
AP
343 struct net_device *net;
344#endif
f8dae531 345 int ret, i;
c6c56008
MN
346
347 ENTER();
348
581791f5 349 if (missing_funcs)
c6c56008 350 return -ENODEV;
f212ad4e
AP
351#if defined CONFIG_USB_FUNCTIONFS_ETH
352 if (can_support_ecm(cdev->gadget)) {
353 struct f_ecm_opts *ecm_opts;
354
355 fi_ecm = usb_get_function_instance("ecm");
356 if (IS_ERR(fi_ecm))
357 return PTR_ERR(fi_ecm);
358 ecm_opts = container_of(fi_ecm, struct f_ecm_opts, func_inst);
85aec59f 359 net = ecm_opts->net;
f212ad4e 360 } else {
85aec59f
AP
361 struct f_gether_opts *geth_opts;
362
363 fi_geth = usb_get_function_instance("geth");
364 if (IS_ERR(fi_geth))
365 return PTR_ERR(fi_geth);
366 geth_opts = container_of(fi_geth, struct f_gether_opts,
367 func_inst);
368 net = geth_opts->net;
f212ad4e 369 }
6e257b14
AP
370#endif
371
372#ifdef CONFIG_USB_FUNCTIONFS_RNDIS
373 {
374 struct f_rndis_opts *rndis_opts;
375
376 fi_rndis = usb_get_function_instance("rndis");
377 if (IS_ERR(fi_rndis)) {
378 ret = PTR_ERR(fi_rndis);
379 goto error;
380 }
381 rndis_opts = container_of(fi_rndis, struct f_rndis_opts,
382 func_inst);
383#ifndef CONFIG_USB_FUNCTIONFS_ETH
384 net = rndis_opts->net;
385#endif
386 }
387#endif
85aec59f 388
6e257b14
AP
389#if defined CONFIG_USB_FUNCTIONFS_ETH || defined CONFIG_USB_FUNCTIONFS_RNDIS
390 gether_set_qmult(net, qmult);
85aec59f
AP
391 if (!gether_set_host_addr(net, host_addr))
392 pr_info("using host ethernet address: %s", host_addr);
393 if (!gether_set_dev_addr(net, dev_addr))
394 pr_info("using self ethernet address: %s", dev_addr);
d6a01439 395#endif
f212ad4e
AP
396
397#if defined CONFIG_USB_FUNCTIONFS_RNDIS && defined CONFIG_USB_FUNCTIONFS_ETH
85aec59f
AP
398 gether_set_gadget(net, cdev->gadget);
399 ret = gether_register_netdev(net);
400 if (ret)
6e257b14 401 goto error_rndis;
85aec59f 402
f212ad4e
AP
403 if (can_support_ecm(cdev->gadget)) {
404 struct f_ecm_opts *ecm_opts;
405
406 ecm_opts = container_of(fi_ecm, struct f_ecm_opts, func_inst);
f212ad4e 407 ecm_opts->bound = true;
85aec59f
AP
408 } else {
409 struct f_gether_opts *geth_opts;
410
411 geth_opts = container_of(fi_geth, struct f_gether_opts,
412 func_inst);
413 geth_opts->bound = true;
d6a01439 414 }
6e257b14
AP
415
416 rndis_borrow_net(fi_rndis, net);
f212ad4e 417#endif
c6c56008 418
f8dae531 419 ret = usb_string_ids_tab(cdev, gfs_strings);
c6c56008 420 if (unlikely(ret < 0))
6e257b14 421 goto error_rndis;
d33f74fc 422 gfs_dev_desc.iProduct = gfs_strings[USB_GADGET_PRODUCT_IDX].id;
c6c56008 423
3416905b 424 for (i = func_num; i--; ) {
581791f5
AP
425 ret = functionfs_bind(ffs_tab[i].ffs_data, cdev);
426 if (unlikely(ret < 0)) {
427 while (++i < func_num)
428 functionfs_unbind(ffs_tab[i].ffs_data);
6e257b14 429 goto error_rndis;
581791f5
AP
430 }
431 }
c6c56008 432
f8dae531
MN
433 for (i = 0; i < ARRAY_SIZE(gfs_configurations); ++i) {
434 struct gfs_configuration *c = gfs_configurations + i;
276e2e4f 435 int sid = USB_GADGET_FIRST_AVAIL_IDX + i;
c6c56008 436
276e2e4f
SAS
437 c->c.label = gfs_strings[sid].s;
438 c->c.iConfiguration = gfs_strings[sid].id;
f8dae531
MN
439 c->c.bConfigurationValue = 1 + i;
440 c->c.bmAttributes = USB_CONFIG_ATT_SELFPOWER;
c6c56008 441
c9bfff9c 442 ret = usb_add_config(cdev, &c->c, gfs_do_config);
f8dae531
MN
443 if (unlikely(ret < 0))
444 goto error_unbind;
445 }
7d16e8d3 446 usb_composite_overwrite_options(cdev, &coverwrite);
c6c56008
MN
447 return 0;
448
449error_unbind:
581791f5
AP
450 for (i = 0; i < func_num; i++)
451 functionfs_unbind(ffs_tab[i].ffs_data);
6e257b14
AP
452error_rndis:
453#ifdef CONFIG_USB_FUNCTIONFS_RNDIS
454 usb_put_function_instance(fi_rndis);
c6c56008 455error:
6e257b14 456#endif
f212ad4e
AP
457#if defined CONFIG_USB_FUNCTIONFS_ETH
458 if (can_support_ecm(cdev->gadget))
459 usb_put_function_instance(fi_ecm);
460 else
85aec59f 461 usb_put_function_instance(fi_geth);
f212ad4e 462#endif
c6c56008
MN
463 return ret;
464}
465
581791f5
AP
466/*
467 * It is assumed that gfs_unbind is called from a context where gfs_lock is held
468 */
c6c56008
MN
469static int gfs_unbind(struct usb_composite_dev *cdev)
470{
581791f5
AP
471 int i;
472
c6c56008
MN
473 ENTER();
474
f212ad4e 475
6e257b14
AP
476#ifdef CONFIG_USB_FUNCTIONFS_RNDIS
477 usb_put_function(f_rndis);
478 usb_put_function_instance(fi_rndis);
479#endif
480
f212ad4e
AP
481#if defined CONFIG_USB_FUNCTIONFS_ETH
482 if (can_support_ecm(cdev->gadget)) {
483 usb_put_function(f_ecm);
484 usb_put_function_instance(fi_ecm);
485 } else {
85aec59f
AP
486 usb_put_function(f_geth);
487 usb_put_function_instance(fi_geth);
f212ad4e 488 }
f212ad4e 489#endif
1ec8f00f 490
fc19de61
MN
491 /*
492 * We may have been called in an error recovery from
c6c56008 493 * composite_bind() after gfs_unbind() failure so we need to
1ec8f00f 494 * check if instance's ffs_data is not NULL since gfs_bind() handles
c6c56008
MN
495 * all error recovery itself. I'd rather we werent called
496 * from composite on orror recovery, but what you're gonna
fc19de61
MN
497 * do...?
498 */
3416905b 499 for (i = func_num; i--; )
581791f5
AP
500 if (ffs_tab[i].ffs_data)
501 functionfs_unbind(ffs_tab[i].ffs_data);
c6c56008
MN
502
503 return 0;
504}
505
581791f5
AP
506/*
507 * It is assumed that gfs_do_config is called from a context where
508 * gfs_lock is held
509 */
f8dae531 510static int gfs_do_config(struct usb_configuration *c)
c6c56008 511{
f8dae531
MN
512 struct gfs_configuration *gc =
513 container_of(c, struct gfs_configuration, c);
581791f5 514 int i;
c6c56008
MN
515 int ret;
516
581791f5 517 if (missing_funcs)
c6c56008
MN
518 return -ENODEV;
519
520 if (gadget_is_otg(c->cdev->gadget)) {
521 c->descriptors = gfs_otg_desc;
522 c->bmAttributes |= USB_CONFIG_ATT_WAKEUP;
523 }
524
f8dae531 525 if (gc->eth) {
6e257b14 526 ret = gc->eth(c);
c6c56008
MN
527 if (unlikely(ret < 0))
528 return ret;
529 }
530
581791f5
AP
531 for (i = 0; i < func_num; i++) {
532 ret = functionfs_bind_config(c->cdev, c, ffs_tab[i].ffs_data);
533 if (unlikely(ret < 0))
534 return ret;
535 }
c6c56008 536
fc19de61
MN
537 /*
538 * After previous do_configs there may be some invalid
f588c0db
MN
539 * pointers in c->interface array. This happens every time
540 * a user space function with fewer interfaces than a user
541 * space function that was run before the new one is run. The
542 * compasit's set_config() assumes that if there is no more
543 * then MAX_CONFIG_INTERFACES interfaces in a configuration
544 * then there is a NULL pointer after the last interface in
fc19de61
MN
545 * c->interface array. We need to make sure this is true.
546 */
f588c0db
MN
547 if (c->next_interface_id < ARRAY_SIZE(c->interface))
548 c->interface[c->next_interface_id] = NULL;
549
c6c56008
MN
550 return 0;
551}
552
c6c56008 553#ifdef CONFIG_USB_FUNCTIONFS_ETH
fc19de61 554
6e257b14 555static int eth_bind_config(struct usb_configuration *c)
c6c56008 556{
f212ad4e
AP
557 int status = 0;
558
559 if (can_support_ecm(c->cdev->gadget)) {
560 f_ecm = usb_get_function(fi_ecm);
561 if (IS_ERR(f_ecm))
562 return PTR_ERR(f_ecm);
563
564 status = usb_add_function(c, f_ecm);
565 if (status < 0)
566 usb_put_function(f_ecm);
567
568 } else {
85aec59f
AP
569 f_geth = usb_get_function(fi_geth);
570 if (IS_ERR(f_geth))
571 return PTR_ERR(f_geth);
572
573 status = usb_add_function(c, f_geth);
574 if (status < 0)
575 usb_put_function(f_geth);
f212ad4e
AP
576 }
577 return status;
c6c56008 578}
fc19de61 579
c6c56008 580#endif
6e257b14
AP
581
582#ifdef CONFIG_USB_FUNCTIONFS_RNDIS
583
584static int bind_rndis_config(struct usb_configuration *c)
585{
586 int status = 0;
587
588 f_rndis = usb_get_function(fi_rndis);
589 if (IS_ERR(f_rndis))
590 return PTR_ERR(f_rndis);
591
592 status = usb_add_function(c, f_rndis);
593 if (status < 0)
594 usb_put_function(f_rndis);
595
596 return status;
597}
598
599#endif
This page took 1.468796 seconds and 5 git commands to generate.