Sat Jul 9 14:46:56 2011 UTC ()
add digital TV framework which implements a subset of Linux DVB APIs
(jmcneill)
diff -r0 -r1.1 src/sys/dev/dtv/Makefile
diff -r0 -r1.1 src/sys/dev/dtv/dtv_buffer.c
diff -r0 -r1.1 src/sys/dev/dtv/dtv_device.c
diff -r0 -r1.1 src/sys/dev/dtv/dtv_ioctl.c
diff -r0 -r1.1 src/sys/dev/dtv/dtv_scatter.c
diff -r0 -r1.1 src/sys/dev/dtv/dtv_scatter.h
diff -r0 -r1.1 src/sys/dev/dtv/dtvif.h
diff -r0 -r1.1 src/sys/dev/dtv/dtvio.h
diff -r0 -r1.1 src/sys/dev/dtv/dtvio_demux.h
diff -r0 -r1.1 src/sys/dev/dtv/dtvio_frontend.h
diff -r0 -r1.1 src/sys/dev/dtv/dtvmodule.h
diff -r0 -r1.1 src/sys/dev/dtv/dtvvar.h
diff -r0 -r1.1 src/sys/dev/dtv/files.dtv
# $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>
/* $NetBSD: dtv_buffer.c,v 1.1 2011/07/09 14:46:56 jmcneill Exp $ */
/*-
* Copyright (c) 2011 Jared D. McNeill <jmcneill@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;
}
/* $NetBSD: dtv_device.c,v 1.1 2011/07/09 14:46:56 jmcneill Exp $ */
/*-
* Copyright (c) 2011 Jared D. McNeill <jmcneill@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;
}
/* $NetBSD: dtv_ioctl.c,v 1.1 2011/07/09 14:46:56 jmcneill Exp $ */
/*-
* Copyright (c) 2011 Jared D. McNeill <jmcneill@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;
}
}
/* $NetBSD: dtv_scatter.c,v 1.1 2011/07/09 14:46:56 jmcneill Exp $ */
/*
* Copyright (c) 2008 Patrick Mahoney <pat@polycrystal.org>
* All rights reserved.
*
* This code was written by Patrick Mahoney (pat@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;
}
/* $NetBSD: dtv_scatter.h,v 1.1 2011/07/09 14:46:56 jmcneill Exp $ */
/*-
* Copyright (c) 2011 Jared D. McNeill <jmcneill@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 */
/* $NetBSD: dtvif.h,v 1.1 2011/07/09 14:46:56 jmcneill Exp $ */
/*-
* Copyright (c) 2011 Jared D. McNeill <jmcneill@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 */
/* $NetBSD: dtvio.h,v 1.1 2011/07/09 14:46:56 jmcneill Exp $ */
/*-
* Copyright (c) 2011 Jared D. McNeill <jmcneill@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 */
/* $NetBSD: dtvio_demux.h,v 1.1 2011/07/09 14:46:56 jmcneill Exp $ */
/*-
* Copyright (c) 2011 Jared D. McNeill <jmcneill@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 */
/* $NetBSD: dtvio_frontend.h,v 1.1 2011/07/09 14:46:56 jmcneill Exp $ */
/*-
* Copyright (c) 2011 Jared D. McNeill <jmcneill@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 */
/* $NetBSD: dtvmodule.h,v 1.1 2011/07/09 14:46:56 jmcneill Exp $ */
/*-
* Copyright (c) 2011 Jared D. McNeill <jmcneill@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 */
/* $NetBSD: dtvvar.h,v 1.1 2011/07/09 14:46:56 jmcneill Exp $ */
/*-
* Copyright (c) 2011 Jared D. McNeill <jmcneill@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 */
# $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