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