- 追加された行はこの色です。
- 削除された行はこの色です。
*参照元 [#g67f836d]
#backlinks
*説明 [#b144c45e]
-パス: [[linux-4.4.1/arch/arm/mm/dma-mapping.c]]
-FIXME: これは何?
--説明
**引数 [#i200bce6]
-struct device *dev
--
--[[linux-4.4.1/device]]
-size_t size
--
-dma_addr_t *handle
--
--[[linux-4.4.1/dma_addr_t]]
-gfp_t gfp
--
--[[linux-4.4.1/gfp_t]]
-pgprot_t prot
--
--[[linux-4.4.1/pgprot_t]]
-bool is_coherent
--
-struct dma_attrs *attrs
--
--[[linux-4.4.1/dma_attrs]]
-const void *caller
--
**返り値 [#y8721785]
-void *
--
**参考 [#u85ffe64]
*実装 [#j8654022]
static void *__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
gfp_t gfp, pgprot_t prot, bool is_coherent,
struct dma_attrs *attrs, const void *caller)
{
u64 mask = get_coherent_dma_mask(dev);
struct page *page = NULL;
void *addr;
bool want_vaddr;
-
--[[linux-4.4.1/get_coherent_dma_mask()]]
--[[linux-4.4.1/page]]
#ifdef CONFIG_DMA_API_DEBUG
-
--[[linux-4.4.1/CONFIG_DMA_API_DEBUG]]
u64 limit = (mask + 1) & ~mask;
if (limit && size >= limit) {
dev_warn(dev, "coherent allocation too big (requested %#x mask %#llx)\n",
size, mask);
-
--[[linux-4.4.1/dev_warn()]]
return NULL;
}
#endif
if (!mask)
return NULL;
if (mask < 0xffffffffULL)
gfp |= GFP_DMA;
/*
* Following is a work-around (a.k.a. hack) to prevent pages
* with __GFP_COMP being passed to split_page() which cannot
* handle them. The real problem is that this flag probably
* should be 0 on ARM as it is not supported on this
* platform; see CONFIG_HUGETLBFS.
*/
gfp &= ~(__GFP_COMP);
*handle = DMA_ERROR_CODE;
size = PAGE_ALIGN(size);
want_vaddr = !dma_get_attr(DMA_ATTR_NO_KERNEL_MAPPING, attrs);
-
--[[linux-4.4.1/PAGE_ALIGN()]]
--[[linux-4.4.1/dma_get_attr()]]
if (nommu())
addr = __alloc_simple_buffer(dev, size, gfp, &page);
-
--[[linux-4.4.1/nommu()]]
--[[linux-4.4.1/__alloc_simple_buffer()]]
else if (dev_get_cma_area(dev) && (gfp & __GFP_DIRECT_RECLAIM))
addr = __alloc_from_contiguous(dev, size, prot, &page,
caller, want_vaddr);
-
--[[linux-4.4.1/dev_get_cma_area()]]
--[[linux-4.4.1/__alloc_from_contiguous()]]
else if (is_coherent)
addr = __alloc_simple_buffer(dev, size, gfp, &page);
else if (!gfpflags_allow_blocking(gfp))
addr = __alloc_from_pool(size, &page);
-
--[[linux-4.4.1/gfpflags_allow_blocking()]]
--[[linux-4.4.1/__alloc_from_pool()]]
else
addr = __alloc_remap_buffer(dev, size, gfp, prot, &page,
caller, want_vaddr);
-
--[[linux-4.4.1/__alloc_remap_buffer()]]
if (page)
*handle = pfn_to_dma(dev, page_to_pfn(page));
-
--[[linux-4.4.1/pfn_to_dma()]]
--[[linux-4.4.1/page_to_pfn()]]
return want_vaddr ? addr : page;
}
*コメント [#g21e54ba]