diff options
Diffstat (limited to 'drivers/usb/gadget/function/f_fs.c')
-rw-r--r-- | drivers/usb/gadget/function/f_fs.c | 29 |
1 files changed, 22 insertions, 7 deletions
diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c index 31e8bf3578c8..65b72e5c4605 100644 --- a/drivers/usb/gadget/function/f_fs.c +++ b/drivers/usb/gadget/function/f_fs.c @@ -23,6 +23,7 @@ #include <linux/uio.h> #include <asm/unaligned.h> +#include <linux/usb/ccid.h> #include <linux/usb/composite.h> #include <linux/usb/functionfs.h> @@ -1926,7 +1927,7 @@ typedef int (*ffs_os_desc_callback)(enum ffs_os_desc_type entity, static int __must_check ffs_do_single_desc(char *data, unsigned len, ffs_entity_callback entity, - void *priv) + void *priv, int *current_class) { struct usb_descriptor_header *_ds = (void *)data; u8 length; @@ -1984,6 +1985,7 @@ static int __must_check ffs_do_single_desc(char *data, unsigned len, __entity(INTERFACE, ds->bInterfaceNumber); if (ds->iInterface) __entity(STRING, ds->iInterface); + *current_class = ds->bInterfaceClass; } break; @@ -1997,11 +1999,22 @@ static int __must_check ffs_do_single_desc(char *data, unsigned len, } break; - case HID_DT_HID: - pr_vdebug("hid descriptor\n"); - if (length != sizeof(struct hid_descriptor)) - goto inv_length; - break; + case USB_TYPE_CLASS | 0x01: + if (*current_class == USB_INTERFACE_CLASS_HID) { + pr_vdebug("hid descriptor\n"); + if (length != sizeof(struct hid_descriptor)) + goto inv_length; + break; + } else if (*current_class == USB_INTERFACE_CLASS_CCID) { + pr_vdebug("ccid descriptor\n"); + if (length != sizeof(struct ccid_descriptor)) + goto inv_length; + break; + } else { + pr_vdebug("unknown descriptor: %d for class %d\n", + _ds->bDescriptorType, *current_class); + return -EINVAL; + } case USB_DT_OTG: if (length != sizeof(struct usb_otg_descriptor)) @@ -2058,6 +2071,7 @@ static int __must_check ffs_do_descs(unsigned count, char *data, unsigned len, { const unsigned _len = len; unsigned long num = 0; + int current_class = -1; ENTER(); @@ -2078,7 +2092,8 @@ static int __must_check ffs_do_descs(unsigned count, char *data, unsigned len, if (!data) return _len - len; - ret = ffs_do_single_desc(data, len, entity, priv); + ret = ffs_do_single_desc(data, len, entity, priv, + ¤t_class); if (unlikely(ret < 0)) { pr_debug("%s returns %d\n", __func__, ret); return ret; |