{
unsigned int buffer;
- /*
- * Sanity check: when preparing a buffer the queue lock is released for
- * a short while (see __buf_prepare for the details), which would allow
- * a race with a reqbufs which can call this function. Removing the
- * buffers from underneath __buf_prepare is obviously a bad idea, so we
- * check if any of the buffers is in the state PREPARING, and if so we
- * just return -EAGAIN.
- */
- for (buffer = q->num_buffers - buffers; buffer < q->num_buffers;
- ++buffer) {
- if (q->bufs[buffer] == NULL)
- continue;
- if (q->bufs[buffer]->state == VB2_BUF_STATE_PREPARING) {
- dprintk(1, "preparing buffers, cannot free\n");
- return -EAGAIN;
+ /* Call driver-provided cleanup function for each buffer, if provided */
+ if (q->ops->buf_cleanup) {
+ for (buffer = q->num_buffers - buffers; buffer < q->num_buffers;
+ ++buffer) {
+ struct vb2_buffer *vb = q->bufs[buffer];
+
+ if (vb && vb->planes[0].mem_priv)
+ q->ops->buf_cleanup(vb);
}
}
if (vb->planes[plane].mem_priv) {
if (!reacquired) {
reacquired = true;
- call_void_vb_qop(vb, buf_cleanup, vb);
+ q->ops->buf_cleanup(vb);
}
- call_void_memop(vb, put_userptr, vb->planes[plane].mem_priv);
+ call_memop(q, put_userptr, vb->planes[plane].mem_priv);
}
vb->planes[plane].mem_priv = NULL;
* the driver-specific initialization on the newly acquired
* buffer, if provided.
*/
- ret = call_vb_qop(vb, buf_init, vb);
+ ret = call_qop(q, buf_init, vb);
if (ret) {
- dprintk(1, "buffer initialization failed\n");
+ dprintk(1, "qbuf: buffer initialization failed\n");
goto err;
}
}
- ret = call_vb_qop(vb, buf_prepare, vb);
+ ret = call_qop(q, buf_prepare, vb);
if (ret) {
- dprintk(1, "buffer preparation failed\n");
- call_void_vb_qop(vb, buf_cleanup, vb);
+ dprintk(1, "qbuf: buffer preparation failed\n");
+ call_qop(q, buf_cleanup, vb);
goto err;
}
}
/**
+ * __qbuf_mmap() - handle qbuf of an MMAP buffer
+ */
+static int __qbuf_mmap(struct vb2_buffer *vb, const struct v4l2_buffer *b)
+{
+ int ret;
+ struct vb2_queue *q = vb->vb2_queue;
+
+ __fill_vb2_buffer(vb, b, vb->v4l2_planes);
+ ret = call_qop(q, buf_prepare, vb);
+ return ret;
+}
+
+/**
* __qbuf_dmabuf() - handle qbuf of a DMABUF buffer
*/
static int __qbuf_dmabuf(struct vb2_buffer *vb, const struct v4l2_buffer *b)
call_void_vb_qop(vb, buf_cleanup, vb);
}
+ if (!reacquired) {
+ reacquired = true;
+ call_qop(q, buf_cleanup, vb);
+ }
+
/* Release previously acquired memory if present */
__vb2_plane_dmabuf_put(vb, &vb->planes[plane]);
memset(&vb->v4l2_planes[plane], 0, sizeof(struct v4l2_plane));
* Call driver-specific initialization on the newly acquired buffer,
* if provided.
*/
- ret = call_vb_qop(vb, buf_init, vb);
+ ret = call_qop(q, buf_init, vb);
if (ret) {
- dprintk(1, "buffer initialization failed\n");
+ dprintk(1, "qbuf: buffer initialization failed\n");
goto err;
}
}
- ret = call_vb_qop(vb, buf_prepare, vb);
+ ret = call_qop(q, buf_prepare, vb);
if (ret) {
- dprintk(1, "buffer preparation failed\n");
- call_void_vb_qop(vb, buf_cleanup, vb);
+ dprintk(1, "qbuf: buffer preparation failed\n");
+ call_qop(q, buf_cleanup, vb);
goto err;
}