diff options
Diffstat (limited to 'drivers/usb/host')
-rw-r--r-- | drivers/usb/host/ehci-atmel.c | 17 | ||||
-rw-r--r-- | drivers/usb/host/ehci-hcd.c | 21 | ||||
-rw-r--r-- | drivers/usb/host/ehci-omap.c | 12 | ||||
-rw-r--r-- | drivers/usb/host/ohci-at91.c | 21 | ||||
-rw-r--r-- | drivers/usb/host/ohci-hcd.c | 15 | ||||
-rw-r--r-- | drivers/usb/host/xhci-mem.c | 103 | ||||
-rw-r--r-- | drivers/usb/host/xhci-ring.c | 209 | ||||
-rw-r--r-- | drivers/usb/host/xhci.c | 80 | ||||
-rw-r--r-- | drivers/usb/host/xhci.h | 24 |
9 files changed, 320 insertions, 182 deletions
diff --git a/drivers/usb/host/ehci-atmel.c b/drivers/usb/host/ehci-atmel.c index ba24709e13..f176babfa7 100644 --- a/drivers/usb/host/ehci-atmel.c +++ b/drivers/usb/host/ehci-atmel.c @@ -8,9 +8,9 @@ #include <linux/err.h> #include <driver.h> #include <init.h> -#include <usb/usb.h> -#include <usb/usb_defs.h> -#include <usb/ehci.h> +#include <linux/usb/usb.h> +#include <linux/usb/usb_defs.h> +#include <linux/usb/ehci.h> #include <errno.h> #include <io.h> @@ -18,7 +18,7 @@ struct atmel_ehci_priv { struct ehci_host *ehci; - struct device_d *dev; + struct device *dev; struct clk *iclk; struct clk *uclk; }; @@ -47,7 +47,7 @@ static void atmel_stop_clock(struct atmel_ehci_priv *atehci) clk_disable(atehci->uclk); } -static int atmel_ehci_probe(struct device_d *dev) +static int atmel_ehci_probe(struct device *dev) { int ret; struct resource *iores; @@ -56,7 +56,7 @@ static int atmel_ehci_probe(struct device_d *dev) const char *uclk_name; struct ehci_host *ehci; - uclk_name = (dev->device_node) ? "usb_clk" : "uhpck"; + uclk_name = (dev->of_node) ? "usb_clk" : "uhpck"; atehci = xzalloc(sizeof(*atehci)); atehci->dev = dev; @@ -97,7 +97,7 @@ static int atmel_ehci_probe(struct device_d *dev) return 0; } -static void atmel_ehci_remove(struct device_d *dev) +static void atmel_ehci_remove(struct device *dev) { struct atmel_ehci_priv *atehci = dev->priv; @@ -113,8 +113,9 @@ static const struct of_device_id atmel_ehci_dt_ids[] = { { .compatible = "atmel,at91sam9g45-ehci" }, { /* sentinel */ } }; +MODULE_DEVICE_TABLE(of, atmel_ehci_dt_ids); -static struct driver_d atmel_ehci_driver = { +static struct driver atmel_ehci_driver = { .name = "atmel-ehci", .probe = atmel_ehci_probe, .remove = atmel_ehci_remove, diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 068504557b..7ae3a285a0 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -10,7 +10,7 @@ #include <common.h> #include <dma.h> #include <asm/byteorder.h> -#include <usb/usb.h> +#include <linux/usb/usb.h> #include <io.h> #include <malloc.h> #include <driver.h> @@ -19,7 +19,7 @@ #include <clock.h> #include <errno.h> #include <of.h> -#include <usb/ehci.h> +#include <linux/usb/ehci.h> #include <linux/err.h> #include <linux/sizes.h> #include <linux/clk.h> @@ -29,7 +29,7 @@ struct ehci_host { int rootdev; - struct device_d *dev; + struct device *dev; struct ehci_hccr *hccr; struct ehci_hcor *hcor; struct usb_host host; @@ -242,7 +242,7 @@ static int ehci_td_buffer(struct qTD *td, dma_addr_t addr, size_t sz) return 0; } -static int ehci_prepare_qtd(struct device_d *dev, +static int ehci_prepare_qtd(struct device *dev, struct qTD *td, uint32_t token, void *buffer, size_t length, dma_addr_t *buffer_dma, @@ -510,7 +510,7 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer, } #if defined(CONFIG_MACH_EFIKA_MX_SMARTBOOK) && defined(CONFIG_USB_ULPI) -#include <usb/ulpi.h> +#include <linux/usb/ulpi.h> /* * Add support for setting CHRGVBUS to workaround a hardware bug on efika mx/sb * boards. @@ -1341,7 +1341,7 @@ submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer, return result; } -struct ehci_host *ehci_register(struct device_d *dev, struct ehci_data *data) +struct ehci_host *ehci_register(struct device *dev, struct ehci_data *data) { struct usb_host *host; struct ehci_host *ehci; @@ -1398,12 +1398,12 @@ void ehci_unregister(struct ehci_host *ehci) free(ehci); } -static int ehci_probe(struct device_d *dev) +static int ehci_probe(struct device *dev) { struct resource *iores; struct ehci_data data = {}; struct ehci_platform_data *pdata = dev->platform_data; - struct device_node *dn = dev->device_node; + struct device_node *dn = dev->of_node; struct ehci_host *ehci; struct clk_bulk_data *clks; int num_clocks, ret; @@ -1465,7 +1465,7 @@ static int ehci_probe(struct device_d *dev) return 0; } -static void ehci_remove(struct device_d *dev) +static void ehci_remove(struct device *dev) { struct ehci_host *ehci = dev->priv; @@ -1479,8 +1479,9 @@ static __maybe_unused struct of_device_id ehci_platform_dt_ids[] = { /* sentinel */ } }; +MODULE_DEVICE_TABLE(of, ehci_platform_dt_ids); -static struct driver_d ehci_driver = { +static struct driver ehci_driver = { .name = "ehci", .probe = ehci_probe, .remove = ehci_remove, diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c index 858dc55f32..e364796a1a 100644 --- a/drivers/usb/host/ehci-omap.c +++ b/drivers/usb/host/ehci-omap.c @@ -10,16 +10,16 @@ /*-------------------------------------------------------------------------*/ #include <mfd/twl4030.h> -#include <usb/twl4030.h> -#include <mach/ehci.h> +#include <linux/usb/twl4030.h> +#include <mach/omap/ehci.h> #include <common.h> #include <io.h> #include <clock.h> #include <gpio.h> -#include <mach/omap3-silicon.h> -#include <mach/omap3-clock.h> -#include <mach/cm-regbits-34xx.h> -#include <mach/sys_info.h> +#include <mach/omap/omap3-silicon.h> +#include <mach/omap/omap3-clock.h> +#include <mach/omap/cm-regbits-34xx.h> +#include <mach/omap/sys_info.h> void omap_usb_utmi_init(struct omap_hcd *omap, u8 tll_channel_mask) { diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c index a77e2cae14..867c0977be 100644 --- a/drivers/usb/host/ohci-at91.c +++ b/drivers/usb/host/ohci-at91.c @@ -7,14 +7,14 @@ #include <linux/clk.h> #include <driver.h> #include <init.h> -#include <usb/usb.h> -#include <usb/usb_defs.h> +#include <linux/usb/usb.h> +#include <linux/usb/usb_defs.h> #include <errno.h> #include <gpio.h> #include <of_gpio.h> #include <io.h> -#include <mach/board.h> +#include <mach/at91/board.h> #include "ohci.h" @@ -23,7 +23,7 @@ struct ohci_at91_priv { - struct device_d *dev; + struct device *dev; struct clk *iclk; struct clk *fclk; struct ohci_regs __iomem *regs; @@ -54,13 +54,13 @@ static void at91_stop_clock(struct ohci_at91_priv *ohci_at91) clk_disable(ohci_at91->iclk); } -static int at91_ohci_probe_dt(struct device_d *dev) +static int at91_ohci_probe_dt(struct device *dev) { u32 ports; int i, ret, gpio; enum of_gpio_flags flags; struct at91_usbh_data *pdata; - struct device_node *np = dev->device_node; + struct device_node *np = dev->of_node; pdata = xzalloc(sizeof(*pdata)); dev->platform_data = pdata; @@ -107,7 +107,7 @@ static int at91_ohci_probe_dt(struct device_d *dev) return 0; } -static int at91_ohci_probe(struct device_d *dev) +static int at91_ohci_probe(struct device *dev) { int ret; struct resource *io; @@ -116,7 +116,7 @@ static int at91_ohci_probe(struct device_d *dev) dev->priv = ohci_at91; ohci_at91->dev = dev; - if (dev->device_node) { + if (dev->of_node) { ret = at91_ohci_probe_dt(dev); if (ret < 0) return ret; @@ -159,7 +159,7 @@ static int at91_ohci_probe(struct device_d *dev) return 0; } -static void at91_ohci_remove(struct device_d *dev) +static void at91_ohci_remove(struct device *dev) { struct at91_usbh_data *pdata = dev->platform_data; struct ohci_at91_priv *ohci_at91 = dev->priv; @@ -194,8 +194,9 @@ static const struct of_device_id at91_ohci_dt_ids[] = { { .compatible = "atmel,at91rm9200-ohci" }, { /* sentinel */ } }; +MODULE_DEVICE_TABLE(of, at91_ohci_dt_ids); -static struct driver_d at91_ohci_driver = { +static struct driver at91_ohci_driver = { .name = "at91_ohci", .probe = at91_ohci_probe, .remove = at91_ohci_remove, diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index ce5d39166b..ae4c34e818 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c @@ -30,8 +30,8 @@ #include <clock.h> #include <dma.h> #include <malloc.h> -#include <usb/usb.h> -#include <usb/usb_defs.h> +#include <linux/usb/usb.h> +#include <linux/usb/usb_defs.h> #include <init.h> #include <errno.h> #include <linux/err.h> @@ -842,7 +842,8 @@ static void td_fill(struct ohci *ohci, unsigned int info, td->hwNextTD = virt_to_phys((void *)m32_swap((unsigned long)td_pt)); - dma_sync_single_for_device((unsigned long)data, len, DMA_BIDIRECTIONAL); + dma_sync_single_for_device(ohci->host.hw_dev, (unsigned long)data, + len, DMA_BIDIRECTIONAL); /* append to queue */ td->ed->hwTailP = td->hwNextTD; @@ -1078,7 +1079,7 @@ static int dl_done_list(struct ohci *ohci) unsigned long ptdphys = virt_to_phys(ptd); struct td *td_list; - dma_sync_single_for_device((unsigned long)ptdphys, + dma_sync_single_for_device(ohci->host.hw_dev, (unsigned long)ptdphys, sizeof(struct td) * NUM_TD, DMA_BIDIRECTIONAL); td_list = dl_reverse_done_list(ohci); @@ -1515,7 +1516,7 @@ static int submit_common_msg(struct usb_device *dev, unsigned long pipe, void *b dev->status = stat; dev->act_len = urb->actual_length; - dma_sync_single_for_cpu((unsigned long)buffer, transfer_len, + dma_sync_single_for_cpu(host->hw_dev, (unsigned long)buffer, transfer_len, DMA_BIDIRECTIONAL); pkt_print(urb, dev, pipe, buffer, transfer_len, @@ -1775,7 +1776,7 @@ static int ohci_init(struct usb_host *host) return 0; } -static int ohci_probe(struct device_d *dev) +static int ohci_probe(struct device *dev) { struct resource *iores; struct usb_host *host; @@ -1810,7 +1811,7 @@ static int ohci_probe(struct device_d *dev) return 0; } -static struct driver_d ohci_driver = { +static struct driver ohci_driver = { .name = "ohci", .probe = ohci_probe, }; diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index ae20560eb5..e962bfde3f 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -20,8 +20,8 @@ #include <io.h> #include <linux/err.h> #include <linux/sizes.h> -#include <usb/usb.h> -#include <usb/xhci.h> +#include <linux/usb/usb.h> +#include <linux/usb/xhci.h> #include <asm/unaligned.h> #include "xhci.h" @@ -82,11 +82,11 @@ static void xhci_free(struct xhci_ctrl *ctrl, void *ptr) * @param size size of memory to be allocated * @return allocates the memory and returns the aligned pointer */ -static void *xhci_malloc(struct xhci_ctrl *ctrl, unsigned int size) +static void *xhci_malloc(struct xhci_ctrl *ctrl, unsigned int size, dma_addr_t *dma_addr) { void *ptr; - ptr = dma_alloc_coherent(size, DMA_ADDRESS_BROKEN); + ptr = dma_alloc_coherent(size, dma_addr); if (!ptr) return NULL; @@ -145,7 +145,7 @@ static void xhci_scratchpad_free(struct xhci_ctrl *ctrl) ctrl->dcbaa->dev_context_ptrs[0] = 0; - xhci_free(ctrl, (void *)(uintptr_t)ctrl->scratchpad->sp_array[0]); + xhci_free(ctrl, ctrl->scratchpad->scratchpad); xhci_free(ctrl, ctrl->scratchpad->sp_array); free(ctrl->scratchpad); ctrl->scratchpad = NULL; @@ -234,14 +234,13 @@ static void xhci_link_segments(struct xhci_segment *prev, struct xhci_segment *next, bool link_trbs) { u32 val; - u64 val_64 = 0; if (!prev || !next) return; prev->next = next; if (link_trbs) { - val_64 = (uintptr_t)next->trbs; - prev->trbs[TRBS_PER_SEGMENT-1].link.segment_ptr = val_64; + prev->trbs[TRBS_PER_SEGMENT-1].link.segment_ptr = + cpu_to_le64(next->dma); /* * Set the last TRB in the segment to @@ -249,8 +248,7 @@ static void xhci_link_segments(struct xhci_segment *prev, */ val = le32_to_cpu(prev->trbs[TRBS_PER_SEGMENT-1].link.control); val &= ~TRB_TYPE_BITMASK; - val |= (TRB_LINK << TRB_TYPE_SHIFT); - + val |= TRB_TYPE(TRB_LINK); prev->trbs[TRBS_PER_SEGMENT-1].link.control = cpu_to_le32(val); } } @@ -295,7 +293,7 @@ static struct xhci_segment *xhci_segment_alloc(struct xhci_ctrl *ctrl) seg = xzalloc(sizeof(*seg)); - seg->trbs = xhci_malloc(ctrl, SEGMENT_SIZE); + seg->trbs = xhci_malloc(ctrl, SEGMENT_SIZE, &seg->dma); return seg; } @@ -365,6 +363,7 @@ static int xhci_scratchpad_alloc(struct xhci_ctrl *ctrl) struct xhci_hccr *hccr = ctrl->hccr; struct xhci_hcor *hcor = ctrl->hcor; struct xhci_scratchpad *scratchpad; + dma_addr_t val_64; int num_sp; uint32_t page_size; void *buf; @@ -379,11 +378,11 @@ static int xhci_scratchpad_alloc(struct xhci_ctrl *ctrl) goto fail_sp; ctrl->scratchpad = scratchpad; - scratchpad->sp_array = xhci_malloc(ctrl, num_sp * sizeof(u64)); + scratchpad->sp_array = xhci_malloc(ctrl, num_sp * sizeof(u64), &val_64); if (!scratchpad->sp_array) goto fail_sp2; - ctrl->dcbaa->dev_context_ptrs[0] = - cpu_to_le64((uintptr_t)scratchpad->sp_array); + + ctrl->dcbaa->dev_context_ptrs[0] = cpu_to_le64(val_64); xhci_flush_cache((uintptr_t)&ctrl->dcbaa->dev_context_ptrs[0], sizeof(ctrl->dcbaa->dev_context_ptrs[0])); @@ -397,17 +396,21 @@ static int xhci_scratchpad_alloc(struct xhci_ctrl *ctrl) BUG_ON(i == 16); page_size = 1 << (i + 12); - buf = xhci_malloc(ctrl, num_sp * page_size); + buf = xhci_malloc(ctrl, num_sp * page_size, &val_64); if (!buf) goto fail_sp3; xhci_flush_cache((uintptr_t)buf, num_sp * page_size); + scratchpad->scratchpad = buf; for (i = 0; i < num_sp; i++) { - uintptr_t ptr = (uintptr_t)buf + i * page_size; - scratchpad->sp_array[i] = cpu_to_le64(ptr); + scratchpad->sp_array[i] = cpu_to_le64(val_64); + val_64 += page_size; } + xhci_flush_cache((uintptr_t)scratchpad->sp_array, + sizeof(u64) * num_sp); + return 0; fail_sp3: @@ -438,11 +441,11 @@ static struct xhci_container_ctx BUG_ON((type != XHCI_CTX_TYPE_DEVICE) && (type != XHCI_CTX_TYPE_INPUT)); ctx->type = type; ctx->size = (MAX_EP_CTX_NUM + 1) * - CTX_SIZE(readl(&ctrl->hccr->cr_hccparams)); + CTX_SIZE(xhci_readl(&ctrl->hccr->cr_hccparams)); if (type == XHCI_CTX_TYPE_INPUT) - ctx->size += CTX_SIZE(readl(&ctrl->hccr->cr_hccparams)); + ctx->size += CTX_SIZE(xhci_readl(&ctrl->hccr->cr_hccparams)); - ctx->bytes = xhci_malloc(ctrl, ctx->size); + ctx->bytes = xhci_malloc(ctrl, ctx->size, &ctx->dma); return ctx; } @@ -464,8 +467,7 @@ int xhci_alloc_virt_device(struct xhci_ctrl *ctrl, unsigned int slot_id) return -EEXIST; } - ctrl->devs[slot_id] = (struct xhci_virt_device *) - malloc(sizeof(struct xhci_virt_device)); + ctrl->devs[slot_id] = malloc(sizeof(struct xhci_virt_device)); if (!ctrl->devs[slot_id]) { dev_err(ctrl->dev, "Failed to allocate virtual device\n"); @@ -494,10 +496,10 @@ int xhci_alloc_virt_device(struct xhci_ctrl *ctrl, unsigned int slot_id) /* Allocate endpoint 0 ring */ virt_dev->eps[0].ring = xhci_ring_alloc(ctrl, 1, true); - byte_64 = (uintptr_t)(virt_dev->out_ctx->bytes); + byte_64 = virt_dev->out_ctx->dma; /* Point to output device context in dcbaa. */ - ctrl->dcbaa->dev_context_ptrs[slot_id] = byte_64; + ctrl->dcbaa->dev_context_ptrs[slot_id] = cpu_to_le64(byte_64); xhci_flush_cache((uintptr_t)&ctrl->dcbaa->dev_context_ptrs[slot_id], sizeof(__le64)); @@ -516,29 +518,27 @@ int xhci_alloc_virt_device(struct xhci_ctrl *ctrl, unsigned int slot_id) int xhci_mem_init(struct xhci_ctrl *ctrl, struct xhci_hccr *hccr, struct xhci_hcor *hcor) { + dma_addr_t dma; uint64_t val_64; uint64_t trb_64; uint32_t val; - unsigned long deq; + uint64_t deq; int i; struct xhci_segment *seg; /* DCBAA initialization */ - ctrl->dcbaa = xhci_malloc(ctrl, sizeof(*ctrl->dcbaa)); - if (!ctrl->dcbaa) { - dev_err(ctrl->dev, "unable to allocate DCBA\n"); - return -ENOMEM; - } + ctrl->dcbaa = xhci_malloc(ctrl, sizeof(struct xhci_device_context_array), + &dma); + ctrl->dcbaa->dma = dma; - val_64 = (uintptr_t)ctrl->dcbaa; /* Set the pointer in DCBAA register */ - xhci_writeq(&hcor->or_dcbaap, val_64); + xhci_writeq(&hcor->or_dcbaap, dma); /* Command ring control pointer register initialization */ ctrl->cmd_ring = xhci_ring_alloc(ctrl, 1, true); /* Set the address in the Command Ring Control register */ - trb_64 = (uintptr_t)ctrl->cmd_ring->first_seg->trbs; + trb_64 = ctrl->cmd_ring->first_seg->dma; val_64 = xhci_readq(&hcor->or_crcr); val_64 = (val_64 & (u64) CMD_RING_RSVD_BITS) | (trb_64 & (u64) ~CMD_RING_RSVD_BITS) | @@ -560,8 +560,8 @@ int xhci_mem_init(struct xhci_ctrl *ctrl, struct xhci_hccr *hccr, /* Event ring does not maintain link TRB */ ctrl->event_ring = xhci_ring_alloc(ctrl, ERST_NUM_SEGS, false); - ctrl->erst.entries = - xhci_malloc(ctrl, sizeof(struct xhci_erst_entry) * ERST_NUM_SEGS); + ctrl->erst.entries = xhci_malloc(ctrl, sizeof(struct xhci_erst_entry) * + ERST_NUM_SEGS, &ctrl->erst.erst_dma_addr); ctrl->erst.num_entries = ERST_NUM_SEGS; @@ -570,9 +570,8 @@ int xhci_mem_init(struct xhci_ctrl *ctrl, struct xhci_hccr *hccr, val++) { struct xhci_erst_entry *entry = &ctrl->erst.entries[val]; - trb_64 = 0; - trb_64 = (uintptr_t)seg->trbs; - xhci_writeq(&entry->seg_addr, trb_64); + trb_64 = seg->dma; + entry->seg_addr = cpu_to_le64(trb_64); entry->seg_size = cpu_to_le32(TRBS_PER_SEGMENT); entry->rsvd = 0; seg = seg->next; @@ -580,7 +579,8 @@ int xhci_mem_init(struct xhci_ctrl *ctrl, struct xhci_hccr *hccr, xhci_flush_cache((uintptr_t)ctrl->erst.entries, ERST_NUM_SEGS * sizeof(struct xhci_erst_entry)); - deq = (unsigned long)ctrl->event_ring->dequeue; + deq = xhci_trb_virt_to_dma(ctrl->event_ring->deq_seg, + ctrl->event_ring->dequeue); /* Update HC event ring dequeue pointer */ xhci_writeq(&ctrl->ir_set->erst_dequeue, @@ -595,7 +595,7 @@ int xhci_mem_init(struct xhci_ctrl *ctrl, struct xhci_hccr *hccr, /* this is the event ring segment table pointer */ val_64 = xhci_readq(&ctrl->ir_set->erst_base); val_64 &= ERST_PTR_MASK; - val_64 |= ((uintptr_t)(ctrl->erst.entries) & ~ERST_PTR_MASK); + val_64 |= ctrl->erst.erst_dma_addr & ~ERST_PTR_MASK; xhci_writeq(&ctrl->ir_set->erst_base, val_64); @@ -645,7 +645,7 @@ struct xhci_slot_ctx *xhci_get_slot_ctx(struct xhci_ctrl *ctrl, return (struct xhci_slot_ctx *)ctx->bytes; return (struct xhci_slot_ctx *) - (ctx->bytes + CTX_SIZE(readl(&ctrl->hccr->cr_hccparams))); + (ctx->bytes + CTX_SIZE(xhci_readl(&ctrl->hccr->cr_hccparams))); } /** @@ -667,7 +667,7 @@ struct xhci_ep_ctx *xhci_get_ep_ctx(struct xhci_ctrl *ctrl, return (struct xhci_ep_ctx *) (ctx->bytes + - (ep_index * CTX_SIZE(readl(&ctrl->hccr->cr_hccparams)))); + (ep_index * CTX_SIZE(xhci_readl(&ctrl->hccr->cr_hccparams)))); } /** @@ -776,7 +776,7 @@ void xhci_setup_addressable_virt_dev(struct xhci_ctrl *ctrl, dev_dbg(&udev->dev, "route string 0x%x\n", route); - slot_ctx->dev_info |= route; + slot_ctx->dev_info |= cpu_to_le32(route); switch (speed) { case USB_SPEED_SUPER: @@ -824,25 +824,22 @@ void xhci_setup_addressable_virt_dev(struct xhci_ctrl *ctrl, /* Step 4 - ring already allocated */ /* Step 5 */ - ep0_ctx->ep_info2 = cpu_to_le32(CTRL_EP << EP_TYPE_SHIFT); + ep0_ctx->ep_info2 = cpu_to_le32(EP_TYPE(CTRL_EP)); dev_dbg(&udev->dev, "SPEED = %d\n", speed); switch (speed) { case USB_SPEED_SUPER: - ep0_ctx->ep_info2 |= cpu_to_le32(((512 & MAX_PACKET_MASK) << - MAX_PACKET_SHIFT)); + ep0_ctx->ep_info2 |= cpu_to_le32(MAX_PACKET(512)); dev_dbg(&udev->dev, "Setting Packet size = 512bytes\n"); break; case USB_SPEED_HIGH: /* USB core guesses at a 64-byte max packet first for FS devices */ case USB_SPEED_FULL: - ep0_ctx->ep_info2 |= cpu_to_le32(((64 & MAX_PACKET_MASK) << - MAX_PACKET_SHIFT)); + ep0_ctx->ep_info2 |= cpu_to_le32(MAX_PACKET(64)); dev_dbg(&udev->dev, "Setting Packet size = 64bytes\n"); break; case USB_SPEED_LOW: - ep0_ctx->ep_info2 |= cpu_to_le32(((8 & MAX_PACKET_MASK) << - MAX_PACKET_SHIFT)); + ep0_ctx->ep_info2 |= cpu_to_le32(MAX_PACKET(8)); dev_dbg(&udev->dev, "Setting Packet size = 8bytes\n"); break; default: @@ -851,11 +848,9 @@ void xhci_setup_addressable_virt_dev(struct xhci_ctrl *ctrl, } /* EP 0 can handle "burst" sizes of 1, so Max Burst Size field is 0 */ - ep0_ctx->ep_info2 |= - cpu_to_le32(((0 & MAX_BURST_MASK) << MAX_BURST_SHIFT) | - ((3 & ERROR_COUNT_MASK) << ERROR_COUNT_SHIFT)); + ep0_ctx->ep_info2 |= cpu_to_le32(MAX_BURST(0) | ERROR_COUNT(3)); - trb_64 = (uintptr_t)virt_dev->eps[0].ring->first_seg->trbs; + trb_64 = virt_dev->eps[0].ring->first_seg->dma; ep0_ctx->deq = cpu_to_le64(trb_64 | virt_dev->eps[0].ring->cycle_state); /* diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 60764222af..691d9c7463 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -19,12 +19,30 @@ #include <io.h> #include <linux/err.h> #include <linux/sizes.h> -#include <usb/usb.h> -#include <usb/xhci.h> +#include <linux/usb/usb.h> +#include <linux/usb/xhci.h> #include <asm/unaligned.h> #include "xhci.h" +/* + * Returns zero if the TRB isn't in this segment, otherwise it returns the DMA + * address of the TRB. + */ +dma_addr_t xhci_trb_virt_to_dma(struct xhci_segment *seg, + union xhci_trb *trb) +{ + unsigned long segment_offset; + + BUG_ON(!seg || !trb || trb < seg->trbs); + + /* offset in TRBs */ + segment_offset = trb - seg->trbs; + BUG_ON(segment_offset >= TRBS_PER_SEGMENT); + + return seg->dma + (segment_offset * sizeof(*trb)); +} + /** * Is this TRB a link TRB or was the last TRB the last TRB in this event ring * segment? I.e. would the updated event TRB pointer step off the end of the @@ -181,12 +199,11 @@ static void inc_deq(struct xhci_ctrl *ctrl, struct xhci_ring *ring) * @param trb_fields pointer to trb field array containing TRB contents * @return pointer to the enqueued trb */ -static struct xhci_generic_trb *queue_trb(struct xhci_ctrl *ctrl, - struct xhci_ring *ring, - bool more_trbs_coming, - unsigned int *trb_fields) +static dma_addr_t queue_trb(struct xhci_ctrl *ctrl, struct xhci_ring *ring, + bool more_trbs_coming, unsigned int *trb_fields) { struct xhci_generic_trb *trb; + dma_addr_t addr; int i; trb = &ring->enqueue->generic; @@ -196,9 +213,11 @@ static struct xhci_generic_trb *queue_trb(struct xhci_ctrl *ctrl, xhci_flush_cache((uintptr_t)trb, sizeof(struct xhci_generic_trb)); + addr = xhci_trb_virt_to_dma(ring->enq_seg, (union xhci_trb *)trb); + inc_enq(ctrl, ring, more_trbs_coming); - return trb; + return addr; } /** @@ -273,16 +292,15 @@ static int prepare_ring(struct xhci_ctrl *ctrl, struct xhci_ring *ep_ring, * @param cmd Command type to enqueue * @return none */ -void xhci_queue_command(struct xhci_ctrl *ctrl, u8 *ptr, u32 slot_id, +void xhci_queue_command(struct xhci_ctrl *ctrl, dma_addr_t addr, u32 slot_id, u32 ep_index, trb_type cmd) { u32 fields[4]; - u64 val_64 = (uintptr_t)ptr; BUG_ON(prepare_ring(ctrl, ctrl->cmd_ring, EP_STATE_RUNNING)); - fields[0] = lower_32_bits(val_64); - fields[1] = upper_32_bits(val_64); + fields[0] = lower_32_bits(addr); + fields[1] = upper_32_bits(addr); fields[2] = 0; fields[3] = TRB_TYPE(cmd) | SLOT_ID_FOR_TRB(slot_id) | ctrl->cmd_ring->cycle_state; @@ -396,12 +414,15 @@ static void giveback_first_trb(struct usb_device *udev, int ep_index, */ void xhci_acknowledge_event(struct xhci_ctrl *ctrl) { + dma_addr_t deq; + /* Advance our dequeue pointer to the next event */ inc_deq(ctrl, ctrl->event_ring); /* Inform the hardware */ - xhci_writeq(&ctrl->ir_set->erst_dequeue, - (uintptr_t)ctrl->event_ring->dequeue | ERST_EHB); + deq = xhci_trb_virt_to_dma(ctrl->event_ring->deq_seg, + ctrl->event_ring->dequeue); + xhci_writeq(&ctrl->ir_set->erst_dequeue, deq | ERST_EHB); } /** @@ -449,7 +470,8 @@ union xhci_trb *xhci_wait_for_event(struct xhci_ctrl *ctrl, trb_type expected, continue; type = TRB_FIELD_TO_TYPE(le32_to_cpu(event->event_cmd.flags)); - if (type == expected) + if (type == expected || + (expected == TRB_NONE && type != TRB_PORT_STATUS)) return event; if (type == TRB_PORT_STATUS) @@ -461,14 +483,59 @@ union xhci_trb *xhci_wait_for_event(struct xhci_ctrl *ctrl, trb_type expected, BUG_ON(GET_COMP_CODE( le32_to_cpu(event->generic.field[2])) != COMP_SUCCESS); + else + dev_dbg(ctrl->dev, "Unexpected XHCI event TRB, skipping... " + "(%08x %08x %08x %08x)\n", + le32_to_cpu(event->generic.field[0]), + le32_to_cpu(event->generic.field[1]), + le32_to_cpu(event->generic.field[2]), + le32_to_cpu(event->generic.field[3])); + xhci_acknowledge_event(ctrl); } while (!is_timeout_non_interruptible(start, timeout_ms * MSECOND)); if (expected == TRB_TRANSFER) return NULL; - dev_err(ctrl->dev, "XHCI timeout on event type %d... cannot recover.\n", expected); - BUG(); + dev_warn(ctrl->dev, "XHCI timeout on event type %d...\n", expected); + + return NULL; +} + +/* + * Send reset endpoint command for given endpoint. This recovers from a + * halted endpoint (e.g. due to a stall error). + */ +static void reset_ep(struct usb_device *udev, int ep_index, unsigned int timeout_ms) +{ + struct xhci_ctrl *ctrl = xhci_get_ctrl(udev); + struct xhci_ring *ring = ctrl->devs[udev->slot_id]->eps[ep_index].ring; + union xhci_trb *event; + u64 addr; + u32 field; + + dev_info(&udev->dev, "Resetting EP %d...\n", ep_index); + + xhci_queue_command(ctrl, 0, udev->slot_id, ep_index, TRB_RESET_EP); + event = xhci_wait_for_event(ctrl, TRB_COMPLETION, timeout_ms); + if (!event) + return; + + field = le32_to_cpu(event->trans_event.flags); + BUG_ON(TRB_TO_SLOT_ID(field) != udev->slot_id); + xhci_acknowledge_event(ctrl); + + addr = xhci_trb_virt_to_dma(ring->enq_seg, + (void *)((uintptr_t)ring->enqueue | ring->cycle_state)); + xhci_queue_command(ctrl, addr, udev->slot_id, ep_index, TRB_SET_DEQ); + event = xhci_wait_for_event(ctrl, TRB_COMPLETION, timeout_ms); + if (!event) + return; + + BUG_ON(TRB_TO_SLOT_ID(le32_to_cpu(event->event_cmd.flags)) + != udev->slot_id || GET_COMP_CODE(le32_to_cpu( + event->event_cmd.status)) != COMP_SUCCESS); + xhci_acknowledge_event(ctrl); } /* @@ -484,27 +551,49 @@ static void abort_td(struct usb_device *udev, int ep_index) struct xhci_ctrl *ctrl = xhci_get_ctrl(udev); struct xhci_ring *ring = ctrl->devs[udev->slot_id]->eps[ep_index].ring; union xhci_trb *event; + xhci_comp_code comp; + trb_type type; + dma_addr_t addr; u32 field; - xhci_queue_command(ctrl, NULL, udev->slot_id, ep_index, TRB_STOP_RING); + xhci_queue_command(ctrl, 0, udev->slot_id, ep_index, TRB_STOP_RING); - event = xhci_wait_for_event(ctrl, TRB_TRANSFER, XHCI_TIMEOUT_DEFAULT); - field = le32_to_cpu(event->trans_event.flags); - BUG_ON(TRB_TO_SLOT_ID(field) != udev->slot_id); - BUG_ON(TRB_TO_EP_INDEX(field) != ep_index); - BUG_ON(GET_COMP_CODE(le32_to_cpu(event->trans_event.transfer_len - != COMP_STOP))); - xhci_acknowledge_event(ctrl); + event = xhci_wait_for_event(ctrl, TRB_NONE, XHCI_TIMEOUT_DEFAULT); + if (!event) + return; - event = xhci_wait_for_event(ctrl, TRB_COMPLETION, XHCI_TIMEOUT_DEFAULT); - BUG_ON(TRB_TO_SLOT_ID(le32_to_cpu(event->event_cmd.flags)) - != udev->slot_id || GET_COMP_CODE(le32_to_cpu( - event->event_cmd.status)) != COMP_SUCCESS); + type = TRB_FIELD_TO_TYPE(le32_to_cpu(event->event_cmd.flags)); + if (type == TRB_TRANSFER) { + field = le32_to_cpu(event->trans_event.flags); + BUG_ON(TRB_TO_SLOT_ID(field) != udev->slot_id); + BUG_ON(TRB_TO_EP_INDEX(field) != ep_index); + BUG_ON(GET_COMP_CODE(le32_to_cpu(event->trans_event.transfer_len + != COMP_STOP))); + xhci_acknowledge_event(ctrl); + + event = xhci_wait_for_event(ctrl, TRB_COMPLETION, XHCI_TIMEOUT_DEFAULT); + if (!event) + return; + type = TRB_FIELD_TO_TYPE(le32_to_cpu(event->event_cmd.flags)); + + } else { + dev_warn(ctrl->dev, "abort_td: Expected a TRB_TRANSFER TRB first\n"); + } + + comp = GET_COMP_CODE(le32_to_cpu(event->event_cmd.status)); + BUG_ON(type != TRB_COMPLETION || + TRB_TO_SLOT_ID(le32_to_cpu(event->event_cmd.flags)) + != udev->slot_id || (comp != COMP_SUCCESS && comp + != COMP_CTX_STATE)); xhci_acknowledge_event(ctrl); - xhci_queue_command(ctrl, (void *)((uintptr_t)ring->enqueue | - ring->cycle_state), udev->slot_id, ep_index, TRB_SET_DEQ); + addr = xhci_trb_virt_to_dma(ring->enq_seg, ring->enqueue); + addr |= ring->cycle_state; + xhci_queue_command(ctrl, addr, udev->slot_id, ep_index, TRB_SET_DEQ); event = xhci_wait_for_event(ctrl, TRB_COMPLETION, XHCI_TIMEOUT_DEFAULT); + if (!event) + return; + BUG_ON(TRB_TO_SLOT_ID(le32_to_cpu(event->event_cmd.flags)) != udev->slot_id || GET_COMP_CODE(le32_to_cpu( event->event_cmd.status)) != COMP_SUCCESS); @@ -594,7 +683,7 @@ int xhci_bulk_tx(struct usb_device *udev, unsigned long pipe, memcpy(bounce, buffer, length); } - map = addr = dma_map_single(ctrl->dev, bounce, length, direction); + map = addr = dma_map_single(ctrl->host.hw_dev, bounce, length, direction); dev_dbg(&udev->dev, "pipe=0x%lx, buffer=%p, length=%d\n", pipe, buffer, length); @@ -607,6 +696,14 @@ int xhci_bulk_tx(struct usb_device *udev, unsigned long pipe, ep_ctx = xhci_get_ep_ctx(ctrl, virt_dev->out_ctx, ep_index); + /* + * If the endpoint was halted due to a prior error, resume it before + * the next transfer. It is the responsibility of the upper layer to + * have dealt with whatever caused the error. + */ + if ((le32_to_cpu(ep_ctx->ep_info) & EP_STATE_MASK) == EP_STATE_HALTED) + reset_ep(udev, ep_index, timeout_ms); + ring = virt_dev->eps[ep_index].ring; /* * How much data is (potentially) left before the 64KB boundary? @@ -639,8 +736,10 @@ int xhci_bulk_tx(struct usb_device *udev, unsigned long pipe, */ ret = prepare_ring(ctrl, ring, le32_to_cpu(ep_ctx->ep_info) & EP_STATE_MASK); - if (ret < 0) + if (ret < 0) { + dma_unmap_single(ctrl->host.hw_dev, map, length, direction); return ret; + } /* * Don't give the first TRB to the hardware (by toggling the cycle bit) @@ -660,6 +759,9 @@ int xhci_bulk_tx(struct usb_device *udev, unsigned long pipe, first_trb = true; + /* flush the buffer before use */ + xhci_flush_cache((uintptr_t)buffer, length); + /* Queue the first TRB, even if it's zero-length */ do { u32 remainder = 0; @@ -696,15 +798,14 @@ int xhci_bulk_tx(struct usb_device *udev, unsigned long pipe, maxpacketsize, num_trbs - 1); - length_field = ((trb_buff_len & TRB_LEN_MASK) | + length_field = (TRB_LEN(trb_buff_len) | remainder | - ((0 & TRB_INTR_TARGET_MASK) << - TRB_INTR_TARGET_SHIFT)); + TRB_INTR_TARGET(0)); trb_fields[0] = lower_32_bits(addr); trb_fields[1] = upper_32_bits(addr); trb_fields[2] = length_field; - trb_fields[3] = field | (TRB_NORMAL << TRB_TYPE_SHIFT); + trb_fields[3] = field | TRB_TYPE(TRB_NORMAL); queue_trb(ctrl, ring, (num_trbs > 1), trb_fields); @@ -725,6 +826,7 @@ int xhci_bulk_tx(struct usb_device *udev, unsigned long pipe, abort_td(udev, ep_index); udev->status = USB_ST_NAK_REC; /* closest thing to a timeout */ udev->act_len = 0; + dma_unmap_single(ctrl->host.hw_dev, map, length, direction); return -ETIMEDOUT; } field = le32_to_cpu(event->trans_event.flags); @@ -740,7 +842,7 @@ int xhci_bulk_tx(struct usb_device *udev, unsigned long pipe, record_transfer_result(udev, event, length); xhci_acknowledge_event(ctrl); - dma_unmap_single(ctrl->dev, map, length, direction); + dma_unmap_single(ctrl->host.hw_dev, map, length, direction); if (usb_pipein(pipe)) memcpy(buffer, bounce, length); @@ -839,7 +941,7 @@ int xhci_ctrl_tx(struct usb_device *udev, unsigned long pipe, /* Queue setup TRB - see section 6.4.1.2.1 */ /* FIXME better way to translate setup_packet into two u32 fields? */ field = 0; - field |= TRB_IDT | (TRB_SETUP << TRB_TYPE_SHIFT); + field |= TRB_IDT | TRB_TYPE(TRB_SETUP); if (start_cycle == 0) field |= 0x1; @@ -847,9 +949,9 @@ int xhci_ctrl_tx(struct usb_device *udev, unsigned long pipe, if (HC_VERSION(xhci_readl(&ctrl->hccr->cr_capbase)) >= 0x100) { if (length > 0) { if (req->requesttype & USB_DIR_IN) - field |= (TRB_DATA_IN << TRB_TX_TYPE_SHIFT); + field |= TRB_TX_TYPE(TRB_DATA_IN); else - field |= (TRB_DATA_OUT << TRB_TX_TYPE_SHIFT); + field |= TRB_TX_TYPE(TRB_DATA_OUT); } } @@ -865,8 +967,7 @@ int xhci_ctrl_tx(struct usb_device *udev, unsigned long pipe, trb_fields[1] = le16_to_cpu(req->index) | le16_to_cpu(req->length) << 16; /* TRB_LEN | (TRB_INTR_TARGET) */ - trb_fields[2] = (8 | ((0 & TRB_INTR_TARGET_MASK) << - TRB_INTR_TARGET_SHIFT)); + trb_fields[2] = (TRB_LEN(8) | TRB_INTR_TARGET(0)); /* Immediate data in pointer */ trb_fields[3] = field; queue_trb(ctrl, ep_ring, true, trb_fields); @@ -876,15 +977,15 @@ int xhci_ctrl_tx(struct usb_device *udev, unsigned long pipe, /* If there's data, queue data TRBs */ /* Only set interrupt on short packet for IN endpoints */ if (usb_pipein(pipe)) - field = TRB_ISP | (TRB_DATA << TRB_TYPE_SHIFT); + field = TRB_ISP | TRB_TYPE(TRB_DATA); else - field = (TRB_DATA << TRB_TYPE_SHIFT); + field = TRB_TYPE(TRB_DATA); - length_field = (length & TRB_LEN_MASK) | xhci_td_remainder(length) | + length_field = TRB_LEN(length) | xhci_td_remainder(length) | ((0 & TRB_INTR_TARGET_MASK) << TRB_INTR_TARGET_SHIFT); dev_dbg(&udev->dev, "length_field = %d, length = %d," "xhci_td_remainder(length) = %d , TRB_INTR_TARGET(0) = %d\n", - length_field, (length & TRB_LEN_MASK), + length_field, TRB_LEN(length), xhci_td_remainder(length), 0); if (req->requesttype & USB_DIR_IN) @@ -895,13 +996,14 @@ int xhci_ctrl_tx(struct usb_device *udev, unsigned long pipe, if (length > 0) { if (req->requesttype & USB_DIR_IN) field |= TRB_DIR_IN; - map = buf_64 = dma_map_single(ctrl->dev, buffer, length, direction); + map = buf_64 = dma_map_single(ctrl->host.hw_dev, buffer, length, direction); trb_fields[0] = lower_32_bits(buf_64); trb_fields[1] = upper_32_bits(buf_64); trb_fields[2] = length_field; trb_fields[3] = field | ep_ring->cycle_state; + xhci_flush_cache((uintptr_t)buffer, length); queue_trb(ctrl, ep_ring, true, trb_fields); } @@ -919,11 +1021,10 @@ int xhci_ctrl_tx(struct usb_device *udev, unsigned long pipe, trb_fields[0] = 0; trb_fields[1] = 0; - trb_fields[2] = ((0 & TRB_INTR_TARGET_MASK) << TRB_INTR_TARGET_SHIFT); + trb_fields[2] = TRB_INTR_TARGET(0); /* Event on completion */ trb_fields[3] = field | TRB_IOC | - (TRB_STATUS << TRB_TYPE_SHIFT) | - ep_ring->cycle_state; + TRB_TYPE(TRB_STATUS) | ep_ring->cycle_state; queue_trb(ctrl, ep_ring, false, trb_fields); @@ -947,7 +1048,12 @@ int xhci_ctrl_tx(struct usb_device *udev, unsigned long pipe, /* Invalidate buffer to make it available to usb-core */ if (length > 0) - dma_unmap_single(ctrl->dev, map, length, direction); + dma_unmap_single(ctrl->host.hw_dev, map, length, direction); + + if (udev->status == USB_ST_STALLED) { + reset_ep(udev, ep_index, timeout_ms); + return -EPIPE; + } if (GET_COMP_CODE(le32_to_cpu(event->trans_event.transfer_len)) == COMP_SHORT_TX) { @@ -967,5 +1073,6 @@ abort: abort_td(udev, ep_index); udev->status = USB_ST_NAK_REC; udev->act_len = 0; + dma_unmap_single(ctrl->host.hw_dev, map, length, direction); return -ETIMEDOUT; } diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index ce93d345f9..e7b8344181 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -24,13 +24,13 @@ #include <init.h> #include <io.h> #include <linux/err.h> -#include <usb/usb.h> -#include <usb/xhci.h> +#include <linux/usb/usb.h> +#include <linux/usb/xhci.h> #include <asm/unaligned.h> #include "xhci.h" -static struct descriptor { +static const struct descriptor { struct usb_hub_descriptor hub; struct usb_device_descriptor device; struct usb_config_descriptor config; @@ -151,6 +151,8 @@ static int xhci_start(struct xhci_ctrl *ctrl) u32 temp; int ret; + dev_dbg(ctrl->dev, "Starting the controller\n"); + temp = xhci_readl(&hcor->or_usbcmd); temp |= (CMD_RUN); xhci_writel(&hcor->or_usbcmd, temp); @@ -441,9 +443,12 @@ static int xhci_configure_endpoints(struct usb_device *udev, bool ctx_change) in_ctx = virt_dev->in_ctx; xhci_flush_cache((uintptr_t)in_ctx->bytes, in_ctx->size); - xhci_queue_command(ctrl, in_ctx->bytes, udev->slot_id, 0, + xhci_queue_command(ctrl, in_ctx->dma, udev->slot_id, 0, ctx_change ? TRB_EVAL_CONTEXT : TRB_CONFIG_EP); event = xhci_wait_for_event(ctrl, TRB_COMPLETION, XHCI_TIMEOUT_DEFAULT); + if (!event) + return -ETIMEDOUT; + BUG_ON(TRB_TO_SLOT_ID(le32_to_cpu(event->event_cmd.flags)) != udev->slot_id); @@ -566,8 +571,7 @@ static int xhci_set_configuration(struct usb_device *udev) cpu_to_le32(EP_MAX_ESIT_PAYLOAD_HI(max_esit_payload) | EP_INTERVAL(interval) | EP_MULT(mult)); - ep_ctx[ep_index]->ep_info2 = - cpu_to_le32(ep_type << EP_TYPE_SHIFT); + ep_ctx[ep_index]->ep_info2 = cpu_to_le32(EP_TYPE(ep_type)); ep_ctx[ep_index]->ep_info2 |= cpu_to_le32(MAX_PACKET (get_unaligned(&endpt_desc->wMaxPacketSize))); @@ -579,8 +583,8 @@ static int xhci_set_configuration(struct usb_device *udev) cpu_to_le32(MAX_BURST(max_burst) | ERROR_COUNT(err_count)); - trb_64 = (uintptr_t) - virt_dev->eps[ep_index].ring->enqueue; + trb_64 = xhci_trb_virt_to_dma(virt_dev->eps[ep_index].ring->enq_seg, + virt_dev->eps[ep_index].ring->enqueue); ep_ctx[ep_index]->deq = cpu_to_le64(trb_64 | virt_dev->eps[ep_index].ring->cycle_state); @@ -628,8 +632,12 @@ static int xhci_address_device(struct usb_device *udev, int root_portnr) ctrl_ctx->add_flags = cpu_to_le32(SLOT_FLAG | EP0_FLAG); ctrl_ctx->drop_flags = 0; - xhci_queue_command(ctrl, (void *)ctrl_ctx, slot_id, 0, TRB_ADDR_DEV); + xhci_queue_command(ctrl, virt_dev->in_ctx->dma, + slot_id, 0, TRB_ADDR_DEV); event = xhci_wait_for_event(ctrl, TRB_COMPLETION, XHCI_TIMEOUT_DEFAULT); + if (!event) + return -ETIMEDOUT; + BUG_ON(TRB_TO_SLOT_ID(le32_to_cpu(event->event_cmd.flags)) != slot_id); switch (GET_COMP_CODE(le32_to_cpu(event->event_cmd.status))) { @@ -703,8 +711,11 @@ static int _xhci_alloc_device(struct usb_device *udev) return 0; } - xhci_queue_command(ctrl, NULL, 0, 0, TRB_ENABLE_SLOT); + xhci_queue_command(ctrl, 0, 0, 0, TRB_ENABLE_SLOT); event = xhci_wait_for_event(ctrl, TRB_COMPLETION, XHCI_TIMEOUT_DEFAULT); + if (!event) + return -ETIMEDOUT; + BUG_ON(GET_COMP_CODE(le32_to_cpu(event->event_cmd.status)) != COMP_SUCCESS); @@ -764,8 +775,7 @@ int xhci_check_maxpacket(struct usb_device *udev) ctrl->devs[slot_id]->out_ctx, ep_index); in_ctx = ctrl->devs[slot_id]->in_ctx; ep_ctx = xhci_get_ep_ctx(ctrl, in_ctx, ep_index); - ep_ctx->ep_info2 &= cpu_to_le32(~((0xffff & MAX_PACKET_MASK) - << MAX_PACKET_SHIFT)); + ep_ctx->ep_info2 &= cpu_to_le32(~MAX_PACKET(MAX_PACKET_MASK)); ep_ctx->ep_info2 |= cpu_to_le32(MAX_PACKET(max_packet_size)); /* @@ -860,7 +870,7 @@ static int xhci_submit_root(struct usb_device *udev, unsigned long pipe, { uint8_t tmpbuf[4]; u16 typeReq; - void *srcptr = NULL; + const void *srcptr = NULL; int len, srclen; uint32_t reg; volatile uint32_t *status_reg; @@ -928,7 +938,7 @@ static int xhci_submit_root(struct usb_device *udev, unsigned long pipe, case USB_DT_HUB: case USB_DT_SS_HUB: dev_dbg(&udev->dev, "USB_DT_HUB config\n"); - srcptr = &descriptor.hub; + srcptr = &ctrl->hub_desc; srclen = 0x8; break; default: @@ -1088,8 +1098,10 @@ unknown: static int _xhci_submit_int_msg(struct usb_device *udev, unsigned long pipe, void *buffer, int length, int interval) { - if (usb_pipetype(pipe) != PIPE_INTERRUPT) + if (usb_pipetype(pipe) != PIPE_INTERRUPT) { + dev_err(&udev->dev, "non-interrupt pipe (type=%lu)", usb_pipetype(pipe)); return -EINVAL; + } /* * xHCI uses normal TRBs for both bulk and interrupt. When the @@ -1112,8 +1124,10 @@ static int _xhci_submit_int_msg(struct usb_device *udev, unsigned long pipe, static int _xhci_submit_bulk_msg(struct usb_device *udev, unsigned long pipe, void *buffer, int length, int timeout_ms) { - if (usb_pipetype(pipe) != PIPE_BULK) + if (usb_pipetype(pipe) != PIPE_BULK) { + dev_err(&udev->dev, "non-bulk pipe (type=%lu)", usb_pipetype(pipe)); return -EINVAL; + } return xhci_bulk_tx(udev, pipe, length, buffer, timeout_ms); } @@ -1137,8 +1151,10 @@ static int _xhci_submit_control_msg(struct usb_device *udev, unsigned long pipe, struct xhci_ctrl *ctrl = xhci_get_ctrl(udev); int ret = 0; - if (usb_pipetype(pipe) != PIPE_CONTROL) + if (usb_pipetype(pipe) != PIPE_CONTROL) { + dev_err(&udev->dev, "non-control pipe (type=%lu)", usb_pipetype(pipe)); return -EINVAL; + } if (usb_pipedevice(pipe) == ctrl->rootdev) return xhci_submit_root(udev, pipe, buffer, setup); @@ -1181,21 +1197,23 @@ static int xhci_lowlevel_init(struct xhci_ctrl *ctrl) /* initializing xhci data structures */ if (xhci_mem_init(ctrl, hccr, hcor) < 0) return -ENOMEM; + ctrl->hub_desc = descriptor.hub; reg = xhci_readl(&hccr->cr_hcsparams1); - descriptor.hub.bNbrPorts = ((reg & HCS_MAX_PORTS_MASK) >> - HCS_MAX_PORTS_SHIFT); + ctrl->hub_desc.bNbrPorts = HCS_MAX_PORTS(reg); + + dev_dbg(ctrl->dev, "Register 0x%x NbrPorts %d\n", reg, ctrl->hub_desc.bNbrPorts); /* Port Indicators */ reg = xhci_readl(&hccr->cr_hccparams); if (HCS_INDICATOR(reg)) - put_unaligned(get_unaligned(&descriptor.hub.wHubCharacteristics) - | 0x80, &descriptor.hub.wHubCharacteristics); + put_unaligned(get_unaligned(&ctrl->hub_desc.wHubCharacteristics) + | 0x80, &ctrl->hub_desc.wHubCharacteristics); /* Port Power Control */ if (HCC_PPC(reg)) - put_unaligned(get_unaligned(&descriptor.hub.wHubCharacteristics) - | 0x01, &descriptor.hub.wHubCharacteristics); + put_unaligned(get_unaligned(&ctrl->hub_desc.wHubCharacteristics) + | 0x01, &ctrl->hub_desc.wHubCharacteristics); if (xhci_start(ctrl)) { xhci_reset(ctrl); @@ -1218,6 +1236,8 @@ static int xhci_lowlevel_stop(struct xhci_ctrl *ctrl) xhci_reset(ctrl); + dev_dbg(ctrl->dev, "Disabling event ring interrupts\n"); + temp = xhci_readl(&ctrl->hcor->or_usbsts); xhci_writel(&ctrl->hcor->or_usbsts, temp & ~STS_EINT); temp = xhci_readl(&ctrl->ir_set->irq_pending); @@ -1344,7 +1364,7 @@ static __maybe_unused int xhci_get_max_xfer_size(size_t *size) int xhci_register(struct xhci_ctrl *ctrl) { struct usb_host *host; - struct device_d *dev = ctrl->dev; + struct device *dev = ctrl->dev; int ret; dev_dbg(dev, "%s: hccr=%p, hcor=%p\n", __func__, ctrl->hccr, ctrl->hcor); @@ -1359,7 +1379,11 @@ int xhci_register(struct xhci_ctrl *ctrl) */ host->no_desc_before_addr = true; - host->hw_dev = dev; + /* + * If xHCI doesn't have its own DT node, it'll be a child of a + * physical USB host controller device that should be used for DMA + */ + host->hw_dev = dev_of_node(dev) ? dev : dev->parent; host->submit_int_msg = xhci_submit_int_msg; host->submit_control_msg = xhci_submit_control_msg; host->submit_bulk_msg = xhci_submit_bulk_msg; @@ -1394,7 +1418,7 @@ int xhci_deregister(struct xhci_ctrl *ctrl) * xHCI platform driver */ -static int xhci_probe(struct device_d *dev) +static int xhci_probe(struct device *dev) { struct resource *iores; struct xhci_ctrl *ctrl; @@ -1415,14 +1439,14 @@ static int xhci_probe(struct device_d *dev) return xhci_register(ctrl); } -static void xhci_remove(struct device_d *dev) +static void xhci_remove(struct device *dev) { struct xhci_ctrl *ctrl = dev->priv; xhci_deregister(ctrl); } -static struct driver_d xhci_driver = { +static struct driver xhci_driver = { .name = "xHCI", .probe = xhci_probe, .remove = xhci_remove, diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index e445438e81..37e8cee843 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -16,7 +16,7 @@ #ifndef HOST_XHCI_H_ #define HOST_XHCI_H_ -#include <asm/types.h> +#include <linux/types.h> #include <io.h> #include <io-64-nonatomic-lo-hi.h> #include <linux/list.h> @@ -30,8 +30,8 @@ /* Section 5.3.3 - MaxPorts */ #define MAX_HC_PORTS 255 -/* Up to 16 ms to halt an HC */ -#define XHCI_MAX_HALT_USEC (16*1000) +/* Up to 32 ms to halt an HC */ +#define XHCI_MAX_HALT_USEC (32*1000) #define XHCI_MAX_RESET_USEC (250*1000) @@ -490,6 +490,7 @@ struct xhci_container_ctx { int size; u8 *bytes; + dma_addr_t dma; }; /** @@ -691,6 +692,8 @@ struct xhci_input_control_ctx { struct xhci_device_context_array { /* 64-bit device addresses; we only write 32-bit addresses */ __le64 dev_context_ptrs[MAX_HC_SLOTS]; + /* private xHCD pointers */ + dma_addr_t dma; }; /* TODO: write function to set the 64-bit device DMA address */ /* @@ -903,6 +906,8 @@ union xhci_trb { /* TRB type IDs */ typedef enum { + /* reserved, used as a software sentinel */ + TRB_NONE = 0, /* bulk, interrupt, isoc scatter/gather, and control data stage */ TRB_NORMAL = 1, /* setup stage for control transfers */ @@ -1003,6 +1008,7 @@ struct xhci_segment { union xhci_trb *trbs; /* private to HCD */ struct xhci_segment *next; + dma_addr_t dma; }; struct xhci_ring { @@ -1031,11 +1037,14 @@ struct xhci_erst_entry { struct xhci_erst { struct xhci_erst_entry *entries; unsigned int num_entries; + /* xhci->event_ring keeps track of segment dma addresses */ + dma_addr_t erst_dma_addr; /* Num entries the ERST can contain */ unsigned int erst_size; }; struct xhci_scratchpad { + void *scratchpad; u64 *sp_array; }; @@ -1134,8 +1143,6 @@ void xhci_hcd_stop(int index); /************************************************************* EXTENDED CAPABILITY DEFINITIONS *************************************************************/ -/* Up to 16 ms to halt an HC */ -#define XHCI_MAX_HALT_USEC (16*1000) /* HC not running - set to 1 when run/stop bit is cleared. */ #define XHCI_STS_HALT (1 << 0) @@ -1203,7 +1210,7 @@ void xhci_hcd_stop(int index); struct xhci_ctrl { struct usb_host host; - struct device_d *dev; + struct device *dev; struct xhci_hccr *hccr; /* R/O registers, not need for volatile */ struct xhci_hcor *hcor; struct xhci_doorbell_array *dba; @@ -1218,6 +1225,7 @@ struct xhci_ctrl { struct xhci_erst_entry entry[ERST_NUM_SEGS]; struct xhci_scratchpad *scratchpad; struct xhci_virt_device *devs[MAX_HC_SLOTS]; + struct usb_hub_descriptor hub_desc; void *bounce_buffer; int rootdev; }; @@ -1227,7 +1235,7 @@ static inline struct xhci_ctrl *to_xhci(struct usb_host *host) return container_of(host, struct xhci_ctrl, host); } -unsigned long trb_addr(struct xhci_segment *seg, union xhci_trb *trb); +dma_addr_t xhci_trb_virt_to_dma(struct xhci_segment *seg, union xhci_trb *trb); struct xhci_input_control_ctx *xhci_get_input_control_ctx(struct xhci_container_ctx *ctx); struct xhci_slot_ctx *xhci_get_slot_ctx(struct xhci_ctrl *ctrl, @@ -1244,7 +1252,7 @@ void xhci_slot_copy(struct xhci_ctrl *ctrl, struct xhci_container_ctx *out_ctx); void xhci_setup_addressable_virt_dev(struct xhci_ctrl *ctrl, struct usb_device *udev, int hop_portnr); -void xhci_queue_command(struct xhci_ctrl *ctrl, u8 *ptr, +void xhci_queue_command(struct xhci_ctrl *ctrl, dma_addr_t addr, u32 slot_id, u32 ep_index, trb_type cmd); void xhci_acknowledge_event(struct xhci_ctrl *ctrl); #define XHCI_TIMEOUT_DEFAULT 5000 |