Loading drivers/bluetooth/ath3k.c +63 −61 Original line number Diff line number Diff line /* * Copyright (c) 2008-2009 Atheros Communications Inc. * Copyright (c) 2014 The Linux Foundation. All rights reserved. * Copyright (c) 2014-2015 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by Loading Loading @@ -31,6 +31,8 @@ #include <asm/unaligned.h> #include <net/bluetooth/bluetooth.h> #include "ath3k.h" #define VERSION "1.0" #define ATH3K_FIRMWARE "ath3k-1.fw" Loading Loading @@ -75,14 +77,6 @@ #define ATH3K_XTAL_FREQ_19P2 0x02 #define ATH3K_NAME_LEN 0xFF struct ath3k_version { unsigned int rom_version; unsigned int build_version; unsigned int ram_version; unsigned char ref_clock; unsigned char reserved[0x07]; }; struct __packed rome1_1_version { u8 type; u8 length[3]; Loading Loading @@ -337,10 +331,15 @@ static int ath3k_get_version(struct usb_device *udev, return ret; } int get_rome_version(struct usb_device *udev) int get_rome_version(struct usb_device *udev, struct ath3k_version *version) { struct ath3k_version fw_version; int ret = 0; int ret; if (!version) { BT_ERR("NULL output parameters"); return -EINVAL; } ret = ath3k_get_version(udev, &fw_version); if (ret < 0) { Loading @@ -352,12 +351,15 @@ int get_rome_version(struct usb_device *udev) case ROME1_1_USB_CHIP_VERSION: case ROME2_1_USB_CHIP_VERSION: case ROME3_0_USB_CHIP_VERSION: ret = fw_version.rom_version; memcpy(version, &fw_version, sizeof(struct ath3k_version)); ret = 0; break; default: ret = 0; BT_ERR("Unsupported ROME USB version"); ret = -EINVAL; break; } return ret; } EXPORT_SYMBOL(get_rome_version); Loading Loading @@ -450,12 +452,13 @@ static int ath3k_set_normal_mode(struct usb_device *udev) NULL, 0, USB_CTRL_SET_TIMEOUT); } static int ath3k_load_patch(struct usb_device *udev) static int ath3k_load_patch(struct usb_device *udev, struct ath3k_version *version) { unsigned char fw_state; char filename[ATH3K_NAME_LEN] = {0}; const struct firmware *firmware; struct ath3k_version fw_version, pt_version; struct ath3k_version pt_version; struct rome2_1_version *rome2_1_version; struct rome1_1_version *rome1_1_version; int ret; Loading @@ -474,66 +477,67 @@ static int ath3k_load_patch(struct usb_device *udev) } BT_DBG("Downloading RamPatch(fw_state: %d)", fw_state); ret = ath3k_get_version(udev, &fw_version); if (ret < 0) { BT_ERR("Can't get version to change to load ram patch err"); return ret; } if (fw_version.rom_version == ROME1_1_USB_CHIP_VERSION) { switch (version->rom_version) { case ROME1_1_USB_CHIP_VERSION: BT_DBG("Chip Detected as ROME1.1"); snprintf(filename, ATH3K_NAME_LEN, ROME1_1_USB_RAMPATCH_FILE); } else if (fw_version.rom_version == ROME2_1_USB_CHIP_VERSION) { break; case ROME2_1_USB_CHIP_VERSION: BT_DBG("Chip Detected as ROME2.1"); snprintf(filename, ATH3K_NAME_LEN, ROME2_1_USB_RAMPATCH_FILE); } else if (fw_version.rom_version == ROME3_0_USB_CHIP_VERSION) { break; case ROME3_0_USB_CHIP_VERSION: BT_DBG("Chip Detected as ROME3.0"); snprintf(filename, ATH3K_NAME_LEN, ROME3_0_USB_RAMPATCH_FILE); } else { break; default: BT_DBG("Chip Detected as Ath3k"); snprintf(filename, ATH3K_NAME_LEN, "ar3k/AthrBT_0x%08x.dfu", fw_version.rom_version); version->rom_version); break; } ret = request_firmware(&firmware, filename, &udev->dev); if (ret < 0) { BT_ERR("Patch file not found %s", filename); return ret; } if ((fw_version.rom_version == ROME2_1_USB_CHIP_VERSION) || (fw_version.rom_version == ROME3_0_USB_CHIP_VERSION)) { if ((version->rom_version == ROME2_1_USB_CHIP_VERSION) || (version->rom_version == ROME3_0_USB_CHIP_VERSION)) { rome2_1_version = (struct rome2_1_version *) firmware->data; pt_version.rom_version = rome2_1_version->build_ver; pt_version.build_version = rome2_1_version->patch_ver; BT_DBG("pt_ver.rome_ver : 0x%x", pt_version.rom_version); BT_DBG("pt_ver.build_ver: 0x%x", pt_version.build_version); BT_DBG("fw_ver.rom_ver: 0x%x", fw_version.rom_version); BT_DBG("fw_ver.build_ver: 0x%x", fw_version.build_version); } else if (fw_version.rom_version == ROME1_1_USB_CHIP_VERSION) { BT_DBG("fw_ver.rom_ver: 0x%x", version->rom_version); BT_DBG("fw_ver.build_ver: 0x%x", version->build_version); } else if (version->rom_version == ROME1_1_USB_CHIP_VERSION) { rome1_1_version = (struct rome1_1_version *) firmware->data; pt_version.build_version = rome1_1_version->build_ver; pt_version.rom_version = rome1_1_version->patch_ver; BT_DBG("pt_ver.rom1.1_ver : 0x%x", pt_version.rom_version); BT_DBG("pt_ver.build1.1_ver: 0x%x", pt_version.build_version); BT_DBG("fw_ver.rom1.1_ver: 0x%x", fw_version.rom_version); BT_DBG("fw_ver.build1.1_ver: 0x%x", fw_version.build_version); BT_DBG("fw_ver.rom1.1_ver: 0x%x", version->rom_version); BT_DBG("fw_ver.build1.1_ver: 0x%x", version->build_version); } else { pt_version.rom_version = *(int *)(firmware->data + firmware->size - 8); pt_version.build_version = *(int *) (firmware->data + firmware->size - 4); } if ((pt_version.rom_version != fw_version.rom_version) || (pt_version.build_version <= fw_version.build_version)) { if ((pt_version.rom_version != version->rom_version) || (pt_version.build_version <= version->build_version)) { BT_ERR("Patch file version did not match with firmware"); release_firmware(firmware); return -EINVAL; } if ((fw_version.rom_version == ROME2_1_USB_CHIP_VERSION) || (fw_version.rom_version == ROME3_0_USB_CHIP_VERSION)) if ((version->rom_version == ROME2_1_USB_CHIP_VERSION) || (version->rom_version == ROME3_0_USB_CHIP_VERSION)) ret = ath3k_load_fwfile(udev, firmware, ROME2_1_USB_RAMPATCH_HEADER); else if (fw_version.rom_version == ROME1_1_USB_CHIP_VERSION) else if (version->rom_version == ROME1_1_USB_CHIP_VERSION) ret = ath3k_load_fwfile(udev, firmware, ROME1_1_USB_RAMPATCH_HEADER); else Loading @@ -544,12 +548,12 @@ static int ath3k_load_patch(struct usb_device *udev) return ret; } static int ath3k_load_syscfg(struct usb_device *udev) static int ath3k_load_syscfg(struct usb_device *udev, struct ath3k_version *version) { unsigned char fw_state; char filename[ATH3K_NAME_LEN] = {0}; const struct firmware *firmware; struct ath3k_version fw_version; int clk_value, ret; ret = ath3k_get_state(udev, &fw_state); Loading @@ -566,14 +570,7 @@ static int ath3k_load_syscfg(struct usb_device *udev) } BT_DBG("Downloading NVM(fw_state: %d)", fw_state); ret = ath3k_get_version(udev, &fw_version); if (ret < 0) { BT_ERR("Can't get version to change to load ram patch err"); return ret; } switch (fw_version.ref_clock) { switch (version->ref_clock) { case ATH3K_XTAL_FREQ_26M: clk_value = 26; break; Loading @@ -588,15 +585,15 @@ static int ath3k_load_syscfg(struct usb_device *udev) break; } if (fw_version.rom_version == ROME2_1_USB_CHIP_VERSION) if (version->rom_version == ROME2_1_USB_CHIP_VERSION) snprintf(filename, ATH3K_NAME_LEN, ROME2_1_USB_NVM_FILE); else if (fw_version.rom_version == ROME3_0_USB_CHIP_VERSION) else if (version->rom_version == ROME3_0_USB_CHIP_VERSION) snprintf(filename, ATH3K_NAME_LEN, ROME3_0_USB_NVM_FILE); else if (fw_version.rom_version == ROME1_1_USB_CHIP_VERSION) else if (version->rom_version == ROME1_1_USB_CHIP_VERSION) snprintf(filename, ATH3K_NAME_LEN, ROME1_1_USB_NVM_FILE); else snprintf(filename, ATH3K_NAME_LEN, "ar3k/ramps_0x%08x_%d%s", fw_version.rom_version, clk_value, ".dfu"); version->rom_version, clk_value, ".dfu"); ret = request_firmware(&firmware, filename, &udev->dev); if (ret < 0) { Loading @@ -604,29 +601,29 @@ static int ath3k_load_syscfg(struct usb_device *udev) return ret; } if ((fw_version.rom_version == ROME2_1_USB_CHIP_VERSION) || (fw_version.rom_version == ROME3_0_USB_CHIP_VERSION)) if ((version->rom_version == ROME2_1_USB_CHIP_VERSION) || (version->rom_version == ROME3_0_USB_CHIP_VERSION)) ret = ath3k_load_fwfile(udev, firmware, ROME2_1_USB_NVM_HEADER); else if (fw_version.rom_version == ROME1_1_USB_CHIP_VERSION) else if (version->rom_version == ROME1_1_USB_CHIP_VERSION) ret = ath3k_load_fwfile(udev, firmware, ROME1_1_USB_NVM_HEADER); else ret = ath3k_load_fwfile(udev, firmware, FW_HDR_SIZE); release_firmware(firmware); return ret; } int rome_download(struct usb_device *udev) int rome_download(struct usb_device *udev, struct ath3k_version *version) { int ret; ret = ath3k_load_patch(udev); ret = ath3k_load_patch(udev, version); if (ret < 0) { BT_ERR("Loading patch file failed"); return ret; } ret = ath3k_load_syscfg(udev); ret = ath3k_load_syscfg(udev, version); if (ret < 0) { BT_ERR("Loading sysconfig file failed"); return ret; Loading @@ -635,21 +632,26 @@ int rome_download(struct usb_device *udev) return ret; } EXPORT_SYMBOL(rome_download); static int ath3k_probe(struct usb_interface *intf, const struct usb_device_id *id) { const struct firmware *firmware; struct usb_device *udev = interface_to_usbdev(intf); int ret; struct ath3k_version version; BT_DBG("intf %p id %p", intf, id); if (intf->cur_altsetting->desc.bInterfaceNumber != 0) return -ENODEV; if (get_rome_version(udev)) { ret = get_rome_version(udev, &version); if (!ret) { BT_INFO("Rome detected, fw dnld will be triggered from btusb"); return -ENODEV; } /* match device ID in ath3k blacklist table */ if (!id->driver_info) { const struct usb_device_id *match; Loading @@ -665,12 +667,12 @@ static int ath3k_probe(struct usb_interface *intf, if (le16_to_cpu(udev->descriptor.bcdDevice) > 0x0001) return -ENODEV; ret = ath3k_load_patch(udev); ret = ath3k_load_patch(udev, &version); if (ret < 0) { BT_ERR("Loading patch file failed"); return ret; } ret = ath3k_load_syscfg(udev); ret = ath3k_load_syscfg(udev, &version); if (ret < 0) { BT_ERR("Loading sysconfig file failed"); return ret; Loading drivers/bluetooth/ath3k.h 0 → 100644 +27 −0 Original line number Diff line number Diff line /* * Copyright (c) 2008-2009 Atheros Communications Inc. * Copyright (c) 2014-2015 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and * only version 2 as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ #include <linux/usb.h> struct ath3k_version { unsigned int rom_version; unsigned int build_version; unsigned int ram_version; unsigned char ref_clock; unsigned char reserved[0x07]; }; int get_rome_version(struct usb_device *udev, struct ath3k_version *version); int rome_download(struct usb_device *udev, struct ath3k_version *version); drivers/bluetooth/btusb.c +17 −8 Original line number Diff line number Diff line Loading @@ -27,6 +27,8 @@ #include <net/bluetooth/bluetooth.h> #include <net/bluetooth/hci_core.h> #include "ath3k.h" #define VERSION "0.6" static bool disable_scofix; Loading Loading @@ -1964,7 +1966,8 @@ static int btusb_probe(struct usb_interface *intf, struct usb_endpoint_descriptor *ep_desc; struct btusb_data *data; struct hci_dev *hdev; int i, version, err; int i, err; struct ath3k_version version; BT_DBG("intf %p id %p", intf, id); Loading @@ -1985,18 +1988,24 @@ static int btusb_probe(struct usb_interface *intf, if (id->driver_info & BTUSB_ATH3012) { struct usb_device *udev = interface_to_usbdev(intf); version = get_rome_version(udev); BT_INFO("Rome Version: 0x%x", version); /* Old firmware would otherwise let ath3k driver load * patch and sysconfig files */ if (version) rome_download(udev); else if (le16_to_cpu(udev->descriptor.bcdDevice) <= 0x0001) { err = get_rome_version(udev, &version); if (err < 0) { if (le16_to_cpu(udev->descriptor.bcdDevice) <= 0x0001) BT_INFO("FW for ar3k is yet to be downloaded"); else BT_ERR("Failed to get ROME USB version"); return -ENODEV; } BT_INFO("Rome Version: 0x%x", version.rom_version); err = rome_download(udev, &version); if (err < 0) { BT_ERR("Failed to download ROME firmware"); return -ENODEV; } } data = devm_kzalloc(&intf->dev, sizeof(*data), GFP_KERNEL); if (!data) return -ENOMEM; Loading include/net/bluetooth/bluetooth.h +1 −4 Original line number Diff line number Diff line /* BlueZ - Bluetooth protocol stack for Linux Copyright (C) 2000-2001 Qualcomm Incorporated Copyright (C) 2014 The Linux Foundation. All rights reserved. Copyright (C) 2014-2015 The Linux Foundation. All rights reserved. Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com> Loading Loading @@ -362,7 +362,4 @@ void sco_exit(void); void bt_sock_reclassify_lock(struct sock *sk, int proto); int get_rome_version(struct usb_device *udev); int rome_download(struct usb_device *udev); #endif /* __BLUETOOTH_H */ Loading
drivers/bluetooth/ath3k.c +63 −61 Original line number Diff line number Diff line /* * Copyright (c) 2008-2009 Atheros Communications Inc. * Copyright (c) 2014 The Linux Foundation. All rights reserved. * Copyright (c) 2014-2015 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by Loading Loading @@ -31,6 +31,8 @@ #include <asm/unaligned.h> #include <net/bluetooth/bluetooth.h> #include "ath3k.h" #define VERSION "1.0" #define ATH3K_FIRMWARE "ath3k-1.fw" Loading Loading @@ -75,14 +77,6 @@ #define ATH3K_XTAL_FREQ_19P2 0x02 #define ATH3K_NAME_LEN 0xFF struct ath3k_version { unsigned int rom_version; unsigned int build_version; unsigned int ram_version; unsigned char ref_clock; unsigned char reserved[0x07]; }; struct __packed rome1_1_version { u8 type; u8 length[3]; Loading Loading @@ -337,10 +331,15 @@ static int ath3k_get_version(struct usb_device *udev, return ret; } int get_rome_version(struct usb_device *udev) int get_rome_version(struct usb_device *udev, struct ath3k_version *version) { struct ath3k_version fw_version; int ret = 0; int ret; if (!version) { BT_ERR("NULL output parameters"); return -EINVAL; } ret = ath3k_get_version(udev, &fw_version); if (ret < 0) { Loading @@ -352,12 +351,15 @@ int get_rome_version(struct usb_device *udev) case ROME1_1_USB_CHIP_VERSION: case ROME2_1_USB_CHIP_VERSION: case ROME3_0_USB_CHIP_VERSION: ret = fw_version.rom_version; memcpy(version, &fw_version, sizeof(struct ath3k_version)); ret = 0; break; default: ret = 0; BT_ERR("Unsupported ROME USB version"); ret = -EINVAL; break; } return ret; } EXPORT_SYMBOL(get_rome_version); Loading Loading @@ -450,12 +452,13 @@ static int ath3k_set_normal_mode(struct usb_device *udev) NULL, 0, USB_CTRL_SET_TIMEOUT); } static int ath3k_load_patch(struct usb_device *udev) static int ath3k_load_patch(struct usb_device *udev, struct ath3k_version *version) { unsigned char fw_state; char filename[ATH3K_NAME_LEN] = {0}; const struct firmware *firmware; struct ath3k_version fw_version, pt_version; struct ath3k_version pt_version; struct rome2_1_version *rome2_1_version; struct rome1_1_version *rome1_1_version; int ret; Loading @@ -474,66 +477,67 @@ static int ath3k_load_patch(struct usb_device *udev) } BT_DBG("Downloading RamPatch(fw_state: %d)", fw_state); ret = ath3k_get_version(udev, &fw_version); if (ret < 0) { BT_ERR("Can't get version to change to load ram patch err"); return ret; } if (fw_version.rom_version == ROME1_1_USB_CHIP_VERSION) { switch (version->rom_version) { case ROME1_1_USB_CHIP_VERSION: BT_DBG("Chip Detected as ROME1.1"); snprintf(filename, ATH3K_NAME_LEN, ROME1_1_USB_RAMPATCH_FILE); } else if (fw_version.rom_version == ROME2_1_USB_CHIP_VERSION) { break; case ROME2_1_USB_CHIP_VERSION: BT_DBG("Chip Detected as ROME2.1"); snprintf(filename, ATH3K_NAME_LEN, ROME2_1_USB_RAMPATCH_FILE); } else if (fw_version.rom_version == ROME3_0_USB_CHIP_VERSION) { break; case ROME3_0_USB_CHIP_VERSION: BT_DBG("Chip Detected as ROME3.0"); snprintf(filename, ATH3K_NAME_LEN, ROME3_0_USB_RAMPATCH_FILE); } else { break; default: BT_DBG("Chip Detected as Ath3k"); snprintf(filename, ATH3K_NAME_LEN, "ar3k/AthrBT_0x%08x.dfu", fw_version.rom_version); version->rom_version); break; } ret = request_firmware(&firmware, filename, &udev->dev); if (ret < 0) { BT_ERR("Patch file not found %s", filename); return ret; } if ((fw_version.rom_version == ROME2_1_USB_CHIP_VERSION) || (fw_version.rom_version == ROME3_0_USB_CHIP_VERSION)) { if ((version->rom_version == ROME2_1_USB_CHIP_VERSION) || (version->rom_version == ROME3_0_USB_CHIP_VERSION)) { rome2_1_version = (struct rome2_1_version *) firmware->data; pt_version.rom_version = rome2_1_version->build_ver; pt_version.build_version = rome2_1_version->patch_ver; BT_DBG("pt_ver.rome_ver : 0x%x", pt_version.rom_version); BT_DBG("pt_ver.build_ver: 0x%x", pt_version.build_version); BT_DBG("fw_ver.rom_ver: 0x%x", fw_version.rom_version); BT_DBG("fw_ver.build_ver: 0x%x", fw_version.build_version); } else if (fw_version.rom_version == ROME1_1_USB_CHIP_VERSION) { BT_DBG("fw_ver.rom_ver: 0x%x", version->rom_version); BT_DBG("fw_ver.build_ver: 0x%x", version->build_version); } else if (version->rom_version == ROME1_1_USB_CHIP_VERSION) { rome1_1_version = (struct rome1_1_version *) firmware->data; pt_version.build_version = rome1_1_version->build_ver; pt_version.rom_version = rome1_1_version->patch_ver; BT_DBG("pt_ver.rom1.1_ver : 0x%x", pt_version.rom_version); BT_DBG("pt_ver.build1.1_ver: 0x%x", pt_version.build_version); BT_DBG("fw_ver.rom1.1_ver: 0x%x", fw_version.rom_version); BT_DBG("fw_ver.build1.1_ver: 0x%x", fw_version.build_version); BT_DBG("fw_ver.rom1.1_ver: 0x%x", version->rom_version); BT_DBG("fw_ver.build1.1_ver: 0x%x", version->build_version); } else { pt_version.rom_version = *(int *)(firmware->data + firmware->size - 8); pt_version.build_version = *(int *) (firmware->data + firmware->size - 4); } if ((pt_version.rom_version != fw_version.rom_version) || (pt_version.build_version <= fw_version.build_version)) { if ((pt_version.rom_version != version->rom_version) || (pt_version.build_version <= version->build_version)) { BT_ERR("Patch file version did not match with firmware"); release_firmware(firmware); return -EINVAL; } if ((fw_version.rom_version == ROME2_1_USB_CHIP_VERSION) || (fw_version.rom_version == ROME3_0_USB_CHIP_VERSION)) if ((version->rom_version == ROME2_1_USB_CHIP_VERSION) || (version->rom_version == ROME3_0_USB_CHIP_VERSION)) ret = ath3k_load_fwfile(udev, firmware, ROME2_1_USB_RAMPATCH_HEADER); else if (fw_version.rom_version == ROME1_1_USB_CHIP_VERSION) else if (version->rom_version == ROME1_1_USB_CHIP_VERSION) ret = ath3k_load_fwfile(udev, firmware, ROME1_1_USB_RAMPATCH_HEADER); else Loading @@ -544,12 +548,12 @@ static int ath3k_load_patch(struct usb_device *udev) return ret; } static int ath3k_load_syscfg(struct usb_device *udev) static int ath3k_load_syscfg(struct usb_device *udev, struct ath3k_version *version) { unsigned char fw_state; char filename[ATH3K_NAME_LEN] = {0}; const struct firmware *firmware; struct ath3k_version fw_version; int clk_value, ret; ret = ath3k_get_state(udev, &fw_state); Loading @@ -566,14 +570,7 @@ static int ath3k_load_syscfg(struct usb_device *udev) } BT_DBG("Downloading NVM(fw_state: %d)", fw_state); ret = ath3k_get_version(udev, &fw_version); if (ret < 0) { BT_ERR("Can't get version to change to load ram patch err"); return ret; } switch (fw_version.ref_clock) { switch (version->ref_clock) { case ATH3K_XTAL_FREQ_26M: clk_value = 26; break; Loading @@ -588,15 +585,15 @@ static int ath3k_load_syscfg(struct usb_device *udev) break; } if (fw_version.rom_version == ROME2_1_USB_CHIP_VERSION) if (version->rom_version == ROME2_1_USB_CHIP_VERSION) snprintf(filename, ATH3K_NAME_LEN, ROME2_1_USB_NVM_FILE); else if (fw_version.rom_version == ROME3_0_USB_CHIP_VERSION) else if (version->rom_version == ROME3_0_USB_CHIP_VERSION) snprintf(filename, ATH3K_NAME_LEN, ROME3_0_USB_NVM_FILE); else if (fw_version.rom_version == ROME1_1_USB_CHIP_VERSION) else if (version->rom_version == ROME1_1_USB_CHIP_VERSION) snprintf(filename, ATH3K_NAME_LEN, ROME1_1_USB_NVM_FILE); else snprintf(filename, ATH3K_NAME_LEN, "ar3k/ramps_0x%08x_%d%s", fw_version.rom_version, clk_value, ".dfu"); version->rom_version, clk_value, ".dfu"); ret = request_firmware(&firmware, filename, &udev->dev); if (ret < 0) { Loading @@ -604,29 +601,29 @@ static int ath3k_load_syscfg(struct usb_device *udev) return ret; } if ((fw_version.rom_version == ROME2_1_USB_CHIP_VERSION) || (fw_version.rom_version == ROME3_0_USB_CHIP_VERSION)) if ((version->rom_version == ROME2_1_USB_CHIP_VERSION) || (version->rom_version == ROME3_0_USB_CHIP_VERSION)) ret = ath3k_load_fwfile(udev, firmware, ROME2_1_USB_NVM_HEADER); else if (fw_version.rom_version == ROME1_1_USB_CHIP_VERSION) else if (version->rom_version == ROME1_1_USB_CHIP_VERSION) ret = ath3k_load_fwfile(udev, firmware, ROME1_1_USB_NVM_HEADER); else ret = ath3k_load_fwfile(udev, firmware, FW_HDR_SIZE); release_firmware(firmware); return ret; } int rome_download(struct usb_device *udev) int rome_download(struct usb_device *udev, struct ath3k_version *version) { int ret; ret = ath3k_load_patch(udev); ret = ath3k_load_patch(udev, version); if (ret < 0) { BT_ERR("Loading patch file failed"); return ret; } ret = ath3k_load_syscfg(udev); ret = ath3k_load_syscfg(udev, version); if (ret < 0) { BT_ERR("Loading sysconfig file failed"); return ret; Loading @@ -635,21 +632,26 @@ int rome_download(struct usb_device *udev) return ret; } EXPORT_SYMBOL(rome_download); static int ath3k_probe(struct usb_interface *intf, const struct usb_device_id *id) { const struct firmware *firmware; struct usb_device *udev = interface_to_usbdev(intf); int ret; struct ath3k_version version; BT_DBG("intf %p id %p", intf, id); if (intf->cur_altsetting->desc.bInterfaceNumber != 0) return -ENODEV; if (get_rome_version(udev)) { ret = get_rome_version(udev, &version); if (!ret) { BT_INFO("Rome detected, fw dnld will be triggered from btusb"); return -ENODEV; } /* match device ID in ath3k blacklist table */ if (!id->driver_info) { const struct usb_device_id *match; Loading @@ -665,12 +667,12 @@ static int ath3k_probe(struct usb_interface *intf, if (le16_to_cpu(udev->descriptor.bcdDevice) > 0x0001) return -ENODEV; ret = ath3k_load_patch(udev); ret = ath3k_load_patch(udev, &version); if (ret < 0) { BT_ERR("Loading patch file failed"); return ret; } ret = ath3k_load_syscfg(udev); ret = ath3k_load_syscfg(udev, &version); if (ret < 0) { BT_ERR("Loading sysconfig file failed"); return ret; Loading
drivers/bluetooth/ath3k.h 0 → 100644 +27 −0 Original line number Diff line number Diff line /* * Copyright (c) 2008-2009 Atheros Communications Inc. * Copyright (c) 2014-2015 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and * only version 2 as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ #include <linux/usb.h> struct ath3k_version { unsigned int rom_version; unsigned int build_version; unsigned int ram_version; unsigned char ref_clock; unsigned char reserved[0x07]; }; int get_rome_version(struct usb_device *udev, struct ath3k_version *version); int rome_download(struct usb_device *udev, struct ath3k_version *version);
drivers/bluetooth/btusb.c +17 −8 Original line number Diff line number Diff line Loading @@ -27,6 +27,8 @@ #include <net/bluetooth/bluetooth.h> #include <net/bluetooth/hci_core.h> #include "ath3k.h" #define VERSION "0.6" static bool disable_scofix; Loading Loading @@ -1964,7 +1966,8 @@ static int btusb_probe(struct usb_interface *intf, struct usb_endpoint_descriptor *ep_desc; struct btusb_data *data; struct hci_dev *hdev; int i, version, err; int i, err; struct ath3k_version version; BT_DBG("intf %p id %p", intf, id); Loading @@ -1985,18 +1988,24 @@ static int btusb_probe(struct usb_interface *intf, if (id->driver_info & BTUSB_ATH3012) { struct usb_device *udev = interface_to_usbdev(intf); version = get_rome_version(udev); BT_INFO("Rome Version: 0x%x", version); /* Old firmware would otherwise let ath3k driver load * patch and sysconfig files */ if (version) rome_download(udev); else if (le16_to_cpu(udev->descriptor.bcdDevice) <= 0x0001) { err = get_rome_version(udev, &version); if (err < 0) { if (le16_to_cpu(udev->descriptor.bcdDevice) <= 0x0001) BT_INFO("FW for ar3k is yet to be downloaded"); else BT_ERR("Failed to get ROME USB version"); return -ENODEV; } BT_INFO("Rome Version: 0x%x", version.rom_version); err = rome_download(udev, &version); if (err < 0) { BT_ERR("Failed to download ROME firmware"); return -ENODEV; } } data = devm_kzalloc(&intf->dev, sizeof(*data), GFP_KERNEL); if (!data) return -ENOMEM; Loading
include/net/bluetooth/bluetooth.h +1 −4 Original line number Diff line number Diff line /* BlueZ - Bluetooth protocol stack for Linux Copyright (C) 2000-2001 Qualcomm Incorporated Copyright (C) 2014 The Linux Foundation. All rights reserved. Copyright (C) 2014-2015 The Linux Foundation. All rights reserved. Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com> Loading Loading @@ -362,7 +362,4 @@ void sco_exit(void); void bt_sock_reclassify_lock(struct sock *sk, int proto); int get_rome_version(struct usb_device *udev); int rome_download(struct usb_device *udev); #endif /* __BLUETOOTH_H */