summaryrefslogtreecommitdiff
path: root/net
diff options
context:
space:
mode:
authorJiri Slaby <jirislaby@gmail.com>2008-05-16 13:49:15 +0400
committerJiri Kosina <jkosina@suse.cz>2008-10-15 01:50:48 +0400
commit85cdaf524b7ddab627e7d15405693f2511ef7505 (patch)
treea85fb7c801df07842301c27dc57cf2eb5092f6ed /net
parente8c84f9a5f06912c94c38961096c994da3890a2e (diff)
downloadlinux-85cdaf524b7ddab627e7d15405693f2511ef7505.tar.xz
HID: make a bus from hid code
Make a bus from hid core. This is the first step for converting all the quirks and separate almost-drivers into real drivers attached to this bus. It's implemented to change behaviour in very tiny manner, so that no driver needs to be changed this time. Also add generic drivers for both usb and bt into usbhid or hidp respectively which will bind all non-blacklisted device. Those blacklisted will be either grabbed by special drivers or by nobody if they are broken at the very rude base. Signed-off-by: Jiri Slaby <jslaby@suse.cz> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Diffstat (limited to 'net')
-rw-r--r--net/bluetooth/hidp/core.c64
1 files changed, 55 insertions, 9 deletions
diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c
index 96434d774c84..56a51f91591a 100644
--- a/net/bluetooth/hidp/core.c
+++ b/net/bluetooth/hidp/core.c
@@ -578,7 +578,7 @@ static int hidp_session(void *arg)
if (session->hid) {
if (session->hid->claimed & HID_CLAIMED_INPUT)
hidinput_disconnect(session->hid);
- hid_free_device(session->hid);
+ hid_destroy_device(session->hid);
}
/* Wakeup user-space polling for socket errors */
@@ -698,12 +698,13 @@ static void hidp_setup_quirks(struct hid_device *hid)
hid->quirks = hidp_blacklist[n].quirks;
}
-static void hidp_setup_hid(struct hidp_session *session,
+static int hidp_setup_hid(struct hidp_session *session,
struct hidp_connadd_req *req)
{
struct hid_device *hid = session->hid;
struct hid_report *report;
bdaddr_t src, dst;
+ int ret;
baswap(&src, &bt_sk(session->ctrl_sock->sk)->src);
baswap(&dst, &bt_sk(session->ctrl_sock->sk)->dst);
@@ -721,7 +722,7 @@ static void hidp_setup_hid(struct hidp_session *session,
strncpy(hid->phys, batostr(&src), 64);
strncpy(hid->uniq, batostr(&dst), 64);
- hid->dev = hidp_get_device(session);
+ hid->dev.parent = hidp_get_device(session);
hid->hid_open = hidp_open;
hid->hid_close = hidp_close;
@@ -738,6 +739,15 @@ static void hidp_setup_hid(struct hidp_session *session,
if (hidinput_connect(hid) == 0)
hid->claimed |= HID_CLAIMED_INPUT;
+
+ ret = hid_add_device(hid);
+ if (ret) {
+ if (hid->claimed & HID_CLAIMED_INPUT)
+ hidinput_disconnect(hid);
+ skb_queue_purge(&session->intr_transmit);
+ }
+
+ return ret;
}
int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock, struct socket *intr_sock)
@@ -771,11 +781,19 @@ int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock,
return -EFAULT;
}
- session->hid = hid_parse_report(buf, req->rd_size);
+ session->hid = hid_allocate_device();
+ if (IS_ERR(session->hid)) {
+ kfree(buf);
+ kfree(session);
+ return PTR_ERR(session->hid);
+ }
+
+ err = hid_parse_report(session->hid, buf, req->rd_size);
kfree(buf);
- if (!session->hid) {
+ if (err) {
+ hid_destroy_device(session->hid);
kfree(session);
return -EINVAL;
}
@@ -822,8 +840,11 @@ int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock,
goto failed;
}
- if (session->hid)
- hidp_setup_hid(session, req);
+ if (session->hid) {
+ err = hidp_setup_hid(session, req);
+ if (err)
+ goto failed;
+ }
__hidp_link_session(session);
@@ -859,7 +880,7 @@ failed:
up_write(&hidp_session_sem);
if (session->hid)
- hid_free_device(session->hid);
+ hid_destroy_device(session->hid);
input_free_device(session->input);
kfree(session);
@@ -950,18 +971,43 @@ int hidp_get_conninfo(struct hidp_conninfo *ci)
return err;
}
+static const struct hid_device_id hidp_table[] = {
+ { HID_BLUETOOTH_DEVICE(HID_ANY_ID, HID_ANY_ID) },
+ { }
+};
+
+static struct hid_driver hidp_driver = {
+ .name = "generic-bluetooth",
+ .id_table = hidp_table,
+};
+
static int __init hidp_init(void)
{
+ int ret;
+
l2cap_load();
BT_INFO("HIDP (Human Interface Emulation) ver %s", VERSION);
- return hidp_init_sockets();
+ ret = hid_register_driver(&hidp_driver);
+ if (ret)
+ goto err;
+
+ ret = hidp_init_sockets();
+ if (ret)
+ goto err_drv;
+
+ return 0;
+err_drv:
+ hid_unregister_driver(&hidp_driver);
+err:
+ return ret;
}
static void __exit hidp_exit(void)
{
hidp_cleanup_sockets();
+ hid_unregister_driver(&hidp_driver);
}
module_init(hidp_init);