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
This commit is contained in:
Dmitry Torokhov 2017-05-30 14:46:26 -07:00 committed by Todd Poynor
parent 7d16e880c6
commit df6e5af086

View file

@ -28,6 +28,8 @@
#define UHID_NAME "uhid" #define UHID_NAME "uhid"
#define UHID_BUFSIZE 32 #define UHID_BUFSIZE 32
static DEFINE_MUTEX(uhid_open_mutex);
struct uhid_device { struct uhid_device {
struct mutex devlock; struct mutex devlock;
bool running; bool running;
@ -142,15 +144,26 @@ static void uhid_hid_stop(struct hid_device *hid)
static int uhid_hid_open(struct hid_device *hid) static int uhid_hid_open(struct hid_device *hid)
{ {
struct uhid_device *uhid = hid->driver_data; 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) static void uhid_hid_close(struct hid_device *hid)
{ {
struct uhid_device *uhid = hid->driver_data; 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) static int uhid_hid_parse(struct hid_device *hid)