From: Dmitry Torokhov Date: Tue, 30 May 2017 21:46:26 +0000 (-0700) Subject: ANDROID: hid: uhid: implement refcount for open and close X-Git-Tag: release-20171130_firefly~4^2~100^2~88 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=76dac329519c70c14330464a23f984ff484b9d7f;p=firefly-linux-kernel-4.4.55.git 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 Signed-off-by: Dmitry Torokhov Change-Id: I57413e42ec961a960a8ddc4942228df22c730d80 --- 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)