From d4299ce6b33c0afd22cf6a170cfaf89c63d1114d Mon Sep 17 00:00:00 2001 From: Andre Guedes Date: Wed, 27 Mar 2013 20:04:57 -0300 Subject: Bluetooth: Remove unneeded hci_req_cmd_status function This patch removes the hci_req_cmd_status function since it is not used anymore. The HCI request framework now considers the HCI command has complete once the Command Status or Command Complete Event is received. Signed-off-by: Andre Guedes Signed-off-by: Johan Hedberg --- include/net/bluetooth/hci_core.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include/net') diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 358a6983d3b..0e7ee892d7a 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -1055,7 +1055,6 @@ void hci_req_init(struct hci_request *req, struct hci_dev *hdev); int hci_req_run(struct hci_request *req, hci_req_complete_t complete); void hci_req_add(struct hci_request *req, u16 opcode, u32 plen, void *param); void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status); -void hci_req_cmd_status(struct hci_dev *hdev, u16 opcode, u8 status); int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, void *param); void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags); -- cgit v1.2.3 From b6ddb638235d90ed67af9af40e63880fd66a1939 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Tue, 2 Apr 2013 13:34:31 +0300 Subject: Bluetooth: Track received events in hdev This patch adds tracking of received HCI events to the hci_dev struct. This is necessary so that a subsequent patch can implement a function for sending a single command synchronously and returning the resulting command complete parameters in the function return value. Signed-off-by: Johan Hedberg Acked-by: Marcel Holtmann --- include/net/bluetooth/hci_core.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/net') diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 0e7ee892d7a..89eda2ef238 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -244,6 +244,7 @@ struct hci_dev { struct sk_buff_head raw_q; struct sk_buff_head cmd_q; + struct sk_buff *recv_evt; struct sk_buff *sent_cmd; struct sk_buff *reassembly[NUM_REASSEMBLY]; -- cgit v1.2.3 From 75e84b7c522c6e07964cd1f5bf28535768a1e9fa Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Tue, 2 Apr 2013 13:35:04 +0300 Subject: Bluetooth: Add __hci_cmd_sync() helper function This patch adds a helper function for sending a single HCI command waiting for its completion and then returning back the parameters in the resulting command complete event (if there was one). The implementation is very similar to that of hci_req_sync() except that instead of invocing a callback for sending HCI commands the function constructs and sends one itself and after being woken up picks the last received event from hdev->recv_evt (if it matches the right criteria) and returns it. Signed-off-by: Johan Hedberg Acked-by: Marcel Holtmann --- include/net/bluetooth/hci_core.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include/net') diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 89eda2ef238..755743d508a 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -1057,6 +1057,9 @@ int hci_req_run(struct hci_request *req, hci_req_complete_t complete); void hci_req_add(struct hci_request *req, u16 opcode, u32 plen, void *param); void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status); +struct sk_buff *__hci_cmd_sync(struct hci_dev *hdev, u16 opcode, u32 plen, + void *param, u32 timeout); + int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, void *param); void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags); void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb); -- cgit v1.2.3 From 02350a725f5bc44490c30a10e7e04a12a5ecd406 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Wed, 3 Apr 2013 21:50:29 +0300 Subject: Bluetooth: Add support for custom event terminated commands This patch adds support for having commands within HCI requests that do not result in a command complete but some other event. This is at least needed for some vendor specific commands to be issued in the hdev->setup() procecure, but might also be useful for other commands. The way that the support is implemented is by extending the skb control buffer to have a field to indicate that the command is expected to terminate with a special event. After sending the command each received event can then be compared against this field through hdev->sent_cmd. Signed-off-by: Johan Hedberg Acked-by: Marcel Holtmann --- include/net/bluetooth/bluetooth.h | 1 + include/net/bluetooth/hci_core.h | 2 ++ 2 files changed, 3 insertions(+) (limited to 'include/net') diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h index ed6e9552252..591fee7d006 100644 --- a/include/net/bluetooth/bluetooth.h +++ b/include/net/bluetooth/bluetooth.h @@ -266,6 +266,7 @@ typedef void (*hci_req_complete_t)(struct hci_dev *hdev, u8 status); struct hci_req_ctrl { bool start; + u8 event; hci_req_complete_t complete; }; diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 755743d508a..b85eefb230f 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -1055,6 +1055,8 @@ struct hci_request { void hci_req_init(struct hci_request *req, struct hci_dev *hdev); int hci_req_run(struct hci_request *req, hci_req_complete_t complete); void hci_req_add(struct hci_request *req, u16 opcode, u32 plen, void *param); +void hci_req_add_ev(struct hci_request *req, u16 opcode, u32 plen, void *param, + u8 event); void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status); struct sk_buff *__hci_cmd_sync(struct hci_dev *hdev, u16 opcode, u32 plen, -- cgit v1.2.3 From 7b1abbbed0f2a1bc19bb8c0d48a284466043092a Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Wed, 3 Apr 2013 21:54:47 +0300 Subject: Bluetooth: Add __hci_cmd_sync_ev function This patch adds a __hci_cmd_sync_ev function, analogous to __hci_cmd_sync except that it also takes an event parameter to indicate that the command completes with a special event instead of command complete. Internally this new function takes advantage of the hci_req_add_ev function introduced in the previous patch. The primary expected user of this new function are the setup routines of HCI drivers which may want to send custom commands and return only when they have completed. Signed-off-by: Johan Hedberg Acked-by: Marcel Holtmann --- include/net/bluetooth/hci_core.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/net') diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index b85eefb230f..47129b1ee20 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -1061,6 +1061,8 @@ void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status); struct sk_buff *__hci_cmd_sync(struct hci_dev *hdev, u16 opcode, u32 plen, void *param, u32 timeout); +struct sk_buff *__hci_cmd_sync_ev(struct hci_dev *hdev, u16 opcode, u32 plen, + void *param, u8 event, u32 timeout); int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, void *param); void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags); -- cgit v1.2.3 From f41c70c4d5e3f6c2a7f9e5dfc10af452591a2484 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 12 Nov 2012 14:02:14 +0900 Subject: Bluetooth: Add driver setup stage for early init Some drivers require a special stage for their early init. This is always specific to the driver or transport. So call back into driver to allow bringing up the device. The advantage with this stage is that the Bluetooth core is actually handling the HCI layer now. This means that command and event processing is available. Signed-off-by: Marcel Holtmann Signed-off-by: Johan Hedberg --- include/net/bluetooth/hci_core.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/net') diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 47129b1ee20..395e8f6982f 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -293,6 +293,7 @@ struct hci_dev { int (*open)(struct hci_dev *hdev); int (*close)(struct hci_dev *hdev); int (*flush)(struct hci_dev *hdev); + int (*setup)(struct hci_dev *hdev); int (*send)(struct sk_buff *skb); void (*notify)(struct hci_dev *hdev, unsigned int evt); int (*ioctl)(struct hci_dev *hdev, unsigned int cmd, unsigned long arg); -- cgit v1.2.3 From 5afff03815e26abf34702ec10422535224cdfe38 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 12 Nov 2012 14:02:16 +0900 Subject: Bluetooth: Remove driver init queue from core The driver init queue is no longer needed. This can be all handled inside the drivers now. So remove it. Signed-off-by: Marcel Holtmann Signed-off-by: Johan Hedberg --- include/net/bluetooth/hci_core.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'include/net') diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 395e8f6982f..d4e13bf5ae5 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -269,8 +269,6 @@ struct hci_dev { struct hci_dev_stats stat; - struct sk_buff_head driver_init; - atomic_t promisc; struct dentry *debugfs; -- cgit v1.2.3 From b3916db32c4a3124eee9f3742a2f4723731d7602 Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Fri, 5 Apr 2013 14:57:34 +0200 Subject: Bluetooth: hidp: verify l2cap sockets We need to verify that the given sockets actually are l2cap sockets. If they aren't, we are not supposed to access bt_sk(sock) and we shouldn't start the session if the offsets turn out to be valid local BT addresses. That is, if someone passes a TCP socket to HIDCONNADD, then we access some random offset in the TCP socket (which isn't even guaranteed to be valid). Fix this by checking that the socket is an l2cap socket. Signed-off-by: David Herrmann Acked-by: Marcel Holtmann Signed-off-by: Gustavo Padovan --- include/net/bluetooth/l2cap.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/net') diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index cdd33021f83..278830ef92c 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -786,6 +786,7 @@ extern bool disable_ertm; int l2cap_init_sockets(void); void l2cap_cleanup_sockets(void); +bool l2cap_is_socket(struct socket *sock); void __l2cap_connect_rsp_defer(struct l2cap_chan *chan); int __l2cap_wait_ack(struct sock *sk); -- cgit v1.2.3 From 76a68ba0ae097be72dfa8f918b3139130da769a4 Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Sat, 6 Apr 2013 20:28:37 +0200 Subject: Bluetooth: rename hci_conn_put to hci_conn_drop We use _get() and _put() for device ref-counting in the kernel. However, hci_conn_put() is _not_ used for ref-counting, hence, rename it to hci_conn_drop() so we can later fix ref-counting and introduce hci_conn_put(). hci_conn_hold() and hci_conn_put() are currently used to manage how long a connection should be held alive. When the last user drops the connection, we spawn a delayed work that performs the disconnect. Obviously, this has nothing to do with ref-counting for the _object_ but rather for the keep-alive of the connection. But we really _need_ proper ref-counting for the _object_ to allow connection-users like rfcomm-tty, HIDP or others. Signed-off-by: David Herrmann Acked-by: Marcel Holtmann Signed-off-by: Gustavo Padovan --- include/net/bluetooth/hci_core.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/net') diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index d4e13bf5ae5..78ea9c7c202 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -612,7 +612,7 @@ static inline void hci_conn_hold(struct hci_conn *conn) cancel_delayed_work(&conn->disc_work); } -static inline void hci_conn_put(struct hci_conn *conn) +static inline void hci_conn_drop(struct hci_conn *conn) { BT_DBG("hcon %p orig refcnt %d", conn, atomic_read(&conn->refcnt)); -- cgit v1.2.3 From fc225c3f5d1b6aa6f99c5c300af4605e4923ce79 Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Sat, 6 Apr 2013 20:28:38 +0200 Subject: Bluetooth: remove unneeded hci_conn_hold/put_device() hci_conn_hold/put_device() is used to control when hci_conn->dev is no longer needed and can be deleted from the system. Lets first look how they are currently used throughout the code (excluding HIDP!). All code that uses hci_conn_hold_device() looks like this: ... hci_conn_hold_device(); hci_conn_add_sysfs(); ... On the other side, hci_conn_put_device() is exclusively used in hci_conn_del(). So, considering that hci_conn_del() must not be called twice (which would fail horribly), we know that hci_conn_put_device() is only called _once_ (which is in hci_conn_del()). On the other hand, hci_conn_add_sysfs() must not be called twice, either (it would call device_add twice, which breaks the device, see drivers/base/core.c). So we know that hci_conn_hold_device() is also called only once (it's only called directly before hci_conn_add_sysfs()). So hold and put are known to be called only once. That means we can safely remove them and directly call hci_conn_del_sysfs() in hci_conn_del(). But there is one issue left: HIDP also uses hci_conn_hold/put_device(). However, this case can be ignored and simply removed as it is totally broken. The issue is, the only thing HIDP delays with hci_conn_hold_device() is the removal of the hci_conn->dev from sysfs. But, the hci_conn device has no mechanism to get notified when its own parent (hci_dev) gets removed from sysfs. hci_dev_hold/put() does _not_ control when it is removed but only when the device object is created and destroyed. And hci_dev calls hci_conn_flush_*() when it removes itself from sysfs, which itself causes hci_conn_del() to be called, but it does _not_ cause hci_conn_del_sysfs() to be called, which is wrong. Hence, we fix it to call hci_conn_del_sysfs() in hci_conn_del(). This guarantees that a hci_conn object is removed from sysfs _before_ its parent hci_dev is removed. The changes to HIDP look scary, wrong and broken. However, if you look at the HIDP session management, you will notice they're already broken in the exact _same_ way (ever tried "unplugging" HIDP devices? Breaks _all_ the time). So this patch only makes HIDP look _scary_ and _obviously broken_. It does not break HIDP itself, it already is! See later patches in this series which fix HIDP to use proper session-management. Signed-off-by: David Herrmann Acked-by: Marcel Holtmann Signed-off-by: Gustavo Padovan --- include/net/bluetooth/hci_core.h | 4 ---- 1 file changed, 4 deletions(-) (limited to 'include/net') diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 78ea9c7c202..5590cc4412c 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -345,7 +345,6 @@ struct hci_conn { struct timer_list auto_accept_timer; struct device dev; - atomic_t devref; struct hci_dev *hdev; void *l2cap_data; @@ -601,9 +600,6 @@ int hci_conn_switch_role(struct hci_conn *conn, __u8 role); void hci_conn_enter_active_mode(struct hci_conn *conn, __u8 force_active); -void hci_conn_hold_device(struct hci_conn *conn); -void hci_conn_put_device(struct hci_conn *conn); - static inline void hci_conn_hold(struct hci_conn *conn) { BT_DBG("hcon %p orig refcnt %d", conn, atomic_read(&conn->refcnt)); -- cgit v1.2.3 From 8d12356f33f819ec0d064e233f7ca8e59eaa38ef Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Sat, 6 Apr 2013 20:28:39 +0200 Subject: Bluetooth: introduce hci_conn ref-counting We currently do not allow using hci_conn from outside of HCI-core. However, several other users could make great use of it. This includes HIDP, rfcomm and all other sub-protocols that rely on an active connection. Hence, we now introduce hci_conn ref-counting. We currently never call get_device(). put_device() is exclusively used in hci_conn_del_sysfs(). Hence, we currently never have a greater device-refcnt than 1. Therefore, it is safe to move the put_device() call from hci_conn_del_sysfs() to hci_conn_del() (it's the only caller). In fact, this even fixes a "use-after-free" bug as we access hci_conn after calling hci_conn_del_sysfs() in hci_conn_del(). From now on we can add references to hci_conn objects in other layers (like l2cap_sock, HIDP, rfcomm, ...) and grab a reference via hci_conn_get(). This does _not_ guarantee, that the connection is still alive. But, this isn't what we want. We can simply lock the hci_conn device and use "device_is_registered(hci_conn->dev)" to test that. However, this is hardly necessary as outside users should never rely on the HCI connection to be alive, anyway. Instead, they should solely rely on the device-object to be available. But if sub-devices want the hci_conn object as sysfs parent, they need to be notified when the connection drops. This will be introduced in later patches with l2cap_users. Signed-off-by: David Herrmann Acked-by: Marcel Holtmann Signed-off-by: Gustavo Padovan --- include/net/bluetooth/hci_core.h | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) (limited to 'include/net') diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 5590cc4412c..d324b11a0c8 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -600,6 +600,37 @@ int hci_conn_switch_role(struct hci_conn *conn, __u8 role); void hci_conn_enter_active_mode(struct hci_conn *conn, __u8 force_active); +/* + * hci_conn_get() and hci_conn_put() are used to control the life-time of an + * "hci_conn" object. They do not guarantee that the hci_conn object is running, + * working or anything else. They just guarantee that the object is available + * and can be dereferenced. So you can use its locks, local variables and any + * other constant data. + * Before accessing runtime data, you _must_ lock the object and then check that + * it is still running. As soon as you release the locks, the connection might + * get dropped, though. + * + * On the other hand, hci_conn_hold() and hci_conn_drop() are used to control + * how long the underlying connection is held. So every channel that runs on the + * hci_conn object calls this to prevent the connection from disappearing. As + * long as you hold a device, you must also guarantee that you have a valid + * reference to the device via hci_conn_get() (or the initial reference from + * hci_conn_add()). + * The hold()/drop() ref-count is known to drop below 0 sometimes, which doesn't + * break because nobody cares for that. But this means, we cannot use + * _get()/_drop() in it, but require the caller to have a valid ref (FIXME). + */ + +static inline void hci_conn_get(struct hci_conn *conn) +{ + get_device(&conn->dev); +} + +static inline void hci_conn_put(struct hci_conn *conn) +{ + put_device(&conn->dev); +} + static inline void hci_conn_hold(struct hci_conn *conn) { BT_DBG("hcon %p orig refcnt %d", conn, atomic_read(&conn->refcnt)); -- cgit v1.2.3 From f53c20e93612f708ed3b378ec9735b779dcd7d59 Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Sat, 6 Apr 2013 20:28:42 +0200 Subject: Bluetooth: allow constant arguments for bacmp()/bacpy() There is no reason to require the source arguments to be writeable so fix this to allow constant source addresses. Signed-off-by: David Herrmann Acked-by: Marcel Holtmann Signed-off-by: Gustavo Padovan --- include/net/bluetooth/bluetooth.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include/net') diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h index 591fee7d006..6912ef9a188 100644 --- a/include/net/bluetooth/bluetooth.h +++ b/include/net/bluetooth/bluetooth.h @@ -193,11 +193,11 @@ static inline bool bdaddr_type_is_le(__u8 type) #define BDADDR_LOCAL (&(bdaddr_t) {{0, 0, 0, 0xff, 0xff, 0xff} }) /* Copy, swap, convert BD Address */ -static inline int bacmp(bdaddr_t *ba1, bdaddr_t *ba2) +static inline int bacmp(const bdaddr_t *ba1, const bdaddr_t *ba2) { return memcmp(ba1, ba2, sizeof(bdaddr_t)); } -static inline void bacpy(bdaddr_t *dst, bdaddr_t *src) +static inline void bacpy(bdaddr_t *dst, const bdaddr_t *src) { memcpy(dst, src, sizeof(bdaddr_t)); } -- cgit v1.2.3 From 9c903e373c11f62d62bce1209f662ca92589a075 Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Sat, 6 Apr 2013 20:28:44 +0200 Subject: Bluetooth: l2cap: introduce l2cap_conn ref-counting If we want to use l2cap_conn outside of l2cap_core.c, we need refcounting for these objects. Otherwise, we cannot synchronize l2cap locks with outside locks and end up with deadlocks. Hence, introduce ref-counting for l2cap_conn objects. This doesn't affect l2cap internals at all, as they use a direct synchronization. We also keep a reference to the parent hci_conn for locking purposes as l2cap_conn depends on this. This doesn't affect the connection itself but only the lifetime of the (dead) object. Signed-off-by: David Herrmann Acked-by: Marcel Holtmann Signed-off-by: Gustavo Padovan --- include/net/bluetooth/l2cap.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include/net') diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index 278830ef92c..7b4cc5b9853 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -583,6 +583,7 @@ struct l2cap_conn { struct list_head chan_l; struct mutex chan_lock; + struct kref ref; }; #define L2CAP_INFO_CL_MTU_REQ_SENT 0x01 @@ -813,4 +814,7 @@ void l2cap_logical_cfm(struct l2cap_chan *chan, struct hci_chan *hchan, u8 status); void __l2cap_physical_cfm(struct l2cap_chan *chan, int result); +void l2cap_conn_get(struct l2cap_conn *conn); +void l2cap_conn_put(struct l2cap_conn *conn); + #endif /* __L2CAP_H */ -- cgit v1.2.3 From 2c8e1411e93391c5a78f55b09697a997474a4707 Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Sat, 6 Apr 2013 20:28:45 +0200 Subject: Bluetooth: l2cap: add l2cap_user sub-modules Several sub-modules like HIDP, rfcomm, ... need to track l2cap connections. The l2cap_conn->hcon->dev object is used as parent for sysfs devices so the sub-modules need to be notified when the hci_conn object is removed from sysfs. As submodules normally use the l2cap layer, the l2cap_user objects are registered there instead of on the underlying hci_conn object. This avoids any direct dependency on the HCI layer and lets the l2cap core handle any specifics. This patch introduces l2cap_user objects which contain a "probe" and "remove" callback. You can register them on any l2cap_conn object and if it is active, the "probe" callback will get called. Otherwise, an error is returned. The l2cap_conn object will call your "remove" callback directly before it is removed from user-space. This allows you to remove your submodules _before_ the parent l2cap_conn and hci_conn object is removed. At any time you can asynchronously unregister your l2cap_user object if your submodule vanishes before the l2cap_conn object does. There is no way around l2cap_user. If we want wire-protocols in the kernel, we always want the hci_conn object as parent in the sysfs tree. We cannot use a channel here since we might need multiple channels for a single protocol. But the problem is, we _must_ get notified when an l2cap_conn object is removed. We cannot use reference-counting for object-removal! This is not how it works. If a hardware is removed, we should immediately remove the object from sysfs. Any other behavior would be inconsistent with the rest of the system. Also note that device_del() might sleep, but it doesn't wait for user-space or block very long. It only _unlinks_ the object from sysfs and the whole device-tree. Everything else is handled by ref-counts! This is exactly what the other sub-modules must do: unlink their devices when the "remove" l2cap_user callback is called. They should not do any cleanup or synchronous shutdowns. Signed-off-by: David Herrmann Acked-by: Marcel Holtmann Signed-off-by: Gustavo Padovan --- include/net/bluetooth/l2cap.h | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'include/net') diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index 7b4cc5b9853..fb94cf13c77 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -584,6 +584,13 @@ struct l2cap_conn { struct list_head chan_l; struct mutex chan_lock; struct kref ref; + struct list_head users; +}; + +struct l2cap_user { + struct list_head list; + int (*probe) (struct l2cap_conn *conn, struct l2cap_user *user); + void (*remove) (struct l2cap_conn *conn, struct l2cap_user *user); }; #define L2CAP_INFO_CL_MTU_REQ_SENT 0x01 @@ -817,4 +824,7 @@ void __l2cap_physical_cfm(struct l2cap_chan *chan, int result); void l2cap_conn_get(struct l2cap_conn *conn); void l2cap_conn_put(struct l2cap_conn *conn); +int l2cap_register_user(struct l2cap_conn *conn, struct l2cap_user *user); +void l2cap_unregister_user(struct l2cap_conn *conn, struct l2cap_user *user); + #endif /* __L2CAP_H */ -- cgit v1.2.3 From fa5513be2b709c8ce6ff0b11d0715760a9a70ffd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Dalleau?= Date: Tue, 16 Apr 2013 17:28:58 +0200 Subject: Bluetooth: Move and rename hci_conn_accept MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since this function is only used by sco, move it from hci_event.c to sco.c and rename to sco_conn_defer_accept. Make it static. Signed-off-by: Frédéric Dalleau Acked-by: Marcel Holtmann Signed-off-by: Gustavo Padovan --- include/net/bluetooth/hci_core.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include/net') diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index d324b11a0c8..74f77b7ef13 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -583,7 +583,6 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst); int hci_conn_del(struct hci_conn *conn); void hci_conn_hash_flush(struct hci_dev *hdev); void hci_conn_check_pending(struct hci_dev *hdev); -void hci_conn_accept(struct hci_conn *conn, int mask); struct hci_chan *hci_chan_create(struct hci_conn *conn); void hci_chan_del(struct hci_chan *chan); -- cgit v1.2.3 From cad718ed2f6fd204b2c5cac6b611fc3fcde7b183 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Wed, 17 Apr 2013 15:00:51 +0300 Subject: Bluetooth: Track feature pages in a single table The local and remote features are organized by page number. Page 0 are the LMP features, page 1 the host features, and any pages beyond 1 features that future core specification versions may define. So far we've only had the first two pages and two separate variables has been convenient enough, however with the introduction of Core Specification Addendum 4 there are features defined on page 2. Instead of requiring the addition of a new variable each time a new page number is defined, this patch refactors the code to use a single table for the features. The patch needs to update both the hci_dev and hci_conn structures since there are macros that depend on the features being represented in the same way in both of them. Signed-off-by: Johan Hedberg Signed-off-by: Gustavo Padovan --- include/net/bluetooth/hci_core.h | 49 ++++++++++++++++++++-------------------- 1 file changed, 25 insertions(+), 24 deletions(-) (limited to 'include/net') diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 74f77b7ef13..26822967e29 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -134,6 +134,8 @@ struct amp_assoc { __u8 data[HCI_MAX_AMP_ASSOC_SIZE]; }; +#define HCI_MAX_PAGES 2 + #define NUM_REASSEMBLY 4 struct hci_dev { struct list_head list; @@ -151,8 +153,7 @@ struct hci_dev { __u8 dev_class[3]; __u8 major_class; __u8 minor_class; - __u8 features[8]; - __u8 host_features[8]; + __u8 features[HCI_MAX_PAGES][8]; __u8 le_features[8]; __u8 le_white_list_size; __u8 le_states[8]; @@ -313,7 +314,7 @@ struct hci_conn { bool out; __u8 attempt; __u8 dev_class[3]; - __u8 features[8]; + __u8 features[HCI_MAX_PAGES][8]; __u16 interval; __u16 pkt_type; __u16 link_policy; @@ -786,29 +787,29 @@ void hci_conn_del_sysfs(struct hci_conn *conn); #define SET_HCIDEV_DEV(hdev, pdev) ((hdev)->dev.parent = (pdev)) /* ----- LMP capabilities ----- */ -#define lmp_encrypt_capable(dev) ((dev)->features[0] & LMP_ENCRYPT) -#define lmp_rswitch_capable(dev) ((dev)->features[0] & LMP_RSWITCH) -#define lmp_hold_capable(dev) ((dev)->features[0] & LMP_HOLD) -#define lmp_sniff_capable(dev) ((dev)->features[0] & LMP_SNIFF) -#define lmp_park_capable(dev) ((dev)->features[1] & LMP_PARK) -#define lmp_inq_rssi_capable(dev) ((dev)->features[3] & LMP_RSSI_INQ) -#define lmp_esco_capable(dev) ((dev)->features[3] & LMP_ESCO) -#define lmp_bredr_capable(dev) (!((dev)->features[4] & LMP_NO_BREDR)) -#define lmp_le_capable(dev) ((dev)->features[4] & LMP_LE) -#define lmp_sniffsubr_capable(dev) ((dev)->features[5] & LMP_SNIFF_SUBR) -#define lmp_pause_enc_capable(dev) ((dev)->features[5] & LMP_PAUSE_ENC) -#define lmp_ext_inq_capable(dev) ((dev)->features[6] & LMP_EXT_INQ) -#define lmp_le_br_capable(dev) !!((dev)->features[6] & LMP_SIMUL_LE_BR) -#define lmp_ssp_capable(dev) ((dev)->features[6] & LMP_SIMPLE_PAIR) -#define lmp_no_flush_capable(dev) ((dev)->features[6] & LMP_NO_FLUSH) -#define lmp_lsto_capable(dev) ((dev)->features[7] & LMP_LSTO) -#define lmp_inq_tx_pwr_capable(dev) ((dev)->features[7] & LMP_INQ_TX_PWR) -#define lmp_ext_feat_capable(dev) ((dev)->features[7] & LMP_EXTFEATURES) +#define lmp_encrypt_capable(dev) ((dev)->features[0][0] & LMP_ENCRYPT) +#define lmp_rswitch_capable(dev) ((dev)->features[0][0] & LMP_RSWITCH) +#define lmp_hold_capable(dev) ((dev)->features[0][0] & LMP_HOLD) +#define lmp_sniff_capable(dev) ((dev)->features[0][0] & LMP_SNIFF) +#define lmp_park_capable(dev) ((dev)->features[0][1] & LMP_PARK) +#define lmp_inq_rssi_capable(dev) ((dev)->features[0][3] & LMP_RSSI_INQ) +#define lmp_esco_capable(dev) ((dev)->features[0][3] & LMP_ESCO) +#define lmp_bredr_capable(dev) (!((dev)->features[0][4] & LMP_NO_BREDR)) +#define lmp_le_capable(dev) ((dev)->features[0][4] & LMP_LE) +#define lmp_sniffsubr_capable(dev) ((dev)->features[0][5] & LMP_SNIFF_SUBR) +#define lmp_pause_enc_capable(dev) ((dev)->features[0][5] & LMP_PAUSE_ENC) +#define lmp_ext_inq_capable(dev) ((dev)->features[0][6] & LMP_EXT_INQ) +#define lmp_le_br_capable(dev) (!!((dev)->features[0][6] & LMP_SIMUL_LE_BR)) +#define lmp_ssp_capable(dev) ((dev)->features[0][6] & LMP_SIMPLE_PAIR) +#define lmp_no_flush_capable(dev) ((dev)->features[0][6] & LMP_NO_FLUSH) +#define lmp_lsto_capable(dev) ((dev)->features[0][7] & LMP_LSTO) +#define lmp_inq_tx_pwr_capable(dev) ((dev)->features[0][7] & LMP_INQ_TX_PWR) +#define lmp_ext_feat_capable(dev) ((dev)->features[0][7] & LMP_EXTFEATURES) /* ----- Extended LMP capabilities ----- */ -#define lmp_host_ssp_capable(dev) ((dev)->host_features[0] & LMP_HOST_SSP) -#define lmp_host_le_capable(dev) !!((dev)->host_features[0] & LMP_HOST_LE) -#define lmp_host_le_br_capable(dev) !!((dev)->host_features[0] & LMP_HOST_LE_BREDR) +#define lmp_host_ssp_capable(dev) ((dev)->features[1][0] & LMP_HOST_SSP) +#define lmp_host_le_capable(dev) (!!((dev)->features[1][0] & LMP_HOST_LE)) +#define lmp_host_le_br_capable(dev) (!!((dev)->features[1][0] & LMP_HOST_LE_BREDR)) /* returns true if at least one AMP active */ static inline bool hci_amp_capable(void) -- cgit v1.2.3 From d2c5d77fff6ac0f43fc36f4fde020f726f773c1d Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Wed, 17 Apr 2013 15:00:52 +0300 Subject: Bluetooth: Add reading of all local feature pages With the introduction of CSA4 there is now also a features page number 2 available. This patch increments the maximum supported page number to 2 and adds code for reading all available pages (as long as we have support for them - indicated by HCI_MAX_PAGES). Signed-off-by: Johan Hedberg Signed-off-by: Gustavo Padovan --- include/net/bluetooth/hci_core.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include/net') diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 26822967e29..80d718a9b31 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -134,7 +134,7 @@ struct amp_assoc { __u8 data[HCI_MAX_AMP_ASSOC_SIZE]; }; -#define HCI_MAX_PAGES 2 +#define HCI_MAX_PAGES 3 #define NUM_REASSEMBLY 4 struct hci_dev { @@ -153,6 +153,7 @@ struct hci_dev { __u8 dev_class[3]; __u8 major_class; __u8 minor_class; + __u8 max_page; __u8 features[HCI_MAX_PAGES][8]; __u8 le_features[8]; __u8 le_white_list_size; -- cgit v1.2.3 From 5df480b56e427d83830576862463226c8fcc95d7 Mon Sep 17 00:00:00 2001 From: Andre Guedes Date: Thu, 4 Apr 2013 20:21:00 -0300 Subject: Bluetooth: Add LE scan type macros This patch adds macros for active and passive LE scan type values. The LE_SCAN_PASSIVE was also defined since it will be used in future by LE connection routine and GAP Observer Role support. Signed-off-by: Andre Guedes Acked-by: Johan Hedberg Signed-off-by: Gustavo Padovan --- include/net/bluetooth/hci.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include/net') diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index b3308927a0a..3f4266b3c3b 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h @@ -984,6 +984,9 @@ struct hci_cp_le_set_adv_data { #define HCI_OP_LE_SET_ADV_ENABLE 0x200a +#define LE_SCAN_PASSIVE 0x00 +#define LE_SCAN_ACTIVE 0x01 + #define HCI_OP_LE_SET_SCAN_PARAM 0x200b struct hci_cp_le_set_scan_param { __u8 type; -- cgit v1.2.3 From 525e296a28561659d85a63befb694f36e6ec3429 Mon Sep 17 00:00:00 2001 From: Andre Guedes Date: Thu, 4 Apr 2013 20:21:01 -0300 Subject: Bluetooth: Add macros for filter duplicates values This patch adds macros for filter_duplicates parameter values from HCI LE Set Scan Enable command. It also fixes le_scan_enable_req function so it uses the LE_SCAN_FILTER_DUP_ENABLE macro instead of a magic number. The LE_SCAN_FILTER_DUP_DISABLE was also defined since it will be required to properly support the GAP Observer Role. Signed-off-by: Andre Guedes Acked-by: Johan Hedberg Signed-off-by: Gustavo Padovan --- include/net/bluetooth/hci.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/net') diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index 3f4266b3c3b..84c37abc48c 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h @@ -998,6 +998,8 @@ struct hci_cp_le_set_scan_param { #define LE_SCANNING_DISABLED 0x00 #define LE_SCANNING_ENABLED 0x01 +#define LE_SCAN_FILTER_DUP_DISABLE 0x00 +#define LE_SCAN_FILTER_DUP_ENABLE 0x01 #define HCI_OP_LE_SET_SCAN_ENABLE 0x200c struct hci_cp_le_set_scan_enable { -- cgit v1.2.3 From 76a388beaf92cc75b829d4a0b7d69afaaeaa4b0a Mon Sep 17 00:00:00 2001 From: Andre Guedes Date: Thu, 4 Apr 2013 20:21:02 -0300 Subject: Bluetooth: Rename LE_SCANNING_* macros This patch renames LE_SCANNING_ENABLED and LE_SCANNING_DISABLED macros to LE_SCAN_ENABLE and LE_SCAN_DISABLE in order to keep the same prefix others LE scan macros have. It also fixes le_scan_enable_req function so it uses the LE_SCAN_ ENABLE macro instead of a magic number. Signed-off-by: Andre Guedes Acked-by: Johan Hedberg Signed-off-by: Gustavo Padovan --- include/net/bluetooth/hci.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include/net') diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index 84c37abc48c..e0512aaef4b 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h @@ -996,8 +996,8 @@ struct hci_cp_le_set_scan_param { __u8 filter_policy; } __packed; -#define LE_SCANNING_DISABLED 0x00 -#define LE_SCANNING_ENABLED 0x01 +#define LE_SCAN_DISABLE 0x00 +#define LE_SCAN_ENABLE 0x01 #define LE_SCAN_FILTER_DUP_DISABLE 0x00 #define LE_SCAN_FILTER_DUP_ENABLE 0x01 -- cgit v1.2.3