Home | History | Annotate | Line # | Download | only in dtv
dtv_demux.c revision 1.4
      1 /* $NetBSD: dtv_demux.c,v 1.4 2011/07/16 12:20:01 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.4 2011/07/16 12:20:01 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_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 	if (demux == NULL)
    303 		return ENOMEM;
    304 	demux->dd_sc = sc;
    305 	/* Default operation mode is unconfigured */
    306 	demux->dd_mode = DTV_DEMUX_MODE_NONE;
    307 	selinit(&demux->dd_sel);
    308 	mutex_init(&demux->dd_lock, MUTEX_DEFAULT, IPL_VM);
    309 	cv_init(&demux->dd_section_cv, "dtvsec");
    310 
    311 	error = fd_allocfile(&fp, &fd);
    312 	if (error) {
    313 		kmem_free(demux, sizeof(*demux));
    314 		return error;
    315 	}
    316 
    317 	/* Add the demux to the list of demux instances */
    318 	mutex_enter(&sc->sc_demux_lock);
    319 	TAILQ_INSERT_TAIL(&sc->sc_demux_list, demux, dd_entries);
    320 	mutex_exit(&sc->sc_demux_lock);
    321 
    322 	return fd_clone(fp, fd, flags, &dtv_demux_fileops, demux);
    323 }
    324 
    325 /*
    326  * Close the instance of the demux cloning device.
    327  */
    328 int
    329 dtv_demux_close(struct file *fp)
    330 {
    331 	struct dtv_demux *demux = fp->f_data;
    332 	struct dtv_softc *sc;
    333 	int error;
    334 
    335 	if (demux == NULL)
    336 		return ENXIO;
    337 
    338 	fp->f_data = NULL;
    339 
    340 	sc = demux->dd_sc;
    341 
    342 	/* If the demux is still running, stop it */
    343 	if (demux->dd_running) {
    344 		error = dtv_demux_stop(demux);
    345 		if (error)
    346 			return error;
    347 	}
    348 
    349 	/* Remove the demux from the list of demux instances */
    350 	mutex_enter(&sc->sc_demux_lock);
    351 	TAILQ_REMOVE(&sc->sc_demux_list, demux, dd_entries);
    352 	mutex_exit(&sc->sc_demux_lock);
    353 
    354 	mutex_destroy(&demux->dd_lock);
    355 	cv_destroy(&demux->dd_section_cv);
    356 	kmem_free(demux, sizeof(*demux));
    357 
    358 	/* Update the global device open count */
    359 	dtv_common_close(sc);
    360 
    361 	return 0;
    362 }
    363 
    364 /*
    365  * Handle demux ioctl requests
    366  */
    367 static int
    368 dtv_demux_ioctl(struct file *fp, u_long cmd, void *data)
    369 {
    370 	struct dtv_demux *demux = fp->f_data;
    371 	struct dtv_softc *sc;
    372 	struct dmx_pes_filter_params *pesfilt;
    373 	struct dmx_sct_filter_params *sctfilt;
    374 	uint16_t pid;
    375 	int error;
    376 
    377 	if (demux == NULL)
    378 		return ENXIO;
    379 	sc = demux->dd_sc;
    380 
    381 	switch (cmd) {
    382 	case DMX_START:
    383 		return dtv_demux_start(demux);
    384 	case DMX_STOP:
    385 		return dtv_demux_stop(demux);
    386 	case DMX_SET_BUFFER_SIZE:
    387 		/*
    388 		 * The demux driver doesn't support configurable buffer sizes,
    389 		 * but software relies on this command succeeding.
    390 		 */
    391 		return 0;
    392 	case DMX_SET_FILTER:
    393 		sctfilt = data;
    394 
    395 		/* Verify that the requested PID is in range. */
    396 		if (sctfilt->pid >= 0x2000)
    397 			return EINVAL;
    398 
    399 		/*
    400 		 * Update section filter parameters, reset read/write ptrs,
    401 		 * clear section count and overflow flag, and set the
    402 		 * demux instance mode to section filter.
    403 		 */
    404 		demux->dd_secfilt.params = *sctfilt;
    405 		demux->dd_secfilt.rp = demux->dd_secfilt.wp = 0;
    406 		demux->dd_secfilt.nsections = 0;
    407 		demux->dd_secfilt.overflow = false;
    408 		demux->dd_mode = DTV_DEMUX_MODE_SECTION;
    409 
    410 		/*
    411 		 * If the DMX_IMMEDIATE_START flag is present in the request,
    412 		 * start running the demux immediately (no need for a
    413 		 * subsequent DMX_START ioctl).
    414 		 */
    415 		if (sctfilt->flags & DMX_IMMEDIATE_START) {
    416 			error = dtv_demux_start(demux);
    417 			if (error)
    418 				return error;
    419 		}
    420 
    421 		return 0;
    422 	case DMX_SET_PES_FILTER:
    423 		pesfilt = data;
    424 
    425 		/* The driver only supports input from the frontend */
    426 		if (pesfilt->input != DMX_IN_FRONTEND)
    427 			return EINVAL;
    428 		/*
    429 		 * The driver only supports output to the TS TAP in PID
    430 		 * filter mode.
    431 		 */
    432 		if (pesfilt->output != DMX_OUT_TS_TAP)
    433 			return EINVAL;
    434 
    435 		/* Update PID filter table */
    436 		error = dtv_demux_set_pidfilter(demux, pesfilt->pid, true);
    437 		if (error)
    438 			return error;
    439 
    440 		/*
    441 		 * If the DMX_IMMEDIATE_START flag is present in the request,
    442 		 * start running the demux immediately (no need for a
    443 		 * subsequent DMX_START ioctl).
    444 		 */
    445 		if (pesfilt->flags & DMX_IMMEDIATE_START) {
    446 			error = dtv_demux_start(demux);
    447 			if (error)
    448 				return error;
    449 		}
    450 		return 0;
    451 	case DMX_ADD_PID:
    452 		pid = *(uint16_t *)data;
    453 		return dtv_demux_set_pidfilter(demux, pid, true);
    454 	case DMX_REMOVE_PID:
    455 		pid = *(uint16_t *)data;
    456 		return dtv_demux_set_pidfilter(demux, pid, false);
    457 	default:
    458 		return EINVAL;
    459 	}
    460 }
    461 
    462 /*
    463  * Test for I/O readiness
    464  */
    465 static int
    466 dtv_demux_poll(struct file *fp, int events)
    467 {
    468 	struct dtv_demux *demux = fp->f_data;
    469 	int revents = 0;
    470 
    471 	if (demux == NULL)
    472 		return POLLERR;
    473 
    474 	/*
    475 	 * If the demux instance is in section filter mode, wait for an
    476 	 * entire section to become ready.
    477 	 */
    478 	mutex_enter(&demux->dd_lock);
    479 	if (demux->dd_mode == DTV_DEMUX_MODE_SECTION &&
    480 	    demux->dd_secfilt.nsections > 0) {
    481 		revents |= POLLIN;
    482 	} else {
    483 		selrecord(curlwp, &demux->dd_sel);
    484 	}
    485 	mutex_exit(&demux->dd_lock);
    486 
    487 	return revents;
    488 }
    489 
    490 /*
    491  * Read from the demux instance
    492  */
    493 static int
    494 dtv_demux_read(struct file *fp, off_t *offp, struct uio *uio,
    495     kauth_cred_t cred, int flags)
    496 {
    497 	struct dtv_demux *demux = fp->f_data;
    498 	struct dtv_ts_section sec;
    499 	int error;
    500 
    501 	if (demux == NULL)
    502 		return ENXIO;
    503 
    504 	/* Only support read if the instance is in section filter mode */
    505 	if (demux->dd_mode != DTV_DEMUX_MODE_SECTION)
    506 		return EIO;
    507 
    508 	/* Wait for a complete PSI section */
    509 	mutex_enter(&demux->dd_lock);
    510 	while (demux->dd_secfilt.nsections == 0) {
    511 		if (flags & IO_NDELAY) {
    512 			mutex_exit(&demux->dd_lock);
    513 			/* No data available */
    514 			return EWOULDBLOCK;
    515 		}
    516 		error = cv_wait_sig(&demux->dd_section_cv, &demux->dd_lock);
    517 		if (error) {
    518 			mutex_exit(&demux->dd_lock);
    519 			return error;
    520 		}
    521 	}
    522 	/* Copy the completed PSI section */
    523 	sec = demux->dd_secfilt.section[demux->dd_secfilt.rp];
    524 	/* Update read pointer */
    525 	demux->dd_secfilt.rp++;
    526 	if (demux->dd_secfilt.rp >= __arraycount(demux->dd_secfilt.section))
    527 		demux->dd_secfilt.rp = 0;
    528 	/* Update section count */
    529 	demux->dd_secfilt.nsections--;
    530 	mutex_exit(&demux->dd_lock);
    531 
    532 	/*
    533 	 * If the filter parameters specify the DMX_ONESHOT flag, stop
    534 	 * the demux after one PSI section is received.
    535 	 */
    536 	if (demux->dd_secfilt.params.flags & DMX_ONESHOT)
    537 		dtv_demux_stop(demux);
    538 
    539 	/*
    540 	 * Copy the PSI section to userspace. If the receiving buffer is
    541 	 * too small, the rest of the payload will be discarded. Although
    542 	 * this behaviour differs from the Linux implementation, in practice
    543 	 * it should not be an issue as PSI sections have a max size of 4KB
    544 	 * (and callers will generally provide a big enough buffer).
    545 	 */
    546 	return uiomove(sec.sec_buf, sec.sec_length, uio);
    547 }
    548 
    549 /*
    550  * Verify the CRC of a PSI section.
    551  */
    552 static bool
    553 dtv_demux_check_crc(struct dtv_demux *demux, struct dtv_ts_section *sec)
    554 {
    555 	uint32_t crc, sec_crc;
    556 
    557 	/*
    558 	 * If section_syntax_indicator is not set, the PSI section does
    559 	 * not include a CRC field.
    560 	 */
    561 	if ((sec->sec_buf[1] & 0x80) == 0)
    562 		return false;
    563 
    564 	sec_crc = be32dec(&sec->sec_buf[sec->sec_length - 4]);
    565 	crc = dtv_demux_crc32(&sec->sec_buf[0], sec->sec_length - 4);
    566 
    567 	return crc == sec_crc;
    568 }
    569 
    570 /*
    571  * Process a single TS packet and extract PSI sections based on the
    572  * instance's section filter.
    573  */
    574 static int
    575 dtv_demux_process(struct dtv_demux *demux, const uint8_t *tspkt,
    576     size_t tspktlen)
    577 {
    578 	struct dtv_ts_section *sec;
    579 	dmx_filter_t *dmxfilt = &demux->dd_secfilt.params.filter;
    580 	const uint8_t *p;
    581 	uint16_t section_length;
    582 	int brem, avail;
    583 
    584 	KASSERT(tspktlen == TS_PKTLEN);
    585 
    586 	/* If the demux instance is not running, ignore the packet */
    587 	if (demux->dd_running == false)
    588 		return 0;
    589 
    590 	/*
    591 	 * If the demux instance is not in section filter mode, ignore
    592 	 * the packet
    593 	 */
    594 	if (demux->dd_mode != DTV_DEMUX_MODE_SECTION)
    595 		return 0;
    596 	/*
    597 	 * If the packet's TS PID does not match the section filter PID,
    598 	 * ignore the packet
    599 	 */
    600 	if (TS_PID(tspkt) != demux->dd_secfilt.params.pid)
    601 		return 0;
    602 	/*
    603 	 * If the TS packet does not contain a payload, ignore the packet
    604 	 */
    605 	if (TS_HAS_PAYLOAD(tspkt) == 0)
    606 		return 0;
    607 
    608 	mutex_enter(&demux->dd_lock);
    609 
    610 	/* If the section buffer is full, set the overflow flag and return */
    611 	if (demux->dd_secfilt.nsections ==
    612 	    __arraycount(demux->dd_secfilt.section)) {
    613 		demux->dd_secfilt.overflow = true;
    614 		goto done;
    615 	}
    616 	sec = &demux->dd_secfilt.section[demux->dd_secfilt.wp];
    617 	/* If we have no bytes in our buffer, wait for payload unit start */
    618 	if (sec->sec_bytesused == 0 && TS_HAS_PUSI(tspkt) == 0)
    619 		goto done;
    620 
    621 	/* find payload start */
    622 	p = tspkt + 4;
    623 	if (TS_HAS_AF(tspkt)) {
    624 		if (*p > 182)	/* AF length with payload is between 0-182 */
    625 			goto done;
    626 		p += (1 + *p);
    627 	}
    628 	if (TS_HAS_PUSI(tspkt)) {
    629 		p += (1 + *p);
    630 	}
    631 
    632 	brem = tspktlen - (p - tspkt);
    633 
    634 	if (TS_HAS_PUSI(tspkt)) {
    635 		if (brem < 16)
    636 			goto done;
    637 
    638 		section_length = ((p[1] & 0xf) << 8) | p[2];
    639 
    640 		/* table_id filter */
    641 		if (dmxfilt->mask[0]) {
    642 			if ((p[0] & dmxfilt->mask[0]) != dmxfilt->filter[0])
    643 				goto done;
    644 		}
    645 		/* table_id_ext filter */
    646 		if (dmxfilt->mask[1] && dmxfilt->mask[2]) {
    647 			/*
    648 			 * table_id_ext is only valid if
    649 			 * section_syntax_indicator is set
    650 			 */
    651 			if (section_length < 2 || (p[1] & 0x80) == 0)
    652 				goto done;
    653 			if ((p[3] & dmxfilt->mask[1]) != dmxfilt->filter[1])
    654 				goto done;
    655 			if ((p[4] & dmxfilt->mask[2]) != dmxfilt->filter[2])
    656 				goto done;
    657 		}
    658 
    659 		sec->sec_length = section_length + 3;
    660 
    661 		/* maximum section length is 4KB */
    662 		if (sec->sec_length > sizeof(sec->sec_buf)) {
    663 			sec->sec_bytesused = sec->sec_length = 0;
    664 			goto done;
    665 		}
    666 
    667 	}
    668 
    669 	/* If we have bytes pending and we see payload unit start, flush buf */
    670 	if (sec->sec_bytesused > 0 && TS_HAS_PUSI(tspkt))
    671 		sec->sec_bytesused = sec->sec_length = 0;
    672 
    673 	/* Copy data into section buffer */
    674 	avail = min(sec->sec_length - sec->sec_bytesused, brem);
    675 	if (avail < 0)
    676 		goto done;
    677 	memcpy(&sec->sec_buf[sec->sec_bytesused], p, avail);
    678 	sec->sec_bytesused += avail;
    679 
    680 	/*
    681 	 * If a complete section has been received, update section count
    682 	 * and notify readers.
    683 	 */
    684 	if (sec->sec_bytesused == sec->sec_length) {
    685 		/*
    686 		 * If the DMX_CHECK_CRC flag was present in the DMX_SET_FILTER
    687 		 * parameters, verify the PSI section checksum. If the
    688 		 * checksum is invalid, discard the entire corrupt section.
    689 		 */
    690 		if ((demux->dd_secfilt.params.flags & DMX_CHECK_CRC) &&
    691 		    dtv_demux_check_crc(demux, sec) == false) {
    692 			/* discard section */
    693 			sec->sec_bytesused = sec->sec_length = 0;
    694 			goto done;
    695 		}
    696 
    697 		demux->dd_secfilt.wp++;
    698 		if (demux->dd_secfilt.wp >=
    699 		    __arraycount(demux->dd_secfilt.section))
    700 			demux->dd_secfilt.wp = 0;
    701 		demux->dd_secfilt.nsections++;
    702 		cv_broadcast(&demux->dd_section_cv);
    703 		selnotify(&demux->dd_sel, 0, 0);
    704 	}
    705 
    706 done:
    707 	mutex_exit(&demux->dd_lock);
    708 	return 0;
    709 }
    710 
    711 /*
    712  * Submit TS data to all demux instances
    713  */
    714 void
    715 dtv_demux_write(struct dtv_softc *sc, const uint8_t *tspkt, size_t tspktlen)
    716 {
    717 	struct dtv_demux *demux;
    718 
    719 	mutex_enter(&sc->sc_demux_lock);
    720 	TAILQ_FOREACH(demux, &sc->sc_demux_list, dd_entries) {
    721 		dtv_demux_process(demux, tspkt, tspktlen);
    722 	}
    723 	mutex_exit(&sc->sc_demux_lock);
    724 }
    725