aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/gadget/multi.c
diff options
context:
space:
mode:
authorAndrzej Pietrasiewicz <andrzej.p@samsung.com>2013-10-09 04:08:25 -0400
committerFelipe Balbi <balbi@ti.com>2013-10-10 11:24:39 -0400
commit7388901528411cbda3f5e0d121ae3797f4397ded (patch)
tree30e86109b40608d5deab969c72fc67a706984d8e /drivers/usb/gadget/multi.c
parente6c661ef18177f2f1ce32210140f8497851d9388 (diff)
usb: gadget: multi: convert to new interface of f_ecm
Convert the legacy multi gadget to the new interface of f_ecm, so that later the compatibility layer in f_ecm 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/multi.c')
-rw-r--r--drivers/usb/gadget/multi.c68
1 files changed, 60 insertions, 8 deletions
diff --git a/drivers/usb/gadget/multi.c b/drivers/usb/gadget/multi.c
index 42a5bed75388..7dd554481dd4 100644
--- a/drivers/usb/gadget/multi.c
+++ b/drivers/usb/gadget/multi.c
@@ -15,6 +15,7 @@
15 15
16#include <linux/kernel.h> 16#include <linux/kernel.h>
17#include <linux/module.h> 17#include <linux/module.h>
18#include <linux/netdevice.h>
18 19
19#include "u_serial.h" 20#include "u_serial.h"
20#if defined USB_ETH_RNDIS 21#if defined USB_ETH_RNDIS
@@ -44,8 +45,7 @@ MODULE_LICENSE("GPL");
44#define USB_FMS_INCLUDED 45#define USB_FMS_INCLUDED
45#include "f_mass_storage.c" 46#include "f_mass_storage.c"
46 47
47#define USBF_ECM_INCLUDED 48#include "u_ecm.h"
48#include "f_ecm.c"
49#ifdef USB_ETH_RNDIS 49#ifdef USB_ETH_RNDIS
50# define USB_FRNDIS_INCLUDED 50# define USB_FRNDIS_INCLUDED
51# include "f_rndis.c" 51# include "f_rndis.c"
@@ -151,14 +151,14 @@ FSG_MODULE_PARAMETERS(/* no prefix */, fsg_mod_data);
151 151
152static struct fsg_common fsg_common; 152static struct fsg_common fsg_common;
153 153
154static u8 host_mac[ETH_ALEN];
155
156static struct usb_function_instance *fi_acm; 154static struct usb_function_instance *fi_acm;
157static struct eth_dev *the_dev; 155static struct eth_dev *the_dev;
158 156
159/********** RNDIS **********/ 157/********** RNDIS **********/
160 158
161#ifdef USB_ETH_RNDIS 159#ifdef USB_ETH_RNDIS
160static u8 host_mac[ETH_ALEN];
161
162static struct usb_function *f_acm_rndis; 162static struct usb_function *f_acm_rndis;
163 163
164static __init int rndis_do_config(struct usb_configuration *c) 164static __init int rndis_do_config(struct usb_configuration *c)
@@ -220,7 +220,9 @@ static __ref int rndis_config_register(struct usb_composite_dev *cdev)
220/********** CDC ECM **********/ 220/********** CDC ECM **********/
221 221
222#ifdef CONFIG_USB_G_MULTI_CDC 222#ifdef CONFIG_USB_G_MULTI_CDC
223static struct usb_function_instance *fi_ecm;
223static struct usb_function *f_acm_multi; 224static struct usb_function *f_acm_multi;
225static struct usb_function *f_ecm;
224 226
225static __init int cdc_do_config(struct usb_configuration *c) 227static __init int cdc_do_config(struct usb_configuration *c)
226{ 228{
@@ -231,14 +233,20 @@ static __init int cdc_do_config(struct usb_configuration *c)
231 c->bmAttributes |= USB_CONFIG_ATT_WAKEUP; 233 c->bmAttributes |= USB_CONFIG_ATT_WAKEUP;
232 } 234 }
233 235
234 ret = ecm_bind_config(c, host_mac, the_dev); 236 f_ecm = usb_get_function(fi_ecm);
237 if (IS_ERR(f_ecm))
238 return PTR_ERR(f_ecm);
239
240 ret = usb_add_function(c, f_ecm);
235 if (ret < 0) 241 if (ret < 0)
236 return ret; 242 goto err_func_ecm;
237 243
238 /* implicit port_num is zero */ 244 /* implicit port_num is zero */
239 f_acm_multi = usb_get_function(fi_acm); 245 f_acm_multi = usb_get_function(fi_acm);
240 if (IS_ERR(f_acm_multi)) 246 if (IS_ERR(f_acm_multi)) {
241 return PTR_ERR(f_acm_multi); 247 ret = PTR_ERR(f_acm_multi);
248 goto err_func_acm;
249 }
242 250
243 ret = usb_add_function(c, f_acm_multi); 251 ret = usb_add_function(c, f_acm_multi);
244 if (ret) 252 if (ret)
@@ -253,6 +261,10 @@ err_fsg:
253 usb_remove_function(c, f_acm_multi); 261 usb_remove_function(c, f_acm_multi);
254err_conf: 262err_conf:
255 usb_put_function(f_acm_multi); 263 usb_put_function(f_acm_multi);
264err_func_acm:
265 usb_remove_function(c, f_ecm);
266err_func_ecm:
267 usb_put_function(f_ecm);
256 return ret; 268 return ret;
257} 269}
258 270
@@ -285,6 +297,9 @@ static __ref int cdc_config_register(struct usb_composite_dev *cdev)
285static int __ref multi_bind(struct usb_composite_dev *cdev) 297static int __ref multi_bind(struct usb_composite_dev *cdev)
286{ 298{
287 struct usb_gadget *gadget = cdev->gadget; 299 struct usb_gadget *gadget = cdev->gadget;
300#ifdef CONFIG_USB_G_MULTI_CDC
301 struct f_ecm_opts *ecm_opts;
302#endif
288 int status; 303 int status;
289 304
290 if (!can_support_ecm(cdev->gadget)) { 305 if (!can_support_ecm(cdev->gadget)) {
@@ -293,11 +308,39 @@ static int __ref multi_bind(struct usb_composite_dev *cdev)
293 return -EINVAL; 308 return -EINVAL;
294 } 309 }
295 310
311#ifdef CONFIG_USB_G_MULTI_CDC
312 fi_ecm = usb_get_function_instance("ecm");
313 if (IS_ERR(fi_ecm))
314 return PTR_ERR(fi_ecm);
315
316 ecm_opts = container_of(fi_ecm, struct f_ecm_opts, func_inst);
317
318 gether_set_qmult(ecm_opts->net, qmult);
319 if (!gether_set_host_addr(ecm_opts->net, host_addr))
320 pr_info("using host ethernet address: %s", host_addr);
321 if (!gether_set_dev_addr(ecm_opts->net, dev_addr))
322 pr_info("using self ethernet address: %s", dev_addr);
323
324 the_dev = netdev_priv(ecm_opts->net);
325
326#elif defined USB_ETH_RNDIS
327
296 /* set up network link layer */ 328 /* set up network link layer */
297 the_dev = gether_setup(cdev->gadget, dev_addr, host_addr, host_mac, 329 the_dev = gether_setup(cdev->gadget, dev_addr, host_addr, host_mac,
298 qmult); 330 qmult);
299 if (IS_ERR(the_dev)) 331 if (IS_ERR(the_dev))
300 return PTR_ERR(the_dev); 332 return PTR_ERR(the_dev);
333#endif
334
335#if (defined CONFIG_USB_G_MULTI_CDC && defined USB_ETH_RNDIS)
336 gether_set_gadget(ecm_opts->net, cdev->gadget);
337 status = gether_register_netdev(ecm_opts->net);
338 if (status)
339 goto fail0;
340 ecm_opts->bound = true;
341
342 gether_get_host_addr_u8(ecm_opts->net, host_mac);
343#endif
301 344
302 /* set up serial link layer */ 345 /* set up serial link layer */
303 fi_acm = usb_get_function_instance("acm"); 346 fi_acm = usb_get_function_instance("acm");
@@ -345,7 +388,11 @@ fail2:
345fail1: 388fail1:
346 usb_put_function_instance(fi_acm); 389 usb_put_function_instance(fi_acm);
347fail0: 390fail0:
391#ifdef CONFIG_USB_G_MULTI_CDC
392 usb_put_function_instance(fi_ecm);
393#else
348 gether_cleanup(the_dev); 394 gether_cleanup(the_dev);
395#endif
349 return status; 396 return status;
350} 397}
351 398
@@ -358,7 +405,12 @@ static int __exit multi_unbind(struct usb_composite_dev *cdev)
358 usb_put_function(f_acm_rndis); 405 usb_put_function(f_acm_rndis);
359#endif 406#endif
360 usb_put_function_instance(fi_acm); 407 usb_put_function_instance(fi_acm);
408#ifdef CONFIG_USB_G_MULTI_CDC
409 usb_put_function(f_ecm);
410 usb_put_function_instance(fi_ecm);
411#else
361 gether_cleanup(the_dev); 412 gether_cleanup(the_dev);
413#endif
362 return 0; 414 return 0;
363} 415}
364 416