Hi everybody, I have been taking a look at adding DMA to userspace to the V4L2 API. My ideas are discussed below. Any comments/criticisms are welcome. 1) Exisiting mechanism: The existing streaming capture mechanism can be summarised as follows: 1 - Set capture format (S_FMT) 2 - Request buffers (REQBUFS) 3 - Map buffers into userspace (QUERYBUF and mmap) 4 - do streaming capture here. 5 - unmap buffers (implicity unrequests buffers). This should be changed to include an explicit "unrequest buffers" operation (as userspace buffers can not be munmapped). This would be done via a REQBUFS ioctl with a count of 0. A REQBUFS ioctl performed while not streaming will unmap and deallocate all allocated buffers, and allocate the requested count. If the requested count is 0, no new buffers are allocated. Since munmapping buffers would still be an implicit unrequest buffers, this will not require any change to existing user applications. All drivers should be modified to include this functionality (This is the one incompatibility - can anyone see a way around this?). 2) Identification: A driver supporting DMA to userspace will set the V4L2_FLAG_DMA flag, as returned by QUERYCAP. 3) Requesting userspace buffers: This is handled by the REQBUFS ioctl as before, except the user application must set a V4L2_BUF_REQ_DMA flag in requestbuffers. 4) Mapping userspace buffers: This is performed via the QUERYBUF ioctl. The v4l2_buffer structure is modified as follows: struct v4l2_buffer { int index; __u32 type; __u32 offset; __u32 length; __u32 bytesused; __u32 flags; stamp_t timestamp; struct v4l2_timecode timecode; __u32 sequence; struct v4l2_dmabuffer *dmabuf; /* need some #ifdef magic here to waste 4 bytes on a 32 bit architecture */ __u32 reserved; }; where struct v4l2_dmabuffer is: struct v4l2_dmabuffer { void *start; unsigned long size; unsigned long stride; unsigned long reserved[2]; }; The dmabuf pointer passed by the application is a pointer to an array of struct v4l2_dmabuffer, with one element for each plane in the color format (for the current formats, that would be one plane for the packed formats, and 3 for the planar formats). *start is the start address of the buffer. size is the size in bytes of the buffer. stride is the length in bytes of a line in the buffer. 5) DMA to userspace example: 1 - set capture format (S_FMT) 2 - request buffers (REQBUFS with V4L2_BUF_REQ_DMA set) 3 - allocate userspace memory for the number of granted buffers. 4 - call QUERYBUF on each buffer, filling in dmabuf with a pointer to the struct v4l2_dmabuffer describing each buffer (note that dmabuf is ignored if V4L2_BUF_REQ_DMA was not set when the buffers were requested). 5 - perform streaming capture. 6 - unmap requested buffers (REQBUFS with count set to 0). 6) Conclusion This is a first draft, and probably has a number of nasty flaws in it. Please look at it closely, and see if it looks OK to you. As far as I can see, this API extension would give the maximum flexibility, with a minimum of incompatibilities. Thanks -justin