]> err.no Git - linux-2.6/blobdiff - drivers/net/bonding/bond_main.c
ath5k: Misc hw_attach fixes
[linux-2.6] / drivers / net / bonding / bond_main.c
index d57b65dc2c72d518d3dab4c6d4f1779db23c07cd..a641eeaa2a2f488bdef9a074e431c187321135f7 100644 (file)
@@ -772,39 +772,49 @@ static struct dev_mc_list *bond_mc_list_find_dmi(struct dev_mc_list *dmi, struct
 /*
  * Push the promiscuity flag down to appropriate slaves
  */
-static void bond_set_promiscuity(struct bonding *bond, int inc)
+static int bond_set_promiscuity(struct bonding *bond, int inc)
 {
+       int err = 0;
        if (USES_PRIMARY(bond->params.mode)) {
                /* write lock already acquired */
                if (bond->curr_active_slave) {
-                       dev_set_promiscuity(bond->curr_active_slave->dev, inc);
+                       err = dev_set_promiscuity(bond->curr_active_slave->dev,
+                                                 inc);
                }
        } else {
                struct slave *slave;
                int i;
                bond_for_each_slave(bond, slave, i) {
-                       dev_set_promiscuity(slave->dev, inc);
+                       err = dev_set_promiscuity(slave->dev, inc);
+                       if (err)
+                               return err;
                }
        }
+       return err;
 }
 
 /*
  * Push the allmulti flag down to all slaves
  */
-static void bond_set_allmulti(struct bonding *bond, int inc)
+static int bond_set_allmulti(struct bonding *bond, int inc)
 {
+       int err = 0;
        if (USES_PRIMARY(bond->params.mode)) {
                /* write lock already acquired */
                if (bond->curr_active_slave) {
-                       dev_set_allmulti(bond->curr_active_slave->dev, inc);
+                       err = dev_set_allmulti(bond->curr_active_slave->dev,
+                                              inc);
                }
        } else {
                struct slave *slave;
                int i;
                bond_for_each_slave(bond, slave, i) {
-                       dev_set_allmulti(slave->dev, inc);
+                       err = dev_set_allmulti(slave->dev, inc);
+                       if (err)
+                               return err;
                }
        }
+       return err;
 }
 
 /*
@@ -965,6 +975,7 @@ static void bond_mc_swap(struct bonding *bond, struct slave *new_active, struct
        }
 
        if (new_active) {
+               /* FIXME: Signal errors upstream. */
                if (bond->dev->flags & IFF_PROMISC) {
                        dev_set_promiscuity(new_active->dev, 1);
                }
@@ -1544,20 +1555,24 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
        if (!USES_PRIMARY(bond->params.mode)) {
                /* set promiscuity level to new slave */
                if (bond_dev->flags & IFF_PROMISC) {
-                       dev_set_promiscuity(slave_dev, 1);
+                       res = dev_set_promiscuity(slave_dev, 1);
+                       if (res)
+                               goto err_close;
                }
 
                /* set allmulti level to new slave */
                if (bond_dev->flags & IFF_ALLMULTI) {
-                       dev_set_allmulti(slave_dev, 1);
+                       res = dev_set_allmulti(slave_dev, 1);
+                       if (res)
+                               goto err_close;
                }
 
-               netif_tx_lock_bh(bond_dev);
+               netif_addr_lock_bh(bond_dev);
                /* upload master's mc_list to new slave */
                for (dmi = bond_dev->mc_list; dmi; dmi = dmi->next) {
                        dev_mc_add (slave_dev, dmi->dmi_addr, dmi->dmi_addrlen, 0);
                }
-               netif_tx_unlock_bh(bond_dev);
+               netif_addr_unlock_bh(bond_dev);
        }
 
        if (bond->params.mode == BOND_MODE_8023AD) {
@@ -1921,9 +1936,9 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
                }
 
                /* flush master's mc_list from slave */
-               netif_tx_lock_bh(bond_dev);
+               netif_addr_lock_bh(bond_dev);
                bond_mc_list_flush(bond_dev, slave_dev);
-               netif_tx_unlock_bh(bond_dev);
+               netif_addr_unlock_bh(bond_dev);
        }
 
        netdev_set_master(slave_dev, NULL);
@@ -2044,9 +2059,9 @@ static int bond_release_all(struct net_device *bond_dev)
                        }
 
                        /* flush master's mc_list from slave */
-                       netif_tx_lock_bh(bond_dev);
+                       netif_addr_lock_bh(bond_dev);
                        bond_mc_list_flush(bond_dev, slave_dev);
-                       netif_tx_unlock_bh(bond_dev);
+                       netif_addr_unlock_bh(bond_dev);
                }
 
                netdev_set_master(slave_dev, NULL);
@@ -4065,6 +4080,10 @@ static void bond_set_multicast_list(struct net_device *bond_dev)
         * Do promisc before checking multicast_mode
         */
        if ((bond_dev->flags & IFF_PROMISC) && !(bond->flags & IFF_PROMISC)) {
+               /*
+                * FIXME: Need to handle the error when one of the multi-slaves
+                * encounters error.
+                */
                bond_set_promiscuity(bond, 1);
        }
 
@@ -4074,6 +4093,10 @@ static void bond_set_multicast_list(struct net_device *bond_dev)
 
        /* set allmulti flag to slaves */
        if ((bond_dev->flags & IFF_ALLMULTI) && !(bond->flags & IFF_ALLMULTI)) {
+               /*
+                * FIXME: Need to handle the error when one of the multi-slaves
+                * encounters error.
+                */
                bond_set_allmulti(bond, 1);
        }
 
@@ -4650,9 +4673,9 @@ static void bond_free_all(void)
                struct net_device *bond_dev = bond->dev;
 
                bond_work_cancel_all(bond);
-               netif_tx_lock_bh(bond_dev);
+               netif_addr_lock_bh(bond_dev);
                bond_mc_list_destroy(bond);
-               netif_tx_unlock_bh(bond_dev);
+               netif_addr_unlock_bh(bond_dev);
                /* Release the bonded slaves */
                bond_release_all(bond_dev);
                bond_destroy(bond);
@@ -5018,6 +5041,22 @@ static int bond_check_params(struct bond_params *params)
 }
 
 static struct lock_class_key bonding_netdev_xmit_lock_key;
+static struct lock_class_key bonding_netdev_addr_lock_key;
+
+static void bond_set_lockdep_class_one(struct net_device *dev,
+                                      struct netdev_queue *txq,
+                                      void *_unused)
+{
+       lockdep_set_class(&txq->_xmit_lock,
+                         &bonding_netdev_xmit_lock_key);
+}
+
+static void bond_set_lockdep_class(struct net_device *dev)
+{
+       lockdep_set_class(&dev->addr_list_lock,
+                         &bonding_netdev_addr_lock_key);
+       netdev_for_each_tx_queue(dev, bond_set_lockdep_class_one, NULL);
+}
 
 /* Create a new bond based on the specified name and bonding parameters.
  * If name is NULL, obtain a suitable "bond%d" name for us.
@@ -5076,7 +5115,7 @@ int bond_create(char *name, struct bond_params *params)
                goto out_bond;
        }
 
-       lockdep_set_class(&bond_dev->_xmit_lock, &bonding_netdev_xmit_lock_key);
+       bond_set_lockdep_class(bond_dev);
 
        netif_carrier_off(bond_dev);