summaryrefslogtreecommitdiffstats
path: root/drivers/usb/gadget/configfs.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/gadget/configfs.c')
-rw-r--r--drivers/usb/gadget/configfs.c66
1 files changed, 30 insertions, 36 deletions
diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c
index 163d305e1200..b6f60ca8a035 100644
--- a/drivers/usb/gadget/configfs.c
+++ b/drivers/usb/gadget/configfs.c
@@ -49,14 +49,12 @@ struct gadget_info {
struct config_group configs_group;
struct config_group strings_group;
struct config_group os_desc_group;
- struct config_group *default_groups[5];
struct mutex lock;
struct usb_gadget_strings *gstrings[MAX_USB_STRING_LANGS + 1];
struct list_head string_list;
struct list_head available_func;
- const char *udc_name;
struct usb_composite_driver composite;
struct usb_composite_dev cdev;
bool use_os_desc;
@@ -72,7 +70,6 @@ static inline struct gadget_info *to_gadget_info(struct config_item *item)
struct config_usb_cfg {
struct config_group group;
struct config_group strings_group;
- struct config_group *default_groups[2];
struct list_head string_list;
struct usb_configuration c;
struct list_head func_list;
@@ -233,21 +230,23 @@ static ssize_t gadget_dev_desc_bcdUSB_store(struct config_item *item,
static ssize_t gadget_dev_desc_UDC_show(struct config_item *item, char *page)
{
- return sprintf(page, "%s\n", to_gadget_info(item)->udc_name ?: "");
+ char *udc_name = to_gadget_info(item)->composite.gadget_driver.udc_name;
+
+ return sprintf(page, "%s\n", udc_name ?: "");
}
static int unregister_gadget(struct gadget_info *gi)
{
int ret;
- if (!gi->udc_name)
+ if (!gi->composite.gadget_driver.udc_name)
return -ENODEV;
ret = usb_gadget_unregister_driver(&gi->composite.gadget_driver);
if (ret)
return ret;
- kfree(gi->udc_name);
- gi->udc_name = NULL;
+ kfree(gi->composite.gadget_driver.udc_name);
+ gi->composite.gadget_driver.udc_name = NULL;
return 0;
}
@@ -271,14 +270,16 @@ static ssize_t gadget_dev_desc_UDC_store(struct config_item *item,
if (ret)
goto err;
} else {
- if (gi->udc_name) {
+ if (gi->composite.gadget_driver.udc_name) {
ret = -EBUSY;
goto err;
}
- ret = usb_udc_attach_driver(name, &gi->composite.gadget_driver);
- if (ret)
+ gi->composite.gadget_driver.udc_name = name;
+ ret = usb_gadget_probe_driver(&gi->composite.gadget_driver);
+ if (ret) {
+ gi->composite.gadget_driver.udc_name = NULL;
goto err;
- gi->udc_name = name;
+ }
}
mutex_unlock(&gi->lock);
return len;
@@ -427,9 +428,9 @@ static int config_usb_cfg_unlink(
* remove the function.
*/
mutex_lock(&gi->lock);
- if (gi->udc_name)
+ if (gi->composite.gadget_driver.udc_name)
unregister_gadget(gi);
- WARN_ON(gi->udc_name);
+ WARN_ON(gi->composite.gadget_driver.udc_name);
list_for_each_entry(f, &cfg->func_list, list) {
if (f->fi == fi) {
@@ -663,13 +664,12 @@ static struct config_group *config_desc_make(
INIT_LIST_HEAD(&cfg->string_list);
INIT_LIST_HEAD(&cfg->func_list);
- cfg->group.default_groups = cfg->default_groups;
- cfg->default_groups[0] = &cfg->strings_group;
-
config_group_init_type_name(&cfg->group, name,
&gadget_config_type);
+
config_group_init_type_name(&cfg->strings_group, "strings",
&gadget_config_name_strings_type);
+ configfs_add_default_group(&cfg->strings_group, &cfg->group);
ret = usb_add_config_only(&gi->cdev, &cfg->c);
if (ret)
@@ -873,10 +873,10 @@ static int os_desc_unlink(struct config_item *os_desc_ci,
struct usb_composite_dev *cdev = &gi->cdev;
mutex_lock(&gi->lock);
- if (gi->udc_name)
+ if (gi->composite.gadget_driver.udc_name)
unregister_gadget(gi);
cdev->os_desc_config = NULL;
- WARN_ON(gi->udc_name);
+ WARN_ON(gi->composite.gadget_driver.udc_name);
mutex_unlock(&gi->lock);
return 0;
}
@@ -1146,15 +1146,11 @@ int usb_os_desc_prepare_interf_dir(struct config_group *parent,
char **names,
struct module *owner)
{
- struct config_group **f_default_groups, *os_desc_group,
- **interface_groups;
+ struct config_group *os_desc_group;
struct config_item_type *os_desc_type, *interface_type;
vla_group(data_chunk);
- vla_item(data_chunk, struct config_group *, f_default_groups, 2);
vla_item(data_chunk, struct config_group, os_desc_group, 1);
- vla_item(data_chunk, struct config_group *, interface_groups,
- n_interf + 1);
vla_item(data_chunk, struct config_item_type, os_desc_type, 1);
vla_item(data_chunk, struct config_item_type, interface_type, 1);
@@ -1162,18 +1158,14 @@ int usb_os_desc_prepare_interf_dir(struct config_group *parent,
if (!vlabuf)
return -ENOMEM;
- f_default_groups = vla_ptr(vlabuf, data_chunk, f_default_groups);
os_desc_group = vla_ptr(vlabuf, data_chunk, os_desc_group);
os_desc_type = vla_ptr(vlabuf, data_chunk, os_desc_type);
- interface_groups = vla_ptr(vlabuf, data_chunk, interface_groups);
interface_type = vla_ptr(vlabuf, data_chunk, interface_type);
- parent->default_groups = f_default_groups;
os_desc_type->ct_owner = owner;
config_group_init_type_name(os_desc_group, "os_desc", os_desc_type);
- f_default_groups[0] = os_desc_group;
+ configfs_add_default_group(os_desc_group, parent);
- os_desc_group->default_groups = interface_groups;
interface_type->ct_group_ops = &interf_grp_ops;
interface_type->ct_attrs = interf_grp_attrs;
interface_type->ct_owner = owner;
@@ -1186,7 +1178,7 @@ int usb_os_desc_prepare_interf_dir(struct config_group *parent,
config_group_init_type_name(&d->group, "", interface_type);
config_item_set_name(&d->group.cg_item, "interface.%s",
names[n_interf]);
- interface_groups[n_interf] = &d->group;
+ configfs_add_default_group(&d->group, os_desc_group);
}
return 0;
@@ -1226,6 +1218,7 @@ static void purge_configs_funcs(struct gadget_info *gi)
}
c->next_interface_id = 0;
memset(c->interface, 0, sizeof(c->interface));
+ c->superspeed_plus = 0;
c->superspeed = 0;
c->highspeed = 0;
c->fullspeed = 0;
@@ -1420,20 +1413,23 @@ static struct config_group *gadgets_make(
if (!gi)
return ERR_PTR(-ENOMEM);
- gi->group.default_groups = gi->default_groups;
- gi->group.default_groups[0] = &gi->functions_group;
- gi->group.default_groups[1] = &gi->configs_group;
- gi->group.default_groups[2] = &gi->strings_group;
- gi->group.default_groups[3] = &gi->os_desc_group;
+ config_group_init_type_name(&gi->group, name, &gadget_root_type);
config_group_init_type_name(&gi->functions_group, "functions",
&functions_type);
+ configfs_add_default_group(&gi->functions_group, &gi->group);
+
config_group_init_type_name(&gi->configs_group, "configs",
&config_desc_type);
+ configfs_add_default_group(&gi->configs_group, &gi->group);
+
config_group_init_type_name(&gi->strings_group, "strings",
&gadget_strings_strings_type);
+ configfs_add_default_group(&gi->strings_group, &gi->group);
+
config_group_init_type_name(&gi->os_desc_group, "os_desc",
&os_desc_type);
+ configfs_add_default_group(&gi->os_desc_group, &gi->group);
gi->composite.bind = configfs_do_nothing;
gi->composite.unbind = configfs_do_nothing;
@@ -1458,8 +1454,6 @@ static struct config_group *gadgets_make(
if (!gi->composite.gadget_driver.function)
goto err;
- config_group_init_type_name(&gi->group, name,
- &gadget_root_type);
return &gi->group;
err:
kfree(gi);
OpenPOWER on IntegriCloud