aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/gspca
diff options
context:
space:
mode:
authorJean-Francois Moine <moinejf@free.fr>2008-07-02 08:14:56 -0400
committerMauro Carvalho Chehab <mchehab@infradead.org>2008-07-20 06:16:00 -0400
commit82643d0e90896fba965e6e43692538b2cc093d34 (patch)
tree417f6af7c540ab08767e60fcca1ce23b198f1119 /drivers/media/video/gspca
parent956e42d28f300f5bb928fb5850b3e3c0a8982d23 (diff)
V4L/DVB (8181): gspca: read() did not work (loop in kernel, timeout...)
main: Remove some vidioc_xx traces. main: read() did not work (user irq instead of mmap irq). main: Lack of v4l1 compat. main: Process loop inside kernel when no frame arriving. main: Double qbuf in read() when too many buffered frames. Signed-off-by: Jean-Francois Moine <moinejf@free.fr> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media/video/gspca')
-rw-r--r--drivers/media/video/gspca/gspca.c71
1 files changed, 28 insertions, 43 deletions
diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c
index 13cd9968f1f5..25e42bd7af87 100644
--- a/drivers/media/video/gspca/gspca.c
+++ b/drivers/media/video/gspca/gspca.c
@@ -35,8 +35,6 @@
35 35
36#include "gspca.h" 36#include "gspca.h"
37 37
38#undef CONFIG_VIDEO_V4L1_COMPAT
39
40/* global values */ 38/* global values */
41#define DEF_NURBS 2 /* default number of URBs (mmap) */ 39#define DEF_NURBS 2 /* default number of URBs (mmap) */
42#define USR_NURBS 5 /* default number of URBs (userptr) */ 40#define USR_NURBS 5 /* default number of URBs (userptr) */
@@ -45,8 +43,8 @@ MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>");
45MODULE_DESCRIPTION("GSPCA USB Camera Driver"); 43MODULE_DESCRIPTION("GSPCA USB Camera Driver");
46MODULE_LICENSE("GPL"); 44MODULE_LICENSE("GPL");
47 45
48#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 1) 46#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 2)
49static const char version[] = "2.1.1"; 47static const char version[] = "2.1.2";
50 48
51static int video_nr = -1; 49static int video_nr = -1;
52 50
@@ -281,10 +279,16 @@ struct gspca_frame *gspca_frame_add(struct gspca_dev *gspca_dev,
281 frame->v4l2_buf.length); 279 frame->v4l2_buf.length);
282 packet_type = DISCARD_PACKET; 280 packet_type = DISCARD_PACKET;
283 } else { 281 } else {
284 if (frame->v4l2_buf.memory != V4L2_MEMORY_USERPTR) 282 if (frame->v4l2_buf.memory != V4L2_MEMORY_USERPTR) {
285 memcpy(frame->data_end, data, len); 283 memcpy(frame->data_end, data, len);
286 else 284 } else {
287 copy_to_user(frame->data_end, data, len); 285 if (copy_to_user(frame->data_end,
286 data, len) != 0) {
287 PDEBUG(D_ERR|D_PACK,
288 "copy to user failed");
289 packet_type = DISCARD_PACKET;
290 }
291 }
288 frame->data_end += len; 292 frame->data_end += len;
289 } 293 }
290 } 294 }
@@ -565,9 +569,8 @@ static int create_urbs(struct gspca_dev *gspca_dev,
565 bsize = psize * npkt; 569 bsize = psize * npkt;
566 PDEBUG(D_STREAM, 570 PDEBUG(D_STREAM,
567 "isoc %d pkts size %d (bsize:%d)", npkt, psize, bsize); 571 "isoc %d pkts size %d (bsize:%d)", npkt, psize, bsize);
568/*fixme:change for userptr*/
569/*fixme:don't submit all URBs when userptr*/ 572/*fixme:don't submit all URBs when userptr*/
570 if (gspca_dev->memory == V4L2_MEMORY_MMAP) { 573 if (gspca_dev->memory != V4L2_MEMORY_USERPTR) {
571 usb_complete = isoc_irq_mmap; 574 usb_complete = isoc_irq_mmap;
572 nurbs = DEF_NURBS; 575 nurbs = DEF_NURBS;
573 } else { 576 } else {
@@ -746,8 +749,6 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
746 int i, j, index; 749 int i, j, index;
747 __u32 fmt_tb[8]; 750 __u32 fmt_tb[8];
748 751
749 PDEBUG(D_CONF, "enum fmt cap");
750
751 /* give an index to each format */ 752 /* give an index to each format */
752 index = 0; 753 index = 0;
753 j = 0; 754 j = 0;
@@ -792,14 +793,6 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
792 fmt->fmt.pix.width = gspca_dev->width; 793 fmt->fmt.pix.width = gspca_dev->width;
793 fmt->fmt.pix.height = gspca_dev->height; 794 fmt->fmt.pix.height = gspca_dev->height;
794 fmt->fmt.pix.pixelformat = gspca_dev->pixfmt; 795 fmt->fmt.pix.pixelformat = gspca_dev->pixfmt;
795#ifdef VIDEO_ADV_DEBUG
796 if (gspca_debug & D_CONF) {
797 PDEBUG_MODE("get fmt cap",
798 fmt->fmt.pix.pixelformat,
799 fmt->fmt.pix.width,
800 fmt->fmt.pix.height);
801 }
802#endif
803 fmt->fmt.pix.field = V4L2_FIELD_NONE; 796 fmt->fmt.pix.field = V4L2_FIELD_NONE;
804 fmt->fmt.pix.bytesperline = get_v4l2_depth(fmt->fmt.pix.pixelformat) 797 fmt->fmt.pix.bytesperline = get_v4l2_depth(fmt->fmt.pix.pixelformat)
805 * fmt->fmt.pix.width / 8; 798 * fmt->fmt.pix.width / 8;
@@ -894,13 +887,6 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
894 return 0; 887 return 0;
895 } 888 }
896#endif 889#endif
897#ifdef VIDEO_ADV_DEBUG
898 if (gspca_debug & D_CONF) {
899 PDEBUG_MODE("set fmt cap",
900 fmt->fmt.pix.pixelformat,
901 fmt->fmt.pix.width, fmt->fmt.pix.height);
902 }
903#endif
904 if (mutex_lock_interruptible(&gspca_dev->queue_lock)) 890 if (mutex_lock_interruptible(&gspca_dev->queue_lock))
905 return -ERESTARTSYS; 891 return -ERESTARTSYS;
906 892
@@ -1013,7 +999,6 @@ static int vidioc_querycap(struct file *file, void *priv,
1013{ 999{
1014 struct gspca_dev *gspca_dev = priv; 1000 struct gspca_dev *gspca_dev = priv;
1015 1001
1016 PDEBUG(D_CONF, "querycap");
1017 memset(cap, 0, sizeof *cap); 1002 memset(cap, 0, sizeof *cap);
1018 strncpy(cap->driver, gspca_dev->sd_desc->name, sizeof cap->driver); 1003 strncpy(cap->driver, gspca_dev->sd_desc->name, sizeof cap->driver);
1019 strncpy(cap->card, gspca_dev->cam.dev_name, sizeof cap->card); 1004 strncpy(cap->card, gspca_dev->cam.dev_name, sizeof cap->card);
@@ -1071,7 +1056,6 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
1071 struct ctrl *ctrls; 1056 struct ctrl *ctrls;
1072 int i, ret; 1057 int i, ret;
1073 1058
1074 PDEBUG(D_CONF, "set ctrl");
1075 for (i = 0, ctrls = gspca_dev->sd_desc->ctrls; 1059 for (i = 0, ctrls = gspca_dev->sd_desc->ctrls;
1076 i < gspca_dev->sd_desc->nctrls; 1060 i < gspca_dev->sd_desc->nctrls;
1077 i++, ctrls++) { 1061 i++, ctrls++) {
@@ -1155,7 +1139,6 @@ static int vidioc_reqbufs(struct file *file, void *priv,
1155 struct gspca_dev *gspca_dev = priv; 1139 struct gspca_dev *gspca_dev = priv;
1156 int i, ret = 0; 1140 int i, ret = 0;
1157 1141
1158 PDEBUG(D_STREAM, "reqbufs %d", rb->count);
1159 if (rb->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 1142 if (rb->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1160 return -EINVAL; 1143 return -EINVAL;
1161 switch (rb->memory) { 1144 switch (rb->memory) {
@@ -1205,7 +1188,6 @@ static int vidioc_querybuf(struct file *file, void *priv,
1205 struct gspca_dev *gspca_dev = priv; 1188 struct gspca_dev *gspca_dev = priv;
1206 struct gspca_frame *frame; 1189 struct gspca_frame *frame;
1207 1190
1208 PDEBUG(D_STREAM, "querybuf");
1209 if (v4l2_buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE 1191 if (v4l2_buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE
1210 || v4l2_buf->index < 0 1192 || v4l2_buf->index < 0
1211 || v4l2_buf->index >= gspca_dev->nframes) 1193 || v4l2_buf->index >= gspca_dev->nframes)
@@ -1222,7 +1204,6 @@ static int vidioc_streamon(struct file *file, void *priv,
1222 struct gspca_dev *gspca_dev = priv; 1204 struct gspca_dev *gspca_dev = priv;
1223 int ret; 1205 int ret;
1224 1206
1225 PDEBUG(D_STREAM, "stream on");
1226 if (buf_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 1207 if (buf_type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1227 return -EINVAL; 1208 return -EINVAL;
1228 if (mutex_lock_interruptible(&gspca_dev->queue_lock)) 1209 if (mutex_lock_interruptible(&gspca_dev->queue_lock))
@@ -1264,7 +1245,6 @@ static int vidioc_streamoff(struct file *file, void *priv,
1264 struct gspca_dev *gspca_dev = priv; 1245 struct gspca_dev *gspca_dev = priv;
1265 int ret; 1246 int ret;
1266 1247
1267 PDEBUG(D_STREAM, "stream off");
1268 if (buf_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 1248 if (buf_type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1269 return -EINVAL; 1249 return -EINVAL;
1270 if (!gspca_dev->streaming) 1250 if (!gspca_dev->streaming)
@@ -1499,8 +1479,10 @@ static int frame_wait(struct gspca_dev *gspca_dev,
1499 i = gspca_dev->fr_o; 1479 i = gspca_dev->fr_o;
1500 j = gspca_dev->fr_queue[i]; 1480 j = gspca_dev->fr_queue[i];
1501 frame = &gspca_dev->frame[j]; 1481 frame = &gspca_dev->frame[j];
1502 if (frame->v4l2_buf.flags & V4L2_BUF_FLAG_DONE) 1482 if (frame->v4l2_buf.flags & V4L2_BUF_FLAG_DONE) {
1483 atomic_dec(&gspca_dev->nevent);
1503 goto ok; 1484 goto ok;
1485 }
1504 if (nonblock_ing) /* no frame yet */ 1486 if (nonblock_ing) /* no frame yet */
1505 return -EAGAIN; 1487 return -EAGAIN;
1506 1488
@@ -1511,9 +1493,10 @@ static int frame_wait(struct gspca_dev *gspca_dev,
1511 msecs_to_jiffies(3000)); 1493 msecs_to_jiffies(3000));
1512 if (ret <= 0) { 1494 if (ret <= 0) {
1513 if (ret < 0) 1495 if (ret < 0)
1514 return ret; 1496 return ret; /* interrupt */
1515 return -EIO; 1497 return -EIO; /* timeout */
1516 } 1498 }
1499 atomic_dec(&gspca_dev->nevent);
1517 if (!gspca_dev->streaming || !gspca_dev->present) 1500 if (!gspca_dev->streaming || !gspca_dev->present)
1518 return -EIO; 1501 return -EIO;
1519 if (gspca_dev->memory == V4L2_MEMORY_USERPTR) 1502 if (gspca_dev->memory == V4L2_MEMORY_USERPTR)
@@ -1525,7 +1508,6 @@ static int frame_wait(struct gspca_dev *gspca_dev,
1525 break; 1508 break;
1526 } 1509 }
1527ok: 1510ok:
1528 atomic_dec(&gspca_dev->nevent);
1529 gspca_dev->fr_o = (i + 1) % gspca_dev->nframes; 1511 gspca_dev->fr_o = (i + 1) % gspca_dev->nframes;
1530 PDEBUG(D_FRAM, "frame wait q:%d i:%d o:%d", 1512 PDEBUG(D_FRAM, "frame wait q:%d i:%d o:%d",
1531 gspca_dev->fr_q, 1513 gspca_dev->fr_q,
@@ -1725,7 +1707,7 @@ static unsigned int dev_poll(struct file *file, poll_table *wait)
1725 goto out; 1707 goto out;
1726 } 1708 }
1727 1709
1728 /* if not mmap, treat the awaiting URBs */ 1710 /* if userptr, treat the awaiting URBs */
1729 if (gspca_dev->memory == V4L2_MEMORY_USERPTR 1711 if (gspca_dev->memory == V4L2_MEMORY_USERPTR
1730 && gspca_dev->capt_file == file) 1712 && gspca_dev->capt_file == file)
1731 isoc_transfer(gspca_dev); 1713 isoc_transfer(gspca_dev);
@@ -1748,7 +1730,7 @@ static ssize_t dev_read(struct file *file, char __user *data,
1748 struct gspca_frame *frame; 1730 struct gspca_frame *frame;
1749 struct v4l2_buffer v4l2_buf; 1731 struct v4l2_buffer v4l2_buf;
1750 struct timeval timestamp; 1732 struct timeval timestamp;
1751 int i, ret, ret2; 1733 int n, ret, ret2;
1752 1734
1753 PDEBUG(D_FRAM, "read (%d)", count); 1735 PDEBUG(D_FRAM, "read (%d)", count);
1754 if (!gspca_dev->present) 1736 if (!gspca_dev->present)
@@ -1760,9 +1742,9 @@ static ssize_t dev_read(struct file *file, char __user *data,
1760 return ret; 1742 return ret;
1761 break; 1743 break;
1762 case GSPCA_MEMORY_READ: 1744 case GSPCA_MEMORY_READ:
1763 if (gspca_dev->capt_file != file) 1745 if (gspca_dev->capt_file == file)
1764 return -EINVAL; 1746 break;
1765 break; 1747 /* fall thru */
1766 default: 1748 default:
1767 return -EINVAL; 1749 return -EINVAL;
1768 } 1750 }
@@ -1770,7 +1752,8 @@ static ssize_t dev_read(struct file *file, char __user *data,
1770 /* get a frame */ 1752 /* get a frame */
1771 jiffies_to_timeval(get_jiffies_64(), &timestamp); 1753 jiffies_to_timeval(get_jiffies_64(), &timestamp);
1772 timestamp.tv_sec--; 1754 timestamp.tv_sec--;
1773 for (i = 0; i < 2; i++) { 1755 n = 2;
1756 for (;;) {
1774 memset(&v4l2_buf, 0, sizeof v4l2_buf); 1757 memset(&v4l2_buf, 0, sizeof v4l2_buf);
1775 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 1758 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1776 v4l2_buf.memory = V4L2_MEMORY_MMAP; 1759 v4l2_buf.memory = V4L2_MEMORY_MMAP;
@@ -1781,8 +1764,10 @@ static ssize_t dev_read(struct file *file, char __user *data,
1781 } 1764 }
1782 1765
1783 /* if the process slept for more than 1 second, 1766 /* if the process slept for more than 1 second,
1784 * get a brand new frame */ 1767 * get anewer frame */
1785 frame = &gspca_dev->frame[v4l2_buf.index]; 1768 frame = &gspca_dev->frame[v4l2_buf.index];
1769 if (--n < 0)
1770 break; /* avoid infinite loop */
1786 if (frame->v4l2_buf.timestamp.tv_sec >= timestamp.tv_sec) 1771 if (frame->v4l2_buf.timestamp.tv_sec >= timestamp.tv_sec)
1787 break; 1772 break;
1788 ret = vidioc_qbuf(file, gspca_dev, &v4l2_buf); 1773 ret = vidioc_qbuf(file, gspca_dev, &v4l2_buf);