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-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        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->nents, buf->dma_dir);
 214}
 215
 216static void vb2_dma_sg_finish(void *buf_priv)
 217{
 218        struct vb2_dma_sg_buf *buf = buf_priv;
 219        struct sg_table *sgt = buf->dma_sgt;
 220
 221        /* DMABUF exporter will flush the cache for us */
 222        if (buf->db_attach)
 223                return;
 224
 225        dma_sync_sg_for_cpu(buf->dev, sgt->sgl, sgt->nents, buf->dma_dir);
 226}
 227
 228static inline int vma_is_io(struct vm_area_struct *vma)
 229{
 230        return !!(vma->vm_flags & (VM_IO | VM_PFNMAP));
 231}
 232
 233static void *vb2_dma_sg_get_userptr(void *alloc_ctx, unsigned long vaddr,
 234                                    unsigned long size,
 235                                    enum dma_data_direction dma_dir)
 236{
 237        struct vb2_dma_sg_conf *conf = alloc_ctx;
 238        struct vb2_dma_sg_buf *buf;
 239        unsigned long first, last;
 240        int num_pages_from_user;
 241        struct vm_area_struct *vma;
 242        struct sg_table *sgt;
 243        DEFINE_DMA_ATTRS(attrs);
 244
 245        dma_set_attr(DMA_ATTR_SKIP_CPU_SYNC, &attrs);
 246
 247        buf = kzalloc(sizeof *buf, GFP_KERNEL);
 248        if (!buf)
 249                return NULL;
 250
 251        buf->vaddr = NULL;
 252        buf->dev = conf->dev;
 253        buf->dma_dir = dma_dir;
 254        buf->offset = vaddr & ~PAGE_MASK;
 255        buf->size = size;
 256        buf->dma_sgt = &buf->sg_table;
 257
 258        first = (vaddr           & PAGE_MASK) >> PAGE_SHIFT;
 259        last  = ((vaddr + size - 1) & PAGE_MASK) >> PAGE_SHIFT;
 260        buf->num_pages = last - first + 1;
 261
 262        buf->pages = kzalloc(buf->num_pages * sizeof(struct page *),
 263                             GFP_KERNEL);
 264        if (!buf->pages)
 265                goto userptr_fail_alloc_pages;
 266
 267        vma = find_vma(current->mm, vaddr);
 268        if (!vma) {
 269                dprintk(1, "no vma for address %lu\n", vaddr);
 270                goto userptr_fail_find_vma;
 271        }
 272
 273        if (vma->vm_end < vaddr + size) {
 274                dprintk(1, "vma at %lu is too small for %lu bytes\n",
 275                        vaddr, size);
 276                goto userptr_fail_find_vma;
 277        }
 278
 279        buf->vma = vb2_get_vma(vma);
 280        if (!buf->vma) {
 281                dprintk(1, "failed to copy vma\n");
 282                goto userptr_fail_find_vma;
 283        }
 284
 285        if (vma_is_io(buf->vma)) {
 286                for (num_pages_from_user = 0;
 287                     num_pages_from_user < buf->num_pages;
 288                     ++num_pages_from_user, vaddr += PAGE_SIZE) {
 289                        unsigned long pfn;
 290
 291                        if (follow_pfn(vma, vaddr, &pfn)) {
 292                                dprintk(1, "no page for address %lu\n", vaddr);
 293                                break;
 294                        }
 295                        buf->pages[num_pages_from_user] = pfn_to_page(pfn);
 296                }
 297        } else
 298                num_pages_from_user = get_user_pages(current, current->mm,
 299                                             vaddr & PAGE_MASK,
 300                                             buf->num_pages,
 301                                             buf->dma_dir == DMA_FROM_DEVICE,
 302                                             1, /* force */
 303                                             buf->pages,
 304                                             NULL);
 305
 306        if (num_pages_from_user != buf->num_pages)
 307                goto userptr_fail_get_user_pages;
 308
 309        if (sg_alloc_table_from_pages(buf->dma_sgt, buf->pages,
 310                        buf->num_pages, buf->offset, size, 0))
 311                goto userptr_fail_alloc_table_from_pages;
 312
 313        sgt = &buf->sg_table;
 314        /*
 315         * No need to sync to the device, this will happen later when the
 316         * prepare() memop is called.
 317         */
 318        sgt->nents = dma_map_sg_attrs(buf->dev, sgt->sgl, sgt->orig_nents,
 319                                      buf->dma_dir, &attrs);
 320        if (!sgt->nents)
 321                goto userptr_fail_map;
 322
 323        return buf;
 324
 325userptr_fail_map:
 326        sg_free_table(&buf->sg_table);
 327userptr_fail_alloc_table_from_pages:
 328userptr_fail_get_user_pages:
 329        dprintk(1, "get_user_pages requested/got: %d/%d]\n",
 330                buf->num_pages, num_pages_from_user);
 331        if (!vma_is_io(buf->vma))
 332                while (--num_pages_from_user >= 0)
 333                        put_page(buf->pages[num_pages_from_user]);
 334        vb2_put_vma(buf->vma);
 335userptr_fail_find_vma:
 336        kfree(buf->pages);
 337userptr_fail_alloc_pages:
 338        kfree(buf);
 339        return NULL;
 340}
 341
 342/*
 343 * @put_userptr: inform the allocator that a USERPTR buffer will no longer
 344 *               be used
 345 */
 346static void vb2_dma_sg_put_userptr(void *buf_priv)
 347{
 348        struct vb2_dma_sg_buf *buf = buf_priv;
 349        struct sg_table *sgt = &buf->sg_table;
 350        int i = buf->num_pages;
 351        DEFINE_DMA_ATTRS(attrs);
 352
 353        dma_set_attr(DMA_ATTR_SKIP_CPU_SYNC, &attrs);
 354
 355        dprintk(1, "%s: Releasing userspace buffer of %d pages\n",
 356               __func__, buf->num_pages);
 357        dma_unmap_sg_attrs(buf->dev, sgt->sgl, sgt->orig_nents, buf->dma_dir,
 358                           &attrs);
 359        if (buf->vaddr)
 360                vm_unmap_ram(buf->vaddr, buf->num_pages);
 361        sg_free_table(buf->dma_sgt);
 362        while (--i >= 0) {
 363                if (buf->dma_dir == DMA_FROM_DEVICE)
 364                        set_page_dirty_lock(buf->pages[i]);
 365                if (!vma_is_io(buf->vma))
 366                        put_page(buf->pages[i]);
 367        }
 368        kfree(buf->pages);
 369        vb2_put_vma(buf->vma);
 370        kfree(buf);
 371}
 372
 373static void *vb2_dma_sg_vaddr(void *buf_priv)
 374{
 375        struct vb2_dma_sg_buf *buf = buf_priv;
 376
 377        BUG_ON(!buf);
 378
 379        if (!buf->vaddr) {
 380                if (buf->db_attach)
 381                        buf->vaddr = dma_buf_vmap(buf->db_attach->dmabuf);
 382                else
 383                        buf->vaddr = vm_map_ram(buf->pages,
 384                                        buf->num_pages, -1, PAGE_KERNEL);
 385        }
 386
 387        /* add offset in case userptr is not page-aligned */
 388        return buf->vaddr ? buf->vaddr + buf->offset : NULL;
 389}
 390
 391static unsigned int vb2_dma_sg_num_users(void *buf_priv)
 392{
 393        struct vb2_dma_sg_buf *buf = buf_priv;
 394
 395        return atomic_read(&buf->refcount);
 396}
 397
 398static int vb2_dma_sg_mmap(void *buf_priv, struct vm_area_struct *vma)
 399{
 400        struct vb2_dma_sg_buf *buf = buf_priv;
 401        unsigned long uaddr = vma->vm_start;
 402        unsigned long usize = vma->vm_end - vma->vm_start;
 403        int i = 0;
 404
 405        if (!buf) {
 406                printk(KERN_ERR "No memory to map\n");
 407                return -EINVAL;
 408        }
 409
 410        do {
 411                int ret;
 412
 413                ret = vm_insert_page(vma, uaddr, buf->pages[i++]);
 414                if (ret) {
 415                        printk(KERN_ERR "Remapping memory, error: %d\n", ret);
 416                        return ret;
 417                }
 418
 419                uaddr += PAGE_SIZE;
 420                usize -= PAGE_SIZE;
 421        } while (usize > 0);
 422
 423
 424        /*
 425         * Use common vm_area operations to track buffer refcount.
 426         */
 427        vma->vm_private_data    = &buf->handler;
 428        vma->vm_ops             = &vb2_common_vm_ops;
 429
 430        vma->vm_ops->open(vma);
 431
 432        return 0;
 433}
 434
 435/*********************************************/
 436/*         DMABUF ops for exporters          */
 437/*********************************************/
 438
 439struct vb2_dma_sg_attachment {
 440        struct sg_table sgt;
 441        enum dma_data_direction dma_dir;
 442};
 443
 444static int vb2_dma_sg_dmabuf_ops_attach(struct dma_buf *dbuf, struct device *dev,
 445        struct dma_buf_attachment *dbuf_attach)
 446{
 447        struct vb2_dma_sg_attachment *attach;
 448        unsigned int i;
 449        struct scatterlist *rd, *wr;
 450        struct sg_table *sgt;
 451        struct vb2_dma_sg_buf *buf = dbuf->priv;
 452        int ret;
 453
 454        attach = kzalloc(sizeof(*attach), GFP_KERNEL);
 455        if (!attach)
 456                return -ENOMEM;
 457
 458        sgt = &attach->sgt;
 459        /* Copy the buf->base_sgt scatter list to the attachment, as we can't
 460         * map the same scatter list to multiple attachments at the same time.
 461         */
 462        ret = sg_alloc_table(sgt, buf->dma_sgt->orig_nents, GFP_KERNEL);
 463        if (ret) {
 464                kfree(attach);
 465                return -ENOMEM;
 466        }
 467
 468        rd = buf->dma_sgt->sgl;
 469        wr = sgt->sgl;
 470        for (i = 0; i < sgt->orig_nents; ++i) {
 471                sg_set_page(wr, sg_page(rd), rd->length, rd->offset);
 472                rd = sg_next(rd);
 473                wr = sg_next(wr);
 474        }
 475
 476        attach->dma_dir = DMA_NONE;
 477        dbuf_attach->priv = attach;
 478
 479        return 0;
 480}
 481
 482static void vb2_dma_sg_dmabuf_ops_detach(struct dma_buf *dbuf,
 483        struct dma_buf_attachment *db_attach)
 484{
 485        struct vb2_dma_sg_attachment *attach = db_attach->priv;
 486        struct sg_table *sgt;
 487
 488        if (!attach)
 489                return;
 490
 491        sgt = &attach->sgt;
 492
 493        /* release the scatterlist cache */
 494        if (attach->dma_dir != DMA_NONE)
 495                dma_unmap_sg(db_attach->dev, sgt->sgl, sgt->orig_nents,
 496                        attach->dma_dir);
 497        sg_free_table(sgt);
 498        kfree(attach);
 499        db_attach->priv = NULL;
 500}
 501
 502static struct sg_table *vb2_dma_sg_dmabuf_ops_map(
 503        struct dma_buf_attachment *db_attach, enum dma_data_direction dma_dir)
 504{
 505        struct vb2_dma_sg_attachment *attach = db_attach->priv;
 506        /* stealing dmabuf mutex to serialize map/unmap operations */
 507        struct mutex *lock = &db_attach->dmabuf->lock;
 508        struct sg_table *sgt;
 509
 510        mutex_lock(lock);
 511
 512        sgt = &attach->sgt;
 513        /* return previously mapped sg table */
 514        if (attach->dma_dir == dma_dir) {
 515                mutex_unlock(lock);
 516                return sgt;
 517        }
 518
 519        /* release any previous cache */
 520        if (attach->dma_dir != DMA_NONE) {
 521                dma_unmap_sg(db_attach->dev, sgt->sgl, sgt->orig_nents,
 522                        attach->dma_dir);
 523                attach->dma_dir = DMA_NONE;
 524        }
 525
 526        /* mapping to the client with new direction */
 527        sgt->nents = dma_map_sg(db_attach->dev, sgt->sgl, sgt->orig_nents,
 528                                dma_dir);
 529        if (!sgt->nents) {
 530                pr_err("failed to map scatterlist\n");
 531                mutex_unlock(lock);
 532                return ERR_PTR(-EIO);
 533        }
 534
 535        attach->dma_dir = dma_dir;
 536
 537        mutex_unlock(lock);
 538
 539        return sgt;
 540}
 541
 542static void vb2_dma_sg_dmabuf_ops_unmap(struct dma_buf_attachment *db_attach,
 543        struct sg_table *sgt, enum dma_data_direction dma_dir)
 544{
 545        /* nothing to be done here */
 546}
 547
 548static void vb2_dma_sg_dmabuf_ops_release(struct dma_buf *dbuf)
 549{
 550        /* drop reference obtained in vb2_dma_sg_get_dmabuf */
 551        vb2_dma_sg_put(dbuf->priv);
 552}
 553
 554static void *vb2_dma_sg_dmabuf_ops_kmap(struct dma_buf *dbuf, unsigned long pgnum)
 555{
 556        struct vb2_dma_sg_buf *buf = dbuf->priv;
 557
 558        return buf->vaddr ? buf->vaddr + pgnum * PAGE_SIZE : NULL;
 559}
 560
 561static void *vb2_dma_sg_dmabuf_ops_vmap(struct dma_buf *dbuf)
 562{
 563        struct vb2_dma_sg_buf *buf = dbuf->priv;
 564
 565        return vb2_dma_sg_vaddr(buf);
 566}
 567
 568static int vb2_dma_sg_dmabuf_ops_mmap(struct dma_buf *dbuf,
 569        struct vm_area_struct *vma)
 570{
 571        return vb2_dma_sg_mmap(dbuf->priv, vma);
 572}
 573
 574static struct dma_buf_ops vb2_dma_sg_dmabuf_ops = {
 575        .attach = vb2_dma_sg_dmabuf_ops_attach,
 576        .detach = vb2_dma_sg_dmabuf_ops_detach,
 577        .map_dma_buf = vb2_dma_sg_dmabuf_ops_map,
 578        .unmap_dma_buf = vb2_dma_sg_dmabuf_ops_unmap,
 579        .kmap = vb2_dma_sg_dmabuf_ops_kmap,
 580        .kmap_atomic = vb2_dma_sg_dmabuf_ops_kmap,
 581        .vmap = vb2_dma_sg_dmabuf_ops_vmap,
 582        .mmap = vb2_dma_sg_dmabuf_ops_mmap,
 583        .release = vb2_dma_sg_dmabuf_ops_release,
 584};
 585
 586static struct dma_buf *vb2_dma_sg_get_dmabuf(void *buf_priv, unsigned long flags)
 587{
 588        struct vb2_dma_sg_buf *buf = buf_priv;
 589        struct dma_buf *dbuf;
 590        DEFINE_DMA_BUF_EXPORT_INFO(exp_info);
 591
 592        exp_info.ops = &vb2_dma_sg_dmabuf_ops;
 593        exp_info.size = buf->size;
 594        exp_info.flags = flags;
 595        exp_info.priv = buf;
 596
 597        if (WARN_ON(!buf->dma_sgt))
 598                return NULL;
 599
 600        dbuf = dma_buf_export(&exp_info);
 601        if (IS_ERR(dbuf))
 602                return NULL;
 603
 604        /* dmabuf keeps reference to vb2 buffer */
 605        atomic_inc(&buf->refcount);
 606
 607        return dbuf;
 608}
 609
 610/*********************************************/
 611/*       callbacks for DMABUF buffers        */
 612/*********************************************/
 613
 614static int vb2_dma_sg_map_dmabuf(void *mem_priv)
 615{
 616        struct vb2_dma_sg_buf *buf = mem_priv;
 617        struct sg_table *sgt;
 618
 619        if (WARN_ON(!buf->db_attach)) {
 620                pr_err("trying to pin a non attached buffer\n");
 621                return -EINVAL;
 622        }
 623
 624        if (WARN_ON(buf->dma_sgt)) {
 625                pr_err("dmabuf buffer is already pinned\n");
 626                return 0;
 627        }
 628
 629        /* get the associated scatterlist for this buffer */
 630        sgt = dma_buf_map_attachment(buf->db_attach, buf->dma_dir);
 631        if (IS_ERR(sgt)) {
 632                pr_err("Error getting dmabuf scatterlist\n");
 633                return -EINVAL;
 634        }
 635
 636        buf->dma_sgt = sgt;
 637        buf->vaddr = NULL;
 638
 639        return 0;
 640}
 641
 642static void vb2_dma_sg_unmap_dmabuf(void *mem_priv)
 643{
 644        struct vb2_dma_sg_buf *buf = mem_priv;
 645        struct sg_table *sgt = buf->dma_sgt;
 646
 647        if (WARN_ON(!buf->db_attach)) {
 648                pr_err("trying to unpin a not attached buffer\n");
 649                return;
 650        }
 651
 652        if (WARN_ON(!sgt)) {
 653                pr_err("dmabuf buffer is already unpinned\n");
 654                return;
 655        }
 656
 657        if (buf->vaddr) {
 658                dma_buf_vunmap(buf->db_attach->dmabuf, buf->vaddr);
 659                buf->vaddr = NULL;
 660        }
 661        dma_buf_unmap_attachment(buf->db_attach, sgt, buf->dma_dir);
 662
 663        buf->dma_sgt = NULL;
 664}
 665
 666static void vb2_dma_sg_detach_dmabuf(void *mem_priv)
 667{
 668        struct vb2_dma_sg_buf *buf = mem_priv;
 669
 670        /* if vb2 works correctly you should never detach mapped buffer */
 671        if (WARN_ON(buf->dma_sgt))
 672                vb2_dma_sg_unmap_dmabuf(buf);
 673
 674        /* detach this attachment */
 675        dma_buf_detach(buf->db_attach->dmabuf, buf->db_attach);
 676        kfree(buf);
 677}
 678
 679static void *vb2_dma_sg_attach_dmabuf(void *alloc_ctx, struct dma_buf *dbuf,
 680        unsigned long size, enum dma_data_direction dma_dir)
 681{
 682        struct vb2_dma_sg_conf *conf = alloc_ctx;
 683        struct vb2_dma_sg_buf *buf;
 684        struct dma_buf_attachment *dba;
 685
 686        if (dbuf->size < size)
 687                return ERR_PTR(-EFAULT);
 688
 689        buf = kzalloc(sizeof(*buf), GFP_KERNEL);
 690        if (!buf)
 691                return ERR_PTR(-ENOMEM);
 692
 693        buf->dev = conf->dev;
 694        /* create attachment for the dmabuf with the user device */
 695        dba = dma_buf_attach(dbuf, buf->dev);
 696        if (IS_ERR(dba)) {
 697                pr_err("failed to attach dmabuf\n");
 698                kfree(buf);
 699                return dba;
 700        }
 701
 702        buf->dma_dir = dma_dir;
 703        buf->size = size;
 704        buf->db_attach = dba;
 705
 706        return buf;
 707}
 708
 709static void *vb2_dma_sg_cookie(void *buf_priv)
 710{
 711        struct vb2_dma_sg_buf *buf = buf_priv;
 712
 713        return buf->dma_sgt;
 714}
 715
 716const struct vb2_mem_ops vb2_dma_sg_memops = {
 717        .alloc          = vb2_dma_sg_alloc,
 718        .put            = vb2_dma_sg_put,
 719        .get_userptr    = vb2_dma_sg_get_userptr,
 720        .put_userptr    = vb2_dma_sg_put_userptr,
 721        .prepare        = vb2_dma_sg_prepare,
 722        .finish         = vb2_dma_sg_finish,
 723        .vaddr          = vb2_dma_sg_vaddr,
 724        .mmap           = vb2_dma_sg_mmap,
 725        .num_users      = vb2_dma_sg_num_users,
 726        .get_dmabuf     = vb2_dma_sg_get_dmabuf,
 727        .map_dmabuf     = vb2_dma_sg_map_dmabuf,
 728        .unmap_dmabuf   = vb2_dma_sg_unmap_dmabuf,
 729        .attach_dmabuf  = vb2_dma_sg_attach_dmabuf,
 730        .detach_dmabuf  = vb2_dma_sg_detach_dmabuf,
 731        .cookie         = vb2_dma_sg_cookie,
 732};
 733EXPORT_SYMBOL_GPL(vb2_dma_sg_memops);
 734
 735void *vb2_dma_sg_init_ctx(struct device *dev)
 736{
 737        struct vb2_dma_sg_conf *conf;
 738
 739        conf = kzalloc(sizeof(*conf), GFP_KERNEL);
 740        if (!conf)
 741                return ERR_PTR(-ENOMEM);
 742
 743        conf->dev = dev;
 744
 745        return conf;
 746}
 747EXPORT_SYMBOL_GPL(vb2_dma_sg_init_ctx);
 748
 749void vb2_dma_sg_cleanup_ctx(void *alloc_ctx)
 750{
 751        if (!IS_ERR_OR_NULL(alloc_ctx))
 752                kfree(alloc_ctx);
 753}
 754EXPORT_SYMBOL_GPL(vb2_dma_sg_cleanup_ctx);
 755
 756MODULE_DESCRIPTION("dma scatter/gather memory handling routines for videobuf2");
 757MODULE_AUTHOR("Andrzej Pietrasiewicz");
 758MODULE_LICENSE("GPL");
 759