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