Commit d2db8fee authored by Hans Verkuil's avatar Hans Verkuil Committed by Mauro Carvalho Chehab
Browse files

[media] cpia2: convert .ioctl to .unlocked_ioctl



Implement core-assisted locking in cpia2.

Signed-off-by: default avatarHans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent 9af39713
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -378,7 +378,7 @@ struct cpia2_fh {

struct camera_data {
	/* locks */
	struct mutex busy_lock;	/* guard against SMP multithreading */
	struct mutex v4l2_lock;	/* serialize file operations */
	struct v4l2_prio_state prio;

	/* camera status */
+15 −50
Original line number Diff line number Diff line
@@ -2247,7 +2247,7 @@ struct camera_data *cpia2_init_camera_struct(void)


	cam->present = 1;
	mutex_init(&cam->busy_lock);
	mutex_init(&cam->v4l2_lock);
	init_waitqueue_head(&cam->wq_stream);

	return cam;
@@ -2365,9 +2365,9 @@ long cpia2_read(struct camera_data *cam,
		char __user *buf, unsigned long count, int noblock)
{
	struct framebuf *frame;
	if (!count) {

	if (!count)
		return 0;
	}

	if (!buf) {
		ERR("%s: buffer NULL\n",__func__);
@@ -2379,13 +2379,8 @@ long cpia2_read(struct camera_data *cam,
		return -EINVAL;
	}

	/* make this _really_ smp and multithread-safe */
	if (mutex_lock_interruptible(&cam->busy_lock))
		return -ERESTARTSYS;

	if (!cam->present) {
		LOG("%s: camera removed\n",__func__);
		mutex_unlock(&cam->busy_lock);
		return 0;	/* EOF */
	}

@@ -2398,42 +2393,31 @@ long cpia2_read(struct camera_data *cam,
	/* Copy cam->curbuff in case it changes while we're processing */
	frame = cam->curbuff;
	if (noblock && frame->status != FRAME_READY) {
		mutex_unlock(&cam->busy_lock);
		return -EAGAIN;
	}

	if (frame->status != FRAME_READY) {
		mutex_unlock(&cam->busy_lock);
		mutex_unlock(&cam->v4l2_lock);
		wait_event_interruptible(cam->wq_stream,
			       !cam->present ||
			       (frame = cam->curbuff)->status == FRAME_READY);
		mutex_lock(&cam->v4l2_lock);
		if (signal_pending(current))
			return -ERESTARTSYS;
		/* make this _really_ smp and multithread-safe */
		if (mutex_lock_interruptible(&cam->busy_lock)) {
			return -ERESTARTSYS;
		}
		if(!cam->present) {
			mutex_unlock(&cam->busy_lock);
		if (!cam->present)
			return 0;
	}
	}

	/* copy data to user space */
	if (frame->length > count) {
		mutex_unlock(&cam->busy_lock);
	if (frame->length > count)
		return -EFAULT;
	}
	if (copy_to_user(buf, frame->data, frame->length)) {
		mutex_unlock(&cam->busy_lock);
	if (copy_to_user(buf, frame->data, frame->length))
		return -EFAULT;
	}

	count = frame->length;

	frame->status = FRAME_EMPTY;

	mutex_unlock(&cam->busy_lock);
	return count;
}

@@ -2452,12 +2436,8 @@ unsigned int cpia2_poll(struct camera_data *cam, struct file *filp,
		return POLLERR;
	}

	mutex_lock(&cam->busy_lock);

	if(!cam->present) {
		mutex_unlock(&cam->busy_lock);
	if (!cam->present)
		return POLLHUP;
	}

	if(!cam->streaming) {
		/* Start streaming */
@@ -2465,16 +2445,13 @@ unsigned int cpia2_poll(struct camera_data *cam, struct file *filp,
				       cam->params.camera_state.stream_mode);
	}

	mutex_unlock(&cam->busy_lock);
	poll_wait(filp, &cam->wq_stream, wait);
	mutex_lock(&cam->busy_lock);

	if(!cam->present)
		status = POLLHUP;
	else if(cam->curbuff->status == FRAME_READY)
		status = POLLIN | POLLRDNORM;

	mutex_unlock(&cam->busy_lock);
	return status;
}

@@ -2496,29 +2473,19 @@ int cpia2_remap_buffer(struct camera_data *cam, struct vm_area_struct *vma)

	DBG("mmap offset:%ld size:%ld\n", start_offset, size);

	/* make this _really_ smp-safe */
	if (mutex_lock_interruptible(&cam->busy_lock))
		return -ERESTARTSYS;

	if (!cam->present) {
		mutex_unlock(&cam->busy_lock);
	if (!cam->present)
		return -ENODEV;
	}

	if (size > cam->frame_size*cam->num_frames  ||
	    (start_offset % cam->frame_size) != 0 ||
	    (start_offset+size > cam->frame_size*cam->num_frames)) {
		mutex_unlock(&cam->busy_lock);
	    (start_offset+size > cam->frame_size*cam->num_frames))
		return -EINVAL;
	}

	pos = ((unsigned long) (cam->frame_buffer)) + start_offset;
	while (size > 0) {
		page = kvirt_to_pa(pos);
		if (remap_pfn_range(vma, start, page >> PAGE_SHIFT, PAGE_SIZE, PAGE_SHARED)) {
			mutex_unlock(&cam->busy_lock);
		if (remap_pfn_range(vma, start, page >> PAGE_SHIFT, PAGE_SIZE, PAGE_SHARED))
			return -EAGAIN;
		}
		start += PAGE_SIZE;
		pos += PAGE_SIZE;
		if (size > PAGE_SIZE)
@@ -2528,7 +2495,5 @@ int cpia2_remap_buffer(struct camera_data *cam, struct vm_area_struct *vma)
	}

	cam->mmapped = true;
	mutex_unlock(&cam->busy_lock);
	return 0;
}
+34 −70
Original line number Diff line number Diff line
@@ -238,59 +238,40 @@ static struct v4l2_queryctrl controls[] = {
static int cpia2_open(struct file *file)
{
	struct camera_data *cam = video_drvdata(file);
	int retval = 0;
	struct cpia2_fh *fh;

	if (!cam) {
		ERR("Internal error, camera_data not found!\n");
		return -ENODEV;
	}

	if(mutex_lock_interruptible(&cam->busy_lock))
		return -ERESTARTSYS;

	if(!cam->present) {
		retval = -ENODEV;
		goto err_return;
	}

	if (cam->open_count > 0) {
		goto skip_init;
	}
	if (!cam->present)
		return -ENODEV;

	if (cpia2_allocate_buffers(cam)) {
		retval = -ENOMEM;
		goto err_return;
	}
	if (cam->open_count == 0) {
		if (cpia2_allocate_buffers(cam))
			return -ENOMEM;

		/* reset the camera */
	if (cpia2_reset_camera(cam) < 0) {
		retval = -EIO;
		goto err_return;
	}
		if (cpia2_reset_camera(cam) < 0)
			return -EIO;

		cam->APP_len = 0;
		cam->COM_len = 0;

skip_init:
	{
		struct cpia2_fh *fh = kmalloc(sizeof(*fh),GFP_KERNEL);
		if(!fh) {
			retval = -ENOMEM;
			goto err_return;
	}

	fh = kmalloc(sizeof(*fh), GFP_KERNEL);
	if (!fh)
		return -ENOMEM;
	file->private_data = fh;
	fh->prio = V4L2_PRIORITY_UNSET;
	v4l2_prio_open(&cam->prio, &fh->prio);
	fh->mmapped = 0;
	}

	++cam->open_count;

	cpia2_dbg_dump_registers(cam);

err_return:
	mutex_unlock(&cam->busy_lock);
	return retval;
	return 0;
}

/******************************************************************************
@@ -304,12 +285,8 @@ static int cpia2_close(struct file *file)
	struct camera_data *cam = video_get_drvdata(dev);
	struct cpia2_fh *fh = file->private_data;

	mutex_lock(&cam->busy_lock);

	if (cam->present &&
	    (cam->open_count == 1
	     || fh->prio == V4L2_PRIORITY_RECORD
	    )) {
	    (cam->open_count == 1 || fh->prio == V4L2_PRIORITY_RECORD)) {
		cpia2_usb_stream_stop(cam);

		if (cam->open_count == 1) {
@@ -321,26 +298,21 @@ static int cpia2_close(struct file *file)
		}
	}

	{
	if (fh->mmapped)
		cam->mmapped = 0;
	v4l2_prio_close(&cam->prio, fh->prio);
	file->private_data = NULL;
	kfree(fh);
	}

	if (--cam->open_count == 0) {
		cpia2_free_buffers(cam);
		if (!cam->present) {
			video_unregister_device(dev);
			mutex_unlock(&cam->busy_lock);
			kfree(cam);
			return 0;
		}
	}

	mutex_unlock(&cam->busy_lock);

	return 0;
}

@@ -405,11 +377,11 @@ static int sync(struct camera_data *cam, int frame_nr)
			return 0;
		}

		mutex_unlock(&cam->busy_lock);
		mutex_unlock(&cam->v4l2_lock);
		wait_event_interruptible(cam->wq_stream,
					 !cam->streaming ||
					 frame->status == FRAME_READY);
		mutex_lock(&cam->busy_lock);
		mutex_lock(&cam->v4l2_lock);
		if (signal_pending(current))
			return -ERESTARTSYS;
		if(!cam->present)
@@ -1293,11 +1265,11 @@ static int ioctl_dqbuf(void *arg,struct camera_data *cam, struct file *file)
	if(frame < 0) {
		/* Wait for a frame to become available */
		struct framebuf *cb=cam->curbuff;
		mutex_unlock(&cam->busy_lock);
		mutex_unlock(&cam->v4l2_lock);
		wait_event_interruptible(cam->wq_stream,
					 !cam->present ||
					 (cb=cam->curbuff)->status == FRAME_READY);
		mutex_lock(&cam->busy_lock);
		mutex_lock(&cam->v4l2_lock);
		if (signal_pending(current))
			return -ERESTARTSYS;
		if(!cam->present)
@@ -1337,14 +1309,8 @@ static long cpia2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
	if (!cam)
		return -ENOTTY;

	/* make this _really_ smp-safe */
	if (mutex_lock_interruptible(&cam->busy_lock))
		return -ERESTARTSYS;

	if (!cam->present) {
		mutex_unlock(&cam->busy_lock);
	if (!cam->present)
		return -ENODEV;
	}

	/* Priority check */
	switch (cmd) {
@@ -1352,10 +1318,8 @@ static long cpia2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
	{
		struct cpia2_fh *fh = file->private_data;
		retval = v4l2_prio_check(&cam->prio, fh->prio);
		if(retval) {
			mutex_unlock(&cam->busy_lock);
		if (retval)
			return retval;
		}
		break;
	}
	default:
@@ -1529,7 +1493,6 @@ static long cpia2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
		break;
	}

	mutex_unlock(&cam->busy_lock);
	return retval;
}

@@ -1596,7 +1559,7 @@ static const struct v4l2_file_operations cpia2_fops = {
	.release	= cpia2_close,
	.read		= cpia2_v4l_read,
	.poll		= cpia2_v4l_poll,
	.ioctl		= cpia2_ioctl,
	.unlocked_ioctl	= cpia2_ioctl,
	.mmap		= cpia2_mmap,
};

@@ -1620,6 +1583,7 @@ int cpia2_register_camera(struct camera_data *cam)

	memcpy(cam->vdev, &cpia2_template, sizeof(cpia2_template));
	video_set_drvdata(cam->vdev, cam);
	cam->vdev->lock = &cam->v4l2_lock;

	reset_camera_struct_v4l(cam);