Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/usbhub/usbhub.c

    r4d0c40b rdf3ad97  
    5353#include "usb/classes/classes.h"
    5454
     55
     56static void usb_hub_init_add_device(usb_hub_info_t * hub, uint16_t port,
     57                usb_speed_t speed);
     58
     59static int usb_hub_trigger_connecting_non_removable_devices(
     60                usb_hub_info_t * hub, usb_hub_descriptor_t * descriptor);
     61
     62/**
     63 * control loop running in hub`s fibril
     64 *
     65 * Hub`s fibril periodically asks for changes on hub and if needded calls
     66 * change handling routine.
     67 * @warning currently hub driver asks for changes once a second
     68 * @param hub_info_param hub representation pointer
     69 * @return zero
     70 */
    5571int usb_hub_control_loop(void * hub_info_param){
    5672        usb_hub_info_t * hub_info = (usb_hub_info_t*)hub_info_param;
     
    91107
    92108/**
    93  * Load hub-specific information into hub_info structure.
     109 * Load hub-specific information into hub_info structure and process if needed
    94110 *
    95111 * Particularly read port count and initialize structure holding port
    96  * information.
     112 * information. If there are non-removable devices, start initializing them.
    97113 * This function is hub-specific and should be run only after the hub is
    98114 * configured using usb_hub_set_configuration function.
    99  * @param hub_info pointer to structure with usb hub data
     115 * @param hub_info hub representation
    100116 * @return error code
    101117 */
    102 static int usb_hub_get_hub_specific_info(usb_hub_info_t * hub_info){
     118static int usb_hub_process_hub_specific_info(usb_hub_info_t * hub_info){
    103119        // get hub descriptor
    104120        usb_log_debug("creating serialized descriptor\n");
     
    107123
    108124        /* this was one fix of some bug, should not be needed anymore
     125         * these lines allow to reset hub once more, it can be used as
     126         * brute-force initialization for non-removable devices
    109127        int opResult = usb_request_set_configuration(&result->endpoints.control, 1);
    110128        if(opResult!=EOK){
     
    132150                return opResult;
    133151        }
    134         usb_log_info("setting port count to %d\n",descriptor->ports_count);
     152        usb_log_debug("setting port count to %d\n",descriptor->ports_count);
    135153        hub_info->port_count = descriptor->ports_count;
    136154        hub_info->attached_devs = (usb_hc_attached_device_t*)
     
    141159                hub_info->attached_devs[i].address=0;
    142160        }
     161        //handle non-removable devices
     162        usb_hub_trigger_connecting_non_removable_devices(hub_info, descriptor);
    143163        usb_log_debug2("freeing data\n");
    144164        free(serialized_descriptor);
     
    152172 * Check whether there is at least one configuration and sets the first one.
    153173 * This function should be run prior to running any hub-specific action.
    154  * @param hub_info
    155  * @return
     174 * @param hub_info hub representation
     175 * @return error code
    156176 */
    157177static int usb_hub_set_configuration(usb_hub_info_t * hub_info){
     
    159179        usb_standard_device_descriptor_t *std_descriptor
    160180            = &hub_info->usb_device->descriptors.device;
    161         usb_log_info("hub has %d configurations\n",
     181        usb_log_debug("hub has %d configurations\n",
    162182            std_descriptor->configuration_count);
    163183        if(std_descriptor->configuration_count<1){
     
    218238        }
    219239        //get port count and create attached_devs
    220         opResult = usb_hub_get_hub_specific_info(hub_info);
     240        opResult = usb_hub_process_hub_specific_info(hub_info);
    221241        if(opResult!=EOK){
    222242                usb_log_error("could not set hub configuration, errno %d\n",opResult);
     
    256276//*********************************************
    257277//
    258 //  hub driver code, main loop
     278//  hub driver code, main loop and port handling
    259279//
    260280//*********************************************
     281
     282/**
     283 * triggers actions to connect non0removable devices
     284 *
     285 * This will trigger operations leading to activated non-removable device.
     286 * Control pipe of the hub must be open fo communication.
     287 * @param hub hub representation
     288 * @param descriptor usb hub descriptor
     289 * @return error code
     290 */
     291static int usb_hub_trigger_connecting_non_removable_devices(usb_hub_info_t * hub,
     292                usb_hub_descriptor_t * descriptor)
     293{
     294        usb_log_info("attaching non-removable devices(if any)\n");
     295        usb_device_request_setup_packet_t request;
     296        int opResult;
     297        size_t rcvd_size;
     298        usb_port_status_t status;
     299        uint8_t * non_removable_dev_bitmap = descriptor->devices_removable;
     300        int port;
     301        for(port=1;port<=descriptor->ports_count;++port){
     302                bool is_non_removable =
     303                                ((non_removable_dev_bitmap[port/8]) >> (port%8)) %2;
     304                if(is_non_removable){
     305                        usb_log_debug("non-removable device on port %d\n",port);
     306                        usb_hub_set_port_status_request(&request, port);
     307                        opResult = usb_pipe_control_read(
     308                                        hub->control_pipe,
     309                                        &request, sizeof(usb_device_request_setup_packet_t),
     310                                        &status, 4, &rcvd_size
     311                                        );
     312                        if (opResult != EOK) {
     313                                usb_log_error("could not get port status of port %d errno:%d\n",
     314                                                port, opResult);
     315                                return opResult;
     316                        }
     317                        //set the status change bit, so it will be noticed in driver loop
     318                        if(usb_port_dev_connected(&status)){
     319                                usb_hub_set_enable_port_feature_request(&request, port,
     320                                                USB_HUB_FEATURE_C_PORT_CONNECTION);
     321                                opResult = usb_pipe_control_read(
     322                                                hub->control_pipe,
     323                                                &request, sizeof(usb_device_request_setup_packet_t),
     324                                                &status, 4, &rcvd_size
     325                                                );
     326                                if (opResult != EOK) {
     327                                        usb_log_warning(
     328                                                        "could not set port change on port %d errno:%d\n",
     329                                                        port, opResult);
     330                                }
     331                        }
     332                }
     333        }
     334        return EOK;
     335}
     336
    261337
    262338/**
     
    280356/**
    281357 * Reset the port with new device and reserve the default address.
    282  * @param hc
    283  * @param port
    284  * @param target
     358 * @param hub hub representation
     359 * @param port port number, starting from 1
     360 * @param speed transfer speed of attached device, one of low, full or high
    285361 */
    286362static void usb_hub_init_add_device(usb_hub_info_t * hub, uint16_t port,
     
    288364        //if this hub already uses default address, it cannot request it once more
    289365        if(hub->is_default_address_used) return;
    290         usb_log_info("some connection changed\n");
     366        usb_log_debug("some connection changed\n");
    291367        assert(hub->control_pipe->hc_phone);
    292368        int opResult = usb_hub_clear_port_feature(hub->control_pipe,
     
    315391        if (opResult != EOK) {
    316392                usb_log_error("something went wrong when reseting a port %d\n",opResult);
    317                 //usb_hub_release_default_address(hc);
    318393                usb_hub_release_default_address(hub);
    319394        }
     
    323398/**
    324399 * Finalize adding new device after port reset
    325  * @param hc
    326  * @param port
    327  * @param target
     400 *
     401 * Set device`s address and start it`s driver.
     402 * @param hub hub representation
     403 * @param port port number, starting from 1
     404 * @param speed transfer speed of attached device, one of low, full or high
    328405 */
    329406static void usb_hub_finalize_add_device( usb_hub_info_t * hub,
     
    331408
    332409        int opResult;
    333         usb_log_info("finalizing add device\n");
     410        usb_log_debug("finalizing add device\n");
    334411        opResult = usb_hub_clear_port_feature(hub->control_pipe,
    335412            port, USB_HUB_FEATURE_C_PORT_RESET);
     
    363440                return;
    364441        }
    365         usb_log_info("setting new address %d\n",new_device_address);
     442        usb_log_debug("setting new address %d\n",new_device_address);
    366443        //opResult = usb_drv_req_set_address(hc, USB_ADDRESS_DEFAULT,
    367444        //    new_device_address);
     
    375452        }
    376453
    377 
    378454        //opResult = usb_hub_release_default_address(hc);
    379455        opResult = usb_hub_release_default_address(hub);
     
    403479                return;
    404480        }
    405         usb_log_info("new device address %d, handle %zu\n",
     481        usb_log_info("Detected new device on `%s' (port %d), " \
     482            "address %d (handle %llu).\n",
     483            hub->usb_device->ddf_dev->name, (int) port,
    406484            new_device_address, child_handle);
    407 
    408 }
    409 
    410 /**
    411  * Unregister device address in hc
    412  * @param hc
    413  * @param port
    414  * @param target
     485}
     486
     487/**
     488 * routine called when a device on port has been removed
     489 *
     490 * If the device on port had default address, it releases default address.
     491 * Otherwise does not do anything, because DDF does not allow to remove device
     492 * from it`s device tree.
     493 * @param hub hub representation
     494 * @param port port number, starting from 1
    415495 */
    416496static void usb_hub_removed_device(
     
    451531 * Turn off the power on the port.
    452532 *
    453  * @param hub
    454  * @param port
     533 * @param hub hub representation
     534 * @param port port number, starting from 1
    455535 */
    456536static void usb_hub_over_current( usb_hub_info_t * hub,
     
    467547/**
    468548 * Process interrupts on given hub port
    469  * @param hc
    470  * @param port
    471  * @param target
     549 *
     550 * Accepts connection, over current and port reset change.
     551 * @param hub hub representation
     552 * @param port port number, starting from 1
    472553 */
    473554static void usb_hub_process_interrupt(usb_hub_info_t * hub,
     
    502583        if (usb_port_connect_change(&status)) {
    503584                if (usb_port_dev_connected(&status)) {
    504                         usb_log_info("some connection changed\n");
     585                        usb_log_debug("some connection changed\n");
    505586                        usb_hub_init_add_device(hub, port, usb_port_speed(&status));
    506587                } else {
     
    514595                        usb_hub_over_current(hub,port);
    515596                }else{
    516                         usb_log_info("over current condition was auto-resolved on port %d\n",
     597                        usb_log_debug("over current condition was auto-resolved on port %d\n",
    517598                                        port);
    518599                }
     
    520601        //port reset
    521602        if (usb_port_reset_completed(&status)) {
    522                 usb_log_info("port reset complete\n");
     603                usb_log_debug("port reset complete\n");
    523604                if (usb_port_enabled(&status)) {
    524605                        usb_hub_finalize_add_device(hub, port, usb_port_speed(&status));
     
    540621
    541622/**
    542  * Check changes on particular hub
    543  * @param hub_info_param pointer to usb_hub_info_t structure
    544  * @return error code if there is problem when initializing communication with
    545  * hub, EOK otherwise
     623 * check changes on hub
     624 *
     625 * Handles changes on each port with a status change.
     626 * @param hub_info hub representation
     627 * @return error code
    546628 */
    547629int usb_hub_check_hub_changes(usb_hub_info_t * hub_info){
Note: See TracChangeset for help on using the changeset viewer.