Andrzej Pietrasiewicz
2014-07-09 10:24:38 UTC
When gadgets are composed with configfs the user must know what are the
available function names. The names are parts of usb_f_*.ko
modules' aliases. If a function is compiled as a module, the information
can be found in modules.alias file. But if a function is compiled-in,
there is no way to know the function's name.
This patch adds a sysfs attribute in libcomposite's sys directory to
show functions which are already registered. Functions which are
compiled-in will be in this list as well.
Signed-off-by: Andrzej Pietrasiewicz <andrzej.p-***@public.gmane.org>
---
drivers/usb/gadget/configfs.c | 24 ++++++++++++++++++++++++
drivers/usb/gadget/functions.c | 19 +++++++++++++++++++
drivers/usb/gadget/u_f.h | 2 ++
3 files changed, 45 insertions(+)
diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c
index bcc2a62..352571b 100644
--- a/drivers/usb/gadget/configfs.c
+++ b/drivers/usb/gadget/configfs.c
@@ -1553,13 +1553,36 @@ void unregister_gadget_item(struct config_item *item)
}
EXPORT_SYMBOL_GPL(unregister_gadget_item);
+static ssize_t sysfs_func_list_show(struct module_attribute *ma,
+ struct module_kobject *ko, char *buf)
+{
+ return usb_function_list_functions(buf, PAGE_SIZE);
+}
+
+static struct module_attribute sysfs_func_list = {
+ .attr = {
+ .name = "func_list",
+ .mode = S_IRUGO,
+ },
+ .show = sysfs_func_list_show,
+};
+
static int __init gadget_cfs_init(void)
{
int ret;
config_group_init(&gadget_subsys.su_group);
+ ret = sysfs_create_file(&THIS_MODULE->mkobj.kobj,
+ &sysfs_func_list.attr);
+ if (ret)
+ return ret;
+
ret = configfs_register_subsystem(&gadget_subsys);
+ if (ret)
+ sysfs_remove_file(&THIS_MODULE->mkobj.kobj,
+ &sysfs_func_list.attr);
+
return ret;
}
module_init(gadget_cfs_init);
@@ -1567,5 +1590,6 @@ module_init(gadget_cfs_init);
static void __exit gadget_cfs_exit(void)
{
configfs_unregister_subsystem(&gadget_subsys);
+ sysfs_remove_file(&THIS_MODULE->mkobj.kobj, &sysfs_func_list.attr);
}
module_exit(gadget_cfs_exit);
diff --git a/drivers/usb/gadget/functions.c b/drivers/usb/gadget/functions.c
index b13f839..46b2f60 100644
--- a/drivers/usb/gadget/functions.c
+++ b/drivers/usb/gadget/functions.c
@@ -114,3 +114,22 @@ void usb_function_unregister(struct usb_function_driver *fd)
mutex_unlock(&func_lock);
}
EXPORT_SYMBOL_GPL(usb_function_unregister);
+
+size_t usb_function_list_functions(char *buf, size_t len)
+{
+ struct usb_function_driver *fd;
+ char *_buf = buf;
+
+ mutex_lock(&func_lock);
+ list_for_each_entry(fd, &func_list, list) {
+ sprintf(_buf, "%s\n", fd->name);
+ _buf += strlen(fd->name) + 1;
+ if (_buf - buf > len) {
+ mutex_unlock(&func_lock);
+ return -ENOMEM;
+ }
+ }
+ mutex_unlock(&func_lock);
+
+ return _buf - buf;
+}
diff --git a/drivers/usb/gadget/u_f.h b/drivers/usb/gadget/u_f.h
index 1d5f0eb..f1a8dff 100644
--- a/drivers/usb/gadget/u_f.h
+++ b/drivers/usb/gadget/u_f.h
@@ -47,6 +47,8 @@ struct usb_request;
struct usb_request *alloc_ep_req(struct usb_ep *ep, int len, int default_len);
+size_t usb_function_list_functions(char *buf, size_t len);
+
#endif /* __U_F_H__ */
available function names. The names are parts of usb_f_*.ko
modules' aliases. If a function is compiled as a module, the information
can be found in modules.alias file. But if a function is compiled-in,
there is no way to know the function's name.
This patch adds a sysfs attribute in libcomposite's sys directory to
show functions which are already registered. Functions which are
compiled-in will be in this list as well.
Signed-off-by: Andrzej Pietrasiewicz <andrzej.p-***@public.gmane.org>
---
drivers/usb/gadget/configfs.c | 24 ++++++++++++++++++++++++
drivers/usb/gadget/functions.c | 19 +++++++++++++++++++
drivers/usb/gadget/u_f.h | 2 ++
3 files changed, 45 insertions(+)
diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c
index bcc2a62..352571b 100644
--- a/drivers/usb/gadget/configfs.c
+++ b/drivers/usb/gadget/configfs.c
@@ -1553,13 +1553,36 @@ void unregister_gadget_item(struct config_item *item)
}
EXPORT_SYMBOL_GPL(unregister_gadget_item);
+static ssize_t sysfs_func_list_show(struct module_attribute *ma,
+ struct module_kobject *ko, char *buf)
+{
+ return usb_function_list_functions(buf, PAGE_SIZE);
+}
+
+static struct module_attribute sysfs_func_list = {
+ .attr = {
+ .name = "func_list",
+ .mode = S_IRUGO,
+ },
+ .show = sysfs_func_list_show,
+};
+
static int __init gadget_cfs_init(void)
{
int ret;
config_group_init(&gadget_subsys.su_group);
+ ret = sysfs_create_file(&THIS_MODULE->mkobj.kobj,
+ &sysfs_func_list.attr);
+ if (ret)
+ return ret;
+
ret = configfs_register_subsystem(&gadget_subsys);
+ if (ret)
+ sysfs_remove_file(&THIS_MODULE->mkobj.kobj,
+ &sysfs_func_list.attr);
+
return ret;
}
module_init(gadget_cfs_init);
@@ -1567,5 +1590,6 @@ module_init(gadget_cfs_init);
static void __exit gadget_cfs_exit(void)
{
configfs_unregister_subsystem(&gadget_subsys);
+ sysfs_remove_file(&THIS_MODULE->mkobj.kobj, &sysfs_func_list.attr);
}
module_exit(gadget_cfs_exit);
diff --git a/drivers/usb/gadget/functions.c b/drivers/usb/gadget/functions.c
index b13f839..46b2f60 100644
--- a/drivers/usb/gadget/functions.c
+++ b/drivers/usb/gadget/functions.c
@@ -114,3 +114,22 @@ void usb_function_unregister(struct usb_function_driver *fd)
mutex_unlock(&func_lock);
}
EXPORT_SYMBOL_GPL(usb_function_unregister);
+
+size_t usb_function_list_functions(char *buf, size_t len)
+{
+ struct usb_function_driver *fd;
+ char *_buf = buf;
+
+ mutex_lock(&func_lock);
+ list_for_each_entry(fd, &func_list, list) {
+ sprintf(_buf, "%s\n", fd->name);
+ _buf += strlen(fd->name) + 1;
+ if (_buf - buf > len) {
+ mutex_unlock(&func_lock);
+ return -ENOMEM;
+ }
+ }
+ mutex_unlock(&func_lock);
+
+ return _buf - buf;
+}
diff --git a/drivers/usb/gadget/u_f.h b/drivers/usb/gadget/u_f.h
index 1d5f0eb..f1a8dff 100644
--- a/drivers/usb/gadget/u_f.h
+++ b/drivers/usb/gadget/u_f.h
@@ -47,6 +47,8 @@ struct usb_request;
struct usb_request *alloc_ep_req(struct usb_ep *ep, int len, int default_len);
+size_t usb_function_list_functions(char *buf, size_t len);
+
#endif /* __U_F_H__ */
--
1.8.3.2
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo-***@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
1.8.3.2
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo-***@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html