1 1.36 riastrad /* $NetBSD: sunos32_ioctl.c,v 1.36 2021/09/07 11:43:05 riastradh Exp $ */ 2 1.2 mrg /* from: NetBSD: sunos_ioctl.c,v 1.35 2001/02/03 22:20:02 mrg Exp */ 3 1.1 mrg 4 1.1 mrg /* 5 1.1 mrg * Copyright (c) 2001 Matthew R. Green 6 1.1 mrg * All rights reserved. 7 1.1 mrg * 8 1.1 mrg * Redistribution and use in source and binary forms, with or without 9 1.1 mrg * modification, are permitted provided that the following conditions 10 1.1 mrg * are met: 11 1.1 mrg * 1. Redistributions of source code must retain the above copyright 12 1.1 mrg * notice, this list of conditions and the following disclaimer. 13 1.1 mrg * 2. Redistributions in binary form must reproduce the above copyright 14 1.1 mrg * notice, this list of conditions and the following disclaimer in the 15 1.1 mrg * documentation and/or other materials provided with the distribution. 16 1.1 mrg * 17 1.1 mrg * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 1.1 mrg * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 1.1 mrg * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 1.1 mrg * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 1.1 mrg * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 22 1.1 mrg * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 23 1.1 mrg * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 24 1.1 mrg * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 1.1 mrg * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 1.1 mrg * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 1.1 mrg * SUCH DAMAGE. 28 1.1 mrg */ 29 1.1 mrg 30 1.2 mrg /* 31 1.2 mrg * Copyright (c) 1993 Markus Wild. 32 1.2 mrg * All rights reserved. 33 1.2 mrg * 34 1.2 mrg * Redistribution and use in source and binary forms, with or without 35 1.2 mrg * modification, are permitted provided that the following conditions 36 1.2 mrg * are met: 37 1.2 mrg * 1. Redistributions of source code must retain the above copyright 38 1.2 mrg * notice, this list of conditions and the following disclaimer. 39 1.2 mrg * 2. The name of the author may not be used to endorse or promote products 40 1.2 mrg * derived from this software without specific prior written permission 41 1.2 mrg * 42 1.2 mrg * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 43 1.2 mrg * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 44 1.2 mrg * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 45 1.2 mrg * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 46 1.2 mrg * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 47 1.2 mrg * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 48 1.2 mrg * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 49 1.2 mrg * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 50 1.2 mrg * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 51 1.2 mrg * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 52 1.2 mrg * 53 1.2 mrg * loosely from: Header: sunos_ioctl.c,v 1.7 93/05/28 04:40:43 torek Exp 54 1.2 mrg */ 55 1.7 lukem 56 1.7 lukem #include <sys/cdefs.h> 57 1.36 riastrad __KERNEL_RCSID(0, "$NetBSD: sunos32_ioctl.c,v 1.36 2021/09/07 11:43:05 riastradh Exp $"); 58 1.2 mrg 59 1.4 mrg #if defined(_KERNEL_OPT) 60 1.2 mrg #include "opt_compat_netbsd32.h" 61 1.2 mrg #include "opt_execfmt.h" 62 1.2 mrg #endif 63 1.2 mrg 64 1.2 mrg #include <sys/param.h> 65 1.2 mrg #include <sys/proc.h> 66 1.2 mrg #include <sys/systm.h> 67 1.2 mrg #include <sys/file.h> 68 1.2 mrg #include <sys/filedesc.h> 69 1.2 mrg #include <sys/ioctl.h> 70 1.2 mrg #include <sys/termios.h> 71 1.2 mrg #include <sys/tty.h> 72 1.2 mrg #include <sys/socket.h> 73 1.2 mrg #include <sys/audioio.h> 74 1.2 mrg #include <sys/vnode.h> 75 1.2 mrg #include <sys/mount.h> 76 1.2 mrg #include <sys/disklabel.h> 77 1.2 mrg #include <sys/syscallargs.h> 78 1.2 mrg 79 1.2 mrg #include <miscfs/specfs/specdev.h> 80 1.2 mrg 81 1.2 mrg #include <net/if.h> 82 1.2 mrg 83 1.2 mrg #include <dev/sun/disklabel.h> 84 1.2 mrg 85 1.22 christos #include <compat/sys/sockio.h> 86 1.22 christos 87 1.2 mrg #include <compat/sunos/sunos.h> 88 1.2 mrg #include <compat/sunos/sunos_syscallargs.h> 89 1.2 mrg #include <compat/netbsd32/netbsd32.h> 90 1.2 mrg #include <compat/netbsd32/netbsd32_syscallargs.h> 91 1.2 mrg #include <compat/sunos32/sunos32.h> 92 1.2 mrg #include <compat/sunos32/sunos32_syscallargs.h> 93 1.2 mrg #include <compat/common/compat_util.h> 94 1.2 mrg 95 1.2 mrg /* 96 1.2 mrg * SunOS ioctl calls. 97 1.2 mrg * This file is something of a hodge-podge. 98 1.2 mrg * Support gets added as things turn up.... 99 1.2 mrg */ 100 1.2 mrg 101 1.14 matt static const struct speedtab sptab[] = { 102 1.2 mrg { 0, 0 }, 103 1.2 mrg { 50, 1 }, 104 1.2 mrg { 75, 2 }, 105 1.2 mrg { 110, 3 }, 106 1.2 mrg { 134, 4 }, 107 1.2 mrg { 135, 4 }, 108 1.2 mrg { 150, 5 }, 109 1.2 mrg { 200, 6 }, 110 1.2 mrg { 300, 7 }, 111 1.2 mrg { 600, 8 }, 112 1.2 mrg { 1200, 9 }, 113 1.2 mrg { 1800, 10 }, 114 1.2 mrg { 2400, 11 }, 115 1.2 mrg { 4800, 12 }, 116 1.2 mrg { 9600, 13 }, 117 1.2 mrg { 19200, 14 }, 118 1.2 mrg { 38400, 15 }, 119 1.2 mrg { -1, -1 } 120 1.2 mrg }; 121 1.2 mrg 122 1.14 matt static const netbsd32_u_long s2btab[] = { 123 1.2 mrg 0, 124 1.2 mrg 50, 125 1.2 mrg 75, 126 1.2 mrg 110, 127 1.2 mrg 134, 128 1.2 mrg 150, 129 1.2 mrg 200, 130 1.2 mrg 300, 131 1.2 mrg 600, 132 1.2 mrg 1200, 133 1.2 mrg 1800, 134 1.2 mrg 2400, 135 1.2 mrg 4800, 136 1.2 mrg 9600, 137 1.2 mrg 19200, 138 1.2 mrg 38400, 139 1.2 mrg }; 140 1.2 mrg 141 1.24 dsl static void stios2btios(struct sunos_termios *, struct termios *); 142 1.24 dsl static void btios2stios(struct termios *, struct sunos_termios *); 143 1.24 dsl static void stios2stio(struct sunos_termios *, struct sunos_termio *); 144 1.24 dsl static void stio2stios(struct sunos_termio *, struct sunos_termios *); 145 1.2 mrg 146 1.2 mrg /* 147 1.2 mrg * These two conversion functions have mostly been done 148 1.2 mrg * with some perl cut&paste, then hand-edited to comment 149 1.2 mrg * out what doesn't exist under NetBSD. 150 1.2 mrg * A note from Markus's code: 151 1.2 mrg * (l & BITMASK1) / BITMASK1 * BITMASK2 is translated 152 1.2 mrg * optimally by gcc m68k, much better than any ?: stuff. 153 1.2 mrg * Code may vary with different architectures of course. 154 1.2 mrg * 155 1.2 mrg * I don't know what optimizer you used, but seeing divu's and 156 1.2 mrg * bfextu's in the m68k assembly output did not encourage me... 157 1.2 mrg * as well, gcc on the sparc definitely generates much better 158 1.2 mrg * code with `?:'. 159 1.2 mrg */ 160 1.2 mrg 161 1.2 mrg static void 162 1.25 dsl stios2btios(struct sunos_termios *st, struct termios *bt) 163 1.2 mrg { 164 1.3 mrg netbsd32_u_long l, r; 165 1.2 mrg 166 1.36 riastrad memset(bt, 0, sizeof(*bt)); 167 1.36 riastrad 168 1.2 mrg l = st->c_iflag; 169 1.2 mrg r = ((l & 0x00000001) ? IGNBRK : 0); 170 1.2 mrg r |= ((l & 0x00000002) ? BRKINT : 0); 171 1.2 mrg r |= ((l & 0x00000004) ? IGNPAR : 0); 172 1.2 mrg r |= ((l & 0x00000008) ? PARMRK : 0); 173 1.2 mrg r |= ((l & 0x00000010) ? INPCK : 0); 174 1.2 mrg r |= ((l & 0x00000020) ? ISTRIP : 0); 175 1.2 mrg r |= ((l & 0x00000040) ? INLCR : 0); 176 1.2 mrg r |= ((l & 0x00000080) ? IGNCR : 0); 177 1.2 mrg r |= ((l & 0x00000100) ? ICRNL : 0); 178 1.2 mrg /* ((l & 0x00000200) ? IUCLC : 0) */ 179 1.2 mrg r |= ((l & 0x00000400) ? IXON : 0); 180 1.2 mrg r |= ((l & 0x00000800) ? IXANY : 0); 181 1.2 mrg r |= ((l & 0x00001000) ? IXOFF : 0); 182 1.2 mrg r |= ((l & 0x00002000) ? IMAXBEL : 0); 183 1.2 mrg bt->c_iflag = r; 184 1.2 mrg 185 1.2 mrg l = st->c_oflag; 186 1.2 mrg r = ((l & 0x00000001) ? OPOST : 0); 187 1.2 mrg /* ((l & 0x00000002) ? OLCUC : 0) */ 188 1.2 mrg r |= ((l & 0x00000004) ? ONLCR : 0); 189 1.2 mrg /* ((l & 0x00000008) ? OCRNL : 0) */ 190 1.2 mrg /* ((l & 0x00000010) ? ONOCR : 0) */ 191 1.2 mrg /* ((l & 0x00000020) ? ONLRET : 0) */ 192 1.2 mrg /* ((l & 0x00000040) ? OFILL : 0) */ 193 1.2 mrg /* ((l & 0x00000080) ? OFDEL : 0) */ 194 1.2 mrg /* ((l & 0x00000100) ? NLDLY : 0) */ 195 1.2 mrg /* ((l & 0x00000100) ? NL1 : 0) */ 196 1.2 mrg /* ((l & 0x00000600) ? CRDLY : 0) */ 197 1.2 mrg /* ((l & 0x00000200) ? CR1 : 0) */ 198 1.2 mrg /* ((l & 0x00000400) ? CR2 : 0) */ 199 1.2 mrg /* ((l & 0x00000600) ? CR3 : 0) */ 200 1.2 mrg /* ((l & 0x00001800) ? TABDLY : 0) */ 201 1.2 mrg /* ((l & 0x00000800) ? TAB1 : 0) */ 202 1.2 mrg /* ((l & 0x00001000) ? TAB2 : 0) */ 203 1.2 mrg r |= ((l & 0x00001800) ? OXTABS : 0); 204 1.2 mrg /* ((l & 0x00002000) ? BSDLY : 0) */ 205 1.2 mrg /* ((l & 0x00002000) ? BS1 : 0) */ 206 1.2 mrg /* ((l & 0x00004000) ? VTDLY : 0) */ 207 1.2 mrg /* ((l & 0x00004000) ? VT1 : 0) */ 208 1.2 mrg /* ((l & 0x00008000) ? FFDLY : 0) */ 209 1.2 mrg /* ((l & 0x00008000) ? FF1 : 0) */ 210 1.2 mrg /* ((l & 0x00010000) ? PAGEOUT : 0) */ 211 1.2 mrg /* ((l & 0x00020000) ? WRAP : 0) */ 212 1.2 mrg bt->c_oflag = r; 213 1.2 mrg 214 1.2 mrg l = st->c_cflag; 215 1.2 mrg switch (l & 0x00000030) { 216 1.2 mrg case 0: 217 1.2 mrg r = CS5; 218 1.2 mrg break; 219 1.2 mrg case 0x00000010: 220 1.2 mrg r = CS6; 221 1.2 mrg break; 222 1.2 mrg case 0x00000020: 223 1.2 mrg r = CS7; 224 1.2 mrg break; 225 1.2 mrg case 0x00000030: 226 1.2 mrg r = CS8; 227 1.2 mrg break; 228 1.2 mrg } 229 1.2 mrg r |= ((l & 0x00000040) ? CSTOPB : 0); 230 1.2 mrg r |= ((l & 0x00000080) ? CREAD : 0); 231 1.2 mrg r |= ((l & 0x00000100) ? PARENB : 0); 232 1.2 mrg r |= ((l & 0x00000200) ? PARODD : 0); 233 1.2 mrg r |= ((l & 0x00000400) ? HUPCL : 0); 234 1.2 mrg r |= ((l & 0x00000800) ? CLOCAL : 0); 235 1.2 mrg /* ((l & 0x00001000) ? LOBLK : 0) */ 236 1.2 mrg r |= ((l & 0x80000000) ? (CRTS_IFLOW|CCTS_OFLOW) : 0); 237 1.2 mrg bt->c_cflag = r; 238 1.2 mrg 239 1.2 mrg bt->c_ispeed = bt->c_ospeed = s2btab[l & 0x0000000f]; 240 1.2 mrg 241 1.2 mrg l = st->c_lflag; 242 1.2 mrg r = ((l & 0x00000001) ? ISIG : 0); 243 1.2 mrg r |= ((l & 0x00000002) ? ICANON : 0); 244 1.2 mrg /* ((l & 0x00000004) ? XCASE : 0) */ 245 1.2 mrg r |= ((l & 0x00000008) ? ECHO : 0); 246 1.2 mrg r |= ((l & 0x00000010) ? ECHOE : 0); 247 1.2 mrg r |= ((l & 0x00000020) ? ECHOK : 0); 248 1.2 mrg r |= ((l & 0x00000040) ? ECHONL : 0); 249 1.2 mrg r |= ((l & 0x00000080) ? NOFLSH : 0); 250 1.2 mrg r |= ((l & 0x00000100) ? TOSTOP : 0); 251 1.2 mrg r |= ((l & 0x00000200) ? ECHOCTL : 0); 252 1.2 mrg r |= ((l & 0x00000400) ? ECHOPRT : 0); 253 1.2 mrg r |= ((l & 0x00000800) ? ECHOKE : 0); 254 1.2 mrg /* ((l & 0x00001000) ? DEFECHO : 0) */ 255 1.2 mrg r |= ((l & 0x00002000) ? FLUSHO : 0); 256 1.2 mrg r |= ((l & 0x00004000) ? PENDIN : 0); 257 1.2 mrg bt->c_lflag = r; 258 1.2 mrg 259 1.2 mrg bt->c_cc[VINTR] = st->c_cc[0] ? st->c_cc[0] : _POSIX_VDISABLE; 260 1.2 mrg bt->c_cc[VQUIT] = st->c_cc[1] ? st->c_cc[1] : _POSIX_VDISABLE; 261 1.2 mrg bt->c_cc[VERASE] = st->c_cc[2] ? st->c_cc[2] : _POSIX_VDISABLE; 262 1.2 mrg bt->c_cc[VKILL] = st->c_cc[3] ? st->c_cc[3] : _POSIX_VDISABLE; 263 1.2 mrg bt->c_cc[VEOF] = st->c_cc[4] ? st->c_cc[4] : _POSIX_VDISABLE; 264 1.2 mrg bt->c_cc[VEOL] = st->c_cc[5] ? st->c_cc[5] : _POSIX_VDISABLE; 265 1.2 mrg bt->c_cc[VEOL2] = st->c_cc[6] ? st->c_cc[6] : _POSIX_VDISABLE; 266 1.2 mrg /* bt->c_cc[VSWTCH] = st->c_cc[7] ? st->c_cc[7] : _POSIX_VDISABLE; */ 267 1.2 mrg bt->c_cc[VSTART] = st->c_cc[8] ? st->c_cc[8] : _POSIX_VDISABLE; 268 1.2 mrg bt->c_cc[VSTOP] = st->c_cc[9] ? st->c_cc[9] : _POSIX_VDISABLE; 269 1.2 mrg bt->c_cc[VSUSP] = st->c_cc[10] ? st->c_cc[10] : _POSIX_VDISABLE; 270 1.2 mrg bt->c_cc[VDSUSP] = st->c_cc[11] ? st->c_cc[11] : _POSIX_VDISABLE; 271 1.2 mrg bt->c_cc[VREPRINT] = st->c_cc[12] ? st->c_cc[12] : _POSIX_VDISABLE; 272 1.2 mrg bt->c_cc[VDISCARD] = st->c_cc[13] ? st->c_cc[13] : _POSIX_VDISABLE; 273 1.2 mrg bt->c_cc[VWERASE] = st->c_cc[14] ? st->c_cc[14] : _POSIX_VDISABLE; 274 1.2 mrg bt->c_cc[VLNEXT] = st->c_cc[15] ? st->c_cc[15] : _POSIX_VDISABLE; 275 1.2 mrg bt->c_cc[VSTATUS] = st->c_cc[16] ? st->c_cc[16] : _POSIX_VDISABLE; 276 1.2 mrg 277 1.2 mrg /* if `raw mode', create native VMIN/VTIME from SunOS VEOF/VEOL */ 278 1.2 mrg bt->c_cc[VMIN] = (bt->c_lflag & ICANON) ? 1 : bt->c_cc[VEOF]; 279 1.2 mrg bt->c_cc[VTIME] = (bt->c_lflag & ICANON) ? 1 : bt->c_cc[VEOL]; 280 1.2 mrg } 281 1.2 mrg 282 1.2 mrg 283 1.2 mrg static void 284 1.25 dsl btios2stios(struct termios *bt, struct sunos_termios *st) 285 1.2 mrg { 286 1.3 mrg netbsd32_u_long l, r; 287 1.2 mrg int s; 288 1.2 mrg 289 1.36 riastrad memset(st, 0, sizeof(*st)); 290 1.36 riastrad 291 1.2 mrg l = bt->c_iflag; 292 1.2 mrg r = ((l & IGNBRK) ? 0x00000001 : 0); 293 1.2 mrg r |= ((l & BRKINT) ? 0x00000002 : 0); 294 1.2 mrg r |= ((l & IGNPAR) ? 0x00000004 : 0); 295 1.2 mrg r |= ((l & PARMRK) ? 0x00000008 : 0); 296 1.2 mrg r |= ((l & INPCK) ? 0x00000010 : 0); 297 1.2 mrg r |= ((l & ISTRIP) ? 0x00000020 : 0); 298 1.2 mrg r |= ((l & INLCR) ? 0x00000040 : 0); 299 1.2 mrg r |= ((l & IGNCR) ? 0x00000080 : 0); 300 1.2 mrg r |= ((l & ICRNL) ? 0x00000100 : 0); 301 1.2 mrg /* ((l & IUCLC) ? 0x00000200 : 0) */ 302 1.2 mrg r |= ((l & IXON) ? 0x00000400 : 0); 303 1.2 mrg r |= ((l & IXANY) ? 0x00000800 : 0); 304 1.2 mrg r |= ((l & IXOFF) ? 0x00001000 : 0); 305 1.2 mrg r |= ((l & IMAXBEL) ? 0x00002000 : 0); 306 1.2 mrg st->c_iflag = r; 307 1.2 mrg 308 1.2 mrg l = bt->c_oflag; 309 1.2 mrg r = ((l & OPOST) ? 0x00000001 : 0); 310 1.2 mrg /* ((l & OLCUC) ? 0x00000002 : 0) */ 311 1.2 mrg r |= ((l & ONLCR) ? 0x00000004 : 0); 312 1.2 mrg /* ((l & OCRNL) ? 0x00000008 : 0) */ 313 1.2 mrg /* ((l & ONOCR) ? 0x00000010 : 0) */ 314 1.2 mrg /* ((l & ONLRET) ? 0x00000020 : 0) */ 315 1.2 mrg /* ((l & OFILL) ? 0x00000040 : 0) */ 316 1.2 mrg /* ((l & OFDEL) ? 0x00000080 : 0) */ 317 1.2 mrg /* ((l & NLDLY) ? 0x00000100 : 0) */ 318 1.2 mrg /* ((l & NL1) ? 0x00000100 : 0) */ 319 1.2 mrg /* ((l & CRDLY) ? 0x00000600 : 0) */ 320 1.2 mrg /* ((l & CR1) ? 0x00000200 : 0) */ 321 1.2 mrg /* ((l & CR2) ? 0x00000400 : 0) */ 322 1.2 mrg /* ((l & CR3) ? 0x00000600 : 0) */ 323 1.2 mrg /* ((l & TABDLY) ? 0x00001800 : 0) */ 324 1.2 mrg /* ((l & TAB1) ? 0x00000800 : 0) */ 325 1.2 mrg /* ((l & TAB2) ? 0x00001000 : 0) */ 326 1.2 mrg r |= ((l & OXTABS) ? 0x00001800 : 0); 327 1.2 mrg /* ((l & BSDLY) ? 0x00002000 : 0) */ 328 1.2 mrg /* ((l & BS1) ? 0x00002000 : 0) */ 329 1.2 mrg /* ((l & VTDLY) ? 0x00004000 : 0) */ 330 1.2 mrg /* ((l & VT1) ? 0x00004000 : 0) */ 331 1.2 mrg /* ((l & FFDLY) ? 0x00008000 : 0) */ 332 1.2 mrg /* ((l & FF1) ? 0x00008000 : 0) */ 333 1.2 mrg /* ((l & PAGEOUT) ? 0x00010000 : 0) */ 334 1.2 mrg /* ((l & WRAP) ? 0x00020000 : 0) */ 335 1.2 mrg st->c_oflag = r; 336 1.2 mrg 337 1.2 mrg l = bt->c_cflag; 338 1.2 mrg switch (l & CSIZE) { 339 1.2 mrg case CS5: 340 1.2 mrg r = 0; 341 1.2 mrg break; 342 1.2 mrg case CS6: 343 1.2 mrg r = 0x00000010; 344 1.2 mrg break; 345 1.2 mrg case CS7: 346 1.2 mrg r = 0x00000020; 347 1.2 mrg break; 348 1.2 mrg case CS8: 349 1.2 mrg r = 0x00000030; 350 1.2 mrg break; 351 1.2 mrg } 352 1.2 mrg r |= ((l & CSTOPB) ? 0x00000040 : 0); 353 1.2 mrg r |= ((l & CREAD) ? 0x00000080 : 0); 354 1.2 mrg r |= ((l & PARENB) ? 0x00000100 : 0); 355 1.2 mrg r |= ((l & PARODD) ? 0x00000200 : 0); 356 1.2 mrg r |= ((l & HUPCL) ? 0x00000400 : 0); 357 1.2 mrg r |= ((l & CLOCAL) ? 0x00000800 : 0); 358 1.2 mrg /* ((l & LOBLK) ? 0x00001000 : 0) */ 359 1.2 mrg r |= ((l & (CRTS_IFLOW|CCTS_OFLOW)) ? 0x80000000 : 0); 360 1.2 mrg st->c_cflag = r; 361 1.2 mrg 362 1.2 mrg l = bt->c_lflag; 363 1.2 mrg r = ((l & ISIG) ? 0x00000001 : 0); 364 1.2 mrg r |= ((l & ICANON) ? 0x00000002 : 0); 365 1.2 mrg /* ((l & XCASE) ? 0x00000004 : 0) */ 366 1.2 mrg r |= ((l & ECHO) ? 0x00000008 : 0); 367 1.2 mrg r |= ((l & ECHOE) ? 0x00000010 : 0); 368 1.2 mrg r |= ((l & ECHOK) ? 0x00000020 : 0); 369 1.2 mrg r |= ((l & ECHONL) ? 0x00000040 : 0); 370 1.2 mrg r |= ((l & NOFLSH) ? 0x00000080 : 0); 371 1.2 mrg r |= ((l & TOSTOP) ? 0x00000100 : 0); 372 1.2 mrg r |= ((l & ECHOCTL) ? 0x00000200 : 0); 373 1.2 mrg r |= ((l & ECHOPRT) ? 0x00000400 : 0); 374 1.2 mrg r |= ((l & ECHOKE) ? 0x00000800 : 0); 375 1.2 mrg /* ((l & DEFECHO) ? 0x00001000 : 0) */ 376 1.2 mrg r |= ((l & FLUSHO) ? 0x00002000 : 0); 377 1.2 mrg r |= ((l & PENDIN) ? 0x00004000 : 0); 378 1.2 mrg st->c_lflag = r; 379 1.2 mrg 380 1.2 mrg s = ttspeedtab(bt->c_ospeed, sptab); 381 1.2 mrg if (s >= 0) 382 1.2 mrg st->c_cflag |= s; 383 1.2 mrg 384 1.2 mrg st->c_cc[0] = bt->c_cc[VINTR] != _POSIX_VDISABLE? bt->c_cc[VINTR]:0; 385 1.2 mrg st->c_cc[1] = bt->c_cc[VQUIT] != _POSIX_VDISABLE? bt->c_cc[VQUIT]:0; 386 1.2 mrg st->c_cc[2] = bt->c_cc[VERASE] != _POSIX_VDISABLE? bt->c_cc[VERASE]:0; 387 1.2 mrg st->c_cc[3] = bt->c_cc[VKILL] != _POSIX_VDISABLE? bt->c_cc[VKILL]:0; 388 1.2 mrg st->c_cc[4] = bt->c_cc[VEOF] != _POSIX_VDISABLE? bt->c_cc[VEOF]:0; 389 1.2 mrg st->c_cc[5] = bt->c_cc[VEOL] != _POSIX_VDISABLE? bt->c_cc[VEOL]:0; 390 1.2 mrg st->c_cc[6] = bt->c_cc[VEOL2] != _POSIX_VDISABLE? bt->c_cc[VEOL2]:0; 391 1.2 mrg st->c_cc[7] = 0; 392 1.2 mrg /* bt->c_cc[VSWTCH] != _POSIX_VDISABLE? bt->c_cc[VSWTCH]: */ 393 1.2 mrg st->c_cc[8] = bt->c_cc[VSTART] != _POSIX_VDISABLE? bt->c_cc[VSTART]:0; 394 1.2 mrg st->c_cc[9] = bt->c_cc[VSTOP] != _POSIX_VDISABLE? bt->c_cc[VSTOP]:0; 395 1.2 mrg st->c_cc[10]= bt->c_cc[VSUSP] != _POSIX_VDISABLE? bt->c_cc[VSUSP]:0; 396 1.2 mrg st->c_cc[11]= bt->c_cc[VDSUSP] != _POSIX_VDISABLE? bt->c_cc[VDSUSP]:0; 397 1.2 mrg st->c_cc[12]= bt->c_cc[VREPRINT]!= _POSIX_VDISABLE? bt->c_cc[VREPRINT]:0; 398 1.2 mrg st->c_cc[13]= bt->c_cc[VDISCARD]!= _POSIX_VDISABLE? bt->c_cc[VDISCARD]:0; 399 1.2 mrg st->c_cc[14]= bt->c_cc[VWERASE] != _POSIX_VDISABLE? bt->c_cc[VWERASE]:0; 400 1.2 mrg st->c_cc[15]= bt->c_cc[VLNEXT] != _POSIX_VDISABLE? bt->c_cc[VLNEXT]:0; 401 1.2 mrg st->c_cc[16]= bt->c_cc[VSTATUS] != _POSIX_VDISABLE? bt->c_cc[VSTATUS]:0; 402 1.2 mrg 403 1.2 mrg if (!(bt->c_lflag & ICANON)) { 404 1.2 mrg /* SunOS stores VMIN/VTIME in VEOF/VEOL (if ICANON is off) */ 405 1.2 mrg st->c_cc[4] = bt->c_cc[VMIN]; 406 1.2 mrg st->c_cc[5] = bt->c_cc[VTIME]; 407 1.2 mrg } 408 1.2 mrg 409 1.2 mrg st->c_line = 0; 410 1.2 mrg } 411 1.2 mrg 412 1.2 mrg static void 413 1.25 dsl stios2stio(struct sunos_termios *ts, struct sunos_termio *t) 414 1.2 mrg { 415 1.36 riastrad 416 1.36 riastrad memset(t, 0, sizeof(*t)); 417 1.2 mrg t->c_iflag = ts->c_iflag; 418 1.2 mrg t->c_oflag = ts->c_oflag; 419 1.2 mrg t->c_cflag = ts->c_cflag; 420 1.2 mrg t->c_lflag = ts->c_lflag; 421 1.2 mrg t->c_line = ts->c_line; 422 1.2 mrg memcpy(t->c_cc, ts->c_cc, 8); 423 1.2 mrg } 424 1.2 mrg 425 1.2 mrg static void 426 1.25 dsl stio2stios(struct sunos_termio *t, struct sunos_termios *ts) 427 1.2 mrg { 428 1.36 riastrad 429 1.36 riastrad memset(ts, 0, sizeof(*ts)); 430 1.2 mrg ts->c_iflag = t->c_iflag; 431 1.2 mrg ts->c_oflag = t->c_oflag; 432 1.2 mrg ts->c_cflag = t->c_cflag; 433 1.2 mrg ts->c_lflag = t->c_lflag; 434 1.2 mrg ts->c_line = t->c_line; 435 1.2 mrg memcpy(ts->c_cc, t->c_cc, 8); /* don't touch the upper fields! */ 436 1.2 mrg } 437 1.2 mrg 438 1.27 dsl 439 1.27 dsl static int 440 1.27 dsl sunos32_do_ioctl(int fd, int cmd, void *arg, struct lwp *l) 441 1.27 dsl { 442 1.28 ad file_t *fp; 443 1.27 dsl struct vnode *vp; 444 1.27 dsl int error; 445 1.27 dsl 446 1.31 nakayama if ((error = fd_getvnode(fd, &fp)) != 0) 447 1.30 matt return error; 448 1.27 dsl if ((fp->f_flag & (FREAD|FWRITE)) == 0) { 449 1.28 ad fd_putfile(fd); 450 1.27 dsl return EBADF; 451 1.27 dsl } 452 1.28 ad error = fp->f_ops->fo_ioctl(fp, cmd, arg); 453 1.27 dsl if (error == EIO && cmd == TIOCGPGRP) { 454 1.30 matt vp = fp->f_vnode; 455 1.27 dsl if (vp != NULL && vp->v_type == VCHR && major(vp->v_rdev) == 21) 456 1.27 dsl error = ENOTTY; 457 1.27 dsl } 458 1.28 ad fd_putfile(fd); 459 1.27 dsl return error; 460 1.27 dsl } 461 1.27 dsl 462 1.2 mrg int 463 1.35 msaitoh sunos32_sys_ioctl(struct lwp *l, const struct sunos32_sys_ioctl_args *uap, 464 1.35 msaitoh register_t *retval) 465 1.2 mrg { 466 1.26 dsl /* { 467 1.2 mrg int fd; 468 1.2 mrg netbsd32_u_long com; 469 1.19 christos netbsd32_caddr_t data; 470 1.26 dsl } */ 471 1.26 dsl struct netbsd32_ioctl_args bsd_ua; 472 1.2 mrg int error; 473 1.2 mrg 474 1.26 dsl SCARG(&bsd_ua, fd) = SCARG(uap, fd); 475 1.26 dsl SCARG(&bsd_ua, com) = SCARG(uap, com); 476 1.26 dsl SCARG(&bsd_ua, data) = SCARG(uap, data); 477 1.26 dsl 478 1.2 mrg switch (SCARG(uap, com)) { 479 1.2 mrg case _IOR('t', 0, int): 480 1.26 dsl SCARG(&bsd_ua, com) = TIOCGETD; 481 1.2 mrg break; 482 1.2 mrg case _IOW('t', 1, int): 483 1.2 mrg { 484 1.2 mrg int disc; 485 1.2 mrg 486 1.20 dsl if ((error = copyin(SCARG_P32(uap, data), &disc, 487 1.2 mrg sizeof disc)) != 0) 488 1.2 mrg return error; 489 1.2 mrg 490 1.2 mrg /* map SunOS NTTYDISC into our termios discipline */ 491 1.2 mrg if (disc == 2) 492 1.2 mrg disc = 0; 493 1.2 mrg /* all other disciplines are not supported by NetBSD */ 494 1.2 mrg if (disc) 495 1.2 mrg return ENXIO; 496 1.2 mrg 497 1.27 dsl return sunos32_do_ioctl(SCARG(&bsd_ua, fd), TIOCSETD, &disc, l); 498 1.2 mrg } 499 1.2 mrg case _IOW('t', 101, int): /* sun SUNOS_TIOCSSOFTCAR */ 500 1.2 mrg { 501 1.2 mrg int x; /* unused */ 502 1.2 mrg 503 1.20 dsl return copyin(SCARG_P32(uap, data), &x, sizeof x); 504 1.2 mrg } 505 1.2 mrg case _IOR('t', 100, int): /* sun SUNOS_TIOCSSOFTCAR */ 506 1.2 mrg { 507 1.2 mrg int x = 0; 508 1.2 mrg 509 1.20 dsl return copyout(&x, SCARG_P32(uap, data), sizeof x); 510 1.2 mrg } 511 1.2 mrg case _IO('t', 36): /* sun TIOCCONS, no parameters */ 512 1.2 mrg { 513 1.2 mrg int on = 1; 514 1.27 dsl return sunos32_do_ioctl(SCARG(&bsd_ua, fd), TIOCCONS, &on, l); 515 1.2 mrg } 516 1.2 mrg case _IOW('t', 37, struct sunos_ttysize): 517 1.2 mrg { 518 1.2 mrg struct winsize ws; 519 1.2 mrg struct sunos_ttysize ss; 520 1.2 mrg 521 1.35 msaitoh error = sunos32_do_ioctl(SCARG(&bsd_ua, fd), TIOCGWINSZ, &ws, 522 1.35 msaitoh l); 523 1.35 msaitoh if (error != 0) 524 1.35 msaitoh return error; 525 1.2 mrg 526 1.35 msaitoh error = copyin(SCARG_P32(uap, data), &ss, sizeof(ss)); 527 1.35 msaitoh if (error != 0) 528 1.2 mrg return error; 529 1.2 mrg 530 1.2 mrg ws.ws_row = ss.ts_row; 531 1.2 mrg ws.ws_col = ss.ts_col; 532 1.2 mrg 533 1.35 msaitoh return sunos32_do_ioctl(SCARG(&bsd_ua, fd), TIOCSWINSZ, &ws, l); 534 1.2 mrg } 535 1.2 mrg case _IOW('t', 38, struct sunos_ttysize): 536 1.2 mrg { 537 1.2 mrg struct winsize ws; 538 1.2 mrg struct sunos_ttysize ss; 539 1.2 mrg 540 1.35 msaitoh error = sunos32_do_ioctl(SCARG(&bsd_ua, fd), TIOCGWINSZ, &ws, 541 1.35 msaitoh l); 542 1.35 msaitoh if (error != 0) 543 1.35 msaitoh return error; 544 1.2 mrg 545 1.36 riastrad memset(&ss, 0, sizeof(ss)); 546 1.2 mrg ss.ts_row = ws.ws_row; 547 1.2 mrg ss.ts_col = ws.ws_col; 548 1.2 mrg 549 1.35 msaitoh return copyout(&ss, SCARG_P32(uap, data), sizeof(ss)); 550 1.2 mrg } 551 1.2 mrg case _IOW('t', 130, int): /* TIOCSETPGRP: posix variant */ 552 1.26 dsl SCARG(&bsd_ua, com) = TIOCSPGRP; 553 1.2 mrg break; 554 1.2 mrg case _IOR('t', 131, int): /* TIOCGETPGRP: posix variant */ 555 1.2 mrg { 556 1.2 mrg /* 557 1.2 mrg * sigh, must do error translation on pty devices 558 1.2 mrg * (see also kern/tty_pty.c) 559 1.2 mrg */ 560 1.2 mrg int pgrp; 561 1.35 msaitoh error = sunos32_do_ioctl(SCARG(&bsd_ua, fd), TIOCGPGRP, &pgrp, 562 1.35 msaitoh l); 563 1.27 dsl if (error) 564 1.35 msaitoh return error; 565 1.20 dsl return copyout(&pgrp, SCARG_P32(uap, data), sizeof(pgrp)); 566 1.2 mrg } 567 1.2 mrg case _IO('t', 132): 568 1.26 dsl SCARG(&bsd_ua, com) = TIOCSCTTY; 569 1.2 mrg break; 570 1.2 mrg case SUNOS_TCGETA: 571 1.2 mrg case SUNOS_TCGETS: 572 1.2 mrg { 573 1.2 mrg struct termios bts; 574 1.2 mrg struct sunos_termios sts; 575 1.2 mrg struct sunos_termio st; 576 1.2 mrg 577 1.35 msaitoh error = sunos32_do_ioctl(SCARG(&bsd_ua, fd), TIOCGETA, &bts, 578 1.35 msaitoh l); 579 1.35 msaitoh if (error != 0) 580 1.2 mrg return error; 581 1.2 mrg 582 1.2 mrg btios2stios (&bts, &sts); 583 1.2 mrg if (SCARG(uap, com) == SUNOS_TCGETA) { 584 1.2 mrg stios2stio (&sts, &st); 585 1.35 msaitoh return copyout(&st, SCARG_P32(uap, data), sizeof(st)); 586 1.2 mrg } else 587 1.20 dsl return copyout(&sts, SCARG_P32(uap, data), 588 1.35 msaitoh sizeof(sts)); 589 1.2 mrg /*NOTREACHED*/ 590 1.2 mrg } 591 1.2 mrg case SUNOS_TCSETA: 592 1.2 mrg case SUNOS_TCSETAW: 593 1.2 mrg case SUNOS_TCSETAF: 594 1.2 mrg { 595 1.2 mrg struct termios bts; 596 1.2 mrg struct sunos_termios sts; 597 1.2 mrg struct sunos_termio st; 598 1.2 mrg 599 1.20 dsl if ((error = copyin(SCARG_P32(uap, data), &st, 600 1.35 msaitoh sizeof(st))) != 0) 601 1.2 mrg return error; 602 1.2 mrg 603 1.2 mrg /* get full BSD termios so we don't lose information */ 604 1.35 msaitoh if ((error = sunos32_do_ioctl(SCARG(&bsd_ua, fd), TIOCGETA, 605 1.35 msaitoh &bts, l)) != 0) 606 1.2 mrg return error; 607 1.2 mrg 608 1.2 mrg /* 609 1.2 mrg * convert to sun termios, copy in information from 610 1.2 mrg * termio, and convert back, then set new values. 611 1.2 mrg */ 612 1.2 mrg btios2stios(&bts, &sts); 613 1.2 mrg stio2stios(&st, &sts); 614 1.2 mrg stios2btios(&sts, &bts); 615 1.2 mrg 616 1.35 msaitoh return sunos32_do_ioctl(SCARG(&bsd_ua, fd), 617 1.35 msaitoh SCARG(uap, com) - SUNOS_TCSETA + TIOCSETA, &bts, l); 618 1.2 mrg } 619 1.2 mrg case SUNOS_TCSETS: 620 1.2 mrg case SUNOS_TCSETSW: 621 1.2 mrg case SUNOS_TCSETSF: 622 1.2 mrg { 623 1.2 mrg struct termios bts; 624 1.2 mrg struct sunos_termios sts; 625 1.2 mrg 626 1.20 dsl if ((error = copyin(SCARG_P32(uap, data), &sts, 627 1.35 msaitoh sizeof(sts))) != 0) 628 1.2 mrg return error; 629 1.2 mrg stios2btios (&sts, &bts); 630 1.35 msaitoh return sunos32_do_ioctl(SCARG(&bsd_ua, fd), 631 1.35 msaitoh SCARG(uap, com) - SUNOS_TCSETS + TIOCSETA, &bts, l); 632 1.2 mrg } 633 1.2 mrg /* 634 1.2 mrg * Pseudo-tty ioctl translations. 635 1.2 mrg */ 636 1.2 mrg case _IOW('t', 32, int): { /* TIOCTCNTL */ 637 1.15 christos int error1, on; 638 1.2 mrg 639 1.35 msaitoh error1 = copyin(SCARG_P32(uap, data), &on, sizeof(on)); 640 1.15 christos if (error1) 641 1.15 christos return error1; 642 1.27 dsl return sunos32_do_ioctl(SCARG(&bsd_ua, fd), TIOCUCNTL, &on, l); 643 1.2 mrg } 644 1.2 mrg case _IOW('t', 33, int): { /* TIOCSIGNAL */ 645 1.15 christos int error1, sig; 646 1.2 mrg 647 1.35 msaitoh error1 = copyin(SCARG_P32(uap, data), &sig, sizeof(sig)); 648 1.15 christos if (error1) 649 1.15 christos return error1; 650 1.27 dsl return sunos32_do_ioctl(SCARG(&bsd_ua, fd), TIOCSIG, &sig, l); 651 1.2 mrg } 652 1.2 mrg 653 1.2 mrg /* 654 1.2 mrg * Socket ioctl translations. 655 1.2 mrg */ 656 1.2 mrg #define IFREQ_IN(a) { \ 657 1.22 christos struct oifreq ifreq; \ 658 1.35 msaitoh error = copyin(SCARG_P32(uap, data), &ifreq, sizeof(ifreq)); \ 659 1.2 mrg if (error) \ 660 1.2 mrg return error; \ 661 1.27 dsl return sunos32_do_ioctl(SCARG(&bsd_ua, fd), a, &ifreq, l); \ 662 1.2 mrg } 663 1.2 mrg #define IFREQ_INOUT(a) { \ 664 1.22 christos struct oifreq ifreq; \ 665 1.35 msaitoh error = copyin(SCARG_P32(uap, data), &ifreq, sizeof(ifreq)); \ 666 1.2 mrg if (error) \ 667 1.2 mrg return error; \ 668 1.27 dsl if ((error = sunos32_do_ioctl(SCARG(&bsd_ua, fd), a, &ifreq, l)) != 0) \ 669 1.2 mrg return error; \ 670 1.35 msaitoh return copyout(&ifreq, SCARG_P32(uap, data), sizeof(ifreq)); \ 671 1.2 mrg } 672 1.2 mrg 673 1.22 christos case _IOW('i', 12, struct oifreq): 674 1.2 mrg /* SIOCSIFADDR */ 675 1.2 mrg break; 676 1.2 mrg 677 1.22 christos case _IOWR('i', 13, struct oifreq): 678 1.23 hannken IFREQ_INOUT(OOSIOCGIFADDR); 679 1.2 mrg 680 1.22 christos case _IOW('i', 14, struct oifreq): 681 1.2 mrg /* SIOCSIFDSTADDR */ 682 1.2 mrg break; 683 1.2 mrg 684 1.22 christos case _IOWR('i', 15, struct oifreq): 685 1.23 hannken IFREQ_INOUT(OOSIOCGIFDSTADDR); 686 1.2 mrg 687 1.22 christos case _IOW('i', 16, struct oifreq): 688 1.2 mrg /* SIOCSIFFLAGS */ 689 1.2 mrg break; 690 1.2 mrg 691 1.22 christos case _IOWR('i', 17, struct oifreq): 692 1.2 mrg /* SIOCGIFFLAGS */ 693 1.2 mrg break; 694 1.2 mrg 695 1.22 christos case _IOW('i', 21, struct oifreq): 696 1.2 mrg IFREQ_IN(SIOCSIFMTU); 697 1.2 mrg 698 1.22 christos case _IOWR('i', 22, struct oifreq): 699 1.2 mrg IFREQ_INOUT(SIOCGIFMTU); 700 1.2 mrg 701 1.22 christos case _IOWR('i', 23, struct oifreq): 702 1.2 mrg IFREQ_INOUT(SIOCGIFBRDADDR); 703 1.2 mrg 704 1.22 christos case _IOW('i', 24, struct oifreq): 705 1.2 mrg IFREQ_IN(SIOCSIFBRDADDR); 706 1.2 mrg 707 1.22 christos case _IOWR('i', 25, struct oifreq): 708 1.23 hannken IFREQ_INOUT(OOSIOCGIFNETMASK); 709 1.2 mrg 710 1.22 christos case _IOW('i', 26, struct oifreq): 711 1.2 mrg IFREQ_IN(SIOCSIFNETMASK); 712 1.2 mrg 713 1.22 christos case _IOWR('i', 27, struct oifreq): 714 1.2 mrg IFREQ_INOUT(SIOCGIFMETRIC); 715 1.2 mrg 716 1.22 christos case _IOWR('i', 28, struct oifreq): 717 1.2 mrg IFREQ_IN(SIOCSIFMETRIC); 718 1.2 mrg 719 1.2 mrg case _IOW('i', 30, struct arpreq): 720 1.2 mrg /* SIOCSARP */ 721 1.2 mrg break; 722 1.2 mrg 723 1.2 mrg case _IOWR('i', 31, struct arpreq): 724 1.2 mrg /* SIOCGARP */ 725 1.2 mrg break; 726 1.2 mrg 727 1.2 mrg case _IOW('i', 32, struct arpreq): 728 1.2 mrg /* SIOCDARP */ 729 1.2 mrg break; 730 1.2 mrg 731 1.22 christos case _IOW('i', 18, struct oifreq): /* SIOCSIFMEM */ 732 1.22 christos case _IOWR('i', 19, struct oifreq): /* SIOCGIFMEM */ 733 1.22 christos case _IOW('i', 40, struct oifreq): /* SIOCUPPER */ 734 1.22 christos case _IOW('i', 41, struct oifreq): /* SIOCLOWER */ 735 1.22 christos case _IOW('i', 44, struct oifreq): /* SIOCSETSYNC */ 736 1.22 christos case _IOWR('i', 45, struct oifreq): /* SIOCGETSYNC */ 737 1.22 christos case _IOWR('i', 46, struct oifreq): /* SIOCSDSTATS */ 738 1.22 christos case _IOWR('i', 47, struct oifreq): /* SIOCSESTATS */ 739 1.2 mrg case _IOW('i', 48, int): /* SIOCSPROMISC */ 740 1.22 christos case _IOW('i', 49, struct oifreq): /* SIOCADDMULTI */ 741 1.22 christos case _IOW('i', 50, struct oifreq): /* SIOCDELMULTI */ 742 1.2 mrg return EOPNOTSUPP; 743 1.2 mrg 744 1.22 christos case _IOWR('i', 20, struct oifconf): /* SIOCGIFCONF */ 745 1.2 mrg { 746 1.22 christos struct oifconf ifcf; 747 1.2 mrg 748 1.2 mrg /* 749 1.2 mrg * XXX: two more problems 750 1.35 msaitoh * 1. our sockaddr's are variable length, not always 751 1.35 msaitoh * sizeof(sockaddr) 752 1.35 msaitoh * 2. this returns a name per protocol, ie. it returns two 753 1.35 msaitoh * "lo0"'s 754 1.2 mrg */ 755 1.35 msaitoh error = copyin(SCARG_P32(uap, data), &ifcf, sizeof(ifcf)); 756 1.2 mrg if (error) 757 1.2 mrg return error; 758 1.35 msaitoh error = sunos32_do_ioctl(SCARG(&bsd_ua, fd), OOSIOCGIFCONF, 759 1.35 msaitoh &ifcf, l); 760 1.2 mrg if (error) 761 1.2 mrg return error; 762 1.35 msaitoh return copyout(&ifcf, SCARG_P32(uap, data), sizeof(ifcf)); 763 1.2 mrg } 764 1.2 mrg 765 1.2 mrg /* 766 1.2 mrg * Audio ioctl translations. 767 1.2 mrg */ 768 1.2 mrg case _IOR('A', 1, struct sunos_audio_info): /* AUDIO_GETINFO */ 769 1.2 mrg sunos_au_getinfo: 770 1.2 mrg { 771 1.2 mrg struct audio_info aui; 772 1.2 mrg struct sunos_audio_info sunos_aui; 773 1.2 mrg 774 1.27 dsl error = sunos32_do_ioctl(SCARG(&bsd_ua, fd), AUDIO_GETINFO, &aui, l); 775 1.2 mrg if (error) 776 1.2 mrg return error; 777 1.2 mrg 778 1.36 riastrad memset(&sunos_aui, 0, sizeof(sunos_aui)); 779 1.36 riastrad 780 1.2 mrg sunos_aui.play = *(struct sunos_audio_prinfo *)&aui.play; 781 1.2 mrg sunos_aui.record = *(struct sunos_audio_prinfo *)&aui.record; 782 1.2 mrg 783 1.2 mrg /* `avail_ports' is `seek' in BSD */ 784 1.2 mrg sunos_aui.play.avail_ports = AUDIO_SPEAKER | AUDIO_HEADPHONE; 785 1.2 mrg sunos_aui.record.avail_ports = AUDIO_SPEAKER | AUDIO_HEADPHONE; 786 1.2 mrg 787 1.2 mrg sunos_aui.play.waiting = 0; 788 1.2 mrg sunos_aui.record.waiting = 0; 789 1.2 mrg sunos_aui.play.eof = 0; 790 1.2 mrg sunos_aui.record.eof = 0; 791 1.2 mrg sunos_aui.monitor_gain = 0; /* aui.__spare; XXX */ 792 1.2 mrg /*XXXsunos_aui.output_muted = 0;*/ 793 1.2 mrg /*XXX*/sunos_aui.reserved[0] = 0; 794 1.2 mrg /*XXX*/sunos_aui.reserved[1] = 0; 795 1.2 mrg /*XXX*/sunos_aui.reserved[2] = 0; 796 1.2 mrg /*XXX*/sunos_aui.reserved[3] = 0; 797 1.2 mrg 798 1.20 dsl return copyout(&sunos_aui, SCARG_P32(uap, data), 799 1.35 msaitoh sizeof(sunos_aui)); 800 1.2 mrg } 801 1.2 mrg 802 1.2 mrg case _IOWR('A', 2, struct sunos_audio_info): /* AUDIO_SETINFO */ 803 1.2 mrg { 804 1.2 mrg struct audio_info aui; 805 1.2 mrg struct sunos_audio_info sunos_aui; 806 1.2 mrg 807 1.20 dsl error = copyin(SCARG_P32(uap, data), &sunos_aui, 808 1.35 msaitoh sizeof(sunos_aui)); 809 1.2 mrg if (error) 810 1.2 mrg return error; 811 1.2 mrg 812 1.2 mrg aui.play = *(struct audio_prinfo *)&sunos_aui.play; 813 1.2 mrg aui.record = *(struct audio_prinfo *)&sunos_aui.record; 814 1.2 mrg /* aui.__spare = sunos_aui.monitor_gain; */ 815 1.2 mrg aui.blocksize = ~0; 816 1.2 mrg aui.hiwat = ~0; 817 1.2 mrg aui.lowat = ~0; 818 1.2 mrg /* XXX somebody check this please. - is: aui.backlog = ~0; */ 819 1.2 mrg aui.mode = ~0; 820 1.2 mrg /* 821 1.2 mrg * The bsd driver does not distinguish between paused and 822 1.2 mrg * active. (In the sun driver, not active means samples are 823 1.9 wiz * not output at all, but paused means the last streams buffer 824 1.2 mrg * is drained and then output stops.) If either are 0, then 825 1.2 mrg * when stop output. Otherwise, if either are non-zero, 826 1.2 mrg * we resume. 827 1.2 mrg */ 828 1.2 mrg if (sunos_aui.play.pause == 0 || sunos_aui.play.active == 0) 829 1.2 mrg aui.play.pause = 0; 830 1.2 mrg else if (sunos_aui.play.pause != (u_char)~0 || 831 1.2 mrg sunos_aui.play.active != (u_char)~0) 832 1.2 mrg aui.play.pause = 1; 833 1.2 mrg if (sunos_aui.record.pause == 0 || sunos_aui.record.active == 0) 834 1.2 mrg aui.record.pause = 0; 835 1.2 mrg else if (sunos_aui.record.pause != (u_char)~0 || 836 1.2 mrg sunos_aui.record.active != (u_char)~0) 837 1.2 mrg aui.record.pause = 1; 838 1.2 mrg 839 1.35 msaitoh error = sunos32_do_ioctl(SCARG(&bsd_ua, fd), AUDIO_SETINFO, 840 1.35 msaitoh &aui, l); 841 1.2 mrg if (error) 842 1.2 mrg return error; 843 1.2 mrg /* Return new state */ 844 1.2 mrg goto sunos_au_getinfo; 845 1.2 mrg } 846 1.2 mrg case _IO('A', 3): /* AUDIO_DRAIN */ 847 1.35 msaitoh return sunos32_do_ioctl(SCARG(&bsd_ua, fd), AUDIO_DRAIN, NULL, 848 1.35 msaitoh l); 849 1.2 mrg case _IOR('A', 4, int): /* AUDIO_GETDEV */ 850 1.2 mrg { 851 1.2 mrg int devtype = SUNOS_AUDIO_DEV_AMD; 852 1.20 dsl return copyout(&devtype, SCARG_P32(uap, data), 853 1.35 msaitoh sizeof(devtype)); 854 1.2 mrg } 855 1.2 mrg 856 1.2 mrg /* 857 1.2 mrg * Selected streams ioctls. 858 1.2 mrg */ 859 1.2 mrg #define SUNOS_S_FLUSHR 1 860 1.2 mrg #define SUNOS_S_FLUSHW 2 861 1.2 mrg #define SUNOS_S_FLUSHRW 3 862 1.2 mrg 863 1.2 mrg #define SUNOS_S_INPUT 1 864 1.2 mrg #define SUNOS_S_HIPRI 2 865 1.2 mrg #define SUNOS_S_OUTPUT 4 866 1.2 mrg #define SUNOS_S_MSG 8 867 1.2 mrg 868 1.2 mrg case _IO('S', 5): /* I_FLUSH */ 869 1.2 mrg { 870 1.2 mrg int tmp = 0; 871 1.20 dsl switch ((intptr_t)SCARG_P32(uap, data)) { 872 1.34 mlelstv case SUNOS_S_FLUSHR: tmp = FREAD; break; 873 1.34 mlelstv case SUNOS_S_FLUSHW: tmp = FWRITE; break; 874 1.34 mlelstv case SUNOS_S_FLUSHRW: tmp = FREAD|FWRITE; break; 875 1.2 mrg } 876 1.27 dsl return sunos32_do_ioctl(SCARG(&bsd_ua, fd), TIOCFLUSH, &tmp, l); 877 1.2 mrg } 878 1.2 mrg case _IO('S', 9): /* I_SETSIG */ 879 1.2 mrg { 880 1.2 mrg int on = 1; 881 1.20 dsl if (((intptr_t)SCARG_P32(uap, data) & 882 1.35 msaitoh (SUNOS_S_HIPRI|SUNOS_S_INPUT)) == SUNOS_S_HIPRI) 883 1.2 mrg return EOPNOTSUPP; 884 1.27 dsl return sunos32_do_ioctl(SCARG(&bsd_ua, fd), FIOASYNC, &on, l); 885 1.2 mrg } 886 1.2 mrg /* 887 1.2 mrg * SunOS disk ioctls, taken from arch/sparc/sparc/disksubr.c 888 1.2 mrg * (which was from the old sparc/scsi/sun_disklabel.c), and 889 1.2 mrg * modified to suite. 890 1.2 mrg */ 891 1.32 christos case SUN_DKIOCGGEOM: 892 1.2 mrg { 893 1.2 mrg struct disklabel dl; 894 1.2 mrg 895 1.35 msaitoh error = sunos32_do_ioctl(SCARG(&bsd_ua, fd), DIOCGDINFO, 896 1.35 msaitoh &dl, l); 897 1.2 mrg if (error) 898 1.35 msaitoh return error; 899 1.2 mrg 900 1.20 dsl #define datageom ((struct sun_dkgeom *)SCARG_P32(uap, data)) 901 1.11 dsl /* XXX can't do memset() on a user address (dsl) */ 902 1.20 dsl memset(SCARG_P32(uap, data), 0, sizeof(*datageom)); 903 1.2 mrg 904 1.2 mrg datageom->sdkc_ncylinders = dl.d_ncylinders; 905 1.2 mrg datageom->sdkc_acylinders = dl.d_acylinders; 906 1.2 mrg datageom->sdkc_ntracks = dl.d_ntracks; 907 1.2 mrg datageom->sdkc_nsectors = dl.d_nsectors; 908 1.2 mrg datageom->sdkc_interleave = dl.d_interleave; 909 1.2 mrg datageom->sdkc_sparespercyl = dl.d_sparespercyl; 910 1.2 mrg datageom->sdkc_rpm = dl.d_rpm; 911 1.2 mrg datageom->sdkc_pcylinders = dl.d_ncylinders + dl.d_acylinders; 912 1.2 mrg #undef datageom 913 1.2 mrg break; 914 1.2 mrg } 915 1.2 mrg 916 1.32 christos case SUN_DKIOCINFO: 917 1.2 mrg /* Homey don't do DKIOCINFO */ 918 1.11 dsl /* XXX can't do memset() on a user address (dsl) */ 919 1.20 dsl memset(SCARG_P32(uap, data), 0, sizeof(struct sun_dkctlr)); 920 1.2 mrg break; 921 1.2 mrg 922 1.32 christos case SUN_DKIOCGPART: 923 1.2 mrg { 924 1.2 mrg struct partinfo pi; 925 1.33 christos struct disklabel label; 926 1.33 christos int fd = SCARG(&bsd_ua, fd); 927 1.2 mrg 928 1.33 christos error = sunos32_do_ioctl(fd, DIOCGPARTINFO, &pi, l); 929 1.2 mrg if (error) 930 1.33 christos return error; 931 1.33 christos error = sunos32_do_ioctl(fd, DIOCGDINFO, &label, l); 932 1.33 christos if (error) 933 1.33 christos return error; 934 1.2 mrg 935 1.33 christos if (label.d_secpercyl == 0) 936 1.33 christos return ERANGE; /* XXX */ 937 1.33 christos if (pi.pi_offset % label.d_secpercyl != 0) 938 1.33 christos return ERANGE; /* XXX */ 939 1.20 dsl /* XXX can't do direct writes to a user address (dsl) */ 940 1.20 dsl #define datapart ((struct sun_dkpart *)SCARG_P32(uap, data)) 941 1.33 christos datapart->sdkp_cyloffset = pi.pi_offset / label.d_secpercyl; 942 1.33 christos datapart->sdkp_nsectors = pi.pi_size; 943 1.2 mrg #undef datapart 944 1.2 mrg } 945 1.2 mrg 946 1.2 mrg } 947 1.35 msaitoh return netbsd32_ioctl(l, &bsd_ua, retval); 948 1.2 mrg } 949 1.2 mrg 950 1.2 mrg /* SunOS fcntl(2) cmds not implemented */ 951 1.2 mrg #define SUN_F_RGETLK 10 952 1.2 mrg #define SUN_F_RSETLK 11 953 1.2 mrg #define SUN_F_CNVT 12 954 1.2 mrg #define SUN_F_RSETLKW 13 955 1.2 mrg 956 1.2 mrg /* SunOS flock translation */ 957 1.2 mrg struct sunos_flock { 958 1.2 mrg short l_type; 959 1.2 mrg short l_whence; 960 1.3 mrg netbsd32_long l_start; 961 1.3 mrg netbsd32_long l_len; 962 1.2 mrg short l_pid; 963 1.2 mrg short l_xxx; 964 1.2 mrg }; 965 1.2 mrg 966 1.24 dsl static void bsd_to_sunos_flock(struct flock *, struct sunos_flock *); 967 1.24 dsl static void sunos_to_bsd_flock(struct sunos_flock *, struct flock *); 968 1.2 mrg 969 1.2 mrg #define SUNOS_F_RDLCK 1 970 1.2 mrg #define SUNOS_F_WRLCK 2 971 1.2 mrg #define SUNOS_F_UNLCK 3 972 1.2 mrg 973 1.2 mrg static void 974 1.25 dsl bsd_to_sunos_flock(struct flock *iflp, struct sunos_flock *oflp) 975 1.2 mrg { 976 1.36 riastrad 977 1.36 riastrad memset(oflp, 0, sizeof(*oflp)); 978 1.36 riastrad 979 1.2 mrg switch (iflp->l_type) { 980 1.2 mrg case F_RDLCK: 981 1.2 mrg oflp->l_type = SUNOS_F_RDLCK; 982 1.2 mrg break; 983 1.2 mrg case F_WRLCK: 984 1.2 mrg oflp->l_type = SUNOS_F_WRLCK; 985 1.2 mrg break; 986 1.2 mrg case F_UNLCK: 987 1.2 mrg oflp->l_type = SUNOS_F_UNLCK; 988 1.2 mrg break; 989 1.2 mrg default: 990 1.2 mrg oflp->l_type = -1; 991 1.2 mrg break; 992 1.2 mrg } 993 1.2 mrg 994 1.35 msaitoh oflp->l_whence = (short)iflp->l_whence; 995 1.35 msaitoh oflp->l_start = (netbsd32_long)iflp->l_start; 996 1.35 msaitoh oflp->l_len = (netbsd32_long)iflp->l_len; 997 1.35 msaitoh oflp->l_pid = (short)iflp->l_pid; 998 1.2 mrg oflp->l_xxx = 0; 999 1.2 mrg } 1000 1.2 mrg 1001 1.2 mrg 1002 1.2 mrg static void 1003 1.25 dsl sunos_to_bsd_flock(struct sunos_flock *iflp, struct flock *oflp) 1004 1.2 mrg { 1005 1.36 riastrad 1006 1.36 riastrad memset(oflp, 0, sizeof(*oflp)); 1007 1.36 riastrad 1008 1.2 mrg switch (iflp->l_type) { 1009 1.2 mrg case SUNOS_F_RDLCK: 1010 1.2 mrg oflp->l_type = F_RDLCK; 1011 1.2 mrg break; 1012 1.2 mrg case SUNOS_F_WRLCK: 1013 1.2 mrg oflp->l_type = F_WRLCK; 1014 1.2 mrg break; 1015 1.2 mrg case SUNOS_F_UNLCK: 1016 1.2 mrg oflp->l_type = F_UNLCK; 1017 1.2 mrg break; 1018 1.2 mrg default: 1019 1.2 mrg oflp->l_type = -1; 1020 1.2 mrg break; 1021 1.2 mrg } 1022 1.2 mrg 1023 1.2 mrg oflp->l_whence = iflp->l_whence; 1024 1.2 mrg oflp->l_start = (off_t) iflp->l_start; 1025 1.2 mrg oflp->l_len = (off_t) iflp->l_len; 1026 1.2 mrg oflp->l_pid = (pid_t) iflp->l_pid; 1027 1.2 mrg 1028 1.2 mrg } 1029 1.2 mrg static struct { 1030 1.3 mrg netbsd32_long sun_flg; 1031 1.3 mrg netbsd32_long bsd_flg; 1032 1.2 mrg } sunfcntl_flgtab[] = { 1033 1.2 mrg /* F_[GS]ETFLags that differ: */ 1034 1.2 mrg #define SUN_FSETBLK 0x0010 1035 1.2 mrg #define SUN_SHLOCK 0x0080 1036 1.2 mrg #define SUN_EXLOCK 0x0100 1037 1.2 mrg #define SUN_FNBIO 0x1000 1038 1.2 mrg #define SUN_FSYNC 0x2000 1039 1.2 mrg #define SUN_NONBLOCK 0x4000 1040 1.2 mrg #define SUN_FNOCTTY 0x8000 1041 1.2 mrg { SUN_NONBLOCK, O_NONBLOCK }, 1042 1.2 mrg { SUN_FNBIO, O_NONBLOCK }, 1043 1.2 mrg { SUN_SHLOCK, O_SHLOCK }, 1044 1.2 mrg { SUN_EXLOCK, O_EXLOCK }, 1045 1.2 mrg { SUN_FSYNC, O_FSYNC }, 1046 1.2 mrg { SUN_FSETBLK, 0 }, 1047 1.2 mrg { SUN_FNOCTTY, 0 } 1048 1.2 mrg }; 1049 1.2 mrg 1050 1.2 mrg int 1051 1.35 msaitoh sunos32_sys_fcntl(struct lwp *l, const struct sunos32_sys_fcntl_args *uap, 1052 1.35 msaitoh register_t *retval) 1053 1.2 mrg { 1054 1.26 dsl /* { 1055 1.3 mrg syscallarg(int) fd; 1056 1.3 mrg syscallarg(int) cmd; 1057 1.3 mrg syscallarg(netbsd32_voidp) arg; 1058 1.26 dsl } */ 1059 1.26 dsl struct sys_fcntl_args bsd_ua; 1060 1.20 dsl uintptr_t flg; 1061 1.2 mrg int n, ret; 1062 1.2 mrg 1063 1.26 dsl SCARG(&bsd_ua, fd) = SCARG(uap, fd); 1064 1.26 dsl SCARG(&bsd_ua, cmd) = SCARG(uap, cmd); 1065 1.26 dsl SCARG(&bsd_ua, arg) = SCARG_P32(uap, arg); 1066 1.26 dsl 1067 1.2 mrg switch (SCARG(uap, cmd)) { 1068 1.2 mrg case F_SETFL: 1069 1.20 dsl flg = (intptr_t)SCARG_P32(uap, arg); 1070 1.2 mrg n = sizeof(sunfcntl_flgtab) / sizeof(sunfcntl_flgtab[0]); 1071 1.2 mrg while (--n >= 0) { 1072 1.2 mrg if (flg & sunfcntl_flgtab[n].sun_flg) { 1073 1.2 mrg flg &= ~sunfcntl_flgtab[n].sun_flg; 1074 1.2 mrg flg |= sunfcntl_flgtab[n].bsd_flg; 1075 1.2 mrg } 1076 1.2 mrg } 1077 1.26 dsl SCARG(&bsd_ua, arg) = (void *)flg; 1078 1.2 mrg break; 1079 1.2 mrg 1080 1.2 mrg case F_GETLK: 1081 1.2 mrg case F_SETLK: 1082 1.2 mrg case F_SETLKW: 1083 1.2 mrg { 1084 1.2 mrg int error; 1085 1.21 dsl struct sunos_flock ifl; 1086 1.21 dsl struct flock fl; 1087 1.2 mrg 1088 1.20 dsl error = copyin(SCARG_P32(uap, arg), &ifl, sizeof ifl); 1089 1.2 mrg if (error) 1090 1.2 mrg return error; 1091 1.2 mrg sunos_to_bsd_flock(&ifl, &fl); 1092 1.2 mrg 1093 1.35 msaitoh error = do_fcntl_lock(SCARG(uap, fd), SCARG(uap, cmd), 1094 1.35 msaitoh &fl); 1095 1.21 dsl if (error || SCARG(uap, cmd) != F_GETLK) 1096 1.2 mrg return error; 1097 1.2 mrg 1098 1.2 mrg bsd_to_sunos_flock(&fl, &ifl); 1099 1.20 dsl return copyout(&ifl, SCARG_P32(uap, arg), sizeof ifl); 1100 1.2 mrg } 1101 1.2 mrg break; 1102 1.2 mrg case SUN_F_RGETLK: 1103 1.2 mrg case SUN_F_RSETLK: 1104 1.2 mrg case SUN_F_CNVT: 1105 1.2 mrg case SUN_F_RSETLKW: 1106 1.35 msaitoh return EOPNOTSUPP; 1107 1.2 mrg } 1108 1.2 mrg 1109 1.26 dsl ret = sys_fcntl(l, &bsd_ua, retval); 1110 1.26 dsl if (ret != 0) 1111 1.26 dsl return ret; 1112 1.2 mrg 1113 1.2 mrg switch (SCARG(uap, cmd)) { 1114 1.2 mrg case F_GETFL: 1115 1.2 mrg n = sizeof(sunfcntl_flgtab) / sizeof(sunfcntl_flgtab[0]); 1116 1.26 dsl ret = *retval; 1117 1.2 mrg while (--n >= 0) { 1118 1.2 mrg if (ret & sunfcntl_flgtab[n].bsd_flg) { 1119 1.2 mrg ret &= ~sunfcntl_flgtab[n].bsd_flg; 1120 1.2 mrg ret |= sunfcntl_flgtab[n].sun_flg; 1121 1.2 mrg } 1122 1.2 mrg } 1123 1.26 dsl *retval = ret; 1124 1.2 mrg break; 1125 1.2 mrg } 1126 1.1 mrg 1127 1.26 dsl return 0; 1128 1.2 mrg } 1129