Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Bluetooth: btrtl: Add Realtek devcoredump support

Catch debug exception from controller and driver, and trigger a
devcoredump using hci devcoredump APIs. The debug exception data
will be parsed in userspace.

Signed-off-by: Alex Lu <alex_lu@realsil.com.cn>
Signed-off-by: Hilda Wu <hildawu@realtek.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

authored by

Hilda Wu and committed by
Luiz Augusto von Dentz
044014ce ae753361

+205 -27
+118 -27
drivers/bluetooth/btrtl.c
··· 32 32 #define RTL_ROM_LMP_8851B 0x8851 33 33 #define RTL_CONFIG_MAGIC 0x8723ab55 34 34 35 + #define RTL_VSC_OP_COREDUMP 0xfcff 36 + 35 37 #define IC_MATCH_FL_LMPSUBV (1 << 0) 36 38 #define IC_MATCH_FL_HCIREV (1 << 1) 37 39 #define IC_MATCH_FL_HCIVER (1 << 2) ··· 83 81 bool has_msft_ext; 84 82 char *fw_name; 85 83 char *cfg_name; 84 + char *hw_info; 86 85 }; 87 86 88 87 struct btrtl_device_info { ··· 105 102 .config_needed = false, 106 103 .has_rom_version = false, 107 104 .fw_name = "rtl_bt/rtl8723a_fw.bin", 108 - .cfg_name = NULL }, 105 + .cfg_name = NULL, 106 + .hw_info = "rtl8723au" }, 109 107 110 108 /* 8723BS */ 111 109 { IC_INFO(RTL_ROM_LMP_8723B, 0xb, 0x6, HCI_UART), 112 110 .config_needed = true, 113 111 .has_rom_version = true, 114 112 .fw_name = "rtl_bt/rtl8723bs_fw.bin", 115 - .cfg_name = "rtl_bt/rtl8723bs_config" }, 113 + .cfg_name = "rtl_bt/rtl8723bs_config", 114 + .hw_info = "rtl8723bs" }, 116 115 117 116 /* 8723B */ 118 117 { IC_INFO(RTL_ROM_LMP_8723B, 0xb, 0x6, HCI_USB), 119 118 .config_needed = false, 120 119 .has_rom_version = true, 121 120 .fw_name = "rtl_bt/rtl8723b_fw.bin", 122 - .cfg_name = "rtl_bt/rtl8723b_config" }, 121 + .cfg_name = "rtl_bt/rtl8723b_config", 122 + .hw_info = "rtl8723bu" }, 123 123 124 124 /* 8723CS-CG */ 125 125 { .match_flags = IC_MATCH_FL_LMPSUBV | IC_MATCH_FL_CHIP_TYPE | ··· 133 127 .config_needed = true, 134 128 .has_rom_version = true, 135 129 .fw_name = "rtl_bt/rtl8723cs_cg_fw.bin", 136 - .cfg_name = "rtl_bt/rtl8723cs_cg_config" }, 130 + .cfg_name = "rtl_bt/rtl8723cs_cg_config", 131 + .hw_info = "rtl8723cs-cg" }, 137 132 138 133 /* 8723CS-VF */ 139 134 { .match_flags = IC_MATCH_FL_LMPSUBV | IC_MATCH_FL_CHIP_TYPE | ··· 145 138 .config_needed = true, 146 139 .has_rom_version = true, 147 140 .fw_name = "rtl_bt/rtl8723cs_vf_fw.bin", 148 - .cfg_name = "rtl_bt/rtl8723cs_vf_config" }, 141 + .cfg_name = "rtl_bt/rtl8723cs_vf_config", 142 + .hw_info = "rtl8723cs-vf" }, 149 143 150 144 /* 8723CS-XX */ 151 145 { .match_flags = IC_MATCH_FL_LMPSUBV | IC_MATCH_FL_CHIP_TYPE | ··· 157 149 .config_needed = true, 158 150 .has_rom_version = true, 159 151 .fw_name = "rtl_bt/rtl8723cs_xx_fw.bin", 160 - .cfg_name = "rtl_bt/rtl8723cs_xx_config" }, 152 + .cfg_name = "rtl_bt/rtl8723cs_xx_config", 153 + .hw_info = "rtl8723cs" }, 161 154 162 155 /* 8723D */ 163 156 { IC_INFO(RTL_ROM_LMP_8723B, 0xd, 0x8, HCI_USB), 164 157 .config_needed = true, 165 158 .has_rom_version = true, 166 159 .fw_name = "rtl_bt/rtl8723d_fw.bin", 167 - .cfg_name = "rtl_bt/rtl8723d_config" }, 160 + .cfg_name = "rtl_bt/rtl8723d_config", 161 + .hw_info = "rtl8723du" }, 168 162 169 163 /* 8723DS */ 170 164 { IC_INFO(RTL_ROM_LMP_8723B, 0xd, 0x8, HCI_UART), 171 165 .config_needed = true, 172 166 .has_rom_version = true, 173 167 .fw_name = "rtl_bt/rtl8723ds_fw.bin", 174 - .cfg_name = "rtl_bt/rtl8723ds_config" }, 168 + .cfg_name = "rtl_bt/rtl8723ds_config", 169 + .hw_info = "rtl8723ds" }, 175 170 176 171 /* 8821A */ 177 172 { IC_INFO(RTL_ROM_LMP_8821A, 0xa, 0x6, HCI_USB), 178 173 .config_needed = false, 179 174 .has_rom_version = true, 180 175 .fw_name = "rtl_bt/rtl8821a_fw.bin", 181 - .cfg_name = "rtl_bt/rtl8821a_config" }, 176 + .cfg_name = "rtl_bt/rtl8821a_config", 177 + .hw_info = "rtl8821au" }, 182 178 183 179 /* 8821C */ 184 180 { IC_INFO(RTL_ROM_LMP_8821A, 0xc, 0x8, HCI_USB), ··· 190 178 .has_rom_version = true, 191 179 .has_msft_ext = true, 192 180 .fw_name = "rtl_bt/rtl8821c_fw.bin", 193 - .cfg_name = "rtl_bt/rtl8821c_config" }, 181 + .cfg_name = "rtl_bt/rtl8821c_config", 182 + .hw_info = "rtl8821cu" }, 194 183 195 184 /* 8821CS */ 196 185 { IC_INFO(RTL_ROM_LMP_8821A, 0xc, 0x8, HCI_UART), ··· 199 186 .has_rom_version = true, 200 187 .has_msft_ext = true, 201 188 .fw_name = "rtl_bt/rtl8821cs_fw.bin", 202 - .cfg_name = "rtl_bt/rtl8821cs_config" }, 189 + .cfg_name = "rtl_bt/rtl8821cs_config", 190 + .hw_info = "rtl8821cs" }, 203 191 204 192 /* 8761A */ 205 193 { IC_INFO(RTL_ROM_LMP_8761A, 0xa, 0x6, HCI_USB), 206 194 .config_needed = false, 207 195 .has_rom_version = true, 208 196 .fw_name = "rtl_bt/rtl8761a_fw.bin", 209 - .cfg_name = "rtl_bt/rtl8761a_config" }, 197 + .cfg_name = "rtl_bt/rtl8761a_config", 198 + .hw_info = "rtl8761au" }, 210 199 211 200 /* 8761B */ 212 201 { IC_INFO(RTL_ROM_LMP_8761A, 0xb, 0xa, HCI_UART), ··· 216 201 .has_rom_version = true, 217 202 .has_msft_ext = true, 218 203 .fw_name = "rtl_bt/rtl8761b_fw.bin", 219 - .cfg_name = "rtl_bt/rtl8761b_config" }, 204 + .cfg_name = "rtl_bt/rtl8761b_config", 205 + .hw_info = "rtl8761btv" }, 220 206 221 207 /* 8761BU */ 222 208 { IC_INFO(RTL_ROM_LMP_8761A, 0xb, 0xa, HCI_USB), 223 209 .config_needed = false, 224 210 .has_rom_version = true, 225 211 .fw_name = "rtl_bt/rtl8761bu_fw.bin", 226 - .cfg_name = "rtl_bt/rtl8761bu_config" }, 212 + .cfg_name = "rtl_bt/rtl8761bu_config", 213 + .hw_info = "rtl8761bu" }, 227 214 228 215 /* 8822C with UART interface */ 229 216 { IC_INFO(RTL_ROM_LMP_8822B, 0xc, 0x8, HCI_UART), ··· 233 216 .has_rom_version = true, 234 217 .has_msft_ext = true, 235 218 .fw_name = "rtl_bt/rtl8822cs_fw.bin", 236 - .cfg_name = "rtl_bt/rtl8822cs_config" }, 219 + .cfg_name = "rtl_bt/rtl8822cs_config", 220 + .hw_info = "rtl8822cs" }, 237 221 238 222 /* 8822C with UART interface */ 239 223 { IC_INFO(RTL_ROM_LMP_8822B, 0xc, 0xa, HCI_UART), ··· 242 224 .has_rom_version = true, 243 225 .has_msft_ext = true, 244 226 .fw_name = "rtl_bt/rtl8822cs_fw.bin", 245 - .cfg_name = "rtl_bt/rtl8822cs_config" }, 227 + .cfg_name = "rtl_bt/rtl8822cs_config", 228 + .hw_info = "rtl8822cs" }, 246 229 247 230 /* 8822C with USB interface */ 248 231 { IC_INFO(RTL_ROM_LMP_8822B, 0xc, 0xa, HCI_USB), ··· 251 232 .has_rom_version = true, 252 233 .has_msft_ext = true, 253 234 .fw_name = "rtl_bt/rtl8822cu_fw.bin", 254 - .cfg_name = "rtl_bt/rtl8822cu_config" }, 235 + .cfg_name = "rtl_bt/rtl8822cu_config", 236 + .hw_info = "rtl8822cu" }, 255 237 256 238 /* 8822B */ 257 239 { IC_INFO(RTL_ROM_LMP_8822B, 0xb, 0x7, HCI_USB), ··· 260 240 .has_rom_version = true, 261 241 .has_msft_ext = true, 262 242 .fw_name = "rtl_bt/rtl8822b_fw.bin", 263 - .cfg_name = "rtl_bt/rtl8822b_config" }, 243 + .cfg_name = "rtl_bt/rtl8822b_config", 244 + .hw_info = "rtl8822bu" }, 264 245 265 246 /* 8852A */ 266 247 { IC_INFO(RTL_ROM_LMP_8852A, 0xa, 0xb, HCI_USB), ··· 269 248 .has_rom_version = true, 270 249 .has_msft_ext = true, 271 250 .fw_name = "rtl_bt/rtl8852au_fw.bin", 272 - .cfg_name = "rtl_bt/rtl8852au_config" }, 251 + .cfg_name = "rtl_bt/rtl8852au_config", 252 + .hw_info = "rtl8852au" }, 273 253 274 254 /* 8852B with UART interface */ 275 255 { IC_INFO(RTL_ROM_LMP_8852A, 0xb, 0xb, HCI_UART), ··· 278 256 .has_rom_version = true, 279 257 .has_msft_ext = true, 280 258 .fw_name = "rtl_bt/rtl8852bs_fw.bin", 281 - .cfg_name = "rtl_bt/rtl8852bs_config" }, 259 + .cfg_name = "rtl_bt/rtl8852bs_config", 260 + .hw_info = "rtl8852bs" }, 282 261 283 262 /* 8852B */ 284 263 { IC_INFO(RTL_ROM_LMP_8852A, 0xb, 0xb, HCI_USB), ··· 287 264 .has_rom_version = true, 288 265 .has_msft_ext = true, 289 266 .fw_name = "rtl_bt/rtl8852bu_fw.bin", 290 - .cfg_name = "rtl_bt/rtl8852bu_config" }, 267 + .cfg_name = "rtl_bt/rtl8852bu_config", 268 + .hw_info = "rtl8852bu" }, 291 269 292 270 /* 8852C */ 293 271 { IC_INFO(RTL_ROM_LMP_8852A, 0xc, 0xc, HCI_USB), ··· 296 272 .has_rom_version = true, 297 273 .has_msft_ext = true, 298 274 .fw_name = "rtl_bt/rtl8852cu_fw.bin", 299 - .cfg_name = "rtl_bt/rtl8852cu_config" }, 275 + .cfg_name = "rtl_bt/rtl8852cu_config", 276 + .hw_info = "rtl8852cu" }, 300 277 301 278 /* 8851B */ 302 279 { IC_INFO(RTL_ROM_LMP_8851B, 0xb, 0xc, HCI_USB), ··· 305 280 .has_rom_version = true, 306 281 .has_msft_ext = false, 307 282 .fw_name = "rtl_bt/rtl8851bu_fw.bin", 308 - .cfg_name = "rtl_bt/rtl8851bu_config" }, 283 + .cfg_name = "rtl_bt/rtl8851bu_config", 284 + .hw_info = "rtl8851bu" }, 309 285 }; 310 286 311 287 static const struct id_table *btrtl_match_ic(u16 lmp_subver, u16 hci_rev, ··· 616 590 unsigned char **_buf) 617 591 { 618 592 static const u8 extension_sig[] = { 0x51, 0x04, 0xfd, 0x77 }; 593 + struct btrealtek_data *coredump_info = hci_get_priv(hdev); 619 594 struct rtl_epatch_header *epatch_info; 620 595 unsigned char *buf; 621 596 int i, len; ··· 732 705 733 706 epatch_info = (struct rtl_epatch_header *)btrtl_dev->fw_data; 734 707 num_patches = le16_to_cpu(epatch_info->num_patches); 708 + 735 709 BT_DBG("fw_version=%x, num_patches=%d", 736 710 le32_to_cpu(epatch_info->fw_version), num_patches); 711 + coredump_info->rtl_dump.fw_version = le32_to_cpu(epatch_info->fw_version); 737 712 738 713 /* After the rtl_epatch_header there is a funky patch metadata section. 739 714 * Assuming 2 patches, the layout is: ··· 932 903 return ret; 933 904 } 934 905 906 + static void btrtl_coredump(struct hci_dev *hdev) 907 + { 908 + static const u8 param[] = { 0x00, 0x00 }; 909 + 910 + __hci_cmd_send(hdev, RTL_VSC_OP_COREDUMP, sizeof(param), param); 911 + } 912 + 913 + static void btrtl_dmp_hdr(struct hci_dev *hdev, struct sk_buff *skb) 914 + { 915 + struct btrealtek_data *coredump_info = hci_get_priv(hdev); 916 + char buf[80]; 917 + 918 + if (coredump_info->rtl_dump.controller) 919 + snprintf(buf, sizeof(buf), "Controller Name: %s\n", 920 + coredump_info->rtl_dump.controller); 921 + else 922 + snprintf(buf, sizeof(buf), "Controller Name: Unknown\n"); 923 + skb_put_data(skb, buf, strlen(buf)); 924 + 925 + snprintf(buf, sizeof(buf), "Firmware Version: 0x%X\n", 926 + coredump_info->rtl_dump.fw_version); 927 + skb_put_data(skb, buf, strlen(buf)); 928 + 929 + snprintf(buf, sizeof(buf), "Driver: %s\n", coredump_info->rtl_dump.driver_name); 930 + skb_put_data(skb, buf, strlen(buf)); 931 + 932 + snprintf(buf, sizeof(buf), "Vendor: Realtek\n"); 933 + skb_put_data(skb, buf, strlen(buf)); 934 + } 935 + 936 + static int btrtl_register_devcoredump_support(struct hci_dev *hdev) 937 + { 938 + int err; 939 + 940 + err = hci_devcd_register(hdev, btrtl_coredump, btrtl_dmp_hdr, NULL); 941 + 942 + return err; 943 + } 944 + 945 + void btrtl_set_driver_name(struct hci_dev *hdev, const char *driver_name) 946 + { 947 + struct btrealtek_data *coredump_info = hci_get_priv(hdev); 948 + 949 + coredump_info->rtl_dump.driver_name = driver_name; 950 + } 951 + EXPORT_SYMBOL_GPL(btrtl_set_driver_name); 952 + 935 953 static bool rtl_has_chip_type(u16 lmp_subver) 936 954 { 937 955 switch (lmp_subver) { ··· 1040 964 struct btrtl_device_info *btrtl_initialize(struct hci_dev *hdev, 1041 965 const char *postfix) 1042 966 { 967 + struct btrealtek_data *coredump_info = hci_get_priv(hdev); 1043 968 struct btrtl_device_info *btrtl_dev; 1044 969 struct sk_buff *skb; 1045 970 struct hci_rp_read_local_version *resp; ··· 1190 1113 if (btrtl_dev->ic_info->has_msft_ext) 1191 1114 hci_set_msft_opcode(hdev, 0xFCF0); 1192 1115 1116 + if (btrtl_dev->ic_info) 1117 + coredump_info->rtl_dump.controller = btrtl_dev->ic_info->hw_info; 1118 + 1193 1119 return btrtl_dev; 1194 1120 1195 1121 err_free: ··· 1205 1125 int btrtl_download_firmware(struct hci_dev *hdev, 1206 1126 struct btrtl_device_info *btrtl_dev) 1207 1127 { 1128 + int err = 0; 1129 + 1208 1130 /* Match a set of subver values that correspond to stock firmware, 1209 1131 * which is not compatible with standard btusb. 1210 1132 * If matched, upload an alternative firmware that does conform to ··· 1215 1133 */ 1216 1134 if (!btrtl_dev->ic_info) { 1217 1135 rtl_dev_info(hdev, "assuming no firmware upload needed"); 1218 - return 0; 1136 + err = 0; 1137 + goto done; 1219 1138 } 1220 1139 1221 1140 switch (btrtl_dev->ic_info->lmp_subver) { 1222 1141 case RTL_ROM_LMP_8723A: 1223 - return btrtl_setup_rtl8723a(hdev, btrtl_dev); 1142 + err = btrtl_setup_rtl8723a(hdev, btrtl_dev); 1143 + break; 1224 1144 case RTL_ROM_LMP_8723B: 1225 1145 case RTL_ROM_LMP_8821A: 1226 1146 case RTL_ROM_LMP_8761A: ··· 1230 1146 case RTL_ROM_LMP_8852A: 1231 1147 case RTL_ROM_LMP_8703B: 1232 1148 case RTL_ROM_LMP_8851B: 1233 - return btrtl_setup_rtl8723b(hdev, btrtl_dev); 1149 + err = btrtl_setup_rtl8723b(hdev, btrtl_dev); 1150 + break; 1234 1151 default: 1235 1152 rtl_dev_info(hdev, "assuming no firmware upload needed"); 1236 - return 0; 1153 + break; 1237 1154 } 1155 + 1156 + done: 1157 + if (!err) 1158 + err = btrtl_register_devcoredump_support(hdev); 1159 + 1160 + return err; 1238 1161 } 1239 1162 EXPORT_SYMBOL_GPL(btrtl_download_firmware); 1240 1163
+13
drivers/bluetooth/btrtl.h
··· 109 109 __REALTEK_NUM_FLAGS, 110 110 }; 111 111 112 + struct rtl_dump_info { 113 + const char *driver_name; 114 + char *controller; 115 + u32 fw_version; 116 + }; 117 + 112 118 struct btrealtek_data { 113 119 DECLARE_BITMAP(flags, __REALTEK_NUM_FLAGS); 120 + 121 + struct rtl_dump_info rtl_dump; 114 122 }; 115 123 116 124 #define btrealtek_set_flag(hdev, nr) \ ··· 147 139 struct btrtl_device_info *btrtl_dev, 148 140 unsigned int *controller_baudrate, 149 141 u32 *device_baudrate, bool *flow_control); 142 + void btrtl_set_driver_name(struct hci_dev *hdev, const char *driver_name); 150 143 151 144 #else 152 145 ··· 189 180 bool *flow_control) 190 181 { 191 182 return -ENOENT; 183 + } 184 + 185 + static inline void btrtl_set_driver_name(struct hci_dev *hdev, const char *driver_name) 186 + { 192 187 } 193 188 194 189 #endif
+74
drivers/bluetooth/btusb.c
··· 887 887 gpiod_set_value_cansleep(reset_gpio, 0); 888 888 } 889 889 890 + #define RTK_DEVCOREDUMP_CODE_MEMDUMP 0x01 891 + #define RTK_DEVCOREDUMP_CODE_HW_ERR 0x02 892 + #define RTK_DEVCOREDUMP_CODE_CMD_TIMEOUT 0x03 893 + 894 + #define RTK_SUB_EVENT_CODE_COREDUMP 0x34 895 + 896 + struct rtk_dev_coredump_hdr { 897 + u8 type; 898 + u8 code; 899 + u8 reserved[2]; 900 + } __packed; 901 + 902 + static inline void btusb_rtl_alloc_devcoredump(struct hci_dev *hdev, 903 + struct rtk_dev_coredump_hdr *hdr, u8 *buf, u32 len) 904 + { 905 + struct sk_buff *skb; 906 + 907 + skb = alloc_skb(len + sizeof(*hdr), GFP_ATOMIC); 908 + if (!skb) 909 + return; 910 + 911 + skb_put_data(skb, hdr, sizeof(*hdr)); 912 + if (len) 913 + skb_put_data(skb, buf, len); 914 + 915 + if (!hci_devcd_init(hdev, skb->len)) { 916 + hci_devcd_append(hdev, skb); 917 + hci_devcd_complete(hdev); 918 + } else { 919 + bt_dev_err(hdev, "RTL: Failed to generate devcoredump"); 920 + kfree_skb(skb); 921 + } 922 + } 923 + 890 924 static void btusb_rtl_cmd_timeout(struct hci_dev *hdev) 891 925 { 892 926 struct btusb_data *data = hci_get_drvdata(hdev); 893 927 struct gpio_desc *reset_gpio = data->reset_gpio; 928 + struct rtk_dev_coredump_hdr hdr = { 929 + .type = RTK_DEVCOREDUMP_CODE_CMD_TIMEOUT, 930 + }; 931 + 932 + btusb_rtl_alloc_devcoredump(hdev, &hdr, NULL, 0); 894 933 895 934 if (++data->cmd_timeout_cnt < 5) 896 935 return; ··· 954 915 gpiod_set_value_cansleep(reset_gpio, 1); 955 916 msleep(200); 956 917 gpiod_set_value_cansleep(reset_gpio, 0); 918 + } 919 + 920 + static void btusb_rtl_hw_error(struct hci_dev *hdev, u8 code) 921 + { 922 + struct rtk_dev_coredump_hdr hdr = { 923 + .type = RTK_DEVCOREDUMP_CODE_HW_ERR, 924 + .code = code, 925 + }; 926 + 927 + bt_dev_err(hdev, "RTL: hw err, trigger devcoredump (%d)", code); 928 + 929 + btusb_rtl_alloc_devcoredump(hdev, &hdr, NULL, 0); 957 930 } 958 931 959 932 static void btusb_qca_cmd_timeout(struct hci_dev *hdev) ··· 2613 2562 return ret; 2614 2563 } 2615 2564 2565 + static int btusb_recv_event_realtek(struct hci_dev *hdev, struct sk_buff *skb) 2566 + { 2567 + if (skb->data[0] == HCI_VENDOR_PKT && skb->data[2] == RTK_SUB_EVENT_CODE_COREDUMP) { 2568 + struct rtk_dev_coredump_hdr hdr = { 2569 + .code = RTK_DEVCOREDUMP_CODE_MEMDUMP, 2570 + }; 2571 + 2572 + bt_dev_dbg(hdev, "RTL: received coredump vendor evt, len %u", 2573 + skb->len); 2574 + 2575 + btusb_rtl_alloc_devcoredump(hdev, &hdr, skb->data, skb->len); 2576 + kfree_skb(skb); 2577 + 2578 + return 0; 2579 + } 2580 + 2581 + return hci_recv_frame(hdev, skb); 2582 + } 2583 + 2616 2584 /* UHW CR mapping */ 2617 2585 #define MTK_BT_MISC 0x70002510 2618 2586 #define MTK_BT_SUBSYS_RST 0x70002610 ··· 4271 4201 } else if (id->driver_info & BTUSB_REALTEK) { 4272 4202 /* Allocate extra space for Realtek device */ 4273 4203 priv_size += sizeof(struct btrealtek_data); 4204 + 4205 + data->recv_event = btusb_recv_event_realtek; 4274 4206 } 4275 4207 4276 4208 data->recv_acl = hci_recv_frame; ··· 4436 4364 4437 4365 if (IS_ENABLED(CONFIG_BT_HCIBTUSB_RTL) && 4438 4366 (id->driver_info & BTUSB_REALTEK)) { 4367 + btrtl_set_driver_name(hdev, btusb_driver.name); 4439 4368 hdev->setup = btusb_setup_realtek; 4440 4369 hdev->shutdown = btrtl_shutdown_realtek; 4441 4370 hdev->cmd_timeout = btusb_rtl_cmd_timeout; 4371 + hdev->hw_error = btusb_rtl_hw_error; 4442 4372 4443 4373 /* Realtek devices need to set remote wakeup on auto-suspend */ 4444 4374 set_bit(BTUSB_WAKEUP_AUTOSUSPEND, &data->flags);