2021-04-07 03:47:40

by Marcel Holtmann

[permalink] [raw]
Subject: [PATCH] Bluetooth: Add support for reading AOSP vendor capabilities

When drivers indicate support for AOSP vendor extension, initialize them
and read its capabilities.

Signed-off-by: Marcel Holtmann <[email protected]>
---
include/net/bluetooth/hci_core.h | 11 ++++++++++
net/bluetooth/Kconfig | 7 +++++++
net/bluetooth/Makefile | 1 +
net/bluetooth/aosp.c | 35 ++++++++++++++++++++++++++++++++
net/bluetooth/aosp.h | 16 +++++++++++++++
net/bluetooth/hci_core.c | 3 +++
6 files changed, 73 insertions(+)
create mode 100644 net/bluetooth/aosp.c
create mode 100644 net/bluetooth/aosp.h

diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 1101589422d8..29f609b67f22 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -596,6 +596,10 @@ struct hci_dev {
void *msft_data;
#endif

+#if IS_ENABLED(CONFIG_BT_AOSPEXT)
+ bool aosp_capable;
+#endif
+
int (*open)(struct hci_dev *hdev);
int (*close)(struct hci_dev *hdev);
int (*flush)(struct hci_dev *hdev);
@@ -1248,6 +1252,13 @@ static inline void hci_set_msft_opcode(struct hci_dev *hdev, __u16 opcode)
#endif
}

+static inline void hci_set_aosp_capable(struct hci_dev *hdev)
+{
+#if IS_ENABLED(CONFIG_BT_AOSPEXT)
+ hdev->aosp_capable = true;
+#endif
+}
+
int hci_dev_open(__u16 dev);
int hci_dev_close(__u16 dev);
int hci_dev_do_close(struct hci_dev *hdev);
diff --git a/net/bluetooth/Kconfig b/net/bluetooth/Kconfig
index 400c5130dc0a..e0ab4cd7afc3 100644
--- a/net/bluetooth/Kconfig
+++ b/net/bluetooth/Kconfig
@@ -99,6 +99,13 @@ config BT_MSFTEXT
This options enables support for the Microsoft defined HCI
vendor extensions.

+config BT_AOSPEXT
+ bool "Enable Android Open Source Project extensions"
+ depends on BT
+ help
+ This options enables support for the Android Open Source
+ Project defined HCI vendor extensions.
+
config BT_DEBUGFS
bool "Export Bluetooth internals in debugfs"
depends on BT && DEBUG_FS
diff --git a/net/bluetooth/Makefile b/net/bluetooth/Makefile
index 1c645fba8c49..cc0995301f93 100644
--- a/net/bluetooth/Makefile
+++ b/net/bluetooth/Makefile
@@ -20,5 +20,6 @@ bluetooth-$(CONFIG_BT_BREDR) += sco.o
bluetooth-$(CONFIG_BT_HS) += a2mp.o amp.o
bluetooth-$(CONFIG_BT_LEDS) += leds.o
bluetooth-$(CONFIG_BT_MSFTEXT) += msft.o
+bluetooth-$(CONFIG_BT_AOSPEXT) += aosp.o
bluetooth-$(CONFIG_BT_DEBUGFS) += hci_debugfs.o
bluetooth-$(CONFIG_BT_SELFTEST) += selftest.o
diff --git a/net/bluetooth/aosp.c b/net/bluetooth/aosp.c
new file mode 100644
index 000000000000..a1b7762335a5
--- /dev/null
+++ b/net/bluetooth/aosp.c
@@ -0,0 +1,35 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2021 Intel Corporation
+ */
+
+#include <net/bluetooth/bluetooth.h>
+#include <net/bluetooth/hci_core.h>
+
+#include "aosp.h"
+
+void aosp_do_open(struct hci_dev *hdev)
+{
+ struct sk_buff *skb;
+
+ if (!hdev->aosp_capable)
+ return;
+
+ bt_dev_dbg(hdev, "Initialize AOSP extension");
+
+ /* LE Get Vendor Capabilities Command */
+ skb = __hci_cmd_sync(hdev, hci_opcode_pack(0x3f, 0x153), 0, NULL,
+ HCI_CMD_TIMEOUT);
+ if (IS_ERR(skb))
+ return;
+
+ kfree_skb(skb);
+}
+
+void aosp_do_close(struct hci_dev *hdev)
+{
+ if (!hdev->aosp_capable)
+ return;
+
+ bt_dev_dbg(hdev, "Cleanup of AOSP extension");
+}
diff --git a/net/bluetooth/aosp.h b/net/bluetooth/aosp.h
new file mode 100644
index 000000000000..d5603afeb718
--- /dev/null
+++ b/net/bluetooth/aosp.h
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2021 Intel Corporation
+ */
+
+#if IS_ENABLED(CONFIG_BT_AOSPEXT)
+
+void aosp_do_open(struct hci_dev *hdev);
+void aosp_do_close(struct hci_dev *hdev);
+
+#else
+
+static inline void msft_do_open(struct hci_dev *hdev) {}
+static inline void msft_do_close(struct hci_dev *hdev) {}
+
+#endif
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 520718d7679b..37a6c566aa62 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -44,6 +44,7 @@
#include "smp.h"
#include "leds.h"
#include "msft.h"
+#include "aosp.h"

static void hci_rx_work(struct work_struct *work);
static void hci_cmd_work(struct work_struct *work);
@@ -1586,6 +1587,7 @@ static int hci_dev_do_open(struct hci_dev *hdev)
ret = hdev->set_diag(hdev, true);

msft_do_open(hdev);
+ aosp_do_open(hdev);

clear_bit(HCI_INIT, &hdev->flags);

@@ -1782,6 +1784,7 @@ int hci_dev_do_close(struct hci_dev *hdev)

hci_sock_dev_event(hdev, HCI_DEV_DOWN);

+ aosp_do_close(hdev);
msft_do_close(hdev);

if (hdev->flush)
--
2.30.2


2021-04-07 08:17:24

by kernel test robot

[permalink] [raw]
Subject: Re: [PATCH] Bluetooth: Add support for reading AOSP vendor capabilities

Hi Marcel,

I love your patch! Yet something to improve:

[auto build test ERROR on bluetooth-next/master]
[also build test ERROR on v5.12-rc6 next-20210406]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url: https://github.com/0day-ci/linux/commits/Marcel-Holtmann/Bluetooth-Add-support-for-reading-AOSP-vendor-capabilities/20210406-213836
base: https://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next.git master
config: m68k-randconfig-r023-20210406 (attached as .config)
compiler: m68k-linux-gcc (GCC) 9.3.0
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# https://github.com/0day-ci/linux/commit/71e8a18c61c482db0f170ec897450ba76c18b7ec
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Marcel-Holtmann/Bluetooth-Add-support-for-reading-AOSP-vendor-capabilities/20210406-213836
git checkout 71e8a18c61c482db0f170ec897450ba76c18b7ec
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=m68k

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <[email protected]>

All errors (new ones prefixed by >>):

In file included from net/bluetooth/hci_core.c:47:
>> net/bluetooth/aosp.h:13:20: error: static declaration of 'msft_do_open' follows non-static declaration
13 | static inline void msft_do_open(struct hci_dev *hdev) {}
| ^~~~~~~~~~~~
In file included from net/bluetooth/hci_core.c:46:
net/bluetooth/msft.h:16:6: note: previous declaration of 'msft_do_open' was here
16 | void msft_do_open(struct hci_dev *hdev);
| ^~~~~~~~~~~~
In file included from net/bluetooth/hci_core.c:47:
>> net/bluetooth/aosp.h:14:20: error: static declaration of 'msft_do_close' follows non-static declaration
14 | static inline void msft_do_close(struct hci_dev *hdev) {}
| ^~~~~~~~~~~~~
In file included from net/bluetooth/hci_core.c:46:
net/bluetooth/msft.h:17:6: note: previous declaration of 'msft_do_close' was here
17 | void msft_do_close(struct hci_dev *hdev);
| ^~~~~~~~~~~~~
net/bluetooth/hci_core.c: In function 'hci_dev_do_open':
>> net/bluetooth/hci_core.c:1590:2: error: implicit declaration of function 'aosp_do_open'; did you mean 'msft_do_open'? [-Werror=implicit-function-declaration]
1590 | aosp_do_open(hdev);
| ^~~~~~~~~~~~
| msft_do_open
net/bluetooth/hci_core.c: In function 'hci_dev_do_close':
>> net/bluetooth/hci_core.c:1787:2: error: implicit declaration of function 'aosp_do_close'; did you mean 'msft_do_close'? [-Werror=implicit-function-declaration]
1787 | aosp_do_close(hdev);
| ^~~~~~~~~~~~~
| msft_do_close
cc1: some warnings being treated as errors


vim +/msft_do_open +13 net/bluetooth/aosp.h

12
> 13 static inline void msft_do_open(struct hci_dev *hdev) {}
> 14 static inline void msft_do_close(struct hci_dev *hdev) {}
15

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/[email protected]


Attachments:
(No filename) (3.42 kB)
.config.gz (26.41 kB)
Download all attachments

2021-04-07 10:31:04

by kernel test robot

[permalink] [raw]
Subject: Re: [PATCH] Bluetooth: Add support for reading AOSP vendor capabilities

Hi Marcel,

I love your patch! Yet something to improve:

[auto build test ERROR on bluetooth-next/master]
[also build test ERROR on v5.12-rc6 next-20210406]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url: https://github.com/0day-ci/linux/commits/Marcel-Holtmann/Bluetooth-Add-support-for-reading-AOSP-vendor-capabilities/20210406-213836
base: https://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next.git master
config: powerpc-randconfig-r012-20210406 (attached as .config)
compiler: clang version 13.0.0 (https://github.com/llvm/llvm-project a46f59a747a7273cc439efaf3b4f98d8b63d2f20)
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# install powerpc cross compiling tool for clang build
# apt-get install binutils-powerpc-linux-gnu
# https://github.com/0day-ci/linux/commit/71e8a18c61c482db0f170ec897450ba76c18b7ec
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Marcel-Holtmann/Bluetooth-Add-support-for-reading-AOSP-vendor-capabilities/20210406-213836
git checkout 71e8a18c61c482db0f170ec897450ba76c18b7ec
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=powerpc

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <[email protected]>

All errors (new ones prefixed by >>):

In file included from include/linux/io.h:13:
In file included from arch/powerpc/include/asm/io.h:619:
arch/powerpc/include/asm/io-defs.h:47:1: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
DEF_PCI_AC_NORET(insl, (unsigned long p, void *b, unsigned long c),
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/io.h:616:3: note: expanded from macro 'DEF_PCI_AC_NORET'
__do_##name al; \
^~~~~~~~~~~~~~
<scratch space>:42:1: note: expanded from here
__do_insl
^
arch/powerpc/include/asm/io.h:558:56: note: expanded from macro '__do_insl'
#define __do_insl(p, b, n) readsl((PCI_IO_ADDR)_IO_BASE+(p), (b), (n))
~~~~~~~~~~~~~~~~~~~~~^
In file included from net/bluetooth/hci_core.c:33:
In file included from include/linux/suspend.h:5:
In file included from include/linux/swap.h:9:
In file included from include/linux/memcontrol.h:13:
In file included from include/linux/cgroup.h:26:
In file included from include/linux/kernel_stat.h:9:
In file included from include/linux/interrupt.h:11:
In file included from include/linux/hardirq.h:10:
In file included from arch/powerpc/include/asm/hardirq.h:6:
In file included from include/linux/irq.h:20:
In file included from include/linux/io.h:13:
In file included from arch/powerpc/include/asm/io.h:619:
arch/powerpc/include/asm/io-defs.h:49:1: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
DEF_PCI_AC_NORET(outsb, (unsigned long p, const void *b, unsigned long c),
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/io.h:616:3: note: expanded from macro 'DEF_PCI_AC_NORET'
__do_##name al; \
^~~~~~~~~~~~~~
<scratch space>:44:1: note: expanded from here
__do_outsb
^
arch/powerpc/include/asm/io.h:559:58: note: expanded from macro '__do_outsb'
#define __do_outsb(p, b, n) writesb((PCI_IO_ADDR)_IO_BASE+(p),(b),(n))
~~~~~~~~~~~~~~~~~~~~~^
In file included from net/bluetooth/hci_core.c:33:
In file included from include/linux/suspend.h:5:
In file included from include/linux/swap.h:9:
In file included from include/linux/memcontrol.h:13:
In file included from include/linux/cgroup.h:26:
In file included from include/linux/kernel_stat.h:9:
In file included from include/linux/interrupt.h:11:
In file included from include/linux/hardirq.h:10:
In file included from arch/powerpc/include/asm/hardirq.h:6:
In file included from include/linux/irq.h:20:
In file included from include/linux/io.h:13:
In file included from arch/powerpc/include/asm/io.h:619:
arch/powerpc/include/asm/io-defs.h:51:1: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
DEF_PCI_AC_NORET(outsw, (unsigned long p, const void *b, unsigned long c),
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/io.h:616:3: note: expanded from macro 'DEF_PCI_AC_NORET'
__do_##name al; \
^~~~~~~~~~~~~~
<scratch space>:46:1: note: expanded from here
__do_outsw
^
arch/powerpc/include/asm/io.h:560:58: note: expanded from macro '__do_outsw'
#define __do_outsw(p, b, n) writesw((PCI_IO_ADDR)_IO_BASE+(p),(b),(n))
~~~~~~~~~~~~~~~~~~~~~^
In file included from net/bluetooth/hci_core.c:33:
In file included from include/linux/suspend.h:5:
In file included from include/linux/swap.h:9:
In file included from include/linux/memcontrol.h:13:
In file included from include/linux/cgroup.h:26:
In file included from include/linux/kernel_stat.h:9:
In file included from include/linux/interrupt.h:11:
In file included from include/linux/hardirq.h:10:
In file included from arch/powerpc/include/asm/hardirq.h:6:
In file included from include/linux/irq.h:20:
In file included from include/linux/io.h:13:
In file included from arch/powerpc/include/asm/io.h:619:
arch/powerpc/include/asm/io-defs.h:53:1: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
DEF_PCI_AC_NORET(outsl, (unsigned long p, const void *b, unsigned long c),
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/io.h:616:3: note: expanded from macro 'DEF_PCI_AC_NORET'
__do_##name al; \
^~~~~~~~~~~~~~
<scratch space>:48:1: note: expanded from here
__do_outsl
^
arch/powerpc/include/asm/io.h:561:58: note: expanded from macro '__do_outsl'
#define __do_outsl(p, b, n) writesl((PCI_IO_ADDR)_IO_BASE+(p),(b),(n))
~~~~~~~~~~~~~~~~~~~~~^
In file included from net/bluetooth/hci_core.c:47:
net/bluetooth/aosp.h:13:20: error: redefinition of 'msft_do_open'
static inline void msft_do_open(struct hci_dev *hdev) {}
^
net/bluetooth/msft.h:33:20: note: previous definition is here
static inline void msft_do_open(struct hci_dev *hdev) {}
^
In file included from net/bluetooth/hci_core.c:47:
net/bluetooth/aosp.h:14:20: error: redefinition of 'msft_do_close'
static inline void msft_do_close(struct hci_dev *hdev) {}
^
net/bluetooth/msft.h:34:20: note: previous definition is here
static inline void msft_do_close(struct hci_dev *hdev) {}
^
>> net/bluetooth/hci_core.c:1590:2: error: implicit declaration of function 'aosp_do_open' [-Werror,-Wimplicit-function-declaration]
aosp_do_open(hdev);
^
net/bluetooth/hci_core.c:1590:2: note: did you mean 'msft_do_open'?
net/bluetooth/aosp.h:13:20: note: 'msft_do_open' declared here
static inline void msft_do_open(struct hci_dev *hdev) {}
^
>> net/bluetooth/hci_core.c:1787:2: error: implicit declaration of function 'aosp_do_close' [-Werror,-Wimplicit-function-declaration]
aosp_do_close(hdev);
^
net/bluetooth/hci_core.c:1787:2: note: did you mean 'msft_do_close'?
net/bluetooth/aosp.h:14:20: note: 'msft_do_close' declared here
static inline void msft_do_close(struct hci_dev *hdev) {}
^
12 warnings and 4 errors generated.


vim +/aosp_do_open +1590 net/bluetooth/hci_core.c

1432
1433 static int hci_dev_do_open(struct hci_dev *hdev)
1434 {
1435 int ret = 0;
1436
1437 BT_DBG("%s %p", hdev->name, hdev);
1438
1439 hci_req_sync_lock(hdev);
1440
1441 if (hci_dev_test_flag(hdev, HCI_UNREGISTER)) {
1442 ret = -ENODEV;
1443 goto done;
1444 }
1445
1446 if (!hci_dev_test_flag(hdev, HCI_SETUP) &&
1447 !hci_dev_test_flag(hdev, HCI_CONFIG)) {
1448 /* Check for rfkill but allow the HCI setup stage to
1449 * proceed (which in itself doesn't cause any RF activity).
1450 */
1451 if (hci_dev_test_flag(hdev, HCI_RFKILLED)) {
1452 ret = -ERFKILL;
1453 goto done;
1454 }
1455
1456 /* Check for valid public address or a configured static
1457 * random adddress, but let the HCI setup proceed to
1458 * be able to determine if there is a public address
1459 * or not.
1460 *
1461 * In case of user channel usage, it is not important
1462 * if a public address or static random address is
1463 * available.
1464 *
1465 * This check is only valid for BR/EDR controllers
1466 * since AMP controllers do not have an address.
1467 */
1468 if (!hci_dev_test_flag(hdev, HCI_USER_CHANNEL) &&
1469 hdev->dev_type == HCI_PRIMARY &&
1470 !bacmp(&hdev->bdaddr, BDADDR_ANY) &&
1471 !bacmp(&hdev->static_addr, BDADDR_ANY)) {
1472 ret = -EADDRNOTAVAIL;
1473 goto done;
1474 }
1475 }
1476
1477 if (test_bit(HCI_UP, &hdev->flags)) {
1478 ret = -EALREADY;
1479 goto done;
1480 }
1481
1482 if (hdev->open(hdev)) {
1483 ret = -EIO;
1484 goto done;
1485 }
1486
1487 set_bit(HCI_RUNNING, &hdev->flags);
1488 hci_sock_dev_event(hdev, HCI_DEV_OPEN);
1489
1490 atomic_set(&hdev->cmd_cnt, 1);
1491 set_bit(HCI_INIT, &hdev->flags);
1492
1493 if (hci_dev_test_flag(hdev, HCI_SETUP) ||
1494 test_bit(HCI_QUIRK_NON_PERSISTENT_SETUP, &hdev->quirks)) {
1495 bool invalid_bdaddr;
1496
1497 hci_sock_dev_event(hdev, HCI_DEV_SETUP);
1498
1499 if (hdev->setup)
1500 ret = hdev->setup(hdev);
1501
1502 /* The transport driver can set the quirk to mark the
1503 * BD_ADDR invalid before creating the HCI device or in
1504 * its setup callback.
1505 */
1506 invalid_bdaddr = test_bit(HCI_QUIRK_INVALID_BDADDR,
1507 &hdev->quirks);
1508
1509 if (ret)
1510 goto setup_failed;
1511
1512 if (test_bit(HCI_QUIRK_USE_BDADDR_PROPERTY, &hdev->quirks)) {
1513 if (!bacmp(&hdev->public_addr, BDADDR_ANY))
1514 hci_dev_get_bd_addr_from_property(hdev);
1515
1516 if (bacmp(&hdev->public_addr, BDADDR_ANY) &&
1517 hdev->set_bdaddr) {
1518 ret = hdev->set_bdaddr(hdev,
1519 &hdev->public_addr);
1520
1521 /* If setting of the BD_ADDR from the device
1522 * property succeeds, then treat the address
1523 * as valid even if the invalid BD_ADDR
1524 * quirk indicates otherwise.
1525 */
1526 if (!ret)
1527 invalid_bdaddr = false;
1528 }
1529 }
1530
1531 setup_failed:
1532 /* The transport driver can set these quirks before
1533 * creating the HCI device or in its setup callback.
1534 *
1535 * For the invalid BD_ADDR quirk it is possible that
1536 * it becomes a valid address if the bootloader does
1537 * provide it (see above).
1538 *
1539 * In case any of them is set, the controller has to
1540 * start up as unconfigured.
1541 */
1542 if (test_bit(HCI_QUIRK_EXTERNAL_CONFIG, &hdev->quirks) ||
1543 invalid_bdaddr)
1544 hci_dev_set_flag(hdev, HCI_UNCONFIGURED);
1545
1546 /* For an unconfigured controller it is required to
1547 * read at least the version information provided by
1548 * the Read Local Version Information command.
1549 *
1550 * If the set_bdaddr driver callback is provided, then
1551 * also the original Bluetooth public device address
1552 * will be read using the Read BD Address command.
1553 */
1554 if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED))
1555 ret = __hci_unconf_init(hdev);
1556 }
1557
1558 if (hci_dev_test_flag(hdev, HCI_CONFIG)) {
1559 /* If public address change is configured, ensure that
1560 * the address gets programmed. If the driver does not
1561 * support changing the public address, fail the power
1562 * on procedure.
1563 */
1564 if (bacmp(&hdev->public_addr, BDADDR_ANY) &&
1565 hdev->set_bdaddr)
1566 ret = hdev->set_bdaddr(hdev, &hdev->public_addr);
1567 else
1568 ret = -EADDRNOTAVAIL;
1569 }
1570
1571 if (!ret) {
1572 if (!hci_dev_test_flag(hdev, HCI_UNCONFIGURED) &&
1573 !hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
1574 ret = __hci_init(hdev);
1575 if (!ret && hdev->post_init)
1576 ret = hdev->post_init(hdev);
1577 }
1578 }
1579
1580 /* If the HCI Reset command is clearing all diagnostic settings,
1581 * then they need to be reprogrammed after the init procedure
1582 * completed.
1583 */
1584 if (test_bit(HCI_QUIRK_NON_PERSISTENT_DIAG, &hdev->quirks) &&
1585 !hci_dev_test_flag(hdev, HCI_USER_CHANNEL) &&
1586 hci_dev_test_flag(hdev, HCI_VENDOR_DIAG) && hdev->set_diag)
1587 ret = hdev->set_diag(hdev, true);
1588
1589 msft_do_open(hdev);
> 1590 aosp_do_open(hdev);
1591
1592 clear_bit(HCI_INIT, &hdev->flags);
1593
1594 if (!ret) {
1595 hci_dev_hold(hdev);
1596 hci_dev_set_flag(hdev, HCI_RPA_EXPIRED);
1597 hci_adv_instances_set_rpa_expired(hdev, true);
1598 set_bit(HCI_UP, &hdev->flags);
1599 hci_sock_dev_event(hdev, HCI_DEV_UP);
1600 hci_leds_update_powered(hdev, true);
1601 if (!hci_dev_test_flag(hdev, HCI_SETUP) &&
1602 !hci_dev_test_flag(hdev, HCI_CONFIG) &&
1603 !hci_dev_test_flag(hdev, HCI_UNCONFIGURED) &&
1604 !hci_dev_test_flag(hdev, HCI_USER_CHANNEL) &&
1605 hci_dev_test_flag(hdev, HCI_MGMT) &&
1606 hdev->dev_type == HCI_PRIMARY) {
1607 ret = __hci_req_hci_power_on(hdev);
1608 mgmt_power_on(hdev, ret);
1609 }
1610 } else {
1611 /* Init failed, cleanup */
1612 flush_work(&hdev->tx_work);
1613 flush_work(&hdev->cmd_work);
1614 flush_work(&hdev->rx_work);
1615
1616 skb_queue_purge(&hdev->cmd_q);
1617 skb_queue_purge(&hdev->rx_q);
1618
1619 if (hdev->flush)
1620 hdev->flush(hdev);
1621
1622 if (hdev->sent_cmd) {
1623 kfree_skb(hdev->sent_cmd);
1624 hdev->sent_cmd = NULL;
1625 }
1626
1627 clear_bit(HCI_RUNNING, &hdev->flags);
1628 hci_sock_dev_event(hdev, HCI_DEV_CLOSE);
1629
1630 hdev->close(hdev);
1631 hdev->flags &= BIT(HCI_RAW);
1632 }
1633
1634 done:
1635 hci_req_sync_unlock(hdev);
1636 return ret;
1637 }
1638
1639 /* ---- HCI ioctl helpers ---- */
1640
1641 int hci_dev_open(__u16 dev)
1642 {
1643 struct hci_dev *hdev;
1644 int err;
1645
1646 hdev = hci_dev_get(dev);
1647 if (!hdev)
1648 return -ENODEV;
1649
1650 /* Devices that are marked as unconfigured can only be powered
1651 * up as user channel. Trying to bring them up as normal devices
1652 * will result into a failure. Only user channel operation is
1653 * possible.
1654 *
1655 * When this function is called for a user channel, the flag
1656 * HCI_USER_CHANNEL will be set first before attempting to
1657 * open the device.
1658 */
1659 if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED) &&
1660 !hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
1661 err = -EOPNOTSUPP;
1662 goto done;
1663 }
1664
1665 /* We need to ensure that no other power on/off work is pending
1666 * before proceeding to call hci_dev_do_open. This is
1667 * particularly important if the setup procedure has not yet
1668 * completed.
1669 */
1670 if (hci_dev_test_and_clear_flag(hdev, HCI_AUTO_OFF))
1671 cancel_delayed_work(&hdev->power_off);
1672
1673 /* After this call it is guaranteed that the setup procedure
1674 * has finished. This means that error conditions like RFKILL
1675 * or no valid public or static random address apply.
1676 */
1677 flush_workqueue(hdev->req_workqueue);
1678
1679 /* For controllers not using the management interface and that
1680 * are brought up using legacy ioctl, set the HCI_BONDABLE bit
1681 * so that pairing works for them. Once the management interface
1682 * is in use this bit will be cleared again and userspace has
1683 * to explicitly enable it.
1684 */
1685 if (!hci_dev_test_flag(hdev, HCI_USER_CHANNEL) &&
1686 !hci_dev_test_flag(hdev, HCI_MGMT))
1687 hci_dev_set_flag(hdev, HCI_BONDABLE);
1688
1689 err = hci_dev_do_open(hdev);
1690
1691 done:
1692 hci_dev_put(hdev);
1693 return err;
1694 }
1695
1696 /* This function requires the caller holds hdev->lock */
1697 static void hci_pend_le_actions_clear(struct hci_dev *hdev)
1698 {
1699 struct hci_conn_params *p;
1700
1701 list_for_each_entry(p, &hdev->le_conn_params, list) {
1702 if (p->conn) {
1703 hci_conn_drop(p->conn);
1704 hci_conn_put(p->conn);
1705 p->conn = NULL;
1706 }
1707 list_del_init(&p->action);
1708 }
1709
1710 BT_DBG("All LE pending actions cleared");
1711 }
1712
1713 int hci_dev_do_close(struct hci_dev *hdev)
1714 {
1715 bool auto_off;
1716
1717 BT_DBG("%s %p", hdev->name, hdev);
1718
1719 if (!hci_dev_test_flag(hdev, HCI_UNREGISTER) &&
1720 !hci_dev_test_flag(hdev, HCI_USER_CHANNEL) &&
1721 test_bit(HCI_UP, &hdev->flags)) {
1722 /* Execute vendor specific shutdown routine */
1723 if (hdev->shutdown)
1724 hdev->shutdown(hdev);
1725 }
1726
1727 cancel_delayed_work(&hdev->power_off);
1728
1729 hci_request_cancel_all(hdev);
1730 hci_req_sync_lock(hdev);
1731
1732 if (!test_and_clear_bit(HCI_UP, &hdev->flags)) {
1733 cancel_delayed_work_sync(&hdev->cmd_timer);
1734 hci_req_sync_unlock(hdev);
1735 return 0;
1736 }
1737
1738 hci_leds_update_powered(hdev, false);
1739
1740 /* Flush RX and TX works */
1741 flush_work(&hdev->tx_work);
1742 flush_work(&hdev->rx_work);
1743
1744 if (hdev->discov_timeout > 0) {
1745 hdev->discov_timeout = 0;
1746 hci_dev_clear_flag(hdev, HCI_DISCOVERABLE);
1747 hci_dev_clear_flag(hdev, HCI_LIMITED_DISCOVERABLE);
1748 }
1749
1750 if (hci_dev_test_and_clear_flag(hdev, HCI_SERVICE_CACHE))
1751 cancel_delayed_work(&hdev->service_cache);
1752
1753 if (hci_dev_test_flag(hdev, HCI_MGMT)) {
1754 struct adv_info *adv_instance;
1755
1756 cancel_delayed_work_sync(&hdev->rpa_expired);
1757
1758 list_for_each_entry(adv_instance, &hdev->adv_instances, list)
1759 cancel_delayed_work_sync(&adv_instance->rpa_expired_cb);
1760 }
1761
1762 /* Avoid potential lockdep warnings from the *_flush() calls by
1763 * ensuring the workqueue is empty up front.
1764 */
1765 drain_workqueue(hdev->workqueue);
1766
1767 hci_dev_lock(hdev);
1768
1769 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1770
1771 auto_off = hci_dev_test_and_clear_flag(hdev, HCI_AUTO_OFF);
1772
1773 if (!auto_off && hdev->dev_type == HCI_PRIMARY &&
1774 !hci_dev_test_flag(hdev, HCI_USER_CHANNEL) &&
1775 hci_dev_test_flag(hdev, HCI_MGMT))
1776 __mgmt_power_off(hdev);
1777
1778 hci_inquiry_cache_flush(hdev);
1779 hci_pend_le_actions_clear(hdev);
1780 hci_conn_hash_flush(hdev);
1781 hci_dev_unlock(hdev);
1782
1783 smp_unregister(hdev);
1784
1785 hci_sock_dev_event(hdev, HCI_DEV_DOWN);
1786
> 1787 aosp_do_close(hdev);
1788 msft_do_close(hdev);
1789
1790 if (hdev->flush)
1791 hdev->flush(hdev);
1792
1793 /* Reset device */
1794 skb_queue_purge(&hdev->cmd_q);
1795 atomic_set(&hdev->cmd_cnt, 1);
1796 if (test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks) &&
1797 !auto_off && !hci_dev_test_flag(hdev, HCI_UNCONFIGURED)) {
1798 set_bit(HCI_INIT, &hdev->flags);
1799 __hci_req_sync(hdev, hci_reset_req, 0, HCI_CMD_TIMEOUT, NULL);
1800 clear_bit(HCI_INIT, &hdev->flags);
1801 }
1802
1803 /* flush cmd work */
1804 flush_work(&hdev->cmd_work);
1805
1806 /* Drop queues */
1807 skb_queue_purge(&hdev->rx_q);
1808 skb_queue_purge(&hdev->cmd_q);
1809 skb_queue_purge(&hdev->raw_q);
1810
1811 /* Drop last sent command */
1812 if (hdev->sent_cmd) {
1813 cancel_delayed_work_sync(&hdev->cmd_timer);
1814 kfree_skb(hdev->sent_cmd);
1815 hdev->sent_cmd = NULL;
1816 }
1817
1818 clear_bit(HCI_RUNNING, &hdev->flags);
1819 hci_sock_dev_event(hdev, HCI_DEV_CLOSE);
1820
1821 if (test_and_clear_bit(SUSPEND_POWERING_DOWN, hdev->suspend_tasks))
1822 wake_up(&hdev->suspend_wait_q);
1823
1824 /* After this point our queues are empty
1825 * and no tasks are scheduled. */
1826 hdev->close(hdev);
1827
1828 /* Clear flags */
1829 hdev->flags &= BIT(HCI_RAW);
1830 hci_dev_clear_volatile_flags(hdev);
1831
1832 /* Controller radio is available but is currently powered down */
1833 hdev->amp_status = AMP_STATUS_POWERED_DOWN;
1834
1835 memset(hdev->eir, 0, sizeof(hdev->eir));
1836 memset(hdev->dev_class, 0, sizeof(hdev->dev_class));
1837 bacpy(&hdev->random_addr, BDADDR_ANY);
1838
1839 hci_req_sync_unlock(hdev);
1840
1841 hci_dev_put(hdev);
1842 return 0;
1843 }
1844

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/[email protected]


Attachments:
(No filename) (22.41 kB)
.config.gz (36.98 kB)
Download all attachments