projects/linux·blob master · refs

132 lines · 3.5 KiB

1/* SPDX-License-Identifier: GPL-2.0-only */
2/*
3 * Copyright (C) 2022 Google Corporation
4 */
5
6#ifndef __COREDUMP_H
7#define __COREDUMP_H
8
9#define DEVCOREDUMP_TIMEOUT msecs_to_jiffies(10000) /* 10 sec */
10
11/*
12 * Max header size, shared by both the devcoredump core and
13 * the dmp_hdr() registered by driver via hci_devcd_register()
14 */
15#define HCI_DEVCD_HDR_SIZE_MAX 512
16#define HCI_DEVCD_HDR_END_MARKER "--- Start dump ---\n"
17
18typedef void (*coredump_t)(struct hci_dev *hdev);
19typedef void (*dmp_hdr_t)(struct hci_dev *hdev, struct sk_buff *skb);
20typedef void (*notify_change_t)(struct hci_dev *hdev, int state);
21
22/* struct hci_devcoredump - Devcoredump state
23 *
24 * @supported: Indicates if FW dump collection is supported by driver
25 * @state: Current state of dump collection
26 * @timeout: Indicates a timeout for collecting the devcoredump
27 *
28 * @alloc_size: Total size of the dump
29 * @head: Start of the dump
30 * @tail: Pointer to current end of dump
31 * @end: head + alloc_size for easy comparisons
32 *
33 * @dump_q: Dump queue for state machine to process
34 * @dump_rx: Devcoredump state machine work
35 * @dump_timeout: Devcoredump timeout work
36 *
37 * @coredump: Called from the driver's .coredump() function.
38 * @dmp_hdr: Create a dump header to identify controller/fw/driver info
39 * @notify_change: Notify driver when devcoredump state has changed
40 */
41struct hci_devcoredump {
42 bool supported;
43
44 enum devcoredump_state {
45 HCI_DEVCOREDUMP_IDLE,
46 HCI_DEVCOREDUMP_ACTIVE,
47 HCI_DEVCOREDUMP_DONE,
48 HCI_DEVCOREDUMP_ABORT,
49 HCI_DEVCOREDUMP_TIMEOUT,
50 } state;
51
52 unsigned long timeout;
53
54 size_t alloc_size;
55 char *head;
56 char *tail;
57 char *end;
58
59 struct sk_buff_head dump_q;
60 struct work_struct dump_rx;
61 struct delayed_work dump_timeout;
62
63 coredump_t coredump;
64 dmp_hdr_t dmp_hdr;
65 notify_change_t notify_change;
66};
67
68#ifdef CONFIG_DEV_COREDUMP
69
70const char *hci_devcd_state_name(enum devcoredump_state state);
71
72void hci_devcd_reset(struct hci_dev *hdev);
73void hci_devcd_shutdown(struct hci_dev *hdev);
74void hci_devcd_rx(struct work_struct *work);
75void hci_devcd_timeout(struct work_struct *work);
76
77int hci_devcd_register(struct hci_dev *hdev, coredump_t coredump,
78 dmp_hdr_t dmp_hdr, notify_change_t notify_change);
79int hci_devcd_init(struct hci_dev *hdev, u32 dump_size);
80int hci_devcd_append(struct hci_dev *hdev, struct sk_buff *skb);
81int hci_devcd_append_pattern(struct hci_dev *hdev, u8 pattern, u32 len);
82int hci_devcd_complete(struct hci_dev *hdev);
83int hci_devcd_abort(struct hci_dev *hdev);
84
85#else
86
87static inline const char *hci_devcd_state_name(enum devcoredump_state state)
88{
89 return "";
90}
91
92static inline void hci_devcd_reset(struct hci_dev *hdev) {}
93static inline void hci_devcd_shutdown(struct hci_dev *hdev) {}
94static inline void hci_devcd_rx(struct work_struct *work) {}
95static inline void hci_devcd_timeout(struct work_struct *work) {}
96
97static inline int hci_devcd_register(struct hci_dev *hdev, coredump_t coredump,
98 dmp_hdr_t dmp_hdr,
99 notify_change_t notify_change)
100{
101 return -EOPNOTSUPP;
102}
103
104static inline int hci_devcd_init(struct hci_dev *hdev, u32 dump_size)
105{
106 return -EOPNOTSUPP;
107}
108
109static inline int hci_devcd_append(struct hci_dev *hdev, struct sk_buff *skb)
110{
111 return -EOPNOTSUPP;
112}
113
114static inline int hci_devcd_append_pattern(struct hci_dev *hdev,
115 u8 pattern, u32 len)
116{
117 return -EOPNOTSUPP;
118}
119
120static inline int hci_devcd_complete(struct hci_dev *hdev)
121{
122 return -EOPNOTSUPP;
123}
124
125static inline int hci_devcd_abort(struct hci_dev *hdev)
126{
127 return -EOPNOTSUPP;
128}
129
130#endif /* CONFIG_DEV_COREDUMP */
131
132#endif /* __COREDUMP_H */