*参照元 [#la25221b] #backlinks *説明 [#j280d8ea] -パス: [[linux-4.4.1/drivers/media/v4l2-core/videobuf2-core.c]] -FIXME: これは何? --説明 **引数 [#tfd92376] -struct vb2_queue *q -- --[[linux-4.4.1/vb2_queue]] -enum vb2_memory memory -- --[[linux-4.4.1/vb2_memory]] -unsigned int *count -- **返り値 [#t0fef9e1] -int -- **参考 [#u5d4bbee] *実装 [#v1cad5b5] /** * vb2_core_reqbufs() - Initiate streaming * @q: videobuf2 queue * @memory: memory type * @count: requested buffer count * * Should be called from vidioc_reqbufs ioctl handler of a driver. * This function: * 1) verifies streaming parameters passed from the userspace, * 2) sets up the queue, * 3) negotiates number of buffers and planes per buffer with the driver * to be used during streaming, * 4) allocates internal buffer structures (struct vb2_buffer), according to * the agreed parameters, * 5) for MMAP memory type, allocates actual video memory, using the * memory handling/allocation routines provided during queue initialization * * If req->count is 0, all the memory will be freed instead. * If the queue has been allocated previously (by a previous vb2_reqbufs) call * and the queue is not busy, memory will be reallocated. * * The return values from this function are intended to be directly returned * from vidioc_reqbufs handler in driver. */ int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory memory, unsigned int *count) { unsigned int num_buffers, allocated_buffers, num_planes = 0; int ret; if (q->streaming) { dprintk(1, "streaming active\n"); return -EBUSY; } - --[[linux-4.4.1/dprintk()]] if (*count == 0 || q->num_buffers != 0 || q->memory != memory) { /* * We already have buffers allocated, so first check if they * are not in use and can be freed. */ mutex_lock(&q->mmap_lock); if (q->memory == VB2_MEMORY_MMAP && __buffers_in_use(q)) { mutex_unlock(&q->mmap_lock); dprintk(1, "memory in use, cannot free\n"); return -EBUSY; } - --[[linux-4.4.1/mutex_lock()]] --[[linux-4.4.1/__buffers_in_use()]] --[[linux-4.4.1/mutex_unlock()]] /* * Call queue_cancel to clean up any buffers in the PREPARED or * QUEUED state which is possible if buffers were prepared or * queued without ever calling STREAMON. */ __vb2_queue_cancel(q); ret = __vb2_queue_free(q, q->num_buffers); mutex_unlock(&q->mmap_lock); if (ret) return ret; - --[[linux-4.4.1/__vb2_queue_cancel()]] --[[linux-4.4.1/__vb2_queue_free()]] /* * In case of REQBUFS(0) return immediately without calling * driver's queue_setup() callback and allocating resources. */ if (*count == 0) return 0; } /* * Make sure the requested values and current defaults are sane. */ num_buffers = min_t(unsigned int, *count, VB2_MAX_FRAME); num_buffers = max_t(unsigned int, num_buffers, q->min_buffers_needed); memset(q->plane_sizes, 0, sizeof(q->plane_sizes)); memset(q->alloc_ctx, 0, sizeof(q->alloc_ctx)); q->memory = memory; - --[[linux-4.4.1/min_t()]] --[[linux-4.4.1/max_t()]] --[[linux-4.4.1/memset()]] /* * Ask the driver how many buffers and planes per buffer it requires. * Driver also sets the size and allocator context for each plane. */ ret = call_qop(q, queue_setup, q, NULL, &num_buffers, &num_planes, q->plane_sizes, q->alloc_ctx); if (ret) return ret; - --q->ops->queue_setup を呼び出す。 ---q->ops は const struct vb2_ops * 型 ---[[linux-4.4.1/vb2_ops]] --[[linux-4.4.1/call_qop()]] /* Finally, allocate buffers and video memory */ allocated_buffers = __vb2_queue_alloc(q, memory, num_buffers, num_planes); if (allocated_buffers == 0) { dprintk(1, "memory allocation failed\n"); return -ENOMEM; } - --[[linux-4.4.1/__vb2_queue_alloc()]] /* * There is no point in continuing if we can't allocate the minimum * number of buffers needed by this vb2_queue. */ if (allocated_buffers < q->min_buffers_needed) ret = -ENOMEM; /* * Check if driver can handle the allocated number of buffers. */ if (!ret && allocated_buffers < num_buffers) { num_buffers = allocated_buffers; ret = call_qop(q, queue_setup, q, NULL, &num_buffers, &num_planes, q->plane_sizes, q->alloc_ctx); - --q->ops->queue_setup を呼び出す。 ---q->ops は const struct vb2_ops * 型 ---[[linux-4.4.1/vb2_ops]] --[[linux-4.4.1/call_qop()]] if (!ret && allocated_buffers < num_buffers) ret = -ENOMEM; /* * Either the driver has accepted a smaller number of buffers, * or .queue_setup() returned an error */ } mutex_lock(&q->mmap_lock); q->num_buffers = allocated_buffers; if (ret < 0) { /* * Note: __vb2_queue_free() will subtract 'allocated_buffers' * from q->num_buffers. */ __vb2_queue_free(q, allocated_buffers); mutex_unlock(&q->mmap_lock); return ret; } mutex_unlock(&q->mmap_lock); - --[[linux-4.4.1/__vb2_queue_free()]] /* * Return the number of successfully allocated buffers * to the userspace. */ *count = allocated_buffers; q->waiting_for_buffers = !q->is_output; return 0; } EXPORT_SYMBOL_GPL(vb2_core_reqbufs); - --[[linux-4.4.1/EXPORT_SYMBOL_GPL()]] *コメント [#c9ad2e89]