forked from mirrors/linux
		
	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
					
				
					 2 changed files with 98 additions and 0 deletions
				
			
		|  | @ -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 a new issue
	
	 Manish Mandlik
						Manish Mandlik