Re: [PATCH v4 16/16] usb/gadget: FunctionFS: add configfs support

2013-12-02 Thread Michal Nazarewicz
On Mon, Dec 02 2013, Andrzej Pietrasiewicz wrote:
> Add support for using FunctionFS in configfs-based USB gadgets.
>
> Signed-off-by: Andrzej Pietrasiewicz 
> Signed-off-by: Kyungmin Park 

Acked-by: Michal Nazarewicz 

Sorry for the delay with this patchset.

> ---
>  Documentation/ABI/testing/configfs-usb-gadget-ffs |9 +++
>  drivers/usb/gadget/Kconfig|   12 +++
>  drivers/usb/gadget/f_fs.c |   77 
> +
>  drivers/usb/gadget/u_fs.h |5 ++
>  4 files changed, 103 insertions(+), 0 deletions(-)
>  create mode 100644 Documentation/ABI/testing/configfs-usb-gadget-ffs

-- 
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 v4 16/16] usb/gadget: FunctionFS: add configfs support

2013-12-02 Thread Andrzej Pietrasiewicz
Add support for using FunctionFS in configfs-based USB gadgets.

Signed-off-by: Andrzej Pietrasiewicz 
Signed-off-by: Kyungmin Park 
---
 Documentation/ABI/testing/configfs-usb-gadget-ffs |9 +++
 drivers/usb/gadget/Kconfig|   12 +++
 drivers/usb/gadget/f_fs.c |   77 +
 drivers/usb/gadget/u_fs.h |5 ++
 4 files changed, 103 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/ABI/testing/configfs-usb-gadget-ffs

diff --git a/Documentation/ABI/testing/configfs-usb-gadget-ffs 
b/Documentation/ABI/testing/configfs-usb-gadget-ffs
new file mode 100644
index 000..14343e2
--- /dev/null
+++ b/Documentation/ABI/testing/configfs-usb-gadget-ffs
@@ -0,0 +1,9 @@
+What:  /config/usb-gadget/gadget/functions/ffs.name
+Date:  Nov 2013
+KenelVersion:  3.13
+Description:   The purpose of this directory is to create and remove it.
+
+   A corresponding USB function instance is created/removed.
+   There are no attributes here.
+
+   All parameters are set through FunctionFS.
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
index 2479644..8da2b1d 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -689,6 +689,18 @@ config USB_CONFIGFS_MASS_STORAGE
  device (in much the same way as the "loop" device driver),
  specified as a module parameter or sysfs option.
 
+config USB_CONFIGFS_F_FS
+   boolean "Function filesystem (FunctionFS)"
+   depends on USB_CONFIGFS
+   select USB_F_FS
+   help
+ The Function Filesystem (FunctionFS) lets one create USB
+ composite functions in user space in the same way GadgetFS
+ lets one create USB gadgets in user space.  This allows creation
+ of composite gadgets such that some of the functions are
+ implemented in kernel space (for instance Ethernet, serial or
+ mass storage) and other are implemented in user space.
+
 config USB_ZERO
tristate "Gadget Zero (DEVELOPMENT)"
select USB_LIBCOMPOSITE
diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c
index e9eaa91..8a81e98 100644
--- a/drivers/usb/gadget/f_fs.c
+++ b/drivers/usb/gadget/f_fs.c
@@ -29,6 +29,7 @@
 #include 
 
 #include "u_fs.h"
+#include "configfs.h"
 
 #define FUNCTIONFS_MAGIC   0xa647361 /* Chosen by a honest dice roll ;) */
 
@@ -2294,6 +2295,31 @@ static struct ffs_dev *ffs_find_dev(const char *name)
return _ffs_find_dev(name);
 }
 
+/* Configfs support */
+
+static inline struct f_fs_opts *to_ffs_opts(struct config_item *item)
+{
+   return container_of(to_config_group(item), struct f_fs_opts,
+   func_inst.group);
+}
+
+static void ffs_attr_release(struct config_item *item)
+{
+   struct f_fs_opts *opts = to_ffs_opts(item);
+
+   usb_put_function_instance(&opts->func_inst);
+}
+
+static struct configfs_item_operations ffs_item_ops = {
+   .release= ffs_attr_release,
+};
+
+static struct config_item_type ffs_func_type = {
+   .ct_item_ops= &ffs_item_ops,
+   .ct_owner   = THIS_MODULE,
+};
+
+
 /* Function registration interface **/
 
 static void ffs_free_inst(struct usb_function_instance *f)
@@ -2307,6 +2333,44 @@ static void ffs_free_inst(struct usb_function_instance 
*f)
kfree(opts);
 }
 
+#define MAX_INST_NAME_LEN  40
+
+static int ffs_set_inst_name(struct usb_function_instance *fi, const char 
*name)
+{
+   struct f_fs_opts *opts;
+   char *ptr;
+   const char *tmp;
+   int name_len, ret;
+
+   name_len = strlen(name) + 1;
+   if (name_len > MAX_INST_NAME_LEN)
+   return -ENAMETOOLONG;
+
+   ptr = kstrndup(name, name_len, GFP_KERNEL);
+   if (!ptr)
+   return -ENOMEM;
+
+   opts = to_f_fs_opts(fi);
+   tmp = NULL;
+
+   ffs_dev_lock();
+
+   tmp = opts->dev->name_allocated ? opts->dev->name : NULL;
+   ret = ffs_name_dev(opts->dev, ptr);
+   if (ret) {
+   kfree(ptr);
+   ffs_dev_unlock();
+   return ret;
+   }
+   opts->dev->name_allocated = true;
+   
+   ffs_dev_unlock();
+
+   kfree(tmp);
+
+   return 0;
+}
+
 static struct usb_function_instance *ffs_alloc_inst(void)
 {
struct f_fs_opts *opts;
@@ -2316,6 +2380,7 @@ static struct usb_function_instance *ffs_alloc_inst(void)
if (!opts)
return ERR_PTR(-ENOMEM);
 
+   opts->func_inst.set_inst_name = ffs_set_inst_name;
opts->func_inst.free_func_inst = ffs_free_inst;
ffs_dev_lock();
dev = ffs_alloc_dev();
@@ -2325,7 +2390,10 @@ static struct usb_function_instance *ffs_alloc_inst(void)
return ERR_CAST(dev);
}
opts->dev = dev;
+   dev->opts = opts;
 
+