1*55105Storek /* 2*55105Storek * Copyright (c) 1992 The Regents of the University of California. 3*55105Storek * All rights reserved. 4*55105Storek * 5*55105Storek * This software was developed by the Computer Systems Engineering group 6*55105Storek * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and 7*55105Storek * contributed to Berkeley. 8*55105Storek * 9*55105Storek * %sccs.include.redist.c% 10*55105Storek * 11*55105Storek * @(#)kbd.c 7.1 (Berkeley) 07/13/92 12*55105Storek * 13*55105Storek * from: $Header: kbd.c,v 1.15 92/07/09 07:59:27 torek Exp $ (LBL) 14*55105Storek */ 15*55105Storek 16*55105Storek /* 17*55105Storek * Keyboard driver (/dev/kbd -- note that we do not have minor numbers 18*55105Storek * [yet?]). Translates incoming bytes to ASCII or to `firm_events' and 19*55105Storek * passes them up to the appropriate reader. 20*55105Storek */ 21*55105Storek 22*55105Storek #include "sys/param.h" 23*55105Storek #include "sys/conf.h" 24*55105Storek #include "sys/device.h" 25*55105Storek #include "sys/ioctl.h" 26*55105Storek #include "sys/kernel.h" 27*55105Storek #include "sys/proc.h" 28*55105Storek #include "sys/syslog.h" 29*55105Storek #include "sys/systm.h" 30*55105Storek #include "sys/tty.h" 31*55105Storek 32*55105Storek #include "machine/autoconf.h" 33*55105Storek 34*55105Storek #include "vuid_event.h" 35*55105Storek #include "event_var.h" 36*55105Storek #include "kbd.h" 37*55105Storek #include "kbio.h" 38*55105Storek 39*55105Storek /* 40*55105Storek * Sun keyboard definitions (from Sprite). 41*55105Storek * These apply to type 2, 3 and 4 keyboards. 42*55105Storek */ 43*55105Storek #define KEY_CODE(c) ((c) & KBD_KEYMASK) /* keyboard code index */ 44*55105Storek #define KEY_UP(c) ((c) & KBD_UP) /* true => key went up */ 45*55105Storek 46*55105Storek /* 47*55105Storek * Each KEY_CODE(x) can be translated via the tables below. 48*55105Storek * The result is either a valid ASCII value in [0..0x7f] or is one 49*55105Storek * of the following `magic' values saying something interesting 50*55105Storek * happened. If LSHIFT or RSHIFT has changed state the next 51*55105Storek * lookup should come from the appropriate table; if ALLUP is 52*55105Storek * sent all keys (including both shifts and the control key) are 53*55105Storek * now up, and the next byte is the keyboard ID code. 54*55105Storek * 55*55105Storek * These tables ignore all function keys (on the theory that if you 56*55105Storek * want these keys, you should use a window system). Note that 57*55105Storek * `caps lock' is just mapped as `ignore' (so there!). (Only the 58*55105Storek * type 3 and 4 keyboards have a caps lock key anyway.) 59*55105Storek */ 60*55105Storek #define KEY_MAGIC 0x80 /* flag => magic value */ 61*55105Storek #define KEY_IGNORE 0x80 62*55105Storek #define KEY_L1 KEY_IGNORE 63*55105Storek #define KEY_CAPSLOCK KEY_IGNORE 64*55105Storek #define KEY_LSHIFT 0x81 65*55105Storek #define KEY_RSHIFT 0x82 66*55105Storek #define KEY_CONTROL 0x83 67*55105Storek #define KEY_ALLUP 0x84 /* all keys are now up; also reset */ 68*55105Storek 69*55105Storek /* 70*55105Storek * Decode tables for type 2, 3, and 4 keyboards 71*55105Storek * (stolen from Sprite; see also kbd.h). 72*55105Storek */ 73*55105Storek static const u_char kbd_unshifted[] = { 74*55105Storek /* 0 */ KEY_IGNORE, KEY_L1, KEY_IGNORE, KEY_IGNORE, 75*55105Storek /* 4 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, 76*55105Storek /* 8 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, 77*55105Storek /* 12 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, 78*55105Storek /* 16 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, 79*55105Storek /* 20 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, 80*55105Storek /* 24 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, 81*55105Storek /* 28 */ KEY_IGNORE, '\033', '1', '2', 82*55105Storek /* 32 */ '3', '4', '5', '6', 83*55105Storek /* 36 */ '7', '8', '9', '0', 84*55105Storek /* 40 */ '-', '=', '`', '\b', 85*55105Storek /* 44 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, 86*55105Storek /* 48 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, 87*55105Storek /* 52 */ KEY_IGNORE, '\t', 'q', 'w', 88*55105Storek /* 56 */ 'e', 'r', 't', 'y', 89*55105Storek /* 60 */ 'u', 'i', 'o', 'p', 90*55105Storek /* 64 */ '[', ']', '\177', KEY_IGNORE, 91*55105Storek /* 68 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, 92*55105Storek /* 72 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, 93*55105Storek /* 76 */ KEY_CONTROL, 'a', 's', 'd', 94*55105Storek /* 80 */ 'f', 'g', 'h', 'j', 95*55105Storek /* 84 */ 'k', 'l', ';', '\'', 96*55105Storek /* 88 */ '\\', '\r', KEY_IGNORE, KEY_IGNORE, 97*55105Storek /* 92 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, 98*55105Storek /* 96 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_LSHIFT, 99*55105Storek /* 100 */ 'z', 'x', 'c', 'v', 100*55105Storek /* 104 */ 'b', 'n', 'm', ',', 101*55105Storek /* 108 */ '.', '/', KEY_RSHIFT, '\n', 102*55105Storek /* 112 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, 103*55105Storek /* 116 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_CAPSLOCK, 104*55105Storek /* 120 */ KEY_IGNORE, ' ', KEY_IGNORE, KEY_IGNORE, 105*55105Storek /* 124 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_ALLUP, 106*55105Storek }; 107*55105Storek 108*55105Storek static const u_char kbd_shifted[] = { 109*55105Storek /* 0 */ KEY_IGNORE, KEY_L1, KEY_IGNORE, KEY_IGNORE, 110*55105Storek /* 4 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, 111*55105Storek /* 8 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, 112*55105Storek /* 12 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, 113*55105Storek /* 16 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, 114*55105Storek /* 20 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, 115*55105Storek /* 24 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, 116*55105Storek /* 28 */ KEY_IGNORE, '\033', '!', '@', 117*55105Storek /* 32 */ '#', '$', '%', '^', 118*55105Storek /* 36 */ '&', '*', '(', ')', 119*55105Storek /* 40 */ '_', '+', '~', '\b', 120*55105Storek /* 44 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, 121*55105Storek /* 48 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, 122*55105Storek /* 52 */ KEY_IGNORE, '\t', 'Q', 'W', 123*55105Storek /* 56 */ 'E', 'R', 'T', 'Y', 124*55105Storek /* 60 */ 'U', 'I', 'O', 'P', 125*55105Storek /* 64 */ '{', '}', '\177', KEY_IGNORE, 126*55105Storek /* 68 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, 127*55105Storek /* 72 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, 128*55105Storek /* 76 */ KEY_CONTROL, 'A', 'S', 'D', 129*55105Storek /* 80 */ 'F', 'G', 'H', 'J', 130*55105Storek /* 84 */ 'K', 'L', ':', '"', 131*55105Storek /* 88 */ '|', '\r', KEY_IGNORE, KEY_IGNORE, 132*55105Storek /* 92 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, 133*55105Storek /* 96 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_LSHIFT, 134*55105Storek /* 100 */ 'Z', 'X', 'C', 'V', 135*55105Storek /* 104 */ 'B', 'N', 'M', '<', 136*55105Storek /* 108 */ '>', '?', KEY_RSHIFT, '\n', 137*55105Storek /* 112 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, 138*55105Storek /* 116 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_CAPSLOCK, 139*55105Storek /* 120 */ KEY_IGNORE, ' ', KEY_IGNORE, KEY_IGNORE, 140*55105Storek /* 124 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_ALLUP, 141*55105Storek }; 142*55105Storek 143*55105Storek /* 144*55105Storek * We need to remember the state of the keyboard's shift and control 145*55105Storek * keys, and we need a per-type translation table. 146*55105Storek */ 147*55105Storek struct kbd_state { 148*55105Storek const u_char *kbd_unshifted; /* unshifted keys */ 149*55105Storek const u_char *kbd_shifted; /* shifted keys */ 150*55105Storek const u_char *kbd_cur; /* current keys (either of the preceding) */ 151*55105Storek union { 152*55105Storek char c[2]; /* left and right shift keys */ 153*55105Storek short s; /* true => either shift key */ 154*55105Storek } kbd_shift; 155*55105Storek #define kbd_lshift kbd_shift.c[0] 156*55105Storek #define kbd_rshift kbd_shift.c[1] 157*55105Storek #define kbd_anyshift kbd_shift.s 158*55105Storek char kbd_control; /* true => ctrl down */ 159*55105Storek char kbd_click; /* true => keyclick enabled */ 160*55105Storek char kbd_takeid; /* take next byte as ID */ 161*55105Storek u_char kbd_id; /* a place to store the ID */ 162*55105Storek }; 163*55105Storek 164*55105Storek /* 165*55105Storek * Keyboard driver state. The ascii and kbd links go up and down and 166*55105Storek * we just sit in the middle doing translation. Note that it is possible 167*55105Storek * to get just one of the two links, in which case /dev/kbd is unavailable. 168*55105Storek * The downlink supplies us with `internal' open and close routines which 169*55105Storek * will enable dataflow across the downlink. We promise to call open when 170*55105Storek * we are willing to take keystrokes, and to call close when we are not. 171*55105Storek * If /dev/kbd is not the console tty input source, we do this whenever 172*55105Storek * /dev/kbd is in use; otherwise we just leave it open forever. 173*55105Storek */ 174*55105Storek struct kbd_softc { 175*55105Storek struct tty *k_cons; /* uplink for ASCII data to console */ 176*55105Storek struct tty *k_kbd; /* downlink for output to keyboard */ 177*55105Storek void (*k_open) __P((struct tty *)); /* enable dataflow */ 178*55105Storek void (*k_close) __P((struct tty *)); /* disable dataflow */ 179*55105Storek int k_evmode; /* set if we should produce events */ 180*55105Storek struct kbd_state k_state; /* ASCII decode state */ 181*55105Storek struct evvar k_events; /* event queue state */ 182*55105Storek } kbd_softc; 183*55105Storek 184*55105Storek /* Prototypes */ 185*55105Storek void kbd_ascii(struct tty *); 186*55105Storek void kbd_serial(struct tty *, void (*)(), void (*)()); 187*55105Storek static void kbd_getid(void *); 188*55105Storek void kbd_reset(struct kbd_state *); 189*55105Storek static int kbd_translate(int, struct kbd_state *); 190*55105Storek void kbd_rint(int); 191*55105Storek int kbdopen(dev_t, int, int, struct proc *); 192*55105Storek int kbdclose(dev_t, int, int, struct proc *); 193*55105Storek int kbdread(dev_t, struct uio *, int); 194*55105Storek int kbdwrite(dev_t, struct uio *, int); 195*55105Storek int kbdioctl(dev_t, int, caddr_t, int, struct proc *); 196*55105Storek int kbdselect(dev_t, int, struct proc *); 197*55105Storek int kbd_docmd(int, int); 198*55105Storek 199*55105Storek /* 200*55105Storek * Attach the console keyboard ASCII (up-link) interface. 201*55105Storek * This happens before kbd_serial. 202*55105Storek */ 203*55105Storek void 204*55105Storek kbd_ascii(struct tty *tp) 205*55105Storek { 206*55105Storek 207*55105Storek kbd_softc.k_cons = tp; 208*55105Storek } 209*55105Storek 210*55105Storek /* 211*55105Storek * Attach the console keyboard serial (down-link) interface. 212*55105Storek * We pick up the initial keyboard clock state here as well. 213*55105Storek */ 214*55105Storek void 215*55105Storek kbd_serial(struct tty *tp, void (*iopen)(), void (*iclose)()) 216*55105Storek { 217*55105Storek register struct kbd_softc *k; 218*55105Storek register char *cp; 219*55105Storek 220*55105Storek k = &kbd_softc; 221*55105Storek k->k_kbd = tp; 222*55105Storek k->k_open = iopen; 223*55105Storek k->k_close = iclose; 224*55105Storek 225*55105Storek cp = getpropstring(optionsnode, "keyboard-click?"); 226*55105Storek if (cp && strcmp(cp, "true") == 0) 227*55105Storek k->k_state.kbd_click = 1; 228*55105Storek 229*55105Storek if (k->k_cons) { 230*55105Storek /* 231*55105Storek * We supply keys for /dev/console. Before we can 232*55105Storek * do so, we have to ``open'' the line. We also need 233*55105Storek * the type, got by sending a RESET down the line ... 234*55105Storek * but clists are not yet set up, so we use a timeout 235*55105Storek * to try constantly until we can get the ID. (gag) 236*55105Storek */ 237*55105Storek (*iopen)(tp); /* never to be closed */ 238*55105Storek kbd_getid(NULL); 239*55105Storek } 240*55105Storek } 241*55105Storek 242*55105Storek /* 243*55105Storek * Initial keyboard reset, to obtain ID and thus a translation table. 244*55105Storek * We have to try again and again until the tty subsystem works. 245*55105Storek */ 246*55105Storek static void 247*55105Storek kbd_getid(void *arg) 248*55105Storek { 249*55105Storek register struct kbd_softc *k; 250*55105Storek register struct tty *tp; 251*55105Storek register int retry; 252*55105Storek extern int cold; /* XXX */ 253*55105Storek 254*55105Storek k = &kbd_softc; 255*55105Storek if (k->k_state.kbd_cur != NULL) 256*55105Storek return; 257*55105Storek tp = k->k_kbd; 258*55105Storek if (cold || ttyoutput(KBD_CMD_RESET, tp) >= 0) 259*55105Storek retry = 1; 260*55105Storek else { 261*55105Storek (*tp->t_oproc)(tp); 262*55105Storek retry = 2 * hz; 263*55105Storek } 264*55105Storek timeout(kbd_getid, NULL, retry); 265*55105Storek } 266*55105Storek 267*55105Storek void 268*55105Storek kbd_reset(register struct kbd_state *ks) 269*55105Storek { 270*55105Storek /* 271*55105Storek * On first identification, wake up anyone waiting for type 272*55105Storek * and set up the table pointers. 273*55105Storek */ 274*55105Storek if (ks->kbd_unshifted == NULL) { 275*55105Storek wakeup((caddr_t)ks); 276*55105Storek ks->kbd_unshifted = kbd_unshifted; 277*55105Storek ks->kbd_shifted = kbd_shifted; 278*55105Storek ks->kbd_cur = ks->kbd_unshifted; 279*55105Storek } 280*55105Storek 281*55105Storek /* Restore keyclick, if necessary */ 282*55105Storek switch (ks->kbd_id) { 283*55105Storek 284*55105Storek case KB_SUN2: 285*55105Storek /* Type 2 keyboards don't support keyclick */ 286*55105Storek break; 287*55105Storek 288*55105Storek case KB_SUN3: 289*55105Storek /* Type 3 keyboards come up with keyclick on */ 290*55105Storek if (!ks->kbd_click) 291*55105Storek (void) kbd_docmd(KBD_CMD_NOCLICK, 0); 292*55105Storek break; 293*55105Storek 294*55105Storek case KB_SUN4: 295*55105Storek /* Type 4 keyboards come up with keyclick off */ 296*55105Storek if (ks->kbd_click) 297*55105Storek (void) kbd_docmd(KBD_CMD_CLICK, 0); 298*55105Storek break; 299*55105Storek } 300*55105Storek } 301*55105Storek 302*55105Storek /* 303*55105Storek * Turn keyboard up/down codes into ASCII. 304*55105Storek */ 305*55105Storek static int 306*55105Storek kbd_translate(register int c, register struct kbd_state *ks) 307*55105Storek { 308*55105Storek register int down; 309*55105Storek 310*55105Storek if (ks->kbd_cur == NULL) { 311*55105Storek /* 312*55105Storek * Do not know how to translate yet. 313*55105Storek * We will find out when a RESET comes along. 314*55105Storek */ 315*55105Storek return (-1); 316*55105Storek } 317*55105Storek down = !KEY_UP(c); 318*55105Storek c = ks->kbd_cur[KEY_CODE(c)]; 319*55105Storek if (c & KEY_MAGIC) { 320*55105Storek switch (c) { 321*55105Storek 322*55105Storek case KEY_LSHIFT: 323*55105Storek ks->kbd_lshift = down; 324*55105Storek break; 325*55105Storek 326*55105Storek case KEY_RSHIFT: 327*55105Storek ks->kbd_rshift = down; 328*55105Storek break; 329*55105Storek 330*55105Storek case KEY_ALLUP: 331*55105Storek ks->kbd_anyshift = 0; 332*55105Storek ks->kbd_control = 0; 333*55105Storek break; 334*55105Storek 335*55105Storek case KEY_CONTROL: 336*55105Storek ks->kbd_control = down; 337*55105Storek /* FALLTHROUGH */ 338*55105Storek 339*55105Storek case KEY_IGNORE: 340*55105Storek return (-1); 341*55105Storek 342*55105Storek default: 343*55105Storek panic("kbd_translate"); 344*55105Storek } 345*55105Storek if (ks->kbd_anyshift) 346*55105Storek ks->kbd_cur = ks->kbd_shifted; 347*55105Storek else 348*55105Storek ks->kbd_cur = ks->kbd_unshifted; 349*55105Storek return (-1); 350*55105Storek } 351*55105Storek if (!down) 352*55105Storek return (-1); 353*55105Storek if (ks->kbd_control) { 354*55105Storek /* control space and unshifted control atsign return null */ 355*55105Storek if (c == ' ' || c == '2') 356*55105Storek return (0); 357*55105Storek /* unshifted control hat */ 358*55105Storek if (c == '6') 359*55105Storek return ('^' & 0x1f); 360*55105Storek /* standard controls */ 361*55105Storek if (c >= '@' && c < 0x7f) 362*55105Storek return (c & 0x1f); 363*55105Storek } 364*55105Storek return (c); 365*55105Storek } 366*55105Storek 367*55105Storek void 368*55105Storek kbd_rint(register int c) 369*55105Storek { 370*55105Storek register struct kbd_softc *k = &kbd_softc; 371*55105Storek register struct firm_event *fe; 372*55105Storek register int put; 373*55105Storek 374*55105Storek /* 375*55105Storek * Reset keyboard after serial port overrun, so we can resynch. 376*55105Storek * The printf below should be shortened and/or replaced with a 377*55105Storek * call to log() after this is tested (and how will we test it?!). 378*55105Storek */ 379*55105Storek if (c & (TTY_FE|TTY_PE)) { 380*55105Storek printf("keyboard input parity or framing error (0x%x)\n", c); 381*55105Storek (void) ttyoutput(KBD_CMD_RESET, k->k_kbd); 382*55105Storek (*k->k_kbd->t_oproc)(k->k_kbd); 383*55105Storek return; 384*55105Storek } 385*55105Storek 386*55105Storek /* Read the keyboard id if we read a KBD_RESET last time */ 387*55105Storek if (k->k_state.kbd_takeid) { 388*55105Storek k->k_state.kbd_takeid = 0; 389*55105Storek k->k_state.kbd_id = c; 390*55105Storek kbd_reset(&k->k_state); 391*55105Storek return; 392*55105Storek } 393*55105Storek 394*55105Storek /* If we have been reset, setup to grab the keyboard id next time */ 395*55105Storek if (c == KBD_RESET) { 396*55105Storek k->k_state.kbd_takeid = 1; 397*55105Storek return; 398*55105Storek } 399*55105Storek 400*55105Storek /* 401*55105Storek * If /dev/kbd is not connected in event mode, but we are sending 402*55105Storek * data to /dev/console, translate and send upstream. Note that 403*55105Storek * we will get this while opening /dev/kbd if it is not already 404*55105Storek * open and we do not know its type. 405*55105Storek */ 406*55105Storek if (!k->k_evmode) { 407*55105Storek c = kbd_translate(c, &k->k_state); 408*55105Storek if (c >= 0 && k->k_cons != NULL) 409*55105Storek ttyinput(c, k->k_cons); 410*55105Storek return; 411*55105Storek } 412*55105Storek 413*55105Storek /* 414*55105Storek * IDLEs confuse the MIT X11R4 server badly, so we must drop them. 415*55105Storek * This is bad as it means the server will not automatically resync 416*55105Storek * on all-up IDLEs, but I did not drop them before, and the server 417*55105Storek * goes crazy when it comes time to blank the screen.... 418*55105Storek */ 419*55105Storek if (c == KBD_IDLE) 420*55105Storek return; 421*55105Storek 422*55105Storek /* 423*55105Storek * Keyboard is generating events. Turn this keystroke into an 424*55105Storek * event and put it in the queue. If the queue is full, the 425*55105Storek * keystroke is lost (sorry!). 426*55105Storek */ 427*55105Storek put = k->k_events.ev_put; 428*55105Storek fe = &k->k_events.ev_q[put]; 429*55105Storek put = (put + 1) % EV_QSIZE; 430*55105Storek if (put == k->k_events.ev_get) { 431*55105Storek log(LOG_WARNING, "keyboard event queue overflow\n"); /* ??? */ 432*55105Storek return; 433*55105Storek } 434*55105Storek fe->id = KEY_CODE(c); 435*55105Storek fe->value = KEY_UP(c) ? VKEY_UP : VKEY_DOWN; 436*55105Storek fe->time = time; 437*55105Storek k->k_events.ev_put = put; 438*55105Storek EV_WAKEUP(&k->k_events); 439*55105Storek } 440*55105Storek 441*55105Storek int 442*55105Storek kbdopen(dev_t dev, int flags, int mode, struct proc *p) 443*55105Storek { 444*55105Storek int s, error; 445*55105Storek 446*55105Storek if (kbd_softc.k_events.ev_io) 447*55105Storek return (EBUSY); 448*55105Storek kbd_softc.k_events.ev_io = p; 449*55105Storek /* 450*55105Storek * If no console keyboard, tell the device to open up, maybe for 451*55105Storek * the first time. Then make sure we know what kind of keyboard 452*55105Storek * it is. 453*55105Storek */ 454*55105Storek if (kbd_softc.k_cons == NULL) 455*55105Storek (*kbd_softc.k_open)(kbd_softc.k_kbd); 456*55105Storek error = 0; 457*55105Storek s = spltty(); 458*55105Storek if (kbd_softc.k_state.kbd_cur == NULL) { 459*55105Storek (void) ttyoutput(KBD_CMD_RESET, kbd_softc.k_kbd); 460*55105Storek error = tsleep((caddr_t)&kbd_softc.k_state, PZERO | PCATCH, 461*55105Storek devopn, hz); 462*55105Storek if (error == EWOULDBLOCK) /* no response */ 463*55105Storek error = ENXIO; 464*55105Storek } 465*55105Storek splx(s); 466*55105Storek if (error) { 467*55105Storek kbd_softc.k_events.ev_io = NULL; 468*55105Storek return (error); 469*55105Storek } 470*55105Storek ev_init(&kbd_softc.k_events); 471*55105Storek return (0); 472*55105Storek } 473*55105Storek 474*55105Storek int 475*55105Storek kbdclose(dev_t dev, int flags, int mode, struct proc *p) 476*55105Storek { 477*55105Storek 478*55105Storek /* 479*55105Storek * Turn off event mode, dump the queue, and close the keyboard 480*55105Storek * unless it is supplying console input. 481*55105Storek */ 482*55105Storek kbd_softc.k_evmode = 0; 483*55105Storek ev_fini(&kbd_softc.k_events); 484*55105Storek if (kbd_softc.k_cons == NULL) 485*55105Storek (*kbd_softc.k_close)(kbd_softc.k_kbd); 486*55105Storek kbd_softc.k_events.ev_io = NULL; 487*55105Storek return (0); 488*55105Storek } 489*55105Storek 490*55105Storek int 491*55105Storek kbdread(dev_t dev, struct uio *uio, int flags) 492*55105Storek { 493*55105Storek 494*55105Storek return (ev_read(&kbd_softc.k_events, uio, flags)); 495*55105Storek } 496*55105Storek 497*55105Storek /* this routine should not exist, but is convenient to write here for now */ 498*55105Storek int 499*55105Storek kbdwrite(dev_t dev, struct uio *uio, int flags) 500*55105Storek { 501*55105Storek 502*55105Storek return (EOPNOTSUPP); 503*55105Storek } 504*55105Storek 505*55105Storek int 506*55105Storek kbdioctl(dev_t dev, int cmd, register caddr_t data, int flag, struct proc *p) 507*55105Storek { 508*55105Storek register struct kbd_softc *k = &kbd_softc; 509*55105Storek 510*55105Storek switch (cmd) { 511*55105Storek 512*55105Storek case KIOCTRANS: 513*55105Storek if (*(int *)data == TR_UNTRANS_EVENT) 514*55105Storek return (0); 515*55105Storek break; 516*55105Storek 517*55105Storek case KIOCGTRANS: 518*55105Storek /* 519*55105Storek * Get translation mode 520*55105Storek */ 521*55105Storek *(int *)data = TR_UNTRANS_EVENT; 522*55105Storek return (0); 523*55105Storek 524*55105Storek case KIOCGETKEY: 525*55105Storek if (((struct kiockey *)data)->kio_station == 118) { 526*55105Storek /* 527*55105Storek * This is X11 asking if a type 3 keyboard is 528*55105Storek * really a type 3 keyboard. Say yes. 529*55105Storek */ 530*55105Storek ((struct kiockey *)data)->kio_entry = HOLE; 531*55105Storek return (0); 532*55105Storek } 533*55105Storek break; 534*55105Storek 535*55105Storek case KIOCCMD: 536*55105Storek /* 537*55105Storek * ``unimplemented commands are ignored'' (blech) 538*55105Storek * so cannot check return value from kbd_docmd 539*55105Storek */ 540*55105Storek #ifdef notyet 541*55105Storek while (kbd_docmd(*(int *)data, 1) == ENOSPC) /*ERESTART?*/ 542*55105Storek (void) sleep((caddr_t)&lbolt, TTOPRI); 543*55105Storek #else 544*55105Storek (void) kbd_docmd(*(int *)data, 1); 545*55105Storek #endif 546*55105Storek return (0); 547*55105Storek 548*55105Storek case KIOCTYPE: 549*55105Storek *(int *)data = k->k_state.kbd_id; 550*55105Storek return (0); 551*55105Storek 552*55105Storek case KIOCSDIRECT: 553*55105Storek k->k_evmode = *(int *)data; 554*55105Storek return (0); 555*55105Storek 556*55105Storek case FIONBIO: /* we will remove this someday (soon???) */ 557*55105Storek return (0); 558*55105Storek 559*55105Storek case FIOASYNC: 560*55105Storek k->k_events.ev_async = *(int *)data != 0; 561*55105Storek return (0); 562*55105Storek 563*55105Storek case TIOCSPGRP: 564*55105Storek if (*(int *)data != k->k_events.ev_io->p_pgid) 565*55105Storek return (EPERM); 566*55105Storek return (0); 567*55105Storek 568*55105Storek default: 569*55105Storek return (ENOTTY); 570*55105Storek } 571*55105Storek 572*55105Storek /* 573*55105Storek * We identified the ioctl, but we do not handle it. 574*55105Storek */ 575*55105Storek return (EOPNOTSUPP); /* misuse, but what the heck */ 576*55105Storek } 577*55105Storek 578*55105Storek int 579*55105Storek kbdselect(dev_t dev, int rw, struct proc *p) 580*55105Storek { 581*55105Storek 582*55105Storek return (ev_select(&kbd_softc.k_events, rw, p)); 583*55105Storek } 584*55105Storek 585*55105Storek /* 586*55105Storek * Execute a keyboard command; return 0 on success. 587*55105Storek * If `isuser', force a small delay before output if output queue 588*55105Storek * is flooding. (The keyboard runs at 1200 baud, or 120 cps.) 589*55105Storek */ 590*55105Storek int 591*55105Storek kbd_docmd(int cmd, int isuser) 592*55105Storek { 593*55105Storek register struct tty *tp = kbd_softc.k_kbd; 594*55105Storek register struct kbd_softc *k = &kbd_softc; 595*55105Storek int s; 596*55105Storek 597*55105Storek if (tp == NULL) 598*55105Storek return (ENXIO); /* ??? */ 599*55105Storek switch (cmd) { 600*55105Storek 601*55105Storek case KBD_CMD_BELL: 602*55105Storek case KBD_CMD_NOBELL: 603*55105Storek /* Supported by type 2, 3, and 4 keyboards */ 604*55105Storek break; 605*55105Storek 606*55105Storek case KBD_CMD_CLICK: 607*55105Storek /* Unsupported by type 2 keyboards */ 608*55105Storek if (k->k_state.kbd_id != KB_SUN2) { 609*55105Storek k->k_state.kbd_click = 1; 610*55105Storek break; 611*55105Storek } 612*55105Storek return (EINVAL); 613*55105Storek 614*55105Storek case KBD_CMD_NOCLICK: 615*55105Storek /* Unsupported by type 2 keyboards */ 616*55105Storek if (k->k_state.kbd_id != KB_SUN2) { 617*55105Storek k->k_state.kbd_click = 0; 618*55105Storek break; 619*55105Storek } 620*55105Storek return (EINVAL); 621*55105Storek 622*55105Storek default: 623*55105Storek return (EINVAL); /* ENOTTY? EOPNOTSUPP? */ 624*55105Storek } 625*55105Storek 626*55105Storek if (isuser) { 627*55105Storek s = spltty(); 628*55105Storek if (tp->t_outq.c_cc > 120) 629*55105Storek (void) tsleep((caddr_t)&lbolt, TTIPRI, 630*55105Storek ttyout, 0); 631*55105Storek splx(s); 632*55105Storek } 633*55105Storek if (ttyoutput(cmd, tp) >= 0) 634*55105Storek return (ENOSPC); /* ERESTART? */ 635*55105Storek (*tp->t_oproc)(tp); 636*55105Storek return (0); 637*55105Storek } 638