]> git.karo-electronics.de Git - linux-beck.git/commitdiff
[media] cpia2: convert .ioctl to .unlocked_ioctl
authorHans Verkuil <hverkuil@xs4all.nl>
Sat, 18 Dec 2010 12:50:43 +0000 (09:50 -0300)
committerMauro Carvalho Chehab <mchehab@redhat.com>
Wed, 19 Jan 2011 13:28:12 +0000 (11:28 -0200)
Implement core-assisted locking in cpia2.

Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
drivers/media/video/cpia2/cpia2.h
drivers/media/video/cpia2/cpia2_core.c
drivers/media/video/cpia2/cpia2_v4l.c

index 916c13d5cf7d12c9a725f895227bd2b197017de6..6d6d1843791ce0a7ef880211b33f92c85bee4922 100644 (file)
@@ -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 */
index 9606bc01b803c118db6ffeee85f21a3f58f046d7..aaffca8e13fde4a0aa2f3a30848b25590fcbc021 100644 (file)
@@ -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,17 +2379,12 @@ 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 */
        }
 
-       if(!cam->streaming) {
+       if (!cam->streaming) {
                /* Start streaming */
                cpia2_usb_stream_start(cam,
                                       cam->params.camera_state.stream_mode);
@@ -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);
+       if (frame->status != FRAME_READY) {
+               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;
 }
 
@@ -2447,17 +2431,13 @@ unsigned int cpia2_poll(struct camera_data *cam, struct file *filp,
 {
        unsigned int status=0;
 
-       if(!cam) {
+       if (!cam) {
                ERR("%s: Internal error, camera_data not found!\n",__func__);
                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;
 }
-
index 7edf80b0d01aabee0a080721f1ca2c36c90d66ec..9bad398429366934a83fc3d2c1c8cddabb6fbf50 100644 (file)
@@ -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->present)
+               return -ENODEV;
 
-       if (cam->open_count > 0) {
-               goto skip_init;
-       }
+       if (cam->open_count == 0) {
+               if (cpia2_allocate_buffers(cam))
+                       return -ENOMEM;
 
-       if (cpia2_allocate_buffers(cam)) {
-               retval = -ENOMEM;
-               goto err_return;
-       }
+               /* reset the camera */
+               if (cpia2_reset_camera(cam) < 0)
+                       return -EIO;
 
-       /* reset the camera */
-       if (cpia2_reset_camera(cam) < 0) {
-               retval = -EIO;
-               goto err_return;
+               cam->APP_len = 0;
+               cam->COM_len = 0;
        }
 
-       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;
-               }
-               file->private_data = fh;
-               fh->prio = V4L2_PRIORITY_UNSET;
-               v4l2_prio_open(&cam->prio, &fh->prio);
-               fh->mmapped = 0;
-       }
+       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,15 +285,11 @@ 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) {
+               if (cam->open_count == 1) {
                        /* save camera state for later open */
                        cpia2_save_camera_state(cam);
 
@@ -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 (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);