aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/gadget/f_eem.c
diff options
context:
space:
mode:
authorAndrzej Pietrasiewicz <andrzej.p@samsung.com>2013-05-28 03:15:47 -0400
committerFelipe Balbi <balbi@ti.com>2013-06-10 10:57:46 -0400
commitb29002a157940752dfed2c488b2011f63f007d71 (patch)
treeca07b354cfb93af8a19613669ce32629a94869f9 /drivers/usb/gadget/f_eem.c
parent9c62ce83e4258bacc459faf57bf2ed83cce6be08 (diff)
usb: gadget: f_eem: convert to new function interface with backward compatibility
Converting eem to the new function interface requires converting the USB eem's function code and its users. This patch converts the f_eem.c to the new function interface. The file is now compiled into a separate usb_f_eem.ko module. The old function interface is provided by means of a preprocessor conditional directives. After all users are converted, the old interface can be removed. Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com> Signed-off-by: Felipe Balbi <balbi@ti.com>
Diffstat (limited to 'drivers/usb/gadget/f_eem.c')
-rw-r--r--drivers/usb/gadget/f_eem.c174
1 files changed, 138 insertions, 36 deletions
diff --git a/drivers/usb/gadget/f_eem.c b/drivers/usb/gadget/f_eem.c
index f4e0bbef602a..471acc824115 100644
--- a/drivers/usb/gadget/f_eem.c
+++ b/drivers/usb/gadget/f_eem.c
@@ -12,12 +12,14 @@
12 */ 12 */
13 13
14#include <linux/kernel.h> 14#include <linux/kernel.h>
15#include <linux/module.h>
15#include <linux/device.h> 16#include <linux/device.h>
16#include <linux/etherdevice.h> 17#include <linux/etherdevice.h>
17#include <linux/crc32.h> 18#include <linux/crc32.h>
18#include <linux/slab.h> 19#include <linux/slab.h>
19 20
20#include "u_ether.h" 21#include "u_ether.h"
22#include "u_eem.h"
21 23
22#define EEM_HLEN 2 24#define EEM_HLEN 2
23 25
@@ -40,7 +42,7 @@ static inline struct f_eem *func_to_eem(struct usb_function *f)
40 42
41/* interface descriptor: */ 43/* interface descriptor: */
42 44
43static struct usb_interface_descriptor eem_intf __initdata = { 45static struct usb_interface_descriptor eem_intf = {
44 .bLength = sizeof eem_intf, 46 .bLength = sizeof eem_intf,
45 .bDescriptorType = USB_DT_INTERFACE, 47 .bDescriptorType = USB_DT_INTERFACE,
46 48
@@ -54,7 +56,7 @@ static struct usb_interface_descriptor eem_intf __initdata = {
54 56
55/* full speed support: */ 57/* full speed support: */
56 58
57static struct usb_endpoint_descriptor eem_fs_in_desc __initdata = { 59static struct usb_endpoint_descriptor eem_fs_in_desc = {
58 .bLength = USB_DT_ENDPOINT_SIZE, 60 .bLength = USB_DT_ENDPOINT_SIZE,
59 .bDescriptorType = USB_DT_ENDPOINT, 61 .bDescriptorType = USB_DT_ENDPOINT,
60 62
@@ -62,7 +64,7 @@ static struct usb_endpoint_descriptor eem_fs_in_desc __initdata = {
62 .bmAttributes = USB_ENDPOINT_XFER_BULK, 64 .bmAttributes = USB_ENDPOINT_XFER_BULK,
63}; 65};
64 66
65static struct usb_endpoint_descriptor eem_fs_out_desc __initdata = { 67static struct usb_endpoint_descriptor eem_fs_out_desc = {
66 .bLength = USB_DT_ENDPOINT_SIZE, 68 .bLength = USB_DT_ENDPOINT_SIZE,
67 .bDescriptorType = USB_DT_ENDPOINT, 69 .bDescriptorType = USB_DT_ENDPOINT,
68 70
@@ -70,7 +72,7 @@ static struct usb_endpoint_descriptor eem_fs_out_desc __initdata = {
70 .bmAttributes = USB_ENDPOINT_XFER_BULK, 72 .bmAttributes = USB_ENDPOINT_XFER_BULK,
71}; 73};
72 74
73static struct usb_descriptor_header *eem_fs_function[] __initdata = { 75static struct usb_descriptor_header *eem_fs_function[] = {
74 /* CDC EEM control descriptors */ 76 /* CDC EEM control descriptors */
75 (struct usb_descriptor_header *) &eem_intf, 77 (struct usb_descriptor_header *) &eem_intf,
76 (struct usb_descriptor_header *) &eem_fs_in_desc, 78 (struct usb_descriptor_header *) &eem_fs_in_desc,
@@ -80,7 +82,7 @@ static struct usb_descriptor_header *eem_fs_function[] __initdata = {
80 82
81/* high speed support: */ 83/* high speed support: */
82 84
83static struct usb_endpoint_descriptor eem_hs_in_desc __initdata = { 85static struct usb_endpoint_descriptor eem_hs_in_desc = {
84 .bLength = USB_DT_ENDPOINT_SIZE, 86 .bLength = USB_DT_ENDPOINT_SIZE,
85 .bDescriptorType = USB_DT_ENDPOINT, 87 .bDescriptorType = USB_DT_ENDPOINT,
86 88
@@ -89,7 +91,7 @@ static struct usb_endpoint_descriptor eem_hs_in_desc __initdata = {
89 .wMaxPacketSize = cpu_to_le16(512), 91 .wMaxPacketSize = cpu_to_le16(512),
90}; 92};
91 93
92static struct usb_endpoint_descriptor eem_hs_out_desc __initdata = { 94static struct usb_endpoint_descriptor eem_hs_out_desc = {
93 .bLength = USB_DT_ENDPOINT_SIZE, 95 .bLength = USB_DT_ENDPOINT_SIZE,
94 .bDescriptorType = USB_DT_ENDPOINT, 96 .bDescriptorType = USB_DT_ENDPOINT,
95 97
@@ -98,7 +100,7 @@ static struct usb_endpoint_descriptor eem_hs_out_desc __initdata = {
98 .wMaxPacketSize = cpu_to_le16(512), 100 .wMaxPacketSize = cpu_to_le16(512),
99}; 101};
100 102
101static struct usb_descriptor_header *eem_hs_function[] __initdata = { 103static struct usb_descriptor_header *eem_hs_function[] = {
102 /* CDC EEM control descriptors */ 104 /* CDC EEM control descriptors */
103 (struct usb_descriptor_header *) &eem_intf, 105 (struct usb_descriptor_header *) &eem_intf,
104 (struct usb_descriptor_header *) &eem_hs_in_desc, 106 (struct usb_descriptor_header *) &eem_hs_in_desc,
@@ -108,7 +110,7 @@ static struct usb_descriptor_header *eem_hs_function[] __initdata = {
108 110
109/* super speed support: */ 111/* super speed support: */
110 112
111static struct usb_endpoint_descriptor eem_ss_in_desc __initdata = { 113static struct usb_endpoint_descriptor eem_ss_in_desc = {
112 .bLength = USB_DT_ENDPOINT_SIZE, 114 .bLength = USB_DT_ENDPOINT_SIZE,
113 .bDescriptorType = USB_DT_ENDPOINT, 115 .bDescriptorType = USB_DT_ENDPOINT,
114 116
@@ -117,7 +119,7 @@ static struct usb_endpoint_descriptor eem_ss_in_desc __initdata = {
117 .wMaxPacketSize = cpu_to_le16(1024), 119 .wMaxPacketSize = cpu_to_le16(1024),
118}; 120};
119 121
120static struct usb_endpoint_descriptor eem_ss_out_desc __initdata = { 122static struct usb_endpoint_descriptor eem_ss_out_desc = {
121 .bLength = USB_DT_ENDPOINT_SIZE, 123 .bLength = USB_DT_ENDPOINT_SIZE,
122 .bDescriptorType = USB_DT_ENDPOINT, 124 .bDescriptorType = USB_DT_ENDPOINT,
123 125
@@ -126,7 +128,7 @@ static struct usb_endpoint_descriptor eem_ss_out_desc __initdata = {
126 .wMaxPacketSize = cpu_to_le16(1024), 128 .wMaxPacketSize = cpu_to_le16(1024),
127}; 129};
128 130
129static struct usb_ss_ep_comp_descriptor eem_ss_bulk_comp_desc __initdata = { 131static struct usb_ss_ep_comp_descriptor eem_ss_bulk_comp_desc = {
130 .bLength = sizeof eem_ss_bulk_comp_desc, 132 .bLength = sizeof eem_ss_bulk_comp_desc,
131 .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, 133 .bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
132 134
@@ -135,7 +137,7 @@ static struct usb_ss_ep_comp_descriptor eem_ss_bulk_comp_desc __initdata = {
135 /* .bmAttributes = 0, */ 137 /* .bmAttributes = 0, */
136}; 138};
137 139
138static struct usb_descriptor_header *eem_ss_function[] __initdata = { 140static struct usb_descriptor_header *eem_ss_function[] = {
139 /* CDC EEM control descriptors */ 141 /* CDC EEM control descriptors */
140 (struct usb_descriptor_header *) &eem_intf, 142 (struct usb_descriptor_header *) &eem_intf,
141 (struct usb_descriptor_header *) &eem_ss_in_desc, 143 (struct usb_descriptor_header *) &eem_ss_in_desc,
@@ -242,14 +244,44 @@ static void eem_disable(struct usb_function *f)
242 244
243/* EEM function driver setup/binding */ 245/* EEM function driver setup/binding */
244 246
245static int __init 247static int eem_bind(struct usb_configuration *c, struct usb_function *f)
246eem_bind(struct usb_configuration *c, struct usb_function *f)
247{ 248{
248 struct usb_composite_dev *cdev = c->cdev; 249 struct usb_composite_dev *cdev = c->cdev;
249 struct f_eem *eem = func_to_eem(f); 250 struct f_eem *eem = func_to_eem(f);
250 int status; 251 int status;
251 struct usb_ep *ep; 252 struct usb_ep *ep;
252 253
254#ifndef USB_FEEM_INCLUDED
255 struct f_eem_opts *eem_opts;
256
257 eem_opts = container_of(f->fi, struct f_eem_opts, func_inst);
258 /*
259 * in drivers/usb/gadget/configfs.c:configfs_composite_bind()
260 * configurations are bound in sequence with list_for_each_entry,
261 * in each configuration its functions are bound in sequence
262 * with list_for_each_entry, so we assume no race condition
263 * with regard to eem_opts->bound access
264 */
265 if (!eem_opts->bound) {
266 gether_set_gadget(eem_opts->net, cdev->gadget);
267 status = gether_register_netdev(eem_opts->net);
268 if (status)
269 return status;
270 eem_opts->bound = true;
271 }
272#endif
273
274 /* maybe allocate device-global string IDs */
275 if (eem_string_defs[0].id == 0) {
276
277 /* control interface label */
278 status = usb_string_id(c->cdev);
279 if (status < 0)
280 return status;
281 eem_string_defs[0].id = status;
282 eem_intf.iInterface = status;
283 }
284
253 /* allocate instance-specific interface IDs */ 285 /* allocate instance-specific interface IDs */
254 status = usb_interface_id(c, f); 286 status = usb_interface_id(c, f);
255 if (status < 0) 287 if (status < 0)
@@ -307,17 +339,6 @@ fail:
307 return status; 339 return status;
308} 340}
309 341
310static void
311eem_unbind(struct usb_configuration *c, struct usb_function *f)
312{
313 struct f_eem *eem = func_to_eem(f);
314
315 DBG(c->cdev, "eem unbind\n");
316
317 usb_free_all_descriptors(f);
318 kfree(eem);
319}
320
321static void eem_cmd_complete(struct usb_ep *ep, struct usb_request *req) 342static void eem_cmd_complete(struct usb_ep *ep, struct usb_request *req)
322{ 343{
323 struct sk_buff *skb = (struct sk_buff *)req->context; 344 struct sk_buff *skb = (struct sk_buff *)req->context;
@@ -518,6 +539,18 @@ error:
518 return status; 539 return status;
519} 540}
520 541
542#ifdef USB_FEEM_INCLUDED
543
544static void eem_old_unbind(struct usb_configuration *c, struct usb_function *f)
545{
546 struct f_eem *eem = func_to_eem(f);
547
548 DBG(c->cdev, "eem unbind\n");
549
550 usb_free_all_descriptors(f);
551 kfree(eem);
552}
553
521/** 554/**
522 * eem_bind_config - add CDC Ethernet (EEM) network link to a configuration 555 * eem_bind_config - add CDC Ethernet (EEM) network link to a configuration
523 * @c: the configuration to support the network link 556 * @c: the configuration to support the network link
@@ -533,17 +566,6 @@ int __init eem_bind_config(struct usb_configuration *c, struct eth_dev *dev)
533 struct f_eem *eem; 566 struct f_eem *eem;
534 int status; 567 int status;
535 568
536 /* maybe allocate device-global string IDs */
537 if (eem_string_defs[0].id == 0) {
538
539 /* control interface label */
540 status = usb_string_id(c->cdev);
541 if (status < 0)
542 return status;
543 eem_string_defs[0].id = status;
544 eem_intf.iInterface = status;
545 }
546
547 /* allocate and initialize one new instance */ 569 /* allocate and initialize one new instance */
548 eem = kzalloc(sizeof *eem, GFP_KERNEL); 570 eem = kzalloc(sizeof *eem, GFP_KERNEL);
549 if (!eem) 571 if (!eem)
@@ -556,7 +578,7 @@ int __init eem_bind_config(struct usb_configuration *c, struct eth_dev *dev)
556 eem->port.func.strings = eem_strings; 578 eem->port.func.strings = eem_strings;
557 /* descriptors are per-instance copies */ 579 /* descriptors are per-instance copies */
558 eem->port.func.bind = eem_bind; 580 eem->port.func.bind = eem_bind;
559 eem->port.func.unbind = eem_unbind; 581 eem->port.func.unbind = eem_old_unbind;
560 eem->port.func.set_alt = eem_set_alt; 582 eem->port.func.set_alt = eem_set_alt;
561 eem->port.func.setup = eem_setup; 583 eem->port.func.setup = eem_setup;
562 eem->port.func.disable = eem_disable; 584 eem->port.func.disable = eem_disable;
@@ -570,3 +592,83 @@ int __init eem_bind_config(struct usb_configuration *c, struct eth_dev *dev)
570 return status; 592 return status;
571} 593}
572 594
595#else
596
597static void eem_free_inst(struct usb_function_instance *f)
598{
599 struct f_eem_opts *opts;
600
601 opts = container_of(f, struct f_eem_opts, func_inst);
602 if (opts->bound)
603 gether_cleanup(netdev_priv(opts->net));
604 else
605 free_netdev(opts->net);
606 kfree(opts);
607}
608
609static struct usb_function_instance *eem_alloc_inst(void)
610{
611 struct f_eem_opts *opts;
612
613 opts = kzalloc(sizeof(*opts), GFP_KERNEL);
614 if (!opts)
615 return ERR_PTR(-ENOMEM);
616 opts->func_inst.free_func_inst = eem_free_inst;
617 opts->net = gether_setup_default();
618 if (IS_ERR(opts->net))
619 return ERR_CAST(opts->net);
620
621 return &opts->func_inst;
622}
623
624static void eem_free(struct usb_function *f)
625{
626 struct f_eem *eem;
627
628 eem = func_to_eem(f);
629 kfree(eem);
630}
631
632static void eem_unbind(struct usb_configuration *c, struct usb_function *f)
633{
634 DBG(c->cdev, "eem unbind\n");
635
636 usb_free_all_descriptors(f);
637}
638
639struct usb_function *eem_alloc(struct usb_function_instance *fi)
640{
641 struct f_eem *eem;
642 struct f_eem_opts *opts;
643
644 /* allocate and initialize one new instance */
645 eem = kzalloc(sizeof(*eem), GFP_KERNEL);
646 if (!eem)
647 return ERR_PTR(-ENOMEM);
648
649 opts = container_of(fi, struct f_eem_opts, func_inst);
650
651 eem->port.ioport = netdev_priv(opts->net);
652 eem->port.cdc_filter = DEFAULT_FILTER;
653
654 eem->port.func.name = "cdc_eem";
655 eem->port.func.strings = eem_strings;
656 /* descriptors are per-instance copies */
657 eem->port.func.bind = eem_bind;
658 eem->port.func.unbind = eem_unbind;
659 eem->port.func.set_alt = eem_set_alt;
660 eem->port.func.setup = eem_setup;
661 eem->port.func.disable = eem_disable;
662 eem->port.func.free_func = eem_free;
663 eem->port.wrap = eem_wrap;
664 eem->port.unwrap = eem_unwrap;
665 eem->port.header_len = EEM_HLEN;
666
667 return &eem->port.func;
668}
669
670DECLARE_USB_FUNCTION_INIT(eem, eem_alloc_inst, eem_alloc);
671MODULE_LICENSE("GPL");
672MODULE_AUTHOR("David Brownell");
673
674#endif