aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/gspca/gspca.c
diff options
context:
space:
mode:
authorJean-Francois Moine <moinejf@free.fr>2008-07-08 05:58:15 -0400
committerMauro Carvalho Chehab <mchehab@infradead.org>2008-07-20 06:18:04 -0400
commitac0d6df69bc72eabda944fd14a958074dc08ca0c (patch)
tree28d452f1d5f4ca2316b8e1ad11c7476998567407 /drivers/media/video/gspca/gspca.c
parentc41492c89a00630c7482eae25deaf9af91b73c98 (diff)
V4L/DVB (8232): gspca: Change the USERPTR mechanism.
main: Change the packet copy mechanism for userptr. Cannot do reqbufs ioctl when already done and count != 0. Accept count < frame size in read(). 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/gspca.c')
-rw-r--r--drivers/media/video/gspca/gspca.c202
1 files changed, 52 insertions, 150 deletions
diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c
index cb0aeb0c0a45..77e5e4f4335b 100644
--- a/drivers/media/video/gspca/gspca.c
+++ b/drivers/media/video/gspca/gspca.c
@@ -36,15 +36,14 @@
36#include "gspca.h" 36#include "gspca.h"
37 37
38/* global values */ 38/* global values */
39#define DEF_NURBS 2 /* default number of URBs (mmap) */ 39#define DEF_NURBS 2 /* default number of URBs */
40#define USR_NURBS 5 /* default number of URBs (userptr) */
41 40
42MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>"); 41MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>");
43MODULE_DESCRIPTION("GSPCA USB Camera Driver"); 42MODULE_DESCRIPTION("GSPCA USB Camera Driver");
44MODULE_LICENSE("GPL"); 43MODULE_LICENSE("GPL");
45 44
46#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 5) 45#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 6)
47static const char version[] = "2.1.5"; 46static const char version[] = "2.1.6";
48 47
49static int video_nr = -1; 48static int video_nr = -1;
50 49
@@ -153,7 +152,6 @@ static void fill_frame(struct gspca_dev *gspca_dev,
153 } 152 }
154 153
155 /* resubmit the URB */ 154 /* resubmit the URB */
156/*fixme: don't do that when userptr and too many URBs sent*/
157 urb->status = 0; 155 urb->status = 0;
158 st = usb_submit_urb(urb, GFP_ATOMIC); 156 st = usb_submit_urb(urb, GFP_ATOMIC);
159 if (st < 0) 157 if (st < 0)
@@ -163,18 +161,9 @@ static void fill_frame(struct gspca_dev *gspca_dev,
163/* 161/*
164 * ISOC message interrupt from the USB device 162 * ISOC message interrupt from the USB device
165 * 163 *
166 * Analyse each packet and call the subdriver for copy 164 * Analyse each packet and call the subdriver for copy to the frame buffer.
167 * to the frame buffer.
168 *
169 * There are 2 functions:
170 * - the first one (isoc_irq_mmap) is used when the application
171 * buffers are mapped. The frame detection and copy is done
172 * at interrupt level.
173 * - the second one (isoc_irq_user) is used when the application
174 * buffers are in user space (userptr). The frame detection
175 * and copy is done by the application.
176 */ 165 */
177static void isoc_irq_mmap(struct urb *urb 166static void isoc_irq(struct urb *urb
178) 167)
179{ 168{
180 struct gspca_dev *gspca_dev = (struct gspca_dev *) urb->context; 169 struct gspca_dev *gspca_dev = (struct gspca_dev *) urb->context;
@@ -185,56 +174,11 @@ static void isoc_irq_mmap(struct urb *urb
185 fill_frame(gspca_dev, urb); 174 fill_frame(gspca_dev, urb);
186} 175}
187 176
188static void isoc_irq_user(struct urb *urb
189)
190{
191 struct gspca_dev *gspca_dev = (struct gspca_dev *) urb->context;
192 int i;
193
194 PDEBUG(D_PACK, "isoc irq user");
195 if (!gspca_dev->streaming)
196 return;
197
198 i = gspca_dev->urb_in % gspca_dev->nurbs;
199 if (urb != gspca_dev->urb[i]) {
200 PDEBUG(D_ERR|D_PACK, "urb out of sequence");
201 return; /* should never occur */
202 }
203
204 gspca_dev->urb_in++;
205 atomic_inc(&gspca_dev->nevent); /* new event */
206 wake_up_interruptible(&gspca_dev->wq);
207/*fixme: submit a new URBs until urb_in == urb_out (% nurbs)*/
208}
209
210/*
211 * treat the isoc messages
212 *
213 * This routine is called by the application (case userptr).
214 */
215static void isoc_transfer(struct gspca_dev *gspca_dev)
216{
217 struct urb *urb;
218 int i;
219
220 for (;;) {
221 i = gspca_dev->urb_out;
222 PDEBUG(D_PACK, "isoc transf i:%d o:%d", gspca_dev->urb_in, i);
223 if (i == gspca_dev->urb_in) /* isoc message to read */
224 break; /* no (more) message */
225 atomic_dec(&gspca_dev->nevent);
226/*PDEBUG(D_PACK, "isoc_trf nevent: %d", atomic_read(&gspca_dev->nevent));*/
227 gspca_dev->urb_out = i + 1; /* message treated */
228 urb = gspca_dev->urb[i % gspca_dev->nurbs];
229 fill_frame(gspca_dev, urb);
230 }
231}
232
233/* 177/*
234 * add data to the current frame 178 * add data to the current frame
235 * 179 *
236 * This function is called by the subdrivers at interrupt level 180 * This function is called by the subdrivers at interrupt level.
237 * or user level. 181 *
238 * To build a frame, these ones must add 182 * To build a frame, these ones must add
239 * - one FIRST_PACKET 183 * - one FIRST_PACKET
240 * - 0 or many INTER_PACKETs 184 * - 0 or many INTER_PACKETs
@@ -277,16 +221,7 @@ struct gspca_frame *gspca_frame_add(struct gspca_dev *gspca_dev,
277 frame->v4l2_buf.length); 221 frame->v4l2_buf.length);
278 packet_type = DISCARD_PACKET; 222 packet_type = DISCARD_PACKET;
279 } else { 223 } else {
280 if (frame->v4l2_buf.memory != V4L2_MEMORY_USERPTR) { 224 memcpy(frame->data_end, data, len);
281 memcpy(frame->data_end, data, len);
282 } else {
283 if (copy_to_user(frame->data_end,
284 data, len) != 0) {
285 PDEBUG(D_ERR|D_PACK,
286 "copy to user failed");
287 packet_type = DISCARD_PACKET;
288 }
289 }
290 frame->data_end += len; 225 frame->data_end += len;
291 } 226 }
292 } 227 }
@@ -333,7 +268,6 @@ static void *rvmalloc(unsigned long size)
333/* size = PAGE_ALIGN(size); (already done) */ 268/* size = PAGE_ALIGN(size); (already done) */
334 mem = vmalloc_32(size); 269 mem = vmalloc_32(size);
335 if (mem != NULL) { 270 if (mem != NULL) {
336 memset(mem, 0, size);
337 adr = (unsigned long) mem; 271 adr = (unsigned long) mem;
338 while ((long) size > 0) { 272 while ((long) size > 0) {
339 SetPageReserved(vmalloc_to_page((void *) adr)); 273 SetPageReserved(vmalloc_to_page((void *) adr));
@@ -344,14 +278,12 @@ static void *rvmalloc(unsigned long size)
344 return mem; 278 return mem;
345} 279}
346 280
347static void rvfree(void *mem, unsigned long size) 281static void rvfree(void *mem, long size)
348{ 282{
349 unsigned long adr; 283 unsigned long adr;
350 284
351 if (!mem)
352 return;
353 adr = (unsigned long) mem; 285 adr = (unsigned long) mem;
354 while ((long) size > 0) { 286 while (size > 0) {
355 ClearPageReserved(vmalloc_to_page((void *) adr)); 287 ClearPageReserved(vmalloc_to_page((void *) adr));
356 adr += PAGE_SIZE; 288 adr += PAGE_SIZE;
357 size -= PAGE_SIZE; 289 size -= PAGE_SIZE;
@@ -370,16 +302,13 @@ static int frame_alloc(struct gspca_dev *gspca_dev,
370 frsz = gspca_dev->cam.cam_mode[i].sizeimage; 302 frsz = gspca_dev->cam.cam_mode[i].sizeimage;
371 PDEBUG(D_STREAM, "frame alloc frsz: %d", frsz); 303 PDEBUG(D_STREAM, "frame alloc frsz: %d", frsz);
372 frsz = PAGE_ALIGN(frsz); 304 frsz = PAGE_ALIGN(frsz);
373 PDEBUG(D_STREAM, "new fr_sz: %d", frsz);
374 gspca_dev->frsz = frsz; 305 gspca_dev->frsz = frsz;
375 if (count > GSPCA_MAX_FRAMES) 306 if (count > GSPCA_MAX_FRAMES)
376 count = GSPCA_MAX_FRAMES; 307 count = GSPCA_MAX_FRAMES;
377 if (gspca_dev->memory == V4L2_MEMORY_MMAP) { 308 gspca_dev->frbuf = rvmalloc(frsz * count);
378 gspca_dev->frbuf = rvmalloc(frsz * count); 309 if (!gspca_dev->frbuf) {
379 if (!gspca_dev->frbuf) { 310 err("frame alloc failed");
380 err("frame alloc failed"); 311 return -ENOMEM;
381 return -ENOMEM;
382 }
383 } 312 }
384 gspca_dev->nframes = count; 313 gspca_dev->nframes = count;
385 for (i = 0; i < count; i++) { 314 for (i = 0; i < count; i++) {
@@ -391,11 +320,9 @@ static int frame_alloc(struct gspca_dev *gspca_dev,
391 frame->v4l2_buf.length = frsz; 320 frame->v4l2_buf.length = frsz;
392 frame->v4l2_buf.memory = gspca_dev->memory; 321 frame->v4l2_buf.memory = gspca_dev->memory;
393 frame->v4l2_buf.sequence = 0; 322 frame->v4l2_buf.sequence = 0;
394 if (gspca_dev->memory == V4L2_MEMORY_MMAP) { 323 frame->data = frame->data_end =
395 frame->data = frame->data_end =
396 gspca_dev->frbuf + i * frsz; 324 gspca_dev->frbuf + i * frsz;
397 frame->v4l2_buf.m.offset = i * frsz; 325 frame->v4l2_buf.m.offset = i * frsz;
398 }
399 } 326 }
400 gspca_dev->fr_i = gspca_dev->fr_o = gspca_dev->fr_q = 0; 327 gspca_dev->fr_i = gspca_dev->fr_o = gspca_dev->fr_q = 0;
401 gspca_dev->last_packet_type = DISCARD_PACKET; 328 gspca_dev->last_packet_type = DISCARD_PACKET;
@@ -509,7 +436,6 @@ static int create_urbs(struct gspca_dev *gspca_dev,
509{ 436{
510 struct urb *urb; 437 struct urb *urb;
511 int n, nurbs, i, psize, npkt, bsize; 438 int n, nurbs, i, psize, npkt, bsize;
512 usb_complete_t usb_complete;
513 439
514 /* calculate the packet size and the number of packets */ 440 /* calculate the packet size and the number of packets */
515 psize = le16_to_cpu(ep->desc.wMaxPacketSize); 441 psize = le16_to_cpu(ep->desc.wMaxPacketSize);
@@ -522,14 +448,7 @@ static int create_urbs(struct gspca_dev *gspca_dev,
522 bsize = psize * npkt; 448 bsize = psize * npkt;
523 PDEBUG(D_STREAM, 449 PDEBUG(D_STREAM,
524 "isoc %d pkts size %d (bsize:%d)", npkt, psize, bsize); 450 "isoc %d pkts size %d (bsize:%d)", npkt, psize, bsize);
525/*fixme:don't submit all URBs when userptr*/ 451 nurbs = DEF_NURBS;
526 if (gspca_dev->memory != V4L2_MEMORY_USERPTR) {
527 usb_complete = isoc_irq_mmap;
528 nurbs = DEF_NURBS;
529 } else {
530 usb_complete = isoc_irq_user;
531 nurbs = USR_NURBS;
532 }
533 gspca_dev->nurbs = nurbs; 452 gspca_dev->nurbs = nurbs;
534 for (n = 0; n < nurbs; n++) { 453 for (n = 0; n < nurbs; n++) {
535 urb = usb_alloc_urb(npkt, GFP_KERNEL); 454 urb = usb_alloc_urb(npkt, GFP_KERNEL);
@@ -556,7 +475,7 @@ static int create_urbs(struct gspca_dev *gspca_dev,
556 urb->transfer_flags = URB_ISO_ASAP 475 urb->transfer_flags = URB_ISO_ASAP
557 | URB_NO_TRANSFER_DMA_MAP; 476 | URB_NO_TRANSFER_DMA_MAP;
558 urb->interval = ep->desc.bInterval; 477 urb->interval = ep->desc.bInterval;
559 urb->complete = usb_complete; 478 urb->complete = isoc_irq;
560 urb->number_of_packets = npkt; 479 urb->number_of_packets = npkt;
561 urb->transfer_buffer_length = bsize; 480 urb->transfer_buffer_length = bsize;
562 for (i = 0; i < npkt; i++) { 481 for (i = 0; i < npkt; i++) {
@@ -564,7 +483,6 @@ static int create_urbs(struct gspca_dev *gspca_dev,
564 urb->iso_frame_desc[i].offset = psize * i; 483 urb->iso_frame_desc[i].offset = psize * i;
565 } 484 }
566 } 485 }
567 gspca_dev->urb_in = gspca_dev->urb_out = 0;
568 return 0; 486 return 0;
569} 487}
570 488
@@ -1063,6 +981,7 @@ static int vidioc_reqbufs(struct file *file, void *priv,
1063 if (rb->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 981 if (rb->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1064 return -EINVAL; 982 return -EINVAL;
1065 switch (rb->memory) { 983 switch (rb->memory) {
984 case GSPCA_MEMORY_READ:
1066 case V4L2_MEMORY_MMAP: 985 case V4L2_MEMORY_MMAP:
1067 case V4L2_MEMORY_USERPTR: 986 case V4L2_MEMORY_USERPTR:
1068 break; 987 break;
@@ -1072,13 +991,6 @@ static int vidioc_reqbufs(struct file *file, void *priv,
1072 if (mutex_lock_interruptible(&gspca_dev->queue_lock)) 991 if (mutex_lock_interruptible(&gspca_dev->queue_lock))
1073 return -ERESTARTSYS; 992 return -ERESTARTSYS;
1074 993
1075 for (i = 0; i < gspca_dev->nframes; i++) {
1076 if (gspca_dev->frame[i].vma_use_count) {
1077 ret = -EBUSY;
1078 goto out;
1079 }
1080 }
1081
1082 /* only one file may do capture */ 994 /* only one file may do capture */
1083 if ((gspca_dev->capt_file != NULL && gspca_dev->capt_file != file) 995 if ((gspca_dev->capt_file != NULL && gspca_dev->capt_file != file)
1084 || gspca_dev->streaming) { 996 || gspca_dev->streaming) {
@@ -1086,10 +998,20 @@ static int vidioc_reqbufs(struct file *file, void *priv,
1086 goto out; 998 goto out;
1087 } 999 }
1088 1000
1089 if (rb->count == 0) { /* unrequest? */ 1001 if (rb->count == 0) { /* unrequest */
1002 for (i = 0; i < gspca_dev->nframes; i++) {
1003 if (gspca_dev->frame[i].vma_use_count) {
1004 ret = -EBUSY;
1005 goto out;
1006 }
1007 }
1090 frame_free(gspca_dev); 1008 frame_free(gspca_dev);
1091 gspca_dev->capt_file = NULL; 1009 gspca_dev->capt_file = NULL;
1092 } else { 1010 } else {
1011 if (gspca_dev->nframes != 0) {
1012 ret = -EBUSY;
1013 goto out;
1014 }
1093 gspca_dev->memory = rb->memory; 1015 gspca_dev->memory = rb->memory;
1094 ret = frame_alloc(gspca_dev, rb->count); 1016 ret = frame_alloc(gspca_dev, rb->count);
1095 if (ret == 0) { 1017 if (ret == 0) {
@@ -1301,9 +1223,6 @@ static int dev_mmap(struct file *file, struct vm_area_struct *vma)
1301 struct page *page; 1223 struct page *page;
1302 unsigned long addr, start, size; 1224 unsigned long addr, start, size;
1303 int i, ret; 1225 int i, ret;
1304#ifdef CONFIG_VIDEO_V4L1_COMPAT
1305 int compat = 0;
1306#endif
1307 1226
1308 start = vma->vm_start; 1227 start = vma->vm_start;
1309 size = vma->vm_end - vma->vm_start; 1228 size = vma->vm_end - vma->vm_start;
@@ -1338,11 +1257,11 @@ static int dev_mmap(struct file *file, struct vm_area_struct *vma)
1338 goto out; 1257 goto out;
1339 } 1258 }
1340#ifdef CONFIG_VIDEO_V4L1_COMPAT 1259#ifdef CONFIG_VIDEO_V4L1_COMPAT
1341 if (i == 0 && size == frame->v4l2_buf.length * gspca_dev->nframes) 1260 /* v4l1 maps all the buffers */
1342 compat = 1; 1261 if (i != 0
1343 else 1262 || size != frame->v4l2_buf.length * gspca_dev->nframes)
1344#endif 1263#endif
1345 if (size != frame->v4l2_buf.length) { 1264 if (size != frame->v4l2_buf.length) {
1346 PDEBUG(D_STREAM, "mmap bad size"); 1265 PDEBUG(D_STREAM, "mmap bad size");
1347 ret = -EINVAL; 1266 ret = -EINVAL;
1348 goto out; 1267 goto out;
@@ -1368,14 +1287,6 @@ static int dev_mmap(struct file *file, struct vm_area_struct *vma)
1368 vma->vm_ops = &gspca_vm_ops; 1287 vma->vm_ops = &gspca_vm_ops;
1369 vma->vm_private_data = frame; 1288 vma->vm_private_data = frame;
1370 gspca_vm_open(vma); 1289 gspca_vm_open(vma);
1371#ifdef CONFIG_VIDEO_V4L1_COMPAT
1372 if (compat) {
1373/*fixme: ugly*/
1374 for (i = 1; i < gspca_dev->nframes; ++i)
1375 gspca_dev->frame[i].v4l2_buf.flags |=
1376 V4L2_BUF_FLAG_MAPPED;
1377 }
1378#endif
1379 ret = 0; 1290 ret = 0;
1380out: 1291out:
1381 mutex_unlock(&gspca_dev->queue_lock); 1292 mutex_unlock(&gspca_dev->queue_lock);
@@ -1393,10 +1304,6 @@ static int frame_wait(struct gspca_dev *gspca_dev,
1393 struct gspca_frame *frame; 1304 struct gspca_frame *frame;
1394 int i, j, ret; 1305 int i, j, ret;
1395 1306
1396 /* if userptr, treat the awaiting URBs */
1397 if (gspca_dev->memory == V4L2_MEMORY_USERPTR)
1398 isoc_transfer(gspca_dev);
1399
1400 /* check if a frame is ready */ 1307 /* check if a frame is ready */
1401 i = gspca_dev->fr_o; 1308 i = gspca_dev->fr_o;
1402 j = gspca_dev->fr_queue[i]; 1309 j = gspca_dev->fr_queue[i];
@@ -1421,8 +1328,6 @@ static int frame_wait(struct gspca_dev *gspca_dev,
1421 atomic_dec(&gspca_dev->nevent); 1328 atomic_dec(&gspca_dev->nevent);
1422 if (!gspca_dev->streaming || !gspca_dev->present) 1329 if (!gspca_dev->streaming || !gspca_dev->present)
1423 return -EIO; 1330 return -EIO;
1424 if (gspca_dev->memory == V4L2_MEMORY_USERPTR)
1425 isoc_transfer(gspca_dev);
1426 i = gspca_dev->fr_o; 1331 i = gspca_dev->fr_o;
1427 j = gspca_dev->fr_queue[i]; 1332 j = gspca_dev->fr_queue[i];
1428 frame = &gspca_dev->frame[j]; 1333 frame = &gspca_dev->frame[j];
@@ -1455,9 +1360,9 @@ static int vidioc_dqbuf(struct file *file, void *priv,
1455 int i, ret; 1360 int i, ret;
1456 1361
1457 PDEBUG(D_FRAM, "dqbuf"); 1362 PDEBUG(D_FRAM, "dqbuf");
1458 if (v4l2_buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE 1363 if (v4l2_buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1459 || (v4l2_buf->memory != V4L2_MEMORY_MMAP 1364 return -EINVAL;
1460 && v4l2_buf->memory != V4L2_MEMORY_USERPTR)) 1365 if (v4l2_buf->memory != gspca_dev->memory)
1461 return -EINVAL; 1366 return -EINVAL;
1462 if (!gspca_dev->streaming) 1367 if (!gspca_dev->streaming)
1463 return -EINVAL; 1368 return -EINVAL;
@@ -1475,6 +1380,16 @@ static int vidioc_dqbuf(struct file *file, void *priv,
1475 goto out; 1380 goto out;
1476 i = ret; /* frame index */ 1381 i = ret; /* frame index */
1477 frame = &gspca_dev->frame[i]; 1382 frame = &gspca_dev->frame[i];
1383 if (gspca_dev->memory == V4L2_MEMORY_USERPTR) {
1384 if (copy_to_user((__u8 *) frame->v4l2_buf.m.userptr,
1385 frame->data,
1386 frame->v4l2_buf.bytesused)) {
1387 PDEBUG(D_ERR|D_STREAM,
1388 "dqbuf cp to user failed");
1389 ret = -EFAULT;
1390 goto out;
1391 }
1392 }
1478 frame->v4l2_buf.flags &= ~V4L2_BUF_FLAG_DONE; 1393 frame->v4l2_buf.flags &= ~V4L2_BUF_FLAG_DONE;
1479 memcpy(v4l2_buf, &frame->v4l2_buf, sizeof *v4l2_buf); 1394 memcpy(v4l2_buf, &frame->v4l2_buf, sizeof *v4l2_buf);
1480 PDEBUG(D_FRAM, "dqbuf %d", i); 1395 PDEBUG(D_FRAM, "dqbuf %d", i);
@@ -1529,8 +1444,6 @@ static int vidioc_qbuf(struct file *file, void *priv,
1529/* frame->v4l2_buf.flags &= ~V4L2_BUF_FLAG_DONE; */ 1444/* frame->v4l2_buf.flags &= ~V4L2_BUF_FLAG_DONE; */
1530 1445
1531 if (frame->v4l2_buf.memory == V4L2_MEMORY_USERPTR) { 1446 if (frame->v4l2_buf.memory == V4L2_MEMORY_USERPTR) {
1532 frame->data = frame->data_end =
1533 (__u8 *) v4l2_buf->m.userptr;
1534 frame->v4l2_buf.m.userptr = v4l2_buf->m.userptr; 1447 frame->v4l2_buf.m.userptr = v4l2_buf->m.userptr;
1535 frame->v4l2_buf.length = v4l2_buf->length; 1448 frame->v4l2_buf.length = v4l2_buf->length;
1536 } 1449 }
@@ -1568,7 +1481,7 @@ static int read_alloc(struct gspca_dev *gspca_dev,
1568 memset(&rb, 0, sizeof rb); 1481 memset(&rb, 0, sizeof rb);
1569 rb.count = gspca_dev->nbufread; 1482 rb.count = gspca_dev->nbufread;
1570 rb.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 1483 rb.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1571 rb.memory = V4L2_MEMORY_MMAP; 1484 rb.memory = GSPCA_MEMORY_READ;
1572 ret = vidioc_reqbufs(file, gspca_dev, &rb); 1485 ret = vidioc_reqbufs(file, gspca_dev, &rb);
1573 if (ret != 0) { 1486 if (ret != 0) {
1574 PDEBUG(D_STREAM, "read reqbuf err %d", ret); 1487 PDEBUG(D_STREAM, "read reqbuf err %d", ret);
@@ -1576,7 +1489,7 @@ static int read_alloc(struct gspca_dev *gspca_dev,
1576 } 1489 }
1577 memset(&v4l2_buf, 0, sizeof v4l2_buf); 1490 memset(&v4l2_buf, 0, sizeof v4l2_buf);
1578 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 1491 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1579 v4l2_buf.memory = V4L2_MEMORY_MMAP; 1492 v4l2_buf.memory = GSPCA_MEMORY_READ;
1580 for (i = 0; i < gspca_dev->nbufread; i++) { 1493 for (i = 0; i < gspca_dev->nbufread; i++) {
1581 v4l2_buf.index = i; 1494 v4l2_buf.index = i;
1582/*fixme: ugly!*/ 1495/*fixme: ugly!*/
@@ -1629,11 +1542,6 @@ static unsigned int dev_poll(struct file *file, poll_table *wait)
1629 goto out; 1542 goto out;
1630 } 1543 }
1631 1544
1632 /* if userptr, treat the awaiting URBs */
1633 if (gspca_dev->memory == V4L2_MEMORY_USERPTR
1634 && gspca_dev->capt_file == file)
1635 isoc_transfer(gspca_dev);
1636
1637 i = gspca_dev->fr_o; 1545 i = gspca_dev->fr_o;
1638 i = gspca_dev->fr_queue[i]; 1546 i = gspca_dev->fr_queue[i];
1639 if (gspca_dev->frame[i].v4l2_buf.flags & V4L2_BUF_FLAG_DONE) 1547 if (gspca_dev->frame[i].v4l2_buf.flags & V4L2_BUF_FLAG_DONE)
@@ -1678,7 +1586,7 @@ static ssize_t dev_read(struct file *file, char __user *data,
1678 for (;;) { 1586 for (;;) {
1679 memset(&v4l2_buf, 0, sizeof v4l2_buf); 1587 memset(&v4l2_buf, 0, sizeof v4l2_buf);
1680 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 1588 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1681 v4l2_buf.memory = V4L2_MEMORY_MMAP; 1589 v4l2_buf.memory = GSPCA_MEMORY_READ;
1682 ret = vidioc_dqbuf(file, gspca_dev, &v4l2_buf); 1590 ret = vidioc_dqbuf(file, gspca_dev, &v4l2_buf);
1683 if (ret != 0) { 1591 if (ret != 0) {
1684 PDEBUG(D_STREAM, "read dqbuf err %d", ret); 1592 PDEBUG(D_STREAM, "read dqbuf err %d", ret);
@@ -1700,14 +1608,8 @@ static ssize_t dev_read(struct file *file, char __user *data,
1700 } 1608 }
1701 1609
1702 /* copy the frame */ 1610 /* copy the frame */
1703 if (count < frame->v4l2_buf.bytesused) { 1611 if (count > frame->v4l2_buf.bytesused)
1704 PDEBUG(D_STREAM, "read bad count: %d < %d", 1612 count = frame->v4l2_buf.bytesused;
1705 count, frame->v4l2_buf.bytesused);
1706/*fixme: special errno?*/
1707 ret = -EINVAL;
1708 goto out;
1709 }
1710 count = frame->v4l2_buf.bytesused;
1711 ret = copy_to_user(data, frame->data, count); 1613 ret = copy_to_user(data, frame->data, count);
1712 if (ret != 0) { 1614 if (ret != 0) {
1713 PDEBUG(D_ERR|D_STREAM, 1615 PDEBUG(D_ERR|D_STREAM,