aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@intel.com>2015-04-02 06:41:08 -0400
committerMarcel Holtmann <marcel@holtmann.org>2015-04-02 10:09:27 -0400
commite6214487492566b15ff24e97c6747bb2e5d9e040 (patch)
tree6c6a1538555999336070eedfa4648d7463ef3771 /net/bluetooth
parent444c6dd54d81edf81c606f571cb52eff4d47fa99 (diff)
Bluetooth: Add second hci_request callback option for full skb
This patch adds a second possible callback for HCI requests where the callback will receive the full skb of the last successfully completed HCI command. This API is useful for cases where we want to use a request to read some data and the existing hci_event.c handlers do not store it e.g. in the hci_dev struct. The reason the patch is a bit bigger than just adding the new API is because the hci_req_cmd_complete() functions required some refactoring to enable it: now hci_req_cmd_complete() is simply used to request the callback pointers if any, and the actual calling of them happens from a single place at the end of hci_event_packet(). The reason for this is that we need to pass the original skb (without any skb_pull, etc modifications done to it) and it's simplest to keep track of it within the hci_event_packet() function. 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.c30
-rw-r--r--net/bluetooth/hci_event.c76
-rw-r--r--net/bluetooth/hci_request.c14
-rw-r--r--net/bluetooth/hci_request.h5
4 files changed, 81 insertions, 44 deletions
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 246d7eca5d29..8af3af324eee 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -4288,9 +4288,10 @@ static void hci_resend_last(struct hci_dev *hdev)
4288 queue_work(hdev->workqueue, &hdev->cmd_work); 4288 queue_work(hdev->workqueue, &hdev->cmd_work);
4289} 4289}
4290 4290
4291void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status) 4291void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status,
4292 hci_req_complete_t *req_complete,
4293 hci_req_complete_skb_t *req_complete_skb)
4292{ 4294{
4293 hci_req_complete_t req_complete = NULL;
4294 struct sk_buff *skb; 4295 struct sk_buff *skb;
4295 unsigned long flags; 4296 unsigned long flags;
4296 4297
@@ -4322,18 +4323,14 @@ void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status)
4322 * callback would be found in hdev->sent_cmd instead of the 4323 * callback would be found in hdev->sent_cmd instead of the
4323 * command queue (hdev->cmd_q). 4324 * command queue (hdev->cmd_q).
4324 */ 4325 */
4325 if (hdev->sent_cmd) { 4326 if (bt_cb(hdev->sent_cmd)->req.complete) {
4326 req_complete = bt_cb(hdev->sent_cmd)->req.complete; 4327 *req_complete = bt_cb(hdev->sent_cmd)->req.complete;
4327 4328 return;
4328 if (req_complete) { 4329 }
4329 /* We must set the complete callback to NULL to
4330 * avoid calling the callback more than once if
4331 * this function gets called again.
4332 */
4333 bt_cb(hdev->sent_cmd)->req.complete = NULL;
4334 4330
4335 goto call_complete; 4331 if (bt_cb(hdev->sent_cmd)->req.complete_skb) {
4336 } 4332 *req_complete_skb = bt_cb(hdev->sent_cmd)->req.complete_skb;
4333 return;
4337 } 4334 }
4338 4335
4339 /* Remove all pending commands belonging to this request */ 4336 /* Remove all pending commands belonging to this request */
@@ -4344,14 +4341,11 @@ void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status)
4344 break; 4341 break;
4345 } 4342 }
4346 4343
4347 req_complete = bt_cb(skb)->req.complete; 4344 *req_complete = bt_cb(skb)->req.complete;
4345 *req_complete_skb = bt_cb(skb)->req.complete_skb;
4348 kfree_skb(skb); 4346 kfree_skb(skb);
4349 } 4347 }
4350 spin_unlock_irqrestore(&hdev->cmd_q.lock, flags); 4348 spin_unlock_irqrestore(&hdev->cmd_q.lock, flags);
4351
4352call_complete:
4353 if (req_complete)
4354 req_complete(hdev, status, status ? opcode : HCI_OP_NOP);
4355} 4349}
4356 4350
4357static void hci_rx_work(struct work_struct *work) 4351static void hci_rx_work(struct work_struct *work)
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 87e5bee36408..7c69eb3629b7 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -2731,17 +2731,19 @@ unlock:
2731 hci_dev_unlock(hdev); 2731 hci_dev_unlock(hdev);
2732} 2732}
2733 2733
2734static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) 2734static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb,
2735 u16 *opcode, u8 *status,
2736 hci_req_complete_t *req_complete,
2737 hci_req_complete_skb_t *req_complete_skb)
2735{ 2738{
2736 struct hci_ev_cmd_complete *ev = (void *) skb->data; 2739 struct hci_ev_cmd_complete *ev = (void *) skb->data;
2737 u8 status = skb->data[sizeof(*ev)];
2738 __u16 opcode;
2739 2740
2740 skb_pull(skb, sizeof(*ev)); 2741 *opcode = __le16_to_cpu(ev->opcode);
2742 *status = skb->data[sizeof(*ev)];
2741 2743
2742 opcode = __le16_to_cpu(ev->opcode); 2744 skb_pull(skb, sizeof(*ev));
2743 2745
2744 switch (opcode) { 2746 switch (*opcode) {
2745 case HCI_OP_INQUIRY_CANCEL: 2747 case HCI_OP_INQUIRY_CANCEL:
2746 hci_cc_inquiry_cancel(hdev, skb); 2748 hci_cc_inquiry_cancel(hdev, skb);
2747 break; 2749 break;
@@ -3019,32 +3021,36 @@ static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
3019 break; 3021 break;
3020 3022
3021 default: 3023 default:
3022 BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode); 3024 BT_DBG("%s opcode 0x%4.4x", hdev->name, *opcode);
3023 break; 3025 break;
3024 } 3026 }
3025 3027
3026 if (opcode != HCI_OP_NOP) 3028 if (*opcode != HCI_OP_NOP)
3027 cancel_delayed_work(&hdev->cmd_timer); 3029 cancel_delayed_work(&hdev->cmd_timer);
3028 3030
3029 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) 3031 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags))
3030 atomic_set(&hdev->cmd_cnt, 1); 3032 atomic_set(&hdev->cmd_cnt, 1);
3031 3033
3032 hci_req_cmd_complete(hdev, opcode, status); 3034 hci_req_cmd_complete(hdev, *opcode, *status, req_complete,
3035 req_complete_skb);
3033 3036
3034 if (atomic_read(&hdev->cmd_cnt) && !skb_queue_empty(&hdev->cmd_q)) 3037 if (atomic_read(&hdev->cmd_cnt) && !skb_queue_empty(&hdev->cmd_q))
3035 queue_work(hdev->workqueue, &hdev->cmd_work); 3038 queue_work(hdev->workqueue, &hdev->cmd_work);
3036} 3039}
3037 3040
3038static void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb) 3041static void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb,
3042 u16 *opcode, u8 *status,
3043 hci_req_complete_t *req_complete,
3044 hci_req_complete_skb_t *req_complete_skb)
3039{ 3045{
3040 struct hci_ev_cmd_status *ev = (void *) skb->data; 3046 struct hci_ev_cmd_status *ev = (void *) skb->data;
3041 __u16 opcode;
3042 3047
3043 skb_pull(skb, sizeof(*ev)); 3048 skb_pull(skb, sizeof(*ev));
3044 3049
3045 opcode = __le16_to_cpu(ev->opcode); 3050 *opcode = __le16_to_cpu(ev->opcode);
3051 *status = ev->status;
3046 3052
3047 switch (opcode) { 3053 switch (*opcode) {
3048 case HCI_OP_INQUIRY: 3054 case HCI_OP_INQUIRY:
3049 hci_cs_inquiry(hdev, ev->status); 3055 hci_cs_inquiry(hdev, ev->status);
3050 break; 3056 break;
@@ -3114,11 +3120,11 @@ static void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
3114 break; 3120 break;
3115 3121
3116 default: 3122 default:
3117 BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode); 3123 BT_DBG("%s opcode 0x%4.4x", hdev->name, *opcode);
3118 break; 3124 break;
3119 } 3125 }
3120 3126
3121 if (opcode != HCI_OP_NOP) 3127 if (*opcode != HCI_OP_NOP)
3122 cancel_delayed_work(&hdev->cmd_timer); 3128 cancel_delayed_work(&hdev->cmd_timer);
3123 3129
3124 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) 3130 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags))
@@ -3132,7 +3138,8 @@ static void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
3132 */ 3138 */
3133 if (ev->status || 3139 if (ev->status ||
3134 (hdev->sent_cmd && !bt_cb(hdev->sent_cmd)->req.event)) 3140 (hdev->sent_cmd && !bt_cb(hdev->sent_cmd)->req.event))
3135 hci_req_cmd_complete(hdev, opcode, ev->status); 3141 hci_req_cmd_complete(hdev, *opcode, ev->status, req_complete,
3142 req_complete_skb);
3136 3143
3137 if (atomic_read(&hdev->cmd_cnt) && !skb_queue_empty(&hdev->cmd_q)) 3144 if (atomic_read(&hdev->cmd_cnt) && !skb_queue_empty(&hdev->cmd_q))
3138 queue_work(hdev->workqueue, &hdev->cmd_work); 3145 queue_work(hdev->workqueue, &hdev->cmd_work);
@@ -5039,7 +5046,11 @@ static void hci_chan_selected_evt(struct hci_dev *hdev, struct sk_buff *skb)
5039void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb) 5046void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
5040{ 5047{
5041 struct hci_event_hdr *hdr = (void *) skb->data; 5048 struct hci_event_hdr *hdr = (void *) skb->data;
5042 __u8 event = hdr->evt; 5049 hci_req_complete_t req_complete = NULL;
5050 hci_req_complete_skb_t req_complete_skb = NULL;
5051 struct sk_buff *orig_skb = NULL;
5052 u8 status = 0, event = hdr->evt;
5053 u16 opcode = HCI_OP_NOP;
5043 5054
5044 hci_dev_lock(hdev); 5055 hci_dev_lock(hdev);
5045 5056
@@ -5053,15 +5064,24 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
5053 5064
5054 hci_dev_unlock(hdev); 5065 hci_dev_unlock(hdev);
5055 5066
5056 skb_pull(skb, HCI_EVENT_HDR_SIZE);
5057
5058 if (hdev->sent_cmd && bt_cb(hdev->sent_cmd)->req.event == event) { 5067 if (hdev->sent_cmd && bt_cb(hdev->sent_cmd)->req.event == event) {
5059 struct hci_command_hdr *cmd_hdr = (void *) hdev->sent_cmd->data; 5068 struct hci_command_hdr *cmd_hdr = (void *) hdev->sent_cmd->data;
5060 u16 opcode = __le16_to_cpu(cmd_hdr->opcode); 5069 opcode = __le16_to_cpu(cmd_hdr->opcode);
5061 5070 hci_req_cmd_complete(hdev, opcode, status, &req_complete,
5062 hci_req_cmd_complete(hdev, opcode, 0); 5071 &req_complete_skb);
5063 } 5072 }
5064 5073
5074 /* If it looks like we might end up having to call
5075 * req_complete_skb, store a pristine copy of the skb since the
5076 * various handlers may modify the original one through
5077 * skb_pull() calls, etc.
5078 */
5079 if (req_complete_skb || event == HCI_EV_CMD_STATUS ||
5080 event == HCI_EV_CMD_COMPLETE)
5081 orig_skb = skb_clone(skb, GFP_KERNEL);
5082
5083 skb_pull(skb, HCI_EVENT_HDR_SIZE);
5084
5065 switch (event) { 5085 switch (event) {
5066 case HCI_EV_INQUIRY_COMPLETE: 5086 case HCI_EV_INQUIRY_COMPLETE:
5067 hci_inquiry_complete_evt(hdev, skb); 5087 hci_inquiry_complete_evt(hdev, skb);
@@ -5104,11 +5124,13 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
5104 break; 5124 break;
5105 5125
5106 case HCI_EV_CMD_COMPLETE: 5126 case HCI_EV_CMD_COMPLETE:
5107 hci_cmd_complete_evt(hdev, skb); 5127 hci_cmd_complete_evt(hdev, skb, &opcode, &status,
5128 &req_complete, &req_complete_skb);
5108 break; 5129 break;
5109 5130
5110 case HCI_EV_CMD_STATUS: 5131 case HCI_EV_CMD_STATUS:
5111 hci_cmd_status_evt(hdev, skb); 5132 hci_cmd_status_evt(hdev, skb, &opcode, &status, &req_complete,
5133 &req_complete_skb);
5112 break; 5134 break;
5113 5135
5114 case HCI_EV_HARDWARE_ERROR: 5136 case HCI_EV_HARDWARE_ERROR:
@@ -5240,6 +5262,12 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
5240 break; 5262 break;
5241 } 5263 }
5242 5264
5265 if (req_complete)
5266 req_complete(hdev, status, opcode);
5267 else if (req_complete_skb)
5268 req_complete_skb(hdev, status, opcode, orig_skb);
5269
5270 kfree_skb(orig_skb);
5243 kfree_skb(skb); 5271 kfree_skb(skb);
5244 hdev->stat.evt_rx++; 5272 hdev->stat.evt_rx++;
5245} 5273}
diff --git a/net/bluetooth/hci_request.c b/net/bluetooth/hci_request.c
index 7e17907effb3..d6025d6e6d59 100644
--- a/net/bluetooth/hci_request.c
+++ b/net/bluetooth/hci_request.c
@@ -34,7 +34,8 @@ void hci_req_init(struct hci_request *req, struct hci_dev *hdev)
34 req->err = 0; 34 req->err = 0;
35} 35}
36 36
37int hci_req_run(struct hci_request *req, hci_req_complete_t complete) 37static int req_run(struct hci_request *req, hci_req_complete_t complete,
38 hci_req_complete_skb_t complete_skb)
38{ 39{
39 struct hci_dev *hdev = req->hdev; 40 struct hci_dev *hdev = req->hdev;
40 struct sk_buff *skb; 41 struct sk_buff *skb;
@@ -56,6 +57,7 @@ int hci_req_run(struct hci_request *req, hci_req_complete_t complete)
56 57
57 skb = skb_peek_tail(&req->cmd_q); 58 skb = skb_peek_tail(&req->cmd_q);
58 bt_cb(skb)->req.complete = complete; 59 bt_cb(skb)->req.complete = complete;
60 bt_cb(skb)->req.complete_skb = complete_skb;
59 61
60 spin_lock_irqsave(&hdev->cmd_q.lock, flags); 62 spin_lock_irqsave(&hdev->cmd_q.lock, flags);
61 skb_queue_splice_tail(&req->cmd_q, &hdev->cmd_q); 63 skb_queue_splice_tail(&req->cmd_q, &hdev->cmd_q);
@@ -66,6 +68,16 @@ int hci_req_run(struct hci_request *req, hci_req_complete_t complete)
66 return 0; 68 return 0;
67} 69}
68 70
71int hci_req_run(struct hci_request *req, hci_req_complete_t complete)
72{
73 return req_run(req, complete, NULL);
74}
75
76int hci_req_run_skb(struct hci_request *req, hci_req_complete_skb_t complete)
77{
78 return req_run(req, NULL, complete);
79}
80
69struct sk_buff *hci_prepare_cmd(struct hci_dev *hdev, u16 opcode, u32 plen, 81struct sk_buff *hci_prepare_cmd(struct hci_dev *hdev, u16 opcode, u32 plen,
70 const void *param) 82 const void *param)
71{ 83{
diff --git a/net/bluetooth/hci_request.h b/net/bluetooth/hci_request.h
index adf074d33544..bf6df92f42db 100644
--- a/net/bluetooth/hci_request.h
+++ b/net/bluetooth/hci_request.h
@@ -32,11 +32,14 @@ struct hci_request {
32 32
33void hci_req_init(struct hci_request *req, struct hci_dev *hdev); 33void hci_req_init(struct hci_request *req, struct hci_dev *hdev);
34int hci_req_run(struct hci_request *req, hci_req_complete_t complete); 34int hci_req_run(struct hci_request *req, hci_req_complete_t complete);
35int hci_req_run_skb(struct hci_request *req, hci_req_complete_skb_t complete);
35void hci_req_add(struct hci_request *req, u16 opcode, u32 plen, 36void hci_req_add(struct hci_request *req, u16 opcode, u32 plen,
36 const void *param); 37 const void *param);
37void hci_req_add_ev(struct hci_request *req, u16 opcode, u32 plen, 38void hci_req_add_ev(struct hci_request *req, u16 opcode, u32 plen,
38 const void *param, u8 event); 39 const void *param, u8 event);
39void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status); 40void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status,
41 hci_req_complete_t *req_complete,
42 hci_req_complete_skb_t *req_complete_skb);
40 43
41struct sk_buff *hci_prepare_cmd(struct hci_dev *hdev, u16 opcode, u32 plen, 44struct sk_buff *hci_prepare_cmd(struct hci_dev *hdev, u16 opcode, u32 plen,
42 const void *param); 45 const void *param);