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