Message ID | ddcbc509b5024882583d5c143ec5f4520bef860a.1683065391.git.objelf@gmail.com (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
Series | [v5,1/3] Bluetooth: btusb: mediatek: use readx_poll_timeout instead of open coding | expand |
Context | Check | Description |
---|---|---|
tedd_an/pre-ci_am | success | Success |
tedd_an/CheckPatch | success | CheckPatch PASS |
tedd_an/GitLint | success | Gitlint PASS |
tedd_an/SubjectPrefix | success | Gitlint PASS |
tedd_an/IncrementalBuild | success | Incremental Build PASS |
Hi, kernel test robot noticed the following build errors: [auto build test ERROR on bluetooth/master] [also build test ERROR on bluetooth-next/master linus/master v6.3 next-20230428] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/sean-wang-mediatek-com/Bluetooth-btmtk-introduce-btmtk-reset-work/20230503-070640 base: https://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth.git master patch link: https://lore.kernel.org/r/ddcbc509b5024882583d5c143ec5f4520bef860a.1683065391.git.objelf%40gmail.com patch subject: [PATCH v5 3/3] Bluetooth: btusb: mediatek: add MediaTek devcoredump support config: x86_64-randconfig-a016-20230501 (https://download.01.org/0day-ci/archive/20230503/202305031708.UQZ6jRn6-lkp@intel.com/config) compiler: clang version 14.0.6 (https://github.com/llvm/llvm-project f28c006a5895fc0e329fe15fead81e37457cb1d1) reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # https://github.com/intel-lab-lkp/linux/commit/635545fc4095e7e6b159177a07b0359b7eafe482 git remote add linux-review https://github.com/intel-lab-lkp/linux git fetch --no-tags linux-review sean-wang-mediatek-com/Bluetooth-btmtk-introduce-btmtk-reset-work/20230503-070640 git checkout 635545fc4095e7e6b159177a07b0359b7eafe482 # save the config file mkdir build_dir && cp config build_dir/.config COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=x86_64 olddefconfig COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=x86_64 SHELL=/bin/bash drivers/bluetooth/ If you fix the issue, kindly add following tag where applicable | Reported-by: kernel test robot <lkp@intel.com> | Link: https://lore.kernel.org/oe-kbuild-all/202305031708.UQZ6jRn6-lkp@intel.com/ All errors (new ones prefixed by >>): drivers/bluetooth/btmtk.c:97:7: error: use of undeclared identifier 'HCI_DEVCOREDUMP_IDLE' case HCI_DEVCOREDUMP_IDLE: ^ drivers/bluetooth/btmtk.c:100:7: error: use of undeclared identifier 'HCI_DEVCOREDUMP_ACTIVE'; did you mean 'BTMTK_COREDUMP_ACTIVE'? case HCI_DEVCOREDUMP_ACTIVE: ^~~~~~~~~~~~~~~~~~~~~~ BTMTK_COREDUMP_ACTIVE drivers/bluetooth/btmtk.c:25:2: note: 'BTMTK_COREDUMP_ACTIVE' declared here BTMTK_COREDUMP_ACTIVE, ^ drivers/bluetooth/btmtk.c:103:7: error: use of undeclared identifier 'HCI_DEVCOREDUMP_TIMEOUT' case HCI_DEVCOREDUMP_TIMEOUT: ^ drivers/bluetooth/btmtk.c:104:7: error: use of undeclared identifier 'HCI_DEVCOREDUMP_ABORT' case HCI_DEVCOREDUMP_ABORT: ^ drivers/bluetooth/btmtk.c:105:7: error: use of undeclared identifier 'HCI_DEVCOREDUMP_DONE' case HCI_DEVCOREDUMP_DONE: ^ drivers/bluetooth/btmtk.c:367:9: error: implicit declaration of function 'hci_devcd_register' is invalid in C99 [-Werror,-Wimplicit-function-declaration] return hci_devcd_register(hdev, btmtk_coredump, btmtk_coredump_hdr, ^ drivers/bluetooth/btmtk.c:385:9: error: implicit declaration of function 'hci_devcd_init' is invalid in C99 [-Werror,-Wimplicit-function-declaration] err = hci_devcd_init(hdev, MTK_COREDUMP_SIZE); ^ drivers/bluetooth/btmtk.c:385:9: note: did you mean 'hci_sock_init'? include/net/bluetooth/bluetooth.h:577:5: note: 'hci_sock_init' declared here int hci_sock_init(void); ^ >> drivers/bluetooth/btmtk.c:389:32: error: no member named 'dump' in 'struct hci_dev' schedule_delayed_work(&hdev->dump.dump_timeout, ~~~~ ^ drivers/bluetooth/btmtk.c:394:9: error: implicit declaration of function 'hci_devcd_append' is invalid in C99 [-Werror,-Wimplicit-function-declaration] err = hci_devcd_append(hdev, skb); ^ drivers/bluetooth/btmtk.c:394:9: note: did you mean 'hci_dev_open'? include/net/bluetooth/hci_core.h:1500:5: note: 'hci_dev_open' declared here int hci_dev_open(__u16 dev); ^ drivers/bluetooth/btmtk.c:401:4: error: implicit declaration of function 'hci_devcd_complete' is invalid in C99 [-Werror,-Wimplicit-function-declaration] hci_devcd_complete(hdev); ^ drivers/bluetooth/btmtk.c:401:4: note: did you mean 'hci_devcd_append'? drivers/bluetooth/btmtk.c:394:9: note: 'hci_devcd_append' declared here err = hci_devcd_append(hdev, skb); ^ 10 errors generated. vim +389 drivers/bluetooth/btmtk.c 371 372 int btmtk_process_coredump(struct hci_dev *hdev, struct sk_buff *skb) 373 { 374 struct btmtk_data *data = hci_get_priv(hdev); 375 int err; 376 377 if (!IS_ENABLED(CONFIG_DEV_COREDUMP)) 378 return 0; 379 380 switch (data->cd_info.state) { 381 case BTMTK_COREDUMP_DISABLED: 382 err = -EINVAL; 383 break; 384 case BTMTK_COREDUMP_INIT: > 385 err = hci_devcd_init(hdev, MTK_COREDUMP_SIZE); 386 if (err < 0) 387 break; 388 /* It is supposed coredump can be done within 5 seconds */ > 389 schedule_delayed_work(&hdev->dump.dump_timeout, 390 msecs_to_jiffies(5000)); 391 fallthrough; 392 case BTMTK_COREDUMP_ACTIVE: 393 default: 394 err = hci_devcd_append(hdev, skb); 395 if (err < 0) 396 break; 397 398 if (skb->len > 12 && 399 !strncmp((char *)&skb->data[skb->len - 13], 400 MTK_COREDUMP_END, 12)) 401 hci_devcd_complete(hdev); 402 403 break; 404 } 405 406 if (err < 0) { 407 data->cd_info.state = BTMTK_COREDUMP_DISABLED; 408 kfree_skb(skb); 409 } 410 411 return err; 412 } 413 EXPORT_SYMBOL_GPL(btmtk_process_coredump); 414
Hi Sean, On Tue, May 2, 2023 at 4:02 PM <sean.wang@mediatek.com> wrote: > > From: Jing Cai <jing.cai@mediatek.com> > > This patch implement function .coredump() and dmp_hdr() in btusb > driver for MediaTek controller. FW core dump was triggered by FW > specific event to show something unexpected happened in the controller. > > The driver would be responsible for collecting and uploading the device > core dump pieces in hci driver using core dump API. Once we finished > the whole process, the driver would reset the controller to recover the > kind of fatal error. > > Co-developed-by: Chris Lu <chris.lu@mediatek.com> > Signed-off-by: Chris Lu <chris.lu@mediatek.com> > Co-developed-by: Sean Wang <sean.wang@mediatek.com> > Signed-off-by: Sean Wang <sean.wang@mediatek.com> > Signed-off-by: Jing Cai <jing.cai@mediatek.com> > --- > v2, v3: rebase onto the latest codebase > v4: update the newest API usage for the coredump which was already > into the upstream > v5: support devcoredump on hdev basis > --- > drivers/bluetooth/btmtk.c | 117 ++++++++++++++++++++++++++++++++++++++ > drivers/bluetooth/btmtk.h | 28 +++++++++ > drivers/bluetooth/btusb.c | 14 +++++ > 3 files changed, 159 insertions(+) > > diff --git a/drivers/bluetooth/btmtk.c b/drivers/bluetooth/btmtk.c > index ac2fac7e3c5f..657792f9dcab 100644 > --- a/drivers/bluetooth/btmtk.c > +++ b/drivers/bluetooth/btmtk.c > @@ -19,6 +19,12 @@ > #define MTK_SEC_MAP_COMMON_SIZE 12 > #define MTK_SEC_MAP_NEED_SEND_SIZE 52 > > +enum { > + BTMTK_COREDUMP_INIT, > + BTMTK_COREDUMP_DISABLED, > + BTMTK_COREDUMP_ACTIVE, > +}; > + > struct btmtk_patch_header { > u8 datetime[16]; > u8 platform[4]; > @@ -53,6 +59,56 @@ struct btmtk_section_map { > }; > } __packed; > > +static void btmtk_coredump(struct hci_dev *hdev) > +{ > + int err; > + > + err = __hci_cmd_send(hdev, 0xfd5b, 0, NULL); > + if (err < 0) > + bt_dev_err(hdev, "Coredump failed (%d)", err); > +} > + > +static void btmtk_coredump_hdr(struct hci_dev *hdev, struct sk_buff *skb) > +{ > + struct btmtk_data *data = hci_get_priv(hdev); > + char buf[80]; > + > + snprintf(buf, sizeof(buf), "Controller Name: 0x%X\n", > + data->cd_info.dev_id); > + skb_put_data(skb, buf, strlen(buf)); > + > + snprintf(buf, sizeof(buf), "Firmware Version: 0x%X\n", > + data->cd_info.fw_version); > + skb_put_data(skb, buf, strlen(buf)); > + > + snprintf(buf, sizeof(buf), "Driver: %s\n", > + data->cd_info.driver_name); > + skb_put_data(skb, buf, strlen(buf)); > + > + snprintf(buf, sizeof(buf), "Vendor: MediaTek\n"); > + skb_put_data(skb, buf, strlen(buf)); > +} > + > +static void btmtk_coredump_notify(struct hci_dev *hdev, int state) > +{ > + struct btmtk_data *data = hci_get_priv(hdev); > + > + switch (state) { > + case HCI_DEVCOREDUMP_IDLE: > + data->cd_info.state = BTMTK_COREDUMP_INIT; > + break; > + case HCI_DEVCOREDUMP_ACTIVE: > + data->cd_info.state = BTMTK_COREDUMP_ACTIVE; > + break; > + case HCI_DEVCOREDUMP_TIMEOUT: > + case HCI_DEVCOREDUMP_ABORT: > + case HCI_DEVCOREDUMP_DONE: > + data->cd_info.state = BTMTK_COREDUMP_INIT; > + btmtk_reset_sync(hdev); > + break; > + } > +} Don't really like where this is going, why can't you just use the state from devcd? > + > int btmtk_setup_firmware_79xx(struct hci_dev *hdev, const char *fwname, > wmt_cmd_sync_func_t wmt_cmd_sync) > { > @@ -295,6 +351,67 @@ void btmtk_reset_sync(struct hci_dev *hdev) > } > EXPORT_SYMBOL_GPL(btmtk_reset_sync); > > +int btmtk_register_coredump(struct hci_dev *hdev, u32 dev_id, > + const char *name, u32 fw_version) > +{ > + struct btmtk_data *data = hci_get_priv(hdev); > + > + if (!IS_ENABLED(CONFIG_DEV_COREDUMP)) > + return -EOPNOTSUPP; > + > + data->cd_info.dev_id = dev_id; > + data->cd_info.fw_version = fw_version; > + data->cd_info.state = BTMTK_COREDUMP_INIT; > + strncpy(data->cd_info.driver_name, name, MTK_DRIVER_NAME_LEN - 1); Im not really sure why every devcd is having to store the driver name as a copy, the driver name is already accessible via hdev->dev->driver->name. @Manish Mandlik we might want to fix any code that still is doing copies of driver name like above. > + > + return hci_devcd_register(hdev, btmtk_coredump, btmtk_coredump_hdr, > + btmtk_coredump_notify); > +} > +EXPORT_SYMBOL_GPL(btmtk_register_coredump); > + > +int btmtk_process_coredump(struct hci_dev *hdev, struct sk_buff *skb) > +{ > + struct btmtk_data *data = hci_get_priv(hdev); > + int err; > + > + if (!IS_ENABLED(CONFIG_DEV_COREDUMP)) > + return 0; > + > + switch (data->cd_info.state) { > + case BTMTK_COREDUMP_DISABLED: > + err = -EINVAL; > + break; > + case BTMTK_COREDUMP_INIT: > + err = hci_devcd_init(hdev, MTK_COREDUMP_SIZE); > + if (err < 0) > + break; > + /* It is supposed coredump can be done within 5 seconds */ > + schedule_delayed_work(&hdev->dump.dump_timeout, > + msecs_to_jiffies(5000)); > + fallthrough; > + case BTMTK_COREDUMP_ACTIVE: > + default: > + err = hci_devcd_append(hdev, skb); > + if (err < 0) > + break; > + > + if (skb->len > 12 && > + !strncmp((char *)&skb->data[skb->len - 13], > + MTK_COREDUMP_END, 12)) > + hci_devcd_complete(hdev); > + > + break; > + } > + > + if (err < 0) { > + data->cd_info.state = BTMTK_COREDUMP_DISABLED; > + kfree_skb(skb); > + } > + > + return err; > +} > +EXPORT_SYMBOL_GPL(btmtk_process_coredump); > + > MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>"); > MODULE_AUTHOR("Mark Chen <mark-yw.chen@mediatek.com>"); > MODULE_DESCRIPTION("Bluetooth support for MediaTek devices ver " VERSION); > diff --git a/drivers/bluetooth/btmtk.h b/drivers/bluetooth/btmtk.h > index 6245662f6ccb..7eb162f0e7aa 100644 > --- a/drivers/bluetooth/btmtk.h > +++ b/drivers/bluetooth/btmtk.h > @@ -21,6 +21,10 @@ > #define MT7921_DLSTATUS 0x7c053c10 > #define BT_DL_STATE BIT(1) > > +#define MTK_DRIVER_NAME_LEN 16 > +#define MTK_COREDUMP_SIZE (1024 * 1000) > +#define MTK_COREDUMP_END "coredump end" > + > enum { > BTMTK_WMT_PATCH_DWNLD = 0x1, > BTMTK_WMT_TEST = 0x2, > @@ -119,12 +123,20 @@ struct btmtk_hci_wmt_params { > u32 *status; > }; > > +struct btmtk_coredump_info { > + char driver_name[MTK_DRIVER_NAME_LEN]; > + u32 dev_id; > + u32 fw_version; > + int state; > +}; > + > typedef int (*wmt_cmd_sync_func_t)(struct hci_dev *, > struct btmtk_hci_wmt_params *); > > typedef int (*btmtk_reset_sync_func_t)(struct hci_dev *, void *); > > struct btmtk_data { > + struct btmtk_coredump_info cd_info; > btmtk_reset_sync_func_t reset_sync; > }; > > @@ -139,6 +151,11 @@ int btmtk_setup_firmware(struct hci_dev *hdev, const char *fwname, > wmt_cmd_sync_func_t wmt_cmd_sync); > > void btmtk_reset_sync(struct hci_dev *hdev); > + > +int btmtk_register_coredump(struct hci_dev *hdev, u32 dev_id, const char *name, > + u32 fw_version); > + > +int btmtk_process_coredump(struct hci_dev *hdev, struct sk_buff *skb); > #else > > static inline int btmtk_set_bdaddr(struct hci_dev *hdev, > @@ -162,4 +179,15 @@ static int btmtk_setup_firmware(struct hci_dev *hdev, const char *fwname, > static void btmtk_reset_sync(struct hci_dev *hdev) > { > } > + > +static int btmtk_register_coredump(struct hci_dev *hdev, u32 dev_id, const char *name, > + u32 fw_version) > +{ > + return -EOPNOTSUPP; > +} > + > +static int btmtk_process_coredump(struct hci_dev *hdev, struct sk_buff *skb) > +{ > + return -EOPNOTSUPP; > +} > #endif > diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c > index 034edd8ad777..1c2a0cbcf62e 100644 > --- a/drivers/bluetooth/btusb.c > +++ b/drivers/bluetooth/btusb.c > @@ -3035,6 +3035,10 @@ static int btusb_mtk_setup(struct hci_dev *hdev) > } > > btmtk_data->reset_sync = btusb_mtk_reset_work; > + err = btmtk_register_coredump(hdev, dev_id, btusb_driver.name, > + fw_version); > + if (err < 0) > + bt_dev_err(hdev, "Failed to register coredump (%d)", err); > > switch (dev_id) { > case 0x7663: > @@ -3189,6 +3193,7 @@ static int btusb_recv_acl_mtk(struct hci_dev *hdev, struct sk_buff *skb) > { > struct btusb_data *data = hci_get_drvdata(hdev); > u16 handle = le16_to_cpu(hci_acl_hdr(skb)->handle); > + struct sk_buff *skb_cd; > > switch (handle) { > case 0xfc6f: /* Firmware dump from device */ > @@ -3196,6 +3201,15 @@ static int btusb_recv_acl_mtk(struct hci_dev *hdev, struct sk_buff *skb) > * suspend and thus disable auto-suspend. > */ > usb_disable_autosuspend(data->udev); > + > + /* We need to forward the diagnostic packet to userspace daemon > + * for backward compatibility, so we have to clone the packet > + * extraly for the in-kernel coredump support. > + */ > + skb_cd = skb_clone(skb, GFP_ATOMIC); > + if (skb_cd) > + btmtk_process_coredump(hdev, skb_cd); > + > fallthrough; > case 0x05ff: /* Firmware debug logging 1 */ > case 0x05fe: /* Firmware debug logging 2 */ > -- > 2.25.1 >
diff --git a/drivers/bluetooth/btmtk.c b/drivers/bluetooth/btmtk.c index ac2fac7e3c5f..657792f9dcab 100644 --- a/drivers/bluetooth/btmtk.c +++ b/drivers/bluetooth/btmtk.c @@ -19,6 +19,12 @@ #define MTK_SEC_MAP_COMMON_SIZE 12 #define MTK_SEC_MAP_NEED_SEND_SIZE 52 +enum { + BTMTK_COREDUMP_INIT, + BTMTK_COREDUMP_DISABLED, + BTMTK_COREDUMP_ACTIVE, +}; + struct btmtk_patch_header { u8 datetime[16]; u8 platform[4]; @@ -53,6 +59,56 @@ struct btmtk_section_map { }; } __packed; +static void btmtk_coredump(struct hci_dev *hdev) +{ + int err; + + err = __hci_cmd_send(hdev, 0xfd5b, 0, NULL); + if (err < 0) + bt_dev_err(hdev, "Coredump failed (%d)", err); +} + +static void btmtk_coredump_hdr(struct hci_dev *hdev, struct sk_buff *skb) +{ + struct btmtk_data *data = hci_get_priv(hdev); + char buf[80]; + + snprintf(buf, sizeof(buf), "Controller Name: 0x%X\n", + data->cd_info.dev_id); + skb_put_data(skb, buf, strlen(buf)); + + snprintf(buf, sizeof(buf), "Firmware Version: 0x%X\n", + data->cd_info.fw_version); + skb_put_data(skb, buf, strlen(buf)); + + snprintf(buf, sizeof(buf), "Driver: %s\n", + data->cd_info.driver_name); + skb_put_data(skb, buf, strlen(buf)); + + snprintf(buf, sizeof(buf), "Vendor: MediaTek\n"); + skb_put_data(skb, buf, strlen(buf)); +} + +static void btmtk_coredump_notify(struct hci_dev *hdev, int state) +{ + struct btmtk_data *data = hci_get_priv(hdev); + + switch (state) { + case HCI_DEVCOREDUMP_IDLE: + data->cd_info.state = BTMTK_COREDUMP_INIT; + break; + case HCI_DEVCOREDUMP_ACTIVE: + data->cd_info.state = BTMTK_COREDUMP_ACTIVE; + break; + case HCI_DEVCOREDUMP_TIMEOUT: + case HCI_DEVCOREDUMP_ABORT: + case HCI_DEVCOREDUMP_DONE: + data->cd_info.state = BTMTK_COREDUMP_INIT; + btmtk_reset_sync(hdev); + break; + } +} + int btmtk_setup_firmware_79xx(struct hci_dev *hdev, const char *fwname, wmt_cmd_sync_func_t wmt_cmd_sync) { @@ -295,6 +351,67 @@ void btmtk_reset_sync(struct hci_dev *hdev) } EXPORT_SYMBOL_GPL(btmtk_reset_sync); +int btmtk_register_coredump(struct hci_dev *hdev, u32 dev_id, + const char *name, u32 fw_version) +{ + struct btmtk_data *data = hci_get_priv(hdev); + + if (!IS_ENABLED(CONFIG_DEV_COREDUMP)) + return -EOPNOTSUPP; + + data->cd_info.dev_id = dev_id; + data->cd_info.fw_version = fw_version; + data->cd_info.state = BTMTK_COREDUMP_INIT; + strncpy(data->cd_info.driver_name, name, MTK_DRIVER_NAME_LEN - 1); + + return hci_devcd_register(hdev, btmtk_coredump, btmtk_coredump_hdr, + btmtk_coredump_notify); +} +EXPORT_SYMBOL_GPL(btmtk_register_coredump); + +int btmtk_process_coredump(struct hci_dev *hdev, struct sk_buff *skb) +{ + struct btmtk_data *data = hci_get_priv(hdev); + int err; + + if (!IS_ENABLED(CONFIG_DEV_COREDUMP)) + return 0; + + switch (data->cd_info.state) { + case BTMTK_COREDUMP_DISABLED: + err = -EINVAL; + break; + case BTMTK_COREDUMP_INIT: + err = hci_devcd_init(hdev, MTK_COREDUMP_SIZE); + if (err < 0) + break; + /* It is supposed coredump can be done within 5 seconds */ + schedule_delayed_work(&hdev->dump.dump_timeout, + msecs_to_jiffies(5000)); + fallthrough; + case BTMTK_COREDUMP_ACTIVE: + default: + err = hci_devcd_append(hdev, skb); + if (err < 0) + break; + + if (skb->len > 12 && + !strncmp((char *)&skb->data[skb->len - 13], + MTK_COREDUMP_END, 12)) + hci_devcd_complete(hdev); + + break; + } + + if (err < 0) { + data->cd_info.state = BTMTK_COREDUMP_DISABLED; + kfree_skb(skb); + } + + return err; +} +EXPORT_SYMBOL_GPL(btmtk_process_coredump); + MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>"); MODULE_AUTHOR("Mark Chen <mark-yw.chen@mediatek.com>"); MODULE_DESCRIPTION("Bluetooth support for MediaTek devices ver " VERSION); diff --git a/drivers/bluetooth/btmtk.h b/drivers/bluetooth/btmtk.h index 6245662f6ccb..7eb162f0e7aa 100644 --- a/drivers/bluetooth/btmtk.h +++ b/drivers/bluetooth/btmtk.h @@ -21,6 +21,10 @@ #define MT7921_DLSTATUS 0x7c053c10 #define BT_DL_STATE BIT(1) +#define MTK_DRIVER_NAME_LEN 16 +#define MTK_COREDUMP_SIZE (1024 * 1000) +#define MTK_COREDUMP_END "coredump end" + enum { BTMTK_WMT_PATCH_DWNLD = 0x1, BTMTK_WMT_TEST = 0x2, @@ -119,12 +123,20 @@ struct btmtk_hci_wmt_params { u32 *status; }; +struct btmtk_coredump_info { + char driver_name[MTK_DRIVER_NAME_LEN]; + u32 dev_id; + u32 fw_version; + int state; +}; + typedef int (*wmt_cmd_sync_func_t)(struct hci_dev *, struct btmtk_hci_wmt_params *); typedef int (*btmtk_reset_sync_func_t)(struct hci_dev *, void *); struct btmtk_data { + struct btmtk_coredump_info cd_info; btmtk_reset_sync_func_t reset_sync; }; @@ -139,6 +151,11 @@ int btmtk_setup_firmware(struct hci_dev *hdev, const char *fwname, wmt_cmd_sync_func_t wmt_cmd_sync); void btmtk_reset_sync(struct hci_dev *hdev); + +int btmtk_register_coredump(struct hci_dev *hdev, u32 dev_id, const char *name, + u32 fw_version); + +int btmtk_process_coredump(struct hci_dev *hdev, struct sk_buff *skb); #else static inline int btmtk_set_bdaddr(struct hci_dev *hdev, @@ -162,4 +179,15 @@ static int btmtk_setup_firmware(struct hci_dev *hdev, const char *fwname, static void btmtk_reset_sync(struct hci_dev *hdev) { } + +static int btmtk_register_coredump(struct hci_dev *hdev, u32 dev_id, const char *name, + u32 fw_version) +{ + return -EOPNOTSUPP; +} + +static int btmtk_process_coredump(struct hci_dev *hdev, struct sk_buff *skb) +{ + return -EOPNOTSUPP; +} #endif diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 034edd8ad777..1c2a0cbcf62e 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -3035,6 +3035,10 @@ static int btusb_mtk_setup(struct hci_dev *hdev) } btmtk_data->reset_sync = btusb_mtk_reset_work; + err = btmtk_register_coredump(hdev, dev_id, btusb_driver.name, + fw_version); + if (err < 0) + bt_dev_err(hdev, "Failed to register coredump (%d)", err); switch (dev_id) { case 0x7663: @@ -3189,6 +3193,7 @@ static int btusb_recv_acl_mtk(struct hci_dev *hdev, struct sk_buff *skb) { struct btusb_data *data = hci_get_drvdata(hdev); u16 handle = le16_to_cpu(hci_acl_hdr(skb)->handle); + struct sk_buff *skb_cd; switch (handle) { case 0xfc6f: /* Firmware dump from device */ @@ -3196,6 +3201,15 @@ static int btusb_recv_acl_mtk(struct hci_dev *hdev, struct sk_buff *skb) * suspend and thus disable auto-suspend. */ usb_disable_autosuspend(data->udev); + + /* We need to forward the diagnostic packet to userspace daemon + * for backward compatibility, so we have to clone the packet + * extraly for the in-kernel coredump support. + */ + skb_cd = skb_clone(skb, GFP_ATOMIC); + if (skb_cd) + btmtk_process_coredump(hdev, skb_cd); + fallthrough; case 0x05ff: /* Firmware debug logging 1 */ case 0x05fe: /* Firmware debug logging 2 */