static int __vb2_queue_alloc(struct vb2_queue *q, enum v4l2_memory memory, unsigned int num_buffers, unsigned int num_planes, unsigned long plane_sizes[]) { unsigned int buffer; struct vb2_buffer *vb; int ret; for (buffer = 0; buffer < num_buffers; ++buffer) { vb = kzalloc(q->buf_struct_size, GFP_KERNEL); if (!vb) { dprintk(1, "Memory alloc for buffer struct failed\n"); break; } if (V4L2_TYPE_IS_MULTIPLANAR(q->type)) vb->v4l2_buf.length = num_planes; vb->state = VB2_BUF_STATE_DEQUEUED; vb->vb2_queue = q; vb->num_planes = num_planes; vb->v4l2_buf.index = buffer; vb->v4l2_buf.type = q->type; vb->v4l2_buf.memory = memory; if (memory == V4L2_MEMORY_MMAP) { ret = __vb2_buf_mem_alloc(vb, plane_sizes); if (ret) { dprintk(1, "Failed allocating memory for " "buffer %d\n", buffer); kfree(vb); break; } ret = call_qop(q, buf_init, vb); if (ret) { dprintk(1, "Buffer %d %p initialization" " failed\n", buffer, vb); __vb2_buf_mem_free(vb); kfree(vb); break; } } q->bufs[buffer] = vb; } q->num_buffers = buffer; __setup_offsets(q); dprintk(1, "Allocated %d buffers, %d plane(s) each\n", q->num_buffers, num_planes); return buffer; }
/** * __vb2_free_mem() - release all video buffer memory for a given queue */ static void __vb2_free_mem(struct vb2_queue *q) { unsigned int buffer; struct vb2_buffer *vb; for (buffer = 0; buffer < q->num_buffers; ++buffer) { vb = q->bufs[buffer]; if (!vb) continue; /* Free MMAP buffers or release USERPTR buffers */ if (q->memory == V4L2_MEMORY_MMAP) __vb2_buf_mem_free(vb); else __vb2_buf_userptr_put(vb); } }
/** * __vb2_queue_alloc() - allocate videobuf buffer structures and (for MMAP type) * video buffer memory for all buffers/planes on the queue and initializes the * queue * * Returns the number of buffers successfully allocated. */ static int __vb2_queue_alloc(struct vb2_queue *q, enum v4l2_memory memory, unsigned int num_buffers, unsigned int num_planes, unsigned long plane_sizes[]) { unsigned int buffer; struct vb2_buffer *vb; int ret; for (buffer = 0; buffer < num_buffers; ++buffer) { /* Allocate videobuf buffer structures */ vb = kzalloc(q->buf_struct_size, GFP_KERNEL); if (!vb) { dprintk(1, "Memory alloc for buffer struct failed\n"); break; } /* Length stores number of planes for multiplanar buffers */ if (V4L2_TYPE_IS_MULTIPLANAR(q->type)) vb->v4l2_buf.length = num_planes; vb->state = VB2_BUF_STATE_DEQUEUED; vb->vb2_queue = q; vb->num_planes = num_planes; vb->v4l2_buf.index = buffer; vb->v4l2_buf.type = q->type; vb->v4l2_buf.memory = memory; /* Allocate video buffer memory for the MMAP type */ if (memory == V4L2_MEMORY_MMAP) { ret = __vb2_buf_mem_alloc(vb, plane_sizes); if (ret) { dprintk(1, "Failed allocating memory for " "buffer %d\n", buffer); kfree(vb); break; } /* * Call the driver-provided buffer initialization * callback, if given. An error in initialization * results in queue setup failure. */ ret = call_qop(q, buf_init, vb); if (ret) { dprintk(1, "Buffer %d %p initialization" " failed\n", buffer, vb); __vb2_buf_mem_free(vb); kfree(vb); break; } } q->bufs[buffer] = vb; } q->num_buffers = buffer; __setup_offsets(q); dprintk(1, "Allocated %d buffers, %d plane(s) each\n", q->num_buffers, num_planes); return buffer; }