diff options
-rw-r--r-- | linux/drivers/media/dvb/dvb-core/dvbdev.c | 13 | ||||
-rw-r--r-- | linux/drivers/media/dvb/dvb-core/dvbdev.h | 5 | ||||
-rw-r--r-- | linux/drivers/media/dvb/ttpci/av7110.c | 54 |
3 files changed, 50 insertions, 22 deletions
diff --git a/linux/drivers/media/dvb/dvb-core/dvbdev.c b/linux/drivers/media/dvb/dvb-core/dvbdev.c index 1e9d07b8f..7f3421778 100644 --- a/linux/drivers/media/dvb/dvb-core/dvbdev.c +++ b/linux/drivers/media/dvb/dvb-core/dvbdev.c @@ -121,7 +121,11 @@ int dvb_generic_open(struct inode *inode, struct file *file) if (!dvbdev->users) return -EBUSY; - if ((file->f_flags & O_ACCMODE) != O_RDONLY) { + if ((file->f_flags & O_ACCMODE) == O_RDONLY) { + if (!dvbdev->readers) + return -EBUSY; + dvbdev->readers--; + } else { if (!dvbdev->writers) return -EBUSY; dvbdev->writers--; @@ -139,9 +143,12 @@ int dvb_generic_release(struct inode *inode, struct file *file) if (!dvbdev) return -ENODEV; - if ((file->f_flags & O_ACCMODE) != O_RDONLY) + if ((file->f_flags & O_ACCMODE) == O_RDONLY) { + dvbdev->readers++; + } else { dvbdev->writers++; - + } + dvbdev->users++; return 0; } diff --git a/linux/drivers/media/dvb/dvb-core/dvbdev.h b/linux/drivers/media/dvb/dvb-core/dvbdev.h index 2c14d0e1f..14a872011 100644 --- a/linux/drivers/media/dvb/dvb-core/dvbdev.h +++ b/linux/drivers/media/dvb/dvb-core/dvbdev.h @@ -66,8 +66,11 @@ struct dvb_device { int type; u32 id; - int users; + /* in theory, 'users' can vanish now, + but I don't want to change too much now... */ + int readers; int writers; + int users; /* don't really need those !? -- FIXME: use video_usercopy */ int (*kernel_ioctl)(struct inode *inode, struct file *file, diff --git a/linux/drivers/media/dvb/ttpci/av7110.c b/linux/drivers/media/dvb/ttpci/av7110.c index 521b7f3de..b97616626 100644 --- a/linux/drivers/media/dvb/ttpci/av7110.c +++ b/linux/drivers/media/dvb/ttpci/av7110.c @@ -3646,18 +3646,23 @@ static unsigned int dvb_video_poll(struct file *file, poll_table *wait) DEB_EE(("av7110: %p\n",av7110)); - poll_wait(file, &av7110->avout.queue, wait); + if ((file->f_flags & O_ACCMODE) != O_RDONLY) { + poll_wait(file, &av7110->avout.queue, wait); + } + poll_wait(file, &av7110->video_events.wait_queue, wait); if (av7110->video_events.eventw != av7110->video_events.eventr) mask = POLLPRI; - if (av7110->playing) { - if (FREE_COND) - mask |= (POLLOUT | POLLWRNORM); - } else /* if not playing: may play if asked for */ - mask |= (POLLOUT | POLLWRNORM); - + if ((file->f_flags & O_ACCMODE) != O_RDONLY) { + if (av7110->playing) { + if (FREE_COND) + mask |= (POLLOUT | POLLWRNORM); + } else /* if not playing: may play if asked for */ + mask |= (POLLOUT | POLLWRNORM); + } + return mask; } @@ -3669,6 +3674,10 @@ static ssize_t dvb_video_write(struct file *file, const char *buf, DEB_EE(("av7110: %p\n",av7110)); + if ((file->f_flags & O_ACCMODE) == O_RDONLY) { + return -EPERM; + } + if (av7110->videostate.stream_source!=VIDEO_SOURCE_MEMORY) return -EPERM; @@ -3727,9 +3736,12 @@ static int dvb_video_ioctl(struct inode *inode, struct file *file, DEB_EE(("av7110: %p\n",av7110)); - if (((file->f_flags&O_ACCMODE)==O_RDONLY) && - (cmd!=VIDEO_GET_STATUS)) - return -EPERM; + if ((file->f_flags&O_ACCMODE)==O_RDONLY) { + if ( cmd!=VIDEO_GET_STATUS && cmd!=VIDEO_GET_EVENT && + cmd!=VIDEO_GET_SIZE ) { + return -EPERM; + } + } switch (cmd) { case VIDEO_STOP: @@ -4043,15 +4055,17 @@ static int dvb_video_open(struct inode *inode, struct file *file) if ((err=dvb_generic_open(inode, file))<0) return err; - dvb_ringbuffer_flush_spinlock_wakeup(&av7110->aout); - dvb_ringbuffer_flush_spinlock_wakeup(&av7110->avout); - av7110->video_blank=1; - av7110->audiostate.AV_sync_state=1; - av7110->videostate.stream_source=VIDEO_SOURCE_DEMUX; - if ((file->f_flags & O_ACCMODE) != O_RDONLY) + if ((file->f_flags & O_ACCMODE) != O_RDONLY) { + dvb_ringbuffer_flush_spinlock_wakeup(&av7110->aout); + dvb_ringbuffer_flush_spinlock_wakeup(&av7110->avout); + av7110->video_blank=1; + av7110->audiostate.AV_sync_state=1; + av7110->videostate.stream_source=VIDEO_SOURCE_DEMUX; + /* empty event queue */ av7110->video_events.eventr = av7110->video_events.eventw = 0; + } return 0; } @@ -4063,7 +4077,10 @@ static int dvb_video_release(struct inode *inode, struct file *file) DEB_EE(("av7110: %p\n",av7110)); - AV_Stop(av7110, RP_VIDEO); + if ((file->f_flags & O_ACCMODE) != O_RDONLY) { + AV_Stop(av7110, RP_VIDEO); + } + return dvb_generic_release(inode, file); } @@ -4110,7 +4127,8 @@ static struct file_operations dvb_video_fops = { static struct dvb_device dvbdev_video = { .priv = 0, - .users = 1, + .users = 6, + .readers = 5, /* arbitrary */ .writers = 1, .fops = &dvb_video_fops, .kernel_ioctl = dvb_video_ioctl, |