diff options
author | John Keeping <john@metanate.com> | 2022-11-22 15:35:23 +0300 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2022-11-29 10:56:09 +0300 |
commit | 944fe915d00d3cb1bacb1e77cabfb6dc82e6f8b8 (patch) | |
tree | e340f46d18fbc8894047252e3cdcc2389496c3ae /drivers/usb/gadget/function/f_hid.c | |
parent | 70a3288a7586526315105c699b687d78cd32559a (diff) | |
download | linux-944fe915d00d3cb1bacb1e77cabfb6dc82e6f8b8.tar.xz |
usb: gadget: f_hid: tidy error handling in hidg_alloc
Unify error handling at the end of the function, reducing the risk of
missing something on one of the error paths.
Moving the increment of opts->refcnt later means there is no need to
decrement it on the error path and is safe as this is guarded by
opts->lock which is held for this entire section.
Tested-by: Lee Jones <lee@kernel.org>
Reviewed-by: Andrzej Pietrasiewicz <andrzej.p@collabora.com>
Reviewed-by: Lee Jones <lee@kernel.org>
Signed-off-by: John Keeping <john@metanate.com>
Link: https://lore.kernel.org/r/20221122123523.3068034-4-john@metanate.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/gadget/function/f_hid.c')
-rw-r--r-- | drivers/usb/gadget/function/f_hid.c | 21 |
1 files changed, 11 insertions, 10 deletions
diff --git a/drivers/usb/gadget/function/f_hid.c b/drivers/usb/gadget/function/f_hid.c index 6be6009f911e..a8da3b4a2855 100644 --- a/drivers/usb/gadget/function/f_hid.c +++ b/drivers/usb/gadget/function/f_hid.c @@ -1269,18 +1269,14 @@ static struct usb_function *hidg_alloc(struct usb_function_instance *fi) opts = container_of(fi, struct f_hid_opts, func_inst); mutex_lock(&opts->lock); - ++opts->refcnt; device_initialize(&hidg->dev); hidg->dev.release = hidg_release; hidg->dev.class = hidg_class; hidg->dev.devt = MKDEV(major, opts->minor); ret = dev_set_name(&hidg->dev, "hidg%d", opts->minor); - if (ret) { - --opts->refcnt; - mutex_unlock(&opts->lock); - return ERR_PTR(ret); - } + if (ret) + goto err_unlock; hidg->bInterfaceSubClass = opts->subclass; hidg->bInterfaceProtocol = opts->protocol; @@ -1291,14 +1287,13 @@ static struct usb_function *hidg_alloc(struct usb_function_instance *fi) opts->report_desc_length, GFP_KERNEL); if (!hidg->report_desc) { - put_device(&hidg->dev); - --opts->refcnt; - mutex_unlock(&opts->lock); - return ERR_PTR(-ENOMEM); + ret = -ENOMEM; + goto err_put_device; } } hidg->use_out_ep = !opts->no_out_endpoint; + ++opts->refcnt; mutex_unlock(&opts->lock); hidg->func.name = "hid"; @@ -1313,6 +1308,12 @@ static struct usb_function *hidg_alloc(struct usb_function_instance *fi) hidg->qlen = 4; return &hidg->func; + +err_put_device: + put_device(&hidg->dev); +err_unlock: + mutex_unlock(&opts->lock); + return ERR_PTR(ret); } DECLARE_USB_FUNCTION_INIT(hid, hidg_alloc_inst, hidg_alloc); |