• Frank Li's avatar
    docs: dma: correct dma_set_mask() sample code · f7ae20f2
    Frank Li authored
    There are bunch of codes in driver like
    
           if (dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64)))
                   dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32))
    
    Actually it is wrong because if dma_set_mask_and_coherent(64) fails,
    dma_set_mask_and_coherent(32) will fail for the same reason.
    
    And dma_set_mask_and_coherent(64) never returns failure.
    
    According to the definition of dma_set_mask(), it indicates the width of
    address that device DMA can access. If it can access 64-bit address, it
    must access 32-bit address inherently. So only need set biggest address
    width.
    
    See below code fragment:
    
    dma_set_mask(mask)
    {
    	mask = (dma_addr_t)mask;
    
    	if (!dev->dma_mask || !dma_supported(dev, mask))
    		return -EIO;
    
    	arch_dma_set_mask(dev, mask);
    	*dev->dma_mask = mask;
    	return 0;
    }
    
    dma_supported() will call dma_direct_supported or iommux's dma_supported
    call back function.
    
    int dma_direct_supported(struct device *dev, u64 mask)
    {
    	u64 min_mask = (max_pfn - 1) << PAGE_SHIFT;
    
    	/*
    	 * Because 32-bit DMA masks are so common we expect every architecture
    	 * to be able to satisfy them - either by not supporting more physical
    	 * memory, or by providing a ZONE_DMA32.  If neither is the case, the
    	 * architecture needs to use an IOMMU instead of the direct mapping.
    	 */
    	if (mask >= DMA_BIT_MASK(32))
    		return 1;
    
    	...
    }
    
    The iommux's dma_supported() actually means iommu requires devices's
    minimized dma capability.
    
    An example:
    
    static int sba_dma_supported( struct device *dev, u64 mask)()
    {
    	...
    	 * check if mask is >= than the current max IO Virt Address
             * The max IO Virt address will *always* < 30 bits.
             */
            return((int)(mask >= (ioc->ibase - 1 +
                            (ioc->pdir_size / sizeof(u64) * IOVP_SIZE) )));
    	...
    }
    
    1 means supported. 0 means unsupported.
    
    Correct document to make it more clear and provide correct sample code.
    Signed-off-by: default avatarFrank Li <Frank.Li@nxp.com>
    Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
    Signed-off-by: default avatarJonathan Corbet <corbet@lwn.net>
    [jc: fixed then/than typo]
    Link: https://lore.kernel.org/r/20240401174159.642998-1-Frank.Li@nxp.com
    f7ae20f2
dma-api-howto.rst 32.6 KB