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 relyable on some notebooks (it reports 0x03) 297 // status = ps2_command(PS2_CTRL_KEYBOARD_TEST, NULL, 0, &data, 1); 298 // if (status != B_OK || data != 0x00) { 299 // INFO("ps2: keyboard test failed, status 0x%08lx, data 0x%02x\n", status, data); 300 // return B_ERROR; 301 // } 302 303 status = ps2_dev_command(&ps2_device[PS2_DEVICE_KEYB], PS2_CMD_RESET, NULL, 304 0, &data, 1); 305 // Checking for reset is unrealiable on some controllers. But we check 306 // ID which is good enough for linux and should be 307 // good enough for us. Reset itself is needed though. 308 if (status != B_OK || data != 0xaa) { 309 INFO("ps2: keyboard reset failed, status 0x%08" B_PRIx32 ", data 0x%02x" 310 "\n", status, data); 311 ids_read = 1; 312 status = ps2_dev_command(&ps2_device[PS2_DEVICE_KEYB], 313 PS2_CMD_GET_DEVICE_ID, NULL, 0, sKeyboardIds, sizeof(sKeyboardIds)); 314 if ((status != B_OK) || (sKeyboardIds[0] != 0xab && sKeyboardIds[0] != 0xac && /* Regular and NCD Sun keyboards */ 315 sKeyboardIds[0] != 0x2b && sKeyboardIds[0] != 0x5d && /* Trust keyboard, raw and translated */ 316 sKeyboardIds[0] != 0x60 && sKeyboardIds[0] != 0x47)) { /* NMB SGI keyboard, raw and translated */ 317 INFO("ps2: keyboard getid failed, status 0x%08" B_PRIx32 ", data 0x%02x%02x." 318 " Assuming no keyboard\n", status, sKeyboardIds[0], sKeyboardIds[1]); 319 return B_ERROR; 320 } 321 } 322 323 // default settings after keyboard reset: delay = 0x01 (500 ms), 324 // rate = 0x0b (10.9 chr/sec) 325 sKeyboardRepeatRate = ((31 - 0x0b) * 280) / 31 + 20; 326 sKeyboardRepeatDelay = 500000; 327 328 // status = ps2_dev_command(&ps2_device[PS2_DEVICE_KEYB], PS2_ENABLE_KEYBOARD, NULL, 0, NULL, 0); 329 330 // On my notebook, the keyboard controller does NACK the echo command. 331 // status = ps2_dev_command(&ps2_device[PS2_DEVICE_KEYB], PS2_CMD_ECHO, NULL, 0, &data, 1); 332 // if (status != B_OK || data != 0xee) { 333 // INFO("ps2: keyboard echo test failed, status 0x%08lx, data 0x%02x\n", status, data); 334 // return B_ERROR; 335 // } 336 337 // Some controllers set the disable keyboard command bit to "on" after resetting 338 // the keyboard device. Read #7973 #6313 for more details. 339 // So check the command byte now and re-enable the keyboard if it is the case. 340 uint8 cmdbyte = 0; 341 status = ps2_command(PS2_CTRL_READ_CMD, NULL, 0, &cmdbyte, 1); 342 343 if (status != B_OK) { 344 INFO("ps2: cannot read CMD byte on kbd probe:%#08" B_PRIx32 "\n", 345 status); 346 } else 347 if ((cmdbyte & PS2_BITS_KEYBOARD_DISABLED) == PS2_BITS_KEYBOARD_DISABLED) { 348 cmdbyte &= ~PS2_BITS_KEYBOARD_DISABLED; 349 status = ps2_command(PS2_CTRL_WRITE_CMD, &cmdbyte, 1, NULL, 0); 350 if (status != B_OK) { 351 INFO("ps2: cannot write 0x%02x to CMD byte on kbd probe:%#08" 352 B_PRIx32 "\n", cmdbyte, status); 353 } 354 } 355 356 if (!ids_read) { 357 status = ps2_dev_command(&ps2_device[PS2_DEVICE_KEYB], 358 PS2_CMD_GET_DEVICE_ID, NULL, 0, sKeyboardIds, sizeof(sKeyboardIds)); 359 360 if (status != B_OK) { 361 INFO("ps2: cannot read keyboard device id:%#08" B_PRIx32 "\n", status); 362 } 363 } 364 365 return B_OK; 366 } 367 368 369 // #pragma mark - 370 371 372 static status_t 373 keyboard_open(const char *name, uint32 flags, void **_cookie) 374 { 375 TRACE("ps2: keyboard_open %s\n", name); 376 377 keyboard_cookie* cookie = new(std::nothrow) keyboard_cookie(); 378 if (cookie == NULL) 379 return B_NO_MEMORY; 380 381 cookie->is_reader = false; 382 cookie->is_debugger = false; 383 384 MutexLocker locker(sInitializeLock); 385 386 if (atomic_get(&sKeyboardOpenCount) == 0) { 387 status_t status = probe_keyboard(); 388 if (status != B_OK) { 389 INFO("ps2: keyboard probing failed\n"); 390 ps2_service_notify_device_removed(&ps2_device[PS2_DEVICE_KEYB]); 391 delete cookie; 392 return status; 393 } 394 395 INFO("ps2: keyboard found\n"); 396 397 sKeyboardSem = create_sem(0, "keyboard_sem"); 398 if (sKeyboardSem < 0) { 399 delete cookie; 400 return sKeyboardSem; 401 } 402 403 sKeyBuffer 404 = create_packet_buffer(KEY_BUFFER_SIZE * sizeof(raw_key_info)); 405 if (sKeyBuffer == NULL) { 406 delete_sem(sKeyboardSem); 407 delete cookie; 408 return B_NO_MEMORY; 409 } 410 411 ps2_device[PS2_DEVICE_KEYB].disconnect = &ps2_keyboard_disconnect; 412 ps2_device[PS2_DEVICE_KEYB].handle_int = &keyboard_handle_int; 413 414 atomic_or(&ps2_device[PS2_DEVICE_KEYB].flags, PS2_FLAG_ENABLED); 415 } 416 417 atomic_add(&sKeyboardOpenCount, 1); 418 *_cookie = cookie; 419 420 TRACE("ps2: keyboard_open %s success\n", name); 421 return B_OK; 422 } 423 424 425 static status_t 426 keyboard_close(void *_cookie) 427 { 428 keyboard_cookie *cookie = (keyboard_cookie *)_cookie; 429 430 TRACE("ps2: keyboard_close enter\n"); 431 432 if (atomic_add(&sKeyboardOpenCount, -1) == 1) { 433 delete_packet_buffer(sKeyBuffer); 434 delete_sem(sKeyboardSem); 435 436 atomic_and(&ps2_device[PS2_DEVICE_KEYB].flags, ~PS2_FLAG_ENABLED); 437 438 sKeyboardIds[0] = sKeyboardIds[1] = 0; 439 } 440 441 if (cookie->is_reader) 442 sHasKeyboardReader = false; 443 if (cookie->is_debugger) 444 sHasDebugReader = false; 445 446 TRACE("ps2: keyboard_close done\n"); 447 return B_OK; 448 } 449 450 451 static status_t 452 keyboard_freecookie(void *cookie) 453 { 454 delete (keyboard_cookie*)cookie; 455 return B_OK; 456 } 457 458 459 static status_t 460 keyboard_read(void *cookie, off_t pos, void *buffer, size_t *_length) 461 { 462 TRACE("ps2: keyboard read\n"); 463 *_length = 0; 464 return B_NOT_ALLOWED; 465 } 466 467 468 static status_t 469 keyboard_write(void *cookie, off_t pos, const void *buffer, size_t *_length) 470 { 471 TRACE("ps2: keyboard write\n"); 472 *_length = 0; 473 return B_NOT_ALLOWED; 474 } 475 476 477 static status_t 478 keyboard_ioctl(void *_cookie, uint32 op, void *buffer, size_t length) 479 { 480 keyboard_cookie *cookie = (keyboard_cookie *)_cookie; 481 482 switch (op) { 483 case KB_READ: 484 { 485 if (!sHasKeyboardReader && !cookie->is_debugger) { 486 cookie->is_reader = true; 487 sHasKeyboardReader = true; 488 } else if (!cookie->is_debugger && !cookie->is_reader) 489 return B_BUSY; 490 491 raw_key_info packet; 492 status_t status = read_keyboard_packet(&packet, 493 cookie->is_debugger); 494 TRACE("ps2: ioctl KB_READ: %s\n", strerror(status)); 495 if (status != B_OK) 496 return status; 497 498 return user_memcpy(buffer, &packet, sizeof(packet)); 499 } 500 501 case KB_SET_LEDS: 502 { 503 led_info info; 504 TRACE("ps2: ioctl KB_SET_LEDS\n"); 505 if (user_memcpy(&info, buffer, sizeof(led_info)) < B_OK) 506 return B_BAD_ADDRESS; 507 return set_leds(&info); 508 } 509 510 case KB_SET_KEY_REPEATING: 511 { 512 TRACE("ps2: ioctl KB_SET_KEY_REPEATING\n"); 513 // 0xFA (Set All Keys Typematic/Make/Break) - Keyboard responds 514 // with "ack" (0xFA). 515 return ps2_dev_command(&ps2_device[PS2_DEVICE_KEYB], 0xfa, NULL, 0, 516 NULL, 0); 517 } 518 519 case KB_SET_KEY_NONREPEATING: 520 { 521 TRACE("ps2: ioctl KB_SET_KEY_NONREPEATING\n"); 522 // 0xF8 (Set All Keys Make/Break) - Keyboard responds with "ack" 523 // (0xFA). 524 return ps2_dev_command(&ps2_device[PS2_DEVICE_KEYB], 0xf8, NULL, 0, 525 NULL, 0); 526 } 527 528 case KB_SET_KEY_REPEAT_RATE: 529 { 530 int32 key_repeat_rate; 531 TRACE("ps2: ioctl KB_SET_KEY_REPEAT_RATE\n"); 532 if (user_memcpy(&key_repeat_rate, buffer, sizeof(key_repeat_rate)) 533 != B_OK) 534 return B_BAD_ADDRESS; 535 if (set_typematic(key_repeat_rate, sKeyboardRepeatDelay) != B_OK) 536 return B_ERROR; 537 sKeyboardRepeatRate = key_repeat_rate; 538 return B_OK; 539 } 540 541 case KB_GET_KEY_REPEAT_RATE: 542 { 543 TRACE("ps2: ioctl KB_GET_KEY_REPEAT_RATE\n"); 544 return user_memcpy(buffer, &sKeyboardRepeatRate, 545 sizeof(sKeyboardRepeatRate)); 546 } 547 548 case KB_SET_KEY_REPEAT_DELAY: 549 { 550 bigtime_t key_repeat_delay; 551 TRACE("ps2: ioctl KB_SET_KEY_REPEAT_DELAY\n"); 552 if (user_memcpy(&key_repeat_delay, buffer, sizeof(key_repeat_delay)) 553 != B_OK) 554 return B_BAD_ADDRESS; 555 if (set_typematic(sKeyboardRepeatRate, key_repeat_delay) != B_OK) 556 return B_ERROR; 557 sKeyboardRepeatDelay = key_repeat_delay; 558 return B_OK; 559 560 } 561 562 case KB_GET_KEY_REPEAT_DELAY: 563 { 564 TRACE("ps2: ioctl KB_GET_KEY_REPEAT_DELAY\n"); 565 return user_memcpy(buffer, &sKeyboardRepeatDelay, 566 sizeof(sKeyboardRepeatDelay)); 567 } 568 569 case KB_GET_KEYBOARD_ID: 570 { 571 TRACE("ps2: ioctl KB_GET_KEYBOARD_ID\n"); 572 uint16 keyboardId = sKeyboardIds[1] << 8 | sKeyboardIds[0]; 573 return user_memcpy(buffer, &keyboardId, sizeof(keyboardId)); 574 } 575 576 case KB_SET_CONTROL_ALT_DEL_TIMEOUT: 577 case KB_CANCEL_CONTROL_ALT_DEL: 578 case KB_DELAY_CONTROL_ALT_DEL: 579 INFO("ps2: ioctl 0x%" B_PRIx32 " not implemented yet, returning " 580 "B_OK\n", op); 581 return B_OK; 582 583 case KB_SET_DEBUG_READER: 584 if (sHasDebugReader) 585 return B_BUSY; 586 587 cookie->is_debugger = true; 588 sHasDebugReader = true; 589 return B_OK; 590 591 default: 592 INFO("ps2: invalid ioctl 0x%" B_PRIx32 "\n", op); 593 return B_DEV_INVALID_IOCTL; 594 } 595 } 596 597 598 device_hooks gKeyboardDeviceHooks = { 599 keyboard_open, 600 keyboard_close, 601 keyboard_freecookie, 602 keyboard_ioctl, 603 keyboard_read, 604 keyboard_write, 605 }; 606