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 <burzalod...@gmail.com>
---

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 majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to