core.c revision b03efcfb2180289718991bb984044ce6c5b7d1b0
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/sched.h>
30#include <linux/slab.h>
31#include <linux/poll.h>
32#include <linux/fcntl.h>
33#include <linux/skbuff.h>
34#include <linux/socket.h>
35#include <linux/ioctl.h>
36#include <linux/file.h>
37#include <linux/init.h>
38#include <linux/wait.h>
39#include <net/sock.h>
40
41#include <linux/input.h>
42
43#include <net/bluetooth/bluetooth.h>
44#include <net/bluetooth/l2cap.h>
45
46#include "hidp.h"
47
48#ifndef CONFIG_BT_HIDP_DEBUG
49#undef  BT_DBG
50#define BT_DBG(D...)
51#endif
52
53#define VERSION "1.1"
54
55static DECLARE_RWSEM(hidp_session_sem);
56static LIST_HEAD(hidp_session_list);
57
58static 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
75};
76
77static unsigned char hidp_mkeyspat[] = { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 };
78
79static struct hidp_session *__hidp_get_session(bdaddr_t *bdaddr)
80{
81	struct hidp_session *session;
82	struct list_head *p;
83
84	BT_DBG("");
85
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;
90	}
91	return NULL;
92}
93
94static void __hidp_link_session(struct hidp_session *session)
95{
96	__module_get(THIS_MODULE);
97	list_add(&session->list, &hidp_session_list);
98}
99
100static void __hidp_unlink_session(struct hidp_session *session)
101{
102	list_del(&session->list);
103	module_put(THIS_MODULE);
104}
105
106static void __hidp_copy_session(struct hidp_session *session, struct hidp_conninfo *ci)
107{
108	bacpy(&ci->bdaddr, &session->bdaddr);
109
110	ci->flags = session->flags;
111	ci->state = session->state;
112
113	ci->vendor  = 0x0000;
114	ci->product = 0x0000;
115	ci->version = 0x0000;
116	memset(ci->name, 0, 128);
117
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);
126	}
127}
128
129static int hidp_input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
130{
131	struct hidp_session *session = dev->private;
132	struct sk_buff *skb;
133	unsigned char newleds;
134
135	BT_DBG("input %p type %d code %d value %d", dev, type, code, value);
136
137	if (type != EV_LED)
138		return -1;
139
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));
145
146	if (session->leds == newleds)
147		return 0;
148
149	session->leds = newleds;
150
151	if (!(skb = alloc_skb(3, GFP_ATOMIC))) {
152		BT_ERR("Can't allocate memory for new frame");
153		return -ENOMEM;
154	}
155
156	*skb_put(skb, 1) = HIDP_TRANS_DATA | HIDP_DATA_RTYPE_OUPUT;
157	*skb_put(skb, 1) = 0x01;
158	*skb_put(skb, 1) = newleds;
159
160	skb_queue_tail(&session->intr_transmit, skb);
161
162	hidp_schedule(session);
163
164	return 0;
165}
166
167static void hidp_input_report(struct hidp_session *session, struct sk_buff *skb)
168{
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;
174
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);
179
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;
184
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]);
191			}
192
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]);
198			}
199		}
200
201		memcpy(keys, udata, 8);
202		break;
203
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);
210
211		input_report_rel(dev, REL_X, sdata[1]);
212		input_report_rel(dev, REL_Y, sdata[2]);
213
214		if (size > 3)
215			input_report_rel(dev, REL_WHEEL, sdata[3]);
216		break;
217	}
218
219	input_sync(dev);
220}
221
222static void hidp_idle_timeout(unsigned long arg)
223{
224	struct hidp_session *session = (struct hidp_session *) arg;
225
226	atomic_inc(&session->terminate);
227	hidp_schedule(session);
228}
229
230static inline void hidp_set_timer(struct hidp_session *session)
231{
232	if (session->idle_to > 0)
233		mod_timer(&session->timer, jiffies + HZ * session->idle_to);
234}
235
236static inline void hidp_del_timer(struct hidp_session *session)
237{
238	if (session->idle_to > 0)
239		del_timer(&session->timer);
240}
241
242static int __hidp_send_ctrl_message(struct hidp_session *session,
243			unsigned char hdr, unsigned char *data, int size)
244{
245	struct sk_buff *skb;
246
247	BT_DBG("session %p data %p size %d", session, data, size);
248
249	if (!(skb = alloc_skb(size + 1, GFP_ATOMIC))) {
250		BT_ERR("Can't allocate memory for new frame");
251		return -ENOMEM;
252	}
253
254	*skb_put(skb, 1) = hdr;
255	if (data && size > 0)
256		memcpy(skb_put(skb, size), data, size);
257
258	skb_queue_tail(&session->ctrl_transmit, skb);
259
260	return 0;
261}
262
263static int inline hidp_send_ctrl_message(struct hidp_session *session,
264			unsigned char hdr, unsigned char *data, int size)
265{
266	int err;
267
268	err = __hidp_send_ctrl_message(session, hdr, data, size);
269
270	hidp_schedule(session);
271
272	return err;
273}
274
275static inline void hidp_process_handshake(struct hidp_session *session, unsigned char param)
276{
277	BT_DBG("session %p param 0x%02x", session, param);
278
279	switch (param) {
280	case HIDP_HSHK_SUCCESSFUL:
281		/* FIXME: Call into SET_ GET_ handlers here */
282		break;
283
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;
290
291	case HIDP_HSHK_ERR_UNKNOWN:
292		break;
293
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;
300
301	default:
302		__hidp_send_ctrl_message(session,
303			HIDP_TRANS_HANDSHAKE | HIDP_HSHK_ERR_INVALID_PARAMETER, NULL, 0);
304		break;
305	}
306}
307
308static inline void hidp_process_hid_control(struct hidp_session *session, unsigned char param)
309{
310	BT_DBG("session %p param 0x%02x", session, param);
311
312	switch (param) {
313	case HIDP_CTRL_NOP:
314		break;
315
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);
320
321		/* Kill session thread */
322		atomic_inc(&session->terminate);
323		break;
324
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;
331
332	default:
333		__hidp_send_ctrl_message(session,
334			HIDP_TRANS_HANDSHAKE | HIDP_HSHK_ERR_INVALID_PARAMETER, NULL, 0);
335		break;
336	}
337}
338
339static inline void hidp_process_data(struct hidp_session *session, struct sk_buff *skb, unsigned char param)
340{
341	BT_DBG("session %p skb %p len %d param 0x%02x", session, skb, skb->len, param);
342
343	switch (param) {
344	case HIDP_DATA_RTYPE_INPUT:
345		hidp_set_timer(session);
346
347		if (session->input)
348			hidp_input_report(session, skb);
349		break;
350
351	case HIDP_DATA_RTYPE_OTHER:
352	case HIDP_DATA_RTYPE_OUPUT:
353	case HIDP_DATA_RTYPE_FEATURE:
354		break;
355
356	default:
357		__hidp_send_ctrl_message(session,
358			HIDP_TRANS_HANDSHAKE | HIDP_HSHK_ERR_INVALID_PARAMETER, NULL, 0);
359	}
360}
361
362static inline void hidp_recv_ctrl_frame(struct hidp_session *session, struct sk_buff *skb)
363{
364	unsigned char hdr, type, param;
365
366	BT_DBG("session %p skb %p len %d", session, skb, skb->len);
367
368	hdr = skb->data[0];
369	skb_pull(skb, 1);
370
371	type = hdr & HIDP_HEADER_TRANS_MASK;
372	param = hdr & HIDP_HEADER_PARAM_MASK;
373
374	switch (type) {
375	case HIDP_TRANS_HANDSHAKE:
376		hidp_process_handshake(session, param);
377		break;
378
379	case HIDP_TRANS_HID_CONTROL:
380		hidp_process_hid_control(session, param);
381		break;
382
383	case HIDP_TRANS_DATA:
384		hidp_process_data(session, skb, param);
385		break;
386
387	default:
388		__hidp_send_ctrl_message(session,
389			HIDP_TRANS_HANDSHAKE | HIDP_HSHK_ERR_UNSUPPORTED_REQUEST, NULL, 0);
390		break;
391	}
392
393	kfree_skb(skb);
394}
395
396static inline void hidp_recv_intr_frame(struct hidp_session *session, struct sk_buff *skb)
397{
398	unsigned char hdr;
399
400	BT_DBG("session %p skb %p len %d", session, skb, skb->len);
401
402	hdr = skb->data[0];
403	skb_pull(skb, 1);
404
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);
411	}
412
413	kfree_skb(skb);
414}
415
416static int hidp_send_frame(struct socket *sock, unsigned char *data, int len)
417{
418	struct kvec iv = { data, len };
419	struct msghdr msg;
420
421	BT_DBG("sock %p data %p len %d", sock, data, len);
422
423	if (!len)
424		return 0;
425
426	memset(&msg, 0, sizeof(msg));
427
428	return kernel_sendmsg(sock, &msg, &iv, 1, len);
429}
430
431static void hidp_process_transmit(struct hidp_session *session)
432{
433	struct sk_buff *skb;
434
435	BT_DBG("session %p", session);
436
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;
441		}
442
443		hidp_set_timer(session);
444		kfree_skb(skb);
445	}
446
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;
451		}
452
453		hidp_set_timer(session);
454		kfree_skb(skb);
455	}
456}
457
458static int hidp_session(void *arg)
459{
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;
466
467	BT_DBG("session %p", session);
468
469	if (session->input) {
470		vendor  = session->input->id.vendor;
471		product = session->input->id.product;
472	}
473
474	daemonize("khidpd_%04x%04x", vendor, product);
475	set_user_nice(current, -15);
476	current->flags |= PF_NOFREEZE;
477
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);
484
485		if (ctrl_sk->sk_state != BT_CONNECTED || intr_sk->sk_state != BT_CONNECTED)
486			break;
487
488		while ((skb = skb_dequeue(&ctrl_sk->sk_receive_queue))) {
489			skb_orphan(skb);
490			hidp_recv_ctrl_frame(session, skb);
491		}
492
493		while ((skb = skb_dequeue(&intr_sk->sk_receive_queue))) {
494			skb_orphan(skb);
495			hidp_recv_intr_frame(session, skb);
496		}
497
498		hidp_process_transmit(session);
499
500		schedule();
501	}
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);
505
506	down_write(&hidp_session_sem);
507
508	hidp_del_timer(session);
509
510	if (intr_sk->sk_state != BT_CONNECTED)
511		wait_event_timeout(*(ctrl_sk->sk_sleep), (ctrl_sk->sk_state == BT_CLOSED), HZ);
512
513	fput(session->ctrl_sock->file);
514
515	wait_event_timeout(*(intr_sk->sk_sleep), (intr_sk->sk_state == BT_CLOSED), HZ);
516
517	fput(session->intr_sock->file);
518
519	__hidp_unlink_session(session);
520
521	if (session->input) {
522		input_unregister_device(session->input);
523		kfree(session->input);
524	}
525
526	up_write(&hidp_session_sem);
527
528	kfree(session);
529	return 0;
530}
531
532static inline void hidp_setup_input(struct hidp_session *session, struct hidp_connadd_req *req)
533{
534	struct input_dev *input = session->input;
535	int i;
536
537	input->private = session;
538
539	input->id.bustype = BUS_BLUETOOTH;
540	input->id.vendor  = req->vendor;
541	input->id.product = req->product;
542	input->id.version = req->version;
543
544	if (req->subclass & 0x40) {
545		set_bit(EV_KEY, input->evbit);
546		set_bit(EV_LED, input->evbit);
547		set_bit(EV_REP, input->evbit);
548
549		set_bit(LED_NUML,    input->ledbit);
550		set_bit(LED_CAPSL,   input->ledbit);
551		set_bit(LED_SCROLLL, input->ledbit);
552		set_bit(LED_COMPOSE, input->ledbit);
553		set_bit(LED_KANA,    input->ledbit);
554
555		for (i = 0; i < sizeof(hidp_keycode); i++)
556			set_bit(hidp_keycode[i], input->keybit);
557		clear_bit(0, input->keybit);
558	}
559
560	if (req->subclass & 0x80) {
561		input->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
562		input->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE);
563		input->relbit[0] = BIT(REL_X) | BIT(REL_Y);
564		input->keybit[LONG(BTN_MOUSE)] |= BIT(BTN_SIDE) | BIT(BTN_EXTRA);
565		input->relbit[0] |= BIT(REL_WHEEL);
566	}
567
568	input->event = hidp_input_event;
569
570	input_register_device(input);
571}
572
573int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock, struct socket *intr_sock)
574{
575	struct hidp_session *session, *s;
576	int err;
577
578	BT_DBG("");
579
580	if (bacmp(&bt_sk(ctrl_sock->sk)->src, &bt_sk(intr_sock->sk)->src) ||
581			bacmp(&bt_sk(ctrl_sock->sk)->dst, &bt_sk(intr_sock->sk)->dst))
582		return -ENOTUNIQ;
583
584	session = kmalloc(sizeof(struct hidp_session), GFP_KERNEL);
585	if (!session)
586		return -ENOMEM;
587	memset(session, 0, sizeof(struct hidp_session));
588
589	session->input = kmalloc(sizeof(struct input_dev), GFP_KERNEL);
590	if (!session->input) {
591		kfree(session);
592		return -ENOMEM;
593	}
594	memset(session->input, 0, sizeof(struct input_dev));
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
649unlink:
650	hidp_del_timer(session);
651
652	__hidp_unlink_session(session);
653
654	if (session->input)
655		input_unregister_device(session->input);
656
657failed:
658	up_write(&hidp_session_sem);
659
660	if (session->input)
661		kfree(session->input);
662
663	kfree(session);
664	return err;
665}
666
667int 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
697int 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
730int 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
747static 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
756static void __exit hidp_exit(void)
757{
758	hidp_cleanup_sockets();
759}
760
761module_init(hidp_init);
762module_exit(hidp_exit);
763
764MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
765MODULE_DESCRIPTION("Bluetooth HIDP ver " VERSION);
766MODULE_VERSION(VERSION);
767MODULE_LICENSE("GPL");
768MODULE_ALIAS("bt-proto-6");
769