diff options
author | nox <nox@FreeBSD.org> | 2011-04-24 23:51:13 +0800 |
---|---|---|
committer | nox <nox@FreeBSD.org> | 2011-04-24 23:51:13 +0800 |
commit | d5d0ef9be4d632e8a30d18b93698663f4b3a1a05 (patch) | |
tree | 98a1e45e31094c2d77e76cebd1b1aaebafc38d00 | |
parent | 5f10932f6ef5448855e151c53c14963c12c548a5 (diff) | |
download | freebsd-ports-gnome-d5d0ef9be4d632e8a30d18b93698663f4b3a1a05.tar.gz freebsd-ports-gnome-d5d0ef9be4d632e8a30d18b93698663f4b3a1a05.tar.zst freebsd-ports-gnome-d5d0ef9be4d632e8a30d18b93698663f4b3a1a05.zip |
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/
-rw-r--r-- | multimedia/Makefile | 1 | ||||
-rw-r--r-- | multimedia/linux_dvbwrapper-kmod/Makefile | 43 | ||||
-rw-r--r-- | multimedia/linux_dvbwrapper-kmod/files/Makefile | 13 | ||||
-rw-r--r-- | multimedia/linux_dvbwrapper-kmod/files/linux_dvb.h | 63 | ||||
-rw-r--r-- | multimedia/linux_dvbwrapper-kmod/files/linux_dvb_compat.h | 26 | ||||
-rw-r--r-- | multimedia/linux_dvbwrapper-kmod/files/linux_dvb_ioctl.h | 122 | ||||
-rw-r--r-- | multimedia/linux_dvbwrapper-kmod/files/linux_dvbwrapper.c | 334 | ||||
-rw-r--r-- | multimedia/linux_dvbwrapper-kmod/pkg-descr | 7 |
8 files changed, 609 insertions, 0 deletions
diff --git a/multimedia/Makefile b/multimedia/Makefile index 667b33412bea..b3794f024252 100644 --- a/multimedia/Makefile +++ b/multimedia/Makefile @@ -181,6 +181,7 @@ SUBDIR += linux-realplayer SUBDIR += linux-tsmuxer SUBDIR += linux-xmovie + SUBDIR += linux_dvbwrapper-kmod SUBDIR += lives SUBDIR += lsdvd SUBDIR += lxdvdrip 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/ |