]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/usb/host/ehci-hcd.c
Merge branch 'linus' into test
[linux-2.6-omap-h63xx.git] / drivers / usb / host / ehci-hcd.c
index d9d53f289caf48b83001b42321e1bbaf9ca00886..15a803b206b8ea72c4774ba6edb504a0fd5e964c 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/ioport.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
+#include <linux/vmalloc.h>
 #include <linux/errno.h>
 #include <linux/init.h>
 #include <linux/timer.h>
@@ -59,7 +60,6 @@
  * providing early devices for those host controllers to talk to!
  */
 
-#define DRIVER_VERSION "10 Dec 2004"
 #define DRIVER_AUTHOR "David Brownell"
 #define DRIVER_DESC "USB 2.0 'Enhanced' Host Controller (EHCI) Driver"
 
@@ -145,16 +145,6 @@ static int handshake (struct ehci_hcd *ehci, void __iomem *ptr,
        return -ETIMEDOUT;
 }
 
-static int handshake_on_error_set_halt(struct ehci_hcd *ehci, void __iomem *ptr,
-                                      u32 mask, u32 done, int usec)
-{
-       int error = handshake(ehci, ptr, mask, done, usec);
-       if (error)
-               ehci_to_hcd(ehci)->state = HC_STATE_HALT;
-
-       return error;
-}
-
 /* force HC to halt state from unknown (EHCI spec section 2.3) */
 static int ehci_halt (struct ehci_hcd *ehci)
 {
@@ -173,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)
 {
@@ -614,9 +620,9 @@ static int ehci_run (struct usb_hcd *hcd)
 
        temp = HC_VERSION(ehci_readl(ehci, &ehci->caps->hc_capbase));
        ehci_info (ehci,
-               "USB %x.%x started, EHCI %x.%02x, driver %s%s\n",
+               "USB %x.%x started, EHCI %x.%02x%s\n",
                ((ehci->sbrn & 0xf0)>>4), (ehci->sbrn & 0x0f),
-               temp >> 8, temp & 0xff, DRIVER_VERSION,
+               temp >> 8, temp & 0xff,
                ignore_oc ? ", overcurrent ignored" : "");
 
        ehci_writel(ehci, INTR_MASK,
@@ -700,7 +706,7 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)
                pcd_status = status;
 
                /* resume root hub? */
-               if (!(ehci_readl(ehci, &ehci->regs->command) & CMD_RUN))
+               if (!(cmd & CMD_RUN))
                        usb_hcd_resume_root_hub(hcd);
 
                while (i--) {
@@ -709,8 +715,11 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)
 
                        if (pstatus & PORT_OWNER)
                                continue;
-                       if (!(pstatus & PORT_RESUME)
-                                       || ehci->reset_done [i] != 0)
+                       if (!(test_bit(i, &ehci->suspended_ports) &&
+                                       ((pstatus & PORT_RESUME) ||
+                                               !(pstatus & PORT_SUSPEND)) &&
+                                       (pstatus & PORT_PE) &&
+                                       ehci->reset_done[i] == 0))
                                continue;
 
                        /* start 20 msec resume signaling from this port,
@@ -725,9 +734,8 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)
 
        /* PCI errors [4.15.2.4] */
        if (unlikely ((status & STS_FATAL) != 0)) {
-               dbg_cmd (ehci, "fatal", ehci_readl(ehci,
-                                                  &ehci->regs->command));
-               dbg_status (ehci, "fatal", status);
+               dbg_cmd(ehci, "fatal", cmd);
+               dbg_status(ehci, "fatal", status);
                if (status & STS_HALT) {
                        ehci_err (ehci, "fatal error\n");
 dead:
@@ -988,9 +996,7 @@ static int ehci_get_frame (struct usb_hcd *hcd)
 
 /*-------------------------------------------------------------------------*/
 
-#define DRIVER_INFO DRIVER_VERSION " " DRIVER_DESC
-
-MODULE_DESCRIPTION (DRIVER_INFO);
+MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_AUTHOR (DRIVER_AUTHOR);
 MODULE_LICENSE ("GPL");
 
@@ -1014,11 +1020,6 @@ MODULE_LICENSE ("GPL");
 #define        PS3_SYSTEM_BUS_DRIVER   ps3_ehci_driver
 #endif
 
-#if defined(CONFIG_440EPX) && !defined(CONFIG_PPC_MERGE)
-#include "ehci-ppc-soc.c"
-#define        PLATFORM_DRIVER         ehci_ppc_soc_driver
-#endif
-
 #ifdef CONFIG_USB_EHCI_HCD_PPC_OF
 #include "ehci-ppc-of.c"
 #define OF_PLATFORM_DRIVER     ehci_hcd_ppc_of_driver
@@ -1043,6 +1044,16 @@ static int __init ehci_hcd_init(void)
 {
        int retval = 0;
 
+       if (usb_disabled())
+               return -ENODEV;
+
+       printk(KERN_INFO "%s: " DRIVER_DESC "\n", hcd_name);
+       set_bit(USB_EHCI_LOADED, &usb_hcds_loaded);
+       if (test_bit(USB_UHCI_LOADED, &usb_hcds_loaded) ||
+                       test_bit(USB_OHCI_LOADED, &usb_hcds_loaded))
+               printk(KERN_WARNING "Warning! ehci_hcd should always be loaded"
+                               " before uhci_hcd and ohci_hcd, not after\n");
+
        pr_debug("%s: block sizes: qh %Zd qtd %Zd itd %Zd sitd %Zd\n",
                 hcd_name,
                 sizeof(struct ehci_qh), sizeof(struct ehci_qtd),
@@ -1050,8 +1061,10 @@ static int __init ehci_hcd_init(void)
 
 #ifdef DEBUG
        ehci_debug_root = debugfs_create_dir("ehci", NULL);
-       if (!ehci_debug_root)
-               return -ENOENT;
+       if (!ehci_debug_root) {
+               retval = -ENOENT;
+               goto err_debug;
+       }
 #endif
 
 #ifdef PLATFORM_DRIVER
@@ -1098,7 +1111,9 @@ clean0:
 #ifdef DEBUG
        debugfs_remove(ehci_debug_root);
        ehci_debug_root = NULL;
+err_debug:
 #endif
+       clear_bit(USB_EHCI_LOADED, &usb_hcds_loaded);
        return retval;
 }
 module_init(ehci_hcd_init);
@@ -1120,6 +1135,7 @@ static void __exit ehci_hcd_cleanup(void)
 #ifdef DEBUG
        debugfs_remove(ehci_debug_root);
 #endif
+       clear_bit(USB_EHCI_LOADED, &usb_hcds_loaded);
 }
 module_exit(ehci_hcd_cleanup);