Re: [PATCH v5 12/16] usb/gadget: FunctionFS: add devices management code

2013-12-03 Thread Michal Nazarewicz
On Tue, Dec 03 2013, Andrzej Pietrasiewicz wrote:
> 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 
> Signed-off-by: Kyunmgin Park 

Acked-by: Michal Nazarewicz 

> ---
>  drivers/usb/gadget/f_fs.c  |  238 ++-
>  drivers/usb/gadget/g_ffs.c |  175 ++---
>  drivers/usb/gadget/u_fs.h  |   24 
>  include/linux/usb/functionfs.h |   14 ---
>  4 files changed, 314 insertions(+), 137 deletions(-)

-- 
Best regards, _ _
.o. | Liege of Serenely Enlightened Majesty of  o' \,=./ `o
..o | Computer Science,  Michał “mina86” Nazarewicz(o o)
ooo +--ooO--(_)--Ooo--


signature.asc
Description: PGP signature


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

2013-12-03 Thread Andrzej Pietrasiewicz
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 
Signed-off-by: Kyunmgin Park 
---
 drivers/usb/gadget/f_fs.c  |  238 ++-
 drivers/usb/gadget/g_ffs.c |  175 ++---
 drivers/usb/gadget/u_fs.h  |   24 
 include/linux/usb/functionfs.h |   14 ---
 4 files changed, 314 insertions(+), 137 deletions(-)

diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c
index 9c946cd..8c45dc3 100644
--- a/drivers/usb/gadget/f_fs.c
+++ b/drivers/usb/gadget/f_fs.c
@@ -90,7 +90,7 @@ enum ffs_state {
 
/*
 * We've got descriptors and strings.  We are or have called
-* functionfs_ready_callback().  functionfs_bind() may have
+* ffs_ready().  functionfs_bind() may have
 * been called but we don't know.
 *
 * This is the only state in which operations on epfiles may
@@ -103,7 +103,7 @@ enum ffs_state {
 * we encounter an unrecoverable error.  The only
 * unrecoverable error is situation when after reading strings
 * from user space we fail to initialise epfiles or
-* functionfs_ready_callback() returns with error (<0).
+* ffs_ready() returns with error (<0).
 *
 * In this state no open(2), read(2) or write(2) (both on ep0
 * as well as epfile) may succeed (at this point epfiles are
@@ -361,6 +361,15 @@ ffs_sb_create_file(struct super_block *sb, const char 
*name, void *data,
   const struct file_operations *fops,
   struct dentry **dentry_p);
 
+/* Devices management ***/
+
+DEFINE_MUTEX(ffs_lock);
+
+static struct ffs_dev *ffs_find_dev(const char *name);
+static void *ffs_acquire_dev(const char *dev_name);
+static void ffs_release_dev(struct ffs_data *ffs_data);
+static int ffs_ready(struct ffs_data *ffs);
+static void ffs_closed(struct ffs_data *ffs);
 
 /* Misc helper functions /
 
@@ -486,7 +495,7 @@ static ssize_t ffs_ep0_write(struct file *file, const char 
__user *buf,
ffs->state = FFS_ACTIVE;
mutex_unlock(&ffs->mutex);
 
-   ret = functionfs_ready_callback(ffs);
+   ret = ffs_ready(ffs);
if (unlikely(ret < 0)) {
ffs->state = FFS_CLOSING;
return ret;
@@ -1217,7 +1226,7 @@ ffs_fs_mount(struct file_system_type *t, int flags,
return ERR_PTR(-ENOMEM);
}
 
-   ffs_dev = functionfs_acquire_dev_callback(dev_name);
+   ffs_dev = ffs_acquire_dev(dev_name);
if (IS_ERR(ffs_dev)) {
ffs_data_put(ffs);
return ERR_CAST(ffs_dev);
@@ -1227,7 +1236,7 @@ ffs_fs_mount(struct file_system_type *t, int flags,
 
rv = mount_nodev(t, flags, &data, ffs_sb_fill);
if (IS_ERR(rv) && data.ffs_data) {
-   functionfs_release_dev_callback(data.ffs_data);
+   ffs_release_dev(data.ffs_data);
ffs_data_put(data.ffs_data);
}
return rv;
@@ -1240,7 +1249,7 @@ ffs_fs_kill_sb(struct super_block *sb)
 
kill_litter_super(sb);
if (sb->s_fs_info) {
-   functionfs_release_dev_callback(sb->s_fs_info);
+   ffs_release_dev(sb->s_fs_info);
ffs_data_put(sb->s_fs_info);
}
 }
@@ -1353,7 +1362,7 @@ static void ffs_data_clear(struct ffs_data *ffs)
ENTER();
 
if (test_and_clear_bit(FFS_FL_CALL_CLOSED_CALLBACK, &ffs->flags))
-   functionfs_closed_callback(ffs);
+   ffs_closed(ffs);
 
BUG_ON(ffs->gadget);
 
@@ -2465,6 +2474,221 @@ static int ffs_func_revmap_intf(struct ffs_function 
*func, u8 intf)
 }
 
 
+/* Devices management ***/
+
+static LIST_HEAD(ffs_devices);
+
+static struct ffs_dev *_ffs_find_dev(const char *name)
+{
+   struct ffs_dev *dev;
+
+   list_for_each_entry(dev, &ffs_devices, entry) {
+   if (!dev->name || !name)
+   continue;
+   if (strcmp(dev->name, name) == 0)
+   return dev;
+   }
+   
+   return NULL;
+}
+
+/*
+ * ffs_lock must be taken by the caller of this function
+ */
+static struct ffs_dev *ffs_get_single_dev(void)
+{
+   struct ffs_dev *dev;
+
+   if (list_is_singular(&ffs_devices)) {
+   dev = list_first_entry(&ffs_devices, struct ffs_dev, entry);
+   if (dev->single)
+   return dev;
+   }
+
+   return NULL;
+}
+
+/*
+ * ffs_lock must be taken by the caller of this function
+ */
+static struct ffs_dev *ffs_find_dev(const char *name)
+{
+   struct ffs_dev *dev;
+
+   dev = ffs_get_single