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