aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@intel.com>2015-02-17 08:05:21 -0500
committerMarcel Holtmann <marcel@holtmann.org>2015-02-17 12:52:39 -0500
commit0af801b9bf34e3eb9f86a210e9928d42922f6631 (patch)
tree41f97e73ed67162099992ed2aed334334fad209c /net/bluetooth
parent315917e0a6d552a33f774935d8897ec1697605dd (diff)
Bluetooth: Fix AMP init for certain AMP controllers
Some AMP controllers do not support the Read Local Features HCI commands (even though according to the spec they should). Luckily they at least correctly omit this from the supported commands bitmask, so we can work around the issue by creating a second AMP init phase and issuing the HCI command conditionally there. Signed-off-by: Johan Hedberg <johan.hedberg@intel.com> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net/bluetooth')
-rw-r--r--net/bluetooth/hci_core.c30
1 files changed, 20 insertions, 10 deletions
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 4135a4406aed..980260846d25 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -390,7 +390,7 @@ static void bredr_init(struct hci_request *req)
390 hci_req_add(req, HCI_OP_READ_BD_ADDR, 0, NULL); 390 hci_req_add(req, HCI_OP_READ_BD_ADDR, 0, NULL);
391} 391}
392 392
393static void amp_init(struct hci_request *req) 393static void amp_init1(struct hci_request *req)
394{ 394{
395 req->hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_BLOCK_BASED; 395 req->hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_BLOCK_BASED;
396 396
@@ -400,9 +400,6 @@ static void amp_init(struct hci_request *req)
400 /* Read Local Supported Commands */ 400 /* Read Local Supported Commands */
401 hci_req_add(req, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL); 401 hci_req_add(req, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL);
402 402
403 /* Read Local Supported Features */
404 hci_req_add(req, HCI_OP_READ_LOCAL_FEATURES, 0, NULL);
405
406 /* Read Local AMP Info */ 403 /* Read Local AMP Info */
407 hci_req_add(req, HCI_OP_READ_LOCAL_AMP_INFO, 0, NULL); 404 hci_req_add(req, HCI_OP_READ_LOCAL_AMP_INFO, 0, NULL);
408 405
@@ -416,6 +413,16 @@ static void amp_init(struct hci_request *req)
416 hci_req_add(req, HCI_OP_READ_LOCATION_DATA, 0, NULL); 413 hci_req_add(req, HCI_OP_READ_LOCATION_DATA, 0, NULL);
417} 414}
418 415
416static void amp_init2(struct hci_request *req)
417{
418 /* Read Local Supported Features. Not all AMP controllers
419 * support this so it's placed conditionally in the second
420 * stage init.
421 */
422 if (req->hdev->commands[14] & 0x20)
423 hci_req_add(req, HCI_OP_READ_LOCAL_FEATURES, 0, NULL);
424}
425
419static void hci_init1_req(struct hci_request *req, unsigned long opt) 426static void hci_init1_req(struct hci_request *req, unsigned long opt)
420{ 427{
421 struct hci_dev *hdev = req->hdev; 428 struct hci_dev *hdev = req->hdev;
@@ -432,7 +439,7 @@ static void hci_init1_req(struct hci_request *req, unsigned long opt)
432 break; 439 break;
433 440
434 case HCI_AMP: 441 case HCI_AMP:
435 amp_init(req); 442 amp_init1(req);
436 break; 443 break;
437 444
438 default: 445 default:
@@ -578,6 +585,9 @@ static void hci_init2_req(struct hci_request *req, unsigned long opt)
578{ 585{
579 struct hci_dev *hdev = req->hdev; 586 struct hci_dev *hdev = req->hdev;
580 587
588 if (hdev->dev_type == HCI_AMP)
589 return amp_init2(req);
590
581 if (lmp_bredr_capable(hdev)) 591 if (lmp_bredr_capable(hdev))
582 bredr_setup(req); 592 bredr_setup(req);
583 else 593 else
@@ -896,17 +906,17 @@ static int __hci_init(struct hci_dev *hdev)
896 &dut_mode_fops); 906 &dut_mode_fops);
897 } 907 }
898 908
909 err = __hci_req_sync(hdev, hci_init2_req, 0, HCI_INIT_TIMEOUT);
910 if (err < 0)
911 return err;
912
899 /* HCI_BREDR covers both single-mode LE, BR/EDR and dual-mode 913 /* HCI_BREDR covers both single-mode LE, BR/EDR and dual-mode
900 * BR/EDR/LE type controllers. AMP controllers only need the 914 * BR/EDR/LE type controllers. AMP controllers only need the
901 * first stage init. 915 * first two stages of init.
902 */ 916 */
903 if (hdev->dev_type != HCI_BREDR) 917 if (hdev->dev_type != HCI_BREDR)
904 return 0; 918 return 0;
905 919
906 err = __hci_req_sync(hdev, hci_init2_req, 0, HCI_INIT_TIMEOUT);
907 if (err < 0)
908 return err;
909
910 err = __hci_req_sync(hdev, hci_init3_req, 0, HCI_INIT_TIMEOUT); 920 err = __hci_req_sync(hdev, hci_init3_req, 0, HCI_INIT_TIMEOUT);
911 if (err < 0) 921 if (err < 0)
912 return err; 922 return err;