1 /* 2 * Copyright 2004-2010 Haiku, Inc. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors (in chronological order): 6 * Stefano Ceccherini (burton666@libero.it) 7 * Axel Dörfler, axeld@pinc-software.de 8 * Marcus Overhagen <marcus@overhagen.de> 9 */ 10 11 12 /*! PS/2 keyboard device driver */ 13 14 15 #include <string.h> 16 17 #include <new> 18 19 #include <debug.h> 20 #include <debugger_keymaps.h> 21 #include <lock.h> 22 #include <util/AutoLock.h> 23 24 #include "ATKeymap.h" 25 #include "ps2_service.h" 26 #include "keyboard_mouse_driver.h" 27 #include "packet_buffer.h" 28 29 30 #define KEY_BUFFER_SIZE 100 31 // we will buffer 100 key strokes before we start dropping them 32 33 //#define TRACE_PS2_KEYBOARD 34 #ifdef TRACE_PS2_KEYBOARD 35 # define TRACE(x...) dprintf(x) 36 #else 37 # define TRACE(x...) 38 #endif 39 40 enum { 41 LED_SCROLL = 1, 42 LED_NUM = 2, 43 LED_CAPS = 4 44 }; 45 46 enum { 47 EXTENDED_KEY_0 = 0xe0, 48 EXTENDED_KEY_1 = 0xe1, 49 50 LEFT_ALT_KEY = 0x38, 51 RIGHT_ALT_KEY = 0xb8, 52 SYS_REQ_KEY = 0x54, 53 PRNT_SCRN_KEY = 0x80 | 0x37, 54 PAUSE_KEY = 0x80 | 0x46, 55 }; 56 57 58 struct keyboard_cookie { 59 bool is_reader; 60 bool is_debugger; 61 }; 62 63 64 static mutex sInitializeLock = MUTEX_INITIALIZER("keyboard init"); 65 static int32 sKeyboardOpenCount = 0; 66 static bool sHasKeyboardReader = false; 67 static bool sHasDebugReader = false; 68 static sem_id sKeyboardSem; 69 static struct packet_buffer *sKeyBuffer; 70 static bool sIsExtended0 = false; 71 static bool sIsExtended1 = false; 72 static uint8 sPauseSequenceRead = 0; 73 74 static int32 sKeyboardRepeatRate; 75 static bigtime_t sKeyboardRepeatDelay; 76 static uint8 sKeyboardIds[2]; 77 78 79 static status_t 80 set_leds(led_info *ledInfo) 81 { 82 uint8 leds = 0; 83 84 TRACE("ps2: set keyboard LEDs\n"); 85 86 if (ledInfo->scroll_lock) 87 leds |= LED_SCROLL; 88 if (ledInfo->num_lock) 89 leds |= LED_NUM; 90 if (ledInfo->caps_lock) 91 leds |= LED_CAPS; 92 93 return ps2_dev_command(&ps2_device[PS2_DEVICE_KEYB], 94 PS2_CMD_KEYBOARD_SET_LEDS, &leds, 1, NULL, 0); 95 } 96 97 98 static status_t 99 set_typematic(int32 rate, bigtime_t delay) 100 { 101 uint8 value; 102 103 TRACE("ps2: set_typematic rate %" B_PRId32 ", delay %" B_PRId64 "\n", 104 rate, delay); 105 106 // input server and keyboard preferences *seem* to use a range of 20-300 107 if (rate < 20) 108 rate = 20; 109 if (rate > 300) 110 rate = 300; 111 112 // map this into range 0-31 113 rate = ((rate - 20) * 31) / (300 - 20); 114 115 // keyboard uses 0 == fast, 31 == slow 116 value = 31 - rate; 117 118 if (delay >= 875000) 119 value |= 3 << 5; 120 else if (delay >= 625000) 121 value |= 2 << 5; 122 else if (delay >= 375000) 123 value |= 1 << 5; 124 else 125 value |= 0 << 5; 126 127 return ps2_dev_command(&ps2_device[PS2_DEVICE_KEYB], 128 PS2_CMD_SET_TYPEMATIC, &value, 1, NULL, 0); 129 } 130 131 132 static int32 133 keyboard_handle_int(ps2_dev *dev) 134 { 135 enum emergency_keys { 136 EMERGENCY_LEFT_ALT = 0x01, 137 EMERGENCY_RIGHT_ALT = 0x02, 138 EMERGENCY_SYS_REQ = 0x04, 139 }; 140 141 static const uint8 pauseSequence[] = { 0x1D, 0x45 }; 142 static int emergencyKeyStatus = 0; 143 raw_key_info keyInfo; 144 uint8 scancode = dev->history[0].data; 145 146 if (atomic_get(&sKeyboardOpenCount) == 0) 147 return B_HANDLED_INTERRUPT; 148 149 if (scancode == EXTENDED_KEY_0) { 150 sIsExtended0 = true; 151 //TRACE("Extended key 0\n"); 152 return B_HANDLED_INTERRUPT; 153 } 154 155 if (scancode == EXTENDED_KEY_1) { 156 sIsExtended1 = true; 157 //TRACE("Extended key 1\n"); 158 return B_HANDLED_INTERRUPT; 159 } 160 161 if ((scancode & 0x80) != 0) { 162 keyInfo.is_keydown = false; 163 scancode &= 0x7f; 164 } else 165 keyInfo.is_keydown = true; 166 167 // TRACE("scancode: %x\n", scancode); 168 169 // Handle braindead "pause" key special case 170 if (sIsExtended1 && scancode == pauseSequence[sPauseSequenceRead]) { 171 sPauseSequenceRead++; 172 if (sPauseSequenceRead == 2) { 173 sIsExtended1 = false; 174 sPauseSequenceRead = 0; 175 scancode = PAUSE_KEY; 176 } else { 177 return B_HANDLED_INTERRUPT; 178 } 179 } 180 181 if (sIsExtended0) { 182 scancode |= 0x80; 183 sIsExtended0 = false; 184 } 185 186 // Handle emergency keys 187 if (scancode == LEFT_ALT_KEY || scancode == RIGHT_ALT_KEY) { 188 // left or right alt-key pressed 189 if (keyInfo.is_keydown) { 190 emergencyKeyStatus |= scancode == LEFT_ALT_KEY 191 ? EMERGENCY_LEFT_ALT : EMERGENCY_RIGHT_ALT; 192 } else { 193 emergencyKeyStatus &= ~(scancode == LEFT_ALT_KEY 194 ? EMERGENCY_LEFT_ALT : EMERGENCY_RIGHT_ALT); 195 } 196 } else if (scancode == SYS_REQ_KEY || scancode == PRNT_SCRN_KEY) { 197 if (keyInfo.is_keydown) 198 emergencyKeyStatus |= EMERGENCY_SYS_REQ; 199 else 200 emergencyKeyStatus &= ~EMERGENCY_SYS_REQ; 201 } else if (emergencyKeyStatus > EMERGENCY_SYS_REQ 202 && debug_emergency_key_pressed(kUnshiftedKeymap[scancode])) { 203 static const int kKeys[] = {LEFT_ALT_KEY, RIGHT_ALT_KEY, SYS_REQ_KEY}; 204 205 // we probably have lost some keys, so reset our key states 206 emergencyKeyStatus = 0; 207 208 // send key ups for alt-sysreq 209 keyInfo.timestamp = system_time(); 210 keyInfo.is_keydown = false; 211 for (size_t i = 0; i < sizeof(kKeys) / sizeof(kKeys[0]); i++) { 212 keyInfo.keycode = kATKeycodeMap[kKeys[i] - 1]; 213 if (packet_buffer_write(sKeyBuffer, (uint8 *)&keyInfo, 214 sizeof(keyInfo)) != 0) 215 release_sem_etc(sKeyboardSem, 1, B_DO_NOT_RESCHEDULE); 216 } 217 218 return B_HANDLED_INTERRUPT; 219 } 220 221 keyInfo.timestamp = dev->history[0].time; 222 keyInfo.keycode = kATKeycodeMap[scancode - 1]; 223 224 if (packet_buffer_write(sKeyBuffer, (uint8 *)&keyInfo, 225 sizeof(keyInfo)) == 0) { 226 // If there is no space left in the buffer, we drop this key stroke. We 227 // avoid dropping old key strokes, to not destroy what already was 228 // typed. 229 return B_HANDLED_INTERRUPT; 230 } 231 232 release_sem_etc(sKeyboardSem, 1, B_DO_NOT_RESCHEDULE); 233 234 return B_INVOKE_SCHEDULER; 235 } 236 237 238 static status_t 239 read_keyboard_packet(raw_key_info *packet, bool isDebugger) 240 { 241 status_t status; 242 243 TRACE("ps2: read_keyboard_packet: enter\n"); 244 245 while (true) { 246 status = acquire_sem_etc(sKeyboardSem, 1, B_CAN_INTERRUPT, 0); 247 if (status != B_OK) 248 return status; 249 250 if (!ps2_device[PS2_DEVICE_KEYB].active) { 251 TRACE("ps2: read_keyboard_packet, Error device no longer active\n"); 252 return B_ERROR; 253 } 254 255 if (isDebugger || !sHasDebugReader) 256 break; 257 258 // Give the debugger a chance to read this packet 259 release_sem(sKeyboardSem); 260 snooze(100000); 261 } 262 263 if (packet_buffer_read(sKeyBuffer, (uint8 *)packet, sizeof(*packet)) == 0) { 264 TRACE("ps2: read_keyboard_packet, Error reading packet: %s\n", 265 strerror(status)); 266 return B_ERROR; 267 } 268 269 TRACE("ps2: read_keyboard_packet: keycode: %" B_PRIx32 ", keydown: %s\n", 270 packet->keycode, packet->is_keydown ? "true" : "false"); 271 272 return B_OK; 273 } 274 275 276 static void 277 ps2_keyboard_disconnect(ps2_dev *dev) 278 { 279 // the keyboard might not be opened at this point 280 INFO("ps2: ps2_keyboard_disconnect %s\n", dev->name); 281 if (atomic_get(&sKeyboardOpenCount) != 0) 282 release_sem(sKeyboardSem); 283 } 284 285 286 // #pragma mark - 287 288 289 status_t 290 probe_keyboard(void) 291 { 292 uint8 data; 293 status_t status; 294 int ids_read = 0; 295 296 // This test doesn't work reliably on some notebooks (it reports 0x03) 297 #if 0 298 status = ps2_command(PS2_CTRL_KEYBOARD_TEST, NULL, 0, &data, 1); 299 if (status != B_OK || data != 0x00) { 300 INFO("ps2: keyboard test failed, status 0x%08lx, data 0x%02x\n", status, data); 301 return B_ERROR; 302 } 303 #endif 304 305 status = ps2_dev_command(&ps2_device[PS2_DEVICE_KEYB], PS2_CMD_RESET, NULL, 306 0, &data, 1); 307 // Checking for reset is unreliable on some controllers, but we check 308 // ID which is good enough for Linux and should be good enough for us. 309 // Reset is needed though. 310 if (status != B_OK || data != 0xaa) { 311 ERROR("ps2: keyboard reset failed, status 0x%08" B_PRIx32 ", data 0x%02x" 312 "\n", status, data); 313 ids_read = 1; 314 status = ps2_dev_command(&ps2_device[PS2_DEVICE_KEYB], 315 PS2_CMD_GET_DEVICE_ID, NULL, 0, sKeyboardIds, sizeof(sKeyboardIds)); 316 if ((status != B_OK) || (sKeyboardIds[0] != 0xab && sKeyboardIds[0] != 0xac && /* Regular and NCD Sun keyboards */ 317 sKeyboardIds[0] != 0x2b && sKeyboardIds[0] != 0x5d && /* Trust keyboard, raw and translated */ 318 sKeyboardIds[0] != 0x60 && sKeyboardIds[0] != 0x47)) { /* NMB SGI keyboard, raw and translated */ 319 ERROR("ps2: keyboard getid failed, status 0x%08" B_PRIx32 ", data 0x%02x%02x." 320 " Assuming no keyboard\n", status, sKeyboardIds[0], sKeyboardIds[1]); 321 return B_ERROR; 322 } 323 } 324 325 // default settings after keyboard reset: delay = 0x01 (500 ms), 326 // rate = 0x0b (10.9 chr/sec) 327 sKeyboardRepeatRate = ((31 - 0x0b) * 280) / 31 + 20; 328 sKeyboardRepeatDelay = 500000; 329 330 #if 0 331 status = ps2_dev_command(&ps2_device[PS2_DEVICE_KEYB], PS2_ENABLE_KEYBOARD, NULL, 0, NULL, 0); 332 #endif 333 334 // On at least some machines, the keyboard controller does NACK the echo command. 335 #if 0 336 status = ps2_dev_command(&ps2_device[PS2_DEVICE_KEYB], PS2_CMD_ECHO, NULL, 0, &data, 1); 337 if (status != B_OK || data != 0xee) { 338 INFO("ps2: keyboard echo test failed, status 0x%08lx, data 0x%02x\n", status, data); 339 return B_ERROR; 340 } 341 #endif 342 343 // Some controllers set the disable keyboard command bit to "on" after resetting 344 // the keyboard device. Read #7973 #6313 for more details. 345 // So check the command byte now and re-enable the keyboard if it is the case. 346 uint8 cmdbyte = 0; 347 status = ps2_command(PS2_CTRL_READ_CMD, NULL, 0, &cmdbyte, 1); 348 349 if (status != B_OK) { 350 ERROR("ps2: cannot read CMD byte on kbd probe:%#08" B_PRIx32 "\n", 351 status); 352 } else if ((cmdbyte & PS2_BITS_KEYBOARD_DISABLED) == PS2_BITS_KEYBOARD_DISABLED) { 353 cmdbyte &= ~PS2_BITS_KEYBOARD_DISABLED; 354 status = ps2_command(PS2_CTRL_WRITE_CMD, &cmdbyte, 1, NULL, 0); 355 if (status != B_OK) { 356 ERROR("ps2: cannot write 0x%02x to CMD byte on kbd probe:%#08" 357 B_PRIx32 "\n", cmdbyte, status); 358 } 359 } 360 361 if (!ids_read) { 362 status = ps2_dev_command(&ps2_device[PS2_DEVICE_KEYB], 363 PS2_CMD_GET_DEVICE_ID, NULL, 0, sKeyboardIds, sizeof(sKeyboardIds)); 364 365 if (status != B_OK) 366 ERROR("ps2: cannot read keyboard device id:%#08" B_PRIx32 "\n", status); 367 } 368 369 return B_OK; 370 } 371 372 373 // #pragma mark - 374 375 376 static status_t 377 keyboard_open(const char *name, uint32 flags, void **_cookie) 378 { 379 TRACE("ps2: keyboard_open %s\n", name); 380 381 keyboard_cookie* cookie = new(std::nothrow) keyboard_cookie(); 382 if (cookie == NULL) 383 return B_NO_MEMORY; 384 385 cookie->is_reader = false; 386 cookie->is_debugger = false; 387 388 MutexLocker locker(sInitializeLock); 389 390 if (atomic_get(&sKeyboardOpenCount) == 0) { 391 status_t status = probe_keyboard(); 392 if (status != B_OK) { 393 INFO("ps2: keyboard probing failed\n"); 394 ps2_service_notify_device_removed(&ps2_device[PS2_DEVICE_KEYB]); 395 delete cookie; 396 return status; 397 } 398 399 INFO("ps2: keyboard found\n"); 400 401 sKeyboardSem = create_sem(0, "keyboard_sem"); 402 if (sKeyboardSem < 0) { 403 delete cookie; 404 return sKeyboardSem; 405 } 406 407 sKeyBuffer 408 = create_packet_buffer(KEY_BUFFER_SIZE * sizeof(raw_key_info)); 409 if (sKeyBuffer == NULL) { 410 delete_sem(sKeyboardSem); 411 delete cookie; 412 return B_NO_MEMORY; 413 } 414 415 ps2_device[PS2_DEVICE_KEYB].disconnect = &ps2_keyboard_disconnect; 416 ps2_device[PS2_DEVICE_KEYB].handle_int = &keyboard_handle_int; 417 418 atomic_or(&ps2_device[PS2_DEVICE_KEYB].flags, PS2_FLAG_ENABLED); 419 } 420 421 atomic_add(&sKeyboardOpenCount, 1); 422 *_cookie = cookie; 423 424 TRACE("ps2: keyboard_open %s success\n", name); 425 return B_OK; 426 } 427 428 429 static status_t 430 keyboard_close(void *_cookie) 431 { 432 keyboard_cookie *cookie = (keyboard_cookie *)_cookie; 433 434 TRACE("ps2: keyboard_close enter\n"); 435 436 if (atomic_add(&sKeyboardOpenCount, -1) == 1) { 437 delete_packet_buffer(sKeyBuffer); 438 delete_sem(sKeyboardSem); 439 440 atomic_and(&ps2_device[PS2_DEVICE_KEYB].flags, ~PS2_FLAG_ENABLED); 441 442 sKeyboardIds[0] = sKeyboardIds[1] = 0; 443 } 444 445 if (cookie->is_reader) 446 sHasKeyboardReader = false; 447 if (cookie->is_debugger) 448 sHasDebugReader = false; 449 450 TRACE("ps2: keyboard_close done\n"); 451 return B_OK; 452 } 453 454 455 static status_t 456 keyboard_freecookie(void *cookie) 457 { 458 delete (keyboard_cookie*)cookie; 459 return B_OK; 460 } 461 462 463 static status_t 464 keyboard_read(void *cookie, off_t pos, void *buffer, size_t *_length) 465 { 466 TRACE("ps2: keyboard read\n"); 467 *_length = 0; 468 return B_NOT_ALLOWED; 469 } 470 471 472 static status_t 473 keyboard_write(void *cookie, off_t pos, const void *buffer, size_t *_length) 474 { 475 TRACE("ps2: keyboard write\n"); 476 *_length = 0; 477 return B_NOT_ALLOWED; 478 } 479 480 481 static status_t 482 keyboard_ioctl(void *_cookie, uint32 op, void *buffer, size_t length) 483 { 484 keyboard_cookie *cookie = (keyboard_cookie *)_cookie; 485 486 switch (op) { 487 case KB_READ: 488 { 489 if (!sHasKeyboardReader && !cookie->is_debugger) { 490 cookie->is_reader = true; 491 sHasKeyboardReader = true; 492 } else if (!cookie->is_debugger && !cookie->is_reader) 493 return B_BUSY; 494 495 raw_key_info packet; 496 status_t status = read_keyboard_packet(&packet, 497 cookie->is_debugger); 498 TRACE("ps2: ioctl KB_READ: %s\n", strerror(status)); 499 if (status != B_OK) 500 return status; 501 502 return user_memcpy(buffer, &packet, sizeof(packet)); 503 } 504 505 case KB_SET_LEDS: 506 { 507 led_info info; 508 TRACE("ps2: ioctl KB_SET_LEDS\n"); 509 if (user_memcpy(&info, buffer, sizeof(led_info)) < B_OK) 510 return B_BAD_ADDRESS; 511 return set_leds(&info); 512 } 513 514 case KB_SET_KEY_REPEATING: 515 { 516 TRACE("ps2: ioctl KB_SET_KEY_REPEATING\n"); 517 // 0xFA (Set All Keys Typematic/Make/Break) - Keyboard responds 518 // with "ack" (0xFA). 519 return ps2_dev_command(&ps2_device[PS2_DEVICE_KEYB], 0xfa, NULL, 0, 520 NULL, 0); 521 } 522 523 case KB_SET_KEY_NONREPEATING: 524 { 525 TRACE("ps2: ioctl KB_SET_KEY_NONREPEATING\n"); 526 // 0xF8 (Set All Keys Make/Break) - Keyboard responds with "ack" 527 // (0xFA). 528 return ps2_dev_command(&ps2_device[PS2_DEVICE_KEYB], 0xf8, NULL, 0, 529 NULL, 0); 530 } 531 532 case KB_SET_KEY_REPEAT_RATE: 533 { 534 int32 key_repeat_rate; 535 TRACE("ps2: ioctl KB_SET_KEY_REPEAT_RATE\n"); 536 if (user_memcpy(&key_repeat_rate, buffer, sizeof(key_repeat_rate)) 537 != B_OK) 538 return B_BAD_ADDRESS; 539 if (set_typematic(key_repeat_rate, sKeyboardRepeatDelay) != B_OK) 540 return B_ERROR; 541 sKeyboardRepeatRate = key_repeat_rate; 542 return B_OK; 543 } 544 545 case KB_GET_KEY_REPEAT_RATE: 546 { 547 TRACE("ps2: ioctl KB_GET_KEY_REPEAT_RATE\n"); 548 return user_memcpy(buffer, &sKeyboardRepeatRate, 549 sizeof(sKeyboardRepeatRate)); 550 } 551 552 case KB_SET_KEY_REPEAT_DELAY: 553 { 554 bigtime_t key_repeat_delay; 555 TRACE("ps2: ioctl KB_SET_KEY_REPEAT_DELAY\n"); 556 if (user_memcpy(&key_repeat_delay, buffer, sizeof(key_repeat_delay)) 557 != B_OK) 558 return B_BAD_ADDRESS; 559 if (set_typematic(sKeyboardRepeatRate, key_repeat_delay) != B_OK) 560 return B_ERROR; 561 sKeyboardRepeatDelay = key_repeat_delay; 562 return B_OK; 563 564 } 565 566 case KB_GET_KEY_REPEAT_DELAY: 567 { 568 TRACE("ps2: ioctl KB_GET_KEY_REPEAT_DELAY\n"); 569 return user_memcpy(buffer, &sKeyboardRepeatDelay, 570 sizeof(sKeyboardRepeatDelay)); 571 } 572 573 case KB_GET_KEYBOARD_ID: 574 { 575 TRACE("ps2: ioctl KB_GET_KEYBOARD_ID\n"); 576 uint16 keyboardId = sKeyboardIds[1] << 8 | sKeyboardIds[0]; 577 return user_memcpy(buffer, &keyboardId, sizeof(keyboardId)); 578 } 579 580 case KB_SET_CONTROL_ALT_DEL_TIMEOUT: 581 case KB_CANCEL_CONTROL_ALT_DEL: 582 case KB_DELAY_CONTROL_ALT_DEL: 583 INFO("ps2: ioctl 0x%" B_PRIx32 " not implemented yet, returning " 584 "B_OK\n", op); 585 return B_OK; 586 587 case KB_SET_DEBUG_READER: 588 if (sHasDebugReader) 589 return B_BUSY; 590 591 cookie->is_debugger = true; 592 sHasDebugReader = true; 593 return B_OK; 594 595 default: 596 INFO("ps2: invalid ioctl 0x%" B_PRIx32 "\n", op); 597 return B_DEV_INVALID_IOCTL; 598 } 599 } 600 601 602 device_hooks gKeyboardDeviceHooks = { 603 keyboard_open, 604 keyboard_close, 605 keyboard_freecookie, 606 keyboard_ioctl, 607 keyboard_read, 608 keyboard_write, 609 }; 610