git.openpandora.org
/
pandora-kernel.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
Bluetooth: Let HIDP grab the device reference for connections
[pandora-kernel.git]
/
net
/
bluetooth
/
hidp
/
core.c
diff --git
a/net/bluetooth/hidp/core.c
b/net/bluetooth/hidp/core.c
index
acdeab3
..
09bedeb
100644
(file)
--- a/
net/bluetooth/hidp/core.c
+++ b/
net/bluetooth/hidp/core.c
@@
-40,6
+40,7
@@
#include <linux/input.h>
#include <linux/hid.h>
#include <linux/input.h>
#include <linux/hid.h>
+#include <linux/hidraw.h>
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
@@
-47,11
+48,6
@@
#include "hidp.h"
#include "hidp.h"
-#ifndef CONFIG_BT_HIDP_DEBUG
-#undef BT_DBG
-#define BT_DBG(D...)
-#endif
-
#define VERSION "1.2"
static DECLARE_RWSEM(hidp_session_sem);
#define VERSION "1.2"
static DECLARE_RWSEM(hidp_session_sem);
@@
-97,10
+93,14
@@
static void __hidp_link_session(struct hidp_session *session)
{
__module_get(THIS_MODULE);
list_add(&session->list, &hidp_session_list);
{
__module_get(THIS_MODULE);
list_add(&session->list, &hidp_session_list);
+
+ hci_conn_hold_device(session->conn);
}
static void __hidp_unlink_session(struct hidp_session *session)
{
}
static void __hidp_unlink_session(struct hidp_session *session)
{
+ hci_conn_put_device(session->conn);
+
list_del(&session->list);
module_put(THIS_MODULE);
}
list_del(&session->list);
module_put(THIS_MODULE);
}
@@
-379,6
+379,7
@@
static void hidp_process_hid_control(struct hidp_session *session,
/* Kill session thread */
atomic_inc(&session->terminate);
/* Kill session thread */
atomic_inc(&session->terminate);
+ hidp_schedule(session);
}
}
}
}
@@
-578,7
+579,11
@@
static int hidp_session(void *arg)
if (session->hid) {
if (session->hid->claimed & HID_CLAIMED_INPUT)
hidinput_disconnect(session->hid);
if (session->hid) {
if (session->hid->claimed & HID_CLAIMED_INPUT)
hidinput_disconnect(session->hid);
+ if (session->hid->claimed & HID_CLAIMED_HIDRAW)
+ hidraw_disconnect(session->hid);
+
hid_destroy_device(session->hid);
hid_destroy_device(session->hid);
+ session->hid = NULL;
}
/* Wakeup user-space polling for socket errors */
}
/* Wakeup user-space polling for socket errors */
@@
-606,25
+611,27
@@
static struct device *hidp_get_device(struct hidp_session *session)
{
bdaddr_t *src = &bt_sk(session->ctrl_sock->sk)->src;
bdaddr_t *dst = &bt_sk(session->ctrl_sock->sk)->dst;
{
bdaddr_t *src = &bt_sk(session->ctrl_sock->sk)->src;
bdaddr_t *dst = &bt_sk(session->ctrl_sock->sk)->dst;
+ struct device *device = NULL;
struct hci_dev *hdev;
struct hci_dev *hdev;
- struct hci_conn *conn;
hdev = hci_get_route(dst, src);
if (!hdev)
return NULL;
hdev = hci_get_route(dst, src);
if (!hdev)
return NULL;
- conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, dst);
+ session->conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, dst);
+ if (session->conn)
+ device = &session->conn->dev;
hci_dev_put(hdev);
hci_dev_put(hdev);
- return
conn ? &conn->dev : NULL
;
+ return
device
;
}
static int hidp_setup_input(struct hidp_session *session,
struct hidp_connadd_req *req)
{
struct input_dev *input;
}
static int hidp_setup_input(struct hidp_session *session,
struct hidp_connadd_req *req)
{
struct input_dev *input;
- int i;
+ int
err,
i;
input = input_allocate_device();
if (!input)
input = input_allocate_device();
if (!input)
@@
-671,7
+678,13
@@
static int hidp_setup_input(struct hidp_session *session,
input->event = hidp_input_event;
input->event = hidp_input_event;
- return input_register_device(input);
+ err = input_register_device(input);
+ if (err < 0) {
+ hci_conn_put_device(session->conn);
+ return err;
+ }
+
+ return 0;
}
static int hidp_open(struct hid_device *hid)
}
static int hidp_open(struct hid_device *hid)
@@
-753,13
+766,11
@@
static int hidp_setup_hid(struct hidp_session *session,
{
struct hid_device *hid;
bdaddr_t src, dst;
{
struct hid_device *hid;
bdaddr_t src, dst;
- int
ret
;
+ int
err
;
hid = hid_allocate_device();
hid = hid_allocate_device();
- if (IS_ERR(hid)) {
- ret = PTR_ERR(session->hid);
- goto err;
- }
+ if (IS_ERR(hid))
+ return PTR_ERR(session->hid);
session->hid = hid;
session->req = req;
session->hid = hid;
session->req = req;
@@
-781,16
+792,17
@@
static int hidp_setup_hid(struct hidp_session *session,
hid->dev.parent = hidp_get_device(session);
hid->ll_driver = &hidp_hid_driver;
hid->dev.parent = hidp_get_device(session);
hid->ll_driver = &hidp_hid_driver;
-
ret
= hid_add_device(hid);
- if (
ret
)
- goto
err_hi
d;
+
err
= hid_add_device(hid);
+ if (
err < 0
)
+ goto
faile
d;
return 0;
return 0;
-err_hid:
+
+failed:
hid_destroy_device(hid);
session->hid = NULL;
hid_destroy_device(hid);
session->hid = NULL;
-err:
- return
ret
;
+
+ return
err
;
}
int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock, struct socket *intr_sock)
}
int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock, struct socket *intr_sock)
@@
-840,13
+852,13
@@
int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock,
if (req->rd_size > 0) {
err = hidp_setup_hid(session, req);
if (err && err != -ENODEV)
if (req->rd_size > 0) {
err = hidp_setup_hid(session, req);
if (err && err != -ENODEV)
- goto
err_skb
;
+ goto
purge
;
}
if (!session->hid) {
err = hidp_setup_input(session, req);
if (err < 0)
}
if (!session->hid) {
err = hidp_setup_input(session, req);
if (err < 0)
- goto
err_skb
;
+ goto
purge
;
}
__hidp_link_session(session);
}
__hidp_link_session(session);
@@
-874,13
+886,20
@@
unlink:
__hidp_unlink_session(session);
__hidp_unlink_session(session);
- if (session->input)
+ if (session->input)
{
input_unregister_device(session->input);
input_unregister_device(session->input);
- if (session->hid)
+ session->input = NULL;
+ }
+
+ if (session->hid) {
hid_destroy_device(session->hid);
hid_destroy_device(session->hid);
-err_skb:
+ session->hid = NULL;
+ }
+
+purge:
skb_queue_purge(&session->ctrl_transmit);
skb_queue_purge(&session->intr_transmit);
skb_queue_purge(&session->ctrl_transmit);
skb_queue_purge(&session->intr_transmit);
+
failed:
up_write(&hidp_session_sem);
failed:
up_write(&hidp_session_sem);