<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">ChangeSet 1.783, 2002/12/05 14:20:31-08:00, oliver@oenone.homelinux.org

[PATCH] - use of unplugged scanner oops fix



diff -Nru a/drivers/usb/hpusbscsi.c b/drivers/usb/hpusbscsi.c
--- a/drivers/usb/hpusbscsi.c	Thu Dec  5 14:48:41 2002
+++ b/drivers/usb/hpusbscsi.c	Thu Dec  5 14:48:41 2002
@@ -125,6 +125,7 @@
 	new-&gt;dev = dev;
 	init_waitqueue_head (&amp;new-&gt;pending);
 	init_waitqueue_head (&amp;new-&gt;deathrow);
+	init_MUTEX(&amp;new-&gt;lock);
 	INIT_LIST_HEAD (&amp;new-&gt;lh);
 
 
@@ -202,12 +203,12 @@
 {
 	struct hpusbscsi *hp = (struct hpusbscsi *)ptr;
 
+	down(&amp;hp-&gt;lock);
 	usb_unlink_urb(&amp;hp-&gt;controlurb);
 	usb_unlink_urb(&amp;hp-&gt;dataurb);
 
-	spin_lock_irq(&amp;io_request_lock);
 	hp-&gt;dev = NULL;
-	spin_unlock_irq(&amp;io_request_lock);
+	up(&amp;hp-&gt;lock);
 }
 
 static struct usb_device_id hpusbscsi_usb_ids[] = {
@@ -347,6 +348,15 @@
 	if ( srb-&gt;device-&gt;lun || srb-&gt;device-&gt;id || srb-&gt;device-&gt;channel ) {
 		srb-&gt;result = DID_BAD_TARGET;
 		callback(srb);
+		goto out_nolock;
+	}
+
+	/* to prevent a race with removal */
+	down(&amp;hpusbscsi-&gt;lock);
+
+	if (hpusbscsi-&gt;dev == NULL) {
+		srb-&gt;result = DID_ERROR;
+		callback(srb);
 		goto out;
 	}
 
@@ -400,12 +410,7 @@
 	);
 	hpusbscsi-&gt;scallback = callback;
 	hpusbscsi-&gt;srb = srb;
-	
-	if (hpusbscsi-&gt;dev == NULL) {
-		srb-&gt;result = DID_ERROR;
-		callback(srb);
-		goto out;
-	}
+
 
 	res = usb_submit_urb(&amp;hpusbscsi-&gt;dataurb);
 	if (res) {
@@ -417,6 +422,8 @@
 	}
 
 out:
+	up(&amp;hpusbscsi-&gt;lock);
+out_nolock:
 	spin_lock_irq(&amp;io_request_lock);
 	return 0;
 }
diff -Nru a/drivers/usb/hpusbscsi.h b/drivers/usb/hpusbscsi.h
--- a/drivers/usb/hpusbscsi.h	Thu Dec  5 14:48:41 2002
+++ b/drivers/usb/hpusbscsi.h	Thu Dec  5 14:48:41 2002
@@ -29,6 +29,7 @@
 	u8 sense_command[SENSE_COMMAND_SIZE];
 
         int use_count;
+	struct semaphore lock;
         wait_queue_head_t pending;
         wait_queue_head_t deathrow;
 
</pre></body></html>