diff mbox series

[12/15] Bluetooth: hci_event: Use of a function table to handle HCI events

Message ID 20211201000215.1134831-13-luiz.dentz@gmail.com
State New
Headers show
Series Rework parsing of HCI events | expand

Commit Message

Luiz Augusto von Dentz Dec. 1, 2021, 12:02 a.m. UTC
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

This change the use of switch statement to a function table
which is easier to extend and can include min/max length of each HCI
event.

Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
---
 net/bluetooth/hci_event.c | 903 ++++++++++++++++----------------------
 net/bluetooth/msft.c      |   2 +-
 net/bluetooth/msft.h      |   2 +-
 3 files changed, 391 insertions(+), 516 deletions(-)

Comments

kernel test robot Dec. 1, 2021, 1:54 a.m. UTC | #1
Hi Luiz,

I love your patch! Yet something to improve:

[auto build test ERROR on bluetooth-next/master]
[also build test ERROR on next-20211130]
[cannot apply to net-next/master net/master linus/master v5.16-rc3]
[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]

url:    https://github.com/0day-ci/linux/commits/Luiz-Augusto-von-Dentz/Rework-parsing-of-HCI-events/20211201-080632
base:   https://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next.git master
config: riscv-randconfig-r042-20211128 (https://download.01.org/0day-ci/archive/20211201/202112010916.SwsMdzpu-lkp@intel.com/config)
compiler: riscv32-linux-gcc (GCC) 11.2.0
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/0day-ci/linux/commit/bd4b2eeacef50f9df8f08056e9f6523083ac96f3
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Luiz-Augusto-von-Dentz/Rework-parsing-of-HCI-events/20211201-080632
        git checkout bd4b2eeacef50f9df8f08056e9f6523083ac96f3
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross O=build_dir ARCH=riscv SHELL=/bin/bash net/bluetooth/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

>> net/bluetooth/hci_event.c:7129:31: error: initialization of 'void (*)(struct hci_dev *, void *, struct sk_buff *)' from incompatible pointer type 'void (*)(struct hci_dev *, struct sk_buff *)' [-Werror=incompatible-pointer-types]
    7129 |         HCI_EV(HCI_EV_VENDOR, msft_vendor_evt, 0),
         |                               ^~~~~~~~~~~~~~~
   net/bluetooth/hci_event.c:6952:17: note: in definition of macro 'HCI_EV_VL'
    6952 |         .func = _func, \
         |                 ^~~~~
   net/bluetooth/hci_event.c:7129:9: note: in expansion of macro 'HCI_EV'
    7129 |         HCI_EV(HCI_EV_VENDOR, msft_vendor_evt, 0),
         |         ^~~~~~
   net/bluetooth/hci_event.c:7129:31: note: (near initialization for 'hci_ev_table[255].<anonymous>.func')
    7129 |         HCI_EV(HCI_EV_VENDOR, msft_vendor_evt, 0),
         |                               ^~~~~~~~~~~~~~~
   net/bluetooth/hci_event.c:6952:17: note: in definition of macro 'HCI_EV_VL'
    6952 |         .func = _func, \
         |                 ^~~~~
   net/bluetooth/hci_event.c:7129:9: note: in expansion of macro 'HCI_EV'
    7129 |         HCI_EV(HCI_EV_VENDOR, msft_vendor_evt, 0),
         |         ^~~~~~
   net/bluetooth/hci_event.c:7132:6: warning: no previous prototype for 'hci_event_func' [-Wmissing-prototypes]
    7132 | void hci_event_func(struct hci_dev *hdev, u8 event, struct sk_buff *skb,
         |      ^~~~~~~~~~~~~~
   cc1: some warnings being treated as errors


vim +7129 net/bluetooth/hci_event.c

  6970	
  6971	#define HCI_EV_REQ(_op, _func, _len) \
  6972		HCI_EV_REQ_VL(_op, _func, _len, _len)
  6973	
  6974	/* Entries in this table shall have their position according to the event opcode
  6975	 * they handle so the use of the macros above is recommend since it does attempt
  6976	 * to initialize at its proper index using Designated Initializers that way
  6977	 * events without a callback function don't have entered.
  6978	 */
  6979	static const struct hci_ev {
  6980		bool req;
  6981		union {
  6982			void (*func)(struct hci_dev *hdev, void *data,
  6983				     struct sk_buff *skb);
  6984			void (*func_req)(struct hci_dev *hdev, void *data,
  6985					 struct sk_buff *skb, u16 *opcode, u8 *status,
  6986					 hci_req_complete_t *req_complete,
  6987					 hci_req_complete_skb_t *req_complete_skb);
  6988		};
  6989		u16  min_len;
  6990		u16  max_len;
  6991	} hci_ev_table[U8_MAX + 1] = {
  6992		/* [0x01 = HCI_EV_INQUIRY_COMPLETE] */
  6993		HCI_EV_STATUS(HCI_EV_INQUIRY_COMPLETE, hci_inquiry_complete_evt),
  6994		/* [0x02 = HCI_EV_INQUIRY_RESULT] */
  6995		HCI_EV_VL(HCI_EV_INQUIRY_RESULT, hci_inquiry_result_evt,
  6996			  sizeof(struct hci_ev_inquiry_result), HCI_MAX_EVENT_SIZE),
  6997		/* [0x03 = HCI_EV_CONN_COMPLETE] */
  6998		HCI_EV(HCI_EV_CONN_COMPLETE, hci_conn_complete_evt,
  6999		       sizeof(struct hci_ev_conn_complete)),
  7000		/* [0x04 = HCI_EV_CONN_REQUEST] */
  7001		HCI_EV(HCI_EV_CONN_REQUEST, hci_conn_request_evt,
  7002		       sizeof(struct hci_ev_conn_request)),
  7003		/* [0x05 = HCI_EV_DISCONN_COMPLETE] */
  7004		HCI_EV(HCI_EV_DISCONN_COMPLETE, hci_disconn_complete_evt,
  7005		       sizeof(struct hci_ev_disconn_complete)),
  7006		/* [0x06 = HCI_EV_AUTH_COMPLETE] */
  7007		HCI_EV(HCI_EV_AUTH_COMPLETE, hci_auth_complete_evt,
  7008		       sizeof(struct hci_ev_auth_complete)),
  7009		/* [0x07 = HCI_EV_REMOTE_NAME] */
  7010		HCI_EV(HCI_EV_REMOTE_NAME, hci_remote_name_evt,
  7011		       sizeof(struct hci_ev_remote_name)),
  7012		/* [0x08 = HCI_EV_ENCRYPT_CHANGE] */
  7013		HCI_EV(HCI_EV_ENCRYPT_CHANGE, hci_encrypt_change_evt,
  7014		       sizeof(struct hci_ev_encrypt_change)),
  7015		/* [0x09 = HCI_EV_CHANGE_LINK_KEY_COMPLETE] */
  7016		HCI_EV(HCI_EV_CHANGE_LINK_KEY_COMPLETE,
  7017		       hci_change_link_key_complete_evt,
  7018		       sizeof(struct hci_ev_change_link_key_complete)),
  7019		/* [0x0b = HCI_EV_REMOTE_FEATURES] */
  7020		HCI_EV(HCI_EV_REMOTE_FEATURES, hci_remote_features_evt,
  7021		       sizeof(struct hci_ev_remote_features)),
  7022		/* [0x0e = HCI_EV_CMD_COMPLETE] */
  7023		HCI_EV_REQ_VL(HCI_EV_CMD_COMPLETE, hci_cmd_complete_evt,
  7024			      sizeof(struct hci_ev_cmd_complete), HCI_MAX_EVENT_SIZE),
  7025		/* [0x0f = HCI_EV_CMD_STATUS] */
  7026		HCI_EV_REQ(HCI_EV_CMD_STATUS, hci_cmd_status_evt,
  7027			   sizeof(struct hci_ev_cmd_status)),
  7028		/* [0x10 = HCI_EV_CMD_STATUS] */
  7029		HCI_EV(HCI_EV_HARDWARE_ERROR, hci_hardware_error_evt,
  7030		       sizeof(struct hci_ev_hardware_error)),
  7031		/* [0x12 = HCI_EV_ROLE_CHANGE] */
  7032		HCI_EV(HCI_EV_ROLE_CHANGE, hci_role_change_evt,
  7033		       sizeof(struct hci_ev_role_change)),
  7034		/* [0x13 = HCI_EV_NUM_COMP_PKTS] */
  7035		HCI_EV_VL(HCI_EV_NUM_COMP_PKTS, hci_num_comp_pkts_evt,
  7036			  sizeof(struct hci_ev_num_comp_pkts), HCI_MAX_EVENT_SIZE),
  7037		/* [0x14 = HCI_EV_MODE_CHANGE] */
  7038		HCI_EV(HCI_EV_MODE_CHANGE, hci_mode_change_evt,
  7039		       sizeof(struct hci_ev_mode_change)),
  7040		/* [0x16 = HCI_EV_PIN_CODE_REQ] */
  7041		HCI_EV(HCI_EV_PIN_CODE_REQ, hci_pin_code_request_evt,
  7042		       sizeof(struct hci_ev_pin_code_req)),
  7043		/* [0x17 = HCI_EV_LINK_KEY_REQ] */
  7044		HCI_EV(HCI_EV_LINK_KEY_REQ, hci_link_key_request_evt,
  7045		       sizeof(struct hci_ev_link_key_req)),
  7046		/* [0x18 = HCI_EV_LINK_KEY_NOTIFY] */
  7047		HCI_EV(HCI_EV_LINK_KEY_NOTIFY, hci_link_key_notify_evt,
  7048		       sizeof(struct hci_ev_link_key_notify)),
  7049		/* [0x1c = HCI_EV_CLOCK_OFFSET] */
  7050		HCI_EV(HCI_EV_CLOCK_OFFSET, hci_clock_offset_evt,
  7051		       sizeof(struct hci_ev_clock_offset)),
  7052		/* [0x1d = HCI_EV_PKT_TYPE_CHANGE] */
  7053		HCI_EV(HCI_EV_PKT_TYPE_CHANGE, hci_pkt_type_change_evt,
  7054		       sizeof(struct hci_ev_pkt_type_change)),
  7055		/* [0x20 = HCI_EV_PSCAN_REP_MODE] */
  7056		HCI_EV(HCI_EV_PSCAN_REP_MODE, hci_pscan_rep_mode_evt,
  7057		       sizeof(struct hci_ev_pscan_rep_mode)),
  7058		/* [0x22 = HCI_EV_INQUIRY_RESULT_WITH_RSSI] */
  7059		HCI_EV_VL(HCI_EV_INQUIRY_RESULT_WITH_RSSI,
  7060			  hci_inquiry_result_with_rssi_evt,
  7061			  sizeof(struct hci_ev_inquiry_result_rssi),
  7062			  HCI_MAX_EVENT_SIZE),
  7063		/* [0x23 = HCI_EV_REMOTE_EXT_FEATURES] */
  7064		HCI_EV(HCI_EV_REMOTE_EXT_FEATURES, hci_remote_ext_features_evt,
  7065		       sizeof(struct hci_ev_remote_ext_features)),
  7066		/* [0x2c = HCI_EV_SYNC_CONN_COMPLETE] */
  7067		HCI_EV(HCI_EV_SYNC_CONN_COMPLETE, hci_sync_conn_complete_evt,
  7068		       sizeof(struct hci_ev_sync_conn_complete)),
  7069		/* [0x2d = HCI_EV_EXTENDED_INQUIRY_RESULT] */
  7070		HCI_EV_VL(HCI_EV_EXTENDED_INQUIRY_RESULT,
  7071			  hci_extended_inquiry_result_evt,
  7072			  sizeof(struct hci_ev_ext_inquiry_result), HCI_MAX_EVENT_SIZE),
  7073		/* [0x30 = HCI_EV_KEY_REFRESH_COMPLETE] */
  7074		HCI_EV(HCI_EV_KEY_REFRESH_COMPLETE, hci_key_refresh_complete_evt,
  7075		       sizeof(struct hci_ev_key_refresh_complete)),
  7076		/* [0x31 = HCI_EV_IO_CAPA_REQUEST] */
  7077		HCI_EV(HCI_EV_IO_CAPA_REQUEST, hci_io_capa_request_evt,
  7078		       sizeof(struct hci_ev_io_capa_request)),
  7079		/* [0x32 = HCI_EV_IO_CAPA_REPLY] */
  7080		HCI_EV(HCI_EV_IO_CAPA_REPLY, hci_io_capa_reply_evt,
  7081		       sizeof(struct hci_ev_io_capa_reply)),
  7082		/* [0x33 = HCI_EV_USER_CONFIRM_REQUEST] */
  7083		HCI_EV(HCI_EV_USER_CONFIRM_REQUEST, hci_user_confirm_request_evt,
  7084		       sizeof(struct hci_ev_user_confirm_req)),
  7085		/* [0x34 = HCI_EV_USER_PASSKEY_REQUEST] */
  7086		HCI_EV(HCI_EV_USER_PASSKEY_REQUEST, hci_user_passkey_request_evt,
  7087		       sizeof(struct hci_ev_user_passkey_req)),
  7088		/* [0x35 = HCI_EV_REMOTE_OOB_DATA_REQUEST] */
  7089		HCI_EV(HCI_EV_REMOTE_OOB_DATA_REQUEST, hci_remote_oob_data_request_evt,
  7090		       sizeof(struct hci_ev_remote_oob_data_request)),
  7091		/* [0x36 = HCI_EV_SIMPLE_PAIR_COMPLETE] */
  7092		HCI_EV(HCI_EV_SIMPLE_PAIR_COMPLETE, hci_simple_pair_complete_evt,
  7093		       sizeof(struct hci_ev_simple_pair_complete)),
  7094		/* [0x3b = HCI_EV_USER_PASSKEY_NOTIFY] */
  7095		HCI_EV(HCI_EV_USER_PASSKEY_NOTIFY, hci_user_passkey_notify_evt,
  7096		       sizeof(struct hci_ev_user_passkey_notify)),
  7097		/* [0x3c = HCI_EV_KEYPRESS_NOTIFY] */
  7098		HCI_EV(HCI_EV_KEYPRESS_NOTIFY, hci_keypress_notify_evt,
  7099		       sizeof(struct hci_ev_keypress_notify)),
  7100		/* [0x3d = HCI_EV_REMOTE_HOST_FEATURES] */
  7101		HCI_EV(HCI_EV_REMOTE_HOST_FEATURES, hci_remote_host_features_evt,
  7102		       sizeof(struct hci_ev_remote_host_features)),
  7103		/* [0x3e = HCI_EV_LE_META] */
  7104		HCI_EV_VL(HCI_EV_LE_META, hci_le_meta_evt,
  7105			  sizeof(struct hci_ev_le_meta), HCI_MAX_EVENT_SIZE),
  7106	#if IS_ENABLED(CONFIG_BT_HS)
  7107		/* [0x40 = HCI_EV_PHY_LINK_COMPLETE] */
  7108		HCI_EV(HCI_EV_PHY_LINK_COMPLETE, hci_phy_link_complete_evt,
  7109		       sizeof(struct hci_ev_phy_link_complete)),
  7110		/* [0x41 = HCI_EV_CHANNEL_SELECTED] */
  7111		HCI_EV(HCI_EV_CHANNEL_SELECTED, hci_chan_selected_evt,
  7112		       sizeof(struct hci_ev_channel_selected)),
  7113		/* [0x42 = HCI_EV_DISCONN_PHY_LINK_COMPLETE] */
  7114		HCI_EV(HCI_EV_DISCONN_LOGICAL_LINK_COMPLETE,
  7115		       hci_disconn_loglink_complete_evt,
  7116		       sizeof(struct hci_ev_disconn_logical_link_complete)),
  7117		/* [0x45 = HCI_EV_LOGICAL_LINK_COMPLETE] */
  7118		HCI_EV(HCI_EV_LOGICAL_LINK_COMPLETE, hci_loglink_complete_evt,
  7119		       sizeof(struct hci_ev_logical_link_complete)),
  7120		/* [0x46 = HCI_EV_DISCONN_LOGICAL_LINK_COMPLETE] */
  7121		HCI_EV(HCI_EV_DISCONN_PHY_LINK_COMPLETE,
  7122		       hci_disconn_phylink_complete_evt,
  7123		       sizeof(struct hci_ev_disconn_phy_link_complete)),
  7124	#endif
  7125		/* [0x48 = HCI_EV_NUM_COMP_BLOCKS] */
  7126		HCI_EV(HCI_EV_NUM_COMP_BLOCKS, hci_num_comp_blocks_evt,
  7127		       sizeof(struct hci_ev_num_comp_blocks)),
  7128		/* [0xff = HCI_EV_VENDOR] */
> 7129		HCI_EV(HCI_EV_VENDOR, msft_vendor_evt, 0),
  7130	};
  7131	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
kernel test robot Dec. 1, 2021, 3:22 a.m. UTC | #2
Hi Luiz,

I love your patch! Yet something to improve:

[auto build test ERROR on bluetooth-next/master]
[also build test ERROR on next-20211130]
[cannot apply to net-next/master net/master linus/master bluetooth/master v5.16-rc3]
[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]

url:    https://github.com/0day-ci/linux/commits/Luiz-Augusto-von-Dentz/Rework-parsing-of-HCI-events/20211201-080632
base:   https://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next.git master
config: hexagon-randconfig-r026-20211130 (https://download.01.org/0day-ci/archive/20211201/202112011149.SZaZiW8X-lkp@intel.com/config)
compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project 25eb7fa01d7ebbe67648ea03841cda55b4239ab2)
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/0day-ci/linux/commit/bd4b2eeacef50f9df8f08056e9f6523083ac96f3
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Luiz-Augusto-von-Dentz/Rework-parsing-of-HCI-events/20211201-080632
        git checkout bd4b2eeacef50f9df8f08056e9f6523083ac96f3
        # save the config file to linux build tree
        mkdir build_dir
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=hexagon SHELL=/bin/bash net/bluetooth/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All error/warnings (new ones prefixed by >>):

>> net/bluetooth/hci_event.c:7129:24: error: incompatible function pointer types initializing 'void (*)(struct hci_dev *, void *, struct sk_buff *)' with an expression of type 'void (struct hci_dev *, struct sk_buff *)' [-Werror,-Wincompatible-function-pointer-types]
           HCI_EV(HCI_EV_VENDOR, msft_vendor_evt, 0),
                                 ^~~~~~~~~~~~~~~
   net/bluetooth/hci_event.c:6958:17: note: expanded from macro 'HCI_EV'
           HCI_EV_VL(_op, _func, _len, _len)
                          ^~~~~
   net/bluetooth/hci_event.c:6952:10: note: expanded from macro 'HCI_EV_VL'
           .func = _func, \
                   ^~~~~
>> net/bluetooth/hci_event.c:7132:6: warning: no previous prototype for function 'hci_event_func' [-Wmissing-prototypes]
   void hci_event_func(struct hci_dev *hdev, u8 event, struct sk_buff *skb,
        ^
   net/bluetooth/hci_event.c:7132:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
   void hci_event_func(struct hci_dev *hdev, u8 event, struct sk_buff *skb,
   ^
   static 
   1 warning and 1 error generated.


vim +7129 net/bluetooth/hci_event.c

  6970	
  6971	#define HCI_EV_REQ(_op, _func, _len) \
  6972		HCI_EV_REQ_VL(_op, _func, _len, _len)
  6973	
  6974	/* Entries in this table shall have their position according to the event opcode
  6975	 * they handle so the use of the macros above is recommend since it does attempt
  6976	 * to initialize at its proper index using Designated Initializers that way
  6977	 * events without a callback function don't have entered.
  6978	 */
  6979	static const struct hci_ev {
  6980		bool req;
  6981		union {
  6982			void (*func)(struct hci_dev *hdev, void *data,
  6983				     struct sk_buff *skb);
  6984			void (*func_req)(struct hci_dev *hdev, void *data,
  6985					 struct sk_buff *skb, u16 *opcode, u8 *status,
  6986					 hci_req_complete_t *req_complete,
  6987					 hci_req_complete_skb_t *req_complete_skb);
  6988		};
  6989		u16  min_len;
  6990		u16  max_len;
  6991	} hci_ev_table[U8_MAX + 1] = {
  6992		/* [0x01 = HCI_EV_INQUIRY_COMPLETE] */
  6993		HCI_EV_STATUS(HCI_EV_INQUIRY_COMPLETE, hci_inquiry_complete_evt),
  6994		/* [0x02 = HCI_EV_INQUIRY_RESULT] */
  6995		HCI_EV_VL(HCI_EV_INQUIRY_RESULT, hci_inquiry_result_evt,
  6996			  sizeof(struct hci_ev_inquiry_result), HCI_MAX_EVENT_SIZE),
  6997		/* [0x03 = HCI_EV_CONN_COMPLETE] */
  6998		HCI_EV(HCI_EV_CONN_COMPLETE, hci_conn_complete_evt,
  6999		       sizeof(struct hci_ev_conn_complete)),
  7000		/* [0x04 = HCI_EV_CONN_REQUEST] */
  7001		HCI_EV(HCI_EV_CONN_REQUEST, hci_conn_request_evt,
  7002		       sizeof(struct hci_ev_conn_request)),
  7003		/* [0x05 = HCI_EV_DISCONN_COMPLETE] */
  7004		HCI_EV(HCI_EV_DISCONN_COMPLETE, hci_disconn_complete_evt,
  7005		       sizeof(struct hci_ev_disconn_complete)),
  7006		/* [0x06 = HCI_EV_AUTH_COMPLETE] */
  7007		HCI_EV(HCI_EV_AUTH_COMPLETE, hci_auth_complete_evt,
  7008		       sizeof(struct hci_ev_auth_complete)),
  7009		/* [0x07 = HCI_EV_REMOTE_NAME] */
  7010		HCI_EV(HCI_EV_REMOTE_NAME, hci_remote_name_evt,
  7011		       sizeof(struct hci_ev_remote_name)),
  7012		/* [0x08 = HCI_EV_ENCRYPT_CHANGE] */
  7013		HCI_EV(HCI_EV_ENCRYPT_CHANGE, hci_encrypt_change_evt,
  7014		       sizeof(struct hci_ev_encrypt_change)),
  7015		/* [0x09 = HCI_EV_CHANGE_LINK_KEY_COMPLETE] */
  7016		HCI_EV(HCI_EV_CHANGE_LINK_KEY_COMPLETE,
  7017		       hci_change_link_key_complete_evt,
  7018		       sizeof(struct hci_ev_change_link_key_complete)),
  7019		/* [0x0b = HCI_EV_REMOTE_FEATURES] */
  7020		HCI_EV(HCI_EV_REMOTE_FEATURES, hci_remote_features_evt,
  7021		       sizeof(struct hci_ev_remote_features)),
  7022		/* [0x0e = HCI_EV_CMD_COMPLETE] */
  7023		HCI_EV_REQ_VL(HCI_EV_CMD_COMPLETE, hci_cmd_complete_evt,
  7024			      sizeof(struct hci_ev_cmd_complete), HCI_MAX_EVENT_SIZE),
  7025		/* [0x0f = HCI_EV_CMD_STATUS] */
  7026		HCI_EV_REQ(HCI_EV_CMD_STATUS, hci_cmd_status_evt,
  7027			   sizeof(struct hci_ev_cmd_status)),
  7028		/* [0x10 = HCI_EV_CMD_STATUS] */
  7029		HCI_EV(HCI_EV_HARDWARE_ERROR, hci_hardware_error_evt,
  7030		       sizeof(struct hci_ev_hardware_error)),
  7031		/* [0x12 = HCI_EV_ROLE_CHANGE] */
  7032		HCI_EV(HCI_EV_ROLE_CHANGE, hci_role_change_evt,
  7033		       sizeof(struct hci_ev_role_change)),
  7034		/* [0x13 = HCI_EV_NUM_COMP_PKTS] */
  7035		HCI_EV_VL(HCI_EV_NUM_COMP_PKTS, hci_num_comp_pkts_evt,
  7036			  sizeof(struct hci_ev_num_comp_pkts), HCI_MAX_EVENT_SIZE),
  7037		/* [0x14 = HCI_EV_MODE_CHANGE] */
  7038		HCI_EV(HCI_EV_MODE_CHANGE, hci_mode_change_evt,
  7039		       sizeof(struct hci_ev_mode_change)),
  7040		/* [0x16 = HCI_EV_PIN_CODE_REQ] */
  7041		HCI_EV(HCI_EV_PIN_CODE_REQ, hci_pin_code_request_evt,
  7042		       sizeof(struct hci_ev_pin_code_req)),
  7043		/* [0x17 = HCI_EV_LINK_KEY_REQ] */
  7044		HCI_EV(HCI_EV_LINK_KEY_REQ, hci_link_key_request_evt,
  7045		       sizeof(struct hci_ev_link_key_req)),
  7046		/* [0x18 = HCI_EV_LINK_KEY_NOTIFY] */
  7047		HCI_EV(HCI_EV_LINK_KEY_NOTIFY, hci_link_key_notify_evt,
  7048		       sizeof(struct hci_ev_link_key_notify)),
  7049		/* [0x1c = HCI_EV_CLOCK_OFFSET] */
  7050		HCI_EV(HCI_EV_CLOCK_OFFSET, hci_clock_offset_evt,
  7051		       sizeof(struct hci_ev_clock_offset)),
  7052		/* [0x1d = HCI_EV_PKT_TYPE_CHANGE] */
  7053		HCI_EV(HCI_EV_PKT_TYPE_CHANGE, hci_pkt_type_change_evt,
  7054		       sizeof(struct hci_ev_pkt_type_change)),
  7055		/* [0x20 = HCI_EV_PSCAN_REP_MODE] */
  7056		HCI_EV(HCI_EV_PSCAN_REP_MODE, hci_pscan_rep_mode_evt,
  7057		       sizeof(struct hci_ev_pscan_rep_mode)),
  7058		/* [0x22 = HCI_EV_INQUIRY_RESULT_WITH_RSSI] */
  7059		HCI_EV_VL(HCI_EV_INQUIRY_RESULT_WITH_RSSI,
  7060			  hci_inquiry_result_with_rssi_evt,
  7061			  sizeof(struct hci_ev_inquiry_result_rssi),
  7062			  HCI_MAX_EVENT_SIZE),
  7063		/* [0x23 = HCI_EV_REMOTE_EXT_FEATURES] */
  7064		HCI_EV(HCI_EV_REMOTE_EXT_FEATURES, hci_remote_ext_features_evt,
  7065		       sizeof(struct hci_ev_remote_ext_features)),
  7066		/* [0x2c = HCI_EV_SYNC_CONN_COMPLETE] */
  7067		HCI_EV(HCI_EV_SYNC_CONN_COMPLETE, hci_sync_conn_complete_evt,
  7068		       sizeof(struct hci_ev_sync_conn_complete)),
  7069		/* [0x2d = HCI_EV_EXTENDED_INQUIRY_RESULT] */
  7070		HCI_EV_VL(HCI_EV_EXTENDED_INQUIRY_RESULT,
  7071			  hci_extended_inquiry_result_evt,
  7072			  sizeof(struct hci_ev_ext_inquiry_result), HCI_MAX_EVENT_SIZE),
  7073		/* [0x30 = HCI_EV_KEY_REFRESH_COMPLETE] */
  7074		HCI_EV(HCI_EV_KEY_REFRESH_COMPLETE, hci_key_refresh_complete_evt,
  7075		       sizeof(struct hci_ev_key_refresh_complete)),
  7076		/* [0x31 = HCI_EV_IO_CAPA_REQUEST] */
  7077		HCI_EV(HCI_EV_IO_CAPA_REQUEST, hci_io_capa_request_evt,
  7078		       sizeof(struct hci_ev_io_capa_request)),
  7079		/* [0x32 = HCI_EV_IO_CAPA_REPLY] */
  7080		HCI_EV(HCI_EV_IO_CAPA_REPLY, hci_io_capa_reply_evt,
  7081		       sizeof(struct hci_ev_io_capa_reply)),
  7082		/* [0x33 = HCI_EV_USER_CONFIRM_REQUEST] */
  7083		HCI_EV(HCI_EV_USER_CONFIRM_REQUEST, hci_user_confirm_request_evt,
  7084		       sizeof(struct hci_ev_user_confirm_req)),
  7085		/* [0x34 = HCI_EV_USER_PASSKEY_REQUEST] */
  7086		HCI_EV(HCI_EV_USER_PASSKEY_REQUEST, hci_user_passkey_request_evt,
  7087		       sizeof(struct hci_ev_user_passkey_req)),
  7088		/* [0x35 = HCI_EV_REMOTE_OOB_DATA_REQUEST] */
  7089		HCI_EV(HCI_EV_REMOTE_OOB_DATA_REQUEST, hci_remote_oob_data_request_evt,
  7090		       sizeof(struct hci_ev_remote_oob_data_request)),
  7091		/* [0x36 = HCI_EV_SIMPLE_PAIR_COMPLETE] */
  7092		HCI_EV(HCI_EV_SIMPLE_PAIR_COMPLETE, hci_simple_pair_complete_evt,
  7093		       sizeof(struct hci_ev_simple_pair_complete)),
  7094		/* [0x3b = HCI_EV_USER_PASSKEY_NOTIFY] */
  7095		HCI_EV(HCI_EV_USER_PASSKEY_NOTIFY, hci_user_passkey_notify_evt,
  7096		       sizeof(struct hci_ev_user_passkey_notify)),
  7097		/* [0x3c = HCI_EV_KEYPRESS_NOTIFY] */
  7098		HCI_EV(HCI_EV_KEYPRESS_NOTIFY, hci_keypress_notify_evt,
  7099		       sizeof(struct hci_ev_keypress_notify)),
  7100		/* [0x3d = HCI_EV_REMOTE_HOST_FEATURES] */
  7101		HCI_EV(HCI_EV_REMOTE_HOST_FEATURES, hci_remote_host_features_evt,
  7102		       sizeof(struct hci_ev_remote_host_features)),
  7103		/* [0x3e = HCI_EV_LE_META] */
  7104		HCI_EV_VL(HCI_EV_LE_META, hci_le_meta_evt,
  7105			  sizeof(struct hci_ev_le_meta), HCI_MAX_EVENT_SIZE),
  7106	#if IS_ENABLED(CONFIG_BT_HS)
  7107		/* [0x40 = HCI_EV_PHY_LINK_COMPLETE] */
  7108		HCI_EV(HCI_EV_PHY_LINK_COMPLETE, hci_phy_link_complete_evt,
  7109		       sizeof(struct hci_ev_phy_link_complete)),
  7110		/* [0x41 = HCI_EV_CHANNEL_SELECTED] */
  7111		HCI_EV(HCI_EV_CHANNEL_SELECTED, hci_chan_selected_evt,
  7112		       sizeof(struct hci_ev_channel_selected)),
  7113		/* [0x42 = HCI_EV_DISCONN_PHY_LINK_COMPLETE] */
  7114		HCI_EV(HCI_EV_DISCONN_LOGICAL_LINK_COMPLETE,
  7115		       hci_disconn_loglink_complete_evt,
  7116		       sizeof(struct hci_ev_disconn_logical_link_complete)),
  7117		/* [0x45 = HCI_EV_LOGICAL_LINK_COMPLETE] */
  7118		HCI_EV(HCI_EV_LOGICAL_LINK_COMPLETE, hci_loglink_complete_evt,
  7119		       sizeof(struct hci_ev_logical_link_complete)),
  7120		/* [0x46 = HCI_EV_DISCONN_LOGICAL_LINK_COMPLETE] */
  7121		HCI_EV(HCI_EV_DISCONN_PHY_LINK_COMPLETE,
  7122		       hci_disconn_phylink_complete_evt,
  7123		       sizeof(struct hci_ev_disconn_phy_link_complete)),
  7124	#endif
  7125		/* [0x48 = HCI_EV_NUM_COMP_BLOCKS] */
  7126		HCI_EV(HCI_EV_NUM_COMP_BLOCKS, hci_num_comp_blocks_evt,
  7127		       sizeof(struct hci_ev_num_comp_blocks)),
  7128		/* [0xff = HCI_EV_VENDOR] */
> 7129		HCI_EV(HCI_EV_VENDOR, msft_vendor_evt, 0),
  7130	};
  7131	
> 7132	void hci_event_func(struct hci_dev *hdev, u8 event, struct sk_buff *skb,
  7133			    u16 *opcode, u8 *status, hci_req_complete_t *req_complete,
  7134			    hci_req_complete_skb_t *req_complete_skb)
  7135	{
  7136		const struct hci_ev *ev = &hci_ev_table[event];
  7137		void *data;
  7138	
  7139		if (!ev->func)
  7140			return;
  7141	
  7142		if (skb->len < ev->min_len) {
  7143			bt_dev_err(hdev, "unexpected event 0x%2.2x length: %u < %u",
  7144				   event, skb->len, ev->min_len);
  7145			return;
  7146		}
  7147	
  7148		/* Just warn if the length is over max_len size it still be
  7149		 * possible to partially parse the event so leave to callback to
  7150		 * decide if that is acceptable.
  7151		 */
  7152		if (skb->len > ev->max_len)
  7153			bt_dev_warn(hdev, "unexpected event 0x%2.2x length: %u > %u",
  7154				    event, skb->len, ev->max_len);
  7155	
  7156		data = hci_ev_skb_pull(hdev, skb, event, ev->min_len);
  7157		if (!data)
  7158			return;
  7159	
  7160		if (ev->req)
  7161			ev->func_req(hdev, data, skb, opcode, status, req_complete,
  7162				     req_complete_skb);
  7163		else
  7164			ev->func(hdev, data, skb);
  7165	}
  7166	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
Mike Lothian Jan. 25, 2022, 2:46 p.m. UTC | #3
Hi

This patch is causing a lot of spam in my dmesg at boot until it seems my wifi connects (or perhaps the bluetooth manager does something)

Bluetooth: hci0: unexpected event 0xff length: 5 > 0

Thanks

Mike
Mike Lothian March 12, 2022, 1:56 a.m. UTC | #4
On Tue, 25 Jan 2022 at 14:46, Mike Lothian <mike@fireburn.co.uk> wrote:
>
> Hi
>
> This patch is causing a lot of spam in my dmesg at boot until it seems my wifi connects (or perhaps the bluetooth manager does something)
>
> Bluetooth: hci0: unexpected event 0xff length: 5 > 0
>
> Thanks
>
> Mike

Hi

Has there been any movement on this issue?

I'm currently running with this patch locally to make the dmesg spam go away
Dan Carpenter March 12, 2022, 2:45 p.m. UTC | #5
On Sat, Mar 12, 2022 at 01:56:13AM +0000, Mike Lothian wrote:
> On Tue, 25 Jan 2022 at 14:46, Mike Lothian <mike@fireburn.co.uk> wrote:
> >
> > Hi
> >
> > This patch is causing a lot of spam in my dmesg at boot until it seems my wifi connects (or perhaps the bluetooth manager does something)
> >
> > Bluetooth: hci0: unexpected event 0xff length: 5 > 0
> >
> > Thanks
> >
> > Mike
> 
> Hi
> 
> Has there been any movement on this issue?
> 
> I'm currently running with this patch locally to make the dmesg spam go away
> 
> >From f786c85baac0ee93730998fa52cbd588c9f39286 Mon Sep 17 00:00:00 2001
> From: Mike Lothian <mike@fireburn.co.uk>
> Date: Tue, 25 Jan 2022 14:52:00 +0000
> Subject: [PATCH] Remove excessive bluetooth warning
> 
> ---

It seems reasonable enought to remove a spammy error message.

Can you resend your patch in the proper format with a proper subject,
commit message and signed-off-by line?

regards,
dan carpenter
Mike Lothian March 14, 2022, 1:14 p.m. UTC | #6
On Sat, 12 Mar 2022 at 14:45, Dan Carpenter <dan.carpenter@oracle.com> wrote:
>
> It seems reasonable enought to remove a spammy error message.
>
> Can you resend your patch in the proper format with a proper subject,
> commit message and signed-off-by line?
>
> regards,
> dan carpenter
>

I've done that, but I'm not sure if I need to do anything else

The patch was based against 5.17-rc7, but just let me know if I need
to rebase it to a different tree

Cheers

Mike
diff mbox series

Patch

diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 8f21405997d1..6fbb16997849 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -3126,17 +3126,14 @@  static void hci_cs_switch_role(struct hci_dev *hdev, u8 status)
 	hci_dev_unlock(hdev);
 }
 
-static void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
+static void hci_inquiry_complete_evt(struct hci_dev *hdev, void *data,
+				     struct sk_buff *skb)
 {
-	struct hci_ev_status *ev;
+	struct hci_ev_status *ev = data;
 	struct discovery_state *discov = &hdev->discovery;
 	struct inquiry_entry *e;
 
-	ev = hci_ev_skb_pull(hdev, skb, HCI_EV_INQUIRY_COMPLETE, sizeof(*ev));
-	if (!ev)
-		return;
-
-	BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
+	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
 
 	hci_conn_check_pending(hdev);
 
@@ -3190,21 +3187,18 @@  static void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
 	hci_dev_unlock(hdev);
 }
 
-static void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
+static void hci_inquiry_result_evt(struct hci_dev *hdev, void *edata,
+				   struct sk_buff *skb)
 {
-	struct hci_ev_inquiry_result *ev;
+	struct hci_ev_inquiry_result *ev = edata;
 	struct inquiry_data data;
 	int i;
 
-	ev = hci_ev_skb_pull(hdev, skb, HCI_EV_INQUIRY_RESULT, sizeof(*ev));
-	if (!ev)
-		return;
-
 	if (!hci_ev_skb_pull(hdev, skb, HCI_EV_INQUIRY_RESULT,
 			     flex_array_size(ev, info, ev->num)))
 		return;
 
-	BT_DBG("%s num %d", hdev->name, ev->num);
+	bt_dev_dbg(hdev, "num %d", ev->num);
 
 	if (!ev->num)
 		return;
@@ -3237,16 +3231,13 @@  static void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
 	hci_dev_unlock(hdev);
 }
 
-static void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
+static void hci_conn_complete_evt(struct hci_dev *hdev, void *data,
+				  struct sk_buff *skb)
 {
-	struct hci_ev_conn_complete *ev;
+	struct hci_ev_conn_complete *ev = data;
 	struct hci_conn *conn;
 
-	ev = hci_ev_skb_pull(hdev, skb, HCI_EV_CONN_COMPLETE, sizeof(*ev));
-	if (!ev)
-		return;
-
-	BT_DBG("%s", hdev->name);
+	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
 
 	hci_dev_lock(hdev);
 
@@ -3365,20 +3356,16 @@  static void hci_reject_conn(struct hci_dev *hdev, bdaddr_t *bdaddr)
 	hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp);
 }
 
-static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
+static void hci_conn_request_evt(struct hci_dev *hdev, void *data,
+				 struct sk_buff *skb)
 {
-	struct hci_ev_conn_request *ev;
+	struct hci_ev_conn_request *ev = data;
 	int mask = hdev->link_mode;
 	struct inquiry_entry *ie;
 	struct hci_conn *conn;
 	__u8 flags = 0;
 
-	ev = hci_ev_skb_pull(hdev, skb, HCI_EV_CONN_REQUEST, sizeof(*ev));
-	if (!ev)
-		return;
-
-	BT_DBG("%s bdaddr %pMR type 0x%x", hdev->name, &ev->bdaddr,
-	       ev->link_type);
+	bt_dev_dbg(hdev, "bdaddr %pMR type 0x%x", &ev->bdaddr, ev->link_type);
 
 	mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type,
 				      &flags);
@@ -3480,19 +3467,16 @@  static u8 hci_to_mgmt_reason(u8 err)
 	}
 }
 
-static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
+static void hci_disconn_complete_evt(struct hci_dev *hdev, void *data,
+				     struct sk_buff *skb)
 {
-	struct hci_ev_disconn_complete *ev;
+	struct hci_ev_disconn_complete *ev = data;
 	u8 reason;
 	struct hci_conn_params *params;
 	struct hci_conn *conn;
 	bool mgmt_connected;
 
-	ev = hci_ev_skb_pull(hdev, skb, HCI_EV_DISCONN_COMPLETE, sizeof(*ev));
-	if (!ev)
-		return;
-
-	BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
+	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
 
 	hci_dev_lock(hdev);
 
@@ -3568,16 +3552,13 @@  static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
 	hci_dev_unlock(hdev);
 }
 
-static void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
+static void hci_auth_complete_evt(struct hci_dev *hdev, void *data,
+				  struct sk_buff *skb)
 {
-	struct hci_ev_auth_complete *ev;
+	struct hci_ev_auth_complete *ev = data;
 	struct hci_conn *conn;
 
-	ev = hci_ev_skb_pull(hdev, skb, HCI_EV_AUTH_COMPLETE, sizeof(*ev));
-	if (!ev)
-		return;
-
-	BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
+	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
 
 	hci_dev_lock(hdev);
 
@@ -3642,16 +3623,13 @@  static void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
 	hci_dev_unlock(hdev);
 }
 
-static void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb)
+static void hci_remote_name_evt(struct hci_dev *hdev, void *data,
+				struct sk_buff *skb)
 {
-	struct hci_ev_remote_name *ev;
+	struct hci_ev_remote_name *ev = data;
 	struct hci_conn *conn;
 
-	ev = hci_ev_skb_pull(hdev, skb, HCI_EV_REMOTE_NAME, sizeof(*ev));
-	if (!ev)
-		return;
-
-	BT_DBG("%s", hdev->name);
+	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
 
 	hci_conn_check_pending(hdev);
 
@@ -3729,16 +3707,13 @@  static void read_enc_key_size_complete(struct hci_dev *hdev, u8 status,
 	hci_dev_unlock(hdev);
 }
 
-static void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
+static void hci_encrypt_change_evt(struct hci_dev *hdev, void *data,
+				   struct sk_buff *skb)
 {
-	struct hci_ev_encrypt_change *ev;
+	struct hci_ev_encrypt_change *ev = data;
 	struct hci_conn *conn;
 
-	ev = hci_ev_skb_pull(hdev, skb, HCI_EV_ENCRYPT_CHANGE, sizeof(*ev));
-	if (!ev)
-		return;
-
-	BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
+	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
 
 	hci_dev_lock(hdev);
 
@@ -3847,18 +3822,13 @@  static void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
 	hci_dev_unlock(hdev);
 }
 
-static void hci_change_link_key_complete_evt(struct hci_dev *hdev,
+static void hci_change_link_key_complete_evt(struct hci_dev *hdev, void *data,
 					     struct sk_buff *skb)
 {
-	struct hci_ev_change_link_key_complete *ev;
+	struct hci_ev_change_link_key_complete *ev = data;
 	struct hci_conn *conn;
 
-	ev = hci_ev_skb_pull(hdev, skb, HCI_EV_CHANGE_LINK_KEY_COMPLETE,
-			     sizeof(*ev));
-	if (!ev)
-		return;
-
-	BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
+	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
 
 	hci_dev_lock(hdev);
 
@@ -3875,17 +3845,13 @@  static void hci_change_link_key_complete_evt(struct hci_dev *hdev,
 	hci_dev_unlock(hdev);
 }
 
-static void hci_remote_features_evt(struct hci_dev *hdev,
+static void hci_remote_features_evt(struct hci_dev *hdev, void *data,
 				    struct sk_buff *skb)
 {
-	struct hci_ev_remote_features *ev;
+	struct hci_ev_remote_features *ev = data;
 	struct hci_conn *conn;
 
-	ev = hci_ev_skb_pull(hdev, skb, HCI_EV_REMOTE_FEATURES, sizeof(*ev));
-	if (!ev)
-		return;
-
-	BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
+	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
 
 	hci_dev_lock(hdev);
 
@@ -3943,16 +3909,12 @@  static inline void handle_cmd_cnt_and_timer(struct hci_dev *hdev, u8 ncmd)
 	}
 }
 
-static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb,
-				 u16 *opcode, u8 *status,
+static void hci_cmd_complete_evt(struct hci_dev *hdev, void *data,
+				 struct sk_buff *skb, u16 *opcode, u8 *status,
 				 hci_req_complete_t *req_complete,
 				 hci_req_complete_skb_t *req_complete_skb)
 {
-	struct hci_ev_cmd_complete *ev;
-
-	ev = hci_ev_skb_pull(hdev, skb, HCI_EV_CMD_COMPLETE, sizeof(*ev));
-	if (!ev)
-		return;
+	struct hci_ev_cmd_complete *ev = data;
 
 	*opcode = __le16_to_cpu(ev->opcode);
 	*status = skb->data[0];
@@ -4330,16 +4292,12 @@  static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb,
 		queue_work(hdev->workqueue, &hdev->cmd_work);
 }
 
-static void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb,
-			       u16 *opcode, u8 *status,
+static void hci_cmd_status_evt(struct hci_dev *hdev, void *data,
+			       struct sk_buff *skb, u16 *opcode, u8 *status,
 			       hci_req_complete_t *req_complete,
 			       hci_req_complete_skb_t *req_complete_skb)
 {
-	struct hci_ev_cmd_status *ev;
-
-	ev = hci_ev_skb_pull(hdev, skb, HCI_EV_CMD_STATUS, sizeof(*ev));
-	if (!ev)
-		return;
+	struct hci_ev_cmd_status *ev = data;
 
 	*opcode = __le16_to_cpu(ev->opcode);
 	*status = ev->status;
@@ -4445,29 +4403,25 @@  static void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb,
 		queue_work(hdev->workqueue, &hdev->cmd_work);
 }
 
-static void hci_hardware_error_evt(struct hci_dev *hdev, struct sk_buff *skb)
+static void hci_hardware_error_evt(struct hci_dev *hdev, void *data,
+				   struct sk_buff *skb)
 {
-	struct hci_ev_hardware_error *ev;
+	struct hci_ev_hardware_error *ev = data;
 
-	ev = hci_ev_skb_pull(hdev, skb, HCI_EV_HARDWARE_ERROR, sizeof(*ev));
-	if (!ev)
-		return;
+	bt_dev_dbg(hdev, "code 0x%2.2x", ev->code);
 
 	hdev->hw_error_code = ev->code;
 
 	queue_work(hdev->req_workqueue, &hdev->error_reset);
 }
 
-static void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
+static void hci_role_change_evt(struct hci_dev *hdev, void *data,
+				struct sk_buff *skb)
 {
-	struct hci_ev_role_change *ev;
+	struct hci_ev_role_change *ev = data;
 	struct hci_conn *conn;
 
-	ev = hci_ev_skb_pull(hdev, skb, HCI_EV_ROLE_CHANGE, sizeof(*ev));
-	if (!ev)
-		return;
-
-	BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
+	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
 
 	hci_dev_lock(hdev);
 
@@ -4484,15 +4438,12 @@  static void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
 	hci_dev_unlock(hdev);
 }
 
-static void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
+static void hci_num_comp_pkts_evt(struct hci_dev *hdev, void *data,
+				  struct sk_buff *skb)
 {
-	struct hci_ev_num_comp_pkts *ev;
+	struct hci_ev_num_comp_pkts *ev = data;
 	int i;
 
-	ev = hci_ev_skb_pull(hdev, skb, HCI_EV_NUM_COMP_PKTS, sizeof(*ev));
-	if (!ev)
-		return;
-
 	if (!hci_ev_skb_pull(hdev, skb, HCI_EV_NUM_COMP_PKTS,
 			     flex_array_size(ev, handles, ev->num)))
 		return;
@@ -4502,7 +4453,7 @@  static void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
 		return;
 	}
 
-	BT_DBG("%s num %d", hdev->name, ev->num);
+	bt_dev_dbg(hdev, "num %d", ev->num);
 
 	for (i = 0; i < ev->num; i++) {
 		struct hci_comp_pkts_info *info = &ev->handles[i];
@@ -4574,26 +4525,24 @@  static struct hci_conn *__hci_conn_lookup_handle(struct hci_dev *hdev,
 	return NULL;
 }
 
-static void hci_num_comp_blocks_evt(struct hci_dev *hdev, struct sk_buff *skb)
+static void hci_num_comp_blocks_evt(struct hci_dev *hdev, void *data,
+				    struct sk_buff *skb)
 {
-	struct hci_ev_num_comp_blocks *ev;
+	struct hci_ev_num_comp_blocks *ev = data;
 	int i;
 
-	ev = hci_ev_skb_pull(hdev, skb, HCI_EV_NUM_COMP_BLOCKS, sizeof(*ev));
-	if (!ev)
-		return;
-
 	if (!hci_ev_skb_pull(hdev, skb, HCI_EV_NUM_COMP_BLOCKS,
 			     flex_array_size(ev, handles, ev->num_hndl)))
 		return;
 
 	if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_BLOCK_BASED) {
-		bt_dev_err(hdev, "wrong event for mode %d", hdev->flow_ctl_mode);
+		bt_dev_err(hdev, "wrong event for mode %d",
+			   hdev->flow_ctl_mode);
 		return;
 	}
 
-	BT_DBG("%s num_blocks %d num_hndl %d", hdev->name, ev->num_blocks,
-	       ev->num_hndl);
+	bt_dev_dbg(hdev, "num_blocks %d num_hndl %d", ev->num_blocks,
+		   ev->num_hndl);
 
 	for (i = 0; i < ev->num_hndl; i++) {
 		struct hci_comp_blocks_info *info = &ev->handles[i];
@@ -4627,16 +4576,13 @@  static void hci_num_comp_blocks_evt(struct hci_dev *hdev, struct sk_buff *skb)
 	queue_work(hdev->workqueue, &hdev->tx_work);
 }
 
-static void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
+static void hci_mode_change_evt(struct hci_dev *hdev, void *data,
+				struct sk_buff *skb)
 {
-	struct hci_ev_mode_change *ev;
+	struct hci_ev_mode_change *ev = data;
 	struct hci_conn *conn;
 
-	ev = hci_ev_skb_pull(hdev, skb, HCI_EV_MODE_CHANGE, sizeof(*ev));
-	if (!ev)
-		return;
-
-	BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
+	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
 
 	hci_dev_lock(hdev);
 
@@ -4659,16 +4605,13 @@  static void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
 	hci_dev_unlock(hdev);
 }
 
-static void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
+static void hci_pin_code_request_evt(struct hci_dev *hdev, void *data,
+				     struct sk_buff *skb)
 {
-	struct hci_ev_pin_code_req *ev;
+	struct hci_ev_pin_code_req *ev = data;
 	struct hci_conn *conn;
 
-	ev = hci_ev_skb_pull(hdev, skb, HCI_EV_PIN_CODE_REQ, sizeof(*ev));
-	if (!ev)
-		return;
-
-	BT_DBG("%s", hdev->name);
+	bt_dev_dbg(hdev, "");
 
 	hci_dev_lock(hdev);
 
@@ -4733,18 +4676,15 @@  static void conn_set_key(struct hci_conn *conn, u8 key_type, u8 pin_len)
 	}
 }
 
-static void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
+static void hci_link_key_request_evt(struct hci_dev *hdev, void *data,
+				     struct sk_buff *skb)
 {
-	struct hci_ev_link_key_req *ev;
+	struct hci_ev_link_key_req *ev = data;
 	struct hci_cp_link_key_reply cp;
 	struct hci_conn *conn;
 	struct link_key *key;
 
-	ev = hci_ev_skb_pull(hdev, skb, HCI_EV_LINK_KEY_REQ, sizeof(*ev));
-	if (!ev)
-		return;
-
-	BT_DBG("%s", hdev->name);
+	bt_dev_dbg(hdev, "");
 
 	if (!hci_dev_test_flag(hdev, HCI_MGMT))
 		return;
@@ -4753,13 +4693,11 @@  static void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
 
 	key = hci_find_link_key(hdev, &ev->bdaddr);
 	if (!key) {
-		BT_DBG("%s link key not found for %pMR", hdev->name,
-		       &ev->bdaddr);
+		bt_dev_dbg(hdev, "link key not found for %pMR", &ev->bdaddr);
 		goto not_found;
 	}
 
-	BT_DBG("%s found key type %u for %pMR", hdev->name, key->type,
-	       &ev->bdaddr);
+	bt_dev_dbg(hdev, "found key type %u for %pMR", key->type, &ev->bdaddr);
 
 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
 	if (conn) {
@@ -4768,15 +4706,14 @@  static void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
 		if ((key->type == HCI_LK_UNAUTH_COMBINATION_P192 ||
 		     key->type == HCI_LK_UNAUTH_COMBINATION_P256) &&
 		    conn->auth_type != 0xff && (conn->auth_type & 0x01)) {
-			BT_DBG("%s ignoring unauthenticated key", hdev->name);
+			bt_dev_dbg(hdev, "ignoring unauthenticated key");
 			goto not_found;
 		}
 
 		if (key->type == HCI_LK_COMBINATION && key->pin_len < 16 &&
 		    (conn->pending_sec_level == BT_SECURITY_HIGH ||
 		     conn->pending_sec_level == BT_SECURITY_FIPS)) {
-			BT_DBG("%s ignoring key unauthenticated for high security",
-			       hdev->name);
+			bt_dev_dbg(hdev, "ignoring key unauthenticated for high security");
 			goto not_found;
 		}
 
@@ -4797,19 +4734,16 @@  static void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
 	hci_dev_unlock(hdev);
 }
 
-static void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
+static void hci_link_key_notify_evt(struct hci_dev *hdev, void *data,
+				    struct sk_buff *skb)
 {
-	struct hci_ev_link_key_notify *ev;
+	struct hci_ev_link_key_notify *ev = data;
 	struct hci_conn *conn;
 	struct link_key *key;
 	bool persistent;
 	u8 pin_len = 0;
 
-	ev = hci_ev_skb_pull(hdev, skb, HCI_EV_LINK_KEY_NOTIFY, sizeof(*ev));
-	if (!ev)
-		return;
-
-	BT_DBG("%s", hdev->name);
+	bt_dev_dbg(hdev, "");
 
 	hci_dev_lock(hdev);
 
@@ -4861,16 +4795,13 @@  static void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
 	hci_dev_unlock(hdev);
 }
 
-static void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb)
+static void hci_clock_offset_evt(struct hci_dev *hdev, void *data,
+				 struct sk_buff *skb)
 {
-	struct hci_ev_clock_offset *ev;
+	struct hci_ev_clock_offset *ev = data;
 	struct hci_conn *conn;
 
-	ev = hci_ev_skb_pull(hdev, skb, HCI_EV_CLOCK_OFFSET, sizeof(*ev));
-	if (!ev)
-		return;
-
-	BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
+	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
 
 	hci_dev_lock(hdev);
 
@@ -4888,16 +4819,13 @@  static void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb)
 	hci_dev_unlock(hdev);
 }
 
-static void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
+static void hci_pkt_type_change_evt(struct hci_dev *hdev, void *data,
+				    struct sk_buff *skb)
 {
-	struct hci_ev_pkt_type_change *ev;
+	struct hci_ev_pkt_type_change *ev = data;
 	struct hci_conn *conn;
 
-	ev = hci_ev_skb_pull(hdev, skb, HCI_EV_PKT_TYPE_CHANGE, sizeof(*ev));
-	if (!ev)
-		return;
-
-	BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
+	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
 
 	hci_dev_lock(hdev);
 
@@ -4908,16 +4836,13 @@  static void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
 	hci_dev_unlock(hdev);
 }
 
-static void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb)
+static void hci_pscan_rep_mode_evt(struct hci_dev *hdev, void *data,
+				   struct sk_buff *skb)
 {
-	struct hci_ev_pscan_rep_mode *ev;
+	struct hci_ev_pscan_rep_mode *ev = data;
 	struct inquiry_entry *ie;
 
-	ev = hci_ev_skb_pull(hdev, skb, HCI_EV_PSCAN_REP_MODE, sizeof(*ev));
-	if (!ev)
-		return;
-
-	BT_DBG("%s", hdev->name);
+	bt_dev_dbg(hdev, "");
 
 	hci_dev_lock(hdev);
 
@@ -4930,22 +4855,17 @@  static void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb)
 	hci_dev_unlock(hdev);
 }
 
-static void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev,
+static void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, void *edata,
 					     struct sk_buff *skb)
 {
 	union {
 		struct hci_ev_inquiry_result_rssi *res1;
 		struct hci_ev_inquiry_result_rssi_pscan *res2;
-	} *ev;
+	} *ev = edata;
 	struct inquiry_data data;
 	int i;
 
-	ev = hci_ev_skb_pull(hdev, skb, HCI_EV_INQUIRY_RESULT_WITH_RSSI,
-			     sizeof(*ev));
-	if (!ev)
-		return;
-
-	BT_DBG("%s num_rsp %d", hdev->name, ev->res1->num);
+	bt_dev_dbg(hdev, "num_rsp %d", ev->res1->num);
 
 	if (!ev->res1->num)
 		return;
@@ -5007,18 +4927,13 @@  static void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev,
 	hci_dev_unlock(hdev);
 }
 
-static void hci_remote_ext_features_evt(struct hci_dev *hdev,
+static void hci_remote_ext_features_evt(struct hci_dev *hdev, void *data,
 					struct sk_buff *skb)
 {
-	struct hci_ev_remote_ext_features *ev;
+	struct hci_ev_remote_ext_features *ev = data;
 	struct hci_conn *conn;
 
-	ev = hci_ev_skb_pull(hdev, skb, HCI_EV_REMOTE_EXT_FEATURES,
-			     sizeof(*ev));
-	if (!ev)
-		return;
-
-	BT_DBG("%s", hdev->name);
+	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
 
 	hci_dev_lock(hdev);
 
@@ -5076,17 +4991,13 @@  static void hci_remote_ext_features_evt(struct hci_dev *hdev,
 	hci_dev_unlock(hdev);
 }
 
-static void hci_sync_conn_complete_evt(struct hci_dev *hdev,
+static void hci_sync_conn_complete_evt(struct hci_dev *hdev, void *data,
 				       struct sk_buff *skb)
 {
-	struct hci_ev_sync_conn_complete *ev;
+	struct hci_ev_sync_conn_complete *ev = data;
 	struct hci_conn *conn;
 
-	ev = hci_ev_skb_pull(hdev, skb, HCI_EV_SYNC_CONN_COMPLETE, sizeof(*ev));
-	if (!ev)
-		return;
-
-	BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
+	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
 
 	hci_dev_lock(hdev);
 
@@ -5195,24 +5106,19 @@  static inline size_t eir_get_length(u8 *eir, size_t eir_len)
 	return eir_len;
 }
 
-static void hci_extended_inquiry_result_evt(struct hci_dev *hdev,
+static void hci_extended_inquiry_result_evt(struct hci_dev *hdev, void *edata,
 					    struct sk_buff *skb)
 {
-	struct hci_ev_ext_inquiry_result *ev;
+	struct hci_ev_ext_inquiry_result *ev = edata;
 	struct inquiry_data data;
 	size_t eir_len;
 	int i;
 
-	ev = hci_ev_skb_pull(hdev, skb, HCI_EV_EXTENDED_INQUIRY_RESULT,
-			     sizeof(*ev));
-	if (!ev)
-		return;
-
 	if (!hci_ev_skb_pull(hdev, skb, HCI_EV_EXTENDED_INQUIRY_RESULT,
 			     flex_array_size(ev, info, ev->num)))
 		return;
 
-	BT_DBG("%s num %d", hdev->name, ev->num);
+	bt_dev_dbg(hdev, "num %d", ev->num);
 
 	if (!ev->num)
 		return;
@@ -5255,19 +5161,14 @@  static void hci_extended_inquiry_result_evt(struct hci_dev *hdev,
 	hci_dev_unlock(hdev);
 }
 
-static void hci_key_refresh_complete_evt(struct hci_dev *hdev,
+static void hci_key_refresh_complete_evt(struct hci_dev *hdev, void *data,
 					 struct sk_buff *skb)
 {
-	struct hci_ev_key_refresh_complete *ev;
+	struct hci_ev_key_refresh_complete *ev = data;
 	struct hci_conn *conn;
 
-	ev = hci_ev_skb_pull(hdev, skb, HCI_EV_KEY_REFRESH_COMPLETE,
-			     sizeof(*ev));
-	if (!ev)
-		return;
-
-	BT_DBG("%s status 0x%2.2x handle 0x%4.4x", hdev->name, ev->status,
-	       __le16_to_cpu(ev->handle));
+	bt_dev_dbg(hdev, "status 0x%2.2x handle 0x%4.4x", ev->status,
+		   __le16_to_cpu(ev->handle));
 
 	hci_dev_lock(hdev);
 
@@ -5370,16 +5271,13 @@  static u8 bredr_oob_data_present(struct hci_conn *conn)
 	return 0x01;
 }
 
-static void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
+static void hci_io_capa_request_evt(struct hci_dev *hdev, void *data,
+				    struct sk_buff *skb)
 {
-	struct hci_ev_io_capa_request *ev;
+	struct hci_ev_io_capa_request *ev = data;
 	struct hci_conn *conn;
 
-	ev = hci_ev_skb_pull(hdev, skb, HCI_EV_IO_CAPA_REQUEST, sizeof(*ev));
-	if (!ev)
-		return;
-
-	BT_DBG("%s", hdev->name);
+	bt_dev_dbg(hdev, "");
 
 	hci_dev_lock(hdev);
 
@@ -5443,16 +5341,13 @@  static void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
 	hci_dev_unlock(hdev);
 }
 
-static void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *skb)
+static void hci_io_capa_reply_evt(struct hci_dev *hdev, void *data,
+				  struct sk_buff *skb)
 {
-	struct hci_ev_io_capa_reply *ev;
+	struct hci_ev_io_capa_reply *ev = data;
 	struct hci_conn *conn;
 
-	ev = hci_ev_skb_pull(hdev, skb, HCI_EV_IO_CAPA_REPLY, sizeof(*ev));
-	if (!ev)
-		return;
-
-	BT_DBG("%s", hdev->name);
+	bt_dev_dbg(hdev, "");
 
 	hci_dev_lock(hdev);
 
@@ -5467,19 +5362,14 @@  static void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *skb)
 	hci_dev_unlock(hdev);
 }
 
-static void hci_user_confirm_request_evt(struct hci_dev *hdev,
+static void hci_user_confirm_request_evt(struct hci_dev *hdev, void *data,
 					 struct sk_buff *skb)
 {
-	struct hci_ev_user_confirm_req *ev;
+	struct hci_ev_user_confirm_req *ev = data;
 	int loc_mitm, rem_mitm, confirm_hint = 0;
 	struct hci_conn *conn;
 
-	ev = hci_ev_skb_pull(hdev, skb, HCI_EV_USER_CONFIRM_REQUEST,
-			     sizeof(*ev));
-	if (!ev)
-		return;
-
-	BT_DBG("%s", hdev->name);
+	bt_dev_dbg(hdev, "");
 
 	hci_dev_lock(hdev);
 
@@ -5500,7 +5390,7 @@  static void hci_user_confirm_request_evt(struct hci_dev *hdev,
 	 */
 	if (conn->pending_sec_level > BT_SECURITY_MEDIUM &&
 	    conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT) {
-		BT_DBG("Rejecting request: remote device can't provide MITM");
+		bt_dev_dbg(hdev, "Rejecting request: remote device can't provide MITM");
 		hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_NEG_REPLY,
 			     sizeof(ev->bdaddr), &ev->bdaddr);
 		goto unlock;
@@ -5519,7 +5409,7 @@  static void hci_user_confirm_request_evt(struct hci_dev *hdev,
 		if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) &&
 		    conn->io_capability != HCI_IO_NO_INPUT_OUTPUT &&
 		    (loc_mitm || rem_mitm)) {
-			BT_DBG("Confirming auto-accept as acceptor");
+			bt_dev_dbg(hdev, "Confirming auto-accept as acceptor");
 			confirm_hint = 1;
 			goto confirm;
 		}
@@ -5557,34 +5447,24 @@  static void hci_user_confirm_request_evt(struct hci_dev *hdev,
 	hci_dev_unlock(hdev);
 }
 
-static void hci_user_passkey_request_evt(struct hci_dev *hdev,
+static void hci_user_passkey_request_evt(struct hci_dev *hdev, void *data,
 					 struct sk_buff *skb)
 {
-	struct hci_ev_user_passkey_req *ev;
-
-	ev = hci_ev_skb_pull(hdev, skb, HCI_EV_USER_PASSKEY_REQUEST,
-			     sizeof(*ev));
-	if (!ev)
-		return;
+	struct hci_ev_user_passkey_req *ev = data;
 
-	BT_DBG("%s", hdev->name);
+	bt_dev_dbg(hdev, "");
 
 	if (hci_dev_test_flag(hdev, HCI_MGMT))
 		mgmt_user_passkey_request(hdev, &ev->bdaddr, ACL_LINK, 0);
 }
 
-static void hci_user_passkey_notify_evt(struct hci_dev *hdev,
+static void hci_user_passkey_notify_evt(struct hci_dev *hdev, void *data,
 					struct sk_buff *skb)
 {
-	struct hci_ev_user_passkey_notify *ev;
+	struct hci_ev_user_passkey_notify *ev = data;
 	struct hci_conn *conn;
 
-	ev = hci_ev_skb_pull(hdev, skb, HCI_EV_USER_PASSKEY_NOTIFY,
-			     sizeof(*ev));
-	if (!ev)
-		return;
-
-	BT_DBG("%s", hdev->name);
+	bt_dev_dbg(hdev, "");
 
 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
 	if (!conn)
@@ -5599,16 +5479,13 @@  static void hci_user_passkey_notify_evt(struct hci_dev *hdev,
 					 conn->passkey_entered);
 }
 
-static void hci_keypress_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
+static void hci_keypress_notify_evt(struct hci_dev *hdev, void *data,
+				    struct sk_buff *skb)
 {
-	struct hci_ev_keypress_notify *ev;
+	struct hci_ev_keypress_notify *ev = data;
 	struct hci_conn *conn;
 
-	ev = hci_ev_skb_pull(hdev, skb, HCI_EV_KEYPRESS_NOTIFY, sizeof(*ev));
-	if (!ev)
-		return;
-
-	BT_DBG("%s", hdev->name);
+	bt_dev_dbg(hdev, "");
 
 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
 	if (!conn)
@@ -5641,18 +5518,13 @@  static void hci_keypress_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
 					 conn->passkey_entered);
 }
 
-static void hci_simple_pair_complete_evt(struct hci_dev *hdev,
+static void hci_simple_pair_complete_evt(struct hci_dev *hdev, void *data,
 					 struct sk_buff *skb)
 {
-	struct hci_ev_simple_pair_complete *ev;
+	struct hci_ev_simple_pair_complete *ev = data;
 	struct hci_conn *conn;
 
-	ev = hci_ev_skb_pull(hdev, skb, HCI_EV_SIMPLE_PAIR_COMPLETE,
-			     sizeof(*ev));
-	if (!ev)
-		return;
-
-	BT_DBG("%s", hdev->name);
+	bt_dev_dbg(hdev, "");
 
 	hci_dev_lock(hdev);
 
@@ -5677,19 +5549,14 @@  static void hci_simple_pair_complete_evt(struct hci_dev *hdev,
 	hci_dev_unlock(hdev);
 }
 
-static void hci_remote_host_features_evt(struct hci_dev *hdev,
+static void hci_remote_host_features_evt(struct hci_dev *hdev, void *data,
 					 struct sk_buff *skb)
 {
-	struct hci_ev_remote_host_features *ev;
+	struct hci_ev_remote_host_features *ev = data;
 	struct inquiry_entry *ie;
 	struct hci_conn *conn;
 
-	ev = hci_ev_skb_pull(hdev, skb, HCI_EV_REMOTE_HOST_FEATURES,
-			     sizeof(*ev));
-	if (!ev)
-		return;
-
-	BT_DBG("%s", hdev->name);
+	bt_dev_dbg(hdev, "");
 
 	hci_dev_lock(hdev);
 
@@ -5704,18 +5571,13 @@  static void hci_remote_host_features_evt(struct hci_dev *hdev,
 	hci_dev_unlock(hdev);
 }
 
-static void hci_remote_oob_data_request_evt(struct hci_dev *hdev,
+static void hci_remote_oob_data_request_evt(struct hci_dev *hdev, void *edata,
 					    struct sk_buff *skb)
 {
-	struct hci_ev_remote_oob_data_request *ev;
+	struct hci_ev_remote_oob_data_request *ev = edata;
 	struct oob_data *data;
 
-	ev = hci_ev_skb_pull(hdev, skb, HCI_EV_REMOTE_OOB_DATA_REQUEST,
-			     sizeof(*ev));
-	if (!ev)
-		return;
-
-	BT_DBG("%s", hdev->name);
+	bt_dev_dbg(hdev, "");
 
 	hci_dev_lock(hdev);
 
@@ -5764,16 +5626,13 @@  static void hci_remote_oob_data_request_evt(struct hci_dev *hdev,
 }
 
 #if IS_ENABLED(CONFIG_BT_HS)
-static void hci_chan_selected_evt(struct hci_dev *hdev, struct sk_buff *skb)
+static void hci_chan_selected_evt(struct hci_dev *hdev, void *data,
+				  struct sk_buff *skb)
 {
-	struct hci_ev_channel_selected *ev;
+	struct hci_ev_channel_selected *ev = data;
 	struct hci_conn *hcon;
 
-	ev = hci_ev_skb_pull(hdev, skb, HCI_EV_CHANNEL_SELECTED, sizeof(*ev));
-	if (!ev)
-		return;
-
-	BT_DBG("%s handle 0x%2.2x", hdev->name, ev->phy_handle);
+	bt_dev_dbg(hdev, "handle 0x%2.2x", ev->phy_handle);
 
 	hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
 	if (!hcon)
@@ -5782,18 +5641,14 @@  static void hci_chan_selected_evt(struct hci_dev *hdev, struct sk_buff *skb)
 	amp_read_loc_assoc_final_data(hdev, hcon);
 }
 
-static void hci_phy_link_complete_evt(struct hci_dev *hdev,
+static void hci_phy_link_complete_evt(struct hci_dev *hdev, void *data,
 				      struct sk_buff *skb)
 {
-	struct hci_ev_phy_link_complete *ev;
+	struct hci_ev_phy_link_complete *ev = data;
 	struct hci_conn *hcon, *bredr_hcon;
 
-	ev = hci_ev_skb_pull(hdev, skb, HCI_EV_PHY_LINK_COMPLETE, sizeof(*ev));
-	if (!ev)
-		return;
-
-	BT_DBG("%s handle 0x%2.2x status 0x%2.2x", hdev->name, ev->phy_handle,
-	       ev->status);
+	bt_dev_dbg(hdev, "handle 0x%2.2x status 0x%2.2x", ev->phy_handle,
+		   ev->status);
 
 	hci_dev_lock(hdev);
 
@@ -5827,21 +5682,16 @@  static void hci_phy_link_complete_evt(struct hci_dev *hdev,
 	hci_dev_unlock(hdev);
 }
 
-static void hci_loglink_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
+static void hci_loglink_complete_evt(struct hci_dev *hdev, void *data,
+				     struct sk_buff *skb)
 {
-	struct hci_ev_logical_link_complete *ev;
+	struct hci_ev_logical_link_complete *ev = data;
 	struct hci_conn *hcon;
 	struct hci_chan *hchan;
 	struct amp_mgr *mgr;
 
-	ev = hci_ev_skb_pull(hdev, skb, HCI_EV_LOGICAL_LINK_COMPLETE,
-			     sizeof(*ev));
-	if (!ev)
-		return;
-
-	BT_DBG("%s log_handle 0x%4.4x phy_handle 0x%2.2x status 0x%2.2x",
-	       hdev->name, le16_to_cpu(ev->handle), ev->phy_handle,
-	       ev->status);
+	bt_dev_dbg(hdev, "log_handle 0x%4.4x phy_handle 0x%2.2x status 0x%2.2x",
+		   le16_to_cpu(ev->handle), ev->phy_handle, ev->status);
 
 	hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
 	if (!hcon)
@@ -5871,19 +5721,14 @@  static void hci_loglink_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
 	}
 }
 
-static void hci_disconn_loglink_complete_evt(struct hci_dev *hdev,
+static void hci_disconn_loglink_complete_evt(struct hci_dev *hdev, void *data,
 					     struct sk_buff *skb)
 {
-	struct hci_ev_disconn_logical_link_complete *ev;
+	struct hci_ev_disconn_logical_link_complete *ev = data;
 	struct hci_chan *hchan;
 
-	ev = hci_ev_skb_pull(hdev, skb, HCI_EV_DISCONN_LOGICAL_LINK_COMPLETE,
-			     sizeof(*ev));
-	if (!ev)
-		return;
-
-	BT_DBG("%s log handle 0x%4.4x status 0x%2.2x", hdev->name,
-	       le16_to_cpu(ev->handle), ev->status);
+	bt_dev_dbg(hdev, "handle 0x%4.4x status 0x%2.2x",
+		   le16_to_cpu(ev->handle), ev->status);
 
 	if (ev->status)
 		return;
@@ -5900,18 +5745,13 @@  static void hci_disconn_loglink_complete_evt(struct hci_dev *hdev,
 	hci_dev_unlock(hdev);
 }
 
-static void hci_disconn_phylink_complete_evt(struct hci_dev *hdev,
+static void hci_disconn_phylink_complete_evt(struct hci_dev *hdev, void *data,
 					     struct sk_buff *skb)
 {
-	struct hci_ev_disconn_phy_link_complete *ev;
+	struct hci_ev_disconn_phy_link_complete *ev = data;
 	struct hci_conn *hcon;
 
-	ev = hci_ev_skb_pull(hdev, skb, HCI_EV_DISCONN_PHY_LINK_COMPLETE,
-			     sizeof(*ev));
-	if (!ev)
-		return;
-
-	BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
+	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
 
 	if (ev->status)
 		return;
@@ -6938,13 +6778,10 @@  static void hci_le_phy_update_evt(struct hci_dev *hdev, struct sk_buff *skb)
 	hci_dev_unlock(hdev);
 }
 
-static void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb)
+static void hci_le_meta_evt(struct hci_dev *hdev, void *data,
+			    struct sk_buff *skb)
 {
-	struct hci_ev_le_meta *ev;
-
-	ev = hci_ev_skb_pull(hdev, skb, HCI_EV_LE_META, sizeof(*ev));
-	if (!ev)
-		return;
+	struct hci_ev_le_meta *ev = data;
 
 	switch (ev->subevent) {
 	case HCI_EV_LE_CONN_COMPLETE:
@@ -7109,6 +6946,224 @@  static void hci_store_wake_reason(struct hci_dev *hdev, u8 event,
 	hci_dev_unlock(hdev);
 }
 
+#define HCI_EV_VL(_op, _func, _min_len, _max_len) \
+[_op] = { \
+	.req = false, \
+	.func = _func, \
+	.min_len = _min_len, \
+	.max_len = _max_len, \
+}
+
+#define HCI_EV(_op, _func, _len) \
+	HCI_EV_VL(_op, _func, _len, _len)
+
+#define HCI_EV_STATUS(_op, _func) \
+	HCI_EV(_op, _func, sizeof(struct hci_ev_status))
+
+#define HCI_EV_REQ_VL(_op, _func, _min_len, _max_len) \
+[_op] = { \
+	.req = true, \
+	.func_req = _func, \
+	.min_len = _min_len, \
+	.max_len = _max_len, \
+}
+
+#define HCI_EV_REQ(_op, _func, _len) \
+	HCI_EV_REQ_VL(_op, _func, _len, _len)
+
+/* Entries in this table shall have their position according to the event opcode
+ * they handle so the use of the macros above is recommend since it does attempt
+ * to initialize at its proper index using Designated Initializers that way
+ * events without a callback function don't have entered.
+ */
+static const struct hci_ev {
+	bool req;
+	union {
+		void (*func)(struct hci_dev *hdev, void *data,
+			     struct sk_buff *skb);
+		void (*func_req)(struct hci_dev *hdev, void *data,
+				 struct sk_buff *skb, u16 *opcode, u8 *status,
+				 hci_req_complete_t *req_complete,
+				 hci_req_complete_skb_t *req_complete_skb);
+	};
+	u16  min_len;
+	u16  max_len;
+} hci_ev_table[U8_MAX + 1] = {
+	/* [0x01 = HCI_EV_INQUIRY_COMPLETE] */
+	HCI_EV_STATUS(HCI_EV_INQUIRY_COMPLETE, hci_inquiry_complete_evt),
+	/* [0x02 = HCI_EV_INQUIRY_RESULT] */
+	HCI_EV_VL(HCI_EV_INQUIRY_RESULT, hci_inquiry_result_evt,
+		  sizeof(struct hci_ev_inquiry_result), HCI_MAX_EVENT_SIZE),
+	/* [0x03 = HCI_EV_CONN_COMPLETE] */
+	HCI_EV(HCI_EV_CONN_COMPLETE, hci_conn_complete_evt,
+	       sizeof(struct hci_ev_conn_complete)),
+	/* [0x04 = HCI_EV_CONN_REQUEST] */
+	HCI_EV(HCI_EV_CONN_REQUEST, hci_conn_request_evt,
+	       sizeof(struct hci_ev_conn_request)),
+	/* [0x05 = HCI_EV_DISCONN_COMPLETE] */
+	HCI_EV(HCI_EV_DISCONN_COMPLETE, hci_disconn_complete_evt,
+	       sizeof(struct hci_ev_disconn_complete)),
+	/* [0x06 = HCI_EV_AUTH_COMPLETE] */
+	HCI_EV(HCI_EV_AUTH_COMPLETE, hci_auth_complete_evt,
+	       sizeof(struct hci_ev_auth_complete)),
+	/* [0x07 = HCI_EV_REMOTE_NAME] */
+	HCI_EV(HCI_EV_REMOTE_NAME, hci_remote_name_evt,
+	       sizeof(struct hci_ev_remote_name)),
+	/* [0x08 = HCI_EV_ENCRYPT_CHANGE] */
+	HCI_EV(HCI_EV_ENCRYPT_CHANGE, hci_encrypt_change_evt,
+	       sizeof(struct hci_ev_encrypt_change)),
+	/* [0x09 = HCI_EV_CHANGE_LINK_KEY_COMPLETE] */
+	HCI_EV(HCI_EV_CHANGE_LINK_KEY_COMPLETE,
+	       hci_change_link_key_complete_evt,
+	       sizeof(struct hci_ev_change_link_key_complete)),
+	/* [0x0b = HCI_EV_REMOTE_FEATURES] */
+	HCI_EV(HCI_EV_REMOTE_FEATURES, hci_remote_features_evt,
+	       sizeof(struct hci_ev_remote_features)),
+	/* [0x0e = HCI_EV_CMD_COMPLETE] */
+	HCI_EV_REQ_VL(HCI_EV_CMD_COMPLETE, hci_cmd_complete_evt,
+		      sizeof(struct hci_ev_cmd_complete), HCI_MAX_EVENT_SIZE),
+	/* [0x0f = HCI_EV_CMD_STATUS] */
+	HCI_EV_REQ(HCI_EV_CMD_STATUS, hci_cmd_status_evt,
+		   sizeof(struct hci_ev_cmd_status)),
+	/* [0x10 = HCI_EV_CMD_STATUS] */
+	HCI_EV(HCI_EV_HARDWARE_ERROR, hci_hardware_error_evt,
+	       sizeof(struct hci_ev_hardware_error)),
+	/* [0x12 = HCI_EV_ROLE_CHANGE] */
+	HCI_EV(HCI_EV_ROLE_CHANGE, hci_role_change_evt,
+	       sizeof(struct hci_ev_role_change)),
+	/* [0x13 = HCI_EV_NUM_COMP_PKTS] */
+	HCI_EV_VL(HCI_EV_NUM_COMP_PKTS, hci_num_comp_pkts_evt,
+		  sizeof(struct hci_ev_num_comp_pkts), HCI_MAX_EVENT_SIZE),
+	/* [0x14 = HCI_EV_MODE_CHANGE] */
+	HCI_EV(HCI_EV_MODE_CHANGE, hci_mode_change_evt,
+	       sizeof(struct hci_ev_mode_change)),
+	/* [0x16 = HCI_EV_PIN_CODE_REQ] */
+	HCI_EV(HCI_EV_PIN_CODE_REQ, hci_pin_code_request_evt,
+	       sizeof(struct hci_ev_pin_code_req)),
+	/* [0x17 = HCI_EV_LINK_KEY_REQ] */
+	HCI_EV(HCI_EV_LINK_KEY_REQ, hci_link_key_request_evt,
+	       sizeof(struct hci_ev_link_key_req)),
+	/* [0x18 = HCI_EV_LINK_KEY_NOTIFY] */
+	HCI_EV(HCI_EV_LINK_KEY_NOTIFY, hci_link_key_notify_evt,
+	       sizeof(struct hci_ev_link_key_notify)),
+	/* [0x1c = HCI_EV_CLOCK_OFFSET] */
+	HCI_EV(HCI_EV_CLOCK_OFFSET, hci_clock_offset_evt,
+	       sizeof(struct hci_ev_clock_offset)),
+	/* [0x1d = HCI_EV_PKT_TYPE_CHANGE] */
+	HCI_EV(HCI_EV_PKT_TYPE_CHANGE, hci_pkt_type_change_evt,
+	       sizeof(struct hci_ev_pkt_type_change)),
+	/* [0x20 = HCI_EV_PSCAN_REP_MODE] */
+	HCI_EV(HCI_EV_PSCAN_REP_MODE, hci_pscan_rep_mode_evt,
+	       sizeof(struct hci_ev_pscan_rep_mode)),
+	/* [0x22 = HCI_EV_INQUIRY_RESULT_WITH_RSSI] */
+	HCI_EV_VL(HCI_EV_INQUIRY_RESULT_WITH_RSSI,
+		  hci_inquiry_result_with_rssi_evt,
+		  sizeof(struct hci_ev_inquiry_result_rssi),
+		  HCI_MAX_EVENT_SIZE),
+	/* [0x23 = HCI_EV_REMOTE_EXT_FEATURES] */
+	HCI_EV(HCI_EV_REMOTE_EXT_FEATURES, hci_remote_ext_features_evt,
+	       sizeof(struct hci_ev_remote_ext_features)),
+	/* [0x2c = HCI_EV_SYNC_CONN_COMPLETE] */
+	HCI_EV(HCI_EV_SYNC_CONN_COMPLETE, hci_sync_conn_complete_evt,
+	       sizeof(struct hci_ev_sync_conn_complete)),
+	/* [0x2d = HCI_EV_EXTENDED_INQUIRY_RESULT] */
+	HCI_EV_VL(HCI_EV_EXTENDED_INQUIRY_RESULT,
+		  hci_extended_inquiry_result_evt,
+		  sizeof(struct hci_ev_ext_inquiry_result), HCI_MAX_EVENT_SIZE),
+	/* [0x30 = HCI_EV_KEY_REFRESH_COMPLETE] */
+	HCI_EV(HCI_EV_KEY_REFRESH_COMPLETE, hci_key_refresh_complete_evt,
+	       sizeof(struct hci_ev_key_refresh_complete)),
+	/* [0x31 = HCI_EV_IO_CAPA_REQUEST] */
+	HCI_EV(HCI_EV_IO_CAPA_REQUEST, hci_io_capa_request_evt,
+	       sizeof(struct hci_ev_io_capa_request)),
+	/* [0x32 = HCI_EV_IO_CAPA_REPLY] */
+	HCI_EV(HCI_EV_IO_CAPA_REPLY, hci_io_capa_reply_evt,
+	       sizeof(struct hci_ev_io_capa_reply)),
+	/* [0x33 = HCI_EV_USER_CONFIRM_REQUEST] */
+	HCI_EV(HCI_EV_USER_CONFIRM_REQUEST, hci_user_confirm_request_evt,
+	       sizeof(struct hci_ev_user_confirm_req)),
+	/* [0x34 = HCI_EV_USER_PASSKEY_REQUEST] */
+	HCI_EV(HCI_EV_USER_PASSKEY_REQUEST, hci_user_passkey_request_evt,
+	       sizeof(struct hci_ev_user_passkey_req)),
+	/* [0x35 = HCI_EV_REMOTE_OOB_DATA_REQUEST] */
+	HCI_EV(HCI_EV_REMOTE_OOB_DATA_REQUEST, hci_remote_oob_data_request_evt,
+	       sizeof(struct hci_ev_remote_oob_data_request)),
+	/* [0x36 = HCI_EV_SIMPLE_PAIR_COMPLETE] */
+	HCI_EV(HCI_EV_SIMPLE_PAIR_COMPLETE, hci_simple_pair_complete_evt,
+	       sizeof(struct hci_ev_simple_pair_complete)),
+	/* [0x3b = HCI_EV_USER_PASSKEY_NOTIFY] */
+	HCI_EV(HCI_EV_USER_PASSKEY_NOTIFY, hci_user_passkey_notify_evt,
+	       sizeof(struct hci_ev_user_passkey_notify)),
+	/* [0x3c = HCI_EV_KEYPRESS_NOTIFY] */
+	HCI_EV(HCI_EV_KEYPRESS_NOTIFY, hci_keypress_notify_evt,
+	       sizeof(struct hci_ev_keypress_notify)),
+	/* [0x3d = HCI_EV_REMOTE_HOST_FEATURES] */
+	HCI_EV(HCI_EV_REMOTE_HOST_FEATURES, hci_remote_host_features_evt,
+	       sizeof(struct hci_ev_remote_host_features)),
+	/* [0x3e = HCI_EV_LE_META] */
+	HCI_EV_VL(HCI_EV_LE_META, hci_le_meta_evt,
+		  sizeof(struct hci_ev_le_meta), HCI_MAX_EVENT_SIZE),
+#if IS_ENABLED(CONFIG_BT_HS)
+	/* [0x40 = HCI_EV_PHY_LINK_COMPLETE] */
+	HCI_EV(HCI_EV_PHY_LINK_COMPLETE, hci_phy_link_complete_evt,
+	       sizeof(struct hci_ev_phy_link_complete)),
+	/* [0x41 = HCI_EV_CHANNEL_SELECTED] */
+	HCI_EV(HCI_EV_CHANNEL_SELECTED, hci_chan_selected_evt,
+	       sizeof(struct hci_ev_channel_selected)),
+	/* [0x42 = HCI_EV_DISCONN_PHY_LINK_COMPLETE] */
+	HCI_EV(HCI_EV_DISCONN_LOGICAL_LINK_COMPLETE,
+	       hci_disconn_loglink_complete_evt,
+	       sizeof(struct hci_ev_disconn_logical_link_complete)),
+	/* [0x45 = HCI_EV_LOGICAL_LINK_COMPLETE] */
+	HCI_EV(HCI_EV_LOGICAL_LINK_COMPLETE, hci_loglink_complete_evt,
+	       sizeof(struct hci_ev_logical_link_complete)),
+	/* [0x46 = HCI_EV_DISCONN_LOGICAL_LINK_COMPLETE] */
+	HCI_EV(HCI_EV_DISCONN_PHY_LINK_COMPLETE,
+	       hci_disconn_phylink_complete_evt,
+	       sizeof(struct hci_ev_disconn_phy_link_complete)),
+#endif
+	/* [0x48 = HCI_EV_NUM_COMP_BLOCKS] */
+	HCI_EV(HCI_EV_NUM_COMP_BLOCKS, hci_num_comp_blocks_evt,
+	       sizeof(struct hci_ev_num_comp_blocks)),
+	/* [0xff = HCI_EV_VENDOR] */
+	HCI_EV(HCI_EV_VENDOR, msft_vendor_evt, 0),
+};
+
+void hci_event_func(struct hci_dev *hdev, u8 event, struct sk_buff *skb,
+		    u16 *opcode, u8 *status, hci_req_complete_t *req_complete,
+		    hci_req_complete_skb_t *req_complete_skb)
+{
+	const struct hci_ev *ev = &hci_ev_table[event];
+	void *data;
+
+	if (!ev->func)
+		return;
+
+	if (skb->len < ev->min_len) {
+		bt_dev_err(hdev, "unexpected event 0x%2.2x length: %u < %u",
+			   event, skb->len, ev->min_len);
+		return;
+	}
+
+	/* Just warn if the length is over max_len size it still be
+	 * possible to partially parse the event so leave to callback to
+	 * decide if that is acceptable.
+	 */
+	if (skb->len > ev->max_len)
+		bt_dev_warn(hdev, "unexpected event 0x%2.2x length: %u > %u",
+			    event, skb->len, ev->max_len);
+
+	data = hci_ev_skb_pull(hdev, skb, event, ev->min_len);
+	if (!data)
+		return;
+
+	if (ev->req)
+		ev->func_req(hdev, data, skb, opcode, status, req_complete,
+			     req_complete_skb);
+	else
+		ev->func(hdev, data, skb);
+}
+
 void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
 {
 	struct hci_event_hdr *hdr = (void *) skb->data;
@@ -7125,7 +7180,8 @@  void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
 
 	event = hdr->evt;
 	if (!event) {
-		bt_dev_warn(hdev, "Received unexpected HCI Event 00000000");
+		bt_dev_warn(hdev, "Received unexpected HCI Event 0x%2.2x",
+			    event);
 		goto done;
 	}
 
@@ -7151,191 +7207,10 @@  void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
 	/* Store wake reason if we're suspended */
 	hci_store_wake_reason(hdev, event, skb);
 
-	switch (event) {
-	case HCI_EV_INQUIRY_COMPLETE:
-		hci_inquiry_complete_evt(hdev, skb);
-		break;
-
-	case HCI_EV_INQUIRY_RESULT:
-		hci_inquiry_result_evt(hdev, skb);
-		break;
-
-	case HCI_EV_CONN_COMPLETE:
-		hci_conn_complete_evt(hdev, skb);
-		break;
-
-	case HCI_EV_CONN_REQUEST:
-		hci_conn_request_evt(hdev, skb);
-		break;
-
-	case HCI_EV_DISCONN_COMPLETE:
-		hci_disconn_complete_evt(hdev, skb);
-		break;
-
-	case HCI_EV_AUTH_COMPLETE:
-		hci_auth_complete_evt(hdev, skb);
-		break;
-
-	case HCI_EV_REMOTE_NAME:
-		hci_remote_name_evt(hdev, skb);
-		break;
-
-	case HCI_EV_ENCRYPT_CHANGE:
-		hci_encrypt_change_evt(hdev, skb);
-		break;
-
-	case HCI_EV_CHANGE_LINK_KEY_COMPLETE:
-		hci_change_link_key_complete_evt(hdev, skb);
-		break;
-
-	case HCI_EV_REMOTE_FEATURES:
-		hci_remote_features_evt(hdev, skb);
-		break;
-
-	case HCI_EV_CMD_COMPLETE:
-		hci_cmd_complete_evt(hdev, skb, &opcode, &status,
-				     &req_complete, &req_complete_skb);
-		break;
+	bt_dev_dbg(hdev, "event 0x%2.2x", event);
 
-	case HCI_EV_CMD_STATUS:
-		hci_cmd_status_evt(hdev, skb, &opcode, &status, &req_complete,
-				   &req_complete_skb);
-		break;
-
-	case HCI_EV_HARDWARE_ERROR:
-		hci_hardware_error_evt(hdev, skb);
-		break;
-
-	case HCI_EV_ROLE_CHANGE:
-		hci_role_change_evt(hdev, skb);
-		break;
-
-	case HCI_EV_NUM_COMP_PKTS:
-		hci_num_comp_pkts_evt(hdev, skb);
-		break;
-
-	case HCI_EV_MODE_CHANGE:
-		hci_mode_change_evt(hdev, skb);
-		break;
-
-	case HCI_EV_PIN_CODE_REQ:
-		hci_pin_code_request_evt(hdev, skb);
-		break;
-
-	case HCI_EV_LINK_KEY_REQ:
-		hci_link_key_request_evt(hdev, skb);
-		break;
-
-	case HCI_EV_LINK_KEY_NOTIFY:
-		hci_link_key_notify_evt(hdev, skb);
-		break;
-
-	case HCI_EV_CLOCK_OFFSET:
-		hci_clock_offset_evt(hdev, skb);
-		break;
-
-	case HCI_EV_PKT_TYPE_CHANGE:
-		hci_pkt_type_change_evt(hdev, skb);
-		break;
-
-	case HCI_EV_PSCAN_REP_MODE:
-		hci_pscan_rep_mode_evt(hdev, skb);
-		break;
-
-	case HCI_EV_INQUIRY_RESULT_WITH_RSSI:
-		hci_inquiry_result_with_rssi_evt(hdev, skb);
-		break;
-
-	case HCI_EV_REMOTE_EXT_FEATURES:
-		hci_remote_ext_features_evt(hdev, skb);
-		break;
-
-	case HCI_EV_SYNC_CONN_COMPLETE:
-		hci_sync_conn_complete_evt(hdev, skb);
-		break;
-
-	case HCI_EV_EXTENDED_INQUIRY_RESULT:
-		hci_extended_inquiry_result_evt(hdev, skb);
-		break;
-
-	case HCI_EV_KEY_REFRESH_COMPLETE:
-		hci_key_refresh_complete_evt(hdev, skb);
-		break;
-
-	case HCI_EV_IO_CAPA_REQUEST:
-		hci_io_capa_request_evt(hdev, skb);
-		break;
-
-	case HCI_EV_IO_CAPA_REPLY:
-		hci_io_capa_reply_evt(hdev, skb);
-		break;
-
-	case HCI_EV_USER_CONFIRM_REQUEST:
-		hci_user_confirm_request_evt(hdev, skb);
-		break;
-
-	case HCI_EV_USER_PASSKEY_REQUEST:
-		hci_user_passkey_request_evt(hdev, skb);
-		break;
-
-	case HCI_EV_USER_PASSKEY_NOTIFY:
-		hci_user_passkey_notify_evt(hdev, skb);
-		break;
-
-	case HCI_EV_KEYPRESS_NOTIFY:
-		hci_keypress_notify_evt(hdev, skb);
-		break;
-
-	case HCI_EV_SIMPLE_PAIR_COMPLETE:
-		hci_simple_pair_complete_evt(hdev, skb);
-		break;
-
-	case HCI_EV_REMOTE_HOST_FEATURES:
-		hci_remote_host_features_evt(hdev, skb);
-		break;
-
-	case HCI_EV_LE_META:
-		hci_le_meta_evt(hdev, skb);
-		break;
-
-	case HCI_EV_REMOTE_OOB_DATA_REQUEST:
-		hci_remote_oob_data_request_evt(hdev, skb);
-		break;
-
-#if IS_ENABLED(CONFIG_BT_HS)
-	case HCI_EV_CHANNEL_SELECTED:
-		hci_chan_selected_evt(hdev, skb);
-		break;
-
-	case HCI_EV_PHY_LINK_COMPLETE:
-		hci_phy_link_complete_evt(hdev, skb);
-		break;
-
-	case HCI_EV_LOGICAL_LINK_COMPLETE:
-		hci_loglink_complete_evt(hdev, skb);
-		break;
-
-	case HCI_EV_DISCONN_LOGICAL_LINK_COMPLETE:
-		hci_disconn_loglink_complete_evt(hdev, skb);
-		break;
-
-	case HCI_EV_DISCONN_PHY_LINK_COMPLETE:
-		hci_disconn_phylink_complete_evt(hdev, skb);
-		break;
-#endif
-
-	case HCI_EV_NUM_COMP_BLOCKS:
-		hci_num_comp_blocks_evt(hdev, skb);
-		break;
-
-	case HCI_EV_VENDOR:
-		msft_vendor_evt(hdev, skb);
-		break;
-
-	default:
-		BT_DBG("%s event 0x%2.2x", hdev->name, event);
-		break;
-	}
+	hci_event_func(hdev, event, skb, &opcode, &status, &req_complete,
+		       &req_complete_skb);
 
 	if (req_complete) {
 		req_complete(hdev, status, opcode);
diff --git a/net/bluetooth/msft.c b/net/bluetooth/msft.c
index 1122097e1e49..6a943634b31a 100644
--- a/net/bluetooth/msft.c
+++ b/net/bluetooth/msft.c
@@ -590,7 +590,7 @@  void msft_unregister(struct hci_dev *hdev)
 	kfree(msft);
 }
 
-void msft_vendor_evt(struct hci_dev *hdev, struct sk_buff *skb)
+void msft_vendor_evt(struct hci_dev *hdev, void *data, struct sk_buff *skb)
 {
 	struct msft_data *msft = hdev->msft_data;
 	u8 event;
diff --git a/net/bluetooth/msft.h b/net/bluetooth/msft.h
index b59b63dc0ea8..7fefc0655b6f 100644
--- a/net/bluetooth/msft.h
+++ b/net/bluetooth/msft.h
@@ -17,7 +17,7 @@  void msft_register(struct hci_dev *hdev);
 void msft_unregister(struct hci_dev *hdev);
 void msft_do_open(struct hci_dev *hdev);
 void msft_do_close(struct hci_dev *hdev);
-void msft_vendor_evt(struct hci_dev *hdev, struct sk_buff *skb);
+void msft_vendor_evt(struct hci_dev *hdev, void *data, struct sk_buff *skb);
 __u64 msft_get_features(struct hci_dev *hdev);
 int msft_add_monitor_pattern(struct hci_dev *hdev, struct adv_monitor *monitor);
 int msft_remove_monitor(struct hci_dev *hdev, struct adv_monitor *monitor,