1ae528485SDavid E. O'Brien /*- 2*51369649SPedro F. Giffuni * SPDX-License-Identifier: BSD-3-Clause 3*51369649SPedro F. Giffuni * 4ae528485SDavid E. O'Brien * Copyright (c) 2008 David E. O'Brien 5ae528485SDavid E. O'Brien * All rights reserved. 6ae528485SDavid E. O'Brien * 7ae528485SDavid E. O'Brien * Redistribution and use in source and binary forms, with or without 8ae528485SDavid E. O'Brien * modification, are permitted provided that the following conditions 9ae528485SDavid E. O'Brien * are met: 10ae528485SDavid E. O'Brien * 1. Redistributions of source code must retain the above copyright 11ae528485SDavid E. O'Brien * notice, this list of conditions and the following disclaimer. 12ae528485SDavid E. O'Brien * 2. Redistributions in binary form must reproduce the above copyright 13ae528485SDavid E. O'Brien * notice, this list of conditions and the following disclaimer in the 14ae528485SDavid E. O'Brien * documentation and/or other materials provided with the distribution. 15ae528485SDavid E. O'Brien * 3. Neither the name of the author nor the names of its contributors 16ae528485SDavid E. O'Brien * may be used to endorse or promote products derived from this software 17ae528485SDavid E. O'Brien * without specific prior written permission. 18ae528485SDavid E. O'Brien * 19ae528485SDavid E. O'Brien * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 20ae528485SDavid E. O'Brien * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21ae528485SDavid E. O'Brien * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22ae528485SDavid E. O'Brien * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 23ae528485SDavid E. O'Brien * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24ae528485SDavid E. O'Brien * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25ae528485SDavid E. O'Brien * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26ae528485SDavid E. O'Brien * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27ae528485SDavid E. O'Brien * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28ae528485SDavid E. O'Brien * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29ae528485SDavid E. O'Brien * SUCH DAMAGE. 30ae528485SDavid E. O'Brien */ 31ae528485SDavid E. O'Brien 32ae528485SDavid E. O'Brien #include <sys/cdefs.h> 33ae528485SDavid E. O'Brien __FBSDID("$FreeBSD$"); 34ae528485SDavid E. O'Brien 35ae528485SDavid E. O'Brien #include "opt_compat.h" 36ae528485SDavid E. O'Brien 37ae528485SDavid E. O'Brien #include <sys/param.h> 384a144410SRobert Watson #include <sys/capsicum.h> 39ae528485SDavid E. O'Brien #include <sys/cdio.h> 40ae528485SDavid E. O'Brien #include <sys/fcntl.h> 417eac36edSEd Schouten #include <sys/filio.h> 42ae528485SDavid E. O'Brien #include <sys/file.h> 43ae528485SDavid E. O'Brien #include <sys/ioccom.h> 44bfac1583SKonstantin Belousov #include <sys/malloc.h> 45ae528485SDavid E. O'Brien #include <sys/mdioctl.h> 46bfac1583SKonstantin Belousov #include <sys/memrange.h> 474ee107ddSKonstantin Belousov #include <sys/pciio.h> 48ae528485SDavid E. O'Brien #include <sys/proc.h> 49ae528485SDavid E. O'Brien #include <sys/syscall.h> 50ae528485SDavid E. O'Brien #include <sys/syscallsubr.h> 51ae528485SDavid E. O'Brien #include <sys/sysctl.h> 52ae528485SDavid E. O'Brien #include <sys/sysent.h> 53ae528485SDavid E. O'Brien #include <sys/sysproto.h> 54ae528485SDavid E. O'Brien #include <sys/systm.h> 55ae528485SDavid E. O'Brien 56ae528485SDavid E. O'Brien #include <compat/freebsd32/freebsd32.h> 57ae528485SDavid E. O'Brien #include <compat/freebsd32/freebsd32_ioctl.h> 58ae528485SDavid E. O'Brien #include <compat/freebsd32/freebsd32_proto.h> 59ae528485SDavid E. O'Brien 60f76de5ddSMaxim Sobolev CTASSERT((sizeof(struct md_ioctl32)) == 436); 61c750e17cSDavid E. O'Brien CTASSERT(sizeof(struct ioc_read_toc_entry32) == 8); 62bfac1583SKonstantin Belousov CTASSERT(sizeof(struct mem_range_op32) == 12); 634ee107ddSKonstantin Belousov CTASSERT(sizeof(struct pci_conf_io32) == 36); 644ee107ddSKonstantin Belousov CTASSERT(sizeof(struct pci_match_conf32) == 44); 654ee107ddSKonstantin Belousov CTASSERT(sizeof(struct pci_conf32) == 44); 66ae528485SDavid E. O'Brien 67ae528485SDavid E. O'Brien 68ae528485SDavid E. O'Brien static int 69ae528485SDavid E. O'Brien freebsd32_ioctl_md(struct thread *td, struct freebsd32_ioctl_args *uap, 70ae528485SDavid E. O'Brien struct file *fp) 71ae528485SDavid E. O'Brien { 72ae528485SDavid E. O'Brien struct md_ioctl mdv; 73ae528485SDavid E. O'Brien struct md_ioctl32 md32; 74ae528485SDavid E. O'Brien u_long com = 0; 75bc13c742SKonstantin Belousov int i, error; 76ae528485SDavid E. O'Brien 77ae528485SDavid E. O'Brien if (uap->com & IOC_IN) { 78ae528485SDavid E. O'Brien if ((error = copyin(uap->data, &md32, sizeof(md32)))) { 79ae528485SDavid E. O'Brien return (error); 80ae528485SDavid E. O'Brien } 81ae528485SDavid E. O'Brien CP(md32, mdv, md_version); 82ae528485SDavid E. O'Brien CP(md32, mdv, md_unit); 83ae528485SDavid E. O'Brien CP(md32, mdv, md_type); 84ae528485SDavid E. O'Brien PTRIN_CP(md32, mdv, md_file); 85ae528485SDavid E. O'Brien CP(md32, mdv, md_mediasize); 86ae528485SDavid E. O'Brien CP(md32, mdv, md_sectorsize); 87ae528485SDavid E. O'Brien CP(md32, mdv, md_options); 88ae528485SDavid E. O'Brien CP(md32, mdv, md_base); 89ae528485SDavid E. O'Brien CP(md32, mdv, md_fwheads); 90ae528485SDavid E. O'Brien CP(md32, mdv, md_fwsectors); 91f76de5ddSMaxim Sobolev PTRIN_CP(md32, mdv, md_label); 92ae528485SDavid E. O'Brien } else if (uap->com & IOC_OUT) { 93ae528485SDavid E. O'Brien /* 94ae528485SDavid E. O'Brien * Zero the buffer so the user always 95ae528485SDavid E. O'Brien * gets back something deterministic. 96ae528485SDavid E. O'Brien */ 97ae528485SDavid E. O'Brien bzero(&mdv, sizeof mdv); 98ae528485SDavid E. O'Brien } 99ae528485SDavid E. O'Brien 100ae528485SDavid E. O'Brien switch (uap->com) { 101ae528485SDavid E. O'Brien case MDIOCATTACH_32: 102ae528485SDavid E. O'Brien com = MDIOCATTACH; 103ae528485SDavid E. O'Brien break; 104ae528485SDavid E. O'Brien case MDIOCDETACH_32: 105ae528485SDavid E. O'Brien com = MDIOCDETACH; 106ae528485SDavid E. O'Brien break; 107ae528485SDavid E. O'Brien case MDIOCQUERY_32: 108ae528485SDavid E. O'Brien com = MDIOCQUERY; 109ae528485SDavid E. O'Brien break; 110ae528485SDavid E. O'Brien case MDIOCLIST_32: 111ae528485SDavid E. O'Brien com = MDIOCLIST; 112ae528485SDavid E. O'Brien break; 113ae528485SDavid E. O'Brien default: 114ae528485SDavid E. O'Brien panic("%s: unknown MDIOC %#x", __func__, uap->com); 115ae528485SDavid E. O'Brien } 116ae528485SDavid E. O'Brien error = fo_ioctl(fp, com, (caddr_t)&mdv, td->td_ucred, td); 117ae528485SDavid E. O'Brien if (error == 0 && (com & IOC_OUT)) { 118ae528485SDavid E. O'Brien CP(mdv, md32, md_version); 119ae528485SDavid E. O'Brien CP(mdv, md32, md_unit); 120ae528485SDavid E. O'Brien CP(mdv, md32, md_type); 121ae528485SDavid E. O'Brien PTROUT_CP(mdv, md32, md_file); 122ae528485SDavid E. O'Brien CP(mdv, md32, md_mediasize); 123ae528485SDavid E. O'Brien CP(mdv, md32, md_sectorsize); 124ae528485SDavid E. O'Brien CP(mdv, md32, md_options); 125ae528485SDavid E. O'Brien CP(mdv, md32, md_base); 126ae528485SDavid E. O'Brien CP(mdv, md32, md_fwheads); 127ae528485SDavid E. O'Brien CP(mdv, md32, md_fwsectors); 128f76de5ddSMaxim Sobolev PTROUT_CP(mdv, md32, md_label); 129bc13c742SKonstantin Belousov if (com == MDIOCLIST) { 130bc13c742SKonstantin Belousov /* 131bc13c742SKonstantin Belousov * Use MDNPAD, and not MDNPAD32. Padding is 132bc13c742SKonstantin Belousov * allocated and used by compat32 ABI. 133bc13c742SKonstantin Belousov */ 134bc13c742SKonstantin Belousov for (i = 0; i < MDNPAD; i++) 135bc13c742SKonstantin Belousov CP(mdv, md32, md_pad[i]); 136bc13c742SKonstantin Belousov } 137ae528485SDavid E. O'Brien error = copyout(&md32, uap->data, sizeof(md32)); 138ae528485SDavid E. O'Brien } 139ae528485SDavid E. O'Brien return error; 140ae528485SDavid E. O'Brien } 141ae528485SDavid E. O'Brien 142ae528485SDavid E. O'Brien 143c750e17cSDavid E. O'Brien static int 144c750e17cSDavid E. O'Brien freebsd32_ioctl_ioc_read_toc(struct thread *td, 145c750e17cSDavid E. O'Brien struct freebsd32_ioctl_args *uap, struct file *fp) 146c750e17cSDavid E. O'Brien { 147c750e17cSDavid E. O'Brien struct ioc_read_toc_entry toce; 148c750e17cSDavid E. O'Brien struct ioc_read_toc_entry32 toce32; 149c750e17cSDavid E. O'Brien int error; 150c750e17cSDavid E. O'Brien 151c750e17cSDavid E. O'Brien if ((error = copyin(uap->data, &toce32, sizeof(toce32)))) 152c750e17cSDavid E. O'Brien return (error); 153c750e17cSDavid E. O'Brien CP(toce32, toce, address_format); 154c750e17cSDavid E. O'Brien CP(toce32, toce, starting_track); 155c750e17cSDavid E. O'Brien CP(toce32, toce, data_len); 156c750e17cSDavid E. O'Brien PTRIN_CP(toce32, toce, data); 157c750e17cSDavid E. O'Brien 158c750e17cSDavid E. O'Brien if ((error = fo_ioctl(fp, CDIOREADTOCENTRYS, (caddr_t)&toce, 159c750e17cSDavid E. O'Brien td->td_ucred, td))) { 160c750e17cSDavid E. O'Brien CP(toce, toce32, address_format); 161c750e17cSDavid E. O'Brien CP(toce, toce32, starting_track); 162c750e17cSDavid E. O'Brien CP(toce, toce32, data_len); 163c750e17cSDavid E. O'Brien PTROUT_CP(toce, toce32, data); 164c750e17cSDavid E. O'Brien error = copyout(&toce32, uap->data, sizeof(toce32)); 165c750e17cSDavid E. O'Brien } 166c750e17cSDavid E. O'Brien return error; 167c750e17cSDavid E. O'Brien } 168c750e17cSDavid E. O'Brien 1697eac36edSEd Schouten static int 1707eac36edSEd Schouten freebsd32_ioctl_fiodgname(struct thread *td, 1717eac36edSEd Schouten struct freebsd32_ioctl_args *uap, struct file *fp) 1727eac36edSEd Schouten { 1737eac36edSEd Schouten struct fiodgname_arg fgn; 1747eac36edSEd Schouten struct fiodgname_arg32 fgn32; 1757eac36edSEd Schouten int error; 1767eac36edSEd Schouten 1777eac36edSEd Schouten if ((error = copyin(uap->data, &fgn32, sizeof fgn32)) != 0) 1787eac36edSEd Schouten return (error); 1797eac36edSEd Schouten CP(fgn32, fgn, len); 1807eac36edSEd Schouten PTRIN_CP(fgn32, fgn, buf); 1817eac36edSEd Schouten error = fo_ioctl(fp, FIODGNAME, (caddr_t)&fgn, td->td_ucred, td); 1827eac36edSEd Schouten return (error); 1837eac36edSEd Schouten } 184c750e17cSDavid E. O'Brien 185bfac1583SKonstantin Belousov static int 186bfac1583SKonstantin Belousov freebsd32_ioctl_memrange(struct thread *td, 187bfac1583SKonstantin Belousov struct freebsd32_ioctl_args *uap, struct file *fp) 188bfac1583SKonstantin Belousov { 189bfac1583SKonstantin Belousov struct mem_range_op mro; 190bfac1583SKonstantin Belousov struct mem_range_op32 mro32; 191bfac1583SKonstantin Belousov int error; 192bfac1583SKonstantin Belousov u_long com; 193bfac1583SKonstantin Belousov 194bfac1583SKonstantin Belousov if ((error = copyin(uap->data, &mro32, sizeof(mro32))) != 0) 195bfac1583SKonstantin Belousov return (error); 196bfac1583SKonstantin Belousov 197bfac1583SKonstantin Belousov PTRIN_CP(mro32, mro, mo_desc); 198bfac1583SKonstantin Belousov CP(mro32, mro, mo_arg[0]); 199bfac1583SKonstantin Belousov CP(mro32, mro, mo_arg[1]); 200bfac1583SKonstantin Belousov 201bfac1583SKonstantin Belousov com = 0; 202bfac1583SKonstantin Belousov switch (uap->com) { 203bfac1583SKonstantin Belousov case MEMRANGE_GET32: 204bfac1583SKonstantin Belousov com = MEMRANGE_GET; 205bfac1583SKonstantin Belousov break; 206bfac1583SKonstantin Belousov 207bfac1583SKonstantin Belousov case MEMRANGE_SET32: 208bfac1583SKonstantin Belousov com = MEMRANGE_SET; 209bfac1583SKonstantin Belousov break; 210bfac1583SKonstantin Belousov 211bfac1583SKonstantin Belousov default: 212bfac1583SKonstantin Belousov panic("%s: unknown MEMRANGE %#x", __func__, uap->com); 213bfac1583SKonstantin Belousov } 214bfac1583SKonstantin Belousov 215bfac1583SKonstantin Belousov if ((error = fo_ioctl(fp, com, (caddr_t)&mro, td->td_ucred, td)) != 0) 216bfac1583SKonstantin Belousov return (error); 217bfac1583SKonstantin Belousov 218bfac1583SKonstantin Belousov if ( (com & IOC_OUT) ) { 219bfac1583SKonstantin Belousov CP(mro, mro32, mo_arg[0]); 220bfac1583SKonstantin Belousov CP(mro, mro32, mo_arg[1]); 221bfac1583SKonstantin Belousov 222bfac1583SKonstantin Belousov error = copyout(&mro32, uap->data, sizeof(mro32)); 223bfac1583SKonstantin Belousov } 224bfac1583SKonstantin Belousov 225bfac1583SKonstantin Belousov return (error); 226bfac1583SKonstantin Belousov } 227bfac1583SKonstantin Belousov 22878272eedSKonstantin Belousov static int 22978272eedSKonstantin Belousov freebsd32_ioctl_pciocgetconf(struct thread *td, 23078272eedSKonstantin Belousov struct freebsd32_ioctl_args *uap, struct file *fp) 23178272eedSKonstantin Belousov { 23278272eedSKonstantin Belousov struct pci_conf_io pci; 23378272eedSKonstantin Belousov struct pci_conf_io32 pci32; 23478272eedSKonstantin Belousov struct pci_match_conf32 pmc32; 23578272eedSKonstantin Belousov struct pci_match_conf32 *pmc32p; 23678272eedSKonstantin Belousov struct pci_match_conf pmc; 23778272eedSKonstantin Belousov struct pci_match_conf *pmcp; 23878272eedSKonstantin Belousov struct pci_conf32 pc32; 23978272eedSKonstantin Belousov struct pci_conf32 *pc32p; 24078272eedSKonstantin Belousov struct pci_conf pc; 24178272eedSKonstantin Belousov struct pci_conf *pcp; 24278272eedSKonstantin Belousov u_int32_t i; 24378272eedSKonstantin Belousov u_int32_t npat_to_convert; 24478272eedSKonstantin Belousov u_int32_t nmatch_to_convert; 24578272eedSKonstantin Belousov vm_offset_t addr; 24678272eedSKonstantin Belousov int error; 24778272eedSKonstantin Belousov 24878272eedSKonstantin Belousov if ((error = copyin(uap->data, &pci32, sizeof(pci32))) != 0) 24978272eedSKonstantin Belousov return (error); 25078272eedSKonstantin Belousov 25178272eedSKonstantin Belousov CP(pci32, pci, num_patterns); 25278272eedSKonstantin Belousov CP(pci32, pci, offset); 25378272eedSKonstantin Belousov CP(pci32, pci, generation); 25478272eedSKonstantin Belousov 25578272eedSKonstantin Belousov npat_to_convert = pci32.pat_buf_len / sizeof(struct pci_match_conf32); 25678272eedSKonstantin Belousov pci.pat_buf_len = npat_to_convert * sizeof(struct pci_match_conf); 25778272eedSKonstantin Belousov pci.patterns = NULL; 25878272eedSKonstantin Belousov nmatch_to_convert = pci32.match_buf_len / sizeof(struct pci_conf32); 25978272eedSKonstantin Belousov pci.match_buf_len = nmatch_to_convert * sizeof(struct pci_conf); 26078272eedSKonstantin Belousov pci.matches = NULL; 26178272eedSKonstantin Belousov 26278272eedSKonstantin Belousov if ((error = copyout_map(td, &addr, pci.pat_buf_len)) != 0) 26378272eedSKonstantin Belousov goto cleanup; 26478272eedSKonstantin Belousov pci.patterns = (struct pci_match_conf *)addr; 26578272eedSKonstantin Belousov if ((error = copyout_map(td, &addr, pci.match_buf_len)) != 0) 26678272eedSKonstantin Belousov goto cleanup; 26778272eedSKonstantin Belousov pci.matches = (struct pci_conf *)addr; 26878272eedSKonstantin Belousov 26978272eedSKonstantin Belousov npat_to_convert = min(npat_to_convert, pci.num_patterns); 27078272eedSKonstantin Belousov 27178272eedSKonstantin Belousov for (i = 0, pmc32p = (struct pci_match_conf32 *)PTRIN(pci32.patterns), 27278272eedSKonstantin Belousov pmcp = pci.patterns; 27378272eedSKonstantin Belousov i < npat_to_convert; i++, pmc32p++, pmcp++) { 27478272eedSKonstantin Belousov if ((error = copyin(pmc32p, &pmc32, sizeof(pmc32))) != 0) 27578272eedSKonstantin Belousov goto cleanup; 27678272eedSKonstantin Belousov CP(pmc32,pmc,pc_sel); 27778272eedSKonstantin Belousov strlcpy(pmc.pd_name, pmc32.pd_name, sizeof(pmc.pd_name)); 27878272eedSKonstantin Belousov CP(pmc32,pmc,pd_unit); 27978272eedSKonstantin Belousov CP(pmc32,pmc,pc_vendor); 28078272eedSKonstantin Belousov CP(pmc32,pmc,pc_device); 28178272eedSKonstantin Belousov CP(pmc32,pmc,pc_class); 28278272eedSKonstantin Belousov CP(pmc32,pmc,flags); 28378272eedSKonstantin Belousov if ((error = copyout(&pmc, pmcp, sizeof(pmc))) != 0) 28478272eedSKonstantin Belousov goto cleanup; 28578272eedSKonstantin Belousov } 28678272eedSKonstantin Belousov 28778272eedSKonstantin Belousov if ((error = fo_ioctl(fp, PCIOCGETCONF, (caddr_t)&pci, 28878272eedSKonstantin Belousov td->td_ucred, td)) != 0) 28978272eedSKonstantin Belousov goto cleanup; 29078272eedSKonstantin Belousov 29178272eedSKonstantin Belousov nmatch_to_convert = min(nmatch_to_convert, pci.num_matches); 29278272eedSKonstantin Belousov 29378272eedSKonstantin Belousov for (i = 0, pcp = pci.matches, 29478272eedSKonstantin Belousov pc32p = (struct pci_conf32 *)PTRIN(pci32.matches); 29578272eedSKonstantin Belousov i < nmatch_to_convert; i++, pcp++, pc32p++) { 29678272eedSKonstantin Belousov if ((error = copyin(pcp, &pc, sizeof(pc))) != 0) 29778272eedSKonstantin Belousov goto cleanup; 29878272eedSKonstantin Belousov CP(pc,pc32,pc_sel); 29978272eedSKonstantin Belousov CP(pc,pc32,pc_hdr); 30078272eedSKonstantin Belousov CP(pc,pc32,pc_subvendor); 30178272eedSKonstantin Belousov CP(pc,pc32,pc_subdevice); 30278272eedSKonstantin Belousov CP(pc,pc32,pc_vendor); 30378272eedSKonstantin Belousov CP(pc,pc32,pc_device); 30478272eedSKonstantin Belousov CP(pc,pc32,pc_class); 30578272eedSKonstantin Belousov CP(pc,pc32,pc_subclass); 30678272eedSKonstantin Belousov CP(pc,pc32,pc_progif); 30778272eedSKonstantin Belousov CP(pc,pc32,pc_revid); 30878272eedSKonstantin Belousov strlcpy(pc32.pd_name, pc.pd_name, sizeof(pc32.pd_name)); 30978272eedSKonstantin Belousov CP(pc,pc32,pd_unit); 31078272eedSKonstantin Belousov if ((error = copyout(&pc32, pc32p, sizeof(pc32))) != 0) 31178272eedSKonstantin Belousov goto cleanup; 31278272eedSKonstantin Belousov } 31378272eedSKonstantin Belousov 31478272eedSKonstantin Belousov CP(pci, pci32, num_matches); 31578272eedSKonstantin Belousov CP(pci, pci32, offset); 31678272eedSKonstantin Belousov CP(pci, pci32, generation); 31778272eedSKonstantin Belousov CP(pci, pci32, status); 31878272eedSKonstantin Belousov 31978272eedSKonstantin Belousov error = copyout(&pci32, uap->data, sizeof(pci32)); 32078272eedSKonstantin Belousov 32178272eedSKonstantin Belousov cleanup: 32278272eedSKonstantin Belousov if (pci.patterns) 32378272eedSKonstantin Belousov copyout_unmap(td, (vm_offset_t)pci.patterns, pci.pat_buf_len); 32478272eedSKonstantin Belousov if (pci.matches) 32578272eedSKonstantin Belousov copyout_unmap(td, (vm_offset_t)pci.matches, pci.match_buf_len); 32678272eedSKonstantin Belousov 32778272eedSKonstantin Belousov return (error); 32878272eedSKonstantin Belousov } 32978272eedSKonstantin Belousov 330fcaf473cSAlexander Motin static int 331fcaf473cSAlexander Motin freebsd32_ioctl_sg(struct thread *td, 332fcaf473cSAlexander Motin struct freebsd32_ioctl_args *uap, struct file *fp) 333fcaf473cSAlexander Motin { 334fcaf473cSAlexander Motin struct sg_io_hdr io; 335fcaf473cSAlexander Motin struct sg_io_hdr32 io32; 336fcaf473cSAlexander Motin int error; 337fcaf473cSAlexander Motin 338fcaf473cSAlexander Motin if ((error = copyin(uap->data, &io32, sizeof(io32))) != 0) 339fcaf473cSAlexander Motin return (error); 340fcaf473cSAlexander Motin 341fcaf473cSAlexander Motin CP(io32, io, interface_id); 342fcaf473cSAlexander Motin CP(io32, io, dxfer_direction); 343fcaf473cSAlexander Motin CP(io32, io, cmd_len); 344fcaf473cSAlexander Motin CP(io32, io, mx_sb_len); 345fcaf473cSAlexander Motin CP(io32, io, iovec_count); 346fcaf473cSAlexander Motin CP(io32, io, dxfer_len); 347fcaf473cSAlexander Motin PTRIN_CP(io32, io, dxferp); 348fcaf473cSAlexander Motin PTRIN_CP(io32, io, cmdp); 349fcaf473cSAlexander Motin PTRIN_CP(io32, io, sbp); 350fcaf473cSAlexander Motin CP(io32, io, timeout); 351fcaf473cSAlexander Motin CP(io32, io, flags); 352fcaf473cSAlexander Motin CP(io32, io, pack_id); 353fcaf473cSAlexander Motin PTRIN_CP(io32, io, usr_ptr); 354fcaf473cSAlexander Motin CP(io32, io, status); 355fcaf473cSAlexander Motin CP(io32, io, masked_status); 356fcaf473cSAlexander Motin CP(io32, io, msg_status); 357fcaf473cSAlexander Motin CP(io32, io, sb_len_wr); 358fcaf473cSAlexander Motin CP(io32, io, host_status); 359fcaf473cSAlexander Motin CP(io32, io, driver_status); 360fcaf473cSAlexander Motin CP(io32, io, resid); 361fcaf473cSAlexander Motin CP(io32, io, duration); 362fcaf473cSAlexander Motin CP(io32, io, info); 363fcaf473cSAlexander Motin 364fcaf473cSAlexander Motin if ((error = fo_ioctl(fp, SG_IO, (caddr_t)&io, td->td_ucred, td)) != 0) 365fcaf473cSAlexander Motin return (error); 366fcaf473cSAlexander Motin 367fcaf473cSAlexander Motin CP(io, io32, interface_id); 368fcaf473cSAlexander Motin CP(io, io32, dxfer_direction); 369fcaf473cSAlexander Motin CP(io, io32, cmd_len); 370fcaf473cSAlexander Motin CP(io, io32, mx_sb_len); 371fcaf473cSAlexander Motin CP(io, io32, iovec_count); 372fcaf473cSAlexander Motin CP(io, io32, dxfer_len); 373fcaf473cSAlexander Motin PTROUT_CP(io, io32, dxferp); 374fcaf473cSAlexander Motin PTROUT_CP(io, io32, cmdp); 375fcaf473cSAlexander Motin PTROUT_CP(io, io32, sbp); 376fcaf473cSAlexander Motin CP(io, io32, timeout); 377fcaf473cSAlexander Motin CP(io, io32, flags); 378fcaf473cSAlexander Motin CP(io, io32, pack_id); 379fcaf473cSAlexander Motin PTROUT_CP(io, io32, usr_ptr); 380fcaf473cSAlexander Motin CP(io, io32, status); 381fcaf473cSAlexander Motin CP(io, io32, masked_status); 382fcaf473cSAlexander Motin CP(io, io32, msg_status); 383fcaf473cSAlexander Motin CP(io, io32, sb_len_wr); 384fcaf473cSAlexander Motin CP(io, io32, host_status); 385fcaf473cSAlexander Motin CP(io, io32, driver_status); 386fcaf473cSAlexander Motin CP(io, io32, resid); 387fcaf473cSAlexander Motin CP(io, io32, duration); 388fcaf473cSAlexander Motin CP(io, io32, info); 389fcaf473cSAlexander Motin 390fcaf473cSAlexander Motin error = copyout(&io32, uap->data, sizeof(io32)); 391fcaf473cSAlexander Motin 392fcaf473cSAlexander Motin return (error); 393fcaf473cSAlexander Motin } 394fcaf473cSAlexander Motin 395ae528485SDavid E. O'Brien int 396ae528485SDavid E. O'Brien freebsd32_ioctl(struct thread *td, struct freebsd32_ioctl_args *uap) 397ae528485SDavid E. O'Brien { 398ae528485SDavid E. O'Brien struct ioctl_args ap /*{ 399ae528485SDavid E. O'Brien int fd; 400ae528485SDavid E. O'Brien u_long com; 401ae528485SDavid E. O'Brien caddr_t data; 402ae528485SDavid E. O'Brien }*/ ; 403ae528485SDavid E. O'Brien struct file *fp; 4047008be5bSPawel Jakub Dawidek cap_rights_t rights; 405ae528485SDavid E. O'Brien int error; 406ae528485SDavid E. O'Brien 4077008be5bSPawel Jakub Dawidek error = fget(td, uap->fd, cap_rights_init(&rights, CAP_IOCTL), &fp); 4087008be5bSPawel Jakub Dawidek if (error != 0) 409ae528485SDavid E. O'Brien return (error); 410ae528485SDavid E. O'Brien if ((fp->f_flag & (FREAD | FWRITE)) == 0) { 411ae528485SDavid E. O'Brien fdrop(fp, td); 412ae528485SDavid E. O'Brien return (EBADF); 413ae528485SDavid E. O'Brien } 414ae528485SDavid E. O'Brien 415ae528485SDavid E. O'Brien switch (uap->com) { 416ae528485SDavid E. O'Brien case MDIOCATTACH_32: /* FALLTHROUGH */ 417ae528485SDavid E. O'Brien case MDIOCDETACH_32: /* FALLTHROUGH */ 418ae528485SDavid E. O'Brien case MDIOCQUERY_32: /* FALLTHROUGH */ 419ae528485SDavid E. O'Brien case MDIOCLIST_32: 4201e67ebb1SKonstantin Belousov error = freebsd32_ioctl_md(td, uap, fp); 4211e67ebb1SKonstantin Belousov break; 422ae528485SDavid E. O'Brien 423c750e17cSDavid E. O'Brien case CDIOREADTOCENTRYS_32: 4241e67ebb1SKonstantin Belousov error = freebsd32_ioctl_ioc_read_toc(td, uap, fp); 4251e67ebb1SKonstantin Belousov break; 426c750e17cSDavid E. O'Brien 4277eac36edSEd Schouten case FIODGNAME_32: 4281e67ebb1SKonstantin Belousov error = freebsd32_ioctl_fiodgname(td, uap, fp); 4291e67ebb1SKonstantin Belousov break; 4307eac36edSEd Schouten 431bfac1583SKonstantin Belousov case MEMRANGE_GET32: /* FALLTHROUGH */ 432bfac1583SKonstantin Belousov case MEMRANGE_SET32: 433bfac1583SKonstantin Belousov error = freebsd32_ioctl_memrange(td, uap, fp); 434bfac1583SKonstantin Belousov break; 435bfac1583SKonstantin Belousov 43678272eedSKonstantin Belousov case PCIOCGETCONF_32: 43778272eedSKonstantin Belousov error = freebsd32_ioctl_pciocgetconf(td, uap, fp); 43878272eedSKonstantin Belousov break; 43978272eedSKonstantin Belousov 440fcaf473cSAlexander Motin case SG_IO_32: 441fcaf473cSAlexander Motin error = freebsd32_ioctl_sg(td, uap, fp); 442fcaf473cSAlexander Motin break; 443fcaf473cSAlexander Motin 444ae528485SDavid E. O'Brien default: 445ae528485SDavid E. O'Brien fdrop(fp, td); 446ae528485SDavid E. O'Brien ap.fd = uap->fd; 447ae528485SDavid E. O'Brien ap.com = uap->com; 448ae528485SDavid E. O'Brien PTRIN_CP(*uap, ap, data); 4498451d0ddSKip Macy return sys_ioctl(td, &ap); 450ae528485SDavid E. O'Brien } 4511e67ebb1SKonstantin Belousov 4521e67ebb1SKonstantin Belousov fdrop(fp, td); 4531e67ebb1SKonstantin Belousov return error; 454ae528485SDavid E. O'Brien } 455