FreeBSD/Linux Kernel Cross Reference
sys/device/chario.c
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 Software.Distribution@CS.CMU.EDU
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 * HISTORY
28 * $Log: chario.c,v $
29 * Revision 2.27 93/11/17 16:29:34 dbg
30 * Added include of kern/time_out.h.
31 * [93/06/04 dbg]
32 *
33 * Revision 2.26 93/08/10 15:10:24 mrt
34 * Added test to check that buffer is large enough to hold data
35 * returned by tty_get_status. Fix by Tero Kivinen (kivinen) at
36 * Helsinki University of Technology. This code was added in
37 * Rev 2.20 and flushed by misktake in Rev 24.
38 * [93/08/09 mrt]
39 *
40 * Revision 2.25 93/08/03 12:31:04 mrt
41 * Removed the check for success on putc in ttyinput.
42 * We want to wakeup everyone on the delayed queue, regardless
43 * of how the putc turned out.
44 * Fix by bsy and af.
45 * [93/08/03 mrt]
46 *
47 * Revision 2.24 93/05/30 21:07:50 rvb
48 * Added calls for modem control operations. Pdma code on by default.
49 * Added ttyinput_many and tty_cts. Lint.
50 * [93/05/29 09:50:55 af]
51 *
52 * Revision 2.23 93/05/17 20:11:55 rvb
53 * Flush some debugging for AF
54 *
55 * Revision 2.22 93/05/15 18:52:43 mrt
56 * machparam.h -> machspl.h
57 *
58 * Revision 2.21 93/05/10 21:18:05 rvb
59 * Fixed pdma stuff.
60 * [93/05/06 11:07:39 af]
61 *
62 * Revision 2.20 93/05/10 17:46:00 rvb
63 * Added test to check that buffer is large enough to hold data
64 * returned by tty_get_status.
65 * [93/04/20 kivinen]
66 *
67 * Revision 2.19 93/03/18 10:37:17 mrt
68 * Missed a label.
69 * [93/03/18 01:04:14 af]
70 *
71 * Compressed code here and there.
72 * [93/03/17 af]
73 *
74 * Revision 2.18 93/02/01 09:46:22 danner
75 * Extend buffering down to 300 baud.
76 * [93/01/27 danner]
77 *
78 * Refined pdma support (feedback from rvb & af).
79 * [93/01/27 danner]
80 *
81 * Revision 2.17 93/01/14 17:26:27 danner
82 * Proper spl typing. 64bit safe. Bumped up tty_inq_size.
83 * [92/11/30 af]
84 *
85 * Added function prototypes. Fixed documentation.
86 * Removed tty_queueempty and ttyoutput.
87 * [92/11/17 dbg]
88 *
89 * Revision 2.16 92/08/03 17:32:48 jfriedl
90 * removed silly prototypes
91 * [92/08/02 jfriedl]
92 *
93 * Revision 2.15 92/05/21 17:08:37 jfriedl
94 * Added void to fcns that still needed it.
95 * Made CHAR args to ttyinput() and ttyoutput() UNSIGNED.
96 * [92/05/16 jfriedl]
97 *
98 * Revision 2.14 92/05/05 10:46:10 danner
99 * Added (optional) delayed wakeup of receiver until
100 * a minimum of chars present, or timeout.
101 * [92/05/04 11:29:43 af]
102 *
103 * Revision 2.13 91/09/12 16:36:51 bohman
104 * Added missing clear of TS_TTSTOP in char_write().
105 * TS_INIT belongs in t_state, not t_flags.
106 * [91/09/11 17:04:18 bohman]
107 *
108 * Revision 2.12 91/08/28 11:11:08 jsb
109 * Fixed char_write to check vm_map_copyout's return code.
110 * [91/08/03 rpd]
111 *
112 * Revision 2.11 91/08/24 11:55:34 af
113 * Spl definitions.
114 * [91/08/02 02:44:21 af]
115 *
116 * Revision 2.10 91/05/14 15:39:09 mrt
117 * Correcting copyright
118 *
119 * Revision 2.9 91/02/05 17:07:55 mrt
120 * Changed to new Mach copyright
121 * [91/01/31 17:26:20 mrt]
122 *
123 * Revision 2.8 90/08/27 21:54:21 dbg
124 * Fixed type declaration for char_open.
125 * [90/07/16 dbg]
126 *
127 * Added call to cb_alloc in ttychars.
128 * [90/07/09 dbg]
129 *
130 * Revision 2.7 90/06/02 14:47:02 rpd
131 * Updated for new IPC. Purged MACH_XP_FPD.
132 * [90/03/26 21:42:42 rpd]
133 *
134 * Revision 2.6 90/01/11 11:41:39 dbg
135 * Fix test on 'i' (clist exhausted) in char_write.
136 * Document what operations need locking, and which must be
137 * serialized if the device driver only runs on one CPU.
138 * [89/11/30 dbg]
139 *
140 * Revision 2.5 89/11/29 14:08:50 af
141 * char_write wasn't calling b_to_q() with the right char count.
142 * [89/11/11 af]
143 * Marked tty as initialized in ttychars.
144 * [89/11/03 16:57:39 af]
145 *
146 * Revision 2.4 89/09/08 11:23:01 dbg
147 * Add in-band write check to char_write.
148 * [89/08/30 dbg]
149 *
150 * Make char_write copy data directly from user instead of wiring
151 * down data buffer first.
152 * [89/08/24 dbg]
153 *
154 * Convert to run in kernel task.
155 * [89/07/27 dbg]
156 *
157 * Revision 2.3 89/08/31 16:17:20 rwd
158 * Don't assume adequate spl when inserting/deleting ior's from
159 * delay queues.
160 * [89/08/31 rwd]
161 *
162 * Revision 2.2 89/08/05 16:04:35 rwd
163 * Added tty_queueempty for sun console input polling.
164 * Added ttyoutput for sundev/kbd.c. Allow inband data.
165 * [89/06/02 rwd]
166 *
167 * 18-May-89 David Golub (dbg) at Carnegie-Mellon University
168 * Check for uninitialized TTY queues in close/port_death.
169 *
170 * 12-Apr-89 David Golub (dbg) at Carnegie-Mellon University
171 * Added port_death routines.
172 *
173 * 24-Aug-88 David Golub (dbg) at Carnegie-Mellon University
174 * Created.
175 *
176 */
177 /*
178 * Author: David B. Golub, Carnegie Mellon University
179 * Date: 8/88
180 *
181 * TTY io.
182 * Compatibility with old TTY device drivers.
183 */
184
185 #include <mach/kern_return.h>
186 #include <mach/mig_errors.h>
187 #include <mach/vm_param.h>
188
189 #include <ipc/ipc_port.h>
190
191 #include <kern/lock.h>
192 #include <kern/queue.h>
193 #include <kern/time_out.h>
194
195 #include <vm/vm_map.h>
196 #include <vm/vm_kern.h>
197 #include <vm/vm_user.h>
198
199 #include <device/device_types.h>
200 #include <device/io_req.h>
201 #include <device/ds_routines.h>
202 #include <device/device_reply.h>
203
204 #include <device/tty.h>
205
206 #include <machine/machspl.h> /* for spl */
207
208 short tthiwat[16] =
209 { 100,100,100,100,100,100,100,200,200,400,400,400,650,650,1300,2000 };
210 short ttlowat[16] =
211 { 30, 30, 30, 30, 30, 30, 30, 50, 50,120,120,120,125,125, 125, 125 };
212
213 /*
214 * forward declarations
215 */
216 void queue_delayed_reply(
217 queue_t, io_req_t, boolean_t (*)(io_req_t));
218 void tty_output(struct tty *);
219 void tty_flush(struct tty *, int);
220 boolean_t char_open_done(io_req_t);
221 boolean_t char_read_done(io_req_t);
222 boolean_t char_write_done(io_req_t);
223
224 /*
225 * Fake 'line discipline' switch for the benefit of old code
226 * that wants to call through it.
227 */
228 struct ldisc_switch linesw[] = {
229 {
230 char_read,
231 char_write,
232 ttyinput,
233 ttymodem,
234 tty_output
235 }
236 };
237
238 /*
239 * Sizes for input and output circular buffers.
240 */
241 int tty_inq_size = 4096; /* big nuf */
242 int tty_outq_size = 256; /* XXX */
243 int pdma_default = 1; /* turn pseudo dma on by default */
244
245 /*
246 * compute pseudo-dma tables
247 */
248
249 int pdma_timeouts[NSPEEDS]; /* how many ticks in timeout */
250 int pdma_water_mark[NSPEEDS];
251
252
253 void chario_init(void)
254 {
255 /* the basic idea with the timeouts is two allow enough
256 time for a character to show up if data is coming in at full data rate
257 plus a little slack. 2 ticks is considered slack
258 Below 300 baud we just glob a character at a time */
259 #define _PR(x) ((hz/x) + 2)
260
261 int i;
262
263 for (i = B0; i < B300; i++)
264 pdma_timeouts[i] = 0;
265
266 pdma_timeouts[B300] = _PR(30);
267 pdma_timeouts[B600] = _PR(60);
268 pdma_timeouts[B1200] = _PR(120);
269 pdma_timeouts[B1800] = _PR(180);
270 pdma_timeouts[B2400] = _PR(240);
271 pdma_timeouts[B4800] = _PR(480);
272 pdma_timeouts[B9600] = _PR(960);
273 pdma_timeouts[EXTA] = _PR(1440); /* >14400 baud */
274 pdma_timeouts[EXTB] = _PR(1920); /* >19200 baud */
275
276 for (i = B0; i < B300; i++)
277 pdma_water_mark[i] = 0;
278
279 /* for the slow speeds, we try to buffer 0.02 of the baud rate
280 (20% of the character rate). For the faster lines,
281 we try to buffer 1/2 the input queue size */
282
283 #undef _PR
284 #define _PR(x) (0.20 * x)
285
286 pdma_water_mark[B300] = _PR(120);
287 pdma_water_mark[B600] = _PR(120);
288 pdma_water_mark[B1200] = _PR(120);
289 pdma_water_mark[B1800] = _PR(180);
290 pdma_water_mark[B2400] = _PR(240);
291 pdma_water_mark[B4800] = _PR(480);
292 i = tty_inq_size/2;
293 pdma_water_mark[B9600] = i;
294 pdma_water_mark[EXTA] = i; /* >14400 baud */
295 pdma_water_mark[EXTB] = i; /* >19200 baud */
296
297 return;
298 }
299
300 /*
301 * Open TTY, waiting for CARR_ON.
302 * No locks may be held.
303 * May run on any CPU.
304 */
305 io_return_t char_open(
306 int dev,
307 struct tty * tp,
308 dev_mode_t mode,
309 io_req_t ior)
310 {
311 spl_t s;
312 io_return_t rc = D_SUCCESS;
313
314 s = spltty();
315 simple_lock(&tp->t_lock);
316
317 tp->t_dev = dev;
318
319 if (tp->t_mctl)
320 (*tp->t_mctl)(tp, TM_DTR, DMSET);
321
322 if (pdma_default)
323 tp->t_state |= TS_MIN;
324
325 if ((tp->t_state & TS_CARR_ON) == 0) {
326 /*
327 * No carrier.
328 */
329 if (mode & D_NODELAY) {
330 tp->t_state |= TS_ONDELAY;
331 }
332 else {
333 /*
334 * Don`t return from open until carrier detected.
335 */
336 tp->t_state |= TS_WOPEN;
337
338 ior->io_dev_ptr = (char *)tp;
339
340 queue_delayed_reply(&tp->t_delayed_open, ior, char_open_done);
341 rc = D_IO_QUEUED;
342 goto out;
343 }
344 }
345 tp->t_state |= TS_ISOPEN;
346 if (tp->t_mctl)
347 (*tp->t_mctl)(tp, TM_RTS, DMBIS);
348 out:
349 simple_unlock(&tp->t_lock);
350 splx(s);
351 return rc;
352 }
353
354 /*
355 * Retry wait for CARR_ON for open.
356 * No locks may be held.
357 * May run on any CPU.
358 */
359 boolean_t char_open_done(
360 io_req_t ior)
361 {
362 register struct tty *tp = (struct tty *)ior->io_dev_ptr;
363 spl_t s = spltty();
364
365 simple_lock(&tp->t_lock);
366 if ((tp->t_state & TS_ISOPEN) == 0) {
367 queue_delayed_reply(&tp->t_delayed_open, ior, char_open_done);
368 simple_unlock(&tp->t_lock);
369 splx(s);
370 return FALSE;
371 }
372
373 tp->t_state |= TS_ISOPEN;
374 tp->t_state &= ~TS_WOPEN;
375
376 if (tp->t_mctl)
377 (*tp->t_mctl)(tp, TM_RTS, DMBIS);
378
379 simple_unlock(&tp->t_lock);
380 splx(s);
381
382 ior->io_error = D_SUCCESS;
383 (void) ds_open_done(ior);
384 return TRUE;
385 }
386
387 boolean_t tty_close_open_reply(
388 io_req_t ior)
389 {
390 ior->io_error = D_DEVICE_DOWN;
391 (void) ds_open_done(ior);
392 return TRUE;
393 }
394
395 /*
396 * Write to TTY.
397 * No locks may be held.
398 * Calls device start routine; must already be on master if
399 * device needs to run on master.
400 */
401 io_return_t char_write(
402 register struct tty * tp,
403 register io_req_t ior)
404 {
405 spl_t s;
406 register int count;
407 register char *data;
408 vm_offset_t addr;
409 io_return_t rc = D_SUCCESS;
410
411 data = ior->io_data;
412 count = ior->io_count;
413 if (count == 0)
414 return rc;
415
416 if (!(ior->io_op & IO_INBAND)) {
417 /*
418 * Copy out-of-line data into kernel address space.
419 * Since data is copied as page list, it will be
420 * accessible.
421 */
422 vm_map_copy_t copy = (vm_map_copy_t) data;
423 kern_return_t kr;
424
425 kr = vm_map_copyout(device_io_map, &addr, copy);
426 if (kr != KERN_SUCCESS)
427 return kr;
428 data = (char *) addr;
429 }
430
431 /*
432 * Check for tty operating.
433 */
434 s = spltty();
435 simple_lock(&tp->t_lock);
436
437 if ((tp->t_state & TS_CARR_ON) == 0) {
438
439 if ((tp->t_state & TS_ONDELAY) == 0) {
440 /*
441 * No delayed writes - tell caller that device is down
442 */
443 rc = D_IO_ERROR;
444 goto out;
445 }
446
447 if (ior->io_mode & D_NOWAIT) {
448 rc = D_WOULD_BLOCK;
449 goto out;
450 }
451 }
452
453 /*
454 * Copy data into the output buffer.
455 * Report the amount not copied.
456 */
457
458 ior->io_residual = b_to_q(data, count, &tp->t_outq);
459
460 /*
461 * Start hardware output.
462 */
463
464 tp->t_state &= ~TS_TTSTOP;
465 tty_output(tp);
466
467 if (tp->t_outq.c_cc > TTHIWAT(tp) ||
468 (tp->t_state & TS_CARR_ON) == 0) {
469
470 /*
471 * Do not send reply until some characters have been sent.
472 */
473 ior->io_dev_ptr = (char *)tp;
474 queue_delayed_reply(&tp->t_delayed_write, ior, char_write_done);
475
476 rc = D_IO_QUEUED;
477 }
478 out:
479 simple_unlock(&tp->t_lock);
480 splx(s);
481
482 if (!(ior->io_op & IO_INBAND))
483 (void) vm_deallocate(device_io_map, addr, ior->io_count);
484 return rc;
485 }
486
487 /*
488 * Retry wait for output queue emptied, for write.
489 * No locks may be held.
490 * May run on any CPU.
491 */
492 boolean_t char_write_done(
493 register io_req_t ior)
494 {
495 register struct tty *tp = (struct tty *)ior->io_dev_ptr;
496 register spl_t s = spltty();
497
498 simple_lock(&tp->t_lock);
499 if (tp->t_outq.c_cc > TTHIWAT(tp) ||
500 (tp->t_state & TS_CARR_ON) == 0) {
501
502 queue_delayed_reply(&tp->t_delayed_write, ior, char_write_done);
503 simple_unlock(&tp->t_lock);
504 splx(s);
505 return FALSE;
506 }
507 simple_unlock(&tp->t_lock);
508 splx(s);
509
510 if (IP_VALID(ior->io_reply_port)) {
511 (void) ds_device_write_reply(ior->io_reply_port,
512 ior->io_reply_port_type,
513 ior->io_error,
514 (int)(ior->io_count - ior->io_residual));
515 }
516 device_deallocate(ior->io_device);
517 return TRUE;
518 }
519
520 boolean_t tty_close_write_reply(
521 register io_req_t ior)
522 {
523 ior->io_residual = ior->io_count;
524 ior->io_error = D_DEVICE_DOWN;
525 (void) ds_write_done(ior);
526 return TRUE;
527 }
528
529 /*
530 * Read from TTY.
531 * No locks may be held.
532 * May run on any CPU - does not talk to device driver.
533 */
534 io_return_t char_read(
535 register struct tty *tp,
536 register io_req_t ior)
537 {
538 spl_t s;
539 kern_return_t rc;
540
541 /*
542 * Allocate memory for read buffer.
543 */
544 rc = device_read_alloc(ior, (vm_size_t)ior->io_count);
545 if (rc != KERN_SUCCESS)
546 return rc;
547
548 s = spltty();
549 simple_lock(&tp->t_lock);
550 if ((tp->t_state & TS_CARR_ON) == 0) {
551
552 if ((tp->t_state & TS_ONDELAY) == 0) {
553 /*
554 * No delayed writes - tell caller that device is down
555 */
556 rc = D_IO_ERROR;
557 goto out;
558 }
559
560 if (ior->io_mode & D_NOWAIT) {
561 rc = D_WOULD_BLOCK;
562 goto out;
563 }
564
565 }
566
567 if (tp->t_inq.c_cc <= 0 ||
568 (tp->t_state & TS_CARR_ON) == 0) {
569
570 ior->io_dev_ptr = (char *)tp;
571 queue_delayed_reply(&tp->t_delayed_read, ior, char_read_done);
572 rc = D_IO_QUEUED;
573 goto out;
574 }
575
576 ior->io_residual = ior->io_count - q_to_b(&tp->t_inq,
577 ior->io_data,
578 (int)ior->io_count);
579 out:
580 simple_unlock(&tp->t_lock);
581 splx(s);
582 return rc;
583 }
584
585 /*
586 * Retry wait for characters, for read.
587 * No locks may be held.
588 * May run on any CPU - does not talk to device driver.
589 */
590 boolean_t char_read_done(
591 register io_req_t ior)
592 {
593 register struct tty *tp = (struct tty *)ior->io_dev_ptr;
594 register spl_t s = spltty();
595
596 simple_lock(&tp->t_lock);
597
598 if (tp->t_inq.c_cc <= 0 ||
599 (tp->t_state & TS_CARR_ON) == 0) {
600
601 queue_delayed_reply(&tp->t_delayed_read, ior, char_read_done);
602 simple_unlock(&tp->t_lock);
603 splx(s);
604 return FALSE;
605 }
606
607 ior->io_residual = ior->io_count - q_to_b(&tp->t_inq,
608 ior->io_data,
609 (int)ior->io_count);
610 simple_unlock(&tp->t_lock);
611 splx(s);
612
613 (void) ds_read_done(ior);
614 return TRUE;
615 }
616
617 boolean_t tty_close_read_reply(
618 register io_req_t ior)
619 {
620 ior->io_residual = ior->io_count;
621 ior->io_error = D_DEVICE_DOWN;
622 (void) ds_read_done(ior);
623 return TRUE;
624 }
625
626 /*
627 * Close the tty.
628 * Tty must be locked (at spltty).
629 * Iff modem control should run on master.
630 */
631 void ttyclose(
632 register struct tty *tp)
633 {
634 register io_req_t ior;
635
636 /*
637 * Flush the read and write queues. Signal
638 * the open queue so that those waiting for open
639 * to complete will see that the tty is closed.
640 */
641 while ((ior = (io_req_t)dequeue_head(&tp->t_delayed_read)) != 0) {
642 ior->io_done = tty_close_read_reply;
643 iodone(ior);
644 }
645 while ((ior = (io_req_t)dequeue_head(&tp->t_delayed_write)) != 0) {
646 ior->io_done = tty_close_write_reply;
647 iodone(ior);
648 }
649 while ((ior = (io_req_t)dequeue_head(&tp->t_delayed_open)) != 0) {
650 ior->io_done = tty_close_open_reply;
651 iodone(ior);
652 }
653
654 /* Close down modem */
655 if (tp->t_mctl) {
656 (*tp->t_mctl)(tp, TM_BRK|TM_RTS, DMBIC);
657 if ((tp->t_state&(TS_HUPCLS|TS_WOPEN)) || (tp->t_state&TS_ISOPEN)==0)
658 (*tp->t_mctl)(tp, TM_HUP, DMSET);
659 }
660
661 /* only save buffering bit, and carrier */
662 tp->t_state = tp->t_state & (TS_MIN|TS_CARR_ON);
663 }
664
665 /*
666 * Port-death routine to clean up reply messages.
667 */
668 boolean_t
669 tty_queue_clean(
670 queue_t q,
671 ipc_port_t port,
672 boolean_t (*routine)(io_req_t) )
673 {
674 register io_req_t ior;
675
676 ior = (io_req_t)queue_first(q);
677 while (!queue_end(q, (queue_entry_t)ior)) {
678 if (ior->io_reply_port == port) {
679 remqueue(q, (queue_entry_t)ior);
680 ior->io_done = routine;
681 iodone(ior);
682 return TRUE;
683 }
684 ior = ior->io_next;
685 }
686 return FALSE;
687 }
688
689 /*
690 * Handle port-death (dead reply port) for tty.
691 * No locks may be held.
692 * May run on any CPU.
693 */
694 boolean_t
695 tty_portdeath(
696 struct tty * tp,
697 ipc_port_t port)
698 {
699 register spl_t spl = spltty();
700 register boolean_t result;
701
702 simple_lock(&tp->t_lock);
703
704 /*
705 * The queues may never have been initialized
706 */
707 if (tp->t_delayed_read.next == 0) {
708 result = FALSE;
709 }
710 else {
711 result =
712 tty_queue_clean(&tp->t_delayed_read, port,
713 tty_close_read_reply)
714 || tty_queue_clean(&tp->t_delayed_write, port,
715 tty_close_write_reply)
716 || tty_queue_clean(&tp->t_delayed_open, port,
717 tty_close_open_reply);
718 }
719 simple_unlock(&tp->t_lock);
720 splx(spl);
721
722 return result;
723 }
724
725 /*
726 * Get TTY status.
727 * No locks may be held.
728 * May run on any CPU.
729 */
730 io_return_t tty_get_status(
731 register struct tty *tp,
732 dev_flavor_t flavor,
733 int * data, /* pointer to OUT array */
734 natural_t *count) /* out */
735 {
736 spl_t s;
737
738 switch (flavor) {
739 case TTY_STATUS:
740 {
741 register struct tty_status *tsp =
742 (struct tty_status *) data;
743
744 if (*count < TTY_STATUS_COUNT)
745 return D_INVALID_OPERATION;
746
747 s = spltty();
748 simple_lock(&tp->t_lock);
749
750 tsp->tt_ispeed = tp->t_ispeed;
751 tsp->tt_ospeed = tp->t_ospeed;
752 tsp->tt_breakc = tp->t_breakc;
753 tsp->tt_flags = tp->t_flags;
754 if (tp->t_state & TS_HUPCLS)
755 tsp->tt_flags |= TF_HUPCLS;
756
757 simple_unlock(&tp->t_lock);
758 splx(s);
759
760 *count = TTY_STATUS_COUNT;
761 break;
762
763 }
764 default:
765 return D_INVALID_OPERATION;
766 }
767 return D_SUCCESS;
768 }
769
770 /*
771 * Set TTY status.
772 * No locks may be held.
773 * Calls device start or stop routines; must already be on master if
774 * device needs to run on master.
775 */
776 io_return_t tty_set_status(
777 register struct tty *tp,
778 dev_flavor_t flavor,
779 int * data,
780 natural_t count)
781 {
782 int s;
783
784 switch (flavor) {
785 case TTY_FLUSH:
786 {
787 register int flags;
788 if (count < TTY_FLUSH_COUNT)
789 return D_INVALID_OPERATION;
790
791 flags = *data;
792 if (flags == 0)
793 flags = D_READ | D_WRITE;
794
795 s = spltty();
796 simple_lock(&tp->t_lock);
797 tty_flush(tp, flags);
798 simple_unlock(&tp->t_lock);
799 splx(s);
800
801 break;
802 }
803 case TTY_STOP:
804 /* stop output */
805 s = spltty();
806 simple_lock(&tp->t_lock);
807 if ((tp->t_state & TS_TTSTOP) == 0) {
808 tp->t_state |= TS_TTSTOP;
809 (*tp->t_stop)(tp, 0);
810 }
811 simple_unlock(&tp->t_lock);
812 splx(s);
813 break;
814
815 case TTY_START:
816 /* start output */
817 s = spltty();
818 simple_lock(&tp->t_lock);
819 if (tp->t_state & TS_TTSTOP) {
820 tp->t_state &= ~TS_TTSTOP;
821 tty_output(tp);
822 }
823 simple_unlock(&tp->t_lock);
824 splx(s);
825 break;
826
827 case TTY_STATUS:
828 /* set special characters and speed */
829 {
830 register struct tty_status *tsp;
831
832 if (count < TTY_STATUS_COUNT)
833 return D_INVALID_OPERATION;
834
835 tsp = (struct tty_status *)data;
836
837 if (tsp->tt_ispeed < 0 ||
838 tsp->tt_ispeed >= NSPEEDS ||
839 tsp->tt_ospeed < 0 ||
840 tsp->tt_ospeed >= NSPEEDS)
841 {
842 return D_INVALID_OPERATION;
843 }
844
845 s = spltty();
846 simple_lock(&tp->t_lock);
847
848 tp->t_ispeed = tsp->tt_ispeed;
849 tp->t_ospeed = tsp->tt_ospeed;
850 tp->t_breakc = tsp->tt_breakc;
851 tp->t_flags = tsp->tt_flags & ~TF_HUPCLS;
852 if (tsp->tt_flags & TF_HUPCLS)
853 tp->t_state |= TS_HUPCLS;
854
855 simple_unlock(&tp->t_lock);
856 splx(s);
857 break;
858 }
859 default:
860 return D_INVALID_OPERATION;
861 }
862 return D_SUCCESS;
863 }
864
865
866 /*
867 * [internal]
868 * Queue IOR on reply queue, to wait for TTY operation.
869 * TTY must be locked (at spltty).
870 */
871 void queue_delayed_reply(
872 queue_t qh,
873 io_req_t ior,
874 boolean_t (*io_done)(io_req_t) )
875 {
876 ior->io_done = io_done;
877 enqueue_tail(qh, (queue_entry_t)ior);
878 }
879
880 /*
881 * Retry delayed IO operations for TTY.
882 * TTY containing queue must be locked (at spltty).
883 */
884 void tty_queue_completion(
885 register queue_t qh)
886 {
887 register io_req_t ior;
888
889 while ((ior = (io_req_t)dequeue_head(qh)) != 0) {
890 iodone(ior);
891 }
892 }
893
894 /*
895 * Set the default special characters.
896 * Since this routine is called whenever a tty has never been opened,
897 * we can initialize the queues here.
898 */
899 void ttychars(
900 register struct tty *tp)
901 {
902 if ((tp->t_flags & TS_INIT) == 0) {
903 /*
904 * Initialize queues
905 */
906 queue_init(&tp->t_delayed_open);
907 queue_init(&tp->t_delayed_read);
908 queue_init(&tp->t_delayed_write);
909
910 /*
911 * Initialize character buffers
912 */
913 cb_alloc(&tp->t_inq, tty_inq_size);
914
915 /* if we might do modem flow control */
916 if (tp->t_mctl && tp->t_inq.c_hog > 30)
917 tp->t_inq.c_hog -= 30;
918
919 cb_alloc(&tp->t_outq, tty_outq_size);
920
921 /*
922 * Mark initialized
923 */
924 tp->t_state |= TS_INIT;
925 }
926
927 tp->t_breakc = 0;
928 }
929
930 /*
931 * Flush all TTY queues.
932 * Called at spltty, tty already locked.
933 * Calls device STOP routine; must already be on master if
934 * device needs to run on master.
935 */
936 void tty_flush(
937 register struct tty *tp,
938 int rw)
939 {
940 if (rw & D_READ) {
941 cb_clear(&tp->t_inq);
942 tty_queue_completion(&tp->t_delayed_read);
943 }
944 if (rw & D_WRITE) {
945 tp->t_state &= ~TS_TTSTOP;
946 (*tp->t_stop)(tp, rw);
947 cb_clear(&tp->t_outq);
948 tty_queue_completion(&tp->t_delayed_write);
949 }
950 }
951
952 /*
953 * Restart character output after a delay timeout.
954 * Calls device start routine - must be on master CPU.
955 *
956 * Timeout routines are called only on master CPU.
957 * What if device runs on a different CPU?
958 */
959 void ttrstrt(
960 register struct tty *tp)
961 {
962 register spl_t s;
963
964 s = spltty();
965 simple_lock(&tp->t_lock);
966
967 tp->t_state &= ~TS_TIMEOUT;
968 if ((tp->t_state & (TS_TTSTOP | TS_BUSY)) == 0) {
969 /*
970 * Not busy - start output.
971 */
972 (*tp->t_start)(tp);
973
974 /*
975 * If output buffer has been drained,
976 * wake up writers.
977 */
978 if (tp->t_outq.c_cc <= TTLOWAT(tp))
979 tty_queue_completion(&tp->t_delayed_write);
980 }
981
982 simple_unlock(&tp->t_lock);
983 splx(s);
984 }
985
986 /*
987 * Start character output, if the device is not busy or
988 * stopped or waiting for a timeout.
989 *
990 * Called at spltty, tty already locked.
991 * Must be on master CPU if device runs on master.
992 */
993 void tty_output(
994 register struct tty *tp)
995 {
996 if ((tp->t_state & (TS_TIMEOUT|TS_TTSTOP|TS_BUSY)) == 0) {
997 /*
998 * Not busy. Start output.
999 */
1000 (*tp->t_start)(tp);
1001
1002 /*
1003 * Wake up those waiting for write completion.
1004 */
1005 if (tp->t_outq.c_cc <= TTLOWAT(tp))
1006 tty_queue_completion(&tp->t_delayed_write);
1007 }
1008 }
1009
1010 /*
1011 * Send any buffered recvd chars up to user
1012 */
1013 void ttypush(
1014 register struct tty *tp)
1015 {
1016 spl_t s = spltty();
1017 register int state;
1018
1019 simple_lock(&tp->t_lock);
1020
1021 /*
1022 The pdma timeout has gone off.
1023 If no character has been received since the timeout
1024 was set, push any pending characters up.
1025 If any characters were received in the last interval
1026 then just reset the timeout and the character received bit.
1027 */
1028
1029 state = tp->t_state;
1030
1031 if (state & TS_MIN_TO)
1032 {
1033 if (state & TS_MIN_TO_RCV)
1034 { /* a character was received */
1035 tp->t_state = state & ~TS_MIN_TO_RCV;
1036 timeout(ttypush,tp,pdma_timeouts[tp->t_ispeed]);
1037 }
1038 else
1039 {
1040 tp->t_state = state & ~TS_MIN_TO;
1041 if (tp->t_inq.c_cc) /* pending characters */
1042 tty_queue_completion(&tp->t_delayed_read);
1043 }
1044 }
1045 else
1046 {
1047 tp->t_state = state & ~TS_MIN_TO_RCV;/* sanity */
1048 }
1049
1050 simple_unlock(&tp->t_lock);
1051 splx(s);
1052 }
1053
1054 /*
1055 * Put input character on input queue.
1056 *
1057 * Called at spltty, tty already locked.
1058 */
1059 void ttyinput(
1060 unsigned int c,
1061 struct tty *tp)
1062 {
1063 if (tp->t_inq.c_cc >= tp->t_inq.c_hog) {
1064 /*
1065 * Do not want to overflow input queue
1066 */
1067 if (tp->t_mctl) {
1068 (*tp->t_mctl)(tp, TM_RTS, DMBIC);
1069 tp->t_state |= TS_RTS_DOWN;
1070 }
1071 tty_queue_completion(&tp->t_delayed_read);
1072 return;
1073
1074 } else if (tp->t_state & TS_RTS_DOWN) {
1075 (*tp->t_mctl)(tp, TM_RTS, DMBIS);
1076 tp->t_state &= ~TS_RTS_DOWN;
1077 }
1078
1079 c &= 0xff;
1080
1081 (void) putc(c, &tp->t_inq);
1082 if ((tp->t_state & TS_MIN) == 0 ||
1083 tp->t_inq.c_cc > pdma_water_mark[tp->t_ispeed])
1084 {
1085 /*
1086 * No input buffering, or input minimum exceeded.
1087 * Grab a request from input queue and queue it
1088 * to io_done thread.
1089 */
1090 if (tp->t_state & TS_MIN_TO) {
1091 tp->t_state &= ~(TS_MIN_TO|TS_MIN_TO_RCV);
1092 untimeout(ttypush, tp);
1093 }
1094 tty_queue_completion(&tp->t_delayed_read);
1095 }
1096 else {
1097 /*
1098 * Not enough characters.
1099 * If no timeout is set, initiate the timeout
1100 * Otherwise set the character received during timeout interval
1101 * flag.
1102 * One alternative approach would be just to reset the timeout
1103 * into the future, but this involves making a timeout/untimeout
1104 * call on every character.
1105 */
1106 register int ptime = pdma_timeouts[tp->t_ispeed];
1107 if (ptime > 0)
1108 {
1109 if ((tp->t_state & TS_MIN_TO) == 0)
1110 {
1111 tp->t_state |= TS_MIN_TO;
1112 timeout(ttypush, tp, ptime);
1113 }
1114 else
1115 {
1116 tp->t_state |= TS_MIN_TO_RCV;
1117 }
1118 }
1119 }
1120 }
1121
1122 /*
1123 * Put many characters on input queue.
1124 *
1125 * Called at spltty, tty already locked.
1126 */
1127 void ttyinput_many(
1128 struct tty *tp,
1129 unsigned char *chars,
1130 int count)
1131 {
1132 /*
1133 * Do not want to overflow input queue
1134 */
1135 if (tp->t_inq.c_cc < tp->t_inq.c_hog)
1136 count -= b_to_q( chars, count, &tp->t_inq);
1137
1138 tty_queue_completion(&tp->t_delayed_read);
1139 }
1140
1141
1142 /*
1143 * Handle modem control transition on a tty.
1144 * Flag indicates new state of carrier.
1145 * Returns FALSE if the line should be turned off.
1146 *
1147 * Called at spltty, tty already locked.
1148 */
1149 boolean_t ttymodem(
1150 struct tty * tp,
1151 boolean_t carrier_up)
1152 {
1153 if ((tp->t_state&TS_WOPEN) == 0 && (tp->t_flags & MDMBUF)) {
1154 /*
1155 * Flow control by carrier. Carrier down stops
1156 * output; carrier up restarts output.
1157 */
1158 if (carrier_up) {
1159 tp->t_state &= ~TS_TTSTOP;
1160 tty_output(tp);
1161 }
1162 else if ((tp->t_state&TS_TTSTOP) == 0) {
1163 tp->t_state |= TS_TTSTOP;
1164 (*tp->t_stop)(tp, 0);
1165 }
1166 }
1167 else if (carrier_up) {
1168 /*
1169 * Carrier now on.
1170 */
1171 tp->t_state |= TS_CARR_ON;
1172 tt_open_wakeup(tp);
1173 }
1174 else {
1175 /*
1176 * Lost carrier.
1177 */
1178 tp->t_state &= ~TS_CARR_ON;
1179 if (tp->t_state & TS_ISOPEN &&
1180 (tp->t_flags & NOHANG) == 0)
1181 {
1182 /*
1183 * Hang up TTY if carrier drops.
1184 * Need to alert users, somehow...
1185 */
1186 tty_flush(tp, D_READ|D_WRITE);
1187 return FALSE;
1188 }
1189 }
1190 return TRUE;
1191 }
1192
1193 /*
1194 * Similarly, handle transitions on the ClearToSend
1195 * signal. Nowadays, it is used by many modems as
1196 * a flow-control device: they turn it down to stop
1197 * us from sending more chars. We do the same with
1198 * the RequestToSend signal. [Yes, that is exactly
1199 * why those signals are defined in the standard.]
1200 *
1201 * Tty must be locked and on master.
1202 */
1203 void tty_cts(
1204 struct tty * tp,
1205 boolean_t cts_up)
1206 {
1207 if (tp->t_state & TS_ISOPEN){
1208 if (cts_up) {
1209 tp->t_state &= ~(TS_TTSTOP|TS_BUSY);
1210 tty_output(tp);
1211 } else {
1212 tp->t_state |= (TS_TTSTOP|TS_BUSY);
1213 (*tp->t_stop)(tp, D_WRITE);
1214 }
1215 }
1216 }
Cache object: 46f0790527e2117047d1bdc3a14c35c8
|