aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/bluetooth/hci_core.h7
-rw-r--r--net/bluetooth/hci_conn.c1
-rw-r--r--net/bluetooth/hci_core.c16
-rw-r--r--net/bluetooth/hci_event.c29
-rw-r--r--net/bluetooth/hci_sock.c105
5 files changed, 64 insertions, 94 deletions
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 9209e4c8a211..41adae509e9c 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -941,21 +941,18 @@ static inline u16 eir_append_data(u8 *eir, u16 eir_len, u8 type, u8 *data,
941int hci_register_cb(struct hci_cb *hcb); 941int hci_register_cb(struct hci_cb *hcb);
942int hci_unregister_cb(struct hci_cb *hcb); 942int hci_unregister_cb(struct hci_cb *hcb);
943 943
944int hci_register_notifier(struct notifier_block *nb);
945int hci_unregister_notifier(struct notifier_block *nb);
946
947int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, void *param); 944int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, void *param);
948void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags); 945void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags);
949void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb); 946void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb);
950 947
951void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode); 948void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode);
952 949
953void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data);
954
955/* ----- HCI Sockets ----- */ 950/* ----- HCI Sockets ----- */
956void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb); 951void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb);
957void hci_send_to_control(struct sk_buff *skb, struct sock *skip_sk); 952void hci_send_to_control(struct sk_buff *skb, struct sock *skip_sk);
958 953
954void hci_sock_dev_event(struct hci_dev *hdev, int event);
955
959/* Management interface */ 956/* Management interface */
960#define MGMT_ADDR_BREDR 0x00 957#define MGMT_ADDR_BREDR 0x00
961#define MGMT_ADDR_LE_PUBLIC 0x01 958#define MGMT_ADDR_LE_PUBLIC 0x01
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 8549d04e3313..3c68e606d5e5 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -35,7 +35,6 @@
35#include <linux/init.h> 35#include <linux/init.h>
36#include <linux/skbuff.h> 36#include <linux/skbuff.h>
37#include <linux/interrupt.h> 37#include <linux/interrupt.h>
38#include <linux/notifier.h>
39#include <net/sock.h> 38#include <net/sock.h>
40 39
41#include <asm/system.h> 40#include <asm/system.h>
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 638fa8c393d8..47217281d9ac 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -40,7 +40,6 @@
40#include <linux/skbuff.h> 40#include <linux/skbuff.h>
41#include <linux/workqueue.h> 41#include <linux/workqueue.h>
42#include <linux/interrupt.h> 42#include <linux/interrupt.h>
43#include <linux/notifier.h>
44#include <linux/rfkill.h> 43#include <linux/rfkill.h>
45#include <linux/timer.h> 44#include <linux/timer.h>
46#include <linux/crypto.h> 45#include <linux/crypto.h>
@@ -69,24 +68,11 @@ DEFINE_RWLOCK(hci_dev_list_lock);
69LIST_HEAD(hci_cb_list); 68LIST_HEAD(hci_cb_list);
70DEFINE_RWLOCK(hci_cb_list_lock); 69DEFINE_RWLOCK(hci_cb_list_lock);
71 70
72/* HCI notifiers list */
73static ATOMIC_NOTIFIER_HEAD(hci_notifier);
74
75/* ---- HCI notifications ---- */ 71/* ---- HCI notifications ---- */
76 72
77int hci_register_notifier(struct notifier_block *nb)
78{
79 return atomic_notifier_chain_register(&hci_notifier, nb);
80}
81
82int hci_unregister_notifier(struct notifier_block *nb)
83{
84 return atomic_notifier_chain_unregister(&hci_notifier, nb);
85}
86
87static void hci_notify(struct hci_dev *hdev, int event) 73static void hci_notify(struct hci_dev *hdev, int event)
88{ 74{
89 atomic_notifier_call_chain(&hci_notifier, event, hdev); 75 hci_sock_dev_event(hdev, event);
90} 76}
91 77
92/* ---- HCI requests ---- */ 78/* ---- HCI requests ---- */
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index e69db4a7b3ef..f00faf0ac32f 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -35,7 +35,6 @@
35#include <linux/init.h> 35#include <linux/init.h>
36#include <linux/skbuff.h> 36#include <linux/skbuff.h>
37#include <linux/interrupt.h> 37#include <linux/interrupt.h>
38#include <linux/notifier.h>
39#include <net/sock.h> 38#include <net/sock.h>
40 39
41#include <asm/system.h> 40#include <asm/system.h>
@@ -3547,33 +3546,5 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
3547 hdev->stat.evt_rx++; 3546 hdev->stat.evt_rx++;
3548} 3547}
3549 3548
3550/* Generate internal stack event */
3551void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data)
3552{
3553 struct hci_event_hdr *hdr;
3554 struct hci_ev_stack_internal *ev;
3555 struct sk_buff *skb;
3556
3557 skb = bt_skb_alloc(HCI_EVENT_HDR_SIZE + sizeof(*ev) + dlen, GFP_ATOMIC);
3558 if (!skb)
3559 return;
3560
3561 hdr = (void *) skb_put(skb, HCI_EVENT_HDR_SIZE);
3562 hdr->evt = HCI_EV_STACK_INTERNAL;
3563 hdr->plen = sizeof(*ev) + dlen;
3564
3565 ev = (void *) skb_put(skb, sizeof(*ev) + dlen);
3566 ev->type = type;
3567 memcpy(ev->data, data, dlen);
3568
3569 bt_cb(skb)->incoming = 1;
3570 __net_timestamp(skb);
3571
3572 bt_cb(skb)->pkt_type = HCI_EVENT_PKT;
3573 skb->dev = (void *) hdev;
3574 hci_send_to_sock(hdev, skb);
3575 kfree_skb(skb);
3576}
3577
3578module_param(enable_le, bool, 0644); 3549module_param(enable_le, bool, 0644);
3579MODULE_PARM_DESC(enable_le, "Enable LE support"); 3550MODULE_PARM_DESC(enable_le, "Enable LE support");
diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c
index cf940bd7a2b0..14727cb43f63 100644
--- a/net/bluetooth/hci_sock.c
+++ b/net/bluetooth/hci_sock.c
@@ -189,6 +189,67 @@ void hci_send_to_control(struct sk_buff *skb, struct sock *skip_sk)
189 read_unlock(&hci_sk_list.lock); 189 read_unlock(&hci_sk_list.lock);
190} 190}
191 191
192/* Generate internal stack event */
193static void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data)
194{
195 struct hci_event_hdr *hdr;
196 struct hci_ev_stack_internal *ev;
197 struct sk_buff *skb;
198
199 skb = bt_skb_alloc(HCI_EVENT_HDR_SIZE + sizeof(*ev) + dlen, GFP_ATOMIC);
200 if (!skb)
201 return;
202
203 hdr = (void *) skb_put(skb, HCI_EVENT_HDR_SIZE);
204 hdr->evt = HCI_EV_STACK_INTERNAL;
205 hdr->plen = sizeof(*ev) + dlen;
206
207 ev = (void *) skb_put(skb, sizeof(*ev) + dlen);
208 ev->type = type;
209 memcpy(ev->data, data, dlen);
210
211 bt_cb(skb)->incoming = 1;
212 __net_timestamp(skb);
213
214 bt_cb(skb)->pkt_type = HCI_EVENT_PKT;
215 skb->dev = (void *) hdev;
216 hci_send_to_sock(hdev, skb);
217 kfree_skb(skb);
218}
219
220void hci_sock_dev_event(struct hci_dev *hdev, int event)
221{
222 struct hci_ev_si_device ev;
223
224 BT_DBG("hdev %s event %d", hdev->name, event);
225
226 /* Send event to sockets */
227 ev.event = event;
228 ev.dev_id = hdev->id;
229 hci_si_event(NULL, HCI_EV_SI_DEVICE, sizeof(ev), &ev);
230
231 if (event == HCI_DEV_UNREG) {
232 struct sock *sk;
233 struct hlist_node *node;
234
235 /* Detach sockets from device */
236 read_lock(&hci_sk_list.lock);
237 sk_for_each(sk, node, &hci_sk_list.head) {
238 bh_lock_sock_nested(sk);
239 if (hci_pi(sk)->hdev == hdev) {
240 hci_pi(sk)->hdev = NULL;
241 sk->sk_err = EPIPE;
242 sk->sk_state = BT_OPEN;
243 sk->sk_state_change(sk);
244
245 hci_dev_put(hdev);
246 }
247 bh_unlock_sock(sk);
248 }
249 read_unlock(&hci_sk_list.lock);
250 }
251}
252
192static int hci_sock_release(struct socket *sock) 253static int hci_sock_release(struct socket *sock)
193{ 254{
194 struct sock *sk = sock->sk; 255 struct sock *sk = sock->sk;
@@ -821,52 +882,12 @@ static int hci_sock_create(struct net *net, struct socket *sock, int protocol,
821 return 0; 882 return 0;
822} 883}
823 884
824static int hci_sock_dev_event(struct notifier_block *this, unsigned long event, void *ptr)
825{
826 struct hci_dev *hdev = (struct hci_dev *) ptr;
827 struct hci_ev_si_device ev;
828
829 BT_DBG("hdev %s event %ld", hdev->name, event);
830
831 /* Send event to sockets */
832 ev.event = event;
833 ev.dev_id = hdev->id;
834 hci_si_event(NULL, HCI_EV_SI_DEVICE, sizeof(ev), &ev);
835
836 if (event == HCI_DEV_UNREG) {
837 struct sock *sk;
838 struct hlist_node *node;
839
840 /* Detach sockets from device */
841 read_lock(&hci_sk_list.lock);
842 sk_for_each(sk, node, &hci_sk_list.head) {
843 bh_lock_sock_nested(sk);
844 if (hci_pi(sk)->hdev == hdev) {
845 hci_pi(sk)->hdev = NULL;
846 sk->sk_err = EPIPE;
847 sk->sk_state = BT_OPEN;
848 sk->sk_state_change(sk);
849
850 hci_dev_put(hdev);
851 }
852 bh_unlock_sock(sk);
853 }
854 read_unlock(&hci_sk_list.lock);
855 }
856
857 return NOTIFY_DONE;
858}
859
860static const struct net_proto_family hci_sock_family_ops = { 885static const struct net_proto_family hci_sock_family_ops = {
861 .family = PF_BLUETOOTH, 886 .family = PF_BLUETOOTH,
862 .owner = THIS_MODULE, 887 .owner = THIS_MODULE,
863 .create = hci_sock_create, 888 .create = hci_sock_create,
864}; 889};
865 890
866static struct notifier_block hci_sock_nblock = {
867 .notifier_call = hci_sock_dev_event
868};
869
870int __init hci_sock_init(void) 891int __init hci_sock_init(void)
871{ 892{
872 int err; 893 int err;
@@ -879,8 +900,6 @@ int __init hci_sock_init(void)
879 if (err < 0) 900 if (err < 0)
880 goto error; 901 goto error;
881 902
882 hci_register_notifier(&hci_sock_nblock);
883
884 BT_INFO("HCI socket layer initialized"); 903 BT_INFO("HCI socket layer initialized");
885 904
886 return 0; 905 return 0;
@@ -896,8 +915,6 @@ void hci_sock_cleanup(void)
896 if (bt_sock_unregister(BTPROTO_HCI) < 0) 915 if (bt_sock_unregister(BTPROTO_HCI) < 0)
897 BT_ERR("HCI socket unregistration failed"); 916 BT_ERR("HCI socket unregistration failed");
898 917
899 hci_unregister_notifier(&hci_sock_nblock);
900
901 proto_unregister(&hci_sk_proto); 918 proto_unregister(&hci_sk_proto);
902} 919}
903 920