*参照元 [#s952ff78]
#backlinks

*説明 [#x8942cb1]
-パス: 複数あり
--ARCH_HAS_DMA_DECLARE_COHERENT_MEMORY 有効: [[linux-4.4.1/drivers/base/dma-coherent.c]]
--ARCH_HAS_DMA_DECLARE_COHERENT_MEMORY 無効: [[linux-4.4.1/include/asm-generic/dma-coherent.h]]
--[[linux-4.4.1/ARCH_HAS_DMA_DECLARE_COHERENT_MEMORY]]


-FIXME: これは何?
--確保した領域は 0 データで埋められる。
--コンフィグにより、マクロの場合と関数の場合の 2通りある。


**引数 [#pbc777e0]
-struct device *dev
--デバイス
--[[linux-4.4.1/device]]
-ssize_t size
--確保する領域のサイズ
-dma_addr_t *dma_handle
--確保した領域の DMA アドレスを返すためのポインタ
--失敗したときは不定値が返る
--[[linux-4.4.1/dma_addr_t]]
-void **ret
--確保した領域の仮想アドレスを返すためのポインタ
--失敗したときは不定値が返る


**返り値 [#o3705ddb]
-int
--成功なら 0以外、失敗なら 0


**参考 [#k35515dc]


*実装 [#zf0a4f05]

**ARCH_HAS_DMA_DECLARE_COHERENT_MEMORY 有効: drivers/base/dma-coherent.c [#gf0ef482]

 /**
  * dma_alloc_from_coherent() - try to allocate memory from the per-device coherent area
  *
  * @dev:        device from which we allocate memory
  * @size:       size of requested memory area
  * @dma_handle: This will be filled with the correct dma handle
  * @ret:        This pointer will be filled with the virtual address
  *              to allocated area.
  *
  * This function should be only called from per-arch dma_alloc_coherent()
  * to support allocation from per-device coherent memory pools.
  *
  * Returns 0 if dma_alloc_coherent should continue with allocating from
  * generic memory areas, or !0 if dma_alloc_coherent should return @ret.
  */
 int dma_alloc_from_coherent(struct device *dev, ssize_t size,
                                        dma_addr_t *dma_handle, void **ret)
 {
         struct dma_coherent_mem *mem;
         int order = get_order(size);
         unsigned long flags;
         int pageno;
 
-
--[[linux-4.4.1/dma_coherent_mem]]
--[[linux-4.4.1/get_order()]]

         if (!dev)
                 return 0;
         mem = dev->dma_mem;
         if (!mem)
                 return 0;
 
-dev->dma_mem の初期化は dma_assign_coherent_memory() にて行われる。
--[[linux-4.4.1/dma_assign_coherent_memory()]]

         *ret = NULL;
         spin_lock_irqsave(&mem->spinlock, flags);
 
-
--[[linux-4.4.1/spin_lock_irqsave()]]

         if (unlikely(size > (mem->size << PAGE_SHIFT)))
                 goto err;
 
-
--[[linux-4.4.1/unlikely()]]

         pageno = bitmap_find_free_region(mem->bitmap, mem->size, order);
         if (unlikely(pageno < 0))
                 goto err;
 
-
--[[linux-4.4.1/bitmap_find_free_region()]]

         /*
          * Memory was found in the per-device area.
          */
         *dma_handle = mem->device_base + (pageno << PAGE_SHIFT);
         *ret = mem->virt_base + (pageno << PAGE_SHIFT);
         memset(*ret, 0, size);
         spin_unlock_irqrestore(&mem->spinlock, flags);
 
-
--[[linux-4.4.1/memset()]]
--[[linux-4.4.1/spin_unlock_irqrestore()]]

         return 1;
 
 err:
         spin_unlock_irqrestore(&mem->spinlock, flags);
         /*
          * In the case where the allocation can not be satisfied from the
          * per-device area, try to fall back to generic memory if the
          * constraints allow it.
          */
         return mem->flags & DMA_MEMORY_EXCLUSIVE;
 }
 EXPORT_SYMBOL(dma_alloc_from_coherent);
-
--[[linux-4.4.1/EXPORT_SYMBOL()]]


**ARCH_HAS_DMA_DECLARE_COHERENT_MEMORY 無効: include/asm-generic/dma-coherent.h [#lac7af35]

 #define dma_alloc_from_coherent(dev, size, handle, ret) (0)
-割り当てられる領域がない、常に失敗する


*コメント [#jd9190f0]

トップ   編集 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS