Changeset 299d53e in mainline for uspace/drv/usbhub/usbhub.c
- Timestamp:
- 2011-02-27T02:54:49Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 4abc304
- Parents:
- 8e1eb4d0 (diff), 81c508c (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
r8e1eb4d0 r299d53e 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 … … 249 253 usb_endpoint_pipe_start_session(&result->endpoints.control); 250 254 opResult = usb_request_get_descriptor(&result->endpoints.control, 251 USB_REQUEST_TYPE_CLASS, 252 USB_DESCTYPE_HUB, 0, 0, serialized_descriptor, 255 USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_DEVICE, 256 USB_DESCTYPE_HUB, 257 0, 0, serialized_descriptor, 253 258 USB_HUB_MAX_DESCRIPTOR_SIZE, &received_size); 254 259 usb_endpoint_pipe_end_session(&result->endpoints.control); … … 267 272 } 268 273 269 270 274 dprintf(USB_LOG_LEVEL_INFO, "setting port count to %d",descriptor->ports_count); 271 275 result->port_count = descriptor->ports_count; … … 329 333 330 334 //add the hub to list 335 //is this needed now? 331 336 fibril_mutex_lock(&usb_hub_list_lock); 332 337 usb_lst_append(&usb_hub_list, hub_info); 333 338 fibril_mutex_unlock(&usb_hub_list_lock); 334 335 339 dprintf(USB_LOG_LEVEL_DEBUG, "hub info added to list"); 340 341 dprintf(USB_LOG_LEVEL_DEBUG, "adding to ddf"); 342 ddf_fun_t *hub_fun = ddf_fun_create(dev, fun_exposed, "hub"); 343 assert(hub_fun != NULL); 344 hub_fun->ops = NULL; 345 346 int rc = ddf_fun_bind(hub_fun); 347 assert(rc == EOK); 348 rc = ddf_fun_add_to_class(hub_fun, "hub"); 349 assert(rc == EOK); 350 351 fid_t fid = fibril_create(usb_hub_control_loop, hub_info); 352 if (fid == 0) { 353 dprintf(USB_LOG_LEVEL_ERROR, 354 ": failed to start monitoring fibril for new hub"); 355 return ENOMEM; 356 } 357 fibril_add_ready(fid); 358 359 dprintf(USB_LOG_LEVEL_DEBUG, "hub fibril created"); 336 360 //(void)hub_info; 337 usb_hub_check_hub_changes();361 //usb_hub_check_hub_changes(); 338 362 339 363 dprintf(USB_LOG_LEVEL_INFO, "hub dev added"); … … 368 392 //opResult = usb_drv_reserve_default_address(hc); 369 393 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"); 394 395 if (opResult != EOK) { 396 dprintf(USB_LOG_LEVEL_WARNING, 397 "cannot assign default address, it is probably used %d",opResult); 373 398 return; 374 399 } … … 381 406 ); 382 407 if (opResult != EOK) { 383 dprintf(USB_LOG_LEVEL_ERROR, "something went wrong when reseting a port"); 408 dprintf(USB_LOG_LEVEL_ERROR, 409 "something went wrong when reseting a port %d",opResult); 384 410 //usb_hub_release_default_address(hc); 385 411 usb_hc_release_default_address(&hub->connection); … … 394 420 */ 395 421 static void usb_hub_finalize_add_device( usb_hub_info_t * hub, 396 uint16_t port ) {422 uint16_t port, bool isLowSpeed) { 397 423 398 424 int opResult; … … 417 443 &new_device_connection); 418 444 /// \TODO get highspeed info 419 420 421 445 usb_speed_t speed = isLowSpeed?USB_SPEED_LOW:USB_SPEED_FULL; 422 446 423 447 … … 425 449 usb_address_t new_device_address = usb_hc_request_address( 426 450 &hub->connection, 427 USB_SPEED_LOW/// \TODO fullspeed??451 speed/// \TODO fullspeed?? 428 452 ); 429 453 if (new_device_address < 0) { … … 436 460 //opResult = usb_drv_req_set_address(hc, USB_ADDRESS_DEFAULT, 437 461 // new_device_address); 462 usb_endpoint_pipe_start_session(&new_device_pipe); 438 463 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"); 464 usb_endpoint_pipe_end_session(&new_device_pipe); 465 if (opResult != EOK) { 466 dprintf(USB_LOG_LEVEL_ERROR, 467 "could not set address for new device %d",opResult); 442 468 usb_hc_release_default_address(&hub->connection); 443 469 return; … … 458 484 459 485 if (opResult != EOK) { 460 dprintf(USB_LOG_LEVEL_ERROR, "could not start driver for new device"); 486 dprintf(USB_LOG_LEVEL_ERROR, 487 "could not start driver for new device %d",opResult); 461 488 return; 462 489 } … … 469 496 &hub->attached_devs[port]); 470 497 if (opResult != EOK) { 471 dprintf(USB_LOG_LEVEL_ERROR, "could not assign address of device in hcd"); 498 dprintf(USB_LOG_LEVEL_ERROR, 499 "could not assign address of device in hcd %d",opResult); 472 500 return; 473 501 } … … 511 539 } 512 540 541 542 /** 543 *Process over current condition on port. 544 * 545 * Turn off the power on the port. 546 * 547 * @param hub 548 * @param port 549 */ 550 static void usb_hub_over_current( usb_hub_info_t * hub, 551 uint16_t port){ 552 int opResult; 553 opResult = usb_hub_clear_port_feature(&hub->endpoints.control, 554 port, USB_HUB_FEATURE_PORT_POWER); 555 if(opResult!=EOK){ 556 dprintf(USB_LOG_LEVEL_ERROR, "cannot power off port %d; %d", 557 port, opResult); 558 } 559 } 560 513 561 /** 514 562 * Process interrupts on given hub port … … 522 570 //determine type of change 523 571 usb_endpoint_pipe_t *pipe = &hub->endpoints.control; 524 int opResult = usb_endpoint_pipe_start_session(pipe);525 572 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 */ 573 int opResult; 535 574 536 575 usb_port_status_t status; … … 547 586 ); 548 587 if (opResult != EOK) { 549 dprintf(USB_LOG_LEVEL_ERROR, " ERROR:could not get port status");588 dprintf(USB_LOG_LEVEL_ERROR, "could not get port status"); 550 589 return; 551 590 } 552 591 if (rcvd_size != sizeof (usb_port_status_t)) { 553 dprintf(USB_LOG_LEVEL_ERROR, " ERROR:received status has incorrect size");592 dprintf(USB_LOG_LEVEL_ERROR, "received status has incorrect size"); 554 593 return; 555 594 } … … 566 605 } 567 606 } 607 //over current 608 if (usb_port_overcurrent_change(&status)) { 609 //check if it was not auto-resolved 610 if(usb_port_over_current(&status)){ 611 usb_hub_over_current(hub,port); 612 }else{ 613 dprintf(USB_LOG_LEVEL_INFO, 614 "over current condition was auto-resolved on port %d",port); 615 } 616 } 568 617 //port reset 569 618 if (usb_port_reset_completed(&status)) { 570 619 dprintf(USB_LOG_LEVEL_INFO, "port reset complete"); 571 620 if (usb_port_enabled(&status)) { 572 usb_hub_finalize_add_device(hub, port );621 usb_hub_finalize_add_device(hub, port, usb_port_low_speed(&status)); 573 622 } else { 574 dprintf(USB_LOG_LEVEL_WARNING, " ERROR:port reset, but port still not enabled");623 dprintf(USB_LOG_LEVEL_WARNING, "port reset, but port still not enabled"); 575 624 } 576 625 } … … 585 634 } 586 635 /// \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) { 636 } 637 638 /** 639 * Check changes on particular hub 640 * @param hub_info_param 641 */ 642 void usb_hub_check_hub_changes(usb_hub_info_t * hub_info){ 643 int opResult; 644 opResult = usb_endpoint_pipe_start_session(&hub_info->endpoints.status_change); 645 if(opResult != EOK){ 646 dprintf(USB_LOG_LEVEL_ERROR, 647 "could not initialize communication for hub; %d", opResult); 648 return; 649 } 650 651 size_t port_count = hub_info->port_count; 652 653 /// FIXME: count properly 654 size_t byte_length = ((port_count+1) / 8) + 1; 655 void *change_bitmap = malloc(byte_length); 656 size_t actual_size; 657 597 658 /* 598 * Iterate through all hubs.659 * Send the request. 599 660 */ 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; 661 opResult = usb_endpoint_pipe_read( 662 &hub_info->endpoints.status_change, 663 change_bitmap, byte_length, &actual_size 664 ); 665 666 if (opResult != EOK) { 667 free(change_bitmap); 668 dprintf(USB_LOG_LEVEL_WARNING, "something went wrong while getting status of hub"); 669 usb_endpoint_pipe_end_session(&hub_info->endpoints.status_change); 670 return; 671 } 672 unsigned int port; 673 opResult = usb_endpoint_pipe_start_session(&hub_info->endpoints.control); 674 if(opResult!=EOK){ 675 dprintf(USB_LOG_LEVEL_ERROR, "could not start control pipe session %d", 676 opResult); 677 usb_endpoint_pipe_end_session(&hub_info->endpoints.status_change); 678 return; 679 } 680 opResult = usb_hc_connection_open(&hub_info->connection); 681 if(opResult!=EOK){ 682 dprintf(USB_LOG_LEVEL_ERROR, "could not start host controller session %d", 683 opResult); 684 usb_endpoint_pipe_end_session(&hub_info->endpoints.control); 685 usb_endpoint_pipe_end_session(&hub_info->endpoints.status_change); 686 return; 687 } 688 689 ///todo, opresult check, pre obe konekce 690 for (port = 1; port < port_count+1; ++port) { 691 bool interrupt = 692 (((uint8_t*) change_bitmap)[port / 8] >> (port % 8)) % 2; 693 if (interrupt) { 694 usb_hub_process_interrupt( 695 hub_info, port); 612 696 } 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 697 } 698 usb_hc_connection_close(&hub_info->connection); 699 usb_endpoint_pipe_end_session(&hub_info->endpoints.control); 700 usb_endpoint_pipe_end_session(&hub_info->endpoints.status_change); 701 free(change_bitmap); 702 } 675 703 676 704
Note:
See TracChangeset
for help on using the changeset viewer.