goto cleanup;
 
        input_device->report_desc_size = le16_to_cpu(
-                                       desc->desc[0].wDescriptorLength);
+                                       desc->rpt_desc.wDescriptorLength);
        if (input_device->report_desc_size == 0) {
                input_device->dev_info_status = -EINVAL;
                goto cleanup;
 
        memcpy(input_device->report_desc,
               ((unsigned char *)desc) + desc->bLength,
-              le16_to_cpu(desc->desc[0].wDescriptorLength));
+              le16_to_cpu(desc->rpt_desc.wDescriptorLength));
 
        /* Send the ack */
        memset(&ack, 0, sizeof(struct mousevsc_prt_msg));
 
        struct usb_host_interface *interface = intf->cur_altsetting;
        struct usb_device *dev = interface_to_usbdev (intf);
        struct hid_descriptor *hdesc;
+       struct hid_class_descriptor *hcdesc;
        u32 quirks = 0;
        unsigned int rsize = 0;
        char *rdesc;
-       int ret, n;
-       int num_descriptors;
-       size_t offset = offsetof(struct hid_descriptor, desc);
+       int ret;
 
        quirks = hid_lookup_quirk(hid);
 
                return -ENODEV;
        }
 
-       if (hdesc->bLength < sizeof(struct hid_descriptor)) {
-               dbg_hid("hid descriptor is too short\n");
+       if (!hdesc->bNumDescriptors ||
+           hdesc->bLength != sizeof(*hdesc) +
+                             (hdesc->bNumDescriptors - 1) * sizeof(*hcdesc)) {
+               dbg_hid("hid descriptor invalid, bLen=%hhu bNum=%hhu\n",
+                       hdesc->bLength, hdesc->bNumDescriptors);
                return -EINVAL;
        }
 
        hid->version = le16_to_cpu(hdesc->bcdHID);
        hid->country = hdesc->bCountryCode;
 
-       num_descriptors = min_t(int, hdesc->bNumDescriptors,
-              (hdesc->bLength - offset) / sizeof(struct hid_class_descriptor));
-
-       for (n = 0; n < num_descriptors; n++)
-               if (hdesc->desc[n].bDescriptorType == HID_DT_REPORT)
-                       rsize = le16_to_cpu(hdesc->desc[n].wDescriptorLength);
+       if (hdesc->rpt_desc.bDescriptorType == HID_DT_REPORT)
+               rsize = le16_to_cpu(hdesc->rpt_desc.wDescriptorLength);
 
        if (!rsize || rsize > HID_MAX_DESCRIPTOR_SIZE) {
                dbg_hid("weird size of report descriptor (%u)\n", rsize);
                goto err;
        }
 
+       if (hdesc->bNumDescriptors > 1)
+               hid_warn(intf,
+                       "%u unsupported optional hid class descriptors\n",
+                       (int)(hdesc->bNumDescriptors - 1));
+
        hid->quirks |= quirks;
 
        return 0;
 
        .bcdHID                         = cpu_to_le16(0x0101),
        .bCountryCode                   = 0x00,
        .bNumDescriptors                = 0x1,
-       /*.desc[0].bDescriptorType      = DYNAMIC */
-       /*.desc[0].wDescriptorLenght    = DYNAMIC */
+       /*.rpt_desc.bDescriptorType     = DYNAMIC */
+       /*.rpt_desc.wDescriptorLength   = DYNAMIC */
 };
 
 /* Super-Speed Support */
                        struct hid_descriptor hidg_desc_copy = hidg_desc;
 
                        VDBG(cdev, "USB_REQ_GET_DESCRIPTOR: HID\n");
-                       hidg_desc_copy.desc[0].bDescriptorType = HID_DT_REPORT;
-                       hidg_desc_copy.desc[0].wDescriptorLength =
+                       hidg_desc_copy.rpt_desc.bDescriptorType = HID_DT_REPORT;
+                       hidg_desc_copy.rpt_desc.wDescriptorLength =
                                cpu_to_le16(hidg->report_desc_length);
 
                        length = min_t(unsigned short, length,
         * We can use hidg_desc struct here but we should not relay
         * that its content won't change after returning from this function.
         */
-       hidg_desc.desc[0].bDescriptorType = HID_DT_REPORT;
-       hidg_desc.desc[0].wDescriptorLength =
+       hidg_desc.rpt_desc.bDescriptorType = HID_DT_REPORT;
+       hidg_desc.rpt_desc.wDescriptorLength =
                cpu_to_le16(hidg->report_desc_length);
 
        hidg_hs_in_ep_desc.bEndpointAddress =
 
        __le16 bcdHID;
        __u8  bCountryCode;
        __u8  bNumDescriptors;
+       struct hid_class_descriptor rpt_desc;
 
-       struct hid_class_descriptor desc[1];
+       struct hid_class_descriptor opt_descs[];
 } __attribute__ ((packed));
 
 #define HID_DEVICE(b, g, ven, prod)                                    \