Merge current mainline tree into linux-omap tree
[pandora-kernel.git] / drivers / usb / host / ehci-hcd.c
index 85074cb..0689462 100644 (file)
  * Special thanks to Intel and VIA for providing host controllers to
  * test this driver on, and Cypress (including In-System Design) for
  * providing early devices for those host controllers to talk to!
- *
- * HISTORY:
- *
- * 2004-05-10 Root hub and PCI suspend/resume support; remote wakeup. (db)
- * 2004-02-24 Replace pci_* with generic dma_* API calls (dsaxena@plexity.net)
- * 2003-12-29 Rewritten high speed iso transfer support (by Michal Sojka,
- *     <sojkam@centrum.cz>, updates by DB).
- *
- * 2002-11-29  Correct handling for hw async_next register.
- * 2002-08-06  Handling for bulk and interrupt transfers is mostly shared;
- *     only scheduling is different, no arbitrary limitations.
- * 2002-07-25  Sanity check PCI reads, mostly for better cardbus support,
- *     clean up HC run state handshaking.
- * 2002-05-24  Preliminary FS/LS interrupts, using scheduling shortcuts
- * 2002-05-11  Clear TT errors for FS/LS ctrl/bulk.  Fill in some other
- *     missing pieces:  enabling 64bit dma, handoff from BIOS/SMM.
- * 2002-05-07  Some error path cleanups to report better errors; wmb();
- *     use non-CVS version id; better iso bandwidth claim.
- * 2002-04-19  Control/bulk/interrupt submit no longer uses giveback() on
- *     errors in submit path.  Bugfixes to interrupt scheduling/processing.
- * 2002-03-05  Initial high-speed ISO support; reduce ITD memory; shift
- *     more checking to generic hcd framework (db).  Make it work with
- *     Philips EHCI; reduce PCI traffic; shorten IRQ path (Rory Bolt).
- * 2002-01-14  Minor cleanup; version synch.
- * 2002-01-08  Fix roothub handoff of FS/LS to companion controllers.
- * 2002-01-04  Control/Bulk queuing behaves.
- *
- * 2001-12-12  Initial patch version for Linux 2.5.1 kernel.
- * 2001-June   Works with usb-storage and NEC EHCI on 2.4
  */
 
 #define DRIVER_VERSION "10 Dec 2004"
@@ -95,7 +66,7 @@
 static const char      hcd_name [] = "ehci_hcd";
 
 
-#undef EHCI_VERBOSE_DEBUG
+#undef VERBOSE_DEBUG
 #undef EHCI_URB_TRACE
 
 #ifdef DEBUG
@@ -113,7 +84,7 @@ static const char    hcd_name [] = "ehci_hcd";
 #define EHCI_IAA_MSECS         10              /* arbitrary */
 #define EHCI_IO_JIFFIES                (HZ/10)         /* io watchdog > irq_thresh */
 #define EHCI_ASYNC_JIFFIES     (HZ/20)         /* async idle timeout */
-#define EHCI_SHRINK_JIFFIES    (HZ/200)        /* async qh unlink delay */
+#define EHCI_SHRINK_FRAMES     5               /* async qh unlink delay */
 
 /* Initial IRQ latency:  faster than hw default */
 static int log2_irq_thresh = 0;                // 0 to 6
@@ -192,6 +163,22 @@ static int ehci_halt (struct ehci_hcd *ehci)
                          STS_HALT, STS_HALT, 16 * 125);
 }
 
+static int handshake_on_error_set_halt(struct ehci_hcd *ehci, void __iomem *ptr,
+                                      u32 mask, u32 done, int usec)
+{
+       int error;
+
+       error = handshake(ehci, ptr, mask, done, usec);
+       if (error) {
+               ehci_halt(ehci);
+               ehci_to_hcd(ehci)->state = HC_STATE_HALT;
+               ehci_err(ehci, "force halt; handhake %p %08x %08x -> %d\n",
+                       ptr, mask, done, error);
+       }
+
+       return error;
+}
+
 /* put TDI/ARC silicon into EHCI mode */
 static void tdi_reset (struct ehci_hcd *ehci)
 {
@@ -246,11 +233,9 @@ static void ehci_quiesce (struct ehci_hcd *ehci)
        /* wait for any schedule enables/disables to take effect */
        temp = ehci_readl(ehci, &ehci->regs->command) << 10;
        temp &= STS_ASS | STS_PSS;
-       if (handshake (ehci, &ehci->regs->status, STS_ASS | STS_PSS,
-                               temp, 16 * 125) != 0) {
-               ehci_to_hcd(ehci)->state = HC_STATE_HALT;
+       if (handshake_on_error_set_halt(ehci, &ehci->regs->status,
+                                       STS_ASS | STS_PSS, temp, 16 * 125))
                return;
-       }
 
        /* then disable anything that's still active */
        temp = ehci_readl(ehci, &ehci->regs->command);
@@ -258,11 +243,8 @@ static void ehci_quiesce (struct ehci_hcd *ehci)
        ehci_writel(ehci, temp, &ehci->regs->command);
 
        /* hardware can take 16 microframes to turn off ... */
-       if (handshake (ehci, &ehci->regs->status, STS_ASS | STS_PSS,
-                               0, 16 * 125) != 0) {
-               ehci_to_hcd(ehci)->state = HC_STATE_HALT;
-               return;
-       }
+       handshake_on_error_set_halt(ehci, &ehci->regs->status,
+                                   STS_ASS | STS_PSS, 0, 16 * 125);
 }
 
 /*-------------------------------------------------------------------------*/
@@ -355,17 +337,13 @@ static void ehci_turn_off_all_ports(struct ehci_hcd *ehci)
                                &ehci->regs->port_status[port]);
 }
 
-/* ehci_shutdown kick in for silicon on any bus (not just pci, etc).
- * This forcibly disables dma and IRQs, helping kexec and other cases
- * where the next system software may expect clean state.
+/*
+ * Halt HC, turn off all ports, and let the BIOS use the companion controllers.
+ * Should be called with ehci->lock held.
  */
-static void
-ehci_shutdown (struct usb_hcd *hcd)
+static void ehci_silence_controller(struct ehci_hcd *ehci)
 {
-       struct ehci_hcd *ehci;
-
-       ehci = hcd_to_ehci (hcd);
-       (void) ehci_halt (ehci);
+       ehci_halt(ehci);
        ehci_turn_off_all_ports(ehci);
 
        /* make BIOS/etc use companion controller during reboot */
@@ -375,6 +353,22 @@ ehci_shutdown (struct usb_hcd *hcd)
        ehci_readl(ehci, &ehci->regs->configured_flag);
 }
 
+/* ehci_shutdown kick in for silicon on any bus (not just pci, etc).
+ * This forcibly disables dma and IRQs, helping kexec and other cases
+ * where the next system software may expect clean state.
+ */
+static void ehci_shutdown(struct usb_hcd *hcd)
+{
+       struct ehci_hcd *ehci = hcd_to_ehci(hcd);
+
+       del_timer_sync(&ehci->watchdog);
+       del_timer_sync(&ehci->iaa_watchdog);
+
+       spin_lock_irq(&ehci->lock);
+       ehci_silence_controller(ehci);
+       spin_unlock_irq(&ehci->lock);
+}
+
 static void ehci_port_power (struct ehci_hcd *ehci, int is_on)
 {
        unsigned port;
@@ -425,15 +419,15 @@ static void ehci_work (struct ehci_hcd *ehci)
                timer_action (ehci, TIMER_IO_WATCHDOG);
 }
 
+/*
+ * Called when the ehci_hcd module is removed.
+ */
 static void ehci_stop (struct usb_hcd *hcd)
 {
        struct ehci_hcd         *ehci = hcd_to_ehci (hcd);
 
        ehci_dbg (ehci, "stop\n");
 
-       /* Turn off port power on all root hub ports. */
-       ehci_port_power (ehci, 0);
-
        /* no more interrupts ... */
        del_timer_sync (&ehci->watchdog);
        del_timer_sync(&ehci->iaa_watchdog);
@@ -442,13 +436,10 @@ static void ehci_stop (struct usb_hcd *hcd)
        if (HC_IS_RUNNING (hcd->state))
                ehci_quiesce (ehci);
 
+       ehci_silence_controller(ehci);
        ehci_reset (ehci);
-       ehci_writel(ehci, 0, &ehci->regs->intr_enable);
        spin_unlock_irq(&ehci->lock);
 
-       /* let companion controllers work when we aren't */
-       ehci_writel(ehci, 0, &ehci->regs->configured_flag);
-
        remove_companion_file(ehci);
        remove_debug_files (ehci);
 
@@ -676,7 +667,7 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)
        cmd = ehci_readl(ehci, &ehci->regs->command);
        bh = 0;
 
-#ifdef EHCI_VERBOSE_DEBUG
+#ifdef VERBOSE_DEBUG
        /* unrequested/ignored: Frame List Rollover */
        dbg_status (ehci, "irq", status);
 #endif
@@ -710,6 +701,8 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)
        /* remote wakeup [4.3.1] */
        if (status & STS_PCD) {
                unsigned        i = HCS_N_PORTS (ehci->hcs_params);
+
+               /* kick root hub later */
                pcd_status = status;
 
                /* resume root hub? */
@@ -738,8 +731,6 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)
 
        /* PCI errors [4.15.2.4] */
        if (unlikely ((status & STS_FATAL) != 0)) {
-               /* bogus "fatal" IRQs appear on some chips... why?  */
-               status = ehci_readl(ehci, &ehci->regs->status);
                dbg_cmd (ehci, "fatal", ehci_readl(ehci,
                                                   &ehci->regs->command));
                dbg_status (ehci, "fatal", status);
@@ -758,7 +749,7 @@ dead:
        if (bh)
                ehci_work (ehci);
        spin_unlock (&ehci->lock);
-       if (pcd_status & STS_PCD)
+       if (pcd_status)
                usb_hcd_poll_rh_status(hcd);
        return IRQ_HANDLED;
 }
@@ -788,8 +779,14 @@ static int ehci_urb_enqueue (
        INIT_LIST_HEAD (&qtd_list);
 
        switch (usb_pipetype (urb->pipe)) {
-       // case PIPE_CONTROL:
-       // case PIPE_BULK:
+       case PIPE_CONTROL:
+               /* qh_completions() code doesn't handle all the fault cases
+                * in multi-TD control transfers.  Even 1KB is rare anyway.
+                */
+               if (urb->transfer_buffer_length > (16 * 1024))
+                       return -EMSGSIZE;
+               /* FALLTHROUGH */
+       /* case PIPE_BULK: */
        default:
                if (!qh_urb_transaction (ehci, urb, &qtd_list, mem_flags))
                        return -ENOMEM;
@@ -1018,6 +1015,11 @@ MODULE_LICENSE ("GPL");
 #define        PLATFORM_DRIVER         ehci_hcd_au1xxx_driver
 #endif
 
+#ifdef CONFIG_ARCH_OMAP34XX
+#include "ehci-omap.c"
+#define        PLATFORM_DRIVER         ehci_hcd_omap_driver
+#endif
+
 #ifdef CONFIG_PPC_PS3
 #include "ehci-ps3.c"
 #define        PS3_SYSTEM_BUS_DRIVER   ps3_ehci_driver