ANDROID: hid: uhid: implement refcount for open and close
authorDmitry Torokhov <dmitry.torokhov@gmail.com>
Tue, 30 May 2017 21:46:26 +0000 (14:46 -0700)
committerAmit Pundir <amit.pundir@linaro.org>
Wed, 21 Jun 2017 11:04:04 +0000 (16:34 +0530)
Fix concurrent open and close activity sending a UHID_CLOSE while
some consumers still have the device open.

Temporary solution for reference counts on device open and close
calls, absent a facility for this in the HID core likely to appear
in the future.

[toddpoynor@google.com: commit text]
Bug: 38448648
Signed-off-by: Todd Poynor <toddpoynor@google.com>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Change-Id: I57413e42ec961a960a8ddc4942228df22c730d80

drivers/hid/uhid.c

index 1a2032c2c1fb5674d33a1cdbfe3a1fe90255802f..690a9f0fa04293ff8b6ec617109a6e5dd08a34bc 100644 (file)
@@ -28,6 +28,8 @@
 #define UHID_NAME      "uhid"
 #define UHID_BUFSIZE   32
 
+static DEFINE_MUTEX(uhid_open_mutex);
+
 struct uhid_device {
        struct mutex devlock;
        bool running;
@@ -142,15 +144,26 @@ static void uhid_hid_stop(struct hid_device *hid)
 static int uhid_hid_open(struct hid_device *hid)
 {
        struct uhid_device *uhid = hid->driver_data;
+       int retval = 0;
 
-       return uhid_queue_event(uhid, UHID_OPEN);
+       mutex_lock(&uhid_open_mutex);
+       if (!hid->open++) {
+               retval = uhid_queue_event(uhid, UHID_OPEN);
+               if (retval)
+                       hid->open--;
+       }
+       mutex_unlock(&uhid_open_mutex);
+       return retval;
 }
 
 static void uhid_hid_close(struct hid_device *hid)
 {
        struct uhid_device *uhid = hid->driver_data;
 
-       uhid_queue_event(uhid, UHID_CLOSE);
+       mutex_lock(&uhid_open_mutex);
+       if (!--hid->open)
+               uhid_queue_event(uhid, UHID_CLOSE);
+       mutex_unlock(&uhid_open_mutex);
 }
 
 static int uhid_hid_parse(struct hid_device *hid)