diff options
author | Wolfgang Wiedmeyer <wolfgit@wiedmeyer.de> | 2015-10-25 03:56:13 +0100 |
---|---|---|
committer | Wolfgang Wiedmeyer <wolfgit@wiedmeyer.de> | 2015-10-25 03:56:13 +0100 |
commit | 795ad0819be4d5922b5140bdda6ff9d0368b0512 (patch) | |
tree | e96992a37b3ebc611b7de7a745f28237ecf7a365 /net/bluetooth | |
parent | 549367162dfdc75d573f74f4e2891f2dba41582f (diff) | |
download | kernel_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.c | 6 | ||||
-rw-r--r-- | net/bluetooth/cmtp/capi.c | 3 | ||||
-rw-r--r-- | net/bluetooth/hci_core.c | 5 | ||||
-rw-r--r-- | net/bluetooth/rfcomm/core.c | 39 | ||||
-rw-r--r-- | net/bluetooth/rfcomm/sock.c | 33 |
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; |