Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph...
[sfrench/cifs-2.6.git] / drivers / usb / gadget / g_ffs.c
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
34 static u8 gfs_hostaddr[ETH_ALEN];
35 #else
36 #  if !defined CONFIG_USB_FUNCTIONFS_GENERIC
37 #    define CONFIG_USB_FUNCTIONFS_GENERIC
38 #  endif
39 #  define gether_cleanup() do { } while (0)
40 #  define gether_setup(gadget, hostaddr)   ((int)0)
41 #endif
42
43 #include "f_fs.c"
44
45
46 #define DRIVER_NAME     "g_ffs"
47 #define DRIVER_DESC     "USB Function Filesystem"
48 #define DRIVER_VERSION  "24 Aug 2004"
49
50 MODULE_DESCRIPTION(DRIVER_DESC);
51 MODULE_AUTHOR("Michal Nazarewicz");
52 MODULE_LICENSE("GPL");
53
54
55 static unsigned short gfs_vendor_id    = 0x0525;        /* XXX NetChip */
56 static unsigned short gfs_product_id   = 0xa4ac;        /* XXX */
57
58 static struct usb_device_descriptor gfs_dev_desc = {
59         .bLength                = sizeof gfs_dev_desc,
60         .bDescriptorType        = USB_DT_DEVICE,
61
62         .bcdUSB                 = cpu_to_le16(0x0200),
63         .bDeviceClass           = USB_CLASS_PER_INTERFACE,
64
65         /* Vendor and product id can be overridden by module parameters.  */
66         /* .idVendor            = cpu_to_le16(gfs_vendor_id), */
67         /* .idProduct           = cpu_to_le16(gfs_product_id), */
68         /* .bcdDevice           = f(hardware) */
69         /* .iManufacturer       = DYNAMIC */
70         /* .iProduct            = DYNAMIC */
71         /* NO SERIAL NUMBER */
72         .bNumConfigurations     = 1,
73 };
74
75 #define GFS_MODULE_PARAM_DESC(name, field) \
76         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.")
77
78 module_param_named(usb_class,    gfs_dev_desc.bDeviceClass,    byte,   0644);
79 GFS_MODULE_PARAM_DESC(usb_class, bDeviceClass);
80 module_param_named(usb_subclass, gfs_dev_desc.bDeviceSubClass, byte,   0644);
81 GFS_MODULE_PARAM_DESC(usb_subclass, bDeviceSubClass);
82 module_param_named(usb_protocol, gfs_dev_desc.bDeviceProtocol, byte,   0644);
83 GFS_MODULE_PARAM_DESC(usb_protocol, bDeviceProtocol);
84 module_param_named(usb_vendor,   gfs_vendor_id,                ushort, 0644);
85 GFS_MODULE_PARAM_DESC(usb_vendor, idVendor);
86 module_param_named(usb_product,  gfs_product_id,               ushort, 0644);
87 GFS_MODULE_PARAM_DESC(usb_product, idProduct);
88
89
90
91 static const struct usb_descriptor_header *gfs_otg_desc[] = {
92         (const struct usb_descriptor_header *)
93         &(const struct usb_otg_descriptor) {
94                 .bLength                = sizeof(struct usb_otg_descriptor),
95                 .bDescriptorType        = USB_DT_OTG,
96
97                 /* REVISIT SRP-only hardware is possible, although
98                  * it would not be called "OTG" ... */
99                 .bmAttributes           = USB_OTG_SRP | USB_OTG_HNP,
100         },
101
102         NULL
103 };
104
105 /* string IDs are assigned dynamically */
106
107 enum {
108         GFS_STRING_MANUFACTURER_IDX,
109         GFS_STRING_PRODUCT_IDX,
110 #ifdef CONFIG_USB_FUNCTIONFS_RNDIS
111         GFS_STRING_RNDIS_CONFIG_IDX,
112 #endif
113 #ifdef CONFIG_USB_FUNCTIONFS_ETH
114         GFS_STRING_ECM_CONFIG_IDX,
115 #endif
116 #ifdef CONFIG_USB_FUNCTIONFS_GENERIC
117         GFS_STRING_GENERIC_CONFIG_IDX,
118 #endif
119 };
120
121 static       char gfs_manufacturer[50];
122 static const char gfs_driver_desc[] = DRIVER_DESC;
123 static const char gfs_short_name[]  = DRIVER_NAME;
124
125 static struct usb_string gfs_strings[] = {
126         [GFS_STRING_MANUFACTURER_IDX].s = gfs_manufacturer,
127         [GFS_STRING_PRODUCT_IDX].s = gfs_driver_desc,
128 #ifdef CONFIG_USB_FUNCTIONFS_RNDIS
129         [GFS_STRING_RNDIS_CONFIG_IDX].s = "FunctionFS + RNDIS",
130 #endif
131 #ifdef CONFIG_USB_FUNCTIONFS_ETH
132         [GFS_STRING_ECM_CONFIG_IDX].s = "FunctionFS + ECM",
133 #endif
134 #ifdef CONFIG_USB_FUNCTIONFS_GENERIC
135         [GFS_STRING_GENERIC_CONFIG_IDX].s = "FunctionFS",
136 #endif
137         {  } /* end of list */
138 };
139
140 static struct usb_gadget_strings *gfs_dev_strings[] = {
141         &(struct usb_gadget_strings) {
142                 .language       = 0x0409,       /* en-us */
143                 .strings        = gfs_strings,
144         },
145         NULL,
146 };
147
148
149 #ifdef CONFIG_USB_FUNCTIONFS_RNDIS
150 static int gfs_do_rndis_config(struct usb_configuration *c);
151
152 static struct usb_configuration gfs_rndis_config_driver = {
153         .label                  = "FunctionFS + RNDIS",
154         .bind                   = gfs_do_rndis_config,
155         .bConfigurationValue    = 1,
156         /* .iConfiguration      = DYNAMIC */
157         .bmAttributes           = USB_CONFIG_ATT_SELFPOWER,
158 };
159 #  define gfs_add_rndis_config(cdev) \
160         usb_add_config(cdev, &gfs_rndis_config_driver)
161 #else
162 #  define gfs_add_rndis_config(cdev) 0
163 #endif
164
165
166 #ifdef CONFIG_USB_FUNCTIONFS_ETH
167 static int gfs_do_ecm_config(struct usb_configuration *c);
168
169 static struct usb_configuration gfs_ecm_config_driver = {
170         .label                  = "FunctionFS + ECM",
171         .bind                   = gfs_do_ecm_config,
172         .bConfigurationValue    = 1,
173         /* .iConfiguration      = DYNAMIC */
174         .bmAttributes           = USB_CONFIG_ATT_SELFPOWER,
175 };
176 #  define gfs_add_ecm_config(cdev) \
177         usb_add_config(cdev, &gfs_ecm_config_driver)
178 #else
179 #  define gfs_add_ecm_config(cdev) 0
180 #endif
181
182
183 #ifdef CONFIG_USB_FUNCTIONFS_GENERIC
184 static int gfs_do_generic_config(struct usb_configuration *c);
185
186 static struct usb_configuration gfs_generic_config_driver = {
187         .label                  = "FunctionFS",
188         .bind                   = gfs_do_generic_config,
189         .bConfigurationValue    = 2,
190         /* .iConfiguration      = DYNAMIC */
191         .bmAttributes           = USB_CONFIG_ATT_SELFPOWER,
192 };
193 #  define gfs_add_generic_config(cdev) \
194         usb_add_config(cdev, &gfs_generic_config_driver)
195 #else
196 #  define gfs_add_generic_config(cdev) 0
197 #endif
198
199
200 static int gfs_bind(struct usb_composite_dev *cdev);
201 static int gfs_unbind(struct usb_composite_dev *cdev);
202
203 static struct usb_composite_driver gfs_driver = {
204         .name           = gfs_short_name,
205         .dev            = &gfs_dev_desc,
206         .strings        = gfs_dev_strings,
207         .bind           = gfs_bind,
208         .unbind         = gfs_unbind,
209 };
210
211
212 static struct ffs_data *gfs_ffs_data;
213 static unsigned long gfs_registered;
214
215
216 static int  gfs_init(void)
217 {
218         ENTER();
219
220         return functionfs_init();
221 }
222 module_init(gfs_init);
223
224 static void  gfs_exit(void)
225 {
226         ENTER();
227
228         if (test_and_clear_bit(0, &gfs_registered))
229                 usb_composite_unregister(&gfs_driver);
230
231         functionfs_cleanup();
232 }
233 module_exit(gfs_exit);
234
235
236 static int functionfs_ready_callback(struct ffs_data *ffs)
237 {
238         int ret;
239
240         ENTER();
241
242         if (WARN_ON(test_and_set_bit(0, &gfs_registered)))
243                 return -EBUSY;
244
245         gfs_ffs_data = ffs;
246         ret = usb_composite_register(&gfs_driver);
247         if (unlikely(ret < 0))
248                 clear_bit(0, &gfs_registered);
249         return ret;
250 }
251
252 static void functionfs_closed_callback(struct ffs_data *ffs)
253 {
254         ENTER();
255
256         if (test_and_clear_bit(0, &gfs_registered))
257                 usb_composite_unregister(&gfs_driver);
258 }
259
260
261 static int functionfs_check_dev_callback(const char *dev_name)
262 {
263         return 0;
264 }
265
266
267
268 static int gfs_bind(struct usb_composite_dev *cdev)
269 {
270         int ret;
271
272         ENTER();
273
274         if (WARN_ON(!gfs_ffs_data))
275                 return -ENODEV;
276
277         ret = gether_setup(cdev->gadget, gfs_hostaddr);
278         if (unlikely(ret < 0))
279                 goto error_quick;
280
281         gfs_dev_desc.idVendor  = cpu_to_le16(gfs_vendor_id);
282         gfs_dev_desc.idProduct = cpu_to_le16(gfs_product_id);
283
284         snprintf(gfs_manufacturer, sizeof gfs_manufacturer, "%s %s with %s",
285                  init_utsname()->sysname, init_utsname()->release,
286                  cdev->gadget->name);
287         ret = usb_string_id(cdev);
288         if (unlikely(ret < 0))
289                 goto error;
290         gfs_strings[GFS_STRING_MANUFACTURER_IDX].id = ret;
291         gfs_dev_desc.iManufacturer = ret;
292
293         ret = usb_string_id(cdev);
294         if (unlikely(ret < 0))
295                 goto error;
296         gfs_strings[GFS_STRING_PRODUCT_IDX].id = ret;
297         gfs_dev_desc.iProduct = ret;
298
299 #ifdef CONFIG_USB_FUNCTIONFS_RNDIS
300         ret = usb_string_id(cdev);
301         if (unlikely(ret < 0))
302                 goto error;
303         gfs_strings[GFS_STRING_RNDIS_CONFIG_IDX].id = ret;
304         gfs_rndis_config_driver.iConfiguration = ret;
305 #endif
306
307 #ifdef CONFIG_USB_FUNCTIONFS_ETH
308         ret = usb_string_id(cdev);
309         if (unlikely(ret < 0))
310                 goto error;
311         gfs_strings[GFS_STRING_ECM_CONFIG_IDX].id = ret;
312         gfs_ecm_config_driver.iConfiguration = ret;
313 #endif
314
315 #ifdef CONFIG_USB_FUNCTIONFS_GENERIC
316         ret = usb_string_id(cdev);
317         if (unlikely(ret < 0))
318                 goto error;
319         gfs_strings[GFS_STRING_GENERIC_CONFIG_IDX].id = ret;
320         gfs_generic_config_driver.iConfiguration = ret;
321 #endif
322
323         ret = functionfs_bind(gfs_ffs_data, cdev);
324         if (unlikely(ret < 0))
325                 goto error;
326
327         ret = gfs_add_rndis_config(cdev);
328         if (unlikely(ret < 0))
329                 goto error_unbind;
330
331         ret = gfs_add_ecm_config(cdev);
332         if (unlikely(ret < 0))
333                 goto error_unbind;
334
335         ret = gfs_add_generic_config(cdev);
336         if (unlikely(ret < 0))
337                 goto error_unbind;
338
339         return 0;
340
341 error_unbind:
342         functionfs_unbind(gfs_ffs_data);
343 error:
344         gether_cleanup();
345 error_quick:
346         gfs_ffs_data = NULL;
347         return ret;
348 }
349
350 static int gfs_unbind(struct usb_composite_dev *cdev)
351 {
352         ENTER();
353
354         /* We may have been called in an error recovery frem
355          * composite_bind() after gfs_unbind() failure so we need to
356          * check if gfs_ffs_data is not NULL since gfs_bind() handles
357          * all error recovery itself.  I'd rather we werent called
358          * from composite on orror recovery, but what you're gonna
359          * do...? */
360
361         if (gfs_ffs_data) {
362                 gether_cleanup();
363                 functionfs_unbind(gfs_ffs_data);
364                 gfs_ffs_data = NULL;
365         }
366
367         return 0;
368 }
369
370
371 static int __gfs_do_config(struct usb_configuration *c,
372                            int (*eth)(struct usb_configuration *c, u8 *ethaddr),
373                            u8 *ethaddr)
374 {
375         int ret;
376
377         if (WARN_ON(!gfs_ffs_data))
378                 return -ENODEV;
379
380         if (gadget_is_otg(c->cdev->gadget)) {
381                 c->descriptors = gfs_otg_desc;
382                 c->bmAttributes |= USB_CONFIG_ATT_WAKEUP;
383         }
384
385         if (eth) {
386                 ret = eth(c, ethaddr);
387                 if (unlikely(ret < 0))
388                         return ret;
389         }
390
391         ret = functionfs_add(c->cdev, c, gfs_ffs_data);
392         if (unlikely(ret < 0))
393                 return ret;
394
395         /* After previous do_configs there may be some invalid
396          * pointers in c->interface array.  This happens every time
397          * a user space function with fewer interfaces than a user
398          * space function that was run before the new one is run.  The
399          * compasit's set_config() assumes that if there is no more
400          * then MAX_CONFIG_INTERFACES interfaces in a configuration
401          * then there is a NULL pointer after the last interface in
402          * c->interface array.  We need to make sure this is true. */
403         if (c->next_interface_id < ARRAY_SIZE(c->interface))
404                 c->interface[c->next_interface_id] = NULL;
405
406         return 0;
407 }
408
409 #ifdef CONFIG_USB_FUNCTIONFS_RNDIS
410 static int gfs_do_rndis_config(struct usb_configuration *c)
411 {
412         ENTER();
413
414         return __gfs_do_config(c, rndis_bind_config, gfs_hostaddr);
415 }
416 #endif
417
418 #ifdef CONFIG_USB_FUNCTIONFS_ETH
419 static int gfs_do_ecm_config(struct usb_configuration *c)
420 {
421         ENTER();
422
423         return __gfs_do_config(c,
424                                can_support_ecm(c->cdev->gadget)
425                              ? ecm_bind_config : geth_bind_config,
426                                gfs_hostaddr);
427 }
428 #endif
429
430 #ifdef CONFIG_USB_FUNCTIONFS_GENERIC
431 static int gfs_do_generic_config(struct usb_configuration *c)
432 {
433         ENTER();
434
435         return __gfs_do_config(c, NULL, NULL);
436 }
437 #endif