参照元

説明

引数

返り値

参考

実装

static void *__dma_alloc(struct device *dev, size_t size,
                         dma_addr_t *dma_handle, gfp_t flags,
                         struct dma_attrs *attrs)
{
        struct page *page;
        void *ptr, *coherent_ptr;
        bool coherent = is_device_dma_coherent(dev);
        pgprot_t prot = __get_dma_pgprot(attrs, PAGE_KERNEL, false);
        size = PAGE_ALIGN(size);
        if (!coherent && !gfpflags_allow_blocking(flags)) {
                struct page *page = NULL;
                void *addr = __alloc_from_pool(size, &page, flags);

                if (addr)
                        *dma_handle = phys_to_dma(dev, page_to_phys(page));
                return addr;
        }

        ptr = __dma_alloc_coherent(dev, size, dma_handle, flags, attrs);
        if (!ptr)
                goto no_mem;
        /* no need for non-cacheable mapping if coherent */
        if (coherent)
                return ptr;

        /* remove any dirty cache lines on the kernel alias */
        __dma_flush_range(ptr, ptr + size);
        /* create a coherent mapping */
        page = virt_to_page(ptr);
        coherent_ptr = dma_common_contiguous_remap(page, size, VM_USERMAP,
                                                   prot, NULL);
        if (!coherent_ptr)
                goto no_map;
        return coherent_ptr;

no_map:
        __dma_free_coherent(dev, size, ptr, *dma_handle, attrs);
no_mem:
        *dma_handle = DMA_ERROR_CODE;
        return NULL;
}

コメント


トップ   編集 凍結 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2016-05-06 (金) 11:15:36