sunos_ioctl.c revision 1.3 1 /*
2 * Copyright (c) 1993 Markus Wild.
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. The name of the author may not be used to endorse or promote products
11 * derived from this software withough specific prior written permission
12 *
13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
14 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
15 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
16 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
17 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
18 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
19 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
20 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
22 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 *
24 * loosely from: Header: sun_ioctl.c,v 1.7 93/05/28 04:40:43 torek Exp
25 * $Id: sunos_ioctl.c,v 1.3 1993/11/14 14:46:54 deraadt Exp $
26 */
27
28 #include <sys/param.h>
29 #include <sys/proc.h>
30 #include <sys/file.h>
31 #include <sys/filedesc.h>
32 #include <sys/ioctl.h>
33 #include <sys/termios.h>
34 #include <sys/tty.h>
35
36 /*
37 * SunOS ioctl calls.
38 * This file is something of a hodge-podge.
39 * Support gets added as things turn up....
40 */
41
42 struct sun_ttysize {
43 int ts_row;
44 int ts_col;
45 };
46
47 struct sun_termio {
48 u_short c_iflag;
49 u_short c_oflag;
50 u_short c_cflag;
51 u_short c_lflag;
52 char c_line;
53 unsigned char c_cc[8];
54 };
55 #define SUN_TCGETA _IOR('T', 1, struct sun_termio)
56 #define SUN_TCSETA _IOW('T', 2, struct sun_termio)
57 #define SUN_TCSETAW _IOW('T', 3, struct sun_termio)
58 #define SUN_TCSETAF _IOW('T', 4, struct sun_termio)
59 #define SUN_TCSBRK _IO('T', 5)
60
61 struct sun_termios {
62 u_long c_iflag;
63 u_long c_oflag;
64 u_long c_cflag;
65 u_long c_lflag;
66 char c_line;
67 u_char c_cc[17];
68 };
69 #define SUN_TCXONC _IO('T', 6)
70 #define SUN_TCFLSH _IO('T', 7)
71 #define SUN_TCGETS _IOR('T', 8, struct sun_termios)
72 #define SUN_TCSETS _IOW('T', 9, struct sun_termios)
73 #define SUN_TCSETSW _IOW('T', 10, struct sun_termios)
74 #define SUN_TCSETSF _IOW('T', 11, struct sun_termios)
75 #define SUN_TCSNDBRK _IO('T', 12)
76 #define SUN_TCDRAIN _IO('T', 13)
77
78 static struct speedtab sptab[] = {
79 { 0, 0 },
80 { 50, 1 },
81 { 75, 2 },
82 { 110, 3 },
83 { 134, 4 },
84 { 135, 4 },
85 { 150, 5 },
86 { 200, 6 },
87 { 300, 7 },
88 { 600, 8 },
89 { 1200, 9 },
90 { 1800, 10 },
91 { 2400, 11 },
92 { 4800, 12 },
93 { 9600, 13 },
94 { 19200, 14 },
95 { 38400, 15 },
96 { -1, -1 }
97 };
98
99 static u_long s2btab[] = {
100 0,
101 50,
102 75,
103 110,
104 134,
105 150,
106 200,
107 300,
108 600,
109 1200,
110 1800,
111 2400,
112 4800,
113 9600,
114 19200,
115 38400,
116 };
117
118 /*
119 * these two conversion functions have mostly been done
120 * with some perl cut&paste, then handedited to comment
121 * out what doesn't exist under NetBSD.
122 * A note from Markus's code:
123 * (l & BITMASK1) / BITMASK1 * BITMASK2 is translated
124 * optimally by gcc m68k, much better than any ?: stuff.
125 * Code may vary with different architectures of course.
126 *
127 * I don't know what optimizer you used, but seeing divu's and
128 * bfextu's in the m68k assembly output did not encourage me...
129 * as well, gcc on the sparc definately generates much better
130 * code with ?:.
131 */
132
133 static void
134 stios2btios(st, bt)
135 struct sun_termios *st;
136 struct termios *bt;
137 {
138 register u_long l, r;
139
140 l = st->c_iflag;
141 r = ((l & 0x00000001) ? IGNBRK : 0);
142 r |= ((l & 0x00000002) ? BRKINT : 0);
143 r |= ((l & 0x00000004) ? IGNPAR : 0);
144 r |= ((l & 0x00000008) ? PARMRK : 0);
145 r |= ((l & 0x00000010) ? INPCK : 0);
146 r |= ((l & 0x00000020) ? ISTRIP : 0);
147 r |= ((l & 0x00000040) ? INLCR : 0);
148 r |= ((l & 0x00000080) ? IGNCR : 0);
149 r |= ((l & 0x00000100) ? ICRNL : 0);
150 /* ((l & 0x00000200) ? IUCLC : 0) */
151 r |= ((l & 0x00000400) ? IXON : 0);
152 r |= ((l & 0x00000800) ? IXANY : 0);
153 r |= ((l & 0x00001000) ? IXOFF : 0);
154 r |= ((l & 0x00002000) ? IMAXBEL : 0);
155 bt->c_iflag = r;
156
157 l = st->c_oflag;
158 r = ((l & 0x00000001) ? OPOST : 0);
159 /* ((l & 0x00000002) ? OLCUC : 0) */
160 r |= ((l & 0x00000004) ? ONLCR : 0);
161 /* ((l & 0x00000008) ? OCRNL : 0) */
162 /* ((l & 0x00000010) ? ONOCR : 0) */
163 /* ((l & 0x00000020) ? ONLRET : 0) */
164 /* ((l & 0x00000040) ? OFILL : 0) */
165 /* ((l & 0x00000080) ? OFDEL : 0) */
166 /* ((l & 0x00000100) ? NLDLY : 0) */
167 /* ((l & 0x00000100) ? NL1 : 0) */
168 /* ((l & 0x00000600) ? CRDLY : 0) */
169 /* ((l & 0x00000200) ? CR1 : 0) */
170 /* ((l & 0x00000400) ? CR2 : 0) */
171 /* ((l & 0x00000600) ? CR3 : 0) */
172 /* ((l & 0x00001800) ? TABDLY : 0) */
173 /* ((l & 0x00000800) ? TAB1 : 0) */
174 /* ((l & 0x00001000) ? TAB2 : 0) */
175 r |= ((l & 0x00001800) ? OXTABS : 0);
176 /* ((l & 0x00002000) ? BSDLY : 0) */
177 /* ((l & 0x00002000) ? BS1 : 0) */
178 /* ((l & 0x00004000) ? VTDLY : 0) */
179 /* ((l & 0x00004000) ? VT1 : 0) */
180 /* ((l & 0x00008000) ? FFDLY : 0) */
181 /* ((l & 0x00008000) ? FF1 : 0) */
182 /* ((l & 0x00010000) ? PAGEOUT : 0) */
183 /* ((l & 0x00020000) ? WRAP : 0) */
184 bt->c_oflag = r;
185
186 l = st->c_cflag;
187 r = ((l & 0x00000010) ? CS6 : 0);
188 r |= ((l & 0x00000020) ? CS7 : 0);
189 r |= ((l & 0x00000030) ? CS8 : 0);
190 r |= ((l & 0x00000040) ? CSTOPB : 0);
191 r |= ((l & 0x00000080) ? CREAD : 0);
192 r |= ((l & 0x00000100) ? PARENB : 0);
193 r |= ((l & 0x00000200) ? PARODD : 0);
194 r |= ((l & 0x00000400) ? HUPCL : 0);
195 r |= ((l & 0x00000800) ? CLOCAL : 0);
196 /* ((l & 0x00001000) ? LOBLK : 0) */
197 r |= ((l & 0x80000000) ? (CRTS_IFLOW|CCTS_OFLOW) : 0);
198 bt->c_cflag = r;
199
200 bt->c_ispeed = bt->c_ospeed = s2btab[l & 0x0000000f];
201
202 l = st->c_lflag;
203 r = ((l & 0x00000001) ? ISIG : 0);
204 r |= ((l & 0x00000002) ? ICANON : 0);
205 /* ((l & 0x00000004) ? XCASE : 0) */
206 r |= ((l & 0x00000008) ? ECHO : 0);
207 r |= ((l & 0x00000010) ? ECHOE : 0);
208 r |= ((l & 0x00000020) ? ECHOK : 0);
209 r |= ((l & 0x00000040) ? ECHONL : 0);
210 r |= ((l & 0x00000080) ? NOFLSH : 0);
211 r |= ((l & 0x00000100) ? TOSTOP : 0);
212 r |= ((l & 0x00000200) ? ECHOCTL : 0);
213 r |= ((l & 0x00000400) ? ECHOPRT : 0);
214 r |= ((l & 0x00000800) ? ECHOKE : 0);
215 /* ((l & 0x00001000) ? DEFECHO : 0) */
216 r |= ((l & 0x00002000) ? FLUSHO : 0);
217 r |= ((l & 0x00004000) ? PENDIN : 0);
218 bt->c_lflag = r;
219
220 bt->c_cc[VINTR] = st->c_cc[0] ? st->c_cc[0] : _POSIX_VDISABLE;
221 bt->c_cc[VQUIT] = st->c_cc[1] ? st->c_cc[1] : _POSIX_VDISABLE;
222 bt->c_cc[VERASE] = st->c_cc[2] ? st->c_cc[2] : _POSIX_VDISABLE;
223 bt->c_cc[VKILL] = st->c_cc[3] ? st->c_cc[3] : _POSIX_VDISABLE;
224 bt->c_cc[VEOF] = st->c_cc[4] ? st->c_cc[4] : _POSIX_VDISABLE;
225 bt->c_cc[VEOL] = st->c_cc[5] ? st->c_cc[5] : _POSIX_VDISABLE;
226 bt->c_cc[VEOL2] = st->c_cc[6] ? st->c_cc[6] : _POSIX_VDISABLE;
227 /* bt->c_cc[VSWTCH] = st->c_cc[7] ? st->c_cc[7] : _POSIX_VDISABLE; */
228 bt->c_cc[VSTART] = st->c_cc[8] ? st->c_cc[8] : _POSIX_VDISABLE;
229 bt->c_cc[VSTOP] = st->c_cc[9] ? st->c_cc[9] : _POSIX_VDISABLE;
230 bt->c_cc[VSUSP] = st->c_cc[10] ? st->c_cc[10] : _POSIX_VDISABLE;
231 bt->c_cc[VDSUSP] = st->c_cc[11] ? st->c_cc[11] : _POSIX_VDISABLE;
232 bt->c_cc[VREPRINT] = st->c_cc[12] ? st->c_cc[12] : _POSIX_VDISABLE;
233 bt->c_cc[VDISCARD] = st->c_cc[13] ? st->c_cc[13] : _POSIX_VDISABLE;
234 bt->c_cc[VWERASE] = st->c_cc[14] ? st->c_cc[14] : _POSIX_VDISABLE;
235 bt->c_cc[VLNEXT] = st->c_cc[15] ? st->c_cc[15] : _POSIX_VDISABLE;
236 bt->c_cc[VSTATUS] = st->c_cc[16] ? st->c_cc[16] : _POSIX_VDISABLE;
237 }
238
239
240 static void
241 btios2stios(bt, st)
242 struct termios *bt;
243 struct sun_termios *st;
244 {
245 register u_long l, r;
246
247 l = bt->c_iflag;
248 r = ((l & IGNBRK) ? 0x00000001 : 0);
249 r |= ((l & BRKINT) ? 0x00000002 : 0);
250 r |= ((l & IGNPAR) ? 0x00000004 : 0);
251 r |= ((l & PARMRK) ? 0x00000008 : 0);
252 r |= ((l & INPCK) ? 0x00000010 : 0);
253 r |= ((l & ISTRIP) ? 0x00000020 : 0);
254 r |= ((l & INLCR) ? 0x00000040 : 0);
255 r |= ((l & IGNCR) ? 0x00000080 : 0);
256 r |= ((l & ICRNL) ? 0x00000100 : 0);
257 /* ((l & IUCLC) ? 0x00000200 : 0) */
258 r |= ((l & IXON) ? 0x00000400 : 0);
259 r |= ((l & IXANY) ? 0x00000800 : 0);
260 r |= ((l & IXOFF) ? 0x00001000 : 0);
261 r |= ((l & IMAXBEL) ? 0x00002000 : 0);
262 st->c_iflag = r;
263
264 l = bt->c_oflag;
265 r = ((l & OPOST) ? 0x00000001 : 0);
266 /* ((l & OLCUC) ? 0x00000002 : 0) */
267 r |= ((l & ONLCR) ? 0x00000004 : 0);
268 /* ((l & OCRNL) ? 0x00000008 : 0) */
269 /* ((l & ONOCR) ? 0x00000010 : 0) */
270 /* ((l & ONLRET) ? 0x00000020 : 0) */
271 /* ((l & OFILL) ? 0x00000040 : 0) */
272 /* ((l & OFDEL) ? 0x00000080 : 0) */
273 /* ((l & NLDLY) ? 0x00000100 : 0) */
274 /* ((l & NL1) ? 0x00000100 : 0) */
275 /* ((l & CRDLY) ? 0x00000600 : 0) */
276 /* ((l & CR1) ? 0x00000200 : 0) */
277 /* ((l & CR2) ? 0x00000400 : 0) */
278 /* ((l & CR3) ? 0x00000600 : 0) */
279 /* ((l & TABDLY) ? 0x00001800 : 0) */
280 /* ((l & TAB1) ? 0x00000800 : 0) */
281 /* ((l & TAB2) ? 0x00001000 : 0) */
282 r |= ((l & OXTABS) ? 0x00001800 : 0);
283 /* ((l & BSDLY) ? 0x00002000 : 0) */
284 /* ((l & BS1) ? 0x00002000 : 0) */
285 /* ((l & VTDLY) ? 0x00004000 : 0) */
286 /* ((l & VT1) ? 0x00004000 : 0) */
287 /* ((l & FFDLY) ? 0x00008000 : 0) */
288 /* ((l & FF1) ? 0x00008000 : 0) */
289 /* ((l & PAGEOUT) ? 0x00010000 : 0) */
290 /* ((l & WRAP) ? 0x00020000 : 0) */
291 st->c_oflag = r;
292
293 l = bt->c_cflag;
294 r = ((l & CS6) ? 0x00000010 : 0);
295 r |= ((l & CS7) ? 0x00000020 : 0);
296 r |= ((l & CS8) ? 0x00000030 : 0);
297 r |= ((l & CSTOPB) ? 0x00000040 : 0);
298 r |= ((l & CREAD) ? 0x00000080 : 0);
299 r |= ((l & PARENB) ? 0x00000100 : 0);
300 r |= ((l & PARODD) ? 0x00000200 : 0);
301 r |= ((l & HUPCL) ? 0x00000400 : 0);
302 r |= ((l & CLOCAL) ? 0x00000800 : 0);
303 /* ((l & LOBLK) ? 0x00001000 : 0) */
304 r |= ((l & (CRTS_IFLOW|CCTS_OFLOW)) ? 0x80000000 : 0);
305 st->c_cflag = r;
306
307 l = bt->c_lflag;
308 r = ((l & ISIG) ? 0x00000001 : 0);
309 r |= ((l & ICANON) ? 0x00000002 : 0);
310 /* ((l & XCASE) ? 0x00000004 : 0) */
311 r |= ((l & ECHO) ? 0x00000008 : 0);
312 r |= ((l & ECHOE) ? 0x00000010 : 0);
313 r |= ((l & ECHOK) ? 0x00000020 : 0);
314 r |= ((l & ECHONL) ? 0x00000040 : 0);
315 r |= ((l & NOFLSH) ? 0x00000080 : 0);
316 r |= ((l & TOSTOP) ? 0x00000100 : 0);
317 r |= ((l & ECHOCTL) ? 0x00000200 : 0);
318 r |= ((l & ECHOPRT) ? 0x00000400 : 0);
319 r |= ((l & ECHOKE) ? 0x00000800 : 0);
320 /* ((l & DEFECHO) ? 0x00001000 : 0) */
321 r |= ((l & FLUSHO) ? 0x00002000 : 0);
322 r |= ((l & PENDIN) ? 0x00004000 : 0);
323 st->c_lflag = r;
324
325 l = ttspeedtab(bt->c_ospeed, sptab);
326 if (l >= 0)
327 st->c_cflag |= l;
328
329 st->c_cc[0] = bt->c_cc[VINTR] != _POSIX_VDISABLE? bt->c_cc[VINTR]:0;
330 st->c_cc[1] = bt->c_cc[VQUIT] != _POSIX_VDISABLE? bt->c_cc[VQUIT]:0;
331 st->c_cc[2] = bt->c_cc[VERASE] != _POSIX_VDISABLE? bt->c_cc[VERASE]:0;
332 st->c_cc[3] = bt->c_cc[VKILL] != _POSIX_VDISABLE? bt->c_cc[VKILL]:0;
333 st->c_cc[4] = bt->c_cc[VEOF] != _POSIX_VDISABLE? bt->c_cc[VEOF]:0;
334 st->c_cc[5] = bt->c_cc[VEOL] != _POSIX_VDISABLE? bt->c_cc[VEOL]:0;
335 st->c_cc[6] = bt->c_cc[VEOL2] != _POSIX_VDISABLE? bt->c_cc[VEOL2]:0;
336 st->c_cc[7] = 0;
337 /* bt->c_cc[VSWTCH] != _POSIX_VDISABLE? bt->c_cc[VSWTCH]: */
338 st->c_cc[8] = bt->c_cc[VSTART] != _POSIX_VDISABLE? bt->c_cc[VSTART]:0;
339 st->c_cc[9] = bt->c_cc[VSTOP] != _POSIX_VDISABLE? bt->c_cc[VSTOP]:0;
340 st->c_cc[10]= bt->c_cc[VSUSP] != _POSIX_VDISABLE? bt->c_cc[VSUSP]:0;
341 st->c_cc[11]= bt->c_cc[VDSUSP] != _POSIX_VDISABLE? bt->c_cc[VDSUSP]:0;
342 st->c_cc[12]= bt->c_cc[VREPRINT]!= _POSIX_VDISABLE? bt->c_cc[VREPRINT]:0;
343 st->c_cc[13]= bt->c_cc[VDISCARD]!= _POSIX_VDISABLE? bt->c_cc[VDISCARD]:0;
344 st->c_cc[14]= bt->c_cc[VWERASE] != _POSIX_VDISABLE? bt->c_cc[VWERASE]:0;
345 st->c_cc[15]= bt->c_cc[VLNEXT] != _POSIX_VDISABLE? bt->c_cc[VLNEXT]:0;
346 st->c_cc[16]= bt->c_cc[VSTATUS] != _POSIX_VDISABLE? bt->c_cc[VSTATUS]:0;
347
348 st->c_line = 0;
349 }
350
351 static void
352 stios2stio(ts, t)
353 struct sun_termios *ts;
354 struct sun_termio *t;
355 {
356 t->c_iflag = ts->c_iflag;
357 t->c_oflag = ts->c_oflag;
358 t->c_cflag = ts->c_cflag;
359 t->c_lflag = ts->c_lflag;
360 t->c_line = ts->c_line;
361 bcopy(ts->c_cc, t->c_cc, 8);
362 }
363
364 static void
365 stio2stios(t, ts)
366 struct sun_termio *t;
367 struct sun_termios *ts;
368 {
369 ts->c_iflag = t->c_iflag;
370 ts->c_oflag = t->c_oflag;
371 ts->c_cflag = t->c_cflag;
372 ts->c_lflag = t->c_lflag;
373 ts->c_line = t->c_line;
374 bcopy(t->c_cc, ts->c_cc, 8); /* don't touch the upper fields! */
375 }
376
377 struct sun_ioctl_args {
378 int fd;
379 int cmd;
380 caddr_t data;
381 };
382
383 int
384 sun_ioctl(p, uap, retval)
385 register struct proc *p;
386 register struct sun_ioctl_args *uap;
387 int *retval;
388 {
389 register struct filedesc *fdp = p->p_fd;
390 register struct file *fp;
391 register int (*ctl)();
392 int error;
393
394 if ( (unsigned)uap->fd >= fdp->fd_nfiles ||
395 (fp = fdp->fd_ofiles[uap->fd]) == NULL)
396 return EBADF;
397
398 if ((fp->f_flag & (FREAD|FWRITE)) == 0)
399 return EBADF;
400
401 ctl = fp->f_ops->fo_ioctl;
402
403 switch (uap->cmd) {
404 case _IOR('t', 0, int):
405 uap->cmd = TIOCGETD;
406 break;
407 case _IOW('t', 1, int):
408 {
409 int disc;
410
411 if ((error = copyin(uap->data, (caddr_t)&disc,
412 sizeof disc)) != 0)
413 return error;
414
415 /* map SunOS NTTYDISC into our termios discipline */
416 if (disc == 2)
417 disc = 0;
418 /* all other disciplines are not supported by NetBSD */
419 if (disc)
420 return ENXIO;
421
422 return (*ctl)(fp, TIOCSETD, (caddr_t)&disc, p);
423 }
424 case _IO('t', 36): /* sun TIOCCONS, no parameters */
425 {
426 int on = 1;
427 return (*ctl)(fp, TIOCCONS, (caddr_t)&on, p);
428 }
429 case _IOW('t', 37, struct sun_ttysize):
430 {
431 struct winsize ws;
432 struct sun_ttysize ss;
433
434 if ((error = (*ctl)(fp, TIOCGWINSZ, (caddr_t)&ws, p)) != 0)
435 return (error);
436
437 if ((error = copyin (uap->data, &ss, sizeof (ss))) != 0)
438 return error;
439
440 ws.ws_row = ss.ts_row;
441 ws.ws_col = ss.ts_col;
442
443 return ((*ctl)(fp, TIOCSWINSZ, (caddr_t)&ws, p));
444 }
445 case _IOW('t', 38, struct sun_ttysize):
446 {
447 struct winsize ws;
448 struct sun_ttysize ss;
449
450 if ((error = (*ctl)(fp, TIOCGWINSZ, (caddr_t)&ws, p)) != 0)
451 return (error);
452
453 ss.ts_row = ws.ws_row;
454 ss.ts_col = ws.ws_col;
455
456 return copyout ((caddr_t)&ss, uap->data, sizeof (ss));
457 }
458 case _IOR('t', 130, int):
459 uap->cmd = TIOCSPGRP;
460 break;
461 case _IOR('t', 131, int):
462 uap->cmd = TIOCGPGRP;
463 break;
464 case _IO('t', 132):
465 uap->cmd = TIOCSCTTY;
466 break;
467 case SUN_TCGETA:
468 case SUN_TCGETS:
469 {
470 struct termios bts;
471 struct sun_termios sts;
472 struct sun_termio st;
473
474 if ((error = (*ctl)(fp, TIOCGETA, (caddr_t)&bts, p)) != 0)
475 return error;
476
477 btios2stios (&bts, &sts);
478 if (uap->cmd == SUN_TCGETA) {
479 stios2stio (&sts, &st);
480 return copyout((caddr_t)&st, uap->data, sizeof (st));
481 } else
482 return copyout((caddr_t)&sts, uap->data, sizeof (sts));
483 /*NOTREACHED*/
484 }
485 case SUN_TCSETA:
486 case SUN_TCSETAW:
487 case SUN_TCSETAF:
488 {
489 struct termios bts;
490 struct sun_termios sts;
491 struct sun_termio st;
492
493 if ((error = copyin(uap->data, (caddr_t)&st,
494 sizeof (st))) != 0)
495 return error;
496
497 /* get full BSD termios so we don't lose information */
498 if ((error = (*ctl)(fp, TIOCGETA, (caddr_t)&bts, p)) != 0)
499 return error;
500
501 /*
502 * convert to sun termios, copy in information from
503 * termio, and convert back, then set new values.
504 */
505 btios2stios(&bts, &sts);
506 stio2stios(&st, &sts);
507 stios2btios(&sts, &bts);
508
509 return (*ctl)(fp, uap->cmd - SUN_TCSETA + TIOCSETA,
510 (caddr_t)&bts, p);
511 }
512 case SUN_TCSETS:
513 case SUN_TCSETSW:
514 case SUN_TCSETSF:
515 {
516 struct termios bts;
517 struct sun_termios sts;
518
519 if ((error = copyin (uap->data, (caddr_t)&sts,
520 sizeof (sts))) != 0)
521 return error;
522 stios2btios (&sts, &bts);
523 return (*ctl)(fp, uap->cmd - SUN_TCSETS + TIOCSETA,
524 (caddr_t)&bts, p);
525 }
526 }
527 return (ioctl(p, uap, retval));
528 }
529