Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 47629
b: refs/heads/master
c: c70555b
h: refs/heads/master
i:
  47627: 0f92a9f
v: v3
  • Loading branch information
Alexandre Bounine authored and Linus Torvalds committed Feb 11, 2007
1 parent b51bf4b commit df7bddf
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 32 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: d5698c28b6e4711e4747bf155f69936208d60e28
refs/heads/master: c70555b051f2a32bf94a7e1c75b6b6759031b989
118 changes: 87 additions & 31 deletions trunk/drivers/rapidio/rio-scan.c
Original file line number Diff line number Diff line change
Expand Up @@ -326,14 +326,17 @@ static struct rio_dev *rio_setup_device(struct rio_net *net,
rio_mport_read_config_32(port, destid, hopcount, RIO_DST_OPS_CAR,
&rdev->dst_ops);

if (rio_device_has_destid(port, rdev->src_ops, rdev->dst_ops)
&& do_enum) {
rio_set_device_id(port, destid, hopcount, next_destid);
rdev->destid = next_destid++;
if (next_destid == port->host_deviceid)
next_destid++;
if (rio_device_has_destid(port, rdev->src_ops, rdev->dst_ops)) {
if (do_enum) {
rio_set_device_id(port, destid, hopcount, next_destid);
rdev->destid = next_destid++;
if (next_destid == port->host_deviceid)
next_destid++;
} else
rdev->destid = rio_get_device_id(port, destid, hopcount);
} else
rdev->destid = rio_get_device_id(port, destid, hopcount);
/* Switch device has an associated destID */
rdev->destid = RIO_INVALID_DESTID;

/* If a PE has both switch and other functions, show it as a switch */
if (rio_is_switch(rdev)) {
Expand All @@ -347,7 +350,7 @@ static struct rio_dev *rio_setup_device(struct rio_net *net,
}
rswitch->switchid = next_switchid;
rswitch->hopcount = hopcount;
rswitch->destid = 0xffff;
rswitch->destid = destid;
/* Initialize switch route table */
for (rdid = 0; rdid < RIO_MAX_ROUTE_ENTRIES; rdid++)
rswitch->route_table[rdid] = RIO_INVALID_ROUTE;
Expand Down Expand Up @@ -422,7 +425,7 @@ rio_sport_is_active(struct rio_mport *port, u16 destid, u8 hopcount, int sport)
/**
* rio_route_add_entry- Add a route entry to a switch routing table
* @mport: Master port to send transaction
* @rdev: Switch device
* @rswitch: Switch device
* @table: Routing table ID
* @route_destid: Destination ID to be routed
* @route_port: Port number to be routed
Expand All @@ -434,18 +437,18 @@ rio_sport_is_active(struct rio_mport *port, u16 destid, u8 hopcount, int sport)
* %RIO_GLOBAL_TABLE in @table. Returns %0 on success or %-EINVAL
* on failure.
*/
static int rio_route_add_entry(struct rio_mport *mport, struct rio_dev *rdev,
static int rio_route_add_entry(struct rio_mport *mport, struct rio_switch *rswitch,
u16 table, u16 route_destid, u8 route_port)
{
return rdev->rswitch->add_entry(mport, rdev->rswitch->destid,
rdev->rswitch->hopcount, table,
return rswitch->add_entry(mport, rswitch->destid,
rswitch->hopcount, table,
route_destid, route_port);
}

/**
* rio_route_get_entry- Read a route entry in a switch routing table
* @mport: Master port to send transaction
* @rdev: Switch device
* @rswitch: Switch device
* @table: Routing table ID
* @route_destid: Destination ID to be routed
* @route_port: Pointer to read port number into
Expand All @@ -458,11 +461,11 @@ static int rio_route_add_entry(struct rio_mport *mport, struct rio_dev *rdev,
* on failure.
*/
static int
rio_route_get_entry(struct rio_mport *mport, struct rio_dev *rdev, u16 table,
rio_route_get_entry(struct rio_mport *mport, struct rio_switch *rswitch, u16 table,
u16 route_destid, u8 * route_port)
{
return rdev->rswitch->get_entry(mport, rdev->rswitch->destid,
rdev->rswitch->hopcount, table,
return rswitch->get_entry(mport, rswitch->destid,
rswitch->hopcount, table,
route_destid, route_port);
}

Expand Down Expand Up @@ -552,6 +555,8 @@ static int rio_enum_peer(struct rio_net *net, struct rio_mport *port,
int port_num;
int num_ports;
int cur_destid;
int sw_destid;
int sw_inport;
struct rio_dev *rdev;
u16 destid;
int tmp;
Expand Down Expand Up @@ -594,25 +599,27 @@ static int rio_enum_peer(struct rio_net *net, struct rio_mport *port,

if (rio_is_switch(rdev)) {
next_switchid++;
sw_inport = rio_get_swpinfo_inport(port, RIO_ANY_DESTID, hopcount);
rio_route_add_entry(port, rdev->rswitch, RIO_GLOBAL_TABLE,
port->host_deviceid, sw_inport);
rdev->rswitch->route_table[port->host_deviceid] = sw_inport;

for (destid = 0; destid < next_destid; destid++) {
rio_route_add_entry(port, rdev, RIO_GLOBAL_TABLE,
destid, rio_get_swpinfo_inport(port,
RIO_ANY_DESTID,
hopcount));
rdev->rswitch->route_table[destid] =
rio_get_swpinfo_inport(port, RIO_ANY_DESTID,
hopcount);
if (destid == port->host_deviceid)
continue;
rio_route_add_entry(port, rdev->rswitch, RIO_GLOBAL_TABLE,
destid, sw_inport);
rdev->rswitch->route_table[destid] = sw_inport;
}

num_ports =
rio_get_swpinfo_tports(port, RIO_ANY_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);
sw_destid = next_destid;
for (port_num = 0; port_num < num_ports; port_num++) {
if (rio_get_swpinfo_inport
(port, RIO_ANY_DESTID, hopcount) == port_num)
if (sw_inport == port_num)
continue;

cur_destid = next_destid;
Expand All @@ -622,7 +629,7 @@ static int rio_enum_peer(struct rio_net *net, struct rio_mport *port,
pr_debug(
"RIO: scanning device on port %d\n",
port_num);
rio_route_add_entry(port, rdev,
rio_route_add_entry(port, rdev->rswitch,
RIO_GLOBAL_TABLE,
RIO_ANY_DESTID, port_num);

Expand All @@ -633,18 +640,28 @@ static int rio_enum_peer(struct rio_net *net, struct rio_mport *port,
if (next_destid > cur_destid) {
for (destid = cur_destid;
destid < next_destid; destid++) {
rio_route_add_entry(port, rdev,
if (destid == port->host_deviceid)
continue;
rio_route_add_entry(port, rdev->rswitch,
RIO_GLOBAL_TABLE,
destid,
port_num);
rdev->rswitch->
route_table[destid] =
port_num;
}
rdev->rswitch->destid = cur_destid;
}
}
}

/* Check for empty switch */
if (next_destid == sw_destid) {
next_destid++;
if (next_destid == port->host_deviceid)
next_destid++;
}

rdev->rswitch->destid = sw_destid;
} else
pr_debug("RIO: found %s (vid %4.4x did %4.4x)\n",
rio_name(rdev), rdev->vid, rdev->did);
Expand Down Expand Up @@ -721,7 +738,7 @@ rio_disc_peer(struct rio_net *net, struct rio_mport *port, u16 destid,
port_num);
for (ndestid = 0; ndestid < RIO_ANY_DESTID;
ndestid++) {
rio_route_get_entry(port, rdev,
rio_route_get_entry(port, rdev->rswitch,
RIO_GLOBAL_TABLE,
ndestid,
&route_port);
Expand Down Expand Up @@ -797,6 +814,44 @@ static struct rio_net __devinit *rio_alloc_net(struct rio_mport *port)
return net;
}

/**
* rio_update_route_tables- Updates route tables in switches
* @port: Master port associated with the RIO network
*
* For each enumerated device, ensure that each switch in a system
* has correct routing entries. Add routes for devices that where
* unknown dirung the first enumeration pass through the switch.
*/
static void rio_update_route_tables(struct rio_mport *port)
{
struct rio_dev *rdev;
struct rio_switch *rswitch;
u8 sport;
u16 destid;

list_for_each_entry(rdev, &rio_devices, global_list) {

destid = (rio_is_switch(rdev))?rdev->rswitch->destid:rdev->destid;

list_for_each_entry(rswitch, &rio_switches, node) {

if (rio_is_switch(rdev) && (rdev->rswitch == rswitch))
continue;

if (RIO_INVALID_ROUTE == rswitch->route_table[destid]) {

sport = rio_get_swpinfo_inport(port,
rswitch->destid, rswitch->hopcount);

if (rswitch->add_entry) {
rio_route_add_entry(port, rswitch, RIO_GLOBAL_TABLE, destid, sport);
rswitch->route_table[destid] = sport;
}
}
}
}
}

/**
* rio_enum_mport- Start enumeration through a master port
* @mport: Master port to send transactions
Expand Down Expand Up @@ -838,6 +893,7 @@ int rio_enum_mport(struct rio_mport *mport)
rc = -EBUSY;
goto out;
}
rio_update_route_tables(mport);
rio_clear_locks(mport);
} else {
printk(KERN_INFO "RIO: master port %d link inactive\n",
Expand Down Expand Up @@ -865,8 +921,8 @@ static void rio_build_route_tables(void)
if (rio_is_switch(rdev))
for (i = 0; i < RIO_MAX_ROUTE_ENTRIES; i++) {
if (rio_route_get_entry
(rdev->net->hport, rdev, RIO_GLOBAL_TABLE, i,
&sport) < 0)
(rdev->net->hport, rdev->rswitch, RIO_GLOBAL_TABLE,
i, &sport) < 0)
continue;
rdev->rswitch->route_table[i] = sport;
}
Expand Down
1 change: 1 addition & 0 deletions trunk/include/linux/rio.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@

#define RIO_ANY_DESTID 0xff
#define RIO_NO_HOPCOUNT -1
#define RIO_INVALID_DESTID 0xffff

#define RIO_MAX_MPORT_RESOURCES 16
#define RIO_MAX_DEV_RESOURCES 16
Expand Down

0 comments on commit df7bddf

Please sign in to comment.