Commit 65946eac authored by Yeounsu Moon's avatar Yeounsu Moon Committed by David S. Miller
Browse files

net: dlink: handle dma_map_single() failure properly



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: 1da177e4 ("Linux-2.6.12-rc2")
Signed-off-by: default avatarYeounsu Moon <yyyynoom@gmail.com>
Tested-on: D-Link DGE-550T Rev-A3
Suggested-by: default avatarSimon Horman <horms@kernel.org>
Reviewed-by: default avatarSimon Horman <horms@kernel.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 3abc0e55
Loading
Loading
Loading
Loading
+16 −7
Original line number Diff line number Diff line
@@ -508,25 +508,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)