* [PATCH 5/5] Remove unneeded variable
From: Claudio Takahasi @ 2010-12-15 19:54 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Claudio Takahasi
In-Reply-To: <1292442852-26457-1-git-send-email-claudio.takahasi@openbossa.org>
---
src/glib-helper.c | 5 ++---
1 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/src/glib-helper.c b/src/glib-helper.c
index edc46d8..8cf29ae 100644
--- a/src/glib-helper.c
+++ b/src/glib-helper.c
@@ -525,7 +525,6 @@ int bt_discover_primary(const bdaddr_t *src, const bdaddr_t *dst, int psm,
{
struct gattrib_context *ctxt;
GIOChannel *io;
- GError *gerr = NULL;
ctxt = g_try_new0(struct gattrib_context, 1);
if (ctxt == NULL)
@@ -538,14 +537,14 @@ int bt_discover_primary(const bdaddr_t *src, const bdaddr_t *dst, int psm,
ctxt->destroy = destroy;
if (psm < 0)
- io = bt_io_connect(BT_IO_L2CAP, connect_cb, ctxt, NULL, &gerr,
+ io = bt_io_connect(BT_IO_L2CAP, connect_cb, ctxt, NULL, NULL,
BT_IO_OPT_SOURCE_BDADDR, src,
BT_IO_OPT_DEST_BDADDR, dst,
BT_IO_OPT_CID, GATT_CID,
BT_IO_OPT_SEC_LEVEL, sec_level,
BT_IO_OPT_INVALID);
else
- io = bt_io_connect(BT_IO_L2CAP, connect_cb, ctxt, NULL, &gerr,
+ io = bt_io_connect(BT_IO_L2CAP, connect_cb, ctxt, NULL, NULL,
BT_IO_OPT_SOURCE_BDADDR, src,
BT_IO_OPT_DEST_BDADDR, dst,
BT_IO_OPT_PSM, psm,
--
1.7.3.3
^ permalink raw reply related
* [PATCH 4/5] Fix missing reply when create device is cancelled
From: Claudio Takahasi @ 2010-12-15 19:54 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Claudio Takahasi
In-Reply-To: <1292442852-26457-1-git-send-email-claudio.takahasi@openbossa.org>
When CancelDeviceCreation is called or when the device is removed for
any reason, the reply for the pending CreateDevice is not sent.
---
src/device.c | 8 ++++++--
1 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/src/device.c b/src/device.c
index cf3b146..a881c4c 100644
--- a/src/device.c
+++ b/src/device.c
@@ -730,8 +730,10 @@ void device_request_disconnect(struct btd_device *device, DBusMessage *msg)
if (device->bonding)
bonding_request_cancel(device->bonding);
- if (device->browse)
+ if (device->browse) {
+ discover_services_reply(device->browse, -ECANCELED, NULL);
browse_request_cancel(device->browse);
+ }
if (msg)
device->disconnects = g_slist_append(device->disconnects,
@@ -1043,8 +1045,10 @@ void device_remove(struct btd_device *device, gboolean remove_stored)
if (device->bonding)
device_cancel_bonding(device, HCI_OE_USER_ENDED_CONNECTION);
- if (device->browse)
+ if (device->browse) {
+ discover_services_reply(device->browse, -ECANCELED, NULL);
browse_request_cancel(device->browse);
+ }
if (device->handle)
do_disconnect(device);
--
1.7.3.3
^ permalink raw reply related
* [PATCH 3/5] Return an error if adapter_create_device fails
From: Claudio Takahasi @ 2010-12-15 19:54 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Claudio Takahasi
In-Reply-To: <1292442852-26457-1-git-send-email-claudio.takahasi@openbossa.org>
This function can fail if the device object is already registered or if
the system doesn't have enough memory. Issue detected due wrong device
object reference counting that doesn't unregister the D-Bus object path
when the device is removed.
---
src/adapter.c | 6 ++++--
1 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/src/adapter.c b/src/adapter.c
index c1fddce..f71d063 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -1595,7 +1595,8 @@ static DBusMessage *create_device(DBusConnection *conn,
device = adapter_create_device(conn, adapter, address, type);
if (!device)
- return NULL;
+ return btd_error_failed(msg,
+ "Unable to create a new device object");
if (type == DEVICE_TYPE_LE && !event_is_connectable(dev->evt_type)) {
/* Device is not connectable */
@@ -1693,7 +1694,8 @@ static DBusMessage *create_paired_device(DBusConnection *conn,
device = adapter_create_device(conn, adapter, address, type);
if (!device)
- return NULL;
+ return btd_error_failed(msg,
+ "Unable to create a new device object");
} else
type = device_get_type(device);
--
1.7.3.3
^ permalink raw reply related
* [PATCH 2/5] Change CreatePairedDevice to support LE devices
From: Claudio Takahasi @ 2010-12-15 19:54 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Sheldon Demario
In-Reply-To: <1292442852-26457-1-git-send-email-claudio.takahasi@openbossa.org>
From: Sheldon Demario <sheldon.demario@openbossa.org>
CreatePairedDevice implements now the same behaviour of CreateDevice,
triggering Discover All Primary Services when needed. SMP negotiation
starts when the link is established. LE capable kernel is required to
test this method properly.
Limitation: For dual mode devices, Discover All Primary Services is not
being executed after SDP search if GATT record is found.
---
src/adapter.c | 46 ++++++++++++++++++++++++---
src/device.c | 89 +++++++++++++++++++++++++++-------------------------
src/device.h | 7 +++-
src/glib-helper.c | 5 ++-
src/glib-helper.h | 3 ++
5 files changed, 98 insertions(+), 52 deletions(-)
diff --git a/src/adapter.c b/src/adapter.c
index 2ff59a0..c1fddce 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -1611,7 +1611,11 @@ static DBusMessage *create_device(DBusConnection *conn,
return reply;
}
- err = device_browse(device, conn, msg, NULL, FALSE);
+ if (type != DEVICE_TYPE_LE)
+ err = device_browse_sdp(device, conn, msg, NULL, FALSE);
+ else
+ err = device_browse_primary(device, conn, msg, BT_IO_SEC_LOW);
+
if (err < 0) {
adapter_remove_device(conn, adapter, device, TRUE);
return btd_error_failed(msg, strerror(-err));
@@ -1642,6 +1646,8 @@ static DBusMessage *create_paired_device(DBusConnection *conn,
struct btd_device *device;
const gchar *address, *agent_path, *capability, *sender;
uint8_t cap;
+ device_type_t type;
+ int err;
if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &address,
DBUS_TYPE_OBJECT_PATH, &agent_path,
@@ -1666,12 +1672,40 @@ static DBusMessage *create_paired_device(DBusConnection *conn,
if (cap == IO_CAPABILITY_INVALID)
return btd_error_invalid_args(msg);
- device = adapter_get_device(conn, adapter, address);
- if (!device)
- return btd_error_failed(msg,
- "Unable to create a new device object");
+ device = adapter_find_device(adapter, address);
+ if (!device) {
+ struct remote_dev_info *dev, match;
+
+ memset(&match, 0, sizeof(struct remote_dev_info));
+ str2ba(address, &match.bdaddr);
+ match.name_status = NAME_ANY;
+
+ dev = adapter_search_found_devices(adapter, &match);
+ if (dev && dev->flags)
+ type = flags2type(dev->flags);
+ else
+ type = DEVICE_TYPE_BREDR;
+
+ if (type == DEVICE_TYPE_LE &&
+ !event_is_connectable(dev->evt_type))
+ return btd_error_failed(msg,
+ "Device is not connectable");
+
+ device = adapter_create_device(conn, adapter, address, type);
+ if (!device)
+ return NULL;
+ } else
+ type = device_get_type(device);
+
+ if (type != DEVICE_TYPE_LE)
+ return device_create_bonding(device, conn, msg,
+ agent_path, cap);
- return device_create_bonding(device, conn, msg, agent_path, cap);
+ err = device_browse_primary(device, conn, msg, BT_IO_SEC_HIGH);
+ if (err < 0)
+ return btd_error_failed(msg, strerror(-err));
+
+ return NULL;
}
static gint device_path_cmp(struct btd_device *device, const gchar *path)
diff --git a/src/device.c b/src/device.c
index d20a6d4..cf3b146 100644
--- a/src/device.c
+++ b/src/device.c
@@ -586,7 +586,7 @@ static DBusMessage *discover_services(DBusConnection *conn,
return btd_error_invalid_args(msg);
if (strlen(pattern) == 0) {
- err = device_browse(device, conn, msg, NULL, FALSE);
+ err = device_browse_sdp(device, conn, msg, NULL, FALSE);
if (err < 0)
goto fail;
} else {
@@ -597,7 +597,7 @@ static DBusMessage *discover_services(DBusConnection *conn,
sdp_uuid128_to_uuid(&uuid);
- err = device_browse(device, conn, msg, &uuid, FALSE);
+ err = device_browse_sdp(device, conn, msg, &uuid, FALSE);
if (err < 0)
goto fail;
}
@@ -988,6 +988,11 @@ void device_get_name(struct btd_device *device, char *name, size_t len)
strncpy(name, device->name, len);
}
+device_type_t device_get_type(struct btd_device *device)
+{
+ return device->type;
+}
+
void device_remove_bonding(struct btd_device *device)
{
char filename[PATH_MAX + 1];
@@ -1540,41 +1545,62 @@ done:
browse_request_free(req);
}
-static struct browse_req *browse_primary(struct btd_device *device, int *err)
+int device_browse_primary(struct btd_device *device, DBusConnection *conn,
+ DBusMessage *msg, BtIOSecLevel sec_level)
{
struct btd_adapter *adapter = device->adapter;
struct browse_req *req;
bdaddr_t src;
- int ret;
+ int err;
+
+ if (device->browse)
+ return -EBUSY;
req = g_new0(struct browse_req, 1);
req->device = btd_device_ref(device);
adapter_get_address(adapter, &src);
- ret = bt_discover_primary(&src, &device->bdaddr, -1, primary_cb, req,
- NULL);
-
- if (ret < 0) {
+ err = bt_discover_primary(&src, &device->bdaddr, -1, primary_cb, req,
+ sec_level, NULL);
+ if (err < 0) {
browse_request_free(req);
- if (err)
- *err = ret;
+ return err;
+ }
- return NULL;
+ if (conn == NULL)
+ conn = get_dbus_connection();
+
+ req->conn = dbus_connection_ref(conn);
+ device->browse = req;
+
+ if (msg) {
+ const char *sender = dbus_message_get_sender(msg);
+
+ req->msg = dbus_message_ref(msg);
+ /* Track the request owner to cancel it
+ * automatically if the owner exits */
+ req->listener_id = g_dbus_add_disconnect_watch(conn,
+ sender,
+ discover_services_req_exit,
+ req, NULL);
}
- return req;
+ return err;
}
-static struct browse_req *browse_sdp(struct btd_device *device, uuid_t *search,
- gboolean reverse, int *err)
+int device_browse_sdp(struct btd_device *device, DBusConnection *conn,
+ DBusMessage *msg, uuid_t *search, gboolean reverse)
{
struct btd_adapter *adapter = device->adapter;
struct browse_req *req;
bt_callback_t cb;
bdaddr_t src;
uuid_t uuid;
- int ret;
+ int err;
+
+ if (device->browse)
+ return -EBUSY;
adapter_get_address(adapter, &src);
@@ -1589,34 +1615,11 @@ static struct browse_req *browse_sdp(struct btd_device *device, uuid_t *search,
cb = browse_cb;
}
- ret = bt_search_service(&src, &device->bdaddr, &uuid, cb, req, NULL);
- if (ret < 0) {
+ err = bt_search_service(&src, &device->bdaddr, &uuid, cb, req, NULL);
+ if (err < 0) {
browse_request_free(req);
- if (err)
- *err = ret;
-
- return NULL;
- }
-
- return req;
-}
-
-int device_browse(struct btd_device *device, DBusConnection *conn,
- DBusMessage *msg, uuid_t *search, gboolean reverse)
-{
- struct browse_req *req;
- int err = 0;
-
- if (device->browse)
- return -EBUSY;
-
- if (device->type == DEVICE_TYPE_LE)
- req = browse_primary(device, &err);
- else
- req = browse_sdp(device, search, reverse, &err);
-
- if (req == NULL)
return err;
+ }
if (conn == NULL)
conn = get_dbus_connection();
@@ -1719,7 +1722,7 @@ static gboolean start_discovery(gpointer user_data)
{
struct btd_device *device = user_data;
- device_browse(device, NULL, NULL, NULL, TRUE);
+ device_browse_sdp(device, NULL, NULL, NULL, TRUE);
device->discov_timer = 0;
@@ -2051,7 +2054,7 @@ void device_bonding_complete(struct btd_device *device, uint8_t status)
device->discov_timer = 0;
}
- device_browse(device, bonding->conn, bonding->msg,
+ device_browse_sdp(device, bonding->conn, bonding->msg,
NULL, FALSE);
bonding_request_free(bonding);
diff --git a/src/device.h b/src/device.h
index 784e931..cafa529 100644
--- a/src/device.h
+++ b/src/device.h
@@ -24,6 +24,8 @@
#define DEVICE_INTERFACE "org.bluez.Device"
+#include "btio.h"
+
struct btd_device;
typedef enum {
@@ -46,9 +48,12 @@ struct btd_device *device_create(DBusConnection *conn,
const gchar *address, device_type_t type);
void device_set_name(struct btd_device *device, const char *name);
void device_get_name(struct btd_device *device, char *name, size_t len);
+device_type_t device_get_type(struct btd_device *device);
void device_remove(struct btd_device *device, gboolean remove_stored);
gint device_address_cmp(struct btd_device *device, const gchar *address);
-int device_browse(struct btd_device *device, DBusConnection *conn,
+int device_browse_primary(struct btd_device *device, DBusConnection *conn,
+ DBusMessage *msg, BtIOSecLevel sec_level);
+int device_browse_sdp(struct btd_device *device, DBusConnection *conn,
DBusMessage *msg, uuid_t *search, gboolean reverse);
void device_probe_drivers(struct btd_device *device, GSList *profiles);
const sdp_record_t *btd_device_get_record(struct btd_device *device,
diff --git a/src/glib-helper.c b/src/glib-helper.c
index 6505249..edc46d8 100644
--- a/src/glib-helper.c
+++ b/src/glib-helper.c
@@ -520,6 +520,7 @@ static void connect_cb(GIOChannel *io, GError *gerr, gpointer user_data)
int bt_discover_primary(const bdaddr_t *src, const bdaddr_t *dst, int psm,
bt_primary_t cb, void *user_data,
+ BtIOSecLevel sec_level,
bt_destroy_t destroy)
{
struct gattrib_context *ctxt;
@@ -541,14 +542,14 @@ int bt_discover_primary(const bdaddr_t *src, const bdaddr_t *dst, int psm,
BT_IO_OPT_SOURCE_BDADDR, src,
BT_IO_OPT_DEST_BDADDR, dst,
BT_IO_OPT_CID, GATT_CID,
- BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
+ BT_IO_OPT_SEC_LEVEL, sec_level,
BT_IO_OPT_INVALID);
else
io = bt_io_connect(BT_IO_L2CAP, connect_cb, ctxt, NULL, &gerr,
BT_IO_OPT_SOURCE_BDADDR, src,
BT_IO_OPT_DEST_BDADDR, dst,
BT_IO_OPT_PSM, psm,
- BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
+ BT_IO_OPT_SEC_LEVEL, sec_level,
BT_IO_OPT_INVALID);
if (io == NULL) {
diff --git a/src/glib-helper.h b/src/glib-helper.h
index 5bb20a6..a16de6c 100644
--- a/src/glib-helper.h
+++ b/src/glib-helper.h
@@ -21,6 +21,8 @@
*
*/
+#include "btio.h"
+
typedef void (*bt_callback_t) (sdp_list_t *recs, int err, gpointer user_data);
typedef void (*bt_primary_t) (GSList *l, int err, gpointer user_data);
typedef void (*bt_destroy_t) (gpointer user_data);
@@ -35,6 +37,7 @@ int bt_cancel_discovery(const bdaddr_t *src, const bdaddr_t *dst);
int bt_discover_primary(const bdaddr_t *src, const bdaddr_t *dst, int psm,
bt_primary_t cb, void *user_data,
+ BtIOSecLevel sec_level,
bt_destroy_t destroy);
gchar *bt_uuid2string(uuid_t *uuid);
--
1.7.3.3
^ permalink raw reply related
* [PATCH 1/5] Implement cancel primary discovery session
From: Claudio Takahasi @ 2010-12-15 19:54 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Claudio Takahasi
Extend bt_cancel_discovery function to cancel an ongoing Discover
All Primary Services procedure.
---
src/device.c | 11 +++----
src/glib-helper.c | 73 ++++++++++++++++++++++++++++++++++++++++++-----------
2 files changed, 63 insertions(+), 21 deletions(-)
diff --git a/src/device.c b/src/device.c
index cec2153..d20a6d4 100644
--- a/src/device.c
+++ b/src/device.c
@@ -186,8 +186,7 @@ static void browse_request_cancel(struct browse_req *req)
adapter_get_address(adapter, &src);
- if (device->type != DEVICE_TYPE_LE)
- bt_cancel_discovery(&src, &device->bdaddr);
+ bt_cancel_discovery(&src, &device->bdaddr);
device->browse = NULL;
browse_request_free(req);
@@ -1530,11 +1529,11 @@ static void primary_cb(GSList *services, int err, gpointer user_data)
goto done;
}
- services_changed(req->device);
- device_set_temporary(req->device, FALSE);
- device_probe_drivers(req->device, services);
+ services_changed(device);
+ device_set_temporary(device, FALSE);
+ device_probe_drivers(device, services);
- create_device_reply(req->device, req);
+ create_device_reply(device, req);
done:
device->browse = NULL;
diff --git a/src/glib-helper.c b/src/glib-helper.c
index 8181f4d..6505249 100644
--- a/src/glib-helper.c
+++ b/src/glib-helper.c
@@ -51,12 +51,15 @@ struct gattrib_context {
bdaddr_t src;
bdaddr_t dst;
GAttrib *attrib;
+ GIOChannel *io;
bt_primary_t cb;
bt_destroy_t destroy;
gpointer user_data;
GSList *uuids;
};
+static GSList *gattrib_list = NULL;
+
struct cached_sdp_session {
bdaddr_t src;
bdaddr_t dst;
@@ -68,12 +71,18 @@ static GSList *cached_sdp_sessions = NULL;
static void gattrib_context_free(struct gattrib_context *ctxt)
{
+ gattrib_list = g_slist_remove(gattrib_list, ctxt);
if (ctxt->destroy)
ctxt->destroy(ctxt->user_data);
g_slist_foreach(ctxt->uuids, (GFunc) g_free, NULL);
g_slist_free(ctxt->uuids);
g_attrib_unref(ctxt->attrib);
+ if (ctxt->io) {
+ g_io_channel_unref(ctxt->io);
+ g_io_channel_shutdown(ctxt->io, FALSE, NULL);
+ }
+
g_free(ctxt);
}
@@ -138,7 +147,6 @@ struct search_context {
bdaddr_t dst;
sdp_session_t *session;
bt_callback_t cb;
- bt_primary_t prim_cb;
bt_destroy_t destroy;
gpointer user_data;
uuid_t uuid;
@@ -373,21 +381,16 @@ static gint find_by_bdaddr(gconstpointer data, gconstpointer user_data)
bacmp(&ctxt->src, &search->src));
}
-int bt_cancel_discovery(const bdaddr_t *src, const bdaddr_t *dst)
+static gint gattrib_find_by_bdaddr(gconstpointer data, gconstpointer user_data)
{
- struct search_context search, *ctxt;
- GSList *match;
+ const struct gattrib_context *ctxt = data, *search = user_data;
- memset(&search, 0, sizeof(search));
- bacpy(&search.src, src);
- bacpy(&search.dst, dst);
-
- /* Ongoing SDP Discovery */
- match = g_slist_find_custom(context_list, &search, find_by_bdaddr);
- if (!match)
- return -ENODATA;
+ return (bacmp(&ctxt->dst, &search->dst) &&
+ bacmp(&ctxt->src, &search->src));
+}
- ctxt = match->data;
+static int cancel_sdp(struct search_context *ctxt)
+{
if (!ctxt->session)
return -ENOTCONN;
@@ -398,9 +401,48 @@ int bt_cancel_discovery(const bdaddr_t *src, const bdaddr_t *dst)
sdp_close(ctxt->session);
search_context_cleanup(ctxt);
+
+ return 0;
+}
+
+static int cancel_gattrib(struct gattrib_context *ctxt)
+{
+ if (ctxt->attrib)
+ g_attrib_cancel_all(ctxt->attrib);
+
+ gattrib_context_free(ctxt);
+
return 0;
}
+int bt_cancel_discovery(const bdaddr_t *src, const bdaddr_t *dst)
+{
+ struct search_context sdp_ctxt;
+ struct gattrib_context gatt_ctxt;
+ GSList *match;
+
+ memset(&sdp_ctxt, 0, sizeof(sdp_ctxt));
+ bacpy(&sdp_ctxt.src, src);
+ bacpy(&sdp_ctxt.dst, dst);
+
+ /* Ongoing SDP Discovery */
+ match = g_slist_find_custom(context_list, &sdp_ctxt, find_by_bdaddr);
+ if (match)
+ return cancel_sdp(match->data);
+
+ memset(&gatt_ctxt, 0, sizeof(gatt_ctxt));
+ bacpy(&gatt_ctxt.src, src);
+ bacpy(&gatt_ctxt.dst, dst);
+
+ /* Ongoing Discover All Primary Services */
+ match = g_slist_find_custom(gattrib_list, &gatt_ctxt,
+ gattrib_find_by_bdaddr);
+ if (match == NULL)
+ return -ENOTCONN;
+
+ return cancel_gattrib(match->data);
+}
+
static void primary_cb(guint8 status, const guint8 *pdu, guint16 plen,
gpointer user_data)
{
@@ -471,6 +513,7 @@ static void connect_cb(GIOChannel *io, GError *gerr, gpointer user_data)
return;
}
+ ctxt->attrib = g_attrib_new(io);
gatt_discover_primary(ctxt->attrib, 0x0001, 0xffff, NULL, primary_cb,
ctxt);
}
@@ -513,9 +556,9 @@ int bt_discover_primary(const bdaddr_t *src, const bdaddr_t *dst, int psm,
return -EIO;
}
- ctxt->attrib = g_attrib_new(io);
+ ctxt->io = io;
- g_io_channel_unref(io);
+ gattrib_list = g_slist_append(gattrib_list, ctxt);
return 0;
}
--
1.7.3.3
^ permalink raw reply related
* Re: [PATCH] Fix crash while reading from mapped file
From: Anderson Lizardo @ 2010-12-15 18:19 UTC (permalink / raw)
To: Lukasz Pawlik; +Cc: Bastien Nocera, Johan Hedberg, linux-bluetooth
In-Reply-To: <AANLkTimMOeuyUj5CRMsm7QpoumgHRMmOsby2E6GoSHrd@mail.gmail.com>
On Tue, Dec 14, 2010 at 2:20 PM, Lukasz Pawlik <lucas.pawlik@gmail.com> wrote:
> 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.
What about using g_strstr_len() instead of strpbrk() on the original
code? See http://library.gnome.org/devel/glib/unstable/glib-String-Utility-Functions.html#g-strstr-len
Regards,
--
Anderson Lizardo
OpenBossa Labs - INdT
Manaus - Brazil
^ permalink raw reply
* [PATCH v2] Bluetooth: Fix __hci_request synchronization for hci_open_dev
From: johan.hedberg @ 2010-12-15 17:33 UTC (permalink / raw)
To: linux-bluetooth
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 adding a new hdev->last_init_cmd variable
and making use of the HCI_INIT flag which is set during the
initialization procedure. The hci_req_complete function will no longer
do anything when this flag is set and the completed command wasn't the
last_init_cmd one.
Signed-off-by: Johan Hedberg <johan.hedberg@nokia.com>
---
v2: (based on feedback from Gustavo Padovan) hci_event.c and hci_core.c
are now less dependent on each other regarding this issue. Now the
hci_init_complete call doesn't need to be moved to a new location in
hci_event.c if the sequence of initialization HCI commands changes in
hci_core.c.
include/net/bluetooth/hci_core.h | 4 +++-
net/bluetooth/hci_core.c | 8 ++++++--
net/bluetooth/hci_event.c | 33 +++++++++++++++++++++++----------
3 files changed, 32 insertions(+), 13 deletions(-)
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 3786ee8..23ca4b1 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -134,6 +134,8 @@ struct hci_dev {
struct hci_conn_hash conn_hash;
struct list_head blacklist;
+ int last_init_cmd;
+
struct hci_dev_stats stat;
struct sk_buff_head driver_init;
@@ -693,6 +695,6 @@ struct hci_sec_filter {
#define hci_req_lock(d) mutex_lock(&d->req_lock)
#define hci_req_unlock(d) mutex_unlock(&d->req_lock)
-void hci_req_complete(struct hci_dev *hdev, int result);
+void hci_req_complete(struct hci_dev *hdev, int cmd, int result);
#endif /* __HCI_CORE_H */
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 6374054..e37b839 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -91,9 +91,12 @@ static void hci_notify(struct hci_dev *hdev, int event)
/* ---- HCI requests ---- */
-void hci_req_complete(struct hci_dev *hdev, int result)
+void hci_req_complete(struct hci_dev *hdev, int cmd, int result)
{
- BT_DBG("%s result 0x%2.2x", hdev->name, result);
+ BT_DBG("%s command %d result 0x%2.2x", hdev->name, cmd, result);
+
+ if (test_bit(HCI_INIT, &hdev->flags) && cmd != hdev->last_init_cmd)
+ return;
if (hdev->req_status == HCI_REQ_PEND) {
hdev->req_result = result;
@@ -252,6 +255,7 @@ static void hci_init_req(struct hci_dev *hdev, unsigned long opt)
/* Connection accept timeout ~20 secs */
param = cpu_to_le16(0x7d00);
hci_send_cmd(hdev, HCI_OP_WRITE_CA_TIMEOUT, 2, ¶m);
+ hdev->last_init_cmd = HCI_OP_WRITE_CA_TIMEOUT;
}
static void hci_scan_req(struct hci_dev *hdev, unsigned long opt)
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 8923b36..3810017 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -58,7 +58,7 @@ static void hci_cc_inquiry_cancel(struct hci_dev *hdev, struct sk_buff *skb)
clear_bit(HCI_INQUIRY, &hdev->flags);
- hci_req_complete(hdev, status);
+ hci_req_complete(hdev, HCI_OP_INQUIRY_CANCEL, status);
hci_conn_check_pending(hdev);
}
@@ -174,7 +174,7 @@ static void hci_cc_write_def_link_policy(struct hci_dev *hdev, struct sk_buff *s
if (!status)
hdev->link_policy = get_unaligned_le16(sent);
- hci_req_complete(hdev, status);
+ hci_req_complete(hdev, HCI_OP_WRITE_DEF_LINK_POLICY, status);
}
static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb)
@@ -183,7 +183,7 @@ static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb)
BT_DBG("%s status 0x%x", hdev->name, status);
- hci_req_complete(hdev, status);
+ hci_req_complete(hdev, HCI_OP_RESET, status);
}
static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb)
@@ -235,7 +235,7 @@ static void hci_cc_write_auth_enable(struct hci_dev *hdev, struct sk_buff *skb)
clear_bit(HCI_AUTH, &hdev->flags);
}
- hci_req_complete(hdev, status);
+ hci_req_complete(hdev, HCI_OP_WRITE_AUTH_ENABLE, status);
}
static void hci_cc_write_encrypt_mode(struct hci_dev *hdev, struct sk_buff *skb)
@@ -258,7 +258,7 @@ static void hci_cc_write_encrypt_mode(struct hci_dev *hdev, struct sk_buff *skb)
clear_bit(HCI_ENCRYPT, &hdev->flags);
}
- hci_req_complete(hdev, status);
+ hci_req_complete(hdev, HCI_OP_WRITE_ENCRYPT_MODE, status);
}
static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb)
@@ -285,7 +285,7 @@ static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb)
set_bit(HCI_PSCAN, &hdev->flags);
}
- hci_req_complete(hdev, status);
+ hci_req_complete(hdev, HCI_OP_WRITE_SCAN_ENABLE, status);
}
static void hci_cc_read_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
@@ -383,7 +383,7 @@ static void hci_cc_host_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
BT_DBG("%s status 0x%x", hdev->name, status);
- hci_req_complete(hdev, status);
+ hci_req_complete(hdev, HCI_OP_HOST_BUFFER_SIZE, status);
}
static void hci_cc_read_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb)
@@ -536,7 +536,16 @@ static void hci_cc_read_bd_addr(struct hci_dev *hdev, struct sk_buff *skb)
if (!rp->status)
bacpy(&hdev->bdaddr, &rp->bdaddr);
- hci_req_complete(hdev, rp->status);
+ hci_req_complete(hdev, HCI_OP_READ_BD_ADDR, 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);
+
+ hci_req_complete(hdev, HCI_OP_WRITE_CA_TIMEOUT, status);
}
static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
@@ -544,7 +553,7 @@ static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
BT_DBG("%s status 0x%x", hdev->name, status);
if (status) {
- hci_req_complete(hdev, status);
+ hci_req_complete(hdev, HCI_OP_INQUIRY, status);
hci_conn_check_pending(hdev);
} else
@@ -871,7 +880,7 @@ static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff
clear_bit(HCI_INQUIRY, &hdev->flags);
- hci_req_complete(hdev, status);
+ hci_req_complete(hdev, HCI_OP_INQUIRY, status);
hci_conn_check_pending(hdev);
}
@@ -1379,6 +1388,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
* Re: [RFC] Bluetooth: Use non-flushable pb flag by default for ACL data on capable chipsets.
From: Mat Martineau @ 2010-12-15 16:35 UTC (permalink / raw)
To: Gustavo F. Padovan; +Cc: Emeltchenko Andrei, linux-bluetooth
In-Reply-To: <20101214192223.GD18509@vigoh>
On Tue, 14 Dec 2010, Gustavo F. Padovan wrote:
> 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).
This is a great feature to add, not only for A2DP. Both ERTM and
streaming mode only really make sense on unreliable links.
>> 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;
Does it make sense to check the HCI device for flush capability here?
If the HCI device is not capable, this option should remain false.
This would also let the application use getsockopt() to find out if
the link is really flushable or not.
>
> You are not using this flushable value anywhere. Something is wrong here.
I agree - like Gustavo mentioned above, l2cap_do_send() needs to be
checking l2cap_pi(sk)->flushable and setting the flags in
hci_send_acl() appropriately.
There is one more thing missing: Even though there is an L2CAP socket
option to set flush_to, and the flush_to is passed around during L2CAP
configuration, there is no use of the "Write Automatic Flush Timeout"
HCI command to tell the baseband what the flush timeout is! Since the
flush timeout is shared across all connections on the ACL, how should
BlueZ handle the case where different flush timeouts are set on
connections that share the same ACL? (My guess is that either the
longest or shortest timeout should be used, but there are good
arguments either way)
--
Mat Martineau
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum
^ permalink raw reply
* [PATCH] Add AVDTP SRC stream send buffer size verification
From: Dmitriy Paliy @ 2010-12-15 9:48 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Dmitriy Paliy
In-Reply-To: <1292406533-18574-1-git-send-email-dmitriy.paliy@nokia.com>
Functions get_send_buffer_size and set_send_buffer_size are added to
avdpt.c.
get_send_buffer_size returns size of send buffer for a given socket
on success or error code on failure. set_send_buffer_size sets size
of send buffer for a given socket, and returns 0 on success or error
code on failure.
Size of send buffer for L2CAP socket for SRC AVDTP stream is verified
during establishment of a new transport channel. If the size is less
than twice of outgoing L2CAP MTU, then it is considered as being
insufficient to handle streaming data reliably.
In this case buffer size is increased to be twice of MTU size. Such
fixes some IOP problems with car-kits that use large MTU for music
playback.
---
audio/avdtp.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 53 insertions(+), 0 deletions(-)
diff --git a/audio/avdtp.c b/audio/avdtp.c
index 1683e7c..34b95fd 100644
--- a/audio/avdtp.c
+++ b/audio/avdtp.c
@@ -838,6 +838,40 @@ static gboolean transport_cb(GIOChannel *chan, GIOCondition cond,
return FALSE;
}
+static int get_send_buffer_size(int sk)
+{
+ int size;
+ socklen_t optlen = sizeof(size);
+
+ if (getsockopt(sk, SOL_SOCKET, SO_SNDBUF, &size, &optlen) < 0) {
+ int err = -errno;
+ error("getsockopt(SO_SNDBUF) failed: %s (%d)", strerror(-err),
+ -err);
+ return err;
+ }
+
+ /*
+ * Doubled value is returned by getsockopt since kernel uses that
+ * space for its own purposes (see man 7 socket, bookkeeping overhead
+ * for SO_SNDBUF).
+ */
+ return size / 2;
+}
+
+static int set_send_buffer_size(int sk, int size)
+{
+ socklen_t optlen = sizeof(size);
+
+ if (setsockopt(sk, SOL_SOCKET, SO_SNDBUF, &size, optlen) < 0) {
+ int err = -errno;
+ error("setsockopt(SO_SNDBUF) failed: %s (%d)", strerror(-err),
+ -err);
+ return err;
+ }
+
+ return 0;
+}
+
static void handle_transport_connect(struct avdtp *session, GIOChannel *io,
uint16_t imtu, uint16_t omtu)
{
@@ -865,6 +899,25 @@ static void handle_transport_connect(struct avdtp *session, GIOChannel *io,
stream->omtu = omtu;
stream->imtu = imtu;
+ /* only if local SEP is of type SRC */
+ if (sep->info.type == AVDTP_SEP_TYPE_SOURCE) {
+ int sk, buf_size, min_buf_size;
+
+ sk = g_io_channel_unix_get_fd(stream->io);
+ buf_size = get_send_buffer_size(sk);
+ if (buf_size < 0)
+ goto proceed;
+
+ DBG("sk %d, omtu %d, send buffer size %d", sk, omtu, buf_size);
+ min_buf_size = omtu * 2;
+ if (buf_size < min_buf_size) {
+ DBG("send buffer size to be increassed to %d",
+ min_buf_size);
+ set_send_buffer_size(sk, min_buf_size);
+ }
+ }
+
+proceed:
if (!stream->open_acp && sep->cfm && sep->cfm->open)
sep->cfm->open(session, sep, stream, NULL, sep->user_data);
--
1.7.0.4
^ permalink raw reply related
* [PATCH 0/1] AVDTP SRC stream send buffer size verification
From: Dmitriy Paliy @ 2010-12-15 9:48 UTC (permalink / raw)
To: linux-bluetooth
Hi,
In this patch, send buffer size for L2CAP socket is verified against
outgoing L2CAP MTU size and increased to be twice of it if it is less
than that. Such verification is done for AVDTP source transport channel
only.
Reason to do this check is that system default socket buffer size was
reduced in Meego and it affected IOP with some car-kits that use large
MTUs.
Worth to mention that send buffer size is never decreased, and can be
increased only.
BR,
Dmitriy
^ permalink raw reply
* Re: [PATCH] Added enc_read_blob_req() API to ATT transport, to enable the reading of attributes that exceed the length of the MTU.
From: Anderson Lizardo @ 2010-12-14 20:29 UTC (permalink / raw)
To: Brian Gix; +Cc: linux-bluetooth, padovan, rshaffer
In-Reply-To: <1292356246-24012-2-git-send-email-bgix@codeaurora.org>
On Tue, Dec 14, 2010 at 3:50 PM, Brian Gix <bgix@codeaurora.org> wrote:
> --
> Brian Gix
> bgix@codeaurora.org
> Employee of Qualcomm Innovation Center, Inc.
> Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum
>
> ---
> attrib/att.c | 19 +++++++++++++++++++
> attrib/att.h | 2 ++
> 2 files changed, 21 insertions(+), 0 deletions(-)
Usually, patches sent do Bluez, starte with short commit messages like:
Add ...
Fix ...
Implement ...
Note that we don't use "Added", "Fixed" etc. See the git log for
reference. In this case, you should consider at least adding a short
summary and your original summary as the "commit description", in the
form:
<short summary, e.g. "Implement Read Blob Request">
<empty line>
<long description>
Also as Vinicius mentioned, I think your e-mail signature will show up
on the commit description if someone applies it with "git am". I
suggest you send your patches with "git send-email".
Another issue: looks your e-mail client replaced tabs with spaces (but
it might just be Google messing up on my side).
Regards,
--
Anderson Lizardo
OpenBossa Labs - INdT
Manaus - Brazil
^ permalink raw reply
* Re: [PATCH 0/1] Add enc_read_blob_req() API to ATT
From: Brian Gix @ 2010-12-14 19:54 UTC (permalink / raw)
To: linux-bluetooth; +Cc: padovan, rshaffer
In-Reply-To: <1292356246-24012-1-git-send-email-bgix@codeaurora.org>
Hi Gustavo, Vinicius,
On 12/14/2010 11:50 AM, Brian Gix wrote:
> Atomic change to add ATT_OP_READ_BLOB_REQ encoing to ATT. No dependancies.
>
>
This patch contains only the stand-alone ATT changes, and corrects the
ws issue identified by Vinicius.
--
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] Added enc_read_blob_req() API to ATT transport, to enable the reading of attributes that exceed the length of the MTU.
From: Brian Gix @ 2010-12-14 19:50 UTC (permalink / raw)
To: linux-bluetooth; +Cc: padovan, rshaffer, Brian Gix
In-Reply-To: <1292356246-24012-1-git-send-email-bgix@codeaurora.org>
--
Brian Gix
bgix@codeaurora.org
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum
---
attrib/att.c | 19 +++++++++++++++++++
attrib/att.h | 2 ++
2 files changed, 21 insertions(+), 0 deletions(-)
diff --git a/attrib/att.c b/attrib/att.c
index 445b192..f8dbc02 100644
--- a/attrib/att.c
+++ b/attrib/att.c
@@ -542,6 +542,25 @@ uint16_t enc_read_req(uint16_t handle, uint8_t *pdu, int len)
return min_len;
}
+uint16_t enc_read_blob_req(uint16_t handle, uint16_t offset, uint8_t *pdu,
+ int len)
+{
+ const uint16_t min_len = sizeof(pdu[0]) + sizeof(handle) +
+ sizeof(offset);
+
+ if (pdu == NULL)
+ return 0;
+
+ if (len < min_len)
+ return 0;
+
+ pdu[0] = ATT_OP_READ_BLOB_REQ;
+ att_put_u16(handle, &pdu[1]);
+ att_put_u16(offset, &pdu[3]);
+
+ return min_len;
+}
+
uint16_t dec_read_req(const uint8_t *pdu, int len, uint16_t *handle)
{
const uint16_t min_len = sizeof(pdu[0]) + sizeof(*handle);
diff --git a/attrib/att.h b/attrib/att.h
index 2c8c724..0b8612e 100644
--- a/attrib/att.h
+++ b/attrib/att.h
@@ -202,6 +202,8 @@ uint16_t enc_write_req(uint16_t handle, const uint8_t *value, int vlen,
uint16_t dec_write_req(const uint8_t *pdu, int len, uint16_t *handle,
uint8_t *value, int *vlen);
uint16_t enc_read_req(uint16_t handle, uint8_t *pdu, int len);
+uint16_t enc_read_blob_req(uint16_t handle, uint16_t offset, uint8_t *pdu,
+ int len);
uint16_t dec_read_req(const uint8_t *pdu, int len, uint16_t *handle);
uint16_t enc_read_resp(uint8_t *value, int vlen, uint8_t *pdu, int len);
uint16_t dec_read_resp(const uint8_t *pdu, int len, uint8_t *value, int *vlen);
--
1.7.1
^ permalink raw reply related
* [PATCH 0/1] Add enc_read_blob_req() API to ATT
From: Brian Gix @ 2010-12-14 19:50 UTC (permalink / raw)
To: linux-bluetooth; +Cc: padovan, rshaffer
Atomic change to add ATT_OP_READ_BLOB_REQ encoing to ATT. No dependancies.
--
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: [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
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox