diff options
author | Nathan Hintz <nlhintz@hotmail.com> | 2013-10-29 22:32:01 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-10-29 22:59:19 -0400 |
commit | b757a62e9f0df5c997c666dca4ad81197b5d8917 (patch) | |
tree | 9d5eea9809b64db417adbb5b4d375b1b6722f128 | |
parent | 32663b8b8948cc05f812ab82c1c7db2db3ddf717 (diff) |
bgmac: don't update slot on skb alloc/dma mapping error
Don't update the slot in "bgmac_dma_rx_skb_for_slot" unless both the
skb alloc and dma mapping are successful; and free the newly allocated
skb if a dma mapping error occurs. This relieves the caller of the need
to deduce/execute the appropriate cleanup action required when an error
occurs.
Signed-off-by: Nathan Hintz <nlhintz@hotmail.com>
Acked-by: Rafał Miłecki <zajec5@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/ethernet/broadcom/bgmac.c | 20 |
1 files changed, 14 insertions, 6 deletions
diff --git a/drivers/net/ethernet/broadcom/bgmac.c b/drivers/net/ethernet/broadcom/bgmac.c index 249468f95365..9e8a3e024e01 100644 --- a/drivers/net/ethernet/broadcom/bgmac.c +++ b/drivers/net/ethernet/broadcom/bgmac.c | |||
@@ -244,25 +244,33 @@ static int bgmac_dma_rx_skb_for_slot(struct bgmac *bgmac, | |||
244 | struct bgmac_slot_info *slot) | 244 | struct bgmac_slot_info *slot) |
245 | { | 245 | { |
246 | struct device *dma_dev = bgmac->core->dma_dev; | 246 | struct device *dma_dev = bgmac->core->dma_dev; |
247 | struct sk_buff *skb; | ||
248 | dma_addr_t dma_addr; | ||
247 | struct bgmac_rx_header *rx; | 249 | struct bgmac_rx_header *rx; |
248 | 250 | ||
249 | /* Alloc skb */ | 251 | /* Alloc skb */ |
250 | slot->skb = netdev_alloc_skb(bgmac->net_dev, BGMAC_RX_BUF_SIZE); | 252 | skb = netdev_alloc_skb(bgmac->net_dev, BGMAC_RX_BUF_SIZE); |
251 | if (!slot->skb) | 253 | if (!skb) |
252 | return -ENOMEM; | 254 | return -ENOMEM; |
253 | 255 | ||
254 | /* Poison - if everything goes fine, hardware will overwrite it */ | 256 | /* Poison - if everything goes fine, hardware will overwrite it */ |
255 | rx = (struct bgmac_rx_header *)slot->skb->data; | 257 | rx = (struct bgmac_rx_header *)skb->data; |
256 | rx->len = cpu_to_le16(0xdead); | 258 | rx->len = cpu_to_le16(0xdead); |
257 | rx->flags = cpu_to_le16(0xbeef); | 259 | rx->flags = cpu_to_le16(0xbeef); |
258 | 260 | ||
259 | /* Map skb for the DMA */ | 261 | /* Map skb for the DMA */ |
260 | slot->dma_addr = dma_map_single(dma_dev, slot->skb->data, | 262 | dma_addr = dma_map_single(dma_dev, skb->data, |
261 | BGMAC_RX_BUF_SIZE, DMA_FROM_DEVICE); | 263 | BGMAC_RX_BUF_SIZE, DMA_FROM_DEVICE); |
262 | if (dma_mapping_error(dma_dev, slot->dma_addr)) { | 264 | if (dma_mapping_error(dma_dev, dma_addr)) { |
263 | bgmac_err(bgmac, "DMA mapping error\n"); | 265 | bgmac_err(bgmac, "DMA mapping error\n"); |
266 | dev_kfree_skb(skb); | ||
264 | return -ENOMEM; | 267 | return -ENOMEM; |
265 | } | 268 | } |
269 | |||
270 | /* Update the slot */ | ||
271 | slot->skb = skb; | ||
272 | slot->dma_addr = dma_addr; | ||
273 | |||
266 | if (slot->dma_addr & 0xC0000000) | 274 | if (slot->dma_addr & 0xC0000000) |
267 | bgmac_warn(bgmac, "DMA address using 0xC0000000 bit(s), it may need translation trick\n"); | 275 | bgmac_warn(bgmac, "DMA address using 0xC0000000 bit(s), it may need translation trick\n"); |
268 | 276 | ||