diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index 289461c06bf9..019dac47c5d6 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -877,8 +877,8 @@ void xhci_free_virt_device(struct xhci_hcd *xhci, struct xhci_virt_device *dev, /* If device ctx array still points to _this_ device, clear it */ if (dev->out_ctx && - xhci->dcbaa->dev_context_ptrs[slot_id] == cpu_to_le64(dev->out_ctx->dma)) - xhci->dcbaa->dev_context_ptrs[slot_id] = 0; + xhci->dcbaa.ctx_array[slot_id] == cpu_to_le64(dev->out_ctx->dma)) + xhci->dcbaa.ctx_array[slot_id] = 0; trace_xhci_free_virt_device(dev); @@ -1016,11 +1016,11 @@ int xhci_alloc_virt_device(struct xhci_hcd *xhci, int slot_id, dev->udev = udev; /* Point to output device context in dcbaa. */ - xhci->dcbaa->dev_context_ptrs[slot_id] = cpu_to_le64(dev->out_ctx->dma); + xhci->dcbaa.ctx_array[slot_id] = cpu_to_le64(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[slot_id], - le64_to_cpu(xhci->dcbaa->dev_context_ptrs[slot_id])); + &xhci->dcbaa.ctx_array[slot_id], + le64_to_cpu(xhci->dcbaa.ctx_array[slot_id])); trace_xhci_alloc_virt_device(dev); @@ -1671,7 +1671,7 @@ static int scratchpad_alloc(struct xhci_hcd *xhci, gfp_t flags) if (!xhci->scratchpad->sp_buffers) goto fail_sp3; - xhci->dcbaa->dev_context_ptrs[0] = cpu_to_le64(xhci->scratchpad->sp_dma); + xhci->dcbaa.ctx_array[0] = cpu_to_le64(xhci->scratchpad->sp_dma); for (i = 0; i < num_sp; i++) { dma_addr_t dma; void *buf = dma_alloc_coherent(dev, xhci->page_size, &dma, @@ -1927,6 +1927,7 @@ void xhci_rh_bw_cleanup(struct xhci_hcd *xhci) void xhci_mem_cleanup(struct xhci_hcd *xhci) { struct device *dev = xhci_to_hcd(xhci)->self.sysdev; + struct xhci_device_context_array *dcbaa; int i; cancel_delayed_work_sync(&xhci->cmd_timer); @@ -1972,10 +1973,12 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci) xhci_dbg_trace(xhci, trace_xhci_dbg_init, "Freed medium stream array pool"); - if (xhci->dcbaa) - dma_free_coherent(dev, sizeof(*xhci->dcbaa), - xhci->dcbaa, xhci->dcbaa->dma); - xhci->dcbaa = NULL; + dcbaa = &xhci->dcbaa; + if (dcbaa->ctx_array) { + dma_free_coherent(dev, array_size(sizeof(*dcbaa->ctx_array), MAX_HC_SLOTS), + dcbaa->ctx_array, dcbaa->dma); + dcbaa->ctx_array = NULL; + } scratchpad_free(xhci); @@ -2403,23 +2406,20 @@ EXPORT_SYMBOL_GPL(xhci_create_secondary_interrupter); int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) { - struct device *dev = xhci_to_hcd(xhci)->self.sysdev; - dma_addr_t dma; + struct device *dev = xhci_to_hcd(xhci)->self.sysdev; + struct xhci_device_context_array *dcbaa = &xhci->dcbaa; xhci_dbg_trace(xhci, trace_xhci_dbg_init, "Starting %s", __func__); - /* - * xHCI section 5.4.6 - Device Context array must be - * "physically contiguous and 64-byte (cache line) aligned". - */ - xhci->dcbaa = dma_alloc_coherent(dev, sizeof(*xhci->dcbaa), &dma, flags); - if (!xhci->dcbaa) + dcbaa->ctx_array = + dma_alloc_coherent(dev, array_size(sizeof(*dcbaa->ctx_array), MAX_HC_SLOTS), + &dcbaa->dma, flags); + if (!dcbaa->ctx_array) goto fail; - xhci->dcbaa->dma = dma; xhci_dbg_trace(xhci, trace_xhci_dbg_init, "Device context base array address = %pad (DMA), %p (virt)", - &xhci->dcbaa->dma, xhci->dcbaa); + &dcbaa->dma, dcbaa->ctx_array); /* * Initialize the ring segment pool. The ring must be a contiguous diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 83209db29962..3c304372bad3 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -1613,7 +1613,7 @@ static void xhci_handle_cmd_disable_slot(struct xhci_hcd *xhci, int slot_id, /* Delete default control endpoint resources */ xhci_free_device_endpoint_resources(xhci, virt_dev, true); if (cmd_comp_code == COMP_SUCCESS) { - xhci->dcbaa->dev_context_ptrs[slot_id] = 0; + xhci->dcbaa.ctx_array[slot_id] = 0; xhci->devs[slot_id] = NULL; } } diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 0646fedf2042..14d7f866f220 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -551,7 +551,7 @@ static void xhci_init(struct usb_hcd *hcd) 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); + xhci_write_64(xhci, xhci->dcbaa.dma, &xhci->op_regs->dcbaa_ptr); /* Set Doorbell array pointer */ xhci_set_doorbell_ptr(xhci); @@ -4457,9 +4457,9 @@ static int xhci_setup_device(struct usb_hcd *hcd, struct usb_device *udev, xhci_dbg_trace(xhci, trace_xhci_dbg_address, "Slot ID %d dcbaa entry @%p = %#016llx", udev->slot_id, - &xhci->dcbaa->dev_context_ptrs[udev->slot_id], + &xhci->dcbaa.ctx_array[udev->slot_id], (unsigned long long) - le64_to_cpu(xhci->dcbaa->dev_context_ptrs[udev->slot_id])); + le64_to_cpu(xhci->dcbaa.ctx_array[udev->slot_id])); xhci_dbg_trace(xhci, trace_xhci_dbg_address, "Output Context DMA address = %#08llx", (unsigned long long)virt_dev->out_ctx->dma); diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index e73c498449e8..9d57def08ea6 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -792,12 +792,15 @@ struct xhci_tt_bw_info { /** * struct xhci_device_context_array - * @dev_context_ptr array of 64-bit DMA addresses for device contexts + * @ctx_array: Pointer to an array of addresses + * @dma: DMA address to @ctx_array + * + * Device Context Base Address Array (DCBAA) - Section 6.1. + * ctx_array[0]: Scratchpad Buffer Array Base Address + * ctx_array[1-MaxSlots]: Device Context Base Address */ 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 */ + __le64 *ctx_array; dma_addr_t dma; }; /* @@ -1531,7 +1534,7 @@ struct xhci_hcd { /* optional reset controller */ struct reset_control *reset; /* data structures */ - struct xhci_device_context_array *dcbaa; + struct xhci_device_context_array dcbaa; struct xhci_interrupter **interrupters; struct xhci_ring *cmd_ring; unsigned int cmd_ring_state;