Linux bluetooth development
 help / color / mirror / Atom feed
* Re: [RFC] Bluetooth: Set ISOC altsetting from within notify callback
From: Marcel Holtmann @ 2013-10-11 12:36 UTC (permalink / raw)
  To: Timo Müller; +Cc: linux-bluetooth
In-Reply-To: <5257EB7A.7010407@timomueller.eu>

Hi Timo,

>> Since the event handling is done within a workqueue, the notify
>> callback can now sleep. So no need to trigger a separate workqueue
>> from within the Bluetooth USB driver.
>> 
>> This should give a little bit better latency with the SCO packet
>> processing since the ISOC altsetting is correct from the beginning.
>> 
>> However I am not sure if we can actually sleep in the USB reset
>> handler and what we need to do to restore the correct altsetting
>> in there. This could potentially fail, so please test ;)
>> 
>> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
>> ---
>>  drivers/bluetooth/btusb.c | 34 ++++++++++++++--------------------
>>  1 file changed, 14 insertions(+), 20 deletions(-)
>> 
>> diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
>> index f3dfc0a..32cae73 100644
>> --- a/drivers/bluetooth/btusb.c
>> +++ b/drivers/bluetooth/btusb.c
>> @@ -245,7 +245,6 @@ struct btusb_data {
>> 
>>  	unsigned long flags;
>> 
>> -	struct work_struct work;
>>  	struct work_struct waker;
>> 
>>  	struct usb_anchor tx_anchor;
>> @@ -685,7 +684,6 @@ static int btusb_close(struct hci_dev *hdev)
>>  	if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
>>  		return 0;
>> 
>> -	cancel_work_sync(&data->work);
>>  	cancel_work_sync(&data->waker);
>> 
>>  	clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
>> @@ -827,18 +825,6 @@ done:
>>  	return err;
>>  }
>> 
>> -static void btusb_notify(struct hci_dev *hdev, unsigned int evt)
>> -{
>> -	struct btusb_data *data = hci_get_drvdata(hdev);
>> -
>> -	BT_DBG("%s evt %d", hdev->name, evt);
>> -
>> -	if (hdev->conn_hash.sco_num != data->sco_num) {
>> -		data->sco_num = hdev->conn_hash.sco_num;
>> -		schedule_work(&data->work);
>> -	}
>> -}
>> -
>>  static inline int __set_isoc_interface(struct hci_dev *hdev, int altsetting)
>>  {
>>  	struct btusb_data *data = hci_get_drvdata(hdev);
>> @@ -882,9 +868,8 @@ static inline int __set_isoc_interface(struct hci_dev *hdev, int altsetting)
>>  	return 0;
>>  }
>> 
>> -static void btusb_work(struct work_struct *work)
>> +static void btusb_update_isoc_altsetting(struct btusb_data *data)
>>  {
>> -	struct btusb_data *data = container_of(work, struct btusb_data, work);
>>  	struct hci_dev *hdev = data->hdev;
>>  	int new_alts;
>>  	int err;
>> @@ -932,6 +917,18 @@ static void btusb_work(struct work_struct *work)
>>  	}
>>  }
>> 
>> +static void btusb_notify(struct hci_dev *hdev, unsigned int evt)
>> +{
>> +	struct btusb_data *data = hci_get_drvdata(hdev);
>> +
>> +	BT_DBG("%s evt %d", hdev->name, evt);
>> +
>> +	if (hdev->conn_hash.sco_num != data->sco_num) {
>> +		data->sco_num = hdev->conn_hash.sco_num;
>> +		btusb_update_isoc_altsetting(data);
>> +	}
>> +}
>> +
>>  static void btusb_waker(struct work_struct *work)
>>  {
>>  	struct btusb_data *data = container_of(work, struct btusb_data, waker);
>> @@ -1404,7 +1401,6 @@ static int btusb_probe(struct usb_interface *intf,
>> 
>>  	spin_lock_init(&data->lock);
>> 
>> -	INIT_WORK(&data->work, btusb_work);
>>  	INIT_WORK(&data->waker, btusb_waker);
>>  	spin_lock_init(&data->txlock);
>> 
>> @@ -1540,8 +1536,6 @@ static int btusb_suspend(struct usb_interface *intf, pm_message_t message)
>>  		return -EBUSY;
>>  	}
>> 
>> -	cancel_work_sync(&data->work);
>> -
>>  	btusb_stop_traffic(data);
>>  	usb_kill_anchored_urbs(&data->tx_anchor);
>> 
>> @@ -1606,8 +1600,8 @@ static int btusb_resume(struct usb_interface *intf)
>>  	play_deferred(data);
>>  	clear_bit(BTUSB_SUSPENDING, &data->flags);
>>  	spin_unlock_irq(&data->txlock);
>> -	schedule_work(&data->work);
>> 
>> +	btusb_update_isoc_altsetting(data);
>>  	return 0;
>> 
>>  failed:
>> 
> 
> I have been testing this patch for the last two days at the UPF in Vienna. It was running fine most of the time, but I experienced two crashes. Both crashes appeared when there was an active call and the phone transferred audio to the phone and back. Both times I wasn't able to reproduce, when I restarted everything and tested again it worked fine.
> 
> Unfortunately the kernel log is not complete but, when it failed the kernel reported:
> [147.344546] Bluetooth: hci0 SCO packet for unknown connection handle 5
> [147.354515] Bluetooth: hci0 SCO packet for unknown connection handle 21
> [147.354537] Bluetooth: hci0 SCO packet for unknown connection handle 29
> [147.354548] Bluetooth: hci0 SCO packet for unknown connection handle 65534
> [147.364574] Bluetooth: hci0 SCO packet for unknown connection handle 65532
> [147.364581] Bluetooth: hci0 SCO packet for unknown connection handle 27
> …

what kind of hardware where you testing with?

This handle mismatch normally means that our SCO packet frames are out of sync. I think we are not doing a good job trying to keep them nicely lined up.

For the crash, do you happen to have a backtrace of the crash. Personally I was worried about the reset handling and not the actual alternate setting switching.

Regards

Marcel


^ permalink raw reply

* [PATCH] Bluetooth: Add hdev parameter to hdev->send driver callback
From: Marcel Holtmann @ 2013-10-11 13:19 UTC (permalink / raw)
  To: linux-bluetooth

Instead of masking hdev inside the skb->dev parameter, hand it
directly to the driver as a parameter to hdev->send. This makes
the driver interface more clear and simpler.

This patch fixes all drivers to accept and handle the new parameter
of hdev->send callback. Special care has been taken for bpa10x
and btusb drivers that require having skb->dev set to hdev for
the URB transmit complete handlers.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
 drivers/bluetooth/bfusb.c        | 3 +--
 drivers/bluetooth/bluecard_cs.c  | 3 +--
 drivers/bluetooth/bpa10x.c       | 5 +++--
 drivers/bluetooth/bt3c_cs.c      | 3 +--
 drivers/bluetooth/btmrvl_main.c  | 4 +---
 drivers/bluetooth/btsdio.c       | 3 +--
 drivers/bluetooth/btuart_cs.c    | 3 +--
 drivers/bluetooth/btusb.c        | 5 +++--
 drivers/bluetooth/btwilink.c     | 5 +----
 drivers/bluetooth/dtl1_cs.c      | 3 +--
 drivers/bluetooth/hci_ldisc.c    | 3 +--
 drivers/bluetooth/hci_ll.c       | 1 -
 drivers/bluetooth/hci_vhci.c     | 3 +--
 include/net/bluetooth/hci_core.h | 2 +-
 net/bluetooth/hci_core.c         | 4 +---
 15 files changed, 18 insertions(+), 32 deletions(-)

diff --git a/drivers/bluetooth/bfusb.c b/drivers/bluetooth/bfusb.c
index b7b5bb8..a675849 100644
--- a/drivers/bluetooth/bfusb.c
+++ b/drivers/bluetooth/bfusb.c
@@ -464,9 +464,8 @@ static int bfusb_close(struct hci_dev *hdev)
 	return 0;
 }
 
-static int bfusb_send_frame(struct sk_buff *skb)
+static int bfusb_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
 {
-	struct hci_dev *hdev = (struct hci_dev *) skb->dev;
 	struct bfusb_data *data;
 	struct sk_buff *nskb;
 	unsigned char buf[3];
diff --git a/drivers/bluetooth/bluecard_cs.c b/drivers/bluetooth/bluecard_cs.c
index 395acde..9194a1b 100644
--- a/drivers/bluetooth/bluecard_cs.c
+++ b/drivers/bluetooth/bluecard_cs.c
@@ -658,10 +658,9 @@ static int bluecard_hci_close(struct hci_dev *hdev)
 }
 
 
-static int bluecard_hci_send_frame(struct sk_buff *skb)
+static int bluecard_hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
 {
 	bluecard_info_t *info;
-	struct hci_dev *hdev = (struct hci_dev *)(skb->dev);
 
 	if (!hdev) {
 		BT_ERR("Frame for unknown HCI device (hdev=NULL)");
diff --git a/drivers/bluetooth/bpa10x.c b/drivers/bluetooth/bpa10x.c
index 3188fb4..b9e4e62 100644
--- a/drivers/bluetooth/bpa10x.c
+++ b/drivers/bluetooth/bpa10x.c
@@ -350,9 +350,8 @@ static int bpa10x_flush(struct hci_dev *hdev)
 	return 0;
 }
 
-static int bpa10x_send_frame(struct sk_buff *skb)
+static int bpa10x_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
 {
-	struct hci_dev *hdev = (struct hci_dev *) skb->dev;
 	struct bpa10x_data *data = hci_get_drvdata(hdev);
 	struct usb_ctrlrequest *dr;
 	struct urb *urb;
@@ -364,6 +363,8 @@ static int bpa10x_send_frame(struct sk_buff *skb)
 	if (!test_bit(HCI_RUNNING, &hdev->flags))
 		return -EBUSY;
 
+	skb->dev = (void *) hdev;
+
 	urb = usb_alloc_urb(0, GFP_ATOMIC);
 	if (!urb)
 		return -ENOMEM;
diff --git a/drivers/bluetooth/bt3c_cs.c b/drivers/bluetooth/bt3c_cs.c
index d8e4b0d..fcd5fe9 100644
--- a/drivers/bluetooth/bt3c_cs.c
+++ b/drivers/bluetooth/bt3c_cs.c
@@ -415,10 +415,9 @@ static int bt3c_hci_close(struct hci_dev *hdev)
 }
 
 
-static int bt3c_hci_send_frame(struct sk_buff *skb)
+static int bt3c_hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
 {
 	bt3c_info_t *info;
-	struct hci_dev *hdev = (struct hci_dev *)(skb->dev);
 	unsigned long flags;
 
 	if (!hdev) {
diff --git a/drivers/bluetooth/btmrvl_main.c b/drivers/bluetooth/btmrvl_main.c
index 8ac4d93..547a447 100644
--- a/drivers/bluetooth/btmrvl_main.c
+++ b/drivers/bluetooth/btmrvl_main.c
@@ -187,7 +187,6 @@ static int btmrvl_send_sync_cmd(struct btmrvl_private *priv, u16 cmd_no,
 
 	bt_cb(skb)->pkt_type = MRVL_VENDOR_PKT;
 
-	skb->dev = (void *) priv->btmrvl_dev.hcidev;
 	skb_queue_head(&priv->adapter->tx_queue, skb);
 
 	priv->btmrvl_dev.sendcmdflag = true;
@@ -356,9 +355,8 @@ static void btmrvl_free_adapter(struct btmrvl_private *priv)
 	priv->adapter = NULL;
 }
 
-static int btmrvl_send_frame(struct sk_buff *skb)
+static int btmrvl_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
 {
-	struct hci_dev *hdev = (struct hci_dev *) skb->dev;
 	struct btmrvl_private *priv = NULL;
 
 	BT_DBG("type=%d, len=%d", skb->pkt_type, skb->len);
diff --git a/drivers/bluetooth/btsdio.c b/drivers/bluetooth/btsdio.c
index 72fe49e..b61440a 100644
--- a/drivers/bluetooth/btsdio.c
+++ b/drivers/bluetooth/btsdio.c
@@ -254,9 +254,8 @@ static int btsdio_flush(struct hci_dev *hdev)
 	return 0;
 }
 
-static int btsdio_send_frame(struct sk_buff *skb)
+static int btsdio_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
 {
-	struct hci_dev *hdev = (struct hci_dev *) skb->dev;
 	struct btsdio_data *data = hci_get_drvdata(hdev);
 
 	BT_DBG("%s", hdev->name);
diff --git a/drivers/bluetooth/btuart_cs.c b/drivers/bluetooth/btuart_cs.c
index d0b89ec..f567cd8 100644
--- a/drivers/bluetooth/btuart_cs.c
+++ b/drivers/bluetooth/btuart_cs.c
@@ -423,10 +423,9 @@ static int btuart_hci_close(struct hci_dev *hdev)
 }
 
 
-static int btuart_hci_send_frame(struct sk_buff *skb)
+static int btuart_hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
 {
 	btuart_info_t *info;
-	struct hci_dev *hdev = (struct hci_dev *)(skb->dev);
 
 	if (!hdev) {
 		BT_ERR("Frame for unknown HCI device (hdev=NULL)");
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index faa429f..621069c 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -716,9 +716,8 @@ static int btusb_flush(struct hci_dev *hdev)
 	return 0;
 }
 
-static int btusb_send_frame(struct sk_buff *skb)
+static int btusb_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
 {
-	struct hci_dev *hdev = (struct hci_dev *) skb->dev;
 	struct btusb_data *data = hci_get_drvdata(hdev);
 	struct usb_ctrlrequest *dr;
 	struct urb *urb;
@@ -730,6 +729,8 @@ static int btusb_send_frame(struct sk_buff *skb)
 	if (!test_bit(HCI_RUNNING, &hdev->flags))
 		return -EBUSY;
 
+	skb->dev = (void *) hdev;
+
 	switch (bt_cb(skb)->pkt_type) {
 	case HCI_COMMAND_PKT:
 		urb = usb_alloc_urb(0, GFP_ATOMIC);
diff --git a/drivers/bluetooth/btwilink.c b/drivers/bluetooth/btwilink.c
index 5e10fb0..f038dba 100644
--- a/drivers/bluetooth/btwilink.c
+++ b/drivers/bluetooth/btwilink.c
@@ -251,14 +251,11 @@ static int ti_st_close(struct hci_dev *hdev)
 	return err;
 }
 
-static int ti_st_send_frame(struct sk_buff *skb)
+static int ti_st_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
 {
-	struct hci_dev *hdev;
 	struct ti_st *hst;
 	long len;
 
-	hdev = (struct hci_dev *)skb->dev;
-
 	if (!test_bit(HCI_RUNNING, &hdev->flags))
 		return -EBUSY;
 
diff --git a/drivers/bluetooth/dtl1_cs.c b/drivers/bluetooth/dtl1_cs.c
index 2945141..ad1a2f9 100644
--- a/drivers/bluetooth/dtl1_cs.c
+++ b/drivers/bluetooth/dtl1_cs.c
@@ -382,10 +382,9 @@ static int dtl1_hci_close(struct hci_dev *hdev)
 }
 
 
-static int dtl1_hci_send_frame(struct sk_buff *skb)
+static int dtl1_hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
 {
 	dtl1_info_t *info;
-	struct hci_dev *hdev = (struct hci_dev *)(skb->dev);
 	struct sk_buff *s;
 	nsh_t nsh;
 
diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c
index bc68a44..b040546 100644
--- a/drivers/bluetooth/hci_ldisc.c
+++ b/drivers/bluetooth/hci_ldisc.c
@@ -234,9 +234,8 @@ static int hci_uart_close(struct hci_dev *hdev)
 }
 
 /* Send frames from HCI layer */
-static int hci_uart_send_frame(struct sk_buff *skb)
+static int hci_uart_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
 {
-	struct hci_dev* hdev = (struct hci_dev *) skb->dev;
 	struct hci_uart *hu;
 
 	if (!hdev) {
diff --git a/drivers/bluetooth/hci_ll.c b/drivers/bluetooth/hci_ll.c
index 58a9541..69a90b1 100644
--- a/drivers/bluetooth/hci_ll.c
+++ b/drivers/bluetooth/hci_ll.c
@@ -110,7 +110,6 @@ static int send_hcill_cmd(u8 cmd, struct hci_uart *hu)
 	/* prepare packet */
 	hcill_packet = (struct hcill_cmd *) skb_put(skb, 1);
 	hcill_packet->cmd = cmd;
-	skb->dev = (void *) hu->hdev;
 
 	/* send packet */
 	skb_queue_tail(&ll->txq, skb);
diff --git a/drivers/bluetooth/hci_vhci.c b/drivers/bluetooth/hci_vhci.c
index 0fd522e..e6f5919 100644
--- a/drivers/bluetooth/hci_vhci.c
+++ b/drivers/bluetooth/hci_vhci.c
@@ -81,9 +81,8 @@ static int vhci_flush(struct hci_dev *hdev)
 	return 0;
 }
 
-static int vhci_send_frame(struct sk_buff *skb)
+static int vhci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
 {
-	struct hci_dev* hdev = (struct hci_dev *) skb->dev;
 	struct vhci_data *data;
 
 	if (!hdev) {
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 29b8147..0e01dc2 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -285,7 +285,7 @@ struct hci_dev {
 	int (*close)(struct hci_dev *hdev);
 	int (*flush)(struct hci_dev *hdev);
 	int (*setup)(struct hci_dev *hdev);
-	int (*send)(struct sk_buff *skb);
+	int (*send)(struct hci_dev *hdev, struct sk_buff *skb);
 	void (*notify)(struct hci_dev *hdev, unsigned int evt);
 };
 
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 4f0d4b4..a097a62 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -2713,9 +2713,7 @@ static void hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
 	/* Get rid of skb owner, prior to sending to the driver. */
 	skb_orphan(skb);
 
-	skb->dev = (void *) hdev;
-
-	if (hdev->send(skb) < 0)
+	if (hdev->send(hdev, skb) < 0)
 		BT_ERR("%s sending frame failed", hdev->name);
 }
 
-- 
1.8.3.1


^ permalink raw reply related

* Re: [PATCH] Bluetooth: Add hdev parameter to hdev->send driver callback
From: Johan Hedberg @ 2013-10-11 13:38 UTC (permalink / raw)
  To: Marcel Holtmann; +Cc: linux-bluetooth
In-Reply-To: <1381497558-6315-1-git-send-email-marcel@holtmann.org>

Hi Marcel,

On Fri, Oct 11, 2013, Marcel Holtmann wrote:
> Instead of masking hdev inside the skb->dev parameter, hand it
> directly to the driver as a parameter to hdev->send. This makes
> the driver interface more clear and simpler.
> 
> This patch fixes all drivers to accept and handle the new parameter
> of hdev->send callback. Special care has been taken for bpa10x
> and btusb drivers that require having skb->dev set to hdev for
> the URB transmit complete handlers.
> 
> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
> ---
>  drivers/bluetooth/bfusb.c        | 3 +--
>  drivers/bluetooth/bluecard_cs.c  | 3 +--
>  drivers/bluetooth/bpa10x.c       | 5 +++--
>  drivers/bluetooth/bt3c_cs.c      | 3 +--
>  drivers/bluetooth/btmrvl_main.c  | 4 +---
>  drivers/bluetooth/btsdio.c       | 3 +--
>  drivers/bluetooth/btuart_cs.c    | 3 +--
>  drivers/bluetooth/btusb.c        | 5 +++--
>  drivers/bluetooth/btwilink.c     | 5 +----
>  drivers/bluetooth/dtl1_cs.c      | 3 +--
>  drivers/bluetooth/hci_ldisc.c    | 3 +--
>  drivers/bluetooth/hci_ll.c       | 1 -
>  drivers/bluetooth/hci_vhci.c     | 3 +--
>  include/net/bluetooth/hci_core.h | 2 +-
>  net/bluetooth/hci_core.c         | 4 +---
>  15 files changed, 18 insertions(+), 32 deletions(-)

Applied to bluetooth-next. Thanks.

Johan

^ permalink raw reply

* [PATCH] Bluetooth: Add hdev parameter to hdev->send driver callback
From: Marcel Holtmann @ 2013-10-11 14:00 UTC (permalink / raw)
  To: linux-bluetooth

Instead of masking hdev inside the skb->dev parameter, hand it
directly to the driver as a parameter to hdev->send. This makes
the driver interface more clear and simpler.

This patch fixes all drivers to accept and handle the new parameter
of hdev->send callback. Special care has been taken for bpa10x
and btusb drivers that require having skb->dev set to hdev for
the URB transmit complete handlers.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
 drivers/bluetooth/bfusb.c        | 3 +--
 drivers/bluetooth/bluecard_cs.c  | 3 +--
 drivers/bluetooth/bpa10x.c       | 5 +++--
 drivers/bluetooth/bt3c_cs.c      | 3 +--
 drivers/bluetooth/btmrvl_main.c  | 4 +---
 drivers/bluetooth/btsdio.c       | 3 +--
 drivers/bluetooth/btuart_cs.c    | 3 +--
 drivers/bluetooth/btusb.c        | 5 +++--
 drivers/bluetooth/btwilink.c     | 5 +----
 drivers/bluetooth/dtl1_cs.c      | 3 +--
 drivers/bluetooth/hci_ldisc.c    | 3 +--
 drivers/bluetooth/hci_ll.c       | 1 -
 drivers/bluetooth/hci_vhci.c     | 3 +--
 include/net/bluetooth/hci_core.h | 2 +-
 net/bluetooth/hci_core.c         | 4 +---
 15 files changed, 18 insertions(+), 32 deletions(-)

diff --git a/drivers/bluetooth/bfusb.c b/drivers/bluetooth/bfusb.c
index b7b5bb8..a675849 100644
--- a/drivers/bluetooth/bfusb.c
+++ b/drivers/bluetooth/bfusb.c
@@ -464,9 +464,8 @@ static int bfusb_close(struct hci_dev *hdev)
 	return 0;
 }
 
-static int bfusb_send_frame(struct sk_buff *skb)
+static int bfusb_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
 {
-	struct hci_dev *hdev = (struct hci_dev *) skb->dev;
 	struct bfusb_data *data;
 	struct sk_buff *nskb;
 	unsigned char buf[3];
diff --git a/drivers/bluetooth/bluecard_cs.c b/drivers/bluetooth/bluecard_cs.c
index 395acde..9194a1b 100644
--- a/drivers/bluetooth/bluecard_cs.c
+++ b/drivers/bluetooth/bluecard_cs.c
@@ -658,10 +658,9 @@ static int bluecard_hci_close(struct hci_dev *hdev)
 }
 
 
-static int bluecard_hci_send_frame(struct sk_buff *skb)
+static int bluecard_hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
 {
 	bluecard_info_t *info;
-	struct hci_dev *hdev = (struct hci_dev *)(skb->dev);
 
 	if (!hdev) {
 		BT_ERR("Frame for unknown HCI device (hdev=NULL)");
diff --git a/drivers/bluetooth/bpa10x.c b/drivers/bluetooth/bpa10x.c
index 3188fb4..b9e4e62 100644
--- a/drivers/bluetooth/bpa10x.c
+++ b/drivers/bluetooth/bpa10x.c
@@ -350,9 +350,8 @@ static int bpa10x_flush(struct hci_dev *hdev)
 	return 0;
 }
 
-static int bpa10x_send_frame(struct sk_buff *skb)
+static int bpa10x_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
 {
-	struct hci_dev *hdev = (struct hci_dev *) skb->dev;
 	struct bpa10x_data *data = hci_get_drvdata(hdev);
 	struct usb_ctrlrequest *dr;
 	struct urb *urb;
@@ -364,6 +363,8 @@ static int bpa10x_send_frame(struct sk_buff *skb)
 	if (!test_bit(HCI_RUNNING, &hdev->flags))
 		return -EBUSY;
 
+	skb->dev = (void *) hdev;
+
 	urb = usb_alloc_urb(0, GFP_ATOMIC);
 	if (!urb)
 		return -ENOMEM;
diff --git a/drivers/bluetooth/bt3c_cs.c b/drivers/bluetooth/bt3c_cs.c
index d8e4b0d..fcd5fe9 100644
--- a/drivers/bluetooth/bt3c_cs.c
+++ b/drivers/bluetooth/bt3c_cs.c
@@ -415,10 +415,9 @@ static int bt3c_hci_close(struct hci_dev *hdev)
 }
 
 
-static int bt3c_hci_send_frame(struct sk_buff *skb)
+static int bt3c_hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
 {
 	bt3c_info_t *info;
-	struct hci_dev *hdev = (struct hci_dev *)(skb->dev);
 	unsigned long flags;
 
 	if (!hdev) {
diff --git a/drivers/bluetooth/btmrvl_main.c b/drivers/bluetooth/btmrvl_main.c
index 8ac4d93..547a447 100644
--- a/drivers/bluetooth/btmrvl_main.c
+++ b/drivers/bluetooth/btmrvl_main.c
@@ -187,7 +187,6 @@ static int btmrvl_send_sync_cmd(struct btmrvl_private *priv, u16 cmd_no,
 
 	bt_cb(skb)->pkt_type = MRVL_VENDOR_PKT;
 
-	skb->dev = (void *) priv->btmrvl_dev.hcidev;
 	skb_queue_head(&priv->adapter->tx_queue, skb);
 
 	priv->btmrvl_dev.sendcmdflag = true;
@@ -356,9 +355,8 @@ static void btmrvl_free_adapter(struct btmrvl_private *priv)
 	priv->adapter = NULL;
 }
 
-static int btmrvl_send_frame(struct sk_buff *skb)
+static int btmrvl_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
 {
-	struct hci_dev *hdev = (struct hci_dev *) skb->dev;
 	struct btmrvl_private *priv = NULL;
 
 	BT_DBG("type=%d, len=%d", skb->pkt_type, skb->len);
diff --git a/drivers/bluetooth/btsdio.c b/drivers/bluetooth/btsdio.c
index 72fe49e..b61440a 100644
--- a/drivers/bluetooth/btsdio.c
+++ b/drivers/bluetooth/btsdio.c
@@ -254,9 +254,8 @@ static int btsdio_flush(struct hci_dev *hdev)
 	return 0;
 }
 
-static int btsdio_send_frame(struct sk_buff *skb)
+static int btsdio_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
 {
-	struct hci_dev *hdev = (struct hci_dev *) skb->dev;
 	struct btsdio_data *data = hci_get_drvdata(hdev);
 
 	BT_DBG("%s", hdev->name);
diff --git a/drivers/bluetooth/btuart_cs.c b/drivers/bluetooth/btuart_cs.c
index d0b89ec..f567cd8 100644
--- a/drivers/bluetooth/btuart_cs.c
+++ b/drivers/bluetooth/btuart_cs.c
@@ -423,10 +423,9 @@ static int btuart_hci_close(struct hci_dev *hdev)
 }
 
 
-static int btuart_hci_send_frame(struct sk_buff *skb)
+static int btuart_hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
 {
 	btuart_info_t *info;
-	struct hci_dev *hdev = (struct hci_dev *)(skb->dev);
 
 	if (!hdev) {
 		BT_ERR("Frame for unknown HCI device (hdev=NULL)");
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index faa429f..621069c 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -716,9 +716,8 @@ static int btusb_flush(struct hci_dev *hdev)
 	return 0;
 }
 
-static int btusb_send_frame(struct sk_buff *skb)
+static int btusb_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
 {
-	struct hci_dev *hdev = (struct hci_dev *) skb->dev;
 	struct btusb_data *data = hci_get_drvdata(hdev);
 	struct usb_ctrlrequest *dr;
 	struct urb *urb;
@@ -730,6 +729,8 @@ static int btusb_send_frame(struct sk_buff *skb)
 	if (!test_bit(HCI_RUNNING, &hdev->flags))
 		return -EBUSY;
 
+	skb->dev = (void *) hdev;
+
 	switch (bt_cb(skb)->pkt_type) {
 	case HCI_COMMAND_PKT:
 		urb = usb_alloc_urb(0, GFP_ATOMIC);
diff --git a/drivers/bluetooth/btwilink.c b/drivers/bluetooth/btwilink.c
index 5e10fb0..f038dba 100644
--- a/drivers/bluetooth/btwilink.c
+++ b/drivers/bluetooth/btwilink.c
@@ -251,14 +251,11 @@ static int ti_st_close(struct hci_dev *hdev)
 	return err;
 }
 
-static int ti_st_send_frame(struct sk_buff *skb)
+static int ti_st_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
 {
-	struct hci_dev *hdev;
 	struct ti_st *hst;
 	long len;
 
-	hdev = (struct hci_dev *)skb->dev;
-
 	if (!test_bit(HCI_RUNNING, &hdev->flags))
 		return -EBUSY;
 
diff --git a/drivers/bluetooth/dtl1_cs.c b/drivers/bluetooth/dtl1_cs.c
index 2945141..ad1a2f9 100644
--- a/drivers/bluetooth/dtl1_cs.c
+++ b/drivers/bluetooth/dtl1_cs.c
@@ -382,10 +382,9 @@ static int dtl1_hci_close(struct hci_dev *hdev)
 }
 
 
-static int dtl1_hci_send_frame(struct sk_buff *skb)
+static int dtl1_hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
 {
 	dtl1_info_t *info;
-	struct hci_dev *hdev = (struct hci_dev *)(skb->dev);
 	struct sk_buff *s;
 	nsh_t nsh;
 
diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c
index bc68a44..b040546 100644
--- a/drivers/bluetooth/hci_ldisc.c
+++ b/drivers/bluetooth/hci_ldisc.c
@@ -234,9 +234,8 @@ static int hci_uart_close(struct hci_dev *hdev)
 }
 
 /* Send frames from HCI layer */
-static int hci_uart_send_frame(struct sk_buff *skb)
+static int hci_uart_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
 {
-	struct hci_dev* hdev = (struct hci_dev *) skb->dev;
 	struct hci_uart *hu;
 
 	if (!hdev) {
diff --git a/drivers/bluetooth/hci_ll.c b/drivers/bluetooth/hci_ll.c
index 58a9541..69a90b1 100644
--- a/drivers/bluetooth/hci_ll.c
+++ b/drivers/bluetooth/hci_ll.c
@@ -110,7 +110,6 @@ static int send_hcill_cmd(u8 cmd, struct hci_uart *hu)
 	/* prepare packet */
 	hcill_packet = (struct hcill_cmd *) skb_put(skb, 1);
 	hcill_packet->cmd = cmd;
-	skb->dev = (void *) hu->hdev;
 
 	/* send packet */
 	skb_queue_tail(&ll->txq, skb);
diff --git a/drivers/bluetooth/hci_vhci.c b/drivers/bluetooth/hci_vhci.c
index 0fd522e..e6f5919 100644
--- a/drivers/bluetooth/hci_vhci.c
+++ b/drivers/bluetooth/hci_vhci.c
@@ -81,9 +81,8 @@ static int vhci_flush(struct hci_dev *hdev)
 	return 0;
 }
 
-static int vhci_send_frame(struct sk_buff *skb)
+static int vhci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
 {
-	struct hci_dev* hdev = (struct hci_dev *) skb->dev;
 	struct vhci_data *data;
 
 	if (!hdev) {
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 29b8147..0e01dc2 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -285,7 +285,7 @@ struct hci_dev {
 	int (*close)(struct hci_dev *hdev);
 	int (*flush)(struct hci_dev *hdev);
 	int (*setup)(struct hci_dev *hdev);
-	int (*send)(struct sk_buff *skb);
+	int (*send)(struct hci_dev *hdev, struct sk_buff *skb);
 	void (*notify)(struct hci_dev *hdev, unsigned int evt);
 };
 
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 4f0d4b4..a097a62 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -2713,9 +2713,7 @@ static void hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
 	/* Get rid of skb owner, prior to sending to the driver. */
 	skb_orphan(skb);
 
-	skb->dev = (void *) hdev;
-
-	if (hdev->send(skb) < 0)
+	if (hdev->send(hdev, skb) < 0)
 		BT_ERR("%s sending frame failed", hdev->name);
 }
 
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH 1/8] Bluetooth: Remove pointless parameter check in bfusb_send_frame()
From: Marcel Holtmann @ 2013-10-11 14:00 UTC (permalink / raw)
  To: linux-bluetooth

The hdev parameter of bfusb_send_frame() is always valid. If it were
not valid, then it would have crashed earlier in the call chain.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
 drivers/bluetooth/bfusb.c | 9 +--------
 1 file changed, 1 insertion(+), 8 deletions(-)

diff --git a/drivers/bluetooth/bfusb.c b/drivers/bluetooth/bfusb.c
index a675849..cce2304 100644
--- a/drivers/bluetooth/bfusb.c
+++ b/drivers/bluetooth/bfusb.c
@@ -466,23 +466,16 @@ static int bfusb_close(struct hci_dev *hdev)
 
 static int bfusb_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
 {
-	struct bfusb_data *data;
+	struct bfusb_data *data = hci_get_drvdata(hdev);
 	struct sk_buff *nskb;
 	unsigned char buf[3];
 	int sent = 0, size, count;
 
 	BT_DBG("hdev %p skb %p type %d len %d", hdev, skb, bt_cb(skb)->pkt_type, skb->len);
 
-	if (!hdev) {
-		BT_ERR("Frame for unknown HCI device (hdev=NULL)");
-		return -ENODEV;
-	}
-
 	if (!test_bit(HCI_RUNNING, &hdev->flags))
 		return -EBUSY;
 
-	data = hci_get_drvdata(hdev);
-
 	switch (bt_cb(skb)->pkt_type) {
 	case HCI_COMMAND_PKT:
 		hdev->stat.cmd_tx++;
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH 2/8] Bluetooth: Remove pointless parameter check in bluecard_hci_send_frame()
From: Marcel Holtmann @ 2013-10-11 14:00 UTC (permalink / raw)
  To: linux-bluetooth

The hdev parameter of bluecard_hci_send_frame() is always valid. If it
were not valid, then it would have crashed earlier in the call chain.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
 drivers/bluetooth/bluecard_cs.c | 9 +--------
 1 file changed, 1 insertion(+), 8 deletions(-)

diff --git a/drivers/bluetooth/bluecard_cs.c b/drivers/bluetooth/bluecard_cs.c
index 9194a1b..57427de 100644
--- a/drivers/bluetooth/bluecard_cs.c
+++ b/drivers/bluetooth/bluecard_cs.c
@@ -660,14 +660,7 @@ static int bluecard_hci_close(struct hci_dev *hdev)
 
 static int bluecard_hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
 {
-	bluecard_info_t *info;
-
-	if (!hdev) {
-		BT_ERR("Frame for unknown HCI device (hdev=NULL)");
-		return -ENODEV;
-	}
-
-	info = hci_get_drvdata(hdev);
+	bluecard_info_t *info = hci_get_drvdata(hdev);
 
 	switch (bt_cb(skb)->pkt_type) {
 	case HCI_COMMAND_PKT:
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH 3/8] Bluetooth: Remove pointless parameter check in bt3c_hci_send_frame()
From: Marcel Holtmann @ 2013-10-11 14:00 UTC (permalink / raw)
  To: linux-bluetooth

The hdev parameter of bt3c_hci_send_frame() is always valid. If it
were not valid, then it would have crashed earlier in the call chain.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
 drivers/bluetooth/bt3c_cs.c | 9 +--------
 1 file changed, 1 insertion(+), 8 deletions(-)

diff --git a/drivers/bluetooth/bt3c_cs.c b/drivers/bluetooth/bt3c_cs.c
index fcd5fe9..73d8799 100644
--- a/drivers/bluetooth/bt3c_cs.c
+++ b/drivers/bluetooth/bt3c_cs.c
@@ -417,16 +417,9 @@ static int bt3c_hci_close(struct hci_dev *hdev)
 
 static int bt3c_hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
 {
-	bt3c_info_t *info;
+	bt3c_info_t *info = hci_get_drvdata(hdev);
 	unsigned long flags;
 
-	if (!hdev) {
-		BT_ERR("Frame for unknown HCI device (hdev=NULL)");
-		return -ENODEV;
-	}
-
-	info = hci_get_drvdata(hdev);
-
 	switch (bt_cb(skb)->pkt_type) {
 	case HCI_COMMAND_PKT:
 		hdev->stat.cmd_tx++;
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH 4/8] Bluetooth: Remove pointless parameter check in btmrvl_send_frame()
From: Marcel Holtmann @ 2013-10-11 14:01 UTC (permalink / raw)
  To: linux-bluetooth

The hdev parameter of btmrvl_send_frame() is always valid. If it were
not valid, then it would have crashed earlier in the call chain.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
 drivers/bluetooth/btmrvl_main.c | 9 +--------
 1 file changed, 1 insertion(+), 8 deletions(-)

diff --git a/drivers/bluetooth/btmrvl_main.c b/drivers/bluetooth/btmrvl_main.c
index 547a447..5cf31c4 100644
--- a/drivers/bluetooth/btmrvl_main.c
+++ b/drivers/bluetooth/btmrvl_main.c
@@ -357,17 +357,10 @@ static void btmrvl_free_adapter(struct btmrvl_private *priv)
 
 static int btmrvl_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
 {
-	struct btmrvl_private *priv = NULL;
+	struct btmrvl_private *priv = hci_get_drvdata(hdev);
 
 	BT_DBG("type=%d, len=%d", skb->pkt_type, skb->len);
 
-	if (!hdev) {
-		BT_ERR("Frame for unknown HCI device");
-		return -ENODEV;
-	}
-
-	priv = hci_get_drvdata(hdev);
-
 	if (!test_bit(HCI_RUNNING, &hdev->flags)) {
 		BT_ERR("Failed testing HCI_RUNING, flags=%lx", hdev->flags);
 		print_hex_dump_bytes("data: ", DUMP_PREFIX_OFFSET,
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH 5/8] Bluetooth: Remove pointless parameter check in btuart_hci_send_frame()
From: Marcel Holtmann @ 2013-10-11 14:01 UTC (permalink / raw)
  To: linux-bluetooth

The hdev parameter of btuart_hci_send_frame() is always valid. If it
were not valid, then it would have crashed earlier in the call chain.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
 drivers/bluetooth/btuart_cs.c | 9 +--------
 1 file changed, 1 insertion(+), 8 deletions(-)

diff --git a/drivers/bluetooth/btuart_cs.c b/drivers/bluetooth/btuart_cs.c
index f567cd8..a03ecc2 100644
--- a/drivers/bluetooth/btuart_cs.c
+++ b/drivers/bluetooth/btuart_cs.c
@@ -425,14 +425,7 @@ static int btuart_hci_close(struct hci_dev *hdev)
 
 static int btuart_hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
 {
-	btuart_info_t *info;
-
-	if (!hdev) {
-		BT_ERR("Frame for unknown HCI device (hdev=NULL)");
-		return -ENODEV;
-	}
-
-	info = hci_get_drvdata(hdev);
+	btuart_info_t *info = hci_get_drvdata(hdev);
 
 	switch (bt_cb(skb)->pkt_type) {
 	case HCI_COMMAND_PKT:
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH 6/8] Bluetooth: Remove pointless parameter check in dtl1_hci_send_frame()
From: Marcel Holtmann @ 2013-10-11 14:01 UTC (permalink / raw)
  To: linux-bluetooth

The hdev parameter of dtl1_hci_send_frame() is always valid. If it
were not valid, then it would have crashed earlier in the call chain.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
 drivers/bluetooth/dtl1_cs.c | 9 +--------
 1 file changed, 1 insertion(+), 8 deletions(-)

diff --git a/drivers/bluetooth/dtl1_cs.c b/drivers/bluetooth/dtl1_cs.c
index ad1a2f9..52eed1f 100644
--- a/drivers/bluetooth/dtl1_cs.c
+++ b/drivers/bluetooth/dtl1_cs.c
@@ -384,17 +384,10 @@ static int dtl1_hci_close(struct hci_dev *hdev)
 
 static int dtl1_hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
 {
-	dtl1_info_t *info;
+	dtl1_info_t *info = hci_get_drvdata(hdev);
 	struct sk_buff *s;
 	nsh_t nsh;
 
-	if (!hdev) {
-		BT_ERR("Frame for unknown HCI device (hdev=NULL)");
-		return -ENODEV;
-	}
-
-	info = hci_get_drvdata(hdev);
-
 	switch (bt_cb(skb)->pkt_type) {
 	case HCI_COMMAND_PKT:
 		hdev->stat.cmd_tx++;
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH 7/8] Bluetooth: Remove pointless parameter check in hci_uart_send_frame()
From: Marcel Holtmann @ 2013-10-11 14:01 UTC (permalink / raw)
  To: linux-bluetooth

The hdev parameter of hci_uart_send_frame() is always valid. If it
were not valid, then it would have crashed earlier in the call chain.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
 drivers/bluetooth/hci_ldisc.c | 9 +--------
 1 file changed, 1 insertion(+), 8 deletions(-)

diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c
index b040546..6e06f6f 100644
--- a/drivers/bluetooth/hci_ldisc.c
+++ b/drivers/bluetooth/hci_ldisc.c
@@ -236,18 +236,11 @@ static int hci_uart_close(struct hci_dev *hdev)
 /* Send frames from HCI layer */
 static int hci_uart_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
 {
-	struct hci_uart *hu;
-
-	if (!hdev) {
-		BT_ERR("Frame for unknown device (hdev=NULL)");
-		return -ENODEV;
-	}
+	struct hci_uart *hu = hci_get_drvdata(hdev);
 
 	if (!test_bit(HCI_RUNNING, &hdev->flags))
 		return -EBUSY;
 
-	hu = hci_get_drvdata(hdev);
-
 	BT_DBG("%s: type %d len %d", hdev->name, bt_cb(skb)->pkt_type, skb->len);
 
 	hu->proto->enqueue(hu, skb);
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH 8/8] Bluetooth: Remove pointless parameter check in vhci_send_frame()
From: Marcel Holtmann @ 2013-10-11 14:01 UTC (permalink / raw)
  To: linux-bluetooth

The hdev parameter of vhci_send_frame() is always valid. If it were
not valid, then it would have crashed earlier in the call chain.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
 drivers/bluetooth/hci_vhci.c | 9 +--------
 1 file changed, 1 insertion(+), 8 deletions(-)

diff --git a/drivers/bluetooth/hci_vhci.c b/drivers/bluetooth/hci_vhci.c
index e6f5919..7b16738 100644
--- a/drivers/bluetooth/hci_vhci.c
+++ b/drivers/bluetooth/hci_vhci.c
@@ -83,18 +83,11 @@ static int vhci_flush(struct hci_dev *hdev)
 
 static int vhci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
 {
-	struct vhci_data *data;
-
-	if (!hdev) {
-		BT_ERR("Frame for unknown HCI device (hdev=NULL)");
-		return -ENODEV;
-	}
+	struct vhci_data *data = hci_get_drvdata(hdev);
 
 	if (!test_bit(HCI_RUNNING, &hdev->flags))
 		return -EBUSY;
 
-	data = hci_get_drvdata(hdev);
-
 	memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1);
 	skb_queue_tail(&data->readq, skb);
 
-- 
1.8.3.1


^ permalink raw reply related

* Re: [PATCH] Bluetooth: Add hdev parameter to hdev->send driver callback
From: Marcel Holtmann @ 2013-10-11 14:03 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1381500064-24414-1-git-send-email-marcel@holtmann.org>

Hi Johan,

> Instead of masking hdev inside the skb->dev parameter, hand it
> directly to the driver as a parameter to hdev->send. This makes
> the driver interface more clear and simpler.
> 
> This patch fixes all drivers to accept and handle the new parameter
> of hdev->send callback. Special care has been taken for bpa10x
> and btusb drivers that require having skb->dev set to hdev for
> the URB transmit complete handlers.
> 
> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
> ---
> drivers/bluetooth/bfusb.c        | 3 +--
> drivers/bluetooth/bluecard_cs.c  | 3 +--
> drivers/bluetooth/bpa10x.c       | 5 +++--
> drivers/bluetooth/bt3c_cs.c      | 3 +--
> drivers/bluetooth/btmrvl_main.c  | 4 +---
> drivers/bluetooth/btsdio.c       | 3 +--
> drivers/bluetooth/btuart_cs.c    | 3 +--
> drivers/bluetooth/btusb.c        | 5 +++--
> drivers/bluetooth/btwilink.c     | 5 +----
> drivers/bluetooth/dtl1_cs.c      | 3 +--
> drivers/bluetooth/hci_ldisc.c    | 3 +--
> drivers/bluetooth/hci_ll.c       | 1 -
> drivers/bluetooth/hci_vhci.c     | 3 +--
> include/net/bluetooth/hci_core.h | 2 +-
> net/bluetooth/hci_core.c         | 4 +---
> 15 files changed, 18 insertions(+), 32 deletions(-)

I accidentally send this one twice. So just ignore it.

Regards

Marcel


^ permalink raw reply

* [PATCH 1/4] Bluetooth: Declare btusb_table[] and blacklist_table[] as const
From: Marcel Holtmann @ 2013-10-11 14:46 UTC (permalink / raw)
  To: linux-bluetooth

The btusb_table[] and blacklist_table[] USB device tables can be
declared as const.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
 drivers/bluetooth/btusb.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index 621069c..30868fa 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -50,7 +50,7 @@ static struct usb_driver btusb_driver;
 #define BTUSB_ATH3012		0x80
 #define BTUSB_INTEL		0x100
 
-static struct usb_device_id btusb_table[] = {
+static const struct usb_device_id btusb_table[] = {
 	/* Generic Bluetooth USB device */
 	{ USB_DEVICE_INFO(0xe0, 0x01, 0x01) },
 
@@ -121,7 +121,7 @@ static struct usb_device_id btusb_table[] = {
 
 MODULE_DEVICE_TABLE(usb, btusb_table);
 
-static struct usb_device_id blacklist_table[] = {
+static const struct usb_device_id blacklist_table[] = {
 	/* CSR BlueCore devices */
 	{ USB_DEVICE(0x0a12, 0x0001), .driver_info = BTUSB_CSR },
 
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH 2/4] Bluetooth: Declare bfusb_table[] as const
From: Marcel Holtmann @ 2013-10-11 14:46 UTC (permalink / raw)
  To: linux-bluetooth

The bfusb_table[] device table can be declared as const

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
 drivers/bluetooth/bfusb.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/bluetooth/bfusb.c b/drivers/bluetooth/bfusb.c
index cce2304..3138699 100644
--- a/drivers/bluetooth/bfusb.c
+++ b/drivers/bluetooth/bfusb.c
@@ -42,7 +42,7 @@
 
 static struct usb_driver bfusb_driver;
 
-static struct usb_device_id bfusb_table[] = {
+static const struct usb_device_id bfusb_table[] = {
 	/* AVM BlueFRITZ! USB */
 	{ USB_DEVICE(0x057c, 0x2200) },
 
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH 3/4] Bluetooth: Declare bpa10x_table[] as const
From: Marcel Holtmann @ 2013-10-11 14:46 UTC (permalink / raw)
  To: linux-bluetooth

The bpa10x_table[] device table can be declared as const

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
 drivers/bluetooth/bpa10x.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/bluetooth/bpa10x.c b/drivers/bluetooth/bpa10x.c
index b9e4e62..8a31991 100644
--- a/drivers/bluetooth/bpa10x.c
+++ b/drivers/bluetooth/bpa10x.c
@@ -37,7 +37,7 @@
 
 #define VERSION "0.10"
 
-static struct usb_device_id bpa10x_table[] = {
+static const struct usb_device_id bpa10x_table[] = {
 	/* Tektronix BPA 100/105 (Digianswer) */
 	{ USB_DEVICE(0x08fd, 0x0002) },
 
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH 4/4] Bluetooth: Declare ath3k_table[] and ath3k_blist_tbl[] as const
From: Marcel Holtmann @ 2013-10-11 14:46 UTC (permalink / raw)
  To: linux-bluetooth

The ath3k_table[] and ath3k_blist_tbl[] USB device tables can be
declared as const.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
 drivers/bluetooth/ath3k.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c
index 0a327f4..6bfc1bb 100644
--- a/drivers/bluetooth/ath3k.c
+++ b/drivers/bluetooth/ath3k.c
@@ -57,7 +57,7 @@ struct ath3k_version {
 	unsigned char	reserved[0x07];
 };
 
-static struct usb_device_id ath3k_table[] = {
+static const struct usb_device_id ath3k_table[] = {
 	/* Atheros AR3011 */
 	{ USB_DEVICE(0x0CF3, 0x3000) },
 
@@ -112,7 +112,7 @@ MODULE_DEVICE_TABLE(usb, ath3k_table);
 #define BTUSB_ATH3012		0x80
 /* This table is to load patch and sysconfig files
  * for AR3012 */
-static struct usb_device_id ath3k_blist_tbl[] = {
+static const struct usb_device_id ath3k_blist_tbl[] = {
 
 	/* Atheros AR3012 with sflash firmware*/
 	{ USB_DEVICE(0x0CF3, 0x0036), .driver_info = BTUSB_ATH3012 },
-- 
1.8.3.1


^ permalink raw reply related

* Re: [PATCH 1/8] Bluetooth: Remove pointless parameter check in bfusb_send_frame()
From: Johan Hedberg @ 2013-10-11 15:01 UTC (permalink / raw)
  To: Marcel Holtmann; +Cc: linux-bluetooth
In-Reply-To: <1381500064-24414-2-git-send-email-marcel@holtmann.org>

Hi Marcel,

On Fri, Oct 11, 2013, Marcel Holtmann wrote:
> The hdev parameter of bfusb_send_frame() is always valid. If it were
> not valid, then it would have crashed earlier in the call chain.
> 
> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
> ---
>  drivers/bluetooth/bfusb.c | 9 +--------
>  1 file changed, 1 insertion(+), 8 deletions(-)

All eight patches have been applied to bluetooth-next. Thanks.

Johan

^ permalink raw reply

* Re: [PATCH 1/4] Bluetooth: Declare btusb_table[] and blacklist_table[] as const
From: Johan Hedberg @ 2013-10-11 15:07 UTC (permalink / raw)
  To: Marcel Holtmann; +Cc: linux-bluetooth
In-Reply-To: <1381502781-42826-1-git-send-email-marcel@holtmann.org>

Hi Marcel,

On Fri, Oct 11, 2013, Marcel Holtmann wrote:
> The btusb_table[] and blacklist_table[] USB device tables can be
> declared as const.
> 
> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
> ---
>  drivers/bluetooth/btusb.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)

All four patches in this set have been applied to bluetooth-next. Thanks.

Johan

^ permalink raw reply

* [PATCH v2 1/2] Bluetooth: Make LE scan interval and window a controller option
From: Marcel Holtmann @ 2013-10-11 15:23 UTC (permalink / raw)
  To: linux-bluetooth

The scan interval and window for LE passive scanning and connection
establishment should be configurable on a per controller basis. So
introduce a setting that later on will allow modifying it.

This setting does not affect LE active scanning during device
discovery phase. As long as that phase uses interleaved discovery,
it will continuously scan.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
 include/net/bluetooth/hci_core.h | 2 ++
 net/bluetooth/hci_conn.c         | 4 ++--
 net/bluetooth/hci_core.c         | 3 +++
 3 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 0e01dc2..6900454 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -164,6 +164,8 @@ struct hci_dev {
 	__u16		page_scan_interval;
 	__u16		page_scan_window;
 	__u8		page_scan_type;
+	__u16		le_scan_interval;
+	__u16		le_scan_window;
 
 	__u16		devid_source;
 	__u16		devid_vendor;
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 1395871..c52bfb7 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -562,8 +562,8 @@ static int hci_create_le_conn(struct hci_conn *conn)
 	hci_req_init(&req, hdev);
 
 	memset(&cp, 0, sizeof(cp));
-	cp.scan_interval = __constant_cpu_to_le16(0x0060);
-	cp.scan_window = __constant_cpu_to_le16(0x0030);
+	cp.scan_interval = cpu_to_le16(hdev->le_scan_interval);
+	cp.scan_window = cpu_to_le16(hdev->le_scan_window);
 	bacpy(&cp.peer_addr, &conn->dst);
 	cp.peer_addr_type = conn->dst_type;
 	if (bacmp(&hdev->bdaddr, BDADDR_ANY))
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index a097a62..1910dc2 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -2273,6 +2273,9 @@ struct hci_dev *hci_alloc_dev(void)
 	hdev->sniff_max_interval = 800;
 	hdev->sniff_min_interval = 80;
 
+	hdev->le_scan_interval = 0x0060;
+	hdev->le_scan_window = 0x0030;
+
 	mutex_init(&hdev->lock);
 	mutex_init(&hdev->req_lock);
 
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH v2 2/2] Bluetooth: Add management command for setting LE scan parameters
From: Marcel Holtmann @ 2013-10-11 15:23 UTC (permalink / raw)
  To: linux-bluetooth

The scan interval and window parameters are used for LE passive
background scanning and connection establishment. This allows
userspace to change the values.

These two values should be kept in sync with whatever is used for
the scan parameters service on remote devices. And it puts the
controlling daemon (for example bluetoothd) in charge of setting
the values.

Main use case would be to switch between two sets of values. One
for foreground applications and one for background applications.

At this moment, the values are only used for manual connection
establishment, but soon that should be extended to background
scanning and automatic connection establishment.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
 include/net/bluetooth/mgmt.h |  7 +++++++
 net/bluetooth/mgmt.c         | 38 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 45 insertions(+)

diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h
index 2ad433bb..518c5c8 100644
--- a/include/net/bluetooth/mgmt.h
+++ b/include/net/bluetooth/mgmt.h
@@ -362,6 +362,13 @@ struct mgmt_cp_set_static_address {
 } __packed;
 #define MGMT_SET_STATIC_ADDRESS_SIZE	6
 
+#define MGMT_OP_SET_SCAN_PARAMS		0x002C
+struct mgmt_cp_set_scan_params {
+	__le16	interval;
+	__le16	window;
+} __packed;
+#define MGMT_SET_SCAN_PARAMS_SIZE	4
+
 #define MGMT_EV_CMD_COMPLETE		0x0001
 struct mgmt_ev_cmd_complete {
 	__le16	opcode;
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 143dd73..f57ec19 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -3374,6 +3374,43 @@ static int set_static_address(struct sock *sk, struct hci_dev *hdev,
 	return err;
 }
 
+static int set_scan_params(struct sock *sk, struct hci_dev *hdev,
+			   void *data, u16 len)
+{
+	struct mgmt_cp_set_scan_params *cp = data;
+	__u16 interval, window;
+	int err;
+
+	BT_DBG("%s", hdev->name);
+
+	if (!lmp_le_capable(hdev))
+		return cmd_status(sk, hdev->id, MGMT_OP_SET_SCAN_PARAMS,
+				  MGMT_STATUS_NOT_SUPPORTED);
+
+	interval = __le16_to_cpu(cp->interval);
+
+	if (interval < 0x0004 || interval > 0x4000)
+		return cmd_status(sk, hdev->id, MGMT_OP_SET_SCAN_PARAMS,
+				  MGMT_STATUS_INVALID_PARAMS);
+
+	window = __le16_to_cpu(cp->window);
+
+	if (window < 0x0004 || window > 0x4000)
+		return cmd_status(sk, hdev->id, MGMT_OP_SET_SCAN_PARAMS,
+				  MGMT_STATUS_INVALID_PARAMS);
+
+	hci_dev_lock(hdev);
+
+	hdev->le_scan_interval = interval;
+	hdev->le_scan_window = window;
+
+	err = cmd_complete(sk, hdev->id, MGMT_OP_SET_SCAN_PARAMS, 0, NULL, 0);
+
+	hci_dev_unlock(hdev);
+
+	return err;
+}
+
 static void fast_connectable_complete(struct hci_dev *hdev, u8 status)
 {
 	struct pending_cmd *cmd;
@@ -3710,6 +3747,7 @@ static const struct mgmt_handler {
 	{ set_advertising,        false, MGMT_SETTING_SIZE },
 	{ set_bredr,              false, MGMT_SETTING_SIZE },
 	{ set_static_address,     false, MGMT_SET_STATIC_ADDRESS_SIZE },
+	{ set_scan_params,        false, MGMT_SET_SCAN_PARAMS_SIZE },
 };
 
 
-- 
1.8.3.1


^ permalink raw reply related

* Re: [PATCH v2 1/2] Bluetooth: Make LE scan interval and window a controller option
From: Johan Hedberg @ 2013-10-11 16:21 UTC (permalink / raw)
  To: Marcel Holtmann; +Cc: linux-bluetooth
In-Reply-To: <1381505000-50787-1-git-send-email-marcel@holtmann.org>

Hi Marcel,

On Fri, Oct 11, 2013, Marcel Holtmann wrote:
> The scan interval and window for LE passive scanning and connection
> establishment should be configurable on a per controller basis. So
> introduce a setting that later on will allow modifying it.
> 
> This setting does not affect LE active scanning during device
> discovery phase. As long as that phase uses interleaved discovery,
> it will continuously scan.
> 
> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
> ---
>  include/net/bluetooth/hci_core.h | 2 ++
>  net/bluetooth/hci_conn.c         | 4 ++--
>  net/bluetooth/hci_core.c         | 3 +++
>  3 files changed, 7 insertions(+), 2 deletions(-)

Both patches have been applied to bluetooth-next. Thanks.

Johan

^ permalink raw reply

* [PATCH] Bluetooth: Fix endless loop with HCI_QUIRK_RESET_ON_CLOSE
From: Marcel Holtmann @ 2013-10-11 16:44 UTC (permalink / raw)
  To: linux-bluetooth

Really early versions of the Bluetooth specification were unclear
with the behavior of HCI Reset for USB devices. They assumed that
also an USB reset needs to be issued. Later Bluetooth specifications
cleared this out and it is safe to call HCI Reset without affecting
the transport.

For old devices that misbehave, the HCI_QUIRK_RESET_ON_CLOSE quirk
was introduced to postpone the HCI Reset until the device was no
longer in use.

One of these devices is the Digianswer BPA-105 Bluetooth Protocol
Analyzer. The only problem now is that with the quirk set, the
HCI Reset is also executed at the end of the setup phase. So the
controller gets configured and then it disconnects from the USB
bus, connects again, gets configured and of course disconnects
again. This game goes on forever.

For devices that need HCI_QUIRK_RESET_ON_CLOSE it is important
that the HCI Reset is not executed after the setup phase. In
specific when HCI_AUTO_OFF is set, do not call HCI Reset when
closing the device.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
 net/bluetooth/hci_core.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 1910dc2..8f70a35 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -1378,6 +1378,7 @@ static int hci_dev_do_close(struct hci_dev *hdev)
 	skb_queue_purge(&hdev->cmd_q);
 	atomic_set(&hdev->cmd_cnt, 1);
 	if (!test_bit(HCI_RAW, &hdev->flags) &&
+	    !test_bit(HCI_AUTO_OFF, &hdev->dev_flags) &&
 	    test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) {
 		set_bit(HCI_INIT, &hdev->flags);
 		__hci_req_sync(hdev, hci_reset_req, 0, HCI_CMD_TIMEOUT);
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH] Bluetooth: Don't advertise high speed support without SSP
From: Marcel Holtmann @ 2013-10-11 16:48 UTC (permalink / raw)
  To: linux-bluetooth

It is not allowed to enable high speed support when Secure Simple
Pairing is not available or disabled.

However the support for high speed gets advertised on a controller
that does not even support Secure Simple Pairing. Since there is
no way to enable high speed support on such a controller, do not
even advertise its support.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
---
 net/bluetooth/mgmt.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index f57ec19..aa59490 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -363,9 +363,6 @@ static u32 get_supported_settings(struct hci_dev *hdev)
 	settings |= MGMT_SETTING_POWERED;
 	settings |= MGMT_SETTING_PAIRABLE;
 
-	if (lmp_ssp_capable(hdev))
-		settings |= MGMT_SETTING_SSP;
-
 	if (lmp_bredr_capable(hdev)) {
 		settings |= MGMT_SETTING_CONNECTABLE;
 		if (hdev->hci_ver >= BLUETOOTH_VER_1_2)
@@ -373,7 +370,11 @@ static u32 get_supported_settings(struct hci_dev *hdev)
 		settings |= MGMT_SETTING_DISCOVERABLE;
 		settings |= MGMT_SETTING_BREDR;
 		settings |= MGMT_SETTING_LINK_SECURITY;
-		settings |= MGMT_SETTING_HS;
+
+		if (lmp_ssp_capable(hdev)) {
+			settings |= MGMT_SETTING_SSP;
+			settings |= MGMT_SETTING_HS;
+		}
 	}
 
 	if (lmp_le_capable(hdev)) {
-- 
1.8.3.1


^ permalink raw reply related

* Re: [PATCH] Bluetooth: Fix endless loop with HCI_QUIRK_RESET_ON_CLOSE
From: Johan Hedberg @ 2013-10-11 20:59 UTC (permalink / raw)
  To: Marcel Holtmann; +Cc: linux-bluetooth
In-Reply-To: <1381509852-64080-1-git-send-email-marcel@holtmann.org>

Hi Marcel,

On Fri, Oct 11, 2013, Marcel Holtmann wrote:
> Really early versions of the Bluetooth specification were unclear
> with the behavior of HCI Reset for USB devices. They assumed that
> also an USB reset needs to be issued. Later Bluetooth specifications
> cleared this out and it is safe to call HCI Reset without affecting
> the transport.
> 
> For old devices that misbehave, the HCI_QUIRK_RESET_ON_CLOSE quirk
> was introduced to postpone the HCI Reset until the device was no
> longer in use.
> 
> One of these devices is the Digianswer BPA-105 Bluetooth Protocol
> Analyzer. The only problem now is that with the quirk set, the
> HCI Reset is also executed at the end of the setup phase. So the
> controller gets configured and then it disconnects from the USB
> bus, connects again, gets configured and of course disconnects
> again. This game goes on forever.
> 
> For devices that need HCI_QUIRK_RESET_ON_CLOSE it is important
> that the HCI Reset is not executed after the setup phase. In
> specific when HCI_AUTO_OFF is set, do not call HCI Reset when
> closing the device.
> 
> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
> ---
>  net/bluetooth/hci_core.c | 1 +
>  1 file changed, 1 insertion(+)

Applied to bluetooth-next. Thanks.

Johan

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox