Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c7b0ac05 authored by Mauro Carvalho Chehab's avatar Mauro Carvalho Chehab
Browse files

V4L/DVB (3516): Make video_buf more generic



Video_buf were concerned to allow PCI devices to be used as
video capture devices. This patch extends video_buf features
by virtualizing pci-dependent functions and allowing other
type of devices to use it.
It is still DMA centric, although it may be used also by
devices that emulates scatter/gather behavior or a DMA device

Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@infradead.org>
parent b2fd16b4
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -50,14 +50,15 @@ void saa7146_res_free(struct saa7146_fh *fh, unsigned int bits)
/********************************************************************************/
/* common dma functions */

void saa7146_dma_free(struct saa7146_dev *dev,struct saa7146_buf *buf)
void saa7146_dma_free(struct saa7146_dev *dev,struct videobuf_queue *q,
						struct saa7146_buf *buf)
{
	DEB_EE(("dev:%p, buf:%p\n",dev,buf));

	BUG_ON(in_interrupt());

	videobuf_waiton(&buf->vb,0,0);
	videobuf_dma_pci_unmap(dev->pci, &buf->vb.dma);
	videobuf_dma_unmap(q, &buf->vb.dma);
	videobuf_dma_free(&buf->vb.dma);
	buf->vb.state = STATE_NEEDS_INIT;
}
+4 −4
Original line number Diff line number Diff line
@@ -236,7 +236,7 @@ static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,e
	}

	if (buf->vb.size != size)
		saa7146_dma_free(dev,buf);
		saa7146_dma_free(dev,q,buf);

	if (STATE_NEEDS_INIT == buf->vb.state) {
		buf->vb.width  = llength;
@@ -247,7 +247,7 @@ static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,e
		saa7146_pgtable_free(dev->pci, &buf->pt[2]);
		saa7146_pgtable_alloc(dev->pci, &buf->pt[2]);

		err = videobuf_iolock(dev->pci,&buf->vb, NULL);
		err = videobuf_iolock(q,&buf->vb, NULL);
		if (err)
			goto oops;
		err = saa7146_pgtable_build_single(dev->pci, &buf->pt[2], buf->vb.dma.sglist, buf->vb.dma.sglen);
@@ -261,7 +261,7 @@ static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,e

 oops:
	DEB_VBI(("error out.\n"));
	saa7146_dma_free(dev,buf);
	saa7146_dma_free(dev,q,buf);

	return err;
}
@@ -301,7 +301,7 @@ static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
	struct saa7146_buf *buf = (struct saa7146_buf *)vb;

	DEB_VBI(("vb:%p\n",vb));
	saa7146_dma_free(dev,buf);
	saa7146_dma_free(dev,q,buf);
}

static struct videobuf_queue_ops vbi_qops = {
+4 −4
Original line number Diff line number Diff line
@@ -1275,7 +1275,7 @@ static int buffer_prepare(struct videobuf_queue *q,
	    buf->vb.field  != field      ||
	    buf->vb.field  != fh->video_fmt.field  ||
	    buf->fmt       != &fh->video_fmt) {
		saa7146_dma_free(dev,buf);
		saa7146_dma_free(dev,q,buf);
	}

	if (STATE_NEEDS_INIT == buf->vb.state) {
@@ -1304,7 +1304,7 @@ static int buffer_prepare(struct videobuf_queue *q,
			saa7146_pgtable_alloc(dev->pci, &buf->pt[0]);
		}

		err = videobuf_iolock(dev->pci,&buf->vb, &vv->ov_fb);
		err = videobuf_iolock(q,&buf->vb, &vv->ov_fb);
		if (err)
			goto oops;
		err = saa7146_pgtable_build(dev,buf);
@@ -1318,7 +1318,7 @@ static int buffer_prepare(struct videobuf_queue *q,

 oops:
	DEB_D(("error out.\n"));
	saa7146_dma_free(dev,buf);
	saa7146_dma_free(dev,q,buf);

	return err;
}
@@ -1363,7 +1363,7 @@ static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
	struct saa7146_buf *buf = (struct saa7146_buf *)vb;

	DEB_CAP(("vbuf:%p\n",vb));
	saa7146_dma_free(dev,buf);
	saa7146_dma_free(dev,q,buf);
}

static struct videobuf_queue_ops video_qops = {
+10 −9
Original line number Diff line number Diff line
@@ -1397,7 +1397,7 @@ bttv_switch_overlay(struct bttv *btv, struct bttv_fh *fh,
		free_btres(btv,fh,RESOURCE_OVERLAY);
	if (NULL != old) {
		dprintk("switch_overlay: old=%p state is %d\n",old,old->vb.state);
		bttv_dma_free(btv, old);
		bttv_dma_free(&fh->cap,btv, old);
		kfree(old);
	}
	dprintk("switch_overlay: done\n");
@@ -1407,7 +1407,8 @@ bttv_switch_overlay(struct bttv *btv, struct bttv_fh *fh,
/* ----------------------------------------------------------------------- */
/* video4linux (1) interface                                               */

static int bttv_prepare_buffer(struct bttv *btv, struct bttv_buffer *buf,
static int bttv_prepare_buffer(struct videobuf_queue *q,struct bttv *btv,
			       struct bttv_buffer *buf,
			       const struct bttv_format *fmt,
			       unsigned int width, unsigned int height,
			       enum v4l2_field field)
@@ -1450,7 +1451,7 @@ static int bttv_prepare_buffer(struct bttv *btv, struct bttv_buffer *buf,
	/* alloc risc memory */
	if (STATE_NEEDS_INIT == buf->vb.state) {
		redo_dma_risc = 1;
		if (0 != (rc = videobuf_iolock(btv->c.pci,&buf->vb,&btv->fbuf)))
		if (0 != (rc = videobuf_iolock(q,&buf->vb,&btv->fbuf)))
			goto fail;
	}

@@ -1462,7 +1463,7 @@ static int bttv_prepare_buffer(struct bttv *btv, struct bttv_buffer *buf,
	return 0;

 fail:
	bttv_dma_free(btv,buf);
	bttv_dma_free(q,btv,buf);
	return rc;
}

@@ -1486,7 +1487,7 @@ buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
	struct bttv_buffer *buf = container_of(vb,struct bttv_buffer,vb);
	struct bttv_fh *fh = q->priv_data;

	return bttv_prepare_buffer(fh->btv, buf, fh->fmt,
	return bttv_prepare_buffer(q,fh->btv, buf, fh->fmt,
				   fh->width, fh->height, field);
}

@@ -1510,7 +1511,7 @@ static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
	struct bttv_buffer *buf = container_of(vb,struct bttv_buffer,vb);
	struct bttv_fh *fh = q->priv_data;

	bttv_dma_free(fh->btv,buf);
	bttv_dma_free(&fh->cap,fh->btv,buf);
}

static struct videobuf_queue_ops bttv_video_qops = {
@@ -2496,7 +2497,7 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
		field = (vm->height > bttv_tvnorms[btv->tvnorm].sheight/2)
			? V4L2_FIELD_INTERLACED
			: V4L2_FIELD_BOTTOM;
		retval = bttv_prepare_buffer(btv,buf,
		retval = bttv_prepare_buffer(&fh->cap,btv,buf,
					     format_by_palette(vm->format),
					     vm->width,vm->height,field);
		if (0 != retval)
@@ -2528,8 +2529,8 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
			retval = -EIO;
			/* fall through */
		case STATE_DONE:
			videobuf_dma_pci_sync(btv->c.pci,&buf->vb.dma);
			bttv_dma_free(btv,buf);
			videobuf_dma_sync(&fh->cap,&buf->vb.dma);
			bttv_dma_free(&fh->cap,btv,buf);
			break;
		default:
			retval = -EINVAL;
+2 −2
Original line number Diff line number Diff line
@@ -509,11 +509,11 @@ bttv_risc_hook(struct bttv *btv, int slot, struct btcx_riscmem *risc,
}

void
bttv_dma_free(struct bttv *btv, struct bttv_buffer *buf)
bttv_dma_free(struct videobuf_queue *q,struct bttv *btv, struct bttv_buffer *buf)
{
	BUG_ON(in_interrupt());
	videobuf_waiton(&buf->vb,0,0);
	videobuf_dma_pci_unmap(btv->c.pci, &buf->vb.dma);
	videobuf_dma_unmap(q, &buf->vb.dma);
	videobuf_dma_free(&buf->vb.dma);
	btcx_riscmem_free(btv->c.pci,&buf->bottom);
	btcx_riscmem_free(btv->c.pci,&buf->top);
Loading