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