static int ehci_msm_reset(struct usb_hcd *hcd) { struct ehci_hcd *ehci = hcd_to_ehci(hcd); int retval; ehci->caps = USB_CAPLENGTH; hcd->has_tt = 1; ehci->no_testmode_suspend = true; retval = ehci_setup(hcd); if (retval) return retval; /* bursts of unspecified length. */ writel_relaxed(0, USB_AHBBURST); /* Use the AHB transactor */ writel_relaxed(0x08, USB_AHBMODE); /* Disable streaming mode and select host mode */ writel_relaxed(0x13, USB_USBMODE); if (hcd->phy->flags & ENABLE_SECONDARY_PHY) { ehci_dbg(ehci, "using secondary hsphy\n"); writel_relaxed(readl_relaxed(USB_PHY_CTRL2) | (1<<16), USB_PHY_CTRL2); } /* Disable ULPI_TX_PKT_EN_CLR_FIX which is valid only for HSIC */ writel_relaxed(readl_relaxed(USB_GENCONFIG2) & ~(1<<19), USB_GENCONFIG2); return 0; }
static struct ehci_qh *ehci_qh_alloc (struct ehci_hcd *ehci, int flags) { struct ehci_qh *qh; //dma_addr_t dma; void* real; real = kmalloc( sizeof( struct ehci_qh ) + 32, MEMF_KERNEL | MEMF_CLEAR ); qh = ( struct ehci_qh* )( ( (uint32)real + 32 ) & ~31 ); #if 0 qh = (struct ehci_qh *) pci_pool_alloc (ehci->qh_pool, flags, &dma); #endif if (!real) return real; memset (qh, 0, sizeof *qh); atomic_set(&qh->refcount, 1); qh->qh_real = real; // INIT_LIST_HEAD (&qh->qh_list); INIT_LIST_HEAD (&qh->qtd_list); /* dummy td enables safe urb queuing */ qh->dummy = ehci_qtd_alloc (ehci, flags); if (qh->dummy == 0) { ehci_dbg (ehci, "no dummy td\n"); kfree( qh->qh_real ); // pci_pool_free (ehci->qh_pool, qh, qh->qh_dma); qh = 0; } return qh; }
static int __maybe_unused ehci_lpm_set_da(struct ehci_hcd *ehci, int dev_addr, int port_num) { u32 __iomem portsc; ehci_dbg(ehci, "set dev address %d for port %d\n", dev_addr, port_num); if (port_num > HCS_N_PORTS(ehci->hcs_params)) { ehci_dbg(ehci, "invalid port number %d\n", port_num); return -ENODEV; } portsc = ehci_readl(ehci, &ehci->regs->port_status[port_num-1]); portsc &= ~PORT_DEV_ADDR; portsc |= dev_addr<<25; ehci_writel(ehci, portsc, &ehci->regs->port_status[port_num-1]); return 0; }
static irqreturn_t tegra_ehci_irq(struct usb_hcd *hcd) { struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller); struct ehci_hcd *ehci = hcd_to_ehci(hcd); irqreturn_t irq_status; spin_lock(&ehci->lock); irq_status = tegra_usb_phy_irq(tegra->phy); if (irq_status == IRQ_NONE) { spin_unlock(&ehci->lock); return irq_status; } if (tegra_usb_phy_pmc_wakeup(tegra->phy)) { ehci_dbg(ehci, "pmc interrupt detected\n"); wake_lock_timeout(&tegra->ehci_wake_lock, HZ); usb_hcd_resume_root_hub(hcd); spin_unlock(&ehci->lock); return irq_status; } spin_unlock(&ehci->lock); EHCI_DBG("%s() cmd = 0x%x, int_sts = 0x%x, portsc = 0x%x\n", __func__, ehci_readl(ehci, &ehci->regs->command), ehci_readl(ehci, &ehci->regs->status), ehci_readl(ehci, &ehci->regs->port_status[0])); irq_status = ehci_irq(hcd); if (ehci->controller_remote_wakeup) { ehci->controller_remote_wakeup = false; tegra_usb_phy_pre_resume(tegra->phy, true); tegra->port_resuming = 1; } return irq_status; }
static struct ehci_qh *ehci_qh_alloc (struct ehci_hcd *ehci, gfp_t flags) { struct ehci_qh *qh; dma_addr_t dma; qh = (struct ehci_qh *) dma_pool_alloc (ehci->qh_pool, flags, &dma); if (!qh) return qh; memset (qh, 0, sizeof *qh); qh->refcount = 1; qh->ehci = ehci; qh->qh_dma = dma; // INIT_LIST_HEAD (&qh->qh_list); INIT_LIST_HEAD (&qh->qtd_list); /* dummy td enables safe urb queuing */ qh->dummy = ehci_qtd_alloc (ehci, flags); if (qh->dummy == NULL) { ehci_dbg (ehci, "no dummy td\n"); dma_pool_free (ehci->qh_pool, qh, qh->qh_dma); qh = NULL; } return qh; }
/* EHCI 0.96 (and later) section 5.1 says how to kick BIOS/SMM/... * off the controller (maybe it can boot from highspeed USB disks). */ static int bios_handoff (struct ehci_hcd *ehci, int where, u32 cap) { if (cap & (1 << 16)) { int msec = 5000; struct pci_dev *pdev = to_pci_dev(ehci_to_hcd(ehci)->self.controller); /* request handoff to OS */ cap |= 1 << 24; pci_write_config_dword(pdev, where, cap); /* and wait a while for it to happen */ do { msleep(10); msec -= 10; pci_read_config_dword(pdev, where, &cap); } while ((cap & (1 << 16)) && msec); if (cap & (1 << 16)) { ehci_err (ehci, "BIOS handoff failed (%d, %04x)\n", where, cap); // some BIOS versions seem buggy... // return 1; ehci_warn (ehci, "continuing after BIOS bug...\n"); return 0; } ehci_dbg (ehci, "BIOS handoff succeeded\n"); } return 0; }
static struct ehci_qh *ehci_qh_alloc(struct ehci_hcd *ehci, gfp_t flags) { struct ehci_qh *qh; dma_addr_t dma; dma = usb_malloc(sizeof(struct ehci_qh), flags); if (dma != 0) qh = (struct ehci_qh *)IO_ADDRESS(dma); else qh = (struct ehci_qh *) dma_pool_alloc(ehci->qh_pool, flags, &dma); ++g_debug_qH_allocated; if (qh == NULL) { panic("run out of i-ram for qH allocation\n"); return qh; } memset(qh, 0, sizeof *qh); qh->refcount = 1; qh->ehci = ehci; qh->qh_dma = dma; INIT_LIST_HEAD(&qh->qtd_list); /* dummy td enables safe urb queuing */ qh->dummy = ehci_qtd_alloc(ehci, flags); if (qh->dummy == NULL) { ehci_dbg(ehci, "no dummy td\n"); dma_pool_free(ehci->qh_pool, qh, qh->qh_dma); qh = NULL; } return qh; }
/* EHCI 0.96 (and later) section 5.1 says how to kick BIOS/SMM/... * off the controller (maybe it can boot from highspeed USB disks). */ static int bios_handoff (struct ehci_hcd *ehci, int where, u32 cap) { struct pci_dev *pdev = to_pci_dev(ehci_to_hcd(ehci)->self.controller); /* always say Linux will own the hardware */ pci_write_config_byte(pdev, where + 3, 1); /* maybe wait a while for BIOS to respond */ if (cap & (1 << 16)) { int msec = 5000; do { msleep(10); msec -= 10; pci_read_config_dword(pdev, where, &cap); } while ((cap & (1 << 16)) && msec); if (cap & (1 << 16)) { ehci_err(ehci, "BIOS handoff failed (%d, %08x)\n", where, cap); // some BIOS versions seem buggy... // return 1; ehci_warn (ehci, "continuing after BIOS bug...\n"); /* disable all SMIs, and clear "BIOS owns" flag */ pci_write_config_dword(pdev, where + 4, 0); pci_write_config_byte(pdev, where + 2, 0); } else ehci_dbg(ehci, "BIOS handoff succeeded\n"); } return 0; }
/** * ehci_ppc_soc_hcd_init - init echi structure * Context: !in_interrupt() * * Init basic fields like regs for this USB host controller. * */ static int ehci_ppc_soc_hcd_init(struct ehci_hcd *ehci) { u32 temp; spin_lock_init(&ehci->lock); ehci->caps = ehci->hcd.regs; ehci->regs = ehci->hcd.regs + HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase)); dbg_hcs_params(ehci, "init"); dbg_hcc_params(ehci, "init"); /* cache this readonly data; minimize chip reads */ ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); ehci_reset(ehci); ehci_port_power(ehci, 0); temp = HCS_N_CC(ehci->hcs_params) * HCS_N_PCC(ehci->hcs_params); temp &= 0x0f; if (temp && HCS_N_PORTS(ehci->hcs_params) > temp) { ehci_dbg(ehci, "bogus port configuration: " "cc=%d x pcc=%d < ports=%d\n", HCS_N_CC(ehci->hcs_params), HCS_N_PCC(ehci->hcs_params), HCS_N_PORTS(ehci->hcs_params)); } /* force HC to halt state */ return ehci_halt(ehci); }
static struct ehci_qh *ehci_qh_alloc (struct ehci_hcd *ehci, gfp_t flags) { struct ehci_qh *qh; dma_addr_t dma; qh = kzalloc(sizeof *qh, GFP_ATOMIC); if (!qh) goto done; qh->hw = (struct ehci_qh_hw *) dma_pool_alloc(ehci->qh_pool, flags, &dma); if (!qh->hw) goto fail; memset(qh->hw, 0, sizeof *qh->hw); qh->refcount = 1; qh->ehci = ehci; qh->qh_dma = dma; // INIT_LIST_HEAD (&qh->qh_list); INIT_LIST_HEAD (&qh->qtd_list); /* dummy td enables safe urb queuing */ qh->dummy = ehci_qtd_alloc (ehci, flags); if (qh->dummy == NULL) { ehci_dbg (ehci, "no dummy td\n"); goto fail1; } done: return qh; fail1: dma_pool_free(ehci->qh_pool, qh->hw, qh->qh_dma); fail: kfree(qh); return NULL; }
static int s5p_ehci_resume(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct s5p_ehci_hcd *s5p_ehci = platform_get_drvdata(pdev); struct usb_hcd *hcd = s5p_ehci->hcd; struct ehci_hcd *ehci = hcd_to_ehci(hcd); clk_enable(s5p_ehci->clk); s5p_ehci_phy_init(pdev); if (time_before(jiffies, ehci->next_statechange)) msleep(10); /* Mark hardware accessible again as we are out of D3 state by now */ set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); if (ehci_readl(ehci, &ehci->regs->configured_flag) == FLAG_CF) { int mask = INTR_MASK; if (!hcd->self.root_hub->do_remote_wakeup) mask &= ~STS_PCD; ehci_writel(ehci, mask, &ehci->regs->intr_enable); ehci_readl(ehci, &ehci->regs->intr_enable); return 0; } ehci_dbg(ehci, "lost power, restarting\n"); usb_root_hub_lost_power(hcd->self.root_hub); (void) ehci_halt(ehci); (void) ehci_reset(ehci); /* emptying the schedule aborts any urbs */ spin_lock_irq(&ehci->lock); if (ehci->reclaim) end_unlink_async(ehci); ehci_work(ehci); spin_unlock_irq(&ehci->lock); ehci_writel(ehci, ehci->command, &ehci->regs->command); ehci_writel(ehci, FLAG_CF, &ehci->regs->configured_flag); ehci_readl(ehci, &ehci->regs->command); /* unblock posted writes */ /* here we "know" root ports should always stay powered */ ehci_port_power(ehci, 1); ehci->rh_state = EHCI_RH_SUSPENDED; /* Update runtime PM status and clear runtime_error */ pm_runtime_disable(dev); pm_runtime_set_active(dev); pm_runtime_enable(dev); /* Prevent device from runtime suspend during resume time */ pm_runtime_get_sync(dev); return 0; }
/* * this function is used to check if the device support LPM * if yes, mark the PORTSC register with PORT_LPM bit */ static int __maybe_unused ehci_lpm_check(struct ehci_hcd *ehci, int port) { u32 __iomem *portsc ; u32 val32; int retval; portsc = &ehci->regs->port_status[port-1]; val32 = ehci_readl(ehci, portsc); if (!(val32 & PORT_DEV_ADDR)) { ehci_dbg(ehci, "LPM: no device attached\n"); return -ENODEV; } val32 |= PORT_LPM; ehci_writel(ehci, val32, portsc); msleep(5); val32 |= PORT_SUSPEND; ehci_dbg(ehci, "Sending LPM 0x%08x to port %d\n", val32, port); ehci_writel(ehci, val32, portsc); /* wait for ACK */ msleep(10); retval = handshake(ehci, &ehci->regs->port_status[port-1], PORT_SSTS, PORTSC_SUSPEND_STS_ACK, 125); dbg_port(ehci, "LPM", port, val32); if (retval != -ETIMEDOUT) { ehci_dbg(ehci, "LPM: device ACK for LPM\n"); val32 |= PORT_LPM; /* * now device should be in L1 sleep, let's wake up the device * so that we can complete enumeration. */ ehci_writel(ehci, val32, portsc); msleep(10); val32 |= PORT_RESUME; ehci_writel(ehci, val32, portsc); } else { ehci_dbg(ehci, "LPM: device does not ACK, disable LPM %d\n", retval); val32 &= ~PORT_LPM; retval = -ETIMEDOUT; ehci_writel(ehci, val32, portsc); } return retval; }
static int ehci_hcd_au1xxx_drv_resume(struct device *dev) { struct usb_hcd *hcd = dev_get_drvdata(dev); struct ehci_hcd *ehci = hcd_to_ehci(hcd); alchemy_usb_control(ALCHEMY_USB_EHCI0, 1); // if (time_before(jiffies, ehci->next_statechange)) msleep(100); /* */ set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); /* */ if (ehci_readl(ehci, &ehci->regs->configured_flag) == FLAG_CF) { int mask = INTR_MASK; ehci_prepare_ports_for_controller_resume(ehci); if (!hcd->self.root_hub->do_remote_wakeup) mask &= ~STS_PCD; ehci_writel(ehci, mask, &ehci->regs->intr_enable); ehci_readl(ehci, &ehci->regs->intr_enable); return 0; } ehci_dbg(ehci, "lost power, restarting\n"); usb_root_hub_lost_power(hcd->self.root_hub); /* */ (void) ehci_halt(ehci); (void) ehci_reset(ehci); /* */ spin_lock_irq(&ehci->lock); if (ehci->reclaim) end_unlink_async(ehci); ehci_work(ehci); spin_unlock_irq(&ehci->lock); ehci_writel(ehci, ehci->command, &ehci->regs->command); ehci_writel(ehci, FLAG_CF, &ehci->regs->configured_flag); ehci_readl(ehci, &ehci->regs->command); /* */ /* */ ehci_port_power(ehci, 1); ehci->rh_state = EHCI_RH_SUSPENDED; return 0; }
static int ehci_hcd_au1xxx_drv_resume(struct device *dev) { struct usb_hcd *hcd = dev_get_drvdata(dev); struct ehci_hcd *ehci = hcd_to_ehci(hcd); au1xxx_start_ehc(); // maybe restore FLADJ if (time_before(jiffies, ehci->next_statechange)) msleep(100); /* Mark hardware accessible again as we are out of D3 state by now */ set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); /* If CF is still set, we maintained PCI Vaux power. * Just undo the effect of ehci_pci_suspend(). */ if (ehci_readl(ehci, &ehci->regs->configured_flag) == FLAG_CF) { int mask = INTR_MASK; ehci_prepare_ports_for_controller_resume(ehci); if (!hcd->self.root_hub->do_remote_wakeup) mask &= ~STS_PCD; ehci_writel(ehci, mask, &ehci->regs->intr_enable); ehci_readl(ehci, &ehci->regs->intr_enable); return 0; } ehci_dbg(ehci, "lost power, restarting\n"); usb_root_hub_lost_power(hcd->self.root_hub); /* Else reset, to cope with power loss or flush-to-storage * style "resume" having let BIOS kick in during reboot. */ (void) ehci_halt(ehci); (void) ehci_reset(ehci); /* emptying the schedule aborts any urbs */ spin_lock_irq(&ehci->lock); if (ehci->reclaim) end_unlink_async(ehci); ehci_work(ehci); spin_unlock_irq(&ehci->lock); ehci_writel(ehci, ehci->command, &ehci->regs->command); ehci_writel(ehci, FLAG_CF, &ehci->regs->configured_flag); ehci_readl(ehci, &ehci->regs->command); /* unblock posted writes */ /* here we "know" root ports should always stay powered */ ehci_port_power(ehci, 1); ehci->rh_state = EHCI_RH_SUSPENDED; return 0; }
static int ehci_pci_reinit(struct ehci_hcd *ehci, struct pci_dev *pdev) { int retval; retval = pci_set_mwi(pdev); if (!retval) ehci_dbg(ehci, "MWI active\n"); return 0; }
static void qh_destroy(struct ehci_hcd *ehci, struct ehci_qh *qh) { /* clean qtds first, and know this is not linked */ if (!list_empty (&qh->qtd_list) || qh->qh_next.ptr) { ehci_dbg (ehci, "unused qh not empty!\n"); BUG (); } if (qh->dummy) ehci_qtd_free (ehci, qh->dummy); dma_pool_free(ehci->qh_pool, qh->hw, qh->qh_dma); kfree(qh); }
static void qh_put (struct ehci_hcd *ehci, struct ehci_qh *qh) { if (!atomic_dec_and_test (&qh->refcount)) return; /* clean qtds first, and know this is not linked */ if (!list_empty (&qh->qtd_list) || qh->qh_next.ptr) { ehci_dbg (ehci, "unused qh not empty!\n"); BUG (); } if (qh->dummy) ehci_qtd_free (ehci, qh->dummy); pci_pool_free (ehci->qh_pool, qh, qh->qh_dma); }
/* * 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"); /* no more interrupts ... */ del_timer_sync (&ehci->watchdog); del_timer_sync(&ehci->iaa_watchdog); spin_lock_irq(&ehci->lock); if (HC_IS_RUNNING (hcd->state)) ehci_quiesce (ehci); ehci_silence_controller(ehci); ehci_reset (ehci); spin_unlock_irq(&ehci->lock); remove_companion_file(ehci); remove_debug_files (ehci); /* root hub is shut down separately (first, when possible) */ spin_lock_irq (&ehci->lock); if (ehci->async) ehci_work (ehci); spin_unlock_irq (&ehci->lock); ehci_mem_cleanup (ehci); #ifdef EHCI_STATS ehci_dbg (ehci, "irq normal %ld err %ld reclaim %ld (lost %ld)\n", ehci->stats.normal, ehci->stats.error, ehci->stats.reclaim, ehci->stats.lost_iaa); ehci_dbg (ehci, "complete %ld unlink %ld\n", ehci->stats.complete, ehci->stats.unlink); #endif dbg_status (ehci, "ehci_stop completed", ehci_readl(ehci, &ehci->regs->status)); }
static void periodic_tt_usecs ( struct ehci_hcd *ehci, struct usb_device *dev, unsigned frame, unsigned short tt_usecs[8] ) { __hc32 *hw_p = &ehci->periodic [frame]; union ehci_shadow *q = &ehci->pshadow [frame]; unsigned char uf; memset(tt_usecs, 0, 16); while (q->ptr) { switch (hc32_to_cpu(ehci, Q_NEXT_TYPE(ehci, *hw_p))) { case Q_TYPE_ITD: hw_p = &q->itd->hw_next; q = &q->itd->itd_next; continue; case Q_TYPE_QH: if (same_tt(dev, q->qh->dev)) { uf = tt_start_uframe(ehci, q->qh->hw->hw_info2); tt_usecs[uf] += q->qh->tt_usecs; } hw_p = &q->qh->hw->hw_next; q = &q->qh->qh_next; continue; case Q_TYPE_SITD: if (same_tt(dev, q->sitd->urb->dev)) { uf = tt_start_uframe(ehci, q->sitd->hw_uframe); tt_usecs[uf] += q->sitd->stream->tt_usecs; } hw_p = &q->sitd->hw_next; q = &q->sitd->sitd_next; continue; default: ehci_dbg(ehci, "ignoring periodic frame %d FSTN\n", frame); hw_p = &q->fstn->hw_next; q = &q->fstn->fstn_next; } } carryover_tt_bandwidth(tt_usecs); if (max_tt_usecs[7] < tt_usecs[7]) ehci_err(ehci, "frame %d tt sched overrun: %d usecs\n", frame, tt_usecs[7] - max_tt_usecs[7]); }
static void qh_destroy(struct ehci_qh *qh) { struct ehci_hcd *ehci = qh->ehci; if (!list_empty (&qh->qtd_list) || qh->qh_next.ptr) { ehci_dbg (ehci, "unused qh not empty!\n"); BUG (); } if (qh->dummy) ehci_qtd_free (ehci, qh->dummy); dma_pool_free(ehci->qh_pool, qh->hw, qh->qh_dma); kfree(qh); }
static void qh_destroy (struct kref *kref) { struct ehci_qh *qh = container_of(kref, struct ehci_qh, kref); struct ehci_hcd *ehci = qh->ehci; /* clean qtds first, and know this is not linked */ if (!list_empty (&qh->qtd_list) || qh->qh_next.ptr) { ehci_dbg (ehci, "unused qh not empty!\n"); BUG (); } if (qh->dummy) ehci_qtd_free (ehci, qh->dummy); dma_pool_free (ehci->qh_pool, qh, qh->qh_dma); }
/* called after powerup, by probe or system-pm "wakeup" */ static int ehci_pci_reinit(struct ehci_hcd *ehci, struct pci_dev *pdev) { int retval; /* we expect static quirk code to handle the "extended capabilities" * (currently just BIOS handoff) allowed starting with EHCI 0.96 */ /* PCI Memory-Write-Invalidate cycle support is optional (uncommon) */ retval = pci_set_mwi(pdev); if (!retval) ehci_dbg(ehci, "MWI active\n"); return 0; }
static int check_reset_complete ( struct ehci_hcd *ehci, int index, int port_status ) { if (!(port_status & PORT_CONNECT)) { ehci->reset_done [index] = 0; return port_status; } /* if reset finished and it's still not enabled -- handoff */ if (!(port_status & PORT_PE)) { ehci_dbg (ehci, "port %d full speed --> companion\n", index + 1); // what happens if HCS_N_CC(params) == 0 ? port_status |= PORT_OWNER; writel (port_status, &ehci->regs->port_status [index]); } else ehci_dbg (ehci, "port %d high speed\n", index + 1); return port_status; }
static void ehci_port_power (struct ehci_hcd *ehci, int is_on) { unsigned port; if (!HCS_PPC (ehci->hcs_params)) return; ehci_dbg (ehci, "...power%s ports...\n", is_on ? "up" : "down"); for (port = HCS_N_PORTS (ehci->hcs_params); port > 0; ) (void) ehci_hub_control(ehci_to_hcd(ehci), is_on ? SetPortFeature : ClearPortFeature, USB_PORT_FEAT_POWER, port--, NULL, 0); msleep(20); }
static int ehci_hcd_s5pv210_drv_resume(struct platform_device *pdev) { struct usb_hcd *hcd = platform_get_drvdata(pdev); struct ehci_hcd *ehci = hcd_to_ehci(hcd); s5pv210_start_ehc(); if (time_before(jiffies, ehci->next_statechange)) msleep(10); /* Mark hardware accessible again as we are out of D3 state by now */ set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); if (ehci_readl(ehci, &ehci->regs->configured_flag) == FLAG_CF) { int mask = INTR_MASK; if (!hcd->self.root_hub->do_remote_wakeup) mask &= ~STS_PCD; ehci_writel(ehci, mask, &ehci->regs->intr_enable); ehci_readl(ehci, &ehci->regs->intr_enable); return 0; } ehci_dbg(ehci, "lost power, restarting\n"); usb_root_hub_lost_power(hcd->self.root_hub); (void) ehci_halt(ehci); (void) ehci_reset(ehci); /* emptying the schedule aborts any urbs */ spin_lock_irq(&ehci->lock); if (ehci->reclaim) end_unlink_async(ehci); ehci_work(ehci); spin_unlock_irq(&ehci->lock); ehci_writel(ehci, ehci->command, &ehci->regs->command); ehci_writel(ehci, FLAG_CF, &ehci->regs->configured_flag); ehci_readl(ehci, &ehci->regs->command); /* unblock posted writes */ /* here we "know" root ports should always stay powered */ ehci_port_power(ehci, 1); hcd->state = HC_STATE_SUSPENDED; return 0; }
static void qh_destroy(struct ehci_qh *qh) { struct ehci_hcd *ehci = qh->ehci; /* clean qtds first, and know this is not linked */ if (!list_empty (&qh->qtd_list) || qh->qh_next.ptr) { ehci_dbg (ehci, "unused qh not empty!\n"); BUG (); } if (qh->dummy) ehci_qtd_free (ehci, qh->dummy); /* tony.yu map between PHY addr & BUS addr */ #if defined(CONFIG_ARM) && (MP_USB_MSTAR==1) qh->qh_dma = PA2BUS(qh->qh_dma); #endif dma_pool_free(ehci->qh_pool, qh->hw, qh->qh_dma); kfree(qh); }
static int ehci_orion_resume(struct platform_device *pdev) { struct orion_ehci_data *pd = pdev->dev.platform_data; struct usb_hcd *hcd = platform_get_drvdata(pdev); struct ehci_hcd *ehci = hcd_to_ehci(hcd); // maybe restore FLADJ if (time_before(jiffies, ehci->next_statechange)) msleep(100); /* Mark hardware accessible again as we are out of D3 state by now */ set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); ehci_dbg(ehci, "lost power, restarting\n"); usb_root_hub_lost_power(hcd->self.root_hub); /* Else reset, to cope with power loss or flush-to-storage * style "resume" having let BIOS kick in during reboot. */ (void) ehci_halt(ehci); (void) ehci_reset(ehci); ehci_orion_hw_init(hcd, pd); /* emptying the schedule aborts any urbs */ spin_lock_irq(&ehci->lock); if (ehci->reclaim) end_unlink_async(ehci); ehci_work(ehci); spin_unlock_irq(&ehci->lock); ehci_writel(ehci, ehci->command, &ehci->regs->command); ehci_writel(ehci, FLAG_CF, &ehci->regs->configured_flag); ehci_readl(ehci, &ehci->regs->command); /* unblock posted writes */ /* here we "know" root ports should always stay powered */ ehci_port_power(ehci, 1); hcd->state = HC_STATE_SUSPENDED; return 0; }
static struct ehci_qh *ehci_qh_alloc (struct ehci_hcd *ehci, gfp_t flags) { struct ehci_qh *qh; dma_addr_t dma; qh = kzalloc(sizeof *qh, GFP_ATOMIC); if (!qh) goto done; qh->hw = (struct ehci_qh_hw *) dma_pool_alloc(ehci->qh_pool, flags, &dma); /* tony.yu map between PHY addr & BUS addr */ #if defined(CONFIG_ARM) && (MP_USB_MSTAR==1) dma = BUS2PA(dma); #endif if (!qh->hw) goto fail; memset(qh->hw, 0, sizeof *qh->hw); qh->refcount = 1; qh->ehci = ehci; qh->qh_dma = dma; // INIT_LIST_HEAD (&qh->qh_list); INIT_LIST_HEAD (&qh->qtd_list); /* dummy td enables safe urb queuing */ qh->dummy = ehci_qtd_alloc (ehci, flags); if (qh->dummy == NULL) { ehci_dbg (ehci, "no dummy td\n"); goto fail1; } done: return qh; fail1: /* tony.yu map between PHY addr & BUS addr */ #if defined(CONFIG_ARM) && (MP_USB_MSTAR==1) qh->qh_dma = PA2BUS(qh->qh_dma); #endif dma_pool_free(ehci->qh_pool, qh->hw, qh->qh_dma); fail: kfree(qh); return NULL; }
/* Poll the STS_ASS status bit; see when it agrees with CMD_ASE */ static void ehci_poll_ASS(struct ehci_hcd *ehci) { unsigned actual, want; /* Don't enable anything if the controller isn't running (e.g., died) */ if (ehci->rh_state != EHCI_RH_RUNNING) return; want = (ehci->command & CMD_ASE) ? STS_ASS : 0; actual = ehci_readl(ehci, &ehci->regs->status) & STS_ASS; if (want != actual) { /* Poll again later */ ehci_enable_event(ehci, EHCI_HRTIMER_POLL_ASS, true); ++ehci->ASS_poll_count; return; } if (ehci->ASS_poll_count > 20) ehci_dbg(ehci, "ASS poll count reached %d\n", ehci->ASS_poll_count); ehci->ASS_poll_count = 0; /* The status is up-to-date; restart or stop the schedule as needed */ if (want == 0) { /* Stopped */ if (ehci->async_count > 0) ehci_set_command_bit(ehci, CMD_ASE); } else { /* Running */ if (ehci->async_count == 0) { /* Turn off the schedule after a while */ ehci_enable_event(ehci, EHCI_HRTIMER_DISABLE_ASYNC, true); } } }
/* called after powerup, by probe or system-pm "wakeup" */ static int ehci_pci_reinit(struct ehci_hcd *ehci, struct pci_dev *pdev) { u32 temp; int retval; /* optional debug port, normally in the first BAR */ temp = pci_find_capability(pdev, 0x0a); if (temp) { pci_read_config_dword(pdev, temp, &temp); temp >>= 16; if ((temp & (3 << 13)) == (1 << 13)) { temp &= 0x1fff; ehci->debug = ehci_to_hcd(ehci)->regs + temp; temp = ehci_readl(ehci, &ehci->debug->control); ehci_info(ehci, "debug port %d%s\n", HCS_DEBUG_PORT(ehci->hcs_params), (temp & DBGP_ENABLED) ? " IN USE" : ""); if (!(temp & DBGP_ENABLED)) ehci->debug = NULL; } } /* we expect static quirk code to handle the "extended capabilities" * (currently just BIOS handoff) allowed starting with EHCI 0.96 */ /* PCI Memory-Write-Invalidate cycle support is optional (uncommon) */ retval = pci_set_mwi(pdev); if (!retval) ehci_dbg(ehci, "MWI active\n"); ehci_port_power(ehci, 0); return 0; }