1300829Sgrehan/*- 2300829Sgrehan * Copyright (c) 2015 Tycho Nightingale <tycho.nightingale@pluribusnetworks.com> 3300829Sgrehan * Copyright (c) 2015 Nahanni Systems Inc. 4300829Sgrehan * All rights reserved. 5300829Sgrehan * 6300829Sgrehan * Redistribution and use in source and binary forms, with or without 7300829Sgrehan * modification, are permitted provided that the following conditions 8300829Sgrehan * are met: 9300829Sgrehan * 1. Redistributions of source code must retain the above copyright 10300829Sgrehan * notice, this list of conditions and the following disclaimer. 11300829Sgrehan * 2. Redistributions in binary form must reproduce the above copyright 12300829Sgrehan * notice, this list of conditions and the following disclaimer in the 13300829Sgrehan * documentation and/or other materials provided with the distribution. 14300829Sgrehan * 15300829Sgrehan * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND 16300829Sgrehan * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17300829Sgrehan * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18300829Sgrehan * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19300829Sgrehan * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20300829Sgrehan * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21300829Sgrehan * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22300829Sgrehan * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23300829Sgrehan * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24300829Sgrehan * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25300829Sgrehan * SUCH DAMAGE. 26300829Sgrehan */ 27300829Sgrehan 28300829Sgrehan#include <sys/cdefs.h> 29300829Sgrehan__FBSDID("$FreeBSD: releng/11.0/usr.sbin/bhyve/ps2kbd.c 302408 2016-07-08 00:04:57Z gjb $"); 30300829Sgrehan 31300829Sgrehan#include <sys/types.h> 32300829Sgrehan 33300829Sgrehan#include <assert.h> 34300829Sgrehan#include <stdbool.h> 35300829Sgrehan#include <stdio.h> 36300829Sgrehan#include <stdlib.h> 37300829Sgrehan#include <strings.h> 38300829Sgrehan#include <pthread.h> 39300829Sgrehan#include <pthread_np.h> 40300829Sgrehan 41300829Sgrehan#include "atkbdc.h" 42300829Sgrehan#include "console.h" 43300829Sgrehan 44300829Sgrehan/* keyboard device commands */ 45300829Sgrehan#define PS2KC_RESET_DEV 0xff 46300829Sgrehan#define PS2KC_DISABLE 0xf5 47300829Sgrehan#define PS2KC_ENABLE 0xf4 48300829Sgrehan#define PS2KC_SET_TYPEMATIC 0xf3 49300829Sgrehan#define PS2KC_SEND_DEV_ID 0xf2 50300829Sgrehan#define PS2KC_SET_SCANCODE_SET 0xf0 51300829Sgrehan#define PS2KC_ECHO 0xee 52300829Sgrehan#define PS2KC_SET_LEDS 0xed 53300829Sgrehan 54300829Sgrehan#define PS2KC_BAT_SUCCESS 0xaa 55300829Sgrehan#define PS2KC_ACK 0xfa 56300829Sgrehan 57300829Sgrehan#define PS2KBD_FIFOSZ 16 58300829Sgrehan 59300829Sgrehanstruct fifo { 60300829Sgrehan uint8_t buf[PS2KBD_FIFOSZ]; 61300829Sgrehan int rindex; /* index to read from */ 62300829Sgrehan int windex; /* index to write to */ 63300829Sgrehan int num; /* number of bytes in the fifo */ 64300829Sgrehan int size; /* size of the fifo */ 65300829Sgrehan}; 66300829Sgrehan 67300829Sgrehanstruct ps2kbd_softc { 68300829Sgrehan struct atkbdc_softc *atkbdc_sc; 69300829Sgrehan pthread_mutex_t mtx; 70300829Sgrehan 71300829Sgrehan bool enabled; 72300829Sgrehan struct fifo fifo; 73300829Sgrehan 74300829Sgrehan uint8_t curcmd; /* current command for next byte */ 75300829Sgrehan}; 76300829Sgrehan 77300829Sgrehanstatic void 78300829Sgrehanfifo_init(struct ps2kbd_softc *sc) 79300829Sgrehan{ 80300829Sgrehan struct fifo *fifo; 81300829Sgrehan 82300829Sgrehan fifo = &sc->fifo; 83300829Sgrehan fifo->size = sizeof(((struct fifo *)0)->buf); 84300829Sgrehan} 85300829Sgrehan 86300829Sgrehanstatic void 87300829Sgrehanfifo_reset(struct ps2kbd_softc *sc) 88300829Sgrehan{ 89300829Sgrehan struct fifo *fifo; 90300829Sgrehan 91300829Sgrehan fifo = &sc->fifo; 92300829Sgrehan bzero(fifo, sizeof(struct fifo)); 93300829Sgrehan fifo->size = sizeof(((struct fifo *)0)->buf); 94300829Sgrehan} 95300829Sgrehan 96300829Sgrehanstatic void 97300829Sgrehanfifo_put(struct ps2kbd_softc *sc, uint8_t val) 98300829Sgrehan{ 99300829Sgrehan struct fifo *fifo; 100300829Sgrehan 101300829Sgrehan fifo = &sc->fifo; 102300829Sgrehan if (fifo->num < fifo->size) { 103300829Sgrehan fifo->buf[fifo->windex] = val; 104300829Sgrehan fifo->windex = (fifo->windex + 1) % fifo->size; 105300829Sgrehan fifo->num++; 106300829Sgrehan } 107300829Sgrehan} 108300829Sgrehan 109300829Sgrehanstatic int 110300829Sgrehanfifo_get(struct ps2kbd_softc *sc, uint8_t *val) 111300829Sgrehan{ 112300829Sgrehan struct fifo *fifo; 113300829Sgrehan 114300829Sgrehan fifo = &sc->fifo; 115300829Sgrehan if (fifo->num > 0) { 116300829Sgrehan *val = fifo->buf[fifo->rindex]; 117300829Sgrehan fifo->rindex = (fifo->rindex + 1) % fifo->size; 118300829Sgrehan fifo->num--; 119300829Sgrehan return (0); 120300829Sgrehan } 121300829Sgrehan 122300829Sgrehan return (-1); 123300829Sgrehan} 124300829Sgrehan 125300829Sgrehanint 126300829Sgrehanps2kbd_read(struct ps2kbd_softc *sc, uint8_t *val) 127300829Sgrehan{ 128300829Sgrehan int retval; 129300829Sgrehan 130300829Sgrehan pthread_mutex_lock(&sc->mtx); 131300829Sgrehan retval = fifo_get(sc, val); 132300829Sgrehan pthread_mutex_unlock(&sc->mtx); 133300829Sgrehan 134300829Sgrehan return (retval); 135300829Sgrehan} 136300829Sgrehan 137300829Sgrehanvoid 138300829Sgrehanps2kbd_write(struct ps2kbd_softc *sc, uint8_t val) 139300829Sgrehan{ 140300829Sgrehan pthread_mutex_lock(&sc->mtx); 141300829Sgrehan if (sc->curcmd) { 142300829Sgrehan switch (sc->curcmd) { 143300829Sgrehan case PS2KC_SET_TYPEMATIC: 144300829Sgrehan fifo_put(sc, PS2KC_ACK); 145300829Sgrehan break; 146300829Sgrehan case PS2KC_SET_SCANCODE_SET: 147300829Sgrehan fifo_put(sc, PS2KC_ACK); 148300829Sgrehan break; 149300829Sgrehan case PS2KC_SET_LEDS: 150300829Sgrehan fifo_put(sc, PS2KC_ACK); 151300829Sgrehan break; 152300829Sgrehan default: 153300829Sgrehan fprintf(stderr, "Unhandled ps2 keyboard current " 154300829Sgrehan "command byte 0x%02x\n", val); 155300829Sgrehan break; 156300829Sgrehan } 157300829Sgrehan sc->curcmd = 0; 158300829Sgrehan } else { 159300829Sgrehan switch (val) { 160300829Sgrehan case 0x00: 161300829Sgrehan fifo_put(sc, PS2KC_ACK); 162300829Sgrehan break; 163300829Sgrehan case PS2KC_RESET_DEV: 164300829Sgrehan fifo_reset(sc); 165300829Sgrehan fifo_put(sc, PS2KC_ACK); 166300829Sgrehan fifo_put(sc, PS2KC_BAT_SUCCESS); 167300829Sgrehan break; 168300829Sgrehan case PS2KC_DISABLE: 169300829Sgrehan sc->enabled = false; 170300829Sgrehan fifo_put(sc, PS2KC_ACK); 171300829Sgrehan break; 172300829Sgrehan case PS2KC_ENABLE: 173300829Sgrehan sc->enabled = true; 174300829Sgrehan fifo_reset(sc); 175300829Sgrehan fifo_put(sc, PS2KC_ACK); 176300829Sgrehan break; 177300829Sgrehan case PS2KC_SET_TYPEMATIC: 178300829Sgrehan sc->curcmd = val; 179300829Sgrehan fifo_put(sc, PS2KC_ACK); 180300829Sgrehan break; 181300829Sgrehan case PS2KC_SEND_DEV_ID: 182300829Sgrehan fifo_put(sc, PS2KC_ACK); 183300829Sgrehan fifo_put(sc, 0xab); 184300829Sgrehan fifo_put(sc, 0x83); 185300829Sgrehan break; 186300829Sgrehan case PS2KC_SET_SCANCODE_SET: 187300829Sgrehan sc->curcmd = val; 188300829Sgrehan fifo_put(sc, PS2KC_ACK); 189300829Sgrehan break; 190300829Sgrehan case PS2KC_ECHO: 191300829Sgrehan fifo_put(sc, PS2KC_ECHO); 192300829Sgrehan break; 193300829Sgrehan case PS2KC_SET_LEDS: 194300829Sgrehan sc->curcmd = val; 195300829Sgrehan fifo_put(sc, PS2KC_ACK); 196300829Sgrehan break; 197300829Sgrehan default: 198300829Sgrehan fprintf(stderr, "Unhandled ps2 keyboard command " 199300829Sgrehan "0x%02x\n", val); 200300829Sgrehan break; 201300829Sgrehan } 202300829Sgrehan } 203300829Sgrehan pthread_mutex_unlock(&sc->mtx); 204300829Sgrehan} 205300829Sgrehan 206300829Sgrehan/* 207300829Sgrehan * Translate keysym to type 2 scancode and insert into keyboard buffer. 208300829Sgrehan */ 209300829Sgrehanstatic void 210300829Sgrehanps2kbd_keysym_queue(struct ps2kbd_softc *sc, 211300829Sgrehan int down, uint32_t keysym) 212300829Sgrehan{ 213300829Sgrehan /* ASCII to type 2 scancode lookup table */ 214300829Sgrehan const uint8_t translation[128] = { 215300829Sgrehan 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 216300829Sgrehan 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 217300829Sgrehan 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 218300829Sgrehan 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 219300829Sgrehan 0x29, 0x16, 0x52, 0x26, 0x25, 0x2e, 0x3d, 0x52, 220300829Sgrehan 0x46, 0x45, 0x3e, 0x55, 0x41, 0x4e, 0x49, 0x4a, 221300829Sgrehan 0x45, 0x16, 0x1e, 0x26, 0x25, 0x2e, 0x36, 0x3d, 222300829Sgrehan 0x3e, 0x46, 0x4c, 0x4c, 0x41, 0x55, 0x49, 0x4a, 223300829Sgrehan 0x1e, 0x1c, 0x32, 0x21, 0x23, 0x24, 0x2b, 0x34, 224300829Sgrehan 0x33, 0x43, 0x3b, 0x42, 0x4b, 0x3a, 0x31, 0x44, 225300829Sgrehan 0x4d, 0x15, 0x2d, 0x1b, 0x2c, 0x3c, 0x2a, 0x1d, 226300829Sgrehan 0x22, 0x35, 0x1a, 0x54, 0x5d, 0x5b, 0x36, 0x4e, 227300829Sgrehan 0x0e, 0x1c, 0x32, 0x21, 0x23, 0x24, 0x2b, 0x34, 228300829Sgrehan 0x33, 0x43, 0x3b, 0x42, 0x4b, 0x3a, 0x31, 0x44, 229300829Sgrehan 0x4d, 0x15, 0x2d, 0x1b, 0x2c, 0x3c, 0x2a, 0x1d, 230300829Sgrehan 0x22, 0x35, 0x1a, 0x54, 0x5d, 0x5b, 0x0e, 0x00, 231300829Sgrehan }; 232300829Sgrehan 233300829Sgrehan assert(pthread_mutex_isowned_np(&sc->mtx)); 234300829Sgrehan 235300829Sgrehan switch (keysym) { 236300829Sgrehan case 0x0 ... 0x7f: 237300829Sgrehan if (!down) 238300829Sgrehan fifo_put(sc, 0xf0); 239300829Sgrehan fifo_put(sc, translation[keysym]); 240300829Sgrehan break; 241300829Sgrehan case 0xff08: /* Back space */ 242300829Sgrehan if (!down) 243300829Sgrehan fifo_put(sc, 0xf0); 244300829Sgrehan fifo_put(sc, 0x66); 245300829Sgrehan break; 246300829Sgrehan case 0xff09: /* Tab */ 247300829Sgrehan if (!down) 248300829Sgrehan fifo_put(sc, 0xf0); 249300829Sgrehan fifo_put(sc, 0x0d); 250300829Sgrehan break; 251300829Sgrehan case 0xff0d: /* Return */ 252300829Sgrehan if (!down) 253300829Sgrehan fifo_put(sc, 0xf0); 254300829Sgrehan fifo_put(sc, 0x5a); 255300829Sgrehan break; 256300829Sgrehan case 0xff1b: /* Escape */ 257300829Sgrehan if (!down) 258300829Sgrehan fifo_put(sc, 0xf0); 259300829Sgrehan fifo_put(sc, 0x76); 260300829Sgrehan break; 261300829Sgrehan case 0xff50: /* Home */ 262300829Sgrehan fifo_put(sc, 0xe0); 263300829Sgrehan if (!down) 264300829Sgrehan fifo_put(sc, 0xf0); 265300829Sgrehan fifo_put(sc, 0x6c); 266300829Sgrehan break; 267300829Sgrehan case 0xff51: /* Left arrow */ 268300829Sgrehan fifo_put(sc, 0xe0); 269300829Sgrehan if (!down) 270300829Sgrehan fifo_put(sc, 0xf0); 271300829Sgrehan fifo_put(sc, 0x6b); 272300829Sgrehan break; 273300829Sgrehan case 0xff52: /* Up arrow */ 274300829Sgrehan fifo_put(sc, 0xe0); 275300829Sgrehan if (!down) 276300829Sgrehan fifo_put(sc, 0xf0); 277300829Sgrehan fifo_put(sc, 0x75); 278300829Sgrehan break; 279300829Sgrehan case 0xff53: /* Right arrow */ 280300829Sgrehan fifo_put(sc, 0xe0); 281300829Sgrehan if (!down) 282300829Sgrehan fifo_put(sc, 0xf0); 283300829Sgrehan fifo_put(sc, 0x74); 284300829Sgrehan break; 285300829Sgrehan case 0xff54: /* Down arrow */ 286300829Sgrehan fifo_put(sc, 0xe0); 287300829Sgrehan if (!down) 288300829Sgrehan fifo_put(sc, 0xf0); 289300829Sgrehan fifo_put(sc, 0x72); 290300829Sgrehan break; 291300829Sgrehan case 0xff55: /* PgUp */ 292300829Sgrehan fifo_put(sc, 0xe0); 293300829Sgrehan if (!down) 294300829Sgrehan fifo_put(sc, 0xf0); 295300829Sgrehan fifo_put(sc, 0x7d); 296300829Sgrehan break; 297300829Sgrehan case 0xff56: /* PgDwn */ 298300829Sgrehan fifo_put(sc, 0xe0); 299300829Sgrehan if (!down) 300300829Sgrehan fifo_put(sc, 0xf0); 301300829Sgrehan fifo_put(sc, 0x7a); 302300829Sgrehan break; 303300829Sgrehan case 0xff57: /* End */ 304300829Sgrehan fifo_put(sc, 0xe0); 305300829Sgrehan if (!down) 306300829Sgrehan fifo_put(sc, 0xf0); 307300829Sgrehan fifo_put(sc, 0x69); 308300829Sgrehan break; 309300829Sgrehan case 0xff63: /* Ins */ 310300829Sgrehan fifo_put(sc, 0xe0); 311300829Sgrehan if (!down) 312300829Sgrehan fifo_put(sc, 0xf0); 313300829Sgrehan fifo_put(sc, 0x70); 314300829Sgrehan break; 315300829Sgrehan case 0xff8d: /* Keypad Enter */ 316300829Sgrehan fifo_put(sc, 0xe0); 317300829Sgrehan if (!down) 318300829Sgrehan fifo_put(sc, 0xf0); 319300829Sgrehan fifo_put(sc, 0x5a); 320300829Sgrehan break; 321300829Sgrehan case 0xffe1: /* Left shift */ 322300829Sgrehan if (!down) 323300829Sgrehan fifo_put(sc, 0xf0); 324300829Sgrehan fifo_put(sc, 0x12); 325300829Sgrehan break; 326300829Sgrehan case 0xffe2: /* Right shift */ 327300829Sgrehan /* XXX */ 328300829Sgrehan break; 329300829Sgrehan case 0xffe3: /* Left control */ 330300829Sgrehan if (!down) 331300829Sgrehan fifo_put(sc, 0xf0); 332300829Sgrehan fifo_put(sc, 0x14); 333300829Sgrehan break; 334300829Sgrehan case 0xffe4: /* Right control */ 335300829Sgrehan /* XXX */ 336300829Sgrehan break; 337300829Sgrehan case 0xffe7: /* Left meta */ 338300829Sgrehan /* XXX */ 339300829Sgrehan break; 340300829Sgrehan case 0xffe8: /* Right meta */ 341300829Sgrehan /* XXX */ 342300829Sgrehan break; 343300829Sgrehan case 0xffe9: /* Left alt */ 344300829Sgrehan if (!down) 345300829Sgrehan fifo_put(sc, 0xf0); 346300829Sgrehan fifo_put(sc, 0x11); 347300829Sgrehan break; 348300829Sgrehan case 0xffea: /* Right alt */ 349300829Sgrehan fifo_put(sc, 0xe0); 350300829Sgrehan if (!down) 351300829Sgrehan fifo_put(sc, 0xf0); 352300829Sgrehan fifo_put(sc, 0x11); 353300829Sgrehan break; 354300829Sgrehan case 0xffeb: /* Left Windows */ 355300829Sgrehan fifo_put(sc, 0xe0); 356300829Sgrehan if (!down) 357300829Sgrehan fifo_put(sc, 0xf0); 358300829Sgrehan fifo_put(sc, 0x1f); 359300829Sgrehan break; 360300829Sgrehan case 0xffec: /* Right Windows */ 361300829Sgrehan fifo_put(sc, 0xe0); 362300829Sgrehan if (!down) 363300829Sgrehan fifo_put(sc, 0xf0); 364300829Sgrehan fifo_put(sc, 0x27); 365300829Sgrehan break; 366300829Sgrehan case 0xffbe: /* F1 */ 367300829Sgrehan if (!down) 368300829Sgrehan fifo_put(sc, 0xf0); 369300829Sgrehan fifo_put(sc, 0x05); 370300829Sgrehan break; 371300829Sgrehan case 0xffbf: /* F2 */ 372300829Sgrehan if (!down) 373300829Sgrehan fifo_put(sc, 0xf0); 374300829Sgrehan fifo_put(sc, 0x06); 375300829Sgrehan break; 376300829Sgrehan case 0xffc0: /* F3 */ 377300829Sgrehan if (!down) 378300829Sgrehan fifo_put(sc, 0xf0); 379300829Sgrehan fifo_put(sc, 0x04); 380300829Sgrehan break; 381300829Sgrehan case 0xffc1: /* F4 */ 382300829Sgrehan if (!down) 383300829Sgrehan fifo_put(sc, 0xf0); 384300829Sgrehan fifo_put(sc, 0x0C); 385300829Sgrehan break; 386300829Sgrehan case 0xffc2: /* F5 */ 387300829Sgrehan if (!down) 388300829Sgrehan fifo_put(sc, 0xf0); 389300829Sgrehan fifo_put(sc, 0x03); 390300829Sgrehan break; 391300829Sgrehan case 0xffc3: /* F6 */ 392300829Sgrehan if (!down) 393300829Sgrehan fifo_put(sc, 0xf0); 394300829Sgrehan fifo_put(sc, 0x0B); 395300829Sgrehan break; 396300829Sgrehan case 0xffc4: /* F7 */ 397300829Sgrehan if (!down) 398300829Sgrehan fifo_put(sc, 0xf0); 399300829Sgrehan fifo_put(sc, 0x83); 400300829Sgrehan break; 401300829Sgrehan case 0xffc5: /* F8 */ 402300829Sgrehan if (!down) 403300829Sgrehan fifo_put(sc, 0xf0); 404300829Sgrehan fifo_put(sc, 0x0A); 405300829Sgrehan break; 406300829Sgrehan case 0xffc6: /* F9 */ 407300829Sgrehan if (!down) 408300829Sgrehan fifo_put(sc, 0xf0); 409300829Sgrehan fifo_put(sc, 0x01); 410300829Sgrehan break; 411300829Sgrehan case 0xffc7: /* F10 */ 412300829Sgrehan if (!down) 413300829Sgrehan fifo_put(sc, 0xf0); 414300829Sgrehan fifo_put(sc, 0x09); 415300829Sgrehan break; 416300829Sgrehan case 0xffc8: /* F11 */ 417300829Sgrehan if (!down) 418300829Sgrehan fifo_put(sc, 0xf0); 419300829Sgrehan fifo_put(sc, 0x78); 420300829Sgrehan break; 421300829Sgrehan case 0xffc9: /* F12 */ 422300829Sgrehan if (!down) 423300829Sgrehan fifo_put(sc, 0xf0); 424300829Sgrehan fifo_put(sc, 0x07); 425300829Sgrehan break; 426300829Sgrehan case 0xffff: /* Del */ 427300829Sgrehan fifo_put(sc, 0xe0); 428300829Sgrehan if (!down) 429300829Sgrehan fifo_put(sc, 0xf0); 430300829Sgrehan fifo_put(sc, 0x71); 431300829Sgrehan break; 432300829Sgrehan default: 433300829Sgrehan fprintf(stderr, "Unhandled ps2 keyboard keysym 0x%x\n", 434300829Sgrehan keysym); 435300829Sgrehan break; 436300829Sgrehan } 437300829Sgrehan} 438300829Sgrehan 439300829Sgrehanstatic void 440300829Sgrehanps2kbd_event(int down, uint32_t keysym, void *arg) 441300829Sgrehan{ 442300829Sgrehan struct ps2kbd_softc *sc = arg; 443300829Sgrehan int fifo_full; 444300829Sgrehan 445300829Sgrehan pthread_mutex_lock(&sc->mtx); 446300829Sgrehan if (!sc->enabled) { 447300829Sgrehan pthread_mutex_unlock(&sc->mtx); 448300829Sgrehan return; 449300829Sgrehan } 450300829Sgrehan fifo_full = sc->fifo.num == PS2KBD_FIFOSZ; 451300829Sgrehan ps2kbd_keysym_queue(sc, down, keysym); 452300829Sgrehan pthread_mutex_unlock(&sc->mtx); 453300829Sgrehan 454300829Sgrehan if (!fifo_full) 455300829Sgrehan atkbdc_event(sc->atkbdc_sc, 1); 456300829Sgrehan} 457300829Sgrehan 458300829Sgrehanstruct ps2kbd_softc * 459300829Sgrehanps2kbd_init(struct atkbdc_softc *atkbdc_sc) 460300829Sgrehan{ 461300829Sgrehan struct ps2kbd_softc *sc; 462300829Sgrehan 463300829Sgrehan sc = calloc(1, sizeof (struct ps2kbd_softc)); 464300829Sgrehan pthread_mutex_init(&sc->mtx, NULL); 465300829Sgrehan fifo_init(sc); 466300829Sgrehan sc->atkbdc_sc = atkbdc_sc; 467300829Sgrehan 468300829Sgrehan console_kbd_register(ps2kbd_event, sc, 1); 469300829Sgrehan 470300829Sgrehan return (sc); 471300829Sgrehan} 472300829Sgrehan 473