Re: [PATCH 2/2] dma-buf: add helpers for attacher dma-parms

2012-08-06 Thread Tomasz Stanislawski
On 08/06/2012 01:58 PM, Michal Nazarewicz wrote:
> 
> Tomasz Stanislawski  writes:
>> I recommend to change the semantics for unlimited number of segments
>> from 'value 0' to:
>>
>> #define DMA_SEGMENTS_COUNT_UNLIMITED ((unsigned long)INT_MAX)

Sorry. It should be:
#define DMA_SEGMENTS_COUNT_UNLIMITED ((unsigned int)INT_MAX)

>>
>> Using INT_MAX will allow using safe conversions between signed and
>> unsigned integers.
> 
> LONG_MAX seems cleaner regardless.
> 
> 
> 

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] dma-buf: add reference counting for exporter module

2012-08-08 Thread Tomasz Stanislawski
This patch adds reference counting on a module that exports dma-buf and
implements its operations. This prevents the module from being unloaded while
DMABUF file is in use.

Signed-off-by: Tomasz Stanislawski 
---
 Documentation/dma-buf-sharing.txt  |3 ++-
 drivers/base/dma-buf.c |   10 +-
 drivers/gpu/drm/exynos/exynos_drm_dmabuf.c |1 +
 drivers/gpu/drm/i915/i915_gem_dmabuf.c |1 +
 drivers/gpu/drm/nouveau/nouveau_prime.c|1 +
 drivers/gpu/drm/radeon/radeon_prime.c  |1 +
 drivers/staging/omapdrm/omap_gem_dmabuf.c  |1 +
 include/linux/dma-buf.h|2 ++
 8 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/Documentation/dma-buf-sharing.txt 
b/Documentation/dma-buf-sharing.txt
index ad86fb8..2613057 100644
--- a/Documentation/dma-buf-sharing.txt
+++ b/Documentation/dma-buf-sharing.txt
@@ -49,7 +49,8 @@ The dma_buf buffer sharing API usage contains the following 
steps:
The buffer exporter announces its wish to export a buffer. In this, it
connects its own private buffer data, provides implementation for operations
that can be performed on the exported dma_buf, and flags for the file
-   associated with this buffer.
+   associated with this buffer. The operations structure has owner field.
+   You should initialize this to THIS_MODULE in most cases.

Interface:
   struct dma_buf *dma_buf_export(void *priv, struct dma_buf_ops *ops,
diff --git a/drivers/base/dma-buf.c b/drivers/base/dma-buf.c
index c30f3e1..d14b2f5 100644
--- a/drivers/base/dma-buf.c
+++ b/drivers/base/dma-buf.c
@@ -27,6 +27,7 @@
 #include 
 #include 
 #include 
+#include 

 static inline int is_dma_buf_file(struct file *);

@@ -40,6 +41,7 @@ static int dma_buf_release(struct inode *inode, struct file 
*file)
dmabuf = file->private_data;

dmabuf->ops->release(dmabuf);
+   module_put(dmabuf->ops->owner);
kfree(dmabuf);
return 0;
 }
@@ -96,6 +98,7 @@ struct dma_buf *dma_buf_export(void *priv, const struct 
dma_buf_ops *ops,
struct file *file;

if (WARN_ON(!priv || !ops
+ || !ops->owner
  || !ops->map_dma_buf
  || !ops->unmap_dma_buf
  || !ops->release
@@ -105,9 +108,14 @@ struct dma_buf *dma_buf_export(void *priv, const struct 
dma_buf_ops *ops,
return ERR_PTR(-EINVAL);
}

+   if (!try_module_get(ops->owner))
+   return ERR_PTR(-ENOENT);
+
dmabuf = kzalloc(sizeof(struct dma_buf), GFP_KERNEL);
-   if (dmabuf == NULL)
+   if (dmabuf == NULL) {
+   module_put(ops->owner);
return ERR_PTR(-ENOMEM);
+   }

dmabuf->priv = priv;
dmabuf->ops = ops;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c 
b/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c
index 613bf8a..cf3bc6d 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c
@@ -164,6 +164,7 @@ static void exynos_gem_dmabuf_kunmap(struct dma_buf 
*dma_buf,
 }

 static struct dma_buf_ops exynos_dmabuf_ops = {
+   .owner  = THIS_MODULE,
.map_dma_buf= exynos_gem_map_dma_buf,
.unmap_dma_buf  = exynos_gem_unmap_dma_buf,
.kmap   = exynos_gem_dmabuf_kmap,
diff --git a/drivers/gpu/drm/i915/i915_gem_dmabuf.c 
b/drivers/gpu/drm/i915/i915_gem_dmabuf.c
index aa308e1..07ff03b 100644
--- a/drivers/gpu/drm/i915/i915_gem_dmabuf.c
+++ b/drivers/gpu/drm/i915/i915_gem_dmabuf.c
@@ -152,6 +152,7 @@ static int i915_gem_dmabuf_mmap(struct dma_buf *dma_buf, 
struct vm_area_struct *
 }

 static const struct dma_buf_ops i915_dmabuf_ops =  {
+   .owner = THIS_MODULE,
.map_dma_buf = i915_gem_map_dma_buf,
.unmap_dma_buf = i915_gem_unmap_dma_buf,
.release = i915_gem_dmabuf_release,
diff --git a/drivers/gpu/drm/nouveau/nouveau_prime.c 
b/drivers/gpu/drm/nouveau/nouveau_prime.c
index a25cf2c..8605033 100644
--- a/drivers/gpu/drm/nouveau/nouveau_prime.c
+++ b/drivers/gpu/drm/nouveau/nouveau_prime.c
@@ -127,6 +127,7 @@ static void nouveau_gem_prime_vunmap(struct dma_buf 
*dma_buf, void *vaddr)
 }

 static const struct dma_buf_ops nouveau_dmabuf_ops =  {
+   .owner = THIS_MODULE,
.map_dma_buf = nouveau_gem_map_dma_buf,
.unmap_dma_buf = nouveau_gem_unmap_dma_buf,
.release = nouveau_gem_dmabuf_release,
diff --git a/drivers/gpu/drm/radeon/radeon_prime.c 
b/drivers/gpu/drm/radeon/radeon_prime.c
index 6bef46a..4061fd3 100644
--- a/drivers/gpu/drm/radeon/radeon_prime.c
+++ b/drivers/gpu/drm/radeon/radeon_prime.c
@@ -127,6 +127,7 @@ static void radeon_gem_prime_vunmap(struct dma_buf 
*dma_buf, void *vaddr)
mutex_unlock(&dev->struct_mutex);
 }
 const static struct dma_buf_ops radeon_dmabuf_ops =  {
+   .owner = THIS_MODULE,

Re: [PATCH] dma-buf: add reference counting for exporter module

2012-08-08 Thread Tomasz Stanislawski
Hi Laurent,

On 08/08/2012 03:35 PM, Laurent Pinchart wrote:
> Hi Tomasz,
> 
> Thanks for the patch.
> 
> On Wednesday 08 August 2012 12:17:41 Tomasz Stanislawski wrote:
>> This patch adds reference counting on a module that exports dma-buf and
>> implements its operations. This prevents the module from being unloaded
>> while DMABUF file is in use.
>>
>> Signed-off-by: Tomasz Stanislawski 
>> ---
>>  Documentation/dma-buf-sharing.txt  |3 ++-
>>  drivers/base/dma-buf.c |   10 +-
>>  drivers/gpu/drm/exynos/exynos_drm_dmabuf.c |1 +
>>  drivers/gpu/drm/i915/i915_gem_dmabuf.c |1 +
>>  drivers/gpu/drm/nouveau/nouveau_prime.c|1 +
>>  drivers/gpu/drm/radeon/radeon_prime.c  |1 +
>>  drivers/staging/omapdrm/omap_gem_dmabuf.c  |1 +
>>  include/linux/dma-buf.h|2 ++
>>  8 files changed, 18 insertions(+), 2 deletions(-)
>>
[snip]

>> @@ -96,6 +98,7 @@ struct dma_buf *dma_buf_export(void *priv, const struct
>> dma_buf_ops *ops, struct file *file;
>>
>>  if (WARN_ON(!priv || !ops
>> +  || !ops->owner

Thank you for spotting this.
I didn'y know that try_get_module returned true is module was NULL.

BTW. Is it worth to add ".owner = THIS_MODULE," to all dma_buf
exporters in this patch?

Regards,
Tomasz Stanislawski

> 
> THIS_MODULE is defined as ((struct module *)0) when the driver is built-in, 
> this check should thus be removed.
> 
>>|| !ops->map_dma_buf
>>|| !ops->unmap_dma_buf
>>|| !ops->release
>>

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 1/2] dma-buf: add reference counting for exporter module

2012-08-09 Thread Tomasz Stanislawski
This patch adds reference counting on a module that exported dma-buf and
implements its operations. This prevents the module from being unloaded while
DMABUF file is in use.

Signed-off-by: Tomasz Stanislawski 
Acked-by: Sumit Semwal 
Acked-by: Daniel Vetter 
CC: linux-...@vger.kernel.org
---
 Documentation/dma-buf-sharing.txt |3 ++-
 drivers/base/dma-buf.c|9 -
 include/linux/dma-buf.h   |2 ++
 3 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/Documentation/dma-buf-sharing.txt 
b/Documentation/dma-buf-sharing.txt
index ad86fb8..2613057 100644
--- a/Documentation/dma-buf-sharing.txt
+++ b/Documentation/dma-buf-sharing.txt
@@ -49,7 +49,8 @@ The dma_buf buffer sharing API usage contains the following 
steps:
The buffer exporter announces its wish to export a buffer. In this, it
connects its own private buffer data, provides implementation for operations
that can be performed on the exported dma_buf, and flags for the file
-   associated with this buffer.
+   associated with this buffer. The operations structure has owner field.
+   You should initialize this to THIS_MODULE in most cases.
 
Interface:
   struct dma_buf *dma_buf_export(void *priv, struct dma_buf_ops *ops,
diff --git a/drivers/base/dma-buf.c b/drivers/base/dma-buf.c
index c30f3e1..a1d9cab 100644
--- a/drivers/base/dma-buf.c
+++ b/drivers/base/dma-buf.c
@@ -27,6 +27,7 @@
 #include 
 #include 
 #include 
+#include 
 
 static inline int is_dma_buf_file(struct file *);
 
@@ -40,6 +41,7 @@ static int dma_buf_release(struct inode *inode, struct file 
*file)
dmabuf = file->private_data;
 
dmabuf->ops->release(dmabuf);
+   module_put(dmabuf->ops->owner);
kfree(dmabuf);
return 0;
 }
@@ -105,9 +107,14 @@ struct dma_buf *dma_buf_export(void *priv, const struct 
dma_buf_ops *ops,
return ERR_PTR(-EINVAL);
}
 
+   if (!try_module_get(ops->owner))
+   return ERR_PTR(-ENOENT);
+
dmabuf = kzalloc(sizeof(struct dma_buf), GFP_KERNEL);
-   if (dmabuf == NULL)
+   if (dmabuf == NULL) {
+   module_put(ops->owner);
return ERR_PTR(-ENOMEM);
+   }
 
dmabuf->priv = priv;
dmabuf->ops = ops;
diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h
index eb48f38..22953de 100644
--- a/include/linux/dma-buf.h
+++ b/include/linux/dma-buf.h
@@ -37,6 +37,7 @@ struct dma_buf_attachment;
 
 /**
  * struct dma_buf_ops - operations possible on struct dma_buf
+ * @owner: the module that implements dma_buf operations
  * @attach: [optional] allows different devices to 'attach' themselves to the
  * given buffer. It might return -EBUSY to signal that backing storage
  * is already allocated and incompatible with the requirements
@@ -70,6 +71,7 @@ struct dma_buf_attachment;
  * @vunmap: [optional] unmaps a vmap from the buffer
  */
 struct dma_buf_ops {
+   struct module *owner;
int (*attach)(struct dma_buf *, struct device *,
struct dma_buf_attachment *);
 
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 2/2] drm: set owner field to for all DMABUF exporters

2012-08-09 Thread Tomasz Stanislawski
This patch sets owner field in DMABUF operations for all DMABUF exporters in
DRM subsystem.  This prevents an exporting module from being unloaded while
exported DMABUF descriptor is in use.

Signed-off-by: Tomasz Stanislawski 
Acked-by: Sumit Semwal 
Acked-by: Daniel Vetter 
---
 drivers/gpu/drm/exynos/exynos_drm_dmabuf.c |1 +
 drivers/gpu/drm/i915/i915_gem_dmabuf.c |1 +
 drivers/gpu/drm/nouveau/nouveau_prime.c|1 +
 drivers/gpu/drm/radeon/radeon_prime.c  |1 +
 drivers/staging/omapdrm/omap_gem_dmabuf.c  |1 +
 5 files changed, 5 insertions(+)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c 
b/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c
index 613bf8a..cf3bc6d 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c
@@ -164,6 +164,7 @@ static void exynos_gem_dmabuf_kunmap(struct dma_buf 
*dma_buf,
 }
 
 static struct dma_buf_ops exynos_dmabuf_ops = {
+   .owner  = THIS_MODULE,
.map_dma_buf= exynos_gem_map_dma_buf,
.unmap_dma_buf  = exynos_gem_unmap_dma_buf,
.kmap   = exynos_gem_dmabuf_kmap,
diff --git a/drivers/gpu/drm/i915/i915_gem_dmabuf.c 
b/drivers/gpu/drm/i915/i915_gem_dmabuf.c
index aa308e1..07ff03b 100644
--- a/drivers/gpu/drm/i915/i915_gem_dmabuf.c
+++ b/drivers/gpu/drm/i915/i915_gem_dmabuf.c
@@ -152,6 +152,7 @@ static int i915_gem_dmabuf_mmap(struct dma_buf *dma_buf, 
struct vm_area_struct *
 }
 
 static const struct dma_buf_ops i915_dmabuf_ops =  {
+   .owner = THIS_MODULE,
.map_dma_buf = i915_gem_map_dma_buf,
.unmap_dma_buf = i915_gem_unmap_dma_buf,
.release = i915_gem_dmabuf_release,
diff --git a/drivers/gpu/drm/nouveau/nouveau_prime.c 
b/drivers/gpu/drm/nouveau/nouveau_prime.c
index a25cf2c..8605033 100644
--- a/drivers/gpu/drm/nouveau/nouveau_prime.c
+++ b/drivers/gpu/drm/nouveau/nouveau_prime.c
@@ -127,6 +127,7 @@ static void nouveau_gem_prime_vunmap(struct dma_buf 
*dma_buf, void *vaddr)
 }
 
 static const struct dma_buf_ops nouveau_dmabuf_ops =  {
+   .owner = THIS_MODULE,
.map_dma_buf = nouveau_gem_map_dma_buf,
.unmap_dma_buf = nouveau_gem_unmap_dma_buf,
.release = nouveau_gem_dmabuf_release,
diff --git a/drivers/gpu/drm/radeon/radeon_prime.c 
b/drivers/gpu/drm/radeon/radeon_prime.c
index 6bef46a..4061fd3 100644
--- a/drivers/gpu/drm/radeon/radeon_prime.c
+++ b/drivers/gpu/drm/radeon/radeon_prime.c
@@ -127,6 +127,7 @@ static void radeon_gem_prime_vunmap(struct dma_buf 
*dma_buf, void *vaddr)
mutex_unlock(&dev->struct_mutex);
 }
 const static struct dma_buf_ops radeon_dmabuf_ops =  {
+   .owner = THIS_MODULE,
.map_dma_buf = radeon_gem_map_dma_buf,
.unmap_dma_buf = radeon_gem_unmap_dma_buf,
.release = radeon_gem_dmabuf_release,
diff --git a/drivers/staging/omapdrm/omap_gem_dmabuf.c 
b/drivers/staging/omapdrm/omap_gem_dmabuf.c
index 42728e0..6a4dd67 100644
--- a/drivers/staging/omapdrm/omap_gem_dmabuf.c
+++ b/drivers/staging/omapdrm/omap_gem_dmabuf.c
@@ -179,6 +179,7 @@ out_unlock:
 }
 
 struct dma_buf_ops omap_dmabuf_ops = {
+   .owner = THIS_MODULE,
.map_dma_buf = omap_gem_map_dma_buf,
.unmap_dma_buf = omap_gem_unmap_dma_buf,
.release = omap_gem_dmabuf_release,
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 0/2] Enhance DMABUF with reference counting for exporter module

2012-08-09 Thread Tomasz Stanislawski
Hello,
This patchset adds reference counting for an exporter module to DMABUF
framework.  Moreover, it adds setup of an owner field for exporters in DRM
subsystem.

v1: Original
v2:
  - split patch into DMABUF and DRM part
  - allow owner to be NULL

Regards,
Tomasz Stanislawski

Tomasz Stanislawski (2):
  dma-buf: add reference counting for exporter module
  drm: set owner field to for all DMABUF exporters

 Documentation/dma-buf-sharing.txt  |3 ++-
 drivers/base/dma-buf.c |9 -
 drivers/gpu/drm/exynos/exynos_drm_dmabuf.c |1 +
 drivers/gpu/drm/i915/i915_gem_dmabuf.c |1 +
 drivers/gpu/drm/nouveau/nouveau_prime.c|1 +
 drivers/gpu/drm/radeon/radeon_prime.c  |1 +
 drivers/staging/omapdrm/omap_gem_dmabuf.c  |1 +
 include/linux/dma-buf.h|2 ++
 8 files changed, 17 insertions(+), 2 deletions(-)

-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 1/2] dma-buf: add reference counting for exporter module

2012-08-09 Thread Tomasz Stanislawski
Hi Greg,

On 08/09/2012 04:23 PM, Greg KH wrote:
> On Thu, Aug 09, 2012 at 11:36:21AM +0200, Tomasz Stanislawski wrote:
>> This patch adds reference counting on a module that exported dma-buf and
>> implements its operations. This prevents the module from being unloaded while
>> DMABUF file is in use.
> 
> Why force all of the modules to be changed "by hand", and not just do
> this automatically by changing the register function to include the
> THIS_MODULE macro in it?  Much like the pci_register_driver() function
> is implemented in include/linux/pci.h?

Thank you for the hint.

The owner field belongs to dma_buf_ops structure that is often a 'const'
entity. Therefore owner field would have to be moved to 'struct dma_buf'
to avoid 'deconstification' issues.

Regards,
Tomasz Stanislawski

> 
> That makes it impossible for driver authors to get it wrong, which is
> always a good sign of a correct api.
> 
> thanks,
> 
> greg k-h
> 

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv8 01/26] v4l: Add DMABUF as a memory type

2012-08-14 Thread Tomasz Stanislawski
From: Sumit Semwal 

Adds DMABUF memory type to v4l framework. Also adds the related file
descriptor in v4l2_plane and v4l2_buffer.

Signed-off-by: Tomasz Stanislawski 
   [original work in the PoC for buffer sharing]
Signed-off-by: Sumit Semwal 
Signed-off-by: Sumit Semwal 
Acked-by: Laurent Pinchart 
---
 drivers/media/video/v4l2-compat-ioctl32.c |   18 ++
 drivers/media/video/v4l2-ioctl.c  |1 +
 include/linux/videodev2.h |7 +++
 3 files changed, 26 insertions(+)

diff --git a/drivers/media/video/v4l2-compat-ioctl32.c 
b/drivers/media/video/v4l2-compat-ioctl32.c
index 9ebd5c5..a2e0549 100644
--- a/drivers/media/video/v4l2-compat-ioctl32.c
+++ b/drivers/media/video/v4l2-compat-ioctl32.c
@@ -304,6 +304,7 @@ struct v4l2_plane32 {
union {
__u32   mem_offset;
compat_long_t   userptr;
+   __u32   fd;
} m;
__u32   data_offset;
__u32   reserved[11];
@@ -325,6 +326,7 @@ struct v4l2_buffer32 {
__u32   offset;
compat_long_t   userptr;
compat_caddr_t  planes;
+   __u32   fd;
} m;
__u32   length;
__u32   reserved2;
@@ -348,6 +350,9 @@ static int get_v4l2_plane32(struct v4l2_plane *up, struct 
v4l2_plane32 *up32,
up_pln = compat_ptr(p);
if (put_user((unsigned long)up_pln, &up->m.userptr))
return -EFAULT;
+   } else if (memory == V4L2_MEMORY_DMABUF) {
+   if (copy_in_user(&up->m.fd, &up32->m.fd, sizeof(int)))
+   return -EFAULT;
} else {
if (copy_in_user(&up->m.mem_offset, &up32->m.mem_offset,
sizeof(__u32)))
@@ -371,6 +376,11 @@ static int put_v4l2_plane32(struct v4l2_plane *up, struct 
v4l2_plane32 *up32,
if (copy_in_user(&up32->m.mem_offset, &up->m.mem_offset,
sizeof(__u32)))
return -EFAULT;
+   /* For DMABUF, driver might've set up the fd, so copy it back. */
+   if (memory == V4L2_MEMORY_DMABUF)
+   if (copy_in_user(&up32->m.fd, &up->m.fd,
+   sizeof(int)))
+   return -EFAULT;
 
return 0;
 }
@@ -453,6 +463,10 @@ static int get_v4l2_buffer32(struct v4l2_buffer *kp, 
struct v4l2_buffer32 __user
if (get_user(kp->m.offset, &up->m.offset))
return -EFAULT;
break;
+   case V4L2_MEMORY_DMABUF:
+   if (get_user(kp->m.fd, &up->m.fd))
+   return -EFAULT;
+   break;
}
}
 
@@ -517,6 +531,10 @@ static int put_v4l2_buffer32(struct v4l2_buffer *kp, 
struct v4l2_buffer32 __user
if (put_user(kp->m.offset, &up->m.offset))
return -EFAULT;
break;
+   case V4L2_MEMORY_DMABUF:
+   if (put_user(kp->m.fd, &up->m.fd))
+   return -EFAULT;
+   break;
}
}
 
diff --git a/drivers/media/video/v4l2-ioctl.c b/drivers/media/video/v4l2-ioctl.c
index 6bc47fc..dffd3c9 100644
--- a/drivers/media/video/v4l2-ioctl.c
+++ b/drivers/media/video/v4l2-ioctl.c
@@ -155,6 +155,7 @@ static const char *v4l2_memory_names[] = {
[V4L2_MEMORY_MMAP]= "mmap",
[V4L2_MEMORY_USERPTR] = "userptr",
[V4L2_MEMORY_OVERLAY] = "overlay",
+   [V4L2_MEMORY_DMABUF] = "dmabuf",
 };
 
 #define prt_names(a, arr) a) >= 0) && ((a) < ARRAY_SIZE(arr))) ? \
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index 7a147c8..7f918dc 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -186,6 +186,7 @@ enum v4l2_memory {
V4L2_MEMORY_MMAP = 1,
V4L2_MEMORY_USERPTR  = 2,
V4L2_MEMORY_OVERLAY  = 3,
+   V4L2_MEMORY_DMABUF   = 4,
 };
 
 /* see also http://vektor.theorem.ca/graphics/ycbcr/ */
@@ -596,6 +597,8 @@ struct v4l2_requestbuffers {
  * should be passed to mmap() called on the video node)
  * @userptr:   when memory is V4L2_MEMORY_USERPTR, a userspace pointer
  * pointing to this plane
+ * @fd:when memory is V4L2_MEMORY_DMABUF, a userspace 
file
+ * descriptor associated with this plane
  * @data_offset:   offset in the plane to the start of data; usually 0,
  * unless there is a header in front of the data
  

[PATCHv8 00/26] Integration of videobuf2 with DMABUF

2012-08-14 Thread Tomasz Stanislawski
Hello everyone,
This patchset adds support for DMABUF [2] importing and exporting to V4L2
stack.  The importer and exporter part were merged because DMA mapping
redesign [3] was scheduled for merge to mainline.

v8:
- rebased on 3.6-rc1
- merged importer and exporter patchsets
- fixed missing fields in v4l2_plane32 and v4l2_buffer32 structs
- fixed typos/style in documentation
- significant reduction of warnings from checkpatch.pl
- fixed STREAMOFF issues reported by Dima Zavin [4] by adding
  __vb2_dqbuf helper to vb2-core
- DC fails if userptr is not correctly aligned
- add support for DMA attributes in DC
- add support for buffers with no kernel mapping
- add reference counting on device from allocator context
- dummy support for mmap
- use dma_get_sgtable, drop vb2_dc_kaddr_to_pages hack and
  vb2_dc_get_base_sgt helper

v7:
- support for V4L2_MEMORY_DMABUF in v4l2-compact-ioctl32.c
- cosmetic fixes to the documentation
- added importing for vmalloc because vmap support in dmabuf for 3.5
  was pull-requested
- support for dmabuf importing for VIVI
- resurrect allocation of dma-contig context
- remove reference of alloc_ctx in dma-contig buffer
- use sg_alloc_table_from_pages
- fix DMA scatterlist calls to use orig_nents instead of nents
- fix memleak in vb2_dc_sgt_foreach_page (use orig_nents instead of nents)

v6:
- fixed missing entry in v4l2_memory_names
- fixed a bug occuring after get_user_pages failure
- fixed a bug caused by using invalid vma for get_user_pages
- prepare/finish no longer call dma_sync for dmabuf buffers

v5:
- removed change of importer/exporter behaviour
- fixes vb2_dc_pages_to_sgt basing on Laurent's hints
- changed pin/unpin words to lock/unlock in Doc

v4:
- rebased on mainline 3.4-rc2
- included missing importing support for s5p-fimc and s5p-tv
- added patch for changing map/unmap for importers
- fixes to Documentation part
- coding style fixes
- pairing {map/unmap}_dmabuf in vb2-core
- fixing variable types and semantic of arguments in videobufb2-dma-contig.c

v3:
- rebased on mainline 3.4-rc1
- split 'code refactor' patch to multiple smaller patches
- squashed fixes to Sumit's patches
- patchset is no longer dependant on 'DMA mapping redesign'
- separated path for handling IO and non-IO mappings
- add documentation for DMABUF importing to V4L
- removed all DMABUF exporter related code
- removed usage of dma_get_pages extension

v2:
- extended VIDIOC_EXPBUF argument from integer memoffset to struct
  v4l2_exportbuffer
- added patch that breaks DMABUF spec on (un)map_atachment callcacks but allows
  to work with existing implementation of DMABUF prime in DRM
- all dma-contig code refactoring patches were squashed
- bugfixes

v1: List of changes since [1].
- support for DMA api extension dma_get_pages, the function is used to retrieve
  pages used to create DMA mapping.
- small fixes/code cleanup to videobuf2
- added prepare and finish callbacks to vb2 allocators, it is used keep
  consistency between dma-cpu acess to the memory (by Marek Szyprowski)
- support for exporting of DMABUF buffer in V4L2 and Videobuf2, originated from
  [3].
- support for dma-buf exporting in vb2-dma-contig allocator
- support for DMABUF for s5p-tv and s5p-fimc (capture interface) drivers,
  originated from [3]
- changed handling for userptr buffers (by Marek Szyprowski, Andrzej
  Pietrasiewicz)
- let mmap method to use dma_mmap_writecombine call (by Marek Szyprowski)

[1] 
http://thread.gmane.org/gmane.linux.drivers.video-input-infrastructure/42966/focus=42968
[2] https://lkml.org/lkml/2011/12/26/29
[3] http://thread.gmane.org/gmane.linux.kernel.cross-arch/12819
[4] 
http://article.gmane.org/gmane.linux.drivers.video-input-infrastructure/49700

Laurent Pinchart (2):
  v4l: vb2-dma-contig: Shorten vb2_dma_contig prefix to vb2_dc
  v4l: vb2-dma-contig: Reorder functions

Marek Szyprowski (5):
  v4l: vb2: add prepare/finish callbacks to allocators
  v4l: vb2-dma-contig: add prepare/finish to dma-contig allocator
  v4l: vb2-dma-contig: let mmap method to use dma_mmap_coherent call
  media: vb2: fail if user ptr buffer is not correctly aligned
  v4l: vb2: add support for DMA_ATTR_NO_KERNEL_MAPPING

Sumit Semwal (4):
  v4l: Add DMABUF as a memory type
  v4l: vb2: add support for shared buffer (dma_buf)
  v4l: vb: remove warnings about MEMORY_DMABUF
  v4l: vb2-dma-contig: add support for dma_buf importing

Tomasz Stanislawski (15):
  Documentation: media: description of DMABUF importing in V4L2
  v4l: vb2-dma-contig: remove reference of alloc_ctx from a buffer
  v4l: vb2-dma-contig: add support for scatterlist in userptr mode
  v4l: vb2-vmalloc: add support for dmabuf importing
  v4l: vivi: support for dmabuf importing
  v4l: s5p-tv: mixer: support for dmabuf importing
  v4l: s5p-fimc: support for dmabuf importing
  Documentation: media: description of DMABUF exporting in V4L2
  v4l: add buffer exporting via dmabuf
  v4l: vb2: add buffer exporting via dmabuf
  v4l: v

[PATCHv8 02/26] Documentation: media: description of DMABUF importing in V4L2

2012-08-14 Thread Tomasz Stanislawski
This patch adds description and usage examples for importing
DMABUF file descriptor in V4L2.

Signed-off-by: Tomasz Stanislawski 
Signed-off-by: Kyungmin Park 
CC: linux-...@vger.kernel.org
---
 Documentation/DocBook/media/v4l/compat.xml |4 +
 Documentation/DocBook/media/v4l/io.xml |  180 
 .../DocBook/media/v4l/vidioc-create-bufs.xml   |3 +-
 Documentation/DocBook/media/v4l/vidioc-qbuf.xml|   15 ++
 Documentation/DocBook/media/v4l/vidioc-reqbufs.xml |   47 ++---
 5 files changed, 226 insertions(+), 23 deletions(-)

diff --git a/Documentation/DocBook/media/v4l/compat.xml 
b/Documentation/DocBook/media/v4l/compat.xml
index 98e8d08..ff45330 100644
--- a/Documentation/DocBook/media/v4l/compat.xml
+++ b/Documentation/DocBook/media/v4l/compat.xml
@@ -2605,6 +2605,10 @@ ioctls.
 
  Support for frequency band enumeration: 
&VIDIOC-ENUM-FREQ-BANDS; ioctl.
 
+
+ Importing DMABUF file descriptors as a new IO method described
+ in .
+
   
 
 
diff --git a/Documentation/DocBook/media/v4l/io.xml 
b/Documentation/DocBook/media/v4l/io.xml
index 1885cc0..98253ee 100644
--- a/Documentation/DocBook/media/v4l/io.xml
+++ b/Documentation/DocBook/media/v4l/io.xml
@@ -472,6 +472,163 @@ rest should be evident.
   
   
 
+  
+Streaming I/O (DMA buffer importing)
+
+
+  Experimental
+  This is an  experimental 
+  interface and may change in the future.
+
+
+The DMABUF framework provides a generic mean for sharing buffers between
+ multiple devices. Device drivers that support DMABUF can export a DMA buffer
+to userspace as a file descriptor (known as the exporter role), import a DMA
+buffer from userspace using a file descriptor previously exported for a
+different or the same device (known as the importer role), or both. This
+section describes the DMABUF importer role API in V4L2.
+
+Input and output devices support the streaming I/O method when the
+V4L2_CAP_STREAMING flag in the
+capabilities field of &v4l2-capability; returned by
+the &VIDIOC-QUERYCAP; ioctl is set. Whether importing DMA buffers through
+DMABUF file descriptors is supported is determined by calling the
+&VIDIOC-REQBUFS; ioctl with the memory type set to
+V4L2_MEMORY_DMABUF.
+
+This I/O method is dedicated for sharing DMA buffers between V4L and
+other APIs.  Buffers (planes) are allocated by a driver on behalf of the
+application, and exported to the application as file descriptors using an API
+specific to the allocator driver.  Only those file descriptor are exchanged,
+these files and meta-information are passed in &v4l2-buffer; (or in
+&v4l2-plane; in the multi-planar API case).  The driver must be switched into
+DMABUF I/O mode by calling the &VIDIOC-REQBUFS; with the desired buffer type.
+No buffers (planes) are allocated beforehand, consequently they are not indexed
+and cannot be queried like mapped buffers with the
+VIDIOC_QUERYBUF ioctl.
+
+
+  Initiating streaming I/O with DMABUF file descriptors
+
+  
+&v4l2-requestbuffers; reqbuf;
+
+memset (&reqbuf, 0, sizeof (reqbuf));
+reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+reqbuf.memory = V4L2_MEMORY_DMABUF;
+reqbuf.count = 1;
+
+if (ioctl (fd, &VIDIOC-REQBUFS;, &reqbuf) == -1) {
+   if (errno == EINVAL)
+   printf ("Video capturing or DMABUF streaming is not 
supported\n");
+   else
+   perror ("VIDIOC_REQBUFS");
+
+   exit (EXIT_FAILURE);
+}
+  
+
+
+Buffer (plane) file descriptor is passed on the fly with the
+&VIDIOC-QBUF; ioctl. In case of multiplanar buffers, every plane can be
+associated with a different DMABUF descriptor. Although buffers are commonly
+cycled, applications can pass a different DMABUF descriptor at each
+VIDIOC_QBUF call.
+
+
+  Queueing DMABUF using single plane API
+
+  
+int buffer_queue(int v4lfd, int index, int dmafd)
+{
+   &v4l2-buffer; buf;
+
+   memset(&buf, 0, sizeof buf);
+   buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+   buf.memory = V4L2_MEMORY_DMABUF;
+   buf.index = index;
+   buf.m.fd = dmafd;
+
+   if (ioctl (v4lfd, &VIDIOC-QBUF;, &buf) == -1) {
+   perror ("VIDIOC_QBUF");
+   return -1;
+   }
+
+   return 0;
+}
+  
+
+
+
+  Queueing DMABUF using multi plane API
+
+  
+int buffer_queue_mp(int v4lfd, int index, int dmafd[], int n_planes)
+{
+   &v4l2-buffer; buf;
+   &v4l2-plane; planes[VIDEO_MAX_PLANES];
+   int i;
+
+   memset(&buf, 0, sizeof buf);
+   buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+   buf.memory = V4L2_MEMORY_DMABUF;
+   buf.index = index;
+   buf.m.planes = planes;
+   buf.length = n_planes;
+
+   memset(&planes, 0, sizeof planes);
+
+   for (i = 0; i < n_planes; ++i)
+   

[PATCHv8 03/26] v4l: vb2: add support for shared buffer (dma_buf)

2012-08-14 Thread Tomasz Stanislawski
From: Sumit Semwal 

This patch adds support for DMABUF memory type in videobuf2. It calls relevant
APIs of dma_buf for v4l reqbuf / qbuf / dqbuf operations.

For this version, the support is for videobuf2 as a user of the shared buffer;
so the allocation of the buffer is done outside of V4L2. [A sample allocator of
dma-buf shared buffer is given at [1]]

[1]: Rob Clark's DRM:
   https://github.com/robclark/kernel-omap4/commits/drmplane-dmabuf

Signed-off-by: Tomasz Stanislawski 
   [original work in the PoC for buffer sharing]
Signed-off-by: Sumit Semwal 
Signed-off-by: Sumit Semwal 
Acked-by: Laurent Pinchart 
---
 drivers/media/video/videobuf2-core.c |  197 +-
 include/media/videobuf2-core.h   |   27 +
 2 files changed, 221 insertions(+), 3 deletions(-)

diff --git a/drivers/media/video/videobuf2-core.c 
b/drivers/media/video/videobuf2-core.c
index 4da3df6..a5d5081 100644
--- a/drivers/media/video/videobuf2-core.c
+++ b/drivers/media/video/videobuf2-core.c
@@ -109,6 +109,36 @@ static void __vb2_buf_userptr_put(struct vb2_buffer *vb)
 }
 
 /**
+ * __vb2_plane_dmabuf_put() - release memory associated with
+ * a DMABUF shared plane
+ */
+static void __vb2_plane_dmabuf_put(struct vb2_queue *q, struct vb2_plane *p)
+{
+   if (!p->mem_priv)
+   return;
+
+   if (p->dbuf_mapped)
+   call_memop(q, unmap_dmabuf, p->mem_priv);
+
+   call_memop(q, detach_dmabuf, p->mem_priv);
+   dma_buf_put(p->dbuf);
+   memset(p, 0, sizeof(*p));
+}
+
+/**
+ * __vb2_buf_dmabuf_put() - release memory associated with
+ * a DMABUF shared buffer
+ */
+static void __vb2_buf_dmabuf_put(struct vb2_buffer *vb)
+{
+   struct vb2_queue *q = vb->vb2_queue;
+   unsigned int plane;
+
+   for (plane = 0; plane < vb->num_planes; ++plane)
+   __vb2_plane_dmabuf_put(q, &vb->planes[plane]);
+}
+
+/**
  * __setup_offsets() - setup unique offsets ("cookies") for every plane in
  * every buffer on the queue
  */
@@ -230,6 +260,8 @@ static void __vb2_free_mem(struct vb2_queue *q, unsigned 
int buffers)
/* Free MMAP buffers or release USERPTR buffers */
if (q->memory == V4L2_MEMORY_MMAP)
__vb2_buf_mem_free(vb);
+   else if (q->memory == V4L2_MEMORY_DMABUF)
+   __vb2_buf_dmabuf_put(vb);
else
__vb2_buf_userptr_put(vb);
}
@@ -352,6 +384,12 @@ static int __fill_v4l2_buffer(struct vb2_buffer *vb, 
struct v4l2_buffer *b)
 */
memcpy(b->m.planes, vb->v4l2_planes,
b->length * sizeof(struct v4l2_plane));
+
+   if (q->memory == V4L2_MEMORY_DMABUF) {
+   unsigned int plane;
+   for (plane = 0; plane < vb->num_planes; ++plane)
+   b->m.planes[plane].m.fd = 0;
+   }
} else {
/*
 * We use length and offset in v4l2_planes array even for
@@ -363,6 +401,8 @@ static int __fill_v4l2_buffer(struct vb2_buffer *vb, struct 
v4l2_buffer *b)
b->m.offset = vb->v4l2_planes[0].m.mem_offset;
else if (q->memory == V4L2_MEMORY_USERPTR)
b->m.userptr = vb->v4l2_planes[0].m.userptr;
+   else if (q->memory == V4L2_MEMORY_DMABUF)
+   b->m.fd = 0;
}
 
/*
@@ -454,13 +494,28 @@ static int __verify_mmap_ops(struct vb2_queue *q)
 }
 
 /**
+ * __verify_dmabuf_ops() - verify that all memory operations required for
+ * DMABUF queue type have been provided
+ */
+static int __verify_dmabuf_ops(struct vb2_queue *q)
+{
+   if (!(q->io_modes & VB2_DMABUF) || !q->mem_ops->attach_dmabuf ||
+   !q->mem_ops->detach_dmabuf  || !q->mem_ops->map_dmabuf ||
+   !q->mem_ops->unmap_dmabuf)
+   return -EINVAL;
+
+   return 0;
+}
+
+/**
  * __verify_memory_type() - Check whether the memory type and buffer type
  * passed to a buffer operation are compatible with the queue.
  */
 static int __verify_memory_type(struct vb2_queue *q,
enum v4l2_memory memory, enum v4l2_buf_type type)
 {
-   if (memory != V4L2_MEMORY_MMAP && memory != V4L2_MEMORY_USERPTR) {
+   if (memory != V4L2_MEMORY_MMAP && memory != V4L2_MEMORY_USERPTR &&
+   memory != V4L2_MEMORY_DMABUF) {
dprintk(1, "reqbufs: unsupported memory type\n");
return -EINVAL;
}
@@ -484,6 +539,11 @@ static int __verify_memory_type(struct vb2_queue *q,
return -EINVAL;
}
 
+   if (memory == V4L2_MEMORY_DMABUF && __verify_dmabuf_ops(q)) {
+   dprintk(1, "reqbufs: DMABUF for current setup unsupported\n");
+

[PATCHv8 04/26] v4l: vb: remove warnings about MEMORY_DMABUF

2012-08-14 Thread Tomasz Stanislawski
From: Sumit Semwal 

Adding DMABUF memory type causes videobuf to complain about not using it
in some switch cases. This patch removes these warnings.

Signed-off-by: Sumit Semwal 
Acked-by: Laurent Pinchart 
---
 drivers/media/video/videobuf-core.c |4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/media/video/videobuf-core.c 
b/drivers/media/video/videobuf-core.c
index bf7a326..5449e8a 100644
--- a/drivers/media/video/videobuf-core.c
+++ b/drivers/media/video/videobuf-core.c
@@ -335,6 +335,9 @@ static void videobuf_status(struct videobuf_queue *q, 
struct v4l2_buffer *b,
case V4L2_MEMORY_OVERLAY:
b->m.offset  = vb->boff;
break;
+   case V4L2_MEMORY_DMABUF:
+   /* DMABUF is not handled in videobuf framework */
+   break;
}
 
b->flags= 0;
@@ -405,6 +408,7 @@ int __videobuf_mmap_setup(struct videobuf_queue *q,
break;
case V4L2_MEMORY_USERPTR:
case V4L2_MEMORY_OVERLAY:
+   case V4L2_MEMORY_DMABUF:
/* nothing */
break;
}
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv8 05/26] v4l: vb2-dma-contig: Shorten vb2_dma_contig prefix to vb2_dc

2012-08-14 Thread Tomasz Stanislawski
From: Laurent Pinchart 

Signed-off-by: Laurent Pinchart 
---
 drivers/media/video/videobuf2-dma-contig.c |   36 ++--
 1 file changed, 18 insertions(+), 18 deletions(-)

diff --git a/drivers/media/video/videobuf2-dma-contig.c 
b/drivers/media/video/videobuf2-dma-contig.c
index 4b71326..a05784f 100644
--- a/drivers/media/video/videobuf2-dma-contig.c
+++ b/drivers/media/video/videobuf2-dma-contig.c
@@ -32,9 +32,9 @@ struct vb2_dc_buf {
struct vb2_vmarea_handler   handler;
 };
 
-static void vb2_dma_contig_put(void *buf_priv);
+static void vb2_dc_put(void *buf_priv);
 
-static void *vb2_dma_contig_alloc(void *alloc_ctx, unsigned long size)
+static void *vb2_dc_alloc(void *alloc_ctx, unsigned long size)
 {
struct vb2_dc_conf *conf = alloc_ctx;
struct vb2_dc_buf *buf;
@@ -56,7 +56,7 @@ static void *vb2_dma_contig_alloc(void *alloc_ctx, unsigned 
long size)
buf->size = size;
 
buf->handler.refcount = &buf->refcount;
-   buf->handler.put = vb2_dma_contig_put;
+   buf->handler.put = vb2_dc_put;
buf->handler.arg = buf;
 
atomic_inc(&buf->refcount);
@@ -64,7 +64,7 @@ static void *vb2_dma_contig_alloc(void *alloc_ctx, unsigned 
long size)
return buf;
 }
 
-static void vb2_dma_contig_put(void *buf_priv)
+static void vb2_dc_put(void *buf_priv)
 {
struct vb2_dc_buf *buf = buf_priv;
 
@@ -75,14 +75,14 @@ static void vb2_dma_contig_put(void *buf_priv)
}
 }
 
-static void *vb2_dma_contig_cookie(void *buf_priv)
+static void *vb2_dc_cookie(void *buf_priv)
 {
struct vb2_dc_buf *buf = buf_priv;
 
return &buf->dma_addr;
 }
 
-static void *vb2_dma_contig_vaddr(void *buf_priv)
+static void *vb2_dc_vaddr(void *buf_priv)
 {
struct vb2_dc_buf *buf = buf_priv;
if (!buf)
@@ -91,14 +91,14 @@ static void *vb2_dma_contig_vaddr(void *buf_priv)
return buf->vaddr;
 }
 
-static unsigned int vb2_dma_contig_num_users(void *buf_priv)
+static unsigned int vb2_dc_num_users(void *buf_priv)
 {
struct vb2_dc_buf *buf = buf_priv;
 
return atomic_read(&buf->refcount);
 }
 
-static int vb2_dma_contig_mmap(void *buf_priv, struct vm_area_struct *vma)
+static int vb2_dc_mmap(void *buf_priv, struct vm_area_struct *vma)
 {
struct vb2_dc_buf *buf = buf_priv;
 
@@ -111,7 +111,7 @@ static int vb2_dma_contig_mmap(void *buf_priv, struct 
vm_area_struct *vma)
  &vb2_common_vm_ops, &buf->handler);
 }
 
-static void *vb2_dma_contig_get_userptr(void *alloc_ctx, unsigned long vaddr,
+static void *vb2_dc_get_userptr(void *alloc_ctx, unsigned long vaddr,
unsigned long size, int write)
 {
struct vb2_dc_buf *buf;
@@ -138,7 +138,7 @@ static void *vb2_dma_contig_get_userptr(void *alloc_ctx, 
unsigned long vaddr,
return buf;
 }
 
-static void vb2_dma_contig_put_userptr(void *mem_priv)
+static void vb2_dc_put_userptr(void *mem_priv)
 {
struct vb2_dc_buf *buf = mem_priv;
 
@@ -150,14 +150,14 @@ static void vb2_dma_contig_put_userptr(void *mem_priv)
 }
 
 const struct vb2_mem_ops vb2_dma_contig_memops = {
-   .alloc  = vb2_dma_contig_alloc,
-   .put= vb2_dma_contig_put,
-   .cookie = vb2_dma_contig_cookie,
-   .vaddr  = vb2_dma_contig_vaddr,
-   .mmap   = vb2_dma_contig_mmap,
-   .get_userptr= vb2_dma_contig_get_userptr,
-   .put_userptr= vb2_dma_contig_put_userptr,
-   .num_users  = vb2_dma_contig_num_users,
+   .alloc  = vb2_dc_alloc,
+   .put= vb2_dc_put,
+   .cookie = vb2_dc_cookie,
+   .vaddr  = vb2_dc_vaddr,
+   .mmap   = vb2_dc_mmap,
+   .get_userptr= vb2_dc_get_userptr,
+   .put_userptr= vb2_dc_put_userptr,
+   .num_users  = vb2_dc_num_users,
 };
 EXPORT_SYMBOL_GPL(vb2_dma_contig_memops);
 
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv8 06/26] v4l: vb2-dma-contig: remove reference of alloc_ctx from a buffer

2012-08-14 Thread Tomasz Stanislawski
This patch removes a reference to alloc_ctx from an instance of a DMA
contiguous buffer. It helps to avoid a risk of a dangling pointer if the
context is released while the buffer is still valid. Moreover it removes one
dereference step while accessing a device structure.

Signed-off-by: Tomasz Stanislawski 
Signed-off-by: Kyungmin Park 
---
 drivers/media/video/videobuf2-dma-contig.c |   13 ++---
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/drivers/media/video/videobuf2-dma-contig.c 
b/drivers/media/video/videobuf2-dma-contig.c
index a05784f..20c95da 100644
--- a/drivers/media/video/videobuf2-dma-contig.c
+++ b/drivers/media/video/videobuf2-dma-contig.c
@@ -23,7 +23,7 @@ struct vb2_dc_conf {
 };
 
 struct vb2_dc_buf {
-   struct vb2_dc_conf  *conf;
+   struct device   *dev;
void*vaddr;
dma_addr_t  dma_addr;
unsigned long   size;
@@ -37,22 +37,21 @@ static void vb2_dc_put(void *buf_priv);
 static void *vb2_dc_alloc(void *alloc_ctx, unsigned long size)
 {
struct vb2_dc_conf *conf = alloc_ctx;
+   struct device *dev = conf->dev;
struct vb2_dc_buf *buf;
 
buf = kzalloc(sizeof *buf, GFP_KERNEL);
if (!buf)
return ERR_PTR(-ENOMEM);
 
-   buf->vaddr = dma_alloc_coherent(conf->dev, size, &buf->dma_addr,
-   GFP_KERNEL);
+   buf->vaddr = dma_alloc_coherent(dev, size, &buf->dma_addr, GFP_KERNEL);
if (!buf->vaddr) {
-   dev_err(conf->dev, "dma_alloc_coherent of size %ld failed\n",
-   size);
+   dev_err(dev, "dma_alloc_coherent of size %ld failed\n", size);
kfree(buf);
return ERR_PTR(-ENOMEM);
}
 
-   buf->conf = conf;
+   buf->dev = dev;
buf->size = size;
 
buf->handler.refcount = &buf->refcount;
@@ -69,7 +68,7 @@ static void vb2_dc_put(void *buf_priv)
struct vb2_dc_buf *buf = buf_priv;
 
if (atomic_dec_and_test(&buf->refcount)) {
-   dma_free_coherent(buf->conf->dev, buf->size, buf->vaddr,
+   dma_free_coherent(buf->dev, buf->size, buf->vaddr,
  buf->dma_addr);
kfree(buf);
}
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv8 07/26] v4l: vb2-dma-contig: Reorder functions

2012-08-14 Thread Tomasz Stanislawski
From: Laurent Pinchart 

Group functions by buffer type.

Signed-off-by: Laurent Pinchart 
---
 drivers/media/video/videobuf2-dma-contig.c |   92 
 1 file changed, 54 insertions(+), 38 deletions(-)

diff --git a/drivers/media/video/videobuf2-dma-contig.c 
b/drivers/media/video/videobuf2-dma-contig.c
index 20c95da..daac2b2 100644
--- a/drivers/media/video/videobuf2-dma-contig.c
+++ b/drivers/media/video/videobuf2-dma-contig.c
@@ -25,14 +25,56 @@ struct vb2_dc_conf {
 struct vb2_dc_buf {
struct device   *dev;
void*vaddr;
-   dma_addr_t  dma_addr;
unsigned long   size;
-   struct vm_area_struct   *vma;
-   atomic_trefcount;
+   dma_addr_t  dma_addr;
+
+   /* MMAP related */
struct vb2_vmarea_handler   handler;
+   atomic_trefcount;
+
+   /* USERPTR related */
+   struct vm_area_struct   *vma;
 };
 
-static void vb2_dc_put(void *buf_priv);
+/*/
+/* callbacks for all buffers */
+/*/
+
+static void *vb2_dc_cookie(void *buf_priv)
+{
+   struct vb2_dc_buf *buf = buf_priv;
+
+   return &buf->dma_addr;
+}
+
+static void *vb2_dc_vaddr(void *buf_priv)
+{
+   struct vb2_dc_buf *buf = buf_priv;
+
+   return buf->vaddr;
+}
+
+static unsigned int vb2_dc_num_users(void *buf_priv)
+{
+   struct vb2_dc_buf *buf = buf_priv;
+
+   return atomic_read(&buf->refcount);
+}
+
+/*/
+/*callbacks for MMAP buffers */
+/*/
+
+static void vb2_dc_put(void *buf_priv)
+{
+   struct vb2_dc_buf *buf = buf_priv;
+
+   if (!atomic_dec_and_test(&buf->refcount))
+   return;
+
+   dma_free_coherent(buf->dev, buf->size, buf->vaddr, buf->dma_addr);
+   kfree(buf);
+}
 
 static void *vb2_dc_alloc(void *alloc_ctx, unsigned long size)
 {
@@ -63,40 +105,6 @@ static void *vb2_dc_alloc(void *alloc_ctx, unsigned long 
size)
return buf;
 }
 
-static void vb2_dc_put(void *buf_priv)
-{
-   struct vb2_dc_buf *buf = buf_priv;
-
-   if (atomic_dec_and_test(&buf->refcount)) {
-   dma_free_coherent(buf->dev, buf->size, buf->vaddr,
- buf->dma_addr);
-   kfree(buf);
-   }
-}
-
-static void *vb2_dc_cookie(void *buf_priv)
-{
-   struct vb2_dc_buf *buf = buf_priv;
-
-   return &buf->dma_addr;
-}
-
-static void *vb2_dc_vaddr(void *buf_priv)
-{
-   struct vb2_dc_buf *buf = buf_priv;
-   if (!buf)
-   return NULL;
-
-   return buf->vaddr;
-}
-
-static unsigned int vb2_dc_num_users(void *buf_priv)
-{
-   struct vb2_dc_buf *buf = buf_priv;
-
-   return atomic_read(&buf->refcount);
-}
-
 static int vb2_dc_mmap(void *buf_priv, struct vm_area_struct *vma)
 {
struct vb2_dc_buf *buf = buf_priv;
@@ -110,6 +118,10 @@ static int vb2_dc_mmap(void *buf_priv, struct 
vm_area_struct *vma)
  &vb2_common_vm_ops, &buf->handler);
 }
 
+/*/
+/*   callbacks for USERPTR buffers   */
+/*/
+
 static void *vb2_dc_get_userptr(void *alloc_ctx, unsigned long vaddr,
unsigned long size, int write)
 {
@@ -148,6 +160,10 @@ static void vb2_dc_put_userptr(void *mem_priv)
kfree(buf);
 }
 
+/*/
+/*   DMA CONTIG exported functions   */
+/*/
+
 const struct vb2_mem_ops vb2_dma_contig_memops = {
.alloc  = vb2_dc_alloc,
.put= vb2_dc_put,
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv8 09/26] v4l: vb2: add prepare/finish callbacks to allocators

2012-08-14 Thread Tomasz Stanislawski
From: Marek Szyprowski 

This patch adds support for prepare/finish callbacks in VB2 allocators. These
callback are used for buffer flushing.

Signed-off-by: Marek Szyprowski 
Acked-by: Laurent Pinchart 
---
 drivers/media/video/videobuf2-core.c |   11 +++
 include/media/videobuf2-core.h   |7 +++
 2 files changed, 18 insertions(+)

diff --git a/drivers/media/video/videobuf2-core.c 
b/drivers/media/video/videobuf2-core.c
index a5d5081..aed21e4 100644
--- a/drivers/media/video/videobuf2-core.c
+++ b/drivers/media/video/videobuf2-core.c
@@ -850,6 +850,7 @@ void vb2_buffer_done(struct vb2_buffer *vb, enum 
vb2_buffer_state state)
 {
struct vb2_queue *q = vb->vb2_queue;
unsigned long flags;
+   unsigned int plane;
 
if (vb->state != VB2_BUF_STATE_ACTIVE)
return;
@@ -860,6 +861,10 @@ void vb2_buffer_done(struct vb2_buffer *vb, enum 
vb2_buffer_state state)
dprintk(4, "Done processing on buffer %d, state: %d\n",
vb->v4l2_buf.index, vb->state);
 
+   /* sync buffers */
+   for (plane = 0; plane < vb->num_planes; ++plane)
+   call_memop(q, finish, vb->planes[plane].mem_priv);
+
/* Add the buffer to the done buffers list */
spin_lock_irqsave(&q->done_lock, flags);
vb->state = state;
@@ -1138,9 +1143,15 @@ err:
 static void __enqueue_in_driver(struct vb2_buffer *vb)
 {
struct vb2_queue *q = vb->vb2_queue;
+   unsigned int plane;
 
vb->state = VB2_BUF_STATE_ACTIVE;
atomic_inc(&q->queued_count);
+
+   /* sync buffers */
+   for (plane = 0; plane < vb->num_planes; ++plane)
+   call_memop(q, prepare, vb->planes[plane].mem_priv);
+
q->ops->buf_queue(vb);
 }
 
diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h
index 84f11f2..c306fec 100644
--- a/include/media/videobuf2-core.h
+++ b/include/media/videobuf2-core.h
@@ -56,6 +56,10 @@ struct vb2_fileio_data;
  * dmabuf
  * @unmap_dmabuf: releases access control to the dmabuf - allocator is notified
  *   that this driver is done using the dmabuf for now
+ * @prepare:   called everytime the buffer is passed from userspace to the
+ * driver, usefull for cache synchronisation, optional
+ * @finish:called everytime the buffer is passed back from the driver
+ * to the userspace, also optional
  * @vaddr: return a kernel virtual address to a given memory buffer
  * associated with the passed private structure or NULL if no
  * such mapping exists
@@ -82,6 +86,9 @@ struct vb2_mem_ops {
unsigned long size, int write);
void(*put_userptr)(void *buf_priv);
 
+   void(*prepare)(void *buf_priv);
+   void(*finish)(void *buf_priv);
+
void*(*attach_dmabuf)(void *alloc_ctx, struct dma_buf *dbuf,
unsigned long size, int write);
void(*detach_dmabuf)(void *buf_priv);
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv8 08/26] v4l: vb2-dma-contig: add support for scatterlist in userptr mode

2012-08-14 Thread Tomasz Stanislawski
This patch introduces usage of dma_map_sg to map memory behind
a userspace pointer to a device as dma-contiguous mapping.

This patch contains some of the code kindly provided by Marek Szyprowski
 and Kamil Debski  and Andrzej
Pietrasiewicz . Kind thanks for bug reports from Laurent
Pinchart  and Seung-Woo Kim
.

Signed-off-by: Tomasz Stanislawski 
Signed-off-by: Kyungmin Park 
Acked-by: Laurent Pinchart 
---
 drivers/media/video/videobuf2-dma-contig.c |  226 ++--
 1 file changed, 210 insertions(+), 16 deletions(-)

diff --git a/drivers/media/video/videobuf2-dma-contig.c 
b/drivers/media/video/videobuf2-dma-contig.c
index daac2b2..8486e06 100644
--- a/drivers/media/video/videobuf2-dma-contig.c
+++ b/drivers/media/video/videobuf2-dma-contig.c
@@ -11,6 +11,8 @@
  */
 
 #include 
+#include 
+#include 
 #include 
 #include 
 
@@ -27,6 +29,8 @@ struct vb2_dc_buf {
void*vaddr;
unsigned long   size;
dma_addr_t  dma_addr;
+   enum dma_data_direction dma_dir;
+   struct sg_table *dma_sgt;
 
/* MMAP related */
struct vb2_vmarea_handler   handler;
@@ -37,6 +41,44 @@ struct vb2_dc_buf {
 };
 
 /*/
+/*scatterlist table functions*/
+/*/
+
+
+static void vb2_dc_sgt_foreach_page(struct sg_table *sgt,
+   void (*cb)(struct page *pg))
+{
+   struct scatterlist *s;
+   unsigned int i;
+
+   for_each_sg(sgt->sgl, s, sgt->orig_nents, i) {
+   struct page *page = sg_page(s);
+   unsigned int n_pages = PAGE_ALIGN(s->offset + s->length)
+   >> PAGE_SHIFT;
+   unsigned int j;
+
+   for (j = 0; j < n_pages; ++j, ++page)
+   cb(page);
+   }
+}
+
+static unsigned long vb2_dc_get_contiguous_size(struct sg_table *sgt)
+{
+   struct scatterlist *s;
+   dma_addr_t expected = sg_dma_address(sgt->sgl);
+   unsigned int i;
+   unsigned long size = 0;
+
+   for_each_sg(sgt->sgl, s, sgt->nents, i) {
+   if (sg_dma_address(s) != expected)
+   break;
+   expected = sg_dma_address(s) + sg_dma_len(s);
+   size += sg_dma_len(s);
+   }
+   return size;
+}
+
+/*/
 /* callbacks for all buffers */
 /*/
 
@@ -122,42 +164,194 @@ static int vb2_dc_mmap(void *buf_priv, struct 
vm_area_struct *vma)
 /*   callbacks for USERPTR buffers   */
 /*/
 
+static inline int vma_is_io(struct vm_area_struct *vma)
+{
+   return !!(vma->vm_flags & (VM_IO | VM_PFNMAP));
+}
+
+static int vb2_dc_get_user_pages(unsigned long start, struct page **pages,
+   int n_pages, struct vm_area_struct *vma, int write)
+{
+   if (vma_is_io(vma)) {
+   unsigned int i;
+
+   for (i = 0; i < n_pages; ++i, start += PAGE_SIZE) {
+   unsigned long pfn;
+   int ret = follow_pfn(vma, start, &pfn);
+
+   if (ret) {
+   pr_err("no page for address %lu\n", start);
+   return ret;
+   }
+   pages[i] = pfn_to_page(pfn);
+   }
+   } else {
+   int n;
+
+   n = get_user_pages(current, current->mm, start & PAGE_MASK,
+   n_pages, write, 1, pages, NULL);
+   /* negative error means that no page was pinned */
+   n = max(n, 0);
+   if (n != n_pages) {
+   pr_err("got only %d of %d user pages\n", n, n_pages);
+   while (n)
+   put_page(pages[--n]);
+   return -EFAULT;
+   }
+   }
+
+   return 0;
+}
+
+static void vb2_dc_put_dirty_page(struct page *page)
+{
+   set_page_dirty_lock(page);
+   put_page(page);
+}
+
+static void vb2_dc_put_userptr(void *buf_priv)
+{
+   struct vb2_dc_buf *buf = buf_priv;
+   struct sg_table *sgt = buf->dma_sgt;
+
+   dma_unmap_sg(buf->dev, sgt->sgl, sgt->orig_nents, buf->dma_dir);
+   if (!vma_is_io(buf->vma))
+   vb2_dc_sgt_foreach_page(sgt, vb2_dc_put_dirty_page);
+
+   sg_free_table(sgt);
+   kfree(sgt);
+   vb2_put_vma(buf->vma);
+   kfree(buf);
+}
+
 static void *vb2_dc_get_userptr(void *alloc_ctx, unsigned long vaddr,
-   unsigned long size, int write)
+   unsigned long size, int write)
 {
+   struct vb2_dc_conf *conf = alloc_ctx;
struct vb2_dc_buf *buf;
+   unsigned long

[PATCHv8 10/26] v4l: vb2-dma-contig: add prepare/finish to dma-contig allocator

2012-08-14 Thread Tomasz Stanislawski
From: Marek Szyprowski 

Add prepare/finish callbacks to vb2-dma-contig allocator.

Signed-off-by: Marek Szyprowski 
---
 drivers/media/video/videobuf2-dma-contig.c |   24 
 1 file changed, 24 insertions(+)

diff --git a/drivers/media/video/videobuf2-dma-contig.c 
b/drivers/media/video/videobuf2-dma-contig.c
index 8486e06..494a824 100644
--- a/drivers/media/video/videobuf2-dma-contig.c
+++ b/drivers/media/video/videobuf2-dma-contig.c
@@ -103,6 +103,28 @@ static unsigned int vb2_dc_num_users(void *buf_priv)
return atomic_read(&buf->refcount);
 }
 
+static void vb2_dc_prepare(void *buf_priv)
+{
+   struct vb2_dc_buf *buf = buf_priv;
+   struct sg_table *sgt = buf->dma_sgt;
+
+   if (!sgt)
+   return;
+
+   dma_sync_sg_for_device(buf->dev, sgt->sgl, sgt->nents, buf->dma_dir);
+}
+
+static void vb2_dc_finish(void *buf_priv)
+{
+   struct vb2_dc_buf *buf = buf_priv;
+   struct sg_table *sgt = buf->dma_sgt;
+
+   if (!sgt)
+   return;
+
+   dma_sync_sg_for_cpu(buf->dev, sgt->sgl, sgt->nents, buf->dma_dir);
+}
+
 /*/
 /*callbacks for MMAP buffers */
 /*/
@@ -366,6 +388,8 @@ const struct vb2_mem_ops vb2_dma_contig_memops = {
.mmap   = vb2_dc_mmap,
.get_userptr= vb2_dc_get_userptr,
.put_userptr= vb2_dc_put_userptr,
+   .prepare= vb2_dc_prepare,
+   .finish = vb2_dc_finish,
.num_users  = vb2_dc_num_users,
 };
 EXPORT_SYMBOL_GPL(vb2_dma_contig_memops);
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv8 11/26] v4l: vb2-dma-contig: add support for dma_buf importing

2012-08-14 Thread Tomasz Stanislawski
From: Sumit Semwal 

This patch makes changes for adding dma-contig as a dma_buf user. It provides
function implementations for the {attach, detach, map, unmap}_dmabuf()
mem_ops of DMABUF memory type.

Signed-off-by: Sumit Semwal 
Signed-off-by: Sumit Semwal 
[author of the original patch]
Signed-off-by: Tomasz Stanislawski 
[integration with refactored dma-contig allocator]
Acked-by: Laurent Pinchart 
---
 drivers/media/video/videobuf2-dma-contig.c |  120 +++-
 1 file changed, 118 insertions(+), 2 deletions(-)

diff --git a/drivers/media/video/videobuf2-dma-contig.c 
b/drivers/media/video/videobuf2-dma-contig.c
index 494a824..a5804cf 100644
--- a/drivers/media/video/videobuf2-dma-contig.c
+++ b/drivers/media/video/videobuf2-dma-contig.c
@@ -10,6 +10,7 @@
  * the Free Software Foundation.
  */
 
+#include 
 #include 
 #include 
 #include 
@@ -38,6 +39,9 @@ struct vb2_dc_buf {
 
/* USERPTR related */
struct vm_area_struct   *vma;
+
+   /* DMABUF related */
+   struct dma_buf_attachment   *db_attach;
 };
 
 /*/
@@ -108,7 +112,8 @@ static void vb2_dc_prepare(void *buf_priv)
struct vb2_dc_buf *buf = buf_priv;
struct sg_table *sgt = buf->dma_sgt;
 
-   if (!sgt)
+   /* DMABUF exporter will flush the cache for us */
+   if (!sgt || buf->db_attach)
return;
 
dma_sync_sg_for_device(buf->dev, sgt->sgl, sgt->nents, buf->dma_dir);
@@ -119,7 +124,8 @@ static void vb2_dc_finish(void *buf_priv)
struct vb2_dc_buf *buf = buf_priv;
struct sg_table *sgt = buf->dma_sgt;
 
-   if (!sgt)
+   /* DMABUF exporter will flush the cache for us */
+   if (!sgt || buf->db_attach)
return;
 
dma_sync_sg_for_cpu(buf->dev, sgt->sgl, sgt->nents, buf->dma_dir);
@@ -377,6 +383,112 @@ fail_buf:
 }
 
 /*/
+/*   callbacks for DMABUF buffers*/
+/*/
+
+static int vb2_dc_map_dmabuf(void *mem_priv)
+{
+   struct vb2_dc_buf *buf = mem_priv;
+   struct sg_table *sgt;
+   unsigned long contig_size;
+
+   if (WARN_ON(!buf->db_attach)) {
+   pr_err("trying to pin a non attached buffer\n");
+   return -EINVAL;
+   }
+
+   if (WARN_ON(buf->dma_sgt)) {
+   pr_err("dmabuf buffer is already pinned\n");
+   return 0;
+   }
+
+   /* get the associated scatterlist for this buffer */
+   sgt = dma_buf_map_attachment(buf->db_attach, buf->dma_dir);
+   if (IS_ERR_OR_NULL(sgt)) {
+   pr_err("Error getting dmabuf scatterlist\n");
+   return -EINVAL;
+   }
+
+   /* checking if dmabuf is big enough to store contiguous chunk */
+   contig_size = vb2_dc_get_contiguous_size(sgt);
+   if (contig_size < buf->size) {
+   pr_err("contiguous chunk is too small %lu/%lu b\n",
+   contig_size, buf->size);
+   dma_buf_unmap_attachment(buf->db_attach, sgt, buf->dma_dir);
+   return -EFAULT;
+   }
+
+   buf->dma_addr = sg_dma_address(sgt->sgl);
+   buf->dma_sgt = sgt;
+
+   return 0;
+}
+
+static void vb2_dc_unmap_dmabuf(void *mem_priv)
+{
+   struct vb2_dc_buf *buf = mem_priv;
+   struct sg_table *sgt = buf->dma_sgt;
+
+   if (WARN_ON(!buf->db_attach)) {
+   pr_err("trying to unpin a not attached buffer\n");
+   return;
+   }
+
+   if (WARN_ON(!sgt)) {
+   pr_err("dmabuf buffer is already unpinned\n");
+   return;
+   }
+
+   dma_buf_unmap_attachment(buf->db_attach, sgt, buf->dma_dir);
+
+   buf->dma_addr = 0;
+   buf->dma_sgt = NULL;
+}
+
+static void vb2_dc_detach_dmabuf(void *mem_priv)
+{
+   struct vb2_dc_buf *buf = mem_priv;
+
+   /* if vb2 works correctly you should never detach mapped buffer */
+   if (WARN_ON(buf->dma_addr))
+   vb2_dc_unmap_dmabuf(buf);
+
+   /* detach this attachment */
+   dma_buf_detach(buf->db_attach->dmabuf, buf->db_attach);
+   kfree(buf);
+}
+
+static void *vb2_dc_attach_dmabuf(void *alloc_ctx, struct dma_buf *dbuf,
+   unsigned long size, int write)
+{
+   struct vb2_dc_conf *conf = alloc_ctx;
+   struct vb2_dc_buf *buf;
+   struct dma_buf_attachment *dba;
+
+   if (dbuf->size < size)
+   return ERR_PTR(-EFAULT);
+
+   buf = kzalloc(sizeof(*buf), GFP_KERNEL);
+   if (!buf)
+   return ERR_PTR(-ENOMEM);
+
+   buf->dev = conf->dev;
+   /* create attachment for the dmabuf with the user device */
+   dba = dma_buf_attach(dbuf, buf->dev);
+   if (IS_ERR(dba)) {
+   pr_

[PATCHv8 12/26] v4l: vb2-vmalloc: add support for dmabuf importing

2012-08-14 Thread Tomasz Stanislawski
This patch adds support for importing DMABUF files for
vmalloc allocator in Videobuf2.

Signed-off-by: Tomasz Stanislawski 
Signed-off-by: Kyungmin Park 
---
 drivers/media/video/videobuf2-vmalloc.c |   56 +++
 1 file changed, 56 insertions(+)

diff --git a/drivers/media/video/videobuf2-vmalloc.c 
b/drivers/media/video/videobuf2-vmalloc.c
index 94efa04..a47fd4f 100644
--- a/drivers/media/video/videobuf2-vmalloc.c
+++ b/drivers/media/video/videobuf2-vmalloc.c
@@ -30,6 +30,7 @@ struct vb2_vmalloc_buf {
unsigned intn_pages;
atomic_trefcount;
struct vb2_vmarea_handler   handler;
+   struct dma_buf  *dbuf;
 };
 
 static void vb2_vmalloc_put(void *buf_priv);
@@ -207,11 +208,66 @@ static int vb2_vmalloc_mmap(void *buf_priv, struct 
vm_area_struct *vma)
return 0;
 }
 
+/*/
+/*   callbacks for DMABUF buffers*/
+/*/
+
+static int vb2_vmalloc_map_dmabuf(void *mem_priv)
+{
+   struct vb2_vmalloc_buf *buf = mem_priv;
+
+   buf->vaddr = dma_buf_vmap(buf->dbuf);
+
+   return buf->vaddr ? 0 : -EFAULT;
+}
+
+static void vb2_vmalloc_unmap_dmabuf(void *mem_priv)
+{
+   struct vb2_vmalloc_buf *buf = mem_priv;
+
+   dma_buf_vunmap(buf->dbuf, buf->vaddr);
+   buf->vaddr = NULL;
+}
+
+static void vb2_vmalloc_detach_dmabuf(void *mem_priv)
+{
+   struct vb2_vmalloc_buf *buf = mem_priv;
+
+   if (buf->vaddr)
+   dma_buf_vunmap(buf->dbuf, buf->vaddr);
+
+   kfree(buf);
+}
+
+static void *vb2_vmalloc_attach_dmabuf(void *alloc_ctx, struct dma_buf *dbuf,
+   unsigned long size, int write)
+{
+   struct vb2_vmalloc_buf *buf;
+
+   if (dbuf->size < size)
+   return ERR_PTR(-EFAULT);
+
+   buf = kzalloc(sizeof(*buf), GFP_KERNEL);
+   if (!buf)
+   return ERR_PTR(-ENOMEM);
+
+   buf->dbuf = dbuf;
+   buf->write = write;
+   buf->size = size;
+
+   return buf;
+}
+
+
 const struct vb2_mem_ops vb2_vmalloc_memops = {
.alloc  = vb2_vmalloc_alloc,
.put= vb2_vmalloc_put,
.get_userptr= vb2_vmalloc_get_userptr,
.put_userptr= vb2_vmalloc_put_userptr,
+   .map_dmabuf = vb2_vmalloc_map_dmabuf,
+   .unmap_dmabuf   = vb2_vmalloc_unmap_dmabuf,
+   .attach_dmabuf  = vb2_vmalloc_attach_dmabuf,
+   .detach_dmabuf  = vb2_vmalloc_detach_dmabuf,
.vaddr  = vb2_vmalloc_vaddr,
.mmap   = vb2_vmalloc_mmap,
.num_users  = vb2_vmalloc_num_users,
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv8 13/26] v4l: vivi: support for dmabuf importing

2012-08-14 Thread Tomasz Stanislawski
This patch enhances VIVI driver with a support for importing a buffer
from DMABUF file descriptors.

Signed-off-by: Tomasz Stanislawski 
Signed-off-by: Kyungmin Park 
---
 drivers/media/video/Kconfig |1 +
 drivers/media/video/vivi.c  |2 +-
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index 966954d..8fa81be 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -653,6 +653,7 @@ config VIDEO_VIVI
depends on FRAMEBUFFER_CONSOLE || STI_CONSOLE
select FONT_8x16
select VIDEOBUF2_VMALLOC
+   select DMA_SHARED_BUFFER
default n
---help---
  Enables a virtual video driver. This device shows a color bar
diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c
index a6351c4..37d8fd4 100644
--- a/drivers/media/video/vivi.c
+++ b/drivers/media/video/vivi.c
@@ -1308,7 +1308,7 @@ static int __init vivi_create_instance(int inst)
q = &dev->vb_vidq;
memset(q, 0, sizeof(dev->vb_vidq));
q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-   q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ;
+   q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF | VB2_READ;
q->drv_priv = dev;
q->buf_struct_size = sizeof(struct vivi_buffer);
q->ops = &vivi_video_qops;
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv8 14/26] v4l: s5p-tv: mixer: support for dmabuf importing

2012-08-14 Thread Tomasz Stanislawski
This patch enhances s5p-tv with support for DMABUF importing via
V4L2_MEMORY_DMABUF memory type.

Signed-off-by: Tomasz Stanislawski 
Signed-off-by: Kyungmin Park 
---
 drivers/media/video/s5p-tv/Kconfig   |1 +
 drivers/media/video/s5p-tv/mixer_video.c |2 +-
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/media/video/s5p-tv/Kconfig 
b/drivers/media/video/s5p-tv/Kconfig
index f248b28..2e80126 100644
--- a/drivers/media/video/s5p-tv/Kconfig
+++ b/drivers/media/video/s5p-tv/Kconfig
@@ -10,6 +10,7 @@ config VIDEO_SAMSUNG_S5P_TV
bool "Samsung TV driver for S5P platform (experimental)"
depends on PLAT_S5P && PM_RUNTIME
depends on EXPERIMENTAL
+   select DMA_SHARED_BUFFER
default n
---help---
  Say Y here to enable selecting the TV output devices for
diff --git a/drivers/media/video/s5p-tv/mixer_video.c 
b/drivers/media/video/s5p-tv/mixer_video.c
index e0e02cc..da5b7a5 100644
--- a/drivers/media/video/s5p-tv/mixer_video.c
+++ b/drivers/media/video/s5p-tv/mixer_video.c
@@ -1091,7 +1091,7 @@ struct mxr_layer *mxr_base_layer_create(struct mxr_device 
*mdev,
 
layer->vb_queue = (struct vb2_queue) {
.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
-   .io_modes = VB2_MMAP | VB2_USERPTR,
+   .io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF,
.drv_priv = layer,
.buf_struct_size = sizeof(struct mxr_buffer),
.ops = &mxr_video_qops,
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv8 15/26] v4l: s5p-fimc: support for dmabuf importing

2012-08-14 Thread Tomasz Stanislawski
This patch enhances s5p-fimc with support for DMABUF importing via
V4L2_MEMORY_DMABUF memory type.

Signed-off-by: Tomasz Stanislawski 
Signed-off-by: Kyungmin Park 
Acked-by: Sylwester Nawrocki 
---
 drivers/media/video/s5p-fimc/Kconfig|1 +
 drivers/media/video/s5p-fimc/fimc-capture.c |2 +-
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/media/video/s5p-fimc/Kconfig 
b/drivers/media/video/s5p-fimc/Kconfig
index a564f7e..3106026 100644
--- a/drivers/media/video/s5p-fimc/Kconfig
+++ b/drivers/media/video/s5p-fimc/Kconfig
@@ -14,6 +14,7 @@ config VIDEO_S5P_FIMC
depends on I2C
select VIDEOBUF2_DMA_CONTIG
select V4L2_MEM2MEM_DEV
+   select DMA_SHARED_BUFFER
help
  This is a V4L2 driver for Samsung S5P and EXYNOS4 SoC camera host
  interface and video postprocessor (FIMC and FIMC-LITE) devices.
diff --git a/drivers/media/video/s5p-fimc/fimc-capture.c 
b/drivers/media/video/s5p-fimc/fimc-capture.c
index 8e413dd..3fcaf7d 100644
--- a/drivers/media/video/s5p-fimc/fimc-capture.c
+++ b/drivers/media/video/s5p-fimc/fimc-capture.c
@@ -1634,7 +1634,7 @@ static int fimc_register_capture_device(struct fimc_dev 
*fimc,
q = &fimc->vid_cap.vbq;
memset(q, 0, sizeof(*q));
q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
-   q->io_modes = VB2_MMAP | VB2_USERPTR;
+   q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
q->drv_priv = fimc->vid_cap.ctx;
q->ops = &fimc_capture_qops;
q->mem_ops = &vb2_dma_contig_memops;
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv8 16/26] v4l: vb2-dma-contig: let mmap method to use dma_mmap_coherent call

2012-08-14 Thread Tomasz Stanislawski
From: Marek Szyprowski 

Let mmap method to use dma_mmap_coherent call.  Moreover, this patch removes
vb2_mmap_pfn_range from videobuf2 helpers as it was suggested by Laurent
Pinchart.  The function is no longer used in vb2 code.

Signed-off-by: Marek Szyprowski 
Signed-off-by: Tomasz Stanislawski 
Acked-by: Laurent Pinchart 
---
 drivers/media/video/videobuf2-dma-contig.c |   28 +--
 drivers/media/video/videobuf2-memops.c |   40 
 include/media/videobuf2-memops.h   |5 
 3 files changed, 26 insertions(+), 47 deletions(-)

diff --git a/drivers/media/video/videobuf2-dma-contig.c 
b/drivers/media/video/videobuf2-dma-contig.c
index a5804cf..7fc71a0 100644
--- a/drivers/media/video/videobuf2-dma-contig.c
+++ b/drivers/media/video/videobuf2-dma-contig.c
@@ -178,14 +178,38 @@ static void *vb2_dc_alloc(void *alloc_ctx, unsigned long 
size)
 static int vb2_dc_mmap(void *buf_priv, struct vm_area_struct *vma)
 {
struct vb2_dc_buf *buf = buf_priv;
+   int ret;
 
if (!buf) {
printk(KERN_ERR "No buffer to map\n");
return -EINVAL;
}
 
-   return vb2_mmap_pfn_range(vma, buf->dma_addr, buf->size,
- &vb2_common_vm_ops, &buf->handler);
+   /*
+* dma_mmap_* uses vm_pgoff as in-buffer offset, but we want to
+* map whole buffer
+*/
+   vma->vm_pgoff = 0;
+
+   ret = dma_mmap_coherent(buf->dev, vma, buf->vaddr,
+   buf->dma_addr, buf->size);
+
+   if (ret) {
+   pr_err("Remapping memory failed, error: %d\n", ret);
+   return ret;
+   }
+
+   vma->vm_flags   |= VM_DONTEXPAND | VM_DONTDUMP;
+   vma->vm_private_data= &buf->handler;
+   vma->vm_ops = &vb2_common_vm_ops;
+
+   vma->vm_ops->open(vma);
+
+   pr_debug("%s: mapped dma addr 0x%08lx at 0x%08lx, size %ld\n",
+   __func__, (unsigned long)buf->dma_addr, vma->vm_start,
+   buf->size);
+
+   return 0;
 }
 
 /*/
diff --git a/drivers/media/video/videobuf2-memops.c 
b/drivers/media/video/videobuf2-memops.c
index 051ea35..81c1ad8 100644
--- a/drivers/media/video/videobuf2-memops.c
+++ b/drivers/media/video/videobuf2-memops.c
@@ -137,46 +137,6 @@ int vb2_get_contig_userptr(unsigned long vaddr, unsigned 
long size,
 EXPORT_SYMBOL_GPL(vb2_get_contig_userptr);
 
 /**
- * vb2_mmap_pfn_range() - map physical pages to userspace
- * @vma:   virtual memory region for the mapping
- * @paddr: starting physical address of the memory to be mapped
- * @size:  size of the memory to be mapped
- * @vm_ops:vm operations to be assigned to the created area
- * @priv:  private data to be associated with the area
- *
- * Returns 0 on success.
- */
-int vb2_mmap_pfn_range(struct vm_area_struct *vma, unsigned long paddr,
-   unsigned long size,
-   const struct vm_operations_struct *vm_ops,
-   void *priv)
-{
-   int ret;
-
-   size = min_t(unsigned long, vma->vm_end - vma->vm_start, size);
-
-   vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
-   ret = remap_pfn_range(vma, vma->vm_start, paddr >> PAGE_SHIFT,
-   size, vma->vm_page_prot);
-   if (ret) {
-   printk(KERN_ERR "Remapping memory failed, error: %d\n", ret);
-   return ret;
-   }
-
-   vma->vm_flags   |= VM_DONTEXPAND | VM_DONTDUMP;
-   vma->vm_private_data= priv;
-   vma->vm_ops = vm_ops;
-
-   vma->vm_ops->open(vma);
-
-   pr_debug("%s: mapped paddr 0x%08lx at 0x%08lx, size %ld\n",
-   __func__, paddr, vma->vm_start, size);
-
-   return 0;
-}
-EXPORT_SYMBOL_GPL(vb2_mmap_pfn_range);
-
-/**
  * vb2_common_vm_open() - increase refcount of the vma
  * @vma:   virtual memory region for the mapping
  *
diff --git a/include/media/videobuf2-memops.h b/include/media/videobuf2-memops.h
index 84e1f6c..f05444c 100644
--- a/include/media/videobuf2-memops.h
+++ b/include/media/videobuf2-memops.h
@@ -33,11 +33,6 @@ extern const struct vm_operations_struct vb2_common_vm_ops;
 int vb2_get_contig_userptr(unsigned long vaddr, unsigned long size,
   struct vm_area_struct **res_vma, dma_addr_t *res_pa);
 
-int vb2_mmap_pfn_range(struct vm_area_struct *vma, unsigned long paddr,
-   unsigned long size,
-   const struct vm_operations_struct *vm_ops,
-   void *priv);
-
 struct vm_area_struct *vb2_get_vma(struct vm_area_struct *vma);
 void vb2_put_vma(struct vm_area_struct *vma);
 
-- 
1.7.9.

[PATCHv8 19/26] v4l: vb2: add buffer exporting via dmabuf

2012-08-14 Thread Tomasz Stanislawski
This patch adds extension to videobuf2-core. It allow to export a mmap buffer
as a file descriptor.

Signed-off-by: Tomasz Stanislawski 
Signed-off-by: Kyungmin Park 
Acked-by: Laurent Pinchart 
---
 drivers/media/video/videobuf2-core.c |   67 ++
 include/media/videobuf2-core.h   |2 +
 2 files changed, 69 insertions(+)

diff --git a/drivers/media/video/videobuf2-core.c 
b/drivers/media/video/videobuf2-core.c
index aed21e4..61354ec 100644
--- a/drivers/media/video/videobuf2-core.c
+++ b/drivers/media/video/videobuf2-core.c
@@ -1743,6 +1743,73 @@ static int __find_plane_by_offset(struct vb2_queue *q, 
unsigned long off,
 }
 
 /**
+ * vb2_expbuf() - Export a buffer as a file descriptor
+ * @q: videobuf2 queue
+ * @eb:export buffer structure passed from userspace to 
vidioc_expbuf
+ * handler in driver
+ *
+ * The return values from this function are intended to be directly returned
+ * from vidioc_expbuf handler in driver.
+ */
+int vb2_expbuf(struct vb2_queue *q, struct v4l2_exportbuffer *eb)
+{
+   struct vb2_buffer *vb = NULL;
+   struct vb2_plane *vb_plane;
+   unsigned int buffer, plane;
+   int ret;
+   struct dma_buf *dbuf;
+
+   if (q->memory != V4L2_MEMORY_MMAP) {
+   dprintk(1, "Queue is not currently set up for mmap\n");
+   return -EINVAL;
+   }
+
+   if (!q->mem_ops->get_dmabuf) {
+   dprintk(1, "Queue does not support DMA buffer exporting\n");
+   return -EINVAL;
+   }
+
+   if (eb->flags & ~O_CLOEXEC) {
+   dprintk(1, "Queue does support only O_CLOEXEC flag\n");
+   return -EINVAL;
+   }
+
+   /*
+* Find the plane corresponding to the offset passed by userspace.
+*/
+   ret = __find_plane_by_offset(q, eb->mem_offset, &buffer, &plane);
+   if (ret) {
+   dprintk(1, "invalid offset %u\n", eb->mem_offset);
+   return ret;
+   }
+
+   vb = q->bufs[buffer];
+   vb_plane = &vb->planes[plane];
+
+   dbuf = call_memop(q, get_dmabuf, vb_plane->mem_priv);
+   if (IS_ERR_OR_NULL(dbuf)) {
+   dprintk(1, "Failed to export buffer %d, plane %d\n",
+   buffer, plane);
+   return -EINVAL;
+   }
+
+   ret = dma_buf_fd(dbuf, eb->flags);
+   if (ret < 0) {
+   dprintk(3, "buffer %d, plane %d failed to export (%d)\n",
+   buffer, plane, ret);
+   dma_buf_put(dbuf);
+   return ret;
+   }
+
+   dprintk(3, "buffer %d, plane %d exported as %d descriptor\n",
+   buffer, plane, ret);
+   eb->fd = ret;
+
+   return 0;
+}
+EXPORT_SYMBOL_GPL(vb2_expbuf);
+
+/**
  * vb2_mmap() - map video buffers into application address space
  * @q: videobuf2 queue
  * @vma:   vma passed to the mmap file operation handler in the driver
diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h
index c306fec..b034424 100644
--- a/include/media/videobuf2-core.h
+++ b/include/media/videobuf2-core.h
@@ -81,6 +81,7 @@ struct vb2_fileio_data;
 struct vb2_mem_ops {
void*(*alloc)(void *alloc_ctx, unsigned long size);
void(*put)(void *buf_priv);
+   struct dma_buf *(*get_dmabuf)(void *buf_priv);
 
void*(*get_userptr)(void *alloc_ctx, unsigned long vaddr,
unsigned long size, int write);
@@ -363,6 +364,7 @@ int vb2_queue_init(struct vb2_queue *q);
 void vb2_queue_release(struct vb2_queue *q);
 
 int vb2_qbuf(struct vb2_queue *q, struct v4l2_buffer *b);
+int vb2_expbuf(struct vb2_queue *q, struct v4l2_exportbuffer *eb);
 int vb2_dqbuf(struct vb2_queue *q, struct v4l2_buffer *b, bool nonblocking);
 
 int vb2_streamon(struct vb2_queue *q, enum v4l2_buf_type type);
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv8 18/26] v4l: add buffer exporting via dmabuf

2012-08-14 Thread Tomasz Stanislawski
This patch adds extension to V4L2 api. It allow to export a mmap buffer as file
descriptor. New ioctl VIDIOC_EXPBUF is added. It takes a buffer offset used by
mmap and return a file descriptor on success.

Signed-off-by: Tomasz Stanislawski 
Signed-off-by: Kyungmin Park 
---
 drivers/media/video/v4l2-compat-ioctl32.c |1 +
 drivers/media/video/v4l2-dev.c|1 +
 drivers/media/video/v4l2-ioctl.c  |   15 +++
 include/linux/videodev2.h |   26 ++
 include/media/v4l2-ioctl.h|2 ++
 5 files changed, 45 insertions(+)

diff --git a/drivers/media/video/v4l2-compat-ioctl32.c 
b/drivers/media/video/v4l2-compat-ioctl32.c
index a2e0549..7689c4a 100644
--- a/drivers/media/video/v4l2-compat-ioctl32.c
+++ b/drivers/media/video/v4l2-compat-ioctl32.c
@@ -971,6 +971,7 @@ long v4l2_compat_ioctl32(struct file *file, unsigned int 
cmd, unsigned long arg)
case VIDIOC_S_FBUF32:
case VIDIOC_OVERLAY32:
case VIDIOC_QBUF32:
+   case VIDIOC_EXPBUF:
case VIDIOC_DQBUF32:
case VIDIOC_STREAMON32:
case VIDIOC_STREAMOFF32:
diff --git a/drivers/media/video/v4l2-dev.c b/drivers/media/video/v4l2-dev.c
index 71237f5..f6e7ea5 100644
--- a/drivers/media/video/v4l2-dev.c
+++ b/drivers/media/video/v4l2-dev.c
@@ -607,6 +607,7 @@ static void determine_valid_ioctls(struct video_device 
*vdev)
SET_VALID_IOCTL(ops, VIDIOC_REQBUFS, vidioc_reqbufs);
SET_VALID_IOCTL(ops, VIDIOC_QUERYBUF, vidioc_querybuf);
SET_VALID_IOCTL(ops, VIDIOC_QBUF, vidioc_qbuf);
+   SET_VALID_IOCTL(ops, VIDIOC_EXPBUF, vidioc_expbuf);
SET_VALID_IOCTL(ops, VIDIOC_DQBUF, vidioc_dqbuf);
SET_VALID_IOCTL(ops, VIDIOC_OVERLAY, vidioc_overlay);
SET_VALID_IOCTL(ops, VIDIOC_G_FBUF, vidioc_g_fbuf);
diff --git a/drivers/media/video/v4l2-ioctl.c b/drivers/media/video/v4l2-ioctl.c
index dffd3c9..c4e8c7e 100644
--- a/drivers/media/video/v4l2-ioctl.c
+++ b/drivers/media/video/v4l2-ioctl.c
@@ -458,6 +458,14 @@ static void v4l_print_buffer(const void *arg, bool 
write_only)
tc->type, tc->flags, tc->frames, *(__u32 
*)tc->userbits);
 }
 
+static void v4l_print_exportbuffer(const void *arg, bool write_only)
+{
+   const struct v4l2_exportbuffer *p = arg;
+
+   pr_cont("fd=%d, mem_offset=%lx, flags=%lx\n",
+   p->fd, (unsigned long)p->mem_offset, (unsigned long)p->flags);
+}
+
 static void v4l_print_create_buffers(const void *arg, bool write_only)
 {
const struct v4l2_create_buffers *p = arg;
@@ -1254,6 +1262,12 @@ static int v4l_streamoff(const struct v4l2_ioctl_ops 
*ops,
return ops->vidioc_streamoff(file, fh, *(unsigned int *)arg);
 }
 
+static int v4l_expbuf(const struct v4l2_ioctl_ops *ops,
+   struct file *file, void *fh, void *arg)
+{
+   return ops->vidioc_expbuf(file, fh, arg);
+}
+
 static int v4l_g_tuner(const struct v4l2_ioctl_ops *ops,
struct file *file, void *fh, void *arg)
 {
@@ -1947,6 +1961,7 @@ static struct v4l2_ioctl_info v4l2_ioctls[] = {
IOCTL_INFO_STD(VIDIOC_S_FBUF, vidioc_s_fbuf, v4l_print_framebuffer, 
INFO_FL_PRIO),
IOCTL_INFO_STD(VIDIOC_OVERLAY, vidioc_overlay, v4l_print_u32, 
INFO_FL_PRIO),
IOCTL_INFO_FNC(VIDIOC_QBUF, v4l_qbuf, v4l_print_buffer, INFO_FL_QUEUE),
+   IOCTL_INFO_FNC(VIDIOC_EXPBUF, v4l_expbuf, v4l_print_exportbuffer, 
INFO_FL_CLEAR(v4l2_exportbuffer, flags)),
IOCTL_INFO_FNC(VIDIOC_DQBUF, v4l_dqbuf, v4l_print_buffer, 
INFO_FL_QUEUE),
IOCTL_INFO_FNC(VIDIOC_STREAMON, v4l_streamon, v4l_print_buftype, 
INFO_FL_PRIO | INFO_FL_QUEUE),
IOCTL_INFO_FNC(VIDIOC_STREAMOFF, v4l_streamoff, v4l_print_buftype, 
INFO_FL_PRIO | INFO_FL_QUEUE),
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index 7f918dc..b5d058b 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -688,6 +688,31 @@ struct v4l2_buffer {
 #define V4L2_BUF_FLAG_NO_CACHE_INVALIDATE  0x0800
 #define V4L2_BUF_FLAG_NO_CACHE_CLEAN   0x1000
 
+/**
+ * struct v4l2_exportbuffer - export of video buffer as DMABUF file descriptor
+ *
+ * @fd:file descriptor associated with DMABUF (set by driver)
+ * @mem_offset:buffer memory offset as returned by VIDIOC_QUERYBUF in 
struct
+ * v4l2_buffer::m.offset (for single-plane formats) or
+ * v4l2_plane::m.offset (for multi-planar formats)
+ * @flags: flags for newly created file, currently only O_CLOEXEC is
+ * supported, refer to manual of open syscall for more details
+ *
+ * Contains data used for exporting a video buffer as DMABUF file descriptor.
+ * The buffer is identified by a 'cookie' returned by VIDIOC_QUERYBUF
+ * (identical to the cookie used to mmap() the buffer to userspace). All
+ * reserved fields must be set to zero. The field reserv

[PATCHv8 20/26] v4l: vb2-dma-contig: add support for DMABUF exporting

2012-08-14 Thread Tomasz Stanislawski
This patch adds support for exporting a dma-contig buffer using
DMABUF interface.

Signed-off-by: Tomasz Stanislawski 
Signed-off-by: Kyungmin Park 
---
 drivers/media/video/videobuf2-dma-contig.c |  204 
 1 file changed, 204 insertions(+)

diff --git a/drivers/media/video/videobuf2-dma-contig.c 
b/drivers/media/video/videobuf2-dma-contig.c
index 7fc71a0..bb2b4ac8 100644
--- a/drivers/media/video/videobuf2-dma-contig.c
+++ b/drivers/media/video/videobuf2-dma-contig.c
@@ -36,6 +36,7 @@ struct vb2_dc_buf {
/* MMAP related */
struct vb2_vmarea_handler   handler;
atomic_trefcount;
+   struct sg_table *sgt_base;
 
/* USERPTR related */
struct vm_area_struct   *vma;
@@ -142,6 +143,10 @@ static void vb2_dc_put(void *buf_priv)
if (!atomic_dec_and_test(&buf->refcount))
return;
 
+   if (buf->sgt_base) {
+   sg_free_table(buf->sgt_base);
+   kfree(buf->sgt_base);
+   }
dma_free_coherent(buf->dev, buf->size, buf->vaddr, buf->dma_addr);
kfree(buf);
 }
@@ -213,6 +218,204 @@ static int vb2_dc_mmap(void *buf_priv, struct 
vm_area_struct *vma)
 }
 
 /*/
+/* DMABUF ops for exporters  */
+/*/
+
+struct vb2_dc_attachment {
+   struct sg_table sgt;
+   enum dma_data_direction dir;
+};
+
+static int vb2_dc_dmabuf_ops_attach(struct dma_buf *dbuf, struct device *dev,
+   struct dma_buf_attachment *dbuf_attach)
+{
+   struct vb2_dc_attachment *attach;
+   unsigned int i;
+   struct scatterlist *rd, *wr;
+   struct sg_table *sgt;
+   struct vb2_dc_buf *buf = dbuf->priv;
+   int ret;
+
+   attach = kzalloc(sizeof(*attach), GFP_KERNEL);
+   if (!attach)
+   return -ENOMEM;
+
+   sgt = &attach->sgt;
+   /* Copy the buf->base_sgt scatter list to the attachment, as we can't
+* map the same scatter list to multiple attachments at the same time.
+*/
+   ret = sg_alloc_table(sgt, buf->sgt_base->orig_nents, GFP_KERNEL);
+   if (ret) {
+   kfree(attach);
+   return -ENOMEM;
+   }
+
+   rd = buf->sgt_base->sgl;
+   wr = sgt->sgl;
+   for (i = 0; i < sgt->orig_nents; ++i) {
+   sg_set_page(wr, sg_page(rd), rd->length, rd->offset);
+   rd = sg_next(rd);
+   wr = sg_next(wr);
+   }
+
+   attach->dir = DMA_NONE;
+   dbuf_attach->priv = attach;
+
+   return 0;
+}
+
+static void vb2_dc_dmabuf_ops_detach(struct dma_buf *dbuf,
+   struct dma_buf_attachment *db_attach)
+{
+   struct vb2_dc_attachment *attach = db_attach->priv;
+   struct sg_table *sgt;
+
+   if (!attach)
+   return;
+
+   sgt = &attach->sgt;
+
+   /* release the scatterlist cache */
+   if (attach->dir != DMA_NONE)
+   dma_unmap_sg(db_attach->dev, sgt->sgl, sgt->orig_nents,
+   attach->dir);
+   sg_free_table(sgt);
+   kfree(attach);
+   db_attach->priv = NULL;
+}
+
+static struct sg_table *vb2_dc_dmabuf_ops_map(
+   struct dma_buf_attachment *db_attach, enum dma_data_direction dir)
+{
+   struct vb2_dc_attachment *attach = db_attach->priv;
+   /* stealing dmabuf mutex to serialize map/unmap operations */
+   struct mutex *lock = &db_attach->dmabuf->lock;
+   struct sg_table *sgt;
+   int ret;
+
+   mutex_lock(lock);
+
+   sgt = &attach->sgt;
+   /* return previously mapped sg table */
+   if (attach->dir == dir) {
+   mutex_unlock(lock);
+   return sgt;
+   }
+
+   /* release any previous cache */
+   if (attach->dir != DMA_NONE) {
+   dma_unmap_sg(db_attach->dev, sgt->sgl, sgt->orig_nents,
+   attach->dir);
+   attach->dir = DMA_NONE;
+   }
+
+   /* mapping to the client with new direction */
+   ret = dma_map_sg(db_attach->dev, sgt->sgl, sgt->orig_nents, dir);
+   if (ret <= 0) {
+   pr_err("failed to map scatterlist\n");
+   mutex_unlock(lock);
+   return ERR_PTR(-EIO);
+   }
+
+   attach->dir = dir;
+
+   mutex_unlock(lock);
+
+   return sgt;
+}
+
+static void vb2_dc_dmabuf_ops_unmap(struct dma_buf_attachment *db_attach,
+   struct sg_table *sgt, enum dma_data_direction dir)
+{
+   /* nothing to be done here */
+}
+
+static void vb2_dc_dmabuf_ops_release(struct dma_buf *dbuf)
+{
+   /* drop reference obtained in vb2_dc_get_dmabuf */
+   vb2_dc_put(dbuf->priv);
+}
+
+static void *vb2_dc_dmabuf_ops_kmap(struct dma_buf *dbuf, unsigned long pgnum)
+{

[PATCHv8 21/26] v4l: vb2-dma-contig: add reference counting for a device from allocator context

2012-08-14 Thread Tomasz Stanislawski
This patch adds taking reference to the device for MMAP buffers.

Such buffers, may be exported using DMABUF mechanism. If the driver that
created a queue is unloaded then the queue is released, the device might be
released too.  However, buffers cannot be released if they are referenced by
DMABUF descriptor(s). The device pointer kept in a buffer must be valid for the
whole buffer's lifetime. Therefore MMAP buffers should take a reference to the
device to avoid risk of dangling pointers.

Signed-off-by: Tomasz Stanislawski 
---
 drivers/media/video/videobuf2-dma-contig.c |5 +
 1 file changed, 5 insertions(+)

diff --git a/drivers/media/video/videobuf2-dma-contig.c 
b/drivers/media/video/videobuf2-dma-contig.c
index bb2b4ac8..d44766e 100644
--- a/drivers/media/video/videobuf2-dma-contig.c
+++ b/drivers/media/video/videobuf2-dma-contig.c
@@ -148,6 +148,7 @@ static void vb2_dc_put(void *buf_priv)
kfree(buf->sgt_base);
}
dma_free_coherent(buf->dev, buf->size, buf->vaddr, buf->dma_addr);
+   put_device(buf->dev);
kfree(buf);
 }
 
@@ -161,9 +162,13 @@ static void *vb2_dc_alloc(void *alloc_ctx, unsigned long 
size)
if (!buf)
return ERR_PTR(-ENOMEM);
 
+   /* prevent the device from release while the buffer is exported */
+   get_device(dev);
+
buf->vaddr = dma_alloc_coherent(dev, size, &buf->dma_addr, GFP_KERNEL);
if (!buf->vaddr) {
dev_err(dev, "dma_alloc_coherent of size %ld failed\n", size);
+   put_device(dev);
kfree(buf);
return ERR_PTR(-ENOMEM);
}
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv8 22/26] media: vb2: fail if user ptr buffer is not correctly aligned

2012-08-14 Thread Tomasz Stanislawski
From: Marek Szyprowski 

Signed-off-by: Marek Szyprowski 
---
 drivers/media/video/videobuf2-dma-contig.c |   10 ++
 1 file changed, 10 insertions(+)

diff --git a/drivers/media/video/videobuf2-dma-contig.c 
b/drivers/media/video/videobuf2-dma-contig.c
index d44766e..11f4a46 100644
--- a/drivers/media/video/videobuf2-dma-contig.c
+++ b/drivers/media/video/videobuf2-dma-contig.c
@@ -498,6 +498,16 @@ static void *vb2_dc_get_userptr(void *alloc_ctx, unsigned 
long vaddr,
struct vm_area_struct *vma;
struct sg_table *sgt;
unsigned long contig_size;
+   unsigned long dma_align = dma_get_cache_alignment();
+
+   /*
+* DMA transfers are not reliable to buffers which
+* are not cache line aligned!
+*/
+   if (vaddr & (dma_align - 1)) {
+   pr_err("userptr must be aligned to %lu bytes\n", dma_align);
+   return ERR_PTR(-EINVAL);
+   }
 
buf = kzalloc(sizeof *buf, GFP_KERNEL);
if (!buf)
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv8 23/26] v4l: vb2: add support for DMA_ATTR_NO_KERNEL_MAPPING

2012-08-14 Thread Tomasz Stanislawski
From: Marek Szyprowski 

Signed-off-by: Marek Szyprowski 
---
 drivers/media/video/atmel-isi.c  |2 +-
 drivers/media/video/blackfin/bfin_capture.c  |2 +-
 drivers/media/video/marvell-ccic/mcam-core.c |3 ++-
 drivers/media/video/mx2_camera.c |2 +-
 drivers/media/video/mx2_emmaprp.c|2 +-
 drivers/media/video/mx3_camera.c |2 +-
 drivers/media/video/s5p-fimc/fimc-core.c |2 +-
 drivers/media/video/s5p-fimc/fimc-lite.c |2 +-
 drivers/media/video/s5p-g2d/g2d.c|2 +-
 drivers/media/video/s5p-jpeg/jpeg-core.c |2 +-
 drivers/media/video/s5p-mfc/s5p_mfc.c|5 ++--
 drivers/media/video/s5p-tv/mixer_video.c |2 +-
 drivers/media/video/sh_mobile_ceu_camera.c   |2 +-
 drivers/media/video/videobuf2-dma-contig.c   |   33 +++---
 drivers/staging/media/dt3155v4l/dt3155v4l.c  |2 +-
 include/media/videobuf2-dma-contig.h |4 +++-
 16 files changed, 44 insertions(+), 25 deletions(-)

diff --git a/drivers/media/video/atmel-isi.c b/drivers/media/video/atmel-isi.c
index 6274a91..9fb5283 100644
--- a/drivers/media/video/atmel-isi.c
+++ b/drivers/media/video/atmel-isi.c
@@ -1000,7 +1000,7 @@ static int __devinit atmel_isi_probe(struct 
platform_device *pdev)
list_add(&isi->dma_desc[i].list, &isi->dma_desc_head);
}
 
-   isi->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev);
+   isi->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev, 0);
if (IS_ERR(isi->alloc_ctx)) {
ret = PTR_ERR(isi->alloc_ctx);
goto err_alloc_ctx;
diff --git a/drivers/media/video/blackfin/bfin_capture.c 
b/drivers/media/video/blackfin/bfin_capture.c
index 1677623..7e90b65 100644
--- a/drivers/media/video/blackfin/bfin_capture.c
+++ b/drivers/media/video/blackfin/bfin_capture.c
@@ -893,7 +893,7 @@ static int __devinit bcap_probe(struct platform_device 
*pdev)
}
bcap_dev->ppi->priv = bcap_dev;
 
-   bcap_dev->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev);
+   bcap_dev->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev, 0);
if (IS_ERR(bcap_dev->alloc_ctx)) {
ret = PTR_ERR(bcap_dev->alloc_ctx);
goto err_free_ppi;
diff --git a/drivers/media/video/marvell-ccic/mcam-core.c 
b/drivers/media/video/marvell-ccic/mcam-core.c
index ce2b7b4..10d4db5 100644
--- a/drivers/media/video/marvell-ccic/mcam-core.c
+++ b/drivers/media/video/marvell-ccic/mcam-core.c
@@ -,7 +,8 @@ static int mcam_setup_vb2(struct mcam_camera *cam)
 #ifdef MCAM_MODE_DMA_CONTIG
vq->ops = &mcam_vb2_ops;
vq->mem_ops = &vb2_dma_contig_memops;
-   cam->vb_alloc_ctx = vb2_dma_contig_init_ctx(cam->dev);
+   cam->vb_alloc_ctx = vb2_dma_contig_init_ctx(cam->dev,
+   VB2_CREATE_VADDR);
vq->io_modes = VB2_MMAP | VB2_USERPTR;
cam->dma_setup = mcam_ctlr_dma_contig;
cam->frame_complete = mcam_dma_contig_done;
diff --git a/drivers/media/video/mx2_camera.c b/drivers/media/video/mx2_camera.c
index 637bde8..5c30302 100644
--- a/drivers/media/video/mx2_camera.c
+++ b/drivers/media/video/mx2_camera.c
@@ -1766,7 +1766,7 @@ static int __devinit mx2_camera_probe(struct 
platform_device *pdev)
if (cpu_is_mx25())
pcdev->soc_host.capabilities = SOCAM_HOST_CAP_STRIDE;
 
-   pcdev->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev);
+   pcdev->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev, 0);
if (IS_ERR(pcdev->alloc_ctx)) {
err = PTR_ERR(pcdev->alloc_ctx);
goto eallocctx;
diff --git a/drivers/media/video/mx2_emmaprp.c 
b/drivers/media/video/mx2_emmaprp.c
index 2810015..23c6c42 100644
--- a/drivers/media/video/mx2_emmaprp.c
+++ b/drivers/media/video/mx2_emmaprp.c
@@ -962,7 +962,7 @@ static int emmaprp_probe(struct platform_device *pdev)
 0, MEM2MEM_NAME, pcdev) < 0)
goto rel_vdev;
 
-   pcdev->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev);
+   pcdev->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev, 0);
if (IS_ERR(pcdev->alloc_ctx)) {
v4l2_err(&pcdev->v4l2_dev, "Failed to alloc vb2 context\n");
ret = PTR_ERR(pcdev->alloc_ctx);
diff --git a/drivers/media/video/mx3_camera.c b/drivers/media/video/mx3_camera.c
index f13643d..882026f 100644
--- a/drivers/media/video/mx3_camera.c
+++ b/drivers/media/video/mx3_camera.c
@@ -1227,7 +1227,7 @@ static int __devinit mx3_camera_probe(struct 
platform_device *pdev)
soc_host->v4l2_dev.dev  = &pdev->dev;
soc_host->nr= pdev->id;
 
-   mx3_cam->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev);
+   mx3_cam->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev, 0);
if (IS_ERR(mx3_cam->alloc_ctx)) {
err = PTR_ERR(mx3_cam->alloc_ctx);
goto eallocctx;
diff --

[PATCHv8 24/26] v4l: s5p-fimc: support for dmabuf exporting

2012-08-14 Thread Tomasz Stanislawski
This patch enhances s5p-fimc with support for DMABUF exporting via
VIDIOC_EXPBUF ioctl.

Signed-off-by: Tomasz Stanislawski 
Signed-off-by: Kyungmin Park 
---
 drivers/media/video/s5p-fimc/fimc-capture.c |9 +
 1 file changed, 9 insertions(+)

diff --git a/drivers/media/video/s5p-fimc/fimc-capture.c 
b/drivers/media/video/s5p-fimc/fimc-capture.c
index 3fcaf7d..bdd2de5 100644
--- a/drivers/media/video/s5p-fimc/fimc-capture.c
+++ b/drivers/media/video/s5p-fimc/fimc-capture.c
@@ -1129,6 +1129,14 @@ static int fimc_cap_qbuf(struct file *file, void *priv,
return vb2_qbuf(&fimc->vid_cap.vbq, buf);
 }
 
+static int fimc_cap_expbuf(struct file *file, void *priv,
+ struct v4l2_exportbuffer *eb)
+{
+   struct fimc_dev *fimc = video_drvdata(file);
+
+   return vb2_expbuf(&fimc->vid_cap.vbq, eb);
+}
+
 static int fimc_cap_dqbuf(struct file *file, void *priv,
   struct v4l2_buffer *buf)
 {
@@ -1253,6 +1261,7 @@ static const struct v4l2_ioctl_ops fimc_capture_ioctl_ops 
= {
 
.vidioc_qbuf= fimc_cap_qbuf,
.vidioc_dqbuf   = fimc_cap_dqbuf,
+   .vidioc_expbuf  = fimc_cap_expbuf,
 
.vidioc_prepare_buf = fimc_cap_prepare_buf,
.vidioc_create_bufs = fimc_cap_create_bufs,
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv8 25/26] v4l: s5p-tv: mixer: support for dmabuf exporting

2012-08-14 Thread Tomasz Stanislawski
This patch enhances s5p-tv with support for DMABUF exporting via
VIDIOC_EXPBUF ioctl.

Signed-off-by: Tomasz Stanislawski 
Signed-off-by: Kyungmin Park 
---
 drivers/media/video/s5p-tv/mixer_video.c |   10 ++
 1 file changed, 10 insertions(+)

diff --git a/drivers/media/video/s5p-tv/mixer_video.c 
b/drivers/media/video/s5p-tv/mixer_video.c
index a7e3b53..e5ec6bd 100644
--- a/drivers/media/video/s5p-tv/mixer_video.c
+++ b/drivers/media/video/s5p-tv/mixer_video.c
@@ -697,6 +697,15 @@ static int mxr_dqbuf(struct file *file, void *priv, struct 
v4l2_buffer *p)
return vb2_dqbuf(&layer->vb_queue, p, file->f_flags & O_NONBLOCK);
 }
 
+static int mxr_expbuf(struct file *file, void *priv,
+   struct v4l2_exportbuffer *eb)
+{
+   struct mxr_layer *layer = video_drvdata(file);
+
+   mxr_dbg(layer->mdev, "%s:%d\n", __func__, __LINE__);
+   return vb2_expbuf(&layer->vb_queue, eb);
+}
+
 static int mxr_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
 {
struct mxr_layer *layer = video_drvdata(file);
@@ -724,6 +733,7 @@ static const struct v4l2_ioctl_ops mxr_ioctl_ops = {
.vidioc_querybuf = mxr_querybuf,
.vidioc_qbuf = mxr_qbuf,
.vidioc_dqbuf = mxr_dqbuf,
+   .vidioc_expbuf = mxr_expbuf,
/* Streaming control */
.vidioc_streamon = mxr_streamon,
.vidioc_streamoff = mxr_streamoff,
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv8 26/26] v4l: s5p-mfc: support for dmabuf exporting

2012-08-14 Thread Tomasz Stanislawski
This patch enhances s5p-mfc with support for DMABUF exporting via
VIDIOC_EXPBUF ioctl.

Signed-off-by: Tomasz Stanislawski 
Signed-off-by: Kyungmin Park 
CC: Kamil Debski 
---
 drivers/media/video/s5p-mfc/s5p_mfc_dec.c |   18 ++
 drivers/media/video/s5p-mfc/s5p_mfc_enc.c |   18 ++
 2 files changed, 36 insertions(+)

diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_dec.c 
b/drivers/media/video/s5p-mfc/s5p_mfc_dec.c
index c5d567f..b375209 100644
--- a/drivers/media/video/s5p-mfc/s5p_mfc_dec.c
+++ b/drivers/media/video/s5p-mfc/s5p_mfc_dec.c
@@ -570,6 +570,23 @@ static int vidioc_dqbuf(struct file *file, void *priv, 
struct v4l2_buffer *buf)
return -EINVAL;
 }
 
+/* Export DMA buffer */
+static int vidioc_expbuf(struct file *file, void *priv,
+   struct v4l2_exportbuffer *eb)
+{
+   struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
+   int ret;
+
+   if (eb->mem_offset < DST_QUEUE_OFF_BASE)
+   return vb2_expbuf(&ctx->vq_src, eb);
+
+   eb->mem_offset -= DST_QUEUE_OFF_BASE;
+   ret = vb2_expbuf(&ctx->vq_dst, eb);
+   eb->mem_offset += DST_QUEUE_OFF_BASE;
+
+   return ret;
+}
+
 /* Stream on */
 static int vidioc_streamon(struct file *file, void *priv,
   enum v4l2_buf_type type)
@@ -745,6 +762,7 @@ static const struct v4l2_ioctl_ops s5p_mfc_dec_ioctl_ops = {
.vidioc_querybuf = vidioc_querybuf,
.vidioc_qbuf = vidioc_qbuf,
.vidioc_dqbuf = vidioc_dqbuf,
+   .vidioc_expbuf = vidioc_expbuf,
.vidioc_streamon = vidioc_streamon,
.vidioc_streamoff = vidioc_streamoff,
.vidioc_g_crop = vidioc_g_crop,
diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_enc.c 
b/drivers/media/video/s5p-mfc/s5p_mfc_enc.c
index aa1c244..df3da50 100644
--- a/drivers/media/video/s5p-mfc/s5p_mfc_enc.c
+++ b/drivers/media/video/s5p-mfc/s5p_mfc_enc.c
@@ -1142,6 +1142,23 @@ static int vidioc_dqbuf(struct file *file, void *priv, 
struct v4l2_buffer *buf)
return -EINVAL;
 }
 
+/* Export DMA buffer */
+static int vidioc_expbuf(struct file *file, void *priv,
+   struct v4l2_exportbuffer *eb)
+{
+   struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
+   int ret;
+
+   if (eb->mem_offset < DST_QUEUE_OFF_BASE)
+   return vb2_expbuf(&ctx->vq_src, eb);
+
+   eb->mem_offset -= DST_QUEUE_OFF_BASE;
+   ret = vb2_expbuf(&ctx->vq_dst, eb);
+   eb->mem_offset += DST_QUEUE_OFF_BASE;
+
+   return ret;
+}
+
 /* Stream on */
 static int vidioc_streamon(struct file *file, void *priv,
   enum v4l2_buf_type type)
@@ -1487,6 +1504,7 @@ static const struct v4l2_ioctl_ops s5p_mfc_enc_ioctl_ops 
= {
.vidioc_querybuf = vidioc_querybuf,
.vidioc_qbuf = vidioc_qbuf,
.vidioc_dqbuf = vidioc_dqbuf,
+   .vidioc_expbuf = vidioc_expbuf,
.vidioc_streamon = vidioc_streamon,
.vidioc_streamoff = vidioc_streamoff,
.vidioc_s_parm = vidioc_s_parm,
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv8 17/26] Documentation: media: description of DMABUF exporting in V4L2

2012-08-14 Thread Tomasz Stanislawski
This patch adds description and usage examples for exporting
DMABUF file descriptor in V4L2.

Signed-off-by: Tomasz Stanislawski 
Signed-off-by: Kyungmin Park 
CC: linux-...@vger.kernel.org
---
 Documentation/DocBook/media/v4l/compat.xml|3 +
 Documentation/DocBook/media/v4l/io.xml|3 +
 Documentation/DocBook/media/v4l/v4l2.xml  |1 +
 Documentation/DocBook/media/v4l/vidioc-expbuf.xml |  223 +
 4 files changed, 230 insertions(+)
 create mode 100644 Documentation/DocBook/media/v4l/vidioc-expbuf.xml

diff --git a/Documentation/DocBook/media/v4l/compat.xml 
b/Documentation/DocBook/media/v4l/compat.xml
index ff45330..802c1ab 100644
--- a/Documentation/DocBook/media/v4l/compat.xml
+++ b/Documentation/DocBook/media/v4l/compat.xml
@@ -2609,6 +2609,9 @@ ioctls.
  Importing DMABUF file descriptors as a new IO method described
  in .
 
+
+ Exporting DMABUF files using &VIDIOC-EXPBUF; ioctl.
+
   
 
 
diff --git a/Documentation/DocBook/media/v4l/io.xml 
b/Documentation/DocBook/media/v4l/io.xml
index 98253ee..c27e59b 100644
--- a/Documentation/DocBook/media/v4l/io.xml
+++ b/Documentation/DocBook/media/v4l/io.xml
@@ -488,6 +488,9 @@ buffer from userspace using a file descriptor previously 
exported for a
 different or the same device (known as the importer role), or both. This
 section describes the DMABUF importer role API in V4L2.
 
+Refer to  DMABUF exporting  for
+details about exporting a V4L2 buffers as DMABUF file descriptors.
+
 Input and output devices support the streaming I/O method when the
 V4L2_CAP_STREAMING flag in the
 capabilities field of &v4l2-capability; returned by
diff --git a/Documentation/DocBook/media/v4l/v4l2.xml 
b/Documentation/DocBook/media/v4l/v4l2.xml
index 0292ed1..874c085 100644
--- a/Documentation/DocBook/media/v4l/v4l2.xml
+++ b/Documentation/DocBook/media/v4l/v4l2.xml
@@ -568,6 +568,7 @@ and discussions on the V4L mailing list.
 &sub-overlay;
 &sub-prepare-buf;
 &sub-qbuf;
+&sub-expbuf;
 &sub-querybuf;
 &sub-querycap;
 &sub-queryctrl;
diff --git a/Documentation/DocBook/media/v4l/vidioc-expbuf.xml 
b/Documentation/DocBook/media/v4l/vidioc-expbuf.xml
new file mode 100644
index 000..30ebf67
--- /dev/null
+++ b/Documentation/DocBook/media/v4l/vidioc-expbuf.xml
@@ -0,0 +1,223 @@
+
+
+  
+ioctl VIDIOC_EXPBUF
+&manvol;
+  
+
+  
+VIDIOC_EXPBUF
+Export a buffer as a DMABUF file descriptor.
+  
+
+  
+
+  
+   int ioctl
+   int fd
+   int request
+   struct v4l2_exportbuffer 
*argp
+  
+
+  
+
+  
+Arguments
+
+
+  
+   fd
+   
+ &fd;
+   
+  
+  
+   request
+   
+ VIDIOC_EXPBUF
+   
+  
+  
+   argp
+   
+ 
+   
+  
+
+  
+
+  
+Description
+
+
+  Experimental
+  This is an  experimental 
+  interface and may change in the future.
+
+
+This ioctl is an extension to the memory
+mapping I/O method therefore it is available only for
+V4L2_MEMORY_MMAP buffers.  It can be used to export a
+buffer as DMABUF file at any time after buffers have been allocated with the
+&VIDIOC-REQBUFS; ioctl.
+
+Prior to exporting an application calls VIDIOC_QUERYBUF to obtain memory offsets. When
+using the multi-planar API every plane has
+own offset.
+
+To export a buffer, the application fills &v4l2-exportbuffer;.  The
+ mem_offset  field is set to the offset obtained
+from  VIDIOC_QUERYBUF .  Additional flags may be posted in
+the  flags  field.  Refer to manual for open syscall
+for details. Currently only O_CLOEXEC is guaranteed to be supported.  All other
+fields must be set to zero.  In a case of multi-planar API, every plane is
+exported separately using multiple  VIDIOC_EXPBUF 
+calls.
+
+ After calling VIDIOC_EXPBUF the  fd
+ field will be set by a driver.  This is a DMABUF file
+descriptor. The application may pass it to other API. Refer to DMABUF importing for details about importing DMABUF
+files into V4L2 nodes. A developer is encouraged to close a DMABUF file when it
+is no longer used.  
+
+  
+  
+   
+  Examples
+
+  
+   Exporting a buffer.
+   
+int buffer_export(int v4lfd, &v4l2-buf-type; bt, int index, int *dmafd)
+{
+   &v4l2-buffer; buf;
+   &v4l2-exportbuffer; expbuf;
+
+   memset(&buf, 0, sizeof buf);
+   buf.type = bt;
+   buf.memory = V4L2_MEMORY_MMAP;
+   buf.index = index;
+
+   if (ioctl (v4lfd, &VIDIOC-QUERYBUF;, &buf) == -1) {
+   perror ("VIDIOC_QUERYBUF");
+   return -1;
+   }
+
+   memset(&expbuf, 0, sizeof expbuf);
+   expbuf.mem_offset = buf.m.offset;
+   if (ioctl (v4lfd, &VIDIOC-EXPBUF;, &expbuf) == -1) {
+   perror ("VIDIOC_EXPBUF");
+   return -1;

Re: [PATCHv8 20/26] v4l: vb2-dma-contig: add support for DMABUF exporting

2012-08-21 Thread Tomasz Stanislawski
Hi Laurent,
Thank you for your comments.

On 08/21/2012 12:03 PM, Laurent Pinchart wrote:
> Hi Tomasz,
> 
> Thanks for the patch.
> 
> Just a couple of small comments below.
> 
> On Tuesday 14 August 2012 17:34:50 Tomasz Stanislawski wrote:
>> This patch adds support for exporting a dma-contig buffer using
>> DMABUF interface.
>>
>> Signed-off-by: Tomasz Stanislawski 
>> Signed-off-by: Kyungmin Park 
>> ---
>>  drivers/media/video/videobuf2-dma-contig.c |  204 +
>>  1 file changed, 204 insertions(+)
>>
>> diff --git a/drivers/media/video/videobuf2-dma-contig.c
>> b/drivers/media/video/videobuf2-dma-contig.c index 7fc71a0..bb2b4ac8 100644
>> --- a/drivers/media/video/videobuf2-dma-contig.c
>> +++ b/drivers/media/video/videobuf2-dma-contig.c
> 
> [snip]
> 
>> +static struct sg_table *vb2_dc_dmabuf_ops_map(
>> +struct dma_buf_attachment *db_attach, enum dma_data_direction dir)
>> +{
>> +struct vb2_dc_attachment *attach = db_attach->priv;
>> +/* stealing dmabuf mutex to serialize map/unmap operations */
> 
> Why isn't this operation serialized by the dma-buf core itself ?
> 

Indeed, it is a very good question. The lock was introduced in RFCv3 of
DMABUF patches. It was dedicated to serialize attach/detach calls.
No requirements for map/unmap serialization were stated so serialization
was delegated to an exporter.

A deadlock could occur if dma_map_attachment is called from inside
of attach ops. IMO, such an operation is invalid because an attachment
list is not in a valid state while attach ops is being processed.

Do you think that stealing a lock from dma-buf internals is too hacky?
I prefer not to introduce any extra locks in dma-contig allocator
but it is not a big deal to add it.

>> +struct mutex *lock = &db_attach->dmabuf->lock;
>> +struct sg_table *sgt;
>> +int ret;
>> +
>> +mutex_lock(lock);
>> +
>> +sgt = &attach->sgt;
>> +/* return previously mapped sg table */
>> +if (attach->dir == dir) {
>> +mutex_unlock(lock);
>> +return sgt;
>> +}
>> +
>> +/* release any previous cache */
>> +if (attach->dir != DMA_NONE) {
>> +dma_unmap_sg(db_attach->dev, sgt->sgl, sgt->orig_nents,
>> +attach->dir);
>> +attach->dir = DMA_NONE;
>> +}
>> +
>> +/* mapping to the client with new direction */
>> +ret = dma_map_sg(db_attach->dev, sgt->sgl, sgt->orig_nents, dir);
>> +if (ret <= 0) {
>> +pr_err("failed to map scatterlist\n");
>> +mutex_unlock(lock);
>> +return ERR_PTR(-EIO);
>> +}
>> +
>> +attach->dir = dir;
>> +
>> +mutex_unlock(lock);
>> +
>> +return sgt;
>> +}
> 
> [snip]
> 
>> +static int vb2_dc_dmabuf_ops_mmap(struct dma_buf *dbuf,
>> +struct vm_area_struct *vma)
>> +{
>> +/* Dummy support for mmap */
>> +return -ENOTTY;
> 
> What about calling the dma-contig mmap handler here ? Is there a specific 
> reason why you haven't implemented mmap support for dmabuf ?
> 

The mmap ops is mandatory in the latest DMABUF api.
I added a stub function to make DC work with DMABUF without any big effort.
Calling vb2_dc_mmap from mmap ops seams to be a simple and safe way to
handle mmap functionality.  Thank you for spotting this :)

>> +}
>> +
>> +static struct dma_buf_ops vb2_dc_dmabuf_ops = {
>> +.attach = vb2_dc_dmabuf_ops_attach,
>> +.detach = vb2_dc_dmabuf_ops_detach,
>> +.map_dma_buf = vb2_dc_dmabuf_ops_map,
>> +.unmap_dma_buf = vb2_dc_dmabuf_ops_unmap,
>> +.kmap = vb2_dc_dmabuf_ops_kmap,
>> +.kmap_atomic = vb2_dc_dmabuf_ops_kmap,
>> +.vmap = vb2_dc_dmabuf_ops_vmap,
>> +.mmap = vb2_dc_dmabuf_ops_mmap,
>> +.release = vb2_dc_dmabuf_ops_release,
>> +};
>> +
>> +static struct sg_table *vb2_dc_get_base_sgt(struct vb2_dc_buf *buf)
>> +{
>> +int ret;
>> +struct sg_table *sgt;
>> +
>> +sgt = kmalloc(sizeof(*sgt), GFP_KERNEL);
>> +if (!sgt) {
>> +dev_err(buf->dev, "failed to alloc sg table\n");
>> +return ERR_PTR(-ENOMEM);
>> +}
>> +
>> +ret = dma_get_sgtable(buf->dev, sgt, buf->vaddr, buf->dma_addr,
>> +buf->size);
>> +if (ret < 0) {
>> +dev_err(buf->dev, "failed to get scatterlist from DMA API\n");
>> +  

Re: [PATCHv8 01/26] v4l: Add DMABUF as a memory type

2012-08-22 Thread Tomasz Stanislawski
Hi Hans,
Thank your for the review.
Please refer to the comments below.

On 08/22/2012 12:27 PM, Hans Verkuil wrote:
> On Tue August 14 2012 17:34:31 Tomasz Stanislawski wrote:
>> From: Sumit Semwal 
>>
>> Adds DMABUF memory type to v4l framework. Also adds the related file
>> descriptor in v4l2_plane and v4l2_buffer.
>>
>> Signed-off-by: Tomasz Stanislawski 
>>[original work in the PoC for buffer sharing]
>> Signed-off-by: Sumit Semwal 
>> Signed-off-by: Sumit Semwal 
>> Acked-by: Laurent Pinchart 
>> ---
>>  drivers/media/video/v4l2-compat-ioctl32.c |   18 ++
>>  drivers/media/video/v4l2-ioctl.c  |1 +
>>  include/linux/videodev2.h |7 +++
>>  3 files changed, 26 insertions(+)
>>
>> diff --git a/drivers/media/video/v4l2-compat-ioctl32.c 
>> b/drivers/media/video/v4l2-compat-ioctl32.c
>> index 9ebd5c5..a2e0549 100644
>> --- a/drivers/media/video/v4l2-compat-ioctl32.c
>> +++ b/drivers/media/video/v4l2-compat-ioctl32.c
>> @@ -304,6 +304,7 @@ struct v4l2_plane32 {
>>  union {
>>  __u32   mem_offset;
>>  compat_long_t   userptr;
>> +__u32   fd;
> 
> Shouldn't this be int?
> 

Notice that this field should be consistent with fd field used in
'struct v4l2_exportbuffer'. Therefore I prefer to use fixed-size types.
One could use __s32 here but notice that file descriptors are defined
as small, nonnegative integers according to POSIX spec. The type __u32
suits well for this purpose. The negative values returned by open
syscall are used only to indicate failures.

On the other hand, using __s32 may help to avoid compiler warning while
building userspace apps due to 'signed-vs-unsigned comparisons'.

However, I do not have any strong opinion about 'int vs __u32' issue :).
Do you think that using __s32 for both QUERYBUF and EXPBUF is a good
compromise?

>>  } m;
>>  __u32   data_offset;
>>  __u32   reserved[11];
>> @@ -325,6 +326,7 @@ struct v4l2_buffer32 {
>>  __u32   offset;
>>  compat_long_t   userptr;
>>  compat_caddr_t  planes;
>> +__u32   fd;
> 
> Ditto.
> 
>>  } m;
>>  __u32   length;
>>  __u32   reserved2;

> Regards,
> 
>   Hans
> 

Regards,

Tomasz
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] [media] s5p-tv: Fix potential NULL pointer dereference error

2012-09-24 Thread Tomasz Stanislawski
On 09/22/2012 09:39 AM, Sachin Kamat wrote:
> When mdev is NULL, the error print statement will try to dereference
> the NULL pointer.
> 
> Signed-off-by: Sachin Kamat 
> ---
>  drivers/media/platform/s5p-tv/mixer_drv.c |2 +-
>  1 files changed, 1 insertions(+), 1 deletions(-)
> 
> diff --git a/drivers/media/platform/s5p-tv/mixer_drv.c 
> b/drivers/media/platform/s5p-tv/mixer_drv.c
> index a15ca05..ca0f297 100644
> --- a/drivers/media/platform/s5p-tv/mixer_drv.c
> +++ b/drivers/media/platform/s5p-tv/mixer_drv.c
> @@ -384,7 +384,7 @@ static int __devinit mxr_probe(struct platform_device 
> *pdev)
>  
>   mdev = kzalloc(sizeof *mdev, GFP_KERNEL);
>   if (!mdev) {
> - mxr_err(mdev, "not enough memory.\n");
> + dev_err(dev, "not enough memory.\n");
>   ret = -ENOMEM;
>   goto fail;
>   }
> 

Acked-by: Tomasz Stanislawski 
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2] drivers/media/platform/s5p-tv/sdo_drv.c: fix error return code

2012-09-24 Thread Tomasz Stanislawski
Hi.

On 09/06/2012 10:38 AM, Peter Senna Tschudin wrote:
> From: Peter Senna Tschudin 
> 
> Convert a nonnegative error return code to a negative one, as returned
> elsewhere in the function.
> 
> A simplified version of the semantic match that finds this problem is as
> follows: (http://coccinelle.lip6.fr/)
> 
> // 
> (
> if@p1 (\(ret < 0\|ret != 0\))
>  { ... return ret; }
> |
> ret@p1 = 0
> )
> ... when != ret = e1
> when != &ret
> *if(...)
> {
>   ... when != ret = e2
>   when forall
>  return ret;
> }
> 
> // 
> 
> Signed-off-by: Peter Senna Tschudin 

Acked-by: Tomasz Stanislawski 

> 
> ---
>  drivers/media/platform/s5p-tv/sdo_drv.c |3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/drivers/media/platform/s5p-tv/sdo_drv.c 
> b/drivers/media/platform/s5p-tv/sdo_drv.c
> index ad68bbe..58cf56d 100644
> --- a/drivers/media/platform/s5p-tv/sdo_drv.c
> +++ b/drivers/media/platform/s5p-tv/sdo_drv.c
> @@ -369,6 +369,7 @@ static int __devinit sdo_probe(struct platform_device 
> *pdev)
>   sdev->fout_vpll = clk_get(dev, "fout_vpll");
>   if (IS_ERR_OR_NULL(sdev->fout_vpll)) {
>   dev_err(dev, "failed to get clock 'fout_vpll'\n");
> + ret = -ENXIO;
>   goto fail_dacphy;
>   }
>   dev_info(dev, "fout_vpll.rate = %lu\n", clk_get_rate(sclk_vpll));
> @@ -377,11 +378,13 @@ static int __devinit sdo_probe(struct platform_device 
> *pdev)
>   sdev->vdac = devm_regulator_get(dev, "vdd33a_dac");
>   if (IS_ERR_OR_NULL(sdev->vdac)) {
>   dev_err(dev, "failed to get regulator 'vdac'\n");
> + ret = -ENXIO;
>   goto fail_fout_vpll;
>   }
>   sdev->vdet = devm_regulator_get(dev, "vdet");
>   if (IS_ERR_OR_NULL(sdev->vdet)) {
>   dev_err(dev, "failed to get regulator 'vdet'\n");
> + ret = -ENXIO;
>   goto fail_fout_vpll;
>   }
>  
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCHv8 02/26] Documentation: media: description of DMABUF importing in V4L2

2012-09-24 Thread Tomasz Stanislawski
Hi Hans,
Thank you for review.

On 08/22/2012 12:47 PM, Hans Verkuil wrote:
> On Tue August 14 2012 17:34:32 Tomasz Stanislawski wrote:
>> This patch adds description and usage examples for importing
>> DMABUF file descriptor in V4L2.
>>
>> Signed-off-by: Tomasz Stanislawski 
>> Signed-off-by: Kyungmin Park 
>> CC: linux-...@vger.kernel.org
>> ---
>>  Documentation/DocBook/media/v4l/compat.xml |4 +
>>  Documentation/DocBook/media/v4l/io.xml |  180 
>> 
>>  .../DocBook/media/v4l/vidioc-create-bufs.xml   |3 +-
>>  Documentation/DocBook/media/v4l/vidioc-qbuf.xml|   15 ++
>>  Documentation/DocBook/media/v4l/vidioc-reqbufs.xml |   47 ++---
>>  5 files changed, 226 insertions(+), 23 deletions(-)
>>

[snip]

>> +&v4l2-plane; in the multi-planar API case).  The driver must be switched 
>> into
>> +DMABUF I/O mode by calling the &VIDIOC-REQBUFS; with the desired buffer 
>> type.
>> +No buffers (planes) are allocated beforehand, consequently they are not 
>> indexed
>> +and cannot be queried like mapped buffers with the
>> +VIDIOC_QUERYBUF ioctl.
> 
> I disagree with that. Userptr buffers can use QUERYBUF just fine. Even for the
> userptr you still have to fill in the buffer index when calling QBUF.
> 
> So I see no reason why you couldn't use QUERYBUF in the DMABUF case. The only
> difference is that the fd field is undefined (set to -1 perhaps?) if the 
> bufffer
> isn't queued.
> 
> QUERYBUF can be very useful for debugging, for example to see what the status
> is of each buffer and how many are queued.
> 

Ok. I agree that QUERYBUF can be useful for debugging. The value of fd field
should be the last value passed using QBUF. It would simplify streaming
because an application would not have to keep the file descriptor around.

>> +
>> +
>> +  Initiating streaming I/O with DMABUF file descriptors
>> +
>> +  
>> +&v4l2-requestbuffers; reqbuf;
>> +
>> +memset (&reqbuf, 0, sizeof (reqbuf));
>> +reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
>> +reqbuf.memory = V4L2_MEMORY_DMABUF;
>> +reqbuf.count = 1;
>> +
>> +if (ioctl (fd, &VIDIOC-REQBUFS;, &reqbuf) == -1) {
>> +if (errno == EINVAL)
>> +printf ("Video capturing or DMABUF streaming is not 
>> supported\n");
>> +else
>> +perror ("VIDIOC_REQBUFS");
>> +
>> +exit (EXIT_FAILURE);
> 
> Let's stick to the kernel coding style, so no ' ' before '(' in function 
> calls.
> Same for the other program examples below.
> 

The ' ' before function was used for userptr and mmap usage examples.
These examples should be fixed too.

>> +}
>> +  
>> +
>> +
>> +Buffer (plane) file descriptor is passed on the fly with the
> 
> s/Buffer/The buffer/
> 
>> +&VIDIOC-QBUF; ioctl. In case of multiplanar buffers, every plane can be
> 
> 'Can be', 'should be' or 'must be'? Does it ever make sense to have the same
> fd for different planes? Do we have restrictions on this in the userptr case?
> 

I think that we should keep to 'can be'. I see no good reason to
prevent the same dmabuf to be used for different planes.
Allowing reusing of dmabufs with assistance of data_offset field
would allow to pass a 2-planar YUV420 from V4L2-single-plane API
to a driver with V4L2-multi-plane API.

[snip]

>> diff --git a/Documentation/DocBook/media/v4l/vidioc-qbuf.xml 
>> b/Documentation/DocBook/media/v4l/vidioc-qbuf.xml
>> index 77ff5be..436d21c 100644
>> --- a/Documentation/DocBook/media/v4l/vidioc-qbuf.xml
>> +++ b/Documentation/DocBook/media/v4l/vidioc-qbuf.xml
>> @@ -109,6 +109,21 @@ they cannot be swapped out to disk. Buffers remain 
>> locked until
>>  dequeued, until the &VIDIOC-STREAMOFF; or &VIDIOC-REQBUFS; ioctl is
>>  called, or until the device is closed.
>>  
>> +To enqueue a DMABUF buffer 
>> applications
>> +set the memory field to
>> +V4L2_MEMORY_DMABUF and the 
>> m.fd
>> +field to a file descriptor associated with a DMABUF buffer. When the
>> +multi-planar API is used m.fd of the passed 
>> array of
> 
> multi-planar API is used the m.fd fields of the 
> passed array of
> 
>> +&v4l2-plane; have to be used instead. When VIDIOC_QBUF 
>> is
>> +called with a pointer to this structure the driver sets the
>> +V4L2_BUF_FLAG_QUEUED flag and clears the
>> +V4L2_BUF_FLAG_MAPPED and
>> +V4L2_BUF_FLAG_DONE flags in the
>> +f

Re: [PATCHv8 13/26] v4l: vivi: support for dmabuf importing

2012-09-25 Thread Tomasz Stanislawski
On 08/22/2012 01:47 PM, Hans Verkuil wrote:
> On Wed August 22 2012 12:56:30 Hans Verkuil wrote:
>> On Tue August 14 2012 17:34:43 Tomasz Stanislawski wrote:
>>> This patch enhances VIVI driver with a support for importing a buffer
>>> from DMABUF file descriptors.
>>
>> Thanks for adding DMABUF support to vivi.
>>
>> What would be great is if DMABUF support is also added to mem2mem_testdev.
>> It would make an excellent test case to take the vivi output, pass it
>> through mem2mem_testdev, and finally output the image using the gpu, all
>> using dmabuf.
>>
>> It's also very useful for application developers to test dmabuf support
>> without requiring special hardware (other than a dmabuf-enabled gpu
>> driver).
> 
> Adding VIDIOC_EXPBUF support to vivi and mem2mem_testdev would be
> welcome as well for the same reasons.
> 
> Regards,
> 
>   Hans
> 

Hi Hans,

Adding DMABUF exporting to vmalloc is not easy as it seams.
Exporting introduces a new level of complexity and code bloat to a framework.
I mean support for:
- NULL devices as DMABUF exporters
- vmalloc to sglist conversions
- calling dma_map_sg for importers
- cache management

I admit that most of the work should be delegated to dmabuf framework.
I propose to postpone support for dmabuf exporting in vmalloc until
vb2-dmabuf gets merged.

Regards,
Tomasz Stanislawski


>>
>> Regards,
>>
>>  Hans
>>
>>>
>>> Signed-off-by: Tomasz Stanislawski 
>>> Signed-off-by: Kyungmin Park 
>>> ---
>>>  drivers/media/video/Kconfig |1 +
>>>  drivers/media/video/vivi.c  |2 +-
>>>  2 files changed, 2 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
>>> index 966954d..8fa81be 100644
>>> --- a/drivers/media/video/Kconfig
>>> +++ b/drivers/media/video/Kconfig
>>> @@ -653,6 +653,7 @@ config VIDEO_VIVI
>>> depends on FRAMEBUFFER_CONSOLE || STI_CONSOLE
>>> select FONT_8x16
>>> select VIDEOBUF2_VMALLOC
>>> +   select DMA_SHARED_BUFFER
>>> default n
>>> ---help---
>>>   Enables a virtual video driver. This device shows a color bar
>>> diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c
>>> index a6351c4..37d8fd4 100644
>>> --- a/drivers/media/video/vivi.c
>>> +++ b/drivers/media/video/vivi.c
>>> @@ -1308,7 +1308,7 @@ static int __init vivi_create_instance(int inst)
>>> q = &dev->vb_vidq;
>>> memset(q, 0, sizeof(dev->vb_vidq));
>>> q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
>>> -   q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ;
>>> +   q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF | VB2_READ;
>>> q->drv_priv = dev;
>>> q->buf_struct_size = sizeof(struct vivi_buffer);
>>> q->ops = &vivi_video_qops;
>>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-media" in
>> the body of a message to majord...@vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCHv8 18/26] v4l: add buffer exporting via dmabuf

2012-09-25 Thread Tomasz Stanislawski
Hi Hans,
Thank you for review.
Please refer to the comments below.

On 08/22/2012 01:41 PM, Hans Verkuil wrote:
> On Tue August 14 2012 17:34:48 Tomasz Stanislawski wrote:
>> This patch adds extension to V4L2 api. It allow to export a mmap buffer as 
>> file
>> descriptor. New ioctl VIDIOC_EXPBUF is added. It takes a buffer offset used 
>> by
>> mmap and return a file descriptor on success.
>>
>> Signed-off-by: Tomasz Stanislawski 
>> Signed-off-by: Kyungmin Park 
>> ---
>>  drivers/media/video/v4l2-compat-ioctl32.c |1 +
>>  drivers/media/video/v4l2-dev.c|1 +
>>  drivers/media/video/v4l2-ioctl.c  |   15 +++
>>  include/linux/videodev2.h |   26 ++
>>  include/media/v4l2-ioctl.h|2 ++
>>  5 files changed, 45 insertions(+)
>>

[snip]

>> diff --git a/drivers/media/video/v4l2-ioctl.c 
>> b/drivers/media/video/v4l2-ioctl.c
>> index dffd3c9..c4e8c7e 100644
>> --- a/drivers/media/video/v4l2-ioctl.c
>> +++ b/drivers/media/video/v4l2-ioctl.c
>> @@ -458,6 +458,14 @@ static void v4l_print_buffer(const void *arg, bool 
>> write_only)
>>  tc->type, tc->flags, tc->frames, *(__u32 
>> *)tc->userbits);
>>  }
>>  
>> +static void v4l_print_exportbuffer(const void *arg, bool write_only)
>> +{
>> +const struct v4l2_exportbuffer *p = arg;
>> +
>> +pr_cont("fd=%d, mem_offset=%lx, flags=%lx\n",
>> +p->fd, (unsigned long)p->mem_offset, (unsigned long)p->flags);
> 
> Why the unsigned long casts?
> 

It is needed to avoid compiler warnings on machines where "%lx" is not
compatible with u32.

>> +}
>> +
>>  static void v4l_print_create_buffers(const void *arg, bool write_only)
>>  {
>>  const struct v4l2_create_buffers *p = arg;

[snip]

>> diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
>> index 7f918dc..b5d058b 100644
>> --- a/include/linux/videodev2.h
>> +++ b/include/linux/videodev2.h
>> @@ -688,6 +688,31 @@ struct v4l2_buffer {
>>  #define V4L2_BUF_FLAG_NO_CACHE_INVALIDATE   0x0800
>>  #define V4L2_BUF_FLAG_NO_CACHE_CLEAN0x1000
>>  
>> +/**
>> + * struct v4l2_exportbuffer - export of video buffer as DMABUF file 
>> descriptor
>> + *
>> + * @fd: file descriptor associated with DMABUF (set by driver)
>> + * @mem_offset: buffer memory offset as returned by VIDIOC_QUERYBUF in 
>> struct
>> + *  v4l2_buffer::m.offset (for single-plane formats) or
>> + *  v4l2_plane::m.offset (for multi-planar formats)
>> + * @flags:  flags for newly created file, currently only O_CLOEXEC is
>> + *  supported, refer to manual of open syscall for more details
>> + *
>> + * Contains data used for exporting a video buffer as DMABUF file 
>> descriptor.
>> + * The buffer is identified by a 'cookie' returned by VIDIOC_QUERYBUF
>> + * (identical to the cookie used to mmap() the buffer to userspace). All
>> + * reserved fields must be set to zero. The field reserved0 is expected to
>> + * become a structure 'type' allowing an alternative layout of the structure
>> + * content. Therefore this field should not be used for any other 
>> extensions.
>> + */
>> +struct v4l2_exportbuffer {
>> +__u32   fd;
>> +__u32   reserved0;
>> +__u32   mem_offset;
>> +__u32   flags;
>> +__u32   reserved[12];
>> +};
> 
> OK, I realized that we also need a type field here: you need the type field
> (same as in v4l2_buffer) to know which queue the mem_offset refers to. For
> M2M devices you have two queues, so you need this information.

I do not agree with you. The mmap() does not need buffer_type.
So VIDIOC_EXPBUF should not need the field either.
Please refer to patch "[PATCHv8 26/26] v4l: s5p-mfc: support for dmabuf 
exporting"
for example how to deal without buffer_type.

> 
> Is there any reason not to use __u32 memory instead of __u32 reserved0?
> I really dislike 'reserved0'. It's also very inconsistent with the other
> buffer ioctls which all have type+memory fields.

The type is not needed for exporting if mem_offset is available like in mmap() 
case.
The memory is not needed because exporting is available only for MMAP buffers.

I see two ways to describe a buffer for exporting:
a) by mem_offset
b) by (buffer_type, index, plane_index) tuple

For know I prefer to implement only method (a) to avoid
"single vs. multi plane" m

Re: [PATCHv8 18/26] v4l: add buffer exporting via dmabuf

2012-09-26 Thread Tomasz Stanislawski
Hi Hans,
Thank your for your comments.

On 09/26/2012 08:39 AM, Hans Verkuil wrote:
> On Tue September 25 2012 18:30:43 Tomasz Stanislawski wrote:
>> Hi Hans,
>> Thank you for review.
>> Please refer to the comments below.
>>
>> On 08/22/2012 01:41 PM, Hans Verkuil wrote:
>>> On Tue August 14 2012 17:34:48 Tomasz Stanislawski wrote:
>>>> This patch adds extension to V4L2 api. It allow to export a mmap buffer as 
>>>> file
>>>> descriptor. New ioctl VIDIOC_EXPBUF is added. It takes a buffer offset 
>>>> used by
>>>> mmap and return a file descriptor on success.
>>>>
>>>> Signed-off-by: Tomasz Stanislawski 
>>>> Signed-off-by: Kyungmin Park 
>>>> ---
>>>>  drivers/media/video/v4l2-compat-ioctl32.c |1 +
>>>>  drivers/media/video/v4l2-dev.c|1 +
>>>>  drivers/media/video/v4l2-ioctl.c  |   15 +++
>>>>  include/linux/videodev2.h |   26 
>>>> ++
>>>>  include/media/v4l2-ioctl.h|2 ++
>>>>  5 files changed, 45 insertions(+)
>>>>
>>
>> [snip]
>>
>>>> diff --git a/drivers/media/video/v4l2-ioctl.c 
>>>> b/drivers/media/video/v4l2-ioctl.c
>>>> index dffd3c9..c4e8c7e 100644
>>>> --- a/drivers/media/video/v4l2-ioctl.c
>>>> +++ b/drivers/media/video/v4l2-ioctl.c
>>>> @@ -458,6 +458,14 @@ static void v4l_print_buffer(const void *arg, bool 
>>>> write_only)
>>>>tc->type, tc->flags, tc->frames, *(__u32 
>>>> *)tc->userbits);
>>>>  }
>>>>  
>>>> +static void v4l_print_exportbuffer(const void *arg, bool write_only)
>>>> +{
>>>> +  const struct v4l2_exportbuffer *p = arg;
>>>> +
>>>> +  pr_cont("fd=%d, mem_offset=%lx, flags=%lx\n",
>>>> +  p->fd, (unsigned long)p->mem_offset, (unsigned long)p->flags);
>>>
>>> Why the unsigned long casts?
>>>
>>
>> It is needed to avoid compiler warnings on machines where "%lx" is not
>> compatible with u32.
> 
> Why not use %x instead of %lx?
> 

Ok. '%x' or '%08x' should be compatible with u32.
Hopefully, no one is using V4L2 on 16-bit machines :).

>>>> +}
>>>> +
>>>>  static void v4l_print_create_buffers(const void *arg, bool write_only)
>>>>  {
>>>>const struct v4l2_create_buffers *p = arg;
>>
>> [snip]
>>
>>>> diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
>>>> index 7f918dc..b5d058b 100644
>>>> --- a/include/linux/videodev2.h
>>>> +++ b/include/linux/videodev2.h
>>>> @@ -688,6 +688,31 @@ struct v4l2_buffer {
>>>>  #define V4L2_BUF_FLAG_NO_CACHE_INVALIDATE 0x0800
>>>>  #define V4L2_BUF_FLAG_NO_CACHE_CLEAN  0x1000
>>>>  
>>>> +/**
>>>> + * struct v4l2_exportbuffer - export of video buffer as DMABUF file 
>>>> descriptor
>>>> + *
>>>> + * @fd:   file descriptor associated with DMABUF (set by driver)
>>>> + * @mem_offset:   buffer memory offset as returned by VIDIOC_QUERYBUF in 
>>>> struct
>>>> + *v4l2_buffer::m.offset (for single-plane formats) or
>>>> + *v4l2_plane::m.offset (for multi-planar formats)
>>>> + * @flags:flags for newly created file, currently only O_CLOEXEC 
>>>> is
>>>> + *supported, refer to manual of open syscall for more 
>>>> details
>>>> + *
>>>> + * Contains data used for exporting a video buffer as DMABUF file 
>>>> descriptor.
>>>> + * The buffer is identified by a 'cookie' returned by VIDIOC_QUERYBUF
>>>> + * (identical to the cookie used to mmap() the buffer to userspace). All
>>>> + * reserved fields must be set to zero. The field reserved0 is expected to
>>>> + * become a structure 'type' allowing an alternative layout of the 
>>>> structure
>>>> + * content. Therefore this field should not be used for any other 
>>>> extensions.
>>>> + */
>>>> +struct v4l2_exportbuffer {
>>>> +  __u32   fd;
>>>> +  __u32   reserved0;
>>>> +  __u32   mem_offset;
>>>> +  __u32   flags;
>>>> +  __u32   

Re: Question: interaction between selection API, ENUM_FRAMESIZES and S_FMT?

2013-07-02 Thread Tomasz Stanislawski
Hi Hans,
Maybe it is a good time to separate configuration of a data source from
configuration of a data sink. Currently, everything is pretty mixed
for videodev API. The magic ioctl called S_FMT does to much.
As I understand it includes:
  a) setting pixelformat
  b) setting size of a buffer
  c) setting/adjusting crop rectangle previously defined using S_CROP
  d) if S_CROP is not used then S_FMT sets the framesize
 changing framesize ahs huge impact on a pipeline for capture device
  e) setting composing rectangle to the whole buffer

IMO, it would a good idea to split S_FMT into separate calls for a sink and
a source.

In case of a capture device, the source is TV grabber or sensor array.
They are controlled using S_STD for anlog TV, S_DV_TIMING for digital TV
or hypothetical S_FRAMESIZE for sensor arrays.
All mentioned medias are pretty different so they deserve dedicated ioctl.
I think it might be much better to introduce an ioctl dedicated
only for sensor arrays like {S/G}_SENSOR(_ARRAY). This ioctl would take width,
height as parameters (updating to defaults if only one resolution is supported).
All binning, skipping, etc. magic might have dedicated fields in S_SENSOR.
Introducing new selection target like SEL_TGT_FRAMESIZE or even
SEL_TGT_SOURCE is a nice abstraction but it is not need to provide HW
functionality to userspace.

In case of a capture device, the sink is a buffer. IMO, it would be nice
to have an ioctl dedicated only for configuration of buffers in memory.
Let's call it S_BUFFER. It will take width, height and pixelformat
as parameters. This ioctl would be very similar to S_FMT expect
much smaller influence on other parts of the pipeline. This call would
not change neither framesize nor cropping rectangle. There would be no
requirement that the buffer is fully filled without margins. This would
greatly simplify interactions with composing rectangle and scaling setup.

The interactions between composing rectangle and S_BUFFER are
an interesting topic. During the discussion about pipeline
configuration [1] it was mentioned that all dependencies
should be executed in to-memory order. It means that S_BUFFER
would adjust width and height to be assure that composing
rectangle fits. The same way adjusting composing rectangle will
change buffer size if necessary.

Finally S_FMT could be emulated in libv4l2 or v4l2-core as series of
of S_SELECTION and S_BUFFER calls, optionally S_STD, S_DV_TIMING or S_SENSOR
if possible. The same emulation would have to be performed for S_CROP.
The emulation would be used only to handle support for legacy applications.
All new and experimental applications must not use S_FMT or S_CROP.

I know that the changes are dramatic but fixing issues with pipeline
configuration is worth it.

What do you think about the proposed idea?

Regards,
Tomasz Stanislawski

[1] http://www.spinics.net/lists/linux-media/msg34541.html



--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCHv8 21/26] v4l: vb2-dma-contig: add reference counting for a device from allocator context

2012-09-27 Thread Tomasz Stanislawski
Hi Laurent,

On 08/15/2012 10:04 PM, Laurent Pinchart wrote:
> Hi Tomasz,
> 
> Thanks for the patch.
> 
> On Tuesday 14 August 2012 17:34:51 Tomasz Stanislawski wrote:
>> This patch adds taking reference to the device for MMAP buffers.
>>
>> Such buffers, may be exported using DMABUF mechanism. If the driver that
>> created a queue is unloaded then the queue is released, the device might be
>> released too.  However, buffers cannot be released if they are referenced by
>> DMABUF descriptor(s). The device pointer kept in a buffer must be valid for
>> the whole buffer's lifetime. Therefore MMAP buffers should take a reference
>> to the device to avoid risk of dangling pointers.
> 
> That patch looks good, but that approach won't scale if we ever need a more 
> complex context that can't be copied. We can ignore that for now, but if we 
> decide to support "orphan" vb2 buffers, that's an issue we need to be aware 
> of 
> as it might come back to bite us in the future.
> 

Good news is that vb2-dma-contig knows the structure of the context.
Therefore it will always be able to implement a proper 'copy constructor'.
One could always add reference counting for contexts but I consider it
little over-engineering.

> I assume that this patch requires your dmabuf owner patch to fix the orphan 
> buffer case properly.
> 

The 'dmabuf owner' patch is not required for this patchset.
It will only protect 'videobuf2-dma-contig' module from being
unloaded while its dmabuf is in use.

Regards,
Tomasz Stanislawski

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv9 00/25] Integration of videobuf2 with DMABUF

2012-10-02 Thread Tomasz Stanislawski
ma_buf)
  v4l: vb: remove warnings about MEMORY_DMABUF
  v4l: vb2-dma-contig: add support for dma_buf importing

Tomasz Stanislawski (15):
  Documentation: media: description of DMABUF importing in V4L2
  v4l: vb2-dma-contig: remove reference of alloc_ctx from a buffer
  v4l: vb2-dma-contig: add support for scatterlist in userptr mode
  v4l: vb2-vmalloc: add support for dmabuf importing
  v4l: vivi: support for dmabuf importing
  v4l: s5p-tv: mixer: support for dmabuf importing
  v4l: s5p-fimc: support for dmabuf importing
  Documentation: media: description of DMABUF exporting in V4L2
  v4l: add buffer exporting via dmabuf
  v4l: vb2: add buffer exporting via dmabuf
  v4l: vb2-dma-contig: add support for DMABUF exporting
  v4l: vb2-dma-contig: add reference counting for a device from
allocator context
  v4l: s5p-fimc: support for dmabuf exporting
  v4l: s5p-tv: mixer: support for dmabuf exporting
  v4l: s5p-mfc: support for dmabuf exporting

 Documentation/DocBook/media/v4l/compat.xml |7 +
 Documentation/DocBook/media/v4l/io.xml |  183 +-
 Documentation/DocBook/media/v4l/v4l2.xml   |1 +
 .../DocBook/media/v4l/vidioc-create-bufs.xml   |   16 +-
 Documentation/DocBook/media/v4l/vidioc-expbuf.xml  |  212 ++
 Documentation/DocBook/media/v4l/vidioc-qbuf.xml|   17 +
 Documentation/DocBook/media/v4l/vidioc-reqbufs.xml |   47 +-
 drivers/media/video/Kconfig|2 +
 drivers/media/video/s5p-fimc/fimc-capture.c|   11 +-
 drivers/media/video/s5p-mfc/s5p_mfc_dec.c  |   14 +
 drivers/media/video/s5p-mfc/s5p_mfc_enc.c  |   14 +
 drivers/media/video/s5p-tv/mixer_video.c   |   12 +-
 drivers/media/video/v4l2-compat-ioctl32.c  |   19 +
 drivers/media/video/v4l2-dev.c |1 +
 drivers/media/video/v4l2-ioctl.c   |   11 +
 drivers/media/video/videobuf-core.c|4 +
 drivers/media/video/videobuf2-core.c   |  300 -
 drivers/media/video/videobuf2-dma-contig.c |  695 ++--
 drivers/media/video/videobuf2-memops.c |   40 --
 drivers/media/video/videobuf2-vmalloc.c|   56 ++
 drivers/media/video/vivi.c |2 +-
 include/linux/videodev2.h  |   35 +
 include/media/v4l2-ioctl.h |2 +
 include/media/videobuf2-core.h |   38 ++
 include/media/videobuf2-memops.h   |5 -
 25 files changed, 1608 insertions(+), 136 deletions(-)
 create mode 100644 Documentation/DocBook/media/v4l/vidioc-expbuf.xml

-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv9 01/25] v4l: Add DMABUF as a memory type

2012-10-02 Thread Tomasz Stanislawski
From: Sumit Semwal 

Adds DMABUF memory type to v4l framework. Also adds the related file
descriptor in v4l2_plane and v4l2_buffer.

Signed-off-by: Tomasz Stanislawski 
   [original work in the PoC for buffer sharing]
Signed-off-by: Sumit Semwal 
Signed-off-by: Sumit Semwal 
Acked-by: Laurent Pinchart 
---
 drivers/media/video/v4l2-compat-ioctl32.c |   18 ++
 drivers/media/video/v4l2-ioctl.c  |1 +
 include/linux/videodev2.h |7 +++
 3 files changed, 26 insertions(+)

diff --git a/drivers/media/video/v4l2-compat-ioctl32.c 
b/drivers/media/video/v4l2-compat-ioctl32.c
index 9ebd5c5..f0b5aba 100644
--- a/drivers/media/video/v4l2-compat-ioctl32.c
+++ b/drivers/media/video/v4l2-compat-ioctl32.c
@@ -304,6 +304,7 @@ struct v4l2_plane32 {
union {
__u32   mem_offset;
compat_long_t   userptr;
+   __s32   fd;
} m;
__u32   data_offset;
__u32   reserved[11];
@@ -325,6 +326,7 @@ struct v4l2_buffer32 {
__u32   offset;
compat_long_t   userptr;
compat_caddr_t  planes;
+   __s32   fd;
} m;
__u32   length;
__u32   reserved2;
@@ -348,6 +350,9 @@ static int get_v4l2_plane32(struct v4l2_plane *up, struct 
v4l2_plane32 *up32,
up_pln = compat_ptr(p);
if (put_user((unsigned long)up_pln, &up->m.userptr))
return -EFAULT;
+   } else if (memory == V4L2_MEMORY_DMABUF) {
+   if (copy_in_user(&up->m.fd, &up32->m.fd, sizeof(int)))
+   return -EFAULT;
} else {
if (copy_in_user(&up->m.mem_offset, &up32->m.mem_offset,
sizeof(__u32)))
@@ -371,6 +376,11 @@ static int put_v4l2_plane32(struct v4l2_plane *up, struct 
v4l2_plane32 *up32,
if (copy_in_user(&up32->m.mem_offset, &up->m.mem_offset,
sizeof(__u32)))
return -EFAULT;
+   /* For DMABUF, driver might've set up the fd, so copy it back. */
+   if (memory == V4L2_MEMORY_DMABUF)
+   if (copy_in_user(&up32->m.fd, &up->m.fd,
+   sizeof(int)))
+   return -EFAULT;
 
return 0;
 }
@@ -453,6 +463,10 @@ static int get_v4l2_buffer32(struct v4l2_buffer *kp, 
struct v4l2_buffer32 __user
if (get_user(kp->m.offset, &up->m.offset))
return -EFAULT;
break;
+   case V4L2_MEMORY_DMABUF:
+   if (get_user(kp->m.fd, &up->m.fd))
+   return -EFAULT;
+   break;
}
}
 
@@ -517,6 +531,10 @@ static int put_v4l2_buffer32(struct v4l2_buffer *kp, 
struct v4l2_buffer32 __user
if (put_user(kp->m.offset, &up->m.offset))
return -EFAULT;
break;
+   case V4L2_MEMORY_DMABUF:
+   if (put_user(kp->m.fd, &up->m.fd))
+   return -EFAULT;
+   break;
}
}
 
diff --git a/drivers/media/video/v4l2-ioctl.c b/drivers/media/video/v4l2-ioctl.c
index 6bc47fc..dffd3c9 100644
--- a/drivers/media/video/v4l2-ioctl.c
+++ b/drivers/media/video/v4l2-ioctl.c
@@ -155,6 +155,7 @@ static const char *v4l2_memory_names[] = {
[V4L2_MEMORY_MMAP]= "mmap",
[V4L2_MEMORY_USERPTR] = "userptr",
[V4L2_MEMORY_OVERLAY] = "overlay",
+   [V4L2_MEMORY_DMABUF] = "dmabuf",
 };
 
 #define prt_names(a, arr) a) >= 0) && ((a) < ARRAY_SIZE(arr))) ? \
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index 7a147c8..e04a73e 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -186,6 +186,7 @@ enum v4l2_memory {
V4L2_MEMORY_MMAP = 1,
V4L2_MEMORY_USERPTR  = 2,
V4L2_MEMORY_OVERLAY  = 3,
+   V4L2_MEMORY_DMABUF   = 4,
 };
 
 /* see also http://vektor.theorem.ca/graphics/ycbcr/ */
@@ -596,6 +597,8 @@ struct v4l2_requestbuffers {
  * should be passed to mmap() called on the video node)
  * @userptr:   when memory is V4L2_MEMORY_USERPTR, a userspace pointer
  * pointing to this plane
+ * @fd:when memory is V4L2_MEMORY_DMABUF, a userspace 
file
+ * descriptor associated with this plane
  * @data_offset:   offset in the plane to the start of data; usually 0,
  * unless there is a header in

[PATCHv9 02/25] Documentation: media: description of DMABUF importing in V4L2

2012-10-02 Thread Tomasz Stanislawski
This patch adds description and usage examples for importing
DMABUF file descriptor in V4L2.

Signed-off-by: Tomasz Stanislawski 
Signed-off-by: Kyungmin Park 
CC: linux-...@vger.kernel.org
---
 Documentation/DocBook/media/v4l/compat.xml |4 +
 Documentation/DocBook/media/v4l/io.xml |  180 +++-
 .../DocBook/media/v4l/vidioc-create-bufs.xml   |   16 +-
 Documentation/DocBook/media/v4l/vidioc-qbuf.xml|   17 ++
 Documentation/DocBook/media/v4l/vidioc-reqbufs.xml |   47 ++---
 5 files changed, 234 insertions(+), 30 deletions(-)

diff --git a/Documentation/DocBook/media/v4l/compat.xml 
b/Documentation/DocBook/media/v4l/compat.xml
index faa0fd1..a46f95b 100644
--- a/Documentation/DocBook/media/v4l/compat.xml
+++ b/Documentation/DocBook/media/v4l/compat.xml
@@ -2621,6 +2621,10 @@ ioctls.
 
  Support for frequency band enumeration: 
&VIDIOC-ENUM-FREQ-BANDS; ioctl.
 
+
+ Importing DMABUF file descriptors as a new IO method described
+ in .
+
   
 
 
diff --git a/Documentation/DocBook/media/v4l/io.xml 
b/Documentation/DocBook/media/v4l/io.xml
index 1885cc0..5b58657 100644
--- a/Documentation/DocBook/media/v4l/io.xml
+++ b/Documentation/DocBook/media/v4l/io.xml
@@ -331,7 +331,7 @@ application until one or more buffers can be dequeued. By 
default
 outgoing queue. When the O_NONBLOCK flag was
 given to the &func-open; function, VIDIOC_DQBUF
 returns immediately with an &EAGAIN; when no buffer is available. The
-&func-select; or &func-poll; function are always available.
+&func-select; or &func-poll; functions are always available.
 
 To start and stop capturing or output applications call the
 &VIDIOC-STREAMON; and &VIDIOC-STREAMOFF; ioctl. Note
@@ -472,6 +472,161 @@ rest should be evident.
   
   
 
+  
+Streaming I/O (DMA buffer importing)
+
+
+  Experimental
+  This is an  experimental 
+  interface and may change in the future.
+
+
+The DMABUF framework provides a generic method for sharing buffers
+between multiple devices. Device drivers that support DMABUF can export a DMA
+buffer to userspace as a file descriptor (known as the exporter role), import a
+DMA buffer from userspace using a file descriptor previously exported for a
+different or the same device (known as the importer role), or both. This
+section describes the DMABUF importer role API in V4L2.
+
+Input and output devices support the streaming I/O method when the
+V4L2_CAP_STREAMING flag in the
+capabilities field of &v4l2-capability; returned by
+the &VIDIOC-QUERYCAP; ioctl is set. Whether importing DMA buffers through
+DMABUF file descriptors is supported is determined by calling the
+&VIDIOC-REQBUFS; ioctl with the memory type set to
+V4L2_MEMORY_DMABUF.
+
+This I/O method is dedicated for sharing DMA buffers between V4L and
+other APIs.  Buffers (planes) are allocated by a driver on behalf of an
+application. Next, these buffers are exported to the application as file
+descriptors using an API which is specific for an allocator driver.  Only such
+file descriptor are exchanged. The descriptors and meta-information are passed
+in &v4l2-buffer; (or in &v4l2-plane; in the multi-planar API case).  The driver
+must be switched into DMABUF I/O mode by calling the &VIDIOC-REQBUFS; with the
+desired buffer type.
+
+
+  Initiating streaming I/O with DMABUF file descriptors
+
+  
+&v4l2-requestbuffers; reqbuf;
+
+memset (&reqbuf, 0, sizeof (reqbuf));
+reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+reqbuf.memory = V4L2_MEMORY_DMABUF;
+reqbuf.count = 1;
+
+if (ioctl (fd, &VIDIOC-REQBUFS;, &reqbuf) == -1) {
+   if (errno == EINVAL)
+   printf("Video capturing or DMABUF streaming is not 
supported\n");
+   else
+   perror("VIDIOC_REQBUFS");
+
+   exit(EXIT_FAILURE);
+}
+  
+
+
+The buffer (plane) file descriptor is passed on the fly with the
+&VIDIOC-QBUF; ioctl. In case of multiplanar buffers, every plane can be
+associated with a different DMABUF descriptor. Although buffers are commonly
+cycled, applications can pass a different DMABUF descriptor at each
+VIDIOC_QBUF call.
+
+
+  Queueing DMABUF using single plane API
+
+  
+int buffer_queue(int v4lfd, int index, int dmafd)
+{
+   &v4l2-buffer; buf;
+
+   memset(&buf, 0, sizeof buf);
+   buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+   buf.memory = V4L2_MEMORY_DMABUF;
+   buf.index = index;
+   buf.m.fd = dmafd;
+
+   if (ioctl(v4lfd, &VIDIOC-QBUF;, &buf) == -1) {
+   perror("VIDIOC_QBUF");
+   return -1;
+   }
+
+   return 0;
+}
+  
+
+
+
+  Queueing DMABUF using multi plane API
+
+  
+int buffer_queue_mp(int v4lfd, int index, int dmafd[], int n_planes)
+{
+   &v4l2-

[PATCHv9 03/25] v4l: vb2: add support for shared buffer (dma_buf)

2012-10-02 Thread Tomasz Stanislawski
From: Sumit Semwal 

This patch adds support for DMABUF memory type in videobuf2. It calls relevant
APIs of dma_buf for v4l reqbuf / qbuf / dqbuf operations.

For this version, the support is for videobuf2 as a user of the shared buffer;
so the allocation of the buffer is done outside of V4L2. [A sample allocator of
dma-buf shared buffer is given at [1]]

[1]: Rob Clark's DRM:
   https://github.com/robclark/kernel-omap4/commits/drmplane-dmabuf

Signed-off-by: Tomasz Stanislawski 
   [original work in the PoC for buffer sharing]
Signed-off-by: Sumit Semwal 
Signed-off-by: Sumit Semwal 
Acked-by: Laurent Pinchart 
---
 drivers/media/video/Kconfig  |1 +
 drivers/media/video/videobuf2-core.c |  207 +-
 include/media/videobuf2-core.h   |   27 +
 3 files changed, 232 insertions(+), 3 deletions(-)

diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index c128fac..c558d37 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -45,6 +45,7 @@ config V4L2_MEM2MEM_DEV
depends on VIDEOBUF2_CORE
 
 config VIDEOBUF2_CORE
+   select DMA_SHARED_BUFFER
tristate
 
 config VIDEOBUF2_MEMOPS
diff --git a/drivers/media/video/videobuf2-core.c 
b/drivers/media/video/videobuf2-core.c
index 268c7dd..901bc56 100644
--- a/drivers/media/video/videobuf2-core.c
+++ b/drivers/media/video/videobuf2-core.c
@@ -109,6 +109,36 @@ static void __vb2_buf_userptr_put(struct vb2_buffer *vb)
 }
 
 /**
+ * __vb2_plane_dmabuf_put() - release memory associated with
+ * a DMABUF shared plane
+ */
+static void __vb2_plane_dmabuf_put(struct vb2_queue *q, struct vb2_plane *p)
+{
+   if (!p->mem_priv)
+   return;
+
+   if (p->dbuf_mapped)
+   call_memop(q, unmap_dmabuf, p->mem_priv);
+
+   call_memop(q, detach_dmabuf, p->mem_priv);
+   dma_buf_put(p->dbuf);
+   memset(p, 0, sizeof(*p));
+}
+
+/**
+ * __vb2_buf_dmabuf_put() - release memory associated with
+ * a DMABUF shared buffer
+ */
+static void __vb2_buf_dmabuf_put(struct vb2_buffer *vb)
+{
+   struct vb2_queue *q = vb->vb2_queue;
+   unsigned int plane;
+
+   for (plane = 0; plane < vb->num_planes; ++plane)
+   __vb2_plane_dmabuf_put(q, &vb->planes[plane]);
+}
+
+/**
  * __setup_offsets() - setup unique offsets ("cookies") for every plane in
  * every buffer on the queue
  */
@@ -230,6 +260,8 @@ static void __vb2_free_mem(struct vb2_queue *q, unsigned 
int buffers)
/* Free MMAP buffers or release USERPTR buffers */
if (q->memory == V4L2_MEMORY_MMAP)
__vb2_buf_mem_free(vb);
+   else if (q->memory == V4L2_MEMORY_DMABUF)
+   __vb2_buf_dmabuf_put(vb);
else
__vb2_buf_userptr_put(vb);
}
@@ -363,6 +395,8 @@ static int __fill_v4l2_buffer(struct vb2_buffer *vb, struct 
v4l2_buffer *b)
b->m.offset = vb->v4l2_planes[0].m.mem_offset;
else if (q->memory == V4L2_MEMORY_USERPTR)
b->m.userptr = vb->v4l2_planes[0].m.userptr;
+   else if (q->memory == V4L2_MEMORY_DMABUF)
+   b->m.fd = vb->v4l2_planes[0].m.fd;
}
 
/*
@@ -454,13 +488,28 @@ static int __verify_mmap_ops(struct vb2_queue *q)
 }
 
 /**
+ * __verify_dmabuf_ops() - verify that all memory operations required for
+ * DMABUF queue type have been provided
+ */
+static int __verify_dmabuf_ops(struct vb2_queue *q)
+{
+   if (!(q->io_modes & VB2_DMABUF) || !q->mem_ops->attach_dmabuf ||
+   !q->mem_ops->detach_dmabuf  || !q->mem_ops->map_dmabuf ||
+   !q->mem_ops->unmap_dmabuf)
+   return -EINVAL;
+
+   return 0;
+}
+
+/**
  * __verify_memory_type() - Check whether the memory type and buffer type
  * passed to a buffer operation are compatible with the queue.
  */
 static int __verify_memory_type(struct vb2_queue *q,
enum v4l2_memory memory, enum v4l2_buf_type type)
 {
-   if (memory != V4L2_MEMORY_MMAP && memory != V4L2_MEMORY_USERPTR) {
+   if (memory != V4L2_MEMORY_MMAP && memory != V4L2_MEMORY_USERPTR &&
+   memory != V4L2_MEMORY_DMABUF) {
dprintk(1, "reqbufs: unsupported memory type\n");
return -EINVAL;
}
@@ -484,6 +533,11 @@ static int __verify_memory_type(struct vb2_queue *q,
return -EINVAL;
}
 
+   if (memory == V4L2_MEMORY_DMABUF && __verify_dmabuf_ops(q)) {
+   dprintk(1, "reqbufs: DMABUF for current setup unsupported\n");
+   return -EINVAL;
+   }
+
/*
 * Place the busy tests at the end: -EBUSY can be ignored when
 * create_bufs is called with count == 0, but count == 0 should still
@@ -853,6

[PATCHv9 04/25] v4l: vb: remove warnings about MEMORY_DMABUF

2012-10-02 Thread Tomasz Stanislawski
From: Sumit Semwal 

Adding DMABUF memory type causes videobuf to complain about not using it
in some switch cases. This patch removes these warnings.

Signed-off-by: Sumit Semwal 
Acked-by: Laurent Pinchart 
---
 drivers/media/video/videobuf-core.c |4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/media/video/videobuf-core.c 
b/drivers/media/video/videobuf-core.c
index bf7a326..5449e8a 100644
--- a/drivers/media/video/videobuf-core.c
+++ b/drivers/media/video/videobuf-core.c
@@ -335,6 +335,9 @@ static void videobuf_status(struct videobuf_queue *q, 
struct v4l2_buffer *b,
case V4L2_MEMORY_OVERLAY:
b->m.offset  = vb->boff;
break;
+   case V4L2_MEMORY_DMABUF:
+   /* DMABUF is not handled in videobuf framework */
+   break;
}
 
b->flags= 0;
@@ -405,6 +408,7 @@ int __videobuf_mmap_setup(struct videobuf_queue *q,
break;
case V4L2_MEMORY_USERPTR:
case V4L2_MEMORY_OVERLAY:
+   case V4L2_MEMORY_DMABUF:
/* nothing */
break;
}
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv9 05/25] v4l: vb2-dma-contig: shorten vb2_dma_contig prefix to vb2_dc

2012-10-02 Thread Tomasz Stanislawski
From: Laurent Pinchart 

Signed-off-by: Laurent Pinchart 
---
 drivers/media/video/videobuf2-dma-contig.c |   36 ++--
 1 file changed, 18 insertions(+), 18 deletions(-)

diff --git a/drivers/media/video/videobuf2-dma-contig.c 
b/drivers/media/video/videobuf2-dma-contig.c
index 4b71326..a05784f 100644
--- a/drivers/media/video/videobuf2-dma-contig.c
+++ b/drivers/media/video/videobuf2-dma-contig.c
@@ -32,9 +32,9 @@ struct vb2_dc_buf {
struct vb2_vmarea_handler   handler;
 };
 
-static void vb2_dma_contig_put(void *buf_priv);
+static void vb2_dc_put(void *buf_priv);
 
-static void *vb2_dma_contig_alloc(void *alloc_ctx, unsigned long size)
+static void *vb2_dc_alloc(void *alloc_ctx, unsigned long size)
 {
struct vb2_dc_conf *conf = alloc_ctx;
struct vb2_dc_buf *buf;
@@ -56,7 +56,7 @@ static void *vb2_dma_contig_alloc(void *alloc_ctx, unsigned 
long size)
buf->size = size;
 
buf->handler.refcount = &buf->refcount;
-   buf->handler.put = vb2_dma_contig_put;
+   buf->handler.put = vb2_dc_put;
buf->handler.arg = buf;
 
atomic_inc(&buf->refcount);
@@ -64,7 +64,7 @@ static void *vb2_dma_contig_alloc(void *alloc_ctx, unsigned 
long size)
return buf;
 }
 
-static void vb2_dma_contig_put(void *buf_priv)
+static void vb2_dc_put(void *buf_priv)
 {
struct vb2_dc_buf *buf = buf_priv;
 
@@ -75,14 +75,14 @@ static void vb2_dma_contig_put(void *buf_priv)
}
 }
 
-static void *vb2_dma_contig_cookie(void *buf_priv)
+static void *vb2_dc_cookie(void *buf_priv)
 {
struct vb2_dc_buf *buf = buf_priv;
 
return &buf->dma_addr;
 }
 
-static void *vb2_dma_contig_vaddr(void *buf_priv)
+static void *vb2_dc_vaddr(void *buf_priv)
 {
struct vb2_dc_buf *buf = buf_priv;
if (!buf)
@@ -91,14 +91,14 @@ static void *vb2_dma_contig_vaddr(void *buf_priv)
return buf->vaddr;
 }
 
-static unsigned int vb2_dma_contig_num_users(void *buf_priv)
+static unsigned int vb2_dc_num_users(void *buf_priv)
 {
struct vb2_dc_buf *buf = buf_priv;
 
return atomic_read(&buf->refcount);
 }
 
-static int vb2_dma_contig_mmap(void *buf_priv, struct vm_area_struct *vma)
+static int vb2_dc_mmap(void *buf_priv, struct vm_area_struct *vma)
 {
struct vb2_dc_buf *buf = buf_priv;
 
@@ -111,7 +111,7 @@ static int vb2_dma_contig_mmap(void *buf_priv, struct 
vm_area_struct *vma)
  &vb2_common_vm_ops, &buf->handler);
 }
 
-static void *vb2_dma_contig_get_userptr(void *alloc_ctx, unsigned long vaddr,
+static void *vb2_dc_get_userptr(void *alloc_ctx, unsigned long vaddr,
unsigned long size, int write)
 {
struct vb2_dc_buf *buf;
@@ -138,7 +138,7 @@ static void *vb2_dma_contig_get_userptr(void *alloc_ctx, 
unsigned long vaddr,
return buf;
 }
 
-static void vb2_dma_contig_put_userptr(void *mem_priv)
+static void vb2_dc_put_userptr(void *mem_priv)
 {
struct vb2_dc_buf *buf = mem_priv;
 
@@ -150,14 +150,14 @@ static void vb2_dma_contig_put_userptr(void *mem_priv)
 }
 
 const struct vb2_mem_ops vb2_dma_contig_memops = {
-   .alloc  = vb2_dma_contig_alloc,
-   .put= vb2_dma_contig_put,
-   .cookie = vb2_dma_contig_cookie,
-   .vaddr  = vb2_dma_contig_vaddr,
-   .mmap   = vb2_dma_contig_mmap,
-   .get_userptr= vb2_dma_contig_get_userptr,
-   .put_userptr= vb2_dma_contig_put_userptr,
-   .num_users  = vb2_dma_contig_num_users,
+   .alloc  = vb2_dc_alloc,
+   .put= vb2_dc_put,
+   .cookie = vb2_dc_cookie,
+   .vaddr  = vb2_dc_vaddr,
+   .mmap   = vb2_dc_mmap,
+   .get_userptr= vb2_dc_get_userptr,
+   .put_userptr= vb2_dc_put_userptr,
+   .num_users  = vb2_dc_num_users,
 };
 EXPORT_SYMBOL_GPL(vb2_dma_contig_memops);
 
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv9 06/25] v4l: vb2-dma-contig: remove reference of alloc_ctx from a buffer

2012-10-02 Thread Tomasz Stanislawski
This patch removes a reference to alloc_ctx from an instance of a DMA
contiguous buffer. It helps to avoid a risk of a dangling pointer if the
context is released while the buffer is still valid. Moreover it removes one
dereference step while accessing a device structure.

Signed-off-by: Tomasz Stanislawski 
Signed-off-by: Kyungmin Park 
Acked-by: Laurent Pinchart 
---
 drivers/media/video/videobuf2-dma-contig.c |   13 ++---
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/drivers/media/video/videobuf2-dma-contig.c 
b/drivers/media/video/videobuf2-dma-contig.c
index a05784f..20c95da 100644
--- a/drivers/media/video/videobuf2-dma-contig.c
+++ b/drivers/media/video/videobuf2-dma-contig.c
@@ -23,7 +23,7 @@ struct vb2_dc_conf {
 };
 
 struct vb2_dc_buf {
-   struct vb2_dc_conf  *conf;
+   struct device   *dev;
void*vaddr;
dma_addr_t  dma_addr;
unsigned long   size;
@@ -37,22 +37,21 @@ static void vb2_dc_put(void *buf_priv);
 static void *vb2_dc_alloc(void *alloc_ctx, unsigned long size)
 {
struct vb2_dc_conf *conf = alloc_ctx;
+   struct device *dev = conf->dev;
struct vb2_dc_buf *buf;
 
buf = kzalloc(sizeof *buf, GFP_KERNEL);
if (!buf)
return ERR_PTR(-ENOMEM);
 
-   buf->vaddr = dma_alloc_coherent(conf->dev, size, &buf->dma_addr,
-   GFP_KERNEL);
+   buf->vaddr = dma_alloc_coherent(dev, size, &buf->dma_addr, GFP_KERNEL);
if (!buf->vaddr) {
-   dev_err(conf->dev, "dma_alloc_coherent of size %ld failed\n",
-   size);
+   dev_err(dev, "dma_alloc_coherent of size %ld failed\n", size);
kfree(buf);
return ERR_PTR(-ENOMEM);
}
 
-   buf->conf = conf;
+   buf->dev = dev;
buf->size = size;
 
buf->handler.refcount = &buf->refcount;
@@ -69,7 +68,7 @@ static void vb2_dc_put(void *buf_priv)
struct vb2_dc_buf *buf = buf_priv;
 
if (atomic_dec_and_test(&buf->refcount)) {
-   dma_free_coherent(buf->conf->dev, buf->size, buf->vaddr,
+   dma_free_coherent(buf->dev, buf->size, buf->vaddr,
  buf->dma_addr);
kfree(buf);
}
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv9 07/25] v4l: vb2-dma-contig: reorder functions

2012-10-02 Thread Tomasz Stanislawski
From: Laurent Pinchart 

Group functions by buffer type.

Signed-off-by: Laurent Pinchart 
---
 drivers/media/video/videobuf2-dma-contig.c |   92 
 1 file changed, 54 insertions(+), 38 deletions(-)

diff --git a/drivers/media/video/videobuf2-dma-contig.c 
b/drivers/media/video/videobuf2-dma-contig.c
index 20c95da..daac2b2 100644
--- a/drivers/media/video/videobuf2-dma-contig.c
+++ b/drivers/media/video/videobuf2-dma-contig.c
@@ -25,14 +25,56 @@ struct vb2_dc_conf {
 struct vb2_dc_buf {
struct device   *dev;
void*vaddr;
-   dma_addr_t  dma_addr;
unsigned long   size;
-   struct vm_area_struct   *vma;
-   atomic_trefcount;
+   dma_addr_t  dma_addr;
+
+   /* MMAP related */
struct vb2_vmarea_handler   handler;
+   atomic_trefcount;
+
+   /* USERPTR related */
+   struct vm_area_struct   *vma;
 };
 
-static void vb2_dc_put(void *buf_priv);
+/*/
+/* callbacks for all buffers */
+/*/
+
+static void *vb2_dc_cookie(void *buf_priv)
+{
+   struct vb2_dc_buf *buf = buf_priv;
+
+   return &buf->dma_addr;
+}
+
+static void *vb2_dc_vaddr(void *buf_priv)
+{
+   struct vb2_dc_buf *buf = buf_priv;
+
+   return buf->vaddr;
+}
+
+static unsigned int vb2_dc_num_users(void *buf_priv)
+{
+   struct vb2_dc_buf *buf = buf_priv;
+
+   return atomic_read(&buf->refcount);
+}
+
+/*/
+/*callbacks for MMAP buffers */
+/*/
+
+static void vb2_dc_put(void *buf_priv)
+{
+   struct vb2_dc_buf *buf = buf_priv;
+
+   if (!atomic_dec_and_test(&buf->refcount))
+   return;
+
+   dma_free_coherent(buf->dev, buf->size, buf->vaddr, buf->dma_addr);
+   kfree(buf);
+}
 
 static void *vb2_dc_alloc(void *alloc_ctx, unsigned long size)
 {
@@ -63,40 +105,6 @@ static void *vb2_dc_alloc(void *alloc_ctx, unsigned long 
size)
return buf;
 }
 
-static void vb2_dc_put(void *buf_priv)
-{
-   struct vb2_dc_buf *buf = buf_priv;
-
-   if (atomic_dec_and_test(&buf->refcount)) {
-   dma_free_coherent(buf->dev, buf->size, buf->vaddr,
- buf->dma_addr);
-   kfree(buf);
-   }
-}
-
-static void *vb2_dc_cookie(void *buf_priv)
-{
-   struct vb2_dc_buf *buf = buf_priv;
-
-   return &buf->dma_addr;
-}
-
-static void *vb2_dc_vaddr(void *buf_priv)
-{
-   struct vb2_dc_buf *buf = buf_priv;
-   if (!buf)
-   return NULL;
-
-   return buf->vaddr;
-}
-
-static unsigned int vb2_dc_num_users(void *buf_priv)
-{
-   struct vb2_dc_buf *buf = buf_priv;
-
-   return atomic_read(&buf->refcount);
-}
-
 static int vb2_dc_mmap(void *buf_priv, struct vm_area_struct *vma)
 {
struct vb2_dc_buf *buf = buf_priv;
@@ -110,6 +118,10 @@ static int vb2_dc_mmap(void *buf_priv, struct 
vm_area_struct *vma)
  &vb2_common_vm_ops, &buf->handler);
 }
 
+/*/
+/*   callbacks for USERPTR buffers   */
+/*/
+
 static void *vb2_dc_get_userptr(void *alloc_ctx, unsigned long vaddr,
unsigned long size, int write)
 {
@@ -148,6 +160,10 @@ static void vb2_dc_put_userptr(void *mem_priv)
kfree(buf);
 }
 
+/*/
+/*   DMA CONTIG exported functions   */
+/*/
+
 const struct vb2_mem_ops vb2_dma_contig_memops = {
.alloc  = vb2_dc_alloc,
.put= vb2_dc_put,
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv9 08/25] v4l: vb2-dma-contig: add support for scatterlist in userptr mode

2012-10-02 Thread Tomasz Stanislawski
This patch introduces usage of dma_map_sg to map memory behind
a userspace pointer to a device as dma-contiguous mapping.

This patch contains some of the code kindly provided by Marek Szyprowski
 and Kamil Debski  and Andrzej
Pietrasiewicz . Kind thanks for bug reports from Laurent
Pinchart  and Seung-Woo Kim
.

Signed-off-by: Tomasz Stanislawski 
Signed-off-by: Kyungmin Park 
Acked-by: Laurent Pinchart 
---
 drivers/media/video/videobuf2-dma-contig.c |  226 ++--
 1 file changed, 210 insertions(+), 16 deletions(-)

diff --git a/drivers/media/video/videobuf2-dma-contig.c 
b/drivers/media/video/videobuf2-dma-contig.c
index daac2b2..8486e06 100644
--- a/drivers/media/video/videobuf2-dma-contig.c
+++ b/drivers/media/video/videobuf2-dma-contig.c
@@ -11,6 +11,8 @@
  */
 
 #include 
+#include 
+#include 
 #include 
 #include 
 
@@ -27,6 +29,8 @@ struct vb2_dc_buf {
void*vaddr;
unsigned long   size;
dma_addr_t  dma_addr;
+   enum dma_data_direction dma_dir;
+   struct sg_table *dma_sgt;
 
/* MMAP related */
struct vb2_vmarea_handler   handler;
@@ -37,6 +41,44 @@ struct vb2_dc_buf {
 };
 
 /*/
+/*scatterlist table functions*/
+/*/
+
+
+static void vb2_dc_sgt_foreach_page(struct sg_table *sgt,
+   void (*cb)(struct page *pg))
+{
+   struct scatterlist *s;
+   unsigned int i;
+
+   for_each_sg(sgt->sgl, s, sgt->orig_nents, i) {
+   struct page *page = sg_page(s);
+   unsigned int n_pages = PAGE_ALIGN(s->offset + s->length)
+   >> PAGE_SHIFT;
+   unsigned int j;
+
+   for (j = 0; j < n_pages; ++j, ++page)
+   cb(page);
+   }
+}
+
+static unsigned long vb2_dc_get_contiguous_size(struct sg_table *sgt)
+{
+   struct scatterlist *s;
+   dma_addr_t expected = sg_dma_address(sgt->sgl);
+   unsigned int i;
+   unsigned long size = 0;
+
+   for_each_sg(sgt->sgl, s, sgt->nents, i) {
+   if (sg_dma_address(s) != expected)
+   break;
+   expected = sg_dma_address(s) + sg_dma_len(s);
+   size += sg_dma_len(s);
+   }
+   return size;
+}
+
+/*/
 /* callbacks for all buffers */
 /*/
 
@@ -122,42 +164,194 @@ static int vb2_dc_mmap(void *buf_priv, struct 
vm_area_struct *vma)
 /*   callbacks for USERPTR buffers   */
 /*/
 
+static inline int vma_is_io(struct vm_area_struct *vma)
+{
+   return !!(vma->vm_flags & (VM_IO | VM_PFNMAP));
+}
+
+static int vb2_dc_get_user_pages(unsigned long start, struct page **pages,
+   int n_pages, struct vm_area_struct *vma, int write)
+{
+   if (vma_is_io(vma)) {
+   unsigned int i;
+
+   for (i = 0; i < n_pages; ++i, start += PAGE_SIZE) {
+   unsigned long pfn;
+   int ret = follow_pfn(vma, start, &pfn);
+
+   if (ret) {
+   pr_err("no page for address %lu\n", start);
+   return ret;
+   }
+   pages[i] = pfn_to_page(pfn);
+   }
+   } else {
+   int n;
+
+   n = get_user_pages(current, current->mm, start & PAGE_MASK,
+   n_pages, write, 1, pages, NULL);
+   /* negative error means that no page was pinned */
+   n = max(n, 0);
+   if (n != n_pages) {
+   pr_err("got only %d of %d user pages\n", n, n_pages);
+   while (n)
+   put_page(pages[--n]);
+   return -EFAULT;
+   }
+   }
+
+   return 0;
+}
+
+static void vb2_dc_put_dirty_page(struct page *page)
+{
+   set_page_dirty_lock(page);
+   put_page(page);
+}
+
+static void vb2_dc_put_userptr(void *buf_priv)
+{
+   struct vb2_dc_buf *buf = buf_priv;
+   struct sg_table *sgt = buf->dma_sgt;
+
+   dma_unmap_sg(buf->dev, sgt->sgl, sgt->orig_nents, buf->dma_dir);
+   if (!vma_is_io(buf->vma))
+   vb2_dc_sgt_foreach_page(sgt, vb2_dc_put_dirty_page);
+
+   sg_free_table(sgt);
+   kfree(sgt);
+   vb2_put_vma(buf->vma);
+   kfree(buf);
+}
+
 static void *vb2_dc_get_userptr(void *alloc_ctx, unsigned long vaddr,
-   unsigned long size, int write)
+   unsigned long size, int write)
 {
+   struct vb2_dc_conf *conf = alloc_ctx;
struct vb2_dc_buf *buf;
+   unsigned long

[PATCHv9 09/25] v4l: vb2: add prepare/finish callbacks to allocators

2012-10-02 Thread Tomasz Stanislawski
From: Marek Szyprowski 

This patch adds support for prepare/finish callbacks in VB2 allocators. These
callback are used for buffer flushing.

Signed-off-by: Marek Szyprowski 
Acked-by: Laurent Pinchart 
---
 drivers/media/video/videobuf2-core.c |   11 +++
 include/media/videobuf2-core.h   |7 +++
 2 files changed, 18 insertions(+)

diff --git a/drivers/media/video/videobuf2-core.c 
b/drivers/media/video/videobuf2-core.c
index 901bc56..05da3b4 100644
--- a/drivers/media/video/videobuf2-core.c
+++ b/drivers/media/video/videobuf2-core.c
@@ -844,6 +844,7 @@ void vb2_buffer_done(struct vb2_buffer *vb, enum 
vb2_buffer_state state)
 {
struct vb2_queue *q = vb->vb2_queue;
unsigned long flags;
+   unsigned int plane;
 
if (vb->state != VB2_BUF_STATE_ACTIVE)
return;
@@ -854,6 +855,10 @@ void vb2_buffer_done(struct vb2_buffer *vb, enum 
vb2_buffer_state state)
dprintk(4, "Done processing on buffer %d, state: %d\n",
vb->v4l2_buf.index, vb->state);
 
+   /* sync buffers */
+   for (plane = 0; plane < vb->num_planes; ++plane)
+   call_memop(q, finish, vb->planes[plane].mem_priv);
+
/* Add the buffer to the done buffers list */
spin_lock_irqsave(&q->done_lock, flags);
vb->state = state;
@@ -1148,9 +1153,15 @@ err:
 static void __enqueue_in_driver(struct vb2_buffer *vb)
 {
struct vb2_queue *q = vb->vb2_queue;
+   unsigned int plane;
 
vb->state = VB2_BUF_STATE_ACTIVE;
atomic_inc(&q->queued_count);
+
+   /* sync buffers */
+   for (plane = 0; plane < vb->num_planes; ++plane)
+   call_memop(q, prepare, vb->planes[plane].mem_priv);
+
q->ops->buf_queue(vb);
 }
 
diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h
index 84f11f2..c306fec 100644
--- a/include/media/videobuf2-core.h
+++ b/include/media/videobuf2-core.h
@@ -56,6 +56,10 @@ struct vb2_fileio_data;
  * dmabuf
  * @unmap_dmabuf: releases access control to the dmabuf - allocator is notified
  *   that this driver is done using the dmabuf for now
+ * @prepare:   called everytime the buffer is passed from userspace to the
+ * driver, usefull for cache synchronisation, optional
+ * @finish:called everytime the buffer is passed back from the driver
+ * to the userspace, also optional
  * @vaddr: return a kernel virtual address to a given memory buffer
  * associated with the passed private structure or NULL if no
  * such mapping exists
@@ -82,6 +86,9 @@ struct vb2_mem_ops {
unsigned long size, int write);
void(*put_userptr)(void *buf_priv);
 
+   void(*prepare)(void *buf_priv);
+   void(*finish)(void *buf_priv);
+
void*(*attach_dmabuf)(void *alloc_ctx, struct dma_buf *dbuf,
unsigned long size, int write);
void(*detach_dmabuf)(void *buf_priv);
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv9 10/25] v4l: vb2-dma-contig: add prepare/finish to dma-contig allocator

2012-10-02 Thread Tomasz Stanislawski
From: Marek Szyprowski 

Add prepare/finish callbacks to vb2-dma-contig allocator.

Signed-off-by: Marek Szyprowski 
Acked-by: Laurent Pinchart 
---
 drivers/media/video/videobuf2-dma-contig.c |   24 
 1 file changed, 24 insertions(+)

diff --git a/drivers/media/video/videobuf2-dma-contig.c 
b/drivers/media/video/videobuf2-dma-contig.c
index 8486e06..494a824 100644
--- a/drivers/media/video/videobuf2-dma-contig.c
+++ b/drivers/media/video/videobuf2-dma-contig.c
@@ -103,6 +103,28 @@ static unsigned int vb2_dc_num_users(void *buf_priv)
return atomic_read(&buf->refcount);
 }
 
+static void vb2_dc_prepare(void *buf_priv)
+{
+   struct vb2_dc_buf *buf = buf_priv;
+   struct sg_table *sgt = buf->dma_sgt;
+
+   if (!sgt)
+   return;
+
+   dma_sync_sg_for_device(buf->dev, sgt->sgl, sgt->nents, buf->dma_dir);
+}
+
+static void vb2_dc_finish(void *buf_priv)
+{
+   struct vb2_dc_buf *buf = buf_priv;
+   struct sg_table *sgt = buf->dma_sgt;
+
+   if (!sgt)
+   return;
+
+   dma_sync_sg_for_cpu(buf->dev, sgt->sgl, sgt->nents, buf->dma_dir);
+}
+
 /*/
 /*callbacks for MMAP buffers */
 /*/
@@ -366,6 +388,8 @@ const struct vb2_mem_ops vb2_dma_contig_memops = {
.mmap   = vb2_dc_mmap,
.get_userptr= vb2_dc_get_userptr,
.put_userptr= vb2_dc_put_userptr,
+   .prepare= vb2_dc_prepare,
+   .finish = vb2_dc_finish,
.num_users  = vb2_dc_num_users,
 };
 EXPORT_SYMBOL_GPL(vb2_dma_contig_memops);
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv9 11/25] v4l: vb2-dma-contig: add support for dma_buf importing

2012-10-02 Thread Tomasz Stanislawski
From: Sumit Semwal 

This patch makes changes for adding dma-contig as a dma_buf user. It provides
function implementations for the {attach, detach, map, unmap}_dmabuf()
mem_ops of DMABUF memory type.

Signed-off-by: Sumit Semwal 
Signed-off-by: Sumit Semwal 
[author of the original patch]
Signed-off-by: Tomasz Stanislawski 
[integration with refactored dma-contig allocator]
Acked-by: Laurent Pinchart 
---
 drivers/media/video/Kconfig|1 +
 drivers/media/video/videobuf2-dma-contig.c |  120 +++-
 2 files changed, 119 insertions(+), 2 deletions(-)

diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index c558d37..ec089da 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -54,6 +54,7 @@ config VIDEOBUF2_MEMOPS
 config VIDEOBUF2_DMA_CONTIG
select VIDEOBUF2_CORE
select VIDEOBUF2_MEMOPS
+   select DMA_SHARED_BUFFER
tristate
 
 config VIDEOBUF2_VMALLOC
diff --git a/drivers/media/video/videobuf2-dma-contig.c 
b/drivers/media/video/videobuf2-dma-contig.c
index 494a824..a5804cf 100644
--- a/drivers/media/video/videobuf2-dma-contig.c
+++ b/drivers/media/video/videobuf2-dma-contig.c
@@ -10,6 +10,7 @@
  * the Free Software Foundation.
  */
 
+#include 
 #include 
 #include 
 #include 
@@ -38,6 +39,9 @@ struct vb2_dc_buf {
 
/* USERPTR related */
struct vm_area_struct   *vma;
+
+   /* DMABUF related */
+   struct dma_buf_attachment   *db_attach;
 };
 
 /*/
@@ -108,7 +112,8 @@ static void vb2_dc_prepare(void *buf_priv)
struct vb2_dc_buf *buf = buf_priv;
struct sg_table *sgt = buf->dma_sgt;
 
-   if (!sgt)
+   /* DMABUF exporter will flush the cache for us */
+   if (!sgt || buf->db_attach)
return;
 
dma_sync_sg_for_device(buf->dev, sgt->sgl, sgt->nents, buf->dma_dir);
@@ -119,7 +124,8 @@ static void vb2_dc_finish(void *buf_priv)
struct vb2_dc_buf *buf = buf_priv;
struct sg_table *sgt = buf->dma_sgt;
 
-   if (!sgt)
+   /* DMABUF exporter will flush the cache for us */
+   if (!sgt || buf->db_attach)
return;
 
dma_sync_sg_for_cpu(buf->dev, sgt->sgl, sgt->nents, buf->dma_dir);
@@ -377,6 +383,112 @@ fail_buf:
 }
 
 /*/
+/*   callbacks for DMABUF buffers*/
+/*/
+
+static int vb2_dc_map_dmabuf(void *mem_priv)
+{
+   struct vb2_dc_buf *buf = mem_priv;
+   struct sg_table *sgt;
+   unsigned long contig_size;
+
+   if (WARN_ON(!buf->db_attach)) {
+   pr_err("trying to pin a non attached buffer\n");
+   return -EINVAL;
+   }
+
+   if (WARN_ON(buf->dma_sgt)) {
+   pr_err("dmabuf buffer is already pinned\n");
+   return 0;
+   }
+
+   /* get the associated scatterlist for this buffer */
+   sgt = dma_buf_map_attachment(buf->db_attach, buf->dma_dir);
+   if (IS_ERR_OR_NULL(sgt)) {
+   pr_err("Error getting dmabuf scatterlist\n");
+   return -EINVAL;
+   }
+
+   /* checking if dmabuf is big enough to store contiguous chunk */
+   contig_size = vb2_dc_get_contiguous_size(sgt);
+   if (contig_size < buf->size) {
+   pr_err("contiguous chunk is too small %lu/%lu b\n",
+   contig_size, buf->size);
+   dma_buf_unmap_attachment(buf->db_attach, sgt, buf->dma_dir);
+   return -EFAULT;
+   }
+
+   buf->dma_addr = sg_dma_address(sgt->sgl);
+   buf->dma_sgt = sgt;
+
+   return 0;
+}
+
+static void vb2_dc_unmap_dmabuf(void *mem_priv)
+{
+   struct vb2_dc_buf *buf = mem_priv;
+   struct sg_table *sgt = buf->dma_sgt;
+
+   if (WARN_ON(!buf->db_attach)) {
+   pr_err("trying to unpin a not attached buffer\n");
+   return;
+   }
+
+   if (WARN_ON(!sgt)) {
+   pr_err("dmabuf buffer is already unpinned\n");
+   return;
+   }
+
+   dma_buf_unmap_attachment(buf->db_attach, sgt, buf->dma_dir);
+
+   buf->dma_addr = 0;
+   buf->dma_sgt = NULL;
+}
+
+static void vb2_dc_detach_dmabuf(void *mem_priv)
+{
+   struct vb2_dc_buf *buf = mem_priv;
+
+   /* if vb2 works correctly you should never detach mapped buffer */
+   if (WARN_ON(buf->dma_addr))
+   vb2_dc_unmap_dmabuf(buf);
+
+   /* detach this attachment */
+   dma_buf_detach(buf->db_attach->dmabuf, buf->db_attach);
+   kfree(buf);
+}
+
+static void *vb2_dc_attach_dmabuf(void *alloc_ctx, struct dma_buf *dbuf,
+   unsigned long size, int write)
+{
+   struct vb2_dc_conf *conf = alloc_ctx;
+   struct vb2_

[PATCHv9 12/25] v4l: vb2-vmalloc: add support for dmabuf importing

2012-10-02 Thread Tomasz Stanislawski
This patch adds support for importing DMABUF files for
vmalloc allocator in Videobuf2.

Signed-off-by: Tomasz Stanislawski 
Signed-off-by: Kyungmin Park 
Acked-by: Laurent Pinchart 
---
 drivers/media/video/videobuf2-vmalloc.c |   56 +++
 1 file changed, 56 insertions(+)

diff --git a/drivers/media/video/videobuf2-vmalloc.c 
b/drivers/media/video/videobuf2-vmalloc.c
index 6b5ca6c..e91449c 100644
--- a/drivers/media/video/videobuf2-vmalloc.c
+++ b/drivers/media/video/videobuf2-vmalloc.c
@@ -29,6 +29,7 @@ struct vb2_vmalloc_buf {
unsigned intn_pages;
atomic_trefcount;
struct vb2_vmarea_handler   handler;
+   struct dma_buf  *dbuf;
 };
 
 static void vb2_vmalloc_put(void *buf_priv);
@@ -206,11 +207,66 @@ static int vb2_vmalloc_mmap(void *buf_priv, struct 
vm_area_struct *vma)
return 0;
 }
 
+/*/
+/*   callbacks for DMABUF buffers*/
+/*/
+
+static int vb2_vmalloc_map_dmabuf(void *mem_priv)
+{
+   struct vb2_vmalloc_buf *buf = mem_priv;
+
+   buf->vaddr = dma_buf_vmap(buf->dbuf);
+
+   return buf->vaddr ? 0 : -EFAULT;
+}
+
+static void vb2_vmalloc_unmap_dmabuf(void *mem_priv)
+{
+   struct vb2_vmalloc_buf *buf = mem_priv;
+
+   dma_buf_vunmap(buf->dbuf, buf->vaddr);
+   buf->vaddr = NULL;
+}
+
+static void vb2_vmalloc_detach_dmabuf(void *mem_priv)
+{
+   struct vb2_vmalloc_buf *buf = mem_priv;
+
+   if (buf->vaddr)
+   dma_buf_vunmap(buf->dbuf, buf->vaddr);
+
+   kfree(buf);
+}
+
+static void *vb2_vmalloc_attach_dmabuf(void *alloc_ctx, struct dma_buf *dbuf,
+   unsigned long size, int write)
+{
+   struct vb2_vmalloc_buf *buf;
+
+   if (dbuf->size < size)
+   return ERR_PTR(-EFAULT);
+
+   buf = kzalloc(sizeof(*buf), GFP_KERNEL);
+   if (!buf)
+   return ERR_PTR(-ENOMEM);
+
+   buf->dbuf = dbuf;
+   buf->write = write;
+   buf->size = size;
+
+   return buf;
+}
+
+
 const struct vb2_mem_ops vb2_vmalloc_memops = {
.alloc  = vb2_vmalloc_alloc,
.put= vb2_vmalloc_put,
.get_userptr= vb2_vmalloc_get_userptr,
.put_userptr= vb2_vmalloc_put_userptr,
+   .map_dmabuf = vb2_vmalloc_map_dmabuf,
+   .unmap_dmabuf   = vb2_vmalloc_unmap_dmabuf,
+   .attach_dmabuf  = vb2_vmalloc_attach_dmabuf,
+   .detach_dmabuf  = vb2_vmalloc_detach_dmabuf,
.vaddr  = vb2_vmalloc_vaddr,
.mmap   = vb2_vmalloc_mmap,
.num_users  = vb2_vmalloc_num_users,
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv9 13/25] v4l: vivi: support for dmabuf importing

2012-10-02 Thread Tomasz Stanislawski
This patch enhances VIVI driver with a support for importing a buffer
from DMABUF file descriptors.

Signed-off-by: Tomasz Stanislawski 
Signed-off-by: Kyungmin Park 
---
 drivers/media/video/vivi.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c
index a05494b..4fb38b9 100644
--- a/drivers/media/video/vivi.c
+++ b/drivers/media/video/vivi.c
@@ -1284,7 +1284,7 @@ static int __init vivi_create_instance(int inst)
q = &dev->vb_vidq;
memset(q, 0, sizeof(dev->vb_vidq));
q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-   q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ;
+   q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF | VB2_READ;
q->drv_priv = dev;
q->buf_struct_size = sizeof(struct vivi_buffer);
q->ops = &vivi_video_qops;
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv9 14/25] v4l: s5p-tv: mixer: support for dmabuf importing

2012-10-02 Thread Tomasz Stanislawski
This patch enhances s5p-tv with support for DMABUF importing via
V4L2_MEMORY_DMABUF memory type.

Signed-off-by: Tomasz Stanislawski 
Signed-off-by: Kyungmin Park 
---
 drivers/media/video/s5p-tv/mixer_video.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/media/video/s5p-tv/mixer_video.c 
b/drivers/media/video/s5p-tv/mixer_video.c
index 6c74b05..2c299db 100644
--- a/drivers/media/video/s5p-tv/mixer_video.c
+++ b/drivers/media/video/s5p-tv/mixer_video.c
@@ -1078,7 +1078,7 @@ struct mxr_layer *mxr_base_layer_create(struct mxr_device 
*mdev,
 
layer->vb_queue = (struct vb2_queue) {
.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
-   .io_modes = VB2_MMAP | VB2_USERPTR,
+   .io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF,
.drv_priv = layer,
.buf_struct_size = sizeof(struct mxr_buffer),
.ops = &mxr_video_qops,
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv9 15/25] v4l: s5p-fimc: support for dmabuf importing

2012-10-02 Thread Tomasz Stanislawski
This patch enhances s5p-fimc with support for DMABUF importing via
V4L2_MEMORY_DMABUF memory type.

Signed-off-by: Tomasz Stanislawski 
Signed-off-by: Kyungmin Park 
Acked-by: Sylwester Nawrocki 
---
 drivers/media/video/s5p-fimc/fimc-capture.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/media/video/s5p-fimc/fimc-capture.c 
b/drivers/media/video/s5p-fimc/fimc-capture.c
index 8e413dd..3fcaf7d 100644
--- a/drivers/media/video/s5p-fimc/fimc-capture.c
+++ b/drivers/media/video/s5p-fimc/fimc-capture.c
@@ -1634,7 +1634,7 @@ static int fimc_register_capture_device(struct fimc_dev 
*fimc,
q = &fimc->vid_cap.vbq;
memset(q, 0, sizeof(*q));
q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
-   q->io_modes = VB2_MMAP | VB2_USERPTR;
+   q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
q->drv_priv = fimc->vid_cap.ctx;
q->ops = &fimc_capture_qops;
q->mem_ops = &vb2_dma_contig_memops;
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv9 16/25] v4l: vb2-dma-contig: let mmap method to use dma_mmap_coherent call

2012-10-02 Thread Tomasz Stanislawski
From: Marek Szyprowski 

Let mmap method to use dma_mmap_coherent call.  Moreover, this patch removes
vb2_mmap_pfn_range from videobuf2 helpers as it was suggested by Laurent
Pinchart.  The function is no longer used in vb2 code.

Signed-off-by: Marek Szyprowski 
Signed-off-by: Tomasz Stanislawski 
Acked-by: Laurent Pinchart 
---
 drivers/media/video/videobuf2-dma-contig.c |   28 +--
 drivers/media/video/videobuf2-memops.c |   40 
 include/media/videobuf2-memops.h   |5 
 3 files changed, 26 insertions(+), 47 deletions(-)

diff --git a/drivers/media/video/videobuf2-dma-contig.c 
b/drivers/media/video/videobuf2-dma-contig.c
index a5804cf..0e065ce 100644
--- a/drivers/media/video/videobuf2-dma-contig.c
+++ b/drivers/media/video/videobuf2-dma-contig.c
@@ -178,14 +178,38 @@ static void *vb2_dc_alloc(void *alloc_ctx, unsigned long 
size)
 static int vb2_dc_mmap(void *buf_priv, struct vm_area_struct *vma)
 {
struct vb2_dc_buf *buf = buf_priv;
+   int ret;
 
if (!buf) {
printk(KERN_ERR "No buffer to map\n");
return -EINVAL;
}
 
-   return vb2_mmap_pfn_range(vma, buf->dma_addr, buf->size,
- &vb2_common_vm_ops, &buf->handler);
+   /*
+* dma_mmap_* uses vm_pgoff as in-buffer offset, but we want to
+* map whole buffer
+*/
+   vma->vm_pgoff = 0;
+
+   ret = dma_mmap_coherent(buf->dev, vma, buf->vaddr,
+   buf->dma_addr, buf->size);
+
+   if (ret) {
+   pr_err("Remapping memory failed, error: %d\n", ret);
+   return ret;
+   }
+
+   vma->vm_flags   |= VM_DONTEXPAND | VM_RESERVED;
+   vma->vm_private_data= &buf->handler;
+   vma->vm_ops = &vb2_common_vm_ops;
+
+   vma->vm_ops->open(vma);
+
+   pr_debug("%s: mapped dma addr 0x%08lx at 0x%08lx, size %ld\n",
+   __func__, (unsigned long)buf->dma_addr, vma->vm_start,
+   buf->size);
+
+   return 0;
 }
 
 /*/
diff --git a/drivers/media/video/videobuf2-memops.c 
b/drivers/media/video/videobuf2-memops.c
index 504cd4c..81c1ad8 100644
--- a/drivers/media/video/videobuf2-memops.c
+++ b/drivers/media/video/videobuf2-memops.c
@@ -137,46 +137,6 @@ int vb2_get_contig_userptr(unsigned long vaddr, unsigned 
long size,
 EXPORT_SYMBOL_GPL(vb2_get_contig_userptr);
 
 /**
- * vb2_mmap_pfn_range() - map physical pages to userspace
- * @vma:   virtual memory region for the mapping
- * @paddr: starting physical address of the memory to be mapped
- * @size:  size of the memory to be mapped
- * @vm_ops:vm operations to be assigned to the created area
- * @priv:  private data to be associated with the area
- *
- * Returns 0 on success.
- */
-int vb2_mmap_pfn_range(struct vm_area_struct *vma, unsigned long paddr,
-   unsigned long size,
-   const struct vm_operations_struct *vm_ops,
-   void *priv)
-{
-   int ret;
-
-   size = min_t(unsigned long, vma->vm_end - vma->vm_start, size);
-
-   vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
-   ret = remap_pfn_range(vma, vma->vm_start, paddr >> PAGE_SHIFT,
-   size, vma->vm_page_prot);
-   if (ret) {
-   printk(KERN_ERR "Remapping memory failed, error: %d\n", ret);
-   return ret;
-   }
-
-   vma->vm_flags   |= VM_DONTEXPAND | VM_RESERVED;
-   vma->vm_private_data= priv;
-   vma->vm_ops = vm_ops;
-
-   vma->vm_ops->open(vma);
-
-   pr_debug("%s: mapped paddr 0x%08lx at 0x%08lx, size %ld\n",
-   __func__, paddr, vma->vm_start, size);
-
-   return 0;
-}
-EXPORT_SYMBOL_GPL(vb2_mmap_pfn_range);
-
-/**
  * vb2_common_vm_open() - increase refcount of the vma
  * @vma:   virtual memory region for the mapping
  *
diff --git a/include/media/videobuf2-memops.h b/include/media/videobuf2-memops.h
index 84e1f6c..f05444c 100644
--- a/include/media/videobuf2-memops.h
+++ b/include/media/videobuf2-memops.h
@@ -33,11 +33,6 @@ extern const struct vm_operations_struct vb2_common_vm_ops;
 int vb2_get_contig_userptr(unsigned long vaddr, unsigned long size,
   struct vm_area_struct **res_vma, dma_addr_t *res_pa);
 
-int vb2_mmap_pfn_range(struct vm_area_struct *vma, unsigned long paddr,
-   unsigned long size,
-   const struct vm_operations_struct *vm_ops,
-   void *priv);
-
 struct vm_area_struct *vb2_get_vma(struct vm_area_struct *vma);
 void vb2_put_vma(struct vm_area_struct *vma);
 
-- 
1.7.9.

[PATCHv9 17/25] Documentation: media: description of DMABUF exporting in V4L2

2012-10-02 Thread Tomasz Stanislawski
This patch adds description and usage examples for exporting
DMABUF file descriptor in V4L2.

Signed-off-by: Tomasz Stanislawski 
Signed-off-by: Kyungmin Park 
CC: linux-...@vger.kernel.org
---
 Documentation/DocBook/media/v4l/compat.xml|3 +
 Documentation/DocBook/media/v4l/io.xml|3 +
 Documentation/DocBook/media/v4l/v4l2.xml  |1 +
 Documentation/DocBook/media/v4l/vidioc-expbuf.xml |  212 +
 4 files changed, 219 insertions(+)
 create mode 100644 Documentation/DocBook/media/v4l/vidioc-expbuf.xml

diff --git a/Documentation/DocBook/media/v4l/compat.xml 
b/Documentation/DocBook/media/v4l/compat.xml
index a46f95b..f0512aa 100644
--- a/Documentation/DocBook/media/v4l/compat.xml
+++ b/Documentation/DocBook/media/v4l/compat.xml
@@ -2625,6 +2625,9 @@ ioctls.
  Importing DMABUF file descriptors as a new IO method described
  in .
 
+
+ Exporting DMABUF files using &VIDIOC-EXPBUF; ioctl.
+
   
 
 
diff --git a/Documentation/DocBook/media/v4l/io.xml 
b/Documentation/DocBook/media/v4l/io.xml
index 5b58657..476f448 100644
--- a/Documentation/DocBook/media/v4l/io.xml
+++ b/Documentation/DocBook/media/v4l/io.xml
@@ -488,6 +488,9 @@ DMA buffer from userspace using a file descriptor 
previously exported for a
 different or the same device (known as the importer role), or both. This
 section describes the DMABUF importer role API in V4L2.
 
+Refer to  DMABUF exporting  for
+details about exporting a V4L2 buffers as DMABUF file descriptors.
+
 Input and output devices support the streaming I/O method when the
 V4L2_CAP_STREAMING flag in the
 capabilities field of &v4l2-capability; returned by
diff --git a/Documentation/DocBook/media/v4l/v4l2.xml 
b/Documentation/DocBook/media/v4l/v4l2.xml
index eee6908..d8c2597 100644
--- a/Documentation/DocBook/media/v4l/v4l2.xml
+++ b/Documentation/DocBook/media/v4l/v4l2.xml
@@ -543,6 +543,7 @@ and discussions on the V4L mailing list.
 &sub-enuminput;
 &sub-enumoutput;
 &sub-enumstd;
+&sub-expbuf;
 &sub-g-audio;
 &sub-g-audioout;
 &sub-g-crop;
diff --git a/Documentation/DocBook/media/v4l/vidioc-expbuf.xml 
b/Documentation/DocBook/media/v4l/vidioc-expbuf.xml
new file mode 100644
index 000..bf28e7d
--- /dev/null
+++ b/Documentation/DocBook/media/v4l/vidioc-expbuf.xml
@@ -0,0 +1,212 @@
+
+
+  
+ioctl VIDIOC_EXPBUF
+&manvol;
+  
+
+  
+VIDIOC_EXPBUF
+Export a buffer as a DMABUF file descriptor.
+  
+
+  
+
+  
+   int ioctl
+   int fd
+   int request
+   struct v4l2_exportbuffer 
*argp
+  
+
+  
+
+  
+Arguments
+
+
+  
+   fd
+   
+ &fd;
+   
+  
+  
+   request
+   
+ VIDIOC_EXPBUF
+   
+  
+  
+   argp
+   
+ 
+   
+  
+
+  
+
+  
+Description
+
+
+  Experimental
+  This is an  experimental 
+  interface and may change in the future.
+
+
+This ioctl is an extension to the memory
+mapping I/O method therefore it is available only for
+V4L2_MEMORY_MMAP buffers.  It can be used to export a
+buffer as a DMABUF file at any time after buffers have been allocated with the
+&VIDIOC-REQBUFS; ioctl.
+
+ To export a buffer, applicationis fill &v4l2-exportbuffer;.  The
+ type  field is set to the same buffer type as was
+previously used with  &v4l2-requestbuffers; type .
+Applications must also set the  index  field. Valid
+index numbers range from zero to the number of buffers allocated with
+&VIDIOC-REQBUFS; (&v4l2-requestbuffers; count )
+minus one.  For multi plane API, applications set the  plane
+ field to the index of the plane to be exported. Valid planes
+range from zero to the maximal number of valid planes for currently active
+format. For single plane API, applications must set  plane
+ to zero.  Additional flags may be posted in the 
+flags  field.  Refer to a manual for open() for details.
+Currently only O_CLOEXEC is supported.  All other fields must be set to zero.
+In a case of multi-planar API, every plane is exported separately using
+multiple  VIDIOC_EXPBUF  calls. 
+
+ After calling VIDIOC_EXPBUF the  fd
+ field will be set by a driver.  This is a DMABUF file
+descriptor. The application may pass it to other API. Refer to DMABUF importing for details about importing DMABUF
+files into V4L2 nodes. A developer is encouraged to close a DMABUF file when it
+is no longer used to avoid a resource leak.  
+
+  
+  
+   
+  Examples
+
+  
+   Exporting a buffer.
+   
+int buffer_export(int v4lfd, &v4l2-buf-type; bt, int index, int *dmafd)
+{
+   &v4l2-exportbuffer; expbuf;
+
+   memset(&expbuf, 0, sizeof expbuf);
+   expbuf.type = bt;
+   expbuf.index = index;
+   if (ioctl(v4lfd, &VIDIOC-EXPBUF;, &expbuf) == -1) {
+   perror("VIDIOC_EXPBUF

[PATCHv9 18/25] v4l: add buffer exporting via dmabuf

2012-10-02 Thread Tomasz Stanislawski
This patch adds extension to V4L2 api. It allow to export a mmap buffer as file
descriptor. New ioctl VIDIOC_EXPBUF is added. It takes a buffer offset used by
mmap and return a file descriptor on success.

Signed-off-by: Tomasz Stanislawski 
Signed-off-by: Kyungmin Park 
---
 drivers/media/video/v4l2-compat-ioctl32.c |1 +
 drivers/media/video/v4l2-dev.c|1 +
 drivers/media/video/v4l2-ioctl.c  |   10 ++
 include/linux/videodev2.h |   28 
 include/media/v4l2-ioctl.h|2 ++
 5 files changed, 42 insertions(+)

diff --git a/drivers/media/video/v4l2-compat-ioctl32.c 
b/drivers/media/video/v4l2-compat-ioctl32.c
index f0b5aba..8788000 100644
--- a/drivers/media/video/v4l2-compat-ioctl32.c
+++ b/drivers/media/video/v4l2-compat-ioctl32.c
@@ -971,6 +971,7 @@ long v4l2_compat_ioctl32(struct file *file, unsigned int 
cmd, unsigned long arg)
case VIDIOC_S_FBUF32:
case VIDIOC_OVERLAY32:
case VIDIOC_QBUF32:
+   case VIDIOC_EXPBUF:
case VIDIOC_DQBUF32:
case VIDIOC_STREAMON32:
case VIDIOC_STREAMOFF32:
diff --git a/drivers/media/video/v4l2-dev.c b/drivers/media/video/v4l2-dev.c
index 07aeafc..c43127c 100644
--- a/drivers/media/video/v4l2-dev.c
+++ b/drivers/media/video/v4l2-dev.c
@@ -638,6 +638,7 @@ static void determine_valid_ioctls(struct video_device 
*vdev)
SET_VALID_IOCTL(ops, VIDIOC_REQBUFS, vidioc_reqbufs);
SET_VALID_IOCTL(ops, VIDIOC_QUERYBUF, vidioc_querybuf);
SET_VALID_IOCTL(ops, VIDIOC_QBUF, vidioc_qbuf);
+   SET_VALID_IOCTL(ops, VIDIOC_EXPBUF, vidioc_expbuf);
SET_VALID_IOCTL(ops, VIDIOC_DQBUF, vidioc_dqbuf);
SET_VALID_IOCTL(ops, VIDIOC_OVERLAY, vidioc_overlay);
SET_VALID_IOCTL(ops, VIDIOC_G_FBUF, vidioc_g_fbuf);
diff --git a/drivers/media/video/v4l2-ioctl.c b/drivers/media/video/v4l2-ioctl.c
index dffd3c9..f3ec8c0 100644
--- a/drivers/media/video/v4l2-ioctl.c
+++ b/drivers/media/video/v4l2-ioctl.c
@@ -458,6 +458,15 @@ static void v4l_print_buffer(const void *arg, bool 
write_only)
tc->type, tc->flags, tc->frames, *(__u32 
*)tc->userbits);
 }
 
+static void v4l_print_exportbuffer(const void *arg, bool write_only)
+{
+   const struct v4l2_exportbuffer *p = arg;
+
+   pr_cont("fd=%d, type=%s, index=%u, plane=%u, flags=0x%08x\n",
+   p->fd, prt_names(p->type, v4l2_type_names),
+   p->index, p->plane, p->flags);
+}
+
 static void v4l_print_create_buffers(const void *arg, bool write_only)
 {
const struct v4l2_create_buffers *p = arg;
@@ -1947,6 +1956,7 @@ static struct v4l2_ioctl_info v4l2_ioctls[] = {
IOCTL_INFO_STD(VIDIOC_S_FBUF, vidioc_s_fbuf, v4l_print_framebuffer, 
INFO_FL_PRIO),
IOCTL_INFO_STD(VIDIOC_OVERLAY, vidioc_overlay, v4l_print_u32, 
INFO_FL_PRIO),
IOCTL_INFO_FNC(VIDIOC_QBUF, v4l_qbuf, v4l_print_buffer, INFO_FL_QUEUE),
+   IOCTL_INFO_STD(VIDIOC_EXPBUF, vidioc_expbuf, v4l_print_exportbuffer, 0),
IOCTL_INFO_FNC(VIDIOC_DQBUF, v4l_dqbuf, v4l_print_buffer, 
INFO_FL_QUEUE),
IOCTL_INFO_FNC(VIDIOC_STREAMON, v4l_streamon, v4l_print_buftype, 
INFO_FL_PRIO | INFO_FL_QUEUE),
IOCTL_INFO_FNC(VIDIOC_STREAMOFF, v4l_streamoff, v4l_print_buftype, 
INFO_FL_PRIO | INFO_FL_QUEUE),
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index e04a73e..f429b6a 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -688,6 +688,33 @@ struct v4l2_buffer {
 #define V4L2_BUF_FLAG_NO_CACHE_INVALIDATE  0x0800
 #define V4L2_BUF_FLAG_NO_CACHE_CLEAN   0x1000
 
+/**
+ * struct v4l2_exportbuffer - export of video buffer as DMABUF file descriptor
+ *
+ * @fd:file descriptor associated with DMABUF (set by driver)
+ * @flags: flags for newly created file, currently only O_CLOEXEC is
+ * supported, refer to manual of open syscall for more details
+ * @index: id number of the buffer
+ * @type:  enum v4l2_buf_type; buffer type (type == *_MPLANE for
+ * multiplanar buffers);
+ * @plane: index of the plane to be exported, 0 for single plane queues
+ *
+ * Contains data used for exporting a video buffer as DMABUF file descriptor.
+ * The buffer is identified by a 'cookie' returned by VIDIOC_QUERYBUF
+ * (identical to the cookie used to mmap() the buffer to userspace). All
+ * reserved fields must be set to zero. The field reserved0 is expected to
+ * become a structure 'type' allowing an alternative layout of the structure
+ * content. Therefore this field should not be used for any other extensions.
+ */
+struct v4l2_exportbuffer {
+   __s32   fd;
+   __u32   flags;
+   __u32   type; /* enum v4l2_buf_type */
+   __u32   index;
+   __u32   plane;
+   __u32   reserved[11];
+};
+
 /*
  * O V E 

[PATCHv9 19/25] v4l: vb2: add buffer exporting via dmabuf

2012-10-02 Thread Tomasz Stanislawski
This patch adds extension to videobuf2-core. It allow to export a mmap buffer
as a file descriptor.

Signed-off-by: Tomasz Stanislawski 
Signed-off-by: Kyungmin Park 
Acked-by: Laurent Pinchart 
---
 drivers/media/video/videobuf2-core.c |   82 ++
 include/media/videobuf2-core.h   |4 ++
 2 files changed, 86 insertions(+)

diff --git a/drivers/media/video/videobuf2-core.c 
b/drivers/media/video/videobuf2-core.c
index 05da3b4..a97815b 100644
--- a/drivers/media/video/videobuf2-core.c
+++ b/drivers/media/video/videobuf2-core.c
@@ -1753,6 +1753,79 @@ static int __find_plane_by_offset(struct vb2_queue *q, 
unsigned long off,
 }
 
 /**
+ * vb2_expbuf() - Export a buffer as a file descriptor
+ * @q: videobuf2 queue
+ * @eb:export buffer structure passed from userspace to 
vidioc_expbuf
+ * handler in driver
+ *
+ * The return values from this function are intended to be directly returned
+ * from vidioc_expbuf handler in driver.
+ */
+int vb2_expbuf(struct vb2_queue *q, struct v4l2_exportbuffer *eb)
+{
+   struct vb2_buffer *vb = NULL;
+   struct vb2_plane *vb_plane;
+   int ret;
+   struct dma_buf *dbuf;
+
+   if (q->memory != V4L2_MEMORY_MMAP) {
+   dprintk(1, "Queue is not currently set up for mmap\n");
+   return -EINVAL;
+   }
+
+   if (!q->mem_ops->get_dmabuf) {
+   dprintk(1, "Queue does not support DMA buffer exporting\n");
+   return -EINVAL;
+   }
+
+   if (eb->flags & ~O_CLOEXEC) {
+   dprintk(1, "Queue does support only O_CLOEXEC flag\n");
+   return -EINVAL;
+   }
+
+   if (eb->type != q->type) {
+   dprintk(1, "qbuf: invalid buffer type\n");
+   return -EINVAL;
+   }
+
+   if (eb->index >= q->num_buffers) {
+   dprintk(1, "buffer index out of range\n");
+   return -EINVAL;
+   }
+
+   vb = q->bufs[eb->index];
+
+   if (eb->plane >= vb->num_planes) {
+   dprintk(1, "buffer plane out of range\n");
+   return -EINVAL;
+   }
+
+   vb_plane = &vb->planes[eb->plane];
+
+   dbuf = call_memop(q, get_dmabuf, vb_plane->mem_priv);
+   if (IS_ERR_OR_NULL(dbuf)) {
+   dprintk(1, "Failed to export buffer %d, plane %d\n",
+   eb->index, eb->plane);
+   return -EINVAL;
+   }
+
+   ret = dma_buf_fd(dbuf, eb->flags);
+   if (ret < 0) {
+   dprintk(3, "buffer %d, plane %d failed to export (%d)\n",
+   eb->index, eb->plane, ret);
+   dma_buf_put(dbuf);
+   return ret;
+   }
+
+   dprintk(3, "buffer %d, plane %d exported as %d descriptor\n",
+   eb->index, eb->plane, ret);
+   eb->fd = ret;
+
+   return 0;
+}
+EXPORT_SYMBOL_GPL(vb2_expbuf);
+
+/**
  * vb2_mmap() - map video buffers into application address space
  * @q: videobuf2 queue
  * @vma:   vma passed to the mmap file operation handler in the driver
@@ -2455,6 +2528,15 @@ int vb2_ioctl_streamoff(struct file *file, void *priv, 
enum v4l2_buf_type i)
 }
 EXPORT_SYMBOL_GPL(vb2_ioctl_streamoff);
 
+int vb2_ioctl_expbuf(struct file *file, void *priv, struct v4l2_exportbuffer 
*p)
+{
+   struct video_device *vdev = video_devdata(file);
+
+   /* No need to call vb2_queue_is_busy(), anyone can export buffers. */
+   return vb2_expbuf(vdev->queue, p);
+}
+EXPORT_SYMBOL_GPL(vb2_ioctl_expbuf);
+
 /* v4l2_file_operations helpers */
 
 int vb2_fop_mmap(struct file *file, struct vm_area_struct *vma)
diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h
index c306fec..3f57ccb 100644
--- a/include/media/videobuf2-core.h
+++ b/include/media/videobuf2-core.h
@@ -81,6 +81,7 @@ struct vb2_fileio_data;
 struct vb2_mem_ops {
void*(*alloc)(void *alloc_ctx, unsigned long size);
void(*put)(void *buf_priv);
+   struct dma_buf *(*get_dmabuf)(void *buf_priv);
 
void*(*get_userptr)(void *alloc_ctx, unsigned long vaddr,
unsigned long size, int write);
@@ -363,6 +364,7 @@ int vb2_queue_init(struct vb2_queue *q);
 void vb2_queue_release(struct vb2_queue *q);
 
 int vb2_qbuf(struct vb2_queue *q, struct v4l2_buffer *b);
+int vb2_expbuf(struct vb2_queue *q, struct v4l2_exportbuffer *eb);
 int vb2_dqbuf(struct vb2_queue *q, struct v4l2_buffer *b, bool nonblocking);
 
 int vb2_streamon(struct vb2_queue *q, enum v4l2_buf_type type);
@@ -472,6 +474,8 @@ int vb2_ioctl_qbuf(struct file *file, void *priv, struct 
v4l2_buffer *p);
 int vb2_ioctl_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p);
 int vb2_ioctl_streamon(struct file *file, vo

[PATCHv9 20/25] v4l: vb2-dma-contig: add support for DMABUF exporting

2012-10-02 Thread Tomasz Stanislawski
This patch adds support for exporting a dma-contig buffer using
DMABUF interface.

Signed-off-by: Tomasz Stanislawski 
Signed-off-by: Kyungmin Park 
---
 drivers/media/video/videobuf2-dma-contig.c |  200 
 1 file changed, 200 insertions(+)

diff --git a/drivers/media/video/videobuf2-dma-contig.c 
b/drivers/media/video/videobuf2-dma-contig.c
index 0e065ce..b138b5c 100644
--- a/drivers/media/video/videobuf2-dma-contig.c
+++ b/drivers/media/video/videobuf2-dma-contig.c
@@ -36,6 +36,7 @@ struct vb2_dc_buf {
/* MMAP related */
struct vb2_vmarea_handler   handler;
atomic_trefcount;
+   struct sg_table *sgt_base;
 
/* USERPTR related */
struct vm_area_struct   *vma;
@@ -142,6 +143,10 @@ static void vb2_dc_put(void *buf_priv)
if (!atomic_dec_and_test(&buf->refcount))
return;
 
+   if (buf->sgt_base) {
+   sg_free_table(buf->sgt_base);
+   kfree(buf->sgt_base);
+   }
dma_free_coherent(buf->dev, buf->size, buf->vaddr, buf->dma_addr);
kfree(buf);
 }
@@ -213,6 +218,200 @@ static int vb2_dc_mmap(void *buf_priv, struct 
vm_area_struct *vma)
 }
 
 /*/
+/* DMABUF ops for exporters  */
+/*/
+
+struct vb2_dc_attachment {
+   struct sg_table sgt;
+   enum dma_data_direction dir;
+};
+
+static int vb2_dc_dmabuf_ops_attach(struct dma_buf *dbuf, struct device *dev,
+   struct dma_buf_attachment *dbuf_attach)
+{
+   struct vb2_dc_attachment *attach;
+   unsigned int i;
+   struct scatterlist *rd, *wr;
+   struct sg_table *sgt;
+   struct vb2_dc_buf *buf = dbuf->priv;
+   int ret;
+
+   attach = kzalloc(sizeof(*attach), GFP_KERNEL);
+   if (!attach)
+   return -ENOMEM;
+
+   sgt = &attach->sgt;
+   /* Copy the buf->base_sgt scatter list to the attachment, as we can't
+* map the same scatter list to multiple attachments at the same time.
+*/
+   ret = sg_alloc_table(sgt, buf->sgt_base->orig_nents, GFP_KERNEL);
+   if (ret) {
+   kfree(attach);
+   return -ENOMEM;
+   }
+
+   rd = buf->sgt_base->sgl;
+   wr = sgt->sgl;
+   for (i = 0; i < sgt->orig_nents; ++i) {
+   sg_set_page(wr, sg_page(rd), rd->length, rd->offset);
+   rd = sg_next(rd);
+   wr = sg_next(wr);
+   }
+
+   attach->dir = DMA_NONE;
+   dbuf_attach->priv = attach;
+
+   return 0;
+}
+
+static void vb2_dc_dmabuf_ops_detach(struct dma_buf *dbuf,
+   struct dma_buf_attachment *db_attach)
+{
+   struct vb2_dc_attachment *attach = db_attach->priv;
+   struct sg_table *sgt;
+
+   if (!attach)
+   return;
+
+   sgt = &attach->sgt;
+
+   /* release the scatterlist cache */
+   if (attach->dir != DMA_NONE)
+   dma_unmap_sg(db_attach->dev, sgt->sgl, sgt->orig_nents,
+   attach->dir);
+   sg_free_table(sgt);
+   kfree(attach);
+   db_attach->priv = NULL;
+}
+
+static struct sg_table *vb2_dc_dmabuf_ops_map(
+   struct dma_buf_attachment *db_attach, enum dma_data_direction dir)
+{
+   struct vb2_dc_attachment *attach = db_attach->priv;
+   /* stealing dmabuf mutex to serialize map/unmap operations */
+   struct mutex *lock = &db_attach->dmabuf->lock;
+   struct sg_table *sgt;
+   int ret;
+
+   mutex_lock(lock);
+
+   sgt = &attach->sgt;
+   /* return previously mapped sg table */
+   if (attach->dir == dir) {
+   mutex_unlock(lock);
+   return sgt;
+   }
+
+   /* release any previous cache */
+   if (attach->dir != DMA_NONE) {
+   dma_unmap_sg(db_attach->dev, sgt->sgl, sgt->orig_nents,
+   attach->dir);
+   attach->dir = DMA_NONE;
+   }
+
+   /* mapping to the client with new direction */
+   ret = dma_map_sg(db_attach->dev, sgt->sgl, sgt->orig_nents, dir);
+   if (ret <= 0) {
+   pr_err("failed to map scatterlist\n");
+   mutex_unlock(lock);
+   return ERR_PTR(-EIO);
+   }
+
+   attach->dir = dir;
+
+   mutex_unlock(lock);
+
+   return sgt;
+}
+
+static void vb2_dc_dmabuf_ops_unmap(struct dma_buf_attachment *db_attach,
+   struct sg_table *sgt, enum dma_data_direction dir)
+{
+   /* nothing to be done here */
+}
+
+static void vb2_dc_dmabuf_ops_release(struct dma_buf *dbuf)
+{
+   /* drop reference obtained in vb2_dc_get_dmabuf */
+   vb2_dc_put(dbuf->priv);
+}
+
+static void *vb2_dc_dmabuf_ops_kmap(struct dma_buf *dbuf, unsigned long pgnum)
+{

[PATCHv9 21/25] v4l: vb2-dma-contig: add reference counting for a device from allocator context

2012-10-02 Thread Tomasz Stanislawski
This patch adds taking reference to the device for MMAP buffers.

Such buffers, may be exported using DMABUF mechanism. If the driver that
created a queue is unloaded then the queue is released, the device might be
released too.  However, buffers cannot be released if they are referenced by
DMABUF descriptor(s). The device pointer kept in a buffer must be valid for the
whole buffer's lifetime. Therefore MMAP buffers should take a reference to the
device to avoid risk of dangling pointers.

Signed-off-by: Tomasz Stanislawski 
---
 drivers/media/video/videobuf2-dma-contig.c |5 +
 1 file changed, 5 insertions(+)

diff --git a/drivers/media/video/videobuf2-dma-contig.c 
b/drivers/media/video/videobuf2-dma-contig.c
index b138b5c..b4d287a 100644
--- a/drivers/media/video/videobuf2-dma-contig.c
+++ b/drivers/media/video/videobuf2-dma-contig.c
@@ -148,6 +148,7 @@ static void vb2_dc_put(void *buf_priv)
kfree(buf->sgt_base);
}
dma_free_coherent(buf->dev, buf->size, buf->vaddr, buf->dma_addr);
+   put_device(buf->dev);
kfree(buf);
 }
 
@@ -161,9 +162,13 @@ static void *vb2_dc_alloc(void *alloc_ctx, unsigned long 
size)
if (!buf)
return ERR_PTR(-ENOMEM);
 
+   /* prevent the device from release while the buffer is exported */
+   get_device(dev);
+
buf->vaddr = dma_alloc_coherent(dev, size, &buf->dma_addr, GFP_KERNEL);
if (!buf->vaddr) {
dev_err(dev, "dma_alloc_coherent of size %ld failed\n", size);
+   put_device(dev);
kfree(buf);
return ERR_PTR(-ENOMEM);
}
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv9 22/25] v4l: vb2-dma-contig: fail if user ptr buffer is not correctly aligned

2012-10-02 Thread Tomasz Stanislawski
From: Marek Szyprowski 

The DMA transfer must be aligned to a specific value. If userptr is not aligned
to DMA requirements then unexpected corruptions of the memory may occur before
or after a buffer.  To prevent such situations, all unligned userptr buffers
are rejected at VIDIOC_QBUF.

Signed-off-by: Marek Szyprowski 
---
 drivers/media/video/videobuf2-dma-contig.c |7 +++
 1 file changed, 7 insertions(+)

diff --git a/drivers/media/video/videobuf2-dma-contig.c 
b/drivers/media/video/videobuf2-dma-contig.c
index b4d287a..55f8c80 100644
--- a/drivers/media/video/videobuf2-dma-contig.c
+++ b/drivers/media/video/videobuf2-dma-contig.c
@@ -494,6 +494,13 @@ static void *vb2_dc_get_userptr(void *alloc_ctx, unsigned 
long vaddr,
struct vm_area_struct *vma;
struct sg_table *sgt;
unsigned long contig_size;
+   unsigned long dma_align = dma_get_cache_alignment();
+
+   /* Only cache aligned DMA transfers are reliable */
+   if (!IS_ALIGNED(vaddr | size, dma_align)) {
+   pr_err("user data must be aligned to %lu bytes\n", dma_align);
+   return ERR_PTR(-EINVAL);
+   }
 
buf = kzalloc(sizeof *buf, GFP_KERNEL);
if (!buf)
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv9 23/25] v4l: s5p-fimc: support for dmabuf exporting

2012-10-02 Thread Tomasz Stanislawski
This patch enhances s5p-fimc with support for DMABUF exporting via
VIDIOC_EXPBUF ioctl.

Signed-off-by: Tomasz Stanislawski 
Signed-off-by: Kyungmin Park 
CC: Sylwester Nawrocki 
---
 drivers/media/video/s5p-fimc/fimc-capture.c |9 +
 1 file changed, 9 insertions(+)

diff --git a/drivers/media/video/s5p-fimc/fimc-capture.c 
b/drivers/media/video/s5p-fimc/fimc-capture.c
index 3fcaf7d..bdd2de5 100644
--- a/drivers/media/video/s5p-fimc/fimc-capture.c
+++ b/drivers/media/video/s5p-fimc/fimc-capture.c
@@ -1129,6 +1129,14 @@ static int fimc_cap_qbuf(struct file *file, void *priv,
return vb2_qbuf(&fimc->vid_cap.vbq, buf);
 }
 
+static int fimc_cap_expbuf(struct file *file, void *priv,
+ struct v4l2_exportbuffer *eb)
+{
+   struct fimc_dev *fimc = video_drvdata(file);
+
+   return vb2_expbuf(&fimc->vid_cap.vbq, eb);
+}
+
 static int fimc_cap_dqbuf(struct file *file, void *priv,
   struct v4l2_buffer *buf)
 {
@@ -1253,6 +1261,7 @@ static const struct v4l2_ioctl_ops fimc_capture_ioctl_ops 
= {
 
.vidioc_qbuf= fimc_cap_qbuf,
.vidioc_dqbuf   = fimc_cap_dqbuf,
+   .vidioc_expbuf  = fimc_cap_expbuf,
 
.vidioc_prepare_buf = fimc_cap_prepare_buf,
.vidioc_create_bufs = fimc_cap_create_bufs,
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv9 24/25] v4l: s5p-tv: mixer: support for dmabuf exporting

2012-10-02 Thread Tomasz Stanislawski
This patch enhances s5p-tv with support for DMABUF exporting via
VIDIOC_EXPBUF ioctl.

Signed-off-by: Tomasz Stanislawski 
Signed-off-by: Kyungmin Park 
---
 drivers/media/video/s5p-tv/mixer_video.c |   10 ++
 1 file changed, 10 insertions(+)

diff --git a/drivers/media/video/s5p-tv/mixer_video.c 
b/drivers/media/video/s5p-tv/mixer_video.c
index 2c299db..d1641b6 100644
--- a/drivers/media/video/s5p-tv/mixer_video.c
+++ b/drivers/media/video/s5p-tv/mixer_video.c
@@ -697,6 +697,15 @@ static int mxr_dqbuf(struct file *file, void *priv, struct 
v4l2_buffer *p)
return vb2_dqbuf(&layer->vb_queue, p, file->f_flags & O_NONBLOCK);
 }
 
+static int mxr_expbuf(struct file *file, void *priv,
+   struct v4l2_exportbuffer *eb)
+{
+   struct mxr_layer *layer = video_drvdata(file);
+
+   mxr_dbg(layer->mdev, "%s:%d\n", __func__, __LINE__);
+   return vb2_expbuf(&layer->vb_queue, eb);
+}
+
 static int mxr_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
 {
struct mxr_layer *layer = video_drvdata(file);
@@ -724,6 +733,7 @@ static const struct v4l2_ioctl_ops mxr_ioctl_ops = {
.vidioc_querybuf = mxr_querybuf,
.vidioc_qbuf = mxr_qbuf,
.vidioc_dqbuf = mxr_dqbuf,
+   .vidioc_expbuf = mxr_expbuf,
/* Streaming control */
.vidioc_streamon = mxr_streamon,
.vidioc_streamoff = mxr_streamoff,
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv9 25/25] v4l: s5p-mfc: support for dmabuf exporting

2012-10-02 Thread Tomasz Stanislawski
This patch enhances s5p-mfc with support for DMABUF exporting via
VIDIOC_EXPBUF ioctl.

Signed-off-by: Tomasz Stanislawski 
Signed-off-by: Kyungmin Park 
CC: Kamil Debski 
---
 drivers/media/video/s5p-mfc/s5p_mfc_dec.c |   14 ++
 drivers/media/video/s5p-mfc/s5p_mfc_enc.c |   14 ++
 2 files changed, 28 insertions(+)

diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_dec.c 
b/drivers/media/video/s5p-mfc/s5p_mfc_dec.c
index c5d567f..c2f4f49 100644
--- a/drivers/media/video/s5p-mfc/s5p_mfc_dec.c
+++ b/drivers/media/video/s5p-mfc/s5p_mfc_dec.c
@@ -570,6 +570,19 @@ static int vidioc_dqbuf(struct file *file, void *priv, 
struct v4l2_buffer *buf)
return -EINVAL;
 }
 
+/* Export DMA buffer */
+static int vidioc_expbuf(struct file *file, void *priv,
+   struct v4l2_exportbuffer *eb)
+{
+   struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
+
+   if (eb->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
+   return vb2_expbuf(&ctx->vq_src, eb);
+   if (eb->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
+   return vb2_expbuf(&ctx->vq_dst, eb);
+   return -EINVAL;
+}
+
 /* Stream on */
 static int vidioc_streamon(struct file *file, void *priv,
   enum v4l2_buf_type type)
@@ -745,6 +758,7 @@ static const struct v4l2_ioctl_ops s5p_mfc_dec_ioctl_ops = {
.vidioc_querybuf = vidioc_querybuf,
.vidioc_qbuf = vidioc_qbuf,
.vidioc_dqbuf = vidioc_dqbuf,
+   .vidioc_expbuf = vidioc_expbuf,
.vidioc_streamon = vidioc_streamon,
.vidioc_streamoff = vidioc_streamoff,
.vidioc_g_crop = vidioc_g_crop,
diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_enc.c 
b/drivers/media/video/s5p-mfc/s5p_mfc_enc.c
index aa1c244..a08ce0a 100644
--- a/drivers/media/video/s5p-mfc/s5p_mfc_enc.c
+++ b/drivers/media/video/s5p-mfc/s5p_mfc_enc.c
@@ -1142,6 +1142,19 @@ static int vidioc_dqbuf(struct file *file, void *priv, 
struct v4l2_buffer *buf)
return -EINVAL;
 }
 
+/* Export DMA buffer */
+static int vidioc_expbuf(struct file *file, void *priv,
+   struct v4l2_exportbuffer *eb)
+{
+   struct s5p_mfc_ctx *ctx = fh_to_ctx(priv);
+
+   if (eb->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
+   return vb2_expbuf(&ctx->vq_src, eb);
+   if (eb->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
+   return vb2_expbuf(&ctx->vq_dst, eb);
+   return -EINVAL;
+}
+
 /* Stream on */
 static int vidioc_streamon(struct file *file, void *priv,
   enum v4l2_buf_type type)
@@ -1487,6 +1500,7 @@ static const struct v4l2_ioctl_ops s5p_mfc_enc_ioctl_ops 
= {
.vidioc_querybuf = vidioc_querybuf,
.vidioc_qbuf = vidioc_qbuf,
.vidioc_dqbuf = vidioc_dqbuf,
+   .vidioc_expbuf = vidioc_expbuf,
.vidioc_streamon = vidioc_streamon,
.vidioc_streamoff = vidioc_streamoff,
.vidioc_s_parm = vidioc_s_parm,
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[GIT PULL FOR v3.7] media: s5p-hdmi: add HPD GPIO to platform data

2012-10-05 Thread Tomasz Stanislawski
Hi Mauro,
This patch is a part of "[PATCH v1 00/14] drm: exynos: hdmi: add dt based 
support for exynos5 hdmi"
patchset. The patchset refers to DRM tree (exynos-drm-next to be more exact).
However the patch 'media: s5p-hdmi: add HPD GPIO to platform data' belong to 
the media tree.

Regards,
Tomasz Stanislawski

The following changes since commit 2425bb3d4016ed95ce83a90b53bd92c7f31091e4:

  em28xx: regression fix: use DRX-K sync firmware requests on em28xx 
(2012-10-02 17:15:22 -0300)

are available in the git repository at:

  git://git.infradead.org/users/kmpark/linux-samsung v4l-s5p-tv-for3.7

for you to fetch changes up to b26bab928dd6f6e1d5613b68fa6fea1d29c9005e:

  media: s5p-hdmi: add HPD GPIO to platform data (2012-10-05 14:53:05 +0200)

----
Tomasz Stanislawski (1):
  media: s5p-hdmi: add HPD GPIO to platform data

 include/media/s5p_hdmi.h |2 ++
 1 file changed, 2 insertions(+)

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCHv9 18/25] v4l: add buffer exporting via dmabuf

2012-10-08 Thread Tomasz Stanislawski
Hi Hans,

On 10/07/2012 04:17 PM, Hans Verkuil wrote:
> On Sun October 7 2012 15:38:30 Laurent Pinchart wrote:
>> Hi Hans,
>>
>> On Friday 05 October 2012 10:55:40 Hans Verkuil wrote:
>>> On Tue October 2 2012 16:27:29 Tomasz Stanislawski wrote:
>>>> This patch adds extension to V4L2 api. It allow to export a mmap buffer as
>>>> file descriptor. New ioctl VIDIOC_EXPBUF is added. It takes a buffer
>>>> offset used by mmap and return a file descriptor on success.
>>>>
>>>> Signed-off-by: Tomasz Stanislawski 
>>>> Signed-off-by: Kyungmin Park 
>>
>> [snip]
>>
>>>> diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
>>>> index e04a73e..f429b6a 100644
>>>> --- a/include/linux/videodev2.h
>>>> +++ b/include/linux/videodev2.h
>>>> @@ -688,6 +688,33 @@ struct v4l2_buffer {
>>>>
>>>>  #define V4L2_BUF_FLAG_NO_CACHE_INVALIDATE 0x0800
>>>>  #define V4L2_BUF_FLAG_NO_CACHE_CLEAN  0x1000
>>>>
>>>> +/**
>>>> + * struct v4l2_exportbuffer - export of video buffer as DMABUF file
>>>> descriptor + *
>>>> + * @fd:   file descriptor associated with DMABUF (set by driver)
>>>> + * @flags:flags for newly created file, currently only O_CLOEXEC 
>>>> is
>>>> + *supported, refer to manual of open syscall for more 
>>>> details
>>>> + * @index:id number of the buffer
>>>> + * @type: enum v4l2_buf_type; buffer type (type == *_MPLANE for
>>>> + *multiplanar buffers);
>>>> + * @plane:index of the plane to be exported, 0 for single plane 
>>>> queues
>>>> + *
>>>> + * Contains data used for exporting a video buffer as DMABUF file
>>>> descriptor. + * The buffer is identified by a 'cookie' returned by
>>>> VIDIOC_QUERYBUF + * (identical to the cookie used to mmap() the buffer to
>>>> userspace). All + * reserved fields must be set to zero. The field
>>>> reserved0 is expected to + * become a structure 'type' allowing an
>>>> alternative layout of the structure + * content. Therefore this field
>>>> should not be used for any other extensions. + */
>>>> +struct v4l2_exportbuffer {
>>>> +  __s32   fd;
>>>> +  __u32   flags;
>>>> +  __u32   type; /* enum v4l2_buf_type */
>>>> +  __u32   index;
>>>> +  __u32   plane;
>>>
>>> As suggested in my comments in the previous patch, I think it is a more
>>> natural order to have the type/index/plane fields first in this struct.
>>>
>>> Actually, I think that flags should also come before fd:
>>>
>>> struct v4l2_exportbuffer {
>>> __u32   type; /* enum v4l2_buf_type */
>>> __u32   index;
>>> __u32   plane;
>>> __u32   flags;
>>> __s32   fd;
>>> __u32   reserved[11];
>>> };
>>
>> It would indeed feel more natural, but putting them right before the 
>> reserved 
>> fields allows creating an anonymous union around type, index and plane and 
>> extending it with reserved fields if needed. That's (at least to my 
>> understanding) the rationale behind the current structure layout.
> 
> The anonymous union argument makes no sense to me, to be honest.

I agree that the anonymous unions are not good solutions because they are not
supported in many C dialects. However I have nothing against using named unions.

> It's standard practice within V4L2 to have the IN fields first, then the OUT 
> fields, followed
> by reserved fields for future expansion.

IMO, the "input/output/reserved rule" is only a recommendation.
The are places in V4L2 where this rule is violated with structure
v4l2_buffer being the most notable example.

Notice that if at least one of the reserved fields becomes an input
file then "the rule" will be violated anyway.

> Should we ever need a, say, sub-plane
> index (whatever that might be), then we can use one of the reserved fields.

Maybe not subplane :).
But maybe some data_offset for exporting only a part of the buffer will
be needed some day.
Moreover, the integration of DMABUF with the DMA synchronization framework
may involve passing additional parameters from the userspace.

Notice that flags and fd fields are not logically connected with
(type/index/plane) tuple.
Therefore both field sets should be separated by some reserved fields to
ensure that any of them can be extended if needed.

This was the rationale for the structure layout in v9.

Regards,
Tomasz Stanislawski

> Regards,
> 
>   Hans
> 
>>
>>>> +  __u32   reserved[11];
>>>> +};
>>>> +
>>>>
>>>>  /*
>>>>  
>>>>   *O V E R L A Y   P R E V I E W
>>>>   */
>>
>>
> 

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCHv9 18/25] v4l: add buffer exporting via dmabuf

2012-10-08 Thread Tomasz Stanislawski
Hi Hans,

On 10/08/2012 11:54 AM, Hans Verkuil wrote:
> On Mon October 8 2012 11:40:37 Tomasz Stanislawski wrote:
>> Hi Hans,
>>
>> On 10/07/2012 04:17 PM, Hans Verkuil wrote:
>>> On Sun October 7 2012 15:38:30 Laurent Pinchart wrote:
>>>> Hi Hans,
>>>>
>>>> On Friday 05 October 2012 10:55:40 Hans Verkuil wrote:
>>>>> On Tue October 2 2012 16:27:29 Tomasz Stanislawski wrote:
>>>>>> This patch adds extension to V4L2 api. It allow to export a mmap buffer 
>>>>>> as
>>>>>> file descriptor. New ioctl VIDIOC_EXPBUF is added. It takes a buffer
>>>>>> offset used by mmap and return a file descriptor on success.
>>>>>>
>>>>>> Signed-off-by: Tomasz Stanislawski 
>>>>>> Signed-off-by: Kyungmin Park 
[snip]
>>>>>> +struct v4l2_exportbuffer {
>>>>>> +__s32   fd;
>>>>>> +__u32   flags;
>>>>>> +__u32   type; /* enum v4l2_buf_type */
>>>>>> +__u32   index;
>>>>>> +__u32   plane;
>>>>>
>>>>> As suggested in my comments in the previous patch, I think it is a more
>>>>> natural order to have the type/index/plane fields first in this struct.
>>>>>
>>>>> Actually, I think that flags should also come before fd:
>>>>>
>>>>> struct v4l2_exportbuffer {
>>>>>   __u32   type; /* enum v4l2_buf_type */
>>>>>   __u32   index;
>>>>>   __u32   plane;
>>>>>   __u32   flags;
>>>>>   __s32   fd;
>>>>>   __u32   reserved[11];
>>>>> };
>>>>
>>>> It would indeed feel more natural, but putting them right before the 
>>>> reserved 
>>>> fields allows creating an anonymous union around type, index and plane and 
>>>> extending it with reserved fields if needed. That's (at least to my 
>>>> understanding) the rationale behind the current structure layout.
>>>
>>> The anonymous union argument makes no sense to me, to be honest.
>>
>> I agree that the anonymous unions are not good solutions because they are not
>> supported in many C dialects. However I have nothing against using named 
>> unions.
> 
> Named or unnamed, I don't see how a union will help. What do you want to do
> with a union?
> 

Currently, there exist three sane layouts of the structure, that use
only one reserved field:

A)
struct v4l2_exportbuffer {
__s32   fd;
__u32   flags;
__u32   type; /* enum v4l2_buf_type */
__u32   index;
__u32   plane;
__u32   reserved[11];
}

B)
struct v4l2_exportbuffer {
__u32   type; /* enum v4l2_buf_type */
__u32   index;
__u32   plane;
__u32   flags;
__s32   fd;
__u32   reserved[11];
}

C)
struct v4l2_exportbuffer {
__u32   type; /* enum v4l2_buf_type */
__u32   index;
__u32   plane;
__u32   reserved[11];
__u32   flags;
__s32   fd;
}

Only the layout B follows 'input/output/reserved' rule.

The layouts A and C allows to extend (type/index/plane) tuple without mixing
it with (flags,fd).

For layouts A and C it is possible to use unions to provide new
means of describing a buffer to be exported.

struct v4l2_exportbuffer {
__s32   fd;
__u32   flags;
union {
struct by_tip { /* type, index, plane */
__u32   type; /* enum v4l2_buf_type */
__u32   index;
__u32   plane;
} by_tip;
struct by_userptr {
u64 userptr;
u64 length;
} by_userptr;
__u32   reserved[6];
} b;
__u32   union_type; /* BY_TIP or BY_USERPTR */
__u32   reserved[4];
};

No such an extension can be applied for layout B.

The similar scheme can be used for layout C. Moreover it support
extensions and variants for (flags/fd) tuple. It might be
useful if one day we would like to export a buffer as something
different from DMABUF file descriptors.

Anyway, we have to choose between the elegance of the layout
and the extensibility.

I think that layout A is a good trade-off.
We could swap fd and flags to get little closer to "the rule&q

Re: [PATCHv9 19/25] v4l: vb2: add buffer exporting via dmabuf

2012-10-10 Thread Tomasz Stanislawski
On 10/06/2012 02:22 PM, Hans Verkuil wrote:
> On Tue October 2 2012 16:27:30 Tomasz Stanislawski wrote:
>> This patch adds extension to videobuf2-core. It allow to export a mmap buffer
>> as a file descriptor.
>>
>> Signed-off-by: Tomasz Stanislawski 
>> Signed-off-by: Kyungmin Park 
>> Acked-by: Laurent Pinchart 
>> ---
>>  drivers/media/video/videobuf2-core.c |   82 
>> ++
>>  include/media/videobuf2-core.h   |4 ++
>>  2 files changed, 86 insertions(+)
>>
>> diff --git a/drivers/media/video/videobuf2-core.c 
>> b/drivers/media/video/videobuf2-core.c
>> index 05da3b4..a97815b 100644
>> --- a/drivers/media/video/videobuf2-core.c
>> +++ b/drivers/media/video/videobuf2-core.c
> 
> 
> 
>> @@ -2455,6 +2528,15 @@ int vb2_ioctl_streamoff(struct file *file, void 
>> *priv, enum v4l2_buf_type i)
>>  }
>>  EXPORT_SYMBOL_GPL(vb2_ioctl_streamoff);
>>  
>> +int vb2_ioctl_expbuf(struct file *file, void *priv, struct 
>> v4l2_exportbuffer *p)
>> +{
>> +struct video_device *vdev = video_devdata(file);
>> +
>> +/* No need to call vb2_queue_is_busy(), anyone can export buffers. */

Hi Hans,

> 
> After thinking about this some more I'm not so sure we should allow this.
> Exporting a buffer also means that the memory can't be freed as long as the
> exported filehandle remains open.
> 

You are completely right.
But the problem is much more complex ... see below.

> That means that it is possible to make a malicious application that exports
> the buffers and never frees them, which can cause havoc.

What kind of havoc do you mean? Resource leakage?

> I think that only
> the filehandle that called REQBUFS/CREATE_BUFS should be allowed to export
> buffers.

Notice that you should allow to call mmap() only for the file handles that 
called
REQBUFS/CREATE_BUFS. The mmap() creates a vma that holds a reference to a 
buffer.
As long as the mapping exists, the buffers cannot be freed and REQBUFS(count=0) 
returns -EBUSY.
According to V4L2 spec all the nodes share the same context, therefore
one process can call REQBUFS, and the other can call QUERYBUF and mmap().

Therefore if EXPBUF has to check vb2_queue_is_busy() then vb2_fop_mmap()
should do the same check too.

IMO, it is very difficult to develop a useful multi-client API that
would protect V4L2 from creating non-freeable buffers by a rogue applications.

I think that the requirements below:

- the buffers should be sharable between processes by mmap(), or DMABUF 
exporting
- the REQBUFS(count=0) should release the buffers

are contradictory and cannot be *reliably* satisfied at the same time.
Notice that REQBUFS(count=0) that unexpectedly return -EBUSY is not
a reliable solution. The application cannot do anything fix the problem
after receiving -EBUSY.

Anyway, I will apply the check for vb2_queue_is_busy() in v2b_ioctl_expbuf().

Regards,
Tomasz Stanislawski

> 
> What do you think?
> 
> Regards,
> 
>   Hans
> 
>> +return vb2_expbuf(vdev->queue, p);
>> +}
>> +EXPORT_SYMBOL_GPL(vb2_ioctl_expbuf);
>> +
>>  /* v4l2_file_operations helpers */
>>  
>>  int vb2_fop_mmap(struct file *file, struct vm_area_struct *vma)

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv10 00/26] Integration of videobuf2 with DMABUF

2012-10-10 Thread Tomasz Stanislawski
] https://lkml.org/lkml/2011/12/26/29
[3] http://thread.gmane.org/gmane.linux.kernel.cross-arch/12819
[4] 
http://article.gmane.org/gmane.linux.drivers.video-input-infrastructure/49700

Laurent Pinchart (2):
  v4l: vb2-dma-contig: shorten vb2_dma_contig prefix to vb2_dc
  v4l: vb2-dma-contig: reorder functions

Marek Szyprowski (4):
  v4l: vb2: add prepare/finish callbacks to allocators
  v4l: vb2-dma-contig: add prepare/finish to dma-contig allocator
  v4l: vb2-dma-contig: let mmap method to use dma_mmap_coherent call
  v4l: vb2-dma-contig: fail if user ptr buffer is not correctly aligned

Sumit Semwal (4):
  v4l: Add DMABUF as a memory type
  v4l: vb2: add support for shared buffer (dma_buf)
  v4l: vb: remove warnings about MEMORY_DMABUF
  v4l: vb2-dma-contig: add support for dma_buf importing

Tomasz Stanislawski (16):
  Documentation: media: description of DMABUF importing in V4L2
  v4l: vb2-dma-contig: remove reference of alloc_ctx from a buffer
  v4l: vb2-dma-contig: add support for scatterlist in userptr mode
  v4l: vb2-vmalloc: add support for dmabuf importing
  v4l: vivi: support for dmabuf importing
  v4l: s5p-tv: mixer: support for dmabuf importing
  v4l: s5p-fimc: support for dmabuf importing
  Documentation: media: description of DMABUF exporting in V4L2
  v4l: add buffer exporting via dmabuf
  v4l: vb2: add buffer exporting via dmabuf
  v4l: vb2-dma-contig: add support for DMABUF exporting
  v4l: vb2-dma-contig: add reference counting for a device from
allocator context
  v4l: vb2-dma-contig: align buffer size to PAGE_SIZE
  v4l: s5p-fimc: support for dmabuf exporting
  v4l: s5p-tv: mixer: support for dmabuf exporting
  v4l: s5p-mfc: support for dmabuf exporting

 Documentation/DocBook/media/v4l/compat.xml |7 +
 Documentation/DocBook/media/v4l/io.xml |  184 -
 Documentation/DocBook/media/v4l/v4l2.xml   |1 +
 .../DocBook/media/v4l/vidioc-create-bufs.xml   |   16 +-
 Documentation/DocBook/media/v4l/vidioc-expbuf.xml  |  212 ++
 Documentation/DocBook/media/v4l/vidioc-qbuf.xml|   17 +
 Documentation/DocBook/media/v4l/vidioc-reqbufs.xml |   47 +-
 drivers/media/platform/s5p-fimc/fimc-capture.c |   11 +-
 drivers/media/platform/s5p-fimc/fimc-m2m.c |   14 +-
 drivers/media/platform/s5p-mfc/s5p_mfc_dec.c   |   14 +
 drivers/media/platform/s5p-mfc/s5p_mfc_enc.c   |   14 +
 drivers/media/platform/s5p-tv/mixer_video.c|   12 +-
 drivers/media/platform/vivi.c  |2 +-
 drivers/media/v4l2-core/Kconfig|3 +
 drivers/media/v4l2-core/v4l2-compat-ioctl32.c  |   19 +
 drivers/media/v4l2-core/v4l2-dev.c |1 +
 drivers/media/v4l2-core/v4l2-ioctl.c   |   11 +
 drivers/media/v4l2-core/v4l2-mem2mem.c |   13 +
 drivers/media/v4l2-core/videobuf-core.c|4 +
 drivers/media/v4l2-core/videobuf2-core.c   |  300 -
 drivers/media/v4l2-core/videobuf2-dma-contig.c |  702 ++--
 drivers/media/v4l2-core/videobuf2-memops.c |   40 --
 drivers/media/v4l2-core/videobuf2-vmalloc.c|   56 ++
 include/linux/videodev2.h  |   35 +
 include/media/v4l2-ioctl.h |2 +
 include/media/v4l2-mem2mem.h   |3 +
 include/media/videobuf2-core.h |   38 ++
 include/media/videobuf2-memops.h   |5 -
 28 files changed, 1645 insertions(+), 138 deletions(-)
 create mode 100644 Documentation/DocBook/media/v4l/vidioc-expbuf.xml

-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv10 01/26] v4l: Add DMABUF as a memory type

2012-10-10 Thread Tomasz Stanislawski
From: Sumit Semwal 

Adds DMABUF memory type to v4l framework. Also adds the related file
descriptor in v4l2_plane and v4l2_buffer.

Signed-off-by: Tomasz Stanislawski 
   [original work in the PoC for buffer sharing]
Signed-off-by: Sumit Semwal 
Signed-off-by: Sumit Semwal 
Acked-by: Laurent Pinchart 
Acked-by: Hans Verkuil 
---
 drivers/media/v4l2-core/v4l2-compat-ioctl32.c |   18 ++
 drivers/media/v4l2-core/v4l2-ioctl.c  |1 +
 include/linux/videodev2.h |7 +++
 3 files changed, 26 insertions(+)

diff --git a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c 
b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
index 83ffb64..cc5998b 100644
--- a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
+++ b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
@@ -297,6 +297,7 @@ struct v4l2_plane32 {
union {
__u32   mem_offset;
compat_long_t   userptr;
+   __s32   fd;
} m;
__u32   data_offset;
__u32   reserved[11];
@@ -318,6 +319,7 @@ struct v4l2_buffer32 {
__u32   offset;
compat_long_t   userptr;
compat_caddr_t  planes;
+   __s32   fd;
} m;
__u32   length;
__u32   reserved2;
@@ -341,6 +343,9 @@ static int get_v4l2_plane32(struct v4l2_plane *up, struct 
v4l2_plane32 *up32,
up_pln = compat_ptr(p);
if (put_user((unsigned long)up_pln, &up->m.userptr))
return -EFAULT;
+   } else if (memory == V4L2_MEMORY_DMABUF) {
+   if (copy_in_user(&up->m.fd, &up32->m.fd, sizeof(int)))
+   return -EFAULT;
} else {
if (copy_in_user(&up->m.mem_offset, &up32->m.mem_offset,
sizeof(__u32)))
@@ -364,6 +369,11 @@ static int put_v4l2_plane32(struct v4l2_plane *up, struct 
v4l2_plane32 *up32,
if (copy_in_user(&up32->m.mem_offset, &up->m.mem_offset,
sizeof(__u32)))
return -EFAULT;
+   /* For DMABUF, driver might've set up the fd, so copy it back. */
+   if (memory == V4L2_MEMORY_DMABUF)
+   if (copy_in_user(&up32->m.fd, &up->m.fd,
+   sizeof(int)))
+   return -EFAULT;
 
return 0;
 }
@@ -446,6 +456,10 @@ static int get_v4l2_buffer32(struct v4l2_buffer *kp, 
struct v4l2_buffer32 __user
if (get_user(kp->m.offset, &up->m.offset))
return -EFAULT;
break;
+   case V4L2_MEMORY_DMABUF:
+   if (get_user(kp->m.fd, &up->m.fd))
+   return -EFAULT;
+   break;
}
}
 
@@ -510,6 +524,10 @@ static int put_v4l2_buffer32(struct v4l2_buffer *kp, 
struct v4l2_buffer32 __user
if (put_user(kp->m.offset, &up->m.offset))
return -EFAULT;
break;
+   case V4L2_MEMORY_DMABUF:
+   if (put_user(kp->m.fd, &up->m.fd))
+   return -EFAULT;
+   break;
}
}
 
diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c 
b/drivers/media/v4l2-core/v4l2-ioctl.c
index 8f388ff..530a67e 100644
--- a/drivers/media/v4l2-core/v4l2-ioctl.c
+++ b/drivers/media/v4l2-core/v4l2-ioctl.c
@@ -155,6 +155,7 @@ static const char *v4l2_memory_names[] = {
[V4L2_MEMORY_MMAP]= "mmap",
[V4L2_MEMORY_USERPTR] = "userptr",
[V4L2_MEMORY_OVERLAY] = "overlay",
+   [V4L2_MEMORY_DMABUF] = "dmabuf",
 };
 
 #define prt_names(a, arr) (((unsigned)(a)) < ARRAY_SIZE(arr) ? arr[a] : 
"unknown")
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index 873adbe..07bc5d6 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -188,6 +188,7 @@ enum v4l2_memory {
V4L2_MEMORY_MMAP = 1,
V4L2_MEMORY_USERPTR  = 2,
V4L2_MEMORY_OVERLAY  = 3,
+   V4L2_MEMORY_DMABUF   = 4,
 };
 
 /* see also http://vektor.theorem.ca/graphics/ycbcr/ */
@@ -604,6 +605,8 @@ struct v4l2_requestbuffers {
  * should be passed to mmap() called on the video node)
  * @userptr:   when memory is V4L2_MEMORY_USERPTR, a userspace pointer
  * pointing to this plane
+ * @fd:when memory is V4L2_MEMORY_DMABUF, a userspace 
file
+ * descriptor associated with this plane
  * @data_offset:   offset in the plane to the start of data; u

[PATCHv10 02/26] Documentation: media: description of DMABUF importing in V4L2

2012-10-10 Thread Tomasz Stanislawski
This patch adds description and usage examples for importing
DMABUF file descriptor in V4L2.

Signed-off-by: Tomasz Stanislawski 
Signed-off-by: Kyungmin Park 
CC: linux-...@vger.kernel.org
---
 Documentation/DocBook/media/v4l/compat.xml |4 +
 Documentation/DocBook/media/v4l/io.xml |  181 +++-
 .../DocBook/media/v4l/vidioc-create-bufs.xml   |   16 +-
 Documentation/DocBook/media/v4l/vidioc-qbuf.xml|   17 ++
 Documentation/DocBook/media/v4l/vidioc-reqbufs.xml |   47 ++---
 5 files changed, 235 insertions(+), 30 deletions(-)

diff --git a/Documentation/DocBook/media/v4l/compat.xml 
b/Documentation/DocBook/media/v4l/compat.xml
index 4fdf6b5..50eb630 100644
--- a/Documentation/DocBook/media/v4l/compat.xml
+++ b/Documentation/DocBook/media/v4l/compat.xml
@@ -2586,6 +2586,10 @@ ioctls.
  Vendor and device specific media bus pixel formats.
.
 
+
+ Importing DMABUF file descriptors as a new IO method described
+ in .
+
   
 
 
diff --git a/Documentation/DocBook/media/v4l/io.xml 
b/Documentation/DocBook/media/v4l/io.xml
index b5d1cbd..0abb5cb 100644
--- a/Documentation/DocBook/media/v4l/io.xml
+++ b/Documentation/DocBook/media/v4l/io.xml
@@ -331,7 +331,7 @@ application until one or more buffers can be dequeued. By 
default
 outgoing queue. When the O_NONBLOCK flag was
 given to the &func-open; function, VIDIOC_DQBUF
 returns immediately with an &EAGAIN; when no buffer is available. The
-&func-select; or &func-poll; function are always available.
+&func-select; or &func-poll; functions are always available.
 
 To start and stop capturing or output applications call the
 &VIDIOC-STREAMON; and &VIDIOC-STREAMOFF; ioctl. Note
@@ -472,6 +472,162 @@ rest should be evident.
   
   
 
+  
+Streaming I/O (DMA buffer importing)
+
+
+  Experimental
+  This is an  experimental 
+  interface and may change in the future.
+
+
+The DMABUF framework provides a generic method for sharing buffers
+between multiple devices. Device drivers that support DMABUF can export a DMA
+buffer to userspace as a file descriptor (known as the exporter role), import a
+DMA buffer from userspace using a file descriptor previously exported for a
+different or the same device (known as the importer role), or both. This
+section describes the DMABUF importer role API in V4L2.
+
+Input and output devices support the streaming I/O method when the
+V4L2_CAP_STREAMING flag in the
+capabilities field of &v4l2-capability; returned by
+the &VIDIOC-QUERYCAP; ioctl is set. Whether importing DMA buffers through
+DMABUF file descriptors is supported is determined by calling the
+&VIDIOC-REQBUFS; ioctl with the memory type set to
+V4L2_MEMORY_DMABUF.
+
+This I/O method is dedicated to sharing DMA buffers between different
+devices, which may be V4L devices or other video-related devices (e.g. DRM).
+Buffers (planes) are allocated by a driver on behalf of an application. Next,
+these buffers are exported to the application as file descriptors using an API
+which is specific for an allocator driver.  Only such file descriptor are
+exchanged. The descriptors and meta-information are passed in &v4l2-buffer; (or
+in &v4l2-plane; in the multi-planar API case).  The driver must be switched
+into DMABUF I/O mode by calling the &VIDIOC-REQBUFS; with the desired buffer
+type.
+
+
+  Initiating streaming I/O with DMABUF file descriptors
+
+  
+&v4l2-requestbuffers; reqbuf;
+
+memset(&reqbuf, 0, sizeof (reqbuf));
+reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+reqbuf.memory = V4L2_MEMORY_DMABUF;
+reqbuf.count = 1;
+
+if (ioctl(fd, &VIDIOC-REQBUFS;, &reqbuf) == -1) {
+   if (errno == EINVAL)
+   printf("Video capturing or DMABUF streaming is not 
supported\n");
+   else
+   perror("VIDIOC_REQBUFS");
+
+   exit(EXIT_FAILURE);
+}
+  
+
+
+The buffer (plane) file descriptor is passed on the fly with the
+&VIDIOC-QBUF; ioctl. In case of multiplanar buffers, every plane can be
+associated with a different DMABUF descriptor. Although buffers are commonly
+cycled, applications can pass a different DMABUF descriptor at each
+VIDIOC_QBUF call.
+
+
+  Queueing DMABUF using single plane API
+
+  
+int buffer_queue(int v4lfd, int index, int dmafd)
+{
+   &v4l2-buffer; buf;
+
+   memset(&buf, 0, sizeof buf);
+   buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+   buf.memory = V4L2_MEMORY_DMABUF;
+   buf.index = index;
+   buf.m.fd = dmafd;
+
+   if (ioctl(v4lfd, &VIDIOC-QBUF;, &buf) == -1) {
+   perror("VIDIOC_QBUF");
+   return -1;
+   }
+
+   return 0;
+}
+  
+
+
+
+  Queueing DMABUF using multi plane API
+
+  
+int buffer_queue_mp(int v4lfd, int index, int dmafd[], int n_pl

[PATCHv10 03/26] v4l: vb2: add support for shared buffer (dma_buf)

2012-10-10 Thread Tomasz Stanislawski
From: Sumit Semwal 

This patch adds support for DMABUF memory type in videobuf2. It calls relevant
APIs of dma_buf for v4l reqbuf / qbuf / dqbuf operations.

For this version, the support is for videobuf2 as a user of the shared buffer;
so the allocation of the buffer is done outside of V4L2. [A sample allocator of
dma-buf shared buffer is given at [1]]

[1]: Rob Clark's DRM:
   https://github.com/robclark/kernel-omap4/commits/drmplane-dmabuf

Signed-off-by: Tomasz Stanislawski 
   [original work in the PoC for buffer sharing]
Signed-off-by: Sumit Semwal 
Signed-off-by: Sumit Semwal 
Acked-by: Laurent Pinchart 
Acked-by: Hans Verkuil 
---
 drivers/media/v4l2-core/Kconfig  |1 +
 drivers/media/v4l2-core/videobuf2-core.c |  206 +-
 include/media/videobuf2-core.h   |   27 
 3 files changed, 231 insertions(+), 3 deletions(-)

diff --git a/drivers/media/v4l2-core/Kconfig b/drivers/media/v4l2-core/Kconfig
index 0c54e19..2e787cc 100644
--- a/drivers/media/v4l2-core/Kconfig
+++ b/drivers/media/v4l2-core/Kconfig
@@ -59,6 +59,7 @@ config VIDEOBUF_DVB
 
 # Used by drivers that need Videobuf2 modules
 config VIDEOBUF2_CORE
+   select DMA_SHARED_BUFFER
tristate
 
 config VIDEOBUF2_MEMOPS
diff --git a/drivers/media/v4l2-core/videobuf2-core.c 
b/drivers/media/v4l2-core/videobuf2-core.c
index 432df11..a51dad6 100644
--- a/drivers/media/v4l2-core/videobuf2-core.c
+++ b/drivers/media/v4l2-core/videobuf2-core.c
@@ -109,6 +109,36 @@ static void __vb2_buf_userptr_put(struct vb2_buffer *vb)
 }
 
 /**
+ * __vb2_plane_dmabuf_put() - release memory associated with
+ * a DMABUF shared plane
+ */
+static void __vb2_plane_dmabuf_put(struct vb2_queue *q, struct vb2_plane *p)
+{
+   if (!p->mem_priv)
+   return;
+
+   if (p->dbuf_mapped)
+   call_memop(q, unmap_dmabuf, p->mem_priv);
+
+   call_memop(q, detach_dmabuf, p->mem_priv);
+   dma_buf_put(p->dbuf);
+   memset(p, 0, sizeof(*p));
+}
+
+/**
+ * __vb2_buf_dmabuf_put() - release memory associated with
+ * a DMABUF shared buffer
+ */
+static void __vb2_buf_dmabuf_put(struct vb2_buffer *vb)
+{
+   struct vb2_queue *q = vb->vb2_queue;
+   unsigned int plane;
+
+   for (plane = 0; plane < vb->num_planes; ++plane)
+   __vb2_plane_dmabuf_put(q, &vb->planes[plane]);
+}
+
+/**
  * __setup_offsets() - setup unique offsets ("cookies") for every plane in
  * every buffer on the queue
  */
@@ -230,6 +260,8 @@ static void __vb2_free_mem(struct vb2_queue *q, unsigned 
int buffers)
/* Free MMAP buffers or release USERPTR buffers */
if (q->memory == V4L2_MEMORY_MMAP)
__vb2_buf_mem_free(vb);
+   else if (q->memory == V4L2_MEMORY_DMABUF)
+   __vb2_buf_dmabuf_put(vb);
else
__vb2_buf_userptr_put(vb);
}
@@ -362,6 +394,8 @@ static void __fill_v4l2_buffer(struct vb2_buffer *vb, 
struct v4l2_buffer *b)
b->m.offset = vb->v4l2_planes[0].m.mem_offset;
else if (q->memory == V4L2_MEMORY_USERPTR)
b->m.userptr = vb->v4l2_planes[0].m.userptr;
+   else if (q->memory == V4L2_MEMORY_DMABUF)
+   b->m.fd = vb->v4l2_planes[0].m.fd;
}
 
/*
@@ -454,13 +488,28 @@ static int __verify_mmap_ops(struct vb2_queue *q)
 }
 
 /**
+ * __verify_dmabuf_ops() - verify that all memory operations required for
+ * DMABUF queue type have been provided
+ */
+static int __verify_dmabuf_ops(struct vb2_queue *q)
+{
+   if (!(q->io_modes & VB2_DMABUF) || !q->mem_ops->attach_dmabuf ||
+   !q->mem_ops->detach_dmabuf  || !q->mem_ops->map_dmabuf ||
+   !q->mem_ops->unmap_dmabuf)
+   return -EINVAL;
+
+   return 0;
+}
+
+/**
  * __verify_memory_type() - Check whether the memory type and buffer type
  * passed to a buffer operation are compatible with the queue.
  */
 static int __verify_memory_type(struct vb2_queue *q,
enum v4l2_memory memory, enum v4l2_buf_type type)
 {
-   if (memory != V4L2_MEMORY_MMAP && memory != V4L2_MEMORY_USERPTR) {
+   if (memory != V4L2_MEMORY_MMAP && memory != V4L2_MEMORY_USERPTR &&
+   memory != V4L2_MEMORY_DMABUF) {
dprintk(1, "reqbufs: unsupported memory type\n");
return -EINVAL;
}
@@ -484,6 +533,11 @@ static int __verify_memory_type(struct vb2_queue *q,
return -EINVAL;
}
 
+   if (memory == V4L2_MEMORY_DMABUF && __verify_dmabuf_ops(q)) {
+   dprintk(1, "reqbufs: DMABUF for current setup unsupported\n");
+   return -EINVAL;
+   }
+
/*
 * Place the busy tests at the end: -EBUSY can be ignored when
  

[PATCHv10 04/26] v4l: vb: remove warnings about MEMORY_DMABUF

2012-10-10 Thread Tomasz Stanislawski
From: Sumit Semwal 

Adding DMABUF memory type causes videobuf to complain about not using it
in some switch cases. This patch removes these warnings.

Signed-off-by: Sumit Semwal 
Acked-by: Laurent Pinchart 
Acked-by: Hans Verkuil 
---
 drivers/media/v4l2-core/videobuf-core.c |4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/media/v4l2-core/videobuf-core.c 
b/drivers/media/v4l2-core/videobuf-core.c
index bf7a326..5449e8a 100644
--- a/drivers/media/v4l2-core/videobuf-core.c
+++ b/drivers/media/v4l2-core/videobuf-core.c
@@ -335,6 +335,9 @@ static void videobuf_status(struct videobuf_queue *q, 
struct v4l2_buffer *b,
case V4L2_MEMORY_OVERLAY:
b->m.offset  = vb->boff;
break;
+   case V4L2_MEMORY_DMABUF:
+   /* DMABUF is not handled in videobuf framework */
+   break;
}
 
b->flags= 0;
@@ -405,6 +408,7 @@ int __videobuf_mmap_setup(struct videobuf_queue *q,
break;
case V4L2_MEMORY_USERPTR:
case V4L2_MEMORY_OVERLAY:
+   case V4L2_MEMORY_DMABUF:
/* nothing */
break;
}
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv10 05/26] v4l: vb2-dma-contig: shorten vb2_dma_contig prefix to vb2_dc

2012-10-10 Thread Tomasz Stanislawski
From: Laurent Pinchart 

Signed-off-by: Laurent Pinchart 
Acked-by: Hans Verkuil 
---
 drivers/media/v4l2-core/videobuf2-dma-contig.c |   36 
 1 file changed, 18 insertions(+), 18 deletions(-)

diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c 
b/drivers/media/v4l2-core/videobuf2-dma-contig.c
index 4b71326..a05784f 100644
--- a/drivers/media/v4l2-core/videobuf2-dma-contig.c
+++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c
@@ -32,9 +32,9 @@ struct vb2_dc_buf {
struct vb2_vmarea_handler   handler;
 };
 
-static void vb2_dma_contig_put(void *buf_priv);
+static void vb2_dc_put(void *buf_priv);
 
-static void *vb2_dma_contig_alloc(void *alloc_ctx, unsigned long size)
+static void *vb2_dc_alloc(void *alloc_ctx, unsigned long size)
 {
struct vb2_dc_conf *conf = alloc_ctx;
struct vb2_dc_buf *buf;
@@ -56,7 +56,7 @@ static void *vb2_dma_contig_alloc(void *alloc_ctx, unsigned 
long size)
buf->size = size;
 
buf->handler.refcount = &buf->refcount;
-   buf->handler.put = vb2_dma_contig_put;
+   buf->handler.put = vb2_dc_put;
buf->handler.arg = buf;
 
atomic_inc(&buf->refcount);
@@ -64,7 +64,7 @@ static void *vb2_dma_contig_alloc(void *alloc_ctx, unsigned 
long size)
return buf;
 }
 
-static void vb2_dma_contig_put(void *buf_priv)
+static void vb2_dc_put(void *buf_priv)
 {
struct vb2_dc_buf *buf = buf_priv;
 
@@ -75,14 +75,14 @@ static void vb2_dma_contig_put(void *buf_priv)
}
 }
 
-static void *vb2_dma_contig_cookie(void *buf_priv)
+static void *vb2_dc_cookie(void *buf_priv)
 {
struct vb2_dc_buf *buf = buf_priv;
 
return &buf->dma_addr;
 }
 
-static void *vb2_dma_contig_vaddr(void *buf_priv)
+static void *vb2_dc_vaddr(void *buf_priv)
 {
struct vb2_dc_buf *buf = buf_priv;
if (!buf)
@@ -91,14 +91,14 @@ static void *vb2_dma_contig_vaddr(void *buf_priv)
return buf->vaddr;
 }
 
-static unsigned int vb2_dma_contig_num_users(void *buf_priv)
+static unsigned int vb2_dc_num_users(void *buf_priv)
 {
struct vb2_dc_buf *buf = buf_priv;
 
return atomic_read(&buf->refcount);
 }
 
-static int vb2_dma_contig_mmap(void *buf_priv, struct vm_area_struct *vma)
+static int vb2_dc_mmap(void *buf_priv, struct vm_area_struct *vma)
 {
struct vb2_dc_buf *buf = buf_priv;
 
@@ -111,7 +111,7 @@ static int vb2_dma_contig_mmap(void *buf_priv, struct 
vm_area_struct *vma)
  &vb2_common_vm_ops, &buf->handler);
 }
 
-static void *vb2_dma_contig_get_userptr(void *alloc_ctx, unsigned long vaddr,
+static void *vb2_dc_get_userptr(void *alloc_ctx, unsigned long vaddr,
unsigned long size, int write)
 {
struct vb2_dc_buf *buf;
@@ -138,7 +138,7 @@ static void *vb2_dma_contig_get_userptr(void *alloc_ctx, 
unsigned long vaddr,
return buf;
 }
 
-static void vb2_dma_contig_put_userptr(void *mem_priv)
+static void vb2_dc_put_userptr(void *mem_priv)
 {
struct vb2_dc_buf *buf = mem_priv;
 
@@ -150,14 +150,14 @@ static void vb2_dma_contig_put_userptr(void *mem_priv)
 }
 
 const struct vb2_mem_ops vb2_dma_contig_memops = {
-   .alloc  = vb2_dma_contig_alloc,
-   .put= vb2_dma_contig_put,
-   .cookie = vb2_dma_contig_cookie,
-   .vaddr  = vb2_dma_contig_vaddr,
-   .mmap   = vb2_dma_contig_mmap,
-   .get_userptr= vb2_dma_contig_get_userptr,
-   .put_userptr= vb2_dma_contig_put_userptr,
-   .num_users  = vb2_dma_contig_num_users,
+   .alloc  = vb2_dc_alloc,
+   .put= vb2_dc_put,
+   .cookie = vb2_dc_cookie,
+   .vaddr  = vb2_dc_vaddr,
+   .mmap   = vb2_dc_mmap,
+   .get_userptr= vb2_dc_get_userptr,
+   .put_userptr= vb2_dc_put_userptr,
+   .num_users  = vb2_dc_num_users,
 };
 EXPORT_SYMBOL_GPL(vb2_dma_contig_memops);
 
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv10 06/26] v4l: vb2-dma-contig: remove reference of alloc_ctx from a buffer

2012-10-10 Thread Tomasz Stanislawski
This patch removes a reference to alloc_ctx from an instance of a DMA
contiguous buffer. It helps to avoid a risk of a dangling pointer if the
context is released while the buffer is still valid. Moreover it removes one
dereference step while accessing a device structure.

Signed-off-by: Tomasz Stanislawski 
Signed-off-by: Kyungmin Park 
Acked-by: Laurent Pinchart 
Acked-by: Hans Verkuil 
---
 drivers/media/v4l2-core/videobuf2-dma-contig.c |   13 ++---
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c 
b/drivers/media/v4l2-core/videobuf2-dma-contig.c
index a05784f..20c95da 100644
--- a/drivers/media/v4l2-core/videobuf2-dma-contig.c
+++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c
@@ -23,7 +23,7 @@ struct vb2_dc_conf {
 };
 
 struct vb2_dc_buf {
-   struct vb2_dc_conf  *conf;
+   struct device   *dev;
void*vaddr;
dma_addr_t  dma_addr;
unsigned long   size;
@@ -37,22 +37,21 @@ static void vb2_dc_put(void *buf_priv);
 static void *vb2_dc_alloc(void *alloc_ctx, unsigned long size)
 {
struct vb2_dc_conf *conf = alloc_ctx;
+   struct device *dev = conf->dev;
struct vb2_dc_buf *buf;
 
buf = kzalloc(sizeof *buf, GFP_KERNEL);
if (!buf)
return ERR_PTR(-ENOMEM);
 
-   buf->vaddr = dma_alloc_coherent(conf->dev, size, &buf->dma_addr,
-   GFP_KERNEL);
+   buf->vaddr = dma_alloc_coherent(dev, size, &buf->dma_addr, GFP_KERNEL);
if (!buf->vaddr) {
-   dev_err(conf->dev, "dma_alloc_coherent of size %ld failed\n",
-   size);
+   dev_err(dev, "dma_alloc_coherent of size %ld failed\n", size);
kfree(buf);
return ERR_PTR(-ENOMEM);
}
 
-   buf->conf = conf;
+   buf->dev = dev;
buf->size = size;
 
buf->handler.refcount = &buf->refcount;
@@ -69,7 +68,7 @@ static void vb2_dc_put(void *buf_priv)
struct vb2_dc_buf *buf = buf_priv;
 
if (atomic_dec_and_test(&buf->refcount)) {
-   dma_free_coherent(buf->conf->dev, buf->size, buf->vaddr,
+   dma_free_coherent(buf->dev, buf->size, buf->vaddr,
  buf->dma_addr);
kfree(buf);
}
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv10 07/26] v4l: vb2-dma-contig: reorder functions

2012-10-10 Thread Tomasz Stanislawski
From: Laurent Pinchart 

Group functions by buffer type.

Signed-off-by: Laurent Pinchart 
Acked-by: Hans Verkuil 
---
 drivers/media/v4l2-core/videobuf2-dma-contig.c |   92 ++--
 1 file changed, 54 insertions(+), 38 deletions(-)

diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c 
b/drivers/media/v4l2-core/videobuf2-dma-contig.c
index 20c95da..daac2b2 100644
--- a/drivers/media/v4l2-core/videobuf2-dma-contig.c
+++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c
@@ -25,14 +25,56 @@ struct vb2_dc_conf {
 struct vb2_dc_buf {
struct device   *dev;
void*vaddr;
-   dma_addr_t  dma_addr;
unsigned long   size;
-   struct vm_area_struct   *vma;
-   atomic_trefcount;
+   dma_addr_t  dma_addr;
+
+   /* MMAP related */
struct vb2_vmarea_handler   handler;
+   atomic_trefcount;
+
+   /* USERPTR related */
+   struct vm_area_struct   *vma;
 };
 
-static void vb2_dc_put(void *buf_priv);
+/*/
+/* callbacks for all buffers */
+/*/
+
+static void *vb2_dc_cookie(void *buf_priv)
+{
+   struct vb2_dc_buf *buf = buf_priv;
+
+   return &buf->dma_addr;
+}
+
+static void *vb2_dc_vaddr(void *buf_priv)
+{
+   struct vb2_dc_buf *buf = buf_priv;
+
+   return buf->vaddr;
+}
+
+static unsigned int vb2_dc_num_users(void *buf_priv)
+{
+   struct vb2_dc_buf *buf = buf_priv;
+
+   return atomic_read(&buf->refcount);
+}
+
+/*/
+/*callbacks for MMAP buffers */
+/*/
+
+static void vb2_dc_put(void *buf_priv)
+{
+   struct vb2_dc_buf *buf = buf_priv;
+
+   if (!atomic_dec_and_test(&buf->refcount))
+   return;
+
+   dma_free_coherent(buf->dev, buf->size, buf->vaddr, buf->dma_addr);
+   kfree(buf);
+}
 
 static void *vb2_dc_alloc(void *alloc_ctx, unsigned long size)
 {
@@ -63,40 +105,6 @@ static void *vb2_dc_alloc(void *alloc_ctx, unsigned long 
size)
return buf;
 }
 
-static void vb2_dc_put(void *buf_priv)
-{
-   struct vb2_dc_buf *buf = buf_priv;
-
-   if (atomic_dec_and_test(&buf->refcount)) {
-   dma_free_coherent(buf->dev, buf->size, buf->vaddr,
- buf->dma_addr);
-   kfree(buf);
-   }
-}
-
-static void *vb2_dc_cookie(void *buf_priv)
-{
-   struct vb2_dc_buf *buf = buf_priv;
-
-   return &buf->dma_addr;
-}
-
-static void *vb2_dc_vaddr(void *buf_priv)
-{
-   struct vb2_dc_buf *buf = buf_priv;
-   if (!buf)
-   return NULL;
-
-   return buf->vaddr;
-}
-
-static unsigned int vb2_dc_num_users(void *buf_priv)
-{
-   struct vb2_dc_buf *buf = buf_priv;
-
-   return atomic_read(&buf->refcount);
-}
-
 static int vb2_dc_mmap(void *buf_priv, struct vm_area_struct *vma)
 {
struct vb2_dc_buf *buf = buf_priv;
@@ -110,6 +118,10 @@ static int vb2_dc_mmap(void *buf_priv, struct 
vm_area_struct *vma)
  &vb2_common_vm_ops, &buf->handler);
 }
 
+/*/
+/*   callbacks for USERPTR buffers   */
+/*/
+
 static void *vb2_dc_get_userptr(void *alloc_ctx, unsigned long vaddr,
unsigned long size, int write)
 {
@@ -148,6 +160,10 @@ static void vb2_dc_put_userptr(void *mem_priv)
kfree(buf);
 }
 
+/*/
+/*   DMA CONTIG exported functions   */
+/*/
+
 const struct vb2_mem_ops vb2_dma_contig_memops = {
.alloc  = vb2_dc_alloc,
.put= vb2_dc_put,
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv10 08/26] v4l: vb2-dma-contig: add support for scatterlist in userptr mode

2012-10-10 Thread Tomasz Stanislawski
This patch introduces usage of dma_map_sg to map memory behind
a userspace pointer to a device as dma-contiguous mapping.

This patch contains some of the code kindly provided by Marek Szyprowski
 and Kamil Debski  and Andrzej
Pietrasiewicz . Kind thanks for bug reports from Laurent
Pinchart  and Seung-Woo Kim
.

Signed-off-by: Tomasz Stanislawski 
Signed-off-by: Kyungmin Park 
Acked-by: Laurent Pinchart 
Acked-by: Hans Verkuil 
---
 drivers/media/v4l2-core/videobuf2-dma-contig.c |  226 ++--
 1 file changed, 210 insertions(+), 16 deletions(-)

diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c 
b/drivers/media/v4l2-core/videobuf2-dma-contig.c
index daac2b2..8486e06 100644
--- a/drivers/media/v4l2-core/videobuf2-dma-contig.c
+++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c
@@ -11,6 +11,8 @@
  */
 
 #include 
+#include 
+#include 
 #include 
 #include 
 
@@ -27,6 +29,8 @@ struct vb2_dc_buf {
void*vaddr;
unsigned long   size;
dma_addr_t  dma_addr;
+   enum dma_data_direction dma_dir;
+   struct sg_table *dma_sgt;
 
/* MMAP related */
struct vb2_vmarea_handler   handler;
@@ -37,6 +41,44 @@ struct vb2_dc_buf {
 };
 
 /*/
+/*scatterlist table functions*/
+/*/
+
+
+static void vb2_dc_sgt_foreach_page(struct sg_table *sgt,
+   void (*cb)(struct page *pg))
+{
+   struct scatterlist *s;
+   unsigned int i;
+
+   for_each_sg(sgt->sgl, s, sgt->orig_nents, i) {
+   struct page *page = sg_page(s);
+   unsigned int n_pages = PAGE_ALIGN(s->offset + s->length)
+   >> PAGE_SHIFT;
+   unsigned int j;
+
+   for (j = 0; j < n_pages; ++j, ++page)
+   cb(page);
+   }
+}
+
+static unsigned long vb2_dc_get_contiguous_size(struct sg_table *sgt)
+{
+   struct scatterlist *s;
+   dma_addr_t expected = sg_dma_address(sgt->sgl);
+   unsigned int i;
+   unsigned long size = 0;
+
+   for_each_sg(sgt->sgl, s, sgt->nents, i) {
+   if (sg_dma_address(s) != expected)
+   break;
+   expected = sg_dma_address(s) + sg_dma_len(s);
+   size += sg_dma_len(s);
+   }
+   return size;
+}
+
+/*/
 /* callbacks for all buffers */
 /*/
 
@@ -122,42 +164,194 @@ static int vb2_dc_mmap(void *buf_priv, struct 
vm_area_struct *vma)
 /*   callbacks for USERPTR buffers   */
 /*/
 
+static inline int vma_is_io(struct vm_area_struct *vma)
+{
+   return !!(vma->vm_flags & (VM_IO | VM_PFNMAP));
+}
+
+static int vb2_dc_get_user_pages(unsigned long start, struct page **pages,
+   int n_pages, struct vm_area_struct *vma, int write)
+{
+   if (vma_is_io(vma)) {
+   unsigned int i;
+
+   for (i = 0; i < n_pages; ++i, start += PAGE_SIZE) {
+   unsigned long pfn;
+   int ret = follow_pfn(vma, start, &pfn);
+
+   if (ret) {
+   pr_err("no page for address %lu\n", start);
+   return ret;
+   }
+   pages[i] = pfn_to_page(pfn);
+   }
+   } else {
+   int n;
+
+   n = get_user_pages(current, current->mm, start & PAGE_MASK,
+   n_pages, write, 1, pages, NULL);
+   /* negative error means that no page was pinned */
+   n = max(n, 0);
+   if (n != n_pages) {
+   pr_err("got only %d of %d user pages\n", n, n_pages);
+   while (n)
+   put_page(pages[--n]);
+   return -EFAULT;
+   }
+   }
+
+   return 0;
+}
+
+static void vb2_dc_put_dirty_page(struct page *page)
+{
+   set_page_dirty_lock(page);
+   put_page(page);
+}
+
+static void vb2_dc_put_userptr(void *buf_priv)
+{
+   struct vb2_dc_buf *buf = buf_priv;
+   struct sg_table *sgt = buf->dma_sgt;
+
+   dma_unmap_sg(buf->dev, sgt->sgl, sgt->orig_nents, buf->dma_dir);
+   if (!vma_is_io(buf->vma))
+   vb2_dc_sgt_foreach_page(sgt, vb2_dc_put_dirty_page);
+
+   sg_free_table(sgt);
+   kfree(sgt);
+   vb2_put_vma(buf->vma);
+   kfree(buf);
+}
+
 static void *vb2_dc_get_userptr(void *alloc_ctx, unsigned long vaddr,
-   unsigned long size, int write)
+   unsigned long size, int write)
 {
+   struct vb2_dc_conf *conf = alloc_ctx;
struct vb

[PATCHv10 09/26] v4l: vb2: add prepare/finish callbacks to allocators

2012-10-10 Thread Tomasz Stanislawski
From: Marek Szyprowski 

This patch adds support for prepare/finish callbacks in VB2 allocators. These
callback are used for buffer flushing.

Signed-off-by: Marek Szyprowski 
Acked-by: Laurent Pinchart 
Acked-by: Hans Verkuil 
---
 drivers/media/v4l2-core/videobuf2-core.c |   11 +++
 include/media/videobuf2-core.h   |7 +++
 2 files changed, 18 insertions(+)

diff --git a/drivers/media/v4l2-core/videobuf2-core.c 
b/drivers/media/v4l2-core/videobuf2-core.c
index a51dad6..613dea1 100644
--- a/drivers/media/v4l2-core/videobuf2-core.c
+++ b/drivers/media/v4l2-core/videobuf2-core.c
@@ -844,6 +844,7 @@ void vb2_buffer_done(struct vb2_buffer *vb, enum 
vb2_buffer_state state)
 {
struct vb2_queue *q = vb->vb2_queue;
unsigned long flags;
+   unsigned int plane;
 
if (vb->state != VB2_BUF_STATE_ACTIVE)
return;
@@ -854,6 +855,10 @@ void vb2_buffer_done(struct vb2_buffer *vb, enum 
vb2_buffer_state state)
dprintk(4, "Done processing on buffer %d, state: %d\n",
vb->v4l2_buf.index, vb->state);
 
+   /* sync buffers */
+   for (plane = 0; plane < vb->num_planes; ++plane)
+   call_memop(q, finish, vb->planes[plane].mem_priv);
+
/* Add the buffer to the done buffers list */
spin_lock_irqsave(&q->done_lock, flags);
vb->state = state;
@@ -1136,9 +1141,15 @@ err:
 static void __enqueue_in_driver(struct vb2_buffer *vb)
 {
struct vb2_queue *q = vb->vb2_queue;
+   unsigned int plane;
 
vb->state = VB2_BUF_STATE_ACTIVE;
atomic_inc(&q->queued_count);
+
+   /* sync buffers */
+   for (plane = 0; plane < vb->num_planes; ++plane)
+   call_memop(q, prepare, vb->planes[plane].mem_priv);
+
q->ops->buf_queue(vb);
 }
 
diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h
index 689ae4a..24b9c90 100644
--- a/include/media/videobuf2-core.h
+++ b/include/media/videobuf2-core.h
@@ -56,6 +56,10 @@ struct vb2_fileio_data;
  * dmabuf
  * @unmap_dmabuf: releases access control to the dmabuf - allocator is notified
  *   that this driver is done using the dmabuf for now
+ * @prepare:   called every time the buffer is passed from userspace to the
+ * driver, useful for cache synchronisation, optional
+ * @finish:called every time the buffer is passed back from the driver
+ * to the userspace, also optional
  * @vaddr: return a kernel virtual address to a given memory buffer
  * associated with the passed private structure or NULL if no
  * such mapping exists
@@ -82,6 +86,9 @@ struct vb2_mem_ops {
unsigned long size, int write);
void(*put_userptr)(void *buf_priv);
 
+   void(*prepare)(void *buf_priv);
+   void(*finish)(void *buf_priv);
+
void*(*attach_dmabuf)(void *alloc_ctx, struct dma_buf *dbuf,
unsigned long size, int write);
void(*detach_dmabuf)(void *buf_priv);
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv10 10/26] v4l: vb2-dma-contig: add prepare/finish to dma-contig allocator

2012-10-10 Thread Tomasz Stanislawski
From: Marek Szyprowski 

Add prepare/finish callbacks to vb2-dma-contig allocator.

Signed-off-by: Marek Szyprowski 
Acked-by: Laurent Pinchart 
Acked-by: Hans Verkuil 
---
 drivers/media/v4l2-core/videobuf2-dma-contig.c |   24 
 1 file changed, 24 insertions(+)

diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c 
b/drivers/media/v4l2-core/videobuf2-dma-contig.c
index 8486e06..494a824 100644
--- a/drivers/media/v4l2-core/videobuf2-dma-contig.c
+++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c
@@ -103,6 +103,28 @@ static unsigned int vb2_dc_num_users(void *buf_priv)
return atomic_read(&buf->refcount);
 }
 
+static void vb2_dc_prepare(void *buf_priv)
+{
+   struct vb2_dc_buf *buf = buf_priv;
+   struct sg_table *sgt = buf->dma_sgt;
+
+   if (!sgt)
+   return;
+
+   dma_sync_sg_for_device(buf->dev, sgt->sgl, sgt->nents, buf->dma_dir);
+}
+
+static void vb2_dc_finish(void *buf_priv)
+{
+   struct vb2_dc_buf *buf = buf_priv;
+   struct sg_table *sgt = buf->dma_sgt;
+
+   if (!sgt)
+   return;
+
+   dma_sync_sg_for_cpu(buf->dev, sgt->sgl, sgt->nents, buf->dma_dir);
+}
+
 /*/
 /*callbacks for MMAP buffers */
 /*/
@@ -366,6 +388,8 @@ const struct vb2_mem_ops vb2_dma_contig_memops = {
.mmap   = vb2_dc_mmap,
.get_userptr= vb2_dc_get_userptr,
.put_userptr= vb2_dc_put_userptr,
+   .prepare= vb2_dc_prepare,
+   .finish = vb2_dc_finish,
.num_users  = vb2_dc_num_users,
 };
 EXPORT_SYMBOL_GPL(vb2_dma_contig_memops);
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv10 11/26] v4l: vb2-dma-contig: add support for dma_buf importing

2012-10-10 Thread Tomasz Stanislawski
From: Sumit Semwal 

This patch makes changes for adding dma-contig as a dma_buf user. It provides
function implementations for the {attach, detach, map, unmap}_dmabuf()
mem_ops of DMABUF memory type.

Signed-off-by: Sumit Semwal 
Signed-off-by: Sumit Semwal 
[author of the original patch]
Signed-off-by: Tomasz Stanislawski 
[integration with refactored dma-contig allocator]
Acked-by: Laurent Pinchart 
---
 drivers/media/v4l2-core/Kconfig|1 +
 drivers/media/v4l2-core/videobuf2-dma-contig.c |  120 +++-
 2 files changed, 119 insertions(+), 2 deletions(-)

diff --git a/drivers/media/v4l2-core/Kconfig b/drivers/media/v4l2-core/Kconfig
index 2e787cc..e30583b 100644
--- a/drivers/media/v4l2-core/Kconfig
+++ b/drivers/media/v4l2-core/Kconfig
@@ -69,6 +69,7 @@ config VIDEOBUF2_DMA_CONTIG
tristate
select VIDEOBUF2_CORE
select VIDEOBUF2_MEMOPS
+   select DMA_SHARED_BUFFER
 
 config VIDEOBUF2_VMALLOC
tristate
diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c 
b/drivers/media/v4l2-core/videobuf2-dma-contig.c
index 494a824..a5804cf 100644
--- a/drivers/media/v4l2-core/videobuf2-dma-contig.c
+++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c
@@ -10,6 +10,7 @@
  * the Free Software Foundation.
  */
 
+#include 
 #include 
 #include 
 #include 
@@ -38,6 +39,9 @@ struct vb2_dc_buf {
 
/* USERPTR related */
struct vm_area_struct   *vma;
+
+   /* DMABUF related */
+   struct dma_buf_attachment   *db_attach;
 };
 
 /*/
@@ -108,7 +112,8 @@ static void vb2_dc_prepare(void *buf_priv)
struct vb2_dc_buf *buf = buf_priv;
struct sg_table *sgt = buf->dma_sgt;
 
-   if (!sgt)
+   /* DMABUF exporter will flush the cache for us */
+   if (!sgt || buf->db_attach)
return;
 
dma_sync_sg_for_device(buf->dev, sgt->sgl, sgt->nents, buf->dma_dir);
@@ -119,7 +124,8 @@ static void vb2_dc_finish(void *buf_priv)
struct vb2_dc_buf *buf = buf_priv;
struct sg_table *sgt = buf->dma_sgt;
 
-   if (!sgt)
+   /* DMABUF exporter will flush the cache for us */
+   if (!sgt || buf->db_attach)
return;
 
dma_sync_sg_for_cpu(buf->dev, sgt->sgl, sgt->nents, buf->dma_dir);
@@ -377,6 +383,112 @@ fail_buf:
 }
 
 /*/
+/*   callbacks for DMABUF buffers*/
+/*/
+
+static int vb2_dc_map_dmabuf(void *mem_priv)
+{
+   struct vb2_dc_buf *buf = mem_priv;
+   struct sg_table *sgt;
+   unsigned long contig_size;
+
+   if (WARN_ON(!buf->db_attach)) {
+   pr_err("trying to pin a non attached buffer\n");
+   return -EINVAL;
+   }
+
+   if (WARN_ON(buf->dma_sgt)) {
+   pr_err("dmabuf buffer is already pinned\n");
+   return 0;
+   }
+
+   /* get the associated scatterlist for this buffer */
+   sgt = dma_buf_map_attachment(buf->db_attach, buf->dma_dir);
+   if (IS_ERR_OR_NULL(sgt)) {
+   pr_err("Error getting dmabuf scatterlist\n");
+   return -EINVAL;
+   }
+
+   /* checking if dmabuf is big enough to store contiguous chunk */
+   contig_size = vb2_dc_get_contiguous_size(sgt);
+   if (contig_size < buf->size) {
+   pr_err("contiguous chunk is too small %lu/%lu b\n",
+   contig_size, buf->size);
+   dma_buf_unmap_attachment(buf->db_attach, sgt, buf->dma_dir);
+   return -EFAULT;
+   }
+
+   buf->dma_addr = sg_dma_address(sgt->sgl);
+   buf->dma_sgt = sgt;
+
+   return 0;
+}
+
+static void vb2_dc_unmap_dmabuf(void *mem_priv)
+{
+   struct vb2_dc_buf *buf = mem_priv;
+   struct sg_table *sgt = buf->dma_sgt;
+
+   if (WARN_ON(!buf->db_attach)) {
+   pr_err("trying to unpin a not attached buffer\n");
+   return;
+   }
+
+   if (WARN_ON(!sgt)) {
+   pr_err("dmabuf buffer is already unpinned\n");
+   return;
+   }
+
+   dma_buf_unmap_attachment(buf->db_attach, sgt, buf->dma_dir);
+
+   buf->dma_addr = 0;
+   buf->dma_sgt = NULL;
+}
+
+static void vb2_dc_detach_dmabuf(void *mem_priv)
+{
+   struct vb2_dc_buf *buf = mem_priv;
+
+   /* if vb2 works correctly you should never detach mapped buffer */
+   if (WARN_ON(buf->dma_addr))
+   vb2_dc_unmap_dmabuf(buf);
+
+   /* detach this attachment */
+   dma_buf_detach(buf->db_attach->dmabuf, buf->db_attach);
+   kfree(buf);
+}
+
+static void *vb2_dc_attach_dmabuf(void *alloc_ctx, struct dma_buf *dbuf,
+   unsigned long size, int write)
+{
+   struct vb2_dc_conf *conf = alloc_ct

[PATCHv10 12/26] v4l: vb2-vmalloc: add support for dmabuf importing

2012-10-10 Thread Tomasz Stanislawski
This patch adds support for importing DMABUF files for
vmalloc allocator in Videobuf2.

Signed-off-by: Tomasz Stanislawski 
Signed-off-by: Kyungmin Park 
Acked-by: Laurent Pinchart 
Acked-by: Hans Verkuil 
---
 drivers/media/v4l2-core/Kconfig |1 +
 drivers/media/v4l2-core/videobuf2-vmalloc.c |   56 +++
 2 files changed, 57 insertions(+)

diff --git a/drivers/media/v4l2-core/Kconfig b/drivers/media/v4l2-core/Kconfig
index e30583b..65875c3 100644
--- a/drivers/media/v4l2-core/Kconfig
+++ b/drivers/media/v4l2-core/Kconfig
@@ -75,6 +75,7 @@ config VIDEOBUF2_VMALLOC
tristate
select VIDEOBUF2_CORE
select VIDEOBUF2_MEMOPS
+   select DMA_SHARED_BUFFER
 
 config VIDEOBUF2_DMA_SG
tristate
diff --git a/drivers/media/v4l2-core/videobuf2-vmalloc.c 
b/drivers/media/v4l2-core/videobuf2-vmalloc.c
index 94efa04..a47fd4f 100644
--- a/drivers/media/v4l2-core/videobuf2-vmalloc.c
+++ b/drivers/media/v4l2-core/videobuf2-vmalloc.c
@@ -30,6 +30,7 @@ struct vb2_vmalloc_buf {
unsigned intn_pages;
atomic_trefcount;
struct vb2_vmarea_handler   handler;
+   struct dma_buf  *dbuf;
 };
 
 static void vb2_vmalloc_put(void *buf_priv);
@@ -207,11 +208,66 @@ static int vb2_vmalloc_mmap(void *buf_priv, struct 
vm_area_struct *vma)
return 0;
 }
 
+/*/
+/*   callbacks for DMABUF buffers*/
+/*/
+
+static int vb2_vmalloc_map_dmabuf(void *mem_priv)
+{
+   struct vb2_vmalloc_buf *buf = mem_priv;
+
+   buf->vaddr = dma_buf_vmap(buf->dbuf);
+
+   return buf->vaddr ? 0 : -EFAULT;
+}
+
+static void vb2_vmalloc_unmap_dmabuf(void *mem_priv)
+{
+   struct vb2_vmalloc_buf *buf = mem_priv;
+
+   dma_buf_vunmap(buf->dbuf, buf->vaddr);
+   buf->vaddr = NULL;
+}
+
+static void vb2_vmalloc_detach_dmabuf(void *mem_priv)
+{
+   struct vb2_vmalloc_buf *buf = mem_priv;
+
+   if (buf->vaddr)
+   dma_buf_vunmap(buf->dbuf, buf->vaddr);
+
+   kfree(buf);
+}
+
+static void *vb2_vmalloc_attach_dmabuf(void *alloc_ctx, struct dma_buf *dbuf,
+   unsigned long size, int write)
+{
+   struct vb2_vmalloc_buf *buf;
+
+   if (dbuf->size < size)
+   return ERR_PTR(-EFAULT);
+
+   buf = kzalloc(sizeof(*buf), GFP_KERNEL);
+   if (!buf)
+   return ERR_PTR(-ENOMEM);
+
+   buf->dbuf = dbuf;
+   buf->write = write;
+   buf->size = size;
+
+   return buf;
+}
+
+
 const struct vb2_mem_ops vb2_vmalloc_memops = {
.alloc  = vb2_vmalloc_alloc,
.put= vb2_vmalloc_put,
.get_userptr= vb2_vmalloc_get_userptr,
.put_userptr= vb2_vmalloc_put_userptr,
+   .map_dmabuf = vb2_vmalloc_map_dmabuf,
+   .unmap_dmabuf   = vb2_vmalloc_unmap_dmabuf,
+   .attach_dmabuf  = vb2_vmalloc_attach_dmabuf,
+   .detach_dmabuf  = vb2_vmalloc_detach_dmabuf,
.vaddr  = vb2_vmalloc_vaddr,
.mmap   = vb2_vmalloc_mmap,
.num_users  = vb2_vmalloc_num_users,
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv10 13/26] v4l: vivi: support for dmabuf importing

2012-10-10 Thread Tomasz Stanislawski
This patch enhances VIVI driver with a support for importing a buffer
from DMABUF file descriptors.

Signed-off-by: Tomasz Stanislawski 
Signed-off-by: Kyungmin Park 
Acked-by: Hans Verkuil 
---
 drivers/media/platform/vivi.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/media/platform/vivi.c b/drivers/media/platform/vivi.c
index b366b05..9e077bb 100644
--- a/drivers/media/platform/vivi.c
+++ b/drivers/media/platform/vivi.c
@@ -1308,7 +1308,7 @@ static int __init vivi_create_instance(int inst)
/* initialize queue */
q = &dev->vb_vidq;
q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-   q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ;
+   q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF | VB2_READ;
q->drv_priv = dev;
q->buf_struct_size = sizeof(struct vivi_buffer);
q->ops = &vivi_video_qops;
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv10 14/26] v4l: s5p-tv: mixer: support for dmabuf importing

2012-10-10 Thread Tomasz Stanislawski
This patch enhances s5p-tv with support for DMABUF importing via
V4L2_MEMORY_DMABUF memory type.

Signed-off-by: Tomasz Stanislawski 
Signed-off-by: Kyungmin Park 
Acked-by: Hans Verkuil 
---
 drivers/media/platform/s5p-tv/mixer_video.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/media/platform/s5p-tv/mixer_video.c 
b/drivers/media/platform/s5p-tv/mixer_video.c
index 0c1cd89..2421e527 100644
--- a/drivers/media/platform/s5p-tv/mixer_video.c
+++ b/drivers/media/platform/s5p-tv/mixer_video.c
@@ -1093,7 +1093,7 @@ struct mxr_layer *mxr_base_layer_create(struct mxr_device 
*mdev,
 
layer->vb_queue = (struct vb2_queue) {
.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
-   .io_modes = VB2_MMAP | VB2_USERPTR,
+   .io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF,
.drv_priv = layer,
.buf_struct_size = sizeof(struct mxr_buffer),
.ops = &mxr_video_qops,
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv10 15/26] v4l: s5p-fimc: support for dmabuf importing

2012-10-10 Thread Tomasz Stanislawski
This patch enhances s5p-fimc with support for DMABUF importing via
V4L2_MEMORY_DMABUF memory type.

Signed-off-by: Tomasz Stanislawski 
Signed-off-by: Kyungmin Park 
Acked-by: Sylwester Nawrocki 
Acked-by: Hans Verkuil 
---
 drivers/media/platform/s5p-fimc/fimc-capture.c |2 +-
 drivers/media/platform/s5p-fimc/fimc-m2m.c |4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/media/platform/s5p-fimc/fimc-capture.c 
b/drivers/media/platform/s5p-fimc/fimc-capture.c
index 367efd1..246bb32 100644
--- a/drivers/media/platform/s5p-fimc/fimc-capture.c
+++ b/drivers/media/platform/s5p-fimc/fimc-capture.c
@@ -1730,7 +1730,7 @@ static int fimc_register_capture_device(struct fimc_dev 
*fimc,
q = &fimc->vid_cap.vbq;
memset(q, 0, sizeof(*q));
q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
-   q->io_modes = VB2_MMAP | VB2_USERPTR;
+   q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
q->drv_priv = fimc->vid_cap.ctx;
q->ops = &fimc_capture_qops;
q->mem_ops = &vb2_dma_contig_memops;
diff --git a/drivers/media/platform/s5p-fimc/fimc-m2m.c 
b/drivers/media/platform/s5p-fimc/fimc-m2m.c
index 4500e44..17067a7 100644
--- a/drivers/media/platform/s5p-fimc/fimc-m2m.c
+++ b/drivers/media/platform/s5p-fimc/fimc-m2m.c
@@ -622,7 +622,7 @@ static int queue_init(void *priv, struct vb2_queue *src_vq,
int ret;
 
src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
-   src_vq->io_modes = VB2_MMAP | VB2_USERPTR;
+   src_vq->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
src_vq->drv_priv = ctx;
src_vq->ops = &fimc_qops;
src_vq->mem_ops = &vb2_dma_contig_memops;
@@ -633,7 +633,7 @@ static int queue_init(void *priv, struct vb2_queue *src_vq,
return ret;
 
dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
-   dst_vq->io_modes = VB2_MMAP | VB2_USERPTR;
+   dst_vq->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
dst_vq->drv_priv = ctx;
dst_vq->ops = &fimc_qops;
dst_vq->mem_ops = &vb2_dma_contig_memops;
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv10 16/26] v4l: vb2-dma-contig: let mmap method to use dma_mmap_coherent call

2012-10-10 Thread Tomasz Stanislawski
From: Marek Szyprowski 

Let mmap method to use dma_mmap_coherent call.  Moreover, this patch removes
vb2_mmap_pfn_range from videobuf2 helpers as it was suggested by Laurent
Pinchart.  The function is no longer used in vb2 code.

Signed-off-by: Marek Szyprowski 
Signed-off-by: Tomasz Stanislawski 
Acked-by: Laurent Pinchart 
Acked-by: Hans Verkuil 
---
 drivers/media/v4l2-core/videobuf2-dma-contig.c |   28 +++--
 drivers/media/v4l2-core/videobuf2-memops.c |   40 
 include/media/videobuf2-memops.h   |5 ---
 3 files changed, 26 insertions(+), 47 deletions(-)

diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c 
b/drivers/media/v4l2-core/videobuf2-dma-contig.c
index a5804cf..0e065ce 100644
--- a/drivers/media/v4l2-core/videobuf2-dma-contig.c
+++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c
@@ -178,14 +178,38 @@ static void *vb2_dc_alloc(void *alloc_ctx, unsigned long 
size)
 static int vb2_dc_mmap(void *buf_priv, struct vm_area_struct *vma)
 {
struct vb2_dc_buf *buf = buf_priv;
+   int ret;
 
if (!buf) {
printk(KERN_ERR "No buffer to map\n");
return -EINVAL;
}
 
-   return vb2_mmap_pfn_range(vma, buf->dma_addr, buf->size,
- &vb2_common_vm_ops, &buf->handler);
+   /*
+* dma_mmap_* uses vm_pgoff as in-buffer offset, but we want to
+* map whole buffer
+*/
+   vma->vm_pgoff = 0;
+
+   ret = dma_mmap_coherent(buf->dev, vma, buf->vaddr,
+   buf->dma_addr, buf->size);
+
+   if (ret) {
+   pr_err("Remapping memory failed, error: %d\n", ret);
+   return ret;
+   }
+
+   vma->vm_flags   |= VM_DONTEXPAND | VM_RESERVED;
+   vma->vm_private_data= &buf->handler;
+   vma->vm_ops = &vb2_common_vm_ops;
+
+   vma->vm_ops->open(vma);
+
+   pr_debug("%s: mapped dma addr 0x%08lx at 0x%08lx, size %ld\n",
+   __func__, (unsigned long)buf->dma_addr, vma->vm_start,
+   buf->size);
+
+   return 0;
 }
 
 /*/
diff --git a/drivers/media/v4l2-core/videobuf2-memops.c 
b/drivers/media/v4l2-core/videobuf2-memops.c
index 504cd4c..81c1ad8 100644
--- a/drivers/media/v4l2-core/videobuf2-memops.c
+++ b/drivers/media/v4l2-core/videobuf2-memops.c
@@ -137,46 +137,6 @@ int vb2_get_contig_userptr(unsigned long vaddr, unsigned 
long size,
 EXPORT_SYMBOL_GPL(vb2_get_contig_userptr);
 
 /**
- * vb2_mmap_pfn_range() - map physical pages to userspace
- * @vma:   virtual memory region for the mapping
- * @paddr: starting physical address of the memory to be mapped
- * @size:  size of the memory to be mapped
- * @vm_ops:vm operations to be assigned to the created area
- * @priv:  private data to be associated with the area
- *
- * Returns 0 on success.
- */
-int vb2_mmap_pfn_range(struct vm_area_struct *vma, unsigned long paddr,
-   unsigned long size,
-   const struct vm_operations_struct *vm_ops,
-   void *priv)
-{
-   int ret;
-
-   size = min_t(unsigned long, vma->vm_end - vma->vm_start, size);
-
-   vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
-   ret = remap_pfn_range(vma, vma->vm_start, paddr >> PAGE_SHIFT,
-   size, vma->vm_page_prot);
-   if (ret) {
-   printk(KERN_ERR "Remapping memory failed, error: %d\n", ret);
-   return ret;
-   }
-
-   vma->vm_flags   |= VM_DONTEXPAND | VM_RESERVED;
-   vma->vm_private_data= priv;
-   vma->vm_ops = vm_ops;
-
-   vma->vm_ops->open(vma);
-
-   pr_debug("%s: mapped paddr 0x%08lx at 0x%08lx, size %ld\n",
-   __func__, paddr, vma->vm_start, size);
-
-   return 0;
-}
-EXPORT_SYMBOL_GPL(vb2_mmap_pfn_range);
-
-/**
  * vb2_common_vm_open() - increase refcount of the vma
  * @vma:   virtual memory region for the mapping
  *
diff --git a/include/media/videobuf2-memops.h b/include/media/videobuf2-memops.h
index 84e1f6c..f05444c 100644
--- a/include/media/videobuf2-memops.h
+++ b/include/media/videobuf2-memops.h
@@ -33,11 +33,6 @@ extern const struct vm_operations_struct vb2_common_vm_ops;
 int vb2_get_contig_userptr(unsigned long vaddr, unsigned long size,
   struct vm_area_struct **res_vma, dma_addr_t *res_pa);
 
-int vb2_mmap_pfn_range(struct vm_area_struct *vma, unsigned long paddr,
-   unsigned long size,
-   const struct vm_operations_struct *vm_ops,
-   void *priv);
-
 struct vm_area_struct *vb2_get_vma(struct vm_area_struct *vma);
 voi

[PATCHv10 17/26] Documentation: media: description of DMABUF exporting in V4L2

2012-10-10 Thread Tomasz Stanislawski
This patch adds description and usage examples for exporting
DMABUF file descriptor in V4L2.

Signed-off-by: Tomasz Stanislawski 
Signed-off-by: Kyungmin Park 
CC: linux-...@vger.kernel.org
---
 Documentation/DocBook/media/v4l/compat.xml|3 +
 Documentation/DocBook/media/v4l/io.xml|3 +
 Documentation/DocBook/media/v4l/v4l2.xml  |1 +
 Documentation/DocBook/media/v4l/vidioc-expbuf.xml |  212 +
 4 files changed, 219 insertions(+)
 create mode 100644 Documentation/DocBook/media/v4l/vidioc-expbuf.xml

diff --git a/Documentation/DocBook/media/v4l/compat.xml 
b/Documentation/DocBook/media/v4l/compat.xml
index 50eb630..3dd9e78 100644
--- a/Documentation/DocBook/media/v4l/compat.xml
+++ b/Documentation/DocBook/media/v4l/compat.xml
@@ -2590,6 +2590,9 @@ ioctls.
  Importing DMABUF file descriptors as a new IO method described
  in .
 
+
+ Exporting DMABUF files using &VIDIOC-EXPBUF; ioctl.
+
   
 
 
diff --git a/Documentation/DocBook/media/v4l/io.xml 
b/Documentation/DocBook/media/v4l/io.xml
index 0abb5cb..81d0ed4 100644
--- a/Documentation/DocBook/media/v4l/io.xml
+++ b/Documentation/DocBook/media/v4l/io.xml
@@ -488,6 +488,9 @@ DMA buffer from userspace using a file descriptor 
previously exported for a
 different or the same device (known as the importer role), or both. This
 section describes the DMABUF importer role API in V4L2.
 
+Refer to  DMABUF exporting  for
+details about exporting V4L2 buffers as DMABUF file descriptors.
+
 Input and output devices support the streaming I/O method when the
 V4L2_CAP_STREAMING flag in the
 capabilities field of &v4l2-capability; returned by
diff --git a/Documentation/DocBook/media/v4l/v4l2.xml 
b/Documentation/DocBook/media/v4l/v4l2.xml
index 10ccde9..4d110b1 100644
--- a/Documentation/DocBook/media/v4l/v4l2.xml
+++ b/Documentation/DocBook/media/v4l/v4l2.xml
@@ -543,6 +543,7 @@ and discussions on the V4L mailing list.
 &sub-enuminput;
 &sub-enumoutput;
 &sub-enumstd;
+&sub-expbuf;
 &sub-g-audio;
 &sub-g-audioout;
 &sub-g-crop;
diff --git a/Documentation/DocBook/media/v4l/vidioc-expbuf.xml 
b/Documentation/DocBook/media/v4l/vidioc-expbuf.xml
new file mode 100644
index 000..72dfbd2
--- /dev/null
+++ b/Documentation/DocBook/media/v4l/vidioc-expbuf.xml
@@ -0,0 +1,212 @@
+
+
+  
+ioctl VIDIOC_EXPBUF
+&manvol;
+  
+
+  
+VIDIOC_EXPBUF
+Export a buffer as a DMABUF file descriptor.
+  
+
+  
+
+  
+   int ioctl
+   int fd
+   int request
+   struct v4l2_exportbuffer 
*argp
+  
+
+  
+
+  
+Arguments
+
+
+  
+   fd
+   
+ &fd;
+   
+  
+  
+   request
+   
+ VIDIOC_EXPBUF
+   
+  
+  
+   argp
+   
+ 
+   
+  
+
+  
+
+  
+Description
+
+
+  Experimental
+  This is an  experimental 
+  interface and may change in the future.
+
+
+This ioctl is an extension to the memory
+mapping I/O method, therefore it is available only for
+V4L2_MEMORY_MMAP buffers.  It can be used to export a
+buffer as a DMABUF file at any time after buffers have been allocated with the
+&VIDIOC-REQBUFS; ioctl.
+
+ To export a buffer, applications fill &v4l2-exportbuffer;.  The
+ type  field is set to the same buffer type as was
+previously used with  &v4l2-requestbuffers; type .
+Applications must also set the  index  field. Valid
+index numbers range from zero to the number of buffers allocated with
+&VIDIOC-REQBUFS; (&v4l2-requestbuffers; count )
+minus one.  For the multi-planar API, applications set the  plane
+ field to the index of the plane to be exported. Valid planes
+range from zero to the maximal number of valid planes for the currently active
+format. For the single-planar API, applications must set  plane
+ to zero.  Additional flags may be posted in the 
+flags  field.  Refer to a manual for open() for details.
+Currently only O_CLOEXEC is supported.  All other fields must be set to zero.
+In the case of multi-planar API, every plane is exported separately using
+multiple  VIDIOC_EXPBUF  calls. 
+
+ After calling VIDIOC_EXPBUF the  fd
+ field will be set by a driver.  This is a DMABUF file
+descriptor. The application may pass it to other DMABUF-aware devices. Refer to
+DMABUF importing for details about importing
+DMABUF files into V4L2 nodes. It is recommended to close a DMABUF file when it
+is no longer used to allow the associated memory to be reclaimed. 
+
+  
+  
+   
+  Examples
+
+  
+   Exporting a buffer.
+   
+int buffer_export(int v4lfd, &v4l2-buf-type; bt, int index, int *dmafd)
+{
+   &v4l2-exportbuffer; expbuf;
+
+   memset(&expbuf, 0, sizeof(expbuf));
+   expbuf.type = bt;
+   expbuf.index = index;
+   if (ioctl(v4lfd, &VIDIOC-EXPBUF;, &

[PATCHv10 18/26] v4l: add buffer exporting via dmabuf

2012-10-10 Thread Tomasz Stanislawski
This patch adds extension to V4L2 api. It allow to export a mmap buffer as file
descriptor. New ioctl VIDIOC_EXPBUF is added. It takes a buffer offset used by
mmap and return a file descriptor on success.

Signed-off-by: Tomasz Stanislawski 
Signed-off-by: Kyungmin Park 
---
 drivers/media/v4l2-core/v4l2-compat-ioctl32.c |1 +
 drivers/media/v4l2-core/v4l2-dev.c|1 +
 drivers/media/v4l2-core/v4l2-ioctl.c  |   10 +
 include/linux/videodev2.h |   28 +
 include/media/v4l2-ioctl.h|2 ++
 5 files changed, 42 insertions(+)

diff --git a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c 
b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
index cc5998b..7157af3 100644
--- a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
+++ b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
@@ -1018,6 +1018,7 @@ long v4l2_compat_ioctl32(struct file *file, unsigned int 
cmd, unsigned long arg)
case VIDIOC_S_FBUF32:
case VIDIOC_OVERLAY32:
case VIDIOC_QBUF32:
+   case VIDIOC_EXPBUF:
case VIDIOC_DQBUF32:
case VIDIOC_STREAMON32:
case VIDIOC_STREAMOFF32:
diff --git a/drivers/media/v4l2-core/v4l2-dev.c 
b/drivers/media/v4l2-core/v4l2-dev.c
index a2df842..98dcad9 100644
--- a/drivers/media/v4l2-core/v4l2-dev.c
+++ b/drivers/media/v4l2-core/v4l2-dev.c
@@ -571,6 +571,7 @@ static void determine_valid_ioctls(struct video_device 
*vdev)
SET_VALID_IOCTL(ops, VIDIOC_REQBUFS, vidioc_reqbufs);
SET_VALID_IOCTL(ops, VIDIOC_QUERYBUF, vidioc_querybuf);
SET_VALID_IOCTL(ops, VIDIOC_QBUF, vidioc_qbuf);
+   SET_VALID_IOCTL(ops, VIDIOC_EXPBUF, vidioc_expbuf);
SET_VALID_IOCTL(ops, VIDIOC_DQBUF, vidioc_dqbuf);
SET_VALID_IOCTL(ops, VIDIOC_STREAMON, vidioc_streamon);
SET_VALID_IOCTL(ops, VIDIOC_STREAMOFF, vidioc_streamoff);
diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c 
b/drivers/media/v4l2-core/v4l2-ioctl.c
index 530a67e..aa6e7c7 100644
--- a/drivers/media/v4l2-core/v4l2-ioctl.c
+++ b/drivers/media/v4l2-core/v4l2-ioctl.c
@@ -454,6 +454,15 @@ static void v4l_print_buffer(const void *arg, bool 
write_only)
tc->type, tc->flags, tc->frames, *(__u32 
*)tc->userbits);
 }
 
+static void v4l_print_exportbuffer(const void *arg, bool write_only)
+{
+   const struct v4l2_exportbuffer *p = arg;
+
+   pr_cont("fd=%d, type=%s, index=%u, plane=%u, flags=0x%08x\n",
+   p->fd, prt_names(p->type, v4l2_type_names),
+   p->index, p->plane, p->flags);
+}
+
 static void v4l_print_create_buffers(const void *arg, bool write_only)
 {
const struct v4l2_create_buffers *p = arg;
@@ -1961,6 +1970,7 @@ static struct v4l2_ioctl_info v4l2_ioctls[] = {
IOCTL_INFO_STD(VIDIOC_S_FBUF, vidioc_s_fbuf, v4l_print_framebuffer, 
INFO_FL_PRIO),
IOCTL_INFO_FNC(VIDIOC_OVERLAY, v4l_overlay, v4l_print_u32, 
INFO_FL_PRIO),
IOCTL_INFO_FNC(VIDIOC_QBUF, v4l_qbuf, v4l_print_buffer, INFO_FL_QUEUE),
+   IOCTL_INFO_STD(VIDIOC_EXPBUF, vidioc_expbuf, v4l_print_exportbuffer, 
INFO_FL_QUEUE | INFO_FL_CLEAR(v4l2_exportbuffer, flags)),
IOCTL_INFO_FNC(VIDIOC_DQBUF, v4l_dqbuf, v4l_print_buffer, 
INFO_FL_QUEUE),
IOCTL_INFO_FNC(VIDIOC_STREAMON, v4l_streamon, v4l_print_buftype, 
INFO_FL_PRIO | INFO_FL_QUEUE),
IOCTL_INFO_FNC(VIDIOC_STREAMOFF, v4l_streamoff, v4l_print_buftype, 
INFO_FL_PRIO | INFO_FL_QUEUE),
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index 07bc5d6..19765df 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -696,6 +696,33 @@ struct v4l2_buffer {
 #define V4L2_BUF_FLAG_NO_CACHE_INVALIDATE  0x0800
 #define V4L2_BUF_FLAG_NO_CACHE_CLEAN   0x1000
 
+/**
+ * struct v4l2_exportbuffer - export of video buffer as DMABUF file descriptor
+ *
+ * @index: id number of the buffer
+ * @type:  enum v4l2_buf_type; buffer type (type == *_MPLANE for
+ * multiplanar buffers);
+ * @plane: index of the plane to be exported, 0 for single plane queues
+ * @flags: flags for newly created file, currently only O_CLOEXEC is
+ * supported, refer to manual of open syscall for more details
+ * @fd:file descriptor associated with DMABUF (set by driver)
+ *
+ * Contains data used for exporting a video buffer as DMABUF file descriptor.
+ * The buffer is identified by a 'cookie' returned by VIDIOC_QUERYBUF
+ * (identical to the cookie used to mmap() the buffer to userspace). All
+ * reserved fields must be set to zero. The field reserved0 is expected to
+ * become a structure 'type' allowing an alternative layout of the structure
+ * content. Therefore this field should not be used for any other extensions.
+ */
+struct v4l2_exportbuffer {
+   __u32   type; /* enum v4l2_buf_type */
+   __u32   index;
+   __u32   plane;

[PATCHv10 19/26] v4l: vb2: add buffer exporting via dmabuf

2012-10-10 Thread Tomasz Stanislawski
This patch adds extension to videobuf2-core. It allow to export a mmap buffer
as a file descriptor.

Signed-off-by: Tomasz Stanislawski 
Signed-off-by: Kyungmin Park 
Acked-by: Laurent Pinchart 
Acked-by: Hans Verkuil 
---
 drivers/media/v4l2-core/v4l2-mem2mem.c   |   13 +
 drivers/media/v4l2-core/videobuf2-core.c |   83 ++
 include/media/v4l2-mem2mem.h |3 ++
 include/media/videobuf2-core.h   |4 ++
 4 files changed, 103 insertions(+)

diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c 
b/drivers/media/v4l2-core/v4l2-mem2mem.c
index 3ac8358..9aa7cc7 100644
--- a/drivers/media/v4l2-core/v4l2-mem2mem.c
+++ b/drivers/media/v4l2-core/v4l2-mem2mem.c
@@ -369,6 +369,19 @@ int v4l2_m2m_dqbuf(struct file *file, struct v4l2_m2m_ctx 
*m2m_ctx,
 EXPORT_SYMBOL_GPL(v4l2_m2m_dqbuf);
 
 /**
+ * v4l2_m2m_expbuf() - export a source or destination buffer, depending on
+ * the type
+ */
+int v4l2_m2m_expbuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
+ struct v4l2_exportbuffer *eb)
+{
+   struct vb2_queue *vq;
+
+   vq = v4l2_m2m_get_vq(m2m_ctx, eb->type);
+   return vb2_expbuf(vq, eb);
+}
+EXPORT_SYMBOL_GPL(v4l2_m2m_expbuf);
+/**
  * v4l2_m2m_streamon() - turn on streaming for a video queue
  */
 int v4l2_m2m_streamon(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
diff --git a/drivers/media/v4l2-core/videobuf2-core.c 
b/drivers/media/v4l2-core/videobuf2-core.c
index 613dea1..9f81be2 100644
--- a/drivers/media/v4l2-core/videobuf2-core.c
+++ b/drivers/media/v4l2-core/videobuf2-core.c
@@ -1751,6 +1751,79 @@ static int __find_plane_by_offset(struct vb2_queue *q, 
unsigned long off,
 }
 
 /**
+ * vb2_expbuf() - Export a buffer as a file descriptor
+ * @q: videobuf2 queue
+ * @eb:export buffer structure passed from userspace to 
vidioc_expbuf
+ * handler in driver
+ *
+ * The return values from this function are intended to be directly returned
+ * from vidioc_expbuf handler in driver.
+ */
+int vb2_expbuf(struct vb2_queue *q, struct v4l2_exportbuffer *eb)
+{
+   struct vb2_buffer *vb = NULL;
+   struct vb2_plane *vb_plane;
+   int ret;
+   struct dma_buf *dbuf;
+
+   if (q->memory != V4L2_MEMORY_MMAP) {
+   dprintk(1, "Queue is not currently set up for mmap\n");
+   return -EINVAL;
+   }
+
+   if (!q->mem_ops->get_dmabuf) {
+   dprintk(1, "Queue does not support DMA buffer exporting\n");
+   return -EINVAL;
+   }
+
+   if (eb->flags & ~O_CLOEXEC) {
+   dprintk(1, "Queue does support only O_CLOEXEC flag\n");
+   return -EINVAL;
+   }
+
+   if (eb->type != q->type) {
+   dprintk(1, "qbuf: invalid buffer type\n");
+   return -EINVAL;
+   }
+
+   if (eb->index >= q->num_buffers) {
+   dprintk(1, "buffer index out of range\n");
+   return -EINVAL;
+   }
+
+   vb = q->bufs[eb->index];
+
+   if (eb->plane >= vb->num_planes) {
+   dprintk(1, "buffer plane out of range\n");
+   return -EINVAL;
+   }
+
+   vb_plane = &vb->planes[eb->plane];
+
+   dbuf = call_memop(q, get_dmabuf, vb_plane->mem_priv);
+   if (IS_ERR_OR_NULL(dbuf)) {
+   dprintk(1, "Failed to export buffer %d, plane %d\n",
+   eb->index, eb->plane);
+   return -EINVAL;
+   }
+
+   ret = dma_buf_fd(dbuf, eb->flags);
+   if (ret < 0) {
+   dprintk(3, "buffer %d, plane %d failed to export (%d)\n",
+   eb->index, eb->plane, ret);
+   dma_buf_put(dbuf);
+   return ret;
+   }
+
+   dprintk(3, "buffer %d, plane %d exported as %d descriptor\n",
+   eb->index, eb->plane, ret);
+   eb->fd = ret;
+
+   return 0;
+}
+EXPORT_SYMBOL_GPL(vb2_expbuf);
+
+/**
  * vb2_mmap() - map video buffers into application address space
  * @q: videobuf2 queue
  * @vma:   vma passed to the mmap file operation handler in the driver
@@ -2456,6 +2529,16 @@ int vb2_ioctl_streamoff(struct file *file, void *priv, 
enum v4l2_buf_type i)
 }
 EXPORT_SYMBOL_GPL(vb2_ioctl_streamoff);
 
+int vb2_ioctl_expbuf(struct file *file, void *priv, struct v4l2_exportbuffer 
*p)
+{
+   struct video_device *vdev = video_devdata(file);
+
+   if (vb2_queue_is_busy(vdev, file))
+   return -EBUSY;
+   return vb2_expbuf(vdev->queue, p);
+}
+EXPORT_SYMBOL_GPL(vb2_ioctl_expbuf);
+
 /* v4l2_file_operations helpers */
 
 int vb2_fop_mmap(struct file *file, struct vm_area_struct *vma)
diff --git a/include/media/v4l2-mem2mem.h b/include/media/v4l2-mem2mem.h
index 131cc4a..7e82d2b 100644
--- a/include/media/v4l2-mem2mem.h
+++ b/in

[PATCHv10 20/26] v4l: vb2-dma-contig: add support for DMABUF exporting

2012-10-10 Thread Tomasz Stanislawski
This patch adds support for exporting a dma-contig buffer using
DMABUF interface.

Signed-off-by: Tomasz Stanislawski 
Signed-off-by: Kyungmin Park 
Acked-by: Hans Verkuil 
---
 drivers/media/v4l2-core/videobuf2-dma-contig.c |  200 
 1 file changed, 200 insertions(+)

diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c 
b/drivers/media/v4l2-core/videobuf2-dma-contig.c
index 0e065ce..b138b5c 100644
--- a/drivers/media/v4l2-core/videobuf2-dma-contig.c
+++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c
@@ -36,6 +36,7 @@ struct vb2_dc_buf {
/* MMAP related */
struct vb2_vmarea_handler   handler;
atomic_trefcount;
+   struct sg_table *sgt_base;
 
/* USERPTR related */
struct vm_area_struct   *vma;
@@ -142,6 +143,10 @@ static void vb2_dc_put(void *buf_priv)
if (!atomic_dec_and_test(&buf->refcount))
return;
 
+   if (buf->sgt_base) {
+   sg_free_table(buf->sgt_base);
+   kfree(buf->sgt_base);
+   }
dma_free_coherent(buf->dev, buf->size, buf->vaddr, buf->dma_addr);
kfree(buf);
 }
@@ -213,6 +218,200 @@ static int vb2_dc_mmap(void *buf_priv, struct 
vm_area_struct *vma)
 }
 
 /*/
+/* DMABUF ops for exporters  */
+/*/
+
+struct vb2_dc_attachment {
+   struct sg_table sgt;
+   enum dma_data_direction dir;
+};
+
+static int vb2_dc_dmabuf_ops_attach(struct dma_buf *dbuf, struct device *dev,
+   struct dma_buf_attachment *dbuf_attach)
+{
+   struct vb2_dc_attachment *attach;
+   unsigned int i;
+   struct scatterlist *rd, *wr;
+   struct sg_table *sgt;
+   struct vb2_dc_buf *buf = dbuf->priv;
+   int ret;
+
+   attach = kzalloc(sizeof(*attach), GFP_KERNEL);
+   if (!attach)
+   return -ENOMEM;
+
+   sgt = &attach->sgt;
+   /* Copy the buf->base_sgt scatter list to the attachment, as we can't
+* map the same scatter list to multiple attachments at the same time.
+*/
+   ret = sg_alloc_table(sgt, buf->sgt_base->orig_nents, GFP_KERNEL);
+   if (ret) {
+   kfree(attach);
+   return -ENOMEM;
+   }
+
+   rd = buf->sgt_base->sgl;
+   wr = sgt->sgl;
+   for (i = 0; i < sgt->orig_nents; ++i) {
+   sg_set_page(wr, sg_page(rd), rd->length, rd->offset);
+   rd = sg_next(rd);
+   wr = sg_next(wr);
+   }
+
+   attach->dir = DMA_NONE;
+   dbuf_attach->priv = attach;
+
+   return 0;
+}
+
+static void vb2_dc_dmabuf_ops_detach(struct dma_buf *dbuf,
+   struct dma_buf_attachment *db_attach)
+{
+   struct vb2_dc_attachment *attach = db_attach->priv;
+   struct sg_table *sgt;
+
+   if (!attach)
+   return;
+
+   sgt = &attach->sgt;
+
+   /* release the scatterlist cache */
+   if (attach->dir != DMA_NONE)
+   dma_unmap_sg(db_attach->dev, sgt->sgl, sgt->orig_nents,
+   attach->dir);
+   sg_free_table(sgt);
+   kfree(attach);
+   db_attach->priv = NULL;
+}
+
+static struct sg_table *vb2_dc_dmabuf_ops_map(
+   struct dma_buf_attachment *db_attach, enum dma_data_direction dir)
+{
+   struct vb2_dc_attachment *attach = db_attach->priv;
+   /* stealing dmabuf mutex to serialize map/unmap operations */
+   struct mutex *lock = &db_attach->dmabuf->lock;
+   struct sg_table *sgt;
+   int ret;
+
+   mutex_lock(lock);
+
+   sgt = &attach->sgt;
+   /* return previously mapped sg table */
+   if (attach->dir == dir) {
+   mutex_unlock(lock);
+   return sgt;
+   }
+
+   /* release any previous cache */
+   if (attach->dir != DMA_NONE) {
+   dma_unmap_sg(db_attach->dev, sgt->sgl, sgt->orig_nents,
+   attach->dir);
+   attach->dir = DMA_NONE;
+   }
+
+   /* mapping to the client with new direction */
+   ret = dma_map_sg(db_attach->dev, sgt->sgl, sgt->orig_nents, dir);
+   if (ret <= 0) {
+   pr_err("failed to map scatterlist\n");
+   mutex_unlock(lock);
+   return ERR_PTR(-EIO);
+   }
+
+   attach->dir = dir;
+
+   mutex_unlock(lock);
+
+   return sgt;
+}
+
+static void vb2_dc_dmabuf_ops_unmap(struct dma_buf_attachment *db_attach,
+   struct sg_table *sgt, enum dma_data_direction dir)
+{
+   /* nothing to be done here */
+}
+
+static void vb2_dc_dmabuf_ops_release(struct dma_buf *dbuf)
+{
+   /* drop reference obtained in vb2_dc_get_dmabuf */
+   vb2_dc_put(dbuf->priv);
+}
+
+static void *vb2_dc_dmabuf_ops_kmap(struct dma_b

[PATCHv10 21/26] v4l: vb2-dma-contig: add reference counting for a device from allocator context

2012-10-10 Thread Tomasz Stanislawski
This patch adds taking reference to the device for MMAP buffers.

Such buffers, may be exported using DMABUF mechanism. If the driver that
created a queue is unloaded then the queue is released, the device might be
released too.  However, buffers cannot be released if they are referenced by
DMABUF descriptor(s). The device pointer kept in a buffer must be valid for the
whole buffer's lifetime. Therefore MMAP buffers should take a reference to the
device to avoid risk of dangling pointers.

Signed-off-by: Tomasz Stanislawski 
Acked-by: Hans Verkuil 
---
 drivers/media/v4l2-core/videobuf2-dma-contig.c |4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c 
b/drivers/media/v4l2-core/videobuf2-dma-contig.c
index b138b5c..2d661fd 100644
--- a/drivers/media/v4l2-core/videobuf2-dma-contig.c
+++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c
@@ -148,6 +148,7 @@ static void vb2_dc_put(void *buf_priv)
kfree(buf->sgt_base);
}
dma_free_coherent(buf->dev, buf->size, buf->vaddr, buf->dma_addr);
+   put_device(buf->dev);
kfree(buf);
 }
 
@@ -168,6 +169,9 @@ static void *vb2_dc_alloc(void *alloc_ctx, unsigned long 
size)
return ERR_PTR(-ENOMEM);
}
 
+   /* prevent the device from release while the buffer is exported */
+   get_device(dev);
+
buf->dev = dev;
buf->size = size;
 
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv10 22/26] v4l: vb2-dma-contig: fail if user ptr buffer is not correctly aligned

2012-10-10 Thread Tomasz Stanislawski
From: Marek Szyprowski 

The DMA transfer must be aligned to a specific value. If userptr is not aligned
to DMA requirements then unexpected corruptions of the memory may occur before
or after a buffer.  To prevent such situations, all unligned userptr buffers
are rejected at VIDIOC_QBUF.

Signed-off-by: Marek Szyprowski 
Acked-by: Hans Verkuil 
---
 drivers/media/v4l2-core/videobuf2-dma-contig.c |   12 
 1 file changed, 12 insertions(+)

diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c 
b/drivers/media/v4l2-core/videobuf2-dma-contig.c
index 2d661fd..571a919 100644
--- a/drivers/media/v4l2-core/videobuf2-dma-contig.c
+++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c
@@ -493,6 +493,18 @@ static void *vb2_dc_get_userptr(void *alloc_ctx, unsigned 
long vaddr,
struct vm_area_struct *vma;
struct sg_table *sgt;
unsigned long contig_size;
+   unsigned long dma_align = dma_get_cache_alignment();
+
+   /* Only cache aligned DMA transfers are reliable */
+   if (!IS_ALIGNED(vaddr | size, dma_align)) {
+   pr_debug("user data must be aligned to %lu bytes\n", dma_align);
+   return ERR_PTR(-EINVAL);
+   }
+
+   if (!size) {
+   pr_debug("size is zero\n");
+   return ERR_PTR(-EINVAL);
+   }
 
buf = kzalloc(sizeof *buf, GFP_KERNEL);
if (!buf)
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv10 23/26] v4l: vb2-dma-contig: align buffer size to PAGE_SIZE

2012-10-10 Thread Tomasz Stanislawski
Most operations on DMA and DMABUF framework need page
aligned buffers. This fix guarantees this requirement
for vb2-dma-contig buffers.

Signed-off-by: Tomasz Stanislawski 
---
 drivers/media/v4l2-core/videobuf2-dma-contig.c |3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/media/v4l2-core/videobuf2-dma-contig.c 
b/drivers/media/v4l2-core/videobuf2-dma-contig.c
index 571a919..002ee50 100644
--- a/drivers/media/v4l2-core/videobuf2-dma-contig.c
+++ b/drivers/media/v4l2-core/videobuf2-dma-contig.c
@@ -162,6 +162,9 @@ static void *vb2_dc_alloc(void *alloc_ctx, unsigned long 
size)
if (!buf)
return ERR_PTR(-ENOMEM);
 
+   /* align image size to PAGE_SIZE */
+   size = PAGE_ALIGN(size);
+
buf->vaddr = dma_alloc_coherent(dev, size, &buf->dma_addr, GFP_KERNEL);
if (!buf->vaddr) {
dev_err(dev, "dma_alloc_coherent of size %ld failed\n", size);
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv10 24/26] v4l: s5p-fimc: support for dmabuf exporting

2012-10-10 Thread Tomasz Stanislawski
This patch enhances s5p-fimc with support for DMABUF exporting via
VIDIOC_EXPBUF ioctl.

Signed-off-by: Tomasz Stanislawski 
Signed-off-by: Kyungmin Park 
CC: Sylwester Nawrocki 
Acked-by: Hans Verkuil 
---
 drivers/media/platform/s5p-fimc/fimc-capture.c |9 +
 drivers/media/platform/s5p-fimc/fimc-m2m.c |   10 ++
 2 files changed, 19 insertions(+)

diff --git a/drivers/media/platform/s5p-fimc/fimc-capture.c 
b/drivers/media/platform/s5p-fimc/fimc-capture.c
index 246bb32..e5fd159 100644
--- a/drivers/media/platform/s5p-fimc/fimc-capture.c
+++ b/drivers/media/platform/s5p-fimc/fimc-capture.c
@@ -1231,6 +1231,14 @@ static int fimc_cap_qbuf(struct file *file, void *priv,
return vb2_qbuf(&fimc->vid_cap.vbq, buf);
 }
 
+static int fimc_cap_expbuf(struct file *file, void *priv,
+ struct v4l2_exportbuffer *eb)
+{
+   struct fimc_dev *fimc = video_drvdata(file);
+
+   return vb2_expbuf(&fimc->vid_cap.vbq, eb);
+}
+
 static int fimc_cap_dqbuf(struct file *file, void *priv,
   struct v4l2_buffer *buf)
 {
@@ -1355,6 +1363,7 @@ static const struct v4l2_ioctl_ops fimc_capture_ioctl_ops 
= {
 
.vidioc_qbuf= fimc_cap_qbuf,
.vidioc_dqbuf   = fimc_cap_dqbuf,
+   .vidioc_expbuf  = fimc_cap_expbuf,
 
.vidioc_prepare_buf = fimc_cap_prepare_buf,
.vidioc_create_bufs = fimc_cap_create_bufs,
diff --git a/drivers/media/platform/s5p-fimc/fimc-m2m.c 
b/drivers/media/platform/s5p-fimc/fimc-m2m.c
index 17067a7..1cd4fcf 100644
--- a/drivers/media/platform/s5p-fimc/fimc-m2m.c
+++ b/drivers/media/platform/s5p-fimc/fimc-m2m.c
@@ -439,6 +439,15 @@ static int fimc_m2m_dqbuf(struct file *file, void *fh,
return v4l2_m2m_dqbuf(file, ctx->m2m_ctx, buf);
 }
 
+static int fimc_m2m_expbuf(struct file *file, void *fh,
+   struct v4l2_exportbuffer *eb)
+{
+   struct fimc_ctx *ctx = fh_to_ctx(fh);
+
+   return v4l2_m2m_expbuf(file, ctx->m2m_ctx, eb);
+}
+
+
 static int fimc_m2m_streamon(struct file *file, void *fh,
 enum v4l2_buf_type type)
 {
@@ -607,6 +616,7 @@ static const struct v4l2_ioctl_ops fimc_m2m_ioctl_ops = {
.vidioc_querybuf= fimc_m2m_querybuf,
.vidioc_qbuf= fimc_m2m_qbuf,
.vidioc_dqbuf   = fimc_m2m_dqbuf,
+   .vidioc_expbuf  = fimc_m2m_expbuf,
.vidioc_streamon= fimc_m2m_streamon,
.vidioc_streamoff   = fimc_m2m_streamoff,
.vidioc_g_crop  = fimc_m2m_g_crop,
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv10 25/26] v4l: s5p-tv: mixer: support for dmabuf exporting

2012-10-10 Thread Tomasz Stanislawski
This patch enhances s5p-tv with support for DMABUF exporting via
VIDIOC_EXPBUF ioctl.

Signed-off-by: Tomasz Stanislawski 
Signed-off-by: Kyungmin Park 
Acked-by: Hans Verkuil 
---
 drivers/media/platform/s5p-tv/mixer_video.c |   10 ++
 1 file changed, 10 insertions(+)

diff --git a/drivers/media/platform/s5p-tv/mixer_video.c 
b/drivers/media/platform/s5p-tv/mixer_video.c
index 2421e527..5e3cdb2 100644
--- a/drivers/media/platform/s5p-tv/mixer_video.c
+++ b/drivers/media/platform/s5p-tv/mixer_video.c
@@ -698,6 +698,15 @@ static int mxr_dqbuf(struct file *file, void *priv, struct 
v4l2_buffer *p)
return vb2_dqbuf(&layer->vb_queue, p, file->f_flags & O_NONBLOCK);
 }
 
+static int mxr_expbuf(struct file *file, void *priv,
+   struct v4l2_exportbuffer *eb)
+{
+   struct mxr_layer *layer = video_drvdata(file);
+
+   mxr_dbg(layer->mdev, "%s:%d\n", __func__, __LINE__);
+   return vb2_expbuf(&layer->vb_queue, eb);
+}
+
 static int mxr_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
 {
struct mxr_layer *layer = video_drvdata(file);
@@ -725,6 +734,7 @@ static const struct v4l2_ioctl_ops mxr_ioctl_ops = {
.vidioc_querybuf = mxr_querybuf,
.vidioc_qbuf = mxr_qbuf,
.vidioc_dqbuf = mxr_dqbuf,
+   .vidioc_expbuf = mxr_expbuf,
/* Streaming control */
.vidioc_streamon = mxr_streamon,
.vidioc_streamoff = mxr_streamoff,
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


<    1   2   3   4   5   >