mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-23 20:24:12 +08:00
Bluetooth: Add vhci devcoredump support
Add devcoredump support for vhci that creates forcce_devcoredump debugfs entry. This is used for mgmt-tester tests. Signed-off-by: Manish Mandlik <mmandlik@google.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This commit is contained in:
parent
9695ef876f
commit
ab4e4380d4
@ -363,6 +363,7 @@ config BT_HCIBLUECARD
|
||||
|
||||
config BT_HCIVHCI
|
||||
tristate "HCI VHCI (Virtual HCI device) driver"
|
||||
select WANT_DEV_COREDUMP
|
||||
help
|
||||
Bluetooth Virtual HCI device driver.
|
||||
This driver is required if you want to use HCI Emulation software.
|
||||
|
@ -278,6 +278,100 @@ static int vhci_setup(struct hci_dev *hdev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void vhci_coredump(struct hci_dev *hdev)
|
||||
{
|
||||
/* No need to do anything */
|
||||
}
|
||||
|
||||
static void vhci_coredump_hdr(struct hci_dev *hdev, struct sk_buff *skb)
|
||||
{
|
||||
char buf[80];
|
||||
|
||||
snprintf(buf, sizeof(buf), "Controller Name: vhci_ctrl\n");
|
||||
skb_put_data(skb, buf, strlen(buf));
|
||||
|
||||
snprintf(buf, sizeof(buf), "Firmware Version: vhci_fw\n");
|
||||
skb_put_data(skb, buf, strlen(buf));
|
||||
|
||||
snprintf(buf, sizeof(buf), "Driver: vhci_drv\n");
|
||||
skb_put_data(skb, buf, strlen(buf));
|
||||
|
||||
snprintf(buf, sizeof(buf), "Vendor: vhci\n");
|
||||
skb_put_data(skb, buf, strlen(buf));
|
||||
}
|
||||
|
||||
#define MAX_COREDUMP_LINE_LEN 40
|
||||
|
||||
struct devcoredump_test_data {
|
||||
enum devcoredump_state state;
|
||||
unsigned int timeout;
|
||||
char data[MAX_COREDUMP_LINE_LEN];
|
||||
};
|
||||
|
||||
static inline void force_devcd_timeout(struct hci_dev *hdev,
|
||||
unsigned int timeout)
|
||||
{
|
||||
#ifdef CONFIG_DEV_COREDUMP
|
||||
hdev->dump.timeout = msecs_to_jiffies(timeout * 1000);
|
||||
#endif
|
||||
}
|
||||
|
||||
static ssize_t force_devcd_write(struct file *file, const char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct vhci_data *data = file->private_data;
|
||||
struct hci_dev *hdev = data->hdev;
|
||||
struct sk_buff *skb = NULL;
|
||||
struct devcoredump_test_data dump_data;
|
||||
int ret;
|
||||
|
||||
ret = simple_write_to_buffer(&dump_data, sizeof(dump_data), ppos,
|
||||
user_buf, count);
|
||||
if (ret < count)
|
||||
return ret;
|
||||
|
||||
skb = alloc_skb(sizeof(dump_data.data), GFP_ATOMIC);
|
||||
if (!skb)
|
||||
return -ENOMEM;
|
||||
skb_put_data(skb, &dump_data.data, sizeof(dump_data.data));
|
||||
|
||||
hci_devcd_register(hdev, vhci_coredump, vhci_coredump_hdr, NULL);
|
||||
|
||||
/* Force the devcoredump timeout */
|
||||
if (dump_data.timeout)
|
||||
force_devcd_timeout(hdev, dump_data.timeout);
|
||||
|
||||
ret = hci_devcd_init(hdev, skb->len);
|
||||
if (ret) {
|
||||
BT_ERR("Failed to generate devcoredump");
|
||||
kfree_skb(skb);
|
||||
return ret;
|
||||
}
|
||||
|
||||
hci_devcd_append(hdev, skb);
|
||||
|
||||
switch (dump_data.state) {
|
||||
case HCI_DEVCOREDUMP_DONE:
|
||||
hci_devcd_complete(hdev);
|
||||
break;
|
||||
case HCI_DEVCOREDUMP_ABORT:
|
||||
hci_devcd_abort(hdev);
|
||||
break;
|
||||
case HCI_DEVCOREDUMP_TIMEOUT:
|
||||
/* Do nothing */
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static const struct file_operations force_devcoredump_fops = {
|
||||
.open = simple_open,
|
||||
.write = force_devcd_write,
|
||||
};
|
||||
|
||||
static int __vhci_create_device(struct vhci_data *data, __u8 opcode)
|
||||
{
|
||||
struct hci_dev *hdev;
|
||||
@ -355,6 +449,9 @@ static int __vhci_create_device(struct vhci_data *data, __u8 opcode)
|
||||
debugfs_create_file("aosp_capable", 0644, hdev->debugfs, data,
|
||||
&aosp_capable_fops);
|
||||
|
||||
debugfs_create_file("force_devcoredump", 0644, hdev->debugfs, data,
|
||||
&force_devcoredump_fops);
|
||||
|
||||
hci_skb_pkt_type(skb) = HCI_VENDOR_PKT;
|
||||
|
||||
skb_put_u8(skb, 0xff);
|
||||
|
Loading…
Reference in New Issue
Block a user