This commit was manufactured by cvs2svn to create tag
[linux-2.6.git] / drivers / net / iseries_veth.c
index e62ca7b..634cb04 100644 (file)
@@ -81,6 +81,8 @@
 
 #include "iseries_veth.h"
 
+extern struct vio_dev *iSeries_veth_dev;
+
 MODULE_AUTHOR("Kyle Lucke <klucke@us.ibm.com>");
 MODULE_DESCRIPTION("iSeries Virtual ethernet driver");
 MODULE_LICENSE("GPL");
@@ -117,7 +119,6 @@ struct veth_msg {
        int token;
        unsigned long in_use;
        struct sk_buff *skb;
-       struct device *dev;
 };
 
 struct veth_lpar_connection {
@@ -146,7 +147,6 @@ struct veth_lpar_connection {
 };
 
 struct veth_port {
-       struct device *dev;
        struct net_device_stats stats;
        u64 mac_addr;
        HvLpIndexMap lpar_map;
@@ -843,7 +843,7 @@ static void veth_tx_timeout(struct net_device *dev)
        spin_unlock_irqrestore(&port->pending_gate, flags);
 }
 
-static struct net_device * __init veth_probe_one(int vlan, struct device *vdev)
+struct net_device * __init veth_probe_one(int vlan)
 {
        struct net_device *dev;
        struct veth_port *port;
@@ -869,7 +869,6 @@ static struct net_device * __init veth_probe_one(int vlan, struct device *vdev)
                if (map & (0x8000 >> vlan))
                        port->lpar_map |= (1 << i);
        }
-       port->dev = vdev;
 
        dev->dev_addr[0] = 0x02;
        dev->dev_addr[1] = 0x01;
@@ -894,8 +893,6 @@ static struct net_device * __init veth_probe_one(int vlan, struct device *vdev)
        dev->watchdog_timeo = 2 * (VETH_ACKTIMEOUT * HZ / 1000000);
        dev->tx_timeout = veth_tx_timeout;
 
-       SET_NETDEV_DEV(dev, vdev);
-
        rc = register_netdev(dev);
        if (rc != 0) {
                veth_printk(KERN_ERR,
@@ -948,7 +945,7 @@ static int veth_transmit_to_one(struct sk_buff *skb, HvLpIndex rlp,
        }
 
        dma_length = skb->len;
-       dma_address = dma_map_single(port->dev, skb->data,
+       dma_address = vio_map_single(iSeries_veth_dev, skb->data,
                                     dma_length, DMA_TO_DEVICE);
 
        if (dma_mapping_error(dma_address))
@@ -957,7 +954,6 @@ static int veth_transmit_to_one(struct sk_buff *skb, HvLpIndex rlp,
        /* Is it really necessary to check the length and address
         * fields of the first entry here? */
        msg->skb = skb;
-       msg->dev = port->dev;
        msg->data.addr[0] = dma_address;
        msg->data.len[0] = dma_length;
        msg->data.eofmask = 1 << VETH_EOF_SHIFT;
@@ -1063,7 +1059,7 @@ static void veth_recycle_msg(struct veth_lpar_connection *cnx,
                dma_address = msg->data.addr[0];
                dma_length = msg->data.len[0];
 
-               dma_unmap_single(msg->dev, dma_address, dma_length,
+               vio_unmap_single(iSeries_veth_dev, dma_address, dma_length,
                                 DMA_TO_DEVICE);
 
                if (msg->skb) {
@@ -1331,58 +1327,6 @@ static void veth_timed_ack(unsigned long ptr)
        spin_unlock_irqrestore(&cnx->lock, flags);
 }
 
-static int veth_remove(struct vio_dev *vdev)
-{
-       int i = vdev->unit_address;
-       struct net_device *dev;
-
-       dev = veth_dev[i];
-       if (dev != NULL) {
-               veth_dev[i] = NULL;
-               unregister_netdev(dev);
-               free_netdev(dev);
-       }
-       return 0;
-}
-
-static int veth_probe(struct vio_dev *vdev, const struct vio_device_id *id)
-{
-       int i = vdev->unit_address;
-       struct net_device *dev;
-
-       dev = veth_probe_one(i, &vdev->dev);
-       if (dev == NULL) {
-               veth_remove(vdev);
-               return 1;
-       }
-       veth_dev[i] = dev;
-
-       /* Start the state machine on each connection, to commence
-        * link negotiation */
-       for (i = 0; i < HVMAXARCHITECTEDLPS; i++)
-               if (veth_cnx[i])
-                       veth_kick_statemachine(veth_cnx[i]);
-
-       return 0;
-}
-
-/**
- * veth_device_table: Used by vio.c to match devices that we
- * support.
- */
-static struct vio_device_id veth_device_table[] __devinitdata = {
-       { "vlan", "" },
-       { NULL, NULL }
-};
-MODULE_DEVICE_TABLE(vio, veth_device_table);
-
-static struct vio_driver veth_driver = {
-       .name = "iseries_veth",
-       .id_table = veth_device_table,
-       .probe = veth_probe,
-       .remove = veth_remove
-};
-
 /*
  * Module initialization/cleanup
  */
@@ -1391,17 +1335,27 @@ void __exit veth_module_cleanup(void)
 {
        int i;
 
-       vio_unregister_driver(&veth_driver);
-
        for (i = 0; i < HVMAXARCHITECTEDLPS; ++i)
                veth_destroy_connection(i);
 
        HvLpEvent_unregisterHandler(HvLpEvent_Type_VirtualLan);
+
+       for (i = 0; i < HVMAXARCHITECTEDVIRTUALLANS; ++i) {
+               struct net_device *dev = veth_dev[i];
+
+               if (! dev)
+                       continue;
+
+               veth_dev[i] = NULL;
+               unregister_netdev(dev);
+               free_netdev(dev);
+       }
 }
 module_exit(veth_module_cleanup);
 
 int __init veth_module_init(void)
 {
+       HvLpIndexMap vlan_map = HvLpConfig_getVirtualLanIndexMap();
        int i;
        int rc;
 
@@ -1415,9 +1369,31 @@ int __init veth_module_init(void)
                }
        }
 
+       for (i = 0; i < HVMAXARCHITECTEDVIRTUALLANS; ++i) {
+               struct net_device *dev;
+
+               if (! (vlan_map & (0x8000 >> i)))
+                       continue;
+
+               dev = veth_probe_one(i);
+
+               if (! dev) {
+                       veth_module_cleanup();
+                       return rc;
+               }
+
+               veth_dev[i] = dev;
+       }
+
        HvLpEvent_registerHandler(HvLpEvent_Type_VirtualLan,
                                  &veth_handle_event);
 
-       return vio_register_driver(&veth_driver);
+       /* Start the state machine on each connection, to commence
+        * link negotiation */
+       for (i = 0; i < HVMAXARCHITECTEDLPS; i++)
+               if (veth_cnx[i])
+                       veth_kick_statemachine(veth_cnx[i]);
+
+       return 0;
 }
 module_init(veth_module_init);