aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid/hid-core.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hid/hid-core.c')
-rw-r--r--drivers/hid/hid-core.c63
1 files changed, 33 insertions, 30 deletions
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index aa341d135867..6961bbeab3ed 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -728,8 +728,7 @@ static int hid_scan_report(struct hid_device *hid)
} else if (page == HID_UP_SENSOR &&
item.type == HID_ITEM_TYPE_MAIN &&
item.tag == HID_MAIN_ITEM_TAG_BEGIN_COLLECTION &&
- (item_udata(&item) & 0xff) == HID_COLLECTION_PHYSICAL &&
- (hid->bus == BUS_USB || hid->bus == BUS_I2C))
+ (item_udata(&item) & 0xff) == HID_COLLECTION_PHYSICAL)
hid->group = HID_GROUP_SENSOR_HUB;
}
@@ -1260,14 +1259,12 @@ int hid_input_report(struct hid_device *hid, int type, u8 *data, int size, int i
struct hid_report_enum *report_enum;
struct hid_driver *hdrv;
struct hid_report *report;
- char *buf;
- unsigned int i;
int ret = 0;
if (!hid)
return -ENODEV;
- if (down_trylock(&hid->driver_lock))
+ if (down_trylock(&hid->driver_input_lock))
return -EBUSY;
if (!hid->driver) {
@@ -1284,28 +1281,9 @@ int hid_input_report(struct hid_device *hid, int type, u8 *data, int size, int i
}
/* Avoid unnecessary overhead if debugfs is disabled */
- if (list_empty(&hid->debug_list))
- goto nomem;
-
- buf = kmalloc(sizeof(char) * HID_DEBUG_BUFSIZE, GFP_ATOMIC);
-
- if (!buf)
- goto nomem;
-
- /* dump the report */
- snprintf(buf, HID_DEBUG_BUFSIZE - 1,
- "\nreport (size %u) (%snumbered) = ", size, report_enum->numbered ? "" : "un");
- hid_debug_event(hid, buf);
-
- for (i = 0; i < size; i++) {
- snprintf(buf, HID_DEBUG_BUFSIZE - 1,
- " %02x", data[i]);
- hid_debug_event(hid, buf);
- }
- hid_debug_event(hid, "\n");
- kfree(buf);
+ if (!list_empty(&hid->debug_list))
+ hid_dump_report(hid, type, data, size);
-nomem:
report = hid_get_report(report_enum, data);
if (!report) {
@@ -1324,7 +1302,7 @@ nomem:
ret = hid_report_raw_event(hid, type, data, size, interrupt);
unlock:
- up(&hid->driver_lock);
+ up(&hid->driver_input_lock);
return ret;
}
EXPORT_SYMBOL_GPL(hid_input_report);
@@ -1502,8 +1480,6 @@ static const struct hid_device_id hid_have_special_driver[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_X5_005D) },
{ HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_RP_649) },
{ HID_USB_DEVICE(USB_VENDOR_ID_ACRUX, 0x0802) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ATV_IRCONTROL) },
- { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL4) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MIGHTYMOUSE) },
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGICMOUSE) },
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGICTRACKPAD) },
@@ -1527,6 +1503,11 @@ static const struct hid_device_id hid_have_special_driver[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ANSI) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ISO) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_JIS) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL2) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL3) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL4) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL5) },
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI) },
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ISO) },
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS) },
@@ -1654,6 +1635,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_COMFORT_MOUSE_4500) },
{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_SIDEWINDER_GV) },
{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_NE4K) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_NE4K_JP) },
{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_LK6K) },
{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_USB) },
{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_DIGITAL_MEDIA_3K) },
@@ -1687,6 +1669,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_ARVO) },
{ HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_ISKU) },
{ HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONEPLUS) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONEPURE) },
{ HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KOVAPLUS) },
{ HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_LUA) },
{ HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_PYRA_WIRED) },
@@ -1747,6 +1730,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_BT) },
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_NINTENDO, USB_DEVICE_ID_NINTENDO_WIIMOTE) },
+ { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_NINTENDO, USB_DEVICE_ID_NINTENDO_WIIMOTE2) },
{ }
};
@@ -1845,6 +1829,11 @@ static int hid_device_probe(struct device *dev)
if (down_interruptible(&hdev->driver_lock))
return -EINTR;
+ if (down_interruptible(&hdev->driver_input_lock)) {
+ ret = -EINTR;
+ goto unlock_driver_lock;
+ }
+ hdev->io_started = false;
if (!hdev->driver) {
id = hid_match_device(hdev, hdrv);
@@ -1867,6 +1856,9 @@ static int hid_device_probe(struct device *dev)
}
}
unlock:
+ if (!hdev->io_started)
+ up(&hdev->driver_input_lock);
+unlock_driver_lock:
up(&hdev->driver_lock);
return ret;
}
@@ -1875,9 +1867,15 @@ static int hid_device_remove(struct device *dev)
{
struct hid_device *hdev = container_of(dev, struct hid_device, dev);
struct hid_driver *hdrv;
+ int ret = 0;
if (down_interruptible(&hdev->driver_lock))
return -EINTR;
+ if (down_interruptible(&hdev->driver_input_lock)) {
+ ret = -EINTR;
+ goto unlock_driver_lock;
+ }
+ hdev->io_started = false;
hdrv = hdev->driver;
if (hdrv) {
@@ -1889,8 +1887,11 @@ static int hid_device_remove(struct device *dev)
hdev->driver = NULL;
}
+ if (!hdev->io_started)
+ up(&hdev->driver_input_lock);
+unlock_driver_lock:
up(&hdev->driver_lock);
- return 0;
+ return ret;
}
static ssize_t modalias_show(struct device *dev, struct device_attribute *a,
@@ -2340,7 +2341,9 @@ struct hid_device *hid_allocate_device(void)
init_waitqueue_head(&hdev->debug_wait);
INIT_LIST_HEAD(&hdev->debug_list);
+ mutex_init(&hdev->debug_list_lock);
sema_init(&hdev->driver_lock, 1);
+ sema_init(&hdev->driver_input_lock, 1);
return hdev;
}