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