|
Lee, Chun-Yi |
1f7ef9 |
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
|
|
Lee, Chun-Yi |
1f7ef9 |
Date: Fri, 4 Feb 2022 13:04:38 -0800
|
|
Lee, Chun-Yi |
1f7ef9 |
Subject: Bluetooth: hci_core: Introduce hci_recv_event_data
|
|
Lee, Chun-Yi |
1f7ef9 |
Patch-mainline: v6.0-rc1
|
|
Lee, Chun-Yi |
1f7ef9 |
Git-commit: dfe6d5c3ec23c5b999261d989059aa35403d791d
|
|
Lee, Chun-Yi |
1f7ef9 |
References: jsc#PED-1407
|
|
Lee, Chun-Yi |
1f7ef9 |
|
|
Lee, Chun-Yi |
1f7ef9 |
This introduces hci_recv_event_data to make it simpler to access the
|
|
Lee, Chun-Yi |
1f7ef9 |
contents of last received event rather than having to pass its contents
|
|
Lee, Chun-Yi |
1f7ef9 |
to the likes of *_ind/*_cfm callbacks.
|
|
Lee, Chun-Yi |
1f7ef9 |
|
|
Lee, Chun-Yi |
1f7ef9 |
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
|
|
Lee, Chun-Yi |
1f7ef9 |
Acked-by: Lee, Chun-Yi <jlee@suse.com>
|
|
Lee, Chun-Yi |
1f7ef9 |
---
|
|
Lee, Chun-Yi |
1f7ef9 |
include/net/bluetooth/hci_core.h | 2 ++
|
|
Lee, Chun-Yi |
1f7ef9 |
net/bluetooth/hci_core.c | 32 ++++++++++++++++++++++++++++++++
|
|
Lee, Chun-Yi |
1f7ef9 |
net/bluetooth/hci_event.c | 3 +++
|
|
Lee, Chun-Yi |
1f7ef9 |
3 files changed, 37 insertions(+)
|
|
Lee, Chun-Yi |
1f7ef9 |
|
|
Lee, Chun-Yi |
1f7ef9 |
--- a/include/net/bluetooth/hci_core.h
|
|
Lee, Chun-Yi |
1f7ef9 |
+++ b/include/net/bluetooth/hci_core.h
|
|
Lee, Chun-Yi |
1f7ef9 |
@@ -525,6 +525,7 @@ struct hci_dev {
|
|
Lee, Chun-Yi |
1f7ef9 |
struct sk_buff_head cmd_q;
|
|
Lee, Chun-Yi |
1f7ef9 |
|
|
Lee, Chun-Yi |
1f7ef9 |
struct sk_buff *sent_cmd;
|
|
Lee, Chun-Yi |
1f7ef9 |
+ struct sk_buff *recv_event;
|
|
Lee, Chun-Yi |
1f7ef9 |
|
|
Lee, Chun-Yi |
1f7ef9 |
struct mutex req_lock;
|
|
Lee, Chun-Yi |
1f7ef9 |
wait_queue_head_t req_wait_q;
|
|
Lee, Chun-Yi |
1f7ef9 |
@@ -1747,6 +1748,7 @@ void hci_send_acl(struct hci_chan *chan,
|
|
Lee, Chun-Yi |
1f7ef9 |
void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb);
|
|
Lee, Chun-Yi |
1f7ef9 |
|
|
Lee, Chun-Yi |
1f7ef9 |
void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode);
|
|
Lee, Chun-Yi |
1f7ef9 |
+void *hci_recv_event_data(struct hci_dev *hdev, __u8 event);
|
|
Lee, Chun-Yi |
1f7ef9 |
|
|
Lee, Chun-Yi |
1f7ef9 |
u32 hci_conn_get_phy(struct hci_conn *conn);
|
|
Lee, Chun-Yi |
1f7ef9 |
|
|
Lee, Chun-Yi |
1f7ef9 |
--- a/net/bluetooth/hci_core.c
|
|
Lee, Chun-Yi |
1f7ef9 |
+++ b/net/bluetooth/hci_core.c
|
|
Lee, Chun-Yi |
1f7ef9 |
@@ -2712,6 +2712,7 @@ void hci_release_dev(struct hci_dev *hde
|
|
Lee, Chun-Yi |
1f7ef9 |
|
|
Lee, Chun-Yi |
1f7ef9 |
ida_simple_remove(&hci_index_ida, hdev->id);
|
|
Lee, Chun-Yi |
1f7ef9 |
kfree_skb(hdev->sent_cmd);
|
|
Lee, Chun-Yi |
1f7ef9 |
+ kfree_skb(hdev->recv_event);
|
|
Lee, Chun-Yi |
1f7ef9 |
kfree(hdev);
|
|
Lee, Chun-Yi |
1f7ef9 |
}
|
|
Lee, Chun-Yi |
1f7ef9 |
EXPORT_SYMBOL(hci_release_dev);
|
|
Lee, Chun-Yi |
1f7ef9 |
@@ -3018,6 +3019,37 @@ void *hci_sent_cmd_data(struct hci_dev *
|
|
Lee, Chun-Yi |
1f7ef9 |
return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE;
|
|
Lee, Chun-Yi |
1f7ef9 |
}
|
|
Lee, Chun-Yi |
1f7ef9 |
|
|
Lee, Chun-Yi |
1f7ef9 |
+/* Get data from last received event */
|
|
Lee, Chun-Yi |
1f7ef9 |
+void *hci_recv_event_data(struct hci_dev *hdev, __u8 event)
|
|
Lee, Chun-Yi |
1f7ef9 |
+{
|
|
Lee, Chun-Yi |
1f7ef9 |
+ struct hci_event_hdr *hdr;
|
|
Lee, Chun-Yi |
1f7ef9 |
+ int offset;
|
|
Lee, Chun-Yi |
1f7ef9 |
+
|
|
Lee, Chun-Yi |
1f7ef9 |
+ if (!hdev->recv_event)
|
|
Lee, Chun-Yi |
1f7ef9 |
+ return NULL;
|
|
Lee, Chun-Yi |
1f7ef9 |
+
|
|
Lee, Chun-Yi |
1f7ef9 |
+ hdr = (void *)hdev->recv_event->data;
|
|
Lee, Chun-Yi |
1f7ef9 |
+ offset = sizeof(*hdr);
|
|
Lee, Chun-Yi |
1f7ef9 |
+
|
|
Lee, Chun-Yi |
1f7ef9 |
+ if (hdr->evt != event) {
|
|
Lee, Chun-Yi |
1f7ef9 |
+ /* In case of LE metaevent check the subevent match */
|
|
Lee, Chun-Yi |
1f7ef9 |
+ if (hdr->evt == HCI_EV_LE_META) {
|
|
Lee, Chun-Yi |
1f7ef9 |
+ struct hci_ev_le_meta *ev;
|
|
Lee, Chun-Yi |
1f7ef9 |
+
|
|
Lee, Chun-Yi |
1f7ef9 |
+ ev = (void *)hdev->recv_event->data + offset;
|
|
Lee, Chun-Yi |
1f7ef9 |
+ offset += sizeof(*ev);
|
|
Lee, Chun-Yi |
1f7ef9 |
+ if (ev->subevent == event)
|
|
Lee, Chun-Yi |
1f7ef9 |
+ goto found;
|
|
Lee, Chun-Yi |
1f7ef9 |
+ }
|
|
Lee, Chun-Yi |
1f7ef9 |
+ return NULL;
|
|
Lee, Chun-Yi |
1f7ef9 |
+ }
|
|
Lee, Chun-Yi |
1f7ef9 |
+
|
|
Lee, Chun-Yi |
1f7ef9 |
+found:
|
|
Lee, Chun-Yi |
1f7ef9 |
+ bt_dev_dbg(hdev, "event 0x%2.2x", event);
|
|
Lee, Chun-Yi |
1f7ef9 |
+
|
|
Lee, Chun-Yi |
1f7ef9 |
+ return hdev->recv_event->data + offset;
|
|
Lee, Chun-Yi |
1f7ef9 |
+}
|
|
Lee, Chun-Yi |
1f7ef9 |
+
|
|
Lee, Chun-Yi |
1f7ef9 |
/* Send ACL data */
|
|
Lee, Chun-Yi |
1f7ef9 |
static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags)
|
|
Lee, Chun-Yi |
1f7ef9 |
{
|
|
Lee, Chun-Yi |
1f7ef9 |
--- a/net/bluetooth/hci_event.c
|
|
Lee, Chun-Yi |
1f7ef9 |
+++ b/net/bluetooth/hci_event.c
|
|
Lee, Chun-Yi |
1f7ef9 |
@@ -6936,6 +6936,9 @@ void hci_event_packet(struct hci_dev *hd
|
|
Lee, Chun-Yi |
1f7ef9 |
goto done;
|
|
Lee, Chun-Yi |
1f7ef9 |
}
|
|
Lee, Chun-Yi |
1f7ef9 |
|
|
Lee, Chun-Yi |
1f7ef9 |
+ kfree_skb(hdev->recv_event);
|
|
Lee, Chun-Yi |
1f7ef9 |
+ hdev->recv_event = skb_clone(skb, GFP_KERNEL);
|
|
Lee, Chun-Yi |
1f7ef9 |
+
|
|
Lee, Chun-Yi |
1f7ef9 |
event = hdr->evt;
|
|
Lee, Chun-Yi |
1f7ef9 |
if (!event) {
|
|
Lee, Chun-Yi |
1f7ef9 |
bt_dev_warn(hdev, "Received unexpected HCI Event 0x%2.2x",
|