This flag allows users to directly specify when
they want a ffs instance to be used for handling
control requests only via the configfs control_config/
group. When the flag is set, user must set *none*
of the speed descriptor flags and provide no
speeds in the descriptor. This ensures that it
cannot be mixed up with a normal function.

Signed-off-by: Jerry Zhang <zhangje...@google.com>
---
 drivers/usb/gadget/function/f_fs.c  | 22 +++++++++++-----------
 include/uapi/linux/usb/functionfs.h |  1 +
 2 files changed, 12 insertions(+), 11 deletions(-)

diff --git a/drivers/usb/gadget/function/f_fs.c 
b/drivers/usb/gadget/function/f_fs.c
index 4b2cb9d93176..4ef37ed70c5d 100644
--- a/drivers/usb/gadget/function/f_fs.c
+++ b/drivers/usb/gadget/function/f_fs.c
@@ -338,11 +338,6 @@ static ssize_t ffs_ep0_write(struct file *file, const char 
__user *buf,
        case FFS_READ_DESCRIPTORS:
        case FFS_READ_STRINGS:
                /* Copy data */
-               if (unlikely(len < 16)) {
-                       ret = -EINVAL;
-                       break;
-               }
-
                data = ffs_prepare_buffer(buf, len);
                if (IS_ERR(data)) {
                        ret = PTR_ERR(data);
@@ -2383,10 +2378,19 @@ static int __ffs_data_got_descs(struct ffs_data *ffs,
                              FUNCTIONFS_VIRTUAL_ADDR |
                              FUNCTIONFS_EVENTFD |
                              FUNCTIONFS_ALL_CTRL_RECIP |
-                             FUNCTIONFS_CONFIG0_SETUP)) {
+                             FUNCTIONFS_CONFIG0_SETUP |
+                             FUNCTIONFS_CONTROL_ONLY)) {
                        ret = -ENOSYS;
                        goto error;
                }
+               if ((bool) (flags & (FUNCTIONFS_HAS_FS_DESC |
+                             FUNCTIONFS_HAS_HS_DESC |
+                             FUNCTIONFS_HAS_SS_DESC)) ==
+                   (bool) (flags & FUNCTIONFS_CONTROL_ONLY)) {
+                       pr_err("Must have at least one speed descriptor "
+                                       "or CONTROL_ONLY (but not both)\n");
+                       goto error;
+               }
                data += 12;
                len  -= 12;
                break;
@@ -2466,7 +2470,7 @@ static int __ffs_data_got_descs(struct ffs_data *ffs,
                len -= ret;
        }
 
-       if (raw_descs == data || len) {
+       if (len) {
                ret = -EINVAL;
                goto error;
        }
@@ -3020,10 +3024,6 @@ static int _ffs_func_bind(struct usb_configuration *c,
 
        ENTER();
 
-       /* Has descriptors only for speeds gadget does not support */
-       if (unlikely(!(full | high | super)))
-               return -ENOTSUPP;
-
        /* Allocate a single chunk, less management later on */
        vlabuf = kzalloc(vla_group_size(d), GFP_KERNEL);
        if (unlikely(!vlabuf))
diff --git a/include/uapi/linux/usb/functionfs.h 
b/include/uapi/linux/usb/functionfs.h
index d77ee6b65328..25e55f485a6e 100644
--- a/include/uapi/linux/usb/functionfs.h
+++ b/include/uapi/linux/usb/functionfs.h
@@ -24,6 +24,7 @@ enum functionfs_flags {
        FUNCTIONFS_EVENTFD = 32,
        FUNCTIONFS_ALL_CTRL_RECIP = 64,
        FUNCTIONFS_CONFIG0_SETUP = 128,
+       FUNCTIONFS_CONTROL_ONLY = 256,
 };
 
 /* Descriptor of an non-audio endpoint */
-- 
2.17.0.484.g0c8726318c-goog

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to