Skip to content

Commit 85b5685

Browse files
Vudentzholtmann
authored andcommitted
Bluetooth: hci_sync: Add support for waiting specific LE subevents
This adds support for waiting for specific LE subevents instead of command status which may only indicate that the commands is in progress and a different event is used to complete the operation. Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
1 parent 8e8b92e commit 85b5685

File tree

3 files changed

+28
-16
lines changed

3 files changed

+28
-16
lines changed

include/net/bluetooth/bluetooth.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,7 @@ struct bt_skb_cb {
412412
#define hci_skb_pkt_type(skb) bt_cb((skb))->pkt_type
413413
#define hci_skb_expect(skb) bt_cb((skb))->expect
414414
#define hci_skb_opcode(skb) bt_cb((skb))->hci.opcode
415+
#define hci_skb_event(skb) bt_cb((skb))->hci.req_event
415416
#define hci_skb_sk(skb) bt_cb((skb))->hci.sk
416417

417418
static inline struct sk_buff *bt_skb_alloc(unsigned int len, gfp_t how)

net/bluetooth/hci_event.c

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4038,15 +4038,14 @@ static void hci_cmd_status_evt(struct hci_dev *hdev, void *data,
40384038
* (since for this kind of commands there will not be a command
40394039
* complete event).
40404040
*/
4041-
if (ev->status ||
4042-
(hdev->sent_cmd && !bt_cb(hdev->sent_cmd)->hci.req_event))
4041+
if (ev->status || (hdev->sent_cmd && !hci_skb_event(hdev->sent_cmd))) {
40434042
hci_req_cmd_complete(hdev, *opcode, ev->status, req_complete,
40444043
req_complete_skb);
4045-
4046-
if (hci_dev_test_flag(hdev, HCI_CMD_PENDING)) {
4047-
bt_dev_err(hdev,
4048-
"unexpected event for opcode 0x%4.4x", *opcode);
4049-
return;
4044+
if (hci_dev_test_flag(hdev, HCI_CMD_PENDING)) {
4045+
bt_dev_err(hdev, "unexpected event for opcode 0x%4.4x",
4046+
*opcode);
4047+
return;
4048+
}
40504049
}
40514050

40524051
if (atomic_read(&hdev->cmd_cnt) && !skb_queue_empty(&hdev->cmd_q))
@@ -6464,13 +6463,24 @@ static const struct hci_le_ev {
64646463
};
64656464

64666465
static void hci_le_meta_evt(struct hci_dev *hdev, void *data,
6467-
struct sk_buff *skb)
6466+
struct sk_buff *skb, u16 *opcode, u8 *status,
6467+
hci_req_complete_t *req_complete,
6468+
hci_req_complete_skb_t *req_complete_skb)
64686469
{
64696470
struct hci_ev_le_meta *ev = data;
64706471
const struct hci_le_ev *subev;
64716472

64726473
bt_dev_dbg(hdev, "subevent 0x%2.2x", ev->subevent);
64736474

6475+
/* Only match event if command OGF is for LE */
6476+
if (hdev->sent_cmd &&
6477+
hci_opcode_ogf(hci_skb_opcode(hdev->sent_cmd)) == 0x08 &&
6478+
hci_skb_event(hdev->sent_cmd) == ev->subevent) {
6479+
*opcode = hci_skb_opcode(hdev->sent_cmd);
6480+
hci_req_cmd_complete(hdev, *opcode, 0x00, req_complete,
6481+
req_complete_skb);
6482+
}
6483+
64746484
subev = &hci_le_ev_table[ev->subevent];
64756485
if (!subev->func)
64766486
return;
@@ -6764,8 +6774,8 @@ static const struct hci_ev {
67646774
HCI_EV(HCI_EV_REMOTE_HOST_FEATURES, hci_remote_host_features_evt,
67656775
sizeof(struct hci_ev_remote_host_features)),
67666776
/* [0x3e = HCI_EV_LE_META] */
6767-
HCI_EV_VL(HCI_EV_LE_META, hci_le_meta_evt,
6768-
sizeof(struct hci_ev_le_meta), HCI_MAX_EVENT_SIZE),
6777+
HCI_EV_REQ_VL(HCI_EV_LE_META, hci_le_meta_evt,
6778+
sizeof(struct hci_ev_le_meta), HCI_MAX_EVENT_SIZE),
67696779
#if IS_ENABLED(CONFIG_BT_HS)
67706780
/* [0x40 = HCI_EV_PHY_LINK_COMPLETE] */
67716781
HCI_EV(HCI_EV_PHY_LINK_COMPLETE, hci_phy_link_complete_evt,
@@ -6849,11 +6859,12 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
68496859
goto done;
68506860
}
68516861

6852-
if (hdev->sent_cmd && bt_cb(hdev->sent_cmd)->hci.req_event == event) {
6853-
struct hci_command_hdr *cmd_hdr = (void *) hdev->sent_cmd->data;
6854-
opcode = __le16_to_cpu(cmd_hdr->opcode);
6855-
hci_req_cmd_complete(hdev, opcode, status, &req_complete,
6856-
&req_complete_skb);
6862+
/* Only match event if command OGF is not for LE */
6863+
if (hdev->sent_cmd &&
6864+
hci_opcode_ogf(hci_skb_opcode(hdev->sent_cmd)) != 0x08 &&
6865+
hci_skb_event(hdev->sent_cmd) == event) {
6866+
hci_req_cmd_complete(hdev, hci_skb_opcode(hdev->sent_cmd),
6867+
status, &req_complete, &req_complete_skb);
68576868
req_evt = event;
68586869
}
68596870

net/bluetooth/hci_sync.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ static void hci_cmd_sync_add(struct hci_request *req, u16 opcode, u32 plen,
103103
if (skb_queue_empty(&req->cmd_q))
104104
bt_cb(skb)->hci.req_flags |= HCI_REQ_START;
105105

106-
bt_cb(skb)->hci.req_event = event;
106+
hci_skb_event(skb) = event;
107107

108108
skb_queue_tail(&req->cmd_q, skb);
109109
}

0 commit comments

Comments
 (0)