linux/drivers/usb/gadget/functions.c
<<
>>
Prefs
   1#include <linux/kernel.h>
   2#include <linux/slab.h>
   3#include <linux/module.h>
   4#include <linux/err.h>
   5
   6#include <linux/usb/composite.h>
   7
   8static LIST_HEAD(func_list);
   9static DEFINE_MUTEX(func_lock);
  10
  11static struct usb_function_instance *try_get_usb_function_instance(const char *name)
  12{
  13        struct usb_function_driver *fd;
  14        struct usb_function_instance *fi;
  15
  16        fi = ERR_PTR(-ENOENT);
  17        mutex_lock(&func_lock);
  18        list_for_each_entry(fd, &func_list, list) {
  19
  20                if (strcmp(name, fd->name))
  21                        continue;
  22
  23                if (!try_module_get(fd->mod)) {
  24                        fi = ERR_PTR(-EBUSY);
  25                        break;
  26                }
  27                fi = fd->alloc_inst();
  28                if (IS_ERR(fi))
  29                        module_put(fd->mod);
  30                else
  31                        fi->fd = fd;
  32                break;
  33        }
  34        mutex_unlock(&func_lock);
  35        return fi;
  36}
  37
  38struct usb_function_instance *usb_get_function_instance(const char *name)
  39{
  40        struct usb_function_instance *fi;
  41        int ret;
  42
  43        fi = try_get_usb_function_instance(name);
  44        if (!IS_ERR(fi))
  45                return fi;
  46        ret = PTR_ERR(fi);
  47        if (ret != -ENOENT)
  48                return fi;
  49        ret = request_module("usbfunc:%s", name);
  50        if (ret < 0)
  51                return ERR_PTR(ret);
  52        return try_get_usb_function_instance(name);
  53}
  54EXPORT_SYMBOL_GPL(usb_get_function_instance);
  55
  56struct usb_function *usb_get_function(struct usb_function_instance *fi)
  57{
  58        struct usb_function *f;
  59
  60        f = fi->fd->alloc_func(fi);
  61        if (IS_ERR(f))
  62                return f;
  63        f->fi = fi;
  64        return f;
  65}
  66EXPORT_SYMBOL_GPL(usb_get_function);
  67
  68void usb_put_function_instance(struct usb_function_instance *fi)
  69{
  70        struct module *mod;
  71
  72        if (!fi)
  73                return;
  74
  75        mod = fi->fd->mod;
  76        fi->free_func_inst(fi);
  77        module_put(mod);
  78}
  79EXPORT_SYMBOL_GPL(usb_put_function_instance);
  80
  81void usb_put_function(struct usb_function *f)
  82{
  83        if (!f)
  84                return;
  85
  86        f->free_func(f);
  87}
  88EXPORT_SYMBOL_GPL(usb_put_function);
  89
  90int usb_function_register(struct usb_function_driver *newf)
  91{
  92        struct usb_function_driver *fd;
  93        int ret;
  94
  95        ret = -EEXIST;
  96
  97        mutex_lock(&func_lock);
  98        list_for_each_entry(fd, &func_list, list) {
  99                if (!strcmp(fd->name, newf->name))
 100                        goto out;
 101        }
 102        ret = 0;
 103        list_add_tail(&newf->list, &func_list);
 104out:
 105        mutex_unlock(&func_lock);
 106        return ret;
 107}
 108EXPORT_SYMBOL_GPL(usb_function_register);
 109
 110void usb_function_unregister(struct usb_function_driver *fd)
 111{
 112        mutex_lock(&func_lock);
 113        list_del(&fd->list);
 114        mutex_unlock(&func_lock);
 115}
 116EXPORT_SYMBOL_GPL(usb_function_unregister);
 117