mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-06 02:50:49 +09:00
net: dlink: handle dma_map_single() failure properly
[ Upstream commit 65946eac6d888d50ae527c4e5c237dbe5cc3a2f2 ]
There is no error handling for `dma_map_single()` failures.
Add error handling by checking `dma_mapping_error()` and freeing
the `skb` using `dev_kfree_skb()` (process context) when it fails.
Fixes: 1da177e4c3 ("Linux-2.6.12-rc2")
Signed-off-by: Yeounsu Moon <yyyynoom@gmail.com>
Tested-on: D-Link DGE-550T Rev-A3
Suggested-by: Simon Horman <horms@kernel.org>
Reviewed-by: Simon Horman <horms@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
e3fdc2b2c6
commit
3f4a318dec
@@ -498,25 +498,34 @@ static int alloc_list(struct net_device *dev)
|
||||
for (i = 0; i < RX_RING_SIZE; i++) {
|
||||
/* Allocated fixed size of skbuff */
|
||||
struct sk_buff *skb;
|
||||
dma_addr_t addr;
|
||||
|
||||
skb = netdev_alloc_skb_ip_align(dev, np->rx_buf_sz);
|
||||
np->rx_skbuff[i] = skb;
|
||||
if (!skb) {
|
||||
free_list(dev);
|
||||
return -ENOMEM;
|
||||
}
|
||||
if (!skb)
|
||||
goto err_free_list;
|
||||
|
||||
addr = dma_map_single(&np->pdev->dev, skb->data,
|
||||
np->rx_buf_sz, DMA_FROM_DEVICE);
|
||||
if (dma_mapping_error(&np->pdev->dev, addr))
|
||||
goto err_kfree_skb;
|
||||
|
||||
np->rx_ring[i].next_desc = cpu_to_le64(np->rx_ring_dma +
|
||||
((i + 1) % RX_RING_SIZE) *
|
||||
sizeof(struct netdev_desc));
|
||||
/* Rubicon now supports 40 bits of addressing space. */
|
||||
np->rx_ring[i].fraginfo =
|
||||
cpu_to_le64(dma_map_single(&np->pdev->dev, skb->data,
|
||||
np->rx_buf_sz, DMA_FROM_DEVICE));
|
||||
np->rx_ring[i].fraginfo = cpu_to_le64(addr);
|
||||
np->rx_ring[i].fraginfo |= cpu_to_le64((u64)np->rx_buf_sz << 48);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_kfree_skb:
|
||||
dev_kfree_skb(np->rx_skbuff[i]);
|
||||
np->rx_skbuff[i] = NULL;
|
||||
err_free_list:
|
||||
free_list(dev);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
static void rio_hw_init(struct net_device *dev)
|
||||
|
||||
Reference in New Issue
Block a user