]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - drivers/rapidio/rio-scan.c
Merge branch 'master' into tk71
[mv-sheeva.git] / drivers / rapidio / rio-scan.c
index 8070e074c739f89b0902cfcc1ed9c20e5374c76c..a50391b6ba2a95b8afcc6d397a90c068c5f9bc36 100644 (file)
@@ -46,9 +46,8 @@ static void rio_init_em(struct rio_dev *rdev);
 DEFINE_SPINLOCK(rio_global_list_lock);
 
 static int next_destid = 0;
-static int next_switchid = 0;
 static int next_net = 0;
-static int next_comptag;
+static int next_comptag = 1;
 
 static struct timer_list rio_enum_timer =
 TIMER_INITIALIZER(rio_enum_timeout, 0, 0);
@@ -121,27 +120,6 @@ static int rio_clear_locks(struct rio_mport *port)
        u32 result;
        int ret = 0;
 
-       /* Assign component tag to all devices */
-       next_comptag = 1;
-       rio_local_write_config_32(port, RIO_COMPONENT_TAG_CSR, next_comptag++);
-
-       list_for_each_entry(rdev, &rio_devices, global_list) {
-               /* Mark device as discovered */
-               rio_read_config_32(rdev,
-                                  rdev->phys_efptr + RIO_PORT_GEN_CTL_CSR,
-                                  &result);
-               rio_write_config_32(rdev,
-                                   rdev->phys_efptr + RIO_PORT_GEN_CTL_CSR,
-                                   result | RIO_PORT_GEN_DISCOVERED);
-
-               rio_write_config_32(rdev, RIO_COMPONENT_TAG_CSR, next_comptag);
-               rdev->comp_tag = next_comptag++;
-               if (next_comptag >= 0x10000) {
-                       pr_err("RIO: Component Tag Counter Overflow\n");
-                       break;
-               }
-       }
-
        /* Release host device id locks */
        rio_local_write_config_32(port, RIO_HOST_DID_LOCK_CSR,
                                  port->host_deviceid);
@@ -162,6 +140,15 @@ static int rio_clear_locks(struct rio_mport *port)
                               rdev->vid, rdev->did);
                        ret = -EINVAL;
                }
+
+               /* Mark device as discovered and enable master */
+               rio_read_config_32(rdev,
+                                  rdev->phys_efptr + RIO_PORT_GEN_CTL_CSR,
+                                  &result);
+               result |= RIO_PORT_GEN_DISCOVERED | RIO_PORT_GEN_MASTER;
+               rio_write_config_32(rdev,
+                                   rdev->phys_efptr + RIO_PORT_GEN_CTL_CSR,
+                                   result);
        }
 
        return ret;
@@ -390,12 +377,30 @@ static struct rio_dev __devinit *rio_setup_device(struct rio_net *net,
        struct rio_dev *rdev;
        struct rio_switch *rswitch = NULL;
        int result, rdid;
+       size_t size;
+       u32 swpinfo = 0;
+
+       size = sizeof(struct rio_dev);
+       if (rio_mport_read_config_32(port, destid, hopcount,
+                                    RIO_PEF_CAR, &result))
+               return NULL;
 
-       rdev = kzalloc(sizeof(struct rio_dev), GFP_KERNEL);
+       if (result & (RIO_PEF_SWITCH | RIO_PEF_MULTIPORT)) {
+               rio_mport_read_config_32(port, destid, hopcount,
+                                        RIO_SWP_INFO_CAR, &swpinfo);
+               if (result & RIO_PEF_SWITCH) {
+                       size += (RIO_GET_TOTAL_PORTS(swpinfo) *
+                               sizeof(rswitch->nextdev[0])) + sizeof(*rswitch);
+               }
+       }
+
+       rdev = kzalloc(size, GFP_KERNEL);
        if (!rdev)
                return NULL;
 
        rdev->net = net;
+       rdev->pef = result;
+       rdev->swpinfo = swpinfo;
        rio_mport_read_config_32(port, destid, hopcount, RIO_DEV_ID_CAR,
                                 &result);
        rdev->did = result >> 16;
@@ -409,8 +414,6 @@ static struct rio_dev __devinit *rio_setup_device(struct rio_net *net,
        rio_mport_read_config_32(port, destid, hopcount, RIO_ASM_INFO_CAR,
                                 &result);
        rdev->asm_rev = result >> 16;
-       rio_mport_read_config_32(port, destid, hopcount, RIO_PEF_CAR,
-                                &rdev->pef);
        if (rdev->pef & RIO_PEF_EXT_FEATURES) {
                rdev->efptr = result & 0xffff;
                rdev->phys_efptr = rio_mport_get_physefb(port, 0, destid,
@@ -425,6 +428,21 @@ static struct rio_dev __devinit *rio_setup_device(struct rio_net *net,
        rio_mport_read_config_32(port, destid, hopcount, RIO_DST_OPS_CAR,
                                 &rdev->dst_ops);
 
+       if (do_enum) {
+               /* Assign component tag to device */
+               if (next_comptag >= 0x10000) {
+                       pr_err("RIO: Component Tag Counter Overflow\n");
+                       goto cleanup;
+               }
+               rio_mport_write_config_32(port, destid, hopcount,
+                                         RIO_COMPONENT_TAG_CSR, next_comptag);
+               rdev->comp_tag = next_comptag++;
+       }  else {
+               rio_mport_read_config_32(port, destid, hopcount,
+                                        RIO_COMPONENT_TAG_CSR,
+                                        &rdev->comp_tag);
+       }
+
        if (rio_device_has_destid(port, rdev->src_ops, rdev->dst_ops)) {
                if (do_enum) {
                        rio_set_device_id(port, destid, hopcount, next_destid);
@@ -433,20 +451,20 @@ static struct rio_dev __devinit *rio_setup_device(struct rio_net *net,
                                next_destid++;
                } else
                        rdev->destid = rio_get_device_id(port, destid, hopcount);
-       } else
-               /* Switch device has an associated destID */
-               rdev->destid = RIO_INVALID_DESTID;
+
+               rdev->hopcount = 0xff;
+       } else {
+               /* Switch device has an associated destID which
+                * will be adjusted later
+                */
+               rdev->destid = destid;
+               rdev->hopcount = hopcount;
+       }
 
        /* If a PE has both switch and other functions, show it as a switch */
        if (rio_is_switch(rdev)) {
-               rio_mport_read_config_32(port, destid, hopcount,
-                                        RIO_SWP_INFO_CAR, &rdev->swpinfo);
-               rswitch = kzalloc(sizeof(struct rio_switch), GFP_KERNEL);
-               if (!rswitch)
-                       goto cleanup;
-               rswitch->switchid = next_switchid;
-               rswitch->hopcount = hopcount;
-               rswitch->destid = destid;
+               rswitch = rdev->rswitch;
+               rswitch->switchid = rdev->comp_tag & RIO_CTAG_UDEVID;
                rswitch->port_ok = 0;
                rswitch->route_table = kzalloc(sizeof(u8)*
                                        RIO_MAX_ROUTE_ENTRIES(port->sys_size),
@@ -457,14 +475,13 @@ static struct rio_dev __devinit *rio_setup_device(struct rio_net *net,
                for (rdid = 0; rdid < RIO_MAX_ROUTE_ENTRIES(port->sys_size);
                                rdid++)
                        rswitch->route_table[rdid] = RIO_INVALID_ROUTE;
-               rdev->rswitch = rswitch;
                dev_set_name(&rdev->dev, "%02x:s:%04x", rdev->net->id,
-                            rdev->rswitch->switchid);
+                            rswitch->switchid);
                rio_switch_init(rdev, do_enum);
 
-               if (do_enum && rdev->rswitch->clr_table)
-                       rdev->rswitch->clr_table(port, destid, hopcount,
-                                                RIO_GLOBAL_TABLE);
+               if (do_enum && rswitch->clr_table)
+                       rswitch->clr_table(port, destid, hopcount,
+                                          RIO_GLOBAL_TABLE);
 
                list_add_tail(&rswitch->node, &rio_switches);
 
@@ -478,6 +495,7 @@ static struct rio_dev __devinit *rio_setup_device(struct rio_net *net,
        }
 
        rdev->dev.bus = &rio_bus_type;
+       rdev->dev.parent = &rio_bus;
 
        device_initialize(&rdev->dev);
        rdev->dev.release = rio_release_dev;
@@ -499,10 +517,9 @@ static struct rio_dev __devinit *rio_setup_device(struct rio_net *net,
        return rdev;
 
 cleanup:
-       if (rswitch) {
+       if (rswitch->route_table)
                kfree(rswitch->route_table);
-               kfree(rswitch);
-       }
+
        kfree(rdev);
        return NULL;
 }
@@ -625,8 +642,7 @@ rio_unlock_device(struct rio_mport *port, u16 destid, u8 hopcount)
 
 /**
  * rio_route_add_entry- Add a route entry to a switch routing table
- * @mport: Master port to send transaction
- * @rswitch: Switch device
+ * @rdev: RIO device
  * @table: Routing table ID
  * @route_destid: Destination ID to be routed
  * @route_port: Port number to be routed
@@ -640,31 +656,31 @@ rio_unlock_device(struct rio_mport *port, u16 destid, u8 hopcount)
  * on failure.
  */
 static int
-rio_route_add_entry(struct rio_mport *mport, struct rio_switch *rswitch,
+rio_route_add_entry(struct rio_dev *rdev,
                    u16 table, u16 route_destid, u8 route_port, int lock)
 {
        int rc;
 
        if (lock) {
-               rc = rio_lock_device(mport, rswitch->destid,
-                                    rswitch->hopcount, 1000);
+               rc = rio_lock_device(rdev->net->hport, rdev->destid,
+                                    rdev->hopcount, 1000);
                if (rc)
                        return rc;
        }
 
-       rc = rswitch->add_entry(mport, rswitch->destid,
-                                       rswitch->hopcount, table,
-                                       route_destid, route_port);
+       rc = rdev->rswitch->add_entry(rdev->net->hport, rdev->destid,
+                                     rdev->hopcount, table,
+                                     route_destid, route_port);
        if (lock)
-               rio_unlock_device(mport, rswitch->destid, rswitch->hopcount);
+               rio_unlock_device(rdev->net->hport, rdev->destid,
+                                 rdev->hopcount);
 
        return rc;
 }
 
 /**
  * rio_route_get_entry- Read a route entry in a switch routing table
- * @mport: Master port to send transaction
- * @rswitch: Switch device
+ * @rdev: RIO device
  * @table: Routing table ID
  * @route_destid: Destination ID to be routed
  * @route_port: Pointer to read port number into
@@ -678,23 +694,24 @@ rio_route_add_entry(struct rio_mport *mport, struct rio_switch *rswitch,
  * on failure.
  */
 static int
-rio_route_get_entry(struct rio_mport *mport, struct rio_switch *rswitch, u16 table,
+rio_route_get_entry(struct rio_dev *rdev, u16 table,
                    u16 route_destid, u8 *route_port, int lock)
 {
        int rc;
 
        if (lock) {
-               rc = rio_lock_device(mport, rswitch->destid,
-                                    rswitch->hopcount, 1000);
+               rc = rio_lock_device(rdev->net->hport, rdev->destid,
+                                    rdev->hopcount, 1000);
                if (rc)
                        return rc;
        }
 
-       rc = rswitch->get_entry(mport, rswitch->destid,
-                                       rswitch->hopcount, table,
-                                       route_destid, route_port);
+       rc = rdev->rswitch->get_entry(rdev->net->hport, rdev->destid,
+                                     rdev->hopcount, table,
+                                     route_destid, route_port);
        if (lock)
-               rio_unlock_device(mport, rswitch->destid, rswitch->hopcount);
+               rio_unlock_device(rdev->net->hport, rdev->destid,
+                                 rdev->hopcount);
 
        return rc;
 }
@@ -717,87 +734,54 @@ static u16 rio_get_host_deviceid_lock(struct rio_mport *port, u8 hopcount)
        return (u16) (result & 0xffff);
 }
 
-/**
- * rio_get_swpinfo_inport- Gets the ingress port number
- * @mport: Master port to send transaction
- * @destid: Destination ID associated with the switch
- * @hopcount: Number of hops to the device
- *
- * Returns port number being used to access the switch device.
- */
-static u8
-rio_get_swpinfo_inport(struct rio_mport *mport, u16 destid, u8 hopcount)
-{
-       u32 result;
-
-       rio_mport_read_config_32(mport, destid, hopcount, RIO_SWP_INFO_CAR,
-                                &result);
-
-       return (u8) (result & 0xff);
-}
-
-/**
- * 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
- * @port: Master port to add
- *
- * Adds a master port to the network list of associated master
- * ports..
- */
-static void rio_net_add_mport(struct rio_net *net, struct rio_mport *port)
-{
-       spin_lock(&rio_global_list_lock);
-       list_add_tail(&port->nnode, &net->mports);
-       spin_unlock(&rio_global_list_lock);
-}
-
 /**
  * rio_enum_peer- Recursively enumerate a RIO network through a master 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;
        struct rio_dev *rdev;
        u16 destid;
+       u32 regval;
        int tmp;
 
+       if (rio_mport_chk_dev_access(port,
+                       RIO_ANY_DESTID(port->sys_size), hopcount)) {
+               pr_debug("RIO: device access check failed\n");
+               return -1;
+       }
+
        if (rio_get_host_deviceid_lock(port, hopcount) == port->host_deviceid) {
                pr_debug("RIO: PE already discovered by this host\n");
                /*
                 * Already discovered by this host. Add it as another
-                * master port for the current network.
+                * link to the existing device.
                 */
-               rio_net_add_mport(net, port);
+               rio_mport_read_config_32(port, RIO_ANY_DESTID(port->sys_size),
+                               hopcount, RIO_COMPONENT_TAG_CSR, &regval);
+
+               if (regval) {
+                       rdev = rio_get_comptag((regval & 0xffff), NULL);
+
+                       if (rdev && prev && rio_is_switch(prev)) {
+                               pr_debug("RIO: redundant path to %s\n",
+                                        rio_name(rdev));
+                               prev->rswitch->nextdev[prev_port] = rdev;
+                       }
+               }
+
                return 0;
        }
 
@@ -828,33 +812,34 @@ 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;
 
        if (rio_is_switch(rdev)) {
-               next_switchid++;
-               sw_inport = rio_get_swpinfo_inport(port,
-                               RIO_ANY_DESTID(port->sys_size), hopcount);
-               rio_route_add_entry(port, rdev->rswitch, RIO_GLOBAL_TABLE,
+               sw_inport = RIO_GET_PORT_NUM(rdev->swpinfo);
+               rio_route_add_entry(rdev, RIO_GLOBAL_TABLE,
                                    port->host_deviceid, sw_inport, 0);
                rdev->rswitch->route_table[port->host_deviceid] = sw_inport;
 
                for (destid = 0; destid < next_destid; destid++) {
                        if (destid == port->host_deviceid)
                                continue;
-                       rio_route_add_entry(port, rdev->rswitch, RIO_GLOBAL_TABLE,
+                       rio_route_add_entry(rdev, RIO_GLOBAL_TABLE,
                                            destid, sw_inport, 0);
                        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),
@@ -874,12 +859,12 @@ static int __devinit rio_enum_peer(struct rio_net *net, struct rio_mport *port,
                                    "RIO: scanning device on port %d\n",
                                    port_num);
                                rdev->rswitch->port_ok |= (1 << port_num);
-                               rio_route_add_entry(port, rdev->rswitch,
-                                               RIO_GLOBAL_TABLE,
+                               rio_route_add_entry(rdev, RIO_GLOBAL_TABLE,
                                                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 */
@@ -888,7 +873,7 @@ static int __devinit rio_enum_peer(struct rio_net *net, struct rio_mport *port,
                                             destid < next_destid; destid++) {
                                                if (destid == port->host_deviceid)
                                                        continue;
-                                               rio_route_add_entry(port, rdev->rswitch,
+                                               rio_route_add_entry(rdev,
                                                                    RIO_GLOBAL_TABLE,
                                                                    destid,
                                                                    port_num,
@@ -927,7 +912,7 @@ static int __devinit rio_enum_peer(struct rio_net *net, struct rio_mport *port,
                                next_destid++;
                }
 
-               rdev->rswitch->destid = sw_destid;
+               rdev->destid = sw_destid;
        } else
                pr_debug("RIO: found %s (vid %4.4x did %4.4x)\n",
                    rio_name(rdev), rdev->vid, rdev->did);
@@ -945,10 +930,11 @@ static int __devinit rio_enum_peer(struct rio_net *net, struct rio_mport *port,
  */
 static int rio_enum_complete(struct rio_mport *port)
 {
-       u32 tag_csr;
+       u32 regval;
 
-       rio_local_read_config_32(port, RIO_COMPONENT_TAG_CSR, &tag_csr);
-       return (tag_csr & 0xffff) ? 1 : 0;
+       rio_local_read_config_32(port, port->phys_efptr + RIO_PORT_GEN_CTL_CSR,
+                                &regval);
+       return (regval & RIO_PORT_GEN_MASTER) ? 1 : 0;
 }
 
 /**
@@ -957,16 +943,17 @@ static int rio_enum_complete(struct rio_mport *port)
  * @port: Master port to send transactions
  * @destid: Current destination ID in network
  * @hopcount: Number of hops into the network
+ * @prev: previous rio_dev
+ * @prev_port: previous port number
  *
  * Recursively discovers a RIO network.  Transactions are sent via the
  * master port passed in @port.
  */
 static int __devinit
 rio_disc_peer(struct rio_net *net, struct rio_mport *port, u16 destid,
-             u8 hopcount)
+             u8 hopcount, struct rio_dev *prev, int prev_port)
 {
        u8 port_num, route_port;
-       int num_ports;
        struct rio_dev *rdev;
        u16 ndestid;
 
@@ -974,22 +961,24 @@ rio_disc_peer(struct rio_net *net, struct rio_mport *port, u16 destid,
        if ((rdev = rio_setup_device(net, port, destid, hopcount, 0))) {
                /* 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;
 
        if (rio_is_switch(rdev)) {
-               next_switchid++;
-
                /* Associated destid is how we accessed this switch */
-               rdev->rswitch->destid = destid;
+               rdev->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++) {
-                       if (rio_get_swpinfo_inport(port, destid, hopcount) ==
-                           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;
 
                        if (rio_sport_is_active
@@ -1003,7 +992,7 @@ rio_disc_peer(struct rio_net *net, struct rio_mport *port, u16 destid,
                                for (ndestid = 0;
                                     ndestid < RIO_ANY_DESTID(port->sys_size);
                                     ndestid++) {
-                                       rio_route_get_entry(port, rdev->rswitch,
+                                       rio_route_get_entry(rdev,
                                                            RIO_GLOBAL_TABLE,
                                                            ndestid,
                                                            &route_port, 0);
@@ -1011,9 +1000,11 @@ rio_disc_peer(struct rio_net *net, struct rio_mport *port, u16 destid,
                                                break;
                                }
 
+                               if (ndestid == RIO_ANY_DESTID(port->sys_size))
+                                       continue;
                                rio_unlock_device(port, destid, hopcount);
-                               if (rio_disc_peer
-                                   (net, port, ndestid, hopcount + 1) < 0)
+                               if (rio_disc_peer(net, port, ndestid,
+                                       hopcount + 1, rdev, port_num) < 0)
                                        return -1;
                        }
                }
@@ -1089,14 +1080,14 @@ static struct rio_net __devinit *rio_alloc_net(struct rio_mport *port)
  */
 static void rio_update_route_tables(struct rio_mport *port)
 {
-       struct rio_dev *rdev;
+       struct rio_dev *rdev, *swrdev;
        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;
+               destid = rdev->destid;
 
                list_for_each_entry(rswitch, &rio_switches, node) {
 
@@ -1104,15 +1095,16 @@ static void rio_update_route_tables(struct rio_mport *port)
                                continue;
 
                        if (RIO_INVALID_ROUTE == rswitch->route_table[destid]) {
+                               swrdev = sw_to_rio_dev(rswitch);
+
                                /* Skip if destid ends in empty switch*/
-                               if (rswitch->destid == destid)
+                               if (swrdev->destid == destid)
                                        continue;
 
-                               sport = rio_get_swpinfo_inport(port,
-                                               rswitch->destid, rswitch->hopcount);
+                               sport = RIO_GET_PORT_NUM(swrdev->swpinfo);
 
                                if (rswitch->add_entry) {
-                                       rio_route_add_entry(port, rswitch,
+                                       rio_route_add_entry(swrdev,
                                                RIO_GLOBAL_TABLE, destid,
                                                sport, 0);
                                        rswitch->route_table[destid] = sport;
@@ -1184,7 +1176,11 @@ 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) {
+               /* Set component tag for host */
+               rio_local_write_config_32(mport, RIO_COMPONENT_TAG_CSR,
+                                         next_comptag++);
+
+               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",
@@ -1220,21 +1216,20 @@ static void rio_build_route_tables(void)
 
        list_for_each_entry(rdev, &rio_devices, global_list)
                if (rio_is_switch(rdev)) {
-                       rio_lock_device(rdev->net->hport, rdev->rswitch->destid,
-                                       rdev->rswitch->hopcount, 1000);
+                       rio_lock_device(rdev->net->hport, rdev->destid,
+                                       rdev->hopcount, 1000);
                        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) < 0)
+                               if (rio_route_get_entry(rdev,
+                                       RIO_GLOBAL_TABLE, i, &sport, 0) < 0)
                                        continue;
                                rdev->rswitch->route_table[i] = sport;
                        }
 
                        rio_unlock_device(rdev->net->hport,
-                                         rdev->rswitch->destid,
-                                         rdev->rswitch->hopcount);
+                                         rdev->destid,
+                                         rdev->hopcount);
                }
 }
 
@@ -1301,7 +1296,7 @@ int __devinit rio_disc_mport(struct rio_mport *mport)
                                                   mport->host_deviceid);
 
                if (rio_disc_peer(net, mport, RIO_ANY_DESTID(mport->sys_size),
-                                       0) < 0) {
+                                       0, NULL, 0) < 0) {
                        printk(KERN_INFO
                               "RIO: master port %d device has failed discovery\n",
                               mport->id);