| File: | compat/freebsd32/freebsd32_ioctl.c |
| Warning: | line 135, column 11 Copies out a struct with untouched element(s): md_pad |
| 1 | /*- | |||
| 2 | * Copyright (c) 2008 David E. O'Brien | |||
| 3 | * All rights reserved. | |||
| 4 | * | |||
| 5 | * Redistribution and use in source and binary forms, with or without | |||
| 6 | * modification, are permitted provided that the following conditions | |||
| 7 | * are met: | |||
| 8 | * 1. Redistributions of source code must retain the above copyright | |||
| 9 | * notice, this list of conditions and the following disclaimer. | |||
| 10 | * 2. Redistributions in binary form must reproduce the above copyright | |||
| 11 | * notice, this list of conditions and the following disclaimer in the | |||
| 12 | * documentation and/or other materials provided with the distribution. | |||
| 13 | * 3. Neither the name of the author nor the names of its contributors | |||
| 14 | * may be used to endorse or promote products derived from this software | |||
| 15 | * without specific prior written permission. | |||
| 16 | * | |||
| 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | |||
| 18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |||
| 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||
| 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | |||
| 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |||
| 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |||
| 23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |||
| 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |||
| 25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |||
| 26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||
| 27 | * SUCH DAMAGE. | |||
| 28 | */ | |||
| 29 | ||||
| 30 | #include <sys/cdefs.h> | |||
| 31 | __FBSDID("$FreeBSD: releng/11.0/sys/compat/freebsd32/freebsd32_ioctl.c 266981 2014-06-02 19:53:53Z mav $")__asm__(".ident\t\"" "$FreeBSD: releng/11.0/sys/compat/freebsd32/freebsd32_ioctl.c 266981 2014-06-02 19:53:53Z mav $" "\""); | |||
| 32 | ||||
| 33 | #include "opt_compat.h" | |||
| 34 | ||||
| 35 | #include <sys/param.h> | |||
| 36 | #include <sys/capsicum.h> | |||
| 37 | #include <sys/cdio.h> | |||
| 38 | #include <sys/fcntl.h> | |||
| 39 | #include <sys/filio.h> | |||
| 40 | #include <sys/file.h> | |||
| 41 | #include <sys/ioccom.h> | |||
| 42 | #include <sys/malloc.h> | |||
| 43 | #include <sys/mdioctl.h> | |||
| 44 | #include <sys/memrange.h> | |||
| 45 | #include <sys/pciio.h> | |||
| 46 | #include <sys/proc.h> | |||
| 47 | #include <sys/syscall.h> | |||
| 48 | #include <sys/syscallsubr.h> | |||
| 49 | #include <sys/sysctl.h> | |||
| 50 | #include <sys/sysent.h> | |||
| 51 | #include <sys/sysproto.h> | |||
| 52 | #include <sys/systm.h> | |||
| 53 | ||||
| 54 | #include <compat/freebsd32/freebsd32.h> | |||
| 55 | #include <compat/freebsd32/freebsd32_ioctl.h> | |||
| 56 | #include <compat/freebsd32/freebsd32_proto.h> | |||
| 57 | ||||
| 58 | /* Cannot get exact size in 64-bit due to alignment issue of entire struct. */ | |||
| 59 | CTASSERT((sizeof(struct md_ioctl32)+4) == 436)_Static_assert((sizeof(struct md_ioctl32)+4) == 436, "compile-time assertion failed" ); | |||
| 60 | CTASSERT(sizeof(struct ioc_read_toc_entry32) == 8)_Static_assert(sizeof(struct ioc_read_toc_entry32) == 8, "compile-time assertion failed" ); | |||
| 61 | CTASSERT(sizeof(struct ioc_toc_header32) == 4)_Static_assert(sizeof(struct ioc_toc_header32) == 4, "compile-time assertion failed" ); | |||
| 62 | CTASSERT(sizeof(struct mem_range_op32) == 12)_Static_assert(sizeof(struct mem_range_op32) == 12, "compile-time assertion failed" ); | |||
| 63 | CTASSERT(sizeof(struct pci_conf_io32) == 36)_Static_assert(sizeof(struct pci_conf_io32) == 36, "compile-time assertion failed" ); | |||
| 64 | CTASSERT(sizeof(struct pci_match_conf32) == 44)_Static_assert(sizeof(struct pci_match_conf32) == 44, "compile-time assertion failed" ); | |||
| 65 | CTASSERT(sizeof(struct pci_conf32) == 44)_Static_assert(sizeof(struct pci_conf32) == 44, "compile-time assertion failed" ); | |||
| 66 | ||||
| 67 | ||||
| 68 | static int | |||
| 69 | freebsd32_ioctl_md(struct thread *td, struct freebsd32_ioctl_args *uap, | |||
| 70 | struct file *fp) | |||
| 71 | { | |||
| 72 | struct md_ioctl mdv; | |||
| 73 | struct md_ioctl32 md32; | |||
| 74 | u_long com = 0; | |||
| 75 | int i, error; | |||
| 76 | ||||
| 77 | if (uap->com & IOC_IN0x80000000) { | |||
| ||||
| 78 | if ((error = copyin(uap->data, &md32, sizeof(md32)))) { | |||
| 79 | return (error); | |||
| 80 | } | |||
| 81 | CP(md32, mdv, md_version)do { (mdv).md_version = (md32).md_version; } while (0); | |||
| 82 | CP(md32, mdv, md_unit)do { (mdv).md_unit = (md32).md_unit; } while (0); | |||
| 83 | CP(md32, mdv, md_type)do { (mdv).md_type = (md32).md_type; } while (0); | |||
| 84 | PTRIN_CP(md32, mdv, md_file)do { (mdv).md_file = (void *)(uintptr_t) ((md32).md_file); } while (0); | |||
| 85 | CP(md32, mdv, md_mediasize)do { (mdv).md_mediasize = (md32).md_mediasize; } while (0); | |||
| 86 | CP(md32, mdv, md_sectorsize)do { (mdv).md_sectorsize = (md32).md_sectorsize; } while (0); | |||
| 87 | CP(md32, mdv, md_options)do { (mdv).md_options = (md32).md_options; } while (0); | |||
| 88 | CP(md32, mdv, md_base)do { (mdv).md_base = (md32).md_base; } while (0); | |||
| 89 | CP(md32, mdv, md_fwheads)do { (mdv).md_fwheads = (md32).md_fwheads; } while (0); | |||
| 90 | CP(md32, mdv, md_fwsectors)do { (mdv).md_fwsectors = (md32).md_fwsectors; } while (0); | |||
| 91 | } else if (uap->com & IOC_OUT0x40000000) { | |||
| 92 | /* | |||
| 93 | * Zero the buffer so the user always | |||
| 94 | * gets back something deterministic. | |||
| 95 | */ | |||
| 96 | bzero(&mdv, sizeof mdv); | |||
| 97 | } | |||
| 98 | ||||
| 99 | switch (uap->com) { | |||
| 100 | case MDIOCATTACH_32((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct md_ioctl32) + 4) & ((1 << 13) - 1)) << 16) | (('m') << 8) | (0))): | |||
| 101 | com = MDIOCATTACH((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct md_ioctl)) & ((1 << 13) - 1)) << 16) | ((('m' )) << 8) | ((0)))); | |||
| 102 | break; | |||
| 103 | case MDIOCDETACH_32((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct md_ioctl32) + 4) & ((1 << 13) - 1)) << 16) | (('m') << 8) | (1))): | |||
| 104 | com = MDIOCDETACH((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct md_ioctl)) & ((1 << 13) - 1)) << 16) | ((('m' )) << 8) | ((1)))); | |||
| 105 | break; | |||
| 106 | case MDIOCQUERY_32((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct md_ioctl32) + 4) & ((1 << 13) - 1)) << 16) | (('m') << 8) | (2))): | |||
| 107 | com = MDIOCQUERY((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct md_ioctl)) & ((1 << 13) - 1)) << 16) | ((('m' )) << 8) | ((2)))); | |||
| 108 | break; | |||
| 109 | case MDIOCLIST_32((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct md_ioctl32) + 4) & ((1 << 13) - 1)) << 16) | (('m') << 8) | (3))): | |||
| 110 | com = MDIOCLIST((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct md_ioctl)) & ((1 << 13) - 1)) << 16) | ((('m' )) << 8) | ((3)))); | |||
| 111 | break; | |||
| 112 | default: | |||
| 113 | panic("%s: unknown MDIOC %#x", __func__, uap->com); | |||
| 114 | } | |||
| 115 | error = fo_ioctl(fp, com, (caddr_t)&mdv, td->td_ucred, td); | |||
| 116 | if (error == 0 && (com & IOC_OUT0x40000000)) { | |||
| 117 | CP(mdv, md32, md_version)do { (md32).md_version = (mdv).md_version; } while (0); | |||
| 118 | CP(mdv, md32, md_unit)do { (md32).md_unit = (mdv).md_unit; } while (0); | |||
| 119 | CP(mdv, md32, md_type)do { (md32).md_type = (mdv).md_type; } while (0); | |||
| 120 | PTROUT_CP(mdv, md32, md_file)do { (md32).md_file = (u_int32_t)(uintptr_t) ((mdv).md_file); } while (0); | |||
| 121 | CP(mdv, md32, md_mediasize)do { (md32).md_mediasize = (mdv).md_mediasize; } while (0); | |||
| 122 | CP(mdv, md32, md_sectorsize)do { (md32).md_sectorsize = (mdv).md_sectorsize; } while (0); | |||
| 123 | CP(mdv, md32, md_options)do { (md32).md_options = (mdv).md_options; } while (0); | |||
| 124 | CP(mdv, md32, md_base)do { (md32).md_base = (mdv).md_base; } while (0); | |||
| 125 | CP(mdv, md32, md_fwheads)do { (md32).md_fwheads = (mdv).md_fwheads; } while (0); | |||
| 126 | CP(mdv, md32, md_fwsectors)do { (md32).md_fwsectors = (mdv).md_fwsectors; } while (0); | |||
| 127 | if (com == MDIOCLIST((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct md_ioctl)) & ((1 << 13) - 1)) << 16) | ((('m' )) << 8) | ((3))))) { | |||
| 128 | /* | |||
| 129 | * Use MDNPAD, and not MDNPAD32. Padding is | |||
| 130 | * allocated and used by compat32 ABI. | |||
| 131 | */ | |||
| 132 | for (i = 0; i < MDNPAD97; i++) | |||
| 133 | CP(mdv, md32, md_pad[i])do { (md32).md_pad[i] = (mdv).md_pad[i]; } while (0); | |||
| 134 | } | |||
| 135 | error = copyout(&md32, uap->data, sizeof(md32)); | |||
| ||||
| 136 | } | |||
| 137 | return error; | |||
| 138 | } | |||
| 139 | ||||
| 140 | ||||
| 141 | static int | |||
| 142 | freebsd32_ioctl_ioc_toc_header(struct thread *td, | |||
| 143 | struct freebsd32_ioctl_args *uap, struct file *fp) | |||
| 144 | { | |||
| 145 | struct ioc_toc_header toch; | |||
| 146 | struct ioc_toc_header32 toch32; | |||
| 147 | int error; | |||
| 148 | ||||
| 149 | if ((error = copyin(uap->data, &toch32, sizeof(toch32)))) | |||
| 150 | return (error); | |||
| 151 | CP(toch32, toch, len)do { (toch).len = (toch32).len; } while (0); | |||
| 152 | CP(toch32, toch, starting_track)do { (toch).starting_track = (toch32).starting_track; } while (0); | |||
| 153 | CP(toch32, toch, ending_track)do { (toch).ending_track = (toch32).ending_track; } while (0); | |||
| 154 | error = fo_ioctl(fp, CDIOREADTOCHEADER((unsigned long) ((0x40000000) | (((sizeof(struct ioc_toc_header )) & ((1 << 13) - 1)) << 16) | ((('c')) << 8) | ((4)))), (caddr_t)&toch, | |||
| 155 | td->td_ucred, td); | |||
| 156 | return (error); | |||
| 157 | } | |||
| 158 | ||||
| 159 | ||||
| 160 | static int | |||
| 161 | freebsd32_ioctl_ioc_read_toc(struct thread *td, | |||
| 162 | struct freebsd32_ioctl_args *uap, struct file *fp) | |||
| 163 | { | |||
| 164 | struct ioc_read_toc_entry toce; | |||
| 165 | struct ioc_read_toc_entry32 toce32; | |||
| 166 | int error; | |||
| 167 | ||||
| 168 | if ((error = copyin(uap->data, &toce32, sizeof(toce32)))) | |||
| 169 | return (error); | |||
| 170 | CP(toce32, toce, address_format)do { (toce).address_format = (toce32).address_format; } while (0); | |||
| 171 | CP(toce32, toce, starting_track)do { (toce).starting_track = (toce32).starting_track; } while (0); | |||
| 172 | CP(toce32, toce, data_len)do { (toce).data_len = (toce32).data_len; } while (0); | |||
| 173 | PTRIN_CP(toce32, toce, data)do { (toce).data = (void *)(uintptr_t) ((toce32).data); } while (0); | |||
| 174 | ||||
| 175 | if ((error = fo_ioctl(fp, CDIOREADTOCENTRYS((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct ioc_read_toc_entry)) & ((1 << 13) - 1)) << 16 ) | ((('c')) << 8) | ((5)))), (caddr_t)&toce, | |||
| 176 | td->td_ucred, td))) { | |||
| 177 | CP(toce, toce32, address_format)do { (toce32).address_format = (toce).address_format; } while (0); | |||
| 178 | CP(toce, toce32, starting_track)do { (toce32).starting_track = (toce).starting_track; } while (0); | |||
| 179 | CP(toce, toce32, data_len)do { (toce32).data_len = (toce).data_len; } while (0); | |||
| 180 | PTROUT_CP(toce, toce32, data)do { (toce32).data = (u_int32_t)(uintptr_t) ((toce).data); } while (0); | |||
| 181 | error = copyout(&toce32, uap->data, sizeof(toce32)); | |||
| 182 | } | |||
| 183 | return error; | |||
| 184 | } | |||
| 185 | ||||
| 186 | static int | |||
| 187 | freebsd32_ioctl_fiodgname(struct thread *td, | |||
| 188 | struct freebsd32_ioctl_args *uap, struct file *fp) | |||
| 189 | { | |||
| 190 | struct fiodgname_arg fgn; | |||
| 191 | struct fiodgname_arg32 fgn32; | |||
| 192 | int error; | |||
| 193 | ||||
| 194 | if ((error = copyin(uap->data, &fgn32, sizeof fgn32)) != 0) | |||
| 195 | return (error); | |||
| 196 | CP(fgn32, fgn, len)do { (fgn).len = (fgn32).len; } while (0); | |||
| 197 | PTRIN_CP(fgn32, fgn, buf)do { (fgn).buf = (void *)(uintptr_t) ((fgn32).buf); } while ( 0); | |||
| 198 | error = fo_ioctl(fp, FIODGNAME((unsigned long) ((0x80000000) | (((sizeof(struct fiodgname_arg )) & ((1 << 13) - 1)) << 16) | ((('f')) << 8) | ((120)))), (caddr_t)&fgn, td->td_ucred, td); | |||
| 199 | return (error); | |||
| 200 | } | |||
| 201 | ||||
| 202 | static int | |||
| 203 | freebsd32_ioctl_memrange(struct thread *td, | |||
| 204 | struct freebsd32_ioctl_args *uap, struct file *fp) | |||
| 205 | { | |||
| 206 | struct mem_range_op mro; | |||
| 207 | struct mem_range_op32 mro32; | |||
| 208 | int error; | |||
| 209 | u_long com; | |||
| 210 | ||||
| 211 | if ((error = copyin(uap->data, &mro32, sizeof(mro32))) != 0) | |||
| 212 | return (error); | |||
| 213 | ||||
| 214 | PTRIN_CP(mro32, mro, mo_desc)do { (mro).mo_desc = (void *)(uintptr_t) ((mro32).mo_desc); } while (0); | |||
| 215 | CP(mro32, mro, mo_arg[0])do { (mro).mo_arg[0] = (mro32).mo_arg[0]; } while (0); | |||
| 216 | CP(mro32, mro, mo_arg[1])do { (mro).mo_arg[1] = (mro32).mo_arg[1]; } while (0); | |||
| 217 | ||||
| 218 | com = 0; | |||
| 219 | switch (uap->com) { | |||
| 220 | case MEMRANGE_GET32((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct mem_range_op32)) & ((1 << 13) - 1)) << 16) | ((('m')) << 8) | ((50)))): | |||
| 221 | com = MEMRANGE_GET((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct mem_range_op)) & ((1 << 13) - 1)) << 16) | ( (('m')) << 8) | ((50)))); | |||
| 222 | break; | |||
| 223 | ||||
| 224 | case MEMRANGE_SET32((unsigned long) ((0x80000000) | (((sizeof(struct mem_range_op32 )) & ((1 << 13) - 1)) << 16) | ((('m')) << 8) | ((51)))): | |||
| 225 | com = MEMRANGE_SET((unsigned long) ((0x80000000) | (((sizeof(struct mem_range_op )) & ((1 << 13) - 1)) << 16) | ((('m')) << 8) | ((51)))); | |||
| 226 | break; | |||
| 227 | ||||
| 228 | default: | |||
| 229 | panic("%s: unknown MEMRANGE %#x", __func__, uap->com); | |||
| 230 | } | |||
| 231 | ||||
| 232 | if ((error = fo_ioctl(fp, com, (caddr_t)&mro, td->td_ucred, td)) != 0) | |||
| 233 | return (error); | |||
| 234 | ||||
| 235 | if ( (com & IOC_OUT0x40000000) ) { | |||
| 236 | CP(mro, mro32, mo_arg[0])do { (mro32).mo_arg[0] = (mro).mo_arg[0]; } while (0); | |||
| 237 | CP(mro, mro32, mo_arg[1])do { (mro32).mo_arg[1] = (mro).mo_arg[1]; } while (0); | |||
| 238 | ||||
| 239 | error = copyout(&mro32, uap->data, sizeof(mro32)); | |||
| 240 | } | |||
| 241 | ||||
| 242 | return (error); | |||
| 243 | } | |||
| 244 | ||||
| 245 | static int | |||
| 246 | freebsd32_ioctl_pciocgetconf(struct thread *td, | |||
| 247 | struct freebsd32_ioctl_args *uap, struct file *fp) | |||
| 248 | { | |||
| 249 | struct pci_conf_io pci; | |||
| 250 | struct pci_conf_io32 pci32; | |||
| 251 | struct pci_match_conf32 pmc32; | |||
| 252 | struct pci_match_conf32 *pmc32p; | |||
| 253 | struct pci_match_conf pmc; | |||
| 254 | struct pci_match_conf *pmcp; | |||
| 255 | struct pci_conf32 pc32; | |||
| 256 | struct pci_conf32 *pc32p; | |||
| 257 | struct pci_conf pc; | |||
| 258 | struct pci_conf *pcp; | |||
| 259 | u_int32_t i; | |||
| 260 | u_int32_t npat_to_convert; | |||
| 261 | u_int32_t nmatch_to_convert; | |||
| 262 | vm_offset_t addr; | |||
| 263 | int error; | |||
| 264 | ||||
| 265 | if ((error = copyin(uap->data, &pci32, sizeof(pci32))) != 0) | |||
| 266 | return (error); | |||
| 267 | ||||
| 268 | CP(pci32, pci, num_patterns)do { (pci).num_patterns = (pci32).num_patterns; } while (0); | |||
| 269 | CP(pci32, pci, offset)do { (pci).offset = (pci32).offset; } while (0); | |||
| 270 | CP(pci32, pci, generation)do { (pci).generation = (pci32).generation; } while (0); | |||
| 271 | ||||
| 272 | npat_to_convert = pci32.pat_buf_len / sizeof(struct pci_match_conf32); | |||
| 273 | pci.pat_buf_len = npat_to_convert * sizeof(struct pci_match_conf); | |||
| 274 | pci.patterns = NULL((void *)0); | |||
| 275 | nmatch_to_convert = pci32.match_buf_len / sizeof(struct pci_conf32); | |||
| 276 | pci.match_buf_len = nmatch_to_convert * sizeof(struct pci_conf); | |||
| 277 | pci.matches = NULL((void *)0); | |||
| 278 | ||||
| 279 | if ((error = copyout_map(td, &addr, pci.pat_buf_len)) != 0) | |||
| 280 | goto cleanup; | |||
| 281 | pci.patterns = (struct pci_match_conf *)addr; | |||
| 282 | if ((error = copyout_map(td, &addr, pci.match_buf_len)) != 0) | |||
| 283 | goto cleanup; | |||
| 284 | pci.matches = (struct pci_conf *)addr; | |||
| 285 | ||||
| 286 | npat_to_convert = min(npat_to_convert, pci.num_patterns); | |||
| 287 | ||||
| 288 | for (i = 0, pmc32p = (struct pci_match_conf32 *)PTRIN(pci32.patterns)(void *)(uintptr_t) (pci32.patterns), | |||
| 289 | pmcp = pci.patterns; | |||
| 290 | i < npat_to_convert; i++, pmc32p++, pmcp++) { | |||
| 291 | if ((error = copyin(pmc32p, &pmc32, sizeof(pmc32))) != 0) | |||
| 292 | goto cleanup; | |||
| 293 | CP(pmc32,pmc,pc_sel)do { (pmc).pc_sel = (pmc32).pc_sel; } while (0); | |||
| 294 | strlcpy(pmc.pd_name, pmc32.pd_name, sizeof(pmc.pd_name)); | |||
| 295 | CP(pmc32,pmc,pd_unit)do { (pmc).pd_unit = (pmc32).pd_unit; } while (0); | |||
| 296 | CP(pmc32,pmc,pc_vendor)do { (pmc).pc_vendor = (pmc32).pc_vendor; } while (0); | |||
| 297 | CP(pmc32,pmc,pc_device)do { (pmc).pc_device = (pmc32).pc_device; } while (0); | |||
| 298 | CP(pmc32,pmc,pc_class)do { (pmc).pc_class = (pmc32).pc_class; } while (0); | |||
| 299 | CP(pmc32,pmc,flags)do { (pmc).flags = (pmc32).flags; } while (0); | |||
| 300 | if ((error = copyout(&pmc, pmcp, sizeof(pmc))) != 0) | |||
| 301 | goto cleanup; | |||
| 302 | } | |||
| 303 | ||||
| 304 | if ((error = fo_ioctl(fp, PCIOCGETCONF((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pci_conf_io)) & ((1 << 13) - 1)) << 16) | (( ('p')) << 8) | ((5)))), (caddr_t)&pci, | |||
| 305 | td->td_ucred, td)) != 0) | |||
| 306 | goto cleanup; | |||
| 307 | ||||
| 308 | nmatch_to_convert = min(nmatch_to_convert, pci.num_matches); | |||
| 309 | ||||
| 310 | for (i = 0, pcp = pci.matches, | |||
| 311 | pc32p = (struct pci_conf32 *)PTRIN(pci32.matches)(void *)(uintptr_t) (pci32.matches); | |||
| 312 | i < nmatch_to_convert; i++, pcp++, pc32p++) { | |||
| 313 | if ((error = copyin(pcp, &pc, sizeof(pc))) != 0) | |||
| 314 | goto cleanup; | |||
| 315 | CP(pc,pc32,pc_sel)do { (pc32).pc_sel = (pc).pc_sel; } while (0); | |||
| 316 | CP(pc,pc32,pc_hdr)do { (pc32).pc_hdr = (pc).pc_hdr; } while (0); | |||
| 317 | CP(pc,pc32,pc_subvendor)do { (pc32).pc_subvendor = (pc).pc_subvendor; } while (0); | |||
| 318 | CP(pc,pc32,pc_subdevice)do { (pc32).pc_subdevice = (pc).pc_subdevice; } while (0); | |||
| 319 | CP(pc,pc32,pc_vendor)do { (pc32).pc_vendor = (pc).pc_vendor; } while (0); | |||
| 320 | CP(pc,pc32,pc_device)do { (pc32).pc_device = (pc).pc_device; } while (0); | |||
| 321 | CP(pc,pc32,pc_class)do { (pc32).pc_class = (pc).pc_class; } while (0); | |||
| 322 | CP(pc,pc32,pc_subclass)do { (pc32).pc_subclass = (pc).pc_subclass; } while (0); | |||
| 323 | CP(pc,pc32,pc_progif)do { (pc32).pc_progif = (pc).pc_progif; } while (0); | |||
| 324 | CP(pc,pc32,pc_revid)do { (pc32).pc_revid = (pc).pc_revid; } while (0); | |||
| 325 | strlcpy(pc32.pd_name, pc.pd_name, sizeof(pc32.pd_name)); | |||
| 326 | CP(pc,pc32,pd_unit)do { (pc32).pd_unit = (pc).pd_unit; } while (0); | |||
| 327 | if ((error = copyout(&pc32, pc32p, sizeof(pc32))) != 0) | |||
| 328 | goto cleanup; | |||
| 329 | } | |||
| 330 | ||||
| 331 | CP(pci, pci32, num_matches)do { (pci32).num_matches = (pci).num_matches; } while (0); | |||
| 332 | CP(pci, pci32, offset)do { (pci32).offset = (pci).offset; } while (0); | |||
| 333 | CP(pci, pci32, generation)do { (pci32).generation = (pci).generation; } while (0); | |||
| 334 | CP(pci, pci32, status)do { (pci32).status = (pci).status; } while (0); | |||
| 335 | ||||
| 336 | error = copyout(&pci32, uap->data, sizeof(pci32)); | |||
| 337 | ||||
| 338 | cleanup: | |||
| 339 | if (pci.patterns) | |||
| 340 | copyout_unmap(td, (vm_offset_t)pci.patterns, pci.pat_buf_len); | |||
| 341 | if (pci.matches) | |||
| 342 | copyout_unmap(td, (vm_offset_t)pci.matches, pci.match_buf_len); | |||
| 343 | ||||
| 344 | return (error); | |||
| 345 | } | |||
| 346 | ||||
| 347 | static int | |||
| 348 | freebsd32_ioctl_sg(struct thread *td, | |||
| 349 | struct freebsd32_ioctl_args *uap, struct file *fp) | |||
| 350 | { | |||
| 351 | struct sg_io_hdr io; | |||
| 352 | struct sg_io_hdr32 io32; | |||
| 353 | int error; | |||
| 354 | ||||
| 355 | if ((error = copyin(uap->data, &io32, sizeof(io32))) != 0) | |||
| 356 | return (error); | |||
| 357 | ||||
| 358 | CP(io32, io, interface_id)do { (io).interface_id = (io32).interface_id; } while (0); | |||
| 359 | CP(io32, io, dxfer_direction)do { (io).dxfer_direction = (io32).dxfer_direction; } while ( 0); | |||
| 360 | CP(io32, io, cmd_len)do { (io).cmd_len = (io32).cmd_len; } while (0); | |||
| 361 | CP(io32, io, mx_sb_len)do { (io).mx_sb_len = (io32).mx_sb_len; } while (0); | |||
| 362 | CP(io32, io, iovec_count)do { (io).iovec_count = (io32).iovec_count; } while (0); | |||
| 363 | CP(io32, io, dxfer_len)do { (io).dxfer_len = (io32).dxfer_len; } while (0); | |||
| 364 | PTRIN_CP(io32, io, dxferp)do { (io).dxferp = (void *)(uintptr_t) ((io32).dxferp); } while (0); | |||
| 365 | PTRIN_CP(io32, io, cmdp)do { (io).cmdp = (void *)(uintptr_t) ((io32).cmdp); } while ( 0); | |||
| 366 | PTRIN_CP(io32, io, sbp)do { (io).sbp = (void *)(uintptr_t) ((io32).sbp); } while (0); | |||
| 367 | CP(io32, io, timeout)do { (io).timeout = (io32).timeout; } while (0); | |||
| 368 | CP(io32, io, flags)do { (io).flags = (io32).flags; } while (0); | |||
| 369 | CP(io32, io, pack_id)do { (io).pack_id = (io32).pack_id; } while (0); | |||
| 370 | PTRIN_CP(io32, io, usr_ptr)do { (io).usr_ptr = (void *)(uintptr_t) ((io32).usr_ptr); } while (0); | |||
| 371 | CP(io32, io, status)do { (io).status = (io32).status; } while (0); | |||
| 372 | CP(io32, io, masked_status)do { (io).masked_status = (io32).masked_status; } while (0); | |||
| 373 | CP(io32, io, msg_status)do { (io).msg_status = (io32).msg_status; } while (0); | |||
| 374 | CP(io32, io, sb_len_wr)do { (io).sb_len_wr = (io32).sb_len_wr; } while (0); | |||
| 375 | CP(io32, io, host_status)do { (io).host_status = (io32).host_status; } while (0); | |||
| 376 | CP(io32, io, driver_status)do { (io).driver_status = (io32).driver_status; } while (0); | |||
| 377 | CP(io32, io, resid)do { (io).resid = (io32).resid; } while (0); | |||
| 378 | CP(io32, io, duration)do { (io).duration = (io32).duration; } while (0); | |||
| 379 | CP(io32, io, info)do { (io).info = (io32).info; } while (0); | |||
| 380 | ||||
| 381 | if ((error = fo_ioctl(fp, SG_IO((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct sg_io_hdr)) & ((1 << 13) - 1)) << 16) | ((('"' )) << 8) | ((0x85)))), (caddr_t)&io, td->td_ucred, td)) != 0) | |||
| 382 | return (error); | |||
| 383 | ||||
| 384 | CP(io, io32, interface_id)do { (io32).interface_id = (io).interface_id; } while (0); | |||
| 385 | CP(io, io32, dxfer_direction)do { (io32).dxfer_direction = (io).dxfer_direction; } while ( 0); | |||
| 386 | CP(io, io32, cmd_len)do { (io32).cmd_len = (io).cmd_len; } while (0); | |||
| 387 | CP(io, io32, mx_sb_len)do { (io32).mx_sb_len = (io).mx_sb_len; } while (0); | |||
| 388 | CP(io, io32, iovec_count)do { (io32).iovec_count = (io).iovec_count; } while (0); | |||
| 389 | CP(io, io32, dxfer_len)do { (io32).dxfer_len = (io).dxfer_len; } while (0); | |||
| 390 | PTROUT_CP(io, io32, dxferp)do { (io32).dxferp = (u_int32_t)(uintptr_t) ((io).dxferp); } while (0); | |||
| 391 | PTROUT_CP(io, io32, cmdp)do { (io32).cmdp = (u_int32_t)(uintptr_t) ((io).cmdp); } while (0); | |||
| 392 | PTROUT_CP(io, io32, sbp)do { (io32).sbp = (u_int32_t)(uintptr_t) ((io).sbp); } while ( 0); | |||
| 393 | CP(io, io32, timeout)do { (io32).timeout = (io).timeout; } while (0); | |||
| 394 | CP(io, io32, flags)do { (io32).flags = (io).flags; } while (0); | |||
| 395 | CP(io, io32, pack_id)do { (io32).pack_id = (io).pack_id; } while (0); | |||
| 396 | PTROUT_CP(io, io32, usr_ptr)do { (io32).usr_ptr = (u_int32_t)(uintptr_t) ((io).usr_ptr); } while (0); | |||
| 397 | CP(io, io32, status)do { (io32).status = (io).status; } while (0); | |||
| 398 | CP(io, io32, masked_status)do { (io32).masked_status = (io).masked_status; } while (0); | |||
| 399 | CP(io, io32, msg_status)do { (io32).msg_status = (io).msg_status; } while (0); | |||
| 400 | CP(io, io32, sb_len_wr)do { (io32).sb_len_wr = (io).sb_len_wr; } while (0); | |||
| 401 | CP(io, io32, host_status)do { (io32).host_status = (io).host_status; } while (0); | |||
| 402 | CP(io, io32, driver_status)do { (io32).driver_status = (io).driver_status; } while (0); | |||
| 403 | CP(io, io32, resid)do { (io32).resid = (io).resid; } while (0); | |||
| 404 | CP(io, io32, duration)do { (io32).duration = (io).duration; } while (0); | |||
| 405 | CP(io, io32, info)do { (io32).info = (io).info; } while (0); | |||
| 406 | ||||
| 407 | error = copyout(&io32, uap->data, sizeof(io32)); | |||
| 408 | ||||
| 409 | return (error); | |||
| 410 | } | |||
| 411 | ||||
| 412 | int | |||
| 413 | freebsd32_ioctl(struct thread *td, struct freebsd32_ioctl_args *uap) | |||
| 414 | { | |||
| 415 | struct ioctl_args ap /*{ | |||
| 416 | int fd; | |||
| 417 | u_long com; | |||
| 418 | caddr_t data; | |||
| 419 | }*/ ; | |||
| 420 | struct file *fp; | |||
| 421 | cap_rights_t rights; | |||
| 422 | int error; | |||
| 423 | ||||
| 424 | error = fget(td, uap->fd, cap_rights_init(&rights, CAP_IOCTL)__cap_rights_init(0, &rights, ((1ULL << (57 + (1))) | (0x0000000000000080ULL)), 0ULL), &fp); | |||
| 425 | if (error != 0) | |||
| 426 | return (error); | |||
| 427 | if ((fp->f_flag & (FREAD0x0001 | FWRITE0x0002)) == 0) { | |||
| 428 | fdrop(fp, td)(refcount_release(&(fp)->f_count) ? _fdrop((fp), (td)) : _fnoop()); | |||
| 429 | return (EBADF9); | |||
| 430 | } | |||
| 431 | ||||
| 432 | switch (uap->com) { | |||
| 433 | case MDIOCATTACH_32((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct md_ioctl32) + 4) & ((1 << 13) - 1)) << 16) | (('m') << 8) | (0))): /* FALLTHROUGH */ | |||
| 434 | case MDIOCDETACH_32((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct md_ioctl32) + 4) & ((1 << 13) - 1)) << 16) | (('m') << 8) | (1))): /* FALLTHROUGH */ | |||
| 435 | case MDIOCQUERY_32((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct md_ioctl32) + 4) & ((1 << 13) - 1)) << 16) | (('m') << 8) | (2))): /* FALLTHROUGH */ | |||
| 436 | case MDIOCLIST_32((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct md_ioctl32) + 4) & ((1 << 13) - 1)) << 16) | (('m') << 8) | (3))): | |||
| 437 | error = freebsd32_ioctl_md(td, uap, fp); | |||
| 438 | break; | |||
| 439 | ||||
| 440 | case CDIOREADTOCENTRYS_32((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct ioc_read_toc_entry32)) & ((1 << 13) - 1)) << 16) | ((('c')) << 8) | ((5)))): | |||
| 441 | error = freebsd32_ioctl_ioc_read_toc(td, uap, fp); | |||
| 442 | break; | |||
| 443 | ||||
| 444 | case CDIOREADTOCHEADER_32((unsigned long) ((0x40000000) | (((sizeof(struct ioc_toc_header32 )) & ((1 << 13) - 1)) << 16) | ((('c')) << 8) | ((4)))): | |||
| 445 | error = freebsd32_ioctl_ioc_toc_header(td, uap, fp); | |||
| 446 | break; | |||
| 447 | ||||
| 448 | case FIODGNAME_32((unsigned long) ((0x80000000) | (((sizeof(struct fiodgname_arg32 )) & ((1 << 13) - 1)) << 16) | ((('f')) << 8) | ((120)))): | |||
| 449 | error = freebsd32_ioctl_fiodgname(td, uap, fp); | |||
| 450 | break; | |||
| 451 | ||||
| 452 | case MEMRANGE_GET32((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct mem_range_op32)) & ((1 << 13) - 1)) << 16) | ((('m')) << 8) | ((50)))): /* FALLTHROUGH */ | |||
| 453 | case MEMRANGE_SET32((unsigned long) ((0x80000000) | (((sizeof(struct mem_range_op32 )) & ((1 << 13) - 1)) << 16) | ((('m')) << 8) | ((51)))): | |||
| 454 | error = freebsd32_ioctl_memrange(td, uap, fp); | |||
| 455 | break; | |||
| 456 | ||||
| 457 | case PCIOCGETCONF_32((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct pci_conf_io32)) & ((1 << 13) - 1)) << 16) | ( (('p')) << 8) | ((5)))): | |||
| 458 | error = freebsd32_ioctl_pciocgetconf(td, uap, fp); | |||
| 459 | break; | |||
| 460 | ||||
| 461 | case SG_IO_32((unsigned long) (((0x80000000|0x40000000)) | (((sizeof(struct sg_io_hdr32)) & ((1 << 13) - 1)) << 16) | (( ('"')) << 8) | ((0x85)))): | |||
| 462 | error = freebsd32_ioctl_sg(td, uap, fp); | |||
| 463 | break; | |||
| 464 | ||||
| 465 | default: | |||
| 466 | fdrop(fp, td)(refcount_release(&(fp)->f_count) ? _fdrop((fp), (td)) : _fnoop()); | |||
| 467 | ap.fd = uap->fd; | |||
| 468 | ap.com = uap->com; | |||
| 469 | PTRIN_CP(*uap, ap, data)do { (ap).data = (void *)(uintptr_t) ((*uap).data); } while ( 0); | |||
| 470 | return sys_ioctl(td, &ap); | |||
| 471 | } | |||
| 472 | ||||
| 473 | fdrop(fp, td)(refcount_release(&(fp)->f_count) ? _fdrop((fp), (td)) : _fnoop()); | |||
| 474 | return error; | |||
| 475 | } |