]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
Merge branches 'for-3.10/appleir', 'for-3.10/hid-debug', 'for-3.10/hid-driver-transpo...
authorJiri Kosina <jkosina@suse.cz>
Tue, 30 Apr 2013 08:12:44 +0000 (10:12 +0200)
committerJiri Kosina <jkosina@suse.cz>
Tue, 30 Apr 2013 08:12:44 +0000 (10:12 +0200)
1  2  3  4 
drivers/hid/Kconfig
drivers/hid/hid-apple.c
drivers/hid/hid-core.c
drivers/hid/hid-lg4ff.c
drivers/hid/hid-logitech-dj.c
drivers/hid/hid-magicmouse.c
drivers/hid/hid-multitouch.c
include/linux/hid.h

diff --combined drivers/hid/Kconfig
index 7f5e0aa5fe5a10bdafc8a92ab7d4c661528ab3e3,5f07d85c4189fc4e0aa41ad5c3bf63e7d77b2ae8,d1dcfc78bed2273a7f64e0d87c61a469639d6fc1,5f07d85c4189fc4e0aa41ad5c3bf63e7d77b2ae8..15187b85895d408ad561d02e374cbc8070d9dc9c
@@@@@ -92,14 -92,14 -92,14 -92,14 +92,14 @@@@@ menu "Special HID drivers
    
    config HID_A4TECH
        tristate "A4 tech mice" if EXPERT
-- -    depends on USB_HID
++ +    depends on HID
        default !EXPERT
        ---help---
        Support for A4 tech X5 and WOP-35 / Trust 450L mice.
    
    config HID_ACRUX
        tristate "ACRUX game controller support"
-- -    depends on USB_HID
++ +    depends on HID
        ---help---
        Say Y here if you want to enable support for ACRUX game controllers.
    
@@@@@ -113,7 -113,7 -113,7 -113,7 +113,7 @@@@@ config HID_ACRUX_F
    
    config HID_APPLE
        tristate "Apple {i,Power,Mac}Books" if EXPERT
-- -    depends on (USB_HID || BT_HIDP)
++ +    depends on HID
        default !EXPERT
        ---help---
        Support for some Apple devices which less or more break
        Say Y here if you want support for keyboards of Apple iBooks, PowerBooks,
        MacBooks, MacBook Pros and Apple Aluminum.
    
 +++config HID_APPLEIR
 +++    tristate "Apple infrared receiver"
 +++    depends on (USB_HID)
 +++    ---help---
 +++    Support for Apple infrared remote control. All the Apple computers from
 +++      2005 onwards include such a port, except the unibody Macbook (2009),
 +++      and Mac Pros. This receiver is also used in the Apple TV set-top box
 +++      prior to the 2010 model.
 +++
 +++    Say Y here if you want support for Apple infrared remote control.
 +++
    config HID_AUREAL
        tristate "Aureal"
-- -    depends on USB_HID
++ +    depends on HID
        ---help---
        Support for Aureal Cy se W-01RN Remote Controller and other Aureal derived remotes.
    
    config HID_BELKIN
        tristate "Belkin Flip KVM and Wireless keyboard" if EXPERT
-- -    depends on USB_HID
++ +    depends on HID
        default !EXPERT
        ---help---
        Support for Belkin Flip KVM and Wireless keyboard.
    
    config HID_CHERRY
        tristate "Cherry Cymotion keyboard" if EXPERT
-- -    depends on USB_HID
++ +    depends on HID
        default !EXPERT
        ---help---
        Support for Cherry Cymotion keyboard.
    
    config HID_CHICONY
        tristate "Chicony Tactical pad" if EXPERT
-- -    depends on USB_HID
++ +    depends on HID
        default !EXPERT
        ---help---
        Support for Chicony Tactical pad.
    
    config HID_PRODIKEYS
        tristate "Prodikeys PC-MIDI Keyboard support"
-- -    depends on USB_HID && SND
++ +    depends on HID && SND
        select SND_RAWMIDI
        ---help---
        Support for Prodikeys PC-MIDI Keyboard device support.
    
    config HID_CYPRESS
        tristate "Cypress mouse and barcode readers" if EXPERT
-- -    depends on USB_HID
++ +    depends on HID
        default !EXPERT
        ---help---
        Support for cypress mouse and barcode readers.
    
    config HID_DRAGONRISE
        tristate "DragonRise Inc. game controller"
-- -    depends on USB_HID
++ +    depends on HID
        ---help---
        Say Y here if you have DragonRise Inc. game controllers.
        These might be branded as:
@@@@@ -203,7 -192,7 -192,7 -192,7 +203,7 @@@@@ config DRAGONRISE_F
    
    config HID_EMS_FF
        tristate "EMS Production Inc. force feedback support"
-- -    depends on USB_HID
++ +    depends on HID
        select INPUT_FF_MEMLESS
        ---help---
        Say Y here if you want to enable force feedback support for devices by
    
    config HID_ELECOM
        tristate "ELECOM BM084 bluetooth mouse"
-- -    depends on BT_HIDP
++ +    depends on HID
        ---help---
        Support for the ELECOM BM084 (bluetooth mouse).
    
    config HID_EZKEY
        tristate "Ezkey BTC 8193 keyboard" if EXPERT
-- -    depends on USB_HID
++ +    depends on HID
        default !EXPERT
        ---help---
        Support for Ezkey BTC 8193 keyboard.
@@@@@ -242,7 -231,7 -231,7 -231,7 +242,7 @@@@@ config HOLTEK_F
    
    config HID_KEYTOUCH
        tristate "Keytouch HID devices"
-- -    depends on USB_HID
++ +    depends on HID
        ---help---
        Support for Keytouch HID devices not fully compliant with
        the specification. Currently supported:
    
    config HID_KYE
        tristate "KYE/Genius devices"
-- -    depends on USB_HID
++ +    depends on HID
        ---help---
        Support for KYE/Genius devices not fully compliant with HID standard:
        - Ergo Mouse
    
    config HID_UCLOGIC
        tristate "UC-Logic"
-- -    depends on USB_HID
++ +    depends on HID
        ---help---
        Support for UC-Logic tablets.
    
    config HID_WALTOP
        tristate "Waltop"
-- -    depends on USB_HID
++ +    depends on HID
        ---help---
        Support for Waltop tablets.
    
    config HID_GYRATION
        tristate "Gyration remote control"
-- -    depends on USB_HID
++ +    depends on HID
        ---help---
        Support for Gyration remote control.
    
    config HID_ICADE
        tristate "ION iCade arcade controller"
-- -    depends on BT_HIDP
++ +    depends on HID
        ---help---
        Support for the ION iCade arcade controller to work as a joystick.
    
    
    config HID_TWINHAN
        tristate "Twinhan IR remote control"
-- -    depends on USB_HID
++ +    depends on HID
        ---help---
        Support for Twinhan IR remote control.
    
    config HID_KENSINGTON
        tristate "Kensington Slimblade Trackball" if EXPERT
-- -    depends on USB_HID
++ +    depends on HID
        default !EXPERT
        ---help---
        Support for Kensington Slimblade Trackball.
    
    config HID_LCPOWER
        tristate "LC-Power"
-- -    depends on USB_HID
++ +    depends on HID
        ---help---
        Support for LC-Power RC1000MCE RF remote control.
    
@@@@@ -319,7 -308,7 -308,7 -308,7 +319,7 @@@@@ config HID_LENOVO_TPKB
    
    config HID_LOGITECH
        tristate "Logitech devices" if EXPERT
-- -    depends on USB_HID
++ +    depends on HID
        default !EXPERT
        ---help---
        Support for Logitech devices that are not fully compliant with HID standard.
@@@@@ -385,7 -374,7 -374,7 -374,7 +385,7 @@@@@ config LOGIWHEELS_F
    
    config HID_MAGICMOUSE
        tristate "Apple MagicMouse multi-touch support"
-- -    depends on BT_HIDP
++ +    depends on HID
        ---help---
        Support for the Apple Magic Mouse multi-touch.
    
    
    config HID_MICROSOFT
        tristate "Microsoft non-fully HID-compliant devices" if EXPERT
-- -    depends on USB_HID
++ +    depends on HID
        default !EXPERT
        ---help---
        Support for Microsoft devices that are not fully compliant with HID standard.
    
    config HID_MONTEREY
        tristate "Monterey Genius KB29E keyboard" if EXPERT
-- -    depends on USB_HID
++ +    depends on HID
        default !EXPERT
        ---help---
        Support for Monterey Genius KB29E.
    
    config HID_MULTITOUCH
        tristate "HID Multitouch panels"
-- -    depends on USB_HID
++ +    depends on HID
        ---help---
          Generic support for HID multitouch panels.
    
@@@@@ -456,7 -445,7 -445,7 -445,7 +456,7 @@@@@ config HID_NTRI
    
    config HID_ORTEK
        tristate "Ortek PKB-1700/WKB-2000/Skycable wireless keyboard and mouse trackpad"
-- -    depends on USB_HID
++ +    depends on HID
        ---help---
        There are certain devices which have LogicalMaximum wrong in the keyboard
        usage page of their report descriptor. The most prevailing ones so far
    
    config HID_PANTHERLORD
        tristate "Pantherlord/GreenAsia game controller"
-- -    depends on USB_HID
++ +    depends on HID
        ---help---
          Say Y here if you have a PantherLord/GreenAsia based game controller
          or adapter.
@@@@@ -484,13 -473,13 -473,13 -473,13 +484,13 @@@@@ config PANTHERLORD_F
    
    config HID_PETALYNX
        tristate "Petalynx Maxter remote control"
-- -    depends on USB_HID
++ +    depends on HID
        ---help---
        Support for Petalynx Maxter remote control.
    
    config HID_PICOLCD
        tristate "PicoLCD (graphic version)"
-- -    depends on USB_HID
++ +    depends on HID
        ---help---
          This provides support for Minibox PicoLCD devices, currently
          only the graphical ones are supported.
@@@@@ -556,14 -545,14 -545,14 -545,14 +556,14 @@@@@ config HID_PICOLCD_CI
    
    config HID_PRIMAX
        tristate "Primax non-fully HID-compliant devices"
-- -    depends on USB_HID
++ +    depends on HID
        ---help---
        Support for Primax devices that are not fully compliant with the
        HID standard.
    
    config HID_PS3REMOTE
        tristate "Sony PS3 BD Remote Control"
-- -    depends on BT_HIDP
++ +    depends on HID
        ---help---
        Support for the Sony PS3 Blue-ray Disk Remote Control and Logitech
        Harmony Adapter for PS3, which connect over Bluetooth.
@@@@@ -580,7 -569,7 -569,7 -569,7 +580,7 @@@@@ config HID_ROCCA
    
    config HID_SAITEK
        tristate "Saitek non-fully HID-compliant devices"
-- -    depends on USB_HID
++ +    depends on HID
        ---help---
        Support for Saitek devices that are not fully compliant with the
        HID standard.
    
    config HID_SAMSUNG
        tristate "Samsung InfraRed remote control or keyboards"
-- -    depends on USB_HID
++ +    depends on HID
        ---help---
        Support for Samsung InfraRed remote control or keyboards.
    
@@@@@ -603,25 -592,25 -592,25 -592,25 +603,25 @@@@@ config HID_SON
    
    config HID_SPEEDLINK
        tristate "Speedlink VAD Cezanne mouse support"
-- -    depends on USB_HID
++ +    depends on HID
        ---help---
        Support for Speedlink Vicious and Divine Cezanne mouse.
    
    config HID_STEELSERIES
        tristate "Steelseries SRW-S1 steering wheel support"
-- -    depends on USB_HID
++ +    depends on HID
        ---help---
        Support for Steelseries SRW-S1 steering wheel
    
    config HID_SUNPLUS
        tristate "Sunplus wireless desktop"
-- -    depends on USB_HID
++ +    depends on HID
        ---help---
        Support for Sunplus wireless desktop.
    
    config HID_GREENASIA
        tristate "GreenAsia (Product ID 0x12) game controller support"
-- -    depends on USB_HID
++ +    depends on HID
        ---help---
          Say Y here if you have a GreenAsia (Product ID 0x12) based game
          controller or adapter.
@@@@@ -643,7 -632,7 -632,7 -632,7 +643,7 @@@@@ config HID_HYPERV_MOUS
    
    config HID_SMARTJOYPLUS
        tristate "SmartJoy PLUS PS2/USB adapter support"
-- -    depends on USB_HID
++ +    depends on HID
        ---help---
        Support for SmartJoy PLUS PS2/USB adapter, Super Dual Box,
        Super Joy Box 3 Pro, Super Dual Box Pro, and Super Joy Box 5 Pro.
@@@@@ -661,20 -650,20 -650,20 -650,20 +661,20 @@@@@ config SMARTJOYPLUS_F
    
    config HID_TIVO
        tristate "TiVo Slide Bluetooth remote control support"
-- -    depends on (USB_HID || BT_HIDP)
++ +    depends on HID
        ---help---
        Say Y if you have a TiVo Slide Bluetooth remote control.
    
    config HID_TOPSEED
        tristate "TopSeed Cyberlink, BTC Emprex, Conceptronic remote control support"
-- -    depends on USB_HID
++ +    depends on HID
        ---help---
        Say Y if you have a TopSeed Cyberlink or BTC Emprex or Conceptronic
        CLLRCMCE remote control.
    
    config HID_THINGM
        tristate "ThingM blink(1) USB RGB LED"
-- -    depends on USB_HID
++ +    depends on HID
        depends on LEDS_CLASS
        ---help---
        Support for the ThingM blink(1) USB RGB LED. This driver registers a
    
    config HID_THRUSTMASTER
        tristate "ThrustMaster devices support"
-- -    depends on USB_HID
++ +    depends on HID
        ---help---
          Say Y here if you have a THRUSTMASTER FireStore Dual Power 2 or
          a THRUSTMASTER Ferrari GT Rumble Wheel.
@@@@@ -700,7 -689,7 -689,7 -689,7 +700,7 @@@@@ config THRUSTMASTER_F
    
    config HID_WACOM
        tristate "Wacom Bluetooth devices support"
-- -    depends on BT_HIDP
++ +    depends on HID
        depends on LEDS_CLASS
        select POWER_SUPPLY
        ---help---
    
    config HID_WIIMOTE
        tristate "Nintendo Wii Remote support"
-- -    depends on BT_HIDP
++ +    depends on HID
        depends on LEDS_CLASS
        select POWER_SUPPLY
        select INPUT_FF_MEMLESS
@@@@@ -726,7 -715,7 -715,7 -715,7 +726,7 @@@@@ config HID_WIIMOTE_EX
    
    config HID_ZEROPLUS
        tristate "Zeroplus based game controller support"
-- -    depends on USB_HID
++ +    depends on HID
        ---help---
          Say Y here if you have a Zeroplus based game controller.
    
@@@@@ -740,13 -729,13 -729,13 -729,13 +740,13 @@@@@ config ZEROPLUS_F
    
    config HID_ZYDACRON
        tristate "Zydacron remote control support"
-- -    depends on USB_HID
++ +    depends on HID
        ---help---
        Support for Zydacron remote control.
    
    config HID_SENSOR_HUB
        tristate "HID Sensors framework support"
-- -    depends on USB_HID && GENERIC_HARDIRQS
++ +    depends on HID && GENERIC_HARDIRQS
        select MFD_CORE
        default n
        -- help---
diff --combined drivers/hid/hid-apple.c
index 5c5c57b6d59a8063f3a0e2aa52c2e495fae47d2f,320a958d4139ce57fc386087a93bffa23054d13f,9e0c4fbbb840a6b788da7dffecd31db844fde939,320a958d4139ce57fc386087a93bffa23054d13f..feae88b53fcd7597bc477aeef4dae7182f8f05ed
    #include <linux/hid.h>
    #include <linux/module.h>
    #include <linux/slab.h>
-- -#include <linux/usb.h>
    
    #include "hid-ids.h"
    
@@@@@ -390,6 -390,10 -389,10 -390,10 +389,6 @@@@@ static void apple_remove(struct hid_dev
    }
    
    static const struct hid_device_id apple_devices[] = {
 ---    { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ATV_IRCONTROL),
 ---            .driver_data = APPLE_HIDDEV | APPLE_IGNORE_HIDINPUT },
 ---    { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL4),
 ---            .driver_data = APPLE_HIDDEV | APPLE_IGNORE_HIDINPUT },
        { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MIGHTYMOUSE),
                .driver_data = APPLE_MIGHTYMOUSE | APPLE_INVERT_HWHEEL },
    
diff --combined drivers/hid/hid-core.c
index bf434a0f813f5c758983e8e86bb11ea8037c9b8f,e7765ede339e6f8d2e5a04bcb3c5bc8295bcbf5b,b76eb9eb6ff177e3216051674ee3fbe8cf863fce,680068c0c46af3ca8f9d61bf5d987a86e24c77eb..734b3d44dae5aa08dbc22f2ac9d7a664a3997922
@@@@@ -728,8 -728,8 -728,7 -728,8 +728,7 @@@@@ static int hid_scan_report(struct hid_d
                } 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 -1260,12 -1259,14 -1260,14 +1259,12 @@@@@ int hid_input_report(struct hid_device 
        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) {
        }
    
        /* 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) {
        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,6 -1481,8 -1501,8 -1502,8 +1480,6 @@@@@ static const struct hid_device_id hid_h
        { 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) },
        { 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) },
@@@@@ -1848,6 -1824,6 -1844,6 -1845,11 +1826,11 @@@@@ static int hid_device_probe(struct devi
    
        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);
                }
        }
    unlock:
+++     if (!hdev->io_started)
+++             up(&hdev->driver_input_lock);
+++ unlock_driver_lock:
        up(&hdev->driver_lock);
        return ret;
    }
@@@@@ -1878,9 -1854,9 -1874,9 -1883,15 +1864,15 @@@@@ static int hid_device_remove(struct 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) {
                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,
@@@@@ -2080,6 -2056,6 -2076,7 -2094,6 +2075,6 @@@@@ static const struct hid_device_id hid_i
        { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_HYBRID) },
        { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_HEATCONTROL) },
        { HID_USB_DEVICE(USB_VENDOR_ID_MADCATZ, USB_DEVICE_ID_MADCATZ_BEATPAD) },
  -     { HID_USB_DEVICE(USB_VENDOR_ID_MASTERKIT, USB_DEVICE_ID_MASTERKIT_MA901RADIO) },
        { HID_USB_DEVICE(USB_VENDOR_ID_MCC, USB_DEVICE_ID_MCC_PMD1024LS) },
        { HID_USB_DEVICE(USB_VENDOR_ID_MCC, USB_DEVICE_ID_MCC_PMD1208LS) },
        { HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICKIT1) },
@@@@@ -2246,18 -2222,18 -2243,6 -2260,6 +2241,18 @@@@@ bool hid_ignore(struct hid_device *hdev
                     hdev->product <= USB_DEVICE_ID_VELLEMAN_K8061_LAST))
                        return true;
                break;
  ++    case USB_VENDOR_ID_ATMEL_V_USB:
  ++            /* Masterkit MA901 usb radio based on Atmel tiny85 chip and
  ++             * it has the same USB ID as many Atmel V-USB devices. This
  ++             * usb radio is handled by radio-ma901.c driver so we want
  ++             * ignore the hid. Check the name, bus, product and ignore
  ++             * if we have MA901 usb radio.
  ++             */
  ++            if (hdev->product == USB_DEVICE_ID_ATMEL_V_USB &&
  ++                    hdev->bus == BUS_USB &&
  ++                    strncmp(hdev->name, "www.masterkit.ru MA901", 22) == 0)
  ++                    return true;
  ++            break;
        }
    
        if (hdev->type == HID_TYPE_USBMOUSE &&
@@@@@ -2343,7 -2319,8 -2328,7 -2345,8 +2338,9 @@@@@ struct hid_device *hid_allocate_device(
    
        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;
    }
diff --combined drivers/hid/hid-lg4ff.c
index 65a6ec8d37421343d597f2a42234a84532205ae0,65a6ec8d37421343d597f2a42234a84532205ae0,7da40a1797cd83b6675ab1fe8998ebba7d30202e,2dd73604c68f680160645355d0a83e32ffb40013..0ddae2a00d59a595b4d7ad436dc8cedcfdde7b71
    
    #define DFGT_REV_MAJ 0x13
    #define DFGT_REV_MIN 0x22
+++ #define DFGT2_REV_MIN 0x26
    #define DFP_REV_MAJ 0x11
    #define DFP_REV_MIN 0x06
    #define FFEX_REV_MAJ 0x21
@@@@@ -125,6 -125,6 -125,6 -126,7 +126,7 @@@@@ static const struct lg4ff_native_cmd na
    
    static const struct lg4ff_usb_revision lg4ff_revs[] = {
        {DFGT_REV_MAJ, DFGT_REV_MIN, &native_dfgt},     /* Driving Force GT */
+++     {DFGT_REV_MAJ, DFGT2_REV_MIN, &native_dfgt},    /* Driving Force GT v2 */
        {DFP_REV_MAJ,  DFP_REV_MIN,  &native_dfp},      /* Driving Force Pro */
        {G25_REV_MAJ,  G25_REV_MIN,  &native_g25},      /* G25 */
        {G27_REV_MAJ,  G27_REV_MIN,  &native_g27},      /* G27 */
@@@@@ -202,7 -202,7 -202,7 -204,7 +204,7 @@@@@ static int hid_lg4ff_play(struct input_
                value[5] = 0x00;
                value[6] = 0x00;
    
-- -            usbhid_submit_report(hid, report, USB_DIR_OUT);
++ +            hid_hw_request(hid, report, HID_REQ_SET_REPORT);
                break;
        }
        return 0;
@@@@@ -225,7 -225,7 -225,7 -227,7 +227,7 @@@@@ static void hid_lg4ff_set_autocenter_de
        value[5] = 0x00;
        value[6] = 0x00;
    
-- -    usbhid_submit_report(hid, report, USB_DIR_OUT);
++ +    hid_hw_request(hid, report, HID_REQ_SET_REPORT);
    }
    
    /* Sends autocentering command compatible with Formula Force EX */
@@@@@ -245,7 -245,7 -245,7 -247,7 +247,7 @@@@@ static void hid_lg4ff_set_autocenter_ff
        value[5] = 0x00;
        value[6] = 0x00;
    
-- -    usbhid_submit_report(hid, report, USB_DIR_OUT);
++ +    hid_hw_request(hid, report, HID_REQ_SET_REPORT);
    }
    
    /* Sends command to set range compatible with G25/G27/Driving Force GT */
@@@@@ -265,7 -265,7 -265,7 -267,7 +267,7 @@@@@ static void hid_lg4ff_set_range_g25(str
        value[5] = 0x00;
        value[6] = 0x00;
    
-- -    usbhid_submit_report(hid, report, USB_DIR_OUT);
++ +    hid_hw_request(hid, report, HID_REQ_SET_REPORT);
    }
    
    /* Sends commands to set range compatible with Driving Force Pro wheel */
@@@@@ -294,7 -294,7 -294,7 -296,7 +296,7 @@@@@ static void hid_lg4ff_set_range_dfp(str
                report->field[0]->value[1] = 0x02;
                full_range = 200;
        }
-- -    usbhid_submit_report(hid, report, USB_DIR_OUT);
++ +    hid_hw_request(hid, report, HID_REQ_SET_REPORT);
    
        /* Prepare "fine" limit command */
        value[0] = 0x81;
        value[6] = 0x00;
    
        if (range == 200 || range == 900) {     /* Do not apply any fine limit */
-- -            usbhid_submit_report(hid, report, USB_DIR_OUT);
++ +            hid_hw_request(hid, report, HID_REQ_SET_REPORT);
                return;
        }
    
        value[5] = (start_right & 0xe) << 4 | (start_left & 0xe);
        value[6] = 0xff;
    
-- -    usbhid_submit_report(hid, report, USB_DIR_OUT);
++ +    hid_hw_request(hid, report, HID_REQ_SET_REPORT);
    }
    
    static void hid_lg4ff_switch_native(struct hid_device *hid, const struct lg4ff_native_cmd *cmd)
                for (i = 0; i < 7; i++)
                        report->field[0]->value[i] = cmd->cmd[j++];
    
-- -            usbhid_submit_report(hid, report, USB_DIR_OUT);
++ +            hid_hw_request(hid, report, HID_REQ_SET_REPORT);
        }
    }
    
@@@@@ -410,7 -410,7 -410,7 -412,7 +412,7 @@@@@ static void lg4ff_set_leds(struct hid_d
        value[4] = 0x00;
        value[5] = 0x00;
        value[6] = 0x00;
-- -    usbhid_submit_report(hid, report, USB_DIR_OUT);
++ +    hid_hw_request(hid, report, HID_REQ_SET_REPORT);
    }
    
    static void lg4ff_led_set_brightness(struct led_classdev *led_cdev,
index 8758f38c948c2022b45da342f15025228ea6b22d,8758f38c948c2022b45da342f15025228ea6b22d,d9043434ddb32f1e62129e4596a42d72043e6791,199b78c8a5f36b272bbf3949fb50ab7053f5874b..5207591a598c05944a348be2252c4a346e0e5cfa
    #include <linux/module.h>
    #include <linux/usb.h>
    #include <asm/unaligned.h>
-- -#include "usbhid/usbhid.h"
    #include "hid-ids.h"
    #include "hid-logitech-dj.h"
    
@@@@@ -193,7 -193,7 -192,7 -193,6 +192,6 @@@@@ static struct hid_ll_driver logi_dj_ll_
    static int logi_dj_output_hidraw_report(struct hid_device *hid, u8 * buf,
                                        size_t count,
                                        unsigned char report_type);
--- static int logi_dj_recv_query_paired_devices(struct dj_receiver_dev *djrcv_dev);
    
    static void logi_dj_recv_destroy_djhid_device(struct dj_receiver_dev *djrcv_dev,
                                                struct dj_report *dj_report)
@@@@@ -234,7 -234,7 -233,7 -233,6 +232,6 @@@@@ static void logi_dj_recv_add_djhid_devi
        if (dj_report->report_params[DEVICE_PAIRED_PARAM_SPFUNCTION] &
            SPFUNCTION_DEVICE_LIST_EMPTY) {
                dbg_hid("%s: device list is empty\n", __func__);
---             djrcv_dev->querying_devices = false;
                return;
        }
    
                return;
        }
    
---     if (djrcv_dev->paired_dj_devices[dj_report->device_index]) {
---             /* The device is already known. No need to reallocate it. */
---             dbg_hid("%s: device is already known\n", __func__);
---             return;
---     }
--- 
        dj_hiddev = hid_allocate_device();
        if (IS_ERR(dj_hiddev)) {
                dev_err(&djrcv_hdev->dev, "%s: hid_allocate_device failed\n",
@@@@@ -314,7 -314,7 -313,7 -306,6 +305,6 @@@@@ static void delayedwork_callback(struc
        struct dj_report dj_report;
        unsigned long flags;
        int count;
---     int retval;
    
        dbg_hid("%s\n", __func__);
    
                logi_dj_recv_destroy_djhid_device(djrcv_dev, &dj_report);
                break;
        default:
---     /* A normal report (i. e. not belonging to a pair/unpair notification)
---      * arriving here, means that the report arrived but we did not have a
---      * paired dj_device associated to the report's device_index, this
---      * means that the original "device paired" notification corresponding
---      * to this dj_device never arrived to this driver. The reason is that
---      * hid-core discards all packets coming from a device while probe() is
---      * executing. */
---     if (!djrcv_dev->paired_dj_devices[dj_report.device_index]) {
---             /* ok, we don't know the device, just re-ask the
---              * receiver for the list of connected devices. */
---             retval = logi_dj_recv_query_paired_devices(djrcv_dev);
---             if (!retval) {
---                     /* everything went fine, so just leave */
---                     break;
---             }
---             dev_err(&djrcv_dev->hdev->dev,
---                     "%s:logi_dj_recv_query_paired_devices "
---                     "error:%d\n", __func__, retval);
---             }
                dbg_hid("%s: unexpected report type\n", __func__);
        }
    }
@@@@@ -396,12 -396,12 -395,12 -368,6 +367,6 @@@@@ static void logi_dj_recv_forward_null_r
        if (!djdev) {
                dbg_hid("djrcv_dev->paired_dj_devices[dj_report->device_index]"
                        " is NULL, index %d\n", dj_report->device_index);
---             kfifo_in(&djrcv_dev->notif_fifo, dj_report, sizeof(struct dj_report));
--- 
---             if (schedule_work(&djrcv_dev->work) == 0) {
---                     dbg_hid("%s: did not schedule the work item, was already "
---                     "queued\n", __func__);
---             }
                return;
        }
    
@@@@@ -432,12 -432,12 -431,12 -398,6 +397,6 @@@@@ static void logi_dj_recv_forward_report
        if (dj_device == NULL) {
                dbg_hid("djrcv_dev->paired_dj_devices[dj_report->device_index]"
                        " is NULL, index %d\n", dj_report->device_index);
---             kfifo_in(&djrcv_dev->notif_fifo, dj_report, sizeof(struct dj_report));
--- 
---             if (schedule_work(&djrcv_dev->work) == 0) {
---                     dbg_hid("%s: did not schedule the work item, was already "
---                     "queued\n", __func__);
---             }
                return;
        }
    
@@@@@ -459,25 -459,25 -458,25 -419,19 +418,25 @@@@@ static int logi_dj_recv_send_report(str
                                    struct dj_report *dj_report)
    {
        struct hid_device *hdev = djrcv_dev->hdev;
   -    int sent_bytes;
   +    struct hid_report *report;
   +    struct hid_report_enum *output_report_enum;
   +    u8 *data = (u8 *)(&dj_report->device_index);
   +    int i;
   +
   +    output_report_enum = &hdev->report_enum[HID_OUTPUT_REPORT];
   +    report = output_report_enum->report_id_hash[REPORT_ID_DJ_SHORT];
    
   -    if (!hdev->hid_output_raw_report) {
   -            dev_err(&hdev->dev, "%s:"
   -                    "hid_output_raw_report is null\n", __func__);
   +    if (!report) {
   +            dev_err(&hdev->dev, "%s: unable to find dj report\n", __func__);
                return -ENODEV;
        }
    
   -    sent_bytes = hdev->hid_output_raw_report(hdev, (u8 *) dj_report,
   -                                             sizeof(struct dj_report),
   -                                             HID_OUTPUT_REPORT);
   +    for (i = 0; i < report->field[0]->report_count; i++)
   +            report->field[0]->value[i] = data[i];
   +
--      usbhid_submit_report(hdev, report, USB_DIR_OUT);
++ +    hid_hw_request(hdev, report, HID_REQ_SET_REPORT);
    
   -    return (sent_bytes < 0) ? sent_bytes : 0;
   +    return 0;
    }
    
    static int logi_dj_recv_query_paired_devices(struct dj_receiver_dev *djrcv_dev)
        struct dj_report *dj_report;
        int retval;
    
---     /* no need to protect djrcv_dev->querying_devices */
---     if (djrcv_dev->querying_devices)
---             return 0;
--- 
        dj_report = kzalloc(sizeof(struct dj_report), GFP_KERNEL);
        if (!dj_report)
                return -ENOMEM;
        return retval;
    }
    
--- 
    static int logi_dj_recv_switch_to_dj_mode(struct dj_receiver_dev *djrcv_dev,
                                          unsigned timeout)
    {
@@@@@ -644,7 -644,7 -643,7 -593,7 +598,7 @@@@@ static int logi_dj_ll_input_event(struc
        hid_set_field(report->field[0], 1, REPORT_TYPE_LEDS);
        hid_set_field(report->field[0], 2, data[1]);
    
-- -    usbhid_submit_report(dj_rcv_hiddev, report, USB_DIR_OUT);
++ +    hid_hw_request(dj_rcv_hiddev, report, HID_REQ_SET_REPORT);
    
        return 0;
    
@@@@@ -809,6 -809,6 -808,6 -758,9 +763,9 @@@@@ static int logi_dj_probe(struct hid_dev
                goto llopen_failed;
        }
    
+++     /* Allow incoming packets to arrive: */
+++     hid_device_io_start(hdev);
+++ 
        retval = logi_dj_recv_query_paired_devices(djrcv_dev);
        if (retval < 0) {
                dev_err(&hdev->dev, "%s:logi_dj_recv_query_paired_devices "
index a8ce44296cfddaf34a486a7c78edde4836cd3115,a8ce44296cfddaf34a486a7c78edde4836cd3115,ef89573d65fcb5cdcbf1d103e0a46f2a95c00f61,f7f113ba083eb43fb1073d189a4979f7d4d6d724..5bc37343eb22b3de7f3cca6163c6f1fd9a10dd4b
    #include <linux/input/mt.h>
    #include <linux/module.h>
    #include <linux/slab.h>
-- -#include <linux/usb.h>
    
    #include "hid-ids.h"
    
@@@@@ -462,21 -462,21 -461,6 -462,6 +461,21 @@@@@ static int magicmouse_input_mapping(str
        return 0;
    }
    
  ++static void magicmouse_input_configured(struct hid_device *hdev,
  ++            struct hid_input *hi)
  ++
  ++{
  ++    struct magicmouse_sc *msc = hid_get_drvdata(hdev);
  ++
  ++    int ret = magicmouse_setup_input(msc->input, hdev);
  ++    if (ret) {
  ++            hid_err(hdev, "magicmouse setup input failed (%d)\n", ret);
  ++            /* clean msc->input to notify probe() of the failure */
  ++            msc->input = NULL;
  ++    }
  ++}
  ++
  ++
    static int magicmouse_probe(struct hid_device *hdev,
        const struct hid_device_id *id)
    {
                goto err_free;
        }
    
  --    /* We do this after hid-input is done parsing reports so that
  --     * hid-input uses the most natural button and axis IDs.
  --     */
  --    if (msc->input) {
  --            ret = magicmouse_setup_input(msc->input, hdev);
  --            if (ret) {
  --                    hid_err(hdev, "magicmouse setup input failed (%d)\n", ret);
  --                    goto err_stop_hw;
  --            }
  ++    if (!msc->input) {
  ++            hid_err(hdev, "magicmouse input not registered\n");
  ++            ret = -ENOMEM;
  ++            goto err_stop_hw;
        }
    
        if (id->product == USB_DEVICE_ID_APPLE_MAGICMOUSE)
@@@@@ -578,7 -578,7 -567,6 -568,6 +577,7 @@@@@ static struct hid_driver magicmouse_dri
        .remove = magicmouse_remove,
        .raw_event = magicmouse_raw_event,
        .input_mapping = magicmouse_input_mapping,
  ++    .input_configured = magicmouse_input_configured,
    };
    module_hid_driver(magicmouse_driver);
    
index 82e9211b3ca97cfec8f316d33870f22f6fac0617,82e9211b3ca97cfec8f316d33870f22f6fac0617,f712772437cb631ee616ecca5594d12bc60b02f5,7a1ebb867cf499596e9c4fe5b1a43860b86d4351..f19ec1586c5a67b4af1a70a4d31a2d5e5f68fe50
@@@@@ -2,8 -2,8 -2,9 -2,8 +2,9 @@@@@
     *  HID driver for multitouch panels
     *
     *  Copyright (c) 2010-2012 Stephane Chatty <chatty@enac.fr>
-- - *  Copyright (c) 2010-2012 Benjamin Tissoires <benjamin.tissoires@gmail.com>
++ + *  Copyright (c) 2010-2013 Benjamin Tissoires <benjamin.tissoires@gmail.com>
     *  Copyright (c) 2010-2012 Ecole Nationale de l'Aviation Civile, France
++ + *  Copyright (c) 2012-2013 Red Hat, Inc
     *
     *  This code is partly based on hid-egalax.c:
     *
     * any later version.
     */
    
++ +/*
++ + * This driver is regularly tested thanks to the tool hid-test[1].
++ + * This tool relies on hid-replay[2] and a database of hid devices[3].
++ + * Please run these regression tests before patching this module so that
++ + * your patch won't break existing known devices.
++ + *
++ + * [1] https://github.com/bentiss/hid-test
++ + * [2] https://github.com/bentiss/hid-replay
++ + * [3] https://github.com/bentiss/hid-devices
++ + */
++ +
    #include <linux/device.h>
    #include <linux/hid.h>
    #include <linux/module.h>
    #include <linux/slab.h>
    #include <linux/usb.h>
    #include <linux/input/mt.h>
-- -#include "usbhid/usbhid.h"
    
    
    MODULE_AUTHOR("Stephane Chatty <chatty@enac.fr>");
@@@@@ -621,7 -621,7 -632,6 -621,6 +632,7 @@@@@ static void mt_process_mt_event(struct 
    {
        struct mt_device *td = hid_get_drvdata(hid);
        __s32 quirks = td->mtclass.quirks;
  ++    struct input_dev *input = field->hidinput->input;
    
        if (hid->claimed & HID_CLAIMED_INPUT) {
                switch (usage->hid) {
                        break;
    
                default:
  ++                    if (usage->type)
  ++                            input_event(input, usage->type, usage->code,
  ++                                            value);
                        return;
                }
    
                if (usage->usage_index + 1 == field->report_count) {
                        /* we only take into account the last report. */
                        if (usage->hid == td->last_slot_field)
  --                            mt_complete_slot(td, field->hidinput->input);
  ++                            mt_complete_slot(td, input);
    
                        if (field->index == td->last_field_index
                                && td->num_received >= td->num_expected)
@@@@@ -740,7 -740,7 -747,7 -736,7 +751,7 @@@@@ static void mt_set_input_mode(struct hi
        r = re->report_id_hash[td->inputmode];
        if (r) {
                r->field[0]->value[td->inputmode_index] = 0x02;
-- -            usbhid_submit_report(hdev, r, USB_DIR_OUT);
++ +            hid_hw_request(hdev, r, HID_REQ_SET_REPORT);
        }
    }
    
@@@@@ -765,7 -765,7 -772,7 -761,7 +776,7 @@@@@ static void mt_set_maxcontacts(struct h
                max = min(fieldmax, max);
                if (r->field[0]->value[0] != max) {
                        r->field[0]->value[0] = max;
-- -                    usbhid_submit_report(hdev, r, USB_DIR_OUT);
++ +                    hid_hw_request(hdev, r, HID_REQ_SET_REPORT);
                }
        }
    }
@@@@@ -902,26 -902,26 -909,11 -898,26 +913,11 @@@@@ static int mt_reset_resume(struct hid_d
    
    static int mt_resume(struct hid_device *hdev)
    {
-- -    struct usb_interface *intf;
-- -    struct usb_host_interface *interface;
-- -    struct usb_device *dev;
-- -
-- -    if (hdev->bus != BUS_USB)
-- -            return 0;
-- -
-- -    intf = to_usb_interface(hdev->dev.parent);
-- -    interface = intf->cur_altsetting;
-- -    dev = hid_to_usb_dev(hdev);
-- -
        /* Some Elan legacy devices require SET_IDLE to be set on resume.
         * It should be safe to send it to other devices too.
         * Tested on 3M, Stantum, Cypress, Zytronic, eGalax, and Elan panels. */
    
-- -    usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
-- -                    HID_REQ_SET_IDLE,
-- -                    USB_TYPE_CLASS | USB_RECIP_INTERFACE,
-- -                    0, interface->desc.bInterfaceNumber,
-- -                    NULL, 0, USB_CTRL_SET_TIMEOUT);
++ +    hid_hw_idle(hdev, 0, 0, HID_REQ_SET_IDLE);
    
        return 0;
    }
diff --combined include/linux/hid.h
index e14b465b11463d353553027e602d79499d8be01d,06579c72d19544622b42d6adc4151ab7bae64823,863744c38ddc88c2c324c0021a9763b7bab43887,895b85639dec6a1f7d022df14024fe5ae56e6db1..31e7cb51b17d92787476603ff52f8520f2678784
@@@@@ -456,7 -456,7 -456,7 -456,8 +456,8 @@@@@ struct hid_device {                                                      /* device rep
        unsigned country;                                               /* HID country */
        struct hid_report_enum report_enum[HID_REPORT_TYPES];
    
---     struct semaphore driver_lock;                                   /* protects the current driver */
+++     struct semaphore driver_lock;                                   /* protects the current driver, except during input */
+++     struct semaphore driver_input_lock;                             /* protects the current driver */
        struct device dev;                                              /* device */
        struct hid_driver *driver;
        struct hid_ll_driver *ll_driver;
        unsigned int status;                                            /* see STAT flags above */
        unsigned claimed;                                               /* Claimed by hidinput, hiddev? */
        unsigned quirks;                                                /* Various quirks the device can pull on us */
+++     bool io_started;                                                /* Protected by driver_lock. If IO has started */
    
        struct list_head inputs;                                        /* The list of inputs */
        void *hiddev;                                                   /* The hiddev structure */
        struct dentry *debug_rdesc;
        struct dentry *debug_events;
        struct list_head debug_list;
+ ++    struct mutex debug_list_lock;
        wait_queue_head_t debug_wait;
    };
    
@@@@@ -599,6 -600,6 -599,6 -601,10 +602,10 @@@@@ struct hid_usage_id 
     * @resume: invoked on resume if device was not reset (NULL means nop)
     * @reset_resume: invoked on resume if device was reset (NULL means nop)
     *
+++  * probe should return -errno on error, or 0 on success. During probe,
+++  * input will not be passed to raw_event unless hid_device_io_start is
+++  * called.
+++  *
     * raw_event and event should return 0 on no action performed, 1 when no
     * further processing should be done and negative on error
     *
@@@@@ -662,6 -663,6 -662,9 -668,6 +669,9 @@@@@ struct hid_driver 
     * @hidinput_input_event: event input event (e.g. ff or leds)
     * @parse: this method is called only once to parse the device data,
     *     shouldn't allocate anything to not leak memory
++ + * @request: send report request to device (e.g. feature report)
++ + * @wait: wait for buffered io to complete (send/recv reports)
++ + * @idle: send idle request to device
     */
    struct hid_ll_driver {
        int (*start)(struct hid_device *hdev);
                        unsigned int code, int value);
    
        int (*parse)(struct hid_device *hdev);
++ +
++ +    void (*request)(struct hid_device *hdev,
++ +                    struct hid_report *report, int reqtype);
++ +
++ +    int (*wait)(struct hid_device *hdev);
++ +    int (*idle)(struct hid_device *hdev, int report, int idle, int reqtype);
++ +
    };
    
    #define     PM_HINT_FULLON  1<<5
@@@@@ -737,6 -738,6 -747,6 -743,44 +754,44 @@@@@ const struct hid_device_id *hid_match_i
                                         const struct hid_device_id *id);
    s32 hid_snto32(__u32 value, unsigned n);
    
+++ /**
+++  * hid_device_io_start - enable HID input during probe, remove
+++  *
+++  * @hid - the device
+++  *
+++  * This should only be called during probe or remove and only be
+++  * called by the thread calling probe or remove. It will allow
+++  * incoming packets to be delivered to the driver.
+++  */
+++ static inline void hid_device_io_start(struct hid_device *hid) {
+++     if (hid->io_started) {
+++             dev_warn(&hid->dev, "io already started");
+++             return;
+++     }
+++     hid->io_started = true;
+++     up(&hid->driver_input_lock);
+++ }
+++ 
+++ /**
+++  * hid_device_io_stop - disable HID input during probe, remove
+++  *
+++  * @hid - the device
+++  *
+++  * Should only be called after hid_device_io_start. It will prevent
+++  * incoming packets from going to the driver for the duration of
+++  * probe, remove. If called during probe, packets will still go to the
+++  * driver after probe is complete. This function should only be called
+++  * by the thread calling probe or remove.
+++  */
+++ static inline void hid_device_io_stop(struct hid_device *hid) {
+++     if (!hid->io_started) {
+++             dev_warn(&hid->dev, "io already stopped");
+++             return;
+++     }
+++     hid->io_started = false;
+++     down(&hid->driver_input_lock);
+++ }
+++ 
    /**
     * hid_map_usage - map usage input bits
     *
@@@@@ -883,6 -884,6 -893,49 -927,6 +938,49 @@@@@ static inline int hid_hw_power(struct h
        return hdev->ll_driver->power ? hdev->ll_driver->power(hdev, level) : 0;
    }
    
++ +
++ +/**
++ + * hid_hw_request - send report request to device
++ + *
++ + * @hdev: hid device
++ + * @report: report to send
++ + * @reqtype: hid request type
++ + */
++ +static inline void hid_hw_request(struct hid_device *hdev,
++ +                              struct hid_report *report, int reqtype)
++ +{
++ +    if (hdev->ll_driver->request)
++ +            hdev->ll_driver->request(hdev, report, reqtype);
++ +}
++ +
++ +/**
++ + * hid_hw_idle - send idle request to device
++ + *
++ + * @hdev: hid device
++ + * @report: report to control
++ + * @idle: idle state
++ + * @reqtype: hid request type
++ + */
++ +static inline int hid_hw_idle(struct hid_device *hdev, int report, int idle,
++ +            int reqtype)
++ +{
++ +    if (hdev->ll_driver->idle)
++ +            return hdev->ll_driver->idle(hdev, report, idle, reqtype);
++ +
++ +    return 0;
++ +}
++ +
++ +/**
++ + * hid_hw_wait - wait for buffered io to complete
++ + *
++ + * @hdev: hid device
++ + */
++ +static inline void hid_hw_wait(struct hid_device *hdev)
++ +{
++ +    if (hdev->ll_driver->wait)
++ +            hdev->ll_driver->wait(hdev);
++ +}
++ +
    int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, int size,
                int interrupt);