Annotation of sys/compat/sunos/sunos_ioctl.c, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: sunos_ioctl.c,v 1.16 2004/09/19 21:34:43 mickey Exp $ */
! 2: /* $NetBSD: sunos_ioctl.c,v 1.23 1996/03/14 19:33:46 christos Exp $ */
! 3:
! 4: /*
! 5: * Copyright (c) 1993 Markus Wild.
! 6: * All rights reserved.
! 7: *
! 8: * Redistribution and use in source and binary forms, with or without
! 9: * modification, are permitted provided that the following conditions
! 10: * are met:
! 11: * 1. Redistributions of source code must retain the above copyright
! 12: * notice, this list of conditions and the following disclaimer.
! 13: * 2. The name of the author may not be used to endorse or promote products
! 14: * derived from this software without specific prior written permission
! 15: *
! 16: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
! 17: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
! 18: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
! 19: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
! 20: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
! 21: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
! 22: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
! 23: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
! 24: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
! 25: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
! 26: *
! 27: * loosely from: Header: sunos_ioctl.c,v 1.7 93/05/28 04:40:43 torek Exp
! 28: */
! 29:
! 30: #include <sys/param.h>
! 31: #include <sys/proc.h>
! 32: #include <sys/systm.h>
! 33: #include <sys/file.h>
! 34: #include <sys/filedesc.h>
! 35: #include <sys/ioctl.h>
! 36: #include <sys/termios.h>
! 37: #include <sys/tty.h>
! 38: #include <sys/socket.h>
! 39: #include <sys/audioio.h>
! 40: #include <sys/vnode.h>
! 41: #include <net/if.h>
! 42:
! 43: #include <sys/mount.h>
! 44:
! 45: #include <miscfs/specfs/specdev.h>
! 46:
! 47: #include <sys/syscallargs.h>
! 48: #include <compat/sunos/sunos.h>
! 49: #include <compat/sunos/sunos_syscallargs.h>
! 50: #include <compat/sunos/sunos_util.h>
! 51:
! 52: /*
! 53: * SunOS ioctl calls.
! 54: * This file is something of a hodge-podge.
! 55: * Support gets added as things turn up....
! 56: */
! 57:
! 58: static const struct speedtab sptab[] = {
! 59: { 0, 0 },
! 60: { 50, 1 },
! 61: { 75, 2 },
! 62: { 110, 3 },
! 63: { 134, 4 },
! 64: { 135, 4 },
! 65: { 150, 5 },
! 66: { 200, 6 },
! 67: { 300, 7 },
! 68: { 600, 8 },
! 69: { 1200, 9 },
! 70: { 1800, 10 },
! 71: { 2400, 11 },
! 72: { 4800, 12 },
! 73: { 9600, 13 },
! 74: { 19200, 14 },
! 75: { 38400, 15 },
! 76: { -1, -1 }
! 77: };
! 78:
! 79: static const u_long s2btab[] = {
! 80: 0,
! 81: 50,
! 82: 75,
! 83: 110,
! 84: 134,
! 85: 150,
! 86: 200,
! 87: 300,
! 88: 600,
! 89: 1200,
! 90: 1800,
! 91: 2400,
! 92: 4800,
! 93: 9600,
! 94: 19200,
! 95: 38400,
! 96: };
! 97:
! 98: static void stios2btios(struct sunos_termios *, struct termios *);
! 99: static void btios2stios(struct termios *, struct sunos_termios *);
! 100: static void stios2stio(struct sunos_termios *, struct sunos_termio *);
! 101: static void stio2stios(struct sunos_termio *, struct sunos_termios *);
! 102:
! 103: /*
! 104: * These two conversion functions have mostly been done
! 105: * with some perl cut&paste, then hand-edited to comment
! 106: * out what doesn't exist under NetBSD.
! 107: * A note from Markus's code:
! 108: * (l & BITMASK1) / BITMASK1 * BITMASK2 is translated
! 109: * optimally by gcc m68k, much better than any ?: stuff.
! 110: * Code may vary with different architectures of course.
! 111: *
! 112: * I don't know what optimizer you used, but seeing divu's and
! 113: * bfextu's in the m68k assembly output did not encourage me...
! 114: * as well, gcc on the sparc definitely generates much better
! 115: * code with `?:'.
! 116: */
! 117:
! 118: static void
! 119: stios2btios(st, bt)
! 120: struct sunos_termios *st;
! 121: struct termios *bt;
! 122: {
! 123: register u_long l, r;
! 124:
! 125: l = st->c_iflag;
! 126: r = ((l & 0x00000001) ? IGNBRK : 0);
! 127: r |= ((l & 0x00000002) ? BRKINT : 0);
! 128: r |= ((l & 0x00000004) ? IGNPAR : 0);
! 129: r |= ((l & 0x00000008) ? PARMRK : 0);
! 130: r |= ((l & 0x00000010) ? INPCK : 0);
! 131: r |= ((l & 0x00000020) ? ISTRIP : 0);
! 132: r |= ((l & 0x00000040) ? INLCR : 0);
! 133: r |= ((l & 0x00000080) ? IGNCR : 0);
! 134: r |= ((l & 0x00000100) ? ICRNL : 0);
! 135: /* ((l & 0x00000200) ? IUCLC : 0) */
! 136: r |= ((l & 0x00000400) ? IXON : 0);
! 137: r |= ((l & 0x00000800) ? IXANY : 0);
! 138: r |= ((l & 0x00001000) ? IXOFF : 0);
! 139: r |= ((l & 0x00002000) ? IMAXBEL : 0);
! 140: bt->c_iflag = r;
! 141:
! 142: l = st->c_oflag;
! 143: r = ((l & 0x00000001) ? OPOST : 0);
! 144: /* ((l & 0x00000002) ? OLCUC : 0) */
! 145: r |= ((l & 0x00000004) ? ONLCR : 0);
! 146: /* ((l & 0x00000008) ? OCRNL : 0) */
! 147: /* ((l & 0x00000010) ? ONOCR : 0) */
! 148: /* ((l & 0x00000020) ? ONLRET : 0) */
! 149: /* ((l & 0x00000040) ? OFILL : 0) */
! 150: /* ((l & 0x00000080) ? OFDEL : 0) */
! 151: /* ((l & 0x00000100) ? NLDLY : 0) */
! 152: /* ((l & 0x00000100) ? NL1 : 0) */
! 153: /* ((l & 0x00000600) ? CRDLY : 0) */
! 154: /* ((l & 0x00000200) ? CR1 : 0) */
! 155: /* ((l & 0x00000400) ? CR2 : 0) */
! 156: /* ((l & 0x00000600) ? CR3 : 0) */
! 157: /* ((l & 0x00001800) ? TABDLY : 0) */
! 158: /* ((l & 0x00000800) ? TAB1 : 0) */
! 159: /* ((l & 0x00001000) ? TAB2 : 0) */
! 160: r |= ((l & 0x00001800) ? OXTABS : 0);
! 161: /* ((l & 0x00002000) ? BSDLY : 0) */
! 162: /* ((l & 0x00002000) ? BS1 : 0) */
! 163: /* ((l & 0x00004000) ? VTDLY : 0) */
! 164: /* ((l & 0x00004000) ? VT1 : 0) */
! 165: /* ((l & 0x00008000) ? FFDLY : 0) */
! 166: /* ((l & 0x00008000) ? FF1 : 0) */
! 167: /* ((l & 0x00010000) ? PAGEOUT : 0) */
! 168: /* ((l & 0x00020000) ? WRAP : 0) */
! 169: bt->c_oflag = r;
! 170:
! 171: l = st->c_cflag;
! 172: switch (l & 0x00000030) {
! 173: case 0:
! 174: r = CS5;
! 175: break;
! 176: case 0x00000010:
! 177: r = CS6;
! 178: break;
! 179: case 0x00000020:
! 180: r = CS7;
! 181: break;
! 182: case 0x00000030:
! 183: r = CS8;
! 184: break;
! 185: }
! 186: r |= ((l & 0x00000040) ? CSTOPB : 0);
! 187: r |= ((l & 0x00000080) ? CREAD : 0);
! 188: r |= ((l & 0x00000100) ? PARENB : 0);
! 189: r |= ((l & 0x00000200) ? PARODD : 0);
! 190: r |= ((l & 0x00000400) ? HUPCL : 0);
! 191: r |= ((l & 0x00000800) ? CLOCAL : 0);
! 192: /* ((l & 0x00001000) ? LOBLK : 0) */
! 193: r |= ((l & 0x80000000) ? (CRTS_IFLOW|CCTS_OFLOW) : 0);
! 194: bt->c_cflag = r;
! 195:
! 196: bt->c_ispeed = bt->c_ospeed = s2btab[l & 0x0000000f];
! 197:
! 198: l = st->c_lflag;
! 199: r = ((l & 0x00000001) ? ISIG : 0);
! 200: r |= ((l & 0x00000002) ? ICANON : 0);
! 201: /* ((l & 0x00000004) ? XCASE : 0) */
! 202: r |= ((l & 0x00000008) ? ECHO : 0);
! 203: r |= ((l & 0x00000010) ? ECHOE : 0);
! 204: r |= ((l & 0x00000020) ? ECHOK : 0);
! 205: r |= ((l & 0x00000040) ? ECHONL : 0);
! 206: r |= ((l & 0x00000080) ? NOFLSH : 0);
! 207: r |= ((l & 0x00000100) ? TOSTOP : 0);
! 208: r |= ((l & 0x00000200) ? ECHOCTL : 0);
! 209: r |= ((l & 0x00000400) ? ECHOPRT : 0);
! 210: r |= ((l & 0x00000800) ? ECHOKE : 0);
! 211: /* ((l & 0x00001000) ? DEFECHO : 0) */
! 212: r |= ((l & 0x00002000) ? FLUSHO : 0);
! 213: r |= ((l & 0x00004000) ? PENDIN : 0);
! 214: bt->c_lflag = r;
! 215:
! 216: bt->c_cc[VINTR] = st->c_cc[0] ? st->c_cc[0] : _POSIX_VDISABLE;
! 217: bt->c_cc[VQUIT] = st->c_cc[1] ? st->c_cc[1] : _POSIX_VDISABLE;
! 218: bt->c_cc[VERASE] = st->c_cc[2] ? st->c_cc[2] : _POSIX_VDISABLE;
! 219: bt->c_cc[VKILL] = st->c_cc[3] ? st->c_cc[3] : _POSIX_VDISABLE;
! 220: bt->c_cc[VEOF] = st->c_cc[4] ? st->c_cc[4] : _POSIX_VDISABLE;
! 221: bt->c_cc[VEOL] = st->c_cc[5] ? st->c_cc[5] : _POSIX_VDISABLE;
! 222: bt->c_cc[VEOL2] = st->c_cc[6] ? st->c_cc[6] : _POSIX_VDISABLE;
! 223: /* bt->c_cc[VSWTCH] = st->c_cc[7] ? st->c_cc[7] : _POSIX_VDISABLE; */
! 224: bt->c_cc[VSTART] = st->c_cc[8] ? st->c_cc[8] : _POSIX_VDISABLE;
! 225: bt->c_cc[VSTOP] = st->c_cc[9] ? st->c_cc[9] : _POSIX_VDISABLE;
! 226: bt->c_cc[VSUSP] = st->c_cc[10] ? st->c_cc[10] : _POSIX_VDISABLE;
! 227: bt->c_cc[VDSUSP] = st->c_cc[11] ? st->c_cc[11] : _POSIX_VDISABLE;
! 228: bt->c_cc[VREPRINT] = st->c_cc[12] ? st->c_cc[12] : _POSIX_VDISABLE;
! 229: bt->c_cc[VDISCARD] = st->c_cc[13] ? st->c_cc[13] : _POSIX_VDISABLE;
! 230: bt->c_cc[VWERASE] = st->c_cc[14] ? st->c_cc[14] : _POSIX_VDISABLE;
! 231: bt->c_cc[VLNEXT] = st->c_cc[15] ? st->c_cc[15] : _POSIX_VDISABLE;
! 232: bt->c_cc[VSTATUS] = st->c_cc[16] ? st->c_cc[16] : _POSIX_VDISABLE;
! 233:
! 234: /* if `raw mode', create native VMIN/VTIME from SunOS VEOF/VEOL */
! 235: bt->c_cc[VMIN] = (bt->c_lflag & ICANON) ? 1 : bt->c_cc[VEOF];
! 236: bt->c_cc[VTIME] = (bt->c_lflag & ICANON) ? 1 : bt->c_cc[VEOL];
! 237: }
! 238:
! 239:
! 240: static void
! 241: btios2stios(bt, st)
! 242: struct termios *bt;
! 243: struct sunos_termios *st;
! 244: {
! 245: register u_long l, r;
! 246: int s;
! 247:
! 248: l = bt->c_iflag;
! 249: r = ((l & IGNBRK) ? 0x00000001 : 0);
! 250: r |= ((l & BRKINT) ? 0x00000002 : 0);
! 251: r |= ((l & IGNPAR) ? 0x00000004 : 0);
! 252: r |= ((l & PARMRK) ? 0x00000008 : 0);
! 253: r |= ((l & INPCK) ? 0x00000010 : 0);
! 254: r |= ((l & ISTRIP) ? 0x00000020 : 0);
! 255: r |= ((l & INLCR) ? 0x00000040 : 0);
! 256: r |= ((l & IGNCR) ? 0x00000080 : 0);
! 257: r |= ((l & ICRNL) ? 0x00000100 : 0);
! 258: /* ((l & IUCLC) ? 0x00000200 : 0) */
! 259: r |= ((l & IXON) ? 0x00000400 : 0);
! 260: r |= ((l & IXANY) ? 0x00000800 : 0);
! 261: r |= ((l & IXOFF) ? 0x00001000 : 0);
! 262: r |= ((l & IMAXBEL) ? 0x00002000 : 0);
! 263: st->c_iflag = r;
! 264:
! 265: l = bt->c_oflag;
! 266: r = ((l & OPOST) ? 0x00000001 : 0);
! 267: /* ((l & OLCUC) ? 0x00000002 : 0) */
! 268: r |= ((l & ONLCR) ? 0x00000004 : 0);
! 269: /* ((l & OCRNL) ? 0x00000008 : 0) */
! 270: /* ((l & ONOCR) ? 0x00000010 : 0) */
! 271: /* ((l & ONLRET) ? 0x00000020 : 0) */
! 272: /* ((l & OFILL) ? 0x00000040 : 0) */
! 273: /* ((l & OFDEL) ? 0x00000080 : 0) */
! 274: /* ((l & NLDLY) ? 0x00000100 : 0) */
! 275: /* ((l & NL1) ? 0x00000100 : 0) */
! 276: /* ((l & CRDLY) ? 0x00000600 : 0) */
! 277: /* ((l & CR1) ? 0x00000200 : 0) */
! 278: /* ((l & CR2) ? 0x00000400 : 0) */
! 279: /* ((l & CR3) ? 0x00000600 : 0) */
! 280: /* ((l & TABDLY) ? 0x00001800 : 0) */
! 281: /* ((l & TAB1) ? 0x00000800 : 0) */
! 282: /* ((l & TAB2) ? 0x00001000 : 0) */
! 283: r |= ((l & OXTABS) ? 0x00001800 : 0);
! 284: /* ((l & BSDLY) ? 0x00002000 : 0) */
! 285: /* ((l & BS1) ? 0x00002000 : 0) */
! 286: /* ((l & VTDLY) ? 0x00004000 : 0) */
! 287: /* ((l & VT1) ? 0x00004000 : 0) */
! 288: /* ((l & FFDLY) ? 0x00008000 : 0) */
! 289: /* ((l & FF1) ? 0x00008000 : 0) */
! 290: /* ((l & PAGEOUT) ? 0x00010000 : 0) */
! 291: /* ((l & WRAP) ? 0x00020000 : 0) */
! 292: st->c_oflag = r;
! 293:
! 294: l = bt->c_cflag;
! 295: switch (l & CSIZE) {
! 296: case CS5:
! 297: r = 0;
! 298: break;
! 299: case CS6:
! 300: r = 0x00000010;
! 301: break;
! 302: case CS7:
! 303: r = 0x00000020;
! 304: break;
! 305: case CS8:
! 306: r = 0x00000030;
! 307: break;
! 308: }
! 309: r |= ((l & CSTOPB) ? 0x00000040 : 0);
! 310: r |= ((l & CREAD) ? 0x00000080 : 0);
! 311: r |= ((l & PARENB) ? 0x00000100 : 0);
! 312: r |= ((l & PARODD) ? 0x00000200 : 0);
! 313: r |= ((l & HUPCL) ? 0x00000400 : 0);
! 314: r |= ((l & CLOCAL) ? 0x00000800 : 0);
! 315: /* ((l & LOBLK) ? 0x00001000 : 0) */
! 316: r |= ((l & (CRTS_IFLOW|CCTS_OFLOW)) ? 0x80000000 : 0);
! 317: st->c_cflag = r;
! 318:
! 319: l = bt->c_lflag;
! 320: r = ((l & ISIG) ? 0x00000001 : 0);
! 321: r |= ((l & ICANON) ? 0x00000002 : 0);
! 322: /* ((l & XCASE) ? 0x00000004 : 0) */
! 323: r |= ((l & ECHO) ? 0x00000008 : 0);
! 324: r |= ((l & ECHOE) ? 0x00000010 : 0);
! 325: r |= ((l & ECHOK) ? 0x00000020 : 0);
! 326: r |= ((l & ECHONL) ? 0x00000040 : 0);
! 327: r |= ((l & NOFLSH) ? 0x00000080 : 0);
! 328: r |= ((l & TOSTOP) ? 0x00000100 : 0);
! 329: r |= ((l & ECHOCTL) ? 0x00000200 : 0);
! 330: r |= ((l & ECHOPRT) ? 0x00000400 : 0);
! 331: r |= ((l & ECHOKE) ? 0x00000800 : 0);
! 332: /* ((l & DEFECHO) ? 0x00001000 : 0) */
! 333: r |= ((l & FLUSHO) ? 0x00002000 : 0);
! 334: r |= ((l & PENDIN) ? 0x00004000 : 0);
! 335: st->c_lflag = r;
! 336:
! 337: s = ttspeedtab(bt->c_ospeed, sptab);
! 338: if (s >= 0)
! 339: st->c_cflag |= s;
! 340:
! 341: st->c_cc[0] = bt->c_cc[VINTR] != _POSIX_VDISABLE? bt->c_cc[VINTR]:0;
! 342: st->c_cc[1] = bt->c_cc[VQUIT] != _POSIX_VDISABLE? bt->c_cc[VQUIT]:0;
! 343: st->c_cc[2] = bt->c_cc[VERASE] != _POSIX_VDISABLE? bt->c_cc[VERASE]:0;
! 344: st->c_cc[3] = bt->c_cc[VKILL] != _POSIX_VDISABLE? bt->c_cc[VKILL]:0;
! 345: st->c_cc[4] = bt->c_cc[VEOF] != _POSIX_VDISABLE? bt->c_cc[VEOF]:0;
! 346: st->c_cc[5] = bt->c_cc[VEOL] != _POSIX_VDISABLE? bt->c_cc[VEOL]:0;
! 347: st->c_cc[6] = bt->c_cc[VEOL2] != _POSIX_VDISABLE? bt->c_cc[VEOL2]:0;
! 348: st->c_cc[7] = 0;
! 349: /* bt->c_cc[VSWTCH] != _POSIX_VDISABLE? bt->c_cc[VSWTCH]: */
! 350: st->c_cc[8] = bt->c_cc[VSTART] != _POSIX_VDISABLE? bt->c_cc[VSTART]:0;
! 351: st->c_cc[9] = bt->c_cc[VSTOP] != _POSIX_VDISABLE? bt->c_cc[VSTOP]:0;
! 352: st->c_cc[10]= bt->c_cc[VSUSP] != _POSIX_VDISABLE? bt->c_cc[VSUSP]:0;
! 353: st->c_cc[11]= bt->c_cc[VDSUSP] != _POSIX_VDISABLE? bt->c_cc[VDSUSP]:0;
! 354: st->c_cc[12]= bt->c_cc[VREPRINT]!= _POSIX_VDISABLE? bt->c_cc[VREPRINT]:0;
! 355: st->c_cc[13]= bt->c_cc[VDISCARD]!= _POSIX_VDISABLE? bt->c_cc[VDISCARD]:0;
! 356: st->c_cc[14]= bt->c_cc[VWERASE] != _POSIX_VDISABLE? bt->c_cc[VWERASE]:0;
! 357: st->c_cc[15]= bt->c_cc[VLNEXT] != _POSIX_VDISABLE? bt->c_cc[VLNEXT]:0;
! 358: st->c_cc[16]= bt->c_cc[VSTATUS] != _POSIX_VDISABLE? bt->c_cc[VSTATUS]:0;
! 359:
! 360: if (!(bt->c_lflag & ICANON)) {
! 361: /* SunOS stores VMIN/VTIME in VEOF/VEOL (if ICANON is off) */
! 362: st->c_cc[4] = bt->c_cc[VMIN];
! 363: st->c_cc[5] = bt->c_cc[VTIME];
! 364: }
! 365:
! 366: st->c_line = 0;
! 367: }
! 368:
! 369: static void
! 370: stios2stio(ts, t)
! 371: struct sunos_termios *ts;
! 372: struct sunos_termio *t;
! 373: {
! 374: t->c_iflag = ts->c_iflag;
! 375: t->c_oflag = ts->c_oflag;
! 376: t->c_cflag = ts->c_cflag;
! 377: t->c_lflag = ts->c_lflag;
! 378: t->c_line = ts->c_line;
! 379: bcopy(ts->c_cc, t->c_cc, 8);
! 380: }
! 381:
! 382: static void
! 383: stio2stios(t, ts)
! 384: struct sunos_termio *t;
! 385: struct sunos_termios *ts;
! 386: {
! 387: ts->c_iflag = t->c_iflag;
! 388: ts->c_oflag = t->c_oflag;
! 389: ts->c_cflag = t->c_cflag;
! 390: ts->c_lflag = t->c_lflag;
! 391: ts->c_line = t->c_line;
! 392: bcopy(t->c_cc, ts->c_cc, 8); /* don't touch the upper fields! */
! 393: }
! 394:
! 395: int
! 396: sunos_sys_ioctl(p, v, retval)
! 397: register struct proc *p;
! 398: void *v;
! 399: register_t *retval;
! 400: {
! 401: struct sunos_sys_ioctl_args *uap = v;
! 402: struct filedesc *fdp = p->p_fd;
! 403: struct file *fp;
! 404: int (*ctl)(struct file *, u_long, caddr_t, struct proc *);
! 405: int error;
! 406:
! 407: if ((fp = fd_getfile(fdp, SCARG(uap, fd))) == NULL)
! 408: return EBADF;
! 409: FREF(fp);
! 410:
! 411: if ((fp->f_flag & (FREAD|FWRITE)) == 0) {
! 412: error = EBADF;
! 413: goto out;
! 414: }
! 415:
! 416: ctl = fp->f_ops->fo_ioctl;
! 417:
! 418: switch (SCARG(uap, com)) {
! 419: case _IOR('t', 0, int):
! 420: SCARG(uap, com) = TIOCGETD;
! 421: break;
! 422: case _IOW('t', 1, int):
! 423: {
! 424: int disc;
! 425:
! 426: if ((error = copyin(SCARG(uap, data), (caddr_t)&disc,
! 427: sizeof disc)) != 0)
! 428: goto out;
! 429:
! 430: /* map SunOS NTTYDISC into our termios discipline */
! 431: if (disc == 2)
! 432: disc = 0;
! 433: /* all other disciplines are not supported by NetBSD */
! 434: if (disc) {
! 435: error = ENXIO;
! 436: goto out;
! 437: }
! 438:
! 439: error = (*ctl)(fp, TIOCSETD, (caddr_t)&disc, p);
! 440: goto out;
! 441: }
! 442: case _IOW('t', 101, int): /* sun SUNOS_TIOCSSOFTCAR */
! 443: {
! 444: int x; /* unused */
! 445:
! 446: error = copyin((caddr_t)&x, SCARG(uap, data), sizeof x);
! 447: goto out;
! 448: }
! 449: case _IOR('t', 100, int): /* sun SUNOS_TIOCGSOFTCAR */
! 450: {
! 451: int x = 0;
! 452:
! 453: error = copyout((caddr_t)&x, SCARG(uap, data), sizeof x);
! 454: goto out;
! 455: }
! 456: case _IO('t', 36): /* sun TIOCCONS, no parameters */
! 457: {
! 458: int on = 1;
! 459: error = (*ctl)(fp, TIOCCONS, (caddr_t)&on, p);
! 460: goto out;
! 461: }
! 462: case _IOW('t', 37, struct sunos_ttysize):
! 463: {
! 464: struct winsize ws;
! 465: struct sunos_ttysize ss;
! 466:
! 467: if ((error = (*ctl)(fp, TIOCGWINSZ, (caddr_t)&ws, p)) != 0)
! 468: goto out;
! 469:
! 470: if ((error = copyin (SCARG(uap, data), &ss, sizeof (ss))) != 0)
! 471: goto out;
! 472:
! 473: ws.ws_row = ss.ts_row;
! 474: ws.ws_col = ss.ts_col;
! 475:
! 476: error = ((*ctl)(fp, TIOCSWINSZ, (caddr_t)&ws, p));
! 477: goto out;
! 478: }
! 479: case _IOW('t', 38, struct sunos_ttysize):
! 480: {
! 481: struct winsize ws;
! 482: struct sunos_ttysize ss;
! 483:
! 484: if ((error = (*ctl)(fp, TIOCGWINSZ, (caddr_t)&ws, p)) != 0)
! 485: goto out;
! 486:
! 487: ss.ts_row = ws.ws_row;
! 488: ss.ts_col = ws.ws_col;
! 489:
! 490: error = copyout ((caddr_t)&ss, SCARG(uap, data), sizeof (ss));
! 491: goto out;
! 492: }
! 493: case _IOW('t', 130, int): /* TIOCSETPGRP: posix variant */
! 494: SCARG(uap, com) = TIOCSPGRP;
! 495: break;
! 496: case _IOR('t', 131, int): /* TIOCGETPGRP: posix variant */
! 497: {
! 498: /*
! 499: * sigh, must do error translation on pty devices
! 500: * (see also kern/tty_pty.c)
! 501: */
! 502: int pgrp;
! 503: struct vnode *vp;
! 504: error = (*ctl)(fp, TIOCGPGRP, (caddr_t)&pgrp, p);
! 505: if (error) {
! 506: vp = (struct vnode *)fp->f_data;
! 507: if (error == EIO && vp != NULL &&
! 508: vp->v_type == VCHR && major(vp->v_rdev) == 21)
! 509: error = ENOTTY;
! 510: goto out;
! 511: }
! 512: error = copyout((caddr_t)&pgrp, SCARG(uap, data), sizeof(pgrp));
! 513: goto out;
! 514: }
! 515: case _IO('t', 132):
! 516: SCARG(uap, com) = TIOCSCTTY;
! 517: break;
! 518: case SUNOS_TCFLSH:
! 519: /* XXX: fixme */
! 520: error = 0;
! 521: goto out;
! 522: case SUNOS_TCGETA:
! 523: case SUNOS_TCGETS:
! 524: {
! 525: struct termios bts;
! 526: struct sunos_termios sts;
! 527: struct sunos_termio st;
! 528:
! 529: if ((error = (*ctl)(fp, TIOCGETA, (caddr_t)&bts, p)) != 0)
! 530: goto out;
! 531:
! 532: btios2stios (&bts, &sts);
! 533: if (SCARG(uap, com) == SUNOS_TCGETA) {
! 534: stios2stio (&sts, &st);
! 535: error = copyout((caddr_t)&st, SCARG(uap, data),
! 536: sizeof (st));
! 537: goto out;
! 538: } else {
! 539: error = copyout((caddr_t)&sts, SCARG(uap, data),
! 540: sizeof (sts));
! 541: goto out;
! 542: }
! 543: /*NOTREACHED*/
! 544: }
! 545: case SUNOS_TCSETA:
! 546: case SUNOS_TCSETAW:
! 547: case SUNOS_TCSETAF:
! 548: {
! 549: struct termios bts;
! 550: struct sunos_termios sts;
! 551: struct sunos_termio st;
! 552:
! 553: if ((error = copyin(SCARG(uap, data), (caddr_t)&st,
! 554: sizeof (st))) != 0)
! 555: goto out;
! 556:
! 557: /* get full BSD termios so we don't lose information */
! 558: if ((error = (*ctl)(fp, TIOCGETA, (caddr_t)&bts, p)) != 0)
! 559: goto out;
! 560:
! 561: /*
! 562: * convert to sun termios, copy in information from
! 563: * termio, and convert back, then set new values.
! 564: */
! 565: btios2stios(&bts, &sts);
! 566: stio2stios(&st, &sts);
! 567: stios2btios(&sts, &bts);
! 568:
! 569: error = (*ctl)(fp, SCARG(uap, com) - SUNOS_TCSETA + TIOCSETA,
! 570: (caddr_t)&bts, p);
! 571: goto out;
! 572: }
! 573: case SUNOS_TCSETS:
! 574: case SUNOS_TCSETSW:
! 575: case SUNOS_TCSETSF:
! 576: {
! 577: struct termios bts;
! 578: struct sunos_termios sts;
! 579:
! 580: if ((error = copyin (SCARG(uap, data), (caddr_t)&sts,
! 581: sizeof (sts))) != 0)
! 582: goto out;
! 583: stios2btios (&sts, &bts);
! 584: error = (*ctl)(fp, SCARG(uap, com) - SUNOS_TCSETS + TIOCSETA,
! 585: (caddr_t)&bts, p);
! 586: goto out;
! 587: }
! 588: /*
! 589: * Pseudo-tty ioctl translations.
! 590: */
! 591: case _IOW('t', 32, int): { /* TIOCTCNTL */
! 592: int error, on;
! 593:
! 594: error = copyin (SCARG(uap, data), (caddr_t)&on, sizeof (on));
! 595: if (error)
! 596: goto out;
! 597: error = (*ctl)(fp, TIOCUCNTL, (caddr_t)&on, p);
! 598: goto out;
! 599: }
! 600: case _IOW('t', 33, int): { /* TIOCSIGNAL */
! 601: int error, sig;
! 602:
! 603: error = copyin (SCARG(uap, data), (caddr_t)&sig, sizeof (sig));
! 604: if (error)
! 605: goto out;
! 606: error = (*ctl)(fp, TIOCSIG, (caddr_t)&sig, p);
! 607: goto out;
! 608: }
! 609:
! 610: /*
! 611: * Socket ioctl translations.
! 612: */
! 613: #define IFREQ_IN(a) { \
! 614: struct ifreq ifreq; \
! 615: error = copyin (SCARG(uap, data), (caddr_t)&ifreq, sizeof (ifreq)); \
! 616: if (error) \
! 617: goto out; \
! 618: error = (*ctl)(fp, a, (caddr_t)&ifreq, p); \
! 619: goto out; \
! 620: }
! 621: #define IFREQ_INOUT(a) { \
! 622: struct ifreq ifreq; \
! 623: error = copyin (SCARG(uap, data), (caddr_t)&ifreq, sizeof (ifreq)); \
! 624: if (error) \
! 625: goto out; \
! 626: if ((error = (*ctl)(fp, a, (caddr_t)&ifreq, p)) != 0) \
! 627: goto out; \
! 628: error = copyout ((caddr_t)&ifreq, SCARG(uap, data), sizeof (ifreq)); \
! 629: goto out; \
! 630: }
! 631:
! 632: case _IOW('i', 12, struct ifreq):
! 633: /* SIOCSIFADDR */
! 634: break;
! 635:
! 636: case _IOWR('i', 13, struct ifreq):
! 637: IFREQ_INOUT(OSIOCGIFADDR);
! 638:
! 639: case _IOW('i', 14, struct ifreq):
! 640: /* SIOCSIFDSTADDR */
! 641: break;
! 642:
! 643: case _IOWR('i', 15, struct ifreq):
! 644: IFREQ_INOUT(OSIOCGIFDSTADDR);
! 645:
! 646: case _IOW('i', 16, struct ifreq):
! 647: /* SIOCSIFFLAGS */
! 648: break;
! 649:
! 650: case _IOWR('i', 17, struct ifreq):
! 651: /* SIOCGIFFLAGS */
! 652: break;
! 653:
! 654: case _IOW('i', 21, struct ifreq):
! 655: IFREQ_IN(SIOCSIFMTU);
! 656:
! 657: case _IOWR('i', 22, struct ifreq):
! 658: IFREQ_INOUT(SIOCGIFMTU);
! 659:
! 660: case _IOWR('i', 23, struct ifreq):
! 661: IFREQ_INOUT(SIOCGIFBRDADDR);
! 662:
! 663: case _IOW('i', 24, struct ifreq):
! 664: IFREQ_IN(SIOCSIFBRDADDR);
! 665:
! 666: case _IOWR('i', 25, struct ifreq):
! 667: IFREQ_INOUT(OSIOCGIFNETMASK);
! 668:
! 669: case _IOW('i', 26, struct ifreq):
! 670: IFREQ_IN(SIOCSIFNETMASK);
! 671:
! 672: case _IOWR('i', 27, struct ifreq):
! 673: IFREQ_INOUT(SIOCGIFMETRIC);
! 674:
! 675: case _IOWR('i', 28, struct ifreq):
! 676: IFREQ_IN(SIOCSIFMETRIC);
! 677:
! 678: case _IOW('i', 30, struct arpreq):
! 679: /* SIOCSARP */
! 680: break;
! 681:
! 682: case _IOWR('i', 31, struct arpreq):
! 683: /* SIOCGARP */
! 684: break;
! 685:
! 686: case _IOW('i', 32, struct arpreq):
! 687: /* SIOCDARP */
! 688: break;
! 689:
! 690: case _IOW('i', 18, struct ifreq): /* SIOCSIFMEM */
! 691: case _IOWR('i', 19, struct ifreq): /* SIOCGIFMEM */
! 692: case _IOW('i', 40, struct ifreq): /* SIOCUPPER */
! 693: case _IOW('i', 41, struct ifreq): /* SIOCLOWER */
! 694: case _IOW('i', 44, struct ifreq): /* SIOCSETSYNC */
! 695: case _IOWR('i', 45, struct ifreq): /* SIOCGETSYNC */
! 696: case _IOWR('i', 46, struct ifreq): /* SIOCSDSTATS */
! 697: case _IOWR('i', 47, struct ifreq): /* SIOCSESTATS */
! 698: case _IOW('i', 48, int): /* SIOCSPROMISC */
! 699: case _IOW('i', 49, struct ifreq): /* SIOCADDMULTI */
! 700: case _IOW('i', 50, struct ifreq): /* SIOCDELMULTI */
! 701: error = EOPNOTSUPP;
! 702: goto out;
! 703:
! 704: case _IOWR('i', 20, struct ifconf): /* SIOCGIFCONF */
! 705: {
! 706: struct ifconf ifconf;
! 707:
! 708: /*
! 709: * XXX: two more problems
! 710: * 1. our sockaddr's are variable length, not always sizeof(sockaddr)
! 711: * 2. this returns a name per protocol, ie. it returns two "lo0"'s
! 712: */
! 713: error = copyin (SCARG(uap, data), (caddr_t)&ifconf,
! 714: sizeof (ifconf));
! 715: if (error)
! 716: goto out;
! 717: error = (*ctl)(fp, OSIOCGIFCONF, (caddr_t)&ifconf, p);
! 718: if (error)
! 719: goto out;
! 720: error = copyout ((caddr_t)&ifconf, SCARG(uap, data),
! 721: sizeof (ifconf));
! 722: goto out;
! 723: }
! 724:
! 725: /*
! 726: * Audio ioctl translations.
! 727: */
! 728: case _IOR('A', 1, struct sunos_audio_info): /* AUDIO_GETINFO */
! 729: sunos_au_getinfo:
! 730: {
! 731: struct audio_info aui;
! 732: struct sunos_audio_info sunos_aui;
! 733:
! 734: error = (*ctl)(fp, AUDIO_GETINFO, (caddr_t)&aui, p);
! 735: if (error)
! 736: goto out;
! 737:
! 738: sunos_aui.play = *(struct sunos_audio_prinfo *)&aui.play;
! 739: sunos_aui.record = *(struct sunos_audio_prinfo *)&aui.record;
! 740:
! 741: /* `avail_ports' is `seek' in BSD */
! 742: sunos_aui.play.avail_ports = AUDIO_SPEAKER | AUDIO_HEADPHONE;
! 743: sunos_aui.record.avail_ports = AUDIO_SPEAKER | AUDIO_HEADPHONE;
! 744:
! 745: sunos_aui.play.waiting = 0;
! 746: sunos_aui.record.waiting = 0;
! 747: sunos_aui.play.eof = 0;
! 748: sunos_aui.record.eof = 0;
! 749: sunos_aui.monitor_gain = 0; /* aui.__spare; XXX */
! 750: /*XXXsunos_aui.output_muted = 0;*/
! 751: /*XXX*/sunos_aui.reserved[0] = 0;
! 752: /*XXX*/sunos_aui.reserved[1] = 0;
! 753: /*XXX*/sunos_aui.reserved[2] = 0;
! 754: /*XXX*/sunos_aui.reserved[3] = 0;
! 755:
! 756: error = copyout ((caddr_t)&sunos_aui, SCARG(uap, data),
! 757: sizeof (sunos_aui));
! 758: goto out;
! 759: }
! 760:
! 761: case _IOWR('A', 2, struct sunos_audio_info): /* AUDIO_SETINFO */
! 762: {
! 763: struct audio_info aui;
! 764: struct sunos_audio_info sunos_aui;
! 765:
! 766: error = copyin (SCARG(uap, data), (caddr_t)&sunos_aui,
! 767: sizeof (sunos_aui));
! 768: if (error)
! 769: goto out;
! 770:
! 771: aui.play = *(struct audio_prinfo *)&sunos_aui.play;
! 772: aui.record = *(struct audio_prinfo *)&sunos_aui.record;
! 773: /* aui.__spare = sunos_aui.monitor_gain; */
! 774: aui.blocksize = ~0;
! 775: aui.hiwat = ~0;
! 776: aui.lowat = ~0;
! 777: /* XXX somebody check this please. - is: aui.backlog = ~0; */
! 778: aui.mode = ~0;
! 779: /*
! 780: * The bsd driver does not distinguish between paused and
! 781: * active. (In the sun driver, not active means samples are
! 782: * not output at all, but paused means the last streams buffer
! 783: * is drained and then output stops.) If either are 0, then
! 784: * when stop output. Otherwise, if either are non-zero,
! 785: * we resume.
! 786: */
! 787: if (sunos_aui.play.pause == 0 || sunos_aui.play.active == 0)
! 788: aui.play.pause = 0;
! 789: else if (sunos_aui.play.pause != (u_char)~0 ||
! 790: sunos_aui.play.active != (u_char)~0)
! 791: aui.play.pause = 1;
! 792: if (sunos_aui.record.pause == 0 || sunos_aui.record.active == 0)
! 793: aui.record.pause = 0;
! 794: else if (sunos_aui.record.pause != (u_char)~0 ||
! 795: sunos_aui.record.active != (u_char)~0)
! 796: aui.record.pause = 1;
! 797:
! 798: error = (*ctl)(fp, AUDIO_SETINFO, (caddr_t)&aui, p);
! 799: if (error)
! 800: goto out;
! 801: /* Return new state */
! 802: goto sunos_au_getinfo;
! 803: }
! 804: case _IO('A', 3): /* AUDIO_DRAIN */
! 805: error = (*ctl)(fp, AUDIO_DRAIN, (void *)0, p);
! 806: goto out;
! 807: case _IOR('A', 4, int): /* AUDIO_GETDEV */
! 808: {
! 809: int devtype = SUNOS_AUDIO_DEV_AMD;
! 810: error = copyout ((caddr_t)&devtype, SCARG(uap, data),
! 811: sizeof (devtype));
! 812: goto out;
! 813: }
! 814:
! 815: /*
! 816: * Selected streams ioctls.
! 817: */
! 818: #define SUNOS_S_FLUSHR 1
! 819: #define SUNOS_S_FLUSHW 2
! 820: #define SUNOS_S_FLUSHRW 3
! 821:
! 822: #define SUNOS_S_INPUT 1
! 823: #define SUNOS_S_HIPRI 2
! 824: #define SUNOS_S_OUTPUT 4
! 825: #define SUNOS_S_MSG 8
! 826:
! 827: case _IO('S', 5): /* I_FLUSH */
! 828: {
! 829: int tmp = 0;
! 830: switch ((int)SCARG(uap, data)) {
! 831: case SUNOS_S_FLUSHR:
! 832: tmp = FREAD;
! 833: break;
! 834: case SUNOS_S_FLUSHW:
! 835: tmp = FWRITE;
! 836: break;
! 837: case SUNOS_S_FLUSHRW:
! 838: tmp = FREAD|FWRITE;
! 839: break;
! 840: }
! 841: error = (*ctl)(fp, TIOCFLUSH, (caddr_t)&tmp, p);
! 842: goto out;
! 843: }
! 844: case _IO('S', 9): /* I_SETSIG */
! 845: {
! 846: int on = 1;
! 847:
! 848: if (((int)SCARG(uap, data) & (SUNOS_S_HIPRI|SUNOS_S_INPUT)) ==
! 849: SUNOS_S_HIPRI) {
! 850: error = EOPNOTSUPP;
! 851: goto out;
! 852: }
! 853: error = (*ctl)(fp, FIOASYNC, (caddr_t)&on, p);
! 854: goto out;
! 855: }
! 856: }
! 857: error = (sys_ioctl(p, uap, retval));
! 858: out:
! 859: FRELE(fp);
! 860: return (error);
! 861: }
! 862:
! 863: /* SunOS fcntl(2) cmds not implemented */
! 864: #define SUN_F_RGETLK 10
! 865: #define SUN_F_RSETLK 11
! 866: #define SUN_F_CNVT 12
! 867: #define SUN_F_RSETLKW 13
! 868:
! 869: /* SunOS flock translation */
! 870: struct sunos_flock {
! 871: short l_type;
! 872: short l_whence;
! 873: long l_start;
! 874: long l_len;
! 875: short l_pid;
! 876: short l_xxx;
! 877: };
! 878:
! 879: static void bsd_to_sunos_flock(struct flock *, struct sunos_flock *);
! 880: static void sunos_to_bsd_flock(struct sunos_flock *, struct flock *);
! 881:
! 882: #define SUNOS_F_RDLCK 1
! 883: #define SUNOS_F_WRLCK 2
! 884: #define SUNOS_F_UNLCK 3
! 885:
! 886: static void
! 887: bsd_to_sunos_flock(iflp, oflp)
! 888: struct flock *iflp;
! 889: struct sunos_flock *oflp;
! 890: {
! 891: switch (iflp->l_type) {
! 892: case F_RDLCK:
! 893: oflp->l_type = SUNOS_F_RDLCK;
! 894: break;
! 895: case F_WRLCK:
! 896: oflp->l_type = SUNOS_F_WRLCK;
! 897: break;
! 898: case F_UNLCK:
! 899: oflp->l_type = SUNOS_F_UNLCK;
! 900: break;
! 901: default:
! 902: oflp->l_type = -1;
! 903: break;
! 904: }
! 905:
! 906: oflp->l_whence = (short) iflp->l_whence;
! 907: oflp->l_start = (long) iflp->l_start;
! 908: oflp->l_len = (long) iflp->l_len;
! 909: oflp->l_pid = (short) iflp->l_pid;
! 910: oflp->l_xxx = 0;
! 911: }
! 912:
CVSweb