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

Reply via email to