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