linux/drivers/media/v4l2-core/videobuf2-dma-sg.c
<<
>>
Prefs
   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-v4l2.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        struct frame_vector             *vec;
  42        int                             offset;
  43        enum dma_data_direction         dma_dir;
  44        struct sg_table                 sg_table;
  45        /*
  46         * This will point to sg_table when used with the MMAP or USERPTR
  47         * memory model, and to the dma_buf sglist when used with the
  48         * DMABUF memory model.
  49         */
  50        struct sg_table                 *dma_sgt;
  51        size_t                          size;
  52        unsigned int                    num_pages;
  53        atomic_t                        refcount;
  54        struct vb2_vmarea_handler       handler;
  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        sgt->nents = dma_map_sg_attrs(buf->dev, sgt->sgl, sgt->orig_nents,
 151                                      buf->dma_dir, &attrs);
 152        if (!sgt->nents)
 153                goto fail_map;
 154
 155        buf->handler.refcount = &buf->refcount;
 156        buf->handler.put = vb2_dma_sg_put;
 157        buf->handler.arg = buf;
 158
 159        atomic_inc(&buf->refcount);
 160
 161        dprintk(1, "%s: Allocated buffer of %d pages\n",
 162                __func__, buf->num_pages);
 163        return buf;
 164
 165fail_map:
 166        put_device(buf->dev);
 167        sg_free_table(buf->dma_sgt);
 168fail_table_alloc:
 169        num_pages = buf->num_pages;
 170        while (num_pages--)
 171                __free_page(buf->pages[num_pages]);
 172fail_pages_alloc:
 173        kfree(buf->pages);
 174fail_pages_array_alloc:
 175        kfree(buf);
 176        return NULL;
 177}
 178
 179static void vb2_dma_sg_put(void *buf_priv)
 180{
 181        struct vb2_dma_sg_buf *buf = buf_priv;
 182        struct sg_table *sgt = &buf->sg_table;
 183        int i = buf->num_pages;
 184
 185        if (atomic_dec_and_test(&buf->refcount)) {
 186                DEFINE_DMA_ATTRS(attrs);
 187
 188                dma_set_attr(DMA_ATTR_SKIP_CPU_SYNC, &attrs);
 189                dprintk(1, "%s: Freeing buffer of %d pages\n", __func__,
 190                        buf->num_pages);
 191                dma_unmap_sg_attrs(buf->dev, sgt->sgl, sgt->orig_nents,
 192                                   buf->dma_dir, &attrs);
 193                if (buf->vaddr)
 194                        vm_unmap_ram(buf->vaddr, buf->num_pages);
 195                sg_free_table(buf->dma_sgt);
 196                while (--i >= 0)
 197                        __free_page(buf->pages[i]);
 198                kfree(buf->pages);
 199                put_device(buf->dev);
 200                kfree(buf);
 201        }
 202}
 203
 204static void vb2_dma_sg_prepare(void *buf_priv)
 205{
 206        struct vb2_dma_sg_buf *buf = buf_priv;
 207        struct sg_table *sgt = buf->dma_sgt;
 208
 209        /* DMABUF exporter will flush the cache for us */
 210        if (buf->db_attach)
 211                return;
 212
 213        dma_sync_sg_for_device(buf->dev, sgt->sgl, sgt->orig_nents,
 214                               buf->dma_dir);
 215}
 216
 217static void vb2_dma_sg_finish(void *buf_priv)
 218{
 219        struct vb2_dma_sg_buf *buf = buf_priv;
 220        struct sg_table *sgt = buf->dma_sgt;
 221
 222        /* DMABUF exporter will flush the cache for us */
 223        if (buf->db_attach)
 224                return;
 225
 226        dma_sync_sg_for_cpu(buf->dev, sgt->sgl, sgt->orig_nents, buf->dma_dir);
 227}
 228
 229static void *vb2_dma_sg_get_userptr(void *alloc_ctx, unsigned long vaddr,
 230                                    unsigned long size,
 231                                    enum dma_data_direction dma_dir)
 232{
 233        struct vb2_dma_sg_conf *conf = alloc_ctx;
 234        struct vb2_dma_sg_buf *buf;
 235        struct sg_table *sgt;
 236        DEFINE_DMA_ATTRS(attrs);
 237        struct frame_vector *vec;
 238
 239        dma_set_attr(DMA_ATTR_SKIP_CPU_SYNC, &attrs);
 240        buf = kzalloc(sizeof *buf, GFP_KERNEL);
 241        if (!buf)
 242                return NULL;
 243
 244        buf->vaddr = NULL;
 245        buf->dev = conf->dev;
 246        buf->dma_dir = dma_dir;
 247        buf->offset = vaddr & ~PAGE_MASK;
 248        buf->size = size;
 249        buf->dma_sgt = &buf->sg_table;
 250        vec = vb2_create_framevec(vaddr, size, buf->dma_dir == DMA_FROM_DEVICE);
 251        if (IS_ERR(vec))
 252                goto userptr_fail_pfnvec;
 253        buf->vec = vec;
 254
 255        buf->pages = frame_vector_pages(vec);
 256        if (IS_ERR(buf->pages))
 257                goto userptr_fail_sgtable;
 258        buf->num_pages = frame_vector_count(vec);
 259
 260        if (sg_alloc_table_from_pages(buf->dma_sgt, buf->pages,
 261                        buf->num_pages, buf->offset, size, 0))
 262                goto userptr_fail_sgtable;
 263
 264        sgt = &buf->sg_table;
 265        /*
 266         * No need to sync to the device, this will happen later when the
 267         * prepare() memop is called.
 268         */
 269        sgt->nents = dma_map_sg_attrs(buf->dev, sgt->sgl, sgt->orig_nents,
 270                                      buf->dma_dir, &attrs);
 271        if (!sgt->nents)
 272                goto userptr_fail_map;
 273
 274        return buf;
 275
 276userptr_fail_map:
 277        sg_free_table(&buf->sg_table);
 278userptr_fail_sgtable:
 279        vb2_destroy_framevec(vec);
 280userptr_fail_pfnvec:
 281        kfree(buf);
 282        return NULL;
 283}
 284
 285/*
 286 * @put_userptr: inform the allocator that a USERPTR buffer will no longer
 287 *               be used
 288 */
 289static void vb2_dma_sg_put_userptr(void *buf_priv)
 290{
 291        struct vb2_dma_sg_buf *buf = buf_priv;
 292        struct sg_table *sgt = &buf->sg_table;
 293        int i = buf->num_pages;
 294        DEFINE_DMA_ATTRS(attrs);
 295
 296        dma_set_attr(DMA_ATTR_SKIP_CPU_SYNC, &attrs);
 297
 298        dprintk(1, "%s: Releasing userspace buffer of %d pages\n",
 299               __func__, buf->num_pages);
 300        dma_unmap_sg_attrs(buf->dev, sgt->sgl, sgt->orig_nents, buf->dma_dir,
 301                           &attrs);
 302        if (buf->vaddr)
 303                vm_unmap_ram(buf->vaddr, buf->num_pages);
 304        sg_free_table(buf->dma_sgt);
 305        while (--i >= 0) {
 306                if (buf->dma_dir == DMA_FROM_DEVICE)
 307                        set_page_dirty_lock(buf->pages[i]);
 308        }
 309        vb2_destroy_framevec(buf->vec);
 310        kfree(buf);
 311}
 312
 313static void *vb2_dma_sg_vaddr(void *buf_priv)
 314{
 315        struct vb2_dma_sg_buf *buf = buf_priv;
 316
 317        BUG_ON(!buf);
 318
 319        if (!buf->vaddr) {
 320                if (buf->db_attach)
 321                        buf->vaddr = dma_buf_vmap(buf->db_attach->dmabuf);
 322                else
 323                        buf->vaddr = vm_map_ram(buf->pages,
 324                                        buf->num_pages, -1, PAGE_KERNEL);
 325        }
 326
 327        /* add offset in case userptr is not page-aligned */
 328        return buf->vaddr ? buf->vaddr + buf->offset : NULL;
 329}
 330
 331static unsigned int vb2_dma_sg_num_users(void *buf_priv)
 332{
 333        struct vb2_dma_sg_buf *buf = buf_priv;
 334
 335        return atomic_read(&buf->refcount);
 336}
 337
 338static int vb2_dma_sg_mmap(void *buf_priv, struct vm_area_struct *vma)
 339{
 340        struct vb2_dma_sg_buf *buf = buf_priv;
 341        unsigned long uaddr = vma->vm_start;
 342        unsigned long usize = vma->vm_end - vma->vm_start;
 343        int i = 0;
 344
 345        if (!buf) {
 346                printk(KERN_ERR "No memory to map\n");
 347                return -EINVAL;
 348        }
 349
 350        do {
 351                int ret;
 352
 353                ret = vm_insert_page(vma, uaddr, buf->pages[i++]);
 354                if (ret) {
 355                        printk(KERN_ERR "Remapping memory, error: %d\n", ret);
 356                        return ret;
 357                }
 358
 359                uaddr += PAGE_SIZE;
 360                usize -= PAGE_SIZE;
 361        } while (usize > 0);
 362
 363
 364        /*
 365         * Use common vm_area operations to track buffer refcount.
 366         */
 367        vma->vm_private_data    = &buf->handler;
 368        vma->vm_ops             = &vb2_common_vm_ops;
 369
 370        vma->vm_ops->open(vma);
 371
 372        return 0;
 373}
 374
 375/*********************************************/
 376/*         DMABUF ops for exporters          */
 377/*********************************************/
 378
 379struct vb2_dma_sg_attachment {
 380        struct sg_table sgt;
 381        enum dma_data_direction dma_dir;
 382};
 383
 384static int vb2_dma_sg_dmabuf_ops_attach(struct dma_buf *dbuf, struct device *dev,
 385        struct dma_buf_attachment *dbuf_attach)
 386{
 387        struct vb2_dma_sg_attachment *attach;
 388        unsigned int i;
 389        struct scatterlist *rd, *wr;
 390        struct sg_table *sgt;
 391        struct vb2_dma_sg_buf *buf = dbuf->priv;
 392        int ret;
 393
 394        attach = kzalloc(sizeof(*attach), GFP_KERNEL);
 395        if (!attach)
 396                return -ENOMEM;
 397
 398        sgt = &attach->sgt;
 399        /* Copy the buf->base_sgt scatter list to the attachment, as we can't
 400         * map the same scatter list to multiple attachments at the same time.
 401         */
 402        ret = sg_alloc_table(sgt, buf->dma_sgt->orig_nents, GFP_KERNEL);
 403        if (ret) {
 404                kfree(attach);
 405                return -ENOMEM;
 406        }
 407
 408        rd = buf->dma_sgt->sgl;
 409        wr = sgt->sgl;
 410        for (i = 0; i < sgt->orig_nents; ++i) {
 411                sg_set_page(wr, sg_page(rd), rd->length, rd->offset);
 412                rd = sg_next(rd);
 413                wr = sg_next(wr);
 414        }
 415
 416        attach->dma_dir = DMA_NONE;
 417        dbuf_attach->priv = attach;
 418
 419        return 0;
 420}
 421
 422static void vb2_dma_sg_dmabuf_ops_detach(struct dma_buf *dbuf,
 423        struct dma_buf_attachment *db_attach)
 424{
 425        struct vb2_dma_sg_attachment *attach = db_attach->priv;
 426        struct sg_table *sgt;
 427
 428        if (!attach)
 429                return;
 430
 431        sgt = &attach->sgt;
 432
 433        /* release the scatterlist cache */
 434        if (attach->dma_dir != DMA_NONE)
 435                dma_unmap_sg(db_attach->dev, sgt->sgl, sgt->orig_nents,
 436                        attach->dma_dir);
 437        sg_free_table(sgt);
 438        kfree(attach);
 439        db_attach->priv = NULL;
 440}
 441
 442static struct sg_table *vb2_dma_sg_dmabuf_ops_map(
 443        struct dma_buf_attachment *db_attach, enum dma_data_direction dma_dir)
 444{
 445        struct vb2_dma_sg_attachment *attach = db_attach->priv;
 446        /* stealing dmabuf mutex to serialize map/unmap operations */
 447        struct mutex *lock = &db_attach->dmabuf->lock;
 448        struct sg_table *sgt;
 449
 450        mutex_lock(lock);
 451
 452        sgt = &attach->sgt;
 453        /* return previously mapped sg table */
 454        if (attach->dma_dir == dma_dir) {
 455                mutex_unlock(lock);
 456                return sgt;
 457        }
 458
 459        /* release any previous cache */
 460        if (attach->dma_dir != DMA_NONE) {
 461                dma_unmap_sg(db_attach->dev, sgt->sgl, sgt->orig_nents,
 462                        attach->dma_dir);
 463                attach->dma_dir = DMA_NONE;
 464        }
 465
 466        /* mapping to the client with new direction */
 467        sgt->nents = dma_map_sg(db_attach->dev, sgt->sgl, sgt->orig_nents,
 468                                dma_dir);
 469        if (!sgt->nents) {
 470                pr_err("failed to map scatterlist\n");
 471                mutex_unlock(lock);
 472                return ERR_PTR(-EIO);
 473        }
 474
 475        attach->dma_dir = dma_dir;
 476
 477        mutex_unlock(lock);
 478
 479        return sgt;
 480}
 481
 482static void vb2_dma_sg_dmabuf_ops_unmap(struct dma_buf_attachment *db_attach,
 483        struct sg_table *sgt, enum dma_data_direction dma_dir)
 484{
 485        /* nothing to be done here */
 486}
 487
 488static void vb2_dma_sg_dmabuf_ops_release(struct dma_buf *dbuf)
 489{
 490        /* drop reference obtained in vb2_dma_sg_get_dmabuf */
 491        vb2_dma_sg_put(dbuf->priv);
 492}
 493
 494static void *vb2_dma_sg_dmabuf_ops_kmap(struct dma_buf *dbuf, unsigned long pgnum)
 495{
 496        struct vb2_dma_sg_buf *buf = dbuf->priv;
 497
 498        return buf->vaddr ? buf->vaddr + pgnum * PAGE_SIZE : NULL;
 499}
 500
 501static void *vb2_dma_sg_dmabuf_ops_vmap(struct dma_buf *dbuf)
 502{
 503        struct vb2_dma_sg_buf *buf = dbuf->priv;
 504
 505        return vb2_dma_sg_vaddr(buf);
 506}
 507
 508static int vb2_dma_sg_dmabuf_ops_mmap(struct dma_buf *dbuf,
 509        struct vm_area_struct *vma)
 510{
 511        return vb2_dma_sg_mmap(dbuf->priv, vma);
 512}
 513
 514static struct dma_buf_ops vb2_dma_sg_dmabuf_ops = {
 515        .attach = vb2_dma_sg_dmabuf_ops_attach,
 516        .detach = vb2_dma_sg_dmabuf_ops_detach,
 517        .map_dma_buf = vb2_dma_sg_dmabuf_ops_map,
 518        .unmap_dma_buf = vb2_dma_sg_dmabuf_ops_unmap,
 519        .kmap = vb2_dma_sg_dmabuf_ops_kmap,
 520        .kmap_atomic = vb2_dma_sg_dmabuf_ops_kmap,
 521        .vmap = vb2_dma_sg_dmabuf_ops_vmap,
 522        .mmap = vb2_dma_sg_dmabuf_ops_mmap,
 523        .release = vb2_dma_sg_dmabuf_ops_release,
 524};
 525
 526static struct dma_buf *vb2_dma_sg_get_dmabuf(void *buf_priv, unsigned long flags)
 527{
 528        struct vb2_dma_sg_buf *buf = buf_priv;
 529        struct dma_buf *dbuf;
 530        DEFINE_DMA_BUF_EXPORT_INFO(exp_info);
 531
 532        exp_info.ops = &vb2_dma_sg_dmabuf_ops;
 533        exp_info.size = buf->size;
 534        exp_info.flags = flags;
 535        exp_info.priv = buf;
 536
 537        if (WARN_ON(!buf->dma_sgt))
 538                return NULL;
 539
 540        dbuf = dma_buf_export(&exp_info);
 541        if (IS_ERR(dbuf))
 542                return NULL;
 543
 544        /* dmabuf keeps reference to vb2 buffer */
 545        atomic_inc(&buf->refcount);
 546
 547        return dbuf;
 548}
 549
 550/*********************************************/
 551/*       callbacks for DMABUF buffers        */
 552/*********************************************/
 553
 554static int vb2_dma_sg_map_dmabuf(void *mem_priv)
 555{
 556        struct vb2_dma_sg_buf *buf = mem_priv;
 557        struct sg_table *sgt;
 558
 559        if (WARN_ON(!buf->db_attach)) {
 560                pr_err("trying to pin a non attached buffer\n");
 561                return -EINVAL;
 562        }
 563
 564        if (WARN_ON(buf->dma_sgt)) {
 565                pr_err("dmabuf buffer is already pinned\n");
 566                return 0;
 567        }
 568
 569        /* get the associated scatterlist for this buffer */
 570        sgt = dma_buf_map_attachment(buf->db_attach, buf->dma_dir);
 571        if (IS_ERR(sgt)) {
 572                pr_err("Error getting dmabuf scatterlist\n");
 573                return -EINVAL;
 574        }
 575
 576        buf->dma_sgt = sgt;
 577        buf->vaddr = NULL;
 578
 579        return 0;
 580}
 581
 582static void vb2_dma_sg_unmap_dmabuf(void *mem_priv)
 583{
 584        struct vb2_dma_sg_buf *buf = mem_priv;
 585        struct sg_table *sgt = buf->dma_sgt;
 586
 587        if (WARN_ON(!buf->db_attach)) {
 588                pr_err("trying to unpin a not attached buffer\n");
 589                return;
 590        }
 591
 592        if (WARN_ON(!sgt)) {
 593                pr_err("dmabuf buffer is already unpinned\n");
 594                return;
 595        }
 596
 597        if (buf->vaddr) {
 598                dma_buf_vunmap(buf->db_attach->dmabuf, buf->vaddr);
 599                buf->vaddr = NULL;
 600        }
 601        dma_buf_unmap_attachment(buf->db_attach, sgt, buf->dma_dir);
 602
 603        buf->dma_sgt = NULL;
 604}
 605
 606static void vb2_dma_sg_detach_dmabuf(void *mem_priv)
 607{
 608        struct vb2_dma_sg_buf *buf = mem_priv;
 609
 610        /* if vb2 works correctly you should never detach mapped buffer */
 611        if (WARN_ON(buf->dma_sgt))
 612                vb2_dma_sg_unmap_dmabuf(buf);
 613
 614        /* detach this attachment */
 615        dma_buf_detach(buf->db_attach->dmabuf, buf->db_attach);
 616        kfree(buf);
 617}
 618
 619static void *vb2_dma_sg_attach_dmabuf(void *alloc_ctx, struct dma_buf *dbuf,
 620        unsigned long size, enum dma_data_direction dma_dir)
 621{
 622        struct vb2_dma_sg_conf *conf = alloc_ctx;
 623        struct vb2_dma_sg_buf *buf;
 624        struct dma_buf_attachment *dba;
 625
 626        if (dbuf->size < size)
 627                return ERR_PTR(-EFAULT);
 628
 629        buf = kzalloc(sizeof(*buf), GFP_KERNEL);
 630        if (!buf)
 631                return ERR_PTR(-ENOMEM);
 632
 633        buf->dev = conf->dev;
 634        /* create attachment for the dmabuf with the user device */
 635        dba = dma_buf_attach(dbuf, buf->dev);
 636        if (IS_ERR(dba)) {
 637                pr_err("failed to attach dmabuf\n");
 638                kfree(buf);
 639                return dba;
 640        }
 641
 642        buf->dma_dir = dma_dir;
 643        buf->size = size;
 644        buf->db_attach = dba;
 645
 646        return buf;
 647}
 648
 649static void *vb2_dma_sg_cookie(void *buf_priv)
 650{
 651        struct vb2_dma_sg_buf *buf = buf_priv;
 652
 653        return buf->dma_sgt;
 654}
 655
 656const struct vb2_mem_ops vb2_dma_sg_memops = {
 657        .alloc          = vb2_dma_sg_alloc,
 658        .put            = vb2_dma_sg_put,
 659        .get_userptr    = vb2_dma_sg_get_userptr,
 660        .put_userptr    = vb2_dma_sg_put_userptr,
 661        .prepare        = vb2_dma_sg_prepare,
 662        .finish         = vb2_dma_sg_finish,
 663        .vaddr          = vb2_dma_sg_vaddr,
 664        .mmap           = vb2_dma_sg_mmap,
 665        .num_users      = vb2_dma_sg_num_users,
 666        .get_dmabuf     = vb2_dma_sg_get_dmabuf,
 667        .map_dmabuf     = vb2_dma_sg_map_dmabuf,
 668        .unmap_dmabuf   = vb2_dma_sg_unmap_dmabuf,
 669        .attach_dmabuf  = vb2_dma_sg_attach_dmabuf,
 670        .detach_dmabuf  = vb2_dma_sg_detach_dmabuf,
 671        .cookie         = vb2_dma_sg_cookie,
 672};
 673EXPORT_SYMBOL_GPL(vb2_dma_sg_memops);
 674
 675void *vb2_dma_sg_init_ctx(struct device *dev)
 676{
 677        struct vb2_dma_sg_conf *conf;
 678
 679        conf = kzalloc(sizeof(*conf), GFP_KERNEL);
 680        if (!conf)
 681                return ERR_PTR(-ENOMEM);
 682
 683        conf->dev = dev;
 684
 685        return conf;
 686}
 687EXPORT_SYMBOL_GPL(vb2_dma_sg_init_ctx);
 688
 689void vb2_dma_sg_cleanup_ctx(void *alloc_ctx)
 690{
 691        if (!IS_ERR_OR_NULL(alloc_ctx))
 692                kfree(alloc_ctx);
 693}
 694EXPORT_SYMBOL_GPL(vb2_dma_sg_cleanup_ctx);
 695
 696MODULE_DESCRIPTION("dma scatter/gather memory handling routines for videobuf2");
 697MODULE_AUTHOR("Andrzej Pietrasiewicz");
 698MODULE_LICENSE("GPL");
 699