diff options
author | Jan Dumon <j.dumon@option.com> | 2009-04-02 02:57:20 +0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-04-03 03:31:43 +0400 |
commit | 3b7d2b319db0ba1f6208ca58b297fb419301f85a (patch) | |
tree | ec1ec255d2e3b5d513b7c0f5791a3f7154632e8c | |
parent | b6bc978b361bb9da7526a78b0a247bdd34984282 (diff) | |
download | linux-3b7d2b319db0ba1f6208ca58b297fb419301f85a.tar.xz |
hso: fix for crash when unplugging the device
Changed the order in which things are freed. This fixes an oops when
unplugging the device while network traffic is ongoing.
Signed-off-by: Jan Dumon <j.dumon@option.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/usb/hso.c | 19 |
1 files changed, 11 insertions, 8 deletions
diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index 28d1424a3110..779a0078fcde 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c @@ -5,6 +5,7 @@ * Copyright (C) 2008 Option International * Filip Aben <f.aben@option.com> * Denis Joseph Barrow <d.barow@option.com> + * Jan Dumon <j.dumon@option.com> * Copyright (C) 2007 Andrew Bird (Sphere Systems Ltd) * <ajb@spheresystems.co.uk> * Copyright (C) 2008 Greg Kroah-Hartman <gregkh@suse.de> @@ -2417,20 +2418,22 @@ static void hso_free_net_device(struct hso_device *hso_dev) if (!hso_net) return; + remove_net_device(hso_net->parent); + + if (hso_net->net) { + unregister_netdev(hso_net->net); + free_netdev(hso_net->net); + } + /* start freeing */ for (i = 0; i < MUX_BULK_RX_BUF_COUNT; i++) { usb_free_urb(hso_net->mux_bulk_rx_urb_pool[i]); kfree(hso_net->mux_bulk_rx_buf_pool[i]); + hso_net->mux_bulk_rx_buf_pool[i] = NULL; } usb_free_urb(hso_net->mux_bulk_tx_urb); kfree(hso_net->mux_bulk_tx_buf); - - remove_net_device(hso_net->parent); - - if (hso_net->net) { - unregister_netdev(hso_net->net); - free_netdev(hso_net->net); - } + hso_net->mux_bulk_tx_buf = NULL; kfree(hso_dev); } @@ -2620,12 +2623,12 @@ static void hso_free_tiomget(struct hso_serial *serial) { struct hso_tiocmget *tiocmget = serial->tiocmget; if (tiocmget) { - kfree(tiocmget); if (tiocmget->urb) { usb_free_urb(tiocmget->urb); tiocmget->urb = NULL; } serial->tiocmget = NULL; + kfree(tiocmget); } } |