Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@xxxxxxxxxxx> Signed-off-by: Kyungmin Park <kyungmin.park@xxxxxxxxxxx> --- drivers/usb/gadget/Kconfig | 1 + drivers/usb/gadget/multi.c | 40 ++++++++++++++++++++++++++++++++++------ 2 files changed, 35 insertions(+), 6 deletions(-) diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index 46cef77..b9e615f 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -960,6 +960,7 @@ config USB_G_MULTI select USB_F_ACM select USB_F_MASS_STORAGE select USB_F_ECM + select USB_F_RNDIS help The Multifunction Composite Gadget provides Ethernet (RNDIS and/or CDC Ethernet), mass storage and ACM serial link diff --git a/drivers/usb/gadget/multi.c b/drivers/usb/gadget/multi.c index 7404d53..77930b6 100644 --- a/drivers/usb/gadget/multi.c +++ b/drivers/usb/gadget/multi.c @@ -45,8 +45,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" @@ -142,28 +141,43 @@ static struct usb_function_instance *fi_fsg; static struct usb_function_instance *fi_ecm; +static struct usb_function_instance *fi_rndis; + /********** RNDIS **********/ #ifdef USB_ETH_RNDIS static struct usb_function *f_acm_rndis; static struct usb_function *f_fsg_rndis; +static struct usb_function *f_rndis_rndis; static __init int rndis_do_config(struct usb_configuration *c) { + struct f_rndis_opts *rndis_opts; int ret; if (gadget_is_otg(c->cdev->gadget)) { c->descriptors = otg_desc; c->bmAttributes |= USB_CONFIG_ATT_WAKEUP; } + rndis_opts = container_of(fi_rndis, struct f_rndis_opts, func_inst); + rndis_opts->ethaddr = hostaddr; + rndis_opts->vendor_id = 0; + rndis_opts->manufacturer = NULL; + rndis_opts->dev = the_dev; + + f_rndis_rndis = usb_get_function(fi_rndis); + if (IS_ERR(f_rndis_rndis)) + return PTR_ERR(f_rndis_rndis); - ret = rndis_bind_config(c, hostaddr, the_dev); - if (ret < 0) - return ret; + ret = usb_add_function(c, f_rndis_rndis); + if (ret) + goto err_func_rndis; f_acm_rndis = usb_get_function(fi_acm); - if (IS_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) @@ -187,6 +201,9 @@ err_fsg: err_conf: usb_put_function(f_acm_rndis); err_func_acm: + usb_remove_function(c, f_rndis_rndis); +err_func_rndis: + usb_put_function(f_rndis_rndis); return ret; } @@ -324,6 +341,12 @@ static int __ref multi_bind(struct usb_composite_dev *cdev) goto fail; } + fi_rndis = usb_get_function_instance("rndis"); + if (IS_ERR(fi_rndis)) { + status = PTR_ERR(fi_rndis); + goto fail_get_rndis; + } + /* set up serial link layer */ fi_acm = usb_get_function_instance("acm"); if (IS_ERR(fi_acm)) { @@ -372,6 +395,7 @@ fail4: #ifdef USB_ETH_RNDIS usb_put_function(f_acm_rndis); usb_put_function(f_fsg_rndis); + usb_put_function(f_rndis_rndis); #endif fail3: fsg_common_put(fsg_common); @@ -380,6 +404,8 @@ fail2: fail1: usb_put_function_instance(fi_acm); fail0: + usb_put_function_instance(fi_rndis); +fail_get_rndis: usb_put_function_instance(fi_ecm); fail: gether_cleanup(the_dev); @@ -396,7 +422,9 @@ static int __exit multi_unbind(struct usb_composite_dev *cdev) #ifdef USB_ETH_RNDIS usb_put_function(f_acm_rndis); usb_put_function(f_fsg_rndis); + usb_put_function(f_rndis_rndis); #endif + usb_put_function_instance(fi_rndis); usb_put_function_instance(fi_acm); usb_put_function_instance(fi_fsg); usb_put_function_instance(fi_ecm); -- 1.7.0.4 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html