aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth
diff options
context:
space:
mode:
authorAndre Guedes <andre.guedes@openbossa.org>2013-03-27 19:04:56 -0400
committerJohan Hedberg <johan.hedberg@intel.com>2013-04-04 04:12:33 -0400
commit3e13fa1e1fab479940728272b6425d343e0c0f84 (patch)
tree1d4557f4d37cb982a95aec9456cf9c57e7500fa3 /net/bluetooth
parent33720450bb811a0cec1f0147bf8a1801113fa94d (diff)
Bluetooth: Fix hci_inquiry ioctl usage
Since the HCI request framework was properly fixed, the hci_req_sync call, in hci_inquiry, will return as soon as the HCI command completes (not the Inquiry procedure). However, in inquiry ioctl implementation, we want to sleep the user process until the inquiry procedure finishes. This patch changes hci_inquiry so, in case the HCI Inquiry command was executed successfully, it waits the HCI_INQUIRY flag to be cleared. This way, the user process will sleep until the inquiry procedure finishes. Signed-off-by: Andre Guedes <andre.guedes@openbossa.org> Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Diffstat (limited to 'net/bluetooth')
-rw-r--r--net/bluetooth/hci_core.c13
-rw-r--r--net/bluetooth/hci_event.c5
2 files changed, 18 insertions, 0 deletions
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index cfcad5423f1c..123992984a7c 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -818,6 +818,12 @@ static void hci_inq_req(struct hci_request *req, unsigned long opt)
818 hci_req_add(req, HCI_OP_INQUIRY, sizeof(cp), &cp); 818 hci_req_add(req, HCI_OP_INQUIRY, sizeof(cp), &cp);
819} 819}
820 820
821static int wait_inquiry(void *word)
822{
823 schedule();
824 return signal_pending(current);
825}
826
821int hci_inquiry(void __user *arg) 827int hci_inquiry(void __user *arg)
822{ 828{
823 __u8 __user *ptr = arg; 829 __u8 __user *ptr = arg;
@@ -849,6 +855,13 @@ int hci_inquiry(void __user *arg)
849 timeo); 855 timeo);
850 if (err < 0) 856 if (err < 0)
851 goto done; 857 goto done;
858
859 /* Wait until Inquiry procedure finishes (HCI_INQUIRY flag is
860 * cleared). If it is interrupted by a signal, return -EINTR.
861 */
862 if (wait_on_bit(&hdev->flags, HCI_INQUIRY, wait_inquiry,
863 TASK_INTERRUPTIBLE))
864 return -EINTR;
852 } 865 }
853 866
854 /* for unlimited number of responses we will use buffer with 867 /* for unlimited number of responses we will use buffer with
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 8efb9c0d9b2c..7e7fbca59439 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -48,6 +48,8 @@ static void hci_cc_inquiry_cancel(struct hci_dev *hdev, struct sk_buff *skb)
48 } 48 }
49 49
50 clear_bit(HCI_INQUIRY, &hdev->flags); 50 clear_bit(HCI_INQUIRY, &hdev->flags);
51 smp_mb__after_clear_bit(); /* wake_up_bit advises about this barrier */
52 wake_up_bit(&hdev->flags, HCI_INQUIRY);
51 53
52 hci_dev_lock(hdev); 54 hci_dev_lock(hdev);
53 hci_discovery_set_state(hdev, DISCOVERY_STOPPED); 55 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
@@ -1603,6 +1605,9 @@ static void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1603 if (!test_and_clear_bit(HCI_INQUIRY, &hdev->flags)) 1605 if (!test_and_clear_bit(HCI_INQUIRY, &hdev->flags))
1604 return; 1606 return;
1605 1607
1608 smp_mb__after_clear_bit(); /* wake_up_bit advises about this barrier */
1609 wake_up_bit(&hdev->flags, HCI_INQUIRY);
1610
1606 if (!test_bit(HCI_MGMT, &hdev->dev_flags)) 1611 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
1607 return; 1612 return;
1608 1613