[PATCH v2 3/3] Bluetooth: coredump: Expose header size and end marker to drivers

From: Zijun Hu

Date: Tue Jul 28 2026 - 02:55:48 EST


To separate the coredump header and data far more easily, give a
vendor driver the option to pad its header to a fixed size, by
moving the header size limit and ending marker to coredump.h:

- HCI_DEVCD_HDR_SIZE_MAX: the max header size
- HCI_DEVCD_HDR_END_MARKER: the header-ending marker

No functional change intended.

Signed-off-by: Zijun Hu <zijun.hu@xxxxxxxxxxxxxxxx>
---
Previous version:
https://lore.kernel.org/all/20260713-btusb_prep_qcc2072-v2-2-bbcb651285f2@xxxxxxxxxxxxxxxx

Changes since previous version:
- Rename MAX_HCI_DEVCD_HDR_SIZE to HCI_DEVCD_HDR_SIZE_MAX
- Rename HCI_DEVCD_HDR_END to HCI_DEVCD_HDR_END_MARKER
- Improve the commit title and message
---
include/net/bluetooth/coredump.h | 7 +++++++
net/bluetooth/coredump.c | 7 ++-----
2 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/include/net/bluetooth/coredump.h b/include/net/bluetooth/coredump.h
index ab85a6adfffd..1f071ab55416 100644
--- a/include/net/bluetooth/coredump.h
+++ b/include/net/bluetooth/coredump.h
@@ -3,16 +3,23 @@
* Copyright (C) 2022 Google Corporation
*/

#ifndef __COREDUMP_H
#define __COREDUMP_H

#define DEVCOREDUMP_TIMEOUT msecs_to_jiffies(10000) /* 10 sec */

+/*
+ * Max header size, shared by both the devcoredump core and
+ * the dmp_hdr() registered by driver via hci_devcd_register()
+ */
+#define HCI_DEVCD_HDR_SIZE_MAX 512
+#define HCI_DEVCD_HDR_END_MARKER "--- Start dump ---\n"
+
typedef void (*coredump_t)(struct hci_dev *hdev);
typedef void (*dmp_hdr_t)(struct hci_dev *hdev, struct sk_buff *skb);
typedef void (*notify_change_t)(struct hci_dev *hdev, int state);

/* struct hci_devcoredump - Devcoredump state
*
* @supported: Indicates if FW dump collection is supported by driver
* @state: Current state of dump collection
diff --git a/net/bluetooth/coredump.c b/net/bluetooth/coredump.c
index 913bbba559f8..5bee863bd6d2 100644
--- a/net/bluetooth/coredump.c
+++ b/net/bluetooth/coredump.c
@@ -29,18 +29,16 @@ struct hci_devcoredump_skb_pattern {
#define hci_dmp_cb(skb) ((struct hci_devcoredump_skb_cb *)((skb)->cb))

#define DBG_UNEXPECTED_STATE() \
bt_dev_dbg(hdev, \
"Unexpected packet (%d) for state %s.", \
hci_dmp_cb(skb)->pkt_type, \
hci_devcd_state_name(hdev->dump.state))

-#define MAX_DEVCOREDUMP_HDR_SIZE 512 /* bytes */
-
static int hci_devcd_update_hdr_state(char *buf, size_t size, int state)
{
int len = 0;

if (!buf)
return 0;

len = scnprintf(buf, size, "Bluetooth devcoredump\nState: %d\n", state);
@@ -58,28 +56,27 @@ static int hci_devcd_update_state(struct hci_dev *hdev, int state)
hdev->dump.state = state;

return hci_devcd_update_hdr_state(hdev->dump.head,
hdev->dump.alloc_size, state);
}

static int hci_devcd_mkheader(struct hci_dev *hdev, struct sk_buff *skb)
{
- char dump_start[] = "--- Start dump ---\n";
char hdr[80];
int hdr_len;

hdr_len = hci_devcd_update_hdr_state(hdr, sizeof(hdr),
HCI_DEVCOREDUMP_IDLE);
skb_put_data(skb, hdr, hdr_len);

if (hdev->dump.dmp_hdr)
hdev->dump.dmp_hdr(hdev, skb);

- skb_put_data(skb, dump_start, strlen(dump_start));
+ skb_put_data(skb, HCI_DEVCD_HDR_END_MARKER, strlen(HCI_DEVCD_HDR_END_MARKER));

return skb->len;
}

/* Do not call with hci_dev_lock since this calls driver code. */
static void hci_devcd_notify(struct hci_dev *hdev, int state)
{
if (hdev->dump.notify_change)
@@ -149,17 +146,17 @@ static bool hci_devcd_memset(struct hci_dev *hdev, u8 pattern, u32 len)

/* Call with hci_dev_lock only. */
static int hci_devcd_prepare(struct hci_dev *hdev, u32 dump_size)
{
struct sk_buff *skb;
int dump_hdr_size;
int err = 0;

- skb = alloc_skb(MAX_DEVCOREDUMP_HDR_SIZE, GFP_ATOMIC);
+ skb = alloc_skb(HCI_DEVCD_HDR_SIZE_MAX, GFP_ATOMIC);
if (!skb)
return -ENOMEM;

dump_hdr_size = hci_devcd_mkheader(hdev, skb);

if (hci_devcd_alloc(hdev, dump_hdr_size + dump_size)) {
err = -ENOMEM;
goto hdr_free;

--
2.34.1