0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/module.h>
0010 #include <linux/idr.h>
0011 #include <linux/slab.h>
0012
0013 #include <linux/pci-epc.h>
0014 #include <linux/pci-epf.h>
0015 #include <linux/pci-ep-cfs.h>
0016
0017 static DEFINE_IDR(functions_idr);
0018 static DEFINE_MUTEX(functions_mutex);
0019 static struct config_group *functions_group;
0020 static struct config_group *controllers_group;
0021
0022 struct pci_epf_group {
0023 struct config_group group;
0024 struct config_group primary_epc_group;
0025 struct config_group secondary_epc_group;
0026 struct delayed_work cfs_work;
0027 struct pci_epf *epf;
0028 int index;
0029 };
0030
0031 struct pci_epc_group {
0032 struct config_group group;
0033 struct pci_epc *epc;
0034 bool start;
0035 };
0036
0037 static inline struct pci_epf_group *to_pci_epf_group(struct config_item *item)
0038 {
0039 return container_of(to_config_group(item), struct pci_epf_group, group);
0040 }
0041
0042 static inline struct pci_epc_group *to_pci_epc_group(struct config_item *item)
0043 {
0044 return container_of(to_config_group(item), struct pci_epc_group, group);
0045 }
0046
0047 static int pci_secondary_epc_epf_link(struct config_item *epf_item,
0048 struct config_item *epc_item)
0049 {
0050 int ret;
0051 struct pci_epf_group *epf_group = to_pci_epf_group(epf_item->ci_parent);
0052 struct pci_epc_group *epc_group = to_pci_epc_group(epc_item);
0053 struct pci_epc *epc = epc_group->epc;
0054 struct pci_epf *epf = epf_group->epf;
0055
0056 ret = pci_epc_add_epf(epc, epf, SECONDARY_INTERFACE);
0057 if (ret)
0058 return ret;
0059
0060 ret = pci_epf_bind(epf);
0061 if (ret) {
0062 pci_epc_remove_epf(epc, epf, SECONDARY_INTERFACE);
0063 return ret;
0064 }
0065
0066 return 0;
0067 }
0068
0069 static void pci_secondary_epc_epf_unlink(struct config_item *epc_item,
0070 struct config_item *epf_item)
0071 {
0072 struct pci_epf_group *epf_group = to_pci_epf_group(epf_item->ci_parent);
0073 struct pci_epc_group *epc_group = to_pci_epc_group(epc_item);
0074 struct pci_epc *epc;
0075 struct pci_epf *epf;
0076
0077 WARN_ON_ONCE(epc_group->start);
0078
0079 epc = epc_group->epc;
0080 epf = epf_group->epf;
0081 pci_epf_unbind(epf);
0082 pci_epc_remove_epf(epc, epf, SECONDARY_INTERFACE);
0083 }
0084
0085 static struct configfs_item_operations pci_secondary_epc_item_ops = {
0086 .allow_link = pci_secondary_epc_epf_link,
0087 .drop_link = pci_secondary_epc_epf_unlink,
0088 };
0089
0090 static const struct config_item_type pci_secondary_epc_type = {
0091 .ct_item_ops = &pci_secondary_epc_item_ops,
0092 .ct_owner = THIS_MODULE,
0093 };
0094
0095 static struct config_group
0096 *pci_ep_cfs_add_secondary_group(struct pci_epf_group *epf_group)
0097 {
0098 struct config_group *secondary_epc_group;
0099
0100 secondary_epc_group = &epf_group->secondary_epc_group;
0101 config_group_init_type_name(secondary_epc_group, "secondary",
0102 &pci_secondary_epc_type);
0103 configfs_register_group(&epf_group->group, secondary_epc_group);
0104
0105 return secondary_epc_group;
0106 }
0107
0108 static int pci_primary_epc_epf_link(struct config_item *epf_item,
0109 struct config_item *epc_item)
0110 {
0111 int ret;
0112 struct pci_epf_group *epf_group = to_pci_epf_group(epf_item->ci_parent);
0113 struct pci_epc_group *epc_group = to_pci_epc_group(epc_item);
0114 struct pci_epc *epc = epc_group->epc;
0115 struct pci_epf *epf = epf_group->epf;
0116
0117 ret = pci_epc_add_epf(epc, epf, PRIMARY_INTERFACE);
0118 if (ret)
0119 return ret;
0120
0121 ret = pci_epf_bind(epf);
0122 if (ret) {
0123 pci_epc_remove_epf(epc, epf, PRIMARY_INTERFACE);
0124 return ret;
0125 }
0126
0127 return 0;
0128 }
0129
0130 static void pci_primary_epc_epf_unlink(struct config_item *epc_item,
0131 struct config_item *epf_item)
0132 {
0133 struct pci_epf_group *epf_group = to_pci_epf_group(epf_item->ci_parent);
0134 struct pci_epc_group *epc_group = to_pci_epc_group(epc_item);
0135 struct pci_epc *epc;
0136 struct pci_epf *epf;
0137
0138 WARN_ON_ONCE(epc_group->start);
0139
0140 epc = epc_group->epc;
0141 epf = epf_group->epf;
0142 pci_epf_unbind(epf);
0143 pci_epc_remove_epf(epc, epf, PRIMARY_INTERFACE);
0144 }
0145
0146 static struct configfs_item_operations pci_primary_epc_item_ops = {
0147 .allow_link = pci_primary_epc_epf_link,
0148 .drop_link = pci_primary_epc_epf_unlink,
0149 };
0150
0151 static const struct config_item_type pci_primary_epc_type = {
0152 .ct_item_ops = &pci_primary_epc_item_ops,
0153 .ct_owner = THIS_MODULE,
0154 };
0155
0156 static struct config_group
0157 *pci_ep_cfs_add_primary_group(struct pci_epf_group *epf_group)
0158 {
0159 struct config_group *primary_epc_group = &epf_group->primary_epc_group;
0160
0161 config_group_init_type_name(primary_epc_group, "primary",
0162 &pci_primary_epc_type);
0163 configfs_register_group(&epf_group->group, primary_epc_group);
0164
0165 return primary_epc_group;
0166 }
0167
0168 static ssize_t pci_epc_start_store(struct config_item *item, const char *page,
0169 size_t len)
0170 {
0171 int ret;
0172 bool start;
0173 struct pci_epc *epc;
0174 struct pci_epc_group *epc_group = to_pci_epc_group(item);
0175
0176 epc = epc_group->epc;
0177
0178 if (kstrtobool(page, &start) < 0)
0179 return -EINVAL;
0180
0181 if (!start) {
0182 pci_epc_stop(epc);
0183 epc_group->start = 0;
0184 return len;
0185 }
0186
0187 ret = pci_epc_start(epc);
0188 if (ret) {
0189 dev_err(&epc->dev, "failed to start endpoint controller\n");
0190 return -EINVAL;
0191 }
0192
0193 epc_group->start = start;
0194
0195 return len;
0196 }
0197
0198 static ssize_t pci_epc_start_show(struct config_item *item, char *page)
0199 {
0200 return sysfs_emit(page, "%d\n", to_pci_epc_group(item)->start);
0201 }
0202
0203 CONFIGFS_ATTR(pci_epc_, start);
0204
0205 static struct configfs_attribute *pci_epc_attrs[] = {
0206 &pci_epc_attr_start,
0207 NULL,
0208 };
0209
0210 static int pci_epc_epf_link(struct config_item *epc_item,
0211 struct config_item *epf_item)
0212 {
0213 int ret;
0214 struct pci_epf_group *epf_group = to_pci_epf_group(epf_item);
0215 struct pci_epc_group *epc_group = to_pci_epc_group(epc_item);
0216 struct pci_epc *epc = epc_group->epc;
0217 struct pci_epf *epf = epf_group->epf;
0218
0219 ret = pci_epc_add_epf(epc, epf, PRIMARY_INTERFACE);
0220 if (ret)
0221 return ret;
0222
0223 ret = pci_epf_bind(epf);
0224 if (ret) {
0225 pci_epc_remove_epf(epc, epf, PRIMARY_INTERFACE);
0226 return ret;
0227 }
0228
0229 return 0;
0230 }
0231
0232 static void pci_epc_epf_unlink(struct config_item *epc_item,
0233 struct config_item *epf_item)
0234 {
0235 struct pci_epc *epc;
0236 struct pci_epf *epf;
0237 struct pci_epf_group *epf_group = to_pci_epf_group(epf_item);
0238 struct pci_epc_group *epc_group = to_pci_epc_group(epc_item);
0239
0240 WARN_ON_ONCE(epc_group->start);
0241
0242 epc = epc_group->epc;
0243 epf = epf_group->epf;
0244 pci_epf_unbind(epf);
0245 pci_epc_remove_epf(epc, epf, PRIMARY_INTERFACE);
0246 }
0247
0248 static struct configfs_item_operations pci_epc_item_ops = {
0249 .allow_link = pci_epc_epf_link,
0250 .drop_link = pci_epc_epf_unlink,
0251 };
0252
0253 static const struct config_item_type pci_epc_type = {
0254 .ct_item_ops = &pci_epc_item_ops,
0255 .ct_attrs = pci_epc_attrs,
0256 .ct_owner = THIS_MODULE,
0257 };
0258
0259 struct config_group *pci_ep_cfs_add_epc_group(const char *name)
0260 {
0261 int ret;
0262 struct pci_epc *epc;
0263 struct config_group *group;
0264 struct pci_epc_group *epc_group;
0265
0266 epc_group = kzalloc(sizeof(*epc_group), GFP_KERNEL);
0267 if (!epc_group) {
0268 ret = -ENOMEM;
0269 goto err;
0270 }
0271
0272 group = &epc_group->group;
0273
0274 config_group_init_type_name(group, name, &pci_epc_type);
0275 ret = configfs_register_group(controllers_group, group);
0276 if (ret) {
0277 pr_err("failed to register configfs group for %s\n", name);
0278 goto err_register_group;
0279 }
0280
0281 epc = pci_epc_get(name);
0282 if (IS_ERR(epc)) {
0283 ret = PTR_ERR(epc);
0284 goto err_epc_get;
0285 }
0286
0287 epc_group->epc = epc;
0288
0289 return group;
0290
0291 err_epc_get:
0292 configfs_unregister_group(group);
0293
0294 err_register_group:
0295 kfree(epc_group);
0296
0297 err:
0298 return ERR_PTR(ret);
0299 }
0300 EXPORT_SYMBOL(pci_ep_cfs_add_epc_group);
0301
0302 void pci_ep_cfs_remove_epc_group(struct config_group *group)
0303 {
0304 struct pci_epc_group *epc_group;
0305
0306 if (!group)
0307 return;
0308
0309 epc_group = container_of(group, struct pci_epc_group, group);
0310 pci_epc_put(epc_group->epc);
0311 configfs_unregister_group(&epc_group->group);
0312 kfree(epc_group);
0313 }
0314 EXPORT_SYMBOL(pci_ep_cfs_remove_epc_group);
0315
0316 #define PCI_EPF_HEADER_R(_name) \
0317 static ssize_t pci_epf_##_name##_show(struct config_item *item, char *page) \
0318 { \
0319 struct pci_epf *epf = to_pci_epf_group(item)->epf; \
0320 if (WARN_ON_ONCE(!epf->header)) \
0321 return -EINVAL; \
0322 return sysfs_emit(page, "0x%04x\n", epf->header->_name); \
0323 }
0324
0325 #define PCI_EPF_HEADER_W_u32(_name) \
0326 static ssize_t pci_epf_##_name##_store(struct config_item *item, \
0327 const char *page, size_t len) \
0328 { \
0329 u32 val; \
0330 struct pci_epf *epf = to_pci_epf_group(item)->epf; \
0331 if (WARN_ON_ONCE(!epf->header)) \
0332 return -EINVAL; \
0333 if (kstrtou32(page, 0, &val) < 0) \
0334 return -EINVAL; \
0335 epf->header->_name = val; \
0336 return len; \
0337 }
0338
0339 #define PCI_EPF_HEADER_W_u16(_name) \
0340 static ssize_t pci_epf_##_name##_store(struct config_item *item, \
0341 const char *page, size_t len) \
0342 { \
0343 u16 val; \
0344 struct pci_epf *epf = to_pci_epf_group(item)->epf; \
0345 if (WARN_ON_ONCE(!epf->header)) \
0346 return -EINVAL; \
0347 if (kstrtou16(page, 0, &val) < 0) \
0348 return -EINVAL; \
0349 epf->header->_name = val; \
0350 return len; \
0351 }
0352
0353 #define PCI_EPF_HEADER_W_u8(_name) \
0354 static ssize_t pci_epf_##_name##_store(struct config_item *item, \
0355 const char *page, size_t len) \
0356 { \
0357 u8 val; \
0358 struct pci_epf *epf = to_pci_epf_group(item)->epf; \
0359 if (WARN_ON_ONCE(!epf->header)) \
0360 return -EINVAL; \
0361 if (kstrtou8(page, 0, &val) < 0) \
0362 return -EINVAL; \
0363 epf->header->_name = val; \
0364 return len; \
0365 }
0366
0367 static ssize_t pci_epf_msi_interrupts_store(struct config_item *item,
0368 const char *page, size_t len)
0369 {
0370 u8 val;
0371
0372 if (kstrtou8(page, 0, &val) < 0)
0373 return -EINVAL;
0374
0375 to_pci_epf_group(item)->epf->msi_interrupts = val;
0376
0377 return len;
0378 }
0379
0380 static ssize_t pci_epf_msi_interrupts_show(struct config_item *item,
0381 char *page)
0382 {
0383 return sysfs_emit(page, "%d\n",
0384 to_pci_epf_group(item)->epf->msi_interrupts);
0385 }
0386
0387 static ssize_t pci_epf_msix_interrupts_store(struct config_item *item,
0388 const char *page, size_t len)
0389 {
0390 u16 val;
0391
0392 if (kstrtou16(page, 0, &val) < 0)
0393 return -EINVAL;
0394
0395 to_pci_epf_group(item)->epf->msix_interrupts = val;
0396
0397 return len;
0398 }
0399
0400 static ssize_t pci_epf_msix_interrupts_show(struct config_item *item,
0401 char *page)
0402 {
0403 return sysfs_emit(page, "%d\n",
0404 to_pci_epf_group(item)->epf->msix_interrupts);
0405 }
0406
0407 PCI_EPF_HEADER_R(vendorid)
0408 PCI_EPF_HEADER_W_u16(vendorid)
0409
0410 PCI_EPF_HEADER_R(deviceid)
0411 PCI_EPF_HEADER_W_u16(deviceid)
0412
0413 PCI_EPF_HEADER_R(revid)
0414 PCI_EPF_HEADER_W_u8(revid)
0415
0416 PCI_EPF_HEADER_R(progif_code)
0417 PCI_EPF_HEADER_W_u8(progif_code)
0418
0419 PCI_EPF_HEADER_R(subclass_code)
0420 PCI_EPF_HEADER_W_u8(subclass_code)
0421
0422 PCI_EPF_HEADER_R(baseclass_code)
0423 PCI_EPF_HEADER_W_u8(baseclass_code)
0424
0425 PCI_EPF_HEADER_R(cache_line_size)
0426 PCI_EPF_HEADER_W_u8(cache_line_size)
0427
0428 PCI_EPF_HEADER_R(subsys_vendor_id)
0429 PCI_EPF_HEADER_W_u16(subsys_vendor_id)
0430
0431 PCI_EPF_HEADER_R(subsys_id)
0432 PCI_EPF_HEADER_W_u16(subsys_id)
0433
0434 PCI_EPF_HEADER_R(interrupt_pin)
0435 PCI_EPF_HEADER_W_u8(interrupt_pin)
0436
0437 CONFIGFS_ATTR(pci_epf_, vendorid);
0438 CONFIGFS_ATTR(pci_epf_, deviceid);
0439 CONFIGFS_ATTR(pci_epf_, revid);
0440 CONFIGFS_ATTR(pci_epf_, progif_code);
0441 CONFIGFS_ATTR(pci_epf_, subclass_code);
0442 CONFIGFS_ATTR(pci_epf_, baseclass_code);
0443 CONFIGFS_ATTR(pci_epf_, cache_line_size);
0444 CONFIGFS_ATTR(pci_epf_, subsys_vendor_id);
0445 CONFIGFS_ATTR(pci_epf_, subsys_id);
0446 CONFIGFS_ATTR(pci_epf_, interrupt_pin);
0447 CONFIGFS_ATTR(pci_epf_, msi_interrupts);
0448 CONFIGFS_ATTR(pci_epf_, msix_interrupts);
0449
0450 static struct configfs_attribute *pci_epf_attrs[] = {
0451 &pci_epf_attr_vendorid,
0452 &pci_epf_attr_deviceid,
0453 &pci_epf_attr_revid,
0454 &pci_epf_attr_progif_code,
0455 &pci_epf_attr_subclass_code,
0456 &pci_epf_attr_baseclass_code,
0457 &pci_epf_attr_cache_line_size,
0458 &pci_epf_attr_subsys_vendor_id,
0459 &pci_epf_attr_subsys_id,
0460 &pci_epf_attr_interrupt_pin,
0461 &pci_epf_attr_msi_interrupts,
0462 &pci_epf_attr_msix_interrupts,
0463 NULL,
0464 };
0465
0466 static int pci_epf_vepf_link(struct config_item *epf_pf_item,
0467 struct config_item *epf_vf_item)
0468 {
0469 struct pci_epf_group *epf_vf_group = to_pci_epf_group(epf_vf_item);
0470 struct pci_epf_group *epf_pf_group = to_pci_epf_group(epf_pf_item);
0471 struct pci_epf *epf_pf = epf_pf_group->epf;
0472 struct pci_epf *epf_vf = epf_vf_group->epf;
0473
0474 return pci_epf_add_vepf(epf_pf, epf_vf);
0475 }
0476
0477 static void pci_epf_vepf_unlink(struct config_item *epf_pf_item,
0478 struct config_item *epf_vf_item)
0479 {
0480 struct pci_epf_group *epf_vf_group = to_pci_epf_group(epf_vf_item);
0481 struct pci_epf_group *epf_pf_group = to_pci_epf_group(epf_pf_item);
0482 struct pci_epf *epf_pf = epf_pf_group->epf;
0483 struct pci_epf *epf_vf = epf_vf_group->epf;
0484
0485 pci_epf_remove_vepf(epf_pf, epf_vf);
0486 }
0487
0488 static void pci_epf_release(struct config_item *item)
0489 {
0490 struct pci_epf_group *epf_group = to_pci_epf_group(item);
0491
0492 mutex_lock(&functions_mutex);
0493 idr_remove(&functions_idr, epf_group->index);
0494 mutex_unlock(&functions_mutex);
0495 pci_epf_destroy(epf_group->epf);
0496 kfree(epf_group);
0497 }
0498
0499 static struct configfs_item_operations pci_epf_ops = {
0500 .allow_link = pci_epf_vepf_link,
0501 .drop_link = pci_epf_vepf_unlink,
0502 .release = pci_epf_release,
0503 };
0504
0505 static struct config_group *pci_epf_type_make(struct config_group *group,
0506 const char *name)
0507 {
0508 struct pci_epf_group *epf_group = to_pci_epf_group(&group->cg_item);
0509 struct config_group *epf_type_group;
0510
0511 epf_type_group = pci_epf_type_add_cfs(epf_group->epf, group);
0512 return epf_type_group;
0513 }
0514
0515 static void pci_epf_type_drop(struct config_group *group,
0516 struct config_item *item)
0517 {
0518 config_item_put(item);
0519 }
0520
0521 static struct configfs_group_operations pci_epf_type_group_ops = {
0522 .make_group = &pci_epf_type_make,
0523 .drop_item = &pci_epf_type_drop,
0524 };
0525
0526 static const struct config_item_type pci_epf_type = {
0527 .ct_group_ops = &pci_epf_type_group_ops,
0528 .ct_item_ops = &pci_epf_ops,
0529 .ct_attrs = pci_epf_attrs,
0530 .ct_owner = THIS_MODULE,
0531 };
0532
0533 static void pci_epf_cfs_work(struct work_struct *work)
0534 {
0535 struct pci_epf_group *epf_group;
0536 struct config_group *group;
0537
0538 epf_group = container_of(work, struct pci_epf_group, cfs_work.work);
0539 group = pci_ep_cfs_add_primary_group(epf_group);
0540 if (IS_ERR(group)) {
0541 pr_err("failed to create 'primary' EPC interface\n");
0542 return;
0543 }
0544
0545 group = pci_ep_cfs_add_secondary_group(epf_group);
0546 if (IS_ERR(group)) {
0547 pr_err("failed to create 'secondary' EPC interface\n");
0548 return;
0549 }
0550 }
0551
0552 static struct config_group *pci_epf_make(struct config_group *group,
0553 const char *name)
0554 {
0555 struct pci_epf_group *epf_group;
0556 struct pci_epf *epf;
0557 char *epf_name;
0558 int index, err;
0559
0560 epf_group = kzalloc(sizeof(*epf_group), GFP_KERNEL);
0561 if (!epf_group)
0562 return ERR_PTR(-ENOMEM);
0563
0564 mutex_lock(&functions_mutex);
0565 index = idr_alloc(&functions_idr, epf_group, 0, 0, GFP_KERNEL);
0566 mutex_unlock(&functions_mutex);
0567 if (index < 0) {
0568 err = index;
0569 goto free_group;
0570 }
0571
0572 epf_group->index = index;
0573
0574 config_group_init_type_name(&epf_group->group, name, &pci_epf_type);
0575
0576 epf_name = kasprintf(GFP_KERNEL, "%s.%d",
0577 group->cg_item.ci_name, epf_group->index);
0578 if (!epf_name) {
0579 err = -ENOMEM;
0580 goto remove_idr;
0581 }
0582
0583 epf = pci_epf_create(epf_name);
0584 if (IS_ERR(epf)) {
0585 pr_err("failed to create endpoint function device\n");
0586 err = -EINVAL;
0587 goto free_name;
0588 }
0589
0590 epf->group = &epf_group->group;
0591 epf_group->epf = epf;
0592
0593 kfree(epf_name);
0594
0595 INIT_DELAYED_WORK(&epf_group->cfs_work, pci_epf_cfs_work);
0596 queue_delayed_work(system_wq, &epf_group->cfs_work,
0597 msecs_to_jiffies(1));
0598
0599 return &epf_group->group;
0600
0601 free_name:
0602 kfree(epf_name);
0603
0604 remove_idr:
0605 mutex_lock(&functions_mutex);
0606 idr_remove(&functions_idr, epf_group->index);
0607 mutex_unlock(&functions_mutex);
0608
0609 free_group:
0610 kfree(epf_group);
0611
0612 return ERR_PTR(err);
0613 }
0614
0615 static void pci_epf_drop(struct config_group *group, struct config_item *item)
0616 {
0617 config_item_put(item);
0618 }
0619
0620 static struct configfs_group_operations pci_epf_group_ops = {
0621 .make_group = &pci_epf_make,
0622 .drop_item = &pci_epf_drop,
0623 };
0624
0625 static const struct config_item_type pci_epf_group_type = {
0626 .ct_group_ops = &pci_epf_group_ops,
0627 .ct_owner = THIS_MODULE,
0628 };
0629
0630 struct config_group *pci_ep_cfs_add_epf_group(const char *name)
0631 {
0632 struct config_group *group;
0633
0634 group = configfs_register_default_group(functions_group, name,
0635 &pci_epf_group_type);
0636 if (IS_ERR(group))
0637 pr_err("failed to register configfs group for %s function\n",
0638 name);
0639
0640 return group;
0641 }
0642 EXPORT_SYMBOL(pci_ep_cfs_add_epf_group);
0643
0644 void pci_ep_cfs_remove_epf_group(struct config_group *group)
0645 {
0646 if (IS_ERR_OR_NULL(group))
0647 return;
0648
0649 configfs_unregister_default_group(group);
0650 }
0651 EXPORT_SYMBOL(pci_ep_cfs_remove_epf_group);
0652
0653 static const struct config_item_type pci_functions_type = {
0654 .ct_owner = THIS_MODULE,
0655 };
0656
0657 static const struct config_item_type pci_controllers_type = {
0658 .ct_owner = THIS_MODULE,
0659 };
0660
0661 static const struct config_item_type pci_ep_type = {
0662 .ct_owner = THIS_MODULE,
0663 };
0664
0665 static struct configfs_subsystem pci_ep_cfs_subsys = {
0666 .su_group = {
0667 .cg_item = {
0668 .ci_namebuf = "pci_ep",
0669 .ci_type = &pci_ep_type,
0670 },
0671 },
0672 .su_mutex = __MUTEX_INITIALIZER(pci_ep_cfs_subsys.su_mutex),
0673 };
0674
0675 static int __init pci_ep_cfs_init(void)
0676 {
0677 int ret;
0678 struct config_group *root = &pci_ep_cfs_subsys.su_group;
0679
0680 config_group_init(root);
0681
0682 ret = configfs_register_subsystem(&pci_ep_cfs_subsys);
0683 if (ret) {
0684 pr_err("Error %d while registering subsystem %s\n",
0685 ret, root->cg_item.ci_namebuf);
0686 goto err;
0687 }
0688
0689 functions_group = configfs_register_default_group(root, "functions",
0690 &pci_functions_type);
0691 if (IS_ERR(functions_group)) {
0692 ret = PTR_ERR(functions_group);
0693 pr_err("Error %d while registering functions group\n",
0694 ret);
0695 goto err_functions_group;
0696 }
0697
0698 controllers_group =
0699 configfs_register_default_group(root, "controllers",
0700 &pci_controllers_type);
0701 if (IS_ERR(controllers_group)) {
0702 ret = PTR_ERR(controllers_group);
0703 pr_err("Error %d while registering controllers group\n",
0704 ret);
0705 goto err_controllers_group;
0706 }
0707
0708 return 0;
0709
0710 err_controllers_group:
0711 configfs_unregister_default_group(functions_group);
0712
0713 err_functions_group:
0714 configfs_unregister_subsystem(&pci_ep_cfs_subsys);
0715
0716 err:
0717 return ret;
0718 }
0719 module_init(pci_ep_cfs_init);
0720
0721 static void __exit pci_ep_cfs_exit(void)
0722 {
0723 configfs_unregister_default_group(controllers_group);
0724 configfs_unregister_default_group(functions_group);
0725 configfs_unregister_subsystem(&pci_ep_cfs_subsys);
0726 }
0727 module_exit(pci_ep_cfs_exit);
0728
0729 MODULE_DESCRIPTION("PCI EP CONFIGFS");
0730 MODULE_AUTHOR("Kishon Vijay Abraham I <kishon@ti.com>");
0731 MODULE_LICENSE("GPL v2");