gadget_configfs.h 2.9 KB

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