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