From: Johan Hedberg <johan.hedberg@gmail.com>
To: linux-bluetooth@vger.kernel.org
Subject: [PATCH v2 5/6] Bluetooth: Fix UUID/class mgmt command response synchronization
Date: Wed, 6 Mar 2013 09:29:27 +0200 [thread overview]
Message-ID: <1362554968-22174-6-git-send-email-johan.hedberg@gmail.com> (raw)
In-Reply-To: <1362554968-22174-1-git-send-email-johan.hedberg@gmail.com>
From: Johan Hedberg <johan.hedberg@intel.com>
We should only return a mgmt command complete once all HCI commands to a
mgmt_set_dev_class or mgmt_add/remove_uuid command have completed. This
patch fixes the issue by having a proper async request complete callback
for these actions and responding to user space in the callback.
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
---
net/bluetooth/mgmt.c | 67 +++++++++++++++++++++++++++++++++++---------------
1 file changed, 47 insertions(+), 20 deletions(-)
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index aa54bde..55fd7b5 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -1381,6 +1381,32 @@ static u8 get_uuid_size(const u8 *uuid)
return 16;
}
+static void mgmt_class_complete(struct hci_dev *hdev, u16 mgmt_op, u8 status)
+{
+ struct pending_cmd *cmd;
+
+ hci_dev_lock(hdev);
+
+ cmd = mgmt_pending_find(mgmt_op, hdev);
+ if (!cmd)
+ goto unlock;
+
+ cmd_complete(cmd->sk, cmd->index, cmd->opcode, mgmt_status(status),
+ hdev->dev_class, 3);
+
+ mgmt_pending_remove(cmd);
+
+unlock:
+ hci_dev_unlock(hdev);
+}
+
+static void add_uuid_complete(struct hci_dev *hdev, u8 status)
+{
+ BT_DBG("status 0x%02x", status);
+
+ mgmt_class_complete(hdev, MGMT_OP_ADD_UUID, status);
+}
+
static int add_uuid(struct sock *sk, struct hci_dev *hdev, void *data, u16 len)
{
struct mgmt_cp_add_uuid *cp = data;
@@ -1416,9 +1442,7 @@ static int add_uuid(struct sock *sk, struct hci_dev *hdev, void *data, u16 len)
update_class(&req);
update_eir(&req);
- hci_req_run(&req, NULL);
-
- if (!test_bit(HCI_PENDING_CLASS, &hdev->dev_flags)) {
+ if (hci_req_run(&req, add_uuid_complete) < 0) {
err = cmd_complete(sk, hdev->id, MGMT_OP_ADD_UUID, 0,
hdev->dev_class, 3);
goto failed;
@@ -1451,6 +1475,13 @@ static bool enable_service_cache(struct hci_dev *hdev)
return false;
}
+static void remove_uuid_complete(struct hci_dev *hdev, u8 status)
+{
+ BT_DBG("status 0x%02x", status);
+
+ mgmt_class_complete(hdev, MGMT_OP_REMOVE_UUID, status);
+}
+
static int remove_uuid(struct sock *sk, struct hci_dev *hdev, void *data,
u16 len)
{
@@ -1506,9 +1537,7 @@ update_class:
update_class(&req);
update_eir(&req);
- hci_req_run(&req, NULL);
-
- if (!test_bit(HCI_PENDING_CLASS, &hdev->dev_flags)) {
+ if (hci_req_run(&req, remove_uuid_complete) < 0) {
err = cmd_complete(sk, hdev->id, MGMT_OP_REMOVE_UUID, 0,
hdev->dev_class, 3);
goto unlock;
@@ -1527,6 +1556,13 @@ unlock:
return err;
}
+static void set_class_complete(struct hci_dev *hdev, u8 status)
+{
+ BT_DBG("status 0x%02x", status);
+
+ mgmt_class_complete(hdev, MGMT_OP_SET_DEV_CLASS, status);
+}
+
static int set_dev_class(struct sock *sk, struct hci_dev *hdev, void *data,
u16 len)
{
@@ -1575,9 +1611,7 @@ static int set_dev_class(struct sock *sk, struct hci_dev *hdev, void *data,
update_class(&req);
- hci_req_run(&req, NULL);
-
- if (!test_bit(HCI_PENDING_CLASS, &hdev->dev_flags)) {
+ if (hci_req_run(&req, set_class_complete) < 0) {
err = cmd_complete(sk, hdev->id, MGMT_OP_SET_DEV_CLASS, 0,
hdev->dev_class, 3);
goto unlock;
@@ -3705,21 +3739,14 @@ int mgmt_ssp_enable_complete(struct hci_dev *hdev, u8 enable, u8 status)
return err;
}
-static void class_rsp(struct pending_cmd *cmd, void *data)
+static void sk_lookup(struct pending_cmd *cmd, void *data)
{
struct cmd_lookup *match = data;
- cmd_complete(cmd->sk, cmd->index, cmd->opcode, match->mgmt_status,
- match->hdev->dev_class, 3);
-
- list_del(&cmd->list);
-
if (match->sk == NULL) {
match->sk = cmd->sk;
sock_hold(match->sk);
}
-
- mgmt_pending_free(cmd);
}
int mgmt_set_class_of_dev_complete(struct hci_dev *hdev, u8 *dev_class,
@@ -3730,9 +3757,9 @@ int mgmt_set_class_of_dev_complete(struct hci_dev *hdev, u8 *dev_class,
clear_bit(HCI_PENDING_CLASS, &hdev->dev_flags);
- mgmt_pending_foreach(MGMT_OP_SET_DEV_CLASS, hdev, class_rsp, &match);
- mgmt_pending_foreach(MGMT_OP_ADD_UUID, hdev, class_rsp, &match);
- mgmt_pending_foreach(MGMT_OP_REMOVE_UUID, hdev, class_rsp, &match);
+ mgmt_pending_foreach(MGMT_OP_SET_DEV_CLASS, hdev, sk_lookup, &match);
+ mgmt_pending_foreach(MGMT_OP_ADD_UUID, hdev, sk_lookup, &match);
+ mgmt_pending_foreach(MGMT_OP_REMOVE_UUID, hdev, sk_lookup, &match);
if (!status)
err = mgmt_event(MGMT_EV_CLASS_OF_DEV_CHANGED, hdev, dev_class,
--
1.7.10.4
next prev parent reply other threads:[~2013-03-06 7:29 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-03-06 7:29 [PATCH v2 0/6] Bluetooth: HCI command synchronisation fixes Johan Hedberg
2013-03-06 7:29 ` [PATCH v2 1/6] Bluetooth: Move power on HCI command updates to their own function Johan Hedberg
2013-03-06 7:29 ` [PATCH v2 2/6] Bluetooth: Update mgmt powered HCI commands to use async requests Johan Hedberg
2013-03-06 7:29 ` [PATCH v2 3/6] Bluetooth: Wait for HCI command completion with mgmt_set_powered Johan Hedberg
2013-03-06 7:29 ` [PATCH v2 4/6] Bluetooth: Fix busy condition testing for EIR and class updates Johan Hedberg
2013-03-06 7:29 ` Johan Hedberg [this message]
2013-03-06 7:29 ` [PATCH v2 6/6] Bluetooth: Remove useless HCI_PENDING_CLASS flag Johan Hedberg
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1362554968-22174-6-git-send-email-johan.hedberg@gmail.com \
--to=johan.hedberg@gmail.com \
--cc=linux-bluetooth@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.