[PATCH] dgrs.c: kmalloc release on failure

From: Arnaldo Carvalho de Melo (acme@conectiva.com.br)
Date: Thu Jan 11 2001 - 09:21:39 EST


Hi,

        Please consider applying.

- Arnaldo

--- linux-2.4.0-ac6/drivers/net/hp100.c Tue Dec 19 11:25:41 2000
+++ linux-2.4.0-ac6.acme/drivers/net/hp100.c Thu Jan 11 11:52:34 2001
@@ -45,6 +45,8 @@
 ** along with this program; if not, write to the Free Software
 ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 **
+** 1.57b -> 1.57c - Arnaldo Carvalho de Melo <acme@conectiva.com.br>
+** - release resources on failure in init_module
 **
 ** 1.57 -> 1.57b - Jean II
 ** - fix spinlocks, SMP is now working !
@@ -3024,7 +3026,25 @@
 MODULE_PARM(hp100_name, "1-5c" __MODULE_STRING(IFNAMSIZ));
 
 /* List of devices */
-static struct net_device *hp100_devlist[5] = { NULL, NULL, NULL, NULL, NULL };
+static struct net_device *hp100_devlist[5];
+
+static void release_dev(int i)
+{
+ struct net_device *d = hp100_devlist[i];
+ struct hp100_private *p = (struct hp100_private *)d->priv;
+
+ unregister_netdev(d);
+ release_region(d->base_addr, HP100_REGION_SIZE);
+
+ if (p->mode == 1) /* busmaster */
+ kfree(p->page_vaddr);
+ if (p->mem_ptr_virt)
+ iounmap(p->mem_ptr_virt);
+ kfree(d->priv);
+ d->priv = NULL;
+ kfree(d);
+ hp100_devlist[i] = NULL;
+}
 
 /*
  * Note: if you have more than five 100vg cards in your pc, feel free to
@@ -3051,6 +3071,8 @@
     {
       /* Create device and set basics args */
       hp100_devlist[i] = kmalloc(sizeof(struct net_device), GFP_KERNEL);
+ if (!hp100_devlist[i])
+ goto fail;
       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 */
@@ -3073,6 +3095,13 @@
     } /* Loop over all devices */
 
   return cards > 0 ? 0 : -ENODEV;
+ fail:
+ while (cards && --i)
+ if (hp100_devlist[i]) {
+ release_dev(i);
+ --cards;
+ }
+ return -ENOMEM;
 }
 
 void cleanup_module( void )
@@ -3082,18 +3111,7 @@
   /* TODO: Check if all skb's are released/freed. */
   for(i = 0; i < 5; i++)
     if(hp100_devlist[i] != (struct net_device *) NULL)
- {
- unregister_netdev( hp100_devlist[i] );
- release_region( hp100_devlist[i]->base_addr, HP100_REGION_SIZE );
- if( ((struct hp100_private *)hp100_devlist[i]->priv)->mode==1 ) /* busmaster */
- kfree( ((struct hp100_private *)hp100_devlist[i]->priv)->page_vaddr );
- if ( ((struct hp100_private *)hp100_devlist[i]->priv) -> mem_ptr_virt )
- iounmap( ((struct hp100_private *)hp100_devlist[i]->priv) -> mem_ptr_virt );
- kfree( hp100_devlist[i]->priv );
- hp100_devlist[i]->priv = NULL;
- kfree(hp100_devlist[i]);
- hp100_devlist[i] = (struct net_device *) NULL;
- }
+ release_dev(i);
 }
 
 #endif /* MODULE */
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Mon Jan 15 2001 - 21:00:31 EST