aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/bluetooth/hci_ldisc.c
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2015-04-04 19:13:01 -0400
committerMarcel Holtmann <marcel@holtmann.org>2015-04-07 12:47:08 -0400
commitfb2ce8d11f0399a1359e02fa2fcc5ad7e595544a (patch)
tree16ce28ed621ca03d222c0edaf633fc852f0e7052 /drivers/bluetooth/hci_ldisc.c
parent7abccdba25be45630eede85053496f1f48d36ec8 (diff)
Bluetooth: hci_uart: Add support for vendor detection flag
This adds a new HCI_UART_VND_DETECT flag to allow automatic vendor detection. This allows to enable known vendor commands (for example for setting the public device address) when using a standard H:4 UART protocol or when running in virtual machines. When this new flag is configured and no vendor specific setup routine is provided, then the local version information are read and the provided manufacturer information can be evaluated to configure extra vendor callbacks. Signed-off-by: Marcel Holtmann <marcel@holtmann.org> Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Diffstat (limited to 'drivers/bluetooth/hci_ldisc.c')
-rw-r--r--drivers/bluetooth/hci_ldisc.c29
1 files changed, 28 insertions, 1 deletions
diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c
index 1363dc616ace..b1e8083044ce 100644
--- a/drivers/bluetooth/hci_ldisc.c
+++ b/drivers/bluetooth/hci_ldisc.c
@@ -264,10 +264,36 @@ static int hci_uart_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
264static int hci_uart_setup(struct hci_dev *hdev) 264static int hci_uart_setup(struct hci_dev *hdev)
265{ 265{
266 struct hci_uart *hu = hci_get_drvdata(hdev); 266 struct hci_uart *hu = hci_get_drvdata(hdev);
267 struct hci_rp_read_local_version *ver;
268 struct sk_buff *skb;
267 269
268 if (hu->proto->setup) 270 if (hu->proto->setup)
269 return hu->proto->setup(hu); 271 return hu->proto->setup(hu);
270 272
273 if (!test_bit(HCI_UART_VND_DETECT, &hu->hdev_flags))
274 return 0;
275
276 skb = __hci_cmd_sync(hdev, HCI_OP_READ_LOCAL_VERSION, 0, NULL,
277 HCI_INIT_TIMEOUT);
278 if (IS_ERR(skb)) {
279 BT_ERR("%s: Reading local version information failed (%ld)",
280 hdev->name, PTR_ERR(skb));
281 return 0;
282 }
283
284 if (skb->len != sizeof(*ver)) {
285 BT_ERR("%s: Event length mismatch for version information",
286 hdev->name);
287 goto done;
288 }
289
290 ver = (struct hci_rp_read_local_version *)skb->data;
291
292 switch (le16_to_cpu(ver->manufacturer)) {
293 }
294
295done:
296 kfree_skb(skb);
271 return 0; 297 return 0;
272} 298}
273 299
@@ -497,7 +523,8 @@ static int hci_uart_set_flags(struct hci_uart *hu, unsigned long flags)
497 BIT(HCI_UART_RESET_ON_INIT) | 523 BIT(HCI_UART_RESET_ON_INIT) |
498 BIT(HCI_UART_CREATE_AMP) | 524 BIT(HCI_UART_CREATE_AMP) |
499 BIT(HCI_UART_INIT_PENDING) | 525 BIT(HCI_UART_INIT_PENDING) |
500 BIT(HCI_UART_EXT_CONFIG); 526 BIT(HCI_UART_EXT_CONFIG) |
527 BIT(HCI_UART_VND_DETECT);
501 528
502 if (flags & ~valid_flags) 529 if (flags & ~valid_flags)
503 return -EINVAL; 530 return -EINVAL;