@@ -750,6 +750,7 @@ rio_disc_peer(struct rio_net *net, struc
int num_ports;
struct rio_dev *rdev;
u16 ndestid;
+ u32 result;
/* Setup new RIO device */
if ((rdev = rio_setup_device(net, port, destid, hopcount, 0))) {
@@ -778,6 +779,27 @@ rio_disc_peer(struct rio_net *net, struc
pr_debug(
"RIO: scanning device on port %d\n",
port_num);
+
+ /* Attempt to acquire device lock */
+ rio_mport_write_config_32(port, destid,
+ hopcount,
+ RIO_HOST_DID_LOCK_CSR,
+ port->host_deviceid);
+ rio_mport_read_config_32(port, destid, hopcount,
+ RIO_HOST_DID_LOCK_CSR, &result);
+ while (result != port->host_deviceid) {
+ /* Delay a bit */
+ mdelay(1);
+ /* Try to acquire device lock again */
+ rio_mport_write_config_32(port, destid,
+ hopcount,
+ RIO_HOST_DID_LOCK_CSR,
+ port->host_deviceid);
+ rio_mport_read_config_32(port, destid,
+ hopcount,
+ RIO_HOST_DID_LOCK_CSR, &result);
+ }
+
for (ndestid = 0;
ndestid < RIO_ANY_DESTID(port->sys_size);
ndestid++) {
@@ -789,6 +811,19 @@ rio_disc_peer(struct rio_net *net, struc
break;
}
+ /* Release device lock */
+ rio_mport_write_config_32(port, destid,
+ hopcount,
+ RIO_HOST_DID_LOCK_CSR,
+ port->host_deviceid);
+ rio_mport_read_config_32(port, destid, hopcount,
+ RIO_HOST_DID_LOCK_CSR, &result);
+ if ((result & 0xffff) != 0xffff) {
+ pr_info("RIO: badness when releasing " \
+ "host lock on %s\n",
+ rio_name(rdev));
+ }
+
if (rio_disc_peer
(net, port, ndestid, hopcount + 1) < 0)
return -1;
@@ -958,17 +993,45 @@ static void rio_build_route_tables(void)
struct rio_dev *rdev;
int i;
u8 sport;
+ u32 result;
list_for_each_entry(rdev, &rio_devices, global_list)
- if (rio_is_switch(rdev))
- for (i = 0;
- i < RIO_MAX_ROUTE_ENTRIES(rdev->net->hport->sys_size);
- i++) {
- if (rio_route_get_entry
- (rdev->net->hport, rdev->rswitch, RIO_GLOBAL_TABLE,
- i, &sport) < 0)
- continue;
- rdev->rswitch->route_table[i] = sport;
+ if (rio_is_switch(rdev)) {
+ /* Attempt to acquire device lock */
+ rio_write_config_32(rdev, RIO_HOST_DID_LOCK_CSR,
+ rdev->net->hport->host_deviceid);
+ rio_read_config_32(rdev,
+ RIO_HOST_DID_LOCK_CSR, &result);
+ while (result != rdev->net->hport->host_deviceid) {
+ /* Delay a bit */
+ mdelay(1);
+ /* Attempt to acquire device lock again */
+ rio_write_config_32(rdev, RIO_HOST_DID_LOCK_CSR,
+ rdev->net->hport->host_deviceid);
+ rio_read_config_32(rdev,
+ RIO_HOST_DID_LOCK_CSR, &result);
+ }
+
+ for (i = 0;
+ i < RIO_MAX_ROUTE_ENTRIES(rdev->net->hport->sys_size);
+ i++) {
+ if (rio_route_get_entry
+ (rdev->net->hport, rdev->rswitch,
+ RIO_GLOBAL_TABLE, i, &sport) < 0)
+ continue;
+ rdev->rswitch->route_table[i] = sport;
+ }
+
+ /* Release device lock */
+ rio_write_config_32(rdev, RIO_HOST_DID_LOCK_CSR,
+ rdev->net->hport->host_deviceid);
+ rio_read_config_32(rdev,
+ RIO_HOST_DID_LOCK_CSR, &result);
+ if ((result & 0xffff) != 0xffff) {
+ pr_info("RIO: badness when releasing " \
+ "host lock on %s\n", rio_name(rdev));
+ }
+
}
}
@@ -1027,6 +1090,13 @@ int __devinit rio_disc_mport(struct rio_
del_timer_sync(&rio_enum_timer);
pr_debug("done\n");
+
+ /* Read DestID assigned by enumerator */
+ rio_local_read_config_32(mport, RIO_DID_CSR,
+ &mport->host_deviceid);
+ mport->host_deviceid = RIO_GET_DID(mport->sys_size,
+ mport->host_deviceid);
+
if (rio_disc_peer(net, mport, RIO_ANY_DESTID(mport->sys_size),
0) < 0) {
printk(KERN_INFO