diff options
author | Russell King <rmk+kernel@arm.linux.org.uk> | 2014-07-07 19:23:30 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-07-08 00:21:23 -0400 |
commit | ffdce2cc6a18e3460fd31a399934004bf4cf6539 (patch) | |
tree | 995647ca7efe3a7c9c8fd369c2dd66334122099b /drivers/net/ethernet/freescale/fec_main.c | |
parent | 8b7c9efa018f96e58fa379ddb8c03f002c4f6a84 (diff) |
net: fec: fix missing kmalloc() failure check in fec_enet_alloc_buffers()
fec_enet_alloc_buffers() assumes that kmalloc() will never fail, which
is an invalid assumption. Fix this by implementing a common error
cleanup path, and use it to also clean up after failed bounce buffer
allocation.
Acked-by: Fugang Duan <B38611@freescale.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/freescale/fec_main.c')
-rw-r--r-- | drivers/net/ethernet/freescale/fec_main.c | 15 |
1 files changed, 9 insertions, 6 deletions
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c index 5499bd8ad0a5..f43c388e2eb9 100644 --- a/drivers/net/ethernet/freescale/fec_main.c +++ b/drivers/net/ethernet/freescale/fec_main.c | |||
@@ -2100,19 +2100,16 @@ static int fec_enet_alloc_buffers(struct net_device *ndev) | |||
2100 | dma_addr_t addr; | 2100 | dma_addr_t addr; |
2101 | 2101 | ||
2102 | skb = netdev_alloc_skb(ndev, FEC_ENET_RX_FRSIZE); | 2102 | skb = netdev_alloc_skb(ndev, FEC_ENET_RX_FRSIZE); |
2103 | if (!skb) { | 2103 | if (!skb) |
2104 | fec_enet_free_buffers(ndev); | 2104 | goto err_alloc; |
2105 | return -ENOMEM; | ||
2106 | } | ||
2107 | 2105 | ||
2108 | addr = dma_map_single(&fep->pdev->dev, skb->data, | 2106 | addr = dma_map_single(&fep->pdev->dev, skb->data, |
2109 | FEC_ENET_RX_FRSIZE, DMA_FROM_DEVICE); | 2107 | FEC_ENET_RX_FRSIZE, DMA_FROM_DEVICE); |
2110 | if (dma_mapping_error(&fep->pdev->dev, addr)) { | 2108 | if (dma_mapping_error(&fep->pdev->dev, addr)) { |
2111 | dev_kfree_skb(skb); | 2109 | dev_kfree_skb(skb); |
2112 | fec_enet_free_buffers(ndev); | ||
2113 | if (net_ratelimit()) | 2110 | if (net_ratelimit()) |
2114 | netdev_err(ndev, "Rx DMA memory map failed\n"); | 2111 | netdev_err(ndev, "Rx DMA memory map failed\n"); |
2115 | return -ENOMEM; | 2112 | goto err_alloc; |
2116 | } | 2113 | } |
2117 | 2114 | ||
2118 | fep->rx_skbuff[i] = skb; | 2115 | fep->rx_skbuff[i] = skb; |
@@ -2134,6 +2131,8 @@ static int fec_enet_alloc_buffers(struct net_device *ndev) | |||
2134 | bdp = fep->tx_bd_base; | 2131 | bdp = fep->tx_bd_base; |
2135 | for (i = 0; i < fep->tx_ring_size; i++) { | 2132 | for (i = 0; i < fep->tx_ring_size; i++) { |
2136 | fep->tx_bounce[i] = kmalloc(FEC_ENET_TX_FRSIZE, GFP_KERNEL); | 2133 | fep->tx_bounce[i] = kmalloc(FEC_ENET_TX_FRSIZE, GFP_KERNEL); |
2134 | if (!fep->tx_bounce[i]) | ||
2135 | goto err_alloc; | ||
2137 | 2136 | ||
2138 | bdp->cbd_sc = 0; | 2137 | bdp->cbd_sc = 0; |
2139 | bdp->cbd_bufaddr = 0; | 2138 | bdp->cbd_bufaddr = 0; |
@@ -2151,6 +2150,10 @@ static int fec_enet_alloc_buffers(struct net_device *ndev) | |||
2151 | bdp->cbd_sc |= BD_SC_WRAP; | 2150 | bdp->cbd_sc |= BD_SC_WRAP; |
2152 | 2151 | ||
2153 | return 0; | 2152 | return 0; |
2153 | |||
2154 | err_alloc: | ||
2155 | fec_enet_free_buffers(ndev); | ||
2156 | return -ENOMEM; | ||
2154 | } | 2157 | } |
2155 | 2158 | ||
2156 | static int | 2159 | static int |