diff options
author | Marcel Holtmann <marcel@holtmann.org> | 2012-02-20 08:50:37 -0500 |
---|---|---|
committer | Johan Hedberg <johan.hedberg@intel.com> | 2012-02-20 08:59:22 -0500 |
commit | 040030ef7d907107e6489b39da518bdf94136d68 (patch) | |
tree | 79617d057852bc0293a63d9a176ca73972404824 | |
parent | e0edf3733fb62f91bbb8ec3fab4a90b0ac2dd037 (diff) |
Bluetooth: Remove HCI notifier handling
The HCI notifier handling was never used outside of Bluetooth core layer
and thus remove it and replace it with direct function calls. Also move
the stack internal event generation into the HCI socket layer.
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
-rw-r--r-- | include/net/bluetooth/hci_core.h | 7 | ||||
-rw-r--r-- | net/bluetooth/hci_conn.c | 1 | ||||
-rw-r--r-- | net/bluetooth/hci_core.c | 16 | ||||
-rw-r--r-- | net/bluetooth/hci_event.c | 29 | ||||
-rw-r--r-- | net/bluetooth/hci_sock.c | 105 |
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, | |||
941 | int hci_register_cb(struct hci_cb *hcb); | 941 | int hci_register_cb(struct hci_cb *hcb); |
942 | int hci_unregister_cb(struct hci_cb *hcb); | 942 | int hci_unregister_cb(struct hci_cb *hcb); |
943 | 943 | ||
944 | int hci_register_notifier(struct notifier_block *nb); | ||
945 | int hci_unregister_notifier(struct notifier_block *nb); | ||
946 | |||
947 | int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, void *param); | 944 | int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, void *param); |
948 | void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags); | 945 | void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags); |
949 | void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb); | 946 | void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb); |
950 | 947 | ||
951 | void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode); | 948 | void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode); |
952 | 949 | ||
953 | void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data); | ||
954 | |||
955 | /* ----- HCI Sockets ----- */ | 950 | /* ----- HCI Sockets ----- */ |
956 | void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb); | 951 | void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb); |
957 | void hci_send_to_control(struct sk_buff *skb, struct sock *skip_sk); | 952 | void hci_send_to_control(struct sk_buff *skb, struct sock *skip_sk); |
958 | 953 | ||
954 | void 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); | |||
69 | LIST_HEAD(hci_cb_list); | 68 | LIST_HEAD(hci_cb_list); |
70 | DEFINE_RWLOCK(hci_cb_list_lock); | 69 | DEFINE_RWLOCK(hci_cb_list_lock); |
71 | 70 | ||
72 | /* HCI notifiers list */ | ||
73 | static ATOMIC_NOTIFIER_HEAD(hci_notifier); | ||
74 | |||
75 | /* ---- HCI notifications ---- */ | 71 | /* ---- HCI notifications ---- */ |
76 | 72 | ||
77 | int hci_register_notifier(struct notifier_block *nb) | ||
78 | { | ||
79 | return atomic_notifier_chain_register(&hci_notifier, nb); | ||
80 | } | ||
81 | |||
82 | int hci_unregister_notifier(struct notifier_block *nb) | ||
83 | { | ||
84 | return atomic_notifier_chain_unregister(&hci_notifier, nb); | ||
85 | } | ||
86 | |||
87 | static void hci_notify(struct hci_dev *hdev, int event) | 73 | static 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 */ | ||
3551 | void 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 | |||
3578 | module_param(enable_le, bool, 0644); | 3549 | module_param(enable_le, bool, 0644); |
3579 | MODULE_PARM_DESC(enable_le, "Enable LE support"); | 3550 | MODULE_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 */ | ||
193 | static 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 | |||
220 | void 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 | |||
192 | static int hci_sock_release(struct socket *sock) | 253 | static 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 | ||
824 | static 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 | |||
860 | static const struct net_proto_family hci_sock_family_ops = { | 885 | static 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 | ||
866 | static struct notifier_block hci_sock_nblock = { | ||
867 | .notifier_call = hci_sock_dev_event | ||
868 | }; | ||
869 | |||
870 | int __init hci_sock_init(void) | 891 | int __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 | ||