include cleanup: Update gfp.h and slab.h includes to prepare for breaking implicit...
[safe/jmp/linux-2.6] / drivers / infiniband / ulp / ipoib / ipoib_vlan.c
index 085eafe..d7e9740 100644 (file)
  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
- *
- * $Id: ipoib_vlan.c 1349 2004-12-16 21:09:43Z roland $
  */
 
 #include <linux/module.h>
 
 #include <linux/init.h>
-#include <linux/slab.h>
 #include <linux/seq_file.h>
 
 #include <asm/uaccess.h>
@@ -63,6 +60,8 @@ int ipoib_vlan_add(struct net_device *pdev, unsigned short pkey)
 
        ppriv = netdev_priv(pdev);
 
+       if (!rtnl_trylock())
+               return restart_syscall();
        mutex_lock(&ppriv->vlan_mutex);
 
        /*
@@ -71,12 +70,14 @@ int ipoib_vlan_add(struct net_device *pdev, unsigned short pkey)
         */
        if (ppriv->pkey == pkey) {
                result = -ENOTUNIQ;
+               priv = NULL;
                goto err;
        }
 
        list_for_each_entry(priv, &ppriv->child_intfs, list) {
                if (priv->pkey == pkey) {
                        result = -ENOTUNIQ;
+                       priv = NULL;
                        goto err;
                }
        }
@@ -89,8 +90,16 @@ int ipoib_vlan_add(struct net_device *pdev, unsigned short pkey)
                goto err;
        }
 
+       priv->max_ib_mtu = ppriv->max_ib_mtu;
+       /* MTU will be reset when mcast join happens */
+       priv->dev->mtu   = IPOIB_UD_MTU(priv->max_ib_mtu);
+       priv->mcast_mtu  = priv->admin_mtu = priv->dev->mtu;
        set_bit(IPOIB_FLAG_SUBINTERFACE, &priv->flags);
 
+       result = ipoib_set_dev_features(priv, ppriv->ca);
+       if (result)
+               goto err;
+
        priv->pkey = pkey;
 
        memcpy(priv->dev->dev_addr, ppriv->dev->dev_addr, INFINIBAND_ALEN);
@@ -102,10 +111,10 @@ int ipoib_vlan_add(struct net_device *pdev, unsigned short pkey)
                ipoib_warn(ppriv, "failed to initialize subinterface: "
                           "device %s, port %d",
                           ppriv->ca->name, ppriv->port);
-               goto device_init_failed;
+               goto err;
        }
 
-       result = register_netdev(priv->dev);
+       result = register_netdevice(priv->dev);
        if (result) {
                ipoib_warn(priv, "failed to initialize; error %i", result);
                goto register_failed;
@@ -115,8 +124,12 @@ int ipoib_vlan_add(struct net_device *pdev, unsigned short pkey)
 
        ipoib_create_debug_files(priv->dev);
 
+       if (ipoib_cm_add_mode_attr(priv->dev))
+               goto sysfs_failed;
        if (ipoib_add_pkey_attr(priv->dev))
                goto sysfs_failed;
+       if (ipoib_add_umcast_attr(priv->dev))
+               goto sysfs_failed;
 
        if (device_create_file(&priv->dev->dev, &dev_attr_parent))
                goto sysfs_failed;
@@ -124,47 +137,55 @@ int ipoib_vlan_add(struct net_device *pdev, unsigned short pkey)
        list_add_tail(&priv->list, &ppriv->child_intfs);
 
        mutex_unlock(&ppriv->vlan_mutex);
+       rtnl_unlock();
 
        return 0;
 
 sysfs_failed:
        ipoib_delete_debug_files(priv->dev);
-       unregister_netdev(priv->dev);
+       unregister_netdevice(priv->dev);
 
 register_failed:
        ipoib_dev_cleanup(priv->dev);
 
-device_init_failed:
-       free_netdev(priv->dev);
-
 err:
        mutex_unlock(&ppriv->vlan_mutex);
+       rtnl_unlock();
+       if (priv)
+               free_netdev(priv->dev);
+
        return result;
 }
 
 int ipoib_vlan_delete(struct net_device *pdev, unsigned short pkey)
 {
        struct ipoib_dev_priv *ppriv, *priv, *tpriv;
-       int ret = -ENOENT;
+       struct net_device *dev = NULL;
 
        if (!capable(CAP_NET_ADMIN))
                return -EPERM;
 
        ppriv = netdev_priv(pdev);
 
+       if (!rtnl_trylock())
+               return restart_syscall();
        mutex_lock(&ppriv->vlan_mutex);
        list_for_each_entry_safe(priv, tpriv, &ppriv->child_intfs, list) {
                if (priv->pkey == pkey) {
-                       unregister_netdev(priv->dev);
+                       unregister_netdevice(priv->dev);
                        ipoib_dev_cleanup(priv->dev);
                        list_del(&priv->list);
-                       free_netdev(priv->dev);
-
-                       ret = 0;
+                       dev = priv->dev;
                        break;
                }
        }
        mutex_unlock(&ppriv->vlan_mutex);
+       rtnl_unlock();
+
+       if (dev) {
+               free_netdev(dev);
+               return 0;
+       }
 
-       return ret;
+       return -ENODEV;
 }