# 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.635   -> 1.636  
#	drivers/usb/storage/transport.c	1.13    -> 1.14   
#	drivers/usb/storage/scsiglue.c	1.11    -> 1.12   
#	drivers/usb/storage/usb.h	1.4     -> 1.5    
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 02/08/29	zaitcev@redhat.com	1.636
# [PATCH] Patch for urb->status abuse in usb-storage in 2.4
# 
# Here is a patch from Pete Zaitcev <zaitcev@redhat.com> which rids us of a
# EINPROGRESS test.  These tests really aren't a good thing according to
# Pete, and I tend to agree with him.
# 
# This is for the 2.4 tree.  Pete claims to have tested this.
# Note that the changes are in an error-handling path and look pretty
# reasonable on their face, so I don't think there is any reason not to send
# this on to Marcello.
# --------------------------------------------
#
diff -Nru a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c
--- a/drivers/usb/storage/scsiglue.c	Thu Aug 29 13:54:16 2002
+++ b/drivers/usb/storage/scsiglue.c	Thu Aug 29 13:54:16 2002
@@ -190,7 +190,7 @@
 	}
 
 	/* if we have an urb pending, let's wake the control thread up */
-	if (us->current_urb->status == -EINPROGRESS) {
+	if (!us->current_done.done) {
 		/* cancel the URB -- this will automatically wake the thread */
 		usb_unlink_urb(us->current_urb);
 
diff -Nru a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c
--- a/drivers/usb/storage/transport.c	Thu Aug 29 13:54:16 2002
+++ b/drivers/usb/storage/transport.c	Thu Aug 29 13:54:16 2002
@@ -360,7 +360,6 @@
 			 u8 request, u8 requesttype, u16 value, u16 index, 
 			 void *data, u16 size)
 {
-	struct completion urb_done;
 	int status;
 	struct usb_ctrlrequest *dr;
 
@@ -377,7 +376,7 @@
 	dr->wLength = cpu_to_le16(size);
 
 	/* set up data structures for the wakeup system */
-	init_completion(&urb_done);
+	init_completion(&us->current_done);
 
 	/* lock the URB */
 	down(&(us->current_urb_sem));
@@ -385,7 +384,7 @@
 	/* fill the URB */
 	FILL_CONTROL_URB(us->current_urb, us->pusb_dev, pipe, 
 			 (unsigned char*) dr, data, size, 
-			 usb_stor_blocking_completion, &urb_done);
+			 usb_stor_blocking_completion, &us->current_done);
 	us->current_urb->actual_length = 0;
 	us->current_urb->error_count = 0;
 	us->current_urb->transfer_flags = USB_ASYNC_UNLINK;
@@ -401,7 +400,7 @@
 
 	/* wait for the completion of the URB */
 	up(&(us->current_urb_sem));
-	wait_for_completion(&urb_done);
+	wait_for_completion(&us->current_done);
 	down(&(us->current_urb_sem));
 
 	/* return the actual length of the data transferred if no error*/
@@ -421,18 +420,17 @@
 int usb_stor_bulk_msg(struct us_data *us, void *data, int pipe,
 		      unsigned int len, unsigned int *act_len)
 {
-	struct completion urb_done;
 	int status;
 
 	/* set up data structures for the wakeup system */
-	init_completion(&urb_done);
+	init_completion(&us->current_done);
 
 	/* lock the URB */
 	down(&(us->current_urb_sem));
 
 	/* fill the URB */
 	FILL_BULK_URB(us->current_urb, us->pusb_dev, pipe, data, len,
-		      usb_stor_blocking_completion, &urb_done);
+		      usb_stor_blocking_completion, &us->current_done);
 	us->current_urb->actual_length = 0;
 	us->current_urb->error_count = 0;
 	us->current_urb->transfer_flags = USB_ASYNC_UNLINK;
@@ -447,7 +445,7 @@
 
 	/* wait for the completion of the URB */
 	up(&(us->current_urb_sem));
-	wait_for_completion(&urb_done);
+	wait_for_completion(&us->current_done);
 	down(&(us->current_urb_sem));
 
 	/* return the actual length of the data transferred */
diff -Nru a/drivers/usb/storage/usb.h b/drivers/usb/storage/usb.h
--- a/drivers/usb/storage/usb.h	Thu Aug 29 13:54:16 2002
+++ b/drivers/usb/storage/usb.h	Thu Aug 29 13:54:16 2002
@@ -166,6 +166,7 @@
 	/* control and bulk communications data */
 	struct semaphore	current_urb_sem; /* to protect irq_urb	 */
 	struct urb		*current_urb;	 /* non-int USB requests */
+	struct completion	current_done;	 /* the done flag        */
 
 	/* the semaphore for sleeping the control thread */
 	struct semaphore	sema;		 /* to sleep thread on   */
