From: Greg KH <greg@kroah.com>
To: torvalds@transmeta.com
Cc: linux-usb-devel@lists.sourceforge.net
Subject: [PATCH 3 of 9] USB Kaweth driver update

Hi,

Here's a patch against 2.5.3 for the USB kaweth driver that does the
following:
	- removes SMP deadlock
	- removes nfs deadlock
	- fixes a memory leak when the firmware is not loaded.
	- few other minor cleanups.
This patch was done by Oliver Neukum.


thanks,

greg k-h



diff -Nru a/drivers/usb/kaweth.c b/drivers/usb/kaweth.c
--- a/drivers/usb/kaweth.c	Sun Feb  3 00:53:04 2002
+++ b/drivers/usb/kaweth.c	Sun Feb  3 00:53:04 2002
@@ -155,6 +155,7 @@
  *     kaweth_driver
  ****************************************************************/
 static struct usb_driver kaweth_driver = {
+	owner:		THIS_MODULE,
 	name:		"kaweth",
 	probe:		kaweth_probe,
 	disconnect:	kaweth_disconnect,
@@ -238,8 +239,7 @@
 		return -EBUSY;
 	}
 
-	dr = kmalloc(sizeof(struct usb_ctrlrequest), 
-                     in_interrupt() ? GFP_ATOMIC : GFP_KERNEL);
+	dr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_ATOMIC);
 
 	if (!dr) {
 		kaweth_dbg("kmalloc() failed");
@@ -586,14 +586,10 @@
 {
 	struct kaweth_device *kaweth = urb->context;
 
-	spin_lock(&kaweth->device_lock);
-
-	if (urb->status)
+	if (unlikely(urb->status != 0))
 		kaweth_dbg("%s: TX status %d.", kaweth->net->name, urb->status);
 
 	netif_wake_queue(kaweth->net);
-
-	spin_unlock(&kaweth->device_lock);
 }
 
 /****************************************************************
@@ -757,9 +753,7 @@
 	memset(kaweth, 0, sizeof(struct kaweth_device));
 
 	kaweth->dev = dev;
-	kaweth->status = 0;
-	kaweth->net = NULL;
-	kaweth->device_lock = SPIN_LOCK_UNLOCKED;
+	spin_lock_init(&kaweth->device_lock);
 		
 	kaweth_dbg("Resetting.");
 
@@ -824,6 +818,7 @@
 
 		/* Device will now disappear for a moment...  */
 		kaweth_info("Firmware loaded.  I'll be back...");
+		kfree(kaweth);
 		return NULL;
 	}
 
@@ -925,6 +920,8 @@
 		kaweth_warn("unregistering non-existant device");
 		return;
 	}
+	usb_unlink_urb(kaweth->tx_urb);
+	usb_unlink_urb(kaweth->rx_urb);
 
 	if(kaweth->net) {
 		if(kaweth->net->flags & IFF_UP) {

