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