diff options
24 files changed, 329 insertions, 175 deletions
diff --git a/Documentation/media/dmx.h.rst.exceptions b/Documentation/media/dmx.h.rst.exceptions index 63f55a9ae2b1..a8c4239ed95b 100644 --- a/Documentation/media/dmx.h.rst.exceptions +++ b/Documentation/media/dmx.h.rst.exceptions | |||
@@ -50,9 +50,15 @@ replace typedef dmx_filter_t :c:type:`dmx_filter` | |||
50 | replace typedef dmx_pes_type_t :c:type:`dmx_pes_type` | 50 | replace typedef dmx_pes_type_t :c:type:`dmx_pes_type` |
51 | replace typedef dmx_input_t :c:type:`dmx_input` | 51 | replace typedef dmx_input_t :c:type:`dmx_input` |
52 | 52 | ||
53 | ignore symbol DMX_OUT_DECODER | 53 | replace symbol DMX_BUFFER_FLAG_HAD_CRC32_DISCARD :c:type:`dmx_buffer_flags` |
54 | ignore symbol DMX_OUT_TAP | 54 | replace symbol DMX_BUFFER_FLAG_TEI :c:type:`dmx_buffer_flags` |
55 | ignore symbol DMX_OUT_TS_TAP | 55 | replace symbol DMX_BUFFER_PKT_COUNTER_MISMATCH :c:type:`dmx_buffer_flags` |
56 | ignore symbol DMX_OUT_TSDEMUX_TAP | 56 | replace symbol DMX_BUFFER_FLAG_DISCONTINUITY_DETECTED :c:type:`dmx_buffer_flags` |
57 | replace symbol DMX_BUFFER_FLAG_DISCONTINUITY_INDICATOR :c:type:`dmx_buffer_flags` | ||
58 | |||
59 | replace symbol DMX_OUT_DECODER :c:type:`dmx_output` | ||
60 | replace symbol DMX_OUT_TAP :c:type:`dmx_output` | ||
61 | replace symbol DMX_OUT_TS_TAP :c:type:`dmx_output` | ||
62 | replace symbol DMX_OUT_TSDEMUX_TAP :c:type:`dmx_output` | ||
57 | 63 | ||
58 | replace ioctl DMX_DQBUF dmx_qbuf | 64 | replace ioctl DMX_DQBUF dmx_qbuf |
diff --git a/Documentation/media/uapi/dvb/dmx-qbuf.rst b/Documentation/media/uapi/dvb/dmx-qbuf.rst index b48c4931658e..be5a4c6f1904 100644 --- a/Documentation/media/uapi/dvb/dmx-qbuf.rst +++ b/Documentation/media/uapi/dvb/dmx-qbuf.rst | |||
@@ -51,9 +51,10 @@ out to disk. Buffers remain locked until dequeued, until the | |||
51 | the device is closed. | 51 | the device is closed. |
52 | 52 | ||
53 | Applications call the ``DMX_DQBUF`` ioctl to dequeue a filled | 53 | Applications call the ``DMX_DQBUF`` ioctl to dequeue a filled |
54 | (capturing) buffer from the driver's outgoing queue. They just set the ``reserved`` field array to zero. When ``DMX_DQBUF`` is called with a | 54 | (capturing) buffer from the driver's outgoing queue. |
55 | pointer to this structure, the driver fills the remaining fields or | 55 | They just set the ``index`` field withe the buffer ID to be queued. |
56 | returns an error code. | 56 | When ``DMX_DQBUF`` is called with a pointer to struct :c:type:`dmx_buffer`, |
57 | the driver fills the remaining fields or returns an error code. | ||
57 | 58 | ||
58 | By default ``DMX_DQBUF`` blocks when no buffer is in the outgoing | 59 | By default ``DMX_DQBUF`` blocks when no buffer is in the outgoing |
59 | queue. When the ``O_NONBLOCK`` flag was given to the | 60 | queue. When the ``O_NONBLOCK`` flag was given to the |
diff --git a/drivers/media/Kconfig b/drivers/media/Kconfig index 145e12bfb819..372c074bb1b9 100644 --- a/drivers/media/Kconfig +++ b/drivers/media/Kconfig | |||
@@ -147,6 +147,8 @@ config DVB_CORE | |||
147 | config DVB_MMAP | 147 | config DVB_MMAP |
148 | bool "Enable DVB memory-mapped API (EXPERIMENTAL)" | 148 | bool "Enable DVB memory-mapped API (EXPERIMENTAL)" |
149 | depends on DVB_CORE | 149 | depends on DVB_CORE |
150 | depends on VIDEO_V4L2=y || VIDEO_V4L2=DVB_CORE | ||
151 | select VIDEOBUF2_VMALLOC | ||
150 | default n | 152 | default n |
151 | help | 153 | help |
152 | This option enables DVB experimental memory-mapped API, with | 154 | This option enables DVB experimental memory-mapped API, with |
diff --git a/drivers/media/common/videobuf2/Kconfig b/drivers/media/common/videobuf2/Kconfig index 5df05250de94..17c32ea58395 100644 --- a/drivers/media/common/videobuf2/Kconfig +++ b/drivers/media/common/videobuf2/Kconfig | |||
@@ -3,6 +3,9 @@ config VIDEOBUF2_CORE | |||
3 | select DMA_SHARED_BUFFER | 3 | select DMA_SHARED_BUFFER |
4 | tristate | 4 | tristate |
5 | 5 | ||
6 | config VIDEOBUF2_V4L2 | ||
7 | tristate | ||
8 | |||
6 | config VIDEOBUF2_MEMOPS | 9 | config VIDEOBUF2_MEMOPS |
7 | tristate | 10 | tristate |
8 | select FRAME_VECTOR | 11 | select FRAME_VECTOR |
diff --git a/drivers/media/common/videobuf2/Makefile b/drivers/media/common/videobuf2/Makefile index 19de5ccda20b..77bebe8b202f 100644 --- a/drivers/media/common/videobuf2/Makefile +++ b/drivers/media/common/videobuf2/Makefile | |||
@@ -1,5 +1,12 @@ | |||
1 | # SPDX-License-Identifier: GPL-2.0 | ||
2 | videobuf2-common-objs := videobuf2-core.o | ||
1 | 3 | ||
2 | obj-$(CONFIG_VIDEOBUF2_CORE) += videobuf2-core.o videobuf2-v4l2.o | 4 | ifeq ($(CONFIG_TRACEPOINTS),y) |
5 | videobuf2-common-objs += vb2-trace.o | ||
6 | endif | ||
7 | |||
8 | obj-$(CONFIG_VIDEOBUF2_CORE) += videobuf2-common.o | ||
9 | obj-$(CONFIG_VIDEOBUF2_V4L2) += videobuf2-v4l2.o | ||
3 | obj-$(CONFIG_VIDEOBUF2_MEMOPS) += videobuf2-memops.o | 10 | obj-$(CONFIG_VIDEOBUF2_MEMOPS) += videobuf2-memops.o |
4 | obj-$(CONFIG_VIDEOBUF2_VMALLOC) += videobuf2-vmalloc.o | 11 | obj-$(CONFIG_VIDEOBUF2_VMALLOC) += videobuf2-vmalloc.o |
5 | obj-$(CONFIG_VIDEOBUF2_DMA_CONTIG) += videobuf2-dma-contig.o | 12 | obj-$(CONFIG_VIDEOBUF2_DMA_CONTIG) += videobuf2-dma-contig.o |
diff --git a/drivers/media/v4l2-core/vb2-trace.c b/drivers/media/common/videobuf2/vb2-trace.c index 4c0f39d271f0..4c0f39d271f0 100644 --- a/drivers/media/v4l2-core/vb2-trace.c +++ b/drivers/media/common/videobuf2/vb2-trace.c | |||
diff --git a/drivers/media/dvb-core/Makefile b/drivers/media/dvb-core/Makefile index 3a105d82019a..62b028ded9f7 100644 --- a/drivers/media/dvb-core/Makefile +++ b/drivers/media/dvb-core/Makefile | |||
@@ -4,7 +4,7 @@ | |||
4 | # | 4 | # |
5 | 5 | ||
6 | dvb-net-$(CONFIG_DVB_NET) := dvb_net.o | 6 | dvb-net-$(CONFIG_DVB_NET) := dvb_net.o |
7 | dvb-vb2-$(CONFIG_DVB_MMSP) := dvb_vb2.o | 7 | dvb-vb2-$(CONFIG_DVB_MMAP) := dvb_vb2.o |
8 | 8 | ||
9 | dvb-core-objs := dvbdev.o dmxdev.o dvb_demux.o \ | 9 | dvb-core-objs := dvbdev.o dmxdev.o dvb_demux.o \ |
10 | dvb_ca_en50221.o dvb_frontend.o \ | 10 | dvb_ca_en50221.o dvb_frontend.o \ |
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 | ||
381 | static int dvb_dmxdev_section_callback(const u8 *buffer1, size_t buffer1_len, | 386 | static 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 | ||
423 | static int dvb_dmxdev_ts_callback(const u8 *buffer1, size_t buffer1_len, | 431 | static 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 |
1203 | static int dvb_demux_mmap(struct file *file, struct vm_area_struct *vma) | 1220 | static 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 |
1357 | static int dvb_dvr_mmap(struct file *file, struct vm_area_struct *vma) | 1369 | static 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 | }; |
diff --git a/drivers/media/dvb-core/dvb_demux.c b/drivers/media/dvb-core/dvb_demux.c index 210eed0269b0..f45091246bdc 100644 --- a/drivers/media/dvb-core/dvb_demux.c +++ b/drivers/media/dvb-core/dvb_demux.c | |||
@@ -55,6 +55,17 @@ MODULE_PARM_DESC(dvb_demux_feed_err_pkts, | |||
55 | dprintk(x); \ | 55 | dprintk(x); \ |
56 | } while (0) | 56 | } while (0) |
57 | 57 | ||
58 | #ifdef CONFIG_DVB_DEMUX_SECTION_LOSS_LOG | ||
59 | # define dprintk_sect_loss(x...) dprintk(x) | ||
60 | #else | ||
61 | # define dprintk_sect_loss(x...) | ||
62 | #endif | ||
63 | |||
64 | #define set_buf_flags(__feed, __flag) \ | ||
65 | do { \ | ||
66 | (__feed)->buffer_flags |= (__flag); \ | ||
67 | } while (0) | ||
68 | |||
58 | /****************************************************************************** | 69 | /****************************************************************************** |
59 | * static inlined helper functions | 70 | * static inlined helper functions |
60 | ******************************************************************************/ | 71 | ******************************************************************************/ |
@@ -104,31 +115,30 @@ static inline int dvb_dmx_swfilter_payload(struct dvb_demux_feed *feed, | |||
104 | { | 115 | { |
105 | int count = payload(buf); | 116 | int count = payload(buf); |
106 | int p; | 117 | int p; |
107 | #ifdef CONFIG_DVB_DEMUX_SECTION_LOSS_LOG | ||
108 | int ccok; | 118 | int ccok; |
109 | u8 cc; | 119 | u8 cc; |
110 | #endif | ||
111 | 120 | ||
112 | if (count == 0) | 121 | if (count == 0) |
113 | return -1; | 122 | return -1; |
114 | 123 | ||
115 | p = 188 - count; | 124 | p = 188 - count; |
116 | 125 | ||
117 | #ifdef CONFIG_DVB_DEMUX_SECTION_LOSS_LOG | ||
118 | cc = buf[3] & 0x0f; | 126 | cc = buf[3] & 0x0f; |
119 | ccok = ((feed->cc + 1) & 0x0f) == cc; | 127 | ccok = ((feed->cc + 1) & 0x0f) == cc; |
120 | feed->cc = cc; | 128 | feed->cc = cc; |
121 | if (!ccok) | 129 | if (!ccok) { |
122 | dprintk("missed packet: %d instead of %d!\n", | 130 | set_buf_flags(feed, DMX_BUFFER_FLAG_DISCONTINUITY_DETECTED); |
123 | cc, (feed->cc + 1) & 0x0f); | 131 | dprintk_sect_loss("missed packet: %d instead of %d!\n", |
124 | #endif | 132 | cc, (feed->cc + 1) & 0x0f); |
133 | } | ||
125 | 134 | ||
126 | if (buf[1] & 0x40) // PUSI ? | 135 | if (buf[1] & 0x40) // PUSI ? |
127 | feed->peslen = 0xfffa; | 136 | feed->peslen = 0xfffa; |
128 | 137 | ||
129 | feed->peslen += count; | 138 | feed->peslen += count; |
130 | 139 | ||
131 | return feed->cb.ts(&buf[p], count, NULL, 0, &feed->feed.ts); | 140 | return feed->cb.ts(&buf[p], count, NULL, 0, &feed->feed.ts, |
141 | &feed->buffer_flags); | ||
132 | } | 142 | } |
133 | 143 | ||
134 | static int dvb_dmx_swfilter_sectionfilter(struct dvb_demux_feed *feed, | 144 | static int dvb_dmx_swfilter_sectionfilter(struct dvb_demux_feed *feed, |
@@ -150,7 +160,7 @@ static int dvb_dmx_swfilter_sectionfilter(struct dvb_demux_feed *feed, | |||
150 | return 0; | 160 | return 0; |
151 | 161 | ||
152 | return feed->cb.sec(feed->feed.sec.secbuf, feed->feed.sec.seclen, | 162 | return feed->cb.sec(feed->feed.sec.secbuf, feed->feed.sec.seclen, |
153 | NULL, 0, &f->filter); | 163 | NULL, 0, &f->filter, &feed->buffer_flags); |
154 | } | 164 | } |
155 | 165 | ||
156 | static inline int dvb_dmx_swfilter_section_feed(struct dvb_demux_feed *feed) | 166 | static inline int dvb_dmx_swfilter_section_feed(struct dvb_demux_feed *feed) |
@@ -169,8 +179,10 @@ static inline int dvb_dmx_swfilter_section_feed(struct dvb_demux_feed *feed) | |||
169 | if (sec->check_crc) { | 179 | if (sec->check_crc) { |
170 | section_syntax_indicator = ((sec->secbuf[1] & 0x80) != 0); | 180 | section_syntax_indicator = ((sec->secbuf[1] & 0x80) != 0); |
171 | if (section_syntax_indicator && | 181 | if (section_syntax_indicator && |
172 | demux->check_crc32(feed, sec->secbuf, sec->seclen)) | 182 | demux->check_crc32(feed, sec->secbuf, sec->seclen)) { |
183 | set_buf_flags(feed, DMX_BUFFER_FLAG_HAD_CRC32_DISCARD); | ||
173 | return -1; | 184 | return -1; |
185 | } | ||
174 | } | 186 | } |
175 | 187 | ||
176 | do { | 188 | do { |
@@ -187,7 +199,6 @@ static void dvb_dmx_swfilter_section_new(struct dvb_demux_feed *feed) | |||
187 | { | 199 | { |
188 | struct dmx_section_feed *sec = &feed->feed.sec; | 200 | struct dmx_section_feed *sec = &feed->feed.sec; |
189 | 201 | ||
190 | #ifdef CONFIG_DVB_DEMUX_SECTION_LOSS_LOG | ||
191 | if (sec->secbufp < sec->tsfeedp) { | 202 | if (sec->secbufp < sec->tsfeedp) { |
192 | int n = sec->tsfeedp - sec->secbufp; | 203 | int n = sec->tsfeedp - sec->secbufp; |
193 | 204 | ||
@@ -197,12 +208,13 @@ static void dvb_dmx_swfilter_section_new(struct dvb_demux_feed *feed) | |||
197 | * but just first and last. | 208 | * but just first and last. |
198 | */ | 209 | */ |
199 | if (sec->secbuf[0] != 0xff || sec->secbuf[n - 1] != 0xff) { | 210 | if (sec->secbuf[0] != 0xff || sec->secbuf[n - 1] != 0xff) { |
200 | dprintk("section ts padding loss: %d/%d\n", | 211 | set_buf_flags(feed, |
201 | n, sec->tsfeedp); | 212 | DMX_BUFFER_FLAG_DISCONTINUITY_DETECTED); |
202 | dprintk("pad data: %*ph\n", n, sec->secbuf); | 213 | dprintk_sect_loss("section ts padding loss: %d/%d\n", |
214 | n, sec->tsfeedp); | ||
215 | dprintk_sect_loss("pad data: %*ph\n", n, sec->secbuf); | ||
203 | } | 216 | } |
204 | } | 217 | } |
205 | #endif | ||
206 | 218 | ||
207 | sec->tsfeedp = sec->secbufp = sec->seclen = 0; | 219 | sec->tsfeedp = sec->secbufp = sec->seclen = 0; |
208 | sec->secbuf = sec->secbuf_base; | 220 | sec->secbuf = sec->secbuf_base; |
@@ -237,11 +249,10 @@ static int dvb_dmx_swfilter_section_copy_dump(struct dvb_demux_feed *feed, | |||
237 | return 0; | 249 | return 0; |
238 | 250 | ||
239 | if (sec->tsfeedp + len > DMX_MAX_SECFEED_SIZE) { | 251 | if (sec->tsfeedp + len > DMX_MAX_SECFEED_SIZE) { |
240 | #ifdef CONFIG_DVB_DEMUX_SECTION_LOSS_LOG | 252 | set_buf_flags(feed, DMX_BUFFER_FLAG_DISCONTINUITY_DETECTED); |
241 | dprintk("section buffer full loss: %d/%d\n", | 253 | dprintk_sect_loss("section buffer full loss: %d/%d\n", |
242 | sec->tsfeedp + len - DMX_MAX_SECFEED_SIZE, | 254 | sec->tsfeedp + len - DMX_MAX_SECFEED_SIZE, |
243 | DMX_MAX_SECFEED_SIZE); | 255 | DMX_MAX_SECFEED_SIZE); |
244 | #endif | ||
245 | len = DMX_MAX_SECFEED_SIZE - sec->tsfeedp; | 256 | len = DMX_MAX_SECFEED_SIZE - sec->tsfeedp; |
246 | } | 257 | } |
247 | 258 | ||
@@ -269,12 +280,13 @@ static int dvb_dmx_swfilter_section_copy_dump(struct dvb_demux_feed *feed, | |||
269 | sec->seclen = seclen; | 280 | sec->seclen = seclen; |
270 | sec->crc_val = ~0; | 281 | sec->crc_val = ~0; |
271 | /* dump [secbuf .. secbuf+seclen) */ | 282 | /* dump [secbuf .. secbuf+seclen) */ |
272 | if (feed->pusi_seen) | 283 | if (feed->pusi_seen) { |
273 | dvb_dmx_swfilter_section_feed(feed); | 284 | dvb_dmx_swfilter_section_feed(feed); |
274 | #ifdef CONFIG_DVB_DEMUX_SECTION_LOSS_LOG | 285 | } else { |
275 | else | 286 | set_buf_flags(feed, |
276 | dprintk("pusi not seen, discarding section data\n"); | 287 | DMX_BUFFER_FLAG_DISCONTINUITY_DETECTED); |
277 | #endif | 288 | dprintk_sect_loss("pusi not seen, discarding section data\n"); |
289 | } | ||
278 | sec->secbufp += seclen; /* secbufp and secbuf moving together is */ | 290 | sec->secbufp += seclen; /* secbufp and secbuf moving together is */ |
279 | sec->secbuf += seclen; /* redundant but saves pointer arithmetic */ | 291 | sec->secbuf += seclen; /* redundant but saves pointer arithmetic */ |
280 | } | 292 | } |
@@ -307,18 +319,22 @@ static int dvb_dmx_swfilter_section_packet(struct dvb_demux_feed *feed, | |||
307 | } | 319 | } |
308 | 320 | ||
309 | if (!ccok || dc_i) { | 321 | if (!ccok || dc_i) { |
310 | #ifdef CONFIG_DVB_DEMUX_SECTION_LOSS_LOG | 322 | if (dc_i) { |
311 | if (dc_i) | 323 | set_buf_flags(feed, |
312 | dprintk("%d frame with disconnect indicator\n", | 324 | DMX_BUFFER_FLAG_DISCONTINUITY_INDICATOR); |
325 | dprintk_sect_loss("%d frame with disconnect indicator\n", | ||
313 | cc); | 326 | cc); |
314 | else | 327 | } else { |
315 | dprintk("discontinuity: %d instead of %d. %d bytes lost\n", | 328 | set_buf_flags(feed, |
329 | DMX_BUFFER_FLAG_DISCONTINUITY_DETECTED); | ||
330 | dprintk_sect_loss("discontinuity: %d instead of %d. %d bytes lost\n", | ||
316 | cc, (feed->cc + 1) & 0x0f, count + 4); | 331 | cc, (feed->cc + 1) & 0x0f, count + 4); |
332 | } | ||
317 | /* | 333 | /* |
318 | * those bytes under sume circumstances will again be reported | 334 | * those bytes under some circumstances will again be reported |
319 | * in the following dvb_dmx_swfilter_section_new | 335 | * in the following dvb_dmx_swfilter_section_new |
320 | */ | 336 | */ |
321 | #endif | 337 | |
322 | /* | 338 | /* |
323 | * Discontinuity detected. Reset pusi_seen to | 339 | * Discontinuity detected. Reset pusi_seen to |
324 | * stop feeding of suspicious data until next PUSI=1 arrives | 340 | * stop feeding of suspicious data until next PUSI=1 arrives |
@@ -326,6 +342,7 @@ static int dvb_dmx_swfilter_section_packet(struct dvb_demux_feed *feed, | |||
326 | * FIXME: does it make sense if the MPEG-TS is the one | 342 | * FIXME: does it make sense if the MPEG-TS is the one |
327 | * reporting discontinuity? | 343 | * reporting discontinuity? |
328 | */ | 344 | */ |
345 | |||
329 | feed->pusi_seen = false; | 346 | feed->pusi_seen = false; |
330 | dvb_dmx_swfilter_section_new(feed); | 347 | dvb_dmx_swfilter_section_new(feed); |
331 | } | 348 | } |
@@ -345,11 +362,11 @@ static int dvb_dmx_swfilter_section_packet(struct dvb_demux_feed *feed, | |||
345 | dvb_dmx_swfilter_section_new(feed); | 362 | dvb_dmx_swfilter_section_new(feed); |
346 | dvb_dmx_swfilter_section_copy_dump(feed, after, | 363 | dvb_dmx_swfilter_section_copy_dump(feed, after, |
347 | after_len); | 364 | after_len); |
365 | } else if (count > 0) { | ||
366 | set_buf_flags(feed, | ||
367 | DMX_BUFFER_FLAG_DISCONTINUITY_DETECTED); | ||
368 | dprintk_sect_loss("PUSI=1 but %d bytes lost\n", count); | ||
348 | } | 369 | } |
349 | #ifdef CONFIG_DVB_DEMUX_SECTION_LOSS_LOG | ||
350 | else if (count > 0) | ||
351 | dprintk("PUSI=1 but %d bytes lost\n", count); | ||
352 | #endif | ||
353 | } else { | 370 | } else { |
354 | /* PUSI=0 (is not set), no section boundary */ | 371 | /* PUSI=0 (is not set), no section boundary */ |
355 | dvb_dmx_swfilter_section_copy_dump(feed, &buf[p], count); | 372 | dvb_dmx_swfilter_section_copy_dump(feed, &buf[p], count); |
@@ -369,7 +386,8 @@ static inline void dvb_dmx_swfilter_packet_type(struct dvb_demux_feed *feed, | |||
369 | if (feed->ts_type & TS_PAYLOAD_ONLY) | 386 | if (feed->ts_type & TS_PAYLOAD_ONLY) |
370 | dvb_dmx_swfilter_payload(feed, buf); | 387 | dvb_dmx_swfilter_payload(feed, buf); |
371 | else | 388 | else |
372 | feed->cb.ts(buf, 188, NULL, 0, &feed->feed.ts); | 389 | feed->cb.ts(buf, 188, NULL, 0, &feed->feed.ts, |
390 | &feed->buffer_flags); | ||
373 | } | 391 | } |
374 | /* Used only on full-featured devices */ | 392 | /* Used only on full-featured devices */ |
375 | if (feed->ts_type & TS_DECODER) | 393 | if (feed->ts_type & TS_DECODER) |
@@ -430,6 +448,11 @@ static void dvb_dmx_swfilter_packet(struct dvb_demux *demux, const u8 *buf) | |||
430 | } | 448 | } |
431 | 449 | ||
432 | if (buf[1] & 0x80) { | 450 | if (buf[1] & 0x80) { |
451 | list_for_each_entry(feed, &demux->feed_list, list_head) { | ||
452 | if ((feed->pid != pid) && (feed->pid != 0x2000)) | ||
453 | continue; | ||
454 | set_buf_flags(feed, DMX_BUFFER_FLAG_TEI); | ||
455 | } | ||
433 | dprintk_tscheck("TEI detected. PID=0x%x data1=0x%x\n", | 456 | dprintk_tscheck("TEI detected. PID=0x%x data1=0x%x\n", |
434 | pid, buf[1]); | 457 | pid, buf[1]); |
435 | /* data in this packet can't be trusted - drop it unless | 458 | /* data in this packet can't be trusted - drop it unless |
@@ -445,6 +468,13 @@ static void dvb_dmx_swfilter_packet(struct dvb_demux *demux, const u8 *buf) | |||
445 | (demux->cnt_storage[pid] + 1) & 0xf; | 468 | (demux->cnt_storage[pid] + 1) & 0xf; |
446 | 469 | ||
447 | if ((buf[3] & 0xf) != demux->cnt_storage[pid]) { | 470 | if ((buf[3] & 0xf) != demux->cnt_storage[pid]) { |
471 | list_for_each_entry(feed, &demux->feed_list, list_head) { | ||
472 | if ((feed->pid != pid) && (feed->pid != 0x2000)) | ||
473 | continue; | ||
474 | set_buf_flags(feed, | ||
475 | DMX_BUFFER_PKT_COUNTER_MISMATCH); | ||
476 | } | ||
477 | |||
448 | dprintk_tscheck("TS packet counter mismatch. PID=0x%x expected 0x%x got 0x%x\n", | 478 | dprintk_tscheck("TS packet counter mismatch. PID=0x%x expected 0x%x got 0x%x\n", |
449 | pid, demux->cnt_storage[pid], | 479 | pid, demux->cnt_storage[pid], |
450 | buf[3] & 0xf); | 480 | buf[3] & 0xf); |
@@ -466,7 +496,8 @@ static void dvb_dmx_swfilter_packet(struct dvb_demux *demux, const u8 *buf) | |||
466 | if (feed->pid == pid) | 496 | if (feed->pid == pid) |
467 | dvb_dmx_swfilter_packet_type(feed, buf); | 497 | dvb_dmx_swfilter_packet_type(feed, buf); |
468 | else if (feed->pid == 0x2000) | 498 | else if (feed->pid == 0x2000) |
469 | feed->cb.ts(buf, 188, NULL, 0, &feed->feed.ts); | 499 | feed->cb.ts(buf, 188, NULL, 0, &feed->feed.ts, |
500 | &feed->buffer_flags); | ||
470 | } | 501 | } |
471 | } | 502 | } |
472 | 503 | ||
@@ -585,7 +616,8 @@ void dvb_dmx_swfilter_raw(struct dvb_demux *demux, const u8 *buf, size_t count) | |||
585 | 616 | ||
586 | spin_lock_irqsave(&demux->lock, flags); | 617 | spin_lock_irqsave(&demux->lock, flags); |
587 | 618 | ||
588 | demux->feed->cb.ts(buf, count, NULL, 0, &demux->feed->feed.ts); | 619 | demux->feed->cb.ts(buf, count, NULL, 0, &demux->feed->feed.ts, |
620 | &demux->feed->buffer_flags); | ||
589 | 621 | ||
590 | spin_unlock_irqrestore(&demux->lock, flags); | 622 | spin_unlock_irqrestore(&demux->lock, flags); |
591 | } | 623 | } |
@@ -785,6 +817,7 @@ static int dvbdmx_allocate_ts_feed(struct dmx_demux *dmx, | |||
785 | feed->demux = demux; | 817 | feed->demux = demux; |
786 | feed->pid = 0xffff; | 818 | feed->pid = 0xffff; |
787 | feed->peslen = 0xfffa; | 819 | feed->peslen = 0xfffa; |
820 | feed->buffer_flags = 0; | ||
788 | 821 | ||
789 | (*ts_feed) = &feed->feed.ts; | 822 | (*ts_feed) = &feed->feed.ts; |
790 | (*ts_feed)->parent = dmx; | 823 | (*ts_feed)->parent = dmx; |
@@ -1042,6 +1075,7 @@ static int dvbdmx_allocate_section_feed(struct dmx_demux *demux, | |||
1042 | dvbdmxfeed->cb.sec = callback; | 1075 | dvbdmxfeed->cb.sec = callback; |
1043 | dvbdmxfeed->demux = dvbdmx; | 1076 | dvbdmxfeed->demux = dvbdmx; |
1044 | dvbdmxfeed->pid = 0xffff; | 1077 | dvbdmxfeed->pid = 0xffff; |
1078 | dvbdmxfeed->buffer_flags = 0; | ||
1045 | dvbdmxfeed->feed.sec.secbuf = dvbdmxfeed->feed.sec.secbuf_base; | 1079 | dvbdmxfeed->feed.sec.secbuf = dvbdmxfeed->feed.sec.secbuf_base; |
1046 | dvbdmxfeed->feed.sec.secbufp = dvbdmxfeed->feed.sec.seclen = 0; | 1080 | dvbdmxfeed->feed.sec.secbufp = dvbdmxfeed->feed.sec.seclen = 0; |
1047 | dvbdmxfeed->feed.sec.tsfeedp = 0; | 1081 | dvbdmxfeed->feed.sec.tsfeedp = 0; |
diff --git a/drivers/media/dvb-core/dvb_net.c b/drivers/media/dvb-core/dvb_net.c index b6c7eec863b9..ba39f9942e1d 100644 --- a/drivers/media/dvb-core/dvb_net.c +++ b/drivers/media/dvb-core/dvb_net.c | |||
@@ -883,7 +883,8 @@ static void dvb_net_ule(struct net_device *dev, const u8 *buf, size_t buf_len) | |||
883 | 883 | ||
884 | static int dvb_net_ts_callback(const u8 *buffer1, size_t buffer1_len, | 884 | static int dvb_net_ts_callback(const u8 *buffer1, size_t buffer1_len, |
885 | const u8 *buffer2, size_t buffer2_len, | 885 | const u8 *buffer2, size_t buffer2_len, |
886 | struct dmx_ts_feed *feed) | 886 | struct dmx_ts_feed *feed, |
887 | u32 *buffer_flags) | ||
887 | { | 888 | { |
888 | struct net_device *dev = feed->priv; | 889 | struct net_device *dev = feed->priv; |
889 | 890 | ||
@@ -992,7 +993,7 @@ static void dvb_net_sec(struct net_device *dev, | |||
992 | 993 | ||
993 | static int dvb_net_sec_callback(const u8 *buffer1, size_t buffer1_len, | 994 | static int dvb_net_sec_callback(const u8 *buffer1, size_t buffer1_len, |
994 | const u8 *buffer2, size_t buffer2_len, | 995 | const u8 *buffer2, size_t buffer2_len, |
995 | struct dmx_section_filter *filter) | 996 | struct dmx_section_filter *filter, u32 *buffer_flags) |
996 | { | 997 | { |
997 | struct net_device *dev = filter->priv; | 998 | struct net_device *dev = filter->priv; |
998 | 999 | ||
diff --git a/drivers/media/dvb-core/dvb_vb2.c b/drivers/media/dvb-core/dvb_vb2.c index 763145d74e83..b811adf88afa 100644 --- a/drivers/media/dvb-core/dvb_vb2.c +++ b/drivers/media/dvb-core/dvb_vb2.c | |||
@@ -256,7 +256,8 @@ int dvb_vb2_is_streaming(struct dvb_vb2_ctx *ctx) | |||
256 | } | 256 | } |
257 | 257 | ||
258 | int dvb_vb2_fill_buffer(struct dvb_vb2_ctx *ctx, | 258 | int dvb_vb2_fill_buffer(struct dvb_vb2_ctx *ctx, |
259 | const unsigned char *src, int len) | 259 | const unsigned char *src, int len, |
260 | enum dmx_buffer_flags *buffer_flags) | ||
260 | { | 261 | { |
261 | unsigned long flags = 0; | 262 | unsigned long flags = 0; |
262 | void *vbuf = NULL; | 263 | void *vbuf = NULL; |
@@ -264,15 +265,17 @@ int dvb_vb2_fill_buffer(struct dvb_vb2_ctx *ctx, | |||
264 | unsigned char *psrc = (unsigned char *)src; | 265 | unsigned char *psrc = (unsigned char *)src; |
265 | int ll = 0; | 266 | int ll = 0; |
266 | 267 | ||
267 | dprintk(3, "[%s] %d bytes are rcvd\n", ctx->name, len); | 268 | /* |
268 | if (!src) { | 269 | * normal case: This func is called twice from demux driver |
269 | dprintk(3, "[%s]:NULL pointer src\n", ctx->name); | 270 | * one with valid src pointer, second time with NULL pointer |
270 | /**normal case: This func is called twice from demux driver | 271 | */ |
271 | * once with valid src pointer, second time with NULL pointer | 272 | if (!src || !len) |
272 | */ | ||
273 | return 0; | 273 | return 0; |
274 | } | ||
275 | spin_lock_irqsave(&ctx->slock, flags); | 274 | spin_lock_irqsave(&ctx->slock, flags); |
275 | if (buffer_flags && *buffer_flags) { | ||
276 | ctx->flags |= *buffer_flags; | ||
277 | *buffer_flags = 0; | ||
278 | } | ||
276 | while (todo) { | 279 | while (todo) { |
277 | if (!ctx->buf) { | 280 | if (!ctx->buf) { |
278 | if (list_empty(&ctx->dvb_q)) { | 281 | if (list_empty(&ctx->dvb_q)) { |
@@ -395,6 +398,7 @@ int dvb_vb2_qbuf(struct dvb_vb2_ctx *ctx, struct dmx_buffer *b) | |||
395 | 398 | ||
396 | int dvb_vb2_dqbuf(struct dvb_vb2_ctx *ctx, struct dmx_buffer *b) | 399 | int dvb_vb2_dqbuf(struct dvb_vb2_ctx *ctx, struct dmx_buffer *b) |
397 | { | 400 | { |
401 | unsigned long flags; | ||
398 | int ret; | 402 | int ret; |
399 | 403 | ||
400 | ret = vb2_core_dqbuf(&ctx->vb_q, &b->index, b, ctx->nonblocking); | 404 | ret = vb2_core_dqbuf(&ctx->vb_q, &b->index, b, ctx->nonblocking); |
@@ -402,7 +406,16 @@ int dvb_vb2_dqbuf(struct dvb_vb2_ctx *ctx, struct dmx_buffer *b) | |||
402 | dprintk(1, "[%s] errno=%d\n", ctx->name, ret); | 406 | dprintk(1, "[%s] errno=%d\n", ctx->name, ret); |
403 | return ret; | 407 | return ret; |
404 | } | 408 | } |
405 | dprintk(5, "[%s] index=%d\n", ctx->name, b->index); | 409 | |
410 | spin_lock_irqsave(&ctx->slock, flags); | ||
411 | b->count = ctx->count++; | ||
412 | b->flags = ctx->flags; | ||
413 | ctx->flags = 0; | ||
414 | spin_unlock_irqrestore(&ctx->slock, flags); | ||
415 | |||
416 | dprintk(5, "[%s] index=%d, count=%d, flags=%d\n", | ||
417 | ctx->name, b->index, ctx->count, b->flags); | ||
418 | |||
406 | 419 | ||
407 | return 0; | 420 | return 0; |
408 | } | 421 | } |
diff --git a/drivers/media/dvb-frontends/m88ds3103.c b/drivers/media/dvb-frontends/m88ds3103.c index 50bce68ffd66..65d157fe76d1 100644 --- a/drivers/media/dvb-frontends/m88ds3103.c +++ b/drivers/media/dvb-frontends/m88ds3103.c | |||
@@ -1262,11 +1262,12 @@ static int m88ds3103_select(struct i2c_mux_core *muxc, u32 chan) | |||
1262 | * New users must use I2C client binding directly! | 1262 | * New users must use I2C client binding directly! |
1263 | */ | 1263 | */ |
1264 | struct dvb_frontend *m88ds3103_attach(const struct m88ds3103_config *cfg, | 1264 | struct dvb_frontend *m88ds3103_attach(const struct m88ds3103_config *cfg, |
1265 | struct i2c_adapter *i2c, struct i2c_adapter **tuner_i2c_adapter) | 1265 | struct i2c_adapter *i2c, |
1266 | struct i2c_adapter **tuner_i2c_adapter) | ||
1266 | { | 1267 | { |
1267 | struct i2c_client *client; | 1268 | struct i2c_client *client; |
1268 | struct i2c_board_info board_info; | 1269 | struct i2c_board_info board_info; |
1269 | struct m88ds3103_platform_data pdata; | 1270 | struct m88ds3103_platform_data pdata = {}; |
1270 | 1271 | ||
1271 | pdata.clk = cfg->clock; | 1272 | pdata.clk = cfg->clock; |
1272 | pdata.i2c_wr_max = cfg->i2c_wr_max; | 1273 | pdata.i2c_wr_max = cfg->i2c_wr_max; |
@@ -1409,6 +1410,8 @@ static int m88ds3103_probe(struct i2c_client *client, | |||
1409 | case M88DS3103_CHIP_ID: | 1410 | case M88DS3103_CHIP_ID: |
1410 | break; | 1411 | break; |
1411 | default: | 1412 | default: |
1413 | ret = -ENODEV; | ||
1414 | dev_err(&client->dev, "Unknown device. Chip_id=%02x\n", dev->chip_id); | ||
1412 | goto err_kfree; | 1415 | goto err_kfree; |
1413 | } | 1416 | } |
1414 | 1417 | ||
diff --git a/drivers/media/i2c/tvp5150.c b/drivers/media/i2c/tvp5150.c index 3c1851984b90..2476d812f669 100644 --- a/drivers/media/i2c/tvp5150.c +++ b/drivers/media/i2c/tvp5150.c | |||
@@ -505,80 +505,77 @@ static struct i2c_vbi_ram_value vbi_ram_default[] = | |||
505 | /* FIXME: Current api doesn't handle all VBI types, those not | 505 | /* FIXME: Current api doesn't handle all VBI types, those not |
506 | yet supported are placed under #if 0 */ | 506 | yet supported are placed under #if 0 */ |
507 | #if 0 | 507 | #if 0 |
508 | {0x010, /* Teletext, SECAM, WST System A */ | 508 | [0] = {0x010, /* Teletext, SECAM, WST System A */ |
509 | {V4L2_SLICED_TELETEXT_SECAM,6,23,1}, | 509 | {V4L2_SLICED_TELETEXT_SECAM,6,23,1}, |
510 | { 0xaa, 0xaa, 0xff, 0xff, 0xe7, 0x2e, 0x20, 0x26, | 510 | { 0xaa, 0xaa, 0xff, 0xff, 0xe7, 0x2e, 0x20, 0x26, |
511 | 0xe6, 0xb4, 0x0e, 0x00, 0x00, 0x00, 0x10, 0x00 } | 511 | 0xe6, 0xb4, 0x0e, 0x00, 0x00, 0x00, 0x10, 0x00 } |
512 | }, | 512 | }, |
513 | #endif | 513 | #endif |
514 | {0x030, /* Teletext, PAL, WST System B */ | 514 | [1] = {0x030, /* Teletext, PAL, WST System B */ |
515 | {V4L2_SLICED_TELETEXT_B,6,22,1}, | 515 | {V4L2_SLICED_TELETEXT_B,6,22,1}, |
516 | { 0xaa, 0xaa, 0xff, 0xff, 0x27, 0x2e, 0x20, 0x2b, | 516 | { 0xaa, 0xaa, 0xff, 0xff, 0x27, 0x2e, 0x20, 0x2b, |
517 | 0xa6, 0x72, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00 } | 517 | 0xa6, 0x72, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00 } |
518 | }, | 518 | }, |
519 | #if 0 | 519 | #if 0 |
520 | {0x050, /* Teletext, PAL, WST System C */ | 520 | [2] = {0x050, /* Teletext, PAL, WST System C */ |
521 | {V4L2_SLICED_TELETEXT_PAL_C,6,22,1}, | 521 | {V4L2_SLICED_TELETEXT_PAL_C,6,22,1}, |
522 | { 0xaa, 0xaa, 0xff, 0xff, 0xe7, 0x2e, 0x20, 0x22, | 522 | { 0xaa, 0xaa, 0xff, 0xff, 0xe7, 0x2e, 0x20, 0x22, |
523 | 0xa6, 0x98, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x00 } | 523 | 0xa6, 0x98, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x00 } |
524 | }, | 524 | }, |
525 | {0x070, /* Teletext, NTSC, WST System B */ | 525 | [3] = {0x070, /* Teletext, NTSC, WST System B */ |
526 | {V4L2_SLICED_TELETEXT_NTSC_B,10,21,1}, | 526 | {V4L2_SLICED_TELETEXT_NTSC_B,10,21,1}, |
527 | { 0xaa, 0xaa, 0xff, 0xff, 0x27, 0x2e, 0x20, 0x23, | 527 | { 0xaa, 0xaa, 0xff, 0xff, 0x27, 0x2e, 0x20, 0x23, |
528 | 0x69, 0x93, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x00 } | 528 | 0x69, 0x93, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x00 } |
529 | }, | 529 | }, |
530 | {0x090, /* Tetetext, NTSC NABTS System C */ | 530 | [4] = {0x090, /* Tetetext, NTSC NABTS System C */ |
531 | {V4L2_SLICED_TELETEXT_NTSC_C,10,21,1}, | 531 | {V4L2_SLICED_TELETEXT_NTSC_C,10,21,1}, |
532 | { 0xaa, 0xaa, 0xff, 0xff, 0xe7, 0x2e, 0x20, 0x22, | 532 | { 0xaa, 0xaa, 0xff, 0xff, 0xe7, 0x2e, 0x20, 0x22, |
533 | 0x69, 0x93, 0x0d, 0x00, 0x00, 0x00, 0x15, 0x00 } | 533 | 0x69, 0x93, 0x0d, 0x00, 0x00, 0x00, 0x15, 0x00 } |
534 | }, | 534 | }, |
535 | {0x0b0, /* Teletext, NTSC-J, NABTS System D */ | 535 | [5] = {0x0b0, /* Teletext, NTSC-J, NABTS System D */ |
536 | {V4L2_SLICED_TELETEXT_NTSC_D,10,21,1}, | 536 | {V4L2_SLICED_TELETEXT_NTSC_D,10,21,1}, |
537 | { 0xaa, 0xaa, 0xff, 0xff, 0xa7, 0x2e, 0x20, 0x23, | 537 | { 0xaa, 0xaa, 0xff, 0xff, 0xa7, 0x2e, 0x20, 0x23, |
538 | 0x69, 0x93, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x00 } | 538 | 0x69, 0x93, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x00 } |
539 | }, | 539 | }, |
540 | {0x0d0, /* Closed Caption, PAL/SECAM */ | 540 | [6] = {0x0d0, /* Closed Caption, PAL/SECAM */ |
541 | {V4L2_SLICED_CAPTION_625,22,22,1}, | 541 | {V4L2_SLICED_CAPTION_625,22,22,1}, |
542 | { 0xaa, 0x2a, 0xff, 0x3f, 0x04, 0x51, 0x6e, 0x02, | 542 | { 0xaa, 0x2a, 0xff, 0x3f, 0x04, 0x51, 0x6e, 0x02, |
543 | 0xa6, 0x7b, 0x09, 0x00, 0x00, 0x00, 0x27, 0x00 } | 543 | 0xa6, 0x7b, 0x09, 0x00, 0x00, 0x00, 0x27, 0x00 } |
544 | }, | 544 | }, |
545 | #endif | 545 | #endif |
546 | {0x0f0, /* Closed Caption, NTSC */ | 546 | [7] = {0x0f0, /* Closed Caption, NTSC */ |
547 | {V4L2_SLICED_CAPTION_525,21,21,1}, | 547 | {V4L2_SLICED_CAPTION_525,21,21,1}, |
548 | { 0xaa, 0x2a, 0xff, 0x3f, 0x04, 0x51, 0x6e, 0x02, | 548 | { 0xaa, 0x2a, 0xff, 0x3f, 0x04, 0x51, 0x6e, 0x02, |
549 | 0x69, 0x8c, 0x09, 0x00, 0x00, 0x00, 0x27, 0x00 } | 549 | 0x69, 0x8c, 0x09, 0x00, 0x00, 0x00, 0x27, 0x00 } |
550 | }, | 550 | }, |
551 | {0x110, /* Wide Screen Signal, PAL/SECAM */ | 551 | [8] = {0x110, /* Wide Screen Signal, PAL/SECAM */ |
552 | {V4L2_SLICED_WSS_625,23,23,1}, | 552 | {V4L2_SLICED_WSS_625,23,23,1}, |
553 | { 0x5b, 0x55, 0xc5, 0xff, 0x00, 0x71, 0x6e, 0x42, | 553 | { 0x5b, 0x55, 0xc5, 0xff, 0x00, 0x71, 0x6e, 0x42, |
554 | 0xa6, 0xcd, 0x0f, 0x00, 0x00, 0x00, 0x3a, 0x00 } | 554 | 0xa6, 0xcd, 0x0f, 0x00, 0x00, 0x00, 0x3a, 0x00 } |
555 | }, | 555 | }, |
556 | #if 0 | 556 | #if 0 |
557 | {0x130, /* Wide Screen Signal, NTSC C */ | 557 | [9] = {0x130, /* Wide Screen Signal, NTSC C */ |
558 | {V4L2_SLICED_WSS_525,20,20,1}, | 558 | {V4L2_SLICED_WSS_525,20,20,1}, |
559 | { 0x38, 0x00, 0x3f, 0x00, 0x00, 0x71, 0x6e, 0x43, | 559 | { 0x38, 0x00, 0x3f, 0x00, 0x00, 0x71, 0x6e, 0x43, |
560 | 0x69, 0x7c, 0x08, 0x00, 0x00, 0x00, 0x39, 0x00 } | 560 | 0x69, 0x7c, 0x08, 0x00, 0x00, 0x00, 0x39, 0x00 } |
561 | }, | 561 | }, |
562 | {0x150, /* Vertical Interval Timecode (VITC), PAL/SECAM */ | 562 | [10] = {0x150, /* Vertical Interval Timecode (VITC), PAL/SECAM */ |
563 | {V4l2_SLICED_VITC_625,6,22,0}, | 563 | {V4l2_SLICED_VITC_625,6,22,0}, |
564 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f, 0x6d, 0x49, | 564 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f, 0x6d, 0x49, |
565 | 0xa6, 0x85, 0x08, 0x00, 0x00, 0x00, 0x4c, 0x00 } | 565 | 0xa6, 0x85, 0x08, 0x00, 0x00, 0x00, 0x4c, 0x00 } |
566 | }, | 566 | }, |
567 | {0x170, /* Vertical Interval Timecode (VITC), NTSC */ | 567 | [11] = {0x170, /* Vertical Interval Timecode (VITC), NTSC */ |
568 | {V4l2_SLICED_VITC_525,10,20,0}, | 568 | {V4l2_SLICED_VITC_525,10,20,0}, |
569 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f, 0x6d, 0x49, | 569 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f, 0x6d, 0x49, |
570 | 0x69, 0x94, 0x08, 0x00, 0x00, 0x00, 0x4c, 0x00 } | 570 | 0x69, 0x94, 0x08, 0x00, 0x00, 0x00, 0x4c, 0x00 } |
571 | }, | 571 | }, |
572 | #endif | 572 | #endif |
573 | {0x190, /* Video Program System (VPS), PAL */ | 573 | [12] = {0x190, /* Video Program System (VPS), PAL */ |
574 | {V4L2_SLICED_VPS,16,16,0}, | 574 | {V4L2_SLICED_VPS,16,16,0}, |
575 | { 0xaa, 0xaa, 0xff, 0xff, 0xba, 0xce, 0x2b, 0x0d, | 575 | { 0xaa, 0xaa, 0xff, 0xff, 0xba, 0xce, 0x2b, 0x0d, |
576 | 0xa6, 0xda, 0x0b, 0x00, 0x00, 0x00, 0x60, 0x00 } | 576 | 0xa6, 0xda, 0x0b, 0x00, 0x00, 0x00, 0x60, 0x00 } |
577 | }, | 577 | }, |
578 | /* 0x1d0 User programmable */ | 578 | /* 0x1d0 User programmable */ |
579 | |||
580 | /* End of struct */ | ||
581 | { (u16)-1 } | ||
582 | }; | 579 | }; |
583 | 580 | ||
584 | static int tvp5150_write_inittab(struct v4l2_subdev *sd, | 581 | static int tvp5150_write_inittab(struct v4l2_subdev *sd, |
@@ -591,10 +588,10 @@ static int tvp5150_write_inittab(struct v4l2_subdev *sd, | |||
591 | return 0; | 588 | return 0; |
592 | } | 589 | } |
593 | 590 | ||
594 | static int tvp5150_vdp_init(struct v4l2_subdev *sd, | 591 | static int tvp5150_vdp_init(struct v4l2_subdev *sd) |
595 | const struct i2c_vbi_ram_value *regs) | ||
596 | { | 592 | { |
597 | unsigned int i; | 593 | unsigned int i; |
594 | int j; | ||
598 | 595 | ||
599 | /* Disable Full Field */ | 596 | /* Disable Full Field */ |
600 | tvp5150_write(sd, TVP5150_FULL_FIELD_ENA, 0); | 597 | tvp5150_write(sd, TVP5150_FULL_FIELD_ENA, 0); |
@@ -604,14 +601,17 @@ static int tvp5150_vdp_init(struct v4l2_subdev *sd, | |||
604 | tvp5150_write(sd, i, 0xff); | 601 | tvp5150_write(sd, i, 0xff); |
605 | 602 | ||
606 | /* Load Ram Table */ | 603 | /* Load Ram Table */ |
607 | while (regs->reg != (u16)-1) { | 604 | for (j = 0; j < ARRAY_SIZE(vbi_ram_default); j++) { |
605 | const struct i2c_vbi_ram_value *regs = &vbi_ram_default[j]; | ||
606 | |||
607 | if (!regs->type.vbi_type) | ||
608 | continue; | ||
609 | |||
608 | tvp5150_write(sd, TVP5150_CONF_RAM_ADDR_HIGH, regs->reg >> 8); | 610 | tvp5150_write(sd, TVP5150_CONF_RAM_ADDR_HIGH, regs->reg >> 8); |
609 | tvp5150_write(sd, TVP5150_CONF_RAM_ADDR_LOW, regs->reg); | 611 | tvp5150_write(sd, TVP5150_CONF_RAM_ADDR_LOW, regs->reg); |
610 | 612 | ||
611 | for (i = 0; i < 16; i++) | 613 | for (i = 0; i < 16; i++) |
612 | tvp5150_write(sd, TVP5150_VDP_CONF_RAM_DATA, regs->values[i]); | 614 | tvp5150_write(sd, TVP5150_VDP_CONF_RAM_DATA, regs->values[i]); |
613 | |||
614 | regs++; | ||
615 | } | 615 | } |
616 | return 0; | 616 | return 0; |
617 | } | 617 | } |
@@ -620,19 +620,23 @@ static int tvp5150_vdp_init(struct v4l2_subdev *sd, | |||
620 | static int tvp5150_g_sliced_vbi_cap(struct v4l2_subdev *sd, | 620 | static int tvp5150_g_sliced_vbi_cap(struct v4l2_subdev *sd, |
621 | struct v4l2_sliced_vbi_cap *cap) | 621 | struct v4l2_sliced_vbi_cap *cap) |
622 | { | 622 | { |
623 | const struct i2c_vbi_ram_value *regs = vbi_ram_default; | 623 | int line, i; |
624 | int line; | ||
625 | 624 | ||
626 | dev_dbg_lvl(sd->dev, 1, debug, "g_sliced_vbi_cap\n"); | 625 | dev_dbg_lvl(sd->dev, 1, debug, "g_sliced_vbi_cap\n"); |
627 | memset(cap, 0, sizeof *cap); | 626 | memset(cap, 0, sizeof *cap); |
628 | 627 | ||
629 | while (regs->reg != (u16)-1 ) { | 628 | for (i = 0; i < ARRAY_SIZE(vbi_ram_default); i++) { |
630 | for (line=regs->type.ini_line;line<=regs->type.end_line;line++) { | 629 | const struct i2c_vbi_ram_value *regs = &vbi_ram_default[i]; |
630 | |||
631 | if (!regs->type.vbi_type) | ||
632 | continue; | ||
633 | |||
634 | for (line = regs->type.ini_line; | ||
635 | line <= regs->type.end_line; | ||
636 | line++) { | ||
631 | cap->service_lines[0][line] |= regs->type.vbi_type; | 637 | cap->service_lines[0][line] |= regs->type.vbi_type; |
632 | } | 638 | } |
633 | cap->service_set |= regs->type.vbi_type; | 639 | cap->service_set |= regs->type.vbi_type; |
634 | |||
635 | regs++; | ||
636 | } | 640 | } |
637 | return 0; | 641 | return 0; |
638 | } | 642 | } |
@@ -651,14 +655,13 @@ static int tvp5150_g_sliced_vbi_cap(struct v4l2_subdev *sd, | |||
651 | * MSB = field2 | 655 | * MSB = field2 |
652 | */ | 656 | */ |
653 | static int tvp5150_set_vbi(struct v4l2_subdev *sd, | 657 | static int tvp5150_set_vbi(struct v4l2_subdev *sd, |
654 | const struct i2c_vbi_ram_value *regs, | ||
655 | unsigned int type,u8 flags, int line, | 658 | unsigned int type,u8 flags, int line, |
656 | const int fields) | 659 | const int fields) |
657 | { | 660 | { |
658 | struct tvp5150 *decoder = to_tvp5150(sd); | 661 | struct tvp5150 *decoder = to_tvp5150(sd); |
659 | v4l2_std_id std = decoder->norm; | 662 | v4l2_std_id std = decoder->norm; |
660 | u8 reg; | 663 | u8 reg; |
661 | int pos = 0; | 664 | int i, pos = 0; |
662 | 665 | ||
663 | if (std == V4L2_STD_ALL) { | 666 | if (std == V4L2_STD_ALL) { |
664 | dev_err(sd->dev, "VBI can't be configured without knowing number of lines\n"); | 667 | dev_err(sd->dev, "VBI can't be configured without knowing number of lines\n"); |
@@ -671,19 +674,19 @@ static int tvp5150_set_vbi(struct v4l2_subdev *sd, | |||
671 | if (line < 6 || line > 27) | 674 | if (line < 6 || line > 27) |
672 | return 0; | 675 | return 0; |
673 | 676 | ||
674 | while (regs->reg != (u16)-1) { | 677 | for (i = 0; i < ARRAY_SIZE(vbi_ram_default); i++) { |
678 | const struct i2c_vbi_ram_value *regs = &vbi_ram_default[i]; | ||
679 | |||
680 | if (!regs->type.vbi_type) | ||
681 | continue; | ||
682 | |||
675 | if ((type & regs->type.vbi_type) && | 683 | if ((type & regs->type.vbi_type) && |
676 | (line >= regs->type.ini_line) && | 684 | (line >= regs->type.ini_line) && |
677 | (line <= regs->type.end_line)) | 685 | (line <= regs->type.end_line)) |
678 | break; | 686 | break; |
679 | |||
680 | regs++; | ||
681 | pos++; | 687 | pos++; |
682 | } | 688 | } |
683 | 689 | ||
684 | if (regs->reg == (u16)-1) | ||
685 | return 0; | ||
686 | |||
687 | type = pos | (flags & 0xf0); | 690 | type = pos | (flags & 0xf0); |
688 | reg = ((line - 6) << 1) + TVP5150_LINE_MODE_INI; | 691 | reg = ((line - 6) << 1) + TVP5150_LINE_MODE_INI; |
689 | 692 | ||
@@ -696,8 +699,7 @@ static int tvp5150_set_vbi(struct v4l2_subdev *sd, | |||
696 | return type; | 699 | return type; |
697 | } | 700 | } |
698 | 701 | ||
699 | static int tvp5150_get_vbi(struct v4l2_subdev *sd, | 702 | static int tvp5150_get_vbi(struct v4l2_subdev *sd, int line) |
700 | const struct i2c_vbi_ram_value *regs, int line) | ||
701 | { | 703 | { |
702 | struct tvp5150 *decoder = to_tvp5150(sd); | 704 | struct tvp5150 *decoder = to_tvp5150(sd); |
703 | v4l2_std_id std = decoder->norm; | 705 | v4l2_std_id std = decoder->norm; |
@@ -726,8 +728,8 @@ static int tvp5150_get_vbi(struct v4l2_subdev *sd, | |||
726 | return 0; | 728 | return 0; |
727 | } | 729 | } |
728 | pos = ret & 0x0f; | 730 | pos = ret & 0x0f; |
729 | if (pos < 0x0f) | 731 | if (pos < ARRAY_SIZE(vbi_ram_default)) |
730 | type |= regs[pos].type.vbi_type; | 732 | type |= vbi_ram_default[pos].type.vbi_type; |
731 | } | 733 | } |
732 | 734 | ||
733 | return type; | 735 | return type; |
@@ -788,7 +790,7 @@ static int tvp5150_reset(struct v4l2_subdev *sd, u32 val) | |||
788 | tvp5150_write_inittab(sd, tvp5150_init_default); | 790 | tvp5150_write_inittab(sd, tvp5150_init_default); |
789 | 791 | ||
790 | /* Initializes VDP registers */ | 792 | /* Initializes VDP registers */ |
791 | tvp5150_vdp_init(sd, vbi_ram_default); | 793 | tvp5150_vdp_init(sd); |
792 | 794 | ||
793 | /* Selects decoder input */ | 795 | /* Selects decoder input */ |
794 | tvp5150_selmux(sd); | 796 | tvp5150_selmux(sd); |
@@ -1121,8 +1123,8 @@ static int tvp5150_s_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_f | |||
1121 | for (i = 0; i <= 23; i++) { | 1123 | for (i = 0; i <= 23; i++) { |
1122 | svbi->service_lines[1][i] = 0; | 1124 | svbi->service_lines[1][i] = 0; |
1123 | svbi->service_lines[0][i] = | 1125 | svbi->service_lines[0][i] = |
1124 | tvp5150_set_vbi(sd, vbi_ram_default, | 1126 | tvp5150_set_vbi(sd, svbi->service_lines[0][i], |
1125 | svbi->service_lines[0][i], 0xf0, i, 3); | 1127 | 0xf0, i, 3); |
1126 | } | 1128 | } |
1127 | /* Enables FIFO */ | 1129 | /* Enables FIFO */ |
1128 | tvp5150_write(sd, TVP5150_FIFO_OUT_CTRL, 1); | 1130 | tvp5150_write(sd, TVP5150_FIFO_OUT_CTRL, 1); |
@@ -1148,7 +1150,7 @@ static int tvp5150_g_sliced_fmt(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_f | |||
1148 | 1150 | ||
1149 | for (i = 0; i <= 23; i++) { | 1151 | for (i = 0; i <= 23; i++) { |
1150 | svbi->service_lines[0][i] = | 1152 | svbi->service_lines[0][i] = |
1151 | tvp5150_get_vbi(sd, vbi_ram_default, i); | 1153 | tvp5150_get_vbi(sd, i); |
1152 | mask |= svbi->service_lines[0][i]; | 1154 | mask |= svbi->service_lines[0][i]; |
1153 | } | 1155 | } |
1154 | svbi->service_set = mask; | 1156 | svbi->service_set = mask; |
diff --git a/drivers/media/pci/ttpci/av7110.c b/drivers/media/pci/ttpci/av7110.c index dc8e577b2f74..d6816effb878 100644 --- a/drivers/media/pci/ttpci/av7110.c +++ b/drivers/media/pci/ttpci/av7110.c | |||
@@ -324,14 +324,15 @@ static int DvbDmxFilterCallback(u8 *buffer1, size_t buffer1_len, | |||
324 | } | 324 | } |
325 | return dvbdmxfilter->feed->cb.sec(buffer1, buffer1_len, | 325 | return dvbdmxfilter->feed->cb.sec(buffer1, buffer1_len, |
326 | buffer2, buffer2_len, | 326 | buffer2, buffer2_len, |
327 | &dvbdmxfilter->filter); | 327 | &dvbdmxfilter->filter, NULL); |
328 | case DMX_TYPE_TS: | 328 | case DMX_TYPE_TS: |
329 | if (!(dvbdmxfilter->feed->ts_type & TS_PACKET)) | 329 | if (!(dvbdmxfilter->feed->ts_type & TS_PACKET)) |
330 | return 0; | 330 | return 0; |
331 | if (dvbdmxfilter->feed->ts_type & TS_PAYLOAD_ONLY) | 331 | if (dvbdmxfilter->feed->ts_type & TS_PAYLOAD_ONLY) |
332 | return dvbdmxfilter->feed->cb.ts(buffer1, buffer1_len, | 332 | return dvbdmxfilter->feed->cb.ts(buffer1, buffer1_len, |
333 | buffer2, buffer2_len, | 333 | buffer2, buffer2_len, |
334 | &dvbdmxfilter->feed->feed.ts); | 334 | &dvbdmxfilter->feed->feed.ts, |
335 | NULL); | ||
335 | else | 336 | else |
336 | av7110_p2t_write(buffer1, buffer1_len, | 337 | av7110_p2t_write(buffer1, buffer1_len, |
337 | dvbdmxfilter->feed->pid, | 338 | dvbdmxfilter->feed->pid, |
diff --git a/drivers/media/pci/ttpci/av7110_av.c b/drivers/media/pci/ttpci/av7110_av.c index 4daba76ec240..ef1bc17cdc4d 100644 --- a/drivers/media/pci/ttpci/av7110_av.c +++ b/drivers/media/pci/ttpci/av7110_av.c | |||
@@ -99,7 +99,7 @@ int av7110_record_cb(struct dvb_filter_pes2ts *p2t, u8 *buf, size_t len) | |||
99 | buf[4] = buf[5] = 0; | 99 | buf[4] = buf[5] = 0; |
100 | if (dvbdmxfeed->ts_type & TS_PAYLOAD_ONLY) | 100 | if (dvbdmxfeed->ts_type & TS_PAYLOAD_ONLY) |
101 | return dvbdmxfeed->cb.ts(buf, len, NULL, 0, | 101 | return dvbdmxfeed->cb.ts(buf, len, NULL, 0, |
102 | &dvbdmxfeed->feed.ts); | 102 | &dvbdmxfeed->feed.ts, NULL); |
103 | else | 103 | else |
104 | return dvb_filter_pes2ts(p2t, buf, len, 1); | 104 | return dvb_filter_pes2ts(p2t, buf, len, 1); |
105 | } | 105 | } |
@@ -109,7 +109,7 @@ static int dvb_filter_pes2ts_cb(void *priv, unsigned char *data) | |||
109 | struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *) priv; | 109 | struct dvb_demux_feed *dvbdmxfeed = (struct dvb_demux_feed *) priv; |
110 | 110 | ||
111 | dvbdmxfeed->cb.ts(data, 188, NULL, 0, | 111 | dvbdmxfeed->cb.ts(data, 188, NULL, 0, |
112 | &dvbdmxfeed->feed.ts); | 112 | &dvbdmxfeed->feed.ts, NULL); |
113 | return 0; | 113 | return 0; |
114 | } | 114 | } |
115 | 115 | ||
@@ -814,7 +814,7 @@ static void p_to_t(u8 const *buf, long int length, u16 pid, u8 *counter, | |||
814 | memcpy(obuf + l, buf + c, TS_SIZE - l); | 814 | memcpy(obuf + l, buf + c, TS_SIZE - l); |
815 | c = length; | 815 | c = length; |
816 | } | 816 | } |
817 | feed->cb.ts(obuf, 188, NULL, 0, &feed->feed.ts); | 817 | feed->cb.ts(obuf, 188, NULL, 0, &feed->feed.ts, NULL); |
818 | pes_start = 0; | 818 | pes_start = 0; |
819 | } | 819 | } |
820 | } | 820 | } |
diff --git a/drivers/media/usb/au0828/Kconfig b/drivers/media/usb/au0828/Kconfig index 70521e0b4c53..bfaa806633df 100644 --- a/drivers/media/usb/au0828/Kconfig +++ b/drivers/media/usb/au0828/Kconfig | |||
@@ -1,7 +1,7 @@ | |||
1 | 1 | ||
2 | config VIDEO_AU0828 | 2 | config VIDEO_AU0828 |
3 | tristate "Auvitek AU0828 support" | 3 | tristate "Auvitek AU0828 support" |
4 | depends on I2C && INPUT && DVB_CORE && USB | 4 | depends on I2C && INPUT && DVB_CORE && USB && VIDEO_V4L2 |
5 | select I2C_ALGOBIT | 5 | select I2C_ALGOBIT |
6 | select VIDEO_TVEEPROM | 6 | select VIDEO_TVEEPROM |
7 | select VIDEOBUF2_VMALLOC | 7 | select VIDEOBUF2_VMALLOC |
diff --git a/drivers/media/usb/ttusb-dec/ttusb_dec.c b/drivers/media/usb/ttusb-dec/ttusb_dec.c index a8900f5571f7..44ca66cb9b8f 100644 --- a/drivers/media/usb/ttusb-dec/ttusb_dec.c +++ b/drivers/media/usb/ttusb-dec/ttusb_dec.c | |||
@@ -428,7 +428,7 @@ static int ttusb_dec_audio_pes2ts_cb(void *priv, unsigned char *data) | |||
428 | struct ttusb_dec *dec = priv; | 428 | struct ttusb_dec *dec = priv; |
429 | 429 | ||
430 | dec->audio_filter->feed->cb.ts(data, 188, NULL, 0, | 430 | dec->audio_filter->feed->cb.ts(data, 188, NULL, 0, |
431 | &dec->audio_filter->feed->feed.ts); | 431 | &dec->audio_filter->feed->feed.ts, NULL); |
432 | 432 | ||
433 | return 0; | 433 | return 0; |
434 | } | 434 | } |
@@ -438,7 +438,7 @@ static int ttusb_dec_video_pes2ts_cb(void *priv, unsigned char *data) | |||
438 | struct ttusb_dec *dec = priv; | 438 | struct ttusb_dec *dec = priv; |
439 | 439 | ||
440 | dec->video_filter->feed->cb.ts(data, 188, NULL, 0, | 440 | dec->video_filter->feed->cb.ts(data, 188, NULL, 0, |
441 | &dec->video_filter->feed->feed.ts); | 441 | &dec->video_filter->feed->feed.ts, NULL); |
442 | 442 | ||
443 | return 0; | 443 | return 0; |
444 | } | 444 | } |
@@ -490,7 +490,7 @@ static void ttusb_dec_process_pva(struct ttusb_dec *dec, u8 *pva, int length) | |||
490 | 490 | ||
491 | if (output_pva) { | 491 | if (output_pva) { |
492 | dec->video_filter->feed->cb.ts(pva, length, NULL, 0, | 492 | dec->video_filter->feed->cb.ts(pva, length, NULL, 0, |
493 | &dec->video_filter->feed->feed.ts); | 493 | &dec->video_filter->feed->feed.ts, NULL); |
494 | return; | 494 | return; |
495 | } | 495 | } |
496 | 496 | ||
@@ -551,7 +551,7 @@ static void ttusb_dec_process_pva(struct ttusb_dec *dec, u8 *pva, int length) | |||
551 | case 0x02: /* MainAudioStream */ | 551 | case 0x02: /* MainAudioStream */ |
552 | if (output_pva) { | 552 | if (output_pva) { |
553 | dec->audio_filter->feed->cb.ts(pva, length, NULL, 0, | 553 | dec->audio_filter->feed->cb.ts(pva, length, NULL, 0, |
554 | &dec->audio_filter->feed->feed.ts); | 554 | &dec->audio_filter->feed->feed.ts, NULL); |
555 | return; | 555 | return; |
556 | } | 556 | } |
557 | 557 | ||
@@ -589,7 +589,7 @@ static void ttusb_dec_process_filter(struct ttusb_dec *dec, u8 *packet, | |||
589 | 589 | ||
590 | if (filter) | 590 | if (filter) |
591 | filter->feed->cb.sec(&packet[2], length - 2, NULL, 0, | 591 | filter->feed->cb.sec(&packet[2], length - 2, NULL, 0, |
592 | &filter->filter); | 592 | &filter->filter, NULL); |
593 | } | 593 | } |
594 | 594 | ||
595 | static void ttusb_dec_process_packet(struct ttusb_dec *dec) | 595 | static void ttusb_dec_process_packet(struct ttusb_dec *dec) |
diff --git a/drivers/media/v4l2-core/Kconfig b/drivers/media/v4l2-core/Kconfig index bf52fbd07aed..8e37e7c5e0f7 100644 --- a/drivers/media/v4l2-core/Kconfig +++ b/drivers/media/v4l2-core/Kconfig | |||
@@ -7,6 +7,7 @@ config VIDEO_V4L2 | |||
7 | tristate | 7 | tristate |
8 | depends on (I2C || I2C=n) && VIDEO_DEV | 8 | depends on (I2C || I2C=n) && VIDEO_DEV |
9 | select RATIONAL | 9 | select RATIONAL |
10 | select VIDEOBUF2_V4L2 if VIDEOBUF2_CORE | ||
10 | default (I2C || I2C=n) && VIDEO_DEV | 11 | default (I2C || I2C=n) && VIDEO_DEV |
11 | 12 | ||
12 | config VIDEO_ADV_DEBUG | 13 | config VIDEO_ADV_DEBUG |
diff --git a/drivers/media/v4l2-core/Makefile b/drivers/media/v4l2-core/Makefile index 80de2cb9c476..7df54582e956 100644 --- a/drivers/media/v4l2-core/Makefile +++ b/drivers/media/v4l2-core/Makefile | |||
@@ -13,7 +13,7 @@ ifeq ($(CONFIG_COMPAT),y) | |||
13 | endif | 13 | endif |
14 | obj-$(CONFIG_V4L2_FWNODE) += v4l2-fwnode.o | 14 | obj-$(CONFIG_V4L2_FWNODE) += v4l2-fwnode.o |
15 | ifeq ($(CONFIG_TRACEPOINTS),y) | 15 | ifeq ($(CONFIG_TRACEPOINTS),y) |
16 | videodev-objs += vb2-trace.o v4l2-trace.o | 16 | videodev-objs += v4l2-trace.o |
17 | endif | 17 | endif |
18 | videodev-$(CONFIG_MEDIA_CONTROLLER) += v4l2-mc.o | 18 | videodev-$(CONFIG_MEDIA_CONTROLLER) += v4l2-mc.o |
19 | 19 | ||
@@ -35,4 +35,3 @@ obj-$(CONFIG_VIDEOBUF_DVB) += videobuf-dvb.o | |||
35 | 35 | ||
36 | ccflags-y += -I$(srctree)/drivers/media/dvb-frontends | 36 | ccflags-y += -I$(srctree)/drivers/media/dvb-frontends |
37 | ccflags-y += -I$(srctree)/drivers/media/tuners | 37 | ccflags-y += -I$(srctree)/drivers/media/tuners |
38 | |||
diff --git a/include/media/demux.h b/include/media/demux.h index c4df6cee48e6..bf00a5a41a90 100644 --- a/include/media/demux.h +++ b/include/media/demux.h | |||
@@ -117,7 +117,7 @@ struct dmx_ts_feed { | |||
117 | * specified by @filter_value that will be used on the filter | 117 | * specified by @filter_value that will be used on the filter |
118 | * match logic. | 118 | * match logic. |
119 | * @filter_mode: Contains a 16 bytes (128 bits) filter mode. | 119 | * @filter_mode: Contains a 16 bytes (128 bits) filter mode. |
120 | * @parent: Pointer to struct dmx_section_feed. | 120 | * @parent: Back-pointer to struct dmx_section_feed. |
121 | * @priv: Pointer to private data of the API client. | 121 | * @priv: Pointer to private data of the API client. |
122 | * | 122 | * |
123 | * | 123 | * |
@@ -130,8 +130,9 @@ struct dmx_section_filter { | |||
130 | u8 filter_value[DMX_MAX_FILTER_SIZE]; | 130 | u8 filter_value[DMX_MAX_FILTER_SIZE]; |
131 | u8 filter_mask[DMX_MAX_FILTER_SIZE]; | 131 | u8 filter_mask[DMX_MAX_FILTER_SIZE]; |
132 | u8 filter_mode[DMX_MAX_FILTER_SIZE]; | 132 | u8 filter_mode[DMX_MAX_FILTER_SIZE]; |
133 | struct dmx_section_feed *parent; /* Back-pointer */ | 133 | struct dmx_section_feed *parent; |
134 | void *priv; /* Pointer to private data of the API client */ | 134 | |
135 | void *priv; | ||
135 | }; | 136 | }; |
136 | 137 | ||
137 | /** | 138 | /** |
@@ -193,6 +194,10 @@ struct dmx_section_feed { | |||
193 | * @buffer2: Pointer to the tail of the filtered TS packets, or NULL. | 194 | * @buffer2: Pointer to the tail of the filtered TS packets, or NULL. |
194 | * @buffer2_length: Length of the TS data in buffer2. | 195 | * @buffer2_length: Length of the TS data in buffer2. |
195 | * @source: Indicates which TS feed is the source of the callback. | 196 | * @source: Indicates which TS feed is the source of the callback. |
197 | * @buffer_flags: Address where buffer flags are stored. Those are | ||
198 | * used to report discontinuity users via DVB | ||
199 | * memory mapped API, as defined by | ||
200 | * &enum dmx_buffer_flags. | ||
196 | * | 201 | * |
197 | * This function callback prototype, provided by the client of the demux API, | 202 | * This function callback prototype, provided by the client of the demux API, |
198 | * is called from the demux code. The function is only called when filtering | 203 | * is called from the demux code. The function is only called when filtering |
@@ -245,7 +250,8 @@ typedef int (*dmx_ts_cb)(const u8 *buffer1, | |||
245 | size_t buffer1_length, | 250 | size_t buffer1_length, |
246 | const u8 *buffer2, | 251 | const u8 *buffer2, |
247 | size_t buffer2_length, | 252 | size_t buffer2_length, |
248 | struct dmx_ts_feed *source); | 253 | struct dmx_ts_feed *source, |
254 | u32 *buffer_flags); | ||
249 | 255 | ||
250 | /** | 256 | /** |
251 | * typedef dmx_section_cb - DVB demux TS filter callback function prototype | 257 | * typedef dmx_section_cb - DVB demux TS filter callback function prototype |
@@ -261,6 +267,10 @@ typedef int (*dmx_ts_cb)(const u8 *buffer1, | |||
261 | * including headers and CRC. | 267 | * including headers and CRC. |
262 | * @source: Indicates which section feed is the source of the | 268 | * @source: Indicates which section feed is the source of the |
263 | * callback. | 269 | * callback. |
270 | * @buffer_flags: Address where buffer flags are stored. Those are | ||
271 | * used to report discontinuity users via DVB | ||
272 | * memory mapped API, as defined by | ||
273 | * &enum dmx_buffer_flags. | ||
264 | * | 274 | * |
265 | * This function callback prototype, provided by the client of the demux API, | 275 | * This function callback prototype, provided by the client of the demux API, |
266 | * is called from the demux code. The function is only called when | 276 | * is called from the demux code. The function is only called when |
@@ -286,7 +296,8 @@ typedef int (*dmx_section_cb)(const u8 *buffer1, | |||
286 | size_t buffer1_len, | 296 | size_t buffer1_len, |
287 | const u8 *buffer2, | 297 | const u8 *buffer2, |
288 | size_t buffer2_len, | 298 | size_t buffer2_len, |
289 | struct dmx_section_filter *source); | 299 | struct dmx_section_filter *source, |
300 | u32 *buffer_flags); | ||
290 | 301 | ||
291 | /* | 302 | /* |
292 | * DVB Front-End | 303 | * DVB Front-End |
diff --git a/include/media/dmxdev.h b/include/media/dmxdev.h index 2f5cb2c7b6a7..baafa3b8aca4 100644 --- a/include/media/dmxdev.h +++ b/include/media/dmxdev.h | |||
@@ -163,6 +163,7 @@ struct dmxdev_filter { | |||
163 | * @demux: pointer to &struct dmx_demux. | 163 | * @demux: pointer to &struct dmx_demux. |
164 | * @filternum: number of filters. | 164 | * @filternum: number of filters. |
165 | * @capabilities: demux capabilities as defined by &enum dmx_demux_caps. | 165 | * @capabilities: demux capabilities as defined by &enum dmx_demux_caps. |
166 | * @may_do_mmap: flag used to indicate if the device may do mmap. | ||
166 | * @exit: flag to indicate that the demux is being released. | 167 | * @exit: flag to indicate that the demux is being released. |
167 | * @dvr_orig_fe: pointer to &struct dmx_frontend. | 168 | * @dvr_orig_fe: pointer to &struct dmx_frontend. |
168 | * @dvr_buffer: embedded &struct dvb_ringbuffer for DVB output. | 169 | * @dvr_buffer: embedded &struct dvb_ringbuffer for DVB output. |
@@ -180,6 +181,7 @@ struct dmxdev { | |||
180 | int filternum; | 181 | int filternum; |
181 | int capabilities; | 182 | int capabilities; |
182 | 183 | ||
184 | unsigned int may_do_mmap:1; | ||
183 | unsigned int exit:1; | 185 | unsigned int exit:1; |
184 | #define DMXDEV_CAP_DUPLEX 1 | 186 | #define DMXDEV_CAP_DUPLEX 1 |
185 | struct dmx_frontend *dvr_orig_fe; | 187 | struct dmx_frontend *dvr_orig_fe; |
diff --git a/include/media/dvb_demux.h b/include/media/dvb_demux.h index b07092038f4b..3b6aeca7a49e 100644 --- a/include/media/dvb_demux.h +++ b/include/media/dvb_demux.h | |||
@@ -115,6 +115,8 @@ struct dvb_demux_filter { | |||
115 | * @pid: PID to be filtered. | 115 | * @pid: PID to be filtered. |
116 | * @timeout: feed timeout. | 116 | * @timeout: feed timeout. |
117 | * @filter: pointer to &struct dvb_demux_filter. | 117 | * @filter: pointer to &struct dvb_demux_filter. |
118 | * @buffer_flags: Buffer flags used to report discontinuity users via DVB | ||
119 | * memory mapped API, as defined by &enum dmx_buffer_flags. | ||
118 | * @ts_type: type of TS, as defined by &enum ts_filter_type. | 120 | * @ts_type: type of TS, as defined by &enum ts_filter_type. |
119 | * @pes_type: type of PES, as defined by &enum dmx_ts_pes. | 121 | * @pes_type: type of PES, as defined by &enum dmx_ts_pes. |
120 | * @cc: MPEG-TS packet continuity counter | 122 | * @cc: MPEG-TS packet continuity counter |
@@ -145,6 +147,8 @@ struct dvb_demux_feed { | |||
145 | ktime_t timeout; | 147 | ktime_t timeout; |
146 | struct dvb_demux_filter *filter; | 148 | struct dvb_demux_filter *filter; |
147 | 149 | ||
150 | u32 buffer_flags; | ||
151 | |||
148 | enum ts_filter_type ts_type; | 152 | enum ts_filter_type ts_type; |
149 | enum dmx_ts_pes pes_type; | 153 | enum dmx_ts_pes pes_type; |
150 | 154 | ||
diff --git a/include/media/dvb_vb2.h b/include/media/dvb_vb2.h index 01d1202d1a55..8cb88452cd6c 100644 --- a/include/media/dvb_vb2.h +++ b/include/media/dvb_vb2.h | |||
@@ -85,6 +85,12 @@ struct dvb_buffer { | |||
85 | * @nonblocking: | 85 | * @nonblocking: |
86 | * If different than zero, device is operating on non-blocking | 86 | * If different than zero, device is operating on non-blocking |
87 | * mode. | 87 | * mode. |
88 | * @flags: buffer flags as defined by &enum dmx_buffer_flags. | ||
89 | * Filled only at &DMX_DQBUF. &DMX_QBUF should zero this field. | ||
90 | * @count: monotonic counter for filled buffers. Helps to identify | ||
91 | * data stream loses. Filled only at &DMX_DQBUF. &DMX_QBUF should | ||
92 | * zero this field. | ||
93 | * | ||
88 | * @name: name of the device type. Currently, it can either be | 94 | * @name: name of the device type. Currently, it can either be |
89 | * "dvr" or "demux_filter". | 95 | * "dvr" or "demux_filter". |
90 | */ | 96 | */ |
@@ -100,10 +106,14 @@ struct dvb_vb2_ctx { | |||
100 | int buf_siz; | 106 | int buf_siz; |
101 | int buf_cnt; | 107 | int buf_cnt; |
102 | int nonblocking; | 108 | int nonblocking; |
109 | |||
110 | enum dmx_buffer_flags flags; | ||
111 | u32 count; | ||
112 | |||
103 | char name[DVB_VB2_NAME_MAX + 1]; | 113 | char name[DVB_VB2_NAME_MAX + 1]; |
104 | }; | 114 | }; |
105 | 115 | ||
106 | #ifndef DVB_MMAP | 116 | #ifndef CONFIG_DVB_MMAP |
107 | static inline int dvb_vb2_init(struct dvb_vb2_ctx *ctx, | 117 | static inline int dvb_vb2_init(struct dvb_vb2_ctx *ctx, |
108 | const char *name, int non_blocking) | 118 | const char *name, int non_blocking) |
109 | { | 119 | { |
@@ -114,7 +124,7 @@ static inline int dvb_vb2_release(struct dvb_vb2_ctx *ctx) | |||
114 | return 0; | 124 | return 0; |
115 | }; | 125 | }; |
116 | #define dvb_vb2_is_streaming(ctx) (0) | 126 | #define dvb_vb2_is_streaming(ctx) (0) |
117 | #define dvb_vb2_fill_buffer(ctx, file, wait) (0) | 127 | #define dvb_vb2_fill_buffer(ctx, file, wait, flags) (0) |
118 | 128 | ||
119 | static inline __poll_t dvb_vb2_poll(struct dvb_vb2_ctx *ctx, | 129 | static inline __poll_t dvb_vb2_poll(struct dvb_vb2_ctx *ctx, |
120 | struct file *file, | 130 | struct file *file, |
@@ -153,9 +163,13 @@ int dvb_vb2_is_streaming(struct dvb_vb2_ctx *ctx); | |||
153 | * @ctx: control struct for VB2 handler | 163 | * @ctx: control struct for VB2 handler |
154 | * @src: place where the data is stored | 164 | * @src: place where the data is stored |
155 | * @len: number of bytes to be copied from @src | 165 | * @len: number of bytes to be copied from @src |
166 | * @buffer_flags: | ||
167 | * pointer to buffer flags as defined by &enum dmx_buffer_flags. | ||
168 | * can be NULL. | ||
156 | */ | 169 | */ |
157 | int dvb_vb2_fill_buffer(struct dvb_vb2_ctx *ctx, | 170 | int dvb_vb2_fill_buffer(struct dvb_vb2_ctx *ctx, |
158 | const unsigned char *src, int len); | 171 | const unsigned char *src, int len, |
172 | enum dmx_buffer_flags *buffer_flags); | ||
159 | 173 | ||
160 | /** | 174 | /** |
161 | * dvb_vb2_poll - Wrapper to vb2_core_streamon() for Digital TV | 175 | * dvb_vb2_poll - Wrapper to vb2_core_streamon() for Digital TV |
diff --git a/include/uapi/linux/dvb/dmx.h b/include/uapi/linux/dvb/dmx.h index 5f3c5a918f00..b4112f0b6dd3 100644 --- a/include/uapi/linux/dvb/dmx.h +++ b/include/uapi/linux/dvb/dmx.h | |||
@@ -212,6 +212,32 @@ struct dmx_stc { | |||
212 | }; | 212 | }; |
213 | 213 | ||
214 | /** | 214 | /** |
215 | * enum dmx_buffer_flags - DMX memory-mapped buffer flags | ||
216 | * | ||
217 | * @DMX_BUFFER_FLAG_HAD_CRC32_DISCARD: | ||
218 | * Indicates that the Kernel discarded one or more frames due to wrong | ||
219 | * CRC32 checksum. | ||
220 | * @DMX_BUFFER_FLAG_TEI: | ||
221 | * Indicates that the Kernel has detected a Transport Error indicator | ||
222 | * (TEI) on a filtered pid. | ||
223 | * @DMX_BUFFER_PKT_COUNTER_MISMATCH: | ||
224 | * Indicates that the Kernel has detected a packet counter mismatch | ||
225 | * on a filtered pid. | ||
226 | * @DMX_BUFFER_FLAG_DISCONTINUITY_DETECTED: | ||
227 | * Indicates that the Kernel has detected one or more frame discontinuity. | ||
228 | * @DMX_BUFFER_FLAG_DISCONTINUITY_INDICATOR: | ||
229 | * Received at least one packet with a frame discontinuity indicator. | ||
230 | */ | ||
231 | |||
232 | enum dmx_buffer_flags { | ||
233 | DMX_BUFFER_FLAG_HAD_CRC32_DISCARD = 1 << 0, | ||
234 | DMX_BUFFER_FLAG_TEI = 1 << 1, | ||
235 | DMX_BUFFER_PKT_COUNTER_MISMATCH = 1 << 2, | ||
236 | DMX_BUFFER_FLAG_DISCONTINUITY_DETECTED = 1 << 3, | ||
237 | DMX_BUFFER_FLAG_DISCONTINUITY_INDICATOR = 1 << 4, | ||
238 | }; | ||
239 | |||
240 | /** | ||
215 | * struct dmx_buffer - dmx buffer info | 241 | * struct dmx_buffer - dmx buffer info |
216 | * | 242 | * |
217 | * @index: id number of the buffer | 243 | * @index: id number of the buffer |
@@ -220,15 +246,24 @@ struct dmx_stc { | |||
220 | * offset from the start of the device memory for this plane, | 246 | * offset from the start of the device memory for this plane, |
221 | * (or a "cookie" that should be passed to mmap() as offset) | 247 | * (or a "cookie" that should be passed to mmap() as offset) |
222 | * @length: size in bytes of the buffer | 248 | * @length: size in bytes of the buffer |
249 | * @flags: bit array of buffer flags as defined by &enum dmx_buffer_flags. | ||
250 | * Filled only at &DMX_DQBUF. | ||
251 | * @count: monotonic counter for filled buffers. Helps to identify | ||
252 | * data stream loses. Filled only at &DMX_DQBUF. | ||
223 | * | 253 | * |
224 | * Contains data exchanged by application and driver using one of the streaming | 254 | * Contains data exchanged by application and driver using one of the streaming |
225 | * I/O methods. | 255 | * I/O methods. |
256 | * | ||
257 | * Please notice that, for &DMX_QBUF, only @index should be filled. | ||
258 | * On &DMX_DQBUF calls, all fields will be filled by the Kernel. | ||
226 | */ | 259 | */ |
227 | struct dmx_buffer { | 260 | struct dmx_buffer { |
228 | __u32 index; | 261 | __u32 index; |
229 | __u32 bytesused; | 262 | __u32 bytesused; |
230 | __u32 offset; | 263 | __u32 offset; |
231 | __u32 length; | 264 | __u32 length; |
265 | __u32 flags; | ||
266 | __u32 count; | ||
232 | }; | 267 | }; |
233 | 268 | ||
234 | /** | 269 | /** |