diff options
| author | Jan Dumon <j.dumon@option.com> | 2009-04-01 18:57:20 -0400 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2009-04-02 19:31:43 -0400 |
| commit | 3b7d2b319db0ba1f6208ca58b297fb419301f85a (patch) | |
| tree | ec1ec255d2e3b5d513b7c0f5791a3f7154632e8c | |
| parent | b6bc978b361bb9da7526a78b0a247bdd34984282 (diff) | |
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 @@ | |||
| 5 | * Copyright (C) 2008 Option International | 5 | * Copyright (C) 2008 Option International |
| 6 | * Filip Aben <f.aben@option.com> | 6 | * Filip Aben <f.aben@option.com> |
| 7 | * Denis Joseph Barrow <d.barow@option.com> | 7 | * Denis Joseph Barrow <d.barow@option.com> |
| 8 | * Jan Dumon <j.dumon@option.com> | ||
| 8 | * Copyright (C) 2007 Andrew Bird (Sphere Systems Ltd) | 9 | * Copyright (C) 2007 Andrew Bird (Sphere Systems Ltd) |
| 9 | * <ajb@spheresystems.co.uk> | 10 | * <ajb@spheresystems.co.uk> |
| 10 | * Copyright (C) 2008 Greg Kroah-Hartman <gregkh@suse.de> | 11 | * Copyright (C) 2008 Greg Kroah-Hartman <gregkh@suse.de> |
| @@ -2417,20 +2418,22 @@ static void hso_free_net_device(struct hso_device *hso_dev) | |||
| 2417 | if (!hso_net) | 2418 | if (!hso_net) |
| 2418 | return; | 2419 | return; |
| 2419 | 2420 | ||
| 2421 | remove_net_device(hso_net->parent); | ||
| 2422 | |||
| 2423 | if (hso_net->net) { | ||
| 2424 | unregister_netdev(hso_net->net); | ||
| 2425 | free_netdev(hso_net->net); | ||
| 2426 | } | ||
| 2427 | |||
| 2420 | /* start freeing */ | 2428 | /* start freeing */ |
| 2421 | for (i = 0; i < MUX_BULK_RX_BUF_COUNT; i++) { | 2429 | for (i = 0; i < MUX_BULK_RX_BUF_COUNT; i++) { |
| 2422 | usb_free_urb(hso_net->mux_bulk_rx_urb_pool[i]); | 2430 | usb_free_urb(hso_net->mux_bulk_rx_urb_pool[i]); |
| 2423 | kfree(hso_net->mux_bulk_rx_buf_pool[i]); | 2431 | kfree(hso_net->mux_bulk_rx_buf_pool[i]); |
| 2432 | hso_net->mux_bulk_rx_buf_pool[i] = NULL; | ||
| 2424 | } | 2433 | } |
| 2425 | usb_free_urb(hso_net->mux_bulk_tx_urb); | 2434 | usb_free_urb(hso_net->mux_bulk_tx_urb); |
| 2426 | kfree(hso_net->mux_bulk_tx_buf); | 2435 | kfree(hso_net->mux_bulk_tx_buf); |
| 2427 | 2436 | hso_net->mux_bulk_tx_buf = NULL; | |
| 2428 | remove_net_device(hso_net->parent); | ||
| 2429 | |||
| 2430 | if (hso_net->net) { | ||
| 2431 | unregister_netdev(hso_net->net); | ||
| 2432 | free_netdev(hso_net->net); | ||
| 2433 | } | ||
| 2434 | 2437 | ||
| 2435 | kfree(hso_dev); | 2438 | kfree(hso_dev); |
| 2436 | } | 2439 | } |
| @@ -2620,12 +2623,12 @@ static void hso_free_tiomget(struct hso_serial *serial) | |||
| 2620 | { | 2623 | { |
| 2621 | struct hso_tiocmget *tiocmget = serial->tiocmget; | 2624 | struct hso_tiocmget *tiocmget = serial->tiocmget; |
| 2622 | if (tiocmget) { | 2625 | if (tiocmget) { |
| 2623 | kfree(tiocmget); | ||
| 2624 | if (tiocmget->urb) { | 2626 | if (tiocmget->urb) { |
| 2625 | usb_free_urb(tiocmget->urb); | 2627 | usb_free_urb(tiocmget->urb); |
| 2626 | tiocmget->urb = NULL; | 2628 | tiocmget->urb = NULL; |
| 2627 | } | 2629 | } |
| 2628 | serial->tiocmget = NULL; | 2630 | serial->tiocmget = NULL; |
| 2631 | kfree(tiocmget); | ||
| 2629 | 2632 | ||
| 2630 | } | 2633 | } |
| 2631 | } | 2634 | } |
