Hi Luiz, > This introduces hci_recv_event_data to make it simpler to access the > contents of last received event rather than having to pass its contents > to the likes of *_ind/*_cfm callbacks. > > Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@xxxxxxxxx> > --- > include/net/bluetooth/hci_core.h | 2 ++ > net/bluetooth/hci_core.c | 32 ++++++++++++++++++++++++++++++++ > net/bluetooth/hci_event.c | 3 +++ > 3 files changed, 37 insertions(+) > > diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h > index f5caff1ddb29..c454913794bf 100644 > --- a/include/net/bluetooth/hci_core.h > +++ b/include/net/bluetooth/hci_core.h > @@ -516,6 +516,7 @@ struct hci_dev { > struct sk_buff_head cmd_q; > > struct sk_buff *sent_cmd; > + struct sk_buff *recv_event; > > struct mutex req_lock; > wait_queue_head_t req_wait_q; > @@ -1727,6 +1728,7 @@ void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags); > void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb); > > void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode); > +void *hci_recv_event_data(struct hci_dev *hdev, __u8 event); > > u32 hci_conn_get_phy(struct hci_conn *conn); > > diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c > index b4782a6c1025..5d1167b67a47 100644 > --- a/net/bluetooth/hci_core.c > +++ b/net/bluetooth/hci_core.c > @@ -2740,6 +2740,7 @@ void hci_release_dev(struct hci_dev *hdev) > > ida_simple_remove(&hci_index_ida, hdev->id); > kfree_skb(hdev->sent_cmd); > + kfree_skb(hdev->recv_event); > kfree(hdev); > } > EXPORT_SYMBOL(hci_release_dev); > @@ -3024,6 +3025,37 @@ void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode) > return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE; > } > > +/* Get data from last received event */ > +void *hci_recv_event_data(struct hci_dev *hdev, __u8 event) > +{ > + struct hci_event_hdr *hdr; > + int offset; > + > + if (!hdev->recv_event) > + return NULL; > + > + hdr = (void *) hdev->recv_event->data; > + offset = sizeof(hdr); > + > + if (hdr->evt != event) { > + /* In case of LE metaevent check the subevent match */ > + if (hdr->evt == HCI_EV_LE_META) { > + struct hci_ev_le_meta *ev; > + > + ev = (void *) hdev->recv_event->data + offset; > + offset += sizeof(*ev); > + if (ev->subevent == event) > + goto found; > + } > + return NULL; > + } > + > +found: > + bt_dev_dbg(hdev, "event 0x%2.2x", event); > + > + return hdev->recv_event->data + offset; > +} > + > /* Send ACL data */ > static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags) > { > diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c > index 63b925921c87..613050bd80cc 100644 > --- a/net/bluetooth/hci_event.c > +++ b/net/bluetooth/hci_event.c > @@ -6898,6 +6898,9 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb) > goto done; > } > > + kfree_skb(hdev->recv_event); > + hdev->recv_event = skb_clone(skb, GFP_KERNEL); > + fill me into why this a good idea. We end up creating clones of an SKB. Is this a good idea? Regards Marcel