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