diff options
author | 2016-03-01 15:10:38 -0500 | |
---|---|---|
committer | 2016-03-01 15:10:38 -0500 | |
commit | c44a72a5e8c16751af456cd711720c3aabd40cdd (patch) | |
tree | d0b2a52f0d240c1f49b06ca454d104b23acc4fa0 | |
parent | 3c59x: mask LAST_FRAG bit from length field in ring (diff) | |
parent | can: gs_usb: fixed disconnect bug by removing erroneous use of kfree() (diff) | |
download | linux-c44a72a5e8c16751af456cd711720c3aabd40cdd.tar.gz linux-c44a72a5e8c16751af456cd711720c3aabd40cdd.tar.bz2 linux-c44a72a5e8c16751af456cd711720c3aabd40cdd.zip |
Merge tag 'linux-can-fixes-for-4.5-20160226' of git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can
Marc Kleine-Budde says:
====================
pull-request: can 2016-02-26
this is a pull request of one patch for net.
The patch by Maximilain Schneider fixes a kfree() problem during disconnect in
the gs_usb driver.
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/can/usb/gs_usb.c | 24 |
1 files changed, 11 insertions, 13 deletions
diff --git a/drivers/net/can/usb/gs_usb.c b/drivers/net/can/usb/gs_usb.c index 5eee62badf45..cbc99d5649af 100644 --- a/drivers/net/can/usb/gs_usb.c +++ b/drivers/net/can/usb/gs_usb.c @@ -826,9 +826,8 @@ static struct gs_can *gs_make_candev(unsigned int channel, struct usb_interface static void gs_destroy_candev(struct gs_can *dev) { unregister_candev(dev->netdev); - free_candev(dev->netdev); usb_kill_anchored_urbs(&dev->tx_submitted); - kfree(dev); + free_candev(dev->netdev); } static int gs_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) @@ -913,12 +912,15 @@ static int gs_usb_probe(struct usb_interface *intf, const struct usb_device_id * for (i = 0; i < icount; i++) { dev->canch[i] = gs_make_candev(i, intf); if (IS_ERR_OR_NULL(dev->canch[i])) { + /* save error code to return later */ + rc = PTR_ERR(dev->canch[i]); + /* on failure destroy previously created candevs */ icount = i; - for (i = 0; i < icount; i++) { + for (i = 0; i < icount; i++) gs_destroy_candev(dev->canch[i]); - dev->canch[i] = NULL; - } + + usb_kill_anchored_urbs(&dev->rx_submitted); kfree(dev); return rc; } @@ -939,16 +941,12 @@ static void gs_usb_disconnect(struct usb_interface *intf) return; } - for (i = 0; i < GS_MAX_INTF; i++) { - struct gs_can *can = dev->canch[i]; - - if (!can) - continue; - - gs_destroy_candev(can); - } + for (i = 0; i < GS_MAX_INTF; i++) + if (dev->canch[i]) + gs_destroy_candev(dev->canch[i]); usb_kill_anchored_urbs(&dev->rx_submitted); + kfree(dev); } static const struct usb_device_id gs_usb_table[] = { |