Merge branch 'upstream' into for-linus
authorJiri Kosina <jkosina@suse.cz>
Tue, 25 Oct 2011 07:59:04 +0000 (09:59 +0200)
committerJiri Kosina <jkosina@suse.cz>
Tue, 25 Oct 2011 07:59:04 +0000 (09:59 +0200)
Conflicts:
drivers/hid/hid-core.c
drivers/hid/hid-ids.h

1  2 
drivers/hid/Kconfig
drivers/hid/Makefile
drivers/hid/hid-apple.c
drivers/hid/hid-core.c
drivers/hid/hid-ids.h
drivers/hid/hidraw.c
drivers/hid/usbhid/hid-quirks.c
include/linux/hid.h

diff --combined drivers/hid/Kconfig
@@@ -69,7 -69,7 +69,7 @@@ config HID_ACRU
        Say Y here if you want to enable support for ACRUX game controllers.
  
  config HID_ACRUX_FF
 -      tristate "ACRUX force feedback support"
 +      bool "ACRUX force feedback support"
        depends on HID_ACRUX
        select INPUT_FF_MEMLESS
        ---help---
@@@ -245,15 -245,6 +245,15 @@@ config HID_LOGITEC
        ---help---
        Support for Logitech devices that are not fully compliant with HID standard.
  
 +config HID_LOGITECH_DJ
 +      tristate "Logitech Unifying receivers full support"
 +      depends on HID_LOGITECH
 +      default m
 +      ---help---
 +      Say Y if you want support for Logitech Unifying receivers and devices.
 +      Unifying receivers are capable of pairing up to 6 Logitech compliant
 +      devices to the same receiver.
 +
  config LOGITECH_FF
        bool "Logitech force feedback support"
        depends on HID_LOGITECH
@@@ -287,21 -278,13 +287,21 @@@ config LOGIG940_F
          Say Y here if you want to enable force feedback support for Logitech
          Flight System G940 devices.
  
 -config LOGIWII_FF
 -      bool "Logitech Speed Force Wireless force feedback support"
 +config LOGIWHEELS_FF
 +      bool "Logitech wheels configuration and force feedback support"
        depends on HID_LOGITECH
        select INPUT_FF_MEMLESS
 +      default LOGITECH_FF
        help
 -        Say Y here if you want to enable force feedback support for Logitech
 -        Speed Force Wireless (Wii) devices.
 +        Say Y here if you want to enable force feedback and range setting
 +        support for following Logitech wheels:
 +        - Logitech Driving Force
 +        - Logitech Driving Force Pro
 +        - Logitech Driving Force GT
 +        - Logitech G25
 +        - Logitech G27
 +        - Logitech MOMO/MOMO 2
 +        - Logitech Formula Force EX
  
  config HID_MAGICMOUSE
        tristate "Apple MagicMouse multi-touch support"
@@@ -345,7 -328,6 +345,7 @@@ config HID_MULTITOUC
          - Hanvon dual touch panels
          - Ilitek dual touch panels
          - IrTouch Infrared USB panels
 +        - LG Display panels (Dell ST2220Tc)
          - Lumio CrystalTouch panels
          - MosArt dual-touch panels
          - PenMount dual touch panels
@@@ -459,6 -441,13 +459,13 @@@ config HID_PICOLCD_LED
        ---help---
          Provide access to PicoLCD's GPO pins via leds class.
  
+ config HID_PRIMAX
+       tristate "Primax non-fully HID-compliant devices"
+       depends on USB_HID
+       ---help---
+       Support for Primax devices that are not fully compliant with the
+       HID standard.
  config HID_QUANTA
        tristate "Quanta Optical Touch panels"
        depends on USB_HID
@@@ -557,7 -546,11 +564,11 @@@ config HID_SMARTJOYPLU
        tristate "SmartJoy PLUS PS2/USB adapter support"
        depends on USB_HID
        ---help---
-       Support for SmartJoy PLUS PS2/USB adapter.
+       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.
+       Note that DDR (Dance Dance Revolution) mode is not supported, nor
+       is pressure sensitive buttons on the pro models.
  
  config SMARTJOYPLUS_FF
        bool "SmartJoy PLUS PS2/USB adapter force feedback support"
@@@ -607,8 -600,6 +618,8 @@@ config HID_WACOM_POWER_SUPPL
  config HID_WIIMOTE
        tristate "Nintendo Wii Remote support"
        depends on BT_HIDP
 +      depends on LEDS_CLASS
 +      select POWER_SUPPLY
        ---help---
        Support for the Nintendo Wii Remote bluetooth device.
  
diff --combined drivers/hid/Makefile
@@@ -21,7 -21,7 +21,7 @@@ endi
  ifdef CONFIG_LOGIG940_FF
        hid-logitech-y  += hid-lg3ff.o
  endif
 -ifdef CONFIG_LOGIWII_FF
 +ifdef CONFIG_LOGIWHEELS_FF
        hid-logitech-y  += hid-lg4ff.o
  endif
  
@@@ -43,7 -43,6 +43,7 @@@ obj-$(CONFIG_HID_KEYTOUCH)    += hid-keyto
  obj-$(CONFIG_HID_KYE)         += hid-kye.o
  obj-$(CONFIG_HID_LCPOWER)       += hid-lcpower.o
  obj-$(CONFIG_HID_LOGITECH)    += hid-logitech.o
 +obj-$(CONFIG_HID_LOGITECH_DJ) += hid-logitech-dj.o
  obj-$(CONFIG_HID_MAGICMOUSE)    += hid-magicmouse.o
  obj-$(CONFIG_HID_MICROSOFT)   += hid-microsoft.o
  obj-$(CONFIG_HID_MONTEREY)    += hid-monterey.o
@@@ -55,6 -54,7 +55,7 @@@ obj-$(CONFIG_HID_QUANTA)      += hid-quanta.
  obj-$(CONFIG_HID_PANTHERLORD) += hid-pl.o
  obj-$(CONFIG_HID_PETALYNX)    += hid-petalynx.o
  obj-$(CONFIG_HID_PICOLCD)     += hid-picolcd.o
+ obj-$(CONFIG_HID_PRIMAX)      += hid-primax.o
  obj-$(CONFIG_HID_ROCCAT)      += hid-roccat.o
  obj-$(CONFIG_HID_ROCCAT_COMMON)       += hid-roccat-common.o
  obj-$(CONFIG_HID_ROCCAT_ARVO) += hid-roccat-arvo.o
diff --combined drivers/hid/hid-apple.c
@@@ -183,6 -183,9 +183,9 @@@ static int hidinput_apple_event(struct 
                if (hid->product >= USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI &&
                                hid->product <= USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS)
                        table = macbookair_fn_keys;
+               else if (hid->product >= USB_DEVICE_ID_APPLE_WELLSPRING6_ANSI &&
+                               hid->product <= USB_DEVICE_ID_APPLE_WELLSPRING6_JIS)
+                       table = macbookair_fn_keys;
                else if (hid->product < 0x21d || hid->product >= 0x300)
                        table = powerbook_fn_keys;
                else
@@@ -444,12 -447,6 +447,12 @@@ static const struct hid_device_id apple
        { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_JIS),
                .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN |
                        APPLE_RDESC_JIS },
 +      { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_REVB_ANSI),
 +              .driver_data = APPLE_HAS_FN },
 +      { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_REVB_ISO),
 +              .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD },
 +      { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_REVB_JIS),
 +              .driver_data = APPLE_HAS_FN },
        { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI),
                .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
        { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ISO),
                .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD },
        { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5_JIS),
                .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS },
+       { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6_ANSI),
+               .driver_data = APPLE_HAS_FN },
+       { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6_ISO),
+               .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD },
+       { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6_JIS),
+               .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS },
+       { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6A_ANSI),
+               .driver_data = APPLE_HAS_FN },
+       { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6A_ISO),
+               .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD },
+       { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6A_JIS),
+               .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS },
        { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI),
                .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
        { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO),
diff --combined drivers/hid/hid-core.c
@@@ -29,6 -29,7 +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>
@@@ -1085,16 -1086,25 +1086,25 @@@ int hid_input_report(struct hid_device 
        struct hid_report *report;
        char *buf;
        unsigned int i;
-       int ret;
+       int ret = 0;
  
-       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);
  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);
  
-       return 0;
+ unlock:
+       up(&hid->driver_lock);
+       return ret;
  }
  EXPORT_SYMBOL_GPL(hid_input_report);
  
@@@ -1212,12 -1228,6 +1228,12 @@@ int hid_connect(struct hid_device *hdev
        if ((connect_mask & HID_CONNECT_HIDINPUT) && !hidinput_connect(hdev,
                                connect_mask & HID_CONNECT_HIDINPUT_FORCE))
                hdev->claimed |= HID_CLAIMED_INPUT;
 +      if (hdev->quirks & HID_QUIRK_MULTITOUCH) {
 +              /* this device should be handled by hid-multitouch, skip it */
 +              hdev->quirks &= ~HID_QUIRK_MULTITOUCH;
 +              return -ENODEV;
 +      }
 +
        if ((connect_mask & HID_CONNECT_HIDDEV) && hdev->hiddev_connect &&
                        !hdev->hiddev_connect(hdev,
                                connect_mask & HID_CONNECT_HIDDEV_FORCE))
@@@ -1346,9 -1356,12 +1362,15 @@@ static const struct hid_device_id hid_h
        { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5_ANSI) },
        { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5_ISO) },
        { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5_JIS) },
 -      { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6A_ANSI) },
 -      { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6A_ISO) },
 -      { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6A_JIS) },
 +      { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_REVB_ANSI) },
 +      { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_REVB_ISO) },
 +      { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_REVB_JIS) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6_ANSI) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6_ISO) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6_JIS) },
++      { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6A_ANSI) },
++      { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6A_ISO) },
++      { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6A_JIS) },
        { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI) },
        { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO) },
        { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS) },
        { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_2) },
        { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_3) },
        { HID_USB_DEVICE(USB_VENDOR_ID_HANVON, USB_DEVICE_ID_HANVON_MULTITOUCH) },
 +      { HID_USB_DEVICE(USB_VENDOR_ID_IDEACOM, USB_DEVICE_ID_IDEACOM_IDC6650) },
        { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK, USB_DEVICE_ID_HOLTEK_ON_LINE_GRIP) },
        { HID_USB_DEVICE(USB_VENDOR_ID_ILITEK, USB_DEVICE_ID_ILITEK_MULTITOUCH) },
        { HID_USB_DEVICE(USB_VENDOR_ID_IRTOUCHSYSTEMS, USB_DEVICE_ID_IRTOUCH_INFRARED_USB) },
        { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_ERGO_525V) },
        { HID_USB_DEVICE(USB_VENDOR_ID_LABTEC, USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD) },
        { HID_USB_DEVICE(USB_VENDOR_ID_LCPOWER, USB_DEVICE_ID_LCPOWER_LC1000 ) },
 +      { HID_USB_DEVICE(USB_VENDOR_ID_LG, USB_DEVICE_ID_LG_MULTITOUCH) },
        { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER) },
        { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER) },
        { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER_2) },
        { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOMO_WHEEL) },
        { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2) },
        { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_DFP_WHEEL) },
 +      { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_DFGT_WHEEL) },
        { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G25_WHEEL) },
        { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G27_WHEEL) },
 +      { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_UNIFYING_RECEIVER) },
 +      { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_UNIFYING_RECEIVER_2) },
        { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WII_WHEEL) },
        { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2) },
        { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACETRAVELLER) },
        { HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_WKB2000) },
        { HID_USB_DEVICE(USB_VENDOR_ID_PENMOUNT, USB_DEVICE_ID_PENMOUNT_PCI) },
        { HID_USB_DEVICE(USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_KEYBOARD) },
        { HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH) },
        { HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_PIXART_IMAGING_INC_OPTICAL_TOUCH_SCREEN) },
        { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONE) },
        { HID_USB_DEVICE(USB_VENDOR_ID_UNITEC, USB_DEVICE_ID_UNITEC_USB_TOUCH_0709) },
        { HID_USB_DEVICE(USB_VENDOR_ID_UNITEC, USB_DEVICE_ID_UNITEC_USB_TOUCH_0A19) },
        { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_SMARTJOY_PLUS) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_DUAL_USB_JOYPAD) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP_LTD, USB_DEVICE_ID_SUPER_JOY_BOX_3_PRO) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP_LTD, USB_DEVICE_ID_SUPER_DUAL_BOX_PRO) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP_LTD, USB_DEVICE_ID_SUPER_JOY_BOX_5_PRO) },
        { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH) },
        { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_SLIM_TABLET_5_8_INCH) },
        { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_SLIM_TABLET_12_1_INCH) },
@@@ -1631,10 -1644,15 +1658,15 @@@ static int hid_device_probe(struct devi
        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)
-                       return -ENODEV;
+               if (id == NULL) {
+                       ret = -ENODEV;
+                       goto unlock;
+               }
  
                hdev->driver = hdrv;
                if (hdrv->probe) {
                if (ret)
                        hdev->driver = NULL;
        }
+ unlock:
+       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);
                hdev->driver = NULL;
        }
  
+       up(&hdev->driver_lock);
        return 0;
  }
  
@@@ -1903,6 -1928,12 +1942,12 @@@ static const struct hid_device_id hid_m
        { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5_ANSI) },
        { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5_ISO) },
        { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5_JIS) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6_ANSI) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6_ISO) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6_JIS) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6A_ANSI) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6A_ISO) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6A_JIS) },
        { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) },
        { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) },
        { }
@@@ -2010,6 -2041,7 +2055,7 @@@ struct hid_device *hid_allocate_device(
  
        init_waitqueue_head(&hdev->debug_wait);
        INIT_LIST_HEAD(&hdev->debug_list);
+       sema_init(&hdev->driver_lock, 1);
  
        return hdev;
  err:
diff --combined drivers/hid/hid-ids.h
  #define USB_DEVICE_ID_APPLE_WELLSPRING5_ANSI  0x0245
  #define USB_DEVICE_ID_APPLE_WELLSPRING5_ISO   0x0246
  #define USB_DEVICE_ID_APPLE_WELLSPRING5_JIS   0x0247
 +#define USB_DEVICE_ID_APPLE_ALU_REVB_ANSI     0x024f
 +#define USB_DEVICE_ID_APPLE_ALU_REVB_ISO      0x0250
 +#define USB_DEVICE_ID_APPLE_ALU_REVB_JIS      0x0251
+ #define USB_DEVICE_ID_APPLE_WELLSPRING6A_ANSI 0x0249
+ #define USB_DEVICE_ID_APPLE_WELLSPRING6A_ISO  0x024a
+ #define USB_DEVICE_ID_APPLE_WELLSPRING6A_JIS  0x024b
+ #define USB_DEVICE_ID_APPLE_WELLSPRING6_ANSI  0x024c
+ #define USB_DEVICE_ID_APPLE_WELLSPRING6_ISO   0x024d
+ #define USB_DEVICE_ID_APPLE_WELLSPRING6_JIS   0x024e
  #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI  0x0239
  #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO   0x023a
  #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS   0x023b
  #define USB_DEVICE_ID_PENPOWER                0x00f4
  
  #define USB_VENDOR_ID_GREENASIA               0x0e8f
 +#define USB_DEVICE_ID_GREENASIA_DUAL_USB_JOYPAD       0x3013
  
  #define USB_VENDOR_ID_GRETAGMACBETH   0x0971
  #define USB_DEVICE_ID_GRETAGMACBETH_HUEY      0x2005
  #define USB_DEVICE_ID_UGCI_FLYING     0x0020
  #define USB_DEVICE_ID_UGCI_FIGHTING   0x0030
  
 +#define USB_VENDOR_ID_IDEACOM         0x1cb6
 +#define USB_DEVICE_ID_IDEACOM_IDC6650 0x6650
 +
  #define USB_VENDOR_ID_ILITEK          0x222a
  #define USB_DEVICE_ID_ILITEK_MULTITOUCH       0x0001
  
  #define USB_DEVICE_ID_LD_HYBRID               0x2090
  #define USB_DEVICE_ID_LD_HEATCONTROL  0x20A0
  
 +#define USB_VENDOR_ID_LG              0x1fd2
 +#define USB_DEVICE_ID_LG_MULTITOUCH   0x0064
 +
  #define USB_VENDOR_ID_LOGITECH                0x046d
  #define USB_DEVICE_ID_LOGITECH_RECEIVER       0xc101
  #define USB_DEVICE_ID_LOGITECH_HARMONY_FIRST  0xc110
  #define USB_DEVICE_ID_LOGITECH_MOMO_WHEEL     0xc295
  #define USB_DEVICE_ID_LOGITECH_DFP_WHEEL      0xc298
  #define USB_DEVICE_ID_LOGITECH_G25_WHEEL      0xc299
 +#define USB_DEVICE_ID_LOGITECH_DFGT_WHEEL     0xc29a
  #define USB_DEVICE_ID_LOGITECH_G27_WHEEL      0xc29b
  #define USB_DEVICE_ID_LOGITECH_WII_WHEEL      0xc29c
  #define USB_DEVICE_ID_LOGITECH_ELITE_KBD      0xc30a
  #define USB_DEVICE_ID_S510_RECEIVER_2 0xc517
  #define USB_DEVICE_ID_LOGITECH_CORDLESS_DESKTOP_LX500 0xc512
  #define USB_DEVICE_ID_MX3000_RECEIVER 0xc513
 +#define USB_DEVICE_ID_LOGITECH_UNIFYING_RECEIVER      0xc52b
 +#define USB_DEVICE_ID_LOGITECH_UNIFYING_RECEIVER_2    0xc532
  #define USB_DEVICE_ID_SPACETRAVELLER  0xc623
  #define USB_DEVICE_ID_SPACENAVIGATOR  0xc626
  #define USB_DEVICE_ID_DINOVO_DESKTOP  0xc704
  #define USB_DEVICE_ID_SAMSUNG_IR_REMOTE       0x0001
  #define USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE      0x0600
  
 +#define USB_VENDOR_ID_SIGMA_MICRO     0x1c4f
 +#define USB_DEVICE_ID_SIGMA_MICRO_KEYBOARD    0x0002
 +
  #define USB_VENDOR_ID_SKYCABLE                        0x1223
  #define       USB_DEVICE_ID_SKYCABLE_WIRELESS_PRESENTER       0x3F07
  
  #define USB_VENDOR_ID_WISEGROUP_LTD   0x6666
  #define USB_VENDOR_ID_WISEGROUP_LTD2  0x6677
  #define USB_DEVICE_ID_SMARTJOY_DUAL_PLUS 0x8802
+ #define USB_DEVICE_ID_SUPER_JOY_BOX_3_PRO 0x8801
+ #define USB_DEVICE_ID_SUPER_DUAL_BOX_PRO 0x8802
+ #define USB_DEVICE_ID_SUPER_JOY_BOX_5_PRO 0x8804
  
  #define USB_VENDOR_ID_X_TENSIONS               0x1ae7
  #define USB_DEVICE_ID_SPEEDLINK_VAD_CEZANNE    0x9001
  #define USB_VENDOR_ID_ZYDACRON        0x13EC
  #define USB_DEVICE_ID_ZYDACRON_REMOTE_CONTROL 0x0006
  
+ #define USB_VENDOR_ID_PRIMAX  0x0461
+ #define USB_DEVICE_ID_PRIMAX_KEYBOARD 0x4e05
  #endif
diff --combined drivers/hid/hidraw.c
@@@ -259,7 -259,6 +259,6 @@@ static int hidraw_open(struct inode *in
  
        mutex_lock(&minors_lock);
        if (!hidraw_table[minor]) {
-               kfree(list);
                err = -ENODEV;
                goto out_unlock;
        }
        dev = hidraw_table[minor];
        if (!dev->open++) {
                err = hid_hw_power(dev->hid, PM_HINT_FULLON);
 -              if (err < 0)
 +              if (err < 0) {
 +                      dev->open--;
                        goto out_unlock;
 +              }
  
                err = hid_hw_open(dev->hid);
                if (err < 0) {
  out_unlock:
        mutex_unlock(&minors_lock);
  out:
+       if (err < 0)
+               kfree(list);
        return err;
  
  }
@@@ -512,12 -511,13 +513,12 @@@ void hidraw_disconnect(struct hid_devic
  {
        struct hidraw *hidraw = hid->hidraw;
  
 +      mutex_lock(&minors_lock);
        hidraw->exist = 0;
  
        device_destroy(hidraw_class, MKDEV(hidraw_major, hidraw->minor));
  
 -      mutex_lock(&minors_lock);
        hidraw_table[hidraw->minor] = NULL;
 -      mutex_unlock(&minors_lock);
  
        if (hidraw->open) {
                hid_hw_close(hid);
        } else {
                kfree(hidraw);
        }
 +      mutex_unlock(&minors_lock);
  }
  EXPORT_SYMBOL_GPL(hidraw_disconnect);
  
@@@ -47,7 -47,6 +47,7 @@@ static const struct hid_blacklist 
        { USB_VENDOR_ID_AFATECH, USB_DEVICE_ID_AFATECH_AF9016, HID_QUIRK_FULLSPEED_INTERVAL },
  
        { USB_VENDOR_ID_ETURBOTOUCH, USB_DEVICE_ID_ETURBOTOUCH, HID_QUIRK_MULTI_INPUT },
 +      { USB_VENDOR_ID_GREENASIA, USB_DEVICE_ID_GREENASIA_DUAL_USB_JOYPAD, HID_QUIRK_MULTI_INPUT },
        { USB_VENDOR_ID_PANTHERLORD, USB_DEVICE_ID_PANTHERLORD_TWIN_USB_JOYSTICK, HID_QUIRK_MULTI_INPUT | HID_QUIRK_SKIP_OUTPUT_REPORTS },
        { USB_VENDOR_ID_PLAYDOTCOM, USB_DEVICE_ID_PLAYDOTCOM_EMS_USBII, HID_QUIRK_MULTI_INPUT },
        { USB_VENDOR_ID_TOUCHPACK, USB_DEVICE_ID_TOUCHPACK_RTS, HID_QUIRK_MULTI_INPUT },
        { USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP8060U, HID_QUIRK_MULTI_INPUT },
        { USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_MEDIA_TABLET_10_6_INCH, HID_QUIRK_MULTI_INPUT },
        { USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_MEDIA_TABLET_14_1_INCH, HID_QUIRK_MULTI_INPUT },
-       { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_DUAL_USB_JOYPAD, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT | HID_QUIRK_SKIP_OUTPUT_REPORTS },
        { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_QUAD_USB_JOYPAD, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT },
  
-       { USB_VENDOR_ID_WISEGROUP_LTD, USB_DEVICE_ID_SMARTJOY_DUAL_PLUS, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT },
        { USB_VENDOR_ID_WISEGROUP_LTD2, USB_DEVICE_ID_SMARTJOY_DUAL_PLUS, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT },
  
        { USB_VENDOR_ID_PI_ENGINEERING, USB_DEVICE_ID_PI_ENGINEERING_VEC_USB_FOOTPEDAL, HID_QUIRK_HIDINPUT_FORCE },
  
        { USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_MULTI_TOUCH, HID_QUIRK_MULTI_INPUT },
        { USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS, HID_QUIRK_MULTI_INPUT },
 +      { USB_VENDOR_ID_SIGMA_MICRO, USB_DEVICE_ID_SIGMA_MICRO_KEYBOARD, HID_QUIRK_NO_INIT_REPORTS },
        { 0, 0 }
  };
  
diff --combined include/linux/hid.h
@@@ -71,6 -71,7 +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
@@@ -312,7 -313,6 +313,7 @@@ struct hid_item 
  #define HID_QUIRK_BADPAD                      0x00000020
  #define HID_QUIRK_MULTI_INPUT                 0x00000040
  #define HID_QUIRK_HIDINPUT_FORCE              0x00000080
 +#define HID_QUIRK_MULTITOUCH                  0x00000100
  #define HID_QUIRK_SKIP_OUTPUT_REPORTS         0x00010000
  #define HID_QUIRK_FULLSPEED_INTERVAL          0x10000000
  #define HID_QUIRK_NO_INIT_REPORTS             0x20000000
@@@ -476,6 -476,7 +477,7 @@@ 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 device dev;                                              /* device */
        struct hid_driver *driver;
        struct hid_ll_driver *ll_driver;