0001
0002 #include <linux/kernel.h>
0003 #include <linux/slab.h>
0004 #include <linux/module.h>
0005 #include <linux/err.h>
0006
0007 #include <linux/usb/composite.h>
0008
0009 static LIST_HEAD(func_list);
0010 static DEFINE_MUTEX(func_lock);
0011
0012 static struct usb_function_instance *try_get_usb_function_instance(const char *name)
0013 {
0014 struct usb_function_driver *fd;
0015 struct usb_function_instance *fi;
0016
0017 fi = ERR_PTR(-ENOENT);
0018 mutex_lock(&func_lock);
0019 list_for_each_entry(fd, &func_list, list) {
0020
0021 if (strcmp(name, fd->name))
0022 continue;
0023
0024 if (!try_module_get(fd->mod)) {
0025 fi = ERR_PTR(-EBUSY);
0026 break;
0027 }
0028 fi = fd->alloc_inst();
0029 if (IS_ERR(fi))
0030 module_put(fd->mod);
0031 else
0032 fi->fd = fd;
0033 break;
0034 }
0035 mutex_unlock(&func_lock);
0036 return fi;
0037 }
0038
0039 struct usb_function_instance *usb_get_function_instance(const char *name)
0040 {
0041 struct usb_function_instance *fi;
0042 int ret;
0043
0044 fi = try_get_usb_function_instance(name);
0045 if (!IS_ERR(fi))
0046 return fi;
0047 ret = PTR_ERR(fi);
0048 if (ret != -ENOENT)
0049 return fi;
0050 ret = request_module("usbfunc:%s", name);
0051 if (ret < 0)
0052 return ERR_PTR(ret);
0053 return try_get_usb_function_instance(name);
0054 }
0055 EXPORT_SYMBOL_GPL(usb_get_function_instance);
0056
0057 struct usb_function *usb_get_function(struct usb_function_instance *fi)
0058 {
0059 struct usb_function *f;
0060
0061 f = fi->fd->alloc_func(fi);
0062 if (IS_ERR(f))
0063 return f;
0064 f->fi = fi;
0065 return f;
0066 }
0067 EXPORT_SYMBOL_GPL(usb_get_function);
0068
0069 void usb_put_function_instance(struct usb_function_instance *fi)
0070 {
0071 struct module *mod;
0072
0073 if (!fi)
0074 return;
0075
0076 mod = fi->fd->mod;
0077 fi->free_func_inst(fi);
0078 module_put(mod);
0079 }
0080 EXPORT_SYMBOL_GPL(usb_put_function_instance);
0081
0082 void usb_put_function(struct usb_function *f)
0083 {
0084 if (!f)
0085 return;
0086
0087 f->free_func(f);
0088 }
0089 EXPORT_SYMBOL_GPL(usb_put_function);
0090
0091 int usb_function_register(struct usb_function_driver *newf)
0092 {
0093 struct usb_function_driver *fd;
0094 int ret;
0095
0096 ret = -EEXIST;
0097
0098 mutex_lock(&func_lock);
0099 list_for_each_entry(fd, &func_list, list) {
0100 if (!strcmp(fd->name, newf->name))
0101 goto out;
0102 }
0103 ret = 0;
0104 list_add_tail(&newf->list, &func_list);
0105 out:
0106 mutex_unlock(&func_lock);
0107 return ret;
0108 }
0109 EXPORT_SYMBOL_GPL(usb_function_register);
0110
0111 void usb_function_unregister(struct usb_function_driver *fd)
0112 {
0113 mutex_lock(&func_lock);
0114 list_del(&fd->list);
0115 mutex_unlock(&func_lock);
0116 }
0117 EXPORT_SYMBOL_GPL(usb_function_unregister);