diff mbox series

Bluetooth: Add support for reading AOSP vendor capabilities

Message ID 20210406133632.241599-1-marcel@holtmann.org (mailing list archive)
State Accepted
Delegated to: Luiz Von Dentz
Headers show
Series Bluetooth: Add support for reading AOSP vendor capabilities | expand

Commit Message

Marcel Holtmann April 6, 2021, 1:36 p.m. UTC
When drivers indicate support for AOSP vendor extension, initialize them
and read its capabilities.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
 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

Comments

kernel test robot April 6, 2021, 5:41 p.m. UTC | #1
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 <lkp@intel.com>

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/kbuild-all@lists.01.org
kernel test robot April 6, 2021, 6:41 p.m. UTC | #2
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 <lkp@intel.com>

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/kbuild-all@lists.01.org
diff mbox series

Patch

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)