summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2017-05-30 14:46:26 -0700
committerTodd Poynor <toddpoynor@google.com>2017-06-01 15:23:02 -0700
commitdf6e5af086d3834986af1f6e63f572edde9bc5ee (patch)
treeaa67a99fe6cd5897a425364e4b8b71c630af515b
parent7d16e880c62547936b431cde966d17e39e6e92e0 (diff)
ANDROID: hid: uhid: implement refcount for open and close
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
-rw-r--r--drivers/hid/uhid.c17
1 files changed, 15 insertions, 2 deletions
diff --git a/drivers/hid/uhid.c b/drivers/hid/uhid.c
index 1a2032c2c1fb..690a9f0fa042 100644
--- a/drivers/hid/uhid.c
+++ b/drivers/hid/uhid.c
@@ -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)