aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/bluetooth
diff options
context:
space:
mode:
authorDavid Herrmann <dh.herrmann@googlemail.com>2012-01-07 09:47:14 -0500
committerJohan Hedberg <johan.hedberg@intel.com>2012-02-13 10:01:23 -0500
commitbf18c7118cf83ad4b9aa476354b4a06bcb9d0c4f (patch)
treec9a0de3c8bf6c6288fee5a0178dfde4c19a16c1e /drivers/bluetooth
parentaed014a02e809bd228a8ce7e7cc432ded9b72ef6 (diff)
Bluetooth: vhci: Free driver_data on file release
This removes the hci-destruct callback and instead frees the private driver data in the vhci_release file release function. There is no reason to keep private driver data available if the driver has already shut down. After vhci_release is called our module can be unloaded. The only reason it is kept alive is the hci-core having a module-ref on us because of our destruct callback. However, this callback only frees hdev->driver_data. That is, we wait for the hdev-device to get destroyed to free our internal driver-data. In fact, the hci-core does never touch hdev->driver_data so it doesn't care if it is NULL. Therefore, we simply free it when unloading the driver. Another important fact is that the hdev core does not call any callbacks other than the destruct-cb after hci_unregister_dev() has been called. So there is no function of our module that will be called nor does the hci-core touch hdev->driver_data. Hence, no other code can touch hdev->driver_data after our cleanup so the destruct callback is definitely unnecessary here. Signed-off-by: David Herrmann <dh.herrmann@googlemail.com> Acked-by: Marcel Holtmann <marcel@holtmann.org> Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Diffstat (limited to 'drivers/bluetooth')
-rw-r--r--drivers/bluetooth/hci_vhci.c7
1 files changed, 1 insertions, 6 deletions
diff --git a/drivers/bluetooth/hci_vhci.c b/drivers/bluetooth/hci_vhci.c
index 2ed6ab1c6e1b..44a801292d62 100644
--- a/drivers/bluetooth/hci_vhci.c
+++ b/drivers/bluetooth/hci_vhci.c
@@ -103,11 +103,6 @@ static int vhci_send_frame(struct sk_buff *skb)
103 return 0; 103 return 0;
104} 104}
105 105
106static void vhci_destruct(struct hci_dev *hdev)
107{
108 kfree(hdev->driver_data);
109}
110
111static inline ssize_t vhci_get_user(struct vhci_data *data, 106static inline ssize_t vhci_get_user(struct vhci_data *data,
112 const char __user *buf, size_t count) 107 const char __user *buf, size_t count)
113{ 108{
@@ -248,7 +243,6 @@ static int vhci_open(struct inode *inode, struct file *file)
248 hdev->close = vhci_close_dev; 243 hdev->close = vhci_close_dev;
249 hdev->flush = vhci_flush; 244 hdev->flush = vhci_flush;
250 hdev->send = vhci_send_frame; 245 hdev->send = vhci_send_frame;
251 hdev->destruct = vhci_destruct;
252 246
253 hdev->owner = THIS_MODULE; 247 hdev->owner = THIS_MODULE;
254 248
@@ -273,6 +267,7 @@ static int vhci_release(struct inode *inode, struct file *file)
273 hci_free_dev(hdev); 267 hci_free_dev(hdev);
274 268
275 file->private_data = NULL; 269 file->private_data = NULL;
270 kfree(data);
276 271
277 return 0; 272 return 0;
278} 273}