diff options
Diffstat (limited to 'drivers/bluetooth')
-rw-r--r-- | drivers/bluetooth/btusb.c | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 66966b9c4244..32aabea731f2 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -1182,6 +1182,49 @@ static int btusb_setup_intel_patching(struct hci_dev *hdev, return 0; } +#define BDADDR_INTEL (&(bdaddr_t) {{0x00, 0x8b, 0x9e, 0x19, 0x03, 0x00}}) + +static int btusb_check_bdaddr_intel(struct hci_dev *hdev) +{ + struct sk_buff *skb; + struct hci_rp_read_bd_addr *rp; + + skb = __hci_cmd_sync(hdev, HCI_OP_READ_BD_ADDR, 0, NULL, + HCI_INIT_TIMEOUT); + if (IS_ERR(skb)) { + BT_ERR("%s reading Intel device address failed (%ld)", + hdev->name, PTR_ERR(skb)); + return PTR_ERR(skb); + } + + if (skb->len != sizeof(*rp)) { + BT_ERR("%s Intel device address length mismatch", hdev->name); + kfree_skb(skb); + return -EIO; + } + + rp = (struct hci_rp_read_bd_addr *) skb->data; + if (rp->status) { + BT_ERR("%s Intel device address result failed (%02x)", + hdev->name, rp->status); + kfree_skb(skb); + return -bt_to_errno(rp->status); + } + + /* For some Intel based controllers, the default Bluetooth device + * address 00:03:19:9E:8B:00 can be found. These controllers are + * fully operational, but have the danger of duplicate addresses + * and that in turn can cause problems with Bluetooth operation. + */ + if (!bacmp(&rp->bdaddr, BDADDR_INTEL)) + BT_ERR("%s found Intel default device address (%pMR)", + hdev->name, &rp->bdaddr); + + kfree_skb(skb); + + return 0; +} + static int btusb_setup_intel(struct hci_dev *hdev) { struct sk_buff *skb; @@ -1254,6 +1297,7 @@ static int btusb_setup_intel(struct hci_dev *hdev) BT_INFO("%s: Intel device is already patched. patch num: %02x", hdev->name, ver->fw_patch_num); kfree_skb(skb); + btusb_check_bdaddr_intel(hdev); return 0; } @@ -1266,6 +1310,7 @@ static int btusb_setup_intel(struct hci_dev *hdev) fw = btusb_setup_intel_get_fw(hdev, ver); if (!fw) { kfree_skb(skb); + btusb_check_bdaddr_intel(hdev); return 0; } fw_ptr = fw->data; @@ -1345,6 +1390,7 @@ static int btusb_setup_intel(struct hci_dev *hdev) BT_INFO("%s: Intel Bluetooth firmware patch completed and activated", hdev->name); + btusb_check_bdaddr_intel(hdev); return 0; exit_mfg_disable: @@ -1359,6 +1405,8 @@ exit_mfg_disable: kfree_skb(skb); BT_INFO("%s: Intel Bluetooth firmware patch completed", hdev->name); + + btusb_check_bdaddr_intel(hdev); return 0; exit_mfg_deactivate: @@ -1379,6 +1427,7 @@ exit_mfg_deactivate: BT_INFO("%s: Intel Bluetooth firmware patch completed and deactivated", hdev->name); + btusb_check_bdaddr_intel(hdev); return 0; } |