Merge branch 'upstream' into for-linus
[platform/adaptation/renesas_rcar/renesas_kernel.git] / drivers / hid / hid-core.c
index 9072e0e..2cd6880 100644 (file)
@@ -126,7 +126,7 @@ static int open_collection(struct hid_parser *parser, unsigned type)
 
        if (parser->collection_stack_ptr == HID_COLLECTION_STACK_SIZE) {
                hid_err(parser->device, "collection stack overflow\n");
-               return -1;
+               return -EINVAL;
        }
 
        if (parser->device->maxcollection == parser->device->collection_size) {
@@ -134,7 +134,7 @@ static int open_collection(struct hid_parser *parser, unsigned type)
                                parser->device->collection_size * 2, GFP_KERNEL);
                if (collection == NULL) {
                        hid_err(parser->device, "failed to reallocate collection array\n");
-                       return -1;
+                       return -ENOMEM;
                }
                memcpy(collection, parser->device->collection,
                        sizeof(struct hid_collection) *
@@ -170,7 +170,7 @@ static int close_collection(struct hid_parser *parser)
 {
        if (!parser->collection_stack_ptr) {
                hid_err(parser->device, "collection stack underflow\n");
-               return -1;
+               return -EINVAL;
        }
        parser->collection_stack_ptr--;
        return 0;
@@ -374,7 +374,7 @@ static int hid_parser_global(struct hid_parser *parser, struct hid_item *item)
 
        case HID_GLOBAL_ITEM_TAG_REPORT_SIZE:
                parser->global.report_size = item_udata(item);
-               if (parser->global.report_size > 96) {
+               if (parser->global.report_size > 128) {
                        hid_err(parser->device, "invalid report_size %d\n",
                                        parser->global.report_size);
                        return -1;
@@ -757,6 +757,7 @@ int hid_open_report(struct hid_device *device)
        struct hid_item item;
        unsigned int size;
        __u8 *start;
+       __u8 *buf;
        __u8 *end;
        int ret;
        static int (*dispatch_type[])(struct hid_parser *parser,
@@ -775,12 +776,21 @@ int hid_open_report(struct hid_device *device)
                return -ENODEV;
        size = device->dev_rsize;
 
+       buf = kmemdup(start, size, GFP_KERNEL);
+       if (buf == NULL)
+               return -ENOMEM;
+
        if (device->driver->report_fixup)
-               start = device->driver->report_fixup(device, start, &size);
+               start = device->driver->report_fixup(device, buf, &size);
+       else
+               start = buf;
 
-       device->rdesc = kmemdup(start, size, GFP_KERNEL);
-       if (device->rdesc == NULL)
+       start = kmemdup(start, size, GFP_KERNEL);
+       kfree(buf);
+       if (start == NULL)
                return -ENOMEM;
+
+       device->rdesc = start;
        device->rsize = size;
 
        parser = vzalloc(sizeof(struct hid_parser));
@@ -1448,7 +1458,14 @@ void hid_disconnect(struct hid_device *hdev)
 }
 EXPORT_SYMBOL_GPL(hid_disconnect);
 
-/* a list of devices for which there is a specialized driver on HID bus */
+/*
+ * A list of devices for which there is a specialized driver on HID bus.
+ *
+ * Please note that for multitouch devices (driven by hid-multitouch driver),
+ * there is a proper autodetection and autoloading in place (based on presence
+ * of HID_DG_CONTACTID), so those devices don't need to be added to this list,
+ * as we are doing the right thing in hid_scan_usage().
+ */
 static const struct hid_device_id hid_have_special_driver[] = {
        { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU) },
        { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_X5_005D) },
@@ -1628,6 +1645,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
        { HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_WKB2000) },
        { 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) },
+#if IS_ENABLED(CONFIG_HID_ROCCAT)
        { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONE) },
        { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_ARVO) },
        { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_ISKU) },
@@ -1636,6 +1654,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
        { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_PYRA_WIRED) },
        { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_PYRA_WIRELESS) },
        { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_SAVU) },
+#endif
        { HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_PS1000) },
        { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE) },
        { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE) },