hso: fix for crash when unplugging the device
authorJan Dumon <j.dumon@option.com>
Wed, 1 Apr 2009 22:57:20 +0000 (22:57 +0000)
committerDavid S. Miller <davem@davemloft.net>
Thu, 2 Apr 2009 23:31:43 +0000 (16:31 -0700)
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>
drivers/net/usb/hso.c

index 28d1424..779a007 100644 (file)
@@ -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);
 
        }
 }