This commit was manufactured by cvs2svn to create tag
[linux-2.6.git] / drivers / usb / host / ehci-hcd.c
index c5bffd2..8670864 100644 (file)
@@ -97,7 +97,7 @@
  * 2001-June   Works with usb-storage and NEC EHCI on 2.4
  */
 
-#define DRIVER_VERSION "26 Oct 2004"
+#define DRIVER_VERSION "2004-May-10"
 #define DRIVER_AUTHOR "David Brownell"
 #define DRIVER_DESC "USB 2.0 'Enhanced' Host Controller (EHCI) Driver"
 
@@ -155,7 +155,7 @@ MODULE_PARM_DESC (log2_irq_thresh, "log2 IRQ latency, 1-64 microframes");
  * before driver shutdown. But it also seems to be caused by bugs in cardbus
  * bridge shutdown:  shutting down the bridge before the devices using it.
  */
-static int handshake (void __iomem *ptr, u32 mask, u32 done, int usec)
+static int handshake (u32 __iomem *ptr, u32 mask, u32 done, int usec)
 {
        u32     result;
 
@@ -172,6 +172,13 @@ static int handshake (void __iomem *ptr, u32 mask, u32 done, int usec)
        return -ETIMEDOUT;
 }
 
+/*
+ * hc states include: unknown, halted, ready, running
+ * transitional states are messy just now
+ * trying to avoid "running" unless urbs are active
+ * a "ready" hc can be finishing prefetched work
+ */
+
 /* force HC to halt state from unknown (EHCI spec section 2.3) */
 static int ehci_halt (struct ehci_hcd *ehci)
 {
@@ -200,7 +207,7 @@ static int ehci_reset (struct ehci_hcd *ehci)
 }
 
 /* idle the controller (from running) */
-static void ehci_quiesce (struct ehci_hcd *ehci)
+static void ehci_ready (struct ehci_hcd *ehci)
 {
        u32     temp;
 
@@ -210,8 +217,11 @@ static void ehci_quiesce (struct ehci_hcd *ehci)
 #endif
 
        /* wait for any schedule enables/disables to take effect */
-       temp = readl (&ehci->regs->command) << 10;
-       temp &= STS_ASS | STS_PSS;
+       temp = 0;
+       if (ehci->async->qh_next.qh)
+               temp = STS_ASS;
+       if (ehci->next_uframe != -1)
+               temp |= STS_PSS;
        if (handshake (&ehci->regs->status, STS_ASS | STS_PSS,
                                temp, 16 * 125) != 0) {
                ehci->hcd.state = USB_STATE_HALT;
@@ -331,25 +341,17 @@ static int ehci_hc_reset (struct usb_hcd *hcd)
        spin_lock_init (&ehci->lock);
 
        ehci->caps = hcd->regs;
-       ehci->regs = hcd->regs + HC_LENGTH (readl (&ehci->caps->hc_capbase));
+       ehci->regs = (hcd->regs + 
+                               HC_LENGTH (readl (&ehci->caps->hc_capbase)));
        dbg_hcs_params (ehci, "reset");
        dbg_hcc_params (ehci, "reset");
 
 #ifdef CONFIG_PCI
        writel(0, &ehci->regs->intr_enable);
        /* EHCI 0.96 and later may have "extended capabilities" */
-       if (hcd->self.controller->bus == &pci_bus_type) {
-               struct pci_dev  *pdev = to_pci_dev(ehci->hcd.self.controller);
-
-               /* AMD8111 EHCI doesn't work, according to AMD errata */
-               if ((pdev->vendor == PCI_VENDOR_ID_AMD)
-                               && (pdev->device == 0x7463)) {
-                       ehci_info (ehci, "ignoring AMD8111 (errata)\n");
-                       return -EIO;
-               }
-
+       if (hcd->self.controller->bus == &pci_bus_type)
                temp = HCC_EXT_CAPS (readl (&ehci->caps->hcc_params));
-       else
+       else
                temp = 0;
        while (temp && count--) {
                u32             cap;
@@ -362,6 +364,10 @@ static int ehci_hc_reset (struct usb_hcd *hcd)
                        if (bios_handoff (ehci, temp, cap) != 0)
                                return -EOPNOTSUPP;
                        break;
+               case 0x0a:              /* appendix C */
+                       ehci_dbg (ehci, "debug registers, BAR %d offset %d\n",
+                               (cap >> 29) & 0x07, (cap >> 16) & 0x0fff);
+                       break;
                case 0:                 /* illegal reserved capability */
                        ehci_warn (ehci, "illegal capability!\n");
                        cap = 0;
@@ -380,14 +386,6 @@ static int ehci_hc_reset (struct usb_hcd *hcd)
        /* cache this readonly data; minimize PCI reads */
        ehci->hcs_params = readl (&ehci->caps->hcs_params);
 
-       /* at least the Genesys GL880S needs fixup here */
-       temp = HCS_N_CC(ehci->hcs_params) * HCS_N_PCC(ehci->hcs_params);
-       temp &= 0x0f;
-       if (temp && HCS_N_PORTS(ehci->hcs_params) > temp) {
-               temp |= (ehci->hcs_params & ~0xf);
-               ehci->hcs_params = temp;
-       }
-
        /* force HC to halt state */
        return ehci_halt (ehci);
 }
@@ -401,22 +399,17 @@ static int ehci_start (struct usb_hcd *hcd)
        int                     retval;
        u32                     hcc_params;
        u8                      sbrn = 0;
-       int                     first;
-
-       /* skip some things on restart paths */
-       first = (ehci->watchdog.data == 0);
-       if (first) {
-               init_timer (&ehci->watchdog);
-               ehci->watchdog.function = ehci_watchdog;
-               ehci->watchdog.data = (unsigned long) ehci;
-       }
+
+       init_timer (&ehci->watchdog);
+       ehci->watchdog.function = ehci_watchdog;
+       ehci->watchdog.data = (unsigned long) ehci;
 
        /*
         * hw default: 1K periodic list heads, one per frame.
         * periodic_size can shrink by USBCMD update if hcc_params allows.
         */
        ehci->periodic_size = DEFAULT_I_TDPS;
-       if (first && (retval = ehci_mem_init (ehci, GFP_KERNEL)) < 0)
+       if ((retval = ehci_mem_init (ehci, GFP_KERNEL)) < 0)
                return retval;
 
        /* controllers may cache some of the periodic schedule ... */
@@ -427,7 +420,6 @@ static int ehci_start (struct usb_hcd *hcd)
                ehci->i_thresh = 2 + HCC_ISOC_THRES (hcc_params);
 
        ehci->reclaim = NULL;
-       ehci->reclaim_ready = 0;
        ehci->next_uframe = -1;
 
        /* controller state:  unknown --> reset */
@@ -474,15 +466,13 @@ static int ehci_start (struct usb_hcd *hcd)
         * its dummy is used in hw_alt_next of many tds, to prevent the qh
         * from automatically advancing to the next td after short reads.
         */
-       if (first) {
-               ehci->async->qh_next.qh = NULL;
-               ehci->async->hw_next = QH_NEXT (ehci->async->qh_dma);
-               ehci->async->hw_info1 = cpu_to_le32 (QH_HEAD);
-               ehci->async->hw_token = cpu_to_le32 (QTD_STS_HALT);
-               ehci->async->hw_qtd_next = EHCI_LIST_END;
-               ehci->async->qh_state = QH_STATE_LINKED;
-               ehci->async->hw_alt_next = QTD_NEXT (ehci->async->dummy->qtd_dma);
-       }
+       ehci->async->qh_next.qh = NULL;
+       ehci->async->hw_next = QH_NEXT (ehci->async->qh_dma);
+       ehci->async->hw_info1 = cpu_to_le32 (QH_HEAD);
+       ehci->async->hw_token = cpu_to_le32 (QTD_STS_HALT);
+       ehci->async->hw_qtd_next = EHCI_LIST_END;
+       ehci->async->qh_state = QH_STATE_LINKED;
+       ehci->async->hw_alt_next = QTD_NEXT (ehci->async->dummy->qtd_dma);
        writel ((u32)ehci->async->qh_dma, &ehci->regs->async_next);
 
        /*
@@ -534,14 +524,12 @@ static int ehci_start (struct usb_hcd *hcd)
 
        /* wire up the root hub */
        bus = hcd_to_bus (hcd);
-       udev = first ? usb_alloc_dev (NULL, bus, 0) : bus->root_hub;
+       udev = usb_alloc_dev (NULL, bus, 0);
        if (!udev) {
 done2:
                ehci_mem_cleanup (ehci);
                return -ENOMEM;
        }
-       udev->speed = USB_SPEED_HIGH;
-       udev->state = first ? USB_STATE_ATTACHED : USB_STATE_CONFIGURED;
 
        /*
         * Start, enabling full USB 2.0 functionality ... usb 1.1 devices
@@ -549,10 +537,8 @@ done2:
         * involved with the root hub.  (Except where one is integrated,
         * and there's no companion controller unless maybe for USB OTG.)
         */
-       if (first) {
-               ehci->reboot_notifier.notifier_call = ehci_reboot;
-               register_reboot_notifier (&ehci->reboot_notifier);
-       }
+       ehci->reboot_notifier.notifier_call = ehci_reboot;
+       register_reboot_notifier (&ehci->reboot_notifier);
 
        ehci->hcd.state = USB_STATE_RUNNING;
        writel (FLAG_CF, &ehci->regs->configured_flag);
@@ -560,23 +546,21 @@ done2:
 
        temp = HC_VERSION(readl (&ehci->caps->hc_capbase));
        ehci_info (ehci,
-               "USB %x.%x %s, EHCI %x.%02x, driver %s\n",
+               "USB %x.%x enabled, EHCI %x.%02x, driver %s\n",
                ((sbrn & 0xf0)>>4), (sbrn & 0x0f),
-               first ? "initialized" : "restarted",
                temp >> 8, temp & 0xff, DRIVER_VERSION);
 
        /*
         * From here on, khubd concurrently accesses the root
         * hub; drivers will be talking to enumerated devices.
-        * (On restart paths, khubd already knows about the root
-        * hub and could find work as soon as we wrote FLAG_CF.)
         *
         * Before this point the HC was idle/ready.  After, khubd
         * and device drivers may start it running.
         */
-       if (first && hcd_register_root (udev, hcd) != 0) {
+       udev->speed = USB_SPEED_HIGH;
+       if (hcd_register_root (udev, hcd) != 0) {
                if (hcd->state == USB_STATE_RUNNING)
-                       ehci_quiesce (ehci);
+                       ehci_ready (ehci);
                ehci_reset (ehci);
                usb_put_dev (udev); 
                retval = -ENODEV;
@@ -585,8 +569,7 @@ done2:
 
        writel (INTR_MASK, &ehci->regs->intr_enable); /* Turn On Interrupts */
 
-       if (first)
-               create_debug_files (ehci);
+       create_debug_files (ehci);
 
        return 0;
 }
@@ -600,23 +583,24 @@ static void ehci_stop (struct usb_hcd *hcd)
 
        ehci_dbg (ehci, "stop\n");
 
-       /* Turn off port power on all root hub ports. */
-       rh_ports = HCS_N_PORTS (ehci->hcs_params);
-       for (port = 1; port <= rh_ports; port++)
-               (void) ehci_hub_control(hcd,
-                       ClearPortFeature, USB_PORT_FEAT_POWER,
-                       port, NULL, 0);
-
        /* no more interrupts ... */
+       if (hcd->state == USB_STATE_RUNNING)
+               ehci_ready (ehci);
+       if (in_interrupt ()) {          /* must not happen!! */
+               ehci_err (ehci, "stopped in_interrupt!\n");
+               return;
+       }
        del_timer_sync (&ehci->watchdog);
 
-       spin_lock_irq(&ehci->lock);
-       if (HCD_IS_RUNNING (ehci->hcd.state))
-               ehci_quiesce (ehci);
+       /* Turn off port power on all root hub ports. */
+       rh_ports = HCS_N_PORTS (ehci->hcs_params);
+       for (port = 1; port <= rh_ports; port++) {
+               ehci_hub_control(hcd, ClearPortFeature, USB_PORT_FEAT_POWER,
+                       port, NULL, 0);
+       }
 
        ehci_reset (ehci);
        writel (0, &ehci->regs->intr_enable);
-       spin_unlock_irq(&ehci->lock);
 
        /* let companion controllers work when we aren't */
        writel (0, &ehci->regs->configured_flag);
@@ -654,8 +638,7 @@ static int ehci_get_frame (struct usb_hcd *hcd)
 
 /* suspend/resume, section 4.3 */
 
-/* These routines rely on the bus (pci, platform, etc)
- * to handle powerdown and wakeup, and currently also on
+/* These routines rely on PCI to handle powerdown and wakeup, and
  * transceivers that don't need any software attention to set up
  * the right sort of wakeup.  
  */
@@ -664,19 +647,17 @@ static int ehci_suspend (struct usb_hcd *hcd, u32 state)
 {
        struct ehci_hcd         *ehci = hcd_to_ehci (hcd);
 
-       if (time_before (jiffies, ehci->next_statechange))
+       while (time_before (jiffies, ehci->next_statechange))
                msleep (100);
 
 #ifdef CONFIG_USB_SUSPEND
        (void) usb_suspend_device (hcd->self.root_hub, state);
 #else
-       usb_lock_device (hcd->self.root_hub);
+       /* FIXME lock root hub */
        (void) ehci_hub_suspend (hcd);
-       usb_unlock_device (hcd->self.root_hub);
 #endif
 
        // save (PCI) FLADJ in case of Vaux power loss
-       // ... we'd only use it to handle clock skew
 
        return 0;
 }
@@ -684,67 +665,21 @@ static int ehci_suspend (struct usb_hcd *hcd, u32 state)
 static int ehci_resume (struct usb_hcd *hcd)
 {
        struct ehci_hcd         *ehci = hcd_to_ehci (hcd);
-       unsigned                port;
-       struct usb_device       *root = hcd->self.root_hub;
-       int                     retval = -EINVAL;
-       int                     powerup = 0;
+       int                     retval;
 
        // maybe restore (PCI) FLADJ
 
-       if (time_before (jiffies, ehci->next_statechange))
+       while (time_before (jiffies, ehci->next_statechange))
                msleep (100);
 
-       /* If any port is suspended, we know we can/must resume the HC. */
-       for (port = HCS_N_PORTS (ehci->hcs_params); port > 0; ) {
-               u32     status;
-               port--;
-               status = readl (&ehci->regs->port_status [port]);
-               if (status & PORT_SUSPEND) {
-                       down (&hcd->self.root_hub->serialize);
-                       retval = ehci_hub_resume (hcd);
-                       up (&hcd->self.root_hub->serialize);
-                       break;
-               }
-               if ((status & PORT_POWER) == 0)
-                       powerup = 1;
-               if (!root->children [port])
-                       continue;
-               dbg_port (ehci, __FUNCTION__, port + 1, status);
-               usb_set_device_state (root->children[port],
-                                       USB_STATE_NOTATTACHED);
-       }
-
-       /* Else reset, to cope with power loss or flush-to-storage
-        * style "resume" having activated BIOS during reboot.
-        */
-       if (port == 0) {
-               (void) ehci_halt (ehci);
-               (void) ehci_reset (ehci);
-               (void) ehci_hc_reset (hcd);
-
-               /* emptying the schedule aborts any urbs */
-               spin_lock_irq (&ehci->lock);
-               if (ehci->reclaim)
-                       ehci->reclaim_ready = 1;
-               ehci_work (ehci, NULL);
-               spin_unlock_irq (&ehci->lock);
-
-               /* restart; khubd will disconnect devices */
-               retval = ehci_start (hcd);
-
-               /* here we "know" root ports should always stay powered;
-                * but some controllers may lost all power.
-                */
-               if (powerup) {
-                       ehci_dbg (ehci, "...powerup ports...\n");
-                       for (port = HCS_N_PORTS (ehci->hcs_params); port > 0; )
-                               (void) ehci_hub_control(hcd,
-                                       SetPortFeature, USB_PORT_FEAT_POWER,
-                                               port--, NULL, 0);
-                       msleep(20);
-               }
-       }
-
+#ifdef CONFIG_USB_SUSPEND
+       retval = usb_resume_device (hcd->self.root_hub);
+#else
+       /* FIXME lock root hub */
+       retval = ehci_hub_resume (hcd);
+#endif
+       if (retval == 0)
+               hcd->self.controller->power.power_state = 0;
        return retval;
 }
 
@@ -778,8 +713,7 @@ static void ehci_work (struct ehci_hcd *ehci, struct pt_regs *regs)
         * misplace IRQs, and should let us run completely without IRQs.
         * such lossage has been observed on both VT6202 and VT8235. 
         */
-       if (HCD_IS_RUNNING (ehci->hcd.state) && (ehci->async->qh_next.ptr != 0
-                       || ehci->periodic_sched != 0))
+       if ((ehci->async->qh_next.ptr != 0) || (ehci->periodic_sched != 0))
                timer_action (ehci, TIMER_IO_WATCHDOG);
 }
 
@@ -925,30 +859,6 @@ static int ehci_urb_enqueue (
        }
 }
 
-static void unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh)
-{
-       /* if we need to use IAA and it's busy, defer */
-       if (qh->qh_state == QH_STATE_LINKED
-                       && ehci->reclaim
-                       && HCD_IS_RUNNING (ehci->hcd.state)) {
-               struct ehci_qh          *last;
-
-               for (last = ehci->reclaim;
-                               last->reclaim;
-                               last = last->reclaim)
-                       continue;
-               qh->qh_state = QH_STATE_UNLINK_WAIT;
-               last->reclaim = qh;
-
-       /* bypass IAA if the hc can't care */
-       } else if (!HCD_IS_RUNNING (ehci->hcd.state) && ehci->reclaim)
-               end_unlink_async (ehci, NULL);
-
-       /* something else might have unlinked the qh by now */
-       if (qh->qh_state == QH_STATE_LINKED)
-               start_unlink_async (ehci, qh);
-}
-
 /* remove from hardware lists
  * completions normally happen asynchronously
  */
@@ -967,7 +877,28 @@ static int ehci_urb_dequeue (struct usb_hcd *hcd, struct urb *urb)
                qh = (struct ehci_qh *) urb->hcpriv;
                if (!qh)
                        break;
-               unlink_async (ehci, qh);
+
+               /* if we need to use IAA and it's busy, defer */
+               if (qh->qh_state == QH_STATE_LINKED
+                               && ehci->reclaim
+                               && HCD_IS_RUNNING (ehci->hcd.state)
+                               ) {
+                       struct ehci_qh          *last;
+
+                       for (last = ehci->reclaim;
+                                       last->reclaim;
+                                       last = last->reclaim)
+                               continue;
+                       qh->qh_state = QH_STATE_UNLINK_WAIT;
+                       last->reclaim = qh;
+
+               /* bypass IAA if the hc can't care */
+               } else if (!HCD_IS_RUNNING (ehci->hcd.state) && ehci->reclaim)
+                       end_unlink_async (ehci, NULL);
+
+               /* something else might have unlinked the qh by now */
+               if (qh->qh_state == QH_STATE_LINKED)
+                       start_unlink_async (ehci, qh);
                break;
 
        case PIPE_INTERRUPT:
@@ -1020,7 +951,7 @@ ehci_endpoint_disable (struct usb_hcd *hcd, struct hcd_dev *dev, int ep)
        struct ehci_hcd         *ehci = hcd_to_ehci (hcd);
        int                     epnum;
        unsigned long           flags;
-       struct ehci_qh          *qh, *tmp;
+       struct ehci_qh          *qh;
 
        /* ASSERT:  any requests/urbs are being unlinked */
        /* ASSERT:  nobody can be submitting urbs for this any more */
@@ -1046,16 +977,6 @@ rescan:
        if (!HCD_IS_RUNNING (ehci->hcd.state))
                qh->qh_state = QH_STATE_IDLE;
        switch (qh->qh_state) {
-       case QH_STATE_LINKED:
-               for (tmp = ehci->async->qh_next.qh;
-                               tmp && tmp != qh;
-                               tmp = tmp->qh_next.qh)
-                       continue;
-               /* periodic qh self-unlinks on empty */
-               if (!tmp)
-                       goto nogood;
-               unlink_async (ehci, qh);
-               /* FALL THROUGH */
        case QH_STATE_UNLINK:           /* wait for hw to finish? */
 idle_timeout:
                spin_unlock_irqrestore (&ehci->lock, flags);
@@ -1069,7 +990,6 @@ idle_timeout:
                }
                /* else FALL THROUGH */
        default:
-nogood:
                /* caller was supposed to have unlinked any requests;
                 * that's not our job.  just leak this memory.
                 */
@@ -1110,6 +1030,7 @@ static const struct hc_driver ehci_driver = {
         * memory lifecycle (except per-request)
         */
        .hcd_alloc =            ehci_hcd_alloc,
+       .hcd_free =             ehci_hcd_free,
 
        /*
         * managing i/o requests and associated device resources
@@ -1181,7 +1102,7 @@ static int __init init (void)
                sizeof (struct ehci_qh), sizeof (struct ehci_qtd),
                sizeof (struct ehci_itd), sizeof (struct ehci_sitd));
 
-       return pci_register_driver (&ehci_pci_driver);
+       return pci_module_init (&ehci_pci_driver);
 }
 module_init (init);