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