drivers/media/dvb-core/dvb_vb2.c

Source file repositories/reference/linux-study-clean/drivers/media/dvb-core/dvb_vb2.c

File Facts

System
Linux kernel
Corpus path
drivers/media/dvb-core/dvb_vb2.c
Extension
.c
Size
10056 bytes
Lines
438
Domain
Driver Families
Bucket
drivers/media
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

if (!ctx->buf) {
			if (list_empty(&ctx->dvb_q)) {
				dprintk(3, "[%s] Buffer overflow!!!\n",
					ctx->name);
				break;
			}

			ctx->buf = list_entry(ctx->dvb_q.next,
					      struct dvb_buffer, list);
			ctx->remain = vb2_plane_size(&ctx->buf->vb, 0);
			ctx->offset = 0;
		}

		if (!dvb_vb2_is_streaming(ctx)) {
			vb2_buffer_done(&ctx->buf->vb, VB2_BUF_STATE_ERROR);
			list_del(&ctx->buf->list);
			ctx->buf = NULL;
			break;
		}

		/* Fill buffer */
		ll = min(todo, ctx->remain);
		vbuf = vb2_plane_vaddr(&ctx->buf->vb, 0);
		memcpy(vbuf + ctx->offset, psrc, ll);
		todo -= ll;
		psrc += ll;

		ctx->remain -= ll;
		ctx->offset += ll;

		if (ctx->remain == 0) {
			vb2_buffer_done(&ctx->buf->vb, VB2_BUF_STATE_DONE);
			list_del(&ctx->buf->list);
			ctx->buf = NULL;
		}
	}

	if (flush && ctx->buf) {
		vb2_set_plane_payload(&ctx->buf->vb, 0, ll);
		vb2_buffer_done(&ctx->buf->vb, VB2_BUF_STATE_DONE);
		list_del(&ctx->buf->list);
		ctx->buf = NULL;
	}
	spin_unlock_irqrestore(&ctx->slock, flags);

	if (todo)
		dprintk(1, "[%s] %d bytes are dropped.\n", ctx->name, todo);
	else
		dprintk(3, "[%s]\n", ctx->name);

	dprintk(3, "[%s] %d bytes are copied\n", ctx->name, len - todo);
	return (len - todo);
}

int dvb_vb2_reqbufs(struct dvb_vb2_ctx *ctx, struct dmx_requestbuffers *req)
{
	int ret;

	/* Adjust size to a sane value */
	if (req->size > DVB_V2_MAX_SIZE)
		req->size = DVB_V2_MAX_SIZE;

	/* FIXME: round req->size to a 188 or 204 multiple */

	ctx->buf_siz = req->size;
	ctx->buf_cnt = req->count;
	ret = vb2_core_reqbufs(&ctx->vb_q, VB2_MEMORY_MMAP, 0, &req->count);
	if (ret) {
		ctx->state = DVB_VB2_STATE_NONE;
		dprintk(1, "[%s] count=%d size=%d errno=%d\n", ctx->name,
			ctx->buf_cnt, ctx->buf_siz, ret);
		return ret;
	}
	ctx->state |= DVB_VB2_STATE_REQBUFS;
	dprintk(3, "[%s] count=%d size=%d\n", ctx->name,
		ctx->buf_cnt, ctx->buf_siz);

	return 0;
}

int dvb_vb2_querybuf(struct dvb_vb2_ctx *ctx, struct dmx_buffer *b)
{
	struct vb2_queue *q = &ctx->vb_q;
	struct vb2_buffer *vb2 = vb2_get_buffer(q, b->index);

	if (!vb2) {
		dprintk(1, "[%s] invalid buffer index\n", ctx->name);
		return -EINVAL;
	}
	vb2_core_querybuf(&ctx->vb_q, vb2, b);

Annotation

Implementation Notes