Changeset 3a1aa20 in mainline for uspace/drv/usbhub/usbhub.c
- Timestamp:
- 2011-02-26T15:22:27Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- ad4562c2
- Parents:
- 0475e13 (diff), b8622e2 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/usbhub/usbhub.c
r0475e13 r3a1aa20 44 44 #include <usb/request.h> 45 45 #include <usb/classes/hub.h> 46 #include <stdio.h> 46 47 47 48 #include "usbhub.h" … … 56 57 }; 57 58 58 /** Hub status-change endpoint description */ 59 /** Hub status-change endpoint description 60 * 61 * For more see usb hub specification in 11.15.1 of 62 */ 59 63 static usb_endpoint_description_t status_change_endpoint_description = { 60 64 .transfer_type = USB_TRANSFER_INTERRUPT, 61 65 .direction = USB_DIRECTION_IN, 62 66 .interface_class = USB_CLASS_HUB, 67 .interface_subclass = 0, 68 .interface_protocol = 0, 63 69 .flags = 0 64 70 }; 71 72 int usb_hub_control_loop(void * hub_info_param){ 73 usb_hub_info_t * hub_info = (usb_hub_info_t*)hub_info_param; 74 while(true){ 75 usb_hub_check_hub_changes(hub_info); 76 async_usleep(1000 * 1000 );/// \TODO proper number once 77 } 78 return 0; 79 } 65 80 66 81 … … 135 150 136 151 //configuration descriptor 137 /// \TODO check other configurations 152 /// \TODO check other configurations? 138 153 usb_standard_configuration_descriptor_t config_descriptor; 139 154 opResult = usb_request_get_bare_configuration_descriptor( … … 179 194 } 180 195 181 /**182 * Initialize the interrupt in endpoint.183 * \TODO this code should be checked...184 */185 196 usb_endpoint_mapping_t endpoint_mapping[1] = { 186 197 { … … 210 221 return EOK; 211 222 212 213 // Initialize the interrupt(=status change) endpoint.214 /*usb_endpoint_pipe_initialize(215 &result->endpoints->status_change,216 &result->device_connection, );USB_TRANSFER_INTERRUPT217 USB_DIRECTION_IN*/218 219 223 } 220 224 … … 267 271 } 268 272 269 270 273 dprintf(USB_LOG_LEVEL_INFO, "setting port count to %d",descriptor->ports_count); 271 274 result->port_count = descriptor->ports_count; … … 329 332 330 333 //add the hub to list 334 //is this needed now? 331 335 fibril_mutex_lock(&usb_hub_list_lock); 332 336 usb_lst_append(&usb_hub_list, hub_info); 333 337 fibril_mutex_unlock(&usb_hub_list_lock); 334 335 338 dprintf(USB_LOG_LEVEL_DEBUG, "hub info added to list"); 339 340 dprintf(USB_LOG_LEVEL_DEBUG, "adding to ddf"); 341 ddf_fun_t *hub_fun = ddf_fun_create(dev, fun_exposed, "hub"); 342 assert(hub_fun != NULL); 343 hub_fun->ops = NULL; 344 345 int rc = ddf_fun_bind(hub_fun); 346 assert(rc == EOK); 347 rc = ddf_fun_add_to_class(hub_fun, "hub"); 348 assert(rc == EOK); 349 350 fid_t fid = fibril_create(usb_hub_control_loop, hub_info); 351 if (fid == 0) { 352 dprintf(USB_LOG_LEVEL_ERROR, 353 ": failed to start monitoring fibril for new hub"); 354 return ENOMEM; 355 } 356 fibril_add_ready(fid); 357 358 dprintf(USB_LOG_LEVEL_DEBUG, "hub fibril created"); 336 359 //(void)hub_info; 337 usb_hub_check_hub_changes();360 //usb_hub_check_hub_changes(); 338 361 339 362 dprintf(USB_LOG_LEVEL_INFO, "hub dev added"); … … 368 391 //opResult = usb_drv_reserve_default_address(hc); 369 392 opResult = usb_hc_reserve_default_address(&hub->connection, USB_SPEED_LOW); 370 371 if (opResult != EOK) { 372 dprintf(USB_LOG_LEVEL_WARNING, "cannot assign default address, it is probably used"); 393 394 if (opResult != EOK) { 395 dprintf(USB_LOG_LEVEL_WARNING, 396 "cannot assign default address, it is probably used %d",opResult); 373 397 return; 374 398 } … … 381 405 ); 382 406 if (opResult != EOK) { 383 dprintf(USB_LOG_LEVEL_ERROR, "something went wrong when reseting a port"); 407 dprintf(USB_LOG_LEVEL_ERROR, 408 "something went wrong when reseting a port %d",opResult); 384 409 //usb_hub_release_default_address(hc); 385 410 usb_hc_release_default_address(&hub->connection); … … 394 419 */ 395 420 static void usb_hub_finalize_add_device( usb_hub_info_t * hub, 396 uint16_t port ) {421 uint16_t port, bool isLowSpeed) { 397 422 398 423 int opResult; … … 417 442 &new_device_connection); 418 443 /// \TODO get highspeed info 419 420 421 444 usb_speed_t speed = isLowSpeed?USB_SPEED_LOW:USB_SPEED_FULL; 422 445 423 446 … … 425 448 usb_address_t new_device_address = usb_hc_request_address( 426 449 &hub->connection, 427 USB_SPEED_LOW/// \TODO fullspeed??450 speed/// \TODO fullspeed?? 428 451 ); 429 452 if (new_device_address < 0) { … … 436 459 //opResult = usb_drv_req_set_address(hc, USB_ADDRESS_DEFAULT, 437 460 // new_device_address); 461 usb_endpoint_pipe_start_session(&new_device_pipe); 438 462 opResult = usb_request_set_address(&new_device_pipe,new_device_address); 439 440 if (opResult != EOK) { 441 dprintf(USB_LOG_LEVEL_ERROR, "could not set address for new device"); 463 usb_endpoint_pipe_end_session(&new_device_pipe); 464 if (opResult != EOK) { 465 dprintf(USB_LOG_LEVEL_ERROR, 466 "could not set address for new device %d",opResult); 442 467 usb_hc_release_default_address(&hub->connection); 443 468 return; … … 458 483 459 484 if (opResult != EOK) { 460 dprintf(USB_LOG_LEVEL_ERROR, "could not start driver for new device"); 485 dprintf(USB_LOG_LEVEL_ERROR, 486 "could not start driver for new device %d",opResult); 461 487 return; 462 488 } … … 469 495 &hub->attached_devs[port]); 470 496 if (opResult != EOK) { 471 dprintf(USB_LOG_LEVEL_ERROR, "could not assign address of device in hcd"); 497 dprintf(USB_LOG_LEVEL_ERROR, 498 "could not assign address of device in hcd %d",opResult); 472 499 return; 473 500 } … … 511 538 } 512 539 540 541 /** 542 *Process over current condition on port. 543 * 544 * Turn off the power on the port. 545 * 546 * @param hub 547 * @param port 548 */ 549 static void usb_hub_over_current( usb_hub_info_t * hub, 550 uint16_t port){ 551 int opResult; 552 opResult = usb_hub_clear_port_feature(&hub->endpoints.control, 553 port, USB_HUB_FEATURE_PORT_POWER); 554 if(opResult!=EOK){ 555 dprintf(USB_LOG_LEVEL_ERROR, "cannot power off port %d; %d", 556 port, opResult); 557 } 558 } 559 513 560 /** 514 561 * Process interrupts on given hub port … … 522 569 //determine type of change 523 570 usb_endpoint_pipe_t *pipe = &hub->endpoints.control; 524 int opResult = usb_endpoint_pipe_start_session(pipe);525 571 526 if(opResult != EOK){ 527 dprintf(USB_LOG_LEVEL_ERROR, "cannot open pipe %d", opResult); 528 } 529 530 /* 531 usb_target_t target; 532 target.address=address; 533 target.endpoint=0; 534 */ 572 int opResult; 535 573 536 574 usb_port_status_t status; … … 547 585 ); 548 586 if (opResult != EOK) { 549 dprintf(USB_LOG_LEVEL_ERROR, " ERROR:could not get port status");587 dprintf(USB_LOG_LEVEL_ERROR, "could not get port status"); 550 588 return; 551 589 } 552 590 if (rcvd_size != sizeof (usb_port_status_t)) { 553 dprintf(USB_LOG_LEVEL_ERROR, " ERROR:received status has incorrect size");591 dprintf(USB_LOG_LEVEL_ERROR, "received status has incorrect size"); 554 592 return; 555 593 } … … 566 604 } 567 605 } 606 //over current 607 if (usb_port_overcurrent_change(&status)) { 608 //check if it was not auto-resolved 609 if(usb_port_over_current(&status)){ 610 usb_hub_over_current(hub,port); 611 }else{ 612 dprintf(USB_LOG_LEVEL_INFO, 613 "over current condition was auto-resolved on port %d",port); 614 } 615 } 568 616 //port reset 569 617 if (usb_port_reset_completed(&status)) { 570 618 dprintf(USB_LOG_LEVEL_INFO, "port reset complete"); 571 619 if (usb_port_enabled(&status)) { 572 usb_hub_finalize_add_device(hub, port );620 usb_hub_finalize_add_device(hub, port, usb_port_low_speed(&status)); 573 621 } else { 574 dprintf(USB_LOG_LEVEL_WARNING, " ERROR:port reset, but port still not enabled");622 dprintf(USB_LOG_LEVEL_WARNING, "port reset, but port still not enabled"); 575 623 } 576 624 } … … 585 633 } 586 634 /// \TODO handle other changes 587 /// \TODO debug log for various situations 588 usb_endpoint_pipe_end_session(pipe); 589 590 591 } 592 593 /** 594 * Check changes on all known hubs. 595 */ 596 void usb_hub_check_hub_changes(void) { 635 } 636 637 /** 638 * Check changes on particular hub 639 * @param hub_info_param 640 */ 641 void usb_hub_check_hub_changes(usb_hub_info_t * hub_info){ 642 int opResult; 643 opResult = usb_endpoint_pipe_start_session(&hub_info->endpoints.status_change); 644 if(opResult != EOK){ 645 dprintf(USB_LOG_LEVEL_ERROR, 646 "could not initialize communication for hub; %d", opResult); 647 return; 648 } 649 650 size_t port_count = hub_info->port_count; 651 652 /// FIXME: count properly 653 size_t byte_length = ((port_count+1) / 8) + 1; 654 void *change_bitmap = malloc(byte_length); 655 size_t actual_size; 656 597 657 /* 598 * Iterate through all hubs.658 * Send the request. 599 659 */ 600 usb_general_list_t * lst_item; 601 fibril_mutex_lock(&usb_hub_list_lock); 602 for (lst_item = usb_hub_list.next; 603 lst_item != &usb_hub_list; 604 lst_item = lst_item->next) { 605 fibril_mutex_unlock(&usb_hub_list_lock); 606 usb_hub_info_t * hub_info = ((usb_hub_info_t*)lst_item->data); 607 int opResult; 608 609 opResult = usb_endpoint_pipe_start_session(&hub_info->endpoints.status_change); 610 if(opResult != EOK){ 611 continue; 660 opResult = usb_endpoint_pipe_read( 661 &hub_info->endpoints.status_change, 662 change_bitmap, byte_length, &actual_size 663 ); 664 665 if (opResult != EOK) { 666 free(change_bitmap); 667 dprintf(USB_LOG_LEVEL_WARNING, "something went wrong while getting status of hub"); 668 usb_endpoint_pipe_end_session(&hub_info->endpoints.status_change); 669 return; 670 } 671 unsigned int port; 672 opResult = usb_endpoint_pipe_start_session(&hub_info->endpoints.control); 673 if(opResult!=EOK){ 674 dprintf(USB_LOG_LEVEL_ERROR, "could not start control pipe session %d", 675 opResult); 676 usb_endpoint_pipe_end_session(&hub_info->endpoints.status_change); 677 return; 678 } 679 opResult = usb_hc_connection_open(&hub_info->connection); 680 if(opResult!=EOK){ 681 dprintf(USB_LOG_LEVEL_ERROR, "could not start host controller session %d", 682 opResult); 683 usb_endpoint_pipe_end_session(&hub_info->endpoints.control); 684 usb_endpoint_pipe_end_session(&hub_info->endpoints.status_change); 685 return; 686 } 687 688 ///todo, opresult check, pre obe konekce 689 for (port = 1; port < port_count+1; ++port) { 690 bool interrupt = 691 (((uint8_t*) change_bitmap)[port / 8] >> (port % 8)) % 2; 692 if (interrupt) { 693 usb_hub_process_interrupt( 694 hub_info, port); 612 695 } 613 /* 614 * Check status change pipe of this hub. 615 */ 616 /* 617 usb_target_t target; 618 target.address = hub_info->address; 619 target.endpoint = 1;/// \TODO get from endpoint descriptor 620 dprintf(USB_LOG_LEVEL_INFO, "checking changes for hub at addr %d", 621 target.address); 622 */ 623 size_t port_count = hub_info->port_count; 624 625 /* 626 * Connect to respective HC. 627 * 628 int hc = usb_drv_hc_connect_auto(hub_info->device, 0); 629 if (hc < 0) { 630 continue; 631 }*/ 632 633 /// FIXME: count properly 634 size_t byte_length = ((port_count+1) / 8) + 1; 635 636 void *change_bitmap = malloc(byte_length); 637 size_t actual_size; 638 //usb_handle_t handle; 639 640 /* 641 * Send the request. 642 */ 643 opResult = usb_endpoint_pipe_read( 644 &hub_info->endpoints.status_change, 645 change_bitmap, byte_length, &actual_size 646 ); 647 648 //usb_drv_async_wait_for(handle); 649 650 if (opResult != EOK) { 651 free(change_bitmap); 652 dprintf(USB_LOG_LEVEL_WARNING, "something went wrong while getting status of hub"); 653 continue; 654 } 655 unsigned int port; 656 for (port = 1; port < port_count+1; ++port) { 657 bool interrupt = 658 (((uint8_t*) change_bitmap)[port / 8] >> (port % 8)) % 2; 659 if (interrupt) { 660 usb_hub_process_interrupt( 661 hub_info, port); 662 } 663 } 664 usb_endpoint_pipe_end_session(&hub_info->endpoints.status_change); 665 free(change_bitmap); 666 667 668 //async_hangup(hc); 669 fibril_mutex_lock(&usb_hub_list_lock); 670 } 671 fibril_mutex_unlock(&usb_hub_list_lock); 672 } 673 674 696 } 697 usb_hc_connection_close(&hub_info->connection); 698 usb_endpoint_pipe_end_session(&hub_info->endpoints.control); 699 usb_endpoint_pipe_end_session(&hub_info->endpoints.status_change); 700 free(change_bitmap); 701 } 675 702 676 703
Note:
See TracChangeset
for help on using the changeset viewer.