static int btrtl_setup_rtl8723b(struct hci_dev *hdev, u16 lmp_subver, const char *fw_name) { unsigned char *fw_data = NULL; const struct firmware *fw; int ret; BT_INFO("%s: rtl: loading %s", hdev->name, fw_name); ret = reject_firmware(&fw, fw_name, &hdev->dev); if (ret < 0) { BT_ERR("%s: Failed to load %s", hdev->name, fw_name); return ret; } ret = rtl8723b_parse_firmware(hdev, lmp_subver, fw, &fw_data); if (ret < 0) goto out; ret = rtl_download_firmware(hdev, fw_data, ret); kfree(fw_data); if (ret < 0) goto out; out: release_firmware(fw); return ret; }
static int btrtl_setup_rtl8723b(struct hci_dev *hdev, u16 lmp_subver, const char *fw_name) { unsigned char *fw_data = NULL; const struct firmware *fw; int ret; int cfg_sz; u8 *cfg_buff = NULL; u8 *tbuff; char *cfg_name = NULL; bool config_needed = false; switch (lmp_subver) { case RTL_ROM_LMP_8723B: cfg_name = "rtl_bt/rtl8723b_config.bin"; break; case RTL_ROM_LMP_8821A: cfg_name = "rtl_bt/rtl8821a_config.bin"; break; case RTL_ROM_LMP_8761A: cfg_name = "rtl_bt/rtl8761a_config.bin"; break; case RTL_ROM_LMP_8822B: cfg_name = "rtl_bt/rtl8822b_config.bin"; config_needed = true; break; default: BT_ERR("%s: rtl: no config according to lmp_subver %04x", hdev->name, lmp_subver); break; } if (cfg_name) { cfg_sz = rtl_load_config(hdev, cfg_name, &cfg_buff); if (cfg_sz < 0) { cfg_sz = 0; if (config_needed) BT_ERR("Necessary config file %s not found\n", cfg_name); } } else cfg_sz = 0; BT_INFO("%s: rtl: loading %s", hdev->name, fw_name); ret = request_firmware(&fw, fw_name, &hdev->dev); if (ret < 0) { BT_ERR("%s: Failed to load %s", hdev->name, fw_name); goto err_req_fw; } ret = rtl8723b_parse_firmware(hdev, lmp_subver, fw, &fw_data); if (ret < 0) goto out; if (cfg_sz) { tbuff = kzalloc(ret + cfg_sz, GFP_KERNEL); if (!tbuff) { ret = -ENOMEM; goto out; } memcpy(tbuff, fw_data, ret); kfree(fw_data); memcpy(tbuff + ret, cfg_buff, cfg_sz); ret += cfg_sz; fw_data = tbuff; } BT_INFO("cfg_sz %d, total size %d", cfg_sz, ret); ret = rtl_download_firmware(hdev, fw_data, ret); out: release_firmware(fw); kfree(fw_data); err_req_fw: if (cfg_sz) kfree(cfg_buff); return ret; }