summaryrefslogtreecommitdiff
path: root/drivers/usb/host/xhci.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/host/xhci.c')
-rw-r--r--drivers/usb/host/xhci.c567
1 files changed, 401 insertions, 166 deletions
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 0a8cf6c17f82..02c9bfe21ae2 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -8,6 +8,7 @@
* Some code borrowed from the Linux EHCI driver.
*/
+#include <linux/jiffies.h>
#include <linux/pci.h>
#include <linux/iommu.h>
#include <linux/iopoll.h>
@@ -16,8 +17,10 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/slab.h>
+#include <linux/string_choices.h>
#include <linux/dmi.h>
#include <linux/dma-mapping.h>
+#include <linux/usb/xhci-sideband.h>
#include "xhci.h"
#include "xhci-trace.h"
@@ -38,17 +41,30 @@ static unsigned long long quirks;
module_param(quirks, ullong, S_IRUGO);
MODULE_PARM_DESC(quirks, "Bit flags for quirks to be enabled as default");
+void xhci_portsc_writel(struct xhci_port *port, u32 val)
+{
+ trace_xhci_portsc_writel(port, val);
+ writel(val, &port->port_reg->portsc);
+}
+EXPORT_SYMBOL_GPL(xhci_portsc_writel);
+
+u32 xhci_portsc_readl(struct xhci_port *port)
+{
+ return readl(&port->port_reg->portsc);
+}
+EXPORT_SYMBOL_GPL(xhci_portsc_readl);
+
static bool td_on_ring(struct xhci_td *td, struct xhci_ring *ring)
{
- struct xhci_segment *seg = ring->first_seg;
+ struct xhci_segment *seg;
if (!td || !td->start_seg)
return false;
- do {
+
+ xhci_for_each_ring_seg(ring->first_seg, seg) {
if (seg == td->start_seg)
return true;
- seg = seg->next;
- } while (seg && seg != ring->first_seg);
+ }
return false;
}
@@ -82,29 +98,6 @@ int xhci_handshake(void __iomem *ptr, u32 mask, u32 done, u64 timeout_us)
}
/*
- * xhci_handshake_check_state - same as xhci_handshake but takes an additional
- * exit_state parameter, and bails out with an error immediately when xhc_state
- * has exit_state flag set.
- */
-int xhci_handshake_check_state(struct xhci_hcd *xhci, void __iomem *ptr,
- u32 mask, u32 done, int usec, unsigned int exit_state)
-{
- u32 result;
- int ret;
-
- ret = readl_poll_timeout_atomic(ptr, result,
- (result & mask) == done ||
- result == U32_MAX ||
- xhci->xhc_state & exit_state,
- 1, usec);
-
- if (result == U32_MAX || xhci->xhc_state & exit_state)
- return -ENODEV;
-
- return ret;
-}
-
-/*
* Disable interrupts and begin the xHCI halting process.
*/
void xhci_quiesce(struct xhci_hcd *xhci)
@@ -141,7 +134,8 @@ int xhci_halt(struct xhci_hcd *xhci)
ret = xhci_handshake(&xhci->op_regs->status,
STS_HALT, STS_HALT, XHCI_MAX_HALT_USEC);
if (ret) {
- xhci_warn(xhci, "Host halt failed, %d\n", ret);
+ if (!(xhci->xhc_state & XHCI_STATE_DYING))
+ xhci_warn(xhci, "Host halt failed, %d\n", ret);
return ret;
}
@@ -200,7 +194,8 @@ int xhci_reset(struct xhci_hcd *xhci, u64 timeout_us)
state = readl(&xhci->op_regs->status);
if (state == ~(u32)0) {
- xhci_warn(xhci, "Host not accessible, reset failed.\n");
+ if (!(xhci->xhc_state & XHCI_STATE_DYING))
+ xhci_warn(xhci, "Host not accessible, reset failed.\n");
return -ENODEV;
}
@@ -224,8 +219,7 @@ int xhci_reset(struct xhci_hcd *xhci, u64 timeout_us)
if (xhci->quirks & XHCI_INTEL_HOST)
udelay(1000);
- ret = xhci_handshake_check_state(xhci, &xhci->op_regs->command,
- CMD_RESET, 0, timeout_us, XHCI_STATE_REMOVING);
+ ret = xhci_handshake(&xhci->op_regs->command, CMD_RESET, 0, timeout_us);
if (ret)
return ret;
@@ -256,7 +250,6 @@ static void xhci_zero_64b_regs(struct xhci_hcd *xhci)
struct iommu_domain *domain;
int err, i;
u64 val;
- u32 intrs;
/*
* Some Renesas controllers get into a weird state if they are
@@ -297,10 +290,7 @@ static void xhci_zero_64b_regs(struct xhci_hcd *xhci)
if (upper_32_bits(val))
xhci_write_64(xhci, 0, &xhci->op_regs->cmd_ring);
- intrs = min_t(u32, HCS_MAX_INTRS(xhci->hcs_params1),
- ARRAY_SIZE(xhci->run_regs->ir_set));
-
- for (i = 0; i < intrs; i++) {
+ for (i = 0; i < xhci->max_interrupters; i++) {
struct xhci_intr_reg __iomem *ir;
ir = &xhci->run_regs->ir_set[i];
@@ -320,45 +310,58 @@ static void xhci_zero_64b_regs(struct xhci_hcd *xhci)
xhci_info(xhci, "Fault detected\n");
}
-static int xhci_enable_interrupter(struct xhci_interrupter *ir)
+int xhci_enable_interrupter(struct xhci_interrupter *ir)
{
u32 iman;
if (!ir || !ir->ir_set)
return -EINVAL;
- iman = readl(&ir->ir_set->irq_pending);
- writel(ER_IRQ_ENABLE(iman), &ir->ir_set->irq_pending);
+ iman = readl(&ir->ir_set->iman);
+ iman &= ~IMAN_IP;
+ iman |= IMAN_IE;
+ writel(iman, &ir->ir_set->iman);
+ /* Read operation to guarantee the write has been flushed from posted buffers */
+ readl(&ir->ir_set->iman);
return 0;
}
-static int xhci_disable_interrupter(struct xhci_interrupter *ir)
+int xhci_disable_interrupter(struct xhci_hcd *xhci, struct xhci_interrupter *ir)
{
u32 iman;
if (!ir || !ir->ir_set)
return -EINVAL;
- iman = readl(&ir->ir_set->irq_pending);
- writel(ER_IRQ_DISABLE(iman), &ir->ir_set->irq_pending);
+ iman = readl(&ir->ir_set->iman);
+ iman &= ~IMAN_IP;
+ iman &= ~IMAN_IE;
+ writel(iman, &ir->ir_set->iman);
+
+ iman = readl(&ir->ir_set->iman);
+ if (iman & IMAN_IP)
+ xhci_dbg(xhci, "%s: Interrupt pending\n", __func__);
return 0;
}
/* interrupt moderation interval imod_interval in nanoseconds */
-static int xhci_set_interrupter_moderation(struct xhci_interrupter *ir,
- u32 imod_interval)
+int xhci_set_interrupter_moderation(struct xhci_interrupter *ir,
+ u32 imod_interval)
{
u32 imod;
- if (!ir || !ir->ir_set || imod_interval > U16_MAX * 250)
+ if (!ir || !ir->ir_set)
return -EINVAL;
- imod = readl(&ir->ir_set->irq_control);
- imod &= ~ER_IRQ_INTERVAL_MASK;
- imod |= (imod_interval / 250) & ER_IRQ_INTERVAL_MASK;
- writel(imod, &ir->ir_set->irq_control);
+ /* IMODI value in IMOD register is in 250ns increments */
+ imod_interval = umin(imod_interval / 250, IMODI_MASK);
+
+ imod = readl(&ir->ir_set->imod);
+ imod &= ~IMODI_MASK;
+ imod |= imod_interval;
+ writel(imod, &ir->ir_set->imod);
return 0;
}
@@ -371,7 +374,7 @@ static void compliance_mode_recovery(struct timer_list *t)
u32 temp;
int i;
- xhci = from_timer(xhci, t, comp_mode_recovery_timer);
+ xhci = timer_container_of(xhci, t, comp_mode_recovery_timer);
rhub = &xhci->usb3_rhub;
hcd = rhub->hcd;
@@ -379,7 +382,7 @@ static void compliance_mode_recovery(struct timer_list *t)
return;
for (i = 0; i < rhub->num_ports; i++) {
- temp = readl(rhub->ports[i]->addr);
+ temp = xhci_portsc_readl(rhub->ports[i]);
if ((temp & PORT_PLS_MASK) == USB_SS_PORT_LS_COMP_MOD) {
/*
* Compliance Mode Detected. Letting USB Core
@@ -458,6 +461,80 @@ static int xhci_all_ports_seen_u0(struct xhci_hcd *xhci)
return (xhci->port_status_u0 == ((1 << xhci->usb3_rhub.num_ports) - 1));
}
+static void xhci_hcd_page_size(struct xhci_hcd *xhci)
+{
+ u32 page_size;
+
+ page_size = readl(&xhci->op_regs->page_size) & XHCI_PAGE_SIZE_MASK;
+ if (!is_power_of_2(page_size)) {
+ xhci_warn(xhci, "Invalid page size register = 0x%x\n", page_size);
+ /* Fallback to 4K page size, since that's common */
+ page_size = 1;
+ }
+
+ xhci->page_size = page_size << 12;
+ xhci_dbg_trace(xhci, trace_xhci_dbg_init, "HCD page size set to %iK",
+ xhci->page_size >> 10);
+}
+
+static void xhci_enable_max_dev_slots(struct xhci_hcd *xhci)
+{
+ u32 config_reg;
+
+ xhci_dbg_trace(xhci, trace_xhci_dbg_init, "xHC can handle at most %d device slots",
+ xhci->max_slots);
+
+ config_reg = readl(&xhci->op_regs->config_reg);
+ config_reg &= ~HCS_SLOTS_MASK;
+ config_reg |= xhci->max_slots;
+
+ xhci_dbg_trace(xhci, trace_xhci_dbg_init, "Setting Max device slots reg = 0x%x",
+ config_reg);
+ writel(config_reg, &xhci->op_regs->config_reg);
+}
+
+static void xhci_set_cmd_ring_deq(struct xhci_hcd *xhci)
+{
+ dma_addr_t deq_dma;
+ u64 crcr;
+
+ deq_dma = xhci_trb_virt_to_dma(xhci->cmd_ring->deq_seg, xhci->cmd_ring->dequeue);
+ deq_dma &= CMD_RING_PTR_MASK;
+
+ crcr = xhci_read_64(xhci, &xhci->op_regs->cmd_ring);
+ crcr &= ~CMD_RING_PTR_MASK;
+ crcr |= deq_dma;
+
+ crcr &= ~CMD_RING_CYCLE;
+ crcr |= xhci->cmd_ring->cycle_state;
+
+ xhci_dbg_trace(xhci, trace_xhci_dbg_init, "Setting command ring address to 0x%llx", crcr);
+ xhci_write_64(xhci, crcr, &xhci->op_regs->cmd_ring);
+}
+
+static void xhci_set_doorbell_ptr(struct xhci_hcd *xhci)
+{
+ u32 offset;
+
+ offset = readl(&xhci->cap_regs->db_off) & DBOFF_MASK;
+ xhci->dba = (void __iomem *)xhci->cap_regs + offset;
+ xhci_dbg_trace(xhci, trace_xhci_dbg_init,
+ "Doorbell array is located at offset 0x%x from cap regs base addr", offset);
+}
+
+/*
+ * Enable USB 3.0 device notifications for function remote wake, which is necessary
+ * for allowing USB 3.0 devices to do remote wakeup from U3 (device suspend).
+ */
+static void xhci_set_dev_notifications(struct xhci_hcd *xhci)
+{
+ u32 dev_notf;
+
+ dev_notf = readl(&xhci->op_regs->dev_notification);
+ dev_notf &= ~DEV_NOTE_MASK;
+ dev_notf |= DEV_NOTE_FWAKE;
+ writel(dev_notf, &xhci->op_regs->dev_notification);
+}
/*
* Initialize memory for HCD and xHC (one-time init).
@@ -471,18 +548,37 @@ static int xhci_init(struct usb_hcd *hcd)
struct xhci_hcd *xhci = hcd_to_xhci(hcd);
int retval;
- xhci_dbg_trace(xhci, trace_xhci_dbg_init, "xhci_init");
+ xhci_dbg_trace(xhci, trace_xhci_dbg_init, "Starting %s", __func__);
spin_lock_init(&xhci->lock);
- if (xhci->hci_version == 0x95 && link_quirk) {
- xhci_dbg_trace(xhci, trace_xhci_dbg_quirks,
- "QUIRK: Not clearing Link TRB chain bits.");
- xhci->quirks |= XHCI_LINK_TRB_QUIRK;
- } else {
- xhci_dbg_trace(xhci, trace_xhci_dbg_init,
- "xHCI doesn't need link TRB QUIRK");
- }
+
+ INIT_LIST_HEAD(&xhci->cmd_list);
+ INIT_DELAYED_WORK(&xhci->cmd_timer, xhci_handle_command_timeout);
+ init_completion(&xhci->cmd_ring_stop_completion);
+ xhci_hcd_page_size(xhci);
+ memset(xhci->devs, 0, MAX_HC_SLOTS * sizeof(*xhci->devs));
+
retval = xhci_mem_init(xhci, GFP_KERNEL);
- xhci_dbg_trace(xhci, trace_xhci_dbg_init, "Finished xhci_init");
+ if (retval)
+ return retval;
+
+ /* Set the Number of Device Slots Enabled to the maximum supported value */
+ xhci_enable_max_dev_slots(xhci);
+
+ /* Set the address in the Command Ring Control register */
+ xhci_set_cmd_ring_deq(xhci);
+
+ /* Set Device Context Base Address Array pointer */
+ xhci_write_64(xhci, xhci->dcbaa->dma, &xhci->op_regs->dcbaa_ptr);
+
+ /* Set Doorbell array pointer */
+ xhci_set_doorbell_ptr(xhci);
+
+ /* Set USB 3.0 device notifications for function remote wake */
+ xhci_set_dev_notifications(xhci);
+
+ /* Initialize the Primary interrupter */
+ xhci_add_interrupter(xhci, 0);
+ xhci->interrupters[0]->isoc_bei_interval = AVOID_BEI_INTERVAL_MAX;
/* Initializing Compliance Mode Recovery Data If Needed */
if (xhci_compliance_mode_recovery_timer_quirk_check()) {
@@ -490,7 +586,8 @@ static int xhci_init(struct usb_hcd *hcd)
compliance_mode_recovery_timer_init(xhci);
}
- return retval;
+ xhci_dbg_trace(xhci, trace_xhci_dbg_init, "Finished %s", __func__);
+ return 0;
}
/*-------------------------------------------------------------------------*/
@@ -632,7 +729,7 @@ void xhci_stop(struct usb_hcd *hcd)
/* Deleting Compliance Mode Recovery Timer */
if ((xhci->quirks & XHCI_COMP_MODE_QUIRK) &&
(!(xhci_all_ports_seen_u0(xhci)))) {
- del_timer_sync(&xhci->comp_mode_recovery_timer);
+ timer_delete_sync(&xhci->comp_mode_recovery_timer);
xhci_dbg_trace(xhci, trace_xhci_dbg_quirks,
"%s: compliance mode recovery timer deleted",
__func__);
@@ -645,7 +742,7 @@ void xhci_stop(struct usb_hcd *hcd)
"// Disabling event ring interrupts");
temp = readl(&xhci->op_regs->status);
writel((temp & ~0x1fff) | STS_EINT, &xhci->op_regs->status);
- xhci_disable_interrupter(ir);
+ xhci_disable_interrupter(xhci, ir);
xhci_dbg_trace(xhci, trace_xhci_dbg_init, "cleaning up memory");
xhci_mem_cleanup(xhci);
@@ -677,11 +774,11 @@ void xhci_shutdown(struct usb_hcd *hcd)
xhci_dbg(xhci, "%s: stopping usb%d port polling.\n",
__func__, hcd->self.busnum);
clear_bit(HCD_FLAG_POLL_RH, &hcd->flags);
- del_timer_sync(&hcd->rh_timer);
+ timer_delete_sync(&hcd->rh_timer);
if (xhci->shared_hcd) {
clear_bit(HCD_FLAG_POLL_RH, &xhci->shared_hcd->flags);
- del_timer_sync(&xhci->shared_hcd->rh_timer);
+ timer_delete_sync(&xhci->shared_hcd->rh_timer);
}
spin_lock_irq(&xhci->lock);
@@ -724,8 +821,8 @@ static void xhci_save_registers(struct xhci_hcd *xhci)
ir->s3_erst_size = readl(&ir->ir_set->erst_size);
ir->s3_erst_base = xhci_read_64(xhci, &ir->ir_set->erst_base);
ir->s3_erst_dequeue = xhci_read_64(xhci, &ir->ir_set->erst_dequeue);
- ir->s3_irq_pending = readl(&ir->ir_set->irq_pending);
- ir->s3_irq_control = readl(&ir->ir_set->irq_control);
+ ir->s3_iman = readl(&ir->ir_set->iman);
+ ir->s3_imod = readl(&ir->ir_set->imod);
}
}
@@ -748,28 +845,11 @@ static void xhci_restore_registers(struct xhci_hcd *xhci)
writel(ir->s3_erst_size, &ir->ir_set->erst_size);
xhci_write_64(xhci, ir->s3_erst_base, &ir->ir_set->erst_base);
xhci_write_64(xhci, ir->s3_erst_dequeue, &ir->ir_set->erst_dequeue);
- writel(ir->s3_irq_pending, &ir->ir_set->irq_pending);
- writel(ir->s3_irq_control, &ir->ir_set->irq_control);
+ writel(ir->s3_iman, &ir->ir_set->iman);
+ writel(ir->s3_imod, &ir->ir_set->imod);
}
}
-static void xhci_set_cmd_ring_deq(struct xhci_hcd *xhci)
-{
- u64 val_64;
-
- /* step 2: initialize command ring buffer */
- val_64 = xhci_read_64(xhci, &xhci->op_regs->cmd_ring);
- val_64 = (val_64 & (u64) CMD_RING_RSVD_BITS) |
- (xhci_trb_virt_to_dma(xhci->cmd_ring->deq_seg,
- xhci->cmd_ring->dequeue) &
- (u64) ~CMD_RING_RSVD_BITS) |
- xhci->cmd_ring->cycle_state;
- xhci_dbg_trace(xhci, trace_xhci_dbg_init,
- "// Setting command ring address to 0x%llx",
- (long unsigned long) val_64);
- xhci_write_64(xhci, val_64, &xhci->op_regs->cmd_ring);
-}
-
/*
* The whole command ring must be cleared to zero when we suspend the host.
*
@@ -785,16 +865,14 @@ static void xhci_clear_command_ring(struct xhci_hcd *xhci)
struct xhci_segment *seg;
ring = xhci->cmd_ring;
- seg = ring->deq_seg;
- do {
- memset(seg->trbs, 0,
- sizeof(union xhci_trb) * (TRBS_PER_SEGMENT - 1));
- seg->trbs[TRBS_PER_SEGMENT - 1].link.control &=
- cpu_to_le32(~TRB_CYCLE);
- seg = seg->next;
- } while (seg != ring->deq_seg);
-
- xhci_initialize_ring_info(ring, 1);
+ xhci_for_each_ring_seg(ring->first_seg, seg) {
+ /* erase all TRBs before the link */
+ memset(seg->trbs, 0, sizeof(union xhci_trb) * (TRBS_PER_SEGMENT - 1));
+ /* clear link cycle bit */
+ seg->trbs[TRBS_PER_SEGMENT - 1].link.control &= cpu_to_le32(~TRB_CYCLE);
+ }
+
+ xhci_initialize_ring_info(ring);
/*
* Reset the hardware dequeue pointer.
* Yes, this will need to be re-written after resume, but we're paranoid
@@ -825,7 +903,7 @@ static void xhci_disable_hub_port_wake(struct xhci_hcd *xhci,
spin_lock_irqsave(&xhci->lock, flags);
for (i = 0; i < rhub->num_ports; i++) {
- portsc = readl(rhub->ports[i]->addr);
+ portsc = xhci_portsc_readl(rhub->ports[i]);
t1 = xhci_port_state_to_neutral(portsc);
t2 = t1;
@@ -838,7 +916,7 @@ static void xhci_disable_hub_port_wake(struct xhci_hcd *xhci,
t2 |= PORT_CSC;
if (t1 != t2) {
- writel(t2, rhub->ports[i]->addr);
+ xhci_portsc_writel(rhub->ports[i], t2);
xhci_dbg(xhci, "config port %d-%d wake bits, portsc: 0x%x, write: 0x%x\n",
rhub->hcd->self.busnum, i + 1, portsc, t2);
}
@@ -865,7 +943,7 @@ static bool xhci_pending_portevent(struct xhci_hcd *xhci)
port_index = xhci->usb2_rhub.num_ports;
ports = xhci->usb2_rhub.ports;
while (port_index--) {
- portsc = readl(ports[port_index]->addr);
+ portsc = xhci_portsc_readl(ports[port_index]);
if (portsc & PORT_CHANGE_MASK ||
(portsc & PORT_PLS_MASK) == XDEV_RESUME)
return true;
@@ -873,7 +951,7 @@ static bool xhci_pending_portevent(struct xhci_hcd *xhci)
port_index = xhci->usb3_rhub.num_ports;
ports = xhci->usb3_rhub.ports;
while (port_index--) {
- portsc = readl(ports[port_index]->addr);
+ portsc = xhci_portsc_readl(ports[port_index]);
if (portsc & (PORT_CHANGE_MASK | PORT_CAS) ||
(portsc & PORT_PLS_MASK) == XDEV_RESUME)
return true;
@@ -915,10 +993,10 @@ int xhci_suspend(struct xhci_hcd *xhci, bool do_wakeup)
xhci_dbg(xhci, "%s: stopping usb%d port polling.\n",
__func__, hcd->self.busnum);
clear_bit(HCD_FLAG_POLL_RH, &hcd->flags);
- del_timer_sync(&hcd->rh_timer);
+ timer_delete_sync(&hcd->rh_timer);
if (xhci->shared_hcd) {
clear_bit(HCD_FLAG_POLL_RH, &xhci->shared_hcd->flags);
- del_timer_sync(&xhci->shared_hcd->rh_timer);
+ timer_delete_sync(&xhci->shared_hcd->rh_timer);
}
if (xhci->quirks & XHCI_SUSPEND_DELAY)
@@ -985,7 +1063,7 @@ int xhci_suspend(struct xhci_hcd *xhci, bool do_wakeup)
*/
if ((xhci->quirks & XHCI_COMP_MODE_QUIRK) &&
(!(xhci_all_ports_seen_u0(xhci)))) {
- del_timer_sync(&xhci->comp_mode_recovery_timer);
+ timer_delete_sync(&xhci->comp_mode_recovery_timer);
xhci_dbg_trace(xhci, trace_xhci_dbg_quirks,
"%s: compliance mode recovery timer deleted",
__func__);
@@ -1001,16 +1079,14 @@ EXPORT_SYMBOL_GPL(xhci_suspend);
* This is called when the machine transition from S3/S4 mode.
*
*/
-int xhci_resume(struct xhci_hcd *xhci, pm_message_t msg)
+int xhci_resume(struct xhci_hcd *xhci, bool power_lost, bool is_auto_resume)
{
- bool hibernated = (msg.event == PM_EVENT_RESTORE);
u32 command, temp = 0;
struct usb_hcd *hcd = xhci_to_hcd(xhci);
int retval = 0;
bool comp_timer_running = false;
bool pending_portevent = false;
bool suspended_usb3_devs = false;
- bool reinit_xhc = false;
if (!hcd->state)
return 0;
@@ -1029,10 +1105,10 @@ int xhci_resume(struct xhci_hcd *xhci, pm_message_t msg)
spin_lock_irq(&xhci->lock);
- if (hibernated || xhci->quirks & XHCI_RESET_ON_RESUME || xhci->broken_suspend)
- reinit_xhc = true;
+ if (xhci->quirks & XHCI_RESET_ON_RESUME || xhci->broken_suspend)
+ power_lost = true;
- if (!reinit_xhc) {
+ if (!power_lost) {
/*
* Some controllers might lose power during suspend, so wait
* for controller not ready bit to clear, just as in xHC init.
@@ -1072,15 +1148,15 @@ int xhci_resume(struct xhci_hcd *xhci, pm_message_t msg)
/* re-initialize the HC on Restore Error, or Host Controller Error */
if ((temp & (STS_SRE | STS_HCE)) &&
!(xhci->xhc_state & XHCI_STATE_REMOVING)) {
- reinit_xhc = true;
- if (!xhci->broken_suspend)
+ if (!power_lost)
xhci_warn(xhci, "xHC error in resume, USBSTS 0x%x, Reinit\n", temp);
+ power_lost = true;
}
- if (reinit_xhc) {
+ if (power_lost) {
if ((xhci->quirks & XHCI_COMP_MODE_QUIRK) &&
!(xhci_all_ports_seen_u0(xhci))) {
- del_timer_sync(&xhci->comp_mode_recovery_timer);
+ timer_delete_sync(&xhci->comp_mode_recovery_timer);
xhci_dbg_trace(xhci, trace_xhci_dbg_quirks,
"Compliance Mode Recovery Timer deleted!");
}
@@ -1093,7 +1169,10 @@ int xhci_resume(struct xhci_hcd *xhci, pm_message_t msg)
xhci_dbg(xhci, "Stop HCD\n");
xhci_halt(xhci);
xhci_zero_64b_regs(xhci);
- retval = xhci_reset(xhci, XHCI_RESET_LONG_USEC);
+ if (xhci->xhc_state & XHCI_STATE_REMOVING)
+ retval = -ENODEV;
+ else
+ retval = xhci_reset(xhci, XHCI_RESET_LONG_USEC);
spin_unlock_irq(&xhci->lock);
if (retval)
return retval;
@@ -1101,7 +1180,7 @@ int xhci_resume(struct xhci_hcd *xhci, pm_message_t msg)
xhci_dbg(xhci, "// Disabling event ring interrupts\n");
temp = readl(&xhci->op_regs->status);
writel((temp & ~0x1fff) | STS_EINT, &xhci->op_regs->status);
- xhci_disable_interrupter(xhci->interrupters[0]);
+ xhci_disable_interrupter(xhci, xhci->interrupters[0]);
xhci_dbg(xhci, "cleaning up memory\n");
xhci_mem_cleanup(xhci);
@@ -1175,8 +1254,7 @@ int xhci_resume(struct xhci_hcd *xhci, pm_message_t msg)
pending_portevent = xhci_pending_portevent(xhci);
- if (suspended_usb3_devs && !pending_portevent &&
- msg.event == PM_EVENT_AUTO_RESUME) {
+ if (suspended_usb3_devs && !pending_portevent && is_auto_resume) {
msleep(120);
pending_portevent = xhci_pending_portevent(xhci);
}
@@ -1265,7 +1343,7 @@ static bool xhci_urb_temp_buffer_required(struct usb_hcd *hcd,
struct scatterlist *tail_sg;
tail_sg = urb->sg;
- max_pkt = usb_endpoint_maxp(&urb->ep->desc);
+ max_pkt = xhci_usb_endpoint_maxp(urb->dev, urb->ep);
if (!urb->num_sgs)
return ret;
@@ -1369,6 +1447,7 @@ static void xhci_unmap_urb_for_dma(struct usb_hcd *hcd, struct urb *urb)
* xhci_get_endpoint_index - Used for passing endpoint bitmasks between the core and
* HCDs. Find the index for an endpoint given its descriptor. Use the return
* value to right shift 1 for the bitmask.
+ * @desc: USB endpoint descriptor to determine index for
*
* Index = (epnum * 2) + direction - 1,
* where direction = 0 for OUT, 1 for IN.
@@ -1756,7 +1835,7 @@ static int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
urb->ep->desc.bEndpointAddress,
(unsigned long long) xhci_trb_virt_to_dma(
urb_priv->td[i].start_seg,
- urb_priv->td[i].first_trb));
+ urb_priv->td[i].start_trb));
for (; i < urb_priv->num_tds; i++) {
td = &urb_priv->td[i];
@@ -1768,15 +1847,27 @@ static int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
}
}
- /* Queue a stop endpoint command, but only if this is
- * the first cancellation to be handled.
- */
- if (!(ep->ep_state & EP_STOP_CMD_PENDING)) {
+ /* These completion handlers will sort out cancelled TDs for us */
+ if (ep->ep_state & (EP_STOP_CMD_PENDING | EP_HALTED | SET_DEQ_PENDING)) {
+ xhci_dbg(xhci, "Not queuing Stop Endpoint on slot %d ep %d in state 0x%x\n",
+ urb->dev->slot_id, ep_index, ep->ep_state);
+ goto done;
+ }
+
+ /* In this case no commands are pending but the endpoint is stopped */
+ if (ep->ep_state & EP_CLEARING_TT) {
+ /* and cancelled TDs can be given back right away */
+ xhci_dbg(xhci, "Invalidating TDs instantly on slot %d ep %d in state 0x%x\n",
+ urb->dev->slot_id, ep_index, ep->ep_state);
+ xhci_process_cancelled_tds(ep);
+ } else {
+ /* Otherwise, queue a new Stop Endpoint command */
command = xhci_alloc_command(xhci, false, GFP_ATOMIC);
if (!command) {
ret = -ENOMEM;
goto done;
}
+ ep->stop_time = jiffies;
ep->ep_state |= EP_STOP_CMD_PENDING;
xhci_queue_stop_endpoint(xhci, command, urb->dev->slot_id,
ep_index, 0);
@@ -2794,6 +2885,65 @@ static int xhci_reserve_bandwidth(struct xhci_hcd *xhci,
return -ENOMEM;
}
+/*
+ * Synchronous XHCI stop endpoint helper. Issues the stop endpoint command and
+ * waits for the command completion before returning. This does not call
+ * xhci_handle_cmd_stop_ep(), which has additional handling for 'context error'
+ * cases, along with transfer ring cleanup.
+ *
+ * xhci_stop_endpoint_sync() is intended to be utilized by clients that manage
+ * their own transfer ring, such as offload situations.
+ */
+int xhci_stop_endpoint_sync(struct xhci_hcd *xhci, struct xhci_virt_ep *ep, int suspend,
+ gfp_t gfp_flags)
+{
+ struct xhci_command *command;
+ unsigned long flags;
+ int ret;
+
+ command = xhci_alloc_command(xhci, true, gfp_flags);
+ if (!command)
+ return -ENOMEM;
+
+ spin_lock_irqsave(&xhci->lock, flags);
+ ret = xhci_queue_stop_endpoint(xhci, command, ep->vdev->slot_id,
+ ep->ep_index, suspend);
+ if (ret < 0) {
+ spin_unlock_irqrestore(&xhci->lock, flags);
+ goto out;
+ }
+
+ xhci_ring_cmd_db(xhci);
+ spin_unlock_irqrestore(&xhci->lock, flags);
+
+ wait_for_completion(command->completion);
+
+ /* No handling for COMP_CONTEXT_STATE_ERROR done at command completion*/
+ if (command->status == COMP_COMMAND_ABORTED ||
+ command->status == COMP_COMMAND_RING_STOPPED) {
+ xhci_warn(xhci, "Timeout while waiting for stop endpoint command\n");
+ ret = -ETIME;
+ }
+out:
+ xhci_free_command(xhci, command);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(xhci_stop_endpoint_sync);
+
+/*
+ * xhci_usb_endpoint_maxp - get endpoint max packet size
+ * @host_ep: USB host endpoint to be checked
+ *
+ * Returns max packet from the correct descriptor
+ */
+int xhci_usb_endpoint_maxp(struct usb_device *udev,
+ struct usb_host_endpoint *host_ep)
+{
+ if (usb_endpoint_is_hs_isoc_double(udev, host_ep))
+ return le16_to_cpu(host_ep->eusb2_isoc_ep_comp.wMaxPacketSize);
+ return usb_endpoint_maxp(&host_ep->desc);
+}
/* Issue a configure endpoint command or evaluate context command
* and wait for it to finish.
@@ -2837,7 +2987,7 @@ static int xhci_configure_endpoint(struct xhci_hcd *xhci,
xhci->num_active_eps);
return -ENOMEM;
}
- if ((xhci->quirks & XHCI_SW_BW_CHECKING) &&
+ if ((xhci->quirks & XHCI_SW_BW_CHECKING) && !ctx_change &&
xhci_reserve_bandwidth(xhci, virt_dev, command->in_ctx)) {
if ((xhci->quirks & XHCI_EP_LIMIT_QUIRK))
xhci_free_host_resources(xhci, ctrl_ctx);
@@ -3042,6 +3192,42 @@ void xhci_reset_bandwidth(struct usb_hcd *hcd, struct usb_device *udev)
}
EXPORT_SYMBOL_GPL(xhci_reset_bandwidth);
+/* Get the available bandwidth of the ports under the xhci roothub */
+int xhci_get_port_bandwidth(struct xhci_hcd *xhci, struct xhci_container_ctx *ctx,
+ u8 dev_speed)
+{
+ struct xhci_command *cmd;
+ unsigned long flags;
+ int ret;
+
+ if (!ctx || !xhci)
+ return -EINVAL;
+
+ cmd = xhci_alloc_command(xhci, true, GFP_KERNEL);
+ if (!cmd)
+ return -ENOMEM;
+
+ cmd->in_ctx = ctx;
+
+ /* get xhci port bandwidth, refer to xhci rev1_2 protocol 4.6.15 */
+ spin_lock_irqsave(&xhci->lock, flags);
+
+ ret = xhci_queue_get_port_bw(xhci, cmd, ctx->dma, dev_speed, 0);
+ if (ret) {
+ spin_unlock_irqrestore(&xhci->lock, flags);
+ goto err_out;
+ }
+ xhci_ring_cmd_db(xhci);
+ spin_unlock_irqrestore(&xhci->lock, flags);
+
+ wait_for_completion(cmd->completion);
+err_out:
+ kfree(cmd->completion);
+ kfree(cmd);
+
+ return ret;
+}
+
static void xhci_setup_input_ctx_for_config_ep(struct xhci_hcd *xhci,
struct xhci_container_ctx *in_ctx,
struct xhci_container_ctx *out_ctx,
@@ -3692,6 +3878,8 @@ void xhci_free_device_endpoint_resources(struct xhci_hcd *xhci,
xhci->num_active_eps);
}
+static void xhci_free_dev(struct usb_hcd *hcd, struct usb_device *udev);
+
/*
* This submits a Reset Device Command, which will set the device state to 0,
* set the device address to 0, and disable all the endpoints except the default
@@ -3762,6 +3950,22 @@ static int xhci_discover_or_reset_device(struct usb_hcd *hcd,
SLOT_STATE_DISABLED)
return 0;
+ if (xhci->quirks & XHCI_ETRON_HOST) {
+ /*
+ * Obtaining a new device slot to inform the xHCI host that
+ * the USB device has been reset.
+ */
+ ret = xhci_disable_and_free_slot(xhci, udev->slot_id);
+ if (!ret) {
+ ret = xhci_alloc_dev(hcd, udev);
+ if (ret == 1)
+ ret = 0;
+ else
+ ret = -EINVAL;
+ }
+ return ret;
+ }
+
trace_xhci_discover_or_reset_device(slot_ctx);
xhci_dbg(xhci, "Resetting device with slot ID %u\n", slot_id);
@@ -3810,6 +4014,7 @@ static int xhci_discover_or_reset_device(struct usb_hcd *hcd,
xhci_get_slot_state(xhci, virt_dev->out_ctx));
xhci_dbg(xhci, "Not freeing device rings.\n");
/* Don't treat this as an error. May change my mind later. */
+ virt_dev->flags = 0;
ret = 0;
goto command_cleanup;
case COMP_SUCCESS:
@@ -3845,6 +4050,8 @@ static int xhci_discover_or_reset_device(struct usb_hcd *hcd,
}
if (ep->ring) {
+ if (ep->sideband)
+ xhci_sideband_notify_ep_ring_free(ep->sideband, i);
xhci_debugfs_remove_endpoint(xhci, virt_dev, i);
xhci_free_endpoint_ring(xhci, virt_dev, i);
}
@@ -3906,7 +4113,7 @@ static void xhci_free_dev(struct usb_hcd *hcd, struct usb_device *udev)
xhci_disable_slot(xhci, udev->slot_id);
spin_lock_irqsave(&xhci->lock, flags);
- xhci_free_virt_device(xhci, udev->slot_id);
+ xhci_free_virt_device(xhci, virt_dev, udev->slot_id);
spin_unlock_irqrestore(&xhci->lock, flags);
}
@@ -3955,6 +4162,16 @@ int xhci_disable_slot(struct xhci_hcd *xhci, u32 slot_id)
return 0;
}
+int xhci_disable_and_free_slot(struct xhci_hcd *xhci, u32 slot_id)
+{
+ struct xhci_virt_device *vdev = xhci->devs[slot_id];
+ int ret;
+
+ ret = xhci_disable_slot(xhci, slot_id);
+ xhci_free_virt_device(xhci, vdev, slot_id);
+ return ret;
+}
+
/*
* Checks if we have enough host controller resources for the default control
* endpoint.
@@ -4013,8 +4230,7 @@ int xhci_alloc_dev(struct usb_hcd *hcd, struct usb_device *udev)
xhci_err(xhci, "Error while assigning device slot ID: %s\n",
xhci_trb_comp_code_string(command->status));
xhci_err(xhci, "Max number of devices this xHCI host supports is %u.\n",
- HCS_MAX_SLOTS(
- readl(&xhci->cap_regs->hcs_params1)));
+ xhci->max_slots);
xhci_free_command(xhci, command);
return 0;
}
@@ -4061,8 +4277,7 @@ int xhci_alloc_dev(struct usb_hcd *hcd, struct usb_device *udev)
return 1;
disable_slot:
- xhci_disable_slot(xhci, udev->slot_id);
- xhci_free_virt_device(xhci, udev->slot_id);
+ xhci_disable_and_free_slot(xhci, udev->slot_id);
return 0;
}
@@ -4158,8 +4373,7 @@ static int xhci_setup_device(struct usb_hcd *hcd, struct usb_device *udev,
ctrl_ctx->add_flags = cpu_to_le32(SLOT_FLAG | EP0_FLAG);
ctrl_ctx->drop_flags = 0;
- trace_xhci_address_ctx(xhci, virt_dev->in_ctx,
- le32_to_cpu(slot_ctx->dev_info) >> 27);
+ trace_xhci_address_ctx(xhci, virt_dev->in_ctx);
trace_xhci_address_ctrl_ctx(ctrl_ctx);
spin_lock_irqsave(&xhci->lock, flags);
@@ -4198,10 +4412,11 @@ static int xhci_setup_device(struct usb_hcd *hcd, struct usb_device *udev,
dev_warn(&udev->dev, "Device not responding to setup %s.\n", act);
mutex_unlock(&xhci->mutex);
- ret = xhci_disable_slot(xhci, udev->slot_id);
- xhci_free_virt_device(xhci, udev->slot_id);
- if (!ret)
- xhci_alloc_dev(hcd, udev);
+ ret = xhci_disable_and_free_slot(xhci, udev->slot_id);
+ if (!ret) {
+ if (xhci_alloc_dev(hcd, udev) == 1)
+ xhci_setup_addressable_virt_dev(xhci, udev);
+ }
kfree(command->completion);
kfree(command);
return -EPROTO;
@@ -4218,7 +4433,7 @@ static int xhci_setup_device(struct usb_hcd *hcd, struct usb_device *udev,
xhci_err(xhci,
"ERROR: unexpected setup %s command completion code 0x%x.\n",
act, command->status);
- trace_xhci_address_ctx(xhci, virt_dev->out_ctx, 1);
+ trace_xhci_address_ctx(xhci, virt_dev->out_ctx);
ret = -EINVAL;
break;
}
@@ -4236,14 +4451,12 @@ static int xhci_setup_device(struct usb_hcd *hcd, struct usb_device *udev,
xhci_dbg_trace(xhci, trace_xhci_dbg_address,
"Output Context DMA address = %#08llx",
(unsigned long long)virt_dev->out_ctx->dma);
- trace_xhci_address_ctx(xhci, virt_dev->in_ctx,
- le32_to_cpu(slot_ctx->dev_info) >> 27);
+ trace_xhci_address_ctx(xhci, virt_dev->in_ctx);
/*
* USB core uses address 1 for the roothubs, so we add one to the
* address given back to us by the HC.
*/
- trace_xhci_address_ctx(xhci, virt_dev->out_ctx,
- le32_to_cpu(slot_ctx->dev_info) >> 27);
+ trace_xhci_address_ctx(xhci, virt_dev->out_ctx);
/* Zero the input context control for later use */
ctrl_ctx->add_flags = 0;
ctrl_ctx->drop_flags = 0;
@@ -4427,7 +4640,7 @@ static int xhci_set_usb2_hardware_lpm(struct usb_hcd *hcd,
{
struct xhci_hcd *xhci = hcd_to_xhci(hcd);
struct xhci_port **ports;
- __le32 __iomem *pm_addr, *hlpm_addr;
+ struct xhci_port_regs __iomem *port_reg;
u32 pm_val, hlpm_val, field;
unsigned int port_num;
unsigned long flags;
@@ -4452,12 +4665,11 @@ static int xhci_set_usb2_hardware_lpm(struct usb_hcd *hcd,
ports = xhci->usb2_rhub.ports;
port_num = udev->portnum - 1;
- pm_addr = ports[port_num]->addr + PORTPMSC;
- pm_val = readl(pm_addr);
- hlpm_addr = ports[port_num]->addr + PORTHLPMC;
+ port_reg = ports[port_num]->port_reg;
+ pm_val = readl(&port_reg->portpmsc);
xhci_dbg(xhci, "%s port %d USB2 hardware LPM\n",
- enable ? "enable" : "disable", port_num + 1);
+ str_enable_disable(enable), port_num + 1);
if (enable) {
/* Host supports BESL timeout instead of HIRD */
@@ -4483,30 +4695,30 @@ static int xhci_set_usb2_hardware_lpm(struct usb_hcd *hcd,
spin_lock_irqsave(&xhci->lock, flags);
hlpm_val = xhci_calculate_usb2_hw_lpm_params(udev);
- writel(hlpm_val, hlpm_addr);
+ writel(hlpm_val, &port_reg->porthlmpc);
/* flush write */
- readl(hlpm_addr);
+ readl(&port_reg->porthlmpc);
} else {
hird = xhci_calculate_hird_besl(xhci, udev);
}
pm_val &= ~PORT_HIRD_MASK;
pm_val |= PORT_HIRD(hird) | PORT_RWE | PORT_L1DS(udev->slot_id);
- writel(pm_val, pm_addr);
- pm_val = readl(pm_addr);
+ writel(pm_val, &port_reg->portpmsc);
+ pm_val = readl(&port_reg->portpmsc);
pm_val |= PORT_HLE;
- writel(pm_val, pm_addr);
+ writel(pm_val, &port_reg->portpmsc);
/* flush write */
- readl(pm_addr);
+ readl(&port_reg->portpmsc);
} else {
pm_val &= ~(PORT_HLE | PORT_RWE | PORT_HIRD_MASK | PORT_L1DS_MASK);
- writel(pm_val, pm_addr);
+ writel(pm_val, &port_reg->portpmsc);
/* flush write */
- readl(pm_addr);
+ readl(&port_reg->portpmsc);
if (udev->usb2_hw_lpm_besl_capable) {
spin_unlock_irqrestore(&xhci->lock, flags);
xhci_change_max_exit_latency(xhci, udev, 0);
- readl_poll_timeout(ports[port_num]->addr, pm_val,
+ readl_poll_timeout(&ports[port_num]->port_reg->portsc, pm_val,
(pm_val & PORT_PLS_MASK) == XDEV_U0,
100, 10000);
return 0;
@@ -4523,6 +4735,20 @@ static int xhci_update_device(struct usb_hcd *hcd, struct usb_device *udev)
struct xhci_port *port;
u32 capability;
+ /* Check if USB3 device at root port is tunneled over USB4 */
+ if (hcd->speed >= HCD_USB3 && !udev->parent->parent) {
+ port = xhci->usb3_rhub.ports[udev->portnum - 1];
+
+ udev->tunnel_mode = xhci_port_is_tunneled(xhci, port);
+ if (udev->tunnel_mode == USB_LINK_UNKNOWN)
+ dev_dbg(&udev->dev, "link tunnel state unknown\n");
+ else if (udev->tunnel_mode == USB_LINK_TUNNELED)
+ dev_dbg(&udev->dev, "tunneled over USB4 link\n");
+ else if (udev->tunnel_mode == USB_LINK_NATIVE)
+ dev_dbg(&udev->dev, "native USB 3.x link\n");
+ return 0;
+ }
+
if (hcd->speed >= HCD_USB3 || !udev->lpm_capable || !xhci->hw_lpm_support)
return 0;
@@ -4674,8 +4900,8 @@ static u16 xhci_calculate_u1_timeout(struct xhci_hcd *xhci,
*/
if (timeout_ns <= USB3_LPM_U1_MAX_TIMEOUT)
return timeout_ns;
- dev_dbg(&udev->dev, "Hub-initiated U1 disabled "
- "due to long timeout %llu ms\n", timeout_ns);
+ dev_dbg(&udev->dev, "Hub-initiated U1 disabled due to long timeout %lluus\n",
+ timeout_ns);
return xhci_get_timeout_no_hub_lpm(udev, USB3_LPM_U1);
}
@@ -4732,8 +4958,8 @@ static u16 xhci_calculate_u2_timeout(struct xhci_hcd *xhci,
*/
if (timeout_ns <= USB3_LPM_U2_MAX_TIMEOUT)
return timeout_ns;
- dev_dbg(&udev->dev, "Hub-initiated U2 disabled "
- "due to long timeout %llu ms\n", timeout_ns);
+ dev_dbg(&udev->dev, "Hub-initiated U2 disabled due to long timeout %lluus\n",
+ timeout_ns * 256);
return xhci_get_timeout_no_hub_lpm(udev, USB3_LPM_U2);
}
@@ -5185,6 +5411,7 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks)
*/
struct device *dev = hcd->self.sysdev;
int retval;
+ u32 hcs_params1;
/* Accept arbitrarily long scatter-gather lists */
hcd->self.sg_tablesize = ~0;
@@ -5210,7 +5437,7 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks)
xhci->run_regs = hcd->regs +
(readl(&xhci->cap_regs->run_regs_off) & RTSOFF_MASK);
/* Cache read-only capability registers */
- xhci->hcs_params1 = readl(&xhci->cap_regs->hcs_params1);
+ hcs_params1 = readl(&xhci->cap_regs->hcs_params1);
xhci->hcs_params2 = readl(&xhci->cap_regs->hcs_params2);
xhci->hcs_params3 = readl(&xhci->cap_regs->hcs_params3);
xhci->hci_version = HC_VERSION(readl(&xhci->cap_regs->hc_capbase));
@@ -5218,10 +5445,13 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks)
if (xhci->hci_version > 0x100)
xhci->hcc_params2 = readl(&xhci->cap_regs->hcc_params2);
+ xhci->max_slots = HCS_MAX_SLOTS(hcs_params1);
+ xhci->max_ports = min(HCS_MAX_PORTS(hcs_params1), MAX_HC_PORTS);
/* xhci-plat or xhci-pci might have set max_interrupters already */
- if ((!xhci->max_interrupters) ||
- xhci->max_interrupters > HCS_MAX_INTRS(xhci->hcs_params1))
- xhci->max_interrupters = HCS_MAX_INTRS(xhci->hcs_params1);
+ if (!xhci->max_interrupters)
+ xhci->max_interrupters = min(HCS_MAX_INTRS(hcs_params1), MAX_HC_INTRS);
+ else if (xhci->max_interrupters > HCS_MAX_INTRS(hcs_params1))
+ xhci->max_interrupters = HCS_MAX_INTRS(hcs_params1);
xhci->quirks |= quirks;
@@ -5235,6 +5465,11 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks)
if (xhci->hci_version > 0x96)
xhci->quirks |= XHCI_SPURIOUS_SUCCESS;
+ if (xhci->hci_version == 0x95 && link_quirk) {
+ xhci_dbg(xhci, "QUIRK: Not clearing Link TRB chain bits");
+ xhci->quirks |= XHCI_LINK_TRB_QUIRK;
+ }
+
/* Make sure the HC is halted. */
retval = xhci_halt(xhci);
if (retval)
@@ -5261,7 +5496,7 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks)
/* Set dma_mask and coherent_dma_mask to 64-bits,
* if xHC supports 64-bit addressing */
- if (HCC_64BIT_ADDR(xhci->hcc_params) &&
+ if ((xhci->hcc_params & HCC_64BIT_ADDR) &&
!dma_set_mask(dev, DMA_BIT_MASK(64))) {
xhci_dbg(xhci, "Enabling 64-bit DMA addresses.\n");
dma_set_coherent_mask(dev, DMA_BIT_MASK(64));
@@ -5435,8 +5670,8 @@ static int __init xhci_hcd_init(void)
BUILD_BUG_ON(sizeof(struct xhci_erst_entry) != 4*32/8);
BUILD_BUG_ON(sizeof(struct xhci_cap_regs) != 8*32/8);
BUILD_BUG_ON(sizeof(struct xhci_intr_reg) != 8*32/8);
- /* xhci_run_regs has eight fields and embeds 128 xhci_intr_regs */
- BUILD_BUG_ON(sizeof(struct xhci_run_regs) != (8+8*128)*32/8);
+ /* xhci_run_regs has eight fields and embeds 1024 xhci_intr_regs */
+ BUILD_BUG_ON(sizeof(struct xhci_run_regs) != (8+8*1024)*32/8);
if (usb_disabled())
return -ENODEV;