Module Name:    src
Committed By:   jmcneill
Date:           Sat Jul  9 14:46:56 UTC 2011

Added Files:
        src/sys/dev/dtv: Makefile dtv_buffer.c dtv_device.c dtv_ioctl.c
            dtv_scatter.c dtv_scatter.h dtvif.h dtvio.h dtvio_demux.h
            dtvio_frontend.h dtvmodule.h dtvvar.h files.dtv

Log Message:
add digital TV framework which implements a subset of Linux DVB APIs


To generate a diff of this commit:
cvs rdiff -u -r0 -r1.1 src/sys/dev/dtv/Makefile src/sys/dev/dtv/dtv_buffer.c \
    src/sys/dev/dtv/dtv_device.c src/sys/dev/dtv/dtv_ioctl.c \
    src/sys/dev/dtv/dtv_scatter.c src/sys/dev/dtv/dtv_scatter.h \
    src/sys/dev/dtv/dtvif.h src/sys/dev/dtv/dtvio.h \
    src/sys/dev/dtv/dtvio_demux.h src/sys/dev/dtv/dtvio_frontend.h \
    src/sys/dev/dtv/dtvmodule.h src/sys/dev/dtv/dtvvar.h \
    src/sys/dev/dtv/files.dtv

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Added files:

Index: src/sys/dev/dtv/Makefile
diff -u /dev/null src/sys/dev/dtv/Makefile:1.1
--- /dev/null	Sat Jul  9 14:46:56 2011
+++ src/sys/dev/dtv/Makefile	Sat Jul  9 14:46:56 2011
@@ -0,0 +1,6 @@
+# $NetBSD: Makefile,v 1.1 2011/07/09 14:46:56 jmcneill Exp $
+
+INCSDIR= /usr/include/dev/dtv
+INCS=	dtvio.h dtvio_frontend.h dtvio_demux.h
+
+.include <bsd.kinc.mk>
Index: src/sys/dev/dtv/dtv_buffer.c
diff -u /dev/null src/sys/dev/dtv/dtv_buffer.c:1.1
--- /dev/null	Sat Jul  9 14:46:56 2011
+++ src/sys/dev/dtv/dtv_buffer.c	Sat Jul  9 14:46:56 2011
@@ -0,0 +1,315 @@
+/* $NetBSD: dtv_buffer.c,v 1.1 2011/07/09 14:46:56 jmcneill Exp $ */
+
+/*-
+ * Copyright (c) 2011 Jared D. McNeill <jmcne...@invisible.ca>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *        This product includes software developed by Jared D. McNeill.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: dtv_buffer.c,v 1.1 2011/07/09 14:46:56 jmcneill Exp $");
+
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/types.h>
+#include <sys/conf.h>
+#include <sys/device.h>
+#include <sys/vnode.h>
+#include <sys/poll.h>
+#include <sys/select.h>
+
+#include <dev/dtv/dtvvar.h>
+
+#define	PAGE_ALIGN(a)	(((a) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1))
+
+static void
+dtv_buffer_write(struct dtv_softc *sc, const uint8_t *buf, size_t buflen)
+{
+	struct dtv_stream *ds = &sc->sc_stream;
+	struct dtv_buffer *db;
+	struct dtv_scatter_io sio;
+	size_t resid = buflen, avail;
+       	off_t offset = 0;
+
+	KASSERT(buflen == TS_PKTLEN);
+
+	while (resid > 0) {
+		mutex_enter(&ds->ds_lock);
+
+		if (SIMPLEQ_EMPTY(&ds->ds_ingress)) {
+			aprint_debug_dev(sc->sc_dev,
+			    "dropping sample (%u)\n", resid);
+			mutex_exit(&ds->ds_lock);
+			return;
+		}
+
+		db = SIMPLEQ_FIRST(&ds->ds_ingress);
+		avail = min(db->db_length - db->db_bytesused, resid);
+		if (dtv_scatter_io_init(&ds->ds_data,
+		    db->db_offset + db->db_bytesused, avail, &sio)) {
+			dtv_scatter_io_copyin(&sio, buf + offset);
+			db->db_bytesused += (avail - sio.sio_resid);
+			offset += (avail - sio.sio_resid);
+			resid -= (avail - sio.sio_resid);
+		}
+
+		if (db->db_bytesused == db->db_length) {
+			SIMPLEQ_REMOVE_HEAD(&ds->ds_ingress, db_entries);
+			SIMPLEQ_INSERT_TAIL(&ds->ds_egress, db, db_entries);
+			cv_broadcast(&ds->ds_sample_cv);
+			selnotify(&ds->ds_sel, 0, 0);
+		}
+
+		mutex_exit(&ds->ds_lock);
+	}
+}
+
+void
+dtv_submit_payload(device_t self, const struct dtv_payload *payload)
+{
+	struct dtv_softc *sc = device_private(self);
+	struct dtv_ts *ts = &sc->sc_ts;
+	const uint8_t *tspkt;
+	unsigned int npkts, i;
+
+	tspkt = payload->data;
+	npkts = payload->size / TS_PKTLEN;
+	for (i = 0; i < npkts; i++) {
+		if (TS_HAS_SYNC(tspkt) && ts->ts_pidfilter[TS_PID(tspkt)]) {
+			dtv_buffer_write(sc, tspkt, TS_PKTLEN);
+		}
+		tspkt += TS_PKTLEN;
+	}
+}
+
+static struct dtv_buffer *
+dtv_buffer_alloc(void)
+{
+	return kmem_alloc(sizeof(struct dtv_buffer), KM_SLEEP);
+}
+
+static void
+dtv_buffer_free(struct dtv_buffer *db)
+{
+	kmem_free(db, sizeof(*db));
+}
+
+static int
+dtv_buffer_realloc(struct dtv_softc *sc, size_t bufsize)
+{
+	struct dtv_stream *ds = &sc->sc_stream;
+	unsigned int i, nbufs, oldnbufs, minnbufs;
+	struct dtv_buffer **oldbuf;
+	off_t offset;
+	int error;
+
+	nbufs = PAGE_ALIGN(bufsize) / PAGE_SIZE;
+
+	error = dtv_scatter_buf_set_size(&ds->ds_data, bufsize);
+	if (error)
+		return error;
+
+	oldnbufs = ds->ds_nbufs;
+	oldbuf = ds->ds_buf;
+
+	ds->ds_nbufs = nbufs;
+	if (nbufs > 0) {
+		ds->ds_buf = kmem_alloc(sizeof(struct dtv_buffer *) * nbufs,
+		    KM_SLEEP);
+		if (ds->ds_buf == NULL) {
+			ds->ds_nbufs = oldnbufs;
+			ds->ds_buf = oldbuf;
+			return ENOMEM;
+		}
+	} else {
+		ds->ds_buf = NULL;
+	}
+
+	minnbufs = min(nbufs, oldnbufs);
+	for (i = 0; i < minnbufs; i++)
+		ds->ds_buf[i] = oldbuf[i];
+	for (; i < nbufs; i++)
+		ds->ds_buf[i] = dtv_buffer_alloc();
+	for (; i < oldnbufs; i++) {
+		dtv_buffer_free(oldbuf[i]);
+		oldbuf[i] = NULL;
+	}
+	if (oldbuf != NULL)
+		kmem_free(oldbuf, sizeof(struct dtv_buffer *) * oldnbufs);
+
+	offset = 0;
+	for (i = 0; i < nbufs; i++) {
+		ds->ds_buf[i]->db_offset = offset;
+		ds->ds_buf[i]->db_bytesused = 0;
+		ds->ds_buf[i]->db_length = PAGE_SIZE;
+		offset += PAGE_SIZE;
+	}
+
+	return 0;
+}
+
+static struct dtv_buffer *
+dtv_stream_dequeue(struct dtv_stream *ds)
+{
+	struct dtv_buffer *db;
+
+	if (!SIMPLEQ_EMPTY(&ds->ds_egress)) {
+		db = SIMPLEQ_FIRST(&ds->ds_egress);
+		SIMPLEQ_REMOVE_HEAD(&ds->ds_egress, db_entries);
+		return db;
+	}
+
+	return NULL;
+}
+
+static void
+dtv_stream_enqueue(struct dtv_stream *ds, struct dtv_buffer *db)
+{
+	db->db_bytesused = 0;
+	SIMPLEQ_INSERT_TAIL(&ds->ds_ingress, db, db_entries);
+}
+
+int
+dtv_buffer_setup(struct dtv_softc *sc, size_t bufsize)
+{
+	struct dtv_stream *ds = &sc->sc_stream;
+	unsigned int i;
+	int error;
+
+	mutex_enter(&ds->ds_lock);
+
+	error = dtv_buffer_realloc(sc, PAGE_ALIGN(bufsize));
+	if (error) {
+		mutex_exit(&ds->ds_lock);
+		return error;
+	}
+
+	for (i = 0; i < ds->ds_nbufs; i++)
+		dtv_stream_enqueue(ds, ds->ds_buf[i]);
+
+	mutex_exit(&ds->ds_lock);
+
+	return 0;
+}
+
+int
+dtv_buffer_destroy(struct dtv_softc *sc)
+{
+	struct dtv_stream *ds = &sc->sc_stream;
+
+	mutex_enter(&ds->ds_lock);
+
+	while (SIMPLEQ_FIRST(&ds->ds_ingress))
+		SIMPLEQ_REMOVE_HEAD(&ds->ds_ingress, db_entries);
+	while (SIMPLEQ_FIRST(&ds->ds_egress))
+		SIMPLEQ_REMOVE_HEAD(&ds->ds_egress, db_entries);
+	dtv_buffer_realloc(sc, 0);
+
+	mutex_exit(&ds->ds_lock);
+
+	return 0;
+}
+
+int
+dtv_buffer_read(struct dtv_softc *sc, struct uio *uio, int flags)
+{
+	struct dtv_stream *ds = &sc->sc_stream;
+	struct dtv_buffer *db;
+	struct dtv_scatter_io sio;
+	off_t offset;
+	size_t len, bread = 0;
+	int error;
+
+	while (uio->uio_resid > 0) {
+		mutex_enter(&ds->ds_lock);
+
+retry:
+		while (SIMPLEQ_EMPTY(&ds->ds_egress)) {
+			if (flags & IO_NDELAY) {
+				mutex_exit(&ds->ds_lock);
+				return bread ? 0 : EWOULDBLOCK;
+			}
+
+			error = cv_wait_sig(&ds->ds_sample_cv, &ds->ds_lock);
+			if (error) {
+				mutex_exit(&ds->ds_lock);
+				return EINTR;
+			}
+		}
+		db = SIMPLEQ_FIRST(&ds->ds_egress);
+
+		if (db->db_bytesused == 0) {
+			db = dtv_stream_dequeue(ds);
+			dtv_stream_enqueue(ds, db);
+			ds->ds_bytesread = 0;
+			goto retry;
+		}
+
+		mutex_exit(&ds->ds_lock);
+
+		len = min(uio->uio_resid, db->db_bytesused - ds->ds_bytesread);
+		offset = db->db_offset + ds->ds_bytesread;
+
+		if (dtv_scatter_io_init(&ds->ds_data, offset, len, &sio)) {
+			error = dtv_scatter_io_uiomove(&sio, uio);
+			if (error == EFAULT)
+				return EFAULT;
+			ds->ds_bytesread += (len - sio.sio_resid);
+			bread += (len - sio.sio_resid);
+		}
+
+		if (ds->ds_bytesread >= db->db_bytesused) {
+			mutex_enter(&ds->ds_lock);
+			db = dtv_stream_dequeue(ds);
+			dtv_stream_enqueue(ds, db);
+			mutex_exit(&ds->ds_lock);
+
+			ds->ds_bytesread = 0;
+		}
+	}
+
+	return 0;
+}
+
+int
+dtv_buffer_poll(struct dtv_softc *sc, int events, lwp_t *l)
+{
+	struct dtv_stream *ds = &sc->sc_stream;
+	int revents = 0;
+
+	mutex_enter(&ds->ds_lock);
+	if (!SIMPLEQ_EMPTY(&ds->ds_egress)) {
+		revents |= (POLLIN | POLLOUT | POLLPRI);
+	} else {
+		selrecord(l, &ds->ds_sel);
+	}
+	mutex_exit(&ds->ds_lock);
+
+	return revents;
+}
Index: src/sys/dev/dtv/dtv_device.c
diff -u /dev/null src/sys/dev/dtv/dtv_device.c:1.1
--- /dev/null	Sat Jul  9 14:46:56 2011
+++ src/sys/dev/dtv/dtv_device.c	Sat Jul  9 14:46:56 2011
@@ -0,0 +1,270 @@
+/* $NetBSD: dtv_device.c,v 1.1 2011/07/09 14:46:56 jmcneill Exp $ */
+
+/*-
+ * Copyright (c) 2011 Jared D. McNeill <jmcne...@invisible.ca>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *        This product includes software developed by Jared D. McNeill.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: dtv_device.c,v 1.1 2011/07/09 14:46:56 jmcneill Exp $");
+
+#include <sys/types.h>
+#include <sys/conf.h>
+#include <sys/device.h>
+#include <sys/atomic.h>
+#include <sys/module.h>
+#include <sys/poll.h>
+#include <sys/select.h>
+
+#include <dev/dtv/dtvvar.h>
+#include <dev/dtv/dtvmodule.h>
+
+MODULE(MODULE_CLASS_DRIVER, dtv, NULL);
+
+static dev_type_open(dtvopen);
+static dev_type_close(dtvclose);
+static dev_type_read(dtvread);
+static dev_type_ioctl(dtvioctl);
+static dev_type_poll(dtvpoll);
+
+const struct cdevsw dtv_cdevsw = {
+	.d_open = dtvopen,
+	.d_close = dtvclose,
+	.d_read = dtvread,
+	.d_ioctl = dtvioctl,
+	.d_poll = dtvpoll,
+	.d_flag = D_OTHER|D_MPSAFE,
+};
+
+static int	dtv_match(device_t, cfdata_t, void *);
+static void	dtv_attach(device_t, device_t, void *);
+static int	dtv_detach(device_t, int);
+
+CFATTACH_DECL_NEW(dtv,
+    sizeof(struct dtv_softc),
+    dtv_match,
+    dtv_attach,
+    dtv_detach,
+    NULL
+);
+
+static int
+dtv_match(device_t parent, cfdata_t cfdata, void *aa)
+{
+	return 1;
+}
+
+static void
+dtv_attach(device_t parent, device_t self, void *aa)
+{
+	struct dtv_attach_args *daa = aa;
+	struct dtv_softc *sc = device_private(self);
+	struct dtv_stream *ds = &sc->sc_stream;
+	struct dvb_frontend_info info;
+
+	sc->sc_dev = self;
+	sc->sc_hw = daa->hw;
+	sc->sc_priv = daa->priv;
+	atomic_swap_uint(&sc->sc_open, 0);
+
+	ds->ds_nbufs = 0;
+	ds->ds_buf = NULL;
+	SIMPLEQ_INIT(&ds->ds_ingress);
+	SIMPLEQ_INIT(&ds->ds_egress);
+	mutex_init(&ds->ds_lock, MUTEX_DEFAULT, IPL_VM);
+	cv_init(&ds->ds_sample_cv, "dtv");
+	selinit(&ds->ds_sel);
+	dtv_scatter_buf_init(&ds->ds_data);
+
+	dtv_device_get_devinfo(sc, &info);
+
+	aprint_naive("\n");
+	aprint_normal(": '%s'", info.name);
+	switch (info.type) {
+	case FE_QPSK:
+		aprint_normal(" [QPSK]");
+		break;
+	case FE_QAM:
+		aprint_normal(" [QAM]");
+		break;
+	case FE_OFDM:
+		aprint_normal(" [OFDM]");
+		break;
+	case FE_ATSC:
+		aprint_normal(" [ATSC]");
+		break;
+	}
+	aprint_normal("\n");
+}
+
+static int
+dtv_detach(device_t self, int flags)
+{
+	struct dtv_softc *sc = device_private(self);
+	struct dtv_stream *ds = &sc->sc_stream;
+
+	cv_destroy(&ds->ds_sample_cv);
+	mutex_destroy(&ds->ds_lock);
+	seldestroy(&ds->ds_sel);
+	dtv_scatter_buf_destroy(&ds->ds_data);
+
+	return 0;
+}
+
+static int
+dtv_modcmd(modcmd_t cmd, void *arg)
+{
+	int error, bmaj = -1, cmaj = -1;
+
+	switch (cmd) {
+	case MODULE_CMD_INIT:
+		error = config_init_component(cfdriver_ioconf_dtv,
+		    cfattach_ioconf_dtv, cfdata_ioconf_dtv);
+		if (error)
+			return error;
+		error = devsw_attach("dtv", NULL, &bmaj, &dtv_cdevsw, &cmaj);
+		if (error)
+			config_fini_component(cfdriver_ioconf_dtv,
+			    cfattach_ioconf_dtv, cfdata_ioconf_dtv);
+		return error;
+	case MODULE_CMD_FINI:
+		devsw_detach(NULL, &dtv_cdevsw);
+		return config_fini_component(cfdriver_ioconf_dtv,
+		    cfattach_ioconf_dtv, cfdata_ioconf_dtv);
+	default:
+		return ENOTTY;
+	}
+}
+
+static int
+dtvopen(dev_t dev, int flags, int mode, lwp_t *l)
+{
+	struct dtv_softc *sc;
+	struct dtv_ts *ts;
+	unsigned int n;
+	int error;
+
+	if ((sc = device_lookup_private(&dtv_cd, DTVUNIT(dev))) == NULL)
+		return ENXIO;
+	if (sc->sc_dying == true)
+		return ENODEV;
+	ts = &sc->sc_ts;
+
+	n = atomic_cas_uint(&sc->sc_open, 0, 1);
+	if (n == 0) {
+		error = dtv_device_open(sc, flags);
+		if (error) {
+			atomic_swap_uint(&sc->sc_open, 0);
+			return error;
+		}
+		sc->sc_bufsize = DTV_DEFAULT_BUFSIZE;
+		sc->sc_bufsize_chg = true;
+		memset(ts->ts_pidfilter, 0, sizeof(ts->ts_pidfilter));
+	}
+
+	return 0;
+}
+
+static int
+dtvclose(dev_t dev, int flags, int mode, lwp_t *l)
+{
+	struct dtv_softc *sc;
+
+	if ((sc = device_lookup_private(&dtv_cd, DTVUNIT(dev))) == NULL)
+		return ENXIO;
+
+	dtv_device_close(sc);
+	dtv_buffer_destroy(sc);
+	atomic_swap_uint(&sc->sc_open, 0);
+
+	return 0;
+}
+
+static int
+dtvread(dev_t dev, struct uio *uio, int flags)
+{
+	struct dtv_softc *sc;
+
+	if ((sc = device_lookup_private(&dtv_cd, DTVUNIT(dev))) == NULL)
+		return ENXIO;
+
+	if (ISDTVDVR(dev))
+		return dtv_buffer_read(sc, uio, flags);
+
+	return ENXIO;
+}
+
+static int
+dtvioctl(dev_t dev, u_long cmd, void *ptr, int flags, lwp_t *l)
+{
+	struct dtv_softc *sc;
+
+	if ((sc = device_lookup_private(&dtv_cd, DTVUNIT(dev))) == NULL)
+		return ENXIO;
+
+	if (ISDTVFRONTEND(dev)) {
+		return dtv_frontend_ioctl(sc, cmd, ptr, flags);
+	} else if (ISDTVDEMUX(dev)) {
+		return dtv_demux_ioctl(sc, cmd, ptr, flags);
+	}
+
+	return EINVAL;
+}
+
+static int
+dtvpoll(dev_t dev, int events, lwp_t *l)
+{
+	struct dtv_softc *sc;
+
+	if ((sc = device_lookup_private(&dtv_cd, DTVUNIT(dev))) == NULL)
+		return POLLERR;
+
+	if (ISDTVFRONTEND(dev)) {
+		return POLLPRI|POLLIN; /* XXX event */
+	} else if (ISDTVDEMUX(dev)) {
+		return POLLIN|POLLOUT; /* XXX */
+	} else if (ISDTVDVR(dev)) {
+		return dtv_buffer_poll(sc, events, l);
+	}
+
+	printf("%s: DTVDEV = 0x%x, events = 0x%x\n",
+	    __func__, DTVDEV(dev), events);
+
+	return POLLERR;
+}
+
+int
+dtv_print(void *arg, const char *pnp)
+{
+	if (pnp)
+		aprint_normal("dtv at %s", pnp);
+
+	return UNCONF;
+}
Index: src/sys/dev/dtv/dtv_ioctl.c
diff -u /dev/null src/sys/dev/dtv/dtv_ioctl.c:1.1
--- /dev/null	Sat Jul  9 14:46:56 2011
+++ src/sys/dev/dtv/dtv_ioctl.c	Sat Jul  9 14:46:56 2011
@@ -0,0 +1,146 @@
+/* $NetBSD: dtv_ioctl.c,v 1.1 2011/07/09 14:46:56 jmcneill Exp $ */
+
+/*-
+ * Copyright (c) 2011 Jared D. McNeill <jmcne...@invisible.ca>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *        This product includes software developed by Jared D. McNeill.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: dtv_ioctl.c,v 1.1 2011/07/09 14:46:56 jmcneill Exp $");
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/conf.h>
+#include <sys/kmem.h>
+#include <sys/device.h>
+#include <sys/select.h>
+
+#include <dev/dtv/dtvvar.h>
+
+int
+dtv_frontend_ioctl(struct dtv_softc *sc, u_long cmd, void *data, int flags)
+{
+	switch (cmd) {
+	case FE_READ_STATUS:
+		*(fe_status_t *)data = dtv_device_get_status(sc);
+		return 0;
+	case FE_READ_BER:
+		*(uint32_t *)data = 0;	/* XXX TODO */
+		return 0;
+	case FE_READ_SNR:
+		*(uint16_t *)data = dtv_device_get_snr(sc);
+		return 0;
+	case FE_READ_SIGNAL_STRENGTH:
+		*(uint16_t *)data = dtv_device_get_signal_strength(sc);
+		return 0;
+	case FE_SET_FRONTEND:
+		return dtv_device_set_tuner(sc, data);
+	case FE_GET_INFO:
+		dtv_device_get_devinfo(sc, data);
+		return 0;
+	default:
+		return EINVAL;
+	}
+}
+
+int
+dtv_demux_ioctl(struct dtv_softc *sc, u_long cmd, void *data, int flags)
+{
+	struct dmx_pes_filter_params *pesfilt;
+	uint16_t pid;
+	size_t bufsize;
+	int error;
+
+	switch (cmd) {
+	case DMX_START:
+		if (sc->sc_bufsize_chg) {
+			if ((error = dtv_buffer_setup(sc, sc->sc_bufsize)) != 0)
+				return error;
+			sc->sc_bufsize_chg = false;
+		}
+		return dtv_device_start_transfer(sc);
+	case DMX_STOP:
+		return dtv_device_stop_transfer(sc);
+	case DMX_SET_BUFFER_SIZE:
+		bufsize = *(uintptr_t *)data;
+		if (bufsize >= DTV_DEFAULT_BUFSIZE &&
+		    sc->sc_bufsize != bufsize) {
+			sc->sc_bufsize = bufsize;
+			sc->sc_bufsize_chg = true;
+		}
+		return 0;
+	case DMX_SET_PES_FILTER:
+		pesfilt = data;
+
+		if (pesfilt->input != DMX_IN_FRONTEND)
+			return EINVAL;
+		if (pesfilt->output != DMX_OUT_TS_TAP)
+			return EINVAL;
+		if (pesfilt->pes_type != DMX_PES_OTHER)
+			return EINVAL;
+
+		error = dtv_demux_ioctl(sc, DMX_ADD_PID, &pesfilt->pid, flags);
+		if (error)
+			return error;
+
+		if (pesfilt->flags & DMX_IMMEDIATE_START) {
+			error = dtv_demux_ioctl(sc, DMX_START, NULL, flags);
+			if (error)
+				return error;
+		}
+		return 0;
+	case DMX_ADD_PID:
+		pid = *(uint16_t *)data;
+		if (pid > 0x2000)
+			return EINVAL;
+
+		if (pid == 0x2000) {
+			memset(sc->sc_ts.ts_pidfilter, 1,
+			    sizeof(sc->sc_ts.ts_pidfilter));
+		} else {
+			sc->sc_ts.ts_pidfilter[pid] = 1;
+		}
+		return 0;
+	case DMX_REMOVE_PID:
+		pid = *(uint16_t *)data;
+		if (pid > 0x2000)
+			return EINVAL;
+
+		if (pid == 0x2000) {
+			memset(sc->sc_ts.ts_pidfilter, 0,
+			    sizeof(sc->sc_ts.ts_pidfilter));
+		} else {
+			sc->sc_ts.ts_pidfilter[pid] = 0;
+		}
+		return 0;
+	default:
+		return EINVAL;
+	}
+}
Index: src/sys/dev/dtv/dtv_scatter.c
diff -u /dev/null src/sys/dev/dtv/dtv_scatter.c:1.1
--- /dev/null	Sat Jul  9 14:46:56 2011
+++ src/sys/dev/dtv/dtv_scatter.c	Sat Jul  9 14:46:56 2011
@@ -0,0 +1,256 @@
+/* $NetBSD: dtv_scatter.c,v 1.1 2011/07/09 14:46:56 jmcneill Exp $ */
+
+/*
+ * Copyright (c) 2008 Patrick Mahoney <p...@polycrystal.org>
+ * All rights reserved.
+ *
+ * This code was written by Patrick Mahoney (p...@polycrystal.org) as
+ * part of Google Summer of Code 2008.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: dtv_scatter.c,v 1.1 2011/07/09 14:46:56 jmcneill Exp $");
+
+#include <sys/param.h>
+#include <sys/ioctl.h>
+#include <sys/fcntl.h>
+#include <sys/vnode.h>
+#include <sys/poll.h>
+#include <sys/select.h>
+#include <sys/kmem.h>
+#include <sys/pool.h>
+#include <sys/conf.h>
+#include <sys/types.h>
+#include <sys/device.h>
+#include <sys/condvar.h>
+#include <sys/queue.h>
+
+#include <dev/dtv/dtvvar.h>
+
+#define IPL_DTV		IPL_VM
+#define spldtv()	splvm()
+
+void
+dtv_scatter_buf_init(struct dtv_scatter_buf *sb)
+{
+	sb->sb_pool = pool_cache_init(PAGE_SIZE, 0, 0, 0,
+				      "dtvscatter", NULL, IPL_DTV,
+				      NULL, NULL, NULL);
+	sb->sb_size = 0;
+	sb->sb_npages = 0;
+	sb->sb_page_ary = NULL;
+}
+
+void
+dtv_scatter_buf_destroy(struct dtv_scatter_buf *sb)
+{
+	/* Do we need to return everything to the pool first? */
+	dtv_scatter_buf_set_size(sb, 0);
+	pool_cache_destroy(sb->sb_pool);
+	sb->sb_pool = 0;
+	sb->sb_npages = 0;
+	sb->sb_page_ary = NULL;
+}
+
+/* Increase or decrease the size of the buffer */
+int
+dtv_scatter_buf_set_size(struct dtv_scatter_buf *sb, size_t sz)
+{
+	unsigned int i;
+	size_t npages, minpages, oldnpages;
+	uint8_t **old_ary;
+
+	npages = (sz >> PAGE_SHIFT) + ((sz & PAGE_MASK) > 0);
+	
+	if (sb->sb_npages == npages) {
+		return 0;
+	}
+
+	oldnpages = sb->sb_npages;
+	old_ary = sb->sb_page_ary;
+
+	sb->sb_npages = npages;
+	if (npages > 0) {
+		sb->sb_page_ary =
+		    kmem_alloc(sizeof(uint8_t *) * npages, KM_SLEEP);
+		if (sb->sb_page_ary == NULL) {
+			sb->sb_npages = oldnpages;
+			sb->sb_page_ary = old_ary;
+			return ENOMEM;
+		}
+	} else {
+		sb->sb_page_ary = NULL;
+	}
+
+	minpages = min(npages, oldnpages);
+	/* copy any pages that will be reused */
+	for (i = 0; i < minpages; ++i)
+		sb->sb_page_ary[i] = old_ary[i];
+	/* allocate any new pages */
+	for (; i < npages; ++i) {
+		sb->sb_page_ary[i] = pool_cache_get(sb->sb_pool, 0);
+		/* TODO: does pool_cache_get return NULL on
+		 * ENOMEM?  If so, we need to release or note
+		 * the pages with did allocate
+		 * successfully. */
+		if (sb->sb_page_ary[i] == NULL) {
+			return ENOMEM;
+		}
+	}
+	/* return any pages no longer needed */
+	for (; i < oldnpages; ++i)
+		pool_cache_put(sb->sb_pool, old_ary[i]);
+
+	if (old_ary != NULL)
+		kmem_free(old_ary, sizeof(uint8_t *) * oldnpages);
+
+	sb->sb_size = sb->sb_npages << PAGE_SHIFT;
+	
+	return 0;
+}
+
+
+paddr_t
+dtv_scatter_buf_map(struct dtv_scatter_buf *sb, off_t off)
+{
+	size_t pg;
+	paddr_t pa;
+	
+	pg = off >> PAGE_SHIFT;
+
+	if (pg >= sb->sb_npages)
+		return -1;
+	else if (!pmap_extract(pmap_kernel(), (vaddr_t)sb->sb_page_ary[pg], &pa))
+		return -1;
+
+	return atop(pa);
+}
+
+/* Initialize data for an io operation on a scatter buffer. Returns
+ * true if the transfer is valid, or false if out of range. */
+bool
+dtv_scatter_io_init(struct dtv_scatter_buf *sb,
+		    off_t off, size_t len,
+		    struct dtv_scatter_io *sio)
+{
+	if ((off + len) > sb->sb_size) {
+		printf("dtv: %s failed: off=%" PRId64
+			 " len=%zu sb->sb_size=%zu\n",
+			 __func__, off, len, sb->sb_size);
+		return false;
+	}
+
+	sio->sio_buf = sb;
+	sio->sio_offset = off;
+	sio->sio_resid = len;
+
+	return true;
+}
+
+/* Store the pointer and size of the next contiguous segment.  Returns
+ * true if the segment is valid, or false if all has been transfered.
+ * Does not check for overflow. */
+bool
+dtv_scatter_io_next(struct dtv_scatter_io *sio, void **p, size_t *sz)
+{
+	size_t pg, pgo;
+
+	if (sio->sio_resid == 0)
+		return false;
+	
+	pg = sio->sio_offset >> PAGE_SHIFT;
+	pgo = sio->sio_offset & PAGE_MASK;
+
+	*sz = min(PAGE_SIZE - pgo, sio->sio_resid);
+	*p = sio->sio_buf->sb_page_ary[pg] + pgo;
+
+	sio->sio_offset += *sz;
+	sio->sio_resid -= *sz;
+
+	return true;
+}
+
+/* Semi-undo of a failed segment copy.  Updates the scatter_io
+ * struct to the previous values prior to a failed segment copy. */
+void
+dtv_scatter_io_undo(struct dtv_scatter_io *sio, size_t sz)
+{
+	sio->sio_offset -= sz;
+	sio->sio_resid += sz;
+}
+
+/* Copy data from src into the scatter_buf as described by io. */
+void
+dtv_scatter_io_copyin(struct dtv_scatter_io *sio, const void *p)
+{
+	void *dst;
+	const uint8_t *src = p;
+	size_t sz;
+
+	while (dtv_scatter_io_next(sio, &dst, &sz)) {
+		memcpy(dst, src, sz);
+		src += sz;
+	}
+}
+
+/* --not used; commented to avoid compiler warnings--
+void
+dtv_scatter_io_copyout(struct dtv_scatter_io *sio, void *p)
+{
+	void *src;
+	uint8_t *dst = p;
+	size_t sz;
+
+	while (dtv_scatter_io_next(sio, &src, &sz)) {
+		memcpy(dst, src, sz);
+		dst += sz;
+	}
+}
+*/
+
+/* Performat a series of uiomove calls on a scatter buf.  Returns
+ * EFAULT if uiomove EFAULTs on the first segment.  Otherwise, returns
+ * an incomplete transfer but with no error. */
+int
+dtv_scatter_io_uiomove(struct dtv_scatter_io *sio, struct uio *uio)
+{
+	void *p;
+	size_t sz;
+	bool first = true;
+	int err;
+	
+	while (dtv_scatter_io_next(sio, &p, &sz)) {
+		err = uiomove(p, sz, uio);
+		if (err == EFAULT) {
+			dtv_scatter_io_undo(sio, sz);
+			if (first)
+				return EFAULT;
+			else
+				return 0;
+		}
+		first = false;
+	}
+
+	return 0;
+}
Index: src/sys/dev/dtv/dtv_scatter.h
diff -u /dev/null src/sys/dev/dtv/dtv_scatter.h:1.1
--- /dev/null	Sat Jul  9 14:46:56 2011
+++ src/sys/dev/dtv/dtv_scatter.h	Sat Jul  9 14:46:56 2011
@@ -0,0 +1,66 @@
+/* $NetBSD: dtv_scatter.h,v 1.1 2011/07/09 14:46:56 jmcneill Exp $ */
+
+/*-
+ * Copyright (c) 2011 Jared D. McNeill <jmcne...@invisible.ca>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *        This product includes software developed by Jared D. McNeill.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _DEV_DTV_DTV_SCATTER_H
+#define _DEV_DTV_DTV_SCATTER_H
+
+#include <sys/pool.h>
+
+struct dtv_scatter_buf {
+	pool_cache_t	sb_pool;
+	size_t		sb_size;    /* size in bytes */
+	size_t		sb_npages;  /* number of pages */
+	uint8_t		**sb_page_ary; /* array of page pointers */
+};
+
+struct dtv_scatter_io {
+	struct dtv_scatter_buf *sio_buf;
+	off_t		sio_offset;
+	size_t		sio_resid;
+};
+
+void	dtv_scatter_buf_init(struct dtv_scatter_buf *);
+void	dtv_scatter_buf_destroy(struct dtv_scatter_buf *);
+int	dtv_scatter_buf_set_size(struct dtv_scatter_buf *, size_t);
+paddr_t	dtv_scatter_buf_map(struct dtv_scatter_buf *, off_t);
+
+bool	dtv_scatter_io_init(struct dtv_scatter_buf *, off_t, size_t,
+			    struct dtv_scatter_io *);
+bool	dtv_scatter_io_next(struct dtv_scatter_io *, void **, size_t *);
+void	dtv_scatter_io_undo(struct dtv_scatter_io *, size_t);
+void	dtv_scatter_io_copyin(struct dtv_scatter_io *, const void *);
+/* void	dtv_scatter_io_copyout(struct dtv_scatter_io *, void *); */
+int	dtv_scatter_io_uiomove(struct dtv_scatter_io *, struct uio *);
+
+#endif /* !_DEV_DTV_DTV_SCATTER_H */
Index: src/sys/dev/dtv/dtvif.h
diff -u /dev/null src/sys/dev/dtv/dtvif.h:1.1
--- /dev/null	Sat Jul  9 14:46:56 2011
+++ src/sys/dev/dtv/dtvif.h	Sat Jul  9 14:46:56 2011
@@ -0,0 +1,80 @@
+/* $NetBSD: dtvif.h,v 1.1 2011/07/09 14:46:56 jmcneill Exp $ */
+
+/*-
+ * Copyright (c) 2011 Jared D. McNeill <jmcne...@invisible.ca>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *        This product includes software developed by Jared D. McNeill.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _DEV_DTV_DTVIF_H
+#define _DEV_DTV_DTVIF_H
+
+#include <dev/dtv/dtvio.h>
+
+#define	DTV_DEVICE_FRONTEND	0
+#define	DTV_DEVICE_DEMUX	1
+#define	DTV_DEVICE_DVR		2
+
+#define	DTV_NUM_DEVICES		3
+
+#define	DTVUNIT(x)		(minor(x) & 0x0f)
+#define	DTVDEV(x)		((minor(x) & 0xf0) >> 4)
+
+#define	ISDTVFRONTEND(x)	(DTVDEV((x)) == DTV_DEVICE_FRONTEND)
+#define	ISDTVDEMUX(x)		(DTVDEV((x)) == DTV_DEVICE_DEMUX)
+#define	ISDTVDVR(x)		(DTVDEV((x)) == DTV_DEVICE_DVR)
+
+struct dtv_hw_if {
+	void		(*get_devinfo)(void *, struct dvb_frontend_info *);
+
+	int		(*open)(void *, int);
+	void		(*close)(void *);
+	int		(*set_tuner)(void *, const struct dvb_frontend_parameters *);
+	fe_status_t	(*get_status)(void *);
+	uint16_t	(*get_signal_strength)(void *);
+	uint16_t	(*get_snr)(void *);
+	int		(*start_transfer)(void *);
+	int		(*stop_transfer)(void *);
+};
+
+struct dtv_attach_args {
+	const struct dtv_hw_if *hw;
+	void *priv;
+};
+
+struct dtv_payload {
+	const uint8_t	*data;
+	size_t		size;
+};
+
+int	dtv_print(void *, const char *);
+
+void	dtv_submit_payload(device_t, const struct dtv_payload *);
+
+#endif /* !_DEV_DTV_DTVIF_H */
Index: src/sys/dev/dtv/dtvio.h
diff -u /dev/null src/sys/dev/dtv/dtvio.h:1.1
--- /dev/null	Sat Jul  9 14:46:56 2011
+++ src/sys/dev/dtv/dtvio.h	Sat Jul  9 14:46:56 2011
@@ -0,0 +1,45 @@
+/* $NetBSD: dtvio.h,v 1.1 2011/07/09 14:46:56 jmcneill Exp $ */
+
+/*-
+ * Copyright (c) 2011 Jared D. McNeill <jmcne...@invisible.ca>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *        This product includes software developed by Jared D. McNeill.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _DEV_DTV_DTVIO_H
+#define _DEV_DTV_DTVIO_H
+
+#define	DVB_API_VERSION		5
+#define	DVB_API_VERSION_MINOR	2
+
+#include <sys/types.h>
+#include <dev/dtv/dtvio_frontend.h>
+#include <dev/dtv/dtvio_demux.h>
+
+#endif /* !_DEV_DTV_DTVIO_H */
Index: src/sys/dev/dtv/dtvio_demux.h
diff -u /dev/null src/sys/dev/dtv/dtvio_demux.h:1.1
--- /dev/null	Sat Jul  9 14:46:56 2011
+++ src/sys/dev/dtv/dtvio_demux.h	Sat Jul  9 14:46:56 2011
@@ -0,0 +1,144 @@
+/* $NetBSD: dtvio_demux.h,v 1.1 2011/07/09 14:46:56 jmcneill Exp $ */
+
+/*-
+ * Copyright (c) 2011 Jared D. McNeill <jmcne...@invisible.ca>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *        This product includes software developed by Jared D. McNeill.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _DEV_DTV_DTVIO_DEMUX_H
+#define _DEV_DTV_DTVIO_DEMUX_H
+
+#include <sys/ioccom.h>
+
+/*
+ * DVB Demux API
+ */
+
+typedef enum {
+	DMX_OUT_DECODER,
+	DMX_OUT_TAP,
+	DMX_OUT_TS_TAP,
+	DMX_OUT_TSDEMUX_TAP,
+} dmx_output_t;
+
+typedef enum {
+	DMX_IN_FRONTEND,
+	DMX_IN_DVR,
+} dmx_input_t;
+
+typedef enum {
+	DMX_PES_AUDIO0,
+	DMX_PES_VIDEO0,
+	DMX_PES_TELETEXT0,
+	DMX_PES_SUBTITLE0,
+	DMX_PES_PCR0,
+
+	DMX_PES_AUDIO1,
+	DMX_PES_VIDEO1,
+	DMX_PES_TELETEXT1,
+	DMX_PES_SUBTITLE1,
+	DMX_PES_PCR1,
+
+	DMX_PES_AUDIO2,
+	DMX_PES_VIDEO2,
+	DMX_PES_TELETEXT2,
+	DMX_PES_SUBTITLE2,
+	DMX_PES_PCR2,
+
+	DMX_PES_AUDIO3,
+	DMX_PES_VIDEO3,
+	DMX_PES_TELETEXT3,
+	DMX_PES_SUBTITLE3,
+	DMX_PES_PCR3,
+
+	DMX_PES_OTHER,
+} dmx_pes_type_t;
+
+#define	DMX_FILTER_SIZE	16
+
+typedef struct dmx_filter {
+	uint8_t		filter[DMX_FILTER_SIZE];
+	uint8_t		mask[DMX_FILTER_SIZE];
+	uint8_t		mode[DMX_FILTER_SIZE];
+} dmx_filter_t;
+
+struct dmx_sct_filter_params {
+	uint16_t	pid;
+	dmx_filter_t	filter;
+	uint32_t	timeout;
+	uint32_t	flags;
+#define	DMX_CHECK_CRC		0x0001
+#define	DMX_ONESHOT		0x0002
+#define	DMX_IMMEDIATE_START	0x0004
+#define	DMX_KERNEL_CLIENT	0x8000
+};
+
+struct dmx_pes_filter_params {
+	uint16_t	pid;
+	dmx_input_t	input;
+	dmx_output_t	output;
+	dmx_pes_type_t	pes_type;
+	uint32_t	flags;
+};
+
+struct dmx_stc {
+	unsigned int	num;
+	unsigned int	base;
+	uint64_t	stc;
+};
+
+typedef struct dmx_caps {
+	uint32_t	caps;
+	int		num_decoders;
+} dmx_caps_t;
+
+typedef enum {
+	DMX_SOURCE_FRONT0 = 0,
+	DMX_SOURCE_FRONT1,
+	DMX_SOURCE_FRONT2,
+	DMX_SOURCE_FRONT3,
+	DMX_SOURCE_DVR0 = 16,
+	DMX_SOURCE_DVR1,
+	DMX_SOURCE_DVR2,
+	DMX_SOURCE_DVR3,
+} dmx_source_t;
+
+#define	DMX_START		   _IO('D', 100)
+#define	DMX_STOP		   _IO('D', 101)
+#define	DMX_SET_FILTER		   _IOW('D', 102, struct dmx_sct_filter_params)
+#define	DMX_SET_PES_FILTER	   _IOW('D', 103, struct dmx_pes_filter_params)
+#define	DMX_SET_BUFFER_SIZE	   _IO('D', 104)
+#define	DMX_GET_STC		   _IOWR('D', 105, struct dmx_stc)
+#define	DMX_ADD_PID		   _IOW('D', 106, uint16_t)
+#define	DMX_REMOVE_PID		   _IOW('D', 107, uint16_t)
+#define	DMX_GET_CAPS		   _IOR('D', 108, dmx_caps_t)
+#define	DMX_SET_SOURCE		   _IOW('D', 109, dmx_source_t)
+
+#endif /* !_DEV_DTV_DTVIO_DEMUX_H */
Index: src/sys/dev/dtv/dtvio_frontend.h
diff -u /dev/null src/sys/dev/dtv/dtvio_frontend.h:1.1
--- /dev/null	Sat Jul  9 14:46:56 2011
+++ src/sys/dev/dtv/dtvio_frontend.h	Sat Jul  9 14:46:56 2011
@@ -0,0 +1,292 @@
+/* $NetBSD: dtvio_frontend.h,v 1.1 2011/07/09 14:46:56 jmcneill Exp $ */
+
+/*-
+ * Copyright (c) 2011 Jared D. McNeill <jmcne...@invisible.ca>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *        This product includes software developed by Jared D. McNeill.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _DEV_DTV_DTVIO_FRONTEND_H
+#define _DEV_DTV_DTVIO_FRONTEND_H
+
+#include <sys/ioccom.h>
+
+/*
+ * DVB Frontend API
+ */
+
+/* Frontend types */
+typedef enum fe_type {
+	FE_QPSK,	/* DVB-S */
+	FE_QAM,		/* DVB-C annex A/C */
+	FE_OFDM,	/* DVB-T */
+	FE_ATSC,	/* ATSC or DVB-C annex B */
+} fe_type_t;
+
+/* Frontend capabilities */
+typedef enum fe_caps {
+	FE_IS_STUPID			= 0,
+	FE_CAN_INVERSION_AUTO		= 0x1,
+	FE_CAN_FEC_1_2			= 0x2,
+	FE_CAN_FEC_2_3			= 0x4,
+	FE_CAN_FEC_3_4			= 0x8,
+	FE_CAN_FEC_4_5			= 0x10,
+	FE_CAN_FEC_5_6			= 0x20,
+	FE_CAN_FEC_6_7			= 0x40,
+	FE_CAN_FEC_7_8			= 0x80,
+	FE_CAN_FEC_8_9			= 0x100,
+	FE_CAN_FEC_AUTO			= 0x200,
+	FE_CAN_QPSK			= 0x400,
+	FE_CAN_QAM_16			= 0x800,
+	FE_CAN_QAM_32			= 0x1000,
+	FE_CAN_QAM_64			= 0x2000,
+	FE_CAN_QAM_128			= 0x4000,
+	FE_CAN_QAM_256			= 0x8000,
+	FE_CAN_QAM_AUTO			= 0x10000,
+	FE_CAN_TRANSMISSION_MODE_AUTO	= 0x20000,
+	FE_CAN_BANDWIDTH_AUTO		= 0x40000,
+	FE_CAN_GUARD_INTERVAL_AUTO	= 0x80000,
+	FE_CAN_HIERARCHY_AUTO		= 0x100000,
+	FE_CAN_8VSB			= 0x200000,
+	FE_CAN_16VSB			= 0x400000,
+	FE_HAS_EXTENDED_CAPS		= 0x800000,
+	FE_CAN_TURBO_FEC		= 0x8000000,
+	FE_CAN_2G_MODULATION		= 0x10000000,
+	FE_NEEDS_BENDING		= 0x20000000,
+	FE_CAN_RECOVER			= 0x40000000,
+	FE_CAN_MUTE_TS			= 0x80000000,
+} fe_caps_t;
+
+/* Frontend information */
+struct dvb_frontend_info {
+	char		name[128];
+	fe_type_t	type;
+	uint32_t	frequency_min;
+	uint32_t	frequency_max;
+	uint32_t	frequency_stepsize;
+	uint32_t	frequency_tolerance;
+	uint32_t	symbol_rate_min;
+	uint32_t	symbol_rate_max;
+	uint32_t	symbol_rate_tolerance;	/* ppm */
+	uint32_t	notifier_delay;		/* ms */
+	fe_caps_t	caps;
+};
+
+/* Frontend status */
+typedef enum fe_status {
+	FE_HAS_SIGNAL	= 0x01,	/* found something above the noise level */
+	FE_HAS_CARRIER	= 0x02,	/* found a DVB signal */
+	FE_HAS_VITERBI	= 0x04,	/* FEC is stable */
+	FE_HAS_SYNC	= 0x08,	/* found sync bytes */
+	FE_HAS_LOCK	= 0x10,	/* everything's working... */
+	FE_TIMEDOUT	= 0x20,	/* no lock within the last ~2 seconds */
+	FE_REINIT	= 0x40,	/* frontend was reinitialized */
+} fe_status_t;
+
+/* Frontend spectral inversion */
+typedef enum fe_spectral_inversion {
+	INVERSION_OFF,
+	INVERSION_ON,
+	INVERSION_AUTO,
+} fe_spectral_inversion_t;
+
+/* Frontend code rate */
+typedef enum fe_code_rate {
+	FEC_NONE = 0,
+	FEC_1_2,
+	FEC_2_3,
+	FEC_3_4,
+	FEC_4_5,
+	FEC_5_6,
+	FEC_6_7,
+	FEC_7_8,
+	FEC_8_9,
+	FEC_AUTO,
+	FEC_3_5,
+	FEC_9_10,
+} fe_code_rate_t;
+
+/* Frontend modulation type for QAM, OFDM, and VSB */
+typedef enum fe_modulation {
+	QPSK,
+	QAM_16,
+	QAM_32,
+	QAM_64,
+	QAM_128,
+	QAM_256,
+	QAM_AUTO,
+	VSB_8,
+	VSB_16,
+	PSK_8,
+	APSK_16,
+	APSK_32,
+	DQPSK,
+} fe_modulation_t;
+
+/* Number of carriers per channel */
+typedef enum fe_transmit_mode {
+	TRANSMISSION_MODE_2K,
+	TRANSMISSION_MODE_8K,
+	TRANSMISSION_MODE_AUTO,
+	TRANSMISSION_MODE_4K,
+	TRANSMISSION_MODE_1K,
+	TRANSMISSION_MODE_16K,
+	TRANSMISSION_MODE_32K,
+} fe_transmit_mode_t;
+
+/* Frontend bandwidth */
+typedef enum fe_bandwidth {
+	BANDWIDTH_8_MHZ,
+	BANDWIDTH_7_MHZ,
+	BANDWIDTH_6_MHZ,
+	BANDWIDTH_AUTO,
+	BANDWIDTH_5_MHZ,
+	BANDWIDTH_10_MHZ,
+	BANDWIDTH_1_172_MHZ,
+} fe_bandwidth_t;
+
+/* Frontend guard interval */
+typedef enum fe_guard_interval {
+	GUARD_INTERVAL_1_32,
+	GUARD_INTERVAL_1_16,
+	GUARD_INTERVAL_1_8,
+	GUARD_INTERVAL_1_4,
+	GUARD_INTERVAL_AUTO,
+	GUARD_INTERVAL_1_128,
+	GUARD_INTERVAL_19_128,
+	GUARD_INTERVAL_19_256,
+} fe_guard_interval_t;
+
+/* Frontend hierarchy */
+typedef enum fe_hierarchy {
+	HIERARCHY_NONE,
+	HIERARCHY_1,
+	HIERARCHY_2,
+	HIERARCHY_4,
+	HIERARCHY_AUTO
+} fe_hierarchy_t;
+
+/* QPSK parameters */
+struct dvb_qpsk_parameters {
+	uint32_t	symbol_rate;
+	fe_code_rate_t	fec_inner;
+};
+
+/* QAM parameters */
+struct dvb_qam_parameters {
+	uint32_t	symbol_rate;
+	fe_code_rate_t	fec_inner;
+	fe_modulation_t	modulation;
+};
+
+/* VSB parameters */
+struct dvb_vsb_parameters {
+	fe_modulation_t	modulation;
+};
+
+/* OFDM parameters */
+struct dvb_ofdm_parameters {
+	fe_bandwidth_t		bandwidth;
+	fe_code_rate_t		code_rate_HP;
+	fe_code_rate_t		code_rate_LP;
+	fe_modulation_t		constellation;
+	fe_transmit_mode_t	transmission_mode;
+	fe_guard_interval_t	guard_interval;
+	fe_hierarchy_t		hierarchy_information;
+};
+
+/* Frontend parameters */
+struct dvb_frontend_parameters {
+	uint32_t		frequency;
+	fe_spectral_inversion_t	inversion;
+	union {
+		struct dvb_qpsk_parameters	qpsk;
+		struct dvb_qam_parameters	qam;
+		struct dvb_ofdm_parameters	ofdm;
+		struct dvb_vsb_parameters	vsb;
+	} u;
+};
+
+/* Frontend events */
+struct dvb_frontend_event {
+	fe_status_t			status;
+	struct dvb_frontend_parameters	parameters;
+};
+
+/* DiSEqC master command */
+struct dvb_diseqc_master_cmd {
+	uint8_t		msg[6];
+	uint8_t		msg_len;
+};
+
+/* DiSEqC slave reply */
+struct dvb_diseqc_slave_reply {
+	uint8_t		msg[4];
+	uint8_t		msg_len;
+	int		timeout;
+};
+
+/* SEC voltage */
+typedef enum fe_sec_voltage {
+	SEC_VOLTAGE_13,
+	SEC_VOLTAGE_18,
+} fe_sec_voltage_t;
+
+/* SEC continuous tone */
+typedef enum fe_sec_tone_mode {
+	SEC_TONE_ON,
+	SEC_TONE_OFF,
+} fe_sec_tone_mode_t;
+
+/* SEC tone burst */
+typedef enum fe_sec_mini_cmd {
+	SEC_MINI_A,
+	SEC_MINI_B,
+} fe_sec_mini_cmd_t;
+
+#define	FE_READ_STATUS		   _IOR('D', 0, fe_status_t)
+#define	FE_READ_BER		   _IOR('D', 1, uint32_t)
+#define	FE_READ_SNR		   _IOR('D', 2, uint16_t)
+#define	FE_READ_SIGNAL_STRENGTH	   _IOR('D', 3, uint16_t)
+#define	FE_READ_UNCORRECTED_BLOCKS _IOR('D', 4, uint32_t)
+#define	FE_SET_FRONTEND		   _IOWR('D', 5, struct dvb_frontend_parameters)
+#define	FE_GET_FRONTEND		   _IOR('D', 6, struct dvb_frontend_parameters)
+#define	FE_GET_EVENT		   _IOR('D', 7, struct dvb_frontend_event)
+#define	FE_GET_INFO		   _IOR('D', 8, struct dvb_frontend_info)
+#define	FE_DISEQC_RESET_OVERLOAD   _IO('D', 9)
+#define	FE_DISEQC_SEND_MASTER_CMD  _IOW('D', 10, struct dvb_diseqc_master_cmd)
+#define	FE_DISEQC_RECV_SLAVE_REPLY _IOR('D', 11, struct dvb_diseqc_slave_reply)
+#define	FE_DISEQC_SEND_BURST	   _IOW('D', 12, fe_sec_mini_cmd_t)
+#define	FE_SET_TONE		   _IOW('D', 13, fe_sec_tone_mode_t)
+#define	FE_SET_VOLTAGE		   _IOW('D', 14, fe_sec_voltage_t)
+#define	FE_ENABLE_HIGH_LNB_VOLTAGE _IOW('D', 15, int)
+#define	FE_SET_FRONTEND_TUNE_MODE  _IOW('D', 16, unsigned int)
+#define	FE_DISHNETWORK_SEND_LEGACY_CMD _IOW('D', 17, unsigned long)
+
+#endif /* !_DEV_DTV_DTVIO_FRONTEND_H */
Index: src/sys/dev/dtv/dtvmodule.h
diff -u /dev/null src/sys/dev/dtv/dtvmodule.h:1.1
--- /dev/null	Sat Jul  9 14:46:56 2011
+++ src/sys/dev/dtv/dtvmodule.h	Sat Jul  9 14:46:56 2011
@@ -0,0 +1,45 @@
+/* $NetBSD: dtvmodule.h,v 1.1 2011/07/09 14:46:56 jmcneill Exp $ */
+
+/*-
+ * Copyright (c) 2011 Jared D. McNeill <jmcne...@invisible.ca>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *        This product includes software developed by Jared D. McNeill.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _DEV_DTV_DTVMODULE_H
+#define _DEV_DTV_DTVMODULE_H
+
+#ifdef _MODULE
+#include "ioconf.c"
+#else
+#define config_init_component(xxx)	0
+#define	config_fini_component(xxx)	0
+#endif
+
+#endif /* !_DEV_DTV_DTVMODULE_H */
Index: src/sys/dev/dtv/dtvvar.h
diff -u /dev/null src/sys/dev/dtv/dtvvar.h:1.1
--- /dev/null	Sat Jul  9 14:46:56 2011
+++ src/sys/dev/dtv/dtvvar.h	Sat Jul  9 14:46:56 2011
@@ -0,0 +1,115 @@
+/* $NetBSD: dtvvar.h,v 1.1 2011/07/09 14:46:56 jmcneill Exp $ */
+
+/*-
+ * Copyright (c) 2011 Jared D. McNeill <jmcne...@invisible.ca>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *        This product includes software developed by Jared D. McNeill.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _DEV_DTV_DTVVAR_H
+#define _DEV_DTV_DTVVAR_H
+
+#include <dev/dtv/dtvif.h>
+#include <dev/dtv/dtv_scatter.h>
+
+#define	DTV_DEFAULT_BUFSIZE	(64 * 4096)
+
+#define	TS_PKTLEN		188
+#define	TS_HAS_SYNC(_tspkt)	((_tspkt)[0] == 0x47)
+#define	TS_PID(_tspkt)		((((_tspkt)[1] & 0x1f) << 8) | (_tspkt)[2])
+
+struct dtv_buffer {
+	uint32_t	db_offset;
+	uint32_t	db_bytesused;
+	size_t		db_length;
+	SIMPLEQ_ENTRY(dtv_buffer) db_entries;
+};
+
+SIMPLEQ_HEAD(dtv_sample_queue, dtv_buffer);
+
+struct dtv_stream {
+	unsigned int		ds_nbufs;
+	struct dtv_buffer	**ds_buf;
+	struct dtv_scatter_buf	ds_data;
+	struct dtv_sample_queue	ds_ingress, ds_egress;
+	kmutex_t		ds_lock;
+	kcondvar_t		ds_sample_cv;
+	struct selinfo		ds_sel;
+	uint32_t		ds_bytesread;
+};
+
+struct dtv_ts {
+	uint8_t			ts_pidfilter[0x2000];
+	kmutex_t		ts_lock;
+};
+
+struct dtv_softc {
+	device_t	sc_dev;
+	const struct dtv_hw_if *sc_hw;
+	void		*sc_priv;
+
+	bool		sc_dying;
+
+	unsigned int	sc_open;
+
+	size_t		sc_bufsize;
+	bool		sc_bufsize_chg;
+
+	struct dtv_stream sc_stream;
+	struct dtv_ts	sc_ts;
+};
+
+#define	dtv_device_get_devinfo(sc, info)	\
+	((sc)->sc_hw->get_devinfo((sc)->sc_priv, (info)))
+#define	dtv_device_open(sc, flags)		\
+	((sc)->sc_hw->open((sc)->sc_priv, (flags)))
+#define	dtv_device_close(sc)			\
+	((sc)->sc_hw->close((sc)->sc_priv))
+#define	dtv_device_set_tuner(sc, params)	\
+	((sc)->sc_hw->set_tuner((sc)->sc_priv, (params)))
+#define	dtv_device_get_status(sc)		\
+	((sc)->sc_hw->get_status((sc)->sc_priv))
+#define	dtv_device_get_signal_strength(sc)	\
+	((sc)->sc_hw->get_signal_strength((sc)->sc_priv))
+#define	dtv_device_get_snr(sc)			\
+	((sc)->sc_hw->get_snr((sc)->sc_priv))
+#define	dtv_device_start_transfer(sc)		\
+	((sc)->sc_hw->start_transfer((sc)->sc_priv))
+#define	dtv_device_stop_transfer(sc)		\
+	((sc)->sc_hw->stop_transfer((sc)->sc_priv))
+
+int	dtv_frontend_ioctl(struct dtv_softc *, u_long, void *, int);
+int	dtv_demux_ioctl(struct dtv_softc *, u_long, void *, int);
+
+int	dtv_buffer_setup(struct dtv_softc *, size_t);
+int	dtv_buffer_destroy(struct dtv_softc *);
+int	dtv_buffer_read(struct dtv_softc *, struct uio *, int);
+int	dtv_buffer_poll(struct dtv_softc *, int, lwp_t *);
+
+#endif /* !_DEV_DTV_DTVVAR_H */
Index: src/sys/dev/dtv/files.dtv
diff -u /dev/null src/sys/dev/dtv/files.dtv:1.1
--- /dev/null	Sat Jul  9 14:46:56 2011
+++ src/sys/dev/dtv/files.dtv	Sat Jul  9 14:46:56 2011
@@ -0,0 +1,10 @@
+# $NetBSD: files.dtv,v 1.1 2011/07/09 14:46:56 jmcneill Exp $
+
+define	dtvbus { }
+
+device	dtv
+attach	dtv at dtvbus
+file	dev/dtv/dtv_buffer.c	dtv
+file	dev/dtv/dtv_device.c	dtv
+file	dev/dtv/dtv_ioctl.c	dtv
+file	dev/dtv/dtv_scatter.c	dtv

Reply via email to