diff options
Diffstat (limited to 'drivers/usb/class/cdc-wdm.c')
-rw-r--r-- | drivers/usb/class/cdc-wdm.c | 31 |
1 files changed, 16 insertions, 15 deletions
diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c index f053b41fae7f..cdc93d066991 100644 --- a/drivers/usb/class/cdc-wdm.c +++ b/drivers/usb/class/cdc-wdm.c @@ -349,30 +349,25 @@ static ssize_t wdm_write r = copy_from_user(buf, buffer, count); if (r > 0) { - kfree(buf); rv = -EFAULT; - goto outnl; + goto out_free_mem; } /* concurrent writes and disconnect */ r = mutex_lock_interruptible(&desc->wlock); rv = -ERESTARTSYS; - if (r) { - kfree(buf); - goto outnl; - } + if (r) + goto out_free_mem; if (test_bit(WDM_DISCONNECTING, &desc->flags)) { - kfree(buf); rv = -ENODEV; - goto outnp; + goto out_free_mem_lock; } r = usb_autopm_get_interface(desc->intf); if (r < 0) { - kfree(buf); rv = usb_translate_errors(r); - goto outnp; + goto out_free_mem_lock; } if (!(file->f_flags & O_NONBLOCK)) @@ -386,9 +381,8 @@ static ssize_t wdm_write r = -EIO; if (r < 0) { - kfree(buf); rv = r; - goto out; + goto out_free_mem_pm; } req = desc->orq; @@ -415,21 +409,28 @@ static ssize_t wdm_write rv = usb_submit_urb(desc->command, GFP_KERNEL); if (rv < 0) { - kfree(buf); desc->outbuf = NULL; clear_bit(WDM_IN_USE, &desc->flags); dev_err(&desc->intf->dev, "Tx URB error: %d\n", rv); rv = usb_translate_errors(rv); + goto out_free_mem_pm; } else { dev_dbg(&desc->intf->dev, "Tx URB has been submitted index=%d", req->wIndex); } -out: + usb_autopm_put_interface(desc->intf); -outnp: mutex_unlock(&desc->wlock); outnl: return rv < 0 ? rv : count; + +out_free_mem_pm: + usb_autopm_put_interface(desc->intf); +out_free_mem_lock: + mutex_unlock(&desc->wlock); +out_free_mem: + kfree(buf); + return rv; } /* |