diff options
Diffstat (limited to 'drivers/usb/host')
39 files changed, 1138 insertions, 1012 deletions
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 1f117c360ebb..3050b18b2447 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -5,6 +5,7 @@ comment "USB Host Controller Drivers" config USB_C67X00_HCD tristate "Cypress C67x00 HCD support" + depends on HAS_IOMEM help The Cypress C67x00 (EZ-Host/EZ-OTG) chips are dual-role host/peripheral/OTG USB controllers. @@ -17,6 +18,7 @@ config USB_C67X00_HCD config USB_XHCI_HCD tristate "xHCI HCD (USB 3.0) support" + depends on HAS_DMA && HAS_IOMEM ---help--- The eXtensible Host Controller Interface (xHCI) is standard for USB 3.0 "SuperSpeed" host controller hardware. @@ -53,6 +55,7 @@ config USB_XHCI_MTK config USB_XHCI_MVEBU tristate "xHCI support for Marvell Armada 375/38x" select USB_XHCI_PLATFORM + depends on HAS_IOMEM depends on ARCH_MVEBU || COMPILE_TEST ---help--- Say 'Y' to enable the support for the xHCI host controller @@ -61,7 +64,7 @@ config USB_XHCI_MVEBU config USB_XHCI_RCAR tristate "xHCI support for Renesas R-Car SoCs" select USB_XHCI_PLATFORM - depends on ARCH_SHMOBILE || COMPILE_TEST + depends on ARCH_RENESAS || COMPILE_TEST ---help--- Say 'Y' to enable the support for the xHCI host controller found in Renesas R-Car ARM SoCs. @@ -70,6 +73,7 @@ endif # USB_XHCI_HCD config USB_EHCI_HCD tristate "EHCI HCD (USB 2.0) support" + depends on HAS_DMA && HAS_IOMEM ---help--- The Enhanced Host Controller Interface (EHCI) is standard for USB 2.0 "high speed" (480 Mbit/sec, 60 Mbyte/sec) host controller hardware. @@ -121,9 +125,6 @@ config USB_EHCI_TT_NEWSCHED If unsure, say Y. -config USB_FSL_MPH_DR_OF - tristate - if USB_EHCI_HCD config USB_EHCI_PCI @@ -156,7 +157,6 @@ config USB_EHCI_FSL tristate "Support for Freescale PPC on-chip EHCI USB controller" depends on FSL_SOC select USB_EHCI_ROOT_HUB_TT - select USB_FSL_MPH_DR_OF if OF ---help--- Variation of ARC USB block used in some Freescale chips. @@ -328,6 +328,7 @@ endif # USB_EHCI_HCD config USB_OXU210HP_HCD tristate "OXU210HP HCD support" + depends on HAS_IOMEM ---help--- The OXU210HP is an USB host/OTG/device controller. Enable this option if your board has this chip. If unsure, say N. @@ -340,6 +341,7 @@ config USB_OXU210HP_HCD config USB_ISP116X_HCD tristate "ISP116X HCD support" + depends on HAS_IOMEM ---help--- The ISP1160 and ISP1161 chips are USB host controllers. Enable this option if your board has this chip. If unsure, say N. @@ -351,6 +353,7 @@ config USB_ISP116X_HCD config USB_ISP1362_HCD tristate "ISP1362 HCD support" + depends on HAS_IOMEM ---help--- Supports the Philips ISP1362 chip as a host controller @@ -361,7 +364,7 @@ config USB_ISP1362_HCD config USB_FOTG210_HCD tristate "FOTG210 HCD support" - depends on USB + depends on USB && HAS_DMA && HAS_IOMEM ---help--- Faraday FOTG210 is an OTG controller which can be configured as an USB2.0 host. It is designed to meet USB2.0 EHCI specification @@ -383,6 +386,7 @@ config USB_MAX3421_HCD config USB_OHCI_HCD tristate "OHCI HCD (USB 1.1) support" + depends on HAS_DMA && HAS_IOMEM ---help--- The Open Host Controller Interface (OHCI) is a standard for accessing USB 1.1 host controller hardware. It does more in hardware than Intel's @@ -668,6 +672,7 @@ config USB_U132_HCD config USB_SL811_HCD tristate "SL811HS HCD support" + depends on HAS_IOMEM help The SL811HS is a single-port USB controller that supports either host side or peripheral side roles. Enable this option if your @@ -699,6 +704,7 @@ config USB_SL811_CS config USB_R8A66597_HCD tristate "R8A66597 HCD support" + depends on HAS_IOMEM help The R8A66597 is a USB 2.0 host and peripheral controller. diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile index 65a06b4382bf..a9ddd3c9ec94 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile @@ -74,7 +74,8 @@ obj-$(CONFIG_USB_U132_HCD) += u132-hcd.o obj-$(CONFIG_USB_R8A66597_HCD) += r8a66597-hcd.o obj-$(CONFIG_USB_HWA_HCD) += hwa-hc.o obj-$(CONFIG_USB_IMX21_HCD) += imx21-hcd.o -obj-$(CONFIG_USB_FSL_MPH_DR_OF) += fsl-mph-dr-of.o +obj-$(CONFIG_USB_FSL_USB2) += fsl-mph-dr-of.o +obj-$(CONFIG_USB_EHCI_FSL) += fsl-mph-dr-of.o obj-$(CONFIG_USB_EHCI_FSL) += ehci-fsl.o obj-$(CONFIG_USB_HCD_BCMA) += bcma-hcd.o obj-$(CONFIG_USB_HCD_SSB) += ssb-hcd.o diff --git a/drivers/usb/host/bcma-hcd.c b/drivers/usb/host/bcma-hcd.c index 291aaa2baed8..963e2d0e8f92 100644 --- a/drivers/usb/host/bcma-hcd.c +++ b/drivers/usb/host/bcma-hcd.c @@ -35,6 +35,7 @@ MODULE_DESCRIPTION("Common USB driver for BCMA Bus"); MODULE_LICENSE("GPL"); struct bcma_hcd_device { + struct bcma_device *core; struct platform_device *ehci_dev; struct platform_device *ohci_dev; struct gpio_desc *gpio_desc; @@ -244,7 +245,10 @@ static const struct usb_ehci_pdata ehci_pdata = { static const struct usb_ohci_pdata ohci_pdata = { }; -static struct platform_device *bcma_hcd_create_pdev(struct bcma_device *dev, bool ohci, u32 addr) +static struct platform_device *bcma_hcd_create_pdev(struct bcma_device *dev, + const char *name, u32 addr, + const void *data, + size_t size) { struct platform_device *hci_dev; struct resource hci_res[2]; @@ -259,8 +263,7 @@ static struct platform_device *bcma_hcd_create_pdev(struct bcma_device *dev, boo hci_res[1].start = dev->irq; hci_res[1].flags = IORESOURCE_IRQ; - hci_dev = platform_device_alloc(ohci ? "ohci-platform" : - "ehci-platform" , 0); + hci_dev = platform_device_alloc(name, 0); if (!hci_dev) return ERR_PTR(-ENOMEM); @@ -271,12 +274,8 @@ static struct platform_device *bcma_hcd_create_pdev(struct bcma_device *dev, boo ARRAY_SIZE(hci_res)); if (ret) goto err_alloc; - if (ohci) - ret = platform_device_add_data(hci_dev, &ohci_pdata, - sizeof(ohci_pdata)); - else - ret = platform_device_add_data(hci_dev, &ehci_pdata, - sizeof(ehci_pdata)); + if (data) + ret = platform_device_add_data(hci_dev, data, size); if (ret) goto err_alloc; ret = platform_device_add(hci_dev); @@ -290,31 +289,16 @@ err_alloc: return ERR_PTR(ret); } -static int bcma_hcd_probe(struct bcma_device *dev) +static int bcma_hcd_usb20_init(struct bcma_hcd_device *usb_dev) { - int err; + struct bcma_device *dev = usb_dev->core; + struct bcma_chipinfo *chipinfo = &dev->bus->chipinfo; u32 ohci_addr; - struct bcma_hcd_device *usb_dev; - struct bcma_chipinfo *chipinfo; - - chipinfo = &dev->bus->chipinfo; - - /* TODO: Probably need checks here; is the core connected? */ + int err; if (dma_set_mask_and_coherent(dev->dma_dev, DMA_BIT_MASK(32))) return -EOPNOTSUPP; - usb_dev = devm_kzalloc(&dev->dev, sizeof(struct bcma_hcd_device), - GFP_KERNEL); - if (!usb_dev) - return -ENOMEM; - - if (dev->dev.of_node) - usb_dev->gpio_desc = devm_get_gpiod_from_child(&dev->dev, "vcc", - &dev->dev.of_node->fwnode); - if (!IS_ERR_OR_NULL(usb_dev->gpio_desc)) - gpiod_direction_output(usb_dev->gpio_desc, 1); - switch (dev->id.id) { case BCMA_CORE_NS_USB20: bcma_hcd_init_chip_arm(dev); @@ -333,17 +317,20 @@ static int bcma_hcd_probe(struct bcma_device *dev) && chipinfo->rev == 0) ohci_addr = 0x18009000; - usb_dev->ohci_dev = bcma_hcd_create_pdev(dev, true, ohci_addr); + usb_dev->ohci_dev = bcma_hcd_create_pdev(dev, "ohci-platform", + ohci_addr, &ohci_pdata, + sizeof(ohci_pdata)); if (IS_ERR(usb_dev->ohci_dev)) return PTR_ERR(usb_dev->ohci_dev); - usb_dev->ehci_dev = bcma_hcd_create_pdev(dev, false, dev->addr); + usb_dev->ehci_dev = bcma_hcd_create_pdev(dev, "ehci-platform", + dev->addr, &ehci_pdata, + sizeof(ehci_pdata)); if (IS_ERR(usb_dev->ehci_dev)) { err = PTR_ERR(usb_dev->ehci_dev); goto err_unregister_ohci_dev; } - bcma_set_drvdata(dev, usb_dev); return 0; err_unregister_ohci_dev: @@ -351,6 +338,40 @@ err_unregister_ohci_dev: return err; } +static int bcma_hcd_probe(struct bcma_device *core) +{ + int err; + struct bcma_hcd_device *usb_dev; + + /* TODO: Probably need checks here; is the core connected? */ + + usb_dev = devm_kzalloc(&core->dev, sizeof(struct bcma_hcd_device), + GFP_KERNEL); + if (!usb_dev) + return -ENOMEM; + usb_dev->core = core; + + if (core->dev.of_node) + usb_dev->gpio_desc = devm_get_gpiod_from_child(&core->dev, "vcc", + &core->dev.of_node->fwnode); + if (!IS_ERR_OR_NULL(usb_dev->gpio_desc)) + gpiod_direction_output(usb_dev->gpio_desc, 1); + + switch (core->id.id) { + case BCMA_CORE_USB20_HOST: + case BCMA_CORE_NS_USB20: + err = bcma_hcd_usb20_init(usb_dev); + if (err) + return err; + break; + default: + return -ENODEV; + } + + bcma_set_drvdata(core, usb_dev); + return 0; +} + static void bcma_hcd_remove(struct bcma_device *dev) { struct bcma_hcd_device *usb_dev = bcma_get_drvdata(dev); diff --git a/drivers/usb/host/ehci-atmel.c b/drivers/usb/host/ehci-atmel.c index be0964a801e8..7440722bfbf0 100644 --- a/drivers/usb/host/ehci-atmel.c +++ b/drivers/usb/host/ehci-atmel.c @@ -185,8 +185,7 @@ static int ehci_atmel_drv_remove(struct platform_device *pdev) return 0; } -#ifdef CONFIG_PM -static int ehci_atmel_drv_suspend(struct device *dev) +static int __maybe_unused ehci_atmel_drv_suspend(struct device *dev) { struct usb_hcd *hcd = dev_get_drvdata(dev); struct atmel_ehci_priv *atmel_ehci = hcd_to_atmel_ehci_priv(hcd); @@ -200,7 +199,7 @@ static int ehci_atmel_drv_suspend(struct device *dev) return 0; } -static int ehci_atmel_drv_resume(struct device *dev) +static int __maybe_unused ehci_atmel_drv_resume(struct device *dev) { struct usb_hcd *hcd = dev_get_drvdata(dev); struct atmel_ehci_priv *atmel_ehci = hcd_to_atmel_ehci_priv(hcd); @@ -208,7 +207,6 @@ static int ehci_atmel_drv_resume(struct device *dev) atmel_start_clock(atmel_ehci); return ehci_resume(hcd, false); } -#endif #ifdef CONFIG_OF static const struct of_device_id atmel_ehci_dt_ids[] = { diff --git a/drivers/usb/host/ehci-dbg.c b/drivers/usb/host/ehci-dbg.c index b7d623f1523c..79d12b2ba3c4 100644 --- a/drivers/usb/host/ehci-dbg.c +++ b/drivers/usb/host/ehci-dbg.c @@ -11,76 +11,73 @@ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* this file is part of ehci-hcd.c */ #ifdef CONFIG_DYNAMIC_DEBUG -/* check the values in the HCSPARAMS register +/* + * check the values in the HCSPARAMS register * (host controller _Structural_ parameters) * see EHCI spec, Table 2-4 for each value */ -static void dbg_hcs_params (struct ehci_hcd *ehci, char *label) +static void dbg_hcs_params(struct ehci_hcd *ehci, char *label) { u32 params = ehci_readl(ehci, &ehci->caps->hcs_params); - ehci_dbg (ehci, + ehci_dbg(ehci, "%s hcs_params 0x%x dbg=%d%s cc=%d pcc=%d%s%s ports=%d\n", label, params, - HCS_DEBUG_PORT (params), - HCS_INDICATOR (params) ? " ind" : "", - HCS_N_CC (params), - HCS_N_PCC (params), - HCS_PORTROUTED (params) ? "" : " ordered", - HCS_PPC (params) ? "" : " !ppc", - HCS_N_PORTS (params) - ); + HCS_DEBUG_PORT(params), + HCS_INDICATOR(params) ? " ind" : "", + HCS_N_CC(params), + HCS_N_PCC(params), + HCS_PORTROUTED(params) ? "" : " ordered", + HCS_PPC(params) ? "" : " !ppc", + HCS_N_PORTS(params)); /* Port routing, per EHCI 0.95 Spec, Section 2.2.5 */ - if (HCS_PORTROUTED (params)) { + if (HCS_PORTROUTED(params)) { int i; - char buf [46], tmp [7], byte; + char buf[46], tmp[7], byte; buf[0] = 0; - for (i = 0; i < HCS_N_PORTS (params); i++) { - // FIXME MIPS won't readb() ... - byte = readb (&ehci->caps->portroute[(i>>1)]); + for (i = 0; i < HCS_N_PORTS(params); i++) { + /* FIXME MIPS won't readb() ... */ + byte = readb(&ehci->caps->portroute[(i >> 1)]); sprintf(tmp, "%d ", - ((i & 0x1) ? ((byte)&0xf) : ((byte>>4)&0xf))); + (i & 0x1) ? byte & 0xf : (byte >> 4) & 0xf); strcat(buf, tmp); } - ehci_dbg (ehci, "%s portroute %s\n", - label, buf); + ehci_dbg(ehci, "%s portroute %s\n", label, buf); } } #else -static inline void dbg_hcs_params (struct ehci_hcd *ehci, char *label) {} +static inline void dbg_hcs_params(struct ehci_hcd *ehci, char *label) {} #endif #ifdef CONFIG_DYNAMIC_DEBUG -/* check the values in the HCCPARAMS register +/* + * check the values in the HCCPARAMS register * (host controller _Capability_ parameters) * see EHCI Spec, Table 2-5 for each value - * */ -static void dbg_hcc_params (struct ehci_hcd *ehci, char *label) + */ +static void dbg_hcc_params(struct ehci_hcd *ehci, char *label) { u32 params = ehci_readl(ehci, &ehci->caps->hcc_params); - if (HCC_ISOC_CACHE (params)) { - ehci_dbg (ehci, + if (HCC_ISOC_CACHE(params)) { + ehci_dbg(ehci, "%s hcc_params %04x caching frame %s%s%s\n", label, params, HCC_PGM_FRAMELISTLEN(params) ? "256/512/1024" : "1024", HCC_CANPARK(params) ? " park" : "", HCC_64BIT_ADDR(params) ? " 64 bit addr" : ""); } else { - ehci_dbg (ehci, + ehci_dbg(ehci, "%s hcc_params %04x thresh %d uframes %s%s%s%s%s%s%s\n", label, params, @@ -97,21 +94,21 @@ static void dbg_hcc_params (struct ehci_hcd *ehci, char *label) } #else -static inline void dbg_hcc_params (struct ehci_hcd *ehci, char *label) {} +static inline void dbg_hcc_params(struct ehci_hcd *ehci, char *label) {} #endif #ifdef CONFIG_DYNAMIC_DEBUG static void __maybe_unused -dbg_qtd (const char *label, struct ehci_hcd *ehci, struct ehci_qtd *qtd) +dbg_qtd(const char *label, struct ehci_hcd *ehci, struct ehci_qtd *qtd) { ehci_dbg(ehci, "%s td %p n%08x %08x t%08x p0=%08x\n", label, qtd, hc32_to_cpup(ehci, &qtd->hw_next), hc32_to_cpup(ehci, &qtd->hw_alt_next), hc32_to_cpup(ehci, &qtd->hw_token), - hc32_to_cpup(ehci, &qtd->hw_buf [0])); - if (qtd->hw_buf [1]) + hc32_to_cpup(ehci, &qtd->hw_buf[0])); + if (qtd->hw_buf[1]) ehci_dbg(ehci, " p1=%08x p2=%08x p3=%08x p4=%08x\n", hc32_to_cpup(ehci, &qtd->hw_buf[1]), hc32_to_cpup(ehci, &qtd->hw_buf[2]), @@ -120,22 +117,22 @@ dbg_qtd (const char *label, struct ehci_hcd *ehci, struct ehci_qtd *qtd) } static void __maybe_unused -dbg_qh (const char *label, struct ehci_hcd *ehci, struct ehci_qh *qh) +dbg_qh(const char *label, struct ehci_hcd *ehci, struct ehci_qh *qh) { struct ehci_qh_hw *hw = qh->hw; - ehci_dbg (ehci, "%s qh %p n%08x info %x %x qtd %x\n", label, + ehci_dbg(ehci, "%s qh %p n%08x info %x %x qtd %x\n", label, qh, hw->hw_next, hw->hw_info1, hw->hw_info2, hw->hw_current); dbg_qtd("overlay", ehci, (struct ehci_qtd *) &hw->hw_qtd_next); } static void __maybe_unused -dbg_itd (const char *label, struct ehci_hcd *ehci, struct ehci_itd *itd) +dbg_itd(const char *label, struct ehci_hcd *ehci, struct ehci_itd *itd) { - ehci_dbg (ehci, "%s [%d] itd %p, next %08x, urb %p\n", + ehci_dbg(ehci, "%s [%d] itd %p, next %08x, urb %p\n", label, itd->frame, itd, hc32_to_cpu(ehci, itd->hw_next), itd->urb); - ehci_dbg (ehci, + ehci_dbg(ehci, " trans: %08x %08x %08x %08x %08x %08x %08x %08x\n", hc32_to_cpu(ehci, itd->hw_transaction[0]), hc32_to_cpu(ehci, itd->hw_transaction[1]), @@ -145,7 +142,7 @@ dbg_itd (const char *label, struct ehci_hcd *ehci, struct ehci_itd *itd) hc32_to_cpu(ehci, itd->hw_transaction[5]), hc32_to_cpu(ehci, itd->hw_transaction[6]), hc32_to_cpu(ehci, itd->hw_transaction[7])); - ehci_dbg (ehci, + ehci_dbg(ehci, " buf: %08x %08x %08x %08x %08x %08x %08x\n", hc32_to_cpu(ehci, itd->hw_bufp[0]), hc32_to_cpu(ehci, itd->hw_bufp[1]), @@ -154,19 +151,19 @@ dbg_itd (const char *label, struct ehci_hcd *ehci, struct ehci_itd *itd) hc32_to_cpu(ehci, itd->hw_bufp[4]), hc32_to_cpu(ehci, itd->hw_bufp[5]), hc32_to_cpu(ehci, itd->hw_bufp[6])); - ehci_dbg (ehci, " index: %d %d %d %d %d %d %d %d\n", + ehci_dbg(ehci, " index: %d %d %d %d %d %d %d %d\n", itd->index[0], itd->index[1], itd->index[2], itd->index[3], itd->index[4], itd->index[5], itd->index[6], itd->index[7]); } static void __maybe_unused -dbg_sitd (const char *label, struct ehci_hcd *ehci, struct ehci_sitd *sitd) +dbg_sitd(const char *label, struct ehci_hcd *ehci, struct ehci_sitd *sitd) { - ehci_dbg (ehci, "%s [%d] sitd %p, next %08x, urb %p\n", + ehci_dbg(ehci, "%s [%d] sitd %p, next %08x, urb %p\n", label, sitd->frame, sitd, hc32_to_cpu(ehci, sitd->hw_next), sitd->urb); - ehci_dbg (ehci, + ehci_dbg(ehci, " addr %08x sched %04x result %08x buf %08x %08x\n", hc32_to_cpu(ehci, sitd->hw_fullspeed_ep), hc32_to_cpu(ehci, sitd->hw_uframe), @@ -176,11 +173,11 @@ dbg_sitd (const char *label, struct ehci_hcd *ehci, struct ehci_sitd *sitd) } static int __maybe_unused -dbg_status_buf (char *buf, unsigned len, const char *label, u32 status) +dbg_status_buf(char *buf, unsigned len, const char *label, u32 status) { - return scnprintf (buf, len, + return scnprintf(buf, len, "%s%sstatus %04x%s%s%s%s%s%s%s%s%s%s%s", - label, label [0] ? " " : "", status, + label, label[0] ? " " : "", status, (status & STS_PPCE_MASK) ? " PPCE" : "", (status & STS_ASS) ? " Async" : "", (status & STS_PSS) ? " Periodic" : "", @@ -191,79 +188,83 @@ dbg_status_buf (char *buf, unsigned len, const char *label, u32 status) (status & STS_FLR) ? " FLR" : "", (status & STS_PCD) ? " PCD" : "", (status & STS_ERR) ? " ERR" : "", - (status & STS_INT) ? " INT" : "" - ); + (status & STS_INT) ? " INT" : ""); } static int __maybe_unused -dbg_intr_buf (char *buf, unsigned len, const char *label, u32 enable) +dbg_intr_buf(char *buf, unsigned len, const char *label, u32 enable) { - return scnprintf (buf, len, + return scnprintf(buf, len, "%s%sintrenable %02x%s%s%s%s%s%s%s", - label, label [0] ? " " : "", enable, + label, label[0] ? " " : "", enable, (enable & STS_PPCE_MASK) ? " PPCE" : "", (enable & STS_IAA) ? " IAA" : "", (enable & STS_FATAL) ? " FATAL" : "", (enable & STS_FLR) ? " FLR" : "", (enable & STS_PCD) ? " PCD" : "", (enable & STS_ERR) ? " ERR" : "", - (enable & STS_INT) ? " INT" : "" - ); + (enable & STS_INT) ? " INT" : ""); } -static const char *const fls_strings [] = - { "1024", "512", "256", "??" }; +static const char *const fls_strings[] = { "1024", "512", "256", "??" }; static int -dbg_command_buf (char *buf, unsigned len, const char *label, u32 command) +dbg_command_buf(char *buf, unsigned len, const char *label, u32 command) { - return scnprintf (buf, len, + return scnprintf(buf, len, "%s%scommand %07x %s%s%s%s%s%s=%d ithresh=%d%s%s%s%s " "period=%s%s %s", - label, label [0] ? " " : "", command, + label, label[0] ? " " : "", command, (command & CMD_HIRD) ? " HIRD" : "", (command & CMD_PPCEE) ? " PPCEE" : "", (command & CMD_FSP) ? " FSP" : "", (command & CMD_ASPE) ? " ASPE" : "", (command & CMD_PSPE) ? " PSPE" : "", (command & CMD_PARK) ? " park" : "(park)", - CMD_PARK_CNT (command), + CMD_PARK_CNT(command), (command >> 16) & 0x3f, (command & CMD_LRESET) ? " LReset" : "", (command & CMD_IAAD) ? " IAAD" : "", (command & CMD_ASE) ? " Async" : "", (command & CMD_PSE) ? " Periodic" : "", - fls_strings [(command >> 2) & 0x3], + fls_strings[(command >> 2) & 0x3], (command & CMD_RESET) ? " Reset" : "", - (command & CMD_RUN) ? "RUN" : "HALT" - ); + (command & CMD_RUN) ? "RUN" : "HALT"); } static int -dbg_port_buf (char *buf, unsigned len, const char *label, int port, u32 status) +dbg_port_buf(char *buf, unsigned len, const char *label, int port, u32 status) { char *sig; /* signaling state */ switch (status & (3 << 10)) { - case 0 << 10: sig = "se0"; break; - case 1 << 10: sig = "k"; break; /* low speed */ - case 2 << 10: sig = "j"; break; - default: sig = "?"; break; + case 0 << 10: + sig = "se0"; + break; + case 1 << 10: /* low speed */ + sig = "k"; + break; + case 2 << 10: + sig = "j"; + break; + default: + sig = "?"; + break; } - return scnprintf (buf, len, + return scnprintf(buf, len, "%s%sport:%d status %06x %d %s%s%s%s%s%s " "sig=%s%s%s%s%s%s%s%s%s%s%s", - label, label [0] ? " " : "", port, status, - status>>25,/*device address */ - (status & PORT_SSTS)>>23 == PORTSC_SUSPEND_STS_ACK ? + label, label[0] ? " " : "", port, status, + status >> 25, /*device address */ + (status & PORT_SSTS) >> 23 == PORTSC_SUSPEND_STS_ACK ? " ACK" : "", - (status & PORT_SSTS)>>23 == PORTSC_SUSPEND_STS_NYET ? + (status & PORT_SSTS) >> 23 == PORTSC_SUSPEND_STS_NYET ? " NYET" : "", - (status & PORT_SSTS)>>23 == PORTSC_SUSPEND_STS_STALL ? + (status & PORT_SSTS) >> 23 == PORTSC_SUSPEND_STS_STALL ? " STALL" : "", - (status & PORT_SSTS)>>23 == PORTSC_SUSPEND_STS_ERR ? + (status & PORT_SSTS) >> 23 == PORTSC_SUSPEND_STS_ERR ? " ERR" : "", (status & PORT_POWER) ? " POWER" : "", (status & PORT_OWNER) ? " OWNER" : "", @@ -282,52 +283,68 @@ dbg_port_buf (char *buf, unsigned len, const char *label, int port, u32 status) #else static inline void __maybe_unused -dbg_qh (char *label, struct ehci_hcd *ehci, struct ehci_qh *qh) +dbg_qh(char *label, struct ehci_hcd *ehci, struct ehci_qh *qh) {} static inline int __maybe_unused -dbg_status_buf (char *buf, unsigned len, const char *label, u32 status) -{ return 0; } +dbg_status_buf(char *buf, unsigned len, const char *label, u32 status) +{ + return 0; +} static inline int __maybe_unused -dbg_command_buf (char *buf, unsigned len, const char *label, u32 command) -{ return 0; } +dbg_command_buf(char *buf, unsigned len, const char *label, u32 command) +{ + return 0; +} static inline int __maybe_unused -dbg_intr_buf (char *buf, unsigned len, const char *label, u32 enable) -{ return 0; } +dbg_intr_buf(char *buf, unsigned len, const char *label, u32 enable) +{ + return 0; +} static inline int __maybe_unused -dbg_port_buf (char *buf, unsigned len, const char *label, int port, u32 status) -{ return 0; } +dbg_port_buf(char *buf, unsigned len, const char *label, int port, u32 status) +{ + return 0; +} #endif /* CONFIG_DYNAMIC_DEBUG */ -/* functions have the "wrong" filename when they're output... */ -#define dbg_status(ehci, label, status) { \ - char _buf [80]; \ - dbg_status_buf (_buf, sizeof _buf, label, status); \ - ehci_dbg (ehci, "%s\n", _buf); \ +static inline void +dbg_status(struct ehci_hcd *ehci, const char *label, u32 status) +{ + char buf[80]; + + dbg_status_buf(buf, sizeof(buf), label, status); + ehci_dbg(ehci, "%s\n", buf); } -#define dbg_cmd(ehci, label, command) { \ - char _buf [80]; \ - dbg_command_buf (_buf, sizeof _buf, label, command); \ - ehci_dbg (ehci, "%s\n", _buf); \ +static inline void +dbg_cmd(struct ehci_hcd *ehci, const char *label, u32 command) +{ + char buf[80]; + + dbg_command_buf(buf, sizeof(buf), label, command); + ehci_dbg(ehci, "%s\n", buf); } -#define dbg_port(ehci, label, port, status) { \ - char _buf [80]; \ - dbg_port_buf (_buf, sizeof _buf, label, port, status); \ - ehci_dbg (ehci, "%s\n", _buf); \ +static inline void +dbg_port(struct ehci_hcd *ehci, const char *label, int port, u32 status) +{ + char buf[80]; + + dbg_port_buf(buf, sizeof(buf), label, port, status); + ehci_dbg(ehci, "%s\n", buf); } /*-------------------------------------------------------------------------*/ -#ifdef STUB_DEBUG_FILES +#ifndef CONFIG_DYNAMIC_DEBUG -static inline void create_debug_files (struct ehci_hcd *bus) { } -static inline void remove_debug_files (struct ehci_hcd *bus) { } +static inline void create_debug_files(struct ehci_hcd *bus) { } +static inline void remove_debug_files(struct ehci_hcd *bus) { } #else @@ -348,6 +365,7 @@ static const struct file_operations debug_async_fops = { .release = debug_close, .llseek = default_llseek, }; + static const struct file_operations debug_bandwidth_fops = { .owner = THIS_MODULE, .open = debug_bandwidth_open, @@ -355,6 +373,7 @@ static const struct file_operations debug_bandwidth_fops = { .release = debug_close, .llseek = default_llseek, }; + static const struct file_operations debug_periodic_fops = { .owner = THIS_MODULE, .open = debug_periodic_open, @@ -362,6 +381,7 @@ static const struct file_operations debug_periodic_fops = { .release = debug_close, .llseek = default_llseek, }; + static const struct file_operations debug_registers_fops = { .owner = THIS_MODULE, .open = debug_registers_open, @@ -381,13 +401,19 @@ struct debug_buffer { size_t alloc_size; }; -#define speed_char(info1) ({ char tmp; \ - switch (info1 & (3 << 12)) { \ - case QH_FULL_SPEED: tmp = 'f'; break; \ - case QH_LOW_SPEED: tmp = 'l'; break; \ - case QH_HIGH_SPEED: tmp = 'h'; break; \ - default: tmp = '?'; break; \ - } tmp; }) +static inline char speed_char(u32 info1) +{ + switch (info1 & (3 << 12)) { + case QH_FULL_SPEED: + return 'f'; + case QH_LOW_SPEED: + return 'l'; + case QH_HIGH_SPEED: + return 'h'; + default: + return '?'; + } +} static inline char token_mark(struct ehci_hcd *ehci, __hc32 token) { @@ -397,18 +423,14 @@ static inline char token_mark(struct ehci_hcd *ehci, __hc32 token) return '*'; if (v & QTD_STS_HALT) return '-'; - if (!IS_SHORT_READ (v)) + if (!IS_SHORT_READ(v)) return ' '; /* tries to advance through hw_alt_next */ return '/'; } -static void qh_lines ( - struct ehci_hcd *ehci, - struct ehci_qh *qh, - char **nextp, - unsigned *sizep -) +static void qh_lines(struct ehci_hcd *ehci, struct ehci_qh *qh, + char **nextp, unsigned *sizep) { u32 scratch; u32 hw_curr; @@ -435,7 +457,7 @@ static void qh_lines ( } scratch = hc32_to_cpup(ehci, &hw->hw_info1); hw_curr = (mark == '*') ? hc32_to_cpup(ehci, &hw->hw_current) : 0; - temp = scnprintf (next, size, + temp = scnprintf(next, size, "qh/%p dev%d %cs ep%d %08x %08x (%08x%c %s nak%d)" " [cur %08x next %08x buf[0] %08x]", qh, scratch & 0x007f, @@ -453,46 +475,52 @@ static void qh_lines ( next += temp; /* hc may be modifying the list as we read it ... */ - list_for_each (entry, &qh->qtd_list) { - td = list_entry (entry, struct ehci_qtd, qtd_list); + list_for_each(entry, &qh->qtd_list) { + char *type; + + td = list_entry(entry, struct ehci_qtd, qtd_list); scratch = hc32_to_cpup(ehci, &td->hw_token); mark = ' '; - if (hw_curr == td->qtd_dma) + if (hw_curr == td->qtd_dma) { mark = '*'; - else if (hw->hw_qtd_next == cpu_to_hc32(ehci, td->qtd_dma)) + } else if (hw->hw_qtd_next == cpu_to_hc32(ehci, td->qtd_dma)) { mark = '+'; - else if (QTD_LENGTH (scratch)) { + } else if (QTD_LENGTH(scratch)) { if (td->hw_alt_next == ehci->async->hw->hw_alt_next) mark = '#'; else if (td->hw_alt_next != list_end) mark = '/'; } - temp = snprintf (next, size, + switch ((scratch >> 8) & 0x03) { + case 0: + type = "out"; + break; + case 1: + type = "in"; + break; + case 2: + type = "setup"; + break; + default: + type = "?"; + break; + } + temp = scnprintf(next, size, "\n\t%p%c%s len=%d %08x urb %p" " [td %08x buf[0] %08x]", - td, mark, ({ char *tmp; - switch ((scratch>>8)&0x03) { - case 0: tmp = "out"; break; - case 1: tmp = "in"; break; - case 2: tmp = "setup"; break; - default: tmp = "?"; break; - } tmp;}), + td, mark, type, (scratch >> 16) & 0x7fff, scratch, td->urb, (u32) td->qtd_dma, hc32_to_cpup(ehci, &td->hw_buf[0])); - if (size < temp) - temp = size; size -= temp; next += temp; if (temp == size) goto done; } - temp = snprintf (next, size, "\n"); - if (size < temp) - temp = size; + temp = scnprintf(next, size, "\n"); size -= temp; next += temp; @@ -511,19 +539,20 @@ static ssize_t fill_async_buffer(struct debug_buffer *buf) struct ehci_qh *qh; hcd = bus_to_hcd(buf->bus); - ehci = hcd_to_ehci (hcd); + ehci = hcd_to_ehci(hcd); next = buf->output_buf; size = buf->alloc_size; *next = 0; - /* dumps a snapshot of the async schedule. + /* + * dumps a snapshot of the async schedule. * usually empty except for long-term bulk reads, or head. * one QH per line, and TDs we know about */ - spin_lock_irqsave (&ehci->lock, flags); + spin_lock_irqsave(&ehci->lock, flags); for (qh = ehci->async->qh_next.qh; size > 0 && qh; qh = qh->qh_next.qh) - qh_lines (ehci, qh, &next, &size); + qh_lines(ehci, qh, &next, &size); if (!list_empty(&ehci->async_unlink) && size > 0) { temp = scnprintf(next, size, "\nunlink =\n"); size -= temp; @@ -535,7 +564,7 @@ static ssize_t fill_async_buffer(struct debug_buffer *buf) qh_lines(ehci, qh, &next, &size); } } - spin_unlock_irqrestore (&ehci->lock, flags); + spin_unlock_irqrestore(&ehci->lock, flags); return strlen(buf->output_buf); } @@ -623,6 +652,33 @@ static ssize_t fill_bandwidth_buffer(struct debug_buffer *buf) return next - buf->output_buf; } +static unsigned output_buf_tds_dir(char *buf, struct ehci_hcd *ehci, + struct ehci_qh_hw *hw, struct ehci_qh *qh, unsigned size) +{ + u32 scratch = hc32_to_cpup(ehci, &hw->hw_info1); + struct ehci_qtd *qtd; + char *type = ""; + unsigned temp = 0; + + /* count tds, get ep direction */ + list_for_each_entry(qtd, &qh->qtd_list, qtd_list) { + temp++; + switch ((hc32_to_cpu(ehci, qtd->hw_token) >> 8) & 0x03) { + case 0: + type = "out"; + continue; + case 1: + type = "in"; + continue; + } + } + + return scnprintf(buf, size, " (%c%d ep%d%s [%d/%d] q%d p%d)", + speed_char(scratch), scratch & 0x007f, + (scratch >> 8) & 0x000f, type, qh->ps.usecs, + qh->ps.c_usecs, temp, 0x7ff & (scratch >> 16)); +} + #define DBG_SCHED_LIMIT 64 static ssize_t fill_periodic_buffer(struct debug_buffer *buf) { @@ -635,31 +691,32 @@ static ssize_t fill_periodic_buffer(struct debug_buffer *buf) unsigned i; __hc32 tag; - seen = kmalloc(DBG_SCHED_LIMIT * sizeof *seen, GFP_ATOMIC); + seen = kmalloc_array(DBG_SCHED_LIMIT, sizeof(*seen), GFP_ATOMIC); if (!seen) return 0; seen_count = 0; hcd = bus_to_hcd(buf->bus); - ehci = hcd_to_ehci (hcd); + ehci = hcd_to_ehci(hcd); next = buf->output_buf; size = buf->alloc_size; - temp = scnprintf (next, size, "size = %d\n", ehci->periodic_size); + temp = scnprintf(next, size, "size = %d\n", ehci->periodic_size); size -= temp; next += temp; - /* dump a snapshot of the periodic schedule. + /* + * dump a snapshot of the periodic schedule. * iso changes, interrupt usually doesn't. */ - spin_lock_irqsave (&ehci->lock, flags); + spin_lock_irqsave(&ehci->lock, flags); for (i = 0; i < ehci->periodic_size; i++) { - p = ehci->pshadow [i]; - if (likely (!p.ptr)) + p = ehci->pshadow[i]; + if (likely(!p.ptr)) continue; - tag = Q_NEXT_TYPE(ehci, ehci->periodic [i]); + tag = Q_NEXT_TYPE(ehci, ehci->periodic[i]); - temp = scnprintf (next, size, "%4d: ", i); + temp = scnprintf(next, size, "%4d: ", i); size -= temp; next += temp; @@ -669,7 +726,7 @@ static ssize_t fill_periodic_buffer(struct debug_buffer *buf) switch (hc32_to_cpu(ehci, tag)) { case Q_TYPE_QH: hw = p.qh->hw; - temp = scnprintf (next, size, " qh%d-%04x/%p", + temp = scnprintf(next, size, " qh%d-%04x/%p", p.qh->ps.period, hc32_to_cpup(ehci, &hw->hw_info2) @@ -680,10 +737,10 @@ static ssize_t fill_periodic_buffer(struct debug_buffer *buf) next += temp; /* don't repeat what follows this qh */ for (temp = 0; temp < seen_count; temp++) { - if (seen [temp].ptr != p.ptr) + if (seen[temp].ptr != p.ptr) continue; if (p.qh->qh_next.ptr) { - temp = scnprintf (next, size, + temp = scnprintf(next, size, " ..."); size -= temp; next += temp; @@ -692,58 +749,32 @@ static ssize_t fill_periodic_buffer(struct debug_buffer *buf) } /* show more info the first time around */ if (temp == seen_count) { - u32 scratch = hc32_to_cpup(ehci, - &hw->hw_info1); - struct ehci_qtd *qtd; - char *type = ""; - - /* count tds, get ep direction */ - temp = 0; - list_for_each_entry (qtd, - &p.qh->qtd_list, - qtd_list) { - temp++; - switch (0x03 & (hc32_to_cpu( - ehci, - qtd->hw_token) >> 8)) { - case 0: type = "out"; continue; - case 1: type = "in"; continue; - } - } - - temp = scnprintf (next, size, - " (%c%d ep%d%s " - "[%d/%d] q%d p%d)", - speed_char (scratch), - scratch & 0x007f, - (scratch >> 8) & 0x000f, type, - p.qh->ps.usecs, - p.qh->ps.c_usecs, - temp, - 0x7ff & (scratch >> 16)); + temp = output_buf_tds_dir(next, ehci, + hw, p.qh, size); if (seen_count < DBG_SCHED_LIMIT) - seen [seen_count++].qh = p.qh; - } else + seen[seen_count++].qh = p.qh; + } else { temp = 0; + } tag = Q_NEXT_TYPE(ehci, hw->hw_next); p = p.qh->qh_next; break; case Q_TYPE_FSTN: - temp = scnprintf (next, size, + temp = scnprintf(next, size, " fstn-%8x/%p", p.fstn->hw_prev, p.fstn); tag = Q_NEXT_TYPE(ehci, p.fstn->hw_next); p = p.fstn->fstn_next; break; case Q_TYPE_ITD: - temp = scnprintf (next, size, + temp = scnprintf(next, size, " itd/%p", p.itd); tag = Q_NEXT_TYPE(ehci, p.itd->hw_next); p = p.itd->itd_next; break; case Q_TYPE_SITD: - temp = scnprintf (next, size, + temp = scnprintf(next, size, " sitd%d-%04x/%p", p.sitd->stream->ps.period, hc32_to_cpup(ehci, &p.sitd->hw_uframe) @@ -757,12 +788,12 @@ static ssize_t fill_periodic_buffer(struct debug_buffer *buf) next += temp; } while (p.ptr); - temp = scnprintf (next, size, "\n"); + temp = scnprintf(next, size, "\n"); size -= temp; next += temp; } - spin_unlock_irqrestore (&ehci->lock, flags); - kfree (seen); + spin_unlock_irqrestore(&ehci->lock, flags); + kfree(seen); return buf->alloc_size - size; } @@ -789,19 +820,19 @@ static ssize_t fill_registers_buffer(struct debug_buffer *buf) struct ehci_hcd *ehci; unsigned long flags; unsigned temp, size, i; - char *next, scratch [80]; - static char fmt [] = "%*s\n"; - static char label [] = ""; + char *next, scratch[80]; + static char fmt[] = "%*s\n"; + static char label[] = ""; hcd = bus_to_hcd(buf->bus); - ehci = hcd_to_ehci (hcd); + ehci = hcd_to_ehci(hcd); next = buf->output_buf; size = buf->alloc_size; - spin_lock_irqsave (&ehci->lock, flags); + spin_lock_irqsave(&ehci->lock, flags); if (!HCD_HW_ACCESSIBLE(hcd)) { - size = scnprintf (next, size, + size = scnprintf(next, size, "bus %s, device %s\n" "%s\n" "SUSPENDED (no register access)\n", @@ -813,7 +844,7 @@ static ssize_t fill_registers_buffer(struct debug_buffer *buf) /* Capability Registers */ i = HC_VERSION(ehci, ehci_readl(ehci, &ehci->caps->hc_capbase)); - temp = scnprintf (next, size, + temp = scnprintf(next, size, "bus %s, device %s\n" "%s\n" "EHCI %x.%02x, rh state %s\n", @@ -829,16 +860,16 @@ static ssize_t fill_registers_buffer(struct debug_buffer *buf) if (dev_is_pci(hcd->self.controller)) { struct pci_dev *pdev; u32 offset, cap, cap2; - unsigned count = 256/4; + unsigned count = 256 / 4; pdev = to_pci_dev(ehci_to_hcd(ehci)->self.controller); offset = HCC_EXT_CAPS(ehci_readl(ehci, &ehci->caps->hcc_params)); while (offset && count--) { - pci_read_config_dword (pdev, offset, &cap); + pci_read_config_dword(pdev, offset, &cap); switch (cap & 0xff) { case 1: - temp = scnprintf (next, size, + temp = scnprintf(next, size, "ownership %08x%s%s\n", cap, (cap & (1 << 24)) ? " linux" : "", (cap & (1 << 16)) ? " firmware" : ""); @@ -846,8 +877,8 @@ static ssize_t fill_registers_buffer(struct debug_buffer *buf) next += temp; offset += 4; - pci_read_config_dword (pdev, offset, &cap2); - temp = scnprintf (next, size, + pci_read_config_dword(pdev, offset, &cap2); + temp = scnprintf(next, size, "SMI sts/enable 0x%08x\n", cap2); size -= temp; next += temp; @@ -863,50 +894,50 @@ static ssize_t fill_registers_buffer(struct debug_buffer *buf) } #endif - // FIXME interpret both types of params + /* FIXME interpret both types of params */ i = ehci_readl(ehci, &ehci->caps->hcs_params); - temp = scnprintf (next, size, "structural params 0x%08x\n", i); + temp = scnprintf(next, size, "structural params 0x%08x\n", i); size -= temp; next += temp; i = ehci_readl(ehci, &ehci->caps->hcc_params); - temp = scnprintf (next, size, "capability params 0x%08x\n", i); + temp = scnprintf(next, size, "capability params 0x%08x\n", i); size -= temp; next += temp; /* Operational Registers */ - temp = dbg_status_buf (scratch, sizeof scratch, label, + temp = dbg_status_buf(scratch, sizeof(scratch), label, ehci_readl(ehci, &ehci->regs->status)); - temp = scnprintf (next, size, fmt, temp, scratch); + temp = scnprintf(next, size, fmt, temp, scratch); size -= temp; next += temp; - temp = dbg_command_buf (scratch, sizeof scratch, label, + temp = dbg_command_buf(scratch, sizeof(scratch), label, ehci_readl(ehci, &ehci->regs->command)); - temp = scnprintf (next, size, fmt, temp, scratch); + temp = scnprintf(next, size, fmt, temp, scratch); size -= temp; next += temp; - temp = dbg_intr_buf (scratch, sizeof scratch, label, + temp = dbg_intr_buf(scratch, sizeof(scratch), label, ehci_readl(ehci, &ehci->regs->intr_enable)); - temp = scnprintf (next, size, fmt, temp, scratch); + temp = scnprintf(next, size, fmt, temp, scratch); size -= temp; next += temp; - temp = scnprintf (next, size, "uframe %04x\n", + temp = scnprintf(next, size, "uframe %04x\n", ehci_read_frame_index(ehci)); size -= temp; next += temp; - for (i = 1; i <= HCS_N_PORTS (ehci->hcs_params); i++) { - temp = dbg_port_buf (scratch, sizeof scratch, label, i, + for (i = 1; i <= HCS_N_PORTS(ehci->hcs_params); i++) { + temp = dbg_port_buf(scratch, sizeof(scratch), label, i, ehci_readl(ehci, &ehci->regs->port_status[i - 1])); - temp = scnprintf (next, size, fmt, temp, scratch); + temp = scnprintf(next, size, fmt, temp, scratch); size -= temp; next += temp; if (i == HCS_DEBUG_PORT(ehci->hcs_params) && ehci->debug) { - temp = scnprintf (next, size, + temp = scnprintf(next, size, " debug control %08x\n", ehci_readl(ehci, &ehci->debug->control)); @@ -924,31 +955,31 @@ static ssize_t fill_registers_buffer(struct debug_buffer *buf) } #ifdef EHCI_STATS - temp = scnprintf (next, size, + temp = scnprintf(next, size, "irq normal %ld err %ld iaa %ld (lost %ld)\n", ehci->stats.normal, ehci->stats.error, ehci->stats.iaa, ehci->stats.lost_iaa); size -= temp; next += temp; - temp = scnprintf (next, size, "complete %ld unlink %ld\n", + temp = scnprintf(next, size, "complete %ld unlink %ld\n", ehci->stats.complete, ehci->stats.unlink); size -= temp; next += temp; #endif done: - spin_unlock_irqrestore (&ehci->lock, flags); + spin_unlock_irqrestore(&ehci->lock, flags); return buf->alloc_size - size; } static struct debug_buffer *alloc_buffer(struct usb_bus *bus, - ssize_t (*fill_func)(struct debug_buffer *)) + ssize_t (*fill_func)(struct debug_buffer *)) { struct debug_buffer *buf; - buf = kzalloc(sizeof(struct debug_buffer), GFP_KERNEL); + buf = kzalloc(sizeof(*buf), GFP_KERNEL); if (buf) { buf->bus = bus; @@ -984,7 +1015,7 @@ out: } static ssize_t debug_output(struct file *file, char __user *user_buf, - size_t len, loff_t *offset) + size_t len, loff_t *offset) { struct debug_buffer *buf = file->private_data; int ret = 0; @@ -1004,7 +1035,6 @@ static ssize_t debug_output(struct file *file, char __user *user_buf, out: return ret; - } static int debug_close(struct inode *inode, struct file *file) @@ -1037,11 +1067,12 @@ static int debug_bandwidth_open(struct inode *inode, struct file *file) static int debug_periodic_open(struct inode *inode, struct file *file) { struct debug_buffer *buf; + buf = alloc_buffer(inode->i_private, fill_periodic_buffer); if (!buf) return -ENOMEM; - buf->alloc_size = (sizeof(void *) == 4 ? 6 : 8)*PAGE_SIZE; + buf->alloc_size = (sizeof(void *) == 4 ? 6 : 8) * PAGE_SIZE; file->private_data = buf; return 0; } @@ -1054,7 +1085,7 @@ static int debug_registers_open(struct inode *inode, struct file *file) return file->private_data ? 0 : -ENOMEM; } -static inline void create_debug_files (struct ehci_hcd *ehci) +static inline void create_debug_files(struct ehci_hcd *ehci) { struct usb_bus *bus = &ehci_to_hcd(ehci)->self; @@ -1084,9 +1115,9 @@ file_error: debugfs_remove_recursive(ehci->debug_dir); } -static inline void remove_debug_files (struct ehci_hcd *ehci) +static inline void remove_debug_files(struct ehci_hcd *ehci) { debugfs_remove_recursive(ehci->debug_dir); } -#endif /* STUB_DEBUG_FILES */ +#endif /* CONFIG_DYNAMIC_DEBUG */ diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c index 3b6eb219de1a..9f5ffb629973 100644 --- a/drivers/usb/host/ehci-fsl.c +++ b/drivers/usb/host/ehci-fsl.c @@ -35,6 +35,7 @@ #include <linux/usb/otg.h> #include <linux/platform_device.h> #include <linux/fsl_devices.h> +#include <linux/of_platform.h> #include "ehci.h" #include "ehci-fsl.h" @@ -241,7 +242,8 @@ static int ehci_fsl_setup_phy(struct usb_hcd *hcd, * to portsc */ if (pdata->check_phy_clk_valid) { - if (!(in_be32(non_ehci + FSL_SOC_USB_CTRL) & PHY_CLK_VALID)) { + if (!(ioread32be(non_ehci + FSL_SOC_USB_CTRL) & + PHY_CLK_VALID)) { dev_warn(hcd->self.controller, "USB PHY clock invalid\n"); return -EINVAL; @@ -273,9 +275,11 @@ static int ehci_fsl_usb_setup(struct ehci_hcd *ehci) /* Setup Snooping for all the 4GB space */ /* SNOOP1 starts from 0x0, size 2G */ - out_be32(non_ehci + FSL_SOC_USB_SNOOP1, 0x0 | SNOOP_SIZE_2GB); + iowrite32be(0x0 | SNOOP_SIZE_2GB, + non_ehci + FSL_SOC_USB_SNOOP1); /* SNOOP2 starts from 0x80000000, size 2G */ - out_be32(non_ehci + FSL_SOC_USB_SNOOP2, 0x80000000 | SNOOP_SIZE_2GB); + iowrite32be(0x80000000 | SNOOP_SIZE_2GB, + non_ehci + FSL_SOC_USB_SNOOP2); } /* Deal with USB erratum A-005275 */ @@ -309,13 +313,13 @@ static int ehci_fsl_usb_setup(struct ehci_hcd *ehci) if (pdata->have_sysif_regs) { #ifdef CONFIG_FSL_SOC_BOOKE - out_be32(non_ehci + FSL_SOC_USB_PRICTRL, 0x00000008); - out_be32(non_ehci + FSL_SOC_USB_AGECNTTHRSH, 0x00000080); + iowrite32be(0x00000008, non_ehci + FSL_SOC_USB_PRICTRL); + iowrite32be(0x00000080, non_ehci + FSL_SOC_USB_AGECNTTHRSH); #else - out_be32(non_ehci + FSL_SOC_USB_PRICTRL, 0x0000000c); - out_be32(non_ehci + FSL_SOC_USB_AGECNTTHRSH, 0x00000040); + iowrite32be(0x0000000c, non_ehci + FSL_SOC_USB_PRICTRL); + iowrite32be(0x00000040, non_ehci + FSL_SOC_USB_AGECNTTHRSH); #endif - out_be32(non_ehci + FSL_SOC_USB_SICTRL, 0x00000001); + iowrite32be(0x00000001, non_ehci + FSL_SOC_USB_SICTRL); } return 0; @@ -554,7 +558,7 @@ static int ehci_fsl_drv_suspend(struct device *dev) if (!fsl_deep_sleep()) return 0; - ehci_fsl->usb_ctrl = in_be32(non_ehci + FSL_SOC_USB_CTRL); + ehci_fsl->usb_ctrl = ioread32be(non_ehci + FSL_SOC_USB_CTRL); return 0; } @@ -577,7 +581,7 @@ static int ehci_fsl_drv_resume(struct device *dev) usb_root_hub_lost_power(hcd->self.root_hub); /* Restore USB PHY settings and enable the controller. */ - out_be32(non_ehci + FSL_SOC_USB_CTRL, ehci_fsl->usb_ctrl); + iowrite32be(ehci_fsl->usb_ctrl, non_ehci + FSL_SOC_USB_CTRL); ehci_reset(ehci); ehci_fsl_reinit(ehci); diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 14178bbf0694..ae1b6e69eb96 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -306,9 +306,9 @@ static void ehci_quiesce (struct ehci_hcd *ehci) /*-------------------------------------------------------------------------*/ +static void end_iaa_cycle(struct ehci_hcd *ehci); static void end_unlink_async(struct ehci_hcd *ehci); static void unlink_empty_async(struct ehci_hcd *ehci); -static void unlink_empty_async_suspended(struct ehci_hcd *ehci); static void ehci_work(struct ehci_hcd *ehci); static void start_unlink_intr(struct ehci_hcd *ehci, struct ehci_qh *qh); static void end_unlink_intr(struct ehci_hcd *ehci, struct ehci_qh *qh); @@ -565,6 +565,9 @@ static int ehci_init(struct usb_hcd *hcd) /* Accept arbitrarily long scatter-gather lists */ if (!(hcd->driver->flags & HCD_LOCAL_MEM)) hcd->self.sg_tablesize = ~0; + + /* Prepare for unlinking active QHs */ + ehci->old_current = ~0; return 0; } @@ -675,8 +678,10 @@ int ehci_setup(struct usb_hcd *hcd) return retval; retval = ehci_halt(ehci); - if (retval) + if (retval) { + ehci_mem_cleanup(ehci); return retval; + } ehci_reset(ehci); @@ -756,7 +761,7 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd) ehci_dbg(ehci, "IAA with IAAD still set?\n"); if (ehci->iaa_in_progress) COUNT(ehci->stats.iaa); - end_unlink_async(ehci); + end_iaa_cycle(ehci); } /* remote wakeup [4.3.1] */ @@ -909,7 +914,7 @@ static int ehci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) */ } else { qh = (struct ehci_qh *) urb->hcpriv; - qh->exception = 1; + qh->unlink_reason |= QH_UNLINK_REQUESTED; switch (qh->qh_state) { case QH_STATE_LINKED: if (usb_pipetype(urb->pipe) == PIPE_INTERRUPT) @@ -970,10 +975,13 @@ rescan: goto done; } - qh->exception = 1; + qh->unlink_reason |= QH_UNLINK_REQUESTED; switch (qh->qh_state) { case QH_STATE_LINKED: - WARN_ON(!list_empty(&qh->qtd_list)); + if (list_empty(&qh->qtd_list)) + qh->unlink_reason |= QH_UNLINK_QUEUE_EMPTY; + else + WARN_ON(1); if (usb_endpoint_type(&ep->desc) != USB_ENDPOINT_XFER_INT) start_unlink_async(ehci, qh); else @@ -1040,7 +1048,7 @@ ehci_endpoint_reset(struct usb_hcd *hcd, struct usb_host_endpoint *ep) * re-linking will call qh_refresh(). */ usb_settoggle(qh->ps.udev, epnum, is_out, 0); - qh->exception = 1; + qh->unlink_reason |= QH_UNLINK_REQUESTED; if (eptype == USB_ENDPOINT_XFER_BULK) start_unlink_async(ehci, qh); else diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c index 086a7115d263..ffc90295a95f 100644 --- a/drivers/usb/host/ehci-hub.c +++ b/drivers/usb/host/ehci-hub.c @@ -33,6 +33,8 @@ #ifdef CONFIG_PM +static void unlink_empty_async_suspended(struct ehci_hcd *ehci); + static int persist_enabled_on_companion(struct usb_device *udev, void *unused) { return !udev->maxchild && udev->persist_enabled && @@ -347,8 +349,10 @@ static int ehci_bus_suspend (struct usb_hcd *hcd) goto done; ehci->rh_state = EHCI_RH_SUSPENDED; - end_unlink_async(ehci); unlink_empty_async_suspended(ehci); + + /* Any IAA cycle that started before the suspend is now invalid */ + end_iaa_cycle(ehci); ehci_handle_start_intr_unlinks(ehci); ehci_handle_intr_unlinks(ehci); end_free_itds(ehci); diff --git a/drivers/usb/host/ehci-msm.c b/drivers/usb/host/ehci-msm.c index c23e2858c815..3e226ef6ca62 100644 --- a/drivers/usb/host/ehci-msm.c +++ b/drivers/usb/host/ehci-msm.c @@ -33,6 +33,7 @@ #include <linux/usb/msm_hsusb_hw.h> #include <linux/usb.h> #include <linux/usb/hcd.h> +#include <linux/acpi.h> #include "ehci.h" @@ -55,12 +56,16 @@ static int ehci_msm_reset(struct usb_hcd *hcd) if (retval) return retval; + /* select ULPI phy and clear other status/control bits in PORTSC */ + writel(PORTSC_PTS_ULPI, USB_PORTSC); /* bursts of unspecified length. */ writel(0, USB_AHBBURST); /* Use the AHB transactor, allow posted data writes */ writel(0x8, USB_AHBMODE); /* Disable streaming mode and select host mode */ writel(0x13, USB_USBMODE); + /* Disable ULPI_TX_PKT_EN_CLR_FIX which is valid only for HSIC */ + writel(readl(USB_GENCONFIG_2) & ~ULPI_TX_PKT_EN_CLR_FIX, USB_GENCONFIG_2); return 0; } @@ -104,9 +109,9 @@ static int ehci_msm_probe(struct platform_device *pdev) } /* - * OTG driver takes care of PHY initialization, clock management, - * powering up VBUS, mapping of registers address space and power - * management. + * If there is an OTG driver, let it take care of PHY initialization, + * clock management, powering up VBUS, mapping of registers address + * space and power management. */ if (pdev->dev.of_node) phy = devm_usb_get_phy_by_phandle(&pdev->dev, "usb-phy", 0); @@ -114,27 +119,35 @@ static int ehci_msm_probe(struct platform_device *pdev) phy = devm_usb_get_phy(&pdev->dev, USB_PHY_TYPE_USB2); if (IS_ERR(phy)) { - dev_err(&pdev->dev, "unable to find transceiver\n"); - ret = -EPROBE_DEFER; - goto put_hcd; - } - - ret = otg_set_host(phy->otg, &hcd->self); - if (ret < 0) { - dev_err(&pdev->dev, "unable to register with transceiver\n"); - goto put_hcd; + if (PTR_ERR(phy) == -EPROBE_DEFER) { + dev_err(&pdev->dev, "unable to find transceiver\n"); + ret = -EPROBE_DEFER; + goto put_hcd; + } + phy = NULL; } hcd->usb_phy = phy; device_init_wakeup(&pdev->dev, 1); - /* - * OTG device parent of HCD takes care of putting - * hardware into low power mode. - */ - pm_runtime_no_callbacks(&pdev->dev); - pm_runtime_enable(&pdev->dev); - /* FIXME: need to call usb_add_hcd() here? */ + if (phy && phy->otg) { + /* + * MSM OTG driver takes care of adding the HCD and + * placing hardware into low power mode via runtime PM. + */ + ret = otg_set_host(phy->otg, &hcd->self); + if (ret < 0) { + dev_err(&pdev->dev, "unable to register with transceiver\n"); + goto put_hcd; + } + + pm_runtime_no_callbacks(&pdev->dev); + pm_runtime_enable(&pdev->dev); + } else { + ret = usb_add_hcd(hcd, hcd->irq, IRQF_SHARED); + if (ret) + goto put_hcd; + } return 0; @@ -152,9 +165,10 @@ static int ehci_msm_remove(struct platform_device *pdev) pm_runtime_disable(&pdev->dev); pm_runtime_set_suspended(&pdev->dev); - otg_set_host(hcd->usb_phy->otg, NULL); - - /* FIXME: need to call usb_remove_hcd() here? */ + if (hcd->usb_phy && hcd->usb_phy->otg) + otg_set_host(hcd->usb_phy->otg, NULL); + else + usb_remove_hcd(hcd); usb_put_hcd(hcd); @@ -191,6 +205,12 @@ static const struct dev_pm_ops ehci_msm_dev_pm_ops = { .resume = ehci_msm_pm_resume, }; +static const struct acpi_device_id msm_ehci_acpi_ids[] = { + { "QCOM8040", 0 }, + { } +}; +MODULE_DEVICE_TABLE(acpi, msm_ehci_acpi_ids); + static const struct of_device_id msm_ehci_dt_match[] = { { .compatible = "qcom,ehci-host", }, {} @@ -200,10 +220,12 @@ MODULE_DEVICE_TABLE(of, msm_ehci_dt_match); static struct platform_driver ehci_msm_driver = { .probe = ehci_msm_probe, .remove = ehci_msm_remove, + .shutdown = usb_hcd_platform_shutdown, .driver = { .name = "msm_hsusb_host", .pm = &ehci_msm_dev_pm_ops, .of_match_table = msm_ehci_dt_match, + .acpi_match_table = ACPI_PTR(msm_ehci_acpi_ids), }, }; diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c index 2a5d2fd76040..3b3649d88c5f 100644 --- a/drivers/usb/host/ehci-pci.c +++ b/drivers/usb/host/ehci-pci.c @@ -377,6 +377,12 @@ static int ehci_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) return usb_hcd_pci_probe(pdev, id); } +static void ehci_pci_remove(struct pci_dev *pdev) +{ + pci_clear_mwi(pdev); + usb_hcd_pci_remove(pdev); +} + /* PCI driver selection metadata; PCI hotplugging uses this */ static const struct pci_device_id pci_ids [] = { { /* handle any USB 2.0 EHCI controller */ @@ -396,7 +402,7 @@ static struct pci_driver ehci_pci_driver = { .id_table = pci_ids, .probe = ehci_pci_probe, - .remove = usb_hcd_pci_remove, + .remove = ehci_pci_remove, .shutdown = usb_hcd_pci_shutdown, #ifdef CONFIG_PM diff --git a/drivers/usb/host/ehci-platform.c b/drivers/usb/host/ehci-platform.c index bd7082f297bb..1757ebb471b6 100644 --- a/drivers/usb/host/ehci-platform.c +++ b/drivers/usb/host/ehci-platform.c @@ -345,8 +345,7 @@ static int ehci_platform_suspend(struct device *dev) { struct usb_hcd *hcd = dev_get_drvdata(dev); struct usb_ehci_pdata *pdata = dev_get_platdata(dev); - struct platform_device *pdev = - container_of(dev, struct platform_device, dev); + struct platform_device *pdev = to_platform_device(dev); bool do_wakeup = device_may_wakeup(dev); int ret; @@ -364,8 +363,7 @@ static int ehci_platform_resume(struct device *dev) { struct usb_hcd *hcd = dev_get_drvdata(dev); struct usb_ehci_pdata *pdata = dev_get_platdata(dev); - struct platform_device *pdev = - container_of(dev, struct platform_device, dev); + struct platform_device *pdev = to_platform_device(dev); struct ehci_platform_priv *priv = hcd_to_ehci_priv(hcd); if (pdata->power_on) { diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c index aad0777240d3..eca3710d8fc4 100644 --- a/drivers/usb/host/ehci-q.c +++ b/drivers/usb/host/ehci-q.c @@ -394,6 +394,7 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh) goto retry_xacterr; } stopped = 1; + qh->unlink_reason |= QH_UNLINK_HALTED; /* magic dummy for some short reads; qh won't advance. * that silicon quirk can kick in with this dummy too. @@ -408,6 +409,7 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh) && !(qtd->hw_alt_next & EHCI_LIST_END(ehci))) { stopped = 1; + qh->unlink_reason |= QH_UNLINK_SHORT_READ; } /* stop scanning when we reach qtds the hc is using */ @@ -420,8 +422,10 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh) stopped = 1; /* cancel everything if we halt, suspend, etc */ - if (ehci->rh_state < EHCI_RH_RUNNING) + if (ehci->rh_state < EHCI_RH_RUNNING) { last_status = -ESHUTDOWN; + qh->unlink_reason |= QH_UNLINK_SHUTDOWN; + } /* this qtd is active; skip it unless a previous qtd * for its urb faulted, or its urb was canceled. @@ -538,10 +542,10 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh) * except maybe high bandwidth ... */ if (stopped != 0 || hw->hw_qtd_next == EHCI_LIST_END(ehci)) - qh->exception = 1; + qh->unlink_reason |= QH_UNLINK_DUMMY_OVERLAY; /* Let the caller know if the QH needs to be unlinked. */ - return qh->exception; + return qh->unlink_reason; } /*-------------------------------------------------------------------------*/ @@ -1003,7 +1007,7 @@ static void qh_link_async (struct ehci_hcd *ehci, struct ehci_qh *qh) qh->qh_state = QH_STATE_LINKED; qh->xacterrs = 0; - qh->exception = 0; + qh->unlink_reason = 0; /* qtd completions reported later by interrupt */ enable_async(ehci); @@ -1279,17 +1283,13 @@ static void single_unlink_async(struct ehci_hcd *ehci, struct ehci_qh *qh) static void start_iaa_cycle(struct ehci_hcd *ehci) { - /* Do nothing if an IAA cycle is already running */ - if (ehci->iaa_in_progress) - return; - ehci->iaa_in_progress = true; - /* If the controller isn't running, we don't have to wait for it */ if (unlikely(ehci->rh_state < EHCI_RH_RUNNING)) { end_unlink_async(ehci); - /* Otherwise start a new IAA cycle */ - } else if (likely(ehci->rh_state == EHCI_RH_RUNNING)) { + /* Otherwise start a new IAA cycle if one isn't already running */ + } else if (ehci->rh_state == EHCI_RH_RUNNING && + !ehci->iaa_in_progress) { /* Make sure the unlinks are all visible to the hardware */ wmb(); @@ -1297,17 +1297,13 @@ static void start_iaa_cycle(struct ehci_hcd *ehci) ehci_writel(ehci, ehci->command | CMD_IAAD, &ehci->regs->command); ehci_readl(ehci, &ehci->regs->command); + ehci->iaa_in_progress = true; ehci_enable_event(ehci, EHCI_HRTIMER_IAA_WATCHDOG, true); } } -/* the async qh for the qtds being unlinked are now gone from the HC */ - -static void end_unlink_async(struct ehci_hcd *ehci) +static void end_iaa_cycle(struct ehci_hcd *ehci) { - struct ehci_qh *qh; - bool early_exit; - if (ehci->has_synopsys_hc_bug) ehci_writel(ehci, (u32) ehci->async->qh_dma, &ehci->regs->async_next); @@ -1315,6 +1311,16 @@ static void end_unlink_async(struct ehci_hcd *ehci) /* The current IAA cycle has ended */ ehci->iaa_in_progress = false; + end_unlink_async(ehci); +} + +/* See if the async qh for the qtds being unlinked are now gone from the HC */ + +static void end_unlink_async(struct ehci_hcd *ehci) +{ + struct ehci_qh *qh; + bool early_exit; + if (list_empty(&ehci->async_unlink)) return; qh = list_first_entry(&ehci->async_unlink, struct ehci_qh, @@ -1335,14 +1341,60 @@ static void end_unlink_async(struct ehci_hcd *ehci) * after the IAA interrupt occurs. In self-defense, always go * through two IAA cycles for each QH. */ - else if (qh->qh_state == QH_STATE_UNLINK_WAIT) { + else if (qh->qh_state == QH_STATE_UNLINK) { + /* + * Second IAA cycle has finished. Process only the first + * waiting QH (NVIDIA (?) bug). + */ + list_move_tail(&qh->unlink_node, &ehci->async_idle); + } + + /* + * AMD/ATI (?) bug: The HC can continue to use an active QH long + * after the IAA interrupt occurs. To prevent problems, QHs that + * may still be active will wait until 2 ms have passed with no + * change to the hw_current and hw_token fields (this delay occurs + * between the two IAA cycles). + * + * The EHCI spec (4.8.2) says that active QHs must not be removed + * from the async schedule and recommends waiting until the QH + * goes inactive. This is ridiculous because the QH will _never_ + * become inactive if the endpoint NAKs indefinitely. + */ + + /* Some reasons for unlinking guarantee the QH can't be active */ + else if (qh->unlink_reason & (QH_UNLINK_HALTED | + QH_UNLINK_SHORT_READ | QH_UNLINK_DUMMY_OVERLAY)) + goto DelayDone; + + /* The QH can't be active if the queue was and still is empty... */ + else if ((qh->unlink_reason & QH_UNLINK_QUEUE_EMPTY) && + list_empty(&qh->qtd_list)) + goto DelayDone; + + /* ... or if the QH has halted */ + else if (qh->hw->hw_token & cpu_to_hc32(ehci, QTD_STS_HALT)) + goto DelayDone; + + /* Otherwise we have to wait until the QH stops changing */ + else { + __hc32 qh_current, qh_token; + + qh_current = qh->hw->hw_current; + qh_token = qh->hw->hw_token; + if (qh_current != ehci->old_current || + qh_token != ehci->old_token) { + ehci->old_current = qh_current; + ehci->old_token = qh_token; + ehci_enable_event(ehci, + EHCI_HRTIMER_ACTIVE_UNLINK, true); + return; + } + DelayDone: qh->qh_state = QH_STATE_UNLINK; early_exit = true; } - - /* Otherwise process only the first waiting QH (NVIDIA bug?) */ - else - list_move_tail(&qh->unlink_node, &ehci->async_idle); + ehci->old_current = ~0; /* Prepare for next QH */ /* Start a new IAA cycle if any QHs are waiting for it */ if (!list_empty(&ehci->async_unlink)) @@ -1395,6 +1447,7 @@ static void unlink_empty_async(struct ehci_hcd *ehci) /* If nothing else is being unlinked, unlink the last empty QH */ if (list_empty(&ehci->async_unlink) && qh_to_unlink) { + qh_to_unlink->unlink_reason |= QH_UNLINK_QUEUE_EMPTY; start_unlink_async(ehci, qh_to_unlink); --count; } @@ -1406,8 +1459,10 @@ static void unlink_empty_async(struct ehci_hcd *ehci) } } +#ifdef CONFIG_PM + /* The root hub is suspended; unlink all the async QHs */ -static void __maybe_unused unlink_empty_async_suspended(struct ehci_hcd *ehci) +static void unlink_empty_async_suspended(struct ehci_hcd *ehci) { struct ehci_qh *qh; @@ -1416,9 +1471,10 @@ static void __maybe_unused unlink_empty_async_suspended(struct ehci_hcd *ehci) WARN_ON(!list_empty(&qh->qtd_list)); single_unlink_async(ehci, qh); } - start_iaa_cycle(ehci); } +#endif + /* makes sure the async qh will become idle */ /* caller must own ehci->lock */ diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index f9a332775c47..1dfe54f14737 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c @@ -34,7 +34,7 @@ * pre-calculated schedule data to make appending to the queue be quick. */ -static int ehci_get_frame (struct usb_hcd *hcd); +static int ehci_get_frame(struct usb_hcd *hcd); /* * periodic_next_shadow - return "next" pointer on shadow list @@ -52,7 +52,7 @@ periodic_next_shadow(struct ehci_hcd *ehci, union ehci_shadow *periodic, return &periodic->fstn->fstn_next; case Q_TYPE_ITD: return &periodic->itd->itd_next; - // case Q_TYPE_SITD: + /* case Q_TYPE_SITD: */ default: return &periodic->sitd->sitd_next; } @@ -73,7 +73,7 @@ shadow_next_periodic(struct ehci_hcd *ehci, union ehci_shadow *periodic, } /* caller must hold ehci->lock */ -static void periodic_unlink (struct ehci_hcd *ehci, unsigned frame, void *ptr) +static void periodic_unlink(struct ehci_hcd *ehci, unsigned frame, void *ptr) { union ehci_shadow *prev_p = &ehci->pshadow[frame]; __hc32 *hw_p = &ehci->periodic[frame]; @@ -296,10 +296,9 @@ static void compute_tt_budget(u8 budget_table[EHCI_BANDWIDTH_SIZE], if (x <= 125) { budget_line[uf] = x; break; - } else { - budget_line[uf] = 125; - x -= 125; } + budget_line[uf] = 125; + x -= 125; } } } @@ -330,7 +329,8 @@ static int __maybe_unused same_tt(struct usb_device *dev1, */ static inline unsigned char tt_start_uframe(struct ehci_hcd *ehci, __hc32 mask) { - unsigned char smask = QH_SMASK & hc32_to_cpu(ehci, mask); + unsigned char smask = hc32_to_cpu(ehci, mask) & QH_SMASK; + if (!smask) { ehci_err(ehci, "invalid empty smask!\n"); /* uframe 7 can't have bw so this will indicate failure */ @@ -346,7 +346,8 @@ max_tt_usecs[] = { 125, 125, 125, 125, 125, 125, 30, 0 }; static inline void carryover_tt_bandwidth(unsigned short tt_usecs[8]) { int i; - for (i=0; i<7; i++) { + + for (i = 0; i < 7; i++) { if (max_tt_usecs[i] < tt_usecs[i]) { tt_usecs[i+1] += tt_usecs[i] - max_tt_usecs[i]; tt_usecs[i] = max_tt_usecs[i]; @@ -375,7 +376,7 @@ static inline void carryover_tt_bandwidth(unsigned short tt_usecs[8]) * limit of 16, specified in USB 2.0 spec section 11.18.4 requirement #4, * since proper scheduling limits ssplits to less than 16 per uframe. */ -static int tt_available ( +static int tt_available( struct ehci_hcd *ehci, struct ehci_per_sched *ps, struct ehci_tt *tt, @@ -409,11 +410,11 @@ static int tt_available ( * must be empty, so as to not illegally delay * already scheduled transactions */ - if (125 < usecs) { + if (usecs > 125) { int ufs = (usecs / 125); for (i = uframe; i < (uframe + ufs) && i < 8; i++) - if (0 < tt_usecs[i]) + if (tt_usecs[i] > 0) return 0; } @@ -435,7 +436,7 @@ static int tt_available ( * for a periodic transfer starting at the specified frame, using * all the uframes in the mask. */ -static int tt_no_collision ( +static int tt_no_collision( struct ehci_hcd *ehci, unsigned period, struct usb_device *dev, @@ -455,8 +456,8 @@ static int tt_no_collision ( __hc32 type; struct ehci_qh_hw *hw; - here = ehci->pshadow [frame]; - type = Q_NEXT_TYPE(ehci, ehci->periodic [frame]); + here = ehci->pshadow[frame]; + type = Q_NEXT_TYPE(ehci, ehci->periodic[frame]); while (here.ptr) { switch (hc32_to_cpu(ehci, type)) { case Q_TYPE_ITD: @@ -479,7 +480,7 @@ static int tt_no_collision ( here = here.qh->qh_next; continue; case Q_TYPE_SITD: - if (same_tt (dev, here.sitd->urb->dev)) { + if (same_tt(dev, here.sitd->urb->dev)) { u16 mask; mask = hc32_to_cpu(ehci, here.sitd @@ -492,9 +493,9 @@ static int tt_no_collision ( type = Q_NEXT_TYPE(ehci, here.sitd->hw_next); here = here.sitd->sitd_next; continue; - // case Q_TYPE_FSTN: + /* case Q_TYPE_FSTN: */ default: - ehci_dbg (ehci, + ehci_dbg(ehci, "periodic frame %d bogus type %d\n", frame, type); } @@ -588,14 +589,14 @@ static void qh_link_periodic(struct ehci_hcd *ehci, struct ehci_qh *qh) qh->qh_next = here; if (here.qh) qh->hw->hw_next = *hw_p; - wmb (); + wmb(); prev->qh = qh; - *hw_p = QH_NEXT (ehci, qh->qh_dma); + *hw_p = QH_NEXT(ehci, qh->qh_dma); } } qh->qh_state = QH_STATE_LINKED; qh->xacterrs = 0; - qh->exception = 0; + qh->unlink_reason = 0; /* update per-qh bandwidth for debugfs */ ehci_to_hcd(ehci)->self.bandwidth_allocated += qh->ps.bw_period @@ -633,7 +634,7 @@ static void qh_unlink_periodic(struct ehci_hcd *ehci, struct ehci_qh *qh) period = qh->ps.period ? : 1; for (i = qh->ps.phase; i < ehci->periodic_size; i += period) - periodic_unlink (ehci, i, qh); + periodic_unlink(ehci, i, qh); /* update per-qh bandwidth for debugfs */ ehci_to_hcd(ehci)->self.bandwidth_allocated -= qh->ps.bw_period @@ -679,7 +680,7 @@ static void start_unlink_intr(struct ehci_hcd *ehci, struct ehci_qh *qh) /* if the qh is waiting for unlink, cancel it now */ cancel_unlink_wait_intr(ehci, qh); - qh_unlink_periodic (ehci, qh); + qh_unlink_periodic(ehci, qh); /* Make sure the unlinks are visible before starting the timer */ wmb(); @@ -763,7 +764,7 @@ static void end_unlink_intr(struct ehci_hcd *ehci, struct ehci_qh *qh) /*-------------------------------------------------------------------------*/ -static int check_period ( +static int check_period( struct ehci_hcd *ehci, unsigned frame, unsigned uframe, @@ -785,11 +786,11 @@ static int check_period ( return 0; } - // success! + /* success! */ return 1; } -static int check_intr_schedule ( +static int check_intr_schedule( struct ehci_hcd *ehci, unsigned frame, unsigned uframe, @@ -925,7 +926,7 @@ done: return status; } -static int intr_submit ( +static int intr_submit( struct ehci_hcd *ehci, struct urb *urb, struct list_head *qtd_list, @@ -940,7 +941,7 @@ static int intr_submit ( /* get endpoint and transfer/schedule data */ epnum = urb->ep->desc.bEndpointAddress; - spin_lock_irqsave (&ehci->lock, flags); + spin_lock_irqsave(&ehci->lock, flags); if (unlikely(!HCD_HW_ACCESSIBLE(ehci_to_hcd(ehci)))) { status = -ESHUTDOWN; @@ -951,20 +952,21 @@ static int intr_submit ( goto done_not_linked; /* get qh and force any scheduling errors */ - INIT_LIST_HEAD (&empty); + INIT_LIST_HEAD(&empty); qh = qh_append_tds(ehci, urb, &empty, epnum, &urb->ep->hcpriv); if (qh == NULL) { status = -ENOMEM; goto done; } if (qh->qh_state == QH_STATE_IDLE) { - if ((status = qh_schedule (ehci, qh)) != 0) + status = qh_schedule(ehci, qh); + if (status) goto done; } /* then queue the urb's tds to the qh */ qh = qh_append_tds(ehci, urb, qtd_list, epnum, &urb->ep->hcpriv); - BUG_ON (qh == NULL); + BUG_ON(qh == NULL); /* stuff into the periodic schedule */ if (qh->qh_state == QH_STATE_IDLE) { @@ -982,9 +984,9 @@ done: if (unlikely(status)) usb_hcd_unlink_urb_from_ep(ehci_to_hcd(ehci), urb); done_not_linked: - spin_unlock_irqrestore (&ehci->lock, flags); + spin_unlock_irqrestore(&ehci->lock, flags); if (status) - qtd_list_free (ehci, urb, qtd_list); + qtd_list_free(ehci, urb, qtd_list); return status; } @@ -1022,12 +1024,12 @@ static void scan_intr(struct ehci_hcd *ehci) /* ehci_iso_stream ops work with both ITD and SITD */ static struct ehci_iso_stream * -iso_stream_alloc (gfp_t mem_flags) +iso_stream_alloc(gfp_t mem_flags) { struct ehci_iso_stream *stream; - stream = kzalloc(sizeof *stream, mem_flags); - if (likely (stream != NULL)) { + stream = kzalloc(sizeof(*stream), mem_flags); + if (likely(stream != NULL)) { INIT_LIST_HEAD(&stream->td_list); INIT_LIST_HEAD(&stream->free_list); stream->next_uframe = NO_FRAME; @@ -1037,13 +1039,13 @@ iso_stream_alloc (gfp_t mem_flags) } static void -iso_stream_init ( +iso_stream_init( struct ehci_hcd *ehci, struct ehci_iso_stream *stream, struct urb *urb ) { - static const u8 smask_out [] = { 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f }; + static const u8 smask_out[] = { 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f }; struct usb_device *dev = urb->dev; u32 buf1; @@ -1058,11 +1060,7 @@ iso_stream_init ( epnum = usb_pipeendpoint(urb->pipe); is_input = usb_pipein(urb->pipe) ? USB_DIR_IN : 0; maxp = usb_endpoint_maxp(&urb->ep->desc); - if (is_input) { - buf1 = (1 << 11); - } else { - buf1 = 0; - } + buf1 = is_input ? 1 << 11 : 0; /* knows about ITD vs SITD */ if (dev->speed == USB_SPEED_HIGH) { @@ -1111,7 +1109,7 @@ iso_stream_init ( think_time = dev->tt ? dev->tt->think_time : 0; stream->ps.tt_usecs = NS_TO_US(think_time + usb_calc_bus_time( dev->speed, is_input, 1, maxp)); - hs_transfers = max (1u, (maxp + 187) / 188); + hs_transfers = max(1u, (maxp + 187) / 188); if (is_input) { u32 tmp; @@ -1151,7 +1149,7 @@ iso_stream_init ( } static struct ehci_iso_stream * -iso_stream_find (struct ehci_hcd *ehci, struct urb *urb) +iso_stream_find(struct ehci_hcd *ehci, struct urb *urb) { unsigned epnum; struct ehci_iso_stream *stream; @@ -1164,25 +1162,25 @@ iso_stream_find (struct ehci_hcd *ehci, struct urb *urb) else ep = urb->dev->ep_out[epnum]; - spin_lock_irqsave (&ehci->lock, flags); + spin_lock_irqsave(&ehci->lock, flags); stream = ep->hcpriv; - if (unlikely (stream == NULL)) { + if (unlikely(stream == NULL)) { stream = iso_stream_alloc(GFP_ATOMIC); - if (likely (stream != NULL)) { + if (likely(stream != NULL)) { ep->hcpriv = stream; iso_stream_init(ehci, stream, urb); } /* if dev->ep [epnum] is a QH, hw is set */ - } else if (unlikely (stream->hw != NULL)) { - ehci_dbg (ehci, "dev %s ep%d%s, not iso??\n", + } else if (unlikely(stream->hw != NULL)) { + ehci_dbg(ehci, "dev %s ep%d%s, not iso??\n", urb->dev->devpath, epnum, usb_pipein(urb->pipe) ? "in" : "out"); stream = NULL; } - spin_unlock_irqrestore (&ehci->lock, flags); + spin_unlock_irqrestore(&ehci->lock, flags); return stream; } @@ -1191,16 +1189,16 @@ iso_stream_find (struct ehci_hcd *ehci, struct urb *urb) /* ehci_iso_sched ops can be ITD-only or SITD-only */ static struct ehci_iso_sched * -iso_sched_alloc (unsigned packets, gfp_t mem_flags) +iso_sched_alloc(unsigned packets, gfp_t mem_flags) { struct ehci_iso_sched *iso_sched; - int size = sizeof *iso_sched; + int size = sizeof(*iso_sched); - size += packets * sizeof (struct ehci_iso_packet); + size += packets * sizeof(struct ehci_iso_packet); iso_sched = kzalloc(size, mem_flags); - if (likely (iso_sched != NULL)) { - INIT_LIST_HEAD (&iso_sched->td_list); - } + if (likely(iso_sched != NULL)) + INIT_LIST_HEAD(&iso_sched->td_list); + return iso_sched; } @@ -1222,17 +1220,17 @@ itd_sched_init( * when we fit new itds into the schedule. */ for (i = 0; i < urb->number_of_packets; i++) { - struct ehci_iso_packet *uframe = &iso_sched->packet [i]; + struct ehci_iso_packet *uframe = &iso_sched->packet[i]; unsigned length; dma_addr_t buf; u32 trans; - length = urb->iso_frame_desc [i].length; - buf = dma + urb->iso_frame_desc [i].offset; + length = urb->iso_frame_desc[i].length; + buf = dma + urb->iso_frame_desc[i].offset; trans = EHCI_ISOC_ACTIVE; trans |= buf & 0x0fff; - if (unlikely (((i + 1) == urb->number_of_packets)) + if (unlikely(((i + 1) == urb->number_of_packets)) && !(urb->transfer_flags & URB_NO_INTERRUPT)) trans |= EHCI_ITD_IOC; trans |= length << 16; @@ -1241,26 +1239,26 @@ itd_sched_init( /* might need to cross a buffer page within a uframe */ uframe->bufp = (buf & ~(u64)0x0fff); buf += length; - if (unlikely ((uframe->bufp != (buf & ~(u64)0x0fff)))) + if (unlikely((uframe->bufp != (buf & ~(u64)0x0fff)))) uframe->cross = 1; } } static void -iso_sched_free ( +iso_sched_free( struct ehci_iso_stream *stream, struct ehci_iso_sched *iso_sched ) { if (!iso_sched) return; - // caller must hold ehci->lock! - list_splice (&iso_sched->td_list, &stream->free_list); - kfree (iso_sched); + /* caller must hold ehci->lock! */ + list_splice(&iso_sched->td_list, &stream->free_list); + kfree(iso_sched); } static int -itd_urb_transaction ( +itd_urb_transaction( struct ehci_iso_stream *stream, struct ehci_hcd *ehci, struct urb *urb, @@ -1274,8 +1272,8 @@ itd_urb_transaction ( struct ehci_iso_sched *sched; unsigned long flags; - sched = iso_sched_alloc (urb->number_of_packets, mem_flags); - if (unlikely (sched == NULL)) + sched = iso_sched_alloc(urb->number_of_packets, mem_flags); + if (unlikely(sched == NULL)) return -ENOMEM; itd_sched_init(ehci, sched, stream, urb); @@ -1286,7 +1284,7 @@ itd_urb_transaction ( num_itds = urb->number_of_packets; /* allocate/init ITDs */ - spin_lock_irqsave (&ehci->lock, flags); + spin_lock_irqsave(&ehci->lock, flags); for (i = 0; i < num_itds; i++) { /* @@ -1298,14 +1296,14 @@ itd_urb_transaction ( struct ehci_itd, itd_list); if (itd->frame == ehci->now_frame) goto alloc_itd; - list_del (&itd->itd_list); + list_del(&itd->itd_list); itd_dma = itd->itd_dma; } else { alloc_itd: - spin_unlock_irqrestore (&ehci->lock, flags); - itd = dma_pool_alloc (ehci->itd_pool, mem_flags, + spin_unlock_irqrestore(&ehci->lock, flags); + itd = dma_pool_alloc(ehci->itd_pool, mem_flags, &itd_dma); - spin_lock_irqsave (&ehci->lock, flags); + spin_lock_irqsave(&ehci->lock, flags); if (!itd) { iso_sched_free(stream, sched); spin_unlock_irqrestore(&ehci->lock, flags); @@ -1313,12 +1311,12 @@ itd_urb_transaction ( } } - memset (itd, 0, sizeof *itd); + memset(itd, 0, sizeof(*itd)); itd->itd_dma = itd_dma; itd->frame = NO_FRAME; - list_add (&itd->itd_list, &sched->td_list); + list_add(&itd->itd_list, &sched->td_list); } - spin_unlock_irqrestore (&ehci->lock, flags); + spin_unlock_irqrestore(&ehci->lock, flags); /* temporarily store schedule info in hcpriv */ urb->hcpriv = sched; @@ -1385,7 +1383,7 @@ static void reserve_release_iso_bandwidth(struct ehci_hcd *ehci, } static inline int -itd_slot_ok ( +itd_slot_ok( struct ehci_hcd *ehci, struct ehci_iso_stream *stream, unsigned uframe @@ -1405,7 +1403,7 @@ itd_slot_ok ( } static inline int -sitd_slot_ok ( +sitd_slot_ok( struct ehci_hcd *ehci, struct ehci_iso_stream *stream, unsigned uframe, @@ -1492,7 +1490,7 @@ sitd_slot_ok ( */ static int -iso_stream_schedule ( +iso_stream_schedule( struct ehci_hcd *ehci, struct urb *urb, struct ehci_iso_stream *stream @@ -1693,9 +1691,9 @@ itd_init(struct ehci_hcd *ehci, struct ehci_iso_stream *stream, /* it's been recently zeroed */ itd->hw_next = EHCI_LIST_END(ehci); - itd->hw_bufp [0] = stream->buf0; - itd->hw_bufp [1] = stream->buf1; - itd->hw_bufp [2] = stream->buf2; + itd->hw_bufp[0] = stream->buf0; + itd->hw_bufp[1] = stream->buf1; + itd->hw_bufp[2] = stream->buf2; for (i = 0; i < 8; i++) itd->index[i] = -1; @@ -1712,13 +1710,13 @@ itd_patch( u16 uframe ) { - struct ehci_iso_packet *uf = &iso_sched->packet [index]; + struct ehci_iso_packet *uf = &iso_sched->packet[index]; unsigned pg = itd->pg; - // BUG_ON (pg == 6 && uf->cross); + /* BUG_ON(pg == 6 && uf->cross); */ uframe &= 0x07; - itd->index [uframe] = index; + itd->index[uframe] = index; itd->hw_transaction[uframe] = uf->transaction; itd->hw_transaction[uframe] |= cpu_to_hc32(ehci, pg << 12); @@ -1726,7 +1724,7 @@ itd_patch( itd->hw_bufp_hi[pg] |= cpu_to_hc32(ehci, (u32)(uf->bufp >> 32)); /* iso_frame_desc[].offset must be strictly increasing */ - if (unlikely (uf->cross)) { + if (unlikely(uf->cross)) { u64 bufp = uf->bufp + 4096; itd->pg = ++pg; @@ -1736,7 +1734,7 @@ itd_patch( } static inline void -itd_link (struct ehci_hcd *ehci, unsigned frame, struct ehci_itd *itd) +itd_link(struct ehci_hcd *ehci, unsigned frame, struct ehci_itd *itd) { union ehci_shadow *prev = &ehci->pshadow[frame]; __hc32 *hw_p = &ehci->periodic[frame]; @@ -1757,7 +1755,7 @@ itd_link (struct ehci_hcd *ehci, unsigned frame, struct ehci_itd *itd) itd->hw_next = *hw_p; prev->itd = itd; itd->frame = frame; - wmb (); + wmb(); *hw_p = cpu_to_hc32(ehci, itd->itd_dma | Q_TYPE_ITD); } @@ -1776,7 +1774,7 @@ static void itd_link_urb( next_uframe = stream->next_uframe & (mod - 1); - if (unlikely (list_empty(&stream->td_list))) + if (unlikely(list_empty(&stream->td_list))) ehci_to_hcd(ehci)->self.bandwidth_allocated += stream->bandwidth; @@ -1792,16 +1790,16 @@ static void itd_link_urb( packet < urb->number_of_packets;) { if (itd == NULL) { /* ASSERT: we have all necessary itds */ - // BUG_ON (list_empty (&iso_sched->td_list)); + /* BUG_ON(list_empty(&iso_sched->td_list)); */ /* ASSERT: no itds for this endpoint in this uframe */ - itd = list_entry (iso_sched->td_list.next, + itd = list_entry(iso_sched->td_list.next, struct ehci_itd, itd_list); - list_move_tail (&itd->itd_list, &stream->td_list); + list_move_tail(&itd->itd_list, &stream->td_list); itd->stream = stream; itd->urb = urb; - itd_init (ehci, stream, itd); + itd_init(ehci, stream, itd); } uframe = next_uframe & 0x07; @@ -1823,7 +1821,7 @@ static void itd_link_urb( stream->next_uframe = next_uframe; /* don't need that schedule data any more */ - iso_sched_free (stream, iso_sched); + iso_sched_free(stream, iso_sched); urb->hcpriv = stream; ++ehci->isoc_count; @@ -1855,19 +1853,19 @@ static bool itd_complete(struct ehci_hcd *ehci, struct ehci_itd *itd) /* for each uframe with a packet */ for (uframe = 0; uframe < 8; uframe++) { - if (likely (itd->index[uframe] == -1)) + if (likely(itd->index[uframe] == -1)) continue; urb_index = itd->index[uframe]; - desc = &urb->iso_frame_desc [urb_index]; + desc = &urb->iso_frame_desc[urb_index]; - t = hc32_to_cpup(ehci, &itd->hw_transaction [uframe]); - itd->hw_transaction [uframe] = 0; + t = hc32_to_cpup(ehci, &itd->hw_transaction[uframe]); + itd->hw_transaction[uframe] = 0; /* report transfer status */ - if (unlikely (t & ISO_ERRS)) { + if (unlikely(t & ISO_ERRS)) { urb->error_count++; if (t & EHCI_ISOC_BUF_ERR) - desc->status = usb_pipein (urb->pipe) + desc->status = usb_pipein(urb->pipe) ? -ENOSR /* hc couldn't read */ : -ECOMM; /* hc couldn't write */ else if (t & EHCI_ISOC_BABBLE) @@ -1880,7 +1878,7 @@ static bool itd_complete(struct ehci_hcd *ehci, struct ehci_itd *itd) desc->actual_length = EHCI_ITD_LENGTH(t); urb->actual_length += desc->actual_length; } - } else if (likely ((t & EHCI_ISOC_ACTIVE) == 0)) { + } else if (likely((t & EHCI_ISOC_ACTIVE) == 0)) { desc->status = 0; desc->actual_length = EHCI_ITD_LENGTH(t); urb->actual_length += desc->actual_length; @@ -1891,12 +1889,13 @@ static bool itd_complete(struct ehci_hcd *ehci, struct ehci_itd *itd) } /* handle completion now? */ - if (likely ((urb_index + 1) != urb->number_of_packets)) + if (likely((urb_index + 1) != urb->number_of_packets)) goto done; - /* ASSERT: it's really the last itd for this urb - list_for_each_entry (itd, &stream->td_list, itd_list) - BUG_ON (itd->urb == urb); + /* + * ASSERT: it's really the last itd for this urb + * list_for_each_entry (itd, &stream->td_list, itd_list) + * BUG_ON(itd->urb == urb); */ /* give urb back to the driver; completion often (re)submits */ @@ -1936,7 +1935,7 @@ done: /*-------------------------------------------------------------------------*/ -static int itd_submit (struct ehci_hcd *ehci, struct urb *urb, +static int itd_submit(struct ehci_hcd *ehci, struct urb *urb, gfp_t mem_flags) { int status = -EINVAL; @@ -1944,37 +1943,37 @@ static int itd_submit (struct ehci_hcd *ehci, struct urb *urb, struct ehci_iso_stream *stream; /* Get iso_stream head */ - stream = iso_stream_find (ehci, urb); - if (unlikely (stream == NULL)) { - ehci_dbg (ehci, "can't get iso stream\n"); + stream = iso_stream_find(ehci, urb); + if (unlikely(stream == NULL)) { + ehci_dbg(ehci, "can't get iso stream\n"); return -ENOMEM; } if (unlikely(urb->interval != stream->uperiod)) { - ehci_dbg (ehci, "can't change iso interval %d --> %d\n", + ehci_dbg(ehci, "can't change iso interval %d --> %d\n", stream->uperiod, urb->interval); goto done; } #ifdef EHCI_URB_TRACE - ehci_dbg (ehci, + ehci_dbg(ehci, "%s %s urb %p ep%d%s len %d, %d pkts %d uframes [%p]\n", __func__, urb->dev->devpath, urb, - usb_pipeendpoint (urb->pipe), - usb_pipein (urb->pipe) ? "in" : "out", + usb_pipeendpoint(urb->pipe), + usb_pipein(urb->pipe) ? "in" : "out", urb->transfer_buffer_length, urb->number_of_packets, urb->interval, stream); #endif /* allocate ITDs w/o locking anything */ - status = itd_urb_transaction (stream, ehci, urb, mem_flags); - if (unlikely (status < 0)) { - ehci_dbg (ehci, "can't init itds\n"); + status = itd_urb_transaction(stream, ehci, urb, mem_flags); + if (unlikely(status < 0)) { + ehci_dbg(ehci, "can't init itds\n"); goto done; } /* schedule ... need to lock */ - spin_lock_irqsave (&ehci->lock, flags); + spin_lock_irqsave(&ehci->lock, flags); if (unlikely(!HCD_HW_ACCESSIBLE(ehci_to_hcd(ehci)))) { status = -ESHUTDOWN; goto done_not_linked; @@ -1984,7 +1983,7 @@ static int itd_submit (struct ehci_hcd *ehci, struct urb *urb, goto done_not_linked; status = iso_stream_schedule(ehci, urb, stream); if (likely(status == 0)) { - itd_link_urb (ehci, urb, ehci->periodic_size << 3, stream); + itd_link_urb(ehci, urb, ehci->periodic_size << 3, stream); } else if (status > 0) { status = 0; ehci_urb_done(ehci, urb, 0); @@ -1992,7 +1991,7 @@ static int itd_submit (struct ehci_hcd *ehci, struct urb *urb, usb_hcd_unlink_urb_from_ep(ehci_to_hcd(ehci), urb); } done_not_linked: - spin_unlock_irqrestore (&ehci->lock, flags); + spin_unlock_irqrestore(&ehci->lock, flags); done: return status; } @@ -2022,13 +2021,13 @@ sitd_sched_init( * when we fit new sitds into the schedule. */ for (i = 0; i < urb->number_of_packets; i++) { - struct ehci_iso_packet *packet = &iso_sched->packet [i]; + struct ehci_iso_packet *packet = &iso_sched->packet[i]; unsigned length; dma_addr_t buf; u32 trans; - length = urb->iso_frame_desc [i].length & 0x03ff; - buf = dma + urb->iso_frame_desc [i].offset; + length = urb->iso_frame_desc[i].length & 0x03ff; + buf = dma + urb->iso_frame_desc[i].offset; trans = SITD_STS_ACTIVE; if (((i + 1) == urb->number_of_packets) @@ -2054,7 +2053,7 @@ sitd_sched_init( } static int -sitd_urb_transaction ( +sitd_urb_transaction( struct ehci_iso_stream *stream, struct ehci_hcd *ehci, struct urb *urb, @@ -2067,14 +2066,14 @@ sitd_urb_transaction ( struct ehci_iso_sched *iso_sched; unsigned long flags; - iso_sched = iso_sched_alloc (urb->number_of_packets, mem_flags); + iso_sched = iso_sched_alloc(urb->number_of_packets, mem_flags); if (iso_sched == NULL) return -ENOMEM; sitd_sched_init(ehci, iso_sched, stream, urb); /* allocate/init sITDs */ - spin_lock_irqsave (&ehci->lock, flags); + spin_lock_irqsave(&ehci->lock, flags); for (i = 0; i < urb->number_of_packets; i++) { /* NOTE: for now, we don't try to handle wraparound cases @@ -2091,14 +2090,14 @@ sitd_urb_transaction ( struct ehci_sitd, sitd_list); if (sitd->frame == ehci->now_frame) goto alloc_sitd; - list_del (&sitd->sitd_list); + list_del(&sitd->sitd_list); sitd_dma = sitd->sitd_dma; } else { alloc_sitd: - spin_unlock_irqrestore (&ehci->lock, flags); - sitd = dma_pool_alloc (ehci->sitd_pool, mem_flags, + spin_unlock_irqrestore(&ehci->lock, flags); + sitd = dma_pool_alloc(ehci->sitd_pool, mem_flags, &sitd_dma); - spin_lock_irqsave (&ehci->lock, flags); + spin_lock_irqsave(&ehci->lock, flags); if (!sitd) { iso_sched_free(stream, iso_sched); spin_unlock_irqrestore(&ehci->lock, flags); @@ -2106,17 +2105,17 @@ sitd_urb_transaction ( } } - memset (sitd, 0, sizeof *sitd); + memset(sitd, 0, sizeof(*sitd)); sitd->sitd_dma = sitd_dma; sitd->frame = NO_FRAME; - list_add (&sitd->sitd_list, &iso_sched->td_list); + list_add(&sitd->sitd_list, &iso_sched->td_list); } /* temporarily store schedule info in hcpriv */ urb->hcpriv = iso_sched; urb->error_count = 0; - spin_unlock_irqrestore (&ehci->lock, flags); + spin_unlock_irqrestore(&ehci->lock, flags); return 0; } @@ -2131,8 +2130,8 @@ sitd_patch( unsigned index ) { - struct ehci_iso_packet *uf = &iso_sched->packet [index]; - u64 bufp = uf->bufp; + struct ehci_iso_packet *uf = &iso_sched->packet[index]; + u64 bufp; sitd->hw_next = EHCI_LIST_END(ehci); sitd->hw_fullspeed_ep = stream->address; @@ -2152,14 +2151,14 @@ sitd_patch( } static inline void -sitd_link (struct ehci_hcd *ehci, unsigned frame, struct ehci_sitd *sitd) +sitd_link(struct ehci_hcd *ehci, unsigned frame, struct ehci_sitd *sitd) { /* note: sitd ordering could matter (CSPLIT then SSPLIT) */ - sitd->sitd_next = ehci->pshadow [frame]; - sitd->hw_next = ehci->periodic [frame]; - ehci->pshadow [frame].sitd = sitd; + sitd->sitd_next = ehci->pshadow[frame]; + sitd->hw_next = ehci->periodic[frame]; + ehci->pshadow[frame].sitd = sitd; sitd->frame = frame; - wmb (); + wmb(); ehci->periodic[frame] = cpu_to_hc32(ehci, sitd->sitd_dma | Q_TYPE_SITD); } @@ -2196,13 +2195,13 @@ static void sitd_link_urb( packet++) { /* ASSERT: we have all necessary sitds */ - BUG_ON (list_empty (&sched->td_list)); + BUG_ON(list_empty(&sched->td_list)); /* ASSERT: no itds for this endpoint in this frame */ - sitd = list_entry (sched->td_list.next, + sitd = list_entry(sched->td_list.next, struct ehci_sitd, sitd_list); - list_move_tail (&sitd->sitd_list, &stream->td_list); + list_move_tail(&sitd->sitd_list, &stream->td_list); sitd->stream = stream; sitd->urb = urb; @@ -2215,7 +2214,7 @@ static void sitd_link_urb( stream->next_uframe = next_uframe & (mod - 1); /* don't need that schedule data any more */ - iso_sched_free (stream, sched); + iso_sched_free(stream, sched); urb->hcpriv = stream; ++ehci->isoc_count; @@ -2242,20 +2241,20 @@ static bool sitd_complete(struct ehci_hcd *ehci, struct ehci_sitd *sitd) struct urb *urb = sitd->urb; struct usb_iso_packet_descriptor *desc; u32 t; - int urb_index = -1; + int urb_index; struct ehci_iso_stream *stream = sitd->stream; struct usb_device *dev; bool retval = false; urb_index = sitd->index; - desc = &urb->iso_frame_desc [urb_index]; + desc = &urb->iso_frame_desc[urb_index]; t = hc32_to_cpup(ehci, &sitd->hw_results); /* report transfer status */ if (unlikely(t & SITD_ERRS)) { urb->error_count++; if (t & SITD_STS_DBE) - desc->status = usb_pipein (urb->pipe) + desc->status = usb_pipein(urb->pipe) ? -ENOSR /* hc couldn't read */ : -ECOMM; /* hc couldn't write */ else if (t & SITD_STS_BABBLE) @@ -2275,9 +2274,10 @@ static bool sitd_complete(struct ehci_hcd *ehci, struct ehci_sitd *sitd) if ((urb_index + 1) != urb->number_of_packets) goto done; - /* ASSERT: it's really the last sitd for this urb - list_for_each_entry (sitd, &stream->td_list, sitd_list) - BUG_ON (sitd->urb == urb); + /* + * ASSERT: it's really the last sitd for this urb + * list_for_each_entry (sitd, &stream->td_list, sitd_list) + * BUG_ON(sitd->urb == urb); */ /* give urb back to the driver; completion often (re)submits */ @@ -2316,7 +2316,7 @@ done: } -static int sitd_submit (struct ehci_hcd *ehci, struct urb *urb, +static int sitd_submit(struct ehci_hcd *ehci, struct urb *urb, gfp_t mem_flags) { int status = -EINVAL; @@ -2324,35 +2324,35 @@ static int sitd_submit (struct ehci_hcd *ehci, struct urb *urb, struct ehci_iso_stream *stream; /* Get iso_stream head */ - stream = iso_stream_find (ehci, urb); + stream = iso_stream_find(ehci, urb); if (stream == NULL) { - ehci_dbg (ehci, "can't get iso stream\n"); + ehci_dbg(ehci, "can't get iso stream\n"); return -ENOMEM; } if (urb->interval != stream->ps.period) { - ehci_dbg (ehci, "can't change iso interval %d --> %d\n", + ehci_dbg(ehci, "can't change iso interval %d --> %d\n", stream->ps.period, urb->interval); goto done; } #ifdef EHCI_URB_TRACE - ehci_dbg (ehci, + ehci_dbg(ehci, "submit %p dev%s ep%d%s-iso len %d\n", urb, urb->dev->devpath, - usb_pipeendpoint (urb->pipe), - usb_pipein (urb->pipe) ? "in" : "out", + usb_pipeendpoint(urb->pipe), + usb_pipein(urb->pipe) ? "in" : "out", urb->transfer_buffer_length); #endif /* allocate SITDs */ - status = sitd_urb_transaction (stream, ehci, urb, mem_flags); + status = sitd_urb_transaction(stream, ehci, urb, mem_flags); if (status < 0) { - ehci_dbg (ehci, "can't init sitds\n"); + ehci_dbg(ehci, "can't init sitds\n"); goto done; } /* schedule ... need to lock */ - spin_lock_irqsave (&ehci->lock, flags); + spin_lock_irqsave(&ehci->lock, flags); if (unlikely(!HCD_HW_ACCESSIBLE(ehci_to_hcd(ehci)))) { status = -ESHUTDOWN; goto done_not_linked; @@ -2362,7 +2362,7 @@ static int sitd_submit (struct ehci_hcd *ehci, struct urb *urb, goto done_not_linked; status = iso_stream_schedule(ehci, urb, stream); if (likely(status == 0)) { - sitd_link_urb (ehci, urb, ehci->periodic_size << 3, stream); + sitd_link_urb(ehci, urb, ehci->periodic_size << 3, stream); } else if (status > 0) { status = 0; ehci_urb_done(ehci, urb, 0); @@ -2370,7 +2370,7 @@ static int sitd_submit (struct ehci_hcd *ehci, struct urb *urb, usb_hcd_unlink_urb_from_ep(ehci_to_hcd(ehci), urb); } done_not_linked: - spin_unlock_irqrestore (&ehci->lock, flags); + spin_unlock_irqrestore(&ehci->lock, flags); done: return status; } @@ -2379,9 +2379,11 @@ static int sitd_submit (struct ehci_hcd *ehci, struct urb *urb, static void scan_isoc(struct ehci_hcd *ehci) { - unsigned uf, now_frame, frame; - unsigned fmask = ehci->periodic_size - 1; - bool modified, live; + unsigned uf, now_frame, frame; + unsigned fmask = ehci->periodic_size - 1; + bool modified, live; + union ehci_shadow q, *q_p; + __hc32 type, *hw_p; /* * When running, scan from last scan point up to "now" @@ -2399,119 +2401,117 @@ static void scan_isoc(struct ehci_hcd *ehci) ehci->now_frame = now_frame; frame = ehci->last_iso_frame; - for (;;) { - union ehci_shadow q, *q_p; - __hc32 type, *hw_p; restart: - /* scan each element in frame's queue for completions */ - q_p = &ehci->pshadow [frame]; - hw_p = &ehci->periodic [frame]; - q.ptr = q_p->ptr; - type = Q_NEXT_TYPE(ehci, *hw_p); - modified = false; - - while (q.ptr != NULL) { - switch (hc32_to_cpu(ehci, type)) { - case Q_TYPE_ITD: - /* If this ITD is still active, leave it for - * later processing ... check the next entry. - * No need to check for activity unless the - * frame is current. - */ - if (frame == now_frame && live) { - rmb(); - for (uf = 0; uf < 8; uf++) { - if (q.itd->hw_transaction[uf] & - ITD_ACTIVE(ehci)) - break; - } - if (uf < 8) { - q_p = &q.itd->itd_next; - hw_p = &q.itd->hw_next; - type = Q_NEXT_TYPE(ehci, - q.itd->hw_next); - q = *q_p; + /* Scan each element in frame's queue for completions */ + q_p = &ehci->pshadow[frame]; + hw_p = &ehci->periodic[frame]; + q.ptr = q_p->ptr; + type = Q_NEXT_TYPE(ehci, *hw_p); + modified = false; + + while (q.ptr != NULL) { + switch (hc32_to_cpu(ehci, type)) { + case Q_TYPE_ITD: + /* + * If this ITD is still active, leave it for + * later processing ... check the next entry. + * No need to check for activity unless the + * frame is current. + */ + if (frame == now_frame && live) { + rmb(); + for (uf = 0; uf < 8; uf++) { + if (q.itd->hw_transaction[uf] & + ITD_ACTIVE(ehci)) break; - } } - - /* Take finished ITDs out of the schedule - * and process them: recycle, maybe report - * URB completion. HC won't cache the - * pointer for much longer, if at all. - */ - *q_p = q.itd->itd_next; - if (!ehci->use_dummy_qh || - q.itd->hw_next != EHCI_LIST_END(ehci)) - *hw_p = q.itd->hw_next; - else - *hw_p = cpu_to_hc32(ehci, - ehci->dummy->qh_dma); - type = Q_NEXT_TYPE(ehci, q.itd->hw_next); - wmb(); - modified = itd_complete (ehci, q.itd); - q = *q_p; - break; - case Q_TYPE_SITD: - /* If this SITD is still active, leave it for - * later processing ... check the next entry. - * No need to check for activity unless the - * frame is current. - */ - if (((frame == now_frame) || - (((frame + 1) & fmask) == now_frame)) - && live - && (q.sitd->hw_results & - SITD_ACTIVE(ehci))) { - - q_p = &q.sitd->sitd_next; - hw_p = &q.sitd->hw_next; + if (uf < 8) { + q_p = &q.itd->itd_next; + hw_p = &q.itd->hw_next; type = Q_NEXT_TYPE(ehci, - q.sitd->hw_next); + q.itd->hw_next); q = *q_p; break; } + } + + /* + * Take finished ITDs out of the schedule + * and process them: recycle, maybe report + * URB completion. HC won't cache the + * pointer for much longer, if at all. + */ + *q_p = q.itd->itd_next; + if (!ehci->use_dummy_qh || + q.itd->hw_next != EHCI_LIST_END(ehci)) + *hw_p = q.itd->hw_next; + else + *hw_p = cpu_to_hc32(ehci, ehci->dummy->qh_dma); + type = Q_NEXT_TYPE(ehci, q.itd->hw_next); + wmb(); + modified = itd_complete(ehci, q.itd); + q = *q_p; + break; + case Q_TYPE_SITD: + /* + * If this SITD is still active, leave it for + * later processing ... check the next entry. + * No need to check for activity unless the + * frame is current. + */ + if (((frame == now_frame) || + (((frame + 1) & fmask) == now_frame)) + && live + && (q.sitd->hw_results & SITD_ACTIVE(ehci))) { - /* Take finished SITDs out of the schedule - * and process them: recycle, maybe report - * URB completion. - */ - *q_p = q.sitd->sitd_next; - if (!ehci->use_dummy_qh || - q.sitd->hw_next != EHCI_LIST_END(ehci)) - *hw_p = q.sitd->hw_next; - else - *hw_p = cpu_to_hc32(ehci, - ehci->dummy->qh_dma); + q_p = &q.sitd->sitd_next; + hw_p = &q.sitd->hw_next; type = Q_NEXT_TYPE(ehci, q.sitd->hw_next); - wmb(); - modified = sitd_complete (ehci, q.sitd); q = *q_p; break; - default: - ehci_dbg(ehci, "corrupt type %d frame %d shadow %p\n", - type, frame, q.ptr); - // BUG (); - /* FALL THROUGH */ - case Q_TYPE_QH: - case Q_TYPE_FSTN: - /* End of the iTDs and siTDs */ - q.ptr = NULL; - break; } - /* assume completion callbacks modify the queue */ - if (unlikely(modified && ehci->isoc_count > 0)) - goto restart; - } - - /* Stop when we have reached the current frame */ - if (frame == now_frame) + /* + * Take finished SITDs out of the schedule + * and process them: recycle, maybe report + * URB completion. + */ + *q_p = q.sitd->sitd_next; + if (!ehci->use_dummy_qh || + q.sitd->hw_next != EHCI_LIST_END(ehci)) + *hw_p = q.sitd->hw_next; + else + *hw_p = cpu_to_hc32(ehci, ehci->dummy->qh_dma); + type = Q_NEXT_TYPE(ehci, q.sitd->hw_next); + wmb(); + modified = sitd_complete(ehci, q.sitd); + q = *q_p; + break; + default: + ehci_dbg(ehci, "corrupt type %d frame %d shadow %p\n", + type, frame, q.ptr); + /* BUG(); */ + /* FALL THROUGH */ + case Q_TYPE_QH: + case Q_TYPE_FSTN: + /* End of the iTDs and siTDs */ + q.ptr = NULL; break; + } - /* The last frame may still have active siTDs */ - ehci->last_iso_frame = frame; - frame = (frame + 1) & fmask; + /* Assume completion callbacks modify the queue */ + if (unlikely(modified && ehci->isoc_count > 0)) + goto restart; } + + /* Stop when we have reached the current frame */ + if (frame == now_frame) + return; + + /* The last frame may still have active siTDs */ + ehci->last_iso_frame = frame; + frame = (frame + 1) & fmask; + + goto restart; } diff --git a/drivers/usb/host/ehci-st.c b/drivers/usb/host/ehci-st.c index b7c5cfa37a83..a94ed677d937 100644 --- a/drivers/usb/host/ehci-st.c +++ b/drivers/usb/host/ehci-st.c @@ -287,8 +287,7 @@ static int st_ehci_suspend(struct device *dev) { struct usb_hcd *hcd = dev_get_drvdata(dev); struct usb_ehci_pdata *pdata = dev_get_platdata(dev); - struct platform_device *pdev = - container_of(dev, struct platform_device, dev); + struct platform_device *pdev = to_platform_device(dev); bool do_wakeup = device_may_wakeup(dev); int ret; @@ -308,8 +307,7 @@ static int st_ehci_resume(struct device *dev) { struct usb_hcd *hcd = dev_get_drvdata(dev); struct usb_ehci_pdata *pdata = dev_get_platdata(dev); - struct platform_device *pdev = - container_of(dev, struct platform_device, dev); + struct platform_device *pdev = to_platform_device(dev); int err; pinctrl_pm_select_default_state(dev); diff --git a/drivers/usb/host/ehci-timer.c b/drivers/usb/host/ehci-timer.c index 424ac5d83714..69f50e6533a6 100644 --- a/drivers/usb/host/ehci-timer.c +++ b/drivers/usb/host/ehci-timer.c @@ -72,6 +72,7 @@ static unsigned event_delays_ns[] = { 1 * NSEC_PER_MSEC, /* EHCI_HRTIMER_POLL_DEAD */ 1125 * NSEC_PER_USEC, /* EHCI_HRTIMER_UNLINK_INTR */ 2 * NSEC_PER_MSEC, /* EHCI_HRTIMER_FREE_ITDS */ + 2 * NSEC_PER_MSEC, /* EHCI_HRTIMER_ACTIVE_UNLINK */ 5 * NSEC_PER_MSEC, /* EHCI_HRTIMER_START_UNLINK_INTR */ 6 * NSEC_PER_MSEC, /* EHCI_HRTIMER_ASYNC_UNLINKS */ 10 * NSEC_PER_MSEC, /* EHCI_HRTIMER_IAA_WATCHDOG */ @@ -237,6 +238,7 @@ static void ehci_handle_start_intr_unlinks(struct ehci_hcd *ehci) ehci->intr_unlink_wait_cycle)) break; list_del_init(&qh->unlink_node); + qh->unlink_reason |= QH_UNLINK_QUEUE_EMPTY; start_unlink_intr(ehci, qh); } @@ -360,7 +362,7 @@ static void ehci_iaa_watchdog(struct ehci_hcd *ehci) } ehci_dbg(ehci, "IAA watchdog: status %x cmd %x\n", status, cmd); - end_unlink_async(ehci); + end_iaa_cycle(ehci); } @@ -394,6 +396,7 @@ static void (*event_handlers[])(struct ehci_hcd *) = { ehci_handle_controller_death, /* EHCI_HRTIMER_POLL_DEAD */ ehci_handle_intr_unlinks, /* EHCI_HRTIMER_UNLINK_INTR */ end_free_itds, /* EHCI_HRTIMER_FREE_ITDS */ + end_unlink_async, /* EHCI_HRTIMER_ACTIVE_UNLINK */ ehci_handle_start_intr_unlinks, /* EHCI_HRTIMER_START_UNLINK_INTR */ unlink_empty_async, /* EHCI_HRTIMER_ASYNC_UNLINKS */ ehci_iaa_watchdog, /* EHCI_HRTIMER_IAA_WATCHDOG */ diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index ec61aedb0067..3f3b74aeca97 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h @@ -110,6 +110,7 @@ enum ehci_hrtimer_event { EHCI_HRTIMER_POLL_DEAD, /* Wait for dead controller to stop */ EHCI_HRTIMER_UNLINK_INTR, /* Wait for interrupt QH unlink */ EHCI_HRTIMER_FREE_ITDS, /* Wait for unused iTDs and siTDs */ + EHCI_HRTIMER_ACTIVE_UNLINK, /* Wait while unlinking an active QH */ EHCI_HRTIMER_START_UNLINK_INTR, /* Unlink empty interrupt QHs */ EHCI_HRTIMER_ASYNC_UNLINKS, /* Unlink empty async QHs */ EHCI_HRTIMER_IAA_WATCHDOG, /* Handle lost IAA interrupts */ @@ -156,6 +157,8 @@ struct ehci_hcd { /* one per controller */ struct list_head async_idle; unsigned async_unlink_cycle; unsigned async_count; /* async activity count */ + __hc32 old_current; /* Test for QH becoming */ + __hc32 old_token; /* inactive during unlink */ /* periodic schedule support */ #define DEFAULT_I_TDPS 1024 /* some HCs can do less */ @@ -185,7 +188,7 @@ struct ehci_hcd { /* one per controller */ struct ehci_sitd *last_sitd_to_free; /* per root hub port */ - unsigned long reset_done [EHCI_MAX_ROOT_PORTS]; + unsigned long reset_done[EHCI_MAX_ROOT_PORTS]; /* bit vectors (one bit per port) */ unsigned long bus_suspended; /* which ports were @@ -244,9 +247,9 @@ struct ehci_hcd { /* one per controller */ /* irq statistics */ #ifdef EHCI_STATS struct ehci_stats stats; -# define COUNT(x) do { (x)++; } while (0) +# define COUNT(x) ((x)++) #else -# define COUNT(x) do {} while (0) +# define COUNT(x) #endif /* debug files */ @@ -268,13 +271,13 @@ struct ehci_hcd { /* one per controller */ }; /* convert between an HCD pointer and the corresponding EHCI_HCD */ -static inline struct ehci_hcd *hcd_to_ehci (struct usb_hcd *hcd) +static inline struct ehci_hcd *hcd_to_ehci(struct usb_hcd *hcd) { return (struct ehci_hcd *) (hcd->hcd_priv); } -static inline struct usb_hcd *ehci_to_hcd (struct ehci_hcd *ehci) +static inline struct usb_hcd *ehci_to_hcd(struct ehci_hcd *ehci) { - return container_of ((void *) ehci, struct usb_hcd, hcd_priv); + return container_of((void *) ehci, struct usb_hcd, hcd_priv); } /*-------------------------------------------------------------------------*/ @@ -316,25 +319,25 @@ struct ehci_qtd { #define HALT_BIT(ehci) cpu_to_hc32(ehci, QTD_STS_HALT) #define STATUS_BIT(ehci) cpu_to_hc32(ehci, QTD_STS_STS) - __hc32 hw_buf [5]; /* see EHCI 3.5.4 */ - __hc32 hw_buf_hi [5]; /* Appendix B */ + __hc32 hw_buf[5]; /* see EHCI 3.5.4 */ + __hc32 hw_buf_hi[5]; /* Appendix B */ /* the rest is HCD-private */ dma_addr_t qtd_dma; /* qtd address */ struct list_head qtd_list; /* sw qtd list */ struct urb *urb; /* qtd's urb */ size_t length; /* length of buffer */ -} __attribute__ ((aligned (32))); +} __aligned(32); /* mask NakCnt+T in qh->hw_alt_next */ -#define QTD_MASK(ehci) cpu_to_hc32 (ehci, ~0x1f) +#define QTD_MASK(ehci) cpu_to_hc32(ehci, ~0x1f) -#define IS_SHORT_READ(token) (QTD_LENGTH (token) != 0 && QTD_PID (token) == 1) +#define IS_SHORT_READ(token) (QTD_LENGTH(token) != 0 && QTD_PID(token) == 1) /*-------------------------------------------------------------------------*/ /* type tag from {qh,itd,sitd,fstn}->hw_next */ -#define Q_NEXT_TYPE(ehci,dma) ((dma) & cpu_to_hc32(ehci, 3 << 1)) +#define Q_NEXT_TYPE(ehci, dma) ((dma) & cpu_to_hc32(ehci, 3 << 1)) /* * Now the following defines are not converted using the @@ -350,7 +353,8 @@ struct ehci_qtd { #define Q_TYPE_FSTN (3 << 1) /* next async queue entry, or pointer to interrupt/periodic QH */ -#define QH_NEXT(ehci,dma) (cpu_to_hc32(ehci, (((u32)dma)&~0x01f)|Q_TYPE_QH)) +#define QH_NEXT(ehci, dma) \ + (cpu_to_hc32(ehci, (((u32) dma) & ~0x01f) | Q_TYPE_QH)) /* for periodic/async schedules and qtd lists, mark end of list */ #define EHCI_LIST_END(ehci) cpu_to_hc32(ehci, 1) /* "null pointer" to hw */ @@ -405,9 +409,9 @@ struct ehci_qh_hw { __hc32 hw_qtd_next; __hc32 hw_alt_next; __hc32 hw_token; - __hc32 hw_buf [5]; - __hc32 hw_buf_hi [5]; -} __attribute__ ((aligned(32))); + __hc32 hw_buf[5]; + __hc32 hw_buf_hi[5]; +} __aligned(32); struct ehci_qh { struct ehci_qh_hw *hw; /* Must come first */ @@ -432,13 +436,19 @@ struct ehci_qh { u8 xacterrs; /* XactErr retry counter */ #define QH_XACTERR_MAX 32 /* XactErr retry limit */ + u8 unlink_reason; +#define QH_UNLINK_HALTED 0x01 /* Halt flag is set */ +#define QH_UNLINK_SHORT_READ 0x02 /* Recover from a short read */ +#define QH_UNLINK_DUMMY_OVERLAY 0x04 /* QH overlayed the dummy TD */ +#define QH_UNLINK_SHUTDOWN 0x08 /* The HC isn't running */ +#define QH_UNLINK_QUEUE_EMPTY 0x10 /* Reached end of the queue */ +#define QH_UNLINK_REQUESTED 0x20 /* Disable, reset, or dequeue */ + u8 gap_uf; /* uframes split/csplit gap */ unsigned is_out:1; /* bulk or intr OUT */ unsigned clearing_tt:1; /* Clear-TT-Buf in progress */ unsigned dequeue_during_giveback:1; - unsigned exception:1; /* got a fault, or an unlink - was requested */ unsigned should_be_inactive:1; }; @@ -462,7 +472,7 @@ struct ehci_iso_sched { struct list_head td_list; unsigned span; unsigned first_packet; - struct ehci_iso_packet packet [0]; + struct ehci_iso_packet packet[0]; }; /* @@ -510,7 +520,7 @@ struct ehci_iso_stream { struct ehci_itd { /* first part defined by EHCI spec */ __hc32 hw_next; /* see EHCI 3.3.1 */ - __hc32 hw_transaction [8]; /* see EHCI 3.3.2 */ + __hc32 hw_transaction[8]; /* see EHCI 3.3.2 */ #define EHCI_ISOC_ACTIVE (1<<31) /* activate transfer this slot */ #define EHCI_ISOC_BUF_ERR (1<<30) /* Data buffer error */ #define EHCI_ISOC_BABBLE (1<<29) /* babble detected */ @@ -520,8 +530,8 @@ struct ehci_itd { #define ITD_ACTIVE(ehci) cpu_to_hc32(ehci, EHCI_ISOC_ACTIVE) - __hc32 hw_bufp [7]; /* see EHCI 3.3.3 */ - __hc32 hw_bufp_hi [7]; /* Appendix B */ + __hc32 hw_bufp[7]; /* see EHCI 3.3.3 */ + __hc32 hw_bufp_hi[7]; /* Appendix B */ /* the rest is HCD-private */ dma_addr_t itd_dma; /* for this itd */ @@ -535,7 +545,7 @@ struct ehci_itd { unsigned frame; /* where scheduled */ unsigned pg; unsigned index[8]; /* in urb->iso_frame_desc */ -} __attribute__ ((aligned (32))); +} __aligned(32); /*-------------------------------------------------------------------------*/ @@ -554,7 +564,7 @@ struct ehci_sitd { __hc32 hw_results; /* EHCI table 3-11 */ #define SITD_IOC (1 << 31) /* interrupt on completion */ #define SITD_PAGE (1 << 30) /* buffer 0/1 */ -#define SITD_LENGTH(x) (0x3ff & ((x)>>16)) +#define SITD_LENGTH(x) (((x) >> 16) & 0x3ff) #define SITD_STS_ACTIVE (1 << 7) /* HC may execute this */ #define SITD_STS_ERR (1 << 6) /* error from TT */ #define SITD_STS_DBE (1 << 5) /* data buffer error (in HC) */ @@ -565,9 +575,9 @@ struct ehci_sitd { #define SITD_ACTIVE(ehci) cpu_to_hc32(ehci, SITD_STS_ACTIVE) - __hc32 hw_buf [2]; /* EHCI table 3-12 */ + __hc32 hw_buf[2]; /* EHCI table 3-12 */ __hc32 hw_backpointer; /* EHCI table 3-13 */ - __hc32 hw_buf_hi [2]; /* Appendix B */ + __hc32 hw_buf_hi[2]; /* Appendix B */ /* the rest is HCD-private */ dma_addr_t sitd_dma; @@ -578,7 +588,7 @@ struct ehci_sitd { struct list_head sitd_list; /* list of stream's sitds */ unsigned frame; unsigned index; -} __attribute__ ((aligned (32))); +} __aligned(32); /*-------------------------------------------------------------------------*/ @@ -598,7 +608,7 @@ struct ehci_fstn { /* the rest is HCD-private */ dma_addr_t fstn_dma; union ehci_shadow fstn_next; /* ptr to periodic q entry */ -} __attribute__ ((aligned (32))); +} __aligned(32); /*-------------------------------------------------------------------------*/ @@ -634,10 +644,10 @@ struct ehci_tt { /* Prepare the PORTSC wakeup flags during controller suspend/resume */ #define ehci_prepare_ports_for_controller_suspend(ehci, do_wakeup) \ - ehci_adjust_port_wakeup_flags(ehci, true, do_wakeup); + ehci_adjust_port_wakeup_flags(ehci, true, do_wakeup) #define ehci_prepare_ports_for_controller_resume(ehci) \ - ehci_adjust_port_wakeup_flags(ehci, false, false); + ehci_adjust_port_wakeup_flags(ehci, false, false) /*-------------------------------------------------------------------------*/ @@ -731,7 +741,7 @@ ehci_port_speed(struct ehci_hcd *ehci, unsigned int portsc) #endif static inline unsigned int ehci_readl(const struct ehci_hcd *ehci, - __u32 __iomem * regs) + __u32 __iomem *regs) { #ifdef CONFIG_USB_EHCI_BIG_ENDIAN_MMIO return ehci_big_endian_mmio(ehci) ? @@ -806,7 +816,7 @@ static inline void set_ohci_hcfs(struct ehci_hcd *ehci, int operational) #define ehci_big_endian_desc(e) ((e)->big_endian_desc) /* cpu to ehci */ -static inline __hc32 cpu_to_hc32 (const struct ehci_hcd *ehci, const u32 x) +static inline __hc32 cpu_to_hc32(const struct ehci_hcd *ehci, const u32 x) { return ehci_big_endian_desc(ehci) ? (__force __hc32)cpu_to_be32(x) @@ -814,14 +824,14 @@ static inline __hc32 cpu_to_hc32 (const struct ehci_hcd *ehci, const u32 x) } /* ehci to cpu */ -static inline u32 hc32_to_cpu (const struct ehci_hcd *ehci, const __hc32 x) +static inline u32 hc32_to_cpu(const struct ehci_hcd *ehci, const __hc32 x) { return ehci_big_endian_desc(ehci) ? be32_to_cpu((__force __be32)x) : le32_to_cpu((__force __le32)x); } -static inline u32 hc32_to_cpup (const struct ehci_hcd *ehci, const __hc32 *x) +static inline u32 hc32_to_cpup(const struct ehci_hcd *ehci, const __hc32 *x) { return ehci_big_endian_desc(ehci) ? be32_to_cpup((__force __be32 *)x) @@ -831,18 +841,18 @@ static inline u32 hc32_to_cpup (const struct ehci_hcd *ehci, const __hc32 *x) #else /* cpu to ehci */ -static inline __hc32 cpu_to_hc32 (const struct ehci_hcd *ehci, const u32 x) +static inline __hc32 cpu_to_hc32(const struct ehci_hcd *ehci, const u32 x) { return cpu_to_le32(x); } /* ehci to cpu */ -static inline u32 hc32_to_cpu (const struct ehci_hcd *ehci, const __hc32 x) +static inline u32 hc32_to_cpu(const struct ehci_hcd *ehci, const __hc32 x) { return le32_to_cpu(x); } -static inline u32 hc32_to_cpup (const struct ehci_hcd *ehci, const __hc32 *x) +static inline u32 hc32_to_cpup(const struct ehci_hcd *ehci, const __hc32 *x) { return le32_to_cpup(x); } @@ -852,18 +862,13 @@ static inline u32 hc32_to_cpup (const struct ehci_hcd *ehci, const __hc32 *x) /*-------------------------------------------------------------------------*/ #define ehci_dbg(ehci, fmt, args...) \ - dev_dbg(ehci_to_hcd(ehci)->self.controller , fmt , ## args) + dev_dbg(ehci_to_hcd(ehci)->self.controller, fmt, ## args) #define ehci_err(ehci, fmt, args...) \ - dev_err(ehci_to_hcd(ehci)->self.controller , fmt , ## args) + dev_err(ehci_to_hcd(ehci)->self.controller, fmt, ## args) #define ehci_info(ehci, fmt, args...) \ - dev_info(ehci_to_hcd(ehci)->self.controller , fmt , ## args) + dev_info(ehci_to_hcd(ehci)->self.controller, fmt, ## args) #define ehci_warn(ehci, fmt, args...) \ - dev_warn(ehci_to_hcd(ehci)->self.controller , fmt , ## args) - - -#ifndef CONFIG_DYNAMIC_DEBUG -#define STUB_DEBUG_FILES -#endif + dev_warn(ehci_to_hcd(ehci)->self.controller, fmt, ## args) /*-------------------------------------------------------------------------*/ @@ -883,12 +888,10 @@ extern int ehci_handshake(struct ehci_hcd *ehci, void __iomem *ptr, u32 mask, u32 done, int usec); extern int ehci_reset(struct ehci_hcd *ehci); -#ifdef CONFIG_PM extern int ehci_suspend(struct usb_hcd *hcd, bool do_wakeup); extern int ehci_resume(struct usb_hcd *hcd, bool force_reset); extern void ehci_adjust_port_wakeup_flags(struct ehci_hcd *ehci, bool suspending, bool do_wakeup); -#endif /* CONFIG_PM */ extern int ehci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, u16 wIndex, char *buf, u16 wLength); diff --git a/drivers/usb/host/fotg210-hcd.c b/drivers/usb/host/fotg210-hcd.c index 2341af4f3490..360a5e95abca 100644 --- a/drivers/usb/host/fotg210-hcd.c +++ b/drivers/usb/host/fotg210-hcd.c @@ -2267,7 +2267,7 @@ static unsigned qh_completions(struct fotg210_hcd *fotg210, struct fotg210_qh *qh) { struct fotg210_qtd *last, *end = qh->dummy; - struct list_head *entry, *tmp; + struct fotg210_qtd *qtd, *tmp; int last_status; int stopped; unsigned count = 0; @@ -2301,12 +2301,10 @@ rescan: * then let the queue advance. * if queue is stopped, handles unlinks. */ - list_for_each_safe(entry, tmp, &qh->qtd_list) { - struct fotg210_qtd *qtd; + list_for_each_entry_safe(qtd, tmp, &qh->qtd_list, qtd_list) { struct urb *urb; u32 token = 0; - qtd = list_entry(entry, struct fotg210_qtd, qtd_list); urb = qtd->urb; /* clean up any state from previous QTD ...*/ @@ -2544,14 +2542,11 @@ retry_xacterr: * used for cleanup after errors, before HC sees an URB's TDs. */ static void qtd_list_free(struct fotg210_hcd *fotg210, struct urb *urb, - struct list_head *qtd_list) + struct list_head *head) { - struct list_head *entry, *temp; - - list_for_each_safe(entry, temp, qtd_list) { - struct fotg210_qtd *qtd; + struct fotg210_qtd *qtd, *temp; - qtd = list_entry(entry, struct fotg210_qtd, qtd_list); + list_for_each_entry_safe(qtd, temp, head, qtd_list) { list_del(&qtd->qtd_list); fotg210_qtd_free(fotg210, qtd); } diff --git a/drivers/usb/host/fsl-mph-dr-of.c b/drivers/usb/host/fsl-mph-dr-of.c index 0c382652a399..1044b0f9d656 100644 --- a/drivers/usb/host/fsl-mph-dr-of.c +++ b/drivers/usb/host/fsl-mph-dr-of.c @@ -17,6 +17,7 @@ #include <linux/of_platform.h> #include <linux/clk.h> #include <linux/module.h> +#include <linux/dma-mapping.h> struct fsl_usb2_dev_data { char *dr_mode; /* controller mode */ @@ -96,7 +97,11 @@ static struct platform_device *fsl_usb2_device_register( pdev->dev.parent = &ofdev->dev; pdev->dev.coherent_dma_mask = ofdev->dev.coherent_dma_mask; - *pdev->dev.dma_mask = *ofdev->dev.dma_mask; + + if (!pdev->dev.dma_mask) + pdev->dev.dma_mask = &ofdev->dev.coherent_dma_mask; + else + dma_set_mask(&pdev->dev, DMA_BIT_MASK(32)); retval = platform_device_add_data(pdev, pdata, sizeof(*pdata)); if (retval) diff --git a/drivers/usb/host/max3421-hcd.c b/drivers/usb/host/max3421-hcd.c index bd98706d1ce9..c369c29e496d 100644 --- a/drivers/usb/host/max3421-hcd.c +++ b/drivers/usb/host/max3421-hcd.c @@ -797,19 +797,16 @@ max3421_check_unlink(struct usb_hcd *hcd) { struct spi_device *spi = to_spi_device(hcd->self.controller); struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); - struct list_head *pos, *upos, *next_upos; struct max3421_ep *max3421_ep; struct usb_host_endpoint *ep; - struct urb *urb; + struct urb *urb, *next; unsigned long flags; int retval = 0; spin_lock_irqsave(&max3421_hcd->lock, flags); - list_for_each(pos, &max3421_hcd->ep_list) { - max3421_ep = container_of(pos, struct max3421_ep, ep_list); + list_for_each_entry(max3421_ep, &max3421_hcd->ep_list, ep_list) { ep = max3421_ep->ep; - list_for_each_safe(upos, next_upos, &ep->urb_list) { - urb = container_of(upos, struct urb, urb_list); + list_for_each_entry_safe(urb, next, &ep->urb_list, urb_list) { if (urb->unlinked) { retval = 1; dev_dbg(&spi->dev, "%s: URB %p unlinked=%d", @@ -1184,22 +1181,19 @@ dump_eps(struct usb_hcd *hcd) struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); struct max3421_ep *max3421_ep; struct usb_host_endpoint *ep; - struct list_head *pos, *upos; char ubuf[512], *dp, *end; unsigned long flags; struct urb *urb; int epnum, ret; spin_lock_irqsave(&max3421_hcd->lock, flags); - list_for_each(pos, &max3421_hcd->ep_list) { - max3421_ep = container_of(pos, struct max3421_ep, ep_list); + list_for_each_entry(max3421_ep, &max3421_hcd->ep_list, ep_list) { ep = max3421_ep->ep; dp = ubuf; end = dp + sizeof(ubuf); *dp = '\0'; - list_for_each(upos, &ep->urb_list) { - urb = container_of(upos, struct urb, urb_list); + list_for_each_entry(urb, &ep->urb_list, urb_list) { ret = snprintf(dp, end - dp, " %p(%d.%s %d/%d)", urb, usb_pipetype(urb->pipe), usb_urb_dir_in(urb) ? "IN" : "OUT", diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c index 95c8ddde0725..d177372bb357 100644 --- a/drivers/usb/host/ohci-at91.c +++ b/drivers/usb/host/ohci-at91.c @@ -581,9 +581,7 @@ static int ohci_hcd_at91_drv_remove(struct platform_device *pdev) return 0; } -#ifdef CONFIG_PM - -static int +static int __maybe_unused ohci_hcd_at91_drv_suspend(struct device *dev) { struct usb_hcd *hcd = dev_get_drvdata(dev); @@ -628,7 +626,8 @@ ohci_hcd_at91_drv_suspend(struct device *dev) return ret; } -static int ohci_hcd_at91_drv_resume(struct device *dev) +static int __maybe_unused +ohci_hcd_at91_drv_resume(struct device *dev) { struct usb_hcd *hcd = dev_get_drvdata(dev); struct ohci_at91_priv *ohci_at91 = hcd_to_ohci_at91_priv(hcd); @@ -641,7 +640,6 @@ static int ohci_hcd_at91_drv_resume(struct device *dev) ohci_resume(hcd, false); return 0; } -#endif static SIMPLE_DEV_PM_OPS(ohci_hcd_at91_pm_ops, ohci_hcd_at91_drv_suspend, ohci_hcd_at91_drv_resume); diff --git a/drivers/usb/host/ohci-nxp.c b/drivers/usb/host/ohci-nxp.c index cfa94275c52c..b7d4756232ae 100644 --- a/drivers/usb/host/ohci-nxp.c +++ b/drivers/usb/host/ohci-nxp.c @@ -22,7 +22,6 @@ #include <linux/dma-mapping.h> #include <linux/io.h> #include <linux/i2c.h> -#include <linux/kernel.h> #include <linux/module.h> #include <linux/of.h> #include <linux/platform_device.h> @@ -32,25 +31,9 @@ #include "ohci.h" - #include <mach/hardware.h> -#include <asm/mach-types.h> -#include <asm/io.h> - -#include <mach/platform.h> -#include <mach/irqs.h> #define USB_CONFIG_BASE 0x31020000 -#define PWRMAN_BASE 0x40004000 - -#define USB_CTRL IO_ADDRESS(PWRMAN_BASE + 0x64) - -/* USB_CTRL bit defines */ -#define USB_SLAVE_HCLK_EN (1 << 24) -#define USB_DEV_NEED_CLK_EN (1 << 22) -#define USB_HOST_NEED_CLK_EN (1 << 21) -#define PAD_CONTROL_LAST_DRIVEN (1 << 19) - #define USB_OTG_STAT_CONTROL IO_ADDRESS(USB_CONFIG_BASE + 0x110) /* USB_OTG_STAT_CONTROL bit defines */ @@ -75,9 +58,7 @@ static struct i2c_client *isp1301_i2c_client; extern int usb_disabled(void); -static struct clk *usb_pll_clk; -static struct clk *usb_dev_clk; -static struct clk *usb_otg_clk; +static struct clk *usb_host_clk; static void isp1301_configure_lpc32xx(void) { @@ -117,9 +98,6 @@ static void isp1301_configure_lpc32xx(void) i2c_smbus_write_byte_data(isp1301_i2c_client, ISP1301_I2C_INTERRUPT_RISING | ISP1301_I2C_REG_CLEAR_ADDR, ~0); - /* Enable usb_need_clk clock after transceiver is initialized */ - __raw_writel(__raw_readl(USB_CTRL) | USB_HOST_NEED_CLK_EN, USB_CTRL); - printk(KERN_INFO "ISP1301 Vendor ID : 0x%04x\n", i2c_smbus_read_word_data(isp1301_i2c_client, 0x00)); printk(KERN_INFO "ISP1301 Product ID : 0x%04x\n", @@ -192,59 +170,20 @@ static int ohci_hcd_nxp_probe(struct platform_device *pdev) goto fail_disable; } - /* Enable AHB slave USB clock, needed for further USB clock control */ - __raw_writel(USB_SLAVE_HCLK_EN | PAD_CONTROL_LAST_DRIVEN, USB_CTRL); - - /* Enable USB PLL */ - usb_pll_clk = devm_clk_get(&pdev->dev, "ck_pll5"); - if (IS_ERR(usb_pll_clk)) { - dev_err(&pdev->dev, "failed to acquire USB PLL\n"); - ret = PTR_ERR(usb_pll_clk); + /* Enable USB host clock */ + usb_host_clk = devm_clk_get(&pdev->dev, NULL); + if (IS_ERR(usb_host_clk)) { + dev_err(&pdev->dev, "failed to acquire USB OHCI clock\n"); + ret = PTR_ERR(usb_host_clk); goto fail_disable; } - ret = clk_prepare_enable(usb_pll_clk); + ret = clk_prepare_enable(usb_host_clk); if (ret < 0) { - dev_err(&pdev->dev, "failed to start USB PLL\n"); + dev_err(&pdev->dev, "failed to start USB OHCI clock\n"); goto fail_disable; } - ret = clk_set_rate(usb_pll_clk, 48000); - if (ret < 0) { - dev_err(&pdev->dev, "failed to set USB clock rate\n"); - goto fail_rate; - } - - /* Enable USB device clock */ - usb_dev_clk = devm_clk_get(&pdev->dev, "ck_usbd"); - if (IS_ERR(usb_dev_clk)) { - dev_err(&pdev->dev, "failed to acquire USB DEV Clock\n"); - ret = PTR_ERR(usb_dev_clk); - goto fail_rate; - } - - ret = clk_prepare_enable(usb_dev_clk); - if (ret < 0) { - dev_err(&pdev->dev, "failed to start USB DEV Clock\n"); - goto fail_rate; - } - - /* Enable USB otg clocks */ - usb_otg_clk = devm_clk_get(&pdev->dev, "ck_usb_otg"); - if (IS_ERR(usb_otg_clk)) { - dev_err(&pdev->dev, "failed to acquire USB DEV Clock\n"); - ret = PTR_ERR(usb_otg_clk); - goto fail_otg; - } - - __raw_writel(__raw_readl(USB_CTRL) | USB_HOST_NEED_CLK_EN, USB_CTRL); - - ret = clk_prepare_enable(usb_otg_clk); - if (ret < 0) { - dev_err(&pdev->dev, "failed to start USB DEV Clock\n"); - goto fail_otg; - } - isp1301_configure(); hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev)); @@ -283,11 +222,7 @@ static int ohci_hcd_nxp_probe(struct platform_device *pdev) fail_resource: usb_put_hcd(hcd); fail_hcd: - clk_disable_unprepare(usb_otg_clk); -fail_otg: - clk_disable_unprepare(usb_dev_clk); -fail_rate: - clk_disable_unprepare(usb_pll_clk); + clk_disable_unprepare(usb_host_clk); fail_disable: isp1301_i2c_client = NULL; return ret; @@ -300,9 +235,7 @@ static int ohci_hcd_nxp_remove(struct platform_device *pdev) usb_remove_hcd(hcd); ohci_nxp_stop_hc(); usb_put_hcd(hcd); - clk_disable_unprepare(usb_otg_clk); - clk_disable_unprepare(usb_dev_clk); - clk_disable_unprepare(usb_pll_clk); + clk_disable_unprepare(usb_host_clk); isp1301_i2c_client = NULL; return 0; diff --git a/drivers/usb/host/ohci-platform.c b/drivers/usb/host/ohci-platform.c index c2669f185f65..ae1c988da146 100644 --- a/drivers/usb/host/ohci-platform.c +++ b/drivers/usb/host/ohci-platform.c @@ -310,8 +310,7 @@ static int ohci_platform_suspend(struct device *dev) { struct usb_hcd *hcd = dev_get_drvdata(dev); struct usb_ohci_pdata *pdata = dev->platform_data; - struct platform_device *pdev = - container_of(dev, struct platform_device, dev); + struct platform_device *pdev = to_platform_device(dev); bool do_wakeup = device_may_wakeup(dev); int ret; @@ -329,8 +328,7 @@ static int ohci_platform_resume(struct device *dev) { struct usb_hcd *hcd = dev_get_drvdata(dev); struct usb_ohci_pdata *pdata = dev_get_platdata(dev); - struct platform_device *pdev = - container_of(dev, struct platform_device, dev); + struct platform_device *pdev = to_platform_device(dev); if (pdata->power_on) { int err = pdata->power_on(pdev); diff --git a/drivers/usb/host/ohci-pxa27x.c b/drivers/usb/host/ohci-pxa27x.c index e8c006e7a960..a667cf2d5788 100644 --- a/drivers/usb/host/ohci-pxa27x.c +++ b/drivers/usb/host/ohci-pxa27x.c @@ -435,7 +435,7 @@ int usb_hcd_pxa27x_probe (const struct hc_driver *driver, struct platform_device irq = platform_get_irq(pdev, 0); if (irq < 0) { pr_err("no resource of IORESOURCE_IRQ"); - return -ENXIO; + return irq; } usb_clk = devm_clk_get(&pdev->dev, NULL); diff --git a/drivers/usb/host/ohci-st.c b/drivers/usb/host/ohci-st.c index df9028e0d9b4..acf2eb2a5676 100644 --- a/drivers/usb/host/ohci-st.c +++ b/drivers/usb/host/ohci-st.c @@ -270,8 +270,7 @@ static int st_ohci_suspend(struct device *dev) { struct usb_hcd *hcd = dev_get_drvdata(dev); struct usb_ohci_pdata *pdata = dev->platform_data; - struct platform_device *pdev = - container_of(dev, struct platform_device, dev); + struct platform_device *pdev = to_platform_device(dev); bool do_wakeup = device_may_wakeup(dev); int ret; @@ -289,8 +288,7 @@ static int st_ohci_resume(struct device *dev) { struct usb_hcd *hcd = dev_get_drvdata(dev); struct usb_ohci_pdata *pdata = dev_get_platdata(dev); - struct platform_device *pdev = - container_of(dev, struct platform_device, dev); + struct platform_device *pdev = to_platform_device(dev); int err; if (pdata->power_on) { diff --git a/drivers/usb/host/ohci.h b/drivers/usb/host/ohci.h index bc462288cfb0..37f1725e7a46 100644 --- a/drivers/usb/host/ohci.h +++ b/drivers/usb/host/ohci.h @@ -735,10 +735,8 @@ extern void ohci_init_driver(struct hc_driver *drv, const struct ohci_driver_overrides *over); extern int ohci_restart(struct ohci_hcd *ohci); extern int ohci_setup(struct usb_hcd *hcd); -#ifdef CONFIG_PM extern int ohci_suspend(struct usb_hcd *hcd, bool do_wakeup); extern int ohci_resume(struct usb_hcd *hcd, bool hibernated); -#endif extern int ohci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, u16 wIndex, char *buf, u16 wLength); extern int ohci_hub_status_data(struct usb_hcd *hcd, char *buf); diff --git a/drivers/usb/host/oxu210hp-hcd.c b/drivers/usb/host/oxu210hp-hcd.c index bc74aca8a54c..4e4d601af35c 100644 --- a/drivers/usb/host/oxu210hp-hcd.c +++ b/drivers/usb/host/oxu210hp-hcd.c @@ -981,7 +981,7 @@ static int qh_schedule(struct oxu_hcd *oxu, struct ehci_qh *qh); static unsigned qh_completions(struct oxu_hcd *oxu, struct ehci_qh *qh) { struct ehci_qtd *last = NULL, *end = qh->dummy; - struct list_head *entry, *tmp; + struct ehci_qtd *qtd, *tmp; int stopped; unsigned count = 0; int do_status = 0; @@ -1006,12 +1006,10 @@ static unsigned qh_completions(struct oxu_hcd *oxu, struct ehci_qh *qh) * then let the queue advance. * if queue is stopped, handles unlinks. */ - list_for_each_safe(entry, tmp, &qh->qtd_list) { - struct ehci_qtd *qtd; + list_for_each_entry_safe(qtd, tmp, &qh->qtd_list, qtd_list) { struct urb *urb; u32 token = 0; - qtd = list_entry(entry, struct ehci_qtd, qtd_list); urb = qtd->urb; /* Clean up any state from previous QTD ...*/ @@ -1174,14 +1172,11 @@ halt: * used for cleanup after errors, before HC sees an URB's TDs. */ static void qtd_list_free(struct oxu_hcd *oxu, - struct urb *urb, struct list_head *qtd_list) + struct urb *urb, struct list_head *head) { - struct list_head *entry, *temp; - - list_for_each_safe(entry, temp, qtd_list) { - struct ehci_qtd *qtd; + struct ehci_qtd *qtd, *temp; - qtd = list_entry(entry, struct ehci_qtd, qtd_list); + list_for_each_entry_safe(qtd, temp, head, qtd_list) { list_del(&qtd->qtd_list); oxu_qtd_free(oxu, qtd); } diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c index 26cb8c861e6e..35af36253440 100644 --- a/drivers/usb/host/pci-quirks.c +++ b/drivers/usb/host/pci-quirks.c @@ -992,7 +992,7 @@ static void quirk_usb_handoff_xhci(struct pci_dev *pdev) if ((ext_cap_offset + sizeof(val)) > len) { /* We're reading garbage from the controller */ dev_warn(&pdev->dev, "xHCI controller failing to respond"); - return; + goto iounmap; } val = readl(base + ext_cap_offset); @@ -1055,6 +1055,7 @@ hc_init: XHCI_MAX_HALT_USEC, val); } +iounmap: iounmap(base); } diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c index 4cbd0633c5c2..bfa7fa3d2eea 100644 --- a/drivers/usb/host/r8a66597-hcd.c +++ b/drivers/usb/host/r8a66597-hcd.c @@ -2099,16 +2099,13 @@ static void r8a66597_check_detect_child(struct r8a66597 *r8a66597, memset(now_map, 0, sizeof(now_map)); - list_for_each_entry(bus, &usb_bus_list, bus_list) { - if (!bus->root_hub) - continue; - - if (bus->busnum != hcd->self.busnum) - continue; - + mutex_lock(&usb_bus_idr_lock); + bus = idr_find(&usb_bus_idr, hcd->self.busnum); + if (bus && bus->root_hub) { collect_usb_address_map(bus->root_hub, now_map); update_usb_address_map(r8a66597, bus->root_hub, now_map); } + mutex_unlock(&usb_bus_idr_lock); } static int r8a66597_hub_status_data(struct usb_hcd *hcd, char *buf) diff --git a/drivers/usb/host/u132-hcd.c b/drivers/usb/host/u132-hcd.c index 05c85c7baf84..43d52931b5bf 100644 --- a/drivers/usb/host/u132-hcd.c +++ b/drivers/usb/host/u132-hcd.c @@ -1309,13 +1309,9 @@ static void u132_hcd_ring_work_scheduler(struct work_struct *work) u132_ring_put_kref(u132, ring); return; } else if (ring->curr_endp) { - struct u132_endp *last_endp = ring->curr_endp; - struct list_head *scan; - struct list_head *head = &last_endp->endp_ring; + struct u132_endp *endp, *last_endp = ring->curr_endp; unsigned long wakeup = 0; - list_for_each(scan, head) { - struct u132_endp *endp = list_entry(scan, - struct u132_endp, endp_ring); + list_for_each_entry(endp, &last_endp->endp_ring, endp_ring) { if (endp->queue_next == endp->queue_last) { } else if ((endp->delayed == 0) || time_after_eq(jiffies, endp->jiffies)) { @@ -2393,14 +2389,12 @@ static int u132_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, static int dequeue_from_overflow_chain(struct u132 *u132, struct u132_endp *endp, struct urb *urb) { - struct list_head *scan; - struct list_head *head = &endp->urb_more; - list_for_each(scan, head) { - struct u132_urbq *urbq = list_entry(scan, struct u132_urbq, - urb_more); + struct u132_urbq *urbq; + + list_for_each_entry(urbq, &endp->urb_more, urb_more) { if (urbq->urb == urb) { struct usb_hcd *hcd = u132_to_hcd(u132); - list_del(scan); + list_del(&urbq->urb_more); endp->queue_size -= 1; urb->error_count = 0; usb_hcd_giveback_urb(hcd, urb, 0); diff --git a/drivers/usb/host/xhci-ext-caps.h b/drivers/usb/host/xhci-ext-caps.h index 04ce6b156b35..e0244fb3903d 100644 --- a/drivers/usb/host/xhci-ext-caps.h +++ b/drivers/usb/host/xhci-ext-caps.h @@ -112,12 +112,16 @@ static inline int xhci_find_next_ext_cap(void __iomem *base, u32 start, int id) offset = start; if (!start || start == XHCI_HCC_PARAMS_OFFSET) { val = readl(base + XHCI_HCC_PARAMS_OFFSET); + if (val == ~0) + return 0; offset = XHCI_HCC_EXT_CAPS(val) << 2; if (!offset) return 0; }; do { val = readl(base + offset); + if (val == ~0) + return 0; if (XHCI_EXT_CAPS_ID(val) == id && offset != start) return offset; diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c index b30b4ce294d3..d61fcc48099e 100644 --- a/drivers/usb/host/xhci-hub.c +++ b/drivers/usb/host/xhci-hub.c @@ -50,14 +50,18 @@ static u8 usb_bos_descriptor [] = { 0x00, /* bU1DevExitLat, set later. */ 0x00, 0x00, /* __le16 bU2DevExitLat, set later. */ /* Second device capability, SuperSpeedPlus */ - 0x0c, /* bLength 12, will be adjusted later */ + 0x1c, /* bLength 28, will be adjusted later */ USB_DT_DEVICE_CAPABILITY, /* Device Capability */ USB_SSP_CAP_TYPE, /* bDevCapabilityType SUPERSPEED_PLUS */ 0x00, /* bReserved 0 */ - 0x00, 0x00, 0x00, 0x00, /* bmAttributes, get from xhci psic */ - 0x00, 0x00, /* wFunctionalitySupport */ + 0x23, 0x00, 0x00, 0x00, /* bmAttributes, SSAC=3 SSIC=1 */ + 0x01, 0x00, /* wFunctionalitySupport */ 0x00, 0x00, /* wReserved 0 */ - /* Sublink Speed Attributes are added in xhci_create_usb3_bos_desc() */ + /* Default Sublink Speed Attributes, overwrite if custom PSI exists */ + 0x34, 0x00, 0x05, 0x00, /* 5Gbps, symmetric, rx, ID = 4 */ + 0xb4, 0x00, 0x05, 0x00, /* 5Gbps, symmetric, tx, ID = 4 */ + 0x35, 0x40, 0x0a, 0x00, /* 10Gbps, SSP, symmetric, rx, ID = 5 */ + 0xb5, 0x40, 0x0a, 0x00, /* 10Gbps, SSP, symmetric, tx, ID = 5 */ }; static int xhci_create_usb3_bos_desc(struct xhci_hcd *xhci, char *buf, @@ -72,10 +76,14 @@ static int xhci_create_usb3_bos_desc(struct xhci_hcd *xhci, char *buf, ssp_cap_size = sizeof(usb_bos_descriptor) - desc_size; /* does xhci support USB 3.1 Enhanced SuperSpeed */ - if (xhci->usb3_rhub.min_rev >= 0x01 && xhci->usb3_rhub.psi_uid_count) { - /* two SSA entries for each unique PSI ID, one RX and one TX */ - ssa_count = xhci->usb3_rhub.psi_uid_count * 2; - ssa_size = ssa_count * sizeof(u32); + if (xhci->usb3_rhub.min_rev >= 0x01) { + /* does xhci provide a PSI table for SSA speed attributes? */ + if (xhci->usb3_rhub.psi_count) { + /* two SSA entries for each unique PSI ID, RX and TX */ + ssa_count = xhci->usb3_rhub.psi_uid_count * 2; + ssa_size = ssa_count * sizeof(u32); + ssp_cap_size -= 16; /* skip copying the default SSA */ + } desc_size += ssp_cap_size; usb3_1 = true; } @@ -102,7 +110,8 @@ static int xhci_create_usb3_bos_desc(struct xhci_hcd *xhci, char *buf, put_unaligned_le16(HCS_U2_LATENCY(temp), &buf[13]); } - if (usb3_1) { + /* If PSI table exists, add the custom speed attributes from it */ + if (usb3_1 && xhci->usb3_rhub.psi_count) { u32 ssp_cap_base, bm_attrib, psi; int offset; diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index 5cd080e0a685..80c1de239e9a 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -1070,7 +1070,7 @@ static u32 xhci_find_real_port_number(struct xhci_hcd *xhci, struct usb_device *top_dev; struct usb_hcd *hcd; - if (udev->speed == USB_SPEED_SUPER) + if (udev->speed >= USB_SPEED_SUPER) hcd = xhci->shared_hcd; else hcd = xhci->main_hcd; @@ -1105,6 +1105,10 @@ int xhci_setup_addressable_virt_dev(struct xhci_hcd *xhci, struct usb_device *ud /* 3) Only the control endpoint is valid - one endpoint context */ slot_ctx->dev_info |= cpu_to_le32(LAST_CTX(1) | udev->route); switch (udev->speed) { + case USB_SPEED_SUPER_PLUS: + slot_ctx->dev_info |= cpu_to_le32(SLOT_SPEED_SSP); + max_packets = MAX_PACKET(512); + break; case USB_SPEED_SUPER: slot_ctx->dev_info |= cpu_to_le32(SLOT_SPEED_SS); max_packets = MAX_PACKET(512); @@ -1292,6 +1296,7 @@ static unsigned int xhci_get_endpoint_interval(struct usb_device *udev, } /* Fall through - SS and HS isoc/int have same decoding */ + case USB_SPEED_SUPER_PLUS: case USB_SPEED_SUPER: if (usb_endpoint_xfer_int(&ep->desc) || usb_endpoint_xfer_isoc(&ep->desc)) { @@ -1321,7 +1326,7 @@ static unsigned int xhci_get_endpoint_interval(struct usb_device *udev, default: BUG(); } - return EP_INTERVAL(interval); + return interval; } /* The "Mult" field in the endpoint context is only set for SuperSpeed isoc eps. @@ -1332,39 +1337,42 @@ static unsigned int xhci_get_endpoint_interval(struct usb_device *udev, static u32 xhci_get_endpoint_mult(struct usb_device *udev, struct usb_host_endpoint *ep) { - if (udev->speed != USB_SPEED_SUPER || + if (udev->speed < USB_SPEED_SUPER || !usb_endpoint_xfer_isoc(&ep->desc)) return 0; return ep->ss_ep_comp.bmAttributes; } +static u32 xhci_get_endpoint_max_burst(struct usb_device *udev, + struct usb_host_endpoint *ep) +{ + /* Super speed and Plus have max burst in ep companion desc */ + if (udev->speed >= USB_SPEED_SUPER) + return ep->ss_ep_comp.bMaxBurst; + + if (udev->speed == USB_SPEED_HIGH && + (usb_endpoint_xfer_isoc(&ep->desc) || + usb_endpoint_xfer_int(&ep->desc))) + return (usb_endpoint_maxp(&ep->desc) & 0x1800) >> 11; + + return 0; +} + static u32 xhci_get_endpoint_type(struct usb_host_endpoint *ep) { int in; - u32 type; in = usb_endpoint_dir_in(&ep->desc); - if (usb_endpoint_xfer_control(&ep->desc)) { - type = EP_TYPE(CTRL_EP); - } else if (usb_endpoint_xfer_bulk(&ep->desc)) { - if (in) - type = EP_TYPE(BULK_IN_EP); - else - type = EP_TYPE(BULK_OUT_EP); - } else if (usb_endpoint_xfer_isoc(&ep->desc)) { - if (in) - type = EP_TYPE(ISOC_IN_EP); - else - type = EP_TYPE(ISOC_OUT_EP); - } else if (usb_endpoint_xfer_int(&ep->desc)) { - if (in) - type = EP_TYPE(INT_IN_EP); - else - type = EP_TYPE(INT_OUT_EP); - } else { - type = 0; - } - return type; + + if (usb_endpoint_xfer_control(&ep->desc)) + return CTRL_EP; + if (usb_endpoint_xfer_bulk(&ep->desc)) + return in ? BULK_IN_EP : BULK_OUT_EP; + if (usb_endpoint_xfer_isoc(&ep->desc)) + return in ? ISOC_IN_EP : ISOC_OUT_EP; + if (usb_endpoint_xfer_int(&ep->desc)) + return in ? INT_IN_EP : INT_OUT_EP; + return 0; } /* Return the maximum endpoint service interval time (ESIT) payload. @@ -1382,7 +1390,12 @@ static u32 xhci_get_max_esit_payload(struct usb_device *udev, usb_endpoint_xfer_bulk(&ep->desc)) return 0; - if (udev->speed == USB_SPEED_SUPER) + /* SuperSpeedPlus Isoc ep sending over 48k per esit */ + if ((udev->speed >= USB_SPEED_SUPER_PLUS) && + USB_SS_SSP_ISOC_COMP(ep->ss_ep_comp.bmAttributes)) + return le32_to_cpu(ep->ssp_isoc_ep_comp.dwBytesPerInterval); + /* SuperSpeed or SuperSpeedPlus Isoc ep with less than 48k per esit */ + else if (udev->speed >= USB_SPEED_SUPER) return le16_to_cpu(ep->ss_ep_comp.wBytesPerInterval); max_packet = GET_MAX_PACKET(usb_endpoint_maxp(&ep->desc)); @@ -1404,10 +1417,14 @@ int xhci_endpoint_init(struct xhci_hcd *xhci, struct xhci_ep_ctx *ep_ctx; struct xhci_ring *ep_ring; unsigned int max_packet; - unsigned int max_burst; - enum xhci_ring_type type; + enum xhci_ring_type ring_type; u32 max_esit_payload; u32 endpoint_type; + unsigned int max_burst; + unsigned int interval; + unsigned int mult; + unsigned int avg_trb_len; + unsigned int err_count = 0; ep_index = xhci_get_endpoint_index(&ep->desc); ep_ctx = xhci_get_ep_ctx(xhci, virt_dev->in_ctx, ep_index); @@ -1415,12 +1432,11 @@ int xhci_endpoint_init(struct xhci_hcd *xhci, endpoint_type = xhci_get_endpoint_type(ep); if (!endpoint_type) return -EINVAL; - ep_ctx->ep_info2 = cpu_to_le32(endpoint_type); - type = usb_endpoint_type(&ep->desc); + ring_type = usb_endpoint_type(&ep->desc); /* Set up the endpoint ring */ virt_dev->eps[ep_index].new_ring = - xhci_ring_alloc(xhci, 2, 1, type, mem_flags); + xhci_ring_alloc(xhci, 2, 1, ring_type, mem_flags); if (!virt_dev->eps[ep_index].new_ring) { /* Attempt to use the ring cache */ if (virt_dev->num_rings_cached == 0) @@ -1430,80 +1446,52 @@ int xhci_endpoint_init(struct xhci_hcd *xhci, virt_dev->ring_cache[virt_dev->num_rings_cached]; virt_dev->ring_cache[virt_dev->num_rings_cached] = NULL; xhci_reinit_cached_ring(xhci, virt_dev->eps[ep_index].new_ring, - 1, type); + 1, ring_type); } virt_dev->eps[ep_index].skip = false; ep_ring = virt_dev->eps[ep_index].new_ring; - ep_ctx->deq = cpu_to_le64(ep_ring->first_seg->dma | ep_ring->cycle_state); - ep_ctx->ep_info = cpu_to_le32(xhci_get_endpoint_interval(udev, ep) - | EP_MULT(xhci_get_endpoint_mult(udev, ep))); + /* + * Get values to fill the endpoint context, mostly from ep descriptor. + * The average TRB buffer lengt for bulk endpoints is unclear as we + * have no clue on scatter gather list entry size. For Isoc and Int, + * set it to max available. See xHCI 1.1 spec 4.14.1.1 for details. + */ + max_esit_payload = xhci_get_max_esit_payload(udev, ep); + interval = xhci_get_endpoint_interval(udev, ep); + mult = xhci_get_endpoint_mult(udev, ep); + max_packet = GET_MAX_PACKET(usb_endpoint_maxp(&ep->desc)); + max_burst = xhci_get_endpoint_max_burst(udev, ep); + avg_trb_len = max_esit_payload; /* FIXME dig Mult and streams info out of ep companion desc */ - /* Allow 3 retries for everything but isoc; - * CErr shall be set to 0 for Isoch endpoints. - */ + /* Allow 3 retries for everything but isoc, set CErr = 3 */ if (!usb_endpoint_xfer_isoc(&ep->desc)) - ep_ctx->ep_info2 |= cpu_to_le32(ERROR_COUNT(3)); - else - ep_ctx->ep_info2 |= cpu_to_le32(ERROR_COUNT(0)); - - /* Set the max packet size and max burst */ - max_packet = GET_MAX_PACKET(usb_endpoint_maxp(&ep->desc)); - max_burst = 0; - switch (udev->speed) { - case USB_SPEED_SUPER: - /* dig out max burst from ep companion desc */ - max_burst = ep->ss_ep_comp.bMaxBurst; - break; - case USB_SPEED_HIGH: - /* Some devices get this wrong */ - if (usb_endpoint_xfer_bulk(&ep->desc)) - max_packet = 512; - /* bits 11:12 specify the number of additional transaction - * opportunities per microframe (USB 2.0, section 9.6.6) - */ - if (usb_endpoint_xfer_isoc(&ep->desc) || - usb_endpoint_xfer_int(&ep->desc)) { - max_burst = (usb_endpoint_maxp(&ep->desc) - & 0x1800) >> 11; - } - break; - case USB_SPEED_FULL: - case USB_SPEED_LOW: - break; - default: - BUG(); - } - ep_ctx->ep_info2 |= cpu_to_le32(MAX_PACKET(max_packet) | - MAX_BURST(max_burst)); - max_esit_payload = xhci_get_max_esit_payload(udev, ep); - ep_ctx->tx_info = cpu_to_le32(MAX_ESIT_PAYLOAD_FOR_EP(max_esit_payload)); - - /* - * XXX no idea how to calculate the average TRB buffer length for bulk - * endpoints, as the driver gives us no clue how big each scatter gather - * list entry (or buffer) is going to be. - * - * For isochronous and interrupt endpoints, we set it to the max - * available, until we have new API in the USB core to allow drivers to - * declare how much bandwidth they actually need. - * - * Normally, it would be calculated by taking the total of the buffer - * lengths in the TD and then dividing by the number of TRBs in a TD, - * including link TRBs, No-op TRBs, and Event data TRBs. Since we don't - * use Event Data TRBs, and we don't chain in a link TRB on short - * transfers, we're basically dividing by 1. - * - * xHCI 1.0 and 1.1 specification indicates that the Average TRB Length - * should be set to 8 for control endpoints. - */ + err_count = 3; + /* Some devices get this wrong */ + if (usb_endpoint_xfer_bulk(&ep->desc) && udev->speed == USB_SPEED_HIGH) + max_packet = 512; + /* xHCI 1.0 and 1.1 indicates that ctrl ep avg TRB Length should be 8 */ if (usb_endpoint_xfer_control(&ep->desc) && xhci->hci_version >= 0x100) - ep_ctx->tx_info |= cpu_to_le32(AVG_TRB_LENGTH_FOR_EP(8)); - else - ep_ctx->tx_info |= - cpu_to_le32(AVG_TRB_LENGTH_FOR_EP(max_esit_payload)); + avg_trb_len = 8; + /* xhci 1.1 with LEC support doesn't use mult field, use RsvdZ */ + if ((xhci->hci_version > 0x100) && HCC2_LEC(xhci->hcc_params2)) + mult = 0; + + /* Fill the endpoint context */ + ep_ctx->ep_info = cpu_to_le32(EP_MAX_ESIT_PAYLOAD_HI(max_esit_payload) | + EP_INTERVAL(interval) | + EP_MULT(mult)); + ep_ctx->ep_info2 = cpu_to_le32(EP_TYPE(endpoint_type) | + MAX_PACKET(max_packet) | + MAX_BURST(max_burst) | + ERROR_COUNT(err_count)); + ep_ctx->deq = cpu_to_le64(ep_ring->first_seg->dma | + ep_ring->cycle_state); + + ep_ctx->tx_info = cpu_to_le32(EP_MAX_ESIT_PAYLOAD_LO(max_esit_payload) | + EP_AVG_TRB_LENGTH(avg_trb_len)); /* FIXME Debug endpoint context */ return 0; diff --git a/drivers/usb/host/xhci-mtk-sch.c b/drivers/usb/host/xhci-mtk-sch.c index c30de7c39f44..73f763c4f5f5 100644 --- a/drivers/usb/host/xhci-mtk-sch.c +++ b/drivers/usb/host/xhci-mtk-sch.c @@ -275,8 +275,9 @@ static bool need_bw_sch(struct usb_host_endpoint *ep, return false; /* - * for LS & FS periodic endpoints which its device don't attach - * to TT are also ignored, root-hub will schedule them directly + * for LS & FS periodic endpoints which its device is not behind + * a TT are also ignored, root-hub will schedule them directly, + * but need set @bpkts field of endpoint context to 1. */ if (is_fs_or_ls(speed) && !has_tt) return false; @@ -339,8 +340,17 @@ int xhci_mtk_add_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev, GET_MAX_PACKET(usb_endpoint_maxp(&ep->desc)), usb_endpoint_dir_in(&ep->desc), ep); - if (!need_bw_sch(ep, udev->speed, slot_ctx->tt_info & TT_SLOT)) + if (!need_bw_sch(ep, udev->speed, slot_ctx->tt_info & TT_SLOT)) { + /* + * set @bpkts to 1 if it is LS or FS periodic endpoint, and its + * device does not connected through an external HS hub + */ + if (usb_endpoint_xfer_int(&ep->desc) + || usb_endpoint_xfer_isoc(&ep->desc)) + ep_ctx->reserved[0] |= cpu_to_le32(EP_BPKTS(1)); + return 0; + } bw_index = get_bw_index(xhci, udev, ep); sch_bw = &sch_array[bw_index]; diff --git a/drivers/usb/host/xhci-mtk.c b/drivers/usb/host/xhci-mtk.c index c9ab6a44c34a..79959f17c38c 100644 --- a/drivers/usb/host/xhci-mtk.c +++ b/drivers/usb/host/xhci-mtk.c @@ -695,10 +695,24 @@ static int xhci_mtk_remove(struct platform_device *dev) return 0; } -#ifdef CONFIG_PM_SLEEP -static int xhci_mtk_suspend(struct device *dev) +/* + * if ip sleep fails, and all clocks are disabled, access register will hang + * AHB bus, so stop polling roothubs to avoid regs access on bus suspend. + * and no need to check whether ip sleep failed or not; this will cause SPM + * to wake up system immediately after system suspend complete if ip sleep + * fails, it is what we wanted. + */ +static int __maybe_unused xhci_mtk_suspend(struct device *dev) { struct xhci_hcd_mtk *mtk = dev_get_drvdata(dev); + struct usb_hcd *hcd = mtk->hcd; + struct xhci_hcd *xhci = hcd_to_xhci(hcd); + + xhci_dbg(xhci, "%s: stop port polling\n", __func__); + clear_bit(HCD_FLAG_POLL_RH, &hcd->flags); + del_timer_sync(&hcd->rh_timer); + clear_bit(HCD_FLAG_POLL_RH, &xhci->shared_hcd->flags); + del_timer_sync(&xhci->shared_hcd->rh_timer); xhci_mtk_host_disable(mtk); xhci_mtk_phy_power_off(mtk); @@ -707,24 +721,29 @@ static int xhci_mtk_suspend(struct device *dev) return 0; } -static int xhci_mtk_resume(struct device *dev) +static int __maybe_unused xhci_mtk_resume(struct device *dev) { struct xhci_hcd_mtk *mtk = dev_get_drvdata(dev); + struct usb_hcd *hcd = mtk->hcd; + struct xhci_hcd *xhci = hcd_to_xhci(hcd); usb_wakeup_disable(mtk); xhci_mtk_clks_enable(mtk); xhci_mtk_phy_power_on(mtk); xhci_mtk_host_enable(mtk); + + xhci_dbg(xhci, "%s: restart port polling\n", __func__); + set_bit(HCD_FLAG_POLL_RH, &hcd->flags); + usb_hcd_poll_rh_status(hcd); + set_bit(HCD_FLAG_POLL_RH, &xhci->shared_hcd->flags); + usb_hcd_poll_rh_status(xhci->shared_hcd); return 0; } static const struct dev_pm_ops xhci_mtk_pm_ops = { SET_SYSTEM_SLEEP_PM_OPS(xhci_mtk_suspend, xhci_mtk_resume) }; -#define DEV_PM_OPS (&xhci_mtk_pm_ops) -#else -#define DEV_PM_OPS NULL -#endif /* CONFIG_PM */ +#define DEV_PM_OPS IS_ENABLED(CONFIG_PM) ? &xhci_mtk_pm_ops : NULL #ifdef CONFIG_OF static const struct of_device_id mtk_xhci_of_match[] = { diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index 58c43ed7ff3b..f0640b7a1c42 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -28,7 +28,9 @@ #include "xhci.h" #include "xhci-trace.h" -#define PORT2_SSIC_CONFIG_REG2 0x883c +#define SSIC_PORT_NUM 2 +#define SSIC_PORT_CFG2 0x880c +#define SSIC_PORT_CFG2_OFFSET 0x30 #define PROG_DONE (1 << 30) #define SSIC_PORT_UNUSED (1 << 31) @@ -45,6 +47,7 @@ #define PCI_DEVICE_ID_INTEL_CHERRYVIEW_XHCI 0x22b5 #define PCI_DEVICE_ID_INTEL_SUNRISEPOINT_H_XHCI 0xa12f #define PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_XHCI 0x9d2f +#define PCI_DEVICE_ID_INTEL_BROXTON_M_XHCI 0x0aa8 static const char hcd_name[] = "xhci_hcd"; @@ -151,9 +154,14 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) if (pdev->vendor == PCI_VENDOR_ID_INTEL && (pdev->device == PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_XHCI || pdev->device == PCI_DEVICE_ID_INTEL_SUNRISEPOINT_H_XHCI || - pdev->device == PCI_DEVICE_ID_INTEL_CHERRYVIEW_XHCI)) { + pdev->device == PCI_DEVICE_ID_INTEL_CHERRYVIEW_XHCI || + pdev->device == PCI_DEVICE_ID_INTEL_BROXTON_M_XHCI)) { xhci->quirks |= XHCI_PME_STUCK_QUIRK; } + if (pdev->vendor == PCI_VENDOR_ID_INTEL && + pdev->device == PCI_DEVICE_ID_INTEL_CHERRYVIEW_XHCI) { + xhci->quirks |= XHCI_SSIC_PORT_UNUSED; + } if (pdev->vendor == PCI_VENDOR_ID_ETRON && pdev->device == PCI_DEVICE_ID_EJ168) { xhci->quirks |= XHCI_RESET_ON_RESUME; @@ -312,22 +320,20 @@ static void xhci_pci_remove(struct pci_dev *dev) * SSIC PORT need to be marked as "unused" before putting xHCI * into D3. After D3 exit, the SSIC port need to be marked as "used". * Without this change, xHCI might not enter D3 state. - * Make sure PME works on some Intel xHCI controllers by writing 1 to clear - * the Internal PME flag bit in vendor specific PMCTRL register at offset 0x80a4 */ -static void xhci_pme_quirk(struct usb_hcd *hcd, bool suspend) +static void xhci_ssic_port_unused_quirk(struct usb_hcd *hcd, bool suspend) { struct xhci_hcd *xhci = hcd_to_xhci(hcd); - struct pci_dev *pdev = to_pci_dev(hcd->self.controller); u32 val; void __iomem *reg; + int i; - if (pdev->vendor == PCI_VENDOR_ID_INTEL && - pdev->device == PCI_DEVICE_ID_INTEL_CHERRYVIEW_XHCI) { - - reg = (void __iomem *) xhci->cap_regs + PORT2_SSIC_CONFIG_REG2; + for (i = 0; i < SSIC_PORT_NUM; i++) { + reg = (void __iomem *) xhci->cap_regs + + SSIC_PORT_CFG2 + + i * SSIC_PORT_CFG2_OFFSET; - /* Notify SSIC that SSIC profile programming is not done */ + /* Notify SSIC that SSIC profile programming is not done. */ val = readl(reg) & ~PROG_DONE; writel(val, reg); @@ -344,6 +350,17 @@ static void xhci_pme_quirk(struct usb_hcd *hcd, bool suspend) writel(val, reg); readl(reg); } +} + +/* + * Make sure PME works on some Intel xHCI controllers by writing 1 to clear + * the Internal PME flag bit in vendor specific PMCTRL register at offset 0x80a4 + */ +static void xhci_pme_quirk(struct usb_hcd *hcd) +{ + struct xhci_hcd *xhci = hcd_to_xhci(hcd); + void __iomem *reg; + u32 val; reg = (void __iomem *) xhci->cap_regs + 0x80a4; val = readl(reg); @@ -355,6 +372,7 @@ static int xhci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup) { struct xhci_hcd *xhci = hcd_to_xhci(hcd); struct pci_dev *pdev = to_pci_dev(hcd->self.controller); + int ret; /* * Systems with the TI redriver that loses port status change events @@ -364,9 +382,16 @@ static int xhci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup) pdev->no_d3cold = true; if (xhci->quirks & XHCI_PME_STUCK_QUIRK) - xhci_pme_quirk(hcd, true); + xhci_pme_quirk(hcd); + + if (xhci->quirks & XHCI_SSIC_PORT_UNUSED) + xhci_ssic_port_unused_quirk(hcd, true); - return xhci_suspend(xhci, do_wakeup); + ret = xhci_suspend(xhci, do_wakeup); + if (ret && (xhci->quirks & XHCI_SSIC_PORT_UNUSED)) + xhci_ssic_port_unused_quirk(hcd, false); + + return ret; } static int xhci_pci_resume(struct usb_hcd *hcd, bool hibernated) @@ -396,8 +421,11 @@ static int xhci_pci_resume(struct usb_hcd *hcd, bool hibernated) if (pdev->vendor == PCI_VENDOR_ID_INTEL) usb_enable_intel_xhci_ports(pdev); + if (xhci->quirks & XHCI_SSIC_PORT_UNUSED) + xhci_ssic_port_unused_quirk(hcd, false); + if (xhci->quirks & XHCI_PME_STUCK_QUIRK) - xhci_pme_quirk(hcd, false); + xhci_pme_quirk(hcd); retval = xhci_resume(xhci, hibernated); return retval; diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c index 770b6b088797..5c15e9bc5f7a 100644 --- a/drivers/usb/host/xhci-plat.c +++ b/drivers/usb/host/xhci-plat.c @@ -110,7 +110,13 @@ static const struct of_device_id usb_xhci_of_match[] = { .compatible = "renesas,xhci-r8a7795", .data = &xhci_plat_renesas_rcar_gen3, }, { + .compatible = "renesas,rcar-gen2-xhci", + .data = &xhci_plat_renesas_rcar_gen2, + }, { + .compatible = "renesas,rcar-gen3-xhci", + .data = &xhci_plat_renesas_rcar_gen3, }, + {}, }; MODULE_DEVICE_TABLE(of, usb_xhci_of_match); #endif @@ -184,7 +190,8 @@ static int xhci_plat_probe(struct platform_device *pdev) struct xhci_plat_priv *priv = hcd_to_xhci_priv(hcd); /* Just copy data for now */ - *priv = *priv_match; + if (priv_match) + *priv = *priv_match; } if (xhci_plat_type_is(hcd, XHCI_PLAT_TYPE_MARVELL_ARMADA)) { diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index f1c21c40b4a6..7cf66212ceae 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -2193,10 +2193,6 @@ static int process_bulk_intr_td(struct xhci_hcd *xhci, struct xhci_td *td, } /* Fast path - was this the last TRB in the TD for this URB? */ } else if (event_trb == td->last_trb) { - if (td->urb_length_set && trb_comp_code == COMP_SHORT_TX) - return finish_td(xhci, td, event_trb, event, ep, - status, false); - if (EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)) != 0) { td->urb->actual_length = td->urb->transfer_buffer_length - @@ -2248,12 +2244,6 @@ static int process_bulk_intr_td(struct xhci_hcd *xhci, struct xhci_td *td, td->urb->actual_length += TRB_LEN(le32_to_cpu(cur_trb->generic.field[2])) - EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)); - - if (trb_comp_code == COMP_SHORT_TX) { - xhci_dbg(xhci, "mid bulk/intr SP, wait for last TRB event\n"); - td->urb_length_set = true; - return 0; - } } return finish_td(xhci, td, event_trb, event, ep, status, false); @@ -3568,12 +3558,11 @@ static int count_isoc_trbs_needed(struct xhci_hcd *xhci, * zero. Only xHCI 1.0 host controllers support this field. */ static unsigned int xhci_get_burst_count(struct xhci_hcd *xhci, - struct usb_device *udev, struct urb *urb, unsigned int total_packet_count) { unsigned int max_burst; - if (xhci->hci_version < 0x100 || udev->speed != USB_SPEED_SUPER) + if (xhci->hci_version < 0x100 || urb->dev->speed < USB_SPEED_SUPER) return 0; max_burst = urb->ep->ss_ep_comp.bMaxBurst; @@ -3589,7 +3578,6 @@ static unsigned int xhci_get_burst_count(struct xhci_hcd *xhci, * contain 1 to (bMaxBurst + 1) packets. */ static unsigned int xhci_get_last_burst_packet_count(struct xhci_hcd *xhci, - struct usb_device *udev, struct urb *urb, unsigned int total_packet_count) { unsigned int max_burst; @@ -3598,8 +3586,7 @@ static unsigned int xhci_get_last_burst_packet_count(struct xhci_hcd *xhci, if (xhci->hci_version < 0x100) return 0; - switch (udev->speed) { - case USB_SPEED_SUPER: + if (urb->dev->speed >= USB_SPEED_SUPER) { /* bMaxBurst is zero based: 0 means 1 packet per burst */ max_burst = urb->ep->ss_ep_comp.bMaxBurst; residue = total_packet_count % (max_burst + 1); @@ -3609,11 +3596,10 @@ static unsigned int xhci_get_last_burst_packet_count(struct xhci_hcd *xhci, if (residue == 0) return max_burst; return residue - 1; - default: - if (total_packet_count == 0) - return 0; - return total_packet_count - 1; } + if (total_packet_count == 0) + return 0; + return total_packet_count - 1; } /* @@ -3724,6 +3710,7 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags, int i, j; bool more_trbs_coming; struct xhci_virt_ep *xep; + int frame_id; xep = &xhci->devs[slot_id]->eps[ep_index]; ep_ring = xhci->devs[slot_id]->eps[ep_index].ring; @@ -3733,33 +3720,31 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags, xhci_dbg(xhci, "Isoc URB with zero packets?\n"); return -EINVAL; } - start_addr = (u64) urb->transfer_dma; start_trb = &ep_ring->enqueue->generic; start_cycle = ep_ring->cycle_state; urb_priv = urb->hcpriv; - /* Queue the first TRB, even if it's zero-length */ + /* Queue the TRBs for each TD, even if they are zero-length */ for (i = 0; i < num_tds; i++) { - unsigned int total_packet_count; - unsigned int burst_count; - unsigned int residue; + unsigned int total_pkt_count, max_pkt; + unsigned int burst_count, last_burst_pkt_count; + u32 sia_frame_id; first_trb = true; running_total = 0; addr = start_addr + urb->iso_frame_desc[i].offset; td_len = urb->iso_frame_desc[i].length; td_remain_len = td_len; - total_packet_count = DIV_ROUND_UP(td_len, - GET_MAX_PACKET( - usb_endpoint_maxp(&urb->ep->desc))); + max_pkt = GET_MAX_PACKET(usb_endpoint_maxp(&urb->ep->desc)); + total_pkt_count = DIV_ROUND_UP(td_len, max_pkt); + /* A zero-length transfer still involves at least one packet. */ - if (total_packet_count == 0) - total_packet_count++; - burst_count = xhci_get_burst_count(xhci, urb->dev, urb, - total_packet_count); - residue = xhci_get_last_burst_packet_count(xhci, - urb->dev, urb, total_packet_count); + if (total_pkt_count == 0) + total_pkt_count++; + burst_count = xhci_get_burst_count(xhci, urb, total_pkt_count); + last_burst_pkt_count = xhci_get_last_burst_packet_count(xhci, + urb, total_pkt_count); trbs_per_td = count_isoc_trbs_needed(xhci, urb, i); @@ -3770,68 +3755,57 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags, return ret; goto cleanup; } - td = urb_priv->td[i]; + + /* use SIA as default, if frame id is used overwrite it */ + sia_frame_id = TRB_SIA; + if (!(urb->transfer_flags & URB_ISO_ASAP) && + HCC_CFC(xhci->hcc_params)) { + frame_id = xhci_get_isoc_frame_id(xhci, urb, i); + if (frame_id >= 0) + sia_frame_id = TRB_FRAME_ID(frame_id); + } + /* + * Set isoc specific data for the first TRB in a TD. + * Prevent HW from getting the TRBs by keeping the cycle state + * inverted in the first TDs isoc TRB. + */ + field = TRB_TYPE(TRB_ISOC) | + TRB_TLBPC(last_burst_pkt_count) | + sia_frame_id | + (i ? ep_ring->cycle_state : !start_cycle); + + /* xhci 1.1 with ETE uses TD_Size field for TBC, old is Rsvdz */ + if (!xep->use_extended_tbc) + field |= TRB_TBC(burst_count); + + /* fill the rest of the TRB fields, and remaining normal TRBs */ for (j = 0; j < trbs_per_td; j++) { - int frame_id = 0; u32 remainder = 0; - field = 0; - - if (first_trb) { - field = TRB_TBC(burst_count) | - TRB_TLBPC(residue); - /* Queue the isoc TRB */ - field |= TRB_TYPE(TRB_ISOC); - - /* Calculate Frame ID and SIA fields */ - if (!(urb->transfer_flags & URB_ISO_ASAP) && - HCC_CFC(xhci->hcc_params)) { - frame_id = xhci_get_isoc_frame_id(xhci, - urb, - i); - if (frame_id >= 0) - field |= TRB_FRAME_ID(frame_id); - else - field |= TRB_SIA; - } else - field |= TRB_SIA; - - if (i == 0) { - if (start_cycle == 0) - field |= 0x1; - } else - field |= ep_ring->cycle_state; - first_trb = false; - } else { - /* Queue other normal TRBs */ - field |= TRB_TYPE(TRB_NORMAL); - field |= ep_ring->cycle_state; - } + + /* only first TRB is isoc, overwrite otherwise */ + if (!first_trb) + field = TRB_TYPE(TRB_NORMAL) | + ep_ring->cycle_state; /* Only set interrupt on short packet for IN EPs */ if (usb_urb_dir_in(urb)) field |= TRB_ISP; - /* Chain all the TRBs together; clear the chain bit in - * the last TRB to indicate it's the last TRB in the - * chain. - */ + /* Set the chain bit for all except the last TRB */ if (j < trbs_per_td - 1) { - field |= TRB_CHAIN; more_trbs_coming = true; + field |= TRB_CHAIN; } else { + more_trbs_coming = false; td->last_trb = ep_ring->enqueue; field |= TRB_IOC; - if (xhci->hci_version == 0x100 && - !(xhci->quirks & - XHCI_AVOID_BEI)) { - /* Set BEI bit except for the last td */ - if (i < num_tds - 1) - field |= TRB_BEI; - } - more_trbs_coming = false; + /* set BEI, except for the last TD */ + if (xhci->hci_version >= 0x100 && + !(xhci->quirks & XHCI_AVOID_BEI) && + i < num_tds - 1) + field |= TRB_BEI; } - /* Calculate TRB length */ trb_buff_len = TRB_MAX_BUFF_SIZE - (addr & ((1 << TRB_MAX_BUFF_SHIFT) - 1)); @@ -3844,9 +3818,15 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags, urb, trbs_per_td - j - 1); length_field = TRB_LEN(trb_buff_len) | - TRB_TD_SIZE(remainder) | TRB_INTR_TARGET(0); + /* xhci 1.1 with ETE uses TD Size field for TBC */ + if (first_trb && xep->use_extended_tbc) + length_field |= TRB_TD_SIZE_TBC(burst_count); + else + length_field |= TRB_TD_SIZE(remainder); + first_trb = false; + queue_trb(xhci, ep_ring, more_trbs_coming, lower_32_bits(addr), upper_32_bits(addr), diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 26a44c0e969e..d51ee0c3cf9f 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -1554,7 +1554,9 @@ int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb, "HW died, freeing TD."); urb_priv = urb->hcpriv; - for (i = urb_priv->td_cnt; i < urb_priv->length; i++) { + for (i = urb_priv->td_cnt; + i < urb_priv->length && xhci->devs[urb->dev->slot_id]; + i++) { td = urb_priv->td[i]; if (!list_empty(&td->td_list)) list_del_init(&td->td_list); @@ -2084,6 +2086,7 @@ static unsigned int xhci_get_block_size(struct usb_device *udev) case USB_SPEED_HIGH: return HS_BLOCK; case USB_SPEED_SUPER: + case USB_SPEED_SUPER_PLUS: return SS_BLOCK; case USB_SPEED_UNKNOWN: case USB_SPEED_WIRELESS: @@ -2209,7 +2212,7 @@ static int xhci_check_bw_table(struct xhci_hcd *xhci, unsigned int packets_remaining = 0; unsigned int i; - if (virt_dev->udev->speed == USB_SPEED_SUPER) + if (virt_dev->udev->speed >= USB_SPEED_SUPER) return xhci_check_ss_bw(xhci, virt_dev); if (virt_dev->udev->speed == USB_SPEED_HIGH) { @@ -2410,7 +2413,7 @@ void xhci_drop_ep_from_interval_table(struct xhci_hcd *xhci, if (xhci_is_async_ep(ep_bw->type)) return; - if (udev->speed == USB_SPEED_SUPER) { + if (udev->speed >= USB_SPEED_SUPER) { if (xhci_is_sync_in_ep(ep_bw->type)) xhci->devs[udev->slot_id]->bw_table->ss_bw_in -= xhci_get_ss_bw_consumed(ep_bw); @@ -2448,6 +2451,7 @@ void xhci_drop_ep_from_interval_table(struct xhci_hcd *xhci, interval_bw->overhead[HS_OVERHEAD_TYPE] -= 1; break; case USB_SPEED_SUPER: + case USB_SPEED_SUPER_PLUS: case USB_SPEED_UNKNOWN: case USB_SPEED_WIRELESS: /* Should never happen because only LS/FS/HS endpoints will get @@ -2507,6 +2511,7 @@ static void xhci_add_ep_to_interval_table(struct xhci_hcd *xhci, interval_bw->overhead[HS_OVERHEAD_TYPE] += 1; break; case USB_SPEED_SUPER: + case USB_SPEED_SUPER_PLUS: case USB_SPEED_UNKNOWN: case USB_SPEED_WIRELESS: /* Should never happen because only LS/FS/HS endpoints will get @@ -4895,6 +4900,7 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks) if (xhci->sbrn == 0x31) { xhci_info(xhci, "Host supports USB 3.1 Enhanced SuperSpeed\n"); hcd->speed = HCD_USB31; + hcd->self.root_hub->speed = USB_SPEED_SUPER_PLUS; } /* xHCI private pointer was set in xhci_pci_probe for the second * registered roothub. diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 9be7348872ba..e293e0974f48 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -232,7 +232,9 @@ struct xhci_op_regs { * disabled, or powered-off state. */ #define CMD_PM_INDEX (1 << 11) -/* bits 12:31 are reserved (and should be preserved on writes). */ +/* bit 14 Extended TBC Enable, changes Isoc TRB fields to support larger TBC */ +#define CMD_ETE (1 << 14) +/* bits 15:31 are reserved (and should be preserved on writes). */ /* IMAN - Interrupt Management Register */ #define IMAN_IE (1 << 1) @@ -343,6 +345,7 @@ struct xhci_op_regs { #define SLOT_SPEED_LS (XDEV_LS << 10) #define SLOT_SPEED_HS (XDEV_HS << 10) #define SLOT_SPEED_SS (XDEV_SS << 10) +#define SLOT_SPEED_SSP (XDEV_SSP << 10) /* Port Indicator Control */ #define PORT_LED_OFF (0 << 14) #define PORT_LED_AMBER (1 << 14) @@ -748,8 +751,9 @@ struct xhci_ep_ctx { #define GET_MAX_PACKET(p) ((p) & 0x7ff) /* tx_info bitmasks */ -#define AVG_TRB_LENGTH_FOR_EP(p) ((p) & 0xffff) -#define MAX_ESIT_PAYLOAD_FOR_EP(p) (((p) & 0xffff) << 16) +#define EP_AVG_TRB_LENGTH(p) ((p) & 0xffff) +#define EP_MAX_ESIT_PAYLOAD_LO(p) (((p) & 0xffff) << 16) +#define EP_MAX_ESIT_PAYLOAD_HI(p) ((((p) >> 16) & 0xff) << 24) #define CTX_TO_MAX_ESIT_PAYLOAD(p) (((p) >> 16) & 0xffff) /* deq bitmasks */ @@ -941,6 +945,8 @@ struct xhci_virt_ep { struct list_head bw_endpoint_list; /* Isoch Frame ID checking storage */ int next_frame_id; + /* Use new Isoch TRB layout needed for extended TBC support */ + bool use_extended_tbc; }; enum xhci_overhead_type { @@ -1182,9 +1188,12 @@ enum xhci_setup_dev { #define TRB_LEN(p) ((p) & 0x1ffff) /* TD Size, packets remaining in this TD, bits 21:17 (5 bits, so max 31) */ #define TRB_TD_SIZE(p) (min((p), (u32)31) << 17) +/* xhci 1.1 uses the TD_SIZE field for TBC if Extended TBC is enabled (ETE) */ +#define TRB_TD_SIZE_TBC(p) (min((p), (u32)31) << 17) /* Interrupter Target - which MSI-X vector to target the completion event at */ #define TRB_INTR_TARGET(p) (((p) & 0x3ff) << 22) #define GET_INTR_TARGET(p) (((p) >> 22) & 0x3ff) +/* Total burst count field, Rsvdz on xhci 1.1 with Extended TBC enabled (ETE) */ #define TRB_TBC(p) (((p) & 0x3) << 7) #define TRB_TLBPC(p) (((p) & 0xf) << 16) @@ -1631,6 +1640,7 @@ struct xhci_hcd { #define XHCI_BROKEN_STREAMS (1 << 19) #define XHCI_PME_STUCK_QUIRK (1 << 20) #define XHCI_MTK_HOST (1 << 21) +#define XHCI_SSIC_PORT_UNUSED (1 << 22) unsigned int num_active_eps; unsigned int limit_active_eps; /* There are two roothubs to keep track of bus suspend info for */ |