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