diff options
author | Andrzej Pietrasiewicz <andrzej.p@samsung.com> | 2013-10-09 10:08:26 +0200 |
---|---|---|
committer | Felipe Balbi <balbi@ti.com> | 2013-10-10 10:24:43 -0500 |
commit | 4d1a8f68b42d2a726e36bfe2f891496b4c6bdbbb (patch) | |
tree | dd220555877c4330721aed74ca73c66da9298aae /drivers/usb/gadget/multi.c | |
parent | 7388901528411cbda3f5e0d121ae3797f4397ded (diff) | |
download | op-kernel-dev-4d1a8f68b42d2a726e36bfe2f891496b4c6bdbbb.zip op-kernel-dev-4d1a8f68b42d2a726e36bfe2f891496b4c6bdbbb.tar.gz |
usb: gadget: multi: convert to new interface of f_rndis
Convert the legacy multi gadget to the new interface of f_rndis,
so that later the compatibility layer in f_rndis 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.c | 73 |
1 files changed, 50 insertions, 23 deletions
diff --git a/drivers/usb/gadget/multi.c b/drivers/usb/gadget/multi.c index 7dd554481..fceef0f 100644 --- a/drivers/usb/gadget/multi.c +++ b/drivers/usb/gadget/multi.c @@ -47,8 +47,7 @@ MODULE_LICENSE("GPL"); #include "u_ecm.h" #ifdef USB_ETH_RNDIS -# define USB_FRNDIS_INCLUDED -# include "f_rndis.c" +# include "u_rndis.h" # include "rndis.h" #endif #include "u_ether.h" @@ -152,14 +151,13 @@ FSG_MODULE_PARAMETERS(/* no prefix */, fsg_mod_data); static struct fsg_common fsg_common; static struct usb_function_instance *fi_acm; -static struct eth_dev *the_dev; /********** RNDIS **********/ #ifdef USB_ETH_RNDIS -static u8 host_mac[ETH_ALEN]; - +static struct usb_function_instance *fi_rndis; static struct usb_function *f_acm_rndis; +static struct usb_function *f_rndis; static __init int rndis_do_config(struct usb_configuration *c) { @@ -170,13 +168,19 @@ static __init int rndis_do_config(struct usb_configuration *c) c->bmAttributes |= USB_CONFIG_ATT_WAKEUP; } - ret = rndis_bind_config(c, host_mac, the_dev); + f_rndis = usb_get_function(fi_rndis); + if (IS_ERR(f_rndis)) + return PTR_ERR(f_rndis); + + ret = usb_add_function(c, f_rndis); if (ret < 0) - return ret; + goto err_func_rndis; f_acm_rndis = usb_get_function(fi_acm); - if (IS_ERR(f_acm_rndis)) - return PTR_ERR(f_acm_rndis); + if (IS_ERR(f_acm_rndis)) { + ret = PTR_ERR(f_acm_rndis); + goto err_func_acm; + } ret = usb_add_function(c, f_acm_rndis); if (ret) @@ -191,6 +195,10 @@ err_fsg: usb_remove_function(c, f_acm_rndis); err_conf: usb_put_function(f_acm_rndis); +err_func_acm: + usb_remove_function(c, f_rndis); +err_func_rndis: + usb_put_function(f_rndis); return ret; } @@ -300,11 +308,14 @@ static int __ref multi_bind(struct usb_composite_dev *cdev) #ifdef CONFIG_USB_G_MULTI_CDC struct f_ecm_opts *ecm_opts; #endif +#ifdef USB_ETH_RNDIS + struct f_rndis_opts *rndis_opts; +#endif int status; if (!can_support_ecm(cdev->gadget)) { dev_err(&gadget->dev, "controller '%s' not usable\n", - gadget->name); + gadget->name); return -EINVAL; } @@ -320,26 +331,38 @@ static int __ref multi_bind(struct usb_composite_dev *cdev) pr_info("using host ethernet address: %s", host_addr); if (!gether_set_dev_addr(ecm_opts->net, dev_addr)) pr_info("using self ethernet address: %s", dev_addr); +#endif - the_dev = netdev_priv(ecm_opts->net); +#ifdef USB_ETH_RNDIS + fi_rndis = usb_get_function_instance("rndis"); + if (IS_ERR(fi_rndis)) { + status = PTR_ERR(fi_rndis); + goto fail; + } -#elif defined USB_ETH_RNDIS + rndis_opts = container_of(fi_rndis, struct f_rndis_opts, func_inst); - /* set up network link layer */ - the_dev = gether_setup(cdev->gadget, dev_addr, host_addr, host_mac, - qmult); - if (IS_ERR(the_dev)) - return PTR_ERR(the_dev); + gether_set_qmult(rndis_opts->net, qmult); + if (!gether_set_host_addr(rndis_opts->net, host_addr)) + pr_info("using host ethernet address: %s", host_addr); + if (!gether_set_dev_addr(rndis_opts->net, dev_addr)) + pr_info("using self ethernet address: %s", dev_addr); #endif #if (defined CONFIG_USB_G_MULTI_CDC && defined USB_ETH_RNDIS) + /* + * If both ecm and rndis are selected then: + * 1) rndis borrows the net interface from ecm + * 2) since the interface is shared it must not be bound + * twice - in ecm's _and_ rndis' binds, so do it here. + */ gether_set_gadget(ecm_opts->net, cdev->gadget); status = gether_register_netdev(ecm_opts->net); if (status) goto fail0; - ecm_opts->bound = true; - gether_get_host_addr_u8(ecm_opts->net, host_mac); + rndis_borrow_net(fi_rndis, ecm_opts->net); + ecm_opts->bound = true; #endif /* set up serial link layer */ @@ -388,10 +411,12 @@ fail2: fail1: usb_put_function_instance(fi_acm); fail0: +#ifdef USB_ETH_RNDIS + usb_put_function_instance(fi_rndis); +fail: +#endif #ifdef CONFIG_USB_G_MULTI_CDC usb_put_function_instance(fi_ecm); -#else - gether_cleanup(the_dev); #endif return status; } @@ -405,11 +430,13 @@ static int __exit multi_unbind(struct usb_composite_dev *cdev) usb_put_function(f_acm_rndis); #endif usb_put_function_instance(fi_acm); +#ifdef USB_ETH_RNDIS + usb_put_function(f_rndis); + usb_put_function_instance(fi_rndis); +#endif #ifdef CONFIG_USB_G_MULTI_CDC usb_put_function(f_ecm); usb_put_function_instance(fi_ecm); -#else - gether_cleanup(the_dev); #endif return 0; } |