diff -Naurp linux-2.6.21-rc6-mm1.orig/net/bluetooth/hidp/core.c
linux-2.6.21-rc6-mm1.new/net/bluetooth/hidp/core.c
--- linux-2.6.21-rc6-mm1.orig/net/bluetooth/hidp/core.c 2007-04-10
09:16:51.000000000 +0800
+++ linux-2.6.21-rc6-mm1.new/net/bluetooth/hidp/core.c 2007-04-17
09:19:27.000000000 +0800
@@ -54,6 +54,7 @@
#define VERSION "1.2"
+static DECLARE_WAIT_QUEUE_HEAD(hidp_session_clean_barrier);
static DECLARE_RWSEM(hidp_session_sem);
static LIST_HEAD(hidp_session_list);
@@ -78,6 +79,15 @@ static unsigned char hidp_keycode[256] =
static unsigned char hidp_mkeyspat[] = { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 };
+static void hidp_update_busid(struct hid_device *dev)
+{
+ static atomic_t hidp_hiddev_idx = ATOMIC_INIT(-1);
+
+ snprintf(dev->device.bus_id, BUS_ID_SIZE, "B:%04x:%04x:%d",
+ dev->vendor, dev->product,
+ atomic_add_return(1, &hidp_hiddev_idx));
+}
+
static struct hidp_session *__hidp_get_session(bdaddr_t *bdaddr)
{
struct hidp_session *session;
@@ -176,7 +186,7 @@ static inline int hidp_queue_event(struc
static int hidp_hidinput_event(struct input_dev *dev, unsigned int type,
unsigned int code, int value)
{
struct hid_device *hid = dev->private;
- struct hidp_session *session = hid->driver_data;
+ struct hidp_session *session = hid->tl_data;
return hidp_queue_event(session, dev, type, code, value);
}
@@ -544,6 +554,11 @@ static int hidp_session(void *arg)
if (session->hid) {
vendor = session->hid->vendor;
product = session->hid->product;
+ session->hid->module = THIS_MODULE;
+ if (hid_register_device(session->hid)) {
+ hid_free_device(session->hid);
+ session->hid = NULL;
+ }
}
daemonize("khidpd_%04x%04x", vendor, product);
@@ -598,14 +613,17 @@ static int hidp_session(void *arg)
}
if (session->hid) {
- if (session->hid->claimed & HID_CLAIMED_INPUT)
- hidinput_disconnect(session->hid);
+ hid_unregister_device(session->hid);
hid_free_device(session->hid);
}
up_write(&hidp_session_sem);
kfree(session);
+
+ if (list_empty(&hidp_session_list))
+ wake_up(&hidp_session_clean_barrier);
+
return 0;
}
@@ -711,7 +729,7 @@ static inline void hidp_setup_hid(struct
baswap(&src, &bt_sk(session->ctrl_sock->sk)->src);
baswap(&dst, &bt_sk(session->ctrl_sock->sk)->dst);
- hid->driver_data = session;
+ hid->tl_data = session;
hid->country = req->country;
@@ -726,11 +744,6 @@ static inline void hidp_setup_hid(struct
hid->dev = hidp_get_device(session);
- hid->hid_open = hidp_open;
- hid->hid_close = hidp_close;
-
- hid->hidinput_input_event = hidp_hidinput_event;
-
hidp_setup_quirks(hid);
list_for_each_entry(report,
&hid->report_enum[HID_INPUT_REPORT].report_list, list)
@@ -738,11 +751,6 @@ static inline void hidp_setup_hid(struct
list_for_each_entry(report,
&hid->report_enum[HID_FEATURE_REPORT].report_list, list)
hidp_send_report(session, report);
-
- if (hidinput_connect(hid) == 0) {
- hid->claimed |= HID_CLAIMED_INPUT;
- hid_ff_init(hid);
- }
}
int hidp_add_connection(struct hidp_connadd_req *req, struct socket
*ctrl_sock, struct socket *intr_sock)
@@ -868,6 +876,10 @@ failed:
kfree(session->input);
kfree(session);
+
+ if (list_empty(&hidp_session_list))
+ wake_up(&hidp_session_clean_barrier);
+
return err;
}
@@ -951,8 +963,57 @@ int hidp_get_conninfo(struct hidp_connin
return err;
}
+static struct hid_driver hid_bt_driver = {
+ .name = "hidbt",
+ .version = "0.9.0",
+ .bus = BUS_BLUETOOTH,
+ .module = THIS_MODULE,
+ .match = NULL, /* default match any bluetooth hidp device. */
+ .probe = NULL, /* default is hidinput_connect() */
+ .remove = NULL, /* default is hidinput_disconnect() */
+};
+
+static struct hid_transport hid_bt_transport = {
+ .bus = BUS_BLUETOOTH,
+ .event = hidp_hidinput_event,
+ .open = hidp_open,
+ .close = hidp_close,
+ .update_busid = hidp_update_busid,
+ .module = THIS_MODULE,
+};
+
+static int is_hidp_session_list_empty(void)
+{
+ int ret;
+
+ down_read(&hidp_session_sem);
+ ret = list_empty(&hidp_session_list);
+ up_read(&hidp_session_sem);
+ return ret;
+}
+
+static void hidp_session_clean(void)
+{
+ struct hidp_session *session;
+
+ down_read(&hidp_session_sem);
+ list_for_each_entry(session, &hidp_session_list, list) {
+ atomic_inc(&session->terminate);
+ hidp_schedule(session);
+ }
+ up_read(&hidp_session_sem);
+}
+
+
static int __init hidp_init(void)
{
+ if (hid_register_transport(&hid_bt_transport))
+ return -ENODEV;
+ if (hid_register_driver(&hid_bt_driver)) {
+ hid_unregister_transport(&hid_bt_transport);
+ return -ENODEV;
+ }
+
l2cap_load();
BT_INFO("HIDP (Human Interface Emulation) ver %s", VERSION);
@@ -962,6 +1023,11 @@ static int __init hidp_init(void)
static void __exit hidp_exit(void)
{
+ hidp_session_clean();
+ wait_event(hidp_session_clean_barrier, is_hidp_session_list_empty());
+
+ hid_unregister_transport(&hid_bt_transport);
+ hid_unregister_driver(&hid_bt_driver);
hidp_cleanup_sockets();
}
-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
[email protected]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel