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