diff options
author | Marcel Holtmann <marcel@holtmann.org> | 2012-02-20 08:50:30 -0500 |
---|---|---|
committer | Johan Hedberg <johan.hedberg@intel.com> | 2012-02-20 08:55:11 -0500 |
commit | 470fe1b540fb50ba8ce01e0ac985602e8fbb108c (patch) | |
tree | c2c0b9b33c1a596c032e0eb330b0d6a66fd9c56c | |
parent | 48c7aba91f372251867d15efc9cf694ceee2de02 (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.h | 4 | ||||
-rw-r--r-- | net/bluetooth/hci_core.c | 4 | ||||
-rw-r--r-- | net/bluetooth/hci_event.c | 2 | ||||
-rw-r--r-- | net/bluetooth/hci_sock.c | 51 | ||||
-rw-r--r-- | net/bluetooth/mgmt.c | 2 |
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); | |||
953 | void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data); | 953 | void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data); |
954 | 954 | ||
955 | /* ----- HCI Sockets ----- */ | 955 | /* ----- HCI Sockets ----- */ |
956 | void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb, | 956 | void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb); |
957 | struct sock *skip_sk); | 957 | void 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 */ |
88 | void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb, | 88 | void 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 | ||
140 | clone: | ||
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 */ | ||
149 | void 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; |