]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/bluetooth/btusb.c
Merge tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
[karo-tx-linux.git] / drivers / bluetooth / btusb.c
index 92f0ee388f9e0bfddd0cdf32b684edf25741d991..a191e318fab88a92fa52641b3d27d1ea94ced0ce 100644 (file)
@@ -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 },
@@ -437,22 +441,22 @@ static int btusb_recv_intr(struct btusb_data *data, void *buffer, int count)
                                break;
                        }
 
-                       bt_cb(skb)->pkt_type = HCI_EVENT_PKT;
-                       bt_cb(skb)->expect = HCI_EVENT_HDR_SIZE;
+                       hci_skb_pkt_type(skb) = HCI_EVENT_PKT;
+                       hci_skb_expect(skb) = HCI_EVENT_HDR_SIZE;
                }
 
-               len = min_t(uint, bt_cb(skb)->expect, count);
+               len = min_t(uint, hci_skb_expect(skb), count);
                memcpy(skb_put(skb, len), buffer, len);
 
                count -= len;
                buffer += len;
-               bt_cb(skb)->expect -= len;
+               hci_skb_expect(skb) -= len;
 
                if (skb->len == HCI_EVENT_HDR_SIZE) {
                        /* Complete event header */
-                       bt_cb(skb)->expect = hci_event_hdr(skb)->plen;
+                       hci_skb_expect(skb) = hci_event_hdr(skb)->plen;
 
-                       if (skb_tailroom(skb) < bt_cb(skb)->expect) {
+                       if (skb_tailroom(skb) < hci_skb_expect(skb)) {
                                kfree_skb(skb);
                                skb = NULL;
 
@@ -461,7 +465,7 @@ static int btusb_recv_intr(struct btusb_data *data, void *buffer, int count)
                        }
                }
 
-               if (bt_cb(skb)->expect == 0) {
+               if (!hci_skb_expect(skb)) {
                        /* Complete frame */
                        data->recv_event(data->hdev, skb);
                        skb = NULL;
@@ -492,24 +496,24 @@ static int btusb_recv_bulk(struct btusb_data *data, void *buffer, int count)
                                break;
                        }
 
-                       bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
-                       bt_cb(skb)->expect = HCI_ACL_HDR_SIZE;
+                       hci_skb_pkt_type(skb) = HCI_ACLDATA_PKT;
+                       hci_skb_expect(skb) = HCI_ACL_HDR_SIZE;
                }
 
-               len = min_t(uint, bt_cb(skb)->expect, count);
+               len = min_t(uint, hci_skb_expect(skb), count);
                memcpy(skb_put(skb, len), buffer, len);
 
                count -= len;
                buffer += len;
-               bt_cb(skb)->expect -= len;
+               hci_skb_expect(skb) -= len;
 
                if (skb->len == HCI_ACL_HDR_SIZE) {
                        __le16 dlen = hci_acl_hdr(skb)->dlen;
 
                        /* Complete ACL header */
-                       bt_cb(skb)->expect = __le16_to_cpu(dlen);
+                       hci_skb_expect(skb) = __le16_to_cpu(dlen);
 
-                       if (skb_tailroom(skb) < bt_cb(skb)->expect) {
+                       if (skb_tailroom(skb) < hci_skb_expect(skb)) {
                                kfree_skb(skb);
                                skb = NULL;
 
@@ -518,7 +522,7 @@ static int btusb_recv_bulk(struct btusb_data *data, void *buffer, int count)
                        }
                }
 
-               if (bt_cb(skb)->expect == 0) {
+               if (!hci_skb_expect(skb)) {
                        /* Complete frame */
                        hci_recv_frame(data->hdev, skb);
                        skb = NULL;
@@ -549,22 +553,22 @@ static int btusb_recv_isoc(struct btusb_data *data, void *buffer, int count)
                                break;
                        }
 
-                       bt_cb(skb)->pkt_type = HCI_SCODATA_PKT;
-                       bt_cb(skb)->expect = HCI_SCO_HDR_SIZE;
+                       hci_skb_pkt_type(skb) = HCI_SCODATA_PKT;
+                       hci_skb_expect(skb) = HCI_SCO_HDR_SIZE;
                }
 
-               len = min_t(uint, bt_cb(skb)->expect, count);
+               len = min_t(uint, hci_skb_expect(skb), count);
                memcpy(skb_put(skb, len), buffer, len);
 
                count -= len;
                buffer += len;
-               bt_cb(skb)->expect -= len;
+               hci_skb_expect(skb) -= len;
 
                if (skb->len == HCI_SCO_HDR_SIZE) {
                        /* Complete SCO header */
-                       bt_cb(skb)->expect = hci_sco_hdr(skb)->dlen;
+                       hci_skb_expect(skb) = hci_sco_hdr(skb)->dlen;
 
-                       if (skb_tailroom(skb) < bt_cb(skb)->expect) {
+                       if (skb_tailroom(skb) < hci_skb_expect(skb)) {
                                kfree_skb(skb);
                                skb = NULL;
 
@@ -573,7 +577,7 @@ static int btusb_recv_isoc(struct btusb_data *data, void *buffer, int count)
                        }
                }
 
-               if (bt_cb(skb)->expect == 0) {
+               if (!hci_skb_expect(skb)) {
                        /* Complete frame */
                        hci_recv_frame(data->hdev, skb);
                        skb = NULL;
@@ -1257,7 +1261,7 @@ static int btusb_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
 
        BT_DBG("%s", hdev->name);
 
-       switch (bt_cb(skb)->pkt_type) {
+       switch (hci_skb_pkt_type(skb)) {
        case HCI_COMMAND_PKT:
                urb = alloc_ctrl_urb(hdev, skb);
                if (IS_ERR(urb))
@@ -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);
@@ -1853,7 +1814,7 @@ static int inject_cmd_complete(struct hci_dev *hdev, __u16 opcode)
 
        *skb_put(skb, 1) = 0x00;
 
-       bt_cb(skb)->pkt_type = HCI_EVENT_PKT;
+       hci_skb_pkt_type(skb) = HCI_EVENT_PKT;
 
        return hci_recv_frame(hdev, skb);
 }
@@ -1945,7 +1906,7 @@ static int btusb_send_frame_intel(struct hci_dev *hdev, struct sk_buff *skb)
 
        BT_DBG("%s", hdev->name);
 
-       switch (bt_cb(skb)->pkt_type) {
+       switch (hci_skb_pkt_type(skb)) {
        case HCI_COMMAND_PKT:
                if (test_bit(BTUSB_BOOTLOADER, &data->flags)) {
                        struct hci_command_hdr *cmd = (void *)skb->data;
@@ -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.
         */