aboutsummaryrefslogtreecommitdiff
path: root/multimedia/linux_dvbwrapper-kmod
diff options
context:
space:
mode:
authorJuergen Lock <nox@FreeBSD.org>2011-04-24 15:51:13 +0000
committerJuergen Lock <nox@FreeBSD.org>2011-04-24 15:51:13 +0000
commit5c392de08e25481fc1571ba09e497241e01792c0 (patch)
tree65eec7ecbd253136bc956ebf5fb92367ade8b46f /multimedia/linux_dvbwrapper-kmod
parentaaa59c1b11e58d2aee70752d85260c56524f930d (diff)
downloadports-5c392de08e25481fc1571ba09e497241e01792c0.tar.gz
ports-5c392de08e25481fc1571ba09e497241e01792c0.zip
Notes
Diffstat (limited to 'multimedia/linux_dvbwrapper-kmod')
-rw-r--r--multimedia/linux_dvbwrapper-kmod/Makefile43
-rw-r--r--multimedia/linux_dvbwrapper-kmod/files/Makefile13
-rw-r--r--multimedia/linux_dvbwrapper-kmod/files/linux_dvb.h63
-rw-r--r--multimedia/linux_dvbwrapper-kmod/files/linux_dvb_compat.h26
-rw-r--r--multimedia/linux_dvbwrapper-kmod/files/linux_dvb_ioctl.h122
-rw-r--r--multimedia/linux_dvbwrapper-kmod/files/linux_dvbwrapper.c334
-rw-r--r--multimedia/linux_dvbwrapper-kmod/pkg-descr7
7 files changed, 608 insertions, 0 deletions
diff --git a/multimedia/linux_dvbwrapper-kmod/Makefile b/multimedia/linux_dvbwrapper-kmod/Makefile
new file mode 100644
index 000000000000..47e03abfdaf7
--- /dev/null
+++ b/multimedia/linux_dvbwrapper-kmod/Makefile
@@ -0,0 +1,43 @@
+# New ports collection makefile for: linux_dvbwrapper-kmod
+# Date created: Thu Apr 21 17:34:08 CEST 2011
+# Whom: nox@FreeBSD.org
+#
+# $FreeBSD$
+#
+
+PORTNAME= linux_dvbwrapper-kmod
+PORTVERSION= 1.0
+CATEGORIES= multimedia kld
+DISTFILES= # none
+
+MAINTAINER= nox@FreeBSD.org
+COMMENT= Linux compatibility layer - DVB ioctl handler
+
+ONLY_FOR_ARCHS= i386 amd64
+
+.include <bsd.port.pre.mk>
+
+PLIST_FILES+= "@cwd /"
+PLIST_FILES+= ${KMODDIR:C,^/,,}/linux_dvbwrapper.ko
+PLIST_FILES+= "@exec kldxref ${KMODDIR}"
+PLIST_FILES+= "@unexec kldxref ${KMODDIR}"
+
+# install where x11/nvidia-driver does also:
+KMODDIR= /boot/modules
+
+MAKE_ENV+= KMODDIR="${KMODDIR}"
+
+SYSDIR?= ${SRC_BASE}/sys
+MAKE_ENV+= SYSDIR="${SYSDIR}"
+
+CFLAGS+= ${DEBUG_FLAGS}
+
+.if !exists(${SYSDIR}/Makefile)
+IGNORE= requires kernel source to be installed
+.endif
+
+do-extract:
+ ${MKDIR} ${WRKSRC}
+ ${CP} ${FILESDIR}/Makefile ${FILESDIR}/*.[ch] ${WRKSRC}
+
+.include <bsd.port.post.mk>
diff --git a/multimedia/linux_dvbwrapper-kmod/files/Makefile b/multimedia/linux_dvbwrapper-kmod/files/Makefile
new file mode 100644
index 000000000000..0c8812c215f8
--- /dev/null
+++ b/multimedia/linux_dvbwrapper-kmod/files/Makefile
@@ -0,0 +1,13 @@
+# $FreeBSD$
+
+.if ${MACHINE_ARCH} == "amd64"
+SFX= 32
+CFLAGS+=-DCOMPAT_FREEBSD32 -DCOMPAT_LINUX32
+.endif
+
+CWARNFLAGS+=-Wno-missing-prototypes
+
+KMOD= linux_dvbwrapper
+SRCS= linux_dvbwrapper.c
+
+.include <bsd.kmod.mk>
diff --git a/multimedia/linux_dvbwrapper-kmod/files/linux_dvb.h b/multimedia/linux_dvbwrapper-kmod/files/linux_dvb.h
new file mode 100644
index 000000000000..21e63c02e2b9
--- /dev/null
+++ b/multimedia/linux_dvbwrapper-kmod/files/linux_dvb.h
@@ -0,0 +1,63 @@
+/*
+ * Extracted from <linux/dvb/frontend.h>, which is:
+ *
+ * Copyright (C) 2000 Marcus Metzler <marcus@convergence.de>
+ * Ralph Metzler <ralph@convergence.de>
+ * Holger Waechtler <holger@convergence.de>
+ * Andre Draszik <ad@convergence.de>
+ * for convergence integrated media GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifndef __LINUX_DVB_H
+#define __LINUX_DVB_H
+
+#include <sys/types.h>
+
+struct dtv_property {
+ uint32_t cmd;
+ uint32_t reserved[3];
+ union {
+ uint32_t data;
+ struct {
+ uint8_t data[32];
+ uint32_t len;
+ uint32_t reserved1[3];
+ void *reserved2;
+ } buffer;
+ } u;
+ int result;
+} __attribute__ ((packed));
+
+/* num of properties cannot exceed DTV_IOCTL_MAX_MSGS per ioctl */
+#define DTV_IOCTL_MAX_MSGS 64
+
+struct dtv_properties {
+ uint32_t num;
+ struct dtv_property *props;
+};
+
+#define FE_SET_PROPERTY _IOW('o', 82, struct dtv_properties)
+/*
+ * This is broken on linux as well but they workaround it in the driver.
+ * Since this is impossible to do on FreeBSD fix the header instead.
+ * Detailed and discussion :
+ * http://lists.freebsd.org/pipermail/freebsd-multimedia/2010-April/010958.html
+ */
+#define FE_GET_PROPERTY _IOW('o', 83, struct dtv_properties)
+
+#endif /*__LINUX_DVB_H*/
diff --git a/multimedia/linux_dvbwrapper-kmod/files/linux_dvb_compat.h b/multimedia/linux_dvbwrapper-kmod/files/linux_dvb_compat.h
new file mode 100644
index 000000000000..02d5e6078a03
--- /dev/null
+++ b/multimedia/linux_dvbwrapper-kmod/files/linux_dvb_compat.h
@@ -0,0 +1,26 @@
+#ifndef __LINUX_DVB_COMPAT_H
+#define __LINUX_DVB_COMPAT_H
+
+#include <sys/types.h>
+
+struct l_dtv_property {
+ uint32_t cmd;
+ uint32_t reserved[3];
+ union {
+ uint32_t data;
+ struct {
+ uint8_t data[32];
+ uint32_t len;
+ uint32_t reserved1[3];
+ l_uintptr_t reserved2;
+ } buffer;
+ } u;
+ l_int result;
+} __attribute__ ((packed));
+
+struct l_dtv_properties {
+ uint32_t num;
+ l_uintptr_t props;
+};
+
+#endif /*__LINUX_DVB_H*/
diff --git a/multimedia/linux_dvbwrapper-kmod/files/linux_dvb_ioctl.h b/multimedia/linux_dvbwrapper-kmod/files/linux_dvb_ioctl.h
new file mode 100644
index 000000000000..87d1f349b34d
--- /dev/null
+++ b/multimedia/linux_dvbwrapper-kmod/files/linux_dvb_ioctl.h
@@ -0,0 +1,122 @@
+/*-
+ * Copyright (c) 2011 Juergen Lock
+ * 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
+ * in this position and unchanged.
+ * 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. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * $FreeBSD: /tmp/pcvs/ports/multimedia/linux_dvbwrapper-kmod/files/linux_dvb_ioctl.h,v 1.1 2011-04-24 15:51:13 nox Exp $
+ */
+
+#ifndef _LINUX_DVB_IOCTL_H_
+#define _LINUX_DVB_IOCTL_H_
+
+/*
+ * ioctl
+ *
+ * XXX comments in Linux' <asm-generic/ioctl.h> indicate these
+ * could be arch-dependant...
+ */
+#define LINUX_IOC_VOID 0
+#define LINUX_IOC_IN 0x40000000
+#define LINUX_IOC_OUT 0x80000000
+#define LINUX_IOC_INOUT (LINUX_IOC_IN|LINUX_IOC_OUT)
+
+/*
+ * DVB (osd.h and video.h not handled)
+ */
+#define LINUX_AUDIO_STOP 0x6f01 /* 0x00006f01 */
+#define LINUX_AUDIO_PLAY 0x6f02 /* 0x00006f02 */
+#define LINUX_AUDIO_PAUSE 0x6f03 /* 0x00006f03 */
+#define LINUX_AUDIO_CONTINUE 0x6f04 /* 0x00006f04 */
+#define LINUX_AUDIO_SELECT_SOURCE 0x6f05 /* 0x00006f05 */
+#define LINUX_AUDIO_SET_MUTE 0x6f06 /* 0x00006f06 */
+#define LINUX_AUDIO_SET_AV_SYNC 0x6f07 /* 0x00006f07 */
+#define LINUX_AUDIO_SET_BYPASS_MODE 0x6f08 /* 0x00006f08 */
+#define LINUX_AUDIO_CHANNEL_SELECT 0x6f09 /* 0x00006f09 */
+#define LINUX_AUDIO_GET_STATUS 0x6f0a /* 0x80206f0a */
+#define LINUX_AUDIO_GET_CAPABILITIES 0x6f0b /* 0x80046f0b */
+#define LINUX_AUDIO_CLEAR_BUFFER 0x6f0c /* 0x00006f0c */
+#define LINUX_AUDIO_SET_ID 0x6f0d /* 0x00006f0d */
+#define LINUX_AUDIO_SET_MIXER 0x6f0e /* 0x40086f0e */
+#define LINUX_AUDIO_SET_STREAMTYPE 0x6f0f /* 0x00006f0f */
+#define LINUX_AUDIO_SET_EXT_ID 0x6f10 /* 0x00006f10 */
+#define LINUX_AUDIO_SET_ATTRIBUTES 0x6f11 /* 0x40026f11 */
+#define LINUX_AUDIO_SET_KARAOKE 0x6f12 /* 0x400c6f12 */
+#define LINUX_AUDIO_GET_PTS 0x6f13 /* 0x80086f13 */
+#define LINUX_AUDIO_BILINGUAL_CHANNEL_SELECT 0x6f14 /* 0x00006f14 */
+#define LINUX_DMX_START 0x6f29 /* 0x00006f29 */
+#define LINUX_DMX_STOP 0x6f2a /* 0x00006f2a */
+#define LINUX_DMX_SET_FILTER 0x6f2b /* 0x403c6f2b */
+#define LINUX_DMX_SET_PES_FILTER 0x6f2c /* 0x40146f2c */
+#define LINUX_DMX_SET_BUFFER_SIZE 0x6f2d /* 0x00006f2d */
+#define LINUX_DMX_GET_PES_PIDS 0x6f2f /* 0x800a6f2f */
+#define LINUX_DMX_GET_CAPS 0x6f30 /* 0x80086f30 */
+#define LINUX_DMX_SET_SOURCE 0x6f31 /* 0x40046f31 */
+#define LINUX_DMX_GET_STC 0x6f32 /* 0xc0106f32 */
+#define LINUX_DMX_ADD_PID 0x6f33 /* 0x40026f33 */
+#define LINUX_DMX_REMOVE_PID 0x6f34 /* 0x40026f34 */
+#define LINUX_FE_GET_INFO 0x6f3d /* 0x80a86f3d */
+#define LINUX_FE_DISEQC_RESET_OVERLOAD 0x6f3e /* 0x00006f3e */
+#define LINUX_FE_DISEQC_SEND_MASTER_CMD 0x6f3f /* 0x40076f3f */
+#define LINUX_FE_DISEQC_RECV_SLAVE_REPLY 0x6f40 /* 0x800c6f40 */
+#define LINUX_FE_DISEQC_SEND_BURST 0x6f41 /* 0x00006f41 */
+#define LINUX_FE_SET_TONE 0x6f42 /* 0x00006f42 */
+#define LINUX_FE_SET_VOLTAGE 0x6f43 /* 0x00006f43 */
+#define LINUX_FE_ENABLE_HIGH_LNB_VOLTAGE 0x6f44 /* 0x00006f44 */
+#define LINUX_FE_READ_STATUS 0x6f45 /* 0x80046f45 */
+#define LINUX_FE_READ_BER 0x6f46 /* 0x80046f46 */
+#define LINUX_FE_READ_SIGNAL_STRENGTH 0x6f47 /* 0x80026f47 */
+#define LINUX_FE_READ_SNR 0x6f48 /* 0x80026f48 */
+#define LINUX_FE_READ_UNCORRECTED_BLOCKS 0x6f49 /* 0x80046f49 */
+#define LINUX_FE_SET_FRONTEND 0x6f4c /* 0x40246f4c */
+#define LINUX_FE_GET_FRONTEND 0x6f4d /* 0x80246f4d */
+#define LINUX_FE_GET_EVENT 0x6f4e /* 0x80286f4e */
+#define LINUX_FE_DISHNETWORK_SEND_LEGACY_CMD 0x6f50 /* 0x00006f50 */
+#define LINUX_FE_SET_FRONTEND_TUNE_MODE 0x6f51 /* 0x00006f51 */
+#define LINUX_FE_SET_PROPERTY 0x6f52 /* 0x40086f52 */
+#define LINUX_FE_GET_PROPERTY 0x6f53 /* 0x80086f53 */
+#define LINUX_CA_RESET 0x6f80 /* 0x00006f80 */
+#define LINUX_CA_GET_CAP 0x6f81 /* 0x80106f81 */
+#define LINUX_CA_GET_SLOT_INFO 0x6f82 /* 0x800c6f82 */
+#define LINUX_CA_GET_DESCR_INFO 0x6f83 /* 0x80086f83 */
+#define LINUX_CA_GET_MSG 0x6f84 /* 0x810c6f84 */
+#define LINUX_CA_SEND_MSG 0x6f85 /* 0x410c6f85 */
+#define LINUX_CA_SET_DESCR 0x6f86 /* 0x40106f86 */
+#define LINUX_CA_SET_PID 0x6f87 /* 0x40086f87 */
+
+/*
+ * DVB net.h
+ * (LINUX_NET_ADD_IF and LINUX___NET_ADD_IF_OLD overlap with
+ * LINUX_DMX_REMOVE_PID)
+ */
+#define LINUX_NET_ADD_IF 0x6f34 /* 0xc0066f34 */
+#define LINUX_NET_REMOVE_IF 0x6f35 /* 0x00006f35 */
+#define LINUX_NET_GET_IF 0x6f36 /* 0xc0066f36 */
+#define LINUX___NET_ADD_IF_OLD 0x6f34 /* 0xc0046f34 */
+#define LINUX___NET_GET_IF_OLD 0x6f36 /* 0xc0046f36 */
+
+#define LINUX_IOCTL_DVB_MIN LINUX_AUDIO_STOP
+#define LINUX_IOCTL_DVB_MAX LINUX_CA_SET_PID
+
+#endif /* !_LINUX_DVB_IOCTL_H_ */
diff --git a/multimedia/linux_dvbwrapper-kmod/files/linux_dvbwrapper.c b/multimedia/linux_dvbwrapper-kmod/files/linux_dvbwrapper.c
new file mode 100644
index 000000000000..8045c12e94c7
--- /dev/null
+++ b/multimedia/linux_dvbwrapper-kmod/files/linux_dvbwrapper.c
@@ -0,0 +1,334 @@
+/*-
+ * Copyright (c) 2011 Juergen Lock
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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>
+__FBSDID("$FreeBSD: /tmp/pcvs/ports/multimedia/linux_dvbwrapper-kmod/files/linux_dvbwrapper.c,v 1.1 2011-04-24 15:51:13 nox Exp $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/conf.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/file.h>
+#include <sys/proc.h>
+#include <sys/ioccom.h>
+#include <sys/sysproto.h>
+#include <sys/mman.h>
+#include <sys/resourcevar.h>
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+#include <vm/vm_extern.h>
+#include <vm/vm_map.h>
+
+#ifdef COMPAT_LINUX32
+#include <machine/../linux32/linux.h>
+#include <machine/../linux32/linux32_proto.h>
+#else
+#include <machine/../linux/linux.h>
+#include <machine/../linux/linux_proto.h>
+#endif
+#include <compat/linux/linux_ioctl.h>
+#include <compat/linux/linux_util.h>
+
+#include "linux_dvb_ioctl.h"
+#include "linux_dvb.h"
+#include "linux_dvb_compat.h"
+
+static linux_ioctl_function_t linux_ioctl_dvb;
+static struct linux_ioctl_handler dvb_handler =
+{ linux_ioctl_dvb, LINUX_IOCTL_DVB_MIN, LINUX_IOCTL_DVB_MAX };
+
+SYSINIT (dvbwrapper_register, SI_SUB_KLD, SI_ORDER_MIDDLE,
+ linux_ioctl_register_handler, &dvb_handler);
+SYSUNINIT(dvbwrapper_unregister, SI_SUB_KLD, SI_ORDER_MIDDLE,
+ linux_ioctl_unregister_handler, &dvb_handler);
+
+static MALLOC_DEFINE(M_LINUX_DVB, "linux_dvbwrapper", "Linux DVB wrapper");
+
+static int
+linux_dvbwrapper_modevent(module_t mod, int cmd, void *data)
+{
+ return (0);
+}
+
+DEV_MODULE(linux_dvbwrapper, linux_dvbwrapper_modevent, NULL);
+MODULE_DEPEND(linux_dvbwrapper, linux, 1, 1, 1);
+
+#if ((__FreeBSD_version >= 900000) && (__FreeBSD_version < 900035)) || \
+ (__FreeBSD_version < 802503)
+/*
+ * Map some anonymous memory in user space of size sz, rounded up to the page
+ * boundary.
+ */
+int
+copyout_map(struct thread *td, vm_offset_t *addr, size_t sz)
+{
+ struct vmspace *vms;
+ int error;
+ vm_size_t size;
+
+ vms = td->td_proc->p_vmspace;
+
+ /*
+ * Map somewhere after heap in process memory.
+ */
+ PROC_LOCK(td->td_proc);
+ *addr = round_page((vm_offset_t)vms->vm_daddr +
+ lim_max(td->td_proc, RLIMIT_DATA));
+ PROC_UNLOCK(td->td_proc);
+
+ /* round size up to page boundry */
+ size = (vm_size_t)round_page(sz);
+
+ error = vm_mmap(&vms->vm_map, addr, size, PROT_READ | PROT_WRITE,
+ VM_PROT_ALL, MAP_PRIVATE | MAP_ANON, OBJT_DEFAULT, NULL, 0);
+
+ return (error);
+}
+
+/*
+ * Unmap memory in user space.
+ */
+int
+copyout_unmap(struct thread *td, vm_offset_t addr, size_t sz)
+{
+ vm_map_t map;
+ vm_size_t size;
+
+ if (sz == 0)
+ return (0);
+
+ map = &td->td_proc->p_vmspace->vm_map;
+ size = (vm_size_t)round_page(sz);
+
+ if (vm_map_remove(map, addr, addr + size) != KERN_SUCCESS)
+ return (EINVAL);
+
+ return (0);
+}
+#endif
+
+static int
+linux_to_bsd_dtv_properties(struct l_dtv_properties *lvps, struct dtv_properties *vps)
+{
+
+ vps->num = lvps->num;
+ vps->props = PTRIN(lvps->props); /* possible pointer size conversion */
+ return (0);
+}
+
+static int
+linux_to_bsd_dtv_property(struct l_dtv_property *lvp, struct dtv_property *vp)
+{
+
+ /*
+ * Everything until u.buffer.reserved2 is fixed size so
+ * just memcpy it.
+ */
+ memcpy(vp, lvp, offsetof(struct l_dtv_property, u.buffer.reserved2));
+ /*
+ * The pointer may be garbage since it's part of a union,
+ * currently no Linux code uses it so just set it to NULL.
+ */
+ vp->u.buffer.reserved2 = NULL;
+ vp->result = lvp->result;
+ return (0);
+}
+
+static int
+bsd_to_linux_dtv_property(struct dtv_property *vp, struct l_dtv_property *lvp)
+{
+
+ /*
+ * Everything until u.buffer.reserved2 is fixed size so
+ * just memcpy it.
+ */
+ memcpy(lvp, vp, offsetof(struct l_dtv_property, u.buffer.reserved2));
+ /*
+ * The pointer may be garbage since it's part of a union,
+ * currently no Linux code uses it so just set it to NULL.
+ */
+ lvp->u.buffer.reserved2 = PTROUT(NULL);
+ lvp->result = vp->result;
+ return (0);
+}
+
+static int
+linux_ioctl_dvb(struct thread *td, struct linux_ioctl_args *args)
+{
+ struct file *fp;
+ int error, i;
+ struct l_dtv_properties l_vps;
+ struct dtv_properties vps;
+ struct l_dtv_property *l_vp, *l_p;
+ struct dtv_property *vp, *p;
+ size_t l_propsiz, propsiz;
+ vm_offset_t uvp;
+
+ l_vp = NULL;
+ vp = NULL;
+
+ switch (args->cmd & 0xffff) {
+ case LINUX_AUDIO_STOP:
+ case LINUX_AUDIO_PLAY:
+ case LINUX_AUDIO_PAUSE:
+ case LINUX_AUDIO_CONTINUE:
+ case LINUX_AUDIO_SELECT_SOURCE:
+ case LINUX_AUDIO_SET_MUTE:
+ case LINUX_AUDIO_SET_AV_SYNC:
+ case LINUX_AUDIO_SET_BYPASS_MODE:
+ case LINUX_AUDIO_CHANNEL_SELECT:
+ case LINUX_AUDIO_CLEAR_BUFFER:
+ case LINUX_AUDIO_SET_ID:
+ case LINUX_AUDIO_SET_STREAMTYPE:
+ case LINUX_AUDIO_SET_EXT_ID:
+ case LINUX_AUDIO_BILINGUAL_CHANNEL_SELECT:
+ case LINUX_DMX_START:
+ case LINUX_DMX_STOP:
+ case LINUX_DMX_SET_BUFFER_SIZE:
+ case LINUX_NET_REMOVE_IF:
+ case LINUX_FE_DISEQC_RESET_OVERLOAD:
+ case LINUX_FE_DISEQC_SEND_BURST:
+ case LINUX_FE_SET_TONE:
+ case LINUX_FE_SET_VOLTAGE:
+ case LINUX_FE_ENABLE_HIGH_LNB_VOLTAGE:
+ case LINUX_FE_DISHNETWORK_SEND_LEGACY_CMD:
+ case LINUX_FE_SET_FRONTEND_TUNE_MODE:
+ case LINUX_CA_RESET:
+ if ((args->cmd & IOC_DIRMASK) != LINUX_IOC_VOID)
+ return ENOIOCTL;
+ args->cmd = (args->cmd & 0xffff) | IOC_VOID;
+ break;
+
+ case LINUX_DMX_REMOVE_PID:
+ /* overlaps with LINUX_NET_ADD_IF */
+ if ((args->cmd & IOC_DIRMASK) == LINUX_IOC_INOUT)
+ goto net_add_if;
+ /* FALLTHRU */
+ case LINUX_AUDIO_SET_MIXER:
+ case LINUX_AUDIO_SET_ATTRIBUTES:
+ case LINUX_AUDIO_SET_KARAOKE:
+ case LINUX_DMX_SET_FILTER:
+ case LINUX_DMX_SET_PES_FILTER:
+ case LINUX_DMX_SET_SOURCE:
+ case LINUX_DMX_ADD_PID:
+ case LINUX_FE_DISEQC_SEND_MASTER_CMD:
+ case LINUX_FE_SET_FRONTEND:
+ case LINUX_CA_SEND_MSG:
+ case LINUX_CA_SET_DESCR:
+ case LINUX_CA_SET_PID:
+ args->cmd = (args->cmd & ~IOC_DIRMASK) | IOC_IN;
+ break;
+
+ case LINUX_AUDIO_GET_STATUS:
+ case LINUX_AUDIO_GET_CAPABILITIES:
+ case LINUX_AUDIO_GET_PTS:
+ case LINUX_DMX_GET_PES_PIDS:
+ case LINUX_DMX_GET_CAPS:
+ case LINUX_FE_GET_INFO:
+ case LINUX_FE_DISEQC_RECV_SLAVE_REPLY:
+ case LINUX_FE_READ_STATUS:
+ case LINUX_FE_READ_BER:
+ case LINUX_FE_READ_SIGNAL_STRENGTH:
+ case LINUX_FE_READ_SNR:
+ case LINUX_FE_READ_UNCORRECTED_BLOCKS:
+ case LINUX_FE_GET_FRONTEND:
+ case LINUX_FE_GET_EVENT:
+ case LINUX_CA_GET_CAP:
+ case LINUX_CA_GET_SLOT_INFO:
+ case LINUX_CA_GET_DESCR_INFO:
+ case LINUX_CA_GET_MSG:
+ args->cmd = (args->cmd & ~IOC_DIRMASK) | IOC_OUT;
+ break;
+
+ case LINUX_DMX_GET_STC:
+ case LINUX_NET_GET_IF:
+ net_add_if:
+ args->cmd = (args->cmd & ~IOC_DIRMASK) | IOC_INOUT;
+ break;
+
+ case LINUX_FE_SET_PROPERTY:
+ case LINUX_FE_GET_PROPERTY:
+ error = copyin((void *)args->arg, &l_vps, sizeof(l_vps));
+ if (error)
+ return (error);
+ linux_to_bsd_dtv_properties(&l_vps, &vps);
+ if ((vps.num == 0) || vps.num > DTV_IOCTL_MAX_MSGS)
+ return EINVAL;
+
+ l_propsiz = vps.num * sizeof(*l_vp);
+ propsiz = vps.num * sizeof(*vp);
+ l_vp = malloc(l_propsiz, M_LINUX_DVB, M_WAITOK);
+ vp = malloc(propsiz, M_LINUX_DVB, M_WAITOK);
+ error = copyin((void *)vps.props, l_vp, l_propsiz);
+ if (error)
+ goto out2;
+ for (i = vps.num, l_p = l_vp, p = vp; i--; ++l_p, ++p)
+ linux_to_bsd_dtv_property(l_p, p);
+
+ error = copyout_map(td, &uvp, propsiz);
+ if (error)
+ goto out2;
+ copyout(vp, (void *)uvp, propsiz);
+
+ if ((error = fget(td, args->fd, &fp)) != 0) {
+ (void)copyout_unmap(td, uvp, propsiz);
+ goto out2;
+ }
+ vps.props = (void *)uvp;
+ if ((args->cmd & 0xffff) == LINUX_FE_SET_PROPERTY)
+ error = fo_ioctl(fp, FE_SET_PROPERTY, &vps, td->td_ucred, td);
+ else
+ error = fo_ioctl(fp, FE_GET_PROPERTY, &vps, td->td_ucred, td);
+ if (error) {
+ (void)copyout_unmap(td, uvp, propsiz);
+ goto out;
+ }
+ error = copyin((void *)uvp, vp, propsiz);
+ (void)copyout_unmap(td, uvp, propsiz);
+ if (error)
+ goto out;
+ for (i = vps.num, l_p = l_vp, p = vp; i--; ++l_p, ++p)
+ bsd_to_linux_dtv_property(p, l_p);
+ linux_to_bsd_dtv_properties(&l_vps, &vps);
+ copyout(l_vp, (void *)vps.props, l_propsiz);
+
+ out:
+ fdrop(fp, td);
+ out2:
+ if (l_vp)
+ free(l_vp, M_LINUX_DVB);
+ if (vp)
+ free(vp, M_LINUX_DVB);
+ return (error);
+
+ default: return (ENOIOCTL);
+ }
+
+ error = ioctl(td, (struct ioctl_args *)args);
+ return (error);
+}
diff --git a/multimedia/linux_dvbwrapper-kmod/pkg-descr b/multimedia/linux_dvbwrapper-kmod/pkg-descr
new file mode 100644
index 000000000000..8ec4837a4ab8
--- /dev/null
+++ b/multimedia/linux_dvbwrapper-kmod/pkg-descr
@@ -0,0 +1,7 @@
+This kld adds DVB ioctl handling to the Linux compatibility layer
+so that Linux apps can talk to DVB/ATSC tuners via /dev/dvb/adapterX.
+
+Note this port does not contain actual DVB drivers, those are
+provided by e.g. the multimedia/webcamd port.
+
+WWW: http://people.freebsd.org/~nox/dvb/