aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethoc.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-05-25 19:59:51 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-05-25 19:59:51 -0400
commitb1cdc4670b9508fcd47a15fbd12f70d269880b37 (patch)
treefea9e2650170886d539488f8b1e064f6ca60ad36 /drivers/net/ethoc.c
parentce7d0226198aac42ed311dd2783232adc16b296d (diff)
parentf925b1303e0672effc78547353bd2ddfe11f5b5f (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6: (63 commits) drivers/net/usb/asix.c: Fix pointer cast. be2net: Bug fix to avoid disabling bottom half during firmware upgrade. proc_dointvec: write a single value hso: add support for new products Phonet: fix potential use-after-free in pep_sock_close() ath9k: remove VEOL support for ad-hoc ath9k: change beacon allocation to prefer the first beacon slot sock.h: fix kernel-doc warning cls_cgroup: Fix build error when built-in macvlan: do proper cleanup in macvlan_common_newlink() V2 be2net: Bug fix in init code in probe net/dccp: expansion of error code size ath9k: Fix rx of mcast/bcast frames in PS mode with auto sleep wireless: fix sta_info.h kernel-doc warnings wireless: fix mac80211.h kernel-doc warnings iwlwifi: testing the wrong variable in iwl_add_bssid_station() ath9k_htc: rare leak in ath9k_hif_usb_alloc_tx_urbs() ath9k_htc: dereferencing before check in hif_usb_tx_cb() rt2x00: Fix rt2800usb TX descriptor writing. rt2x00: Fix failed SLEEP->AWAKE and AWAKE->SLEEP transitions. ...
Diffstat (limited to 'drivers/net/ethoc.c')
-rw-r--r--drivers/net/ethoc.c34
1 files changed, 30 insertions, 4 deletions
diff --git a/drivers/net/ethoc.c b/drivers/net/ethoc.c
index 14cbde5cf68e..6ed2df14ec84 100644
--- a/drivers/net/ethoc.c
+++ b/drivers/net/ethoc.c
@@ -174,6 +174,7 @@ MODULE_PARM_DESC(buffer_size, "DMA buffer allocation size");
174 * @iobase: pointer to I/O memory region 174 * @iobase: pointer to I/O memory region
175 * @membase: pointer to buffer memory region 175 * @membase: pointer to buffer memory region
176 * @dma_alloc: dma allocated buffer size 176 * @dma_alloc: dma allocated buffer size
177 * @io_region_size: I/O memory region size
177 * @num_tx: number of send buffers 178 * @num_tx: number of send buffers
178 * @cur_tx: last send buffer written 179 * @cur_tx: last send buffer written
179 * @dty_tx: last buffer actually sent 180 * @dty_tx: last buffer actually sent
@@ -193,6 +194,7 @@ struct ethoc {
193 void __iomem *iobase; 194 void __iomem *iobase;
194 void __iomem *membase; 195 void __iomem *membase;
195 int dma_alloc; 196 int dma_alloc;
197 resource_size_t io_region_size;
196 198
197 unsigned int num_tx; 199 unsigned int num_tx;
198 unsigned int cur_tx; 200 unsigned int cur_tx;
@@ -943,6 +945,7 @@ static int ethoc_probe(struct platform_device *pdev)
943 priv = netdev_priv(netdev); 945 priv = netdev_priv(netdev);
944 priv->netdev = netdev; 946 priv->netdev = netdev;
945 priv->dma_alloc = 0; 947 priv->dma_alloc = 0;
948 priv->io_region_size = mmio->end - mmio->start + 1;
946 949
947 priv->iobase = devm_ioremap_nocache(&pdev->dev, netdev->base_addr, 950 priv->iobase = devm_ioremap_nocache(&pdev->dev, netdev->base_addr,
948 resource_size(mmio)); 951 resource_size(mmio));
@@ -1047,20 +1050,34 @@ static int ethoc_probe(struct platform_device *pdev)
1047 ret = register_netdev(netdev); 1050 ret = register_netdev(netdev);
1048 if (ret < 0) { 1051 if (ret < 0) {
1049 dev_err(&netdev->dev, "failed to register interface\n"); 1052 dev_err(&netdev->dev, "failed to register interface\n");
1050 goto error; 1053 goto error2;
1051 } 1054 }
1052 1055
1053 goto out; 1056 goto out;
1054 1057
1058error2:
1059 netif_napi_del(&priv->napi);
1055error: 1060error:
1056 mdiobus_unregister(priv->mdio); 1061 mdiobus_unregister(priv->mdio);
1057free_mdio: 1062free_mdio:
1058 kfree(priv->mdio->irq); 1063 kfree(priv->mdio->irq);
1059 mdiobus_free(priv->mdio); 1064 mdiobus_free(priv->mdio);
1060free: 1065free:
1061 if (priv->dma_alloc) 1066 if (priv) {
1062 dma_free_coherent(NULL, priv->dma_alloc, priv->membase, 1067 if (priv->dma_alloc)
1063 netdev->mem_start); 1068 dma_free_coherent(NULL, priv->dma_alloc, priv->membase,
1069 netdev->mem_start);
1070 else if (priv->membase)
1071 devm_iounmap(&pdev->dev, priv->membase);
1072 if (priv->iobase)
1073 devm_iounmap(&pdev->dev, priv->iobase);
1074 }
1075 if (mem)
1076 devm_release_mem_region(&pdev->dev, mem->start,
1077 mem->end - mem->start + 1);
1078 if (mmio)
1079 devm_release_mem_region(&pdev->dev, mmio->start,
1080 mmio->end - mmio->start + 1);
1064 free_netdev(netdev); 1081 free_netdev(netdev);
1065out: 1082out:
1066 return ret; 1083 return ret;
@@ -1078,6 +1095,7 @@ static int ethoc_remove(struct platform_device *pdev)
1078 platform_set_drvdata(pdev, NULL); 1095 platform_set_drvdata(pdev, NULL);
1079 1096
1080 if (netdev) { 1097 if (netdev) {
1098 netif_napi_del(&priv->napi);
1081 phy_disconnect(priv->phy); 1099 phy_disconnect(priv->phy);
1082 priv->phy = NULL; 1100 priv->phy = NULL;
1083 1101
@@ -1089,6 +1107,14 @@ static int ethoc_remove(struct platform_device *pdev)
1089 if (priv->dma_alloc) 1107 if (priv->dma_alloc)
1090 dma_free_coherent(NULL, priv->dma_alloc, priv->membase, 1108 dma_free_coherent(NULL, priv->dma_alloc, priv->membase,
1091 netdev->mem_start); 1109 netdev->mem_start);
1110 else {
1111 devm_iounmap(&pdev->dev, priv->membase);
1112 devm_release_mem_region(&pdev->dev, netdev->mem_start,
1113 netdev->mem_end - netdev->mem_start + 1);
1114 }
1115 devm_iounmap(&pdev->dev, priv->iobase);
1116 devm_release_mem_region(&pdev->dev, netdev->base_addr,
1117 priv->io_region_size);
1092 unregister_netdev(netdev); 1118 unregister_netdev(netdev);
1093 free_netdev(netdev); 1119 free_netdev(netdev);
1094 } 1120 }