示例#1
0
static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,enum v4l2_field field)
{
	struct file *file = q->priv_data;
	struct saa7146_fh *fh = file->private_data;
	struct saa7146_dev *dev = fh->dev;
	struct saa7146_buf *buf = (struct saa7146_buf *)vb;

	int err = 0;
	int lines, llength, size;

	lines   = 16 * 2 ; /* 2 fields */
	llength = vbi_pixel_to_capture;
	size = lines * llength;

	DEB_VBI("vb:%p\n", vb);

	if (0 != buf->vb.baddr  &&  buf->vb.bsize < size) {
		DEB_VBI("size mismatch\n");
		return -EINVAL;
	}

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

	if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
		struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);

		buf->vb.width  = llength;
		buf->vb.height = lines;
		buf->vb.size   = size;
		buf->vb.field  = field;	// FIXME: check this

		saa7146_pgtable_free(dev->pci, &buf->pt[2]);
		saa7146_pgtable_alloc(dev->pci, &buf->pt[2]);

		err = videobuf_iolock(q,&buf->vb, NULL);
		if (err)
			goto oops;
		err = saa7146_pgtable_build_single(dev->pci, &buf->pt[2],
						 dma->sglist, dma->sglen);
		if (0 != err)
			return err;
	}
	buf->vb.state = VIDEOBUF_PREPARED;
	buf->activate = buffer_activate;

	return 0;

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

	return err;
}
示例#2
0
void *saa7146_vmalloc_build_pgtable(struct pci_dev *pci, long length, struct saa7146_pgtable *pt)
{
    int pages = (length+PAGE_SIZE-1)/PAGE_SIZE;
    void *mem = vmalloc_32(length);
    int slen = 0;

    if (NULL == mem)
        goto err_null;

    if (!(pt->slist = vmalloc_to_sg(mem, pages)))
        goto err_free_mem;

    if (saa7146_pgtable_alloc(pci, pt))
        goto err_free_slist;

    pt->nents = pages;
    slen = pci_map_sg(pci,pt->slist,pt->nents,PCI_DMA_FROMDEVICE);
    if (0 == slen)
        goto err_free_pgtable;

    if (0 != saa7146_pgtable_build_single(pci, pt, pt->slist, slen))
        goto err_unmap_sg;

    return mem;

err_unmap_sg:
    pci_unmap_sg(pci, pt->slist, pt->nents, PCI_DMA_FROMDEVICE);
err_free_pgtable:
    saa7146_pgtable_free(pci, pt);
err_free_slist:
    kfree(pt->slist);
    pt->slist = NULL;
err_free_mem:
    vfree(mem);
err_null:
    return NULL;
}
static int buffer_prepare(struct videobuf_queue *q,
			  struct videobuf_buffer *vb, enum v4l2_field field)
{
	struct file *file = q->priv_data;
	struct saa7146_fh *fh = file->private_data;
	struct saa7146_dev *dev = fh->dev;
	struct saa7146_vv *vv = dev->vv_data;
	struct saa7146_buf *buf = (struct saa7146_buf *)vb;
	int size,err = 0;

	DEB_CAP(("vbuf:%p\n",vb));

	/* sanity checks */
	if (fh->video_fmt.width  < 48 ||
	    fh->video_fmt.height < 32 ||
	    fh->video_fmt.width  > vv->standard->h_max_out ||
	    fh->video_fmt.height > vv->standard->v_max_out) {
		DEB_D(("w (%d) / h (%d) out of bounds.\n",fh->video_fmt.width,fh->video_fmt.height));
		return -EINVAL;
	}

	size = fh->video_fmt.sizeimage;
	if (0 != buf->vb.baddr && buf->vb.bsize < size) {
		DEB_D(("size mismatch.\n"));
		return -EINVAL;
	}

	DEB_CAP(("buffer_prepare [size=%dx%d,bytes=%d,fields=%s]\n",
		fh->video_fmt.width,fh->video_fmt.height,size,v4l2_field_names[fh->video_fmt.field]));
	if (buf->vb.width  != fh->video_fmt.width  ||
	    buf->vb.bytesperline != fh->video_fmt.bytesperline ||
	    buf->vb.height != fh->video_fmt.height ||
	    buf->vb.size   != size ||
	    buf->vb.field  != field      ||
	    buf->vb.field  != fh->video_fmt.field  ||
	    buf->fmt       != &fh->video_fmt) {
		saa7146_dma_free(dev,buf);
	}

	if (STATE_NEEDS_INIT == buf->vb.state) {
		struct saa7146_format *sfmt;

		buf->vb.bytesperline  = fh->video_fmt.bytesperline;
		buf->vb.width  = fh->video_fmt.width;
		buf->vb.height = fh->video_fmt.height;
		buf->vb.size   = size;
		buf->vb.field  = field;
		buf->fmt       = &fh->video_fmt;
		buf->vb.field  = fh->video_fmt.field;

		sfmt = format_by_fourcc(dev,buf->fmt->pixelformat);

		if( 0 != IS_PLANAR(sfmt->trans)) {
			saa7146_pgtable_free(dev->pci, &buf->pt[0]);
			saa7146_pgtable_free(dev->pci, &buf->pt[1]);
			saa7146_pgtable_free(dev->pci, &buf->pt[2]);

			saa7146_pgtable_alloc(dev->pci, &buf->pt[0]);
			saa7146_pgtable_alloc(dev->pci, &buf->pt[1]);
			saa7146_pgtable_alloc(dev->pci, &buf->pt[2]);
		} else {
			saa7146_pgtable_free(dev->pci, &buf->pt[0]);
			saa7146_pgtable_alloc(dev->pci, &buf->pt[0]);
		}

		err = videobuf_iolock(dev->pci,&buf->vb, &vv->ov_fb);
		if (err)
			goto oops;
		err = saa7146_pgtable_build(dev,buf);
		if (err)
			goto oops;
	}
	buf->vb.state = STATE_PREPARED;
	buf->activate = buffer_activate;

	return 0;

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

	return err;
}