core.c revision 7b19ffc40b0247fcfe083644fdb621fdb3c05ef6
1469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg/*
2469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg   HIDP implementation for Linux Bluetooth stack (BlueZ).
3469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg   Copyright (C) 2003-2004 Marcel Holtmann <marcel@holtmann.org>
4469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
5469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg   This program is free software; you can redistribute it and/or modify
6469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg   it under the terms of the GNU General Public License version 2 as
7469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg   published by the Free Software Foundation;
8469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
9469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
10469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
11469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
12469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg   IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
13469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg   CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
14469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg   WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg   ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
18469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg   ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
19469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg   COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
20469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg   SOFTWARE IS DISCLAIMED.
21469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg*/
22469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
23469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg#include <linux/module.h>
24469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
252448798133d747ad339e57099e32a1d1e68aca1cJohannes Berg#include <linux/types.h>
26469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg#include <linux/errno.h>
27469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg#include <linux/kernel.h>
28469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg#include <linux/sched.h>
29469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg#include <linux/slab.h>
30469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg#include <linux/poll.h>
31469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg#include <linux/fcntl.h>
32469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg#include <linux/skbuff.h>
334a332a385a86e31bfe181d969a8cb5579798fe03Alina Friedrichsen#include <linux/socket.h>
34469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg#include <linux/ioctl.h>
35469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg#include <linux/file.h>
36469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg#include <linux/init.h>
37469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg#include <linux/wait.h>
38469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg#include <net/sock.h>
39469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
40469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg#include <linux/input.h>
41469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
42469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg#include <net/bluetooth/bluetooth.h>
43469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg#include <net/bluetooth/hci_core.h>
44469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg#include <net/bluetooth/l2cap.h>
45469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
46469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg#include "hidp.h"
47469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
48469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg#ifndef CONFIG_BT_HIDP_DEBUG
49469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg#undef  BT_DBG
50469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg#define BT_DBG(D...)
51469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg#endif
52469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
53469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg#define VERSION "1.1"
54469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
55469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Bergstatic DECLARE_RWSEM(hidp_session_sem);
56469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Bergstatic LIST_HEAD(hidp_session_list);
57469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
58469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Bergstatic unsigned char hidp_keycode[256] = {
59469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	  0,  0,  0,  0, 30, 48, 46, 32, 18, 33, 34, 35, 23, 36, 37, 38,
60fffd0934b9390f34bec45762192b7edd3b12b4b5Johannes Berg	 50, 49, 24, 25, 16, 19, 31, 20, 22, 47, 17, 45, 21, 44,  2,  3,
61469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	  4,  5,  6,  7,  8,  9, 10, 11, 28,  1, 14, 15, 57, 12, 13, 26,
62469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	 27, 43, 43, 39, 40, 41, 51, 52, 53, 58, 59, 60, 61, 62, 63, 64,
63af8cdcd828ad751fae8e6cbfe94eef9f2f23b14bJohannes Berg	 65, 66, 67, 68, 87, 88, 99, 70,119,110,102,104,111,107,109,106,
64af8cdcd828ad751fae8e6cbfe94eef9f2f23b14bJohannes Berg	105,108,103, 69, 98, 55, 74, 78, 96, 79, 80, 81, 75, 76, 77, 71,
65af8cdcd828ad751fae8e6cbfe94eef9f2f23b14bJohannes Berg	 72, 73, 82, 83, 86,127,116,117,183,184,185,186,187,188,189,190,
66b59066a291ca7c12a1e5b58f3ada5ab6e32cb6bdJohannes Berg	191,192,193,194,134,138,130,132,128,129,131,137,133,135,136,113,
67af8cdcd828ad751fae8e6cbfe94eef9f2f23b14bJohannes Berg	115,114,  0,  0,  0,121,  0, 89, 93,124, 92, 94, 95,  0,  0,  0,
68469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	122,123, 90, 91, 85,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
69469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
70469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
71b59066a291ca7c12a1e5b58f3ada5ab6e32cb6bdJohannes Berg	  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
72469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
73469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	 29, 42, 56,125, 97, 54,100,126,164,166,165,163,161,115,114,113,
74469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	150,158,159,128,136,177,178,176,142,152,173,140
75469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg};
76f446d10f214091408b7300f15c9adf60569edf28Johannes Berg
7757c4d7b4c4986037be51476b8e3025d5ba18d8b8Johannes Bergstatic unsigned char hidp_mkeyspat[] = { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 };
78b59066a291ca7c12a1e5b58f3ada5ab6e32cb6bdJohannes Berg
792448798133d747ad339e57099e32a1d1e68aca1cJohannes Bergstatic struct hidp_session *__hidp_get_session(bdaddr_t *bdaddr)
802448798133d747ad339e57099e32a1d1e68aca1cJohannes Berg{
812448798133d747ad339e57099e32a1d1e68aca1cJohannes Berg	struct hidp_session *session;
82469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	struct list_head *p;
83af8cdcd828ad751fae8e6cbfe94eef9f2f23b14bJohannes Berg
84af8cdcd828ad751fae8e6cbfe94eef9f2f23b14bJohannes Berg	BT_DBG("");
85af8cdcd828ad751fae8e6cbfe94eef9f2f23b14bJohannes Berg
86af8cdcd828ad751fae8e6cbfe94eef9f2f23b14bJohannes Berg	list_for_each(p, &hidp_session_list) {
87af8cdcd828ad751fae8e6cbfe94eef9f2f23b14bJohannes Berg		session = list_entry(p, struct hidp_session, list);
88af8cdcd828ad751fae8e6cbfe94eef9f2f23b14bJohannes Berg		if (!bacmp(bdaddr, &session->bdaddr))
89af8cdcd828ad751fae8e6cbfe94eef9f2f23b14bJohannes Berg			return session;
90469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	}
91af8cdcd828ad751fae8e6cbfe94eef9f2f23b14bJohannes Berg	return NULL;
92af8cdcd828ad751fae8e6cbfe94eef9f2f23b14bJohannes Berg}
93469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
94469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Bergstatic void __hidp_link_session(struct hidp_session *session)
95469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg{
96af8cdcd828ad751fae8e6cbfe94eef9f2f23b14bJohannes Berg	__module_get(THIS_MODULE);
97469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	list_add(&session->list, &hidp_session_list);
98af8cdcd828ad751fae8e6cbfe94eef9f2f23b14bJohannes Berg}
99af8cdcd828ad751fae8e6cbfe94eef9f2f23b14bJohannes Berg
100af8cdcd828ad751fae8e6cbfe94eef9f2f23b14bJohannes Bergstatic void __hidp_unlink_session(struct hidp_session *session)
10157c4d7b4c4986037be51476b8e3025d5ba18d8b8Johannes Berg{
102af8cdcd828ad751fae8e6cbfe94eef9f2f23b14bJohannes Berg	list_del(&session->list);
103469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	module_put(THIS_MODULE);
104b59066a291ca7c12a1e5b58f3ada5ab6e32cb6bdJohannes Berg}
105b59066a291ca7c12a1e5b58f3ada5ab6e32cb6bdJohannes Berg
106b59066a291ca7c12a1e5b58f3ada5ab6e32cb6bdJohannes Bergstatic void __hidp_copy_session(struct hidp_session *session, struct hidp_conninfo *ci)
107b59066a291ca7c12a1e5b58f3ada5ab6e32cb6bdJohannes Berg{
108b59066a291ca7c12a1e5b58f3ada5ab6e32cb6bdJohannes Berg	bacpy(&ci->bdaddr, &session->bdaddr);
109b59066a291ca7c12a1e5b58f3ada5ab6e32cb6bdJohannes Berg
110b59066a291ca7c12a1e5b58f3ada5ab6e32cb6bdJohannes Berg	ci->flags = session->flags;
111b59066a291ca7c12a1e5b58f3ada5ab6e32cb6bdJohannes Berg	ci->state = session->state;
112b59066a291ca7c12a1e5b58f3ada5ab6e32cb6bdJohannes Berg
113b59066a291ca7c12a1e5b58f3ada5ab6e32cb6bdJohannes Berg	ci->vendor  = 0x0000;
114469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	ci->product = 0x0000;
115af8cdcd828ad751fae8e6cbfe94eef9f2f23b14bJohannes Berg	ci->version = 0x0000;
116469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	memset(ci->name, 0, 128);
117469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
118469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	if (session->input) {
119469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg		ci->vendor  = session->input->id.vendor;
12047846c9b0c10808d9337d2e7d09361f3e0a0a71aJohannes Berg		ci->product = session->input->id.product;
121469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg		ci->version = session->input->id.version;
12257c4d7b4c4986037be51476b8e3025d5ba18d8b8Johannes Berg		if (session->input->name)
123707c1b4e68a2811ff2c9e75750a98a3310789a2dSujith			strncpy(ci->name, session->input->name, 128);
124469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg		else
125469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg			strncpy(ci->name, "HID Boot Device", 128);
126469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	}
127469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg}
128469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
129469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Bergstatic int hidp_input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
130469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg{
131b59066a291ca7c12a1e5b58f3ada5ab6e32cb6bdJohannes Berg	struct hidp_session *session = dev->private;
132469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	struct sk_buff *skb;
133469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	unsigned char newleds;
134469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
135469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	BT_DBG("input %p type %d code %d value %d", dev, type, code, value);
136469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
137469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	if (type != EV_LED)
138469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg		return -1;
139469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
140469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	newleds = (!!test_bit(LED_KANA,    dev->led) << 3) |
141469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg		  (!!test_bit(LED_COMPOSE, dev->led) << 3) |
142469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg		  (!!test_bit(LED_SCROLLL, dev->led) << 2) |
143af8cdcd828ad751fae8e6cbfe94eef9f2f23b14bJohannes Berg		  (!!test_bit(LED_CAPSL,   dev->led) << 1) |
144469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg		  (!!test_bit(LED_NUML,    dev->led));
145469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
146469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	if (session->leds == newleds)
147469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg		return 0;
148469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
149469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	session->leds = newleds;
150469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
151469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	if (!(skb = alloc_skb(3, GFP_ATOMIC))) {
152469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg		BT_ERR("Can't allocate memory for new frame");
153b59066a291ca7c12a1e5b58f3ada5ab6e32cb6bdJohannes Berg		return -ENOMEM;
154b59066a291ca7c12a1e5b58f3ada5ab6e32cb6bdJohannes Berg	}
155469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
156469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	*skb_put(skb, 1) = HIDP_TRANS_DATA | HIDP_DATA_RTYPE_OUPUT;
157469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	*skb_put(skb, 1) = 0x01;
158469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	*skb_put(skb, 1) = newleds;
159469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
160469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	skb_queue_tail(&session->intr_transmit, skb);
161af8cdcd828ad751fae8e6cbfe94eef9f2f23b14bJohannes Berg
162af8cdcd828ad751fae8e6cbfe94eef9f2f23b14bJohannes Berg	hidp_schedule(session);
163af8cdcd828ad751fae8e6cbfe94eef9f2f23b14bJohannes Berg
164af8cdcd828ad751fae8e6cbfe94eef9f2f23b14bJohannes Berg	return 0;
165af8cdcd828ad751fae8e6cbfe94eef9f2f23b14bJohannes Berg}
166469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
1672d0ddec5b2b859f06116f631fc0ffe94fbceb556Johannes Bergstatic void hidp_input_report(struct hidp_session *session, struct sk_buff *skb)
1682d0ddec5b2b859f06116f631fc0ffe94fbceb556Johannes Berg{
1692d0ddec5b2b859f06116f631fc0ffe94fbceb556Johannes Berg	struct input_dev *dev = session->input;
1702d0ddec5b2b859f06116f631fc0ffe94fbceb556Johannes Berg	unsigned char *keys = session->keys;
1712d0ddec5b2b859f06116f631fc0ffe94fbceb556Johannes Berg	unsigned char *udata = skb->data + 1;
1722d0ddec5b2b859f06116f631fc0ffe94fbceb556Johannes Berg	signed char *sdata = skb->data + 1;
1732d0ddec5b2b859f06116f631fc0ffe94fbceb556Johannes Berg	int i, size = skb->len - 1;
174469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
175b59066a291ca7c12a1e5b58f3ada5ab6e32cb6bdJohannes Berg	switch (skb->data[0]) {
176469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	case 0x01:	/* Keyboard report */
177469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg		for (i = 0; i < 8; i++)
178af8cdcd828ad751fae8e6cbfe94eef9f2f23b14bJohannes Berg			input_report_key(dev, hidp_keycode[i + 224], (udata[0] >> i) & 1);
179af8cdcd828ad751fae8e6cbfe94eef9f2f23b14bJohannes Berg
180469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg		/* If all the key codes have been set to 0x01, it means
181f446d10f214091408b7300f15c9adf60569edf28Johannes Berg		 * too many keys were pressed at the same time. */
182f446d10f214091408b7300f15c9adf60569edf28Johannes Berg		if (!memcmp(udata + 2, hidp_mkeyspat, 6))
183f446d10f214091408b7300f15c9adf60569edf28Johannes Berg			break;
184af8cdcd828ad751fae8e6cbfe94eef9f2f23b14bJohannes Berg
185469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg		for (i = 2; i < 8; i++) {
186469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg			if (keys[i] > 3 && memscan(udata + 2, keys[i], 6) == udata + 8) {
187af8cdcd828ad751fae8e6cbfe94eef9f2f23b14bJohannes Berg				if (hidp_keycode[keys[i]])
188af8cdcd828ad751fae8e6cbfe94eef9f2f23b14bJohannes Berg					input_report_key(dev, hidp_keycode[keys[i]], 0);
189469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg				else
1900c1ad2cac1cb54db38fd4cc1822965071ee83f6eJohannes Berg					BT_ERR("Unknown key (scancode %#x) released.", keys[i]);
1910c1ad2cac1cb54db38fd4cc1822965071ee83f6eJohannes Berg			}
192b59066a291ca7c12a1e5b58f3ada5ab6e32cb6bdJohannes Berg
193b59066a291ca7c12a1e5b58f3ada5ab6e32cb6bdJohannes Berg			if (udata[i] > 3 && memscan(keys + 2, udata[i], 6) == keys + 8) {
194b59066a291ca7c12a1e5b58f3ada5ab6e32cb6bdJohannes Berg				if (hidp_keycode[udata[i]])
1950c1ad2cac1cb54db38fd4cc1822965071ee83f6eJohannes Berg					input_report_key(dev, hidp_keycode[udata[i]], 1);
19657c4d7b4c4986037be51476b8e3025d5ba18d8b8Johannes Berg				else
19757c4d7b4c4986037be51476b8e3025d5ba18d8b8Johannes Berg					BT_ERR("Unknown key (scancode %#x) pressed.", udata[i]);
19857c4d7b4c4986037be51476b8e3025d5ba18d8b8Johannes Berg			}
19957c4d7b4c4986037be51476b8e3025d5ba18d8b8Johannes Berg		}
2000c1ad2cac1cb54db38fd4cc1822965071ee83f6eJohannes Berg
201b59066a291ca7c12a1e5b58f3ada5ab6e32cb6bdJohannes Berg		memcpy(keys, udata, 8);
202b59066a291ca7c12a1e5b58f3ada5ab6e32cb6bdJohannes Berg		break;
203b59066a291ca7c12a1e5b58f3ada5ab6e32cb6bdJohannes Berg
204b59066a291ca7c12a1e5b58f3ada5ab6e32cb6bdJohannes Berg	case 0x02:	/* Mouse report */
205b59066a291ca7c12a1e5b58f3ada5ab6e32cb6bdJohannes Berg		input_report_key(dev, BTN_LEFT,   sdata[0] & 0x01);
206b59066a291ca7c12a1e5b58f3ada5ab6e32cb6bdJohannes Berg		input_report_key(dev, BTN_RIGHT,  sdata[0] & 0x02);
207b59066a291ca7c12a1e5b58f3ada5ab6e32cb6bdJohannes Berg		input_report_key(dev, BTN_MIDDLE, sdata[0] & 0x04);
208b59066a291ca7c12a1e5b58f3ada5ab6e32cb6bdJohannes Berg		input_report_key(dev, BTN_SIDE,   sdata[0] & 0x08);
209b59066a291ca7c12a1e5b58f3ada5ab6e32cb6bdJohannes Berg		input_report_key(dev, BTN_EXTRA,  sdata[0] & 0x10);
210b59066a291ca7c12a1e5b58f3ada5ab6e32cb6bdJohannes Berg
211b59066a291ca7c12a1e5b58f3ada5ab6e32cb6bdJohannes Berg		input_report_rel(dev, REL_X, sdata[1]);
212b59066a291ca7c12a1e5b58f3ada5ab6e32cb6bdJohannes Berg		input_report_rel(dev, REL_Y, sdata[2]);
213b59066a291ca7c12a1e5b58f3ada5ab6e32cb6bdJohannes Berg
214b59066a291ca7c12a1e5b58f3ada5ab6e32cb6bdJohannes Berg		if (size > 3)
215b59066a291ca7c12a1e5b58f3ada5ab6e32cb6bdJohannes Berg			input_report_rel(dev, REL_WHEEL, sdata[3]);
216b59066a291ca7c12a1e5b58f3ada5ab6e32cb6bdJohannes Berg		break;
2170c1ad2cac1cb54db38fd4cc1822965071ee83f6eJohannes Berg	}
21857c4d7b4c4986037be51476b8e3025d5ba18d8b8Johannes Berg
2190c1ad2cac1cb54db38fd4cc1822965071ee83f6eJohannes Berg	input_sync(dev);
220b59066a291ca7c12a1e5b58f3ada5ab6e32cb6bdJohannes Berg}
2210c1ad2cac1cb54db38fd4cc1822965071ee83f6eJohannes Berg
2220c1ad2cac1cb54db38fd4cc1822965071ee83f6eJohannes Bergstatic void hidp_idle_timeout(unsigned long arg)
223469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg{
224469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	struct hidp_session *session = (struct hidp_session *) arg;
225469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
226469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	atomic_inc(&session->terminate);
227469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	hidp_schedule(session);
228469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg}
229469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
230469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Bergstatic inline void hidp_set_timer(struct hidp_session *session)
231469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg{
232469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	if (session->idle_to > 0)
233469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg		mod_timer(&session->timer, jiffies + HZ * session->idle_to);
2340c1ad2cac1cb54db38fd4cc1822965071ee83f6eJohannes Berg}
235469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
236469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Bergstatic inline void hidp_del_timer(struct hidp_session *session)
237469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg{
238469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	if (session->idle_to > 0)
239469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg		del_timer(&session->timer);
240469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg}
241469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
242469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Bergstatic int __hidp_send_ctrl_message(struct hidp_session *session,
243469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg			unsigned char hdr, unsigned char *data, int size)
244469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg{
245469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	struct sk_buff *skb;
246469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
247469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	BT_DBG("session %p data %p size %d", session, data, size);
248469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
249469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	if (!(skb = alloc_skb(size + 1, GFP_ATOMIC))) {
250469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg		BT_ERR("Can't allocate memory for new frame");
251469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg		return -ENOMEM;
252469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	}
253469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
254469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	*skb_put(skb, 1) = hdr;
255469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	if (data && size > 0)
256469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg		memcpy(skb_put(skb, size), data, size);
257469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
258abe60632f311d515b082b450504ee24006023951Johannes Berg	skb_queue_tail(&session->ctrl_transmit, skb);
259469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
260469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	return 0;
261469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg}
262469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
263469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Bergstatic int inline hidp_send_ctrl_message(struct hidp_session *session,
264469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg			unsigned char hdr, unsigned char *data, int size)
265469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg{
266469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	int err;
267469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
268469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	err = __hidp_send_ctrl_message(session, hdr, data, size);
269469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
270469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	hidp_schedule(session);
271469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
27247846c9b0c10808d9337d2e7d09361f3e0a0a71aJohannes Berg	return err;
273469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg}
274469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
275469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Bergstatic inline void hidp_process_handshake(struct hidp_session *session, unsigned char param)
276469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg{
277469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	BT_DBG("session %p param 0x%02x", session, param);
278469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
279469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	switch (param) {
280469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	case HIDP_HSHK_SUCCESSFUL:
281469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg		/* FIXME: Call into SET_ GET_ handlers here */
282469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg		break;
283469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
284469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	case HIDP_HSHK_NOT_READY:
285469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	case HIDP_HSHK_ERR_INVALID_REPORT_ID:
286469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	case HIDP_HSHK_ERR_UNSUPPORTED_REQUEST:
287469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	case HIDP_HSHK_ERR_INVALID_PARAMETER:
288469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg		/* FIXME: Call into SET_ GET_ handlers here */
2890c1ad2cac1cb54db38fd4cc1822965071ee83f6eJohannes Berg		break;
2900c1ad2cac1cb54db38fd4cc1822965071ee83f6eJohannes Berg
291469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	case HIDP_HSHK_ERR_UNKNOWN:
2920c1ad2cac1cb54db38fd4cc1822965071ee83f6eJohannes Berg		break;
293469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
294469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	case HIDP_HSHK_ERR_FATAL:
295469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg		/* Device requests a reboot, as this is the only way this error
296469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg 		 * can be recovered. */
297469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg		__hidp_send_ctrl_message(session,
298469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg			HIDP_TRANS_HID_CONTROL | HIDP_CTRL_SOFT_RESET, NULL, 0);
299469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg		break;
300469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
301af8cdcd828ad751fae8e6cbfe94eef9f2f23b14bJohannes Berg	default:
302469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg		__hidp_send_ctrl_message(session,
303469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg			HIDP_TRANS_HANDSHAKE | HIDP_HSHK_ERR_INVALID_PARAMETER, NULL, 0);
304469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg		break;
3050c1ad2cac1cb54db38fd4cc1822965071ee83f6eJohannes Berg	}
306469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg}
307469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
308469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Bergstatic inline void hidp_process_hid_control(struct hidp_session *session, unsigned char param)
3090c1ad2cac1cb54db38fd4cc1822965071ee83f6eJohannes Berg{
310469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	BT_DBG("session %p param 0x%02x", session, param);
311469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
312469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	switch (param) {
313469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	case HIDP_CTRL_NOP:
314469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg		break;
315469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
316469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	case HIDP_CTRL_VIRTUAL_CABLE_UNPLUG:
317469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg		/* Flush the transmit queues */
31834e8f08231388f9e16c6f1e2461f53afaf7f1e5eAlina Friedrichsen		skb_queue_purge(&session->ctrl_transmit);
3190c1ad2cac1cb54db38fd4cc1822965071ee83f6eJohannes Berg		skb_queue_purge(&session->intr_transmit);
32034e8f08231388f9e16c6f1e2461f53afaf7f1e5eAlina Friedrichsen
32134e8f08231388f9e16c6f1e2461f53afaf7f1e5eAlina Friedrichsen		/* Kill session thread */
322469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg		atomic_inc(&session->terminate);
323469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg		break;
324469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
325469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	case HIDP_CTRL_HARD_RESET:
326469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	case HIDP_CTRL_SOFT_RESET:
327469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	case HIDP_CTRL_SUSPEND:
328469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	case HIDP_CTRL_EXIT_SUSPEND:
329469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg		/* FIXME: We have to parse these and return no error */
330469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg		break;
331469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
332469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	default:
333469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg		__hidp_send_ctrl_message(session,
334469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg			HIDP_TRANS_HANDSHAKE | HIDP_HSHK_ERR_INVALID_PARAMETER, NULL, 0);
335469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg		break;
336469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	}
337469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg}
338469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
339469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Bergstatic inline void hidp_process_data(struct hidp_session *session, struct sk_buff *skb, unsigned char param)
340469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg{
341469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	BT_DBG("session %p skb %p len %d param 0x%02x", session, skb, skb->len, param);
342469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
343469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	switch (param) {
344469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	case HIDP_DATA_RTYPE_INPUT:
345469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg		hidp_set_timer(session);
3462448798133d747ad339e57099e32a1d1e68aca1cJohannes Berg
3472448798133d747ad339e57099e32a1d1e68aca1cJohannes Berg		if (session->input)
3482448798133d747ad339e57099e32a1d1e68aca1cJohannes Berg			hidp_input_report(session, skb);
3492448798133d747ad339e57099e32a1d1e68aca1cJohannes Berg		break;
3502448798133d747ad339e57099e32a1d1e68aca1cJohannes Berg
3512448798133d747ad339e57099e32a1d1e68aca1cJohannes Berg	case HIDP_DATA_RTYPE_OTHER:
3522448798133d747ad339e57099e32a1d1e68aca1cJohannes Berg	case HIDP_DATA_RTYPE_OUPUT:
353469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	case HIDP_DATA_RTYPE_FEATURE:
354469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg		break;
355469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
356469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	default:
357469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg		__hidp_send_ctrl_message(session,
358469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg			HIDP_TRANS_HANDSHAKE | HIDP_HSHK_ERR_INVALID_PARAMETER, NULL, 0);
359469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	}
360469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg}
361469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
362469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Bergstatic inline void hidp_recv_ctrl_frame(struct hidp_session *session, struct sk_buff *skb)
363469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg{
3644a332a385a86e31bfe181d969a8cb5579798fe03Alina Friedrichsen	unsigned char hdr, type, param;
3654a332a385a86e31bfe181d969a8cb5579798fe03Alina Friedrichsen
3664a332a385a86e31bfe181d969a8cb5579798fe03Alina Friedrichsen	BT_DBG("session %p skb %p len %d", session, skb, skb->len);
3674a332a385a86e31bfe181d969a8cb5579798fe03Alina Friedrichsen
368469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	hdr = skb->data[0];
369469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	skb_pull(skb, 1);
370469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
371469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	type = hdr & HIDP_HEADER_TRANS_MASK;
37247846c9b0c10808d9337d2e7d09361f3e0a0a71aJohannes Berg	param = hdr & HIDP_HEADER_PARAM_MASK;
373469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
374469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	switch (type) {
375469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	case HIDP_TRANS_HANDSHAKE:
376469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg		hidp_process_handshake(session, param);
377469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg		break;
378469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
379469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	case HIDP_TRANS_HID_CONTROL:
380469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg		hidp_process_hid_control(session, param);
381469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg		break;
382469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
383469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	case HIDP_TRANS_DATA:
384469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg		hidp_process_data(session, skb, param);
385469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg		break;
386469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
387469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	default:
388469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg		__hidp_send_ctrl_message(session,
389469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg			HIDP_TRANS_HANDSHAKE | HIDP_HSHK_ERR_UNSUPPORTED_REQUEST, NULL, 0);
3902e10d330f8d5f039fa1e00baf59435ab0f11c722Felix Fietkau		break;
391469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	}
392469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
393469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	kfree_skb(skb);
394469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg}
395af8cdcd828ad751fae8e6cbfe94eef9f2f23b14bJohannes Berg
396af8cdcd828ad751fae8e6cbfe94eef9f2f23b14bJohannes Bergstatic inline void hidp_recv_intr_frame(struct hidp_session *session, struct sk_buff *skb)
397af8cdcd828ad751fae8e6cbfe94eef9f2f23b14bJohannes Berg{
398af8cdcd828ad751fae8e6cbfe94eef9f2f23b14bJohannes Berg	unsigned char hdr;
399469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
400af8cdcd828ad751fae8e6cbfe94eef9f2f23b14bJohannes Berg	BT_DBG("session %p skb %p len %d", session, skb, skb->len);
401af8cdcd828ad751fae8e6cbfe94eef9f2f23b14bJohannes Berg
40247846c9b0c10808d9337d2e7d09361f3e0a0a71aJohannes Berg	hdr = skb->data[0];
403469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	skb_pull(skb, 1);
404469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
405469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	if (hdr == (HIDP_TRANS_DATA | HIDP_DATA_RTYPE_INPUT)) {
4062e10d330f8d5f039fa1e00baf59435ab0f11c722Felix Fietkau		hidp_set_timer(session);
4072e10d330f8d5f039fa1e00baf59435ab0f11c722Felix Fietkau		if (session->input)
4082e10d330f8d5f039fa1e00baf59435ab0f11c722Felix Fietkau			hidp_input_report(session, skb);
409469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	} else {
410469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg		BT_DBG("Unsupported protocol header 0x%02x", hdr);
411469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	}
412469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
413469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	kfree_skb(skb);
41447846c9b0c10808d9337d2e7d09361f3e0a0a71aJohannes Berg}
415469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
416469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Bergstatic int hidp_send_frame(struct socket *sock, unsigned char *data, int len)
417469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg{
418469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	struct kvec iv = { data, len };
419469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	struct msghdr msg;
420469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
421469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	BT_DBG("sock %p data %p len %d", sock, data, len);
422469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
423469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	if (!len)
424469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg		return 0;
425469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
426469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	memset(&msg, 0, sizeof(msg));
427469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
428469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	return kernel_sendmsg(sock, &msg, &iv, 1, len);
429469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg}
430469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
431469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Bergstatic void hidp_process_transmit(struct hidp_session *session)
432469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg{
433469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	struct sk_buff *skb;
434469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
435469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	BT_DBG("session %p", session);
436469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
437469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	while ((skb = skb_dequeue(&session->ctrl_transmit))) {
438469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg		if (hidp_send_frame(session->ctrl_sock, skb->data, skb->len) < 0) {
439469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg			skb_queue_head(&session->ctrl_transmit, skb);
440469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg			break;
441469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg		}
442469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
443469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg		hidp_set_timer(session);
444469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg		kfree_skb(skb);
445469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	}
446469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
447469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	while ((skb = skb_dequeue(&session->intr_transmit))) {
448469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg		if (hidp_send_frame(session->intr_sock, skb->data, skb->len) < 0) {
449469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg			skb_queue_head(&session->intr_transmit, skb);
450469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg			break;
451469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg		}
452469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
453469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg		hidp_set_timer(session);
454469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg		kfree_skb(skb);
455469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	}
456469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg}
457ce9058aedd75f14785400dcc49a2bc352ca38871Benoit Papillault
458ce9058aedd75f14785400dcc49a2bc352ca38871Benoit Papillaultstatic int hidp_session(void *arg)
459ce9058aedd75f14785400dcc49a2bc352ca38871Benoit Papillault{
460469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	struct hidp_session *session = arg;
461469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	struct sock *ctrl_sk = session->ctrl_sock->sk;
462469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	struct sock *intr_sk = session->intr_sock->sk;
463469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	struct sk_buff *skb;
464469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	int vendor = 0x0000, product = 0x0000;
465af8cdcd828ad751fae8e6cbfe94eef9f2f23b14bJohannes Berg	wait_queue_t ctrl_wait, intr_wait;
466af8cdcd828ad751fae8e6cbfe94eef9f2f23b14bJohannes Berg
467469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	BT_DBG("session %p", session);
468469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
469af8cdcd828ad751fae8e6cbfe94eef9f2f23b14bJohannes Berg	if (session->input) {
470450aae3d7b60a970f266349a837dfb30a539198bSujith		vendor  = session->input->id.vendor;
471450aae3d7b60a970f266349a837dfb30a539198bSujith		product = session->input->id.product;
472450aae3d7b60a970f266349a837dfb30a539198bSujith	}
473450aae3d7b60a970f266349a837dfb30a539198bSujith
474469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	daemonize("khidpd_%04x%04x", vendor, product);
475469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	set_user_nice(current, -15);
476469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	current->flags |= PF_NOFREEZE;
477af8cdcd828ad751fae8e6cbfe94eef9f2f23b14bJohannes Berg
478469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	init_waitqueue_entry(&ctrl_wait, current);
479469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	init_waitqueue_entry(&intr_wait, current);
480469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	add_wait_queue(ctrl_sk->sk_sleep, &ctrl_wait);
48147846c9b0c10808d9337d2e7d09361f3e0a0a71aJohannes Berg	add_wait_queue(intr_sk->sk_sleep, &intr_wait);
482469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	while (!atomic_read(&session->terminate)) {
483f3b85252f081581a8f257545ed748062dce7798bJohannes Berg		set_current_state(TASK_INTERRUPTIBLE);
484469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
485469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg		if (ctrl_sk->sk_state != BT_CONNECTED || intr_sk->sk_state != BT_CONNECTED)
486af8cdcd828ad751fae8e6cbfe94eef9f2f23b14bJohannes Berg			break;
487469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
488469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg		while ((skb = skb_dequeue(&ctrl_sk->sk_receive_queue))) {
489469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg			skb_orphan(skb);
490469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg			hidp_recv_ctrl_frame(session, skb);
491469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg		}
492469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
493469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg		while ((skb = skb_dequeue(&intr_sk->sk_receive_queue))) {
494469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg			skb_orphan(skb);
495af8cdcd828ad751fae8e6cbfe94eef9f2f23b14bJohannes Berg			hidp_recv_intr_frame(session, skb);
496469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg		}
497469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
498469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg		hidp_process_transmit(session);
499469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
500469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg		schedule();
501469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	}
502469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	set_current_state(TASK_RUNNING);
50347846c9b0c10808d9337d2e7d09361f3e0a0a71aJohannes Berg	remove_wait_queue(intr_sk->sk_sleep, &intr_wait);
504469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	remove_wait_queue(ctrl_sk->sk_sleep, &ctrl_wait);
505469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
506469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	down_write(&hidp_session_sem);
507469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
508469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	hidp_del_timer(session);
50947846c9b0c10808d9337d2e7d09361f3e0a0a71aJohannes Berg
510469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	fput(session->intr_sock->file);
511af8cdcd828ad751fae8e6cbfe94eef9f2f23b14bJohannes Berg
512469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	wait_event_timeout(*(ctrl_sk->sk_sleep),
513469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg		(ctrl_sk->sk_state == BT_CLOSED), msecs_to_jiffies(500));
514469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
515fffd0934b9390f34bec45762192b7edd3b12b4b5Johannes Berg	fput(session->ctrl_sock->file);
516469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
517469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	__hidp_unlink_session(session);
518469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
519469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	if (session->input) {
52057c4d7b4c4986037be51476b8e3025d5ba18d8b8Johannes Berg		input_unregister_device(session->input);
521b59066a291ca7c12a1e5b58f3ada5ab6e32cb6bdJohannes Berg		session->input = NULL;
522b59066a291ca7c12a1e5b58f3ada5ab6e32cb6bdJohannes Berg	}
523469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
524469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	up_write(&hidp_session_sem);
525ce9058aedd75f14785400dcc49a2bc352ca38871Benoit Papillault
526ce9058aedd75f14785400dcc49a2bc352ca38871Benoit Papillault	kfree(session);
527ce9058aedd75f14785400dcc49a2bc352ca38871Benoit Papillault	return 0;
528ce9058aedd75f14785400dcc49a2bc352ca38871Benoit Papillault}
529af8cdcd828ad751fae8e6cbfe94eef9f2f23b14bJohannes Berg
530469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Bergstatic struct device *hidp_get_device(struct hidp_session *session)
531469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg{
532469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	bdaddr_t *src = &bt_sk(session->ctrl_sock->sk)->src;
5330c1ad2cac1cb54db38fd4cc1822965071ee83f6eJohannes Berg	bdaddr_t *dst = &bt_sk(session->ctrl_sock->sk)->dst;
534af8cdcd828ad751fae8e6cbfe94eef9f2f23b14bJohannes Berg	struct hci_dev *hdev;
535469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	struct hci_conn *conn;
536469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
537e0d61887c2ee19bb63f6a8c0e2c149184e879501Johannes Berg	hdev = hci_get_route(dst, src);
538469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	if (!hdev)
539469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg		return NULL;
540469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
541469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, dst);
54247846c9b0c10808d9337d2e7d09361f3e0a0a71aJohannes Berg
543469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	hci_dev_put(hdev);
544469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
545469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	return conn ? &conn->dev : NULL;
546af8cdcd828ad751fae8e6cbfe94eef9f2f23b14bJohannes Berg}
547469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
548e0d61887c2ee19bb63f6a8c0e2c149184e879501Johannes Bergstatic inline void hidp_setup_input(struct hidp_session *session, struct hidp_connadd_req *req)
549fffd0934b9390f34bec45762192b7edd3b12b4b5Johannes Berg{
550e0d61887c2ee19bb63f6a8c0e2c149184e879501Johannes Berg	struct input_dev *input = session->input;
551af8cdcd828ad751fae8e6cbfe94eef9f2f23b14bJohannes Berg	int i;
552af8cdcd828ad751fae8e6cbfe94eef9f2f23b14bJohannes Berg
553af8cdcd828ad751fae8e6cbfe94eef9f2f23b14bJohannes Berg	input->private = session;
554af8cdcd828ad751fae8e6cbfe94eef9f2f23b14bJohannes Berg
555af8cdcd828ad751fae8e6cbfe94eef9f2f23b14bJohannes Berg	input->name = "Bluetooth HID Boot Protocol Device";
556469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
5570c1ad2cac1cb54db38fd4cc1822965071ee83f6eJohannes Berg	input->id.bustype = BUS_BLUETOOTH;
5580c1ad2cac1cb54db38fd4cc1822965071ee83f6eJohannes Berg	input->id.vendor  = req->vendor;
5590c1ad2cac1cb54db38fd4cc1822965071ee83f6eJohannes Berg	input->id.product = req->product;
5600c1ad2cac1cb54db38fd4cc1822965071ee83f6eJohannes Berg	input->id.version = req->version;
5610c1ad2cac1cb54db38fd4cc1822965071ee83f6eJohannes Berg
5620c1ad2cac1cb54db38fd4cc1822965071ee83f6eJohannes Berg	if (req->subclass & 0x40) {
5630c1ad2cac1cb54db38fd4cc1822965071ee83f6eJohannes Berg		set_bit(EV_KEY, input->evbit);
564469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg		set_bit(EV_LED, input->evbit);
5650c1ad2cac1cb54db38fd4cc1822965071ee83f6eJohannes Berg		set_bit(EV_REP, input->evbit);
566469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
567469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg		set_bit(LED_NUML,    input->ledbit);
5680c1ad2cac1cb54db38fd4cc1822965071ee83f6eJohannes Berg		set_bit(LED_CAPSL,   input->ledbit);
569469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg		set_bit(LED_SCROLLL, input->ledbit);
570469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg		set_bit(LED_COMPOSE, input->ledbit);
571469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg		set_bit(LED_KANA,    input->ledbit);
572469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
5730c1ad2cac1cb54db38fd4cc1822965071ee83f6eJohannes Berg		for (i = 0; i < sizeof(hidp_keycode); i++)
574469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg			set_bit(hidp_keycode[i], input->keybit);
575af8cdcd828ad751fae8e6cbfe94eef9f2f23b14bJohannes Berg		clear_bit(0, input->keybit);
576469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	}
577af8cdcd828ad751fae8e6cbfe94eef9f2f23b14bJohannes Berg
578d419b9f0fa69e79ccba3e5e79a58a52ae0c2ed6aReinette Chatre	if (req->subclass & 0x80) {
579469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg		input->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
580469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg		input->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE);
581469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg		input->relbit[0] = BIT(REL_X) | BIT(REL_Y);
582469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg		input->keybit[LONG(BTN_MOUSE)] |= BIT(BTN_SIDE) | BIT(BTN_EXTRA);
583469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg		input->relbit[0] |= BIT(REL_WHEEL);
584469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	}
585ce9058aedd75f14785400dcc49a2bc352ca38871Benoit Papillault
586469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	input->cdev.dev = hidp_get_device(session);
587469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
58847846c9b0c10808d9337d2e7d09361f3e0a0a71aJohannes Berg	input->event = hidp_input_event;
589469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
590f3b85252f081581a8f257545ed748062dce7798bJohannes Berg	input_register_device(input);
591f3b85252f081581a8f257545ed748062dce7798bJohannes Berg}
592ce9058aedd75f14785400dcc49a2bc352ca38871Benoit Papillault
593469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Bergint hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock, struct socket *intr_sock)
594469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg{
595469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	struct hidp_session *session, *s;
596469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	int err;
597af8cdcd828ad751fae8e6cbfe94eef9f2f23b14bJohannes Berg
598af8cdcd828ad751fae8e6cbfe94eef9f2f23b14bJohannes Berg	BT_DBG("");
599af8cdcd828ad751fae8e6cbfe94eef9f2f23b14bJohannes Berg
600af8cdcd828ad751fae8e6cbfe94eef9f2f23b14bJohannes Berg	if (bacmp(&bt_sk(ctrl_sock->sk)->src, &bt_sk(intr_sock->sk)->src) ||
601469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg			bacmp(&bt_sk(ctrl_sock->sk)->dst, &bt_sk(intr_sock->sk)->dst))
60247846c9b0c10808d9337d2e7d09361f3e0a0a71aJohannes Berg		return -ENOTUNIQ;
603469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
604469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	session = kzalloc(sizeof(struct hidp_session), GFP_KERNEL);
605469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	if (!session)
606469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg		return -ENOMEM;
607469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
608469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	session->input = input_allocate_device();
609469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	if (!session->input) {
610af8cdcd828ad751fae8e6cbfe94eef9f2f23b14bJohannes Berg		kfree(session);
611af8cdcd828ad751fae8e6cbfe94eef9f2f23b14bJohannes Berg		return -ENOMEM;
612469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	}
613469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
614469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	down_write(&hidp_session_sem);
615469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
616469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	s = __hidp_get_session(&bt_sk(ctrl_sock->sk)->dst);
617469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	if (s && s->state == BT_CONNECTED) {
618469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg		err = -EEXIST;
619469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg		goto failed;
620469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	}
621469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
622469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	bacpy(&session->bdaddr, &bt_sk(ctrl_sock->sk)->dst);
623469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
624469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	session->ctrl_mtu = min_t(uint, l2cap_pi(ctrl_sock->sk)->omtu, l2cap_pi(ctrl_sock->sk)->imtu);
625469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	session->intr_mtu = min_t(uint, l2cap_pi(intr_sock->sk)->omtu, l2cap_pi(intr_sock->sk)->imtu);
626469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
627af8cdcd828ad751fae8e6cbfe94eef9f2f23b14bJohannes Berg	BT_DBG("ctrl mtu %d intr mtu %d", session->ctrl_mtu, session->intr_mtu);
628469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
629469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	session->ctrl_sock = ctrl_sock;
6302448798133d747ad339e57099e32a1d1e68aca1cJohannes Berg	session->intr_sock = intr_sock;
631469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	session->state     = BT_CONNECTED;
632469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
633469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	init_timer(&session->timer);
634469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
63547846c9b0c10808d9337d2e7d09361f3e0a0a71aJohannes Berg	session->timer.function = hidp_idle_timeout;
636469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	session->timer.data     = (unsigned long) session;
637469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
638469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	skb_queue_head_init(&session->ctrl_transmit);
639469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	skb_queue_head_init(&session->intr_transmit);
640469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
641469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	session->flags   = req->flags & (1 << HIDP_BLUETOOTH_VENDOR_ID);
642469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	session->idle_to = req->idle_to;
643469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
644469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	if (session->input)
645469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg		hidp_setup_input(session, req);
646469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
647469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	__hidp_link_session(session);
648469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
649469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	hidp_set_timer(session);
650469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
651469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	err = kernel_thread(hidp_session, session, CLONE_KERNEL);
652469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	if (err < 0)
65347846c9b0c10808d9337d2e7d09361f3e0a0a71aJohannes Berg		goto unlink;
654469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
655469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	if (session->input) {
656469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg		hidp_send_ctrl_message(session,
657469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg			HIDP_TRANS_SET_PROTOCOL | HIDP_PROTO_BOOT, NULL, 0);
658469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg		session->flags |= (1 << HIDP_BOOT_PROTOCOL_MODE);
659af8cdcd828ad751fae8e6cbfe94eef9f2f23b14bJohannes Berg
660469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg		session->leds = 0xff;
661469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg		hidp_input_event(session->input, EV_LED, 0, 0);
662469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	}
663469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
664469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	up_write(&hidp_session_sem);
665af8cdcd828ad751fae8e6cbfe94eef9f2f23b14bJohannes Berg	return 0;
666469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
667469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Bergunlink:
668469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	hidp_del_timer(session);
669469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
670469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	__hidp_unlink_session(session);
671469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
672469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	if (session->input) {
67347846c9b0c10808d9337d2e7d09361f3e0a0a71aJohannes Berg		input_unregister_device(session->input);
674469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg		session->input = NULL; /* don't try to free it here */
67562ae67be31c2346b6d74653a148ddbd1b9a94424Johannes Berg	}
67662ae67be31c2346b6d74653a148ddbd1b9a94424Johannes Berg
677469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Bergfailed:
678469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	up_write(&hidp_session_sem);
679469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
680469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	kfree(session->input);
681469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	kfree(session);
682469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	return err;
683469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg}
684469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
685469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Bergint hidp_del_connection(struct hidp_conndel_req *req)
686469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg{
68747846c9b0c10808d9337d2e7d09361f3e0a0a71aJohannes Berg	struct hidp_session *session;
688469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	int err = 0;
689469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
690469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	BT_DBG("");
691469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
692469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	down_read(&hidp_session_sem);
693469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
694469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	session = __hidp_get_session(&req->bdaddr);
695469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	if (session) {
696469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg		if (req->flags & (1 << HIDP_VIRTUAL_CABLE_UNPLUG)) {
697469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg			hidp_send_ctrl_message(session,
698469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg				HIDP_TRANS_HID_CONTROL | HIDP_CTRL_VIRTUAL_CABLE_UNPLUG, NULL, 0);
699469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg		} else {
700469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg			/* Flush the transmit queues */
701469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg			skb_queue_purge(&session->ctrl_transmit);
702469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg			skb_queue_purge(&session->intr_transmit);
703469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
704469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg			/* Kill session thread */
705469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg			atomic_inc(&session->terminate);
706469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg			hidp_schedule(session);
707469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg		}
708469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	} else
709469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg		err = -ENOENT;
710469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
711469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	up_read(&hidp_session_sem);
712469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	return err;
713469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg}
714469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
715469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Bergint hidp_get_connlist(struct hidp_connlist_req *req)
716469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg{
717469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	struct list_head *p;
718469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	int err = 0, n = 0;
719469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
720469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	BT_DBG("");
721469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
722469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	down_read(&hidp_session_sem);
723469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
724469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	list_for_each(p, &hidp_session_list) {
725f1d58c2521eb160178b2151d6326d8dc5d7c8560Johannes Berg		struct hidp_session *session;
726469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg		struct hidp_conninfo ci;
727469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
728469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg		session = list_entry(p, struct hidp_session, list);
729469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
730469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg		__hidp_copy_session(session, &ci);
731469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
732469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg		if (copy_to_user(req->ci, &ci, sizeof(ci))) {
733469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg			err = -EFAULT;
734469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg			break;
735469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg		}
736469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
737469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg		if (++n >= req->cnum)
738469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg			break;
739469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
740469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg		req->ci++;
741469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	}
742469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	req->cnum = n;
743469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
744469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	up_read(&hidp_session_sem);
745469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	return err;
746469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg}
747469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
748469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Bergint hidp_get_conninfo(struct hidp_conninfo *ci)
749469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg{
750469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	struct hidp_session *session;
751469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	int err = 0;
752469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
753469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	down_read(&hidp_session_sem);
754469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
755469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	session = __hidp_get_session(&ci->bdaddr);
756469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	if (session)
7575bb644a0fd25a5e083ecbfaa92a211db99aa6ef7Johannes Berg		__hidp_copy_session(session, ci);
7585bb644a0fd25a5e083ecbfaa92a211db99aa6ef7Johannes Berg	else
7595bb644a0fd25a5e083ecbfaa92a211db99aa6ef7Johannes Berg		err = -ENOENT;
7609607e6b66a0d25ca63b70d54a4283fa13d8f7c9dJohannes Berg
761469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	up_read(&hidp_session_sem);
762469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	return err;
763fbe9c429f195111bbf7f1630efa19aee295fd8e7Helmut Schaa}
764469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
765469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Bergstatic int __init hidp_init(void)
766469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg{
767469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	l2cap_load();
768469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
769469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	BT_INFO("HIDP (Human Interface Emulation) ver %s", VERSION);
770469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
771469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	return hidp_init_sockets();
772469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg}
773469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
774469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Bergstatic void __exit hidp_exit(void)
775469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg{
776469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg	hidp_cleanup_sockets();
777469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg}
778469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
779469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Bergmodule_init(hidp_init);
780469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Bergmodule_exit(hidp_exit);
781469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg
782469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes BergMODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
783469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes BergMODULE_DESCRIPTION("Bluetooth HIDP ver " VERSION);
784469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes BergMODULE_VERSION(VERSION);
785469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes BergMODULE_LICENSE("GPL");
786469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes BergMODULE_ALIAS("bt-proto-6");
787469002983fc90c2ff0959e2b03335c0fe2e4d5a9Johannes Berg