On Tue, Sep 1, 2015 at 4:54 AM, Mathias Nyman <mathias.nyman@xxxxxxxxxxxxxxx> wrote: > On 31.08.2015 21:58, Duc Dang wrote: >> >> On Thu, Aug 20, 2015 at 12:38 PM, Duc Dang <dhdang@xxxxxxx> wrote: >>> >>> The xhci platform driver needs to work on systems that >>> either only support 64-bit DMA or only support 32-bit DMA. >>> Attempt to set a coherent dma mask for 64-bit DMA, and >>> attempt again with 32-bit DMA if that fails. >>> >>> [dhdang: regenerate the patch over 4.2-rc5 and address new comments] >>> Signed-off-by: Mark Langsdorf <mlangsdo@xxxxxxxxxx> >>> Tested-by: Mark Salter <msalter@xxxxxxxxxx> >>> Signed-off-by: Duc Dang <dhdang@xxxxxxx> >>> >>> --- >>> Changes from v6: >>> -Add WARN_ON if dma_mask is NULL >>> -Use dma_coerce_mask_and_coherent to assign >>> dma_mask and coherent_dma_mask >>> >>> Changes from v5: >>> -Change comment >>> -Assign dma_mask to coherent_dma_mask if dma_mask is NULL >>> to make sure dma_set_mask_and_coherent does not fail >>> prematurely. >>> >>> Changes from v4: >>> -None >>> >>> Changes from v3: >>> -Re-generate the patch over 4.2-rc5 >>> -No code change. >>> >>> Changes from v2: >>> -None >>> >>> Changes from v1: >>> -Consolidated to use dma_set_mask_and_coherent >>> -Got rid of the check against sizeof(dma_addr_t) >>> >>> drivers/usb/host/xhci-plat.c | 21 +++++++++++++-------- >>> 1 file changed, 13 insertions(+), 8 deletions(-) >>> >>> diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c >>> index 890ad9d..e4c7f9d 100644 >>> --- a/drivers/usb/host/xhci-plat.c >>> +++ b/drivers/usb/host/xhci-plat.c >>> @@ -93,14 +93,19 @@ static int xhci_plat_probe(struct platform_device >>> *pdev) >>> if (irq < 0) >>> 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)); >>> + /* Throw a waring if broken platform code didn't initialize >>> dma_mask */ >>> + WARN_ON(!pdev->dev.dma_mask); >>> + /* >>> + * Try setting dma_mask and coherent_dma_mask to 64 bits, >>> + * then try 32 bits >>> + */ >>> + ret = dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64)); >>> + if (ret) { >>> + ret = dma_coerce_mask_and_coherent(&pdev->dev, >>> + DMA_BIT_MASK(32)); >>> + if (ret) >>> + return ret; >>> + } >>> >>> hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev)); >>> if (!hcd) >>> -- >>> 1.9.1 >>> >> >> Hi Greg, Arnd, Russell, >> >> Do you have any more comment about this patch set? >> > > I'm not sure I fully understand why we need to try the 64 bit DMA mask in > platform probe. > > As I understood it we just want to have some DMA mask set before calling > usb_create_hcd() > to make sure USB core gets the "uses_dma" flag set and dma_set_mask() won't > fail because of > missing dev->dma_mask. > > The correct DMA mask is set later in xhci_gen_setup() > > We also need to make sure the controller supports 64bit addressing > capability before setting a 64 bit DMA mask. > (bit 0 in HCCPARAMS) > > So for platform devices it goes look go this: > > xhci_plat_probe() > usb_create_hcd() > usb_create_shared_hcd() > hcd->self.uses_dma = (dev->dma_mask != NULL); > usb_add_hcd() > hcd->driver->reset() (.reset = xhci_plat_setup) > xhci_plat_setup() > xhci_gen_setup() > 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_coherent_mask(dev, DMA_BIT_MASK(64)); > } > > or do we end up with dev->dma_mask = NULL on 64-bit DMA only after trying to > set it to 32 in xhci_plat_probe(), > and thus also failing the dma_set_mask() in xhci_gen_setup()? > Hi Mathias, dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32)) in xhci_plat_probe fails on our Arm64 X-Gene platform as we do not have DMA memory below 4GB. As a consequence, xhci_plat_probe exits very early without creating any hcd. The xhci_gen_setup code assumes that the dma_mask and coherent_dma_mask were already set to DMA_BIT_MASK(32) and only check to switch to DMA_BIT_MASK(64) if the controller supports 64-bit DMA. So I also see possible regression if a 32-bit controller is used on 64-bit system with my patch. I will integrate Russell's suggestion and add changes to address the case of 32-bit controller on 64-bit system in my next version of this patch set. > -Mathias > > > > > > > > > > Regards, -- Duc Dang. -- 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