Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d642de2e authored by Hans de Goede's avatar Hans de Goede Committed by Mauro Carvalho Chehab
Browse files

[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: default avatarHans de Goede <hdegoede@redhat.com>
Acked-by: default avatarJean-Francois Moine <moinejf@free.fr>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent 7f6eb118
Loading
Loading
Loading
Loading
+11 −12
Original line number Diff line number Diff line
@@ -508,8 +508,8 @@ static int gspca_is_compressed(__u32 format)
	return 0;
}

static int frame_alloc(struct gspca_dev *gspca_dev,
			unsigned int count)
static int frame_alloc(struct gspca_dev *gspca_dev, struct file *file,
			enum v4l2_memory memory, unsigned int count)
{
	struct gspca_frame *frame;
	unsigned int frsz;
@@ -519,7 +519,6 @@ static int frame_alloc(struct gspca_dev *gspca_dev,
	frsz = gspca_dev->cam.cam_mode[i].sizeimage;
	PDEBUG(D_STREAM, "frame alloc frsz: %d", frsz);
	frsz = PAGE_ALIGN(frsz);
	gspca_dev->frsz = frsz;
	if (count >= GSPCA_MAX_FRAMES)
		count = GSPCA_MAX_FRAMES - 1;
	gspca_dev->frbuf = vmalloc_32(frsz * count);
@@ -527,6 +526,9 @@ static int frame_alloc(struct gspca_dev *gspca_dev,
		err("frame alloc failed");
		return -ENOMEM;
	}
	gspca_dev->capt_file = file;
	gspca_dev->memory = memory;
	gspca_dev->frsz = frsz;
	gspca_dev->nframes = count;
	for (i = 0; i < count; i++) {
		frame = &gspca_dev->frame[i];
@@ -535,7 +537,7 @@ static int frame_alloc(struct gspca_dev *gspca_dev,
		frame->v4l2_buf.flags = 0;
		frame->v4l2_buf.field = V4L2_FIELD_NONE;
		frame->v4l2_buf.length = frsz;
		frame->v4l2_buf.memory = gspca_dev->memory;
		frame->v4l2_buf.memory = memory;
		frame->v4l2_buf.sequence = 0;
		frame->data = gspca_dev->frbuf + i * frsz;
		frame->v4l2_buf.m.offset = i * frsz;
@@ -558,6 +560,9 @@ static void frame_free(struct gspca_dev *gspca_dev)
			gspca_dev->frame[i].data = NULL;
	}
	gspca_dev->nframes = 0;
	gspca_dev->frsz = 0;
	gspca_dev->capt_file = NULL;
	gspca_dev->memory = GSPCA_MEMORY_NO;
}

static void destroy_urbs(struct gspca_dev *gspca_dev)
@@ -1250,8 +1255,6 @@ static int dev_close(struct file *file)
			mutex_unlock(&gspca_dev->usb_lock);
		}
		frame_free(gspca_dev);
		gspca_dev->capt_file = NULL;
		gspca_dev->memory = GSPCA_MEMORY_NO;
	}
	file->private_data = NULL;
	module_put(gspca_dev->module);
@@ -1524,17 +1527,13 @@ static int vidioc_reqbufs(struct file *file, void *priv,
	}

	/* free the previous allocated buffers, if any */
	if (gspca_dev->nframes != 0) {
	if (gspca_dev->nframes != 0)
		frame_free(gspca_dev);
		gspca_dev->capt_file = NULL;
	}
	if (rb->count == 0)			/* unrequest */
		goto out;
	gspca_dev->memory = rb->memory;
	ret = frame_alloc(gspca_dev, rb->count);
	ret = frame_alloc(gspca_dev, file, rb->memory, rb->count);
	if (ret == 0) {
		rb->count = gspca_dev->nframes;
		gspca_dev->capt_file = file;
		if (streaming)
			ret = gspca_init_transfer(gspca_dev);
	}