gadget_configfs.h 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. #ifndef __GADGET_CONFIGFS__
  3. #define __GADGET_CONFIGFS__
  4. #include <linux/configfs.h>
  5. int check_user_usb_string(const char *name,
  6. struct usb_gadget_strings *stringtab_dev);
  7. #define GS_STRINGS_W(__struct, __name) \
  8. static ssize_t __struct##_##__name##_store(struct config_item *item, \
  9. const char *page, size_t len) \
  10. { \
  11. struct __struct *gs = to_##__struct(item); \
  12. int ret; \
  13. \
  14. ret = usb_string_copy(page, &gs->__name); \
  15. if (ret) \
  16. return ret; \
  17. return len; \
  18. }
  19. #define GS_STRINGS_R(__struct, __name) \
  20. static ssize_t __struct##_##__name##_show(struct config_item *item, char *page) \
  21. { \
  22. struct __struct *gs = to_##__struct(item); \
  23. return sprintf(page, "%s\n", gs->__name ?: ""); \
  24. }
  25. #define GS_STRINGS_RW(struct_name, _name) \
  26. GS_STRINGS_R(struct_name, _name) \
  27. GS_STRINGS_W(struct_name, _name) \
  28. CONFIGFS_ATTR(struct_name##_, _name)
  29. #define USB_CONFIG_STRING_RW_OPS(struct_in) \
  30. static struct configfs_item_operations struct_in##_langid_item_ops = { \
  31. .release = struct_in##_attr_release, \
  32. }; \
  33. \
  34. static struct config_item_type struct_in##_langid_type = { \
  35. .ct_item_ops = &struct_in##_langid_item_ops, \
  36. .ct_attrs = struct_in##_langid_attrs, \
  37. .ct_owner = THIS_MODULE, \
  38. }
  39. #define USB_CONFIG_STRINGS_LANG(struct_in, struct_member) \
  40. static struct config_group *struct_in##_strings_make( \
  41. struct config_group *group, \
  42. const char *name) \
  43. { \
  44. struct struct_member *gi; \
  45. struct struct_in *gs; \
  46. struct struct_in *new; \
  47. int langs = 0; \
  48. int ret; \
  49. \
  50. new = kzalloc(sizeof(*new), GFP_KERNEL); \
  51. if (!new) \
  52. return ERR_PTR(-ENOMEM); \
  53. \
  54. ret = check_user_usb_string(name, &new->stringtab_dev); \
  55. if (ret) \
  56. goto err; \
  57. config_group_init_type_name(&new->group, name, \
  58. &struct_in##_langid_type); \
  59. \
  60. gi = container_of(group, struct struct_member, strings_group); \
  61. ret = -EEXIST; \
  62. list_for_each_entry(gs, &gi->string_list, list) { \
  63. if (gs->stringtab_dev.language == new->stringtab_dev.language) \
  64. goto err; \
  65. langs++; \
  66. } \
  67. ret = -EOVERFLOW; \
  68. if (langs >= MAX_USB_STRING_LANGS) \
  69. goto err; \
  70. \
  71. list_add_tail(&new->list, &gi->string_list); \
  72. return &new->group; \
  73. err: \
  74. kfree(new); \
  75. return ERR_PTR(ret); \
  76. } \
  77. \
  78. static void struct_in##_strings_drop( \
  79. struct config_group *group, \
  80. struct config_item *item) \
  81. { \
  82. config_item_put(item); \
  83. } \
  84. \
  85. static struct configfs_group_operations struct_in##_strings_ops = { \
  86. .make_group = &struct_in##_strings_make, \
  87. .drop_item = &struct_in##_strings_drop, \
  88. }; \
  89. \
  90. static struct config_item_type struct_in##_strings_type = { \
  91. .ct_group_ops = &struct_in##_strings_ops, \
  92. .ct_owner = THIS_MODULE, \
  93. }
  94. #endif