Linux Audio

Check our new training course

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