Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]
  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.11"
 52 
 53 /* Bluetooth sockets */
 54 #define BT_MAX_PROTO    8
 55 static struct net_proto_family *bt_proto[BT_MAX_PROTO];
 56 
 57 static struct lock_class_key bt_slock_key[BT_MAX_PROTO];
 58 static struct lock_class_key bt_lock_key[BT_MAX_PROTO];
 59 static const char *bt_key_strings[BT_MAX_PROTO] = {
 60         "sk_lock-AF_BLUETOOTH-BTPROTO_L2CAP",
 61         "sk_lock-AF_BLUETOOTH-BTPROTO_HCI",
 62         "sk_lock-AF_BLUETOOTH-BTPROTO_SCO",
 63         "sk_lock-AF_BLUETOOTH-BTPROTO_RFCOMM",
 64         "sk_lock-AF_BLUETOOTH-BTPROTO_BNEP",
 65         "sk_lock-AF_BLUETOOTH-BTPROTO_CMTP",
 66         "sk_lock-AF_BLUETOOTH-BTPROTO_HIDP",
 67         "sk_lock-AF_BLUETOOTH-BTPROTO_AVDTP",
 68 };
 69 
 70 static const char *bt_slock_key_strings[BT_MAX_PROTO] = {
 71         "slock-AF_BLUETOOTH-BTPROTO_L2CAP",
 72         "slock-AF_BLUETOOTH-BTPROTO_HCI",
 73         "slock-AF_BLUETOOTH-BTPROTO_SCO",
 74         "slock-AF_BLUETOOTH-BTPROTO_RFCOMM",
 75         "slock-AF_BLUETOOTH-BTPROTO_BNEP",
 76         "slock-AF_BLUETOOTH-BTPROTO_CMTP",
 77         "slock-AF_BLUETOOTH-BTPROTO_HIDP",
 78         "slock-AF_BLUETOOTH-BTPROTO_AVDTP",
 79 };
 80 static DEFINE_RWLOCK(bt_proto_lock);
 81 
 82 int bt_sock_register(int proto, struct net_proto_family *ops)
 83 {
 84         int err = 0;
 85 
 86         if (proto < 0 || proto >= BT_MAX_PROTO)
 87                 return -EINVAL;
 88 
 89         write_lock(&bt_proto_lock);
 90 
 91         if (bt_proto[proto])
 92                 err = -EEXIST;
 93         else
 94                 bt_proto[proto] = ops;
 95 
 96         write_unlock(&bt_proto_lock);
 97 
 98         return err;
 99 }
100 EXPORT_SYMBOL(bt_sock_register);
101 
102 int bt_sock_unregister(int proto)
103 {
104         int err = 0;
105 
106         if (proto < 0 || proto >= BT_MAX_PROTO)
107                 return -EINVAL;
108 
109         write_lock(&bt_proto_lock);
110 
111         if (!bt_proto[proto])
112                 err = -ENOENT;
113         else
114                 bt_proto[proto] = NULL;
115 
116         write_unlock(&bt_proto_lock);
117 
118         return err;
119 }
120 EXPORT_SYMBOL(bt_sock_unregister);
121 
122 static void bt_reclassify_sock_lock(struct socket *sock, int proto)
123 {
124         struct sock *sk = sock->sk;
125 
126         if (!sk)
127                 return;
128         BUG_ON(sock_owned_by_user(sk));
129 
130         sock_lock_init_class_and_name(sk,
131                         bt_slock_key_strings[proto],
132                         &bt_slock_key[proto],
133                         bt_key_strings[proto],
134                         &bt_lock_key[proto]);
135 }
136 
137 static int bt_sock_create(struct net *net, struct socket *sock, int proto)
138 {
139         int err;
140 
141         if (net != &init_net)
142                 return -EAFNOSUPPORT;
143 
144         if (proto < 0 || proto >= BT_MAX_PROTO)
145                 return -EINVAL;
146 
147 #if defined(CONFIG_KMOD)
148         if (!bt_proto[proto]) {
149                 request_module("bt-proto-%d", proto);
150         }
151 #endif
152 
153         err = -EPROTONOSUPPORT;
154 
155         read_lock(&bt_proto_lock);
156 
157         if (bt_proto[proto] && try_module_get(bt_proto[proto]->owner)) {
158                 err = bt_proto[proto]->create(net, sock, proto);
159                 bt_reclassify_sock_lock(sock, proto);
160                 module_put(bt_proto[proto]->owner);
161         }
162 
163         read_unlock(&bt_proto_lock);
164 
165         return err;
166 }
167 
168 void bt_sock_link(struct bt_sock_list *l, struct sock *sk)
169 {
170         write_lock_bh(&l->lock);
171         sk_add_node(sk, &l->head);
172         write_unlock_bh(&l->lock);
173 }
174 EXPORT_SYMBOL(bt_sock_link);
175 
176 void bt_sock_unlink(struct bt_sock_list *l, struct sock *sk)
177 {
178         write_lock_bh(&l->lock);
179         sk_del_node_init(sk);
180         write_unlock_bh(&l->lock);
181 }
182 EXPORT_SYMBOL(bt_sock_unlink);
183 
184 void bt_accept_enqueue(struct sock *parent, struct sock *sk)
185 {
186         BT_DBG("parent %p, sk %p", parent, sk);
187 
188         sock_hold(sk);
189         list_add_tail(&bt_sk(sk)->accept_q, &bt_sk(parent)->accept_q);
190         bt_sk(sk)->parent = parent;
191         parent->sk_ack_backlog++;
192 }
193 EXPORT_SYMBOL(bt_accept_enqueue);
194 
195 void bt_accept_unlink(struct sock *sk)
196 {
197         BT_DBG("sk %p state %d", sk, sk->sk_state);
198 
199         list_del_init(&bt_sk(sk)->accept_q);
200         bt_sk(sk)->parent->sk_ack_backlog--;
201         bt_sk(sk)->parent = NULL;
202         sock_put(sk);
203 }
204 EXPORT_SYMBOL(bt_accept_unlink);
205 
206 struct sock *bt_accept_dequeue(struct sock *parent, struct socket *newsock)
207 {
208         struct list_head *p, *n;
209         struct sock *sk;
210 
211         BT_DBG("parent %p", parent);
212 
213         list_for_each_safe(p, n, &bt_sk(parent)->accept_q) {
214                 sk = (struct sock *) list_entry(p, struct bt_sock, accept_q);
215 
216                 lock_sock(sk);
217 
218                 /* FIXME: Is this check still needed */
219                 if (sk->sk_state == BT_CLOSED) {
220                         release_sock(sk);
221                         bt_accept_unlink(sk);
222                         continue;
223                 }
224 
225                 if (sk->sk_state == BT_CONNECTED || !newsock) {
226                         bt_accept_unlink(sk);
227                         if (newsock)
228                                 sock_graft(sk, newsock);
229                         release_sock(sk);
230                         return sk;
231                 }
232 
233                 release_sock(sk);
234         }
235         return NULL;
236 }
237 EXPORT_SYMBOL(bt_accept_dequeue);
238 
239 int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
240         struct msghdr *msg, size_t len, int flags)
241 {
242         int noblock = flags & MSG_DONTWAIT;
243         struct sock *sk = sock->sk;
244         struct sk_buff *skb;
245         size_t copied;
246         int err;
247 
248         BT_DBG("sock %p sk %p len %d", sock, sk, len);
249 
250         if (flags & (MSG_OOB))
251                 return -EOPNOTSUPP;
252 
253         if (!(skb = skb_recv_datagram(sk, flags, noblock, &err))) {
254                 if (sk->sk_shutdown & RCV_SHUTDOWN)
255                         return 0;
256                 return err;
257         }
258 
259         msg->msg_namelen = 0;
260 
261         copied = skb->len;
262         if (len < copied) {
263                 msg->msg_flags |= MSG_TRUNC;
264                 copied = len;
265         }
266 
267         skb_reset_transport_header(skb);
268         err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
269 
270         skb_free_datagram(sk, skb);
271 
272         return err ? : copied;
273 }
274 EXPORT_SYMBOL(bt_sock_recvmsg);
275 
276 static inline unsigned int bt_accept_poll(struct sock *parent)
277 {
278         struct list_head *p, *n;
279         struct sock *sk;
280 
281         list_for_each_safe(p, n, &bt_sk(parent)->accept_q) {
282                 sk = (struct sock *) list_entry(p, struct bt_sock, accept_q);
283                 if (sk->sk_state == BT_CONNECTED)
284                         return POLLIN | POLLRDNORM;
285         }
286 
287         return 0;
288 }
289 
290 unsigned int bt_sock_poll(struct file * file, struct socket *sock, poll_table *wait)
291 {
292         struct sock *sk = sock->sk;
293         unsigned int mask = 0;
294 
295         BT_DBG("sock %p, sk %p", sock, sk);
296 
297         poll_wait(file, sk->sk_sleep, wait);
298 
299         if (sk->sk_state == BT_LISTEN)
300                 return bt_accept_poll(sk);
301 
302         if (sk->sk_err || !skb_queue_empty(&sk->sk_error_queue))
303                 mask |= POLLERR;
304 
305         if (sk->sk_shutdown & RCV_SHUTDOWN)
306                 mask |= POLLRDHUP;
307 
308         if (sk->sk_shutdown == SHUTDOWN_MASK)
309                 mask |= POLLHUP;
310 
311         if (!skb_queue_empty(&sk->sk_receive_queue) ||
312                         (sk->sk_shutdown & RCV_SHUTDOWN))
313                 mask |= POLLIN | POLLRDNORM;
314 
315         if (sk->sk_state == BT_CLOSED)
316                 mask |= POLLHUP;
317 
318         if (sk->sk_state == BT_CONNECT ||
319                         sk->sk_state == BT_CONNECT2 ||
320                         sk->sk_state == BT_CONFIG)
321                 return mask;
322 
323         if (sock_writeable(sk))
324                 mask |= POLLOUT | POLLWRNORM | POLLWRBAND;
325         else
326                 set_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags);
327 
328         return mask;
329 }
330 EXPORT_SYMBOL(bt_sock_poll);
331 
332 int bt_sock_wait_state(struct sock *sk, int state, unsigned long timeo)
333 {
334         DECLARE_WAITQUEUE(wait, current);
335         int err = 0;
336 
337         BT_DBG("sk %p", sk);
338 
339         add_wait_queue(sk->sk_sleep, &wait);
340         while (sk->sk_state != state) {
341                 set_current_state(TASK_INTERRUPTIBLE);
342 
343                 if (!timeo) {
344                         err = -EINPROGRESS;
345                         break;
346                 }
347 
348                 if (signal_pending(current)) {
349                         err = sock_intr_errno(timeo);
350                         break;
351                 }
352 
353                 release_sock(sk);
354                 timeo = schedule_timeout(timeo);
355                 lock_sock(sk);
356 
357                 err = sock_error(sk);
358                 if (err)
359                         break;
360         }
361         set_current_state(TASK_RUNNING);
362         remove_wait_queue(sk->sk_sleep, &wait);
363         return err;
364 }
365 EXPORT_SYMBOL(bt_sock_wait_state);
366 
367 static struct net_proto_family bt_sock_family_ops = {
368         .owner  = THIS_MODULE,
369         .family = PF_BLUETOOTH,
370         .create = bt_sock_create,
371 };
372 
373 static int __init bt_init(void)
374 {
375         int err;
376 
377         BT_INFO("Core ver %s", VERSION);
378 
379         err = bt_sysfs_init();
380         if (err < 0)
381                 return err;
382 
383         err = sock_register(&bt_sock_family_ops);
384         if (err < 0) {
385                 bt_sysfs_cleanup();
386                 return err;
387         }
388 
389         BT_INFO("HCI device and connection manager initialized");
390 
391         hci_sock_init();
392 
393         return 0;
394 }
395 
396 static void __exit bt_exit(void)
397 {
398         hci_sock_cleanup();
399 
400         sock_unregister(PF_BLUETOOTH);
401 
402         bt_sysfs_cleanup();
403 }
404 
405 subsys_initcall(bt_init);
406 module_exit(bt_exit);
407 
408 MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>, Marcel Holtmann <marcel@holtmann.org>");
409 MODULE_DESCRIPTION("Bluetooth Core ver " VERSION);
410 MODULE_VERSION(VERSION);
411 MODULE_LICENSE("GPL");
412 MODULE_ALIAS_NETPROTO(PF_BLUETOOTH);
413 
  This page was automatically generated by the LXR engine.