|
|
1.1 root 1: /*
2: * i386/tioc.c
3: *
4: * Convert COH286 tty ioctl's to Sys 5 compatible calls.
5: *
6: * Revised: Wed May 26 16:49:20 1993 CDT
7: */
8:
9: /*
10: * ----------------------------------------------------------------------
11: * Includes.
12: */
13: #include <sys/coherent.h>
14: #include <sgtty.h>
15: #include <sys/errno.h>
16:
17:
18: /*
19: * ----------------------------------------------------------------------
20: * Definitions.
21: * Constants.
22: * Macros with argument lists.
23: * Typedefs.
24: * Enums.
25: */
26:
27: #define OIOC_LOW 0100
28: #define OIOC_HIGH 0110
29:
30: /*
31: * Bits from COH286 sgttyb sg_flags field.
32: */
33: #define O_EVENP 0x0001 /* Allow even parity */
34: #define O_ODDP 0x0002 /* Allow odd parity */
35: #define O_CRMOD 0x0004 /* Map '\r' to '\n' */
36: #define O_ECHO 0x0008 /* Echo input characters */
37: #define O_LCASE 0x0010 /* Lowercase mapping on input */
38: #define O_CBREAK 0x0020 /* Each input character causes wakeup */
39: #define O_RAWIN 0x0040 /* 8-bit input raw */
40: #define O_RAWOUT 0x0080 /* 8-bit output raw */
41: #define O_TANDEM 0x0100 /* flow control protocol */
42: #define O_XTABS 0x0200 /* Expand tabs to spaces */
43: #define O_CRT 0x0400 /* CRT character erase */
44:
45: #define O_RAW (O_RAWIN|O_RAWOUT) /* Raw mode */
46:
47: /*
48: * Names for terminal speeds.
49: */
50: #define O_B0 0 /* Hangup if modem control enabled */
51: #define O_B50 1 /* 50 bps */
52: #define O_B75 2 /* 75 bps */
53: #define O_B110 3 /* 110 bps */
54: #define O_B134 4 /* 134.5 bps (IBM 2741) */
55: #define O_B150 5 /* 150 bps */
56: #define O_B200 6 /* 200 bps */
57: #define O_B300 7 /* 300 bps */
58: #define O_B600 8 /* 600 bps */
59: #define O_B1200 9 /* 1200 bps */
60: #define O_B1800 10 /* 1800 bps */
61: #define O_B2000 11 /* 2000 bps */
62: #define O_B2400 12 /* 2400 bps */
63: #define O_B3600 13 /* 3600 bps */
64: #define O_B4800 14 /* 4800 bps */
65: #define O_B7200 15 /* 7200 bps */
66: #define O_B9600 16 /* 9600 bps */
67: #define O_B19200 17 /* 19200 bps */
68: #define O_EXTA 18 /* External A (DH-11) */
69: #define O_EXTB 19 /* External B (DH-11) */
70:
71: /*
72: * ----------------------------------------------------------------------
73: * Functions.
74: * Import Functions.
75: * Export Functions.
76: * Local Functions.
77: */
78:
79: static void to_s5_sgfld();
80: static void to_s5speed();
81: static void to_coh_sgfld();
82: static void to_cohspeed();
83:
84: /*
85: * ----------------------------------------------------------------------
86: * Global Data.
87: * Import Variables.
88: * Export Variables.
89: * Local Variables.
90: */
91: /*
92: * Here are the COH286 values for tty ioctl's.
93: * In cvtsgtty[] below, subtract 0100 from the 286 COH ioctl value to
94: * index to the equivalent Sys V ioctl.
95: *
96: * OIOCSETP 0100 Terminal set modes (old stty)
97: * OIOCGETP 0101 Terminal get modes (old gtty)
98: * OIOCSETC 0102 Set characters
99: * OIOCGETC 0103 Get characters
100: * OIOCSETN 0104 Set modes w/o delay or out flush
101: * OIOCEXCL 0105 Set exclusive use
102: * OIOCNXCL 0106 Set non-exclusive use
103: * OIOCHPCL 0107 Hang up on last close
104: * OIOCFLUSH 0110 Flush characters in I/O queues
105: */
106: static unsigned short cvtsgtty[] = {
107: TIOCSETP,
108: TIOCGETP,
109: TIOCSETC,
110: TIOCGETC,
111: TIOCSETN,
112: TIOCEXCL,
113: TIOCNXCL,
114: TIOCHPCL,
115: TIOCFLUSH
116: };
117:
118: /*
119: * ----------------------------------------------------------------------
120: * Code.
121: */
122:
123: /*
124: * tioc()
125: *
126: * This function is called by dioctl() whenever a 286 binary does an ioctl().
127: * Its arguments are the arguments for to the ioctl, plus the local driver's
128: * ioctl function, which should support S5 sgtty and termio commands.
129: *
130: * 1. If com is COH 286 TIOC, translate it to S5 TIOC.
131: * 2. If translated com is TIOCSET[NP], convert sgttyb struct *vec to S5.
132: * 3. If translated com is TIOCGETP, point vec to a full S5 struct (COH 286
133: * sgttyb struct is 2 bytes shorter than S5 format).
134: * 4. Call driver's ioctl().
135: * 5. If just finished a converted TIOCGETP, convert back to COH 286 sgttyb.
136: */
137: void tioc(dev, com, vec, iocfn, mode)
138: int dev, com, vec, (*iocfn)();
139: {
140: struct sgttyb sg;
141: int my_com = com, my_vec = vec, old_getp = 0;
142: int space;
143:
144: if (com >= OIOC_LOW && com <= OIOC_HIGH && u.u_error == 0) {
145:
146: my_com = cvtsgtty [com - OIOC_LOW];
147:
148: if (my_com == TIOCSETP || my_com == TIOCSETN) {
149: ukcopy (vec, & sg, sizeof (struct sgttyb));
150: sg.sg_flags &= 0xffff;
151: to_s5_sgfld (& sg);
152: my_vec = & sg;
153: }
154:
155: if (my_com == TIOCGETP) {
156: old_getp = 1;
157: my_vec = &sg;
158: }
159: }
160:
161: /*
162: * NIGEL: I have tightened up the segment limits so that kucopy ()
163: * and ukcopy () no longer accept kernel addresses as user addresses;
164: * in this case, we really do want this to happen, so we use
165: * setspace () to allow access to kernel data space as user space.
166: */
167:
168: if (my_vec != vec)
169: space = setspace (SEG_386_KD);
170:
171: (* iocfn) (dev, my_com, my_vec, mode);
172:
173: if (my_vec != vec)
174: (void) setspace (space);
175:
176: if (old_getp && u.u_error == 0) {
177: to_coh_sgfld (my_vec);
178: kucopy (my_vec, vec, sizeof (struct sgttyb) - 2);
179: }
180: }
181:
182: /*
183: * to_s5_sgfld()
184: *
185: * Convert fields in a sgttyb struct from COH 286 format to Sys 5.
186: */
187:
188: static void to_s5_sgfld(sgp)
189: struct sgttyb * sgp;
190: {
191: unsigned int f = sgp->sg_flags, g = 0;
192:
193: /*
194: * Convert sg_ispeed and sg_ospeed.
195: */
196:
197: to_s5speed (& sgp->sg_ispeed);
198: to_s5speed (& sgp->sg_ospeed);
199:
200: /*
201: * Convert sg_flags.
202: * f is old COH 286 flags.
203: * g is new Sys V flags.
204: */
205: if (f & O_EVENP)
206: g |= EVENP;
207: if (f & O_ODDP)
208: g |= ODDP;
209: if (f & O_CRMOD)
210: g |= CRMOD;
211: if (f & O_ECHO)
212: g |= ECHO;
213: if (f & O_LCASE)
214: g |= LCASE;
215: if (f & O_CBREAK)
216: g |= CBREAK; /* No CBREAK in Sys 5 sgtty. */
217: /* Only one RAW bit in Sys 5 sgtty. */
218: if ((f & O_RAWIN) != 0 && (f & O_RAWOUT) != 0)
219: g |= RAW;
220: if (f & O_RAWIN)
221: g |= RAWIN;
222: if (f & O_RAWOUT)
223: g |= RAWOUT;
224: if (f & O_TANDEM)
225: g |= TANDEM; /* No TANDEM in Sys 5 sgtty. */
226: if (f & O_XTABS)
227: g |= XTABS;
228: if (f & O_CRT)
229: g |= CRT; /* No CRT in Sys 5 sgtty. */
230: sgp->sg_flags = g;
231: }
232:
233: /*
234: * to_s5speed()
235: *
236: * Convert speed from COH286 to Sys5.
237: * Here are the numbers:
238: * const. COH286 Sys5
239: * B0 0 0
240: * B50 1 1
241: * B75 2 2
242: * B110 3 3
243: * B134 4 4
244: * B150 5 5
245: * B200 6 6
246: * B300 7 7
247: * B600 8 8
248: * B1200 9 9
249: * B1800 10 10
250: * B2000 11 -
251: * B2400 12 11
252: * B3600 13 -
253: * B4800 14 12
254: * B7200 15 -
255: * B9600 16 13
256: * B19200 17 14
257: * EXTA 18 14
258: * EXTB 19 15
259: */
260: #define BADSPD 99
261:
262: static void to_s5speed(speed)
263: unsigned char *speed;
264: {
265: static char s5sp[]={B0,B50,B75,B110,B134,B150,B200,B300,B600,B1200,
266: B1800,BADSPD,B2400,BADSPD,B4800,BADSPD,B9600,EXTA,EXTA,EXTB};
267:
268: if (* speed >= sizeof (s5sp))
269: u.u_error = EINVAL;
270: else if (s5sp [* speed] == BADSPD)
271: u.u_error = EINVAL;
272: else
273: * speed = s5sp [* speed];
274: }
275:
276: /*
277: * to_coh_sgfld()
278: *
279: * Convert fields in a sgttyb struct from Sys V format to COH 286.
280: */
281: static void to_coh_sgfld(sgp)
282: struct sgttyb * sgp;
283: {
284: unsigned int f = sgp->sg_flags, g = 0;
285:
286: /*
287: * Convert sg_ispeed and sg_ospeed.
288: */
289:
290: to_cohspeed (& sgp->sg_ispeed);
291: to_cohspeed (& sgp->sg_ospeed);
292:
293: /*
294: * Convert sg_flags.
295: * f is old Sys V flags.
296: * g is new COH 286 flags.
297: */
298: if (f & EVENP)
299: g |= O_EVENP;
300: if (f & ODDP)
301: g |= O_ODDP;
302: if (f & CRMOD)
303: g |= O_CRMOD;
304: if (f & ECHO)
305: g |= O_ECHO;
306: if (f & LCASE)
307: g |= O_LCASE;
308: if (f & CBREAK)
309: g |= O_CBREAK; /* No CBREAK in Sys 5 sgtty. */
310: if (f & RAWIN) /* Only one RAW bit in Sys 5 sgtty. */
311: g |= O_RAWIN;
312: if (f & RAWOUT)
313: g |= O_RAWOUT;
314: if (f & TANDEM)
315: g |= O_TANDEM; /* No TANDEM in Sys 5 sgtty. */
316: if (f & XTABS)
317: g |= O_XTABS;
318: if (f & CRT)
319: g |= O_CRT; /* No CRT in Sys 5 sgtty. */
320: sgp->sg_flags = g;
321: }
322:
323: static void to_cohspeed(speed)
324: unsigned char *speed;
325: {
326: static char cohsp[]={
327: O_B0, O_B50, O_B75, O_B110, O_B134, O_B150, O_B200,
328: O_B300, O_B600, O_B1200, O_B1800, O_B2400, O_B4800,
329: O_B9600, O_EXTA, O_EXTB
330: };
331:
332: if (* speed >= sizeof (cohsp))
333: u.u_error = EINVAL;
334: else
335: * speed = cohsp [* speed];
336: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.