diff options
Diffstat (limited to 'net/bluetooth/l2cap.c')
| -rw-r--r-- | net/bluetooth/l2cap.c | 376 |
1 files changed, 186 insertions, 190 deletions
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c index f6b4a8085357..d56f60b392ac 100644 --- a/net/bluetooth/l2cap.c +++ b/net/bluetooth/l2cap.c | |||
| @@ -24,7 +24,6 @@ | |||
| 24 | 24 | ||
| 25 | /* Bluetooth L2CAP core and sockets. */ | 25 | /* Bluetooth L2CAP core and sockets. */ |
| 26 | 26 | ||
| 27 | #include <linux/config.h> | ||
| 28 | #include <linux/module.h> | 27 | #include <linux/module.h> |
| 29 | 28 | ||
| 30 | #include <linux/types.h> | 29 | #include <linux/types.h> |
| @@ -64,11 +63,6 @@ static struct bt_sock_list l2cap_sk_list = { | |||
| 64 | .lock = RW_LOCK_UNLOCKED | 63 | .lock = RW_LOCK_UNLOCKED |
| 65 | }; | 64 | }; |
| 66 | 65 | ||
| 67 | static int l2cap_conn_del(struct hci_conn *conn, int err); | ||
| 68 | |||
| 69 | static void __l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent); | ||
| 70 | static void l2cap_chan_del(struct sock *sk, int err); | ||
| 71 | |||
| 72 | static void __l2cap_sock_close(struct sock *sk, int reason); | 66 | static void __l2cap_sock_close(struct sock *sk, int reason); |
| 73 | static void l2cap_sock_close(struct sock *sk); | 67 | static void l2cap_sock_close(struct sock *sk); |
| 74 | static void l2cap_sock_kill(struct sock *sk); | 68 | static void l2cap_sock_kill(struct sock *sk); |
| @@ -110,24 +104,177 @@ static void l2cap_sock_init_timer(struct sock *sk) | |||
| 110 | sk->sk_timer.data = (unsigned long)sk; | 104 | sk->sk_timer.data = (unsigned long)sk; |
| 111 | } | 105 | } |
| 112 | 106 | ||
| 107 | /* ---- L2CAP channels ---- */ | ||
| 108 | static struct sock *__l2cap_get_chan_by_dcid(struct l2cap_chan_list *l, u16 cid) | ||
| 109 | { | ||
| 110 | struct sock *s; | ||
| 111 | for (s = l->head; s; s = l2cap_pi(s)->next_c) { | ||
| 112 | if (l2cap_pi(s)->dcid == cid) | ||
| 113 | break; | ||
| 114 | } | ||
| 115 | return s; | ||
| 116 | } | ||
| 117 | |||
| 118 | static struct sock *__l2cap_get_chan_by_scid(struct l2cap_chan_list *l, u16 cid) | ||
| 119 | { | ||
| 120 | struct sock *s; | ||
| 121 | for (s = l->head; s; s = l2cap_pi(s)->next_c) { | ||
| 122 | if (l2cap_pi(s)->scid == cid) | ||
| 123 | break; | ||
| 124 | } | ||
| 125 | return s; | ||
| 126 | } | ||
| 127 | |||
| 128 | /* Find channel with given SCID. | ||
| 129 | * Returns locked socket */ | ||
| 130 | static inline struct sock *l2cap_get_chan_by_scid(struct l2cap_chan_list *l, u16 cid) | ||
| 131 | { | ||
| 132 | struct sock *s; | ||
| 133 | read_lock(&l->lock); | ||
| 134 | s = __l2cap_get_chan_by_scid(l, cid); | ||
| 135 | if (s) bh_lock_sock(s); | ||
| 136 | read_unlock(&l->lock); | ||
| 137 | return s; | ||
| 138 | } | ||
| 139 | |||
| 140 | static struct sock *__l2cap_get_chan_by_ident(struct l2cap_chan_list *l, u8 ident) | ||
| 141 | { | ||
| 142 | struct sock *s; | ||
| 143 | for (s = l->head; s; s = l2cap_pi(s)->next_c) { | ||
| 144 | if (l2cap_pi(s)->ident == ident) | ||
| 145 | break; | ||
| 146 | } | ||
| 147 | return s; | ||
| 148 | } | ||
| 149 | |||
| 150 | static inline struct sock *l2cap_get_chan_by_ident(struct l2cap_chan_list *l, u8 ident) | ||
| 151 | { | ||
| 152 | struct sock *s; | ||
| 153 | read_lock(&l->lock); | ||
| 154 | s = __l2cap_get_chan_by_ident(l, ident); | ||
| 155 | if (s) bh_lock_sock(s); | ||
| 156 | read_unlock(&l->lock); | ||
| 157 | return s; | ||
| 158 | } | ||
| 159 | |||
| 160 | static u16 l2cap_alloc_cid(struct l2cap_chan_list *l) | ||
| 161 | { | ||
| 162 | u16 cid = 0x0040; | ||
| 163 | |||
| 164 | for (; cid < 0xffff; cid++) { | ||
| 165 | if(!__l2cap_get_chan_by_scid(l, cid)) | ||
| 166 | return cid; | ||
| 167 | } | ||
| 168 | |||
| 169 | return 0; | ||
| 170 | } | ||
| 171 | |||
| 172 | static inline void __l2cap_chan_link(struct l2cap_chan_list *l, struct sock *sk) | ||
| 173 | { | ||
| 174 | sock_hold(sk); | ||
| 175 | |||
| 176 | if (l->head) | ||
| 177 | l2cap_pi(l->head)->prev_c = sk; | ||
| 178 | |||
| 179 | l2cap_pi(sk)->next_c = l->head; | ||
| 180 | l2cap_pi(sk)->prev_c = NULL; | ||
| 181 | l->head = sk; | ||
| 182 | } | ||
| 183 | |||
| 184 | static inline void l2cap_chan_unlink(struct l2cap_chan_list *l, struct sock *sk) | ||
| 185 | { | ||
| 186 | struct sock *next = l2cap_pi(sk)->next_c, *prev = l2cap_pi(sk)->prev_c; | ||
| 187 | |||
| 188 | write_lock_bh(&l->lock); | ||
| 189 | if (sk == l->head) | ||
| 190 | l->head = next; | ||
| 191 | |||
| 192 | if (next) | ||
| 193 | l2cap_pi(next)->prev_c = prev; | ||
| 194 | if (prev) | ||
| 195 | l2cap_pi(prev)->next_c = next; | ||
| 196 | write_unlock_bh(&l->lock); | ||
| 197 | |||
| 198 | __sock_put(sk); | ||
| 199 | } | ||
| 200 | |||
| 201 | static void __l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent) | ||
| 202 | { | ||
| 203 | struct l2cap_chan_list *l = &conn->chan_list; | ||
| 204 | |||
| 205 | BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn, l2cap_pi(sk)->psm, l2cap_pi(sk)->dcid); | ||
| 206 | |||
| 207 | l2cap_pi(sk)->conn = conn; | ||
| 208 | |||
| 209 | if (sk->sk_type == SOCK_SEQPACKET) { | ||
| 210 | /* Alloc CID for connection-oriented socket */ | ||
| 211 | l2cap_pi(sk)->scid = l2cap_alloc_cid(l); | ||
| 212 | } else if (sk->sk_type == SOCK_DGRAM) { | ||
| 213 | /* Connectionless socket */ | ||
| 214 | l2cap_pi(sk)->scid = 0x0002; | ||
| 215 | l2cap_pi(sk)->dcid = 0x0002; | ||
| 216 | l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU; | ||
| 217 | } else { | ||
| 218 | /* Raw socket can send/recv signalling messages only */ | ||
| 219 | l2cap_pi(sk)->scid = 0x0001; | ||
| 220 | l2cap_pi(sk)->dcid = 0x0001; | ||
| 221 | l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU; | ||
| 222 | } | ||
| 223 | |||
| 224 | __l2cap_chan_link(l, sk); | ||
| 225 | |||
| 226 | if (parent) | ||
| 227 | bt_accept_enqueue(parent, sk); | ||
| 228 | } | ||
| 229 | |||
| 230 | /* Delete channel. | ||
| 231 | * Must be called on the locked socket. */ | ||
| 232 | static void l2cap_chan_del(struct sock *sk, int err) | ||
| 233 | { | ||
| 234 | struct l2cap_conn *conn = l2cap_pi(sk)->conn; | ||
| 235 | struct sock *parent = bt_sk(sk)->parent; | ||
| 236 | |||
| 237 | l2cap_sock_clear_timer(sk); | ||
| 238 | |||
| 239 | BT_DBG("sk %p, conn %p, err %d", sk, conn, err); | ||
| 240 | |||
| 241 | if (conn) { | ||
| 242 | /* Unlink from channel list */ | ||
| 243 | l2cap_chan_unlink(&conn->chan_list, sk); | ||
| 244 | l2cap_pi(sk)->conn = NULL; | ||
| 245 | hci_conn_put(conn->hcon); | ||
| 246 | } | ||
| 247 | |||
| 248 | sk->sk_state = BT_CLOSED; | ||
| 249 | sock_set_flag(sk, SOCK_ZAPPED); | ||
| 250 | |||
| 251 | if (err) | ||
| 252 | sk->sk_err = err; | ||
| 253 | |||
| 254 | if (parent) { | ||
| 255 | bt_accept_unlink(sk); | ||
| 256 | parent->sk_data_ready(parent, 0); | ||
| 257 | } else | ||
| 258 | sk->sk_state_change(sk); | ||
| 259 | } | ||
| 260 | |||
| 113 | /* ---- L2CAP connections ---- */ | 261 | /* ---- L2CAP connections ---- */ |
| 114 | static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status) | 262 | static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status) |
| 115 | { | 263 | { |
| 116 | struct l2cap_conn *conn; | 264 | struct l2cap_conn *conn = hcon->l2cap_data; |
| 117 | |||
| 118 | if ((conn = hcon->l2cap_data)) | ||
| 119 | return conn; | ||
| 120 | 265 | ||
| 121 | if (status) | 266 | if (conn || status) |
| 122 | return conn; | 267 | return conn; |
| 123 | 268 | ||
| 124 | if (!(conn = kmalloc(sizeof(struct l2cap_conn), GFP_ATOMIC))) | 269 | conn = kzalloc(sizeof(struct l2cap_conn), GFP_ATOMIC); |
| 270 | if (!conn) | ||
| 125 | return NULL; | 271 | return NULL; |
| 126 | memset(conn, 0, sizeof(struct l2cap_conn)); | ||
| 127 | 272 | ||
| 128 | hcon->l2cap_data = conn; | 273 | hcon->l2cap_data = conn; |
| 129 | conn->hcon = hcon; | 274 | conn->hcon = hcon; |
| 130 | 275 | ||
| 276 | BT_DBG("hcon %p conn %p", hcon, conn); | ||
| 277 | |||
| 131 | conn->mtu = hcon->hdev->acl_mtu; | 278 | conn->mtu = hcon->hdev->acl_mtu; |
| 132 | conn->src = &hcon->hdev->bdaddr; | 279 | conn->src = &hcon->hdev->bdaddr; |
| 133 | conn->dst = &hcon->dst; | 280 | conn->dst = &hcon->dst; |
| @@ -135,17 +282,16 @@ static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status) | |||
| 135 | spin_lock_init(&conn->lock); | 282 | spin_lock_init(&conn->lock); |
| 136 | rwlock_init(&conn->chan_list.lock); | 283 | rwlock_init(&conn->chan_list.lock); |
| 137 | 284 | ||
| 138 | BT_DBG("hcon %p conn %p", hcon, conn); | ||
| 139 | return conn; | 285 | return conn; |
| 140 | } | 286 | } |
| 141 | 287 | ||
| 142 | static int l2cap_conn_del(struct hci_conn *hcon, int err) | 288 | static void l2cap_conn_del(struct hci_conn *hcon, int err) |
| 143 | { | 289 | { |
| 144 | struct l2cap_conn *conn; | 290 | struct l2cap_conn *conn = hcon->l2cap_data; |
| 145 | struct sock *sk; | 291 | struct sock *sk; |
| 146 | 292 | ||
| 147 | if (!(conn = hcon->l2cap_data)) | 293 | if (!conn) |
| 148 | return 0; | 294 | return; |
| 149 | 295 | ||
| 150 | BT_DBG("hcon %p conn %p, err %d", hcon, conn, err); | 296 | BT_DBG("hcon %p conn %p, err %d", hcon, conn, err); |
| 151 | 297 | ||
| @@ -162,15 +308,14 @@ static int l2cap_conn_del(struct hci_conn *hcon, int err) | |||
| 162 | 308 | ||
| 163 | hcon->l2cap_data = NULL; | 309 | hcon->l2cap_data = NULL; |
| 164 | kfree(conn); | 310 | kfree(conn); |
| 165 | return 0; | ||
| 166 | } | 311 | } |
| 167 | 312 | ||
| 168 | static inline void l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent) | 313 | static inline void l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent) |
| 169 | { | 314 | { |
| 170 | struct l2cap_chan_list *l = &conn->chan_list; | 315 | struct l2cap_chan_list *l = &conn->chan_list; |
| 171 | write_lock(&l->lock); | 316 | write_lock_bh(&l->lock); |
| 172 | __l2cap_chan_add(conn, sk, parent); | 317 | __l2cap_chan_add(conn, sk, parent); |
| 173 | write_unlock(&l->lock); | 318 | write_unlock_bh(&l->lock); |
| 174 | } | 319 | } |
| 175 | 320 | ||
| 176 | static inline u8 l2cap_get_ident(struct l2cap_conn *conn) | 321 | static inline u8 l2cap_get_ident(struct l2cap_conn *conn) |
| @@ -183,14 +328,14 @@ static inline u8 l2cap_get_ident(struct l2cap_conn *conn) | |||
| 183 | * 200 - 254 are used by utilities like l2ping, etc. | 328 | * 200 - 254 are used by utilities like l2ping, etc. |
| 184 | */ | 329 | */ |
| 185 | 330 | ||
| 186 | spin_lock(&conn->lock); | 331 | spin_lock_bh(&conn->lock); |
| 187 | 332 | ||
| 188 | if (++conn->tx_ident > 128) | 333 | if (++conn->tx_ident > 128) |
| 189 | conn->tx_ident = 1; | 334 | conn->tx_ident = 1; |
| 190 | 335 | ||
| 191 | id = conn->tx_ident; | 336 | id = conn->tx_ident; |
| 192 | 337 | ||
| 193 | spin_unlock(&conn->lock); | 338 | spin_unlock_bh(&conn->lock); |
| 194 | 339 | ||
| 195 | return id; | 340 | return id; |
| 196 | } | 341 | } |
| @@ -926,160 +1071,6 @@ static int l2cap_sock_release(struct socket *sock) | |||
| 926 | return err; | 1071 | return err; |
| 927 | } | 1072 | } |
| 928 | 1073 | ||
| 929 | /* ---- L2CAP channels ---- */ | ||
| 930 | static struct sock *__l2cap_get_chan_by_dcid(struct l2cap_chan_list *l, u16 cid) | ||
| 931 | { | ||
| 932 | struct sock *s; | ||
| 933 | for (s = l->head; s; s = l2cap_pi(s)->next_c) { | ||
| 934 | if (l2cap_pi(s)->dcid == cid) | ||
| 935 | break; | ||
| 936 | } | ||
| 937 | return s; | ||
| 938 | } | ||
| 939 | |||
| 940 | static struct sock *__l2cap_get_chan_by_scid(struct l2cap_chan_list *l, u16 cid) | ||
| 941 | { | ||
| 942 | struct sock *s; | ||
| 943 | for (s = l->head; s; s = l2cap_pi(s)->next_c) { | ||
| 944 | if (l2cap_pi(s)->scid == cid) | ||
| 945 | break; | ||
| 946 | } | ||
| 947 | return s; | ||
| 948 | } | ||
| 949 | |||
| 950 | /* Find channel with given SCID. | ||
| 951 | * Returns locked socket */ | ||
| 952 | static inline struct sock *l2cap_get_chan_by_scid(struct l2cap_chan_list *l, u16 cid) | ||
| 953 | { | ||
| 954 | struct sock *s; | ||
| 955 | read_lock(&l->lock); | ||
| 956 | s = __l2cap_get_chan_by_scid(l, cid); | ||
| 957 | if (s) bh_lock_sock(s); | ||
| 958 | read_unlock(&l->lock); | ||
| 959 | return s; | ||
| 960 | } | ||
| 961 | |||
| 962 | static struct sock *__l2cap_get_chan_by_ident(struct l2cap_chan_list *l, u8 ident) | ||
| 963 | { | ||
| 964 | struct sock *s; | ||
| 965 | for (s = l->head; s; s = l2cap_pi(s)->next_c) { | ||
| 966 | if (l2cap_pi(s)->ident == ident) | ||
| 967 | break; | ||
| 968 | } | ||
| 969 | return s; | ||
| 970 | } | ||
| 971 | |||
| 972 | static inline struct sock *l2cap_get_chan_by_ident(struct l2cap_chan_list *l, u8 ident) | ||
| 973 | { | ||
| 974 | struct sock *s; | ||
| 975 | read_lock(&l->lock); | ||
| 976 | s = __l2cap_get_chan_by_ident(l, ident); | ||
| 977 | if (s) bh_lock_sock(s); | ||
| 978 | read_unlock(&l->lock); | ||
| 979 | return s; | ||
| 980 | } | ||
| 981 | |||
| 982 | static u16 l2cap_alloc_cid(struct l2cap_chan_list *l) | ||
| 983 | { | ||
| 984 | u16 cid = 0x0040; | ||
| 985 | |||
| 986 | for (; cid < 0xffff; cid++) { | ||
| 987 | if(!__l2cap_get_chan_by_scid(l, cid)) | ||
| 988 | return cid; | ||
| 989 | } | ||
| 990 | |||
| 991 | return 0; | ||
| 992 | } | ||
| 993 | |||
| 994 | static inline void __l2cap_chan_link(struct l2cap_chan_list *l, struct sock *sk) | ||
| 995 | { | ||
| 996 | sock_hold(sk); | ||
| 997 | |||
| 998 | if (l->head) | ||
| 999 | l2cap_pi(l->head)->prev_c = sk; | ||
| 1000 | |||
| 1001 | l2cap_pi(sk)->next_c = l->head; | ||
| 1002 | l2cap_pi(sk)->prev_c = NULL; | ||
| 1003 | l->head = sk; | ||
| 1004 | } | ||
| 1005 | |||
| 1006 | static inline void l2cap_chan_unlink(struct l2cap_chan_list *l, struct sock *sk) | ||
| 1007 | { | ||
| 1008 | struct sock *next = l2cap_pi(sk)->next_c, *prev = l2cap_pi(sk)->prev_c; | ||
| 1009 | |||
| 1010 | write_lock(&l->lock); | ||
| 1011 | if (sk == l->head) | ||
| 1012 | l->head = next; | ||
| 1013 | |||
| 1014 | if (next) | ||
| 1015 | l2cap_pi(next)->prev_c = prev; | ||
| 1016 | if (prev) | ||
| 1017 | l2cap_pi(prev)->next_c = next; | ||
| 1018 | write_unlock(&l->lock); | ||
| 1019 | |||
| 1020 | __sock_put(sk); | ||
| 1021 | } | ||
| 1022 | |||
| 1023 | static void __l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent) | ||
| 1024 | { | ||
| 1025 | struct l2cap_chan_list *l = &conn->chan_list; | ||
| 1026 | |||
| 1027 | BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn, l2cap_pi(sk)->psm, l2cap_pi(sk)->dcid); | ||
| 1028 | |||
| 1029 | l2cap_pi(sk)->conn = conn; | ||
| 1030 | |||
| 1031 | if (sk->sk_type == SOCK_SEQPACKET) { | ||
| 1032 | /* Alloc CID for connection-oriented socket */ | ||
| 1033 | l2cap_pi(sk)->scid = l2cap_alloc_cid(l); | ||
| 1034 | } else if (sk->sk_type == SOCK_DGRAM) { | ||
| 1035 | /* Connectionless socket */ | ||
| 1036 | l2cap_pi(sk)->scid = 0x0002; | ||
| 1037 | l2cap_pi(sk)->dcid = 0x0002; | ||
| 1038 | l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU; | ||
| 1039 | } else { | ||
| 1040 | /* Raw socket can send/recv signalling messages only */ | ||
| 1041 | l2cap_pi(sk)->scid = 0x0001; | ||
| 1042 | l2cap_pi(sk)->dcid = 0x0001; | ||
| 1043 | l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU; | ||
| 1044 | } | ||
| 1045 | |||
| 1046 | __l2cap_chan_link(l, sk); | ||
| 1047 | |||
| 1048 | if (parent) | ||
| 1049 | bt_accept_enqueue(parent, sk); | ||
| 1050 | } | ||
| 1051 | |||
| 1052 | /* Delete channel. | ||
| 1053 | * Must be called on the locked socket. */ | ||
| 1054 | static void l2cap_chan_del(struct sock *sk, int err) | ||
| 1055 | { | ||
| 1056 | struct l2cap_conn *conn = l2cap_pi(sk)->conn; | ||
| 1057 | struct sock *parent = bt_sk(sk)->parent; | ||
| 1058 | |||
| 1059 | l2cap_sock_clear_timer(sk); | ||
| 1060 | |||
| 1061 | BT_DBG("sk %p, conn %p, err %d", sk, conn, err); | ||
| 1062 | |||
| 1063 | if (conn) { | ||
| 1064 | /* Unlink from channel list */ | ||
| 1065 | l2cap_chan_unlink(&conn->chan_list, sk); | ||
| 1066 | l2cap_pi(sk)->conn = NULL; | ||
| 1067 | hci_conn_put(conn->hcon); | ||
| 1068 | } | ||
| 1069 | |||
| 1070 | sk->sk_state = BT_CLOSED; | ||
| 1071 | sock_set_flag(sk, SOCK_ZAPPED); | ||
| 1072 | |||
| 1073 | if (err) | ||
| 1074 | sk->sk_err = err; | ||
| 1075 | |||
| 1076 | if (parent) { | ||
| 1077 | bt_accept_unlink(sk); | ||
| 1078 | parent->sk_data_ready(parent, 0); | ||
| 1079 | } else | ||
| 1080 | sk->sk_state_change(sk); | ||
| 1081 | } | ||
| 1082 | |||
| 1083 | static void l2cap_conn_ready(struct l2cap_conn *conn) | 1074 | static void l2cap_conn_ready(struct l2cap_conn *conn) |
| 1084 | { | 1075 | { |
| 1085 | struct l2cap_chan_list *l = &conn->chan_list; | 1076 | struct l2cap_chan_list *l = &conn->chan_list; |
| @@ -1425,11 +1416,11 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd | |||
| 1425 | if (!sk) | 1416 | if (!sk) |
| 1426 | goto response; | 1417 | goto response; |
| 1427 | 1418 | ||
| 1428 | write_lock(&list->lock); | 1419 | write_lock_bh(&list->lock); |
| 1429 | 1420 | ||
| 1430 | /* Check if we already have channel with that dcid */ | 1421 | /* Check if we already have channel with that dcid */ |
| 1431 | if (__l2cap_get_chan_by_dcid(list, scid)) { | 1422 | if (__l2cap_get_chan_by_dcid(list, scid)) { |
| 1432 | write_unlock(&list->lock); | 1423 | write_unlock_bh(&list->lock); |
| 1433 | sock_set_flag(sk, SOCK_ZAPPED); | 1424 | sock_set_flag(sk, SOCK_ZAPPED); |
| 1434 | l2cap_sock_kill(sk); | 1425 | l2cap_sock_kill(sk); |
| 1435 | goto response; | 1426 | goto response; |
| @@ -1467,7 +1458,7 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd | |||
| 1467 | result = status = 0; | 1458 | result = status = 0; |
| 1468 | 1459 | ||
| 1469 | done: | 1460 | done: |
| 1470 | write_unlock(&list->lock); | 1461 | write_unlock_bh(&list->lock); |
| 1471 | 1462 | ||
| 1472 | response: | 1463 | response: |
| 1473 | bh_unlock_sock(parent); | 1464 | bh_unlock_sock(parent); |
| @@ -1835,7 +1826,9 @@ drop: | |||
| 1835 | kfree_skb(skb); | 1826 | kfree_skb(skb); |
| 1836 | 1827 | ||
| 1837 | done: | 1828 | done: |
| 1838 | if (sk) bh_unlock_sock(sk); | 1829 | if (sk) |
| 1830 | bh_unlock_sock(sk); | ||
| 1831 | |||
| 1839 | return 0; | 1832 | return 0; |
| 1840 | } | 1833 | } |
| 1841 | 1834 | ||
| @@ -1926,18 +1919,18 @@ static int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type) | |||
| 1926 | 1919 | ||
| 1927 | static int l2cap_connect_cfm(struct hci_conn *hcon, u8 status) | 1920 | static int l2cap_connect_cfm(struct hci_conn *hcon, u8 status) |
| 1928 | { | 1921 | { |
| 1922 | struct l2cap_conn *conn; | ||
| 1923 | |||
| 1929 | BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status); | 1924 | BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status); |
| 1930 | 1925 | ||
| 1931 | if (hcon->type != ACL_LINK) | 1926 | if (hcon->type != ACL_LINK) |
| 1932 | return 0; | 1927 | return 0; |
| 1933 | 1928 | ||
| 1934 | if (!status) { | 1929 | if (!status) { |
| 1935 | struct l2cap_conn *conn; | ||
| 1936 | |||
| 1937 | conn = l2cap_conn_add(hcon, status); | 1930 | conn = l2cap_conn_add(hcon, status); |
| 1938 | if (conn) | 1931 | if (conn) |
| 1939 | l2cap_conn_ready(conn); | 1932 | l2cap_conn_ready(conn); |
| 1940 | } else | 1933 | } else |
| 1941 | l2cap_conn_del(hcon, bt_err(status)); | 1934 | l2cap_conn_del(hcon, bt_err(status)); |
| 1942 | 1935 | ||
| 1943 | return 0; | 1936 | return 0; |
| @@ -1951,19 +1944,21 @@ static int l2cap_disconn_ind(struct hci_conn *hcon, u8 reason) | |||
| 1951 | return 0; | 1944 | return 0; |
| 1952 | 1945 | ||
| 1953 | l2cap_conn_del(hcon, bt_err(reason)); | 1946 | l2cap_conn_del(hcon, bt_err(reason)); |
| 1947 | |||
| 1954 | return 0; | 1948 | return 0; |
| 1955 | } | 1949 | } |
| 1956 | 1950 | ||
| 1957 | static int l2cap_auth_cfm(struct hci_conn *hcon, u8 status) | 1951 | static int l2cap_auth_cfm(struct hci_conn *hcon, u8 status) |
| 1958 | { | 1952 | { |
| 1959 | struct l2cap_chan_list *l; | 1953 | struct l2cap_chan_list *l; |
| 1960 | struct l2cap_conn *conn; | 1954 | struct l2cap_conn *conn = conn = hcon->l2cap_data; |
| 1961 | struct l2cap_conn_rsp rsp; | 1955 | struct l2cap_conn_rsp rsp; |
| 1962 | struct sock *sk; | 1956 | struct sock *sk; |
| 1963 | int result; | 1957 | int result; |
| 1964 | 1958 | ||
| 1965 | if (!(conn = hcon->l2cap_data)) | 1959 | if (!conn) |
| 1966 | return 0; | 1960 | return 0; |
| 1961 | |||
| 1967 | l = &conn->chan_list; | 1962 | l = &conn->chan_list; |
| 1968 | 1963 | ||
| 1969 | BT_DBG("conn %p", conn); | 1964 | BT_DBG("conn %p", conn); |
| @@ -2006,13 +2001,14 @@ static int l2cap_auth_cfm(struct hci_conn *hcon, u8 status) | |||
| 2006 | static int l2cap_encrypt_cfm(struct hci_conn *hcon, u8 status) | 2001 | static int l2cap_encrypt_cfm(struct hci_conn *hcon, u8 status) |
| 2007 | { | 2002 | { |
| 2008 | struct l2cap_chan_list *l; | 2003 | struct l2cap_chan_list *l; |
| 2009 | struct l2cap_conn *conn; | 2004 | struct l2cap_conn *conn = hcon->l2cap_data; |
| 2010 | struct l2cap_conn_rsp rsp; | 2005 | struct l2cap_conn_rsp rsp; |
| 2011 | struct sock *sk; | 2006 | struct sock *sk; |
| 2012 | int result; | 2007 | int result; |
| 2013 | 2008 | ||
| 2014 | if (!(conn = hcon->l2cap_data)) | 2009 | if (!conn) |
| 2015 | return 0; | 2010 | return 0; |
| 2011 | |||
| 2016 | l = &conn->chan_list; | 2012 | l = &conn->chan_list; |
| 2017 | 2013 | ||
| 2018 | BT_DBG("conn %p", conn); | 2014 | BT_DBG("conn %p", conn); |
| @@ -2220,7 +2216,7 @@ static int __init l2cap_init(void) | |||
| 2220 | goto error; | 2216 | goto error; |
| 2221 | } | 2217 | } |
| 2222 | 2218 | ||
| 2223 | class_create_file(&bt_class, &class_attr_l2cap); | 2219 | class_create_file(bt_class, &class_attr_l2cap); |
| 2224 | 2220 | ||
| 2225 | BT_INFO("L2CAP ver %s", VERSION); | 2221 | BT_INFO("L2CAP ver %s", VERSION); |
| 2226 | BT_INFO("L2CAP socket layer initialized"); | 2222 | BT_INFO("L2CAP socket layer initialized"); |
| @@ -2234,7 +2230,7 @@ error: | |||
| 2234 | 2230 | ||
| 2235 | static void __exit l2cap_exit(void) | 2231 | static void __exit l2cap_exit(void) |
| 2236 | { | 2232 | { |
| 2237 | class_remove_file(&bt_class, &class_attr_l2cap); | 2233 | class_remove_file(bt_class, &class_attr_l2cap); |
| 2238 | 2234 | ||
| 2239 | if (bt_sock_unregister(BTPROTO_L2CAP) < 0) | 2235 | if (bt_sock_unregister(BTPROTO_L2CAP) < 0) |
| 2240 | BT_ERR("L2CAP socket unregistration failed"); | 2236 | BT_ERR("L2CAP socket unregistration failed"); |
