diff options
author | jasoni <jasoni@cvs.openbsd.org> | 2002-02-06 01:55:05 +0000 |
---|---|---|
committer | jasoni <jasoni@cvs.openbsd.org> | 2002-02-06 01:55:05 +0000 |
commit | 10e53106246dde7c85af170458d4800471d42fbe (patch) | |
tree | bf77088b1edeff4b070bc62ee98c08f9bf0e18a4 /sys/arch | |
parent | 2b70dc0b70be0876e3259be709740d5c4c1066d5 (diff) |
emulate linux behaviour by passing ioctl's down to the underlying device
> From NetBSD; ok art@
Diffstat (limited to 'sys/arch')
-rw-r--r-- | sys/arch/i386/i386/linux_machdep.c | 40 |
1 files changed, 34 insertions, 6 deletions
diff --git a/sys/arch/i386/i386/linux_machdep.c b/sys/arch/i386/i386/linux_machdep.c index a2570f84c6c..355f88540b2 100644 --- a/sys/arch/i386/i386/linux_machdep.c +++ b/sys/arch/i386/i386/linux_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: linux_machdep.c,v 1.18 2002/01/16 20:50:16 miod Exp $ */ +/* $OpenBSD: linux_machdep.c,v 1.19 2002/02/06 01:55:04 jasoni Exp $ */ /* $NetBSD: linux_machdep.c,v 1.29 1996/05/03 19:42:11 christos Exp $ */ /* @@ -111,8 +111,8 @@ linux_sendsig(catcher, sig, mask, code, type, val) int type; union sigval val; { - register struct proc *p = curproc; - register struct trapframe *tf; + struct proc *p = curproc; + struct trapframe *tf; struct linux_sigframe *fp, frame; struct sigacts *psp = p->p_sigacts; int oonstack; @@ -212,7 +212,7 @@ linux_sys_sigreturn(p, v, retval) syscallarg(struct linux_sigcontext *) scp; } */ *uap = v; struct linux_sigcontext *scp, context; - register struct trapframe *tf; + struct trapframe *tf; tf = p->p_md.md_regs; @@ -451,11 +451,21 @@ linux_machdepioctl(p, v, retval) struct vt_mode lvt; caddr_t bvtp, sg; #endif + struct filedesc *fdp; + struct file *fp; + int fd; + int (*ioctlf) __P((struct file *, u_long, caddr_t, struct proc *)); + struct ioctl_pt pt; + fd = SCARG(uap, fd); SCARG(&bia, fd) = SCARG(uap, fd); SCARG(&bia, data) = SCARG(uap, data); com = SCARG(uap, com); + fdp = p->p_fd; + if ((fp = fd_getfile(fdp, fd)) == NULL) + return (EBADF); + switch (com) { #if (NWSDISPLAY > 0 && defined(WSDISPLAY_COMPAT_USL)) case LINUX_KDGKBMODE: @@ -570,8 +580,26 @@ linux_machdepioctl(p, v, retval) return (subyte(SCARG(uap, data), KB_101)); #endif default: - printf("linux_machdepioctl: invalid ioctl %08lx\n", com); - return EINVAL; + /* + * Unknown to us. If it's on a device, just pass it through + * using PTIOCLINUX, the device itself might be able to + * make some sense of it. + * XXX hack: if the function returns EJUSTRETURN, + * it has stuffed a sysctl return value in pt.data. + */ + ioctlf = fp->f_ops->fo_ioctl; + pt.com = SCARG(uap, com); + pt.data = SCARG(uap, data); + error = ioctlf(fp, PTIOCLINUX, (caddr_t)&pt, p); + if (error == EJUSTRETURN) { + retval[0] = (register_t)pt.data; + error = 0; + } + + if (error == ENOTTY) + printf("linux_machdepioctl: invalid ioctl %08lx\n", + com); + return (error); } SCARG(&bia, com) = com; return sys_ioctl(p, &bia, retval); |