static int btusb_setup_csr()

in btusb.c [1954:2097]


static int btusb_setup_csr(struct hci_dev *hdev)
{
	struct btusb_data *data = hci_get_drvdata(hdev);
	u16 bcdDevice = le16_to_cpu(data->udev->descriptor.bcdDevice);
	struct hci_rp_read_local_version *rp;
	struct sk_buff *skb;
	bool is_fake = false;
	int ret;

	BT_DBG("%s", hdev->name);

	skb = __hci_cmd_sync(hdev, HCI_OP_READ_LOCAL_VERSION, 0, NULL,
			     HCI_INIT_TIMEOUT);
	if (IS_ERR(skb)) {
		int err = PTR_ERR(skb);
		bt_dev_err(hdev, "CSR: Local version failed (%d)", err);
		return err;
	}

	if (skb->len != sizeof(struct hci_rp_read_local_version)) {
		bt_dev_err(hdev, "CSR: Local version length mismatch");
		kfree_skb(skb);
		return -EIO;
	}

	rp = (struct hci_rp_read_local_version *)skb->data;

	/* Detect a wide host of Chinese controllers that aren't CSR.
	 *
	 * Known fake bcdDevices: 0x0100, 0x0134, 0x1915, 0x2520, 0x7558, 0x8891
	 *
	 * The main thing they have in common is that these are really popular low-cost
	 * options that support newer Bluetooth versions but rely on heavy VID/PID
	 * squatting of this poor old Bluetooth 1.1 device. Even sold as such.
	 *
	 * We detect actual CSR devices by checking that the HCI manufacturer code
	 * is Cambridge Silicon Radio (10) and ensuring that LMP sub-version and
	 * HCI rev values always match. As they both store the firmware number.
	 */
	if (le16_to_cpu(rp->manufacturer) != 10 ||
	    le16_to_cpu(rp->hci_rev) != le16_to_cpu(rp->lmp_subver))
		is_fake = true;

	/* Known legit CSR firmware build numbers and their supported BT versions:
	 * - 1.1 (0x1) -> 0x0073, 0x020d, 0x033c, 0x034e
	 * - 1.2 (0x2) ->                 0x04d9, 0x0529
	 * - 2.0 (0x3) ->         0x07a6, 0x07ad, 0x0c5c
	 * - 2.1 (0x4) ->         0x149c, 0x1735, 0x1899 (0x1899 is a BlueCore4-External)
	 * - 4.0 (0x6) ->         0x1d86, 0x2031, 0x22bb
	 *
	 * e.g. Real CSR dongles with LMP subversion 0x73 are old enough that
	 *      support BT 1.1 only; so it's a dead giveaway when some
	 *      third-party BT 4.0 dongle reuses it.
	 */
	else if (le16_to_cpu(rp->lmp_subver) <= 0x034e &&
		 le16_to_cpu(rp->hci_ver) > BLUETOOTH_VER_1_1)
		is_fake = true;

	else if (le16_to_cpu(rp->lmp_subver) <= 0x0529 &&
		 le16_to_cpu(rp->hci_ver) > BLUETOOTH_VER_1_2)
		is_fake = true;

	else if (le16_to_cpu(rp->lmp_subver) <= 0x0c5c &&
		 le16_to_cpu(rp->hci_ver) > BLUETOOTH_VER_2_0)
		is_fake = true;

	else if (le16_to_cpu(rp->lmp_subver) <= 0x1899 &&
		 le16_to_cpu(rp->hci_ver) > BLUETOOTH_VER_2_1)
		is_fake = true;

	else if (le16_to_cpu(rp->lmp_subver) <= 0x22bb &&
		 le16_to_cpu(rp->hci_ver) > BLUETOOTH_VER_4_0)
		is_fake = true;

	/* Other clones which beat all the above checks */
	else if (bcdDevice == 0x0134 &&
		 le16_to_cpu(rp->lmp_subver) == 0x0c5c &&
		 le16_to_cpu(rp->hci_ver) == BLUETOOTH_VER_2_0)
		is_fake = true;

	if (is_fake) {
		bt_dev_warn(hdev, "CSR: Unbranded CSR clone detected; adding workarounds and force-suspending once...");

		/* Generally these clones have big discrepancies between
		 * advertised features and what's actually supported.
		 * Probably will need to be expanded in the future;
		 * without these the controller will lock up.
		 */
		set_bit(HCI_QUIRK_BROKEN_STORED_LINK_KEY, &hdev->quirks);
		set_bit(HCI_QUIRK_BROKEN_ERR_DATA_REPORTING, &hdev->quirks);

		/* Clear the reset quirk since this is not an actual
		 * early Bluetooth 1.1 device from CSR.
		 */
		clear_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks);
		clear_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks);

		/*
		 * Special workaround for these BT 4.0 chip clones, and potentially more:
		 *
		 * - 0x0134: a Barrot 8041a02                 (HCI rev: 0x1012 sub: 0x0810)
		 * - 0x7558: IC markings FR3191AHAL 749H15143 (HCI rev/sub-version: 0x0709)
		 *
		 * These controllers are really messed-up.
		 *
		 * 1. Their bulk RX endpoint will never report any data unless
		 * the device was suspended at least once (yes, really).
		 * 2. They will not wakeup when autosuspended and receiving data
		 * on their bulk RX endpoint from e.g. a keyboard or mouse
		 * (IOW remote-wakeup support is broken for the bulk endpoint).
		 *
		 * To fix 1. enable runtime-suspend, force-suspend the
		 * HCI and then wake-it up by disabling runtime-suspend.
		 *
		 * To fix 2. clear the HCI's can_wake flag, this way the HCI
		 * will still be autosuspended when it is not open.
		 *
		 * --
		 *
		 * Because these are widespread problems we prefer generic solutions; so
		 * apply this initialization quirk to every controller that gets here,
		 * it should be harmless. The alternative is to not work at all.
		 */
		pm_runtime_allow(&data->udev->dev);

		ret = pm_runtime_suspend(&data->udev->dev);
		if (ret >= 0)
			msleep(200);
		else
			bt_dev_err(hdev, "CSR: Failed to suspend the device for our Barrot 8041a02 receive-issue workaround");

		pm_runtime_forbid(&data->udev->dev);

		device_set_wakeup_capable(&data->udev->dev, false);

		/* Re-enable autosuspend if this was requested */
		if (enable_autosuspend)
			usb_enable_autosuspend(data->udev);
	}

	kfree_skb(skb);

	return 0;
}