From: Christoph Hellwig <hch@infradead.org>

There's tons of leaks in the hplcance probing code, and it doesn't release
the memory region on removal either.

Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 25-akpm/drivers/net/hplance.c |   33 +++++++++++++++++++++++----------
 1 files changed, 23 insertions(+), 10 deletions(-)

diff -puN drivers/net/hplance.c~hp300-lance-leak-fixes drivers/net/hplance.c
--- 25/drivers/net/hplance.c~hp300-lance-leak-fixes	2004-11-16 23:10:45.029828784 -0800
+++ 25-akpm/drivers/net/hplance.c	2004-11-16 23:10:45.032828328 -0800
@@ -71,30 +71,42 @@ static struct dio_driver hplance_driver 
 	.remove    = __devexit_p(hplance_remove_one),
 };
 
+/* XXX(hch): should probably move to a better place */
+#define dio_resource_start(d) \
+	((d)->resource.start)
+#define dio_resource_len(d) \
+	((d)->resource.end - (d)->resource.start)
+
 /* Find all the HP Lance boards and initialise them... */
 static int __devinit hplance_init_one(struct dio_dev *d,
 				const struct dio_device_id *ent)
 {
 	struct net_device *dev;
-	int err;
+	int err = -ENOMEM;
 
 	dev = alloc_etherdev(sizeof(struct hplance_private));
 	if (!dev)
-		return -ENOMEM;
+		goto out;
 
-	if (!request_mem_region(d->resource.start, d->resource.end-d->resource.start, d->name))
-		return -EBUSY;
+	err = -EBUSY;
+	if (!request_mem_region(dio_resource_start(d),
+				dio_resource_len(d), d->name))
+		goto out_free_netdev;
 
-	SET_MODULE_OWNER(dev);
-        
 	hplance_init(dev, d);
 	err = register_netdev(dev);
-	if (err) {
-		free_netdev(dev);
-		return err;
-	}
+	if (err)
+		goto out_free_netdev;
+
 	dio_set_drvdata(d, dev);
 	return 0;
+
+ out_release_mem_region:
+	release_mem_region(dio_resource_start(d), dio_resource_len(d));
+ out_free_netdev:
+	free_netdev(dev);
+ out:
+	return err;
 }
 
 static void __devexit hplance_remove_one(struct dio_dev *d)
@@ -102,6 +114,7 @@ static void __devexit hplance_remove_one
 	struct net_device *dev = dio_get_drvdata(d);
 
 	unregister_netdev(dev);
+	release_mem_region(dio_resource_start(d), dio_resource_len(d));
 	free_netdev(dev);
 }
 
_