Commit a88c844c authored by Don Fry's avatar Don Fry Committed by Jeff Garzik

[PATCH] pcnet32: show name of failing device

Display the name eth%d or pci_name() of device which fails to allocate
memory.  When changing ring size via ethtool, it also releases the
lock before returning on error.  Added comment that the caller of
pcnet32_alloc_ring must call pcnet32_free_ring on error, to avoid leak.
Tested ia32 by forcing allocation errors.
Signed-off-by: default avatarDon Fry <brazilnut@us.ibm.com>
Signed-off-by: default avatarJeff Garzik <jgarzik@pobox.com>
parent 571de88b
...@@ -22,8 +22,8 @@ ...@@ -22,8 +22,8 @@
*************************************************************************/ *************************************************************************/
#define DRV_NAME "pcnet32" #define DRV_NAME "pcnet32"
#define DRV_VERSION "1.31a" #define DRV_VERSION "1.31b"
#define DRV_RELDATE "12.Sep.2005" #define DRV_RELDATE "06.Oct.2005"
#define PFX DRV_NAME ": " #define PFX DRV_NAME ": "
static const char *version = static const char *version =
...@@ -260,6 +260,8 @@ static int homepna[MAX_UNITS]; ...@@ -260,6 +260,8 @@ static int homepna[MAX_UNITS];
* v1.31 02 Sep 2005 Hubert WS Lin <wslin@tw.ibm.c0m> added set_ringparam(). * v1.31 02 Sep 2005 Hubert WS Lin <wslin@tw.ibm.c0m> added set_ringparam().
* v1.31a 12 Sep 2005 Hubert WS Lin <wslin@tw.ibm.c0m> set min ring size to 4 * v1.31a 12 Sep 2005 Hubert WS Lin <wslin@tw.ibm.c0m> set min ring size to 4
* to allow loopback test to work unchanged. * to allow loopback test to work unchanged.
* v1.31b 06 Oct 2005 Don Fry changed alloc_ring to show name of device
* if allocation fails
*/ */
...@@ -408,7 +410,7 @@ static int pcnet32_get_regs_len(struct net_device *dev); ...@@ -408,7 +410,7 @@ static int pcnet32_get_regs_len(struct net_device *dev);
static void pcnet32_get_regs(struct net_device *dev, struct ethtool_regs *regs, static void pcnet32_get_regs(struct net_device *dev, struct ethtool_regs *regs,
void *ptr); void *ptr);
static void pcnet32_purge_tx_ring(struct net_device *dev); static void pcnet32_purge_tx_ring(struct net_device *dev);
static int pcnet32_alloc_ring(struct net_device *dev); static int pcnet32_alloc_ring(struct net_device *dev, char *name);
static void pcnet32_free_ring(struct net_device *dev); static void pcnet32_free_ring(struct net_device *dev);
...@@ -669,15 +671,17 @@ static int pcnet32_set_ringparam(struct net_device *dev, struct ethtool_ringpara ...@@ -669,15 +671,17 @@ static int pcnet32_set_ringparam(struct net_device *dev, struct ethtool_ringpara
lp->rx_mod_mask = lp->rx_ring_size - 1; lp->rx_mod_mask = lp->rx_ring_size - 1;
lp->rx_len_bits = (i << 4); lp->rx_len_bits = (i << 4);
if (pcnet32_alloc_ring(dev)) { if (pcnet32_alloc_ring(dev, dev->name)) {
pcnet32_free_ring(dev); pcnet32_free_ring(dev);
spin_unlock_irqrestore(&lp->lock, flags);
return -ENOMEM; return -ENOMEM;
} }
spin_unlock_irqrestore(&lp->lock, flags); spin_unlock_irqrestore(&lp->lock, flags);
if (pcnet32_debug & NETIF_MSG_DRV) if (pcnet32_debug & NETIF_MSG_DRV)
printk(KERN_INFO PFX "Ring Param Settings: RX: %d, TX: %d\n", lp->rx_ring_size, lp->tx_ring_size); printk(KERN_INFO PFX "%s: Ring Param Settings: RX: %d, TX: %d\n",
dev->name, lp->rx_ring_size, lp->tx_ring_size);
if (netif_running(dev)) if (netif_running(dev))
pcnet32_open(dev); pcnet32_open(dev);
...@@ -1340,7 +1344,8 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev) ...@@ -1340,7 +1344,8 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev)
} }
lp->a = *a; lp->a = *a;
if (pcnet32_alloc_ring(dev)) { /* prior to register_netdev, dev->name is not yet correct */
if (pcnet32_alloc_ring(dev, pci_name(lp->pci_dev))) {
ret = -ENOMEM; ret = -ENOMEM;
goto err_free_ring; goto err_free_ring;
} }
...@@ -1448,48 +1453,63 @@ err_release_region: ...@@ -1448,48 +1453,63 @@ err_release_region:
} }
static int pcnet32_alloc_ring(struct net_device *dev) /* if any allocation fails, caller must also call pcnet32_free_ring */
static int pcnet32_alloc_ring(struct net_device *dev, char *name)
{ {
struct pcnet32_private *lp = dev->priv; struct pcnet32_private *lp = dev->priv;
if ((lp->tx_ring = pci_alloc_consistent(lp->pci_dev, sizeof(struct pcnet32_tx_head) * lp->tx_ring_size, lp->tx_ring = pci_alloc_consistent(lp->pci_dev,
&lp->tx_ring_dma_addr)) == NULL) { sizeof(struct pcnet32_tx_head) * lp->tx_ring_size,
&lp->tx_ring_dma_addr);
if (lp->tx_ring == NULL) {
if (pcnet32_debug & NETIF_MSG_DRV) if (pcnet32_debug & NETIF_MSG_DRV)
printk(KERN_ERR PFX "Consistent memory allocation failed.\n"); printk("\n" KERN_ERR PFX "%s: Consistent memory allocation failed.\n",
name);
return -ENOMEM; return -ENOMEM;
} }
if ((lp->rx_ring = pci_alloc_consistent(lp->pci_dev, sizeof(struct pcnet32_rx_head) * lp->rx_ring_size, lp->rx_ring = pci_alloc_consistent(lp->pci_dev,
&lp->rx_ring_dma_addr)) == NULL) { sizeof(struct pcnet32_rx_head) * lp->rx_ring_size,
&lp->rx_ring_dma_addr);
if (lp->rx_ring == NULL) {
if (pcnet32_debug & NETIF_MSG_DRV) if (pcnet32_debug & NETIF_MSG_DRV)
printk(KERN_ERR PFX "Consistent memory allocation failed.\n"); printk("\n" KERN_ERR PFX "%s: Consistent memory allocation failed.\n",
name);
return -ENOMEM; return -ENOMEM;
} }
if (!(lp->tx_dma_addr = kmalloc(sizeof(dma_addr_t) * lp->tx_ring_size, GFP_ATOMIC))) { lp->tx_dma_addr = kmalloc(sizeof(dma_addr_t) * lp->tx_ring_size,
GFP_ATOMIC);
if (!lp->tx_dma_addr) {
if (pcnet32_debug & NETIF_MSG_DRV) if (pcnet32_debug & NETIF_MSG_DRV)
printk(KERN_ERR PFX "Memory allocation failed.\n"); printk("\n" KERN_ERR PFX "%s: Memory allocation failed.\n", name);
return -ENOMEM; return -ENOMEM;
} }
memset(lp->tx_dma_addr, 0, sizeof(dma_addr_t) * lp->tx_ring_size); memset(lp->tx_dma_addr, 0, sizeof(dma_addr_t) * lp->tx_ring_size);
if (!(lp->rx_dma_addr = kmalloc(sizeof(dma_addr_t) * lp->rx_ring_size, GFP_ATOMIC))) { lp->rx_dma_addr = kmalloc(sizeof(dma_addr_t) * lp->rx_ring_size,
GFP_ATOMIC);
if (!lp->rx_dma_addr) {
if (pcnet32_debug & NETIF_MSG_DRV) if (pcnet32_debug & NETIF_MSG_DRV)
printk(KERN_ERR PFX "Memory allocation failed.\n"); printk("\n" KERN_ERR PFX "%s: Memory allocation failed.\n", name);
return -ENOMEM; return -ENOMEM;
} }
memset(lp->rx_dma_addr, 0, sizeof(dma_addr_t) * lp->rx_ring_size); memset(lp->rx_dma_addr, 0, sizeof(dma_addr_t) * lp->rx_ring_size);
if (!(lp->tx_skbuff = kmalloc(sizeof(struct sk_buff *) * lp->tx_ring_size, GFP_ATOMIC))) { lp->tx_skbuff = kmalloc(sizeof(struct sk_buff *) * lp->tx_ring_size,
GFP_ATOMIC);
if (!lp->tx_skbuff) {
if (pcnet32_debug & NETIF_MSG_DRV) if (pcnet32_debug & NETIF_MSG_DRV)
printk(KERN_ERR PFX "Memory allocation failed.\n"); printk("\n" KERN_ERR PFX "%s: Memory allocation failed.\n", name);
return -ENOMEM; return -ENOMEM;
} }
memset(lp->tx_skbuff, 0, sizeof(struct sk_buff *) * lp->tx_ring_size); memset(lp->tx_skbuff, 0, sizeof(struct sk_buff *) * lp->tx_ring_size);
if (!(lp->rx_skbuff = kmalloc(sizeof(struct sk_buff *) * lp->rx_ring_size, GFP_ATOMIC))) { lp->rx_skbuff = kmalloc(sizeof(struct sk_buff *) * lp->rx_ring_size,
GFP_ATOMIC);
if (!lp->rx_skbuff) {
if (pcnet32_debug & NETIF_MSG_DRV) if (pcnet32_debug & NETIF_MSG_DRV)
printk(KERN_ERR PFX "Memory allocation failed.\n"); printk("\n" KERN_ERR PFX "%s: Memory allocation failed.\n", name);
return -ENOMEM; return -ENOMEM;
} }
memset(lp->rx_skbuff, 0, sizeof(struct sk_buff *) * lp->rx_ring_size); memset(lp->rx_skbuff, 0, sizeof(struct sk_buff *) * lp->rx_ring_size);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment