aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth/hci_conn.c
diff options
context:
space:
mode:
authorJaikumar Ganesh <jaikumar@google.com>2011-05-23 21:06:04 -0400
committerGustavo F. Padovan <padovan@profusion.mobi>2011-06-08 15:58:19 -0400
commit14b12d0b98f87162b7e9e93dde66d1af97886567 (patch)
tree3ee2430863ad890b9b36ee4172fadc5147a01ad0 /net/bluetooth/hci_conn.c
parent96d97a673d42408c0f960cc54d44be7629343bce (diff)
Bluetooth: Add BT_POWER L2CAP socket option.
Add BT_POWER socket option used to control the power characteristics of the underlying ACL link. When the remote end has put the link in sniff mode and the host stack wants to send data we need need to explicitly exit sniff mode to work well with certain devices (For example, A2DP on Plantronics Voyager 855). However, this causes problems with HID devices. Hence, moving into active mode when sending data, irrespective of who set the sniff mode has been made as a socket option. By default, we will move into active mode. HID devices can set the L2CAP socket option to prevent this from happening. Currently, this has been implemented for L2CAP sockets. This has been tested with incoming and outgoing L2CAP sockets for HID and A2DP. Based on discussions on linux-bluetooth and patches submitted by Andrei Emeltchenko. Signed-off-by: Jaikumar Ganesh <jaikumar@google.com> Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
Diffstat (limited to 'net/bluetooth/hci_conn.c')
-rw-r--r--net/bluetooth/hci_conn.c9
1 files changed, 6 insertions, 3 deletions
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index ce67d0ff486f..0408a93570d6 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -507,7 +507,7 @@ struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8
507 if (acl->state == BT_CONNECTED && 507 if (acl->state == BT_CONNECTED &&
508 (sco->state == BT_OPEN || sco->state == BT_CLOSED)) { 508 (sco->state == BT_OPEN || sco->state == BT_CLOSED)) {
509 acl->power_save = 1; 509 acl->power_save = 1;
510 hci_conn_enter_active_mode(acl); 510 hci_conn_enter_active_mode(acl, BT_POWER_FORCE_ACTIVE_ON);
511 511
512 if (test_bit(HCI_CONN_MODE_CHANGE_PEND, &acl->pend)) { 512 if (test_bit(HCI_CONN_MODE_CHANGE_PEND, &acl->pend)) {
513 /* defer SCO setup until mode change completed */ 513 /* defer SCO setup until mode change completed */
@@ -688,7 +688,7 @@ int hci_conn_switch_role(struct hci_conn *conn, __u8 role)
688EXPORT_SYMBOL(hci_conn_switch_role); 688EXPORT_SYMBOL(hci_conn_switch_role);
689 689
690/* Enter active mode */ 690/* Enter active mode */
691void hci_conn_enter_active_mode(struct hci_conn *conn) 691void hci_conn_enter_active_mode(struct hci_conn *conn, __u8 force_active)
692{ 692{
693 struct hci_dev *hdev = conn->hdev; 693 struct hci_dev *hdev = conn->hdev;
694 694
@@ -697,7 +697,10 @@ void hci_conn_enter_active_mode(struct hci_conn *conn)
697 if (test_bit(HCI_RAW, &hdev->flags)) 697 if (test_bit(HCI_RAW, &hdev->flags))
698 return; 698 return;
699 699
700 if (conn->mode != HCI_CM_SNIFF || !conn->power_save) 700 if (conn->mode != HCI_CM_SNIFF)
701 goto timer;
702
703 if (!conn->power_save && !force_active)
701 goto timer; 704 goto timer;
702 705
703 if (!test_and_set_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend)) { 706 if (!test_and_set_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend)) {