Changeset 350274a in mainline
- Timestamp:
- 2014-07-19T15:37:46Z (10 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 9bd4615
- Parents:
- ebc9c2c
- Location:
- uspace/drv/bus/usb/usbhid
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/usbhid/generic/hiddev.c
rebc9c2c r350274a 35 35 */ 36 36 37 /* XXX Fix this */38 #define _DDF_DATA_IMPLANT39 40 37 #include <usb/debug.h> 41 38 #include <usb/classes/classes.h> -
uspace/drv/bus/usb/usbhid/kbd/kbddev.c
rebc9c2c r350274a 34 34 * USB HID keyboard device structure and API. 35 35 */ 36 37 /* XXX Fix this */38 #define _DDF_DATA_IMPLANT39 36 40 37 #include <errno.h> … … 479 476 } 480 477 481 /* HID/KBD structure manipulation */ 482 483 static int usb_kbd_create_function(usb_kbd_t *kbd_dev) 484 { 485 assert(kbd_dev != NULL); 486 assert(kbd_dev->hid_dev != NULL); 487 assert(kbd_dev->hid_dev->usb_dev != NULL); 478 /* API functions */ 479 480 /** 481 * Initialization of the USB/HID keyboard structure. 482 * 483 * This functions initializes required structures from the device's descriptors. 484 * 485 * During initialization, the keyboard is switched into boot protocol, the idle 486 * rate is set to 0 (infinity), resulting in the keyboard only reporting event 487 * when a key is pressed or released. Finally, the LED lights are turned on 488 * according to the default setup of lock keys. 489 * 490 * @note By default, the keyboards is initialized with Num Lock turned on and 491 * other locks turned off. 492 * 493 * @param kbd_dev Keyboard device structure to be initialized. 494 * @param dev DDF device structure of the keyboard. 495 * 496 * @retval EOK if successful. 497 * @retval EINVAL if some parameter is not given. 498 * @return Other value inherited from function usbhid_dev_init(). 499 */ 500 int usb_kbd_init(usb_hid_dev_t *hid_dev, void **data) 501 { 502 ddf_fun_t *fun = NULL; 503 usb_kbd_t *kbd_dev = NULL; 504 usb_hid_report_path_t *path = NULL; 505 bool bound = false; 506 fid_t fid = 0; 507 int rc; 508 509 usb_log_debug("Initializing HID/KBD structure...\n"); 510 511 if (hid_dev == NULL) { 512 usb_log_error( 513 "Failed to init keyboard structure: no structure given.\n"); 514 rc = EINVAL; 515 goto error; 516 } 488 517 489 518 /* Create the exposed function. */ 490 519 usb_log_debug("Creating DDF function %s...\n", HID_KBD_FUN_NAME); 491 ddf_fun_t *fun = ddf_fun_create(kbd_dev->hid_dev->usb_dev->ddf_dev,492 fun_exposed,HID_KBD_FUN_NAME);520 fun = ddf_fun_create(hid_dev->usb_dev->ddf_dev, fun_exposed, 521 HID_KBD_FUN_NAME); 493 522 if (fun == NULL) { 494 523 usb_log_error("Could not create DDF function node.\n"); 495 return ENOMEM; 524 rc = ENOMEM; 525 goto error; 496 526 } 497 527 … … 499 529 * to the DDF function. */ 500 530 ddf_fun_set_ops(fun, &kbdops); 501 ddf_fun_data_implant(fun, kbd_dev); 502 503 int rc = ddf_fun_bind(fun); 531 532 kbd_dev = ddf_fun_data_alloc(fun, sizeof(usb_kbd_t)); 533 if (kbd_dev == NULL) { 534 usb_log_error("Failed to allocate KBD device structure.\n"); 535 rc = ENOMEM; 536 goto error; 537 } 538 539 kbd_dev->fun = fun; 540 541 /* Default values */ 542 fibril_mutex_initialize(&kbd_dev->repeat_mtx); 543 kbd_dev->initialized = USB_KBD_STATUS_UNINITIALIZED; 544 545 /* Store link to HID device */ 546 kbd_dev->hid_dev = hid_dev; 547 548 /* Modifiers and locks */ 549 kbd_dev->mods = DEFAULT_ACTIVE_MODS; 550 551 /* Autorepeat */ 552 kbd_dev->repeat.delay_before = DEFAULT_DELAY_BEFORE_FIRST_REPEAT; 553 kbd_dev->repeat.delay_between = DEFAULT_REPEAT_DELAY; 554 555 // TODO: make more general 556 path = usb_hid_report_path(); 557 if (path == NULL) { 558 usb_log_error("Failed to create kbd report path.\n"); 559 rc = ENOMEM; 560 goto error; 561 } 562 563 rc = usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_KEYBOARD, 0); 564 if (rc != EOK) { 565 usb_log_error("Failed to append item to kbd report path.\n"); 566 goto error; 567 } 568 569 usb_hid_report_path_set_report_id(path, 0); 570 571 kbd_dev->key_count = 572 usb_hid_report_size(&hid_dev->report, 0, USB_HID_REPORT_TYPE_INPUT); 573 574 usb_hid_report_path_free(path); 575 path = NULL; 576 577 usb_log_debug("Size of the input report: %zu\n", kbd_dev->key_count); 578 579 kbd_dev->keys = calloc(kbd_dev->key_count, sizeof(int32_t)); 580 if (kbd_dev->keys == NULL) { 581 usb_log_error("Failed to allocate key buffer.\n"); 582 rc = ENOMEM; 583 goto error; 584 } 585 586 kbd_dev->keys_old = calloc(kbd_dev->key_count, sizeof(int32_t)); 587 if (kbd_dev->keys_old == NULL) { 588 usb_log_error("Failed to allocate old_key buffer.\n"); 589 rc = ENOMEM; 590 goto error; 591 } 592 593 /* Output report */ 594 kbd_dev->output_size = 0; 595 kbd_dev->output_buffer = usb_hid_report_output(&hid_dev->report, 596 &kbd_dev->output_size, 0); 597 if (kbd_dev->output_buffer == NULL) { 598 usb_log_error("Error creating output report buffer.\n"); 599 rc = ENOMEM; 600 goto error; 601 } 602 603 usb_log_debug("Output buffer size: %zu\n", kbd_dev->output_size); 604 605 kbd_dev->led_path = usb_hid_report_path(); 606 if (kbd_dev->led_path == NULL) { 607 usb_log_error("Failed to create kbd led report path.\n"); 608 rc = ENOMEM; 609 goto error; 610 } 611 612 rc = usb_hid_report_path_append_item( 613 kbd_dev->led_path, USB_HIDUT_PAGE_LED, 0); 614 if (rc != EOK) { 615 usb_log_error("Failed to append to kbd/led report path.\n"); 616 goto error; 617 } 618 619 kbd_dev->led_output_size = usb_hid_report_size( 620 &hid_dev->report, 0, USB_HID_REPORT_TYPE_OUTPUT); 621 622 usb_log_debug("Output report size (in items): %zu\n", 623 kbd_dev->led_output_size); 624 625 kbd_dev->led_data = calloc(kbd_dev->led_output_size, sizeof(int32_t)); 626 if (kbd_dev->led_data == NULL) { 627 usb_log_error("Error creating buffer for LED output report.\n"); 628 rc = ENOMEM; 629 goto error; 630 } 631 632 /* Set LEDs according to initial setup. 633 * Set Idle rate */ 634 usb_kbd_set_led(hid_dev, kbd_dev); 635 636 usbhid_req_set_idle(&hid_dev->usb_dev->ctrl_pipe, 637 hid_dev->usb_dev->interface_no, IDLE_RATE); 638 639 /* Create new fibril for auto-repeat. */ 640 fid = fibril_create(usb_kbd_repeat_fibril, kbd_dev); 641 if (fid == 0) { 642 usb_log_error("Failed to start fibril for KBD auto-repeat"); 643 rc = ENOMEM; 644 goto error; 645 } 646 647 kbd_dev->initialized = USB_KBD_STATUS_INITIALIZED; 648 usb_log_debug("HID/KBD device structure initialized.\n"); 649 650 rc = ddf_fun_bind(fun); 504 651 if (rc != EOK) { 505 652 usb_log_error("Could not bind DDF function: %s.\n", 506 653 str_error(rc)); 507 ddf_fun_destroy(fun); 508 return rc; 509 } 654 goto error; 655 } 656 657 bound = true; 510 658 511 659 usb_log_debug("%s function created. Handle: %" PRIun "\n", … … 519 667 "Could not add DDF function to category %s: %s.\n", 520 668 HID_KBD_CATEGORY, str_error(rc)); 521 if (ddf_fun_unbind(fun) == EOK) { 522 ddf_fun_destroy(fun); 523 } else { 524 usb_log_error( 525 "Failed to unbind `%s', will not destroy.\n", 526 ddf_fun_get_name(fun)); 527 } 528 return rc; 529 } 530 kbd_dev->fun = fun; 531 532 return EOK; 533 } 534 535 /* API functions */ 536 537 /** 538 * Initialization of the USB/HID keyboard structure. 539 * 540 * This functions initializes required structures from the device's descriptors. 541 * 542 * During initialization, the keyboard is switched into boot protocol, the idle 543 * rate is set to 0 (infinity), resulting in the keyboard only reporting event 544 * when a key is pressed or released. Finally, the LED lights are turned on 545 * according to the default setup of lock keys. 546 * 547 * @note By default, the keyboards is initialized with Num Lock turned on and 548 * other locks turned off. 549 * 550 * @param kbd_dev Keyboard device structure to be initialized. 551 * @param dev DDF device structure of the keyboard. 552 * 553 * @retval EOK if successful. 554 * @retval EINVAL if some parameter is not given. 555 * @return Other value inherited from function usbhid_dev_init(). 556 */ 557 int usb_kbd_init(usb_hid_dev_t *hid_dev, void **data) 558 { 559 usb_log_debug("Initializing HID/KBD structure...\n"); 560 561 if (hid_dev == NULL) { 562 usb_log_error( 563 "Failed to init keyboard structure: no structure given.\n"); 564 return EINVAL; 565 } 566 567 usb_kbd_t *kbd_dev = calloc(1, sizeof(usb_kbd_t)); 568 if (kbd_dev == NULL) { 569 usb_log_error("Failed to allocate KBD device structure.\n"); 570 return ENOMEM; 571 } 572 /* Default values */ 573 fibril_mutex_initialize(&kbd_dev->repeat_mtx); 574 kbd_dev->initialized = USB_KBD_STATUS_UNINITIALIZED; 575 576 /* Store link to HID device */ 577 kbd_dev->hid_dev = hid_dev; 578 579 /* Modifiers and locks */ 580 kbd_dev->mods = DEFAULT_ACTIVE_MODS; 581 582 /* Autorepeat */ 583 kbd_dev->repeat.delay_before = DEFAULT_DELAY_BEFORE_FIRST_REPEAT; 584 kbd_dev->repeat.delay_between = DEFAULT_REPEAT_DELAY; 585 586 587 // TODO: make more general 588 usb_hid_report_path_t *path = usb_hid_report_path(); 589 if (path == NULL) { 590 usb_log_error("Failed to create kbd report path.\n"); 591 usb_kbd_destroy(kbd_dev); 592 return ENOMEM; 593 } 594 595 int ret = 596 usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_KEYBOARD, 0); 597 if (ret != EOK) { 598 usb_log_error("Failed to append item to kbd report path.\n"); 599 usb_hid_report_path_free(path); 600 usb_kbd_destroy(kbd_dev); 601 return ret; 602 } 603 604 usb_hid_report_path_set_report_id(path, 0); 605 606 kbd_dev->key_count = 607 usb_hid_report_size(&hid_dev->report, 0, USB_HID_REPORT_TYPE_INPUT); 608 609 usb_hid_report_path_free(path); 610 611 usb_log_debug("Size of the input report: %zu\n", kbd_dev->key_count); 612 613 kbd_dev->keys = calloc(kbd_dev->key_count, sizeof(int32_t)); 614 if (kbd_dev->keys == NULL) { 615 usb_log_error("Failed to allocate key buffer.\n"); 616 usb_kbd_destroy(kbd_dev); 617 return ENOMEM; 618 } 619 620 kbd_dev->keys_old = calloc(kbd_dev->key_count, sizeof(int32_t)); 621 if (kbd_dev->keys_old == NULL) { 622 usb_log_error("Failed to allocate old_key buffer.\n"); 623 usb_kbd_destroy(kbd_dev); 624 return ENOMEM; 625 } 626 627 /* Output report */ 628 kbd_dev->output_size = 0; 629 kbd_dev->output_buffer = usb_hid_report_output(&hid_dev->report, 630 &kbd_dev->output_size, 0); 631 if (kbd_dev->output_buffer == NULL) { 632 usb_log_error("Error creating output report buffer.\n"); 633 usb_kbd_destroy(kbd_dev); 634 return ENOMEM; 635 } 636 637 usb_log_debug("Output buffer size: %zu\n", kbd_dev->output_size); 638 639 kbd_dev->led_path = usb_hid_report_path(); 640 if (kbd_dev->led_path == NULL) { 641 usb_log_error("Failed to create kbd led report path.\n"); 642 usb_kbd_destroy(kbd_dev); 643 return ENOMEM; 644 } 645 646 ret = usb_hid_report_path_append_item( 647 kbd_dev->led_path, USB_HIDUT_PAGE_LED, 0); 648 if (ret != EOK) { 649 usb_log_error("Failed to append to kbd/led report path.\n"); 650 usb_kbd_destroy(kbd_dev); 651 return ret; 652 } 653 654 kbd_dev->led_output_size = usb_hid_report_size( 655 &hid_dev->report, 0, USB_HID_REPORT_TYPE_OUTPUT); 656 657 usb_log_debug("Output report size (in items): %zu\n", 658 kbd_dev->led_output_size); 659 660 kbd_dev->led_data = calloc(kbd_dev->led_output_size, sizeof(int32_t)); 661 if (kbd_dev->led_data == NULL) { 662 usb_log_error("Error creating buffer for LED output report.\n"); 663 usb_kbd_destroy(kbd_dev); 664 return ENOMEM; 665 } 666 667 /* Set LEDs according to initial setup. 668 * Set Idle rate */ 669 usb_kbd_set_led(hid_dev, kbd_dev); 670 671 usbhid_req_set_idle(&hid_dev->usb_dev->ctrl_pipe, 672 hid_dev->usb_dev->interface_no, IDLE_RATE); 669 goto error; 670 } 671 672 fibril_add_ready(fid); 673 673 674 674 /* Save the KBD device structure into the HID device structure. */ 675 675 *data = kbd_dev; 676 676 677 kbd_dev->initialized = USB_KBD_STATUS_INITIALIZED;678 usb_log_debug("HID/KBD device structure initialized.\n");679 680 usb_log_debug("Creating KBD function...\n");681 ret = usb_kbd_create_function(kbd_dev);682 if (ret != EOK) {683 usb_kbd_destroy(kbd_dev);684 return ret;685 }686 687 /* Create new fibril for auto-repeat. */688 fid_t fid = fibril_create(usb_kbd_repeat_fibril, kbd_dev);689 if (fid == 0) {690 usb_log_error("Failed to start fibril for KBD auto-repeat");691 usb_kbd_destroy(kbd_dev);692 return ENOMEM;693 }694 fibril_add_ready(fid);695 696 677 return EOK; 678 error: 679 if (bound) 680 ddf_fun_unbind(fun); 681 if (fid != 0) 682 fibril_destroy(fid); 683 if (kbd_dev != NULL) { 684 free(kbd_dev->led_data); 685 if (kbd_dev->led_path != NULL) 686 usb_hid_report_path_free(kbd_dev->led_path); 687 if (kbd_dev->output_buffer != NULL) 688 usb_hid_report_output_free(kbd_dev->output_buffer); 689 free(kbd_dev->keys_old); 690 free(kbd_dev->keys); 691 } 692 if (path != NULL) 693 usb_hid_report_path_free(path); 694 if (fun != NULL) 695 ddf_fun_destroy(fun); 696 return rc; 697 697 } 698 698 … … 749 749 usb_hid_report_output_free(kbd_dev->output_buffer); 750 750 751 if (kbd_dev->fun) { 752 if (ddf_fun_unbind(kbd_dev->fun) != EOK) { 753 usb_log_warning("Failed to unbind %s.\n", 754 ddf_fun_get_name(kbd_dev->fun)); 755 } else { 756 usb_log_debug2("%s unbound.\n", 757 ddf_fun_get_name(kbd_dev->fun)); 758 ddf_fun_destroy(kbd_dev->fun); 759 } 760 } 751 ddf_fun_unbind(kbd_dev->fun); 752 ddf_fun_destroy(kbd_dev->fun); 761 753 } 762 754 -
uspace/drv/bus/usb/usbhid/mouse/mousedev.c
rebc9c2c r350274a 34 34 * USB Mouse driver API. 35 35 */ 36 37 /* XXX Fix this */38 #define _DDF_DATA_IMPLANT39 36 40 37 #include <usb/debug.h> … … 249 246 } 250 247 251 #define FUN_UNBIND_DESTROY(fun) \252 if (fun) { \253 if (ddf_fun_unbind((fun)) == EOK) { \254 ddf_fun_destroy((fun)); \255 } else { \256 usb_log_error("Could not unbind function `%s', it " \257 "will not be destroyed.\n", ddf_fun_get_name(fun)); \258 } \259 } else (void)0260 261 static int usb_mouse_create_function(usb_hid_dev_t *hid_dev, usb_mouse_t *mouse)262 {263 assert(hid_dev != NULL);264 assert(mouse != NULL);265 266 /* Create the exposed function. */267 usb_log_debug("Creating DDF function %s...\n", HID_MOUSE_FUN_NAME);268 ddf_fun_t *fun = ddf_fun_create(hid_dev->usb_dev->ddf_dev, fun_exposed,269 HID_MOUSE_FUN_NAME);270 if (fun == NULL) {271 usb_log_error("Could not create DDF function node `%s'.\n",272 HID_MOUSE_FUN_NAME);273 return ENOMEM;274 }275 276 ddf_fun_set_ops(fun, &ops);277 ddf_fun_data_implant(fun, mouse);278 279 int rc = ddf_fun_bind(fun);280 if (rc != EOK) {281 usb_log_error("Could not bind DDF function `%s': %s.\n",282 ddf_fun_get_name(fun), str_error(rc));283 ddf_fun_destroy(fun);284 return rc;285 }286 287 usb_log_debug("Adding DDF function `%s' to category %s...\n",288 ddf_fun_get_name(fun), HID_MOUSE_CATEGORY);289 rc = ddf_fun_add_to_category(fun, HID_MOUSE_CATEGORY);290 if (rc != EOK) {291 usb_log_error(292 "Could not add DDF function to category %s: %s.\n",293 HID_MOUSE_CATEGORY, str_error(rc));294 FUN_UNBIND_DESTROY(fun);295 return rc;296 }297 mouse->mouse_fun = fun;298 return EOK;299 }300 301 248 /** Get highest index of a button mentioned in given report. 302 249 * … … 341 288 int usb_mouse_init(usb_hid_dev_t *hid_dev, void **data) 342 289 { 290 ddf_fun_t *fun = NULL; 291 usb_mouse_t *mouse_dev = NULL; 292 bool bound = false; 293 int rc; 294 343 295 usb_log_debug("Initializing HID/Mouse structure...\n"); 344 296 … … 346 298 usb_log_error("Failed to init mouse structure: no structure" 347 299 " given.\n"); 348 return EINVAL; 349 } 350 351 usb_mouse_t *mouse_dev = calloc(1, sizeof(usb_mouse_t)); 300 rc = EINVAL; 301 goto error; 302 } 303 304 /* Create the exposed function. */ 305 usb_log_debug("Creating DDF function %s...\n", HID_MOUSE_FUN_NAME); 306 fun = ddf_fun_create(hid_dev->usb_dev->ddf_dev, fun_exposed, 307 HID_MOUSE_FUN_NAME); 308 if (fun == NULL) { 309 usb_log_error("Could not create DDF function node `%s'.\n", 310 HID_MOUSE_FUN_NAME); 311 rc = ENOMEM; 312 goto error; 313 } 314 315 ddf_fun_set_ops(fun, &ops); 316 317 mouse_dev = ddf_fun_data_alloc(fun, sizeof(usb_mouse_t)); 352 318 if (mouse_dev == NULL) { 353 319 usb_log_error("Error while creating USB/HID Mouse device " 354 320 "structure.\n"); 355 return ENOMEM; 321 rc = ENOMEM; 322 goto error; 356 323 } 357 324 … … 368 335 if (mouse_dev->buttons == NULL) { 369 336 usb_log_error(NAME ": out of memory, giving up on device!\n"); 370 free(mouse_dev);371 return ENOMEM;337 rc = ENOMEM; 338 goto error; 372 339 } 373 340 … … 376 343 hid_dev->usb_dev->interface_no, IDLE_RATE); 377 344 378 int rc = usb_mouse_create_function(hid_dev, mouse_dev);345 rc = ddf_fun_bind(fun); 379 346 if (rc != EOK) { 380 free(mouse_dev->buttons); 381 free(mouse_dev); 382 return rc; 383 } 347 usb_log_error("Could not bind DDF function `%s': %s.\n", 348 ddf_fun_get_name(fun), str_error(rc)); 349 goto error; 350 } 351 352 bound = true; 353 354 usb_log_debug("Adding DDF function `%s' to category %s...\n", 355 ddf_fun_get_name(fun), HID_MOUSE_CATEGORY); 356 rc = ddf_fun_add_to_category(fun, HID_MOUSE_CATEGORY); 357 if (rc != EOK) { 358 usb_log_error("Could not add DDF function to category %s: " 359 "%s.\n", HID_MOUSE_CATEGORY, str_error(rc)); 360 goto error; 361 } 362 363 mouse_dev->mouse_fun = fun; 384 364 385 365 /* Save the Mouse device structure into the HID device structure. */ 386 366 *data = mouse_dev; 387 388 367 return EOK; 368 error: 369 if (bound) 370 ddf_fun_unbind(fun); 371 if (mouse_dev != NULL) 372 free(mouse_dev->buttons); 373 if (fun != NULL) 374 ddf_fun_destroy(fun); 375 return rc; 389 376 } 390 377 … … 417 404 } 418 405 419 FUN_UNBIND_DESTROY(mouse_dev->mouse_fun); 420 406 ddf_fun_unbind(mouse_dev->mouse_fun); 421 407 free(mouse_dev->buttons); 408 ddf_fun_destroy(mouse_dev->mouse_fun); 422 409 } 423 410
Note:
See TracChangeset
for help on using the changeset viewer.