|
|
1.1 root 1: /*
2: * Mach Operating System
3: * Copyright (c) 1993-1988 Carnegie Mellon University
4: * All Rights Reserved.
5: *
6: * Permission to use, copy, modify and distribute this software and its
7: * documentation is hereby granted, provided that both the copyright
8: * notice and this permission notice appear in all copies of the
9: * software, derivative works or modified versions, and any portions
10: * thereof, and that both notices appear in supporting documentation.
11: *
12: * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
13: * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
14: * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
15: *
16: * Carnegie Mellon requests users of this software to return to
17: *
18: * Software Distribution Coordinator or [email protected]
19: * School of Computer Science
20: * Carnegie Mellon University
21: * Pittsburgh PA 15213-3890
22: *
23: * any improvements or extensions that they make and grant Carnegie Mellon
24: * the rights to redistribute these changes.
25: */
26: /*
27: * Author: David B. Golub, Carnegie Mellon University
28: * Date: 8/88
29: *
30: * TTY io.
31: * Compatibility with old TTY device drivers.
32: */
33:
34: #include <mach/kern_return.h>
35: #include <mach/mig_errors.h>
36: #include <mach/vm_param.h>
37: #include <machine/machspl.h> /* spl definitions */
38:
39: #include <ipc/ipc_port.h>
40:
41: #include <kern/lock.h>
42: #include <kern/queue.h>
43:
44: #include <vm/vm_map.h>
45: #include <vm/vm_kern.h>
46:
47: #include <device/device_types.h>
48: #include <device/io_req.h>
49: #include <device/ds_routines.h>
50: #include "device_reply.h"
51:
52: #include <device/tty.h>
53:
54: /* If you change these, check that tty_outq_size and tty_inq_size
55: * is greater than largest tthiwat entry.
56: */
57: short tthiwat[16] =
58: { 100,100,100,100,100,100,100,200,200,400,400,400,650,650,1300,2000 };
59: short ttlowat[16] =
60: { 30, 30, 30, 30, 30, 30, 30, 50, 50,120,120,120,125,125, 125, 125 };
61:
62: /*
63: * forward declarations
64: */
65: void queue_delayed_reply(
66: queue_t, io_req_t, boolean_t (*)(io_req_t));
67: void tty_output(struct tty *);
68: void tty_flush(struct tty *, int);
69: boolean_t char_open_done(io_req_t);
70: boolean_t char_read_done(io_req_t);
71: boolean_t char_write_done(io_req_t);
72:
73: /*
74: * Fake 'line discipline' switch for the benefit of old code
75: * that wants to call through it.
76: */
77: struct ldisc_switch linesw[] = {
78: {
79: char_read,
80: char_write,
81: ttyinput,
82: ttymodem,
83: tty_output
84: }
85: };
86:
87: /*
88: * Sizes for input and output circular buffers.
89: */
90: int tty_inq_size = 4096; /* big nuf */
91: int tty_outq_size = 2048; /* Must be bigger that tthiwat */
92: int pdma_default = 1; /* turn pseudo dma on by default */
93:
94: /*
95: * compute pseudo-dma tables
96: */
97:
98: int pdma_timeouts[NSPEEDS]; /* how many ticks in timeout */
99: int pdma_water_mark[NSPEEDS];
100:
101:
102: void chario_init(void)
103: {
104: /* the basic idea with the timeouts is two allow enough
105: time for a character to show up if data is coming in at full data rate
106: plus a little slack. 2 ticks is considered slack
107: Below 300 baud we just glob a character at a time */
108: #define _PR(x) ((hz/x) + 2)
109:
110: int i;
111:
112: for (i = B0; i < B300; i++)
113: pdma_timeouts[i] = 0;
114:
115: pdma_timeouts[B300] = _PR(30);
116: pdma_timeouts[B600] = _PR(60);
117: pdma_timeouts[B1200] = _PR(120);
118: pdma_timeouts[B1800] = _PR(180);
119: pdma_timeouts[B2400] = _PR(240);
120: pdma_timeouts[B4800] = _PR(480);
121: pdma_timeouts[B9600] = _PR(960);
122: pdma_timeouts[EXTA] = _PR(1440); /* >14400 baud */
123: pdma_timeouts[EXTB] = _PR(1920); /* >19200 baud */
124:
125: for (i = B0; i < B300; i++)
126: pdma_water_mark[i] = 0;
127:
128: /* for the slow speeds, we try to buffer 0.02 of the baud rate
129: (20% of the character rate). For the faster lines,
130: we try to buffer 1/2 the input queue size */
131:
132: #undef _PR
133: #define _PR(x) (0.20 * x)
134:
135: pdma_water_mark[B300] = _PR(120);
136: pdma_water_mark[B600] = _PR(120);
137: pdma_water_mark[B1200] = _PR(120);
138: pdma_water_mark[B1800] = _PR(180);
139: pdma_water_mark[B2400] = _PR(240);
140: pdma_water_mark[B4800] = _PR(480);
141: i = tty_inq_size/2;
142: pdma_water_mark[B9600] = i;
143: pdma_water_mark[EXTA] = i; /* >14400 baud */
144: pdma_water_mark[EXTB] = i; /* >19200 baud */
145:
146: return;
147: }
148:
149: /*
150: * Open TTY, waiting for CARR_ON.
151: * No locks may be held.
152: * May run on any CPU.
153: */
154: io_return_t char_open(
155: int dev,
156: struct tty * tp,
157: dev_mode_t mode,
158: io_req_t ior)
159: {
160: spl_t s;
161: io_return_t rc = D_SUCCESS;
162:
163: s = spltty();
164: simple_lock(&tp->t_lock);
165:
166: tp->t_dev = dev;
167:
168: if (tp->t_mctl)
169: (*tp->t_mctl)(tp, TM_DTR, DMSET);
170:
171: if (pdma_default)
172: tp->t_state |= TS_MIN;
173:
174: if ((tp->t_state & TS_CARR_ON) == 0) {
175: /*
176: * No carrier.
177: */
178: if (mode & D_NODELAY) {
179: tp->t_state |= TS_ONDELAY;
180: }
181: else {
182: /*
183: * Don`t return from open until carrier detected.
184: */
185: tp->t_state |= TS_WOPEN;
186:
187: ior->io_dev_ptr = (char *)tp;
188:
189: queue_delayed_reply(&tp->t_delayed_open, ior, char_open_done);
190: rc = D_IO_QUEUED;
191: goto out;
192: }
193: }
194: tp->t_state |= TS_ISOPEN;
195: if (tp->t_mctl)
196: (*tp->t_mctl)(tp, TM_RTS, DMBIS);
197: out:
198: simple_unlock(&tp->t_lock);
199: splx(s);
200: return rc;
201: }
202:
203: /*
204: * Retry wait for CARR_ON for open.
205: * No locks may be held.
206: * May run on any CPU.
207: */
208: boolean_t char_open_done(
209: io_req_t ior)
210: {
211: register struct tty *tp = (struct tty *)ior->io_dev_ptr;
212: spl_t s = spltty();
213:
214: simple_lock(&tp->t_lock);
215: if ((tp->t_state & TS_ISOPEN) == 0) {
216: queue_delayed_reply(&tp->t_delayed_open, ior, char_open_done);
217: simple_unlock(&tp->t_lock);
218: splx(s);
219: return FALSE;
220: }
221:
222: tp->t_state |= TS_ISOPEN;
223: tp->t_state &= ~TS_WOPEN;
224:
225: if (tp->t_mctl)
226: (*tp->t_mctl)(tp, TM_RTS, DMBIS);
227:
228: simple_unlock(&tp->t_lock);
229: splx(s);
230:
231: ior->io_error = D_SUCCESS;
232: (void) ds_open_done(ior);
233: return TRUE;
234: }
235:
236: boolean_t tty_close_open_reply(
237: io_req_t ior)
238: {
239: ior->io_error = D_DEVICE_DOWN;
240: (void) ds_open_done(ior);
241: return TRUE;
242: }
243:
244: /*
245: * Write to TTY.
246: * No locks may be held.
247: * Calls device start routine; must already be on master if
248: * device needs to run on master.
249: */
250: io_return_t char_write(
251: register struct tty * tp,
252: register io_req_t ior)
253: {
254: spl_t s;
255: register int count;
256: register char *data;
257: vm_offset_t addr;
258: io_return_t rc = D_SUCCESS;
259:
260: data = ior->io_data;
261: count = ior->io_count;
262: if (count == 0)
263: return rc;
264:
265: if (!(ior->io_op & IO_INBAND)) {
266: /*
267: * Copy out-of-line data into kernel address space.
268: * Since data is copied as page list, it will be
269: * accessible.
270: */
271: vm_map_copy_t copy = (vm_map_copy_t) data;
272: kern_return_t kr;
273:
274: kr = vm_map_copyout(device_io_map, &addr, copy);
275: if (kr != KERN_SUCCESS)
276: return kr;
277: data = (char *) addr;
278: }
279:
280: /*
281: * Check for tty operating.
282: */
283: s = spltty();
284: simple_lock(&tp->t_lock);
285:
286: if ((tp->t_state & TS_CARR_ON) == 0) {
287:
288: if ((tp->t_state & TS_ONDELAY) == 0) {
289: /*
290: * No delayed writes - tell caller that device is down
291: */
292: rc = D_IO_ERROR;
293: goto out;
294: }
295:
296: if (ior->io_mode & D_NOWAIT) {
297: rc = D_WOULD_BLOCK;
298: goto out;
299: }
300: }
301:
302: /*
303: * Copy data into the output buffer.
304: * Report the amount not copied.
305: */
306:
307: ior->io_residual = b_to_q(data, count, &tp->t_outq);
308:
309: /*
310: * Start hardware output.
311: */
312:
313: tp->t_state &= ~TS_TTSTOP;
314: tty_output(tp);
315:
316: if (tp->t_outq.c_cc > TTHIWAT(tp) ||
317: (tp->t_state & TS_CARR_ON) == 0) {
318:
319: /*
320: * Do not send reply until some characters have been sent.
321: */
322: ior->io_dev_ptr = (char *)tp;
323: queue_delayed_reply(&tp->t_delayed_write, ior, char_write_done);
324:
325: rc = D_IO_QUEUED;
326: }
327: out:
328: simple_unlock(&tp->t_lock);
329: splx(s);
330:
331: if (!(ior->io_op & IO_INBAND))
332: (void) vm_deallocate(device_io_map, addr, ior->io_count);
333: return rc;
334: }
335:
336: /*
337: * Retry wait for output queue emptied, for write.
338: * No locks may be held.
339: * May run on any CPU.
340: */
341: boolean_t char_write_done(
342: register io_req_t ior)
343: {
344: register struct tty *tp = (struct tty *)ior->io_dev_ptr;
345: register spl_t s = spltty();
346:
347: simple_lock(&tp->t_lock);
348: if (tp->t_outq.c_cc > TTHIWAT(tp) ||
349: (tp->t_state & TS_CARR_ON) == 0) {
350:
351: queue_delayed_reply(&tp->t_delayed_write, ior, char_write_done);
352: simple_unlock(&tp->t_lock);
353: splx(s);
354: return FALSE;
355: }
356: simple_unlock(&tp->t_lock);
357: splx(s);
358:
359: if (IP_VALID(ior->io_reply_port)) {
360: (void) (*((ior->io_op & IO_INBAND) ?
361: ds_device_write_reply_inband :
362: ds_device_write_reply))(ior->io_reply_port,
363: ior->io_reply_port_type,
364: ior->io_error,
365: (int) (ior->io_total -
366: ior->io_residual));
367: }
368: mach_device_deallocate(ior->io_device);
369: return TRUE;
370: }
371:
372: boolean_t tty_close_write_reply(
373: register io_req_t ior)
374: {
375: ior->io_residual = ior->io_count;
376: ior->io_error = D_DEVICE_DOWN;
377: (void) ds_write_done(ior);
378: return TRUE;
379: }
380:
381: /*
382: * Read from TTY.
383: * No locks may be held.
384: * May run on any CPU - does not talk to device driver.
385: */
386: io_return_t char_read(
387: register struct tty *tp,
388: register io_req_t ior)
389: {
390: spl_t s;
391: kern_return_t rc;
392:
393: /*
394: * Allocate memory for read buffer.
395: */
396: rc = device_read_alloc(ior, (vm_size_t)ior->io_count);
397: if (rc != KERN_SUCCESS)
398: return rc;
399:
400: s = spltty();
401: simple_lock(&tp->t_lock);
402: if ((tp->t_state & TS_CARR_ON) == 0) {
403:
404: if ((tp->t_state & TS_ONDELAY) == 0) {
405: /*
406: * No delayed writes - tell caller that device is down
407: */
408: rc = D_IO_ERROR;
409: goto out;
410: }
411:
412: if (ior->io_mode & D_NOWAIT) {
413: rc = D_WOULD_BLOCK;
414: goto out;
415: }
416:
417: }
418:
419: if (tp->t_inq.c_cc <= 0 ||
420: (tp->t_state & TS_CARR_ON) == 0) {
421:
422: ior->io_dev_ptr = (char *)tp;
423: queue_delayed_reply(&tp->t_delayed_read, ior, char_read_done);
424: rc = D_IO_QUEUED;
425: goto out;
426: }
427:
428: ior->io_residual = ior->io_count - q_to_b(&tp->t_inq,
429: ior->io_data,
430: (int)ior->io_count);
431: if (tp->t_state & TS_RTS_DOWN) {
432: (*tp->t_mctl)(tp, TM_RTS, DMBIS);
433: tp->t_state &= ~TS_RTS_DOWN;
434: }
435:
436: out:
437: simple_unlock(&tp->t_lock);
438: splx(s);
439: return rc;
440: }
441:
442: /*
443: * Retry wait for characters, for read.
444: * No locks may be held.
445: * May run on any CPU - does not talk to device driver.
446: */
447: boolean_t char_read_done(
448: register io_req_t ior)
449: {
450: register struct tty *tp = (struct tty *)ior->io_dev_ptr;
451: register spl_t s = spltty();
452:
453: simple_lock(&tp->t_lock);
454:
455: if (tp->t_inq.c_cc <= 0 ||
456: (tp->t_state & TS_CARR_ON) == 0) {
457:
458: queue_delayed_reply(&tp->t_delayed_read, ior, char_read_done);
459: simple_unlock(&tp->t_lock);
460: splx(s);
461: return FALSE;
462: }
463:
464: ior->io_residual = ior->io_count - q_to_b(&tp->t_inq,
465: ior->io_data,
466: (int)ior->io_count);
467: if (tp->t_state & TS_RTS_DOWN) {
468: (*tp->t_mctl)(tp, TM_RTS, DMBIS);
469: tp->t_state &= ~TS_RTS_DOWN;
470: }
471:
472: simple_unlock(&tp->t_lock);
473: splx(s);
474:
475: (void) ds_read_done(ior);
476: return TRUE;
477: }
478:
479: boolean_t tty_close_read_reply(
480: register io_req_t ior)
481: {
482: ior->io_residual = ior->io_count;
483: ior->io_error = D_DEVICE_DOWN;
484: (void) ds_read_done(ior);
485: return TRUE;
486: }
487:
488: /*
489: * Close the tty.
490: * Tty must be locked (at spltty).
491: * Iff modem control should run on master.
492: */
493: void ttyclose(
494: register struct tty *tp)
495: {
496: register io_req_t ior;
497:
498: /*
499: * Flush the read and write queues. Signal
500: * the open queue so that those waiting for open
501: * to complete will see that the tty is closed.
502: */
503: while ((ior = (io_req_t)dequeue_head(&tp->t_delayed_read)) != 0) {
504: ior->io_done = tty_close_read_reply;
505: iodone(ior);
506: }
507: while ((ior = (io_req_t)dequeue_head(&tp->t_delayed_write)) != 0) {
508: ior->io_done = tty_close_write_reply;
509: iodone(ior);
510: }
511: while ((ior = (io_req_t)dequeue_head(&tp->t_delayed_open)) != 0) {
512: ior->io_done = tty_close_open_reply;
513: iodone(ior);
514: }
515:
516: /* Close down modem */
517: if (tp->t_mctl) {
518: (*tp->t_mctl)(tp, TM_BRK|TM_RTS, DMBIC);
519: if ((tp->t_state&(TS_HUPCLS|TS_WOPEN)) || (tp->t_state&TS_ISOPEN)==0)
520: (*tp->t_mctl)(tp, TM_HUP, DMSET);
521: }
522:
523: /* only save buffering bit, and carrier */
524: tp->t_state = tp->t_state & (TS_MIN|TS_CARR_ON);
525: }
526:
527: /*
528: * Port-death routine to clean up reply messages.
529: */
530: boolean_t
531: tty_queue_clean(
532: queue_t q,
533: ipc_port_t port,
534: boolean_t (*routine)(io_req_t) )
535: {
536: register io_req_t ior;
537:
538: ior = (io_req_t)queue_first(q);
539: while (!queue_end(q, (queue_entry_t)ior)) {
540: if (ior->io_reply_port == port) {
541: remqueue(q, (queue_entry_t)ior);
542: ior->io_done = routine;
543: iodone(ior);
544: return TRUE;
545: }
546: ior = ior->io_next;
547: }
548: return FALSE;
549: }
550:
551: /*
552: * Handle port-death (dead reply port) for tty.
553: * No locks may be held.
554: * May run on any CPU.
555: */
556: boolean_t
557: tty_portdeath(
558: struct tty * tp,
559: ipc_port_t port)
560: {
561: register spl_t spl = spltty();
562: register boolean_t result;
563:
564: simple_lock(&tp->t_lock);
565:
566: /*
567: * The queues may never have been initialized
568: */
569: if (tp->t_delayed_read.next == 0) {
570: result = FALSE;
571: }
572: else {
573: result =
574: tty_queue_clean(&tp->t_delayed_read, port,
575: tty_close_read_reply)
576: || tty_queue_clean(&tp->t_delayed_write, port,
577: tty_close_write_reply)
578: || tty_queue_clean(&tp->t_delayed_open, port,
579: tty_close_open_reply);
580: }
581: simple_unlock(&tp->t_lock);
582: splx(spl);
583:
584: return result;
585: }
586:
587: /*
588: * Get TTY status.
589: * No locks may be held.
590: * May run on any CPU.
591: */
592: io_return_t tty_get_status(
593: register struct tty *tp,
594: dev_flavor_t flavor,
595: int * data, /* pointer to OUT array */
596: natural_t *count) /* out */
597: {
598: spl_t s;
599:
600: switch (flavor) {
601: case TTY_STATUS:
602: {
603: register struct tty_status *tsp =
604: (struct tty_status *) data;
605:
606: if (*count < TTY_STATUS_COUNT)
607: return (D_INVALID_OPERATION);
608:
609: s = spltty();
610: simple_lock(&tp->t_lock);
611:
612: tsp->tt_ispeed = tp->t_ispeed;
613: tsp->tt_ospeed = tp->t_ospeed;
614: tsp->tt_breakc = tp->t_breakc;
615: tsp->tt_flags = tp->t_flags;
616: if (tp->t_state & TS_HUPCLS)
617: tsp->tt_flags |= TF_HUPCLS;
618:
619: simple_unlock(&tp->t_lock);
620: splx(s);
621:
622: *count = TTY_STATUS_COUNT;
623: break;
624:
625: }
626: default:
627: return D_INVALID_OPERATION;
628: }
629: return D_SUCCESS;
630: }
631:
632: /*
633: * Set TTY status.
634: * No locks may be held.
635: * Calls device start or stop routines; must already be on master if
636: * device needs to run on master.
637: */
638: io_return_t tty_set_status(
639: register struct tty *tp,
640: dev_flavor_t flavor,
641: int * data,
642: natural_t count)
643: {
644: int s;
645:
646: switch (flavor) {
647: case TTY_FLUSH:
648: {
649: register int flags;
650: if (count < TTY_FLUSH_COUNT)
651: return D_INVALID_OPERATION;
652:
653: flags = *data;
654: if (flags == 0)
655: flags = D_READ | D_WRITE;
656:
657: s = spltty();
658: simple_lock(&tp->t_lock);
659: tty_flush(tp, flags);
660: simple_unlock(&tp->t_lock);
661: splx(s);
662:
663: break;
664: }
665: case TTY_STOP:
666: /* stop output */
667: s = spltty();
668: simple_lock(&tp->t_lock);
669: if ((tp->t_state & TS_TTSTOP) == 0) {
670: tp->t_state |= TS_TTSTOP;
671: (*tp->t_stop)(tp, 0);
672: }
673: simple_unlock(&tp->t_lock);
674: splx(s);
675: break;
676:
677: case TTY_START:
678: /* start output */
679: s = spltty();
680: simple_lock(&tp->t_lock);
681: if (tp->t_state & TS_TTSTOP) {
682: tp->t_state &= ~TS_TTSTOP;
683: tty_output(tp);
684: }
685: simple_unlock(&tp->t_lock);
686: splx(s);
687: break;
688:
689: case TTY_STATUS:
690: /* set special characters and speed */
691: {
692: register struct tty_status *tsp;
693:
694: if (count < TTY_STATUS_COUNT)
695: return D_INVALID_OPERATION;
696:
697: tsp = (struct tty_status *)data;
698:
699: if (tsp->tt_ispeed < 0 ||
700: tsp->tt_ispeed >= NSPEEDS ||
701: tsp->tt_ospeed < 0 ||
702: tsp->tt_ospeed >= NSPEEDS)
703: {
704: return D_INVALID_OPERATION;
705: }
706:
707: s = spltty();
708: simple_lock(&tp->t_lock);
709:
710: tp->t_ispeed = tsp->tt_ispeed;
711: tp->t_ospeed = tsp->tt_ospeed;
712: tp->t_breakc = tsp->tt_breakc;
713: tp->t_flags = tsp->tt_flags & ~TF_HUPCLS;
714: if (tsp->tt_flags & TF_HUPCLS)
715: tp->t_state |= TS_HUPCLS;
716:
717: simple_unlock(&tp->t_lock);
718: splx(s);
719: break;
720: }
721: default:
722: return D_INVALID_OPERATION;
723: }
724: return D_SUCCESS;
725: }
726:
727:
728: /*
729: * [internal]
730: * Queue IOR on reply queue, to wait for TTY operation.
731: * TTY must be locked (at spltty).
732: */
733: void queue_delayed_reply(
734: queue_t qh,
735: io_req_t ior,
736: boolean_t (*io_done)(io_req_t) )
737: {
738: ior->io_done = io_done;
739: enqueue_tail(qh, (queue_entry_t)ior);
740: }
741:
742: /*
743: * Retry delayed IO operations for TTY.
744: * TTY containing queue must be locked (at spltty).
745: */
746: void tty_queue_completion(
747: register queue_t qh)
748: {
749: register io_req_t ior;
750:
751: while ((ior = (io_req_t)dequeue_head(qh)) != 0) {
752: iodone(ior);
753: }
754: }
755:
756: /*
757: * Set the default special characters.
758: * Since this routine is called whenever a tty has never been opened,
759: * we can initialize the queues here.
760: */
761: void ttychars(
762: register struct tty *tp)
763: {
764: if ((tp->t_flags & TS_INIT) == 0) {
765: /*
766: * Initialize queues
767: */
768: queue_init(&tp->t_delayed_open);
769: queue_init(&tp->t_delayed_read);
770: queue_init(&tp->t_delayed_write);
771:
772: /*
773: * Initialize character buffers
774: */
775: cb_alloc(&tp->t_inq, tty_inq_size);
776:
777: /* if we might do modem flow control */
778: if (tp->t_mctl && tp->t_inq.c_hog > 30)
779: tp->t_inq.c_hog -= 30;
780:
781: cb_alloc(&tp->t_outq, tty_outq_size);
782:
783: /*
784: * Mark initialized
785: */
786: tp->t_state |= TS_INIT;
787: }
788:
789: tp->t_breakc = 0;
790: }
791:
792: /*
793: * Flush all TTY queues.
794: * Called at spltty, tty already locked.
795: * Calls device STOP routine; must already be on master if
796: * device needs to run on master.
797: */
798: void tty_flush(
799: register struct tty *tp,
800: int rw)
801: {
802: if (rw & D_READ) {
803: cb_clear(&tp->t_inq);
804: tty_queue_completion(&tp->t_delayed_read);
805: }
806: if (rw & D_WRITE) {
807: tp->t_state &= ~TS_TTSTOP;
808: (*tp->t_stop)(tp, rw);
809: cb_clear(&tp->t_outq);
810: tty_queue_completion(&tp->t_delayed_write);
811: }
812: }
813:
814: /*
815: * Restart character output after a delay timeout.
816: * Calls device start routine - must be on master CPU.
817: *
818: * Timeout routines are called only on master CPU.
819: * What if device runs on a different CPU?
820: */
821: void ttrstrt(
822: register struct tty *tp)
823: {
824: register spl_t s;
825:
826: s = spltty();
827: simple_lock(&tp->t_lock);
828:
829: tp->t_state &= ~TS_TIMEOUT;
830: ttstart (tp);
831:
832: simple_unlock(&tp->t_lock);
833: splx(s);
834: }
835:
836: /*
837: * Start output on the typewriter. It is used from the top half
838: * after some characters have been put on the output queue,
839: * from the interrupt routine to transmit the next
840: * character, and after a timeout has finished.
841: *
842: * Called at spltty, tty already locked.
843: * Must be on master CPU if device runs on master.
844: */
845: void ttstart(tp)
846: register struct tty *tp;
847: {
848: if ((tp->t_state & (TS_TIMEOUT|TS_TTSTOP|TS_BUSY)) == 0) {
849: /*
850: * Start up the hardware again
851: */
852: (*tp->t_start)(tp);
853:
854: /*
855: * Wake up those waiting for write completion.
856: */
857: if (tp->t_outq.c_cc <= TTLOWAT(tp))
858: tty_queue_completion(&tp->t_delayed_write);
859: }
860: }
861:
862: /*
863: * Start character output, if the device is not busy or
864: * stopped or waiting for a timeout.
865: *
866: * Called at spltty, tty already locked.
867: * Must be on master CPU if device runs on master.
868: */
869: void tty_output(
870: register struct tty *tp)
871: {
872: if ((tp->t_state & (TS_TIMEOUT|TS_TTSTOP|TS_BUSY)) == 0) {
873: /*
874: * Not busy. Start output.
875: */
876: (*tp->t_start)(tp);
877:
878: /*
879: * Wake up those waiting for write completion.
880: */
881: if (tp->t_outq.c_cc <= TTLOWAT(tp))
882: tty_queue_completion(&tp->t_delayed_write);
883: }
884: }
885:
886: /*
887: * Send any buffered recvd chars up to user
888: */
889: void ttypush(
890: register struct tty *tp)
891: {
892: spl_t s = spltty();
893: register int state;
894:
895: simple_lock(&tp->t_lock);
896:
897: /*
898: The pdma timeout has gone off.
899: If no character has been received since the timeout
900: was set, push any pending characters up.
901: If any characters were received in the last interval
902: then just reset the timeout and the character received bit.
903: */
904:
905: state = tp->t_state;
906:
907: if (state & TS_MIN_TO)
908: {
909: if (state & TS_MIN_TO_RCV)
910: { /* a character was received */
911: tp->t_state = state & ~TS_MIN_TO_RCV;
912: timeout(ttypush,tp,pdma_timeouts[tp->t_ispeed]);
913: }
914: else
915: {
916: tp->t_state = state & ~TS_MIN_TO;
917: if (tp->t_inq.c_cc) /* pending characters */
918: tty_queue_completion(&tp->t_delayed_read);
919: }
920: }
921: else
922: {
923: tp->t_state = state & ~TS_MIN_TO_RCV;/* sanity */
924: }
925:
926: simple_unlock(&tp->t_lock);
927: splx(s);
928: }
929:
930: /*
931: * Put input character on input queue.
932: *
933: * Called at spltty, tty already locked.
934: */
935: void ttyinput(
936: unsigned int c,
937: struct tty *tp)
938: {
939: if (tp->t_inq.c_cc >= tp->t_inq.c_hog) {
940: /*
941: * Do not want to overflow input queue
942: */
943: if (tp->t_mctl) {
944: (*tp->t_mctl)(tp, TM_RTS, DMBIC);
945: tp->t_state |= TS_RTS_DOWN;
946: }
947: tty_queue_completion(&tp->t_delayed_read);
948: return;
949:
950: }
951:
952: c &= 0xff;
953:
954: (void) putc(c, &tp->t_inq);
955: if ((tp->t_state & TS_MIN) == 0 ||
956: tp->t_inq.c_cc > pdma_water_mark[tp->t_ispeed])
957: {
958: /*
959: * No input buffering, or input minimum exceeded.
960: * Grab a request from input queue and queue it
961: * to io_done thread.
962: */
963: if (tp->t_state & TS_MIN_TO) {
964: tp->t_state &= ~(TS_MIN_TO|TS_MIN_TO_RCV);
965: untimeout(ttypush, tp);
966: }
967: tty_queue_completion(&tp->t_delayed_read);
968: }
969: else {
970: /*
971: * Not enough characters.
972: * If no timeout is set, initiate the timeout
973: * Otherwise set the character received during timeout interval
974: * flag.
975: * One alternative approach would be just to reset the timeout
976: * into the future, but this involves making a timeout/untimeout
977: * call on every character.
978: */
979: register int ptime = pdma_timeouts[tp->t_ispeed];
980: if (ptime > 0)
981: {
982: if ((tp->t_state & TS_MIN_TO) == 0)
983: {
984: tp->t_state |= TS_MIN_TO;
985: timeout(ttypush, tp, ptime);
986: }
987: else
988: {
989: tp->t_state |= TS_MIN_TO_RCV;
990: }
991: }
992: }
993: }
994:
995: /*
996: * Put many characters on input queue.
997: *
998: * Called at spltty, tty already locked.
999: */
1000: void ttyinput_many(
1001: struct tty *tp,
1002: unsigned char *chars,
1003: int count)
1004: {
1005: /*
1006: * Do not want to overflow input queue
1007: */
1008: if (tp->t_inq.c_cc < tp->t_inq.c_hog)
1009: count -= b_to_q( chars, count, &tp->t_inq);
1010:
1011: tty_queue_completion(&tp->t_delayed_read);
1012: }
1013:
1014:
1015: /*
1016: * Handle modem control transition on a tty.
1017: * Flag indicates new state of carrier.
1018: * Returns FALSE if the line should be turned off.
1019: *
1020: * Called at spltty, tty already locked.
1021: */
1022: boolean_t ttymodem(
1023: struct tty * tp,
1024: boolean_t carrier_up)
1025: {
1026: if ((tp->t_state&TS_WOPEN) == 0 && (tp->t_flags & MDMBUF)) {
1027: /*
1028: * Flow control by carrier. Carrier down stops
1029: * output; carrier up restarts output.
1030: */
1031: if (carrier_up) {
1032: tp->t_state &= ~TS_TTSTOP;
1033: tty_output(tp);
1034: }
1035: else if ((tp->t_state&TS_TTSTOP) == 0) {
1036: tp->t_state |= TS_TTSTOP;
1037: (*tp->t_stop)(tp, 0);
1038: }
1039: }
1040: else if (carrier_up) {
1041: /*
1042: * Carrier now on.
1043: */
1044: tp->t_state |= TS_CARR_ON;
1045: tt_open_wakeup(tp);
1046: }
1047: else {
1048: /*
1049: * Lost carrier.
1050: */
1051: tp->t_state &= ~TS_CARR_ON;
1052: if (tp->t_state & TS_ISOPEN &&
1053: (tp->t_flags & NOHANG) == 0)
1054: {
1055: /*
1056: * Hang up TTY if carrier drops.
1057: * Need to alert users, somehow...
1058: */
1059: tty_flush(tp, D_READ|D_WRITE);
1060: return FALSE;
1061: }
1062: }
1063: return TRUE;
1064: }
1065:
1066: /*
1067: * Similarly, handle transitions on the ClearToSend
1068: * signal. Nowadays, it is used by many modems as
1069: * a flow-control device: they turn it down to stop
1070: * us from sending more chars. We do the same with
1071: * the RequestToSend signal. [Yes, that is exactly
1072: * why those signals are defined in the standard.]
1073: *
1074: * Tty must be locked and on master.
1075: */
1076: tty_cts(
1077: struct tty * tp,
1078: boolean_t cts_up)
1079: {
1080: if (tp->t_state & TS_ISOPEN){
1081: if (cts_up) {
1082: tp->t_state &= ~(TS_TTSTOP|TS_BUSY);
1083: tty_output(tp);
1084: } else {
1085: tp->t_state |= (TS_TTSTOP|TS_BUSY);
1086: (*tp->t_stop)(tp, D_WRITE);
1087: }
1088: }
1089: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.