1 1.61 tsutsui /* $NetBSD: kd.c,v 1.61 2024/12/21 17:40:11 tsutsui Exp $ */ 2 1.4 cgd 3 1.21 gwr /*- 4 1.21 gwr * Copyright (c) 1996 The NetBSD Foundation, Inc. 5 1.1 gwr * All rights reserved. 6 1.1 gwr * 7 1.21 gwr * This code is derived from software contributed to The NetBSD Foundation 8 1.21 gwr * by Gordon W. Ross. 9 1.21 gwr * 10 1.1 gwr * Redistribution and use in source and binary forms, with or without 11 1.1 gwr * modification, are permitted provided that the following conditions 12 1.1 gwr * are met: 13 1.1 gwr * 1. Redistributions of source code must retain the above copyright 14 1.1 gwr * notice, this list of conditions and the following disclaimer. 15 1.1 gwr * 2. Redistributions in binary form must reproduce the above copyright 16 1.1 gwr * notice, this list of conditions and the following disclaimer in the 17 1.1 gwr * documentation and/or other materials provided with the distribution. 18 1.1 gwr * 19 1.21 gwr * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 1.21 gwr * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 1.21 gwr * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 1.23 gwr * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 1.23 gwr * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 1.21 gwr * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 1.21 gwr * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 1.21 gwr * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 1.21 gwr * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 1.21 gwr * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 1.21 gwr * POSSIBILITY OF SUCH DAMAGE. 30 1.1 gwr */ 31 1.1 gwr 32 1.1 gwr /* 33 1.1 gwr * Keyboard/Display device. 34 1.1 gwr * 35 1.1 gwr * This driver exists simply to provide a tty device that 36 1.1 gwr * the indirect console driver can point to. 37 1.1 gwr * The kbd driver sends its input here. 38 1.20 christos * Output goes to the screen via PROM printf. 39 1.1 gwr */ 40 1.41 lukem 41 1.41 lukem #include <sys/cdefs.h> 42 1.61 tsutsui __KERNEL_RCSID(0, "$NetBSD: kd.c,v 1.61 2024/12/21 17:40:11 tsutsui Exp $"); 43 1.1 gwr 44 1.1 gwr #include <sys/param.h> 45 1.1 gwr #include <sys/proc.h> 46 1.1 gwr #include <sys/systm.h> 47 1.1 gwr #include <sys/ioctl.h> 48 1.1 gwr #include <sys/tty.h> 49 1.1 gwr #include <sys/file.h> 50 1.1 gwr #include <sys/conf.h> 51 1.1 gwr #include <sys/device.h> 52 1.45 elad #include <sys/kauth.h> 53 1.1 gwr 54 1.1 gwr #include <machine/autoconf.h> 55 1.48 tsutsui #include <machine/cpu.h> 56 1.1 gwr #include <machine/mon.h> 57 1.11 gwr #include <machine/psl.h> 58 1.1 gwr 59 1.1 gwr #include <dev/cons.h> 60 1.60 tsutsui #include <dev/sun/event_var.h> 61 1.14 gwr #include <dev/sun/kbd_xlate.h> 62 1.29 pk #include <dev/sun/kbdvar.h> 63 1.22 gwr #include <sun3/dev/zs_cons.h> 64 1.22 gwr 65 1.26 gwr #include "fb.h" 66 1.26 gwr 67 1.14 gwr #define PUT_WSIZE 64 68 1.14 gwr 69 1.14 gwr struct kd_softc { 70 1.14 gwr struct tty *kd_tty; 71 1.29 pk 72 1.29 pk /* Console input hook */ 73 1.29 pk struct cons_channel *kd_in; 74 1.14 gwr }; 75 1.1 gwr 76 1.13 gwr /* 77 1.13 gwr * There is no point in pretending there might be 78 1.13 gwr * more than one keyboard/display device. 79 1.13 gwr */ 80 1.25 gwr static struct kd_softc kd_softc; 81 1.25 gwr static int kd_is_console; 82 1.1 gwr 83 1.1 gwr static int kdparam(struct tty *, struct termios *); 84 1.1 gwr static void kdstart(struct tty *); 85 1.42 chs static void kd_init(struct kd_softc *); 86 1.42 chs static void kd_cons_input(int); 87 1.52 rjs static void kd_later(void *); 88 1.1 gwr 89 1.61 tsutsui static dev_type_open(kdopen); 90 1.61 tsutsui static dev_type_close(kdclose); 91 1.61 tsutsui static dev_type_read(kdread); 92 1.61 tsutsui static dev_type_write(kdwrite); 93 1.61 tsutsui static dev_type_ioctl(kdioctl); 94 1.61 tsutsui static dev_type_tty(kdtty); 95 1.61 tsutsui static dev_type_poll(kdpoll); 96 1.38 gehenna 97 1.38 gehenna const struct cdevsw kd_cdevsw = { 98 1.58 dholland .d_open = kdopen, 99 1.58 dholland .d_close = kdclose, 100 1.58 dholland .d_read = kdread, 101 1.58 dholland .d_write = kdwrite, 102 1.58 dholland .d_ioctl = kdioctl, 103 1.58 dholland .d_stop = nostop, 104 1.58 dholland .d_tty = kdtty, 105 1.58 dholland .d_poll = kdpoll, 106 1.58 dholland .d_mmap = nommap, 107 1.58 dholland .d_kqfilter = ttykqfilter, 108 1.59 dholland .d_discard = nodiscard, 109 1.58 dholland .d_flag = D_TTY 110 1.38 gehenna }; 111 1.10 gwr 112 1.14 gwr /* 113 1.29 pk * Prepare the console tty; called on first open of /dev/console 114 1.14 gwr */ 115 1.60 tsutsui void 116 1.42 chs kd_init(struct kd_softc *kd) 117 1.1 gwr { 118 1.14 gwr struct tty *tp; 119 1.14 gwr 120 1.56 rmind tp = tty_alloc(); 121 1.51 joerg callout_setfunc(&tp->t_rstrt_ch, kd_later, tp); 122 1.51 joerg 123 1.14 gwr tp->t_oproc = kdstart; 124 1.14 gwr tp->t_param = kdparam; 125 1.38 gehenna tp->t_dev = makedev(cdevsw_lookup_major(&kd_cdevsw), 0); 126 1.29 pk 127 1.17 gwr tty_attach(tp); 128 1.17 gwr kd->kd_tty = tp; 129 1.14 gwr 130 1.14 gwr return; 131 1.13 gwr } 132 1.13 gwr 133 1.61 tsutsui static struct tty * 134 1.42 chs kdtty(dev_t dev) 135 1.13 gwr { 136 1.14 gwr struct kd_softc *kd; 137 1.14 gwr 138 1.14 gwr kd = &kd_softc; /* XXX */ 139 1.14 gwr return (kd->kd_tty); 140 1.1 gwr } 141 1.1 gwr 142 1.61 tsutsui static int 143 1.44 christos kdopen(dev_t dev, int flag, int mode, struct lwp *l) 144 1.1 gwr { 145 1.14 gwr struct kd_softc *kd; 146 1.14 gwr int error, s, unit; 147 1.1 gwr struct tty *tp; 148 1.29 pk static int firstopen = 1; 149 1.1 gwr 150 1.1 gwr unit = minor(dev); 151 1.14 gwr if (unit != 0) 152 1.1 gwr return ENXIO; 153 1.14 gwr kd = &kd_softc; /* XXX */ 154 1.29 pk if (firstopen) { 155 1.29 pk kd_init(kd); 156 1.29 pk firstopen = 0; 157 1.29 pk } 158 1.14 gwr tp = kd->kd_tty; 159 1.3 gwr 160 1.14 gwr /* It's simpler to do this up here. */ 161 1.47 elad if (kauth_authorize_device_tty(l->l_cred, KAUTH_DEVICE_TTY_OPEN, tp)) 162 1.14 gwr return (EBUSY); 163 1.14 gwr 164 1.14 gwr s = spltty(); 165 1.14 gwr 166 1.1 gwr if ((tp->t_state & TS_ISOPEN) == 0) { 167 1.14 gwr /* First open. */ 168 1.29 pk 169 1.29 pk /* Notify the input device that serves us */ 170 1.29 pk struct cons_channel *cc = kd->kd_in; 171 1.29 pk if (cc != NULL && 172 1.29 pk (error = (*cc->cc_iopen)(cc)) != 0) { 173 1.29 pk return (error); 174 1.29 pk } 175 1.29 pk 176 1.1 gwr ttychars(tp); 177 1.1 gwr tp->t_iflag = TTYDEF_IFLAG; 178 1.1 gwr tp->t_oflag = TTYDEF_OFLAG; 179 1.1 gwr tp->t_cflag = TTYDEF_CFLAG; 180 1.1 gwr tp->t_lflag = TTYDEF_LFLAG; 181 1.1 gwr tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED; 182 1.14 gwr (void) kdparam(tp, &tp->t_termios); 183 1.1 gwr ttsetwater(tp); 184 1.14 gwr /* Flush pending input? Clear translator? */ 185 1.14 gwr /* This (pseudo)device always has SOFTCAR */ 186 1.14 gwr tp->t_state |= TS_CARR_ON; 187 1.14 gwr } 188 1.14 gwr 189 1.14 gwr splx(s); 190 1.1 gwr 191 1.34 eeh return ((*tp->t_linesw->l_open)(dev, tp)); 192 1.1 gwr } 193 1.1 gwr 194 1.61 tsutsui static int 195 1.44 christos kdclose(dev_t dev, int flag, int mode, struct lwp *l) 196 1.1 gwr { 197 1.14 gwr struct kd_softc *kd; 198 1.14 gwr struct tty *tp; 199 1.29 pk struct cons_channel *cc; 200 1.14 gwr 201 1.14 gwr kd = &kd_softc; /* XXX */ 202 1.14 gwr tp = kd->kd_tty; 203 1.14 gwr 204 1.14 gwr /* XXX This is for cons.c. */ 205 1.14 gwr if ((tp->t_state & TS_ISOPEN) == 0) 206 1.14 gwr return 0; 207 1.1 gwr 208 1.34 eeh (*tp->t_linesw->l_close)(tp, flag); 209 1.1 gwr ttyclose(tp); 210 1.29 pk if ((cc = kd->kd_in) != NULL) 211 1.39 martin (void)(*cc->cc_iclose)(cc); 212 1.1 gwr return (0); 213 1.1 gwr } 214 1.1 gwr 215 1.61 tsutsui static int 216 1.42 chs kdread(dev_t dev, struct uio *uio, int flag) 217 1.1 gwr { 218 1.14 gwr struct kd_softc *kd; 219 1.14 gwr struct tty *tp; 220 1.14 gwr 221 1.14 gwr kd = &kd_softc; /* XXX */ 222 1.14 gwr tp = kd->kd_tty; 223 1.1 gwr 224 1.34 eeh return ((*tp->t_linesw->l_read)(tp, uio, flag)); 225 1.1 gwr } 226 1.1 gwr 227 1.61 tsutsui static int 228 1.42 chs kdwrite(dev_t dev, struct uio *uio, int flag) 229 1.1 gwr { 230 1.14 gwr struct kd_softc *kd; 231 1.14 gwr struct tty *tp; 232 1.14 gwr 233 1.14 gwr kd = &kd_softc; /* XXX */ 234 1.14 gwr tp = kd->kd_tty; 235 1.1 gwr 236 1.34 eeh return ((*tp->t_linesw->l_write)(tp, uio, flag)); 237 1.35 scw } 238 1.35 scw 239 1.61 tsutsui static int 240 1.44 christos kdpoll(dev_t dev, int events, struct lwp *l) 241 1.35 scw { 242 1.35 scw struct kd_softc *kd; 243 1.35 scw struct tty *tp; 244 1.35 scw 245 1.35 scw kd = &kd_softc; /* XXX */ 246 1.35 scw tp = kd->kd_tty; 247 1.60 tsutsui 248 1.44 christos return ((*tp->t_linesw->l_poll)(tp, events, l)); 249 1.12 mycroft } 250 1.12 mycroft 251 1.61 tsutsui static int 252 1.50 christos kdioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l) 253 1.1 gwr { 254 1.14 gwr struct kd_softc *kd; 255 1.14 gwr struct tty *tp; 256 1.1 gwr int error; 257 1.14 gwr 258 1.14 gwr kd = &kd_softc; /* XXX */ 259 1.14 gwr tp = kd->kd_tty; 260 1.1 gwr 261 1.44 christos error = (*tp->t_linesw->l_ioctl)(tp, cmd, data, flag, l); 262 1.37 atatat if (error != EPASSTHROUGH) 263 1.1 gwr return error; 264 1.37 atatat 265 1.44 christos error = ttioctl(tp, cmd, data, flag, l); 266 1.37 atatat if (error != EPASSTHROUGH) 267 1.1 gwr return error; 268 1.1 gwr 269 1.1 gwr /* Handle any ioctl commands specific to kbd/display. */ 270 1.1 gwr /* XXX - Send KB* ioctls to kbd module? */ 271 1.1 gwr /* XXX - Send FB* ioctls to fb module? */ 272 1.1 gwr 273 1.37 atatat return EPASSTHROUGH; 274 1.1 gwr } 275 1.1 gwr 276 1.60 tsutsui static int 277 1.42 chs kdparam(struct tty *tp, struct termios *t) 278 1.14 gwr { 279 1.14 gwr /* XXX - These are ignored... */ 280 1.14 gwr tp->t_ispeed = t->c_ispeed; 281 1.14 gwr tp->t_ospeed = t->c_ospeed; 282 1.14 gwr tp->t_cflag = t->c_cflag; 283 1.14 gwr return 0; 284 1.14 gwr } 285 1.14 gwr 286 1.14 gwr 287 1.11 gwr static void kd_putfb(struct tty *); 288 1.11 gwr 289 1.60 tsutsui static void 290 1.42 chs kdstart(struct tty *tp) 291 1.1 gwr { 292 1.1 gwr struct clist *cl; 293 1.49 ad int s1, s2; 294 1.1 gwr 295 1.49 ad s1 = splsoftclock(); 296 1.49 ad s2 = spltty(); 297 1.1 gwr if (tp->t_state & (TS_BUSY|TS_TTSTOP|TS_TIMEOUT)) 298 1.1 gwr goto out; 299 1.11 gwr 300 1.1 gwr cl = &tp->t_outq; 301 1.53 ad if (ttypull(tp)) { 302 1.10 gwr if (kd_is_console) { 303 1.11 gwr tp->t_state |= TS_BUSY; 304 1.49 ad if ((s1 & PSL_IPL) == 0) { 305 1.11 gwr /* called at level zero - update screen now. */ 306 1.49 ad splx(s2); 307 1.11 gwr kd_putfb(tp); 308 1.49 ad s2 = spltty(); 309 1.11 gwr tp->t_state &= ~TS_BUSY; 310 1.11 gwr } else { 311 1.11 gwr /* called at interrupt level - do it later */ 312 1.51 joerg callout_schedule(&tp->t_rstrt_ch, 0); 313 1.11 gwr } 314 1.11 gwr } else { 315 1.11 gwr /* 316 1.11 gwr * This driver uses the PROM for writing the screen, 317 1.11 gwr * and that only works if this is the console device. 318 1.11 gwr * If this is not the console, just flush the output. 319 1.11 gwr * Sorry. (In that case, use xdm instead of getty.) 320 1.11 gwr */ 321 1.11 gwr ndflush(cl, cl->c_cc); 322 1.11 gwr } 323 1.11 gwr } 324 1.11 gwr out: 325 1.49 ad splx(s2); 326 1.49 ad splx(s1); 327 1.11 gwr } 328 1.11 gwr 329 1.11 gwr /* 330 1.11 gwr * Timeout function to do delayed writes to the screen. 331 1.11 gwr * Called at splsoftclock when requested by kdstart. 332 1.11 gwr */ 333 1.60 tsutsui static void 334 1.42 chs kd_later(void *tpaddr) 335 1.11 gwr { 336 1.11 gwr struct tty *tp = tpaddr; 337 1.36 tsutsui int s; 338 1.1 gwr 339 1.11 gwr kd_putfb(tp); 340 1.11 gwr 341 1.11 gwr s = spltty(); 342 1.1 gwr tp->t_state &= ~TS_BUSY; 343 1.34 eeh (*tp->t_linesw->l_start)(tp); 344 1.11 gwr splx(s); 345 1.11 gwr } 346 1.11 gwr 347 1.11 gwr /* 348 1.11 gwr * Put text on the screen using the PROM monitor. 349 1.11 gwr * This can take a while, so to avoid missing 350 1.11 gwr * interrupts, this is called at splsoftclock. 351 1.11 gwr */ 352 1.60 tsutsui static void 353 1.42 chs kd_putfb(struct tty *tp) 354 1.11 gwr { 355 1.14 gwr char buf[PUT_WSIZE]; 356 1.11 gwr struct clist *cl = &tp->t_outq; 357 1.11 gwr char *p, *end; 358 1.11 gwr int len; 359 1.11 gwr 360 1.14 gwr while ((len = q_to_b(cl, buf, PUT_WSIZE-1)) > 0) { 361 1.11 gwr /* PROM will barf if high bits are set. */ 362 1.11 gwr p = buf; 363 1.11 gwr end = buf + len; 364 1.11 gwr while (p < end) 365 1.11 gwr *p++ &= 0x7f; 366 1.11 gwr (romVectorPtr->fbWriteStr)(buf, len); 367 1.1 gwr } 368 1.1 gwr } 369 1.1 gwr 370 1.60 tsutsui void 371 1.42 chs cons_attach_input(struct cons_channel *cc, struct consdev *cn) 372 1.29 pk { 373 1.29 pk struct kd_softc *kd = &kd_softc; 374 1.29 pk 375 1.29 pk kd->kd_in = cc; 376 1.29 pk cc->cc_upstream = kd_cons_input; 377 1.29 pk } 378 1.29 pk 379 1.29 pk /* 380 1.29 pk * Default PROM-based console input stream 381 1.29 pk */ 382 1.42 chs static int kd_rom_iopen(struct cons_channel *); 383 1.42 chs static int kd_rom_iclose(struct cons_channel *); 384 1.29 pk 385 1.29 pk static struct cons_channel prom_cons_channel; 386 1.29 pk 387 1.60 tsutsui int 388 1.42 chs kd_rom_iopen(struct cons_channel *cc) 389 1.29 pk { 390 1.29 pk /* No-op */ 391 1.29 pk return (0); 392 1.29 pk } 393 1.29 pk 394 1.60 tsutsui int 395 1.42 chs kd_rom_iclose(struct cons_channel *cc) 396 1.29 pk { 397 1.29 pk /* No-op */ 398 1.29 pk return (0); 399 1.29 pk } 400 1.29 pk 401 1.14 gwr /* 402 1.15 gwr * Our "interrupt" routine for input. This is called by 403 1.15 gwr * the keyboard driver (dev/sun/kbd.c) at spltty. 404 1.14 gwr */ 405 1.60 tsutsui void 406 1.42 chs kd_cons_input(int c) 407 1.14 gwr { 408 1.14 gwr struct kd_softc *kd = &kd_softc; 409 1.14 gwr struct tty *tp; 410 1.14 gwr 411 1.14 gwr /* XXX: Make sure the device is open. */ 412 1.14 gwr tp = kd->kd_tty; 413 1.14 gwr if (tp == NULL) 414 1.14 gwr return; 415 1.25 gwr if ((tp->t_state & TS_ISOPEN) == 0) 416 1.14 gwr return; 417 1.11 gwr 418 1.34 eeh (*tp->t_linesw->l_rint)(c, tp); 419 1.1 gwr } 420 1.1 gwr 421 1.1 gwr 422 1.14 gwr /**************************************************************** 423 1.1 gwr * kd console support 424 1.14 gwr ****************************************************************/ 425 1.1 gwr 426 1.14 gwr /* The debugger gets its own key translation state. */ 427 1.14 gwr static struct kbd_state kdcn_state; 428 1.1 gwr 429 1.42 chs static void kdcnprobe(struct consdev *); 430 1.42 chs static void kdcninit(struct consdev *); 431 1.42 chs static int kdcngetc(dev_t); 432 1.42 chs static void kdcnputc(dev_t, int); 433 1.42 chs static void kdcnpollc(dev_t, int); 434 1.25 gwr 435 1.25 gwr struct consdev consdev_kd = { 436 1.25 gwr kdcnprobe, 437 1.25 gwr kdcninit, 438 1.25 gwr kdcngetc, 439 1.25 gwr kdcnputc, 440 1.25 gwr kdcnpollc, 441 1.28 thorpej NULL, 442 1.25 gwr }; 443 1.25 gwr 444 1.25 gwr /* We never call this. */ 445 1.60 tsutsui static void 446 1.42 chs kdcnprobe(struct consdev *cn) 447 1.25 gwr { 448 1.25 gwr } 449 1.25 gwr 450 1.60 tsutsui static void 451 1.42 chs kdcninit(struct consdev *cn) 452 1.1 gwr { 453 1.14 gwr struct kbd_state *ks = &kdcn_state; 454 1.8 gwr 455 1.38 gehenna cn->cn_dev = makedev(cdevsw_lookup_major(&kd_cdevsw), 0); 456 1.24 gwr cn->cn_pri = CN_INTERNAL; 457 1.8 gwr 458 1.8 gwr /* This prepares kbd_translate() */ 459 1.14 gwr ks->kbd_id = KBD_MIN_TYPE; 460 1.14 gwr kbd_xlate_init(ks); 461 1.29 pk 462 1.29 pk /* Set up initial PROM input channel for /dev/console */ 463 1.54 tsutsui prom_cons_channel.cc_private = NULL; 464 1.29 pk prom_cons_channel.cc_iopen = kd_rom_iopen; 465 1.29 pk prom_cons_channel.cc_iclose = kd_rom_iclose; 466 1.33 eeh cons_attach_input(&prom_cons_channel, cn); 467 1.10 gwr 468 1.10 gwr /* Indicate that it is OK to use the PROM fbwrite */ 469 1.10 gwr kd_is_console = 1; 470 1.1 gwr } 471 1.1 gwr 472 1.60 tsutsui static int 473 1.42 chs kdcngetc(dev_t dev) 474 1.1 gwr { 475 1.14 gwr struct kbd_state *ks = &kdcn_state; 476 1.14 gwr int code, class, data, keysym; 477 1.14 gwr 478 1.14 gwr for (;;) { 479 1.14 gwr code = zs_getc(zs_conschan); 480 1.14 gwr keysym = kbd_code_to_keysym(ks, code); 481 1.14 gwr class = KEYSYM_CLASS(keysym); 482 1.14 gwr 483 1.14 gwr switch (class) { 484 1.14 gwr case KEYSYM_ASCII: 485 1.14 gwr goto out; 486 1.14 gwr 487 1.14 gwr case KEYSYM_CLRMOD: 488 1.14 gwr case KEYSYM_SETMOD: 489 1.14 gwr data = (keysym & 0x1F); 490 1.14 gwr /* Only allow ctrl or shift. */ 491 1.14 gwr if (data > KBMOD_SHIFT_R) 492 1.14 gwr break; 493 1.14 gwr data = 1 << data; 494 1.14 gwr if (class == KEYSYM_SETMOD) 495 1.14 gwr ks->kbd_modbits |= data; 496 1.14 gwr else 497 1.14 gwr ks->kbd_modbits &= ~data; 498 1.14 gwr break; 499 1.1 gwr 500 1.14 gwr case KEYSYM_ALL_UP: 501 1.14 gwr /* No toggle keys here. */ 502 1.14 gwr ks->kbd_modbits = 0; 503 1.14 gwr break; 504 1.1 gwr 505 1.14 gwr default: /* ignore all other keysyms */ 506 1.14 gwr break; 507 1.14 gwr } 508 1.14 gwr } 509 1.14 gwr out: 510 1.14 gwr return (keysym); 511 1.1 gwr } 512 1.1 gwr 513 1.60 tsutsui static void 514 1.42 chs kdcnputc(dev_t dev, int c) 515 1.1 gwr { 516 1.11 gwr (romVectorPtr->fbWriteChar)(c & 0x7f); 517 1.9 gwr } 518 1.9 gwr 519 1.60 tsutsui static void 520 1.42 chs kdcnpollc(dev_t dev, int on) 521 1.9 gwr { 522 1.14 gwr struct kbd_state *ks = &kdcn_state; 523 1.14 gwr 524 1.14 gwr if (on) { 525 1.14 gwr /* Entering debugger. */ 526 1.26 gwr #if NFB > 0 527 1.9 gwr fb_unblank(); 528 1.26 gwr #endif 529 1.14 gwr /* Clear shift keys too. */ 530 1.14 gwr ks->kbd_modbits = 0; 531 1.14 gwr } else { 532 1.14 gwr /* Resuming kernel. */ 533 1.14 gwr } 534 1.1 gwr } 535 1.14 gwr 536