Linux-kernel mailing list archive 2000-32,: [PATCH] checking kmalloc, init_etherdev and other fixes

# [PATCH] checking kmalloc, init_etherdev and other fixes

Arnaldo Carvalho de Melo (acme@conectiva.com.br)
Tue, 8 Aug 2000 01:07:37 -0300

- Messages sorted by: [ date ][ thread ][ subject ][ author ]
- Next message: Arnaldo Carvalho de Melo: "Re: [PATCH] checking kmalloc, init_etherdev and other fixes"
- Previous message: Arnaldo Carvalho de Melo: "[PATCH] part2 - checking kmalloc, init_etherdev and other fixes"
- Next in thread: David S. Miller: "Re: [PATCH] checking kmalloc, init_etherdev and other fixes"
- Maybe reply: David S. Miller: "Re: [PATCH] checking kmalloc, init_etherdev and other fixes"

Hi,

This message was sent to Linus, but the limit for the list is
40000 bytes, so I'm breaking it in two pieces so that interested
reviewers in this list can comment on the patch. This is the
first part.

This patch mostly includes checks for kmalloc and init_etherdev
in the net drivers, but also fixes some bugs on some drivers,
please take a look and consider aplying.

- Arnaldo

diff -uNr linux-2.4.0-test6-pre7/drivers/net/3c503.c linux-2.4.0-test6-pre7.acme/drivers/net/3c503.c
--- linux-2.4.0-test6-pre7/drivers/net/3c503.c Mon Jun 19 17:30:56 2000
+++ linux-2.4.0-test6-pre7.acme/drivers/net/3c503.c Mon Aug 7 23:54:48 2000
@@ -190,6 +190,9 @@
if (dev == NULL) {
printk("3c503.c: Passed a NULL device.\n");
dev = init_etherdev(0, 0);
+
+ if (!dev)
+ return -ENOMEM;
}
if (ei_debug && version_printed++ == 0)
diff -uNr linux-2.4.0-test6-pre7/drivers/net/3c507.c linux-2.4.0-test6-pre7.acme/drivers/net/3c507.c
--- linux-2.4.0-test6-pre7/drivers/net/3c507.c Mon Jun 19 17:30:56 2000
+++ linux-2.4.0-test6-pre7.acme/drivers/net/3c507.c Mon Aug 7 23:56:50 2000
@@ -355,7 +355,8 @@
/* Allocate a new 'dev' if needed. */
if (dev == NULL)
- dev = init_etherdev(0, sizeof(struct net_local));
+ if ((dev = init_etherdev(0, sizeof(struct net_local))))
+ return -ENOMEM;
if (net_debug && version_printed++ == 0)
printk(version);
diff -uNr linux-2.4.0-test6-pre7/drivers/net/3c515.c linux-2.4.0-test6-pre7.acme/drivers/net/3c515.c
--- linux-2.4.0-test6-pre7/drivers/net/3c515.c Tue Jul 11 15:12:23 2000
+++ linux-2.4.0-test6-pre7.acme/drivers/net/3c515.c Mon Aug 7 22:17:51 2000
@@ -14,6 +14,12 @@
2/2/00- Added support for kernel-level ISAPnP
by Stephen Frost <sfrost@snowman.net> and Alessandro Zummo
Cleaned up for 2.3.x/softnet by Jeff Garzik and Alan Cox.
+
+ 07/30/2000 - Arnaldo Carvalho de Melo <acme@conectiva.com.br>
+ - check if kmalloc(dev->priv) in corkscrew_found_device was
+ successful, the same for kmalloc(net_device).
+ Avoid reallocating dev->priv when compiled as a module.
+ Check init_etherdev, it can return NULL
*/
static char *version = "3c515.c:v0.99-sn 2000/02/12 becker@cesdis.gsfc.nasa.gov and others\n";
@@ -561,6 +567,10 @@
sizeof(struct corkscrew_private) + 15; /* Pad for alignment */
dev = (struct net_device *) kmalloc(dev_size, GFP_KERNEL);
+
+ if (!dev)
+ return NULL;
+
memset(dev, 0, dev_size);
/* Align the Rx and Tx ring entries. */
dev->priv =
@@ -587,15 +597,23 @@
vp->next_module = root_corkscrew_dev;
root_corkscrew_dev = dev;
if (register_netdev(dev) != 0)
- return 0;
+ return NULL;
#else /* not a MODULE */
- if (dev) {
+ if (dev && !dev->priv) {
/* Caution: quad-word alignment required for rings! */
dev->priv =
kmalloc(sizeof(struct corkscrew_private), GFP_KERNEL);
+
+ if (!dev->priv)
+ return NULL;
+
memset(dev->priv, 0, sizeof(struct corkscrew_private));
}
dev = init_etherdev(dev, sizeof(struct corkscrew_private));
+
+ if (!dev)
+ return NULL;
+
dev->base_addr = ioaddr;
dev->irq = irq;
dev->dma =
diff -uNr linux-2.4.0-test6-pre7/drivers/net/ac3200.c linux-2.4.0-test6-pre7.acme/drivers/net/ac3200.c
--- linux-2.4.0-test6-pre7/drivers/net/ac3200.c Mon Jun 19 17:30:57 2000
+++ linux-2.4.0-test6-pre7.acme/drivers/net/ac3200.c Mon Aug 7 23:57:28 2000
@@ -139,6 +139,9 @@
if (dev == NULL) {
printk("ac3200.c: Passed a NULL device.\n");
dev = init_etherdev(0, 0);
+
+ if (!dev)
+ return -ENOMEM;
}
printk("AC3200 in EISA slot %d, node", ioaddr/0x1000);
diff -uNr linux-2.4.0-test6-pre7/drivers/net/acenic.c linux-2.4.0-test6-pre7.acme/drivers/net/acenic.c
--- linux-2.4.0-test6-pre7/drivers/net/acenic.c Mon Aug 7 21:56:33 2000
+++ linux-2.4.0-test6-pre7.acme/drivers/net/acenic.c Mon Aug 7 22:17:51 2000
@@ -132,6 +132,10 @@
void *virt_ptr;
virt_ptr = kmalloc(size, GFP_KERNEL);
+
+ if (!virt_ptr)
+ return NULL;
+
*dma_handle = virt_to_bus(virt_ptr);
return virt_ptr;
}
diff -uNr linux-2.4.0-test6-pre7/drivers/net/aironet4500_card.c linux-2.4.0-test6-pre7.acme/drivers/net/aironet4500_card.c
--- linux-2.4.0-test6-pre7/drivers/net/aironet4500_card.c Fri Jul 28 06:34:44 2000
+++ linux-2.4.0-test6-pre7.acme/drivers/net/aironet4500_card.c Mon Aug 7 22:17:51 2000
@@ -10,10 +10,18 @@
* Revision 0.2, Feb 27, 2000
* Jeff Garzik - softnet, cleanups
*
+ * Revision 0.3, Aug 03, 2000
+ * Arnaldo Carvalho de Melo <acme@conectiva.com.br>
+ * - only zeroes dev->priv after kmalloc if it was succesfully
+ * allocated
+ * - check if request_irq, request_region and others were successful
+ * - other cleanups
+ *
+ *
*/
#ifdef MODULE
static const char *awc_version =
-"aironet4500_cards.c v0.2 Feb 27, 2000 Elmer Joandi, elmer@ylenurme.ee.\n";
+"aironet4500_cards.c v0.3 Jul 30, 2000 Elmer Joandi, elmer@ylenurme.ee.\n";
#endif
#include <linux/version.h>
@@ -166,16 +174,21 @@
int i;
- if (!dev) {
- dev = init_etherdev(dev, 0 );
- }
+ if (!dev)
+ if ((dev = init_etherdev(0, 0)) == NULL) {
+ printk(KERN_CRIT "aironet4x00: could't allocate device struct\n");
+ return -ENOMEM;
+ }
+
dev->priv = kmalloc(sizeof(struct awc_private),GFP_KERNEL );
- memset(dev->priv,0,sizeof(struct awc_private));
+
if (!dev->priv) {
- printk(KERN_CRIT "aironet4x00: could not allocate device private, some unstability may follow\n");
- return -1;
+ printk(KERN_CRIT "aironet4x00: couldn't allocate device private\n");
+ return -ENOMEM;
};
+ memset(dev->priv,0,sizeof(struct awc_private));
+
// ether_setup(dev);
// dev->tx_queue_len = tx_queue_len;
@@ -193,8 +206,12 @@
dev->tx_timeout = &awc_tx_timeout;
dev->watchdog_timeo = AWC_TX_TIMEOUT;
-
- request_irq(dev->irq,awc_interrupt, SA_SHIRQ | SA_INTERRUPT ,"Aironet 4X00",dev);
+ if (request_irq(dev->irq,awc_interrupt, SA_SHIRQ | SA_INTERRUPT ,"Aironet 4X00",dev)) {
+ printk(KERN_CRIT "aironet4x00: could not allocate device IRQ, some unstability may follow\n");
+ kfree(dev->priv);
+ dev->priv = NULL;
+ return -EAGAIN;
+ }
awc_private_init( dev);
awc_init(dev);
@@ -341,6 +358,23 @@
printk("No logical device found on Aironet board \n");
return -ENODEV;
}
+
+ if (!dev)
+ if ((dev = init_etherdev(0, 0)) == NULL) {
+ printk(KERN_CRIT "aironet4x00: couldn't allocate device struct\n");
+ return -ENOMEM;
+ }
+
+ dev->priv = kmalloc(sizeof(struct awc_private),GFP_KERNEL );
+
+ if (!dev->priv) {
+ printk(KERN_CRIT "aironet4x00: could not allocate device private\n");
+ return -ENOMEM;
+ };
+
+ memset(dev->priv,0,sizeof(struct awc_private));
+ ((struct awc_private *)dev->priv)->bus = logdev;
+
if (isapnp_cfg_begin(logdev->PNP_BUS->PNP_BUS_NUMBER, logdev->PNP_DEV_NUMBER) < 0) {
printk("cfg begin failed for csn %x devnum %x \n",
logdev->PNP_BUS->PNP_BUS_NUMBER, logdev->PNP_DEV_NUMBER);
@@ -351,18 +385,12 @@
isa_irq_line = logdev->irq;
isa_ioaddr = logdev->resource[0].start;
- request_region(isa_ioaddr, AIRONET4X00_IO_SIZE, "aironet4x00 ioaddr");
- if (!dev) {
- dev = init_etherdev(dev, 0 );
+ if (!request_region(isa_ioaddr, AIRONET4X00_IO_SIZE, "aironet4x00 ioaddr")) {
+ kfree(dev->priv);
+ dev->priv = NULL;
+ return -EBUSY;
}
- dev->priv = kmalloc(sizeof(struct awc_private),GFP_KERNEL );
- memset(dev->priv,0,sizeof(struct awc_private));
- if (!dev->priv) {
- printk(KERN_CRIT "aironet4x00: could not allocate device private, some unstability may follow\n");
- return -1;
- };
- ((struct awc_private *)dev->priv)->bus = logdev;
// ether_setup(dev);
@@ -381,9 +409,15 @@
dev->tx_timeout = &awc_tx_timeout;
dev->watchdog_timeo = AWC_TX_TIMEOUT;
+ if (request_irq(dev->irq,awc_interrupt , SA_SHIRQ | SA_INTERRUPT ,"Aironet 4X00",dev)) {
+ printk(KERN_CRIT "aironet4x00: could not allocate device IRQ, some unstability may follow\n");
+ kfree(dev->priv);
+ dev->priv = NULL;
+ release_region(isa_ioaddr, AIRONET4X00_IO_SIZE);
+ return -EAGAIN;
+ }
+
netif_start_queue (dev);
-
- request_irq(dev->irq,awc_interrupt , SA_SHIRQ | SA_INTERRUPT ,"Aironet 4X00",dev);
awc_private_init( dev);
@@ -513,17 +547,24 @@
isa_ioaddr = io[card];
isa_irq_line = irq[card];
- request_region(isa_ioaddr, AIRONET4X00_IO_SIZE, "aironet4x00 ioaddr");
+ if (!request_region(isa_ioaddr, AIRONET4X00_IO_SIZE, "aironet4x00 ioaddr"))
+ return -EBUSY;
- if (!dev) {
- dev = init_etherdev(dev, 0 );
- }
+ if (!dev)
+ if ((dev = init_etherdev(0, 0)) == NULL) {
+ printk(KERN_CRIT "aironet4x00: couldn't allocate device struct, some unstability may follow\n");
+ release_region(isa_ioaddr, AIRONET4X00_IO_SIZE);
+ return -ENOMEM;
+ }
+
+
dev->priv = kmalloc(sizeof(struct awc_private),GFP_KERNEL );
- memset(dev->priv,0,sizeof(struct awc_private));
if (!dev->priv) {
printk(KERN_CRIT "aironet4x00: could not allocate device private, some unstability may follow\n");
+ release_region(isa_ioaddr, AIRONET4X00_IO_SIZE);
return -1;
};
+ memset(dev->priv,0,sizeof(struct awc_private));
// ether_setup(dev);
@@ -542,13 +583,24 @@
dev->tx_timeout = &awc_tx_timeout;
dev->watchdog_timeo = AWC_TX_TIMEOUT;
- request_irq(dev->irq,awc_interrupt ,SA_INTERRUPT ,"Aironet 4X00",dev);
+ if (request_irq(dev->irq,awc_interrupt ,SA_INTERRUPT ,"Aironet 4X00",dev)) {
+ printk(KERN_CRIT "aironet4x00: could not allocate device IRQ, some unstability may follow\n");
+ release_region(isa_ioaddr, AIRONET4X00_IO_SIZE);
+ kfree(dev->priv);
+ dev->priv = NULL;
+ return -EAGAIN;
+ }
awc_private_init( dev);
if ( awc_init(dev) ){
printk("card not found at irq %x mem %x\n",irq[card],io[card]);
- if (card==0)
- return -1;
+ if (card==0) {
+ free_irq(dev->irq, dev);
+ release_region(isa_ioaddr, AIRONET4X00_IO_SIZE);
+ kfree(dev->priv);
+ dev->priv = NULL;
+ return -ENODEV;
+ }
break;
}
@@ -798,8 +850,11 @@
struct net_device * dev;
int i;
-
dev = init_etherdev(0, sizeof(struct awc_private) );
+
+ if (!dev)
+ return -1;
+
// dev->tx_queue_len = tx_queue_len;
ether_setup(dev);
diff -uNr linux-2.4.0-test6-pre7/drivers/net/apne.c linux-2.4.0-test6-pre7.acme/drivers/net/apne.c
--- linux-2.4.0-test6-pre7/drivers/net/apne.c Mon Jun 19 17:30:57 2000
+++ linux-2.4.0-test6-pre7.acme/drivers/net/apne.c Mon Aug 7 23:58:48 2000
@@ -181,7 +181,10 @@
/* We should have a "dev" from Space.c or the static module table. */
if (dev == NULL) {
printk(KERN_ERR "apne.c: Passed a NULL device.\n");
- dev = init_etherdev(0, 0);
+ if ((dev = init_etherdev(0, 0)) == NULL) {
+ printk(KERN_ERR "apne.c: out of memory.\n");
+ return -ENOMEM;
+ }
}
if (ei_debug && version_printed++ == 0)
diff -uNr linux-2.4.0-test6-pre7/drivers/net/ariadne2.c linux-2.4.0-test6-pre7.acme/drivers/net/ariadne2.c
--- linux-2.4.0-test6-pre7/drivers/net/ariadne2.c Mon Jun 19 17:30:57 2000
+++ linux-2.4.0-test6-pre7.acme/drivers/net/ariadne2.c Mon Aug 7 23:59:10 2000
@@ -116,7 +116,10 @@
/* We should have a "dev" from Space.c or the static module table. */
if (dev == NULL) {
printk(KERN_ERR "ariadne2.c: Passed a NULL device.\n");
- dev = init_etherdev(0, 0);
+ if ((dev = init_etherdev(0, 0)) == NULL) {
+ printk(KERN_ERR "ariadne2.c: out of memory.\n");
+ return -ENOMEM;
+ }
}
/* Reset card. Who knows what dain-bramaged state it was left in. */
diff -uNr linux-2.4.0-test6-pre7/drivers/net/at1700.c linux-2.4.0-test6-pre7.acme/drivers/net/at1700.c
--- linux-2.4.0-test6-pre7/drivers/net/at1700.c Mon Aug 7 21:56:33 2000
+++ linux-2.4.0-test6-pre7.acme/drivers/net/at1700.c Mon Aug 7 23:59:39 2000
@@ -326,7 +326,8 @@
/* Allocate a new 'dev' if needed. */
if (dev == NULL)
- dev = init_etherdev(0, sizeof(struct net_local));
+ if ((dev = init_etherdev(0, sizeof(struct net_local))) == NULL)
+ return -ENOMEM;
if (is_at1700)
irq = at1700_irqmap[(read_eeprom(ioaddr, 12)&0x04)
diff -uNr linux-2.4.0-test6-pre7/drivers/net/atari_bionet.c linux-2.4.0-test6-pre7.acme/drivers/net/atari_bionet.c
--- linux-2.4.0-test6-pre7/drivers/net/atari_bionet.c Fri Jul 28 06:34:44 2000
+++ linux-2.4.0-test6-pre7.acme/drivers/net/atari_bionet.c Tue Aug 8 00:03:26 2000
@@ -374,7 +374,9 @@
}
if (dev->priv == NULL)
- dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL);
+ if ((dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL)) == NULL)
+ return -ENOMEM;
+
memset(dev->priv, 0, sizeof(struct net_local));
dev->open = bionet_open;
diff -uNr linux-2.4.0-test6-pre7/drivers/net/atari_pamsnet.c linux-2.4.0-test6-pre7.acme/drivers/net/atari_pamsnet.c
--- linux-2.4.0-test6-pre7/drivers/net/atari_pamsnet.c Fri Jul 28 06:34:44 2000
+++ linux-2.4.0-test6-pre7.acme/drivers/net/atari_pamsnet.c Mon Aug 7 22:17:51 2000
@@ -12,6 +12,10 @@
*
* Little adaptions for integration into pl7 by Roman Hodek
*
+ * Arnaldo Carvalho de Melo <acme@conectiva.com.br> - 07/30/2000
+ * - check if kmalloc(dev->priv) was successful in bionet_probe
+ *
+ *
What is it ?
------------
This driver controls the PAMsNet LAN-Adapter which connects
@@ -630,7 +634,9 @@
/* Initialize the device structure. */
if (dev->priv == NULL)
- dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL);
+ if ((dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL)) == NULL)
+ return -ENOMEM;
+
memset(dev->priv, 0, sizeof(struct net_local));
dev->open = pamsnet_open;
diff -uNr linux-2.4.0-test6-pre7/drivers/net/atarilance.c linux-2.4.0-test6-pre7.acme/drivers/net/atarilance.c
--- linux-2.4.0-test6-pre7/drivers/net/atarilance.c Wed Aug 18 15:36:41 1999
+++ linux-2.4.0-test6-pre7.acme/drivers/net/atarilance.c Tue Aug 8 00:03:05 2000
@@ -511,7 +511,9 @@
probe_ok:
init_etherdev( dev, sizeof(struct lance_private) );
if (!dev->priv)
- dev->priv = kmalloc( sizeof(struct lance_private), GFP_KERNEL );
+ if ((dev->priv = kmalloc( sizeof(struct lance_private), GFP_KERNEL)) == NULL)
+ return 0;
+
lp = (struct lance_private *)dev->priv;
MEM = (struct lance_memory *)memaddr;
IO = lp->iobase = (struct lance_ioreg *)ioaddr;
diff -uNr linux-2.4.0-test6-pre7/drivers/net/bagetlance.c linux-2.4.0-test6-pre7.acme/drivers/net/bagetlance.c
--- linux-2.4.0-test6-pre7/drivers/net/bagetlance.c Sat May 13 12:29:40 2000
+++ linux-2.4.0-test6-pre7.acme/drivers/net/bagetlance.c Tue Aug 8 00:04:41 2000
@@ -584,7 +584,9 @@
probe_ok:
init_etherdev( dev, sizeof(struct lance_private) );
if (!dev->priv)
- dev->priv = kmalloc( sizeof(struct lance_private), GFP_KERNEL );
+ if ((dev->priv = kmalloc( sizeof(struct lance_private), GFP_KERNEL)) == NULL)
+ return 0;
+
lp = (struct lance_private *)dev->priv;
MEM = (struct lance_memory *)memaddr;
IO = lp->iobase = (struct lance_ioreg *)ioaddr;
diff -uNr linux-2.4.0-test6-pre7/drivers/net/bmac.c linux-2.4.0-test6-pre7.acme/drivers/net/bmac.c
--- linux-2.4.0-test6-pre7/drivers/net/bmac.c Sun Feb 13 16:47:01 2000
+++ linux-2.4.0-test6-pre7.acme/drivers/net/bmac.c Tue Aug 8 00:05:25 2000
@@ -1292,6 +1292,12 @@
dev = init_etherdev(NULL, PRIV_BYTES);
+ if (!dev) {
+ printk(KERN_ERR "init_etherdev failed, out of memory for BMAC %s\n",
+ bmac->full_name);
+ return;
+ }
+
dev->base_addr = (unsigned long)
ioremap(bmac->addrs[0].address, bmac->addrs[0].size);
dev->irq = bmac->intrs[0].line;
diff -uNr linux-2.4.0-test6-pre7/drivers/net/declance.c linux-2.4.0-test6-pre7.acme/drivers/net/declance.c
--- linux-2.4.0-test6-pre7/drivers/net/declance.c Sat May 13 12:29:40 2000
+++ linux-2.4.0-test6-pre7.acme/drivers/net/declance.c Tue Aug 8 00:06:05 2000
@@ -1018,6 +1018,9 @@
if (dev == NULL) {
dev = init_etherdev(0, sizeof(struct lance_private) + 8);
+
+ if (!dev)
+ return -ENOMEM;
} else {
dev->priv = kmalloc(sizeof(struct lance_private) + 8,
GFP_KERNEL);
diff -uNr linux-2.4.0-test6-pre7/drivers/net/dgrs.c linux-2.4.0-test6-pre7.acme/drivers/net/dgrs.c
--- linux-2.4.0-test6-pre7/drivers/net/dgrs.c Mon Jun 19 17:30:58 2000
+++ linux-2.4.0-test6-pre7.acme/drivers/net/dgrs.c Mon Aug 7 22:17:51 2000
@@ -71,6 +71,12 @@
* into the kernel.
* - Better handling of multicast addresses.
*
+ * Fixes:
+ * Arnaldo Carvalho de Melo <acme@conectiva.com.br> - 08/03/2000
+ * - fix dgrs_found_device wrt checking kmalloc return and
+ * rollbacking the partial steps of the whole process when
+ * one of the devices can't be allocated.
+ *
*/
static char *version = "$Id: dgrs.c,v 1.13 2000/06/06 04:07:00 rick Exp $";
@@ -1245,13 +1251,17 @@
)
{
DGRS_PRIV *priv;
- struct net_device *dev;
+ struct net_device *dev, *aux;
/* Allocate and fill new device structure. */
int dev_size = sizeof(struct net_device) + sizeof(DGRS_PRIV);
- int i;
+ int i, ret;
dev = (struct net_device *) kmalloc(dev_size, GFP_KERNEL);
+
+ if (!dev)
+ return -ENOMEM;
+
memset(dev, 0, dev_size);
dev->priv = ((void *)dev) + sizeof(struct net_device);
priv = (DGRS_PRIV *)dev->priv;
@@ -1269,11 +1279,12 @@
dev->init = dgrs_probe1;
ether_setup(dev);
- priv->next_dev = dgrs_root_dev;
- dgrs_root_dev = dev;
if (register_netdev(dev) != 0)
return -EIO;
+ priv->next_dev = dgrs_root_dev;
+ dgrs_root_dev = dev;
+
if ( !dgrs_nicmode )
return (0); /* Switch mode, we are done */
@@ -1290,6 +1301,12 @@
/* Allocate new dev and priv structures */
devN = (struct net_device *) kmalloc(dev_size, GFP_KERNEL);
/* Make it an exact copy of dev[0]... */
+
+ if (!devN) {
+ ret = -ENOMEM;
+ goto fail;
+ }
+
memcpy(devN, dev, dev_size);
devN->priv = ((void *)devN) + sizeof(struct net_device);
privN = (DGRS_PRIV *)devN->priv;
@@ -1300,16 +1317,33 @@
devN->irq = 0;
/* ... and base MAC address off address of 1st port */
devN->dev_addr[5] += i;
- privN->chan = i+1;
- priv->devtbl[i] = devN;
devN->init = dgrs_initclone;
ether_setup(devN);
+
+ if (register_netdev(devN) != 0) {
+ kfree(devN);
+ ret = -EIO;
+ goto fail;
+ }
+
+ privN->chan = i+1;
+ priv->devtbl[i] = devN;
privN->next_dev = dgrs_root_dev;
dgrs_root_dev = devN;
- if (register_netdev(devN) != 0)
- return -EIO;
}
return (0);
+fail:
+ aux = priv->next_dev;
+
+ while (dgrs_root_dev != aux) {
+ struct net_device *d = dgrs_root_dev;
+
+ dgrs_root_dev = ((DGRS_PRIV *)dgrs_root_dev->priv)->next_dev;
+ unregister_netdev(d);
+ kfree(d);
+ }
+
+ return ret;
}
/*
diff -uNr linux-2.4.0-test6-pre7/drivers/net/e2100.c linux-2.4.0-test6-pre7.acme/drivers/net/e2100.c
--- linux-2.4.0-test6-pre7/drivers/net/e2100.c Mon Jun 19 17:30:58 2000
+++ linux-2.4.0-test6-pre7.acme/drivers/net/e2100.c Tue Aug 8 00:06:23 2000
@@ -168,8 +168,12 @@
/* We should have a "dev" from Space.c or the static module table. */
if (dev == NULL) {
- printk("e2100.c: Passed a NULL device.\n");
- dev = init_etherdev(0, 0);
+ printk(KERN_ERR "e2100.c: Passed a NULL device.\n");
+
+ if ((dev = init_etherdev(0, 0)) == NULL) {
+ printk(KERN_ERR "e2100.c: Passed a NULL device.\n");
+ return -ENOMEM;
+ }
}
printk("%s: E21** at %#3x,", dev->name, ioaddr);
@@ -178,7 +182,7 @@
/* Allocate dev->priv and fill in 8390 specific dev fields. */
if (ethdev_init(dev)) {
- printk (" unable to get memory for dev->priv.\n");
+ printk (KERN_ERR " unable to get memory for dev->priv.\n");
return -ENOMEM;
}
diff -uNr linux-2.4.0-test6-pre7/drivers/net/es3210.c linux-2.4.0-test6-pre7.acme/drivers/net/es3210.c
--- linux-2.4.0-test6-pre7/drivers/net/es3210.c Mon Jun 19 17:30:58 2000
+++ linux-2.4.0-test6-pre7.acme/drivers/net/es3210.c Tue Aug 8 00:06:47 2000
@@ -183,8 +183,12 @@
/* We should have a "dev" from Space.c or the static module table. */
if (dev == NULL) {
- printk("es3210.c: Passed a NULL device.\n");
- dev = init_etherdev(0, 0);
+ printk(KERN_ERR "es3210.c: Passed a NULL device.\n");
+
+ if ((dev = init_etherdev(0, 0)) == NULL) {
+ printk(KERN_ERR "es3210.c: out of memory.\n");
+ return -ENOMEM;
+ }
}
printk("es3210.c: ES3210 rev. %ld at %#x, node", eisa_id>>24, ioaddr);
diff -uNr linux-2.4.0-test6-pre7/drivers/net/eth16i.c linux-2.4.0-test6-pre7.acme/drivers/net/eth16i.c
--- linux-2.4.0-test6-pre7/drivers/net/eth16i.c Mon Jun 19 17:30:58 2000
+++ linux-2.4.0-test6-pre7.acme/drivers/net/eth16i.c Mon Aug 7 22:17:51 2000
@@ -140,6 +140,10 @@
- IRQ configuration with module parameter. I will do
this when i will get enough info about setting
irq without configuration utility.
+
+ Changes:
+ Arnaldo Carvalho de Melo <acme@conectiva.com.br> - 08/06/2000
+ - check init_etherdev return in eth16i_probe1
*/
static char *version =
@@ -495,6 +499,10 @@
if(eth16i_check_signature(ioaddr) != 0)
return -ENODEV;
+ if(dev == NULL)
+ if ((dev = init_etherdev(0, 0)) == NULL)
+ return -ENOMEM;
+
/*
Now it seems that we have found a ethernet chip in this particular
ioaddr. The MB86985 chip has this feature, that when you read a
@@ -508,9 +516,6 @@
outb(0x00, ioaddr + RESET); /* Reset some parts of chip */
BITSET(ioaddr + CONFIG_REG_0, BIT(7)); /* Disable the data link */
-
- if(dev == NULL)
- dev = init_etherdev(0, 0);
if( (eth16i_debug & version_printed++) == 0)
printk(KERN_INFO "%s", version);
diff -uNr linux-2.4.0-test6-pre7/drivers/net/fmv18x.c linux-2.4.0-test6-pre7.acme/drivers/net/fmv18x.c
--- linux-2.4.0-test6-pre7/drivers/net/fmv18x.c Mon Jun 19 17:30:58 2000
+++ linux-2.4.0-test6-pre7.acme/drivers/net/fmv18x.c Mon Aug 7 22:17:51 2000
@@ -29,6 +29,14 @@
at1700.c
The Fujitsu MB86965 datasheet.
The Fujitsu FMV-181/182 user's guide
+
+ Changes:
+ Arnaldo Carvalho de Melo <acme@conectiva.com.br> - 08/06/2000
+ - check init_etherdev return in fmv18x_probe1
+ - only allocates dev->priv if needed, i.e. if init_etherdev
+ is not used, cause in this case it will get allocated
+ - check request_region, and release the region if later on the
+ fmv18x_probe1 function fails.
*/
static const char *version =
@@ -190,21 +198,31 @@
irq = irqmap[(inb(ioaddr + FJ_CONFIG0)>>6) & 0x03];
}
+ /* Allocate a new 'dev' if needed. */
+ if (dev == NULL) {
+ if ((dev = init_etherdev(0, sizeof(struct net_local))) == NULL)
+ return -ENOMEM;
+ } else {
+ /* Initialize the device structure. */
+ dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL);
+ if (dev->priv == NULL)
+ return -ENOMEM;
+ memset(dev->priv, 0, sizeof(struct net_local));
+ }
+
+ /* Grab the region so that we can find another board if the IRQ request
+ fails. */
+ if (!request_region(ioaddr, FMV18X_IO_EXTENT, "fmv18x"))
+ return -EBUSY;
+
/* Snarf the interrupt vector now. */
if (request_irq(irq, &net_interrupt, 0, "fmv18x", dev)) {
printk ("FMV-18x found at %#3x, but it's unusable due to a conflict on"
"IRQ %d.\n", ioaddr, irq);
+ release_region(ioaddr, FMV18X_IO_EXTENT);
return -EAGAIN;
}
- /* Allocate a new 'dev' if needed. */
- if (dev == NULL)
- dev = init_etherdev(0, sizeof(struct net_local));
-
- /* Grab the region so that we can find another board if the IRQ request
- fails. */
- request_region(ioaddr, FMV18X_IO_EXTENT, "fmv18x");
-
printk("%s: FMV-18x found at %#3x, IRQ %d, address ", dev->name,
ioaddr, irq);
@@ -262,12 +280,6 @@
if (net_debug)
printk(version);
-
- /* Initialize the device structure. */
- dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL);
- if (dev->priv == NULL)
- return -ENOMEM;
- memset(dev->priv, 0, sizeof(struct net_local));
dev->open = net_open;
dev->stop = net_close;
diff -uNr linux-2.4.0-test6-pre7/drivers/net/gmac.c linux-2.4.0-test6-pre7.acme/drivers/net/gmac.c
--- linux-2.4.0-test6-pre7/drivers/net/gmac.c Mon Aug 7 21:56:33 2000
+++ linux-2.4.0-test6-pre7.acme/drivers/net/gmac.c Mon Aug 7 22:17:51 2000
@@ -5,6 +5,10 @@
* Copyright (C) 2000 Paul Mackerras & Ben. Herrenschmidt
*
* portions based on sunhme.c by David S. Miller
+ *
+ * Changes:
+ * Arnaldo Carvalho de Melo <acme@conectiva.com.br> - 08/06/2000
+ * - check init_etherdev return in gmac_probe1
*
*/
@@ -1178,7 +1182,13 @@
}
dev = init_etherdev(0, sizeof(struct gmac));
- memset(dev->priv, 0, sizeof(struct gmac));
+
+ if (!dev) {
+ printk(KERN_ERR "GMAC: init_etherdev failed, out of memory\n");
+ free_page(tx_descpage);
+ free_page(rx_descpage);
+ return;
+ }
gm = (struct gmac *) dev->priv;
dev->base_addr = gmac->addrs[0].address;
diff -uNr linux-2.4.0-test6-pre7/drivers/net/hp-plus.c linux-2.4.0-test6-pre7.acme/drivers/net/hp-plus.c
--- linux-2.4.0-test6-pre7/drivers/net/hp-plus.c Mon Jun 19 17:30:58 2000
+++ linux-2.4.0-test6-pre7.acme/drivers/net/hp-plus.c Tue Aug 8 00:07:39 2000
@@ -161,8 +161,11 @@
/* We should have a "dev" from Space.c or the static module table. */
if (dev == NULL) {
- printk("hp-plus.c: Passed a NULL device.\n");
- dev = init_etherdev(0, 0);
+ printk(KERN_ERR "hp-plus.c: Passed a NULL device.\n");
+ if ((dev = init_etherdev(0, 0)) == NULL) {
+ printk(KERN_ERR "hp-plus.c: init_etherdev failed, out of memory.\n");
+ return -ENOMEM;
+ }
}
if (ei_debug && version_printed++ == 0)
diff -uNr linux-2.4.0-test6-pre7/drivers/net/hp.c linux-2.4.0-test6-pre7.acme/drivers/net/hp.c
--- linux-2.4.0-test6-pre7/drivers/net/hp.c Mon Jun 19 17:30:58 2000
+++ linux-2.4.0-test6-pre7.acme/drivers/net/hp.c Tue Aug 8 00:07:59 2000
@@ -134,7 +134,10 @@
/* We should have a "dev" from Space.c or the static module table. */
if (dev == NULL) {
printk("hp.c: Passed a NULL device.\n");
- dev = init_etherdev(0, 0);
+ if ((dev = init_etherdev(0, 0)) == NULL) {
+ printk("hp.c: init_etherdev failed, out of memory.\n");
+ return -ENOMEM;
+ }
}
if (ei_debug && version_printed++ == 0)
diff -uNr linux-2.4.0-test6-pre7/drivers/net/hp100.c linux-2.4.0-test6-pre7.acme/drivers/net/hp100.c
--- linux-2.4.0-test6-pre7/drivers/net/hp100.c Fri Jul 28 06:34:44 2000
+++ linux-2.4.0-test6-pre7.acme/drivers/net/hp100.c Tue Aug 8 00:08:09 2000
@@ -3026,6 +3026,10 @@
{
/* Create device and set basics args */
hp100_devlist[i] = kmalloc(sizeof(struct net_device), GFP_KERNEL);
+
+ if (!hp100_devlist[i])
+ return -ENOMEM;
+
memset(hp100_devlist[i], 0x00, sizeof(struct net_device));
#if LINUX_VERSION_CODE >= 0x020362 /* 2.3.99-pre7 */
memcpy(hp100_devlist[i]->name, hp100_name[i], IFNAMSIZ); /* Copy name */

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/

- Next message: Arnaldo Carvalho de Melo: "Re: [PATCH] checking kmalloc, init_etherdev and other fixes"
- Previous message: Arnaldo Carvalho de Melo: "[PATCH] part2 - checking kmalloc, init_etherdev and other fixes"
- Next in thread: David S. Miller: "Re: [PATCH] checking kmalloc, init_etherdev and other fixes"
- Maybe reply: David S. Miller: "Re: [PATCH] checking kmalloc, init_etherdev and other fixes"