linux-bluetooth.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/2] Bluetooth: Add custom HCI command termination support
@ 2013-04-03 19:11 Johan Hedberg
  2013-04-03 19:11 ` [PATCH 1/2] Bluetooth: Add support for custom event terminated commands Johan Hedberg
  2013-04-03 19:11 ` [PATCH 2/2] Bluetooth: Add __hci_cmd_sync_ev function Johan Hedberg
  0 siblings, 2 replies; 5+ messages in thread
From: Johan Hedberg @ 2013-04-03 19:11 UTC (permalink / raw)
  To: linux-bluetooth

Hi,

These two patches add support for having commands that do not end with a
command complete event but with some other event. We know that this is
at least needed for the hdev->setup() routine for some specific hardware
where a vendor command doesn't result in command complete but a vendor
specific event instead.

Another option to doing it this way is to add a __hci_wait_evt_sync
function and do __hci_cmd_sync() + __hci_wait_evt_sync(). However,
considering that this has the risk of being racy if the needed event
comes between the two function calls I'd still prefer the solution
offered by this patch set.

Johan

----------------------------------------------------------------
Johan Hedberg (2):
      Bluetooth: Add support for custom event terminated commands
      Bluetooth: Add __hci_cmd_sync_ev function

 include/net/bluetooth/bluetooth.h |    1 +
 include/net/bluetooth/hci_core.h  |    4 ++++
 net/bluetooth/hci_core.c          |   32 ++++++++++++++++++++++++++------
 net/bluetooth/hci_event.c         |   11 ++++++++++-
 4 files changed, 41 insertions(+), 7 deletions(-)


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 1/2] Bluetooth: Add support for custom event terminated commands
  2013-04-03 19:11 [PATCH 0/2] Bluetooth: Add custom HCI command termination support Johan Hedberg
@ 2013-04-03 19:11 ` Johan Hedberg
  2013-04-03 19:25   ` Anderson Lizardo
  2013-04-03 19:11 ` [PATCH 2/2] Bluetooth: Add __hci_cmd_sync_ev function Johan Hedberg
  1 sibling, 1 reply; 5+ messages in thread
From: Johan Hedberg @ 2013-04-03 19:11 UTC (permalink / raw)
  To: linux-bluetooth

From: Johan Hedberg <johan.hedberg@intel.com>

This patch adds support for having commands within HCI requests that do
not result in a command complete but some other event. This is at least
needed for some vendor specific commands to be issued in the
hdev->setup() procecure, but might also be useful for other commands.

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
---
 include/net/bluetooth/bluetooth.h |    1 +
 include/net/bluetooth/hci_core.h  |    2 ++
 net/bluetooth/hci_core.c          |   10 +++++++++-
 net/bluetooth/hci_event.c         |   11 ++++++++++-
 4 files changed, 22 insertions(+), 2 deletions(-)

diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h
index ed6e955..591fee7 100644
--- a/include/net/bluetooth/bluetooth.h
+++ b/include/net/bluetooth/bluetooth.h
@@ -266,6 +266,7 @@ typedef void (*hci_req_complete_t)(struct hci_dev *hdev, u8 status);
 
 struct hci_req_ctrl {
 	bool			start;
+	u8			event;
 	hci_req_complete_t	complete;
 };
 
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 064b057..8ee1381 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -1055,6 +1055,8 @@ struct hci_request {
 void hci_req_init(struct hci_request *req, struct hci_dev *hdev);
 int hci_req_run(struct hci_request *req, hci_req_complete_t complete);
 void hci_req_add(struct hci_request *req, u16 opcode, u32 plen, void *param);
+void hci_req_add_ev(struct hci_request *req, u16 opcode, u32 plen, void *param,
+		    u8 event);
 void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status);
 
 struct sk_buff *__hci_cmd_sync(struct hci_dev *hdev, u16 opcode, u32 plen,
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 689c959..6f71e4c 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -2622,7 +2622,8 @@ int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, void *param)
 }
 
 /* Queue a command to an asynchronous HCI request */
-void hci_req_add(struct hci_request *req, u16 opcode, u32 plen, void *param)
+void hci_req_add_ev(struct hci_request *req, u16 opcode, u32 plen, void *param,
+		    u8 event)
 {
 	struct hci_dev *hdev = req->hdev;
 	struct sk_buff *skb;
@@ -2646,9 +2647,16 @@ void hci_req_add(struct hci_request *req, u16 opcode, u32 plen, void *param)
 	if (skb_queue_empty(&req->cmd_q))
 		bt_cb(skb)->req.start = true;
 
+	bt_cb(skb)->req.event = event;
+
 	skb_queue_tail(&req->cmd_q, skb);
 }
 
+void hci_req_add(struct hci_request *req, u16 opcode, u32 plen, void *param)
+{
+	hci_req_add_ev(req, opcode, plen, param, 0);
+}
+
 /* Get data from the previously sent command */
 void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode)
 {
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 24906fb..5b922a0 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -2463,7 +2463,9 @@ static void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
 	if (opcode != HCI_OP_NOP)
 		del_timer(&hdev->cmd_timer);
 
-	hci_req_cmd_complete(hdev, opcode, ev->status);
+	if (ev->status ||
+	    ((hdev->sent_cmd && !bt_cb(hdev->sent_cmd)->req.event)))
+		hci_req_cmd_complete(hdev, opcode, ev->status);
 
 	if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
 		atomic_set(&hdev->cmd_cnt, 1);
@@ -3709,6 +3711,13 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
 
 	skb_pull(skb, HCI_EVENT_HDR_SIZE);
 
+	if (hdev->sent_cmd && bt_cb(hdev->sent_cmd)->req.event == event) {
+		struct hci_command_hdr *hdr = (void *) hdev->sent_cmd->data;
+		u16 opcode = __le16_to_cpu(hdr->opcode);
+
+		hci_req_cmd_complete(hdev, opcode, 0);
+	}
+
 	switch (event) {
 	case HCI_EV_INQUIRY_COMPLETE:
 		hci_inquiry_complete_evt(hdev, skb);
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 2/2] Bluetooth: Add __hci_cmd_sync_ev function
  2013-04-03 19:11 [PATCH 0/2] Bluetooth: Add custom HCI command termination support Johan Hedberg
  2013-04-03 19:11 ` [PATCH 1/2] Bluetooth: Add support for custom event terminated commands Johan Hedberg
@ 2013-04-03 19:11 ` Johan Hedberg
  1 sibling, 0 replies; 5+ messages in thread
From: Johan Hedberg @ 2013-04-03 19:11 UTC (permalink / raw)
  To: linux-bluetooth

From: Johan Hedberg <johan.hedberg@intel.com>

This patch adds a __hci_cmd_sync_ev function, analogous to
__hci_cmd_sync except that it also takes an event parameter to indicate
that the command completes with a special event instead of command
complete. Internally this new function takes advantage of the
hci_req_add_ev function introduced in the previous patch.

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
---
 include/net/bluetooth/hci_core.h |    2 ++
 net/bluetooth/hci_core.c         |   22 +++++++++++++++++-----
 2 files changed, 19 insertions(+), 5 deletions(-)

diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 8ee1381..be695e6 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -1061,6 +1061,8 @@ void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status);
 
 struct sk_buff *__hci_cmd_sync(struct hci_dev *hdev, u16 opcode, u32 plen,
 			       void *param, u32 timeout);
+struct sk_buff *__hci_cmd_sync_ev(struct hci_dev *hdev, u16 opcode, u32 plen,
+				  void *param, u8 event, u32 timeout);
 
 int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, void *param);
 void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags);
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 6f71e4c..d181992 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -79,7 +79,7 @@ static void hci_req_cancel(struct hci_dev *hdev, int err)
 	}
 }
 
-struct sk_buff *hci_get_cmd_complete(struct hci_dev *hdev, u16 opcode)
+struct sk_buff *hci_get_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 event)
 {
 	struct hci_ev_cmd_complete *ev;
 	struct hci_event_hdr *hdr;
@@ -100,6 +100,12 @@ struct sk_buff *hci_get_cmd_complete(struct hci_dev *hdev, u16 opcode)
 	hdr = (void *) skb->data;
 	skb_pull(skb, HCI_EVENT_HDR_SIZE);
 
+	if (event) {
+		if (hdr->evt != event)
+			goto failed;
+		return skb;
+	}
+
 	if (hdr->evt != HCI_EV_CMD_COMPLETE) {
 		BT_DBG("Last event is not cmd complete (0x%2.2x)", hdr->evt);
 		goto failed;
@@ -119,8 +125,8 @@ failed:
 	return ERR_PTR(-ENODATA);
 }
 
-struct sk_buff *__hci_cmd_sync(struct hci_dev *hdev, u16 opcode, u32 plen,
-			       void *param, u32 timeout)
+struct sk_buff *__hci_cmd_sync_ev(struct hci_dev *hdev, u16 opcode, u32 plen,
+				  void *param, u8 event, u32 timeout)
 {
 	DECLARE_WAITQUEUE(wait, current);
 	struct hci_request req;
@@ -130,7 +136,7 @@ struct sk_buff *__hci_cmd_sync(struct hci_dev *hdev, u16 opcode, u32 plen,
 
 	hci_req_init(&req, hdev);
 
-	hci_req_add(&req, opcode, plen, param);
+	hci_req_add_ev(&req, opcode, plen, param, event);
 
 	hdev->req_status = HCI_REQ_PEND;
 
@@ -169,7 +175,13 @@ struct sk_buff *__hci_cmd_sync(struct hci_dev *hdev, u16 opcode, u32 plen,
 	if (err < 0)
 		return ERR_PTR(err);
 
-	return hci_get_cmd_complete(hdev, opcode);
+	return hci_get_cmd_complete(hdev, opcode, event);
+}
+
+struct sk_buff *__hci_cmd_sync(struct hci_dev *hdev, u16 opcode, u32 plen,
+			       void *param, u32 timeout)
+{
+	return __hci_cmd_sync_ev(hdev, opcode, plen, param, 0, timeout);
 }
 
 /* Execute request and wait for completion. */
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH 1/2] Bluetooth: Add support for custom event terminated commands
  2013-04-03 19:11 ` [PATCH 1/2] Bluetooth: Add support for custom event terminated commands Johan Hedberg
@ 2013-04-03 19:25   ` Anderson Lizardo
  2013-04-03 19:39     ` Johan Hedberg
  0 siblings, 1 reply; 5+ messages in thread
From: Anderson Lizardo @ 2013-04-03 19:25 UTC (permalink / raw)
  To: Johan Hedberg; +Cc: linux-bluetooth

Hi Johan,

On Wed, Apr 3, 2013 at 3:11 PM, Johan Hedberg <johan.hedberg@gmail.com> wrote:
> -       hci_req_cmd_complete(hdev, opcode, ev->status);
> +       if (ev->status ||
> +           ((hdev->sent_cmd && !bt_cb(hdev->sent_cmd)->req.event)))
> +               hci_req_cmd_complete(hdev, opcode, ev->status);

Any reason for the double parenthesis after || ?

Regards,
-- 
Anderson Lizardo
Instituto Nokia de Tecnologia - INdT
Manaus - Brazil

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH 1/2] Bluetooth: Add support for custom event terminated commands
  2013-04-03 19:25   ` Anderson Lizardo
@ 2013-04-03 19:39     ` Johan Hedberg
  0 siblings, 0 replies; 5+ messages in thread
From: Johan Hedberg @ 2013-04-03 19:39 UTC (permalink / raw)
  To: Anderson Lizardo; +Cc: linux-bluetooth

Hi Lizardo,

On Wed, Apr 03, 2013, Anderson Lizardo wrote:
> On Wed, Apr 3, 2013 at 3:11 PM, Johan Hedberg <johan.hedberg@gmail.com> wrote:
> > -       hci_req_cmd_complete(hdev, opcode, ev->status);
> > +       if (ev->status ||
> > +           ((hdev->sent_cmd && !bt_cb(hdev->sent_cmd)->req.event)))
> > +               hci_req_cmd_complete(hdev, opcode, ev->status);
> 
> Any reason for the double parenthesis after || ?

Nope, just my own blindness :)

Johan

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2013-04-03 19:39 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-04-03 19:11 [PATCH 0/2] Bluetooth: Add custom HCI command termination support Johan Hedberg
2013-04-03 19:11 ` [PATCH 1/2] Bluetooth: Add support for custom event terminated commands Johan Hedberg
2013-04-03 19:25   ` Anderson Lizardo
2013-04-03 19:39     ` Johan Hedberg
2013-04-03 19:11 ` [PATCH 2/2] Bluetooth: Add __hci_cmd_sync_ev function Johan Hedberg

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).