aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/dvb/dvb-core/dmxdev.c56
-rw-r--r--drivers/media/dvb/dvb-core/dmxdev.h2
-rw-r--r--drivers/media/dvb/dvb-core/dvb_demux.c2
-rw-r--r--drivers/media/dvb/dvb-core/dvb_demux.h1
-rw-r--r--drivers/media/dvb/dvb-core/dvb_frontend.c13
5 files changed, 67 insertions, 7 deletions
diff --git a/drivers/media/dvb/dvb-core/dmxdev.c b/drivers/media/dvb/dvb-core/dmxdev.c
index a5c0e1a3e6d1..275df65fde99 100644
--- a/drivers/media/dvb/dvb-core/dmxdev.c
+++ b/drivers/media/dvb/dvb-core/dmxdev.c
@@ -132,6 +132,11 @@ static int dvb_dvr_open(struct inode *inode, struct file *file)
132 if (mutex_lock_interruptible(&dmxdev->mutex)) 132 if (mutex_lock_interruptible(&dmxdev->mutex))
133 return -ERESTARTSYS; 133 return -ERESTARTSYS;
134 134
135 if (dmxdev->exit) {
136 mutex_unlock(&dmxdev->mutex);
137 return -ENODEV;
138 }
139
135 if ((file->f_flags & O_ACCMODE) == O_RDWR) { 140 if ((file->f_flags & O_ACCMODE) == O_RDWR) {
136 if (!(dmxdev->capabilities & DMXDEV_CAP_DUPLEX)) { 141 if (!(dmxdev->capabilities & DMXDEV_CAP_DUPLEX)) {
137 mutex_unlock(&dmxdev->mutex); 142 mutex_unlock(&dmxdev->mutex);
@@ -171,6 +176,7 @@ static int dvb_dvr_open(struct inode *inode, struct file *file)
171 dmxdev->demux->disconnect_frontend(dmxdev->demux); 176 dmxdev->demux->disconnect_frontend(dmxdev->demux);
172 dmxdev->demux->connect_frontend(dmxdev->demux, front); 177 dmxdev->demux->connect_frontend(dmxdev->demux, front);
173 } 178 }
179 dvbdev->users++;
174 mutex_unlock(&dmxdev->mutex); 180 mutex_unlock(&dmxdev->mutex);
175 return 0; 181 return 0;
176} 182}
@@ -198,7 +204,16 @@ static int dvb_dvr_release(struct inode *inode, struct file *file)
198 vfree(mem); 204 vfree(mem);
199 } 205 }
200 } 206 }
201 mutex_unlock(&dmxdev->mutex); 207 /* TODO */
208 dvbdev->users--;
209 if(dvbdev->users==-1 && dmxdev->exit==1) {
210 fops_put(file->f_op);
211 file->f_op = NULL;
212 mutex_unlock(&dmxdev->mutex);
213 wake_up(&dvbdev->wait_queue);
214 } else
215 mutex_unlock(&dmxdev->mutex);
216
202 return 0; 217 return 0;
203} 218}
204 219
@@ -215,6 +230,11 @@ static ssize_t dvb_dvr_write(struct file *file, const char __user *buf,
215 return -EINVAL; 230 return -EINVAL;
216 if (mutex_lock_interruptible(&dmxdev->mutex)) 231 if (mutex_lock_interruptible(&dmxdev->mutex))
217 return -ERESTARTSYS; 232 return -ERESTARTSYS;
233
234 if (dmxdev->exit) {
235 mutex_unlock(&dmxdev->mutex);
236 return -ENODEV;
237 }
218 ret = dmxdev->demux->write(dmxdev->demux, buf, count); 238 ret = dmxdev->demux->write(dmxdev->demux, buf, count);
219 mutex_unlock(&dmxdev->mutex); 239 mutex_unlock(&dmxdev->mutex);
220 return ret; 240 return ret;
@@ -227,6 +247,11 @@ static ssize_t dvb_dvr_read(struct file *file, char __user *buf, size_t count,
227 struct dmxdev *dmxdev = dvbdev->priv; 247 struct dmxdev *dmxdev = dvbdev->priv;
228 int ret; 248 int ret;
229 249
250 if (dmxdev->exit) {
251 mutex_unlock(&dmxdev->mutex);
252 return -ENODEV;
253 }
254
230 //mutex_lock(&dmxdev->mutex); 255 //mutex_lock(&dmxdev->mutex);
231 ret = dvb_dmxdev_buffer_read(&dmxdev->dvr_buffer, 256 ret = dvb_dmxdev_buffer_read(&dmxdev->dvr_buffer,
232 file->f_flags & O_NONBLOCK, 257 file->f_flags & O_NONBLOCK,
@@ -665,6 +690,8 @@ static int dvb_demux_open(struct inode *inode, struct file *file)
665 dmxdevfilter->feed.ts = NULL; 690 dmxdevfilter->feed.ts = NULL;
666 init_timer(&dmxdevfilter->timer); 691 init_timer(&dmxdevfilter->timer);
667 692
693 dvbdev->users++;
694
668 mutex_unlock(&dmxdev->mutex); 695 mutex_unlock(&dmxdev->mutex);
669 return 0; 696 return 0;
670} 697}
@@ -943,7 +970,21 @@ static int dvb_demux_release(struct inode *inode, struct file *file)
943 struct dmxdev_filter *dmxdevfilter = file->private_data; 970 struct dmxdev_filter *dmxdevfilter = file->private_data;
944 struct dmxdev *dmxdev = dmxdevfilter->dev; 971 struct dmxdev *dmxdev = dmxdevfilter->dev;
945 972
946 return dvb_dmxdev_filter_free(dmxdev, dmxdevfilter); 973 int ret;
974
975 ret = dvb_dmxdev_filter_free(dmxdev, dmxdevfilter);
976
977 mutex_lock(&dmxdev->mutex);
978 dmxdev->dvbdev->users--;
979 if(dmxdev->dvbdev->users==1 && dmxdev->exit==1) {
980 fops_put(file->f_op);
981 file->f_op = NULL;
982 mutex_unlock(&dmxdev->mutex);
983 wake_up(&dmxdev->dvbdev->wait_queue);
984 } else
985 mutex_unlock(&dmxdev->mutex);
986
987 return ret;
947} 988}
948 989
949static struct file_operations dvb_demux_fops = { 990static struct file_operations dvb_demux_fops = {
@@ -1027,6 +1068,7 @@ static struct file_operations dvb_dvr_fops = {
1027static struct dvb_device dvbdev_dvr = { 1068static struct dvb_device dvbdev_dvr = {
1028 .priv = NULL, 1069 .priv = NULL,
1029 .readers = 1, 1070 .readers = 1,
1071 .users = 1,
1030 .fops = &dvb_dvr_fops 1072 .fops = &dvb_dvr_fops
1031}; 1073};
1032 1074
@@ -1064,6 +1106,16 @@ EXPORT_SYMBOL(dvb_dmxdev_init);
1064 1106
1065void dvb_dmxdev_release(struct dmxdev *dmxdev) 1107void dvb_dmxdev_release(struct dmxdev *dmxdev)
1066{ 1108{
1109 dmxdev->exit=1;
1110 if (dmxdev->dvbdev->users > 1) {
1111 wait_event(dmxdev->dvbdev->wait_queue,
1112 dmxdev->dvbdev->users==1);
1113 }
1114 if (dmxdev->dvr_dvbdev->users > 1) {
1115 wait_event(dmxdev->dvr_dvbdev->wait_queue,
1116 dmxdev->dvr_dvbdev->users==1);
1117 }
1118
1067 dvb_unregister_device(dmxdev->dvbdev); 1119 dvb_unregister_device(dmxdev->dvbdev);
1068 dvb_unregister_device(dmxdev->dvr_dvbdev); 1120 dvb_unregister_device(dmxdev->dvr_dvbdev);
1069 1121
diff --git a/drivers/media/dvb/dvb-core/dmxdev.h b/drivers/media/dvb/dvb-core/dmxdev.h
index d2bee9ffe43c..29746e70d325 100644
--- a/drivers/media/dvb/dvb-core/dmxdev.h
+++ b/drivers/media/dvb/dvb-core/dmxdev.h
@@ -91,6 +91,8 @@ struct dmxdev {
91 91
92 int filternum; 92 int filternum;
93 int capabilities; 93 int capabilities;
94
95 unsigned int exit:1;
94#define DMXDEV_CAP_DUPLEX 1 96#define DMXDEV_CAP_DUPLEX 1
95 struct dmx_frontend *dvr_orig_fe; 97 struct dmx_frontend *dvr_orig_fe;
96 98
diff --git a/drivers/media/dvb/dvb-core/dvb_demux.c b/drivers/media/dvb/dvb-core/dvb_demux.c
index 6d8d1c3df863..f558ac9c0954 100644
--- a/drivers/media/dvb/dvb-core/dvb_demux.c
+++ b/drivers/media/dvb/dvb-core/dvb_demux.c
@@ -1208,6 +1208,8 @@ int dvb_dmx_init(struct dvb_demux *dvbdemux)
1208 dmx->disconnect_frontend = dvbdmx_disconnect_frontend; 1208 dmx->disconnect_frontend = dvbdmx_disconnect_frontend;
1209 dmx->get_pes_pids = dvbdmx_get_pes_pids; 1209 dmx->get_pes_pids = dvbdmx_get_pes_pids;
1210 1210
1211 init_waitqueue_head (&dvbdemux->wait_queue);
1212
1211 mutex_init(&dvbdemux->mutex); 1213 mutex_init(&dvbdemux->mutex);
1212 spin_lock_init(&dvbdemux->lock); 1214 spin_lock_init(&dvbdemux->lock);
1213 1215
diff --git a/drivers/media/dvb/dvb-core/dvb_demux.h b/drivers/media/dvb/dvb-core/dvb_demux.h
index 2c5f915329ca..e1e91399afd9 100644
--- a/drivers/media/dvb/dvb-core/dvb_demux.h
+++ b/drivers/media/dvb/dvb-core/dvb_demux.h
@@ -119,6 +119,7 @@ struct dvb_demux {
119 u16 pids[DMX_TS_PES_OTHER]; 119 u16 pids[DMX_TS_PES_OTHER];
120 int playing; 120 int playing;
121 int recording; 121 int recording;
122 wait_queue_head_t wait_queue;
122 123
123#define DMX_MAX_PID 0x2000 124#define DMX_MAX_PID 0x2000
124 struct list_head feed_list; 125 struct list_head feed_list;
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c
index 9783d392b7d3..f4e4ca2dcade 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.c
@@ -607,10 +607,6 @@ static void dvb_frontend_stop(struct dvb_frontend *fe)
607 607
608 kthread_stop(fepriv->thread); 608 kthread_stop(fepriv->thread);
609 609
610 if (fepriv->dvbdev->users < -1)
611 wait_event_interruptible(fepriv->dvbdev->wait_queue,
612 fepriv->dvbdev->users==-1);
613
614 init_MUTEX (&fepriv->sem); 610 init_MUTEX (&fepriv->sem);
615 fepriv->state = FESTATE_IDLE; 611 fepriv->state = FESTATE_IDLE;
616 612
@@ -1043,7 +1039,7 @@ static int dvb_frontend_release(struct inode *inode, struct file *file)
1043 if (dvbdev->users==-1 && fepriv->exit==1) { 1039 if (dvbdev->users==-1 && fepriv->exit==1) {
1044 fops_put(file->f_op); 1040 fops_put(file->f_op);
1045 file->f_op = NULL; 1041 file->f_op = NULL;
1046 wake_up_interruptible (&dvbdev->wait_queue); 1042 wake_up(&dvbdev->wait_queue);
1047 } 1043 }
1048 return ret; 1044 return ret;
1049} 1045}
@@ -1104,7 +1100,14 @@ int dvb_unregister_frontend(struct dvb_frontend* fe)
1104 struct dvb_frontend_private *fepriv = fe->frontend_priv; 1100 struct dvb_frontend_private *fepriv = fe->frontend_priv;
1105 dprintk ("%s\n", __FUNCTION__); 1101 dprintk ("%s\n", __FUNCTION__);
1106 1102
1103 mutex_lock(&frontend_mutex);
1107 dvb_frontend_stop (fe); 1104 dvb_frontend_stop (fe);
1105 mutex_unlock(&frontend_mutex);
1106
1107 if (fepriv->dvbdev->users < -1)
1108 wait_event(fepriv->dvbdev->wait_queue,
1109 fepriv->dvbdev->users==-1);
1110
1108 mutex_lock(&frontend_mutex); 1111 mutex_lock(&frontend_mutex);
1109 dvb_unregister_device (fepriv->dvbdev); 1112 dvb_unregister_device (fepriv->dvbdev);
1110 1113