]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - net/hsr/hsr_device.c
Merge branches 'acpi-misc' and 'acpi-video'
[linux.git] / net / hsr / hsr_device.c
index 15c72065df79103fa78ee47db8f076a62529b055..f0f9b493c47b9e9cccc01e2fdde58fd649d35cd9 100644 (file)
@@ -227,9 +227,13 @@ static int hsr_dev_xmit(struct sk_buff *skb, struct net_device *dev)
        struct hsr_port *master;
 
        master = hsr_port_get_hsr(hsr, HSR_PT_MASTER);
-       skb->dev = master->dev;
-       hsr_forward_skb(skb, master);
-
+       if (master) {
+               skb->dev = master->dev;
+               hsr_forward_skb(skb, master);
+       } else {
+               atomic_long_inc(&dev->tx_dropped);
+               dev_kfree_skb_any(skb);
+       }
        return NETDEV_TX_OK;
 }
 
@@ -344,27 +348,26 @@ static void hsr_announce(struct timer_list *t)
        rcu_read_unlock();
 }
 
-/* According to comments in the declaration of struct net_device, this function
- * is "Called from unregister, can be used to call free_netdev". Ok then...
- */
-static void hsr_dev_destroy(struct net_device *hsr_dev)
+void hsr_dev_destroy(struct net_device *hsr_dev)
 {
        struct hsr_priv *hsr;
        struct hsr_port *port;
+       struct hsr_port *tmp;
 
        hsr = netdev_priv(hsr_dev);
 
        hsr_debugfs_term(hsr);
 
-       rtnl_lock();
-       hsr_for_each_port(hsr, port)
+       list_for_each_entry_safe(port, tmp, &hsr->ports, port_list)
                hsr_del_port(port);
-       rtnl_unlock();
 
        del_timer_sync(&hsr->prune_timer);
        del_timer_sync(&hsr->announce_timer);
 
        synchronize_rcu();
+
+       hsr_del_self_node(&hsr->self_node_db);
+       hsr_del_nodes(&hsr->node_db);
 }
 
 static const struct net_device_ops hsr_device_ops = {
@@ -391,7 +394,6 @@ void hsr_dev_setup(struct net_device *dev)
        dev->priv_flags |= IFF_NO_QUEUE;
 
        dev->needs_free_netdev = true;
-       dev->priv_destructor = hsr_dev_destroy;
 
        dev->hw_features = NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_HIGHDMA |
                           NETIF_F_GSO_MASK | NETIF_F_HW_CSUM |
@@ -428,6 +430,7 @@ int hsr_dev_finalize(struct net_device *hsr_dev, struct net_device *slave[2],
 {
        struct hsr_priv *hsr;
        struct hsr_port *port;
+       struct hsr_port *tmp;
        int res;
 
        hsr = netdev_priv(hsr_dev);
@@ -492,10 +495,10 @@ int hsr_dev_finalize(struct net_device *hsr_dev, struct net_device *slave[2],
        return 0;
 
 fail:
-       hsr_for_each_port(hsr, port)
+       list_for_each_entry_safe(port, tmp, &hsr->ports, port_list)
                hsr_del_port(port);
 err_add_port:
-       hsr_del_node(&hsr->self_node_db);
+       hsr_del_self_node(&hsr->self_node_db);
 
        return res;
 }