Merge tag 'drivers-for-3.17' of git://git.kernel.org/pub/scm/linux/kernel/git/arm...
[firefly-linux-kernel-4.4.55.git] / drivers / bluetooth / ath3k.c
index f50dffc0374fb4ca9222d75683523c73a9dfce43..a0d7355ef1275e865ad09d6e3503c953111cf4fd 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/device.h>
 #include <linux/firmware.h>
 #include <linux/usb.h>
+#include <asm/unaligned.h>
 #include <net/bluetooth/bluetooth.h>
 
 #define VERSION "1.0"
 #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];
-};
+       __le32  rom_version;
+       __le32  build_version;
+       __le32  ram_version;
+       __u8    ref_clock;
+       __u8    reserved[7];
+} __packed;
 
 static const struct usb_device_id ath3k_table[] = {
        /* Atheros AR3011 */
@@ -103,6 +104,7 @@ static const struct usb_device_id ath3k_table[] = {
        { USB_DEVICE(0x13d3, 0x3375) },
        { USB_DEVICE(0x13d3, 0x3393) },
        { USB_DEVICE(0x13d3, 0x3402) },
+       { USB_DEVICE(0x13d3, 0x3432) },
 
        /* Atheros AR5BBU12 with sflash firmware */
        { USB_DEVICE(0x0489, 0xE02C) },
@@ -152,6 +154,7 @@ static const struct usb_device_id ath3k_blist_tbl[] = {
        { USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x13d3, 0x3393), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x13d3, 0x3402), .driver_info = BTUSB_ATH3012 },
+       { USB_DEVICE(0x13d3, 0x3432), .driver_info = BTUSB_ATH3012 },
 
        /* Atheros AR5BBU22 with sflash firmware */
        { USB_DEVICE(0x0489, 0xE036), .driver_info = BTUSB_ATH3012 },
@@ -288,10 +291,10 @@ static int ath3k_load_fwfile(struct usb_device *udev,
        sent += size;
        count -= size;
 
+       pipe = usb_sndbulkpipe(udev, 0x02);
+
        while (count) {
                size = min_t(uint, count, BULK_SIZE);
-               pipe = usb_sndbulkpipe(udev, 0x02);
-
                memcpy(send_buf, firmware->data + sent, size);
 
                err = usb_bulk_msg(udev, pipe, send_buf, size,
@@ -347,7 +350,8 @@ static int ath3k_load_patch(struct usb_device *udev)
        unsigned char fw_state;
        char filename[ATH3K_NAME_LEN] = {0};
        const struct firmware *firmware;
-       struct ath3k_version fw_version, pt_version;
+       struct ath3k_version fw_version;
+       __u32 pt_rom_version, pt_build_version;
        int ret;
 
        ret = ath3k_get_state(udev, &fw_state);
@@ -368,7 +372,7 @@ static int ath3k_load_patch(struct usb_device *udev)
        }
 
        snprintf(filename, ATH3K_NAME_LEN, "ar3k/AthrBT_0x%08x.dfu",
-               le32_to_cpu(fw_version.rom_version));
+                le32_to_cpu(fw_version.rom_version));
 
        ret = request_firmware(&firmware, filename, &udev->dev);
        if (ret < 0) {
@@ -376,12 +380,13 @@ static int ath3k_load_patch(struct usb_device *udev)
                return ret;
        }
 
-       pt_version.rom_version = *(int *)(firmware->data + firmware->size - 8);
-       pt_version.build_version = *(int *)
-               (firmware->data + firmware->size - 4);
+       pt_rom_version = get_unaligned_le32(firmware->data +
+                                           firmware->size - 8);
+       pt_build_version = get_unaligned_le32(firmware->data +
+                                             firmware->size - 4);
 
-       if ((pt_version.rom_version != fw_version.rom_version) ||
-               (pt_version.build_version <= fw_version.build_version)) {
+       if (pt_rom_version != le32_to_cpu(fw_version.rom_version) ||
+           pt_build_version <= le32_to_cpu(fw_version.build_version)) {
                BT_ERR("Patch file version did not match with firmware");
                release_firmware(firmware);
                return -EINVAL;