]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blob - include/linux/usb/gadget_configfs.h
Merge tag 'irqchip-fixes-4.10' of git://git.infradead.org/users/jcooper/linux into...
[mirror_ubuntu-artful-kernel.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