There is a new funtion interface and g_ffs is the last gadget to use the old. Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@xxxxxxxxxxx> Signed-off-by: Kyungmin Park <kyungmin.park@xxxxxxxxxxx> --- drivers/usb/gadget/Kconfig | 1 + drivers/usb/gadget/g_ffs.c | 94 +++++++++++++++++++++++++++++++++++++------- 2 files changed, 81 insertions(+), 14 deletions(-) diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index a91e642..956bfe9 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -882,6 +882,7 @@ config USB_FUNCTIONFS_ETH bool "Include configuration with CDC ECM (Ethernet)" depends on USB_FUNCTIONFS && NET select USB_U_ETHER + select USB_F_ECM help Include a configuration with CDC ECM function (Ethernet) and the Function Filesystem. diff --git a/drivers/usb/gadget/g_ffs.c b/drivers/usb/gadget/g_ffs.c index e954082..081041a 100644 --- a/drivers/usb/gadget/g_ffs.c +++ b/drivers/usb/gadget/g_ffs.c @@ -21,6 +21,7 @@ * a "gcc --combine ... part1.c part2.c part3.c ... " build would. */ #if defined CONFIG_USB_FUNCTIONFS_ETH || defined CONFIG_USB_FUNCTIONFS_RNDIS + # if defined USB_ETH_RNDIS # undef USB_ETH_RNDIS # endif @@ -28,8 +29,7 @@ # define USB_ETH_RNDIS y # endif -#define USBF_ECM_INCLUDED -# include "f_ecm.c" +# include "u_ecm.h" #define USB_FSUBSET_INCLUDED # include "f_subset.c" # ifdef USB_ETH_RNDIS @@ -39,11 +39,15 @@ # endif # include "u_ether.h" +USB_ETHERNET_MODULE_PARAMETERS(); + static u8 gfs_host_mac[ETH_ALEN]; static struct eth_dev *the_dev; # ifdef CONFIG_USB_FUNCTIONFS_ETH static int eth_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN], struct eth_dev *dev); +static struct usb_function_instance *fi_ecm; +static struct usb_function *f_ecm; # endif #else # define the_dev NULL @@ -76,10 +80,6 @@ struct gfs_ffs_obj { USB_GADGET_COMPOSITE_OPTIONS(); -#if defined CONFIG_USB_FUNCTIONFS_ETH || defined CONFIG_USB_FUNCTIONFS_RNDIS -USB_ETHERNET_MODULE_PARAMETERS(); -#endif - static struct usb_device_descriptor gfs_dev_desc = { .bLength = sizeof gfs_dev_desc, .bDescriptorType = USB_DT_DEVICE, @@ -355,14 +355,50 @@ static int gfs_bind(struct usb_composite_dev *cdev) if (missing_funcs) return -ENODEV; -#if defined CONFIG_USB_FUNCTIONFS_ETH || defined CONFIG_USB_FUNCTIONFS_RNDIS +#if defined CONFIG_USB_FUNCTIONFS_ETH + if (can_support_ecm(cdev->gadget)) { + struct f_ecm_opts *ecm_opts; + + fi_ecm = usb_get_function_instance("ecm"); + if (IS_ERR(fi_ecm)) + return PTR_ERR(fi_ecm); + ecm_opts = container_of(fi_ecm, struct f_ecm_opts, func_inst); + + gether_set_qmult(ecm_opts->net, qmult); + + if (!gether_set_host_addr(ecm_opts->net, host_addr)) + 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); + + the_dev = netdev_priv(ecm_opts->net); + } else { + the_dev = gether_setup(cdev->gadget, dev_addr, host_addr, + gfs_host_mac, qmult); + } + +#elif defined CONFIG_USB_FUNCTIONFS_RNDIS + the_dev = gether_setup(cdev->gadget, dev_addr, host_addr, gfs_host_mac, qmult); #endif - if (IS_ERR(the_dev)) { - ret = PTR_ERR(the_dev); - goto error_quick; + if (IS_ERR(the_dev)) + return PTR_ERR(the_dev); + +#if defined CONFIG_USB_FUNCTIONFS_RNDIS && defined CONFIG_USB_FUNCTIONFS_ETH + if (can_support_ecm(cdev->gadget)) { + struct f_ecm_opts *ecm_opts; + + ecm_opts = container_of(fi_ecm, struct f_ecm_opts, func_inst); + + gether_set_gadget(ecm_opts->net, cdev->gadget); + ret = gether_register_netdev(ecm_opts->net); + if (ret) + goto error; + ecm_opts->bound = true; + gether_get_host_addr_u8(ecm_opts->net, gfs_host_mac); } +#endif ret = usb_string_ids_tab(cdev, gfs_strings); if (unlikely(ret < 0)) @@ -398,9 +434,16 @@ error_unbind: for (i = 0; i < func_num; i++) functionfs_unbind(ffs_tab[i].ffs_data); error: +#if defined CONFIG_USB_FUNCTIONFS_ETH + if (can_support_ecm(cdev->gadget)) + usb_put_function_instance(fi_ecm); + else + gether_cleanup(the_dev); + the_dev = NULL; +#elif defined CONFIG_USB_FUNCTIONFS_RNDIS gether_cleanup(the_dev); the_dev = NULL; -error_quick: +#endif return ret; } @@ -413,8 +456,19 @@ static int gfs_unbind(struct usb_composite_dev *cdev) ENTER(); + +#if defined CONFIG_USB_FUNCTIONFS_ETH + if (can_support_ecm(cdev->gadget)) { + usb_put_function(f_ecm); + usb_put_function_instance(fi_ecm); + } else { + gether_cleanup(the_dev); + } + the_dev = NULL; +#elif defined CONFIG_USB_FUNCTIONFS_RNDIS gether_cleanup(the_dev); the_dev = NULL; +#endif /* * We may have been called in an error recovery from @@ -483,9 +537,21 @@ static int gfs_do_config(struct usb_configuration *c) static int eth_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN], struct eth_dev *dev) { - return can_support_ecm(c->cdev->gadget) - ? ecm_bind_config(c, ethaddr, dev) - : geth_bind_config(c, ethaddr, dev); + int status = 0; + + if (can_support_ecm(c->cdev->gadget)) { + f_ecm = usb_get_function(fi_ecm); + if (IS_ERR(f_ecm)) + return PTR_ERR(f_ecm); + + status = usb_add_function(c, f_ecm); + if (status < 0) + usb_put_function(f_ecm); + + } else { + status = geth_bind_config(c, ethaddr, dev); + } + return status; } #endif -- 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