#include "gspca.h"
-#undef CONFIG_VIDEO_V4L1_COMPAT
-
/* global values */
#define DEF_NURBS 2 /* default number of URBs (mmap) */
#define USR_NURBS 5 /* default number of URBs (userptr) */
MODULE_DESCRIPTION("GSPCA USB Camera Driver");
MODULE_LICENSE("GPL");
-#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 1)
-static const char version[] = "2.1.1";
+#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 2)
+static const char version[] = "2.1.2";
static int video_nr = -1;
frame->v4l2_buf.length);
packet_type = DISCARD_PACKET;
} else {
- if (frame->v4l2_buf.memory != V4L2_MEMORY_USERPTR)
+ if (frame->v4l2_buf.memory != V4L2_MEMORY_USERPTR) {
memcpy(frame->data_end, data, len);
- else
- copy_to_user(frame->data_end, data, len);
+ } else {
+ if (copy_to_user(frame->data_end,
+ data, len) != 0) {
+ PDEBUG(D_ERR|D_PACK,
+ "copy to user failed");
+ packet_type = DISCARD_PACKET;
+ }
+ }
frame->data_end += len;
}
}
bsize = psize * npkt;
PDEBUG(D_STREAM,
"isoc %d pkts size %d (bsize:%d)", npkt, psize, bsize);
-/*fixme:change for userptr*/
/*fixme:don't submit all URBs when userptr*/
- if (gspca_dev->memory == V4L2_MEMORY_MMAP) {
+ if (gspca_dev->memory != V4L2_MEMORY_USERPTR) {
usb_complete = isoc_irq_mmap;
nurbs = DEF_NURBS;
} else {
int i, j, index;
__u32 fmt_tb[8];
- PDEBUG(D_CONF, "enum fmt cap");
-
/* give an index to each format */
index = 0;
j = 0;
fmt->fmt.pix.width = gspca_dev->width;
fmt->fmt.pix.height = gspca_dev->height;
fmt->fmt.pix.pixelformat = gspca_dev->pixfmt;
-#ifdef VIDEO_ADV_DEBUG
- if (gspca_debug & D_CONF) {
- PDEBUG_MODE("get fmt cap",
- fmt->fmt.pix.pixelformat,
- fmt->fmt.pix.width,
- fmt->fmt.pix.height);
- }
-#endif
fmt->fmt.pix.field = V4L2_FIELD_NONE;
fmt->fmt.pix.bytesperline = get_v4l2_depth(fmt->fmt.pix.pixelformat)
* fmt->fmt.pix.width / 8;
fmt->fmt.pix.pixelformat = gspca_dev->pixfmt;
return 0;
}
-#endif
-#ifdef VIDEO_ADV_DEBUG
- if (gspca_debug & D_CONF) {
- PDEBUG_MODE("set fmt cap",
- fmt->fmt.pix.pixelformat,
- fmt->fmt.pix.width, fmt->fmt.pix.height);
- }
#endif
if (mutex_lock_interruptible(&gspca_dev->queue_lock))
return -ERESTARTSYS;
{
struct gspca_dev *gspca_dev = priv;
- PDEBUG(D_CONF, "querycap");
memset(cap, 0, sizeof *cap);
strncpy(cap->driver, gspca_dev->sd_desc->name, sizeof cap->driver);
strncpy(cap->card, gspca_dev->cam.dev_name, sizeof cap->card);
struct ctrl *ctrls;
int i, ret;
- PDEBUG(D_CONF, "set ctrl");
for (i = 0, ctrls = gspca_dev->sd_desc->ctrls;
i < gspca_dev->sd_desc->nctrls;
i++, ctrls++) {
struct gspca_dev *gspca_dev = priv;
int i, ret = 0;
- PDEBUG(D_STREAM, "reqbufs %d", rb->count);
if (rb->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
return -EINVAL;
switch (rb->memory) {
struct gspca_dev *gspca_dev = priv;
struct gspca_frame *frame;
- PDEBUG(D_STREAM, "querybuf");
if (v4l2_buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE
|| v4l2_buf->index < 0
|| v4l2_buf->index >= gspca_dev->nframes)
struct gspca_dev *gspca_dev = priv;
int ret;
- PDEBUG(D_STREAM, "stream on");
if (buf_type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
return -EINVAL;
if (mutex_lock_interruptible(&gspca_dev->queue_lock))
struct gspca_dev *gspca_dev = priv;
int ret;
- PDEBUG(D_STREAM, "stream off");
if (buf_type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
return -EINVAL;
if (!gspca_dev->streaming)
i = gspca_dev->fr_o;
j = gspca_dev->fr_queue[i];
frame = &gspca_dev->frame[j];
- if (frame->v4l2_buf.flags & V4L2_BUF_FLAG_DONE)
+ if (frame->v4l2_buf.flags & V4L2_BUF_FLAG_DONE) {
+ atomic_dec(&gspca_dev->nevent);
goto ok;
+ }
if (nonblock_ing) /* no frame yet */
return -EAGAIN;
msecs_to_jiffies(3000));
if (ret <= 0) {
if (ret < 0)
- return ret;
- return -EIO;
+ return ret; /* interrupt */
+ return -EIO; /* timeout */
}
+ atomic_dec(&gspca_dev->nevent);
if (!gspca_dev->streaming || !gspca_dev->present)
return -EIO;
if (gspca_dev->memory == V4L2_MEMORY_USERPTR)
break;
}
ok:
- atomic_dec(&gspca_dev->nevent);
gspca_dev->fr_o = (i + 1) % gspca_dev->nframes;
PDEBUG(D_FRAM, "frame wait q:%d i:%d o:%d",
gspca_dev->fr_q,
goto out;
}
- /* if not mmap, treat the awaiting URBs */
+ /* if userptr, treat the awaiting URBs */
if (gspca_dev->memory == V4L2_MEMORY_USERPTR
&& gspca_dev->capt_file == file)
isoc_transfer(gspca_dev);
struct gspca_frame *frame;
struct v4l2_buffer v4l2_buf;
struct timeval timestamp;
- int i, ret, ret2;
+ int n, ret, ret2;
PDEBUG(D_FRAM, "read (%d)", count);
if (!gspca_dev->present)
return ret;
break;
case GSPCA_MEMORY_READ:
- if (gspca_dev->capt_file != file)
- return -EINVAL;
- break;
+ if (gspca_dev->capt_file == file)
+ break;
+ /* fall thru */
default:
return -EINVAL;
}
/* get a frame */
jiffies_to_timeval(get_jiffies_64(), ×tamp);
timestamp.tv_sec--;
- for (i = 0; i < 2; i++) {
+ n = 2;
+ for (;;) {
memset(&v4l2_buf, 0, sizeof v4l2_buf);
v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
v4l2_buf.memory = V4L2_MEMORY_MMAP;
}
/* if the process slept for more than 1 second,
- * get a brand new frame */
+ * get anewer frame */
frame = &gspca_dev->frame[v4l2_buf.index];
+ if (--n < 0)
+ break; /* avoid infinite loop */
if (frame->v4l2_buf.timestamp.tv_sec >= timestamp.tv_sec)
break;
ret = vidioc_qbuf(file, gspca_dev, &v4l2_buf);