blob: bcbd30146cfde6a3ff74b252621ee6b0b3e1c764 [file] [log] [blame]
Andrzej Pietrasiewiczaa83c6a2013-05-23 10:32:02 +02001/*
2 * u_ether_configfs.h
3 *
4 * Utility definitions for configfs support in USB Ethernet functions
5 *
6 * Copyright (c) 2013 Samsung Electronics Co., Ltd.
7 * http://www.samsung.com
8 *
9 * Author: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
14 */
15
16#ifndef __U_ETHER_CONFIGFS_H
17#define __U_ETHER_CONFIGFS_H
18
19#define USB_ETHERNET_CONFIGFS_ITEM(_f_) \
20 CONFIGFS_ATTR_STRUCT(f_##_f_##_opts); \
21 CONFIGFS_ATTR_OPS(f_##_f_##_opts); \
22 \
23 static void _f_##_attr_release(struct config_item *item) \
24 { \
25 struct f_##_f_##_opts *opts = to_f_##_f_##_opts(item); \
26 \
27 usb_put_function_instance(&opts->func_inst); \
28 } \
29 \
30 static struct configfs_item_operations _f_##_item_ops = { \
31 .release = _f_##_attr_release, \
32 .show_attribute = f_##_f_##_opts_attr_show, \
33 .store_attribute = f_##_f_##_opts_attr_store, \
34 }
35
36#define USB_ETHERNET_CONFIGFS_ITEM_ATTR_DEV_ADDR(_f_) \
37 static ssize_t _f_##_opts_dev_addr_show(struct f_##_f_##_opts *opts, \
38 char *page) \
39 { \
40 int result; \
41 \
42 mutex_lock(&opts->lock); \
43 result = gether_get_dev_addr(opts->net, page, PAGE_SIZE); \
44 mutex_unlock(&opts->lock); \
45 \
46 return result; \
47 } \
48 \
49 static ssize_t _f_##_opts_dev_addr_store(struct f_##_f_##_opts *opts, \
50 const char *page, size_t len)\
51 { \
52 int ret; \
53 \
54 mutex_lock(&opts->lock); \
55 if (opts->refcnt) { \
56 mutex_unlock(&opts->lock); \
57 return -EBUSY; \
58 } \
59 \
60 ret = gether_set_dev_addr(opts->net, page); \
61 mutex_unlock(&opts->lock); \
62 if (!ret) \
63 ret = len; \
64 return ret; \
65 } \
66 \
67 static struct f_##_f_##_opts_attribute f_##_f_##_opts_dev_addr = \
68 __CONFIGFS_ATTR(dev_addr, S_IRUGO | S_IWUSR, \
69 _f_##_opts_dev_addr_show, \
70 _f_##_opts_dev_addr_store)
71
72#define USB_ETHERNET_CONFIGFS_ITEM_ATTR_HOST_ADDR(_f_) \
73 static ssize_t _f_##_opts_host_addr_show(struct f_##_f_##_opts *opts, \
74 char *page) \
75 { \
76 int result; \
77 \
78 mutex_lock(&opts->lock); \
79 result = gether_get_host_addr(opts->net, page, PAGE_SIZE); \
80 mutex_unlock(&opts->lock); \
81 \
82 return result; \
83 } \
84 \
85 static ssize_t _f_##_opts_host_addr_store(struct f_##_f_##_opts *opts, \
86 const char *page, size_t len)\
87 { \
88 int ret; \
89 \
90 mutex_lock(&opts->lock); \
91 if (opts->refcnt) { \
92 mutex_unlock(&opts->lock); \
93 return -EBUSY; \
94 } \
95 \
96 ret = gether_set_host_addr(opts->net, page); \
97 mutex_unlock(&opts->lock); \
98 if (!ret) \
99 ret = len; \
100 return ret; \
101 } \
102 \
103 static struct f_##_f_##_opts_attribute f_##_f_##_opts_host_addr = \
104 __CONFIGFS_ATTR(host_addr, S_IRUGO | S_IWUSR, \
105 _f_##_opts_host_addr_show, \
106 _f_##_opts_host_addr_store)
107
108#define USB_ETHERNET_CONFIGFS_ITEM_ATTR_QMULT(_f_) \
109 static ssize_t _f_##_opts_qmult_show(struct f_##_f_##_opts *opts, \
110 char *page) \
111 { \
112 unsigned qmult; \
113 \
114 mutex_lock(&opts->lock); \
115 qmult = gether_get_qmult(opts->net); \
116 mutex_unlock(&opts->lock); \
117 return sprintf(page, "%d", qmult); \
118 } \
119 \
120 static ssize_t _f_##_opts_qmult_store(struct f_##_f_##_opts *opts, \
121 const char *page, size_t len)\
122 { \
123 u8 val; \
124 int ret; \
125 \
126 mutex_lock(&opts->lock); \
127 if (opts->refcnt) { \
128 ret = -EBUSY; \
129 goto out; \
130 } \
131 \
132 ret = kstrtou8(page, 0, &val); \
133 if (ret) \
134 goto out; \
135 \
136 gether_set_qmult(opts->net, val); \
137 ret = len; \
138out: \
139 mutex_unlock(&opts->lock); \
140 return ret; \
141 } \
142 \
143 static struct f_##_f_##_opts_attribute f_##_f_##_opts_qmult = \
144 __CONFIGFS_ATTR(qmult, S_IRUGO | S_IWUSR, \
145 _f_##_opts_qmult_show, \
146 _f_##_opts_qmult_store)
147
148#define USB_ETHERNET_CONFIGFS_ITEM_ATTR_IFNAME(_f_) \
149 static ssize_t _f_##_opts_ifname_show(struct f_##_f_##_opts *opts, \
150 char *page) \
151 { \
152 int ret; \
153 \
154 mutex_lock(&opts->lock); \
155 ret = gether_get_ifname(opts->net, page, PAGE_SIZE); \
156 mutex_unlock(&opts->lock); \
157 \
158 return ret; \
159 } \
160 \
161 static struct f_##_f_##_opts_attribute f_##_f_##_opts_ifname = \
162 __CONFIGFS_ATTR_RO(ifname, _f_##_opts_ifname_show)
163
164#endif /* __U_ETHER_CONFIGFS_H */