diff options
author | Johan Hedberg <johan.hedberg@intel.com> | 2015-04-02 06:41:12 -0400 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2015-04-02 10:09:28 -0400 |
commit | 757aa0b56da5d1089c55bf349fa15836dae22b6f (patch) | |
tree | 7d5b7dd93801eaac90f3c8323ebf1a033349db6e /net/bluetooth | |
parent | abe66a4d036933c7376b40b0d7bb5de0458331aa (diff) |
Bluetooth: Move hci_get_cmd_complete() to hci_event.c
To make the hci_req_run_skb() API consistent with hci_cmd_sync_ev()
the callback should receive the cmd_complete parameters in the 'normal'
case and the full HCI event if a special event was expected. This patch
moves the hci_get_cmd_complete() function from hci_core.c to hci_event.c
where it's used to strip the skb from the needed headers before passing
it on to the callback.
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net/bluetooth')
-rw-r--r-- | net/bluetooth/hci_core.c | 52 | ||||
-rw-r--r-- | net/bluetooth/hci_event.c | 57 |
2 files changed, 58 insertions, 51 deletions
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index fda23720e7b8..46b114c0140b 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c | |||
@@ -166,53 +166,6 @@ static void hci_req_cancel(struct hci_dev *hdev, int err) | |||
166 | } | 166 | } |
167 | } | 167 | } |
168 | 168 | ||
169 | static struct sk_buff *hci_get_cmd_complete(struct hci_dev *hdev, u16 opcode, | ||
170 | u8 event, struct sk_buff *skb) | ||
171 | { | ||
172 | struct hci_ev_cmd_complete *ev; | ||
173 | struct hci_event_hdr *hdr; | ||
174 | |||
175 | if (!skb) | ||
176 | return ERR_PTR(-ENODATA); | ||
177 | |||
178 | if (skb->len < sizeof(*hdr)) { | ||
179 | BT_ERR("Too short HCI event"); | ||
180 | goto failed; | ||
181 | } | ||
182 | |||
183 | hdr = (void *) skb->data; | ||
184 | skb_pull(skb, HCI_EVENT_HDR_SIZE); | ||
185 | |||
186 | if (event) { | ||
187 | if (hdr->evt != event) | ||
188 | goto failed; | ||
189 | return skb; | ||
190 | } | ||
191 | |||
192 | if (hdr->evt != HCI_EV_CMD_COMPLETE) { | ||
193 | BT_DBG("Last event is not cmd complete (0x%2.2x)", hdr->evt); | ||
194 | goto failed; | ||
195 | } | ||
196 | |||
197 | if (skb->len < sizeof(*ev)) { | ||
198 | BT_ERR("Too short cmd_complete event"); | ||
199 | goto failed; | ||
200 | } | ||
201 | |||
202 | ev = (void *) skb->data; | ||
203 | skb_pull(skb, sizeof(*ev)); | ||
204 | |||
205 | if (opcode == __le16_to_cpu(ev->opcode)) | ||
206 | return skb; | ||
207 | |||
208 | BT_DBG("opcode doesn't match (0x%2.2x != 0x%2.2x)", opcode, | ||
209 | __le16_to_cpu(ev->opcode)); | ||
210 | |||
211 | failed: | ||
212 | kfree_skb(skb); | ||
213 | return ERR_PTR(-ENODATA); | ||
214 | } | ||
215 | |||
216 | struct sk_buff *__hci_cmd_sync_ev(struct hci_dev *hdev, u16 opcode, u32 plen, | 169 | struct sk_buff *__hci_cmd_sync_ev(struct hci_dev *hdev, u16 opcode, u32 plen, |
217 | const void *param, u8 event, u32 timeout) | 170 | const void *param, u8 event, u32 timeout) |
218 | { | 171 | { |
@@ -271,7 +224,10 @@ struct sk_buff *__hci_cmd_sync_ev(struct hci_dev *hdev, u16 opcode, u32 plen, | |||
271 | return ERR_PTR(err); | 224 | return ERR_PTR(err); |
272 | } | 225 | } |
273 | 226 | ||
274 | return hci_get_cmd_complete(hdev, opcode, event, skb); | 227 | if (!skb) |
228 | return ERR_PTR(-ENODATA); | ||
229 | |||
230 | return skb; | ||
275 | } | 231 | } |
276 | EXPORT_SYMBOL(__hci_cmd_sync_ev); | 232 | EXPORT_SYMBOL(__hci_cmd_sync_ev); |
277 | 233 | ||
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index dc9547c11c45..c2483cb6ffbd 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c | |||
@@ -5043,13 +5043,58 @@ static void hci_chan_selected_evt(struct hci_dev *hdev, struct sk_buff *skb) | |||
5043 | amp_read_loc_assoc_final_data(hdev, hcon); | 5043 | amp_read_loc_assoc_final_data(hdev, hcon); |
5044 | } | 5044 | } |
5045 | 5045 | ||
5046 | static bool hci_get_cmd_complete(struct hci_dev *hdev, u16 opcode, | ||
5047 | u8 event, struct sk_buff *skb) | ||
5048 | { | ||
5049 | struct hci_ev_cmd_complete *ev; | ||
5050 | struct hci_event_hdr *hdr; | ||
5051 | |||
5052 | if (!skb) | ||
5053 | return false; | ||
5054 | |||
5055 | if (skb->len < sizeof(*hdr)) { | ||
5056 | BT_ERR("Too short HCI event"); | ||
5057 | return false; | ||
5058 | } | ||
5059 | |||
5060 | hdr = (void *) skb->data; | ||
5061 | skb_pull(skb, HCI_EVENT_HDR_SIZE); | ||
5062 | |||
5063 | if (event) { | ||
5064 | if (hdr->evt != event) | ||
5065 | return false; | ||
5066 | return true; | ||
5067 | } | ||
5068 | |||
5069 | if (hdr->evt != HCI_EV_CMD_COMPLETE) { | ||
5070 | BT_DBG("Last event is not cmd complete (0x%2.2x)", hdr->evt); | ||
5071 | return false; | ||
5072 | } | ||
5073 | |||
5074 | if (skb->len < sizeof(*ev)) { | ||
5075 | BT_ERR("Too short cmd_complete event"); | ||
5076 | return false; | ||
5077 | } | ||
5078 | |||
5079 | ev = (void *) skb->data; | ||
5080 | skb_pull(skb, sizeof(*ev)); | ||
5081 | |||
5082 | if (opcode != __le16_to_cpu(ev->opcode)) { | ||
5083 | BT_DBG("opcode doesn't match (0x%2.2x != 0x%2.2x)", opcode, | ||
5084 | __le16_to_cpu(ev->opcode)); | ||
5085 | return false; | ||
5086 | } | ||
5087 | |||
5088 | return true; | ||
5089 | } | ||
5090 | |||
5046 | void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb) | 5091 | void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb) |
5047 | { | 5092 | { |
5048 | struct hci_event_hdr *hdr = (void *) skb->data; | 5093 | struct hci_event_hdr *hdr = (void *) skb->data; |
5049 | hci_req_complete_t req_complete = NULL; | 5094 | hci_req_complete_t req_complete = NULL; |
5050 | hci_req_complete_skb_t req_complete_skb = NULL; | 5095 | hci_req_complete_skb_t req_complete_skb = NULL; |
5051 | struct sk_buff *orig_skb = NULL; | 5096 | struct sk_buff *orig_skb = NULL; |
5052 | u8 status = 0, event = hdr->evt; | 5097 | u8 status = 0, event = hdr->evt, req_evt = 0; |
5053 | u16 opcode = HCI_OP_NOP; | 5098 | u16 opcode = HCI_OP_NOP; |
5054 | 5099 | ||
5055 | if (hdev->sent_cmd && bt_cb(hdev->sent_cmd)->req.event == event) { | 5100 | if (hdev->sent_cmd && bt_cb(hdev->sent_cmd)->req.event == event) { |
@@ -5057,6 +5102,7 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb) | |||
5057 | opcode = __le16_to_cpu(cmd_hdr->opcode); | 5102 | opcode = __le16_to_cpu(cmd_hdr->opcode); |
5058 | hci_req_cmd_complete(hdev, opcode, status, &req_complete, | 5103 | hci_req_cmd_complete(hdev, opcode, status, &req_complete, |
5059 | &req_complete_skb); | 5104 | &req_complete_skb); |
5105 | req_evt = event; | ||
5060 | } | 5106 | } |
5061 | 5107 | ||
5062 | /* If it looks like we might end up having to call | 5108 | /* If it looks like we might end up having to call |
@@ -5250,10 +5296,15 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb) | |||
5250 | break; | 5296 | break; |
5251 | } | 5297 | } |
5252 | 5298 | ||
5253 | if (req_complete) | 5299 | if (req_complete) { |
5254 | req_complete(hdev, status, opcode); | 5300 | req_complete(hdev, status, opcode); |
5255 | else if (req_complete_skb) | 5301 | } else if (req_complete_skb) { |
5302 | if (!hci_get_cmd_complete(hdev, opcode, req_evt, orig_skb)) { | ||
5303 | kfree_skb(orig_skb); | ||
5304 | orig_skb = NULL; | ||
5305 | } | ||
5256 | req_complete_skb(hdev, status, opcode, orig_skb); | 5306 | req_complete_skb(hdev, status, opcode, orig_skb); |
5307 | } | ||
5257 | 5308 | ||
5258 | kfree_skb(orig_skb); | 5309 | kfree_skb(orig_skb); |
5259 | kfree_skb(skb); | 5310 | kfree_skb(skb); |