Remove obsolete #include <linux/config.h>
[linux-2.6.git] / net / bluetooth / hidp / core.c
1 /* 
2    HIDP implementation for Linux Bluetooth stack (BlueZ).
3    Copyright (C) 2003-2004 Marcel Holtmann <marcel@holtmann.org>
4
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;
8
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.
17
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.
21 */
22
23 #include <linux/module.h>
24
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>
39
40 #include <linux/input.h>
41
42 #include <net/bluetooth/bluetooth.h>
43 #include <net/bluetooth/l2cap.h>
44
45 #include "hidp.h"
46
47 #ifndef CONFIG_BT_HIDP_DEBUG
48 #undef  BT_DBG
49 #define BT_DBG(D...)
50 #endif
51
52 #define VERSION "1.1"
53
54 static DECLARE_RWSEM(hidp_session_sem);
55 static LIST_HEAD(hidp_session_list);
56
57 static unsigned char hidp_keycode[256] = {
58           0,  0,  0,  0, 30, 48, 46, 32, 18, 33, 34, 35, 23, 36, 37, 38,
59          50, 49, 24, 25, 16, 19, 31, 20, 22, 47, 17, 45, 21, 44,  2,  3,
60           4,  5,  6,  7,  8,  9, 10, 11, 28,  1, 14, 15, 57, 12, 13, 26,
61          27, 43, 43, 39, 40, 41, 51, 52, 53, 58, 59, 60, 61, 62, 63, 64,
62          65, 66, 67, 68, 87, 88, 99, 70,119,110,102,104,111,107,109,106,
63         105,108,103, 69, 98, 55, 74, 78, 96, 79, 80, 81, 75, 76, 77, 71,
64          72, 73, 82, 83, 86,127,116,117,183,184,185,186,187,188,189,190,
65         191,192,193,194,134,138,130,132,128,129,131,137,133,135,136,113,
66         115,114,  0,  0,  0,121,  0, 89, 93,124, 92, 94, 95,  0,  0,  0,
67         122,123, 90, 91, 85,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
68           0,  0,  0,  0,  0,  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          29, 42, 56,125, 97, 54,100,126,164,166,165,163,161,115,114,113,
73         150,158,159,128,136,177,178,176,142,152,173,140
74 };
75
76 static unsigned char hidp_mkeyspat[] = { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 };
77
78 static struct hidp_session *__hidp_get_session(bdaddr_t *bdaddr)
79 {
80         struct hidp_session *session;
81         struct list_head *p;
82
83         BT_DBG("");
84
85         list_for_each(p, &hidp_session_list) {
86                 session = list_entry(p, struct hidp_session, list);
87                 if (!bacmp(bdaddr, &session->bdaddr))
88                         return session;
89         }
90         return NULL;
91 }
92
93 static void __hidp_link_session(struct hidp_session *session)
94 {
95         __module_get(THIS_MODULE);
96         list_add(&session->list, &hidp_session_list);
97 }
98
99 static void __hidp_unlink_session(struct hidp_session *session)
100 {
101         list_del(&session->list);
102         module_put(THIS_MODULE);
103 }
104
105 static void __hidp_copy_session(struct hidp_session *session, struct hidp_conninfo *ci)
106 {
107         bacpy(&ci->bdaddr, &session->bdaddr);
108
109         ci->flags = session->flags;
110         ci->state = session->state;
111
112         ci->vendor  = 0x0000;
113         ci->product = 0x0000;
114         ci->version = 0x0000;
115         memset(ci->name, 0, 128);
116
117         if (session->input) {
118                 ci->vendor  = session->input->id.vendor;
119                 ci->product = session->input->id.product;
120                 ci->version = session->input->id.version;
121                 if (session->input->name)
122                         strncpy(ci->name, session->input->name, 128);
123                 else
124                         strncpy(ci->name, "HID Boot Device", 128);
125         }
126 }
127
128 static int hidp_input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
129 {
130         struct hidp_session *session = dev->private;
131         struct sk_buff *skb;
132         unsigned char newleds;
133
134         BT_DBG("input %p type %d code %d value %d", dev, type, code, value);
135
136         if (type != EV_LED)
137                 return -1;
138
139         newleds = (!!test_bit(LED_KANA,    dev->led) << 3) |
140                   (!!test_bit(LED_COMPOSE, dev->led) << 3) |
141                   (!!test_bit(LED_SCROLLL, dev->led) << 2) |
142                   (!!test_bit(LED_CAPSL,   dev->led) << 1) |
143                   (!!test_bit(LED_NUML,    dev->led));
144
145         if (session->leds == newleds)
146                 return 0;
147
148         session->leds = newleds;
149
150         if (!(skb = alloc_skb(3, GFP_ATOMIC))) {
151                 BT_ERR("Can't allocate memory for new frame");
152                 return -ENOMEM;
153         }
154
155         *skb_put(skb, 1) = HIDP_TRANS_DATA | HIDP_DATA_RTYPE_OUPUT;
156         *skb_put(skb, 1) = 0x01;
157         *skb_put(skb, 1) = newleds;
158
159         skb_queue_tail(&session->intr_transmit, skb);
160
161         hidp_schedule(session);
162
163         return 0;
164 }
165
166 static void hidp_input_report(struct hidp_session *session, struct sk_buff *skb)
167 {
168         struct input_dev *dev = session->input;
169         unsigned char *keys = session->keys;
170         unsigned char *udata = skb->data + 1;
171         signed char *sdata = skb->data + 1;
172         int i, size = skb->len - 1;
173
174         switch (skb->data[0]) {
175         case 0x01:      /* Keyboard report */
176                 for (i = 0; i < 8; i++)
177                         input_report_key(dev, hidp_keycode[i + 224], (udata[0] >> i) & 1);
178
179                 /* If all the key codes have been set to 0x01, it means
180                  * too many keys were pressed at the same time. */
181                 if (!memcmp(udata + 2, hidp_mkeyspat, 6))
182                         break;
183
184                 for (i = 2; i < 8; i++) {
185                         if (keys[i] > 3 && memscan(udata + 2, keys[i], 6) == udata + 8) {
186                                 if (hidp_keycode[keys[i]])
187                                         input_report_key(dev, hidp_keycode[keys[i]], 0);
188                                 else
189                                         BT_ERR("Unknown key (scancode %#x) released.", keys[i]);
190                         }
191
192                         if (udata[i] > 3 && memscan(keys + 2, udata[i], 6) == keys + 8) {
193                                 if (hidp_keycode[udata[i]])
194                                         input_report_key(dev, hidp_keycode[udata[i]], 1);
195                                 else
196                                         BT_ERR("Unknown key (scancode %#x) pressed.", udata[i]);
197                         }
198                 }
199
200                 memcpy(keys, udata, 8);
201                 break;
202
203         case 0x02:      /* Mouse report */
204                 input_report_key(dev, BTN_LEFT,   sdata[0] & 0x01);
205                 input_report_key(dev, BTN_RIGHT,  sdata[0] & 0x02);
206                 input_report_key(dev, BTN_MIDDLE, sdata[0] & 0x04);
207                 input_report_key(dev, BTN_SIDE,   sdata[0] & 0x08);
208                 input_report_key(dev, BTN_EXTRA,  sdata[0] & 0x10);
209
210                 input_report_rel(dev, REL_X, sdata[1]);
211                 input_report_rel(dev, REL_Y, sdata[2]);
212
213                 if (size > 3)
214                         input_report_rel(dev, REL_WHEEL, sdata[3]);
215                 break;
216         }
217
218         input_sync(dev);
219 }
220
221 static void hidp_idle_timeout(unsigned long arg)
222 {
223         struct hidp_session *session = (struct hidp_session *) arg;
224
225         atomic_inc(&session->terminate);
226         hidp_schedule(session);
227 }
228
229 static inline void hidp_set_timer(struct hidp_session *session)
230 {
231         if (session->idle_to > 0)
232                 mod_timer(&session->timer, jiffies + HZ * session->idle_to);
233 }
234
235 static inline void hidp_del_timer(struct hidp_session *session)
236 {
237         if (session->idle_to > 0)
238                 del_timer(&session->timer);
239 }
240
241 static int __hidp_send_ctrl_message(struct hidp_session *session,
242                         unsigned char hdr, unsigned char *data, int size)
243 {
244         struct sk_buff *skb;
245
246         BT_DBG("session %p data %p size %d", session, data, size);
247
248         if (!(skb = alloc_skb(size + 1, GFP_ATOMIC))) {
249                 BT_ERR("Can't allocate memory for new frame");
250                 return -ENOMEM;
251         }
252
253         *skb_put(skb, 1) = hdr;
254         if (data && size > 0)
255                 memcpy(skb_put(skb, size), data, size);
256
257         skb_queue_tail(&session->ctrl_transmit, skb);
258
259         return 0;
260 }
261
262 static int inline hidp_send_ctrl_message(struct hidp_session *session,
263                         unsigned char hdr, unsigned char *data, int size)
264 {
265         int err;
266
267         err = __hidp_send_ctrl_message(session, hdr, data, size);
268
269         hidp_schedule(session);
270
271         return err;
272 }
273
274 static inline void hidp_process_handshake(struct hidp_session *session, unsigned char param)
275 {
276         BT_DBG("session %p param 0x%02x", session, param);
277
278         switch (param) {
279         case HIDP_HSHK_SUCCESSFUL:
280                 /* FIXME: Call into SET_ GET_ handlers here */
281                 break;
282
283         case HIDP_HSHK_NOT_READY:
284         case HIDP_HSHK_ERR_INVALID_REPORT_ID:
285         case HIDP_HSHK_ERR_UNSUPPORTED_REQUEST:
286         case HIDP_HSHK_ERR_INVALID_PARAMETER:
287                 /* FIXME: Call into SET_ GET_ handlers here */
288                 break;
289
290         case HIDP_HSHK_ERR_UNKNOWN:
291                 break;
292
293         case HIDP_HSHK_ERR_FATAL:
294                 /* Device requests a reboot, as this is the only way this error
295                  * can be recovered. */
296                 __hidp_send_ctrl_message(session,
297                         HIDP_TRANS_HID_CONTROL | HIDP_CTRL_SOFT_RESET, NULL, 0);
298                 break;
299
300         default:
301                 __hidp_send_ctrl_message(session,
302                         HIDP_TRANS_HANDSHAKE | HIDP_HSHK_ERR_INVALID_PARAMETER, NULL, 0);
303                 break;
304         }
305 }
306
307 static inline void hidp_process_hid_control(struct hidp_session *session, unsigned char param)
308 {
309         BT_DBG("session %p param 0x%02x", session, param);
310
311         switch (param) {
312         case HIDP_CTRL_NOP:
313                 break;
314
315         case HIDP_CTRL_VIRTUAL_CABLE_UNPLUG:
316                 /* Flush the transmit queues */
317                 skb_queue_purge(&session->ctrl_transmit);
318                 skb_queue_purge(&session->intr_transmit);
319
320                 /* Kill session thread */
321                 atomic_inc(&session->terminate);
322                 break;
323
324         case HIDP_CTRL_HARD_RESET:
325         case HIDP_CTRL_SOFT_RESET:
326         case HIDP_CTRL_SUSPEND:
327         case HIDP_CTRL_EXIT_SUSPEND:
328                 /* FIXME: We have to parse these and return no error */
329                 break;
330
331         default:
332                 __hidp_send_ctrl_message(session,
333                         HIDP_TRANS_HANDSHAKE | HIDP_HSHK_ERR_INVALID_PARAMETER, NULL, 0);
334                 break;
335         }
336 }
337
338 static inline void hidp_process_data(struct hidp_session *session, struct sk_buff *skb, unsigned char param)
339 {
340         BT_DBG("session %p skb %p len %d param 0x%02x", session, skb, skb->len, param);
341
342         switch (param) {
343         case HIDP_DATA_RTYPE_INPUT:
344                 hidp_set_timer(session);
345
346                 if (session->input)
347                         hidp_input_report(session, skb);
348                 break;
349
350         case HIDP_DATA_RTYPE_OTHER:
351         case HIDP_DATA_RTYPE_OUPUT:
352         case HIDP_DATA_RTYPE_FEATURE:
353                 break;
354
355         default:
356                 __hidp_send_ctrl_message(session,
357                         HIDP_TRANS_HANDSHAKE | HIDP_HSHK_ERR_INVALID_PARAMETER, NULL, 0);
358         }
359 }
360
361 static inline void hidp_recv_ctrl_frame(struct hidp_session *session, struct sk_buff *skb)
362 {
363         unsigned char hdr, type, param;
364
365         BT_DBG("session %p skb %p len %d", session, skb, skb->len);
366
367         hdr = skb->data[0];
368         skb_pull(skb, 1);
369
370         type = hdr & HIDP_HEADER_TRANS_MASK;
371         param = hdr & HIDP_HEADER_PARAM_MASK;
372
373         switch (type) {
374         case HIDP_TRANS_HANDSHAKE:
375                 hidp_process_handshake(session, param);
376                 break;
377
378         case HIDP_TRANS_HID_CONTROL:
379                 hidp_process_hid_control(session, param);
380                 break;
381
382         case HIDP_TRANS_DATA:
383                 hidp_process_data(session, skb, param);
384                 break;
385
386         default:
387                 __hidp_send_ctrl_message(session,
388                         HIDP_TRANS_HANDSHAKE | HIDP_HSHK_ERR_UNSUPPORTED_REQUEST, NULL, 0);
389                 break;
390         }
391
392         kfree_skb(skb);
393 }
394
395 static inline void hidp_recv_intr_frame(struct hidp_session *session, struct sk_buff *skb)
396 {
397         unsigned char hdr;
398
399         BT_DBG("session %p skb %p len %d", session, skb, skb->len);
400
401         hdr = skb->data[0];
402         skb_pull(skb, 1);
403
404         if (hdr == (HIDP_TRANS_DATA | HIDP_DATA_RTYPE_INPUT)) {
405                 hidp_set_timer(session);
406                 if (session->input)
407                         hidp_input_report(session, skb);
408         } else {
409                 BT_DBG("Unsupported protocol header 0x%02x", hdr);
410         }
411
412         kfree_skb(skb);
413 }
414
415 static int hidp_send_frame(struct socket *sock, unsigned char *data, int len)
416 {
417         struct kvec iv = { data, len };
418         struct msghdr msg;
419
420         BT_DBG("sock %p data %p len %d", sock, data, len);
421
422         if (!len)
423                 return 0;
424
425         memset(&msg, 0, sizeof(msg));
426
427         return kernel_sendmsg(sock, &msg, &iv, 1, len);
428 }
429
430 static void hidp_process_transmit(struct hidp_session *session)
431 {
432         struct sk_buff *skb;
433
434         BT_DBG("session %p", session);
435
436         while ((skb = skb_dequeue(&session->ctrl_transmit))) {
437                 if (hidp_send_frame(session->ctrl_sock, skb->data, skb->len) < 0) {
438                         skb_queue_head(&session->ctrl_transmit, skb);
439                         break;
440                 }
441
442                 hidp_set_timer(session);
443                 kfree_skb(skb);
444         }
445
446         while ((skb = skb_dequeue(&session->intr_transmit))) {
447                 if (hidp_send_frame(session->intr_sock, skb->data, skb->len) < 0) {
448                         skb_queue_head(&session->intr_transmit, skb);
449                         break;
450                 }
451
452                 hidp_set_timer(session);
453                 kfree_skb(skb);
454         }
455 }
456
457 static int hidp_session(void *arg)
458 {
459         struct hidp_session *session = arg;
460         struct sock *ctrl_sk = session->ctrl_sock->sk;
461         struct sock *intr_sk = session->intr_sock->sk;
462         struct sk_buff *skb;
463         int vendor = 0x0000, product = 0x0000;
464         wait_queue_t ctrl_wait, intr_wait;
465
466         BT_DBG("session %p", session);
467
468         if (session->input) {
469                 vendor  = session->input->id.vendor;
470                 product = session->input->id.product;
471         }
472
473         daemonize("khidpd_%04x%04x", vendor, product);
474         set_user_nice(current, -15);
475         current->flags |= PF_NOFREEZE;
476
477         init_waitqueue_entry(&ctrl_wait, current);
478         init_waitqueue_entry(&intr_wait, current);
479         add_wait_queue(ctrl_sk->sk_sleep, &ctrl_wait);
480         add_wait_queue(intr_sk->sk_sleep, &intr_wait);
481         while (!atomic_read(&session->terminate)) {
482                 set_current_state(TASK_INTERRUPTIBLE);
483
484                 if (ctrl_sk->sk_state != BT_CONNECTED || intr_sk->sk_state != BT_CONNECTED)
485                         break;
486
487                 while ((skb = skb_dequeue(&ctrl_sk->sk_receive_queue))) {
488                         skb_orphan(skb);
489                         hidp_recv_ctrl_frame(session, skb);
490                 }
491
492                 while ((skb = skb_dequeue(&intr_sk->sk_receive_queue))) {
493                         skb_orphan(skb);
494                         hidp_recv_intr_frame(session, skb);
495                 }
496
497                 hidp_process_transmit(session);
498
499                 schedule();
500         }
501         set_current_state(TASK_RUNNING);
502         remove_wait_queue(intr_sk->sk_sleep, &intr_wait);
503         remove_wait_queue(ctrl_sk->sk_sleep, &ctrl_wait);
504
505         down_write(&hidp_session_sem);
506
507         hidp_del_timer(session);
508
509         if (intr_sk->sk_state != BT_CONNECTED)
510                 wait_event_timeout(*(ctrl_sk->sk_sleep), (ctrl_sk->sk_state == BT_CLOSED), HZ);
511
512         fput(session->ctrl_sock->file);
513
514         wait_event_timeout(*(intr_sk->sk_sleep), (intr_sk->sk_state == BT_CLOSED), HZ);
515
516         fput(session->intr_sock->file);
517
518         __hidp_unlink_session(session);
519
520         if (session->input) {
521                 input_unregister_device(session->input);
522                 session->input = NULL;
523         }
524
525         up_write(&hidp_session_sem);
526
527         kfree(session);
528         return 0;
529 }
530
531 static inline void hidp_setup_input(struct hidp_session *session, struct hidp_connadd_req *req)
532 {
533         struct input_dev *input = session->input;
534         int i;
535
536         input->private = session;
537
538         input->name = "Bluetooth HID Boot Protocol Device";
539
540         input->id.bustype = BUS_BLUETOOTH;
541         input->id.vendor  = req->vendor;
542         input->id.product = req->product;
543         input->id.version = req->version;
544
545         if (req->subclass & 0x40) {
546                 set_bit(EV_KEY, input->evbit);
547                 set_bit(EV_LED, input->evbit);
548                 set_bit(EV_REP, input->evbit);
549
550                 set_bit(LED_NUML,    input->ledbit);
551                 set_bit(LED_CAPSL,   input->ledbit);
552                 set_bit(LED_SCROLLL, input->ledbit);
553                 set_bit(LED_COMPOSE, input->ledbit);
554                 set_bit(LED_KANA,    input->ledbit);
555
556                 for (i = 0; i < sizeof(hidp_keycode); i++)
557                         set_bit(hidp_keycode[i], input->keybit);
558                 clear_bit(0, input->keybit);
559         }
560
561         if (req->subclass & 0x80) {
562                 input->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
563                 input->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE);
564                 input->relbit[0] = BIT(REL_X) | BIT(REL_Y);
565                 input->keybit[LONG(BTN_MOUSE)] |= BIT(BTN_SIDE) | BIT(BTN_EXTRA);
566                 input->relbit[0] |= BIT(REL_WHEEL);
567         }
568
569         input->event = hidp_input_event;
570
571         input_register_device(input);
572 }
573
574 int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock, struct socket *intr_sock)
575 {
576         struct hidp_session *session, *s;
577         int err;
578
579         BT_DBG("");
580
581         if (bacmp(&bt_sk(ctrl_sock->sk)->src, &bt_sk(intr_sock->sk)->src) ||
582                         bacmp(&bt_sk(ctrl_sock->sk)->dst, &bt_sk(intr_sock->sk)->dst))
583                 return -ENOTUNIQ;
584
585         session = kmalloc(sizeof(struct hidp_session), GFP_KERNEL);
586         if (!session)
587                 return -ENOMEM;
588         memset(session, 0, sizeof(struct hidp_session));
589
590         session->input = input_allocate_device();
591         if (!session->input) {
592                 kfree(session);
593                 return -ENOMEM;
594         }
595
596         down_write(&hidp_session_sem);
597
598         s = __hidp_get_session(&bt_sk(ctrl_sock->sk)->dst);
599         if (s && s->state == BT_CONNECTED) {
600                 err = -EEXIST;
601                 goto failed;
602         }
603
604         bacpy(&session->bdaddr, &bt_sk(ctrl_sock->sk)->dst);
605
606         session->ctrl_mtu = min_t(uint, l2cap_pi(ctrl_sock->sk)->omtu, l2cap_pi(ctrl_sock->sk)->imtu);
607         session->intr_mtu = min_t(uint, l2cap_pi(intr_sock->sk)->omtu, l2cap_pi(intr_sock->sk)->imtu);
608
609         BT_DBG("ctrl mtu %d intr mtu %d", session->ctrl_mtu, session->intr_mtu);
610
611         session->ctrl_sock = ctrl_sock;
612         session->intr_sock = intr_sock;
613         session->state     = BT_CONNECTED;
614
615         init_timer(&session->timer);
616
617         session->timer.function = hidp_idle_timeout;
618         session->timer.data     = (unsigned long) session;
619
620         skb_queue_head_init(&session->ctrl_transmit);
621         skb_queue_head_init(&session->intr_transmit);
622
623         session->flags   = req->flags & (1 << HIDP_BLUETOOTH_VENDOR_ID);
624         session->idle_to = req->idle_to;
625
626         if (session->input)
627                 hidp_setup_input(session, req);
628
629         __hidp_link_session(session);
630
631         hidp_set_timer(session);
632
633         err = kernel_thread(hidp_session, session, CLONE_KERNEL);
634         if (err < 0)
635                 goto unlink;
636
637         if (session->input) {
638                 hidp_send_ctrl_message(session,
639                         HIDP_TRANS_SET_PROTOCOL | HIDP_PROTO_BOOT, NULL, 0);
640                 session->flags |= (1 << HIDP_BOOT_PROTOCOL_MODE);
641
642                 session->leds = 0xff;
643                 hidp_input_event(session->input, EV_LED, 0, 0);
644         }
645
646         up_write(&hidp_session_sem);
647         return 0;
648
649 unlink:
650         hidp_del_timer(session);
651
652         __hidp_unlink_session(session);
653
654         if (session->input) {
655                 input_unregister_device(session->input);
656                 session->input = NULL; /* don't try to free it here */
657         }
658
659 failed:
660         up_write(&hidp_session_sem);
661
662         kfree(session->input);
663         kfree(session);
664         return err;
665 }
666
667 int hidp_del_connection(struct hidp_conndel_req *req)
668 {
669         struct hidp_session *session;
670         int err = 0;
671
672         BT_DBG("");
673
674         down_read(&hidp_session_sem);
675
676         session = __hidp_get_session(&req->bdaddr);
677         if (session) {
678                 if (req->flags & (1 << HIDP_VIRTUAL_CABLE_UNPLUG)) {
679                         hidp_send_ctrl_message(session,
680                                 HIDP_TRANS_HID_CONTROL | HIDP_CTRL_VIRTUAL_CABLE_UNPLUG, NULL, 0);
681                 } else {
682                         /* Flush the transmit queues */
683                         skb_queue_purge(&session->ctrl_transmit);
684                         skb_queue_purge(&session->intr_transmit);
685
686                         /* Kill session thread */
687                         atomic_inc(&session->terminate);
688                         hidp_schedule(session);
689                 }
690         } else
691                 err = -ENOENT;
692
693         up_read(&hidp_session_sem);
694         return err;
695 }
696
697 int hidp_get_connlist(struct hidp_connlist_req *req)
698 {
699         struct list_head *p;
700         int err = 0, n = 0;
701
702         BT_DBG("");
703
704         down_read(&hidp_session_sem);
705
706         list_for_each(p, &hidp_session_list) {
707                 struct hidp_session *session;
708                 struct hidp_conninfo ci;
709
710                 session = list_entry(p, struct hidp_session, list);
711
712                 __hidp_copy_session(session, &ci);
713
714                 if (copy_to_user(req->ci, &ci, sizeof(ci))) {
715                         err = -EFAULT;
716                         break;
717                 }
718
719                 if (++n >= req->cnum)
720                         break;
721
722                 req->ci++;
723         }
724         req->cnum = n;
725
726         up_read(&hidp_session_sem);
727         return err;
728 }
729
730 int hidp_get_conninfo(struct hidp_conninfo *ci)
731 {
732         struct hidp_session *session;
733         int err = 0;
734
735         down_read(&hidp_session_sem);
736
737         session = __hidp_get_session(&ci->bdaddr);
738         if (session)
739                 __hidp_copy_session(session, ci);
740         else
741                 err = -ENOENT;
742
743         up_read(&hidp_session_sem);
744         return err;
745 }
746
747 static int __init hidp_init(void)
748 {
749         l2cap_load();
750
751         BT_INFO("HIDP (Human Interface Emulation) ver %s", VERSION);
752
753         return hidp_init_sockets();
754 }
755
756 static void __exit hidp_exit(void)
757 {
758         hidp_cleanup_sockets();
759 }
760
761 module_init(hidp_init);
762 module_exit(hidp_exit);
763
764 MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
765 MODULE_DESCRIPTION("Bluetooth HIDP ver " VERSION);
766 MODULE_VERSION(VERSION);
767 MODULE_LICENSE("GPL");
768 MODULE_ALIAS("bt-proto-6");