# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
#	           ChangeSet	1.656   -> 1.657  
#	drivers/usb/net/kaweth.c	1.26    -> 1.27   
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 02/09/12	oliver@neukum.name	1.657
# [PATCH] fixes for races in kaweth probe
# 
# using init_etherdev(0, 0) in probe is a race. The struct net_device must be
# allocate and filled before init_etherdev is called, or there's a race which
# creates a network interface that isn't usable.
# The patch for kaweth for 2.5 fixes it.
# --------------------------------------------
#
diff -Nru a/drivers/usb/net/kaweth.c b/drivers/usb/net/kaweth.c
--- a/drivers/usb/net/kaweth.c	Thu Sep 12 10:25:38 2002
+++ b/drivers/usb/net/kaweth.c	Thu Sep 12 10:25:38 2002
@@ -854,6 +854,7 @@
 	)
 {
 	struct kaweth_device *kaweth;
+	struct net_device *netdev;
 	const eth_addr_t bcast_addr = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
 	int result = 0;
 
@@ -869,10 +870,8 @@
 		 (int)dev->descriptor.bLength,
 		 (int)dev->descriptor.bDescriptorType);
 
-	if(!(kaweth = kmalloc(sizeof(struct kaweth_device), GFP_KERNEL))) {
-		kaweth_dbg("out of memory allocating device structure\n");
+	if(!(kaweth = kmalloc(sizeof(struct kaweth_device), GFP_KERNEL)))
 		return NULL;
-	}
 
 	memset(kaweth, 0, sizeof(struct kaweth_device));
 
@@ -998,11 +997,17 @@
 
 	if(result < 0) {
 		kaweth_err("Error setting receive filter");
-		return kaweth;
+		kfree(kaweth);
+		return NULL;
 	}
 
 	kaweth_dbg("Initializing net device.");
 
+	if(!(netdev = kmalloc(sizeof(struct net_device), GFP_KERNEL))) {
+		kfree(kaweth);
+		return NULL;
+	}
+
 	kaweth->tx_urb = usb_alloc_urb(0, GFP_KERNEL);
 	if (!kaweth->tx_urb)
 		goto err_no_urb;
@@ -1013,12 +1018,7 @@
 	if (!kaweth->irq_urb)
 		goto err_tx_and_rx;
 
-	kaweth->net = init_etherdev(0, 0);
-	if (!kaweth->net) {
-		kaweth_err("Error calling init_etherdev.");
-		return kaweth;
-	}
-
+	kaweth->net = netdev;
 	memcpy(kaweth->net->broadcast, &bcast_addr, sizeof(bcast_addr));
 	memcpy(kaweth->net->dev_addr,
                &kaweth->configuration.hw_addr,
@@ -1038,6 +1038,13 @@
 	kaweth->net->mtu = le16_to_cpu(kaweth->configuration.segment_size);
 
 	memset(&kaweth->stats, 0, sizeof(kaweth->stats));
+	
+	SET_MODULE_OWNER(netdev);
+
+	if (!init_etherdev(netdev, 0)) {
+		kaweth_err("Error calling init_etherdev.");
+		goto err_tx_and_rx;
+	}
 
 	kaweth_info("kaweth interface created at %s", kaweth->net->name);
 
@@ -1051,6 +1058,7 @@
 	usb_free_urb(kaweth->tx_urb);
 err_no_urb:
 	kfree(kaweth);
+	kfree(netdev);
 	return NULL;
 }
 
