diff options
Diffstat (limited to 'drivers/media')
-rw-r--r-- | drivers/media/dvb/dvb-core/dmxdev.c | 56 | ||||
-rw-r--r-- | drivers/media/dvb/dvb-core/dmxdev.h | 2 | ||||
-rw-r--r-- | drivers/media/dvb/dvb-core/dvb_demux.c | 2 | ||||
-rw-r--r-- | drivers/media/dvb/dvb-core/dvb_demux.h | 1 | ||||
-rw-r--r-- | drivers/media/dvb/dvb-core/dvb_frontend.c | 13 |
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 | ||
949 | static struct file_operations dvb_demux_fops = { | 990 | static struct file_operations dvb_demux_fops = { |
@@ -1027,6 +1068,7 @@ static struct file_operations dvb_dvr_fops = { | |||
1027 | static struct dvb_device dvbdev_dvr = { | 1068 | static 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 | ||
1065 | void dvb_dmxdev_release(struct dmxdev *dmxdev) | 1107 | void 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 | ||