• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6/drivers/usb/gadget/
1#include <linux/module.h>
2#include <linux/utsname.h>
3
4
5/*
6 * kbuild is not very cooperative with respect to linking separately
7 * compiled library objects into one module.  So for now we won't use
8 * separate compilation ... ensuring init/exit sections work to shrink
9 * the runtime footprint, and giving us at least some parts of what
10 * a "gcc --combine ... part1.c part2.c part3.c ... " build would.
11 */
12
13#include "composite.c"
14#include "usbstring.c"
15#include "config.c"
16#include "epautoconf.c"
17
18#if defined CONFIG_USB_FUNCTIONFS_ETH || defined CONFIG_USB_FUNCTIONFS_RNDIS
19#  if defined USB_ETH_RNDIS
20#    undef USB_ETH_RNDIS
21#  endif
22#  ifdef CONFIG_USB_FUNCTIONFS_RNDIS
23#    define USB_ETH_RNDIS y
24#  endif
25
26#  include "f_ecm.c"
27#  include "f_subset.c"
28#  ifdef USB_ETH_RNDIS
29#    include "f_rndis.c"
30#    include "rndis.c"
31#  endif
32#  include "u_ether.c"
33
34static u8 gfs_hostaddr[ETH_ALEN];
35#  ifdef CONFIG_USB_FUNCTIONFS_ETH
36static int eth_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN]);
37#  endif
38#else
39#  define gether_cleanup() do { } while (0)
40#  define gether_setup(gadget, hostaddr)   ((int)0)
41#  define gfs_hostaddr NULL
42#endif
43
44#include "f_fs.c"
45
46
47#define DRIVER_NAME	"g_ffs"
48#define DRIVER_DESC	"USB Function Filesystem"
49#define DRIVER_VERSION	"24 Aug 2004"
50
51MODULE_DESCRIPTION(DRIVER_DESC);
52MODULE_AUTHOR("Michal Nazarewicz");
53MODULE_LICENSE("GPL");
54
55
56static unsigned short gfs_vendor_id    = 0x1d6b;	/* Linux Foundation */
57static unsigned short gfs_product_id   = 0x0105;	/* FunctionFS Gadget */
58
59static struct usb_device_descriptor gfs_dev_desc = {
60	.bLength		= sizeof gfs_dev_desc,
61	.bDescriptorType	= USB_DT_DEVICE,
62
63	.bcdUSB			= cpu_to_le16(0x0200),
64	.bDeviceClass		= USB_CLASS_PER_INTERFACE,
65
66	/* Vendor and product id can be overridden by module parameters.  */
67	/* .idVendor		= cpu_to_le16(gfs_vendor_id), */
68	/* .idProduct		= cpu_to_le16(gfs_product_id), */
69	/* .bcdDevice		= f(hardware) */
70	/* .iManufacturer	= DYNAMIC */
71	/* .iProduct		= DYNAMIC */
72	/* NO SERIAL NUMBER */
73	.bNumConfigurations	= 1,
74};
75
76#define GFS_MODULE_PARAM_DESC(name, field) \
77	MODULE_PARM_DESC(name, "Value of the " #field " field of the device descriptor sent to the host.  Takes effect only prior to the user-space driver registering to the FunctionFS.")
78
79module_param_named(usb_class,    gfs_dev_desc.bDeviceClass,    byte,   0644);
80GFS_MODULE_PARAM_DESC(usb_class, bDeviceClass);
81module_param_named(usb_subclass, gfs_dev_desc.bDeviceSubClass, byte,   0644);
82GFS_MODULE_PARAM_DESC(usb_subclass, bDeviceSubClass);
83module_param_named(usb_protocol, gfs_dev_desc.bDeviceProtocol, byte,   0644);
84GFS_MODULE_PARAM_DESC(usb_protocol, bDeviceProtocol);
85module_param_named(usb_vendor,   gfs_vendor_id,                ushort, 0644);
86GFS_MODULE_PARAM_DESC(usb_vendor, idVendor);
87module_param_named(usb_product,  gfs_product_id,               ushort, 0644);
88GFS_MODULE_PARAM_DESC(usb_product, idProduct);
89
90
91
92static const struct usb_descriptor_header *gfs_otg_desc[] = {
93	(const struct usb_descriptor_header *)
94	&(const struct usb_otg_descriptor) {
95		.bLength		= sizeof(struct usb_otg_descriptor),
96		.bDescriptorType	= USB_DT_OTG,
97
98		/* REVISIT SRP-only hardware is possible, although
99		 * it would not be called "OTG" ... */
100		.bmAttributes		= USB_OTG_SRP | USB_OTG_HNP,
101	},
102
103	NULL
104};
105
106/* string IDs are assigned dynamically */
107
108enum {
109	GFS_STRING_MANUFACTURER_IDX,
110	GFS_STRING_PRODUCT_IDX,
111	GFS_STRING_FIRST_CONFIG_IDX,
112};
113
114static       char gfs_manufacturer[50];
115static const char gfs_driver_desc[] = DRIVER_DESC;
116static const char gfs_short_name[]  = DRIVER_NAME;
117
118static struct usb_string gfs_strings[] = {
119	[GFS_STRING_MANUFACTURER_IDX].s = gfs_manufacturer,
120	[GFS_STRING_PRODUCT_IDX].s = gfs_driver_desc,
121#ifdef CONFIG_USB_FUNCTIONFS_RNDIS
122	{ .s = "FunctionFS + RNDIS" },
123#endif
124#ifdef CONFIG_USB_FUNCTIONFS_ETH
125	{ .s = "FunctionFS + ECM" },
126#endif
127#ifdef CONFIG_USB_FUNCTIONFS_GENERIC
128	{ .s = "FunctionFS" },
129#endif
130	{  } /* end of list */
131};
132
133static struct usb_gadget_strings *gfs_dev_strings[] = {
134	&(struct usb_gadget_strings) {
135		.language	= 0x0409,	/* en-us */
136		.strings	= gfs_strings,
137	},
138	NULL,
139};
140
141
142
143struct gfs_configuration {
144	struct usb_configuration c;
145	int (*eth)(struct usb_configuration *c, u8 *ethaddr);
146} gfs_configurations[] = {
147#ifdef CONFIG_USB_FUNCTIONFS_RNDIS
148	{
149		.eth		= rndis_bind_config,
150	},
151#endif
152
153#ifdef CONFIG_USB_FUNCTIONFS_ETH
154	{
155		.eth		= eth_bind_config,
156	},
157#endif
158
159#ifdef CONFIG_USB_FUNCTIONFS_GENERIC
160	{
161	},
162#endif
163};
164
165
166static int gfs_bind(struct usb_composite_dev *cdev);
167static int gfs_unbind(struct usb_composite_dev *cdev);
168static int gfs_do_config(struct usb_configuration *c);
169
170static struct usb_composite_driver gfs_driver = {
171	.name		= gfs_short_name,
172	.dev		= &gfs_dev_desc,
173	.strings	= gfs_dev_strings,
174	.bind		= gfs_bind,
175	.unbind		= gfs_unbind,
176};
177
178
179static struct ffs_data *gfs_ffs_data;
180static unsigned long gfs_registered;
181
182
183static int  gfs_init(void)
184{
185	ENTER();
186
187	return functionfs_init();
188}
189module_init(gfs_init);
190
191static void  gfs_exit(void)
192{
193	ENTER();
194
195	if (test_and_clear_bit(0, &gfs_registered))
196		usb_composite_unregister(&gfs_driver);
197
198	functionfs_cleanup();
199}
200module_exit(gfs_exit);
201
202
203static int functionfs_ready_callback(struct ffs_data *ffs)
204{
205	int ret;
206
207	ENTER();
208
209	if (WARN_ON(test_and_set_bit(0, &gfs_registered)))
210		return -EBUSY;
211
212	gfs_ffs_data = ffs;
213	ret = usb_composite_register(&gfs_driver);
214	if (unlikely(ret < 0))
215		clear_bit(0, &gfs_registered);
216	return ret;
217}
218
219static void functionfs_closed_callback(struct ffs_data *ffs)
220{
221	ENTER();
222
223	if (test_and_clear_bit(0, &gfs_registered))
224		usb_composite_unregister(&gfs_driver);
225}
226
227
228static int functionfs_check_dev_callback(const char *dev_name)
229{
230	return 0;
231}
232
233
234
235static int gfs_bind(struct usb_composite_dev *cdev)
236{
237	int ret, i;
238
239	ENTER();
240
241	if (WARN_ON(!gfs_ffs_data))
242		return -ENODEV;
243
244	ret = gether_setup(cdev->gadget, gfs_hostaddr);
245	if (unlikely(ret < 0))
246		goto error_quick;
247
248	gfs_dev_desc.idVendor  = cpu_to_le16(gfs_vendor_id);
249	gfs_dev_desc.idProduct = cpu_to_le16(gfs_product_id);
250
251	snprintf(gfs_manufacturer, sizeof gfs_manufacturer, "%s %s with %s",
252		 init_utsname()->sysname, init_utsname()->release,
253		 cdev->gadget->name);
254
255	ret = usb_string_ids_tab(cdev, gfs_strings);
256	if (unlikely(ret < 0))
257		goto error;
258
259	gfs_dev_desc.iManufacturer = gfs_strings[GFS_STRING_MANUFACTURER_IDX].id;
260	gfs_dev_desc.iProduct      = gfs_strings[GFS_STRING_PRODUCT_IDX].id;
261
262	ret = functionfs_bind(gfs_ffs_data, cdev);
263	if (unlikely(ret < 0))
264		goto error;
265
266	for (i = 0; i < ARRAY_SIZE(gfs_configurations); ++i) {
267		struct gfs_configuration *c = gfs_configurations + i;
268
269		ret = GFS_STRING_FIRST_CONFIG_IDX + i;
270		c->c.label			= gfs_strings[ret].s;
271		c->c.iConfiguration		= gfs_strings[ret].id;
272		c->c.bind			= gfs_do_config;
273		c->c.bConfigurationValue	= 1 + i;
274		c->c.bmAttributes		= USB_CONFIG_ATT_SELFPOWER;
275
276		ret = usb_add_config(cdev, &c->c);
277		if (unlikely(ret < 0))
278			goto error_unbind;
279	}
280
281	return 0;
282
283error_unbind:
284	functionfs_unbind(gfs_ffs_data);
285error:
286	gether_cleanup();
287error_quick:
288	gfs_ffs_data = NULL;
289	return ret;
290}
291
292static int gfs_unbind(struct usb_composite_dev *cdev)
293{
294	ENTER();
295
296	/* We may have been called in an error recovery frem
297	 * composite_bind() after gfs_unbind() failure so we need to
298	 * check if gfs_ffs_data is not NULL since gfs_bind() handles
299	 * all error recovery itself.  I'd rather we werent called
300	 * from composite on orror recovery, but what you're gonna
301	 * do...? */
302
303	if (gfs_ffs_data) {
304		gether_cleanup();
305		functionfs_unbind(gfs_ffs_data);
306		gfs_ffs_data = NULL;
307	}
308
309	return 0;
310}
311
312
313static int gfs_do_config(struct usb_configuration *c)
314{
315	struct gfs_configuration *gc =
316		container_of(c, struct gfs_configuration, c);
317	int ret;
318
319	if (WARN_ON(!gfs_ffs_data))
320		return -ENODEV;
321
322	if (gadget_is_otg(c->cdev->gadget)) {
323		c->descriptors = gfs_otg_desc;
324		c->bmAttributes |= USB_CONFIG_ATT_WAKEUP;
325	}
326
327	if (gc->eth) {
328		ret = gc->eth(c, gfs_hostaddr);
329		if (unlikely(ret < 0))
330			return ret;
331	}
332
333	ret = functionfs_bind_config(c->cdev, c, gfs_ffs_data);
334	if (unlikely(ret < 0))
335		return ret;
336
337	/* After previous do_configs there may be some invalid
338	 * pointers in c->interface array.  This happens every time
339	 * a user space function with fewer interfaces than a user
340	 * space function that was run before the new one is run.  The
341	 * compasit's set_config() assumes that if there is no more
342	 * then MAX_CONFIG_INTERFACES interfaces in a configuration
343	 * then there is a NULL pointer after the last interface in
344	 * c->interface array.  We need to make sure this is true. */
345	if (c->next_interface_id < ARRAY_SIZE(c->interface))
346		c->interface[c->next_interface_id] = NULL;
347
348	return 0;
349}
350
351
352#ifdef CONFIG_USB_FUNCTIONFS_ETH
353static int eth_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN])
354{
355	return can_support_ecm(c->cdev->gadget)
356		? ecm_bind_config(c, ethaddr)
357		: geth_bind_config(c, ethaddr);
358}
359#endif
360