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