[PATCH] as-iosched: use new io context counting mechanism
[linux-2.6.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/module.h>
28
29 #include <linux/types.h>
30 #include <linux/list.h>
31 #include <linux/errno.h>
32 #include <linux/kernel.h>
33 #include <linux/sched.h>
34 #include <linux/slab.h>
35 #include <linux/skbuff.h>
36 #include <linux/init.h>
37 #include <linux/poll.h>
38 #include <net/sock.h>
39
40 #if defined(CONFIG_KMOD)
41 #include <linux/kmod.h>
42 #endif
43
44 #include <net/bluetooth/bluetooth.h>
45
46 #ifndef CONFIG_BT_SOCK_DEBUG
47 #undef  BT_DBG
48 #define BT_DBG(D...)
49 #endif
50
51 #define VERSION "2.10"
52
53 /* Bluetooth sockets */
54 #define BT_MAX_PROTO    8
55 static struct net_proto_family *bt_proto[BT_MAX_PROTO];
56
57 int bt_sock_register(int proto, struct net_proto_family *ops)
58 {
59         if (proto < 0 || proto >= BT_MAX_PROTO)
60                 return -EINVAL;
61
62         if (bt_proto[proto])
63                 return -EEXIST;
64
65         bt_proto[proto] = ops;
66         return 0;
67 }
68 EXPORT_SYMBOL(bt_sock_register);
69
70 int bt_sock_unregister(int proto)
71 {
72         if (proto < 0 || proto >= BT_MAX_PROTO)
73                 return -EINVAL;
74
75         if (!bt_proto[proto])
76                 return -ENOENT;
77
78         bt_proto[proto] = NULL;
79         return 0;
80 }
81 EXPORT_SYMBOL(bt_sock_unregister);
82
83 static int bt_sock_create(struct socket *sock, int proto)
84 {
85         int err = 0;
86
87         if (proto < 0 || proto >= BT_MAX_PROTO)
88                 return -EINVAL;
89
90 #if defined(CONFIG_KMOD)
91         if (!bt_proto[proto]) {
92                 request_module("bt-proto-%d", proto);
93         }
94 #endif
95         err = -EPROTONOSUPPORT;
96         if (bt_proto[proto] && try_module_get(bt_proto[proto]->owner)) {
97                 err = bt_proto[proto]->create(sock, proto);
98                 module_put(bt_proto[proto]->owner);
99         }
100         return err; 
101 }
102
103 void bt_sock_link(struct bt_sock_list *l, struct sock *sk)
104 {
105         write_lock_bh(&l->lock);
106         sk_add_node(sk, &l->head);
107         write_unlock_bh(&l->lock);
108 }
109 EXPORT_SYMBOL(bt_sock_link);
110
111 void bt_sock_unlink(struct bt_sock_list *l, struct sock *sk)
112 {
113         write_lock_bh(&l->lock);
114         sk_del_node_init(sk);
115         write_unlock_bh(&l->lock);
116 }
117 EXPORT_SYMBOL(bt_sock_unlink);
118
119 void bt_accept_enqueue(struct sock *parent, struct sock *sk)
120 {
121         BT_DBG("parent %p, sk %p", parent, sk);
122
123         sock_hold(sk);
124         list_add_tail(&bt_sk(sk)->accept_q, &bt_sk(parent)->accept_q);
125         bt_sk(sk)->parent = parent;
126         parent->sk_ack_backlog++;
127 }
128 EXPORT_SYMBOL(bt_accept_enqueue);
129
130 void bt_accept_unlink(struct sock *sk)
131 {
132         BT_DBG("sk %p state %d", sk, sk->sk_state);
133
134         list_del_init(&bt_sk(sk)->accept_q);
135         bt_sk(sk)->parent->sk_ack_backlog--;
136         bt_sk(sk)->parent = NULL;
137         sock_put(sk);
138 }
139 EXPORT_SYMBOL(bt_accept_unlink);
140
141 struct sock *bt_accept_dequeue(struct sock *parent, struct socket *newsock)
142 {
143         struct list_head *p, *n;
144         struct sock *sk;
145
146         BT_DBG("parent %p", parent);
147
148         list_for_each_safe(p, n, &bt_sk(parent)->accept_q) {
149                 sk = (struct sock *) list_entry(p, struct bt_sock, accept_q);
150
151                 lock_sock(sk);
152
153                 /* FIXME: Is this check still needed */
154                 if (sk->sk_state == BT_CLOSED) {
155                         release_sock(sk);
156                         bt_accept_unlink(sk);
157                         continue;
158                 }
159
160                 if (sk->sk_state == BT_CONNECTED || !newsock) {
161                         bt_accept_unlink(sk);
162                         if (newsock)
163                                 sock_graft(sk, newsock);
164                         release_sock(sk);
165                         return sk;
166                 }
167
168                 release_sock(sk);
169         }
170         return NULL;
171 }
172 EXPORT_SYMBOL(bt_accept_dequeue);
173
174 int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
175         struct msghdr *msg, size_t len, int flags)
176 {
177         int noblock = flags & MSG_DONTWAIT;
178         struct sock *sk = sock->sk;
179         struct sk_buff *skb;
180         size_t copied;
181         int err;
182
183         BT_DBG("sock %p sk %p len %d", sock, sk, len);
184
185         if (flags & (MSG_OOB))
186                 return -EOPNOTSUPP;
187
188         if (!(skb = skb_recv_datagram(sk, flags, noblock, &err))) {
189                 if (sk->sk_shutdown & RCV_SHUTDOWN)
190                         return 0;
191                 return err;
192         }
193
194         msg->msg_namelen = 0;
195
196         copied = skb->len;
197         if (len < copied) {
198                 msg->msg_flags |= MSG_TRUNC;
199                 copied = len;
200         }
201
202         skb->h.raw = skb->data;
203         err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
204
205         skb_free_datagram(sk, skb);
206
207         return err ? : copied;
208 }
209 EXPORT_SYMBOL(bt_sock_recvmsg);
210
211 static inline unsigned int bt_accept_poll(struct sock *parent)
212 {
213         struct list_head *p, *n;
214         struct sock *sk;
215
216         list_for_each_safe(p, n, &bt_sk(parent)->accept_q) {
217                 sk = (struct sock *) list_entry(p, struct bt_sock, accept_q);
218                 if (sk->sk_state == BT_CONNECTED)
219                         return POLLIN | POLLRDNORM;
220         }
221
222         return 0;
223 }
224
225 unsigned int bt_sock_poll(struct file * file, struct socket *sock, poll_table *wait)
226 {
227         struct sock *sk = sock->sk;
228         unsigned int mask = 0;
229
230         BT_DBG("sock %p, sk %p", sock, sk);
231
232         poll_wait(file, sk->sk_sleep, wait);
233
234         if (sk->sk_state == BT_LISTEN)
235                 return bt_accept_poll(sk);
236
237         if (sk->sk_err || !skb_queue_empty(&sk->sk_error_queue))
238                 mask |= POLLERR;
239
240         if (sk->sk_shutdown & RCV_SHUTDOWN)
241                 mask |= POLLRDHUP;
242
243         if (sk->sk_shutdown == SHUTDOWN_MASK)
244                 mask |= POLLHUP;
245
246         if (!skb_queue_empty(&sk->sk_receive_queue) || 
247                         (sk->sk_shutdown & RCV_SHUTDOWN))
248                 mask |= POLLIN | POLLRDNORM;
249
250         if (sk->sk_state == BT_CLOSED)
251                 mask |= POLLHUP;
252
253         if (sk->sk_state == BT_CONNECT ||
254                         sk->sk_state == BT_CONNECT2 ||
255                         sk->sk_state == BT_CONFIG)
256                 return mask;
257
258         if (sock_writeable(sk))
259                 mask |= POLLOUT | POLLWRNORM | POLLWRBAND;
260         else
261                 set_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags);
262
263         return mask;
264 }
265 EXPORT_SYMBOL(bt_sock_poll);
266
267 int bt_sock_wait_state(struct sock *sk, int state, unsigned long timeo)
268 {
269         DECLARE_WAITQUEUE(wait, current);
270         int err = 0;
271
272         BT_DBG("sk %p", sk);
273
274         add_wait_queue(sk->sk_sleep, &wait);
275         while (sk->sk_state != state) {
276                 set_current_state(TASK_INTERRUPTIBLE);
277
278                 if (!timeo) {
279                         err = -EINPROGRESS;
280                         break;
281                 }
282
283                 if (signal_pending(current)) {
284                         err = sock_intr_errno(timeo);
285                         break;
286                 }
287
288                 release_sock(sk);
289                 timeo = schedule_timeout(timeo);
290                 lock_sock(sk);
291
292                 err = sock_error(sk);
293                 if (err)
294                         break;
295         }
296         set_current_state(TASK_RUNNING);
297         remove_wait_queue(sk->sk_sleep, &wait);
298         return err;
299 }
300 EXPORT_SYMBOL(bt_sock_wait_state);
301
302 static struct net_proto_family bt_sock_family_ops = {
303         .owner  = THIS_MODULE,
304         .family = PF_BLUETOOTH,
305         .create = bt_sock_create,
306 };
307
308 static int __init bt_init(void)
309 {
310         int err;
311
312         BT_INFO("Core ver %s", VERSION);
313
314         err = bt_sysfs_init();
315         if (err < 0)
316                 return err;
317
318         err = sock_register(&bt_sock_family_ops);
319         if (err < 0) {
320                 bt_sysfs_cleanup();
321                 return err;
322         }
323
324         BT_INFO("HCI device and connection manager initialized");
325
326         hci_sock_init();
327
328         return 0;
329 }
330
331 static void __exit bt_exit(void)
332 {
333         hci_sock_cleanup();
334
335         sock_unregister(PF_BLUETOOTH);
336
337         bt_sysfs_cleanup();
338 }
339
340 subsys_initcall(bt_init);
341 module_exit(bt_exit);
342
343 MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>, Marcel Holtmann <marcel@holtmann.org>");
344 MODULE_DESCRIPTION("Bluetooth Core ver " VERSION);
345 MODULE_VERSION(VERSION);
346 MODULE_LICENSE("GPL");
347 MODULE_ALIAS_NETPROTO(PF_BLUETOOTH);