aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans de Goede <hdegoede@redhat.com>2010-12-31 02:51:36 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2011-01-19 08:44:57 -0500
commitd642de2ed472df308f8ee49417e29030f69b2095 (patch)
tree1ac77d33b3866e0542172f8e4ecd9c33c2cf772b
parent7f6eb118df84715b128e25e99dc6a3ebc5b133d6 (diff)
[media] gspca_main: Set memory type to GSPCA_MEMORY_NO on buffer release
Before this patch we were not setting the memory type to GSPCA_MEMORY_NO when the buffers were released by the app doing a reqbufs 0. Nor would the memory type be set to GSPCA_MEMORY_NO on device close, as capture_file already is NULL on device close because of the reqbufs 0. This caused the following problem: -app1 does reqbufs USERPTR for 4 buffers -app1 does reqbufs USERPTR for 0 buffers -app2 tries to do reqbufs MMAP for 4 buffers fails because gspca_dev->memory still is USERPTR Fixing this also allows an app to switch memory type's by unrequesting the buffers and re-requesting them of a different type. This patch also moves the setting of gspca_dev->frsz and gscpa_dev->memory to after alloc_frame succeeding, so that they are not changed when allocating fails. Signed-off-by: Hans de Goede <hdegoede@redhat.com> Acked-by: Jean-Francois Moine <moinejf@free.fr> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r--drivers/media/video/gspca/gspca.c23
1 files changed, 11 insertions, 12 deletions
diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c
index 0ba42dd4b99b..adab34f91a68 100644
--- a/drivers/media/video/gspca/gspca.c
+++ b/drivers/media/video/gspca/gspca.c
@@ -508,8 +508,8 @@ static int gspca_is_compressed(__u32 format)
508 return 0; 508 return 0;
509} 509}
510 510
511static int frame_alloc(struct gspca_dev *gspca_dev, 511static int frame_alloc(struct gspca_dev *gspca_dev, struct file *file,
512 unsigned int count) 512 enum v4l2_memory memory, unsigned int count)
513{ 513{
514 struct gspca_frame *frame; 514 struct gspca_frame *frame;
515 unsigned int frsz; 515 unsigned int frsz;
@@ -519,7 +519,6 @@ static int frame_alloc(struct gspca_dev *gspca_dev,
519 frsz = gspca_dev->cam.cam_mode[i].sizeimage; 519 frsz = gspca_dev->cam.cam_mode[i].sizeimage;
520 PDEBUG(D_STREAM, "frame alloc frsz: %d", frsz); 520 PDEBUG(D_STREAM, "frame alloc frsz: %d", frsz);
521 frsz = PAGE_ALIGN(frsz); 521 frsz = PAGE_ALIGN(frsz);
522 gspca_dev->frsz = frsz;
523 if (count >= GSPCA_MAX_FRAMES) 522 if (count >= GSPCA_MAX_FRAMES)
524 count = GSPCA_MAX_FRAMES - 1; 523 count = GSPCA_MAX_FRAMES - 1;
525 gspca_dev->frbuf = vmalloc_32(frsz * count); 524 gspca_dev->frbuf = vmalloc_32(frsz * count);
@@ -527,6 +526,9 @@ static int frame_alloc(struct gspca_dev *gspca_dev,
527 err("frame alloc failed"); 526 err("frame alloc failed");
528 return -ENOMEM; 527 return -ENOMEM;
529 } 528 }
529 gspca_dev->capt_file = file;
530 gspca_dev->memory = memory;
531 gspca_dev->frsz = frsz;
530 gspca_dev->nframes = count; 532 gspca_dev->nframes = count;
531 for (i = 0; i < count; i++) { 533 for (i = 0; i < count; i++) {
532 frame = &gspca_dev->frame[i]; 534 frame = &gspca_dev->frame[i];
@@ -535,7 +537,7 @@ static int frame_alloc(struct gspca_dev *gspca_dev,
535 frame->v4l2_buf.flags = 0; 537 frame->v4l2_buf.flags = 0;
536 frame->v4l2_buf.field = V4L2_FIELD_NONE; 538 frame->v4l2_buf.field = V4L2_FIELD_NONE;
537 frame->v4l2_buf.length = frsz; 539 frame->v4l2_buf.length = frsz;
538 frame->v4l2_buf.memory = gspca_dev->memory; 540 frame->v4l2_buf.memory = memory;
539 frame->v4l2_buf.sequence = 0; 541 frame->v4l2_buf.sequence = 0;
540 frame->data = gspca_dev->frbuf + i * frsz; 542 frame->data = gspca_dev->frbuf + i * frsz;
541 frame->v4l2_buf.m.offset = i * frsz; 543 frame->v4l2_buf.m.offset = i * frsz;
@@ -558,6 +560,9 @@ static void frame_free(struct gspca_dev *gspca_dev)
558 gspca_dev->frame[i].data = NULL; 560 gspca_dev->frame[i].data = NULL;
559 } 561 }
560 gspca_dev->nframes = 0; 562 gspca_dev->nframes = 0;
563 gspca_dev->frsz = 0;
564 gspca_dev->capt_file = NULL;
565 gspca_dev->memory = GSPCA_MEMORY_NO;
561} 566}
562 567
563static void destroy_urbs(struct gspca_dev *gspca_dev) 568static void destroy_urbs(struct gspca_dev *gspca_dev)
@@ -1250,8 +1255,6 @@ static int dev_close(struct file *file)
1250 mutex_unlock(&gspca_dev->usb_lock); 1255 mutex_unlock(&gspca_dev->usb_lock);
1251 } 1256 }
1252 frame_free(gspca_dev); 1257 frame_free(gspca_dev);
1253 gspca_dev->capt_file = NULL;
1254 gspca_dev->memory = GSPCA_MEMORY_NO;
1255 } 1258 }
1256 file->private_data = NULL; 1259 file->private_data = NULL;
1257 module_put(gspca_dev->module); 1260 module_put(gspca_dev->module);
@@ -1524,17 +1527,13 @@ static int vidioc_reqbufs(struct file *file, void *priv,
1524 } 1527 }
1525 1528
1526 /* free the previous allocated buffers, if any */ 1529 /* free the previous allocated buffers, if any */
1527 if (gspca_dev->nframes != 0) { 1530 if (gspca_dev->nframes != 0)
1528 frame_free(gspca_dev); 1531 frame_free(gspca_dev);
1529 gspca_dev->capt_file = NULL;
1530 }
1531 if (rb->count == 0) /* unrequest */ 1532 if (rb->count == 0) /* unrequest */
1532 goto out; 1533 goto out;
1533 gspca_dev->memory = rb->memory; 1534 ret = frame_alloc(gspca_dev, file, rb->memory, rb->count);
1534 ret = frame_alloc(gspca_dev, rb->count);
1535 if (ret == 0) { 1535 if (ret == 0) {
1536 rb->count = gspca_dev->nframes; 1536 rb->count = gspca_dev->nframes;
1537 gspca_dev->capt_file = file;
1538 if (streaming) 1537 if (streaming)
1539 ret = gspca_init_transfer(gspca_dev); 1538 ret = gspca_init_transfer(gspca_dev);
1540 } 1539 }