Changeset e50cd7f in mainline for uspace/drv/usbhub/usbhub.c


Ignore:
Timestamp:
2011-04-17T19:17:55Z (14 years ago)
Author:
Matej Klonfar <maklf@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
63517c2, cfbbe1d3
Parents:
ef354b6 (diff), 8595577b (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

new report structure fixes

File:
1 edited

Legend:

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

    ref354b6 re50cd7f  
    3737#include <errno.h>
    3838#include <str_error.h>
     39#include <inttypes.h>
    3940
    4041#include <usb_iface.h>
     
    4445#include <usb/request.h>
    4546#include <usb/classes/hub.h>
     47#include <usb/devpoll.h>
    4648#include <stdio.h>
    4749
     
    5355#include "usb/classes/classes.h"
    5456
    55 static int usb_hub_trigger_connecting_non_removable_devices(
    56                 usb_hub_info_t * hub, usb_hub_descriptor_t * descriptor);
    57 
     57
     58static usb_hub_info_t * usb_hub_info_create(usb_device_t * usb_dev);
     59
     60static int usb_hub_process_hub_specific_info(usb_hub_info_t * hub_info);
     61
     62static int usb_hub_set_configuration(usb_hub_info_t * hub_info);
     63
     64static int usb_hub_start_hub_fibril(usb_hub_info_t * hub_info);
     65
     66static int usb_process_hub_over_current(usb_hub_info_t * hub_info,
     67    usb_hub_status_t status);
     68
     69static int usb_process_hub_power_change(usb_hub_info_t * hub_info,
     70    usb_hub_status_t status);
     71
     72static void usb_hub_process_global_interrupt(usb_hub_info_t * hub_info);
     73
     74
     75/// \TODO malloc checking
    5876
    5977//*********************************************
    6078//
    6179//  hub driver code, initialization
     80//
     81//*********************************************
     82
     83/**
     84 * Initialize hub device driver fibril
     85 *
     86 * Creates hub representation and fibril that periodically checks hub`s status.
     87 * Hub representation is passed to the fibril.
     88 * @param usb_dev generic usb device information
     89 * @return error code
     90 */
     91int usb_hub_add_device(usb_device_t * usb_dev) {
     92        if (!usb_dev) return EINVAL;
     93        usb_hub_info_t * hub_info = usb_hub_info_create(usb_dev);
     94        //create hc connection
     95        usb_log_debug("Initializing USB wire abstraction.\n");
     96        int opResult = usb_hc_connection_initialize_from_device(
     97            &hub_info->connection,
     98            hub_info->usb_device->ddf_dev);
     99        if (opResult != EOK) {
     100                usb_log_error("could not initialize connection to device, "
     101                    "errno %d\n",
     102                    opResult);
     103                free(hub_info);
     104                return opResult;
     105        }
     106
     107        //usb_pipe_start_session(hub_info->control_pipe);
     108        //set hub configuration
     109        opResult = usb_hub_set_configuration(hub_info);
     110        if (opResult != EOK) {
     111                usb_log_error("could not set hub configuration, errno %d\n",
     112                    opResult);
     113                free(hub_info);
     114                return opResult;
     115        }
     116        //get port count and create attached_devs
     117        opResult = usb_hub_process_hub_specific_info(hub_info);
     118        if (opResult != EOK) {
     119                usb_log_error("could process hub specific info, errno %d\n",
     120                    opResult);
     121                free(hub_info);
     122                return opResult;
     123        }
     124        //usb_pipe_end_session(hub_info->control_pipe);
     125
     126
     127        usb_log_debug("Creating 'hub' function in DDF.\n");
     128        ddf_fun_t *hub_fun = ddf_fun_create(hub_info->usb_device->ddf_dev,
     129            fun_exposed, "hub");
     130        assert(hub_fun != NULL);
     131        hub_fun->ops = NULL;
     132
     133        opResult = ddf_fun_bind(hub_fun);
     134        assert(opResult == EOK);
     135        opResult = ddf_fun_add_to_class(hub_fun, "hub");
     136        assert(opResult == EOK);
     137
     138        opResult = usb_hub_start_hub_fibril(hub_info);
     139        if(opResult!=EOK)
     140                free(hub_info);
     141        return opResult;
     142}
     143
     144
     145/** Callback for polling hub for changes.
     146 *
     147 * @param dev Device where the change occured.
     148 * @param change_bitmap Bitmap of changed ports.
     149 * @param change_bitmap_size Size of the bitmap in bytes.
     150 * @param arg Custom argument, points to @c usb_hub_info_t.
     151 * @return Whether to continue polling.
     152 */
     153bool hub_port_changes_callback(usb_device_t *dev,
     154    uint8_t *change_bitmap, size_t change_bitmap_size, void *arg) {
     155        usb_log_debug("hub_port_changes_callback\n");
     156        usb_hub_info_t *hub = (usb_hub_info_t *) arg;
     157
     158        /* FIXME: check that we received enough bytes. */
     159        if (change_bitmap_size == 0) {
     160                goto leave;
     161        }
     162
     163        bool change;
     164        change = ((uint8_t*) change_bitmap)[0] & 1;
     165        if (change) {
     166                usb_hub_process_global_interrupt(hub);
     167        }
     168
     169        size_t port;
     170        for (port = 1; port < hub->port_count + 1; port++) {
     171                bool change = (change_bitmap[port / 8] >> (port % 8)) % 2;
     172                if (change) {
     173                        usb_hub_process_interrupt(hub, port);
     174                }
     175        }
     176leave:
     177        /* FIXME: proper interval. */
     178        async_usleep(1000 * 1000 * 10);
     179
     180        return true;
     181}
     182
     183
     184//*********************************************
     185//
     186//  support functions
    62187//
    63188//*********************************************
     
    71196 */
    72197static usb_hub_info_t * usb_hub_info_create(usb_device_t * usb_dev) {
    73         usb_hub_info_t * result = usb_new(usb_hub_info_t);
    74         if(!result) return NULL;
     198        usb_hub_info_t * result = malloc(sizeof(usb_hub_info_t));
     199        if (!result) return NULL;
    75200        result->usb_device = usb_dev;
    76201        result->status_change_pipe = usb_dev->pipes[0].pipe;
     
    90215 * @return error code
    91216 */
    92 static int usb_hub_process_hub_specific_info(usb_hub_info_t * hub_info){
     217static int usb_hub_process_hub_specific_info(usb_hub_info_t * hub_info) {
    93218        // get hub descriptor
    94219        usb_log_debug("creating serialized descriptor\n");
    95         void * serialized_descriptor = malloc(USB_HUB_MAX_DESCRIPTOR_SIZE);
     220        //void * serialized_descriptor = malloc(USB_HUB_MAX_DESCRIPTOR_SIZE);
     221        uint8_t serialized_descriptor[USB_HUB_MAX_DESCRIPTOR_SIZE];
    96222        usb_hub_descriptor_t * descriptor;
    97 
    98         /* this was one fix of some bug, should not be needed anymore
    99          * these lines allow to reset hub once more, it can be used as
    100          * brute-force initialization for non-removable devices
    101         int opResult = usb_request_set_configuration(&result->endpoints.control, 1);
    102         if(opResult!=EOK){
    103                 usb_log_error("could not set default configuration, errno %d",opResult);
    104                 return opResult;
    105         }
    106          */
     223        int opResult;
     224
    107225        size_t received_size;
    108         int opResult = usb_request_get_descriptor(&hub_info->usb_device->ctrl_pipe,
    109                         USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_DEVICE,
    110                         USB_DESCTYPE_HUB,
    111                         0, 0, serialized_descriptor,
    112                         USB_HUB_MAX_DESCRIPTOR_SIZE, &received_size);
    113 
    114         if (opResult != EOK) {
    115                 usb_log_error("failed when receiving hub descriptor, badcode = %d\n",
    116                                 opResult);
     226        opResult = usb_request_get_descriptor(hub_info->control_pipe,
     227            USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_DEVICE,
     228            USB_DESCTYPE_HUB, 0, 0, serialized_descriptor,
     229            USB_HUB_MAX_DESCRIPTOR_SIZE, &received_size);
     230
     231        if (opResult != EOK) {
     232                usb_log_error("failed when receiving hub descriptor, "
     233                    "badcode = %d\n",
     234                    opResult);
    117235                free(serialized_descriptor);
    118236                return opResult;
    119237        }
    120238        usb_log_debug2("deserializing descriptor\n");
    121         descriptor = usb_deserialize_hub_desriptor(serialized_descriptor);
    122         if(descriptor==NULL){
     239        descriptor = usb_create_deserialized_hub_desriptor(
     240            serialized_descriptor);
     241        if (descriptor == NULL) {
    123242                usb_log_warning("could not deserialize descriptor \n");
    124                 return opResult;
    125         }
    126         usb_log_debug("setting port count to %d\n",descriptor->ports_count);
     243                return ENOMEM;
     244        }
     245        usb_log_debug("setting port count to %d\n", descriptor->ports_count);
    127246        hub_info->port_count = descriptor->ports_count;
    128         hub_info->ports = malloc(sizeof(usb_hub_port_t) * (hub_info->port_count+1));
     247        /// \TODO this is not semantically correct
     248        bool is_power_switched =
     249            ((descriptor->hub_characteristics & 1) ==0);
     250        bool has_individual_port_powering =
     251            ((descriptor->hub_characteristics & 1) !=0);
     252        hub_info->ports = malloc(
     253            sizeof (usb_hub_port_t) * (hub_info->port_count + 1));
    129254        size_t port;
    130255        for (port = 0; port < hub_info->port_count + 1; port++) {
    131256                usb_hub_port_init(&hub_info->ports[port]);
    132257        }
    133         //handle non-removable devices
    134         usb_hub_trigger_connecting_non_removable_devices(hub_info, descriptor);
     258        if(is_power_switched){
     259                usb_log_debug("is_power_switched\n");
     260                if(has_individual_port_powering){
     261                        usb_log_debug("has_individual_port_powering\n");
     262                        for (port = 0; port < hub_info->port_count; port++) {
     263                                opResult = usb_hub_set_port_feature(hub_info->control_pipe,
     264                                    port+1, USB_HUB_FEATURE_PORT_POWER);
     265                                if (opResult != EOK) {
     266                                        usb_log_error("cannot power on port %d;  %d\n",
     267                                            port+1, opResult);
     268                                }
     269                        }
     270                }else{
     271                        usb_log_debug("!has_individual_port_powering\n");
     272                        opResult = usb_hub_set_feature(hub_info->control_pipe,
     273                            USB_HUB_FEATURE_C_HUB_LOCAL_POWER);
     274                        if (opResult != EOK) {
     275                                usb_log_error("cannot power hub;  %d\n",
     276                                  opResult);
     277                        }
     278                }
     279        }else{
     280                usb_log_debug("!is_power_switched\n");
     281        }
    135282        usb_log_debug2("freeing data\n");
    136         free(serialized_descriptor);
    137         free(descriptor->devices_removable);
     283        //free(serialized_descriptor);
     284        //free(descriptor->devices_removable);
    138285        free(descriptor);
    139286        return EOK;
    140287}
     288
    141289/**
    142290 * Set configuration of hub
     
    147295 * @return error code
    148296 */
    149 static int usb_hub_set_configuration(usb_hub_info_t * hub_info){
     297static int usb_hub_set_configuration(usb_hub_info_t * hub_info) {
    150298        //device descriptor
    151299        usb_standard_device_descriptor_t *std_descriptor
     
    153301        usb_log_debug("hub has %d configurations\n",
    154302            std_descriptor->configuration_count);
    155         if(std_descriptor->configuration_count<1){
     303        if (std_descriptor->configuration_count < 1) {
    156304                usb_log_error("there are no configurations available\n");
    157305                return EINVAL;
     
    173321        }
    174322        usb_log_debug("\tused configuration %d\n",
    175                         config_descriptor->configuration_number);
     323            config_descriptor->configuration_number);
    176324
    177325        return EOK;
     
    179327
    180328/**
    181  * Initialize hub device driver fibril
    182  *
    183  * Creates hub representation and fibril that periodically checks hub`s status.
    184  * Hub representation is passed to the fibril.
    185  * @param usb_dev generic usb device information
    186  * @return error code
    187  */
    188 int usb_hub_add_device(usb_device_t * usb_dev){
    189         if(!usb_dev) return EINVAL;
    190         usb_hub_info_t * hub_info = usb_hub_info_create(usb_dev);
    191         //create hc connection
    192         usb_log_debug("Initializing USB wire abstraction.\n");
    193         int opResult = usb_hc_connection_initialize_from_device(
    194                         &hub_info->connection,
    195                         hub_info->usb_device->ddf_dev);
    196         if(opResult != EOK){
    197                 usb_log_error("could not initialize connection to device, errno %d\n",
    198                                 opResult);
    199                 free(hub_info);
    200                 return opResult;
    201         }
    202        
    203         usb_pipe_start_session(hub_info->control_pipe);
    204         //set hub configuration
    205         opResult = usb_hub_set_configuration(hub_info);
    206         if(opResult!=EOK){
    207                 usb_log_error("could not set hub configuration, errno %d\n",opResult);
    208                 free(hub_info);
    209                 return opResult;
    210         }
    211         //get port count and create attached_devs
    212         opResult = usb_hub_process_hub_specific_info(hub_info);
    213         if(opResult!=EOK){
    214                 usb_log_error("could not set hub configuration, errno %d\n",opResult);
    215                 free(hub_info);
    216                 return opResult;
    217         }
    218         usb_pipe_end_session(hub_info->control_pipe);
    219 
    220 
    221         /// \TODO what is this?
    222         usb_log_debug("Creating `hub' function.\n");
    223         ddf_fun_t *hub_fun = ddf_fun_create(hub_info->usb_device->ddf_dev,
    224                         fun_exposed, "hub");
    225         assert(hub_fun != NULL);
    226         hub_fun->ops = NULL;
    227 
    228         int rc = ddf_fun_bind(hub_fun);
    229         assert(rc == EOK);
    230         rc = ddf_fun_add_to_class(hub_fun, "hub");
    231         assert(rc == EOK);
    232 
     329 * create and start fibril with hub control loop
     330 *
     331 * Before the fibril is started, the control pipe and host controller
     332 * connection of the hub is open.
     333 *
     334 * @param hub_info hub representing structure
     335 * @return error code
     336 */
     337static int usb_hub_start_hub_fibril(usb_hub_info_t * hub_info){
    233338        /*
    234339         * The processing will require opened control pipe and connection
     
    239344         * auto destruction, this could work better.
    240345         */
    241         rc = usb_pipe_start_session(&usb_dev->ctrl_pipe);
     346        int rc = usb_hc_connection_open(&hub_info->connection);
    242347        if (rc != EOK) {
    243                 usb_log_error("Failed to start session on control pipe: %s.\n",
    244                     str_error(rc));
    245                 goto leave;
    246         }
    247         rc = usb_hc_connection_open(&hub_info->connection);
    248         if (rc != EOK) {
    249                 usb_pipe_end_session(&usb_dev->ctrl_pipe);
     348                //usb_pipe_end_session(hub_info->control_pipe);
    250349                usb_log_error("Failed to open connection to HC: %s.\n",
    251350                    str_error(rc));
    252                 goto leave;
     351                return rc;
    253352        }
    254353
    255354        rc = usb_device_auto_poll(hub_info->usb_device, 0,
    256             hub_port_changes_callback, ((hub_info->port_count+1) / 8) + 1,
     355            hub_port_changes_callback, ((hub_info->port_count + 1) / 8) + 1,
    257356            NULL, hub_info);
    258357        if (rc != EOK) {
     
    266365            hub_info->usb_device->ddf_dev->name, hub_info->port_count);
    267366        return EOK;
    268 
    269 leave:
    270         free(hub_info);
    271 
    272         return rc;
    273 }
    274 
    275 
    276 //*********************************************
    277 //
    278 //  hub driver code, main loop and port handling
    279 //
    280 //*********************************************
    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  */
    291 static 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");
     367}
     368
     369//*********************************************
     370//
     371//  change handling functions
     372//
     373//*********************************************
     374
     375
     376/**
     377 * process hub over current change
     378 *
     379 * This means either to power off the hub or power it on.
     380 * @param hub_info hub instance
     381 * @param status hub status bitmask
     382 * @return error code
     383 */
     384static int usb_process_hub_over_current(usb_hub_info_t * hub_info,
     385    usb_hub_status_t status) {
     386        int opResult;
     387        if (usb_hub_is_status(status,USB_HUB_FEATURE_HUB_OVER_CURRENT)){
     388                opResult = usb_hub_clear_feature(hub_info->control_pipe,
     389                    USB_HUB_FEATURE_HUB_LOCAL_POWER);
     390                if (opResult != EOK) {
     391                        usb_log_error("cannot power off hub: %d\n",
     392                            opResult);
     393                }
     394        } else {
     395                opResult = usb_hub_set_feature(hub_info->control_pipe,
     396                    USB_HUB_FEATURE_HUB_LOCAL_POWER);
     397                if (opResult != EOK) {
     398                        usb_log_error("cannot power on hub: %d\n",
     399                            opResult);
     400                }
     401        }
     402        return opResult;
     403}
     404
     405/**
     406 * process hub power change
     407 *
     408 * If the power has been lost, reestablish it.
     409 * If it was reestablished, re-power all ports.
     410 * @param hub_info hub instance
     411 * @param status hub status bitmask
     412 * @return error code
     413 */
     414static int usb_process_hub_power_change(usb_hub_info_t * hub_info,
     415    usb_hub_status_t status) {
     416        int opResult;
     417        if (usb_hub_is_status(status,USB_HUB_FEATURE_HUB_LOCAL_POWER)) {
     418                //restart power on hub
     419                opResult = usb_hub_set_feature(hub_info->control_pipe,
     420                    USB_HUB_FEATURE_HUB_LOCAL_POWER);
     421                if (opResult != EOK) {
     422                        usb_log_error("cannot power on hub: %d\n",
     423                            opResult);
     424                }
     425        } else {//power reestablished on hub- restart ports
     426                size_t port;
     427                for (port = 0; port < hub_info->port_count; ++port) {
     428                        opResult = usb_hub_set_port_feature(
     429                            hub_info->control_pipe,
     430                            port, USB_HUB_FEATURE_PORT_POWER);
     431                        if (opResult != EOK) {
     432                                usb_log_error("cannot power on port %d;  %d\n",
     433                                    port, opResult);
     434                        }
     435                }
     436        }
     437        return opResult;
     438}
     439
     440/**
     441 * process hub interrupts
     442 *
     443 * The change can be either in the over-current condition or
     444 * local-power lost condition.
     445 * @param hub_info hub instance
     446 */
     447static void usb_hub_process_global_interrupt(usb_hub_info_t * hub_info) {
     448        usb_log_debug("global interrupt on a hub\n");
     449        usb_pipe_t *pipe = hub_info->control_pipe;
     450        int opResult;
     451
     452        usb_port_status_t status;
     453        size_t rcvd_size;
    295454        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_disable_port_feature_request(&request, port,
    320                                                 USB_HUB_FEATURE_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 clear port connection on port %d errno:%d\n",
    329                                                         port, opResult);
    330                                 }
    331                                 usb_log_debug("cleared port connection\n");
    332                                 usb_hub_set_enable_port_feature_request(&request, port,
    333                                                 USB_HUB_FEATURE_PORT_ENABLE);
    334                                 opResult = usb_pipe_control_read(
    335                                                 hub->control_pipe,
    336                                                 &request, sizeof(usb_device_request_setup_packet_t),
    337                                                 &status, 4, &rcvd_size
    338                                                 );
    339                                 if (opResult != EOK) {
    340                                         usb_log_warning(
    341                                                         "could not set port enabled on port %d errno:%d\n",
    342                                                         port, opResult);
    343                                 }
    344                                 usb_log_debug("port set to enabled - should lead to connection change\n");
    345                         }
    346                 }
    347         }
    348         /// \TODO this is just a debug code
    349         for(port=1;port<=descriptor->ports_count;++port){
    350                 bool is_non_removable =
    351                                 ((non_removable_dev_bitmap[port/8]) >> (port%8)) %2;
    352                 if(is_non_removable){
    353                         usb_log_debug("port %d is non-removable\n",port);
    354                         usb_port_status_t status;
    355                         size_t rcvd_size;
    356                         usb_device_request_setup_packet_t request;
    357                         //int opResult;
    358                         usb_hub_set_port_status_request(&request, port);
    359                         //endpoint 0
    360                         opResult = usb_pipe_control_read(
    361                                         hub->control_pipe,
    362                                         &request, sizeof(usb_device_request_setup_packet_t),
    363                                         &status, 4, &rcvd_size
    364                                         );
    365                         if (opResult != EOK) {
    366                                 usb_log_error("could not get port status %d\n",opResult);
    367                         }
    368                         if (rcvd_size != sizeof (usb_port_status_t)) {
    369                                 usb_log_error("received status has incorrect size\n");
    370                         }
    371                         //something connected/disconnected
    372                         if (usb_port_connect_change(&status)) {
    373                                 usb_log_debug("some connection changed\n");
    374                         }
    375                         usb_log_debug("status: %s\n",usb_debug_str_buffer(
    376                                         (uint8_t *)&status,4,4));
    377                 }
    378         }
    379         return EOK;
    380 }
    381 
    382 
    383 /**
    384  * release default address used by given hub
    385  *
    386  * Also unsets hub->is_default_address_used. Convenience wrapper function.
    387  * @note hub->connection MUST be open for communication
    388  * @param hub hub representation
    389  * @return error code
    390  */
    391 static int usb_hub_release_default_address(usb_hub_info_t * hub){
    392         int opResult = usb_hc_release_default_address(&hub->connection);
    393         if(opResult!=EOK){
    394                 usb_log_error("could not release default address, errno %d\n",opResult);
    395                 return opResult;
    396         }
    397         hub->is_default_address_used = false;
    398         return EOK;
    399 }
    400 
    401 /**
    402  * routine called when a device on port has been removed
    403  *
    404  * If the device on port had default address, it releases default address.
    405  * Otherwise does not do anything, because DDF does not allow to remove device
    406  * from it`s device tree.
    407  * @param hub hub representation
    408  * @param port port number, starting from 1
    409  */
    410 void usb_hub_removed_device(
    411     usb_hub_info_t * hub,uint16_t port) {
    412 
    413         int opResult = usb_hub_clear_port_feature(hub->control_pipe,
    414                                 port, USB_HUB_FEATURE_C_PORT_CONNECTION);
    415         if(opResult != EOK){
    416                 usb_log_warning("could not clear port-change-connection flag\n");
    417         }
    418         /** \TODO remove device from device manager - not yet implemented in
    419          * devide manager
    420          */
    421        
    422         //close address
    423         if(hub->ports[port].attached_device.address >= 0){
    424                 /*uncomment this code to use it when DDF allows device removal
    425                 opResult = usb_hc_unregister_device(
    426                                 &hub->connection, hub->attached_devs[port].address);
    427                 if(opResult != EOK) {
    428                         dprintf(USB_LOG_LEVEL_WARNING, "could not release address of " \
    429                             "removed device: %d", opResult);
    430                 }
    431                 hub->attached_devs[port].address = 0;
    432                 hub->attached_devs[port].handle = 0;
    433                  */
    434         }else{
    435                 usb_log_warning("this is strange, disconnected device had no address\n");
    436                 //device was disconnected before it`s port was reset - return default address
    437                 usb_hub_release_default_address(hub);
    438         }
    439 }
    440 
    441 
    442 /**
    443  * Process over current condition on port.
    444  *
    445  * Turn off the power on the port.
    446  *
    447  * @param hub hub representation
    448  * @param port port number, starting from 1
    449  */
    450 void usb_hub_over_current( usb_hub_info_t * hub,
    451                 uint16_t port){
    452         int opResult;
    453         opResult = usb_hub_clear_port_feature(hub->control_pipe,
    454             port, USB_HUB_FEATURE_PORT_POWER);
    455         if(opResult!=EOK){
    456                 usb_log_error("cannot power off port %d;  %d\n",
    457                                 port, opResult);
    458         }
    459 }
    460 
     455        //int opResult;
     456        usb_hub_set_hub_status_request(&request);
     457        //endpoint 0
     458
     459        opResult = usb_pipe_control_read(
     460            pipe,
     461            &request, sizeof (usb_device_request_setup_packet_t),
     462            &status, 4, &rcvd_size
     463            );
     464        if (opResult != EOK) {
     465                usb_log_error("could not get hub status\n");
     466                return;
     467        }
     468        if (rcvd_size != sizeof (usb_port_status_t)) {
     469                usb_log_error("received status has incorrect size\n");
     470                return;
     471        }
     472        //port reset
     473        if (
     474            usb_hub_is_status(status,16+USB_HUB_FEATURE_C_HUB_OVER_CURRENT)) {
     475                usb_process_hub_over_current(hub_info, status);
     476        }
     477        if (
     478            usb_hub_is_status(status,16+USB_HUB_FEATURE_C_HUB_LOCAL_POWER)) {
     479                usb_process_hub_power_change(hub_info, status);
     480        }
     481}
    461482
    462483/**
Note: See TracChangeset for help on using the changeset viewer.