Skip to content

Commit

Permalink
V4L/DVB (3516): Make video_buf more generic
Browse files Browse the repository at this point in the history
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: Mauro Carvalho Chehab <mchehab@infradead.org>
  • Loading branch information
Mauro Carvalho Chehab committed Mar 24, 2006
1 parent b2fd16b commit c7b0ac0
Show file tree
Hide file tree
Showing 26 changed files with 340 additions and 174 deletions.
5 changes: 3 additions & 2 deletions drivers/media/common/saa7146_fops.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
8 changes: 4 additions & 4 deletions drivers/media/common/saa7146_vbi.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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);
Expand All @@ -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;
}
Expand Down Expand Up @@ -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 = {
Expand Down
8 changes: 4 additions & 4 deletions drivers/media/common/saa7146_video.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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);
Expand All @@ -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;
}
Expand Down Expand Up @@ -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 = {
Expand Down
19 changes: 10 additions & 9 deletions drivers/media/video/bttv-driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand All @@ -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)
Expand Down Expand Up @@ -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;
}

Expand All @@ -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;
}

Expand All @@ -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);
}

Expand All @@ -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 = {
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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;
Expand Down
4 changes: 2 additions & 2 deletions drivers/media/video/bttv-risc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
6 changes: 3 additions & 3 deletions drivers/media/video/bttv-vbi.c
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ static int vbi_buffer_prepare(struct videobuf_queue *q,
return -EINVAL;

if (STATE_NEEDS_INIT == buf->vb.state) {
if (0 != (rc = videobuf_iolock(btv->c.pci, &buf->vb, NULL)))
if (0 != (rc = videobuf_iolock(q, &buf->vb, NULL)))
goto fail;
if (0 != (rc = vbi_buffer_risc(btv,buf,fh->lines)))
goto fail;
Expand All @@ -109,7 +109,7 @@ static int vbi_buffer_prepare(struct videobuf_queue *q,
return 0;

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

Expand All @@ -136,7 +136,7 @@ static void vbi_buffer_release(struct videobuf_queue *q, struct videobuf_buffer
struct bttv_buffer *buf = container_of(vb,struct bttv_buffer,vb);

dprintk("free %p\n",vb);
bttv_dma_free(fh->btv,buf);
bttv_dma_free(&fh->cap,fh->btv,buf);
}

struct videobuf_queue_ops bttv_vbi_qops = {
Expand Down
3 changes: 2 additions & 1 deletion drivers/media/video/bttvp.h
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,8 @@ int bttv_buffer_activate_video(struct bttv *btv,
struct bttv_buffer_set *set);
int bttv_buffer_activate_vbi(struct bttv *btv,
struct bttv_buffer *vbi);
void bttv_dma_free(struct bttv *btv, struct bttv_buffer *buf);
void bttv_dma_free(struct videobuf_queue *q, struct bttv *btv,
struct bttv_buffer *buf);

/* overlay handling */
int bttv_overlay_risc(struct bttv *btv, struct bttv_overlay *ov,
Expand Down
4 changes: 2 additions & 2 deletions drivers/media/video/cx88/cx88-alsa.c
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,7 @@ static int dsp_buffer_free(snd_cx88_card_t *chip)
BUG_ON(!chip->dma_size);

dprintk(2,"Freeing buffer\n");
videobuf_dma_pci_unmap(chip->pci, &chip->dma_risc);
videobuf_pci_dma_unmap(chip->pci, &chip->dma_risc);
videobuf_dma_free(&chip->dma_risc);
btcx_riscmem_free(chip->pci,&chip->buf->risc);
kfree(chip->buf);
Expand Down Expand Up @@ -429,7 +429,7 @@ static int snd_cx88_hw_params(struct snd_pcm_substream * substream,
videobuf_dma_init_kernel(&buf->vb.dma,PCI_DMA_FROMDEVICE,
(PAGE_ALIGN(buf->vb.size) >> PAGE_SHIFT));

videobuf_dma_pci_map(chip->pci,&buf->vb.dma);
videobuf_pci_dma_map(chip->pci,&buf->vb.dma);


cx88_risc_databuffer(chip->pci, &buf->risc,
Expand Down
5 changes: 2 additions & 3 deletions drivers/media/video/cx88/cx88-blackbird.c
Original file line number Diff line number Diff line change
Expand Up @@ -1341,7 +1341,7 @@ bb_buf_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
enum v4l2_field field)
{
struct cx8802_fh *fh = q->priv_data;
return cx8802_buf_prepare(fh->dev, (struct cx88_buffer*)vb, field);
return cx8802_buf_prepare(q, fh->dev, (struct cx88_buffer*)vb, field);
}

static void
Expand All @@ -1354,8 +1354,7 @@ bb_buf_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
static void
bb_buf_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
{
struct cx8802_fh *fh = q->priv_data;
cx88_free_buffer(fh->dev->pci, (struct cx88_buffer*)vb);
cx88_free_buffer(q, (struct cx88_buffer*)vb);
}

static struct videobuf_queue_ops blackbird_qops = {
Expand Down
6 changes: 3 additions & 3 deletions drivers/media/video/cx88/cx88-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -213,13 +213,13 @@ int cx88_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc,
}

void
cx88_free_buffer(struct pci_dev *pci, struct cx88_buffer *buf)
cx88_free_buffer(struct videobuf_queue *q, struct cx88_buffer *buf)
{
BUG_ON(in_interrupt());
videobuf_waiton(&buf->vb,0,0);
videobuf_dma_pci_unmap(pci, &buf->vb.dma);
videobuf_dma_unmap(q, &buf->vb.dma);
videobuf_dma_free(&buf->vb.dma);
btcx_riscmem_free(pci, &buf->risc);
btcx_riscmem_free((struct pci_dev *)q->dev, &buf->risc);
buf->vb.state = STATE_NEEDS_INIT;
}

Expand Down
5 changes: 2 additions & 3 deletions drivers/media/video/cx88/cx88-dvb.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ static int dvb_buf_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
enum v4l2_field field)
{
struct cx8802_dev *dev = q->priv_data;
return cx8802_buf_prepare(dev, (struct cx88_buffer*)vb,field);
return cx8802_buf_prepare(q, dev, (struct cx88_buffer*)vb,field);
}

static void dvb_buf_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
Expand All @@ -101,8 +101,7 @@ static void dvb_buf_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)

static void dvb_buf_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
{
struct cx8802_dev *dev = q->priv_data;
cx88_free_buffer(dev->pci, (struct cx88_buffer*)vb);
cx88_free_buffer(q, (struct cx88_buffer*)vb);
}

static struct videobuf_queue_ops dvb_qops = {
Expand Down
28 changes: 14 additions & 14 deletions drivers/media/video/cx88/cx88-mpeg.c
Original file line number Diff line number Diff line change
Expand Up @@ -163,8 +163,8 @@ static int cx8802_restart_queue(struct cx8802_dev *dev,

/* ------------------------------------------------------------------ */

int cx8802_buf_prepare(struct cx8802_dev *dev, struct cx88_buffer *buf,
enum v4l2_field field)
int cx8802_buf_prepare(struct videobuf_queue *q, struct cx8802_dev *dev,
struct cx88_buffer *buf, enum v4l2_field field)
{
int size = dev->ts_packet_size * dev->ts_packet_count;
int rc;
Expand All @@ -179,7 +179,7 @@ int cx8802_buf_prepare(struct cx8802_dev *dev, struct cx88_buffer *buf,
buf->vb.size = size;
buf->vb.field = field /*V4L2_FIELD_TOP*/;

if (0 != (rc = videobuf_iolock(dev->pci,&buf->vb,NULL)))
if (0 != (rc = videobuf_iolock(q,&buf->vb,NULL)))
goto fail;
cx88_risc_databuffer(dev->pci, &buf->risc,
buf->vb.dma.sglist,
Expand All @@ -189,36 +189,36 @@ int cx8802_buf_prepare(struct cx8802_dev *dev, struct cx88_buffer *buf,
return 0;

fail:
cx88_free_buffer(dev->pci,buf);
cx88_free_buffer(q,buf);
return rc;
}

void cx8802_buf_queue(struct cx8802_dev *dev, struct cx88_buffer *buf)
{
struct cx88_buffer *prev;
struct cx88_dmaqueue *q = &dev->mpegq;
struct cx88_dmaqueue *cx88q = &dev->mpegq;

dprintk( 1, "cx8802_buf_queue\n" );
/* add jump to stopper */
buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma);
buf->risc.jmp[1] = cpu_to_le32(cx88q->stopper.dma);

if (list_empty(&q->active)) {
if (list_empty(&cx88q->active)) {
dprintk( 0, "queue is empty - first active\n" );
list_add_tail(&buf->vb.queue,&q->active);
cx8802_start_dma(dev, q, buf);
list_add_tail(&buf->vb.queue,&cx88q->active);
cx8802_start_dma(dev, cx88q, buf);
buf->vb.state = STATE_ACTIVE;
buf->count = q->count++;
mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
buf->count = cx88q->count++;
mod_timer(&cx88q->timeout, jiffies+BUFFER_TIMEOUT);
dprintk(0,"[%p/%d] %s - first active\n",
buf, buf->vb.i, __FUNCTION__);

} else {
dprintk( 1, "queue is not empty - append to active\n" );
prev = list_entry(q->active.prev, struct cx88_buffer, vb.queue);
list_add_tail(&buf->vb.queue,&q->active);
prev = list_entry(cx88q->active.prev, struct cx88_buffer, vb.queue);
list_add_tail(&buf->vb.queue,&cx88q->active);
buf->vb.state = STATE_ACTIVE;
buf->count = q->count++;
buf->count = cx88q->count++;
prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
dprintk( 1, "[%p/%d] %s - append to active\n",
buf, buf->vb.i, __FUNCTION__);
Expand Down
7 changes: 3 additions & 4 deletions drivers/media/video/cx88/cx88-vbi.c
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ vbi_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
buf->vb.size = size;
buf->vb.field = V4L2_FIELD_SEQ_TB;

if (0 != (rc = videobuf_iolock(dev->pci,&buf->vb,NULL)))
if (0 != (rc = videobuf_iolock(q,&buf->vb,NULL)))
goto fail;
cx88_risc_buffer(dev->pci, &buf->risc,
buf->vb.dma.sglist,
Expand All @@ -187,7 +187,7 @@ vbi_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
return 0;

fail:
cx88_free_buffer(dev->pci,buf);
cx88_free_buffer(q,buf);
return rc;
}

Expand Down Expand Up @@ -227,9 +227,8 @@ vbi_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
static void vbi_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
{
struct cx88_buffer *buf = container_of(vb,struct cx88_buffer,vb);
struct cx8800_fh *fh = q->priv_data;

cx88_free_buffer(fh->dev->pci,buf);
cx88_free_buffer(q,buf);
}

struct videobuf_queue_ops cx8800_vbi_qops = {
Expand Down
Loading

0 comments on commit c7b0ac0

Please sign in to comment.