Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

media: dvb-core: make DVB mmap API optional

This API is still experimental. Make it optional, allowing to
compile the code without it.

Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>

+98 -13
+12
drivers/media/Kconfig
··· 144 144 default y 145 145 select CRC32 146 146 147 + config DVB_MMAP 148 + bool "Enable DVB memory-mapped API (EXPERIMENTAL)" 149 + depends on DVB_CORE 150 + default n 151 + help 152 + This option enables DVB experimental memory-mapped API, with 153 + reduces the number of context switches to read DVB buffers, as 154 + the buffers can use mmap() syscalls. 155 + 156 + Support for it is experimental. Use with care. If unsure, 157 + say N. 158 + 147 159 config DVB_NET 148 160 bool "DVB Network Support" 149 161 default (NET && INET)
+2 -1
drivers/media/dvb-core/Makefile
··· 4 4 # 5 5 6 6 dvb-net-$(CONFIG_DVB_NET) := dvb_net.o 7 + dvb-vb2-$(CONFIG_DVB_MMSP) := dvb_vb2.o 7 8 8 9 dvb-core-objs := dvbdev.o dmxdev.o dvb_demux.o \ 9 10 dvb_ca_en50221.o dvb_frontend.o \ 10 - $(dvb-net-y) dvb_ringbuffer.o dvb_vb2.o dvb_math.o 11 + $(dvb-net-y) dvb_ringbuffer.o $(dvb-vb2-y) dvb_math.o 11 12 12 13 obj-$(CONFIG_DVB_CORE) += dvb-core.o
+58 -8
drivers/media/dvb-core/dmxdev.c
··· 128 128 struct dvb_device *dvbdev = file->private_data; 129 129 struct dmxdev *dmxdev = dvbdev->priv; 130 130 struct dmx_frontend *front; 131 + #ifndef DVB_MMAP 132 + bool need_ringbuffer = false; 133 + #else 134 + const bool need_ringbuffer = true; 135 + #endif 131 136 132 137 dprintk("%s\n", __func__); 133 138 ··· 144 139 return -ENODEV; 145 140 } 146 141 147 - if (((file->f_flags & O_ACCMODE) == O_RDONLY) || 148 - ((file->f_flags & O_ACCMODE) == O_RDWR)) { 142 + #ifndef DVB_MMAP 143 + if ((file->f_flags & O_ACCMODE) == O_RDONLY) 144 + need_ringbuffer = true; 145 + #else 146 + if ((file->f_flags & O_ACCMODE) == O_RDWR) { 147 + if (!(dmxdev->capabilities & DMXDEV_CAP_DUPLEX)) { 148 + mutex_unlock(&dmxdev->mutex); 149 + return -EOPNOTSUPP; 150 + } 151 + } 152 + #endif 153 + 154 + if (need_ringbuffer) { 149 155 void *mem; 150 156 151 157 if (!dvbdev->readers) { ··· 200 184 { 201 185 struct dvb_device *dvbdev = file->private_data; 202 186 struct dmxdev *dmxdev = dvbdev->priv; 187 + #ifndef DVB_MMAP 188 + bool need_ringbuffer = false; 189 + #else 190 + const bool need_ringbuffer = true; 191 + #endif 203 192 204 193 mutex_lock(&dmxdev->mutex); 205 194 ··· 213 192 dmxdev->demux->connect_frontend(dmxdev->demux, 214 193 dmxdev->dvr_orig_fe); 215 194 } 216 - if (((file->f_flags & O_ACCMODE) == O_RDONLY) || 217 - ((file->f_flags & O_ACCMODE) == O_RDWR)) { 195 + #ifndef DVB_MMAP 196 + if ((file->f_flags & O_ACCMODE) == O_RDONLY) 197 + need_ringbuffer = true; 198 + #endif 199 + 200 + if (need_ringbuffer) { 218 201 if (dvb_vb2_is_streaming(&dmxdev->dvr_vb2_ctx)) 219 202 dvb_vb2_stream_off(&dmxdev->dvr_vb2_ctx); 220 203 dvb_vb2_release(&dmxdev->dvr_vb2_ctx); ··· 384 359 { 385 360 struct dmxdev_filter *dmxdevfilter = filter->priv; 386 361 int ret; 362 + 387 363 if (!dvb_vb2_is_streaming(&dmxdevfilter->vb2_ctx) && 388 364 dmxdevfilter->buffer.error) { 389 365 wake_up(&dmxdevfilter->buffer.queue); ··· 426 400 { 427 401 struct dmxdev_filter *dmxdevfilter = feed->priv; 428 402 struct dvb_ringbuffer *buffer; 403 + #ifdef DVB_MMAP 429 404 struct dvb_vb2_ctx *ctx; 405 + #endif 430 406 int ret; 431 407 432 408 spin_lock(&dmxdevfilter->dev->lock); ··· 440 412 if (dmxdevfilter->params.pes.output == DMX_OUT_TAP || 441 413 dmxdevfilter->params.pes.output == DMX_OUT_TSDEMUX_TAP) { 442 414 buffer = &dmxdevfilter->buffer; 415 + #ifdef DVB_MMAP 443 416 ctx = &dmxdevfilter->vb2_ctx; 417 + #endif 444 418 } else { 445 419 buffer = &dmxdevfilter->dev->dvr_buffer; 420 + #ifdef DVB_MMAP 446 421 ctx = &dmxdevfilter->dev->dvr_vb2_ctx; 422 + #endif 447 423 } 448 424 449 425 if (dvb_vb2_is_streaming(ctx)) { ··· 1111 1079 mutex_unlock(&dmxdevfilter->mutex); 1112 1080 break; 1113 1081 1082 + #ifdef DVB_MMAP 1114 1083 case DMX_REQBUFS: 1115 1084 if (mutex_lock_interruptible(&dmxdevfilter->mutex)) { 1116 1085 mutex_unlock(&dmxdev->mutex); ··· 1158 1125 ret = dvb_vb2_dqbuf(&dmxdevfilter->vb2_ctx, parg); 1159 1126 mutex_unlock(&dmxdevfilter->mutex); 1160 1127 break; 1161 - 1128 + #endif 1162 1129 default: 1163 1130 ret = -EINVAL; 1164 1131 break; ··· 1199 1166 return mask; 1200 1167 } 1201 1168 1169 + #ifdef DVB_MMAP 1202 1170 static int dvb_demux_mmap(struct file *file, struct vm_area_struct *vma) 1203 1171 { 1204 1172 struct dmxdev_filter *dmxdevfilter = file->private_data; ··· 1220 1186 1221 1187 return ret; 1222 1188 } 1189 + #endif 1223 1190 1224 1191 static int dvb_demux_release(struct inode *inode, struct file *file) 1225 1192 { ··· 1249 1214 .release = dvb_demux_release, 1250 1215 .poll = dvb_demux_poll, 1251 1216 .llseek = default_llseek, 1217 + #ifdef DVB_MMAP 1252 1218 .mmap = dvb_demux_mmap, 1219 + #endif 1253 1220 }; 1254 1221 1255 1222 static const struct dvb_device dvbdev_demux = { ··· 1280 1243 ret = dvb_dvr_set_buffer_size(dmxdev, arg); 1281 1244 break; 1282 1245 1246 + #ifdef DVB_MMAP 1283 1247 case DMX_REQBUFS: 1284 1248 ret = dvb_vb2_reqbufs(&dmxdev->dvr_vb2_ctx, parg); 1285 1249 break; ··· 1302 1264 case DMX_DQBUF: 1303 1265 ret = dvb_vb2_dqbuf(&dmxdev->dvr_vb2_ctx, parg); 1304 1266 break; 1305 - 1267 + #endif 1306 1268 default: 1307 1269 ret = -EINVAL; 1308 1270 break; ··· 1322 1284 struct dvb_device *dvbdev = file->private_data; 1323 1285 struct dmxdev *dmxdev = dvbdev->priv; 1324 1286 unsigned int mask = 0; 1287 + #ifndef DVB_MMAP 1288 + bool need_ringbuffer = false; 1289 + #else 1290 + const bool need_ringbuffer = true; 1291 + #endif 1325 1292 1326 1293 dprintk("%s\n", __func__); 1327 1294 ··· 1337 1294 1338 1295 poll_wait(file, &dmxdev->dvr_buffer.queue, wait); 1339 1296 1340 - if (((file->f_flags & O_ACCMODE) == O_RDONLY) || 1341 - ((file->f_flags & O_ACCMODE) == O_RDWR)) { 1297 + #ifndef DVB_MMAP 1298 + if ((file->f_flags & O_ACCMODE) == O_RDONLY) 1299 + need_ringbuffer = true; 1300 + #endif 1301 + if (need_ringbuffer) { 1342 1302 if (dmxdev->dvr_buffer.error) 1343 1303 mask |= (POLLIN | POLLRDNORM | POLLPRI | POLLERR); 1344 1304 ··· 1353 1307 return mask; 1354 1308 } 1355 1309 1310 + #ifdef DVB_MMAP 1356 1311 static int dvb_dvr_mmap(struct file *file, struct vm_area_struct *vma) 1357 1312 { 1358 1313 struct dvb_device *dvbdev = file->private_data; ··· 1370 1323 mutex_unlock(&dmxdev->mutex); 1371 1324 return ret; 1372 1325 } 1326 + #endif 1373 1327 1374 1328 static const struct file_operations dvb_dvr_fops = { 1375 1329 .owner = THIS_MODULE, ··· 1381 1333 .release = dvb_dvr_release, 1382 1334 .poll = dvb_dvr_poll, 1383 1335 .llseek = default_llseek, 1336 + #ifdef DVB_MMAP 1384 1337 .mmap = dvb_dvr_mmap, 1338 + #endif 1385 1339 }; 1386 1340 1387 1341 static const struct dvb_device dvbdev_dvr = {
+26 -4
drivers/media/dvb-core/dvb_vb2.h
··· 54 54 char name[DVB_VB2_NAME_MAX + 1]; 55 55 }; 56 56 57 - int dvb_vb2_init(struct dvb_vb2_ctx *ctx, const char *name, int non_blocking); 58 - int dvb_vb2_release(struct dvb_vb2_ctx *ctx); 59 57 int dvb_vb2_stream_on(struct dvb_vb2_ctx *ctx); 60 58 int dvb_vb2_stream_off(struct dvb_vb2_ctx *ctx); 59 + #ifndef DVB_MMAP 60 + static inline int dvb_vb2_init(struct dvb_vb2_ctx *ctx, 61 + const char *name, int non_blocking) 62 + { 63 + return 0; 64 + }; 65 + static inline int dvb_vb2_release(struct dvb_vb2_ctx *ctx) 66 + { 67 + return 0; 68 + }; 69 + #define dvb_vb2_is_streaming(ctx) (0) 70 + #define dvb_vb2_fill_buffer(ctx, file, wait) (0) 71 + 72 + static inline unsigned int dvb_vb2_poll(struct dvb_vb2_ctx *ctx, 73 + struct file *file, 74 + poll_table *wait) 75 + { 76 + return 0; 77 + } 78 + #else 79 + int dvb_vb2_init(struct dvb_vb2_ctx *ctx, const char *name, int non_blocking); 80 + int dvb_vb2_release(struct dvb_vb2_ctx *ctx); 61 81 int dvb_vb2_is_streaming(struct dvb_vb2_ctx *ctx); 62 82 int dvb_vb2_fill_buffer(struct dvb_vb2_ctx *ctx, 63 83 const unsigned char *src, int len); 84 + unsigned int dvb_vb2_poll(struct dvb_vb2_ctx *ctx, struct file *file, 85 + poll_table *wait); 86 + #endif 87 + 64 88 65 89 int dvb_vb2_reqbufs(struct dvb_vb2_ctx *ctx, struct dmx_requestbuffers *req); 66 90 int dvb_vb2_querybuf(struct dvb_vb2_ctx *ctx, struct dmx_buffer *b); ··· 92 68 int dvb_vb2_qbuf(struct dvb_vb2_ctx *ctx, struct dmx_buffer *b); 93 69 int dvb_vb2_dqbuf(struct dvb_vb2_ctx *ctx, struct dmx_buffer *b); 94 70 int dvb_vb2_mmap(struct dvb_vb2_ctx *ctx, struct vm_area_struct *vma); 95 - unsigned int dvb_vb2_poll(struct dvb_vb2_ctx *ctx, struct file *file, 96 - poll_table *wait); 97 71 98 72 #endif /* _DVB_VB2_H */