aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/bluetooth/btusb.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/bluetooth/btusb.c')
-rw-r--r--drivers/bluetooth/btusb.c138
1 files changed, 41 insertions, 97 deletions
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index 806353410eb7..a191e318fab8 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -153,6 +153,10 @@ static const struct usb_device_id btusb_table[] = {
{ USB_VENDOR_AND_INTERFACE_INFO(0x13d3, 0xff, 0x01, 0x01),
.driver_info = BTUSB_BCM_PATCHRAM },
+ /* Toshiba Corp - Broadcom based */
+ { USB_VENDOR_AND_INTERFACE_INFO(0x0930, 0xff, 0x01, 0x01),
+ .driver_info = BTUSB_BCM_PATCHRAM },
+
/* Intel Bluetooth USB Bootloader (RAM module) */
{ USB_DEVICE(0x8087, 0x0a5a),
.driver_info = BTUSB_INTEL_BOOT | BTUSB_BROKEN_ISOC },
@@ -1642,13 +1646,8 @@ static int btusb_setup_intel(struct hci_dev *hdev)
struct sk_buff *skb;
const struct firmware *fw;
const u8 *fw_ptr;
- int disable_patch;
- struct intel_version *ver;
-
- const u8 mfg_enable[] = { 0x01, 0x00 };
- const u8 mfg_disable[] = { 0x00, 0x00 };
- const u8 mfg_reset_deactivate[] = { 0x00, 0x01 };
- const u8 mfg_reset_activate[] = { 0x00, 0x02 };
+ int disable_patch, err;
+ struct intel_version ver;
BT_DBG("%s", hdev->name);
@@ -1674,35 +1673,22 @@ static int btusb_setup_intel(struct hci_dev *hdev)
* The returned information are hardware variant and revision plus
* firmware variant, revision and build number.
*/
- skb = __hci_cmd_sync(hdev, 0xfc05, 0, NULL, HCI_INIT_TIMEOUT);
- if (IS_ERR(skb)) {
- BT_ERR("%s reading Intel fw version command failed (%ld)",
- hdev->name, PTR_ERR(skb));
- return PTR_ERR(skb);
- }
-
- if (skb->len != sizeof(*ver)) {
- BT_ERR("%s Intel version event length mismatch", hdev->name);
- kfree_skb(skb);
- return -EIO;
- }
-
- ver = (struct intel_version *)skb->data;
+ err = btintel_read_version(hdev, &ver);
+ if (err)
+ return err;
BT_INFO("%s: read Intel version: %02x%02x%02x%02x%02x%02x%02x%02x%02x",
- hdev->name, ver->hw_platform, ver->hw_variant,
- ver->hw_revision, ver->fw_variant, ver->fw_revision,
- ver->fw_build_num, ver->fw_build_ww, ver->fw_build_yy,
- ver->fw_patch_num);
+ hdev->name, ver.hw_platform, ver.hw_variant, ver.hw_revision,
+ ver.fw_variant, ver.fw_revision, ver.fw_build_num,
+ ver.fw_build_ww, ver.fw_build_yy, ver.fw_patch_num);
/* fw_patch_num indicates the version of patch the device currently
* have. If there is no patch data in the device, it is always 0x00.
* So, if it is other than 0x00, no need to patch the device again.
*/
- if (ver->fw_patch_num) {
+ if (ver.fw_patch_num) {
BT_INFO("%s: Intel device is already patched. patch num: %02x",
- hdev->name, ver->fw_patch_num);
- kfree_skb(skb);
+ hdev->name, ver.fw_patch_num);
goto complete;
}
@@ -1712,31 +1698,21 @@ static int btusb_setup_intel(struct hci_dev *hdev)
* If no patch file is found, allow the device to operate without
* a patch.
*/
- fw = btusb_setup_intel_get_fw(hdev, ver);
- if (!fw) {
- kfree_skb(skb);
+ fw = btusb_setup_intel_get_fw(hdev, &ver);
+ if (!fw)
goto complete;
- }
fw_ptr = fw->data;
- kfree_skb(skb);
-
- /* This Intel specific command enables the manufacturer mode of the
- * controller.
- *
+ /* Enable the manufacturer mode of the controller.
* Only while this mode is enabled, the driver can download the
* firmware patch data and configuration parameters.
*/
- skb = __hci_cmd_sync(hdev, 0xfc11, 2, mfg_enable, HCI_INIT_TIMEOUT);
- if (IS_ERR(skb)) {
- BT_ERR("%s entering Intel manufacturer mode failed (%ld)",
- hdev->name, PTR_ERR(skb));
+ err = btintel_enter_mfg(hdev);
+ if (err) {
release_firmware(fw);
- return PTR_ERR(skb);
+ return err;
}
- kfree_skb(skb);
-
disable_patch = 1;
/* The firmware data file consists of list of Intel specific HCI
@@ -1776,14 +1752,9 @@ static int btusb_setup_intel(struct hci_dev *hdev)
/* Patching completed successfully and disable the manufacturer mode
* with reset and activate the downloaded firmware patches.
*/
- skb = __hci_cmd_sync(hdev, 0xfc11, sizeof(mfg_reset_activate),
- mfg_reset_activate, HCI_INIT_TIMEOUT);
- if (IS_ERR(skb)) {
- BT_ERR("%s exiting Intel manufacturer mode failed (%ld)",
- hdev->name, PTR_ERR(skb));
- return PTR_ERR(skb);
- }
- kfree_skb(skb);
+ err = btintel_exit_mfg(hdev, true, true);
+ if (err)
+ return err;
BT_INFO("%s: Intel Bluetooth firmware patch completed and activated",
hdev->name);
@@ -1792,14 +1763,9 @@ static int btusb_setup_intel(struct hci_dev *hdev)
exit_mfg_disable:
/* Disable the manufacturer mode without reset */
- skb = __hci_cmd_sync(hdev, 0xfc11, sizeof(mfg_disable), mfg_disable,
- HCI_INIT_TIMEOUT);
- if (IS_ERR(skb)) {
- BT_ERR("%s exiting Intel manufacturer mode failed (%ld)",
- hdev->name, PTR_ERR(skb));
- return PTR_ERR(skb);
- }
- kfree_skb(skb);
+ err = btintel_exit_mfg(hdev, false, false);
+ if (err)
+ return err;
BT_INFO("%s: Intel Bluetooth firmware patch completed", hdev->name);
@@ -1811,14 +1777,9 @@ exit_mfg_deactivate:
/* Patching failed. Disable the manufacturer mode with reset and
* deactivate the downloaded firmware patches.
*/
- skb = __hci_cmd_sync(hdev, 0xfc11, sizeof(mfg_reset_deactivate),
- mfg_reset_deactivate, HCI_INIT_TIMEOUT);
- if (IS_ERR(skb)) {
- BT_ERR("%s exiting Intel manufacturer mode failed (%ld)",
- hdev->name, PTR_ERR(skb));
- return PTR_ERR(skb);
- }
- kfree_skb(skb);
+ err = btintel_exit_mfg(hdev, true, false);
+ if (err)
+ return err;
BT_INFO("%s: Intel Bluetooth firmware patch completed and deactivated",
hdev->name);
@@ -2005,7 +1966,7 @@ static int btusb_setup_intel_new(struct hci_dev *hdev)
0x00, 0x08, 0x04, 0x00 };
struct btusb_data *data = hci_get_drvdata(hdev);
struct sk_buff *skb;
- struct intel_version *ver;
+ struct intel_version ver;
struct intel_boot_params *params;
const struct firmware *fw;
const u8 *fw_ptr;
@@ -2023,28 +1984,16 @@ static int btusb_setup_intel_new(struct hci_dev *hdev)
* is in bootloader mode or if it already has operational firmware
* loaded.
*/
- skb = __hci_cmd_sync(hdev, 0xfc05, 0, NULL, HCI_INIT_TIMEOUT);
- if (IS_ERR(skb)) {
- BT_ERR("%s: Reading Intel version information failed (%ld)",
- hdev->name, PTR_ERR(skb));
- return PTR_ERR(skb);
- }
-
- if (skb->len != sizeof(*ver)) {
- BT_ERR("%s: Intel version event size mismatch", hdev->name);
- kfree_skb(skb);
- return -EILSEQ;
- }
-
- ver = (struct intel_version *)skb->data;
+ err = btintel_read_version(hdev, &ver);
+ if (err)
+ return err;
/* The hardware platform number has a fixed value of 0x37 and
* for now only accept this single value.
*/
- if (ver->hw_platform != 0x37) {
+ if (ver.hw_platform != 0x37) {
BT_ERR("%s: Unsupported Intel hardware platform (%u)",
- hdev->name, ver->hw_platform);
- kfree_skb(skb);
+ hdev->name, ver.hw_platform);
return -EINVAL;
}
@@ -2053,14 +2002,13 @@ static int btusb_setup_intel_new(struct hci_dev *hdev)
* put in place to ensure correct forward compatibility options
* when newer hardware variants come along.
*/
- if (ver->hw_variant != 0x0b) {
+ if (ver.hw_variant != 0x0b) {
BT_ERR("%s: Unsupported Intel hardware variant (%u)",
- hdev->name, ver->hw_variant);
- kfree_skb(skb);
+ hdev->name, ver.hw_variant);
return -EINVAL;
}
- btintel_version_info(hdev, ver);
+ btintel_version_info(hdev, &ver);
/* The firmware variant determines if the device is in bootloader
* mode or is running operational firmware. The value 0x06 identifies
@@ -2075,8 +2023,7 @@ static int btusb_setup_intel_new(struct hci_dev *hdev)
* It is not possible to use the Secure Boot Parameters in this
* case since that command is only available in bootloader mode.
*/
- if (ver->fw_variant == 0x23) {
- kfree_skb(skb);
+ if (ver.fw_variant == 0x23) {
clear_bit(BTUSB_BOOTLOADER, &data->flags);
btintel_check_bdaddr(hdev);
return 0;
@@ -2085,15 +2032,12 @@ static int btusb_setup_intel_new(struct hci_dev *hdev)
/* If the device is not in bootloader mode, then the only possible
* choice is to return an error and abort the device initialization.
*/
- if (ver->fw_variant != 0x06) {
+ if (ver.fw_variant != 0x06) {
BT_ERR("%s: Unsupported Intel firmware variant (%u)",
- hdev->name, ver->fw_variant);
- kfree_skb(skb);
+ hdev->name, ver.fw_variant);
return -ENODEV;
}
- kfree_skb(skb);
-
/* Read the secure boot parameters to identify the operating
* details of the bootloader.
*/