]> Pileus Git - ~andy/linux/blobdiff - net/bluetooth/l2cap.c
[NEIGHBOUR]: Use proc_create() to setup ->proc_fops first
[~andy/linux] / net / bluetooth / l2cap.c
index 733c95dbd07e930bb5956a3ad265f1b9f863695f..7c5459c8e8efdf9e7e9e51d485c9f9ff99eb20f9 100644 (file)
@@ -99,13 +99,6 @@ static void l2cap_sock_clear_timer(struct sock *sk)
        sk_stop_timer(sk, &sk->sk_timer);
 }
 
-static void l2cap_sock_init_timer(struct sock *sk)
-{
-       init_timer(&sk->sk_timer);
-       sk->sk_timer.function = l2cap_sock_timeout;
-       sk->sk_timer.data = (unsigned long)sk;
-}
-
 /* ---- L2CAP channels ---- */
 static struct sock *__l2cap_get_chan_by_dcid(struct l2cap_chan_list *l, u16 cid)
 {
@@ -395,9 +388,7 @@ static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status)
 
        conn->feat_mask = 0;
 
-       init_timer(&conn->info_timer);
-       conn->info_timer.function = l2cap_info_timeout;
-       conn->info_timer.data = (unsigned long) conn;
+       setup_timer(&conn->info_timer, l2cap_info_timeout, (unsigned long)conn);
 
        spin_lock_init(&conn->lock);
        rwlock_init(&conn->chan_list.lock);
@@ -426,6 +417,8 @@ static void l2cap_conn_del(struct hci_conn *hcon, int err)
                l2cap_sock_kill(sk);
        }
 
+       del_timer_sync(&conn->info_timer);
+
        hcon->l2cap_data = NULL;
        kfree(conn);
 }
@@ -607,7 +600,7 @@ static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int p
 {
        struct sock *sk;
 
-       sk = sk_alloc(net, PF_BLUETOOTH, prio, &l2cap_proto, 1);
+       sk = sk_alloc(net, PF_BLUETOOTH, prio, &l2cap_proto);
        if (!sk)
                return NULL;
 
@@ -622,7 +615,7 @@ static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int p
        sk->sk_protocol = proto;
        sk->sk_state    = BT_OPEN;
 
-       l2cap_sock_init_timer(sk);
+       setup_timer(&sk->sk_timer, l2cap_sock_timeout, (unsigned long)sk);
 
        bt_sock_link(&l2cap_sk_list, sk);
        return sk;
@@ -1048,7 +1041,7 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, ch
                opts.imtu     = l2cap_pi(sk)->imtu;
                opts.omtu     = l2cap_pi(sk)->omtu;
                opts.flush_to = l2cap_pi(sk)->flush_to;
-               opts.mode     = 0x00;
+               opts.mode     = L2CAP_MODE_BASIC;
 
                len = min_t(unsigned int, sizeof(opts), optlen);
                if (copy_from_user((char *) &opts, optval, len)) {
@@ -1097,7 +1090,7 @@ static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, ch
                opts.imtu     = l2cap_pi(sk)->imtu;
                opts.omtu     = l2cap_pi(sk)->omtu;
                opts.flush_to = l2cap_pi(sk)->flush_to;
-               opts.mode     = 0x00;
+               opts.mode     = L2CAP_MODE_BASIC;
 
                len = min_t(unsigned int, len, sizeof(opts));
                if (copy_to_user(optval, (char *) &opts, len))
@@ -1376,6 +1369,7 @@ static int l2cap_parse_conf_req(struct sock *sk, void *data)
        int len = pi->conf_len;
        int type, hint, olen;
        unsigned long val;
+       struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
        u16 mtu = L2CAP_DEFAULT_MTU;
        u16 result = L2CAP_CONF_SUCCESS;
 
@@ -1399,6 +1393,11 @@ static int l2cap_parse_conf_req(struct sock *sk, void *data)
                case L2CAP_CONF_QOS:
                        break;
 
+               case L2CAP_CONF_RFC:
+                       if (olen == sizeof(rfc))
+                               memcpy(&rfc, (void *) val, olen);
+                       break;
+
                default:
                        if (hint)
                                break;
@@ -1413,14 +1412,24 @@ static int l2cap_parse_conf_req(struct sock *sk, void *data)
                /* Configure output options and let the other side know
                 * which ones we don't like. */
 
-               if (mtu < pi->omtu)
+               if (rfc.mode == L2CAP_MODE_BASIC) {
+                       if (mtu < pi->omtu)
+                               result = L2CAP_CONF_UNACCEPT;
+                       else {
+                               pi->omtu = mtu;
+                               pi->conf_state |= L2CAP_CONF_OUTPUT_DONE;
+                       }
+
+                       l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->omtu);
+               } else {
                        result = L2CAP_CONF_UNACCEPT;
-               else {
-                       pi->omtu = mtu;
-                       pi->conf_state |= L2CAP_CONF_OUTPUT_DONE;
-               }
 
-               l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->omtu);
+                       memset(&rfc, 0, sizeof(rfc));
+                       rfc.mode = L2CAP_MODE_BASIC;
+
+                       l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
+                                               sizeof(rfc), (unsigned long) &rfc);
+               }
        }
 
        rsp->scid   = cpu_to_le16(pi->dcid);