diff options
| author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2017-05-30 14:46:26 -0700 |
|---|---|---|
| committer | Mister Oyster <oysterized@gmail.com> | 2017-06-02 13:07:23 +0200 |
| commit | 50020b79c35a259dbca1d37106d2f4dc9d932109 (patch) | |
| tree | 74bd18c823ec09ceb92ad3e696de381592376ebb | |
| parent | 35cb977136a88ddec0cbf3c79a577316d9f5f6a8 (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.c | 17 |
1 files changed, 15 insertions, 2 deletions
diff --git a/drivers/hid/uhid.c b/drivers/hid/uhid.c index 783797baf..9d0cbc640 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; @@ -105,15 +107,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) |
