Changes in uspace/drv/bus/usb/usbhid/usbhid.c [93d2684:065064e6] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/usbhid/usbhid.c
r93d2684 r065064e6 54 54 55 55 /* Array of endpoints expected on the device, NULL terminated. */ 56 constusb_endpoint_description_t *usb_hid_endpoints[] = {56 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 63 65 /*----------------------------------------------------------------------------*/ 64 66 65 67 static int usb_hid_set_boot_kbd_subdriver(usb_hid_dev_t *hid_dev) 66 68 { 67 assert(hid_dev != NULL );68 assert(hid_dev->subdriver_count == 0); 69 70 hid_dev->subdrivers = malloc(sizeof(usb_hid_subdriver_t));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)); 71 73 if (hid_dev->subdrivers == NULL) { 72 74 return ENOMEM; 73 75 } 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; 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; 77 94 78 95 return EOK; … … 83 100 static int usb_hid_set_boot_mouse_subdriver(usb_hid_dev_t *hid_dev) 84 101 { 85 assert(hid_dev != NULL );86 assert(hid_dev->subdriver_count == 0); 87 88 hid_dev->subdrivers = malloc(sizeof(usb_hid_subdriver_t));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)); 89 106 if (hid_dev->subdrivers == NULL) { 90 107 return ENOMEM; 91 108 } 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; 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; 95 127 96 128 return EOK; … … 103 135 assert(hid_dev != NULL && hid_dev->subdriver_count == 0); 104 136 105 hid_dev->subdrivers = malloc(sizeof(usb_hid_subdriver_t)); 137 hid_dev->subdrivers = (usb_hid_subdriver_t *)malloc( 138 sizeof(usb_hid_subdriver_t)); 106 139 if (hid_dev->subdrivers == NULL) { 107 140 return ENOMEM; 108 141 } 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; 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 = 158 usb_generic_hid_deinit; 159 160 // set subdriver count 161 ++hid_dev->subdriver_count; 116 162 117 163 return EOK; … … 120 166 /*----------------------------------------------------------------------------*/ 121 167 122 static bool usb_hid_ids_match( const usb_hid_dev_t *hid_dev,168 static bool usb_hid_ids_match(usb_hid_dev_t *hid_dev, 123 169 const usb_hid_subdriver_mapping_t *mapping) 124 170 { … … 126 172 assert(hid_dev->usb_dev != NULL); 127 173 128 return (hid_dev->usb_dev->descriptors.device.vendor_id 174 return (hid_dev->usb_dev->descriptors.device.vendor_id 129 175 == mapping->vendor_id 130 176 && hid_dev->usb_dev->descriptors.device.product_id … … 134 180 /*----------------------------------------------------------------------------*/ 135 181 136 static bool usb_hid_path_matches(usb_hid_dev_t *hid_dev, 182 static bool usb_hid_path_matches(usb_hid_dev_t *hid_dev, 137 183 const usb_hid_subdriver_mapping_t *mapping) 138 184 { … … 146 192 } 147 193 int i = 0; 148 while (mapping->usage_path[i].usage != 0 194 while (mapping->usage_path[i].usage != 0 149 195 || mapping->usage_path[i].usage_page != 0) { 150 if (usb_hid_report_path_append_item(usage_path, 151 mapping->usage_path[i].usage_page, 196 if (usb_hid_report_path_append_item(usage_path, 197 mapping->usage_path[i].usage_page, 152 198 mapping->usage_path[i].usage) != EOK) { 153 199 usb_log_debug("Failed to append to usage path.\n"); … … 158 204 } 159 205 206 assert(hid_dev->report != NULL); 207 160 208 usb_log_debug("Compare flags: %d\n", mapping->compare); 161 209 … … 165 213 do { 166 214 usb_log_debug("Trying report id %u\n", report_id); 167 215 168 216 if (report_id != 0) { 169 217 usb_hid_report_path_set_report_id(usage_path, … … 172 220 173 221 usb_hid_report_field_t *field = usb_hid_report_get_sibling( 174 &hid_dev->report, NULL, usage_path, mapping->compare, 222 hid_dev->report, 223 NULL, usage_path, mapping->compare, 175 224 USB_HID_REPORT_TYPE_INPUT); 176 225 177 226 usb_log_debug("Field: %p\n", field); 178 227 … … 181 230 break; 182 231 } 183 232 184 233 report_id = usb_hid_get_next_report_id( 185 &hid_dev->report, report_id, USB_HID_REPORT_TYPE_INPUT); 234 hid_dev->report, report_id, 235 USB_HID_REPORT_TYPE_INPUT); 186 236 } while (!matches && report_id != 0); 187 237 … … 193 243 /*----------------------------------------------------------------------------*/ 194 244 195 static int usb_hid_save_subdrivers(usb_hid_dev_t *hid_dev, 245 static int usb_hid_save_subdrivers(usb_hid_dev_t *hid_dev, 196 246 const usb_hid_subdriver_t **subdrivers, int count) 197 247 { … … 204 254 } 205 255 206 /* +1 for generic hid subdriver */ 207 hid_dev->subdrivers = calloc((count + 1), sizeof(usb_hid_subdriver_t)); 256 // add one generic HID subdriver per device 257 258 hid_dev->subdrivers = (usb_hid_subdriver_t *)malloc((count + 1) * 259 sizeof(usb_hid_subdriver_t)); 208 260 if (hid_dev->subdrivers == NULL) { 209 261 return ENOMEM; … … 217 269 } 218 270 219 /* Add one generic HID subdriver per device */220 271 hid_dev->subdrivers[count].init = usb_generic_hid_init; 221 272 hid_dev->subdrivers[count].poll = usb_generic_hid_polling_callback; … … 256 307 return EINVAL; 257 308 } 258 309 259 310 ids_matched = false; 260 311 matched = false; 261 312 262 313 if (mapping->vendor_id >= 0) { 263 314 assert(mapping->product_id >= 0); … … 270 321 } 271 322 } 272 323 273 324 if (mapping->usage_path != NULL) { 274 325 usb_log_debug("Comparing device against usage path.\n"); … … 281 332 matched = ids_matched; 282 333 } 283 334 284 335 if (matched) { 285 336 usb_log_debug("Subdriver matched.\n"); 286 337 subdrivers[count++] = &mapping->subdriver; 287 338 } 288 339 289 340 mapping = &usb_hid_subdrivers[++i]; 290 341 } 291 342 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 // we have all subdrivers determined, save them into the hid device 295 344 return usb_hid_save_subdrivers(hid_dev, subdrivers, count); 296 345 } … … 298 347 /*----------------------------------------------------------------------------*/ 299 348 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); 349 static int usb_hid_check_pipes(usb_hid_dev_t *hid_dev, usb_device_t *dev) 350 { 351 assert(hid_dev != NULL && dev != NULL); 352 353 int rc = EOK; 304 354 305 355 if (dev->pipes[USB_HID_KBD_POLL_EP_NO].present) { … … 318 368 usb_log_error("None of supported endpoints found - probably" 319 369 " not a supported device.\n"); 320 r eturnENOTSUP;321 } 322 323 return EOK;370 rc = ENOTSUP; 371 } 372 373 return rc; 324 374 } 325 375 … … 328 378 static int usb_hid_init_report(usb_hid_dev_t *hid_dev) 329 379 { 330 assert(hid_dev != NULL );380 assert(hid_dev != NULL && hid_dev->report != NULL); 331 381 332 382 uint8_t report_id = 0; 383 size_t size; 384 333 385 size_t max_size = 0; 334 386 335 387 do { 336 388 usb_log_debug("Getting size of the report.\n"); 337 const size_t size = 338 usb_hid_report_byte_size(&hid_dev->report, report_id, 339 USB_HID_REPORT_TYPE_INPUT); 389 size = usb_hid_report_byte_size(hid_dev->report, report_id, 390 USB_HID_REPORT_TYPE_INPUT); 340 391 usb_log_debug("Report ID: %u, size: %zu\n", report_id, size); 341 392 max_size = (size > max_size) ? size : max_size; 342 393 usb_log_debug("Getting next report ID\n"); 343 report_id = usb_hid_get_next_report_id( &hid_dev->report,394 report_id = usb_hid_get_next_report_id(hid_dev->report, 344 395 report_id, USB_HID_REPORT_TYPE_INPUT); 345 396 } while (report_id != 0); … … 347 398 usb_log_debug("Max size of input report: %zu\n", max_size); 348 399 400 hid_dev->max_input_report_size = max_size; 349 401 assert(hid_dev->input_report == NULL); 350 402 351 hid_dev->input_report = calloc(1,max_size);403 hid_dev->input_report = malloc(max_size); 352 404 if (hid_dev->input_report == NULL) { 353 405 return ENOMEM; 354 406 } 355 hid_dev->max_input_report_size = max_size;407 memset(hid_dev->input_report, 0, max_size); 356 408 357 409 return EOK; … … 378 430 } 379 431 380 usb_hid_report_init(&hid_dev->report); 432 hid_dev->report = (usb_hid_report_t *)(malloc(sizeof( 433 usb_hid_report_t))); 434 if (hid_dev->report == NULL) { 435 usb_log_error("No memory!\n"); 436 return ENOMEM; 437 } 438 usb_hid_report_init(hid_dev->report); 381 439 382 440 /* The USB device should already be initialized, save it in structure */ … … 388 446 return rc; 389 447 } 390 448 391 449 /* Get the report descriptor and parse it. */ 392 rc = usb_hid_process_report_descriptor(hid_dev->usb_dev, 393 &hid_dev->report, &hid_dev->report_desc, &hid_dev->report_desc_size);450 rc = usb_hid_process_report_descriptor(hid_dev->usb_dev, 451 hid_dev->report, &hid_dev->report_desc, &hid_dev->report_desc_size); 394 452 395 453 bool fallback = false; … … 430 488 break; 431 489 default: 432 assert(hid_dev->poll_pipe_index 490 assert(hid_dev->poll_pipe_index 433 491 == USB_HID_GENERIC_POLL_EP_NO); 434 492 435 493 usb_log_info("Falling back to generic HID driver.\n"); 436 494 rc = usb_hid_set_generic_hid_subdriver(hid_dev); … … 441 499 usb_log_error("No subdriver for handling this device could be" 442 500 " initialized: %s.\n", str_error(rc)); 443 usb_log_debug("Subdriver count: %d\n", 501 usb_log_debug("Subdriver count: %d\n", 444 502 hid_dev->subdriver_count); 503 445 504 } else { 446 505 bool ok = false; 447 448 usb_log_debug("Subdriver count: %d\n", 506 507 usb_log_debug("Subdriver count: %d\n", 449 508 hid_dev->subdriver_count); 450 509 451 510 for (i = 0; i < hid_dev->subdriver_count; ++i) { 452 511 if (hid_dev->subdrivers[i].init != NULL) { … … 465 524 } 466 525 } 467 526 468 527 rc = (ok) ? EOK : -1; // what error to report 469 528 } … … 479 538 } 480 539 540 481 541 return rc; 482 542 } … … 484 544 /*----------------------------------------------------------------------------*/ 485 545 486 bool usb_hid_polling_callback(usb_device_t *dev, uint8_t *buffer, 546 bool usb_hid_polling_callback(usb_device_t *dev, uint8_t *buffer, 487 547 size_t buffer_size, void *arg) 488 548 { 549 int i; 550 489 551 if (dev == NULL || arg == NULL || buffer == NULL) { 490 552 usb_log_error("Missing arguments to polling callback.\n"); 491 553 return false; 492 554 } 493 usb_hid_dev_t *hid_dev = arg; 555 556 usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)arg; 494 557 495 558 assert(hid_dev->input_report != NULL); 496 497 559 usb_log_debug("New data [%zu/%zu]: %s\n", buffer_size, 498 560 hid_dev->max_input_report_size, … … 506 568 } 507 569 508 /* Parse the input report */ 509 const int rc = usb_hid_parse_report( 510 &hid_dev->report, buffer, buffer_size, &hid_dev->report_id); 570 // parse the input report 571 572 int rc = usb_hid_parse_report(hid_dev->report, buffer, buffer_size, 573 &hid_dev->report_id); 574 511 575 if (rc != EOK) { 512 576 usb_log_warning("Error in usb_hid_parse_report():" 513 577 "%s\n", str_error(rc)); 514 } 578 } 515 579 516 580 bool cont = false; 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); 581 582 // continue if at least one of the subdrivers want to continue 583 for (i = 0; i < hid_dev->subdriver_count; ++i) { 584 if (hid_dev->subdrivers[i].poll != NULL 585 && hid_dev->subdrivers[i].poll(hid_dev, 586 hid_dev->subdrivers[i].data)) { 587 cont = true; 522 588 } 523 589 } … … 528 594 /*----------------------------------------------------------------------------*/ 529 595 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) { 596 void usb_hid_polling_ended_callback(usb_device_t *dev, bool reason, 597 void *arg) 598 { 599 int i; 600 601 if (dev == NULL || arg == NULL) { 602 return; 603 } 604 605 usb_hid_dev_t *hid_dev = (usb_hid_dev_t *)arg; 606 607 for (i = 0; i < hid_dev->subdriver_count; ++i) { 538 608 if (hid_dev->subdrivers[i].poll_end != NULL) { 539 hid_dev->subdrivers[i].poll_end( 540 hid_dev , hid_dev->subdrivers[i].data, reason);609 hid_dev->subdrivers[i].poll_end(hid_dev, 610 hid_dev->subdrivers[i].data, reason); 541 611 } 542 612 } … … 554 624 /*----------------------------------------------------------------------------*/ 555 625 556 int usb_hid_report_number( constusb_hid_dev_t *hid_dev)626 int usb_hid_report_number(usb_hid_dev_t *hid_dev) 557 627 { 558 628 return hid_dev->report_nr; … … 561 631 /*----------------------------------------------------------------------------*/ 562 632 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 633 void usb_hid_destroy(usb_hid_dev_t *hid_dev) 634 { 635 int i; 636 637 if (hid_dev == NULL) { 638 return; 639 } 568 640 569 641 usb_log_debug("Subdrivers: %p, subdriver count: %d\n", 570 642 hid_dev->subdrivers, hid_dev->subdriver_count); 571 643 572 for (int i = 0; i < hid_dev->subdriver_count; ++i) { 644 assert(hid_dev->subdrivers != NULL 645 || hid_dev->subdriver_count == 0); 646 647 for (i = 0; i < hid_dev->subdriver_count; ++i) { 573 648 if (hid_dev->subdrivers[i].deinit != NULL) { 574 649 hid_dev->subdrivers[i].deinit(hid_dev, … … 582 657 583 658 /* Destroy the parser */ 584 usb_hid_report_deinit(&hid_dev->report); 659 if (hid_dev->report != NULL) { 660 usb_hid_free_report(hid_dev->report); 661 } 585 662 586 663 }
Note:
See TracChangeset
for help on using the changeset viewer.