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