functions.c 2.3 KB

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