aboutsummaryrefslogtreecommitdiffstats
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
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>
-rw-r--r--include/net/bluetooth/hci_core.h4
-rw-r--r--net/bluetooth/hci_core.c4
-rw-r--r--net/bluetooth/hci_event.c2
-rw-r--r--net/bluetooth/hci_sock.c51
-rw-r--r--net/bluetooth/mgmt.c2
5 files changed, 45 insertions, 18 deletions
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 2aafeb3a8793..9209e4c8a211 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -953,8 +953,8 @@ void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode);
953void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data); 953void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data);
954 954
955/* ----- HCI Sockets ----- */ 955/* ----- HCI Sockets ----- */
956void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb, 956void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb);
957 struct sock *skip_sk); 957void hci_send_to_control(struct sk_buff *skb, struct sock *skip_sk);
958 958
959/* Management interface */ 959/* Management interface */
960#define MGMT_ADDR_BREDR 0x00 960#define MGMT_ADDR_BREDR 0x00
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index fabca080ae70..638fa8c393d8 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -2131,7 +2131,7 @@ static int hci_send_frame(struct sk_buff *skb)
2131 /* Time stamp */ 2131 /* Time stamp */
2132 __net_timestamp(skb); 2132 __net_timestamp(skb);
2133 2133
2134 hci_send_to_sock(hdev, skb, NULL); 2134 hci_send_to_sock(hdev, skb);
2135 } 2135 }
2136 2136
2137 /* Get rid of skb owner, prior to sending to the driver. */ 2137 /* Get rid of skb owner, prior to sending to the driver. */
@@ -2818,7 +2818,7 @@ static void hci_rx_work(struct work_struct *work)
2818 while ((skb = skb_dequeue(&hdev->rx_q))) { 2818 while ((skb = skb_dequeue(&hdev->rx_q))) {
2819 if (atomic_read(&hdev->promisc)) { 2819 if (atomic_read(&hdev->promisc)) {
2820 /* Send copy to the sockets */ 2820 /* Send copy to the sockets */
2821 hci_send_to_sock(hdev, skb, NULL); 2821 hci_send_to_sock(hdev, skb);
2822 } 2822 }
2823 2823
2824 if (test_bit(HCI_RAW, &hdev->flags)) { 2824 if (test_bit(HCI_RAW, &hdev->flags)) {
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 04fb1f02dfcc..e69db4a7b3ef 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -3571,7 +3571,7 @@ void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data)
3571 3571
3572 bt_cb(skb)->pkt_type = HCI_EVENT_PKT; 3572 bt_cb(skb)->pkt_type = HCI_EVENT_PKT;
3573 skb->dev = (void *) hdev; 3573 skb->dev = (void *) hdev;
3574 hci_send_to_sock(hdev, skb, NULL); 3574 hci_send_to_sock(hdev, skb);
3575 kfree_skb(skb); 3575 kfree_skb(skb);
3576} 3576}
3577 3577
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
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 18d593f23934..1695d04d927d 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -924,7 +924,7 @@ static int mgmt_event(u16 event, struct hci_dev *hdev, void *data,
924 if (data) 924 if (data)
925 memcpy(skb_put(skb, data_len), data, data_len); 925 memcpy(skb_put(skb, data_len), data, data_len);
926 926
927 hci_send_to_sock(NULL, skb, skip_sk); 927 hci_send_to_control(skb, skip_sk);
928 kfree_skb(skb); 928 kfree_skb(skb);
929 929
930 return 0; 930 return 0;