diff options
| -rw-r--r-- | drivers/bluetooth/bluecard_cs.c | 6 | ||||
| -rw-r--r-- | drivers/bluetooth/bt3c_cs.c | 6 | ||||
| -rw-r--r-- | drivers/bluetooth/btuart_cs.c | 6 | ||||
| -rw-r--r-- | drivers/bluetooth/dtl1_cs.c | 6 | ||||
| -rw-r--r-- | drivers/bluetooth/hci_ldisc.c | 11 | ||||
| -rw-r--r-- | drivers/bluetooth/hci_usb.c | 11 | ||||
| -rw-r--r-- | drivers/bluetooth/hci_vhci.c | 5 | ||||
| -rw-r--r-- | include/net/bluetooth/hci_core.h | 26 | ||||
| -rw-r--r-- | net/bluetooth/hci_conn.c | 5 | ||||
| -rw-r--r-- | net/bluetooth/hci_core.c | 25 |
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; } |
