Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 232159
b: refs/heads/master
c: d2db8fe
h: refs/heads/master
i:
  232157: 435f1b9
  232155: 04deb0f
  232151: 3a0c89c
  232143: 6552d0b
  232127: b9363e8
v: v3
  • Loading branch information
Hans Verkuil authored and Mauro Carvalho Chehab committed Jan 19, 2011
1 parent f49ce6c commit 102b97c
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 122 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 9af39713feb53da96ba23fa94a73ffd0de50a815
refs/heads/master: d2db8fee0d77f43f64e4e97ccc1558a9f59fab41
2 changes: 1 addition & 1 deletion trunk/drivers/media/video/cpia2/cpia2.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down
65 changes: 15 additions & 50 deletions trunk/drivers/media/video/cpia2/cpia2_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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__);
Expand All @@ -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);
Expand All @@ -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;
}

Expand All @@ -2447,34 +2431,27 @@ 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 */
cpia2_usb_stream_start(cam,
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;
}

Expand All @@ -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)
Expand All @@ -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;
}

104 changes: 34 additions & 70 deletions trunk/drivers/media/video/cpia2/cpia2_v4l.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

/******************************************************************************
Expand All @@ -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);

Expand All @@ -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;
}

Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -1337,25 +1309,17 @@ 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) {
case VIDIOC_S_FMT:
{
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:
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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,
};

Expand All @@ -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);

Expand Down

0 comments on commit 102b97c

Please sign in to comment.