kernel/dma/direct.h

Source file repositories/reference/linux-study-clean/kernel/dma/direct.h

File Facts

System
Linux kernel
Corpus path
kernel/dma/direct.h
Extension
.h
Size
4773 bytes
Lines
156
Domain
Core OS
Bucket
Scheduler, Processes, Timers, Sync, And Syscalls
Inferred role
Core OS: implementation source
Status
source implementation candidate

Why This File Exists

Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.

Dependency Surface

Detected Declarations

Annotated Snippet

if (!(attrs & DMA_ATTR_CC_SHARED)) {
			if (attrs & (DMA_ATTR_MMIO | DMA_ATTR_REQUIRE_COHERENT))
				return DMA_MAPPING_ERROR;

			return swiotlb_map(dev, phys, size, dir, attrs);
		}
	} else if (attrs & DMA_ATTR_CC_SHARED) {
		return DMA_MAPPING_ERROR;
	}

	if (attrs & DMA_ATTR_MMIO) {
		dma_addr = phys;
		if (unlikely(!dma_capable(dev, dma_addr, size, false)))
			goto err_overflow;
	} else if (attrs & DMA_ATTR_CC_SHARED) {
		dma_addr = phys_to_dma_unencrypted(dev, phys);
		if (unlikely(!dma_capable(dev, dma_addr, size, false)))
			goto err_overflow;
	} else {
		dma_addr = phys_to_dma(dev, phys);
		if (unlikely(!dma_capable(dev, dma_addr, size, true)) ||
		    dma_kmalloc_needs_bounce(dev, size, dir)) {
			if (is_swiotlb_active(dev) &&
			    !(attrs & DMA_ATTR_REQUIRE_COHERENT))
				return swiotlb_map(dev, phys, size, dir, attrs);

			goto err_overflow;
		}
	}

	if (!dev_is_dma_coherent(dev) &&
	    !(attrs & (DMA_ATTR_SKIP_CPU_SYNC | DMA_ATTR_MMIO))) {
		arch_sync_dma_for_device(phys, size, dir);
		if (flush)
			arch_sync_dma_flush();
	}
	return dma_addr;

err_overflow:
	dev_WARN_ONCE(
		dev, 1,
		"DMA addr %pad+%zu overflow (mask %llx, bus limit %llx).\n",
		&dma_addr, size, *dev->dma_mask, dev->bus_dma_limit);
	return DMA_MAPPING_ERROR;
}

static inline void dma_direct_unmap_phys(struct device *dev, dma_addr_t addr,
		size_t size, enum dma_data_direction dir, unsigned long attrs,
		bool flush)
{
	phys_addr_t phys;

	if (attrs & (DMA_ATTR_MMIO | DMA_ATTR_REQUIRE_COHERENT))
		/* nothing to do: uncached and no swiotlb */
		return;

	phys = dma_to_phys(dev, addr);
	if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC))
		dma_direct_sync_single_for_cpu(dev, addr, size, dir, flush);

	swiotlb_tbl_unmap_single(dev, phys, size, dir,
					 attrs | DMA_ATTR_SKIP_CPU_SYNC);
}
#endif /* _KERNEL_DMA_DIRECT_H */

Annotation

Implementation Notes