ChangeSet 1.1722.83.19, 2004/06/04 15:13:47-07:00, [EMAIL PROTECTED]

[PATCH] USB: Code cleanup for the UHCI driver

This patch makes some simple cleanups in the UHCI driver:

        It introduces msecs_to_jiffies() conversions and uses msleep().

        It wakes up threads waiting for an endpoint to be disabled
        in the oddball case where interrupts aren't working.  (This
        should have been in a previous patch but I missed it.)

        It disables PCI interrupt generation whenever the controller
        is reset and enables it when the controller is started.  This
        may possibly solve some people's problems with suspend/resume.

Signed-off-by: Alan Stern <[EMAIL PROTECTED]>
Signed-off-by: Greg Kroah-Hartman <[EMAIL PROTECTED]>


 drivers/usb/host/uhci-hcd.c |   45 +++++++++++++++++++++++++++-----------------
 1 files changed, 28 insertions(+), 17 deletions(-)


diff -Nru a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c
--- a/drivers/usb/host/uhci-hcd.c       Fri Jun 18 11:03:28 2004
+++ b/drivers/usb/host/uhci-hcd.c       Fri Jun 18 11:03:28 2004
@@ -103,8 +103,8 @@
 static void hc_state_transitions(struct uhci_hcd *uhci);
 
 /* If a transfer is still active after this much time, turn off FSBR */
-#define IDLE_TIMEOUT   (HZ / 20)       /* 50 ms */
-#define FSBR_DELAY     (HZ / 20)       /* 50 ms */
+#define IDLE_TIMEOUT   msecs_to_jiffies(50)
+#define FSBR_DELAY     msecs_to_jiffies(50)
 
 /* When we timeout an idle transfer for FSBR, we'll switch it over to */
 /* depth first traversal. We'll do it in groups of this number of TD's */
@@ -1611,6 +1611,7 @@
        struct uhci_hcd *uhci = hcd_to_uhci(hcd);
        struct list_head list, *tmp, *head;
        unsigned long flags;
+       int called_uhci_finish_completion = 0;
 
        INIT_LIST_HEAD(&list);
 
@@ -1619,6 +1620,7 @@
            uhci_get_current_frame_number(uhci) != uhci->urb_remove_age) {
                uhci_remove_pending_urbps(uhci);
                uhci_finish_completion(hcd, NULL);
+               called_uhci_finish_completion = 1;
        }
 
        head = &uhci->urb_list;
@@ -1646,6 +1648,10 @@
        }
        spin_unlock_irqrestore(&uhci->schedule_lock, flags);
 
+       /* Wake up anyone waiting for an URB to complete */
+       if (called_uhci_finish_completion)
+               wake_up_all(&uhci->waitqh);
+
        head = &list;
        tmp = head->next;
        while (tmp != head) {
@@ -1676,7 +1682,7 @@
        init_timer(&uhci->stall_timer);
        uhci->stall_timer.function = stall_callback;
        uhci->stall_timer.data = (unsigned long)hcd;
-       uhci->stall_timer.expires = jiffies + (HZ / 10);
+       uhci->stall_timer.expires = jiffies + msecs_to_jiffies(100);
        add_timer(&uhci->stall_timer);
 
        return 0;
@@ -1831,16 +1837,20 @@
 {
        unsigned int io_addr = uhci->io_addr;
 
+       /* Turn off PIRQ, SMI, and all interrupts.  This also turns off
+        * the BIOS's USB Legacy Support.
+        */
+       pci_write_config_word(to_pci_dev(uhci_dev(uhci)), USBLEGSUP, 0);
+       outw(0, uhci->io_addr + USBINTR);
+
        /* Global reset for 50ms */
        uhci->state = UHCI_RESET;
        outw(USBCMD_GRESET, io_addr + USBCMD);
-       set_current_state(TASK_UNINTERRUPTIBLE);
-       schedule_timeout((HZ*50+999) / 1000);
+       msleep(50);
        outw(0, io_addr + USBCMD);
 
        /* Another 10ms delay */
-       set_current_state(TASK_UNINTERRUPTIBLE);
-       schedule_timeout((HZ*10+999) / 1000);
+       msleep(10);
        uhci->resume_detect = 0;
 }
 
@@ -1865,7 +1875,7 @@
                        /* Global resume for >= 20ms */
                        outw(USBCMD_FGR | USBCMD_EGSM, io_addr + USBCMD);
                        uhci->state = UHCI_RESUMING_1;
-                       uhci->state_end = jiffies + (20*HZ+999) / 1000;
+                       uhci->state_end = jiffies + msecs_to_jiffies(20);
                        break;
 
                case UHCI_RESUMING_1:           /* End global resume */
@@ -1990,7 +2000,9 @@
                }
        }
 
-       /* Turn on all interrupts */
+       /* Turn on PIRQ and all interrupts */
+       pci_write_config_word(to_pci_dev(uhci_dev(uhci)), USBLEGSUP,
+                       USBLEGSUP_DEFAULT);
        outw(USBINTR_TIMEOUT | USBINTR_RESUME | USBINTR_IOC | USBINTR_SP,
                io_addr + USBINTR);
 
@@ -2054,15 +2066,10 @@
 
        uhci->io_addr = (unsigned long) hcd->regs;
 
-       /* Turn off all interrupts */
-       outw(0, uhci->io_addr + USBINTR);
-
-       /* Maybe kick BIOS off this hardware.  Then reset, so we won't get
+       /* Kick BIOS off this hardware and reset, so we won't get
         * interrupts from any previous setup.
         */
        reset_hc(uhci);
-       pci_write_config_word(to_pci_dev(uhci_dev(uhci)), USBLEGSUP,
-                       USBLEGSUP_DEFAULT);
        return 0;
 }
 
@@ -2369,14 +2376,18 @@
                /*
                 * Some systems don't maintain the UHCI register values
                 * during a PM suspend/resume cycle, so reinitialize
-                * the Frame Number, the Framelist Base Address, and the
-                * Interrupt Enable registers.
+                * the Frame Number, Framelist Base Address, Interrupt
+                * Enable, and Legacy Support registers.
                 */
+               pci_write_config_word(to_pci_dev(uhci_dev(uhci)), USBLEGSUP,
+                               0);
                outw(uhci->saved_framenumber, uhci->io_addr + USBFRNUM);
                outl(uhci->fl->dma_handle, uhci->io_addr + USBFLBASEADD);
                outw(USBINTR_TIMEOUT | USBINTR_RESUME | USBINTR_IOC |
                                USBINTR_SP, uhci->io_addr + USBINTR);
                uhci->resume_detect = 1;
+               pci_write_config_word(to_pci_dev(uhci_dev(uhci)), USBLEGSUP,
+                               USBLEGSUP_DEFAULT);
        } else {
                reset_hc(uhci);
                start_hc(uhci);



-------------------------------------------------------
This SF.Net email is sponsored by The 2004 JavaOne(SM) Conference
Learn from the experts at JavaOne(SM), Sun's Worldwide Java Developer
Conference, June 28 - July 1 at the Moscone Center in San Francisco, CA
REGISTER AND SAVE! http://java.sun.com/javaone/sf Priority Code NWMGYKND
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to