ChangeSet 1.1673.8.61, 2004/03/31 13:09:35-08:00, stern@rowland.harvard.edu

[PATCH] USB: Complete all URBs in UHCI when releasing the bus

This patch changes the UHCI driver's bus-release routine; now it will
correctly finish all pending but not-yet-completed URBs.  This fixes a
reported bug, when trying to rmmod uhci-hcd while using a USB mouse under
X.  Also, the patch changes a variable name from ...hs... to ...fs...
("high speed" -> "full speed") -- something I accidentally omitted in an
earlier patch.


 drivers/usb/host/uhci-debug.c |    2 +-
 drivers/usb/host/uhci-hcd.c   |   16 ++++++++--------
 drivers/usb/host/uhci-hcd.h   |    2 +-
 3 files changed, 10 insertions(+), 10 deletions(-)


diff -Nru a/drivers/usb/host/uhci-debug.c b/drivers/usb/host/uhci-debug.c
--- a/drivers/usb/host/uhci-debug.c	Wed Apr 14 14:34:56 2004
+++ b/drivers/usb/host/uhci-debug.c	Wed Apr 14 14:34:56 2004
@@ -210,7 +210,7 @@
   "skel_int32_qh", "skel_int16_qh",
   "skel_int8_qh", "skel_int4_qh",
   "skel_int2_qh", "skel_int1_qh",
-  "skel_ls_control_qh", "skel_hs_control_qh",
+  "skel_ls_control_qh", "skel_fs_control_qh",
   "skel_bulk_qh", "skel_term_qh"
 };
 
diff -Nru a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c
--- a/drivers/usb/host/uhci-hcd.c	Wed Apr 14 14:34:56 2004
+++ b/drivers/usb/host/uhci-hcd.c	Wed Apr 14 14:34:56 2004
@@ -667,7 +667,7 @@
 	if ((!(urb->transfer_flags & URB_NO_FSBR)) && !urbp->fsbr) {
 		urbp->fsbr = 1;
 		if (!uhci->fsbr++ && !uhci->fsbrtimeout)
-			uhci->skel_term_qh->link = cpu_to_le32(uhci->skel_hs_control_qh->dma_handle) | UHCI_PTR_QH;
+			uhci->skel_term_qh->link = cpu_to_le32(uhci->skel_fs_control_qh->dma_handle) | UHCI_PTR_QH;
 	}
 }
 
@@ -817,7 +817,7 @@
 	if (urb->dev->speed == USB_SPEED_LOW)
 		skelqh = uhci->skel_ls_control_qh;
 	else {
-		skelqh = uhci->skel_hs_control_qh;
+		skelqh = uhci->skel_fs_control_qh;
 		uhci_inc_fsbr(uhci, urb);
 	}
 
@@ -2164,8 +2164,8 @@
 			cpu_to_le32(uhci->skel_int1_qh->dma_handle) | UHCI_PTR_QH;
 	uhci->skel_int1_qh->link = cpu_to_le32(uhci->skel_ls_control_qh->dma_handle) | UHCI_PTR_QH;
 
-	uhci->skel_ls_control_qh->link = cpu_to_le32(uhci->skel_hs_control_qh->dma_handle) | UHCI_PTR_QH;
-	uhci->skel_hs_control_qh->link = cpu_to_le32(uhci->skel_bulk_qh->dma_handle) | UHCI_PTR_QH;
+	uhci->skel_ls_control_qh->link = cpu_to_le32(uhci->skel_fs_control_qh->dma_handle) | UHCI_PTR_QH;
+	uhci->skel_fs_control_qh->link = cpu_to_le32(uhci->skel_bulk_qh->dma_handle) | UHCI_PTR_QH;
 	uhci->skel_bulk_qh->link = cpu_to_le32(uhci->skel_term_qh->dma_handle) | UHCI_PTR_QH;
 
 	/* This dummy TD is to work around a bug in Intel PIIX controllers */
@@ -2276,15 +2276,15 @@
 	 * At this point, we're guaranteed that no new connects can be made
 	 * to this bus since there are no more parents
 	 */
+
+	reset_hc(uhci);
+
 	spin_lock_irq(&uhci->schedule_lock);
 	uhci_free_pending_qhs(uhci);
 	uhci_free_pending_tds(uhci);
 	uhci_remove_pending_urbps(uhci);
-	spin_unlock_irq(&uhci->schedule_lock);
+	uhci_finish_completion(hcd, NULL);
 
-	reset_hc(uhci);
-
-	spin_lock_irq(&uhci->schedule_lock);
 	uhci_free_pending_qhs(uhci);
 	uhci_free_pending_tds(uhci);
 	spin_unlock_irq(&uhci->schedule_lock);
diff -Nru a/drivers/usb/host/uhci-hcd.h b/drivers/usb/host/uhci-hcd.h
--- a/drivers/usb/host/uhci-hcd.h	Wed Apr 14 14:34:56 2004
+++ b/drivers/usb/host/uhci-hcd.h	Wed Apr 14 14:34:56 2004
@@ -254,7 +254,7 @@
 #define skel_int2_qh		skelqh[6]
 #define skel_int1_qh		skelqh[7]
 #define skel_ls_control_qh	skelqh[8]
-#define skel_hs_control_qh	skelqh[9]
+#define skel_fs_control_qh	skelqh[9]
 #define skel_bulk_qh		skelqh[10]
 #define skel_term_qh		skelqh[11]
 
