if (nets[rnet->mport->id].active[destid])
                        rionet_queue_tx_msg(skb, ndev,
                                        nets[rnet->mport->id].active[destid]);
+               else {
+                       /*
+                        * If the target device was removed from the list of
+                        * active peers but we still have TX packets targeting
+                        * it just report sending a packet to the target
+                        * (without actual packet transfer).
+                        */
+                       dev_kfree_skb_any(skb);
+                       ndev->stats.tx_packets++;
+                       ndev->stats.tx_bytes += skb->len;
+               }
        }
 
        spin_unlock_irqrestore(&rnet->tx_lock, flags);
        return 0;
 }
 
-static void rionet_remove(struct rio_dev *rdev)
+static int rionet_remove_dev(struct device *dev, struct subsys_interface *sif)
 {
-       struct net_device *ndev = rio_get_drvdata(rdev);
+       struct rio_dev *rdev = to_rio_dev(dev);
        unsigned char netid = rdev->net->hport->id;
        struct rionet_peer *peer, *tmp;
 
-       unregister_netdev(ndev);
-
-       free_pages((unsigned long)nets[netid].active, get_order(sizeof(void *) *
-                       RIO_MAX_ROUTE_ENTRIES(rdev->net->hport->sys_size)));
-       nets[netid].active = NULL;
+       if (dev_rionet_capable(rdev)) {
+               list_for_each_entry_safe(peer, tmp, &nets[netid].peers, node) {
+                       if (peer->rdev == rdev) {
+                               if (nets[netid].active[rdev->destid]) {
+                                       nets[netid].active[rdev->destid] = NULL;
+                                       nets[netid].nact--;
+                               }
 
-       list_for_each_entry_safe(peer, tmp, &nets[netid].peers, node) {
-               list_del(&peer->node);
-               kfree(peer);
+                               list_del(&peer->node);
+                               kfree(peer);
+                               break;
+                       }
+               }
        }
 
-       free_netdev(ndev);
+       return 0;
 }
 
 static void rionet_get_drvinfo(struct net_device *ndev,
 
 static unsigned long net_table[RIONET_MAX_NETS/sizeof(unsigned long) + 1];
 
-static int rionet_probe(struct rio_dev *rdev, const struct rio_device_id *id)
+static int rionet_add_dev(struct device *dev, struct subsys_interface *sif)
 {
        int rc = -ENODEV;
        u32 lsrc_ops, ldst_ops;
        struct rionet_peer *peer;
        struct net_device *ndev = NULL;
+       struct rio_dev *rdev = to_rio_dev(dev);
        unsigned char netid = rdev->net->hport->id;
        int oldnet;
 
        oldnet = test_and_set_bit(netid, net_table);
 
        /*
-        * First time through, make sure local device is rionet
-        * capable, setup netdev (will be skipped on later probes)
+        * If first time through this net, make sure local device is rionet
+        * capable and setup netdev (this step will be skipped in later probes
+        * on the same net).
         */
        if (!oldnet) {
                rio_local_read_config_32(rdev->net->hport, RIO_SRC_OPS_CAR,
                }
                nets[netid].ndev = ndev;
                rc = rionet_setup_netdev(rdev->net->hport, ndev);
+               if (rc) {
+                       printk(KERN_ERR "%s: failed to setup netdev (rc=%d)\n",
+                              DRV_NAME, rc);
+                       goto out;
+               }
+
                INIT_LIST_HEAD(&nets[netid].peers);
                nets[netid].nact = 0;
        } else if (nets[netid].ndev == NULL)
                list_add_tail(&peer->node, &nets[netid].peers);
        }
 
-       rio_set_drvdata(rdev, nets[netid].ndev);
-
-      out:
+       return 0;
+out:
        return rc;
 }
 
+#ifdef MODULE
 static struct rio_device_id rionet_id_table[] = {
-       {RIO_DEVICE(RIO_ANY_ID, RIO_ANY_ID)}
+       {RIO_DEVICE(RIO_ANY_ID, RIO_ANY_ID)},
+       { 0, }  /* terminate list */
 };
 
-static struct rio_driver rionet_driver = {
-       .name = "rionet",
-       .id_table = rionet_id_table,
-       .probe = rionet_probe,
-       .remove = rionet_remove,
+MODULE_DEVICE_TABLE(rapidio, rionet_id_table);
+#endif
+
+static struct subsys_interface rionet_interface = {
+       .name           = "rionet",
+       .subsys         = &rio_bus_type,
+       .add_dev        = rionet_add_dev,
+       .remove_dev     = rionet_remove_dev,
 };
 
 static int __init rionet_init(void)
 {
-       return rio_register_driver(&rionet_driver);
+       return subsys_interface_register(&rionet_interface);
 }
 
 static void __exit rionet_exit(void)
 {
-       rio_unregister_driver(&rionet_driver);
+       struct rionet_private *rnet;
+       struct net_device *ndev;
+       struct rionet_peer *peer, *tmp;
+       int i;
+
+       for (i = 0; i < RIONET_MAX_NETS; i++) {
+               if (nets[i].ndev != NULL) {
+                       ndev = nets[i].ndev;
+                       rnet = netdev_priv(ndev);
+                       unregister_netdev(ndev);
+
+                       list_for_each_entry_safe(peer,
+                                                tmp, &nets[i].peers, node) {
+                               list_del(&peer->node);
+                               kfree(peer);
+                       }
+
+                       free_pages((unsigned long)nets[i].active,
+                                get_order(sizeof(void *) *
+                                RIO_MAX_ROUTE_ENTRIES(rnet->mport->sys_size)));
+                       nets[i].active = NULL;
+
+                       free_netdev(ndev);
+               }
+       }
+
+       subsys_interface_unregister(&rionet_interface);
 }
 
 late_initcall(rionet_init);