[RFC v5] xhci: fix dma mask setup in xhci.c

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The function dma_set_mask() tests internally whether the dma_mask pointer
for the device is initialized and fails if the dma_mask pointer is NULL.
On pci platforms, the device dma_mask pointer is initialized, when pci
devices are enumerated, to point to the pci_dev->dma_mask which is 0xffffffff.
However, for non-pci platforms, the dma_mask pointer may not be initialized
and in that case dma_set_mask() will fail.

This patch initializes the dma_mask and the coherent_dma_mask to 32bits
in xhci_plat_probe(), before the call to usb_create_hcd() that sets the
"uses_dma" flag for the usb bus and the call to usb_add_hcd() that creates
coherent dma pools for the usb hcd.

Moreover, a call to dma_set_mask() does not set the device coherent_dma_mask.
Since the xhci-hcd driver calls dma_alloc_coherent() and dma_pool_alloc()
to allocate consistent DMA memory blocks, the coherent DMA address mask
has to be set explicitly.

This patch sets the coherent_dma_mask to 64bits in xhci_gen_setup() when
the xHC is capable for 64-bit DMA addressing.

If dma_set_mask() succeeds, for a given bitmask, it is guaranteed that
the given bitmask is also supported for consistent DMA mappings.

Other changes introduced in this patch are:

- The return value of dma_set_mask() is checked to ensure that the required
  dma bitmask conforms with the host system's addressing capabilities.

- The dma_mask setup code for the non-primary hcd was removed since both
  primary and non-primary hcd refer to the same generic device whose
  dma_mask and coherent_dma_mask are already set during the setup of
  the primary hcd.

- The code for reading the HCCPARAMS register to find out the addressing
  capabilities of xHC was removed since its value is already cached in
  xhci->hccparams.

- hcd->self.controller was replaced with the dev variable since it is
  already available.

Signed-off-by: Xenia Ragiadakou <burzalodowa@xxxxxxxxx>
---

Differences from version 4:

- Change the initialization code in xhci_plat_probe() to avoid
  unnecessary second assignment of the dma_mask if the dma_mask
  pointer is initialized to point to the coherent_dma_mask.

- Use dma_set_coherent_mask() instead of assigning directly to
  the coherent_dma_mask.

 drivers/usb/host/xhci-plat.c |  9 +++++++++
 drivers/usb/host/xhci.c      | 19 +++++--------------
 2 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c
index 51e22bf..1d83a7a 100644
--- a/drivers/usb/host/xhci-plat.c
+++ b/drivers/usb/host/xhci-plat.c
@@ -104,6 +104,15 @@ static int xhci_plat_probe(struct platform_device *pdev)
 	if (!res)
 		return -ENODEV;
 
+	/* Initialize dma_mask and coherent_dma_mask to 32-bits */
+	ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
+	if (ret)
+		return ret;
+	if (!pdev->dev.dma_mask)
+		pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
+	else
+		dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
+
 	hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev));
 	if (!hcd)
 		return -ENOMEM;
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index bef1e77..6daf439 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -4804,7 +4804,6 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks)
 	struct xhci_hcd		*xhci;
 	struct device		*dev = hcd->self.controller;
 	int			retval;
-	u32			temp;
 
 	/* Accept arbitrarily long scatter-gather lists */
 	hcd->self.sg_tablesize = ~0;
@@ -4832,14 +4831,6 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks)
 		/* xHCI private pointer was set in xhci_pci_probe for the second
 		 * registered roothub.
 		 */
-		xhci = hcd_to_xhci(hcd);
-		temp = xhci_readl(xhci, &xhci->cap_regs->hcc_params);
-		if (HCC_64BIT_ADDR(temp)) {
-			xhci_dbg(xhci, "Enabling 64-bit DMA addresses.\n");
-			dma_set_mask(hcd->self.controller, DMA_BIT_MASK(64));
-		} else {
-			dma_set_mask(hcd->self.controller, DMA_BIT_MASK(32));
-		}
 		return 0;
 	}
 
@@ -4871,12 +4862,12 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks)
 		goto error;
 	xhci_dbg(xhci, "Reset complete\n");
 
-	temp = xhci_readl(xhci, &xhci->cap_regs->hcc_params);
-	if (HCC_64BIT_ADDR(temp)) {
+	/* Set dma_mask and coherent_dma_mask to 64-bits,
+	 * if xHC supports 64-bit addressing */
+	if (HCC_64BIT_ADDR(xhci->hcc_params) &&
+			!dma_set_mask(dev, DMA_BIT_MASK(64))) {
 		xhci_dbg(xhci, "Enabling 64-bit DMA addresses.\n");
-		dma_set_mask(hcd->self.controller, DMA_BIT_MASK(64));
-	} else {
-		dma_set_mask(hcd->self.controller, DMA_BIT_MASK(32));
+		dma_set_coherent_mask(dev, DMA_BIT_MASK(64));
 	}
 
 	xhci_dbg(xhci, "Calling HCD init\n");
-- 
1.8.3.2

--
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




[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux