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