参照元

説明

引数

返り値

参考

実装

static void dma_cache_maint_page(struct page *page, unsigned long offset,
        size_t size, enum dma_data_direction dir,
        void (*op)(const void *, size_t, int))
{
        unsigned long pfn;
        size_t left = size;

        pfn = page_to_pfn(page) + offset / PAGE_SIZE;
        offset %= PAGE_SIZE;
        /*
         * A single sg entry may refer to multiple physically contiguous
         * pages.  But we still need to process highmem pages individually.
         * If highmem is not configured then the bulk of this loop gets
         * optimized out.
         */
        do {
                size_t len = left;
                void *vaddr;

                page = pfn_to_page(pfn);
                if (PageHighMem(page)) {
                        if (len + offset > PAGE_SIZE)
                                len = PAGE_SIZE - offset;

                        if (cache_is_vipt_nonaliasing()) {
                                vaddr = kmap_atomic(page);
                                op(vaddr + offset, len, dir);
                                kunmap_atomic(vaddr);
                        } else {
                                vaddr = kmap_high_get(page);
                                if (vaddr) {
                                        op(vaddr + offset, len, dir);
                                        kunmap_high(page);
                                }
                        }
                } else {
                        vaddr = page_address(page) + offset;
                        op(vaddr, len, dir);
                }
                offset = 0;
                pfn++;
                left -= len;
        } while (left);
}

コメント


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