static int __videobuf_copy_stream(struct videobuf_queue *q, char __user *data, size_t count, size_t pos, int vbihack, int nonblocking) { unsigned int *fc; struct videobuf_dma_contig_memory *mem = q->read_buf->priv; BUG_ON(!mem); MAGIC_CHECK(mem->magic, MAGIC_DC_MEM); if (vbihack) { /* dirty, undocumented hack -- pass the frame counter * within the last four bytes of each vbi data block. * We need that one to maintain backward compatibility * to all vbi decoding software out there ... */ fc = (unsigned int *)mem->vaddr; fc += (q->read_buf->size >> 2) - 1; *fc = q->read_buf->field_count >> 1; dev_dbg(q->dev, "vbihack: %d\n", *fc); } /* copy stuff using the common method */ count = __videobuf_copy_to_user(q, data, count, nonblocking); if ((count == -EFAULT) && (pos == 0)) return -EFAULT; return count; }
static int __videobuf_copy_stream(struct videobuf_queue *q, struct videobuf_buffer *buf, char __user *data, size_t count, size_t pos, int vbihack, int nonblocking) { unsigned int *fc = CALLPTR(q, vaddr, buf); if (vbihack) { /* dirty, undocumented hack -- pass the frame counter * within the last four bytes of each vbi data block. * We need that one to maintain backward compatibility * to all vbi decoding software out there ... */ fc += (buf->size >> 2) - 1; *fc = buf->field_count >> 1; dprintk(1, "vbihack: %d\n", *fc); } /* copy stuff using the common method */ count = __videobuf_copy_to_user(q, buf, data, count, nonblocking); if ((count == -EFAULT) && (pos == 0)) return -EFAULT; return count; }
static int __videobuf_copy_stream ( struct videobuf_queue *q, char __user *data, size_t count, size_t pos, int vbihack, int nonblocking ) { unsigned int *fc; struct videobuf_vmalloc_memory *mem=q->read_buf->priv; BUG_ON (!mem); MAGIC_CHECK(mem->magic,MAGIC_VMAL_MEM); if (vbihack) { fc = (unsigned int*)mem->vmalloc; fc += (q->read_buf->size>>2) -1; *fc = q->read_buf->field_count >> 1; dprintk(1,"vbihack: %d\n",*fc); } count = __videobuf_copy_to_user (q,data,count,nonblocking); if ( (count==-EFAULT) && (0 == pos) ) return -EFAULT; return count; }
ssize_t videobuf_read_one(struct videobuf_queue *q, char __user *data, size_t count, loff_t *ppos, int nonblocking) { enum v4l2_field field; unsigned long flags = 0; unsigned size = 0, nbufs = 1; int retval; MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS); videobuf_queue_lock(q); q->ops->buf_setup(q, &nbufs, &size); if (NULL == q->read_buf && count >= size && !nonblocking) { retval = videobuf_read_zerocopy(q, data, count, ppos); if (retval >= 0 || retval == -EIO) /* ok, all done */ goto done; /* fallback to kernel bounce buffer on failures */ } if (NULL == q->read_buf) { /* need to capture a new frame */ retval = -ENOMEM; q->read_buf = videobuf_alloc_vb(q); dprintk(1, "video alloc=0x%p\n", q->read_buf); if (NULL == q->read_buf) goto done; q->read_buf->memory = V4L2_MEMORY_USERPTR; q->read_buf->bsize = count; /* preferred size */ field = videobuf_next_field(q); retval = q->ops->buf_prepare(q, q->read_buf, field); if (0 != retval) { kfree(q->read_buf); q->read_buf = NULL; goto done; } spin_lock_irqsave(q->irqlock, flags); q->ops->buf_queue(q, q->read_buf); spin_unlock_irqrestore(q->irqlock, flags); q->read_off = 0; } /* wait until capture is done */ retval = videobuf_waiton(q, q->read_buf, nonblocking, 1); if (0 != retval) goto done; CALL(q, sync, q, q->read_buf); if (VIDEOBUF_ERROR == q->read_buf->state) { /* catch I/O errors */ q->ops->buf_release(q, q->read_buf); kfree(q->read_buf); q->read_buf = NULL; retval = -EIO; goto done; } /* Copy to userspace */ retval = __videobuf_copy_to_user(q, q->read_buf, data, count, nonblocking); if (retval < 0) goto done; q->read_off += retval; if (q->read_off == q->read_buf->size) { /* all data copied, cleanup */ q->ops->buf_release(q, q->read_buf); kfree(q->read_buf); q->read_buf = NULL; } done: videobuf_queue_unlock(q); return retval; }