static void ehci_msm_start_hnp(struct ehci_hcd *ehci) { struct usb_hcd *hcd = ehci_to_hcd(ehci); struct msmusb_hcd *mhcd = hcd_to_mhcd(hcd); /* OTG driver handles HNP */ otg_start_hnp(mhcd->xceiv); }
static void tegra_ehci_hcd_shutdown(struct platform_device *pdev) { struct tegra_ehci_hcd *tegra = platform_get_drvdata(pdev); struct usb_hcd *hcd = ehci_to_hcd(tegra->ehci); if (hcd->driver->shutdown) hcd->driver->shutdown(hcd); }
static void ehci_hcd_omap_shutdown(struct platform_device *pdev) { struct ehci_hcd_omap *omap = platform_get_drvdata(pdev); struct usb_hcd *hcd = ehci_to_hcd(omap->ehci); if (hcd->driver->shutdown) hcd->driver->shutdown(hcd); }
static void berlin_ehci_shutdown(struct platform_device *pdev) { struct berlin_ehci_hcd *berlin = platform_get_drvdata(pdev); struct usb_hcd *hcd = ehci_to_hcd(berlin->ehci); if (hcd->driver->shutdown) hcd->driver->shutdown(hcd); }
static int ar9130_start_hc(struct ehci_hcd *ehci, struct device *dev) { printk ("ar9130_start_hc %p, %p\n", ehci_to_hcd(ehci), &ehci_to_hcd(ehci)->self); if (ehci->transceiver) { int status = otg_set_host(ehci->transceiver, &ehci_to_hcd(ehci)->self); dev_info(dev, "init %s transceiver, status %d\n", ehci->transceiver->label, status); if (status) { if (ehci->transceiver) put_device(ehci->transceiver->dev); } return status; } else { dev_err(dev, "can't find transceiver\n"); return -ENODEV; } }
static int tegra_ehci_remove(struct platform_device *pdev) { struct tegra_ehci_hcd *tegra = platform_get_drvdata(pdev); struct usb_hcd *hcd = ehci_to_hcd(tegra->ehci); dev_info(&pdev->dev, "%s+\n", __func__); //htc_dbg if (tegra == NULL || hcd == NULL) return -EINVAL; #ifdef CONFIG_USB_OTG_UTILS if (tegra->transceiver) { otg_set_host(tegra->transceiver, NULL); otg_put_transceiver(tegra->transceiver); } #endif if (tegra->irq) disable_irq_wake(tegra->irq); /* Make sure phy is powered ON to access USB register */ if(!tegra_usb_phy_hw_accessible(tegra->phy)) tegra_usb_phy_power_on(tegra->phy); pr_info("+%s:usb_remove_hcd\n", __func__); uhsic_phy_remove(tegra->phy); usb_remove_hcd(hcd); usb_put_hcd(hcd); ehci_remove = 1; tegra_usb_phy_power_off(tegra->phy); tegra_usb_phy_close(tegra->phy); iounmap(hcd->regs); platform_set_drvdata(pdev, NULL); //htc++ #ifdef CONFIG_QCT_9K_MODEM if (Modem_is_QCT_MDM9K()) { extern struct platform_device tegra_ehci2_device; if (&tegra_ehci2_device == pdev) { mdm_hsic_ehci_hcd = NULL; mdm_hsic_usb_hcd = NULL; mdm_hsic_phy = NULL; pr_info("%s:: mdm_hsic_ehci_hcd = %x, mdm_hsic_usb_hcd = %x, mdm_hsic_phy = %x\n", __func__, (unsigned int)mdm_hsic_ehci_hcd, (unsigned int)mdm_hsic_usb_hcd, (unsigned int)mdm_hsic_phy); } } #endif //CONFIG_QCT_9K_MODEM //htc-- dev_info(&pdev->dev, "%s-\n", __func__); //htc_dbg return 0; }
static inline void remove_sysfs_files(struct ehci_hcd *ehci) { struct device *controller = ehci_to_hcd(ehci)->self.controller; /* with integrated TT there is no companion! */ if (!ehci_is_TDI(ehci)) device_remove_file(controller, &dev_attr_companion); device_remove_file(controller, &dev_attr_uframe_periodic_max); }
static irqreturn_t ehci_hcd_omap_hack_handler(int irq, void *dev) { struct ehci_hcd_omap *omap = dev_get_drvdata(dev); struct ehci_hcd *ehci = omap->ehci; struct usb_hcd *hcd = ehci_to_hcd(ehci); /* resume root hub? */ usb_hcd_resume_root_hub(hcd); return IRQ_HANDLED; }
static int s5p_ehci_runtime_resume(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct s5p_ehci_platdata *pdata = pdev->dev.platform_data; 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); int rc = 0; if (dev->power.is_suspended) return 0; /* platform device isn't suspended */ if (pdata && pdata->phy_resume) rc = pdata->phy_resume(pdev, S5P_USB_PHY_HOST); if (rc) { s5p_ehci_configurate(hcd); /* 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); usb_root_hub_lost_power(hcd->self.root_hub); ehci_writel(ehci, FLAG_CF, &ehci->regs->configured_flag); ehci_writel(ehci, INTR_MASK, &ehci->regs->intr_enable); (void)ehci_readl(ehci, &ehci->regs->intr_enable); /* here we "know" root ports should always stay powered */ ehci_port_power(ehci, 1); hcd->state = HC_STATE_SUSPENDED; #if 0//def CONFIG_USB_EXYNOS_SWITCH } else { if (1) //samsung_board_rev_is_0_0()) /* the same board configuration that Mehmet DVT has */ { ehci_hub_control(ehci_to_hcd(ehci), SetPortFeature, USB_PORT_FEAT_POWER, 1, NULL, 0); /* Flush those writes */ ehci_readl(ehci, &ehci->regs->command); msleep(20); } #endif } return 0; }
/* * Work thread function for handling the USB power sequence. * * This work thread is created to avoid the pre-emption from the ISR context. * USB Power Rail and Vbus are controlled based on the USB cable connection. * USB Power rail function and VBUS control function cannot be called from ISR * as NvRmPmuSetVoltage() uses I2C driver, that waits on semaphore * during the I2C transaction this will cause the pre-emption if called in ISR. */ static void tegra_ehci_irq_work(struct work_struct* irq_work) { struct ehci_hcd *ehci = container_of(irq_work, struct ehci_hcd, irq_work); struct usb_hcd *hcd = ehci_to_hcd(ehci); struct tegra_hcd_platform_data *pdata; u32 status; bool kick_rhub = false; pdata = hcd->self.controller->platform_data; #ifdef CONFIG_USB_OTG_UTILS if (pdata->otg_mode && ehci->transceiver) { if (ehci->transceiver->state == OTG_STATE_A_HOST) { if (!ehci->host_reinited) { ehci->host_reinited = 1; tegra_ehci_power_up(hcd); if (hcd->state == HC_STATE_SUSPENDED) kick_rhub = true; tegra_ehci_restart(hcd); } } else if (ehci->transceiver->state == OTG_STATE_A_SUSPEND) { if (ehci->host_reinited) { /* indicate hcd flags, that hardware is not accessible now */ clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); ehci_halt(ehci); tegra_ehci_power_down(hcd); ehci->transceiver->state = OTG_STATE_UNDEFINED; ehci->host_reinited = 0; } } } else #endif { if (pdata->id_detect == ID_PIN_CABLE_ID) { /* read otgsc register for ID pin status change */ status = readl(hcd->regs + TEGRA_USB_PHY_WAKEUP_REG_OFFSET); /* Check pin status and enable/disable the power */ if (status & TEGRA_USB_ID_PIN_STATUS) { tegra_ehci_power_down(hcd); } else { tegra_ehci_power_up(hcd); if (hcd->state == HC_STATE_SUSPENDED) kick_rhub = true; } } } if (kick_rhub) { hcd->state = HC_STATE_SUSPENDED; usb_hcd_resume_root_hub(hcd); } }
static int berlin_ehci_remove(struct platform_device *pdev) { struct berlin_ehci_hcd *berlin = platform_get_drvdata(pdev); struct usb_hcd *hcd = ehci_to_hcd(berlin->ehci); mv_stop_ehc(hcd); usb_remove_hcd(hcd); iounmap(hcd->regs); release_mem_region(hcd->rsrc_start, hcd->rsrc_len); usb_put_hcd(hcd); return 0; }
static void ehci_hcd_omap_shutdown(struct platform_device *pdev) { struct ehci_hcd_omap *omap = platform_get_drvdata(pdev); struct usb_hcd *hcd = ehci_to_hcd(omap->ehci); struct uhhtll_apis *uhhtllp = pdev->dev.platform_data; int ret = 0; if (uhhtllp && uhhtllp->resume) ret = uhhtllp->resume(OMAP_EHCI); if (!ret && hcd->driver->shutdown) hcd->driver->shutdown(hcd); }
static int tegra_ehci_remove(struct platform_device *pdev) { struct tegra_ehci_hcd *tegra = platform_get_drvdata(pdev); struct usb_hcd *hcd = ehci_to_hcd(tegra->ehci); struct usb_device *rhdev = NULL; struct tegra_usb_platform_data *pdata; unsigned long timeout = 0; wake_lock_destroy(&tegra->ehci_wake_lock); #ifdef CONFIG_TEGRA_EHCI_BOOST_CPU_FREQ cancel_delayed_work_sync(&tegra->boost_cpu_freq_work); tegra->cpu_boost_in_work = false; pm_qos_remove_request(&tegra->boost_cpu_freq_req); #endif rhdev = hcd->self.root_hub; pdata = dev_get_platdata(&pdev->dev); if (!IS_ERR_OR_NULL(tegra->transceiver)) otg_set_host(tegra->transceiver->otg, NULL); /* Make sure phy is powered ON to access USB register */ if(!tegra_usb_phy_hw_accessible(tegra->phy)) tegra_usb_phy_power_on(tegra->phy); if (pdata->port_otg) { timeout = jiffies + 5 * HZ; /* wait for devices connected to root hub to disconnect*/ while (rhdev && usb_hub_find_child(rhdev, 1)) { /* wait for any control packets sent to root hub to complete */ if (time_after(jiffies, timeout)) break; msleep(20); cpu_relax(); } } #ifdef CONFIG_TEGRA_EHCI_BOOST_CPU_FREQ device_remove_file(hcd->self.controller, &dev_attr_boost_enable); #endif usb_remove_hcd(hcd); usb_put_hcd(hcd); tegra_usb_phy_power_off(tegra->phy); usb_phy_shutdown(get_usb_phy(tegra->phy)); mutex_destroy(&tegra->sync_lock); tegra_pd_remove_device(&pdev->dev); return 0; }
static void ehci_xusbps_start_hnp(struct ehci_hcd *ehci) { const unsigned port = ehci_to_hcd(ehci)->self.otg_port - 1; unsigned long flags; u32 portsc; local_irq_save(flags); portsc = ehci_readl(ehci, &ehci->regs->port_status[port]); portsc |= PORT_SUSPEND; ehci_writel(ehci, portsc, &ehci->regs->port_status[port]); local_irq_restore(flags); otg_start_hnp(ehci->transceiver); }
/** * ehci_hcd_omap_remove - shutdown processing for EHCI HCDs * @pdev: USB Host Controller being removed * * Reverses the effect of usb_ehci_hcd_omap_probe(), first invoking * the HCD's stop() method. It is always called from a thread * context, normally "rmmod", "apmd", or something similar. */ static int ehci_hcd_omap_remove(struct platform_device *pdev) { struct ehci_hcd_omap *omap = platform_get_drvdata(pdev); struct usb_hcd *hcd = ehci_to_hcd(omap->ehci); usb_remove_hcd(hcd); omap_stop_ehc(omap, hcd); iounmap(hcd->regs); iounmap(omap->tll_base); iounmap(omap->uhh_base); usb_put_hcd(hcd); return 0; }
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 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; }
static inline int create_sysfs_files(struct ehci_hcd *ehci) { struct device *controller = ehci_to_hcd(ehci)->self.controller; int i = 0; /* with integrated TT there is no companion! */ if (!ehci_is_TDI(ehci)) i = device_create_file(controller, &dev_attr_companion); if (i) goto out; i = device_create_file(controller, &dev_attr_uframe_periodic_max); out: return i; }
static void ehci_hsic_port_power(struct ehci_hcd *ehci, int is_on) { unsigned port; if (!HCS_PPC(ehci->hcs_params)) return; dev_dbg(&pci_dev->dev, "...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); /* Flush those writes */ ehci_readl(ehci, &ehci->regs->command); }
/** * ehci_hcd_omap_remove - shutdown processing for EHCI HCDs * @pdev: USB Host Controller being removed * * Reverses the effect of usb_ehci_hcd_omap_probe(), first invoking * the HCD's stop() method. It is always called from a thread * context, normally "rmmod", "apmd", or something similar. */ static int ehci_hcd_omap_remove(struct platform_device *pdev) { struct uhhtll_apis *uhhtllp = pdev->dev.platform_data; struct ehci_hcd_omap *omap = platform_get_drvdata(pdev); struct usb_hcd *hcd = ehci_to_hcd(omap->ehci); if (hcd->state == HC_STATE_SUSPENDED) uhhtllp->resume(OMAP_EHCI); usb_remove_hcd(hcd); uhhtllp->disable(OMAP_EHCI); usb_put_hcd(hcd); kfree(omap); return 0; }
void arc_otg_reset(struct ehci_hcd *ehci) { struct device *dev = ehci_to_hcd(ehci)->self.controller; struct arc_usb_config *config = (struct arc_usb_config *)dev->platform_data; dbg("%s ehci->regs=0x%p\n", __FUNCTION__, ehci->regs); dbg("%s config=0x%p config->name=%s\n", __FUNCTION__, config, config->name); writel(USBMODE_CM_HOST, config->usbmode); dbg("%s(): set %s xcvr=0x%x usbmode=0x%x portsc1 at 0x%p\n", __FUNCTION__, config->name, config->xcvr_type, config->usbmode, &ehci->regs->port_status[0]); }
static void ehci_iaa_watchdog(unsigned long param) { struct ehci_hcd *ehci = (struct ehci_hcd *) param; unsigned long flags; spin_lock_irqsave (&ehci->lock, flags); /* Lost IAA irqs wedge things badly; seen first with a vt8235. * So we need this watchdog, but must protect it against both * (a) SMP races against real IAA firing and retriggering, and * (b) clean HC shutdown, when IAA watchdog was pending. */ if (ehci->reclaim && !timer_pending(&ehci->iaa_watchdog) && HC_IS_RUNNING(ehci_to_hcd(ehci)->state)) { u32 cmd, status; /* If we get here, IAA is *REALLY* late. It's barely * conceivable that the system is so busy that CMD_IAAD * is still legitimately set, so let's be sure it's * clear before we read STS_IAA. (The HC should clear * CMD_IAAD when it sets STS_IAA.) */ cmd = ehci_readl(ehci, &ehci->regs->command); if (cmd & CMD_IAAD) ehci_writel(ehci, cmd & ~CMD_IAAD, &ehci->regs->command); /* If IAA is set here it either legitimately triggered * before we cleared IAAD above (but _way_ late, so we'll * still count it as lost) ... or a silicon erratum: * - VIA seems to set IAA without triggering the IRQ; * - IAAD potentially cleared without setting IAA. */ status = ehci_readl(ehci, &ehci->regs->status); if ((status & STS_IAA) || !(cmd & CMD_IAAD)) { COUNT (ehci->stats.lost_iaa); ehci_writel(ehci, STS_IAA, &ehci->regs->status); } ehci_vdbg(ehci, "IAA watchdog: status %x cmd %x\n", status, cmd); end_unlink_async(ehci); } spin_unlock_irqrestore(&ehci->lock, flags); }
/** * ehci_hcd_omap_remove - shutdown processing for EHCI HCDs * @pdev: USB Host Controller being removed * * Reverses the effect of usb_ehci_hcd_omap_probe(), first invoking * the HCD's stop() method. It is always called from a thread * context, normally "rmmod", "apmd", or something similar. */ static int ehci_hcd_omap_remove(struct platform_device *pdev) { struct ehci_hcd_omap *omap = platform_get_drvdata(pdev); struct usb_hcd *hcd = ehci_to_hcd(omap->ehci); int i; if (omap->suspended) ehci_omap_enable(omap, 1); #ifdef CONFIG_LOGIC_OMAP3530_USB3320_HACK usb3320_hack_deinit(); #endif usb_remove_hcd(hcd); omap_stop_ehc(omap, hcd); if (omap->phy_reset) { if (gpio_is_valid(omap->reset_gpio_port[0])) gpio_free(omap->reset_gpio_port[0]); if (gpio_is_valid(omap->reset_gpio_port[1])) gpio_free(omap->reset_gpio_port[1]); } iounmap(hcd->regs); for (i = 0 ; i < OMAP3_HS_USB_PORTS ; i++) { if (omap->regulator[i]) { if (regulator_is_enabled(omap->regulator[i])) regulator_disable(omap->regulator[i]); regulator_put(omap->regulator[i]); } if (omap->regulator_aux[i]) { if (regulator_is_enabled(omap->regulator_aux[i])) regulator_disable(omap->regulator_aux[i]); regulator_put(omap->regulator_aux[i]); } } iounmap(omap->tll_base); iounmap(omap->uhh_base); usb_put_hcd(hcd); kfree(omap); return 0; }
/* reset a non-running (STS_HALT == 1) controller */ static int ehci_reset (struct ehci_hcd *ehci) { int retval; u32 command = readl (&ehci->regs->command); command |= CMD_RESET; dbg_cmd (ehci, "reset", command); writel (command, &ehci->regs->command); ehci_to_hcd(ehci)->state = HC_STATE_HALT; ehci->next_statechange = jiffies; retval = handshake (&ehci->regs->command, CMD_RESET, 0, 250 * 1000); if (retval) return retval; if (ehci_is_TDI(ehci)) tdi_reset (ehci); return retval; }
static void tegra_ehci_hcd_shutdown(struct platform_device *pdev) { struct tegra_ehci_hcd *tegra = NULL; struct usb_hcd *hcd = NULL; dev_info(&pdev->dev, "%s+\n", __func__); device_ehci_shutdown = true; if (!_try_lock(&pdev->dev)) { pr_info("%s failed to lock device\n", __func__); goto exit; } tegra = platform_get_drvdata(pdev); if (!tegra) { pr_info("%s device has no driver data\n", __func__); goto unlock_device; } hcd = ehci_to_hcd(tegra->ehci); if ( !hcd || !hcd->driver ) { pr_info("%s: hcd <%p> or driver is NULL\n", __func__, hcd); WARN_ON(1); goto unlock_device; } if (hcd->driver->shutdown) hcd->driver->shutdown(hcd); dev_info(&pdev->dev, "%s-\n", __func__); //htc_dbg unlock_device: device_unlock(&pdev->dev); exit: return; }
static void ehci_mem_cleanup(struct ehci_hcd *ehci) { if (ehci->async) qh_put(ehci->async); ehci->async = NULL; /* DMA consistent memory and pools */ if (ehci->qtd_pool) dma_pool_destroy(ehci->qtd_pool); ehci->qtd_pool = NULL; if (ehci->qh_pool) { dma_pool_destroy(ehci->qh_pool); ehci->qh_pool = NULL; } if (ehci->itd_pool) dma_pool_destroy(ehci->itd_pool); ehci->itd_pool = NULL; if (ehci->sitd_pool) dma_pool_destroy(ehci->sitd_pool); ehci->sitd_pool = NULL; if (ehci->periodic) dma_free_coherent(ehci_to_hcd(ehci)->self.controller, ehci->periodic_size * sizeof(u32), ehci->periodic, ehci->periodic_dma); ehci->periodic = NULL; if (ehci->iram_buffer[0]) free_iram_buf(ehci->iram_buffer[0]); if (ehci->iram_buffer[1]) free_iram_buf(ehci->iram_buffer[1]); /* shadow periodic table */ kfree(ehci->pshadow); ehci->pshadow = NULL; usb_pool_deinit(); }
static void ehci_mem_cleanup (struct ehci_hcd *ehci) { free_cached_lists(ehci); if (ehci->async) qh_put (ehci->async); ehci->async = NULL; if (ehci->dummy) qh_put(ehci->dummy); ehci->dummy = NULL; if (ehci->qtd_pool) dma_pool_destroy (ehci->qtd_pool); ehci->qtd_pool = NULL; if (ehci->qh_pool) { dma_pool_destroy (ehci->qh_pool); ehci->qh_pool = NULL; } if (ehci->itd_pool) dma_pool_destroy (ehci->itd_pool); ehci->itd_pool = NULL; if (ehci->sitd_pool) dma_pool_destroy (ehci->sitd_pool); ehci->sitd_pool = NULL; if (ehci->periodic) dma_free_coherent (ehci_to_hcd(ehci)->self.controller, ehci->periodic_size * sizeof (u32), ehci->periodic, ehci->periodic_dma); ehci->periodic = NULL; kfree(ehci->pshadow); ehci->pshadow = NULL; }
/** * ehci_hcd_omap_remove - shutdown processing for EHCI HCDs * @pdev: USB Host Controller being removed * * Reverses the effect of usb_ehci_hcd_omap_probe(), first invoking * the HCD's stop() method. It is always called from a thread * context, normally "rmmod", "apmd", or something similar. */ static int ehci_hcd_omap_remove(struct platform_device *pdev) { struct ehci_hcd_omap *omap = platform_get_drvdata(pdev); struct usb_hcd *hcd = ehci_to_hcd(omap->ehci); int i; usb_remove_hcd(hcd); omap_stop_ehc(omap, hcd); iounmap(hcd->regs); for (i = 0 ; i < OMAP3_HS_USB_PORTS ; i++) { if (omap->regulator[i]) { regulator_disable(omap->regulator[i]); regulator_put(omap->regulator[i]); } } iounmap(omap->tll_base); iounmap(omap->uhh_base); usb_put_hcd(hcd); kfree(omap); return 0; }
/* 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; }
/* remember to add cleanup code (above) if you add anything here */ static int ehci_mem_init (struct ehci_hcd *ehci, gfp_t flags) { int i; /* QTDs for control/bulk/intr transfers */ ehci->qtd_pool = dma_pool_create ("ehci_qtd", ehci_to_hcd(ehci)->self.controller, sizeof (struct ehci_qtd), 32 /* byte alignment (for hw parts) */, 4096 /* can't cross 4K */); if (!ehci->qtd_pool) { goto fail; } /* QHs for control/bulk/intr transfers */ ehci->qh_pool = dma_pool_create ("ehci_qh", ehci_to_hcd(ehci)->self.controller, sizeof(struct ehci_qh_hw), 32 /* byte alignment (for hw parts) */, 4096 /* can't cross 4K */); if (!ehci->qh_pool) { goto fail; } ehci->async = ehci_qh_alloc (ehci, flags); if (!ehci->async) { goto fail; } /* ITD for high speed ISO transfers */ ehci->itd_pool = dma_pool_create ("ehci_itd", ehci_to_hcd(ehci)->self.controller, sizeof (struct ehci_itd), 32 /* byte alignment (for hw parts) */, 4096 /* can't cross 4K */); if (!ehci->itd_pool) { goto fail; } /* SITD for full/low speed split ISO transfers */ ehci->sitd_pool = dma_pool_create ("ehci_sitd", ehci_to_hcd(ehci)->self.controller, sizeof (struct ehci_sitd), 32 /* byte alignment (for hw parts) */, 4096 /* can't cross 4K */); if (!ehci->sitd_pool) { goto fail; } /* Hardware periodic table */ ehci->periodic = (__le32 *) dma_alloc_coherent (ehci_to_hcd(ehci)->self.controller, ehci->periodic_size * sizeof(__le32), &ehci->periodic_dma, 0); if (ehci->periodic == NULL) { goto fail; } for (i = 0; i < ehci->periodic_size; i++) ehci->periodic [i] = EHCI_LIST_END(ehci); /* software shadow of hardware table */ ehci->pshadow = kcalloc(ehci->periodic_size, sizeof(void *), flags); if (ehci->pshadow != NULL) return 0; fail: ehci_dbg (ehci, "couldn't init memory\n"); ehci_mem_cleanup (ehci); return -ENOMEM; }