Skip to content

Commit a11650e

Browse files
Alexandre Bouninetorvalds
authored andcommitted
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>
1 parent 585dc0c commit a11650e

File tree

8 files changed

+304
-139
lines changed

8 files changed

+304
-139
lines changed

drivers/rapidio/Kconfig

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,4 +47,24 @@ config RAPIDIO_DEBUG
4747

4848
If you are unsure about this, say N here.
4949

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+
5070
source "drivers/rapidio/switches/Kconfig"

drivers/rapidio/Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
#
22
# Makefile for RapidIO interconnect services
33
#
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
56

67
obj-$(CONFIG_RAPIDIO) += switches/
78
obj-$(CONFIG_RAPIDIO) += devices/

drivers/rapidio/rio-driver.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,13 @@ void rio_unregister_driver(struct rio_driver *rdrv)
164164
driver_unregister(&rdrv->driver);
165165
}
166166

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+
167174
/**
168175
* rio_match_bus - Tell if a RIO device structure has a matching RIO driver device id structure
169176
* @dev: the standard device structure to match against

drivers/rapidio/rio-scan.c

Lines changed: 39 additions & 127 deletions
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,8 @@
3737

3838
#include "rio.h"
3939

40-
LIST_HEAD(rio_devices);
41-
4240
static void rio_init_em(struct rio_dev *rdev);
4341

44-
DEFINE_SPINLOCK(rio_global_list_lock);
45-
4642
static int next_destid = 0;
4743
static int next_comptag = 1;
4844

@@ -326,127 +322,6 @@ static int rio_is_switch(struct rio_dev *rdev)
326322
return 0;
327323
}
328324

329-
/**
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-
*/
338-
static 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-
*/
374-
static 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-
*/
403-
inline 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-
450325
/**
451326
* rio_setup_device- Allocates and sets up a RIO device
452327
* @net: RIO network
@@ -587,8 +462,7 @@ static struct rio_dev *rio_setup_device(struct rio_net *net,
587462
rdev->destid);
588463
}
589464

590-
rdev->dev.bus = &rio_bus_type;
591-
rdev->dev.parent = &rio_bus;
465+
rio_attach_device(rdev);
592466

593467
device_initialize(&rdev->dev);
594468
rdev->dev.release = rio_release_dev;
@@ -1421,3 +1295,41 @@ int rio_disc_mport(struct rio_mport *mport)
14211295
bail:
14221296
return -EBUSY;
14231297
}
1298+
1299+
static struct rio_scan rio_scan_ops = {
1300+
.enumerate = rio_enum_mport,
1301+
.discover = rio_disc_mport,
1302+
};
1303+
1304+
static bool scan;
1305+
module_param(scan, bool, 0);
1306+
MODULE_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+
1323+
static 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+
1332+
late_initcall(rio_basic_attach);
1333+
1334+
MODULE_DESCRIPTION("Basic RapidIO enumeration/discovery");
1335+
MODULE_LICENSE("GPL");

0 commit comments

Comments
 (0)