aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/gadget/ncm.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/gadget/ncm.c')
-rw-r--r--drivers/usb/gadget/ncm.c58
1 files changed, 37 insertions, 21 deletions
diff --git a/drivers/usb/gadget/ncm.c b/drivers/usb/gadget/ncm.c
index 3b02fd4649ce..81956feca1bd 100644
--- a/drivers/usb/gadget/ncm.c
+++ b/drivers/usb/gadget/ncm.c
@@ -24,23 +24,12 @@
24#include <linux/usb/composite.h> 24#include <linux/usb/composite.h>
25 25
26#include "u_ether.h" 26#include "u_ether.h"
27#include "u_ncm.h"
27 28
28#define DRIVER_DESC "NCM Gadget" 29#define DRIVER_DESC "NCM Gadget"
29 30
30/*-------------------------------------------------------------------------*/ 31/*-------------------------------------------------------------------------*/
31 32
32/*
33 * Kbuild is not very cooperative with respect to linking separately
34 * compiled library objects into one module. So for now we won't use
35 * separate compilation ... ensuring init/exit sections work to shrink
36 * the runtime footprint, and giving us at least some parts of what
37 * a "gcc --combine ... part1.c part2.c part3.c ... " build would.
38 */
39#include "f_ncm.c"
40#include "u_ether.c"
41
42/*-------------------------------------------------------------------------*/
43
44/* DO NOT REUSE THESE IDs with a protocol-incompatible driver!! Ever!! 33/* DO NOT REUSE THESE IDs with a protocol-incompatible driver!! Ever!!
45 * Instead: allocate your own, using normal USB-IF procedures. 34 * Instead: allocate your own, using normal USB-IF procedures.
46 */ 35 */
@@ -54,6 +43,8 @@
54/*-------------------------------------------------------------------------*/ 43/*-------------------------------------------------------------------------*/
55USB_GADGET_COMPOSITE_OPTIONS(); 44USB_GADGET_COMPOSITE_OPTIONS();
56 45
46USB_ETHERNET_MODULE_PARAMETERS();
47
57static struct usb_device_descriptor device_desc = { 48static struct usb_device_descriptor device_desc = {
58 .bLength = sizeof device_desc, 49 .bLength = sizeof device_desc,
59 .bDescriptorType = USB_DT_DEVICE, 50 .bDescriptorType = USB_DT_DEVICE,
@@ -111,13 +102,15 @@ static struct usb_gadget_strings *dev_strings[] = {
111 NULL, 102 NULL,
112}; 103};
113 104
114struct eth_dev *the_dev; 105static struct usb_function_instance *f_ncm_inst;
115static u8 hostaddr[ETH_ALEN]; 106static struct usb_function *f_ncm;
116 107
117/*-------------------------------------------------------------------------*/ 108/*-------------------------------------------------------------------------*/
118 109
119static int __init ncm_do_config(struct usb_configuration *c) 110static int __init ncm_do_config(struct usb_configuration *c)
120{ 111{
112 int status;
113
121 /* FIXME alloc iConfiguration string, set it in c->strings */ 114 /* FIXME alloc iConfiguration string, set it in c->strings */
122 115
123 if (gadget_is_otg(c->cdev->gadget)) { 116 if (gadget_is_otg(c->cdev->gadget)) {
@@ -125,7 +118,19 @@ static int __init ncm_do_config(struct usb_configuration *c)
125 c->bmAttributes |= USB_CONFIG_ATT_WAKEUP; 118 c->bmAttributes |= USB_CONFIG_ATT_WAKEUP;
126 } 119 }
127 120
128 return ncm_bind_config(c, hostaddr, the_dev); 121 f_ncm = usb_get_function(f_ncm_inst);
122 if (IS_ERR(f_ncm)) {
123 status = PTR_ERR(f_ncm);
124 return status;
125 }
126
127 status = usb_add_function(c, f_ncm);
128 if (status < 0) {
129 usb_put_function(f_ncm);
130 return status;
131 }
132
133 return 0;
129} 134}
130 135
131static struct usb_configuration ncm_config_driver = { 136static struct usb_configuration ncm_config_driver = {
@@ -141,12 +146,20 @@ static struct usb_configuration ncm_config_driver = {
141static int __init gncm_bind(struct usb_composite_dev *cdev) 146static int __init gncm_bind(struct usb_composite_dev *cdev)
142{ 147{
143 struct usb_gadget *gadget = cdev->gadget; 148 struct usb_gadget *gadget = cdev->gadget;
149 struct f_ncm_opts *ncm_opts;
144 int status; 150 int status;
145 151
146 /* set up network link layer */ 152 f_ncm_inst = usb_get_function_instance("ncm");
147 the_dev = gether_setup(cdev->gadget, hostaddr); 153 if (IS_ERR(f_ncm_inst))
148 if (IS_ERR(the_dev)) 154 return PTR_ERR(f_ncm_inst);
149 return PTR_ERR(the_dev); 155
156 ncm_opts = container_of(f_ncm_inst, struct f_ncm_opts, func_inst);
157
158 gether_set_qmult(ncm_opts->net, qmult);
159 if (!gether_set_host_addr(ncm_opts->net, host_addr))
160 pr_info("using host ethernet address: %s", host_addr);
161 if (!gether_set_dev_addr(ncm_opts->net, dev_addr))
162 pr_info("using self ethernet address: %s", dev_addr);
150 163
151 /* Allocate string descriptor numbers ... note that string 164 /* Allocate string descriptor numbers ... note that string
152 * contents can be overridden by the composite_dev glue. 165 * contents can be overridden by the composite_dev glue.
@@ -169,13 +182,16 @@ static int __init gncm_bind(struct usb_composite_dev *cdev)
169 return 0; 182 return 0;
170 183
171fail: 184fail:
172 gether_cleanup(the_dev); 185 usb_put_function_instance(f_ncm_inst);
173 return status; 186 return status;
174} 187}
175 188
176static int __exit gncm_unbind(struct usb_composite_dev *cdev) 189static int __exit gncm_unbind(struct usb_composite_dev *cdev)
177{ 190{
178 gether_cleanup(the_dev); 191 if (!IS_ERR_OR_NULL(f_ncm))
192 usb_put_function(f_ncm);
193 if (!IS_ERR_OR_NULL(f_ncm_inst))
194 usb_put_function_instance(f_ncm_inst);
179 return 0; 195 return 0;
180} 196}
181 197