Changes in uspace/drv/usbhub/usbhub.c [15b0432:ad4562c2] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/usbhub/usbhub.c
r15b0432 rad4562c2 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; … … 246 253 usb_endpoint_pipe_start_session(&result->endpoints.control); 247 254 opResult = usb_request_get_descriptor(&result->endpoints.control, 248 USB_REQUEST_TYPE_CLASS, 249 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, 250 258 USB_HUB_MAX_DESCRIPTOR_SIZE, &received_size); 251 259 usb_endpoint_pipe_end_session(&result->endpoints.control); … … 264 272 } 265 273 266 267 274 dprintf(USB_LOG_LEVEL_INFO, "setting port count to %d",descriptor->ports_count); 268 275 result->port_count = descriptor->ports_count; … … 291 298 * @return 292 299 */ 293 int usb_add_hub_device(d evice_t *dev) {300 int usb_add_hub_device(ddf_dev_t *dev) { 294 301 dprintf(USB_LOG_LEVEL_INFO, "add_hub_device(handle=%d)", (int) dev->handle); 295 302 296 dev->ops = &hub_device_ops; 303 //dev->ops = &hub_device_ops; 304 (void) hub_device_ops; 297 305 298 306 usb_hub_info_t * hub_info = usb_create_hub_info(dev); … … 325 333 326 334 //add the hub to list 335 //is this needed now? 327 336 fibril_mutex_lock(&usb_hub_list_lock); 328 337 usb_lst_append(&usb_hub_list, hub_info); 329 338 fibril_mutex_unlock(&usb_hub_list_lock); 330 331 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"); 332 360 //(void)hub_info; 333 usb_hub_check_hub_changes();361 //usb_hub_check_hub_changes(); 334 362 335 363 dprintf(USB_LOG_LEVEL_INFO, "hub dev added"); … … 364 392 //opResult = usb_drv_reserve_default_address(hc); 365 393 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"); 394 395 if (opResult != EOK) { 396 dprintf(USB_LOG_LEVEL_WARNING, 397 "cannot assign default address, it is probably used %d",opResult); 369 398 return; 370 399 } … … 377 406 ); 378 407 if (opResult != EOK) { 379 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); 380 410 //usb_hub_release_default_address(hc); 381 411 usb_hc_release_default_address(&hub->connection); … … 390 420 */ 391 421 static void usb_hub_finalize_add_device( usb_hub_info_t * hub, 392 uint16_t port ) {422 uint16_t port, bool isLowSpeed) { 393 423 394 424 int opResult; … … 413 443 &new_device_connection); 414 444 /// \TODO get highspeed info 415 416 417 445 usb_speed_t speed = isLowSpeed?USB_SPEED_LOW:USB_SPEED_FULL; 418 446 419 447 … … 421 449 usb_address_t new_device_address = usb_hc_request_address( 422 450 &hub->connection, 423 USB_SPEED_LOW/// \TODO fullspeed??451 speed/// \TODO fullspeed?? 424 452 ); 425 453 if (new_device_address < 0) { … … 432 460 //opResult = usb_drv_req_set_address(hc, USB_ADDRESS_DEFAULT, 433 461 // new_device_address); 462 usb_endpoint_pipe_start_session(&new_device_pipe); 434 463 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"); 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); 438 468 usb_hc_release_default_address(&hub->connection); 439 469 return; … … 450 480 //?? 451 481 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"); 482 hub->connection.hc_handle, hub->device, &child_handle, 483 NULL, NULL, NULL); 484 485 if (opResult != EOK) { 486 dprintf(USB_LOG_LEVEL_ERROR, 487 "could not start driver for new device %d",opResult); 456 488 return; 457 489 } … … 464 496 &hub->attached_devs[port]); 465 497 if (opResult != EOK) { 466 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); 467 500 return; 468 501 } … … 506 539 } 507 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 508 561 /** 509 562 * Process interrupts on given hub port … … 517 570 //determine type of change 518 571 usb_endpoint_pipe_t *pipe = &hub->endpoints.control; 519 int opResult = usb_endpoint_pipe_start_session(pipe);520 572 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 */ 573 int opResult; 530 574 531 575 usb_port_status_t status; … … 542 586 ); 543 587 if (opResult != EOK) { 544 dprintf(USB_LOG_LEVEL_ERROR, " ERROR:could not get port status");588 dprintf(USB_LOG_LEVEL_ERROR, "could not get port status"); 545 589 return; 546 590 } 547 591 if (rcvd_size != sizeof (usb_port_status_t)) { 548 dprintf(USB_LOG_LEVEL_ERROR, " ERROR:received status has incorrect size");592 dprintf(USB_LOG_LEVEL_ERROR, "received status has incorrect size"); 549 593 return; 550 594 } … … 561 605 } 562 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 } 563 617 //port reset 564 618 if (usb_port_reset_completed(&status)) { 565 619 dprintf(USB_LOG_LEVEL_INFO, "port reset complete"); 566 620 if (usb_port_enabled(&status)) { 567 usb_hub_finalize_add_device(hub, port );621 usb_hub_finalize_add_device(hub, port, usb_port_low_speed(&status)); 568 622 } else { 569 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"); 570 624 } 571 625 } … … 580 634 } 581 635 /// \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) { 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 592 658 /* 593 * Iterate through all hubs.659 * Send the request. 594 660 */ 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; 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); 607 696 } 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 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 } 670 703 671 704
Note:
See TracChangeset
for help on using the changeset viewer.