X-Git-Url: https://gitweb.dragonflybsd.org/dragonfly.git/blobdiff_plain/50b33f0fa41002e8f234c952724f58dc08561fa3..12114ac151d2517f8f91ec2f231d09b75a39e4f9:/sys/dev/misc/syscons/syscons.c diff --git a/sys/dev/misc/syscons/syscons.c b/sys/dev/misc/syscons/syscons.c index 9994b31348..afdbef9add 100644 --- a/sys/dev/misc/syscons/syscons.c +++ b/sys/dev/misc/syscons/syscons.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 1992-1998 Søren Schmidt + * Copyright (c) 1992-1998 Søren Schmidt * All rights reserved. * * This code is derived from software contributed to The DragonFly Project @@ -35,7 +35,9 @@ #include "use_splash.h" #include "opt_syscons.h" #include "opt_ddb.h" +#ifdef __i386__ #include "use_apm.h" +#endif #include #include @@ -43,6 +45,7 @@ #include #include #include +#include #include #include #include @@ -55,7 +58,9 @@ #include #include #include +#ifdef __i386__ #include +#endif #include #include @@ -124,7 +129,8 @@ SYSCTL_INT(_machdep, OID_AUTO, enable_panic_key, CTLFLAG_RW, &enable_panic_key, (SC_DEV((sc),(x))->si_tty) : NULL) #define ISTTYOPEN(tp) ((tp) && ((tp)->t_state & TS_ISOPEN)) -static int debugger; +static int debugger; +static cdev_t cctl_dev; /* prototypes */ static int scvidprobe(int unit, int flags, int cons); @@ -174,6 +180,7 @@ static int save_kbd_state(scr_stat *scp); static int update_kbd_state(scr_stat *scp, int state, int mask); static int update_kbd_leds(scr_stat *scp, int which); static timeout_t blink_screen; +static int sc_allocate_keyboard(sc_softc_t *sc, int unit); #define CDEV_MAJOR 12 @@ -204,7 +211,8 @@ static struct dev_ops sc_ops = { .d_ioctl = scioctl, .d_poll = ttypoll, .d_mmap = scmmap, - .d_kqfilter = ttykqfilter + .d_kqfilter = ttykqfilter, + .d_revoke = ttyrevoke }; int @@ -342,7 +350,7 @@ sc_attach_unit(int unit, int flags) splash_term(sc->adp); #endif sc_set_graphics_mode(scp, NULL, M_VESA_800x600); - sc_set_pixel_mode(scp, NULL, COL, ROW, 16); + sc_set_pixel_mode(scp, NULL, 0, 0, 16); sc->initial_mode = M_VESA_800x600; #if NSPLASH > 0 /* put up the splash again! */ @@ -383,28 +391,22 @@ sc_attach_unit(int unit, int flags) (void *)(uintptr_t)unit, SHUTDOWN_PRI_DEFAULT); /* - * create devices. dev_ops_add() must be called to make devices under - * this major number available to userland. + * create devices. + * + * The first vty already has struct tty and scr_stat initialized + * in scinit(). The other vtys will have these structs when + * first opened. */ - dev_ops_add(&sc_ops, ~(MAXCONS - 1), unit * MAXCONS); - - for (vc = 0; vc < sc->vtys; vc++) { + for (vc = 1; vc < sc->vtys; vc++) { dev = make_dev(&sc_ops, vc + unit * MAXCONS, - UID_ROOT, GID_WHEEL, 0600, "ttyv%r", vc + unit * MAXCONS); + UID_ROOT, GID_WHEEL, + 0600, "ttyv%r", vc + unit * MAXCONS); sc->dev[vc] = dev; - /* - * The first vty already has struct tty and scr_stat initialized - * in scinit(). The other vtys will have these structs when - * first opened. - */ } - - dev_ops_add(&sc_ops, -1, SC_CONSOLECTL); /* XXX */ - dev = make_dev(&sc_ops, SC_CONSOLECTL, - UID_ROOT, GID_WHEEL, 0600, "consolectl"); - dev->si_tty = sc_console_tty = ttymalloc(sc_console_tty); - dev->si_drv1 = sc_console; - + cctl_dev = make_dev(&sc_ops, SC_CONSOLECTL, + UID_ROOT, GID_WHEEL, 0600, "consolectl"); + cctl_dev->si_tty = sc_console_tty = ttymalloc(sc_console_tty); + cctl_dev->si_drv1 = sc_console; return 0; } @@ -473,7 +475,9 @@ scopen(struct dev_open_args *ap) tp->t_oproc = scstart; tp->t_param = scparam; tp->t_stop = nottystop; + tp->t_dev = dev; + if (!ISTTYOPEN(tp)) { ttychars(tp); /* Use the current setting of the <-- key as default VERASE. */ @@ -492,7 +496,7 @@ scopen(struct dev_open_args *ap) (*linesw[tp->t_line].l_modem)(tp, 1); } else - if (tp->t_state & TS_XCLUDE && suser_cred(ap->a_cred, 0)) + if (tp->t_state & TS_XCLUDE && priv_check_cred(ap->a_cred, PRIV_ROOT, 0)) return(EBUSY); error = (*linesw[tp->t_line].l_open)(dev, tp); @@ -559,6 +563,7 @@ scclose(struct dev_close_args *ap) (*linesw[tp->t_line].l_close)(tp, ap->a_fflag); ttyclose(tp); crit_exit(); + return(0); } @@ -982,8 +987,8 @@ scioctl(struct dev_ioctl_args *ap) scp = SC_STAT(SC_DEV(sc, i)); if (scp == scp->sc->cur_scp) return 0; - while ((error=tsleep((caddr_t)&scp->smode, PCATCH, - "waitvt", 0)) == ERESTART) ; + error = tsleep((caddr_t)&scp->smode, PCATCH, "waitvt", 0); + /* May return ERESTART */ return error; case VT_GETACTIVE: /* get active vty # */ @@ -1002,16 +1007,24 @@ scioctl(struct dev_ioctl_args *ap) return 0; case KDENABIO: /* allow io operations */ - error = suser_cred(ap->a_cred, 0); + error = priv_check_cred(ap->a_cred, PRIV_ROOT, 0); if (error != 0) return error; if (securelevel > 0) return EPERM; +#if defined(__i386__) curthread->td_lwp->lwp_md.md_regs->tf_eflags |= PSL_IOPL; +#elif defined(__x86_64__) + curthread->td_lwp->lwp_md.md_regs->tf_rflags |= PSL_IOPL; +#endif return 0; case KDDISABIO: /* disallow io operations (default) */ +#if defined(__i386__) curthread->td_lwp->lwp_md.md_regs->tf_eflags &= ~PSL_IOPL; +#elif defined(__x86_64__) + curthread->td_lwp->lwp_md.md_regs->tf_rflags &= ~PSL_IOPL; +#endif return 0; case KDSKBSTATE: /* set keyboard state (locks) */ @@ -1108,6 +1121,13 @@ scioctl(struct dev_ioctl_args *ap) *(int *)data = scp->status & LED_MASK; return 0; + case KBADDKBD: /* add/remove keyboard to/from mux */ + case KBRELKBD: + error = kbd_ioctl(sc->kbd, cmd, data); + if (error == ENOIOCTL) + error = ENODEV; + return error; + case CONS_SETKBD: /* set the new keyboard */ { keyboard_t *newkbd; @@ -1364,8 +1384,9 @@ sccninit(struct consdev *cp) static void sccninit_fini(struct consdev *cp) { - cp->cn_dev = make_dev(&sc_ops, SC_CONSOLECTL, - UID_ROOT, GID_WHEEL, 0600, "consolectl"); + if (cctl_dev == NULL) + kprintf("sccninit_fini: WARNING: cctl_dev is NULL!\n"); + cp->cn_dev = cctl_dev; } static void @@ -1596,8 +1617,7 @@ scrn_timer(void *arg) if ((sc->kbd == NULL) && (sc->config & SC_AUTODETECT_KBD)) { /* try to allocate a keyboard automatically */ if (++kbd_interval >= 25) { - sc->keyboard = kbd_allocate("*", -1, (void *)&sc->keyboard, - sckbdevent, sc); + sc->keyboard = sc_allocate_keyboard(sc, -1); if (sc->keyboard >= 0) { sc->kbd = kbd_get_keyboard(sc->keyboard); kbd_ioctl(sc->kbd, KDSKBMODE, @@ -2008,8 +2028,9 @@ wait_scrn_saver_stop(sc_softc_t *sc) break; } error = tsleep((caddr_t)&scrn_blanked, PCATCH, "scrsav", 0); - if ((error != 0) && (error != ERESTART)) - break; + /* May return ERESTART */ + if (error) + break; } run_scrn_saver = FALSE; return error; @@ -2499,8 +2520,7 @@ scinit(int unit, int flags) sc->adapter = vid_allocate("*", unit, (void *)&sc->adapter); sc->adp = vid_get_adapter(sc->adapter); /* assert((sc->adapter >= 0) && (sc->adp != NULL)) */ - sc->keyboard = kbd_allocate("*", unit, (void *)&sc->keyboard, - sckbdevent, sc); + sc->keyboard = sc_allocate_keyboard(sc, unit); DPRINTF(1, ("sc%d: keyboard %d\n", unit, sc->keyboard)); sc->kbd = kbd_get_keyboard(sc->keyboard); if (sc->kbd != NULL) { @@ -2546,8 +2566,10 @@ scinit(int unit, int flags) } else { /* assert(sc_malloc) */ sc->dev = kmalloc(sizeof(cdev_t)*sc->vtys, M_SYSCONS, M_WAITOK | M_ZERO); + sc->dev[0] = make_dev(&sc_ops, unit*MAXCONS, UID_ROOT, GID_WHEEL, 0600, "ttyv%r", unit*MAXCONS); + sc->dev[0]->si_tty = ttymalloc(sc->dev[0]->si_tty); scp = alloc_scp(sc, sc->first_vty); sc->dev[0]->si_drv1 = scp; @@ -3450,3 +3472,41 @@ blink_screen(void *arg) callout_reset(&scp->blink_screen_ch, hz / 10, blink_screen, scp); } } + + +/* + * Allocate active keyboard. Try to allocate "kbdmux" keyboard first, and, + * if found, add all non-busy keyboards to "kbdmux". Otherwise look for + * any keyboard. + */ + +static int +sc_allocate_keyboard(sc_softc_t *sc, int unit) +{ + int idx0, idx; + keyboard_t *k0, *k; + keyboard_info_t ki; + + idx0 = kbd_allocate("kbdmux", -1, (void *)&sc->keyboard, sckbdevent, sc); + if (idx0 != -1) { + k0 = kbd_get_keyboard(idx0); + + for (idx = kbd_find_keyboard2("*", -1, 0, 0); + idx != -1; + idx = kbd_find_keyboard2("*", -1, idx + 1, 0)) { + k = kbd_get_keyboard(idx); + + if (idx == idx0 || KBD_IS_BUSY(k)) + continue; + + bzero(&ki, sizeof(ki)); + strcpy(ki.kb_name, k->kb_name); + ki.kb_unit = k->kb_unit; + + kbd_ioctl(k0, KBADDKBD, (caddr_t) &ki); + } + } else + idx0 = kbd_allocate("*", unit, (void *)&sc->keyboard, sckbdevent, sc); + + return (idx0); +}