]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/blame - drivers/infiniband/core/cma_configfs.c
Merge remote-tracking branch 'asoc/fix/rt5645' into asoc-linus
[mirror_ubuntu-zesty-kernel.git] / drivers / infiniband / core / cma_configfs.c
CommitLineData
045959db
MB
1/*
2 * Copyright (c) 2015, Mellanox Technologies inc. All rights reserved.
3 *
4 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU
6 * General Public License (GPL) Version 2, available from the file
7 * COPYING in the main directory of this source tree, or the
8 * OpenIB.org BSD license below:
9 *
10 * Redistribution and use in source and binary forms, with or
11 * without modification, are permitted provided that the following
12 * conditions are met:
13 *
14 * - Redistributions of source code must retain the above
15 * copyright notice, this list of conditions and the following
16 * disclaimer.
17 *
18 * - Redistributions in binary form must reproduce the above
19 * copyright notice, this list of conditions and the following
20 * disclaimer in the documentation and/or other materials
21 * provided with the distribution.
22 *
23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30 * SOFTWARE.
31 */
32
33#include <linux/module.h>
34#include <linux/configfs.h>
35#include <rdma/ib_verbs.h>
36#include "core_priv.h"
37
38struct cma_device;
39
40struct cma_dev_group;
41
42struct cma_dev_port_group {
43 unsigned int port_num;
44 struct cma_dev_group *cma_dev_group;
45 struct config_group group;
46};
47
48struct cma_dev_group {
49 char name[IB_DEVICE_NAME_MAX];
50 struct config_group device_group;
51 struct config_group ports_group;
52 struct config_group *default_dev_group[2];
53 struct config_group **default_ports_group;
54 struct cma_dev_port_group *ports;
55};
56
57static struct cma_dev_port_group *to_dev_port_group(struct config_item *item)
58{
59 struct config_group *group;
60
61 if (!item)
62 return NULL;
63
64 group = container_of(item, struct config_group, cg_item);
65 return container_of(group, struct cma_dev_port_group, group);
66}
67
68static bool filter_by_name(struct ib_device *ib_dev, void *cookie)
69{
70 return !strcmp(ib_dev->name, cookie);
71}
72
73static int cma_configfs_params_get(struct config_item *item,
74 struct cma_device **pcma_dev,
75 struct cma_dev_port_group **pgroup)
76{
77 struct cma_dev_port_group *group = to_dev_port_group(item);
78 struct cma_device *cma_dev;
79
80 if (!group)
81 return -ENODEV;
82
83 cma_dev = cma_enum_devices_by_ibdev(filter_by_name,
84 group->cma_dev_group->name);
85 if (!cma_dev)
86 return -ENODEV;
87
88 *pcma_dev = cma_dev;
89 *pgroup = group;
90
91 return 0;
92}
93
94static void cma_configfs_params_put(struct cma_device *cma_dev)
95{
96 cma_deref_dev(cma_dev);
97}
98
99static ssize_t default_roce_mode_show(struct config_item *item,
100 char *buf)
101{
102 struct cma_device *cma_dev;
103 struct cma_dev_port_group *group;
104 int gid_type;
105 ssize_t ret;
106
107 ret = cma_configfs_params_get(item, &cma_dev, &group);
108 if (ret)
109 return ret;
110
111 gid_type = cma_get_default_gid_type(cma_dev, group->port_num);
112 cma_configfs_params_put(cma_dev);
113
114 if (gid_type < 0)
115 return gid_type;
116
117 return sprintf(buf, "%s\n", ib_cache_gid_type_str(gid_type));
118}
119
120static ssize_t default_roce_mode_store(struct config_item *item,
121 const char *buf, size_t count)
122{
123 struct cma_device *cma_dev;
124 struct cma_dev_port_group *group;
125 int gid_type = ib_cache_gid_parse_type_str(buf);
126 ssize_t ret;
127
128 if (gid_type < 0)
129 return -EINVAL;
130
131 ret = cma_configfs_params_get(item, &cma_dev, &group);
132 if (ret)
133 return ret;
134
135 ret = cma_set_default_gid_type(cma_dev, group->port_num, gid_type);
136
137 cma_configfs_params_put(cma_dev);
138
139 return !ret ? strnlen(buf, count) : ret;
140}
141
142CONFIGFS_ATTR(, default_roce_mode);
143
144static struct configfs_attribute *cma_configfs_attributes[] = {
145 &attr_default_roce_mode,
146 NULL,
147};
148
149static struct config_item_type cma_port_group_type = {
150 .ct_attrs = cma_configfs_attributes,
151 .ct_owner = THIS_MODULE
152};
153
154static int make_cma_ports(struct cma_dev_group *cma_dev_group,
155 struct cma_device *cma_dev)
156{
157 struct ib_device *ibdev;
158 unsigned int i;
159 unsigned int ports_num;
160 struct cma_dev_port_group *ports;
a7d0e959 161 struct config_group **ports_group;
045959db
MB
162 int err;
163
164 ibdev = cma_get_ib_dev(cma_dev);
165
166 if (!ibdev)
167 return -ENODEV;
168
169 ports_num = ibdev->phys_port_cnt;
170 ports = kcalloc(ports_num, sizeof(*cma_dev_group->ports),
171 GFP_KERNEL);
a7d0e959 172 ports_group = kcalloc(ports_num + 1, sizeof(*ports_group), GFP_KERNEL);
045959db 173
a7d0e959 174 if (!ports || !ports_group) {
045959db
MB
175 err = -ENOMEM;
176 goto free;
177 }
178
179 for (i = 0; i < ports_num; i++) {
180 char port_str[10];
181
182 ports[i].port_num = i + 1;
183 snprintf(port_str, sizeof(port_str), "%u", i + 1);
184 ports[i].cma_dev_group = cma_dev_group;
185 config_group_init_type_name(&ports[i].group,
186 port_str,
187 &cma_port_group_type);
a7d0e959 188 ports_group[i] = &ports[i].group;
045959db 189 }
a7d0e959
DC
190 ports_group[i] = NULL;
191 cma_dev_group->default_ports_group = ports_group;
045959db
MB
192 cma_dev_group->ports = ports;
193
194 return 0;
195free:
196 kfree(ports);
a7d0e959 197 kfree(ports_group);
045959db
MB
198 cma_dev_group->ports = NULL;
199 cma_dev_group->default_ports_group = NULL;
200 return err;
201}
202
203static void release_cma_dev(struct config_item *item)
204{
205 struct config_group *group = container_of(item, struct config_group,
206 cg_item);
207 struct cma_dev_group *cma_dev_group = container_of(group,
208 struct cma_dev_group,
209 device_group);
210
211 kfree(cma_dev_group);
212};
213
214static void release_cma_ports_group(struct config_item *item)
215{
216 struct config_group *group = container_of(item, struct config_group,
217 cg_item);
218 struct cma_dev_group *cma_dev_group = container_of(group,
219 struct cma_dev_group,
220 ports_group);
221
222 kfree(cma_dev_group->ports);
223 kfree(cma_dev_group->default_ports_group);
224 cma_dev_group->ports = NULL;
225 cma_dev_group->default_ports_group = NULL;
226};
227
228static struct configfs_item_operations cma_ports_item_ops = {
229 .release = release_cma_ports_group
230};
231
232static struct config_item_type cma_ports_group_type = {
233 .ct_item_ops = &cma_ports_item_ops,
234 .ct_owner = THIS_MODULE
235};
236
237static struct configfs_item_operations cma_device_item_ops = {
238 .release = release_cma_dev
239};
240
241static struct config_item_type cma_device_group_type = {
242 .ct_item_ops = &cma_device_item_ops,
243 .ct_owner = THIS_MODULE
244};
245
246static struct config_group *make_cma_dev(struct config_group *group,
247 const char *name)
248{
249 int err = -ENODEV;
250 struct cma_device *cma_dev = cma_enum_devices_by_ibdev(filter_by_name,
251 (void *)name);
252 struct cma_dev_group *cma_dev_group = NULL;
253
254 if (!cma_dev)
255 goto fail;
256
257 cma_dev_group = kzalloc(sizeof(*cma_dev_group), GFP_KERNEL);
258
259 if (!cma_dev_group) {
260 err = -ENOMEM;
261 goto fail;
262 }
263
264 strncpy(cma_dev_group->name, name, sizeof(cma_dev_group->name));
265
266 err = make_cma_ports(cma_dev_group, cma_dev);
267 if (err)
268 goto fail;
269
270 cma_dev_group->ports_group.default_groups =
271 cma_dev_group->default_ports_group;
272 config_group_init_type_name(&cma_dev_group->ports_group, "ports",
273 &cma_ports_group_type);
274
275 cma_dev_group->device_group.default_groups
276 = cma_dev_group->default_dev_group;
277 cma_dev_group->default_dev_group[0] = &cma_dev_group->ports_group;
278 cma_dev_group->default_dev_group[1] = NULL;
279
280 config_group_init_type_name(&cma_dev_group->device_group, name,
281 &cma_device_group_type);
282
283 cma_deref_dev(cma_dev);
284 return &cma_dev_group->device_group;
285
286fail:
287 if (cma_dev)
288 cma_deref_dev(cma_dev);
289 kfree(cma_dev_group);
290 return ERR_PTR(err);
291}
292
293static struct configfs_group_operations cma_subsys_group_ops = {
294 .make_group = make_cma_dev,
295};
296
297static struct config_item_type cma_subsys_type = {
298 .ct_group_ops = &cma_subsys_group_ops,
299 .ct_owner = THIS_MODULE,
300};
301
302static struct configfs_subsystem cma_subsys = {
303 .su_group = {
304 .cg_item = {
305 .ci_namebuf = "rdma_cm",
306 .ci_type = &cma_subsys_type,
307 },
308 },
309};
310
311int __init cma_configfs_init(void)
312{
313 config_group_init(&cma_subsys.su_group);
314 mutex_init(&cma_subsys.su_mutex);
315 return configfs_register_subsystem(&cma_subsys);
316}
317
318void __exit cma_configfs_exit(void)
319{
320 configfs_unregister_subsystem(&cma_subsys);
321}