aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth/hci_sock.c
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2012-02-20 08:50:30 -0500
committerJohan Hedberg <johan.hedberg@intel.com>2012-02-20 08:55:11 -0500
commit470fe1b540fb50ba8ce01e0ac985602e8fbb108c (patch)
treec2c0b9b33c1a596c032e0eb330b0d6a66fd9c56c /net/bluetooth/hci_sock.c
parent48c7aba91f372251867d15efc9cf694ceee2de02 (diff)
Bluetooth: Split sending for HCI raw and control sockets
The sending functions for HCI raw and control sockets have nothing in common except that they iterate over the socket list. Split them into two so they can do their job more efficient. In addition the code becomes more readable. Signed-off-by: Marcel Holtmann <marcel@holtmann.org> Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Diffstat (limited to 'net/bluetooth/hci_sock.c')
-rw-r--r--net/bluetooth/hci_sock.c51
1 files changed, 39 insertions, 12 deletions
diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c
index 9e854d9fb460..b5b3bc8d2848 100644
--- a/net/bluetooth/hci_sock.c
+++ b/net/bluetooth/hci_sock.c
@@ -85,8 +85,7 @@ static struct bt_sock_list hci_sk_list = {
85}; 85};
86 86
87/* Send frame to RAW socket */ 87/* Send frame to RAW socket */
88void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb, 88void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb)
89 struct sock *skip_sk)
90{ 89{
91 struct sock *sk; 90 struct sock *sk;
92 struct hlist_node *node; 91 struct hlist_node *node;
@@ -94,13 +93,11 @@ void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb,
94 BT_DBG("hdev %p len %d", hdev, skb->len); 93 BT_DBG("hdev %p len %d", hdev, skb->len);
95 94
96 read_lock(&hci_sk_list.lock); 95 read_lock(&hci_sk_list.lock);
96
97 sk_for_each(sk, node, &hci_sk_list.head) { 97 sk_for_each(sk, node, &hci_sk_list.head) {
98 struct hci_filter *flt; 98 struct hci_filter *flt;
99 struct sk_buff *nskb; 99 struct sk_buff *nskb;
100 100
101 if (sk == skip_sk)
102 continue;
103
104 if (sk->sk_state != BT_BOUND || hci_pi(sk)->hdev != hdev) 101 if (sk->sk_state != BT_BOUND || hci_pi(sk)->hdev != hdev)
105 continue; 102 continue;
106 103
@@ -108,12 +105,9 @@ void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb,
108 if (skb->sk == sk) 105 if (skb->sk == sk)
109 continue; 106 continue;
110 107
111 if (bt_cb(skb)->channel != hci_pi(sk)->channel) 108 if (hci_pi(sk)->channel != HCI_CHANNEL_RAW)
112 continue; 109 continue;
113 110
114 if (bt_cb(skb)->channel == HCI_CHANNEL_CONTROL)
115 goto clone;
116
117 /* Apply filter */ 111 /* Apply filter */
118 flt = &hci_pi(sk)->filter; 112 flt = &hci_pi(sk)->filter;
119 113
@@ -137,18 +131,51 @@ void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb,
137 continue; 131 continue;
138 } 132 }
139 133
140clone:
141 nskb = skb_clone(skb, GFP_ATOMIC); 134 nskb = skb_clone(skb, GFP_ATOMIC);
142 if (!nskb) 135 if (!nskb)
143 continue; 136 continue;
144 137
145 /* Put type byte before the data */ 138 /* Put type byte before the data */
146 if (bt_cb(skb)->channel == HCI_CHANNEL_RAW) 139 memcpy(skb_push(nskb, 1), &bt_cb(nskb)->pkt_type, 1);
147 memcpy(skb_push(nskb, 1), &bt_cb(nskb)->pkt_type, 1); 140
141 if (sock_queue_rcv_skb(sk, nskb))
142 kfree_skb(nskb);
143 }
144
145 read_unlock(&hci_sk_list.lock);
146}
147
148/* Send frame to control socket */
149void hci_send_to_control(struct sk_buff *skb, struct sock *skip_sk)
150{
151 struct sock *sk;
152 struct hlist_node *node;
153
154 BT_DBG("len %d", skb->len);
155
156 read_lock(&hci_sk_list.lock);
157
158 sk_for_each(sk, node, &hci_sk_list.head) {
159 struct sk_buff *nskb;
160
161 /* Skip the original socket */
162 if (sk == skip_sk)
163 continue;
164
165 if (sk->sk_state != BT_BOUND)
166 continue;
167
168 if (hci_pi(sk)->channel != HCI_CHANNEL_CONTROL)
169 continue;
170
171 nskb = skb_clone(skb, GFP_ATOMIC);
172 if (!nskb)
173 continue;
148 174
149 if (sock_queue_rcv_skb(sk, nskb)) 175 if (sock_queue_rcv_skb(sk, nskb))
150 kfree_skb(nskb); 176 kfree_skb(nskb);
151 } 177 }
178
152 read_unlock(&hci_sk_list.lock); 179 read_unlock(&hci_sk_list.lock);
153} 180}
154 181