atl1c: cancel task when interface closed
authorHuang, Xiong <xiong@qca.qualcomm.com>
Mon, 30 Apr 2012 15:38:55 +0000 (15:38 +0000)
committerDavid S. Miller <davem@davemloft.net>
Tue, 1 May 2012 01:44:15 +0000 (21:44 -0400)
common_task might be running while close routine is called,
wait/cancel it.

Signed-off-by: xiong <xiong@qca.qualcomm.com>
Tested-by: Liu David <dwliu@qca.qualcomm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/atheros/atl1c/atl1c_main.c

index d910dbb8a296e852ec802d938cd2e871a5b981e4..b95ef45051152fdefc5b04bc46f6f7d420d38c8e 100644 (file)
@@ -330,6 +330,9 @@ static void atl1c_common_task(struct work_struct *work)
        adapter = container_of(work, struct atl1c_adapter, common_task);
        netdev = adapter->netdev;
 
+       if (test_bit(__AT_DOWN, &adapter->flags))
+               return;
+
        if (test_and_clear_bit(ATL1C_WORK_EVENT_RESET, &adapter->work_event)) {
                netif_device_detach(netdev);
                atl1c_down(adapter);
@@ -2311,6 +2314,8 @@ static int atl1c_close(struct net_device *netdev)
        struct atl1c_adapter *adapter = netdev_priv(netdev);
 
        WARN_ON(test_bit(__AT_RESETTING, &adapter->flags));
+       set_bit(__AT_DOWN, &adapter->flags);
+       cancel_work_sync(&adapter->common_task);
        atl1c_down(adapter);
        atl1c_free_ring_resources(adapter);
        return 0;