Linux bluetooth development
 help / color / mirror / Atom feed
* Re: [RFC] Bluetooth: Use non-flushable pb flag by default for ACL data on capable chipsets.
From: Gustavo F. Padovan @ 2010-12-14 19:22 UTC (permalink / raw)
  To: Emeltchenko Andrei; +Cc: linux-bluetooth
In-Reply-To: <1292251105-31130-2-git-send-email-Andrei.Emeltchenko.news@gmail.com>

Hi Andrei,

* Emeltchenko Andrei <Andrei.Emeltchenko.news@gmail.com> [2010-12-13 16:38:25 +0200]:

> From: Andrei Emeltchenko <andrei.emeltchenko@nokia.com>
> 
> Modification of Nick Pelly <npelly@google.com> patch.
> 
> With Bluetooth 2.1 ACL packets can be flushable or non-flushable. This commit
> makes ACL data packets non-flushable by default on compatible chipsets, and
> adds the BT_FLUSHABLE socket option to explicitly request flushable ACL
> data packets for a given L2CAP socket. This is useful for A2DP data which can
> be safely discarded if it can not be delivered within a short time (while
> other ACL data should not be discarded).
> 
> Note that making ACL data flushable has no effect unless the automatic flush
> timeout for that ACL link is changed from its default of 0 (infinite).
> 
> Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@nokia.com>
> ---
>  include/net/bluetooth/bluetooth.h |    5 +++++
>  include/net/bluetooth/hci.h       |    2 ++
>  include/net/bluetooth/hci_core.h  |    1 +
>  include/net/bluetooth/l2cap.h     |    2 ++
>  net/bluetooth/hci_core.c          |    6 ++++--
>  net/bluetooth/l2cap.c             |   33 +++++++++++++++++++++++++++++++--
>  6 files changed, 45 insertions(+), 4 deletions(-)
> 
> diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h
> index 0c5e725..ed7d775 100644
> --- a/include/net/bluetooth/bluetooth.h
> +++ b/include/net/bluetooth/bluetooth.h
> @@ -64,6 +64,11 @@ struct bt_security {
>  
>  #define BT_DEFER_SETUP	7
>  
> +#define BT_FLUSHABLE	8
> +
> +#define BT_FLUSHABLE_OFF	0
> +#define BT_FLUSHABLE_ON		1
> +
>  #define BT_INFO(fmt, arg...) printk(KERN_INFO "Bluetooth: " fmt "\n" , ## arg)
>  #define BT_ERR(fmt, arg...)  printk(KERN_ERR "%s: " fmt "\n" , __func__ , ## arg)
>  #define BT_DBG(fmt, arg...)  pr_debug("%s: " fmt "\n" , __func__ , ## arg)
> diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
> index 29a7a8c..333d5cb 100644
> --- a/include/net/bluetooth/hci.h
> +++ b/include/net/bluetooth/hci.h
> @@ -150,6 +150,7 @@ enum {
>  #define EDR_ESCO_MASK  (ESCO_2EV3 | ESCO_3EV3 | ESCO_2EV5 | ESCO_3EV5)
>  
>  /* ACL flags */
> +#define ACL_START_NO_FLUSH	0x00
>  #define ACL_CONT		0x01
>  #define ACL_START		0x02
>  #define ACL_ACTIVE_BCAST	0x04
> @@ -193,6 +194,7 @@ enum {
>  #define LMP_EDR_ESCO_3M	0x40
>  #define LMP_EDR_3S_ESCO	0x80
>  
> +#define LMP_NO_FLUSH	0x01
>  #define LMP_SIMPLE_PAIR	0x08
>  
>  /* Connection modes */
> diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
> index 1992fac..9778bc8 100644
> --- a/include/net/bluetooth/hci_core.h
> +++ b/include/net/bluetooth/hci_core.h
> @@ -456,6 +456,7 @@ void hci_conn_del_sysfs(struct hci_conn *conn);
>  #define lmp_sniffsubr_capable(dev) ((dev)->features[5] & LMP_SNIFF_SUBR)
>  #define lmp_esco_capable(dev)      ((dev)->features[3] & LMP_ESCO)
>  #define lmp_ssp_capable(dev)       ((dev)->features[6] & LMP_SIMPLE_PAIR)
> +#define lmp_no_flush_capable(dev)  ((dev)->features[6] & LMP_NO_FLUSH)

IMHO lmp_flush_capable() makes more sense. We can avoid things like
(!lmp_no_flush_capable(dev)) and add two negatives in the same comparison.

>  
>  /* ----- HCI protocols ----- */
>  struct hci_proto {
> diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
> index 7ad25ca..af35711 100644
> --- a/include/net/bluetooth/l2cap.h
> +++ b/include/net/bluetooth/l2cap.h
> @@ -75,6 +75,7 @@ struct l2cap_conninfo {
>  #define L2CAP_LM_TRUSTED	0x0008
>  #define L2CAP_LM_RELIABLE	0x0010
>  #define L2CAP_LM_SECURE		0x0020
> +#define L2CAP_LM_FLUSHABLE	0x0040

Not using this anywhere.

>  
>  /* L2CAP command codes */
>  #define L2CAP_COMMAND_REJ	0x01
> @@ -327,6 +328,7 @@ struct l2cap_pinfo {
>  	__u8		sec_level;
>  	__u8		role_switch;
>  	__u8		force_reliable;
> +	__u8		flushable;
>  
>  	__u8		conf_req[64];
>  	__u8		conf_len;
> diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
> index 51c61f7..c0d776b 100644
> --- a/net/bluetooth/hci_core.c
> +++ b/net/bluetooth/hci_core.c
> @@ -1380,7 +1380,7 @@ void hci_send_acl(struct hci_conn *conn, struct sk_buff *skb, __u16 flags)
>  
>  	skb->dev = (void *) hdev;
>  	bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
> -	hci_add_acl_hdr(skb, conn->handle, flags | ACL_START);
> +	hci_add_acl_hdr(skb, conn->handle, flags);
>  
>  	list = skb_shinfo(skb)->frag_list;
>  	if (!list) {
> @@ -1398,12 +1398,14 @@ void hci_send_acl(struct hci_conn *conn, struct sk_buff *skb, __u16 flags)
>  		spin_lock_bh(&conn->data_q.lock);
>  
>  		__skb_queue_tail(&conn->data_q, skb);
> +		flags &= ~ACL_START;
> +		flags |= ACL_CONT;
>  		do {
>  			skb = list; list = list->next;
>  
>  			skb->dev = (void *) hdev;
>  			bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
> -			hci_add_acl_hdr(skb, conn->handle, flags | ACL_CONT);
> +			hci_add_acl_hdr(skb, conn->handle, flags);
>  
>  			BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
>  
> diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
> index c791fcd..c7f25c2 100644
> --- a/net/bluetooth/l2cap.c
> +++ b/net/bluetooth/l2cap.c
> @@ -362,13 +362,19 @@ static inline u8 l2cap_get_ident(struct l2cap_conn *conn)
>  static inline void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, void *data)
>  {
>  	struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data);
> +	u8 flags;
>  
>  	BT_DBG("code 0x%2.2x", code);
>  
>  	if (!skb)
>  		return;
>  
> -	hci_send_acl(conn->hcon, skb, 0);
> +	if (lmp_no_flush_capable(conn->hcon->hdev))
> +		flags = ACL_START_NO_FLUSH;
> +	else
> +		flags = ACL_START;
> +
> +	hci_send_acl(conn->hcon, skb, flags);

I also agree that l2cap commands should be non-flushable. Just pass
ACL_START_NO_FLUSH to hci_send_acl() here.
You should add this check to l2cap_do_send() instead.

>  }
>  
>  static inline void l2cap_send_sframe(struct l2cap_pinfo *pi, u16 control)
> @@ -900,6 +906,7 @@ static void l2cap_sock_init(struct sock *sk, struct sock *parent)
>  		pi->sec_level = l2cap_pi(parent)->sec_level;
>  		pi->role_switch = l2cap_pi(parent)->role_switch;
>  		pi->force_reliable = l2cap_pi(parent)->force_reliable;
> +		pi->flushable = l2cap_pi(parent)->flushable;
>  	} else {
>  		pi->imtu = L2CAP_DEFAULT_MTU;
>  		pi->omtu = 0;
> @@ -915,6 +922,7 @@ static void l2cap_sock_init(struct sock *sk, struct sock *parent)
>  		pi->sec_level = BT_SECURITY_LOW;
>  		pi->role_switch = 0;
>  		pi->force_reliable = 0;
> +		pi->flushable = BT_FLUSHABLE_OFF;
>  	}
>  
>  	/* Default config options */
> @@ -2098,6 +2106,20 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, ch
>  		bt_sk(sk)->defer_setup = opt;
>  		break;
>  
> +	case BT_FLUSHABLE:
> +		if (get_user(opt, (u32 __user *) optval)) {
> +			err = -EFAULT;
> +			break;
> +		}
> +
> +		if (opt > BT_FLUSHABLE_ON) {
> +			err = -EINVAL;
> +			break;
> +		}
> +
> +		l2cap_pi(sk)->flushable = opt;

You are not using this flushable value anywhere. Something is wrong here.

-- 
Gustavo F. Padovan
http://profusion.mobi

^ permalink raw reply

* Re: [PATCH] Fix crash while reading from mapped file
From: Lukasz Pawlik @ 2010-12-14 18:20 UTC (permalink / raw)
  To: Bastien Nocera; +Cc: Johan Hedberg, linux-bluetooth
In-Reply-To: <1292341274.3050.15.camel@novo.hadess.net>

Hi,

> If somebody can explain what that code is supposed to do, then writing a
> glib-ish version should be trivial, without having to duplicate the
> contents again. Then again, using something like:
> g_mapped_file_new ();
> g_strsplit ();
> g_mapped_file_unref ();

That won't fix anything since g_mapped_file_new uses mmap function so
contents may not be zero-terminated and we want use string function
next.

Lukasz Pawlik

^ permalink raw reply

* Re: [PATCH] Fix crash while reading from mapped file
From: Bastien Nocera @ 2010-12-14 15:41 UTC (permalink / raw)
  To: Johan Hedberg; +Cc: Lukasz Pawlik, linux-bluetooth
In-Reply-To: <20101214153405.GA11741@jh-x301>

On Tue, 2010-12-14 at 17:34 +0200, Johan Hedberg wrote:
> Hi Lukasz,
> 
> On Tue, Dec 14, 2010, Lukasz Pawlik wrote:
> > > I also wonder why we didn't use g_strsplit for this, it seems it would
> > > actually do the same, there is a little performance impact since we
> > > would have to iterate on the vector generated to call the callback
> > > while the current code do it in-place.
> > 
> > Marcel, Johan any thoughts about this ? Should we reimplement this
> > code using glib functions ?
> 
> It'd be nice to get some comments from Marcel since he is the original
> author of the textfile.c code. In general I'm not too happy about having
> to allocate a duplicate amount of memory for this (which is completely
> dependent on the file size), but I do agree that some fix is needed. I'd
> also like to make sure that we get a fix upstream before the next BlueZ
> release.

If somebody can explain what that code is supposed to do, then writing a
glib-ish version should be trivial, without having to duplicate the
contents again. Then again, using something like:
g_mapped_file_new ();
g_strsplit ();
g_mapped_file_unref ();
wouldn't actually allocate more memory per se. You could also loop over
the content of each line, from the mmapped contents, but you'd be making
the code harder to read, with not much real world gain.

In a very worst case scenario, duping 50k of memory shouldn't be this
expensive. I would certainly understand the problem if we had megabyte
files though.

Cheers


^ permalink raw reply

* Re: [PATCH] Fix crash while reading from mapped file
From: Johan Hedberg @ 2010-12-14 15:34 UTC (permalink / raw)
  To: Lukasz Pawlik; +Cc: linux-bluetooth
In-Reply-To: <AANLkTi=jaKy=o0MhzV6xRwyk00OxOhk302-DHXM7fEgE@mail.gmail.com>

Hi Lukasz,

On Tue, Dec 14, 2010, Lukasz Pawlik wrote:
> > I also wonder why we didn't use g_strsplit for this, it seems it would
> > actually do the same, there is a little performance impact since we
> > would have to iterate on the vector generated to call the callback
> > while the current code do it in-place.
> 
> Marcel, Johan any thoughts about this ? Should we reimplement this
> code using glib functions ?

It'd be nice to get some comments from Marcel since he is the original
author of the textfile.c code. In general I'm not too happy about having
to allocate a duplicate amount of memory for this (which is completely
dependent on the file size), but I do agree that some fix is needed. I'd
also like to make sure that we get a fix upstream before the next BlueZ
release.

Johan

^ permalink raw reply

* RE: [PATCH 1/4] Sim Access Profile API
From: Waldemar.Rymarkiewicz @ 2010-12-14 15:16 UTC (permalink / raw)
  To: marcel; +Cc: linux-bluetooth, johan.hedberg
In-Reply-To: <99B09243E1A5DA4898CDD8B7001114480BDADF2149@EXMB04.eu.tieto.com>


I see no more comments on this API. Does it mean it's fine.

/Waldek

>-----Original Message-----
>From: linux-bluetooth-owner@vger.kernel.org=20
>[mailto:linux-bluetooth-owner@vger.kernel.org] On Behalf Of=20
>Waldemar.Rymarkiewicz@tieto.com
>Sent: Thursday, December 02, 2010 4:23 PM
>To: padovan@profusion.mobi
>Cc: linux-bluetooth@vger.kernel.org; marcel@holtmann.org;=20
>johan.hedberg@gmail.com
>Subject: RE: [PATCH 1/4] Sim Access Profile API
>
>Hi Gustavo,
>
>>-----Original Message-----
>>From: Gustavo F. Padovan [mailto:pao@profusion.mobi] On Behalf Of=20
>>Gustavo F. Padovan
>>Sent: Thursday, December 02, 2010 4:20 PM
>>To: Rymarkiewicz Waldemar
>>Cc: linux-bluetooth@vger.kernel.org; Marcel Holtmann; Johan Hedberg
>>Subject: Re: [PATCH 1/4] Sim Access Profile API
>>
>>Hi Waldemar,
>>
>>* Waldemar Rymarkiewicz <waldemar.rymarkiewicz@tieto.com>
>>[2010-12-02 15:14:21 +0100]:
>>
>>> New API for Sim Access Profile.
>>> ---
>>>  Makefile.am     |    2 +-
>>>  doc/sap-api.txt |   34 ++++++++++++++++++++++++++++++++++
>>>  2 files changed, 35 insertions(+), 1 deletions(-)  create
>>mode 100644
>>> doc/sap-api.txt
>>>=20
>>> diff --git a/Makefile.am b/Makefile.am index 5f96975..97345a3 100644
>>> --- a/Makefile.am
>>> +++ b/Makefile.am
>>> @@ -354,7 +354,7 @@ EXTRA_DIST +=3D doc/manager-api.txt \
>>>  		doc/service-api.txt doc/agent-api.txt
>>doc/attribute-api.txt \
>>>  		doc/serial-api.txt doc/network-api.txt \
>>>  		doc/input-api.txt doc/audio-api.txt
>>doc/control-api.txt \
>>> -		doc/hfp-api.txt doc/assigned-numbers.txt
>>> +		doc/hfp-api.txt doc/assigned-numbers.txt doc/sap-api.txt
>>
>>Leave assigned-numbers.txt in the end.
>> =20
>>>  AM_YFLAGS =3D -d
>>> =20
>>> diff --git a/doc/sap-api.txt b/doc/sap-api.txt new file mode 100644=20
>>> index 0000000..b8b7253
>>> --- /dev/null
>>> +++ b/doc/sap-api.txt
>>> @@ -0,0 +1,34 @@
>>> +BlueZ D-Bus Sim Access Profile API description
>>> +***********************************
>>> +
>>> +Copyright (C) 2010 ST-Ericsson SA
>>> +
>>> +
>>> +Sim Access Profile hierarchy
>>> +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D
>>> +
>>> +Service		org.bluez
>>> +Interface	org.bluez.SimAccess
>>> +Object path	[variable prefix]/{hci0,hci1,...}
>>> +
>>> +Methods		void Disconnect()
>>> +
>>> +			Disconnects SAP client from the server.
>>> +
>>> +			Possible errors: org.bluez.Error.Failed
>>
>>Don't you need a Connect() method?
>
>It'a a server, not a client.  We will never initialize a connection.
>
>Thanks,
>/Waldek
>--
>To unsubscribe from this list: send the line "unsubscribe=20
>linux-bluetooth" in the body of a message to=20
>majordomo@vger.kernel.org More majordomo info at =20
>http://vger.kernel.org/majordomo-info.html
>=

^ permalink raw reply

* Re: [PATCH] Fix crash while reading from mapped file
From: Lukasz Pawlik @ 2010-12-14 15:10 UTC (permalink / raw)
  To: johan.hedberg; +Cc: linux-bluetooth
In-Reply-To: <AANLkTinVMvv9KG0oG1C=_wA6t7LhcYcCunuYGTWyn1Hs@mail.gmail.com>

> I also wonder why we didn't use g_strsplit for this, it seems it would
> actually do the same, there is a little performance impact since we
> would have to iterate on the vector generated to call the callback
> while the current code do it in-place.

Marcel, Johan any thoughts about this ? Should we reimplement this
code using glib functions ?

Lukasz Pawlik

^ permalink raw reply

* Re: [PATCH] Error should be returned instead of unnecessary dict_append_array()
From: Johan Hedberg @ 2010-12-14 14:44 UTC (permalink / raw)
  To: Pawel Wieczorkiewicz; +Cc: linux-bluetooth
In-Reply-To: <1292336427-20380-1-git-send-email-pawel.wieczorkiewicz@tieto.com>

Hi Pawel,

On Tue, Dec 14, 2010, Pawel Wieczorkiewicz wrote:
> If there are no adapter up and running, there would be
> no elements to be added using dict_append_array(). We
> should return DBus error ".DoesNotExist", rather than
> appending NULL pointer and zero elements.
> 
> On behalf of ST-Ericsson SA
> ---
>  src/manager.c |    9 +++++++++
>  1 files changed, 9 insertions(+), 0 deletions(-)

Nack. Manager.GetProperties shouldn't fail if there no adapters. There
will be more properties coming in the future (a "DefaultAdapter"
property for sure) and could either have an empty array for the Adapters
or just leave out that key from the dictionary (i.e. in the worst case
we've got an empty dictionary, but that's fine too imho).

Johan

^ permalink raw reply

* [PATCH] Error should be returned instead of unnecessary dict_append_array()
From: Pawel Wieczorkiewicz @ 2010-12-14 14:20 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Pawel Wieczorkiewicz

If there are no adapter up and running, there would be
no elements to be added using dict_append_array(). We
should return DBus error ".DoesNotExist", rather than
appending NULL pointer and zero elements.

On behalf of ST-Ericsson SA
---
 src/manager.c |    9 +++++++++
 1 files changed, 9 insertions(+), 0 deletions(-)

diff --git a/src/manager.c b/src/manager.c
index c8ec7e5..9060180 100644
--- a/src/manager.c
+++ b/src/manager.c
@@ -185,12 +185,21 @@ static DBusMessage *get_properties(DBusConnection *conn,
 		array[i] = (char *) adapter_get_path(adapter);
 		i++;
 	}
+
+	if (!i)
+		goto error;
+
 	dict_append_array(&dict, "Adapters", DBUS_TYPE_OBJECT_PATH, &array, i);
 	g_free(array);
 
 	dbus_message_iter_close_container(&iter, &dict);
 
 	return reply;
+
+error:
+	g_free(array);
+	g_free(reply);
+	return g_dbus_create_error(msg, ERROR_INTERFACE ".DoesNotExist", "Adapter does not exist");
 }
 
 static GDBusMethodTable manager_methods[] = {
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH 2/2] drivers:staging: ti-st: update the TI ST BT driver
From: pavan_savoy @ 2010-12-14 12:06 UTC (permalink / raw)
  To: gregkh, linux-kernel; +Cc: padovan, marcel, linux-bluetooth, Pavan Savoy
In-Reply-To: <1292328400-7649-2-git-send-email-pavan_savoy@ti.com>

From: Pavan Savoy <pavan_savoy@ti.com>

Update the bluetooth driver for TI-ST with the latest
bluetooth btwilink driver v7, which had undergone several
reviews.
The driver by itself was un-acceptable because of certain
design/architecture in the underlying TI ST driver.
So, park this driver here, as plans to work on the underlying
driver layer (TI-ST) is carried out.

Signed-off-by: Pavan Savoy <pavan_savoy@ti.com>
---
 drivers/staging/ti-st/Kconfig    |   13 ++
 drivers/staging/ti-st/Makefile   |    1 +
 drivers/staging/ti-st/btwilink.c |  363 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 377 insertions(+), 0 deletions(-)
 create mode 100644 drivers/staging/ti-st/Kconfig
 create mode 100644 drivers/staging/ti-st/Makefile
 create mode 100644 drivers/staging/ti-st/btwilink.c

diff --git a/drivers/staging/ti-st/Kconfig b/drivers/staging/ti-st/Kconfig
new file mode 100644
index 0000000..3cf6c3e
--- /dev/null
+++ b/drivers/staging/ti-st/Kconfig
@@ -0,0 +1,13 @@
+menu "Texas Instruments shared transport line discipline"
+config BT_WILINK
+       tristate "Texas Instruments WiLink7 driver"
+       depends on TI_ST
+       help
+         This enables the Bluetooth driver for Texas Instrument's BT/FM/GPS
+         combo devices. This makes use of shared transport line discipline
+         core driver to communicate with the BT core of the combo chip.
+
+         Say Y here to compile support for Texas Instrument's WiLink7 driver
+         into the kernel or say M to compile it as module.
+ endmenu
+
diff --git a/drivers/staging/ti-st/Makefile b/drivers/staging/ti-st/Makefile
new file mode 100644
index 0000000..8b8a795
--- /dev/null
+++ b/drivers/staging/ti-st/Makefile
@@ -0,0 +1 @@
++obj-$(CONFIG_BT_WILINK)                += btwilink.o
diff --git a/drivers/staging/ti-st/btwilink.c b/drivers/staging/ti-st/btwilink.c
new file mode 100644
index 0000000..71e69f8
--- /dev/null
+++ b/drivers/staging/ti-st/btwilink.c
@@ -0,0 +1,363 @@
+/*
+ *  Texas Instrument's Bluetooth Driver For Shared Transport.
+ *
+ *  Bluetooth Driver acts as interface between HCI core and
+ *  TI Shared Transport Layer.
+ *
+ *  Copyright (C) 2009-2010 Texas Instruments
+ *  Author: Raja Mani <raja_mani@ti.com>
+ *	Pavan Savoy <pavan_savoy@ti.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License 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.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#include <linux/platform_device.h>
+#include <net/bluetooth/bluetooth.h>
+#include <net/bluetooth/hci_core.h>
+
+#include <linux/ti_wilink_st.h>
+
+/* Bluetooth Driver Version */
+#define VERSION               "1.0"
+
+/* Number of seconds to wait for registration completion
+ * when ST returns PENDING status.
+ */
+#define BT_REGISTER_TIMEOUT   6000	/* 6 sec */
+
+/**
+ * struct ti_st - driver operation structure
+ * @hdev: hci device pointer which binds to bt driver
+ * @reg_status: ST registration callback status
+ * @st_write: write function provided by the ST driver
+ *	to be used by the driver during send_frame.
+ * @wait_reg_completion - completion sync between ti_st_open
+ *	and ti_st_registration_completion_cb.
+ */
+struct ti_st {
+	struct hci_dev *hdev;
+	char reg_status;
+	long (*st_write) (struct sk_buff *);
+	struct completion wait_reg_completion;
+};
+
+/* Increments HCI counters based on pocket ID (cmd,acl,sco) */
+static inline void ti_st_tx_complete(struct ti_st *hst, int pkt_type)
+{
+	struct hci_dev *hdev = hst->hdev;
+
+	/* Update HCI stat counters */
+	switch (pkt_type) {
+	case HCI_COMMAND_PKT:
+		hdev->stat.cmd_tx++;
+		break;
+
+	case HCI_ACLDATA_PKT:
+		hdev->stat.acl_tx++;
+		break;
+
+	case HCI_SCODATA_PKT:
+		hdev->stat.sco_tx++;
+		break;
+	}
+}
+
+/* ------- Interfaces to Shared Transport ------ */
+
+/* Called by ST layer to indicate protocol registration completion
+ * status.ti_st_open() function will wait for signal from this
+ * API when st_register() function returns ST_PENDING.
+ */
+static void st_registration_completion_cb(void *priv_data, char data)
+{
+	struct ti_st *lhst = priv_data;
+
+	/* Save registration status for use in ti_st_open() */
+	lhst->reg_status = data;
+	/* complete the wait in ti_st_open() */
+	complete(&lhst->wait_reg_completion);
+}
+
+/* Called by Shared Transport layer when receive data is
+ * available */
+static long st_receive(void *priv_data, struct sk_buff *skb)
+{
+	struct ti_st *lhst = priv_data;
+	int err;
+
+	if (!skb)
+		return -EFAULT;
+
+	if (!lhst) {
+		kfree_skb(skb);
+		return -EFAULT;
+	}
+
+	skb->dev = (void *) lhst->hdev;
+
+	/* Forward skb to HCI core layer */
+	err = hci_recv_frame(skb);
+	if (err < 0) {
+		BT_ERR("Unable to push skb to HCI core(%d)", err);
+		return err;
+	}
+
+	lhst->hdev->stat.byte_rx += skb->len;
+
+	return 0;
+}
+
+/* ------- Interfaces to HCI layer ------ */
+/* protocol structure registered with shared transport */
+static struct st_proto_s ti_st_proto = {
+	.type = ST_BT,
+	.recv = st_receive,
+	.reg_complete_cb = st_registration_completion_cb,
+};
+
+/* Called from HCI core to initialize the device */
+static int ti_st_open(struct hci_dev *hdev)
+{
+	unsigned long timeleft;
+	struct ti_st *hst;
+	int err;
+
+	BT_DBG("%s %p", hdev->name, hdev);
+	if (test_and_set_bit(HCI_RUNNING, &hdev->flags)) {
+		BT_ERR("btwilink already opened");
+		return -EBUSY;
+	}
+
+	/* provide contexts for callbacks from ST */
+	hst = hdev->driver_data;
+	ti_st_proto.priv_data = hst;
+
+	err = st_register(&ti_st_proto);
+	if (err == -EINPROGRESS) {
+		/* ST is busy with either protocol registration or firmware
+		 * download.
+		 */
+		/* Prepare wait-for-completion handler data structures.
+		 */
+		init_completion(&hst->wait_reg_completion);
+
+		/* Reset ST registration callback status flag , this value
+		 * will be updated in ti_st_registration_completion_cb()
+		 * function whenever it called from ST driver.
+		 */
+		hst->reg_status = -EINPROGRESS;
+
+		BT_DBG("waiting for registration completion signal from ST");
+		timeleft = wait_for_completion_timeout
+			(&hst->wait_reg_completion,
+			 msecs_to_jiffies(BT_REGISTER_TIMEOUT));
+		if (!timeleft) {
+			clear_bit(HCI_RUNNING, &hdev->flags);
+			BT_ERR("Timeout(%d sec),didn't get reg "
+					"completion signal from ST",
+					BT_REGISTER_TIMEOUT / 1000);
+			return -ETIMEDOUT;
+		}
+
+		/* Is ST registration callback called with ERROR status? */
+		if (hst->reg_status != 0) {
+			clear_bit(HCI_RUNNING, &hdev->flags);
+			BT_ERR("ST registration completed with invalid "
+					"status %d", hst->reg_status);
+			return -EAGAIN;
+		}
+		err = 0;
+	} else if (err != 0) {
+		clear_bit(HCI_RUNNING, &hdev->flags);
+		BT_ERR("st_register failed %d", err);
+		return err;
+	}
+
+	/* ti_st_proto.write is filled up by the underlying shared
+	 * transport driver upon registration
+	 */
+	hst->st_write = ti_st_proto.write;
+	if (!hst->st_write) {
+		BT_ERR("undefined ST write function");
+		clear_bit(HCI_RUNNING, &hdev->flags);
+
+		/* Undo registration with ST */
+		err = st_unregister(ST_BT);
+		if (err)
+			BT_ERR("st_unregister() failed with error %d", err);
+
+		hst->st_write = NULL;
+		return err;
+	}
+
+	return err;
+}
+
+/* Close device */
+static int ti_st_close(struct hci_dev *hdev)
+{
+	int err;
+	struct ti_st *hst = hdev->driver_data;
+
+	if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
+		return 0;
+
+	/* continue to unregister from transport */
+	err = st_unregister(ST_BT);
+	if (err)
+		BT_ERR("st_unregister() failed with error %d", err);
+
+	hst->st_write = NULL;
+
+	return err;
+}
+
+static int ti_st_send_frame(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;
+
+	hst = hdev->driver_data;
+
+	/* Prepend skb with frame type */
+	memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1);
+
+	BT_DBG("%s: type %d len %d", hdev->name, bt_cb(skb)->pkt_type,
+			skb->len);
+
+	/* Insert skb to shared transport layer's transmit queue.
+	 * Freeing skb memory is taken care in shared transport layer,
+	 * so don't free skb memory here.
+	 */
+	len = hst->st_write(skb);
+	if (len < 0) {
+		kfree_skb(skb);
+		BT_ERR("ST write failed (%ld)", len);
+		/* Try Again, would only fail if UART has gone bad */
+		return -EAGAIN;
+	}
+
+	/* ST accepted our skb. So, Go ahead and do rest */
+	hdev->stat.byte_tx += len;
+	ti_st_tx_complete(hst, bt_cb(skb)->pkt_type);
+
+	return 0;
+}
+
+static void ti_st_destruct(struct hci_dev *hdev)
+{
+	BT_DBG("%s", hdev->name);
+	kfree(hdev->driver_data);
+}
+
+static int bt_ti_probe(struct platform_device *pdev)
+{
+	static struct ti_st *hst;
+	struct hci_dev *hdev;
+	int err;
+
+	hst = kzalloc(sizeof(struct ti_st), GFP_KERNEL);
+	if (!hst)
+		return -ENOMEM;
+
+	/* Expose "hciX" device to user space */
+	hdev = hci_alloc_dev();
+	if (!hdev) {
+		kfree(hst);
+		return -ENOMEM;
+	}
+
+	BT_DBG("hdev %p", hdev);
+
+	hst->hdev = hdev;
+	hdev->bus = HCI_UART;
+	hdev->driver_data = hst;
+	hdev->open = ti_st_open;
+	hdev->close = ti_st_close;
+	hdev->flush = NULL;
+	hdev->send = ti_st_send_frame;
+	hdev->destruct = ti_st_destruct;
+	hdev->owner = THIS_MODULE;
+
+	err = hci_register_dev(hdev);
+	if (err < 0) {
+		BT_ERR("Can't register HCI device error %d", err);
+		kfree(hst);
+		hci_free_dev(hdev);
+		return err;
+	}
+
+	BT_DBG("HCI device registered (hdev %p)", hdev);
+
+	dev_set_drvdata(&pdev->dev, hst);
+	return err;
+}
+
+static int bt_ti_remove(struct platform_device *pdev)
+{
+	struct hci_dev *hdev;
+	struct ti_st *hst = dev_get_drvdata(&pdev->dev);
+
+	if (!hst)
+		return -EFAULT;
+
+	hdev = hst->hdev;
+	ti_st_close(hdev);
+	hci_unregister_dev(hdev);
+
+	hci_free_dev(hdev);
+	kfree(hst);
+
+	dev_set_drvdata(&pdev->dev, NULL);
+	return 0;
+}
+
+static struct platform_driver btwilink_driver = {
+	.probe = bt_ti_probe,
+	.remove = bt_ti_remove,
+	.driver = {
+		.name = "btwilink",
+		.owner = THIS_MODULE,
+	},
+};
+
+/* ------- Module Init/Exit interfaces ------ */
+static int __init btwilink_init(void)
+{
+	BT_INFO("Bluetooth Driver for TI WiLink - Version %s", VERSION);
+
+	return platform_driver_register(&btwilink_driver);
+}
+
+static void __exit btwilink_exit(void)
+{
+	platform_driver_unregister(&btwilink_driver);
+}
+
+module_init(btwilink_init);
+module_exit(btwilink_exit);
+
+/* ------ Module Info ------ */
+
+MODULE_AUTHOR("Raja Mani <raja_mani@ti.com>");
+MODULE_DESCRIPTION("Bluetooth Driver for TI Shared Transport" VERSION);
+MODULE_VERSION(VERSION);
+MODULE_LICENSE("GPL");
-- 
1.6.3.3

^ permalink raw reply related

* [PATCH 1/2] drivers:staging: ti-st: remove bt_drv
From: pavan_savoy @ 2010-12-14 12:06 UTC (permalink / raw)
  To: gregkh, linux-kernel; +Cc: padovan, marcel, linux-bluetooth, Pavan Savoy
In-Reply-To: <1292328400-7649-1-git-send-email-pavan_savoy@ti.com>

From: Pavan Savoy <pavan_savoy@ti.com>

Remove the BT driver from the staging folder.
This is to update the staging folder with the
latest BT driver.

Signed-off-by: Pavan Savoy <pavan_savoy@ti.com>
---
 drivers/staging/ti-st/Kconfig   |   14 -
 drivers/staging/ti-st/Makefile  |    5 -
 drivers/staging/ti-st/bt_drv.c  |  509 ---------------------------------------
 drivers/staging/ti-st/bt_drv.h  |   61 -----
 drivers/staging/ti-st/sysfs-uim |   28 ---
 5 files changed, 0 insertions(+), 617 deletions(-)
 delete mode 100644 drivers/staging/ti-st/Kconfig
 delete mode 100644 drivers/staging/ti-st/Makefile
 delete mode 100644 drivers/staging/ti-st/bt_drv.c
 delete mode 100644 drivers/staging/ti-st/bt_drv.h
 delete mode 100644 drivers/staging/ti-st/sysfs-uim

diff --git a/drivers/staging/ti-st/Kconfig b/drivers/staging/ti-st/Kconfig
deleted file mode 100644
index 074b8e8..0000000
--- a/drivers/staging/ti-st/Kconfig
+++ /dev/null
@@ -1,14 +0,0 @@
-#
-# TI's shared transport line discipline and the protocol
-# drivers (BT, FM and GPS)
-#
-menu "Texas Instruments shared transport line discipline"
-config ST_BT
-	tristate "BlueZ bluetooth driver for ST"
-	depends on BT && RFKILL
-	select TI_ST
-	help
-	  This enables the Bluetooth driver for TI BT/FM/GPS combo devices.
-	  This makes use of shared transport line discipline core driver to
-	  communicate with the BT core of the combo chip.
-endmenu
diff --git a/drivers/staging/ti-st/Makefile b/drivers/staging/ti-st/Makefile
deleted file mode 100644
index 5f11b82..0000000
--- a/drivers/staging/ti-st/Makefile
+++ /dev/null
@@ -1,5 +0,0 @@
-#
-# Makefile for TI's shared transport line discipline
-# and its protocol drivers (BT, FM, GPS)
-#
-obj-$(CONFIG_ST_BT) 		+= bt_drv.o
diff --git a/drivers/staging/ti-st/bt_drv.c b/drivers/staging/ti-st/bt_drv.c
deleted file mode 100644
index 75065bf..0000000
--- a/drivers/staging/ti-st/bt_drv.c
+++ /dev/null
@@ -1,509 +0,0 @@
-/*
- *  Texas Instrument's Bluetooth Driver For Shared Transport.
- *
- *  Bluetooth Driver acts as interface between HCI CORE and
- *  TI Shared Transport Layer.
- *
- *  Copyright (C) 2009 Texas Instruments
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License 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.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- */
-
-#include <net/bluetooth/bluetooth.h>
-#include <net/bluetooth/hci_core.h>
-
-#include <linux/ti_wilink_st.h>
-#include "bt_drv.h"
-
-/* Define this macro to get debug msg */
-#undef DEBUG
-
-#ifdef DEBUG
-#define BT_DRV_DBG(fmt, arg...)  printk(KERN_INFO "(btdrv):"fmt"\n" , ## arg)
-#define BTDRV_API_START()        printk(KERN_INFO "(btdrv): %s Start\n", \
-	__func__)
-#define BTDRV_API_EXIT(errno)    printk(KERN_INFO "(btdrv): %s Exit(%d)\n", \
-	__func__, errno)
-#else
-#define BT_DRV_DBG(fmt, arg...)
-#define BTDRV_API_START()
-#define BTDRV_API_EXIT(errno)
-#endif
-
-#define BT_DRV_ERR(fmt, arg...)  printk(KERN_ERR "(btdrv):"fmt"\n" , ## arg)
-
-static int reset;
-static struct hci_st *hst;
-
-/* Increments HCI counters based on pocket ID (cmd,acl,sco) */
-static inline void hci_st_tx_complete(struct hci_st *hst, int pkt_type)
-{
-	struct hci_dev *hdev;
-
-	BTDRV_API_START();
-
-	hdev = hst->hdev;
-
-	/* Update HCI stat counters */
-	switch (pkt_type) {
-	case HCI_COMMAND_PKT:
-		hdev->stat.cmd_tx++;
-		break;
-
-	case HCI_ACLDATA_PKT:
-		hdev->stat.acl_tx++;
-		break;
-
-	case HCI_SCODATA_PKT:
-		hdev->stat.cmd_tx++;
-		break;
-	}
-
-	BTDRV_API_EXIT(0);
-}
-
-/* ------- Interfaces to Shared Transport ------ */
-
-/* Called by ST layer to indicate protocol registration completion
- * status.hci_st_open() function will wait for signal from this
- * API when st_register() function returns ST_PENDING.
- */
-static void hci_st_registration_completion_cb(void *priv_data, char data)
-{
-	struct hci_st *lhst = (struct hci_st *)priv_data;
-	BTDRV_API_START();
-
-	/* hci_st_open() function needs value of 'data' to know
-	 * the registration status(success/fail),So have a back
-	 * up of it.
-	 */
-	lhst->streg_cbdata = data;
-
-	/* Got a feedback from ST for BT driver registration
-	 * request.Wackup hci_st_open() function to continue
-	 * it's open operation.
-	 */
-	complete(&lhst->wait_for_btdrv_reg_completion);
-
-	BTDRV_API_EXIT(0);
-}
-
-/* Called by Shared Transport layer when receive data is
- * available */
-static long hci_st_receive(void *priv_data, struct sk_buff *skb)
-{
-	int err;
-	int len;
-	struct hci_st *lhst = (struct hci_st *)priv_data;
-
-	BTDRV_API_START();
-
-	err = 0;
-	len = 0;
-
-	if (skb == NULL) {
-		BT_DRV_ERR("Invalid SKB received from ST");
-		BTDRV_API_EXIT(-EFAULT);
-		return -EFAULT;
-	}
-	if (!lhst) {
-		kfree_skb(skb);
-		BT_DRV_ERR("Invalid hci_st memory,freeing SKB");
-		BTDRV_API_EXIT(-EFAULT);
-		return -EFAULT;
-	}
-	if (!test_bit(BT_DRV_RUNNING, &lhst->flags)) {
-		kfree_skb(skb);
-		BT_DRV_ERR("Device is not running,freeing SKB");
-		BTDRV_API_EXIT(-EINVAL);
-		return -EINVAL;
-	}
-
-	len = skb->len;
-	skb->dev = (struct net_device *)lhst->hdev;
-
-	/* Forward skb to HCI CORE layer */
-	err = hci_recv_frame(skb);
-	if (err) {
-		kfree_skb(skb);
-		BT_DRV_ERR("Unable to push skb to HCI CORE(%d),freeing SKB",
-			   err);
-		BTDRV_API_EXIT(err);
-		return err;
-	}
-	lhst->hdev->stat.byte_rx += len;
-
-	BTDRV_API_EXIT(0);
-	return 0;
-}
-
-/* ------- Interfaces to HCI layer ------ */
-
-/* Called from HCI core to initialize the device */
-static int hci_st_open(struct hci_dev *hdev)
-{
-	static struct st_proto_s hci_st_proto;
-	unsigned long timeleft;
-	int err;
-
-	BTDRV_API_START();
-
-	err = 0;
-
-	BT_DRV_DBG("%s %p", hdev->name, hdev);
-
-	/* Already registered with ST ? */
-	if (test_bit(BT_ST_REGISTERED, &hst->flags)) {
-		BT_DRV_ERR("Registered with ST already,open called again?");
-		BTDRV_API_EXIT(0);
-		return 0;
-	}
-
-	/* Populate BT driver info required by ST */
-	memset(&hci_st_proto, 0, sizeof(hci_st_proto));
-
-	/* BT driver ID */
-	hci_st_proto.type = ST_BT;
-
-	/* Receive function which called from ST */
-	hci_st_proto.recv = hci_st_receive;
-
-	/* Packet match function may used in future */
-	hci_st_proto.match_packet = NULL;
-
-	/* Callback to be called when registration is pending */
-	hci_st_proto.reg_complete_cb = hci_st_registration_completion_cb;
-
-	/* This is write function pointer of ST. BT driver will make use of this
-	 * for sending any packets to chip. ST will assign and give to us, so
-	 * make it as NULL */
-	hci_st_proto.write = NULL;
-
-	/* send in the hst to be received at registration complete callback
-	 * and during st's receive
-	 */
-	hci_st_proto.priv_data = hst;
-
-	/* Register with ST layer */
-	err = st_register(&hci_st_proto);
-	if (err == -EINPROGRESS) {
-		/* Prepare wait-for-completion handler data structures.
-		 * Needed to syncronize this and st_registration_completion_cb()
-		 * functions.
-		 */
-		init_completion(&hst->wait_for_btdrv_reg_completion);
-
-		/* Reset ST registration callback status flag , this value
-		 * will be updated in hci_st_registration_completion_cb()
-		 * function whenever it called from ST driver.
-		 */
-		hst->streg_cbdata = -EINPROGRESS;
-
-		/* ST is busy with other protocol registration(may be busy with
-		 * firmware download).So,Wait till the registration callback
-		 * (passed as a argument to st_register() function) getting
-		 * called from ST.
-		 */
-		BT_DRV_DBG(" %s waiting for reg completion signal from ST",
-			   __func__);
-
-		timeleft =
-		    wait_for_completion_timeout
-		    (&hst->wait_for_btdrv_reg_completion,
-		     msecs_to_jiffies(BT_REGISTER_TIMEOUT));
-		if (!timeleft) {
-			BT_DRV_ERR("Timeout(%ld sec),didn't get reg"
-				   "completion signal from ST",
-				   BT_REGISTER_TIMEOUT / 1000);
-			BTDRV_API_EXIT(-ETIMEDOUT);
-			return -ETIMEDOUT;
-		}
-
-		/* Is ST registration callback called with ERROR value? */
-		if (hst->streg_cbdata != 0) {
-			BT_DRV_ERR("ST reg completion CB called with invalid"
-				   "status %d", hst->streg_cbdata);
-			BTDRV_API_EXIT(-EAGAIN);
-			return -EAGAIN;
-		}
-		err = 0;
-	} else if (err == -1) {
-		BT_DRV_ERR("st_register failed %d", err);
-		BTDRV_API_EXIT(-EAGAIN);
-		return -EAGAIN;
-	}
-
-	/* Do we have proper ST write function? */
-	if (hci_st_proto.write != NULL) {
-		/* We need this pointer for sending any Bluetooth pkts */
-		hst->st_write = hci_st_proto.write;
-	} else {
-		BT_DRV_ERR("failed to get ST write func pointer");
-
-		/* Undo registration with ST */
-		err = st_unregister(ST_BT);
-		if (err < 0)
-			BT_DRV_ERR("st_unregister failed %d", err);
-
-		hst->st_write = NULL;
-		BTDRV_API_EXIT(-EAGAIN);
-		return -EAGAIN;
-	}
-
-	/* Registration with ST layer is completed successfully,
-	 * now chip is ready to accept commands from HCI CORE.
-	 * Mark HCI Device flag as RUNNING
-	 */
-	set_bit(HCI_RUNNING, &hdev->flags);
-
-	/* Registration with ST successful */
-	set_bit(BT_ST_REGISTERED, &hst->flags);
-
-	BTDRV_API_EXIT(err);
-	return err;
-}
-
-/* Close device */
-static int hci_st_close(struct hci_dev *hdev)
-{
-	int err;
-
-	BTDRV_API_START();
-
-	err = 0;
-
-	/* Unregister from ST layer */
-	if (test_and_clear_bit(BT_ST_REGISTERED, &hst->flags)) {
-		err = st_unregister(ST_BT);
-		if (err != 0) {
-			BT_DRV_ERR("st_unregister failed %d", err);
-			BTDRV_API_EXIT(-EBUSY);
-			return -EBUSY;
-		}
-	}
-
-	hst->st_write = NULL;
-
-	/* ST layer would have moved chip to inactive state.
-	 * So,clear HCI device RUNNING flag.
-	 */
-	if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags)) {
-		BTDRV_API_EXIT(0);
-		return 0;
-	}
-
-	BTDRV_API_EXIT(err);
-	return err;
-}
-
-/* Called from HCI CORE , Sends frames to Shared Transport */
-static int hci_st_send_frame(struct sk_buff *skb)
-{
-	struct hci_dev *hdev;
-	struct hci_st *hst;
-	long len;
-
-	BTDRV_API_START();
-
-	if (skb == NULL) {
-		BT_DRV_ERR("Invalid skb received from HCI CORE");
-		BTDRV_API_EXIT(-ENOMEM);
-		return -ENOMEM;
-	}
-	hdev = (struct hci_dev *)skb->dev;
-	if (!hdev) {
-		BT_DRV_ERR("SKB received for invalid HCI Device (hdev=NULL)");
-		BTDRV_API_EXIT(-ENODEV);
-		return -ENODEV;
-	}
-	if (!test_bit(HCI_RUNNING, &hdev->flags)) {
-		BT_DRV_ERR("Device is not running");
-		BTDRV_API_EXIT(-EBUSY);
-		return -EBUSY;
-	}
-
-	hst = (struct hci_st *)hdev->driver_data;
-
-	/* Prepend skb with frame type */
-	memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1);
-
-	BT_DRV_DBG(" %s: type %d len %d", hdev->name, bt_cb(skb)->pkt_type,
-		   skb->len);
-
-	/* Insert skb to shared transport layer's transmit queue.
-	 * Freeing skb memory is taken care in shared transport layer,
-	 * so don't free skb memory here.
-	 */
-	if (!hst->st_write) {
-		kfree_skb(skb);
-		BT_DRV_ERR(" Can't write to ST, st_write null?");
-		BTDRV_API_EXIT(-EAGAIN);
-		return -EAGAIN;
-	}
-	len = hst->st_write(skb);
-	if (len < 0) {
-		/* Something went wrong in st write , free skb memory */
-		kfree_skb(skb);
-		BT_DRV_ERR(" ST write failed (%ld)", len);
-		BTDRV_API_EXIT(-EAGAIN);
-		return -EAGAIN;
-	}
-
-	/* ST accepted our skb. So, Go ahead and do rest */
-	hdev->stat.byte_tx += len;
-	hci_st_tx_complete(hst, bt_cb(skb)->pkt_type);
-
-	BTDRV_API_EXIT(0);
-	return 0;
-}
-
-static void hci_st_destruct(struct hci_dev *hdev)
-{
-	BTDRV_API_START();
-
-	if (!hdev) {
-		BT_DRV_ERR("Destruct called with invalid HCI Device"
-			   "(hdev=NULL)");
-		BTDRV_API_EXIT(0);
-		return;
-	}
-
-	BT_DRV_DBG("%s", hdev->name);
-
-	/* free hci_st memory */
-	if (hdev->driver_data != NULL)
-		kfree(hdev->driver_data);
-
-	BTDRV_API_EXIT(0);
-	return;
-}
-
-/* Creates new HCI device */
-static int hci_st_register_dev(struct hci_st *hst)
-{
-	struct hci_dev *hdev;
-
-	BTDRV_API_START();
-
-	/* Initialize and register HCI device */
-	hdev = hci_alloc_dev();
-	if (!hdev) {
-		BT_DRV_ERR("Can't allocate HCI device");
-		BTDRV_API_EXIT(-ENOMEM);
-		return -ENOMEM;
-	}
-	BT_DRV_DBG(" HCI device allocated. hdev= %p", hdev);
-
-	hst->hdev = hdev;
-	hdev->bus = HCI_UART;
-	hdev->driver_data = hst;
-	hdev->open = hci_st_open;
-	hdev->close = hci_st_close;
-	hdev->flush = NULL;
-	hdev->send = hci_st_send_frame;
-	hdev->destruct = hci_st_destruct;
-	hdev->owner = THIS_MODULE;
-
-	if (reset)
-		set_bit(HCI_QUIRK_NO_RESET, &hdev->quirks);
-
-	if (hci_register_dev(hdev) < 0) {
-		BT_DRV_ERR("Can't register HCI device");
-		hci_free_dev(hdev);
-		BTDRV_API_EXIT(-ENODEV);
-		return -ENODEV;
-	}
-
-	BT_DRV_DBG(" HCI device registered. hdev= %p", hdev);
-	BTDRV_API_EXIT(0);
-	return 0;
-}
-
-/* ------- Module Init interface ------ */
-
-static int __init bt_drv_init(void)
-{
-	int err;
-
-	BTDRV_API_START();
-
-	err = 0;
-
-	BT_DRV_DBG(" Bluetooth Driver Version %s", VERSION);
-
-	/* Allocate local resource memory */
-	hst = kzalloc(sizeof(struct hci_st), GFP_KERNEL);
-	if (!hst) {
-		BT_DRV_ERR("Can't allocate control structure");
-		BTDRV_API_EXIT(-ENFILE);
-		return -ENFILE;
-	}
-
-	/* Expose "hciX" device to user space */
-	err = hci_st_register_dev(hst);
-	if (err) {
-		/* Release local resource memory */
-		kfree(hst);
-
-		BT_DRV_ERR("Unable to expose hci0 device(%d)", err);
-		BTDRV_API_EXIT(err);
-		return err;
-	}
-	set_bit(BT_DRV_RUNNING, &hst->flags);
-
-	BTDRV_API_EXIT(err);
-	return err;
-}
-
-/* ------- Module Exit interface ------ */
-
-static void __exit bt_drv_exit(void)
-{
-	BTDRV_API_START();
-
-	/* Deallocate local resource's memory  */
-	if (hst) {
-		struct hci_dev *hdev = hst->hdev;
-
-		if (hdev == NULL) {
-			BT_DRV_ERR("Invalid hdev memory");
-			kfree(hst);
-		} else {
-			hci_st_close(hdev);
-			if (test_and_clear_bit(BT_DRV_RUNNING, &hst->flags)) {
-				/* Remove HCI device (hciX) created
-				 * in module init.
-				 */
-				hci_unregister_dev(hdev);
-
-				/* Free HCI device memory */
-				hci_free_dev(hdev);
-			}
-		}
-	}
-	BTDRV_API_EXIT(0);
-}
-
-module_init(bt_drv_init);
-module_exit(bt_drv_exit);
-
-/* ------ Module Info ------ */
-
-module_param(reset, bool, 0644);
-MODULE_PARM_DESC(reset, "Send HCI reset command on initialization");
-MODULE_AUTHOR("Raja Mani <raja_mani@ti.com>");
-MODULE_DESCRIPTION("Bluetooth Driver for TI Shared Transport" VERSION);
-MODULE_VERSION(VERSION);
-MODULE_LICENSE("GPL");
diff --git a/drivers/staging/ti-st/bt_drv.h b/drivers/staging/ti-st/bt_drv.h
deleted file mode 100644
index a0beebe..0000000
--- a/drivers/staging/ti-st/bt_drv.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- *  Texas Instrument's Bluetooth Driver For Shared Transport.
- *
- *  Bluetooth Driver acts as interface between HCI CORE and
- *  TI Shared Transport Layer.
- *
- *  Copyright (C) 2009 Texas Instruments
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License 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.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- */
-
-#ifndef _BT_DRV_H
-#define _BT_DRV_H
-
-/* Bluetooth Driver Version */
-#define VERSION               "1.0"
-
-/* Defines number of seconds to wait for reg completion
- * callback getting called from ST (in case,registration
- * with ST returns PENDING status)
- */
-#define BT_REGISTER_TIMEOUT   msecs_to_jiffies(6000)	/* 6 sec */
-
-/* BT driver's local status */
-#define BT_DRV_RUNNING        0
-#define BT_ST_REGISTERED      1
-
-/* BT driver operation structure */
-struct hci_st {
-
-	/* hci device pointer which binds to bt driver */
-	struct hci_dev *hdev;
-
-	/* used locally,to maintain various BT driver status */
-	unsigned long flags;
-
-	/* to hold ST registration callback  status */
-	char streg_cbdata;
-
-	/* write function pointer of ST driver */
-	long (*st_write) (struct sk_buff *);
-
-	/* Wait on comepletion handler needed to synchronize
-	 * hci_st_open() and hci_st_registration_completion_cb()
-	 * functions.*/
-	struct completion wait_for_btdrv_reg_completion;
-};
-
-#endif
diff --git a/drivers/staging/ti-st/sysfs-uim b/drivers/staging/ti-st/sysfs-uim
deleted file mode 100644
index 626bda5..0000000
--- a/drivers/staging/ti-st/sysfs-uim
+++ /dev/null
@@ -1,28 +0,0 @@
-What:           /sys/class/rfkill/rfkill%d/
-Date:           March 22
-Contact:        Pavan Savoy <pavan_savoy@ti.com>
-Description:
-		Creates the rfkill entries for Radio apps like
-		BT app, FM app or GPS app to toggle corresponding
-		cores of the chip
-
-What:           /dev/rfkill
-Date:           March 22
-Contact:        Pavan Savoy <pavan_savoy@ti.com>
-Description:
-		A daemon which maintains the ldisc installation and
-		uninstallation would be ppolling on this device and listening
-		on events which would suggest either to install or un-install
-		line discipline
-
-What:           /sys/kernel/debug/ti-st/version
-Contact:        Pavan Savoy <pavan_savoy@ti.com>
-Description:
-		WiLink chip's ROM version exposed to user-space for some
-		proprietary protocol stacks to make use of.
-
-What:           /sys/kernel/debug/ti-st/protocols
-Contact:        Pavan Savoy <pavan_savoy@ti.com>
-Description:
-		The reason for chip being ON, the list of protocols registered.
-
-- 
1.6.3.3

^ permalink raw reply related

* [PATCH 0/2] keep ti-st staging updated
From: pavan_savoy @ 2010-12-14 12:06 UTC (permalink / raw)
  To: gregkh, linux-kernel; +Cc: padovan, marcel, linux-bluetooth, Pavan Savoy

From: Pavan Savoy <pavan_savoy@ti.com>

Greg,

In my attempt to upstream BT driver based on TI ST driver,
I had posted several patches to linux-bluetooth.

At this point, there are no review comments as such specifically
to bluetooth driver but there are few concerns regarding the TI-ST driver itself.

As I await the responses from Gustavo, Marcel on how best to proceed
in improving btwilink driver, I am deleting the very old bt_drv from
the staging and updating it with relatively acceptable btwilink driver.

Pavan Savoy (2):
  drivers:staging: ti-st: remove bt_drv
  drivers:staging: ti-st: update the TI ST BT driver

 drivers/staging/ti-st/Kconfig    |   25 +-
 drivers/staging/ti-st/Makefile   |    6 +-
 drivers/staging/ti-st/bt_drv.c   |  509 --------------------------------------
 drivers/staging/ti-st/bt_drv.h   |   61 -----
 drivers/staging/ti-st/btwilink.c |  363 +++++++++++++++++++++++++++
 drivers/staging/ti-st/sysfs-uim  |   28 --
 6 files changed, 376 insertions(+), 616 deletions(-)
 delete mode 100644 drivers/staging/ti-st/bt_drv.c
 delete mode 100644 drivers/staging/ti-st/bt_drv.h
 create mode 100644 drivers/staging/ti-st/btwilink.c
 delete mode 100644 drivers/staging/ti-st/sysfs-uim

^ permalink raw reply

* [PATCH 2/2] Bluetooth: Fix __hci_request synchronization for hci_open_dev
From: johan.hedberg @ 2010-12-14 12:04 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1292328244-5335-1-git-send-email-johan.hedberg@gmail.com>

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

The initialization function used by hci_open_dev (hci_init_req) sends
many different HCI commands. The __hci_request function should only
return when all of these commands have completed (or a timeout occurs).
Several of these commands cause hci_req_complete to be called which
causes __hci_request to return prematurely.

This patch fixes the issue by making use of the HCI_INIT flag which is
set during the initialization procedure. The hci_req_comple function
will no longer do anything when this flag is set and a new
hci_init_complete function is added which ignores the flag and gets
called when the last hci_init_req HCI command completes.

Signed-off-by: Johan Hedberg <johan.hedberg@nokia.com>
---
 include/net/bluetooth/hci_core.h |    1 +
 net/bluetooth/hci_core.c         |   14 ++++++++++++++
 net/bluetooth/hci_event.c        |   14 ++++++++++++++
 3 files changed, 29 insertions(+), 0 deletions(-)

diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 3786ee8..1f421df 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -694,5 +694,6 @@ struct hci_sec_filter {
 #define hci_req_unlock(d)	mutex_unlock(&d->req_lock)
 
 void hci_req_complete(struct hci_dev *hdev, int result);
+void hci_init_complete(struct hci_dev *hdev, int result);
 
 #endif /* __HCI_CORE_H */
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 6374054..8d08538 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -91,10 +91,24 @@ static void hci_notify(struct hci_dev *hdev, int event)
 
 /* ---- HCI requests ---- */
 
+void hci_init_complete(struct hci_dev *hdev, int result)
+{
+	BT_DBG("%s result 0x%2.2x", hdev->name, result);
+
+	if (hdev->req_status == HCI_REQ_PEND) {
+		hdev->req_result = result;
+		hdev->req_status = HCI_REQ_DONE;
+		wake_up_interruptible(&hdev->req_wait_q);
+	}
+}
+
 void hci_req_complete(struct hci_dev *hdev, int result)
 {
 	BT_DBG("%s result 0x%2.2x", hdev->name, result);
 
+	if (test_bit(HCI_INIT, &hdev->flags))
+		return;
+
 	if (hdev->req_status == HCI_REQ_PEND) {
 		hdev->req_result = result;
 		hdev->req_status = HCI_REQ_DONE;
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 8923b36..939ba9f 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -539,6 +539,16 @@ static void hci_cc_read_bd_addr(struct hci_dev *hdev, struct sk_buff *skb)
 	hci_req_complete(hdev, rp->status);
 }
 
+static void hci_cc_write_ca_timeout(struct hci_dev *hdev, struct sk_buff *skb)
+{
+	__u8 status = *((__u8 *) skb->data);
+
+	BT_DBG("%s status 0x%x", hdev->name, status);
+
+	if (test_bit(HCI_INIT, &hdev->flags))
+		hci_init_complete(hdev, status);
+}
+
 static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
 {
 	BT_DBG("%s status 0x%x", hdev->name, status);
@@ -1379,6 +1389,10 @@ static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *sk
 		hci_cc_read_bd_addr(hdev, skb);
 		break;
 
+	case HCI_OP_WRITE_CA_TIMEOUT:
+		hci_cc_write_ca_timeout(hdev, skb);
+		break;
+
 	default:
 		BT_DBG("%s opcode 0x%x", hdev->name, opcode);
 		break;
-- 
1.7.2.3


^ permalink raw reply related

* [PATCH 1/2] Bluetooth: Introduce a new HCI_CLOSE flag for hci_dev_close()
From: johan.hedberg @ 2010-12-14 12:04 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1292328244-5335-1-git-send-email-johan.hedberg@gmail.com>

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

To be able to handle the intialization state differently from the
closing state (e.g. different sets of HCI commands are sent in them) a
distinct state flag should be used when closing a device.

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

diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index 29a7a8c..517a652 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -68,6 +68,7 @@ enum {
 	HCI_UP,
 	HCI_INIT,
 	HCI_RUNNING,
+	HCI_CLOSE,
 
 	HCI_PSCAN,
 	HCI_ISCAN,
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 1a4ec97..6374054 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -581,10 +581,10 @@ 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)) {
-		set_bit(HCI_INIT, &hdev->flags);
+		set_bit(HCI_CLOSE, &hdev->flags);
 		__hci_request(hdev, hci_reset_req, 0,
 					msecs_to_jiffies(250));
-		clear_bit(HCI_INIT, &hdev->flags);
+		clear_bit(HCI_CLOSE, &hdev->flags);
 	}
 
 	/* Kill cmd task */
@@ -1029,7 +1029,8 @@ int hci_recv_frame(struct sk_buff *skb)
 {
 	struct hci_dev *hdev = (struct hci_dev *) skb->dev;
 	if (!hdev || (!test_bit(HCI_UP, &hdev->flags)
-				&& !test_bit(HCI_INIT, &hdev->flags))) {
+				&& !test_bit(HCI_INIT, &hdev->flags)
+				&& !test_bit(HCI_CLOSE, &hdev->flags))) {
 		kfree_skb(skb);
 		return -ENXIO;
 	}
@@ -1695,7 +1696,8 @@ static void hci_rx_task(unsigned long arg)
 			continue;
 		}
 
-		if (test_bit(HCI_INIT, &hdev->flags)) {
+		if (test_bit(HCI_INIT, &hdev->flags) ||
+					test_bit(HCI_CLOSE, &hdev->flags)) {
 			/* Don't process data packets in this states. */
 			switch (bt_cb(skb)->pkt_type) {
 			case HCI_ACLDATA_PKT:
-- 
1.7.2.3


^ permalink raw reply related

* Patches to fix kernel side init/deinit of adapters
From: johan.hedberg @ 2010-12-14 12:04 UTC (permalink / raw)
  To: linux-bluetooth

Hi,

Before I start implementing support for powering on and off adapters
through the management interface some basic things in the current code
need fixing. The first issue is that the __hci_request doesn't work the
way it's supposed to when called from hci_open_dev. It's supposed to
return when the entire request is complete but right now it returns as
soon as the first command in the request is complete.

The first patch in this set is needed to make it possible to take
advantage of the HCI_INIT flag in the second patch.

Johan


^ permalink raw reply

* Re: [PATCH 00/10] More btd_error_* patches
From: Johan Hedberg @ 2010-12-14  8:56 UTC (permalink / raw)
  To: Gustavo F. Padovan; +Cc: linux-bluetooth
In-Reply-To: <1292275987-13799-1-git-send-email-padovan@profusion.mobi>

Hi Gustavo,

On Mon, Dec 13, 2010, Gustavo F. Padovan wrote:
> This patch set adds a new error function btd_error_failed(), which has a str
> parameter to enable a more accurate error report in the case the usual
> btd_error_* does not fit.
> 
> After this patch set there will 10 occurrences of g_dbus_create_error() inside
> bluez code (not counting health/ here)

Thanks. The patches are now upstream. However, I did have to push other
fixes on top of them since a few functions that you assumed were
returning a proper negative errno value were in fact only returning -1.

Johan

^ permalink raw reply

* Re: [RFC] Bluetooth: Use non-flushable pb flag by default for ACL data on capable chipsets.
From: Suraj Sumangala @ 2010-12-14  6:34 UTC (permalink / raw)
  To: Emeltchenko Andrei; +Cc: linux-bluetooth@vger.kernel.org
In-Reply-To: <1292251105-31130-2-git-send-email-Andrei.Emeltchenko.news@gmail.com>

Hi Andrei,

On 12/13/2010 8:08 PM, Emeltchenko Andrei wrote:
>   static inline void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, void *data)
>   {
>   	struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data);
> +	u8 flags;
>
>   	BT_DBG("code 0x%2.2x", code);
>
>   	if (!skb)
>   		return;
>
> -	hci_send_acl(conn->hcon, skb, 0);
> +	if (lmp_no_flush_capable(conn->hcon->hdev))
> +		flags = ACL_START_NO_FLUSH;
> +	else
> +		flags = ACL_START;
> +
> +	hci_send_acl(conn->hcon, skb, flags);
>   }
>
Should we send L2CAP command packets also as flushable packets? Should 
it be non-flushable?
I thought only L2CAP data frames should be sent as flushable.

Regards
Suraj


^ permalink raw reply

* LE Compound Procedure strategy
From: Brian Gix @ 2010-12-13 21:46 UTC (permalink / raw)
  To: Vinicius Costa Gomes; +Cc: linux-bluetooth


Hi Vinicius,

I am breaking this out into a new conversation.

How about we create a new parameter to g_attrib_send, which is a boolean 
that indicates wether or not the command being sent may be the start (or 
continuation) of a Compound GATT procedure?

If this flag is TRUE, then when gattrib.c creates the command record for 
it, it will see if it is continuing a prior procedure, and if so add it 
to the head of the queue. Perhaps even *replace* the current head, which 
would presumably be recognized as the original command.

This would allow it to reuse the Command ID (allowing the upper layers 
to cancel as needed) and ensure the single-threaded intent of compound 
GATT procedures.

An additional gattrib.c API could then be added which must be called at 
the conclusion of all compound GATT procedures. This new API would 
perform final clean-up on the procedure, including allowing the next 
(following) items in the command queue to be serviced.

Your Thoughts?


-- 
Brian Gix
bgix@codeaurora.org
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum

^ permalink raw reply

* Re: [PATCH 1/1] Support for reading long Characteristic Values.
From: Brian Gix @ 2010-12-13 21:33 UTC (permalink / raw)
  To: Vinicius Costa Gomes; +Cc: linux-bluetooth, padovan, rshaffer
In-Reply-To: <20101213203336.GC7549@eris>

Hi Vinicius,

On 12/13/2010 12:33 PM, Vinicius Costa Gomes wrote:
> On 11:56 Mon 13 Dec, Brian Gix wrote:
> [trimmed]
 >
 >>>> +
 >>>> +	if (ret_val != 0)
 >>>> +		return;
 >>>> +
 >>>> +	status = ATT_ECODE_INSUFF_RESOURCES;
 >>>> +
 >>>> +done:
 >>>> +	long_read->func(status, res_pdu, res_len, long_read->user_data);
 >>>
 >>> If g_attrib_send() fails, load_read->result_data may be leaking here.
>>
>> Is there no guarantee that the GAttribResultFunc parameter will be
>> invoked if there is a non-Zero return value from g_attrib_send?
>>
>> If there is paths that could result in a non-response (abnormal link
>> termination?) then you are correct, and I will need to rethink clean-up.
>
> The case I was referring was when g_attrib_send() cannot allocate memory for
> the command.
>

I don't think this is an issue, because if g_attrib_send() cannot 
allocate memory, then it will return a 0, and fall through to the 
completion and clean-up. However, I like the idea of doing all clean-up 
in the destructor anyway, which resolves the memory leak potential.


>>>  [...]
>> Also:
>> If we intend to use the ID of the (original) command to cancel the GATT
>> procedure, I propose the following:
>>
>> Compound GATT procedure such as the Read Long procedure that I am
>> implementing, should save the original ID returned by g_attrib_send in
>> the nested user_data structure such as I have done. When subsequent ATT
>> commands are sent as part of the same GATT procedure, the new command
>> shall be assigned the same ID as the original.  This could be done with
>> a function in gattrib.c with the prototype:
>>
>> g_attrib_set_id(GAttrib *attrib, guint old_id, guint new_id);
>>
>> This would allow the upper layer to cancel the entire GATT procedure,
>> even if it is partially completed.
>>
>> This same methodology could then be applied to long writes, and other
>> compound GATT procedures.
>>
>> What do you think?
>
> Sounds good, I just don't know about messing with the commands id's,
> maybe having some thing like command groups.
>
> For example, adding these funtions:
>
> guint g_attrib_send_full(GAttrib *attrib, guint8 opcode, const guint8 *pdu,
> 				guint16 len, guint group, GAttribResultFunc func,
> 				gpointer user_data, GDestroyNotify notify);
>
> gboolean g_attrib_cancel_group(GAttrib *attrib, guint group);
>
> How do this look?
>

My biggest objection would be that to go this route, I think we would 
want to extend this "command group" to all GATT procedures, and not just 
the ones known or suspected to be Compound.  I don't think that 
canceling a "Characteristic Value Read" procedure should be any 
different (or use a different parameter type) than canceling "Find 
Primary Service", for example.

Do you think everything in gatt.c should use these "command groups"? 
And if so, by what mechanism would the "group number" remain unique?

It doesn't seem to me to be such a horrible overloading of the id. I do 
see that when a cancel is called, that it is important that only one 
command with that ID is in the queue. However, this reclaimation/reuse 
of the old ID would only occur after the prior instance is in the 
process of being destroyed. The danger I suppose would be the misuse of 
this renumbering capability by an entity other than gatt.c.


I'm sorry this is getting long winded BUT:

This also highlights the inherent danger of allowing multiple Requests 
to be queued up. If are to allow a Read-Value, Write-Value, Read-Value 
sequence of commands to be enqueued onto the attrib->queue, it will be 
impossible to correctly implement any of the compound Read or Write 
commands, because the subsequent "Read-Blob" would be added to the end 
of the queue, and the read could be split around a write.  GATT/ATT was 
always intended to be a single outstanding request (and procedure) at a 
time kind of protocol, and having a FIFO attrib->queue subverts that intent.

To get compound GATT procedures to work properly (while maintaining the 
Attrib queuing mechanism) we may need to restructure gattrib.c such that 
we can add the subsequent commands to the *head* of the queue, and not 
call wake_up_sender in the received_data() function until after the 
cmd->func() has been invoked, and given the opportunity to "continue the 
current procedure".

>
> Cheers,


-- 
Brian Gix
bgix@codeaurora.org
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum

^ permalink raw reply

* [PATCH 10/10] src: use btd_error_failed()
From: Gustavo F. Padovan @ 2010-12-13 21:33 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1292275987-13799-10-git-send-email-padovan@profusion.mobi>

---
 src/adapter.c |   37 +++++++++++++------------------------
 src/device.c  |   44 ++++++++++++--------------------------------
 2 files changed, 25 insertions(+), 56 deletions(-)

diff --git a/src/adapter.c b/src/adapter.c
index e37b200..47ee26a 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -146,12 +146,6 @@ static inline DBusMessage *adapter_not_ready(DBusMessage *msg)
 			"Adapter is not ready");
 }
 
-static inline DBusMessage *failed_strerror(DBusMessage *msg, int err)
-{
-	return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
-							"%s", strerror(err));
-}
-
 static inline DBusMessage *not_in_progress(DBusMessage *msg, const char *str)
 {
 	return g_dbus_create_error(msg, ERROR_INTERFACE ".NotInProgress",
@@ -523,7 +517,7 @@ static DBusMessage *set_discoverable(DBusConnection *conn, DBusMessage *msg,
 
 	err = set_mode(adapter, mode, msg);
 	if (err < 0)
-		return failed_strerror(msg, -err);
+		return btd_error_failed(msg, strerror(-err));
 
 	return NULL;
 }
@@ -548,7 +542,7 @@ static DBusMessage *set_powered(DBusConnection *conn, DBusMessage *msg,
 
 	err = set_mode(adapter, mode, msg);
 	if (err < 0)
-		return failed_strerror(msg, -err);
+		return btd_error_failed(msg, strerror(-err));
 
 	return NULL;
 }
@@ -570,7 +564,7 @@ static DBusMessage *set_pairable(DBusConnection *conn, DBusMessage *msg,
 
 	err = set_mode(adapter, MODE_DISCOVERABLE, NULL);
 	if (err < 0 && msg)
-		return failed_strerror(msg, -err);
+		return btd_error_failed(msg, strerror(-err));
 
 store:
 
@@ -775,7 +769,7 @@ static void confirm_mode_cb(struct agent *agent, DBusError *derr, void *data)
 
 	err = set_mode(req->adapter, req->mode, NULL);
 	if (err < 0)
-		reply = failed_strerror(req->msg, -err);
+		reply = btd_error_failed(req->msg, strerror(-err));
 	else
 		reply = dbus_message_new_method_return(req->msg);
 
@@ -906,7 +900,7 @@ static DBusMessage *set_name(DBusConnection *conn, DBusMessage *msg,
 	if (adapter->up) {
 		int err = adapter_ops->set_name(adapter->dev_id, name);
 		if (err < 0)
-			return failed_strerror(msg, err);
+			return btd_error_failed(msg, strerror(-err));
 
 		adapter->name_stored = TRUE;
 	}
@@ -1185,7 +1179,7 @@ static DBusMessage *adapter_start_discovery(DBusConnection *conn,
 
 	err = start_discovery(adapter);
 	if (err < 0)
-		return failed_strerror(msg, -err);
+		return btd_error_failed(msg, strerror(-err));
 
 done:
 	req = create_session(adapter, conn, msg, 0,
@@ -1208,8 +1202,7 @@ static DBusMessage *adapter_stop_discovery(DBusConnection *conn,
 
 	req = find_session(adapter->disc_sessions, sender);
 	if (!req)
-		return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
-				"Invalid discovery session");
+		return btd_error_failed(msg, "Invalid discovery session");
 
 	session_unref(req);
 	info("Stopping discovery");
@@ -1446,7 +1439,7 @@ static DBusMessage *request_session(DBusConnection *conn,
 					confirm_mode_cb, req, NULL);
 	if (err < 0) {
 		session_unref(req);
-		return failed_strerror(msg, -err);
+		return btd_error_failed(msg, strerror(-err));
 	}
 
 	return NULL;
@@ -1461,8 +1454,7 @@ static DBusMessage *release_session(DBusConnection *conn,
 
 	req = find_session(adapter->mode_sessions, sender);
 	if (!req)
-		return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
-				"No Mode to release");
+		return btd_error_failed(msg, "Invalid Session");
 
 	session_unref(req);
 
@@ -1622,7 +1614,7 @@ static DBusMessage *create_device(DBusConnection *conn,
 	err = device_browse(device, conn, msg, NULL, FALSE);
 	if (err < 0) {
 		adapter_remove_device(conn, adapter, device, TRUE);
-		return failed_strerror(msg, -err);
+		return btd_error_failed(msg, strerror(-err));
 	}
 
 	return NULL;
@@ -1676,8 +1668,7 @@ static DBusMessage *create_paired_device(DBusConnection *conn,
 
 	device = adapter_get_device(conn, adapter, address);
 	if (!device)
-		return g_dbus_create_error(msg,
-				ERROR_INTERFACE ".Failed",
+		return btd_error_failed(msg,
 				"Unable to create a new device object");
 
 	return device_create_bonding(device, conn, msg, agent_path, cap);
@@ -1788,9 +1779,7 @@ static DBusMessage *register_agent(DBusConnection *conn, DBusMessage *msg,
 	agent = agent_create(adapter, name, path, cap,
 				(agent_remove_cb) agent_removed, adapter);
 	if (!agent)
-		return g_dbus_create_error(msg,
-				ERROR_INTERFACE ".Failed",
-				"Failed to create a new agent");
+		return btd_error_failed(msg, "Failed to create a new agent");
 
 	adapter->agent = agent;
 
@@ -2334,7 +2323,7 @@ static void set_mode_complete(struct btd_adapter *adapter)
 		DBusMessage *reply;
 
 		if (err < 0)
-			reply = failed_strerror(msg, -err);
+			reply = btd_error_failed(msg, strerror(-err));
 		else
 			reply = g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
 
diff --git a/src/device.c b/src/device.c
index 0f4dc0b..cec2153 100644
--- a/src/device.c
+++ b/src/device.c
@@ -157,20 +157,6 @@ static uint16_t uuid_list[] = {
 
 static GSList *device_drivers = NULL;
 
-static DBusHandlerResult error_failed(DBusConnection *conn,
-					DBusMessage *msg, const char * desc)
-{
-	return error_common_reply(conn, msg, ERROR_INTERFACE ".Failed", desc);
-}
-
-static DBusHandlerResult error_failed_errno(DBusConnection *conn,
-						DBusMessage *msg, int err)
-{
-	const char *desc = strerror(err);
-
-	return error_failed(conn, msg, desc);
-}
-
 static void browse_request_free(struct browse_req *req)
 {
 	if (req->listener_id)
@@ -380,9 +366,7 @@ static DBusMessage *set_alias(DBusConnection *conn, DBusMessage *msg,
 	err = write_device_alias(srcaddr, dstaddr,
 			g_str_equal(alias, "") ? NULL : alias);
 	if (err < 0)
-		return g_dbus_create_error(msg,
-				ERROR_INTERFACE ".Failed",
-				"%s", strerror(-err));
+		return btd_error_failed(msg, strerror(-err));
 
 	g_free(device->alias);
 	device->alias = g_str_equal(alias, "") ? NULL : g_strdup(alias);
@@ -412,9 +396,7 @@ static DBusMessage *set_trust(DBusConnection *conn, DBusMessage *msg,
 
 	err = write_trust(srcaddr, dstaddr, GLOBAL_TRUST, value);
 	if (err < 0)
-		return g_dbus_create_error(msg,
-				ERROR_INTERFACE ".Failed",
-				"%s", strerror(-err));
+		return btd_error_failed(msg, strerror(-err));
 
 	device->trusted = value;
 
@@ -526,12 +508,9 @@ static DBusMessage *set_blocked(DBusConnection *conn, DBusMessage *msg,
 	case 0:
 		return dbus_message_new_method_return(msg);
 	case EINVAL:
-		return g_dbus_create_error(msg,
-					ERROR_INTERFACE ".NotSupported",
-					"Kernel lacks blacklist support");
+		return btd_error_failed(msg, "Kernel lacks blacklist support");
 	default:
-		return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
-						"%s", strerror(-err));
+		return btd_error_failed(msg, strerror(-err));
 	}
 }
 
@@ -627,8 +606,7 @@ static DBusMessage *discover_services(DBusConnection *conn,
 	return NULL;
 
 fail:
-	return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
-					"Discovery Failed");
+	return btd_error_failed(msg, strerror(-err));
 }
 
 static const char *browse_request_get_requestor(struct browse_req *req)
@@ -1473,7 +1451,9 @@ send_reply:
 	else if (dbus_message_is_method_call(req->msg, ADAPTER_INTERFACE,
 						"CreateDevice")) {
 		if (err < 0) {
-			error_failed_errno(req->conn, req->msg, -err);
+			DBusMessage *reply;
+			reply = btd_error_failed(req->msg, strerror(-err));
+			g_dbus_send_message(req->conn, reply);
 			goto cleanup;
 		}
 
@@ -1544,7 +1524,9 @@ static void primary_cb(GSList *services, int err, gpointer user_data)
 	struct btd_device *device = req->device;
 
 	if (err) {
-		error_failed_errno(req->conn, req->msg, -err);
+		DBusMessage *reply;
+		reply = btd_error_failed(req->msg, strerror(-err));
+		g_dbus_send_message(req->conn, reply);
 		goto done;
 	}
 
@@ -2000,9 +1982,7 @@ DBusMessage *device_create_bonding(struct btd_device *device,
 				BT_IO_OPT_INVALID);
 	if (io == NULL) {
 		DBusMessage *reply;
-		reply = g_dbus_create_error(msg,
-				ERROR_INTERFACE ".ConnectionAttemptFailed",
-				"%s", err->message);
+		reply = btd_error_failed(msg, err->message);
 		error("bt_io_connect: %s", err->message);
 		g_error_free(err);
 		return reply;
-- 
1.7.3.2


^ permalink raw reply related

* [PATCH 09/10] serial: use btd_error_failed()
From: Gustavo F. Padovan @ 2010-12-13 21:33 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1292275987-13799-9-git-send-email-padovan@profusion.mobi>

---
 serial/port.c  |   20 +++++++++-----------
 serial/proxy.c |    8 ++------
 2 files changed, 11 insertions(+), 17 deletions(-)

diff --git a/serial/port.c b/serial/port.c
index 0d1e600..1458f06 100644
--- a/serial/port.c
+++ b/serial/port.c
@@ -248,7 +248,7 @@ static void open_notify(int fd, int err, struct serial_port *port)
 	if (err) {
 		/* Max tries exceeded */
 		port_release(port);
-		reply = failed(port->msg, strerror(err));
+		reply = btd_error_failed(port->msg, strerror(err));
 	} else {
 		port->fd = fd;
 		reply = g_dbus_create_reply(port->msg,
@@ -316,7 +316,7 @@ static void rfcomm_connect_cb(GIOChannel *chan, GError *conn_err,
 
 	if (conn_err) {
 		error("%s", conn_err->message);
-		reply = failed(port->msg, conn_err->message);
+		reply = btd_error_failed(port->msg, conn_err->message);
 		goto fail;
 	}
 
@@ -335,7 +335,7 @@ static void rfcomm_connect_cb(GIOChannel *chan, GError *conn_err,
 	if (port->id < 0) {
 		int err = errno;
 		error("ioctl(RFCOMMCREATEDEV): %s (%d)", strerror(err), err);
-		reply = failed(port->msg, strerror(err));
+		reply = btd_error_failed(port->msg, strerror(err));
 		g_io_channel_shutdown(chan, TRUE, NULL);
 		goto fail;
 	}
@@ -378,13 +378,13 @@ static void get_record_cb(sdp_list_t *recs, int err, gpointer user_data)
 	if (err < 0) {
 		error("Unable to get service record: %s (%d)", strerror(-err),
 			-err);
-		reply = failed(port->msg, strerror(-err));
+		reply = btd_error_failed(port->msg, strerror(-err));
 		goto failed;
 	}
 
 	if (!recs || !recs->data) {
 		error("No record found");
-		reply = failed(port->msg, "No record found");
+		reply = btd_error_failed(port->msg, "No record found");
 		goto failed;
 	}
 
@@ -392,7 +392,7 @@ static void get_record_cb(sdp_list_t *recs, int err, gpointer user_data)
 
 	if (sdp_get_access_protos(record, &protos) < 0) {
 		error("Unable to get access protos from port record");
-		reply = failed(port->msg, "Invalid channel");
+		reply = btd_error_failed(port->msg, "Invalid channel");
 		goto failed;
 	}
 
@@ -409,7 +409,7 @@ static void get_record_cb(sdp_list_t *recs, int err, gpointer user_data)
 				BT_IO_OPT_INVALID);
 	if (!port->io) {
 		error("%s", gerr->message);
-		reply = failed(port->msg, gerr->message);
+		reply = btd_error_failed(port->msg, gerr->message);
 		g_error_free(gerr);
 		goto failed;
 	}
@@ -505,13 +505,11 @@ static DBusMessage *port_connect(DBusConnection *conn,
 
 	err = connect_port(port);
 	if (err < 0) {
-		DBusMessage *reply;
-
 		error("%s", strerror(-err));
 		g_dbus_remove_watch(conn, port->listener_id);
 		port->listener_id = 0;
-		reply = failed(msg, strerror(-err));
-		return reply;
+
+		return btd_error_failed(msg, strerror(-err));
 	}
 
 	return NULL;
diff --git a/serial/proxy.c b/serial/proxy.c
index c779c4e..20aea7d 100644
--- a/serial/proxy.c
+++ b/serial/proxy.c
@@ -553,11 +553,8 @@ static DBusMessage *proxy_enable(DBusConnection *conn,
 	err = enable_proxy(prx);
 	if (err == -EALREADY)
 		return failed(msg, "Already enabled");
-	else if (err == -ENOMEM)
-		return failed(msg, "Unable to allocate new service record");
 	else if (err < 0)
-		return g_dbus_create_error(msg, ERROR_INTERFACE "Failed",
-				"Proxy enable failed (%s)", strerror(-err));
+		return btd_error_failed(msg, strerror(-err));
 
 	return dbus_message_new_method_return(msg);
 }
@@ -1051,8 +1048,7 @@ static DBusMessage *create_proxy(DBusConnection *conn,
 	else if (err == -EALREADY)
 		return btd_error_already_exists(msg);
 	else if (err < 0)
-		return g_dbus_create_error(msg, ERROR_INTERFACE "Failed",
-				"Proxy creation failed (%s)", strerror(-err));
+		return btd_error_failed(msg, strerror(-err));
 
 	proxy->owner = g_strdup(dbus_message_get_sender(msg));
 	proxy->watch = g_dbus_add_disconnect_watch(conn, proxy->owner,
-- 
1.7.3.2


^ permalink raw reply related

* [PATCH 08/10] audio: use btd_error_failed()
From: Gustavo F. Padovan @ 2010-12-13 21:33 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1292275987-13799-8-git-send-email-padovan@profusion.mobi>

---
 audio/control.c   |    6 ++----
 audio/device.c    |   14 +++++---------
 audio/gateway.c   |   11 +++++------
 audio/headset.c   |   18 +++++-------------
 audio/sink.c      |    9 +++------
 audio/source.c    |    9 +++------
 audio/transport.c |    7 +------
 7 files changed, 24 insertions(+), 50 deletions(-)

diff --git a/audio/control.c b/audio/control.c
index 98b6682..75c0b51 100644
--- a/audio/control.c
+++ b/audio/control.c
@@ -1021,8 +1021,7 @@ static DBusMessage *volume_up(DBusConnection *conn, DBusMessage *msg,
 
 	err = avctp_send_passthrough(control, VOL_UP_OP);
 	if (err < 0)
-		return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
-							"%s", strerror(-err));
+		return btd_error_failed(msg, strerror(-err));
 
 	return dbus_message_new_method_return(msg);
 }
@@ -1047,8 +1046,7 @@ static DBusMessage *volume_down(DBusConnection *conn, DBusMessage *msg,
 
 	err = avctp_send_passthrough(control, VOL_DOWN_OP);
 	if (err < 0)
-		return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
-							"%s", strerror(-err));
+		return btd_error_failed(msg, strerror(-err));
 
 	return dbus_message_new_method_return(msg);
 }
diff --git a/audio/device.c b/audio/device.c
index fe7aed4..e38e598 100644
--- a/audio/device.c
+++ b/audio/device.c
@@ -271,10 +271,9 @@ static void device_set_state(struct audio_device *dev, audio_state_t new_state)
 		if (new_state == AUDIO_STATE_CONNECTED)
 			reply = dbus_message_new_method_return(priv->conn_req);
 		else
-			reply = g_dbus_create_error(priv->conn_req,
-							ERROR_INTERFACE
-							".ConnectFailed",
-							"Connecting failed");
+			reply = btd_error_failed(priv->conn_req,
+							"Connect Failed");
+
 		dbus_message_unref(priv->conn_req);
 		priv->conn_req = NULL;
 		g_dbus_send_message(dev->conn, reply);
@@ -532,8 +531,7 @@ static DBusMessage *dev_connect(DBusConnection *conn, DBusMessage *msg,
 		struct avdtp *session = avdtp_get(&dev->src, &dev->dst);
 
 		if (!session)
-			return g_dbus_create_error(msg, ERROR_INTERFACE
-					".Failed",
+			return btd_error_failed(msg,
 					"Failed to get AVDTP session");
 
 		sink_setup_stream(dev->sink, session);
@@ -543,9 +541,7 @@ static DBusMessage *dev_connect(DBusConnection *conn, DBusMessage *msg,
 	/* The previous calls should cause a call to the state callback to
 	 * indicate AUDIO_STATE_CONNECTING */
 	if (priv->state != AUDIO_STATE_CONNECTING)
-		return g_dbus_create_error(msg, ERROR_INTERFACE
-				".ConnectFailed",
-				"Headset connect failed");
+		return btd_error_failed(msg, "Connect Failed");
 
 	priv->conn_req = dbus_message_ref(msg);
 
diff --git a/audio/gateway.c b/audio/gateway.c
index 05b9ff7..4d38be7 100644
--- a/audio/gateway.c
+++ b/audio/gateway.c
@@ -247,8 +247,7 @@ static void rfcomm_connect_cb(GIOChannel *chan, GError *err,
 	if (ret)
 		reply = dbus_message_new_method_return(gw->msg);
 	else
-		reply = g_dbus_create_error(gw->msg, ERROR_INTERFACE ".Failed",
-					"Can not pass file descriptor");
+		reply = btd_error_failed(gw->msg, "Can't pass file descriptor");
 
 	g_dbus_send_message(dev->conn, reply);
 
@@ -365,15 +364,15 @@ static DBusMessage *ag_connect(DBusConnection *conn, DBusMessage *msg,
 {
 	struct audio_device *au_dev = (struct audio_device *) data;
 	struct gateway *gw = au_dev->gateway;
+	int err;
 
 	if (!gw->agent)
 		return g_dbus_create_error(msg, ERROR_INTERFACE
 				".Failed", "Agent not assigned");
 
-	if (get_records(au_dev) < 0)
-		return g_dbus_create_error(msg, ERROR_INTERFACE
-					".ConnectAttemptFailed",
-					"Connect Attempt Failed");
+	err = get_records(au_dev);
+	if (err < 0)
+		return btd_error_failed(msg, strerror(-err));
 
 	gw->msg = dbus_message_ref(msg);
 
diff --git a/audio/headset.c b/audio/headset.c
index 18fd866..34b2b89 100644
--- a/audio/headset.c
+++ b/audio/headset.c
@@ -1709,13 +1709,8 @@ static DBusMessage *hs_connect(DBusConnection *conn, DBusMessage *msg,
 	device->auto_connect = FALSE;
 
 	err = rfcomm_connect(device, NULL, NULL, NULL);
-	if (err == -ECONNREFUSED)
-		return g_dbus_create_error(msg, ERROR_INTERFACE ".NotAllowed",
-						"Too many connected devices");
-	else if (err < 0)
-		return g_dbus_create_error(msg, ERROR_INTERFACE
-						".ConnectAttemptFailed",
-						"Connect Attempt Failed");
+	if (err < 0)
+		return btd_error_failed(msg, strerror(-err));
 
 	hs->auto_dc = FALSE;
 
@@ -1747,8 +1742,7 @@ static DBusMessage *hs_ring(DBusConnection *conn, DBusMessage *msg,
 	err = headset_send(hs, "\r\nRING\r\n");
 	if (err < 0) {
 		dbus_message_unref(reply);
-		return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
-						"%s", strerror(-err));
+		return btd_error_failed(msg, strerror(-err));
 	}
 
 	ring_timer_cb(NULL);
@@ -1815,8 +1809,7 @@ static DBusMessage *hs_play(DBusConnection *conn, DBusMessage *msg,
 
 	err = sco_connect(device, NULL, NULL, NULL);
 	if (err < 0)
-		return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
-						"%s", strerror(-err));
+		return btd_error_failed(msg, strerror(-err));
 
 	hs->pending->msg = dbus_message_ref(msg);
 
@@ -1900,8 +1893,7 @@ static DBusMessage *hs_set_gain(DBusConnection *conn,
 		err = headset_send(hs, "\r\n+VG%c=%u\r\n", type, gain);
 		if (err < 0) {
 			dbus_message_unref(reply);
-			return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
-						"%s", strerror(-err));
+			return btd_error_failed(msg, strerror(-err));
 		}
 	}
 
diff --git a/audio/sink.c b/audio/sink.c
index 176a4ed..5746c55 100644
--- a/audio/sink.c
+++ b/audio/sink.c
@@ -435,8 +435,7 @@ static DBusMessage *sink_connect(DBusConnection *conn,
 		sink->session = avdtp_get(&dev->src, &dev->dst);
 
 	if (!sink->session)
-		return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
-						"Unable to get a session");
+		return btd_error_failed(msg, "Unable to get a session");
 
 	if (sink->connect || sink->disconnect)
 		return btd_error_busy(msg);
@@ -445,8 +444,7 @@ static DBusMessage *sink_connect(DBusConnection *conn,
 		return btd_error_already_connected(msg);
 
 	if (!sink_setup_stream(sink, NULL))
-		return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
-						"Failed to create a stream");
+		return btd_error_failed(msg, "Failed to create a stream");
 
 	dev->auto_connect = FALSE;
 
@@ -485,8 +483,7 @@ static DBusMessage *sink_disconnect(DBusConnection *conn,
 
 	err = avdtp_close(sink->session, sink->stream, FALSE);
 	if (err < 0)
-		return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
-						"%s", strerror(-err));
+		return btd_error_failed(msg, strerror(-err));
 
 	pending = g_new0(struct pending_request, 1);
 	pending->conn = dbus_connection_ref(conn);
diff --git a/audio/source.c b/audio/source.c
index c106eaa..29ceb0f 100644
--- a/audio/source.c
+++ b/audio/source.c
@@ -386,8 +386,7 @@ static DBusMessage *source_connect(DBusConnection *conn,
 		source->session = avdtp_get(&dev->src, &dev->dst);
 
 	if (!source->session)
-		return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
-						"Unable to get a session");
+		return btd_error_failed(msg, "Unable to get a session");
 
 	if (source->connect || source->disconnect)
 		return btd_error_busy(msg);
@@ -396,8 +395,7 @@ static DBusMessage *source_connect(DBusConnection *conn,
 		return btd_error_already_connected(msg);
 
 	if (!source_setup_stream(source, NULL))
-		return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
-						"Failed to create a stream");
+		return btd_error_failed(msg, "Failed to create a stream");
 
 	dev->auto_connect = FALSE;
 
@@ -436,8 +434,7 @@ static DBusMessage *source_disconnect(DBusConnection *conn,
 
 	err = avdtp_close(source->session, source->stream, FALSE);
 	if (err < 0)
-		return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
-						"%s", strerror(-err));
+		return btd_error_failed(msg, strerror(-err));
 
 	pending = g_new0(struct pending_request, 1);
 	pending->conn = dbus_connection_ref(conn);
diff --git a/audio/transport.c b/audio/transport.c
index e2ee400..bdec157 100644
--- a/audio/transport.c
+++ b/audio/transport.c
@@ -93,11 +93,6 @@ struct media_transport {
 					DBusMessageIter *value);
 };
 
-static inline DBusMessage *error_failed(DBusMessage *msg, const char *desc)
-{
-	return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed", "%s", desc);
-}
-
 void media_transport_remove(struct media_transport *transport)
 {
 	char *path;
@@ -572,7 +567,7 @@ static DBusMessage *set_property(DBusConnection *conn, DBusMessage *msg,
 	if (err < 0) {
 		if (err == -EINVAL)
 			return btd_error_invalid_args(msg);
-		return error_failed(msg, strerror(-err));
+		return btd_error_failed(msg, strerror(-err));
 	}
 
 	return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
-- 
1.7.3.2


^ permalink raw reply related

* [PATCH 07/10] input: use btd_error_failed()
From: Gustavo F. Padovan @ 2010-12-13 21:33 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1292275987-13799-7-git-send-email-padovan@profusion.mobi>

---
 input/device.c |   31 ++++++++-----------------------
 1 files changed, 8 insertions(+), 23 deletions(-)

diff --git a/input/device.c b/input/device.c
index dee943b..0543fe6 100644
--- a/input/device.c
+++ b/input/device.c
@@ -315,14 +315,6 @@ failed:
 	return FALSE;
 }
 
-static inline DBusMessage *connection_attempt_failed(DBusMessage *msg,
-							const char *err)
-{
-	return g_dbus_create_error(msg,
-				ERROR_INTERFACE ".ConnectionAttemptFailed",
-				"%s", err ? err : "Connection attempt failed");
-}
-
 static void rfcomm_connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
 {
 	struct input_conn *iconn = user_data;
@@ -331,8 +323,7 @@ static void rfcomm_connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
 	DBusMessage *reply;
 
 	if (err) {
-		reply = connection_attempt_failed(iconn->pending_connect,
-								err->message);
+		reply = btd_error_failed(iconn->pending_connect, err->message);
 		goto failed;
 	}
 
@@ -345,7 +336,7 @@ static void rfcomm_connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
 	fake->uinput = uinput_create(idev->name);
 	if (fake->uinput < 0) {
 		g_io_channel_shutdown(chan, TRUE, NULL);
-		reply = connection_attempt_failed(iconn->pending_connect,
+		reply = btd_error_failed(iconn->pending_connect,
 							strerror(errno));
 		goto failed;
 	}
@@ -834,7 +825,7 @@ static void interrupt_connect_cb(GIOChannel *chan, GError *conn_err,
 
 failed:
 	error("%s", err_msg);
-	reply = connection_attempt_failed(iconn->pending_connect, err_msg);
+	reply = btd_error_failed(iconn->pending_connect, err_msg);
 	g_dbus_send_message(idev->conn, reply);
 
 	if (iconn->ctrl_io)
@@ -859,8 +850,8 @@ static void control_connect_cb(GIOChannel *chan, GError *conn_err,
 
 	if (conn_err) {
 		error("%s", conn_err->message);
-		reply = connection_attempt_failed(iconn->pending_connect,
-							conn_err->message);
+		reply = btd_error_failed(iconn->pending_connect,
+						conn_err->message);
 		goto failed;
 	}
 
@@ -874,7 +865,7 @@ static void control_connect_cb(GIOChannel *chan, GError *conn_err,
 				BT_IO_OPT_INVALID);
 	if (!io) {
 		error("%s", err->message);
-		reply = connection_attempt_failed(iconn->pending_connect,
+		reply = btd_error_failed(iconn->pending_connect,
 							err->message);
 		g_error_free(err);
 		g_io_channel_shutdown(chan, TRUE, NULL);
@@ -960,17 +951,11 @@ static DBusMessage *input_device_connect(DBusConnection *conn,
 	error("%s", err->message);
 	dbus_message_unref(iconn->pending_connect);
 	iconn->pending_connect = NULL;
-	reply = connection_attempt_failed(msg, err->message);
+	reply = btd_error_failed(msg, err->message);
 	g_error_free(err);
 	return reply;
 }
 
-static DBusMessage *create_errno_message(DBusMessage *msg, int err)
-{
-	return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
-							"%s", strerror(err));
-}
-
 static DBusMessage *input_device_disconnect(DBusConnection *conn,
 						DBusMessage *msg, void *data)
 {
@@ -979,7 +964,7 @@ static DBusMessage *input_device_disconnect(DBusConnection *conn,
 
 	err = disconnect(idev, 0);
 	if (err < 0)
-		return create_errno_message(msg, -err);
+		return btd_error_failed(msg, strerror(-err));
 
 	return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
 }
-- 
1.7.3.2


^ permalink raw reply related

* [PATCH 06/10] network: use btd_error_failed()
From: Gustavo F. Padovan @ 2010-12-13 21:33 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1292275987-13799-6-git-send-email-padovan@profusion.mobi>

---
 network/connection.c |   30 ++----------------------------
 network/server.c     |   13 +++----------
 2 files changed, 5 insertions(+), 38 deletions(-)

diff --git a/network/connection.c b/network/connection.c
index 89c38d8..09a4f3c 100644
--- a/network/connection.c
+++ b/network/connection.c
@@ -111,32 +111,6 @@ static struct network_conn *find_connection(GSList *list, uint16_t id)
 	return NULL;
 }
 
-static inline DBusMessage *not_supported(DBusMessage *msg)
-{
-	return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
-							"Not supported");
-}
-
-static inline DBusMessage *already_connected(DBusMessage *msg)
-{
-	return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
-						"Device already connected");
-}
-
-static inline DBusMessage *not_permited(DBusMessage *msg)
-{
-	return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
-						"Operation not permited");
-}
-
-static inline DBusMessage *connection_attempt_failed(DBusMessage *msg,
-							const char *err)
-{
-	return g_dbus_create_error(msg,
-				ERROR_INTERFACE ".ConnectionAttemptFailed",
-				"%s", err ? err : "Connection attempt failed");
-}
-
 static gboolean bnep_watchdog_cb(GIOChannel *chan, GIOCondition cond,
 				gpointer data)
 {
@@ -182,7 +156,7 @@ static void cancel_connection(struct network_conn *nc, const char *err_msg)
 	}
 
 	if (nc->msg && err_msg) {
-		reply = connection_attempt_failed(nc->msg, err_msg);
+		reply = btd_error_failed(nc->msg, err_msg);
 		g_dbus_send_message(connection, reply);
 	}
 
@@ -409,7 +383,7 @@ static DBusMessage *connection_connect(DBusConnection *conn,
 	if (!nc->io) {
 		DBusMessage *reply;
 		error("%s", err->message);
-		reply = connection_attempt_failed(msg, err->message);
+		reply = btd_error_failed(msg, err->message);
 		g_error_free(err);
 		return reply;
 	}
diff --git a/network/server.c b/network/server.c
index 60e1a81..7c63c3e 100644
--- a/network/server.c
+++ b/network/server.c
@@ -566,13 +566,6 @@ static uint32_t register_server_record(struct network_server *ns)
 	return record->handle;
 }
 
-
-static inline DBusMessage *failed(DBusMessage *msg, const char *description)
-{
-	return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
-							"%s", description);
-}
-
 static void server_disconnect(DBusConnection *conn, void *user_data)
 {
 	struct network_server *ns = user_data;
@@ -600,7 +593,7 @@ static DBusMessage *register_server(DBusConnection *conn,
 		return NULL;
 
 	if (g_strcmp0(uuid, "nap"))
-		return failed(msg, "Invalid UUID");
+		return btd_error_failed(msg, "Invalid UUID");
 
 	if (ns->record_id)
 		return btd_error_already_exists(msg);
@@ -611,7 +604,7 @@ static DBusMessage *register_server(DBusConnection *conn,
 
 	ns->record_id = register_server_record(ns);
 	if (!ns->record_id)
-		return failed(msg, "SDP record registration failed");
+		return btd_error_failed(msg, "SDP record registration failed");
 
 	g_free(ns->bridge);
 	ns->bridge = g_strdup(bridge);
@@ -635,7 +628,7 @@ static DBusMessage *unregister_server(DBusConnection *conn,
 		return NULL;
 
 	if (g_strcmp0(uuid, "nap"))
-		return failed(msg, "Invalid UUID");
+		return btd_error_failed(msg, "Invalid UUID");
 
 	reply = dbus_message_new_method_return(msg);
 	if (!reply)
-- 
1.7.3.2


^ permalink raw reply related

* [PATCH 05/10] attrib: use btd_error_failed()
From: Gustavo F. Padovan @ 2010-12-13 21:33 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1292275987-13799-5-git-send-email-padovan@profusion.mobi>

---
 attrib/client.c |   10 ++--------
 1 files changed, 2 insertions(+), 8 deletions(-)

diff --git a/attrib/client.c b/attrib/client.c
index 0805492..8e96af4 100644
--- a/attrib/client.c
+++ b/attrib/client.c
@@ -457,11 +457,8 @@ static DBusMessage *register_watcher(DBusConnection *conn,
 		return btd_error_invalid_args(msg);
 
 	if (l2cap_connect(prim->gatt, &gerr, TRUE) < 0) {
-		DBusMessage *reply;
-		reply = g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
-							"%s", gerr->message);
+		DBusMessage *reply = btd_error_failed(msg, gerr->message);
 		g_error_free(gerr);
-
 		return reply;
 	}
 
@@ -533,11 +530,8 @@ static DBusMessage *set_value(DBusConnection *conn, DBusMessage *msg,
 	dbus_message_iter_get_fixed_array(&sub, &value, &len);
 
 	if (l2cap_connect(gatt, &gerr, FALSE) < 0) {
-		DBusMessage *reply;
-		reply = g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
-							"%s", gerr->message);
+		DBusMessage *reply = btd_error_failed(msg, gerr->message);
 		g_error_free(gerr);
-
 		return reply;
 	}
 
-- 
1.7.3.2


^ permalink raw reply related

* [PATCH 04/10] plugins: use btd_error_failed()
From: Gustavo F. Padovan @ 2010-12-13 21:33 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1292275987-13799-4-git-send-email-padovan@profusion.mobi>

---
 plugins/service.c |   22 ++++------------------
 1 files changed, 4 insertions(+), 18 deletions(-)

diff --git a/plugins/service.c b/plugins/service.c
index a442d53..f44aa92 100644
--- a/plugins/service.c
+++ b/plugins/service.c
@@ -337,17 +337,6 @@ static void exit_callback(DBusConnection *conn, void *user_data)
 	g_free(user_record);
 }
 
-static inline DBusMessage *failed(DBusMessage *msg)
-{
-	return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed", "Failed");
-}
-
-static inline DBusMessage *failed_strerror(DBusMessage *msg, int err)
-{
-	return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
-							"%s", strerror(err));
-}
-
 static int add_xml_record(DBusConnection *conn, const char *sender,
 			struct service_adapter *serv_adapter,
 			const char *record, dbus_uint32_t *handle)
@@ -412,9 +401,7 @@ static DBusMessage *update_record(DBusConnection *conn, DBusMessage *msg,
 	if (err < 0) {
 		sdp_record_free(sdp_record);
 		error("Failed to update the service record");
-		return g_dbus_create_error(msg,
-				ERROR_INTERFACE ".Failed",
-				"%s", strerror(EIO));
+		return btd_error_failed(msg, strerror(-err));
 	}
 
 	return dbus_message_new_method_return(msg);
@@ -449,9 +436,8 @@ static DBusMessage *update_xml_record(DBusConnection *conn,
 	if (!sdp_record) {
 		error("Parsing of XML service record failed");
 		sdp_record_free(sdp_record);
-		return g_dbus_create_error(msg,
-				ERROR_INTERFACE ".Failed",
-				"%s", strerror(EIO));
+		return btd_error_failed(msg,
+					"Parsing of XML service record failed");
 	}
 
 	return update_record(conn, msg, serv_adapter, handle, sdp_record);
@@ -494,7 +480,7 @@ static DBusMessage *add_service_record(DBusConnection *conn,
 	sender = dbus_message_get_sender(msg);
 	err = add_xml_record(conn, sender, serv_adapter, record, &handle);
 	if (err < 0)
-		return failed_strerror(msg, err);
+		return btd_error_failed(msg, strerror(-err));
 
 	reply = dbus_message_new_method_return(msg);
 	if (!reply)
-- 
1.7.3.2


^ permalink raw reply related


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