Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at master 777 lines 20 kB view raw
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 17static DEFINE_IDR(functions_idr); 18static DEFINE_MUTEX(functions_mutex); 19static struct config_group *functions_group; 20static struct config_group *controllers_group; 21 22struct 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 30struct pci_epc_group { 31 struct config_group group; 32 struct pci_epc *epc; 33 bool start; 34}; 35 36static 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 41static 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 46static 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 71static 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 87static const 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 92static 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 97static struct config_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 110static 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 135static 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 151static const 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 156static 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 161static struct config_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 173static 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 206static 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 211CONFIGFS_ATTR(pci_epc_, start); 212 213static struct configfs_attribute *pci_epc_attrs[] = { 214 &pci_epc_attr_start, 215 NULL, 216}; 217 218static 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 243static 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 259static const struct configfs_item_operations pci_epc_item_ops = { 260 .allow_link = pci_epc_epf_link, 261 .drop_link = pci_epc_epf_unlink, 262}; 263 264static 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 270struct 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 302err_epc_get: 303 configfs_unregister_group(group); 304 305err_register_group: 306 kfree(epc_group); 307 308err: 309 return ERR_PTR(ret); 310} 311EXPORT_SYMBOL(pci_ep_cfs_add_epc_group); 312 313void 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} 325EXPORT_SYMBOL(pci_ep_cfs_remove_epc_group); 326 327#define PCI_EPF_HEADER_R(_name) \ 328static 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) \ 337static 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) \ 351static 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) \ 365static 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 378static 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 391static 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 398static 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 411static 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 418PCI_EPF_HEADER_R(vendorid) 419PCI_EPF_HEADER_W_u16(vendorid) 420 421PCI_EPF_HEADER_R(deviceid) 422PCI_EPF_HEADER_W_u16(deviceid) 423 424PCI_EPF_HEADER_R(revid) 425PCI_EPF_HEADER_W_u8(revid) 426 427PCI_EPF_HEADER_R(progif_code) 428PCI_EPF_HEADER_W_u8(progif_code) 429 430PCI_EPF_HEADER_R(subclass_code) 431PCI_EPF_HEADER_W_u8(subclass_code) 432 433PCI_EPF_HEADER_R(baseclass_code) 434PCI_EPF_HEADER_W_u8(baseclass_code) 435 436PCI_EPF_HEADER_R(cache_line_size) 437PCI_EPF_HEADER_W_u8(cache_line_size) 438 439PCI_EPF_HEADER_R(subsys_vendor_id) 440PCI_EPF_HEADER_W_u16(subsys_vendor_id) 441 442PCI_EPF_HEADER_R(subsys_id) 443PCI_EPF_HEADER_W_u16(subsys_id) 444 445PCI_EPF_HEADER_R(interrupt_pin) 446PCI_EPF_HEADER_W_u8(interrupt_pin) 447 448CONFIGFS_ATTR(pci_epf_, vendorid); 449CONFIGFS_ATTR(pci_epf_, deviceid); 450CONFIGFS_ATTR(pci_epf_, revid); 451CONFIGFS_ATTR(pci_epf_, progif_code); 452CONFIGFS_ATTR(pci_epf_, subclass_code); 453CONFIGFS_ATTR(pci_epf_, baseclass_code); 454CONFIGFS_ATTR(pci_epf_, cache_line_size); 455CONFIGFS_ATTR(pci_epf_, subsys_vendor_id); 456CONFIGFS_ATTR(pci_epf_, subsys_id); 457CONFIGFS_ATTR(pci_epf_, interrupt_pin); 458CONFIGFS_ATTR(pci_epf_, msi_interrupts); 459CONFIGFS_ATTR(pci_epf_, msix_interrupts); 460 461static 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 477static 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 488static 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 499static 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 510static const 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 516static 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 */ 538static 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 558static 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: %pe\n", 569 group); 570 return; 571 } 572 573 configfs_add_default_group(group, &epf_group->group); 574} 575 576static void pci_epf_cfs_add_sub_groups(struct pci_epf_group *epf_group) 577{ 578 struct config_group *group; 579 580 group = pci_ep_cfs_add_primary_group(epf_group); 581 if (IS_ERR(group)) { 582 dev_err(&epf_group->epf->dev, 583 "failed to create 'primary' EPC interface: %pe\n", 584 group); 585 return; 586 } 587 588 group = pci_ep_cfs_add_secondary_group(epf_group); 589 if (IS_ERR(group)) { 590 dev_err(&epf_group->epf->dev, 591 "failed to create 'secondary' EPC interface: %pe\n", 592 group); 593 return; 594 } 595 596 pci_ep_cfs_add_type_group(epf_group); 597} 598 599static struct config_group *pci_epf_make(struct config_group *group, 600 const char *name) 601{ 602 struct pci_epf_group *epf_group; 603 struct pci_epf *epf; 604 char *epf_name; 605 int index, err; 606 607 epf_group = kzalloc_obj(*epf_group); 608 if (!epf_group) 609 return ERR_PTR(-ENOMEM); 610 611 mutex_lock(&functions_mutex); 612 index = idr_alloc(&functions_idr, epf_group, 0, 0, GFP_KERNEL); 613 mutex_unlock(&functions_mutex); 614 if (index < 0) { 615 err = index; 616 goto free_group; 617 } 618 619 epf_group->index = index; 620 621 config_group_init_type_name(&epf_group->group, name, &pci_epf_type); 622 623 epf_name = kasprintf(GFP_KERNEL, "%s.%d", 624 group->cg_item.ci_name, epf_group->index); 625 if (!epf_name) { 626 err = -ENOMEM; 627 goto remove_idr; 628 } 629 630 epf = pci_epf_create(epf_name); 631 if (IS_ERR(epf)) { 632 err = PTR_ERR(epf); 633 pr_err("failed to create endpoint function device (%s): %d\n", 634 epf_name, err); 635 goto free_name; 636 } 637 638 epf->group = &epf_group->group; 639 epf_group->epf = epf; 640 641 kfree(epf_name); 642 643 pci_epf_cfs_add_sub_groups(epf_group); 644 645 return &epf_group->group; 646 647free_name: 648 kfree(epf_name); 649 650remove_idr: 651 mutex_lock(&functions_mutex); 652 idr_remove(&functions_idr, epf_group->index); 653 mutex_unlock(&functions_mutex); 654 655free_group: 656 kfree(epf_group); 657 658 return ERR_PTR(err); 659} 660 661static void pci_epf_drop(struct config_group *group, struct config_item *item) 662{ 663 config_item_put(item); 664} 665 666static const struct configfs_group_operations pci_epf_group_ops = { 667 .make_group = &pci_epf_make, 668 .drop_item = &pci_epf_drop, 669}; 670 671static const struct config_item_type pci_epf_group_type = { 672 .ct_group_ops = &pci_epf_group_ops, 673 .ct_owner = THIS_MODULE, 674}; 675 676struct config_group *pci_ep_cfs_add_epf_group(const char *name) 677{ 678 struct config_group *group; 679 680 group = configfs_register_default_group(functions_group, name, 681 &pci_epf_group_type); 682 if (IS_ERR(group)) 683 pr_err("failed to register configfs group for %s function: %pe\n", 684 name, group); 685 686 return group; 687} 688EXPORT_SYMBOL(pci_ep_cfs_add_epf_group); 689 690void pci_ep_cfs_remove_epf_group(struct config_group *group) 691{ 692 if (IS_ERR_OR_NULL(group)) 693 return; 694 695 list_del(&group->group_entry); 696 configfs_unregister_default_group(group); 697} 698EXPORT_SYMBOL(pci_ep_cfs_remove_epf_group); 699 700static const struct config_item_type pci_functions_type = { 701 .ct_owner = THIS_MODULE, 702}; 703 704static const struct config_item_type pci_controllers_type = { 705 .ct_owner = THIS_MODULE, 706}; 707 708static const struct config_item_type pci_ep_type = { 709 .ct_owner = THIS_MODULE, 710}; 711 712static struct configfs_subsystem pci_ep_cfs_subsys = { 713 .su_group = { 714 .cg_item = { 715 .ci_namebuf = "pci_ep", 716 .ci_type = &pci_ep_type, 717 }, 718 }, 719 .su_mutex = __MUTEX_INITIALIZER(pci_ep_cfs_subsys.su_mutex), 720}; 721 722static int __init pci_ep_cfs_init(void) 723{ 724 int ret; 725 struct config_group *root = &pci_ep_cfs_subsys.su_group; 726 727 config_group_init(root); 728 729 ret = configfs_register_subsystem(&pci_ep_cfs_subsys); 730 if (ret) { 731 pr_err("Error %d while registering subsystem %s\n", 732 ret, root->cg_item.ci_namebuf); 733 goto err; 734 } 735 736 functions_group = configfs_register_default_group(root, "functions", 737 &pci_functions_type); 738 if (IS_ERR(functions_group)) { 739 ret = PTR_ERR(functions_group); 740 pr_err("Error %d while registering functions group\n", 741 ret); 742 goto err_functions_group; 743 } 744 745 controllers_group = 746 configfs_register_default_group(root, "controllers", 747 &pci_controllers_type); 748 if (IS_ERR(controllers_group)) { 749 ret = PTR_ERR(controllers_group); 750 pr_err("Error %d while registering controllers group\n", 751 ret); 752 goto err_controllers_group; 753 } 754 755 return 0; 756 757err_controllers_group: 758 configfs_unregister_default_group(functions_group); 759 760err_functions_group: 761 configfs_unregister_subsystem(&pci_ep_cfs_subsys); 762 763err: 764 return ret; 765} 766module_init(pci_ep_cfs_init); 767 768static void __exit pci_ep_cfs_exit(void) 769{ 770 configfs_unregister_default_group(controllers_group); 771 configfs_unregister_default_group(functions_group); 772 configfs_unregister_subsystem(&pci_ep_cfs_subsys); 773} 774module_exit(pci_ep_cfs_exit); 775 776MODULE_DESCRIPTION("PCI EP CONFIGFS"); 777MODULE_AUTHOR("Kishon Vijay Abraham I <kishon@ti.com>");