aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth
diff options
context:
space:
mode:
authorWolfgang Wiedmeyer <wolfgit@wiedmeyer.de>2015-10-25 03:56:13 +0100
committerWolfgang Wiedmeyer <wolfgit@wiedmeyer.de>2015-10-25 03:56:13 +0100
commit795ad0819be4d5922b5140bdda6ff9d0368b0512 (patch)
treee96992a37b3ebc611b7de7a745f28237ecf7a365 /net/bluetooth
parent549367162dfdc75d573f74f4e2891f2dba41582f (diff)
downloadkernel_samsung_smdk4412-795ad0819be4d5922b5140bdda6ff9d0368b0512.zip
kernel_samsung_smdk4412-795ad0819be4d5922b5140bdda6ff9d0368b0512.tar.gz
kernel_samsung_smdk4412-795ad0819be4d5922b5140bdda6ff9d0368b0512.tar.bz2
first merge of networking with upstream
Diffstat (limited to 'net/bluetooth')
-rw-r--r--net/bluetooth/af_bluetooth.c6
-rw-r--r--net/bluetooth/cmtp/capi.c3
-rw-r--r--net/bluetooth/hci_core.c5
-rw-r--r--net/bluetooth/rfcomm/core.c39
-rw-r--r--net/bluetooth/rfcomm/sock.c33
5 files changed, 39 insertions, 47 deletions
diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c
index 9047512..8ea4963 100644
--- a/net/bluetooth/af_bluetooth.c
+++ b/net/bluetooth/af_bluetooth.c
@@ -532,8 +532,9 @@ int bt_sock_wait_state(struct sock *sk, int state, unsigned long timeo)
BT_DBG("sk %p", sk);
add_wait_queue(sk_sleep(sk), &wait);
- set_current_state(TASK_INTERRUPTIBLE);
while (sk->sk_state != state) {
+ set_current_state(TASK_INTERRUPTIBLE);
+
if (!timeo) {
err = -EINPROGRESS;
break;
@@ -547,13 +548,12 @@ int bt_sock_wait_state(struct sock *sk, int state, unsigned long timeo)
release_sock(sk);
timeo = schedule_timeout(timeo);
lock_sock(sk);
- set_current_state(TASK_INTERRUPTIBLE);
err = sock_error(sk);
if (err)
break;
}
- __set_current_state(TASK_RUNNING);
+ set_current_state(TASK_RUNNING);
remove_wait_queue(sk_sleep(sk), &wait);
return err;
}
diff --git a/net/bluetooth/cmtp/capi.c b/net/bluetooth/cmtp/capi.c
index 040f67b..744233c 100644
--- a/net/bluetooth/cmtp/capi.c
+++ b/net/bluetooth/cmtp/capi.c
@@ -326,7 +326,7 @@ void cmtp_recv_capimsg(struct cmtp_session *session, struct sk_buff *skb)
{
struct capi_ctr *ctrl = &session->ctrl;
struct cmtp_application *application;
- __u16 appl;
+ __u16 cmd, appl;
__u32 contr;
BT_DBG("session %p skb %p len %d", session, skb, skb->len);
@@ -344,6 +344,7 @@ void cmtp_recv_capimsg(struct cmtp_session *session, struct sk_buff *skb)
return;
}
+ cmd = CAPICMD(CAPIMSG_COMMAND(skb->data), CAPIMSG_SUBCOMMAND(skb->data));
appl = CAPIMSG_APPID(skb->data);
contr = CAPIMSG_CONTROL(skb->data);
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index b1b7b3d..c1a5685 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -146,7 +146,7 @@ static int __hci_request(struct hci_dev *hdev, void (*req)(struct hci_dev *hdev,
switch (hdev->req_status) {
case HCI_REQ_DONE:
- err = -bt_to_errno(hdev->req_result);
+ err = -bt_err(hdev->req_result);
break;
case HCI_REQ_CANCELED:
@@ -545,7 +545,7 @@ int hci_dev_open(__u16 dev)
ret = __hci_request(hdev, hci_init_req, 0,
msecs_to_jiffies(HCI_INIT_TIMEOUT));
- if (lmp_host_le_capable(hdev))
+ if (lmp_le_capable(hdev))
ret = __hci_request(hdev, hci_le_init_req, 0,
msecs_to_jiffies(HCI_INIT_TIMEOUT));
@@ -1214,6 +1214,7 @@ static void hci_cmd_timer(unsigned long arg)
BT_ERR("%s command tx timeout", hdev->name);
atomic_set(&hdev->cmd_cnt, 1);
+ clear_bit(HCI_RESET, &hdev->flags);
tasklet_schedule(&hdev->cmd_task);
}
diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c
index 754b153..5759bb7 100644
--- a/net/bluetooth/rfcomm/core.c
+++ b/net/bluetooth/rfcomm/core.c
@@ -62,6 +62,7 @@ static DEFINE_MUTEX(rfcomm_mutex);
#define rfcomm_lock() mutex_lock(&rfcomm_mutex)
#define rfcomm_unlock() mutex_unlock(&rfcomm_mutex)
+static unsigned long rfcomm_event;
static LIST_HEAD(session_list);
@@ -119,6 +120,7 @@ static inline void rfcomm_schedule(void)
{
if (!rfcomm_thread)
return;
+ set_bit(RFCOMM_SCHED_WAKEUP, &rfcomm_event);
wake_up_process(rfcomm_thread);
}
@@ -409,19 +411,11 @@ static int __rfcomm_dlc_open(struct rfcomm_dlc *d, bdaddr_t *src, bdaddr_t *dst,
return err;
}
- /* After L2sock created, increase refcnt immediately
- * It can make connection drop in rfcomm_security_cfm because of refcnt.
- */
- rfcomm_session_hold(s);
-
dlci = __dlci(!s->initiator, channel);
/* Check if DLCI already exists */
- if (rfcomm_dlc_get(s, dlci)) {
- /* decrement refcnt */
- rfcomm_session_put(s);
+ if (rfcomm_dlc_get(s, dlci))
return -EBUSY;
- }
rfcomm_dlc_clear_state(d);
@@ -437,9 +431,6 @@ static int __rfcomm_dlc_open(struct rfcomm_dlc *d, bdaddr_t *src, bdaddr_t *dst,
d->mtu = s->mtu;
d->cfc = (s->cfc == RFCOMM_CFC_UNKNOWN) ? 0 : s->cfc;
- /* decrement refcnt */
- rfcomm_session_put(s);
-
if (s->state == BT_CONNECTED) {
if (rfcomm_check_security(d))
rfcomm_send_pn(s, 1, d);
@@ -475,6 +466,7 @@ static int __rfcomm_dlc_close(struct rfcomm_dlc *d, int err)
switch (d->state) {
case BT_CONNECT:
+ case BT_CONFIG:
if (test_and_clear_bit(RFCOMM_DEFER_SETUP, &d->flags)) {
set_bit(RFCOMM_AUTH_REJECT, &d->flags);
rfcomm_schedule();
@@ -1156,7 +1148,6 @@ static int rfcomm_recv_ua(struct rfcomm_session *s, u8 dlci)
if (list_empty(&s->dlcs)) {
s->state = BT_DISCONN;
rfcomm_send_disc(s, 0);
- rfcomm_session_clear_timer(s);
}
break;
@@ -1173,7 +1164,7 @@ static int rfcomm_recv_ua(struct rfcomm_session *s, u8 dlci)
/* When socket is closed and we are not RFCOMM
* initiator rfcomm_process_rx already calls
* rfcomm_session_put() */
- if (s->sock->sk->sk_state != BT_CLOSED && !s->initiator)
+ if (s->sock->sk->sk_state != BT_CLOSED)
if (list_empty(&s->dlcs))
rfcomm_session_put(s);
break;
@@ -1864,10 +1855,7 @@ static inline void rfcomm_process_rx(struct rfcomm_session *s)
/* Get data directly from socket receive queue without copying it. */
while ((skb = skb_dequeue(&sk->sk_receive_queue))) {
skb_orphan(skb);
- if (!skb_linearize(skb))
- rfcomm_recv_frame(s, skb);
- else
- kfree_skb(skb);
+ rfcomm_recv_frame(s, skb);
}
if (sk->sk_state == BT_CLOSED) {
@@ -2050,18 +2038,19 @@ static int rfcomm_run(void *unused)
rfcomm_add_listener(BDADDR_ANY);
- while (1) {
+ while (!kthread_should_stop()) {
set_current_state(TASK_INTERRUPTIBLE);
-
- if (kthread_should_stop())
- break;
+ if (!test_bit(RFCOMM_SCHED_WAKEUP, &rfcomm_event)) {
+ /* No pending events. Let's sleep.
+ * Incoming connections and data will wake us up. */
+ schedule();
+ }
+ set_current_state(TASK_RUNNING);
/* Process stuff */
+ clear_bit(RFCOMM_SCHED_WAKEUP, &rfcomm_event);
rfcomm_process_sessions();
-
- schedule();
}
- __set_current_state(TASK_RUNNING);
rfcomm_kill_listener();
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c
index 56fcfd1..bf6f8f5 100644
--- a/net/bluetooth/rfcomm/sock.c
+++ b/net/bluetooth/rfcomm/sock.c
@@ -485,6 +485,11 @@ static int rfcomm_sock_accept(struct socket *sock, struct socket *newsock, int f
lock_sock(sk);
+ if (sk->sk_state != BT_LISTEN) {
+ err = -EBADFD;
+ goto done;
+ }
+
if (sk->sk_type != SOCK_STREAM) {
err = -EINVAL;
goto done;
@@ -496,20 +501,19 @@ static int rfcomm_sock_accept(struct socket *sock, struct socket *newsock, int f
/* Wait for an incoming connection. (wake-one). */
add_wait_queue_exclusive(sk_sleep(sk), &wait);
- while (1) {
+ while (!(nsk = bt_accept_dequeue(sk, newsock))) {
set_current_state(TASK_INTERRUPTIBLE);
-
- if (sk->sk_state != BT_LISTEN) {
- err = -EBADFD;
+ if (!timeo) {
+ err = -EAGAIN;
break;
}
- nsk = bt_accept_dequeue(sk, newsock);
- if (nsk)
- break;
+ release_sock(sk);
+ timeo = schedule_timeout(timeo);
+ lock_sock(sk);
- if (!timeo) {
- err = -EAGAIN;
+ if (sk->sk_state != BT_LISTEN) {
+ err = -EBADFD;
break;
}
@@ -517,12 +521,8 @@ static int rfcomm_sock_accept(struct socket *sock, struct socket *newsock, int f
err = sock_intr_errno(timeo);
break;
}
-
- release_sock(sk);
- timeo = schedule_timeout(timeo);
- lock_sock(sk);
}
- __set_current_state(TASK_RUNNING);
+ set_current_state(TASK_RUNNING);
remove_wait_queue(sk_sleep(sk), &wait);
if (err)
@@ -681,8 +681,7 @@ static int rfcomm_sock_setsockopt(struct socket *sock, int level, int optname, c
{
struct sock *sk = sock->sk;
struct bt_security sec;
- int err = 0;
- size_t len;
+ int len, err = 0;
u32 opt;
BT_DBG("sk %p", sk);
@@ -744,6 +743,7 @@ static int rfcomm_sock_setsockopt(struct socket *sock, int level, int optname, c
static int rfcomm_sock_getsockopt_old(struct socket *sock, int optname, char __user *optval, int __user *optlen)
{
struct sock *sk = sock->sk;
+ struct sock *l2cap_sk;
struct rfcomm_conninfo cinfo;
struct l2cap_conn *conn = l2cap_pi(sk)->chan->conn;
int len, err = 0;
@@ -788,6 +788,7 @@ static int rfcomm_sock_getsockopt_old(struct socket *sock, int optname, char __u
break;
}
+ l2cap_sk = rfcomm_pi(sk)->dlc->session->sock->sk;
memset(&cinfo, 0, sizeof(cinfo));
cinfo.hci_handle = conn->hcon->handle;