diff --git a/drivers/usb/gadget/function/f_ncm.c b/drivers/usb/gadget/function/f_ncm.c index d9d0cebc37cf..495d31922858 100644 --- a/drivers/usb/gadget/function/f_ncm.c +++ b/drivers/usb/gadget/function/f_ncm.c @@ -1470,38 +1470,18 @@ static int ncm_bind(struct usb_configuration *c, struct usb_function *f) */ if (!ncm_opts->bound) { mutex_lock(&ncm_opts->lock); - ncm_opts->net = gether_setup_default(); - if (IS_ERR(ncm_opts->net)) { - status = PTR_ERR(ncm_opts->net); - mutex_unlock(&ncm_opts->lock); - goto error; - } gether_set_gadget(ncm_opts->net, cdev->gadget); status = gether_register_netdev(ncm_opts->net); mutex_unlock(&ncm_opts->lock); - if (status) { - free_netdev(ncm_opts->net); - goto error; - } + if (status) + goto fail; ncm_opts->bound = true; } - - /* export host's Ethernet address in CDC format */ - status = gether_get_host_addr_cdc(ncm_opts->net, ncm->ethaddr, - sizeof(ncm->ethaddr)); - if (status < 12) { /* strlen("01234567890a") */ - ERROR(cdev, "%s: failed to get host eth addr, err %d\n", - __func__, status); - status = -EINVAL; - goto netdev_cleanup; - } - ncm->port.ioport = netdev_priv(ncm_opts->net); - us = usb_gstrings_attach(cdev, ncm_strings, ARRAY_SIZE(ncm_string_defs)); if (IS_ERR(us)) { status = PTR_ERR(us); - goto netdev_cleanup; + goto fail; } ncm_control_intf.iInterface = us[STRING_CTRL_IDX].id; ncm_data_nop_intf.iInterface = us[STRING_DATA_IDX].id; @@ -1609,10 +1589,7 @@ fail: kfree(ncm->notify_req->buf); usb_ep_free_request(ncm->notify, ncm->notify_req); } -netdev_cleanup: - gether_cleanup(netdev_priv(ncm_opts->net)); -error: ERROR(cdev, "%s: can't bind, err %d\n", f->name, status); return status; @@ -1708,6 +1685,8 @@ static void ncm_free_inst(struct usb_function_instance *f) opts = container_of(f, struct f_ncm_opts, func_inst); if (opts->bound) gether_cleanup(netdev_priv(opts->net)); + else + free_netdev(opts->net); kfree(opts->ncm_interf_group); kfree(opts); } @@ -1726,6 +1705,12 @@ static struct usb_function_instance *ncm_alloc_inst(void) mutex_init(&opts->lock); opts->func_inst.free_func_inst = ncm_free_inst; + opts->net = gether_setup_default(); + if (IS_ERR(opts->net)) { + struct net_device *net = opts->net; + kfree(opts); + return ERR_CAST(net); + } INIT_LIST_HEAD(&opts->ncm_os_desc.ext_prop); descs[0] = &opts->ncm_os_desc; @@ -1768,13 +1753,9 @@ static void ncm_free(struct usb_function *f) static void ncm_unbind(struct usb_configuration *c, struct usb_function *f) { struct f_ncm *ncm = func_to_ncm(f); - struct f_ncm_opts *opts = container_of(f->fi, struct f_ncm_opts, - func_inst); DBG(c->cdev, "ncm unbind\n"); - opts->bound = false; - hrtimer_cancel(&ncm->task_timer); kfree(f->os_desc_table); @@ -1790,14 +1771,13 @@ static void ncm_unbind(struct usb_configuration *c, struct usb_function *f) kfree(ncm->notify_req->buf); usb_ep_free_request(ncm->notify, ncm->notify_req); - - gether_cleanup(netdev_priv(opts->net)); } static struct usb_function *ncm_alloc(struct usb_function_instance *fi) { struct f_ncm *ncm; struct f_ncm_opts *opts; + int status; /* allocate and initialize one new instance */ ncm = kzalloc(sizeof(*ncm), GFP_KERNEL); @@ -1807,9 +1787,20 @@ static struct usb_function *ncm_alloc(struct usb_function_instance *fi) opts = container_of(fi, struct f_ncm_opts, func_inst); mutex_lock(&opts->lock); opts->refcnt++; + + /* export host's Ethernet address in CDC format */ + status = gether_get_host_addr_cdc(opts->net, ncm->ethaddr, + sizeof(ncm->ethaddr)); + if (status < 12) { /* strlen("01234567890a") */ + kfree(ncm); + mutex_unlock(&opts->lock); + return ERR_PTR(-EINVAL); + } ncm_string_defs[STRING_MAC_IDX].s = ncm->ethaddr; + spin_lock_init(&ncm->lock); ncm_reset_values(ncm); + ncm->port.ioport = netdev_priv(opts->net); mutex_unlock(&opts->lock); ncm->port.is_fixed = true; ncm->port.supports_multi_frame = true; diff --git a/drivers/usb/gadget/function/u_ether_configfs.h b/drivers/usb/gadget/function/u_ether_configfs.h index b701a63f771d..e70425a5dcb4 100644 --- a/drivers/usb/gadget/function/u_ether_configfs.h +++ b/drivers/usb/gadget/function/u_ether_configfs.h @@ -32,11 +32,6 @@ struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item); \ int result; \ \ - if (opts->bound == false) { \ - pr_err("Gadget function do not bind yet.\n"); \ - return -ENODEV; \ - } \ - \ mutex_lock(&opts->lock); \ result = gether_get_dev_addr(opts->net, page, PAGE_SIZE); \ mutex_unlock(&opts->lock); \ @@ -50,11 +45,6 @@ struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item); \ int ret; \ \ - if (opts->bound == false) { \ - pr_err("Gadget function do not bind yet.\n"); \ - return -ENODEV; \ - } \ - \ mutex_lock(&opts->lock); \ if (opts->refcnt) { \ mutex_unlock(&opts->lock); \ @@ -77,11 +67,6 @@ struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item); \ int result; \ \ - if (opts->bound == false) { \ - pr_err("Gadget function do not bind yet.\n"); \ - return -ENODEV; \ - } \ - \ mutex_lock(&opts->lock); \ result = gether_get_host_addr(opts->net, page, PAGE_SIZE); \ mutex_unlock(&opts->lock); \ @@ -95,11 +80,6 @@ struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item); \ int ret; \ \ - if (opts->bound == false) { \ - pr_err("Gadget function do not bind yet.\n"); \ - return -ENODEV; \ - } \ - \ mutex_lock(&opts->lock); \ if (opts->refcnt) { \ mutex_unlock(&opts->lock); \ @@ -122,11 +102,6 @@ struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item); \ unsigned qmult; \ \ - if (opts->bound == false) { \ - pr_err("Gadget function do not bind yet.\n"); \ - return -ENODEV; \ - } \ - \ mutex_lock(&opts->lock); \ qmult = gether_get_qmult(opts->net); \ mutex_unlock(&opts->lock); \ @@ -140,11 +115,6 @@ u8 val; \ int ret; \ \ - if (opts->bound == false) { \ - pr_err("Gadget function do not bind yet.\n"); \ - return -ENODEV; \ - } \ - \ mutex_lock(&opts->lock); \ if (opts->refcnt) { \ ret = -EBUSY; \ @@ -171,11 +141,6 @@ out: \ struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item); \ int ret; \ \ - if (opts->bound == false) { \ - pr_err("Gadget function do not bind yet.\n"); \ - return -ENODEV; \ - } \ - \ mutex_lock(&opts->lock); \ ret = gether_get_ifname(opts->net, page, PAGE_SIZE); \ mutex_unlock(&opts->lock); \