Changeset 20a3465 in mainline for uspace/drv/bus/usb/usbhid
- Timestamp:
- 2011-10-30T19:50:54Z (14 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. - Location:
- uspace/drv/bus/usb/usbhid
- Files:
-
- 15 edited
-
generic/hiddev.c (modified) (12 diffs)
-
generic/hiddev.h (modified) (2 diffs)
-
kbd/conv.c (modified) (7 diffs)
-
kbd/kbddev.c (modified) (34 diffs)
-
kbd/kbddev.h (modified) (2 diffs)
-
kbd/kbdrepeat.c (modified) (7 diffs)
-
kbd/kbdrepeat.h (modified) (1 diff)
-
main.c (modified) (10 diffs)
-
mouse/mousedev.c (modified) (28 diffs)
-
mouse/mousedev.h (modified) (1 diff)
-
multimedia/multimedia.c (modified) (10 diffs)
-
subdrivers.c (modified) (3 diffs)
-
subdrivers.h (modified) (2 diffs)
-
usbhid.c (modified) (35 diffs)
-
usbhid.h (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/usbhid/generic/hiddev.c
r4c3ad56 r20a3465 48 48 /*----------------------------------------------------------------------------*/ 49 49 50 usb_endpoint_description_t usb_hid_generic_poll_endpoint_description = {50 const usb_endpoint_description_t usb_hid_generic_poll_endpoint_description = { 51 51 .transfer_type = USB_TRANSFER_INTERRUPT, 52 52 .direction = USB_DIRECTION_IN, 53 53 .interface_class = USB_CLASS_HID, 54 .interface_subclass = -1, 55 .interface_protocol = -1, 54 56 .flags = 0 55 57 }; … … 92 94 usb_log_debug2("Generic HID: Get event length (fun: %p, " 93 95 "fun->driver_data: %p.\n", fun, fun->driver_data); 94 96 95 97 if (fun == NULL || fun->driver_data == NULL) { 96 98 return 0; … … 98 100 99 101 usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)fun->driver_data; 100 102 101 103 usb_log_debug2("hid_dev: %p, Max input report size (%zu).\n", 102 104 hid_dev, hid_dev->max_input_report_size); 103 105 104 106 return hid_dev->max_input_report_size; 105 107 } … … 111 113 { 112 114 usb_log_debug2("Generic HID: Get event.\n"); 113 115 114 116 if (fun == NULL || fun->driver_data == NULL || buffer == NULL 115 117 || act_size == NULL || event_nr == NULL) { … … 119 121 120 122 usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)fun->driver_data; 121 123 122 124 if (hid_dev->input_report_size > size) { 123 125 usb_log_debug("input_report_size > size (%zu, %zu)\n", … … 125 127 return EINVAL; // TODO: other error code 126 128 } 127 129 128 130 /*! @todo This should probably be somehow atomic. */ 129 131 memcpy(buffer, hid_dev->input_report, … … 131 133 *act_size = hid_dev->input_report_size; 132 134 *event_nr = usb_hid_report_number(hid_dev); 133 135 134 136 usb_log_debug2("OK\n"); 135 137 136 138 return EOK; 137 139 } … … 142 144 { 143 145 usb_log_debug("Generic HID: Get report descriptor length.\n"); 144 146 145 147 if (fun == NULL || fun->driver_data == NULL) { 146 148 usb_log_debug("No function"); 147 149 return EINVAL; 148 150 } 149 150 usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)fun->driver_data; 151 151 152 usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)fun->driver_data; 153 152 154 usb_log_debug2("hid_dev->report_desc_size = %zu\n", 153 155 hid_dev->report_desc_size); 154 156 155 157 return hid_dev->report_desc_size; 156 158 } … … 162 164 { 163 165 usb_log_debug2("Generic HID: Get report descriptor.\n"); 164 166 165 167 if (fun == NULL || fun->driver_data == NULL) { 166 168 usb_log_debug("No function"); 167 169 return EINVAL; 168 170 } 169 170 usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)fun->driver_data; 171 171 172 usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)fun->driver_data; 173 172 174 if (hid_dev->report_desc_size > size) { 173 175 return EINVAL; 174 176 } 175 177 176 178 memcpy(desc, hid_dev->report_desc, hid_dev->report_desc_size); 177 179 *actual_size = hid_dev->report_desc_size; 178 180 179 181 return EOK; 180 182 } … … 190 192 /*----------------------------------------------------------------------------*/ 191 193 192 static int usb_generic_hid_create_function(usb_hid_dev_t *hid_dev) 193 { 194 void usb_generic_hid_deinit(usb_hid_dev_t *hid_dev, void *data) 195 { 196 ddf_fun_t *fun = data; 197 const int ret = ddf_fun_unbind(fun); 198 if (ret != EOK) { 199 usb_log_error("Failed to unbind generic hid fun.\n"); 200 return; 201 } 202 usb_log_debug2("%s unbound.\n", fun->name); 203 /* We did not allocate this, so leave this alone 204 * the device would take care of it */ 205 fun->driver_data = NULL; 206 ddf_fun_destroy(fun); 207 } 208 209 /*----------------------------------------------------------------------------*/ 210 211 int usb_generic_hid_init(usb_hid_dev_t *hid_dev, void **data) 212 { 213 if (hid_dev == NULL) { 214 return EINVAL; 215 } 216 194 217 /* Create the exposed function. */ 195 218 /** @todo Generate numbers for the devices? */ … … 201 224 return ENOMEM; 202 225 } 203 226 204 227 fun->ops = &usb_generic_hid_ops; 205 fun->driver_data = hid_dev;206 228 207 229 int rc = ddf_fun_bind(fun); … … 212 234 return rc; 213 235 } 214 236 /* This is nasty both device and this function have the same 237 * driver data, thus destruction would lead to double free */ 238 fun->driver_data = hid_dev; 239 215 240 usb_log_debug("HID function created. Handle: %" PRIun "\n", fun->handle); 216 217 return EOK; 218 } 219 220 /*----------------------------------------------------------------------------*/ 221 222 int usb_generic_hid_init(usb_hid_dev_t *hid_dev, void **data) 223 { 224 if (hid_dev == NULL) { 225 return EINVAL; 226 } 227 228 return usb_generic_hid_create_function(hid_dev); 241 *data = fun; 242 243 return EOK; 229 244 } 230 245 -
uspace/drv/bus/usb/usbhid/generic/hiddev.h
r4c3ad56 r20a3465 41 41 struct usb_hid_dev; 42 42 43 usb_endpoint_description_t usb_hid_generic_poll_endpoint_description; 43 extern const usb_endpoint_description_t 44 usb_hid_generic_poll_endpoint_description; 44 45 45 46 const char *HID_GENERIC_FUN_NAME; … … 50 51 int usb_generic_hid_init(struct usb_hid_dev *hid_dev, void **data); 51 52 53 void usb_generic_hid_deinit(struct usb_hid_dev *hid_dev, void *data); 54 52 55 bool usb_generic_hid_polling_callback(struct usb_hid_dev *hid_dev, void *data); 53 56 -
uspace/drv/bus/usb/usbhid/kbd/conv.c
r4c3ad56 r20a3465 87 87 [0x26] = KC_9, 88 88 [0x27] = KC_0, 89 89 90 90 [0x28] = KC_ENTER, 91 91 [0x29] = KC_ESCAPE, … … 109 109 110 110 [0x39] = KC_CAPS_LOCK, 111 111 112 112 [0x3a] = KC_F1, 113 113 [0x3b] = KC_F2, … … 122 122 [0x44] = KC_F11, 123 123 [0x45] = KC_F12, 124 124 125 125 [0x46] = KC_PRTSCR, 126 126 [0x47] = KC_SCROLL_LOCK, … … 136 136 [0x51] = KC_DOWN, 137 137 [0x52] = KC_UP, 138 138 139 139 //[0x64] = // some funny key 140 140 141 141 [0xe0] = KC_LCTRL, 142 142 [0xe1] = KC_LSHIFT, … … 147 147 [0xe6] = KC_RALT, 148 148 //[0xe7] = KC_R // TODO: right GUI 149 149 150 150 [0x53] = KC_NUM_LOCK, 151 151 [0x54] = KC_NSLASH, … … 165 165 [0x62] = KC_N0, 166 166 [0x63] = KC_NPERIOD 167 167 168 168 }; 169 169 … … 186 186 187 187 key = map[scancode]; 188 188 189 189 return key; 190 190 } -
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 USB_HID_PATH_COMPARE_END | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY,263 USB_HID_REPORT_TYPE_OUTPUT);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 } -
uspace/drv/bus/usb/usbhid/kbd/kbddev.h
r4c3ad56 r20a3465 75 75 /** Currently pressed modifiers (bitmap). */ 76 76 uint8_t modifiers; 77 77 78 78 /** Currently active modifiers including locks. Sent to the console. */ 79 79 unsigned mods; 80 80 81 81 /** Currently active lock keys. */ 82 82 unsigned lock_keys; 83 83 84 84 /** IPC session to the console device (for sending key events). */ 85 85 async_sess_t *console_sess; 86 86 87 87 /** @todo What is this actually? */ 88 88 ddf_dev_ops_t ops; 89 89 90 90 /** Information for auto-repeat of keys. */ 91 91 usb_kbd_repeat_t repeat; 92 92 93 93 /** Mutex for accessing the information about auto-repeat. */ 94 fibril_mutex_t *repeat_mtx;95 94 fibril_mutex_t repeat_mtx; 95 96 96 uint8_t *output_buffer; 97 97 98 98 size_t output_size; 99 99 100 100 size_t led_output_size; 101 101 102 102 usb_hid_report_path_t *led_path; 103 103 104 104 int32_t *led_data; 105 105 106 106 /** State of the structure (for checking before use). 107 107 * … … 111 111 */ 112 112 int initialized; 113 114 /** DDF function */ 115 ddf_fun_t *fun; 113 116 } usb_kbd_t; 114 117 115 118 /*----------------------------------------------------------------------------*/ 116 119 117 usb_endpoint_description_t usb_hid_kbd_poll_endpoint_description;120 extern const usb_endpoint_description_t usb_hid_kbd_poll_endpoint_description; 118 121 119 122 const char *HID_KBD_FUN_NAME; -
uspace/drv/bus/usb/usbhid/kbd/kbdrepeat.c
r4c3ad56 r20a3465 46 46 47 47 48 /** Delay between auto-repeat state checks when no key is being repeated. */49 static unsigned int CHECK_DELAY = 10000;50 48 51 49 /*----------------------------------------------------------------------------*/ … … 73 71 { 74 72 unsigned int delay = 0; 75 73 76 74 usb_log_debug("Starting autorepeat loop.\n"); 77 75 … … 79 77 // check if the kbd structure is usable 80 78 if (!usb_kbd_is_initialized(kbd)) { 81 if (usb_kbd_is_ready_to_destroy(kbd)) { 82 usb_kbd_destroy(kbd); 83 } 79 usb_log_warning("kbd not ready, exiting autorepeat.\n"); 84 80 return; 85 81 } 86 82 87 fibril_mutex_lock( kbd->repeat_mtx);83 fibril_mutex_lock(&kbd->repeat_mtx); 88 84 89 85 if (kbd->repeat.key_new > 0) { … … 109 105 delay = CHECK_DELAY; 110 106 } 111 fibril_mutex_unlock( kbd->repeat_mtx);107 fibril_mutex_unlock(&kbd->repeat_mtx); 112 108 113 109 async_usleep(delay); … … 130 126 { 131 127 usb_log_debug("Autorepeat fibril spawned.\n"); 132 128 133 129 if (arg == NULL) { 134 130 usb_log_error("No device!\n"); 135 131 return EINVAL; 136 132 } 137 133 138 134 usb_kbd_t *kbd = (usb_kbd_t *)arg; 139 135 140 136 usb_kbd_repeat_loop(kbd); 141 137 142 138 return EOK; 143 139 } … … 156 152 void usb_kbd_repeat_start(usb_kbd_t *kbd, unsigned int key) 157 153 { 158 fibril_mutex_lock( kbd->repeat_mtx);154 fibril_mutex_lock(&kbd->repeat_mtx); 159 155 kbd->repeat.key_new = key; 160 fibril_mutex_unlock( kbd->repeat_mtx);156 fibril_mutex_unlock(&kbd->repeat_mtx); 161 157 } 162 158 … … 174 170 void usb_kbd_repeat_stop(usb_kbd_t *kbd, unsigned int key) 175 171 { 176 fibril_mutex_lock( kbd->repeat_mtx);172 fibril_mutex_lock(&kbd->repeat_mtx); 177 173 if (key == kbd->repeat.key_new) { 178 174 kbd->repeat.key_new = 0; 179 175 } 180 fibril_mutex_unlock( kbd->repeat_mtx);176 fibril_mutex_unlock(&kbd->repeat_mtx); 181 177 } 182 178 -
uspace/drv/bus/usb/usbhid/kbd/kbdrepeat.h
r4c3ad56 r20a3465 37 37 #define USB_HID_KBDREPEAT_H_ 38 38 39 /** Delay between auto-repeat state checks when no key is being repeated. */ 40 #define CHECK_DELAY 10000 41 39 42 struct usb_kbd_t; 40 43 -
uspace/drv/bus/usb/usbhid/main.c
r4c3ad56 r20a3465 46 46 #include "usbhid.h" 47 47 48 /*----------------------------------------------------------------------------*/49 50 48 #define NAME "usbhid" 51 49 … … 67 65 * 68 66 * @param dev Device to add. 69 * 70 * @retval EOK if successful. 71 * @retval ENOMEM if there 72 * @return Other error code inherited from one of functions usb_kbd_init(), 73 * ddf_fun_bind() and ddf_fun_add_to_class(). 67 * @return Error code. 74 68 */ 75 69 static int usb_hid_try_add_device(usb_device_t *dev) 76 70 { 77 71 assert(dev != NULL); 78 79 /* 80 * Initialize device (get and process descriptors, get address, etc.) 81 */ 72 73 /* Initialize device (get and process descriptors, get address, etc.) */ 82 74 usb_log_debug("Initializing USB/HID device...\n"); 83 84 usb_hid_dev_t *hid_dev = usb_hid_new(); 75 76 usb_hid_dev_t *hid_dev = 77 usb_device_data_alloc(dev, sizeof(usb_hid_dev_t)); 85 78 if (hid_dev == NULL) { 86 79 usb_log_error("Error while creating USB/HID device " … … 88 81 return ENOMEM; 89 82 } 90 83 91 84 int rc = usb_hid_init(hid_dev, dev); 92 85 93 86 if (rc != EOK) { 94 87 usb_log_error("Failed to initialize USB/HID device.\n"); 95 usb_hid_de stroy(hid_dev);88 usb_hid_deinit(hid_dev); 96 89 return rc; 97 } 98 90 } 91 99 92 usb_log_debug("USB/HID device structure initialized.\n"); 100 93 101 94 /* 102 95 * 1) subdriver vytvori vlastnu ddf_fun, vlastne ddf_dev_ops, ktore da … … 109 102 * pouzit usb/classes/hid/iface.h - prvy int je telefon 110 103 */ 111 104 112 105 /* Start automated polling function. 113 106 * This will create a separate fibril that will query the device … … 125 118 /* Custom argument. */ 126 119 hid_dev); 127 128 120 129 121 if (rc != EOK) { 130 122 usb_log_error("Failed to start polling fibril for `%s'.\n", 131 123 dev->ddf_dev->name); 124 usb_hid_deinit(hid_dev); 132 125 return rc; 133 126 } 127 hid_dev->running = true; 134 128 135 129 /* … … 138 132 return EOK; 139 133 } 140 141 134 /*----------------------------------------------------------------------------*/ 142 135 /** … … 146 139 * 147 140 * @param dev Structure representing the new device. 148 * 149 * @retval EOK if successful. 150 * @retval EREFUSED if the device is not supported. 141 * @return Error code. 151 142 */ 152 143 static int usb_hid_device_add(usb_device_t *dev) 153 144 { 154 145 usb_log_debug("usb_hid_device_add()\n"); 155 146 156 147 if (dev == NULL) { 157 148 usb_log_warning("Wrong parameter given for add_device().\n"); 158 149 return EINVAL; 159 150 } 160 151 161 152 if (dev->interface_no < 0) { 162 153 usb_log_warning("Device is not a supported HID device.\n"); … … 165 156 return ENOTSUP; 166 157 } 167 158 168 159 int rc = usb_hid_try_add_device(dev); 169 160 170 161 if (rc != EOK) { 171 162 usb_log_warning("Device is not a supported HID device.\n"); … … 174 165 return rc; 175 166 } 176 167 177 168 usb_log_info("HID device `%s' ready to use.\n", dev->ddf_dev->name); 178 169 179 170 return EOK; 180 171 } 181 182 /*----------------------------------------------------------------------------*/ 183 184 /* Currently, the framework supports only device adding. Once the framework 185 * supports unplug, more callbacks will be added. */ 186 static usb_driver_ops_t usb_hid_driver_ops = { 187 .device_add = usb_hid_device_add, 172 /*----------------------------------------------------------------------------*/ 173 /** 174 * Callback for a device about to be removed from the driver. 175 * 176 * @param dev Structure representing the device. 177 * @return Error code. 178 */ 179 static int usb_hid_device_rem(usb_device_t *dev) 180 { 181 return EOK; 182 } 183 /*----------------------------------------------------------------------------*/ 184 /** 185 * Callback for removing a device from the driver. 186 * 187 * @param dev Structure representing the device. 188 * @return Error code. 189 */ 190 static int usb_hid_device_gone(usb_device_t *dev) 191 { 192 usb_hid_dev_t *hid_dev = dev->driver_data; 193 unsigned tries = 10; 194 while (hid_dev->running) { 195 async_usleep(100000); 196 if (!tries--) { 197 usb_log_error("Can't remove hub, still running.\n"); 198 return EBUSY; 199 } 200 } 201 202 assert(!hid_dev->running); 203 usb_hid_deinit(hid_dev); 204 usb_log_debug2("%s destruction complete.\n", dev->ddf_dev->name); 205 return EOK; 206 } 207 /*----------------------------------------------------------------------------*/ 208 /** USB generic driver callbacks */ 209 static const usb_driver_ops_t usb_hid_driver_ops = { 210 .device_add = usb_hid_device_add, 211 .device_rem = usb_hid_device_rem, 212 .device_gone = usb_hid_device_gone, 188 213 }; 189 190 191 /* The driver itself. */ 192 static usb_driver_t usb_hid_driver = { 214 /*----------------------------------------------------------------------------*/ 215 /** The driver itself. */ 216 static const usb_driver_t usb_hid_driver = { 193 217 .name = NAME, 194 218 .ops = &usb_hid_driver_ops, 195 219 .endpoints = usb_hid_endpoints 196 220 }; 197 198 /*----------------------------------------------------------------------------*/ 199 221 /*----------------------------------------------------------------------------*/ 200 222 int main(int argc, char *argv[]) 201 223 { … … 206 228 return usb_driver_main(&usb_hid_driver); 207 229 } 208 209 230 /** 210 231 * @} -
uspace/drv/bus/usb/usbhid/mouse/mousedev.c
r4c3ad56 r20a3465 59 59 /*----------------------------------------------------------------------------*/ 60 60 61 usb_endpoint_description_t usb_hid_mouse_poll_endpoint_description = {61 const usb_endpoint_description_t usb_hid_mouse_poll_endpoint_description = { 62 62 .transfer_type = USB_TRANSFER_INTERRUPT, 63 63 .direction = USB_DIRECTION_IN, … … 124 124 { 125 125 usb_mouse_t *mouse_dev = (usb_mouse_t *) fun->driver_data; 126 126 127 127 if (mouse_dev == NULL) { 128 128 usb_log_debug("default_connection_handler: Missing " … … 131 131 return; 132 132 } 133 133 134 134 usb_log_debug("default_connection_handler: fun->name: %s\n", 135 135 fun->name); 136 136 usb_log_debug("default_connection_handler: mouse_sess: %p, " 137 137 "wheel_sess: %p\n", mouse_dev->mouse_sess, mouse_dev->wheel_sess); 138 138 139 139 async_sess_t **sess_ptr = 140 140 (str_cmp(fun->name, HID_MOUSE_FUN_NAME) == 0) ? 141 141 &mouse_dev->mouse_sess : &mouse_dev->wheel_sess; 142 142 143 143 async_sess_t *sess = 144 144 async_callback_receive_start(EXCHANGE_SERIALIZE, icall); … … 170 170 mouse->mouse_sess = NULL; 171 171 mouse->wheel_sess = NULL; 172 172 173 173 return mouse; 174 174 } … … 179 179 { 180 180 assert(mouse_dev != NULL); 181 181 182 182 // hangup session to the console 183 183 if (mouse_dev->mouse_sess != NULL) 184 184 async_hangup(mouse_dev->mouse_sess); 185 185 186 186 if (mouse_dev->wheel_sess != NULL) 187 187 async_hangup(mouse_dev->wheel_sess); 188 int ret = ddf_fun_unbind(mouse_dev->mouse_fun); 189 if (ret != EOK) { 190 usb_log_error("Failed to unbind mouse function.\n"); 191 } else { 192 ddf_fun_destroy(mouse_dev->mouse_fun); 193 /* Prevent double free */ 194 mouse_dev->wheel_fun->driver_data = NULL; 195 } 196 197 ret = ddf_fun_unbind(mouse_dev->wheel_fun); 198 if (ret != EOK) { 199 usb_log_error("Failed to unbind wheel function.\n"); 200 } else { 201 ddf_fun_destroy(mouse_dev->wheel_fun); 202 } 188 203 } 189 204 … … 199 214 return; 200 215 } 201 216 202 217 int count = ((wheel < 0) ? -wheel : wheel) * ARROWS_PER_SINGLE_WHEEL; 203 218 int i; 204 219 205 220 for (i = 0; i < count; i++) { 206 221 /* Send arrow press and release. */ … … 246 261 { 247 262 assert(mouse_dev != NULL); 248 263 249 264 if (mouse_dev->mouse_sess == NULL) { 250 265 usb_log_warning(NAME " No console session.\n"); … … 253 268 254 269 int shift_x = get_mouse_axis_move_value(hid_dev->report_id, 255 hid_dev->report, USB_HIDUT_USAGE_GENERIC_DESKTOP_X);270 &hid_dev->report, USB_HIDUT_USAGE_GENERIC_DESKTOP_X); 256 271 int shift_y = get_mouse_axis_move_value(hid_dev->report_id, 257 hid_dev->report, USB_HIDUT_USAGE_GENERIC_DESKTOP_Y);272 &hid_dev->report, USB_HIDUT_USAGE_GENERIC_DESKTOP_Y); 258 273 int wheel = get_mouse_axis_move_value(hid_dev->report_id, 259 hid_dev->report, USB_HIDUT_USAGE_GENERIC_DESKTOP_WHEEL);274 &hid_dev->report, USB_HIDUT_USAGE_GENERIC_DESKTOP_WHEEL); 260 275 261 276 if ((shift_x != 0) || (shift_y != 0)) { 262 async_exch_t *exch = async_exchange_begin(mouse_dev->mouse_sess); 277 async_exch_t *exch = 278 async_exchange_begin(mouse_dev->mouse_sess); 263 279 async_req_2_0(exch, MOUSEEV_MOVE_EVENT, shift_x, shift_y); 264 280 async_exchange_end(exch); 265 281 } 266 282 267 283 if (wheel != 0) 268 284 usb_mouse_send_wheel(mouse_dev, wheel); 269 285 270 286 /* 271 287 * Buttons … … 274 290 usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_BUTTON, 0); 275 291 usb_hid_report_path_set_report_id(path, hid_dev->report_id); 276 292 277 293 usb_hid_report_field_t *field = usb_hid_report_get_sibling( 278 hid_dev->report, NULL, path, USB_HID_PATH_COMPARE_END 279 | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY, 280 USB_HID_REPORT_TYPE_INPUT); 294 &hid_dev->report, NULL, path, USB_HID_PATH_COMPARE_END 295 | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY, USB_HID_REPORT_TYPE_INPUT); 281 296 282 297 while (field != NULL) { … … 299 314 async_req_2_0(exch, MOUSEEV_BUTTON_EVENT, field->usage, 0); 300 315 async_exchange_end(exch); 301 316 302 317 mouse_dev->buttons[field->usage - field->usage_minimum] = 303 318 field->value; 304 319 } 305 320 306 321 field = usb_hid_report_get_sibling( 307 hid_dev->report, field, path, USB_HID_PATH_COMPARE_END308 | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY, 322 &hid_dev->report, field, path, USB_HID_PATH_COMPARE_END 323 | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY, 309 324 USB_HID_REPORT_TYPE_INPUT); 310 325 } 311 326 312 327 usb_hid_report_path_free(path); 313 328 … … 321 336 assert(hid_dev != NULL); 322 337 assert(mouse != NULL); 323 338 324 339 /* Create the exposed function. */ 325 340 usb_log_debug("Creating DDF function %s...\n", HID_MOUSE_FUN_NAME); … … 330 345 return ENOMEM; 331 346 } 332 347 333 348 fun->ops = &mouse->ops; 334 349 fun->driver_data = mouse; … … 338 353 usb_log_error("Could not bind DDF function: %s.\n", 339 354 str_error(rc)); 340 ddf_fun_destroy(fun); 341 return rc; 342 } 343 355 return rc; 356 } 357 344 358 usb_log_debug("Adding DDF function to category %s...\n", 345 359 HID_MOUSE_CATEGORY); … … 349 363 "Could not add DDF function to category %s: %s.\n", 350 364 HID_MOUSE_CATEGORY, str_error(rc)); 351 ddf_fun_destroy(fun);352 return rc;353 }354 365 return rc; 366 } 367 mouse->mouse_fun = fun; 368 355 369 /* 356 370 * Special function for acting as keyboard (wheel) … … 364 378 return ENOMEM; 365 379 } 366 380 367 381 /* 368 382 * Store the initialized HID device and HID ops … … 376 390 usb_log_error("Could not bind DDF function: %s.\n", 377 391 str_error(rc)); 378 ddf_fun_destroy(fun); 379 return rc; 380 } 381 392 return rc; 393 } 394 382 395 usb_log_debug("Adding DDF function to category %s...\n", 383 396 HID_MOUSE_WHEEL_CATEGORY); … … 387 400 "Could not add DDF function to category %s: %s.\n", 388 401 HID_MOUSE_WHEEL_CATEGORY, str_error(rc)); 389 ddf_fun_destroy(fun);390 return rc;391 }392 402 return rc; 403 } 404 mouse->wheel_fun = fun; 405 393 406 return EOK; 394 407 } … … 441 454 { 442 455 usb_log_debug("Initializing HID/Mouse structure...\n"); 443 456 444 457 if (hid_dev == NULL) { 445 458 usb_log_error("Failed to init keyboard structure: no structure" … … 447 460 return EINVAL; 448 461 } 449 462 450 463 usb_mouse_t *mouse_dev = usb_mouse_new(); 451 464 if (mouse_dev == NULL) { … … 454 467 return ENOMEM; 455 468 } 456 469 457 470 // FIXME: This may not be optimal since stupid hardware vendor may 458 471 // use buttons 1, 2, 3 and 6000 and we would allocate array of … … 461 474 // that the current solution is good enough. 462 475 /* Adding 1 because we will be accessing buttons[highest]. */ 463 mouse_dev->buttons_count = usb_mouse_get_highest_button(hid_dev->report,464 hid_dev->report_id) + 1;476 mouse_dev->buttons_count = 1 + usb_mouse_get_highest_button( 477 &hid_dev->report, hid_dev->report_id); 465 478 mouse_dev->buttons = calloc(mouse_dev->buttons_count, sizeof(int32_t)); 466 479 467 480 if (mouse_dev->buttons == NULL) { 468 481 usb_log_error(NAME ": out of memory, giving up on device!\n"); … … 474 487 // save the Mouse device structure into the HID device structure 475 488 *data = mouse_dev; 476 489 477 490 // set handler for incoming calls 478 491 mouse_dev->ops.default_handler = default_connection_handler; 479 492 480 493 // TODO: how to know if the device supports the request??? 481 494 usbhid_req_set_idle(&hid_dev->usb_dev->ctrl_pipe, 482 495 hid_dev->usb_dev->interface_no, IDLE_RATE); 483 496 484 497 int rc = usb_mouse_create_function(hid_dev, mouse_dev); 485 498 if (rc != EOK) { … … 487 500 return rc; 488 501 } 489 502 490 503 return EOK; 491 504 } … … 500 513 return false; 501 514 } 502 515 503 516 usb_mouse_t *mouse_dev = (usb_mouse_t *)data; 504 517 … … 511 524 { 512 525 if (data != NULL) { 513 usb_mouse_destroy( (usb_mouse_t *)data);526 usb_mouse_destroy(data); 514 527 } 515 528 } … … 519 532 int usb_mouse_set_boot_protocol(usb_hid_dev_t *hid_dev) 520 533 { 521 int rc = usb_hid_parse_report_descriptor( hid_dev->report,522 USB_MOUSE_BOOT_REPORT_DESCRIPTOR,534 int rc = usb_hid_parse_report_descriptor( 535 &hid_dev->report, USB_MOUSE_BOOT_REPORT_DESCRIPTOR, 523 536 USB_MOUSE_BOOT_REPORT_DESCRIPTOR_SIZE); 524 537 525 538 if (rc != EOK) { 526 539 usb_log_error("Failed to parse boot report descriptor: %s\n", … … 528 541 return rc; 529 542 } 530 531 rc = usbhid_req_set_protocol(&hid_dev->usb_dev->ctrl_pipe, 543 544 rc = usbhid_req_set_protocol(&hid_dev->usb_dev->ctrl_pipe, 532 545 hid_dev->usb_dev->interface_no, USB_HID_PROTOCOL_BOOT); 533 546 534 547 if (rc != EOK) { 535 548 usb_log_warning("Failed to set boot protocol to the device: " … … 537 550 return rc; 538 551 } 539 552 540 553 return EOK; 541 554 } -
uspace/drv/bus/usb/usbhid/mouse/mousedev.h
r4c3ad56 r20a3465 49 49 async_sess_t *mouse_sess; 50 50 async_sess_t *wheel_sess; 51 51 52 52 /* Mouse buttons statuses. */ 53 53 int32_t *buttons; 54 54 size_t buttons_count; 55 55 56 56 ddf_dev_ops_t ops; 57 /* DDF mouse function */ 58 ddf_fun_t *mouse_fun; 59 /* DDF mouse function */ 60 ddf_fun_t *wheel_fun; 57 61 } usb_mouse_t; 58 62 59 63 /*----------------------------------------------------------------------------*/ 60 64 61 usb_endpoint_description_t usb_hid_mouse_poll_endpoint_description;65 extern const usb_endpoint_description_t usb_hid_mouse_poll_endpoint_description; 62 66 63 67 const char *HID_MOUSE_FUN_NAME; -
uspace/drv/bus/usb/usbhid/multimedia/multimedia.c
r4c3ad56 r20a3465 64 64 //int32_t *keys; 65 65 /** Count of stored keys (i.e. number of keys in the report). */ 66 //size_t key_count; 66 //size_t key_count; 67 67 /** IPC session to the console device (for sending key events). */ 68 68 async_sess_t *console_sess; 69 /** DDF function */ 70 ddf_fun_t *fun; 69 71 } usb_multimedia_t; 70 72 … … 86 88 { 87 89 usb_log_debug(NAME " default_connection_handler()\n"); 88 90 89 91 usb_multimedia_t *multim_dev = (usb_multimedia_t *)fun->driver_data; 90 92 91 93 if (multim_dev == NULL) { 92 94 async_answer_0(icallid, EINVAL); 93 95 return; 94 96 } 95 97 96 98 async_sess_t *sess = 97 99 async_callback_receive_start(EXCHANGE_SERIALIZE, icall); … … 137 139 assert(hid_dev != NULL); 138 140 assert(multim_dev != NULL); 139 141 140 142 kbd_event_t ev; 141 143 142 144 ev.type = type; 143 145 ev.key = key; … … 151 153 return; 152 154 } 153 155 154 156 async_exch_t *exch = async_exchange_begin(multim_dev->console_sess); 155 157 async_msg_4(exch, KBDEV_EVENT, ev.type, ev.key, ev.mods, ev.c); … … 159 161 /*----------------------------------------------------------------------------*/ 160 162 161 static int usb_multimedia_create_function(usb_hid_dev_t *hid_dev, 162 usb_multimedia_t *multim_dev) 163 { 163 int usb_multimedia_init(struct usb_hid_dev *hid_dev, void **data) 164 { 165 if (hid_dev == NULL || hid_dev->usb_dev == NULL) { 166 return EINVAL; /*! @todo Other return code? */ 167 } 168 169 usb_log_debug(NAME " Initializing HID/multimedia structure...\n"); 170 164 171 /* Create the exposed function. */ 165 ddf_fun_t *fun = ddf_fun_create( hid_dev->usb_dev->ddf_dev, fun_exposed,166 NAME);172 ddf_fun_t *fun = ddf_fun_create( 173 hid_dev->usb_dev->ddf_dev, fun_exposed, NAME); 167 174 if (fun == NULL) { 168 175 usb_log_error("Could not create DDF function node.\n"); 169 176 return ENOMEM; 170 177 } 171 178 172 179 fun->ops = &multimedia_ops; 173 fun->driver_data = multim_dev; // TODO: maybe change to hid_dev->data 174 180 181 usb_multimedia_t *multim_dev = 182 ddf_fun_data_alloc(fun, sizeof(usb_multimedia_t)); 183 if (multim_dev == NULL) { 184 ddf_fun_destroy(fun); 185 return ENOMEM; 186 } 187 188 multim_dev->console_sess = NULL; 189 multim_dev->fun = fun; 190 191 //todo Autorepeat? 192 175 193 int rc = ddf_fun_bind(fun); 176 194 if (rc != EOK) { 177 195 usb_log_error("Could not bind DDF function: %s.\n", 178 196 str_error(rc)); 179 // TODO: Can / should I destroy the DDF function?180 197 ddf_fun_destroy(fun); 181 198 return rc; 182 199 } 183 200 184 201 usb_log_debug("%s function created (handle: %" PRIun ").\n", 185 202 NAME, fun->handle); 186 203 187 204 rc = ddf_fun_add_to_category(fun, "keyboard"); 188 205 if (rc != EOK) { … … 190 207 "Could not add DDF function to category 'keyboard': %s.\n", 191 208 str_error(rc)); 192 // TODO: Can / should I destroy the DDF function?193 209 ddf_fun_destroy(fun); 194 210 return rc; 195 211 } 196 197 return EOK; 198 } 199 200 /*----------------------------------------------------------------------------*/ 201 202 int usb_multimedia_init(struct usb_hid_dev *hid_dev, void **data) 203 { 204 if (hid_dev == NULL || hid_dev->usb_dev == NULL) { 205 return EINVAL; /*! @todo Other return code? */ 206 } 207 208 usb_log_debug(NAME " Initializing HID/multimedia structure...\n"); 209 210 usb_multimedia_t *multim_dev = (usb_multimedia_t *)malloc( 211 sizeof(usb_multimedia_t)); 212 if (multim_dev == NULL) { 213 return ENOMEM; 214 } 215 216 multim_dev->console_sess = NULL; 217 218 /*! @todo Autorepeat */ 219 220 // save the KBD device structure into the HID device structure 212 213 /* Save the KBD device structure into the HID device structure. */ 221 214 *data = multim_dev; 222 223 usb_log_debug(NAME " HID/multimedia device structure initialized.\n"); 224 225 int rc = usb_multimedia_create_function(hid_dev, multim_dev); 226 if (rc != EOK) 227 return rc; 228 215 229 216 usb_log_debug(NAME " HID/multimedia structure initialized.\n"); 230 231 217 return EOK; 232 218 } … … 239 225 return; 240 226 } 241 227 242 228 if (data != NULL) { 243 229 usb_multimedia_t *multim_dev = (usb_multimedia_t *)data; 244 230 // hangup session to the console 245 231 async_hangup(multim_dev->console_sess); 232 const int ret = ddf_fun_unbind(multim_dev->fun); 233 if (ret != EOK) { 234 usb_log_error("Failed to unbind multim function.\n"); 235 } else { 236 usb_log_debug2("%s unbound.\n", multim_dev->fun->name); 237 ddf_fun_destroy(multim_dev->fun); 238 } 246 239 } 247 240 } … … 257 250 258 251 usb_multimedia_t *multim_dev = (usb_multimedia_t *)data; 259 252 260 253 usb_hid_report_path_t *path = usb_hid_report_path(); 261 254 usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_CONSUMER, 0); … … 264 257 265 258 usb_hid_report_field_t *field = usb_hid_report_get_sibling( 266 hid_dev->report, NULL, path, USB_HID_PATH_COMPARE_END267 | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY, 259 &hid_dev->report, NULL, path, USB_HID_PATH_COMPARE_END 260 | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY, 268 261 USB_HID_REPORT_TYPE_INPUT); 269 262 … … 283 276 key); 284 277 } 285 278 286 279 field = usb_hid_report_get_sibling( 287 hid_dev->report, field, path, USB_HID_PATH_COMPARE_END280 &hid_dev->report, field, path, USB_HID_PATH_COMPARE_END 288 281 | USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY, 289 282 USB_HID_REPORT_TYPE_INPUT); 290 } 283 } 291 284 292 285 usb_hid_report_path_free(path); 293 286 294 287 return true; 295 288 } -
uspace/drv/bus/usb/usbhid/subdrivers.c
r4c3ad56 r20a3465 42 42 #include "generic/hiddev.h" 43 43 44 static usb_hid_subdriver_usage_t path_kbd[] = {45 {USB_HIDUT_PAGE_GENERIC_DESKTOP, 46 USB_HIDUT_USAGE_GENERIC_DESKTOP_KEYBOARD}, 44 static const usb_hid_subdriver_usage_t path_kbd[] = { 45 {USB_HIDUT_PAGE_GENERIC_DESKTOP, 46 USB_HIDUT_USAGE_GENERIC_DESKTOP_KEYBOARD}, 47 47 {0, 0} 48 48 }; 49 49 50 static usb_hid_subdriver_usage_t path_mouse[] = {50 static const usb_hid_subdriver_usage_t path_mouse[] = { 51 51 {USB_HIDUT_PAGE_GENERIC_DESKTOP, USB_HIDUT_USAGE_GENERIC_DESKTOP_MOUSE}, 52 52 {0, 0} 53 53 }; 54 54 55 static usb_hid_subdriver_usage_t multim_key_path[] = {55 static const usb_hid_subdriver_usage_t multim_key_path[] = { 56 56 {USB_HIDUT_PAGE_CONSUMER, USB_HIDUT_USAGE_CONSUMER_CONSUMER_CONTROL}, 57 57 {0, 0} … … 71 71 .poll_end = NULL 72 72 }, 73 74 73 }, 75 74 { … … 102 101 }; 103 102 103 const int USB_HID_MAX_SUBDRIVERS = 104 sizeof(usb_hid_subdrivers) / sizeof(usb_hid_subdrivers[0]); 105 104 106 /** 105 107 * @} -
uspace/drv/bus/usb/usbhid/subdrivers.h
r4c3ad56 r20a3465 64 64 */ 65 65 const usb_hid_subdriver_usage_t *usage_path; 66 66 67 67 /** Report ID for which the path should apply. */ 68 68 int report_id; 69 69 70 70 /** Compare type for the Usage path. */ 71 71 int compare; 72 72 73 73 /** Vendor ID (set to -1 if not specified). */ 74 74 int vendor_id; 75 75 76 76 /** Product ID (set to -1 if not specified). */ 77 77 int product_id; 78 78 79 79 /** Subdriver for controlling this device. */ 80 usb_hid_subdriver_t subdriver;80 const usb_hid_subdriver_t subdriver; 81 81 } usb_hid_subdriver_mapping_t; 82 82 … … 84 84 85 85 extern const usb_hid_subdriver_mapping_t usb_hid_subdrivers[]; 86 extern const int USB_HID_MAX_SUBDRIVERS; 86 87 87 88 /*----------------------------------------------------------------------------*/ -
uspace/drv/bus/usb/usbhid/usbhid.c
r4c3ad56 r20a3465 54 54 55 55 /* Array of endpoints expected on the device, NULL terminated. */ 56 usb_endpoint_description_t *usb_hid_endpoints[USB_HID_POLL_EP_COUNT + 1] = {56 const usb_endpoint_description_t *usb_hid_endpoints[] = { 57 57 &usb_hid_kbd_poll_endpoint_description, 58 58 &usb_hid_mouse_poll_endpoint_description, … … 61 61 }; 62 62 63 static const int USB_HID_MAX_SUBDRIVERS = 10;64 65 63 /*----------------------------------------------------------------------------*/ 66 64 67 65 static int usb_hid_set_boot_kbd_subdriver(usb_hid_dev_t *hid_dev) 68 66 { 69 assert(hid_dev != NULL && hid_dev->subdriver_count == 0);70 71 hid_dev->subdrivers = (usb_hid_subdriver_t *)malloc( 72 sizeof(usb_hid_subdriver_t));67 assert(hid_dev != NULL); 68 assert(hid_dev->subdriver_count == 0); 69 70 hid_dev->subdrivers = malloc(sizeof(usb_hid_subdriver_t)); 73 71 if (hid_dev->subdrivers == NULL) { 74 72 return ENOMEM; 75 73 } 76 77 assert(hid_dev->subdriver_count >= 0); 78 79 // set the init callback 80 hid_dev->subdrivers[hid_dev->subdriver_count].init = usb_kbd_init; 81 82 // set the polling callback 83 hid_dev->subdrivers[hid_dev->subdriver_count].poll = 84 usb_kbd_polling_callback; 85 86 // set the polling ended callback 87 hid_dev->subdrivers[hid_dev->subdriver_count].poll_end = NULL; 88 89 // set the deinit callback 90 hid_dev->subdrivers[hid_dev->subdriver_count].deinit = usb_kbd_deinit; 91 92 // set subdriver count 93 ++hid_dev->subdriver_count; 94 74 hid_dev->subdriver_count = 1; 75 // TODO 0 should be keyboard, but find a better way 76 hid_dev->subdrivers[0] = usb_hid_subdrivers[0].subdriver; 77 95 78 return EOK; 96 79 } … … 100 83 static int usb_hid_set_boot_mouse_subdriver(usb_hid_dev_t *hid_dev) 101 84 { 102 assert(hid_dev != NULL && hid_dev->subdriver_count == 0);103 104 hid_dev->subdrivers = (usb_hid_subdriver_t *)malloc( 105 sizeof(usb_hid_subdriver_t));85 assert(hid_dev != NULL); 86 assert(hid_dev->subdriver_count == 0); 87 88 hid_dev->subdrivers = malloc(sizeof(usb_hid_subdriver_t)); 106 89 if (hid_dev->subdrivers == NULL) { 107 90 return ENOMEM; 108 91 } 109 110 assert(hid_dev->subdriver_count >= 0); 111 112 // set the init callback 113 hid_dev->subdrivers[hid_dev->subdriver_count].init = usb_mouse_init; 114 115 // set the polling callback 116 hid_dev->subdrivers[hid_dev->subdriver_count].poll = 117 usb_mouse_polling_callback; 118 119 // set the polling ended callback 120 hid_dev->subdrivers[hid_dev->subdriver_count].poll_end = NULL; 121 122 // set the deinit callback 123 hid_dev->subdrivers[hid_dev->subdriver_count].deinit = usb_mouse_deinit; 124 125 // set subdriver count 126 ++hid_dev->subdriver_count; 127 92 hid_dev->subdriver_count = 1; 93 // TODO 2 should be mouse, but find a better way 94 hid_dev->subdrivers[2] = usb_hid_subdrivers[0].subdriver; 95 128 96 return EOK; 129 97 } … … 134 102 { 135 103 assert(hid_dev != NULL && hid_dev->subdriver_count == 0); 136 137 hid_dev->subdrivers = (usb_hid_subdriver_t *)malloc( 138 sizeof(usb_hid_subdriver_t)); 104 105 hid_dev->subdrivers = malloc(sizeof(usb_hid_subdriver_t)); 139 106 if (hid_dev->subdrivers == NULL) { 140 107 return ENOMEM; 141 108 } 142 143 assert(hid_dev->subdriver_count >= 0); 144 145 // set the init callback 146 hid_dev->subdrivers[hid_dev->subdriver_count].init = 147 usb_generic_hid_init; 148 149 // set the polling callback 150 hid_dev->subdrivers[hid_dev->subdriver_count].poll = 151 usb_generic_hid_polling_callback; 152 153 // set the polling ended callback 154 hid_dev->subdrivers[hid_dev->subdriver_count].poll_end = NULL; 155 156 // set the deinit callback 157 hid_dev->subdrivers[hid_dev->subdriver_count].deinit = NULL; 158 159 // set subdriver count 160 ++hid_dev->subdriver_count; 161 109 hid_dev->subdriver_count = 1; 110 111 /* Set generic hid subdriver routines */ 112 hid_dev->subdrivers[0].init = usb_generic_hid_init; 113 hid_dev->subdrivers[0].poll = usb_generic_hid_polling_callback; 114 hid_dev->subdrivers[0].poll_end = NULL; 115 hid_dev->subdrivers[0].deinit = usb_generic_hid_deinit; 116 162 117 return EOK; 163 118 } … … 165 120 /*----------------------------------------------------------------------------*/ 166 121 167 static bool usb_hid_ids_match( usb_hid_dev_t *hid_dev,122 static bool usb_hid_ids_match(const usb_hid_dev_t *hid_dev, 168 123 const usb_hid_subdriver_mapping_t *mapping) 169 124 { 170 125 assert(hid_dev != NULL); 171 126 assert(hid_dev->usb_dev != NULL); 172 173 return (hid_dev->usb_dev->descriptors.device.vendor_id 127 128 return (hid_dev->usb_dev->descriptors.device.vendor_id 174 129 == mapping->vendor_id 175 130 && hid_dev->usb_dev->descriptors.device.product_id … … 179 134 /*----------------------------------------------------------------------------*/ 180 135 181 static bool usb_hid_path_matches(usb_hid_dev_t *hid_dev, 136 static bool usb_hid_path_matches(usb_hid_dev_t *hid_dev, 182 137 const usb_hid_subdriver_mapping_t *mapping) 183 138 { 184 139 assert(hid_dev != NULL); 185 140 assert(mapping != NULL); 186 141 187 142 usb_hid_report_path_t *usage_path = usb_hid_report_path(); 188 143 if (usage_path == NULL) { … … 191 146 } 192 147 int i = 0; 193 while (mapping->usage_path[i].usage != 0 148 while (mapping->usage_path[i].usage != 0 194 149 || mapping->usage_path[i].usage_page != 0) { 195 if (usb_hid_report_path_append_item(usage_path, 196 mapping->usage_path[i].usage_page, 150 if (usb_hid_report_path_append_item(usage_path, 151 mapping->usage_path[i].usage_page, 197 152 mapping->usage_path[i].usage) != EOK) { 198 153 usb_log_debug("Failed to append to usage path.\n"); … … 202 157 ++i; 203 158 } 204 205 assert(hid_dev->report != NULL); 206 159 207 160 usb_log_debug("Compare flags: %d\n", mapping->compare); 208 161 209 162 bool matches = false; 210 163 uint8_t report_id = mapping->report_id; … … 212 165 do { 213 166 usb_log_debug("Trying report id %u\n", report_id); 214 167 215 168 if (report_id != 0) { 216 169 usb_hid_report_path_set_report_id(usage_path, … … 219 172 220 173 usb_hid_report_field_t *field = usb_hid_report_get_sibling( 221 hid_dev->report, 222 NULL, usage_path, mapping->compare, 174 &hid_dev->report, NULL, usage_path, mapping->compare, 223 175 USB_HID_REPORT_TYPE_INPUT); 224 176 225 177 usb_log_debug("Field: %p\n", field); 226 178 … … 229 181 break; 230 182 } 231 183 232 184 report_id = usb_hid_get_next_report_id( 233 hid_dev->report, report_id, 234 USB_HID_REPORT_TYPE_INPUT); 185 &hid_dev->report, report_id, USB_HID_REPORT_TYPE_INPUT); 235 186 } while (!matches && report_id != 0); 236 187 237 188 usb_hid_report_path_free(usage_path); 238 189 239 190 return matches; 240 191 } … … 242 193 /*----------------------------------------------------------------------------*/ 243 194 244 static int usb_hid_save_subdrivers(usb_hid_dev_t *hid_dev, 195 static int usb_hid_save_subdrivers(usb_hid_dev_t *hid_dev, 245 196 const usb_hid_subdriver_t **subdrivers, int count) 246 197 { 247 198 int i; 248 199 249 200 if (count <= 0) { 250 201 hid_dev->subdriver_count = 0; … … 252 203 return EOK; 253 204 } 254 255 // add one generic HID subdriver per device 256 257 hid_dev->subdrivers = (usb_hid_subdriver_t *)malloc((count + 1) * 258 sizeof(usb_hid_subdriver_t)); 205 206 /* +1 for generic hid subdriver */ 207 hid_dev->subdrivers = calloc((count + 1), sizeof(usb_hid_subdriver_t)); 259 208 if (hid_dev->subdrivers == NULL) { 260 209 return ENOMEM; 261 210 } 262 211 263 212 for (i = 0; i < count; ++i) { 264 213 hid_dev->subdrivers[i].init = subdrivers[i]->init; … … 267 216 hid_dev->subdrivers[i].poll_end = subdrivers[i]->poll_end; 268 217 } 269 218 219 /* Add one generic HID subdriver per device */ 270 220 hid_dev->subdrivers[count].init = usb_generic_hid_init; 271 221 hid_dev->subdrivers[count].poll = usb_generic_hid_polling_callback; 272 hid_dev->subdrivers[count].deinit = NULL;222 hid_dev->subdrivers[count].deinit = usb_generic_hid_deinit; 273 223 hid_dev->subdrivers[count].poll_end = NULL; 274 224 275 225 hid_dev->subdriver_count = count + 1; 276 226 277 227 return EOK; 278 228 } … … 283 233 { 284 234 assert(hid_dev != NULL); 285 235 286 236 const usb_hid_subdriver_t *subdrivers[USB_HID_MAX_SUBDRIVERS]; 287 237 288 238 int i = 0, count = 0; 289 239 const usb_hid_subdriver_mapping_t *mapping = &usb_hid_subdrivers[i]; … … 291 241 bool ids_matched; 292 242 bool matched; 293 243 294 244 while (count < USB_HID_MAX_SUBDRIVERS && 295 245 (mapping->usage_path != NULL … … 306 256 return EINVAL; 307 257 } 308 258 309 259 ids_matched = false; 310 260 matched = false; 311 261 312 262 if (mapping->vendor_id >= 0) { 313 263 assert(mapping->product_id >= 0); … … 320 270 } 321 271 } 322 272 323 273 if (mapping->usage_path != NULL) { 324 274 usb_log_debug("Comparing device against usage path.\n"); … … 331 281 matched = ids_matched; 332 282 } 333 283 334 284 if (matched) { 335 285 usb_log_debug("Subdriver matched.\n"); 336 286 subdrivers[count++] = &mapping->subdriver; 337 287 } 338 288 339 289 mapping = &usb_hid_subdrivers[++i]; 340 290 } 341 342 // we have all subdrivers determined, save them into the hid device 291 292 /* We have all subdrivers determined, save them into the hid device */ 293 // TODO Dowe really need this complicated stuff if there is 294 // max_subdrivers limitation? 343 295 return usb_hid_save_subdrivers(hid_dev, subdrivers, count); 344 296 } … … 346 298 /*----------------------------------------------------------------------------*/ 347 299 348 static int usb_hid_check_pipes(usb_hid_dev_t *hid_dev, usb_device_t *dev) 349 { 350 assert(hid_dev != NULL && dev != NULL); 351 352 int rc = EOK; 353 300 static int usb_hid_check_pipes(usb_hid_dev_t *hid_dev, const usb_device_t *dev) 301 { 302 assert(hid_dev); 303 assert(dev); 304 354 305 if (dev->pipes[USB_HID_KBD_POLL_EP_NO].present) { 355 306 usb_log_debug("Found keyboard endpoint.\n"); … … 367 318 usb_log_error("None of supported endpoints found - probably" 368 319 " not a supported device.\n"); 369 r c =ENOTSUP;370 } 371 372 return rc;320 return ENOTSUP; 321 } 322 323 return EOK; 373 324 } 374 325 … … 377 328 static int usb_hid_init_report(usb_hid_dev_t *hid_dev) 378 329 { 379 assert(hid_dev != NULL && hid_dev->report != NULL);380 330 assert(hid_dev != NULL); 331 381 332 uint8_t report_id = 0; 382 size_t size;383 384 333 size_t max_size = 0; 385 334 386 335 do { 387 336 usb_log_debug("Getting size of the report.\n"); 388 size = usb_hid_report_byte_size(hid_dev->report, report_id, 389 USB_HID_REPORT_TYPE_INPUT); 337 const size_t size = 338 usb_hid_report_byte_size(&hid_dev->report, report_id, 339 USB_HID_REPORT_TYPE_INPUT); 390 340 usb_log_debug("Report ID: %u, size: %zu\n", report_id, size); 391 341 max_size = (size > max_size) ? size : max_size; 392 342 usb_log_debug("Getting next report ID\n"); 393 report_id = usb_hid_get_next_report_id( hid_dev->report,343 report_id = usb_hid_get_next_report_id(&hid_dev->report, 394 344 report_id, USB_HID_REPORT_TYPE_INPUT); 395 345 } while (report_id != 0); 396 346 397 347 usb_log_debug("Max size of input report: %zu\n", max_size); 398 399 hid_dev->max_input_report_size = max_size; 348 400 349 assert(hid_dev->input_report == NULL); 401 402 hid_dev->input_report = malloc(max_size);350 351 hid_dev->input_report = calloc(1, max_size); 403 352 if (hid_dev->input_report == NULL) { 404 353 return ENOMEM; 405 354 } 406 memset(hid_dev->input_report, 0, max_size);407 355 hid_dev->max_input_report_size = max_size; 356 408 357 return EOK; 409 358 } … … 411 360 /*----------------------------------------------------------------------------*/ 412 361 413 usb_hid_dev_t *usb_hid_new(void)414 {415 usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)calloc(1,416 sizeof(usb_hid_dev_t));417 418 if (hid_dev == NULL) {419 usb_log_fatal("No memory!\n");420 return NULL;421 }422 423 hid_dev->report = (usb_hid_report_t *)(malloc(sizeof(424 usb_hid_report_t)));425 if (hid_dev->report == NULL) {426 usb_log_fatal("No memory!\n");427 free(hid_dev);428 return NULL;429 }430 431 hid_dev->poll_pipe_index = -1;432 433 return hid_dev;434 }435 436 /*----------------------------------------------------------------------------*/437 438 362 int usb_hid_init(usb_hid_dev_t *hid_dev, usb_device_t *dev) 439 363 { 440 364 int rc, i; 441 365 442 366 usb_log_debug("Initializing HID structure...\n"); 443 367 444 368 if (hid_dev == NULL) { 445 369 usb_log_error("Failed to init HID structure: no structure given" … … 447 371 return EINVAL; 448 372 } 449 373 450 374 if (dev == NULL) { 451 375 usb_log_error("Failed to init HID structure: no USB device" … … 453 377 return EINVAL; 454 378 } 455 379 380 usb_hid_report_init(&hid_dev->report); 381 456 382 /* The USB device should already be initialized, save it in structure */ 457 383 hid_dev->usb_dev = dev; 458 384 hid_dev->poll_pipe_index = -1; 385 459 386 rc = usb_hid_check_pipes(hid_dev, dev); 460 387 if (rc != EOK) { 461 388 return rc; 462 389 } 463 390 464 391 /* Get the report descriptor and parse it. */ 465 rc = usb_hid_process_report_descriptor(hid_dev->usb_dev, 466 hid_dev->report, &hid_dev->report_desc, &hid_dev->report_desc_size);467 392 rc = usb_hid_process_report_descriptor(hid_dev->usb_dev, 393 &hid_dev->report, &hid_dev->report_desc, &hid_dev->report_desc_size); 394 468 395 bool fallback = false; 469 396 470 397 if (rc == EOK) { 471 398 // try to find subdrivers that may want to handle this device … … 484 411 fallback = true; 485 412 } 486 413 487 414 if (fallback) { 488 415 // fall back to boot protocol … … 503 430 break; 504 431 default: 505 assert(hid_dev->poll_pipe_index 432 assert(hid_dev->poll_pipe_index 506 433 == USB_HID_GENERIC_POLL_EP_NO); 507 434 508 435 usb_log_info("Falling back to generic HID driver.\n"); 509 436 rc = usb_hid_set_generic_hid_subdriver(hid_dev); 510 437 } 511 438 } 512 439 513 440 if (rc != EOK) { 514 441 usb_log_error("No subdriver for handling this device could be" 515 442 " initialized: %s.\n", str_error(rc)); 516 usb_log_debug("Subdriver count: %d\n", 443 usb_log_debug("Subdriver count: %d\n", 517 444 hid_dev->subdriver_count); 518 519 445 } else { 520 446 bool ok = false; 521 522 usb_log_debug("Subdriver count: %d\n", 447 448 usb_log_debug("Subdriver count: %d\n", 523 449 hid_dev->subdriver_count); 524 450 525 451 for (i = 0; i < hid_dev->subdriver_count; ++i) { 526 452 if (hid_dev->subdrivers[i].init != NULL) { … … 539 465 } 540 466 } 541 467 542 468 rc = (ok) ? EOK : -1; // what error to report 543 469 } 544 545 470 471 546 472 if (rc == EOK) { 547 473 // save max input report size and allocate space for the report … … 552 478 } 553 479 } 554 555 480 556 481 return rc; 557 482 } … … 559 484 /*----------------------------------------------------------------------------*/ 560 485 561 bool usb_hid_polling_callback(usb_device_t *dev, uint8_t *buffer, 486 bool usb_hid_polling_callback(usb_device_t *dev, uint8_t *buffer, 562 487 size_t buffer_size, void *arg) 563 488 { 564 int i;565 566 489 if (dev == NULL || arg == NULL || buffer == NULL) { 567 490 usb_log_error("Missing arguments to polling callback.\n"); 568 491 return false; 569 492 } 570 571 usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)arg; 572 493 usb_hid_dev_t *hid_dev = arg; 494 573 495 assert(hid_dev->input_report != NULL); 496 574 497 usb_log_debug("New data [%zu/%zu]: %s\n", buffer_size, 575 498 hid_dev->max_input_report_size, … … 582 505 usb_hid_new_report(hid_dev); 583 506 } 584 585 // parse the input report 586 587 int rc = usb_hid_parse_report(hid_dev->report, buffer, buffer_size, 588 &hid_dev->report_id); 589 507 508 /* Parse the input report */ 509 const int rc = usb_hid_parse_report( 510 &hid_dev->report, buffer, buffer_size, &hid_dev->report_id); 590 511 if (rc != EOK) { 591 512 usb_log_warning("Error in usb_hid_parse_report():" 592 513 "%s\n", str_error(rc)); 593 } 594 514 } 515 595 516 bool cont = false; 596 597 // continue if at least one of the subdrivers want to continue 598 for (i = 0; i < hid_dev->subdriver_count; ++i) { 599 if (hid_dev->subdrivers[i].poll != NULL 600 && hid_dev->subdrivers[i].poll(hid_dev, 601 hid_dev->subdrivers[i].data)) { 602 cont = true; 603 } 604 } 605 517 /* Continue if at least one of the subdrivers want to continue */ 518 for (int i = 0; i < hid_dev->subdriver_count; ++i) { 519 if (hid_dev->subdrivers[i].poll != NULL) { 520 cont = cont || hid_dev->subdrivers[i].poll( 521 hid_dev, hid_dev->subdrivers[i].data); 522 } 523 } 524 606 525 return cont; 607 526 } … … 609 528 /*----------------------------------------------------------------------------*/ 610 529 611 void usb_hid_polling_ended_callback(usb_device_t *dev, bool reason, 612 void *arg) 613 { 614 int i; 615 616 if (dev == NULL || arg == NULL) { 617 return; 618 } 619 620 usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)arg; 621 622 for (i = 0; i < hid_dev->subdriver_count; ++i) { 530 void usb_hid_polling_ended_callback(usb_device_t *dev, bool reason, void *arg) 531 { 532 assert(dev); 533 assert(arg); 534 535 usb_hid_dev_t *hid_dev = arg; 536 537 for (int i = 0; i < hid_dev->subdriver_count; ++i) { 623 538 if (hid_dev->subdrivers[i].poll_end != NULL) { 624 hid_dev->subdrivers[i].poll_end( hid_dev,625 hid_dev ->subdrivers[i].data, reason);626 } 627 } 628 629 usb_hid_destroy(hid_dev);539 hid_dev->subdrivers[i].poll_end( 540 hid_dev, hid_dev->subdrivers[i].data, reason); 541 } 542 } 543 544 hid_dev->running = false; 630 545 } 631 546 … … 639 554 /*----------------------------------------------------------------------------*/ 640 555 641 int usb_hid_report_number( usb_hid_dev_t *hid_dev)556 int usb_hid_report_number(const usb_hid_dev_t *hid_dev) 642 557 { 643 558 return hid_dev->report_nr; … … 646 561 /*----------------------------------------------------------------------------*/ 647 562 648 void usb_hid_destroy(usb_hid_dev_t *hid_dev) 649 { 650 int i; 651 652 if (hid_dev == NULL) { 653 return; 654 } 655 563 void usb_hid_deinit(usb_hid_dev_t *hid_dev) 564 { 565 assert(hid_dev); 566 assert(hid_dev->subdrivers != NULL || hid_dev->subdriver_count == 0); 567 568 656 569 usb_log_debug("Subdrivers: %p, subdriver count: %d\n", 657 570 hid_dev->subdrivers, hid_dev->subdriver_count); 658 659 assert(hid_dev->subdrivers != NULL 660 || hid_dev->subdriver_count == 0); 661 662 for (i = 0; i < hid_dev->subdriver_count; ++i) { 571 572 for (int i = 0; i < hid_dev->subdriver_count; ++i) { 663 573 if (hid_dev->subdrivers[i].deinit != NULL) { 664 574 hid_dev->subdrivers[i].deinit(hid_dev, … … 666 576 } 667 577 } 668 669 // free the subdrivers info 670 if (hid_dev->subdrivers != NULL) { 671 free(hid_dev->subdrivers); 672 } 673 674 // destroy the parser 675 if (hid_dev->report != NULL) { 676 usb_hid_free_report(hid_dev->report); 677 } 678 679 if (hid_dev->report_desc != NULL) { 680 free(hid_dev->report_desc); 681 } 578 579 /* Free allocated structures */ 580 free(hid_dev->subdrivers); 581 free(hid_dev->report_desc); 582 583 /* Destroy the parser */ 584 usb_hid_report_deinit(&hid_dev->report); 585 682 586 } 683 587 -
uspace/drv/bus/usb/usbhid/usbhid.h
r4c3ad56 r20a3465 102 102 /** Structure holding generic USB device information. */ 103 103 usb_device_t *usb_dev; 104 104 105 105 /** Index of the polling pipe in usb_hid_endpoints array. */ 106 106 int poll_pipe_index; 107 107 108 108 /** Subdrivers. */ 109 109 usb_hid_subdriver_t *subdrivers; 110 110 111 111 /** Number of subdrivers. */ 112 112 int subdriver_count; 113 113 114 114 /** Report descriptor. */ 115 115 uint8_t *report_desc; … … 117 117 /** Report descriptor size. */ 118 118 size_t report_desc_size; 119 119 120 120 /** HID Report parser. */ 121 usb_hid_report_t *report;122 121 usb_hid_report_t report; 122 123 123 uint8_t report_id; 124 124 125 125 uint8_t *input_report; 126 126 127 127 size_t input_report_size; 128 128 size_t max_input_report_size; 129 129 130 130 int report_nr; 131 volatile bool running; 131 132 }; 132 133 … … 140 141 }; 141 142 142 usb_endpoint_description_t *usb_hid_endpoints[USB_HID_POLL_EP_COUNT + 1];143 extern const usb_endpoint_description_t *usb_hid_endpoints[]; 143 144 144 145 /*----------------------------------------------------------------------------*/ 145 146 146 usb_hid_dev_t *usb_hid_new(void);147 148 147 int usb_hid_init(usb_hid_dev_t *hid_dev, usb_device_t *dev); 149 148 150 bool usb_hid_polling_callback(usb_device_t *dev, uint8_t *buffer, 151 size_t buffer_size, void *arg); 149 void usb_hid_deinit(usb_hid_dev_t *hid_dev); 152 150 153 void usb_hid_polling_ended_callback(usb_device_t *dev, bool reason, 154 void *arg); 151 bool usb_hid_polling_callback(usb_device_t *dev, 152 uint8_t *buffer, size_t buffer_size, void *arg); 153 154 void usb_hid_polling_ended_callback(usb_device_t *dev, bool reason, void *arg); 155 155 156 156 void usb_hid_new_report(usb_hid_dev_t *hid_dev); 157 157 158 int usb_hid_report_number(usb_hid_dev_t *hid_dev); 159 160 void usb_hid_destroy(usb_hid_dev_t *hid_dev); 158 int usb_hid_report_number(const usb_hid_dev_t *hid_dev); 161 159 162 160 #endif /* USB_HID_USBHID_H_ */
Note:
See TracChangeset
for help on using the changeset viewer.
