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> 387eac36edSEd Schouten #include <sys/filio.h> 39ae528485SDavid E. O'Brien #include <sys/file.h> 40ae528485SDavid E. O'Brien #include <sys/ioccom.h> 41*bfac1583SKonstantin Belousov #include <sys/malloc.h> 42ae528485SDavid E. O'Brien #include <sys/mdioctl.h> 43*bfac1583SKonstantin Belousov #include <sys/memrange.h> 44ae528485SDavid E. O'Brien #include <sys/proc.h> 45ae528485SDavid E. O'Brien #include <sys/syscall.h> 46ae528485SDavid E. O'Brien #include <sys/syscallsubr.h> 47ae528485SDavid E. O'Brien #include <sys/sysctl.h> 48ae528485SDavid E. O'Brien #include <sys/sysent.h> 49ae528485SDavid E. O'Brien #include <sys/sysproto.h> 50ae528485SDavid E. O'Brien #include <sys/systm.h> 51ae528485SDavid E. O'Brien 52ae528485SDavid E. O'Brien #include <compat/freebsd32/freebsd32.h> 53ae528485SDavid E. O'Brien #include <compat/freebsd32/freebsd32_ioctl.h> 54ae528485SDavid E. O'Brien #include <compat/freebsd32/freebsd32_proto.h> 55ae528485SDavid E. O'Brien 56ae528485SDavid E. O'Brien /* Cannot get exact size in 64-bit due to alignment issue of entire struct. */ 57ae528485SDavid E. O'Brien CTASSERT((sizeof(struct md_ioctl32)+4) == 436); 58c750e17cSDavid E. O'Brien CTASSERT(sizeof(struct ioc_read_toc_entry32) == 8); 59c750e17cSDavid E. O'Brien CTASSERT(sizeof(struct ioc_toc_header32) == 4); 60*bfac1583SKonstantin Belousov CTASSERT(sizeof(struct mem_range_op32) == 12); 61ae528485SDavid E. O'Brien 62ae528485SDavid E. O'Brien 63ae528485SDavid E. O'Brien static int 64ae528485SDavid E. O'Brien freebsd32_ioctl_md(struct thread *td, struct freebsd32_ioctl_args *uap, 65ae528485SDavid E. O'Brien struct file *fp) 66ae528485SDavid E. O'Brien { 67ae528485SDavid E. O'Brien struct md_ioctl mdv; 68ae528485SDavid E. O'Brien struct md_ioctl32 md32; 69ae528485SDavid E. O'Brien u_long com = 0; 70bc13c742SKonstantin Belousov int i, error; 71ae528485SDavid E. O'Brien 72ae528485SDavid E. O'Brien if (uap->com & IOC_IN) { 73ae528485SDavid E. O'Brien if ((error = copyin(uap->data, &md32, sizeof(md32)))) { 74ae528485SDavid E. O'Brien return (error); 75ae528485SDavid E. O'Brien } 76ae528485SDavid E. O'Brien CP(md32, mdv, md_version); 77ae528485SDavid E. O'Brien CP(md32, mdv, md_unit); 78ae528485SDavid E. O'Brien CP(md32, mdv, md_type); 79ae528485SDavid E. O'Brien PTRIN_CP(md32, mdv, md_file); 80ae528485SDavid E. O'Brien CP(md32, mdv, md_mediasize); 81ae528485SDavid E. O'Brien CP(md32, mdv, md_sectorsize); 82ae528485SDavid E. O'Brien CP(md32, mdv, md_options); 83ae528485SDavid E. O'Brien CP(md32, mdv, md_base); 84ae528485SDavid E. O'Brien CP(md32, mdv, md_fwheads); 85ae528485SDavid E. O'Brien CP(md32, mdv, md_fwsectors); 86ae528485SDavid E. O'Brien } else if (uap->com & IOC_OUT) { 87ae528485SDavid E. O'Brien /* 88ae528485SDavid E. O'Brien * Zero the buffer so the user always 89ae528485SDavid E. O'Brien * gets back something deterministic. 90ae528485SDavid E. O'Brien */ 91ae528485SDavid E. O'Brien bzero(&mdv, sizeof mdv); 92ae528485SDavid E. O'Brien } 93ae528485SDavid E. O'Brien 94ae528485SDavid E. O'Brien switch (uap->com) { 95ae528485SDavid E. O'Brien case MDIOCATTACH_32: 96ae528485SDavid E. O'Brien com = MDIOCATTACH; 97ae528485SDavid E. O'Brien break; 98ae528485SDavid E. O'Brien case MDIOCDETACH_32: 99ae528485SDavid E. O'Brien com = MDIOCDETACH; 100ae528485SDavid E. O'Brien break; 101ae528485SDavid E. O'Brien case MDIOCQUERY_32: 102ae528485SDavid E. O'Brien com = MDIOCQUERY; 103ae528485SDavid E. O'Brien break; 104ae528485SDavid E. O'Brien case MDIOCLIST_32: 105ae528485SDavid E. O'Brien com = MDIOCLIST; 106ae528485SDavid E. O'Brien break; 107ae528485SDavid E. O'Brien default: 108ae528485SDavid E. O'Brien panic("%s: unknown MDIOC %#x", __func__, uap->com); 109ae528485SDavid E. O'Brien } 110ae528485SDavid E. O'Brien error = fo_ioctl(fp, com, (caddr_t)&mdv, td->td_ucred, td); 111ae528485SDavid E. O'Brien if (error == 0 && (com & IOC_OUT)) { 112ae528485SDavid E. O'Brien CP(mdv, md32, md_version); 113ae528485SDavid E. O'Brien CP(mdv, md32, md_unit); 114ae528485SDavid E. O'Brien CP(mdv, md32, md_type); 115ae528485SDavid E. O'Brien PTROUT_CP(mdv, md32, md_file); 116ae528485SDavid E. O'Brien CP(mdv, md32, md_mediasize); 117ae528485SDavid E. O'Brien CP(mdv, md32, md_sectorsize); 118ae528485SDavid E. O'Brien CP(mdv, md32, md_options); 119ae528485SDavid E. O'Brien CP(mdv, md32, md_base); 120ae528485SDavid E. O'Brien CP(mdv, md32, md_fwheads); 121ae528485SDavid E. O'Brien CP(mdv, md32, md_fwsectors); 122bc13c742SKonstantin Belousov if (com == MDIOCLIST) { 123bc13c742SKonstantin Belousov /* 124bc13c742SKonstantin Belousov * Use MDNPAD, and not MDNPAD32. Padding is 125bc13c742SKonstantin Belousov * allocated and used by compat32 ABI. 126bc13c742SKonstantin Belousov */ 127bc13c742SKonstantin Belousov for (i = 0; i < MDNPAD; i++) 128bc13c742SKonstantin Belousov CP(mdv, md32, md_pad[i]); 129bc13c742SKonstantin Belousov } 130ae528485SDavid E. O'Brien error = copyout(&md32, uap->data, sizeof(md32)); 131ae528485SDavid E. O'Brien } 132ae528485SDavid E. O'Brien return error; 133ae528485SDavid E. O'Brien } 134ae528485SDavid E. O'Brien 135ae528485SDavid E. O'Brien 136c750e17cSDavid E. O'Brien static int 137c750e17cSDavid E. O'Brien freebsd32_ioctl_ioc_toc_header(struct thread *td, 138c750e17cSDavid E. O'Brien struct freebsd32_ioctl_args *uap, struct file *fp) 139c750e17cSDavid E. O'Brien { 140c750e17cSDavid E. O'Brien struct ioc_toc_header toch; 141c750e17cSDavid E. O'Brien struct ioc_toc_header32 toch32; 142c750e17cSDavid E. O'Brien int error; 143c750e17cSDavid E. O'Brien 144c750e17cSDavid E. O'Brien if ((error = copyin(uap->data, &toch32, sizeof(toch32)))) 145c750e17cSDavid E. O'Brien return (error); 146c750e17cSDavid E. O'Brien CP(toch32, toch, len); 147c750e17cSDavid E. O'Brien CP(toch32, toch, starting_track); 148c750e17cSDavid E. O'Brien CP(toch32, toch, ending_track); 149c750e17cSDavid E. O'Brien error = fo_ioctl(fp, CDIOREADTOCHEADER, (caddr_t)&toch, 150c750e17cSDavid E. O'Brien td->td_ucred, td); 151c750e17cSDavid E. O'Brien return (error); 152c750e17cSDavid E. O'Brien } 153c750e17cSDavid E. O'Brien 154c750e17cSDavid E. O'Brien 155c750e17cSDavid E. O'Brien static int 156c750e17cSDavid E. O'Brien freebsd32_ioctl_ioc_read_toc(struct thread *td, 157c750e17cSDavid E. O'Brien struct freebsd32_ioctl_args *uap, struct file *fp) 158c750e17cSDavid E. O'Brien { 159c750e17cSDavid E. O'Brien struct ioc_read_toc_entry toce; 160c750e17cSDavid E. O'Brien struct ioc_read_toc_entry32 toce32; 161c750e17cSDavid E. O'Brien int error; 162c750e17cSDavid E. O'Brien 163c750e17cSDavid E. O'Brien if ((error = copyin(uap->data, &toce32, sizeof(toce32)))) 164c750e17cSDavid E. O'Brien return (error); 165c750e17cSDavid E. O'Brien CP(toce32, toce, address_format); 166c750e17cSDavid E. O'Brien CP(toce32, toce, starting_track); 167c750e17cSDavid E. O'Brien CP(toce32, toce, data_len); 168c750e17cSDavid E. O'Brien PTRIN_CP(toce32, toce, data); 169c750e17cSDavid E. O'Brien 170c750e17cSDavid E. O'Brien if ((error = fo_ioctl(fp, CDIOREADTOCENTRYS, (caddr_t)&toce, 171c750e17cSDavid E. O'Brien td->td_ucred, td))) { 172c750e17cSDavid E. O'Brien CP(toce, toce32, address_format); 173c750e17cSDavid E. O'Brien CP(toce, toce32, starting_track); 174c750e17cSDavid E. O'Brien CP(toce, toce32, data_len); 175c750e17cSDavid E. O'Brien PTROUT_CP(toce, toce32, data); 176c750e17cSDavid E. O'Brien error = copyout(&toce32, uap->data, sizeof(toce32)); 177c750e17cSDavid E. O'Brien } 178c750e17cSDavid E. O'Brien return error; 179c750e17cSDavid E. O'Brien } 180c750e17cSDavid E. O'Brien 1817eac36edSEd Schouten static int 1827eac36edSEd Schouten freebsd32_ioctl_fiodgname(struct thread *td, 1837eac36edSEd Schouten struct freebsd32_ioctl_args *uap, struct file *fp) 1847eac36edSEd Schouten { 1857eac36edSEd Schouten struct fiodgname_arg fgn; 1867eac36edSEd Schouten struct fiodgname_arg32 fgn32; 1877eac36edSEd Schouten int error; 1887eac36edSEd Schouten 1897eac36edSEd Schouten if ((error = copyin(uap->data, &fgn32, sizeof fgn32)) != 0) 1907eac36edSEd Schouten return (error); 1917eac36edSEd Schouten CP(fgn32, fgn, len); 1927eac36edSEd Schouten PTRIN_CP(fgn32, fgn, buf); 1937eac36edSEd Schouten error = fo_ioctl(fp, FIODGNAME, (caddr_t)&fgn, td->td_ucred, td); 1947eac36edSEd Schouten return (error); 1957eac36edSEd Schouten } 196c750e17cSDavid E. O'Brien 197*bfac1583SKonstantin Belousov static int 198*bfac1583SKonstantin Belousov freebsd32_ioctl_memrange(struct thread *td, 199*bfac1583SKonstantin Belousov struct freebsd32_ioctl_args *uap, struct file *fp) 200*bfac1583SKonstantin Belousov { 201*bfac1583SKonstantin Belousov struct mem_range_op mro; 202*bfac1583SKonstantin Belousov struct mem_range_op32 mro32; 203*bfac1583SKonstantin Belousov int error; 204*bfac1583SKonstantin Belousov u_long com; 205*bfac1583SKonstantin Belousov 206*bfac1583SKonstantin Belousov if ((error = copyin(uap->data, &mro32, sizeof(mro32))) != 0) 207*bfac1583SKonstantin Belousov return (error); 208*bfac1583SKonstantin Belousov 209*bfac1583SKonstantin Belousov PTRIN_CP(mro32, mro, mo_desc); 210*bfac1583SKonstantin Belousov CP(mro32, mro, mo_arg[0]); 211*bfac1583SKonstantin Belousov CP(mro32, mro, mo_arg[1]); 212*bfac1583SKonstantin Belousov 213*bfac1583SKonstantin Belousov com = 0; 214*bfac1583SKonstantin Belousov switch (uap->com) { 215*bfac1583SKonstantin Belousov case MEMRANGE_GET32: 216*bfac1583SKonstantin Belousov com = MEMRANGE_GET; 217*bfac1583SKonstantin Belousov break; 218*bfac1583SKonstantin Belousov 219*bfac1583SKonstantin Belousov case MEMRANGE_SET32: 220*bfac1583SKonstantin Belousov com = MEMRANGE_SET; 221*bfac1583SKonstantin Belousov break; 222*bfac1583SKonstantin Belousov 223*bfac1583SKonstantin Belousov default: 224*bfac1583SKonstantin Belousov panic("%s: unknown MEMRANGE %#x", __func__, uap->com); 225*bfac1583SKonstantin Belousov } 226*bfac1583SKonstantin Belousov 227*bfac1583SKonstantin Belousov if ((error = fo_ioctl(fp, com, (caddr_t)&mro, td->td_ucred, td)) != 0) 228*bfac1583SKonstantin Belousov return (error); 229*bfac1583SKonstantin Belousov 230*bfac1583SKonstantin Belousov if ( (com & IOC_OUT) ) { 231*bfac1583SKonstantin Belousov CP(mro, mro32, mo_arg[0]); 232*bfac1583SKonstantin Belousov CP(mro, mro32, mo_arg[1]); 233*bfac1583SKonstantin Belousov 234*bfac1583SKonstantin Belousov error = copyout(&mro32, uap->data, sizeof(mro32)); 235*bfac1583SKonstantin Belousov } 236*bfac1583SKonstantin Belousov 237*bfac1583SKonstantin Belousov return (error); 238*bfac1583SKonstantin Belousov } 239*bfac1583SKonstantin Belousov 240ae528485SDavid E. O'Brien int 241ae528485SDavid E. O'Brien freebsd32_ioctl(struct thread *td, struct freebsd32_ioctl_args *uap) 242ae528485SDavid E. O'Brien { 243ae528485SDavid E. O'Brien struct ioctl_args ap /*{ 244ae528485SDavid E. O'Brien int fd; 245ae528485SDavid E. O'Brien u_long com; 246ae528485SDavid E. O'Brien caddr_t data; 247ae528485SDavid E. O'Brien }*/ ; 248ae528485SDavid E. O'Brien struct file *fp; 249ae528485SDavid E. O'Brien int error; 250ae528485SDavid E. O'Brien 251ae528485SDavid E. O'Brien if ((error = fget(td, uap->fd, &fp)) != 0) 252ae528485SDavid E. O'Brien return (error); 253ae528485SDavid E. O'Brien if ((fp->f_flag & (FREAD | FWRITE)) == 0) { 254ae528485SDavid E. O'Brien fdrop(fp, td); 255ae528485SDavid E. O'Brien return (EBADF); 256ae528485SDavid E. O'Brien } 257ae528485SDavid E. O'Brien 258ae528485SDavid E. O'Brien switch (uap->com) { 259ae528485SDavid E. O'Brien case MDIOCATTACH_32: /* FALLTHROUGH */ 260ae528485SDavid E. O'Brien case MDIOCDETACH_32: /* FALLTHROUGH */ 261ae528485SDavid E. O'Brien case MDIOCQUERY_32: /* FALLTHROUGH */ 262ae528485SDavid E. O'Brien case MDIOCLIST_32: 2631e67ebb1SKonstantin Belousov error = freebsd32_ioctl_md(td, uap, fp); 2641e67ebb1SKonstantin Belousov break; 265ae528485SDavid E. O'Brien 266c750e17cSDavid E. O'Brien case CDIOREADTOCENTRYS_32: 2671e67ebb1SKonstantin Belousov error = freebsd32_ioctl_ioc_read_toc(td, uap, fp); 2681e67ebb1SKonstantin Belousov break; 269c750e17cSDavid E. O'Brien 270c750e17cSDavid E. O'Brien case CDIOREADTOCHEADER_32: 2711e67ebb1SKonstantin Belousov error = freebsd32_ioctl_ioc_toc_header(td, uap, fp); 2721e67ebb1SKonstantin Belousov break; 273c750e17cSDavid E. O'Brien 2747eac36edSEd Schouten case FIODGNAME_32: 2751e67ebb1SKonstantin Belousov error = freebsd32_ioctl_fiodgname(td, uap, fp); 2761e67ebb1SKonstantin Belousov break; 2777eac36edSEd Schouten 278*bfac1583SKonstantin Belousov case MEMRANGE_GET32: /* FALLTHROUGH */ 279*bfac1583SKonstantin Belousov case MEMRANGE_SET32: 280*bfac1583SKonstantin Belousov error = freebsd32_ioctl_memrange(td, uap, fp); 281*bfac1583SKonstantin Belousov break; 282*bfac1583SKonstantin Belousov 283ae528485SDavid E. O'Brien default: 284ae528485SDavid E. O'Brien fdrop(fp, td); 285ae528485SDavid E. O'Brien ap.fd = uap->fd; 286ae528485SDavid E. O'Brien ap.com = uap->com; 287ae528485SDavid E. O'Brien PTRIN_CP(*uap, ap, data); 288ae528485SDavid E. O'Brien return ioctl(td, &ap); 289ae528485SDavid E. O'Brien } 2901e67ebb1SKonstantin Belousov 2911e67ebb1SKonstantin Belousov fdrop(fp, td); 2921e67ebb1SKonstantin Belousov return error; 293ae528485SDavid E. O'Brien } 294