aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/rapidio
diff options
context:
space:
mode:
authorAlexandre Bounine <alexandre.bounine@idt.com>2013-05-24 18:55:05 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-05-24 19:22:50 -0400
commita11650e11093ed57dca78bf16e7836517c599098 (patch)
tree9823799d4c54337971b4654ea9e5510131dae9c5 /drivers/rapidio
parent585dc0c2f68981c02a0bb6fc8fe191a3f513959c (diff)
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>
Diffstat (limited to 'drivers/rapidio')
-rw-r--r--drivers/rapidio/Kconfig20
-rw-r--r--drivers/rapidio/Makefile3
-rw-r--r--drivers/rapidio/rio-driver.c7
-rw-r--r--drivers/rapidio/rio-scan.c166
-rw-r--r--drivers/rapidio/rio.c222
-rw-r--r--drivers/rapidio/rio.h11
6 files changed, 291 insertions, 138 deletions
diff --git a/drivers/rapidio/Kconfig b/drivers/rapidio/Kconfig
index 6194d35ebb97..5ab056494bbe 100644
--- a/drivers/rapidio/Kconfig
+++ b/drivers/rapidio/Kconfig
@@ -47,4 +47,24 @@ config RAPIDIO_DEBUG
47 47
48 If you are unsure about this, say N here. 48 If you are unsure about this, say N here.
49 49
50choice
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
62config 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
68endchoice
69
50source "drivers/rapidio/switches/Kconfig" 70source "drivers/rapidio/switches/Kconfig"
diff --git a/drivers/rapidio/Makefile b/drivers/rapidio/Makefile
index ec3fb8121004..3036702ffe8b 100644
--- a/drivers/rapidio/Makefile
+++ b/drivers/rapidio/Makefile
@@ -1,7 +1,8 @@
1# 1#
2# Makefile for RapidIO interconnect services 2# Makefile for RapidIO interconnect services
3# 3#
4obj-y += rio.o rio-access.o rio-driver.o rio-scan.o rio-sysfs.o 4obj-y += rio.o rio-access.o rio-driver.o rio-sysfs.o
5obj-$(CONFIG_RAPIDIO_ENUM_BASIC) += rio-scan.o
5 6
6obj-$(CONFIG_RAPIDIO) += switches/ 7obj-$(CONFIG_RAPIDIO) += switches/
7obj-$(CONFIG_RAPIDIO) += devices/ 8obj-$(CONFIG_RAPIDIO) += devices/
diff --git a/drivers/rapidio/rio-driver.c b/drivers/rapidio/rio-driver.c
index 0f4a53bdaa3c..55850bb21480 100644
--- a/drivers/rapidio/rio-driver.c
+++ b/drivers/rapidio/rio-driver.c
@@ -164,6 +164,13 @@ void rio_unregister_driver(struct rio_driver *rdrv)
164 driver_unregister(&rdrv->driver); 164 driver_unregister(&rdrv->driver);
165} 165}
166 166
167void rio_attach_device(struct rio_dev *rdev)
168{
169 rdev->dev.bus = &rio_bus_type;
170 rdev->dev.parent = &rio_bus;
171}
172EXPORT_SYMBOL_GPL(rio_attach_device);
173
167/** 174/**
168 * rio_match_bus - Tell if a RIO device structure has a matching RIO driver device id structure 175 * rio_match_bus - Tell if a RIO device structure has a matching RIO driver device id structure
169 * @dev: the standard device structure to match against 176 * @dev: the standard device structure to match against
diff --git a/drivers/rapidio/rio-scan.c b/drivers/rapidio/rio-scan.c
index a965acd3c0e4..7bdc67419cc3 100644
--- a/drivers/rapidio/rio-scan.c
+++ b/drivers/rapidio/rio-scan.c
@@ -37,12 +37,8 @@
37 37
38#include "rio.h" 38#include "rio.h"
39 39
40LIST_HEAD(rio_devices);
41
42static void rio_init_em(struct rio_dev *rdev); 40static void rio_init_em(struct rio_dev *rdev);
43 41
44DEFINE_SPINLOCK(rio_global_list_lock);
45
46static int next_destid = 0; 42static int next_destid = 0;
47static int next_comptag = 1; 43static int next_comptag = 1;
48 44
@@ -327,127 +323,6 @@ static int rio_is_switch(struct rio_dev *rdev)
327} 323}
328 324
329/** 325/**
330 * rio_switch_init - Sets switch operations for a particular vendor switch
331 * @rdev: RIO device
332 * @do_enum: Enumeration/Discovery mode flag
333 *
334 * Searches the RIO switch ops table for known switch types. If the vid
335 * and did match a switch table entry, then call switch initialization
336 * routine to setup switch-specific routines.
337 */
338static void rio_switch_init(struct rio_dev *rdev, int do_enum)
339{
340 struct rio_switch_ops *cur = __start_rio_switch_ops;
341 struct rio_switch_ops *end = __end_rio_switch_ops;
342
343 while (cur < end) {
344 if ((cur->vid == rdev->vid) && (cur->did == rdev->did)) {
345 pr_debug("RIO: calling init routine for %s\n",
346 rio_name(rdev));
347 cur->init_hook(rdev, do_enum);
348 break;
349 }
350 cur++;
351 }
352
353 if ((cur >= end) && (rdev->pef & RIO_PEF_STD_RT)) {
354 pr_debug("RIO: adding STD routing ops for %s\n",
355 rio_name(rdev));
356 rdev->rswitch->add_entry = rio_std_route_add_entry;
357 rdev->rswitch->get_entry = rio_std_route_get_entry;
358 rdev->rswitch->clr_table = rio_std_route_clr_table;
359 }
360
361 if (!rdev->rswitch->add_entry || !rdev->rswitch->get_entry)
362 printk(KERN_ERR "RIO: missing routing ops for %s\n",
363 rio_name(rdev));
364}
365
366/**
367 * rio_add_device- Adds a RIO device to the device model
368 * @rdev: RIO device
369 *
370 * Adds the RIO device to the global device list and adds the RIO
371 * device to the RIO device list. Creates the generic sysfs nodes
372 * for an RIO device.
373 */
374static int rio_add_device(struct rio_dev *rdev)
375{
376 int err;
377
378 err = device_add(&rdev->dev);
379 if (err)
380 return err;
381
382 spin_lock(&rio_global_list_lock);
383 list_add_tail(&rdev->global_list, &rio_devices);
384 spin_unlock(&rio_global_list_lock);
385
386 rio_create_sysfs_dev_files(rdev);
387
388 return 0;
389}
390
391/**
392 * rio_enable_rx_tx_port - enable input receiver and output transmitter of
393 * given port
394 * @port: Master port associated with the RIO network
395 * @local: local=1 select local port otherwise a far device is reached
396 * @destid: Destination ID of the device to check host bit
397 * @hopcount: Number of hops to reach the target
398 * @port_num: Port (-number on switch) to enable on a far end device
399 *
400 * Returns 0 or 1 from on General Control Command and Status Register
401 * (EXT_PTR+0x3C)
402 */
403inline int rio_enable_rx_tx_port(struct rio_mport *port,
404 int local, u16 destid,
405 u8 hopcount, u8 port_num) {
406#ifdef CONFIG_RAPIDIO_ENABLE_RX_TX_PORTS
407 u32 regval;
408 u32 ext_ftr_ptr;
409
410 /*
411 * enable rx input tx output port
412 */
413 pr_debug("rio_enable_rx_tx_port(local = %d, destid = %d, hopcount = "
414 "%d, port_num = %d)\n", local, destid, hopcount, port_num);
415
416 ext_ftr_ptr = rio_mport_get_physefb(port, local, destid, hopcount);
417
418 if (local) {
419 rio_local_read_config_32(port, ext_ftr_ptr +
420 RIO_PORT_N_CTL_CSR(0),
421 &regval);
422 } else {
423 if (rio_mport_read_config_32(port, destid, hopcount,
424 ext_ftr_ptr + RIO_PORT_N_CTL_CSR(port_num), &regval) < 0)
425 return -EIO;
426 }
427
428 if (regval & RIO_PORT_N_CTL_P_TYP_SER) {
429 /* serial */
430 regval = regval | RIO_PORT_N_CTL_EN_RX_SER
431 | RIO_PORT_N_CTL_EN_TX_SER;
432 } else {
433 /* parallel */
434 regval = regval | RIO_PORT_N_CTL_EN_RX_PAR
435 | RIO_PORT_N_CTL_EN_TX_PAR;
436 }
437
438 if (local) {
439 rio_local_write_config_32(port, ext_ftr_ptr +
440 RIO_PORT_N_CTL_CSR(0), regval);
441 } else {
442 if (rio_mport_write_config_32(port, destid, hopcount,
443 ext_ftr_ptr + RIO_PORT_N_CTL_CSR(port_num), regval) < 0)
444 return -EIO;
445 }
446#endif
447 return 0;
448}
449
450/**
451 * rio_setup_device- Allocates and sets up a RIO device 326 * rio_setup_device- Allocates and sets up a RIO device
452 * @net: RIO network 327 * @net: RIO network
453 * @port: Master port to send transactions 328 * @port: Master port to send transactions
@@ -587,8 +462,7 @@ static struct rio_dev *rio_setup_device(struct rio_net *net,
587 rdev->destid); 462 rdev->destid);
588 } 463 }
589 464
590 rdev->dev.bus = &rio_bus_type; 465 rio_attach_device(rdev);
591 rdev->dev.parent = &rio_bus;
592 466
593 device_initialize(&rdev->dev); 467 device_initialize(&rdev->dev);
594 rdev->dev.release = rio_release_dev; 468 rdev->dev.release = rio_release_dev;
@@ -1421,3 +1295,41 @@ enum_done:
1421bail: 1295bail:
1422 return -EBUSY; 1296 return -EBUSY;
1423} 1297}
1298
1299static struct rio_scan rio_scan_ops = {
1300 .enumerate = rio_enum_mport,
1301 .discover = rio_disc_mport,
1302};
1303
1304static bool scan;
1305module_param(scan, bool, 0);
1306MODULE_PARM_DESC(scan, "Start RapidIO network enumeration/discovery "
1307 "(default = 0)");
1308
1309/**
1310 * rio_basic_attach:
1311 *
1312 * When this enumeration/discovery method is loaded as a module this function
1313 * registers its specific enumeration and discover routines for all available
1314 * RapidIO mport devices. The "scan" command line parameter controls ability of
1315 * the module to start RapidIO enumeration/discovery automatically.
1316 *
1317 * Returns 0 for success or -EIO if unable to register itself.
1318 *
1319 * This enumeration/discovery method cannot be unloaded and therefore does not
1320 * provide a matching cleanup_module routine.
1321 */
1322
1323static int __init rio_basic_attach(void)
1324{
1325 if (rio_register_scan(RIO_MPORT_ANY, &rio_scan_ops))
1326 return -EIO;
1327 if (scan)
1328 rio_init_mports();
1329 return 0;
1330}
1331
1332late_initcall(rio_basic_attach);
1333
1334MODULE_DESCRIPTION("Basic RapidIO enumeration/discovery");
1335MODULE_LICENSE("GPL");
diff --git a/drivers/rapidio/rio.c b/drivers/rapidio/rio.c
index d553b5d13722..6e75dda34799 100644
--- a/drivers/rapidio/rio.c
+++ b/drivers/rapidio/rio.c
@@ -31,7 +31,11 @@
31 31
32#include "rio.h" 32#include "rio.h"
33 33
34static LIST_HEAD(rio_devices);
35static DEFINE_SPINLOCK(rio_global_list_lock);
36
34static LIST_HEAD(rio_mports); 37static LIST_HEAD(rio_mports);
38static DEFINE_MUTEX(rio_mport_list_lock);
35static unsigned char next_portid; 39static unsigned char next_portid;
36static DEFINE_SPINLOCK(rio_mmap_lock); 40static DEFINE_SPINLOCK(rio_mmap_lock);
37 41
@@ -53,6 +57,32 @@ u16 rio_local_get_device_id(struct rio_mport *port)
53} 57}
54 58
55/** 59/**
60 * rio_add_device- Adds a RIO device to the device model
61 * @rdev: RIO device
62 *
63 * Adds the RIO device to the global device list and adds the RIO
64 * device to the RIO device list. Creates the generic sysfs nodes
65 * for an RIO device.
66 */
67int rio_add_device(struct rio_dev *rdev)
68{
69 int err;
70
71 err = device_add(&rdev->dev);
72 if (err)
73 return err;
74
75 spin_lock(&rio_global_list_lock);
76 list_add_tail(&rdev->global_list, &rio_devices);
77 spin_unlock(&rio_global_list_lock);
78
79 rio_create_sysfs_dev_files(rdev);
80
81 return 0;
82}
83EXPORT_SYMBOL_GPL(rio_add_device);
84
85/**
56 * rio_request_inb_mbox - request inbound mailbox service 86 * rio_request_inb_mbox - request inbound mailbox service
57 * @mport: RIO master port from which to allocate the mailbox resource 87 * @mport: RIO master port from which to allocate the mailbox resource
58 * @dev_id: Device specific pointer to pass on event 88 * @dev_id: Device specific pointer to pass on event
@@ -489,6 +519,7 @@ rio_mport_get_physefb(struct rio_mport *port, int local,
489 519
490 return ext_ftr_ptr; 520 return ext_ftr_ptr;
491} 521}
522EXPORT_SYMBOL_GPL(rio_mport_get_physefb);
492 523
493/** 524/**
494 * rio_get_comptag - Begin or continue searching for a RIO device by component tag 525 * rio_get_comptag - Begin or continue searching for a RIO device by component tag
@@ -521,6 +552,7 @@ exit:
521 spin_unlock(&rio_global_list_lock); 552 spin_unlock(&rio_global_list_lock);
522 return rdev; 553 return rdev;
523} 554}
555EXPORT_SYMBOL_GPL(rio_get_comptag);
524 556
525/** 557/**
526 * rio_set_port_lockout - Sets/clears LOCKOUT bit (RIO EM 1.3) for a switch port. 558 * rio_set_port_lockout - Sets/clears LOCKOUT bit (RIO EM 1.3) for a switch port.
@@ -545,6 +577,107 @@ int rio_set_port_lockout(struct rio_dev *rdev, u32 pnum, int lock)
545 regval); 577 regval);
546 return 0; 578 return 0;
547} 579}
580EXPORT_SYMBOL_GPL(rio_set_port_lockout);
581
582/**
583 * rio_switch_init - Sets switch operations for a particular vendor switch
584 * @rdev: RIO device
585 * @do_enum: Enumeration/Discovery mode flag
586 *
587 * Searches the RIO switch ops table for known switch types. If the vid
588 * and did match a switch table entry, then call switch initialization
589 * routine to setup switch-specific routines.
590 */
591void rio_switch_init(struct rio_dev *rdev, int do_enum)
592{
593 struct rio_switch_ops *cur = __start_rio_switch_ops;
594 struct rio_switch_ops *end = __end_rio_switch_ops;
595
596 while (cur < end) {
597 if ((cur->vid == rdev->vid) && (cur->did == rdev->did)) {
598 pr_debug("RIO: calling init routine for %s\n",
599 rio_name(rdev));
600 cur->init_hook(rdev, do_enum);
601 break;
602 }
603 cur++;
604 }
605
606 if ((cur >= end) && (rdev->pef & RIO_PEF_STD_RT)) {
607 pr_debug("RIO: adding STD routing ops for %s\n",
608 rio_name(rdev));
609 rdev->rswitch->add_entry = rio_std_route_add_entry;
610 rdev->rswitch->get_entry = rio_std_route_get_entry;
611 rdev->rswitch->clr_table = rio_std_route_clr_table;
612 }
613
614 if (!rdev->rswitch->add_entry || !rdev->rswitch->get_entry)
615 printk(KERN_ERR "RIO: missing routing ops for %s\n",
616 rio_name(rdev));
617}
618EXPORT_SYMBOL_GPL(rio_switch_init);
619
620/**
621 * rio_enable_rx_tx_port - enable input receiver and output transmitter of
622 * given port
623 * @port: Master port associated with the RIO network
624 * @local: local=1 select local port otherwise a far device is reached
625 * @destid: Destination ID of the device to check host bit
626 * @hopcount: Number of hops to reach the target
627 * @port_num: Port (-number on switch) to enable on a far end device
628 *
629 * Returns 0 or 1 from on General Control Command and Status Register
630 * (EXT_PTR+0x3C)
631 */
632int rio_enable_rx_tx_port(struct rio_mport *port,
633 int local, u16 destid,
634 u8 hopcount, u8 port_num)
635{
636#ifdef CONFIG_RAPIDIO_ENABLE_RX_TX_PORTS
637 u32 regval;
638 u32 ext_ftr_ptr;
639
640 /*
641 * enable rx input tx output port
642 */
643 pr_debug("rio_enable_rx_tx_port(local = %d, destid = %d, hopcount = "
644 "%d, port_num = %d)\n", local, destid, hopcount, port_num);
645
646 ext_ftr_ptr = rio_mport_get_physefb(port, local, destid, hopcount);
647
648 if (local) {
649 rio_local_read_config_32(port, ext_ftr_ptr +
650 RIO_PORT_N_CTL_CSR(0),
651 &regval);
652 } else {
653 if (rio_mport_read_config_32(port, destid, hopcount,
654 ext_ftr_ptr + RIO_PORT_N_CTL_CSR(port_num), &regval) < 0)
655 return -EIO;
656 }
657
658 if (regval & RIO_PORT_N_CTL_P_TYP_SER) {
659 /* serial */
660 regval = regval | RIO_PORT_N_CTL_EN_RX_SER
661 | RIO_PORT_N_CTL_EN_TX_SER;
662 } else {
663 /* parallel */
664 regval = regval | RIO_PORT_N_CTL_EN_RX_PAR
665 | RIO_PORT_N_CTL_EN_TX_PAR;
666 }
667
668 if (local) {
669 rio_local_write_config_32(port, ext_ftr_ptr +
670 RIO_PORT_N_CTL_CSR(0), regval);
671 } else {
672 if (rio_mport_write_config_32(port, destid, hopcount,
673 ext_ftr_ptr + RIO_PORT_N_CTL_CSR(port_num), regval) < 0)
674 return -EIO;
675 }
676#endif
677 return 0;
678}
679EXPORT_SYMBOL_GPL(rio_enable_rx_tx_port);
680
548 681
549/** 682/**
550 * rio_chk_dev_route - Validate route to the specified device. 683 * rio_chk_dev_route - Validate route to the specified device.
@@ -610,6 +743,7 @@ rio_mport_chk_dev_access(struct rio_mport *mport, u16 destid, u8 hopcount)
610 743
611 return 0; 744 return 0;
612} 745}
746EXPORT_SYMBOL_GPL(rio_mport_chk_dev_access);
613 747
614/** 748/**
615 * rio_chk_dev_access - Validate access to the specified device. 749 * rio_chk_dev_access - Validate access to the specified device.
@@ -941,6 +1075,7 @@ rio_mport_get_efb(struct rio_mport *port, int local, u16 destid,
941 return RIO_GET_BLOCK_ID(reg_val); 1075 return RIO_GET_BLOCK_ID(reg_val);
942 } 1076 }
943} 1077}
1078EXPORT_SYMBOL_GPL(rio_mport_get_efb);
944 1079
945/** 1080/**
946 * rio_mport_get_feature - query for devices' extended features 1081 * rio_mport_get_feature - query for devices' extended features
@@ -997,6 +1132,7 @@ rio_mport_get_feature(struct rio_mport * port, int local, u16 destid,
997 1132
998 return 0; 1133 return 0;
999} 1134}
1135EXPORT_SYMBOL_GPL(rio_mport_get_feature);
1000 1136
1001/** 1137/**
1002 * rio_get_asm - Begin or continue searching for a RIO device by vid/did/asm_vid/asm_did 1138 * rio_get_asm - Begin or continue searching for a RIO device by vid/did/asm_vid/asm_did
@@ -1246,6 +1382,71 @@ EXPORT_SYMBOL_GPL(rio_dma_prep_slave_sg);
1246 1382
1247#endif /* CONFIG_RAPIDIO_DMA_ENGINE */ 1383#endif /* CONFIG_RAPIDIO_DMA_ENGINE */
1248 1384
1385/**
1386 * rio_register_scan - enumeration/discovery method registration interface
1387 * @mport_id: mport device ID for which fabric scan routine has to be set
1388 * (RIO_MPORT_ANY = set for all available mports)
1389 * @scan_ops: enumeration/discovery control structure
1390 *
1391 * Assigns enumeration or discovery method to the specified mport device (or all
1392 * available mports if RIO_MPORT_ANY is specified).
1393 * Returns error if the mport already has an enumerator attached to it.
1394 * In case of RIO_MPORT_ANY ignores ports with valid scan routines and returns
1395 * an error if was unable to find at least one available mport.
1396 */
1397int rio_register_scan(int mport_id, struct rio_scan *scan_ops)
1398{
1399 struct rio_mport *port;
1400 int rc = -EBUSY;
1401
1402 mutex_lock(&rio_mport_list_lock);
1403 list_for_each_entry(port, &rio_mports, node) {
1404 if (port->id == mport_id || mport_id == RIO_MPORT_ANY) {
1405 if (port->nscan && mport_id == RIO_MPORT_ANY)
1406 continue;
1407 else if (port->nscan)
1408 break;
1409
1410 port->nscan = scan_ops;
1411 rc = 0;
1412
1413 if (mport_id != RIO_MPORT_ANY)
1414 break;
1415 }
1416 }
1417 mutex_unlock(&rio_mport_list_lock);
1418
1419 return rc;
1420}
1421EXPORT_SYMBOL_GPL(rio_register_scan);
1422
1423/**
1424 * rio_unregister_scan - removes enumeration/discovery method from mport
1425 * @mport_id: mport device ID for which fabric scan routine has to be
1426 * unregistered (RIO_MPORT_ANY = set for all available mports)
1427 *
1428 * Removes enumeration or discovery method assigned to the specified mport
1429 * device (or all available mports if RIO_MPORT_ANY is specified).
1430 */
1431int rio_unregister_scan(int mport_id)
1432{
1433 struct rio_mport *port;
1434
1435 mutex_lock(&rio_mport_list_lock);
1436 list_for_each_entry(port, &rio_mports, node) {
1437 if (port->id == mport_id || mport_id == RIO_MPORT_ANY) {
1438 if (port->nscan)
1439 port->nscan = NULL;
1440 if (mport_id != RIO_MPORT_ANY)
1441 break;
1442 }
1443 }
1444 mutex_unlock(&rio_mport_list_lock);
1445
1446 return 0;
1447}
1448EXPORT_SYMBOL_GPL(rio_unregister_scan);
1449
1249static void rio_fixup_device(struct rio_dev *dev) 1450static void rio_fixup_device(struct rio_dev *dev)
1250{ 1451{
1251} 1452}
@@ -1274,7 +1475,7 @@ static void disc_work_handler(struct work_struct *_work)
1274 work = container_of(_work, struct rio_disc_work, work); 1475 work = container_of(_work, struct rio_disc_work, work);
1275 pr_debug("RIO: discovery work for mport %d %s\n", 1476 pr_debug("RIO: discovery work for mport %d %s\n",
1276 work->mport->id, work->mport->name); 1477 work->mport->id, work->mport->name);
1277 rio_disc_mport(work->mport); 1478 work->mport->nscan->discover(work->mport);
1278} 1479}
1279 1480
1280int rio_init_mports(void) 1481int rio_init_mports(void)
@@ -1290,12 +1491,15 @@ int rio_init_mports(void)
1290 * First, run enumerations and check if we need to perform discovery 1491 * First, run enumerations and check if we need to perform discovery
1291 * on any of the registered mports. 1492 * on any of the registered mports.
1292 */ 1493 */
1494 mutex_lock(&rio_mport_list_lock);
1293 list_for_each_entry(port, &rio_mports, node) { 1495 list_for_each_entry(port, &rio_mports, node) {
1294 if (port->host_deviceid >= 0) 1496 if (port->host_deviceid >= 0) {
1295 rio_enum_mport(port); 1497 if (port->nscan)
1296 else 1498 port->nscan->enumerate(port);
1499 } else
1297 n++; 1500 n++;
1298 } 1501 }
1502 mutex_unlock(&rio_mport_list_lock);
1299 1503
1300 if (!n) 1504 if (!n)
1301 goto no_disc; 1505 goto no_disc;
@@ -1322,14 +1526,16 @@ int rio_init_mports(void)
1322 } 1526 }
1323 1527
1324 n = 0; 1528 n = 0;
1529 mutex_lock(&rio_mport_list_lock);
1325 list_for_each_entry(port, &rio_mports, node) { 1530 list_for_each_entry(port, &rio_mports, node) {
1326 if (port->host_deviceid < 0) { 1531 if (port->host_deviceid < 0 && port->nscan) {
1327 work[n].mport = port; 1532 work[n].mport = port;
1328 INIT_WORK(&work[n].work, disc_work_handler); 1533 INIT_WORK(&work[n].work, disc_work_handler);
1329 queue_work(rio_wq, &work[n].work); 1534 queue_work(rio_wq, &work[n].work);
1330 n++; 1535 n++;
1331 } 1536 }
1332 } 1537 }
1538 mutex_unlock(&rio_mport_list_lock);
1333 1539
1334 flush_workqueue(rio_wq); 1540 flush_workqueue(rio_wq);
1335 pr_debug("RIO: destroy discovery workqueue\n"); 1541 pr_debug("RIO: destroy discovery workqueue\n");
@@ -1342,8 +1548,6 @@ no_disc:
1342 return 0; 1548 return 0;
1343} 1549}
1344 1550
1345device_initcall_sync(rio_init_mports);
1346
1347static int hdids[RIO_MAX_MPORTS + 1]; 1551static int hdids[RIO_MAX_MPORTS + 1];
1348 1552
1349static int rio_get_hdid(int index) 1553static int rio_get_hdid(int index)
@@ -1371,7 +1575,10 @@ int rio_register_mport(struct rio_mport *port)
1371 1575
1372 port->id = next_portid++; 1576 port->id = next_portid++;
1373 port->host_deviceid = rio_get_hdid(port->id); 1577 port->host_deviceid = rio_get_hdid(port->id);
1578 port->nscan = NULL;
1579 mutex_lock(&rio_mport_list_lock);
1374 list_add_tail(&port->node, &rio_mports); 1580 list_add_tail(&port->node, &rio_mports);
1581 mutex_unlock(&rio_mport_list_lock);
1375 return 0; 1582 return 0;
1376} 1583}
1377 1584
@@ -1386,3 +1593,4 @@ EXPORT_SYMBOL_GPL(rio_request_inb_mbox);
1386EXPORT_SYMBOL_GPL(rio_release_inb_mbox); 1593EXPORT_SYMBOL_GPL(rio_release_inb_mbox);
1387EXPORT_SYMBOL_GPL(rio_request_outb_mbox); 1594EXPORT_SYMBOL_GPL(rio_request_outb_mbox);
1388EXPORT_SYMBOL_GPL(rio_release_outb_mbox); 1595EXPORT_SYMBOL_GPL(rio_release_outb_mbox);
1596EXPORT_SYMBOL_GPL(rio_init_mports);
diff --git a/drivers/rapidio/rio.h b/drivers/rapidio/rio.h
index b1af414f15e6..0afdf482517e 100644
--- a/drivers/rapidio/rio.h
+++ b/drivers/rapidio/rio.h
@@ -15,6 +15,7 @@
15#include <linux/rio.h> 15#include <linux/rio.h>
16 16
17#define RIO_MAX_CHK_RETRY 3 17#define RIO_MAX_CHK_RETRY 3
18#define RIO_MPORT_ANY (-1)
18 19
19/* Functions internal to the RIO core code */ 20/* Functions internal to the RIO core code */
20 21
@@ -27,8 +28,6 @@ extern u32 rio_mport_get_efb(struct rio_mport *port, int local, u16 destid,
27extern int rio_mport_chk_dev_access(struct rio_mport *mport, u16 destid, 28extern int rio_mport_chk_dev_access(struct rio_mport *mport, u16 destid,
28 u8 hopcount); 29 u8 hopcount);
29extern int rio_create_sysfs_dev_files(struct rio_dev *rdev); 30extern int rio_create_sysfs_dev_files(struct rio_dev *rdev);
30extern int rio_enum_mport(struct rio_mport *mport);
31extern int rio_disc_mport(struct rio_mport *mport);
32extern int rio_std_route_add_entry(struct rio_mport *mport, u16 destid, 31extern int rio_std_route_add_entry(struct rio_mport *mport, u16 destid,
33 u8 hopcount, u16 table, u16 route_destid, 32 u8 hopcount, u16 table, u16 route_destid,
34 u8 route_port); 33 u8 route_port);
@@ -39,10 +38,16 @@ extern int rio_std_route_clr_table(struct rio_mport *mport, u16 destid,
39 u8 hopcount, u16 table); 38 u8 hopcount, u16 table);
40extern int rio_set_port_lockout(struct rio_dev *rdev, u32 pnum, int lock); 39extern int rio_set_port_lockout(struct rio_dev *rdev, u32 pnum, int lock);
41extern struct rio_dev *rio_get_comptag(u32 comp_tag, struct rio_dev *from); 40extern struct rio_dev *rio_get_comptag(u32 comp_tag, struct rio_dev *from);
41extern int rio_add_device(struct rio_dev *rdev);
42extern void rio_switch_init(struct rio_dev *rdev, int do_enum);
43extern int rio_enable_rx_tx_port(struct rio_mport *port, int local, u16 destid,
44 u8 hopcount, u8 port_num);
45extern int rio_register_scan(int mport_id, struct rio_scan *scan_ops);
46extern int rio_unregister_scan(int mport_id);
47extern void rio_attach_device(struct rio_dev *rdev);
42 48
43/* Structures internal to the RIO core code */ 49/* Structures internal to the RIO core code */
44extern struct device_attribute rio_dev_attrs[]; 50extern struct device_attribute rio_dev_attrs[];
45extern spinlock_t rio_global_list_lock;
46 51
47extern struct rio_switch_ops __start_rio_switch_ops[]; 52extern struct rio_switch_ops __start_rio_switch_ops[];
48extern struct rio_switch_ops __end_rio_switch_ops[]; 53extern struct rio_switch_ops __end_rio_switch_ops[];