Merge branch 'for-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetoot...
authorDavid S. Miller <davem@davemloft.net>
Mon, 25 Feb 2019 06:27:19 +0000 (22:27 -0800)
committerDavid S. Miller <davem@davemloft.net>
Mon, 25 Feb 2019 06:27:19 +0000 (22:27 -0800)
Johan Hedberg says:

====================
Here's the main bluetooth-next pull request for the 5.1 kernel.

 - Fixes & improvements to mediatek, hci_qca, btrtl, and btmrvl HCI drivers
 - Fixes to parsing invalid L2CAP config option sizes
 - Locking fix to bt_accept_enqueue()
 - Add support for new Marvel sd8977 chipset
 - Various other smaller fixes & cleanups
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
27 files changed:
drivers/bluetooth/Kconfig
drivers/bluetooth/btmrvl_drv.h
drivers/bluetooth/btmrvl_sdio.c
drivers/bluetooth/btmtkuart.c
drivers/bluetooth/btqca.c
drivers/bluetooth/btqca.h
drivers/bluetooth/btrtl.c
drivers/bluetooth/btusb.c
drivers/bluetooth/h4_recv.h
drivers/bluetooth/hci_h4.c
drivers/bluetooth/hci_ldisc.c
drivers/bluetooth/hci_qca.c
drivers/usb/core/usb-acpi.c
include/net/bluetooth/bluetooth.h
include/net/bluetooth/hci_core.h
net/6lowpan/debugfs.c
net/bluetooth/6lowpan.c
net/bluetooth/a2mp.c
net/bluetooth/af_bluetooth.c
net/bluetooth/hci_core.c
net/bluetooth/hci_event.c
net/bluetooth/hci_sock.c
net/bluetooth/l2cap_core.c
net/bluetooth/l2cap_sock.c
net/bluetooth/rfcomm/core.c
net/bluetooth/rfcomm/sock.c
net/bluetooth/sco.c

index 845b0314ce3a7f599360d6c7e3d73c14a5fc2bbb..7b2e76e7f22fb50799aca97eb034e8e12dae4365 100644 (file)
@@ -336,7 +336,7 @@ config BT_MRVL
          The core driver to support Marvell Bluetooth devices.
 
          This driver is required if you want to support
-         Marvell Bluetooth devices, such as 8688/8787/8797/8887/8897/8997.
+         Marvell Bluetooth devices, such as 8688/8787/8797/8887/8897/8977/8997.
 
          Say Y here to compile Marvell Bluetooth driver
          into the kernel or say M to compile it as module.
@@ -350,7 +350,7 @@ config BT_MRVL_SDIO
          The driver for Marvell Bluetooth chipsets with SDIO interface.
 
          This driver is required if you want to use Marvell Bluetooth
-         devices with SDIO interface. Currently SD8688/SD8787/SD8797/SD8887/SD8897/SD8997
+         devices with SDIO interface. Currently SD8688/SD8787/SD8797/SD8887/SD8897/SD8977/SD8997
          chipsets are supported.
 
          Say Y here to compile support for Marvell BT-over-SDIO driver
index f0454541e5fded11b4a27aee9a8e49f3ece55333..fb77297791661bd533efb46e8a0284cde12b66b0 100644 (file)
 #include <linux/slab.h>
 #include <net/bluetooth/bluetooth.h>
 #include <linux/err.h>
-#include <linux/gpio.h>
 #include <linux/gfp.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
-#include <linux/of_gpio.h>
 #include <linux/of_platform.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
index fb3d03928460281b751b0634ee022e42b163230b..047b75ce1deb76b31d6d52a78028967f954a1a9d 100644 (file)
@@ -62,13 +62,14 @@ static const struct of_device_id btmrvl_sdio_of_match_table[] = {
 static irqreturn_t btmrvl_wake_irq_bt(int irq, void *priv)
 {
        struct btmrvl_sdio_card *card = priv;
+       struct device *dev = &card->func->dev;
        struct btmrvl_plt_wake_cfg *cfg = card->plt_wake_cfg;
 
-       pr_info("%s: wake by bt\n", __func__);
+       dev_info(dev, "wake by bt\n");
        cfg->wake_by_bt = true;
        disable_irq_nosync(irq);
 
-       pm_wakeup_event(&card->func->dev, 0);
+       pm_wakeup_event(dev, 0);
        pm_system_wakeup();
 
        return IRQ_HANDLED;
@@ -87,7 +88,7 @@ static int btmrvl_sdio_probe_of(struct device *dev,
 
        if (!dev->of_node ||
            !of_match_node(btmrvl_sdio_of_match_table, dev->of_node)) {
-               pr_err("sdio platform data not available\n");
+               dev_info(dev, "sdio device tree data not available\n");
                return -1;
        }
 
@@ -211,6 +212,29 @@ static const struct btmrvl_sdio_card_reg btmrvl_reg_8897 = {
        .fw_dump_end = 0xea,
 };
 
+static const struct btmrvl_sdio_card_reg btmrvl_reg_8977 = {
+       .cfg = 0x00,
+       .host_int_mask = 0x08,
+       .host_intstatus = 0x0c,
+       .card_status = 0x5c,
+       .sq_read_base_addr_a0 = 0xf8,
+       .sq_read_base_addr_a1 = 0xf9,
+       .card_revision = 0xc8,
+       .card_fw_status0 = 0xe8,
+       .card_fw_status1 = 0xe9,
+       .card_rx_len = 0xea,
+       .card_rx_unit = 0xeb,
+       .io_port_0 = 0xe4,
+       .io_port_1 = 0xe5,
+       .io_port_2 = 0xe6,
+       .int_read_to_clear = true,
+       .host_int_rsr = 0x04,
+       .card_misc_cfg = 0xD8,
+       .fw_dump_ctrl = 0xf0,
+       .fw_dump_start = 0xf1,
+       .fw_dump_end = 0xf8,
+};
+
 static const struct btmrvl_sdio_card_reg btmrvl_reg_8997 = {
        .cfg = 0x00,
        .host_int_mask = 0x08,
@@ -279,6 +303,15 @@ static const struct btmrvl_sdio_device btmrvl_sdio_sd8897 = {
        .supports_fw_dump = true,
 };
 
+static const struct btmrvl_sdio_device btmrvl_sdio_sd8977 = {
+       .helper         = NULL,
+       .firmware       = "mrvl/sd8977_uapsta.bin",
+       .reg            = &btmrvl_reg_8977,
+       .support_pscan_win_report = true,
+       .sd_blksz_fw_dl = 256,
+       .supports_fw_dump = true,
+};
+
 static const struct btmrvl_sdio_device btmrvl_sdio_sd8997 = {
        .helper         = NULL,
        .firmware       = "mrvl/sd8997_uapsta.bin",
@@ -307,6 +340,9 @@ static const struct sdio_device_id btmrvl_sdio_ids[] = {
        /* Marvell SD8897 Bluetooth device */
        { SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, 0x912E),
                        .driver_data = (unsigned long)&btmrvl_sdio_sd8897 },
+       /* Marvell SD8977 Bluetooth device */
+       { SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, 0x9146),
+                       .driver_data = (unsigned long)&btmrvl_sdio_sd8977 },
        /* Marvell SD8997 Bluetooth device */
        { SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, 0x9142),
                        .driver_data = (unsigned long)&btmrvl_sdio_sd8997 },
@@ -1760,4 +1796,5 @@ MODULE_FIRMWARE("mrvl/sd8787_uapsta.bin");
 MODULE_FIRMWARE("mrvl/sd8797_uapsta.bin");
 MODULE_FIRMWARE("mrvl/sd8887_uapsta.bin");
 MODULE_FIRMWARE("mrvl/sd8897_uapsta.bin");
+MODULE_FIRMWARE("mrvl/sd8977_uapsta.bin");
 MODULE_FIRMWARE("mrvl/sd8997_uapsta.bin");
index 4593baff2bc944f5a003bb666520062f768f52e5..e73b1013ba73403c260915554644d1c2d344899a 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/atomic.h>
 #include <linux/clk.h>
 #include <linux/firmware.h>
+#include <linux/iopoll.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/of.h>
 enum {
        MTK_WMT_PATCH_DWNLD = 0x1,
        MTK_WMT_FUNC_CTRL = 0x6,
-       MTK_WMT_RST = 0x7
+       MTK_WMT_RST = 0x7,
+       MTK_WMT_SEMAPHORE = 0x17,
+};
+
+enum {
+       BTMTK_WMT_INVALID,
+       BTMTK_WMT_PATCH_UNDONE,
+       BTMTK_WMT_PATCH_DONE,
+       BTMTK_WMT_ON_UNDONE,
+       BTMTK_WMT_ON_DONE,
+       BTMTK_WMT_ON_PROGRESS,
 };
 
 struct mtk_stp_hdr {
@@ -58,6 +69,32 @@ struct mtk_hci_wmt_cmd {
        u8 data[256];
 } __packed;
 
+struct btmtk_hci_wmt_evt {
+       struct hci_event_hdr hhdr;
+       struct mtk_wmt_hdr whdr;
+} __packed;
+
+struct btmtk_hci_wmt_evt_funcc {
+       struct btmtk_hci_wmt_evt hwhdr;
+       __be16 status;
+} __packed;
+
+struct btmtk_tci_sleep {
+       u8 mode;
+       __le16 duration;
+       __le16 host_duration;
+       u8 host_wakeup_pin;
+       u8 time_compensation;
+} __packed;
+
+struct btmtk_hci_wmt_params {
+       u8 op;
+       u8 flag;
+       u16 dlen;
+       const void *data;
+       u32 *status;
+};
+
 struct btmtkuart_dev {
        struct hci_dev *hdev;
        struct serdev_device *serdev;
@@ -68,31 +105,34 @@ struct btmtkuart_dev {
        struct sk_buff_head txq;
 
        struct sk_buff *rx_skb;
+       struct sk_buff *evt_skb;
 
        u8      stp_pad[6];
        u8      stp_cursor;
        u16     stp_dlen;
 };
 
-static int mtk_hci_wmt_sync(struct hci_dev *hdev, u8 op, u8 flag, u16 plen,
-                           const void *param)
+static int mtk_hci_wmt_sync(struct hci_dev *hdev,
+                           struct btmtk_hci_wmt_params *wmt_params)
 {
        struct btmtkuart_dev *bdev = hci_get_drvdata(hdev);
+       struct btmtk_hci_wmt_evt_funcc *wmt_evt_funcc;
+       u32 hlen, status = BTMTK_WMT_INVALID;
+       struct btmtk_hci_wmt_evt *wmt_evt;
        struct mtk_hci_wmt_cmd wc;
        struct mtk_wmt_hdr *hdr;
-       u32 hlen;
        int err;
 
-       hlen = sizeof(*hdr) + plen;
+       hlen = sizeof(*hdr) + wmt_params->dlen;
        if (hlen > 255)
                return -EINVAL;
 
        hdr = (struct mtk_wmt_hdr *)&wc;
        hdr->dir = 1;
-       hdr->op = op;
-       hdr->dlen = cpu_to_le16(plen + 1);
-       hdr->flag = flag;
-       memcpy(wc.data, param, plen);
+       hdr->op = wmt_params->op;
+       hdr->dlen = cpu_to_le16(wmt_params->dlen + 1);
+       hdr->flag = wmt_params->flag;
+       memcpy(wc.data, wmt_params->data, wmt_params->dlen);
 
        set_bit(BTMTKUART_TX_WAIT_VND_EVT, &bdev->tx_state);
 
@@ -107,7 +147,7 @@ static int mtk_hci_wmt_sync(struct hci_dev *hdev, u8 op, u8 flag, u16 plen,
         * Complete as with usual HCI command flow control.
         *
         * After sending the command, wait for BTMTKUART_TX_WAIT_VND_EVT
-        * state to be cleared. The driver speicfic event receive routine
+        * state to be cleared. The driver specific event receive routine
         * will clear that state and with that indicate completion of the
         * WMT command.
         */
@@ -115,19 +155,56 @@ static int mtk_hci_wmt_sync(struct hci_dev *hdev, u8 op, u8 flag, u16 plen,
                                  TASK_INTERRUPTIBLE, HCI_INIT_TIMEOUT);
        if (err == -EINTR) {
                bt_dev_err(hdev, "Execution of wmt command interrupted");
+               clear_bit(BTMTKUART_TX_WAIT_VND_EVT, &bdev->tx_state);
                return err;
        }
 
        if (err) {
                bt_dev_err(hdev, "Execution of wmt command timed out");
+               clear_bit(BTMTKUART_TX_WAIT_VND_EVT, &bdev->tx_state);
                return -ETIMEDOUT;
        }
 
-       return 0;
+       /* Parse and handle the return WMT event */
+       wmt_evt = (struct btmtk_hci_wmt_evt *)bdev->evt_skb->data;
+       if (wmt_evt->whdr.op != hdr->op) {
+               bt_dev_err(hdev, "Wrong op received %d expected %d",
+                          wmt_evt->whdr.op, hdr->op);
+               err = -EIO;
+               goto err_free_skb;
+       }
+
+       switch (wmt_evt->whdr.op) {
+       case MTK_WMT_SEMAPHORE:
+               if (wmt_evt->whdr.flag == 2)
+                       status = BTMTK_WMT_PATCH_UNDONE;
+               else
+                       status = BTMTK_WMT_PATCH_DONE;
+               break;
+       case MTK_WMT_FUNC_CTRL:
+               wmt_evt_funcc = (struct btmtk_hci_wmt_evt_funcc *)wmt_evt;
+               if (be16_to_cpu(wmt_evt_funcc->status) == 0x404)
+                       status = BTMTK_WMT_ON_DONE;
+               else if (be16_to_cpu(wmt_evt_funcc->status) == 0x420)
+                       status = BTMTK_WMT_ON_PROGRESS;
+               else
+                       status = BTMTK_WMT_ON_UNDONE;
+               break;
+       }
+
+       if (wmt_params->status)
+               *wmt_params->status = status;
+
+err_free_skb:
+       kfree_skb(bdev->evt_skb);
+       bdev->evt_skb = NULL;
+
+       return err;
 }
 
 static int mtk_setup_fw(struct hci_dev *hdev)
 {
+       struct btmtk_hci_wmt_params wmt_params;
        const struct firmware *fw;
        const u8 *fw_ptr;
        size_t fw_size;
@@ -153,6 +230,9 @@ static int mtk_setup_fw(struct hci_dev *hdev)
        fw_ptr += 30;
        flag = 1;
 
+       wmt_params.op = MTK_WMT_PATCH_DWNLD;
+       wmt_params.status = NULL;
+
        while (fw_size > 0) {
                dlen = min_t(int, 250, fw_size);
 
@@ -162,18 +242,37 @@ static int mtk_setup_fw(struct hci_dev *hdev)
                else if (fw_size < fw->size - 30)
                        flag = 2;
 
-               err = mtk_hci_wmt_sync(hdev, MTK_WMT_PATCH_DWNLD, flag, dlen,
-                                      fw_ptr);
+               wmt_params.flag = flag;
+               wmt_params.dlen = dlen;
+               wmt_params.data = fw_ptr;
+
+               err = mtk_hci_wmt_sync(hdev, &wmt_params);
                if (err < 0) {
                        bt_dev_err(hdev, "Failed to send wmt patch dwnld (%d)",
                                   err);
-                       break;
+                       goto free_fw;
                }
 
                fw_size -= dlen;
                fw_ptr += dlen;
        }
 
+       wmt_params.op = MTK_WMT_RST;
+       wmt_params.flag = 4;
+       wmt_params.dlen = 0;
+       wmt_params.data = NULL;
+       wmt_params.status = NULL;
+
+       /* Activate funciton the firmware providing to */
+       err = mtk_hci_wmt_sync(hdev, &wmt_params);
+       if (err < 0) {
+               bt_dev_err(hdev, "Failed to send wmt rst (%d)", err);
+               goto free_fw;
+       }
+
+       /* Wait a few moments for firmware activation done */
+       usleep_range(10000, 12000);
+
 free_fw:
        release_firmware(fw);
        return err;
@@ -192,7 +291,20 @@ static int btmtkuart_recv_event(struct hci_dev *hdev, struct sk_buff *skb)
        if (hdr->evt == 0xe4)
                hdr->evt = HCI_EV_VENDOR;
 
+       /* When someone waits for the WMT event, the skb is being cloned
+        * and being processed the events from there then.
+        */
+       if (test_bit(BTMTKUART_TX_WAIT_VND_EVT, &bdev->tx_state)) {
+               bdev->evt_skb = skb_clone(skb, GFP_KERNEL);
+               if (!bdev->evt_skb) {
+                       err = -ENOMEM;
+                       goto err_out;
+               }
+       }
+
        err = hci_recv_frame(hdev, skb);
+       if (err < 0)
+               goto err_free_skb;
 
        if (hdr->evt == HCI_EV_VENDOR) {
                if (test_and_clear_bit(BTMTKUART_TX_WAIT_VND_EVT,
@@ -203,6 +315,13 @@ static int btmtkuart_recv_event(struct hci_dev *hdev, struct sk_buff *skb)
                }
        }
 
+       return 0;
+
+err_free_skb:
+       kfree_skb(bdev->evt_skb);
+       bdev->evt_skb = NULL;
+
+err_out:
        return err;
 }
 
@@ -465,42 +584,134 @@ static int btmtkuart_flush(struct hci_dev *hdev)
        return 0;
 }
 
+static int btmtkuart_func_query(struct hci_dev *hdev)
+{
+       struct btmtk_hci_wmt_params wmt_params;
+       int status, err;
+       u8 param = 0;
+
+       /* Query whether the function is enabled */
+       wmt_params.op = MTK_WMT_FUNC_CTRL;
+       wmt_params.flag = 4;
+       wmt_params.dlen = sizeof(param);
+       wmt_params.data = &param;
+       wmt_params.status = &status;
+
+       err = mtk_hci_wmt_sync(hdev, &wmt_params);
+       if (err < 0) {
+               bt_dev_err(hdev, "Failed to query function status (%d)", err);
+               return err;
+       }
+
+       return status;
+}
+
 static int btmtkuart_setup(struct hci_dev *hdev)
 {
+       struct btmtk_hci_wmt_params wmt_params;
+       ktime_t calltime, delta, rettime;
+       struct btmtk_tci_sleep tci_sleep;
+       unsigned long long duration;
+       struct sk_buff *skb;
+       int err, status;
        u8 param = 0x1;
-       int err = 0;
+
+       calltime = ktime_get();
+
+       /* Query whether the firmware is already download */
+       wmt_params.op = MTK_WMT_SEMAPHORE;
+       wmt_params.flag = 1;
+       wmt_params.dlen = 0;
+       wmt_params.data = NULL;
+       wmt_params.status = &status;
+
+       err = mtk_hci_wmt_sync(hdev, &wmt_params);
+       if (err < 0) {
+               bt_dev_err(hdev, "Failed to query firmware status (%d)", err);
+               return err;
+       }
+
+       if (status == BTMTK_WMT_PATCH_DONE) {
+               bt_dev_info(hdev, "Firmware already downloaded");
+               goto ignore_setup_fw;
+       }
 
        /* Setup a firmware which the device definitely requires */
        err = mtk_setup_fw(hdev);
        if (err < 0)
                return err;
 
-       /* Activate function the firmware providing to */
-       err = mtk_hci_wmt_sync(hdev, MTK_WMT_RST, 0x4, 0, 0);
-       if (err < 0) {
-               bt_dev_err(hdev, "Failed to send wmt rst (%d)", err);
+ignore_setup_fw:
+       /* Query whether the device is already enabled */
+       err = readx_poll_timeout(btmtkuart_func_query, hdev, status,
+                                status < 0 || status != BTMTK_WMT_ON_PROGRESS,
+                                2000, 5000000);
+       /* -ETIMEDOUT happens */
+       if (err < 0)
                return err;
+
+       /* The other errors happen in btusb_mtk_func_query */
+       if (status < 0)
+               return status;
+
+       if (status == BTMTK_WMT_ON_DONE) {
+               bt_dev_info(hdev, "function already on");
+               goto ignore_func_on;
        }
 
        /* Enable Bluetooth protocol */
-       err = mtk_hci_wmt_sync(hdev, MTK_WMT_FUNC_CTRL, 0x0, sizeof(param),
-                              &param);
+       wmt_params.op = MTK_WMT_FUNC_CTRL;
+       wmt_params.flag = 0;
+       wmt_params.dlen = sizeof(param);
+       wmt_params.data = &param;
+       wmt_params.status = NULL;
+
+       err = mtk_hci_wmt_sync(hdev, &wmt_params);
        if (err < 0) {
                bt_dev_err(hdev, "Failed to send wmt func ctrl (%d)", err);
                return err;
        }
 
+ignore_func_on:
+       /* Apply the low power environment setup */
+       tci_sleep.mode = 0x5;
+       tci_sleep.duration = cpu_to_le16(0x640);
+       tci_sleep.host_duration = cpu_to_le16(0x640);
+       tci_sleep.host_wakeup_pin = 0;
+       tci_sleep.time_compensation = 0;
+
+       skb = __hci_cmd_sync(hdev, 0xfc7a, sizeof(tci_sleep), &tci_sleep,
+                            HCI_INIT_TIMEOUT);
+       if (IS_ERR(skb)) {
+               err = PTR_ERR(skb);
+               bt_dev_err(hdev, "Failed to apply low power setting (%d)", err);
+               return err;
+       }
+       kfree_skb(skb);
+
+       rettime = ktime_get();
+       delta = ktime_sub(rettime, calltime);
+       duration = (unsigned long long)ktime_to_ns(delta) >> 10;
+
+       bt_dev_info(hdev, "Device setup in %llu usecs", duration);
+
        return 0;
 }
 
 static int btmtkuart_shutdown(struct hci_dev *hdev)
 {
+       struct btmtk_hci_wmt_params wmt_params;
        u8 param = 0x0;
        int err;
 
        /* Disable the device */
-       err = mtk_hci_wmt_sync(hdev, MTK_WMT_FUNC_CTRL, 0x0, sizeof(param),
-                              &param);
+       wmt_params.op = MTK_WMT_FUNC_CTRL;
+       wmt_params.flag = 0;
+       wmt_params.dlen = sizeof(param);
+       wmt_params.data = &param;
+       wmt_params.status = NULL;
+
+       err = mtk_hci_wmt_sync(hdev, &wmt_params);
        if (err < 0) {
                bt_dev_err(hdev, "Failed to send wmt func ctrl (%d)", err);
                return err;
index ec9e03a6b7786084b634b73f24ee5cf0dfc2c70f..612268574fc7841c68c7730303ebcff73302fca3 100644 (file)
@@ -391,6 +391,25 @@ int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
 }
 EXPORT_SYMBOL_GPL(qca_uart_setup);
 
+int qca_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr)
+{
+       struct sk_buff *skb;
+       int err;
+
+       skb = __hci_cmd_sync_ev(hdev, EDL_WRITE_BD_ADDR_OPCODE, 6, bdaddr,
+                               HCI_EV_VENDOR, HCI_INIT_TIMEOUT);
+       if (IS_ERR(skb)) {
+               err = PTR_ERR(skb);
+               bt_dev_err(hdev, "QCA Change address cmd failed (%d)", err);
+               return err;
+       }
+
+       kfree_skb(skb);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(qca_set_bdaddr);
+
 MODULE_AUTHOR("Ben Young Tae Kim <ytkim@qca.qualcomm.com>");
 MODULE_DESCRIPTION("Bluetooth support for Qualcomm Atheros family ver " VERSION);
 MODULE_VERSION(VERSION);
index 0c01f375fe8331908b9bdede207e3a0af38ed0b8..c72c56ea74808b1e850e9e15759925bae72c0760 100644 (file)
@@ -20,6 +20,7 @@
 
 #define EDL_PATCH_CMD_OPCODE           (0xFC00)
 #define EDL_NVM_ACCESS_OPCODE          (0xFC0B)
+#define EDL_WRITE_BD_ADDR_OPCODE       (0xFC14)
 #define EDL_PATCH_CMD_LEN              (1)
 #define EDL_PATCH_VER_REQ_CMD          (0x19)
 #define EDL_PATCH_TLV_REQ_CMD          (0x1E)
@@ -140,7 +141,7 @@ int qca_set_bdaddr_rome(struct hci_dev *hdev, const bdaddr_t *bdaddr);
 int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
                   enum qca_btsoc_type soc_type, u32 soc_ver);
 int qca_read_soc_version(struct hci_dev *hdev, u32 *soc_version);
-
+int qca_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr);
 #else
 
 static inline int qca_set_bdaddr_rome(struct hci_dev *hdev, const bdaddr_t *bdaddr)
@@ -159,4 +160,9 @@ static inline int qca_read_soc_version(struct hci_dev *hdev, u32 *soc_version)
        return -EOPNOTSUPP;
 }
 
+static inline int qca_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr)
+{
+       return -EOPNOTSUPP;
+}
+
 #endif
index 41405de27d66570a1311ba7d9e1389d2d2cb5668..c91bba00df4e494c4c963c9f4297c1f745211e50 100644 (file)
@@ -552,10 +552,9 @@ struct btrtl_device_info *btrtl_initialize(struct hci_dev *hdev,
                                            hdev->bus);
 
        if (!btrtl_dev->ic_info) {
-               rtl_dev_err(hdev, "rtl: unknown IC info, lmp subver %04x, hci rev %04x, hci ver %04x",
+               rtl_dev_info(hdev, "rtl: unknown IC info, lmp subver %04x, hci rev %04x, hci ver %04x",
                            lmp_subver, hci_rev, hci_ver);
-               ret = -EINVAL;
-               goto err_free;
+               return btrtl_dev;
        }
 
        if (btrtl_dev->ic_info->has_rom_version) {
@@ -610,6 +609,11 @@ int btrtl_download_firmware(struct hci_dev *hdev,
         * standard btusb. Once that firmware is uploaded, the subver changes
         * to a different value.
         */
+       if (!btrtl_dev->ic_info) {
+               rtl_dev_info(hdev, "rtl: assuming no firmware upload needed\n");
+               return 0;
+       }
+
        switch (btrtl_dev->ic_info->lmp_subver) {
        case RTL_ROM_LMP_8723A:
        case RTL_ROM_LMP_3499:
index 4761499db9ee5820f76c0619d5848774e830642c..d4c8d989e7149e9d8ea735cf8cd3df8a11e78f20 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/of_device.h>
 #include <linux/of_irq.h>
 #include <linux/suspend.h>
+#include <linux/gpio/consumer.h>
 #include <asm/unaligned.h>
 
 #include <net/bluetooth/bluetooth.h>
@@ -439,6 +440,7 @@ static const struct dmi_system_id btusb_needs_reset_resume_table[] = {
 #define BTUSB_BOOTING          9
 #define BTUSB_DIAG_RUNNING     10
 #define BTUSB_OOB_WAKE_ENABLED 11
+#define BTUSB_HW_RESET_ACTIVE  12
 
 struct btusb_data {
        struct hci_dev       *hdev;
@@ -476,6 +478,8 @@ struct btusb_data {
        struct usb_endpoint_descriptor *diag_tx_ep;
        struct usb_endpoint_descriptor *diag_rx_ep;
 
+       struct gpio_desc *reset_gpio;
+
        __u8 cmdreq_type;
        __u8 cmdreq;
 
@@ -489,8 +493,41 @@ struct btusb_data {
        int (*setup_on_usb)(struct hci_dev *hdev);
 
        int oob_wake_irq;   /* irq for out-of-band wake-on-bt */
+       unsigned cmd_timeout_cnt;
 };
 
+
+static void btusb_intel_cmd_timeout(struct hci_dev *hdev)
+{
+       struct btusb_data *data = hci_get_drvdata(hdev);
+       struct gpio_desc *reset_gpio = data->reset_gpio;
+
+       if (++data->cmd_timeout_cnt < 5)
+               return;
+
+       if (!reset_gpio) {
+               bt_dev_err(hdev, "No way to reset. Ignoring and continuing");
+               return;
+       }
+
+       /*
+        * Toggle the hard reset line if the platform provides one. The reset
+        * is going to yank the device off the USB and then replug. So doing
+        * once is enough. The cleanup is handled correctly on the way out
+        * (standard USB disconnect), and the new device is detected cleanly
+        * and bound to the driver again like it should be.
+        */
+       if (test_and_set_bit(BTUSB_HW_RESET_ACTIVE, &data->flags)) {
+               bt_dev_err(hdev, "last reset failed? Not resetting again");
+               return;
+       }
+
+       bt_dev_err(hdev, "Initiating HW reset via gpio");
+       gpiod_set_value_cansleep(reset_gpio, 1);
+       msleep(100);
+       gpiod_set_value_cansleep(reset_gpio, 0);
+}
+
 static inline void btusb_free_frags(struct btusb_data *data)
 {
        unsigned long flags;
@@ -2397,6 +2434,24 @@ static int btusb_shutdown_intel(struct hci_dev *hdev)
        return 0;
 }
 
+static int btusb_shutdown_intel_new(struct hci_dev *hdev)
+{
+       struct sk_buff *skb;
+
+       /* Send HCI Reset to the controller to stop any BT activity which
+        * were triggered. This will help to save power and maintain the
+        * sync b/w Host and controller
+        */
+       skb = __hci_cmd_sync(hdev, HCI_OP_RESET, 0, NULL, HCI_INIT_TIMEOUT);
+       if (IS_ERR(skb)) {
+               bt_dev_err(hdev, "HCI reset during shutdown failed");
+               return PTR_ERR(skb);
+       }
+       kfree_skb(skb);
+
+       return 0;
+}
+
 #ifdef CONFIG_PM
 /* Configure an out-of-band gpio as wake-up pin, if specified in device tree */
 static int marvell_config_oob_wake(struct hci_dev *hdev)
@@ -2915,6 +2970,7 @@ static int btusb_probe(struct usb_interface *intf,
                       const struct usb_device_id *id)
 {
        struct usb_endpoint_descriptor *ep_desc;
+       struct gpio_desc *reset_gpio;
        struct btusb_data *data;
        struct hci_dev *hdev;
        unsigned ifnum_base;
@@ -3028,6 +3084,15 @@ static int btusb_probe(struct usb_interface *intf,
 
        SET_HCIDEV_DEV(hdev, &intf->dev);
 
+       reset_gpio = gpiod_get_optional(&data->udev->dev, "reset",
+                                       GPIOD_OUT_LOW);
+       if (IS_ERR(reset_gpio)) {
+               err = PTR_ERR(reset_gpio);
+               goto out_free_dev;
+       } else if (reset_gpio) {
+               data->reset_gpio = reset_gpio;
+       }
+
        hdev->open   = btusb_open;
        hdev->close  = btusb_close;
        hdev->flush  = btusb_flush;
@@ -3082,6 +3147,7 @@ static int btusb_probe(struct usb_interface *intf,
                hdev->shutdown = btusb_shutdown_intel;
                hdev->set_diag = btintel_set_diag_mfg;
                hdev->set_bdaddr = btintel_set_bdaddr;
+               hdev->cmd_timeout = btusb_intel_cmd_timeout;
                set_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks);
                set_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks);
                set_bit(HCI_QUIRK_NON_PERSISTENT_DIAG, &hdev->quirks);
@@ -3091,9 +3157,11 @@ static int btusb_probe(struct usb_interface *intf,
                hdev->manufacturer = 2;
                hdev->send = btusb_send_frame_intel;
                hdev->setup = btusb_setup_intel_new;
+               hdev->shutdown = btusb_shutdown_intel_new;
                hdev->hw_error = btintel_hw_error;
                hdev->set_diag = btintel_set_diag;
                hdev->set_bdaddr = btintel_set_bdaddr;
+               hdev->cmd_timeout = btusb_intel_cmd_timeout;
                set_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks);
                set_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks);
                set_bit(HCI_QUIRK_NON_PERSISTENT_DIAG, &hdev->quirks);
@@ -3226,6 +3294,8 @@ static int btusb_probe(struct usb_interface *intf,
        return 0;
 
 out_free_dev:
+       if (data->reset_gpio)
+               gpiod_put(data->reset_gpio);
        hci_free_dev(hdev);
        return err;
 }
@@ -3269,6 +3339,9 @@ static void btusb_disconnect(struct usb_interface *intf)
        if (data->oob_wake_irq)
                device_init_wakeup(&data->udev->dev, false);
 
+       if (data->reset_gpio)
+               gpiod_put(data->reset_gpio);
+
        hci_free_dev(hdev);
 }
 
index b432651f823650a2ca45e6b1e3537a6179e3fa61..87ccaceadba72a544ffcc7b6fc7669f72cf94463 100644 (file)
@@ -60,12 +60,13 @@ static inline struct sk_buff *h4_recv_buf(struct hci_dev *hdev,
                                          const struct h4_recv_pkt *pkts,
                                          int pkts_count)
 {
+       /* Check for error from previous call */
+       if (IS_ERR(skb))
+               skb = NULL;
+
        while (count) {
                int i, len;
 
-               if (!count)
-                       break;
-
                if (!skb) {
                        for (i = 0; i < pkts_count; i++) {
                                if (buffer[0] != (&pkts[i])->type)
index fb97a3bf069bbffbbee9feed7de1ffdb83e8a685..5d97d77627c1a087ee5450b327562ef993ce1887 100644 (file)
@@ -174,6 +174,10 @@ struct sk_buff *h4_recv_buf(struct hci_dev *hdev, struct sk_buff *skb,
        struct hci_uart *hu = hci_get_drvdata(hdev);
        u8 alignment = hu->alignment ? hu->alignment : 1;
 
+       /* Check for error from previous call */
+       if (IS_ERR(skb))
+               skb = NULL;
+
        while (count) {
                int i, len;
 
index fbf7b4df23ab94ed2f3b3f2c4a75c3d6320283dd..4918fefc4a6facf14b49f32c2f9f098db802858f 100644 (file)
@@ -207,11 +207,11 @@ void hci_uart_init_work(struct work_struct *work)
        err = hci_register_dev(hu->hdev);
        if (err < 0) {
                BT_ERR("Can't register HCI device");
+               clear_bit(HCI_UART_PROTO_READY, &hu->flags);
+               hu->proto->close(hu);
                hdev = hu->hdev;
                hu->hdev = NULL;
                hci_free_dev(hdev);
-               clear_bit(HCI_UART_PROTO_READY, &hu->flags);
-               hu->proto->close(hu);
                return;
        }
 
@@ -616,6 +616,7 @@ static void hci_uart_tty_receive(struct tty_struct *tty, const u8 *data,
 static int hci_uart_register_dev(struct hci_uart *hu)
 {
        struct hci_dev *hdev;
+       int err;
 
        BT_DBG("");
 
@@ -659,11 +660,22 @@ static int hci_uart_register_dev(struct hci_uart *hu)
        else
                hdev->dev_type = HCI_PRIMARY;
 
+       /* Only call open() for the protocol after hdev is fully initialized as
+        * open() (or a timer/workqueue it starts) may attempt to reference it.
+        */
+       err = hu->proto->open(hu);
+       if (err) {
+               hu->hdev = NULL;
+               hci_free_dev(hdev);
+               return err;
+       }
+
        if (test_bit(HCI_UART_INIT_PENDING, &hu->hdev_flags))
                return 0;
 
        if (hci_register_dev(hdev) < 0) {
                BT_ERR("Can't register HCI device");
+               hu->proto->close(hu);
                hu->hdev = NULL;
                hci_free_dev(hdev);
                return -ENODEV;
@@ -683,17 +695,12 @@ static int hci_uart_set_proto(struct hci_uart *hu, int id)
        if (!p)
                return -EPROTONOSUPPORT;
 
-       err = p->open(hu);
-       if (err)
-               return err;
-
        hu->proto = p;
        set_bit(HCI_UART_PROTO_READY, &hu->flags);
 
        err = hci_uart_register_dev(hu);
        if (err) {
                clear_bit(HCI_UART_PROTO_READY, &hu->flags);
-               p->close(hu);
                return err;
        }
 
index f036c8f98ea3376317e0256a83cec44a3a4d0cc2..5e03504c4e0ca90c0af976d25f928dc2ed8d2f19 100644 (file)
@@ -60,6 +60,7 @@
 #define IBS_WAKE_RETRANS_TIMEOUT_MS    100
 #define IBS_TX_IDLE_TIMEOUT_MS         2000
 #define BAUDRATE_SETTLE_TIMEOUT_MS     300
+#define POWER_PULSE_TRANS_TIMEOUT_MS   100
 
 /* susclk rate */
 #define SUSCLK_RATE_32KHZ      32768
@@ -770,16 +771,17 @@ static int qca_enqueue(struct hci_uart *hu, struct sk_buff *skb)
        /* Prepend skb with frame type */
        memcpy(skb_push(skb, 1), &hci_skb_pkt_type(skb), 1);
 
+       spin_lock_irqsave(&qca->hci_ibs_lock, flags);
+
        /* Don't go to sleep in middle of patch download or
         * Out-Of-Band(GPIOs control) sleep is selected.
         */
        if (!test_bit(STATE_IN_BAND_SLEEP_ENABLED, &qca->flags)) {
                skb_queue_tail(&qca->txq, skb);
+               spin_unlock_irqrestore(&qca->hci_ibs_lock, flags);
                return 0;
        }
 
-       spin_lock_irqsave(&qca->hci_ibs_lock, flags);
-
        /* Act according to current state */
        switch (qca->tx_ibs_state) {
        case HCI_IBS_TX_AWAKE:
@@ -963,7 +965,6 @@ static int qca_set_baudrate(struct hci_dev *hdev, uint8_t baudrate)
        struct hci_uart *hu = hci_get_drvdata(hdev);
        struct qca_data *qca = hu->priv;
        struct sk_buff *skb;
-       struct qca_serdev *qcadev;
        u8 cmd[] = { 0x01, 0x48, 0xFC, 0x01, 0x00 };
 
        if (baudrate > QCA_BAUDRATE_3200000)
@@ -977,13 +978,6 @@ static int qca_set_baudrate(struct hci_dev *hdev, uint8_t baudrate)
                return -ENOMEM;
        }
 
-       /* Disabling hardware flow control is mandatory while
-        * sending change baudrate request to wcn3990 SoC.
-        */
-       qcadev = serdev_device_get_drvdata(hu->serdev);
-       if (qcadev->btsoc_type == QCA_WCN3990)
-               hci_uart_set_flow_control(hu, true);
-
        /* Assign commands to change baudrate and packet type. */
        skb_put_data(skb, cmd, sizeof(cmd));
        hci_skb_pkt_type(skb) = HCI_COMMAND_PKT;
@@ -999,9 +993,6 @@ static int qca_set_baudrate(struct hci_dev *hdev, uint8_t baudrate)
        schedule_timeout(msecs_to_jiffies(BAUDRATE_SETTLE_TIMEOUT_MS));
        set_current_state(TASK_RUNNING);
 
-       if (qcadev->btsoc_type == QCA_WCN3990)
-               hci_uart_set_flow_control(hu, false);
-
        return 0;
 }
 
@@ -1013,11 +1004,10 @@ static inline void host_set_baudrate(struct hci_uart *hu, unsigned int speed)
                hci_uart_set_baudrate(hu, speed);
 }
 
-static int qca_send_power_pulse(struct hci_dev *hdev, u8 cmd)
+static int qca_send_power_pulse(struct hci_uart *hu, u8 cmd)
 {
-       struct hci_uart *hu = hci_get_drvdata(hdev);
-       struct qca_data *qca = hu->priv;
-       struct sk_buff *skb;
+       int ret;
+       int timeout = msecs_to_jiffies(POWER_PULSE_TRANS_TIMEOUT_MS);
 
        /* These power pulses are single byte command which are sent
         * at required baudrate to wcn3990. On wcn3990, we have an external
@@ -1029,19 +1019,17 @@ static int qca_send_power_pulse(struct hci_dev *hdev, u8 cmd)
         * save power. Disabling hardware flow control is mandatory while
         * sending power pulses to SoC.
         */
-       bt_dev_dbg(hdev, "sending power pulse %02x to SoC", cmd);
-
-       skb = bt_skb_alloc(sizeof(cmd), GFP_KERNEL);
-       if (!skb)
-               return -ENOMEM;
+       bt_dev_dbg(hu->hdev, "sending power pulse %02x to controller", cmd);
 
+       serdev_device_write_flush(hu->serdev);
        hci_uart_set_flow_control(hu, true);
+       ret = serdev_device_write_buf(hu->serdev, &cmd, sizeof(cmd));
+       if (ret < 0) {
+               bt_dev_err(hu->hdev, "failed to send power pulse %02x", cmd);
+               return ret;
+       }
 
-       skb_put_u8(skb, cmd);
-       hci_skb_pkt_type(skb) = HCI_COMMAND_PKT;
-
-       skb_queue_tail(&qca->txq, skb);
-       hci_uart_tx_wakeup(hu);
+       serdev_device_wait_until_sent(hu->serdev, timeout);
 
        /* Wait for 100 uS for SoC to settle down */
        usleep_range(100, 200);
@@ -1091,7 +1079,8 @@ static int qca_check_speeds(struct hci_uart *hu)
 static int qca_set_speed(struct hci_uart *hu, enum qca_speed_type speed_type)
 {
        unsigned int speed, qca_baudrate;
-       int ret;
+       struct qca_serdev *qcadev;
+       int ret = 0;
 
        if (speed_type == QCA_INIT_SPEED) {
                speed = qca_get_speed(hu, QCA_INIT_SPEED);
@@ -1102,21 +1091,31 @@ static int qca_set_speed(struct hci_uart *hu, enum qca_speed_type speed_type)
                if (!speed)
                        return 0;
 
+               /* Disable flow control for wcn3990 to deassert RTS while
+                * changing the baudrate of chip and host.
+                */
+               qcadev = serdev_device_get_drvdata(hu->serdev);
+               if (qcadev->btsoc_type == QCA_WCN3990)
+                       hci_uart_set_flow_control(hu, true);
+
                qca_baudrate = qca_get_baudrate_value(speed);
                bt_dev_dbg(hu->hdev, "Set UART speed to %d", speed);
                ret = qca_set_baudrate(hu->hdev, qca_baudrate);
                if (ret)
-                       return ret;
+                       goto error;
 
                host_set_baudrate(hu, speed);
+
+error:
+               if (qcadev->btsoc_type == QCA_WCN3990)
+                       hci_uart_set_flow_control(hu, false);
        }
 
-       return 0;
+       return ret;
 }
 
 static int qca_wcn3990_init(struct hci_uart *hu)
 {
-       struct hci_dev *hdev = hu->hdev;
        struct qca_serdev *qcadev;
        int ret;
 
@@ -1139,12 +1138,12 @@ static int qca_wcn3990_init(struct hci_uart *hu)
 
        /* Forcefully enable wcn3990 to enter in to boot mode. */
        host_set_baudrate(hu, 2400);
-       ret = qca_send_power_pulse(hdev, QCA_WCN3990_POWEROFF_PULSE);
+       ret = qca_send_power_pulse(hu, QCA_WCN3990_POWEROFF_PULSE);
        if (ret)
                return ret;
 
        qca_set_speed(hu, QCA_INIT_SPEED);
-       ret = qca_send_power_pulse(hdev, QCA_WCN3990_POWERON_PULSE);
+       ret = qca_send_power_pulse(hu, QCA_WCN3990_POWERON_PULSE);
        if (ret)
                return ret;
 
@@ -1241,7 +1240,10 @@ static int qca_setup(struct hci_uart *hu)
        }
 
        /* Setup bdaddr */
-       hu->hdev->set_bdaddr = qca_set_bdaddr_rome;
+       if (qcadev->btsoc_type == QCA_WCN3990)
+               hu->hdev->set_bdaddr = qca_set_bdaddr;
+       else
+               hu->hdev->set_bdaddr = qca_set_bdaddr_rome;
 
        return ret;
 }
@@ -1274,13 +1276,20 @@ static const struct qca_vreg_data qca_soc_data = {
 
 static void qca_power_shutdown(struct hci_uart *hu)
 {
-       struct serdev_device *serdev = hu->serdev;
-       unsigned char cmd = QCA_WCN3990_POWEROFF_PULSE;
+       struct qca_data *qca = hu->priv;
+       unsigned long flags;
+
+       /* From this point we go into power off state. But serial port is
+        * still open, stop queueing the IBS data and flush all the buffered
+        * data in skb's.
+        */
+       spin_lock_irqsave(&qca->hci_ibs_lock, flags);
+       clear_bit(STATE_IN_BAND_SLEEP_ENABLED, &qca->flags);
+       qca_flush(hu);
+       spin_unlock_irqrestore(&qca->hci_ibs_lock, flags);
 
        host_set_baudrate(hu, 2400);
-       hci_uart_set_flow_control(hu, true);
-       serdev_device_write_buf(serdev, &cmd, sizeof(cmd));
-       hci_uart_set_flow_control(hu, false);
+       qca_send_power_pulse(hu, QCA_WCN3990_POWEROFF_PULSE);
        qca_power_setup(hu, false);
 }
 
index e221861b3187c2fcbceb4b3ee58b70d2fca5fa53..9043d7242d67ee40001a3b978e09097928373787 100644 (file)
@@ -139,86 +139,123 @@ static struct acpi_device *usb_acpi_find_port(struct acpi_device *parent,
        return acpi_find_child_device(parent, raw, false);
 }
 
-static struct acpi_device *usb_acpi_find_companion(struct device *dev)
+static struct acpi_device *
+usb_acpi_get_companion_for_port(struct usb_port *port_dev)
 {
        struct usb_device *udev;
        struct acpi_device *adev;
        acpi_handle *parent_handle;
+       int port1;
+
+       /* Get the struct usb_device point of port's hub */
+       udev = to_usb_device(port_dev->dev.parent->parent);
 
        /*
-        * In the ACPI DSDT table, only usb root hub and usb ports are
-        * acpi device nodes. The hierarchy like following.
-        * Device (EHC1)
-        *      Device (HUBN)
-        *              Device (PR01)
-        *                      Device (PR11)
-        *                      Device (PR12)
-        *                      Device (PR13)
-        *                      ...
-        * So all binding process is divided into two parts. binding
-        * root hub and usb ports.
+        * The root hub ports' parent is the root hub. The non-root-hub
+        * ports' parent is the parent hub port which the hub is
+        * connected to.
         */
-       if (is_usb_device(dev)) {
-               udev = to_usb_device(dev);
-               if (udev->parent)
+       if (!udev->parent) {
+               adev = ACPI_COMPANION(&udev->dev);
+               port1 = usb_hcd_find_raw_port_number(bus_to_hcd(udev->bus),
+                                                    port_dev->portnum);
+       } else {
+               parent_handle = usb_get_hub_port_acpi_handle(udev->parent,
+                                                            udev->portnum);
+               if (!parent_handle)
                        return NULL;
 
-               /* root hub is only child (_ADR=0) under its parent, the HC */
-               adev = ACPI_COMPANION(dev->parent);
-               return acpi_find_child_device(adev, 0, false);
-       } else if (is_usb_port(dev)) {
-               struct usb_port *port_dev = to_usb_port(dev);
-               int port1 = port_dev->portnum;
-               struct acpi_pld_info *pld;
-               acpi_handle *handle;
-               acpi_status status;
-
-               /* Get the struct usb_device point of port's hub */
-               udev = to_usb_device(dev->parent->parent);
-
-               /*
-                * The root hub ports' parent is the root hub. The non-root-hub
-                * ports' parent is the parent hub port which the hub is
-                * connected to.
-                */
-               if (!udev->parent) {
-                       struct usb_hcd *hcd = bus_to_hcd(udev->bus);
-                       int raw;
-
-                       raw = usb_hcd_find_raw_port_number(hcd, port1);
-
-                       adev = usb_acpi_find_port(ACPI_COMPANION(&udev->dev),
-                                                 raw);
-
-                       if (!adev)
-                               return NULL;
-               } else {
-                       parent_handle =
-                               usb_get_hub_port_acpi_handle(udev->parent,
-                               udev->portnum);
-                       if (!parent_handle)
-                               return NULL;
-
-                       acpi_bus_get_device(parent_handle, &adev);
-
-                       adev = usb_acpi_find_port(adev, port1);
-
-                       if (!adev)
-                               return NULL;
-               }
-               handle = adev->handle;
-               status = acpi_get_physical_device_location(handle, &pld);
-               if (ACPI_FAILURE(status) || !pld)
-                       return adev;
+               acpi_bus_get_device(parent_handle, &adev);
+               port1 = port_dev->portnum;
+       }
 
+       return usb_acpi_find_port(adev, port1);
+}
+
+static struct acpi_device *
+usb_acpi_find_companion_for_port(struct usb_port *port_dev)
+{
+       struct acpi_device *adev;
+       struct acpi_pld_info *pld;
+       acpi_handle *handle;
+       acpi_status status;
+
+       adev = usb_acpi_get_companion_for_port(port_dev);
+       if (!adev)
+               return NULL;
+
+       handle = adev->handle;
+       status = acpi_get_physical_device_location(handle, &pld);
+       if (!ACPI_FAILURE(status) && pld) {
                port_dev->location = USB_ACPI_LOCATION_VALID
                        | pld->group_token << 8 | pld->group_position;
                port_dev->connect_type = usb_acpi_get_connect_type(handle, pld);
                ACPI_FREE(pld);
+       }
 
-               return adev;
+       return adev;
+}
+
+static struct acpi_device *
+usb_acpi_find_companion_for_device(struct usb_device *udev)
+{
+       struct acpi_device *adev;
+       struct usb_port *port_dev;
+       struct usb_hub *hub;
+
+       if (!udev->parent) {
+               /* root hub is only child (_ADR=0) under its parent, the HC */
+               adev = ACPI_COMPANION(udev->dev.parent);
+               return acpi_find_child_device(adev, 0, false);
        }
 
+       hub = usb_hub_to_struct_hub(udev->parent);
+       if (!hub)
+               return NULL;
+
+       /*
+        * This is an embedded USB device connected to a port and such
+        * devices share port's ACPI companion.
+        */
+       port_dev = hub->ports[udev->portnum - 1];
+       return usb_acpi_get_companion_for_port(port_dev);
+}
+
+static struct acpi_device *usb_acpi_find_companion(struct device *dev)
+{
+       /*
+        * The USB hierarchy like following:
+        *
+        * Device (EHC1)
+        *      Device (HUBN)
+        *              Device (PR01)
+        *                      Device (PR11)
+        *                      Device (PR12)
+        *                              Device (FN12)
+        *                              Device (FN13)
+        *                      Device (PR13)
+        *                      ...
+        * where HUBN is root hub, and PRNN are USB ports and devices
+        * connected to them, and FNNN are individualk functions for
+        * connected composite USB devices. PRNN and FNNN may contain
+        * _CRS and other methods describing sideband resources for
+        * the connected device.
+        *
+        * On the kernel side both root hub and embedded USB devices are
+        * represented as instances of usb_device structure, and ports
+        * are represented as usb_port structures, so the whole process
+        * is split into 2 parts: finding companions for devices and
+        * finding companions for ports.
+        *
+        * Note that we do not handle individual functions of composite
+        * devices yet, for that we would need to assign companions to
+        * devices corresponding to USB interfaces.
+        */
+       if (is_usb_device(dev))
+               return usb_acpi_find_companion_for_device(to_usb_device(dev));
+       else if (is_usb_port(dev))
+               return usb_acpi_find_companion_for_port(to_usb_port(dev));
+
        return NULL;
 }
 
index ec9d6bc658559c55b64ac3c1d23b4e1166cc4b04..fabee6db0abb78ea826cc97d52c622614db900a0 100644 (file)
@@ -276,7 +276,7 @@ int  bt_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg);
 int  bt_sock_wait_state(struct sock *sk, int state, unsigned long timeo);
 int  bt_sock_wait_ready(struct sock *sk, unsigned long flags);
 
-void bt_accept_enqueue(struct sock *parent, struct sock *sk);
+void bt_accept_enqueue(struct sock *parent, struct sock *sk, bool bh);
 void bt_accept_unlink(struct sock *sk);
 struct sock *bt_accept_dequeue(struct sock *parent, struct socket *newsock);
 
index e5ea633ea36880176ac608e20570f46f455c35d2..094e61e07030f5f5418f1aae008db4c00e7ee1f3 100644 (file)
@@ -437,6 +437,7 @@ struct hci_dev {
        int (*post_init)(struct hci_dev *hdev);
        int (*set_diag)(struct hci_dev *hdev, bool enable);
        int (*set_bdaddr)(struct hci_dev *hdev, const bdaddr_t *bdaddr);
+       void (*cmd_timeout)(struct hci_dev *hdev);
 };
 
 #define HCI_PHY_HANDLE(handle) (handle & 0xff)
index 6c152f9ea26eddb41e3a26117c5d82ec8326d899..536aae52eeadd4bea1f3e73fcd44d0148c87928d 100644 (file)
@@ -41,9 +41,9 @@ static int lowpan_ctx_flag_active_get(void *data, u64 *val)
        return 0;
 }
 
-DEFINE_SIMPLE_ATTRIBUTE(lowpan_ctx_flag_active_fops,
-                       lowpan_ctx_flag_active_get,
-                       lowpan_ctx_flag_active_set, "%llu\n");
+DEFINE_DEBUGFS_ATTRIBUTE(lowpan_ctx_flag_active_fops,
+                        lowpan_ctx_flag_active_get,
+                        lowpan_ctx_flag_active_set, "%llu\n");
 
 static int lowpan_ctx_flag_c_set(void *data, u64 val)
 {
@@ -66,8 +66,8 @@ static int lowpan_ctx_flag_c_get(void *data, u64 *val)
        return 0;
 }
 
-DEFINE_SIMPLE_ATTRIBUTE(lowpan_ctx_flag_c_fops, lowpan_ctx_flag_c_get,
-                       lowpan_ctx_flag_c_set, "%llu\n");
+DEFINE_DEBUGFS_ATTRIBUTE(lowpan_ctx_flag_c_fops, lowpan_ctx_flag_c_get,
+                        lowpan_ctx_flag_c_set, "%llu\n");
 
 static int lowpan_ctx_plen_set(void *data, u64 val)
 {
@@ -97,8 +97,8 @@ static int lowpan_ctx_plen_get(void *data, u64 *val)
        return 0;
 }
 
-DEFINE_SIMPLE_ATTRIBUTE(lowpan_ctx_plen_fops, lowpan_ctx_plen_get,
-                       lowpan_ctx_plen_set, "%llu\n");
+DEFINE_DEBUGFS_ATTRIBUTE(lowpan_ctx_plen_fops, lowpan_ctx_plen_get,
+                        lowpan_ctx_plen_set, "%llu\n");
 
 static int lowpan_ctx_pfx_show(struct seq_file *file, void *offset)
 {
@@ -184,15 +184,15 @@ static int lowpan_dev_debugfs_ctx_init(struct net_device *dev,
        if (!root)
                return -EINVAL;
 
-       dentry = debugfs_create_file("active", 0644, root,
-                                    &ldev->ctx.table[id],
-                                    &lowpan_ctx_flag_active_fops);
+       dentry = debugfs_create_file_unsafe("active", 0644, root,
+                                           &ldev->ctx.table[id],
+                                           &lowpan_ctx_flag_active_fops);
        if (!dentry)
                return -EINVAL;
 
-       dentry = debugfs_create_file("compression", 0644, root,
-                                    &ldev->ctx.table[id],
-                                    &lowpan_ctx_flag_c_fops);
+       dentry = debugfs_create_file_unsafe("compression", 0644, root,
+                                           &ldev->ctx.table[id],
+                                           &lowpan_ctx_flag_c_fops);
        if (!dentry)
                return -EINVAL;
 
@@ -202,9 +202,9 @@ static int lowpan_dev_debugfs_ctx_init(struct net_device *dev,
        if (!dentry)
                return -EINVAL;
 
-       dentry = debugfs_create_file("prefix_len", 0644, root,
-                                    &ldev->ctx.table[id],
-                                    &lowpan_ctx_plen_fops);
+       dentry = debugfs_create_file_unsafe("prefix_len", 0644, root,
+                                           &ldev->ctx.table[id],
+                                           &lowpan_ctx_plen_fops);
        if (!dentry)
                return -EINVAL;
 
@@ -245,8 +245,8 @@ static int lowpan_short_addr_get(void *data, u64 *val)
        return 0;
 }
 
-DEFINE_SIMPLE_ATTRIBUTE(lowpan_short_addr_fops, lowpan_short_addr_get,
-                       NULL, "0x%04llx\n");
+DEFINE_DEBUGFS_ATTRIBUTE(lowpan_short_addr_fops, lowpan_short_addr_get, NULL,
+                        "0x%04llx\n");
 
 static int lowpan_dev_debugfs_802154_init(const struct net_device *dev,
                                          struct lowpan_dev *ldev)
@@ -260,9 +260,9 @@ static int lowpan_dev_debugfs_802154_init(const struct net_device *dev,
        if (!root)
                return -EINVAL;
 
-       dentry = debugfs_create_file("short_addr", 0444, root,
-                                    lowpan_802154_dev(dev)->wdev->ieee802154_ptr,
-                                    &lowpan_short_addr_fops);
+       dentry = debugfs_create_file_unsafe("short_addr", 0444, root,
+                                           lowpan_802154_dev(dev)->wdev->ieee802154_ptr,
+                                           &lowpan_short_addr_fops);
        if (!dentry)
                return -EINVAL;
 
index 9d79c7de234a968683cb956318041b1fe503f74d..a7cd23f00bded67d6cbadf0600bfb30aa786f163 100644 (file)
@@ -1108,8 +1108,8 @@ static int lowpan_enable_get(void *data, u64 *val)
        return 0;
 }
 
-DEFINE_SIMPLE_ATTRIBUTE(lowpan_enable_fops, lowpan_enable_get,
-                       lowpan_enable_set, "%llu\n");
+DEFINE_DEBUGFS_ATTRIBUTE(lowpan_enable_fops, lowpan_enable_get,
+                        lowpan_enable_set, "%llu\n");
 
 static ssize_t lowpan_control_write(struct file *fp,
                                    const char __user *user_buffer,
@@ -1278,9 +1278,10 @@ static struct notifier_block bt_6lowpan_dev_notifier = {
 
 static int __init bt_6lowpan_init(void)
 {
-       lowpan_enable_debugfs = debugfs_create_file("6lowpan_enable", 0644,
-                                                   bt_debugfs, NULL,
-                                                   &lowpan_enable_fops);
+       lowpan_enable_debugfs = debugfs_create_file_unsafe("6lowpan_enable",
+                                                          0644, bt_debugfs,
+                                                          NULL,
+                                                          &lowpan_enable_fops);
        lowpan_control_debugfs = debugfs_create_file("6lowpan_control", 0644,
                                                     bt_debugfs, NULL,
                                                     &lowpan_control_fops);
index 58fc6333d41225dcb967052eec798af839013e0b..5f918ea18b5a5c282b3a78bb36b9f4a780080459 100644 (file)
@@ -174,7 +174,7 @@ static int a2mp_discover_req(struct amp_mgr *mgr, struct sk_buff *skb,
                        num_ctrl++;
        }
 
-       len = num_ctrl * sizeof(struct a2mp_cl) + sizeof(*rsp);
+       len = struct_size(rsp, cl, num_ctrl);
        rsp = kmalloc(len, GFP_ATOMIC);
        if (!rsp) {
                read_unlock(&hci_dev_list_lock);
index deacc52d7ff18d41fbac961c4a13c6bae701eaa4..8d12198eaa9490daf54d1dbc9fd52a79108967bb 100644 (file)
@@ -154,15 +154,25 @@ void bt_sock_unlink(struct bt_sock_list *l, struct sock *sk)
 }
 EXPORT_SYMBOL(bt_sock_unlink);
 
-void bt_accept_enqueue(struct sock *parent, struct sock *sk)
+void bt_accept_enqueue(struct sock *parent, struct sock *sk, bool bh)
 {
        BT_DBG("parent %p, sk %p", parent, sk);
 
        sock_hold(sk);
-       lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
+
+       if (bh)
+               bh_lock_sock_nested(sk);
+       else
+               lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
+
        list_add_tail(&bt_sk(sk)->accept_q, &bt_sk(parent)->accept_q);
        bt_sk(sk)->parent = parent;
-       release_sock(sk);
+
+       if (bh)
+               bh_unlock_sock(sk);
+       else
+               release_sock(sk);
+
        parent->sk_ack_backlog++;
 }
 EXPORT_SYMBOL(bt_accept_enqueue);
index 7352fe85674be5c3e73ef50ca3702caec7a69e6c..26e3d36aee2989ed038a3a03f45f39444f7ba699 100644 (file)
@@ -2578,6 +2578,9 @@ static void hci_cmd_timeout(struct work_struct *work)
                bt_dev_err(hdev, "command tx timeout");
        }
 
+       if (hdev->cmd_timeout)
+               hdev->cmd_timeout(hdev);
+
        atomic_set(&hdev->cmd_cnt, 1);
        queue_work(hdev->workqueue, &hdev->cmd_work);
 }
@@ -3401,7 +3404,7 @@ EXPORT_SYMBOL(hci_resume_dev);
 /* Reset HCI device */
 int hci_reset_dev(struct hci_dev *hdev)
 {
-       const u8 hw_err[] = { HCI_EV_HARDWARE_ERROR, 0x01, 0x00 };
+       static const u8 hw_err[] = { HCI_EV_HARDWARE_ERROR, 0x01, 0x00 };
        struct sk_buff *skb;
 
        skb = bt_skb_alloc(3, GFP_ATOMIC);
index ac2826ce162b902a0d1e973744707645ec06dae5..609fd6871c5ad2f060bd191fb3f04cc785bb5392 100644 (file)
@@ -3556,8 +3556,8 @@ static void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
                return;
        }
 
-       if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
-           ev->num_hndl * sizeof(struct hci_comp_pkts_info)) {
+       if (skb->len < sizeof(*ev) ||
+           skb->len < struct_size(ev, handles, ev->num_hndl)) {
                BT_DBG("%s bad parameters", hdev->name);
                return;
        }
@@ -3644,8 +3644,8 @@ static void hci_num_comp_blocks_evt(struct hci_dev *hdev, struct sk_buff *skb)
                return;
        }
 
-       if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
-           ev->num_hndl * sizeof(struct hci_comp_blocks_info)) {
+       if (skb->len < sizeof(*ev) ||
+           skb->len < struct_size(ev, handles, ev->num_hndl)) {
                BT_DBG("%s bad parameters", hdev->name);
                return;
        }
index 65228bfa44872113f9a28586463bee1e7f9ca945..d32077b284337ff4086701b0fa5817a173e09d03 100644 (file)
@@ -831,8 +831,6 @@ static int hci_sock_release(struct socket *sock)
        if (!sk)
                return 0;
 
-       hdev = hci_pi(sk)->hdev;
-
        switch (hci_pi(sk)->channel) {
        case HCI_CHANNEL_MONITOR:
                atomic_dec(&monitor_promisc);
@@ -854,6 +852,7 @@ static int hci_sock_release(struct socket *sock)
 
        bt_sock_unlink(&hci_sk_list, sk);
 
+       hdev = hci_pi(sk)->hdev;
        if (hdev) {
                if (hci_pi(sk)->channel == HCI_CHANNEL_USER) {
                        /* When releasing a user channel exclusive access,
index 2a7fb517d460f02db1b5a901899ff42f9d193e1b..f17e393b43b47078a62f3a30d17595293c65264b 100644 (file)
@@ -3337,16 +3337,22 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data, size_t data
 
        while (len >= L2CAP_CONF_OPT_SIZE) {
                len -= l2cap_get_conf_opt(&req, &type, &olen, &val);
+               if (len < 0)
+                       break;
 
                hint  = type & L2CAP_CONF_HINT;
                type &= L2CAP_CONF_MASK;
 
                switch (type) {
                case L2CAP_CONF_MTU:
+                       if (olen != 2)
+                               break;
                        mtu = val;
                        break;
 
                case L2CAP_CONF_FLUSH_TO:
+                       if (olen != 2)
+                               break;
                        chan->flush_to = val;
                        break;
 
@@ -3354,26 +3360,30 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data, size_t data
                        break;
 
                case L2CAP_CONF_RFC:
-                       if (olen == sizeof(rfc))
-                               memcpy(&rfc, (void *) val, olen);
+                       if (olen != sizeof(rfc))
+                               break;
+                       memcpy(&rfc, (void *) val, olen);
                        break;
 
                case L2CAP_CONF_FCS:
+                       if (olen != 1)
+                               break;
                        if (val == L2CAP_FCS_NONE)
                                set_bit(CONF_RECV_NO_FCS, &chan->conf_state);
                        break;
 
                case L2CAP_CONF_EFS:
-                       if (olen == sizeof(efs)) {
-                               remote_efs = 1;
-                               memcpy(&efs, (void *) val, olen);
-                       }
+                       if (olen != sizeof(efs))
+                               break;
+                       remote_efs = 1;
+                       memcpy(&efs, (void *) val, olen);
                        break;
 
                case L2CAP_CONF_EWS:
+                       if (olen != 2)
+                               break;
                        if (!(chan->conn->local_fixed_chan & L2CAP_FC_A2MP))
                                return -ECONNREFUSED;
-
                        set_bit(FLAG_EXT_CTRL, &chan->flags);
                        set_bit(CONF_EWS_RECV, &chan->conf_state);
                        chan->tx_win_max = L2CAP_DEFAULT_EXT_WINDOW;
@@ -3383,7 +3393,6 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data, size_t data
                default:
                        if (hint)
                                break;
-
                        result = L2CAP_CONF_UNKNOWN;
                        *((u8 *) ptr++) = type;
                        break;
@@ -3548,58 +3557,65 @@ static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len,
 
        while (len >= L2CAP_CONF_OPT_SIZE) {
                len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
+               if (len < 0)
+                       break;
 
                switch (type) {
                case L2CAP_CONF_MTU:
+                       if (olen != 2)
+                               break;
                        if (val < L2CAP_DEFAULT_MIN_MTU) {
                                *result = L2CAP_CONF_UNACCEPT;
                                chan->imtu = L2CAP_DEFAULT_MIN_MTU;
                        } else
                                chan->imtu = val;
-                       l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu, endptr - ptr);
+                       l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, chan->imtu,
+                                          endptr - ptr);
                        break;
 
                case L2CAP_CONF_FLUSH_TO:
+                       if (olen != 2)
+                               break;
                        chan->flush_to = val;
-                       l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO,
-                                          2, chan->flush_to, endptr - ptr);
+                       l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO, 2,
+                                          chan->flush_to, endptr - ptr);
                        break;
 
                case L2CAP_CONF_RFC:
-                       if (olen == sizeof(rfc))
-                               memcpy(&rfc, (void *)val, olen);
-
+                       if (olen != sizeof(rfc))
+                               break;
+                       memcpy(&rfc, (void *)val, olen);
                        if (test_bit(CONF_STATE2_DEVICE, &chan->conf_state) &&
                            rfc.mode != chan->mode)
                                return -ECONNREFUSED;
-
                        chan->fcs = 0;
-
-                       l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
-                                          sizeof(rfc), (unsigned long) &rfc, endptr - ptr);
+                       l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC, sizeof(rfc),
+                                          (unsigned long) &rfc, endptr - ptr);
                        break;
 
                case L2CAP_CONF_EWS:
+                       if (olen != 2)
+                               break;
                        chan->ack_win = min_t(u16, val, chan->ack_win);
                        l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
                                           chan->tx_win, endptr - ptr);
                        break;
 
                case L2CAP_CONF_EFS:
-                       if (olen == sizeof(efs)) {
-                               memcpy(&efs, (void *)val, olen);
-
-                               if (chan->local_stype != L2CAP_SERV_NOTRAFIC &&
-                                   efs.stype != L2CAP_SERV_NOTRAFIC &&
-                                   efs.stype != chan->local_stype)
-                                       return -ECONNREFUSED;
-
-                               l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS, sizeof(efs),
-                                                  (unsigned long) &efs, endptr - ptr);
-                       }
+                       if (olen != sizeof(efs))
+                               break;
+                       memcpy(&efs, (void *)val, olen);
+                       if (chan->local_stype != L2CAP_SERV_NOTRAFIC &&
+                           efs.stype != L2CAP_SERV_NOTRAFIC &&
+                           efs.stype != chan->local_stype)
+                               return -ECONNREFUSED;
+                       l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS, sizeof(efs),
+                                          (unsigned long) &efs, endptr - ptr);
                        break;
 
                case L2CAP_CONF_FCS:
+                       if (olen != 1)
+                               break;
                        if (*result == L2CAP_CONF_PENDING)
                                if (val == L2CAP_FCS_NONE)
                                        set_bit(CONF_RECV_NO_FCS,
@@ -3728,13 +3744,18 @@ static void l2cap_conf_rfc_get(struct l2cap_chan *chan, void *rsp, int len)
 
        while (len >= L2CAP_CONF_OPT_SIZE) {
                len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val);
+               if (len < 0)
+                       break;
 
                switch (type) {
                case L2CAP_CONF_RFC:
-                       if (olen == sizeof(rfc))
-                               memcpy(&rfc, (void *)val, olen);
+                       if (olen != sizeof(rfc))
+                               break;
+                       memcpy(&rfc, (void *)val, olen);
                        break;
                case L2CAP_CONF_EWS:
+                       if (olen != 2)
+                               break;
                        txwin_ext = val;
                        break;
                }
@@ -4244,6 +4265,7 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn,
                                goto done;
                        break;
                }
+               /* fall through */
 
        default:
                l2cap_chan_set_err(chan, ECONNRESET);
index 686bdc6b35b03d1fd0965dc0fd76c5edde78c1eb..a3a2cd55e23a9caa288663e69243db71cdf211fc 100644 (file)
@@ -1252,7 +1252,7 @@ static struct l2cap_chan *l2cap_sock_new_connection_cb(struct l2cap_chan *chan)
 
        l2cap_sock_init(sk, parent);
 
-       bt_accept_enqueue(parent, sk);
+       bt_accept_enqueue(parent, sk, false);
 
        release_sock(parent);
 
index 1a635df80643707b31a4db2b7f3ef5953bc4b4fc..3a9e9d9670be4c4b617e5c9bcaca28ed0d82cf53 100644 (file)
@@ -483,6 +483,7 @@ static int __rfcomm_dlc_close(struct rfcomm_dlc *d, int err)
                /* if closing a dlc in a session that hasn't been started,
                 * just close and unlink the dlc
                 */
+               /* fall through */
 
        default:
                rfcomm_dlc_clear_timer(d);
index aa0db1d1bd9b4132963d1b78459426bfba300f76..b1f49fcc04780e15d27b5daab6a95ec6385c8b39 100644 (file)
@@ -988,7 +988,7 @@ int rfcomm_connect_ind(struct rfcomm_session *s, u8 channel, struct rfcomm_dlc *
        rfcomm_pi(sk)->channel = channel;
 
        sk->sk_state = BT_CONFIG;
-       bt_accept_enqueue(parent, sk);
+       bt_accept_enqueue(parent, sk, true);
 
        /* Accept connection and return socket DLC */
        *d = rfcomm_pi(sk)->dlc;
index 529b38996d8bce4a657e8b4e15d2140b4a6c1cda..9a580999ca57e3037336bbcdb321dbb4ef0cb196 100644 (file)
@@ -193,7 +193,7 @@ static void __sco_chan_add(struct sco_conn *conn, struct sock *sk,
        conn->sk = sk;
 
        if (parent)
-               bt_accept_enqueue(parent, sk);
+               bt_accept_enqueue(parent, sk, true);
 }
 
 static int sco_chan_add(struct sco_conn *conn, struct sock *sk,