This patch adds a check on whether the host machine supports the xHC DMA address mask and sets the DMA mask for coherent DMA address allocation via an explicit call to dma_set_coherent_mask(). According to DMA-API-HOWTO, if coherent DMA address mask has not been set explicitly via dma_set_coherent_mask(), and the driver calls dma_alloc_coherent() or dma_pool_create() to allocate consistent DMA memory blocks, the consistent DMA mapping interface will return by default DMA addresses which are 32-bit addressable. Hence, if 64-bit DMA mapping is supported, it is appropriate to call dma_set_coherent_mask() with DMA_BIT_MASK(64) to take advantage of it. Also, according to DMA-API-HOWTO, dma_set_coherent_mask() is guaranteed to set successfully the same or a smaller mask as dma_set_mask(). Signed-off-by: Xenia Ragiadakou <burzalodowa@xxxxxxxxx> --- Changes from v1: fix of the following checkpatch warning, triggered in v1 WARNING: line over 80 characters drivers/usb/host/xhci.c | 33 +++++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index b4aa79d..2167b98 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -4662,11 +4662,22 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks) */ xhci = hcd_to_xhci(hcd); temp = xhci_readl(xhci, &xhci->cap_regs->hcc_params); - if (HCC_64BIT_ADDR(temp)) { + /* + * Check if host machine supports 64 bit DMA address mask + * and enable it for both streaming and coherent DMA transfers. + * Otherwise, use 32bit DMA mask, if it is supported. + */ + if (HCC_64BIT_ADDR(temp) && + !dma_set_mask(hcd->self.controller, DMA_BIT_MASK(64))) { xhci_dbg(xhci, "Enabling 64-bit DMA addresses.\n"); - dma_set_mask(hcd->self.controller, DMA_BIT_MASK(64)); + dma_set_coherent_mask(hcd->self.controller, + DMA_BIT_MASK(64)); } else { - dma_set_mask(hcd->self.controller, DMA_BIT_MASK(32)); + if (dma_set_mask(hcd->self.controller, + DMA_BIT_MASK(32))) + goto error; + dma_set_coherent_mask(hcd->self.controller, + DMA_BIT_MASK(32)); } return 0; } @@ -4700,11 +4711,21 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks) xhci_dbg(xhci, "Reset complete\n"); temp = xhci_readl(xhci, &xhci->cap_regs->hcc_params); - if (HCC_64BIT_ADDR(temp)) { + /* + * Check if host machine supports 64 bit DMA address mask + * and enable it for both streaming and coherent DMA transfers. + * Otherwise, use 32bit DMA mask, if it is supported. + */ + if (HCC_64BIT_ADDR(temp) && + !dma_set_mask(hcd->self.controller, DMA_BIT_MASK(64))) { xhci_dbg(xhci, "Enabling 64-bit DMA addresses.\n"); - dma_set_mask(hcd->self.controller, DMA_BIT_MASK(64)); + dma_set_coherent_mask(hcd->self.controller, + DMA_BIT_MASK(64)); } else { - dma_set_mask(hcd->self.controller, DMA_BIT_MASK(32)); + if (dma_set_mask(hcd->self.controller, DMA_BIT_MASK(32))) + goto error; + dma_set_coherent_mask(hcd->self.controller, + DMA_BIT_MASK(32)); } xhci_dbg(xhci, "Calling HCD init\n"); -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html