summaryrefslogtreecommitdiffstats
path: root/drivers/usb/host
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2009-09-07 08:19:51 +0200
committerIngo Molnar <mingo@elte.hu>2009-09-07 08:19:51 +0200
commita1922ed661ab2c1637d0b10cde933bd9cd33d965 (patch)
tree0f1777542b385ebefd30b3586d830fd8ed6fda5b /drivers/usb/host
parent75e33751ca8bbb72dd6f1a74d2810ddc8cbe4bdf (diff)
parentd28daf923ac5e4a0d7cecebae56f3e339189366b (diff)
Merge branch 'tracing/core' into tracing/hw-breakpoints
Conflicts: arch/Kconfig kernel/trace/trace.h Merge reason: resolve the conflicts, plus adopt to the new ring-buffer APIs. Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'drivers/usb/host')
-rw-r--r--drivers/usb/host/Kconfig33
-rw-r--r--drivers/usb/host/ehci-au1xxx.c2
-rw-r--r--drivers/usb/host/ehci-fsl.c2
-rw-r--r--drivers/usb/host/ehci-hcd.c40
-rw-r--r--drivers/usb/host/ehci-ixp4xx.c2
-rw-r--r--drivers/usb/host/ehci-orion.c4
-rw-r--r--drivers/usb/host/ehci-pci.c2
-rw-r--r--drivers/usb/host/ehci-ppc-of.c2
-rw-r--r--drivers/usb/host/ehci-ps3.c6
-rw-r--r--drivers/usb/host/ehci-q.c155
-rw-r--r--drivers/usb/host/ehci-sched.c13
-rw-r--r--drivers/usb/host/ehci.h2
-rw-r--r--drivers/usb/host/fhci-sched.c8
-rw-r--r--drivers/usb/host/isp1760-if.c2
-rw-r--r--drivers/usb/host/ohci-omap.c1
-rw-r--r--drivers/usb/host/ohci-ps3.c4
-rw-r--r--drivers/usb/host/r8a66597-hcd.c1
-rw-r--r--drivers/usb/host/xhci-dbg.c199
-rw-r--r--drivers/usb/host/xhci-hcd.c290
-rw-r--r--drivers/usb/host/xhci-mem.c300
-rw-r--r--drivers/usb/host/xhci-pci.c1
-rw-r--r--drivers/usb/host/xhci-ring.c305
-rw-r--r--drivers/usb/host/xhci.h148
23 files changed, 1054 insertions, 468 deletions
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 1576a0520ad..1a920c70b5a 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -181,26 +181,27 @@ config USB_OHCI_HCD_PPC_SOC
Enables support for the USB controller on the MPC52xx or
STB03xxx processor chip. If unsure, say Y.
-config USB_OHCI_HCD_PPC_OF
- bool "OHCI support for PPC USB controller on OF platform bus"
- depends on USB_OHCI_HCD && PPC_OF
- default y
- ---help---
- Enables support for the USB controller PowerPC present on the
- OpenFirmware platform bus.
-
config USB_OHCI_HCD_PPC_OF_BE
- bool "Support big endian HC"
- depends on USB_OHCI_HCD_PPC_OF
- default y
+ bool "OHCI support for OF platform bus (big endian)"
+ depends on USB_OHCI_HCD && PPC_OF
select USB_OHCI_BIG_ENDIAN_DESC
select USB_OHCI_BIG_ENDIAN_MMIO
+ ---help---
+ Enables support for big-endian USB controllers present on the
+ OpenFirmware platform bus.
config USB_OHCI_HCD_PPC_OF_LE
- bool "Support little endian HC"
- depends on USB_OHCI_HCD_PPC_OF
- default n
+ bool "OHCI support for OF platform bus (little endian)"
+ depends on USB_OHCI_HCD && PPC_OF
select USB_OHCI_LITTLE_ENDIAN
+ ---help---
+ Enables support for little-endian USB controllers present on the
+ OpenFirmware platform bus.
+
+config USB_OHCI_HCD_PPC_OF
+ bool
+ depends on USB_OHCI_HCD && PPC_OF
+ default USB_OHCI_HCD_PPC_OF_BE || USB_OHCI_HCD_PPC_OF_LE
config USB_OHCI_HCD_PCI
bool "OHCI support for PCI-bus USB controllers"
@@ -337,10 +338,10 @@ config USB_R8A66597_HCD
config SUPERH_ON_CHIP_R8A66597
boolean "Enable SuperH on-chip R8A66597 USB"
- depends on USB_R8A66597_HCD && (CPU_SUBTYPE_SH7366 || CPU_SUBTYPE_SH7723)
+ depends on USB_R8A66597_HCD && (CPU_SUBTYPE_SH7366 || CPU_SUBTYPE_SH7723 || CPU_SUBTYPE_SH7724)
help
This driver enables support for the on-chip R8A66597 in the
- SH7366 and SH7723 processors.
+ SH7366, SH7723 and SH7724 processors.
config USB_WHCI_HCD
tristate "Wireless USB Host Controller Interface (WHCI) driver (EXPERIMENTAL)"
diff --git a/drivers/usb/host/ehci-au1xxx.c b/drivers/usb/host/ehci-au1xxx.c
index c3a778bd359..59d208d94d4 100644
--- a/drivers/usb/host/ehci-au1xxx.c
+++ b/drivers/usb/host/ehci-au1xxx.c
@@ -113,6 +113,8 @@ static const struct hc_driver ehci_au1xxx_hc_driver = {
.bus_resume = ehci_bus_resume,
.relinquish_port = ehci_relinquish_port,
.port_handed_over = ehci_port_handed_over,
+
+ .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
};
static int ehci_hcd_au1xxx_drv_probe(struct platform_device *pdev)
diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c
index bf86809c512..991174937db 100644
--- a/drivers/usb/host/ehci-fsl.c
+++ b/drivers/usb/host/ehci-fsl.c
@@ -325,6 +325,8 @@ static const struct hc_driver ehci_fsl_hc_driver = {
.bus_resume = ehci_bus_resume,
.relinquish_port = ehci_relinquish_port,
.port_handed_over = ehci_port_handed_over,
+
+ .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
};
static int ehci_fsl_drv_probe(struct platform_device *pdev)
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 2b72473544d..11c627ce602 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -903,7 +903,8 @@ static int ehci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
/* already started */
break;
case QH_STATE_IDLE:
- WARN_ON(1);
+ /* QH might be waiting for a Clear-TT-Buffer */
+ qh_completions(ehci, qh);
break;
}
break;
@@ -1003,6 +1004,8 @@ idle_timeout:
schedule_timeout_uninterruptible(1);
goto rescan;
case QH_STATE_IDLE: /* fully unlinked */
+ if (qh->clearing_tt)
+ goto idle_timeout;
if (list_empty (&qh->qtd_list)) {
qh_put (qh);
break;
@@ -1030,12 +1033,14 @@ ehci_endpoint_reset(struct usb_hcd *hcd, struct usb_host_endpoint *ep)
struct ehci_hcd *ehci = hcd_to_ehci(hcd);
struct ehci_qh *qh;
int eptype = usb_endpoint_type(&ep->desc);
+ int epnum = usb_endpoint_num(&ep->desc);
+ int is_out = usb_endpoint_dir_out(&ep->desc);
+ unsigned long flags;
if (eptype != USB_ENDPOINT_XFER_BULK && eptype != USB_ENDPOINT_XFER_INT)
return;
- rescan:
- spin_lock_irq(&ehci->lock);
+ spin_lock_irqsave(&ehci->lock, flags);
qh = ep->hcpriv;
/* For Bulk and Interrupt endpoints we maintain the toggle state
@@ -1044,29 +1049,24 @@ ehci_endpoint_reset(struct usb_hcd *hcd, struct usb_host_endpoint *ep)
* the toggle bit in the QH.
*/
if (qh) {
+ usb_settoggle(qh->dev, epnum, is_out, 0);
if (!list_empty(&qh->qtd_list)) {
WARN_ONCE(1, "clear_halt for a busy endpoint\n");
- } else if (qh->qh_state == QH_STATE_IDLE) {
- qh->hw_token &= ~cpu_to_hc32(ehci, QTD_TOGGLE);
- } else {
- /* It's not safe to write into the overlay area
- * while the QH is active. Unlink it first and
- * wait for the unlink to complete.
+ } else if (qh->qh_state == QH_STATE_LINKED) {
+
+ /* The toggle value in the QH can't be updated
+ * while the QH is active. Unlink it now;
+ * re-linking will call qh_refresh().
*/
- if (qh->qh_state == QH_STATE_LINKED) {
- if (eptype == USB_ENDPOINT_XFER_BULK) {
- unlink_async(ehci, qh);
- } else {
- intr_deschedule(ehci, qh);
- (void) qh_schedule(ehci, qh);
- }
+ if (eptype == USB_ENDPOINT_XFER_BULK) {
+ unlink_async(ehci, qh);
+ } else {
+ intr_deschedule(ehci, qh);
+ (void) qh_schedule(ehci, qh);
}
- spin_unlock_irq(&ehci->lock);
- schedule_timeout_uninterruptible(1);
- goto rescan;
}
}
- spin_unlock_irq(&ehci->lock);
+ spin_unlock_irqrestore(&ehci->lock, flags);
}
static int ehci_get_frame (struct usb_hcd *hcd)
diff --git a/drivers/usb/host/ehci-ixp4xx.c b/drivers/usb/host/ehci-ixp4xx.c
index a44bb4a9495..89b7c70c6ed 100644
--- a/drivers/usb/host/ehci-ixp4xx.c
+++ b/drivers/usb/host/ehci-ixp4xx.c
@@ -61,6 +61,8 @@ static const struct hc_driver ixp4xx_ehci_hc_driver = {
#endif
.relinquish_port = ehci_relinquish_port,
.port_handed_over = ehci_port_handed_over,
+
+ .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
};
static int ixp4xx_ehci_probe(struct platform_device *pdev)
diff --git a/drivers/usb/host/ehci-orion.c b/drivers/usb/host/ehci-orion.c
index 770dd9aba62..1d283e1b2b8 100644
--- a/drivers/usb/host/ehci-orion.c
+++ b/drivers/usb/host/ehci-orion.c
@@ -105,6 +105,7 @@ static int ehci_orion_setup(struct usb_hcd *hcd)
struct ehci_hcd *ehci = hcd_to_ehci(hcd);
int retval;
+ ehci_reset(ehci);
retval = ehci_halt(ehci);
if (retval)
return retval;
@@ -118,7 +119,6 @@ static int ehci_orion_setup(struct usb_hcd *hcd)
hcd->has_tt = 1;
- ehci_reset(ehci);
ehci_port_power(ehci, 0);
return retval;
@@ -165,6 +165,8 @@ static const struct hc_driver ehci_orion_hc_driver = {
.bus_resume = ehci_bus_resume,
.relinquish_port = ehci_relinquish_port,
.port_handed_over = ehci_port_handed_over,
+
+ .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
};
static void __init
diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c
index f3683e1da16..c2f1b7df918 100644
--- a/drivers/usb/host/ehci-pci.c
+++ b/drivers/usb/host/ehci-pci.c
@@ -404,6 +404,8 @@ static const struct hc_driver ehci_pci_hc_driver = {
.bus_resume = ehci_bus_resume,
.relinquish_port = ehci_relinquish_port,
.port_handed_over = ehci_port_handed_over,
+
+ .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
};
/*-------------------------------------------------------------------------*/
diff --git a/drivers/usb/host/ehci-ppc-of.c b/drivers/usb/host/ehci-ppc-of.c
index fbd272288fc..36f96da129f 100644
--- a/drivers/usb/host/ehci-ppc-of.c
+++ b/drivers/usb/host/ehci-ppc-of.c
@@ -79,6 +79,8 @@ static const struct hc_driver ehci_ppc_of_hc_driver = {
#endif
.relinquish_port = ehci_relinquish_port,
.port_handed_over = ehci_port_handed_over,
+
+ .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
};
diff --git a/drivers/usb/host/ehci-ps3.c b/drivers/usb/host/ehci-ps3.c
index eecd2a0680a..1dee33b9139 100644
--- a/drivers/usb/host/ehci-ps3.c
+++ b/drivers/usb/host/ehci-ps3.c
@@ -75,9 +75,11 @@ static const struct hc_driver ps3_ehci_hc_driver = {
#endif
.relinquish_port = ehci_relinquish_port,
.port_handed_over = ehci_port_handed_over,
+
+ .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
};
-static int ps3_ehci_probe(struct ps3_system_bus_device *dev)
+static int __devinit ps3_ehci_probe(struct ps3_system_bus_device *dev)
{
int result;
struct usb_hcd *hcd;
@@ -225,7 +227,7 @@ static int ps3_ehci_remove(struct ps3_system_bus_device *dev)
return 0;
}
-static int ps3_ehci_driver_register(struct ps3_system_bus_driver *drv)
+static int __init ps3_ehci_driver_register(struct ps3_system_bus_driver *drv)
{
return firmware_has_feature(FW_FEATURE_PS3_LV1)
? ps3_system_bus_driver_register(drv)
diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c
index 3192f683f80..7673554fa64 100644
--- a/drivers/usb/host/ehci-q.c
+++ b/drivers/usb/host/ehci-q.c
@@ -93,6 +93,22 @@ qh_update (struct ehci_hcd *ehci, struct ehci_qh *qh, struct ehci_qtd *qtd)
qh->hw_qtd_next = QTD_NEXT(ehci, qtd->qtd_dma);
qh->hw_alt_next = EHCI_LIST_END(ehci);
+ /* Except for control endpoints, we make hardware maintain data
+ * toggle (like OHCI) ... here (re)initialize the toggle in the QH,
+ * and set the pseudo-toggle in udev. Only usb_clear_halt() will
+ * ever clear it.
+ */
+ if (!(qh->hw_info1 & cpu_to_hc32(ehci, 1 << 14))) {
+ unsigned is_out, epnum;
+
+ is_out = !(qtd->hw_token & cpu_to_hc32(ehci, 1 << 8));
+ epnum = (hc32_to_cpup(ehci, &qh->hw_info1) >> 8) & 0x0f;
+ if (unlikely (!usb_gettoggle (qh->dev, epnum, is_out))) {
+ qh->hw_token &= ~cpu_to_hc32(ehci, QTD_TOGGLE);
+ usb_settoggle (qh->dev, epnum, is_out, 1);
+ }
+ }
+
/* HC must see latest qtd and qh data before we clear ACTIVE+HALT */
wmb ();
qh->hw_token &= cpu_to_hc32(ehci, QTD_TOGGLE | QTD_STS_PING);
@@ -123,6 +139,55 @@ qh_refresh (struct ehci_hcd *ehci, struct ehci_qh *qh)
/*-------------------------------------------------------------------------*/
+static void qh_link_async(struct ehci_hcd *ehci, struct ehci_qh *qh);
+
+static void ehci_clear_tt_buffer_complete(struct usb_hcd *hcd,
+ struct usb_host_endpoint *ep)
+{
+ struct ehci_hcd *ehci = hcd_to_ehci(hcd);
+ struct ehci_qh *qh = ep->hcpriv;
+ unsigned long flags;
+
+ spin_lock_irqsave(&ehci->lock, flags);
+ qh->clearing_tt = 0;
+ if (qh->qh_state == QH_STATE_IDLE && !list_empty(&qh->qtd_list)
+ && HC_IS_RUNNING(hcd->state))
+ qh_link_async(ehci, qh);
+ spin_unlock_irqrestore(&ehci->lock, flags);
+}
+
+static void ehci_clear_tt_buffer(struct ehci_hcd *ehci, struct ehci_qh *qh,
+ struct urb *urb, u32 token)
+{
+
+ /* If an async split transaction gets an error or is unlinked,
+ * the TT buffer may be left in an indeterminate state. We
+ * have to clear the TT buffer.
+ *
+ * Note: this routine is never called for Isochronous transfers.
+ */
+ if (urb->dev->tt && !usb_pipeint(urb->pipe) && !qh->clearing_tt) {
+#ifdef DEBUG
+ struct usb_device *tt = urb->dev->tt->hub;
+ dev_dbg(&tt->dev,
+ "clear tt buffer port %d, a%d ep%d t%08x\n",
+ urb->dev->ttport, urb->dev->devnum,
+ usb_pipeendpoint(urb->pipe), token);
+#endif /* DEBUG */
+ if (!ehci_is_TDI(ehci)
+ || urb->dev->tt->hub !=
+ ehci_to_hcd(ehci)->self.root_hub) {
+ if (usb_hub_clear_tt_buffer(urb) == 0)
+ qh->clearing_tt = 1;
+ } else {
+
+ /* REVISIT ARC-derived cores don't clear the root
+ * hub TT buffer in this way...
+ */
+ }
+ }
+}
+
static int qtd_copy_status (
struct ehci_hcd *ehci,
struct urb *urb,
@@ -149,6 +214,14 @@ static int qtd_copy_status (
if (token & QTD_STS_BABBLE) {
/* FIXME "must" disable babbling device's port too */
status = -EOVERFLOW;
+ /* CERR nonzero + halt --> stall */
+ } else if (QTD_CERR(token)) {
+ status = -EPIPE;
+
+ /* In theory, more than one of the following bits can be set
+ * since they are sticky and the transaction is retried.
+ * Which to test first is rather arbitrary.
+ */
} else if (token & QTD_STS_MMF) {
/* fs/ls interrupt xfer missed the complete-split */
status = -EPROTO;
@@ -157,21 +230,15 @@ static int qtd_copy_status (
? -ENOSR /* hc couldn't read data */
: -ECOMM; /* hc couldn't write data */
} else if (token & QTD_STS_XACT) {
- /* timeout, bad crc, wrong PID, etc; retried */
- if (QTD_CERR (token))
- status = -EPIPE;
- else {
- ehci_dbg (ehci, "devpath %s ep%d%s 3strikes\n",
- urb->dev->devpath,
- usb_pipeendpoint (urb->pipe),
- usb_pipein (urb->pipe) ? "in" : "out");
- status = -EPROTO;
- }
- /* CERR nonzero + no errors + halt --> stall */
- } else if (QTD_CERR (token))
- status = -EPIPE;
- else /* unknown */
+ /* timeout, bad CRC, wrong PID, etc */
+ ehci_dbg(ehci, "devpath %s ep%d%s 3strikes\n",
+ urb->dev->devpath,
+ usb_pipeendpoint(urb->pipe),
+ usb_pipein(urb->pipe) ? "in" : "out");
status = -EPROTO;
+ } else { /* unknown */
+ status = -EPROTO;
+ }
ehci_vdbg (ehci,
"dev%d ep%d%s qtd token %08x --> status %d\n",
@@ -179,28 +246,6 @@ static int qtd_copy_status (
usb_pipeendpoint (urb->pipe),
usb_pipein (urb->pipe) ? "in" : "out",
token, status);
-
- /* if async CSPLIT failed, try cleaning out the TT buffer */
- if (status != -EPIPE
- && urb->dev->tt
- && !usb_pipeint(urb->pipe)
- && ((token & QTD_STS_MMF) != 0
- || QTD_CERR(token) == 0)
- && (!ehci_is_TDI(ehci)
- || urb->dev->tt->hub !=
- ehci_to_hcd(ehci)->self.root_hub)) {
-#ifdef DEBUG
- struct usb_device *tt = urb->dev->tt->hub;
- dev_dbg (&tt->dev,
- "clear tt buffer port %d, a%d ep%d t%08x\n",
- urb->dev->ttport, urb->dev->devnum,
- usb_pipeendpoint (urb->pipe), token);
-#endif /* DEBUG */
- /* REVISIT ARC-derived cores don't clear the root
- * hub TT buffer in this way...
- */
- usb_hub_tt_clear_buffer (urb->dev, urb->pipe);
- }
}
return status;
@@ -330,12 +375,11 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh)
*/
if ((token & QTD_STS_XACT) &&
QTD_CERR(token) == 0 &&
- --qh->xacterrs > 0 &&
+ ++qh->xacterrs < QH_XACTERR_MAX &&
!urb->unlinked) {
ehci_dbg(ehci,
"detected XactErr len %zu/%zu retry %d\n",
- qtd->length - QTD_LENGTH(token), qtd->length,
- QH_XACTERR_MAX - qh->xacterrs);
+ qtd->length - QTD_LENGTH(token), qtd->length, qh->xacterrs);
/* reset the token in the qtd and the
* qh overlay (which still contains
@@ -391,9 +435,16 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh)
/* qh unlinked; token in overlay may be most current */
if (state == QH_STATE_IDLE
&& cpu_to_hc32(ehci, qtd->qtd_dma)
- == qh->hw_current)
+ == qh->hw_current) {
token = hc32_to_cpu(ehci, qh->hw_token);
+ /* An unlink may leave an incomplete
+ * async transaction in the TT buffer.
+ * We have to clear it.
+ */
+ ehci_clear_tt_buffer(ehci, qh, urb, token);
+ }
+
/* force halt for unlinked or blocked qh, so we'll
* patch the qh later and so that completions can't
* activate it while we "know" it's stopped.
@@ -419,6 +470,13 @@ halt:
&& (qtd->hw_alt_next
& EHCI_LIST_END(ehci)))
last_status = -EINPROGRESS;
+
+ /* As part of low/full-speed endpoint-halt processing
+ * we must clear the TT buffer (11.17.5).
+ */
+ if (unlikely(last_status != -EINPROGRESS &&
+ last_status != -EREMOTEIO))
+ ehci_clear_tt_buffer(ehci, qh, urb, token);
}
/* if we're removing something not at the queue head,
@@ -435,7 +493,7 @@ halt:
last = qtd;
/* reinit the xacterr counter for the next qtd */
- qh->xacterrs = QH_XACTERR_MAX;
+ qh->xacterrs = 0;
}
/* last urb's completion might still need calling */
@@ -834,6 +892,7 @@ done:
qh->qh_state = QH_STATE_IDLE;
qh->hw_info1 = cpu_to_hc32(ehci, info1);
qh->hw_info2 = cpu_to_hc32(ehci, info2);
+ usb_settoggle (urb->dev, usb_pipeendpoint (urb->pipe), !is_input, 1);
qh_refresh (ehci, qh);
return qh;
}
@@ -847,6 +906,10 @@ static void qh_link_async (struct ehci_hcd *ehci, struct ehci_qh *qh)
__hc32 dma = QH_NEXT(ehci, qh->qh_dma);
struct ehci_qh *head;
+ /* Don't link a QH if there's a Clear-TT-Buffer pending */
+ if (unlikely(qh->clearing_tt))
+ return;
+
/* (re)start the async schedule? */
head = ehci->async;
timer_action_done (ehci, TIMER_ASYNC_OFF);
@@ -864,7 +927,7 @@ static void qh_link_async (struct ehci_hcd *ehci, struct ehci_qh *qh)
}
}
- /* clear halt and maybe recover from silicon quirk */
+ /* clear halt and/or toggle; and maybe recover from silicon quirk */
if (qh->qh_state == QH_STATE_IDLE)
qh_refresh (ehci, qh);
@@ -876,7 +939,8 @@ static void qh_link_async (struct ehci_hcd *ehci, struct ehci_qh *qh)
head->qh_next.qh = qh;
head->hw_next = dma;
- qh->xacterrs = QH_XACTERR_MAX;
+ qh_get(qh);
+ qh->xacterrs = 0;
qh->qh_state = QH_STATE_LINKED;
/* qtd completions reported later by interrupt */
}
@@ -1016,7 +1080,7 @@ submit_async (
* the HC and TT handle it when the TT has a buffer ready.
*/
if (likely (qh->qh_state == QH_STATE_IDLE))
- qh_link_async (ehci, qh_get (qh));
+ qh_link_async(ehci, qh);
done:
spin_unlock_irqrestore (&ehci->lock, flags);
if (unlikely (qh == NULL))
@@ -1051,8 +1115,6 @@ static void end_unlink_async (struct ehci_hcd *ehci)
&& HC_IS_RUNNING (ehci_to_hcd(ehci)->state))
qh_link_async (ehci, qh);
else {
- qh_put (qh); // refcount from async list
-
/* it's not free to turn the async schedule on/off; leave it
* active but idle for a while once it empties.
*/
@@ -1060,6 +1122,7 @@ static void end_unlink_async (struct ehci_hcd *ehci)
&& ehci->async->qh_next.qh == NULL)
timer_action (ehci, TIMER_ASYNC_OFF);
}
+ qh_put(qh); /* refcount from async list */
if (next) {
ehci->reclaim = NULL;
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c
index 9d1babc7ff6..edd61ee9032 100644
--- a/drivers/usb/host/ehci-sched.c
+++ b/drivers/usb/host/ehci-sched.c
@@ -542,6 +542,7 @@ static int qh_link_periodic (struct ehci_hcd *ehci, struct ehci_qh *qh)
}
}
qh->qh_state = QH_STATE_LINKED;
+ qh->xacterrs = 0;
qh_get (qh);
/* update per-qh bandwidth for usbfs */
@@ -1619,11 +1620,14 @@ itd_complete (
desc->status = -EPROTO;
/* HC need not update length with this error */
- if (!(t & EHCI_ISOC_BABBLE))
- desc->actual_length = EHCI_ITD_LENGTH (t);
+ if (!(t & EHCI_ISOC_BABBLE)) {
+ desc->actual_length = EHCI_ITD_LENGTH(t);
+ urb->actual_length += desc->actual_length;
+ }
} else if (likely ((t & EHCI_ISOC_ACTIVE) == 0)) {
desc->status = 0;
- desc->actual_length = EHCI_ITD_LENGTH (t);
+ desc->actual_length = EHCI_ITD_LENGTH(t);
+ urb->actual_length += desc->actual_length;
} else {
/* URB was too late */
desc->status = -EXDEV;
@@ -2014,7 +2018,8 @@ sitd_complete (
desc->status = -EPROTO;
} else {
desc->status = 0;
- desc->actual_length = desc->length - SITD_LENGTH (t);
+ desc->actual_length = desc->length - SITD_LENGTH(t);
+ urb->actual_length += desc->actual_length;
}
stream->depth -= stream->interval << 3;
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
index 90ad3395bb2..2bfff30f470 100644
--- a/drivers/usb/host/ehci.h
+++ b/drivers/usb/host/ehci.h
@@ -354,7 +354,9 @@ struct ehci_qh {
unsigned short period; /* polling interval */
unsigned short start; /* where polling starts */
#define NO_FRAME ((unsigned short)~0) /* pick new start */
+
struct usb_device *dev; /* access to TT */
+ unsigned clearing_tt:1; /* Clear-TT-Buf in progress */
} __attribute__ ((aligned (32)));
/*-------------------------------------------------------------------------*/
diff --git a/drivers/usb/host/fhci-sched.c b/drivers/usb/host/fhci-sched.c
index bb63b68ddb7..62a226b6167 100644
--- a/drivers/usb/host/fhci-sched.c
+++ b/drivers/usb/host/fhci-sched.c
@@ -576,9 +576,7 @@ irqreturn_t fhci_irq(struct usb_hcd *hcd)
out_be16(&usb->fhci->regs->usb_event,
usb->saved_msk);
} else if (usb->port_status == FHCI_PORT_DISABLED) {
- if (fhci_ioports_check_bus_state(fhci) == 1 &&
- usb->port_status != FHCI_PORT_LOW &&
- usb->port_status != FHCI_PORT_FULL)
+ if (fhci_ioports_check_bus_state(fhci) == 1)
fhci_device_connected_interrupt(fhci);
}
usb_er &= ~USB_E_RESET_MASK;
@@ -605,9 +603,7 @@ irqreturn_t fhci_irq(struct usb_hcd *hcd)
}
if (usb_er & USB_E_IDLE_MASK) {
- if (usb->port_status == FHCI_PORT_DISABLED &&
- usb->port_status != FHCI_PORT_LOW &&
- usb->port_status != FHCI_PORT_FULL) {
+ if (usb->port_status == FHCI_PORT_DISABLED) {
usb_er &= ~USB_E_RESET_MASK;
fhci_device_connected_interrupt(fhci);
} else if (usb->port_status ==
diff --git a/drivers/usb/host/isp1760-if.c b/drivers/usb/host/isp1760-if.c
index 3fa3a170279..d4feebfc63b 100644
--- a/drivers/usb/host/isp1760-if.c
+++ b/drivers/usb/host/isp1760-if.c
@@ -361,7 +361,7 @@ static int __devexit isp1760_plat_remove(struct platform_device *pdev)
static struct platform_driver isp1760_plat_driver = {
.probe = isp1760_plat_probe,
- .remove = isp1760_plat_remove,
+ .remove = __devexit_p(isp1760_plat_remove),
.driver = {
.name = "isp1760",
},
diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c
index f3aaba35e91..83cbecd2a1e 100644
--- a/drivers/usb/host/ohci-omap.c
+++ b/drivers/usb/host/ohci-omap.c
@@ -282,6 +282,7 @@ static int ohci_omap_init(struct usb_hcd *hcd)
static void ohci_omap_stop(struct usb_hcd *hcd)
{
dev_dbg(hcd->self.controller, "stopping USB Controller\n");
+ ohci_stop(hcd);
omap_ohci_clock_power(0);
}
diff --git a/drivers/usb/host/ohci-ps3.c b/drivers/usb/host/ohci-ps3.c
index 1d56259c5db..700950455f4 100644
--- a/drivers/usb/host/ohci-ps3.c
+++ b/drivers/usb/host/ohci-ps3.c
@@ -75,7 +75,7 @@ static const struct hc_driver ps3_ohci_hc_driver = {
#endif
};
-static int ps3_ohci_probe(struct ps3_system_bus_device *dev)
+static int __devinit ps3_ohci_probe(struct ps3_system_bus_device *dev)
{
int result;
struct usb_hcd *hcd;
@@ -224,7 +224,7 @@ static int ps3_ohci_remove(struct ps3_system_bus_device *dev)
return 0;
}
-static int ps3_ohci_driver_register(struct ps3_system_bus_driver *drv)
+static int __init ps3_ohci_driver_register(struct ps3_system_bus_driver *drv)
{
return firmware_has_feature(FW_FEATURE_PS3_LV1)
? ps3_system_bus_driver_register(drv)
diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c
index 56976cc0352..e18f74946e6 100644
--- a/drivers/usb/host/r8a66597-hcd.c
+++ b/drivers/usb/host/r8a66597-hcd.c
@@ -26,7 +26,6 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sched.h>
-#include <linux/smp_lock.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/timer.h>
diff --git a/drivers/usb/host/xhci-dbg.c b/drivers/usb/host/xhci-dbg.c
index 2501c571f85..705e3432415 100644
--- a/drivers/usb/host/xhci-dbg.c
+++ b/drivers/usb/host/xhci-dbg.c
@@ -173,6 +173,7 @@ void xhci_print_ir_set(struct xhci_hcd *xhci, struct xhci_intr_reg *ir_set, int
{
void *addr;
u32 temp;
+ u64 temp_64;
addr = &ir_set->irq_pending;
temp = xhci_readl(xhci, addr);
@@ -200,25 +201,15 @@ void xhci_print_ir_set(struct xhci_hcd *xhci, struct xhci_intr_reg *ir_set, int
xhci_dbg(xhci, " WARN: %p: ir_set.rsvd = 0x%x\n",
addr, (unsigned int)temp);
- addr = &ir_set->erst_base[0];
- temp = xhci_readl(xhci, addr);
- xhci_dbg(xhci, " %p: ir_set.erst_base[0] = 0x%x\n",
- addr, (unsigned int) temp);
-
- addr = &ir_set->erst_base[1];
- temp = xhci_readl(xhci, addr);
- xhci_dbg(xhci, " %p: ir_set.erst_base[1] = 0x%x\n",
- addr, (unsigned int) temp);
+ addr = &ir_set->erst_base;
+ temp_64 = xhci_read_64(xhci, addr);
+ xhci_dbg(xhci, " %p: ir_set.erst_base = @%08llx\n",
+ addr, temp_64);
- addr = &ir_set->erst_dequeue[0];
- temp = xhci_readl(xhci, addr);
- xhci_dbg(xhci, " %p: ir_set.erst_dequeue[0] = 0x%x\n",
- addr, (unsigned int) temp);
-
- addr = &ir_set->erst_dequeue[1];
- temp = xhci_readl(xhci, addr);
- xhci_dbg(xhci, " %p: ir_set.erst_dequeue[1] = 0x%x\n",
- addr, (unsigned int) temp);
+ addr = &ir_set->erst_dequeue;
+ temp_64 = xhci_read_64(xhci, addr);
+ xhci_dbg(xhci, " %p: ir_set.erst_dequeue = @%08llx\n",
+ addr, temp_64);
}
void xhci_print_run_regs(struct xhci_hcd *xhci)
@@ -268,8 +259,7 @@ void xhci_debug_trb(struct xhci_hcd *xhci, union xhci_trb *trb)
xhci_dbg(xhci, "Link TRB:\n");
xhci_print_trb_offsets(xhci, trb);
- address = trb->link.segment_ptr[0] +
- (((u64) trb->link.segment_ptr[1]) << 32);
+ address = trb->link.segment_ptr;
xhci_dbg(xhci, "Next ring segment DMA address = 0x%llx\n", address);
xhci_dbg(xhci, "Interrupter target = 0x%x\n",
@@ -282,8 +272,7 @@ void xhci_debug_trb(struct xhci_hcd *xhci, union xhci_trb *trb)
(unsigned int) (trb->link.control & TRB_NO_SNOOP));
break;
case TRB_TYPE(TRB_TRANSFER):
- address = trb->trans_event.buffer[0] +
- (((u64) trb->trans_event.buffer[1]) << 32);
+ address = 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.
@@ -291,8 +280,7 @@ void xhci_debug_trb(struct xhci_hcd *xhci, union xhci_trb *trb)
xhci_dbg(xhci, "DMA address or buffer contents= %llu\n", address);
break;
case TRB_TYPE(TRB_COMPLETION):
- address = trb->event_cmd.cmd_trb[0] +
- (((u64) trb->event_cmd.cmd_trb[1]) << 32);
+ address = trb->event_cmd.cmd_trb;
xhci_dbg(xhci, "Command TRB pointer = %llu\n", address);
xhci_dbg(xhci, "Completion status = %u\n",
(unsigned int) GET_COMP_CODE(trb->event_cmd.status));
@@ -328,8 +316,8 @@ void xhci_debug_segment(struct xhci_hcd *xhci, struct xhci_segment *seg)
for (i = 0; i < TRBS_PER_SEGMENT; ++i) {
trb = &seg->trbs[i];
xhci_dbg(xhci, "@%08x %08x %08x %08x %08x\n", addr,
- (unsigned int) trb->link.segment_ptr[0],
- (unsigned int) trb->link.segment_ptr[1],
+ lower_32_bits(trb->link.segment_ptr),
+ upper_32_bits(trb->link.segment_ptr),
(unsigned int) trb->link.intr_target,
(unsigned int) trb->link.control);
addr += sizeof(*trb);
@@ -386,8 +374,8 @@ void xhci_dbg_erst(struct xhci_hcd *xhci, struct xhci_erst *erst)
entry = &erst->entries[i];
xhci_dbg(xhci, "@%08x %08x %08x %08x %08x\n",
(unsigned int) addr,
- (unsigned int) entry->seg_addr[0],
- (unsigned int) entry->seg_addr[1],
+ lower_32_bits(entry->seg_addr),
+ upper_32_bits(entry->seg_addr),
(unsigned int) entry->seg_size,
(unsigned int) entry->rsvd);
addr += sizeof(*entry);
@@ -396,90 +384,147 @@ void xhci_dbg_erst(struct xhci_hcd *xhci, struct xhci_erst *erst)
void xhci_dbg_cmd_ptrs(struct xhci_hcd *xhci)
{
- u32 val;
+ u64 val;
- val = xhci_readl(xhci, &xhci->op_regs->cmd_ring[0]);
- xhci_dbg(xhci, "// xHC command ring deq ptr low bits + flags = 0x%x\n", val);
- val = xhci_readl(xhci, &xhci->op_regs->cmd_ring[1]);
- xhci_dbg(xhci, "// xHC command ring deq ptr high bits = 0x%x\n", val);
+ val = xhci_read_64(xhci, &xhci->op_regs->cmd_ring);
+ xhci_dbg(xhci, "// xHC command ring deq ptr low bits + flags = @%08x\n",
+ lower_32_bits(val));
+ xhci_dbg(xhci, "// xHC command ring deq ptr high bits = @%08x\n",
+ upper_32_bits(val));
}
-void xhci_dbg_ctx(struct xhci_hcd *xhci, struct xhci_device_control *ctx, dma_addr_t dma, unsigned int last_ep)
+/* 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;
+ }
+}
+
+void xhci_dbg_slot_ctx(struct xhci_hcd *xhci, struct xhci_container_ctx *ctx)
{
- int i, j;
- int last_ep_ctx = 31;
/* Fields are 32 bits wide, DMA addresses are in bytes */
int field_size = 32 / 8;
+ int i;
- xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - drop flags\n",
- &ctx->drop_flags, (unsigned long long)dma,
- ctx->drop_flags);
- dma += field_size;
- xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - add flags\n",
- &ctx->add_flags, (unsigned long long)dma,
- ctx->add_flags);
- dma += field_size;
- for (i = 0; i > 6; ++i) {
- xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - rsvd[%d]\n",
- &ctx->rsvd[i], (unsigned long long)dma,
- ctx->rsvd[i], i);
- dma += field_size;
- }
+ 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);
+ 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",
- &ctx->slot.dev_info,
- (unsigned long long)dma, ctx->slot.dev_info);
+ &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",
- &ctx->slot.dev_info2,
- (unsigned long long)dma, ctx->slot.dev_info2);
+ &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",
- &ctx->slot.tt_info,
- (unsigned long long)dma, ctx->slot.tt_info);
+ &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",
- &ctx->slot.dev_state,
- (unsigned long long)dma, ctx->slot.dev_state);
+ &slot_ctx->dev_state,
+ (unsigned long long)dma, slot_ctx->dev_state);
dma += field_size;
- for (i = 0; i > 4; ++i) {
+ for (i = 0; i < 4; ++i) {
xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - rsvd[%d]\n",
- &ctx->slot.reserved[i], (unsigned long long)dma,
- ctx->slot.reserved[i], i);
+ &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);
+}
+
+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) {
+ 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);
+
xhci_dbg(xhci, "Endpoint %02d Context:\n", i);
xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - ep_info\n",
- &ctx->ep[i].ep_info,
- (unsigned long long)dma, ctx->ep[i].ep_info);
+ &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",
- &ctx->ep[i].ep_info2,
- (unsigned long long)dma, ctx->ep[i].ep_info2);
- dma += field_size;
- xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - deq[0]\n",
- &ctx->ep[i].deq[0],
- (unsigned long long)dma, ctx->ep[i].deq[0]);
- dma += field_size;
- xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - deq[1]\n",
- &ctx->ep[i].deq[1],
- (unsigned long long)dma, ctx->ep[i].deq[1]);
+ &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",
- &ctx->ep[i].tx_info,
- (unsigned long long)dma, ctx->ep[i].tx_info);
+ &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",
- &ctx->ep[i].reserved[j],
+ &ep_ctx->reserved[j],
(unsigned long long)dma,
- ctx->ep[i].reserved[j], j);
+ 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;
+ struct xhci_slot_ctx *slot_ctx;
+ 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(xhci, ctx);
+ 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);
}
+
+ slot_ctx = xhci_get_slot_ctx(xhci, ctx);
+ xhci_dbg_slot_ctx(xhci, ctx);
+ xhci_dbg_ep_ctx(xhci, ctx, last_ep);
}
diff --git a/drivers/usb/host/xhci-hcd.c b/drivers/usb/host/xhci-hcd.c
index dba3e07ccd0..816c39caca1 100644
--- a/drivers/usb/host/xhci-hcd.c
+++ b/drivers/usb/host/xhci-hcd.c
@@ -103,7 +103,10 @@ int xhci_reset(struct xhci_hcd *xhci)
u32 state;
state = xhci_readl(xhci, &xhci->op_regs->status);
- BUG_ON((state & STS_HALT) == 0);
+ if ((state & STS_HALT) == 0) {
+ xhci_warn(xhci, "Host controller not halted, aborting reset.\n");
+ return 0;
+ }
xhci_dbg(xhci, "// Reset the HC\n");
command = xhci_readl(xhci, &xhci->op_regs->command);
@@ -226,6 +229,7 @@ int xhci_init(struct usb_hcd *hcd)
static void xhci_work(struct xhci_hcd *xhci)
{
u32 temp;
+ u64 temp_64;
/*
* Clear the op reg interrupt status first,
@@ -248,9 +252,9 @@ static void xhci_work(struct xhci_hcd *xhci)
/* FIXME this should be a delayed service routine that clears the EHB */
xhci_handle_event(xhci);
- /* Clear the event handler busy flag; the event ring should be empty. */
- temp = xhci_readl(xhci, &xhci->ir_set->erst_dequeue[0]);
- xhci_writel(xhci, temp & ~ERST_EHB, &xhci->ir_set->erst_dequeue[0]);
+ /* Clear the event handler busy flag (RW1C); the event ring should be empty. */
+ temp_64 = xhci_read_64(xhci, &xhci->ir_set->erst_dequeue);
+ xhci_write_64(xhci, temp_64 | ERST_EHB, &xhci->ir_set->erst_dequeue);
/* Flush posted writes -- FIXME is this necessary? */
xhci_readl(xhci, &xhci->ir_set->irq_pending);
}
@@ -266,19 +270,34 @@ irqreturn_t xhci_irq(struct usb_hcd *hcd)
{
struct xhci_hcd *xhci = hcd_to_xhci(hcd);
u32 temp, temp2;
+ union xhci_trb *trb;
spin_lock(&xhci->lock);
+ trb = xhci->event_ring->dequeue;
/* Check if the xHC generated the interrupt, or the irq is shared */
temp = xhci_readl(xhci, &xhci->op_regs->status);
temp2 = xhci_readl(xhci, &xhci->ir_set->irq_pending);
+ if (temp == 0xffffffff && temp2 == 0xffffffff)
+ goto hw_died;
+
if (!(temp & STS_EINT) && !ER_IRQ_PENDING(temp2)) {
spin_unlock(&xhci->lock);
return IRQ_NONE;
}
+ xhci_dbg(xhci, "op reg status = %08x\n", temp);
+ xhci_dbg(xhci, "ir set irq_pending = %08x\n", temp2);
+ xhci_dbg(xhci, "Event ring dequeue ptr:\n");
+ xhci_dbg(xhci, "@%llx %08x %08x %08x %08x\n",
+ (unsigned long long)xhci_trb_virt_to_dma(xhci->event_ring->deq_seg, trb),
+ lower_32_bits(trb->link.segment_ptr),
+ upper_32_bits(trb->link.segment_ptr),
+ (unsigned int) trb->link.intr_target,
+ (unsigned int) trb->link.control);
if (temp & STS_FATAL) {
xhci_warn(xhci, "WARNING: Host System Error\n");
xhci_halt(xhci);
+hw_died:
xhci_to_hcd(xhci)->state = HC_STATE_HALT;
spin_unlock(&xhci->lock);
return -ESHUTDOWN;
@@ -295,6 +314,7 @@ void xhci_event_ring_work(unsigned long arg)
{
unsigned long flags;
int temp;
+ u64 temp_64;
struct xhci_hcd *xhci = (struct xhci_hcd *) arg;
int i, j;
@@ -311,9 +331,9 @@ void xhci_event_ring_work(unsigned long arg)
xhci_dbg(xhci, "Event ring:\n");
xhci_debug_segment(xhci, xhci->event_ring->deq_seg);
xhci_dbg_ring_ptrs(xhci, xhci->event_ring);
- temp = xhci_readl(xhci, &xhci->ir_set->erst_dequeue[0]);
- temp &= ERST_PTR_MASK;
- xhci_dbg(xhci, "ERST deq = 0x%x\n", temp);
+ temp_64 = xhci_read_64(xhci, &xhci->ir_set->erst_dequeue);
+ temp_64 &= ~ERST_PTR_MASK;
+ xhci_dbg(xhci, "ERST deq = 64'h%0lx\n", (long unsigned int) temp_64);
xhci_dbg(xhci, "Command ring:\n");
xhci_debug_segment(xhci, xhci->cmd_ring->deq_seg);
xhci_dbg_ring_ptrs(xhci, xhci->cmd_ring);
@@ -356,6 +376,7 @@ void xhci_event_ring_work(unsigned long arg)
int xhci_run(struct usb_hcd *hcd)
{
u32 temp;
+ u64 temp_64;
struct xhci_hcd *xhci = hcd_to_xhci(hcd);
void (*doorbell)(struct xhci_hcd *) = NULL;
@@ -382,6 +403,20 @@ int xhci_run(struct usb_hcd *hcd)
add_timer(&xhci->event_ring_timer);
#endif
+ xhci_dbg(xhci, "Command ring memory map follows:\n");
+ xhci_debug_ring(xhci, xhci->cmd_ring);
+ xhci_dbg_ring_ptrs(xhci, xhci->cmd_ring);
+ xhci_dbg_cmd_ptrs(xhci);
+
+ xhci_dbg(xhci, "ERST memory map follows:\n");
+ xhci_dbg_erst(xhci, &xhci->erst);
+ xhci_dbg(xhci, "Event ring:\n");
+ xhci_debug_ring(xhci, xhci->event_ring);
+ xhci_dbg_ring_ptrs(xhci, xhci->event_ring);
+ temp_64 = xhci_read_64(xhci, &xhci->ir_set->erst_dequeue);
+ temp_64 &= ~ERST_PTR_MASK;
+ xhci_dbg(xhci, "ERST deq = 64'h%0lx\n", (long unsigned int) temp_64);
+
xhci_dbg(xhci, "// Set the interrupt modulation register\n");
temp = xhci_readl(xhci, &xhci->ir_set->irq_control);
temp &= ~ER_IRQ_INTERVAL_MASK;
@@ -406,22 +441,6 @@ int xhci_run(struct usb_hcd *hcd)
if (NUM_TEST_NOOPS > 0)
doorbell = xhci_setup_one_noop(xhci);
- xhci_dbg(xhci, "Command ring memory map follows:\n");
- xhci_debug_ring(xhci, xhci->cmd_ring);
- xhci_dbg_ring_ptrs(xhci, xhci->cmd_ring);
- xhci_dbg_cmd_ptrs(xhci);
-
- xhci_dbg(xhci, "ERST memory map follows:\n");
- xhci_dbg_erst(xhci, &xhci->erst);
- xhci_dbg(xhci, "Event ring:\n");
- xhci_debug_ring(xhci, xhci->event_ring);
- xhci_dbg_ring_ptrs(xhci, xhci->event_ring);
- temp = xhci_readl(xhci, &xhci->ir_set->erst_dequeue[0]);
- temp &= ERST_PTR_MASK;
- xhci_dbg(xhci, "ERST deq = 0x%x\n", temp);
- temp = xhci_readl(xhci, &xhci->ir_set->erst_dequeue[1]);
- xhci_dbg(xhci, "ERST deq upper = 0x%x\n", temp);
-
temp = xhci_readl(xhci, &xhci->op_regs->command);
temp |= (CMD_RUN);
xhci_dbg(xhci, "// Turn on HC, cmd = 0x%x.\n",
@@ -601,10 +620,13 @@ int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags)
goto exit;
}
if (usb_endpoint_xfer_control(&urb->ep->desc))
- ret = xhci_queue_ctrl_tx(xhci, mem_flags, urb,
+ /* We have a spinlock and interrupts disabled, so we must pass
+ * atomic context to this function, which may allocate memory.
+ */
+ ret = xhci_queue_ctrl_tx(xhci, GFP_ATOMIC, urb,
slot_id, ep_index);
else if (usb_endpoint_xfer_bulk(&urb->ep->desc))
- ret = xhci_queue_bulk_tx(xhci, mem_flags, urb,
+ ret = xhci_queue_bulk_tx(xhci, GFP_ATOMIC, urb,
slot_id, ep_index);
else
ret = -EINVAL;
@@ -661,8 +683,12 @@ int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
goto done;
xhci_dbg(xhci, "Cancel URB %p\n", urb);
+ xhci_dbg(xhci, "Event ring:\n");
+ xhci_debug_ring(xhci, xhci->event_ring);
ep_index = xhci_get_endpoint_index(&urb->ep->desc);
ep_ring = xhci->devs[urb->dev->slot_id]->ep_rings[ep_index];
+ xhci_dbg(xhci, "Endpoint ring:\n");
+ xhci_debug_ring(xhci, ep_ring);
td = (struct xhci_td *) urb->hcpriv;
ep_ring->cancels_pending++;
@@ -696,7 +722,9 @@ int xhci_drop_endpoint(struct usb_hcd *hcd, struct usb_device *udev,
struct usb_host_endpoint *ep)
{
struct xhci_hcd *xhci;
- struct xhci_device_control *in_ctx;
+ struct xhci_container_ctx *in_ctx, *out_ctx;
+ struct xhci_input_control_ctx *ctrl_ctx;
+ struct xhci_slot_ctx *slot_ctx;
unsigned int last_ctx;
unsigned int ep_index;
struct xhci_ep_ctx *ep_ctx;
@@ -724,31 +752,34 @@ int xhci_drop_endpoint(struct usb_hcd *hcd, struct usb_device *udev,
}
in_ctx = xhci->devs[udev->slot_id]->in_ctx;
+ out_ctx = xhci->devs[udev->slot_id]->out_ctx;
+ ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx);
ep_index = xhci_get_endpoint_index(&ep->desc);
- ep_ctx = &xhci->devs[udev->slot_id]->out_ctx->ep[ep_index];
+ ep_ctx = xhci_get_ep_ctx(xhci, out_ctx, ep_index);
/* If the HC already knows the endpoint is disabled,
* or the HCD has noted it is disabled, ignore this request
*/
if ((ep_ctx->ep_info & EP_STATE_MASK) == EP_STATE_DISABLED ||
- in_ctx->drop_flags & xhci_get_endpoint_flag(&ep->desc)) {
+ ctrl_ctx->drop_flags & xhci_get_endpoint_flag(&ep->desc)) {
xhci_warn(xhci, "xHCI %s called with disabled ep %p\n",
__func__, ep);
return 0;
}
- in_ctx->drop_flags |= drop_flag;
- new_drop_flags = in_ctx->drop_flags;
+ ctrl_ctx->drop_flags |= drop_flag;
+ new_drop_flags = ctrl_ctx->drop_flags;
- in_ctx->add_flags = ~drop_flag;
- new_add_flags = in_ctx->add_flags;
+ ctrl_ctx->add_flags = ~drop_flag;
+ new_add_flags = ctrl_ctx->add_flags;
- last_ctx = xhci_last_valid_endpoint(in_ctx->add_flags);
+ last_ctx = xhci_last_valid_endpoint(ctrl_ctx->add_flags);
+ slot_ctx = xhci_get_slot_ctx(xhci, in_ctx);
/* Update the last valid endpoint context, if we deleted the last one */
- if ((in_ctx->slot.dev_info & LAST_CTX_MASK) > LAST_CTX(last_ctx)) {
- in_ctx->slot.dev_info &= ~LAST_CTX_MASK;
- in_ctx->slot.dev_info |= LAST_CTX(last_ctx);
+ if ((slot_ctx->dev_info & LAST_CTX_MASK) > LAST_CTX(last_ctx)) {
+ slot_ctx->dev_info &= ~LAST_CTX_MASK;
+ slot_ctx->dev_info |= LAST_CTX(last_ctx);
}
- new_slot_info = in_ctx->slot.dev_info;
+ new_slot_info = slot_ctx->dev_info;
xhci_endpoint_zero(xhci, xhci->devs[udev->slot_id], ep);
@@ -778,17 +809,22 @@ int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev,
struct usb_host_endpoint *ep)
{
struct xhci_hcd *xhci;
- struct xhci_device_control *in_ctx;
+ struct xhci_container_ctx *in_ctx, *out_ctx;
unsigned int ep_index;
struct xhci_ep_ctx *ep_ctx;
+ struct xhci_slot_ctx *slot_ctx;
+ struct xhci_input_control_ctx *ctrl_ctx;
u32 added_ctxs;
unsigned int last_ctx;
u32 new_add_flags, new_drop_flags, new_slot_info;
int ret = 0;
ret = xhci_check_args(hcd, udev, ep, 1, __func__);
- if (ret <= 0)
+ if (ret <= 0) {
+ /* So we won't queue a reset ep command for a root hub */
+ ep->hcpriv = NULL;
return ret;
+ }
xhci = hcd_to_xhci(hcd);
added_ctxs = xhci_get_endpoint_flag(&ep->desc);
@@ -810,12 +846,14 @@ int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev,
}
in_ctx = xhci->devs[udev->slot_id]->in_ctx;
+ out_ctx = xhci->devs[udev->slot_id]->out_ctx;
+ ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx);
ep_index = xhci_get_endpoint_index(&ep->desc);
- ep_ctx = &xhci->devs[udev->slot_id]->out_ctx->ep[ep_index];
+ ep_ctx = xhci_get_ep_ctx(xhci, out_ctx, ep_index);
/* If the HCD has already noted the endpoint is enabled,
* ignore this request.
*/
- if (in_ctx->add_flags & xhci_get_endpoint_flag(&ep->desc)) {
+ if (ctrl_ctx->add_flags & xhci_get_endpoint_flag(&ep->desc)) {
xhci_warn(xhci, "xHCI %s called with enabled ep %p\n",
__func__, ep);
return 0;
@@ -833,8 +871,8 @@ int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev,
return -ENOMEM;
}
- in_ctx->add_flags |= added_ctxs;
- new_add_flags = in_ctx->add_flags;
+ ctrl_ctx->add_flags |= added_ctxs;
+ new_add_flags = ctrl_ctx->add_flags;
/* If xhci_endpoint_disable() was called for this endpoint, but the
* xHC hasn't been notified yet through the check_bandwidth() call,
@@ -842,14 +880,18 @@ int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev,
* descriptors. We must drop and re-add this endpoint, so we leave the
* drop flags alone.
*/
- new_drop_flags = in_ctx->drop_flags;
+ new_drop_flags = ctrl_ctx->drop_flags;
+ slot_ctx = xhci_get_slot_ctx(xhci, in_ctx);
/* Update the last valid endpoint context, if we just added one past */
- if ((in_ctx->slot.dev_info & LAST_CTX_MASK) < LAST_CTX(last_ctx)) {
- in_ctx->slot.dev_info &= ~LAST_CTX_MASK;
- in_ctx->slot.dev_info |= LAST_CTX(last_ctx);
+ if ((slot_ctx->dev_info & LAST_CTX_MASK) < LAST_CTX(last_ctx)) {
+ slot_ctx->dev_info &= ~LAST_CTX_MASK;
+ slot_ctx->dev_info |= LAST_CTX(last_ctx);
}
- new_slot_info = in_ctx->slot.dev_info;
+ new_slot_info = slot_ctx->dev_info;
+
+ /* Store the usb_device pointer for later use */
+ ep->hcpriv = udev;
xhci_dbg(xhci, "add ep 0x%x, slot id %d, new drop flags = %#x, new add flags = %#x, new slot info = %#x\n",
(unsigned int) ep->desc.bEndpointAddress,
@@ -860,9 +902,11 @@ int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev,
return 0;
}
-static void xhci_zero_in_ctx(struct xhci_virt_device *virt_dev)
+static void xhci_zero_in_ctx(struct xhci_hcd *xhci, struct xhci_virt_device *virt_dev)
{
+ struct xhci_input_control_ctx *ctrl_ctx;
struct xhci_ep_ctx *ep_ctx;
+ struct xhci_slot_ctx *slot_ctx;
int i;
/* When a device's add flag and drop flag are zero, any subsequent
@@ -870,17 +914,18 @@ static void xhci_zero_in_ctx(struct xhci_virt_device *virt_dev)
* untouched. Make sure we don't leave any old state in the input
* endpoint contexts.
*/
- virt_dev->in_ctx->drop_flags = 0;
- virt_dev->in_ctx->add_flags = 0;
- virt_dev->in_ctx->slot.dev_info &= ~LAST_CTX_MASK;
+ ctrl_ctx = xhci_get_input_control_ctx(xhci, virt_dev->in_ctx);
+ ctrl_ctx->drop_flags = 0;
+ ctrl_ctx->add_flags = 0;
+ slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->in_ctx);
+ slot_ctx->dev_info &= ~LAST_CTX_MASK;
/* Endpoint 0 is always valid */
- virt_dev->in_ctx->slot.dev_info |= LAST_CTX(1);
+ slot_ctx->dev_info |= LAST_CTX(1);
for (i = 1; i < 31; ++i) {
- ep_ctx = &virt_dev->in_ctx->ep[i];
+ ep_ctx = xhci_get_ep_ctx(xhci, virt_dev->in_ctx, i);
ep_ctx->ep_info = 0;
ep_ctx->ep_info2 = 0;
- ep_ctx->deq[0] = 0;
- ep_ctx->deq[1] = 0;
+ ep_ctx->deq = 0;
ep_ctx->tx_info = 0;
}
}
@@ -903,6 +948,8 @@ int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev)
unsigned long flags;
struct xhci_hcd *xhci;
struct xhci_virt_device *virt_dev;
+ struct xhci_input_control_ctx *ctrl_ctx;
+ struct xhci_slot_ctx *slot_ctx;
ret = xhci_check_args(hcd, udev, NULL, 0, __func__);
if (ret <= 0)
@@ -918,16 +965,18 @@ int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev)
virt_dev = xhci->devs[udev->slot_id];
/* See section 4.6.6 - A0 = 1; A1 = D0 = D1 = 0 */
- virt_dev->in_ctx->add_flags |= SLOT_FLAG;
- virt_dev->in_ctx->add_flags &= ~EP0_FLAG;
- virt_dev->in_ctx->drop_flags &= ~SLOT_FLAG;
- virt_dev->in_ctx->drop_flags &= ~EP0_FLAG;
+ ctrl_ctx = xhci_get_input_control_ctx(xhci, virt_dev->in_ctx);
+ ctrl_ctx->add_flags |= SLOT_FLAG;
+ ctrl_ctx->add_flags &= ~EP0_FLAG;
+ ctrl_ctx->drop_flags &= ~SLOT_FLAG;
+ ctrl_ctx->drop_flags &= ~EP0_FLAG;
xhci_dbg(xhci, "New Input Control Context:\n");
- xhci_dbg_ctx(xhci, virt_dev->in_ctx, virt_dev->in_ctx_dma,
- LAST_CTX_TO_EP_NUM(virt_dev->in_ctx->slot.dev_info));
+ slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->in_ctx);
+ xhci_dbg_ctx(xhci, virt_dev->in_ctx,
+ LAST_CTX_TO_EP_NUM(slot_ctx->dev_info));
spin_lock_irqsave(&xhci->lock, flags);
- ret = xhci_queue_configure_endpoint(xhci, virt_dev->in_ctx_dma,
+ ret = xhci_queue_configure_endpoint(xhci, virt_dev->in_ctx->dma,
udev->slot_id);
if (ret < 0) {
spin_unlock_irqrestore(&xhci->lock, flags);
@@ -982,10 +1031,10 @@ int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev)
}
xhci_dbg(xhci, "Output context after successful config ep cmd:\n");
- xhci_dbg_ctx(xhci, virt_dev->out_ctx, virt_dev->out_ctx_dma,
- LAST_CTX_TO_EP_NUM(virt_dev->in_ctx->slot.dev_info));
+ xhci_dbg_ctx(xhci, virt_dev->out_ctx,
+ LAST_CTX_TO_EP_NUM(slot_ctx->dev_info));
- xhci_zero_in_ctx(virt_dev);
+ xhci_zero_in_ctx(xhci, virt_dev);
/* Free any old rings */
for (i = 1; i < 31; ++i) {
if (virt_dev->new_ep_rings[i]) {
@@ -1023,7 +1072,67 @@ void xhci_reset_bandwidth(struct usb_hcd *hcd, struct usb_device *udev)
virt_dev->new_ep_rings[i] = NULL;
}
}
- xhci_zero_in_ctx(virt_dev);
+ xhci_zero_in_ctx(xhci, virt_dev);
+}
+
+/* Deal with stalled endpoints. The core should have sent the control message
+ * to clear the halt condition. However, we need to make the xHCI hardware
+ * reset its sequence number, since a device will expect a sequence number of
+ * zero after the halt condition is cleared.
+ * Context: in_interrupt
+ */
+void xhci_endpoint_reset(struct usb_hcd *hcd,
+ struct usb_host_endpoint *ep)
+{
+ struct xhci_hcd *xhci;
+ struct usb_device *udev;
+ unsigned int ep_index;
+ unsigned long flags;
+ int ret;
+ struct xhci_dequeue_state deq_state;
+ struct xhci_ring *ep_ring;
+
+ xhci = hcd_to_xhci(hcd);
+ udev = (struct usb_device *) ep->hcpriv;
+ /* Called with a root hub endpoint (or an endpoint that wasn't added
+ * with xhci_add_endpoint()
+ */
+ if (!ep->hcpriv)
+ return;
+ ep_index = xhci_get_endpoint_index(&ep->desc);
+ ep_ring = xhci->devs[udev->slot_id]->ep_rings[ep_index];
+ if (!ep_ring->stopped_td) {
+ xhci_dbg(xhci, "Endpoint 0x%x not halted, refusing to reset.\n",
+ ep->desc.bEndpointAddress);
+ return;
+ }
+
+ xhci_dbg(xhci, "Queueing reset endpoint command\n");
+ spin_lock_irqsave(&xhci->lock, flags);
+ ret = xhci_queue_reset_ep(xhci, udev->slot_id, ep_index);
+ /*
+ * Can't change the ring dequeue pointer until it's transitioned to the
+ * stopped state, which is only upon a successful reset endpoint
+ * command. Better hope that last command worked!
+ */
+ if (!ret) {
+ xhci_dbg(xhci, "Cleaning up stalled endpoint ring\n");
+ /* We need to move the HW's dequeue pointer past this TD,
+ * or it will attempt to resend it on the next doorbell ring.
+ */
+ xhci_find_new_dequeue_state(xhci, udev->slot_id,
+ ep_index, ep_ring->stopped_td, &deq_state);
+ xhci_dbg(xhci, "Queueing new dequeue state\n");
+ xhci_queue_new_dequeue_state(xhci, ep_ring,
+ udev->slot_id,
+ ep_index, &deq_state);
+ kfree(ep_ring->stopped_td);
+ xhci_ring_cmd_db(xhci);
+ }
+ spin_unlock_irqrestore(&xhci->lock, flags);
+
+ if (ret)
+ xhci_warn(xhci, "FIXME allocate a new ring segment\n");
}
/*
@@ -1120,7 +1229,9 @@ int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev)
struct xhci_virt_device *virt_dev;
int ret = 0;
struct xhci_hcd *xhci = hcd_to_xhci(hcd);
- u32 temp;
+ struct xhci_slot_ctx *slot_ctx;
+ struct xhci_input_control_ctx *ctrl_ctx;
+ u64 temp_64;
if (!udev->slot_id) {
xhci_dbg(xhci, "Bad Slot ID %d\n", udev->slot_id);
@@ -1133,10 +1244,12 @@ int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev)
if (!udev->config)
xhci_setup_addressable_virt_dev(xhci, udev);
/* Otherwise, assume the core has the device configured how it wants */
+ xhci_dbg(xhci, "Slot ID %d Input Context:\n", udev->slot_id);
+ xhci_dbg_ctx(xhci, virt_dev->in_ctx, 2);
spin_lock_irqsave(&xhci->lock, flags);
- ret = xhci_queue_address_device(xhci, virt_dev->in_ctx_dma,
- udev->slot_id);
+ ret = xhci_queue_address_device(xhci, virt_dev->in_ctx->dma,
+ udev->slot_id);
if (ret) {
spin_unlock_irqrestore(&xhci->lock, flags);
xhci_dbg(xhci, "FIXME: allocate a command ring segment\n");
@@ -1176,41 +1289,37 @@ int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev)
default:
xhci_err(xhci, "ERROR: unexpected command completion "
"code 0x%x.\n", virt_dev->cmd_status);
+ xhci_dbg(xhci, "Slot ID %d Output Context:\n", udev->slot_id);
+ xhci_dbg_ctx(xhci, virt_dev->out_ctx, 2);
ret = -EINVAL;
break;
}
if (ret) {
return ret;
}
- temp = xhci_readl(xhci, &xhci->op_regs->dcbaa_ptr[0]);
- xhci_dbg(xhci, "Op regs DCBAA ptr[0] = %#08x\n", temp);
- temp = xhci_readl(xhci, &xhci->op_regs->dcbaa_ptr[1]);
- xhci_dbg(xhci, "Op regs DCBAA ptr[1] = %#08x\n", temp);
- xhci_dbg(xhci, "Slot ID %d dcbaa entry[0] @%p = %#08x\n",
- udev->slot_id,
- &xhci->dcbaa->dev_context_ptrs[2*udev->slot_id],
- xhci->dcbaa->dev_context_ptrs[2*udev->slot_id]);
- xhci_dbg(xhci, "Slot ID %d dcbaa entry[1] @%p = %#08x\n",
+ temp_64 = xhci_read_64(xhci, &xhci->op_regs->dcbaa_ptr);
+ xhci_dbg(xhci, "Op regs DCBAA ptr = %#016llx\n", temp_64);
+ xhci_dbg(xhci, "Slot ID %d dcbaa entry @%p = %#016llx\n",
udev->slot_id,
- &xhci->dcbaa->dev_context_ptrs[2*udev->slot_id+1],
- xhci->dcbaa->dev_context_ptrs[2*udev->slot_id+1]);
+ &xhci->dcbaa->dev_context_ptrs[udev->slot_id],
+ (unsigned long long)
+ xhci->dcbaa->dev_context_ptrs[udev->slot_id]);
xhci_dbg(xhci, "Output Context DMA address = %#08llx\n",
- (unsigned long long)virt_dev->out_ctx_dma);
+ (unsigned long long)virt_dev->out_ctx->dma);
xhci_dbg(xhci, "Slot ID %d Input Context:\n", udev->slot_id);
- xhci_dbg_ctx(xhci, virt_dev->in_ctx, virt_dev->in_ctx_dma, 2);
+ xhci_dbg_ctx(xhci, virt_dev->in_ctx, 2);
xhci_dbg(xhci, "Slot ID %d Output Context:\n", udev->slot_id);
- xhci_dbg_ctx(xhci, virt_dev->out_ctx, virt_dev->out_ctx_dma, 2);
+ xhci_dbg_ctx(xhci, virt_dev->out_ctx, 2);
/*
* USB core uses address 1 for the roothubs, so we add one to the
* address given back to us by the HC.
*/
- udev->devnum = (virt_dev->out_ctx->slot.dev_state & DEV_ADDR_MASK) + 1;
+ slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->out_ctx);
+ udev->devnum = (slot_ctx->dev_state & DEV_ADDR_MASK) + 1;
/* Zero the input context control for later use */
- virt_dev->in_ctx->add_flags = 0;
- virt_dev->in_ctx->drop_flags = 0;
- /* Mirror flags in the output context for future ep enable/disable */
- virt_dev->out_ctx->add_flags = SLOT_FLAG | EP0_FLAG;
- virt_dev->out_ctx->drop_flags = 0;
+ ctrl_ctx = xhci_get_input_control_ctx(xhci, virt_dev->in_ctx);
+ ctrl_ctx->add_flags = 0;
+ ctrl_ctx->drop_flags = 0;
xhci_dbg(xhci, "Device address = %d\n", udev->devnum);
/* XXX Meh, not sure if anyone else but choose_address uses this. */
@@ -1252,7 +1361,6 @@ static int __init xhci_hcd_init(void)
/* xhci_device_control has eight fields, and also
* embeds one xhci_slot_ctx and 31 xhci_ep_ctx
*/
- BUILD_BUG_ON(sizeof(struct xhci_device_control) != (8+8+8*31)*32/8);
BUILD_BUG_ON(sizeof(struct xhci_stream_ctx) != 4*32/8);
BUILD_BUG_ON(sizeof(union xhci_trb) != 4*32/8);
BUILD_BUG_ON(sizeof(struct xhci_erst_entry) != 4*32/8);
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index c8a72de1c50..e6b9a1c6002 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -88,7 +88,7 @@ static void xhci_link_segments(struct xhci_hcd *xhci, struct xhci_segment *prev,
return;
prev->next = next;
if (link_trbs) {
- prev->trbs[TRBS_PER_SEGMENT-1].link.segment_ptr[0] = next->dma;
+ prev->trbs[TRBS_PER_SEGMENT-1].link.segment_ptr = next->dma;
/* Set the last TRB in the segment to have a TRB type ID of Link TRB */
val = prev->trbs[TRBS_PER_SEGMENT-1].link.control;
@@ -189,6 +189,63 @@ fail:
return 0;
}
+#define CTX_SIZE(_hcc) (HCC_64BYTE_CONTEXT(_hcc) ? 64 : 32)
+
+struct xhci_container_ctx *xhci_alloc_container_ctx(struct xhci_hcd *xhci,
+ int type, gfp_t flags)
+{
+ struct xhci_container_ctx *ctx = kzalloc(sizeof(*ctx), flags);
+ if (!ctx)
+ return NULL;
+
+ BUG_ON((type != XHCI_CTX_TYPE_DEVICE) && (type != XHCI_CTX_TYPE_INPUT));
+ ctx->type = type;
+ ctx->size = HCC_64BYTE_CONTEXT(xhci->hcc_params) ? 2048 : 1024;
+ if (type == XHCI_CTX_TYPE_INPUT)
+ ctx->size += CTX_SIZE(xhci->hcc_params);
+
+ ctx->bytes = dma_pool_alloc(xhci->device_pool, flags, &ctx->dma);
+ memset(ctx->bytes, 0, ctx->size);
+ return ctx;
+}
+
+void xhci_free_container_ctx(struct xhci_hcd *xhci,
+ struct xhci_container_ctx *ctx)
+{
+ dma_pool_free(xhci->device_pool, ctx->bytes, ctx->dma);
+ kfree(ctx);
+}
+
+struct xhci_input_control_ctx *xhci_get_input_control_ctx(struct xhci_hcd *xhci,
+ struct xhci_container_ctx *ctx)
+{
+ BUG_ON(ctx->type != XHCI_CTX_TYPE_INPUT);
+ return (struct xhci_input_control_ctx *)ctx->bytes;
+}
+
+struct xhci_slot_ctx *xhci_get_slot_ctx(struct xhci_hcd *xhci,
+ struct xhci_container_ctx *ctx)
+{
+ if (ctx->type == XHCI_CTX_TYPE_DEVICE)
+ return (struct xhci_slot_ctx *)ctx->bytes;
+
+ return (struct xhci_slot_ctx *)
+ (ctx->bytes + CTX_SIZE(xhci->hcc_params));
+}
+
+struct xhci_ep_ctx *xhci_get_ep_ctx(struct xhci_hcd *xhci,
+ struct xhci_container_ctx *ctx,
+ unsigned int ep_index)
+{
+ /* increment ep index by offset of start of ep ctx array */
+ ep_index++;
+ if (ctx->type == XHCI_CTX_TYPE_INPUT)
+ ep_index++;
+
+ return (struct xhci_ep_ctx *)
+ (ctx->bytes + (ep_index * CTX_SIZE(xhci->hcc_params)));
+}
+
/* All the xhci_tds in the ring's TD list should be freed at this point */
void xhci_free_virt_device(struct xhci_hcd *xhci, int slot_id)
{
@@ -200,8 +257,7 @@ void xhci_free_virt_device(struct xhci_hcd *xhci, int slot_id)
return;
dev = xhci->devs[slot_id];
- xhci->dcbaa->dev_context_ptrs[2*slot_id] = 0;
- xhci->dcbaa->dev_context_ptrs[2*slot_id + 1] = 0;
+ xhci->dcbaa->dev_context_ptrs[slot_id] = 0;
if (!dev)
return;
@@ -210,11 +266,10 @@ void xhci_free_virt_device(struct xhci_hcd *xhci, int slot_id)
xhci_ring_free(xhci, dev->ep_rings[i]);
if (dev->in_ctx)
- dma_pool_free(xhci->device_pool,
- dev->in_ctx, dev->in_ctx_dma);
+ xhci_free_container_ctx(xhci, dev->in_ctx);
if (dev->out_ctx)
- dma_pool_free(xhci->device_pool,
- dev->out_ctx, dev->out_ctx_dma);
+ xhci_free_container_ctx(xhci, dev->out_ctx);
+
kfree(xhci->devs[slot_id]);
xhci->devs[slot_id] = 0;
}
@@ -222,7 +277,6 @@ void xhci_free_virt_device(struct xhci_hcd *xhci, int slot_id)
int xhci_alloc_virt_device(struct xhci_hcd *xhci, int slot_id,
struct usb_device *udev, gfp_t flags)
{
- dma_addr_t dma;
struct xhci_virt_device *dev;
/* Slot ID 0 is reserved */
@@ -236,23 +290,21 @@ int xhci_alloc_virt_device(struct xhci_hcd *xhci, int slot_id,
return 0;
dev = xhci->devs[slot_id];
- /* Allocate the (output) device context that will be used in the HC */
- dev->out_ctx = dma_pool_alloc(xhci->device_pool, flags, &dma);
+ /* Allocate the (output) device context that will be used in the HC. */
+ dev->out_ctx = xhci_alloc_container_ctx(xhci, XHCI_CTX_TYPE_DEVICE, flags);
if (!dev->out_ctx)
goto fail;
- dev->out_ctx_dma = dma;
+
xhci_dbg(xhci, "Slot %d output ctx = 0x%llx (dma)\n", slot_id,
- (unsigned long long)dma);
- memset(dev->out_ctx, 0, sizeof(*dev->out_ctx));
+ (unsigned long long)dev->out_ctx->dma);
/* Allocate the (input) device context for address device command */
- dev->in_ctx = dma_pool_alloc(xhci->device_pool, flags, &dma);
+ dev->in_ctx = xhci_alloc_container_ctx(xhci, XHCI_CTX_TYPE_INPUT, flags);
if (!dev->in_ctx)
goto fail;
- dev->in_ctx_dma = dma;
+
xhci_dbg(xhci, "Slot %d input ctx = 0x%llx (dma)\n", slot_id,
- (unsigned long long)dma);
- memset(dev->in_ctx, 0, sizeof(*dev->in_ctx));
+ (unsigned long long)dev->in_ctx->dma);
/* Allocate endpoint 0 ring */
dev->ep_rings[0] = xhci_ring_alloc(xhci, 1, true, flags);
@@ -261,17 +313,12 @@ int xhci_alloc_virt_device(struct xhci_hcd *xhci, int slot_id,
init_completion(&dev->cmd_completion);
- /*
- * Point to output device context in dcbaa; skip the output control
- * context, which is eight 32 bit fields (or 32 bytes long)
- */
- xhci->dcbaa->dev_context_ptrs[2*slot_id] =
- (u32) dev->out_ctx_dma + (32);
+ /* Point to output device context in dcbaa. */
+ xhci->dcbaa->dev_context_ptrs[slot_id] = dev->out_ctx->dma;
xhci_dbg(xhci, "Set slot id %d dcbaa entry %p to 0x%llx\n",
slot_id,
- &xhci->dcbaa->dev_context_ptrs[2*slot_id],
- (unsigned long long)dev->out_ctx_dma);
- xhci->dcbaa->dev_context_ptrs[2*slot_id + 1] = 0;
+ &xhci->dcbaa->dev_context_ptrs[slot_id],
+ (unsigned long long) xhci->dcbaa->dev_context_ptrs[slot_id]);
return 1;
fail:
@@ -285,6 +332,8 @@ int xhci_setup_addressable_virt_dev(struct xhci_hcd *xhci, struct usb_device *ud
struct xhci_virt_device *dev;
struct xhci_ep_ctx *ep0_ctx;
struct usb_device *top_dev;
+ struct xhci_slot_ctx *slot_ctx;
+ struct xhci_input_control_ctx *ctrl_ctx;
dev = xhci->devs[udev->slot_id];
/* Slot ID 0 is reserved */
@@ -293,27 +342,29 @@ int xhci_setup_addressable_virt_dev(struct xhci_hcd *xhci, struct usb_device *ud
udev->slot_id);
return -EINVAL;
}
- ep0_ctx = &dev->in_ctx->ep[0];
+ ep0_ctx = xhci_get_ep_ctx(xhci, dev->in_ctx, 0);
+ ctrl_ctx = xhci_get_input_control_ctx(xhci, dev->in_ctx);
+ slot_ctx = xhci_get_slot_ctx(xhci, dev->in_ctx);
/* 2) New slot context and endpoint 0 context are valid*/
- dev->in_ctx->add_flags = SLOT_FLAG | EP0_FLAG;
+ ctrl_ctx->add_flags = SLOT_FLAG | EP0_FLAG;
/* 3) Only the control endpoint is valid - one endpoint context */
- dev->in_ctx->slot.dev_info |= LAST_CTX(1);
+ slot_ctx->dev_info |= LAST_CTX(1);
switch (udev->speed) {
case USB_SPEED_SUPER:
- dev->in_ctx->slot.dev_info |= (u32) udev->route;
- dev->in_ctx->slot.dev_info |= (u32) SLOT_SPEED_SS;
+ slot_ctx->dev_info |= (u32) udev->route;
+ slot_ctx->dev_info |= (u32) SLOT_SPEED_SS;
break;
case USB_SPEED_HIGH:
- dev->in_ctx->slot.dev_info |= (u32) SLOT_SPEED_HS;
+ slot_ctx->dev_info |= (u32) SLOT_SPEED_HS;
break;
case USB_SPEED_FULL:
- dev->in_ctx->slot.dev_info |= (u32) SLOT_SPEED_FS;
+ slot_ctx->dev_info |= (u32) SLOT_SPEED_FS;
break;
case USB_SPEED_LOW:
- dev->in_ctx->slot.dev_info |= (u32) SLOT_SPEED_LS;
+ slot_ctx->dev_info |= (u32) SLOT_SPEED_LS;
break;
case USB_SPEED_VARIABLE:
xhci_dbg(xhci, "FIXME xHCI doesn't support wireless speeds\n");
@@ -327,7 +378,7 @@ int xhci_setup_addressable_virt_dev(struct xhci_hcd *xhci, struct usb_device *ud
for (top_dev = udev; top_dev->parent && top_dev->parent->parent;
top_dev = top_dev->parent)
/* Found device below root hub */;
- dev->in_ctx->slot.dev_info2 |= (u32) ROOT_HUB_PORT(top_dev->portnum);
+ slot_ctx->dev_info2 |= (u32) ROOT_HUB_PORT(top_dev->portnum);
xhci_dbg(xhci, "Set root hub portnum to %d\n", top_dev->portnum);
/* Is this a LS/FS device under a HS hub? */
@@ -337,8 +388,8 @@ int xhci_setup_addressable_virt_dev(struct xhci_hcd *xhci, struct usb_device *ud
*/
if ((udev->speed == USB_SPEED_LOW || udev->speed == USB_SPEED_FULL) &&
udev->tt) {
- dev->in_ctx->slot.tt_info = udev->tt->hub->slot_id;
- dev->in_ctx->slot.tt_info |= udev->ttport << 8;
+ slot_ctx->tt_info = udev->tt->hub->slot_id;
+ slot_ctx->tt_info |= udev->ttport << 8;
}
xhci_dbg(xhci, "udev->tt = %p\n", udev->tt);
xhci_dbg(xhci, "udev->ttport = 0x%x\n", udev->ttport);
@@ -360,10 +411,9 @@ int xhci_setup_addressable_virt_dev(struct xhci_hcd *xhci, struct usb_device *ud
ep0_ctx->ep_info2 |= MAX_BURST(0);
ep0_ctx->ep_info2 |= ERROR_COUNT(3);
- ep0_ctx->deq[0] =
+ ep0_ctx->deq =
dev->ep_rings[0]->first_seg->dma;
- ep0_ctx->deq[0] |= dev->ep_rings[0]->cycle_state;
- ep0_ctx->deq[1] = 0;
+ ep0_ctx->deq |= dev->ep_rings[0]->cycle_state;
/* Steps 7 and 8 were done in xhci_alloc_virt_device() */
@@ -470,25 +520,26 @@ int xhci_endpoint_init(struct xhci_hcd *xhci,
unsigned int max_burst;
ep_index = xhci_get_endpoint_index(&ep->desc);
- ep_ctx = &virt_dev->in_ctx->ep[ep_index];
+ ep_ctx = xhci_get_ep_ctx(xhci, virt_dev->in_ctx, ep_index);
/* Set up the endpoint ring */
virt_dev->new_ep_rings[ep_index] = xhci_ring_alloc(xhci, 1, true, mem_flags);
if (!virt_dev->new_ep_rings[ep_index])
return -ENOMEM;
ep_ring = virt_dev->new_ep_rings[ep_index];
- ep_ctx->deq[0] = ep_ring->first_seg->dma | ep_ring->cycle_state;
- ep_ctx->deq[1] = 0;
+ ep_ctx->deq = ep_ring->first_seg->dma | ep_ring->cycle_state;
ep_ctx->ep_info = xhci_get_endpoint_interval(udev, ep);
/* FIXME dig Mult and streams info out of ep companion desc */
- /* Allow 3 retries for everything but isoc */
+ /* Allow 3 retries for everything but isoc;
+ * error count = 0 means infinite retries.
+ */
if (!usb_endpoint_xfer_isoc(&ep->desc))
ep_ctx->ep_info2 = ERROR_COUNT(3);
else
- ep_ctx->ep_info2 = ERROR_COUNT(0);
+ ep_ctx->ep_info2 = ERROR_COUNT(1);
ep_ctx->ep_info2 |= xhci_get_endpoint_type(udev, ep);
@@ -498,7 +549,12 @@ int xhci_endpoint_init(struct xhci_hcd *xhci,
max_packet = ep->desc.wMaxPacketSize;
ep_ctx->ep_info2 |= MAX_PACKET(max_packet);
/* dig out max burst from ep companion desc */
- max_packet = ep->ss_ep_comp->desc.bMaxBurst;
+ if (!ep->ss_ep_comp) {
+ xhci_warn(xhci, "WARN no SS endpoint companion descriptor.\n");
+ max_packet = 0;
+ } else {
+ max_packet = ep->ss_ep_comp->desc.bMaxBurst;
+ }
ep_ctx->ep_info2 |= MAX_BURST(max_packet);
break;
case USB_SPEED_HIGH:
@@ -531,18 +587,114 @@ void xhci_endpoint_zero(struct xhci_hcd *xhci,
struct xhci_ep_ctx *ep_ctx;
ep_index = xhci_get_endpoint_index(&ep->desc);
- ep_ctx = &virt_dev->in_ctx->ep[ep_index];
+ ep_ctx = xhci_get_ep_ctx(xhci, virt_dev->in_ctx, ep_index);
ep_ctx->ep_info = 0;
ep_ctx->ep_info2 = 0;
- ep_ctx->deq[0] = 0;
- ep_ctx->deq[1] = 0;
+ ep_ctx->deq = 0;
ep_ctx->tx_info = 0;
/* Don't free the endpoint ring until the set interface or configuration
* request succeeds.
*/
}
+/* Set up the scratchpad buffer array and scratchpad buffers, if needed. */
+static int scratchpad_alloc(struct xhci_hcd *xhci, gfp_t flags)
+{
+ int i;
+ struct device *dev = xhci_to_hcd(xhci)->self.controller;
+ int num_sp = HCS_MAX_SCRATCHPAD(xhci->hcs_params2);
+
+ xhci_dbg(xhci, "Allocating %d scratchpad buffers\n", num_sp);
+
+ if (!num_sp)
+ return 0;
+
+ xhci->scratchpad = kzalloc(sizeof(*xhci->scratchpad), flags);
+ if (!xhci->scratchpad)
+ goto fail_sp;
+
+ xhci->scratchpad->sp_array =
+ pci_alloc_consistent(to_pci_dev(dev),
+ num_sp * sizeof(u64),
+ &xhci->scratchpad->sp_dma);
+ if (!xhci->scratchpad->sp_array)
+ goto fail_sp2;
+
+ xhci->scratchpad->sp_buffers = kzalloc(sizeof(void *) * num_sp, flags);
+ if (!xhci->scratchpad->sp_buffers)
+ goto fail_sp3;
+
+ xhci->scratchpad->sp_dma_buffers =
+ kzalloc(sizeof(dma_addr_t) * num_sp, flags);
+
+ if (!xhci->scratchpad->sp_dma_buffers)
+ goto fail_sp4;
+
+ xhci->dcbaa->dev_context_ptrs[0] = xhci->scratchpad->sp_dma;
+ for (i = 0; i < num_sp; i++) {
+ dma_addr_t dma;
+ void *buf = pci_alloc_consistent(to_pci_dev(dev),
+ xhci->page_size, &dma);
+ if (!buf)
+ goto fail_sp5;
+
+ xhci->scratchpad->sp_array[i] = dma;
+ xhci->scratchpad->sp_buffers[i] = buf;
+ xhci->scratchpad->sp_dma_buffers[i] = dma;
+ }
+
+ return 0;
+
+ fail_sp5:
+ for (i = i - 1; i >= 0; i--) {
+ pci_free_consistent(to_pci_dev(dev), xhci->page_size,
+ xhci->scratchpad->sp_buffers[i],
+ xhci->scratchpad->sp_dma_buffers[i]);
+ }
+ kfree(xhci->scratchpad->sp_dma_buffers);
+
+ fail_sp4:
+ kfree(xhci->scratchpad->sp_buffers);
+
+ fail_sp3:
+ pci_free_consistent(to_pci_dev(dev), num_sp * sizeof(u64),
+ xhci->scratchpad->sp_array,
+ xhci->scratchpad->sp_dma);
+
+ fail_sp2:
+ kfree(xhci->scratchpad);
+ xhci->scratchpad = NULL;
+
+ fail_sp:
+ return -ENOMEM;
+}
+
+static void scratchpad_free(struct xhci_hcd *xhci)
+{
+ int num_sp;
+ int i;
+ struct pci_dev *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller);
+
+ if (!xhci->scratchpad)
+ return;
+
+ num_sp = HCS_MAX_SCRATCHPAD(xhci->hcs_params2);
+
+ for (i = 0; i < num_sp; i++) {
+ pci_free_consistent(pdev, xhci->page_size,
+ xhci->scratchpad->sp_buffers[i],
+ xhci->scratchpad->sp_dma_buffers[i]);
+ }
+ kfree(xhci->scratchpad->sp_dma_buffers);
+ kfree(xhci->scratchpad->sp_buffers);
+ pci_free_consistent(pdev, num_sp * sizeof(u64),
+ xhci->scratchpad->sp_array,
+ xhci->scratchpad->sp_dma);
+ kfree(xhci->scratchpad);
+ xhci->scratchpad = NULL;
+}
+
void xhci_mem_cleanup(struct xhci_hcd *xhci)
{
struct pci_dev *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller);
@@ -551,10 +703,8 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci)
/* Free the Event Ring Segment Table and the actual Event Ring */
xhci_writel(xhci, 0, &xhci->ir_set->erst_size);
- xhci_writel(xhci, 0, &xhci->ir_set->erst_base[0]);
- xhci_writel(xhci, 0, &xhci->ir_set->erst_base[1]);
- xhci_writel(xhci, 0, &xhci->ir_set->erst_dequeue[0]);
- xhci_writel(xhci, 0, &xhci->ir_set->erst_dequeue[1]);
+ xhci_write_64(xhci, 0, &xhci->ir_set->erst_base);
+ xhci_write_64(xhci, 0, &xhci->ir_set->erst_dequeue);
size = sizeof(struct xhci_erst_entry)*(xhci->erst.num_entries);
if (xhci->erst.entries)
pci_free_consistent(pdev, size,
@@ -566,8 +716,7 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci)
xhci->event_ring = NULL;
xhci_dbg(xhci, "Freed event ring\n");
- xhci_writel(xhci, 0, &xhci->op_regs->cmd_ring[0]);
- xhci_writel(xhci, 0, &xhci->op_regs->cmd_ring[1]);
+ xhci_write_64(xhci, 0, &xhci->op_regs->cmd_ring);
if (xhci->cmd_ring)
xhci_ring_free(xhci, xhci->cmd_ring);
xhci->cmd_ring = NULL;
@@ -586,8 +735,7 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci)
xhci->device_pool = NULL;
xhci_dbg(xhci, "Freed device context pool\n");
- xhci_writel(xhci, 0, &xhci->op_regs->dcbaa_ptr[0]);
- xhci_writel(xhci, 0, &xhci->op_regs->dcbaa_ptr[1]);
+ xhci_write_64(xhci, 0, &xhci->op_regs->dcbaa_ptr);
if (xhci->dcbaa)
pci_free_consistent(pdev, sizeof(*xhci->dcbaa),
xhci->dcbaa, xhci->dcbaa->dma);
@@ -595,6 +743,7 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci)
xhci->page_size = 0;
xhci->page_shift = 0;
+ scratchpad_free(xhci);
}
int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
@@ -602,6 +751,7 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
dma_addr_t dma;
struct device *dev = xhci_to_hcd(xhci)->self.controller;
unsigned int val, val2;
+ u64 val_64;
struct xhci_segment *seg;
u32 page_size;
int i;
@@ -647,8 +797,7 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
xhci->dcbaa->dma = dma;
xhci_dbg(xhci, "// Device context base array address = 0x%llx (DMA), %p (virt)\n",
(unsigned long long)xhci->dcbaa->dma, xhci->dcbaa);
- xhci_writel(xhci, dma, &xhci->op_regs->dcbaa_ptr[0]);
- xhci_writel(xhci, (u32) 0, &xhci->op_regs->dcbaa_ptr[1]);
+ xhci_write_64(xhci, dma, &xhci->op_regs->dcbaa_ptr);
/*
* Initialize the ring segment pool. The ring must be a contiguous
@@ -658,11 +807,10 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
*/
xhci->segment_pool = dma_pool_create("xHCI ring segments", dev,
SEGMENT_SIZE, 64, xhci->page_size);
+
/* See Table 46 and Note on Figure 55 */
- /* FIXME support 64-byte contexts */
xhci->device_pool = dma_pool_create("xHCI input/output contexts", dev,
- sizeof(struct xhci_device_control),
- 64, xhci->page_size);
+ 2112, 64, xhci->page_size);
if (!xhci->segment_pool || !xhci->device_pool)
goto fail;
@@ -675,14 +823,12 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
(unsigned long long)xhci->cmd_ring->first_seg->dma);
/* Set the address in the Command Ring Control register */
- val = xhci_readl(xhci, &xhci->op_regs->cmd_ring[0]);
- val = (val & ~CMD_RING_ADDR_MASK) |
- (xhci->cmd_ring->first_seg->dma & CMD_RING_ADDR_MASK) |
+ val_64 = xhci_read_64(xhci, &xhci->op_regs->cmd_ring);
+ val_64 = (val_64 & (u64) CMD_RING_RSVD_BITS) |
+ (xhci->cmd_ring->first_seg->dma & (u64) ~CMD_RING_RSVD_BITS) |
xhci->cmd_ring->cycle_state;
- xhci_dbg(xhci, "// Setting command ring address low bits to 0x%x\n", val);
- xhci_writel(xhci, val, &xhci->op_regs->cmd_ring[0]);
- xhci_dbg(xhci, "// Setting command ring address high bits to 0x0\n");
- xhci_writel(xhci, (u32) 0, &xhci->op_regs->cmd_ring[1]);
+ xhci_dbg(xhci, "// Setting command ring address to 0x%x\n", val);
+ xhci_write_64(xhci, val_64, &xhci->op_regs->cmd_ring);
xhci_dbg_cmd_ptrs(xhci);
val = xhci_readl(xhci, &xhci->cap_regs->db_off);
@@ -722,8 +868,7 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
/* set ring base address and size for each segment table entry */
for (val = 0, seg = xhci->event_ring->first_seg; val < ERST_NUM_SEGS; val++) {
struct xhci_erst_entry *entry = &xhci->erst.entries[val];
- entry->seg_addr[0] = seg->dma;
- entry->seg_addr[1] = 0;
+ entry->seg_addr = seg->dma;
entry->seg_size = TRBS_PER_SEGMENT;
entry->rsvd = 0;
seg = seg->next;
@@ -741,11 +886,10 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
/* set the segment table base address */
xhci_dbg(xhci, "// Set ERST base address for ir_set 0 = 0x%llx\n",
(unsigned long long)xhci->erst.erst_dma_addr);
- val = xhci_readl(xhci, &xhci->ir_set->erst_base[0]);
- val &= ERST_PTR_MASK;
- val |= (xhci->erst.erst_dma_addr & ~ERST_PTR_MASK);
- xhci_writel(xhci, val, &xhci->ir_set->erst_base[0]);
- xhci_writel(xhci, 0, &xhci->ir_set->erst_base[1]);
+ val_64 = xhci_read_64(xhci, &xhci->ir_set->erst_base);
+ val_64 &= ERST_PTR_MASK;
+ val_64 |= (xhci->erst.erst_dma_addr & (u64) ~ERST_PTR_MASK);
+ xhci_write_64(xhci, val_64, &xhci->ir_set->erst_base);
/* Set the event ring dequeue address */
xhci_set_hc_event_deq(xhci);
@@ -761,7 +905,11 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
for (i = 0; i < MAX_HC_SLOTS; ++i)
xhci->devs[i] = 0;
+ if (scratchpad_alloc(xhci, flags))
+ goto fail;
+
return 0;
+
fail:
xhci_warn(xhci, "Couldn't initialize memory\n");
xhci_mem_cleanup(xhci);
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
index 1462709e26c..592fe7e623f 100644
--- a/drivers/usb/host/xhci-pci.c
+++ b/drivers/usb/host/xhci-pci.c
@@ -117,6 +117,7 @@ static const struct hc_driver xhci_pci_hc_driver = {
.free_dev = xhci_free_dev,
.add_endpoint = xhci_add_endpoint,
.drop_endpoint = xhci_drop_endpoint,
+ .endpoint_reset = xhci_endpoint_reset,
.check_bandwidth = xhci_check_bandwidth,
.reset_bandwidth = xhci_reset_bandwidth,
.address_device = xhci_address_device,
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 02d81985c45..aa88a067148 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -135,6 +135,7 @@ static void next_trb(struct xhci_hcd *xhci,
static void inc_deq(struct xhci_hcd *xhci, struct xhci_ring *ring, bool consumer)
{
union xhci_trb *next = ++(ring->dequeue);
+ unsigned long long addr;
ring->deq_updates++;
/* Update the dequeue pointer further if that was a link TRB or we're at
@@ -152,6 +153,13 @@ static void inc_deq(struct xhci_hcd *xhci, struct xhci_ring *ring, bool consumer
ring->dequeue = ring->deq_seg->trbs;
next = ring->dequeue;
}
+ addr = (unsigned long long) xhci_trb_virt_to_dma(ring->deq_seg, ring->dequeue);
+ if (ring == xhci->event_ring)
+ xhci_dbg(xhci, "Event ring deq = 0x%llx (DMA)\n", addr);
+ else if (ring == xhci->cmd_ring)
+ xhci_dbg(xhci, "Command ring deq = 0x%llx (DMA)\n", addr);
+ else
+ xhci_dbg(xhci, "Ring deq = 0x%llx (DMA)\n", addr);
}
/*
@@ -171,6 +179,7 @@ static void inc_enq(struct xhci_hcd *xhci, struct xhci_ring *ring, bool consumer
{
u32 chain;
union xhci_trb *next;
+ unsigned long long addr;
chain = ring->enqueue->generic.field[3] & TRB_CHAIN;
next = ++(ring->enqueue);
@@ -204,6 +213,13 @@ static void inc_enq(struct xhci_hcd *xhci, struct xhci_ring *ring, bool consumer
ring->enqueue = ring->enq_seg->trbs;
next = ring->enqueue;
}
+ addr = (unsigned long long) xhci_trb_virt_to_dma(ring->enq_seg, ring->enqueue);
+ if (ring == xhci->event_ring)
+ xhci_dbg(xhci, "Event ring enq = 0x%llx (DMA)\n", addr);
+ else if (ring == xhci->cmd_ring)
+ xhci_dbg(xhci, "Command ring enq = 0x%llx (DMA)\n", addr);
+ else
+ xhci_dbg(xhci, "Ring enq = 0x%llx (DMA)\n", addr);
}
/*
@@ -237,7 +253,7 @@ static int room_on_ring(struct xhci_hcd *xhci, struct xhci_ring *ring,
void xhci_set_hc_event_deq(struct xhci_hcd *xhci)
{
- u32 temp;
+ u64 temp;
dma_addr_t deq;
deq = xhci_trb_virt_to_dma(xhci->event_ring->deq_seg,
@@ -246,13 +262,15 @@ void xhci_set_hc_event_deq(struct xhci_hcd *xhci)
xhci_warn(xhci, "WARN something wrong with SW event ring "
"dequeue ptr.\n");
/* Update HC event ring dequeue pointer */
- temp = xhci_readl(xhci, &xhci->ir_set->erst_dequeue[0]);
+ temp = xhci_read_64(xhci, &xhci->ir_set->erst_dequeue);
temp &= ERST_PTR_MASK;
- if (!in_interrupt())
- xhci_dbg(xhci, "// Write event ring dequeue pointer\n");
- xhci_writel(xhci, 0, &xhci->ir_set->erst_dequeue[1]);
- xhci_writel(xhci, (deq & ~ERST_PTR_MASK) | temp,
- &xhci->ir_set->erst_dequeue[0]);
+ /* Don't clear the EHB bit (which is RW1C) because
+ * there might be more events to service.
+ */
+ temp &= ~ERST_EHB;
+ xhci_dbg(xhci, "// Write event ring dequeue pointer, preserving EHB bit\n");
+ xhci_write_64(xhci, ((u64) deq & (u64) ~ERST_PTR_MASK) | temp,
+ &xhci->ir_set->erst_dequeue);
}
/* Ring the host controller doorbell after placing a command on the ring */
@@ -279,7 +297,8 @@ static void ring_ep_doorbell(struct xhci_hcd *xhci,
/* Don't ring the doorbell for this endpoint if there are pending
* cancellations because the we don't want to interrupt processing.
*/
- if (!ep_ring->cancels_pending && !(ep_ring->state & SET_DEQ_PENDING)) {
+ if (!ep_ring->cancels_pending && !(ep_ring->state & SET_DEQ_PENDING)
+ && !(ep_ring->state & EP_HALTED)) {
field = xhci_readl(xhci, db_addr) & DB_MASK;
xhci_writel(xhci, field | EPI_TO_DB(ep_index), db_addr);
/* Flush PCI posted writes - FIXME Matthew Wilcox says this
@@ -316,12 +335,6 @@ static struct xhci_segment *find_trb_seg(
return cur_seg;
}
-struct dequeue_state {
- struct xhci_segment *new_deq_seg;
- union xhci_trb *new_deq_ptr;
- int new_cycle_state;
-};
-
/*
* Move the xHC's endpoint ring dequeue pointer past cur_td.
* Record the new state of the xHC's endpoint ring dequeue segment,
@@ -336,24 +349,30 @@ struct dequeue_state {
* - Finally we move the dequeue state one TRB further, toggling the cycle bit
* if we've moved it past a link TRB with the toggle cycle bit set.
*/
-static void find_new_dequeue_state(struct xhci_hcd *xhci,
+void xhci_find_new_dequeue_state(struct xhci_hcd *xhci,
unsigned int slot_id, unsigned int ep_index,
- struct xhci_td *cur_td, struct dequeue_state *state)
+ struct xhci_td *cur_td, struct xhci_dequeue_state *state)
{
struct xhci_virt_device *dev = xhci->devs[slot_id];
struct xhci_ring *ep_ring = dev->ep_rings[ep_index];
struct xhci_generic_trb *trb;
+ struct xhci_ep_ctx *ep_ctx;
+ dma_addr_t addr;
state->new_cycle_state = 0;
+ xhci_dbg(xhci, "Finding segment containing stopped TRB.\n");
state->new_deq_seg = find_trb_seg(cur_td->start_seg,
ep_ring->stopped_trb,
&state->new_cycle_state);
if (!state->new_deq_seg)
BUG();
/* Dig out the cycle state saved by the xHC during the stop ep cmd */
- state->new_cycle_state = 0x1 & dev->out_ctx->ep[ep_index].deq[0];
+ xhci_dbg(xhci, "Finding endpoint context\n");
+ ep_ctx = xhci_get_ep_ctx(xhci, dev->out_ctx, ep_index);
+ state->new_cycle_state = 0x1 & ep_ctx->deq;
state->new_deq_ptr = cur_td->last_trb;
+ xhci_dbg(xhci, "Finding segment containing last TRB in TD.\n");
state->new_deq_seg = find_trb_seg(state->new_deq_seg,
state->new_deq_ptr,
&state->new_cycle_state);
@@ -367,6 +386,12 @@ static void find_new_dequeue_state(struct xhci_hcd *xhci,
next_trb(xhci, ep_ring, &state->new_deq_seg, &state->new_deq_ptr);
/* Don't update the ring cycle state for the producer (us). */
+ xhci_dbg(xhci, "New dequeue segment = %p (virtual)\n",
+ state->new_deq_seg);
+ addr = xhci_trb_virt_to_dma(state->new_deq_seg, state->new_deq_ptr);
+ xhci_dbg(xhci, "New dequeue pointer = 0x%llx (DMA)\n",
+ (unsigned long long) addr);
+ xhci_dbg(xhci, "Setting dequeue pointer in internal ring state.\n");
ep_ring->dequeue = state->new_deq_ptr;
ep_ring->deq_seg = state->new_deq_seg;
}
@@ -416,6 +441,30 @@ static int queue_set_tr_deq(struct xhci_hcd *xhci, int slot_id,
unsigned int ep_index, struct xhci_segment *deq_seg,
union xhci_trb *deq_ptr, u32 cycle_state);
+void xhci_queue_new_dequeue_state(struct xhci_hcd *xhci,
+ struct xhci_ring *ep_ring, unsigned int slot_id,
+ unsigned int ep_index, struct xhci_dequeue_state *deq_state)
+{
+ xhci_dbg(xhci, "Set TR Deq Ptr cmd, new deq seg = %p (0x%llx dma), "
+ "new deq ptr = %p (0x%llx dma), new cycle = %u\n",
+ deq_state->new_deq_seg,
+ (unsigned long long)deq_state->new_deq_seg->dma,
+ deq_state->new_deq_ptr,
+ (unsigned long long)xhci_trb_virt_to_dma(deq_state->new_deq_seg, deq_state->new_deq_ptr),
+ deq_state->new_cycle_state);
+ queue_set_tr_deq(xhci, slot_id, ep_index,
+ deq_state->new_deq_seg,
+ deq_state->new_deq_ptr,
+ (u32) deq_state->new_cycle_state);
+ /* Stop the TD queueing code from ringing the doorbell until
+ * this command completes. The HC won't set the dequeue pointer
+ * if the ring is running, and ringing the doorbell starts the
+ * ring running.
+ */
+ ep_ring->state |= SET_DEQ_PENDING;
+ xhci_ring_cmd_db(xhci);
+}
+
/*
* When we get a command completion for a Stop Endpoint Command, we need to
* unlink any cancelled TDs from the ring. There are two ways to do that:
@@ -436,7 +485,7 @@ static void handle_stopped_endpoint(struct xhci_hcd *xhci,
struct xhci_td *cur_td = 0;
struct xhci_td *last_unlinked_td;
- struct dequeue_state deq_state;
+ struct xhci_dequeue_state deq_state;
#ifdef CONFIG_USB_HCD_STAT
ktime_t stop_time = ktime_get();
#endif
@@ -464,7 +513,7 @@ static void handle_stopped_endpoint(struct xhci_hcd *xhci,
* move the xHC endpoint ring dequeue pointer past this TD.
*/
if (cur_td == ep_ring->stopped_td)
- find_new_dequeue_state(xhci, slot_id, ep_index, cur_td,
+ xhci_find_new_dequeue_state(xhci, slot_id, ep_index, cur_td,
&deq_state);
else
td_to_noop(xhci, ep_ring, cur_td);
@@ -480,24 +529,8 @@ static void handle_stopped_endpoint(struct xhci_hcd *xhci,
/* If necessary, queue a Set Transfer Ring Dequeue Pointer command */
if (deq_state.new_deq_ptr && deq_state.new_deq_seg) {
- xhci_dbg(xhci, "Set TR Deq Ptr cmd, new deq seg = %p (0x%llx dma), "
- "new deq ptr = %p (0x%llx dma), new cycle = %u\n",
- deq_state.new_deq_seg,
- (unsigned long long)deq_state.new_deq_seg->dma,
- deq_state.new_deq_ptr,
- (unsigned long long)xhci_trb_virt_to_dma(deq_state.new_deq_seg, deq_state.new_deq_ptr),
- deq_state.new_cycle_state);
- queue_set_tr_deq(xhci, slot_id, ep_index,
- deq_state.new_deq_seg,
- deq_state.new_deq_ptr,
- (u32) deq_state.new_cycle_state);
- /* Stop the TD queueing code from ringing the doorbell until
- * this command completes. The HC won't set the dequeue pointer
- * if the ring is running, and ringing the doorbell starts the
- * ring running.
- */
- ep_ring->state |= SET_DEQ_PENDING;
- xhci_ring_cmd_db(xhci);
+ xhci_queue_new_dequeue_state(xhci, ep_ring,
+ slot_id, ep_index, &deq_state);
} else {
/* Otherwise just ring the doorbell to restart the ring */
ring_ep_doorbell(xhci, slot_id, ep_index);
@@ -551,11 +584,15 @@ static void handle_set_deq_completion(struct xhci_hcd *xhci,
unsigned int ep_index;
struct xhci_ring *ep_ring;
struct xhci_virt_device *dev;
+ struct xhci_ep_ctx *ep_ctx;
+ struct xhci_slot_ctx *slot_ctx;
slot_id = TRB_TO_SLOT_ID(trb->generic.field[3]);
ep_index = TRB_TO_EP_INDEX(trb->generic.field[3]);
dev = xhci->devs[slot_id];
ep_ring = dev->ep_rings[ep_index];
+ ep_ctx = xhci_get_ep_ctx(xhci, dev->out_ctx, ep_index);
+ slot_ctx = xhci_get_slot_ctx(xhci, dev->out_ctx);
if (GET_COMP_CODE(event->status) != COMP_SUCCESS) {
unsigned int ep_state;
@@ -569,9 +606,9 @@ static void handle_set_deq_completion(struct xhci_hcd *xhci,
case COMP_CTX_STATE:
xhci_warn(xhci, "WARN Set TR Deq Ptr cmd failed due "
"to incorrect slot or ep state.\n");
- ep_state = dev->out_ctx->ep[ep_index].ep_info;
+ ep_state = ep_ctx->ep_info;
ep_state &= EP_STATE_MASK;
- slot_state = dev->out_ctx->slot.dev_state;
+ slot_state = slot_ctx->dev_state;
slot_state = GET_SLOT_STATE(slot_state);
xhci_dbg(xhci, "Slot state = %u, EP state = %u\n",
slot_state, ep_state);
@@ -593,16 +630,33 @@ static void handle_set_deq_completion(struct xhci_hcd *xhci,
* cancelling URBs, which might not be an error...
*/
} else {
- xhci_dbg(xhci, "Successful Set TR Deq Ptr cmd, deq[0] = 0x%x, "
- "deq[1] = 0x%x.\n",
- dev->out_ctx->ep[ep_index].deq[0],
- dev->out_ctx->ep[ep_index].deq[1]);
+ xhci_dbg(xhci, "Successful Set TR Deq Ptr cmd, deq = @%08llx\n",
+ ep_ctx->deq);
}
ep_ring->state &= ~SET_DEQ_PENDING;
ring_ep_doorbell(xhci, slot_id, ep_index);
}
+static void handle_reset_ep_completion(struct xhci_hcd *xhci,
+ struct xhci_event_cmd *event,
+ union xhci_trb *trb)
+{
+ int slot_id;
+ unsigned int ep_index;
+
+ slot_id = TRB_TO_SLOT_ID(trb->generic.field[3]);
+ ep_index = TRB_TO_EP_INDEX(trb->generic.field[3]);
+ /* This command will only fail if the endpoint wasn't halted,
+ * but we don't care.
+ */
+ xhci_dbg(xhci, "Ignoring reset ep completion code of %u\n",
+ (unsigned int) GET_COMP_CODE(event->status));
+
+ /* Clear our internal halted state and restart the ring */
+ xhci->devs[slot_id]->ep_rings[ep_index]->state &= ~EP_HALTED;
+ ring_ep_doorbell(xhci, slot_id, ep_index);
+}
static void handle_cmd_completion(struct xhci_hcd *xhci,
struct xhci_event_cmd *event)
@@ -611,7 +665,7 @@ static void handle_cmd_completion(struct xhci_hcd *xhci,
u64 cmd_dma;
dma_addr_t cmd_dequeue_dma;
- cmd_dma = (((u64) event->cmd_trb[1]) << 32) + event->cmd_trb[0];
+ cmd_dma = event->cmd_trb;
cmd_dequeue_dma = xhci_trb_virt_to_dma(xhci->cmd_ring->deq_seg,
xhci->cmd_ring->dequeue);
/* Is the command ring deq ptr out of sync with the deq seg ptr? */
@@ -653,6 +707,9 @@ static void handle_cmd_completion(struct xhci_hcd *xhci,
case TRB_TYPE(TRB_CMD_NOOP):
++xhci->noops_handled;
break;
+ case TRB_TYPE(TRB_RESET_EP):
+ handle_reset_ep_completion(xhci, event, xhci->cmd_ring->dequeue);
+ break;
default:
/* Skip over unknown commands on the event ring */
xhci->error_bitmask |= 1 << 6;
@@ -756,7 +813,9 @@ static int handle_tx_event(struct xhci_hcd *xhci,
union xhci_trb *event_trb;
struct urb *urb = 0;
int status = -EINPROGRESS;
+ struct xhci_ep_ctx *ep_ctx;
+ xhci_dbg(xhci, "In %s\n", __func__);
xdev = xhci->devs[TRB_TO_SLOT_ID(event->flags)];
if (!xdev) {
xhci_err(xhci, "ERROR Transfer event pointed to bad slot\n");
@@ -765,17 +824,17 @@ static int handle_tx_event(struct xhci_hcd *xhci,
/* Endpoint ID is 1 based, our index is zero based */
ep_index = TRB_TO_EP_ID(event->flags) - 1;
+ xhci_dbg(xhci, "%s - ep index = %d\n", __func__, ep_index);
ep_ring = xdev->ep_rings[ep_index];
- if (!ep_ring || (xdev->out_ctx->ep[ep_index].ep_info & EP_STATE_MASK) == EP_STATE_DISABLED) {
+ ep_ctx = xhci_get_ep_ctx(xhci, xdev->out_ctx, ep_index);
+ if (!ep_ring || (ep_ctx->ep_info & EP_STATE_MASK) == EP_STATE_DISABLED) {
xhci_err(xhci, "ERROR Transfer event pointed to disabled endpoint\n");
return -ENODEV;
}
- event_dma = event->buffer[0];
- if (event->buffer[1] != 0)
- xhci_warn(xhci, "WARN ignoring upper 32-bits of 64-bit TRB dma address\n");
-
+ event_dma = event->buffer;
/* This TRB should be in the TD at the head of this ring's TD list */
+ xhci_dbg(xhci, "%s - checking for list empty\n", __func__);
if (list_empty(&ep_ring->td_list)) {
xhci_warn(xhci, "WARN Event TRB for slot %d ep %d with no TDs queued?\n",
TRB_TO_SLOT_ID(event->flags), ep_index);
@@ -785,11 +844,14 @@ static int handle_tx_event(struct xhci_hcd *xhci,
urb = NULL;
goto cleanup;
}
+ xhci_dbg(xhci, "%s - getting list entry\n", __func__);
td = list_entry(ep_ring->td_list.next, struct xhci_td, td_list);
/* Is this a TRB in the currently executing TD? */
+ xhci_dbg(xhci, "%s - looking for TD\n", __func__);
event_seg = trb_in_td(ep_ring->deq_seg, ep_ring->dequeue,
td->last_trb, event_dma);
+ xhci_dbg(xhci, "%s - found event_seg = %p\n", __func__, event_seg);
if (!event_seg) {
/* HC is busted, give up! */
xhci_err(xhci, "ERROR Transfer event TRB DMA ptr not part of current TD\n");
@@ -798,10 +860,10 @@ static int handle_tx_event(struct xhci_hcd *xhci,
event_trb = &event_seg->trbs[(event_dma - event_seg->dma) / sizeof(*event_trb)];
xhci_dbg(xhci, "Event TRB with TRB type ID %u\n",
(unsigned int) (event->flags & TRB_TYPE_BITMASK)>>10);
- xhci_dbg(xhci, "Offset 0x00 (buffer[0]) = 0x%x\n",
- (unsigned int) event->buffer[0]);
- xhci_dbg(xhci, "Offset 0x04 (buffer[0]) = 0x%x\n",
- (unsigned int) event->buffer[1]);
+ xhci_dbg(xhci, "Offset 0x00 (buffer lo) = 0x%x\n",
+ lower_32_bits(event->buffer));
+ xhci_dbg(xhci, "Offset 0x04 (buffer hi) = 0x%x\n",
+ upper_32_bits(event->buffer));
xhci_dbg(xhci, "Offset 0x08 (transfer length) = 0x%x\n",
(unsigned int) event->transfer_len);
xhci_dbg(xhci, "Offset 0x0C (flags) = 0x%x\n",
@@ -823,6 +885,7 @@ static int handle_tx_event(struct xhci_hcd *xhci,
break;
case COMP_STALL:
xhci_warn(xhci, "WARN: Stalled endpoint\n");
+ ep_ring->state |= EP_HALTED;
status = -EPIPE;
break;
case COMP_TRB_ERR:
@@ -833,6 +896,10 @@ static int handle_tx_event(struct xhci_hcd *xhci,
xhci_warn(xhci, "WARN: transfer error on endpoint\n");
status = -EPROTO;
break;
+ case COMP_BABBLE:
+ xhci_warn(xhci, "WARN: babble error on endpoint\n");
+ status = -EOVERFLOW;
+ break;
case COMP_DB_ERR:
xhci_warn(xhci, "WARN: HC couldn't access mem fast enough\n");
status = -ENOSR;
@@ -874,15 +941,26 @@ static int handle_tx_event(struct xhci_hcd *xhci,
if (event_trb != ep_ring->dequeue) {
/* The event was for the status stage */
if (event_trb == td->last_trb) {
- td->urb->actual_length =
- td->urb->transfer_buffer_length;
+ if (td->urb->actual_length != 0) {
+ /* Don't overwrite a previously set error code */
+ if (status == -EINPROGRESS || status == 0)
+ /* Did we already see a short data stage? */
+ status = -EREMOTEIO;
+ } else {
+ td->urb->actual_length =
+ td->urb->transfer_buffer_length;
+ }
} else {
/* Maybe the event was for the data stage? */
- if (GET_COMP_CODE(event->transfer_len) != COMP_STOP_INVAL)
+ if (GET_COMP_CODE(event->transfer_len) != COMP_STOP_INVAL) {
/* We didn't stop on a link TRB in the middle */
td->urb->actual_length =
td->urb->transfer_buffer_length -
TRB_LEN(event->transfer_len);
+ xhci_dbg(xhci, "Waiting for status stage event\n");
+ urb = NULL;
+ goto cleanup;
+ }
}
}
} else {
@@ -929,16 +1007,20 @@ static int handle_tx_event(struct xhci_hcd *xhci,
TRB_LEN(event->transfer_len));
td->urb->actual_length = 0;
}
- if (td->urb->transfer_flags & URB_SHORT_NOT_OK)
- status = -EREMOTEIO;
- else
- status = 0;
+ /* Don't overwrite a previously set error code */
+ if (status == -EINPROGRESS) {
+ if (td->urb->transfer_flags & URB_SHORT_NOT_OK)
+ status = -EREMOTEIO;
+ else
+ status = 0;
+ }
} else {
td->urb->actual_length = td->urb->transfer_buffer_length;
/* Ignore a short packet completion if the
* untransferred length was zero.
*/
- status = 0;
+ if (status == -EREMOTEIO)
+ status = 0;
}
} else {
/* Slow path - walk the list, starting from the dequeue
@@ -965,19 +1047,30 @@ static int handle_tx_event(struct xhci_hcd *xhci,
TRB_LEN(event->transfer_len);
}
}
- /* The Endpoint Stop Command completion will take care of
- * any stopped TDs. A stopped TD may be restarted, so don't update the
- * ring dequeue pointer or take this TD off any lists yet.
- */
if (GET_COMP_CODE(event->transfer_len) == COMP_STOP_INVAL ||
GET_COMP_CODE(event->transfer_len) == COMP_STOP) {
+ /* The Endpoint Stop Command completion will take care of any
+ * stopped TDs. A stopped TD may be restarted, so don't update
+ * the ring dequeue pointer or take this TD off any lists yet.
+ */
ep_ring->stopped_td = td;
ep_ring->stopped_trb = event_trb;
} else {
- /* Update ring dequeue pointer */
- while (ep_ring->dequeue != td->last_trb)
+ if (GET_COMP_CODE(event->transfer_len) == COMP_STALL) {
+ /* The transfer is completed from the driver's
+ * perspective, but we need to issue a set dequeue
+ * command for this stalled endpoint to move the dequeue
+ * pointer past the TD. We can't do that here because
+ * the halt condition must be cleared first.
+ */
+ ep_ring->stopped_td = td;
+ ep_ring->stopped_trb = event_trb;
+ } else {
+ /* Update ring dequeue pointer */
+ while (ep_ring->dequeue != td->last_trb)
+ inc_deq(xhci, ep_ring, false);
inc_deq(xhci, ep_ring, false);
- inc_deq(xhci, ep_ring, false);
+ }
/* Clean up the endpoint's TD list */
urb = td->urb;
@@ -987,7 +1080,10 @@ static int handle_tx_event(struct xhci_hcd *xhci,
list_del(&td->cancelled_td_list);
ep_ring->cancels_pending--;
}
- kfree(td);
+ /* Leave the TD around for the reset endpoint function to use */
+ if (GET_COMP_CODE(event->transfer_len) != COMP_STALL) {
+ kfree(td);
+ }
urb->hcpriv = NULL;
}
cleanup:
@@ -997,6 +1093,8 @@ cleanup:
/* FIXME for multi-TD URBs (who have buffers bigger than 64MB) */
if (urb) {
usb_hcd_unlink_urb_from_ep(xhci_to_hcd(xhci), urb);
+ xhci_dbg(xhci, "Giveback URB %p, len = %d, status = %d\n",
+ urb, td->urb->actual_length, status);
spin_unlock(&xhci->lock);
usb_hcd_giveback_urb(xhci_to_hcd(xhci), urb, status);
spin_lock(&xhci->lock);
@@ -1014,6 +1112,7 @@ void xhci_handle_event(struct xhci_hcd *xhci)
int update_ptrs = 1;
int ret;
+ xhci_dbg(xhci, "In %s\n", __func__);
if (!xhci->event_ring || !xhci->event_ring->dequeue) {
xhci->error_bitmask |= 1 << 1;
return;
@@ -1026,18 +1125,25 @@ void xhci_handle_event(struct xhci_hcd *xhci)
xhci->error_bitmask |= 1 << 2;
return;
}
+ xhci_dbg(xhci, "%s - OS owns TRB\n", __func__);
/* FIXME: Handle more event types. */
switch ((event->event_cmd.flags & TRB_TYPE_BITMASK)) {
case TRB_TYPE(TRB_COMPLETION):
+ xhci_dbg(xhci, "%s - calling handle_cmd_completion\n", __func__);
handle_cmd_completion(xhci, &event->event_cmd);
+ xhci_dbg(xhci, "%s - returned from handle_cmd_completion\n", __func__);
break;
case TRB_TYPE(TRB_PORT_STATUS):
+ xhci_dbg(xhci, "%s - calling handle_port_status\n", __func__);
handle_port_status(xhci, event);
+ xhci_dbg(xhci, "%s - returned from handle_port_status\n", __func__);
update_ptrs = 0;
break;
case TRB_TYPE(TRB_TRANSFER):
+ xhci_dbg(xhci, "%s - calling handle_tx_event\n", __func__);
ret = handle_tx_event(xhci, &event->trans_event);
+ xhci_dbg(xhci, "%s - returned from handle_tx_event\n", __func__);
if (ret < 0)
xhci->error_bitmask |= 1 << 9;
else
@@ -1093,13 +1199,13 @@ static int prepare_ring(struct xhci_hcd *xhci, struct xhci_ring *ep_ring,
*/
xhci_warn(xhci, "WARN urb submitted to disabled ep\n");
return -ENOENT;
- case EP_STATE_HALTED:
case EP_STATE_ERROR:
- xhci_warn(xhci, "WARN waiting for halt or error on ep "
- "to be cleared\n");
+ xhci_warn(xhci, "WARN waiting for error on ep to be cleared\n");
/* FIXME event handling code for error needs to clear it */
/* XXX not sure if this should be -ENOENT or not */
return -EINVAL;
+ case EP_STATE_HALTED:
+ xhci_dbg(xhci, "WARN halted endpoint, queueing URB anyway.\n");
case EP_STATE_STOPPED:
case EP_STATE_RUNNING:
break;
@@ -1128,9 +1234,9 @@ static int prepare_transfer(struct xhci_hcd *xhci,
gfp_t mem_flags)
{
int ret;
-
+ struct xhci_ep_ctx *ep_ctx = xhci_get_ep_ctx(xhci, xdev->out_ctx, ep_index);
ret = prepare_ring(xhci, xdev->ep_rings[ep_index],
- xdev->out_ctx->ep[ep_index].ep_info & EP_STATE_MASK,
+ ep_ctx->ep_info & EP_STATE_MASK,
num_trbs, mem_flags);
if (ret)
return ret;
@@ -1285,6 +1391,7 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
/* Queue the first TRB, even if it's zero-length */
do {
u32 field = 0;
+ u32 length_field = 0;
/* Don't change the cycle bit of the first TRB until later */
if (first_trb)
@@ -1314,10 +1421,13 @@ static int queue_bulk_sg_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
(unsigned int) (addr + TRB_MAX_BUFF_SIZE) & ~(TRB_MAX_BUFF_SIZE - 1),
(unsigned int) addr + trb_buff_len);
}
+ length_field = TRB_LEN(trb_buff_len) |
+ TD_REMAINDER(urb->transfer_buffer_length - running_total) |
+ TRB_INTR_TARGET(0);
queue_trb(xhci, ep_ring, false,
- (u32) addr,
- (u32) ((u64) addr >> 32),
- TRB_LEN(trb_buff_len) | TRB_INTR_TARGET(0),
+ lower_32_bits(addr),
+ upper_32_bits(addr),
+ length_field,
/* We always want to know if the TRB was short,
* or we won't get an event when it completes.
* (Unless we use event data TRBs, which are a
@@ -1365,7 +1475,7 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
struct xhci_generic_trb *start_trb;
bool first_trb;
int start_cycle;
- u32 field;
+ u32 field, length_field;
int running_total, trb_buff_len, ret;
u64 addr;
@@ -1443,10 +1553,13 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
td->last_trb = ep_ring->enqueue;
field |= TRB_IOC;
}
+ length_field = TRB_LEN(trb_buff_len) |
+ TD_REMAINDER(urb->transfer_buffer_length - running_total) |
+ TRB_INTR_TARGET(0);
queue_trb(xhci, ep_ring, false,
- (u32) addr,
- (u32) ((u64) addr >> 32),
- TRB_LEN(trb_buff_len) | TRB_INTR_TARGET(0),
+ lower_32_bits(addr),
+ upper_32_bits(addr),
+ length_field,
/* We always want to know if the TRB was short,
* or we won't get an event when it completes.
* (Unless we use event data TRBs, which are a
@@ -1478,7 +1591,7 @@ int xhci_queue_ctrl_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
struct usb_ctrlrequest *setup;
struct xhci_generic_trb *start_trb;
int start_cycle;
- u32 field;
+ u32 field, length_field;
struct xhci_td *td;
ep_ring = xhci->devs[slot_id]->ep_rings[ep_index];
@@ -1528,13 +1641,16 @@ int xhci_queue_ctrl_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
/* If there's data, queue data TRBs */
field = 0;
+ length_field = TRB_LEN(urb->transfer_buffer_length) |
+ TD_REMAINDER(urb->transfer_buffer_length) |
+ TRB_INTR_TARGET(0);
if (urb->transfer_buffer_length > 0) {
if (setup->bRequestType & USB_DIR_IN)
field |= TRB_DIR_IN;
queue_trb(xhci, ep_ring, false,
lower_32_bits(urb->transfer_dma),
upper_32_bits(urb->transfer_dma),
- TRB_LEN(urb->transfer_buffer_length) | TRB_INTR_TARGET(0),
+ length_field,
/* Event on short tx */
field | TRB_ISP | TRB_TYPE(TRB_DATA) | ep_ring->cycle_state);
}
@@ -1603,7 +1719,8 @@ int xhci_queue_slot_control(struct xhci_hcd *xhci, u32 trb_type, u32 slot_id)
int xhci_queue_address_device(struct xhci_hcd *xhci, dma_addr_t in_ctx_ptr,
u32 slot_id)
{
- return queue_command(xhci, in_ctx_ptr, 0, 0,
+ return queue_command(xhci, lower_32_bits(in_ctx_ptr),
+ upper_32_bits(in_ctx_ptr), 0,
TRB_TYPE(TRB_ADDR_DEV) | SLOT_ID_FOR_TRB(slot_id));
}
@@ -1611,7 +1728,8 @@ int xhci_queue_address_device(struct xhci_hcd *xhci, dma_addr_t in_ctx_ptr,
int xhci_queue_configure_endpoint(struct xhci_hcd *xhci, dma_addr_t in_ctx_ptr,
u32 slot_id)
{
- return queue_command(xhci, in_ctx_ptr, 0, 0,
+ return queue_command(xhci, lower_32_bits(in_ctx_ptr),
+ upper_32_bits(in_ctx_ptr), 0,
TRB_TYPE(TRB_CONFIG_EP) | SLOT_ID_FOR_TRB(slot_id));
}
@@ -1639,10 +1757,23 @@ static int queue_set_tr_deq(struct xhci_hcd *xhci, int slot_id,
u32 type = TRB_TYPE(TRB_SET_DEQ);
addr = xhci_trb_virt_to_dma(deq_seg, deq_ptr);
- if (addr == 0)
+ if (addr == 0) {
xhci_warn(xhci, "WARN Cannot submit Set TR Deq Ptr\n");
xhci_warn(xhci, "WARN deq seg = %p, deq pt = %p\n",
deq_seg, deq_ptr);
- return queue_command(xhci, (u32) addr | cycle_state, 0, 0,
+ return 0;
+ }
+ return queue_command(xhci, lower_32_bits(addr) | cycle_state,
+ upper_32_bits(addr), 0,
trb_slot_id | trb_ep_index | type);
}
+
+int xhci_queue_reset_ep(struct xhci_hcd *xhci, int slot_id,
+ unsigned int ep_index)
+{
+ u32 trb_slot_id = SLOT_ID_FOR_TRB(slot_id);
+ u32 trb_ep_index = EP_ID_FOR_TRB(ep_index);
+ u32 type = TRB_TYPE(TRB_RESET_EP);
+
+ return queue_command(xhci, 0, 0, 0, trb_slot_id | trb_ep_index | type);
+}
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index 8936eeb5588..d31d32206ba 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -25,6 +25,7 @@
#include <linux/usb.h>
#include <linux/timer.h>
+#include <linux/kernel.h>
#include "../core/hcd.h"
/* Code sharing between pci-quirks and xhci hcd */
@@ -42,14 +43,6 @@
* xHCI register interface.
* This corresponds to the eXtensible Host Controller Interface (xHCI)
* Revision 0.95 specification
- *
- * Registers should always be accessed with double word or quad word accesses.
- *
- * Some xHCI implementations may support 64-bit address pointers. Registers
- * with 64-bit address pointers should be written to with dword accesses by
- * writing the low dword first (ptr[0]), then the high dword (ptr[1]) second.
- * xHCI implementations that do not support 64-bit address pointers will ignore
- * the high dword, and write order is irrelevant.
*/
/**
@@ -96,6 +89,7 @@ struct xhci_cap_regs {
#define HCS_ERST_MAX(p) (((p) >> 4) & 0xf)
/* bit 26 Scratchpad restore - for save/restore HW state - not used yet */
/* bits 27:31 number of Scratchpad buffers SW must allocate for the HW */
+#define HCS_MAX_SCRATCHPAD(p) (((p) >> 27) & 0x1f)
/* HCSPARAMS3 - hcs_params3 - bitmasks */
/* bits 0:7, Max U1 to U0 latency for the roothub ports */
@@ -166,10 +160,10 @@ struct xhci_op_regs {
u32 reserved1;
u32 reserved2;
u32 dev_notification;
- u32 cmd_ring[2];
+ u64 cmd_ring;
/* rsvd: offset 0x20-2F */
u32 reserved3[4];
- u32 dcbaa_ptr[2];
+ u64 dcbaa_ptr;
u32 config_reg;
/* rsvd: offset 0x3C-3FF */
u32 reserved4[241];
@@ -254,7 +248,7 @@ struct xhci_op_regs {
#define CMD_RING_RUNNING (1 << 3)
/* bits 4:5 reserved and should be preserved */
/* Command Ring pointer - bit mask for the lower 32 bits. */
-#define CMD_RING_ADDR_MASK (0xffffffc0)
+#define CMD_RING_RSVD_BITS (0x3f)
/* CONFIG - Configure Register - config_reg bitmasks */
/* bits 0:7 - maximum number of device slots enabled (NumSlotsEn) */
@@ -382,8 +376,8 @@ struct xhci_intr_reg {
u32 irq_control;
u32 erst_size;
u32 rsvd;
- u32 erst_base[2];
- u32 erst_dequeue[2];
+ u64 erst_base;
+ u64 erst_dequeue;
};
/* irq_pending bitmasks */
@@ -453,6 +447,27 @@ struct xhci_doorbell_array {
/**
+ * struct xhci_container_ctx
+ * @type: Type of context. Used to calculated offsets to contained contexts.
+ * @size: Size of the context data
+ * @bytes: The raw context data given to HW
+ * @dma: dma address of the bytes
+ *
+ * Represents either a Device or Input context. Holds a pointer to the raw
+ * memory used for the context (bytes) and dma address of it (dma).
+ */
+struct xhci_container_ctx {
+ unsigned type;
+#define XHCI_CTX_TYPE_DEVICE 0x1
+#define XHCI_CTX_TYPE_INPUT 0x2
+
+ int size;
+
+ u8 *bytes;
+ dma_addr_t dma;
+};
+
+/**
* struct xhci_slot_ctx
* @dev_info: Route string, device speed, hub info, and last valid endpoint
* @dev_info2: Max exit latency for device number, root hub port number
@@ -538,7 +553,7 @@ struct xhci_slot_ctx {
struct xhci_ep_ctx {
u32 ep_info;
u32 ep_info2;
- u32 deq[2];
+ u64 deq;
u32 tx_info;
/* offset 0x14 - 0x1f reserved for HC internal use */
u32 reserved[3];
@@ -589,18 +604,16 @@ struct xhci_ep_ctx {
/**
- * struct xhci_device_control
- * Input/Output context; see section 6.2.5.
+ * struct xhci_input_control_context
+ * Input control context; see section 6.2.5.
*
* @drop_context: set the bit of the endpoint context you want to disable
* @add_context: set the bit of the endpoint context you want to enable
*/
-struct xhci_device_control {
+struct xhci_input_control_ctx {
u32 drop_flags;
u32 add_flags;
- u32 rsvd[6];
- struct xhci_slot_ctx slot;
- struct xhci_ep_ctx ep[31];
+ u32 rsvd2[6];
};
/* drop context bitmasks */
@@ -608,7 +621,6 @@ struct xhci_device_control {
/* add context bitmasks */
#define ADD_EP(x) (0x1 << x)
-
struct xhci_virt_device {
/*
* Commands to the hardware are passed an "input context" that
@@ -618,11 +630,10 @@ struct xhci_virt_device {
* track of input and output contexts separately because
* these commands might fail and we don't trust the hardware.
*/
- struct xhci_device_control *out_ctx;
- dma_addr_t out_ctx_dma;
+ struct xhci_container_ctx *out_ctx;
/* Used for addressing devices and configuration changes */
- struct xhci_device_control *in_ctx;
- dma_addr_t in_ctx_dma;
+ struct xhci_container_ctx *in_ctx;
+
/* FIXME when stream support is added */
struct xhci_ring *ep_rings[31];
/* Temporary storage in case the configure endpoint command fails and we
@@ -641,7 +652,7 @@ struct xhci_virt_device {
*/
struct xhci_device_context_array {
/* 64-bit device addresses; we only write 32-bit addresses */
- u32 dev_context_ptrs[2*MAX_HC_SLOTS];
+ u64 dev_context_ptrs[MAX_HC_SLOTS];
/* private xHCD pointers */
dma_addr_t dma;
};
@@ -654,7 +665,7 @@ struct xhci_device_context_array {
struct xhci_stream_ctx {
/* 64-bit stream ring address, cycle state, and stream type */
- u32 stream_ring[2];
+ u64 stream_ring;
/* offset 0x14 - 0x1f reserved for HC internal use */
u32 reserved[2];
};
@@ -662,7 +673,7 @@ struct xhci_stream_ctx {
struct xhci_transfer_event {
/* 64-bit buffer address, or immediate data */
- u32 buffer[2];
+ u64 buffer;
u32 transfer_len;
/* This field is interpreted differently based on the type of TRB */
u32 flags;
@@ -744,7 +755,7 @@ struct xhci_transfer_event {
struct xhci_link_trb {
/* 64-bit segment pointer*/
- u32 segment_ptr[2];
+ u64 segment_ptr;
u32 intr_target;
u32 control;
};
@@ -755,7 +766,7 @@ struct xhci_link_trb {
/* Command completion event TRB */
struct xhci_event_cmd {
/* Pointer to command TRB, or the value passed by the event data trb */
- u32 cmd_trb[2];
+ u64 cmd_trb;
u32 status;
u32 flags;
};
@@ -848,8 +859,8 @@ union xhci_trb {
#define TRB_CONFIG_EP 12
/* Evaluate Context Command */
#define TRB_EVAL_CONTEXT 13
-/* Reset Transfer Ring Command */
-#define TRB_RESET_RING 14
+/* Reset Endpoint Command */
+#define TRB_RESET_EP 14
/* Stop Transfer Ring Command */
#define TRB_STOP_RING 15
/* Set Transfer Ring Dequeue Pointer Command */
@@ -929,6 +940,7 @@ struct xhci_ring {
unsigned int cancels_pending;
unsigned int state;
#define SET_DEQ_PENDING (1 << 0)
+#define EP_HALTED (1 << 1)
/* The TRB that was last reported in a stopped endpoint ring */
union xhci_trb *stopped_trb;
struct xhci_td *stopped_td;
@@ -940,9 +952,15 @@ struct xhci_ring {
u32 cycle_state;
};
+struct xhci_dequeue_state {
+ struct xhci_segment *new_deq_seg;
+ union xhci_trb *new_deq_ptr;
+ int new_cycle_state;
+};
+
struct xhci_erst_entry {
/* 64-bit event ring segment address */
- u32 seg_addr[2];
+ u64 seg_addr;
u32 seg_size;
/* Set to zero */
u32 rsvd;
@@ -957,6 +975,13 @@ struct xhci_erst {
unsigned int erst_size;
};
+struct xhci_scratchpad {
+ u64 *sp_array;
+ dma_addr_t sp_dma;
+ void **sp_buffers;
+ dma_addr_t *sp_dma_buffers;
+};
+
/*
* Each segment table entry is 4*32bits long. 1K seems like an ok size:
* (1K bytes * 8bytes/bit) / (4*32 bits) = 64 segment entries in the table,
@@ -1011,6 +1036,9 @@ struct xhci_hcd {
struct xhci_ring *cmd_ring;
struct xhci_ring *event_ring;
struct xhci_erst erst;
+ /* Scratchpad */
+ struct xhci_scratchpad *scratchpad;
+
/* slot enabling and address device helpers */
struct completion addr_dev;
int slot_id;
@@ -1071,13 +1099,43 @@ static inline unsigned int xhci_readl(const struct xhci_hcd *xhci,
static inline void xhci_writel(struct xhci_hcd *xhci,
const unsigned int val, __u32 __iomem *regs)
{
- if (!in_interrupt())
- xhci_dbg(xhci,
- "`MEM_WRITE_DWORD(3'b000, 32'h%p, 32'h%0x, 4'hf);\n",
- regs, val);
+ xhci_dbg(xhci,
+ "`MEM_WRITE_DWORD(3'b000, 32'h%p, 32'h%0x, 4'hf);\n",
+ regs, val);
writel(val, regs);
}
+/*
+ * Registers should always be accessed with double word or quad word accesses.
+ *
+ * Some xHCI implementations may support 64-bit address pointers. Registers
+ * with 64-bit address pointers should be written to with dword accesses by
+ * writing the low dword first (ptr[0]), then the high dword (ptr[1]) second.
+ * xHCI implementations that do not support 64-bit address pointers will ignore
+ * the high dword, and write order is irrelevant.
+ */
+static inline u64 xhci_read_64(const struct xhci_hcd *xhci,
+ __u64 __iomem *regs)
+{
+ __u32 __iomem *ptr = (__u32 __iomem *) regs;
+ u64 val_lo = readl(ptr);
+ u64 val_hi = readl(ptr + 1);
+ return val_lo + (val_hi << 32);
+}
+static inline void xhci_write_64(struct xhci_hcd *xhci,
+ const u64 val, __u64 __iomem *regs)
+{
+ __u32 __iomem *ptr = (__u32 __iomem *) regs;
+ u32 val_lo = lower_32_bits(val);
+ u32 val_hi = upper_32_bits(val);
+
+ xhci_dbg(xhci,
+ "`MEM_WRITE_DWORD(3'b000, 64'h%p, 64'h%0lx, 4'hf);\n",
+ regs, (long unsigned int) val);
+ writel(val_lo, ptr);
+ writel(val_hi, ptr + 1);
+}
+
/* xHCI debugging */
void xhci_print_ir_set(struct xhci_hcd *xhci, struct xhci_intr_reg *ir_set, int set_num);
void xhci_print_registers(struct xhci_hcd *xhci);
@@ -1090,7 +1148,7 @@ void xhci_debug_ring(struct xhci_hcd *xhci, struct xhci_ring *ring);
void xhci_dbg_erst(struct xhci_hcd *xhci, struct xhci_erst *erst);
void xhci_dbg_cmd_ptrs(struct xhci_hcd *xhci);
void xhci_dbg_ring_ptrs(struct xhci_hcd *xhci, struct xhci_ring *ring);
-void xhci_dbg_ctx(struct xhci_hcd *xhci, struct xhci_device_control *ctx, dma_addr_t dma, unsigned int last_ep);
+void xhci_dbg_ctx(struct xhci_hcd *xhci, struct xhci_container_ctx *ctx, unsigned int last_ep);
/* xHCI memory managment */
void xhci_mem_cleanup(struct xhci_hcd *xhci);
@@ -1128,6 +1186,7 @@ int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags);
int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status);
int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev, struct usb_host_endpoint *ep);
int xhci_drop_endpoint(struct usb_hcd *hcd, struct usb_device *udev, struct usb_host_endpoint *ep);
+void xhci_endpoint_reset(struct usb_hcd *hcd, struct usb_host_endpoint *ep);
int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev);
void xhci_reset_bandwidth(struct usb_hcd *hcd, struct usb_device *udev);
@@ -1148,10 +1207,23 @@ int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags, struct urb *urb,
int slot_id, unsigned int ep_index);
int xhci_queue_configure_endpoint(struct xhci_hcd *xhci, dma_addr_t in_ctx_ptr,
u32 slot_id);
+int xhci_queue_reset_ep(struct xhci_hcd *xhci, int slot_id,
+ unsigned int ep_index);
+void xhci_find_new_dequeue_state(struct xhci_hcd *xhci,
+ unsigned int slot_id, unsigned int ep_index,
+ struct xhci_td *cur_td, struct xhci_dequeue_state *state);
+void xhci_queue_new_dequeue_state(struct xhci_hcd *xhci,
+ struct xhci_ring *ep_ring, unsigned int slot_id,
+ unsigned int ep_index, struct xhci_dequeue_state *deq_state);
/* xHCI roothub code */
int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, u16 wIndex,
char *buf, u16 wLength);
int xhci_hub_status_data(struct usb_hcd *hcd, char *buf);
+/* xHCI contexts */
+struct xhci_input_control_ctx *xhci_get_input_control_ctx(struct xhci_hcd *xhci, struct xhci_container_ctx *ctx);
+struct xhci_slot_ctx *xhci_get_slot_ctx(struct xhci_hcd *xhci, struct xhci_container_ctx *ctx);
+struct xhci_ep_ctx *xhci_get_ep_ctx(struct xhci_hcd *xhci, struct xhci_container_ctx *ctx, unsigned int ep_index);
+
#endif /* __LINUX_XHCI_HCD_H */