[PATCH] usb-storage: get rid of the timer during URB submission

This patch uses completion timeout instead of a timer to implement
a timeout when submitting an URB.

It also put the task in interruptible state instead of an
uninterruptible one while waiting for the completion.

Signed-off-by: Franck Bui-Huu <vagabon.xyz@gmail.com>
Signed-off-by: Matthew Dharm <mdharm-usb@one-eyed-alien.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c
index 7ca896a..038f458 100644
--- a/drivers/usb/storage/transport.c
+++ b/drivers/usb/storage/transport.c
@@ -115,19 +115,6 @@
 
 	complete(urb_done_ptr);
 }
- 
-/* This is the timeout handler which will cancel an URB when its timeout
- * expires.
- */
-static void timeout_handler(unsigned long us_)
-{
-	struct us_data *us = (struct us_data *) us_;
-
-	if (test_and_clear_bit(US_FLIDX_URB_ACTIVE, &us->flags)) {
-		US_DEBUGP("Timeout -- cancelling URB\n");
-		usb_unlink_urb(us->current_urb);
-	}
-}
 
 /* This is the common part of the URB message submission code
  *
@@ -138,7 +125,7 @@
 static int usb_stor_msg_common(struct us_data *us, int timeout)
 {
 	struct completion urb_done;
-	struct timer_list to_timer;
+	long timeleft;
 	int status;
 
 	/* don't submit URBs during abort/disconnect processing */
@@ -185,22 +172,17 @@
 		}
 	}
  
-	/* submit the timeout timer, if a timeout was requested */
-	if (timeout > 0) {
-		init_timer(&to_timer);
-		to_timer.expires = jiffies + timeout;
-		to_timer.function = timeout_handler;
-		to_timer.data = (unsigned long) us;
-		add_timer(&to_timer);
-	}
-
 	/* wait for the completion of the URB */
-	wait_for_completion(&urb_done);
-	clear_bit(US_FLIDX_URB_ACTIVE, &us->flags);
+	timeleft = wait_for_completion_interruptible_timeout(
+			&urb_done, timeout ? : MAX_SCHEDULE_TIMEOUT);
  
-	/* clean up the timeout timer */
-	if (timeout > 0)
-		del_timer_sync(&to_timer);
+	clear_bit(US_FLIDX_URB_ACTIVE, &us->flags);
+
+	if (timeleft <= 0) {
+		US_DEBUGP("%s -- cancelling URB\n",
+			  timeleft == 0 ? "Timeout" : "Signal");
+		usb_unlink_urb(us->current_urb);
+	}
 
 	/* return the URB status */
 	return us->current_urb->status;