Changeset c50941f in mainline
- Timestamp:
- 2011-04-07T12:07:42Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 69df9373
- Parents:
- 3eaa5a5
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/usbhub/usbhub.c
r3eaa5a5 rc50941f 53 53 #include "usb/classes/classes.h" 54 54 55 56 //static void usb_hub_init_add_device(usb_hub_info_t * hub, uint16_t port,57 // usb_speed_t speed);58 59 55 static int usb_hub_trigger_connecting_non_removable_devices( 60 56 usb_hub_info_t * hub, usb_hub_descriptor_t * descriptor); 61 62 #if 063 /**64 * control loop running in hub`s fibril65 *66 * Hub`s fibril periodically asks for changes on hub and if needded calls67 * change handling routine.68 * @warning currently hub driver asks for changes once a second69 * @param hub_info_param hub representation pointer70 * @return zero71 */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 int errorCode = EOK;75 76 while(errorCode == EOK){77 async_usleep(1000 * 1000 * 10 );/// \TODO proper number once78 errorCode = usb_hub_check_hub_changes(hub_info);79 }80 usb_log_error("something in ctrl loop went wrong, errno %d\n",errorCode);81 82 return 0;83 }84 #endif85 57 86 58 … … 427 399 } 428 400 429 #if 0430 /**431 * Reset the port with new device and reserve the default address.432 * @param hub hub representation433 * @param port port number, starting from 1434 * @param speed transfer speed of attached device, one of low, full or high435 */436 static void usb_hub_init_add_device(usb_hub_info_t * hub, uint16_t port,437 usb_speed_t speed) {438 //if this hub already uses default address, it cannot request it once more439 if(hub->is_default_address_used) return;440 usb_log_debug("some connection changed\n");441 assert(hub->control_pipe->hc_phone);442 int opResult = usb_hub_clear_port_feature(hub->control_pipe,443 port, USB_HUB_FEATURE_C_PORT_CONNECTION);444 if(opResult != EOK){445 usb_log_warning("could not clear port-change-connection flag\n");446 }447 usb_device_request_setup_packet_t request;448 449 //get default address450 opResult = usb_hc_reserve_default_address(&hub->connection, speed);451 452 if (opResult != EOK) {453 usb_log_warning("cannot assign default address, it is probably used %d\n",454 opResult);455 return;456 }457 hub->is_default_address_used = true;458 //reset port459 usb_hub_set_reset_port_request(&request, port);460 opResult = usb_pipe_control_write(461 hub->control_pipe,462 &request,sizeof(usb_device_request_setup_packet_t),463 NULL, 0464 );465 if (opResult != EOK) {466 usb_log_error("something went wrong when reseting a port %d\n",opResult);467 usb_hub_release_default_address(hub);468 }469 return;470 }471 #endif472 473 #if 0474 /**475 * Finalize adding new device after port reset476 *477 * Set device`s address and start it`s driver.478 * @param hub hub representation479 * @param port port number, starting from 1480 * @param speed transfer speed of attached device, one of low, full or high481 */482 static void usb_hub_finalize_add_device( usb_hub_info_t * hub,483 uint16_t port, usb_speed_t speed) {484 485 int opResult;486 usb_log_debug("finalizing add device\n");487 opResult = usb_hub_clear_port_feature(hub->control_pipe,488 port, USB_HUB_FEATURE_C_PORT_RESET);489 490 if (opResult != EOK) {491 usb_log_error("failed to clear port reset feature\n");492 usb_hub_release_default_address(hub);493 return;494 }495 //create connection to device496 usb_pipe_t new_device_pipe;497 usb_device_connection_t new_device_connection;498 usb_device_connection_initialize_on_default_address(499 &new_device_connection,500 &hub->connection501 );502 usb_pipe_initialize_default_control(503 &new_device_pipe,504 &new_device_connection);505 usb_pipe_probe_default_control(&new_device_pipe);506 507 /* Request address from host controller. */508 usb_address_t new_device_address = usb_hc_request_address(509 &hub->connection,510 speed511 );512 if (new_device_address < 0) {513 usb_log_error("failed to get free USB address\n");514 opResult = new_device_address;515 usb_hub_release_default_address(hub);516 return;517 }518 usb_log_debug("setting new address %d\n",new_device_address);519 //opResult = usb_drv_req_set_address(hc, USB_ADDRESS_DEFAULT,520 // new_device_address);521 usb_pipe_start_session(&new_device_pipe);522 opResult = usb_request_set_address(&new_device_pipe,new_device_address);523 usb_pipe_end_session(&new_device_pipe);524 if (opResult != EOK) {525 usb_log_error("could not set address for new device %d\n",opResult);526 usb_hub_release_default_address(hub);527 return;528 }529 530 //opResult = usb_hub_release_default_address(hc);531 opResult = usb_hub_release_default_address(hub);532 if(opResult!=EOK){533 return;534 }535 536 devman_handle_t child_handle;537 //??538 opResult = usb_device_register_child_in_devman(new_device_address,539 hub->connection.hc_handle, hub->usb_device->ddf_dev, &child_handle,540 NULL, NULL, NULL);541 542 if (opResult != EOK) {543 usb_log_error("could not start driver for new device %d\n",opResult);544 return;545 }546 hub->attached_devs[port].handle = child_handle;547 hub->attached_devs[port].address = new_device_address;548 549 //opResult = usb_drv_bind_address(hc, new_device_address, child_handle);550 opResult = usb_hc_register_device(551 &hub->connection,552 &hub->attached_devs[port]);553 if (opResult != EOK) {554 usb_log_error("could not assign address of device in hcd %d\n",opResult);555 return;556 }557 usb_log_info("Detected new device on `%s' (port %d), " \558 "address %d (handle %llu).\n",559 hub->usb_device->ddf_dev->name, (int) port,560 new_device_address, child_handle);561 }562 #endif563 564 401 /** 565 402 * routine called when a device on port has been removed … … 622 459 } 623 460 624 #if 0625 /**626 * Process interrupts on given hub port627 *628 * Accepts connection, over current and port reset change.629 * @param hub hub representation630 * @param port port number, starting from 1631 */632 static void usb_hub_process_interrupt(usb_hub_info_t * hub,633 uint16_t port) {634 usb_log_debug("interrupt at port %d\n", port);635 //determine type of change636 usb_pipe_t *pipe = hub->control_pipe;637 638 int opResult;639 640 usb_port_status_t status;641 size_t rcvd_size;642 usb_device_request_setup_packet_t request;643 //int opResult;644 usb_hub_set_port_status_request(&request, port);645 //endpoint 0646 647 opResult = usb_pipe_control_read(648 pipe,649 &request, sizeof(usb_device_request_setup_packet_t),650 &status, 4, &rcvd_size651 );652 if (opResult != EOK) {653 usb_log_error("could not get port status\n");654 return;655 }656 if (rcvd_size != sizeof (usb_port_status_t)) {657 usb_log_error("received status has incorrect size\n");658 return;659 }660 //something connected/disconnected661 if (usb_port_connect_change(&status)) {662 usb_log_debug("connection change on port\n");663 if (usb_port_dev_connected(&status)) {664 usb_log_debug("some connection changed\n");665 usb_hub_init_add_device(hub, port, usb_port_speed(&status));666 } else {667 usb_hub_removed_device(hub, port);668 }669 }670 //over current671 if (usb_port_overcurrent_change(&status)) {672 //check if it was not auto-resolved673 usb_log_debug("overcurrent change on port\n");674 if(usb_port_over_current(&status)){675 usb_hub_over_current(hub,port);676 }else{677 usb_log_debug("over current condition was auto-resolved on port %d\n",678 port);679 }680 }681 //port reset682 if (usb_port_reset_completed(&status)) {683 usb_log_debug("port reset complete\n");684 if (usb_port_enabled(&status)) {685 usb_hub_finalize_add_device(hub, port, usb_port_speed(&status));686 } else {687 usb_log_warning("port reset, but port still not enabled\n");688 }689 }690 usb_log_debug("status %x\n ",status);691 692 usb_port_set_connect_change(&status, false);693 usb_port_set_reset(&status, false);694 usb_port_set_reset_completed(&status, false);695 usb_port_set_dev_connected(&status, false);696 if (status>>16) {697 usb_log_info("there was some unsupported change on port %d: %X\n",698 port,status);699 700 }701 }702 703 /**704 * check changes on hub705 *706 * Handles changes on each port with a status change.707 * @param hub_info hub representation708 * @return error code709 */710 int usb_hub_check_hub_changes(usb_hub_info_t * hub_info){711 int opResult;712 opResult = usb_pipe_start_session(713 hub_info->status_change_pipe);714 if(opResult != EOK){715 usb_log_error("could not initialize communication for hub; %d\n",716 opResult);717 return opResult;718 }719 720 size_t port_count = hub_info->port_count;721 722 /// FIXME: count properly723 size_t byte_length = ((port_count+1) / 8) + 1;724 void *change_bitmap = malloc(byte_length);725 size_t actual_size;726 727 /*728 * Send the request.729 */730 opResult = usb_pipe_read(731 hub_info->status_change_pipe,732 change_bitmap, byte_length, &actual_size733 );734 735 if (opResult != EOK) {736 free(change_bitmap);737 usb_log_warning("something went wrong while getting status of hub\n");738 usb_pipe_end_session(hub_info->status_change_pipe);739 return opResult;740 }741 unsigned int port;742 opResult = usb_pipe_start_session(hub_info->control_pipe);743 if(opResult!=EOK){744 usb_log_error("could not start control pipe session %d\n", opResult);745 usb_pipe_end_session(hub_info->status_change_pipe);746 return opResult;747 }748 opResult = usb_hc_connection_open(&hub_info->connection);749 if(opResult!=EOK){750 usb_log_error("could not start host controller session %d\n",751 opResult);752 usb_pipe_end_session(hub_info->control_pipe);753 usb_pipe_end_session(hub_info->status_change_pipe);754 return opResult;755 }756 757 ///todo, opresult check, pre obe konekce758 for (port = 1; port < port_count+1; ++port) {759 bool interrupt =760 (((uint8_t*) change_bitmap)[port / 8] >> (port % 8)) % 2;761 if (interrupt) {762 usb_hub_process_interrupt(763 hub_info, port);764 }765 }766 usb_hc_connection_close(&hub_info->connection);767 usb_pipe_end_session(hub_info->control_pipe);768 usb_pipe_end_session(hub_info->status_change_pipe);769 free(change_bitmap);770 return EOK;771 }772 #endif773 774 461 775 462 /**
Note:
See TracChangeset
for help on using the changeset viewer.