usb: gadget: f_fs: Add support for CCID descriptors.

Nothing to remap, only check length.
Define a minimal structure for CCID descriptor only used to check length.
As this descriptor shares the same value as HID descriptors, keep track and
compare current interface's class to expected HID and CCID standard values.

Signed-off-by: Vincent Pelletier <plr.vincent@gmail.com>
Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
This commit is contained in:
Vincent Pelletier
2018-10-09 14:43:18 +00:00
committed by Felipe Balbi
parent 4ab9c39f03
commit 7f7c548c5f
2 changed files with 73 additions and 7 deletions

View File

@@ -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,
&current_class);
if (unlikely(ret < 0)) {
pr_debug("%s returns %d\n", __func__, ret);
return ret;