summaryrefslogtreecommitdiff
path: root/drivers/usb/host
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/host')
-rw-r--r--drivers/usb/host/Kconfig12
-rw-r--r--drivers/usb/host/Makefile4
-rw-r--r--drivers/usb/host/ehci-dbg.c2
-rw-r--r--drivers/usb/host/ehci-fsl.c4
-rw-r--r--drivers/usb/host/ehci-hcd.c2
-rw-r--r--drivers/usb/host/ehci-mem.c12
-rw-r--r--drivers/usb/host/ehci-orion.c36
-rw-r--r--drivers/usb/host/ehci-platform.c10
-rw-r--r--drivers/usb/host/fotg210-hcd.c2
-rw-r--r--drivers/usb/host/ohci-hcd.c5
-rw-r--r--drivers/usb/host/ohci-pci.c16
-rw-r--r--drivers/usb/host/ohci-platform.c3
-rw-r--r--drivers/usb/host/ohci.h3
-rw-r--r--drivers/usb/host/oxu210hp-hcd.c2
-rw-r--r--drivers/usb/host/pci-quirks.h4
-rw-r--r--drivers/usb/host/uhci-hcd.c2
-rw-r--r--drivers/usb/host/uhci-hcd.h2
-rw-r--r--drivers/usb/host/xhci-dbg.c308
-rw-r--r--drivers/usb/host/xhci-hub.c167
-rw-r--r--drivers/usb/host/xhci-mem.c53
-rw-r--r--drivers/usb/host/xhci-pci.c3
-rw-r--r--drivers/usb/host/xhci-plat.c121
-rw-r--r--drivers/usb/host/xhci-plat.h1
-rw-r--r--drivers/usb/host/xhci-rcar.c11
-rw-r--r--drivers/usb/host/xhci-rcar.h6
-rw-r--r--drivers/usb/host/xhci-ring.c266
-rw-r--r--drivers/usb/host/xhci-trace.h174
-rw-r--r--drivers/usb/host/xhci.c334
-rw-r--r--drivers/usb/host/xhci.h333
29 files changed, 1093 insertions, 805 deletions
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 407d947b34ea..ababb91d654a 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -30,7 +30,7 @@ if USB_XHCI_HCD
config USB_XHCI_PCI
tristate
- depends on PCI
+ depends on USB_PCI
default y
config USB_XHCI_PLATFORM
@@ -139,7 +139,7 @@ if USB_EHCI_HCD
config USB_EHCI_PCI
tristate
- depends on PCI
+ depends on USB_PCI
default y
config USB_EHCI_HCD_PMC_MSP
@@ -188,7 +188,7 @@ config USB_EHCI_HCD_OMAP
config USB_EHCI_HCD_ORION
tristate "Support for Marvell EBU on-chip EHCI USB controller"
- depends on USB_EHCI_HCD && PLAT_ORION
+ depends on USB_EHCI_HCD && (PLAT_ORION || ARCH_MVEBU)
default y
---help---
Enables support for the on-chip EHCI controller on Marvell's
@@ -525,7 +525,7 @@ config USB_OHCI_HCD_PPC_OF
config USB_OHCI_HCD_PCI
tristate "OHCI support for PCI-bus USB controllers"
- depends on PCI
+ depends on USB_PCI
default y
select USB_OHCI_LITTLE_ENDIAN
---help---
@@ -606,7 +606,7 @@ endif # USB_OHCI_HCD
config USB_UHCI_HCD
tristate "UHCI HCD (most Intel and VIA) support"
- depends on PCI || USB_UHCI_SUPPORT_NON_PCI_HC
+ depends on USB_PCI || USB_UHCI_SUPPORT_NON_PCI_HC
---help---
The Universal Host Controller Interface is a standard by Intel for
accessing the USB hardware in the PC (which is also called the USB
@@ -739,7 +739,7 @@ config USB_RENESAS_USBHS_HCD
config USB_WHCI_HCD
tristate "Wireless USB Host Controller Interface (WHCI) driver"
- depends on PCI && USB && UWB
+ depends on USB_PCI && USB && UWB
select USB_WUSB
select UWB_WHCI
help
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index 2644537b7bcf..c77b0a38557b 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -27,9 +27,7 @@ endif
obj-$(CONFIG_USB_WHCI_HCD) += whci/
-ifneq ($(CONFIG_USB), )
- obj-$(CONFIG_PCI) += pci-quirks.o
-endif
+obj-$(CONFIG_USB_PCI) += pci-quirks.o
obj-$(CONFIG_USB_EHCI_HCD) += ehci-hcd.o
obj-$(CONFIG_USB_EHCI_PCI) += ehci-pci.o
diff --git a/drivers/usb/host/ehci-dbg.c b/drivers/usb/host/ehci-dbg.c
index 1a2614aae42c..cbb9b8e12c3c 100644
--- a/drivers/usb/host/ehci-dbg.c
+++ b/drivers/usb/host/ehci-dbg.c
@@ -803,7 +803,7 @@ static ssize_t fill_registers_buffer(struct debug_buffer *buf)
size -= temp;
next += temp;
-#ifdef CONFIG_PCI
+#ifdef CONFIG_USB_PCI
/* EHCI 0.96 and later may have "extended capabilities" */
if (dev_is_pci(hcd->self.controller)) {
struct pci_dev *pdev;
diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c
index 3733aab46efe..4a08b70c81aa 100644
--- a/drivers/usb/host/ehci-fsl.c
+++ b/drivers/usb/host/ehci-fsl.c
@@ -96,8 +96,8 @@ static int fsl_ehci_drv_probe(struct platform_device *pdev)
}
irq = res->start;
- hcd = usb_create_hcd(&fsl_ehci_hc_driver, &pdev->dev,
- dev_name(&pdev->dev));
+ hcd = __usb_create_hcd(&fsl_ehci_hc_driver, pdev->dev.parent,
+ &pdev->dev, dev_name(&pdev->dev), NULL);
if (!hcd) {
retval = -ENOMEM;
goto err1;
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index ac2c4eab478d..6e834b83a104 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -597,7 +597,7 @@ static int ehci_run (struct usb_hcd *hcd)
/*
* hcc_params controls whether ehci->regs->segment must (!!!)
* be used; it constrains QH/ITD/SITD and QTD locations.
- * pci_pool consistent memory always uses segment zero.
+ * dma_pool consistent memory always uses segment zero.
* streaming mappings for I/O buffers, like pci_map_single(),
* can return segments above 4GB, if the device allows.
*
diff --git a/drivers/usb/host/ehci-mem.c b/drivers/usb/host/ehci-mem.c
index 4de43011df23..9b7e63977215 100644
--- a/drivers/usb/host/ehci-mem.c
+++ b/drivers/usb/host/ehci-mem.c
@@ -138,7 +138,7 @@ static void ehci_mem_cleanup (struct ehci_hcd *ehci)
ehci->sitd_pool = NULL;
if (ehci->periodic)
- dma_free_coherent (ehci_to_hcd(ehci)->self.controller,
+ dma_free_coherent(ehci_to_hcd(ehci)->self.sysdev,
ehci->periodic_size * sizeof (u32),
ehci->periodic, ehci->periodic_dma);
ehci->periodic = NULL;
@@ -155,7 +155,7 @@ static int ehci_mem_init (struct ehci_hcd *ehci, gfp_t flags)
/* QTDs for control/bulk/intr transfers */
ehci->qtd_pool = dma_pool_create ("ehci_qtd",
- ehci_to_hcd(ehci)->self.controller,
+ ehci_to_hcd(ehci)->self.sysdev,
sizeof (struct ehci_qtd),
32 /* byte alignment (for hw parts) */,
4096 /* can't cross 4K */);
@@ -165,7 +165,7 @@ static int ehci_mem_init (struct ehci_hcd *ehci, gfp_t flags)
/* QHs for control/bulk/intr transfers */
ehci->qh_pool = dma_pool_create ("ehci_qh",
- ehci_to_hcd(ehci)->self.controller,
+ ehci_to_hcd(ehci)->self.sysdev,
sizeof(struct ehci_qh_hw),
32 /* byte alignment (for hw parts) */,
4096 /* can't cross 4K */);
@@ -179,7 +179,7 @@ static int ehci_mem_init (struct ehci_hcd *ehci, gfp_t flags)
/* ITD for high speed ISO transfers */
ehci->itd_pool = dma_pool_create ("ehci_itd",
- ehci_to_hcd(ehci)->self.controller,
+ ehci_to_hcd(ehci)->self.sysdev,
sizeof (struct ehci_itd),
32 /* byte alignment (for hw parts) */,
4096 /* can't cross 4K */);
@@ -189,7 +189,7 @@ static int ehci_mem_init (struct ehci_hcd *ehci, gfp_t flags)
/* SITD for full/low speed split ISO transfers */
ehci->sitd_pool = dma_pool_create ("ehci_sitd",
- ehci_to_hcd(ehci)->self.controller,
+ ehci_to_hcd(ehci)->self.sysdev,
sizeof (struct ehci_sitd),
32 /* byte alignment (for hw parts) */,
4096 /* can't cross 4K */);
@@ -199,7 +199,7 @@ static int ehci_mem_init (struct ehci_hcd *ehci, gfp_t flags)
/* Hardware periodic table */
ehci->periodic = (__le32 *)
- dma_alloc_coherent (ehci_to_hcd(ehci)->self.controller,
+ dma_alloc_coherent(ehci_to_hcd(ehci)->self.sysdev,
ehci->periodic_size * sizeof(__le32),
&ehci->periodic_dma, flags);
if (ehci->periodic == NULL) {
diff --git a/drivers/usb/host/ehci-orion.c b/drivers/usb/host/ehci-orion.c
index ee8d5faa0194..1aec87ec68df 100644
--- a/drivers/usb/host/ehci-orion.c
+++ b/drivers/usb/host/ehci-orion.c
@@ -47,6 +47,18 @@
#define USB_PHY_IVREF_CTRL 0x440
#define USB_PHY_TST_GRP_CTRL 0x450
+#define USB_SBUSCFG 0x90
+
+/* BAWR = BARD = 3 : Align read/write bursts packets larger than 128 bytes */
+#define USB_SBUSCFG_BAWR_ALIGN_128B (0x3 << 6)
+#define USB_SBUSCFG_BARD_ALIGN_128B (0x3 << 3)
+/* AHBBRST = 3 : Align AHB Burst to INCR16 (64 bytes) */
+#define USB_SBUSCFG_AHBBRST_INCR16 (0x3 << 0)
+
+#define USB_SBUSCFG_DEF_VAL (USB_SBUSCFG_BAWR_ALIGN_128B \
+ | USB_SBUSCFG_BARD_ALIGN_128B \
+ | USB_SBUSCFG_AHBBRST_INCR16)
+
#define DRIVER_DESC "EHCI orion driver"
#define hcd_to_orion_priv(h) ((struct orion_ehci_hcd *)hcd_to_ehci(h)->priv)
@@ -151,8 +163,31 @@ ehci_orion_conf_mbus_windows(struct usb_hcd *hcd,
}
}
+static int ehci_orion_drv_reset(struct usb_hcd *hcd)
+{
+ struct device *dev = hcd->self.controller;
+ int ret;
+
+ ret = ehci_setup(hcd);
+ if (ret)
+ return ret;
+
+ /*
+ * For SoC without hlock, need to program sbuscfg value to guarantee
+ * AHB master's burst would not overrun or underrun FIFO.
+ *
+ * sbuscfg reg has to be set after usb controller reset, otherwise
+ * the value would be override to 0.
+ */
+ if (of_device_is_compatible(dev->of_node, "marvell,armada-3700-ehci"))
+ wrl(USB_SBUSCFG, USB_SBUSCFG_DEF_VAL);
+
+ return ret;
+}
+
static const struct ehci_driver_overrides orion_overrides __initconst = {
.extra_priv_size = sizeof(struct orion_ehci_hcd),
+ .reset = ehci_orion_drv_reset,
};
static int ehci_orion_drv_probe(struct platform_device *pdev)
@@ -310,6 +345,7 @@ static int ehci_orion_drv_remove(struct platform_device *pdev)
static const struct of_device_id ehci_orion_dt_ids[] = {
{ .compatible = "marvell,orion-ehci", },
+ { .compatible = "marvell,armada-3700-ehci", },
{},
};
MODULE_DEVICE_TABLE(of, ehci_orion_dt_ids);
diff --git a/drivers/usb/host/ehci-platform.c b/drivers/usb/host/ehci-platform.c
index a268d9e8d6cf..bc7b9be12f54 100644
--- a/drivers/usb/host/ehci-platform.c
+++ b/drivers/usb/host/ehci-platform.c
@@ -34,6 +34,7 @@
#include <linux/usb.h>
#include <linux/usb/hcd.h>
#include <linux/usb/ehci_pdriver.h>
+#include <linux/usb/of.h>
#include "ehci.h"
@@ -220,6 +221,9 @@ static int ehci_platform_probe(struct platform_device *dev)
if (IS_ERR(priv->phys[phy_num])) {
err = PTR_ERR(priv->phys[phy_num]);
goto err_put_hcd;
+ } else if (!hcd->phy) {
+ /* Avoiding phy_get() in usb_add_hcd() */
+ hcd->phy = priv->phys[phy_num];
}
}
@@ -297,6 +301,7 @@ static int ehci_platform_probe(struct platform_device *dev)
goto err_power;
device_wakeup_enable(hcd->self.controller);
+ device_enable_async_suspend(hcd->self.controller);
platform_set_drvdata(dev, hcd);
return err;
@@ -370,6 +375,7 @@ static int ehci_platform_resume(struct device *dev)
struct usb_ehci_pdata *pdata = dev_get_platdata(dev);
struct platform_device *pdev = to_platform_device(dev);
struct ehci_platform_priv *priv = hcd_to_ehci_priv(hcd);
+ struct device *companion_dev;
if (pdata->power_on) {
int err = pdata->power_on(pdev);
@@ -377,6 +383,10 @@ static int ehci_platform_resume(struct device *dev)
return err;
}
+ companion_dev = usb_of_get_companion_dev(hcd->self.controller);
+ if (companion_dev)
+ device_pm_wait_for_dev(hcd->self.controller, companion_dev);
+
ehci_resume(hcd, priv->reset_on_resume);
return 0;
}
diff --git a/drivers/usb/host/fotg210-hcd.c b/drivers/usb/host/fotg210-hcd.c
index 1c5b34b74860..ced08dc229ad 100644
--- a/drivers/usb/host/fotg210-hcd.c
+++ b/drivers/usb/host/fotg210-hcd.c
@@ -5047,7 +5047,7 @@ static int fotg210_run(struct usb_hcd *hcd)
/*
* hcc_params controls whether fotg210->regs->segment must (!!!)
* be used; it constrains QH/ITD/SITD and QTD locations.
- * pci_pool consistent memory always uses segment zero.
+ * dma_pool consistent memory always uses segment zero.
* streaming mappings for I/O buffers, like pci_map_single(),
* can return segments above 4GB, if the device allows.
*
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index b6daf2e69989..44924824fa41 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -231,7 +231,8 @@ static int ohci_urb_enqueue (
/* Start up the I/O watchdog timer, if it's not running */
if (!timer_pending(&ohci->io_watchdog) &&
- list_empty(&ohci->eds_in_use)) {
+ list_empty(&ohci->eds_in_use) &&
+ !(ohci->flags & OHCI_QUIRK_QEMU)) {
ohci->prev_frame_no = ohci_frame_no(ohci);
mod_timer(&ohci->io_watchdog,
jiffies + IO_WATCHDOG_DELAY);
@@ -994,7 +995,7 @@ static void ohci_stop (struct usb_hcd *hcd)
/*-------------------------------------------------------------------------*/
-#if defined(CONFIG_PM) || defined(CONFIG_PCI)
+#if defined(CONFIG_PM) || defined(CONFIG_USB_PCI)
/* must not be called from interrupt context */
int ohci_restart(struct ohci_hcd *ohci)
diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c
index bb1509675727..a84aebe9b0a9 100644
--- a/drivers/usb/host/ohci-pci.c
+++ b/drivers/usb/host/ohci-pci.c
@@ -164,6 +164,15 @@ static int ohci_quirk_amd700(struct usb_hcd *hcd)
return 0;
}
+static int ohci_quirk_qemu(struct usb_hcd *hcd)
+{
+ struct ohci_hcd *ohci = hcd_to_ohci(hcd);
+
+ ohci->flags |= OHCI_QUIRK_QEMU;
+ ohci_dbg(ohci, "enabled qemu quirk\n");
+ return 0;
+}
+
/* List of quirks for OHCI */
static const struct pci_device_id ohci_pci_quirks[] = {
{
@@ -214,6 +223,13 @@ static const struct pci_device_id ohci_pci_quirks[] = {
PCI_DEVICE(PCI_VENDOR_ID_ATI, 0x4399),
.driver_data = (unsigned long)ohci_quirk_amd700,
},
+ {
+ .vendor = PCI_VENDOR_ID_APPLE,
+ .device = 0x003f,
+ .subvendor = PCI_SUBVENDOR_ID_REDHAT_QUMRANET,
+ .subdevice = PCI_SUBDEVICE_ID_QEMU,
+ .driver_data = (unsigned long)ohci_quirk_qemu,
+ },
/* FIXME for some of the early AMD 760 southbridges, OHCI
* won't work at all. blacklist them.
diff --git a/drivers/usb/host/ohci-platform.c b/drivers/usb/host/ohci-platform.c
index 898b74086c12..6368fce43197 100644
--- a/drivers/usb/host/ohci-platform.c
+++ b/drivers/usb/host/ohci-platform.c
@@ -183,6 +183,9 @@ static int ohci_platform_probe(struct platform_device *dev)
if (IS_ERR(priv->phys[phy_num])) {
err = PTR_ERR(priv->phys[phy_num]);
goto err_put_hcd;
+ } else if (!hcd->phy) {
+ /* Avoiding phy_get() in usb_add_hcd() */
+ hcd->phy = priv->phys[phy_num];
}
}
diff --git a/drivers/usb/host/ohci.h b/drivers/usb/host/ohci.h
index 37f1725e7a46..12742d002d2d 100644
--- a/drivers/usb/host/ohci.h
+++ b/drivers/usb/host/ohci.h
@@ -418,6 +418,7 @@ struct ohci_hcd {
#define OHCI_QUIRK_AMD_PLL 0x200 /* AMD PLL quirk*/
#define OHCI_QUIRK_AMD_PREFETCH 0x400 /* pre-fetch for ISO transfer */
#define OHCI_QUIRK_GLOBAL_SUSPEND 0x800 /* must suspend ports */
+#define OHCI_QUIRK_QEMU 0x1000 /* relax timing expectations */
// there are also chip quirks/bugs in init logic
@@ -438,7 +439,7 @@ struct ohci_hcd {
};
-#ifdef CONFIG_PCI
+#ifdef CONFIG_USB_PCI
static inline int quirk_nec(struct ohci_hcd *ohci)
{
return ohci->flags & OHCI_QUIRK_NEC;
diff --git a/drivers/usb/host/oxu210hp-hcd.c b/drivers/usb/host/oxu210hp-hcd.c
index bcf531c44c70..ed20fb34c897 100644
--- a/drivers/usb/host/oxu210hp-hcd.c
+++ b/drivers/usb/host/oxu210hp-hcd.c
@@ -2708,7 +2708,7 @@ static int oxu_run(struct usb_hcd *hcd)
/* hcc_params controls whether oxu->regs->segment must (!!!)
* be used; it constrains QH/ITD/SITD and QTD locations.
- * pci_pool consistent memory always uses segment zero.
+ * dma_pool consistent memory always uses segment zero.
* streaming mappings for I/O buffers, like pci_map_single(),
* can return segments above 4GB, if the device allows.
*
diff --git a/drivers/usb/host/pci-quirks.h b/drivers/usb/host/pci-quirks.h
index c622ddf21c94..0222195bd5b0 100644
--- a/drivers/usb/host/pci-quirks.h
+++ b/drivers/usb/host/pci-quirks.h
@@ -1,7 +1,7 @@
#ifndef __LINUX_USB_PCI_QUIRKS_H
#define __LINUX_USB_PCI_QUIRKS_H
-#ifdef CONFIG_PCI
+#ifdef CONFIG_USB_PCI
void uhci_reset_hc(struct pci_dev *pdev, unsigned long base);
int uhci_check_and_reset_hc(struct pci_dev *pdev, unsigned long base);
int usb_amd_find_chipset_info(void);
@@ -21,6 +21,6 @@ static inline void usb_amd_quirk_pll_enable(void) {}
static inline void usb_amd_dev_put(void) {}
static inline void usb_disable_xhci_ports(struct pci_dev *xhci_pdev) {}
static inline void sb800_prefetch(struct device *dev, int on) {}
-#endif /* CONFIG_PCI */
+#endif /* CONFIG_USB_PCI */
#endif /* __LINUX_USB_PCI_QUIRKS_H */
diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c
index 683098afa93e..94b150196d4f 100644
--- a/drivers/usb/host/uhci-hcd.c
+++ b/drivers/usb/host/uhci-hcd.c
@@ -837,7 +837,7 @@ static int uhci_count_ports(struct usb_hcd *hcd)
static const char hcd_name[] = "uhci_hcd";
-#ifdef CONFIG_PCI
+#ifdef CONFIG_USB_PCI
#include "uhci-pci.c"
#define PCI_DRIVER uhci_pci_driver
#endif
diff --git a/drivers/usb/host/uhci-hcd.h b/drivers/usb/host/uhci-hcd.h
index 6f986d82472d..7fa318a3091d 100644
--- a/drivers/usb/host/uhci-hcd.h
+++ b/drivers/usb/host/uhci-hcd.h
@@ -530,7 +530,7 @@ static inline void uhci_writeb(const struct uhci_hcd *uhci, u8 val, int reg)
#else
/* Support non-PCI host controllers */
-#ifdef CONFIG_PCI
+#ifdef CONFIG_USB_PCI
/* Support PCI and non-PCI host controllers */
#define uhci_has_pci_registers(u) ((u)->io_addr != 0)
#else
diff --git a/drivers/usb/host/xhci-dbg.c b/drivers/usb/host/xhci-dbg.c
index 2b4a00fa735d..2c83b37ae8f2 100644
--- a/drivers/usb/host/xhci-dbg.c
+++ b/drivers/usb/host/xhci-dbg.c
@@ -254,157 +254,6 @@ void xhci_print_registers(struct xhci_hcd *xhci)
xhci_print_ports(xhci);
}
-void xhci_print_trb_offsets(struct xhci_hcd *xhci, union xhci_trb *trb)
-{
- int i;
- for (i = 0; i < 4; i++)
- xhci_dbg(xhci, "Offset 0x%x = 0x%x\n",
- i*4, trb->generic.field[i]);
-}
-
-/**
- * Debug a transfer request block (TRB).
- */
-void xhci_debug_trb(struct xhci_hcd *xhci, union xhci_trb *trb)
-{
- u64 address;
- u32 type = le32_to_cpu(trb->link.control) & TRB_TYPE_BITMASK;
-
- switch (type) {
- case TRB_TYPE(TRB_LINK):
- xhci_dbg(xhci, "Link TRB:\n");
- xhci_print_trb_offsets(xhci, trb);
-
- address = le64_to_cpu(trb->link.segment_ptr);
- xhci_dbg(xhci, "Next ring segment DMA address = 0x%llx\n", address);
-
- xhci_dbg(xhci, "Interrupter target = 0x%x\n",
- GET_INTR_TARGET(le32_to_cpu(trb->link.intr_target)));
- xhci_dbg(xhci, "Cycle bit = %u\n",
- le32_to_cpu(trb->link.control) & TRB_CYCLE);
- xhci_dbg(xhci, "Toggle cycle bit = %u\n",
- le32_to_cpu(trb->link.control) & LINK_TOGGLE);
- xhci_dbg(xhci, "No Snoop bit = %u\n",
- le32_to_cpu(trb->link.control) & TRB_NO_SNOOP);
- break;
- case TRB_TYPE(TRB_TRANSFER):
- address = le64_to_cpu(trb->trans_event.buffer);
- /*
- * FIXME: look at flags to figure out if it's an address or if
- * the data is directly in the buffer field.
- */
- xhci_dbg(xhci, "DMA address or buffer contents= %llu\n", address);
- break;
- case TRB_TYPE(TRB_COMPLETION):
- address = le64_to_cpu(trb->event_cmd.cmd_trb);
- xhci_dbg(xhci, "Command TRB pointer = %llu\n", address);
- xhci_dbg(xhci, "Completion status = %u\n",
- GET_COMP_CODE(le32_to_cpu(trb->event_cmd.status)));
- xhci_dbg(xhci, "Flags = 0x%x\n",
- le32_to_cpu(trb->event_cmd.flags));
- break;
- default:
- xhci_dbg(xhci, "Unknown TRB with TRB type ID %u\n",
- (unsigned int) type>>10);
- xhci_print_trb_offsets(xhci, trb);
- break;
- }
-}
-
-/**
- * Debug a segment with an xHCI ring.
- *
- * @return The Link TRB of the segment, or NULL if there is no Link TRB
- * (which is a bug, since all segments must have a Link TRB).
- *
- * Prints out all TRBs in the segment, even those after the Link TRB.
- *
- * XXX: should we print out TRBs that the HC owns? As long as we don't
- * write, that should be fine... We shouldn't expect that the memory pointed to
- * by the TRB is valid at all. Do we care about ones the HC owns? Probably,
- * for HC debugging.
- */
-void xhci_debug_segment(struct xhci_hcd *xhci, struct xhci_segment *seg)
-{
- int i;
- u64 addr = seg->dma;
- union xhci_trb *trb = seg->trbs;
-
- for (i = 0; i < TRBS_PER_SEGMENT; i++) {
- trb = &seg->trbs[i];
- xhci_dbg(xhci, "@%016llx %08x %08x %08x %08x\n", addr,
- lower_32_bits(le64_to_cpu(trb->link.segment_ptr)),
- upper_32_bits(le64_to_cpu(trb->link.segment_ptr)),
- le32_to_cpu(trb->link.intr_target),
- le32_to_cpu(trb->link.control));
- addr += sizeof(*trb);
- }
-}
-
-void xhci_dbg_ring_ptrs(struct xhci_hcd *xhci, struct xhci_ring *ring)
-{
- xhci_dbg(xhci, "Ring deq = %p (virt), 0x%llx (dma)\n",
- ring->dequeue,
- (unsigned long long)xhci_trb_virt_to_dma(ring->deq_seg,
- ring->dequeue));
- xhci_dbg(xhci, "Ring deq updated %u times\n",
- ring->deq_updates);
- xhci_dbg(xhci, "Ring enq = %p (virt), 0x%llx (dma)\n",
- ring->enqueue,
- (unsigned long long)xhci_trb_virt_to_dma(ring->enq_seg,
- ring->enqueue));
- xhci_dbg(xhci, "Ring enq updated %u times\n",
- ring->enq_updates);
-}
-
-/**
- * Debugging for an xHCI ring, which is a queue broken into multiple segments.
- *
- * Print out each segment in the ring. Check that the DMA address in
- * each link segment actually matches the segment's stored DMA address.
- * Check that the link end bit is only set at the end of the ring.
- * Check that the dequeue and enqueue pointers point to real data in this ring
- * (not some other ring).
- */
-void xhci_debug_ring(struct xhci_hcd *xhci, struct xhci_ring *ring)
-{
- /* FIXME: Throw an error if any segment doesn't have a Link TRB */
- struct xhci_segment *seg;
- struct xhci_segment *first_seg = ring->first_seg;
- xhci_debug_segment(xhci, first_seg);
-
- if (!ring->enq_updates && !ring->deq_updates) {
- xhci_dbg(xhci, " Ring has not been updated\n");
- return;
- }
- for (seg = first_seg->next; seg != first_seg; seg = seg->next)
- xhci_debug_segment(xhci, seg);
-}
-
-void xhci_dbg_ep_rings(struct xhci_hcd *xhci,
- unsigned int slot_id, unsigned int ep_index,
- struct xhci_virt_ep *ep)
-{
- int i;
- struct xhci_ring *ring;
-
- if (ep->ep_state & EP_HAS_STREAMS) {
- for (i = 1; i < ep->stream_info->num_streams; i++) {
- ring = ep->stream_info->stream_rings[i];
- xhci_dbg(xhci, "Dev %d endpoint %d stream ID %d:\n",
- slot_id, ep_index, i);
- xhci_debug_segment(xhci, ring->deq_seg);
- }
- } else {
- ring = ep->ring;
- if (!ring)
- return;
- xhci_dbg(xhci, "Dev %d endpoint ring %d:\n",
- slot_id, ep_index);
- xhci_debug_segment(xhci, ring->deq_seg);
- }
-}
-
void xhci_dbg_erst(struct xhci_hcd *xhci, struct xhci_erst *erst)
{
u64 addr = erst->erst_dma_addr;
@@ -434,166 +283,13 @@ void xhci_dbg_cmd_ptrs(struct xhci_hcd *xhci)
upper_32_bits(val));
}
-/* Print the last 32 bytes for 64-byte contexts */
-static void dbg_rsvd64(struct xhci_hcd *xhci, u64 *ctx, dma_addr_t dma)
-{
- int i;
- for (i = 0; i < 4; i++) {
- xhci_dbg(xhci, "@%p (virt) @%08llx "
- "(dma) %#08llx - rsvd64[%d]\n",
- &ctx[4 + i], (unsigned long long)dma,
- ctx[4 + i], i);
- dma += 8;
- }
-}
-
char *xhci_get_slot_state(struct xhci_hcd *xhci,
struct xhci_container_ctx *ctx)
{
struct xhci_slot_ctx *slot_ctx = xhci_get_slot_ctx(xhci, ctx);
+ int state = GET_SLOT_STATE(le32_to_cpu(slot_ctx->dev_state));
- switch (GET_SLOT_STATE(le32_to_cpu(slot_ctx->dev_state))) {
- case SLOT_STATE_ENABLED:
- return "enabled/disabled";
- case SLOT_STATE_DEFAULT:
- return "default";
- case SLOT_STATE_ADDRESSED:
- return "addressed";
- case SLOT_STATE_CONFIGURED:
- return "configured";
- default:
- return "reserved";
- }
-}
-
-static void xhci_dbg_slot_ctx(struct xhci_hcd *xhci, struct xhci_container_ctx *ctx)
-{
- /* Fields are 32 bits wide, DMA addresses are in bytes */
- int field_size = 32 / 8;
- int i;
-
- struct xhci_slot_ctx *slot_ctx = xhci_get_slot_ctx(xhci, ctx);
- dma_addr_t dma = ctx->dma +
- ((unsigned long)slot_ctx - (unsigned long)ctx->bytes);
- int csz = HCC_64BYTE_CONTEXT(xhci->hcc_params);
-
- xhci_dbg(xhci, "Slot Context:\n");
- xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - dev_info\n",
- &slot_ctx->dev_info,
- (unsigned long long)dma, slot_ctx->dev_info);
- dma += field_size;
- xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - dev_info2\n",
- &slot_ctx->dev_info2,
- (unsigned long long)dma, slot_ctx->dev_info2);
- dma += field_size;
- xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - tt_info\n",
- &slot_ctx->tt_info,
- (unsigned long long)dma, slot_ctx->tt_info);
- dma += field_size;
- xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - dev_state\n",
- &slot_ctx->dev_state,
- (unsigned long long)dma, slot_ctx->dev_state);
- dma += field_size;
- for (i = 0; i < 4; i++) {
- xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - rsvd[%d]\n",
- &slot_ctx->reserved[i], (unsigned long long)dma,
- slot_ctx->reserved[i], i);
- dma += field_size;
- }
-
- if (csz)
- dbg_rsvd64(xhci, (u64 *)slot_ctx, dma);
-}
-
-static void xhci_dbg_ep_ctx(struct xhci_hcd *xhci,
- struct xhci_container_ctx *ctx,
- unsigned int last_ep)
-{
- int i, j;
- int last_ep_ctx = 31;
- /* Fields are 32 bits wide, DMA addresses are in bytes */
- int field_size = 32 / 8;
- int csz = HCC_64BYTE_CONTEXT(xhci->hcc_params);
-
- if (last_ep < 31)
- last_ep_ctx = last_ep + 1;
- for (i = 0; i < last_ep_ctx; i++) {
- unsigned int epaddr = xhci_get_endpoint_address(i);
- struct xhci_ep_ctx *ep_ctx = xhci_get_ep_ctx(xhci, ctx, i);
- dma_addr_t dma = ctx->dma +
- ((unsigned long)ep_ctx - (unsigned long)ctx->bytes);
-
- xhci_dbg(xhci, "%s Endpoint %02d Context (ep_index %02d):\n",
- usb_endpoint_out(epaddr) ? "OUT" : "IN",
- epaddr & USB_ENDPOINT_NUMBER_MASK, i);
- xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - ep_info\n",
- &ep_ctx->ep_info,
- (unsigned long long)dma, ep_ctx->ep_info);
- dma += field_size;
- xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - ep_info2\n",
- &ep_ctx->ep_info2,
- (unsigned long long)dma, ep_ctx->ep_info2);
- dma += field_size;
- xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08llx - deq\n",
- &ep_ctx->deq,
- (unsigned long long)dma, ep_ctx->deq);
- dma += 2*field_size;
- xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - tx_info\n",
- &ep_ctx->tx_info,
- (unsigned long long)dma, ep_ctx->tx_info);
- dma += field_size;
- for (j = 0; j < 3; j++) {
- xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - rsvd[%d]\n",
- &ep_ctx->reserved[j],
- (unsigned long long)dma,
- ep_ctx->reserved[j], j);
- dma += field_size;
- }
-
- if (csz)
- dbg_rsvd64(xhci, (u64 *)ep_ctx, dma);
- }
-}
-
-void xhci_dbg_ctx(struct xhci_hcd *xhci,
- struct xhci_container_ctx *ctx,
- unsigned int last_ep)
-{
- int i;
- /* Fields are 32 bits wide, DMA addresses are in bytes */
- int field_size = 32 / 8;
- dma_addr_t dma = ctx->dma;
- int csz = HCC_64BYTE_CONTEXT(xhci->hcc_params);
-
- if (ctx->type == XHCI_CTX_TYPE_INPUT) {
- struct xhci_input_control_ctx *ctrl_ctx =
- xhci_get_input_control_ctx(ctx);
- if (!ctrl_ctx) {
- xhci_warn(xhci, "Could not get input context, bad type.\n");
- return;
- }
-
- xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - drop flags\n",
- &ctrl_ctx->drop_flags, (unsigned long long)dma,
- ctrl_ctx->drop_flags);
- dma += field_size;
- xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - add flags\n",
- &ctrl_ctx->add_flags, (unsigned long long)dma,
- ctrl_ctx->add_flags);
- dma += field_size;
- for (i = 0; i < 6; i++) {
- xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - rsvd2[%d]\n",
- &ctrl_ctx->rsvd2[i], (unsigned long long)dma,
- ctrl_ctx->rsvd2[i], i);
- dma += field_size;
- }
-
- if (csz)
- dbg_rsvd64(xhci, (u64 *)ctrl_ctx, dma);
- }
-
- xhci_dbg_slot_ctx(xhci, ctx);
- xhci_dbg_ep_ctx(xhci, ctx, last_ep);
+ return xhci_slot_state_string(state);
}
void xhci_dbg_trace(struct xhci_hcd *xhci, void (*trace)(struct va_format *),
diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
index 3bddeaa1e2d7..5e3e9d4c6956 100644
--- a/drivers/usb/host/xhci-hub.c
+++ b/drivers/usb/host/xhci-hub.c
@@ -392,10 +392,8 @@ static int xhci_stop_device(struct xhci_hcd *xhci, int slot_id, int suspend)