aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
authorSebastian Andrzej Siewior <bigeasy@linutronix.de>2012-12-23 15:10:01 -0500
committerFelipe Balbi <balbi@ti.com>2013-01-21 13:52:40 -0500
commitcf9a08ae5aece88987bbeee8eb0dd0ebb5015815 (patch)
treebbc7e204bd532b6ff84586653f57bc7ec6bf6380 /drivers/usb
parentde53c25447117eae6b3f8952f663f08a09e0dbb7 (diff)
usb: gadget: convert source sink and loopback to new function interface
This patch converts the f_sourcesink and f_loopback file to the USB-function module. Both functions shares a few common utility functions which are currently implemented in g_zero.c itself. This patch moves the common code into the sourcesink file and creates one module out of the the two functions (source sink and loop back). The g_zero gadget is function specific to source sink and loop back to set a few options. This Symbol dependency enforces a modul load right now. Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Signed-off-by: Felipe Balbi <balbi@ti.com>
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/gadget/Kconfig4
-rw-r--r--drivers/usb/gadget/Makefile4
-rw-r--r--drivers/usb/gadget/f_loopback.c75
-rw-r--r--drivers/usb/gadget/f_sourcesink.c165
-rw-r--r--drivers/usb/gadget/g_zero.h31
-rw-r--r--drivers/usb/gadget/zero.c196
6 files changed, 321 insertions, 154 deletions
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
index 14625fd2cecd..0ef5549b6544 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -500,6 +500,9 @@ config USB_LIBCOMPOSITE
500 tristate 500 tristate
501 depends on USB_GADGET 501 depends on USB_GADGET
502 502
503config USB_F_SS_LB
504 tristate
505
503choice 506choice
504 tristate "USB Gadget Drivers" 507 tristate "USB Gadget Drivers"
505 default USB_ETH 508 default USB_ETH
@@ -524,6 +527,7 @@ choice
524config USB_ZERO 527config USB_ZERO
525 tristate "Gadget Zero (DEVELOPMENT)" 528 tristate "Gadget Zero (DEVELOPMENT)"
526 select USB_LIBCOMPOSITE 529 select USB_LIBCOMPOSITE
530 select USB_F_SS_LB
527 help 531 help
528 Gadget Zero is a two-configuration device. It either sinks and 532 Gadget Zero is a two-configuration device. It either sinks and
529 sources bulk data; or it loops back a configurable number of 533 sources bulk data; or it loops back a configurable number of
diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile
index fef41f5d6e8d..e412befa7a35 100644
--- a/drivers/usb/gadget/Makefile
+++ b/drivers/usb/gadget/Makefile
@@ -74,3 +74,7 @@ obj-$(CONFIG_USB_G_WEBCAM) += g_webcam.o
74obj-$(CONFIG_USB_G_NCM) += g_ncm.o 74obj-$(CONFIG_USB_G_NCM) += g_ncm.o
75obj-$(CONFIG_USB_G_ACM_MS) += g_acm_ms.o 75obj-$(CONFIG_USB_G_ACM_MS) += g_acm_ms.o
76obj-$(CONFIG_USB_GADGET_TARGET) += tcm_usb_gadget.o 76obj-$(CONFIG_USB_GADGET_TARGET) += tcm_usb_gadget.o
77
78# USB Functions
79f_ss_lb-y := f_loopback.o f_sourcesink.o
80obj-$(CONFIG_USB_F_SS_LB) += f_ss_lb.o
diff --git a/drivers/usb/gadget/f_loopback.c b/drivers/usb/gadget/f_loopback.c
index 3d103a2f998f..4a3873a0f2d0 100644
--- a/drivers/usb/gadget/f_loopback.c
+++ b/drivers/usb/gadget/f_loopback.c
@@ -15,10 +15,11 @@
15#include <linux/slab.h> 15#include <linux/slab.h>
16#include <linux/kernel.h> 16#include <linux/kernel.h>
17#include <linux/device.h> 17#include <linux/device.h>
18#include <linux/module.h>
19#include <linux/err.h>
20#include <linux/usb/composite.h>
18 21
19#include "g_zero.h" 22#include "g_zero.h"
20#include "gadget_chips.h"
21
22 23
23/* 24/*
24 * LOOPBACK FUNCTION ... a testing vehicle for USB peripherals, 25 * LOOPBACK FUNCTION ... a testing vehicle for USB peripherals,
@@ -44,9 +45,8 @@ static inline struct f_loopback *func_to_loop(struct usb_function *f)
44 return container_of(f, struct f_loopback, function); 45 return container_of(f, struct f_loopback, function);
45} 46}
46 47
47static unsigned qlen = 32; 48static unsigned qlen;
48module_param(qlen, uint, 0); 49static unsigned buflen;
49MODULE_PARM_DESC(qlenn, "depth of loopback queue");
50 50
51/*-------------------------------------------------------------------------*/ 51/*-------------------------------------------------------------------------*/
52 52
@@ -171,8 +171,7 @@ static struct usb_gadget_strings *loopback_strings[] = {
171 171
172/*-------------------------------------------------------------------------*/ 172/*-------------------------------------------------------------------------*/
173 173
174static int __init 174static int loopback_bind(struct usb_configuration *c, struct usb_function *f)
175loopback_bind(struct usb_configuration *c, struct usb_function *f)
176{ 175{
177 struct usb_composite_dev *cdev = c->cdev; 176 struct usb_composite_dev *cdev = c->cdev;
178 struct f_loopback *loop = func_to_loop(f); 177 struct f_loopback *loop = func_to_loop(f);
@@ -229,8 +228,7 @@ autoconf_fail:
229 return 0; 228 return 0;
230} 229}
231 230
232static void 231static void lb_free_func(struct usb_function *f)
233loopback_unbind(struct usb_configuration *c, struct usb_function *f)
234{ 232{
235 usb_free_all_descriptors(f); 233 usb_free_all_descriptors(f);
236 kfree(func_to_loop(f)); 234 kfree(func_to_loop(f));
@@ -372,25 +370,64 @@ static void loopback_disable(struct usb_function *f)
372 disable_loopback(loop); 370 disable_loopback(loop);
373} 371}
374 372
375/*-------------------------------------------------------------------------*/ 373static struct usb_function *loopback_alloc(struct usb_function_instance *fi)
376
377static int __init loopback_bind_config(struct usb_configuration *c)
378{ 374{
379 struct f_loopback *loop; 375 struct f_loopback *loop;
380 int status; 376 struct f_lb_opts *lb_opts;
381 377
382 loop = kzalloc(sizeof *loop, GFP_KERNEL); 378 loop = kzalloc(sizeof *loop, GFP_KERNEL);
383 if (!loop) 379 if (!loop)
384 return -ENOMEM; 380 return ERR_PTR(-ENOMEM);
381
382 lb_opts = container_of(fi, struct f_lb_opts, func_inst);
383 buflen = lb_opts->bulk_buflen;
384 qlen = lb_opts->qlen;
385 if (!qlen)
386 qlen = 32;
385 387
386 loop->function.name = "loopback"; 388 loop->function.name = "loopback";
387 loop->function.bind = loopback_bind; 389 loop->function.bind = loopback_bind;
388 loop->function.unbind = loopback_unbind;
389 loop->function.set_alt = loopback_set_alt; 390 loop->function.set_alt = loopback_set_alt;
390 loop->function.disable = loopback_disable; 391 loop->function.disable = loopback_disable;
392 loop->function.strings = loopback_strings;
393
394 loop->function.free_func = lb_free_func;
395
396 return &loop->function;
397}
398
399static void lb_free_instance(struct usb_function_instance *fi)
400{
401 struct f_lb_opts *lb_opts;
391 402
392 status = usb_add_function(c, &loop->function); 403 lb_opts = container_of(fi, struct f_lb_opts, func_inst);
393 if (status) 404 kfree(lb_opts);
394 kfree(loop);
395 return status;
396} 405}
406
407static struct usb_function_instance *loopback_alloc_instance(void)
408{
409 struct f_lb_opts *lb_opts;
410
411 lb_opts = kzalloc(sizeof(*lb_opts), GFP_KERNEL);
412 if (!lb_opts)
413 return ERR_PTR(-ENOMEM);
414 lb_opts->func_inst.free_func_inst = lb_free_instance;
415 return &lb_opts->func_inst;
416}
417DECLARE_USB_FUNCTION(Loopback, loopback_alloc_instance, loopback_alloc);
418
419int __init lb_modinit(void)
420{
421 int ret;
422
423 ret = usb_function_register(&Loopbackusb_func);
424 if (ret)
425 return ret;
426 return ret;
427}
428void __exit lb_modexit(void)
429{
430 usb_function_unregister(&Loopbackusb_func);
431}
432
433MODULE_LICENSE("GPL");
diff --git a/drivers/usb/gadget/f_sourcesink.c b/drivers/usb/gadget/f_sourcesink.c
index f785cbd59688..41adf3ef96c2 100644
--- a/drivers/usb/gadget/f_sourcesink.c
+++ b/drivers/usb/gadget/f_sourcesink.c
@@ -16,11 +16,12 @@
16#include <linux/kernel.h> 16#include <linux/kernel.h>
17#include <linux/device.h> 17#include <linux/device.h>
18#include <linux/module.h> 18#include <linux/module.h>
19#include <linux/usb/composite.h>
20#include <linux/err.h>
19 21
20#include "g_zero.h" 22#include "g_zero.h"
21#include "gadget_chips.h" 23#include "gadget_chips.h"
22 24
23
24/* 25/*
25 * SOURCE/SINK FUNCTION ... a primary testing vehicle for USB peripheral 26 * SOURCE/SINK FUNCTION ... a primary testing vehicle for USB peripheral
26 * controller drivers. 27 * controller drivers.
@@ -62,24 +63,11 @@ static inline struct f_sourcesink *func_to_ss(struct usb_function *f)
62} 63}
63 64
64static unsigned pattern; 65static unsigned pattern;
65module_param(pattern, uint, S_IRUGO|S_IWUSR); 66static unsigned isoc_interval;
66MODULE_PARM_DESC(pattern, "0 = all zeroes, 1 = mod63, 2 = none"); 67static unsigned isoc_maxpacket;
67
68static unsigned isoc_interval = 4;
69module_param(isoc_interval, uint, S_IRUGO|S_IWUSR);
70MODULE_PARM_DESC(isoc_interval, "1 - 16");
71
72static unsigned isoc_maxpacket = 1024;
73module_param(isoc_maxpacket, uint, S_IRUGO|S_IWUSR);
74MODULE_PARM_DESC(isoc_maxpacket, "0 - 1023 (fs), 0 - 1024 (hs/ss)");
75
76static unsigned isoc_mult; 68static unsigned isoc_mult;
77module_param(isoc_mult, uint, S_IRUGO|S_IWUSR);
78MODULE_PARM_DESC(isoc_mult, "0 - 2 (hs/ss only)");
79
80static unsigned isoc_maxburst; 69static unsigned isoc_maxburst;
81module_param(isoc_maxburst, uint, S_IRUGO|S_IWUSR); 70static unsigned buflen;
82MODULE_PARM_DESC(isoc_maxburst, "0 - 15 (ss only)");
83 71
84/*-------------------------------------------------------------------------*/ 72/*-------------------------------------------------------------------------*/
85 73
@@ -313,7 +301,57 @@ static struct usb_gadget_strings *sourcesink_strings[] = {
313 301
314/*-------------------------------------------------------------------------*/ 302/*-------------------------------------------------------------------------*/
315 303
316static int __init 304struct usb_request *alloc_ep_req(struct usb_ep *ep, int len)
305{
306 struct usb_request *req;
307
308 req = usb_ep_alloc_request(ep, GFP_ATOMIC);
309 if (req) {
310 if (len)
311 req->length = len;
312 else
313 req->length = buflen;
314 req->buf = kmalloc(req->length, GFP_ATOMIC);
315 if (!req->buf) {
316 usb_ep_free_request(ep, req);
317 req = NULL;
318 }
319 }
320 return req;
321}
322
323void free_ep_req(struct usb_ep *ep, struct usb_request *req)
324{
325 kfree(req->buf);
326 usb_ep_free_request(ep, req);
327}
328
329static void disable_ep(struct usb_composite_dev *cdev, struct usb_ep *ep)
330{
331 int value;
332
333 if (ep->driver_data) {
334 value = usb_ep_disable(ep);
335 if (value < 0)
336 DBG(cdev, "disable %s --> %d\n",
337 ep->name, value);
338 ep->driver_data = NULL;
339 }
340}
341
342void disable_endpoints(struct usb_composite_dev *cdev,
343 struct usb_ep *in, struct usb_ep *out,
344 struct usb_ep *iso_in, struct usb_ep *iso_out)
345{
346 disable_ep(cdev, in);
347 disable_ep(cdev, out);
348 if (iso_in)
349 disable_ep(cdev, iso_in);
350 if (iso_out)
351 disable_ep(cdev, iso_out);
352}
353
354static int
317sourcesink_bind(struct usb_configuration *c, struct usb_function *f) 355sourcesink_bind(struct usb_configuration *c, struct usb_function *f)
318{ 356{
319 struct usb_composite_dev *cdev = c->cdev; 357 struct usb_composite_dev *cdev = c->cdev;
@@ -328,14 +366,6 @@ sourcesink_bind(struct usb_configuration *c, struct usb_function *f)
328 source_sink_intf_alt0.bInterfaceNumber = id; 366 source_sink_intf_alt0.bInterfaceNumber = id;
329 source_sink_intf_alt1.bInterfaceNumber = id; 367 source_sink_intf_alt1.bInterfaceNumber = id;
330 368
331 /* allocate string ID(s) */
332 id = usb_string_id(cdev);
333 if (id < 0)
334 return id;
335 strings_sourcesink[0].id = id;
336 source_sink_intf_alt0.iInterface = id;
337 source_sink_intf_alt1.iInterface = id;
338
339 /* allocate bulk endpoints */ 369 /* allocate bulk endpoints */
340 ss->in_ep = usb_ep_autoconfig(cdev->gadget, &fs_source_desc); 370 ss->in_ep = usb_ep_autoconfig(cdev->gadget, &fs_source_desc);
341 if (!ss->in_ep) { 371 if (!ss->in_ep) {
@@ -457,14 +487,11 @@ no_iso:
457 return 0; 487 return 0;
458} 488}
459 489
460static struct usb_function *global_ss_func;
461
462static void 490static void
463sourcesink_unbind(struct usb_configuration *c, struct usb_function *f) 491sourcesink_free_func(struct usb_function *f)
464{ 492{
465 usb_free_all_descriptors(f); 493 usb_free_all_descriptors(f);
466 kfree(func_to_ss(f)); 494 kfree(func_to_ss(f));
467 global_ss_func = NULL;
468} 495}
469 496
470/* optionally require specific source/sink data patterns */ 497/* optionally require specific source/sink data patterns */
@@ -767,6 +794,7 @@ static void sourcesink_disable(struct usb_function *f)
767} 794}
768 795
769/*-------------------------------------------------------------------------*/ 796/*-------------------------------------------------------------------------*/
797
770static int sourcesink_setup(struct usb_function *f, 798static int sourcesink_setup(struct usb_function *f,
771 const struct usb_ctrlrequest *ctrl) 799 const struct usb_ctrlrequest *ctrl)
772{ 800{
@@ -839,41 +867,76 @@ unknown:
839 return value; 867 return value;
840} 868}
841 869
842static int __init sourcesink_bind_config(struct usb_configuration *c) 870static struct usb_function *source_sink_alloc_func(
871 struct usb_function_instance *fi)
843{ 872{
844 struct f_sourcesink *ss; 873 struct f_sourcesink *ss;
845 int status; 874 struct f_ss_opts *ss_opts;
846 875
847 ss = kzalloc(sizeof(*ss), GFP_KERNEL); 876 ss = kzalloc(sizeof(*ss), GFP_KERNEL);
848 if (!ss) 877 if (!ss)
849 return -ENOMEM; 878 return NULL;
850 879
851 global_ss_func = &ss->function; 880 ss_opts = container_of(fi, struct f_ss_opts, func_inst);
881 pattern = ss_opts->pattern;
882 isoc_interval = ss_opts->isoc_interval;
883 isoc_maxpacket = ss_opts->isoc_maxpacket;
884 isoc_mult = ss_opts->isoc_mult;
885 isoc_maxburst = ss_opts->isoc_maxburst;
886 buflen = ss_opts->bulk_buflen;
852 887
853 ss->function.name = "source/sink"; 888 ss->function.name = "source/sink";
854 ss->function.bind = sourcesink_bind; 889 ss->function.bind = sourcesink_bind;
855 ss->function.unbind = sourcesink_unbind;
856 ss->function.set_alt = sourcesink_set_alt; 890 ss->function.set_alt = sourcesink_set_alt;
857 ss->function.get_alt = sourcesink_get_alt; 891 ss->function.get_alt = sourcesink_get_alt;
858 ss->function.disable = sourcesink_disable; 892 ss->function.disable = sourcesink_disable;
859 ss->function.setup = sourcesink_setup; 893 ss->function.setup = sourcesink_setup;
894 ss->function.strings = sourcesink_strings;
860 895
861 status = usb_add_function(c, &ss->function); 896 ss->function.free_func = sourcesink_free_func;
862 if (status) 897
863 kfree(ss); 898 return &ss->function;
864 return status;
865} 899}
866 900
867static int ss_config_setup(struct usb_configuration *c, 901static void acm_free_instance(struct usb_function_instance *fi)
868 const struct usb_ctrlrequest *ctrl)
869{ 902{
870 if (!global_ss_func) 903 struct f_ss_opts *ss_opts;
871 return -EOPNOTSUPP; 904
872 switch (ctrl->bRequest) { 905 ss_opts = container_of(fi, struct f_ss_opts, func_inst);
873 case 0x5b: 906 kfree(ss_opts);
874 case 0x5c:
875 return global_ss_func->setup(global_ss_func, ctrl);
876 default:
877 return -EOPNOTSUPP;
878 }
879} 907}
908
909static struct usb_function_instance *source_sink_alloc_inst(void)
910{
911 struct f_ss_opts *ss_opts;
912
913 ss_opts = kzalloc(sizeof(*ss_opts), GFP_KERNEL);
914 if (!ss_opts)
915 return ERR_PTR(-ENOMEM);
916 ss_opts->func_inst.free_func_inst = acm_free_instance;
917 return &ss_opts->func_inst;
918}
919DECLARE_USB_FUNCTION(SourceSink, source_sink_alloc_inst,
920 source_sink_alloc_func);
921
922static int __init sslb_modinit(void)
923{
924 int ret;
925
926 ret = usb_function_register(&SourceSinkusb_func);
927 if (ret)
928 return ret;
929 ret = lb_modinit();
930 if (ret)
931 usb_function_unregister(&SourceSinkusb_func);
932 return ret;
933}
934static void __exit sslb_modexit(void)
935{
936 usb_function_unregister(&SourceSinkusb_func);
937 lb_modexit();
938}
939module_init(sslb_modinit);
940module_exit(sslb_modexit);
941
942MODULE_LICENSE("GPL");
diff --git a/drivers/usb/gadget/g_zero.h b/drivers/usb/gadget/g_zero.h
index 281239c4e544..ef3e8515272b 100644
--- a/drivers/usb/gadget/g_zero.h
+++ b/drivers/usb/gadget/g_zero.h
@@ -6,11 +6,34 @@
6#ifndef __G_ZERO_H 6#ifndef __G_ZERO_H
7#define __G_ZERO_H 7#define __G_ZERO_H
8 8
9#include <linux/usb/composite.h> 9struct usb_zero_options {
10 unsigned pattern;
11 unsigned isoc_interval;
12 unsigned isoc_maxpacket;
13 unsigned isoc_mult;
14 unsigned isoc_maxburst;
15 unsigned bulk_buflen;
16 unsigned qlen;
17};
10 18
11/* global state */ 19struct f_ss_opts {
12extern unsigned buflen; 20 struct usb_function_instance func_inst;
13extern const struct usb_descriptor_header *otg_desc[]; 21 unsigned pattern;
22 unsigned isoc_interval;
23 unsigned isoc_maxpacket;
24 unsigned isoc_mult;
25 unsigned isoc_maxburst;
26 unsigned bulk_buflen;
27};
28
29struct f_lb_opts {
30 struct usb_function_instance func_inst;
31 unsigned bulk_buflen;
32 unsigned qlen;
33};
34
35void lb_modexit(void);
36int lb_modinit(void);
14 37
15/* common utilities */ 38/* common utilities */
16struct usb_request *alloc_ep_req(struct usb_ep *ep, int len); 39struct usb_request *alloc_ep_req(struct usb_ep *ep, int len);
diff --git a/drivers/usb/gadget/zero.c b/drivers/usb/gadget/zero.c
index 8ba0bee4e6c0..a331ab13f1e5 100644
--- a/drivers/usb/gadget/zero.c
+++ b/drivers/usb/gadget/zero.c
@@ -10,7 +10,6 @@
10 * (at your option) any later version. 10 * (at your option) any later version.
11 */ 11 */
12 12
13
14/* 13/*
15 * Gadget Zero only needs two bulk endpoints, and is an example of how you 14 * Gadget Zero only needs two bulk endpoints, and is an example of how you
16 * can write a hardware-agnostic gadget driver running inside a USB device. 15 * can write a hardware-agnostic gadget driver running inside a USB device.
@@ -43,23 +42,11 @@
43#include <linux/kernel.h> 42#include <linux/kernel.h>
44#include <linux/slab.h> 43#include <linux/slab.h>
45#include <linux/device.h> 44#include <linux/device.h>
45#include <linux/module.h>
46#include <linux/err.h>
47#include <linux/usb/composite.h>
46 48
47#include "g_zero.h" 49#include "g_zero.h"
48#include "gadget_chips.h"
49
50
51/*-------------------------------------------------------------------------*/
52
53/*
54 * Kbuild is not very cooperative with respect to linking separately
55 * compiled library objects into one module. So for now we won't use
56 * separate compilation ... ensuring init/exit sections work to shrink
57 * the runtime footprint, and giving us at least some parts of what
58 * a "gcc --combine ... part1.c part2.c part3.c ... " build would.
59 */
60#include "f_sourcesink.c"
61#include "f_loopback.c"
62
63/*-------------------------------------------------------------------------*/ 50/*-------------------------------------------------------------------------*/
64USB_GADGET_COMPOSITE_OPTIONS(); 51USB_GADGET_COMPOSITE_OPTIONS();
65 52
@@ -67,9 +54,6 @@ USB_GADGET_COMPOSITE_OPTIONS();
67 54
68static const char longname[] = "Gadget Zero"; 55static const char longname[] = "Gadget Zero";
69 56
70unsigned buflen = 4096; /* only used for bulk endpoints */
71module_param(buflen, uint, 0);
72
73/* 57/*
74 * Normally the "loopback" configuration is second (index 1) so 58 * Normally the "loopback" configuration is second (index 1) so
75 * it's not the default. Here's where to change that order, to 59 * it's not the default. Here's where to change that order, to
@@ -79,6 +63,13 @@ module_param(buflen, uint, 0);
79static bool loopdefault = 0; 63static bool loopdefault = 0;
80module_param(loopdefault, bool, S_IRUGO|S_IWUSR); 64module_param(loopdefault, bool, S_IRUGO|S_IWUSR);
81 65
66struct usb_zero_options gzero_options = {
67 .isoc_interval = 4,
68 .isoc_maxpacket = 1024,
69 .bulk_buflen = 4096,
70 .qlen = 32,
71};
72
82/*-------------------------------------------------------------------------*/ 73/*-------------------------------------------------------------------------*/
83 74
84/* Thanks to NetChip Technologies for donating this product ID. 75/* Thanks to NetChip Technologies for donating this product ID.
@@ -129,10 +120,12 @@ static struct usb_otg_descriptor otg_descriptor = {
129 .bmAttributes = USB_OTG_SRP | USB_OTG_HNP, 120 .bmAttributes = USB_OTG_SRP | USB_OTG_HNP,
130}; 121};
131 122
132const struct usb_descriptor_header *otg_desc[] = { 123static const struct usb_descriptor_header *otg_desc[] = {
133 (struct usb_descriptor_header *) &otg_descriptor, 124 (struct usb_descriptor_header *) &otg_descriptor,
134 NULL, 125 NULL,
135}; 126};
127#else
128#define otg_desc NULL
136#endif 129#endif
137 130
138/* string IDs are assigned dynamically */ 131/* string IDs are assigned dynamically */
@@ -163,58 +156,6 @@ static struct usb_gadget_strings *dev_strings[] = {
163 156
164/*-------------------------------------------------------------------------*/ 157/*-------------------------------------------------------------------------*/
165 158
166struct usb_request *alloc_ep_req(struct usb_ep *ep, int len)
167{
168 struct usb_request *req;
169
170 req = usb_ep_alloc_request(ep, GFP_ATOMIC);
171 if (req) {
172 if (len)
173 req->length = len;
174 else
175 req->length = buflen;
176 req->buf = kmalloc(req->length, GFP_ATOMIC);
177 if (!req->buf) {
178 usb_ep_free_request(ep, req);
179 req = NULL;
180 }
181 }
182 return req;
183}
184
185void free_ep_req(struct usb_ep *ep, struct usb_request *req)
186{
187 kfree(req->buf);
188 usb_ep_free_request(ep, req);
189}
190
191static void disable_ep(struct usb_composite_dev *cdev, struct usb_ep *ep)
192{
193 int value;
194
195 if (ep->driver_data) {
196 value = usb_ep_disable(ep);
197 if (value < 0)
198 DBG(cdev, "disable %s --> %d\n",
199 ep->name, value);
200 ep->driver_data = NULL;
201 }
202}
203
204void disable_endpoints(struct usb_composite_dev *cdev,
205 struct usb_ep *in, struct usb_ep *out,
206 struct usb_ep *iso_in, struct usb_ep *iso_out)
207{
208 disable_ep(cdev, in);
209 disable_ep(cdev, out);
210 if (iso_in)
211 disable_ep(cdev, iso_in);
212 if (iso_out)
213 disable_ep(cdev, iso_out);
214}
215
216/*-------------------------------------------------------------------------*/
217
218static struct timer_list autoresume_timer; 159static struct timer_list autoresume_timer;
219 160
220static void zero_autoresume(unsigned long _c) 161static void zero_autoresume(unsigned long _c)
@@ -258,23 +199,63 @@ static void zero_resume(struct usb_composite_dev *cdev)
258 199
259static struct usb_configuration loopback_driver = { 200static struct usb_configuration loopback_driver = {
260 .label = "loopback", 201 .label = "loopback",
261 .strings = loopback_strings,
262 .bConfigurationValue = 2, 202 .bConfigurationValue = 2,
263 .bmAttributes = USB_CONFIG_ATT_SELFPOWER, 203 .bmAttributes = USB_CONFIG_ATT_SELFPOWER,
264 /* .iConfiguration = DYNAMIC */ 204 /* .iConfiguration = DYNAMIC */
265}; 205};
266 206
207static struct usb_function *func_ss;
208static struct usb_function_instance *func_inst_ss;
209
210static int ss_config_setup(struct usb_configuration *c,
211 const struct usb_ctrlrequest *ctrl)
212{
213 switch (ctrl->bRequest) {
214 case 0x5b:
215 case 0x5c:
216 return func_ss->setup(func_ss, ctrl);
217 default:
218 return -EOPNOTSUPP;
219 }
220}
221
267static struct usb_configuration sourcesink_driver = { 222static struct usb_configuration sourcesink_driver = {
268 .label = "source/sink", 223 .label = "source/sink",
269 .strings = sourcesink_strings,
270 .setup = ss_config_setup, 224 .setup = ss_config_setup,
271 .bConfigurationValue = 3, 225 .bConfigurationValue = 3,
272 .bmAttributes = USB_CONFIG_ATT_SELFPOWER, 226 .bmAttributes = USB_CONFIG_ATT_SELFPOWER,
273 /* .iConfiguration = DYNAMIC */ 227 /* .iConfiguration = DYNAMIC */
274}; 228};
275 229
230module_param_named(buflen, gzero_options.bulk_buflen, uint, 0);
231module_param_named(pattern, gzero_options.pattern, uint, S_IRUGO|S_IWUSR);
232MODULE_PARM_DESC(pattern, "0 = all zeroes, 1 = mod63, 2 = none");
233
234module_param_named(isoc_interval, gzero_options.isoc_interval, uint,
235 S_IRUGO|S_IWUSR);
236MODULE_PARM_DESC(isoc_interval, "1 - 16");
237
238module_param_named(isoc_maxpacket, gzero_options.isoc_maxpacket, uint,
239 S_IRUGO|S_IWUSR);
240MODULE_PARM_DESC(isoc_maxpacket, "0 - 1023 (fs), 0 - 1024 (hs/ss)");
241
242module_param_named(isoc_mult, gzero_options.isoc_mult, uint, S_IRUGO|S_IWUSR);
243MODULE_PARM_DESC(isoc_mult, "0 - 2 (hs/ss only)");
244
245module_param_named(isoc_maxburst, gzero_options.isoc_maxburst, uint,
246 S_IRUGO|S_IWUSR);
247MODULE_PARM_DESC(isoc_maxburst, "0 - 15 (ss only)");
248
249static struct usb_function *func_lb;
250static struct usb_function_instance *func_inst_lb;
251
252module_param_named(qlen, gzero_options.qlen, uint, S_IRUGO|S_IWUSR);
253MODULE_PARM_DESC(qlen, "depth of loopback queue");
254
276static int __init zero_bind(struct usb_composite_dev *cdev) 255static int __init zero_bind(struct usb_composite_dev *cdev)
277{ 256{
257 struct f_ss_opts *ss_opts;
258 struct f_lb_opts *lb_opts;
278 int status; 259 int status;
279 260
280 /* Allocate string descriptor numbers ... note that string 261 /* Allocate string descriptor numbers ... note that string
@@ -290,6 +271,36 @@ static int __init zero_bind(struct usb_composite_dev *cdev)
290 271
291 setup_timer(&autoresume_timer, zero_autoresume, (unsigned long) cdev); 272 setup_timer(&autoresume_timer, zero_autoresume, (unsigned long) cdev);
292 273
274 func_inst_ss = usb_get_function_instance("SourceSink");
275 if (IS_ERR(func_inst_ss))
276 return PTR_ERR(func_inst_ss);
277
278 ss_opts = container_of(func_inst_ss, struct f_ss_opts, func_inst);
279 ss_opts->pattern = gzero_options.pattern;
280 ss_opts->isoc_interval = gzero_options.isoc_interval;
281 ss_opts->isoc_maxpacket = gzero_options.isoc_maxpacket;
282 ss_opts->isoc_mult = gzero_options.isoc_mult;
283 ss_opts->isoc_maxburst = gzero_options.isoc_maxpacket;
284 ss_opts->bulk_buflen = gzero_options.bulk_buflen;
285
286 func_ss = usb_get_function(func_inst_ss);
287 if (IS_ERR(func_ss))
288 goto err_put_func_inst_ss;
289
290 func_inst_lb = usb_get_function_instance("Loopback");
291 if (IS_ERR(func_inst_lb))
292 goto err_put_func_ss;
293
294 lb_opts = container_of(func_inst_lb, struct f_lb_opts, func_inst);
295 lb_opts->bulk_buflen = gzero_options.bulk_buflen;
296 lb_opts->qlen = gzero_options.qlen;
297
298 func_lb = usb_get_function(func_inst_lb);
299 if (IS_ERR(func_lb)) {
300 status = PTR_ERR(func_lb);
301 goto err_put_func_inst_lb;
302 }
303
293 sourcesink_driver.iConfiguration = strings_dev[USB_GZERO_SS_DESC].id; 304 sourcesink_driver.iConfiguration = strings_dev[USB_GZERO_SS_DESC].id;
294 loopback_driver.iConfiguration = strings_dev[USB_GZERO_LB_DESC].id; 305 loopback_driver.iConfiguration = strings_dev[USB_GZERO_LB_DESC].id;
295 306
@@ -315,25 +326,50 @@ static int __init zero_bind(struct usb_composite_dev *cdev)
315 * SH3 only allows one config... 326 * SH3 only allows one config...
316 */ 327 */
317 if (loopdefault) { 328 if (loopdefault) {
318 usb_add_config(cdev, &loopback_driver, loopback_bind_config); 329 usb_add_config_only(cdev, &loopback_driver);
319 usb_add_config(cdev, &sourcesink_driver, 330 usb_add_config_only(cdev, &sourcesink_driver);
320 sourcesink_bind_config);
321 } else { 331 } else {
322 usb_add_config(cdev, &sourcesink_driver, 332 usb_add_config_only(cdev, &sourcesink_driver);
323 sourcesink_bind_config); 333 usb_add_config_only(cdev, &loopback_driver);
324 usb_add_config(cdev, &loopback_driver, loopback_bind_config);
325 } 334 }
335 status = usb_add_function(&sourcesink_driver, func_ss);
336 if (status)
337 goto err_conf_flb;
326 338
339 usb_ep_autoconfig_reset(cdev->gadget);
340 status = usb_add_function(&loopback_driver, func_lb);
341 if (status)
342 goto err_conf_flb;
343
344 usb_ep_autoconfig_reset(cdev->gadget);
327 usb_composite_overwrite_options(cdev, &coverwrite); 345 usb_composite_overwrite_options(cdev, &coverwrite);
328 346
329 INFO(cdev, "%s, version: " DRIVER_VERSION "\n", longname); 347 INFO(cdev, "%s, version: " DRIVER_VERSION "\n", longname);
330 348
331 return 0; 349 return 0;
350
351err_conf_flb:
352 usb_put_function(func_lb);
353 func_lb = NULL;
354err_put_func_inst_lb:
355 usb_put_function_instance(func_inst_lb);
356 func_inst_lb = NULL;
357err_put_func_ss:
358 usb_put_function(func_ss);
359 func_ss = NULL;
360err_put_func_inst_ss:
361 usb_put_function_instance(func_inst_ss);
362 func_inst_ss = NULL;
363 return status;
332} 364}
333 365
334static int zero_unbind(struct usb_composite_dev *cdev) 366static int zero_unbind(struct usb_composite_dev *cdev)
335{ 367{
336 del_timer_sync(&autoresume_timer); 368 del_timer_sync(&autoresume_timer);
369 if (!IS_ERR_OR_NULL(func_ss))
370 usb_put_function(func_ss);
371 if (!IS_ERR_OR_NULL(func_lb))
372 usb_put_function(func_lb);
337 return 0; 373 return 0;
338} 374}
339 375