Linux-libre 5.4.49-gnu
[librecmc/linux-libre.git] / drivers / usb / gadget / function / u_ether_configfs.h
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * u_ether_configfs.h
4  *
5  * Utility definitions for configfs support in USB Ethernet functions
6  *
7  * Copyright (c) 2013 Samsung Electronics Co., Ltd.
8  *              http://www.samsung.com
9  *
10  * Author: Andrzej Pietrasiewicz <andrzejtp2010@gmail.com>
11  */
12
13 #ifndef __U_ETHER_CONFIGFS_H
14 #define __U_ETHER_CONFIGFS_H
15
16 #define USB_ETHERNET_CONFIGFS_ITEM(_f_)                                 \
17         static void _f_##_attr_release(struct config_item *item)        \
18         {                                                               \
19                 struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item);  \
20                                                                         \
21                 usb_put_function_instance(&opts->func_inst);            \
22         }                                                               \
23                                                                         \
24         static struct configfs_item_operations _f_##_item_ops = {       \
25                 .release        = _f_##_attr_release,                   \
26         }
27
28 #define USB_ETHERNET_CONFIGFS_ITEM_ATTR_DEV_ADDR(_f_)                   \
29         static ssize_t _f_##_opts_dev_addr_show(struct config_item *item, \
30                                                 char *page)             \
31         {                                                               \
32                 struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item);  \
33                 int result;                                             \
34                                                                         \
35                 mutex_lock(&opts->lock);                                \
36                 result = gether_get_dev_addr(opts->net, page, PAGE_SIZE); \
37                 mutex_unlock(&opts->lock);                              \
38                                                                         \
39                 return result;                                          \
40         }                                                               \
41                                                                         \
42         static ssize_t _f_##_opts_dev_addr_store(struct config_item *item, \
43                                                  const char *page, size_t len)\
44         {                                                               \
45                 struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item);  \
46                 int ret;                                                \
47                                                                         \
48                 mutex_lock(&opts->lock);                                \
49                 if (opts->refcnt) {                                     \
50                         mutex_unlock(&opts->lock);                      \
51                         return -EBUSY;                                  \
52                 }                                                       \
53                                                                         \
54                 ret = gether_set_dev_addr(opts->net, page);             \
55                 mutex_unlock(&opts->lock);                              \
56                 if (!ret)                                               \
57                         ret = len;                                      \
58                 return ret;                                             \
59         }                                                               \
60                                                                         \
61         CONFIGFS_ATTR(_f_##_opts_, dev_addr)
62
63 #define USB_ETHERNET_CONFIGFS_ITEM_ATTR_HOST_ADDR(_f_)                  \
64         static ssize_t _f_##_opts_host_addr_show(struct config_item *item, \
65                                                  char *page)            \
66         {                                                               \
67                 struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item);  \
68                 int result;                                             \
69                                                                         \
70                 mutex_lock(&opts->lock);                                \
71                 result = gether_get_host_addr(opts->net, page, PAGE_SIZE); \
72                 mutex_unlock(&opts->lock);                              \
73                                                                         \
74                 return result;                                          \
75         }                                                               \
76                                                                         \
77         static ssize_t _f_##_opts_host_addr_store(struct config_item *item, \
78                                                   const char *page, size_t len)\
79         {                                                               \
80                 struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item);  \
81                 int ret;                                                \
82                                                                         \
83                 mutex_lock(&opts->lock);                                \
84                 if (opts->refcnt) {                                     \
85                         mutex_unlock(&opts->lock);                      \
86                         return -EBUSY;                                  \
87                 }                                                       \
88                                                                         \
89                 ret = gether_set_host_addr(opts->net, page);            \
90                 mutex_unlock(&opts->lock);                              \
91                 if (!ret)                                               \
92                         ret = len;                                      \
93                 return ret;                                             \
94         }                                                               \
95                                                                         \
96         CONFIGFS_ATTR(_f_##_opts_, host_addr)
97
98 #define USB_ETHERNET_CONFIGFS_ITEM_ATTR_QMULT(_f_)                      \
99         static ssize_t _f_##_opts_qmult_show(struct config_item *item,  \
100                                              char *page)                \
101         {                                                               \
102                 struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item);  \
103                 unsigned qmult;                                         \
104                                                                         \
105                 mutex_lock(&opts->lock);                                \
106                 qmult = gether_get_qmult(opts->net);                    \
107                 mutex_unlock(&opts->lock);                              \
108                 return sprintf(page, "%d\n", qmult);                    \
109         }                                                               \
110                                                                         \
111         static ssize_t _f_##_opts_qmult_store(struct config_item *item, \
112                                               const char *page, size_t len)\
113         {                                                               \
114                 struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item);  \
115                 u8 val;                                                 \
116                 int ret;                                                \
117                                                                         \
118                 mutex_lock(&opts->lock);                                \
119                 if (opts->refcnt) {                                     \
120                         ret = -EBUSY;                                   \
121                         goto out;                                       \
122                 }                                                       \
123                                                                         \
124                 ret = kstrtou8(page, 0, &val);                          \
125                 if (ret)                                                \
126                         goto out;                                       \
127                                                                         \
128                 gether_set_qmult(opts->net, val);                       \
129                 ret = len;                                              \
130 out:                                                                    \
131                 mutex_unlock(&opts->lock);                              \
132                 return ret;                                             \
133         }                                                               \
134                                                                         \
135         CONFIGFS_ATTR(_f_##_opts_, qmult)
136
137 #define USB_ETHERNET_CONFIGFS_ITEM_ATTR_IFNAME(_f_)                     \
138         static ssize_t _f_##_opts_ifname_show(struct config_item *item, \
139                                               char *page)               \
140         {                                                               \
141                 struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item);  \
142                 int ret;                                                \
143                                                                         \
144                 mutex_lock(&opts->lock);                                \
145                 ret = gether_get_ifname(opts->net, page, PAGE_SIZE);    \
146                 mutex_unlock(&opts->lock);                              \
147                                                                         \
148                 return ret;                                             \
149         }                                                               \
150                                                                         \
151         CONFIGFS_ATTR_RO(_f_##_opts_, ifname)
152
153 #define USB_ETHER_CONFIGFS_ITEM_ATTR_U8_RW(_f_, _n_)                    \
154         static ssize_t _f_##_opts_##_n_##_show(struct config_item *item,\
155                                                char *page)              \
156         {                                                               \
157                 struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item);  \
158                 int ret;                                                \
159                                                                         \
160                 mutex_lock(&opts->lock);                                \
161                 ret = sprintf(page, "%02x\n", opts->_n_);               \
162                 mutex_unlock(&opts->lock);                              \
163                                                                         \
164                 return ret;                                             \
165         }                                                               \
166                                                                         \
167         static ssize_t _f_##_opts_##_n_##_store(struct config_item *item,\
168                                                 const char *page,       \
169                                                 size_t len)             \
170         {                                                               \
171                 struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item);  \
172                 int ret;                                                \
173                 u8 val;                                                 \
174                                                                         \
175                 mutex_lock(&opts->lock);                                \
176                 ret = sscanf(page, "%02hhx", &val);                     \
177                 if (ret > 0) {                                          \
178                         opts->_n_ = val;                                \
179                         ret = len;                                      \
180                 }                                                       \
181                 mutex_unlock(&opts->lock);                              \
182                                                                         \
183                 return ret;                                             \
184         }                                                               \
185                                                                         \
186         CONFIGFS_ATTR(_f_##_opts_, _n_)
187
188 #endif /* __U_ETHER_CONFIGFS_H */