Ignore:
File:
1 edited

Legend:

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

    rdff940f8 r15b0432  
    3333 */
    3434
    35 #include <ddf/driver.h>
     35#include <driver.h>
    3636#include <bool.h>
    3737#include <errno.h>
     
    4444#include <usb/request.h>
    4545#include <usb/classes/hub.h>
    46 #include <stdio.h>
    4746
    4847#include "usbhub.h"
     
    5352#include "usb/classes/classes.h"
    5453
    55 static ddf_dev_ops_t hub_device_ops = {
     54static device_ops_t hub_device_ops = {
    5655        .interfaces[USB_DEV_IFACE] = &usb_iface_hub_impl
    5756};
    5857
    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 */
    6359static usb_endpoint_description_t status_change_endpoint_description = {
    6460        .transfer_type = USB_TRANSFER_INTERRUPT,
    6561        .direction = USB_DIRECTION_IN,
    6662        .interface_class = USB_CLASS_HUB,
    67         .interface_subclass = 0,
    68         .interface_protocol = 0,
    6963        .flags = 0
    7064};
    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 }
    8065
    8166
     
    9479 */
    9580static 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);
    9781        int opResult;
    9882        opResult = usb_device_connection_initialize_from_device(
     
    10488                return opResult;
    10589        }
    106         usb_log_debug("Initializing USB wire abstraction.\n");
    10790        opResult = usb_hc_connection_initialize_from_device(&hub->connection,
    10891                        hub->device);
     
    11295                return opResult;
    11396        }
    114         usb_log_debug("Initializing default control pipe.\n");
    11597        opResult = usb_endpoint_pipe_initialize_default_control(&hub->endpoints.control,
    11698            &hub->device_connection);
     
    150132
    151133        //configuration descriptor
    152         /// \TODO check other configurations?
     134        /// \TODO check other configurations
    153135        usb_standard_configuration_descriptor_t config_descriptor;
    154136        opResult = usb_request_get_bare_configuration_descriptor(
     
    194176        }
    195177
     178        /**
     179         * Initialize the interrupt in endpoint.
     180         * \TODO this code should be checked...
     181         */
    196182        usb_endpoint_mapping_t endpoint_mapping[1] = {
    197183                {
     
    221207        return EOK;
    222208       
     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
    223216}
    224217
     
    229222 * @return pointer to created structure or NULL in case of error
    230223 */
    231 usb_hub_info_t * usb_create_hub_info(ddf_dev_t * device) {
     224usb_hub_info_t * usb_create_hub_info(device_t * device) {
    232225        usb_hub_info_t* result = usb_new(usb_hub_info_t);
    233226        result->device = device;
     
    271264        }
    272265
     266       
    273267        dprintf(USB_LOG_LEVEL_INFO, "setting port count to %d",descriptor->ports_count);
    274268        result->port_count = descriptor->ports_count;
     
    297291 * @return
    298292 */
    299 int usb_add_hub_device(ddf_dev_t *dev) {
     293int usb_add_hub_device(device_t *dev) {
    300294        dprintf(USB_LOG_LEVEL_INFO, "add_hub_device(handle=%d)", (int) dev->handle);
    301295
    302         //dev->ops = &hub_device_ops;
    303         (void) hub_device_ops;
     296        dev->ops = &hub_device_ops;
    304297
    305298        usb_hub_info_t * hub_info = usb_create_hub_info(dev);
     
    332325
    333326        //add the hub to list
    334         //is this needed now?
    335327        fibril_mutex_lock(&usb_hub_list_lock);
    336328        usb_lst_append(&usb_hub_list, hub_info);
    337329        fibril_mutex_unlock(&usb_hub_list_lock);
     330
    338331        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");
    359332        //(void)hub_info;
    360         //usb_hub_check_hub_changes();
     333        usb_hub_check_hub_changes();
    361334       
    362335        dprintf(USB_LOG_LEVEL_INFO, "hub dev added");
     
    391364        //opResult = usb_drv_reserve_default_address(hc);
    392365        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");
    397369                return;
    398370        }
     
    405377                        );
    406378        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");
    409380                //usb_hub_release_default_address(hc);
    410381                usb_hc_release_default_address(&hub->connection);
     
    419390 */
    420391static void usb_hub_finalize_add_device( usb_hub_info_t * hub,
    421                 uint16_t port, bool isLowSpeed) {
     392                uint16_t port) {
    422393
    423394        int opResult;
     
    442413                        &new_device_connection);
    443414        /// \TODO get highspeed info
    444         usb_speed_t speed = isLowSpeed?USB_SPEED_LOW:USB_SPEED_FULL;
     415
     416
     417
    445418
    446419
     
    448421        usb_address_t new_device_address = usb_hc_request_address(
    449422                        &hub->connection,
    450                         speed/// \TODO fullspeed??
     423                        USB_SPEED_LOW/// \TODO fullspeed??
    451424                        );
    452425        if (new_device_address < 0) {
     
    459432        //opResult = usb_drv_req_set_address(hc, USB_ADDRESS_DEFAULT,
    460433        //    new_device_address);
    461         usb_endpoint_pipe_start_session(&new_device_pipe);
    462434        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");
    467438                usb_hc_release_default_address(&hub->connection);
    468439                return;
     
    479450        //??
    480451    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");
    487456                return;
    488457        }
     
    495464                        &hub->attached_devs[port]);
    496465        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");
    499467                return;
    500468        }
     
    538506}
    539507
    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 
    560508/**
    561509 * Process interrupts on given hub port
     
    569517        //determine type of change
    570518        usb_endpoint_pipe_t *pipe = &hub->endpoints.control;
     519        int opResult = usb_endpoint_pipe_start_session(pipe);
    571520       
    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        */
    573530
    574531        usb_port_status_t status;
     
    585542                        );
    586543        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");
    588545                return;
    589546        }
    590547        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");
    592549                return;
    593550        }
     
    604561                }
    605562        }
    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         }
    616563        //port reset
    617564        if (usb_port_reset_completed(&status)) {
    618565                dprintf(USB_LOG_LEVEL_INFO, "port reset complete");
    619566                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);
    621568                } 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");
    623570                }
    624571        }
     
    633580        }
    634581        /// \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 */
     591void 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
    654631                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);
    666660                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
    702670
    703671
Note: See TracChangeset for help on using the changeset viewer.