WorkStruct: Typedef the work function prototype
[linux-2.6/verdex.git] / net / bluetooth / hidp / core.c
blob66782010f82cbacf442eba7a2d6c64f17d8c0964
1 /*
2 HIDP implementation for Linux Bluetooth stack (BlueZ).
3 Copyright (C) 2003-2004 Marcel Holtmann <marcel@holtmann.org>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License version 2 as
7 published by the Free Software Foundation;
9 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
10 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
11 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
12 IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
13 CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
14 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
19 COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
20 SOFTWARE IS DISCLAIMED.
23 #include <linux/module.h>
25 #include <linux/types.h>
26 #include <linux/errno.h>
27 #include <linux/kernel.h>
28 #include <linux/sched.h>
29 #include <linux/slab.h>
30 #include <linux/poll.h>
31 #include <linux/fcntl.h>
32 #include <linux/skbuff.h>
33 #include <linux/socket.h>
34 #include <linux/ioctl.h>
35 #include <linux/file.h>
36 #include <linux/init.h>
37 #include <linux/wait.h>
38 #include <net/sock.h>
40 #include <linux/input.h>
42 #include <net/bluetooth/bluetooth.h>
43 #include <net/bluetooth/hci_core.h>
44 #include <net/bluetooth/l2cap.h>
46 #include "hidp.h"
48 #ifndef CONFIG_BT_HIDP_DEBUG
49 #undef BT_DBG
50 #define BT_DBG(D...)
51 #endif
53 #define VERSION "1.1"
55 static DECLARE_RWSEM(hidp_session_sem);
56 static LIST_HEAD(hidp_session_list);
58 static unsigned char hidp_keycode[256] = {
59 0, 0, 0, 0, 30, 48, 46, 32, 18, 33, 34, 35, 23, 36, 37, 38,
60 50, 49, 24, 25, 16, 19, 31, 20, 22, 47, 17, 45, 21, 44, 2, 3,
61 4, 5, 6, 7, 8, 9, 10, 11, 28, 1, 14, 15, 57, 12, 13, 26,
62 27, 43, 43, 39, 40, 41, 51, 52, 53, 58, 59, 60, 61, 62, 63, 64,
63 65, 66, 67, 68, 87, 88, 99, 70,119,110,102,104,111,107,109,106,
64 105,108,103, 69, 98, 55, 74, 78, 96, 79, 80, 81, 75, 76, 77, 71,
65 72, 73, 82, 83, 86,127,116,117,183,184,185,186,187,188,189,190,
66 191,192,193,194,134,138,130,132,128,129,131,137,133,135,136,113,
67 115,114, 0, 0, 0,121, 0, 89, 93,124, 92, 94, 95, 0, 0, 0,
68 122,123, 90, 91, 85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
69 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
70 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
71 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
72 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
73 29, 42, 56,125, 97, 54,100,126,164,166,165,163,161,115,114,113,
74 150,158,159,128,136,177,178,176,142,152,173,140
77 static unsigned char hidp_mkeyspat[] = { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 };
79 static struct hidp_session *__hidp_get_session(bdaddr_t *bdaddr)
81 struct hidp_session *session;
82 struct list_head *p;
84 BT_DBG("");
86 list_for_each(p, &hidp_session_list) {
87 session = list_entry(p, struct hidp_session, list);
88 if (!bacmp(bdaddr, &session->bdaddr))
89 return session;
91 return NULL;
94 static void __hidp_link_session(struct hidp_session *session)
96 __module_get(THIS_MODULE);
97 list_add(&session->list, &hidp_session_list);
100 static void __hidp_unlink_session(struct hidp_session *session)
102 list_del(&session->list);
103 module_put(THIS_MODULE);
106 static void __hidp_copy_session(struct hidp_session *session, struct hidp_conninfo *ci)
108 bacpy(&ci->bdaddr, &session->bdaddr);
110 ci->flags = session->flags;
111 ci->state = session->state;
113 ci->vendor = 0x0000;
114 ci->product = 0x0000;
115 ci->version = 0x0000;
116 memset(ci->name, 0, 128);
118 if (session->input) {
119 ci->vendor = session->input->id.vendor;
120 ci->product = session->input->id.product;
121 ci->version = session->input->id.version;
122 if (session->input->name)
123 strncpy(ci->name, session->input->name, 128);
124 else
125 strncpy(ci->name, "HID Boot Device", 128);
129 static int hidp_input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
131 struct hidp_session *session = dev->private;
132 struct sk_buff *skb;
133 unsigned char newleds;
135 BT_DBG("input %p type %d code %d value %d", dev, type, code, value);
137 if (type != EV_LED)
138 return -1;
140 newleds = (!!test_bit(LED_KANA, dev->led) << 3) |
141 (!!test_bit(LED_COMPOSE, dev->led) << 3) |
142 (!!test_bit(LED_SCROLLL, dev->led) << 2) |
143 (!!test_bit(LED_CAPSL, dev->led) << 1) |
144 (!!test_bit(LED_NUML, dev->led));
146 if (session->leds == newleds)
147 return 0;
149 session->leds = newleds;
151 if (!(skb = alloc_skb(3, GFP_ATOMIC))) {
152 BT_ERR("Can't allocate memory for new frame");
153 return -ENOMEM;
156 *skb_put(skb, 1) = HIDP_TRANS_DATA | HIDP_DATA_RTYPE_OUPUT;
157 *skb_put(skb, 1) = 0x01;
158 *skb_put(skb, 1) = newleds;
160 skb_queue_tail(&session->intr_transmit, skb);
162 hidp_schedule(session);
164 return 0;
167 static void hidp_input_report(struct hidp_session *session, struct sk_buff *skb)
169 struct input_dev *dev = session->input;
170 unsigned char *keys = session->keys;
171 unsigned char *udata = skb->data + 1;
172 signed char *sdata = skb->data + 1;
173 int i, size = skb->len - 1;
175 switch (skb->data[0]) {
176 case 0x01: /* Keyboard report */
177 for (i = 0; i < 8; i++)
178 input_report_key(dev, hidp_keycode[i + 224], (udata[0] >> i) & 1);
180 /* If all the key codes have been set to 0x01, it means
181 * too many keys were pressed at the same time. */
182 if (!memcmp(udata + 2, hidp_mkeyspat, 6))
183 break;
185 for (i = 2; i < 8; i++) {
186 if (keys[i] > 3 && memscan(udata + 2, keys[i], 6) == udata + 8) {
187 if (hidp_keycode[keys[i]])
188 input_report_key(dev, hidp_keycode[keys[i]], 0);
189 else
190 BT_ERR("Unknown key (scancode %#x) released.", keys[i]);
193 if (udata[i] > 3 && memscan(keys + 2, udata[i], 6) == keys + 8) {
194 if (hidp_keycode[udata[i]])
195 input_report_key(dev, hidp_keycode[udata[i]], 1);
196 else
197 BT_ERR("Unknown key (scancode %#x) pressed.", udata[i]);
201 memcpy(keys, udata, 8);
202 break;
204 case 0x02: /* Mouse report */
205 input_report_key(dev, BTN_LEFT, sdata[0] & 0x01);
206 input_report_key(dev, BTN_RIGHT, sdata[0] & 0x02);
207 input_report_key(dev, BTN_MIDDLE, sdata[0] & 0x04);
208 input_report_key(dev, BTN_SIDE, sdata[0] & 0x08);
209 input_report_key(dev, BTN_EXTRA, sdata[0] & 0x10);
211 input_report_rel(dev, REL_X, sdata[1]);
212 input_report_rel(dev, REL_Y, sdata[2]);
214 if (size > 3)
215 input_report_rel(dev, REL_WHEEL, sdata[3]);
216 break;
219 input_sync(dev);
222 static void hidp_idle_timeout(unsigned long arg)
224 struct hidp_session *session = (struct hidp_session *) arg;
226 atomic_inc(&session->terminate);
227 hidp_schedule(session);
230 static inline void hidp_set_timer(struct hidp_session *session)
232 if (session->idle_to > 0)
233 mod_timer(&session->timer, jiffies + HZ * session->idle_to);
236 static inline void hidp_del_timer(struct hidp_session *session)
238 if (session->idle_to > 0)
239 del_timer(&session->timer);
242 static int __hidp_send_ctrl_message(struct hidp_session *session,
243 unsigned char hdr, unsigned char *data, int size)
245 struct sk_buff *skb;
247 BT_DBG("session %p data %p size %d", session, data, size);
249 if (!(skb = alloc_skb(size + 1, GFP_ATOMIC))) {
250 BT_ERR("Can't allocate memory for new frame");
251 return -ENOMEM;
254 *skb_put(skb, 1) = hdr;
255 if (data && size > 0)
256 memcpy(skb_put(skb, size), data, size);
258 skb_queue_tail(&session->ctrl_transmit, skb);
260 return 0;
263 static int inline hidp_send_ctrl_message(struct hidp_session *session,
264 unsigned char hdr, unsigned char *data, int size)
266 int err;
268 err = __hidp_send_ctrl_message(session, hdr, data, size);
270 hidp_schedule(session);
272 return err;
275 static inline void hidp_process_handshake(struct hidp_session *session, unsigned char param)
277 BT_DBG("session %p param 0x%02x", session, param);
279 switch (param) {
280 case HIDP_HSHK_SUCCESSFUL:
281 /* FIXME: Call into SET_ GET_ handlers here */
282 break;
284 case HIDP_HSHK_NOT_READY:
285 case HIDP_HSHK_ERR_INVALID_REPORT_ID:
286 case HIDP_HSHK_ERR_UNSUPPORTED_REQUEST:
287 case HIDP_HSHK_ERR_INVALID_PARAMETER:
288 /* FIXME: Call into SET_ GET_ handlers here */
289 break;
291 case HIDP_HSHK_ERR_UNKNOWN:
292 break;
294 case HIDP_HSHK_ERR_FATAL:
295 /* Device requests a reboot, as this is the only way this error
296 * can be recovered. */
297 __hidp_send_ctrl_message(session,
298 HIDP_TRANS_HID_CONTROL | HIDP_CTRL_SOFT_RESET, NULL, 0);
299 break;
301 default:
302 __hidp_send_ctrl_message(session,
303 HIDP_TRANS_HANDSHAKE | HIDP_HSHK_ERR_INVALID_PARAMETER, NULL, 0);
304 break;
308 static inline void hidp_process_hid_control(struct hidp_session *session, unsigned char param)
310 BT_DBG("session %p param 0x%02x", session, param);
312 switch (param) {
313 case HIDP_CTRL_NOP:
314 break;
316 case HIDP_CTRL_VIRTUAL_CABLE_UNPLUG:
317 /* Flush the transmit queues */
318 skb_queue_purge(&session->ctrl_transmit);
319 skb_queue_purge(&session->intr_transmit);
321 /* Kill session thread */
322 atomic_inc(&session->terminate);
323 break;
325 case HIDP_CTRL_HARD_RESET:
326 case HIDP_CTRL_SOFT_RESET:
327 case HIDP_CTRL_SUSPEND:
328 case HIDP_CTRL_EXIT_SUSPEND:
329 /* FIXME: We have to parse these and return no error */
330 break;
332 default:
333 __hidp_send_ctrl_message(session,
334 HIDP_TRANS_HANDSHAKE | HIDP_HSHK_ERR_INVALID_PARAMETER, NULL, 0);
335 break;
339 static inline void hidp_process_data(struct hidp_session *session, struct sk_buff *skb, unsigned char param)
341 BT_DBG("session %p skb %p len %d param 0x%02x", session, skb, skb->len, param);
343 switch (param) {
344 case HIDP_DATA_RTYPE_INPUT:
345 hidp_set_timer(session);
347 if (session->input)
348 hidp_input_report(session, skb);
349 break;
351 case HIDP_DATA_RTYPE_OTHER:
352 case HIDP_DATA_RTYPE_OUPUT:
353 case HIDP_DATA_RTYPE_FEATURE:
354 break;
356 default:
357 __hidp_send_ctrl_message(session,
358 HIDP_TRANS_HANDSHAKE | HIDP_HSHK_ERR_INVALID_PARAMETER, NULL, 0);
362 static inline void hidp_recv_ctrl_frame(struct hidp_session *session, struct sk_buff *skb)
364 unsigned char hdr, type, param;
366 BT_DBG("session %p skb %p len %d", session, skb, skb->len);
368 hdr = skb->data[0];
369 skb_pull(skb, 1);
371 type = hdr & HIDP_HEADER_TRANS_MASK;
372 param = hdr & HIDP_HEADER_PARAM_MASK;
374 switch (type) {
375 case HIDP_TRANS_HANDSHAKE:
376 hidp_process_handshake(session, param);
377 break;
379 case HIDP_TRANS_HID_CONTROL:
380 hidp_process_hid_control(session, param);
381 break;
383 case HIDP_TRANS_DATA:
384 hidp_process_data(session, skb, param);
385 break;
387 default:
388 __hidp_send_ctrl_message(session,
389 HIDP_TRANS_HANDSHAKE | HIDP_HSHK_ERR_UNSUPPORTED_REQUEST, NULL, 0);
390 break;
393 kfree_skb(skb);
396 static inline void hidp_recv_intr_frame(struct hidp_session *session, struct sk_buff *skb)
398 unsigned char hdr;
400 BT_DBG("session %p skb %p len %d", session, skb, skb->len);
402 hdr = skb->data[0];
403 skb_pull(skb, 1);
405 if (hdr == (HIDP_TRANS_DATA | HIDP_DATA_RTYPE_INPUT)) {
406 hidp_set_timer(session);
407 if (session->input)
408 hidp_input_report(session, skb);
409 } else {
410 BT_DBG("Unsupported protocol header 0x%02x", hdr);
413 kfree_skb(skb);
416 static int hidp_send_frame(struct socket *sock, unsigned char *data, int len)
418 struct kvec iv = { data, len };
419 struct msghdr msg;
421 BT_DBG("sock %p data %p len %d", sock, data, len);
423 if (!len)
424 return 0;
426 memset(&msg, 0, sizeof(msg));
428 return kernel_sendmsg(sock, &msg, &iv, 1, len);
431 static void hidp_process_transmit(struct hidp_session *session)
433 struct sk_buff *skb;
435 BT_DBG("session %p", session);
437 while ((skb = skb_dequeue(&session->ctrl_transmit))) {
438 if (hidp_send_frame(session->ctrl_sock, skb->data, skb->len) < 0) {
439 skb_queue_head(&session->ctrl_transmit, skb);
440 break;
443 hidp_set_timer(session);
444 kfree_skb(skb);
447 while ((skb = skb_dequeue(&session->intr_transmit))) {
448 if (hidp_send_frame(session->intr_sock, skb->data, skb->len) < 0) {
449 skb_queue_head(&session->intr_transmit, skb);
450 break;
453 hidp_set_timer(session);
454 kfree_skb(skb);
458 static int hidp_session(void *arg)
460 struct hidp_session *session = arg;
461 struct sock *ctrl_sk = session->ctrl_sock->sk;
462 struct sock *intr_sk = session->intr_sock->sk;
463 struct sk_buff *skb;
464 int vendor = 0x0000, product = 0x0000;
465 wait_queue_t ctrl_wait, intr_wait;
467 BT_DBG("session %p", session);
469 if (session->input) {
470 vendor = session->input->id.vendor;
471 product = session->input->id.product;
474 daemonize("khidpd_%04x%04x", vendor, product);
475 set_user_nice(current, -15);
476 current->flags |= PF_NOFREEZE;
478 init_waitqueue_entry(&ctrl_wait, current);
479 init_waitqueue_entry(&intr_wait, current);
480 add_wait_queue(ctrl_sk->sk_sleep, &ctrl_wait);
481 add_wait_queue(intr_sk->sk_sleep, &intr_wait);
482 while (!atomic_read(&session->terminate)) {
483 set_current_state(TASK_INTERRUPTIBLE);
485 if (ctrl_sk->sk_state != BT_CONNECTED || intr_sk->sk_state != BT_CONNECTED)
486 break;
488 while ((skb = skb_dequeue(&ctrl_sk->sk_receive_queue))) {
489 skb_orphan(skb);
490 hidp_recv_ctrl_frame(session, skb);
493 while ((skb = skb_dequeue(&intr_sk->sk_receive_queue))) {
494 skb_orphan(skb);
495 hidp_recv_intr_frame(session, skb);
498 hidp_process_transmit(session);
500 schedule();
502 set_current_state(TASK_RUNNING);
503 remove_wait_queue(intr_sk->sk_sleep, &intr_wait);
504 remove_wait_queue(ctrl_sk->sk_sleep, &ctrl_wait);
506 down_write(&hidp_session_sem);
508 hidp_del_timer(session);
510 fput(session->intr_sock->file);
512 wait_event_timeout(*(ctrl_sk->sk_sleep),
513 (ctrl_sk->sk_state == BT_CLOSED), msecs_to_jiffies(500));
515 fput(session->ctrl_sock->file);
517 __hidp_unlink_session(session);
519 if (session->input) {
520 input_unregister_device(session->input);
521 session->input = NULL;
524 up_write(&hidp_session_sem);
526 kfree(session);
527 return 0;
530 static struct device *hidp_get_device(struct hidp_session *session)
532 bdaddr_t *src = &bt_sk(session->ctrl_sock->sk)->src;
533 bdaddr_t *dst = &bt_sk(session->ctrl_sock->sk)->dst;
534 struct hci_dev *hdev;
535 struct hci_conn *conn;
537 hdev = hci_get_route(dst, src);
538 if (!hdev)
539 return NULL;
541 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, dst);
543 hci_dev_put(hdev);
545 return conn ? &conn->dev : NULL;
548 static inline void hidp_setup_input(struct hidp_session *session, struct hidp_connadd_req *req)
550 struct input_dev *input = session->input;
551 int i;
553 input->private = session;
555 input->name = "Bluetooth HID Boot Protocol Device";
557 input->id.bustype = BUS_BLUETOOTH;
558 input->id.vendor = req->vendor;
559 input->id.product = req->product;
560 input->id.version = req->version;
562 if (req->subclass & 0x40) {
563 set_bit(EV_KEY, input->evbit);
564 set_bit(EV_LED, input->evbit);
565 set_bit(EV_REP, input->evbit);
567 set_bit(LED_NUML, input->ledbit);
568 set_bit(LED_CAPSL, input->ledbit);
569 set_bit(LED_SCROLLL, input->ledbit);
570 set_bit(LED_COMPOSE, input->ledbit);
571 set_bit(LED_KANA, input->ledbit);
573 for (i = 0; i < sizeof(hidp_keycode); i++)
574 set_bit(hidp_keycode[i], input->keybit);
575 clear_bit(0, input->keybit);
578 if (req->subclass & 0x80) {
579 input->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
580 input->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE);
581 input->relbit[0] = BIT(REL_X) | BIT(REL_Y);
582 input->keybit[LONG(BTN_MOUSE)] |= BIT(BTN_SIDE) | BIT(BTN_EXTRA);
583 input->relbit[0] |= BIT(REL_WHEEL);
586 input->cdev.dev = hidp_get_device(session);
588 input->event = hidp_input_event;
590 input_register_device(input);
593 int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock, struct socket *intr_sock)
595 struct hidp_session *session, *s;
596 int err;
598 BT_DBG("");
600 if (bacmp(&bt_sk(ctrl_sock->sk)->src, &bt_sk(intr_sock->sk)->src) ||
601 bacmp(&bt_sk(ctrl_sock->sk)->dst, &bt_sk(intr_sock->sk)->dst))
602 return -ENOTUNIQ;
604 session = kzalloc(sizeof(struct hidp_session), GFP_KERNEL);
605 if (!session)
606 return -ENOMEM;
608 session->input = input_allocate_device();
609 if (!session->input) {
610 kfree(session);
611 return -ENOMEM;
614 down_write(&hidp_session_sem);
616 s = __hidp_get_session(&bt_sk(ctrl_sock->sk)->dst);
617 if (s && s->state == BT_CONNECTED) {
618 err = -EEXIST;
619 goto failed;
622 bacpy(&session->bdaddr, &bt_sk(ctrl_sock->sk)->dst);
624 session->ctrl_mtu = min_t(uint, l2cap_pi(ctrl_sock->sk)->omtu, l2cap_pi(ctrl_sock->sk)->imtu);
625 session->intr_mtu = min_t(uint, l2cap_pi(intr_sock->sk)->omtu, l2cap_pi(intr_sock->sk)->imtu);
627 BT_DBG("ctrl mtu %d intr mtu %d", session->ctrl_mtu, session->intr_mtu);
629 session->ctrl_sock = ctrl_sock;
630 session->intr_sock = intr_sock;
631 session->state = BT_CONNECTED;
633 init_timer(&session->timer);
635 session->timer.function = hidp_idle_timeout;
636 session->timer.data = (unsigned long) session;
638 skb_queue_head_init(&session->ctrl_transmit);
639 skb_queue_head_init(&session->intr_transmit);
641 session->flags = req->flags & (1 << HIDP_BLUETOOTH_VENDOR_ID);
642 session->idle_to = req->idle_to;
644 if (session->input)
645 hidp_setup_input(session, req);
647 __hidp_link_session(session);
649 hidp_set_timer(session);
651 err = kernel_thread(hidp_session, session, CLONE_KERNEL);
652 if (err < 0)
653 goto unlink;
655 if (session->input) {
656 hidp_send_ctrl_message(session,
657 HIDP_TRANS_SET_PROTOCOL | HIDP_PROTO_BOOT, NULL, 0);
658 session->flags |= (1 << HIDP_BOOT_PROTOCOL_MODE);
660 session->leds = 0xff;
661 hidp_input_event(session->input, EV_LED, 0, 0);
664 up_write(&hidp_session_sem);
665 return 0;
667 unlink:
668 hidp_del_timer(session);
670 __hidp_unlink_session(session);
672 if (session->input) {
673 input_unregister_device(session->input);
674 session->input = NULL; /* don't try to free it here */
677 failed:
678 up_write(&hidp_session_sem);
680 kfree(session->input);
681 kfree(session);
682 return err;
685 int hidp_del_connection(struct hidp_conndel_req *req)
687 struct hidp_session *session;
688 int err = 0;
690 BT_DBG("");
692 down_read(&hidp_session_sem);
694 session = __hidp_get_session(&req->bdaddr);
695 if (session) {
696 if (req->flags & (1 << HIDP_VIRTUAL_CABLE_UNPLUG)) {
697 hidp_send_ctrl_message(session,
698 HIDP_TRANS_HID_CONTROL | HIDP_CTRL_VIRTUAL_CABLE_UNPLUG, NULL, 0);
699 } else {
700 /* Flush the transmit queues */
701 skb_queue_purge(&session->ctrl_transmit);
702 skb_queue_purge(&session->intr_transmit);
704 /* Kill session thread */
705 atomic_inc(&session->terminate);
706 hidp_schedule(session);
708 } else
709 err = -ENOENT;
711 up_read(&hidp_session_sem);
712 return err;
715 int hidp_get_connlist(struct hidp_connlist_req *req)
717 struct list_head *p;
718 int err = 0, n = 0;
720 BT_DBG("");
722 down_read(&hidp_session_sem);
724 list_for_each(p, &hidp_session_list) {
725 struct hidp_session *session;
726 struct hidp_conninfo ci;
728 session = list_entry(p, struct hidp_session, list);
730 __hidp_copy_session(session, &ci);
732 if (copy_to_user(req->ci, &ci, sizeof(ci))) {
733 err = -EFAULT;
734 break;
737 if (++n >= req->cnum)
738 break;
740 req->ci++;
742 req->cnum = n;
744 up_read(&hidp_session_sem);
745 return err;
748 int hidp_get_conninfo(struct hidp_conninfo *ci)
750 struct hidp_session *session;
751 int err = 0;
753 down_read(&hidp_session_sem);
755 session = __hidp_get_session(&ci->bdaddr);
756 if (session)
757 __hidp_copy_session(session, ci);
758 else
759 err = -ENOENT;
761 up_read(&hidp_session_sem);
762 return err;
765 static int __init hidp_init(void)
767 l2cap_load();
769 BT_INFO("HIDP (Human Interface Emulation) ver %s", VERSION);
771 return hidp_init_sockets();
774 static void __exit hidp_exit(void)
776 hidp_cleanup_sockets();
779 module_init(hidp_init);
780 module_exit(hidp_exit);
782 MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
783 MODULE_DESCRIPTION("Bluetooth HIDP ver " VERSION);
784 MODULE_VERSION(VERSION);
785 MODULE_LICENSE("GPL");
786 MODULE_ALIAS("bt-proto-6");