[PATCH RESEND v2 12/16] usb/gadget: FunctionFS: add devices management code

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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




[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux