Changes in uspace/drv/usbhub/usbhub.c [dff940f8:15b0432] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/usbhub/usbhub.c
rdff940f8 r15b0432 33 33 */ 34 34 35 #include <d df/driver.h>35 #include <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>47 46 48 47 #include "usbhub.h" … … 53 52 #include "usb/classes/classes.h" 54 53 55 static d df_dev_ops_t hub_device_ops = {54 static device_ops_t hub_device_ops = { 56 55 .interfaces[USB_DEV_IFACE] = &usb_iface_hub_impl 57 56 }; 58 57 59 /** Hub status-change endpoint description 60 * 61 * For more see usb hub specification in 11.15.1 of 62 */ 58 /** Hub status-change endpoint description */ 63 59 static usb_endpoint_description_t status_change_endpoint_description = { 64 60 .transfer_type = USB_TRANSFER_INTERRUPT, 65 61 .direction = USB_DIRECTION_IN, 66 62 .interface_class = USB_CLASS_HUB, 67 .interface_subclass = 0,68 .interface_protocol = 0,69 63 .flags = 0 70 64 }; 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 once77 }78 return 0;79 }80 65 81 66 … … 94 79 */ 95 80 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);97 81 int opResult; 98 82 opResult = usb_device_connection_initialize_from_device( … … 104 88 return opResult; 105 89 } 106 usb_log_debug("Initializing USB wire abstraction.\n");107 90 opResult = usb_hc_connection_initialize_from_device(&hub->connection, 108 91 hub->device); … … 112 95 return opResult; 113 96 } 114 usb_log_debug("Initializing default control pipe.\n");115 97 opResult = usb_endpoint_pipe_initialize_default_control(&hub->endpoints.control, 116 98 &hub->device_connection); … … 150 132 151 133 //configuration descriptor 152 /// \TODO check other configurations ?134 /// \TODO check other configurations 153 135 usb_standard_configuration_descriptor_t config_descriptor; 154 136 opResult = usb_request_get_bare_configuration_descriptor( … … 194 176 } 195 177 178 /** 179 * Initialize the interrupt in endpoint. 180 * \TODO this code should be checked... 181 */ 196 182 usb_endpoint_mapping_t endpoint_mapping[1] = { 197 183 { … … 221 207 return EOK; 222 208 209 210 // Initialize the interrupt(=status change) endpoint. 211 /*usb_endpoint_pipe_initialize( 212 &result->endpoints->status_change, 213 &result->device_connection, );USB_TRANSFER_INTERRUPT 214 USB_DIRECTION_IN*/ 215 223 216 } 224 217 … … 229 222 * @return pointer to created structure or NULL in case of error 230 223 */ 231 usb_hub_info_t * usb_create_hub_info(d df_dev_t * device) {224 usb_hub_info_t * usb_create_hub_info(device_t * device) { 232 225 usb_hub_info_t* result = usb_new(usb_hub_info_t); 233 226 result->device = device; … … 271 264 } 272 265 266 273 267 dprintf(USB_LOG_LEVEL_INFO, "setting port count to %d",descriptor->ports_count); 274 268 result->port_count = descriptor->ports_count; … … 297 291 * @return 298 292 */ 299 int usb_add_hub_device(d df_dev_t *dev) {293 int usb_add_hub_device(device_t *dev) { 300 294 dprintf(USB_LOG_LEVEL_INFO, "add_hub_device(handle=%d)", (int) dev->handle); 301 295 302 //dev->ops = &hub_device_ops; 303 (void) hub_device_ops; 296 dev->ops = &hub_device_ops; 304 297 305 298 usb_hub_info_t * hub_info = usb_create_hub_info(dev); … … 332 325 333 326 //add the hub to list 334 //is this needed now?335 327 fibril_mutex_lock(&usb_hub_list_lock); 336 328 usb_lst_append(&usb_hub_list, hub_info); 337 329 fibril_mutex_unlock(&usb_hub_list_lock); 330 338 331 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");359 332 //(void)hub_info; 360 //usb_hub_check_hub_changes();333 usb_hub_check_hub_changes(); 361 334 362 335 dprintf(USB_LOG_LEVEL_INFO, "hub dev added"); … … 391 364 //opResult = usb_drv_reserve_default_address(hc); 392 365 opResult = usb_hc_reserve_default_address(&hub->connection, USB_SPEED_LOW); 393 394 if (opResult != EOK) { 395 dprintf(USB_LOG_LEVEL_WARNING, 396 "cannot assign default address, it is probably used %d",opResult); 366 367 if (opResult != EOK) { 368 dprintf(USB_LOG_LEVEL_WARNING, "cannot assign default address, it is probably used"); 397 369 return; 398 370 } … … 405 377 ); 406 378 if (opResult != EOK) { 407 dprintf(USB_LOG_LEVEL_ERROR, 408 "something went wrong when reseting a port %d",opResult); 379 dprintf(USB_LOG_LEVEL_ERROR, "something went wrong when reseting a port"); 409 380 //usb_hub_release_default_address(hc); 410 381 usb_hc_release_default_address(&hub->connection); … … 419 390 */ 420 391 static void usb_hub_finalize_add_device( usb_hub_info_t * hub, 421 uint16_t port , bool isLowSpeed) {392 uint16_t port) { 422 393 423 394 int opResult; … … 442 413 &new_device_connection); 443 414 /// \TODO get highspeed info 444 usb_speed_t speed = isLowSpeed?USB_SPEED_LOW:USB_SPEED_FULL; 415 416 417 445 418 446 419 … … 448 421 usb_address_t new_device_address = usb_hc_request_address( 449 422 &hub->connection, 450 speed/// \TODO fullspeed??423 USB_SPEED_LOW/// \TODO fullspeed?? 451 424 ); 452 425 if (new_device_address < 0) { … … 459 432 //opResult = usb_drv_req_set_address(hc, USB_ADDRESS_DEFAULT, 460 433 // new_device_address); 461 usb_endpoint_pipe_start_session(&new_device_pipe);462 434 opResult = usb_request_set_address(&new_device_pipe,new_device_address); 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); 435 436 if (opResult != EOK) { 437 dprintf(USB_LOG_LEVEL_ERROR, "could not set address for new device"); 467 438 usb_hc_release_default_address(&hub->connection); 468 439 return; … … 479 450 //?? 480 451 opResult = usb_device_register_child_in_devman(new_device_address, 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); 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"); 487 456 return; 488 457 } … … 495 464 &hub->attached_devs[port]); 496 465 if (opResult != EOK) { 497 dprintf(USB_LOG_LEVEL_ERROR, 498 "could not assign address of device in hcd %d",opResult); 466 dprintf(USB_LOG_LEVEL_ERROR, "could not assign address of device in hcd"); 499 467 return; 500 468 } … … 538 506 } 539 507 540 541 /**542 *Process over current condition on port.543 *544 * Turn off the power on the port.545 *546 * @param hub547 * @param port548 */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 560 508 /** 561 509 * Process interrupts on given hub port … … 569 517 //determine type of change 570 518 usb_endpoint_pipe_t *pipe = &hub->endpoints.control; 519 int opResult = usb_endpoint_pipe_start_session(pipe); 571 520 572 int opResult; 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 530 574 531 usb_port_status_t status; … … 585 542 ); 586 543 if (opResult != EOK) { 587 dprintf(USB_LOG_LEVEL_ERROR, " could not get port status");544 dprintf(USB_LOG_LEVEL_ERROR, "ERROR: could not get port status"); 588 545 return; 589 546 } 590 547 if (rcvd_size != sizeof (usb_port_status_t)) { 591 dprintf(USB_LOG_LEVEL_ERROR, " received status has incorrect size");548 dprintf(USB_LOG_LEVEL_ERROR, "ERROR: received status has incorrect size"); 592 549 return; 593 550 } … … 604 561 } 605 562 } 606 //over current607 if (usb_port_overcurrent_change(&status)) {608 //check if it was not auto-resolved609 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 }616 563 //port reset 617 564 if (usb_port_reset_completed(&status)) { 618 565 dprintf(USB_LOG_LEVEL_INFO, "port reset complete"); 619 566 if (usb_port_enabled(&status)) { 620 usb_hub_finalize_add_device(hub, port , usb_port_low_speed(&status));567 usb_hub_finalize_add_device(hub, port); 621 568 } else { 622 dprintf(USB_LOG_LEVEL_WARNING, " port reset, but port still not enabled");569 dprintf(USB_LOG_LEVEL_WARNING, "ERROR: port reset, but port still not enabled"); 623 570 } 624 571 } … … 633 580 } 634 581 /// \TODO handle other changes 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; 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) { 592 /* 593 * Iterate through all hubs. 594 */ 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; 607 } 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 654 631 void *change_bitmap = malloc(byte_length); 655 size_t actual_size; 656 657 /* 658 * Send the request. 659 */ 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) { 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); 666 660 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); 695 } 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 } 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 702 670 703 671
Note:
See TracChangeset
for help on using the changeset viewer.