Return-Path: From: Andrei Emeltchenko To: linux-bluetooth@vger.kernel.org Subject: [RFCv0 07/19] Bluetooth: AMP: Use HCI callback for Read AMP Info Date: Fri, 29 Jun 2012 17:46:40 +0300 Message-Id: <1340981212-21709-8-git-send-email-Andrei.Emeltchenko.news@gmail.com> In-Reply-To: <1340981212-21709-1-git-send-email-Andrei.Emeltchenko.news@gmail.com> References: <1340981212-21709-1-git-send-email-Andrei.Emeltchenko.news@gmail.com> Sender: linux-bluetooth-owner@vger.kernel.org List-ID: From: Andrei Emeltchenko Adds Read Local AMP Info HCI command with callback to be executed when receiving command complete event. Signed-off-by: Andrei Emeltchenko --- include/net/bluetooth/amp.h | 19 +++++++++++++ net/bluetooth/Makefile | 2 +- net/bluetooth/a2mp.c | 25 ++++++++--------- net/bluetooth/amp.c | 63 +++++++++++++++++++++++++++++++++++++++++++ net/bluetooth/hci_event.c | 6 ++++- 5 files changed, 101 insertions(+), 14 deletions(-) create mode 100644 include/net/bluetooth/amp.h create mode 100644 net/bluetooth/amp.c diff --git a/include/net/bluetooth/amp.h b/include/net/bluetooth/amp.h new file mode 100644 index 0000000..ec7bea7 --- /dev/null +++ b/include/net/bluetooth/amp.h @@ -0,0 +1,19 @@ +/* + Copyright (c) 2011,2012 Intel Corp. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 and + only version 2 as published by the Free Software Foundation. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. +*/ + +#ifndef __AMP_H +#define __AMP_H + +void amp_read_loc_info(struct hci_dev *hdev, struct amp_mgr *mgr); + +#endif /* __AMP_H */ diff --git a/net/bluetooth/Makefile b/net/bluetooth/Makefile index fa6d94a..dea6a28 100644 --- a/net/bluetooth/Makefile +++ b/net/bluetooth/Makefile @@ -10,4 +10,4 @@ obj-$(CONFIG_BT_HIDP) += hidp/ bluetooth-y := af_bluetooth.o hci_core.o hci_conn.o hci_event.o mgmt.o \ hci_sock.o hci_sysfs.o l2cap_core.o l2cap_sock.o smp.o sco.o lib.o \ - a2mp.o + a2mp.o amp.o diff --git a/net/bluetooth/a2mp.c b/net/bluetooth/a2mp.c index 2ea3dcf..f11feb0 100644 --- a/net/bluetooth/a2mp.c +++ b/net/bluetooth/a2mp.c @@ -16,6 +16,7 @@ #include #include #include +#include /* A2MP build & send command helper functions */ static struct a2mp_cmd *__a2mp_build(u8 code, u8 ident, u16 len, void *data) @@ -189,24 +190,24 @@ static int a2mp_getinfo_req(struct amp_mgr *mgr, struct sk_buff *skb, BT_DBG("id %d", req->id); - rsp.id = req->id; - rsp.status = A2MP_STATUS_INVALID_CTRL_ID; - hdev = hci_dev_get(req->id); - if (hdev && hdev->amp_type != HCI_BREDR) { - rsp.status = 0; - rsp.total_bw = cpu_to_le32(hdev->amp_total_bw); - rsp.max_bw = cpu_to_le32(hdev->amp_max_bw); - rsp.min_latency = cpu_to_le32(hdev->amp_min_latency); - rsp.pal_cap = cpu_to_le16(hdev->amp_pal_cap); - rsp.assoc_size = cpu_to_le16(hdev->amp_assoc_size); - } + if (!hdev) + goto send_err; - if (hdev) + if (hdev->amp_type != HCI_BREDR) { + amp_read_loc_info(hdev, mgr); + goto done; + } else { hci_dev_put(hdev); + } + +send_err: + rsp.id = req->id; + rsp.status = A2MP_STATUS_INVALID_CTRL_ID; a2mp_send(mgr, A2MP_GETINFO_RSP, hdr->ident, sizeof(rsp), &rsp); +done: skb_pull(skb, sizeof(*req)); return 0; } diff --git a/net/bluetooth/amp.c b/net/bluetooth/amp.c new file mode 100644 index 0000000..4aea7be --- /dev/null +++ b/net/bluetooth/amp.c @@ -0,0 +1,63 @@ +/* + Copyright (c) 2011,2012 Intel Corp. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 and + only version 2 as published by the Free Software Foundation. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. +*/ + +#include +#include +#include +#include +#include +#include + +static void amp_read_loc_info_complete(struct hci_dev *hdev, + struct hci_cb_cmd *cmd) +{ + struct amp_mgr *mgr = cmd->opt; + struct a2mp_info_rsp rsp; + + BT_DBG("%s cmd %p mgr %p", hdev->name, cmd, cmd->opt); + + rsp.id = hdev->id; + rsp.status = A2MP_STATUS_INVALID_CTRL_ID; + + if (hdev->amp_type != HCI_BREDR) { + rsp.status = 0; + rsp.total_bw = cpu_to_le32(hdev->amp_total_bw); + rsp.max_bw = cpu_to_le32(hdev->amp_max_bw); + rsp.min_latency = cpu_to_le32(hdev->amp_min_latency); + rsp.pal_cap = cpu_to_le16(hdev->amp_pal_cap); + rsp.assoc_size = cpu_to_le16(hdev->amp_assoc_size); + } + + a2mp_send(mgr, A2MP_GETINFO_RSP, mgr->ident, sizeof(rsp), &rsp); +} + +static void cb_destructor(struct hci_dev *hdev, struct hci_cb_cmd *cmd) +{ + struct amp_mgr *mgr = cmd->opt; + + BT_DBG("Destructor cmd %p mgr %p", cmd, mgr); + + hci_dev_put(hdev); + amp_mgr_put(mgr); + kfree(cmd); +} + +void amp_read_loc_info(struct hci_dev *hdev, struct amp_mgr *mgr) +{ + BT_DBG("%s mgr %p", hdev->name, mgr); + + amp_mgr_get(mgr); + + hci_cmd_cb(hdev, HCI_OP_READ_LOCAL_AMP_INFO, 0, NULL, + amp_read_loc_info_complete, mgr, cb_destructor, GFP_KERNEL); +} diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index f4c679b..9b34417 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -29,6 +29,7 @@ #include #include +#include /* Handle HCI Event packets */ @@ -845,7 +846,7 @@ static void hci_cc_read_local_amp_info(struct hci_dev *hdev, BT_DBG("%s status 0x%x", hdev->name, rp->status); if (rp->status) - return; + goto process_cb; hdev->amp_status = rp->amp_status; hdev->amp_total_bw = __le32_to_cpu(rp->total_bw); @@ -859,6 +860,9 @@ static void hci_cc_read_local_amp_info(struct hci_dev *hdev, hdev->amp_max_flush_to = __le32_to_cpu(rp->max_flush_to); hci_req_complete(hdev, HCI_OP_READ_LOCAL_AMP_INFO, rp->status); + +process_cb: + hci_process_cb(hdev, HCI_OP_READ_LOCAL_AMP_INFO, rp->status); } static void hci_cc_delete_stored_link_key(struct hci_dev *hdev, -- 1.7.9.5