Merge branch 'for-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetoot...
authorJohn W. Linville <linville@tuxdriver.com>
Mon, 9 Dec 2013 20:31:57 +0000 (15:31 -0500)
committerJohn W. Linville <linville@tuxdriver.com>
Mon, 9 Dec 2013 20:31:57 +0000 (15:31 -0500)
drivers/bluetooth/ath3k.c
drivers/bluetooth/btmrvl_drv.h
drivers/bluetooth/btmrvl_main.c
drivers/bluetooth/btmrvl_sdio.c
drivers/bluetooth/btmrvl_sdio.h
drivers/bluetooth/btusb.c
net/bluetooth/hci_core.c
net/bluetooth/hci_event.c
net/bluetooth/mgmt.c
net/bluetooth/smp.c

index 6bfc1bb318f6399397ca8f169cc07fd98b46256d..d3fdc32b579d72afcee794d9ba68c68b1f4c367d 100644 (file)
@@ -83,6 +83,7 @@ static const struct usb_device_id ath3k_table[] = {
        { USB_DEVICE(0x04CA, 0x3005) },
        { USB_DEVICE(0x04CA, 0x3006) },
        { USB_DEVICE(0x04CA, 0x3008) },
+       { USB_DEVICE(0x04CA, 0x300b) },
        { USB_DEVICE(0x13d3, 0x3362) },
        { USB_DEVICE(0x0CF3, 0xE004) },
        { USB_DEVICE(0x0CF3, 0xE005) },
@@ -96,6 +97,7 @@ static const struct usb_device_id ath3k_table[] = {
        { USB_DEVICE(0x13d3, 0x3402) },
        { USB_DEVICE(0x0cf3, 0x3121) },
        { USB_DEVICE(0x0cf3, 0xe003) },
+       { USB_DEVICE(0x0489, 0xe05f) },
 
        /* Atheros AR5BBU12 with sflash firmware */
        { USB_DEVICE(0x0489, 0xE02C) },
@@ -125,6 +127,7 @@ static const struct usb_device_id ath3k_blist_tbl[] = {
        { USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x04ca, 0x3006), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x04ca, 0x3008), .driver_info = BTUSB_ATH3012 },
+       { USB_DEVICE(0x04ca, 0x300b), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x0cf3, 0xe005), .driver_info = BTUSB_ATH3012 },
@@ -138,6 +141,7 @@ static const struct usb_device_id ath3k_blist_tbl[] = {
        { USB_DEVICE(0x13d3, 0x3402), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x0cf3, 0x3121), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x0cf3, 0xe003), .driver_info = BTUSB_ATH3012 },
+       { USB_DEVICE(0x0489, 0xe05f), .driver_info = BTUSB_ATH3012 },
 
        /* Atheros AR5BBU22 with sflash firmware */
        { USB_DEVICE(0x0489, 0xE03C), .driver_info = BTUSB_ATH3012 },
index f9d183387f4585b37e0642aef9e269e17c6be1a4..7399303d7d9978447ff722d823c1dcece408029a 100644 (file)
@@ -23,8 +23,6 @@
 #include <linux/bitops.h>
 #include <linux/slab.h>
 #include <net/bluetooth/bluetooth.h>
-#include <linux/ctype.h>
-#include <linux/firmware.h>
 
 #define BTM_HEADER_LEN                 4
 #define BTM_UPLD_SIZE                  2312
@@ -43,8 +41,6 @@ struct btmrvl_thread {
 struct btmrvl_device {
        void *card;
        struct hci_dev *hcidev;
-       struct device *dev;
-       const char *cal_data;
 
        u8 dev_type;
 
@@ -90,12 +86,12 @@ struct btmrvl_private {
 
 #define MRVL_VENDOR_PKT                        0xFE
 
-/* Bluetooth commands  */
-#define BT_CMD_AUTO_SLEEP_MODE         0x23
-#define BT_CMD_HOST_SLEEP_CONFIG       0x59
-#define BT_CMD_HOST_SLEEP_ENABLE       0x5A
-#define BT_CMD_MODULE_CFG_REQ          0x5B
-#define BT_CMD_LOAD_CONFIG_DATA                0x61
+/* Vendor specific Bluetooth commands */
+#define BT_CMD_AUTO_SLEEP_MODE         0xFC23
+#define BT_CMD_HOST_SLEEP_CONFIG       0xFC59
+#define BT_CMD_HOST_SLEEP_ENABLE       0xFC5A
+#define BT_CMD_MODULE_CFG_REQ          0xFC5B
+#define BT_CMD_LOAD_CONFIG_DATA                0xFC61
 
 /* Sub-commands: Module Bringup/Shutdown Request/Response */
 #define MODULE_BRINGUP_REQ             0xF1
@@ -104,6 +100,11 @@ struct btmrvl_private {
 
 #define MODULE_SHUTDOWN_REQ            0xF2
 
+/* Vendor specific Bluetooth events */
+#define BT_EVENT_AUTO_SLEEP_MODE       0x23
+#define BT_EVENT_HOST_SLEEP_CONFIG     0x59
+#define BT_EVENT_HOST_SLEEP_ENABLE     0x5A
+#define BT_EVENT_MODULE_CFG_REQ                0x5B
 #define BT_EVENT_POWER_STATE           0x20
 
 /* Bluetooth Power States */
@@ -111,8 +112,6 @@ struct btmrvl_private {
 #define BT_PS_DISABLE                  0x03
 #define BT_PS_SLEEP                    0x01
 
-#define OGF                            0x3F
-
 /* Host Sleep states */
 #define HS_ACTIVATED                   0x01
 #define HS_DEACTIVATED                 0x00
@@ -121,7 +120,7 @@ struct btmrvl_private {
 #define PS_SLEEP                       0x01
 #define PS_AWAKE                       0x00
 
-#define BT_CMD_DATA_SIZE               32
+#define BT_CAL_HDR_LEN                 4
 #define BT_CAL_DATA_SIZE               28
 
 struct btmrvl_event {
index 5cf31c4fe6d1cf552c9846c8fe7a79857851c9b6..1e0320af00c63be9a1fdd808e8c0301dedf7ad0a 100644 (file)
@@ -19,7 +19,7 @@
  **/
 
 #include <linux/module.h>
-
+#include <linux/of.h>
 #include <net/bluetooth/bluetooth.h>
 #include <net/bluetooth/hci_core.h>
 
@@ -50,12 +50,10 @@ bool btmrvl_check_evtpkt(struct btmrvl_private *priv, struct sk_buff *skb)
 
        if (hdr->evt == HCI_EV_CMD_COMPLETE) {
                struct hci_ev_cmd_complete *ec;
-               u16 opcode, ocf, ogf;
+               u16 opcode;
 
                ec = (void *) (skb->data + HCI_EVENT_HDR_SIZE);
                opcode = __le16_to_cpu(ec->opcode);
-               ocf = hci_opcode_ocf(opcode);
-               ogf = hci_opcode_ogf(opcode);
 
                if (priv->btmrvl_dev.sendcmdflag) {
                        priv->btmrvl_dev.sendcmdflag = false;
@@ -63,9 +61,8 @@ bool btmrvl_check_evtpkt(struct btmrvl_private *priv, struct sk_buff *skb)
                        wake_up_interruptible(&priv->adapter->cmd_wait_q);
                }
 
-               if (ogf == OGF) {
-                       BT_DBG("vendor event skipped: ogf 0x%4.4x ocf 0x%4.4x",
-                              ogf, ocf);
+               if (hci_opcode_ogf(opcode) == 0x3F) {
+                       BT_DBG("vendor event skipped: opcode=%#4.4x", opcode);
                        kfree_skb(skb);
                        return false;
                }
@@ -89,7 +86,7 @@ int btmrvl_process_event(struct btmrvl_private *priv, struct sk_buff *skb)
        }
 
        switch (event->data[0]) {
-       case BT_CMD_AUTO_SLEEP_MODE:
+       case BT_EVENT_AUTO_SLEEP_MODE:
                if (!event->data[2]) {
                        if (event->data[1] == BT_PS_ENABLE)
                                adapter->psmode = 1;
@@ -102,7 +99,7 @@ int btmrvl_process_event(struct btmrvl_private *priv, struct sk_buff *skb)
                }
                break;
 
-       case BT_CMD_HOST_SLEEP_CONFIG:
+       case BT_EVENT_HOST_SLEEP_CONFIG:
                if (!event->data[3])
                        BT_DBG("gpio=%x, gap=%x", event->data[1],
                                                        event->data[2]);
@@ -110,7 +107,7 @@ int btmrvl_process_event(struct btmrvl_private *priv, struct sk_buff *skb)
                        BT_DBG("HSCFG command failed");
                break;
 
-       case BT_CMD_HOST_SLEEP_ENABLE:
+       case BT_EVENT_HOST_SLEEP_ENABLE:
                if (!event->data[1]) {
                        adapter->hs_state = HS_ACTIVATED;
                        if (adapter->psmode)
@@ -121,7 +118,7 @@ int btmrvl_process_event(struct btmrvl_private *priv, struct sk_buff *skb)
                }
                break;
 
-       case BT_CMD_MODULE_CFG_REQ:
+       case BT_EVENT_MODULE_CFG_REQ:
                if (priv->btmrvl_dev.sendcmdflag &&
                                event->data[1] == MODULE_BRINGUP_REQ) {
                        BT_DBG("EVENT:%s",
@@ -166,7 +163,7 @@ exit:
 }
 EXPORT_SYMBOL_GPL(btmrvl_process_event);
 
-static int btmrvl_send_sync_cmd(struct btmrvl_private *priv, u16 cmd_no,
+static int btmrvl_send_sync_cmd(struct btmrvl_private *priv, u16 opcode,
                                const void *param, u8 len)
 {
        struct sk_buff *skb;
@@ -179,7 +176,7 @@ static int btmrvl_send_sync_cmd(struct btmrvl_private *priv, u16 cmd_no,
        }
 
        hdr = (struct hci_command_hdr *)skb_put(skb, HCI_COMMAND_HDR_SIZE);
-       hdr->opcode = cpu_to_le16(hci_opcode_pack(OGF, cmd_no));
+       hdr->opcode = cpu_to_le16(opcode);
        hdr->plen = len;
 
        if (len)
@@ -417,127 +414,62 @@ static int btmrvl_open(struct hci_dev *hdev)
        return 0;
 }
 
-/*
- * This function parses provided calibration data input. It should contain
- * hex bytes separated by space or new line character. Here is an example.
- * 00 1C 01 37 FF FF FF FF 02 04 7F 01
- * CE BA 00 00 00 2D C6 C0 00 00 00 00
- * 00 F0 00 00
- */
-static int btmrvl_parse_cal_cfg(const u8 *src, u32 len, u8 *dst, u32 dst_size)
+static int btmrvl_download_cal_data(struct btmrvl_private *priv,
+                                   u8 *data, int len)
 {
-       const u8 *s = src;
-       u8 *d = dst;
        int ret;
-       u8 tmp[3];
-
-       tmp[2] = '\0';
-       while ((s - src) <= len - 2) {
-               if (isspace(*s)) {
-                       s++;
-                       continue;
-               }
-
-               if (isxdigit(*s)) {
-                       if ((d - dst) >= dst_size) {
-                               BT_ERR("calibration data file too big!!!");
-                               return -EINVAL;
-                       }
-
-                       memcpy(tmp, s, 2);
-
-                       ret = kstrtou8(tmp, 16, d++);
-                       if (ret < 0)
-                               return ret;
-
-                       s += 2;
-               } else {
-                       return -EINVAL;
-               }
-       }
-       if (d == dst)
-               return -EINVAL;
-
-       return 0;
-}
-
-static int btmrvl_load_cal_data(struct btmrvl_private *priv,
-                               u8 *config_data)
-{
-       int i, ret;
-       u8 data[BT_CMD_DATA_SIZE];
 
        data[0] = 0x00;
        data[1] = 0x00;
        data[2] = 0x00;
-       data[3] = BT_CMD_DATA_SIZE - 4;
-
-       /* Swap cal-data bytes. Each four bytes are swapped. Considering 4
-        * byte SDIO header offset, mapping of input and output bytes will be
-        * {3, 2, 1, 0} -> {0+4, 1+4, 2+4, 3+4},
-        * {7, 6, 5, 4} -> {4+4, 5+4, 6+4, 7+4} */
-       for (i = 4; i < BT_CMD_DATA_SIZE; i++)
-               data[i] = config_data[(i / 4) * 8 - 1 - i];
+       data[3] = len;
 
        print_hex_dump_bytes("Calibration data: ",
-                            DUMP_PREFIX_OFFSET, data, BT_CMD_DATA_SIZE);
+                            DUMP_PREFIX_OFFSET, data, BT_CAL_HDR_LEN + len);
 
        ret = btmrvl_send_sync_cmd(priv, BT_CMD_LOAD_CONFIG_DATA, data,
-                                  BT_CMD_DATA_SIZE);
+                                  BT_CAL_HDR_LEN + len);
        if (ret)
                BT_ERR("Failed to download caibration data\n");
 
        return 0;
 }
 
-static int
-btmrvl_process_cal_cfg(struct btmrvl_private *priv, u8 *data, u32 size)
+static int btmrvl_cal_data_dt(struct btmrvl_private *priv)
 {
-       u8 cal_data[BT_CAL_DATA_SIZE];
+       struct device_node *dt_node;
+       u8 cal_data[BT_CAL_HDR_LEN + BT_CAL_DATA_SIZE];
+       const char name[] = "btmrvl_caldata";
+       const char property[] = "btmrvl,caldata";
        int ret;
 
-       ret = btmrvl_parse_cal_cfg(data, size, cal_data, sizeof(cal_data));
+       dt_node = of_find_node_by_name(NULL, name);
+       if (!dt_node)
+               return -ENODEV;
+
+       ret = of_property_read_u8_array(dt_node, property,
+                                       cal_data + BT_CAL_HDR_LEN,
+                                       BT_CAL_DATA_SIZE);
        if (ret)
                return ret;
 
-       ret = btmrvl_load_cal_data(priv, cal_data);
+       BT_DBG("Use cal data from device tree");
+       ret = btmrvl_download_cal_data(priv, cal_data, BT_CAL_DATA_SIZE);
        if (ret) {
-               BT_ERR("Fail to load calibrate data");
+               BT_ERR("Fail to download calibrate data");
                return ret;
        }
 
        return 0;
 }
 
-static int btmrvl_cal_data_config(struct btmrvl_private *priv)
-{
-       const struct firmware *cfg;
-       int ret;
-       const char *cal_data = priv->btmrvl_dev.cal_data;
-
-       if (!cal_data)
-               return 0;
-
-       ret = request_firmware(&cfg, cal_data, priv->btmrvl_dev.dev);
-       if (ret < 0) {
-               BT_DBG("Failed to get %s file, skipping cal data download",
-                      cal_data);
-               return 0;
-       }
-
-       ret = btmrvl_process_cal_cfg(priv, (u8 *)cfg->data, cfg->size);
-       release_firmware(cfg);
-       return ret;
-}
-
 static int btmrvl_setup(struct hci_dev *hdev)
 {
        struct btmrvl_private *priv = hci_get_drvdata(hdev);
 
        btmrvl_send_module_cfg_cmd(priv, MODULE_BRINGUP_REQ);
 
-       if (btmrvl_cal_data_config(priv))
-               BT_ERR("Set cal data failed");
+       btmrvl_cal_data_dt(priv);
 
        priv->btmrvl_dev.psmode = 1;
        btmrvl_enable_ps(priv);
index fabcf5bb48afbb1c62cf5145d5a12f60eb3a05a8..1b52c9f5230d324d0476a2d7dd3f308e7fd723d8 100644 (file)
@@ -18,6 +18,7 @@
  * this warranty disclaimer.
  **/
 
+#include <linux/firmware.h>
 #include <linux/slab.h>
 
 #include <linux/mmc/sdio_ids.h>
@@ -101,7 +102,6 @@ static const struct btmrvl_sdio_card_reg btmrvl_reg_88xx = {
 static const struct btmrvl_sdio_device btmrvl_sdio_sd8688 = {
        .helper         = "mrvl/sd8688_helper.bin",
        .firmware       = "mrvl/sd8688.bin",
-       .cal_data       = NULL,
        .reg            = &btmrvl_reg_8688,
        .sd_blksz_fw_dl = 64,
 };
@@ -109,7 +109,6 @@ static const struct btmrvl_sdio_device btmrvl_sdio_sd8688 = {
 static const struct btmrvl_sdio_device btmrvl_sdio_sd8787 = {
        .helper         = NULL,
        .firmware       = "mrvl/sd8787_uapsta.bin",
-       .cal_data       = NULL,
        .reg            = &btmrvl_reg_87xx,
        .sd_blksz_fw_dl = 256,
 };
@@ -117,7 +116,6 @@ static const struct btmrvl_sdio_device btmrvl_sdio_sd8787 = {
 static const struct btmrvl_sdio_device btmrvl_sdio_sd8797 = {
        .helper         = NULL,
        .firmware       = "mrvl/sd8797_uapsta.bin",
-       .cal_data       = "mrvl/sd8797_caldata.conf",
        .reg            = &btmrvl_reg_87xx,
        .sd_blksz_fw_dl = 256,
 };
@@ -125,7 +123,6 @@ static const struct btmrvl_sdio_device btmrvl_sdio_sd8797 = {
 static const struct btmrvl_sdio_device btmrvl_sdio_sd8897 = {
        .helper         = NULL,
        .firmware       = "mrvl/sd8897_uapsta.bin",
-       .cal_data       = NULL,
        .reg            = &btmrvl_reg_88xx,
        .sd_blksz_fw_dl = 256,
 };
@@ -1007,7 +1004,6 @@ static int btmrvl_sdio_probe(struct sdio_func *func,
                struct btmrvl_sdio_device *data = (void *) id->driver_data;
                card->helper = data->helper;
                card->firmware = data->firmware;
-               card->cal_data = data->cal_data;
                card->reg = data->reg;
                card->sd_blksz_fw_dl = data->sd_blksz_fw_dl;
        }
@@ -1036,8 +1032,6 @@ static int btmrvl_sdio_probe(struct sdio_func *func,
        }
 
        card->priv = priv;
-       priv->btmrvl_dev.dev = &card->func->dev;
-       priv->btmrvl_dev.cal_data = card->cal_data;
 
        /* Initialize the interface specific function pointers */
        priv->hw_host_to_card = btmrvl_sdio_host_to_card;
@@ -1220,5 +1214,4 @@ MODULE_FIRMWARE("mrvl/sd8688_helper.bin");
 MODULE_FIRMWARE("mrvl/sd8688.bin");
 MODULE_FIRMWARE("mrvl/sd8787_uapsta.bin");
 MODULE_FIRMWARE("mrvl/sd8797_uapsta.bin");
-MODULE_FIRMWARE("mrvl/sd8797_caldata.conf");
 MODULE_FIRMWARE("mrvl/sd8897_uapsta.bin");
index 6872d9ecac074ba04792c22776b3baee3971c9de..43d35a609ca9a94795afb731d230fa88ca109bef 100644 (file)
@@ -85,7 +85,6 @@ struct btmrvl_sdio_card {
        u32 ioport;
        const char *helper;
        const char *firmware;
-       const char *cal_data;
        const struct btmrvl_sdio_card_reg *reg;
        u16 sd_blksz_fw_dl;
        u8 rx_unit;
@@ -95,7 +94,6 @@ struct btmrvl_sdio_card {
 struct btmrvl_sdio_device {
        const char *helper;
        const char *firmware;
-       const char *cal_data;
        const struct btmrvl_sdio_card_reg *reg;
        u16 sd_blksz_fw_dl;
 };
index c0ff34f2d2df577efffe902562f9578690ea4e39..bfbcc5a772a61ecb1619d6bbb988eb22bb9f0fef 100644 (file)
@@ -150,6 +150,7 @@ static const struct usb_device_id blacklist_table[] = {
        { USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x04ca, 0x3006), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x04ca, 0x3008), .driver_info = BTUSB_ATH3012 },
+       { USB_DEVICE(0x04ca, 0x300b), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x0cf3, 0xe005), .driver_info = BTUSB_ATH3012 },
@@ -163,6 +164,7 @@ static const struct usb_device_id blacklist_table[] = {
        { USB_DEVICE(0x13d3, 0x3402), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x0cf3, 0x3121), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x0cf3, 0xe003), .driver_info = BTUSB_ATH3012 },
+       { USB_DEVICE(0x0489, 0xe05f), .driver_info = BTUSB_ATH3012 },
 
        /* Atheros AR5BBU12 with sflash firmware */
        { USB_DEVICE(0x0489, 0xe02c), .driver_info = BTUSB_IGNORE },
@@ -223,6 +225,7 @@ static const struct usb_device_id blacklist_table[] = {
 
        /* Intel Bluetooth device */
        { USB_DEVICE(0x8087, 0x07dc), .driver_info = BTUSB_INTEL },
+       { USB_DEVICE(0x8087, 0x0a2a), .driver_info = BTUSB_INTEL },
 
        { }     /* Terminating entry */
 };
@@ -1435,8 +1438,10 @@ static int btusb_probe(struct usb_interface *intf,
        if (id->driver_info & BTUSB_BCM92035)
                hdev->setup = btusb_setup_bcm92035;
 
-       if (id->driver_info & BTUSB_INTEL)
+       if (id->driver_info & BTUSB_INTEL) {
+               usb_enable_autosuspend(data->udev);
                hdev->setup = btusb_setup_intel;
+       }
 
        /* Interface numbers are hardcoded in the specification */
        data->isoc = usb_ifnum_to_if(data->udev, 1);
index 6ccc4eb9e55e4958f3eb070894a7668b05c98b5b..03e83558a41100b8caed44da2f9f3a9ef35d32d2 100644 (file)
@@ -1275,15 +1275,17 @@ static void hci_init3_req(struct hci_request *req, unsigned long opt)
                hci_setup_link_policy(req);
 
        if (lmp_le_capable(hdev)) {
-               /* If the controller has a public BD_ADDR, then by
-                * default use that one. If this is a LE only
-                * controller without one, default to the random
-                * address.
-                */
-               if (bacmp(&hdev->bdaddr, BDADDR_ANY))
-                       hdev->own_addr_type = ADDR_LE_DEV_PUBLIC;
-               else
-                       hdev->own_addr_type = ADDR_LE_DEV_RANDOM;
+               if (test_bit(HCI_SETUP, &hdev->dev_flags)) {
+                       /* If the controller has a public BD_ADDR, then
+                        * by default use that one. If this is a LE only
+                        * controller without a public address, default
+                        * to the random address.
+                        */
+                       if (bacmp(&hdev->bdaddr, BDADDR_ANY))
+                               hdev->own_addr_type = ADDR_LE_DEV_PUBLIC;
+                       else
+                               hdev->own_addr_type = ADDR_LE_DEV_RANDOM;
+               }
 
                hci_set_le_support(req);
        }
index 5935f748c0f9a6fe71cb3c0fe8baeaedb7019c37..5fb3df66c2cd5bda5b0ba7fa6cfda11565dbcde3 100644 (file)
@@ -486,7 +486,10 @@ static void hci_cc_read_local_commands(struct hci_dev *hdev,
 
        BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
 
-       if (!rp->status)
+       if (rp->status)
+               return;
+
+       if (test_bit(HCI_SETUP, &hdev->dev_flags))
                memcpy(hdev->commands, rp->commands, sizeof(hdev->commands));
 }
 
@@ -538,12 +541,6 @@ static void hci_cc_read_local_features(struct hci_dev *hdev,
 
        if (hdev->features[0][5] & LMP_EDR_3S_ESCO)
                hdev->esco_type |= (ESCO_2EV5 | ESCO_3EV5);
-
-       BT_DBG("%s features 0x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x", hdev->name,
-              hdev->features[0][0], hdev->features[0][1],
-              hdev->features[0][2], hdev->features[0][3],
-              hdev->features[0][4], hdev->features[0][5],
-              hdev->features[0][6], hdev->features[0][7]);
 }
 
 static void hci_cc_read_local_ext_features(struct hci_dev *hdev,
@@ -1782,7 +1779,9 @@ static u8 hci_to_mgmt_reason(u8 err)
 static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
 {
        struct hci_ev_disconn_complete *ev = (void *) skb->data;
+       u8 reason = hci_to_mgmt_reason(ev->reason);
        struct hci_conn *conn;
+       u8 type;
 
        BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
 
@@ -1792,43 +1791,38 @@ static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
        if (!conn)
                goto unlock;
 
-       if (ev->status == 0)
-               conn->state = BT_CLOSED;
+       if (ev->status) {
+               mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
+                                      conn->dst_type, ev->status);
+               goto unlock;
+       }
 
-       if (test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags) &&
-           (conn->type == ACL_LINK || conn->type == LE_LINK)) {
-               if (ev->status) {
-                       mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
-                                              conn->dst_type, ev->status);
-               } else {
-                       u8 reason = hci_to_mgmt_reason(ev->reason);
+       conn->state = BT_CLOSED;
 
-                       mgmt_device_disconnected(hdev, &conn->dst, conn->type,
-                                                conn->dst_type, reason);
-               }
-       }
+       if (test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
+               mgmt_device_disconnected(hdev, &conn->dst, conn->type,
+                                        conn->dst_type, reason);
 
-       if (ev->status == 0) {
-               u8 type = conn->type;
+       if (conn->type == ACL_LINK && conn->flush_key)
+               hci_remove_link_key(hdev, &conn->dst);
 
-               if (type == ACL_LINK && conn->flush_key)
-                       hci_remove_link_key(hdev, &conn->dst);
-               hci_proto_disconn_cfm(conn, ev->reason);
-               hci_conn_del(conn);
+       type = conn->type;
 
-               /* Re-enable advertising if necessary, since it might
-                * have been disabled by the connection. From the
-                * HCI_LE_Set_Advertise_Enable command description in
-                * the core specification (v4.0):
-                * "The Controller shall continue advertising until the Host
-                * issues an LE_Set_Advertise_Enable command with
-                * Advertising_Enable set to 0x00 (Advertising is disabled)
-                * or until a connection is created or until the Advertising
-                * is timed out due to Directed Advertising."
-                */
-               if (type == LE_LINK)
-                       mgmt_reenable_advertising(hdev);
-       }
+       hci_proto_disconn_cfm(conn, ev->reason);
+       hci_conn_del(conn);
+
+       /* Re-enable advertising if necessary, since it might
+        * have been disabled by the connection. From the
+        * HCI_LE_Set_Advertise_Enable command description in
+        * the core specification (v4.0):
+        * "The Controller shall continue advertising until the Host
+        * issues an LE_Set_Advertise_Enable command with
+        * Advertising_Enable set to 0x00 (Advertising is disabled)
+        * or until a connection is created or until the Advertising
+        * is timed out due to Directed Advertising."
+        */
+       if (type == LE_LINK)
+               mgmt_reenable_advertising(hdev);
 
 unlock:
        hci_dev_unlock(hdev);
index 074d83690a414c8e668499d7f7e7c86215c563ea..a03ca3ca91bfa77e2663a09f90ce2271addb2331 100644 (file)
@@ -1264,7 +1264,7 @@ static int set_discoverable(struct sock *sk, struct hci_dev *hdev, void *data,
 
                if (cp->val == 0x02) {
                        /* Limited discoverable mode */
-                       hci_cp.num_iac = 2;
+                       hci_cp.num_iac = min_t(u8, hdev->num_iac, 2);
                        hci_cp.iac_lap[0] = 0x00;       /* LIAC */
                        hci_cp.iac_lap[1] = 0x8b;
                        hci_cp.iac_lap[2] = 0x9e;
@@ -4595,6 +4595,9 @@ void mgmt_device_disconnected(struct hci_dev *hdev, bdaddr_t *bdaddr,
        struct mgmt_ev_device_disconnected ev;
        struct sock *sk = NULL;
 
+       if (link_type != ACL_LINK && link_type != LE_LINK)
+               return;
+
        mgmt_pending_foreach(MGMT_OP_DISCONNECT, hdev, disconnect_rsp, &sk);
 
        bacpy(&ev.addr.bdaddr, bdaddr);
@@ -4613,6 +4616,8 @@ void mgmt_device_disconnected(struct hci_dev *hdev, bdaddr_t *bdaddr,
 void mgmt_disconnect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr,
                            u8 link_type, u8 addr_type, u8 status)
 {
+       u8 bdaddr_type = link_to_bdaddr(link_type, addr_type);
+       struct mgmt_cp_disconnect *cp;
        struct mgmt_rp_disconnect rp;
        struct pending_cmd *cmd;
 
@@ -4623,8 +4628,16 @@ void mgmt_disconnect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr,
        if (!cmd)
                return;
 
+       cp = cmd->param;
+
+       if (bacmp(bdaddr, &cp->addr.bdaddr))
+               return;
+
+       if (cp->addr.type != bdaddr_type)
+               return;
+
        bacpy(&rp.addr.bdaddr, bdaddr);
-       rp.addr.type = link_to_bdaddr(link_type, addr_type);
+       rp.addr.type = bdaddr_type;
 
        cmd_complete(cmd->sk, cmd->index, MGMT_OP_DISCONNECT,
                     mgmt_status(status), &rp, sizeof(rp));
index 4b07acb8293c3df3542e2a1661a6ae07bcfa6596..e61e74a1aabb76c57cbe5e4a88530259cb40dc03 100644 (file)
@@ -53,8 +53,7 @@ static int smp_e(struct crypto_blkcipher *tfm, const u8 *k, u8 *r)
 {
        struct blkcipher_desc desc;
        struct scatterlist sg;
-       int err, iv_len;
-       unsigned char iv[128];
+       int err;
 
        if (tfm == NULL) {
                BT_ERR("tfm %p", tfm);
@@ -72,12 +71,6 @@ static int smp_e(struct crypto_blkcipher *tfm, const u8 *k, u8 *r)
 
        sg_init_one(&sg, r, 16);
 
-       iv_len = crypto_blkcipher_ivsize(tfm);
-       if (iv_len) {
-               memset(&iv, 0xff, iv_len);
-               crypto_blkcipher_set_iv(tfm, iv, iv_len);
-       }
-
        err = crypto_blkcipher_encrypt(&desc, &sg, &sg, 16);
        if (err)
                BT_ERR("Encrypt data error %d", err);
@@ -143,13 +136,6 @@ static int smp_s1(struct crypto_blkcipher *tfm, u8 k[16], u8 r1[16],
        return err;
 }
 
-static int smp_rand(u8 *buf)
-{
-       get_random_bytes(buf, 16);
-
-       return 0;
-}
-
 static struct sk_buff *smp_build_cmd(struct l2cap_conn *conn, u8 code,
                                     u16 dlen, void *data)
 {
@@ -257,11 +243,11 @@ static u8 check_enc_key_size(struct l2cap_conn *conn, __u8 max_key_size)
        return 0;
 }
 
-static void smp_failure(struct l2cap_conn *conn, u8 reason, u8 send)
+static void smp_failure(struct l2cap_conn *conn, u8 reason)
 {
        struct hci_conn *hcon = conn->hcon;
 
-       if (send)
+       if (reason)
                smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, sizeof(reason),
                             &reason);
 
@@ -406,7 +392,7 @@ static void confirm_work(struct work_struct *work)
        return;
 
 error:
-       smp_failure(conn, reason, 1);
+       smp_failure(conn, reason);
 }
 
 static void random_work(struct work_struct *work)
@@ -490,7 +476,7 @@ static void random_work(struct work_struct *work)
        return;
 
 error:
-       smp_failure(conn, reason, 1);
+       smp_failure(conn, reason);
 }
 
 static struct smp_chan *smp_chan_create(struct l2cap_conn *conn)
@@ -555,10 +541,10 @@ int smp_user_confirm_reply(struct hci_conn *hcon, u16 mgmt_op, __le32 passkey)
                break;
        case MGMT_OP_USER_PASSKEY_NEG_REPLY:
        case MGMT_OP_USER_CONFIRM_NEG_REPLY:
-               smp_failure(conn, SMP_PASSKEY_ENTRY_FAILED, 1);
+               smp_failure(conn, SMP_PASSKEY_ENTRY_FAILED);
                return 0;
        default:
-               smp_failure(conn, SMP_PASSKEY_ENTRY_FAILED, 1);
+               smp_failure(conn, SMP_PASSKEY_ENTRY_FAILED);
                return -EOPNOTSUPP;
        }
 
@@ -606,9 +592,7 @@ static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
        if (check_enc_key_size(conn, key_size))
                return SMP_ENC_KEY_SIZE;
 
-       ret = smp_rand(smp->prnd);
-       if (ret)
-               return SMP_UNSPECIFIED;
+       get_random_bytes(smp->prnd, sizeof(smp->prnd));
 
        smp->prsp[0] = SMP_CMD_PAIRING_RSP;
        memcpy(&smp->prsp[1], &rsp, sizeof(rsp));
@@ -644,9 +628,7 @@ static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb)
        if (check_enc_key_size(conn, key_size))
                return SMP_ENC_KEY_SIZE;
 
-       ret = smp_rand(smp->prnd);
-       if (ret)
-               return SMP_UNSPECIFIED;
+       get_random_bytes(smp->prnd, sizeof(smp->prnd));
 
        smp->prsp[0] = SMP_CMD_PAIRING_RSP;
        memcpy(&smp->prsp[1], rsp, sizeof(*rsp));
@@ -895,7 +877,7 @@ int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
                break;
 
        case SMP_CMD_PAIRING_FAIL:
-               smp_failure(conn, skb->data[0], 0);
+               smp_failure(conn, 0);
                reason = 0;
                err = -EPERM;
                break;
@@ -941,7 +923,7 @@ int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
 
 done:
        if (reason)
-               smp_failure(conn, reason, 1);
+               smp_failure(conn, reason);
 
        kfree_skb(skb);
        return err;