Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 264770
b: refs/heads/master
c: 4ea5454
h: refs/heads/master
v: v3
  • Loading branch information
David Herrmann authored and Jiri Kosina committed Aug 10, 2011
1 parent ef93c53 commit ab03f95
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 8 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 00b15628b0aa73199f74bd6c988b8d2b55f51190
refs/heads/master: 4ea5454203d991ec85264f64f89ca8855fce69b0
41 changes: 34 additions & 7 deletions trunk/drivers/hid/hid-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include <linux/wait.h>
#include <linux/vmalloc.h>
#include <linux/sched.h>
#include <linux/semaphore.h>

#include <linux/hid.h>
#include <linux/hiddev.h>
Expand Down Expand Up @@ -1087,14 +1088,23 @@ int hid_input_report(struct hid_device *hid, int type, u8 *data, int size, int i
unsigned int i;
int ret;

if (!hid || !hid->driver)
if (!hid)
return -ENODEV;

if (down_trylock(&hid->driver_lock))
return -EBUSY;

if (!hid->driver) {
ret = -ENODEV;
goto unlock;
}
report_enum = hid->report_enum + type;
hdrv = hid->driver;

if (!size) {
dbg_hid("empty report\n");
return -1;
ret = -1;
goto unlock;
}

buf = kmalloc(sizeof(char) * HID_DEBUG_BUFSIZE, GFP_ATOMIC);
Expand All @@ -1118,17 +1128,23 @@ int hid_input_report(struct hid_device *hid, int type, u8 *data, int size, int i
nomem:
report = hid_get_report(report_enum, data);

if (!report)
return -1;
if (!report) {
ret = -1;
goto unlock;
}

if (hdrv && hdrv->raw_event && hid_match_report(hid, report)) {
ret = hdrv->raw_event(hid, report, data, size);
if (ret != 0)
return ret < 0 ? ret : 0;
if (ret != 0) {
ret = ret < 0 ? ret : 0;
goto unlock;
}
}

hid_report_raw_event(hid, type, data, size, interrupt);

unlock:
up(&hid->driver_lock);
return 0;
}
EXPORT_SYMBOL_GPL(hid_input_report);
Expand Down Expand Up @@ -1617,6 +1633,9 @@ static int hid_device_probe(struct device *dev)
const struct hid_device_id *id;
int ret = 0;

if (down_interruptible(&hdev->driver_lock))
return -EINTR;

if (!hdev->driver) {
id = hid_match_device(hdev, hdrv);
if (id == NULL)
Expand All @@ -1633,14 +1652,20 @@ static int hid_device_probe(struct device *dev)
if (ret)
hdev->driver = NULL;
}

up(&hdev->driver_lock);
return ret;
}

static int hid_device_remove(struct device *dev)
{
struct hid_device *hdev = container_of(dev, struct hid_device, dev);
struct hid_driver *hdrv = hdev->driver;
struct hid_driver *hdrv;

if (down_interruptible(&hdev->driver_lock))
return -EINTR;

hdrv = hdev->driver;
if (hdrv) {
if (hdrv->remove)
hdrv->remove(hdev);
Expand All @@ -1649,6 +1674,7 @@ static int hid_device_remove(struct device *dev)
hdev->driver = NULL;
}

up(&hdev->driver_lock);
return 0;
}

Expand Down Expand Up @@ -1996,6 +2022,7 @@ struct hid_device *hid_allocate_device(void)

init_waitqueue_head(&hdev->debug_wait);
INIT_LIST_HEAD(&hdev->debug_list);
sema_init(&hdev->driver_lock, 1);

return hdev;
err:
Expand Down
2 changes: 2 additions & 0 deletions trunk/include/linux/hid.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@
#include <linux/timer.h>
#include <linux/workqueue.h>
#include <linux/input.h>
#include <linux/semaphore.h>

/*
* We parse each description item into this structure. Short items data
Expand Down Expand Up @@ -475,6 +476,7 @@ struct hid_device { /* device report descriptor */
unsigned country; /* HID country */
struct hid_report_enum report_enum[HID_REPORT_TYPES];

struct semaphore driver_lock; /* protects the current driver */
struct device dev; /* device */
struct hid_driver *driver;
struct hid_ll_driver *ll_driver;
Expand Down

0 comments on commit ab03f95

Please sign in to comment.