summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/bluetooth/bluecard_cs.c6
-rw-r--r--drivers/bluetooth/bt3c_cs.c6
-rw-r--r--drivers/bluetooth/btuart_cs.c6
-rw-r--r--drivers/bluetooth/dtl1_cs.c6
-rw-r--r--drivers/bluetooth/hci_ldisc.c11
-rw-r--r--drivers/bluetooth/hci_usb.c11
-rw-r--r--drivers/bluetooth/hci_vhci.c5
-rw-r--r--include/net/bluetooth/hci_core.h26
-rw-r--r--net/bluetooth/hci_conn.c5
-rw-r--r--net/bluetooth/hci_core.c25
10 files changed, 54 insertions, 53 deletions
diff --git a/drivers/bluetooth/bluecard_cs.c b/drivers/bluetooth/bluecard_cs.c
index 0eae1c88ac65..f2dbb950c8ce 100644
--- a/drivers/bluetooth/bluecard_cs.c
+++ b/drivers/bluetooth/bluecard_cs.c
@@ -789,6 +789,8 @@ int bluecard_open(bluecard_info_t *info)
hdev->destruct = bluecard_hci_destruct;
hdev->ioctl = bluecard_hci_ioctl;
+ hdev->owner = THIS_MODULE;
+
if (hci_register_dev(hdev) < 0) {
printk(KERN_WARNING "bluecard_cs: Can't register HCI device %s.\n", hdev->name);
return -ENODEV;
@@ -1002,8 +1004,6 @@ void bluecard_config(dev_link_t *link)
goto failed;
}
- MOD_INC_USE_COUNT;
-
if (bluecard_open(info) != 0)
goto failed;
@@ -1029,8 +1029,6 @@ void bluecard_release(u_long arg)
if (link->state & DEV_PRESENT)
bluecard_close(info);
- MOD_DEC_USE_COUNT;
-
link->dev = NULL;
CardServices(ReleaseConfiguration, link->handle);
diff --git a/drivers/bluetooth/bt3c_cs.c b/drivers/bluetooth/bt3c_cs.c
index e959f7814225..6c32b9e81504 100644
--- a/drivers/bluetooth/bt3c_cs.c
+++ b/drivers/bluetooth/bt3c_cs.c
@@ -593,6 +593,8 @@ int bt3c_open(bt3c_info_t *info)
hdev->destruct = bt3c_hci_destruct;
hdev->ioctl = bt3c_hci_ioctl;
+ hdev->owner = THIS_MODULE;
+
if (hci_register_dev(hdev) < 0) {
printk(KERN_WARNING "bt3c_cs: Can't register HCI device %s.\n", hdev->name);
return -ENODEV;
@@ -835,8 +837,6 @@ found_port:
goto failed;
}
- MOD_INC_USE_COUNT;
-
if (bt3c_open(info) != 0)
goto failed;
@@ -862,8 +862,6 @@ void bt3c_release(u_long arg)
if (link->state & DEV_PRESENT)
bt3c_close(info);
- MOD_DEC_USE_COUNT;
-
link->dev = NULL;
CardServices(ReleaseConfiguration, link->handle);
diff --git a/drivers/bluetooth/btuart_cs.c b/drivers/bluetooth/btuart_cs.c
index 65dd0ec1301a..afc6e99ab7a2 100644
--- a/drivers/bluetooth/btuart_cs.c
+++ b/drivers/bluetooth/btuart_cs.c
@@ -541,6 +541,8 @@ int btuart_open(btuart_info_t *info)
hdev->destruct = btuart_hci_destruct;
hdev->ioctl = btuart_hci_ioctl;
+ hdev->owner = THIS_MODULE;
+
if (hci_register_dev(hdev) < 0) {
printk(KERN_WARNING "btuart_cs: Can't register HCI device %s.\n", hdev->name);
return -ENODEV;
@@ -795,8 +797,6 @@ found_port:
goto failed;
}
- MOD_INC_USE_COUNT;
-
if (btuart_open(info) != 0)
goto failed;
@@ -822,8 +822,6 @@ void btuart_release(u_long arg)
if (link->state & DEV_PRESENT)
btuart_close(info);
- MOD_DEC_USE_COUNT;
-
link->dev = NULL;
CardServices(ReleaseConfiguration, link->handle);
diff --git a/drivers/bluetooth/dtl1_cs.c b/drivers/bluetooth/dtl1_cs.c
index ffcad4245fcf..9791be7e8a80 100644
--- a/drivers/bluetooth/dtl1_cs.c
+++ b/drivers/bluetooth/dtl1_cs.c
@@ -520,6 +520,8 @@ int dtl1_open(dtl1_info_t *info)
hdev->destruct = dtl1_hci_destruct;
hdev->ioctl = dtl1_hci_ioctl;
+ hdev->owner = THIS_MODULE;
+
if (hci_register_dev(hdev) < 0) {
printk(KERN_WARNING "dtl1_cs: Can't register HCI device %s.\n", hdev->name);
return -ENODEV;
@@ -747,8 +749,6 @@ void dtl1_config(dev_link_t *link)
goto failed;
}
- MOD_INC_USE_COUNT;
-
if (dtl1_open(info) != 0)
goto failed;
@@ -774,8 +774,6 @@ void dtl1_release(u_long arg)
if (link->state & DEV_PRESENT)
dtl1_close(info);
- MOD_DEC_USE_COUNT;
-
link->dev = NULL;
CardServices(ReleaseConfiguration, link->handle);
diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c
index c69635b693b5..bff2dd64af10 100644
--- a/drivers/bluetooth/hci_ldisc.c
+++ b/drivers/bluetooth/hci_ldisc.c
@@ -250,8 +250,6 @@ static void hci_uart_destruct(struct hci_dev *hdev)
hu = (struct hci_uart *) hdev->driver_data;
kfree(hu);
-
- MOD_DEC_USE_COUNT;
}
/* ------ LDISC part ------ */
@@ -290,8 +288,7 @@ static int hci_uart_tty_open(struct tty_struct *tty)
if (tty->driver.flush_buffer)
tty->driver.flush_buffer(tty);
-
- MOD_INC_USE_COUNT;
+
return 0;
}
@@ -317,8 +314,6 @@ static void hci_uart_tty_close(struct tty_struct *tty)
hu->proto->close(hu);
hci_unregister_dev(hdev);
}
-
- MOD_DEC_USE_COUNT;
}
}
@@ -411,11 +406,13 @@ static int hci_uart_register_dev(struct hci_uart *hu)
hdev->send = hci_uart_send_frame;
hdev->destruct = hci_uart_destruct;
+ hdev->owner = THIS_MODULE;
+
if (hci_register_dev(hdev) < 0) {
BT_ERR("Can't register HCI device %s", hdev->name);
return -ENODEV;
}
- MOD_INC_USE_COUNT;
+
return 0;
}
diff --git a/drivers/bluetooth/hci_usb.c b/drivers/bluetooth/hci_usb.c
index dcc257777929..9a48c7f957b7 100644
--- a/drivers/bluetooth/hci_usb.c
+++ b/drivers/bluetooth/hci_usb.c
@@ -207,18 +207,15 @@ static int hci_usb_open(struct hci_dev *hdev)
if (test_and_set_bit(HCI_RUNNING, &hdev->flags))
return 0;
- MOD_INC_USE_COUNT;
-
write_lock_irqsave(&husb->completion_lock, flags);
err = hci_usb_enable_intr(husb);
if (!err) {
for (i = 0; i < HCI_MAX_BULK_RX; i++)
hci_usb_rx_submit(husb, NULL);
- } else {
+ } else
clear_bit(HCI_RUNNING, &hdev->flags);
- MOD_DEC_USE_COUNT;
- }
+
write_unlock_irqrestore(&husb->completion_lock, flags);
return err;
@@ -271,8 +268,6 @@ static int hci_usb_close(struct hci_dev *hdev)
hci_usb_flush(hdev);
write_unlock_irqrestore(&husb->completion_lock, flags);
-
- MOD_DEC_USE_COUNT;
return 0;
}
@@ -758,6 +753,8 @@ int hci_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
hdev->send = hci_usb_send_frame;
hdev->destruct = hci_usb_destruct;
+ hdev->owner = THIS_MODULE;
+
if (hci_register_dev(hdev) < 0) {
BT_ERR("Can't register HCI device");
goto probe_error;
diff --git a/drivers/bluetooth/hci_vhci.c b/drivers/bluetooth/hci_vhci.c
index b99591b049bc..60b4d6e6c3f9 100644
--- a/drivers/bluetooth/hci_vhci.c
+++ b/drivers/bluetooth/hci_vhci.c
@@ -84,8 +84,6 @@ static void hci_vhci_destruct(struct hci_dev *hdev)
vhci = (struct hci_vhci_struct *) hdev->driver_data;
kfree(vhci);
-
- MOD_DEC_USE_COUNT;
}
static int hci_vhci_send_frame(struct sk_buff *skb)
@@ -288,11 +286,12 @@ static int hci_vhci_chr_open(struct inode *inode, struct file * file)
hdev->send = hci_vhci_send_frame;
hdev->destruct = hci_vhci_destruct;
+ hdev->owner = THIS_MODULE;
+
if (hci_register_dev(hdev) < 0) {
kfree(hci_vhci);
return -EBUSY;
}
- MOD_INC_USE_COUNT;
file->private_data = hci_vhci;
return 0;
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 852e6ef40901..d83017cc3ebb 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -118,6 +118,8 @@ struct hci_dev {
struct proc_dir_entry *proc;
#endif
+ struct module *owner;
+
int (*open)(struct hci_dev *hdev);
int (*close)(struct hci_dev *hdev);
int (*flush)(struct hci_dev *hdev);
@@ -299,12 +301,30 @@ static inline void hci_sched_tx(struct hci_dev *hdev)
}
/* ----- HCI Devices ----- */
-static inline void hci_dev_put(struct hci_dev *d)
-{
+static inline void __hci_dev_put(struct hci_dev *d)
+{
if (atomic_dec_and_test(&d->refcnt))
d->destruct(d);
}
-#define hci_dev_hold(d) atomic_inc(&d->refcnt)
+
+static inline void hci_dev_put(struct hci_dev *d)
+{
+ __hci_dev_put(d);
+ module_put(d->owner);
+}
+
+static inline struct hci_dev *__hci_dev_hold(struct hci_dev *d)
+{
+ atomic_inc(&d->refcnt);
+ return d;
+}
+
+static inline struct hci_dev *hci_dev_hold(struct hci_dev *d)
+{
+ if (try_module_get(d->owner))
+ return __hci_dev_hold(d);
+ return NULL;
+}
#define hci_dev_lock(d) spin_lock(&d->lock)
#define hci_dev_unlock(d) spin_unlock(&d->lock)
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 2de4ce5edaf3..416b164db547 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -218,8 +218,7 @@ struct hci_dev *hci_get_route(bdaddr_t *dst, bdaddr_t *src)
read_lock_bh(&hci_dev_list_lock);
list_for_each(p, &hci_dev_list) {
- struct hci_dev *d;
- d = list_entry(p, struct hci_dev, list);
+ struct hci_dev *d = list_entry(p, struct hci_dev, list);
if (!test_bit(HCI_UP, &d->flags))
continue;
@@ -241,7 +240,7 @@ struct hci_dev *hci_get_route(bdaddr_t *dst, bdaddr_t *src)
}
if (hdev)
- hci_dev_hold(hdev);
+ hdev = hci_dev_hold(hdev);
read_unlock_bh(&hci_dev_list_lock);
return hdev;
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 1b40336b0ad4..eb0a978ddf62 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -287,10 +287,10 @@ static void hci_encrypt_req(struct hci_dev *hdev, unsigned long opt)
}
/* Get HCI device by index.
- * Device is locked on return. */
+ * Device is held on return. */
struct hci_dev *hci_dev_get(int index)
{
- struct hci_dev *hdev;
+ struct hci_dev *hdev = NULL;
struct list_head *p;
BT_DBG("%d", index);
@@ -300,14 +300,12 @@ struct hci_dev *hci_dev_get(int index)
read_lock(&hci_dev_list_lock);
list_for_each(p, &hci_dev_list) {
- hdev = list_entry(p, struct hci_dev, list);
- if (hdev->id == index) {
- hci_dev_hold(hdev);
- goto done;
+ struct hci_dev *d = list_entry(p, struct hci_dev, list);
+ if (d->id == index) {
+ hdev = hci_dev_hold(d);
+ break;
}
}
- hdev = NULL;
-done:
read_unlock(&hci_dev_list_lock);
return hdev;
}
@@ -483,6 +481,7 @@ int hci_dev_open(__u16 dev)
}
if (!ret) {
+ hci_dev_hold(hdev);
set_bit(HCI_UP, &hdev->flags);
hci_notify(hdev, HCI_DEV_UP);
} else {
@@ -567,6 +566,8 @@ static int hci_dev_do_close(struct hci_dev *hdev)
hdev->flags = 0;
hci_req_unlock(hdev);
+
+ hci_dev_put(hdev);
return 0;
}
@@ -790,7 +791,7 @@ int hci_register_dev(struct hci_dev *hdev)
struct list_head *head = &hci_dev_list, *p;
int id = 0;
- BT_DBG("%p name %s type %d", hdev, hdev->name, hdev->type);
+ BT_DBG("%p name %s type %d owner %p", hdev, hdev->name, hdev->type, hdev->owner);
if (!hdev->open || !hdev->close || !hdev->destruct)
return -EINVAL;
@@ -834,8 +835,6 @@ int hci_register_dev(struct hci_dev *hdev)
atomic_set(&hdev->promisc, 0);
- MOD_INC_USE_COUNT;
-
write_unlock_bh(&hci_dev_list_lock);
hci_dev_proc_init(hdev);
@@ -862,9 +861,7 @@ int hci_unregister_dev(struct hci_dev *hdev)
hci_notify(hdev, HCI_DEV_UNREG);
hci_run_hotplug(hdev->name, "unregister");
- hci_dev_put(hdev);
-
- MOD_DEC_USE_COUNT;
+ __hci_dev_put(hdev);
return 0;
}