# 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.689   -> 1.690  
#	drivers/usb/kaweth.c	1.15    -> 1.16   
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 02/09/26	oliver@neukum.name	1.690
# [PATCH] USB: fixes for kaweth
# 
# this fixes a few SMP locking issues for kaweth.
# --------------------------------------------
#
diff -Nru a/drivers/usb/kaweth.c b/drivers/usb/kaweth.c
--- a/drivers/usb/kaweth.c	Mon Sep 30 10:47:01 2002
+++ b/drivers/usb/kaweth.c	Mon Sep 30 10:47:01 2002
@@ -495,6 +495,7 @@
 static void kaweth_resubmit_rx_urb(struct kaweth_device *kaweth)
 {
 	int result;
+	long flags;
 
 	FILL_BULK_URB(kaweth->rx_urb,
 		      kaweth->dev,
@@ -504,13 +505,17 @@
 		      kaweth_usb_receive,
 		      kaweth);
 
-	if((result = usb_submit_urb(kaweth->rx_urb))) {
-		if (result == -ENOMEM)
-			kaweth->suspend_lowmem = 1;
-		kaweth_err("resubmitting rx_urb %d failed", result);
-	} else {
-		kaweth->suspend_lowmem = 0;
+	spin_lock_irqsave(&kaweth->device_lock, flags);
+	if (!kaweth->removed) { /* no resubmit if disconnecting */
+		if((result = usb_submit_urb(kaweth->rx_urb))) {
+			if (result == -ENOMEM)
+				kaweth->suspend_lowmem = 1;
+			kaweth_err("resubmitting rx_urb %d failed", result);
+		} else {
+			kaweth->suspend_lowmem = 0;
+		}
 	}
+	spin_unlock_irqrestore(&kaweth->device_lock, flags);
 }
 
 static void kaweth_async_set_rx_mode(struct kaweth_device *kaweth);
@@ -625,8 +630,10 @@
 	struct kaweth_device *kaweth = net->priv;
 
 	netif_stop_queue(net);
-
+	
+	spin_lock_irq(&kaweth->device_lock);
 	kaweth->status |= KAWETH_STATUS_CLOSING;
+	spin_unlock_irq(&kaweth->device_lock);
 
 	usb_unlink_urb(kaweth->irq_urb);
 	usb_unlink_urb(kaweth->rx_urb);
@@ -1065,12 +1072,12 @@
 	usb_unlink_urb(kaweth->rx_urb);
 
 	/* we need to wait for the urb to be cancelled, if it is active */
-	spin_lock(&kaweth->device_lock);
+	spin_lock_irq(&kaweth->device_lock);
 	if (usb_unlink_urb(kaweth->tx_urb) == -EINPROGRESS) {
-		spin_unlock(&kaweth->device_lock);
+		spin_unlock_irq(&kaweth->device_lock);
 		wait_event(kaweth->term_wait, kaweth->end);
 	} else {
-		spin_unlock(&kaweth->device_lock);
+		spin_unlock_irq(&kaweth->device_lock);
 	}
 
 	if(kaweth->net) {
