Changes in / [8a02ff3:f8c190e] in mainline
- Location:
- uspace/drv/usbhid
- Files:
-
- 2 deleted
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/usbhid/Makefile
r8a02ff3 rf8c190e 42 42 hidreq.c \ 43 43 kbddev.c \ 44 kbdrepeat.c \45 44 hiddev.c \ 46 45 $(STOLEN_LAYOUT_SOURCES) -
uspace/drv/usbhid/kbddev.c
r8a02ff3 rf8c190e 37 37 #include <errno.h> 38 38 #include <str_error.h> 39 #include <fibril.h> 39 40 #include <stdio.h> 40 41 … … 42 43 #include <ipc/kbd.h> 43 44 #include <async.h> 44 #include <fibril.h>45 #include <fibril_synch.h>46 45 47 46 #include <usb/usb.h> … … 57 56 #include "layout.h" 58 57 #include "conv.h" 59 #include "kbdrepeat.h"60 58 61 59 /*----------------------------------------------------------------------------*/ … … 67 65 static const uint8_t BOOTP_ERROR_ROLLOVER = 1; 68 66 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;71 67 72 68 /** Keyboard polling endpoint description for boot protocol class. */ … … 194 190 /*----------------------------------------------------------------------------*/ 195 191 196 void usbhid_kbd_push_ev(usbhid_kbd_t *kbd_dev, int type, unsigned int key) 192 static void usbhid_kbd_push_ev(usbhid_kbd_t *kbd_dev, int type, 193 unsigned int key) 197 194 { 198 195 console_event_t ev; 199 196 unsigned mod_mask; 200 197 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 */ 198 // TODO: replace by our own parsing?? or are the key codes identical?? 207 199 switch (key) { 208 200 case KC_LCTRL: mod_mask = KM_LCTRL; break; … … 236 228 * up the lock state. 237 229 */ 238 unsigned int locks_old = kbd_dev->lock_keys;239 240 230 kbd_dev->mods = 241 231 kbd_dev->mods ^ (mod_mask & ~kbd_dev->lock_keys); … … 243 233 244 234 /* Update keyboard lock indicator lights. */ 245 if (kbd_dev->lock_keys != locks_old) { 246 usbhid_kbd_set_led(kbd_dev); 247 } 235 usbhid_kbd_set_led(kbd_dev); 248 236 } else { 249 237 kbd_dev->lock_keys = kbd_dev->lock_keys & ~mod_mask; … … 340 328 i = 0; 341 329 // all fields should report Error Rollover 342 while (i < kbd_dev->key _count &&330 while (i < kbd_dev->keycode_count && 343 331 key_codes[i] == BOOTP_ERROR_ROLLOVER) { 344 332 ++i; 345 333 } 346 if (i == kbd_dev->key _count) {334 if (i == kbd_dev->keycode_count) { 347 335 usb_log_debug("Phantom state occured.\n"); 348 336 // phantom state, do nothing … … 355 343 * 1) Key releases 356 344 */ 357 for (j = 0; j < kbd_dev->key _count; ++j) {345 for (j = 0; j < kbd_dev->keycode_count; ++j) { 358 346 // try to find the old key in the new key list 359 347 i = 0; 360 while (i < kbd_dev->key _count361 && key_codes[i] != kbd_dev->key s[j]) {348 while (i < kbd_dev->keycode_count 349 && key_codes[i] != kbd_dev->keycodes[j]) { 362 350 ++i; 363 351 } 364 352 365 if (i == kbd_dev->key _count) {353 if (i == kbd_dev->keycode_count) { 366 354 // not found, i.e. the key was released 367 key = usbhid_parse_scancode(kbd_dev->keys[j]); 368 usbhid_kbd_repeat_stop(kbd_dev, key); 355 key = usbhid_parse_scancode(kbd_dev->keycodes[j]); 369 356 usbhid_kbd_push_ev(kbd_dev, KEY_RELEASE, key); 370 357 usb_log_debug2("Key released: %d\n", key); … … 377 364 * 1) Key presses 378 365 */ 379 for (i = 0; i < kbd_dev->key _count; ++i) {366 for (i = 0; i < kbd_dev->keycode_count; ++i) { 380 367 // try to find the new key in the old key list 381 368 j = 0; 382 while (j < kbd_dev->key _count383 && kbd_dev->key s[j] != key_codes[i]) {369 while (j < kbd_dev->keycode_count 370 && kbd_dev->keycodes[j] != key_codes[i]) { 384 371 ++j; 385 372 } 386 373 387 if (j == kbd_dev->key _count) {374 if (j == kbd_dev->keycode_count) { 388 375 // not found, i.e. new key pressed 389 376 key = usbhid_parse_scancode(key_codes[i]); … … 391 378 key_codes[i]); 392 379 usbhid_kbd_push_ev(kbd_dev, KEY_PRESS, key); 393 usbhid_kbd_repeat_start(kbd_dev, key);394 380 } else { 395 381 // found, nothing happens … … 406 392 // } 407 393 408 memcpy(kbd_dev->key s, key_codes, kbd_dev->key_count);394 memcpy(kbd_dev->keycodes, key_codes, kbd_dev->keycode_count); 409 395 410 396 usb_log_debug("New stored keycodes: %s\n", 411 usb_debug_str_buffer(kbd_dev->key s, kbd_dev->key_count, 0));397 usb_debug_str_buffer(kbd_dev->keycodes, kbd_dev->keycode_count, 0)); 412 398 } 413 399 … … 429 415 430 416 usb_log_debug("Got keys from parser: %s\n", 431 usb_debug_str_buffer(key_codes, kbd_dev->key _count, 0));432 433 if (count != kbd_dev->key _count) {417 usb_debug_str_buffer(key_codes, kbd_dev->keycode_count, 0)); 418 419 if (count != kbd_dev->keycode_count) { 434 420 usb_log_warning("Number of received keycodes (%d) differs from" 435 " expected number (%d).\n", count, kbd_dev->key _count);421 " expected number (%d).\n", count, kbd_dev->keycode_count); 436 422 return; 437 423 } … … 444 430 /* General kbd functions */ 445 431 /*----------------------------------------------------------------------------*/ 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 */ 432 461 433 static void usbhid_kbd_process_data(usbhid_kbd_t *kbd_dev, 462 434 uint8_t *buffer, size_t actual_size) … … 483 455 /* HID/KBD structure manipulation */ 484 456 /*----------------------------------------------------------------------------*/ 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 */ 457 494 458 static usbhid_kbd_t *usbhid_kbd_new(void) 495 459 { … … 517 481 518 482 /*----------------------------------------------------------------------------*/ 519 /** 520 * Properly destroys the USB/HID keyboard structure. 521 * 522 * @param kbd_dev Pointer to the structure to be destroyed. 523 */ 483 524 484 static void usbhid_kbd_free(usbhid_kbd_t **kbd_dev) 525 485 { … … 536 496 } 537 497 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 544 498 free(*kbd_dev); 545 499 *kbd_dev = NULL; … … 547 501 548 502 /*----------------------------------------------------------------------------*/ 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 */ 503 569 504 static int usbhid_kbd_init(usbhid_kbd_t *kbd_dev, ddf_dev_t *dev) 570 505 { … … 601 536 602 537 // save the size of the report (boot protocol report by default) 603 kbd_dev->key _count = BOOTP_REPORT_SIZE;604 kbd_dev->key s = (uint8_t *)calloc(605 kbd_dev->key _count, sizeof(uint8_t));606 607 if (kbd_dev->key s == NULL) {538 kbd_dev->keycode_count = BOOTP_REPORT_SIZE; 539 kbd_dev->keycodes = (uint8_t *)calloc( 540 kbd_dev->keycode_count, sizeof(uint8_t)); 541 542 if (kbd_dev->keycodes == NULL) { 608 543 usb_log_fatal("No memory!\n"); 609 return ENOMEM;544 return rc; 610 545 } 611 546 … … 614 549 kbd_dev->lock_keys = 0; 615 550 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 631 551 /* 632 552 * Set boot protocol. … … 651 571 /* HID/KBD polling */ 652 572 /*----------------------------------------------------------------------------*/ 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 */ 573 666 574 static void usbhid_kbd_poll(usbhid_kbd_t *kbd_dev) 667 575 { … … 731 639 732 640 /*----------------------------------------------------------------------------*/ 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 */ 641 750 642 static int usbhid_kbd_fibril(void *arg) 751 643 { … … 769 661 /* API functions */ 770 662 /*----------------------------------------------------------------------------*/ 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 */ 663 795 664 int usbhid_kbd_try_add_device(ddf_dev_t *dev) 796 665 { … … 814 683 "structure.\n"); 815 684 ddf_fun_destroy(kbd_fun); 816 return E NOMEM; // TODO: some other code??685 return EINVAL; // TODO: some other code?? 817 686 } 818 687 … … 863 732 } 864 733 fibril_add_ready(fid); 865 866 /*867 * Create new fibril for auto-repeat868 */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);875 734 876 735 (void)keyboard_ops; -
uspace/drv/usbhid/kbddev.h
r8a02ff3 rf8c190e 39 39 #include <stdint.h> 40 40 41 #include <fibril_synch.h>42 43 41 #include <usb/classes/hid.h> 44 42 #include <ddf/driver.h> … … 48 46 49 47 /*----------------------------------------------------------------------------*/ 48 50 49 /** 51 * Structure for keeping information needed for auto-repeat of keys.50 * @brief USB/HID keyboard device type. 52 51 */ 53 52 typedef struct { 54 /** Last pressed key. */55 unsigned int key_new;56 /** Key to be repeated. */57 unsigned int key_repeated;58 /** Delay before first repeat in microseconds. */59 unsigned int delay_before;60 /** Delay between repeats in microseconds. */61 unsigned int delay_between;62 } usbhid_kbd_repeat_t;63 64 /**65 * USB/HID keyboard device type.66 *67 * Holds a reference to generic USB/HID device structure and keyboard-specific68 * data, such as currently pressed keys, modifiers and lock keys.69 *70 * Also holds a IPC phone to the console (since there is now no other way to71 * communicate with it).72 *73 * @note Storing active lock keys in this structure results in their setting74 * being device-specific.75 */76 typedef struct {77 /** Structure holding generic USB/HID device information. */78 53 usbhid_dev_t *hid_dev; 79 54 80 /** Currently pressed keys (not translated to key codes). */ 81 uint8_t *keys; 82 /** Count of stored keys (i.e. number of keys in the report). */ 83 size_t key_count; 84 /** Currently pressed modifiers (bitmap). */ 55 uint8_t *keycodes; 56 size_t keycode_count; 85 57 uint8_t modifiers; 86 58 87 /** Currently active modifiers including locks. Sent to the console. */88 59 unsigned mods; 89 90 /** Currently active lock keys. */91 60 unsigned lock_keys; 92 61 93 /** IPC phone to the console device (for sending key events). */94 62 int console_phone; 95 63 96 /** Information for auto-repeat of keys. */97 usbhid_kbd_repeat_t repeat;98 99 /** Mutex for accessing the information about auto-repeat. */100 fibril_mutex_t *repeat_mtx;101 102 /** State of the structure (for checking before use). */103 64 int initialized; 104 65 } usbhid_kbd_t; … … 108 69 int usbhid_kbd_try_add_device(ddf_dev_t *dev); 109 70 110 void usbhid_kbd_push_ev(usbhid_kbd_t *kbd_dev, int type, unsigned int key);111 112 71 #endif /* USBHID_KBDDEV_H_ */ 113 72 -
uspace/drv/usbhid/main.c
r8a02ff3 rf8c190e 47 47 48 48 /*----------------------------------------------------------------------------*/ 49 /** 50 * Callback for passing a new device to the driver. 51 * 52 * @note Currently, only boot-protocol keyboards are supported by this driver. 53 * 54 * @param dev Structure representing the new device. 55 * 56 * @retval EOK if successful. 57 * @retval EREFUSED if the device is not supported. 58 */ 49 59 50 static int usbhid_add_device(ddf_dev_t *dev) 60 51 {
Note:
See TracChangeset
for help on using the changeset viewer.