Merge branch 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/aegl/linux-2.6
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / net / bluetooth / af_bluetooth.c
1 /*
2 BlueZ - Bluetooth protocol stack for Linux
3 Copyright (C) 2000-2001 Qualcomm Incorporated
4
5 Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License version 2 as
9 published by the Free Software Foundation;
10
11 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
12 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
13 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
14 IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
15 CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
16 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19
20 ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
21 COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
22 SOFTWARE IS DISCLAIMED.
23 */
24
25 /* Bluetooth address family and sockets. */
26
27 #include <linux/config.h>
28 #include <linux/module.h>
29
30 #include <linux/types.h>
31 #include <linux/list.h>
32 #include <linux/errno.h>
33 #include <linux/kernel.h>
34 #include <linux/sched.h>
35 #include <linux/slab.h>
36 #include <linux/skbuff.h>
37 #include <linux/init.h>
38 #include <linux/poll.h>
39 #include <linux/proc_fs.h>
40 #include <net/sock.h>
41
42 #if defined(CONFIG_KMOD)
43 #include <linux/kmod.h>
44 #endif
45
46 #include <net/bluetooth/bluetooth.h>
47
48 #ifndef CONFIG_BT_SOCK_DEBUG
49 #undef BT_DBG
50 #define BT_DBG(D...)
51 #endif
52
53 #define VERSION "2.7"
54
55 struct proc_dir_entry *proc_bt;
56 EXPORT_SYMBOL(proc_bt);
57
58 /* Bluetooth sockets */
59 #define BT_MAX_PROTO 8
60 static struct net_proto_family *bt_proto[BT_MAX_PROTO];
61
62 int bt_sock_register(int proto, struct net_proto_family *ops)
63 {
64 if (proto < 0 || proto >= BT_MAX_PROTO)
65 return -EINVAL;
66
67 if (bt_proto[proto])
68 return -EEXIST;
69
70 bt_proto[proto] = ops;
71 return 0;
72 }
73 EXPORT_SYMBOL(bt_sock_register);
74
75 int bt_sock_unregister(int proto)
76 {
77 if (proto < 0 || proto >= BT_MAX_PROTO)
78 return -EINVAL;
79
80 if (!bt_proto[proto])
81 return -ENOENT;
82
83 bt_proto[proto] = NULL;
84 return 0;
85 }
86 EXPORT_SYMBOL(bt_sock_unregister);
87
88 static int bt_sock_create(struct socket *sock, int proto)
89 {
90 int err = 0;
91
92 if (proto < 0 || proto >= BT_MAX_PROTO)
93 return -EINVAL;
94
95 #if defined(CONFIG_KMOD)
96 if (!bt_proto[proto]) {
97 request_module("bt-proto-%d", proto);
98 }
99 #endif
100 err = -EPROTONOSUPPORT;
101 if (bt_proto[proto] && try_module_get(bt_proto[proto]->owner)) {
102 err = bt_proto[proto]->create(sock, proto);
103 module_put(bt_proto[proto]->owner);
104 }
105 return err;
106 }
107
108 void bt_sock_link(struct bt_sock_list *l, struct sock *sk)
109 {
110 write_lock_bh(&l->lock);
111 sk_add_node(sk, &l->head);
112 write_unlock_bh(&l->lock);
113 }
114 EXPORT_SYMBOL(bt_sock_link);
115
116 void bt_sock_unlink(struct bt_sock_list *l, struct sock *sk)
117 {
118 write_lock_bh(&l->lock);
119 sk_del_node_init(sk);
120 write_unlock_bh(&l->lock);
121 }
122 EXPORT_SYMBOL(bt_sock_unlink);
123
124 void bt_accept_enqueue(struct sock *parent, struct sock *sk)
125 {
126 BT_DBG("parent %p, sk %p", parent, sk);
127
128 sock_hold(sk);
129 list_add_tail(&bt_sk(sk)->accept_q, &bt_sk(parent)->accept_q);
130 bt_sk(sk)->parent = parent;
131 parent->sk_ack_backlog++;
132 }
133 EXPORT_SYMBOL(bt_accept_enqueue);
134
135 void bt_accept_unlink(struct sock *sk)
136 {
137 BT_DBG("sk %p state %d", sk, sk->sk_state);
138
139 list_del_init(&bt_sk(sk)->accept_q);
140 bt_sk(sk)->parent->sk_ack_backlog--;
141 bt_sk(sk)->parent = NULL;
142 sock_put(sk);
143 }
144 EXPORT_SYMBOL(bt_accept_unlink);
145
146 struct sock *bt_accept_dequeue(struct sock *parent, struct socket *newsock)
147 {
148 struct list_head *p, *n;
149 struct sock *sk;
150
151 BT_DBG("parent %p", parent);
152
153 list_for_each_safe(p, n, &bt_sk(parent)->accept_q) {
154 sk = (struct sock *) list_entry(p, struct bt_sock, accept_q);
155
156 lock_sock(sk);
157
158 /* FIXME: Is this check still needed */
159 if (sk->sk_state == BT_CLOSED) {
160 release_sock(sk);
161 bt_accept_unlink(sk);
162 continue;
163 }
164
165 if (sk->sk_state == BT_CONNECTED || !newsock) {
166 bt_accept_unlink(sk);
167 if (newsock)
168 sock_graft(sk, newsock);
169 release_sock(sk);
170 return sk;
171 }
172
173 release_sock(sk);
174 }
175 return NULL;
176 }
177 EXPORT_SYMBOL(bt_accept_dequeue);
178
179 int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
180 struct msghdr *msg, size_t len, int flags)
181 {
182 int noblock = flags & MSG_DONTWAIT;
183 struct sock *sk = sock->sk;
184 struct sk_buff *skb;
185 size_t copied;
186 int err;
187
188 BT_DBG("sock %p sk %p len %d", sock, sk, len);
189
190 if (flags & (MSG_OOB))
191 return -EOPNOTSUPP;
192
193 if (!(skb = skb_recv_datagram(sk, flags, noblock, &err))) {
194 if (sk->sk_shutdown & RCV_SHUTDOWN)
195 return 0;
196 return err;
197 }
198
199 msg->msg_namelen = 0;
200
201 copied = skb->len;
202 if (len < copied) {
203 msg->msg_flags |= MSG_TRUNC;
204 copied = len;
205 }
206
207 skb->h.raw = skb->data;
208 err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
209
210 skb_free_datagram(sk, skb);
211
212 return err ? : copied;
213 }
214 EXPORT_SYMBOL(bt_sock_recvmsg);
215
216 static inline unsigned int bt_accept_poll(struct sock *parent)
217 {
218 struct list_head *p, *n;
219 struct sock *sk;
220
221 list_for_each_safe(p, n, &bt_sk(parent)->accept_q) {
222 sk = (struct sock *) list_entry(p, struct bt_sock, accept_q);
223 if (sk->sk_state == BT_CONNECTED)
224 return POLLIN | POLLRDNORM;
225 }
226
227 return 0;
228 }
229
230 unsigned int bt_sock_poll(struct file * file, struct socket *sock, poll_table *wait)
231 {
232 struct sock *sk = sock->sk;
233 unsigned int mask = 0;
234
235 BT_DBG("sock %p, sk %p", sock, sk);
236
237 poll_wait(file, sk->sk_sleep, wait);
238
239 if (sk->sk_state == BT_LISTEN)
240 return bt_accept_poll(sk);
241
242 if (sk->sk_err || !skb_queue_empty(&sk->sk_error_queue))
243 mask |= POLLERR;
244
245 if (sk->sk_shutdown == SHUTDOWN_MASK)
246 mask |= POLLHUP;
247
248 if (!skb_queue_empty(&sk->sk_receive_queue) ||
249 (sk->sk_shutdown & RCV_SHUTDOWN))
250 mask |= POLLIN | POLLRDNORM;
251
252 if (sk->sk_state == BT_CLOSED)
253 mask |= POLLHUP;
254
255 if (sk->sk_state == BT_CONNECT ||
256 sk->sk_state == BT_CONNECT2 ||
257 sk->sk_state == BT_CONFIG)
258 return mask;
259
260 if (sock_writeable(sk))
261 mask |= POLLOUT | POLLWRNORM | POLLWRBAND;
262 else
263 set_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags);
264
265 return mask;
266 }
267 EXPORT_SYMBOL(bt_sock_poll);
268
269 int bt_sock_wait_state(struct sock *sk, int state, unsigned long timeo)
270 {
271 DECLARE_WAITQUEUE(wait, current);
272 int err = 0;
273
274 BT_DBG("sk %p", sk);
275
276 add_wait_queue(sk->sk_sleep, &wait);
277 while (sk->sk_state != state) {
278 set_current_state(TASK_INTERRUPTIBLE);
279
280 if (!timeo) {
281 err = -EAGAIN;
282 break;
283 }
284
285 if (signal_pending(current)) {
286 err = sock_intr_errno(timeo);
287 break;
288 }
289
290 release_sock(sk);
291 timeo = schedule_timeout(timeo);
292 lock_sock(sk);
293
294 if (sk->sk_err) {
295 err = sock_error(sk);
296 break;
297 }
298 }
299 set_current_state(TASK_RUNNING);
300 remove_wait_queue(sk->sk_sleep, &wait);
301 return err;
302 }
303 EXPORT_SYMBOL(bt_sock_wait_state);
304
305 static struct net_proto_family bt_sock_family_ops = {
306 .owner = THIS_MODULE,
307 .family = PF_BLUETOOTH,
308 .create = bt_sock_create,
309 };
310
311 static int __init bt_init(void)
312 {
313 BT_INFO("Core ver %s", VERSION);
314
315 proc_bt = proc_mkdir("bluetooth", NULL);
316 if (proc_bt)
317 proc_bt->owner = THIS_MODULE;
318
319 sock_register(&bt_sock_family_ops);
320
321 BT_INFO("HCI device and connection manager initialized");
322
323 bt_sysfs_init();
324
325 hci_sock_init();
326
327 return 0;
328 }
329
330 static void __exit bt_exit(void)
331 {
332 hci_sock_cleanup();
333
334 bt_sysfs_cleanup();
335
336 sock_unregister(PF_BLUETOOTH);
337
338 remove_proc_entry("bluetooth", NULL);
339 }
340
341 subsys_initcall(bt_init);
342 module_exit(bt_exit);
343
344 MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>, Marcel Holtmann <marcel@holtmann.org>");
345 MODULE_DESCRIPTION("Bluetooth Core ver " VERSION);
346 MODULE_VERSION(VERSION);
347 MODULE_LICENSE("GPL");
348 MODULE_ALIAS_NETPROTO(PF_BLUETOOTH);