*参照元 [#r3c540e1]
#backlinks

*説明 [#p2bacbcf]
-パス: [[linux-4.4.1/arch/arm64/mm/dma-mapping.c]]

-FIXME: これは何?
--説明
--CMA が使えそうなら CMA から取得しようとする。そうでなければ swiotlb から取得しようとする。
--確保された領域は 0 で初期化される。


**引数 [#of6b9568]
-struct device *dev
--デバイス
--[[linux-4.4.1/device]]
-size_t size
--確保したい領域のサイズ
-dma_addr_t *dma_handle
--確保した領域の DMA アドレスが返される
--[[linux-4.4.1/dma_addr_t]]
-gfp_t flags
--
--[[linux-4.4.1/gfp_t]]
-struct dma_attrs *attrs
--
--属性を指定するが、この関数では使わない
--[[linux-4.4.1/dma_attrs]]


**返り値 [#e724921e]
-void *
--確保した領域の先頭を指すポインタ。失敗した場合は NULL。


**参考 [#oaacd9cc]


*実装 [#w4f04f7c]
 static void *__dma_alloc_coherent(struct device *dev, size_t size,
 				  dma_addr_t *dma_handle, gfp_t flags,
 				  struct dma_attrs *attrs)
 {
 	if (dev == NULL) {
 		WARN_ONCE(1, "Use an actual device structure for DMA allocation\n");
 		return NULL;
 	}
 
-
--[[linux-4.4.1/WARN_ONCE()]]

 	if (IS_ENABLED(CONFIG_ZONE_DMA) &&
 	    dev->coherent_dma_mask <= DMA_BIT_MASK(32))
 		flags |= GFP_DMA;
-
--[[linux-4.4.1/IS_ENABLED()]]
--[[linux-4.4.1/CONFIG_ZONE_DMA]]
--[[linux-4.4.1/DMA_BIT_MASK()]]

 	if (dev_get_cma_area(dev) && gfpflags_allow_blocking(flags)) {
 		struct page *page;
 		void *addr;
 
-
--[[linux-4.4.1/dev_get_cma_area()]]
--[[linux-4.4.1/gfpflags_allow_blocking()]]
--[[linux-4.4.1/page]]

 		page = dma_alloc_from_contiguous(dev, size >> PAGE_SHIFT,
 							get_order(size));
 		if (!page)
 			return NULL;
 
-2番めの引数は何ページ確保するか。サイズからページ数に変換している。
-3番目の引数はアラインメント。要求されたサイズが大きくなると、アラインメントも大きくなる。
--[[linux-4.4.1/dma_alloc_from_contiguous()]]
--[[linux-4.4.1/PAGE_SHIFT]]
--[[linux-4.4.1/get_order()]]

 		*dma_handle = phys_to_dma(dev, page_to_phys(page));
 		addr = page_address(page);
 		memset(addr, 0, size);
-
--[[linux-4.4.1/phys_to_dma()]]
--[[linux-4.4.1/page_to_phys()]]
--[[linux-4.4.1/page_address()]]

 		return addr;
 	} else {
 		return swiotlb_alloc_coherent(dev, size, dma_handle, flags);
-
--[[linux-4.4.1/swiotlb_alloc_coherent()]]

 	}
 }


*コメント [#e22f79db]

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