diff options
author | Gustavo F. Padovan <padovan@profusion.mobi> | 2011-04-27 17:26:32 -0400 |
---|---|---|
committer | Gustavo F. Padovan <padovan@profusion.mobi> | 2011-05-05 12:47:45 -0400 |
commit | 23691d75cdc69c3b285211b4d77746aa20a17d18 (patch) | |
tree | 32aa0e3e59dce0226242659a83698bafd6c98fc5 | |
parent | 73b2ec18532f45e9028ce4c7bc8d7f8818eabd2a (diff) |
Bluetooth: Remove l2cap_sk_list
A new list was added to replace the socket based one. This new list
doesn't depent on sock and then fits better inside l2cap_core.c code.
It also rename l2cap_chan_alloc() to l2cap_chan_create() and
l2cap_chan_free() to l2cap_chan_destroy)
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
-rw-r--r-- | include/net/bluetooth/l2cap.h | 6 | ||||
-rw-r--r-- | net/bluetooth/l2cap_core.c | 165 | ||||
-rw-r--r-- | net/bluetooth/l2cap_sock.c | 6 |
3 files changed, 95 insertions, 82 deletions
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index fb3f90eaaaa4..d09c9b1118e3 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h | |||
@@ -350,6 +350,7 @@ struct l2cap_chan { | |||
350 | struct list_head srej_l; | 350 | struct list_head srej_l; |
351 | 351 | ||
352 | struct list_head list; | 352 | struct list_head list; |
353 | struct list_head global_l; | ||
353 | }; | 354 | }; |
354 | 355 | ||
355 | struct l2cap_conn { | 356 | struct l2cap_conn { |
@@ -441,7 +442,6 @@ static inline int l2cap_tx_window_full(struct l2cap_chan *ch) | |||
441 | #define __is_sar_start(ctrl) (((ctrl) & L2CAP_CTRL_SAR) == L2CAP_SDU_START) | 442 | #define __is_sar_start(ctrl) (((ctrl) & L2CAP_CTRL_SAR) == L2CAP_SDU_START) |
442 | 443 | ||
443 | extern int disable_ertm; | 444 | extern int disable_ertm; |
444 | extern struct bt_sock_list l2cap_sk_list; | ||
445 | 445 | ||
446 | int l2cap_init_sockets(void); | 446 | int l2cap_init_sockets(void); |
447 | void l2cap_cleanup_sockets(void); | 447 | void l2cap_cleanup_sockets(void); |
@@ -469,9 +469,9 @@ void l2cap_sock_init(struct sock *sk, struct sock *parent); | |||
469 | struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, | 469 | struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, |
470 | int proto, gfp_t prio); | 470 | int proto, gfp_t prio); |
471 | void l2cap_send_disconn_req(struct l2cap_conn *conn, struct l2cap_chan *chan, int err); | 471 | void l2cap_send_disconn_req(struct l2cap_conn *conn, struct l2cap_chan *chan, int err); |
472 | struct l2cap_chan *l2cap_chan_alloc(struct sock *sk); | 472 | struct l2cap_chan *l2cap_chan_create(struct sock *sk); |
473 | void l2cap_chan_del(struct l2cap_chan *chan, int err); | 473 | void l2cap_chan_del(struct l2cap_chan *chan, int err); |
474 | void l2cap_chan_free(struct l2cap_chan *chan); | 474 | void l2cap_chan_destroy(struct l2cap_chan *chan); |
475 | int l2cap_chan_connect(struct l2cap_chan *chan); | 475 | int l2cap_chan_connect(struct l2cap_chan *chan); |
476 | 476 | ||
477 | #endif /* __L2CAP_H */ | 477 | #endif /* __L2CAP_H */ |
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 9e3f64f05d49..d0769a83cb58 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c | |||
@@ -62,9 +62,8 @@ static u8 l2cap_fixed_chan[8] = { 0x02, }; | |||
62 | 62 | ||
63 | static struct workqueue_struct *_busy_wq; | 63 | static struct workqueue_struct *_busy_wq; |
64 | 64 | ||
65 | struct bt_sock_list l2cap_sk_list = { | 65 | LIST_HEAD(chan_list); |
66 | .lock = __RW_LOCK_UNLOCKED(l2cap_sk_list.lock) | 66 | DEFINE_RWLOCK(chan_list_lock); |
67 | }; | ||
68 | 67 | ||
69 | static void l2cap_busy_work(struct work_struct *work); | 68 | static void l2cap_busy_work(struct work_struct *work); |
70 | 69 | ||
@@ -135,29 +134,27 @@ static inline struct l2cap_chan *l2cap_get_chan_by_ident(struct l2cap_conn *conn | |||
135 | return c; | 134 | return c; |
136 | } | 135 | } |
137 | 136 | ||
138 | static struct sock *__l2cap_get_sock_by_addr(__le16 psm, bdaddr_t *src) | 137 | static struct l2cap_chan *__l2cap_global_chan_by_addr(__le16 psm, bdaddr_t *src) |
139 | { | 138 | { |
140 | struct sock *sk; | 139 | struct l2cap_chan *c; |
141 | struct hlist_node *node; | ||
142 | sk_for_each(sk, node, &l2cap_sk_list.head) { | ||
143 | struct l2cap_chan *chan = l2cap_pi(sk)->chan; | ||
144 | 140 | ||
145 | if (chan->sport == psm && !bacmp(&bt_sk(sk)->src, src)) | 141 | list_for_each_entry(c, &chan_list, global_l) { |
142 | if (c->sport == psm && !bacmp(&bt_sk(c->sk)->src, src)) | ||
146 | goto found; | 143 | goto found; |
147 | } | 144 | } |
148 | 145 | ||
149 | sk = NULL; | 146 | c = NULL; |
150 | found: | 147 | found: |
151 | return sk; | 148 | return c; |
152 | } | 149 | } |
153 | 150 | ||
154 | int l2cap_add_psm(struct l2cap_chan *chan, bdaddr_t *src, __le16 psm) | 151 | int l2cap_add_psm(struct l2cap_chan *chan, bdaddr_t *src, __le16 psm) |
155 | { | 152 | { |
156 | int err; | 153 | int err; |
157 | 154 | ||
158 | write_lock_bh(&l2cap_sk_list.lock); | 155 | write_lock_bh(&chan_list_lock); |
159 | 156 | ||
160 | if (psm && __l2cap_get_sock_by_addr(psm, src)) { | 157 | if (psm && __l2cap_global_chan_by_addr(psm, src)) { |
161 | err = -EADDRINUSE; | 158 | err = -EADDRINUSE; |
162 | goto done; | 159 | goto done; |
163 | } | 160 | } |
@@ -171,7 +168,7 @@ int l2cap_add_psm(struct l2cap_chan *chan, bdaddr_t *src, __le16 psm) | |||
171 | 168 | ||
172 | err = -EINVAL; | 169 | err = -EINVAL; |
173 | for (p = 0x1001; p < 0x1100; p += 2) | 170 | for (p = 0x1001; p < 0x1100; p += 2) |
174 | if (!__l2cap_get_sock_by_addr(cpu_to_le16(p), src)) { | 171 | if (!__l2cap_global_chan_by_addr(cpu_to_le16(p), src)) { |
175 | chan->psm = cpu_to_le16(p); | 172 | chan->psm = cpu_to_le16(p); |
176 | chan->sport = cpu_to_le16(p); | 173 | chan->sport = cpu_to_le16(p); |
177 | err = 0; | 174 | err = 0; |
@@ -180,17 +177,17 @@ int l2cap_add_psm(struct l2cap_chan *chan, bdaddr_t *src, __le16 psm) | |||
180 | } | 177 | } |
181 | 178 | ||
182 | done: | 179 | done: |
183 | write_unlock_bh(&l2cap_sk_list.lock); | 180 | write_unlock_bh(&chan_list_lock); |
184 | return err; | 181 | return err; |
185 | } | 182 | } |
186 | 183 | ||
187 | int l2cap_add_scid(struct l2cap_chan *chan, __u16 scid) | 184 | int l2cap_add_scid(struct l2cap_chan *chan, __u16 scid) |
188 | { | 185 | { |
189 | write_lock_bh(&l2cap_sk_list.lock); | 186 | write_lock_bh(&chan_list_lock); |
190 | 187 | ||
191 | chan->scid = scid; | 188 | chan->scid = scid; |
192 | 189 | ||
193 | write_unlock_bh(&l2cap_sk_list.lock); | 190 | write_unlock_bh(&chan_list_lock); |
194 | 191 | ||
195 | return 0; | 192 | return 0; |
196 | } | 193 | } |
@@ -207,7 +204,7 @@ static u16 l2cap_alloc_cid(struct l2cap_conn *conn) | |||
207 | return 0; | 204 | return 0; |
208 | } | 205 | } |
209 | 206 | ||
210 | struct l2cap_chan *l2cap_chan_alloc(struct sock *sk) | 207 | struct l2cap_chan *l2cap_chan_create(struct sock *sk) |
211 | { | 208 | { |
212 | struct l2cap_chan *chan; | 209 | struct l2cap_chan *chan; |
213 | 210 | ||
@@ -217,11 +214,19 @@ struct l2cap_chan *l2cap_chan_alloc(struct sock *sk) | |||
217 | 214 | ||
218 | chan->sk = sk; | 215 | chan->sk = sk; |
219 | 216 | ||
217 | write_lock_bh(&chan_list_lock); | ||
218 | list_add(&chan->global_l, &chan_list); | ||
219 | write_unlock_bh(&chan_list_lock); | ||
220 | |||
220 | return chan; | 221 | return chan; |
221 | } | 222 | } |
222 | 223 | ||
223 | void l2cap_chan_free(struct l2cap_chan *chan) | 224 | void l2cap_chan_destroy(struct l2cap_chan *chan) |
224 | { | 225 | { |
226 | write_lock_bh(&chan_list_lock); | ||
227 | list_del(&chan->global_l); | ||
228 | write_unlock_bh(&chan_list_lock); | ||
229 | |||
225 | kfree(chan); | 230 | kfree(chan); |
226 | } | 231 | } |
227 | 232 | ||
@@ -651,48 +656,51 @@ static void l2cap_conn_start(struct l2cap_conn *conn) | |||
651 | /* Find socket with cid and source bdaddr. | 656 | /* Find socket with cid and source bdaddr. |
652 | * Returns closest match, locked. | 657 | * Returns closest match, locked. |
653 | */ | 658 | */ |
654 | static struct sock *l2cap_get_sock_by_scid(int state, __le16 cid, bdaddr_t *src) | 659 | static struct l2cap_chan *l2cap_global_chan_by_scid(int state, __le16 cid, bdaddr_t *src) |
655 | { | 660 | { |
656 | struct sock *sk = NULL, *sk1 = NULL; | 661 | struct l2cap_chan *c, *c1 = NULL; |
657 | struct hlist_node *node; | ||
658 | 662 | ||
659 | read_lock(&l2cap_sk_list.lock); | 663 | read_lock(&chan_list_lock); |
660 | 664 | ||
661 | sk_for_each(sk, node, &l2cap_sk_list.head) { | 665 | list_for_each_entry(c, &chan_list, global_l) { |
662 | struct l2cap_chan *chan = l2cap_pi(sk)->chan; | 666 | struct sock *sk = c->sk; |
663 | 667 | ||
664 | if (state && sk->sk_state != state) | 668 | if (state && sk->sk_state != state) |
665 | continue; | 669 | continue; |
666 | 670 | ||
667 | if (chan->scid == cid) { | 671 | if (c->scid == cid) { |
668 | /* Exact match. */ | 672 | /* Exact match. */ |
669 | if (!bacmp(&bt_sk(sk)->src, src)) | 673 | if (!bacmp(&bt_sk(sk)->src, src)) { |
670 | break; | 674 | read_unlock(&chan_list_lock); |
675 | return c; | ||
676 | } | ||
671 | 677 | ||
672 | /* Closest match */ | 678 | /* Closest match */ |
673 | if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) | 679 | if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) |
674 | sk1 = sk; | 680 | c1 = c; |
675 | } | 681 | } |
676 | } | 682 | } |
677 | 683 | ||
678 | read_unlock(&l2cap_sk_list.lock); | 684 | read_unlock(&chan_list_lock); |
679 | 685 | ||
680 | return node ? sk : sk1; | 686 | return c1; |
681 | } | 687 | } |
682 | 688 | ||
683 | static void l2cap_le_conn_ready(struct l2cap_conn *conn) | 689 | static void l2cap_le_conn_ready(struct l2cap_conn *conn) |
684 | { | 690 | { |
685 | struct sock *parent, *sk; | 691 | struct sock *parent, *sk; |
686 | struct l2cap_chan *chan; | 692 | struct l2cap_chan *chan, *pchan; |
687 | 693 | ||
688 | BT_DBG(""); | 694 | BT_DBG(""); |
689 | 695 | ||
690 | /* Check if we have socket listening on cid */ | 696 | /* Check if we have socket listening on cid */ |
691 | parent = l2cap_get_sock_by_scid(BT_LISTEN, L2CAP_CID_LE_DATA, | 697 | pchan = l2cap_global_chan_by_scid(BT_LISTEN, L2CAP_CID_LE_DATA, |
692 | conn->src); | 698 | conn->src); |
693 | if (!parent) | 699 | if (!pchan) |
694 | return; | 700 | return; |
695 | 701 | ||
702 | parent = pchan->sk; | ||
703 | |||
696 | bh_lock_sock(parent); | 704 | bh_lock_sock(parent); |
697 | 705 | ||
698 | /* Check for backlog size */ | 706 | /* Check for backlog size */ |
@@ -705,7 +713,7 @@ static void l2cap_le_conn_ready(struct l2cap_conn *conn) | |||
705 | if (!sk) | 713 | if (!sk) |
706 | goto clean; | 714 | goto clean; |
707 | 715 | ||
708 | chan = l2cap_chan_alloc(sk); | 716 | chan = l2cap_chan_create(sk); |
709 | if (!chan) { | 717 | if (!chan) { |
710 | l2cap_sock_kill(sk); | 718 | l2cap_sock_kill(sk); |
711 | goto clean; | 719 | goto clean; |
@@ -883,33 +891,34 @@ static inline void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *ch | |||
883 | /* Find socket with psm and source bdaddr. | 891 | /* Find socket with psm and source bdaddr. |
884 | * Returns closest match. | 892 | * Returns closest match. |
885 | */ | 893 | */ |
886 | static struct sock *l2cap_get_sock_by_psm(int state, __le16 psm, bdaddr_t *src) | 894 | static struct l2cap_chan *l2cap_global_chan_by_psm(int state, __le16 psm, bdaddr_t *src) |
887 | { | 895 | { |
888 | struct sock *sk = NULL, *sk1 = NULL; | 896 | struct l2cap_chan *c, *c1 = NULL; |
889 | struct hlist_node *node; | ||
890 | 897 | ||
891 | read_lock(&l2cap_sk_list.lock); | 898 | read_lock(&chan_list_lock); |
892 | 899 | ||
893 | sk_for_each(sk, node, &l2cap_sk_list.head) { | 900 | list_for_each_entry(c, &chan_list, global_l) { |
894 | struct l2cap_chan *chan = l2cap_pi(sk)->chan; | 901 | struct sock *sk = c->sk; |
895 | 902 | ||
896 | if (state && sk->sk_state != state) | 903 | if (state && sk->sk_state != state) |
897 | continue; | 904 | continue; |
898 | 905 | ||
899 | if (chan->psm == psm) { | 906 | if (c->psm == psm) { |
900 | /* Exact match. */ | 907 | /* Exact match. */ |
901 | if (!bacmp(&bt_sk(sk)->src, src)) | 908 | if (!bacmp(&bt_sk(sk)->src, src)) { |
902 | break; | 909 | read_unlock_bh(&chan_list_lock); |
910 | return c; | ||
911 | } | ||
903 | 912 | ||
904 | /* Closest match */ | 913 | /* Closest match */ |
905 | if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) | 914 | if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) |
906 | sk1 = sk; | 915 | c1 = c; |
907 | } | 916 | } |
908 | } | 917 | } |
909 | 918 | ||
910 | read_unlock(&l2cap_sk_list.lock); | 919 | read_unlock(&chan_list_lock); |
911 | 920 | ||
912 | return node ? sk : sk1; | 921 | return c1; |
913 | } | 922 | } |
914 | 923 | ||
915 | int l2cap_chan_connect(struct l2cap_chan *chan) | 924 | int l2cap_chan_connect(struct l2cap_chan *chan) |
@@ -2079,22 +2088,26 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd | |||
2079 | { | 2088 | { |
2080 | struct l2cap_conn_req *req = (struct l2cap_conn_req *) data; | 2089 | struct l2cap_conn_req *req = (struct l2cap_conn_req *) data; |
2081 | struct l2cap_conn_rsp rsp; | 2090 | struct l2cap_conn_rsp rsp; |
2082 | struct l2cap_chan *chan = NULL; | 2091 | struct l2cap_chan *chan = NULL, *pchan; |
2083 | struct sock *parent, *sk = NULL; | 2092 | struct sock *parent, *sk = NULL; |
2084 | int result, status = L2CAP_CS_NO_INFO; | 2093 | int result, status = L2CAP_CS_NO_INFO; |
2085 | 2094 | ||
2086 | u16 dcid = 0, scid = __le16_to_cpu(req->scid); | 2095 | u16 dcid = 0, scid = __le16_to_cpu(req->scid); |
2087 | __le16 psm = req->psm; | 2096 | __le16 psm = req->psm; |
2088 | 2097 | ||
2089 | BT_DBG("psm 0x%2.2x scid 0x%4.4x", psm, scid); | 2098 | BT_ERR("psm 0x%2.2x scid 0x%4.4x", psm, scid); |
2090 | 2099 | ||
2091 | /* Check if we have socket listening on psm */ | 2100 | /* Check if we have socket listening on psm */ |
2092 | parent = l2cap_get_sock_by_psm(BT_LISTEN, psm, conn->src); | 2101 | pchan = l2cap_global_chan_by_psm(BT_LISTEN, psm, conn->src); |
2093 | if (!parent) { | 2102 | if (!pchan) { |
2094 | result = L2CAP_CR_BAD_PSM; | 2103 | result = L2CAP_CR_BAD_PSM; |
2095 | goto sendresp; | 2104 | goto sendresp; |
2096 | } | 2105 | } |
2097 | 2106 | ||
2107 | BT_ERR("%p 0x%2.2x", pchan, pchan->psm); | ||
2108 | |||
2109 | parent = pchan->sk; | ||
2110 | |||
2098 | bh_lock_sock(parent); | 2111 | bh_lock_sock(parent); |
2099 | 2112 | ||
2100 | /* Check if the ACL is secure enough (if not SDP) */ | 2113 | /* Check if the ACL is secure enough (if not SDP) */ |
@@ -2117,7 +2130,7 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd | |||
2117 | if (!sk) | 2130 | if (!sk) |
2118 | goto response; | 2131 | goto response; |
2119 | 2132 | ||
2120 | chan = l2cap_chan_alloc(sk); | 2133 | chan = l2cap_chan_create(sk); |
2121 | if (!chan) { | 2134 | if (!chan) { |
2122 | l2cap_sock_kill(sk); | 2135 | l2cap_sock_kill(sk); |
2123 | goto response; | 2136 | goto response; |
@@ -3745,11 +3758,14 @@ done: | |||
3745 | static inline int l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, struct sk_buff *skb) | 3758 | static inline int l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, struct sk_buff *skb) |
3746 | { | 3759 | { |
3747 | struct sock *sk; | 3760 | struct sock *sk; |
3761 | struct l2cap_chan *chan; | ||
3748 | 3762 | ||
3749 | sk = l2cap_get_sock_by_psm(0, psm, conn->src); | 3763 | chan = l2cap_global_chan_by_psm(0, psm, conn->src); |
3750 | if (!sk) | 3764 | if (!chan) |
3751 | goto drop; | 3765 | goto drop; |
3752 | 3766 | ||
3767 | sk = chan->sk; | ||
3768 | |||
3753 | bh_lock_sock(sk); | 3769 | bh_lock_sock(sk); |
3754 | 3770 | ||
3755 | BT_DBG("sk %p, len %d", sk, skb->len); | 3771 | BT_DBG("sk %p, len %d", sk, skb->len); |
@@ -3775,11 +3791,14 @@ done: | |||
3775 | static inline int l2cap_att_channel(struct l2cap_conn *conn, __le16 cid, struct sk_buff *skb) | 3791 | static inline int l2cap_att_channel(struct l2cap_conn *conn, __le16 cid, struct sk_buff *skb) |
3776 | { | 3792 | { |
3777 | struct sock *sk; | 3793 | struct sock *sk; |
3794 | struct l2cap_chan *chan; | ||
3778 | 3795 | ||
3779 | sk = l2cap_get_sock_by_scid(0, cid, conn->src); | 3796 | chan = l2cap_global_chan_by_scid(0, cid, conn->src); |
3780 | if (!sk) | 3797 | if (!chan) |
3781 | goto drop; | 3798 | goto drop; |
3782 | 3799 | ||
3800 | sk = chan->sk; | ||
3801 | |||
3783 | bh_lock_sock(sk); | 3802 | bh_lock_sock(sk); |
3784 | 3803 | ||
3785 | BT_DBG("sk %p, len %d", sk, skb->len); | 3804 | BT_DBG("sk %p, len %d", sk, skb->len); |
@@ -3846,8 +3865,7 @@ static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb) | |||
3846 | static int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type) | 3865 | static int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type) |
3847 | { | 3866 | { |
3848 | int exact = 0, lm1 = 0, lm2 = 0; | 3867 | int exact = 0, lm1 = 0, lm2 = 0; |
3849 | register struct sock *sk; | 3868 | struct l2cap_chan *c; |
3850 | struct hlist_node *node; | ||
3851 | 3869 | ||
3852 | if (type != ACL_LINK) | 3870 | if (type != ACL_LINK) |
3853 | return -EINVAL; | 3871 | return -EINVAL; |
@@ -3855,25 +3873,25 @@ static int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type) | |||
3855 | BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr)); | 3873 | BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr)); |
3856 | 3874 | ||
3857 | /* Find listening sockets and check their link_mode */ | 3875 | /* Find listening sockets and check their link_mode */ |
3858 | read_lock(&l2cap_sk_list.lock); | 3876 | read_lock(&chan_list_lock); |
3859 | sk_for_each(sk, node, &l2cap_sk_list.head) { | 3877 | list_for_each_entry(c, &chan_list, global_l) { |
3860 | struct l2cap_chan *chan = l2cap_pi(sk)->chan; | 3878 | struct sock *sk = c->sk; |
3861 | 3879 | ||
3862 | if (sk->sk_state != BT_LISTEN) | 3880 | if (sk->sk_state != BT_LISTEN) |
3863 | continue; | 3881 | continue; |
3864 | 3882 | ||
3865 | if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr)) { | 3883 | if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr)) { |
3866 | lm1 |= HCI_LM_ACCEPT; | 3884 | lm1 |= HCI_LM_ACCEPT; |
3867 | if (chan->role_switch) | 3885 | if (c->role_switch) |
3868 | lm1 |= HCI_LM_MASTER; | 3886 | lm1 |= HCI_LM_MASTER; |
3869 | exact++; | 3887 | exact++; |
3870 | } else if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) { | 3888 | } else if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) { |
3871 | lm2 |= HCI_LM_ACCEPT; | 3889 | lm2 |= HCI_LM_ACCEPT; |
3872 | if (chan->role_switch) | 3890 | if (c->role_switch) |
3873 | lm2 |= HCI_LM_MASTER; | 3891 | lm2 |= HCI_LM_MASTER; |
3874 | } | 3892 | } |
3875 | } | 3893 | } |
3876 | read_unlock(&l2cap_sk_list.lock); | 3894 | read_unlock(&chan_list_lock); |
3877 | 3895 | ||
3878 | return exact ? lm1 : lm2; | 3896 | return exact ? lm1 : lm2; |
3879 | } | 3897 | } |
@@ -4126,25 +4144,22 @@ drop: | |||
4126 | 4144 | ||
4127 | static int l2cap_debugfs_show(struct seq_file *f, void *p) | 4145 | static int l2cap_debugfs_show(struct seq_file *f, void *p) |
4128 | { | 4146 | { |
4129 | struct sock *sk; | 4147 | struct l2cap_chan *c; |
4130 | struct hlist_node *node; | ||
4131 | 4148 | ||
4132 | read_lock_bh(&l2cap_sk_list.lock); | 4149 | read_lock_bh(&chan_list_lock); |
4133 | 4150 | ||
4134 | sk_for_each(sk, node, &l2cap_sk_list.head) { | 4151 | list_for_each_entry(c, &chan_list, global_l) { |
4135 | struct l2cap_pinfo *pi = l2cap_pi(sk); | 4152 | struct sock *sk = c->sk; |
4136 | struct l2cap_chan *chan = pi->chan; | ||
4137 | 4153 | ||
4138 | seq_printf(f, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d %d %d\n", | 4154 | seq_printf(f, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d %d %d\n", |
4139 | batostr(&bt_sk(sk)->src), | 4155 | batostr(&bt_sk(sk)->src), |
4140 | batostr(&bt_sk(sk)->dst), | 4156 | batostr(&bt_sk(sk)->dst), |
4141 | sk->sk_state, __le16_to_cpu(chan->psm), | 4157 | sk->sk_state, __le16_to_cpu(c->psm), |
4142 | chan->scid, chan->dcid, | 4158 | c->scid, c->dcid, c->imtu, c->omtu, |
4143 | chan->imtu, chan->omtu, chan->sec_level, | 4159 | c->sec_level, c->mode); |
4144 | chan->mode); | ||
4145 | } | 4160 | } |
4146 | 4161 | ||
4147 | read_unlock_bh(&l2cap_sk_list.lock); | 4162 | read_unlock_bh(&chan_list_lock); |
4148 | 4163 | ||
4149 | return 0; | 4164 | return 0; |
4150 | } | 4165 | } |
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index aca99cd5377d..c98360d40b84 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c | |||
@@ -808,8 +808,7 @@ void l2cap_sock_kill(struct sock *sk) | |||
808 | 808 | ||
809 | /* Kill poor orphan */ | 809 | /* Kill poor orphan */ |
810 | 810 | ||
811 | l2cap_chan_free(l2cap_pi(sk)->chan); | 811 | l2cap_chan_destroy(l2cap_pi(sk)->chan); |
812 | bt_sock_unlink(&l2cap_sk_list, sk); | ||
813 | sock_set_flag(sk, SOCK_DEAD); | 812 | sock_set_flag(sk, SOCK_DEAD); |
814 | sock_put(sk); | 813 | sock_put(sk); |
815 | } | 814 | } |
@@ -1025,7 +1024,6 @@ struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int proto, g | |||
1025 | 1024 | ||
1026 | setup_timer(&sk->sk_timer, l2cap_sock_timeout, (unsigned long) sk); | 1025 | setup_timer(&sk->sk_timer, l2cap_sock_timeout, (unsigned long) sk); |
1027 | 1026 | ||
1028 | bt_sock_link(&l2cap_sk_list, sk); | ||
1029 | return sk; | 1027 | return sk; |
1030 | } | 1028 | } |
1031 | 1029 | ||
@@ -1052,7 +1050,7 @@ static int l2cap_sock_create(struct net *net, struct socket *sock, int protocol, | |||
1052 | if (!sk) | 1050 | if (!sk) |
1053 | return -ENOMEM; | 1051 | return -ENOMEM; |
1054 | 1052 | ||
1055 | chan = l2cap_chan_alloc(sk); | 1053 | chan = l2cap_chan_create(sk); |
1056 | if (!chan) { | 1054 | if (!chan) { |
1057 | l2cap_sock_kill(sk); | 1055 | l2cap_sock_kill(sk); |
1058 | return -ENOMEM; | 1056 | return -ENOMEM; |