aboutsummaryrefslogtreecommitdiffstats
path: root/net/nfc
diff options
context:
space:
mode:
authorSamuel Ortiz <sameo@linux.intel.com>2013-02-21 09:40:04 -0500
committerSamuel Ortiz <sameo@linux.intel.com>2013-03-08 08:25:04 -0500
commit3536da06db0baa675f32de608c0a4c0f5ef0e9ff (patch)
tree584815bbafbb526300b00671d226744f0e411e2b /net/nfc
parentb141e811a0763bb107af4cd99d456193ccdb8053 (diff)
NFC: llcp: Clean local timers and works when removing a device
Whenever an adapter is removed we must clean all the local structures, especially the timers and scheduled work. Otherwise those asynchronous threads will eventually try to access the freed nfc_dev pointer if an LLCP link is up. Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Diffstat (limited to 'net/nfc')
-rw-r--r--net/nfc/llcp/llcp.c21
1 files changed, 14 insertions, 7 deletions
diff --git a/net/nfc/llcp/llcp.c b/net/nfc/llcp/llcp.c
index 7f8266dd14cb..77e1d97b3996 100644
--- a/net/nfc/llcp/llcp.c
+++ b/net/nfc/llcp/llcp.c
@@ -142,20 +142,25 @@ struct nfc_llcp_local *nfc_llcp_local_get(struct nfc_llcp_local *local)
142 return local; 142 return local;
143} 143}
144 144
145static void local_release(struct kref *ref) 145static void local_cleanup(struct nfc_llcp_local *local, bool listen)
146{ 146{
147 struct nfc_llcp_local *local; 147 nfc_llcp_socket_release(local, listen);
148
149 local = container_of(ref, struct nfc_llcp_local, ref);
150
151 list_del(&local->list);
152 nfc_llcp_socket_release(local, false);
153 del_timer_sync(&local->link_timer); 148 del_timer_sync(&local->link_timer);
154 skb_queue_purge(&local->tx_queue); 149 skb_queue_purge(&local->tx_queue);
155 cancel_work_sync(&local->tx_work); 150 cancel_work_sync(&local->tx_work);
156 cancel_work_sync(&local->rx_work); 151 cancel_work_sync(&local->rx_work);
157 cancel_work_sync(&local->timeout_work); 152 cancel_work_sync(&local->timeout_work);
158 kfree_skb(local->rx_pending); 153 kfree_skb(local->rx_pending);
154}
155
156static void local_release(struct kref *ref)
157{
158 struct nfc_llcp_local *local;
159
160 local = container_of(ref, struct nfc_llcp_local, ref);
161
162 list_del(&local->list);
163 local_cleanup(local, false);
159 kfree(local); 164 kfree(local);
160} 165}
161 166
@@ -1427,6 +1432,8 @@ void nfc_llcp_unregister_device(struct nfc_dev *dev)
1427 return; 1432 return;
1428 } 1433 }
1429 1434
1435 local_cleanup(local, false);
1436
1430 nfc_llcp_local_put(local); 1437 nfc_llcp_local_put(local);
1431} 1438}
1432 1439