functions.c 2.2 KB

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