1ae528485SDavid E. O'Brien /*- 2ae528485SDavid E. O'Brien * Copyright (c) 2008 David E. O'Brien 3ae528485SDavid E. O'Brien * All rights reserved. 4ae528485SDavid E. O'Brien * 5ae528485SDavid E. O'Brien * Redistribution and use in source and binary forms, with or without 6ae528485SDavid E. O'Brien * modification, are permitted provided that the following conditions 7ae528485SDavid E. O'Brien * are met: 8ae528485SDavid E. O'Brien * 1. Redistributions of source code must retain the above copyright 9ae528485SDavid E. O'Brien * notice, this list of conditions and the following disclaimer. 10ae528485SDavid E. O'Brien * 2. Redistributions in binary form must reproduce the above copyright 11ae528485SDavid E. O'Brien * notice, this list of conditions and the following disclaimer in the 12ae528485SDavid E. O'Brien * documentation and/or other materials provided with the distribution. 13ae528485SDavid E. O'Brien * 3. Neither the name of the author nor the names of its contributors 14ae528485SDavid E. O'Brien * may be used to endorse or promote products derived from this software 15ae528485SDavid E. O'Brien * without specific prior written permission. 16ae528485SDavid E. O'Brien * 17ae528485SDavid E. O'Brien * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18ae528485SDavid E. O'Brien * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19ae528485SDavid E. O'Brien * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20ae528485SDavid E. O'Brien * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21ae528485SDavid E. O'Brien * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22ae528485SDavid E. O'Brien * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23ae528485SDavid E. O'Brien * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24ae528485SDavid E. O'Brien * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25ae528485SDavid E. O'Brien * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26ae528485SDavid E. O'Brien * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27ae528485SDavid E. O'Brien * SUCH DAMAGE. 28ae528485SDavid E. O'Brien */ 29ae528485SDavid E. O'Brien 30ae528485SDavid E. O'Brien #include <sys/cdefs.h> 31ae528485SDavid E. O'Brien __FBSDID("$FreeBSD$"); 32ae528485SDavid E. O'Brien 33ae528485SDavid E. O'Brien #include "opt_compat.h" 34ae528485SDavid E. O'Brien 35ae528485SDavid E. O'Brien #include <sys/param.h> 36ae528485SDavid E. O'Brien #include <sys/cdio.h> 37ae528485SDavid E. O'Brien #include <sys/fcntl.h> 38ae528485SDavid E. O'Brien #include <sys/file.h> 39ae528485SDavid E. O'Brien #include <sys/ioccom.h> 40ae528485SDavid E. O'Brien #include <sys/mdioctl.h> 41ae528485SDavid E. O'Brien #include <sys/proc.h> 42ae528485SDavid E. O'Brien #include <sys/syscall.h> 43ae528485SDavid E. O'Brien #include <sys/syscallsubr.h> 44ae528485SDavid E. O'Brien #include <sys/sysctl.h> 45ae528485SDavid E. O'Brien #include <sys/sysent.h> 46ae528485SDavid E. O'Brien #include <sys/sysproto.h> 47ae528485SDavid E. O'Brien #include <sys/systm.h> 48ae528485SDavid E. O'Brien 49ae528485SDavid E. O'Brien #include <compat/freebsd32/freebsd32.h> 50ae528485SDavid E. O'Brien #include <compat/freebsd32/freebsd32_ioctl.h> 51ae528485SDavid E. O'Brien #include <compat/freebsd32/freebsd32_proto.h> 52ae528485SDavid E. O'Brien 53ae528485SDavid E. O'Brien /* Cannot get exact size in 64-bit due to alignment issue of entire struct. */ 54ae528485SDavid E. O'Brien CTASSERT((sizeof(struct md_ioctl32)+4) == 436); 55ae528485SDavid E. O'Brien 56ae528485SDavid E. O'Brien 57ae528485SDavid E. O'Brien static int 58ae528485SDavid E. O'Brien freebsd32_ioctl_md(struct thread *td, struct freebsd32_ioctl_args *uap, 59ae528485SDavid E. O'Brien struct file *fp) 60ae528485SDavid E. O'Brien { 61ae528485SDavid E. O'Brien struct md_ioctl mdv; 62ae528485SDavid E. O'Brien struct md_ioctl32 md32; 63ae528485SDavid E. O'Brien u_long com = 0; 64ae528485SDavid E. O'Brien int error; 65ae528485SDavid E. O'Brien 66ae528485SDavid E. O'Brien if (uap->data == NULL) 67ae528485SDavid E. O'Brien panic("%s: where is my ioctl data??", __func__); 68ae528485SDavid E. O'Brien if (uap->com & IOC_IN) { 69ae528485SDavid E. O'Brien if ((error = copyin(uap->data, &md32, sizeof(md32)))) { 70ae528485SDavid E. O'Brien fdrop(fp, td); 71ae528485SDavid E. O'Brien return (error); 72ae528485SDavid E. O'Brien } 73ae528485SDavid E. O'Brien CP(md32, mdv, md_version); 74ae528485SDavid E. O'Brien CP(md32, mdv, md_unit); 75ae528485SDavid E. O'Brien CP(md32, mdv, md_type); 76ae528485SDavid E. O'Brien PTRIN_CP(md32, mdv, md_file); 77ae528485SDavid E. O'Brien CP(md32, mdv, md_mediasize); 78ae528485SDavid E. O'Brien CP(md32, mdv, md_sectorsize); 79ae528485SDavid E. O'Brien CP(md32, mdv, md_options); 80ae528485SDavid E. O'Brien CP(md32, mdv, md_base); 81ae528485SDavid E. O'Brien CP(md32, mdv, md_fwheads); 82ae528485SDavid E. O'Brien CP(md32, mdv, md_fwsectors); 83ae528485SDavid E. O'Brien } else if (uap->com & IOC_OUT) { 84ae528485SDavid E. O'Brien /* 85ae528485SDavid E. O'Brien * Zero the buffer so the user always 86ae528485SDavid E. O'Brien * gets back something deterministic. 87ae528485SDavid E. O'Brien */ 88ae528485SDavid E. O'Brien bzero(&mdv, sizeof mdv); 89ae528485SDavid E. O'Brien } 90ae528485SDavid E. O'Brien 91ae528485SDavid E. O'Brien switch (uap->com) { 92ae528485SDavid E. O'Brien case MDIOCATTACH_32: 93ae528485SDavid E. O'Brien com = MDIOCATTACH; 94ae528485SDavid E. O'Brien break; 95ae528485SDavid E. O'Brien case MDIOCDETACH_32: 96ae528485SDavid E. O'Brien com = MDIOCDETACH; 97ae528485SDavid E. O'Brien break; 98ae528485SDavid E. O'Brien case MDIOCQUERY_32: 99ae528485SDavid E. O'Brien com = MDIOCQUERY; 100ae528485SDavid E. O'Brien break; 101ae528485SDavid E. O'Brien case MDIOCLIST_32: 102ae528485SDavid E. O'Brien com = MDIOCLIST; 103ae528485SDavid E. O'Brien break; 104ae528485SDavid E. O'Brien default: 105ae528485SDavid E. O'Brien panic("%s: unknown MDIOC %#x", __func__, uap->com); 106ae528485SDavid E. O'Brien } 107ae528485SDavid E. O'Brien error = fo_ioctl(fp, com, (caddr_t)&mdv, td->td_ucred, td); 108ae528485SDavid E. O'Brien if (error == 0 && (com & IOC_OUT)) { 109ae528485SDavid E. O'Brien CP(mdv, md32, md_version); 110ae528485SDavid E. O'Brien CP(mdv, md32, md_unit); 111ae528485SDavid E. O'Brien CP(mdv, md32, md_type); 112ae528485SDavid E. O'Brien PTROUT_CP(mdv, md32, md_file); 113ae528485SDavid E. O'Brien CP(mdv, md32, md_mediasize); 114ae528485SDavid E. O'Brien CP(mdv, md32, md_sectorsize); 115ae528485SDavid E. O'Brien CP(mdv, md32, md_options); 116ae528485SDavid E. O'Brien CP(mdv, md32, md_base); 117ae528485SDavid E. O'Brien CP(mdv, md32, md_fwheads); 118ae528485SDavid E. O'Brien CP(mdv, md32, md_fwsectors); 119ae528485SDavid E. O'Brien error = copyout(&md32, uap->data, sizeof(md32)); 120ae528485SDavid E. O'Brien } 121ae528485SDavid E. O'Brien fdrop(fp, td); 122ae528485SDavid E. O'Brien return error; 123ae528485SDavid E. O'Brien } 124ae528485SDavid E. O'Brien 125ae528485SDavid E. O'Brien 126ae528485SDavid E. O'Brien int 127ae528485SDavid E. O'Brien freebsd32_ioctl(struct thread *td, struct freebsd32_ioctl_args *uap) 128ae528485SDavid E. O'Brien { 129ae528485SDavid E. O'Brien struct ioctl_args ap /*{ 130ae528485SDavid E. O'Brien int fd; 131ae528485SDavid E. O'Brien u_long com; 132ae528485SDavid E. O'Brien caddr_t data; 133ae528485SDavid E. O'Brien }*/ ; 134ae528485SDavid E. O'Brien struct file *fp; 135ae528485SDavid E. O'Brien int error; 136ae528485SDavid E. O'Brien 137ae528485SDavid E. O'Brien if ((error = fget(td, uap->fd, &fp)) != 0) 138ae528485SDavid E. O'Brien return (error); 139ae528485SDavid E. O'Brien if ((fp->f_flag & (FREAD | FWRITE)) == 0) { 140ae528485SDavid E. O'Brien fdrop(fp, td); 141ae528485SDavid E. O'Brien return (EBADF); 142ae528485SDavid E. O'Brien } 143ae528485SDavid E. O'Brien 144ae528485SDavid E. O'Brien switch (uap->com) { 145ae528485SDavid E. O'Brien case MDIOCATTACH_32: /* FALLTHROUGH */ 146ae528485SDavid E. O'Brien case MDIOCDETACH_32: /* FALLTHROUGH */ 147ae528485SDavid E. O'Brien case MDIOCQUERY_32: /* FALLTHROUGH */ 148ae528485SDavid E. O'Brien case MDIOCLIST_32: 149ae528485SDavid E. O'Brien return freebsd32_ioctl_md(td, uap, fp); 150ae528485SDavid E. O'Brien 151ae528485SDavid E. O'Brien default: 152ae528485SDavid E. O'Brien fdrop(fp, td); 153ae528485SDavid E. O'Brien ap.fd = uap->fd; 154ae528485SDavid E. O'Brien ap.com = uap->com; 155ae528485SDavid E. O'Brien PTRIN_CP(*uap, ap, data); 156ae528485SDavid E. O'Brien return ioctl(td, &ap); 157ae528485SDavid E. O'Brien } 158ae528485SDavid E. O'Brien } 159