Home | History | Annotate | Line # | Download | only in dtv
dtv_demux.c revision 1.10
      1 /* $NetBSD: dtv_demux.c,v 1.10 2019/02/24 12:05:49 jmcneill Exp $ */
      2 
      3 /*-
      4  * Copyright (c) 2011 Jared D. McNeill <jmcneill (at) invisible.ca>
      5  * All rights reserved.
      6  *
      7  * Redistribution and use in source and binary forms, with or without
      8  * modification, are permitted provided that the following conditions
      9  * are met:
     10  * 1. Redistributions of source code must retain the above copyright
     11  *    notice, this list of conditions and the following disclaimer.
     12  * 2. Redistributions in binary form must reproduce the above copyright
     13  *    notice, this list of conditions and the following disclaimer in the
     14  *    documentation and/or other materials provided with the distribution.
     15  * 3. All advertising materials mentioning features or use of this software
     16  *    must display the following acknowledgement:
     17  *        This product includes software developed by Jared D. McNeill.
     18  * 4. Neither the name of The NetBSD Foundation nor the names of its
     19  *    contributors may be used to endorse or promote products derived
     20  *    from this software without specific prior written permission.
     21  *
     22  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     23  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     24  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     25  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     26  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     27  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     28  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     29  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     30  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     31  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     32  * POSSIBILITY OF SUCH DAMAGE.
     33  */
     34 
     35 /*
     36  * This file contains support for the /dev/dvb/adapter<n>/demux0 device.
     37  *
     38  * The demux device is implemented as a cloning device. Each instance can
     39  * be in one of three modes: unconfigured (NONE), section filter (SECTION),
     40  * or PID filter (PES).
     41  *
     42  * An instance in section filter mode extracts PSI sections based on a
     43  * filter configured by the DMX_SET_FILTER ioctl. When an entire section is
     44  * received, it is made available to userspace via read method. Data is fed
     45  * into the section filter using the dtv_demux_write function.
     46  *
     47  * An instance in PID filter mode extracts TS packets that match the
     48  * specified PID filter configured by the DMX_SET_PES_FILTER, DMX_ADD_PID,
     49  * and DMX_REMOVE_PID ioctls. As this driver only implements the
     50  * DMX_OUT_TS_TAP output, these TS packets are made available to userspace
     51  * by calling read on the /dev/dvb/adapter<n>/dvr0 device.
     52  */
     53 
     54 #include <sys/cdefs.h>
     55 __KERNEL_RCSID(0, "$NetBSD: dtv_demux.c,v 1.10 2019/02/24 12:05:49 jmcneill Exp $");
     56 
     57 #include <sys/param.h>
     58 #include <sys/types.h>
     59 #include <sys/conf.h>
     60 #include <sys/kmem.h>
     61 #include <sys/device.h>
     62 #include <sys/select.h>
     63 #include <sys/filedesc.h>
     64 #include <sys/file.h>
     65 #include <sys/poll.h>
     66 #include <sys/vnode.h>
     67 #include <sys/queue.h>
     68 
     69 #include <dev/dtv/dtvvar.h>
     70 
     71 static int	dtv_demux_read(struct file *, off_t *, struct uio *,
     72 		    kauth_cred_t, int);
     73 static int	dtv_demux_ioctl(struct file *, u_long, void *);
     74 static int	dtv_demux_poll(struct file *, int);
     75 static int	dtv_demux_close(struct file *);
     76 
     77 static const struct fileops dtv_demux_fileops = {
     78 	.fo_name = "dtv_demux",
     79 	.fo_read = dtv_demux_read,
     80 	.fo_write = fbadop_write,
     81 	.fo_ioctl = dtv_demux_ioctl,
     82 	.fo_fcntl = fnullop_fcntl,
     83 	.fo_poll = dtv_demux_poll,
     84 	.fo_stat = fbadop_stat,
     85 	.fo_close = dtv_demux_close,
     86 	.fo_kqfilter = fnullop_kqfilter,
     87 	.fo_restart = fnullop_restart,
     88 };
     89 
     90 static uint32_t crc_table[256] = {
     91 	0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9,
     92 	0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005,
     93 	0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
     94 	0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd,
     95 	0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9,
     96 	0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
     97 	0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011,
     98 	0x791d4014, 0x7ddc5da3, 0x709f7b7a, 0x745e66cd,
     99 	0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
    100 	0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5,
    101 	0xbe2b5b58, 0xbaea46ef, 0xb7a96036, 0xb3687d81,
    102 	0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
    103 	0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49,
    104 	0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95,
    105 	0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1,
    106 	0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d,
    107 	0x34867077, 0x30476dc0, 0x3d044b19, 0x39c556ae,
    108 	0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
    109 	0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16,
    110 	0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca,
    111 	0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde,
    112 	0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02,
    113 	0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1, 0x53dc6066,
    114 	0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
    115 	0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e,
    116 	0xbfa1b04b, 0xbb60adfc, 0xb6238b25, 0xb2e29692,
    117 	0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6,
    118 	0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a,
    119 	0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e,
    120 	0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
    121 	0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686,
    122 	0xd5b88683, 0xd1799b34, 0xdc3abded, 0xd8fba05a,
    123 	0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637,
    124 	0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb,
    125 	0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f,
    126 	0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
    127 	0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47,
    128 	0x36194d42, 0x32d850f5, 0x3f9b762c, 0x3b5a6b9b,
    129 	0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
    130 	0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623,
    131 	0xf12f560e, 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7,
    132 	0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
    133 	0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f,
    134 	0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3,
    135 	0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7,
    136 	0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b,
    137 	0x9b3660c6, 0x9ff77d71, 0x92b45ba8, 0x9675461f,
    138 	0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
    139 	0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640,
    140 	0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c,
    141 	0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8,
    142 	0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24,
    143 	0x119b4be9, 0x155a565e, 0x18197087, 0x1cd86d30,
    144 	0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
    145 	0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088,
    146 	0x2497d08d, 0x2056cd3a, 0x2d15ebe3, 0x29d4f654,
    147 	0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0,
    148 	0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c,
    149 	0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18,
    150 	0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
    151 	0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0,
    152 	0x9abc8bd5, 0x9e7d9662, 0x933eb0bb, 0x97ffad0c,
    153 	0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668,
    154 	0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
    155 };
    156 
    157 /* ISO/IEC 13818-1 Annex A "CRC Decoder Model" */
    158 static uint32_t
    159 dtv_demux_crc32(uint8_t *buf, int len)
    160 {
    161 	const uint32_t *crc_tab = crc_table;
    162 	uint32_t CRC = 0xffffffff;
    163 	int i;
    164 
    165 	for (i = 0; i < len; i++)
    166 	      	CRC = (CRC << 8) ^ crc_tab[((CRC >> 24) ^ *buf++) & 0xff];
    167 
    168 	return CRC;
    169 }
    170 
    171 /*
    172  * Start running the demux.
    173  */
    174 static int
    175 dtv_demux_start(struct dtv_demux *demux)
    176 {
    177 	struct dtv_softc *sc = demux->dd_sc;
    178 	int error = 0;
    179 	bool dostart = false;
    180 
    181 	/*
    182 	 * If the demux is not running, mark it as running and update the
    183 	 * global demux run counter.
    184 	 */
    185 	mutex_enter(&sc->sc_lock);
    186 	KASSERT(sc->sc_demux_runcnt >= 0);
    187 	if (demux->dd_running == false) {
    188 		sc->sc_demux_runcnt++;
    189 		demux->dd_running = true;
    190 		/* If this is the first demux running, trigger device start */
    191 		dostart = sc->sc_demux_runcnt == 1;
    192 	}
    193 	mutex_exit(&sc->sc_lock);
    194 
    195 	if (dostart) {
    196 		/* Setup receive buffers and trigger device start */
    197 		error = dtv_buffer_setup(sc);
    198 		if (error == 0)
    199 			error = dtv_device_start_transfer(sc);
    200 	}
    201 
    202 	/*
    203 	 * If something went wrong, restore the run counter and mark this
    204 	 * demux instance as halted.
    205 	 */
    206 	if (error) {
    207 		mutex_enter(&sc->sc_lock);
    208 		sc->sc_demux_runcnt--;
    209 		demux->dd_running = false;
    210 		mutex_exit(&sc->sc_lock);
    211 	}
    212 
    213 	return error;
    214 }
    215 
    216 /*
    217  * Stop running the demux.
    218  */
    219 static int
    220 dtv_demux_stop(struct dtv_demux *demux)
    221 {
    222 	struct dtv_softc *sc = demux->dd_sc;
    223 	int error = 0;
    224 	bool dostop = false;
    225 
    226 	/*
    227 	 * If the demux is running, mark it as halted and update the
    228 	 * global demux run counter.
    229 	 */
    230 	mutex_enter(&sc->sc_lock);
    231 	if (demux->dd_running == true) {
    232 		KASSERT(sc->sc_demux_runcnt > 0);
    233 		demux->dd_running = false;
    234 		sc->sc_demux_runcnt--;
    235 		/* If this was the last demux running, trigger device stop */
    236 		dostop = sc->sc_demux_runcnt == 0;
    237 	}
    238 	mutex_exit(&sc->sc_lock);
    239 
    240 	if (dostop) {
    241 		/* Trigger device stop */
    242 		error = dtv_device_stop_transfer(sc);
    243 	}
    244 
    245 	/*
    246 	 * If something went wrong, restore the run counter and mark this
    247 	 * demux instance as running.
    248 	 */
    249 	if (error) {
    250 		mutex_enter(&sc->sc_lock);
    251 		sc->sc_demux_runcnt++;
    252 		demux->dd_running = true;
    253 		mutex_exit(&sc->sc_lock);
    254 	}
    255 
    256 	return error;
    257 }
    258 
    259 /*
    260  * Put the demux into PID filter mode and update the PID filter table.
    261  */
    262 static int
    263 dtv_demux_set_pidfilter(struct dtv_demux *demux, uint16_t pid, bool onoff)
    264 {
    265 	struct dtv_softc *sc = demux->dd_sc;
    266 
    267 	/*
    268 	 * TS PID is 13 bits; demux device uses special PID 0x2000 to mean
    269 	 * "all PIDs". Verify that the requested PID is in range.
    270 	 */
    271 	if (pid > 0x2000)
    272 		return EINVAL;
    273 
    274 	/* Set demux mode */
    275 	demux->dd_mode = DTV_DEMUX_MODE_PES;
    276 	/*
    277 	 * If requesting "all PIDs", set the on/off flag for all PIDs in
    278 	 * the PID map, otherwise set the on/off flag for the requested
    279 	 * PID.
    280 	 */
    281 	if (pid == 0x2000) {
    282 		memset(sc->sc_ts.ts_pidfilter, onoff ? 0xff : 0,
    283 		    sizeof(sc->sc_ts.ts_pidfilter));
    284 	} else {
    285 		sc->sc_ts.ts_pidfilter[pid] = onoff;
    286 	}
    287 
    288 	return 0;
    289 }
    290 
    291 /*
    292  * Open a new instance of the demux cloning device.
    293  */
    294 int
    295 dtv_demux_open(struct dtv_softc *sc, int flags, int mode, lwp_t *l)
    296 {
    297 	struct file *fp;
    298 	struct dtv_demux *demux;
    299 	int error, fd;
    300 
    301 	/* Allocate private storage */
    302 	demux = kmem_zalloc(sizeof(*demux), KM_SLEEP);
    303 	demux->dd_sc = sc;
    304 	/* Default operation mode is unconfigured */
    305 	demux->dd_mode = DTV_DEMUX_MODE_NONE;
    306 	selinit(&demux->dd_sel);
    307 	mutex_init(&demux->dd_lock, MUTEX_DEFAULT, IPL_SCHED);
    308 	cv_init(&demux->dd_section_cv, "dtvsec");
    309 
    310 	error = fd_allocfile(&fp, &fd);
    311 	if (error) {
    312 		kmem_free(demux, sizeof(*demux));
    313 		return error;
    314 	}
    315 
    316 	/* Add the demux to the list of demux instances */
    317 	mutex_enter(&sc->sc_demux_lock);
    318 	TAILQ_INSERT_TAIL(&sc->sc_demux_list, demux, dd_entries);
    319 	mutex_exit(&sc->sc_demux_lock);
    320 
    321 	return fd_clone(fp, fd, flags, &dtv_demux_fileops, demux);
    322 }
    323 
    324 /*
    325  * Close the instance of the demux cloning device.
    326  */
    327 int
    328 dtv_demux_close(struct file *fp)
    329 {
    330 	struct dtv_demux *demux = fp->f_data;
    331 	struct dtv_softc *sc;
    332 	int error;
    333 
    334 	if (demux == NULL)
    335 		return ENXIO;
    336 
    337 	fp->f_data = NULL;
    338 
    339 	sc = demux->dd_sc;
    340 
    341 	/* If the demux is still running, stop it */
    342 	if (demux->dd_running) {
    343 		error = dtv_demux_stop(demux);
    344 		if (error)
    345 			return error;
    346 	}
    347 
    348 	/* Remove the demux from the list of demux instances */
    349 	mutex_enter(&sc->sc_demux_lock);
    350 	TAILQ_REMOVE(&sc->sc_demux_list, demux, dd_entries);
    351 	mutex_exit(&sc->sc_demux_lock);
    352 
    353 	mutex_destroy(&demux->dd_lock);
    354 	cv_destroy(&demux->dd_section_cv);
    355 	kmem_free(demux, sizeof(*demux));
    356 
    357 	/* Update the global device open count */
    358 	dtv_common_close(sc);
    359 
    360 	return 0;
    361 }
    362 
    363 /*
    364  * Handle demux ioctl requests
    365  */
    366 static int
    367 dtv_demux_ioctl(struct file *fp, u_long cmd, void *data)
    368 {
    369 	struct dtv_demux *demux = fp->f_data;
    370 	struct dmx_pes_filter_params *pesfilt;
    371 	struct dmx_sct_filter_params *sctfilt;
    372 	uint16_t pid;
    373 	int error;
    374 
    375 	if (demux == NULL)
    376 		return ENXIO;
    377 
    378 	switch (cmd) {
    379 	case DMX_START:
    380 		return dtv_demux_start(demux);
    381 	case DMX_STOP:
    382 		return dtv_demux_stop(demux);
    383 	case DMX_SET_BUFFER_SIZE:
    384 		/*
    385 		 * The demux driver doesn't support configurable buffer sizes,
    386 		 * but software relies on this command succeeding.
    387 		 */
    388 		return 0;
    389 	case DMX_SET_FILTER:
    390 		sctfilt = data;
    391 
    392 		/* Verify that the requested PID is in range. */
    393 		if (sctfilt->pid >= 0x2000)
    394 			return EINVAL;
    395 
    396 		/*
    397 		 * Update section filter parameters, reset read/write ptrs,
    398 		 * clear section count and overflow flag, and set the
    399 		 * demux instance mode to section filter.
    400 		 */
    401 		demux->dd_secfilt.params = *sctfilt;
    402 		demux->dd_secfilt.rp = demux->dd_secfilt.wp = 0;
    403 		demux->dd_secfilt.nsections = 0;
    404 		demux->dd_secfilt.overflow = false;
    405 		demux->dd_mode = DTV_DEMUX_MODE_SECTION;
    406 
    407 		/*
    408 		 * If the DMX_IMMEDIATE_START flag is present in the request,
    409 		 * start running the demux immediately (no need for a
    410 		 * subsequent DMX_START ioctl).
    411 		 */
    412 		if (sctfilt->flags & DMX_IMMEDIATE_START) {
    413 			error = dtv_demux_start(demux);
    414 			if (error)
    415 				return error;
    416 		}
    417 
    418 		return 0;
    419 	case DMX_SET_PES_FILTER:
    420 		pesfilt = data;
    421 
    422 		/* The driver only supports input from the frontend */
    423 		if (pesfilt->input != DMX_IN_FRONTEND)
    424 			return EINVAL;
    425 		/*
    426 		 * The driver only supports output to the TS TAP in PID
    427 		 * filter mode.
    428 		 */
    429 		if (pesfilt->output != DMX_OUT_TS_TAP)
    430 			return EINVAL;
    431 
    432 		/* Update PID filter table */
    433 		error = dtv_demux_set_pidfilter(demux, pesfilt->pid, true);
    434 		if (error)
    435 			return error;
    436 
    437 		/*
    438 		 * If the DMX_IMMEDIATE_START flag is present in the request,
    439 		 * start running the demux immediately (no need for a
    440 		 * subsequent DMX_START ioctl).
    441 		 */
    442 		if (pesfilt->flags & DMX_IMMEDIATE_START) {
    443 			error = dtv_demux_start(demux);
    444 			if (error)
    445 				return error;
    446 		}
    447 		return 0;
    448 	case DMX_ADD_PID:
    449 		pid = *(uint16_t *)data;
    450 		return dtv_demux_set_pidfilter(demux, pid, true);
    451 	case DMX_REMOVE_PID:
    452 		pid = *(uint16_t *)data;
    453 		return dtv_demux_set_pidfilter(demux, pid, false);
    454 	default:
    455 		return EINVAL;
    456 	}
    457 }
    458 
    459 /*
    460  * Test for I/O readiness
    461  */
    462 static int
    463 dtv_demux_poll(struct file *fp, int events)
    464 {
    465 	struct dtv_demux *demux = fp->f_data;
    466 	int revents = 0;
    467 
    468 	if (demux == NULL)
    469 		return POLLERR;
    470 
    471 	/*
    472 	 * If the demux instance is in section filter mode, wait for an
    473 	 * entire section to become ready.
    474 	 */
    475 	mutex_enter(&demux->dd_lock);
    476 	if (demux->dd_mode == DTV_DEMUX_MODE_SECTION &&
    477 	    demux->dd_secfilt.nsections > 0) {
    478 		revents |= POLLIN;
    479 	} else {
    480 		selrecord(curlwp, &demux->dd_sel);
    481 	}
    482 	mutex_exit(&demux->dd_lock);
    483 
    484 	return revents;
    485 }
    486 
    487 /*
    488  * Read from the demux instance
    489  */
    490 static int
    491 dtv_demux_read(struct file *fp, off_t *offp, struct uio *uio,
    492     kauth_cred_t cred, int flags)
    493 {
    494 	struct dtv_demux *demux = fp->f_data;
    495 	struct dtv_ts_section sec;
    496 	int error;
    497 
    498 	if (demux == NULL)
    499 		return ENXIO;
    500 
    501 	/* Only support read if the instance is in section filter mode */
    502 	if (demux->dd_mode != DTV_DEMUX_MODE_SECTION)
    503 		return EIO;
    504 
    505 	/* Wait for a complete PSI section */
    506 	mutex_enter(&demux->dd_lock);
    507 	while (demux->dd_secfilt.nsections == 0) {
    508 		if (flags & IO_NDELAY) {
    509 			mutex_exit(&demux->dd_lock);
    510 			/* No data available */
    511 			return EWOULDBLOCK;
    512 		}
    513 		error = cv_wait_sig(&demux->dd_section_cv, &demux->dd_lock);
    514 		if (error) {
    515 			mutex_exit(&demux->dd_lock);
    516 			return error;
    517 		}
    518 	}
    519 	/* Copy the completed PSI section */
    520 	sec = demux->dd_secfilt.section[demux->dd_secfilt.rp];
    521 	/* Update read pointer */
    522 	demux->dd_secfilt.rp++;
    523 	if (demux->dd_secfilt.rp >= __arraycount(demux->dd_secfilt.section))
    524 		demux->dd_secfilt.rp = 0;
    525 	/* Update section count */
    526 	demux->dd_secfilt.nsections--;
    527 	mutex_exit(&demux->dd_lock);
    528 
    529 	/*
    530 	 * If the filter parameters specify the DMX_ONESHOT flag, stop
    531 	 * the demux after one PSI section is received.
    532 	 */
    533 	if (demux->dd_secfilt.params.flags & DMX_ONESHOT)
    534 		dtv_demux_stop(demux);
    535 
    536 	/*
    537 	 * Copy the PSI section to userspace. If the receiving buffer is
    538 	 * too small, the rest of the payload will be discarded. Although
    539 	 * this behaviour differs from the Linux implementation, in practice
    540 	 * it should not be an issue as PSI sections have a max size of 4KB
    541 	 * (and callers will generally provide a big enough buffer).
    542 	 */
    543 	return uiomove(sec.sec_buf, sec.sec_length, uio);
    544 }
    545 
    546 /*
    547  * Verify the CRC of a PSI section.
    548  */
    549 static bool
    550 dtv_demux_check_crc(struct dtv_demux *demux, struct dtv_ts_section *sec)
    551 {
    552 	uint32_t crc, sec_crc;
    553 
    554 	/*
    555 	 * If section_syntax_indicator is not set, the PSI section does
    556 	 * not include a CRC field.
    557 	 */
    558 	if ((sec->sec_buf[1] & 0x80) == 0)
    559 		return false;
    560 
    561 	sec_crc = be32dec(&sec->sec_buf[sec->sec_length - 4]);
    562 	crc = dtv_demux_crc32(&sec->sec_buf[0], sec->sec_length - 4);
    563 
    564 	return crc == sec_crc;
    565 }
    566 
    567 /*
    568  * Process a single TS packet and extract PSI sections based on the
    569  * instance's section filter.
    570  */
    571 static int
    572 dtv_demux_process(struct dtv_demux *demux, const uint8_t *tspkt,
    573     size_t tspktlen)
    574 {
    575 	struct dtv_ts_section *sec;
    576 	dmx_filter_t *dmxfilt = &demux->dd_secfilt.params.filter;
    577 	const uint8_t *p;
    578 	uint16_t section_length;
    579 	int brem, avail;
    580 
    581 	KASSERT(tspktlen == TS_PKTLEN);
    582 
    583 	/* If the demux instance is not running, ignore the packet */
    584 	if (demux->dd_running == false)
    585 		return 0;
    586 
    587 	/*
    588 	 * If the demux instance is not in section filter mode, ignore
    589 	 * the packet
    590 	 */
    591 	if (demux->dd_mode != DTV_DEMUX_MODE_SECTION)
    592 		return 0;
    593 	/*
    594 	 * If the packet's TS PID does not match the section filter PID,
    595 	 * ignore the packet
    596 	 */
    597 	if (TS_PID(tspkt) != demux->dd_secfilt.params.pid)
    598 		return 0;
    599 	/*
    600 	 * If the TS packet does not contain a payload, ignore the packet
    601 	 */
    602 	if (TS_HAS_PAYLOAD(tspkt) == 0)
    603 		return 0;
    604 
    605 	mutex_enter(&demux->dd_lock);
    606 
    607 	/* If the section buffer is full, set the overflow flag and return */
    608 	if (demux->dd_secfilt.nsections ==
    609 	    __arraycount(demux->dd_secfilt.section)) {
    610 		demux->dd_secfilt.overflow = true;
    611 		goto done;
    612 	}
    613 	sec = &demux->dd_secfilt.section[demux->dd_secfilt.wp];
    614 	/* If we have no bytes in our buffer, wait for payload unit start */
    615 	if (sec->sec_bytesused == 0 && TS_HAS_PUSI(tspkt) == 0)
    616 		goto done;
    617 
    618 	/* find payload start */
    619 	p = tspkt + 4;
    620 	if (TS_HAS_AF(tspkt)) {
    621 		if (*p > 182)	/* AF length with payload is between 0-182 */
    622 			goto done;
    623 		p += (1 + *p);
    624 	}
    625 	if (TS_HAS_PUSI(tspkt)) {
    626 		p += (1 + *p);
    627 	}
    628 
    629 	brem = tspktlen - (p - tspkt);
    630 
    631 	if (TS_HAS_PUSI(tspkt)) {
    632 		if (brem < 16)
    633 			goto done;
    634 
    635 		section_length = ((p[1] & 0xf) << 8) | p[2];
    636 
    637 		/* table_id filter */
    638 		if (dmxfilt->mask[0]) {
    639 			if ((p[0] & dmxfilt->mask[0]) != dmxfilt->filter[0])
    640 				goto done;
    641 		}
    642 		/* table_id_ext filter */
    643 		if (dmxfilt->mask[1] && dmxfilt->mask[2]) {
    644 			/*
    645 			 * table_id_ext is only valid if
    646 			 * section_syntax_indicator is set
    647 			 */
    648 			if (section_length < 2 || (p[1] & 0x80) == 0)
    649 				goto done;
    650 			if ((p[3] & dmxfilt->mask[1]) != dmxfilt->filter[1])
    651 				goto done;
    652 			if ((p[4] & dmxfilt->mask[2]) != dmxfilt->filter[2])
    653 				goto done;
    654 		}
    655 
    656 		sec->sec_length = section_length + 3;
    657 
    658 		/* maximum section length is 4KB */
    659 		if (sec->sec_length > sizeof(sec->sec_buf)) {
    660 			sec->sec_bytesused = sec->sec_length = 0;
    661 			goto done;
    662 		}
    663 
    664 	}
    665 
    666 	/* If we have bytes pending and we see payload unit start, flush buf */
    667 	if (sec->sec_bytesused > 0 && TS_HAS_PUSI(tspkt))
    668 		sec->sec_bytesused = sec->sec_length = 0;
    669 
    670 	/* Copy data into section buffer */
    671 	avail = uimin(sec->sec_length - sec->sec_bytesused, brem);
    672 	if (avail < 0)
    673 		goto done;
    674 	memcpy(&sec->sec_buf[sec->sec_bytesused], p, avail);
    675 	sec->sec_bytesused += avail;
    676 
    677 	/*
    678 	 * If a complete section has been received, update section count
    679 	 * and notify readers.
    680 	 */
    681 	if (sec->sec_bytesused == sec->sec_length) {
    682 		/*
    683 		 * If the DMX_CHECK_CRC flag was present in the DMX_SET_FILTER
    684 		 * parameters, verify the PSI section checksum. If the
    685 		 * checksum is invalid, discard the entire corrupt section.
    686 		 */
    687 		if ((demux->dd_secfilt.params.flags & DMX_CHECK_CRC) &&
    688 		    dtv_demux_check_crc(demux, sec) == false) {
    689 			/* discard section */
    690 			sec->sec_bytesused = sec->sec_length = 0;
    691 			goto done;
    692 		}
    693 
    694 		demux->dd_secfilt.wp++;
    695 		if (demux->dd_secfilt.wp >=
    696 		    __arraycount(demux->dd_secfilt.section))
    697 			demux->dd_secfilt.wp = 0;
    698 		demux->dd_secfilt.nsections++;
    699 		cv_broadcast(&demux->dd_section_cv);
    700 		selnotify(&demux->dd_sel, 0, 0);
    701 	}
    702 
    703 done:
    704 	mutex_exit(&demux->dd_lock);
    705 	return 0;
    706 }
    707 
    708 /*
    709  * Submit TS data to all demux instances
    710  */
    711 void
    712 dtv_demux_write(struct dtv_softc *sc, const uint8_t *tspkt, size_t tspktlen)
    713 {
    714 	struct dtv_demux *demux;
    715 
    716 	mutex_enter(&sc->sc_demux_lock);
    717 	TAILQ_FOREACH(demux, &sc->sc_demux_list, dd_entries) {
    718 		dtv_demux_process(demux, tspkt, tspktlen);
    719 	}
    720 	mutex_exit(&sc->sc_demux_lock);
    721 }
    722