Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394...
[safe/jmp/linux-2.6] / drivers / net / ethoc.c
index bd1db92..6ed2df1 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/phy.h>
 #include <linux/platform_device.h>
 #include <linux/sched.h>
+#include <linux/slab.h>
 #include <net/ethoc.h>
 
 static int buffer_size = 0x8000; /* 32 KBytes */
@@ -173,6 +174,7 @@ MODULE_PARM_DESC(buffer_size, "DMA buffer allocation size");
  * @iobase:    pointer to I/O memory region
  * @membase:   pointer to buffer memory region
  * @dma_alloc: dma allocated buffer size
+ * @io_region_size:    I/O memory region size
  * @num_tx:    number of send buffers
  * @cur_tx:    last send buffer written
  * @dty_tx:    last buffer actually sent
@@ -192,6 +194,7 @@ struct ethoc {
        void __iomem *iobase;
        void __iomem *membase;
        int dma_alloc;
+       resource_size_t io_region_size;
 
        unsigned int num_tx;
        unsigned int cur_tx;
@@ -755,7 +758,7 @@ static void ethoc_set_multicast_list(struct net_device *dev)
 {
        struct ethoc *priv = netdev_priv(dev);
        u32 mode = ethoc_read(priv, MODER);
-       struct dev_mc_list *mc = NULL;
+       struct netdev_hw_addr *ha;
        u32 hash[2] = { 0, 0 };
 
        /* set loopback mode if requested */
@@ -783,8 +786,8 @@ static void ethoc_set_multicast_list(struct net_device *dev)
                hash[0] = 0xffffffff;
                hash[1] = 0xffffffff;
        } else {
-               for (mc = dev->mc_list; mc; mc = mc->next) {
-                       u32 crc = ether_crc(mc->dmi_addrlen, mc->dmi_addr);
+               netdev_for_each_mc_addr(ha, dev) {
+                       u32 crc = ether_crc(ETH_ALEN, ha->addr);
                        int bit = (crc >> 26) & 0x3f;
                        hash[bit >> 5] |= 1 << (bit & 0x1f);
                }
@@ -850,7 +853,6 @@ static netdev_tx_t ethoc_start_xmit(struct sk_buff *skb, struct net_device *dev)
                netif_stop_queue(dev);
        }
 
-       dev->trans_start = jiffies;
        spin_unlock_irq(&priv->lock);
 out:
        dev_kfree_skb(skb);
@@ -904,7 +906,7 @@ static int ethoc_probe(struct platform_device *pdev)
        }
 
        mmio = devm_request_mem_region(&pdev->dev, res->start,
-                       res->end - res->start + 1, res->name);
+                       resource_size(res), res->name);
        if (!mmio) {
                dev_err(&pdev->dev, "cannot request I/O memory space\n");
                ret = -ENXIO;
@@ -917,7 +919,7 @@ static int ethoc_probe(struct platform_device *pdev)
        res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
        if (res) {
                mem = devm_request_mem_region(&pdev->dev, res->start,
-                       res->end - res->start + 1, res->name);
+                       resource_size(res), res->name);
                if (!mem) {
                        dev_err(&pdev->dev, "cannot request memory space\n");
                        ret = -ENXIO;
@@ -943,9 +945,10 @@ static int ethoc_probe(struct platform_device *pdev)
        priv = netdev_priv(netdev);
        priv->netdev = netdev;
        priv->dma_alloc = 0;
+       priv->io_region_size = mmio->end - mmio->start + 1;
 
        priv->iobase = devm_ioremap_nocache(&pdev->dev, netdev->base_addr,
-                       mmio->end - mmio->start + 1);
+                       resource_size(mmio));
        if (!priv->iobase) {
                dev_err(&pdev->dev, "cannot remap I/O memory space\n");
                ret = -ENXIO;
@@ -954,7 +957,7 @@ static int ethoc_probe(struct platform_device *pdev)
 
        if (netdev->mem_end) {
                priv->membase = devm_ioremap_nocache(&pdev->dev,
-                       netdev->mem_start, mem->end - mem->start + 1);
+                       netdev->mem_start, resource_size(mem));
                if (!priv->membase) {
                        dev_err(&pdev->dev, "cannot remap memory space\n");
                        ret = -ENXIO;
@@ -1039,7 +1042,6 @@ static int ethoc_probe(struct platform_device *pdev)
        netdev->features |= 0;
 
        /* setup NAPI */
-       memset(&priv->napi, 0, sizeof(priv->napi));
        netif_napi_add(netdev, &priv->napi, ethoc_poll, 64);
 
        spin_lock_init(&priv->rx_lock);
@@ -1048,20 +1050,34 @@ static int ethoc_probe(struct platform_device *pdev)
        ret = register_netdev(netdev);
        if (ret < 0) {
                dev_err(&netdev->dev, "failed to register interface\n");
-               goto error;
+               goto error2;
        }
 
        goto out;
 
+error2:
+       netif_napi_del(&priv->napi);
 error:
        mdiobus_unregister(priv->mdio);
 free_mdio:
        kfree(priv->mdio->irq);
        mdiobus_free(priv->mdio);
 free:
-       if (priv->dma_alloc)
-               dma_free_coherent(NULL, priv->dma_alloc, priv->membase,
-                       netdev->mem_start);
+       if (priv) {
+               if (priv->dma_alloc)
+                       dma_free_coherent(NULL, priv->dma_alloc, priv->membase,
+                                         netdev->mem_start);
+               else if (priv->membase)
+                       devm_iounmap(&pdev->dev, priv->membase);
+               if (priv->iobase)
+                       devm_iounmap(&pdev->dev, priv->iobase);
+       }
+       if (mem)
+               devm_release_mem_region(&pdev->dev, mem->start,
+                                       mem->end - mem->start + 1);
+       if (mmio)
+               devm_release_mem_region(&pdev->dev, mmio->start,
+                                       mmio->end - mmio->start + 1);
        free_netdev(netdev);
 out:
        return ret;
@@ -1079,6 +1095,7 @@ static int ethoc_remove(struct platform_device *pdev)
        platform_set_drvdata(pdev, NULL);
 
        if (netdev) {
+               netif_napi_del(&priv->napi);
                phy_disconnect(priv->phy);
                priv->phy = NULL;
 
@@ -1090,6 +1107,14 @@ static int ethoc_remove(struct platform_device *pdev)
                if (priv->dma_alloc)
                        dma_free_coherent(NULL, priv->dma_alloc, priv->membase,
                                netdev->mem_start);
+               else {
+                       devm_iounmap(&pdev->dev, priv->membase);
+                       devm_release_mem_region(&pdev->dev, netdev->mem_start,
+                               netdev->mem_end - netdev->mem_start + 1);
+               }
+               devm_iounmap(&pdev->dev, priv->iobase);
+               devm_release_mem_region(&pdev->dev, netdev->base_addr,
+                       priv->io_region_size);
                unregister_netdev(netdev);
                free_netdev(netdev);
        }