Changes in uspace/drv/usbhub/usbhub.c [15b0432:dff940f8] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/usbhub/usbhub.c
r15b0432 rdff940f8 33 33 */ 34 34 35 #include <d river.h>35 #include <ddf/driver.h> 36 36 #include <bool.h> 37 37 #include <errno.h> … … 44 44 #include <usb/request.h> 45 45 #include <usb/classes/hub.h> 46 #include <stdio.h> 46 47 47 48 #include "usbhub.h" … … 52 53 #include "usb/classes/classes.h" 53 54 54 static d evice_ops_t hub_device_ops = {55 static ddf_dev_ops_t hub_device_ops = { 55 56 .interfaces[USB_DEV_IFACE] = &usb_iface_hub_impl 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 … … 79 94 */ 80 95 static int usb_hub_init_communication(usb_hub_info_t * hub){ 96 usb_log_debug("Initializing hub USB communication (hub->device->handle=%zu).\n", hub->device->handle); 81 97 int opResult; 82 98 opResult = usb_device_connection_initialize_from_device( … … 88 104 return opResult; 89 105 } 106 usb_log_debug("Initializing USB wire abstraction.\n"); 90 107 opResult = usb_hc_connection_initialize_from_device(&hub->connection, 91 108 hub->device); … … 95 112 return opResult; 96 113 } 114 usb_log_debug("Initializing default control pipe.\n"); 97 115 opResult = usb_endpoint_pipe_initialize_default_control(&hub->endpoints.control, 98 116 &hub->device_connection); … … 132 150 133 151 //configuration descriptor 134 /// \TODO check other configurations 152 /// \TODO check other configurations? 135 153 usb_standard_configuration_descriptor_t config_descriptor; 136 154 opResult = usb_request_get_bare_configuration_descriptor( … … 176 194 } 177 195 178 /**179 * Initialize the interrupt in endpoint.180 * \TODO this code should be checked...181 */182 196 usb_endpoint_mapping_t endpoint_mapping[1] = { 183 197 { … … 207 221 return EOK; 208 222 209 210 // Initialize the interrupt(=status change) endpoint.211 /*usb_endpoint_pipe_initialize(212 &result->endpoints->status_change,213 &result->device_connection, );USB_TRANSFER_INTERRUPT214 USB_DIRECTION_IN*/215 216 223 } 217 224 … … 222 229 * @return pointer to created structure or NULL in case of error 223 230 */ 224 usb_hub_info_t * usb_create_hub_info(d evice_t * device) {231 usb_hub_info_t * usb_create_hub_info(ddf_dev_t * device) { 225 232 usb_hub_info_t* result = usb_new(usb_hub_info_t); 226 233 result->device = device; … … 264 271 } 265 272 266 267 273 dprintf(USB_LOG_LEVEL_INFO, "setting port count to %d",descriptor->ports_count); 268 274 result->port_count = descriptor->ports_count; … … 291 297 * @return 292 298 */ 293 int usb_add_hub_device(d evice_t *dev) {299 int usb_add_hub_device(ddf_dev_t *dev) { 294 300 dprintf(USB_LOG_LEVEL_INFO, "add_hub_device(handle=%d)", (int) dev->handle); 295 301 296 dev->ops = &hub_device_ops; 302 //dev->ops = &hub_device_ops; 303 (void) hub_device_ops; 297 304 298 305 usb_hub_info_t * hub_info = usb_create_hub_info(dev); … … 325 332 326 333 //add the hub to list 334 //is this needed now? 327 335 fibril_mutex_lock(&usb_hub_list_lock); 328 336 usb_lst_append(&usb_hub_list, hub_info); 329 337 fibril_mutex_unlock(&usb_hub_list_lock); 330 331 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"); 332 359 //(void)hub_info; 333 usb_hub_check_hub_changes();360 //usb_hub_check_hub_changes(); 334 361 335 362 dprintf(USB_LOG_LEVEL_INFO, "hub dev added"); … … 364 391 //opResult = usb_drv_reserve_default_address(hc); 365 392 opResult = usb_hc_reserve_default_address(&hub->connection, USB_SPEED_LOW); 366 367 if (opResult != EOK) { 368 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); 369 397 return; 370 398 } … … 377 405 ); 378 406 if (opResult != EOK) { 379 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); 380 409 //usb_hub_release_default_address(hc); 381 410 usb_hc_release_default_address(&hub->connection); … … 390 419 */ 391 420 static void usb_hub_finalize_add_device( usb_hub_info_t * hub, 392 uint16_t port ) {421 uint16_t port, bool isLowSpeed) { 393 422 394 423 int opResult; … … 413 442 &new_device_connection); 414 443 /// \TODO get highspeed info 415 416 417 444 usb_speed_t speed = isLowSpeed?USB_SPEED_LOW:USB_SPEED_FULL; 418 445 419 446 … … 421 448 usb_address_t new_device_address = usb_hc_request_address( 422 449 &hub->connection, 423 USB_SPEED_LOW/// \TODO fullspeed??450 speed/// \TODO fullspeed?? 424 451 ); 425 452 if (new_device_address < 0) { … … 432 459 //opResult = usb_drv_req_set_address(hc, USB_ADDRESS_DEFAULT, 433 460 // new_device_address); 461 usb_endpoint_pipe_start_session(&new_device_pipe); 434 462 opResult = usb_request_set_address(&new_device_pipe,new_device_address); 435 436 if (opResult != EOK) { 437 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); 438 467 usb_hc_release_default_address(&hub->connection); 439 468 return; … … 450 479 //?? 451 480 opResult = usb_device_register_child_in_devman(new_device_address, 452 hub->connection.hc_handle, hub->device, &child_handle); 453 454 if (opResult != EOK) { 455 dprintf(USB_LOG_LEVEL_ERROR, "could not start driver for new device"); 481 hub->connection.hc_handle, hub->device, &child_handle, 482 NULL, NULL, NULL); 483 484 if (opResult != EOK) { 485 dprintf(USB_LOG_LEVEL_ERROR, 486 "could not start driver for new device %d",opResult); 456 487 return; 457 488 } … … 464 495 &hub->attached_devs[port]); 465 496 if (opResult != EOK) { 466 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); 467 499 return; 468 500 } … … 506 538 } 507 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 508 560 /** 509 561 * Process interrupts on given hub port … … 517 569 //determine type of change 518 570 usb_endpoint_pipe_t *pipe = &hub->endpoints.control; 519 int opResult = usb_endpoint_pipe_start_session(pipe);520 571 521 if(opResult != EOK){ 522 dprintf(USB_LOG_LEVEL_ERROR, "cannot open pipe %d", opResult); 523 } 524 525 /* 526 usb_target_t target; 527 target.address=address; 528 target.endpoint=0; 529 */ 572 int opResult; 530 573 531 574 usb_port_status_t status; … … 542 585 ); 543 586 if (opResult != EOK) { 544 dprintf(USB_LOG_LEVEL_ERROR, " ERROR:could not get port status");587 dprintf(USB_LOG_LEVEL_ERROR, "could not get port status"); 545 588 return; 546 589 } 547 590 if (rcvd_size != sizeof (usb_port_status_t)) { 548 dprintf(USB_LOG_LEVEL_ERROR, " ERROR:received status has incorrect size");591 dprintf(USB_LOG_LEVEL_ERROR, "received status has incorrect size"); 549 592 return; 550 593 } … … 561 604 } 562 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 } 563 616 //port reset 564 617 if (usb_port_reset_completed(&status)) { 565 618 dprintf(USB_LOG_LEVEL_INFO, "port reset complete"); 566 619 if (usb_port_enabled(&status)) { 567 usb_hub_finalize_add_device(hub, port );620 usb_hub_finalize_add_device(hub, port, usb_port_low_speed(&status)); 568 621 } else { 569 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"); 570 623 } 571 624 } … … 580 633 } 581 634 /// \TODO handle other changes 582 /// \TODO debug log for various situations 583 usb_endpoint_pipe_end_session(pipe); 584 585 586 } 587 588 /** 589 * Check changes on all known hubs. 590 */ 591 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 592 657 /* 593 * Iterate through all hubs.658 * Send the request. 594 659 */ 595 usb_general_list_t * lst_item; 596 fibril_mutex_lock(&usb_hub_list_lock); 597 for (lst_item = usb_hub_list.next; 598 lst_item != &usb_hub_list; 599 lst_item = lst_item->next) { 600 fibril_mutex_unlock(&usb_hub_list_lock); 601 usb_hub_info_t * hub_info = ((usb_hub_info_t*)lst_item->data); 602 int opResult; 603 604 opResult = usb_endpoint_pipe_start_session(&hub_info->endpoints.status_change); 605 if(opResult != EOK){ 606 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); 607 695 } 608 /* 609 * Check status change pipe of this hub. 610 */ 611 /* 612 usb_target_t target; 613 target.address = hub_info->address; 614 target.endpoint = 1;/// \TODO get from endpoint descriptor 615 dprintf(USB_LOG_LEVEL_INFO, "checking changes for hub at addr %d", 616 target.address); 617 */ 618 size_t port_count = hub_info->port_count; 619 620 /* 621 * Connect to respective HC. 622 * 623 int hc = usb_drv_hc_connect_auto(hub_info->device, 0); 624 if (hc < 0) { 625 continue; 626 }*/ 627 628 /// FIXME: count properly 629 size_t byte_length = ((port_count+1) / 8) + 1; 630 631 void *change_bitmap = malloc(byte_length); 632 size_t actual_size; 633 //usb_handle_t handle; 634 635 /* 636 * Send the request. 637 */ 638 opResult = usb_endpoint_pipe_read( 639 &hub_info->endpoints.status_change, 640 change_bitmap, byte_length, &actual_size 641 ); 642 643 //usb_drv_async_wait_for(handle); 644 645 if (opResult != EOK) { 646 free(change_bitmap); 647 dprintf(USB_LOG_LEVEL_WARNING, "something went wrong while getting status of hub"); 648 continue; 649 } 650 unsigned int port; 651 for (port = 1; port < port_count+1; ++port) { 652 bool interrupt = 653 (((uint8_t*) change_bitmap)[port / 8] >> (port % 8)) % 2; 654 if (interrupt) { 655 usb_hub_process_interrupt( 656 hub_info, port); 657 } 658 } 659 usb_endpoint_pipe_end_session(&hub_info->endpoints.status_change); 660 free(change_bitmap); 661 662 663 //async_hangup(hc); 664 fibril_mutex_lock(&usb_hub_list_lock); 665 } 666 fibril_mutex_unlock(&usb_hub_list_lock); 667 } 668 669 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 } 670 702 671 703
Note:
See TracChangeset
for help on using the changeset viewer.