1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * configfs to configure the PCI endpoint
4 *
5 * Copyright (C) 2017 Texas Instruments
6 * Author: Kishon Vijay Abraham I <kishon@ti.com>
7 */
8
9 #include <linux/module.h>
10 #include <linux/idr.h>
11 #include <linux/slab.h>
12
13 #include <linux/pci-epc.h>
14 #include <linux/pci-epf.h>
15 #include <linux/pci-ep-cfs.h>
16
17 static DEFINE_IDR(functions_idr);
18 static DEFINE_MUTEX(functions_mutex);
19 static struct config_group *functions_group;
20 static struct config_group *controllers_group;
21
22 struct pci_epf_group {
23 struct config_group group;
24 struct config_group primary_epc_group;
25 struct config_group secondary_epc_group;
26 struct pci_epf *epf;
27 int index;
28 };
29
30 struct pci_epc_group {
31 struct config_group group;
32 struct pci_epc *epc;
33 bool start;
34 };
35
to_pci_epf_group(struct config_item * item)36 static inline struct pci_epf_group *to_pci_epf_group(struct config_item *item)
37 {
38 return container_of(to_config_group(item), struct pci_epf_group, group);
39 }
40
to_pci_epc_group(struct config_item * item)41 static inline struct pci_epc_group *to_pci_epc_group(struct config_item *item)
42 {
43 return container_of(to_config_group(item), struct pci_epc_group, group);
44 }
45
pci_secondary_epc_epf_link(struct config_item * epf_item,struct config_item * epc_item)46 static int pci_secondary_epc_epf_link(struct config_item *epf_item,
47 struct config_item *epc_item)
48 {
49 int ret;
50 struct pci_epf_group *epf_group = to_pci_epf_group(epf_item->ci_parent);
51 struct pci_epc_group *epc_group = to_pci_epc_group(epc_item);
52 struct pci_epc *epc = epc_group->epc;
53 struct pci_epf *epf = epf_group->epf;
54
55 ret = pci_epc_add_epf(epc, epf, SECONDARY_INTERFACE);
56 if (ret)
57 return ret;
58
59 ret = pci_epf_bind(epf);
60 if (ret) {
61 pci_epc_remove_epf(epc, epf, SECONDARY_INTERFACE);
62 return ret;
63 }
64
65 /* Send any pending EPC initialization complete to the EPF driver */
66 pci_epc_notify_pending_init(epc, epf);
67
68 return 0;
69 }
70
pci_secondary_epc_epf_unlink(struct config_item * epf_item,struct config_item * epc_item)71 static void pci_secondary_epc_epf_unlink(struct config_item *epf_item,
72 struct config_item *epc_item)
73 {
74 struct pci_epf_group *epf_group = to_pci_epf_group(epf_item->ci_parent);
75 struct pci_epc_group *epc_group = to_pci_epc_group(epc_item);
76 struct pci_epc *epc;
77 struct pci_epf *epf;
78
79 WARN_ON_ONCE(epc_group->start);
80
81 epc = epc_group->epc;
82 epf = epf_group->epf;
83 pci_epf_unbind(epf);
84 pci_epc_remove_epf(epc, epf, SECONDARY_INTERFACE);
85 }
86
87 static struct configfs_item_operations pci_secondary_epc_item_ops = {
88 .allow_link = pci_secondary_epc_epf_link,
89 .drop_link = pci_secondary_epc_epf_unlink,
90 };
91
92 static const struct config_item_type pci_secondary_epc_type = {
93 .ct_item_ops = &pci_secondary_epc_item_ops,
94 .ct_owner = THIS_MODULE,
95 };
96
97 static struct config_group
pci_ep_cfs_add_secondary_group(struct pci_epf_group * epf_group)98 *pci_ep_cfs_add_secondary_group(struct pci_epf_group *epf_group)
99 {
100 struct config_group *secondary_epc_group;
101
102 secondary_epc_group = &epf_group->secondary_epc_group;
103 config_group_init_type_name(secondary_epc_group, "secondary",
104 &pci_secondary_epc_type);
105 configfs_add_default_group(secondary_epc_group, &epf_group->group);
106
107 return secondary_epc_group;
108 }
109
pci_primary_epc_epf_link(struct config_item * epf_item,struct config_item * epc_item)110 static int pci_primary_epc_epf_link(struct config_item *epf_item,
111 struct config_item *epc_item)
112 {
113 int ret;
114 struct pci_epf_group *epf_group = to_pci_epf_group(epf_item->ci_parent);
115 struct pci_epc_group *epc_group = to_pci_epc_group(epc_item);
116 struct pci_epc *epc = epc_group->epc;
117 struct pci_epf *epf = epf_group->epf;
118
119 ret = pci_epc_add_epf(epc, epf, PRIMARY_INTERFACE);
120 if (ret)
121 return ret;
122
123 ret = pci_epf_bind(epf);
124 if (ret) {
125 pci_epc_remove_epf(epc, epf, PRIMARY_INTERFACE);
126 return ret;
127 }
128
129 /* Send any pending EPC initialization complete to the EPF driver */
130 pci_epc_notify_pending_init(epc, epf);
131
132 return 0;
133 }
134
pci_primary_epc_epf_unlink(struct config_item * epf_item,struct config_item * epc_item)135 static void pci_primary_epc_epf_unlink(struct config_item *epf_item,
136 struct config_item *epc_item)
137 {
138 struct pci_epf_group *epf_group = to_pci_epf_group(epf_item->ci_parent);
139 struct pci_epc_group *epc_group = to_pci_epc_group(epc_item);
140 struct pci_epc *epc;
141 struct pci_epf *epf;
142
143 WARN_ON_ONCE(epc_group->start);
144
145 epc = epc_group->epc;
146 epf = epf_group->epf;
147 pci_epf_unbind(epf);
148 pci_epc_remove_epf(epc, epf, PRIMARY_INTERFACE);
149 }
150
151 static struct configfs_item_operations pci_primary_epc_item_ops = {
152 .allow_link = pci_primary_epc_epf_link,
153 .drop_link = pci_primary_epc_epf_unlink,
154 };
155
156 static const struct config_item_type pci_primary_epc_type = {
157 .ct_item_ops = &pci_primary_epc_item_ops,
158 .ct_owner = THIS_MODULE,
159 };
160
161 static struct config_group
pci_ep_cfs_add_primary_group(struct pci_epf_group * epf_group)162 *pci_ep_cfs_add_primary_group(struct pci_epf_group *epf_group)
163 {
164 struct config_group *primary_epc_group = &epf_group->primary_epc_group;
165
166 config_group_init_type_name(primary_epc_group, "primary",
167 &pci_primary_epc_type);
168 configfs_add_default_group(primary_epc_group, &epf_group->group);
169
170 return primary_epc_group;
171 }
172
pci_epc_start_store(struct config_item * item,const char * page,size_t len)173 static ssize_t pci_epc_start_store(struct config_item *item, const char *page,
174 size_t len)
175 {
176 int ret;
177 bool start;
178 struct pci_epc *epc;
179 struct pci_epc_group *epc_group = to_pci_epc_group(item);
180
181 epc = epc_group->epc;
182
183 if (kstrtobool(page, &start) < 0)
184 return -EINVAL;
185
186 if (start == epc_group->start)
187 return -EALREADY;
188
189 if (!start) {
190 pci_epc_stop(epc);
191 epc_group->start = 0;
192 return len;
193 }
194
195 ret = pci_epc_start(epc);
196 if (ret) {
197 dev_err(&epc->dev, "failed to start endpoint controller\n");
198 return -EINVAL;
199 }
200
201 epc_group->start = start;
202
203 return len;
204 }
205
pci_epc_start_show(struct config_item * item,char * page)206 static ssize_t pci_epc_start_show(struct config_item *item, char *page)
207 {
208 return sysfs_emit(page, "%d\n", to_pci_epc_group(item)->start);
209 }
210
211 CONFIGFS_ATTR(pci_epc_, start);
212
213 static struct configfs_attribute *pci_epc_attrs[] = {
214 &pci_epc_attr_start,
215 NULL,
216 };
217
pci_epc_epf_link(struct config_item * epc_item,struct config_item * epf_item)218 static int pci_epc_epf_link(struct config_item *epc_item,
219 struct config_item *epf_item)
220 {
221 int ret;
222 struct pci_epf_group *epf_group = to_pci_epf_group(epf_item);
223 struct pci_epc_group *epc_group = to_pci_epc_group(epc_item);
224 struct pci_epc *epc = epc_group->epc;
225 struct pci_epf *epf = epf_group->epf;
226
227 ret = pci_epc_add_epf(epc, epf, PRIMARY_INTERFACE);
228 if (ret)
229 return ret;
230
231 ret = pci_epf_bind(epf);
232 if (ret) {
233 pci_epc_remove_epf(epc, epf, PRIMARY_INTERFACE);
234 return ret;
235 }
236
237 /* Send any pending EPC initialization complete to the EPF driver */
238 pci_epc_notify_pending_init(epc, epf);
239
240 return 0;
241 }
242
pci_epc_epf_unlink(struct config_item * epc_item,struct config_item * epf_item)243 static void pci_epc_epf_unlink(struct config_item *epc_item,
244 struct config_item *epf_item)
245 {
246 struct pci_epc *epc;
247 struct pci_epf *epf;
248 struct pci_epf_group *epf_group = to_pci_epf_group(epf_item);
249 struct pci_epc_group *epc_group = to_pci_epc_group(epc_item);
250
251 WARN_ON_ONCE(epc_group->start);
252
253 epc = epc_group->epc;
254 epf = epf_group->epf;
255 pci_epf_unbind(epf);
256 pci_epc_remove_epf(epc, epf, PRIMARY_INTERFACE);
257 }
258
259 static struct configfs_item_operations pci_epc_item_ops = {
260 .allow_link = pci_epc_epf_link,
261 .drop_link = pci_epc_epf_unlink,
262 };
263
264 static const struct config_item_type pci_epc_type = {
265 .ct_item_ops = &pci_epc_item_ops,
266 .ct_attrs = pci_epc_attrs,
267 .ct_owner = THIS_MODULE,
268 };
269
pci_ep_cfs_add_epc_group(const char * name)270 struct config_group *pci_ep_cfs_add_epc_group(const char *name)
271 {
272 int ret;
273 struct pci_epc *epc;
274 struct config_group *group;
275 struct pci_epc_group *epc_group;
276
277 epc_group = kzalloc_obj(*epc_group);
278 if (!epc_group) {
279 ret = -ENOMEM;
280 goto err;
281 }
282
283 group = &epc_group->group;
284
285 config_group_init_type_name(group, name, &pci_epc_type);
286 ret = configfs_register_group(controllers_group, group);
287 if (ret) {
288 pr_err("failed to register configfs group for %s\n", name);
289 goto err_register_group;
290 }
291
292 epc = pci_epc_get(name);
293 if (IS_ERR(epc)) {
294 ret = PTR_ERR(epc);
295 goto err_epc_get;
296 }
297
298 epc_group->epc = epc;
299
300 return group;
301
302 err_epc_get:
303 configfs_unregister_group(group);
304
305 err_register_group:
306 kfree(epc_group);
307
308 err:
309 return ERR_PTR(ret);
310 }
311 EXPORT_SYMBOL(pci_ep_cfs_add_epc_group);
312
pci_ep_cfs_remove_epc_group(struct config_group * group)313 void pci_ep_cfs_remove_epc_group(struct config_group *group)
314 {
315 struct pci_epc_group *epc_group;
316
317 if (!group)
318 return;
319
320 epc_group = container_of(group, struct pci_epc_group, group);
321 pci_epc_put(epc_group->epc);
322 configfs_unregister_group(&epc_group->group);
323 kfree(epc_group);
324 }
325 EXPORT_SYMBOL(pci_ep_cfs_remove_epc_group);
326
327 #define PCI_EPF_HEADER_R(_name) \
328 static ssize_t pci_epf_##_name##_show(struct config_item *item, char *page) \
329 { \
330 struct pci_epf *epf = to_pci_epf_group(item)->epf; \
331 if (WARN_ON_ONCE(!epf->header)) \
332 return -EINVAL; \
333 return sysfs_emit(page, "0x%04x\n", epf->header->_name); \
334 }
335
336 #define PCI_EPF_HEADER_W_u32(_name) \
337 static ssize_t pci_epf_##_name##_store(struct config_item *item, \
338 const char *page, size_t len) \
339 { \
340 u32 val; \
341 struct pci_epf *epf = to_pci_epf_group(item)->epf; \
342 if (WARN_ON_ONCE(!epf->header)) \
343 return -EINVAL; \
344 if (kstrtou32(page, 0, &val) < 0) \
345 return -EINVAL; \
346 epf->header->_name = val; \
347 return len; \
348 }
349
350 #define PCI_EPF_HEADER_W_u16(_name) \
351 static ssize_t pci_epf_##_name##_store(struct config_item *item, \
352 const char *page, size_t len) \
353 { \
354 u16 val; \
355 struct pci_epf *epf = to_pci_epf_group(item)->epf; \
356 if (WARN_ON_ONCE(!epf->header)) \
357 return -EINVAL; \
358 if (kstrtou16(page, 0, &val) < 0) \
359 return -EINVAL; \
360 epf->header->_name = val; \
361 return len; \
362 }
363
364 #define PCI_EPF_HEADER_W_u8(_name) \
365 static ssize_t pci_epf_##_name##_store(struct config_item *item, \
366 const char *page, size_t len) \
367 { \
368 u8 val; \
369 struct pci_epf *epf = to_pci_epf_group(item)->epf; \
370 if (WARN_ON_ONCE(!epf->header)) \
371 return -EINVAL; \
372 if (kstrtou8(page, 0, &val) < 0) \
373 return -EINVAL; \
374 epf->header->_name = val; \
375 return len; \
376 }
377
pci_epf_msi_interrupts_store(struct config_item * item,const char * page,size_t len)378 static ssize_t pci_epf_msi_interrupts_store(struct config_item *item,
379 const char *page, size_t len)
380 {
381 u8 val;
382
383 if (kstrtou8(page, 0, &val) < 0)
384 return -EINVAL;
385
386 to_pci_epf_group(item)->epf->msi_interrupts = val;
387
388 return len;
389 }
390
pci_epf_msi_interrupts_show(struct config_item * item,char * page)391 static ssize_t pci_epf_msi_interrupts_show(struct config_item *item,
392 char *page)
393 {
394 return sysfs_emit(page, "%d\n",
395 to_pci_epf_group(item)->epf->msi_interrupts);
396 }
397
pci_epf_msix_interrupts_store(struct config_item * item,const char * page,size_t len)398 static ssize_t pci_epf_msix_interrupts_store(struct config_item *item,
399 const char *page, size_t len)
400 {
401 u16 val;
402
403 if (kstrtou16(page, 0, &val) < 0)
404 return -EINVAL;
405
406 to_pci_epf_group(item)->epf->msix_interrupts = val;
407
408 return len;
409 }
410
pci_epf_msix_interrupts_show(struct config_item * item,char * page)411 static ssize_t pci_epf_msix_interrupts_show(struct config_item *item,
412 char *page)
413 {
414 return sysfs_emit(page, "%d\n",
415 to_pci_epf_group(item)->epf->msix_interrupts);
416 }
417
418 PCI_EPF_HEADER_R(vendorid)
419 PCI_EPF_HEADER_W_u16(vendorid)
420
421 PCI_EPF_HEADER_R(deviceid)
422 PCI_EPF_HEADER_W_u16(deviceid)
423
424 PCI_EPF_HEADER_R(revid)
425 PCI_EPF_HEADER_W_u8(revid)
426
427 PCI_EPF_HEADER_R(progif_code)
428 PCI_EPF_HEADER_W_u8(progif_code)
429
430 PCI_EPF_HEADER_R(subclass_code)
431 PCI_EPF_HEADER_W_u8(subclass_code)
432
433 PCI_EPF_HEADER_R(baseclass_code)
434 PCI_EPF_HEADER_W_u8(baseclass_code)
435
436 PCI_EPF_HEADER_R(cache_line_size)
437 PCI_EPF_HEADER_W_u8(cache_line_size)
438
439 PCI_EPF_HEADER_R(subsys_vendor_id)
440 PCI_EPF_HEADER_W_u16(subsys_vendor_id)
441
442 PCI_EPF_HEADER_R(subsys_id)
443 PCI_EPF_HEADER_W_u16(subsys_id)
444
445 PCI_EPF_HEADER_R(interrupt_pin)
446 PCI_EPF_HEADER_W_u8(interrupt_pin)
447
448 CONFIGFS_ATTR(pci_epf_, vendorid);
449 CONFIGFS_ATTR(pci_epf_, deviceid);
450 CONFIGFS_ATTR(pci_epf_, revid);
451 CONFIGFS_ATTR(pci_epf_, progif_code);
452 CONFIGFS_ATTR(pci_epf_, subclass_code);
453 CONFIGFS_ATTR(pci_epf_, baseclass_code);
454 CONFIGFS_ATTR(pci_epf_, cache_line_size);
455 CONFIGFS_ATTR(pci_epf_, subsys_vendor_id);
456 CONFIGFS_ATTR(pci_epf_, subsys_id);
457 CONFIGFS_ATTR(pci_epf_, interrupt_pin);
458 CONFIGFS_ATTR(pci_epf_, msi_interrupts);
459 CONFIGFS_ATTR(pci_epf_, msix_interrupts);
460
461 static struct configfs_attribute *pci_epf_attrs[] = {
462 &pci_epf_attr_vendorid,
463 &pci_epf_attr_deviceid,
464 &pci_epf_attr_revid,
465 &pci_epf_attr_progif_code,
466 &pci_epf_attr_subclass_code,
467 &pci_epf_attr_baseclass_code,
468 &pci_epf_attr_cache_line_size,
469 &pci_epf_attr_subsys_vendor_id,
470 &pci_epf_attr_subsys_id,
471 &pci_epf_attr_interrupt_pin,
472 &pci_epf_attr_msi_interrupts,
473 &pci_epf_attr_msix_interrupts,
474 NULL,
475 };
476
pci_epf_vepf_link(struct config_item * epf_pf_item,struct config_item * epf_vf_item)477 static int pci_epf_vepf_link(struct config_item *epf_pf_item,
478 struct config_item *epf_vf_item)
479 {
480 struct pci_epf_group *epf_vf_group = to_pci_epf_group(epf_vf_item);
481 struct pci_epf_group *epf_pf_group = to_pci_epf_group(epf_pf_item);
482 struct pci_epf *epf_pf = epf_pf_group->epf;
483 struct pci_epf *epf_vf = epf_vf_group->epf;
484
485 return pci_epf_add_vepf(epf_pf, epf_vf);
486 }
487
pci_epf_vepf_unlink(struct config_item * epf_pf_item,struct config_item * epf_vf_item)488 static void pci_epf_vepf_unlink(struct config_item *epf_pf_item,
489 struct config_item *epf_vf_item)
490 {
491 struct pci_epf_group *epf_vf_group = to_pci_epf_group(epf_vf_item);
492 struct pci_epf_group *epf_pf_group = to_pci_epf_group(epf_pf_item);
493 struct pci_epf *epf_pf = epf_pf_group->epf;
494 struct pci_epf *epf_vf = epf_vf_group->epf;
495
496 pci_epf_remove_vepf(epf_pf, epf_vf);
497 }
498
pci_epf_release(struct config_item * item)499 static void pci_epf_release(struct config_item *item)
500 {
501 struct pci_epf_group *epf_group = to_pci_epf_group(item);
502
503 mutex_lock(&functions_mutex);
504 idr_remove(&functions_idr, epf_group->index);
505 mutex_unlock(&functions_mutex);
506 pci_epf_destroy(epf_group->epf);
507 kfree(epf_group);
508 }
509
510 static struct configfs_item_operations pci_epf_ops = {
511 .allow_link = pci_epf_vepf_link,
512 .drop_link = pci_epf_vepf_unlink,
513 .release = pci_epf_release,
514 };
515
516 static const struct config_item_type pci_epf_type = {
517 .ct_item_ops = &pci_epf_ops,
518 .ct_attrs = pci_epf_attrs,
519 .ct_owner = THIS_MODULE,
520 };
521
522 /**
523 * pci_epf_type_add_cfs() - Help function drivers to expose function specific
524 * attributes in configfs
525 * @epf: the EPF device that has to be configured using configfs
526 * @group: the parent configfs group (corresponding to entries in
527 * pci_epf_device_id)
528 *
529 * Invoke to expose function specific attributes in configfs.
530 *
531 * Return: A pointer to a config_group structure or NULL if the function driver
532 * does not have anything to expose (attributes configured by user) or if
533 * the function driver does not implement the add_cfs() method.
534 *
535 * Returns an error pointer if this function is called for an unbound EPF device
536 * or if the EPF driver add_cfs() method fails.
537 */
pci_epf_type_add_cfs(struct pci_epf * epf,struct config_group * group)538 static struct config_group *pci_epf_type_add_cfs(struct pci_epf *epf,
539 struct config_group *group)
540 {
541 struct config_group *epf_type_group;
542
543 if (!epf->driver) {
544 dev_err(&epf->dev, "epf device not bound to driver\n");
545 return ERR_PTR(-ENODEV);
546 }
547
548 if (!epf->driver->ops->add_cfs)
549 return NULL;
550
551 mutex_lock(&epf->lock);
552 epf_type_group = epf->driver->ops->add_cfs(epf, group);
553 mutex_unlock(&epf->lock);
554
555 return epf_type_group;
556 }
557
pci_ep_cfs_add_type_group(struct pci_epf_group * epf_group)558 static void pci_ep_cfs_add_type_group(struct pci_epf_group *epf_group)
559 {
560 struct config_group *group;
561
562 group = pci_epf_type_add_cfs(epf_group->epf, &epf_group->group);
563 if (!group)
564 return;
565
566 if (IS_ERR(group)) {
567 dev_err(&epf_group->epf->dev,
568 "failed to create epf type specific attributes\n");
569 return;
570 }
571
572 configfs_add_default_group(group, &epf_group->group);
573 }
574
pci_epf_cfs_add_sub_groups(struct pci_epf_group * epf_group)575 static void pci_epf_cfs_add_sub_groups(struct pci_epf_group *epf_group)
576 {
577 struct config_group *group;
578
579 group = pci_ep_cfs_add_primary_group(epf_group);
580 if (IS_ERR(group)) {
581 pr_err("failed to create 'primary' EPC interface\n");
582 return;
583 }
584
585 group = pci_ep_cfs_add_secondary_group(epf_group);
586 if (IS_ERR(group)) {
587 pr_err("failed to create 'secondary' EPC interface\n");
588 return;
589 }
590
591 pci_ep_cfs_add_type_group(epf_group);
592 }
593
pci_epf_make(struct config_group * group,const char * name)594 static struct config_group *pci_epf_make(struct config_group *group,
595 const char *name)
596 {
597 struct pci_epf_group *epf_group;
598 struct pci_epf *epf;
599 char *epf_name;
600 int index, err;
601
602 epf_group = kzalloc_obj(*epf_group);
603 if (!epf_group)
604 return ERR_PTR(-ENOMEM);
605
606 mutex_lock(&functions_mutex);
607 index = idr_alloc(&functions_idr, epf_group, 0, 0, GFP_KERNEL);
608 mutex_unlock(&functions_mutex);
609 if (index < 0) {
610 err = index;
611 goto free_group;
612 }
613
614 epf_group->index = index;
615
616 config_group_init_type_name(&epf_group->group, name, &pci_epf_type);
617
618 epf_name = kasprintf(GFP_KERNEL, "%s.%d",
619 group->cg_item.ci_name, epf_group->index);
620 if (!epf_name) {
621 err = -ENOMEM;
622 goto remove_idr;
623 }
624
625 epf = pci_epf_create(epf_name);
626 if (IS_ERR(epf)) {
627 pr_err("failed to create endpoint function device\n");
628 err = -EINVAL;
629 goto free_name;
630 }
631
632 epf->group = &epf_group->group;
633 epf_group->epf = epf;
634
635 kfree(epf_name);
636
637 pci_epf_cfs_add_sub_groups(epf_group);
638
639 return &epf_group->group;
640
641 free_name:
642 kfree(epf_name);
643
644 remove_idr:
645 mutex_lock(&functions_mutex);
646 idr_remove(&functions_idr, epf_group->index);
647 mutex_unlock(&functions_mutex);
648
649 free_group:
650 kfree(epf_group);
651
652 return ERR_PTR(err);
653 }
654
pci_epf_drop(struct config_group * group,struct config_item * item)655 static void pci_epf_drop(struct config_group *group, struct config_item *item)
656 {
657 config_item_put(item);
658 }
659
660 static struct configfs_group_operations pci_epf_group_ops = {
661 .make_group = &pci_epf_make,
662 .drop_item = &pci_epf_drop,
663 };
664
665 static const struct config_item_type pci_epf_group_type = {
666 .ct_group_ops = &pci_epf_group_ops,
667 .ct_owner = THIS_MODULE,
668 };
669
pci_ep_cfs_add_epf_group(const char * name)670 struct config_group *pci_ep_cfs_add_epf_group(const char *name)
671 {
672 struct config_group *group;
673
674 group = configfs_register_default_group(functions_group, name,
675 &pci_epf_group_type);
676 if (IS_ERR(group))
677 pr_err("failed to register configfs group for %s function\n",
678 name);
679
680 return group;
681 }
682 EXPORT_SYMBOL(pci_ep_cfs_add_epf_group);
683
pci_ep_cfs_remove_epf_group(struct config_group * group)684 void pci_ep_cfs_remove_epf_group(struct config_group *group)
685 {
686 if (IS_ERR_OR_NULL(group))
687 return;
688
689 list_del(&group->group_entry);
690 configfs_unregister_default_group(group);
691 }
692 EXPORT_SYMBOL(pci_ep_cfs_remove_epf_group);
693
694 static const struct config_item_type pci_functions_type = {
695 .ct_owner = THIS_MODULE,
696 };
697
698 static const struct config_item_type pci_controllers_type = {
699 .ct_owner = THIS_MODULE,
700 };
701
702 static const struct config_item_type pci_ep_type = {
703 .ct_owner = THIS_MODULE,
704 };
705
706 static struct configfs_subsystem pci_ep_cfs_subsys = {
707 .su_group = {
708 .cg_item = {
709 .ci_namebuf = "pci_ep",
710 .ci_type = &pci_ep_type,
711 },
712 },
713 .su_mutex = __MUTEX_INITIALIZER(pci_ep_cfs_subsys.su_mutex),
714 };
715
pci_ep_cfs_init(void)716 static int __init pci_ep_cfs_init(void)
717 {
718 int ret;
719 struct config_group *root = &pci_ep_cfs_subsys.su_group;
720
721 config_group_init(root);
722
723 ret = configfs_register_subsystem(&pci_ep_cfs_subsys);
724 if (ret) {
725 pr_err("Error %d while registering subsystem %s\n",
726 ret, root->cg_item.ci_namebuf);
727 goto err;
728 }
729
730 functions_group = configfs_register_default_group(root, "functions",
731 &pci_functions_type);
732 if (IS_ERR(functions_group)) {
733 ret = PTR_ERR(functions_group);
734 pr_err("Error %d while registering functions group\n",
735 ret);
736 goto err_functions_group;
737 }
738
739 controllers_group =
740 configfs_register_default_group(root, "controllers",
741 &pci_controllers_type);
742 if (IS_ERR(controllers_group)) {
743 ret = PTR_ERR(controllers_group);
744 pr_err("Error %d while registering controllers group\n",
745 ret);
746 goto err_controllers_group;
747 }
748
749 return 0;
750
751 err_controllers_group:
752 configfs_unregister_default_group(functions_group);
753
754 err_functions_group:
755 configfs_unregister_subsystem(&pci_ep_cfs_subsys);
756
757 err:
758 return ret;
759 }
760 module_init(pci_ep_cfs_init);
761
pci_ep_cfs_exit(void)762 static void __exit pci_ep_cfs_exit(void)
763 {
764 configfs_unregister_default_group(controllers_group);
765 configfs_unregister_default_group(functions_group);
766 configfs_unregister_subsystem(&pci_ep_cfs_subsys);
767 }
768 module_exit(pci_ep_cfs_exit);
769
770 MODULE_DESCRIPTION("PCI EP CONFIGFS");
771 MODULE_AUTHOR("Kishon Vijay Abraham I <kishon@ti.com>");
772