*参照元 [#e447c409]
#backlinks

*説明 [#h020edbe]
-パス: [[linux-4.4.1/drivers/media/v4l2-core/videobuf2-dma-sg.c]]

-FIXME: これは何?
--説明


**引数 [#v76e0e58]
-void *alloc_ctx
--
-unsigned long size
--
-enum dma_data_direction dma_dir
--
--[[linux-4.4.1/dma_data_direction]]
-gfp_t gfp_flags
--
--[[linux-4.4.1/gfp_t]]


**返り値 [#g34f95a0]
-int
--


**参考 [#d2aa2f0f]


*実装 [#te350b30]
 static void *vb2_dma_sg_alloc(void *alloc_ctx, unsigned long size,
                               enum dma_data_direction dma_dir, gfp_t gfp_flags)
 {
         struct vb2_dma_sg_conf *conf = alloc_ctx;
         struct vb2_dma_sg_buf *buf;
         struct sg_table *sgt;
         int ret;
         int num_pages;
         DEFINE_DMA_ATTRS(attrs);
 
-
--[[linux-4.4.1/vb2_dma_sg_conf]]
--[[linux-4.4.1/vb2_dma_sg_buf]]
--[[linux-4.4.1/sg_table]]
--[[linux-4.4.1/DEFINE_DMA_ATTRS()]]

         dma_set_attr(DMA_ATTR_SKIP_CPU_SYNC, &attrs);
 
-
--[[linux-4.4.1/dma_set_attr()]]

         if (WARN_ON(alloc_ctx == NULL))
                 return NULL;
         buf = kzalloc(sizeof *buf, GFP_KERNEL);
         if (!buf)
                 return NULL;
 
-
--[[linux-4.4.1/WARN_ON()]]
--[[linux-4.4.1/kzalloc()]]

         buf->vaddr = NULL;
         buf->dma_dir = dma_dir;
         buf->offset = 0;
         buf->size = size;
         /* size is already page aligned */
         buf->num_pages = size >> PAGE_SHIFT;
         buf->dma_sgt = &buf->sg_table;
 
         buf->pages = kzalloc(buf->num_pages * sizeof(struct page *),
                              GFP_KERNEL);
         if (!buf->pages)
                 goto fail_pages_array_alloc;
 
         ret = vb2_dma_sg_alloc_compacted(buf, gfp_flags);
         if (ret)
                 goto fail_pages_alloc;
 
-
--[[linux-4.4.1/vb2_dma_sg_alloc_compacted()]]

         ret = sg_alloc_table_from_pages(buf->dma_sgt, buf->pages,
                         buf->num_pages, 0, size, GFP_KERNEL);
         if (ret)
                 goto fail_table_alloc;
 
-
--[[linux-4.4.1/sg_alloc_table_from_pages()]]

         /* Prevent the device from being released while the buffer is used */
         buf->dev = get_device(conf->dev);
 
-
--[[linux-4.4.1/get_device()]]

         sgt = &buf->sg_table;
         /*
          * No need to sync to the device, this will happen later when the
          * prepare() memop is called.
          */
         sgt->nents = dma_map_sg_attrs(buf->dev, sgt->sgl, sgt->orig_nents,
                                       buf->dma_dir, &attrs);
         if (!sgt->nents)
                 goto fail_map;
 
-
--[[linux-4.4.1/dma_map_sg_attrs()]]

         buf->handler.refcount = &buf->refcount;
         buf->handler.put = vb2_dma_sg_put;
         buf->handler.arg = buf;
 
         atomic_inc(&buf->refcount);
 
-
--[[linux-4.4.1/vb2_dma_sg_put()]]
--[[linux-4.4.1/atomic_inc()]]

         dprintk(1, "%s: Allocated buffer of %d pages\n",
                 __func__, buf->num_pages);
         return buf;
 
-
--[[linux-4.4.1/dprintk()]]

 fail_map:
         put_device(buf->dev);
         sg_free_table(buf->dma_sgt);
-
--[[linux-4.4.1/put_device()]]
--[[linux-4.4.1/sg_free_table()]]

 fail_table_alloc:
         num_pages = buf->num_pages;
         while (num_pages--)
                 __free_page(buf->pages[num_pages]);
-
--[[linux-4.4.1/__free_page()]]

 fail_pages_alloc:
         kfree(buf->pages);
 fail_pages_array_alloc:
         kfree(buf);
         return NULL;
-
--[[linux-4.4.1/kfree()]]

 }


*コメント [#l3e16e0b]


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