Linux bluetooth development
 help / color / mirror / Atom feed
* [PATCH v2] Bluetooth: Add support for setting SSP debug mode
From: Marcel Holtmann @ 2013-10-19  9:13 UTC (permalink / raw)
  To: linux-bluetooth

Enabling and disabling SSP debug mode is useful for development. This
adds a debugfs entry that allows to configure the SSP debug mode.

On purpose this has been implemented as debugfs entry and not a public
API since it is really only useful during testing and development.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
 include/net/bluetooth/hci.h      |  2 ++
 include/net/bluetooth/hci_core.h |  1 +
 net/bluetooth/hci_core.c         | 53 +++++++++++++++++++++++++++++++++++++++-
 net/bluetooth/hci_event.c        |  2 ++
 4 files changed, 57 insertions(+), 1 deletion(-)

diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index 77a971a..ac9c4a7 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -1043,6 +1043,8 @@ struct hci_rp_write_remote_amp_assoc {
 	__u8     phy_handle;
 } __packed;
 
+#define HCI_OP_WRITE_SSP_DEBUG_MODE	0x1804
+
 #define HCI_OP_LE_SET_EVENT_MASK	0x2001
 struct hci_cp_le_set_event_mask {
 	__u8     mask[8];
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 0daac39..f621c5b 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -169,6 +169,7 @@ struct hci_dev {
 	__u8		page_scan_type;
 	__u16		le_scan_interval;
 	__u16		le_scan_window;
+	__u8		ssp_debug_mode;
 
 	__u16		devid_source;
 	__u16		devid_vendor;
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 94d5342..8aae80b 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -296,6 +296,54 @@ static int auto_accept_delay_get(void *data, u64 *val)
 DEFINE_SIMPLE_ATTRIBUTE(auto_accept_delay_fops, auto_accept_delay_get,
 			auto_accept_delay_set, "%llu\n");
 
+static int ssp_debug_mode_set(void *data, u64 val)
+{
+	struct hci_dev *hdev = data;
+	struct sk_buff *skb;
+	__u8 mode;
+
+	if (val != 0 && val != 1)
+		return -EINVAL;
+
+	if (!test_bit(HCI_UP, &hdev->flags))
+		return -ENETDOWN;
+
+	hci_req_lock(hdev);
+	mode = val;
+	skb = __hci_cmd_sync(hdev, HCI_OP_WRITE_SSP_DEBUG_MODE, sizeof(mode),
+			     &mode, HCI_CMD_TIMEOUT);
+	hci_req_unlock(hdev);
+
+	if (IS_ERR(skb))
+		return PTR_ERR(skb);
+
+	if (skb->data[0]) {
+		u8 status = skb->data[0];
+		kfree_skb(skb);
+		return -bt_to_errno(status);
+	}
+
+	hci_dev_lock(hdev);
+	hdev->ssp_debug_mode = val;
+	hci_dev_unlock(hdev);
+
+	return 0;
+}
+
+static int ssp_debug_mode_get(void *data, u64 *val)
+{
+	struct hci_dev *hdev = data;
+
+	hci_dev_lock(hdev);
+	*val = hdev->ssp_debug_mode;
+	hci_dev_unlock(hdev);
+
+	return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(ssp_debug_mode_fops, ssp_debug_mode_get,
+			ssp_debug_mode_set, "%llu\n");
+
 static int idle_timeout_set(void *data, u64 val)
 {
 	struct hci_dev *hdev = data;
@@ -1192,9 +1240,12 @@ static int __hci_init(struct hci_dev *hdev)
 				    hdev, &voice_setting_fops);
 	}
 
-	if (lmp_ssp_capable(hdev))
+	if (lmp_ssp_capable(hdev)) {
 		debugfs_create_file("auto_accept_delay", 0644, hdev->debugfs,
 				    hdev, &auto_accept_delay_fops);
+		debugfs_create_file("ssp_debug_mode", 0644, hdev->debugfs,
+				    hdev, &ssp_debug_mode_fops);
+	}
 
 	if (lmp_sniff_capable(hdev)) {
 		debugfs_create_file("idle_timeout", 0644, hdev->debugfs,
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 8480452..83478da 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -198,6 +198,8 @@ static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb)
 
 	memset(hdev->scan_rsp_data, 0, sizeof(hdev->scan_rsp_data));
 	hdev->scan_rsp_data_len = 0;
+
+	hdev->ssp_debug_mode = 0;
 }
 
 static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb)
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH] Bluetooth: Add support for setting SSP debug mode
From: Marcel Holtmann @ 2013-10-19  9:06 UTC (permalink / raw)
  To: linux-bluetooth

Enabling and disabling SSP debug mode is useful for development. This
adds a debugfs entry that allows to configure the SSP debug mode.

On purpose this has been implemented as debugfs entry and not a public
API since it is really only useful during testing and development.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
 include/net/bluetooth/hci.h      |  2 ++
 include/net/bluetooth/hci_core.h |  1 +
 net/bluetooth/hci_core.c         | 53 +++++++++++++++++++++++++++++++++++++++-
 3 files changed, 55 insertions(+), 1 deletion(-)

diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index 77a971a..ac9c4a7 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -1043,6 +1043,8 @@ struct hci_rp_write_remote_amp_assoc {
 	__u8     phy_handle;
 } __packed;
 
+#define HCI_OP_WRITE_SSP_DEBUG_MODE	0x1804
+
 #define HCI_OP_LE_SET_EVENT_MASK	0x2001
 struct hci_cp_le_set_event_mask {
 	__u8     mask[8];
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 0daac39..f621c5b 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -169,6 +169,7 @@ struct hci_dev {
 	__u8		page_scan_type;
 	__u16		le_scan_interval;
 	__u16		le_scan_window;
+	__u8		ssp_debug_mode;
 
 	__u16		devid_source;
 	__u16		devid_vendor;
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 94d5342..8aae80b 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -296,6 +296,54 @@ static int auto_accept_delay_get(void *data, u64 *val)
 DEFINE_SIMPLE_ATTRIBUTE(auto_accept_delay_fops, auto_accept_delay_get,
 			auto_accept_delay_set, "%llu\n");
 
+static int ssp_debug_mode_set(void *data, u64 val)
+{
+	struct hci_dev *hdev = data;
+	struct sk_buff *skb;
+	__u8 mode;
+
+	if (val != 0 && val != 1)
+		return -EINVAL;
+
+	if (!test_bit(HCI_UP, &hdev->flags))
+		return -ENETDOWN;
+
+	hci_req_lock(hdev);
+	mode = val;
+	skb = __hci_cmd_sync(hdev, HCI_OP_WRITE_SSP_DEBUG_MODE, sizeof(mode),
+			     &mode, HCI_CMD_TIMEOUT);
+	hci_req_unlock(hdev);
+
+	if (IS_ERR(skb))
+		return PTR_ERR(skb);
+
+	if (skb->data[0]) {
+		u8 status = skb->data[0];
+		kfree_skb(skb);
+		return -bt_to_errno(status);
+	}
+
+	hci_dev_lock(hdev);
+	hdev->ssp_debug_mode = val;
+	hci_dev_unlock(hdev);
+
+	return 0;
+}
+
+static int ssp_debug_mode_get(void *data, u64 *val)
+{
+	struct hci_dev *hdev = data;
+
+	hci_dev_lock(hdev);
+	*val = hdev->ssp_debug_mode;
+	hci_dev_unlock(hdev);
+
+	return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(ssp_debug_mode_fops, ssp_debug_mode_get,
+			ssp_debug_mode_set, "%llu\n");
+
 static int idle_timeout_set(void *data, u64 val)
 {
 	struct hci_dev *hdev = data;
@@ -1192,9 +1240,12 @@ static int __hci_init(struct hci_dev *hdev)
 				    hdev, &voice_setting_fops);
 	}
 
-	if (lmp_ssp_capable(hdev))
+	if (lmp_ssp_capable(hdev)) {
 		debugfs_create_file("auto_accept_delay", 0644, hdev->debugfs,
 				    hdev, &auto_accept_delay_fops);
+		debugfs_create_file("ssp_debug_mode", 0644, hdev->debugfs,
+				    hdev, &ssp_debug_mode_fops);
+	}
 
 	if (lmp_sniff_capable(hdev)) {
 		debugfs_create_file("idle_timeout", 0644, hdev->debugfs,
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH] Bluetooth: Expose setting if debug keys are used or not
From: Marcel Holtmann @ 2013-10-19  0:14 UTC (permalink / raw)
  To: linux-bluetooth

The system can be figured to accept and use debug keys. Expose this
value in debugfs for debugging purposes.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
 net/bluetooth/hci_core.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index d47c8ec..94d5342 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -215,6 +215,24 @@ static const struct file_operations link_keys_fops = {
 	.release	= single_release,
 };
 
+static ssize_t use_debug_keys_read(struct file *file, char __user *user_buf,
+				   size_t count, loff_t *ppos)
+{
+	struct hci_dev *hdev = file->private_data;
+	char buf[3];
+
+	buf[0] = test_bit(HCI_DEBUG_KEYS, &hdev->dev_flags) ? 'Y': 'N';
+	buf[1] = '\n';
+	buf[2] = '\0';
+	return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
+}
+
+static const struct file_operations use_debug_keys_fops = {
+	.open		= simple_open,
+	.read		= use_debug_keys_read,
+	.llseek		= default_llseek,
+};
+
 static int dev_class_show(struct seq_file *f, void *ptr)
 {
 	struct hci_dev *hdev = f->private;
@@ -1166,6 +1184,8 @@ static int __hci_init(struct hci_dev *hdev)
 				    hdev, &inquiry_cache_fops);
 		debugfs_create_file("link_keys", 0400, hdev->debugfs,
 				    hdev, &link_keys_fops);
+		debugfs_create_file("use_debug_keys", 0444, hdev->debugfs,
+				    hdev, &use_debug_keys_fops);
 		debugfs_create_file("dev_class", 0444, hdev->debugfs,
 				    hdev, &dev_class_fops);
 		debugfs_create_file("voice_setting", 0444, hdev->debugfs,
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH 2/2] Bluetooth: Expose debugfs entry read/write own address type
From: Marcel Holtmann @ 2013-10-18 23:38 UTC (permalink / raw)
  To: linux-bluetooth

For some testing it is important to know the current own addres type,
but also be able to change it. The change is lost over powery cycles
and only intended for debugging.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
 net/bluetooth/hci_core.c | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index c130a23..d47c8ec 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -385,6 +385,34 @@ static const struct file_operations static_address_fops = {
 	.release	= single_release,
 };
 
+static int own_address_type_set(void *data, u64 val)
+{
+	struct hci_dev *hdev = data;
+
+	if (val != 0 && val != 1)
+		return -EINVAL;
+
+	hci_dev_lock(hdev);
+	hdev->own_addr_type = val;
+	hci_dev_unlock(hdev);
+
+	return 0;
+}
+
+static int own_address_type_get(void *data, u64 *val)
+{
+	struct hci_dev *hdev = data;
+
+	hci_dev_lock(hdev);
+	*val = hdev->own_addr_type;
+	hci_dev_unlock(hdev);
+
+	return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(own_address_type_fops, own_address_type_get,
+			own_address_type_set, "%llu\n");
+
 static int long_term_keys_show(struct seq_file *f, void *ptr)
 {
 	struct hci_dev *hdev = f->private;
@@ -1162,6 +1190,8 @@ static int __hci_init(struct hci_dev *hdev)
 				  &hdev->le_white_list_size);
 		debugfs_create_file("static_address", 0444, hdev->debugfs,
 				   hdev, &static_address_fops);
+		debugfs_create_file("own_address_type", 0644, hdev->debugfs,
+				    hdev, &own_address_type_fops);
 		debugfs_create_file("long_term_keys", 0400, hdev->debugfs,
 				    hdev, &long_term_keys_fops);
 	}
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH 1/2] Bluetooth: Select the own address type during initial setup phase
From: Marcel Holtmann @ 2013-10-18 23:38 UTC (permalink / raw)
  To: linux-bluetooth

The own address type is based on the fact if the controller has
a public address or not. This means that this detail can be just
configured once during setup phase.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
 include/net/bluetooth/hci_core.h |  1 +
 net/bluetooth/hci_conn.c         |  7 +------
 net/bluetooth/hci_core.c         | 13 ++++++++++++-
 net/bluetooth/mgmt.c             | 10 ++--------
 4 files changed, 16 insertions(+), 15 deletions(-)

diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 9b5db01..0daac39 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -142,6 +142,7 @@ struct hci_dev {
 	__u8		dev_type;
 	bdaddr_t	bdaddr;
 	bdaddr_t	static_addr;
+	__u8		own_addr_type;
 	__u8		dev_name[HCI_MAX_NAME_LENGTH];
 	__u8		short_name[HCI_MAX_SHORT_NAME_LENGTH];
 	__u8		eir[HCI_MAX_EIR_LENGTH];
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 4e72650..974d7bc 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -615,12 +615,7 @@ static struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst,
 	else
 		conn->dst_type = ADDR_LE_DEV_RANDOM;
 
-	if (bacmp(&conn->src, BDADDR_ANY)) {
-		conn->src_type = ADDR_LE_DEV_PUBLIC;
-	} else {
-		bacpy(&conn->src, &hdev->static_addr);
-		conn->src_type = ADDR_LE_DEV_RANDOM;
-	}
+	conn->src_type = hdev->own_addr_type;
 
 	conn->state = BT_CONNECT;
 	conn->out = true;
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 6b1844f..c130a23 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -1053,8 +1053,19 @@ static void hci_init3_req(struct hci_request *req, unsigned long opt)
 	if (hdev->commands[5] & 0x10)
 		hci_setup_link_policy(req);
 
-	if (lmp_le_capable(hdev))
+	if (lmp_le_capable(hdev)) {
+		/* If the controller has a public BD_ADDR, then by
+		 * default use that one. If this is a LE only
+		 * controller without one, default to the random
+		 * address.
+		 */
+		if (bacmp(&hdev->bdaddr, BDADDR_ANY))
+			hdev->own_addr_type = ADDR_LE_DEV_PUBLIC;
+		else
+			hdev->own_addr_type = ADDR_LE_DEV_RANDOM;
+
 		hci_set_le_support(req);
+	}
 
 	/* Read features beyond page 1 if available */
 	for (p = 2; p < HCI_MAX_PAGES && p <= hdev->max_page; p++) {
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index a727b47..fb7fc9f 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -1325,10 +1325,7 @@ static void enable_advertising(struct hci_request *req)
 	cp.min_interval = __constant_cpu_to_le16(0x0800);
 	cp.max_interval = __constant_cpu_to_le16(0x0800);
 	cp.type = get_adv_type(hdev);
-	if (bacmp(&hdev->bdaddr, BDADDR_ANY))
-		cp.own_address_type = ADDR_LE_DEV_PUBLIC;
-	else
-		cp.own_address_type = ADDR_LE_DEV_RANDOM;
+	cp.own_address_type = hdev->own_addr_type;
 	cp.channel_map = 0x07;
 
 	hci_req_add(req, HCI_OP_LE_SET_ADV_PARAM, sizeof(cp), &cp);
@@ -3237,10 +3234,7 @@ static int start_discovery(struct sock *sk, struct hci_dev *hdev,
 		param_cp.type = LE_SCAN_ACTIVE;
 		param_cp.interval = cpu_to_le16(DISCOV_LE_SCAN_INT);
 		param_cp.window = cpu_to_le16(DISCOV_LE_SCAN_WIN);
-		if (bacmp(&hdev->bdaddr, BDADDR_ANY))
-			param_cp.own_address_type = ADDR_LE_DEV_PUBLIC;
-		else
-			param_cp.own_address_type = ADDR_LE_DEV_RANDOM;
+		param_cp.own_address_type = hdev->own_addr_type;
 		hci_req_add(&req, HCI_OP_LE_SET_SCAN_PARAM, sizeof(param_cp),
 			    &param_cp);
 
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH 5/5] android: Remove not needed property_get function form cutils stubs
From: Szymon Janc @ 2013-10-18 23:01 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1382137302-17237-1-git-send-email-szymon.janc@gmail.com>

From: Szymon Janc <szymon.janc@tieto.com>

This is no longer used as daemon indicates its presence by connecting
socket.
---
 android/cutils/properties.h | 27 ---------------------------
 1 file changed, 27 deletions(-)

diff --git a/android/cutils/properties.h b/android/cutils/properties.h
index 44a712c..f318b01 100644
--- a/android/cutils/properties.h
+++ b/android/cutils/properties.h
@@ -24,33 +24,6 @@
 extern "C" {
 #endif
 
-#define PROPERTY_KEY_MAX   32
-#define PROPERTY_VALUE_MAX  92
-
-/* property_get: returns the length of the value which will never be
-** greater than PROPERTY_VALUE_MAX - 1 and will always be zero terminated.
-** (the length does not include the terminating zero).
-**
-** If the property read fails or returns an empty value, the default
-** value is used (if nonnull).
-*/
-static inline int property_get(const char *key, char *value,
-						const char *default_value)
-{
-	const char *env;
-
-	env = getenv(key);
-	if (!env)
-		env = default_value;
-
-	if (!value || !env)
-		return 0;
-
-	strncpy(value, env, PROPERTY_VALUE_MAX);
-
-	return strlen(value);
-}
-
 /* property_set: returns 0 on success, < 0 on failure
 */
 static inline int property_set(const char *key, const char *value)
-- 
1.8.4.rc3


^ permalink raw reply related

* [PATCH 4/5] android: Make HAL library wait for daemon to connect on init
From: Szymon Janc @ 2013-10-18 23:01 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1382137302-17237-1-git-send-email-szymon.janc@gmail.com>

From: Szymon Janc <szymon.janc@tieto.com>

After starting up, daemon is responsible for connecting to HAL library.
If this doesn't happen before timeout occured init will fail.
---
 android/hal-bluetooth.c | 127 +++++++++++++++++++++++++++++++++++++++---------
 1 file changed, 104 insertions(+), 23 deletions(-)

diff --git a/android/hal-bluetooth.c b/android/hal-bluetooth.c
index 2c6c2eb..c91bc98 100644
--- a/android/hal-bluetooth.c
+++ b/android/hal-bluetooth.c
@@ -19,6 +19,10 @@
 #include <stdlib.h>
 #include <unistd.h>
 #include <stdbool.h>
+#include <errno.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <poll.h>
 
 #include <hardware/bluetooth.h>
 #include <hardware/bt_sock.h>
@@ -31,41 +35,119 @@
 #include <cutils/log.h>
 
 #include "hal.h"
+#include "hal-msg.h"
 
 #define SERVICE_NAME "bluetoothd"
+#define CONNECT_TIMEOUT (5 * 1000)
 
 bt_callbacks_t *bt_hal_cbacks = NULL;
 
+static int cmd_sk = -1;
+static int notif_sk = -1;
+
 static bool interface_ready(void)
 {
 	return bt_hal_cbacks != NULL;
 }
 
-static bool start_bt_daemon(void)
+static int accept_connection(int sk)
 {
-	int tries = 40; /* wait 4 seconds for completion */
+	int err;
+	struct pollfd pfd;
+	int new_sk;
+
+	memset(&pfd, 0 , sizeof(pfd));
+	pfd.fd = sk;
+	pfd.events = POLLIN;
+
+	err = poll(&pfd, 1, CONNECT_TIMEOUT);
+	if (err < 0) {
+		err = errno;
+		ALOGE("Failed to poll: %d (%s)", err, strerror(err));
+		return -1;
+	}
 
-	ALOGD(__func__);
+	if (err == 0) {
+		ALOGE("bluetoothd connect timeout");
+		return -1;
+	}
+
+	new_sk = accept(sk, NULL, NULL);
+	if (new_sk < 0) {
+		err = errno;
+		ALOGE("Failed to accept socket: %d (%s)", err, strerror(err));
+		return -1;
+	}
+
+	return new_sk;
+}
+
+static bool start_daemon(void)
+{
+	struct sockaddr_un addr;
+	int sk;
+	int err;
+
+	sk = socket(AF_LOCAL, SOCK_SEQPACKET, 0);
+	if (sk < 0) {
+		err = errno;
+		ALOGE("Failed to create socket: %d (%s)", err,
+							strerror(err));
+		return false;
+	}
+
+	memset(&addr, 0, sizeof(addr));
+	addr.sun_family = AF_UNIX;
+
+	/* Use abstract sockets so first byte needs to be \0 */
+	strcpy(addr.sun_path + 1, BLUEZ_HAL_SK_PATH);
+
+	if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
+		err = errno;
+		ALOGE("Failed to bind socket: %d (%s)", err, strerror(err));
+		close(sk);
+		return false;
+	}
+
+	if (listen(sk, 2) < 0) {
+		err = errno;
+		ALOGE("Failed to listen on socket: %d (%s)", err,
+								strerror(err));
+		close(sk);
+		return false;
+	}
 
 	/* Start Android Bluetooth daemon service */
 	property_set("ctl.start", SERVICE_NAME);
 
-	while (tries-- > 0) {
-		char val[PROPERTY_VALUE_MAX];
-
-		if (property_get("init.svc." SERVICE_NAME, val, NULL)) {
-			if (!strcmp(val, "running")) {
-				ALOGI("Android BlueZ daemon started");
-				return true;
-			}
-		} else {
-			return false;
-		}
+	cmd_sk = accept_connection(sk);
+	if (cmd_sk < 0) {
+		close(sk);
+		return false;
+	}
 
-		usleep(100000);
+	notif_sk = accept_connection(sk);
+	if (notif_sk < 0) {
+		close(sk);
+		close(cmd_sk);
+		cmd_sk = -1;
+		return false;
 	}
 
-	return false;
+	ALOGI("bluetoothd connected");
+
+	close(sk);
+
+	return true;
+}
+
+static void stop_daemon(void)
+{
+	close(cmd_sk);
+	cmd_sk = -1;
+
+	close(notif_sk);
+	notif_sk = 1;
 }
 
 static int init(bt_callbacks_t *callbacks)
@@ -75,15 +157,12 @@ static int init(bt_callbacks_t *callbacks)
 	if (interface_ready())
 		return BT_STATUS_SUCCESS;
 
-	if (start_bt_daemon()) {
-		/* TODO: open channel */
+	if (!start_daemon())
+		return BT_STATUS_FAIL;
 
-		bt_hal_cbacks = callbacks;
+	bt_hal_cbacks = callbacks;
 
-		return BT_STATUS_SUCCESS;
-	}
-
-	return BT_STATUS_UNSUPPORTED;
+	return BT_STATUS_SUCCESS;
 }
 
 static int enable(void)
@@ -110,6 +189,8 @@ static void cleanup(void)
 	if (!interface_ready())
 		return;
 
+	stop_daemon();
+
 	bt_hal_cbacks = NULL;
 }
 
-- 
1.8.4.rc3


^ permalink raw reply related

* [PATCH 3/5] android: Connect daemon to HAL library
From: Szymon Janc @ 2013-10-18 23:01 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1382137302-17237-1-git-send-email-szymon.janc@gmail.com>

From: Szymon Janc <szymon.janc@tieto.com>

Connect to HAL when adapter initialization is finished. If any problem
with connection occurs or connected socket is closed by remote daemon
shutdowns.
---
 android/main.c | 133 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 133 insertions(+)

diff --git a/android/main.c b/android/main.c
index c3fb80e..5b71265 100644
--- a/android/main.c
+++ b/android/main.c
@@ -32,7 +32,10 @@
 #include <stdlib.h>
 #include <stdbool.h>
 #include <string.h>
+#include <errno.h>
 #include <sys/signalfd.h>
+#include <sys/socket.h>
+#include <sys/un.h>
 
 #include <glib.h>
 
@@ -44,6 +47,7 @@
 #include "src/shared/mgmt.h"
 
 #include "adapter.h"
+#include "hal-msg.h"
 
 #define SHUTDOWN_GRACE_SECONDS 10
 
@@ -55,8 +59,135 @@ static uint8_t mgmt_revision = 0;
 
 static uint16_t adapter_index = MGMT_INDEX_NONE;
 
+static GIOChannel *hal_cmd_io = NULL;
+static GIOChannel *hal_notif_io = NULL;
+
 static volatile sig_atomic_t __terminated = 0;
 
+static gboolean watch_cb(GIOChannel *io, GIOCondition cond,
+							gpointer user_data)
+{
+	info("HAL socket closed, terminating");
+	g_main_loop_quit(event_loop);
+
+	return FALSE;
+}
+
+static GIOChannel *create_io(void)
+{
+	int sk;
+	int err;
+	GIOChannel *io;
+
+	sk = socket(PF_LOCAL, SOCK_SEQPACKET, 0);
+	if (sk < 0) {
+		err = errno;
+		error("Failed to create socket: %d (%s)", err, strerror(err));
+		return NULL;
+	}
+
+	io = g_io_channel_unix_new(sk);
+
+	g_io_channel_set_close_on_unref(io, TRUE);
+	g_io_channel_set_flags(io, G_IO_FLAG_NONBLOCK, NULL);
+
+	return io;
+}
+
+static int connect_io(GIOChannel *io, GIOFunc connect_cb)
+{
+	int err;
+	struct sockaddr_un addr;
+	GIOCondition cond;
+
+	memset(&addr, 0, sizeof(addr));
+	addr.sun_family = AF_UNIX;
+
+	/* Use abstract sockets so first byte needs to be \0 */
+	strcpy(addr.sun_path + 1, BLUEZ_HAL_SK_PATH);
+
+	err = connect(g_io_channel_unix_get_fd(io),
+				(struct sockaddr *) &addr, sizeof(addr));
+	if (err < 0) {
+		err = -errno;
+		error("Failed to connect HAL socket: %d (%s)", -err,
+							strerror(-err));
+		return err;
+	}
+
+	cond = G_IO_OUT | G_IO_ERR | G_IO_HUP | G_IO_NVAL;
+
+	g_io_add_watch(io, cond, connect_cb, NULL);
+
+	return 0;
+}
+
+static gboolean notif_connect_cb(GIOChannel *io, GIOCondition cond,
+							gpointer user_data)
+{
+	DBG("");
+
+	if (cond & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) {
+		g_main_loop_quit(event_loop);
+		return FALSE;
+	}
+
+	cond = G_IO_ERR | G_IO_HUP | G_IO_NVAL;
+
+	g_io_add_watch(io, cond, watch_cb, NULL);
+
+	info("Successfully connected to HAL");
+
+	/* TODO start handling commands */
+
+	return FALSE;
+}
+
+static void connect_notification_socket(void)
+{
+	DBG("");
+
+	hal_notif_io = create_io();
+
+	if (hal_notif_io && connect_io(hal_notif_io, notif_connect_cb) == 0)
+		return;
+
+	error("Cannot connect to HAL, terminating");
+	g_main_loop_quit(event_loop);
+}
+
+static gboolean cmd_connect_cb(GIOChannel *io, GIOCondition cond,
+							gpointer user_data)
+{
+	DBG("");
+
+	if (cond & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) {
+		g_main_loop_quit(event_loop);
+		return FALSE;
+	}
+
+	cond = G_IO_ERR | G_IO_HUP | G_IO_NVAL;
+
+	g_io_add_watch(io, cond, watch_cb, NULL);
+
+	connect_notification_socket();
+
+	return FALSE;
+}
+
+static void connect_cmd_socket(void)
+{
+	DBG("");
+
+	hal_cmd_io = create_io();
+
+	if (hal_cmd_io && connect_io(hal_cmd_io, cmd_connect_cb) == 0)
+		return;
+
+	error("Cannot connect to HAL, terminating");
+	g_main_loop_quit(event_loop);
+}
+
 static gboolean signal_handler(GIOChannel *channel, GIOCondition cond,
 							gpointer user_data)
 {
@@ -141,6 +272,8 @@ static void adapter_ready(struct bt_adapter *adapter, int err)
 	}
 
 	info("Adapter initialized");
+
+	connect_cmd_socket();
 }
 
 static void mgmt_index_added_event(uint16_t index, uint16_t length,
-- 
1.8.4.rc3


^ permalink raw reply related

* [PATCH 2/5] android: Define path for HAL communication socket
From: Szymon Janc @ 2013-10-18 23:01 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1382137302-17237-1-git-send-email-szymon.janc@gmail.com>

From: Szymon Janc <szymon.janc@tieto.com>

This socket will be used by android daemon and libhal to communitate.
---
 android/hal-msg.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/android/hal-msg.h b/android/hal-msg.h
index 4c5ca69..2da5e16 100644
--- a/android/hal-msg.h
+++ b/android/hal-msg.h
@@ -21,6 +21,8 @@
  *
  */
 
+#define BLUEZ_HAL_SK_PATH "bluez_hal_socket"
+
 struct hal_msg_hdr {
 	uint8_t service_id;
 	uint8_t opcode;
-- 
1.8.4.rc3


^ permalink raw reply related

* [PATCH 1/5] android: Fix cutils/log.h stubs
From: Szymon Janc @ 2013-10-18 23:01 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1382137302-17237-1-git-send-email-szymon.janc@gmail.com>

From: Szymon Janc <szymon.janc@tieto.com>

Provide dummy functions that will use macro parameters. This fix
build errors about set-but-not-used used local variables on linux.
---
 android/cutils/log.h | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/android/cutils/log.h b/android/cutils/log.h
index d87da72..7374add 100644
--- a/android/cutils/log.h
+++ b/android/cutils/log.h
@@ -17,11 +17,13 @@
 #ifndef _CUTILS_LOG_H
 #define _CUTILS_LOG_H
 
-#define ALOGV(...)
-#define ALOGD(...)
-#define ALOGI(...)
-#define ALOGW(...)
-#define ALOGE(...)
+static inline void dummy_printf(const char *fmt, ...) { }
+
+#define ALOGV(...) dummy_printf("", __VA_ARGS__)
+#define ALOGD(...) dummy_printf("", __VA_ARGS__)
+#define ALOGI(...) dummy_printf("", __VA_ARGS__)
+#define ALOGW(...) dummy_printf("", __VA_ARGS__)
+#define ALOGE(...) dummy_printf("", __VA_ARGS__)
 #define LOG_ALWAYS_FATAL(...)   do { ALOGE(__VA_ARGS__); exit(1); } while (0)
 
 #endif // _CUTILS_LOG_H
-- 
1.8.4.rc3


^ permalink raw reply related

* [PATCH 0/5] Initial Android IPC
From: Szymon Janc @ 2013-10-18 23:01 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc

Hi,

This adds initial code for Android IPC
- only connection establishment
- connecting ipc from daemon to HAL after adapter is initialized
- daemon track HAL lib lifetime and shutdown if socket is closed
- HAL library starts daemon (via android init) and wait for it to
  connect
- HAL library is *not* yet tracking lifetime of daemon

-- 
BR
Szymon Janc

Szymon Janc (5):
  android: Fix cutils/log.h stubs
  android: Define path for HAL communication socket
  android: Connect daemon to HAL library
  android: Make HAL library wait for daemon to connect on init
  android: Remove not needed property_get function form cutils stubs

 android/cutils/log.h        |  12 ++--
 android/cutils/properties.h |  27 ---------
 android/hal-bluetooth.c     | 127 ++++++++++++++++++++++++++++++++++--------
 android/hal-msg.h           |   2 +
 android/main.c              | 133 ++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 246 insertions(+), 55 deletions(-)

-- 
1.8.4.rc3


^ permalink raw reply

* [PATCH] Bluetooth: Expose current list of long term keys via debugfs
From: Marcel Holtmann @ 2013-10-18 22:56 UTC (permalink / raw)
  To: linux-bluetooth

For debugging purposes expose the current list of long term keys
via debugfs. This file is read-only and limited to root access.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
 net/bluetooth/hci_core.c | 32 ++++++++++++++++++++++++++++++++
 1 file changed, 32 insertions(+)

diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 8710d1f..6b1844f 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -385,6 +385,36 @@ static const struct file_operations static_address_fops = {
 	.release	= single_release,
 };
 
+static int long_term_keys_show(struct seq_file *f, void *ptr)
+{
+	struct hci_dev *hdev = f->private;
+	struct list_head *p, *n;
+
+	hci_dev_lock(hdev);
+	list_for_each_safe(p, n, &hdev->link_keys) {
+		struct smp_ltk *ltk = list_entry(p, struct smp_ltk, list);
+		seq_printf(f, "%pMR (type %u) %u %u %u %.4x %*phN %*phN\\n",
+			   &ltk->bdaddr, ltk->bdaddr_type, ltk->authenticated,
+			   ltk->type, ltk->enc_size, __le16_to_cpu(ltk->ediv),
+			   8, ltk->rand, 16, ltk->val);
+	}
+	hci_dev_unlock(hdev);
+
+	return 0;
+}
+
+static int long_term_keys_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, long_term_keys_show, inode->i_private);
+}
+
+static const struct file_operations long_term_keys_fops = {
+	.open		= long_term_keys_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
 /* ---- HCI requests ---- */
 
 static void hci_req_sync_complete(struct hci_dev *hdev, u8 result)
@@ -1121,6 +1151,8 @@ static int __hci_init(struct hci_dev *hdev)
 				  &hdev->le_white_list_size);
 		debugfs_create_file("static_address", 0444, hdev->debugfs,
 				   hdev, &static_address_fops);
+		debugfs_create_file("long_term_keys", 0400, hdev->debugfs,
+				    hdev, &long_term_keys_fops);
 	}
 
 	return 0;
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH] Bluetooth: Expose white list size information in debugfs
From: Marcel Holtmann @ 2013-10-18 22:23 UTC (permalink / raw)
  To: linux-bluetooth

Knowing the white list size information is important for
debugging. So export it via debugfs.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
 net/bluetooth/hci_core.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index ee946cb..8710d1f 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -1116,9 +1116,12 @@ static int __hci_init(struct hci_dev *hdev)
 				    hdev, &sniff_max_interval_fops);
 	}
 
-	if (lmp_le_capable(hdev))
+	if (lmp_le_capable(hdev)) {
+		debugfs_create_u8("white_list_size", 0444, hdev->debugfs,
+				  &hdev->le_white_list_size);
 		debugfs_create_file("static_address", 0444, hdev->debugfs,
 				   hdev, &static_address_fops);
+	}
 
 	return 0;
 }
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH] Bluetooth: Remove bus attribute in favor of hierarchy
From: Marcel Holtmann @ 2013-10-18 19:39 UTC (permalink / raw)
  To: linux-bluetooth

The bus information are exposed in the actual hierarchy and should
not be exposed as attribute.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
 net/bluetooth/hci_sysfs.c | 31 -------------------------------
 1 file changed, 31 deletions(-)

diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c
index 95fc5bb..0b61250 100644
--- a/net/bluetooth/hci_sysfs.c
+++ b/net/bluetooth/hci_sysfs.c
@@ -131,28 +131,6 @@ void hci_conn_del_sysfs(struct hci_conn *conn)
 	hci_dev_put(hdev);
 }
 
-static inline char *host_bustostr(int bus)
-{
-	switch (bus) {
-	case HCI_VIRTUAL:
-		return "VIRTUAL";
-	case HCI_USB:
-		return "USB";
-	case HCI_PCCARD:
-		return "PCCARD";
-	case HCI_UART:
-		return "UART";
-	case HCI_RS232:
-		return "RS232";
-	case HCI_PCI:
-		return "PCI";
-	case HCI_SDIO:
-		return "SDIO";
-	default:
-		return "UNKNOWN";
-	}
-}
-
 static inline char *host_typetostr(int type)
 {
 	switch (type) {
@@ -165,13 +143,6 @@ static inline char *host_typetostr(int type)
 	}
 }
 
-static ssize_t show_bus(struct device *dev,
-			struct device_attribute *attr, char *buf)
-{
-	struct hci_dev *hdev = to_hci_dev(dev);
-	return sprintf(buf, "%s\n", host_bustostr(hdev->bus));
-}
-
 static ssize_t show_type(struct device *dev,
 			 struct device_attribute *attr, char *buf)
 {
@@ -200,13 +171,11 @@ static ssize_t show_address(struct device *dev,
 	return sprintf(buf, "%pMR\n", &hdev->bdaddr);
 }
 
-static DEVICE_ATTR(bus, S_IRUGO, show_bus, NULL);
 static DEVICE_ATTR(type, S_IRUGO, show_type, NULL);
 static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
 static DEVICE_ATTR(address, S_IRUGO, show_address, NULL);
 
 static struct attribute *bt_host_attrs[] = {
-	&dev_attr_bus.attr,
 	&dev_attr_type.attr,
 	&dev_attr_name.attr,
 	&dev_attr_address.attr,
-- 
1.8.3.1


^ permalink raw reply related

* Re: [PATCH] Bluetooth: ath3k: add support for 0930:021c
From: Robin Kreis @ 2013-10-18 19:20 UTC (permalink / raw)
  To: Marcel Holtmann; +Cc: linux-bluetooth
In-Reply-To: <C5C1D96A-A132-47FA-807A-88D4CF1948AC@holtmann.org>

Am Fri, 18 Oct 2013 18:53:25 +0200
schrieb Marcel Holtmann <marcel@holtmann.org>:

> Hi Robin,

Hi Marcel!

> as usual include the relevant parts
> from /sys/kernel/debug/usb/devices here.

There you go:

T:  Bus=03 Lev=00 Prnt=00 Port=00 Cnt=00 Dev#=  1 Spd=480  MxCh= 4
B:  Alloc=  0/800 us ( 0%), #Int=  0, #Iso=  0
D:  Ver= 2.00 Cls=09(hub  ) Sub=00 Prot=01 MxPS=64 #Cfgs=  1
P:  Vendor=1d6b ProdID=0002 Rev= 3.11
S:  Manufacturer=Linux 3.11.5-1-ARCH xhci_hcd
S:  Product=xHCI Host Controller
S:  SerialNumber=0000:00:14.0
C:* #Ifs= 1 Cfg#= 1 Atr=e0 MxPwr=  0mA
I:* If#= 0 Alt= 0 #EPs= 1 Cls=09(hub  ) Sub=00 Prot=00 Driver=hub
E:  Ad=81(I) Atr=03(Int.) MxPS=   4 Ivl=256ms

T:  Bus=03 Lev=01 Prnt=01 Port=02 Cnt=01 Dev#=  5 Spd=12   MxCh= 0
D:  Ver= 1.10 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs=  1
P:  Vendor=0930 ProdID=021c Rev= 0.02
C:* #Ifs= 2 Cfg#= 1 Atr=e0 MxPwr=100mA
I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E:  Ad=81(I) Atr=03(Int.) MxPS=  16 Ivl=1ms
E:  Ad=82(I) Atr=02(Bulk) MxPS=  64 Ivl=0ms
E:  Ad=02(O) Atr=02(Bulk) MxPS=  64 Ivl=0ms
I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E:  Ad=83(I) Atr=01(Isoc) MxPS=   0 Ivl=1ms
E:  Ad=03(O) Atr=01(Isoc) MxPS=   0 Ivl=1ms
I:  If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E:  Ad=83(I) Atr=01(Isoc) MxPS=   9 Ivl=1ms
E:  Ad=03(O) Atr=01(Isoc) MxPS=   9 Ivl=1ms
I:  If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E:  Ad=83(I) Atr=01(Isoc) MxPS=  17 Ivl=1ms
E:  Ad=03(O) Atr=01(Isoc) MxPS=  17 Ivl=1ms
I:  If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E:  Ad=83(I) Atr=01(Isoc) MxPS=  25 Ivl=1ms
E:  Ad=03(O) Atr=01(Isoc) MxPS=  25 Ivl=1ms
I:  If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E:  Ad=83(I) Atr=01(Isoc) MxPS=  33 Ivl=1ms
E:  Ad=03(O) Atr=01(Isoc) MxPS=  33 Ivl=1ms
I:  If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E:  Ad=83(I) Atr=01(Isoc) MxPS=  49 Ivl=1ms
E:  Ad=03(O) Atr=01(Isoc) MxPS=  49 Ivl=1ms

This is with patched ath3k and btusb modules (and working Bluetooth).

Best regards,
Robin

^ permalink raw reply

* [PATCH 7/7] Bluetooth: Expose current list of link keys via debugfs
From: Marcel Holtmann @ 2013-10-18 19:04 UTC (permalink / raw)
  To: linux-bluetooth

For debugging purposes expose the current list of link keys via
debugfs. This file is read-only and limited to root access.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
 net/bluetooth/hci_core.c | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 3ef5fdd..ee946cb 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -187,6 +187,34 @@ static const struct file_operations inquiry_cache_fops = {
 	.release	= single_release,
 };
 
+static int link_keys_show(struct seq_file *f, void *ptr)
+{
+	struct hci_dev *hdev = f->private;
+	struct list_head *p, *n;
+
+	hci_dev_lock(hdev);
+	list_for_each_safe(p, n, &hdev->link_keys) {
+		struct link_key *key = list_entry(p, struct link_key, list);
+		seq_printf(f, "%pMR %u %*phN %u\n", &key->bdaddr, key->type,
+			   HCI_LINK_KEY_SIZE, key->val, key->pin_len);
+	}
+	hci_dev_unlock(hdev);
+
+	return 0;
+}
+
+static int link_keys_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, link_keys_show, inode->i_private);
+}
+
+static const struct file_operations link_keys_fops = {
+	.open		= link_keys_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
 static int dev_class_show(struct seq_file *f, void *ptr)
 {
 	struct hci_dev *hdev = f->private;
@@ -1067,6 +1095,8 @@ static int __hci_init(struct hci_dev *hdev)
 	if (lmp_bredr_capable(hdev)) {
 		debugfs_create_file("inquiry_cache", 0444, hdev->debugfs,
 				    hdev, &inquiry_cache_fops);
+		debugfs_create_file("link_keys", 0400, hdev->debugfs,
+				    hdev, &link_keys_fops);
 		debugfs_create_file("dev_class", 0444, hdev->debugfs,
 				    hdev, &dev_class_fops);
 		debugfs_create_file("voice_setting", 0444, hdev->debugfs,
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH 6/7] Bluetooth: Move export of class of device information into hci_core.c
From: Marcel Holtmann @ 2013-10-18 19:04 UTC (permalink / raw)
  To: linux-bluetooth

The class of device debugfs information should be directly exported
from hci_core.c and so move them over there.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
 net/bluetooth/hci_core.c  | 26 ++++++++++++++++++++++++++
 net/bluetooth/hci_sysfs.c | 10 ----------
 2 files changed, 26 insertions(+), 10 deletions(-)

diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 1d3c892..3ef5fdd 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -187,6 +187,30 @@ static const struct file_operations inquiry_cache_fops = {
 	.release	= single_release,
 };
 
+static int dev_class_show(struct seq_file *f, void *ptr)
+{
+	struct hci_dev *hdev = f->private;
+
+	hci_dev_lock(hdev);
+	seq_printf(f, "0x%.2x%.2x%.2x\n", hdev->dev_class[2],
+		   hdev->dev_class[1], hdev->dev_class[0]);
+	hci_dev_unlock(hdev);
+
+	return 0;
+}
+
+static int dev_class_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, dev_class_show, inode->i_private);
+}
+
+static const struct file_operations dev_class_fops = {
+	.open		= dev_class_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
 static int voice_setting_get(void *data, u64 *val)
 {
 	struct hci_dev *hdev = data;
@@ -1043,6 +1067,8 @@ static int __hci_init(struct hci_dev *hdev)
 	if (lmp_bredr_capable(hdev)) {
 		debugfs_create_file("inquiry_cache", 0444, hdev->debugfs,
 				    hdev, &inquiry_cache_fops);
+		debugfs_create_file("dev_class", 0444, hdev->debugfs,
+				    hdev, &dev_class_fops);
 		debugfs_create_file("voice_setting", 0444, hdev->debugfs,
 				    hdev, &voice_setting_fops);
 	}
diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c
index acc6a2a..95fc5bb 100644
--- a/net/bluetooth/hci_sysfs.c
+++ b/net/bluetooth/hci_sysfs.c
@@ -193,14 +193,6 @@ static ssize_t show_name(struct device *dev,
 	return sprintf(buf, "%s\n", name);
 }
 
-static ssize_t show_class(struct device *dev,
-			  struct device_attribute *attr, char *buf)
-{
-	struct hci_dev *hdev = to_hci_dev(dev);
-	return sprintf(buf, "0x%.2x%.2x%.2x\n", hdev->dev_class[2],
-		       hdev->dev_class[1], hdev->dev_class[0]);
-}
-
 static ssize_t show_address(struct device *dev,
 			    struct device_attribute *attr, char *buf)
 {
@@ -211,14 +203,12 @@ static ssize_t show_address(struct device *dev,
 static DEVICE_ATTR(bus, S_IRUGO, show_bus, NULL);
 static DEVICE_ATTR(type, S_IRUGO, show_type, NULL);
 static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
-static DEVICE_ATTR(class, S_IRUGO, show_class, NULL);
 static DEVICE_ATTR(address, S_IRUGO, show_address, NULL);
 
 static struct attribute *bt_host_attrs[] = {
 	&dev_attr_bus.attr,
 	&dev_attr_type.attr,
 	&dev_attr_name.attr,
-	&dev_attr_class.attr,
 	&dev_attr_address.attr,
 	NULL
 };
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH 5/7] Bluetooth: Store local version information only during setup phase
From: Marcel Holtmann @ 2013-10-18 19:04 UTC (permalink / raw)
  To: linux-bluetooth

The local version information from the controller can not change
since they are static. So store them only once during setup
phase and not bother overwriting them every time this command
gets executed.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
 net/bluetooth/hci_event.c | 15 +++++++--------
 1 file changed, 7 insertions(+), 8 deletions(-)

diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index c171c07..8480452 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -468,14 +468,13 @@ static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb)
 	if (rp->status)
 		return;
 
-	hdev->hci_ver = rp->hci_ver;
-	hdev->hci_rev = __le16_to_cpu(rp->hci_rev);
-	hdev->lmp_ver = rp->lmp_ver;
-	hdev->manufacturer = __le16_to_cpu(rp->manufacturer);
-	hdev->lmp_subver = __le16_to_cpu(rp->lmp_subver);
-
-	BT_DBG("%s manufacturer 0x%4.4x hci ver %d:%d", hdev->name,
-	       hdev->manufacturer, hdev->hci_ver, hdev->hci_rev);
+	if (test_bit(HCI_SETUP, &hdev->dev_flags)) {
+		hdev->hci_ver = rp->hci_ver;
+		hdev->hci_rev = __le16_to_cpu(rp->hci_rev);
+		hdev->lmp_ver = rp->lmp_ver;
+		hdev->manufacturer = __le16_to_cpu(rp->manufacturer);
+		hdev->lmp_subver = __le16_to_cpu(rp->lmp_subver);
+	}
 }
 
 static void hci_cc_read_local_commands(struct hci_dev *hdev,
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH 4/7] Bluetooth: Move manufacturer, hci_ver and hci_rev into hci_core.c
From: Marcel Holtmann @ 2013-10-18 19:04 UTC (permalink / raw)
  To: linux-bluetooth

Move the debugfs entries for manufacturer, hci_ver and hci_rev into
hci_core.c and use the new helpers for static entries that will not
change at runtime. Once passed the setup procedure, they will stay
fixed.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
 net/bluetooth/hci_core.c  |  4 ++++
 net/bluetooth/hci_sysfs.c | 27 ---------------------------
 2 files changed, 4 insertions(+), 27 deletions(-)

diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index e445f35..1d3c892 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -1032,6 +1032,10 @@ static int __hci_init(struct hci_dev *hdev)
 
 	debugfs_create_file("features", 0444, hdev->debugfs, hdev,
 			    &features_fops);
+	debugfs_create_u16("manufacturer", 0444, hdev->debugfs,
+			   &hdev->manufacturer);
+	debugfs_create_u8("hci_version", 0444, hdev->debugfs, &hdev->hci_ver);
+	debugfs_create_u16("hci_revision", 0444, hdev->debugfs, &hdev->hci_rev);
 	debugfs_create_file("blacklist", 0444, hdev->debugfs, hdev,
 			    &blacklist_fops);
 	debugfs_create_file("uuids", 0444, hdev->debugfs, hdev, &uuids_fops);
diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c
index c5aa42f..acc6a2a 100644
--- a/net/bluetooth/hci_sysfs.c
+++ b/net/bluetooth/hci_sysfs.c
@@ -208,35 +208,11 @@ static ssize_t show_address(struct device *dev,
 	return sprintf(buf, "%pMR\n", &hdev->bdaddr);
 }
 
-static ssize_t show_manufacturer(struct device *dev,
-				 struct device_attribute *attr, char *buf)
-{
-	struct hci_dev *hdev = to_hci_dev(dev);
-	return sprintf(buf, "%d\n", hdev->manufacturer);
-}
-
-static ssize_t show_hci_version(struct device *dev,
-				struct device_attribute *attr, char *buf)
-{
-	struct hci_dev *hdev = to_hci_dev(dev);
-	return sprintf(buf, "%d\n", hdev->hci_ver);
-}
-
-static ssize_t show_hci_revision(struct device *dev,
-				 struct device_attribute *attr, char *buf)
-{
-	struct hci_dev *hdev = to_hci_dev(dev);
-	return sprintf(buf, "%d\n", hdev->hci_rev);
-}
-
 static DEVICE_ATTR(bus, S_IRUGO, show_bus, NULL);
 static DEVICE_ATTR(type, S_IRUGO, show_type, NULL);
 static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
 static DEVICE_ATTR(class, S_IRUGO, show_class, NULL);
 static DEVICE_ATTR(address, S_IRUGO, show_address, NULL);
-static DEVICE_ATTR(manufacturer, S_IRUGO, show_manufacturer, NULL);
-static DEVICE_ATTR(hci_version, S_IRUGO, show_hci_version, NULL);
-static DEVICE_ATTR(hci_revision, S_IRUGO, show_hci_revision, NULL);
 
 static struct attribute *bt_host_attrs[] = {
 	&dev_attr_bus.attr,
@@ -244,9 +220,6 @@ static struct attribute *bt_host_attrs[] = {
 	&dev_attr_name.attr,
 	&dev_attr_class.attr,
 	&dev_attr_address.attr,
-	&dev_attr_manufacturer.attr,
-	&dev_attr_hci_version.attr,
-	&dev_attr_hci_revision.attr,
 	NULL
 };
 
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH 3/7] Bluetooth: Remove debug entry for connection features
From: Marcel Holtmann @ 2013-10-18 19:04 UTC (permalink / raw)
  To: linux-bluetooth

The debug entry for connection features is incomplete and also does
not work with AMP controllers and physical links. So just remove it.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
 net/bluetooth/hci_sysfs.c | 14 --------------
 1 file changed, 14 deletions(-)

diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c
index 90142ae..c5aa42f 100644
--- a/net/bluetooth/hci_sysfs.c
+++ b/net/bluetooth/hci_sysfs.c
@@ -37,29 +37,15 @@ static ssize_t show_link_address(struct device *dev,
 	return sprintf(buf, "%pMR\n", &conn->dst);
 }
 
-static ssize_t show_link_features(struct device *dev,
-				  struct device_attribute *attr, char *buf)
-{
-	struct hci_conn *conn = to_hci_conn(dev);
-
-	return sprintf(buf, "0x%02x%02x%02x%02x%02x%02x%02x%02x\n",
-		       conn->features[0][0], conn->features[0][1],
-		       conn->features[0][2], conn->features[0][3],
-		       conn->features[0][4], conn->features[0][5],
-		       conn->features[0][6], conn->features[0][7]);
-}
-
 #define LINK_ATTR(_name, _mode, _show, _store) \
 struct device_attribute link_attr_##_name = __ATTR(_name, _mode, _show, _store)
 
 static LINK_ATTR(type, S_IRUGO, show_link_type, NULL);
 static LINK_ATTR(address, S_IRUGO, show_link_address, NULL);
-static LINK_ATTR(features, S_IRUGO, show_link_features, NULL);
 
 static struct attribute *bt_link_attrs[] = {
 	&link_attr_type.attr,
 	&link_attr_address.attr,
-	&link_attr_features.attr,
 	NULL
 };
 
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH 2/7] Bluetooth: Add workaround for buggy max_page features page value
From: Marcel Holtmann @ 2013-10-18 19:04 UTC (permalink / raw)
  To: linux-bluetooth

Some controllers list the max_page value from the extended features
response as 0 when SSP has not yet been enabled. To workaround this
issue, force the max_page value to 1 when SSP support has been
detected.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
 net/bluetooth/hci_core.c  | 8 ++++++++
 net/bluetooth/hci_event.c | 3 ++-
 2 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 47fcb49..e445f35 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -834,6 +834,14 @@ static void hci_init2_req(struct hci_request *req, unsigned long opt)
 		hci_req_add(req, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL);
 
 	if (lmp_ssp_capable(hdev)) {
+		/* When SSP is available, then the host features page
+		 * should also be available as well. However some
+		 * controllers list the max_page as 0 as long as SSP
+		 * has not been enabled. To achieve proper debugging
+		 * output, force the minimum max_page to 1 at least.
+		 */
+		hdev->max_page = 0x01;
+
 		if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) {
 			u8 mode = 0x01;
 			hci_req_add(req, HCI_OP_WRITE_SSP_MODE,
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index e43de98..c171c07 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -555,7 +555,8 @@ static void hci_cc_read_local_ext_features(struct hci_dev *hdev,
 	if (rp->status)
 		return;
 
-	hdev->max_page = rp->max_page;
+	if (hdev->max_page < rp->max_page)
+		hdev->max_page = rp->max_page;
 
 	if (rp->page < HCI_MAX_PAGES)
 		memcpy(hdev->features[rp->page], rp->features, 8);
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH 1/7] Bluetooth: Move HCI device features into hci_core.c
From: Marcel Holtmann @ 2013-10-18 19:04 UTC (permalink / raw)
  To: linux-bluetooth

Move the handling of HCI device features debugfs into hci_core.c and
also extend it with handling of multiple feature pages.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
 net/bluetooth/hci_core.c  | 34 +++++++++++++++++++++++++++++++++-
 net/bluetooth/hci_sysfs.c | 14 --------------
 2 files changed, 33 insertions(+), 15 deletions(-)

diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index e8058c3..47fcb49 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -58,6 +58,37 @@ static void hci_notify(struct hci_dev *hdev, int event)
 
 /* ---- HCI debugfs entries ---- */
 
+static int features_show(struct seq_file *f, void *ptr)
+{
+	struct hci_dev *hdev = f->private;
+	u8 p;
+
+	hci_dev_lock(hdev);
+	for (p = 0; p < HCI_MAX_PAGES && p <= hdev->max_page; p++) {
+		seq_printf(f, "Page %u: 0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x "
+			   "0x%2.2x 0x%2.2x 0x%2.2x 0x%2.2x\n", p,
+			   hdev->features[p][0], hdev->features[p][1],
+			   hdev->features[p][2], hdev->features[p][3],
+			   hdev->features[p][4], hdev->features[p][5],
+			   hdev->features[p][6], hdev->features[p][7]);
+	}
+	hci_dev_unlock(hdev);
+
+	return 0;
+}
+
+static int features_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, features_show, inode->i_private);
+}
+
+static const struct file_operations features_fops = {
+	.open		= features_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
 static int blacklist_show(struct seq_file *f, void *p)
 {
 	struct hci_dev *hdev = f->private;
@@ -991,9 +1022,10 @@ static int __hci_init(struct hci_dev *hdev)
 	if (!test_bit(HCI_SETUP, &hdev->dev_flags))
 		return 0;
 
+	debugfs_create_file("features", 0444, hdev->debugfs, hdev,
+			    &features_fops);
 	debugfs_create_file("blacklist", 0444, hdev->debugfs, hdev,
 			    &blacklist_fops);
-
 	debugfs_create_file("uuids", 0444, hdev->debugfs, hdev, &uuids_fops);
 
 	if (lmp_bredr_capable(hdev)) {
diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c
index 4fac57c..90142ae 100644
--- a/net/bluetooth/hci_sysfs.c
+++ b/net/bluetooth/hci_sysfs.c
@@ -222,18 +222,6 @@ static ssize_t show_address(struct device *dev,
 	return sprintf(buf, "%pMR\n", &hdev->bdaddr);
 }
 
-static ssize_t show_features(struct device *dev,
-			     struct device_attribute *attr, char *buf)
-{
-	struct hci_dev *hdev = to_hci_dev(dev);
-
-	return sprintf(buf, "0x%02x%02x%02x%02x%02x%02x%02x%02x\n",
-		       hdev->features[0][0], hdev->features[0][1],
-		       hdev->features[0][2], hdev->features[0][3],
-		       hdev->features[0][4], hdev->features[0][5],
-		       hdev->features[0][6], hdev->features[0][7]);
-}
-
 static ssize_t show_manufacturer(struct device *dev,
 				 struct device_attribute *attr, char *buf)
 {
@@ -260,7 +248,6 @@ static DEVICE_ATTR(type, S_IRUGO, show_type, NULL);
 static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
 static DEVICE_ATTR(class, S_IRUGO, show_class, NULL);
 static DEVICE_ATTR(address, S_IRUGO, show_address, NULL);
-static DEVICE_ATTR(features, S_IRUGO, show_features, NULL);
 static DEVICE_ATTR(manufacturer, S_IRUGO, show_manufacturer, NULL);
 static DEVICE_ATTR(hci_version, S_IRUGO, show_hci_version, NULL);
 static DEVICE_ATTR(hci_revision, S_IRUGO, show_hci_revision, NULL);
@@ -271,7 +258,6 @@ static struct attribute *bt_host_attrs[] = {
 	&dev_attr_name.attr,
 	&dev_attr_class.attr,
 	&dev_attr_address.attr,
-	&dev_attr_features.attr,
 	&dev_attr_manufacturer.attr,
 	&dev_attr_hci_version.attr,
 	&dev_attr_hci_revision.attr,
-- 
1.8.3.1


^ permalink raw reply related

* Re: pull request: bluetooth-next 2013-10-14
From: John W. Linville @ 2013-10-18 17:56 UTC (permalink / raw)
  To: Gustavo Padovan, linux-wireless, linux-bluetooth, linux-kernel
In-Reply-To: <20131014235218.GE2305@joana>

On Mon, Oct 14, 2013 at 08:52:18PM -0300, Gustavo Padovan wrote:
> Hi John,
> 
> More patches for 3.12, busy times for Bluetooth. More than a 100 commits since
> the last pull. The bulk of work comes from Johan and Marcel, they are doing
> fixes and improvements all over the Bluetooth subsystem, as the diffstat can
> show.
> 
> Please pull or let me know of any problems! Thanks.
> 
> 	Gustavo
> --
> The following changes since commit 4f3e219d95a3c31b916dcd5e2631c4e440736f79:
> 
>   Bluetooth: Only one command per L2CAP LE signalling is supported (2013-10-03 16:09:59 +0300)
> 
> are available in the git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next for-upstream
> 
> for you to fetch changes up to 4b836f393bd8ed111857a6ee1865e44627266ec6:
> 
>   Bluetooth: Read current IAC LAP on controller setup (2013-10-14 19:31:18 -0300)

Pulling now...

-- 
John W. Linville		Someday the world will need a hero, and you
linville@tuxdriver.com			might be all we have.  Be ready.

^ permalink raw reply

* Re: [PATCH] Bluetooth: ath3k: add support for 0930:021c
From: Marcel Holtmann @ 2013-10-18 16:53 UTC (permalink / raw)
  To: Robin Kreis; +Cc: linux-bluetooth
In-Reply-To: <20131018173536.6f17d7a7@sat>

Hi Robin,

> This is needed for my Toshiba C850-1K0 (AR9462 chip) to discover any
> Bluetooth devices.

as usual include the relevant parts from /sys/kernel/debug/usb/devices here.

> 
> ---
> drivers/bluetooth/ath3k.c | 2 ++
> drivers/bluetooth/btusb.c | 1 +
> 2 files changed, 3 insertions(+)
> 
> diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c
> index 0a327f4..23b813a 100644
> --- a/drivers/bluetooth/ath3k.c
> +++ b/drivers/bluetooth/ath3k.c
> @@ -87,6 +87,7 @@ static struct usb_device_id ath3k_table[] = {
> 	{ USB_DEVICE(0x0CF3, 0xE004) },
> 	{ USB_DEVICE(0x0CF3, 0xE005) },
> 	{ USB_DEVICE(0x0930, 0x0219) },
> +	{ USB_DEVICE(0x0930, 0x021c) },
> 	{ USB_DEVICE(0x0489, 0xe057) },
> 	{ USB_DEVICE(0x13d3, 0x3393) },
> 	{ USB_DEVICE(0x0489, 0xe04e) },
> @@ -129,6 +130,7 @@ static struct usb_device_id ath3k_blist_tbl[] = {
> 	{ USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 },
> 	{ USB_DEVICE(0x0cf3, 0xe005), .driver_info = BTUSB_ATH3012 },
> 	{ USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 },
> +	{ USB_DEVICE(0x0930, 0x021c), .driver_info = BTUSB_ATH3012 },
> 	{ USB_DEVICE(0x0489, 0xe057), .driver_info = BTUSB_ATH3012 },
> 	{ USB_DEVICE(0x13d3, 0x3393), .driver_info = BTUSB_ATH3012 },
> 	{ USB_DEVICE(0x0489, 0xe04e), .driver_info = BTUSB_ATH3012 },
> diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
> index f3dfc0a..92fe3c00 100644
> --- a/drivers/bluetooth/btusb.c
> +++ b/drivers/bluetooth/btusb.c
> @@ -154,6 +154,7 @@ static struct usb_device_id blacklist_table[] = {
> 	{ USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 },
> 	{ USB_DEVICE(0x0cf3, 0xe005), .driver_info = BTUSB_ATH3012 },
> 	{ USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 },
> +	{ USB_DEVICE(0x0930, 0x021c), .driver_info = BTUSB_ATH3012 },
> 	{ USB_DEVICE(0x0489, 0xe057), .driver_info = BTUSB_ATH3012 },
> 	{ USB_DEVICE(0x13d3, 0x3393), .driver_info = BTUSB_ATH3012 },
> 	{ USB_DEVICE(0x0489, 0xe04e), .driver_info = BTUSB_ATH3012 },

Regards

Marcel


^ permalink raw reply

* [PATCH] Bluetooth: ath3k: add support for 0930:021c
From: Robin Kreis @ 2013-10-18 15:35 UTC (permalink / raw)
  To: linux-bluetooth

This is needed for my Toshiba C850-1K0 (AR9462 chip) to discover any
Bluetooth devices.

---
 drivers/bluetooth/ath3k.c | 2 ++
 drivers/bluetooth/btusb.c | 1 +
 2 files changed, 3 insertions(+)

diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c
index 0a327f4..23b813a 100644
--- a/drivers/bluetooth/ath3k.c
+++ b/drivers/bluetooth/ath3k.c
@@ -87,6 +87,7 @@ static struct usb_device_id ath3k_table[] = {
 	{ USB_DEVICE(0x0CF3, 0xE004) },
 	{ USB_DEVICE(0x0CF3, 0xE005) },
 	{ USB_DEVICE(0x0930, 0x0219) },
+	{ USB_DEVICE(0x0930, 0x021c) },
 	{ USB_DEVICE(0x0489, 0xe057) },
 	{ USB_DEVICE(0x13d3, 0x3393) },
 	{ USB_DEVICE(0x0489, 0xe04e) },
@@ -129,6 +130,7 @@ static struct usb_device_id ath3k_blist_tbl[] = {
 	{ USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0cf3, 0xe005), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 },
+	{ USB_DEVICE(0x0930, 0x021c), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0489, 0xe057), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x13d3, 0x3393), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0489, 0xe04e), .driver_info = BTUSB_ATH3012 },
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index f3dfc0a..92fe3c00 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -154,6 +154,7 @@ static struct usb_device_id blacklist_table[] = {
 	{ USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0cf3, 0xe005), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 },
+	{ USB_DEVICE(0x0930, 0x021c), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0489, 0xe057), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x13d3, 0x3393), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0489, 0xe04e), .driver_info = BTUSB_ATH3012 },
-- 
1.8.4.1

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox