Changes in uspace/drv/usbhid/kbddev.c [d477734:dfe53af] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/usbhid/kbddev.c
rd477734 rdfe53af 37 37 #include <errno.h> 38 38 #include <str_error.h> 39 #include <fibril.h>40 39 #include <stdio.h> 41 40 … … 43 42 #include <ipc/kbd.h> 44 43 #include <async.h> 44 #include <fibril.h> 45 #include <fibril_synch.h> 45 46 46 47 #include <usb/usb.h> … … 56 57 #include "layout.h" 57 58 #include "conv.h" 59 #include "kbdrepeat.h" 58 60 59 61 /*----------------------------------------------------------------------------*/ … … 65 67 static const uint8_t BOOTP_ERROR_ROLLOVER = 1; 66 68 static const uint8_t IDLE_RATE = 0; 69 static const unsigned int DEFAULT_DELAY_BEFORE_FIRST_REPEAT = 500 * 1000; 70 static const unsigned int DEFAULT_REPEAT_DELAY = 50 * 1000; 67 71 68 72 /** Keyboard polling endpoint description for boot protocol class. */ … … 190 194 /*----------------------------------------------------------------------------*/ 191 195 192 static void usbhid_kbd_push_ev(usbhid_kbd_t *kbd_dev, int type, 193 unsigned int key) 196 void usbhid_kbd_push_ev(usbhid_kbd_t *kbd_dev, int type, unsigned int key) 194 197 { 195 198 console_event_t ev; 196 199 unsigned mod_mask; 197 200 198 // TODO: replace by our own parsing?? or are the key codes identical?? 201 /* 202 * These parts are copy-pasted from the AT keyboard driver. 203 * 204 * They definitely require some refactoring, but will keep it for later 205 * when the console and keyboard system is changed in HelenOS. 206 */ 199 207 switch (key) { 200 208 case KC_LCTRL: mod_mask = KM_LCTRL; break; … … 228 236 * up the lock state. 229 237 */ 238 unsigned int locks_old = kbd_dev->lock_keys; 239 230 240 kbd_dev->mods = 231 241 kbd_dev->mods ^ (mod_mask & ~kbd_dev->lock_keys); … … 233 243 234 244 /* Update keyboard lock indicator lights. */ 235 usbhid_kbd_set_led(kbd_dev); 245 if (kbd_dev->lock_keys != locks_old) { 246 usbhid_kbd_set_led(kbd_dev); 247 } 236 248 } else { 237 249 kbd_dev->lock_keys = kbd_dev->lock_keys & ~mod_mask; … … 328 340 i = 0; 329 341 // all fields should report Error Rollover 330 while (i < kbd_dev->key code_count &&342 while (i < kbd_dev->key_count && 331 343 key_codes[i] == BOOTP_ERROR_ROLLOVER) { 332 344 ++i; 333 345 } 334 if (i == kbd_dev->key code_count) {346 if (i == kbd_dev->key_count) { 335 347 usb_log_debug("Phantom state occured.\n"); 336 348 // phantom state, do nothing … … 343 355 * 1) Key releases 344 356 */ 345 for (j = 0; j < kbd_dev->key code_count; ++j) {357 for (j = 0; j < kbd_dev->key_count; ++j) { 346 358 // try to find the old key in the new key list 347 359 i = 0; 348 while (i < kbd_dev->key code_count349 && key_codes[i] != kbd_dev->key codes[j]) {360 while (i < kbd_dev->key_count 361 && key_codes[i] != kbd_dev->keys[j]) { 350 362 ++i; 351 363 } 352 364 353 if (i == kbd_dev->key code_count) {365 if (i == kbd_dev->key_count) { 354 366 // not found, i.e. the key was released 355 key = usbhid_parse_scancode(kbd_dev->keycodes[j]); 367 key = usbhid_parse_scancode(kbd_dev->keys[j]); 368 usbhid_kbd_repeat_stop(kbd_dev, key); 356 369 usbhid_kbd_push_ev(kbd_dev, KEY_RELEASE, key); 357 370 usb_log_debug2("Key released: %d\n", key); … … 364 377 * 1) Key presses 365 378 */ 366 for (i = 0; i < kbd_dev->key code_count; ++i) {379 for (i = 0; i < kbd_dev->key_count; ++i) { 367 380 // try to find the new key in the old key list 368 381 j = 0; 369 while (j < kbd_dev->key code_count370 && kbd_dev->key codes[j] != key_codes[i]) {382 while (j < kbd_dev->key_count 383 && kbd_dev->keys[j] != key_codes[i]) { 371 384 ++j; 372 385 } 373 386 374 if (j == kbd_dev->key code_count) {387 if (j == kbd_dev->key_count) { 375 388 // not found, i.e. new key pressed 376 389 key = usbhid_parse_scancode(key_codes[i]); … … 378 391 key_codes[i]); 379 392 usbhid_kbd_push_ev(kbd_dev, KEY_PRESS, key); 393 usbhid_kbd_repeat_start(kbd_dev, key); 380 394 } else { 381 395 // found, nothing happens … … 392 406 // } 393 407 394 memcpy(kbd_dev->key codes, key_codes, kbd_dev->keycode_count);408 memcpy(kbd_dev->keys, key_codes, kbd_dev->key_count); 395 409 396 410 usb_log_debug("New stored keycodes: %s\n", 397 usb_debug_str_buffer(kbd_dev->key codes, kbd_dev->keycode_count, 0));411 usb_debug_str_buffer(kbd_dev->keys, kbd_dev->key_count, 0)); 398 412 } 399 413 … … 415 429 416 430 usb_log_debug("Got keys from parser: %s\n", 417 usb_debug_str_buffer(key_codes, kbd_dev->key code_count, 0));418 419 if (count != kbd_dev->key code_count) {431 usb_debug_str_buffer(key_codes, kbd_dev->key_count, 0)); 432 433 if (count != kbd_dev->key_count) { 420 434 usb_log_warning("Number of received keycodes (%d) differs from" 421 " expected number (%d).\n", count, kbd_dev->key code_count);435 " expected number (%d).\n", count, kbd_dev->key_count); 422 436 return; 423 437 } … … 430 444 /* General kbd functions */ 431 445 /*----------------------------------------------------------------------------*/ 432 446 /** 447 * Processes data received from the device in form of report. 448 * 449 * This function uses the HID report parser to translate the data received from 450 * the device into generic USB HID key codes and into generic modifiers bitmap. 451 * The parser then calls the given callback (usbhid_kbd_process_keycodes()). 452 * 453 * @note Currently, only the boot protocol is supported. 454 * 455 * @param kbd_dev Keyboard device structure (must be initialized). 456 * @param buffer Data from the keyboard (i.e. the report). 457 * @param actual_size Size of the data from keyboard (report size) in bytes. 458 * 459 * @sa usbhid_kbd_process_keycodes(), usb_hid_boot_keyboard_input_report(). 460 */ 433 461 static void usbhid_kbd_process_data(usbhid_kbd_t *kbd_dev, 434 462 uint8_t *buffer, size_t actual_size) … … 455 483 /* HID/KBD structure manipulation */ 456 484 /*----------------------------------------------------------------------------*/ 457 485 /** 486 * Creates a new USB/HID keyboard structure. 487 * 488 * The structure returned by this function is not initialized. Use 489 * usbhid_kbd_init() to initialize it prior to polling. 490 * 491 * @return New uninitialized structure for representing a USB/HID keyboard or 492 * NULL if not successful (memory error). 493 */ 458 494 static usbhid_kbd_t *usbhid_kbd_new(void) 459 495 { … … 481 517 482 518 /*----------------------------------------------------------------------------*/ 483 519 /** 520 * Properly destroys the USB/HID keyboard structure. 521 * 522 * @param kbd_dev Pointer to the structure to be destroyed. 523 */ 484 524 static void usbhid_kbd_free(usbhid_kbd_t **kbd_dev) 485 525 { … … 496 536 } 497 537 538 if ((*kbd_dev)->repeat_mtx != NULL) { 539 /* TODO: replace by some check and wait */ 540 assert(!fibril_mutex_is_locked((*kbd_dev)->repeat_mtx)); 541 free((*kbd_dev)->repeat_mtx); 542 } 543 498 544 free(*kbd_dev); 499 545 *kbd_dev = NULL; … … 501 547 502 548 /*----------------------------------------------------------------------------*/ 503 549 /** 550 * Initialization of the USB/HID keyboard structure. 551 * 552 * This functions initializes required structures from the device's descriptors. 553 * 554 * During initialization, the keyboard is switched into boot protocol, the idle 555 * rate is set to 0 (infinity), resulting in the keyboard only reporting event 556 * when a key is pressed or released. Finally, the LED lights are turned on 557 * according to the default setup of lock keys. 558 * 559 * @note By default, the keyboards is initialized with Num Lock turned on and 560 * other locks turned off. 561 * 562 * @param kbd_dev Keyboard device structure to be initialized. 563 * @param dev DDF device structure of the keyboard. 564 * 565 * @retval EOK if successful. 566 * @retval EINVAL if some parameter is not given. 567 * @return Other value inherited from function usbhid_dev_init(). 568 */ 504 569 static int usbhid_kbd_init(usbhid_kbd_t *kbd_dev, ddf_dev_t *dev) 505 570 { … … 536 601 537 602 // save the size of the report (boot protocol report by default) 538 kbd_dev->key code_count = BOOTP_REPORT_SIZE;539 kbd_dev->key codes = (uint8_t *)calloc(540 kbd_dev->key code_count, sizeof(uint8_t));541 542 if (kbd_dev->key codes == NULL) {603 kbd_dev->key_count = BOOTP_REPORT_SIZE; 604 kbd_dev->keys = (uint8_t *)calloc( 605 kbd_dev->key_count, sizeof(uint8_t)); 606 607 if (kbd_dev->keys == NULL) { 543 608 usb_log_fatal("No memory!\n"); 544 return rc;609 return ENOMEM; 545 610 } 546 611 … … 549 614 kbd_dev->lock_keys = 0; 550 615 616 kbd_dev->repeat.key_new = 0; 617 kbd_dev->repeat.key_repeated = 0; 618 kbd_dev->repeat.delay_before = DEFAULT_DELAY_BEFORE_FIRST_REPEAT; 619 kbd_dev->repeat.delay_between = DEFAULT_REPEAT_DELAY; 620 621 kbd_dev->repeat_mtx = (fibril_mutex_t *)( 622 malloc(sizeof(fibril_mutex_t))); 623 if (kbd_dev->repeat_mtx == NULL) { 624 usb_log_fatal("No memory!\n"); 625 free(kbd_dev->keys); 626 return ENOMEM; 627 } 628 629 fibril_mutex_initialize(kbd_dev->repeat_mtx); 630 551 631 /* 552 632 * Set boot protocol. … … 571 651 /* HID/KBD polling */ 572 652 /*----------------------------------------------------------------------------*/ 573 653 /** 654 * Main keyboard polling function. 655 * 656 * This function uses the Interrupt In pipe of the keyboard to poll for events. 657 * The keyboard is initialized in a way that it reports only when a key is 658 * pressed or released, so there is no actual need for any sleeping between 659 * polls (see usbhid_kbd_try_add_device() or usbhid_kbd_init()). 660 * 661 * @param kbd_dev Initialized keyboard structure representing the device to 662 * poll. 663 * 664 * @sa usbhid_kbd_process_data() 665 */ 574 666 static void usbhid_kbd_poll(usbhid_kbd_t *kbd_dev) 575 667 { … … 639 731 640 732 /*----------------------------------------------------------------------------*/ 641 733 /** 734 * Function executed by the main driver fibril. 735 * 736 * Just starts polling the keyboard for events. 737 * 738 * @param arg Initialized keyboard device structure (of type usbhid_kbd_t) 739 * representing the device. 740 * 741 * @retval EOK if the fibril finished polling the device. 742 * @retval EINVAL if no device was given in the argument. 743 * 744 * @sa usbhid_kbd_poll() 745 * 746 * @todo Change return value - only case when the fibril finishes is in case 747 * of some error, so the error should probably be propagated from function 748 * usbhid_kbd_poll() to here and up. 749 */ 642 750 static int usbhid_kbd_fibril(void *arg) 643 751 { … … 661 769 /* API functions */ 662 770 /*----------------------------------------------------------------------------*/ 663 771 /** 772 * Function for adding a new device of type USB/HID/keyboard. 773 * 774 * This functions initializes required structures from the device's descriptors 775 * and starts a new fibril for polling the keyboard for events. 776 * 777 * During initialization, the keyboard is switched into boot protocol, the idle 778 * rate is set to 0 (infinity), resulting in the keyboard only reporting event 779 * when a key is pressed or released. Finally, the LED lights are turned on 780 * according to the default setup of lock keys. 781 * 782 * @note By default, the keyboards is initialized with Num Lock turned on and 783 * other locks turned off. 784 * @note Currently supports only boot-protocol keyboards. 785 * 786 * @param dev Device to add. 787 * 788 * @retval EOK if successful. 789 * @retval ENOMEM if there 790 * @return Other error code inherited from one of functions usbhid_kbd_init(), 791 * ddf_fun_bind() and ddf_fun_add_to_class(). 792 * 793 * @sa usbhid_kbd_fibril() 794 */ 664 795 int usbhid_kbd_try_add_device(ddf_dev_t *dev) 665 796 { … … 683 814 "structure.\n"); 684 815 ddf_fun_destroy(kbd_fun); 685 return E INVAL; // TODO: some other code??816 return ENOMEM; // TODO: some other code?? 686 817 } 687 818 … … 732 863 } 733 864 fibril_add_ready(fid); 865 866 /* 867 * Create new fibril for auto-repeat 868 */ 869 fid = fibril_create(usbhid_kbd_repeat_fibril, kbd_dev); 870 if (fid == 0) { 871 usb_log_error("Failed to start fibril for KBD auto-repeat"); 872 return ENOMEM; 873 } 874 fibril_add_ready(fid); 734 875 735 876 (void)keyboard_ops;
Note:
See TracChangeset
for help on using the changeset viewer.