Changeset 882f8b1 in mainline
- Timestamp:
- 2011-02-27T00:07:24Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- c2fa801
- Parents:
- ad4562c2
- Location:
- uspace/drv/usbhid
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/usbhid/hid.h
rad4562c2 r882f8b1 70 70 typedef struct { 71 71 ddf_dev_t *device; 72 usb_hid_configuration_t *conf;73 usb_hid_report_parser_t *parser;74 72 75 73 usb_device_connection_t wire; … … 77 75 usb_endpoint_pipe_t poll_pipe; 78 76 77 uint16_t iface; 78 79 uint8_t *report_desc; 80 usb_hid_report_parser_t *parser; 81 79 82 uint8_t *keycodes; 80 83 size_t keycode_count; 81 84 uint8_t modifiers; 85 86 unsigned mods; 87 unsigned lock_keys; 82 88 } usb_hid_dev_kbd_t; 83 89 -
uspace/drv/usbhid/main.c
rad4562c2 r882f8b1 52 52 #include <io/console.h> 53 53 #include <stdint.h> 54 #include <usb/dp.h> 54 55 #include "hid.h" 55 #include "descparser.h"56 #include "descdump.h"56 //#include "descparser.h" 57 //#include "descdump.h" 57 58 #include "conv.h" 58 59 #include "layout.h" … … 62 63 #define NAME "usbhid" 63 64 64 #define GUESSED_POLL_ENDPOINT 165 //#define GUESSED_POLL_ENDPOINT 1 65 66 #define BOOTP_REPORT_SIZE 6 67 68 static unsigned DEFAULT_ACTIVE_MODS = KM_NUM_LOCK; 66 69 67 70 /** Keyboard polling endpoint description for boot protocol class. */ … … 144 147 * TODO: put to device? 145 148 */ 146 static unsigned mods = KM_NUM_LOCK;149 //static unsigned mods = KM_NUM_LOCK; 147 150 148 151 /** Currently pressed lock keys. We track these to tackle autorepeat. … … 150 153 * TODO: put to device? 151 154 */ 152 static unsigned lock_keys;155 //static unsigned lock_keys; 153 156 154 157 #define NUM_LAYOUTS 3 … … 195 198 } 196 199 197 static void usbkbd_req_set_protocol(usb_hid_dev_kbd_t *kbd_dev, uint16_t iface,200 static void usbkbd_req_set_protocol(usb_hid_dev_kbd_t *kbd_dev, 198 201 usb_hid_protocol_t protocol) 199 202 { … … 207 210 } 208 211 209 usb_log_debug("Sending Set_Protocol request to the device.\n"); 212 usb_log_debug("Sending Set_Protocol request to the device (" 213 "protocol: %d, iface: %d).\n", protocol, kbd_dev->iface); 210 214 211 215 rc = usb_control_request_set(&kbd_dev->ctrl_pipe, 212 216 USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE, 213 USB_HIDREQ_SET_PROTOCOL, protocol, iface, NULL, 0);217 USB_HIDREQ_SET_PROTOCOL, protocol, kbd_dev->iface, NULL, 0); 214 218 215 219 sess_rc = usb_endpoint_pipe_end_session(&kbd_dev->ctrl_pipe); … … 228 232 } 229 233 230 static void usbkbd_set_led(unsigned mods, usb_hid_dev_kbd_t *kbd_dev) 231 { 232 uint8_t buffer[BUFFER_SIZE]; 233 int rc= 0; 234 234 static void usbkbd_set_led(usb_hid_dev_kbd_t *kbd_dev) 235 { 236 uint8_t buffer[BUFFER_OUT_SIZE]; 237 int rc= 0, i; 238 239 memset(buffer, 0, BUFFER_OUT_SIZE); 235 240 uint8_t leds = 0; 236 241 237 if ( mods & KM_NUM_LOCK) {242 if (kbd_dev->mods & KM_NUM_LOCK) { 238 243 leds |= USB_HID_LED_NUM_LOCK; 239 244 } 240 245 241 if ( mods & KM_CAPS_LOCK) {246 if (kbd_dev->mods & KM_CAPS_LOCK) { 242 247 leds |= USB_HID_LED_CAPS_LOCK; 243 248 } 244 249 245 if ( mods & KM_SCROLL_LOCK) {250 if (kbd_dev->mods & KM_SCROLL_LOCK) { 246 251 leds |= USB_HID_LED_SCROLL_LOCK; 247 252 } … … 250 255 251 256 usb_log_debug("Creating output report.\n"); 257 usb_log_debug("Leds: 0x%x\n", leds); 252 258 if ((rc = usb_hid_boot_keyboard_output_report( 253 leds, buffer, BUFFER_ SIZE)) != EOK) {259 leds, buffer, BUFFER_OUT_SIZE)) != EOK) { 254 260 usb_log_warning("Error composing output report to the keyboard:" 255 261 "%s.\n", str_error(rc)); … … 257 263 } 258 264 259 // TODO: determine what interface to use!! (now set to 1) 260 usbkbd_req_set_report(kbd_dev, 1, USB_HID_REPORT_TYPE_OUTPUT, buffer, 261 BUFFER_SIZE); 265 usb_log_debug("Output report buffer: "); 266 for (i = 0; i < BUFFER_OUT_SIZE; ++i) { 267 usb_log_debug("0x%x ", buffer[i]); 268 } 269 usb_log_debug("\n"); 270 271 uint16_t value = 0; 272 value |= (USB_HID_REPORT_TYPE_OUTPUT << 8); 273 274 usbkbd_req_set_report(kbd_dev, kbd_dev->iface, value, buffer, 275 BUFFER_OUT_SIZE); 262 276 } 263 277 … … 280 294 if (mod_mask != 0) { 281 295 if (type == KEY_PRESS) 282 mods =mods | mod_mask;296 kbd_dev->mods = kbd_dev->mods | mod_mask; 283 297 else 284 mods =mods & ~mod_mask;298 kbd_dev->mods = kbd_dev->mods & ~mod_mask; 285 299 } 286 300 … … 294 308 if (mod_mask != 0) { 295 309 usb_log_debug2("\n\nChanging mods and lock keys\n"); 296 usb_log_debug2("\nmods before: 0x%x\n", mods);297 usb_log_debug2("\nLock keys before:0x%x\n\n", lock_keys);310 usb_log_debug2("\nmods before: 0x%x\n", kbd_dev->mods); 311 usb_log_debug2("\nLock keys before:0x%x\n\n", kbd_dev->lock_keys); 298 312 299 313 if (type == KEY_PRESS) { … … 304 318 * up the lock state. 305 319 */ 306 mods = mods ^ (mod_mask & ~lock_keys); 307 lock_keys = lock_keys | mod_mask; 320 kbd_dev->mods = 321 kbd_dev->mods ^ (mod_mask & ~kbd_dev->lock_keys); 322 kbd_dev->lock_keys = kbd_dev->lock_keys | mod_mask; 308 323 309 324 /* Update keyboard lock indicator lights. */ 310 usbkbd_set_led( mods,kbd_dev);325 usbkbd_set_led(kbd_dev); 311 326 } else { 312 327 usb_log_debug2("\nKey released.\n"); 313 lock_keys = lock_keys & ~mod_mask; 314 } 315 } 316 /* 317 usb_log_debug2("type: %d\n", type); 318 usb_log_debug2("mods: 0x%x\n", mods); 319 usb_log_debug2("keycode: %u\n", key); 320 */ 321 usb_log_debug2("\n\nmods after: 0x%x\n", mods); 322 usb_log_debug2("\nLock keys after: 0x%x\n\n", lock_keys); 323 324 if (type == KEY_PRESS && (mods & KM_LCTRL) && 325 key == KC_F1) { 328 kbd_dev->lock_keys = kbd_dev->lock_keys & ~mod_mask; 329 } 330 } 331 332 usb_log_debug2("\n\nmods after: 0x%x\n", kbd_dev->mods); 333 usb_log_debug2("\nLock keys after: 0x%x\n\n", kbd_dev->lock_keys); 334 335 if (type == KEY_PRESS && (kbd_dev->mods & KM_LCTRL) && key == KC_F1) { 326 336 active_layout = 0; 327 337 layout[active_layout]->reset(); … … 329 339 } 330 340 331 if (type == KEY_PRESS && (mods & KM_LCTRL) && 332 key == KC_F2) { 341 if (type == KEY_PRESS && (kbd_dev->mods & KM_LCTRL) && key == KC_F2) { 333 342 active_layout = 1; 334 343 layout[active_layout]->reset(); … … 336 345 } 337 346 338 if (type == KEY_PRESS && (mods & KM_LCTRL) && 339 key == KC_F3) { 347 if (type == KEY_PRESS && (kbd_dev->mods & KM_LCTRL) && key == KC_F3) { 340 348 active_layout = 2; 341 349 layout[active_layout]->reset(); … … 345 353 ev.type = type; 346 354 ev.key = key; 347 ev.mods = mods;355 ev.mods = kbd_dev->mods; 348 356 349 357 if (ev.mods & KM_NUM_LOCK) { … … 506 514 * Kbd functions 507 515 */ 508 static int usbkbd_get_report_descriptor(usb_hid_dev_kbd_t *kbd_dev)509 {510 // iterate over all configurations and interfaces511 // TODO: more configurations!!512 unsigned i;513 for (i = 0; i < kbd_dev->conf->config_descriptor.interface_count; ++i) {514 // TODO: endianness515 uint16_t length = kbd_dev->conf->interfaces[i].hid_desc.516 report_desc_info.length;517 size_t actual_size = 0;518 519 // allocate space for the report descriptor520 kbd_dev->conf->interfaces[i].report_desc =521 (uint8_t *)malloc(length);516 //static int usbkbd_get_report_descriptor(usb_hid_dev_kbd_t *kbd_dev) 517 //{ 518 // // iterate over all configurations and interfaces 519 // // TODO: more configurations!! 520 // unsigned i; 521 // for (i = 0; i < kbd_dev->conf->config_descriptor.interface_count; ++i) { 522 // // TODO: endianness 523 // uint16_t length = kbd_dev->conf->interfaces[i].hid_desc. 524 // report_desc_info.length; 525 // size_t actual_size = 0; 526 527 // // allocate space for the report descriptor 528 // kbd_dev->conf->interfaces[i].report_desc = 529 // (uint8_t *)malloc(length); 522 530 523 // get the descriptor from the device 524 int rc = usb_request_get_descriptor(&kbd_dev->ctrl_pipe, 525 USB_REQUEST_TYPE_CLASS, USB_DESCTYPE_HID_REPORT, 526 i, 0, 527 kbd_dev->conf->interfaces[i].report_desc, length, 528 &actual_size); 529 530 if (rc != EOK) { 531 return rc; 532 } 533 534 assert(actual_size == length); 535 536 //dump_hid_class_descriptor(0, USB_DESCTYPE_HID_REPORT, 537 // kbd_dev->conf->interfaces[i].report_desc, length); 538 } 539 531 // // get the descriptor from the device 532 // int rc = usb_request_get_descriptor(&kbd_dev->ctrl_pipe, 533 // USB_REQUEST_TYPE_CLASS, USB_DESCTYPE_HID_REPORT, 534 // i, 0, 535 // kbd_dev->conf->interfaces[i].report_desc, length, 536 // &actual_size); 537 538 // if (rc != EOK) { 539 // return rc; 540 // } 541 542 // assert(actual_size == length); 543 544 // //dump_hid_class_descriptor(0, USB_DESCTYPE_HID_REPORT, 545 // // kbd_dev->conf->interfaces[i].report_desc, length); 546 // } 547 548 // return EOK; 549 //} 550 551 static int usbkbd_get_report_descriptor(usb_hid_dev_kbd_t *kbd_dev, 552 uint8_t *config_desc, size_t config_desc_size, uint8_t *iface_desc) 553 { 554 assert(kbd_dev != NULL); 555 assert(config_desc != NULL); 556 assert(config_desc_size != 0); 557 assert(iface_desc != NULL); 558 559 usb_dp_parser_t parser = { 560 .nesting = usb_dp_standard_descriptor_nesting 561 }; 562 563 usb_dp_parser_data_t parser_data = { 564 .data = config_desc, 565 .size = config_desc_size, 566 .arg = NULL 567 }; 568 569 /* 570 * First nested descriptor of interface descriptor. 571 */ 572 uint8_t *d = 573 usb_dp_get_nested_descriptor(&parser, &parser_data, iface_desc); 574 575 /* 576 * Search through siblings until the HID descriptor is found. 577 */ 578 while (d != NULL && *(d + 1) != USB_DESCTYPE_HID) { 579 d = usb_dp_get_sibling_descriptor(&parser, &parser_data, 580 iface_desc, d); 581 } 582 583 if (d == NULL) { 584 usb_log_fatal("No HID descriptor found!\n"); 585 return ENOENT; 586 } 587 588 if (*d != sizeof(usb_standard_hid_descriptor_t)) { 589 usb_log_fatal("HID descriptor hass wrong size (%u, expected %u" 590 ")\n", *d, sizeof(usb_standard_hid_descriptor_t)); 591 return EINVAL; 592 } 593 594 usb_standard_hid_descriptor_t *hid_desc = 595 (usb_standard_hid_descriptor_t *)d; 596 597 uint16_t length = hid_desc->report_desc_info.length; 598 size_t actual_size = 0; 599 600 /* 601 * Allocate space for the report descriptor. 602 */ 603 kbd_dev->report_desc = (uint8_t *)malloc(length); 604 if (kbd_dev->report_desc == NULL) { 605 usb_log_fatal("Failed to allocate space for Report descriptor." 606 "\n"); 607 return ENOMEM; 608 } 609 610 usb_log_debug("Getting Report descriptor, expected size: %u\n", length); 611 612 /* 613 * Get the descriptor from the device. 614 */ 615 int rc = usb_request_get_descriptor(&kbd_dev->ctrl_pipe, 616 USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_INTERFACE, 617 USB_DESCTYPE_HID_REPORT, 0, 618 kbd_dev->iface, kbd_dev->report_desc, length, &actual_size); 619 620 if (rc != EOK) { 621 return rc; 622 } 623 624 if (actual_size != length) { 625 free(kbd_dev->report_desc); 626 kbd_dev->report_desc = NULL; 627 usb_log_fatal("Report descriptor has wrong size (%u, expected " 628 "%u)\n", actual_size, length); 629 return EINVAL; 630 } 631 632 usb_log_debug("Done.\n"); 633 540 634 return EOK; 541 635 } … … 588 682 descriptors, config_desc.total_length, 589 683 &kbd_dev->wire); 684 590 685 if (rc != EOK) { 591 686 usb_log_error("Failed to initialize poll pipe: %s.\n", 592 687 str_error(rc)); 688 free(descriptors); 593 689 return rc; 594 690 } 691 595 692 if (!endpoint_mapping[0].present) { 596 693 usb_log_warning("Not accepting device, " \ 597 694 "not boot-protocol keyboard.\n"); 695 free(descriptors); 598 696 return EREFUSED; 599 697 } 600 601 kbd_dev->conf = (usb_hid_configuration_t *)calloc(1, 602 sizeof(usb_hid_configuration_t)); 603 if (kbd_dev->conf == NULL) { 698 699 usb_log_debug("Accepted device. Saving interface, and getting Report" 700 " descriptor.\n"); 701 702 /* 703 * Save assigned interface number. 704 */ 705 if (endpoint_mapping[0].interface_no < 0) { 706 usb_log_error("Bad interface number.\n"); 604 707 free(descriptors); 605 return ENOMEM; 606 } 607 608 /*rc = usbkbd_parse_descriptors(descriptors, transferred, kbd_dev->conf); 708 return EINVAL; 709 } 710 711 kbd_dev->iface = endpoint_mapping[0].interface_no; 712 713 assert(endpoint_mapping[0].interface != NULL); 714 715 rc = usbkbd_get_report_descriptor(kbd_dev, descriptors, transferred, 716 (uint8_t *)endpoint_mapping[0].interface); 717 609 718 free(descriptors); 610 if (rc != EOK) { 611 usb_log_warning("Problem with parsing standard descriptors.\n"); 612 return rc; 613 } 614 615 // get and report descriptors*/ 616 rc = usbkbd_get_report_descriptor(kbd_dev); 719 617 720 if (rc != EOK) { 618 721 usb_log_warning("Problem with parsing REPORT descriptor.\n"); … … 620 723 } 621 724 622 //usbkbd_print_config(kbd_dev->conf); 623 624 /* 625 * TODO: 626 * 1) select one configuration (lets say the first) 627 * 2) how many interfaces?? how to select one?? 628 * ("The default setting for an interface is always alternate 629 * setting zero.") 630 * 3) find endpoint which is IN and INTERRUPT (parse), save its number 631 * as the endpoint for polling 632 */ 633 725 usb_log_debug("Done parsing descriptors.\n"); 726 634 727 return EOK; 635 728 } … … 671 764 672 765 /* 673 * will need all descriptors: 674 * 1) choose one configuration from configuration descriptors 675 * (set it to the device) 676 * 2) set endpoints from endpoint descriptors 677 */ 678 679 // TODO: get descriptors, parse descriptors and save endpoints 766 * Get descriptors, parse descriptors and save endpoints. 767 */ 680 768 usb_endpoint_pipe_start_session(&kbd_dev->ctrl_pipe); 769 681 770 rc = usbkbd_process_descriptors(kbd_dev); 771 682 772 usb_endpoint_pipe_end_session(&kbd_dev->ctrl_pipe); 683 773 if (rc != EOK) { … … 685 775 } 686 776 687 // save the size of the report 777 // save the size of the report (boot protocol report by default) 688 778 kbd_dev->keycode_count = BOOTP_REPORT_SIZE; 689 779 kbd_dev->keycodes = (uint8_t *)calloc( … … 695 785 } 696 786 697 // set configuration to the first one 698 // TODO: handle case with no configurations 699 usb_endpoint_pipe_start_session(&kbd_dev->ctrl_pipe); 700 usb_request_set_configuration(&kbd_dev->ctrl_pipe, 701 kbd_dev->conf->config_descriptor.configuration_number); 702 usb_endpoint_pipe_end_session(&kbd_dev->ctrl_pipe); 787 kbd_dev->modifiers = 0; 788 kbd_dev->mods = DEFAULT_ACTIVE_MODS; 789 kbd_dev->lock_keys = 0; 703 790 704 791 // set boot protocol 705 usbkbd_req_set_protocol(kbd_dev, 1, USB_HID_PROTOCOL_BOOT); 792 usbkbd_req_set_protocol(kbd_dev, USB_HID_PROTOCOL_BOOT); 793 794 // set LEDs according to internal setup (NUM LOCK enabled) 795 usbkbd_set_led(kbd_dev); 706 796 707 797 return kbd_dev; … … 743 833 744 834 while (true) { 745 async_usleep(1000 * 10 00);835 async_usleep(1000 * 10); 746 836 747 837 sess_rc = usb_endpoint_pipe_start_session(&kbd_dev->poll_pipe);
Note:
See TracChangeset
for help on using the changeset viewer.