aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorFlorian Fainelli <florian.fainelli@telecomint.eu>2008-07-13 08:32:18 -0400
committerJeff Garzik <jgarzik@redhat.com>2008-07-22 19:56:32 -0400
commit3d4634193aa95a6d04a786fc12b190d0e4295685 (patch)
treef5dbe0ec58c5961bd97474743d95514cd709657f /drivers/net
parentfec3a23be0daceeb0695f8296aea07ea1ad073d8 (diff)
r6040: rework the RX buffers allocation routine
Rework the RX buffers allocation function so that we do not leak memory in the case we could not allocate skbs for the RX path. Propagate the errors to the r6040_up function where we call the RX buffers allocation function. Also rename the r6040_alloc_txbufs function to r6040_init_txbufs, to reflect what it really does. Signed-Off-By: Joerg Albert <jal2@gmx.de> Signed-off-by: Florian Fainelli <florian.fainelli@telecomint.eu> Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/r6040.c53
1 files changed, 44 insertions, 9 deletions
diff --git a/drivers/net/r6040.c b/drivers/net/r6040.c
index 0972152e5d28..4f2ebb2e71be 100644
--- a/drivers/net/r6040.c
+++ b/drivers/net/r6040.c
@@ -312,7 +312,7 @@ static void r6040_rx_buf_alloc(struct r6040_private *lp, struct net_device *dev)
312 lp->rx_insert_ptr = descptr; 312 lp->rx_insert_ptr = descptr;
313} 313}
314 314
315static void r6040_alloc_txbufs(struct net_device *dev) 315static void r6040_init_txbufs(struct net_device *dev)
316{ 316{
317 struct r6040_private *lp = netdev_priv(dev); 317 struct r6040_private *lp = netdev_priv(dev);
318 318
@@ -322,16 +322,39 @@ static void r6040_alloc_txbufs(struct net_device *dev)
322 r6040_init_ring_desc(lp->tx_ring, lp->tx_ring_dma, TX_DCNT); 322 r6040_init_ring_desc(lp->tx_ring, lp->tx_ring_dma, TX_DCNT);
323} 323}
324 324
325static void r6040_alloc_rxbufs(struct net_device *dev) 325static int r6040_alloc_rxbufs(struct net_device *dev)
326{ 326{
327 struct r6040_private *lp = netdev_priv(dev); 327 struct r6040_private *lp = netdev_priv(dev);
328 328 struct r6040_descriptor *desc;
329 lp->rx_free_desc = 0; 329 struct sk_buff *skb;
330 int rc;
330 331
331 lp->rx_remove_ptr = lp->rx_insert_ptr = lp->rx_ring; 332 lp->rx_remove_ptr = lp->rx_insert_ptr = lp->rx_ring;
332 r6040_init_ring_desc(lp->rx_ring, lp->rx_ring_dma, RX_DCNT); 333 r6040_init_ring_desc(lp->rx_ring, lp->rx_ring_dma, RX_DCNT);
333 334
334 r6040_rx_buf_alloc(lp, dev); 335 /* Allocate skbs for the rx descriptors */
336 desc = lp->rx_ring;
337 do {
338 skb = netdev_alloc_skb(dev, MAX_BUF_SIZE);
339 if (!skb) {
340 printk(KERN_ERR "%s: failed to alloc skb for rx\n", dev->name);
341 rc = -ENOMEM;
342 goto err_exit;
343 }
344 desc->skb_ptr = skb;
345 desc->buf = cpu_to_le32(pci_map_single(lp->pdev,
346 desc->skb_ptr->data,
347 MAX_BUF_SIZE, PCI_DMA_FROMDEVICE));
348 desc->status = 0x8000;
349 desc = desc->vndescp;
350 } while (desc != lp->rx_ring);
351
352 return 0;
353
354err_exit:
355 /* Deallocate all previously allocated skbs */
356 r6040_free_rxbufs(dev);
357 return rc;
335} 358}
336 359
337static void r6040_init_mac_regs(struct net_device *dev) 360static void r6040_init_mac_regs(struct net_device *dev)
@@ -697,14 +720,17 @@ static void r6040_poll_controller(struct net_device *dev)
697#endif 720#endif
698 721
699/* Init RDC MAC */ 722/* Init RDC MAC */
700static void r6040_up(struct net_device *dev) 723static int r6040_up(struct net_device *dev)
701{ 724{
702 struct r6040_private *lp = netdev_priv(dev); 725 struct r6040_private *lp = netdev_priv(dev);
703 void __iomem *ioaddr = lp->base; 726 void __iomem *ioaddr = lp->base;
727 int ret;
704 728
705 /* Initialise and alloc RX/TX buffers */ 729 /* Initialise and alloc RX/TX buffers */
706 r6040_alloc_txbufs(dev); 730 r6040_init_txbufs(dev);
707 r6040_alloc_rxbufs(dev); 731 ret = r6040_alloc_rxbufs(dev);
732 if (ret)
733 return ret;
708 734
709 /* Read the PHY ID */ 735 /* Read the PHY ID */
710 lp->switch_sig = r6040_phy_read(ioaddr, 0, 2); 736 lp->switch_sig = r6040_phy_read(ioaddr, 0, 2);
@@ -734,6 +760,8 @@ static void r6040_up(struct net_device *dev)
734 760
735 /* Initialize all MAC registers */ 761 /* Initialize all MAC registers */
736 r6040_init_mac_regs(dev); 762 r6040_init_mac_regs(dev);
763
764 return 0;
737} 765}
738 766
739/* 767/*
@@ -812,7 +840,14 @@ static int r6040_open(struct net_device *dev)
812 return -ENOMEM; 840 return -ENOMEM;
813 } 841 }
814 842
815 r6040_up(dev); 843 ret = r6040_up(dev);
844 if (ret) {
845 pci_free_consistent(lp->pdev, TX_DESC_SIZE, lp->tx_ring,
846 lp->tx_ring_dma);
847 pci_free_consistent(lp->pdev, RX_DESC_SIZE, lp->rx_ring,
848 lp->rx_ring_dma);
849 return ret;
850 }
816 851
817 napi_enable(&lp->napi); 852 napi_enable(&lp->napi);
818 netif_start_queue(dev); 853 netif_start_queue(dev);