summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@nokia.com>2011-01-26 12:07:10 +0100
committerGustavo F. Padovan <padovan@profusion.mobi>2011-02-08 04:40:05 +0100
commit053f0211d3b1a991f06a7b4aec5b762e42d7c6a4 (patch)
tree346f16fe1eac7dac9a8637e814ac83c45297a613 /net
parentBluetooth: Add flag to track managment controlled adapters (diff)
downloadlinux-053f0211d3b1a991f06a7b4aec5b762e42d7c6a4.tar.xz
linux-053f0211d3b1a991f06a7b4aec5b762e42d7c6a4.zip
Bluetooth: Add send_mode_rsp convenience function for mgmt.c
Several management commands have similar responses but they are not always sent asynchronously. To enable synchronous sending (from the managment command handler function) a send_mode_rsp function is added. Signed-off-by: Johan Hedberg <johan.hedberg@nokia.com> Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
Diffstat (limited to 'net')
-rw-r--r--net/bluetooth/mgmt.c50
1 files changed, 29 insertions, 21 deletions
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 5f871b385a27..13872ae219c9 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -481,6 +481,34 @@ failed:
return err;
}
+static int send_mode_rsp(struct sock *sk, u16 opcode, u16 index, u8 val)
+{
+ struct mgmt_hdr *hdr;
+ struct mgmt_ev_cmd_complete *ev;
+ struct mgmt_mode *rp;
+ struct sk_buff *skb;
+
+ skb = alloc_skb(sizeof(*hdr) + sizeof(*ev) + sizeof(*rp), GFP_ATOMIC);
+ if (!skb)
+ return -ENOMEM;
+
+ hdr = (void *) skb_put(skb, sizeof(*hdr));
+ hdr->opcode = cpu_to_le16(MGMT_EV_CMD_COMPLETE);
+ hdr->len = cpu_to_le16(sizeof(*ev) + sizeof(*rp));
+
+ ev = (void *) skb_put(skb, sizeof(*ev));
+ put_unaligned_le16(opcode, &ev->opcode);
+
+ rp = (void *) skb_put(skb, sizeof(*rp));
+ put_unaligned_le16(index, &rp->index);
+ rp->val = val;
+
+ if (sock_queue_rcv_skb(sk, skb) < 0)
+ kfree_skb(skb);
+
+ return 0;
+}
+
int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen)
{
unsigned char *buf;
@@ -594,33 +622,13 @@ struct cmd_lookup {
static void mode_rsp(struct pending_cmd *cmd, void *data)
{
- struct mgmt_hdr *hdr;
- struct mgmt_ev_cmd_complete *ev;
- struct mgmt_mode *rp;
struct mgmt_mode *cp = cmd->cmd;
- struct sk_buff *skb;
struct cmd_lookup *match = data;
if (cp->val != match->val)
return;
- skb = alloc_skb(sizeof(*hdr) + sizeof(*ev) + sizeof(*rp), GFP_ATOMIC);
- if (!skb)
- return;
-
- hdr = (void *) skb_put(skb, sizeof(*hdr));
- hdr->opcode = cpu_to_le16(MGMT_EV_CMD_COMPLETE);
- hdr->len = cpu_to_le16(sizeof(*ev) + sizeof(*rp));
-
- ev = (void *) skb_put(skb, sizeof(*ev));
- put_unaligned_le16(cmd->opcode, &ev->opcode);
-
- rp = (void *) skb_put(skb, sizeof(*rp));
- put_unaligned_le16(cmd->index, &rp->index);
- rp->val = cp->val;
-
- if (sock_queue_rcv_skb(cmd->sk, skb) < 0)
- kfree_skb(skb);
+ send_mode_rsp(cmd->sk, cmd->opcode, cmd->index, cp->val);
list_del(&cmd->list);