Messages in this thread Patch in this message |  | | Date | Thu, 11 Jan 2001 12:21:39 -0200 | From | Arnaldo Carvalho de Melo <> | Subject | [PATCH] dgrs.c: kmalloc release on failure |
| |
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/
|  |