root/drivers/pci/endpoint/pci-ep-cfs.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. to_pci_epf_group
  2. to_pci_epc_group
  3. pci_epc_start_store
  4. pci_epc_start_show
  5. pci_epc_epf_link
  6. pci_epc_epf_unlink
  7. pci_ep_cfs_add_epc_group
  8. pci_ep_cfs_remove_epc_group
  9. pci_epf_msi_interrupts_store
  10. pci_epf_msi_interrupts_show
  11. pci_epf_msix_interrupts_store
  12. pci_epf_msix_interrupts_show
  13. pci_epf_release
  14. pci_epf_make
  15. pci_epf_drop
  16. pci_ep_cfs_add_epf_group
  17. pci_ep_cfs_remove_epf_group
  18. pci_ep_cfs_init
  19. pci_ep_cfs_exit

   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 pci_epf *epf;
  25         int index;
  26 };
  27 
  28 struct pci_epc_group {
  29         struct config_group group;
  30         struct pci_epc *epc;
  31         bool start;
  32         unsigned long function_num_map;
  33 };
  34 
  35 static inline struct pci_epf_group *to_pci_epf_group(struct config_item *item)
  36 {
  37         return container_of(to_config_group(item), struct pci_epf_group, group);
  38 }
  39 
  40 static inline struct pci_epc_group *to_pci_epc_group(struct config_item *item)
  41 {
  42         return container_of(to_config_group(item), struct pci_epc_group, group);
  43 }
  44 
  45 static ssize_t pci_epc_start_store(struct config_item *item, const char *page,
  46                                    size_t len)
  47 {
  48         int ret;
  49         bool start;
  50         struct pci_epc *epc;
  51         struct pci_epc_group *epc_group = to_pci_epc_group(item);
  52 
  53         epc = epc_group->epc;
  54 
  55         ret = kstrtobool(page, &start);
  56         if (ret)
  57                 return ret;
  58 
  59         if (!start) {
  60                 pci_epc_stop(epc);
  61                 return len;
  62         }
  63 
  64         ret = pci_epc_start(epc);
  65         if (ret) {
  66                 dev_err(&epc->dev, "failed to start endpoint controller\n");
  67                 return -EINVAL;
  68         }
  69 
  70         epc_group->start = start;
  71 
  72         return len;
  73 }
  74 
  75 static ssize_t pci_epc_start_show(struct config_item *item, char *page)
  76 {
  77         return sprintf(page, "%d\n",
  78                        to_pci_epc_group(item)->start);
  79 }
  80 
  81 CONFIGFS_ATTR(pci_epc_, start);
  82 
  83 static struct configfs_attribute *pci_epc_attrs[] = {
  84         &pci_epc_attr_start,
  85         NULL,
  86 };
  87 
  88 static int pci_epc_epf_link(struct config_item *epc_item,
  89                             struct config_item *epf_item)
  90 {
  91         int ret;
  92         u32 func_no = 0;
  93         struct pci_epf_group *epf_group = to_pci_epf_group(epf_item);
  94         struct pci_epc_group *epc_group = to_pci_epc_group(epc_item);
  95         struct pci_epc *epc = epc_group->epc;
  96         struct pci_epf *epf = epf_group->epf;
  97 
  98         func_no = find_first_zero_bit(&epc_group->function_num_map,
  99                                       BITS_PER_LONG);
 100         if (func_no >= BITS_PER_LONG)
 101                 return -EINVAL;
 102 
 103         set_bit(func_no, &epc_group->function_num_map);
 104         epf->func_no = func_no;
 105 
 106         ret = pci_epc_add_epf(epc, epf);
 107         if (ret)
 108                 goto err_add_epf;
 109 
 110         ret = pci_epf_bind(epf);
 111         if (ret)
 112                 goto err_epf_bind;
 113 
 114         return 0;
 115 
 116 err_epf_bind:
 117         pci_epc_remove_epf(epc, epf);
 118 
 119 err_add_epf:
 120         clear_bit(func_no, &epc_group->function_num_map);
 121 
 122         return ret;
 123 }
 124 
 125 static void pci_epc_epf_unlink(struct config_item *epc_item,
 126                                struct config_item *epf_item)
 127 {
 128         struct pci_epc *epc;
 129         struct pci_epf *epf;
 130         struct pci_epf_group *epf_group = to_pci_epf_group(epf_item);
 131         struct pci_epc_group *epc_group = to_pci_epc_group(epc_item);
 132 
 133         WARN_ON_ONCE(epc_group->start);
 134 
 135         epc = epc_group->epc;
 136         epf = epf_group->epf;
 137         clear_bit(epf->func_no, &epc_group->function_num_map);
 138         pci_epf_unbind(epf);
 139         pci_epc_remove_epf(epc, epf);
 140 }
 141 
 142 static struct configfs_item_operations pci_epc_item_ops = {
 143         .allow_link     = pci_epc_epf_link,
 144         .drop_link      = pci_epc_epf_unlink,
 145 };
 146 
 147 static const struct config_item_type pci_epc_type = {
 148         .ct_item_ops    = &pci_epc_item_ops,
 149         .ct_attrs       = pci_epc_attrs,
 150         .ct_owner       = THIS_MODULE,
 151 };
 152 
 153 struct config_group *pci_ep_cfs_add_epc_group(const char *name)
 154 {
 155         int ret;
 156         struct pci_epc *epc;
 157         struct config_group *group;
 158         struct pci_epc_group *epc_group;
 159 
 160         epc_group = kzalloc(sizeof(*epc_group), GFP_KERNEL);
 161         if (!epc_group) {
 162                 ret = -ENOMEM;
 163                 goto err;
 164         }
 165 
 166         group = &epc_group->group;
 167 
 168         config_group_init_type_name(group, name, &pci_epc_type);
 169         ret = configfs_register_group(controllers_group, group);
 170         if (ret) {
 171                 pr_err("failed to register configfs group for %s\n", name);
 172                 goto err_register_group;
 173         }
 174 
 175         epc = pci_epc_get(name);
 176         if (IS_ERR(epc)) {
 177                 ret = PTR_ERR(epc);
 178                 goto err_epc_get;
 179         }
 180 
 181         epc_group->epc = epc;
 182 
 183         return group;
 184 
 185 err_epc_get:
 186         configfs_unregister_group(group);
 187 
 188 err_register_group:
 189         kfree(epc_group);
 190 
 191 err:
 192         return ERR_PTR(ret);
 193 }
 194 EXPORT_SYMBOL(pci_ep_cfs_add_epc_group);
 195 
 196 void pci_ep_cfs_remove_epc_group(struct config_group *group)
 197 {
 198         struct pci_epc_group *epc_group;
 199 
 200         if (!group)
 201                 return;
 202 
 203         epc_group = container_of(group, struct pci_epc_group, group);
 204         pci_epc_put(epc_group->epc);
 205         configfs_unregister_group(&epc_group->group);
 206         kfree(epc_group);
 207 }
 208 EXPORT_SYMBOL(pci_ep_cfs_remove_epc_group);
 209 
 210 #define PCI_EPF_HEADER_R(_name)                                                \
 211 static ssize_t pci_epf_##_name##_show(struct config_item *item, char *page)    \
 212 {                                                                              \
 213         struct pci_epf *epf = to_pci_epf_group(item)->epf;                     \
 214         if (WARN_ON_ONCE(!epf->header))                                        \
 215                 return -EINVAL;                                                \
 216         return sprintf(page, "0x%04x\n", epf->header->_name);                  \
 217 }
 218 
 219 #define PCI_EPF_HEADER_W_u32(_name)                                            \
 220 static ssize_t pci_epf_##_name##_store(struct config_item *item,               \
 221                                        const char *page, size_t len)           \
 222 {                                                                              \
 223         u32 val;                                                               \
 224         int ret;                                                               \
 225         struct pci_epf *epf = to_pci_epf_group(item)->epf;                     \
 226         if (WARN_ON_ONCE(!epf->header))                                        \
 227                 return -EINVAL;                                                \
 228         ret = kstrtou32(page, 0, &val);                                        \
 229         if (ret)                                                               \
 230                 return ret;                                                    \
 231         epf->header->_name = val;                                              \
 232         return len;                                                            \
 233 }
 234 
 235 #define PCI_EPF_HEADER_W_u16(_name)                                            \
 236 static ssize_t pci_epf_##_name##_store(struct config_item *item,               \
 237                                        const char *page, size_t len)           \
 238 {                                                                              \
 239         u16 val;                                                               \
 240         int ret;                                                               \
 241         struct pci_epf *epf = to_pci_epf_group(item)->epf;                     \
 242         if (WARN_ON_ONCE(!epf->header))                                        \
 243                 return -EINVAL;                                                \
 244         ret = kstrtou16(page, 0, &val);                                        \
 245         if (ret)                                                               \
 246                 return ret;                                                    \
 247         epf->header->_name = val;                                              \
 248         return len;                                                            \
 249 }
 250 
 251 #define PCI_EPF_HEADER_W_u8(_name)                                             \
 252 static ssize_t pci_epf_##_name##_store(struct config_item *item,               \
 253                                        const char *page, size_t len)           \
 254 {                                                                              \
 255         u8 val;                                                                \
 256         int ret;                                                               \
 257         struct pci_epf *epf = to_pci_epf_group(item)->epf;                     \
 258         if (WARN_ON_ONCE(!epf->header))                                        \
 259                 return -EINVAL;                                                \
 260         ret = kstrtou8(page, 0, &val);                                         \
 261         if (ret)                                                               \
 262                 return ret;                                                    \
 263         epf->header->_name = val;                                              \
 264         return len;                                                            \
 265 }
 266 
 267 static ssize_t pci_epf_msi_interrupts_store(struct config_item *item,
 268                                             const char *page, size_t len)
 269 {
 270         u8 val;
 271         int ret;
 272 
 273         ret = kstrtou8(page, 0, &val);
 274         if (ret)
 275                 return ret;
 276 
 277         to_pci_epf_group(item)->epf->msi_interrupts = val;
 278 
 279         return len;
 280 }
 281 
 282 static ssize_t pci_epf_msi_interrupts_show(struct config_item *item,
 283                                            char *page)
 284 {
 285         return sprintf(page, "%d\n",
 286                        to_pci_epf_group(item)->epf->msi_interrupts);
 287 }
 288 
 289 static ssize_t pci_epf_msix_interrupts_store(struct config_item *item,
 290                                              const char *page, size_t len)
 291 {
 292         u16 val;
 293         int ret;
 294 
 295         ret = kstrtou16(page, 0, &val);
 296         if (ret)
 297                 return ret;
 298 
 299         to_pci_epf_group(item)->epf->msix_interrupts = val;
 300 
 301         return len;
 302 }
 303 
 304 static ssize_t pci_epf_msix_interrupts_show(struct config_item *item,
 305                                             char *page)
 306 {
 307         return sprintf(page, "%d\n",
 308                        to_pci_epf_group(item)->epf->msix_interrupts);
 309 }
 310 
 311 PCI_EPF_HEADER_R(vendorid)
 312 PCI_EPF_HEADER_W_u16(vendorid)
 313 
 314 PCI_EPF_HEADER_R(deviceid)
 315 PCI_EPF_HEADER_W_u16(deviceid)
 316 
 317 PCI_EPF_HEADER_R(revid)
 318 PCI_EPF_HEADER_W_u8(revid)
 319 
 320 PCI_EPF_HEADER_R(progif_code)
 321 PCI_EPF_HEADER_W_u8(progif_code)
 322 
 323 PCI_EPF_HEADER_R(subclass_code)
 324 PCI_EPF_HEADER_W_u8(subclass_code)
 325 
 326 PCI_EPF_HEADER_R(baseclass_code)
 327 PCI_EPF_HEADER_W_u8(baseclass_code)
 328 
 329 PCI_EPF_HEADER_R(cache_line_size)
 330 PCI_EPF_HEADER_W_u8(cache_line_size)
 331 
 332 PCI_EPF_HEADER_R(subsys_vendor_id)
 333 PCI_EPF_HEADER_W_u16(subsys_vendor_id)
 334 
 335 PCI_EPF_HEADER_R(subsys_id)
 336 PCI_EPF_HEADER_W_u16(subsys_id)
 337 
 338 PCI_EPF_HEADER_R(interrupt_pin)
 339 PCI_EPF_HEADER_W_u8(interrupt_pin)
 340 
 341 CONFIGFS_ATTR(pci_epf_, vendorid);
 342 CONFIGFS_ATTR(pci_epf_, deviceid);
 343 CONFIGFS_ATTR(pci_epf_, revid);
 344 CONFIGFS_ATTR(pci_epf_, progif_code);
 345 CONFIGFS_ATTR(pci_epf_, subclass_code);
 346 CONFIGFS_ATTR(pci_epf_, baseclass_code);
 347 CONFIGFS_ATTR(pci_epf_, cache_line_size);
 348 CONFIGFS_ATTR(pci_epf_, subsys_vendor_id);
 349 CONFIGFS_ATTR(pci_epf_, subsys_id);
 350 CONFIGFS_ATTR(pci_epf_, interrupt_pin);
 351 CONFIGFS_ATTR(pci_epf_, msi_interrupts);
 352 CONFIGFS_ATTR(pci_epf_, msix_interrupts);
 353 
 354 static struct configfs_attribute *pci_epf_attrs[] = {
 355         &pci_epf_attr_vendorid,
 356         &pci_epf_attr_deviceid,
 357         &pci_epf_attr_revid,
 358         &pci_epf_attr_progif_code,
 359         &pci_epf_attr_subclass_code,
 360         &pci_epf_attr_baseclass_code,
 361         &pci_epf_attr_cache_line_size,
 362         &pci_epf_attr_subsys_vendor_id,
 363         &pci_epf_attr_subsys_id,
 364         &pci_epf_attr_interrupt_pin,
 365         &pci_epf_attr_msi_interrupts,
 366         &pci_epf_attr_msix_interrupts,
 367         NULL,
 368 };
 369 
 370 static void pci_epf_release(struct config_item *item)
 371 {
 372         struct pci_epf_group *epf_group = to_pci_epf_group(item);
 373 
 374         mutex_lock(&functions_mutex);
 375         idr_remove(&functions_idr, epf_group->index);
 376         mutex_unlock(&functions_mutex);
 377         pci_epf_destroy(epf_group->epf);
 378         kfree(epf_group);
 379 }
 380 
 381 static struct configfs_item_operations pci_epf_ops = {
 382         .release                = pci_epf_release,
 383 };
 384 
 385 static const struct config_item_type pci_epf_type = {
 386         .ct_item_ops    = &pci_epf_ops,
 387         .ct_attrs       = pci_epf_attrs,
 388         .ct_owner       = THIS_MODULE,
 389 };
 390 
 391 static struct config_group *pci_epf_make(struct config_group *group,
 392                                          const char *name)
 393 {
 394         struct pci_epf_group *epf_group;
 395         struct pci_epf *epf;
 396         char *epf_name;
 397         int index, err;
 398 
 399         epf_group = kzalloc(sizeof(*epf_group), GFP_KERNEL);
 400         if (!epf_group)
 401                 return ERR_PTR(-ENOMEM);
 402 
 403         mutex_lock(&functions_mutex);
 404         index = idr_alloc(&functions_idr, epf_group, 0, 0, GFP_KERNEL);
 405         mutex_unlock(&functions_mutex);
 406         if (index < 0) {
 407                 err = index;
 408                 goto free_group;
 409         }
 410 
 411         epf_group->index = index;
 412 
 413         config_group_init_type_name(&epf_group->group, name, &pci_epf_type);
 414 
 415         epf_name = kasprintf(GFP_KERNEL, "%s.%d",
 416                              group->cg_item.ci_name, epf_group->index);
 417         if (!epf_name) {
 418                 err = -ENOMEM;
 419                 goto remove_idr;
 420         }
 421 
 422         epf = pci_epf_create(epf_name);
 423         if (IS_ERR(epf)) {
 424                 pr_err("failed to create endpoint function device\n");
 425                 err = -EINVAL;
 426                 goto free_name;
 427         }
 428 
 429         epf_group->epf = epf;
 430 
 431         kfree(epf_name);
 432 
 433         return &epf_group->group;
 434 
 435 free_name:
 436         kfree(epf_name);
 437 
 438 remove_idr:
 439         mutex_lock(&functions_mutex);
 440         idr_remove(&functions_idr, epf_group->index);
 441         mutex_unlock(&functions_mutex);
 442 
 443 free_group:
 444         kfree(epf_group);
 445 
 446         return ERR_PTR(err);
 447 }
 448 
 449 static void pci_epf_drop(struct config_group *group, struct config_item *item)
 450 {
 451         config_item_put(item);
 452 }
 453 
 454 static struct configfs_group_operations pci_epf_group_ops = {
 455         .make_group     = &pci_epf_make,
 456         .drop_item      = &pci_epf_drop,
 457 };
 458 
 459 static const struct config_item_type pci_epf_group_type = {
 460         .ct_group_ops   = &pci_epf_group_ops,
 461         .ct_owner       = THIS_MODULE,
 462 };
 463 
 464 struct config_group *pci_ep_cfs_add_epf_group(const char *name)
 465 {
 466         struct config_group *group;
 467 
 468         group = configfs_register_default_group(functions_group, name,
 469                                                 &pci_epf_group_type);
 470         if (IS_ERR(group))
 471                 pr_err("failed to register configfs group for %s function\n",
 472                        name);
 473 
 474         return group;
 475 }
 476 EXPORT_SYMBOL(pci_ep_cfs_add_epf_group);
 477 
 478 void pci_ep_cfs_remove_epf_group(struct config_group *group)
 479 {
 480         if (IS_ERR_OR_NULL(group))
 481                 return;
 482 
 483         configfs_unregister_default_group(group);
 484 }
 485 EXPORT_SYMBOL(pci_ep_cfs_remove_epf_group);
 486 
 487 static const struct config_item_type pci_functions_type = {
 488         .ct_owner       = THIS_MODULE,
 489 };
 490 
 491 static const struct config_item_type pci_controllers_type = {
 492         .ct_owner       = THIS_MODULE,
 493 };
 494 
 495 static const struct config_item_type pci_ep_type = {
 496         .ct_owner       = THIS_MODULE,
 497 };
 498 
 499 static struct configfs_subsystem pci_ep_cfs_subsys = {
 500         .su_group = {
 501                 .cg_item = {
 502                         .ci_namebuf = "pci_ep",
 503                         .ci_type = &pci_ep_type,
 504                 },
 505         },
 506         .su_mutex = __MUTEX_INITIALIZER(pci_ep_cfs_subsys.su_mutex),
 507 };
 508 
 509 static int __init pci_ep_cfs_init(void)
 510 {
 511         int ret;
 512         struct config_group *root = &pci_ep_cfs_subsys.su_group;
 513 
 514         config_group_init(root);
 515 
 516         ret = configfs_register_subsystem(&pci_ep_cfs_subsys);
 517         if (ret) {
 518                 pr_err("Error %d while registering subsystem %s\n",
 519                        ret, root->cg_item.ci_namebuf);
 520                 goto err;
 521         }
 522 
 523         functions_group = configfs_register_default_group(root, "functions",
 524                                                           &pci_functions_type);
 525         if (IS_ERR(functions_group)) {
 526                 ret = PTR_ERR(functions_group);
 527                 pr_err("Error %d while registering functions group\n",
 528                        ret);
 529                 goto err_functions_group;
 530         }
 531 
 532         controllers_group =
 533                 configfs_register_default_group(root, "controllers",
 534                                                 &pci_controllers_type);
 535         if (IS_ERR(controllers_group)) {
 536                 ret = PTR_ERR(controllers_group);
 537                 pr_err("Error %d while registering controllers group\n",
 538                        ret);
 539                 goto err_controllers_group;
 540         }
 541 
 542         return 0;
 543 
 544 err_controllers_group:
 545         configfs_unregister_default_group(functions_group);
 546 
 547 err_functions_group:
 548         configfs_unregister_subsystem(&pci_ep_cfs_subsys);
 549 
 550 err:
 551         return ret;
 552 }
 553 module_init(pci_ep_cfs_init);
 554 
 555 static void __exit pci_ep_cfs_exit(void)
 556 {
 557         configfs_unregister_default_group(controllers_group);
 558         configfs_unregister_default_group(functions_group);
 559         configfs_unregister_subsystem(&pci_ep_cfs_subsys);
 560 }
 561 module_exit(pci_ep_cfs_exit);
 562 
 563 MODULE_DESCRIPTION("PCI EP CONFIGFS");
 564 MODULE_AUTHOR("Kishon Vijay Abraham I <kishon@ti.com>");
 565 MODULE_LICENSE("GPL v2");

/* [<][>][^][v][top][bottom][index][help] */