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> 41bfac1583SKonstantin Belousov #include <sys/malloc.h> 42ae528485SDavid E. O'Brien #include <sys/mdioctl.h> 43bfac1583SKonstantin Belousov #include <sys/memrange.h> 444ee107ddSKonstantin Belousov #include <sys/pciio.h> 45ae528485SDavid E. O'Brien #include <sys/proc.h> 46ae528485SDavid E. O'Brien #include <sys/syscall.h> 47ae528485SDavid E. O'Brien #include <sys/syscallsubr.h> 48ae528485SDavid E. O'Brien #include <sys/sysctl.h> 49ae528485SDavid E. O'Brien #include <sys/sysent.h> 50ae528485SDavid E. O'Brien #include <sys/sysproto.h> 51ae528485SDavid E. O'Brien #include <sys/systm.h> 52ae528485SDavid E. O'Brien 53ae528485SDavid E. O'Brien #include <compat/freebsd32/freebsd32.h> 54ae528485SDavid E. O'Brien #include <compat/freebsd32/freebsd32_ioctl.h> 55ae528485SDavid E. O'Brien #include <compat/freebsd32/freebsd32_proto.h> 56ae528485SDavid E. O'Brien 57ae528485SDavid E. O'Brien /* Cannot get exact size in 64-bit due to alignment issue of entire struct. */ 58ae528485SDavid E. O'Brien CTASSERT((sizeof(struct md_ioctl32)+4) == 436); 59c750e17cSDavid E. O'Brien CTASSERT(sizeof(struct ioc_read_toc_entry32) == 8); 60c750e17cSDavid E. O'Brien CTASSERT(sizeof(struct ioc_toc_header32) == 4); 61bfac1583SKonstantin Belousov CTASSERT(sizeof(struct mem_range_op32) == 12); 624ee107ddSKonstantin Belousov CTASSERT(sizeof(struct pci_conf_io32) == 36); 634ee107ddSKonstantin Belousov CTASSERT(sizeof(struct pci_match_conf32) == 44); 644ee107ddSKonstantin Belousov CTASSERT(sizeof(struct pci_conf32) == 44); 65ae528485SDavid E. O'Brien 66ae528485SDavid E. O'Brien 67ae528485SDavid E. O'Brien static int 68ae528485SDavid E. O'Brien freebsd32_ioctl_md(struct thread *td, struct freebsd32_ioctl_args *uap, 69ae528485SDavid E. O'Brien struct file *fp) 70ae528485SDavid E. O'Brien { 71ae528485SDavid E. O'Brien struct md_ioctl mdv; 72ae528485SDavid E. O'Brien struct md_ioctl32 md32; 73ae528485SDavid E. O'Brien u_long com = 0; 74bc13c742SKonstantin Belousov int i, error; 75ae528485SDavid E. O'Brien 76ae528485SDavid E. O'Brien if (uap->com & IOC_IN) { 77ae528485SDavid E. O'Brien if ((error = copyin(uap->data, &md32, sizeof(md32)))) { 78ae528485SDavid E. O'Brien return (error); 79ae528485SDavid E. O'Brien } 80ae528485SDavid E. O'Brien CP(md32, mdv, md_version); 81ae528485SDavid E. O'Brien CP(md32, mdv, md_unit); 82ae528485SDavid E. O'Brien CP(md32, mdv, md_type); 83ae528485SDavid E. O'Brien PTRIN_CP(md32, mdv, md_file); 84ae528485SDavid E. O'Brien CP(md32, mdv, md_mediasize); 85ae528485SDavid E. O'Brien CP(md32, mdv, md_sectorsize); 86ae528485SDavid E. O'Brien CP(md32, mdv, md_options); 87ae528485SDavid E. O'Brien CP(md32, mdv, md_base); 88ae528485SDavid E. O'Brien CP(md32, mdv, md_fwheads); 89ae528485SDavid E. O'Brien CP(md32, mdv, md_fwsectors); 90ae528485SDavid E. O'Brien } else if (uap->com & IOC_OUT) { 91ae528485SDavid E. O'Brien /* 92ae528485SDavid E. O'Brien * Zero the buffer so the user always 93ae528485SDavid E. O'Brien * gets back something deterministic. 94ae528485SDavid E. O'Brien */ 95ae528485SDavid E. O'Brien bzero(&mdv, sizeof mdv); 96ae528485SDavid E. O'Brien } 97ae528485SDavid E. O'Brien 98ae528485SDavid E. O'Brien switch (uap->com) { 99ae528485SDavid E. O'Brien case MDIOCATTACH_32: 100ae528485SDavid E. O'Brien com = MDIOCATTACH; 101ae528485SDavid E. O'Brien break; 102ae528485SDavid E. O'Brien case MDIOCDETACH_32: 103ae528485SDavid E. O'Brien com = MDIOCDETACH; 104ae528485SDavid E. O'Brien break; 105ae528485SDavid E. O'Brien case MDIOCQUERY_32: 106ae528485SDavid E. O'Brien com = MDIOCQUERY; 107ae528485SDavid E. O'Brien break; 108ae528485SDavid E. O'Brien case MDIOCLIST_32: 109ae528485SDavid E. O'Brien com = MDIOCLIST; 110ae528485SDavid E. O'Brien break; 111ae528485SDavid E. O'Brien default: 112ae528485SDavid E. O'Brien panic("%s: unknown MDIOC %#x", __func__, uap->com); 113ae528485SDavid E. O'Brien } 114ae528485SDavid E. O'Brien error = fo_ioctl(fp, com, (caddr_t)&mdv, td->td_ucred, td); 115ae528485SDavid E. O'Brien if (error == 0 && (com & IOC_OUT)) { 116ae528485SDavid E. O'Brien CP(mdv, md32, md_version); 117ae528485SDavid E. O'Brien CP(mdv, md32, md_unit); 118ae528485SDavid E. O'Brien CP(mdv, md32, md_type); 119ae528485SDavid E. O'Brien PTROUT_CP(mdv, md32, md_file); 120ae528485SDavid E. O'Brien CP(mdv, md32, md_mediasize); 121ae528485SDavid E. O'Brien CP(mdv, md32, md_sectorsize); 122ae528485SDavid E. O'Brien CP(mdv, md32, md_options); 123ae528485SDavid E. O'Brien CP(mdv, md32, md_base); 124ae528485SDavid E. O'Brien CP(mdv, md32, md_fwheads); 125ae528485SDavid E. O'Brien CP(mdv, md32, md_fwsectors); 126bc13c742SKonstantin Belousov if (com == MDIOCLIST) { 127bc13c742SKonstantin Belousov /* 128bc13c742SKonstantin Belousov * Use MDNPAD, and not MDNPAD32. Padding is 129bc13c742SKonstantin Belousov * allocated and used by compat32 ABI. 130bc13c742SKonstantin Belousov */ 131bc13c742SKonstantin Belousov for (i = 0; i < MDNPAD; i++) 132bc13c742SKonstantin Belousov CP(mdv, md32, md_pad[i]); 133bc13c742SKonstantin Belousov } 134ae528485SDavid E. O'Brien error = copyout(&md32, uap->data, sizeof(md32)); 135ae528485SDavid E. O'Brien } 136ae528485SDavid E. O'Brien return error; 137ae528485SDavid E. O'Brien } 138ae528485SDavid E. O'Brien 139ae528485SDavid E. O'Brien 140c750e17cSDavid E. O'Brien static int 141c750e17cSDavid E. O'Brien freebsd32_ioctl_ioc_toc_header(struct thread *td, 142c750e17cSDavid E. O'Brien struct freebsd32_ioctl_args *uap, struct file *fp) 143c750e17cSDavid E. O'Brien { 144c750e17cSDavid E. O'Brien struct ioc_toc_header toch; 145c750e17cSDavid E. O'Brien struct ioc_toc_header32 toch32; 146c750e17cSDavid E. O'Brien int error; 147c750e17cSDavid E. O'Brien 148c750e17cSDavid E. O'Brien if ((error = copyin(uap->data, &toch32, sizeof(toch32)))) 149c750e17cSDavid E. O'Brien return (error); 150c750e17cSDavid E. O'Brien CP(toch32, toch, len); 151c750e17cSDavid E. O'Brien CP(toch32, toch, starting_track); 152c750e17cSDavid E. O'Brien CP(toch32, toch, ending_track); 153c750e17cSDavid E. O'Brien error = fo_ioctl(fp, CDIOREADTOCHEADER, (caddr_t)&toch, 154c750e17cSDavid E. O'Brien td->td_ucred, td); 155c750e17cSDavid E. O'Brien return (error); 156c750e17cSDavid E. O'Brien } 157c750e17cSDavid E. O'Brien 158c750e17cSDavid E. O'Brien 159c750e17cSDavid E. O'Brien static int 160c750e17cSDavid E. O'Brien freebsd32_ioctl_ioc_read_toc(struct thread *td, 161c750e17cSDavid E. O'Brien struct freebsd32_ioctl_args *uap, struct file *fp) 162c750e17cSDavid E. O'Brien { 163c750e17cSDavid E. O'Brien struct ioc_read_toc_entry toce; 164c750e17cSDavid E. O'Brien struct ioc_read_toc_entry32 toce32; 165c750e17cSDavid E. O'Brien int error; 166c750e17cSDavid E. O'Brien 167c750e17cSDavid E. O'Brien if ((error = copyin(uap->data, &toce32, sizeof(toce32)))) 168c750e17cSDavid E. O'Brien return (error); 169c750e17cSDavid E. O'Brien CP(toce32, toce, address_format); 170c750e17cSDavid E. O'Brien CP(toce32, toce, starting_track); 171c750e17cSDavid E. O'Brien CP(toce32, toce, data_len); 172c750e17cSDavid E. O'Brien PTRIN_CP(toce32, toce, data); 173c750e17cSDavid E. O'Brien 174c750e17cSDavid E. O'Brien if ((error = fo_ioctl(fp, CDIOREADTOCENTRYS, (caddr_t)&toce, 175c750e17cSDavid E. O'Brien td->td_ucred, td))) { 176c750e17cSDavid E. O'Brien CP(toce, toce32, address_format); 177c750e17cSDavid E. O'Brien CP(toce, toce32, starting_track); 178c750e17cSDavid E. O'Brien CP(toce, toce32, data_len); 179c750e17cSDavid E. O'Brien PTROUT_CP(toce, toce32, data); 180c750e17cSDavid E. O'Brien error = copyout(&toce32, uap->data, sizeof(toce32)); 181c750e17cSDavid E. O'Brien } 182c750e17cSDavid E. O'Brien return error; 183c750e17cSDavid E. O'Brien } 184c750e17cSDavid E. O'Brien 1857eac36edSEd Schouten static int 1867eac36edSEd Schouten freebsd32_ioctl_fiodgname(struct thread *td, 1877eac36edSEd Schouten struct freebsd32_ioctl_args *uap, struct file *fp) 1887eac36edSEd Schouten { 1897eac36edSEd Schouten struct fiodgname_arg fgn; 1907eac36edSEd Schouten struct fiodgname_arg32 fgn32; 1917eac36edSEd Schouten int error; 1927eac36edSEd Schouten 1937eac36edSEd Schouten if ((error = copyin(uap->data, &fgn32, sizeof fgn32)) != 0) 1947eac36edSEd Schouten return (error); 1957eac36edSEd Schouten CP(fgn32, fgn, len); 1967eac36edSEd Schouten PTRIN_CP(fgn32, fgn, buf); 1977eac36edSEd Schouten error = fo_ioctl(fp, FIODGNAME, (caddr_t)&fgn, td->td_ucred, td); 1987eac36edSEd Schouten return (error); 1997eac36edSEd Schouten } 200c750e17cSDavid E. O'Brien 201bfac1583SKonstantin Belousov static int 202bfac1583SKonstantin Belousov freebsd32_ioctl_memrange(struct thread *td, 203bfac1583SKonstantin Belousov struct freebsd32_ioctl_args *uap, struct file *fp) 204bfac1583SKonstantin Belousov { 205bfac1583SKonstantin Belousov struct mem_range_op mro; 206bfac1583SKonstantin Belousov struct mem_range_op32 mro32; 207bfac1583SKonstantin Belousov int error; 208bfac1583SKonstantin Belousov u_long com; 209bfac1583SKonstantin Belousov 210bfac1583SKonstantin Belousov if ((error = copyin(uap->data, &mro32, sizeof(mro32))) != 0) 211bfac1583SKonstantin Belousov return (error); 212bfac1583SKonstantin Belousov 213bfac1583SKonstantin Belousov PTRIN_CP(mro32, mro, mo_desc); 214bfac1583SKonstantin Belousov CP(mro32, mro, mo_arg[0]); 215bfac1583SKonstantin Belousov CP(mro32, mro, mo_arg[1]); 216bfac1583SKonstantin Belousov 217bfac1583SKonstantin Belousov com = 0; 218bfac1583SKonstantin Belousov switch (uap->com) { 219bfac1583SKonstantin Belousov case MEMRANGE_GET32: 220bfac1583SKonstantin Belousov com = MEMRANGE_GET; 221bfac1583SKonstantin Belousov break; 222bfac1583SKonstantin Belousov 223bfac1583SKonstantin Belousov case MEMRANGE_SET32: 224bfac1583SKonstantin Belousov com = MEMRANGE_SET; 225bfac1583SKonstantin Belousov break; 226bfac1583SKonstantin Belousov 227bfac1583SKonstantin Belousov default: 228bfac1583SKonstantin Belousov panic("%s: unknown MEMRANGE %#x", __func__, uap->com); 229bfac1583SKonstantin Belousov } 230bfac1583SKonstantin Belousov 231bfac1583SKonstantin Belousov if ((error = fo_ioctl(fp, com, (caddr_t)&mro, td->td_ucred, td)) != 0) 232bfac1583SKonstantin Belousov return (error); 233bfac1583SKonstantin Belousov 234bfac1583SKonstantin Belousov if ( (com & IOC_OUT) ) { 235bfac1583SKonstantin Belousov CP(mro, mro32, mo_arg[0]); 236bfac1583SKonstantin Belousov CP(mro, mro32, mo_arg[1]); 237bfac1583SKonstantin Belousov 238bfac1583SKonstantin Belousov error = copyout(&mro32, uap->data, sizeof(mro32)); 239bfac1583SKonstantin Belousov } 240bfac1583SKonstantin Belousov 241bfac1583SKonstantin Belousov return (error); 242bfac1583SKonstantin Belousov } 243bfac1583SKonstantin Belousov 244*78272eedSKonstantin Belousov static int 245*78272eedSKonstantin Belousov freebsd32_ioctl_pciocgetconf(struct thread *td, 246*78272eedSKonstantin Belousov struct freebsd32_ioctl_args *uap, struct file *fp) 247*78272eedSKonstantin Belousov { 248*78272eedSKonstantin Belousov struct pci_conf_io pci; 249*78272eedSKonstantin Belousov struct pci_conf_io32 pci32; 250*78272eedSKonstantin Belousov struct pci_match_conf32 pmc32; 251*78272eedSKonstantin Belousov struct pci_match_conf32 *pmc32p; 252*78272eedSKonstantin Belousov struct pci_match_conf pmc; 253*78272eedSKonstantin Belousov struct pci_match_conf *pmcp; 254*78272eedSKonstantin Belousov struct pci_conf32 pc32; 255*78272eedSKonstantin Belousov struct pci_conf32 *pc32p; 256*78272eedSKonstantin Belousov struct pci_conf pc; 257*78272eedSKonstantin Belousov struct pci_conf *pcp; 258*78272eedSKonstantin Belousov u_int32_t i; 259*78272eedSKonstantin Belousov u_int32_t npat_to_convert; 260*78272eedSKonstantin Belousov u_int32_t nmatch_to_convert; 261*78272eedSKonstantin Belousov vm_offset_t addr; 262*78272eedSKonstantin Belousov int error; 263*78272eedSKonstantin Belousov 264*78272eedSKonstantin Belousov if ((error = copyin(uap->data, &pci32, sizeof(pci32))) != 0) 265*78272eedSKonstantin Belousov return (error); 266*78272eedSKonstantin Belousov 267*78272eedSKonstantin Belousov CP(pci32, pci, num_patterns); 268*78272eedSKonstantin Belousov CP(pci32, pci, offset); 269*78272eedSKonstantin Belousov CP(pci32, pci, generation); 270*78272eedSKonstantin Belousov 271*78272eedSKonstantin Belousov npat_to_convert = pci32.pat_buf_len / sizeof(struct pci_match_conf32); 272*78272eedSKonstantin Belousov pci.pat_buf_len = npat_to_convert * sizeof(struct pci_match_conf); 273*78272eedSKonstantin Belousov pci.patterns = NULL; 274*78272eedSKonstantin Belousov nmatch_to_convert = pci32.match_buf_len / sizeof(struct pci_conf32); 275*78272eedSKonstantin Belousov pci.match_buf_len = nmatch_to_convert * sizeof(struct pci_conf); 276*78272eedSKonstantin Belousov pci.matches = NULL; 277*78272eedSKonstantin Belousov 278*78272eedSKonstantin Belousov if ((error = copyout_map(td, &addr, pci.pat_buf_len)) != 0) 279*78272eedSKonstantin Belousov goto cleanup; 280*78272eedSKonstantin Belousov pci.patterns = (struct pci_match_conf *)addr; 281*78272eedSKonstantin Belousov if ((error = copyout_map(td, &addr, pci.match_buf_len)) != 0) 282*78272eedSKonstantin Belousov goto cleanup; 283*78272eedSKonstantin Belousov pci.matches = (struct pci_conf *)addr; 284*78272eedSKonstantin Belousov 285*78272eedSKonstantin Belousov npat_to_convert = min(npat_to_convert, pci.num_patterns); 286*78272eedSKonstantin Belousov 287*78272eedSKonstantin Belousov for (i = 0, pmc32p = (struct pci_match_conf32 *)PTRIN(pci32.patterns), 288*78272eedSKonstantin Belousov pmcp = pci.patterns; 289*78272eedSKonstantin Belousov i < npat_to_convert; i++, pmc32p++, pmcp++) { 290*78272eedSKonstantin Belousov if ((error = copyin(pmc32p, &pmc32, sizeof(pmc32))) != 0) 291*78272eedSKonstantin Belousov goto cleanup; 292*78272eedSKonstantin Belousov CP(pmc32,pmc,pc_sel); 293*78272eedSKonstantin Belousov strlcpy(pmc.pd_name, pmc32.pd_name, sizeof(pmc.pd_name)); 294*78272eedSKonstantin Belousov CP(pmc32,pmc,pd_unit); 295*78272eedSKonstantin Belousov CP(pmc32,pmc,pc_vendor); 296*78272eedSKonstantin Belousov CP(pmc32,pmc,pc_device); 297*78272eedSKonstantin Belousov CP(pmc32,pmc,pc_class); 298*78272eedSKonstantin Belousov CP(pmc32,pmc,flags); 299*78272eedSKonstantin Belousov if ((error = copyout(&pmc, pmcp, sizeof(pmc))) != 0) 300*78272eedSKonstantin Belousov goto cleanup; 301*78272eedSKonstantin Belousov } 302*78272eedSKonstantin Belousov 303*78272eedSKonstantin Belousov if ((error = fo_ioctl(fp, PCIOCGETCONF, (caddr_t)&pci, 304*78272eedSKonstantin Belousov td->td_ucred, td)) != 0) 305*78272eedSKonstantin Belousov goto cleanup; 306*78272eedSKonstantin Belousov 307*78272eedSKonstantin Belousov nmatch_to_convert = min(nmatch_to_convert, pci.num_matches); 308*78272eedSKonstantin Belousov 309*78272eedSKonstantin Belousov for (i = 0, pcp = pci.matches, 310*78272eedSKonstantin Belousov pc32p = (struct pci_conf32 *)PTRIN(pci32.matches); 311*78272eedSKonstantin Belousov i < nmatch_to_convert; i++, pcp++, pc32p++) { 312*78272eedSKonstantin Belousov if ((error = copyin(pcp, &pc, sizeof(pc))) != 0) 313*78272eedSKonstantin Belousov goto cleanup; 314*78272eedSKonstantin Belousov CP(pc,pc32,pc_sel); 315*78272eedSKonstantin Belousov CP(pc,pc32,pc_hdr); 316*78272eedSKonstantin Belousov CP(pc,pc32,pc_subvendor); 317*78272eedSKonstantin Belousov CP(pc,pc32,pc_subdevice); 318*78272eedSKonstantin Belousov CP(pc,pc32,pc_vendor); 319*78272eedSKonstantin Belousov CP(pc,pc32,pc_device); 320*78272eedSKonstantin Belousov CP(pc,pc32,pc_class); 321*78272eedSKonstantin Belousov CP(pc,pc32,pc_subclass); 322*78272eedSKonstantin Belousov CP(pc,pc32,pc_progif); 323*78272eedSKonstantin Belousov CP(pc,pc32,pc_revid); 324*78272eedSKonstantin Belousov strlcpy(pc32.pd_name, pc.pd_name, sizeof(pc32.pd_name)); 325*78272eedSKonstantin Belousov CP(pc,pc32,pd_unit); 326*78272eedSKonstantin Belousov if ((error = copyout(&pc32, pc32p, sizeof(pc32))) != 0) 327*78272eedSKonstantin Belousov goto cleanup; 328*78272eedSKonstantin Belousov } 329*78272eedSKonstantin Belousov 330*78272eedSKonstantin Belousov CP(pci, pci32, num_matches); 331*78272eedSKonstantin Belousov CP(pci, pci32, offset); 332*78272eedSKonstantin Belousov CP(pci, pci32, generation); 333*78272eedSKonstantin Belousov CP(pci, pci32, status); 334*78272eedSKonstantin Belousov 335*78272eedSKonstantin Belousov error = copyout(&pci32, uap->data, sizeof(pci32)); 336*78272eedSKonstantin Belousov 337*78272eedSKonstantin Belousov cleanup: 338*78272eedSKonstantin Belousov if (pci.patterns) 339*78272eedSKonstantin Belousov copyout_unmap(td, (vm_offset_t)pci.patterns, pci.pat_buf_len); 340*78272eedSKonstantin Belousov if (pci.matches) 341*78272eedSKonstantin Belousov copyout_unmap(td, (vm_offset_t)pci.matches, pci.match_buf_len); 342*78272eedSKonstantin Belousov 343*78272eedSKonstantin Belousov return (error); 344*78272eedSKonstantin Belousov } 345*78272eedSKonstantin Belousov 346ae528485SDavid E. O'Brien int 347ae528485SDavid E. O'Brien freebsd32_ioctl(struct thread *td, struct freebsd32_ioctl_args *uap) 348ae528485SDavid E. O'Brien { 349ae528485SDavid E. O'Brien struct ioctl_args ap /*{ 350ae528485SDavid E. O'Brien int fd; 351ae528485SDavid E. O'Brien u_long com; 352ae528485SDavid E. O'Brien caddr_t data; 353ae528485SDavid E. O'Brien }*/ ; 354ae528485SDavid E. O'Brien struct file *fp; 355ae528485SDavid E. O'Brien int error; 356ae528485SDavid E. O'Brien 357ae528485SDavid E. O'Brien if ((error = fget(td, uap->fd, &fp)) != 0) 358ae528485SDavid E. O'Brien return (error); 359ae528485SDavid E. O'Brien if ((fp->f_flag & (FREAD | FWRITE)) == 0) { 360ae528485SDavid E. O'Brien fdrop(fp, td); 361ae528485SDavid E. O'Brien return (EBADF); 362ae528485SDavid E. O'Brien } 363ae528485SDavid E. O'Brien 364ae528485SDavid E. O'Brien switch (uap->com) { 365ae528485SDavid E. O'Brien case MDIOCATTACH_32: /* FALLTHROUGH */ 366ae528485SDavid E. O'Brien case MDIOCDETACH_32: /* FALLTHROUGH */ 367ae528485SDavid E. O'Brien case MDIOCQUERY_32: /* FALLTHROUGH */ 368ae528485SDavid E. O'Brien case MDIOCLIST_32: 3691e67ebb1SKonstantin Belousov error = freebsd32_ioctl_md(td, uap, fp); 3701e67ebb1SKonstantin Belousov break; 371ae528485SDavid E. O'Brien 372c750e17cSDavid E. O'Brien case CDIOREADTOCENTRYS_32: 3731e67ebb1SKonstantin Belousov error = freebsd32_ioctl_ioc_read_toc(td, uap, fp); 3741e67ebb1SKonstantin Belousov break; 375c750e17cSDavid E. O'Brien 376c750e17cSDavid E. O'Brien case CDIOREADTOCHEADER_32: 3771e67ebb1SKonstantin Belousov error = freebsd32_ioctl_ioc_toc_header(td, uap, fp); 3781e67ebb1SKonstantin Belousov break; 379c750e17cSDavid E. O'Brien 3807eac36edSEd Schouten case FIODGNAME_32: 3811e67ebb1SKonstantin Belousov error = freebsd32_ioctl_fiodgname(td, uap, fp); 3821e67ebb1SKonstantin Belousov break; 3837eac36edSEd Schouten 384bfac1583SKonstantin Belousov case MEMRANGE_GET32: /* FALLTHROUGH */ 385bfac1583SKonstantin Belousov case MEMRANGE_SET32: 386bfac1583SKonstantin Belousov error = freebsd32_ioctl_memrange(td, uap, fp); 387bfac1583SKonstantin Belousov break; 388bfac1583SKonstantin Belousov 389*78272eedSKonstantin Belousov case PCIOCGETCONF_32: 390*78272eedSKonstantin Belousov error = freebsd32_ioctl_pciocgetconf(td, uap, fp); 391*78272eedSKonstantin Belousov break; 392*78272eedSKonstantin Belousov 393ae528485SDavid E. O'Brien default: 394ae528485SDavid E. O'Brien fdrop(fp, td); 395ae528485SDavid E. O'Brien ap.fd = uap->fd; 396ae528485SDavid E. O'Brien ap.com = uap->com; 397ae528485SDavid E. O'Brien PTRIN_CP(*uap, ap, data); 398ae528485SDavid E. O'Brien return ioctl(td, &ap); 399ae528485SDavid E. O'Brien } 4001e67ebb1SKonstantin Belousov 4011e67ebb1SKonstantin Belousov fdrop(fp, td); 4021e67ebb1SKonstantin Belousov return error; 403ae528485SDavid E. O'Brien } 404