#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: linux32_ioctl.c,v 1.15 2021/09/19 23:51:37 thorpej Exp $");
#include <sys/types.h>
#include <sys/param.h>
#include <sys/time.h>
#include <sys/ucred.h>
#include <sys/ioctl.h>
#include <sys/file.h>
#include <sys/filedesc.h>
#include <compat/netbsd32/netbsd32.h>
#include <compat/netbsd32/netbsd32_syscallargs.h>
#include <compat/linux/common/linux_types.h>
#include <compat/linux/common/linux_signal.h>
#include <compat/linux/common/linux_ipc.h>
#include <compat/linux/common/linux_ioctl.h>
#include <compat/linux/common/linux_sem.h>
#include <compat/linux/linux_syscallargs.h>
#include <compat/linux32/common/linux32_types.h>
#include <compat/linux32/common/linux32_signal.h>
#include <compat/linux32/common/linux32_ioctl.h>
#include <compat/linux32/common/linux32_termios.h>
#include <compat/linux32/common/linux32_sysctl.h>
#include <compat/linux32/linux32_syscallargs.h>
#include <compat/ossaudio/ossaudio.h>
#include <compat/ossaudio/ossaudiovar.h>
int
linux32_sys_ioctl(struct lwp *l, const struct linux32_sys_ioctl_args *uap, register_t *retval)
{
struct oss_sys_ioctl_args ossuap;
int group;
int error;
group = LINUX32_IOCGROUP((int)SCARG(uap, com));
#ifdef DEBUG_LINUX
printf("linux32_sys_ioctl(%d, 0x%x/\'%c\', %p)\n", SCARG(uap, fd),
SCARG(uap, com), (char)group, SCARG_P32(uap, data));
#endif
switch(group) {
case 'T':
{
struct file *fp;
if ((fp = fd_getfile(SCARG(uap, fd))) == NULL)
return EBADF;
if (fp->f_type == DTYPE_TIMERFD) {
struct linux_sys_ioctl_args ua;
SCARG(&ua, fd) = SCARG(uap, fd);
SCARG(&ua, com) = SCARG(uap, com);
SCARG(&ua, data) = SCARG_P32(uap, data);
error = linux_ioctl_timerfd(l, &ua, retval);
} else {
error = linux32_ioctl_termios(l, uap, retval);
}
fd_putfile(SCARG(uap, fd));
break;
}
case 'M':
case 'Q':
case 'P':
SCARG(&ossuap, fd) = SCARG(uap, fd);
SCARG(&ossuap, com) = (u_long)SCARG(uap, com);
SCARG(&ossuap, data) = SCARG_P32(uap, data);
switch (group) {
case 'M':
error = oss_ioctl_mixer(l, &ossuap, retval);
break;
case 'Q':
error = oss_ioctl_sequencer(l, &ossuap, retval);
break;
case 'P':
error = oss_ioctl_audio(l, &ossuap, retval);
break;
default:
error = EINVAL;
break;
}
break;
case 'V':
case 'd':
{
struct sys_ioctl_args ua;
u_long com = 0;
if (SCARG(uap, com) & IOC_IN)
com |= IOC_OUT;
if (SCARG(uap, com) & IOC_OUT)
com |= IOC_IN;
SCARG(&ua, fd) = SCARG(uap, fd);
SCARG(&ua, com) = SCARG(uap, com);
SCARG(&ua, com) &= ~IOC_DIRMASK;
SCARG(&ua, com) |= com;
SCARG(&ua, data) = SCARG_P32(uap, data);
error = sys_ioctl(l, (const void *)&ua, retval);
break;
}
case 0x89:
error = linux32_ioctl_socket(l, uap, retval);
break;
default:
#ifdef DEBUG_LINUX
printf("Not yet implemented ioctl group \'%c\'\n", group);
#endif
error = EINVAL;
break;
}
if (error == EPASSTHROUGH)
error = EINVAL;
return error;
}