[PATCH 1/3] usb: gadget: configfs: Create control_config group

2018-07-03 Thread Jerry Zhang
Control_config is a group under gadget that acts
as a normal config group, except it does not
appear in cdev->configs.

Functions that have exactly zero descriptors can
be linked into control_config. These functions
are bound and unbound with the rest of the gadget,
but are never enabled. Also, functions with zero
descriptors cannot be used in real configs.

Create configfs_setup(), which will first attempt
composite setup. If that fails, it will go through
functions in control_config and use req_match to
find and deliver the request to a function that can
handle it.

This allows the user to create a functionfs instance
dedicated to handling non-standard control requests
no matter what functions or configurations are
currently active.

Signed-off-by: Jerry Zhang 
---
 drivers/usb/gadget/configfs.c | 114 --
 1 file changed, 96 insertions(+), 18 deletions(-)

diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c
index efba66ca0719..ed3d675ee7bb 100644
--- a/drivers/usb/gadget/configfs.c
+++ b/drivers/usb/gadget/configfs.c
@@ -44,12 +44,22 @@ int check_user_usb_string(const char *name,
 
 static const struct usb_descriptor_header *otg_desc[2];
 
+struct config_usb_cfg {
+   struct config_group group;
+   struct config_group strings_group;
+   struct list_head string_list;
+   struct usb_configuration c;
+   struct list_head func_list;
+   struct usb_gadget_strings *gstrings[MAX_USB_STRING_LANGS + 1];
+};
+
 struct gadget_info {
struct config_group group;
struct config_group functions_group;
struct config_group configs_group;
struct config_group strings_group;
struct config_group os_desc_group;
+   struct config_usb_cfg control_config;
 
struct mutex lock;
struct usb_gadget_strings *gstrings[MAX_USB_STRING_LANGS + 1];
@@ -68,15 +78,6 @@ static inline struct gadget_info *to_gadget_info(struct 
config_item *item)
 return container_of(to_config_group(item), struct gadget_info, group);
 }
 
-struct config_usb_cfg {
-   struct config_group group;
-   struct config_group strings_group;
-   struct list_head string_list;
-   struct usb_configuration c;
-   struct list_head func_list;
-   struct usb_gadget_strings *gstrings[MAX_USB_STRING_LANGS + 1];
-};
-
 static inline struct config_usb_cfg *to_config_usb_cfg(struct config_item 
*item)
 {
return container_of(to_config_group(item), struct config_usb_cfg,
@@ -512,6 +513,16 @@ static const struct config_item_type gadget_config_type = {
.ct_owner   = THIS_MODULE,
 };
 
+static struct configfs_item_operations control_config_item_ops = {
+   .allow_link = config_usb_cfg_link,
+   .drop_link  = config_usb_cfg_unlink,
+};
+
+static const struct config_item_type control_config_type = {
+   .ct_item_ops= &control_config_item_ops,
+   .ct_owner   = THIS_MODULE,
+};
+
 static const struct config_item_type gadget_root_type = {
.ct_item_ops= &gadget_root_item_ops,
.ct_attrs   = gadget_root_attrs,
@@ -1205,11 +1216,10 @@ int composite_os_desc_req_prepare(struct 
usb_composite_dev *cdev,
 static void purge_configs_funcs(struct gadget_info *gi)
 {
struct usb_configuration*c;
+   struct usb_function *f, *tmp;
+   struct config_usb_cfg *cfg;
 
list_for_each_entry(c, &gi->cdev.configs, list) {
-   struct usb_function *f, *tmp;
-   struct config_usb_cfg *cfg;
-
cfg = container_of(c, struct config_usb_cfg, c);
 
list_for_each_entry_safe(f, tmp, &c->functions, list) {
@@ -1229,6 +1239,14 @@ static void purge_configs_funcs(struct gadget_info *gi)
c->highspeed = 0;
c->fullspeed = 0;
}
+
+   cfg = &gi->control_config;
+   c = &cfg->c;
+   list_for_each_entry_safe(f, tmp, &c->functions, list) {
+   list_move_tail(&f->list, &cfg->func_list);
+   if (f->unbind)
+   f->unbind(c, f);
+   }
 }
 
 static int configfs_composite_bind(struct usb_gadget *gadget,
@@ -1242,6 +1260,9 @@ static int configfs_composite_bind(struct usb_gadget 
*gadget,
struct usb_string   *s;
unsignedi;
int ret;
+   struct config_usb_cfg *cfg;
+   struct usb_function *f;
+   struct usb_function *tmp;
 
/* the gi->lock is hold by the caller */
cdev->gadget = gadget;
@@ -1260,8 +1281,6 @@ static int configfs_composite_bind(struct usb_gadget 
*gadget,
 
 
list_for_each_entry(c, &gi->cdev.configs, list) {
-   struct config_usb_cfg *cfg;
-
cfg = container_of(c, struct config_usb_cfg, c);
if (list_empty(&cfg->func_list)) {
pr_err("Config %s/%d of %s needs at least one 
function.\n",
@@ -1320,9 +1339,6 @@

[PATCH 1/3] usb: gadget: configfs: Create control_config group

2018-07-02 Thread Jerry Zhang
Control_config is a group under gadget that acts
as a normal config group, except it does not
appear in cdev->configs.

Functions that have exactly zero descriptors can
be linked into control_config. These functions
are bound and unbound with the rest of the gadget,
but are never enabled. Also, functions with zero
descriptors cannot be used in real configs.

Create configfs_setup(), which will first attempt
composite setup. If that fails, it will go through
functions in control_config and use req_match to
find and deliver the request to a function that can
handle it.

This allows the user to create a functionfs instance
dedicated to handling non-standard control requests
no matter what functions or configurations are
currently active.

Signed-off-by: Jerry Zhang 
---
 drivers/usb/gadget/configfs.c | 114 --
 1 file changed, 96 insertions(+), 18 deletions(-)

diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c
index efba66ca0719..ed3d675ee7bb 100644
--- a/drivers/usb/gadget/configfs.c
+++ b/drivers/usb/gadget/configfs.c
@@ -44,12 +44,22 @@ int check_user_usb_string(const char *name,
 
 static const struct usb_descriptor_header *otg_desc[2];
 
+struct config_usb_cfg {
+   struct config_group group;
+   struct config_group strings_group;
+   struct list_head string_list;
+   struct usb_configuration c;
+   struct list_head func_list;
+   struct usb_gadget_strings *gstrings[MAX_USB_STRING_LANGS + 1];
+};
+
 struct gadget_info {
struct config_group group;
struct config_group functions_group;
struct config_group configs_group;
struct config_group strings_group;
struct config_group os_desc_group;
+   struct config_usb_cfg control_config;
 
struct mutex lock;
struct usb_gadget_strings *gstrings[MAX_USB_STRING_LANGS + 1];
@@ -68,15 +78,6 @@ static inline struct gadget_info *to_gadget_info(struct 
config_item *item)
 return container_of(to_config_group(item), struct gadget_info, group);
 }
 
-struct config_usb_cfg {
-   struct config_group group;
-   struct config_group strings_group;
-   struct list_head string_list;
-   struct usb_configuration c;
-   struct list_head func_list;
-   struct usb_gadget_strings *gstrings[MAX_USB_STRING_LANGS + 1];
-};
-
 static inline struct config_usb_cfg *to_config_usb_cfg(struct config_item 
*item)
 {
return container_of(to_config_group(item), struct config_usb_cfg,
@@ -512,6 +513,16 @@ static const struct config_item_type gadget_config_type = {
.ct_owner   = THIS_MODULE,
 };
 
+static struct configfs_item_operations control_config_item_ops = {
+   .allow_link = config_usb_cfg_link,
+   .drop_link  = config_usb_cfg_unlink,
+};
+
+static const struct config_item_type control_config_type = {
+   .ct_item_ops= &control_config_item_ops,
+   .ct_owner   = THIS_MODULE,
+};
+
 static const struct config_item_type gadget_root_type = {
.ct_item_ops= &gadget_root_item_ops,
.ct_attrs   = gadget_root_attrs,
@@ -1205,11 +1216,10 @@ int composite_os_desc_req_prepare(struct 
usb_composite_dev *cdev,
 static void purge_configs_funcs(struct gadget_info *gi)
 {
struct usb_configuration*c;
+   struct usb_function *f, *tmp;
+   struct config_usb_cfg *cfg;
 
list_for_each_entry(c, &gi->cdev.configs, list) {
-   struct usb_function *f, *tmp;
-   struct config_usb_cfg *cfg;
-
cfg = container_of(c, struct config_usb_cfg, c);
 
list_for_each_entry_safe(f, tmp, &c->functions, list) {
@@ -1229,6 +1239,14 @@ static void purge_configs_funcs(struct gadget_info *gi)
c->highspeed = 0;
c->fullspeed = 0;
}
+
+   cfg = &gi->control_config;
+   c = &cfg->c;
+   list_for_each_entry_safe(f, tmp, &c->functions, list) {
+   list_move_tail(&f->list, &cfg->func_list);
+   if (f->unbind)
+   f->unbind(c, f);
+   }
 }
 
 static int configfs_composite_bind(struct usb_gadget *gadget,
@@ -1242,6 +1260,9 @@ static int configfs_composite_bind(struct usb_gadget 
*gadget,
struct usb_string   *s;
unsignedi;
int ret;
+   struct config_usb_cfg *cfg;
+   struct usb_function *f;
+   struct usb_function *tmp;
 
/* the gi->lock is hold by the caller */
cdev->gadget = gadget;
@@ -1260,8 +1281,6 @@ static int configfs_composite_bind(struct usb_gadget 
*gadget,
 
 
list_for_each_entry(c, &gi->cdev.configs, list) {
-   struct config_usb_cfg *cfg;
-
cfg = container_of(c, struct config_usb_cfg, c);
if (list_empty(&cfg->func_list)) {
pr_err("Config %s/%d of %s needs at least one 
function.\n",
@@ -1320,9 +1339,6 @@