summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorfrançois romieu <romieu@fr.zoreil.com>2012-12-01 13:08:50 +0000
committerDavid S. Miller <davem@davemloft.net>2012-12-01 20:39:17 -0500
commit892a925e42adb8192a3c832ad29cbc780fc466f6 (patch)
treec89458159f626aa6b722d04331b1bb43c258d150 /drivers
parent64022d0b4e93ea432e95db55a72b8a1c5775f3c0 (diff)
8139cp: fix coherent mapping leak in error path.
cp_open [...] rc = cp_alloc_rings(cp); if (rc) return rc; cp_alloc_rings [...] mem = dma_alloc_coherent(&cp->pdev->dev, CP_RING_BYTES, &cp->ring_dma, GFP_KERNEL); - cp_alloc_rings never frees the coherent mapping it allocates - neither do cp_open when cp_alloc_rings fails Signed-off-by: Francois Romieu <romieu@fr.zoreil.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/ethernet/realtek/8139cp.c11
1 files changed, 8 insertions, 3 deletions
diff --git a/drivers/net/ethernet/realtek/8139cp.c b/drivers/net/ethernet/realtek/8139cp.c
index b01f83a044c..609125a249d 100644
--- a/drivers/net/ethernet/realtek/8139cp.c
+++ b/drivers/net/ethernet/realtek/8139cp.c
@@ -1060,17 +1060,22 @@ static int cp_init_rings (struct cp_private *cp)
static int cp_alloc_rings (struct cp_private *cp)
{
+ struct device *d = &cp->pdev->dev;
void *mem;
+ int rc;
- mem = dma_alloc_coherent(&cp->pdev->dev, CP_RING_BYTES,
- &cp->ring_dma, GFP_KERNEL);
+ mem = dma_alloc_coherent(d, CP_RING_BYTES, &cp->ring_dma, GFP_KERNEL);
if (!mem)
return -ENOMEM;
cp->rx_ring = mem;
cp->tx_ring = &cp->rx_ring[CP_RX_RING_SIZE];
- return cp_init_rings(cp);
+ rc = cp_init_rings(cp);
+ if (rc < 0)
+ dma_free_coherent(d, CP_RING_BYTES, cp->rx_ring, cp->ring_dma);
+
+ return rc;
}
static void cp_clean_rings (struct cp_private *cp)