Changeset 20a3465 in mainline for uspace/drv/bus/usb/usbhid/kbd/kbddev.c
- Timestamp:
- 2011-10-30T19:50:54Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 3ce78580, 48902fa
- Parents:
- 4c3ad56 (diff), 45bf63c (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/usbhid/kbd/kbddev.c
r4c3ad56 r20a3465 88 88 89 89 /** Keyboard polling endpoint description for boot protocol class. */ 90 usb_endpoint_description_t usb_hid_kbd_poll_endpoint_description = {90 const usb_endpoint_description_t usb_hid_kbd_poll_endpoint_description = { 91 91 .transfer_type = USB_TRANSFER_INTERRUPT, 92 92 .direction = USB_DIRECTION_IN, … … 174 174 { 175 175 sysarg_t method = IPC_GET_IMETHOD(*icall); 176 176 177 177 usb_kbd_t *kbd_dev = (usb_kbd_t *) fun->driver_data; 178 178 if (kbd_dev == NULL) { … … 182 182 return; 183 183 } 184 184 185 185 async_sess_t *sess = 186 186 async_callback_receive_start(EXCHANGE_SERIALIZE, icall); … … 237 237 238 238 usb_hid_report_field_t *field = usb_hid_report_get_sibling( 239 hid_dev->report, NULL, kbd_dev->led_path,239 &hid_dev->report, NULL, kbd_dev->led_path, 240 240 USB_HID_PATH_COMPARE_END | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY, 241 241 USB_HID_REPORT_TYPE_OUTPUT); 242 242 243 243 while (field != NULL) { 244 245 if ((field->usage == USB_HID_LED_NUM_LOCK) 244 245 if ((field->usage == USB_HID_LED_NUM_LOCK) 246 246 && (kbd_dev->mods & KM_NUM_LOCK)){ 247 247 field->value = 1; 248 248 } 249 249 250 if ((field->usage == USB_HID_LED_CAPS_LOCK) 250 if ((field->usage == USB_HID_LED_CAPS_LOCK) 251 251 && (kbd_dev->mods & KM_CAPS_LOCK)){ 252 252 field->value = 1; 253 253 } 254 254 255 if ((field->usage == USB_HID_LED_SCROLL_LOCK) 255 if ((field->usage == USB_HID_LED_SCROLL_LOCK) 256 256 && (kbd_dev->mods & KM_SCROLL_LOCK)){ 257 257 field->value = 1; 258 258 } 259 260 field = usb_hid_report_get_sibling( hid_dev->report, field,261 kbd_dev->led_path,262 263 264 } 265 259 260 field = usb_hid_report_get_sibling( 261 &hid_dev->report, field, kbd_dev->led_path, 262 USB_HID_PATH_COMPARE_END | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY, 263 USB_HID_REPORT_TYPE_OUTPUT); 264 } 265 266 266 // TODO: what about the Report ID? 267 int rc = usb_hid_report_output_translate( hid_dev->report, 0,267 int rc = usb_hid_report_output_translate(&hid_dev->report, 0, 268 268 kbd_dev->output_buffer, kbd_dev->output_size); 269 269 270 270 if (rc != EOK) { 271 271 usb_log_warning("Error translating LED output to output report" … … 273 273 return; 274 274 } 275 275 276 276 usb_log_debug("Output report buffer: %s\n", 277 277 usb_debug_str_buffer(kbd_dev->output_buffer, kbd_dev->output_size, 278 278 0)); 279 279 280 280 usbhid_req_set_report(&hid_dev->usb_dev->ctrl_pipe, 281 281 hid_dev->usb_dev->interface_no, USB_HID_REPORT_TYPE_OUTPUT, … … 300 300 return; 301 301 } 302 302 303 303 async_exch_t *exch = async_exchange_begin(kbd_dev->console_sess); 304 304 async_msg_2(exch, KBDEV_EVENT, type, key); … … 347 347 unsigned int key; 348 348 size_t i; 349 349 350 350 /* 351 351 * First of all, check if the kbd have reported phantom state. … … 362 362 return; 363 363 } 364 364 365 365 /* 366 366 * Key releases … … 382 382 } 383 383 } 384 384 385 385 /* 386 386 * Key presses … … 402 402 } 403 403 } 404 404 405 405 memcpy(kbd_dev->keys_old, kbd_dev->keys, kbd_dev->key_count * 4); 406 406 407 407 char key_buffer[512]; 408 408 ddf_dump_buffer(key_buffer, 512, … … 432 432 static void usb_kbd_process_data(usb_hid_dev_t *hid_dev, usb_kbd_t *kbd_dev) 433 433 { 434 assert(hid_dev->report != NULL);435 434 assert(hid_dev != NULL); 436 435 assert(kbd_dev != NULL); 437 436 438 437 usb_hid_report_path_t *path = usb_hid_report_path(); 439 438 usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_KEYBOARD, 0); 440 439 441 440 usb_hid_report_path_set_report_id (path, hid_dev->report_id); 442 441 443 442 // fill in the currently pressed keys 444 443 445 444 usb_hid_report_field_t *field = usb_hid_report_get_sibling( 446 hid_dev->report, NULL, path,447 USB_HID_PATH_COMPARE_END | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY, 445 &hid_dev->report, NULL, path, 446 USB_HID_PATH_COMPARE_END | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY, 448 447 USB_HID_REPORT_TYPE_INPUT); 449 448 unsigned i = 0; 450 449 451 450 while (field != NULL) { 452 451 usb_log_debug2("FIELD (%p) - VALUE(%d) USAGE(%u)\n", … … 454 453 455 454 assert(i < kbd_dev->key_count); 456 455 457 456 // save the key usage 458 457 if (field->value != 0) { … … 463 462 } 464 463 usb_log_debug2("Saved %u. key usage %d\n", i, kbd_dev->keys[i]); 465 464 466 465 ++i; 467 field = usb_hid_report_get_sibling( hid_dev->report, field, path,468 USB_HID_PATH_COMPARE_END469 | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY,466 field = usb_hid_report_get_sibling( 467 &hid_dev->report, field, path, USB_HID_PATH_COMPARE_END 468 | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY, 470 469 USB_HID_REPORT_TYPE_INPUT); 471 470 } 472 471 473 472 usb_hid_report_path_free(path); 474 473 475 474 usb_kbd_check_key_changes(hid_dev, kbd_dev); 476 475 } … … 502 501 503 502 if (kbd_dev == NULL) { 504 usb_log_ fatal("No memory!\n");503 usb_log_error("No memory!\n"); 505 504 return NULL; 506 505 } 507 506 508 507 kbd_dev->console_sess = NULL; 509 508 kbd_dev->initialized = USB_KBD_STATUS_UNINITIALIZED; 510 509 511 510 return kbd_dev; 512 511 } … … 514 513 /*----------------------------------------------------------------------------*/ 515 514 516 static int usb_kbd_create_function(usb_hid_dev_t *hid_dev, usb_kbd_t *kbd_dev) 517 { 518 assert(hid_dev != NULL); 519 assert(hid_dev->usb_dev != NULL); 515 static int usb_kbd_create_function(usb_kbd_t *kbd_dev) 516 { 520 517 assert(kbd_dev != NULL); 521 518 assert(kbd_dev->hid_dev != NULL); 519 assert(kbd_dev->hid_dev->usb_dev != NULL); 520 522 521 /* Create the exposed function. */ 523 522 usb_log_debug("Creating DDF function %s...\n", HID_KBD_FUN_NAME); 524 ddf_fun_t *fun = ddf_fun_create( hid_dev->usb_dev->ddf_dev, fun_exposed,525 HID_KBD_FUN_NAME);523 ddf_fun_t *fun = ddf_fun_create(kbd_dev->hid_dev->usb_dev->ddf_dev, 524 fun_exposed, HID_KBD_FUN_NAME); 526 525 if (fun == NULL) { 527 526 usb_log_error("Could not create DDF function node.\n"); 528 527 return ENOMEM; 529 528 } 530 529 531 530 /* 532 531 * Store the initialized HID device and HID ops … … 540 539 usb_log_error("Could not bind DDF function: %s.\n", 541 540 str_error(rc)); 541 fun->driver_data = NULL; /* We need this later */ 542 542 ddf_fun_destroy(fun); 543 543 return rc; 544 544 } 545 545 546 546 usb_log_debug("%s function created. Handle: %" PRIun "\n", 547 547 HID_KBD_FUN_NAME, fun->handle); 548 548 549 549 usb_log_debug("Adding DDF function to category %s...\n", 550 550 HID_KBD_CLASS_NAME); … … 554 554 "Could not add DDF function to category %s: %s.\n", 555 555 HID_KBD_CLASS_NAME, str_error(rc)); 556 fun->driver_data = NULL; /* We need this later */ 556 557 ddf_fun_destroy(fun); 557 558 return rc; 558 559 } 559 560 kbd_dev->fun = fun; 561 560 562 return EOK; 561 563 } … … 587 589 { 588 590 usb_log_debug("Initializing HID/KBD structure...\n"); 589 591 590 592 if (hid_dev == NULL) { 591 593 usb_log_error("Failed to init keyboard structure: no structure" … … 593 595 return EINVAL; 594 596 } 595 597 596 598 usb_kbd_t *kbd_dev = usb_kbd_new(); 597 599 if (kbd_dev == NULL) { … … 603 605 /* Store link to HID device */ 604 606 kbd_dev->hid_dev = hid_dev; 605 607 606 608 /* 607 609 * TODO: make more general … … 609 611 usb_hid_report_path_t *path = usb_hid_report_path(); 610 612 usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_KEYBOARD, 0); 611 613 612 614 usb_hid_report_path_set_report_id(path, 0); 613 615 614 616 kbd_dev->key_count = usb_hid_report_size( 615 hid_dev->report, 0, USB_HID_REPORT_TYPE_INPUT);617 &hid_dev->report, 0, USB_HID_REPORT_TYPE_INPUT); 616 618 usb_hid_report_path_free(path); 617 619 618 620 usb_log_debug("Size of the input report: %zu\n", kbd_dev->key_count); 619 620 kbd_dev->keys = (int32_t *)calloc(kbd_dev->key_count, sizeof(int32_t));621 621 622 kbd_dev->keys = calloc(kbd_dev->key_count, sizeof(int32_t)); 623 622 624 if (kbd_dev->keys == NULL) { 623 usb_log_ fatal("No memory!\n");625 usb_log_error("No memory!\n"); 624 626 free(kbd_dev); 625 627 return ENOMEM; 626 628 } 627 629 628 630 kbd_dev->keys_old = 629 631 (int32_t *)calloc(kbd_dev->key_count, sizeof(int32_t)); 630 632 631 633 if (kbd_dev->keys_old == NULL) { 632 usb_log_ fatal("No memory!\n");634 usb_log_error("No memory!\n"); 633 635 free(kbd_dev->keys); 634 636 free(kbd_dev); 635 637 return ENOMEM; 636 638 } 637 639 638 640 /* 639 641 * Output report 640 642 */ 641 643 kbd_dev->output_size = 0; 642 kbd_dev->output_buffer = usb_hid_report_output( hid_dev->report,644 kbd_dev->output_buffer = usb_hid_report_output(&hid_dev->report, 643 645 &kbd_dev->output_size, 0); 644 646 if (kbd_dev->output_buffer == NULL) { … … 647 649 return ENOMEM; 648 650 } 649 651 650 652 usb_log_debug("Output buffer size: %zu\n", kbd_dev->output_size); 651 653 652 654 kbd_dev->led_path = usb_hid_report_path(); 653 655 usb_hid_report_path_append_item( 654 656 kbd_dev->led_path, USB_HIDUT_PAGE_LED, 0); 655 656 kbd_dev->led_output_size = usb_hid_report_size( hid_dev->report,657 0, USB_HID_REPORT_TYPE_OUTPUT);658 657 658 kbd_dev->led_output_size = usb_hid_report_size( 659 &hid_dev->report, 0, USB_HID_REPORT_TYPE_OUTPUT); 660 659 661 usb_log_debug("Output report size (in items): %zu\n", 660 662 kbd_dev->led_output_size); 661 663 662 664 kbd_dev->led_data = (int32_t *)calloc( 663 665 kbd_dev->led_output_size, sizeof(int32_t)); 664 666 665 667 if (kbd_dev->led_data == NULL) { 666 668 usb_log_warning("Error creating buffer for LED output report." … … 671 673 return ENOMEM; 672 674 } 673 675 674 676 /* 675 677 * Modifiers and locks … … 678 680 kbd_dev->mods = DEFAULT_ACTIVE_MODS; 679 681 kbd_dev->lock_keys = 0; 680 682 681 683 /* 682 684 * Autorepeat … … 686 688 kbd_dev->repeat.delay_before = DEFAULT_DELAY_BEFORE_FIRST_REPEAT; 687 689 kbd_dev->repeat.delay_between = DEFAULT_REPEAT_DELAY; 688 689 kbd_dev->repeat_mtx = (fibril_mutex_t *)( 690 malloc(sizeof(fibril_mutex_t))); 691 if (kbd_dev->repeat_mtx == NULL) { 692 usb_log_fatal("No memory!\n"); 693 free(kbd_dev->keys); 694 usb_hid_report_output_free(kbd_dev->output_buffer); 695 free(kbd_dev); 696 return ENOMEM; 697 } 698 699 fibril_mutex_initialize(kbd_dev->repeat_mtx); 700 690 691 fibril_mutex_initialize(&kbd_dev->repeat_mtx); 692 701 693 // save the KBD device structure into the HID device structure 702 694 *data = kbd_dev; 703 695 704 696 // set handler for incoming calls 705 697 kbd_dev->ops.default_handler = default_connection_handler; 706 698 707 699 /* 708 700 * Set LEDs according to initial setup. … … 710 702 */ 711 703 usb_kbd_set_led(hid_dev, kbd_dev); 712 704 713 705 usbhid_req_set_idle(&hid_dev->usb_dev->ctrl_pipe, 714 706 hid_dev->usb_dev->interface_no, IDLE_RATE); 715 707 716 708 /* 717 709 * Create new fibril for auto-repeat … … 723 715 } 724 716 fibril_add_ready(fid); 725 717 726 718 kbd_dev->initialized = USB_KBD_STATUS_INITIALIZED; 727 719 usb_log_debug("HID/KBD device structure initialized.\n"); 728 720 729 721 usb_log_debug("Creating KBD function...\n"); 730 int rc = usb_kbd_create_function( hid_dev,kbd_dev);722 int rc = usb_kbd_create_function(kbd_dev); 731 723 if (rc != EOK) { 732 724 usb_kbd_destroy(kbd_dev); 733 725 return rc; 734 726 } 735 727 736 728 return EOK; 737 729 } … … 745 737 return false; 746 738 } 747 739 748 740 usb_kbd_t *kbd_dev = (usb_kbd_t *)data; 749 741 assert(kbd_dev != NULL); 750 742 751 743 // TODO: add return value from this function 752 744 usb_kbd_process_data(hid_dev, kbd_dev); 753 745 754 746 return true; 755 747 } … … 780 772 return; 781 773 } 782 774 783 775 // hangup session to the console 784 776 async_hangup(kbd_dev->console_sess); 785 786 if (kbd_dev->repeat_mtx != NULL) { 787 //assert(!fibril_mutex_is_locked((*kbd_dev)->repeat_mtx)); 788 // FIXME - the fibril_mutex_is_locked may not cause 789 // fibril scheduling 790 while (fibril_mutex_is_locked(kbd_dev->repeat_mtx)) {} 791 free(kbd_dev->repeat_mtx); 792 } 793 777 778 //assert(!fibril_mutex_is_locked((*kbd_dev)->repeat_mtx)); 779 // FIXME - the fibril_mutex_is_locked may not cause 780 // fibril scheduling 781 while (fibril_mutex_is_locked(&kbd_dev->repeat_mtx)) {} 782 794 783 // free all buffers 795 if (kbd_dev->keys != NULL) { 796 free(kbd_dev->keys); 797 } 798 if (kbd_dev->keys_old != NULL) { 799 free(kbd_dev->keys_old); 800 } 801 if (kbd_dev->led_data != NULL) { 802 free(kbd_dev->led_data); 803 } 784 free(kbd_dev->keys); 785 free(kbd_dev->keys_old); 786 free(kbd_dev->led_data); 787 804 788 if (kbd_dev->led_path != NULL) { 805 789 usb_hid_report_path_free(kbd_dev->led_path); … … 808 792 usb_hid_report_output_free(kbd_dev->output_buffer); 809 793 } 794 795 if (ddf_fun_unbind(kbd_dev->fun) != EOK) { 796 usb_log_warning("Failed to unbind kbd function.\n"); 797 } else { 798 usb_log_debug2("%s unbound.\n", kbd_dev->fun->name); 799 kbd_dev->fun->driver_data = NULL; 800 ddf_fun_destroy(kbd_dev->fun); 801 } 810 802 } 811 803 … … 817 809 return; 818 810 } 819 811 820 812 if (data != NULL) { 821 usb_kbd_t *kbd_dev = (usb_kbd_t *)data;813 usb_kbd_t *kbd_dev = data; 822 814 if (usb_kbd_is_initialized(kbd_dev)) { 823 815 usb_kbd_mark_unusable(kbd_dev); 824 } else { 816 /* wait for autorepeat */ 817 async_usleep(CHECK_DELAY); 825 818 usb_kbd_destroy(kbd_dev); 826 819 } … … 832 825 int usb_kbd_set_boot_protocol(usb_hid_dev_t *hid_dev) 833 826 { 834 int rc = usb_hid_parse_report_descriptor( hid_dev->report,835 USB_KBD_BOOT_REPORT_DESCRIPTOR,827 int rc = usb_hid_parse_report_descriptor( 828 &hid_dev->report, USB_KBD_BOOT_REPORT_DESCRIPTOR, 836 829 USB_KBD_BOOT_REPORT_DESCRIPTOR_SIZE); 837 830 838 831 if (rc != EOK) { 839 832 usb_log_error("Failed to parse boot report descriptor: %s\n", … … 841 834 return rc; 842 835 } 843 844 rc = usbhid_req_set_protocol(&hid_dev->usb_dev->ctrl_pipe, 836 837 rc = usbhid_req_set_protocol(&hid_dev->usb_dev->ctrl_pipe, 845 838 hid_dev->usb_dev->interface_no, USB_HID_PROTOCOL_BOOT); 846 839 847 840 if (rc != EOK) { 848 841 usb_log_warning("Failed to set boot protocol to the device: " … … 850 843 return rc; 851 844 } 852 845 853 846 return EOK; 854 847 }
Note:
See TracChangeset
for help on using the changeset viewer.