summaryrefslogtreecommitdiff
path: root/drivers/usb/gadget/function/f_fs.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/gadget/function/f_fs.c')
-rw-r--r--drivers/usb/gadget/function/f_fs.c16
1 files changed, 11 insertions, 5 deletions
diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c
index e0ceaa721949..c626bb73ea59 100644
--- a/drivers/usb/gadget/function/f_fs.c
+++ b/drivers/usb/gadget/function/f_fs.c
@@ -33,6 +33,7 @@
#include <linux/usb/ccid.h>
#include <linux/usb/composite.h>
#include <linux/usb/functionfs.h>
+#include <linux/usb/func_utils.h>
#include <linux/aio.h>
#include <linux/kthread.h>
@@ -40,7 +41,6 @@
#include <linux/eventfd.h>
#include "u_fs.h"
-#include "u_f.h"
#include "u_os_desc.h"
#include "configfs.h"
@@ -722,7 +722,6 @@ static __poll_t ffs_ep0_poll(struct file *file, poll_table *wait)
}
static const struct file_operations ffs_ep0_operations = {
- .llseek = no_llseek,
.open = ffs_ep0_open,
.write = ffs_ep0_write,
@@ -1830,7 +1829,6 @@ static long ffs_epfile_ioctl(struct file *file, unsigned code,
}
static const struct file_operations ffs_epfile_operations = {
- .llseek = no_llseek,
.open = ffs_epfile_open,
.write_iter = ffs_epfile_write_iter,
@@ -2478,7 +2476,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, int *current_class)
+ void *priv, int *current_class, int *current_subclass)
{
struct usb_descriptor_header *_ds = (void *)data;
u8 length;
@@ -2535,6 +2533,7 @@ static int __must_check ffs_do_single_desc(char *data, unsigned len,
if (ds->iInterface)
__entity(STRING, ds->iInterface);
*current_class = ds->bInterfaceClass;
+ *current_subclass = ds->bInterfaceSubClass;
}
break;
@@ -2559,6 +2558,12 @@ static int __must_check ffs_do_single_desc(char *data, unsigned len,
if (length != sizeof(struct ccid_descriptor))
goto inv_length;
break;
+ } else if (*current_class == USB_CLASS_APP_SPEC &&
+ *current_subclass == USB_SUBCLASS_DFU) {
+ pr_vdebug("dfu functional descriptor\n");
+ if (length != sizeof(struct usb_dfu_functional_descriptor))
+ goto inv_length;
+ break;
} else {
pr_vdebug("unknown descriptor: %d for class %d\n",
_ds->bDescriptorType, *current_class);
@@ -2621,6 +2626,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;
+ int current_subclass = -1;
for (;;) {
int ret;
@@ -2640,7 +2646,7 @@ static int __must_check ffs_do_descs(unsigned count, char *data, unsigned len,
return _len - len;
ret = ffs_do_single_desc(data, len, entity, priv,
- &current_class);
+ &current_class, &current_subclass);
if (ret < 0) {
pr_debug("%s returns %d\n", __func__, ret);
return ret;