Skip to content

Commit

Permalink
rapidio: add relation links between RIO device structures
Browse files Browse the repository at this point in the history
Create back and forward links between RIO devices.  These links are
intended for use by error management and hot-plug extensions.  Links for
redundant RIO connections between switches are not set (will be fixed in a
separate patch).

Signed-off-by: Alexandre Bounine <[email protected]>
Cc: Thomas Moll <[email protected]>
Cc: Matt Porter <[email protected]>
Cc: Li Yang <[email protected]>
Cc: Kumar Gala <[email protected]>
Cc: Micha Nelissen <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
Alexandre Bounine authored and torvalds committed Oct 28, 2010
1 parent ae05cbd commit 68fe4df
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 33 deletions.
56 changes: 23 additions & 33 deletions drivers/rapidio/rio-scan.c
Original file line number Diff line number Diff line change
Expand Up @@ -444,7 +444,10 @@ static struct rio_dev __devinit *rio_setup_device(struct rio_net *net,

/* If a PE has both switch and other functions, show it as a switch */
if (rio_is_switch(rdev)) {
rswitch = kzalloc(sizeof(struct rio_switch), GFP_KERNEL);
rswitch = kzalloc(sizeof(*rswitch) +
RIO_GET_TOTAL_PORTS(rdev->swpinfo) *
sizeof(rswitch->nextdev[0]),
GFP_KERNEL);
if (!rswitch)
goto cleanup;
rswitch->switchid = next_switchid;
Expand Down Expand Up @@ -722,25 +725,6 @@ static u16 rio_get_host_deviceid_lock(struct rio_mport *port, u8 hopcount)
return (u16) (result & 0xffff);
}

/**
* rio_get_swpinfo_tports- Gets total number of ports on the switch
* @mport: Master port to send transaction
* @destid: Destination ID associated with the switch
* @hopcount: Number of hops to the device
*
* Returns total numbers of ports implemented by the switch device.
*/
static u8 rio_get_swpinfo_tports(struct rio_mport *mport, u16 destid,
u8 hopcount)
{
u32 result;

rio_mport_read_config_32(mport, destid, hopcount, RIO_SWP_INFO_CAR,
&result);

return RIO_GET_TOTAL_PORTS(result);
}

/**
* rio_net_add_mport- Add a master port to a RIO network
* @net: RIO network
Expand All @@ -761,15 +745,16 @@ static void rio_net_add_mport(struct rio_net *net, struct rio_mport *port)
* @net: RIO network being enumerated
* @port: Master port to send transactions
* @hopcount: Number of hops into the network
* @prev: Previous RIO device connected to the enumerated one
* @prev_port: Port on previous RIO device
*
* Recursively enumerates a RIO network. Transactions are sent via the
* master port passed in @port.
*/
static int __devinit rio_enum_peer(struct rio_net *net, struct rio_mport *port,
u8 hopcount)
u8 hopcount, struct rio_dev *prev, int prev_port)
{
int port_num;
int num_ports;
int cur_destid;
int sw_destid;
int sw_inport;
Expand Down Expand Up @@ -814,6 +799,9 @@ static int __devinit rio_enum_peer(struct rio_net *net, struct rio_mport *port,
if (rdev) {
/* Add device to the global and bus/net specific list. */
list_add_tail(&rdev->net_list, &net->devices);
rdev->prev = prev;
if (prev && rio_is_switch(prev))
prev->rswitch->nextdev[prev_port] = rdev;
} else
return -1;

Expand All @@ -832,14 +820,14 @@ static int __devinit rio_enum_peer(struct rio_net *net, struct rio_mport *port,
rdev->rswitch->route_table[destid] = sw_inport;
}

num_ports =
rio_get_swpinfo_tports(port, RIO_ANY_DESTID(port->sys_size),
hopcount);
pr_debug(
"RIO: found %s (vid %4.4x did %4.4x) with %d ports\n",
rio_name(rdev), rdev->vid, rdev->did, num_ports);
rio_name(rdev), rdev->vid, rdev->did,
RIO_GET_TOTAL_PORTS(rdev->swpinfo));
sw_destid = next_destid;
for (port_num = 0; port_num < num_ports; port_num++) {
for (port_num = 0;
port_num < RIO_GET_TOTAL_PORTS(rdev->swpinfo);
port_num++) {
/*Enable Input Output Port (transmitter reviever)*/
rio_enable_rx_tx_port(port, 0,
RIO_ANY_DESTID(port->sys_size),
Expand All @@ -864,7 +852,8 @@ static int __devinit rio_enum_peer(struct rio_net *net, struct rio_mport *port,
RIO_ANY_DESTID(port->sys_size),
port_num, 0);

if (rio_enum_peer(net, port, hopcount + 1) < 0)
if (rio_enum_peer(net, port, hopcount + 1,
rdev, port_num) < 0)
return -1;

/* Update routing tables */
Expand Down Expand Up @@ -951,7 +940,6 @@ rio_disc_peer(struct rio_net *net, struct rio_mport *port, u16 destid,
u8 hopcount)
{
u8 port_num, route_port;
int num_ports;
struct rio_dev *rdev;
u16 ndestid;

Expand All @@ -968,11 +956,13 @@ rio_disc_peer(struct rio_net *net, struct rio_mport *port, u16 destid,
/* Associated destid is how we accessed this switch */
rdev->rswitch->destid = destid;

num_ports = rio_get_swpinfo_tports(port, destid, hopcount);
pr_debug(
"RIO: found %s (vid %4.4x did %4.4x) with %d ports\n",
rio_name(rdev), rdev->vid, rdev->did, num_ports);
for (port_num = 0; port_num < num_ports; port_num++) {
rio_name(rdev), rdev->vid, rdev->did,
RIO_GET_TOTAL_PORTS(rdev->swpinfo));
for (port_num = 0;
port_num < RIO_GET_TOTAL_PORTS(rdev->swpinfo);
port_num++) {
if (RIO_GET_PORT_NUM(rdev->swpinfo) == port_num)
continue;

Expand Down Expand Up @@ -1167,7 +1157,7 @@ int __devinit rio_enum_mport(struct rio_mport *mport)
/* Enable Input Output Port (transmitter reviever) */
rio_enable_rx_tx_port(mport, 1, 0, 0, 0);

if (rio_enum_peer(net, mport, 0) < 0) {
if (rio_enum_peer(net, mport, 0, NULL, 0) < 0) {
/* A higher priority host won enumeration, bail. */
printk(KERN_INFO
"RIO: master port %d device has lost enumeration to a remote host\n",
Expand Down
4 changes: 4 additions & 0 deletions include/linux/rio.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ union rio_pw_msg;
* @riores: RIO resources this device owns
* @pwcback: port-write callback function for this device
* @destid: Network destination ID
* @prev: Previous RIO device connected to the current one
*/
struct rio_dev {
struct list_head global_list; /* node in list of all RIO devices */
Expand All @@ -125,6 +126,7 @@ struct rio_dev {
struct resource riores[RIO_MAX_DEV_RESOURCES];
int (*pwcback) (struct rio_dev *rdev, union rio_pw_msg *msg, int step);
u16 destid;
struct rio_dev *prev;
};

#define rio_dev_g(n) list_entry(n, struct rio_dev, global_list)
Expand Down Expand Up @@ -232,6 +234,7 @@ struct rio_net {
* @get_domain: Callback for switch-specific domain get function
* @em_init: Callback for switch-specific error management initialization function
* @em_handle: Callback for switch-specific error management handler function
* @nextdev: Array of per-port pointers to the next attached device
*/
struct rio_switch {
struct list_head node;
Expand All @@ -253,6 +256,7 @@ struct rio_switch {
u8 *sw_domain);
int (*em_init) (struct rio_dev *dev);
int (*em_handle) (struct rio_dev *dev, u8 swport);
struct rio_dev *nextdev[0];
};

/* Low-level architecture-dependent routines */
Expand Down

0 comments on commit 68fe4df

Please sign in to comment.