projects/linux·blob master · refs

437 lines · 9.8 KiB

1// SPDX-License-Identifier: GPL-2.0
2/*
3 * dvb-vb2.c - dvb-vb2
4 *
5 * Copyright (C) 2015 Samsung Electronics
6 *
7 * Author: [email protected]
8 */
9
10#include <linux/err.h>
11#include <linux/kernel.h>
12#include <linux/module.h>
13#include <linux/mm.h>
14
15#include <media/dvbdev.h>
16#include <media/dvb_vb2.h>
17
18#define DVB_V2_MAX_SIZE (4096 * 188)
19
20static int vb2_debug;
21module_param(vb2_debug, int, 0644);
22
23#define dprintk(level, fmt, arg...) \
24 do { \
25 if (vb2_debug >= level) \
26 pr_info("vb2: %s: " fmt, __func__, ## arg); \
27 } while (0)
28
29static int _queue_setup(struct vb2_queue *vq,
30 unsigned int *nbuffers, unsigned int *nplanes,
31 unsigned int sizes[], struct device *alloc_devs[])
32{
33 struct dvb_vb2_ctx *ctx = vb2_get_drv_priv(vq);
34
35 ctx->buf_cnt = *nbuffers;
36 *nplanes = 1;
37 sizes[0] = ctx->buf_siz;
38
39 /*
40 * videobuf2-vmalloc allocator is context-less so no need to set
41 * alloc_ctxs array.
42 */
43
44 dprintk(3, "[%s] count=%d, size=%d\n", ctx->name,
45 *nbuffers, sizes[0]);
46
47 return 0;
48}
49
50static int _buffer_prepare(struct vb2_buffer *vb)
51{
52 struct dvb_vb2_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
53 unsigned long size = ctx->buf_siz;
54
55 if (vb2_plane_size(vb, 0) < size) {
56 dprintk(1, "[%s] data will not fit into plane (%lu < %lu)\n",
57 ctx->name, vb2_plane_size(vb, 0), size);
58 return -EINVAL;
59 }
60
61 vb2_set_plane_payload(vb, 0, size);
62 dprintk(3, "[%s]\n", ctx->name);
63
64 return 0;
65}
66
67static void _buffer_queue(struct vb2_buffer *vb)
68{
69 struct dvb_vb2_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
70 struct dvb_buffer *buf = container_of(vb, struct dvb_buffer, vb);
71 unsigned long flags = 0;
72
73 spin_lock_irqsave(&ctx->slock, flags);
74 list_add_tail(&buf->list, &ctx->dvb_q);
75 spin_unlock_irqrestore(&ctx->slock, flags);
76
77 dprintk(3, "[%s]\n", ctx->name);
78}
79
80static int _start_streaming(struct vb2_queue *vq, unsigned int count)
81{
82 struct dvb_vb2_ctx *ctx = vb2_get_drv_priv(vq);
83
84 dprintk(3, "[%s] count=%d\n", ctx->name, count);
85 return 0;
86}
87
88static void _stop_streaming(struct vb2_queue *vq)
89{
90 struct dvb_vb2_ctx *ctx = vb2_get_drv_priv(vq);
91 struct dvb_buffer *buf;
92 unsigned long flags = 0;
93
94 dprintk(3, "[%s]\n", ctx->name);
95
96 spin_lock_irqsave(&ctx->slock, flags);
97 while (!list_empty(&ctx->dvb_q)) {
98 buf = list_entry(ctx->dvb_q.next,
99 struct dvb_buffer, list);
100 vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
101 list_del(&buf->list);
102 }
103 spin_unlock_irqrestore(&ctx->slock, flags);
104}
105
106static const struct vb2_ops dvb_vb2_qops = {
107 .queue_setup = _queue_setup,
108 .buf_prepare = _buffer_prepare,
109 .buf_queue = _buffer_queue,
110 .start_streaming = _start_streaming,
111 .stop_streaming = _stop_streaming,
112};
113
114static void _fill_dmx_buffer(struct vb2_buffer *vb, void *pb)
115{
116 struct dvb_vb2_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
117 struct dmx_buffer *b = pb;
118
119 b->index = vb->index;
120 b->length = vb->planes[0].length;
121 b->bytesused = vb->planes[0].bytesused;
122 b->offset = vb->planes[0].m.offset;
123 dprintk(3, "[%s]\n", ctx->name);
124}
125
126static int _fill_vb2_buffer(struct vb2_buffer *vb, struct vb2_plane *planes)
127{
128 struct dvb_vb2_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
129
130 planes[0].bytesused = 0;
131 dprintk(3, "[%s]\n", ctx->name);
132
133 return 0;
134}
135
136static const struct vb2_buf_ops dvb_vb2_buf_ops = {
137 .fill_user_buffer = _fill_dmx_buffer,
138 .fill_vb2_buffer = _fill_vb2_buffer,
139};
140
141/*
142 * vb2 operations
143 */
144int dvb_vb2_init(struct dvb_vb2_ctx *ctx, const char *name,
145 struct mutex *mutex, int nonblocking)
146{
147 struct vb2_queue *q = &ctx->vb_q;
148 int ret;
149
150 memset(ctx, 0, sizeof(struct dvb_vb2_ctx));
151 q->type = DVB_BUF_TYPE_CAPTURE;
152 /**only mmap is supported currently*/
153 q->io_modes = VB2_MMAP;
154 q->drv_priv = ctx;
155 q->buf_struct_size = sizeof(struct dvb_buffer);
156 q->min_queued_buffers = 1;
157 q->ops = &dvb_vb2_qops;
158 q->mem_ops = &vb2_vmalloc_memops;
159 q->buf_ops = &dvb_vb2_buf_ops;
160 q->lock = mutex;
161 spin_lock_init(&ctx->slock);
162 INIT_LIST_HEAD(&ctx->dvb_q);
163
164 strscpy(ctx->name, name, DVB_VB2_NAME_MAX);
165 ctx->nonblocking = nonblocking;
166 ctx->state = DVB_VB2_STATE_INIT;
167
168 ret = vb2_core_queue_init(q);
169 if (ret) {
170 ctx->state = DVB_VB2_STATE_NONE;
171 dprintk(1, "[%s] errno=%d\n", ctx->name, ret);
172 return ret;
173 }
174
175 dprintk(3, "[%s]\n", ctx->name);
176
177 return 0;
178}
179
180int dvb_vb2_release(struct dvb_vb2_ctx *ctx)
181{
182 struct vb2_queue *q = (struct vb2_queue *)&ctx->vb_q;
183
184 if (ctx->state & DVB_VB2_STATE_INIT)
185 vb2_core_queue_release(q);
186
187 ctx->state = DVB_VB2_STATE_NONE;
188 dprintk(3, "[%s]\n", ctx->name);
189
190 return 0;
191}
192
193int dvb_vb2_stream_on(struct dvb_vb2_ctx *ctx)
194{
195 struct vb2_queue *q = &ctx->vb_q;
196 int ret;
197
198 ret = vb2_core_streamon(q, q->type);
199 if (ret) {
200 ctx->state = DVB_VB2_STATE_NONE;
201 dprintk(1, "[%s] errno=%d\n", ctx->name, ret);
202 return ret;
203 }
204 ctx->state |= DVB_VB2_STATE_STREAMON;
205 dprintk(3, "[%s]\n", ctx->name);
206
207 return 0;
208}
209
210int dvb_vb2_stream_off(struct dvb_vb2_ctx *ctx)
211{
212 struct vb2_queue *q = (struct vb2_queue *)&ctx->vb_q;
213 int ret;
214
215 ctx->state &= ~DVB_VB2_STATE_STREAMON;
216 ret = vb2_core_streamoff(q, q->type);
217 if (ret) {
218 ctx->state = DVB_VB2_STATE_NONE;
219 dprintk(1, "[%s] errno=%d\n", ctx->name, ret);
220 return ret;
221 }
222 dprintk(3, "[%s]\n", ctx->name);
223
224 return 0;
225}
226
227int dvb_vb2_is_streaming(struct dvb_vb2_ctx *ctx)
228{
229 return (ctx->state & DVB_VB2_STATE_STREAMON);
230}
231
232int dvb_vb2_fill_buffer(struct dvb_vb2_ctx *ctx,
233 const unsigned char *src, int len,
234 enum dmx_buffer_flags *buffer_flags,
235 bool flush)
236{
237 unsigned long flags = 0;
238 void *vbuf = NULL;
239 int todo = len;
240 unsigned char *psrc = (unsigned char *)src;
241 int ll = 0;
242
243 /*
244 * normal case: This func is called twice from demux driver
245 * one with valid src pointer, second time with NULL pointer
246 */
247 if (!src || !len)
248 return 0;
249 spin_lock_irqsave(&ctx->slock, flags);
250 if (buffer_flags && *buffer_flags) {
251 ctx->flags |= *buffer_flags;
252 *buffer_flags = 0;
253 }
254 while (todo) {
255 if (!ctx->buf) {
256 if (list_empty(&ctx->dvb_q)) {
257 dprintk(3, "[%s] Buffer overflow!!!\n",
258 ctx->name);
259 break;
260 }
261
262 ctx->buf = list_entry(ctx->dvb_q.next,
263 struct dvb_buffer, list);
264 ctx->remain = vb2_plane_size(&ctx->buf->vb, 0);
265 ctx->offset = 0;
266 }
267
268 if (!dvb_vb2_is_streaming(ctx)) {
269 vb2_buffer_done(&ctx->buf->vb, VB2_BUF_STATE_ERROR);
270 list_del(&ctx->buf->list);
271 ctx->buf = NULL;
272 break;
273 }
274
275 /* Fill buffer */
276 ll = min(todo, ctx->remain);
277 vbuf = vb2_plane_vaddr(&ctx->buf->vb, 0);
278 memcpy(vbuf + ctx->offset, psrc, ll);
279 todo -= ll;
280 psrc += ll;
281
282 ctx->remain -= ll;
283 ctx->offset += ll;
284
285 if (ctx->remain == 0) {
286 vb2_buffer_done(&ctx->buf->vb, VB2_BUF_STATE_DONE);
287 list_del(&ctx->buf->list);
288 ctx->buf = NULL;
289 }
290 }
291
292 if (flush && ctx->buf) {
293 vb2_set_plane_payload(&ctx->buf->vb, 0, ll);
294 vb2_buffer_done(&ctx->buf->vb, VB2_BUF_STATE_DONE);
295 list_del(&ctx->buf->list);
296 ctx->buf = NULL;
297 }
298 spin_unlock_irqrestore(&ctx->slock, flags);
299
300 if (todo)
301 dprintk(1, "[%s] %d bytes are dropped.\n", ctx->name, todo);
302 else
303 dprintk(3, "[%s]\n", ctx->name);
304
305 dprintk(3, "[%s] %d bytes are copied\n", ctx->name, len - todo);
306 return (len - todo);
307}
308
309int dvb_vb2_reqbufs(struct dvb_vb2_ctx *ctx, struct dmx_requestbuffers *req)
310{
311 int ret;
312
313 /* Adjust size to a sane value */
314 if (req->size > DVB_V2_MAX_SIZE)
315 req->size = DVB_V2_MAX_SIZE;
316
317 /* FIXME: round req->size to a 188 or 204 multiple */
318
319 ctx->buf_siz = req->size;
320 ctx->buf_cnt = req->count;
321 ret = vb2_core_reqbufs(&ctx->vb_q, VB2_MEMORY_MMAP, 0, &req->count);
322 if (ret) {
323 ctx->state = DVB_VB2_STATE_NONE;
324 dprintk(1, "[%s] count=%d size=%d errno=%d\n", ctx->name,
325 ctx->buf_cnt, ctx->buf_siz, ret);
326 return ret;
327 }
328 ctx->state |= DVB_VB2_STATE_REQBUFS;
329 dprintk(3, "[%s] count=%d size=%d\n", ctx->name,
330 ctx->buf_cnt, ctx->buf_siz);
331
332 return 0;
333}
334
335int dvb_vb2_querybuf(struct dvb_vb2_ctx *ctx, struct dmx_buffer *b)
336{
337 struct vb2_queue *q = &ctx->vb_q;
338 struct vb2_buffer *vb2 = vb2_get_buffer(q, b->index);
339
340 if (!vb2) {
341 dprintk(1, "[%s] invalid buffer index\n", ctx->name);
342 return -EINVAL;
343 }
344 vb2_core_querybuf(&ctx->vb_q, vb2, b);
345 dprintk(3, "[%s] index=%d\n", ctx->name, b->index);
346 return 0;
347}
348
349int dvb_vb2_expbuf(struct dvb_vb2_ctx *ctx, struct dmx_exportbuffer *exp)
350{
351 struct vb2_queue *q = &ctx->vb_q;
352 struct vb2_buffer *vb2 = vb2_get_buffer(q, exp->index);
353 int ret;
354
355 if (!vb2) {
356 dprintk(1, "[%s] invalid buffer index\n", ctx->name);
357 return -EINVAL;
358 }
359
360 ret = vb2_core_expbuf(&ctx->vb_q, &exp->fd, q->type, vb2,
361 0, exp->flags);
362 if (ret) {
363 dprintk(1, "[%s] index=%d errno=%d\n", ctx->name,
364 exp->index, ret);
365 return ret;
366 }
367 dprintk(3, "[%s] index=%d fd=%d\n", ctx->name, exp->index, exp->fd);
368
369 return 0;
370}
371
372int dvb_vb2_qbuf(struct dvb_vb2_ctx *ctx, struct dmx_buffer *b)
373{
374 struct vb2_queue *q = &ctx->vb_q;
375 struct vb2_buffer *vb2 = vb2_get_buffer(q, b->index);
376 int ret;
377
378 if (!vb2) {
379 dprintk(1, "[%s] invalid buffer index\n", ctx->name);
380 return -EINVAL;
381 }
382 ret = vb2_core_qbuf(&ctx->vb_q, vb2, b, NULL);
383 if (ret) {
384 dprintk(1, "[%s] index=%d errno=%d\n", ctx->name,
385 b->index, ret);
386 return ret;
387 }
388 dprintk(5, "[%s] index=%d\n", ctx->name, b->index);
389
390 return 0;
391}
392
393int dvb_vb2_dqbuf(struct dvb_vb2_ctx *ctx, struct dmx_buffer *b)
394{
395 unsigned long flags;
396 int ret;
397
398 ret = vb2_core_dqbuf(&ctx->vb_q, &b->index, b, ctx->nonblocking);
399 if (ret) {
400 dprintk(1, "[%s] errno=%d\n", ctx->name, ret);
401 return ret;
402 }
403
404 spin_lock_irqsave(&ctx->slock, flags);
405 b->count = ctx->count++;
406 b->flags = ctx->flags;
407 ctx->flags = 0;
408 spin_unlock_irqrestore(&ctx->slock, flags);
409
410 dprintk(5, "[%s] index=%d, count=%d, flags=%d\n",
411 ctx->name, b->index, ctx->count, b->flags);
412
413
414 return 0;
415}
416
417int dvb_vb2_mmap(struct dvb_vb2_ctx *ctx, struct vm_area_struct *vma)
418{
419 int ret;
420
421 ret = vb2_mmap(&ctx->vb_q, vma);
422 if (ret) {
423 dprintk(1, "[%s] errno=%d\n", ctx->name, ret);
424 return ret;
425 }
426 dprintk(3, "[%s] ret=%d\n", ctx->name, ret);
427
428 return 0;
429}
430
431__poll_t dvb_vb2_poll(struct dvb_vb2_ctx *ctx, struct file *file,
432 poll_table *wait)
433{
434 dprintk(3, "[%s]\n", ctx->name);
435 return vb2_core_poll(&ctx->vb_q, file, wait);
436}
437