Commit ab4e4380 authored by Manish Mandlik's avatar Manish Mandlik Committed by Luiz Augusto von Dentz

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: default avatarManish Mandlik <mmandlik@google.com>
Signed-off-by: default avatarLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
parent 9695ef87
...@@ -363,6 +363,7 @@ config BT_HCIBLUECARD ...@@ -363,6 +363,7 @@ config BT_HCIBLUECARD
config BT_HCIVHCI config BT_HCIVHCI
tristate "HCI VHCI (Virtual HCI device) driver" tristate "HCI VHCI (Virtual HCI device) driver"
select WANT_DEV_COREDUMP
help help
Bluetooth Virtual HCI device driver. Bluetooth Virtual HCI device driver.
This driver is required if you want to use HCI Emulation software. This driver is required if you want to use HCI Emulation software.
......
...@@ -278,6 +278,100 @@ static int vhci_setup(struct hci_dev *hdev) ...@@ -278,6 +278,100 @@ static int vhci_setup(struct hci_dev *hdev)
return 0; 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) static int __vhci_create_device(struct vhci_data *data, __u8 opcode)
{ {
struct hci_dev *hdev; struct hci_dev *hdev;
...@@ -355,6 +449,9 @@ static int __vhci_create_device(struct vhci_data *data, __u8 opcode) ...@@ -355,6 +449,9 @@ static int __vhci_create_device(struct vhci_data *data, __u8 opcode)
debugfs_create_file("aosp_capable", 0644, hdev->debugfs, data, debugfs_create_file("aosp_capable", 0644, hdev->debugfs, data,
&aosp_capable_fops); &aosp_capable_fops);
debugfs_create_file("force_devcoredump", 0644, hdev->debugfs, data,
&force_devcoredump_fops);
hci_skb_pkt_type(skb) = HCI_VENDOR_PKT; hci_skb_pkt_type(skb) = HCI_VENDOR_PKT;
skb_put_u8(skb, 0xff); skb_put_u8(skb, 0xff);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment