aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb-core/dmxdev.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/dvb-core/dmxdev.c')
-rw-r--r--drivers/media/dvb-core/dmxdev.c115
1 files changed, 65 insertions, 50 deletions
diff --git a/drivers/media/dvb-core/dmxdev.c b/drivers/media/dvb-core/dmxdev.c
index 6d53af00190e..61a750fae465 100644
--- a/drivers/media/dvb-core/dmxdev.c
+++ b/drivers/media/dvb-core/dmxdev.c
@@ -128,11 +128,7 @@ static int dvb_dvr_open(struct inode *inode, struct file *file)
128 struct dvb_device *dvbdev = file->private_data; 128 struct dvb_device *dvbdev = file->private_data;
129 struct dmxdev *dmxdev = dvbdev->priv; 129 struct dmxdev *dmxdev = dvbdev->priv;
130 struct dmx_frontend *front; 130 struct dmx_frontend *front;
131#ifndef DVB_MMAP
132 bool need_ringbuffer = false; 131 bool need_ringbuffer = false;
133#else
134 const bool need_ringbuffer = true;
135#endif
136 132
137 dprintk("%s\n", __func__); 133 dprintk("%s\n", __func__);
138 134
@@ -144,17 +140,31 @@ static int dvb_dvr_open(struct inode *inode, struct file *file)
144 return -ENODEV; 140 return -ENODEV;
145 } 141 }
146 142
147#ifndef DVB_MMAP 143 dmxdev->may_do_mmap = 0;
144
145 /*
146 * The logic here is a little tricky due to the ifdef.
147 *
148 * The ringbuffer is used for both read and mmap.
149 *
150 * It is not needed, however, on two situations:
151 * - Write devices (access with O_WRONLY);
152 * - For duplex device nodes, opened with O_RDWR.
153 */
154
148 if ((file->f_flags & O_ACCMODE) == O_RDONLY) 155 if ((file->f_flags & O_ACCMODE) == O_RDONLY)
149 need_ringbuffer = true; 156 need_ringbuffer = true;
150#else 157 else if ((file->f_flags & O_ACCMODE) == O_RDWR) {
151 if ((file->f_flags & O_ACCMODE) == O_RDWR) {
152 if (!(dmxdev->capabilities & DMXDEV_CAP_DUPLEX)) { 158 if (!(dmxdev->capabilities & DMXDEV_CAP_DUPLEX)) {
159#ifdef CONFIG_DVB_MMAP
160 dmxdev->may_do_mmap = 1;
161 need_ringbuffer = true;
162#else
153 mutex_unlock(&dmxdev->mutex); 163 mutex_unlock(&dmxdev->mutex);
154 return -EOPNOTSUPP; 164 return -EOPNOTSUPP;
165#endif
155 } 166 }
156 } 167 }
157#endif
158 168
159 if (need_ringbuffer) { 169 if (need_ringbuffer) {
160 void *mem; 170 void *mem;
@@ -169,8 +179,9 @@ static int dvb_dvr_open(struct inode *inode, struct file *file)
169 return -ENOMEM; 179 return -ENOMEM;
170 } 180 }
171 dvb_ringbuffer_init(&dmxdev->dvr_buffer, mem, DVR_BUFFER_SIZE); 181 dvb_ringbuffer_init(&dmxdev->dvr_buffer, mem, DVR_BUFFER_SIZE);
172 dvb_vb2_init(&dmxdev->dvr_vb2_ctx, "dvr", 182 if (dmxdev->may_do_mmap)
173 file->f_flags & O_NONBLOCK); 183 dvb_vb2_init(&dmxdev->dvr_vb2_ctx, "dvr",
184 file->f_flags & O_NONBLOCK);
174 dvbdev->readers--; 185 dvbdev->readers--;
175 } 186 }
176 187
@@ -200,11 +211,6 @@ static int dvb_dvr_release(struct inode *inode, struct file *file)
200{ 211{
201 struct dvb_device *dvbdev = file->private_data; 212 struct dvb_device *dvbdev = file->private_data;
202 struct dmxdev *dmxdev = dvbdev->priv; 213 struct dmxdev *dmxdev = dvbdev->priv;
203#ifndef DVB_MMAP
204 bool need_ringbuffer = false;
205#else
206 const bool need_ringbuffer = true;
207#endif
208 214
209 mutex_lock(&dmxdev->mutex); 215 mutex_lock(&dmxdev->mutex);
210 216
@@ -213,15 +219,14 @@ static int dvb_dvr_release(struct inode *inode, struct file *file)
213 dmxdev->demux->connect_frontend(dmxdev->demux, 219 dmxdev->demux->connect_frontend(dmxdev->demux,
214 dmxdev->dvr_orig_fe); 220 dmxdev->dvr_orig_fe);
215 } 221 }
216#ifndef DVB_MMAP
217 if ((file->f_flags & O_ACCMODE) == O_RDONLY)
218 need_ringbuffer = true;
219#endif
220 222
221 if (need_ringbuffer) { 223 if (((file->f_flags & O_ACCMODE) == O_RDONLY) ||
222 if (dvb_vb2_is_streaming(&dmxdev->dvr_vb2_ctx)) 224 dmxdev->may_do_mmap) {
223 dvb_vb2_stream_off(&dmxdev->dvr_vb2_ctx); 225 if (dmxdev->may_do_mmap) {
224 dvb_vb2_release(&dmxdev->dvr_vb2_ctx); 226 if (dvb_vb2_is_streaming(&dmxdev->dvr_vb2_ctx))
227 dvb_vb2_stream_off(&dmxdev->dvr_vb2_ctx);
228 dvb_vb2_release(&dmxdev->dvr_vb2_ctx);
229 }
225 dvbdev->readers++; 230 dvbdev->readers++;
226 if (dmxdev->dvr_buffer.data) { 231 if (dmxdev->dvr_buffer.data) {
227 void *mem = dmxdev->dvr_buffer.data; 232 void *mem = dmxdev->dvr_buffer.data;
@@ -380,7 +385,8 @@ static void dvb_dmxdev_filter_timer(struct dmxdev_filter *dmxdevfilter)
380 385
381static int dvb_dmxdev_section_callback(const u8 *buffer1, size_t buffer1_len, 386static int dvb_dmxdev_section_callback(const u8 *buffer1, size_t buffer1_len,
382 const u8 *buffer2, size_t buffer2_len, 387 const u8 *buffer2, size_t buffer2_len,
383 struct dmx_section_filter *filter) 388 struct dmx_section_filter *filter,
389 u32 *buffer_flags)
384{ 390{
385 struct dmxdev_filter *dmxdevfilter = filter->priv; 391 struct dmxdev_filter *dmxdevfilter = filter->priv;
386 int ret; 392 int ret;
@@ -399,10 +405,12 @@ static int dvb_dmxdev_section_callback(const u8 *buffer1, size_t buffer1_len,
399 dprintk("section callback %*ph\n", 6, buffer1); 405 dprintk("section callback %*ph\n", 6, buffer1);
400 if (dvb_vb2_is_streaming(&dmxdevfilter->vb2_ctx)) { 406 if (dvb_vb2_is_streaming(&dmxdevfilter->vb2_ctx)) {
401 ret = dvb_vb2_fill_buffer(&dmxdevfilter->vb2_ctx, 407 ret = dvb_vb2_fill_buffer(&dmxdevfilter->vb2_ctx,
402 buffer1, buffer1_len); 408 buffer1, buffer1_len,
409 buffer_flags);
403 if (ret == buffer1_len) 410 if (ret == buffer1_len)
404 ret = dvb_vb2_fill_buffer(&dmxdevfilter->vb2_ctx, 411 ret = dvb_vb2_fill_buffer(&dmxdevfilter->vb2_ctx,
405 buffer2, buffer2_len); 412 buffer2, buffer2_len,
413 buffer_flags);
406 } else { 414 } else {
407 ret = dvb_dmxdev_buffer_write(&dmxdevfilter->buffer, 415 ret = dvb_dmxdev_buffer_write(&dmxdevfilter->buffer,
408 buffer1, buffer1_len); 416 buffer1, buffer1_len);
@@ -422,11 +430,12 @@ static int dvb_dmxdev_section_callback(const u8 *buffer1, size_t buffer1_len,
422 430
423static int dvb_dmxdev_ts_callback(const u8 *buffer1, size_t buffer1_len, 431static int dvb_dmxdev_ts_callback(const u8 *buffer1, size_t buffer1_len,
424 const u8 *buffer2, size_t buffer2_len, 432 const u8 *buffer2, size_t buffer2_len,
425 struct dmx_ts_feed *feed) 433 struct dmx_ts_feed *feed,
434 u32 *buffer_flags)
426{ 435{
427 struct dmxdev_filter *dmxdevfilter = feed->priv; 436 struct dmxdev_filter *dmxdevfilter = feed->priv;
428 struct dvb_ringbuffer *buffer; 437 struct dvb_ringbuffer *buffer;
429#ifdef DVB_MMAP 438#ifdef CONFIG_DVB_MMAP
430 struct dvb_vb2_ctx *ctx; 439 struct dvb_vb2_ctx *ctx;
431#endif 440#endif
432 int ret; 441 int ret;
@@ -440,20 +449,22 @@ static int dvb_dmxdev_ts_callback(const u8 *buffer1, size_t buffer1_len,
440 if (dmxdevfilter->params.pes.output == DMX_OUT_TAP || 449 if (dmxdevfilter->params.pes.output == DMX_OUT_TAP ||
441 dmxdevfilter->params.pes.output == DMX_OUT_TSDEMUX_TAP) { 450 dmxdevfilter->params.pes.output == DMX_OUT_TSDEMUX_TAP) {
442 buffer = &dmxdevfilter->buffer; 451 buffer = &dmxdevfilter->buffer;
443#ifdef DVB_MMAP 452#ifdef CONFIG_DVB_MMAP
444 ctx = &dmxdevfilter->vb2_ctx; 453 ctx = &dmxdevfilter->vb2_ctx;
445#endif 454#endif
446 } else { 455 } else {
447 buffer = &dmxdevfilter->dev->dvr_buffer; 456 buffer = &dmxdevfilter->dev->dvr_buffer;
448#ifdef DVB_MMAP 457#ifdef CONFIG_DVB_MMAP
449 ctx = &dmxdevfilter->dev->dvr_vb2_ctx; 458 ctx = &dmxdevfilter->dev->dvr_vb2_ctx;
450#endif 459#endif
451 } 460 }
452 461
453 if (dvb_vb2_is_streaming(ctx)) { 462 if (dvb_vb2_is_streaming(ctx)) {
454 ret = dvb_vb2_fill_buffer(ctx, buffer1, buffer1_len); 463 ret = dvb_vb2_fill_buffer(ctx, buffer1, buffer1_len,
464 buffer_flags);
455 if (ret == buffer1_len) 465 if (ret == buffer1_len)
456 ret = dvb_vb2_fill_buffer(ctx, buffer2, buffer2_len); 466 ret = dvb_vb2_fill_buffer(ctx, buffer2, buffer2_len,
467 buffer_flags);
457 } else { 468 } else {
458 if (buffer->error) { 469 if (buffer->error) {
459 spin_unlock(&dmxdevfilter->dev->lock); 470 spin_unlock(&dmxdevfilter->dev->lock);
@@ -802,6 +813,12 @@ static int dvb_demux_open(struct inode *inode, struct file *file)
802 mutex_init(&dmxdevfilter->mutex); 813 mutex_init(&dmxdevfilter->mutex);
803 file->private_data = dmxdevfilter; 814 file->private_data = dmxdevfilter;
804 815
816#ifdef CONFIG_DVB_MMAP
817 dmxdev->may_do_mmap = 1;
818#else
819 dmxdev->may_do_mmap = 0;
820#endif
821
805 dvb_ringbuffer_init(&dmxdevfilter->buffer, NULL, 8192); 822 dvb_ringbuffer_init(&dmxdevfilter->buffer, NULL, 8192);
806 dvb_vb2_init(&dmxdevfilter->vb2_ctx, "demux_filter", 823 dvb_vb2_init(&dmxdevfilter->vb2_ctx, "demux_filter",
807 file->f_flags & O_NONBLOCK); 824 file->f_flags & O_NONBLOCK);
@@ -1111,7 +1128,7 @@ static int dvb_demux_do_ioctl(struct file *file,
1111 mutex_unlock(&dmxdevfilter->mutex); 1128 mutex_unlock(&dmxdevfilter->mutex);
1112 break; 1129 break;
1113 1130
1114#ifdef DVB_MMAP 1131#ifdef CONFIG_DVB_MMAP
1115 case DMX_REQBUFS: 1132 case DMX_REQBUFS:
1116 if (mutex_lock_interruptible(&dmxdevfilter->mutex)) { 1133 if (mutex_lock_interruptible(&dmxdevfilter->mutex)) {
1117 mutex_unlock(&dmxdev->mutex); 1134 mutex_unlock(&dmxdev->mutex);
@@ -1160,7 +1177,7 @@ static int dvb_demux_do_ioctl(struct file *file,
1160 break; 1177 break;
1161#endif 1178#endif
1162 default: 1179 default:
1163 ret = -EINVAL; 1180 ret = -ENOTTY;
1164 break; 1181 break;
1165 } 1182 }
1166 mutex_unlock(&dmxdev->mutex); 1183 mutex_unlock(&dmxdev->mutex);
@@ -1199,13 +1216,16 @@ static __poll_t dvb_demux_poll(struct file *file, poll_table *wait)
1199 return mask; 1216 return mask;
1200} 1217}
1201 1218
1202#ifdef DVB_MMAP 1219#ifdef CONFIG_DVB_MMAP
1203static int dvb_demux_mmap(struct file *file, struct vm_area_struct *vma) 1220static int dvb_demux_mmap(struct file *file, struct vm_area_struct *vma)
1204{ 1221{
1205 struct dmxdev_filter *dmxdevfilter = file->private_data; 1222 struct dmxdev_filter *dmxdevfilter = file->private_data;
1206 struct dmxdev *dmxdev = dmxdevfilter->dev; 1223 struct dmxdev *dmxdev = dmxdevfilter->dev;
1207 int ret; 1224 int ret;
1208 1225
1226 if (!dmxdev->may_do_mmap)
1227 return -ENOTTY;
1228
1209 if (mutex_lock_interruptible(&dmxdev->mutex)) 1229 if (mutex_lock_interruptible(&dmxdev->mutex))
1210 return -ERESTARTSYS; 1230 return -ERESTARTSYS;
1211 1231
@@ -1249,7 +1269,7 @@ static const struct file_operations dvb_demux_fops = {
1249 .release = dvb_demux_release, 1269 .release = dvb_demux_release,
1250 .poll = dvb_demux_poll, 1270 .poll = dvb_demux_poll,
1251 .llseek = default_llseek, 1271 .llseek = default_llseek,
1252#ifdef DVB_MMAP 1272#ifdef CONFIG_DVB_MMAP
1253 .mmap = dvb_demux_mmap, 1273 .mmap = dvb_demux_mmap,
1254#endif 1274#endif
1255}; 1275};
@@ -1280,7 +1300,7 @@ static int dvb_dvr_do_ioctl(struct file *file,
1280 ret = dvb_dvr_set_buffer_size(dmxdev, arg); 1300 ret = dvb_dvr_set_buffer_size(dmxdev, arg);
1281 break; 1301 break;
1282 1302
1283#ifdef DVB_MMAP 1303#ifdef CONFIG_DVB_MMAP
1284 case DMX_REQBUFS: 1304 case DMX_REQBUFS:
1285 ret = dvb_vb2_reqbufs(&dmxdev->dvr_vb2_ctx, parg); 1305 ret = dvb_vb2_reqbufs(&dmxdev->dvr_vb2_ctx, parg);
1286 break; 1306 break;
@@ -1304,7 +1324,7 @@ static int dvb_dvr_do_ioctl(struct file *file,
1304 break; 1324 break;
1305#endif 1325#endif
1306 default: 1326 default:
1307 ret = -EINVAL; 1327 ret = -ENOTTY;
1308 break; 1328 break;
1309 } 1329 }
1310 mutex_unlock(&dmxdev->mutex); 1330 mutex_unlock(&dmxdev->mutex);
@@ -1322,11 +1342,6 @@ static __poll_t dvb_dvr_poll(struct file *file, poll_table *wait)
1322 struct dvb_device *dvbdev = file->private_data; 1342 struct dvb_device *dvbdev = file->private_data;
1323 struct dmxdev *dmxdev = dvbdev->priv; 1343 struct dmxdev *dmxdev = dvbdev->priv;
1324 __poll_t mask = 0; 1344 __poll_t mask = 0;
1325#ifndef DVB_MMAP
1326 bool need_ringbuffer = false;
1327#else
1328 const bool need_ringbuffer = true;
1329#endif
1330 1345
1331 dprintk("%s\n", __func__); 1346 dprintk("%s\n", __func__);
1332 1347
@@ -1337,11 +1352,8 @@ static __poll_t dvb_dvr_poll(struct file *file, poll_table *wait)
1337 1352
1338 poll_wait(file, &dmxdev->dvr_buffer.queue, wait); 1353 poll_wait(file, &dmxdev->dvr_buffer.queue, wait);
1339 1354
1340#ifndef DVB_MMAP 1355 if (((file->f_flags & O_ACCMODE) == O_RDONLY) ||
1341 if ((file->f_flags & O_ACCMODE) == O_RDONLY) 1356 dmxdev->may_do_mmap) {
1342 need_ringbuffer = true;
1343#endif
1344 if (need_ringbuffer) {
1345 if (dmxdev->dvr_buffer.error) 1357 if (dmxdev->dvr_buffer.error)
1346 mask |= (EPOLLIN | EPOLLRDNORM | EPOLLPRI | EPOLLERR); 1358 mask |= (EPOLLIN | EPOLLRDNORM | EPOLLPRI | EPOLLERR);
1347 1359
@@ -1353,13 +1365,16 @@ static __poll_t dvb_dvr_poll(struct file *file, poll_table *wait)
1353 return mask; 1365 return mask;
1354} 1366}
1355 1367
1356#ifdef DVB_MMAP 1368#ifdef CONFIG_DVB_MMAP
1357static int dvb_dvr_mmap(struct file *file, struct vm_area_struct *vma) 1369static int dvb_dvr_mmap(struct file *file, struct vm_area_struct *vma)
1358{ 1370{
1359 struct dvb_device *dvbdev = file->private_data; 1371 struct dvb_device *dvbdev = file->private_data;
1360 struct dmxdev *dmxdev = dvbdev->priv; 1372 struct dmxdev *dmxdev = dvbdev->priv;
1361 int ret; 1373 int ret;
1362 1374
1375 if (!dmxdev->may_do_mmap)
1376 return -ENOTTY;
1377
1363 if (dmxdev->exit) 1378 if (dmxdev->exit)
1364 return -ENODEV; 1379 return -ENODEV;
1365 1380
@@ -1381,7 +1396,7 @@ static const struct file_operations dvb_dvr_fops = {
1381 .release = dvb_dvr_release, 1396 .release = dvb_dvr_release,
1382 .poll = dvb_dvr_poll, 1397 .poll = dvb_dvr_poll,
1383 .llseek = default_llseek, 1398 .llseek = default_llseek,
1384#ifdef DVB_MMAP 1399#ifdef CONFIG_DVB_MMAP
1385 .mmap = dvb_dvr_mmap, 1400 .mmap = dvb_dvr_mmap,
1386#endif 1401#endif
1387}; 1402};