X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fusb%2Fhost%2Fohci-hcd.c;h=d13e98e35e0b47698143c3ae4a931cb76cba6457;hb=9bf4aaab3e101692164d49b7ca357651eb691cb6;hp=b5279a019169d0d8569a355b4dd512713fe0101a;hpb=db216c3d5e4c040e557a50f8f5d35d5c415e8c1c;p=linux-2.6.git diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index b5279a019..d13e98e35 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c @@ -17,6 +17,7 @@ * * History: * + * 2004/03/24 LH7A404 support (Durgesh Pattamatta & Marc Singer) * 2004/02/04 use generic dma_* functions instead of pci_* (dsaxena@plexity.net) * 2003/02/24 show registers in sysfs (Kevin Brosius) * @@ -228,7 +229,7 @@ static int ohci_urb_enqueue ( if (urb->status != -EINPROGRESS) { spin_unlock (&urb->lock); urb->hcpriv = urb_priv; - finish_urb (ohci, urb, 0); + finish_urb (ohci, urb, NULL); retval = 0; goto fail; } @@ -339,14 +340,18 @@ rescan: goto done; if (!HCD_IS_RUNNING (ohci->hcd.state)) { +sanitize: ed->state = ED_IDLE; - finish_unlinks (ohci, 0, 0); + finish_unlinks (ohci, 0, NULL); } switch (ed->state) { case ED_UNLINK: /* wait for hw to finish? */ /* major IRQ delivery trouble loses INTR_SF too... */ - WARN_ON (limit-- == 0); + if (limit-- == 0) { + ohci_warn (ohci, "IRQ INTR_SF lossage\n"); + goto sanitize; + } spin_unlock_irqrestore (&ohci->lock, flags); set_current_state (TASK_UNINTERRUPTIBLE); schedule_timeout (1); @@ -368,7 +373,7 @@ rescan: td_free (ohci, ed->dummy); break; } - dev->ep [epnum] = 0; + dev->ep [epnum] = NULL; done: spin_unlock_irqrestore (&ohci->lock, flags); return; @@ -393,7 +398,7 @@ static int hc_reset (struct ohci_hcd *ohci) /* boot firmware should have set this up (5.1.1.3.1) */ if (!ohci->fminterval) { - temp = readl (&ohci->regs->fminterval); + temp = ohci_readl (&ohci->regs->fminterval); if (temp & 0x3fff0000) ohci->fminterval = temp; else @@ -405,7 +410,7 @@ static int hc_reset (struct ohci_hcd *ohci) * On PA-RISC, PDC can leave IR set incorrectly; ignore it there. */ #ifndef __hppa__ - if (readl (&ohci->regs->control) & OHCI_CTRL_IR) { + if (ohci_readl (&ohci->regs->control) & OHCI_CTRL_IR) { ohci_dbg (ohci, "USB HC TakeOver from BIOS/SMM\n"); /* this timeout is arbitrary. we make it long, so systems @@ -416,7 +421,7 @@ static int hc_reset (struct ohci_hcd *ohci) writel (OHCI_INTR_OC, &ohci->regs->intrenable); writel (OHCI_OCR, &ohci->regs->cmdstatus); - while (readl (&ohci->regs->control) & OHCI_CTRL_IR) { + while (ohci_readl (&ohci->regs->control) & OHCI_CTRL_IR) { msleep (10); if (--temp == 0) { ohci_err (ohci, "USB HC TakeOver failed!\n"); @@ -430,13 +435,13 @@ static int hc_reset (struct ohci_hcd *ohci) writel (OHCI_INTR_MIE, &ohci->regs->intrdisable); ohci_dbg (ohci, "reset, control = 0x%x\n", - readl (&ohci->regs->control)); + ohci_readl (&ohci->regs->control)); /* Reset USB (needed by some controllers); RemoteWakeupConnected * saved if boot firmware (BIOS/SMM/...) told us it's connected * (for OHCI integrated on mainboard, it normally is) */ - ohci->hc_control = readl (&ohci->regs->control); + ohci->hc_control = ohci_readl (&ohci->regs->control); ohci->hc_control &= OHCI_CTRL_RWC; /* hcfs 0 = RESET */ if (ohci->hc_control) ohci->hcd.can_wakeup = 1; @@ -450,13 +455,13 @@ static int hc_reset (struct ohci_hcd *ohci) &ohci->regs->roothub.portstatus [temp]); } // flush those pci writes - (void) readl (&ohci->regs->control); + (void) ohci_readl (&ohci->regs->control); msleep (50); /* HC Reset requires max 10 us delay */ writel (OHCI_HCR, &ohci->regs->cmdstatus); temp = 30; /* ... allow extra time */ - while ((readl (&ohci->regs->cmdstatus) & OHCI_HCR) != 0) { + while ((ohci_readl (&ohci->regs->cmdstatus) & OHCI_HCR) != 0) { if (--temp == 0) { ohci_err (ohci, "USB HC reset timed out!\n"); return -1; @@ -473,7 +478,7 @@ static int hc_reset (struct ohci_hcd *ohci) */ writel (ohci->hc_control, &ohci->regs->control); // flush those pci writes - (void) readl (&ohci->regs->control); + (void) ohci_readl (&ohci->regs->control); return 0; } @@ -505,8 +510,8 @@ static int hc_start (struct ohci_hcd *ohci) /* some OHCI implementations are finicky about how they init. * bogus values here mean not even enumeration could work. */ - if ((readl (&ohci->regs->fminterval) & 0x3fff0000) == 0 - || !readl (&ohci->regs->periodicstart)) { + if ((ohci_readl (&ohci->regs->fminterval) & 0x3fff0000) == 0 + || !ohci_readl (&ohci->regs->periodicstart)) { ohci_err (ohci, "init err\n"); return -EOVERFLOW; } @@ -548,7 +553,7 @@ static int hc_start (struct ohci_hcd *ohci) writel (RH_HS_LPSC, &ohci->regs->roothub.status); writel (power_switching ? RH_B_PPCM : 0, &ohci->regs->roothub.b); // flush those pci writes - (void) readl (&ohci->regs->control); + (void) ohci_readl (&ohci->regs->control); // POTPGT delay is bits 24-31, in 2 ms units. mdelay ((roothub_a (ohci) >> 23) & 0x1fe); @@ -560,7 +565,7 @@ static int hc_start (struct ohci_hcd *ohci) } /* connect the virtual root hub */ - bus->root_hub = udev = usb_alloc_dev (NULL, bus, 0); + udev = usb_alloc_dev (NULL, bus, 0); ohci->hcd.state = USB_STATE_RUNNING; if (!udev) { disable (ohci); @@ -570,9 +575,8 @@ static int hc_start (struct ohci_hcd *ohci) } udev->speed = USB_SPEED_FULL; - if (hcd_register_root (&ohci->hcd) != 0) { + if (hcd_register_root (udev, &ohci->hcd) != 0) { usb_put_dev (udev); - bus->root_hub = NULL; disable (ohci); ohci->hc_control &= ~OHCI_CTRL_HCFS; writel (ohci->hc_control, &ohci->regs->control); @@ -592,19 +596,20 @@ static irqreturn_t ohci_irq (struct usb_hcd *hcd, struct pt_regs *ptregs) struct ohci_regs *regs = ohci->regs; int ints; - /* we can eliminate a (slow) readl() if _only_ WDH caused this irq */ + /* we can eliminate a (slow) ohci_readl() + if _only_ WDH caused this irq */ if ((ohci->hcca->done_head != 0) && ! (le32_to_cpup (&ohci->hcca->done_head) & 0x01)) { ints = OHCI_INTR_WDH; /* cardbus/... hardware gone before remove() */ - } else if ((ints = readl (®s->intrstatus)) == ~(u32)0) { + } else if ((ints = ohci_readl (®s->intrstatus)) == ~(u32)0) { disable (ohci); ohci_dbg (ohci, "device removed!\n"); return IRQ_HANDLED; /* interrupt for some other device? */ - } else if ((ints &= readl (®s->intrenable)) == 0) { + } else if ((ints &= ohci_readl (®s->intrenable)) == 0) { return IRQ_NONE; } @@ -650,7 +655,7 @@ static irqreturn_t ohci_irq (struct usb_hcd *hcd, struct pt_regs *ptregs) writel (ints, ®s->intrstatus); writel (OHCI_INTR_MIE, ®s->intrenable); // flush those pci writes - (void) readl (&ohci->regs->control); + (void) ohci_readl (&ohci->regs->control); } return IRQ_HANDLED; @@ -670,6 +675,8 @@ static void ohci_stop (struct usb_hcd *hcd) flush_scheduled_work(); if (HCD_IS_RUNNING(ohci->hcd.state)) hc_reset (ohci); + else + writel (OHCI_INTR_MIE, &ohci->regs->intrdisable); remove_debug_files (ohci); ohci_mem_cleanup (ohci); @@ -727,7 +734,7 @@ static int hc_restart (struct ohci_hcd *ohci) ed_deschedule (ohci, ed); ed->ed_next = ohci->ed_rm_list; - ed->ed_prev = 0; + ed->ed_prev = NULL; ohci->ed_rm_list = ed; /* FALLTHROUGH */ case ED_UNLINK: @@ -741,7 +748,7 @@ static int hc_restart (struct ohci_hcd *ohci) urb->status = -ESHUTDOWN; spin_unlock (&urb->lock); } - finish_unlinks (ohci, 0, 0); + finish_unlinks (ohci, 0, NULL); spin_unlock_irq(&ohci->lock); /* paranoia, in case that didn't work: */ @@ -798,6 +805,14 @@ MODULE_LICENSE ("GPL"); #include "ohci-omap.c" #endif -#if !(defined(CONFIG_PCI) || defined(CONFIG_SA1111) || defined(CONFIG_ARCH_OMAP)) +#ifdef CONFIG_ARCH_LH7A404 +#include "ohci-lh7a404.c" +#endif + +#if !(defined(CONFIG_PCI) \ + || defined(CONFIG_SA1111) \ + || defined(CONFIG_ARCH_OMAP) \ + || defined (CONFIG_ARCH_LH7A404) \ + ) #error "missing bus glue for ohci-hcd" #endif