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"); 566