FreeBSD kernel kern code
kern_cons.c
Go to the documentation of this file.
1/*-
2 * SPDX-License-Identifier: BSD-3-Clause
3 *
4 * Copyright (c) 1988 University of Utah.
5 * Copyright (c) 1991 The Regents of the University of California.
6 * Copyright (c) 1999 Michael Smith
7 * Copyright (c) 2005 Pawel Jakub Dawidek <pjd@FreeBSD.org>
8 *
9 * All rights reserved.
10 *
11 * This code is derived from software contributed to Berkeley by
12 * the Systems Programming Group of the University of Utah Computer
13 * Science Department.
14 *
15 * Redistribution and use in source and binary forms, with or without
16 * modification, are permitted provided that the following conditions
17 * are met:
18 * 1. Redistributions of source code must retain the above copyright
19 * notice, this list of conditions and the following disclaimer.
20 * 2. Redistributions in binary form must reproduce the above copyright
21 * notice, this list of conditions and the following disclaimer in the
22 * documentation and/or other materials provided with the distribution.
23 * 3. Neither the name of the University nor the names of its contributors
24 * may be used to endorse or promote products derived from this software
25 * without specific prior written permission.
26 *
27 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
28 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
31 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37 * SUCH DAMAGE.
38 *
39 * from: @(#)cons.c 7.2 (Berkeley) 5/9/91
40 */
41
42#include <sys/cdefs.h>
43__FBSDID("$FreeBSD$");
44
45#include "opt_ddb.h"
46#include "opt_syscons.h"
47
48#include <sys/param.h>
49#include <sys/systm.h>
50#include <sys/lock.h>
51#include <sys/mutex.h>
52#include <sys/conf.h>
53#include <sys/cons.h>
54#include <sys/fcntl.h>
55#include <sys/kbio.h>
56#include <sys/kdb.h>
57#include <sys/kernel.h>
58#include <sys/malloc.h>
59#include <sys/msgbuf.h>
60#include <sys/namei.h>
61#include <sys/priv.h>
62#include <sys/proc.h>
63#include <sys/queue.h>
64#include <sys/reboot.h>
65#include <sys/sysctl.h>
66#include <sys/sbuf.h>
67#include <sys/tty.h>
68#include <sys/uio.h>
69#include <sys/vnode.h>
70
71#include <ddb/ddb.h>
72
73#include <dev/kbd/kbdreg.h>
74
75#include <machine/cpu.h>
76#include <machine/clock.h>
77
78static MALLOC_DEFINE(M_TTYCONS, "tty console", "tty console handling");
79
80struct cn_device {
81 STAILQ_ENTRY(cn_device) cnd_next;
82 struct consdev *cnd_cn;
83};
84
85#define CNDEVPATHMAX 32
86#define CNDEVTAB_SIZE 4
88static STAILQ_HEAD(, cn_device) cn_devlist =
89 STAILQ_HEAD_INITIALIZER(cn_devlist);
90
91int cons_avail_mask = 0; /* Bit mask. Each registered low level console
92 * which is currently unavailable for inpit
93 * (i.e., if it is in graphics mode) will have
94 * this bit cleared.
95 */
96
97static int cn_mute;
98SYSCTL_INT(_kern, OID_AUTO, consmute, CTLFLAG_RW, &cn_mute, 0,
99 "State of the console muting");
100
101static char *consbuf; /* buffer used by `consmsgbuf' */
102static struct callout conscallout; /* callout for outputting to constty */
103struct msgbuf consmsgbuf; /* message buffer for console tty */
104static bool console_pausing; /* pause after each line during probe */
105static const char console_pausestr[] =
106"<pause; press any key to proceed to next line or '.' to end pause mode>";
107struct tty *constty; /* pointer to console "window" tty */
108static struct mtx constty_mtx; /* Mutex for constty assignment. */
109MTX_SYSINIT(constty_mtx, &constty_mtx, "constty_mtx", MTX_DEF);
110static struct mtx cnputs_mtx; /* Mutex for cnputs(). */
111MTX_SYSINIT(cnputs_mtx, &cnputs_mtx, "cnputs_mtx", MTX_SPIN | MTX_NOWITNESS);
112
113static void constty_timeout(void *arg);
114
115static struct consdev cons_consdev;
116DATA_SET(cons_set, cons_consdev);
117SET_DECLARE(cons_set, struct consdev);
118
119/*
120 * Stub for configurations that don't actually have a keyboard driver. Inclusion
121 * of kbd.c is contingent on any number of keyboard/console drivers being
122 * present in the kernel; rather than trying to catch them all, we'll just
123 * maintain this weak kbdinit that will be overridden by the strong version in
124 * kbd.c if it's present.
125 */
126__weak_symbol void
127kbdinit(void)
128{
129
130}
131
132void
134{
135 struct consdev *best_cn, *cn, **list;
136
137 /*
138 * Check if we should mute the console (for security reasons perhaps)
139 * It can be changes dynamically using sysctl kern.consmute
140 * once we are up and going.
141 *
142 */
143 cn_mute = ((boothowto & (RB_MUTE
144 |RB_SINGLE
145 |RB_VERBOSE
146 |RB_ASKNAME)) == RB_MUTE);
147
148 /*
149 * Bring up the kbd layer just in time for cnprobe. Console drivers
150 * have a dependency on kbd being ready, so this fits nicely between the
151 * machdep callers of cninit() and MI probing/initialization of consoles
152 * here.
153 */
154 kbdinit();
155
156 /*
157 * Find the first console with the highest priority.
158 */
159 best_cn = NULL;
160 SET_FOREACH(list, cons_set) {
161 cn = *list;
162 cnremove(cn);
163 /* Skip cons_consdev. */
164 if (cn->cn_ops == NULL)
165 continue;
166 cn->cn_ops->cn_probe(cn);
167 if (cn->cn_pri == CN_DEAD)
168 continue;
169 if (best_cn == NULL || cn->cn_pri > best_cn->cn_pri)
170 best_cn = cn;
171 if (boothowto & RB_MULTIPLE) {
172 /*
173 * Initialize console, and attach to it.
174 */
175 cn->cn_ops->cn_init(cn);
176 cnadd(cn);
177 }
178 }
179 if (best_cn == NULL)
180 return;
181 if ((boothowto & RB_MULTIPLE) == 0) {
182 best_cn->cn_ops->cn_init(best_cn);
183 cnadd(best_cn);
184 }
185 if (boothowto & RB_PAUSE)
186 console_pausing = true;
187 /*
188 * Make the best console the preferred console.
189 */
190 cnselect(best_cn);
191
192#ifdef EARLY_PRINTF
193 /*
194 * Release early console.
195 */
196 early_putc = NULL;
197#endif
198}
199
200void
202{
203 console_pausing = false;
204}
205
206/* add a new physical console to back the virtual console */
207int
208cnadd(struct consdev *cn)
209{
210 struct cn_device *cnd;
211 int i;
212
213 STAILQ_FOREACH(cnd, &cn_devlist, cnd_next)
214 if (cnd->cnd_cn == cn)
215 return (0);
216 for (i = 0; i < CNDEVTAB_SIZE; i++) {
217 cnd = &cn_devtab[i];
218 if (cnd->cnd_cn == NULL)
219 break;
220 }
221 if (cnd->cnd_cn != NULL)
222 return (ENOMEM);
223 cnd->cnd_cn = cn;
224 if (cn->cn_name[0] == '\0') {
225 /* XXX: it is unclear if/where this print might output */
226 printf("WARNING: console at %p has no name\n", cn);
227 }
228 STAILQ_INSERT_TAIL(&cn_devlist, cnd, cnd_next);
229 if (STAILQ_FIRST(&cn_devlist) == cnd)
230 ttyconsdev_select(cnd->cnd_cn->cn_name);
231
232 /* Add device to the active mask. */
233 cnavailable(cn, (cn->cn_flags & CN_FLAG_NOAVAIL) == 0);
234
235 return (0);
236}
237
238void
239cnremove(struct consdev *cn)
240{
241 struct cn_device *cnd;
242 int i;
243
244 STAILQ_FOREACH(cnd, &cn_devlist, cnd_next) {
245 if (cnd->cnd_cn != cn)
246 continue;
247 if (STAILQ_FIRST(&cn_devlist) == cnd)
248 ttyconsdev_select(NULL);
249 STAILQ_REMOVE(&cn_devlist, cnd, cn_device, cnd_next);
250 cnd->cnd_cn = NULL;
251
252 /* Remove this device from available mask. */
253 for (i = 0; i < CNDEVTAB_SIZE; i++)
254 if (cnd == &cn_devtab[i]) {
255 cons_avail_mask &= ~(1 << i);
256 break;
257 }
258#if 0
259 /*
260 * XXX
261 * syscons gets really confused if console resources are
262 * freed after the system has initialized.
263 */
264 if (cn->cn_term != NULL)
265 cn->cn_ops->cn_term(cn);
266#endif
267 return;
268 }
269}
270
271void
272cnselect(struct consdev *cn)
273{
274 struct cn_device *cnd;
275
276 STAILQ_FOREACH(cnd, &cn_devlist, cnd_next) {
277 if (cnd->cnd_cn != cn)
278 continue;
279 if (cnd == STAILQ_FIRST(&cn_devlist))
280 return;
281 STAILQ_REMOVE(&cn_devlist, cnd, cn_device, cnd_next);
282 STAILQ_INSERT_HEAD(&cn_devlist, cnd, cnd_next);
283 ttyconsdev_select(cnd->cnd_cn->cn_name);
284 return;
285 }
286}
287
288void
289cnavailable(struct consdev *cn, int available)
290{
291 int i;
292
293 for (i = 0; i < CNDEVTAB_SIZE; i++) {
294 if (cn_devtab[i].cnd_cn == cn)
295 break;
296 }
297 if (available) {
298 if (i < CNDEVTAB_SIZE)
299 cons_avail_mask |= (1 << i);
300 cn->cn_flags &= ~CN_FLAG_NOAVAIL;
301 } else {
302 if (i < CNDEVTAB_SIZE)
303 cons_avail_mask &= ~(1 << i);
304 cn->cn_flags |= CN_FLAG_NOAVAIL;
305 }
306}
307
308int
310{
311
312 return (cons_avail_mask == 0);
313}
314
315/*
316 * sysctl_kern_console() provides output parseable in conscontrol(1).
317 */
318static int
319sysctl_kern_console(SYSCTL_HANDLER_ARGS)
320{
321 struct cn_device *cnd;
322 struct consdev *cp, **list;
323 char *p;
324 bool delete;
325 int error;
326 struct sbuf *sb;
327
328 sb = sbuf_new(NULL, NULL, CNDEVPATHMAX * 2, SBUF_AUTOEXTEND |
329 SBUF_INCLUDENUL);
330 if (sb == NULL)
331 return (ENOMEM);
332 sbuf_clear(sb);
333 STAILQ_FOREACH(cnd, &cn_devlist, cnd_next)
334 sbuf_printf(sb, "%s,", cnd->cnd_cn->cn_name);
335 sbuf_printf(sb, "/");
336 SET_FOREACH(list, cons_set) {
337 cp = *list;
338 if (cp->cn_name[0] != '\0')
339 sbuf_printf(sb, "%s,", cp->cn_name);
340 }
341 sbuf_finish(sb);
342 error = sysctl_handle_string(oidp, sbuf_data(sb), sbuf_len(sb), req);
343 if (error == 0 && req->newptr != NULL) {
344 p = sbuf_data(sb);
345 error = ENXIO;
346 delete = false;
347 if (*p == '-') {
348 delete = true;
349 p++;
350 }
351 SET_FOREACH(list, cons_set) {
352 cp = *list;
353 if (strcmp(p, cp->cn_name) != 0)
354 continue;
355 if (delete) {
356 cnremove(cp);
357 error = 0;
358 } else {
359 error = cnadd(cp);
360 if (error == 0)
361 cnselect(cp);
362 }
363 break;
364 }
365 }
366 sbuf_delete(sb);
367 return (error);
368}
369
370SYSCTL_PROC(_kern, OID_AUTO, console,
371 CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_NEEDGIANT, 0, 0,
373 "Console device control");
374
375void
377{
378 struct cn_device *cnd;
379 struct consdev *cn;
380
381 STAILQ_FOREACH(cnd, &cn_devlist, cnd_next) {
382 cn = cnd->cnd_cn;
383 if (!kdb_active || !(cn->cn_flags & CN_FLAG_NODEBUG))
384 cn->cn_ops->cn_grab(cn);
385 }
386}
387
388void
390{
391 struct cn_device *cnd;
392 struct consdev *cn;
393
394 STAILQ_FOREACH(cnd, &cn_devlist, cnd_next) {
395 cn = cnd->cnd_cn;
396 if (!kdb_active || !(cn->cn_flags & CN_FLAG_NODEBUG))
397 cn->cn_ops->cn_ungrab(cn);
398 }
399}
400
401void
403{
404 struct cn_device *cnd;
405 struct consdev *cn;
406
407 STAILQ_FOREACH(cnd, &cn_devlist, cnd_next) {
408 cn = cnd->cnd_cn;
409 if (cn->cn_ops->cn_resume != NULL)
410 cn->cn_ops->cn_resume(cn);
411 }
412}
413
414/*
415 * Low level console routines.
416 */
417int
419{
420 int c;
421
422 if (cn_mute)
423 return (-1);
424 while ((c = cncheckc()) == -1)
425 cpu_spinwait();
426 if (c == '\r')
427 c = '\n'; /* console input is always ICRNL */
428 return (c);
429}
430
431int
433{
434 struct cn_device *cnd;
435 struct consdev *cn;
436 int c;
437
438 if (cn_mute)
439 return (-1);
440 STAILQ_FOREACH(cnd, &cn_devlist, cnd_next) {
441 cn = cnd->cnd_cn;
442 if (!kdb_active || !(cn->cn_flags & CN_FLAG_NODEBUG)) {
443 c = cn->cn_ops->cn_getc(cn);
444 if (c != -1)
445 return (c);
446 }
447 }
448 return (-1);
449}
450
451void
452cngets(char *cp, size_t size, int visible)
453{
454 char *lp, *end;
455 int c;
456
457 cngrab();
458
459 lp = cp;
460 end = cp + size - 1;
461 for (;;) {
462 c = cngetc() & 0177;
463 switch (c) {
464 case '\n':
465 case '\r':
466 cnputc(c);
467 *lp = '\0';
468 cnungrab();
469 return;
470 case '\b':
471 case '\177':
472 if (lp > cp) {
473 if (visible)
474 cnputs("\b \b");
475 lp--;
476 }
477 continue;
478 case '\0':
479 continue;
480 default:
481 if (lp < end) {
482 switch (visible) {
483 case GETS_NOECHO:
484 break;
485 case GETS_ECHOPASS:
486 cnputc('*');
487 break;
488 default:
489 cnputc(c);
490 break;
491 }
492 *lp++ = c;
493 }
494 }
495 }
496}
497
498void
499cnputc(int c)
500{
501 struct cn_device *cnd;
502 struct consdev *cn;
503 const char *cp;
504
505#ifdef EARLY_PRINTF
506 if (early_putc != NULL) {
507 if (c == '\n')
508 early_putc('\r');
509 early_putc(c);
510 return;
511 }
512#endif
513
514 if (cn_mute || c == '\0')
515 return;
516 STAILQ_FOREACH(cnd, &cn_devlist, cnd_next) {
517 cn = cnd->cnd_cn;
518 if (!kdb_active || !(cn->cn_flags & CN_FLAG_NODEBUG)) {
519 if (c == '\n')
520 cn->cn_ops->cn_putc(cn, '\r');
521 cn->cn_ops->cn_putc(cn, c);
522 }
523 }
524 if (console_pausing && c == '\n' && !kdb_active) {
525 for (cp = console_pausestr; *cp != '\0'; cp++)
526 cnputc(*cp);
527 cngrab();
528 if (cngetc() == '.')
529 console_pausing = false;
530 cnungrab();
531 cnputc('\r');
532 for (cp = console_pausestr; *cp != '\0'; cp++)
533 cnputc(' ');
534 cnputc('\r');
535 }
536}
537
538void
539cnputsn(const char *p, size_t n)
540{
541 size_t i;
542 bool unlock_reqd = false;
543
544 if (mtx_initialized(&cnputs_mtx)) {
545 /*
546 * NOTE: Debug prints and/or witness printouts in
547 * console driver clients can cause the "cnputs_mtx"
548 * mutex to recurse. Simply return if that happens.
549 */
550 if (mtx_owned(&cnputs_mtx))
551 return;
552 mtx_lock_spin(&cnputs_mtx);
553 unlock_reqd = true;
554 }
555
556 for (i = 0; i < n; i++)
557 cnputc(p[i]);
558
559 if (unlock_reqd)
560 mtx_unlock_spin(&cnputs_mtx);
561}
562
563void
564cnputs(const char *p)
565{
566 cnputsn(p, strlen(p));
567}
568
569static unsigned int consmsgbuf_size = 65536;
570SYSCTL_UINT(_kern, OID_AUTO, consmsgbuf_size, CTLFLAG_RWTUN, &consmsgbuf_size,
571 0, "Console tty buffer size");
572
573/*
574 * Redirect console output to a tty.
575 */
576int
577constty_set(struct tty *tp)
578{
579 int size = consmsgbuf_size;
580 void *buf = NULL;
581
582 tty_assert_locked(tp);
583 if (constty == tp)
584 return (0);
585 if (constty != NULL)
586 return (EBUSY);
587
588 if (consbuf == NULL) {
589 tty_unlock(tp);
590 buf = malloc(size, M_TTYCONS, M_WAITOK);
591 tty_lock(tp);
592 }
593 mtx_lock(&constty_mtx);
594 if (constty != NULL) {
595 mtx_unlock(&constty_mtx);
596 free(buf, M_TTYCONS);
597 return (EBUSY);
598 }
599 if (consbuf == NULL) {
600 consbuf = buf;
601 msgbuf_init(&consmsgbuf, buf, size);
602 } else
603 free(buf, M_TTYCONS);
604 constty = tp;
605 mtx_unlock(&constty_mtx);
606
607 callout_init_mtx(&conscallout, tty_getlock(tp), 0);
608 constty_timeout(tp);
609 return (0);
610}
611
612/*
613 * Disable console redirection to a tty.
614 */
615int
616constty_clear(struct tty *tp)
617{
618 int c;
619
620 tty_assert_locked(tp);
621 if (constty != tp)
622 return (ENXIO);
623 callout_stop(&conscallout);
624 mtx_lock(&constty_mtx);
625 constty = NULL;
626 mtx_unlock(&constty_mtx);
627 while ((c = msgbuf_getchar(&consmsgbuf)) != -1)
628 cnputc(c);
629 /* We never free consbuf because it can still be in use. */
630 return (0);
631}
632
633/* Times per second to check for pending console tty messages. */
635SYSCTL_INT(_kern, OID_AUTO, constty_wakeups_per_second, CTLFLAG_RW,
637 "Times per second to check for pending console tty messages");
638
639static void
641{
642 struct tty *tp = arg;
643 int c;
644
645 tty_assert_locked(tp);
646 while ((c = msgbuf_getchar(&consmsgbuf)) != -1) {
647 if (tty_putchar(tp, c) < 0) {
648 constty_clear(tp);
649 return;
650 }
651 }
652 callout_reset_sbt(&conscallout, SBT_1S / constty_wakeups_per_second,
653 0, constty_timeout, tp, C_PREL(1));
654}
655
656/*
657 * Sysbeep(), if we have hardware for it
658 */
659
660#ifdef HAS_TIMER_SPKR
661
662static bool beeping;
663static struct callout beeping_timer;
664
665static void
666sysbeepstop(void *chan)
667{
668
669 timer_spkr_release();
670 beeping = false;
671}
672
673int
674sysbeep(int pitch, sbintime_t duration)
675{
676
677 if (timer_spkr_acquire()) {
678 if (!beeping) {
679 /* Something else owns it. */
680 return (EBUSY);
681 }
682 }
683 timer_spkr_setfreq(pitch);
684 if (!beeping) {
685 beeping = true;
686 callout_reset_sbt(&beeping_timer, duration, 0, sysbeepstop,
687 NULL, C_PREL(5));
688 }
689 return (0);
690}
691
692static void
693sysbeep_init(void *unused)
694{
695
696 callout_init(&beeping_timer, 1);
697}
698SYSINIT(sysbeep, SI_SUB_SOFTINTR, SI_ORDER_ANY, sysbeep_init, NULL);
699#else
700
701/*
702 * No hardware, no sound
703 */
704
705int
706sysbeep(int pitch __unused, sbintime_t duration __unused)
707{
708
709 return (ENODEV);
710}
711
712#endif
713
714/*
715 * Temporary support for sc(4) to vt(4) transition.
716 */
717static unsigned vty_prefer;
718static char vty_name[16];
719SYSCTL_STRING(_kern, OID_AUTO, vty, CTLFLAG_RDTUN | CTLFLAG_NOFETCH, vty_name,
720 0, "Console vty driver");
721
722int
723vty_enabled(unsigned vty)
724{
725 static unsigned vty_selected = 0;
726
727 if (vty_selected == 0) {
728 TUNABLE_STR_FETCH("kern.vty", vty_name, sizeof(vty_name));
729 do {
730#if defined(DEV_SC)
731 if (strcmp(vty_name, "sc") == 0) {
732 vty_selected = VTY_SC;
733 break;
734 }
735#endif
736#if defined(DEV_VT)
737 if (strcmp(vty_name, "vt") == 0) {
738 vty_selected = VTY_VT;
739 break;
740 }
741#endif
742 if (vty_prefer != 0) {
743 vty_selected = vty_prefer;
744 break;
745 }
746#if defined(DEV_VT)
747 vty_selected = VTY_VT;
748#elif defined(DEV_SC)
749 vty_selected = VTY_SC;
750#endif
751 } while (0);
752
753 if (vty_selected == VTY_VT)
754 strcpy(vty_name, "vt");
755 else if (vty_selected == VTY_SC)
756 strcpy(vty_name, "sc");
757 }
758 return ((vty_selected & vty) != 0);
759}
760
761void
762vty_set_preferred(unsigned vty)
763{
764
765 vty_prefer = vty;
766#if !defined(DEV_SC)
767 vty_prefer &= ~VTY_SC;
768#endif
769#if !defined(DEV_VT)
770 vty_prefer &= ~VTY_VT;
771#endif
772}
SYSINIT(imgact_binmisc, SI_SUB_EXEC, SI_ORDER_MIDDLE, imgact_binmisc_init, NULL)
int boothowto
Definition: init_main.c:124
SET_DECLARE(sysinit_set, struct sysinit)
SYSCTL_STRING(_kern, OID_AUTO, vty, CTLFLAG_RDTUN|CTLFLAG_NOFETCH, vty_name, 0, "Console vty driver")
SYSCTL_UINT(_kern, OID_AUTO, consmsgbuf_size, CTLFLAG_RWTUN, &consmsgbuf_size, 0, "Console tty buffer size")
static int constty_wakeups_per_second
Definition: kern_cons.c:634
static unsigned vty_prefer
Definition: kern_cons.c:717
void cngets(char *cp, size_t size, int visible)
Definition: kern_cons.c:452
static struct cn_device cn_devtab[CNDEVTAB_SIZE]
Definition: kern_cons.c:87
void cnavailable(struct consdev *cn, int available)
Definition: kern_cons.c:289
void vty_set_preferred(unsigned vty)
Definition: kern_cons.c:762
static void constty_timeout(void *arg)
Definition: kern_cons.c:640
int cnadd(struct consdev *cn)
Definition: kern_cons.c:208
static int sysctl_kern_console(SYSCTL_HANDLER_ARGS)
Definition: kern_cons.c:319
void cngrab()
Definition: kern_cons.c:376
int sysbeep(int pitch __unused, sbintime_t duration __unused)
Definition: kern_cons.c:706
static STAILQ_HEAD(cn_device)
Definition: kern_cons.c:88
int cngetc(void)
Definition: kern_cons.c:418
static unsigned int consmsgbuf_size
Definition: kern_cons.c:569
SYSCTL_PROC(_kern, OID_AUTO, console, CTLTYPE_STRING|CTLFLAG_RW|CTLFLAG_NEEDGIANT, 0, 0, sysctl_kern_console, "A", "Console device control")
void cnputc(int c)
Definition: kern_cons.c:499
SYSCTL_INT(_kern, OID_AUTO, constty_wakeups_per_second, CTLFLAG_RW, &constty_wakeups_per_second, 0, "Times per second to check for pending console tty messages")
void cnputsn(const char *p, size_t n)
Definition: kern_cons.c:539
void cnungrab()
Definition: kern_cons.c:389
static MALLOC_DEFINE(M_TTYCONS, "tty console", "tty console handling")
__FBSDID("$FreeBSD$")
int vty_enabled(unsigned vty)
Definition: kern_cons.c:723
void cninit_finish()
Definition: kern_cons.c:201
int constty_clear(struct tty *tp)
Definition: kern_cons.c:616
#define CNDEVPATHMAX
Definition: kern_cons.c:85
void cnputs(const char *p)
Definition: kern_cons.c:564
int cncheckc(void)
Definition: kern_cons.c:432
void cnselect(struct consdev *cn)
Definition: kern_cons.c:272
#define CNDEVTAB_SIZE
Definition: kern_cons.c:86
static char vty_name[16]
Definition: kern_cons.c:718
void cnresume()
Definition: kern_cons.c:402
void cninit(void)
Definition: kern_cons.c:133
int constty_set(struct tty *tp)
Definition: kern_cons.c:577
void cnremove(struct consdev *cn)
Definition: kern_cons.c:239
int cnunavailable(void)
Definition: kern_cons.c:309
MTX_SYSINIT(et_eventtimers_init, &et_eventtimers_mtx, "et_mtx", MTX_DEF)
void *() malloc(size_t size, struct malloc_type *mtp, int flags)
Definition: kern_malloc.c:632
void free(void *addr, struct malloc_type *mtp)
Definition: kern_malloc.c:907
int sysctl_handle_string(SYSCTL_HANDLER_ARGS)
Definition: kern_sysctl.c:1778
void callout_init(struct callout *c, int mpsafe)
u_char __read_frequently kdb_active
Definition: subr_kdb.c:56
int msgbuf_getchar(struct msgbuf *mbp)
Definition: subr_msgbuf.c:283
void msgbuf_init(struct msgbuf *mbp, void *ptr, int size)
Definition: subr_msgbuf.c:66
int printf(const char *fmt,...)
Definition: subr_prf.c:397
int sbuf_finish(struct sbuf *s)
Definition: subr_sbuf.c:833
void sbuf_delete(struct sbuf *s)
Definition: subr_sbuf.c:898
int sbuf_printf(struct sbuf *s, const char *fmt,...)
Definition: subr_sbuf.c:739
ssize_t sbuf_len(struct sbuf *s)
Definition: subr_sbuf.c:877
char * sbuf_data(struct sbuf *s)
Definition: subr_sbuf.c:862
void sbuf_clear(struct sbuf *s)
Definition: subr_sbuf.c:316
struct sbuf * sbuf_new(struct sbuf *s, char *buf, int length, int flags)
Definition: subr_sbuf.c:196
void ttyconsdev_select(const char *name)
Definition: tty.c:2236
int tty_putchar(struct tty *tp, char c)
Definition: tty_ttydisc.c:1304
struct mtx mtx
Definition: uipc_ktls.c:0
struct stat * buf