1/*
2 * videobuf2-dma-sg.c - dma scatter/gather memory allocator for videobuf2
3 *
4 * Copyright (C) 2010 Samsung Electronics
5 *
6 * Author: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation.
11 */
12
13#include <linux/module.h>
14#include <linux/mm.h>
15#include <linux/scatterlist.h>
16#include <linux/sched.h>
17#include <linux/slab.h>
18#include <linux/vmalloc.h>
19
20#include <media/videobuf2-core.h>
21#include <media/videobuf2-memops.h>
22#include <media/videobuf2-dma-sg.h>
23
24static int debug;
25module_param(debug, int, 0644);
26
27#define dprintk(level, fmt, arg...)					\
28	do {								\
29		if (debug >= level)					\
30			printk(KERN_DEBUG "vb2-dma-sg: " fmt, ## arg);	\
31	} while (0)
32
33struct vb2_dma_sg_conf {
34	struct device		*dev;
35};
36
37struct vb2_dma_sg_buf {
38	struct device			*dev;
39	void				*vaddr;
40	struct page			**pages;
41	int				offset;
42	enum dma_data_direction		dma_dir;
43	struct sg_table			sg_table;
44	/*
45	 * This will point to sg_table when used with the MMAP or USERPTR
46	 * memory model, and to the dma_buf sglist when used with the
47	 * DMABUF memory model.
48	 */
49	struct sg_table			*dma_sgt;
50	size_t				size;
51	unsigned int			num_pages;
52	atomic_t			refcount;
53	struct vb2_vmarea_handler	handler;
54	struct vm_area_struct		*vma;
55
56	struct dma_buf_attachment	*db_attach;
57};
58
59static void vb2_dma_sg_put(void *buf_priv);
60
61static int vb2_dma_sg_alloc_compacted(struct vb2_dma_sg_buf *buf,
62		gfp_t gfp_flags)
63{
64	unsigned int last_page = 0;
65	int size = buf->size;
66
67	while (size > 0) {
68		struct page *pages;
69		int order;
70		int i;
71
72		order = get_order(size);
73		/* Dont over allocate*/
74		if ((PAGE_SIZE << order) > size)
75			order--;
76
77		pages = NULL;
78		while (!pages) {
79			pages = alloc_pages(GFP_KERNEL | __GFP_ZERO |
80					__GFP_NOWARN | gfp_flags, order);
81			if (pages)
82				break;
83
84			if (order == 0) {
85				while (last_page--)
86					__free_page(buf->pages[last_page]);
87				return -ENOMEM;
88			}
89			order--;
90		}
91
92		split_page(pages, order);
93		for (i = 0; i < (1 << order); i++)
94			buf->pages[last_page++] = &pages[i];
95
96		size -= PAGE_SIZE << order;
97	}
98
99	return 0;
100}
101
102static void *vb2_dma_sg_alloc(void *alloc_ctx, unsigned long size,
103			      enum dma_data_direction dma_dir, gfp_t gfp_flags)
104{
105	struct vb2_dma_sg_conf *conf = alloc_ctx;
106	struct vb2_dma_sg_buf *buf;
107	struct sg_table *sgt;
108	int ret;
109	int num_pages;
110	DEFINE_DMA_ATTRS(attrs);
111
112	dma_set_attr(DMA_ATTR_SKIP_CPU_SYNC, &attrs);
113
114	if (WARN_ON(alloc_ctx == NULL))
115		return NULL;
116	buf = kzalloc(sizeof *buf, GFP_KERNEL);
117	if (!buf)
118		return NULL;
119
120	buf->vaddr = NULL;
121	buf->dma_dir = dma_dir;
122	buf->offset = 0;
123	buf->size = size;
124	/* size is already page aligned */
125	buf->num_pages = size >> PAGE_SHIFT;
126	buf->dma_sgt = &buf->sg_table;
127
128	buf->pages = kzalloc(buf->num_pages * sizeof(struct page *),
129			     GFP_KERNEL);
130	if (!buf->pages)
131		goto fail_pages_array_alloc;
132
133	ret = vb2_dma_sg_alloc_compacted(buf, gfp_flags);
134	if (ret)
135		goto fail_pages_alloc;
136
137	ret = sg_alloc_table_from_pages(buf->dma_sgt, buf->pages,
138			buf->num_pages, 0, size, GFP_KERNEL);
139	if (ret)
140		goto fail_table_alloc;
141
142	/* Prevent the device from being released while the buffer is used */
143	buf->dev = get_device(conf->dev);
144
145	sgt = &buf->sg_table;
146	/*
147	 * No need to sync to the device, this will happen later when the
148	 * prepare() memop is called.
149	 */
150	if (dma_map_sg_attrs(buf->dev, sgt->sgl, sgt->nents,
151			     buf->dma_dir, &attrs) == 0)
152		goto fail_map;
153
154	buf->handler.refcount = &buf->refcount;
155	buf->handler.put = vb2_dma_sg_put;
156	buf->handler.arg = buf;
157
158	atomic_inc(&buf->refcount);
159
160	dprintk(1, "%s: Allocated buffer of %d pages\n",
161		__func__, buf->num_pages);
162	return buf;
163
164fail_map:
165	put_device(buf->dev);
166	sg_free_table(buf->dma_sgt);
167fail_table_alloc:
168	num_pages = buf->num_pages;
169	while (num_pages--)
170		__free_page(buf->pages[num_pages]);
171fail_pages_alloc:
172	kfree(buf->pages);
173fail_pages_array_alloc:
174	kfree(buf);
175	return NULL;
176}
177
178static void vb2_dma_sg_put(void *buf_priv)
179{
180	struct vb2_dma_sg_buf *buf = buf_priv;
181	struct sg_table *sgt = &buf->sg_table;
182	int i = buf->num_pages;
183
184	if (atomic_dec_and_test(&buf->refcount)) {
185		DEFINE_DMA_ATTRS(attrs);
186
187		dma_set_attr(DMA_ATTR_SKIP_CPU_SYNC, &attrs);
188		dprintk(1, "%s: Freeing buffer of %d pages\n", __func__,
189			buf->num_pages);
190		dma_unmap_sg_attrs(buf->dev, sgt->sgl, sgt->nents,
191				   buf->dma_dir, &attrs);
192		if (buf->vaddr)
193			vm_unmap_ram(buf->vaddr, buf->num_pages);
194		sg_free_table(buf->dma_sgt);
195		while (--i >= 0)
196			__free_page(buf->pages[i]);
197		kfree(buf->pages);
198		put_device(buf->dev);
199		kfree(buf);
200	}
201}
202
203static void vb2_dma_sg_prepare(void *buf_priv)
204{
205	struct vb2_dma_sg_buf *buf = buf_priv;
206	struct sg_table *sgt = buf->dma_sgt;
207
208	/* DMABUF exporter will flush the cache for us */
209	if (buf->db_attach)
210		return;
211
212	dma_sync_sg_for_device(buf->dev, sgt->sgl, sgt->nents, buf->dma_dir);
213}
214
215static void vb2_dma_sg_finish(void *buf_priv)
216{
217	struct vb2_dma_sg_buf *buf = buf_priv;
218	struct sg_table *sgt = buf->dma_sgt;
219
220	/* DMABUF exporter will flush the cache for us */
221	if (buf->db_attach)
222		return;
223
224	dma_sync_sg_for_cpu(buf->dev, sgt->sgl, sgt->nents, buf->dma_dir);
225}
226
227static inline int vma_is_io(struct vm_area_struct *vma)
228{
229	return !!(vma->vm_flags & (VM_IO | VM_PFNMAP));
230}
231
232static void *vb2_dma_sg_get_userptr(void *alloc_ctx, unsigned long vaddr,
233				    unsigned long size,
234				    enum dma_data_direction dma_dir)
235{
236	struct vb2_dma_sg_conf *conf = alloc_ctx;
237	struct vb2_dma_sg_buf *buf;
238	unsigned long first, last;
239	int num_pages_from_user;
240	struct vm_area_struct *vma;
241	struct sg_table *sgt;
242	DEFINE_DMA_ATTRS(attrs);
243
244	dma_set_attr(DMA_ATTR_SKIP_CPU_SYNC, &attrs);
245
246	buf = kzalloc(sizeof *buf, GFP_KERNEL);
247	if (!buf)
248		return NULL;
249
250	buf->vaddr = NULL;
251	buf->dev = conf->dev;
252	buf->dma_dir = dma_dir;
253	buf->offset = vaddr & ~PAGE_MASK;
254	buf->size = size;
255	buf->dma_sgt = &buf->sg_table;
256
257	first = (vaddr           & PAGE_MASK) >> PAGE_SHIFT;
258	last  = ((vaddr + size - 1) & PAGE_MASK) >> PAGE_SHIFT;
259	buf->num_pages = last - first + 1;
260
261	buf->pages = kzalloc(buf->num_pages * sizeof(struct page *),
262			     GFP_KERNEL);
263	if (!buf->pages)
264		goto userptr_fail_alloc_pages;
265
266	vma = find_vma(current->mm, vaddr);
267	if (!vma) {
268		dprintk(1, "no vma for address %lu\n", vaddr);
269		goto userptr_fail_find_vma;
270	}
271
272	if (vma->vm_end < vaddr + size) {
273		dprintk(1, "vma at %lu is too small for %lu bytes\n",
274			vaddr, size);
275		goto userptr_fail_find_vma;
276	}
277
278	buf->vma = vb2_get_vma(vma);
279	if (!buf->vma) {
280		dprintk(1, "failed to copy vma\n");
281		goto userptr_fail_find_vma;
282	}
283
284	if (vma_is_io(buf->vma)) {
285		for (num_pages_from_user = 0;
286		     num_pages_from_user < buf->num_pages;
287		     ++num_pages_from_user, vaddr += PAGE_SIZE) {
288			unsigned long pfn;
289
290			if (follow_pfn(vma, vaddr, &pfn)) {
291				dprintk(1, "no page for address %lu\n", vaddr);
292				break;
293			}
294			buf->pages[num_pages_from_user] = pfn_to_page(pfn);
295		}
296	} else
297		num_pages_from_user = get_user_pages(current, current->mm,
298					     vaddr & PAGE_MASK,
299					     buf->num_pages,
300					     buf->dma_dir == DMA_FROM_DEVICE,
301					     1, /* force */
302					     buf->pages,
303					     NULL);
304
305	if (num_pages_from_user != buf->num_pages)
306		goto userptr_fail_get_user_pages;
307
308	if (sg_alloc_table_from_pages(buf->dma_sgt, buf->pages,
309			buf->num_pages, buf->offset, size, 0))
310		goto userptr_fail_alloc_table_from_pages;
311
312	sgt = &buf->sg_table;
313	/*
314	 * No need to sync to the device, this will happen later when the
315	 * prepare() memop is called.
316	 */
317	if (dma_map_sg_attrs(buf->dev, sgt->sgl, sgt->nents,
318			     buf->dma_dir, &attrs) == 0)
319		goto userptr_fail_map;
320	return buf;
321
322userptr_fail_map:
323	sg_free_table(&buf->sg_table);
324userptr_fail_alloc_table_from_pages:
325userptr_fail_get_user_pages:
326	dprintk(1, "get_user_pages requested/got: %d/%d]\n",
327		buf->num_pages, num_pages_from_user);
328	if (!vma_is_io(buf->vma))
329		while (--num_pages_from_user >= 0)
330			put_page(buf->pages[num_pages_from_user]);
331	vb2_put_vma(buf->vma);
332userptr_fail_find_vma:
333	kfree(buf->pages);
334userptr_fail_alloc_pages:
335	kfree(buf);
336	return NULL;
337}
338
339/*
340 * @put_userptr: inform the allocator that a USERPTR buffer will no longer
341 *		 be used
342 */
343static void vb2_dma_sg_put_userptr(void *buf_priv)
344{
345	struct vb2_dma_sg_buf *buf = buf_priv;
346	struct sg_table *sgt = &buf->sg_table;
347	int i = buf->num_pages;
348	DEFINE_DMA_ATTRS(attrs);
349
350	dma_set_attr(DMA_ATTR_SKIP_CPU_SYNC, &attrs);
351
352	dprintk(1, "%s: Releasing userspace buffer of %d pages\n",
353	       __func__, buf->num_pages);
354	dma_unmap_sg_attrs(buf->dev, sgt->sgl, sgt->nents, buf->dma_dir, &attrs);
355	if (buf->vaddr)
356		vm_unmap_ram(buf->vaddr, buf->num_pages);
357	sg_free_table(buf->dma_sgt);
358	while (--i >= 0) {
359		if (buf->dma_dir == DMA_FROM_DEVICE)
360			set_page_dirty_lock(buf->pages[i]);
361		if (!vma_is_io(buf->vma))
362			put_page(buf->pages[i]);
363	}
364	kfree(buf->pages);
365	vb2_put_vma(buf->vma);
366	kfree(buf);
367}
368
369static void *vb2_dma_sg_vaddr(void *buf_priv)
370{
371	struct vb2_dma_sg_buf *buf = buf_priv;
372
373	BUG_ON(!buf);
374
375	if (!buf->vaddr) {
376		if (buf->db_attach)
377			buf->vaddr = dma_buf_vmap(buf->db_attach->dmabuf);
378		else
379			buf->vaddr = vm_map_ram(buf->pages,
380					buf->num_pages, -1, PAGE_KERNEL);
381	}
382
383	/* add offset in case userptr is not page-aligned */
384	return buf->vaddr ? buf->vaddr + buf->offset : NULL;
385}
386
387static unsigned int vb2_dma_sg_num_users(void *buf_priv)
388{
389	struct vb2_dma_sg_buf *buf = buf_priv;
390
391	return atomic_read(&buf->refcount);
392}
393
394static int vb2_dma_sg_mmap(void *buf_priv, struct vm_area_struct *vma)
395{
396	struct vb2_dma_sg_buf *buf = buf_priv;
397	unsigned long uaddr = vma->vm_start;
398	unsigned long usize = vma->vm_end - vma->vm_start;
399	int i = 0;
400
401	if (!buf) {
402		printk(KERN_ERR "No memory to map\n");
403		return -EINVAL;
404	}
405
406	do {
407		int ret;
408
409		ret = vm_insert_page(vma, uaddr, buf->pages[i++]);
410		if (ret) {
411			printk(KERN_ERR "Remapping memory, error: %d\n", ret);
412			return ret;
413		}
414
415		uaddr += PAGE_SIZE;
416		usize -= PAGE_SIZE;
417	} while (usize > 0);
418
419
420	/*
421	 * Use common vm_area operations to track buffer refcount.
422	 */
423	vma->vm_private_data	= &buf->handler;
424	vma->vm_ops		= &vb2_common_vm_ops;
425
426	vma->vm_ops->open(vma);
427
428	return 0;
429}
430
431/*********************************************/
432/*         DMABUF ops for exporters          */
433/*********************************************/
434
435struct vb2_dma_sg_attachment {
436	struct sg_table sgt;
437	enum dma_data_direction dma_dir;
438};
439
440static int vb2_dma_sg_dmabuf_ops_attach(struct dma_buf *dbuf, struct device *dev,
441	struct dma_buf_attachment *dbuf_attach)
442{
443	struct vb2_dma_sg_attachment *attach;
444	unsigned int i;
445	struct scatterlist *rd, *wr;
446	struct sg_table *sgt;
447	struct vb2_dma_sg_buf *buf = dbuf->priv;
448	int ret;
449
450	attach = kzalloc(sizeof(*attach), GFP_KERNEL);
451	if (!attach)
452		return -ENOMEM;
453
454	sgt = &attach->sgt;
455	/* Copy the buf->base_sgt scatter list to the attachment, as we can't
456	 * map the same scatter list to multiple attachments at the same time.
457	 */
458	ret = sg_alloc_table(sgt, buf->dma_sgt->orig_nents, GFP_KERNEL);
459	if (ret) {
460		kfree(attach);
461		return -ENOMEM;
462	}
463
464	rd = buf->dma_sgt->sgl;
465	wr = sgt->sgl;
466	for (i = 0; i < sgt->orig_nents; ++i) {
467		sg_set_page(wr, sg_page(rd), rd->length, rd->offset);
468		rd = sg_next(rd);
469		wr = sg_next(wr);
470	}
471
472	attach->dma_dir = DMA_NONE;
473	dbuf_attach->priv = attach;
474
475	return 0;
476}
477
478static void vb2_dma_sg_dmabuf_ops_detach(struct dma_buf *dbuf,
479	struct dma_buf_attachment *db_attach)
480{
481	struct vb2_dma_sg_attachment *attach = db_attach->priv;
482	struct sg_table *sgt;
483
484	if (!attach)
485		return;
486
487	sgt = &attach->sgt;
488
489	/* release the scatterlist cache */
490	if (attach->dma_dir != DMA_NONE)
491		dma_unmap_sg(db_attach->dev, sgt->sgl, sgt->orig_nents,
492			attach->dma_dir);
493	sg_free_table(sgt);
494	kfree(attach);
495	db_attach->priv = NULL;
496}
497
498static struct sg_table *vb2_dma_sg_dmabuf_ops_map(
499	struct dma_buf_attachment *db_attach, enum dma_data_direction dma_dir)
500{
501	struct vb2_dma_sg_attachment *attach = db_attach->priv;
502	/* stealing dmabuf mutex to serialize map/unmap operations */
503	struct mutex *lock = &db_attach->dmabuf->lock;
504	struct sg_table *sgt;
505	int ret;
506
507	mutex_lock(lock);
508
509	sgt = &attach->sgt;
510	/* return previously mapped sg table */
511	if (attach->dma_dir == dma_dir) {
512		mutex_unlock(lock);
513		return sgt;
514	}
515
516	/* release any previous cache */
517	if (attach->dma_dir != DMA_NONE) {
518		dma_unmap_sg(db_attach->dev, sgt->sgl, sgt->orig_nents,
519			attach->dma_dir);
520		attach->dma_dir = DMA_NONE;
521	}
522
523	/* mapping to the client with new direction */
524	ret = dma_map_sg(db_attach->dev, sgt->sgl, sgt->orig_nents, dma_dir);
525	if (ret <= 0) {
526		pr_err("failed to map scatterlist\n");
527		mutex_unlock(lock);
528		return ERR_PTR(-EIO);
529	}
530
531	attach->dma_dir = dma_dir;
532
533	mutex_unlock(lock);
534
535	return sgt;
536}
537
538static void vb2_dma_sg_dmabuf_ops_unmap(struct dma_buf_attachment *db_attach,
539	struct sg_table *sgt, enum dma_data_direction dma_dir)
540{
541	/* nothing to be done here */
542}
543
544static void vb2_dma_sg_dmabuf_ops_release(struct dma_buf *dbuf)
545{
546	/* drop reference obtained in vb2_dma_sg_get_dmabuf */
547	vb2_dma_sg_put(dbuf->priv);
548}
549
550static void *vb2_dma_sg_dmabuf_ops_kmap(struct dma_buf *dbuf, unsigned long pgnum)
551{
552	struct vb2_dma_sg_buf *buf = dbuf->priv;
553
554	return buf->vaddr ? buf->vaddr + pgnum * PAGE_SIZE : NULL;
555}
556
557static void *vb2_dma_sg_dmabuf_ops_vmap(struct dma_buf *dbuf)
558{
559	struct vb2_dma_sg_buf *buf = dbuf->priv;
560
561	return vb2_dma_sg_vaddr(buf);
562}
563
564static int vb2_dma_sg_dmabuf_ops_mmap(struct dma_buf *dbuf,
565	struct vm_area_struct *vma)
566{
567	return vb2_dma_sg_mmap(dbuf->priv, vma);
568}
569
570static struct dma_buf_ops vb2_dma_sg_dmabuf_ops = {
571	.attach = vb2_dma_sg_dmabuf_ops_attach,
572	.detach = vb2_dma_sg_dmabuf_ops_detach,
573	.map_dma_buf = vb2_dma_sg_dmabuf_ops_map,
574	.unmap_dma_buf = vb2_dma_sg_dmabuf_ops_unmap,
575	.kmap = vb2_dma_sg_dmabuf_ops_kmap,
576	.kmap_atomic = vb2_dma_sg_dmabuf_ops_kmap,
577	.vmap = vb2_dma_sg_dmabuf_ops_vmap,
578	.mmap = vb2_dma_sg_dmabuf_ops_mmap,
579	.release = vb2_dma_sg_dmabuf_ops_release,
580};
581
582static struct dma_buf *vb2_dma_sg_get_dmabuf(void *buf_priv, unsigned long flags)
583{
584	struct vb2_dma_sg_buf *buf = buf_priv;
585	struct dma_buf *dbuf;
586	DEFINE_DMA_BUF_EXPORT_INFO(exp_info);
587
588	exp_info.ops = &vb2_dma_sg_dmabuf_ops;
589	exp_info.size = buf->size;
590	exp_info.flags = flags;
591	exp_info.priv = buf;
592
593	if (WARN_ON(!buf->dma_sgt))
594		return NULL;
595
596	dbuf = dma_buf_export(&exp_info);
597	if (IS_ERR(dbuf))
598		return NULL;
599
600	/* dmabuf keeps reference to vb2 buffer */
601	atomic_inc(&buf->refcount);
602
603	return dbuf;
604}
605
606/*********************************************/
607/*       callbacks for DMABUF buffers        */
608/*********************************************/
609
610static int vb2_dma_sg_map_dmabuf(void *mem_priv)
611{
612	struct vb2_dma_sg_buf *buf = mem_priv;
613	struct sg_table *sgt;
614
615	if (WARN_ON(!buf->db_attach)) {
616		pr_err("trying to pin a non attached buffer\n");
617		return -EINVAL;
618	}
619
620	if (WARN_ON(buf->dma_sgt)) {
621		pr_err("dmabuf buffer is already pinned\n");
622		return 0;
623	}
624
625	/* get the associated scatterlist for this buffer */
626	sgt = dma_buf_map_attachment(buf->db_attach, buf->dma_dir);
627	if (IS_ERR(sgt)) {
628		pr_err("Error getting dmabuf scatterlist\n");
629		return -EINVAL;
630	}
631
632	buf->dma_sgt = sgt;
633	buf->vaddr = NULL;
634
635	return 0;
636}
637
638static void vb2_dma_sg_unmap_dmabuf(void *mem_priv)
639{
640	struct vb2_dma_sg_buf *buf = mem_priv;
641	struct sg_table *sgt = buf->dma_sgt;
642
643	if (WARN_ON(!buf->db_attach)) {
644		pr_err("trying to unpin a not attached buffer\n");
645		return;
646	}
647
648	if (WARN_ON(!sgt)) {
649		pr_err("dmabuf buffer is already unpinned\n");
650		return;
651	}
652
653	if (buf->vaddr) {
654		dma_buf_vunmap(buf->db_attach->dmabuf, buf->vaddr);
655		buf->vaddr = NULL;
656	}
657	dma_buf_unmap_attachment(buf->db_attach, sgt, buf->dma_dir);
658
659	buf->dma_sgt = NULL;
660}
661
662static void vb2_dma_sg_detach_dmabuf(void *mem_priv)
663{
664	struct vb2_dma_sg_buf *buf = mem_priv;
665
666	/* if vb2 works correctly you should never detach mapped buffer */
667	if (WARN_ON(buf->dma_sgt))
668		vb2_dma_sg_unmap_dmabuf(buf);
669
670	/* detach this attachment */
671	dma_buf_detach(buf->db_attach->dmabuf, buf->db_attach);
672	kfree(buf);
673}
674
675static void *vb2_dma_sg_attach_dmabuf(void *alloc_ctx, struct dma_buf *dbuf,
676	unsigned long size, enum dma_data_direction dma_dir)
677{
678	struct vb2_dma_sg_conf *conf = alloc_ctx;
679	struct vb2_dma_sg_buf *buf;
680	struct dma_buf_attachment *dba;
681
682	if (dbuf->size < size)
683		return ERR_PTR(-EFAULT);
684
685	buf = kzalloc(sizeof(*buf), GFP_KERNEL);
686	if (!buf)
687		return ERR_PTR(-ENOMEM);
688
689	buf->dev = conf->dev;
690	/* create attachment for the dmabuf with the user device */
691	dba = dma_buf_attach(dbuf, buf->dev);
692	if (IS_ERR(dba)) {
693		pr_err("failed to attach dmabuf\n");
694		kfree(buf);
695		return dba;
696	}
697
698	buf->dma_dir = dma_dir;
699	buf->size = size;
700	buf->db_attach = dba;
701
702	return buf;
703}
704
705static void *vb2_dma_sg_cookie(void *buf_priv)
706{
707	struct vb2_dma_sg_buf *buf = buf_priv;
708
709	return buf->dma_sgt;
710}
711
712const struct vb2_mem_ops vb2_dma_sg_memops = {
713	.alloc		= vb2_dma_sg_alloc,
714	.put		= vb2_dma_sg_put,
715	.get_userptr	= vb2_dma_sg_get_userptr,
716	.put_userptr	= vb2_dma_sg_put_userptr,
717	.prepare	= vb2_dma_sg_prepare,
718	.finish		= vb2_dma_sg_finish,
719	.vaddr		= vb2_dma_sg_vaddr,
720	.mmap		= vb2_dma_sg_mmap,
721	.num_users	= vb2_dma_sg_num_users,
722	.get_dmabuf	= vb2_dma_sg_get_dmabuf,
723	.map_dmabuf	= vb2_dma_sg_map_dmabuf,
724	.unmap_dmabuf	= vb2_dma_sg_unmap_dmabuf,
725	.attach_dmabuf	= vb2_dma_sg_attach_dmabuf,
726	.detach_dmabuf	= vb2_dma_sg_detach_dmabuf,
727	.cookie		= vb2_dma_sg_cookie,
728};
729EXPORT_SYMBOL_GPL(vb2_dma_sg_memops);
730
731void *vb2_dma_sg_init_ctx(struct device *dev)
732{
733	struct vb2_dma_sg_conf *conf;
734
735	conf = kzalloc(sizeof(*conf), GFP_KERNEL);
736	if (!conf)
737		return ERR_PTR(-ENOMEM);
738
739	conf->dev = dev;
740
741	return conf;
742}
743EXPORT_SYMBOL_GPL(vb2_dma_sg_init_ctx);
744
745void vb2_dma_sg_cleanup_ctx(void *alloc_ctx)
746{
747	if (!IS_ERR_OR_NULL(alloc_ctx))
748		kfree(alloc_ctx);
749}
750EXPORT_SYMBOL_GPL(vb2_dma_sg_cleanup_ctx);
751
752MODULE_DESCRIPTION("dma scatter/gather memory handling routines for videobuf2");
753MODULE_AUTHOR("Andrzej Pietrasiewicz");
754MODULE_LICENSE("GPL");
755