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

rapidio: make enumeration/discovery configurable

Systems that use RapidIO fabric may need to implement their own
enumeration and discovery methods which are better suitable for needs of
a target application.

The following set of patches is intended to simplify process of
introduction of new RapidIO fabric enumeration/discovery methods.

The first patch offers ability to add new RapidIO enumeration/discovery
methods using kernel configuration options. This new configuration
option mechanism allows to select statically linked or modular
enumeration/discovery method(s) from the list of existing methods or use
external module(s).

This patch also updates the currently existing enumeration/discovery
code to be used as a statically linked or modular method.

The corresponding configuration option is named "Basic
enumeration/discovery" method. This is the only one configuration
option available today but new methods are expected to be introduced
after adoption of provided patches.

The second patch address a long time complaint of RapidIO subsystem
users regarding fabric enumeration/discovery start sequence. Existing
implementation offers only a boot-time enumeration/discovery start which
requires synchronized boot of all endpoints in RapidIO network. While
it works for small closed configurations with limited number of
endpoints, using this approach in systems with large number of endpoints
is quite challenging.

To eliminate requirement for synchronized start the second patch
introduces RapidIO enumeration/discovery start from user space.

For compatibility with the existing RapidIO subsystem implementation,
automatic boot time enumeration/discovery start can be configured in by
specifying "rio-scan.scan=1" command line parameter if statically linked
basic enumeration method is selected.

This patch:

Rework to implement RapidIO enumeration/discovery method selection
combined with ability to use enumeration/discovery as a kernel module.

This patch adds ability to introduce new RapidIO enumeration/discovery
methods using kernel configuration options. Configuration option
mechanism allows to select statically linked or modular
enumeration/discovery method from the list of existing methods or use
external modules. If a modular enumeration/discovery is selected each
RapidIO mport device can have its own method attached to it.

The existing enumeration/discovery code was updated to be used as
statically linked or modular method. This configuration option is named
"Basic enumeration/discovery" method.

Several common routines have been moved from rio-scan.c to make them
available to other enumeration methods and reduce number of exported
symbols.

Signed-off-by: Alexandre Bounine <alexandre.bounine@idt.com>
Cc: Matt Porter <mporter@kernel.crashing.org>
Cc: Li Yang <leoli@freescale.com>
Cc: Kumar Gala <galak@kernel.crashing.org>
Cc: Andre van Herk <andre.van.herk@Prodrive.nl>
Cc: Micha Nelissen <micha.nelissen@Prodrive.nl>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Alexandre Bounine and committed by
Linus Torvalds
a11650e1 585dc0c2

+304 -139
+20
drivers/rapidio/Kconfig
··· 47 47 48 48 If you are unsure about this, say N here. 49 49 50 + choice 51 + prompt "Enumeration method" 52 + depends on RAPIDIO 53 + default RAPIDIO_ENUM_BASIC 54 + help 55 + There are different enumeration and discovery mechanisms offered 56 + for RapidIO subsystem. You may select single built-in method or 57 + or any number of methods to be built as modules. 58 + Selecting a built-in method disables use of loadable methods. 59 + 60 + If unsure, select Basic built-in. 61 + 62 + config RAPIDIO_ENUM_BASIC 63 + tristate "Basic" 64 + help 65 + This option includes basic RapidIO fabric enumeration and discovery 66 + mechanism similar to one described in RapidIO specification Annex 1. 67 + 68 + endchoice 69 + 50 70 source "drivers/rapidio/switches/Kconfig"
+2 -1
drivers/rapidio/Makefile
··· 1 1 # 2 2 # Makefile for RapidIO interconnect services 3 3 # 4 - obj-y += rio.o rio-access.o rio-driver.o rio-scan.o rio-sysfs.o 4 + obj-y += rio.o rio-access.o rio-driver.o rio-sysfs.o 5 + obj-$(CONFIG_RAPIDIO_ENUM_BASIC) += rio-scan.o 5 6 6 7 obj-$(CONFIG_RAPIDIO) += switches/ 7 8 obj-$(CONFIG_RAPIDIO) += devices/
+7
drivers/rapidio/rio-driver.c
··· 164 164 driver_unregister(&rdrv->driver); 165 165 } 166 166 167 + void rio_attach_device(struct rio_dev *rdev) 168 + { 169 + rdev->dev.bus = &rio_bus_type; 170 + rdev->dev.parent = &rio_bus; 171 + } 172 + EXPORT_SYMBOL_GPL(rio_attach_device); 173 + 167 174 /** 168 175 * rio_match_bus - Tell if a RIO device structure has a matching RIO driver device id structure 169 176 * @dev: the standard device structure to match against
+39 -127
drivers/rapidio/rio-scan.c
··· 37 37 38 38 #include "rio.h" 39 39 40 - LIST_HEAD(rio_devices); 41 - 42 40 static void rio_init_em(struct rio_dev *rdev); 43 - 44 - DEFINE_SPINLOCK(rio_global_list_lock); 45 41 46 42 static int next_destid = 0; 47 43 static int next_comptag = 1; ··· 323 327 } 324 328 325 329 /** 326 - * rio_switch_init - Sets switch operations for a particular vendor switch 327 - * @rdev: RIO device 328 - * @do_enum: Enumeration/Discovery mode flag 329 - * 330 - * Searches the RIO switch ops table for known switch types. If the vid 331 - * and did match a switch table entry, then call switch initialization 332 - * routine to setup switch-specific routines. 333 - */ 334 - static void rio_switch_init(struct rio_dev *rdev, int do_enum) 335 - { 336 - struct rio_switch_ops *cur = __start_rio_switch_ops; 337 - struct rio_switch_ops *end = __end_rio_switch_ops; 338 - 339 - while (cur < end) { 340 - if ((cur->vid == rdev->vid) && (cur->did == rdev->did)) { 341 - pr_debug("RIO: calling init routine for %s\n", 342 - rio_name(rdev)); 343 - cur->init_hook(rdev, do_enum); 344 - break; 345 - } 346 - cur++; 347 - } 348 - 349 - if ((cur >= end) && (rdev->pef & RIO_PEF_STD_RT)) { 350 - pr_debug("RIO: adding STD routing ops for %s\n", 351 - rio_name(rdev)); 352 - rdev->rswitch->add_entry = rio_std_route_add_entry; 353 - rdev->rswitch->get_entry = rio_std_route_get_entry; 354 - rdev->rswitch->clr_table = rio_std_route_clr_table; 355 - } 356 - 357 - if (!rdev->rswitch->add_entry || !rdev->rswitch->get_entry) 358 - printk(KERN_ERR "RIO: missing routing ops for %s\n", 359 - rio_name(rdev)); 360 - } 361 - 362 - /** 363 - * rio_add_device- Adds a RIO device to the device model 364 - * @rdev: RIO device 365 - * 366 - * Adds the RIO device to the global device list and adds the RIO 367 - * device to the RIO device list. Creates the generic sysfs nodes 368 - * for an RIO device. 369 - */ 370 - static int rio_add_device(struct rio_dev *rdev) 371 - { 372 - int err; 373 - 374 - err = device_add(&rdev->dev); 375 - if (err) 376 - return err; 377 - 378 - spin_lock(&rio_global_list_lock); 379 - list_add_tail(&rdev->global_list, &rio_devices); 380 - spin_unlock(&rio_global_list_lock); 381 - 382 - rio_create_sysfs_dev_files(rdev); 383 - 384 - return 0; 385 - } 386 - 387 - /** 388 - * rio_enable_rx_tx_port - enable input receiver and output transmitter of 389 - * given port 390 - * @port: Master port associated with the RIO network 391 - * @local: local=1 select local port otherwise a far device is reached 392 - * @destid: Destination ID of the device to check host bit 393 - * @hopcount: Number of hops to reach the target 394 - * @port_num: Port (-number on switch) to enable on a far end device 395 - * 396 - * Returns 0 or 1 from on General Control Command and Status Register 397 - * (EXT_PTR+0x3C) 398 - */ 399 - inline int rio_enable_rx_tx_port(struct rio_mport *port, 400 - int local, u16 destid, 401 - u8 hopcount, u8 port_num) { 402 - #ifdef CONFIG_RAPIDIO_ENABLE_RX_TX_PORTS 403 - u32 regval; 404 - u32 ext_ftr_ptr; 405 - 406 - /* 407 - * enable rx input tx output port 408 - */ 409 - pr_debug("rio_enable_rx_tx_port(local = %d, destid = %d, hopcount = " 410 - "%d, port_num = %d)\n", local, destid, hopcount, port_num); 411 - 412 - ext_ftr_ptr = rio_mport_get_physefb(port, local, destid, hopcount); 413 - 414 - if (local) { 415 - rio_local_read_config_32(port, ext_ftr_ptr + 416 - RIO_PORT_N_CTL_CSR(0), 417 - &regval); 418 - } else { 419 - if (rio_mport_read_config_32(port, destid, hopcount, 420 - ext_ftr_ptr + RIO_PORT_N_CTL_CSR(port_num), &regval) < 0) 421 - return -EIO; 422 - } 423 - 424 - if (regval & RIO_PORT_N_CTL_P_TYP_SER) { 425 - /* serial */ 426 - regval = regval | RIO_PORT_N_CTL_EN_RX_SER 427 - | RIO_PORT_N_CTL_EN_TX_SER; 428 - } else { 429 - /* parallel */ 430 - regval = regval | RIO_PORT_N_CTL_EN_RX_PAR 431 - | RIO_PORT_N_CTL_EN_TX_PAR; 432 - } 433 - 434 - if (local) { 435 - rio_local_write_config_32(port, ext_ftr_ptr + 436 - RIO_PORT_N_CTL_CSR(0), regval); 437 - } else { 438 - if (rio_mport_write_config_32(port, destid, hopcount, 439 - ext_ftr_ptr + RIO_PORT_N_CTL_CSR(port_num), regval) < 0) 440 - return -EIO; 441 - } 442 - #endif 443 - return 0; 444 - } 445 - 446 - /** 447 330 * rio_setup_device- Allocates and sets up a RIO device 448 331 * @net: RIO network 449 332 * @port: Master port to send transactions ··· 462 587 rdev->destid); 463 588 } 464 589 465 - rdev->dev.bus = &rio_bus_type; 466 - rdev->dev.parent = &rio_bus; 590 + rio_attach_device(rdev); 467 591 468 592 device_initialize(&rdev->dev); 469 593 rdev->dev.release = rio_release_dev; ··· 1295 1421 bail: 1296 1422 return -EBUSY; 1297 1423 } 1424 + 1425 + static struct rio_scan rio_scan_ops = { 1426 + .enumerate = rio_enum_mport, 1427 + .discover = rio_disc_mport, 1428 + }; 1429 + 1430 + static bool scan; 1431 + module_param(scan, bool, 0); 1432 + MODULE_PARM_DESC(scan, "Start RapidIO network enumeration/discovery " 1433 + "(default = 0)"); 1434 + 1435 + /** 1436 + * rio_basic_attach: 1437 + * 1438 + * When this enumeration/discovery method is loaded as a module this function 1439 + * registers its specific enumeration and discover routines for all available 1440 + * RapidIO mport devices. The "scan" command line parameter controls ability of 1441 + * the module to start RapidIO enumeration/discovery automatically. 1442 + * 1443 + * Returns 0 for success or -EIO if unable to register itself. 1444 + * 1445 + * This enumeration/discovery method cannot be unloaded and therefore does not 1446 + * provide a matching cleanup_module routine. 1447 + */ 1448 + 1449 + static int __init rio_basic_attach(void) 1450 + { 1451 + if (rio_register_scan(RIO_MPORT_ANY, &rio_scan_ops)) 1452 + return -EIO; 1453 + if (scan) 1454 + rio_init_mports(); 1455 + return 0; 1456 + } 1457 + 1458 + late_initcall(rio_basic_attach); 1459 + 1460 + MODULE_DESCRIPTION("Basic RapidIO enumeration/discovery"); 1461 + MODULE_LICENSE("GPL");
+215 -7
drivers/rapidio/rio.c
··· 31 31 32 32 #include "rio.h" 33 33 34 + static LIST_HEAD(rio_devices); 35 + static DEFINE_SPINLOCK(rio_global_list_lock); 36 + 34 37 static LIST_HEAD(rio_mports); 38 + static DEFINE_MUTEX(rio_mport_list_lock); 35 39 static unsigned char next_portid; 36 40 static DEFINE_SPINLOCK(rio_mmap_lock); 37 41 ··· 55 51 56 52 return (RIO_GET_DID(port->sys_size, result)); 57 53 } 54 + 55 + /** 56 + * rio_add_device- Adds a RIO device to the device model 57 + * @rdev: RIO device 58 + * 59 + * Adds the RIO device to the global device list and adds the RIO 60 + * device to the RIO device list. Creates the generic sysfs nodes 61 + * for an RIO device. 62 + */ 63 + int rio_add_device(struct rio_dev *rdev) 64 + { 65 + int err; 66 + 67 + err = device_add(&rdev->dev); 68 + if (err) 69 + return err; 70 + 71 + spin_lock(&rio_global_list_lock); 72 + list_add_tail(&rdev->global_list, &rio_devices); 73 + spin_unlock(&rio_global_list_lock); 74 + 75 + rio_create_sysfs_dev_files(rdev); 76 + 77 + return 0; 78 + } 79 + EXPORT_SYMBOL_GPL(rio_add_device); 58 80 59 81 /** 60 82 * rio_request_inb_mbox - request inbound mailbox service ··· 519 489 520 490 return ext_ftr_ptr; 521 491 } 492 + EXPORT_SYMBOL_GPL(rio_mport_get_physefb); 522 493 523 494 /** 524 495 * rio_get_comptag - Begin or continue searching for a RIO device by component tag ··· 552 521 spin_unlock(&rio_global_list_lock); 553 522 return rdev; 554 523 } 524 + EXPORT_SYMBOL_GPL(rio_get_comptag); 555 525 556 526 /** 557 527 * rio_set_port_lockout - Sets/clears LOCKOUT bit (RIO EM 1.3) for a switch port. ··· 577 545 regval); 578 546 return 0; 579 547 } 548 + EXPORT_SYMBOL_GPL(rio_set_port_lockout); 549 + 550 + /** 551 + * rio_switch_init - Sets switch operations for a particular vendor switch 552 + * @rdev: RIO device 553 + * @do_enum: Enumeration/Discovery mode flag 554 + * 555 + * Searches the RIO switch ops table for known switch types. If the vid 556 + * and did match a switch table entry, then call switch initialization 557 + * routine to setup switch-specific routines. 558 + */ 559 + void rio_switch_init(struct rio_dev *rdev, int do_enum) 560 + { 561 + struct rio_switch_ops *cur = __start_rio_switch_ops; 562 + struct rio_switch_ops *end = __end_rio_switch_ops; 563 + 564 + while (cur < end) { 565 + if ((cur->vid == rdev->vid) && (cur->did == rdev->did)) { 566 + pr_debug("RIO: calling init routine for %s\n", 567 + rio_name(rdev)); 568 + cur->init_hook(rdev, do_enum); 569 + break; 570 + } 571 + cur++; 572 + } 573 + 574 + if ((cur >= end) && (rdev->pef & RIO_PEF_STD_RT)) { 575 + pr_debug("RIO: adding STD routing ops for %s\n", 576 + rio_name(rdev)); 577 + rdev->rswitch->add_entry = rio_std_route_add_entry; 578 + rdev->rswitch->get_entry = rio_std_route_get_entry; 579 + rdev->rswitch->clr_table = rio_std_route_clr_table; 580 + } 581 + 582 + if (!rdev->rswitch->add_entry || !rdev->rswitch->get_entry) 583 + printk(KERN_ERR "RIO: missing routing ops for %s\n", 584 + rio_name(rdev)); 585 + } 586 + EXPORT_SYMBOL_GPL(rio_switch_init); 587 + 588 + /** 589 + * rio_enable_rx_tx_port - enable input receiver and output transmitter of 590 + * given port 591 + * @port: Master port associated with the RIO network 592 + * @local: local=1 select local port otherwise a far device is reached 593 + * @destid: Destination ID of the device to check host bit 594 + * @hopcount: Number of hops to reach the target 595 + * @port_num: Port (-number on switch) to enable on a far end device 596 + * 597 + * Returns 0 or 1 from on General Control Command and Status Register 598 + * (EXT_PTR+0x3C) 599 + */ 600 + int rio_enable_rx_tx_port(struct rio_mport *port, 601 + int local, u16 destid, 602 + u8 hopcount, u8 port_num) 603 + { 604 + #ifdef CONFIG_RAPIDIO_ENABLE_RX_TX_PORTS 605 + u32 regval; 606 + u32 ext_ftr_ptr; 607 + 608 + /* 609 + * enable rx input tx output port 610 + */ 611 + pr_debug("rio_enable_rx_tx_port(local = %d, destid = %d, hopcount = " 612 + "%d, port_num = %d)\n", local, destid, hopcount, port_num); 613 + 614 + ext_ftr_ptr = rio_mport_get_physefb(port, local, destid, hopcount); 615 + 616 + if (local) { 617 + rio_local_read_config_32(port, ext_ftr_ptr + 618 + RIO_PORT_N_CTL_CSR(0), 619 + &regval); 620 + } else { 621 + if (rio_mport_read_config_32(port, destid, hopcount, 622 + ext_ftr_ptr + RIO_PORT_N_CTL_CSR(port_num), &regval) < 0) 623 + return -EIO; 624 + } 625 + 626 + if (regval & RIO_PORT_N_CTL_P_TYP_SER) { 627 + /* serial */ 628 + regval = regval | RIO_PORT_N_CTL_EN_RX_SER 629 + | RIO_PORT_N_CTL_EN_TX_SER; 630 + } else { 631 + /* parallel */ 632 + regval = regval | RIO_PORT_N_CTL_EN_RX_PAR 633 + | RIO_PORT_N_CTL_EN_TX_PAR; 634 + } 635 + 636 + if (local) { 637 + rio_local_write_config_32(port, ext_ftr_ptr + 638 + RIO_PORT_N_CTL_CSR(0), regval); 639 + } else { 640 + if (rio_mport_write_config_32(port, destid, hopcount, 641 + ext_ftr_ptr + RIO_PORT_N_CTL_CSR(port_num), regval) < 0) 642 + return -EIO; 643 + } 644 + #endif 645 + return 0; 646 + } 647 + EXPORT_SYMBOL_GPL(rio_enable_rx_tx_port); 648 + 580 649 581 650 /** 582 651 * rio_chk_dev_route - Validate route to the specified device. ··· 743 610 744 611 return 0; 745 612 } 613 + EXPORT_SYMBOL_GPL(rio_mport_chk_dev_access); 746 614 747 615 /** 748 616 * rio_chk_dev_access - Validate access to the specified device. ··· 1075 941 return RIO_GET_BLOCK_ID(reg_val); 1076 942 } 1077 943 } 944 + EXPORT_SYMBOL_GPL(rio_mport_get_efb); 1078 945 1079 946 /** 1080 947 * rio_mport_get_feature - query for devices' extended features ··· 1132 997 1133 998 return 0; 1134 999 } 1000 + EXPORT_SYMBOL_GPL(rio_mport_get_feature); 1135 1001 1136 1002 /** 1137 1003 * rio_get_asm - Begin or continue searching for a RIO device by vid/did/asm_vid/asm_did ··· 1382 1246 1383 1247 #endif /* CONFIG_RAPIDIO_DMA_ENGINE */ 1384 1248 1249 + /** 1250 + * rio_register_scan - enumeration/discovery method registration interface 1251 + * @mport_id: mport device ID for which fabric scan routine has to be set 1252 + * (RIO_MPORT_ANY = set for all available mports) 1253 + * @scan_ops: enumeration/discovery control structure 1254 + * 1255 + * Assigns enumeration or discovery method to the specified mport device (or all 1256 + * available mports if RIO_MPORT_ANY is specified). 1257 + * Returns error if the mport already has an enumerator attached to it. 1258 + * In case of RIO_MPORT_ANY ignores ports with valid scan routines and returns 1259 + * an error if was unable to find at least one available mport. 1260 + */ 1261 + int rio_register_scan(int mport_id, struct rio_scan *scan_ops) 1262 + { 1263 + struct rio_mport *port; 1264 + int rc = -EBUSY; 1265 + 1266 + mutex_lock(&rio_mport_list_lock); 1267 + list_for_each_entry(port, &rio_mports, node) { 1268 + if (port->id == mport_id || mport_id == RIO_MPORT_ANY) { 1269 + if (port->nscan && mport_id == RIO_MPORT_ANY) 1270 + continue; 1271 + else if (port->nscan) 1272 + break; 1273 + 1274 + port->nscan = scan_ops; 1275 + rc = 0; 1276 + 1277 + if (mport_id != RIO_MPORT_ANY) 1278 + break; 1279 + } 1280 + } 1281 + mutex_unlock(&rio_mport_list_lock); 1282 + 1283 + return rc; 1284 + } 1285 + EXPORT_SYMBOL_GPL(rio_register_scan); 1286 + 1287 + /** 1288 + * rio_unregister_scan - removes enumeration/discovery method from mport 1289 + * @mport_id: mport device ID for which fabric scan routine has to be 1290 + * unregistered (RIO_MPORT_ANY = set for all available mports) 1291 + * 1292 + * Removes enumeration or discovery method assigned to the specified mport 1293 + * device (or all available mports if RIO_MPORT_ANY is specified). 1294 + */ 1295 + int rio_unregister_scan(int mport_id) 1296 + { 1297 + struct rio_mport *port; 1298 + 1299 + mutex_lock(&rio_mport_list_lock); 1300 + list_for_each_entry(port, &rio_mports, node) { 1301 + if (port->id == mport_id || mport_id == RIO_MPORT_ANY) { 1302 + if (port->nscan) 1303 + port->nscan = NULL; 1304 + if (mport_id != RIO_MPORT_ANY) 1305 + break; 1306 + } 1307 + } 1308 + mutex_unlock(&rio_mport_list_lock); 1309 + 1310 + return 0; 1311 + } 1312 + EXPORT_SYMBOL_GPL(rio_unregister_scan); 1313 + 1385 1314 static void rio_fixup_device(struct rio_dev *dev) 1386 1315 { 1387 1316 } ··· 1475 1274 work = container_of(_work, struct rio_disc_work, work); 1476 1275 pr_debug("RIO: discovery work for mport %d %s\n", 1477 1276 work->mport->id, work->mport->name); 1478 - rio_disc_mport(work->mport); 1277 + work->mport->nscan->discover(work->mport); 1479 1278 } 1480 1279 1481 1280 int rio_init_mports(void) ··· 1491 1290 * First, run enumerations and check if we need to perform discovery 1492 1291 * on any of the registered mports. 1493 1292 */ 1293 + mutex_lock(&rio_mport_list_lock); 1494 1294 list_for_each_entry(port, &rio_mports, node) { 1495 - if (port->host_deviceid >= 0) 1496 - rio_enum_mport(port); 1497 - else 1295 + if (port->host_deviceid >= 0) { 1296 + if (port->nscan) 1297 + port->nscan->enumerate(port); 1298 + } else 1498 1299 n++; 1499 1300 } 1301 + mutex_unlock(&rio_mport_list_lock); 1500 1302 1501 1303 if (!n) 1502 1304 goto no_disc; ··· 1526 1322 } 1527 1323 1528 1324 n = 0; 1325 + mutex_lock(&rio_mport_list_lock); 1529 1326 list_for_each_entry(port, &rio_mports, node) { 1530 - if (port->host_deviceid < 0) { 1327 + if (port->host_deviceid < 0 && port->nscan) { 1531 1328 work[n].mport = port; 1532 1329 INIT_WORK(&work[n].work, disc_work_handler); 1533 1330 queue_work(rio_wq, &work[n].work); 1534 1331 n++; 1535 1332 } 1536 1333 } 1334 + mutex_unlock(&rio_mport_list_lock); 1537 1335 1538 1336 flush_workqueue(rio_wq); 1539 1337 pr_debug("RIO: destroy discovery workqueue\n"); ··· 1547 1341 1548 1342 return 0; 1549 1343 } 1550 - 1551 - device_initcall_sync(rio_init_mports); 1552 1344 1553 1345 static int hdids[RIO_MAX_MPORTS + 1]; 1554 1346 ··· 1575 1371 1576 1372 port->id = next_portid++; 1577 1373 port->host_deviceid = rio_get_hdid(port->id); 1374 + port->nscan = NULL; 1375 + mutex_lock(&rio_mport_list_lock); 1578 1376 list_add_tail(&port->node, &rio_mports); 1377 + mutex_unlock(&rio_mport_list_lock); 1579 1378 return 0; 1580 1379 } 1581 1380 ··· 1593 1386 EXPORT_SYMBOL_GPL(rio_release_inb_mbox); 1594 1387 EXPORT_SYMBOL_GPL(rio_request_outb_mbox); 1595 1388 EXPORT_SYMBOL_GPL(rio_release_outb_mbox); 1389 + EXPORT_SYMBOL_GPL(rio_init_mports);
+8 -3
drivers/rapidio/rio.h
··· 15 15 #include <linux/rio.h> 16 16 17 17 #define RIO_MAX_CHK_RETRY 3 18 + #define RIO_MPORT_ANY (-1) 18 19 19 20 /* Functions internal to the RIO core code */ 20 21 ··· 28 27 extern int rio_mport_chk_dev_access(struct rio_mport *mport, u16 destid, 29 28 u8 hopcount); 30 29 extern int rio_create_sysfs_dev_files(struct rio_dev *rdev); 31 - extern int rio_enum_mport(struct rio_mport *mport); 32 - extern int rio_disc_mport(struct rio_mport *mport); 33 30 extern int rio_std_route_add_entry(struct rio_mport *mport, u16 destid, 34 31 u8 hopcount, u16 table, u16 route_destid, 35 32 u8 route_port); ··· 38 39 u8 hopcount, u16 table); 39 40 extern int rio_set_port_lockout(struct rio_dev *rdev, u32 pnum, int lock); 40 41 extern struct rio_dev *rio_get_comptag(u32 comp_tag, struct rio_dev *from); 42 + extern int rio_add_device(struct rio_dev *rdev); 43 + extern void rio_switch_init(struct rio_dev *rdev, int do_enum); 44 + extern int rio_enable_rx_tx_port(struct rio_mport *port, int local, u16 destid, 45 + u8 hopcount, u8 port_num); 46 + extern int rio_register_scan(int mport_id, struct rio_scan *scan_ops); 47 + extern int rio_unregister_scan(int mport_id); 48 + extern void rio_attach_device(struct rio_dev *rdev); 41 49 42 50 /* Structures internal to the RIO core code */ 43 51 extern struct device_attribute rio_dev_attrs[]; 44 - extern spinlock_t rio_global_list_lock; 45 52 46 53 extern struct rio_switch_ops __start_rio_switch_ops[]; 47 54 extern struct rio_switch_ops __end_rio_switch_ops[];
+12 -1
include/linux/rio.h
··· 83 83 84 84 extern struct bus_type rio_bus_type; 85 85 extern struct device rio_bus; 86 - extern struct list_head rio_devices; /* list of all devices */ 87 86 88 87 struct rio_mport; 89 88 struct rio_dev; ··· 236 237 * @name: Port name string 237 238 * @priv: Master port private data 238 239 * @dma: DMA device associated with mport 240 + * @nscan: RapidIO network enumeration/discovery operations 239 241 */ 240 242 struct rio_mport { 241 243 struct list_head dbells; /* list of doorbell events */ ··· 262 262 #ifdef CONFIG_RAPIDIO_DMA_ENGINE 263 263 struct dma_device dma; 264 264 #endif 265 + struct rio_scan *nscan; 265 266 }; 266 267 267 268 struct rio_id_table { ··· 460 459 return container_of(ddev, struct rio_mport, dma); 461 460 } 462 461 #endif /* CONFIG_RAPIDIO_DMA_ENGINE */ 462 + 463 + /** 464 + * struct rio_scan - RIO enumeration and discovery operations 465 + * @enumerate: Callback to perform RapidIO fabric enumeration. 466 + * @discover: Callback to perform RapidIO fabric discovery. 467 + */ 468 + struct rio_scan { 469 + int (*enumerate)(struct rio_mport *mport); 470 + int (*discover)(struct rio_mport *mport); 471 + }; 463 472 464 473 /* Architecture and hardware-specific functions */ 465 474 extern int rio_register_mport(struct rio_mport *);
+1
include/linux/rio_drv.h
··· 433 433 extern struct rio_dev *rio_get_device(u16 vid, u16 did, struct rio_dev *from); 434 434 extern struct rio_dev *rio_get_asm(u16 vid, u16 did, u16 asm_vid, u16 asm_did, 435 435 struct rio_dev *from); 436 + extern int rio_init_mports(void); 436 437 437 438 #endif /* LINUX_RIO_DRV_H */