Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/padovan/bluetooth
[platform/kernel/linux-rpi.git] / net / bluetooth / bnep / core.c
index d9edfe8..42d53b8 100644 (file)
@@ -65,31 +65,24 @@ static DECLARE_RWSEM(bnep_session_sem);
 static struct bnep_session *__bnep_get_session(u8 *dst)
 {
        struct bnep_session *s;
-       struct list_head *p;
 
        BT_DBG("");
 
-       list_for_each(p, &bnep_session_list) {
-               s = list_entry(p, struct bnep_session, list);
+       list_for_each_entry(s, &bnep_session_list, list)
                if (!compare_ether_addr(dst, s->eh.h_source))
                        return s;
-       }
+
        return NULL;
 }
 
 static void __bnep_link_session(struct bnep_session *s)
 {
-       /* It's safe to call __module_get() here because sessions are added
-          by the socket layer which has to hold the reference to this module.
-        */
-       __module_get(THIS_MODULE);
        list_add(&s->list, &bnep_session_list);
 }
 
 static void __bnep_unlink_session(struct bnep_session *s)
 {
        list_del(&s->list);
-       module_put(THIS_MODULE);
 }
 
 static int bnep_send(struct bnep_session *s, void *data, size_t len)
@@ -492,7 +485,10 @@ static int bnep_session(void *arg)
                /* RX */
                while ((skb = skb_dequeue(&sk->sk_receive_queue))) {
                        skb_orphan(skb);
-                       bnep_rx_frame(s, skb);
+                       if (!skb_linearize(skb))
+                               bnep_rx_frame(s, skb);
+                       else
+                               kfree_skb(skb);
                }
 
                if (sk->sk_state != BT_CONNECTED)
@@ -527,6 +523,7 @@ static int bnep_session(void *arg)
 
        up_write(&bnep_session_sem);
        free_netdev(dev);
+       module_put_and_exit(0);
        return 0;
 }
 
@@ -613,9 +610,11 @@ int bnep_add_connection(struct bnep_connadd_req *req, struct socket *sock)
 
        __bnep_link_session(s);
 
+       __module_get(THIS_MODULE);
        s->task = kthread_run(bnep_session, s, "kbnepd %s", dev->name);
        if (IS_ERR(s->task)) {
                /* Session thread start failed, gotta cleanup. */
+               module_put(THIS_MODULE);
                unregister_netdev(dev);
                __bnep_unlink_session(s);
                err = PTR_ERR(s->task);
@@ -664,17 +663,14 @@ static void __bnep_copy_ci(struct bnep_conninfo *ci, struct bnep_session *s)
 
 int bnep_get_connlist(struct bnep_connlist_req *req)
 {
-       struct list_head *p;
+       struct bnep_session *s;
        int err = 0, n = 0;
 
        down_read(&bnep_session_sem);
 
-       list_for_each(p, &bnep_session_list) {
-               struct bnep_session *s;
+       list_for_each_entry(s, &bnep_session_list, list) {
                struct bnep_conninfo ci;
 
-               s = list_entry(p, struct bnep_session, list);
-
                __bnep_copy_ci(&ci, s);
 
                if (copy_to_user(req->ci, &ci, sizeof(ci))) {