diff --git a/sys/compat/freebsd32/freebsd32_ioctl.c b/sys/compat/freebsd32/freebsd32_ioctl.c new file mode 100644 index 00000000000..a46b0b9ced0 --- /dev/null +++ b/sys/compat/freebsd32/freebsd32_ioctl.c @@ -0,0 +1,158 @@ +/*- + * Copyright (c) 2008 David E. O'Brien + * 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. Neither the name of the author 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 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 +__FBSDID("$FreeBSD$"); + +#include "opt_compat.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +/* Cannot get exact size in 64-bit due to alignment issue of entire struct. */ +CTASSERT((sizeof(struct md_ioctl32)+4) == 436); + + +static int +freebsd32_ioctl_md(struct thread *td, struct freebsd32_ioctl_args *uap, + struct file *fp) +{ + struct md_ioctl mdv; + struct md_ioctl32 md32; + u_long com = 0; + int error; + + if (uap->data == NULL) + panic("%s: where is my ioctl data??", __func__); + if (uap->com & IOC_IN) { + if ((error = copyin(uap->data, &md32, sizeof(md32)))) { + fdrop(fp, td); + return (error); + } + CP(md32, mdv, md_version); + CP(md32, mdv, md_unit); + CP(md32, mdv, md_type); + PTRIN_CP(md32, mdv, md_file); + CP(md32, mdv, md_mediasize); + CP(md32, mdv, md_sectorsize); + CP(md32, mdv, md_options); + CP(md32, mdv, md_base); + CP(md32, mdv, md_fwheads); + CP(md32, mdv, md_fwsectors); + } else if (uap->com & IOC_OUT) { + /* + * Zero the buffer so the user always + * gets back something deterministic. + */ + bzero(&mdv, sizeof mdv); + } + + switch (uap->com) { + case MDIOCATTACH_32: + com = MDIOCATTACH; + break; + case MDIOCDETACH_32: + com = MDIOCDETACH; + break; + case MDIOCQUERY_32: + com = MDIOCQUERY; + break; + case MDIOCLIST_32: + com = MDIOCLIST; + break; + default: + panic("%s: unknown MDIOC %#x", __func__, uap->com); + } + error = fo_ioctl(fp, com, (caddr_t)&mdv, td->td_ucred, td); + if (error == 0 && (com & IOC_OUT)) { + CP(mdv, md32, md_version); + CP(mdv, md32, md_unit); + CP(mdv, md32, md_type); + PTROUT_CP(mdv, md32, md_file); + CP(mdv, md32, md_mediasize); + CP(mdv, md32, md_sectorsize); + CP(mdv, md32, md_options); + CP(mdv, md32, md_base); + CP(mdv, md32, md_fwheads); + CP(mdv, md32, md_fwsectors); + error = copyout(&md32, uap->data, sizeof(md32)); + } + fdrop(fp, td); + return error; +} + + +int +freebsd32_ioctl(struct thread *td, struct freebsd32_ioctl_args *uap) +{ + struct ioctl_args ap /*{ + int fd; + u_long com; + caddr_t data; + }*/ ; + struct file *fp; + int error; + + if ((error = fget(td, uap->fd, &fp)) != 0) + return (error); + if ((fp->f_flag & (FREAD | FWRITE)) == 0) { + fdrop(fp, td); + return (EBADF); + } + + switch (uap->com) { + case MDIOCATTACH_32: /* FALLTHROUGH */ + case MDIOCDETACH_32: /* FALLTHROUGH */ + case MDIOCQUERY_32: /* FALLTHROUGH */ + case MDIOCLIST_32: + return freebsd32_ioctl_md(td, uap, fp); + + default: + fdrop(fp, td); + ap.fd = uap->fd; + ap.com = uap->com; + PTRIN_CP(*uap, ap, data); + return ioctl(td, &ap); + } +} diff --git a/sys/compat/freebsd32/freebsd32_ioctl.h b/sys/compat/freebsd32/freebsd32_ioctl.h new file mode 100644 index 00000000000..772c8b46fe2 --- /dev/null +++ b/sys/compat/freebsd32/freebsd32_ioctl.h @@ -0,0 +1,56 @@ +/*- + * Copyright (c) 2008 David E. O'Brien + * 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. Neither the name of the author 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 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. + * + * $FreeBSD$ + */ + +#ifndef _COMPAT_FREEBSD32_IOCTL_H_ +#define _COMPAT_FREEBSD32_IOCTL_H_ + +typedef __uint32_t caddr_t32; +#define MDNPAD32 MDNPAD - 1 +struct md_ioctl32 { + unsigned md_version; /* Structure layout version */ + unsigned md_unit; /* unit number */ + enum md_types md_type; /* type of disk */ + caddr_t32 md_file; /* pathname of file to mount */ + off_t md_mediasize; /* size of disk in bytes */ + unsigned md_sectorsize; /* sectorsize */ + unsigned md_options; /* options */ + u_int64_t md_base; /* base address */ + int md_fwheads; /* firmware heads */ + int md_fwsectors; /* firmware sectors */ + int md_pad[MDNPAD32]; /* padding for future ideas */ +}; + +#define MDIOCATTACH_32 _IOC(IOC_INOUT, 'm', 0, sizeof(struct md_ioctl32) + 4) +#define MDIOCDETACH_32 _IOC(IOC_INOUT, 'm', 1, sizeof(struct md_ioctl32) + 4) +#define MDIOCQUERY_32 _IOC(IOC_INOUT, 'm', 2, sizeof(struct md_ioctl32) + 4) +#define MDIOCLIST_32 _IOC(IOC_INOUT, 'm', 3, sizeof(struct md_ioctl32) + 4) + +#endif /* _COMPAT_FREEBSD32_IOCTL_H_ */ diff --git a/sys/compat/freebsd32/syscalls.master b/sys/compat/freebsd32/syscalls.master index 3fedb3e4410..576b85f5e20 100644 --- a/sys/compat/freebsd32/syscalls.master +++ b/sys/compat/freebsd32/syscalls.master @@ -134,8 +134,8 @@ 53 AUE_SIGALTSTACK STD { int freebsd32_sigaltstack( \ struct sigaltstack32 *ss, \ struct sigaltstack32 *oss); } -54 AUE_IOCTL NOPROTO { int ioctl(int fd, u_long com, \ - caddr_t data); } +54 AUE_NULL STD { int freebsd32_ioctl(int fd, uint32_t com, \ + struct md_ioctl32 *data); } 55 AUE_REBOOT NOPROTO { int reboot(int opt); } 56 AUE_REVOKE NOPROTO { int revoke(char *path); } 57 AUE_SYMLINK NOPROTO { int symlink(char *path, char *link); } diff --git a/sys/conf/files.amd64 b/sys/conf/files.amd64 index ee838a76b8f..cea36950bcd 100644 --- a/sys/conf/files.amd64 +++ b/sys/conf/files.amd64 @@ -220,6 +220,7 @@ amd64/ia32/ia32_reg.c optional compat_ia32 amd64/ia32/ia32_signal.c optional compat_ia32 amd64/ia32/ia32_sigtramp.S optional compat_ia32 amd64/ia32/ia32_syscall.c optional compat_ia32 +compat/freebsd32/freebsd32_ioctl.c optional compat_ia32 compat/freebsd32/freebsd32_misc.c optional compat_ia32 compat/freebsd32/freebsd32_syscalls.c optional compat_ia32 compat/freebsd32/freebsd32_sysent.c optional compat_ia32 diff --git a/sys/conf/files.ia64 b/sys/conf/files.ia64 index 3824fe43d00..6556fbb6793 100644 --- a/sys/conf/files.ia64 +++ b/sys/conf/files.ia64 @@ -28,6 +28,7 @@ ukbdmap.h optional ukbd_dflt_keymap \ no-obj no-implicit-rule before-depend \ clean "ukbdmap.h" # +compat/freebsd32/freebsd32_ioctl.c optional compat_ia32 compat/freebsd32/freebsd32_misc.c optional compat_ia32 compat/freebsd32/freebsd32_syscalls.c optional compat_ia32 compat/freebsd32/freebsd32_sysent.c optional compat_ia32