diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-04-30 09:37:55 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-04-30 09:37:55 -0700 |
commit | 19b344efa35dbc253e2d10403dafe6aafda73c56 (patch) | |
tree | 47c4ad25398642bcf1a93e186d77548ced3f7a2a /drivers/hid/hid-core.c | |
parent | 5d434fcb255dec99189f1c58a06e4f56e12bf77d (diff) | |
parent | ad1b890e06af049fb48d7ccb799d0e96c071c893 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid
Pull HID updates from Jiri Kosina:
- hid driver transport cleanup, finalizing the long-desired decoupling
of core from transport layers, by Benjamin Tissoires and Henrik
Rydberg
- support for hybrid finger/pen multitouch HID devices, by Benjamin
Tissoires
- fix for long-standing issue in Logitech unifying driver sometimes not
inializing properly due to device specifics, by Andrew de los Reyes
- Wii remote driver updates to support 2nd generation of devices, by
David Herrmann
- support for Apple IR remote
- roccat driver now supports new devices (Roccat Kone Pure, IskuFX), by
Stefan Achatz
- debugfs locking fixes in hid debug interface, by Jiri Kosina
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid: (43 commits)
HID: protect hid_debug_list
HID: debug: break out hid_dump_report() into hid-debug
HID: Add PID for Japanese version of NE4K keyboard
HID: hid-lg4ff add support for new version of DFGT wheel
HID: icade: u16 which never < 0
HID: clarify Magic Mouse Kconfig description
HID: appleir: add support for Apple ir devices
HID: roccat: added media key support for Kone
HID: hid-lenovo-tpkbd: remove doubled hid_get_drvdata
HID: i2c-hid: fix length for set/get report in i2c hid
HID: wiimote: parse reduced status reports
HID: wiimote: add 2nd generation Wii Remote IDs
HID: wiimote: use unique battery names
HID: hidraw: warn if userspace headers are outdated
HID: multitouch: force BTN_STYLUS for pen devices
HID: multitouch: append " Pen" to the name of the stylus input
HID: multitouch: add handling for pen in dual-sensors device
HID: multitouch: change touch sensor detection in mt_input_configured()
HID: multitouch: do not map usage from non used reports
HID: multitouch: breaks out touch handling in specific functions
...
Diffstat (limited to 'drivers/hid/hid-core.c')
-rw-r--r-- | drivers/hid/hid-core.c | 63 |
1 files changed, 33 insertions, 30 deletions
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index aa341d13586..6961bbeab3e 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; } |