From 915801c37130d8346ca0399fb8637f8f53bbd8e6 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Tue, 30 Mar 2004 21:09:35 -0800 Subject: [PATCH] [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 --git a/drivers/usb/host/uhci-debug.c b/drivers/usb/host/uhci-debug.c index a43c62d807a00..c2e63e29b75a4 100644 --- a/drivers/usb/host/uhci-debug.c +++ b/drivers/usb/host/uhci-debug.c @@ -210,7 +210,7 @@ static const char *qh_names[] = { "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 --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c index 8ad3b5c47ea18..9f548cb09764f 100644 --- a/drivers/usb/host/uhci-hcd.c +++ b/drivers/usb/host/uhci-hcd.c @@ -667,7 +667,7 @@ static void uhci_inc_fsbr(struct uhci_hcd *uhci, struct urb *urb) 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 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb, struct ur 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 @@ static int uhci_start(struct usb_hcd *hcd) 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 @@ static void uhci_stop(struct usb_hcd *hcd) * 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 --git a/drivers/usb/host/uhci-hcd.h b/drivers/usb/host/uhci-hcd.h index 93873e575665c..7f8bd85bac5b8 100644 --- a/drivers/usb/host/uhci-hcd.h +++ b/drivers/usb/host/uhci-hcd.h @@ -254,7 +254,7 @@ struct uhci_td { #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] -- 2.53.0