This will be required in order to use the new function interface (usb_get_function_instance/usb_put_function_instance) Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@xxxxxxxxxxx> Signed-off-by: Kyungmin Park <kyungmin.park@xxxxxxxxxxx> --- drivers/usb/gadget/f_fs.c | 41 ++++++++++++++++++++++++++++++++++++ drivers/usb/gadget/g_ffs.c | 50 ++++++++++++++++++++++++++----------------- drivers/usb/gadget/u_fs.h | 2 + 3 files changed, 73 insertions(+), 20 deletions(-) diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c index 277d193..bfbb580 100644 --- a/drivers/usb/gadget/f_fs.c +++ b/drivers/usb/gadget/f_fs.c @@ -361,6 +361,11 @@ ffs_sb_create_file(struct super_block *sb, const char *name, void *data, const struct file_operations *fops, struct dentry **dentry_p); +/* Devices management *******************************************************/ + +static struct ffs_dev *ffs_alloc_dev(void); +static void ffs_free_dev(struct ffs_dev *dev); +static struct ffs_dev *ffs_find_dev(const char *name); /* Misc helper functions ****************************************************/ @@ -2465,6 +2470,42 @@ static int ffs_func_revmap_intf(struct ffs_function *func, u8 intf) } +/* Devices management *******************************************************/ + +static LIST_HEAD(ffs_devices); + +static struct ffs_dev *ffs_alloc_dev(void) +{ + struct ffs_dev *dev; + + dev = kzalloc(sizeof(*dev), GFP_KERNEL); + if (!dev) + return ERR_PTR(-ENOMEM); + + list_add(&dev->entry, &ffs_devices); + + return dev; +} + +static void ffs_free_dev(struct ffs_dev *dev) +{ + list_del(&dev->entry); + + kfree(dev); +} + +static struct ffs_dev *ffs_find_dev(const char *name) +{ + struct ffs_dev *dev; + + list_for_each_entry(dev, &ffs_devices, entry) + if (strcmp(dev->name, name) == 0) + return dev; + + return NULL; +} + + /* Misc helper functions ****************************************************/ static int ffs_mutex_lock(struct mutex *mutex, unsigned nonblock) diff --git a/drivers/usb/gadget/g_ffs.c b/drivers/usb/gadget/g_ffs.c index 1aaa103..48b0940 100644 --- a/drivers/usb/gadget/g_ffs.c +++ b/drivers/usb/gadget/g_ffs.c @@ -174,35 +174,49 @@ static DEFINE_MUTEX(gfs_lock); static unsigned int missing_funcs; static bool gfs_registered; static bool gfs_single_func; -static struct ffs_dev *ffs_tab; +static struct ffs_dev **ffs_tab; static int __init gfs_init(void) { int i; + int ret = 0; ENTER(); - if (!func_num) { + if (func_num < 2) { gfs_single_func = true; func_num = 1; } - ffs_tab = kcalloc(func_num, sizeof *ffs_tab, GFP_KERNEL); + ffs_tab = kcalloc(func_num, sizeof(*ffs_tab), GFP_KERNEL); if (!ffs_tab) return -ENOMEM; - if (!gfs_single_func) - for (i = 0; i < func_num; i++) - ffs_tab[i].name = func_names[i]; + for (i = 0; i < func_num; i++) { + ffs_tab[i] = ffs_alloc_dev(); + if (IS_ERR(ffs_tab[i])) { + ret = PTR_ERR(ffs_tab[i]); + goto no_dev; + } + if (!gfs_single_func) + ffs_tab[i]->name = func_names[i]; + } missing_funcs = func_num; return functionfs_init(); +no_dev: + while (--i >= 0) + ffs_free_dev(ffs_tab[i]); + kfree(ffs_tab); + return ret; } module_init(gfs_init); static void __exit gfs_exit(void) { + int i; + ENTER(); mutex_lock(&gfs_lock); @@ -213,24 +227,20 @@ static void __exit gfs_exit(void) functionfs_cleanup(); mutex_unlock(&gfs_lock); + for (i = 0; i < func_num; i++) + ffs_free_dev(ffs_tab[i]); kfree(ffs_tab); } module_exit(gfs_exit); static struct ffs_dev *gfs_find_dev(const char *dev_name) { - int i; - ENTER(); if (gfs_single_func) - return &ffs_tab[0]; - - for (i = 0; i < func_num; i++) - if (strcmp(ffs_tab[i].name, dev_name) == 0) - return &ffs_tab[i]; + return ffs_tab[0]; - return NULL; + return ffs_find_dev(dev_name); } static int functionfs_ready_callback(struct ffs_data *ffs) @@ -422,10 +432,10 @@ static int gfs_bind(struct usb_composite_dev *cdev) gfs_dev_desc.iProduct = gfs_strings[USB_GADGET_PRODUCT_IDX].id; for (i = func_num; i--; ) { - ret = functionfs_bind(ffs_tab[i].ffs_data, cdev); + ret = functionfs_bind(ffs_tab[i]->ffs_data, cdev); if (unlikely(ret < 0)) { while (++i < func_num) - functionfs_unbind(ffs_tab[i].ffs_data); + functionfs_unbind(ffs_tab[i]->ffs_data); goto error_rndis; } } @@ -448,7 +458,7 @@ static int gfs_bind(struct usb_composite_dev *cdev) error_unbind: for (i = 0; i < func_num; i++) - functionfs_unbind(ffs_tab[i].ffs_data); + functionfs_unbind(ffs_tab[i]->ffs_data); error_rndis: #ifdef CONFIG_USB_FUNCTIONFS_RNDIS usb_put_function_instance(fi_rndis); @@ -497,8 +507,8 @@ static int gfs_unbind(struct usb_composite_dev *cdev) * do...? */ for (i = func_num; i--; ) - if (ffs_tab[i].ffs_data) - functionfs_unbind(ffs_tab[i].ffs_data); + if (ffs_tab[i]->ffs_data) + functionfs_unbind(ffs_tab[i]->ffs_data); return 0; } @@ -529,7 +539,7 @@ static int gfs_do_config(struct usb_configuration *c) } for (i = 0; i < func_num; i++) { - ret = functionfs_bind_config(c->cdev, c, ffs_tab[i].ffs_data); + ret = functionfs_bind_config(c->cdev, c, ffs_tab[i]->ffs_data); if (unlikely(ret < 0)) return ret; } diff --git a/drivers/usb/gadget/u_fs.h b/drivers/usb/gadget/u_fs.h index 5d9229a..12f6970 100644 --- a/drivers/usb/gadget/u_fs.h +++ b/drivers/usb/gadget/u_fs.h @@ -17,12 +17,14 @@ #define U_FFS_H #include <linux/usb/composite.h> +#include <linux/list.h> struct ffs_dev { const char *name; bool mounted; bool desc_ready; struct ffs_data *ffs_data; + struct list_head entry; }; #endif /* U_FFS_H */ -- 1.7.0.4 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html