Changes in / [a82889e:a4e18e1] in mainline


Ignore:
Location:
uspace/drv
Files:
2 added
2 deleted
6 edited

Legend:

Unmodified
Added
Removed
  • TabularUnified uspace/drv/ohci/root_hub.c

    ra82889e ra4e18e1  
    4747 *      standart device descriptor for ohci root hub
    4848 */
    49 static const usb_standard_device_descriptor_t ohci_rh_device_descriptor =
    50 {
    51                 .configuration_count = 1,
    52                 .descriptor_type = USB_DESCTYPE_DEVICE,
    53                 .device_class = USB_CLASS_HUB,
    54                 .device_protocol = 0,
    55                 .device_subclass = 0,
    56                 .device_version = 0,
    57                 .length = sizeof(usb_standard_device_descriptor_t),
    58                 /// \TODO this value is guessed
    59                 .max_packet_size = 8,
    60                 .vendor_id = 0x16db,
    61                 .product_id = 0x0001,
    62                 /// \TODO these values migt be different
    63                 .str_serial_number = 0,
    64                 .usb_spec_version = 0x110,
     49static const usb_standard_device_descriptor_t ohci_rh_device_descriptor = {
     50        .configuration_count = 1,
     51        .descriptor_type = USB_DESCTYPE_DEVICE,
     52        .device_class = USB_CLASS_HUB,
     53        .device_protocol = 0,
     54        .device_subclass = 0,
     55        .device_version = 0,
     56        .length = sizeof (usb_standard_device_descriptor_t),
     57        /// \TODO this value is guessed
     58        .max_packet_size = 8,
     59        .vendor_id = 0x16db,
     60        .product_id = 0x0001,
     61        /// \TODO these values migt be different
     62        .str_serial_number = 0,
     63        .usb_spec_version = 0x110,
    6564};
    6665
     
    6968 * for ohci root hubs
    7069 */
    71 static const usb_standard_configuration_descriptor_t ohci_rh_conf_descriptor =
    72 {
     70static const usb_standard_configuration_descriptor_t ohci_rh_conf_descriptor = {
    7371        /// \TODO some values are default or guessed
    74         .attributes = 1<<7,
     72        .attributes = 1 << 7,
    7573        .configuration_number = 1,
    7674        .descriptor_type = USB_DESCTYPE_CONFIGURATION,
    7775        .interface_count = 1,
    78         .length = sizeof(usb_standard_configuration_descriptor_t),
     76        .length = sizeof (usb_standard_configuration_descriptor_t),
    7977        .max_power = 100,
    8078        .str_configuration = 0,
     
    8482 * standart ohci root hub interface descriptor
    8583 */
    86 static const usb_standard_interface_descriptor_t ohci_rh_iface_descriptor =
    87 {
     84static const usb_standard_interface_descriptor_t ohci_rh_iface_descriptor = {
    8885        .alternate_setting = 0,
    8986        .descriptor_type = USB_DESCTYPE_INTERFACE,
     
    9491        .interface_protocol = 0,
    9592        .interface_subclass = 0,
    96         .length = sizeof(usb_standard_interface_descriptor_t),
     93        .length = sizeof (usb_standard_interface_descriptor_t),
    9794        .str_interface = 0,
    9895};
     
    10198 * standart ohci root hub endpoint descriptor
    10299 */
    103 static const usb_standard_endpoint_descriptor_t ohci_rh_ep_descriptor =
    104 {
     100static const usb_standard_endpoint_descriptor_t ohci_rh_ep_descriptor = {
    105101        .attributes = USB_TRANSFER_INTERRUPT,
    106102        .descriptor_type = USB_DESCTYPE_ENDPOINT,
    107         .endpoint_address = 1 + (1<<7),
    108         .length = sizeof(usb_standard_endpoint_descriptor_t),
     103        .endpoint_address = 1 + (1 << 7),
     104        .length = sizeof (usb_standard_endpoint_descriptor_t),
    109105        .max_packet_size = 8,
    110106        .poll_interval = 255,
     
    112108
    113109static const uint32_t hub_clear_feature_valid_mask =
    114         (1 << USB_HUB_FEATURE_C_HUB_LOCAL_POWER) +
    115         (1 << USB_HUB_FEATURE_C_HUB_OVER_CURRENT);
     110        (1 << USB_HUB_FEATURE_C_HUB_LOCAL_POWER) |
     111(1 << USB_HUB_FEATURE_C_HUB_OVER_CURRENT);
    116112
    117113static const uint32_t hub_clear_feature_by_writing_one_mask =
     
    121117        (1 << USB_HUB_FEATURE_C_HUB_OVER_CURRENT);
    122118
    123        
     119
    124120static const uint32_t hub_set_feature_direct_mask =
    125121        (1 << USB_HUB_FEATURE_C_HUB_OVER_CURRENT);
    126122
    127123static const uint32_t port_set_feature_valid_mask =
    128         (1 << USB_HUB_FEATURE_PORT_ENABLE) +
    129         (1 << USB_HUB_FEATURE_PORT_SUSPEND) +
    130         (1 << USB_HUB_FEATURE_PORT_RESET) +
    131         (1 << USB_HUB_FEATURE_PORT_POWER);
     124        (1 << USB_HUB_FEATURE_PORT_ENABLE) |
     125(1 << USB_HUB_FEATURE_PORT_SUSPEND) |
     126(1 << USB_HUB_FEATURE_PORT_RESET) |
     127(1 << USB_HUB_FEATURE_PORT_POWER);
    132128
    133129static const uint32_t port_clear_feature_valid_mask =
    134         (1 << USB_HUB_FEATURE_PORT_CONNECTION) +
    135         (1 << USB_HUB_FEATURE_PORT_SUSPEND) +
    136         (1 << USB_HUB_FEATURE_PORT_OVER_CURRENT) +
    137         (1 << USB_HUB_FEATURE_PORT_POWER) +
    138         (1 << USB_HUB_FEATURE_C_PORT_CONNECTION) +
    139         (1 << USB_HUB_FEATURE_C_PORT_ENABLE) +
    140         (1 << USB_HUB_FEATURE_C_PORT_SUSPEND) +
    141         (1 << USB_HUB_FEATURE_C_PORT_OVER_CURRENT) +
    142         (1 << USB_HUB_FEATURE_C_PORT_RESET);
    143 //note that USB_HUB_FEATURE_PORT_POWER bit is translated into USB_HUB_FEATURE_PORT_LOW_SPEED
    144 
    145 
    146 
     130        (1 << USB_HUB_FEATURE_PORT_CONNECTION) |
     131(1 << USB_HUB_FEATURE_PORT_SUSPEND) |
     132(1 << USB_HUB_FEATURE_PORT_OVER_CURRENT) |
     133(1 << USB_HUB_FEATURE_PORT_POWER) |
     134(1 << USB_HUB_FEATURE_C_PORT_CONNECTION) |
     135(1 << USB_HUB_FEATURE_C_PORT_ENABLE) |
     136(1 << USB_HUB_FEATURE_C_PORT_SUSPEND) |
     137(1 << USB_HUB_FEATURE_C_PORT_OVER_CURRENT) |
     138(1 << USB_HUB_FEATURE_C_PORT_RESET);
     139//note that USB_HUB_FEATURE_PORT_POWER bit is translated into
     140//USB_HUB_FEATURE_PORT_LOW_SPEED
     141
     142static const uint32_t port_status_change_mask =
     143(1<< USB_HUB_FEATURE_C_PORT_CONNECTION) |
     144(1<< USB_HUB_FEATURE_C_PORT_ENABLE) |
     145(1<< USB_HUB_FEATURE_C_PORT_OVER_CURRENT) |
     146(1<< USB_HUB_FEATURE_C_PORT_RESET) |
     147(1<< USB_HUB_FEATURE_C_PORT_SUSPEND);
     148
     149
     150static void usb_create_serialized_hub_descriptor(rh_t *instance,
     151        uint8_t ** out_result,
     152        size_t * out_size);
     153
     154static void rh_init_descriptors(rh_t *instance);
     155
     156static int process_get_port_status_request(rh_t *instance, uint16_t port,
     157        usb_transfer_batch_t * request);
     158
     159static int process_get_hub_status_request(rh_t *instance,
     160        usb_transfer_batch_t * request);
     161
     162static int process_get_status_request(rh_t *instance,
     163        usb_transfer_batch_t * request);
     164
     165static void create_interrupt_mask(rh_t *instance, void ** buffer,
     166        size_t * buffer_size);
     167
     168static int process_get_descriptor_request(rh_t *instance,
     169        usb_transfer_batch_t *request);
     170
     171static int process_get_configuration_request(rh_t *instance,
     172        usb_transfer_batch_t *request);
     173
     174static int process_hub_feature_set_request(rh_t *instance, uint16_t feature);
     175
     176static int process_hub_feature_clear_request(rh_t *instance,
     177        uint16_t feature);
     178
     179static int process_port_feature_set_request(rh_t *instance,
     180        uint16_t feature, uint16_t port);
     181
     182static int process_port_feature_clear_request(rh_t *instance,
     183        uint16_t feature, uint16_t port);
     184
     185static int process_address_set_request(rh_t *instance,
     186        uint16_t address);
     187
     188static int process_request_with_output(rh_t *instance,
     189        usb_transfer_batch_t *request);
     190
     191static int process_request_with_input(rh_t *instance,
     192        usb_transfer_batch_t *request);
     193
     194static int process_request_without_data(rh_t *instance,
     195        usb_transfer_batch_t *request);
     196
     197static int process_ctrl_request(rh_t *instance, usb_transfer_batch_t *request);
     198
     199
     200
     201
     202
     203/** Root hub initialization
     204 * @return Error code.
     205 */
     206int rh_init(rh_t *instance, ddf_dev_t *dev, ohci_regs_t *regs) {
     207        assert(instance);
     208        //instance->address = -1;
     209        instance->registers = regs;
     210        instance->device = dev;
     211        instance->port_count = instance->registers->rh_desc_a & 0xff;
     212        rh_init_descriptors(instance);
     213        // set port power mode to no-power-switching
     214        instance->registers->rh_desc_a =
     215                instance->registers->rh_desc_a | (1<<9);
     216
     217        usb_log_info("OHCI root hub with %d ports.\n", instance->port_count);
     218
     219        //start generic usb hub driver
     220
     221        /* TODO: implement */
     222        return EOK;
     223}
     224/*----------------------------------------------------------------------------*/
     225
     226/**
     227 * process root hub request
     228 *
     229 * @param instance root hub instance
     230 * @param request structure containing both request and response information
     231 * @return error code
     232 */
     233int rh_request(rh_t *instance, usb_transfer_batch_t *request) {
     234        assert(instance);
     235        assert(request);
     236        int opResult;
     237        if (request->transfer_type == USB_TRANSFER_CONTROL) {
     238                usb_log_info("Root hub got CONTROL packet\n");
     239                opResult = process_ctrl_request(instance, request);
     240        } else if (request->transfer_type == USB_TRANSFER_INTERRUPT) {
     241                usb_log_info("Root hub got INTERRUPT packet\n");
     242                void * buffer;
     243                create_interrupt_mask(instance, &buffer,
     244                        &(request->transfered_size));
     245                memcpy(request->transport_buffer, buffer,
     246                        request->transfered_size);
     247                opResult = EOK;
     248        } else {
     249                opResult = EINVAL;
     250        }
     251        usb_transfer_batch_finish(request, opResult);
     252        return EOK;
     253}
     254
     255/*----------------------------------------------------------------------------*/
     256
     257
     258void rh_interrupt(rh_t *instance) {
     259        usb_log_info("Whoa whoa wait, I`m not supposed to receive any "
     260                "interrupts, am I?\n");
     261        /* TODO: implement? */
     262}
     263/*----------------------------------------------------------------------------*/
    147264
    148265/**
     
    157274 */
    158275static void usb_create_serialized_hub_descriptor(rh_t *instance,
    159                 uint8_t ** out_result,
    160                 size_t * out_size) {
     276        uint8_t ** out_result,
     277        size_t * out_size) {
    161278        //base size
    162279        size_t size = 7;
    163280        //variable size according to port count
    164281        size_t var_size = instance->port_count / 8 +
    165                         ((instance->port_count % 8 > 0) ? 1 : 0);
     282                ((instance->port_count % 8 > 0) ? 1 : 0);
    166283        size += 2 * var_size;
    167284        uint8_t * result = (uint8_t*) malloc(size);
    168         bzero(result,size);
     285        bzero(result, size);
    169286        //size
    170287        result[0] = size;
     
    174291        uint32_t hub_desc_reg = instance->registers->rh_desc_a;
    175292        result[3] =
    176                         ((hub_desc_reg >> 8) %2) +
    177                         (((hub_desc_reg >> 9) %2) << 1) +
    178                         (((hub_desc_reg >> 10) %2) << 2) +
    179                         (((hub_desc_reg >> 11) %2) << 3) +
    180                         (((hub_desc_reg >> 12) %2) << 4);
     293                ((hub_desc_reg >> 8) % 2) +
     294                (((hub_desc_reg >> 9) % 2) << 1) +
     295                (((hub_desc_reg >> 10) % 2) << 2) +
     296                (((hub_desc_reg >> 11) % 2) << 3) +
     297                (((hub_desc_reg >> 12) % 2) << 4);
    181298        result[4] = 0;
    182299        result[5] = /*descriptor->pwr_on_2_good_time*/ 50;
     
    185302        int port;
    186303        for (port = 1; port <= instance->port_count; ++port) {
    187                 result[7 + port/8] +=
    188                                 ((instance->registers->rh_desc_b >> port)%2) << (port%8);
     304                uint8_t is_non_removable =
     305                        instance->registers->rh_desc_b >> port % 2;
     306                result[7 + port / 8] +=
     307                        is_non_removable << (port % 8);
    189308        }
    190309        size_t i;
     
    195314        (*out_size) = size;
    196315}
    197 
     316/*----------------------------------------------------------------------------*/
    198317
    199318/** initialize hub descriptors
     
    203322 * @instance root hub instance
    204323 */
    205 static void rh_init_descriptors(rh_t *instance){
     324static void rh_init_descriptors(rh_t *instance) {
    206325        memcpy(&instance->descriptors.device, &ohci_rh_device_descriptor,
    207                 sizeof(ohci_rh_device_descriptor)
    208         );
     326                sizeof (ohci_rh_device_descriptor)
     327                );
    209328        usb_standard_configuration_descriptor_t descriptor;
    210         memcpy(&descriptor,&ohci_rh_conf_descriptor,
    211                         sizeof(ohci_rh_conf_descriptor));
     329        memcpy(&descriptor, &ohci_rh_conf_descriptor,
     330                sizeof (ohci_rh_conf_descriptor));
    212331        uint8_t * hub_descriptor;
    213332        size_t hub_desc_size;
    214333        usb_create_serialized_hub_descriptor(instance, &hub_descriptor,
    215                         &hub_desc_size);
     334                &hub_desc_size);
    216335
    217336        descriptor.total_length =
    218                         sizeof(usb_standard_configuration_descriptor_t)+
    219                         sizeof(usb_standard_endpoint_descriptor_t)+
    220                         sizeof(usb_standard_interface_descriptor_t)+
    221                         hub_desc_size;
    222        
     337                sizeof (usb_standard_configuration_descriptor_t) +
     338                sizeof (usb_standard_endpoint_descriptor_t) +
     339                sizeof (usb_standard_interface_descriptor_t) +
     340                hub_desc_size;
     341
    223342        uint8_t * full_config_descriptor =
    224                         (uint8_t*) malloc(descriptor.total_length);
    225         memcpy(full_config_descriptor, &descriptor, sizeof(descriptor));
    226         memcpy(full_config_descriptor + sizeof(descriptor),
    227                         &ohci_rh_iface_descriptor, sizeof(ohci_rh_iface_descriptor));
    228         memcpy(full_config_descriptor + sizeof(descriptor) +
    229                                 sizeof(ohci_rh_iface_descriptor),
    230                         &ohci_rh_ep_descriptor, sizeof(ohci_rh_ep_descriptor));
    231         memcpy(full_config_descriptor + sizeof(descriptor) +
    232                                 sizeof(ohci_rh_iface_descriptor) +
    233                                 sizeof(ohci_rh_ep_descriptor),
    234                         hub_descriptor, hub_desc_size);
    235        
     343                (uint8_t*) malloc(descriptor.total_length);
     344        memcpy(full_config_descriptor, &descriptor, sizeof (descriptor));
     345        memcpy(full_config_descriptor + sizeof (descriptor),
     346                &ohci_rh_iface_descriptor, sizeof (ohci_rh_iface_descriptor));
     347        memcpy(full_config_descriptor + sizeof (descriptor) +
     348                sizeof (ohci_rh_iface_descriptor),
     349                &ohci_rh_ep_descriptor, sizeof (ohci_rh_ep_descriptor));
     350        memcpy(full_config_descriptor + sizeof (descriptor) +
     351                sizeof (ohci_rh_iface_descriptor) +
     352                sizeof (ohci_rh_ep_descriptor),
     353                hub_descriptor, hub_desc_size);
     354
    236355        instance->descriptors.configuration = full_config_descriptor;
    237356        instance->descriptors.configuration_size = descriptor.total_length;
    238357}
    239 
    240 /** Root hub initialization
    241  * @return Error code.
    242  */
    243 int rh_init(rh_t *instance, ddf_dev_t *dev, ohci_regs_t *regs)
    244 {
    245         assert(instance);
    246         instance->address = -1;
    247         instance->registers = regs;
    248         instance->device = dev;
    249         instance->port_count = instance->registers->rh_desc_a & 0xff;
    250         rh_init_descriptors(instance);
    251         /// \TODO set port power mode
    252 
    253 
    254         usb_log_info("OHCI root hub with %d ports.\n", instance->port_count);
    255 
    256         //start generic usb hub driver
    257        
    258         /* TODO: implement */
    259         return EOK;
    260 }
    261358/*----------------------------------------------------------------------------*/
    262359
     
    272369 */
    273370static int process_get_port_status_request(rh_t *instance, uint16_t port,
    274                 usb_transfer_batch_t * request){
    275         if(port<1 || port>instance->port_count)
    276                 return EINVAL;
    277         uint32_t * uint32_buffer = (uint32_t*)request->transport_buffer;
     371        usb_transfer_batch_t * request) {
     372        if (port < 1 || port > instance->port_count)
     373                return EINVAL;
     374        uint32_t * uint32_buffer = (uint32_t*) request->transport_buffer;
    278375        request->transfered_size = 4;
    279         uint32_buffer[0] = instance->registers->rh_port_status[port -1];
    280         return EOK;
    281 }
     376        uint32_buffer[0] = instance->registers->rh_port_status[port - 1];
     377#if 0
     378        int i;
     379        for (i = 0; i < instance->port_count; ++i) {
     380                usb_log_debug("port status %d,x%x\n",
     381                        instance->registers->rh_port_status[i],
     382                        instance->registers->rh_port_status[i]);
     383        }
     384#endif
     385        return EOK;
     386}
     387/*----------------------------------------------------------------------------*/
    282388
    283389/**
     
    291397 */
    292398static int process_get_hub_status_request(rh_t *instance,
    293                 usb_transfer_batch_t * request){
    294         uint32_t * uint32_buffer = (uint32_t*)request->transport_buffer;
     399        usb_transfer_batch_t * request) {
     400        uint32_t * uint32_buffer = (uint32_t*) request->transport_buffer;
     401        request->transfered_size = 4;
    295402        //bits, 0,1,16,17
    296         request->transfered_size = 4;
    297         uint32_t mask = 1 & (1<<1) & (1<<16) & (1<<17);
     403        uint32_t mask = 1 | (1 << 1) | (1 << 16) | (1 << 17);
    298404        uint32_buffer[0] = mask & instance->registers->rh_status;
    299405        return EOK;
    300 
    301 }
    302 
    303 
     406}
     407/*----------------------------------------------------------------------------*/
    304408
    305409/**
     
    313417 */
    314418static int process_get_status_request(rh_t *instance,
    315                 usb_transfer_batch_t * request)
    316 {
     419        usb_transfer_batch_t * request) {
    317420        size_t buffer_size = request->buffer_size;
    318421        usb_device_request_setup_packet_t * request_packet =
    319                         (usb_device_request_setup_packet_t*)
    320                         request->setup_buffer;
     422                (usb_device_request_setup_packet_t*)
     423                request->setup_buffer;
    321424
    322425        usb_hub_bm_request_type_t request_type = request_packet->request_type;
    323         if(buffer_size<4/*request_packet->length*/){///\TODO
     426        if (buffer_size < 4/*request_packet->length*/) {///\TODO
    324427                usb_log_warning("requested more data than buffer size\n");
    325428                return EINVAL;
    326429        }
    327430
    328         if(request_type == USB_HUB_REQ_TYPE_GET_HUB_STATUS)
     431        if (request_type == USB_HUB_REQ_TYPE_GET_HUB_STATUS)
    329432                return process_get_hub_status_request(instance, request);
    330         if(request_type == USB_HUB_REQ_TYPE_GET_PORT_STATUS)
    331                 return process_get_port_status_request(instance, request_packet->index,
    332                                 request);
     433        if (request_type == USB_HUB_REQ_TYPE_GET_PORT_STATUS)
     434                return process_get_port_status_request(instance,
     435                request_packet->index,
     436                request);
    333437        return ENOTSUP;
    334438}
     439/*----------------------------------------------------------------------------*/
    335440
    336441/**
     
    339444 * Result contains bitmap where bit 0 indicates change on hub and
    340445 * bit i indicates change on i`th port (i>0). For more info see
    341  * Hub and Port status bitmap specification in USB specification.
     446 * Hub and Port status bitmap specification in USB specification
     447 * (chapter 11.13.4)
    342448 * @param instance root hub instance
    343449 * @param@out buffer pointer to created interrupt mas
     
    345451 */
    346452static void create_interrupt_mask(rh_t *instance, void ** buffer,
    347                 size_t * buffer_size){
     453        size_t * buffer_size) {
    348454        int bit_count = instance->port_count + 1;
    349         (*buffer_size) = (bit_count / 8) + (bit_count%8==0)?0:1;
     455        (*buffer_size) = (bit_count / 8) + ((bit_count % 8 == 0) ? 0 : 1);
     456
    350457        (*buffer) = malloc(*buffer_size);
    351         uint8_t * bitmap = (uint8_t*)(*buffer);
    352         uint32_t mask = (1<<16) + (1<<17);
    353         bzero(bitmap,(*buffer_size));
    354         if(instance->registers->rh_status & mask){
     458        uint8_t * bitmap = (uint8_t*) (*buffer);
     459        uint32_t mask = (1 << (USB_HUB_FEATURE_C_HUB_LOCAL_POWER + 16))
     460                | (1 << (USB_HUB_FEATURE_C_HUB_OVER_CURRENT + 16));
     461        bzero(bitmap, (*buffer_size));
     462        if (instance->registers->rh_status & mask) {
    355463                bitmap[0] = 1;
    356464        }
    357465        int port;
    358         mask = 0;
    359         int i;
    360         for(i=16;i<=20;++i)
    361                 mask += 1<<i;
    362         for(port = 1; port<=instance->port_count;++port){
    363                 if(mask & instance->registers->rh_port_status[port-1]){
    364                         bitmap[(port+1)/8] += 1<<(port%8);
    365                 }
    366         }
    367 }
    368  
     466        mask = port_status_change_mask;
     467        for (port = 1; port <= instance->port_count; ++port) {
     468                if (mask & instance->registers->rh_port_status[port - 1]) {
     469                        bitmap[(port) / 8] += 1 << (port % 8);
     470                }
     471        }
     472}
     473/*----------------------------------------------------------------------------*/
     474
    369475/**
    370476 * create answer to a descriptor request
     
    377483 */
    378484static int process_get_descriptor_request(rh_t *instance,
    379                 usb_transfer_batch_t *request){
     485        usb_transfer_batch_t *request) {
    380486        usb_device_request_setup_packet_t * setup_request =
    381                         (usb_device_request_setup_packet_t*)request->setup_buffer;
     487                (usb_device_request_setup_packet_t*) request->setup_buffer;
    382488        size_t size;
    383489        const void * result_descriptor = NULL;
    384490        const uint16_t setup_request_value = setup_request->value_high;
    385                         //(setup_request->value_low << 8);
     491        //(setup_request->value_low << 8);
    386492        bool del = false;
    387         switch (setup_request_value)
    388         {
    389                 case USB_DESCTYPE_HUB: {
     493        switch (setup_request_value) {
     494                case USB_DESCTYPE_HUB:
     495                {
    390496                        uint8_t * descriptor;
    391497                        usb_create_serialized_hub_descriptor(
    392498                                instance, &descriptor, &size);
    393499                        result_descriptor = descriptor;
    394                         if(result_descriptor) del = true;
     500                        if (result_descriptor) del = true;
    395501                        break;
    396502                }
    397                 case USB_DESCTYPE_DEVICE: {
     503                case USB_DESCTYPE_DEVICE:
     504                {
    398505                        usb_log_debug("USB_DESCTYPE_DEVICE\n");
    399506                        result_descriptor = &ohci_rh_device_descriptor;
    400                         size = sizeof(ohci_rh_device_descriptor);
     507                        size = sizeof (ohci_rh_device_descriptor);
    401508                        break;
    402509                }
    403                 case USB_DESCTYPE_CONFIGURATION: {
     510                case USB_DESCTYPE_CONFIGURATION:
     511                {
    404512                        usb_log_debug("USB_DESCTYPE_CONFIGURATION\n");
    405513                        result_descriptor = instance->descriptors.configuration;
     
    407515                        break;
    408516                }
    409                 case USB_DESCTYPE_INTERFACE: {
     517                case USB_DESCTYPE_INTERFACE:
     518                {
    410519                        usb_log_debug("USB_DESCTYPE_INTERFACE\n");
    411520                        result_descriptor = &ohci_rh_iface_descriptor;
    412                         size = sizeof(ohci_rh_iface_descriptor);
     521                        size = sizeof (ohci_rh_iface_descriptor);
    413522                        break;
    414523                }
    415                 case USB_DESCTYPE_ENDPOINT: {
     524                case USB_DESCTYPE_ENDPOINT:
     525                {
    416526                        usb_log_debug("USB_DESCTYPE_ENDPOINT\n");
    417527                        result_descriptor = &ohci_rh_ep_descriptor;
    418                         size = sizeof(ohci_rh_ep_descriptor);
     528                        size = sizeof (ohci_rh_ep_descriptor);
    419529                        break;
    420530                }
    421                 default: {
    422                         usb_log_debug("USB_DESCTYPE_EINVAL %d \n",setup_request->value);
    423                         usb_log_debug("\ttype %d\n\trequest %d\n\tvalue %d\n\tindex %d\n\tlen %d\n ",
    424                                         setup_request->request_type,
    425                                         setup_request->request,
    426                                         setup_request_value,
    427                                         setup_request->index,
    428                                         setup_request->length
    429                                         );
     531                default:
     532                {
     533                        usb_log_debug("USB_DESCTYPE_EINVAL %d \n",
     534                                setup_request->value);
     535                        usb_log_debug("\ttype %d\n\trequest %d\n\tvalue "
     536                                "%d\n\tindex %d\n\tlen %d\n ",
     537                                setup_request->request_type,
     538                                setup_request->request,
     539                                setup_request_value,
     540                                setup_request->index,
     541                                setup_request->length
     542                                );
    430543                        return EINVAL;
    431544                }
    432545        }
    433         if(request->buffer_size < size){
     546        if (request->buffer_size < size) {
    434547                size = request->buffer_size;
    435548        }
    436549        request->transfered_size = size;
    437         memcpy(request->transport_buffer,result_descriptor,size);
    438         usb_log_debug("sent desctiptor: %s\n",
    439                         usb_debug_str_buffer((uint8_t*)request->transport_buffer,size,size));
     550        memcpy(request->transport_buffer, result_descriptor, size);
    440551        if (del)
    441552                free(result_descriptor);
    442553        return EOK;
    443554}
     555/*----------------------------------------------------------------------------*/
    444556
    445557/**
     
    451563 * @return error code
    452564 */
    453 static int process_get_configuration_request(rh_t *instance, 
    454                 usb_transfer_batch_t *request){
     565static int process_get_configuration_request(rh_t *instance,
     566        usb_transfer_batch_t *request) {
    455567        //set and get configuration requests do not have any meaning, only dummy
    456568        //values are returned
    457         if(request->buffer_size != 1)
     569        if (request->buffer_size != 1)
    458570                return EINVAL;
    459571        request->transport_buffer[0] = 1;
     
    461573        return EOK;
    462574}
     575/*----------------------------------------------------------------------------*/
    463576
    464577/**
    465578 * process feature-enabling request on hub
    466  * 
     579 *
    467580 * @param instance root hub instance
    468581 * @param feature feature selector
     
    470583 */
    471584static int process_hub_feature_set_request(rh_t *instance,
    472                 uint16_t feature){
    473         if(! ((1<<feature) & hub_set_feature_valid_mask))
     585        uint16_t feature) {
     586        if (!((1 << feature) & hub_set_feature_valid_mask))
    474587                return EINVAL;
    475588        instance->registers->rh_status =
    476                         (instance->registers->rh_status | (1<<feature))
    477                         & (~ hub_clear_feature_by_writing_one_mask);
    478         return EOK;
    479 }
     589                (instance->registers->rh_status | (1 << feature))
     590                & (~hub_clear_feature_by_writing_one_mask);
     591        return EOK;
     592}
     593/*----------------------------------------------------------------------------*/
    480594
    481595/**
     
    487601 */
    488602static int process_hub_feature_clear_request(rh_t *instance,
    489                 uint16_t feature){
    490         if(! ((1<<feature) & hub_clear_feature_valid_mask))
     603        uint16_t feature) {
     604        if (!((1 << feature) & hub_clear_feature_valid_mask))
    491605                return EINVAL;
    492606        //is the feature cleared directly?
    493         if ((1<<feature) & hub_set_feature_direct_mask){
     607        if ((1 << feature) & hub_set_feature_direct_mask) {
    494608                instance->registers->rh_status =
    495                         (instance->registers->rh_status & (~(1<<feature)))
    496                         & (~ hub_clear_feature_by_writing_one_mask);
    497         }else{//the feature is cleared by writing '1'
     609                        (instance->registers->rh_status & (~(1 << feature)))
     610                        & (~hub_clear_feature_by_writing_one_mask);
     611        } else {//the feature is cleared by writing '1'
    498612                instance->registers->rh_status =
    499                                 (instance->registers->rh_status
    500                                 & (~ hub_clear_feature_by_writing_one_mask))
    501                                 | (1<<feature);
    502         }
    503         return EOK;
    504 }
    505 
    506 
     613                        (instance->registers->rh_status
     614                        & (~hub_clear_feature_by_writing_one_mask))
     615                        | (1 << feature);
     616        }
     617        return EOK;
     618}
     619/*----------------------------------------------------------------------------*/
    507620
    508621/**
    509622 * process feature-enabling request on hub
    510  * 
     623 *
    511624 * @param instance root hub instance
    512625 * @param feature feature selector
     
    516629 */
    517630static int process_port_feature_set_request(rh_t *instance,
    518                 uint16_t feature, uint16_t port){
    519         if(!((1<<feature) & port_set_feature_valid_mask))
    520                 return EINVAL;
    521         if(port<1 || port>instance->port_count)
     631        uint16_t feature, uint16_t port) {
     632        if (!((1 << feature) & port_set_feature_valid_mask))
     633                return EINVAL;
     634        if (port < 1 || port > instance->port_count)
    522635                return EINVAL;
    523636        instance->registers->rh_port_status[port - 1] =
    524                         (instance->registers->rh_port_status[port - 1] | (1<<feature))
    525                         & (~port_clear_feature_valid_mask);
     637                (instance->registers->rh_port_status[port - 1] | (1 << feature))
     638                & (~port_clear_feature_valid_mask);
    526639        /// \TODO any error?
    527640        return EOK;
    528641}
     642/*----------------------------------------------------------------------------*/
    529643
    530644/**
     
    538652 */
    539653static int process_port_feature_clear_request(rh_t *instance,
    540                 uint16_t feature, uint16_t port){
    541         if(!((1<<feature) & port_clear_feature_valid_mask))
    542                 return EINVAL;
    543         if(port<1 || port>instance->port_count)
    544                 return EINVAL;
    545         if(feature == USB_HUB_FEATURE_PORT_POWER)
     654        uint16_t feature, uint16_t port) {
     655        if (!((1 << feature) & port_clear_feature_valid_mask))
     656                return EINVAL;
     657        if (port < 1 || port > instance->port_count)
     658                return EINVAL;
     659        if (feature == USB_HUB_FEATURE_PORT_POWER)
    546660                feature = USB_HUB_FEATURE_PORT_LOW_SPEED;
    547         if(feature == USB_HUB_FEATURE_PORT_SUSPEND)
     661        if (feature == USB_HUB_FEATURE_PORT_SUSPEND)
    548662                feature = USB_HUB_FEATURE_PORT_OVER_CURRENT;
    549663        instance->registers->rh_port_status[port - 1] =
    550                         (instance->registers->rh_port_status[port - 1]
    551                         & (~port_clear_feature_valid_mask))
    552                         | (1<<feature);
     664                (instance->registers->rh_port_status[port - 1]
     665                & (~port_clear_feature_valid_mask))
     666                | (1 << feature);
    553667        /// \TODO any error?
    554668        return EOK;
    555669}
    556 
     670/*----------------------------------------------------------------------------*/
    557671
    558672/**
    559673 * register address to this device
    560  * 
     674 *
    561675 * @param instance root hub instance
    562676 * @param address new address
     
    564678 */
    565679static int process_address_set_request(rh_t *instance,
    566                 uint16_t address){
     680        uint16_t address) {
    567681        instance->address = address;
    568682        return EOK;
    569683}
     684/*----------------------------------------------------------------------------*/
    570685
    571686/**
     
    579694 */
    580695static int process_request_with_output(rh_t *instance,
    581                 usb_transfer_batch_t *request){
     696        usb_transfer_batch_t *request) {
    582697        usb_device_request_setup_packet_t * setup_request =
    583                         (usb_device_request_setup_packet_t*)request->setup_buffer;
    584         if(setup_request->request == USB_DEVREQ_GET_STATUS){
     698                (usb_device_request_setup_packet_t*) request->setup_buffer;
     699        if (setup_request->request == USB_DEVREQ_GET_STATUS) {
    585700                usb_log_debug("USB_DEVREQ_GET_STATUS\n");
    586701                return process_get_status_request(instance, request);
    587702        }
    588         if(setup_request->request == USB_DEVREQ_GET_DESCRIPTOR){
     703        if (setup_request->request == USB_DEVREQ_GET_DESCRIPTOR) {
    589704                usb_log_debug("USB_DEVREQ_GET_DESCRIPTOR\n");
    590705                return process_get_descriptor_request(instance, request);
    591706        }
    592         if(setup_request->request == USB_DEVREQ_GET_CONFIGURATION){
     707        if (setup_request->request == USB_DEVREQ_GET_CONFIGURATION) {
    593708                usb_log_debug("USB_DEVREQ_GET_CONFIGURATION\n");
    594709                return process_get_configuration_request(instance, request);
     
    596711        return ENOTSUP;
    597712}
     713/*----------------------------------------------------------------------------*/
    598714
    599715/**
     
    607723 */
    608724static int process_request_with_input(rh_t *instance,
    609                 usb_transfer_batch_t *request){
     725        usb_transfer_batch_t *request) {
    610726        usb_device_request_setup_packet_t * setup_request =
    611                         (usb_device_request_setup_packet_t*)request->setup_buffer;
     727                (usb_device_request_setup_packet_t*) request->setup_buffer;
    612728        request->transfered_size = 0;
    613         if(setup_request->request == USB_DEVREQ_SET_DESCRIPTOR){
     729        if (setup_request->request == USB_DEVREQ_SET_DESCRIPTOR) {
    614730                return ENOTSUP;
    615731        }
    616         if(setup_request->request == USB_DEVREQ_SET_CONFIGURATION){
     732        if (setup_request->request == USB_DEVREQ_SET_CONFIGURATION) {
    617733                //set and get configuration requests do not have any meaning,
    618734                //only dummy values are returned
     
    621737        return ENOTSUP;
    622738}
     739/*----------------------------------------------------------------------------*/
    623740
    624741/**
     
    632749 */
    633750static int process_request_without_data(rh_t *instance,
    634                 usb_transfer_batch_t *request){
     751        usb_transfer_batch_t *request) {
    635752        usb_device_request_setup_packet_t * setup_request =
    636                         (usb_device_request_setup_packet_t*)request->setup_buffer;
     753                (usb_device_request_setup_packet_t*) request->setup_buffer;
    637754        request->transfered_size = 0;
    638         if(setup_request->request == USB_DEVREQ_CLEAR_FEATURE){
    639                 if(setup_request->request_type == USB_HUB_REQ_TYPE_SET_HUB_FEATURE){
     755        if (setup_request->request == USB_DEVREQ_CLEAR_FEATURE) {
     756                if (setup_request->request_type == USB_HUB_REQ_TYPE_SET_HUB_FEATURE) {
    640757                        usb_log_debug("USB_HUB_REQ_TYPE_SET_HUB_FEATURE\n");
    641758                        return process_hub_feature_clear_request(instance,
    642                                         setup_request->value);
    643                 }
    644                 if(setup_request->request_type == USB_HUB_REQ_TYPE_SET_PORT_FEATURE){
     759                                setup_request->value);
     760                }
     761                if (setup_request->request_type == USB_HUB_REQ_TYPE_SET_PORT_FEATURE) {
    645762                        usb_log_debug("USB_HUB_REQ_TYPE_SET_PORT_FEATURE\n");
    646763                        return process_port_feature_clear_request(instance,
    647                                         setup_request->value,
    648                                         setup_request->index);
     764                                setup_request->value,
     765                                setup_request->index);
    649766                }
    650767                usb_log_debug("USB_HUB_REQ_TYPE_INVALID %d\n",
    651                                 setup_request->request_type);
    652                 return EINVAL;
    653         }
    654         if(setup_request->request == USB_DEVREQ_SET_FEATURE){
    655                 if(setup_request->request_type == USB_HUB_REQ_TYPE_SET_HUB_FEATURE){
     768                        setup_request->request_type);
     769                return EINVAL;
     770        }
     771        if (setup_request->request == USB_DEVREQ_SET_FEATURE) {
     772                if (setup_request->request_type == USB_HUB_REQ_TYPE_SET_HUB_FEATURE) {
    656773                        usb_log_debug("USB_HUB_REQ_TYPE_SET_HUB_FEATURE\n");
    657774                        return process_hub_feature_set_request(instance,
    658                                         setup_request->value);
    659                 }
    660                 if(setup_request->request_type == USB_HUB_REQ_TYPE_SET_PORT_FEATURE){
     775                                setup_request->value);
     776                }
     777                if (setup_request->request_type == USB_HUB_REQ_TYPE_SET_PORT_FEATURE) {
    661778                        usb_log_debug("USB_HUB_REQ_TYPE_SET_PORT_FEATURE\n");
    662779                        return process_port_feature_set_request(instance,
    663                                         setup_request->value,
    664                                         setup_request->index);
    665                 }
    666                 usb_log_debug("USB_HUB_REQ_TYPE_INVALID %d\n",setup_request->request_type);
    667                 return EINVAL;
    668         }
    669         if(setup_request->request == USB_DEVREQ_SET_ADDRESS){
     780                                setup_request->value,
     781                                setup_request->index);
     782                }
     783                usb_log_debug("USB_HUB_REQ_TYPE_INVALID %d\n",
     784                        setup_request->request_type);
     785                return EINVAL;
     786        }
     787        if (setup_request->request == USB_DEVREQ_SET_ADDRESS) {
    670788                usb_log_debug("USB_DEVREQ_SET_ADDRESS\n");
    671                 return process_address_set_request(instance, setup_request->value);
    672         }
    673         usb_log_debug("USB_DEVREQ_SET_ENOTSUP %d\n",setup_request->request_type);
     789                return process_address_set_request(instance,
     790                        setup_request->value);
     791        }
     792        usb_log_debug("USB_DEVREQ_SET_ENOTSUP %d\n",
     793                setup_request->request_type);
    674794        return ENOTSUP;
    675795}
     796/*----------------------------------------------------------------------------*/
    676797
    677798/**
     
    693814 * @return error code
    694815 */
    695 static int process_ctrl_request(rh_t *instance, usb_transfer_batch_t *request){
     816static int process_ctrl_request(rh_t *instance, usb_transfer_batch_t *request) {
     817        if (!request->setup_buffer) {
     818                usb_log_error("root hub received empty transaction?");
     819                return EINVAL;
     820        }
    696821        int opResult;
    697         if (request->setup_buffer) {
    698                 if(sizeof(usb_device_request_setup_packet_t)>request->setup_size){
    699                         usb_log_error("setup packet too small\n");
    700                         return EINVAL;
    701                 }
    702                 usb_log_info("CTRL packet: %s.\n",
    703                         usb_debug_str_buffer((const uint8_t *)request->setup_buffer, 8, 8));
    704                 usb_device_request_setup_packet_t * setup_request =
    705                                 (usb_device_request_setup_packet_t*)request->setup_buffer;
    706                 if(
    707                         setup_request->request == USB_DEVREQ_GET_STATUS
    708                         || setup_request->request == USB_DEVREQ_GET_DESCRIPTOR
    709                         || setup_request->request == USB_DEVREQ_GET_CONFIGURATION
    710                 ){
     822        if (sizeof (usb_device_request_setup_packet_t) > request->setup_size) {
     823                usb_log_error("setup packet too small\n");
     824                return EINVAL;
     825        }
     826        usb_log_info("CTRL packet: %s.\n",
     827                usb_debug_str_buffer(
     828                (const uint8_t *) request->setup_buffer, 8, 8));
     829        usb_device_request_setup_packet_t * setup_request =
     830                (usb_device_request_setup_packet_t*)
     831                request->setup_buffer;
     832        switch (setup_request->request) {
     833                case USB_DEVREQ_GET_STATUS:
     834                case USB_DEVREQ_GET_DESCRIPTOR:
     835                case USB_DEVREQ_GET_CONFIGURATION:
    711836                        usb_log_debug("processing request with output\n");
    712                         opResult = process_request_with_output(instance,request);
    713                 }else if(
    714                         setup_request->request == USB_DEVREQ_CLEAR_FEATURE
    715                         || setup_request->request == USB_DEVREQ_SET_FEATURE
    716                         || setup_request->request == USB_DEVREQ_SET_ADDRESS
    717                 ){
    718                         usb_log_debug("processing request without additional data\n");
    719                         opResult = process_request_without_data(instance,request);
    720                 }else if(setup_request->request == USB_DEVREQ_SET_DESCRIPTOR
    721                                 || setup_request->request == USB_DEVREQ_SET_CONFIGURATION
    722                 ){
    723                         usb_log_debug("processing request with input\n");
    724                         opResult = process_request_with_input(instance,request);
    725                 }else{
    726                         usb_log_warning("received unsuported request: %d\n",
    727                                         setup_request->request
    728                                         );
     837                        opResult = process_request_with_output(
     838                                instance, request);
     839                        break;
     840                case USB_DEVREQ_CLEAR_FEATURE:
     841                case USB_DEVREQ_SET_FEATURE:
     842                case USB_DEVREQ_SET_ADDRESS:
     843                        usb_log_debug("processing request without "
     844                                "additional data\n");
     845                        opResult = process_request_without_data(
     846                                instance, request);
     847                        break;
     848                case USB_DEVREQ_SET_DESCRIPTOR:
     849                case USB_DEVREQ_SET_CONFIGURATION:
     850                        usb_log_debug("processing request with "
     851                                "input\n");
     852                        opResult = process_request_with_input(
     853                                instance, request);
     854                        break;
     855                default:
     856                        usb_log_warning("received unsuported request: "
     857                                "%d\n",
     858                                setup_request->request
     859                                );
    729860                        opResult = ENOTSUP;
    730                 }
    731         }else{
    732                 usb_log_error("root hub received empty transaction?");
    733                 opResult = EINVAL;
    734861        }
    735862        return opResult;
    736863}
    737864
    738 /**
    739  * process root hub request
    740  *
    741  * @param instance root hub instance
    742  * @param request structure containing both request and response information
    743  * @return error code
    744  */
    745 int rh_request(rh_t *instance, usb_transfer_batch_t *request)
    746 {
    747         assert(instance);
    748         assert(request);
    749         int opResult;
    750         if(request->transfer_type == USB_TRANSFER_CONTROL){
    751                 usb_log_info("Root hub got CONTROL packet\n");
    752                 opResult = process_ctrl_request(instance,request);
    753         }else if(request->transfer_type == USB_TRANSFER_INTERRUPT){
    754                 usb_log_info("Root hub got INTERRUPT packet\n");
    755                 void * buffer;
    756                 create_interrupt_mask(instance, &buffer,
    757                         &(request->transfered_size));
    758                 memcpy(request->transport_buffer,buffer, request->transfered_size);
    759                 opResult = EOK;
    760         }else{
    761                 opResult = EINVAL;
    762         }
    763         usb_transfer_batch_finish(request, opResult);
    764         return EOK;
    765 }
    766 /*----------------------------------------------------------------------------*/
    767 
    768 
    769 void rh_interrupt(rh_t *instance)
    770 {
    771         usb_log_info("Whoa whoa wait, I`m not supposed to receive any interrupts, am I?\n");
    772         /* TODO: implement? */
    773 }
     865
     866
     867
    774868/**
    775869 * @}
  • TabularUnified uspace/drv/usbhub/Makefile

    ra82889e ra4e18e1  
    3434SOURCES = \
    3535        main.c \
    36         ports.c \
    3736        utils.c \
    38         usbhub.c
     37        usbhub.c \
     38        usblist.c
    3939
    4040include $(USPACE_PREFIX)/Makefile.common
  • TabularUnified uspace/drv/usbhub/port_status.h

    ra82889e ra4e18e1  
    4949
    5050/**
     51 * structure holding hub status and changes flags.
     52 * should not be accessed directly, use supplied getter/setter methods.
     53 *
     54 * For more information refer to table 11.16.2.5 in
     55 * "Universal Serial Bus Specification Revision 1.1"
     56 *
     57 */
     58typedef uint32_t usb_hub_status_t;
     59
     60/**
    5161 * set values in request to be it a port status request
    5262 * @param request
     
    5464 */
    5565static inline void usb_hub_set_port_status_request(
    56 usb_device_request_setup_packet_t * request, uint16_t port
    57 ){
     66        usb_device_request_setup_packet_t * request, uint16_t port
     67        ) {
    5868        request->index = port;
    5969        request->request_type = USB_HUB_REQ_TYPE_GET_PORT_STATUS;
     
    6373}
    6474
     75/**
     76 * set values in request to be it a port status request
     77 * @param request
     78 * @param port
     79 */
     80static inline void usb_hub_set_hub_status_request(
     81        usb_device_request_setup_packet_t * request
     82        ) {
     83        request->index = 0;
     84        request->request_type = USB_HUB_REQ_TYPE_GET_HUB_STATUS;
     85        request->request = USB_HUB_REQUEST_GET_STATUS;
     86        request->value = 0;
     87        request->length = 4;
     88}
    6589
    6690/**
     
    7094 */
    7195static inline usb_device_request_setup_packet_t *
    72 usb_hub_create_port_status_request(uint16_t port){
     96usb_hub_create_port_status_request(uint16_t port) {
    7397        usb_device_request_setup_packet_t * result =
    7498                usb_new(usb_device_request_setup_packet_t);
    75         usb_hub_set_port_status_request(result,port);
     99        usb_hub_set_port_status_request(result, port);
    76100        return result;
    77101}
    78102
    79 
    80103/**
    81104 * set the device request to be a port feature enable request
     
    85108 */
    86109static inline void usb_hub_set_enable_port_feature_request(
    87 usb_device_request_setup_packet_t * request, uint16_t port,
    88                 uint16_t feature_selector
    89 ){
     110        usb_device_request_setup_packet_t * request, uint16_t port,
     111        uint16_t feature_selector
     112        ) {
    90113        request->index = port;
    91114        request->request_type = USB_HUB_REQ_TYPE_SET_PORT_FEATURE;
     
    102125 */
    103126static inline void usb_hub_set_disable_port_feature_request(
    104 usb_device_request_setup_packet_t * request, uint16_t port,
    105                 uint16_t feature_selector
    106 ){
     127        usb_device_request_setup_packet_t * request, uint16_t port,
     128        uint16_t feature_selector
     129        ) {
    107130        request->index = port;
    108131        request->request_type = USB_HUB_REQ_TYPE_SET_PORT_FEATURE;
     
    118141 */
    119142static inline void usb_hub_set_enable_port_request(
    120 usb_device_request_setup_packet_t * request, uint16_t port
    121 ){
     143        usb_device_request_setup_packet_t * request, uint16_t port
     144        ) {
    122145        request->index = port;
    123146        request->request_type = USB_HUB_REQ_TYPE_SET_PORT_FEATURE;
     
    133156 */
    134157static inline usb_device_request_setup_packet_t *
    135 usb_hub_create_enable_port_request(uint16_t port){
     158usb_hub_create_enable_port_request(uint16_t port) {
    136159        usb_device_request_setup_packet_t * result =
    137160                usb_new(usb_device_request_setup_packet_t);
    138         usb_hub_set_enable_port_request(result,port);
     161        usb_hub_set_enable_port_request(result, port);
    139162        return result;
    140163}
     
    146169 */
    147170static inline void usb_hub_set_disable_port_request(
    148 usb_device_request_setup_packet_t * request, uint16_t port
    149 ){
     171        usb_device_request_setup_packet_t * request, uint16_t port
     172        ) {
    150173        request->index = port;
    151174        request->request_type = USB_HUB_REQ_TYPE_SET_PORT_FEATURE;
     
    161184 */
    162185static inline usb_device_request_setup_packet_t *
    163 usb_hub_create_disable_port_request(uint16_t port){
     186usb_hub_create_disable_port_request(uint16_t port) {
    164187        usb_device_request_setup_packet_t * result =
    165188                usb_new(usb_device_request_setup_packet_t);
    166         usb_hub_set_disable_port_request(result,port);
     189        usb_hub_set_disable_port_request(result, port);
    167190        return result;
    168191}
     
    174197 */
    175198static inline void usb_hub_set_reset_port_request(
    176 usb_device_request_setup_packet_t * request, uint16_t port
    177 ){
     199        usb_device_request_setup_packet_t * request, uint16_t port
     200        ) {
    178201        request->index = port;
    179202        request->request_type = USB_HUB_REQ_TYPE_SET_PORT_FEATURE;
     
    189212 */
    190213static inline usb_device_request_setup_packet_t *
    191 usb_hub_create_reset_port_request(uint16_t port){
     214usb_hub_create_reset_port_request(uint16_t port) {
    192215        usb_device_request_setup_packet_t * result =
    193216                usb_new(usb_device_request_setup_packet_t);
    194         usb_hub_set_reset_port_request(result,port);
     217        usb_hub_set_reset_port_request(result, port);
    195218        return result;
    196219}
     
    202225 */
    203226static inline void usb_hub_set_power_port_request(
    204 usb_device_request_setup_packet_t * request, uint16_t port
    205 ){
     227        usb_device_request_setup_packet_t * request, uint16_t port
     228        ) {
    206229        request->index = port;
    207230        request->request_type = USB_HUB_REQ_TYPE_SET_PORT_FEATURE;
     
    217240 */
    218241static inline void usb_hub_unset_power_port_request(
    219 usb_device_request_setup_packet_t * request, uint16_t port
    220 ){
     242        usb_device_request_setup_packet_t * request, uint16_t port
     243        ) {
    221244        request->index = port;
    222245        request->request_type = USB_HUB_REQ_TYPE_SET_PORT_FEATURE;
     
    226249}
    227250
    228 
    229 /** get i`th bit of port status */
    230 static inline bool usb_port_get_bit(usb_port_status_t * status, int idx)
    231 {
    232         return (((*status)>>(idx))%2);
    233 }
    234 
    235 /** set i`th bit of port status */
     251/**
     252 * get i`th bit of port status
     253 *
     254 * @param status
     255 * @param idx
     256 * @return
     257 */
     258static inline bool usb_port_get_bit(usb_port_status_t * status, int idx) {
     259        return ((*status)&(1 << idx))!=0;
     260}
     261
     262/**
     263 * set i`th bit of port status
     264 *
     265 * @param status
     266 * @param idx
     267 * @param value
     268 */
    236269static inline void usb_port_set_bit(
    237         usb_port_status_t * status, int idx, bool value)
    238 {
    239         (*status) = value?
    240                                ((*status)|(1<<(idx))):
    241                                ((*status)&(~(1<<(idx))));
    242 }
    243 
    244 //device connnected on port
    245 static inline bool usb_port_dev_connected(usb_port_status_t * status){
    246         return usb_port_get_bit(status,0);
    247 }
    248 
    249 static inline void usb_port_set_dev_connected(usb_port_status_t * status,bool connected){
    250         usb_port_set_bit(status,0,connected);
     270        usb_port_status_t * status, int idx, bool value) {
     271        (*status) = value ?
     272                ((*status) | (1 << (idx))) :
     273                ((*status)&(~(1 << (idx))));
     274}
     275
     276/**
     277 * get i`th bit of hub status
     278 *
     279 * @param status
     280 * @param idx
     281 * @return
     282 */
     283static inline bool usb_hub_get_bit(usb_hub_status_t * status, int idx) {
     284        return (*status)&(1 << idx);
     285}
     286
     287/**
     288 * set i`th bit of hub status
     289 *
     290 * @param status
     291 * @param idx
     292 * @param value
     293 */
     294static inline void usb_hub_set_bit(
     295        usb_hub_status_t * status, int idx, bool value) {
     296        (*status) = value ?
     297                ((*status) | (1 << (idx))) :
     298                ((*status)&(~(1 << (idx))));
     299}
     300
     301/**
     302 * connection status geter for port status
     303 *
     304 * @param status
     305 * @return true if there is something connected
     306 */
     307static inline bool usb_port_dev_connected(usb_port_status_t * status) {
     308        return usb_port_get_bit(status, 0);
     309}
     310
     311static inline void usb_port_set_dev_connected(usb_port_status_t * status, bool connected) {
     312        usb_port_set_bit(status, 0, connected);
    251313}
    252314
    253315//port enabled
    254 static inline bool usb_port_enabled(usb_port_status_t * status){
    255         return usb_port_get_bit(status,1);
    256 }
    257 
    258 static inline void usb_port_set_enabled(usb_port_status_t * status,bool enabled){
    259         usb_port_set_bit(status,1,enabled);
     316
     317/**
     318 * port enabled getter for port status
     319 *
     320 * @param status
     321 * @return true if the port is enabled
     322 */
     323static inline bool usb_port_enabled(usb_port_status_t * status) {
     324        return usb_port_get_bit(status, 1);
     325}
     326
     327static inline void usb_port_set_enabled(usb_port_status_t * status, bool enabled) {
     328        usb_port_set_bit(status, 1, enabled);
    260329}
    261330
    262331//port suspended
    263 static inline bool usb_port_suspended(usb_port_status_t * status){
    264         return usb_port_get_bit(status,2);
    265 }
    266 
    267 static inline void usb_port_set_suspended(usb_port_status_t * status,bool suspended){
    268         usb_port_set_bit(status,2,suspended);
     332/**
     333 * port suspended getter for port status
     334 *
     335 * @param status
     336 * @return true if port is suspended
     337 */
     338static inline bool usb_port_suspended(usb_port_status_t * status) {
     339        return usb_port_get_bit(status, 2);
     340}
     341
     342static inline void usb_port_set_suspended(usb_port_status_t * status, bool suspended) {
     343        usb_port_set_bit(status, 2, suspended);
    269344}
    270345
    271346//over currect
    272 static inline bool usb_port_over_current(usb_port_status_t * status){
    273         return usb_port_get_bit(status,3);
    274 }
    275 
    276 static inline void usb_port_set_over_current(usb_port_status_t * status,bool value){
    277         usb_port_set_bit(status,3,value);
     347/**
     348 * over current condition indicator getter for port status
     349 *
     350 * @param status
     351 * @return true if there is opver-current condition on the hub
     352 */
     353static inline bool usb_port_over_current(usb_port_status_t * status) {
     354        return usb_port_get_bit(status, 3);
     355}
     356
     357static inline void usb_port_set_over_current(usb_port_status_t * status, bool value) {
     358        usb_port_set_bit(status, 3, value);
    278359}
    279360
    280361//port reset
    281 static inline bool usb_port_reset(usb_port_status_t * status){
    282         return usb_port_get_bit(status,4);
    283 }
    284 
    285 static inline void usb_port_set_reset(usb_port_status_t * status,bool value){
    286         usb_port_set_bit(status,4,value);
     362/**
     363 * port reset indicator getter for port status
     364 *
     365 * @param status
     366 * @return true if port is reset
     367 */
     368static inline bool usb_port_reset(usb_port_status_t * status) {
     369        return usb_port_get_bit(status, 4);
     370}
     371
     372static inline void usb_port_set_reset(usb_port_status_t * status, bool value) {
     373        usb_port_set_bit(status, 4, value);
    287374}
    288375
    289376//powered
    290 static inline bool usb_port_powered(usb_port_status_t * status){
    291         return usb_port_get_bit(status,8);
    292 }
    293 
    294 static inline void usb_port_set_powered(usb_port_status_t * status,bool powered){
    295         usb_port_set_bit(status,8,powered);
     377/**
     378 * power state getter for port status
     379 *
     380 * @param status
     381 * @return true if port is powered
     382 */
     383static inline bool usb_port_powered(usb_port_status_t * status) {
     384        return usb_port_get_bit(status, 8);
     385}
     386
     387static inline void usb_port_set_powered(usb_port_status_t * status, bool powered) {
     388        usb_port_set_bit(status, 8, powered);
    296389}
    297390
    298391//low speed device attached
    299 static inline bool usb_port_low_speed(usb_port_status_t * status){
    300         return usb_port_get_bit(status,9);
    301 }
    302 
    303 static inline void usb_port_set_low_speed(usb_port_status_t * status,bool low_speed){
    304         usb_port_set_bit(status,9,low_speed);
    305 }
    306 
    307 //low speed device attached
    308 static inline bool usb_port_high_speed(usb_port_status_t * status){
    309         return usb_port_get_bit(status,10);
    310 }
    311 
    312 static inline void usb_port_set_high_speed(usb_port_status_t * status,bool high_speed){
    313         usb_port_set_bit(status,10,high_speed);
    314 }
    315 
    316 static inline usb_speed_t usb_port_speed(usb_port_status_t * status){
    317         if(usb_port_low_speed(status))
     392/**
     393 * low speed device on the port indicator
     394 *
     395 * @param status
     396 * @return true if low speed device is attached
     397 */
     398static inline bool usb_port_low_speed(usb_port_status_t * status) {
     399        return usb_port_get_bit(status, 9);
     400}
     401
     402static inline void usb_port_set_low_speed(usb_port_status_t * status, bool low_speed) {
     403        usb_port_set_bit(status, 9, low_speed);
     404}
     405
     406//high speed device attached
     407/**
     408 * high speed device on the port indicator
     409 *
     410 * @param status
     411 * @return true if high speed device is on port
     412 */
     413static inline bool usb_port_high_speed(usb_port_status_t * status) {
     414        return usb_port_get_bit(status, 10);
     415}
     416
     417static inline void usb_port_set_high_speed(usb_port_status_t * status, bool high_speed) {
     418        usb_port_set_bit(status, 10, high_speed);
     419}
     420
     421/**
     422 * speed getter for port status
     423 *
     424 * @param status
     425 * @return speed of usb device (for more see usb specification)
     426 */
     427static inline usb_speed_t usb_port_speed(usb_port_status_t * status) {
     428        if (usb_port_low_speed(status))
    318429                return USB_SPEED_LOW;
    319         if(usb_port_high_speed(status))
     430        if (usb_port_high_speed(status))
    320431                return USB_SPEED_HIGH;
    321432        return USB_SPEED_FULL;
     
    324435
    325436//connect change
    326 static inline bool usb_port_connect_change(usb_port_status_t * status){
    327         return usb_port_get_bit(status,16);
    328 }
    329 
    330 static inline void usb_port_set_connect_change(usb_port_status_t * status,bool change){
    331         usb_port_set_bit(status,16,change);
     437/**
     438 * port connect change indicator
     439 *
     440 * @param status
     441 * @return true if connection has changed
     442 */
     443static inline bool usb_port_connect_change(usb_port_status_t * status) {
     444        return usb_port_get_bit(status, 16);
     445}
     446
     447static inline void usb_port_set_connect_change(usb_port_status_t * status, bool change) {
     448        usb_port_set_bit(status, 16, change);
    332449}
    333450
    334451//port enable change
    335 static inline bool usb_port_enabled_change(usb_port_status_t * status){
    336         return usb_port_get_bit(status,17);
    337 }
    338 
    339 static inline void usb_port_set_enabled_change(usb_port_status_t * status,bool change){
    340         usb_port_set_bit(status,17,change);
     452/**
     453 * port enable change for port status
     454 *
     455 * @param status
     456 * @return true if the port has been enabled/disabled
     457 */
     458static inline bool usb_port_enabled_change(usb_port_status_t * status) {
     459        return usb_port_get_bit(status, 17);
     460}
     461
     462static inline void usb_port_set_enabled_change(usb_port_status_t * status, bool change) {
     463        usb_port_set_bit(status, 17, change);
    341464}
    342465
    343466//suspend change
    344 static inline bool usb_port_suspend_change(usb_port_status_t * status){
    345         return usb_port_get_bit(status,18);
    346 }
    347 
    348 static inline void usb_port_set_suspend_change(usb_port_status_t * status,bool change){
    349         usb_port_set_bit(status,18,change);
     467/**
     468 * port suspend change for port status
     469 *
     470 * @param status
     471 * @return ture if suspend status has changed
     472 */
     473static inline bool usb_port_suspend_change(usb_port_status_t * status) {
     474        return usb_port_get_bit(status, 18);
     475}
     476
     477static inline void usb_port_set_suspend_change(usb_port_status_t * status, bool change) {
     478        usb_port_set_bit(status, 18, change);
    350479}
    351480
    352481//over current change
    353 static inline bool usb_port_overcurrent_change(usb_port_status_t * status){
    354         return usb_port_get_bit(status,19);
    355 }
    356 
    357 static inline void usb_port_set_overcurrent_change(usb_port_status_t * status,bool change){
    358         usb_port_set_bit(status,19,change);
     482/**
     483 * over current change indicator
     484 *
     485 * @param status
     486 * @return true if over-current condition on port has changed
     487 */
     488static inline bool usb_port_overcurrent_change(usb_port_status_t * status) {
     489        return usb_port_get_bit(status, 19);
     490}
     491
     492static inline void usb_port_set_overcurrent_change(usb_port_status_t * status, bool change) {
     493        usb_port_set_bit(status, 19, change);
    359494}
    360495
    361496//reset change
    362 static inline bool usb_port_reset_completed(usb_port_status_t * status){
    363         return usb_port_get_bit(status,20);
    364 }
    365 
    366 static inline void usb_port_set_reset_completed(usb_port_status_t * status,bool completed){
    367         usb_port_set_bit(status,20,completed);
    368 }
    369 
     497/**
     498 * port reset change indicator
     499 * @param status
     500 * @return true if port has been reset
     501 */
     502static inline bool usb_port_reset_completed(usb_port_status_t * status) {
     503        return usb_port_get_bit(status, 20);
     504}
     505
     506static inline void usb_port_set_reset_completed(usb_port_status_t * status, bool completed) {
     507        usb_port_set_bit(status, 20, completed);
     508}
     509
     510//local power status
     511/**
     512 * local power lost indicator for hub status
     513 *
     514 * @param status
     515 * @return true if hub is not powered
     516 */
     517static inline bool usb_hub_local_power_lost(usb_hub_status_t * status) {
     518        return usb_hub_get_bit(status, 0);
     519}
     520
     521static inline void usb_hub_set_local_power_lost(usb_port_status_t * status,
     522        bool power_lost) {
     523        usb_hub_set_bit(status, 0, power_lost);
     524}
     525
     526//over current ocndition
     527/**
     528 * hub over-current indicator
     529 *
     530 * @param status
     531 * @return true if over-current condition occurred on hub
     532 */
     533static inline bool usb_hub_over_current(usb_hub_status_t * status) {
     534        return usb_hub_get_bit(status, 1);
     535}
     536
     537static inline void usb_hub_set_over_current(usb_port_status_t * status,
     538        bool over_current) {
     539        usb_hub_set_bit(status, 1, over_current);
     540}
     541
     542//local power change
     543/**
     544 * hub power change indicator
     545 *
     546 * @param status
     547 * @return true if local power status has been changed - power has been
     548 * dropped or re-established
     549 */
     550static inline bool usb_hub_local_power_change(usb_hub_status_t * status) {
     551        return usb_hub_get_bit(status, 16);
     552}
     553
     554static inline void usb_hub_set_local_power_change(usb_port_status_t * status,
     555        bool change) {
     556        usb_hub_set_bit(status, 16, change);
     557}
     558
     559//local power status
     560/**
     561 * hub over-current condition change indicator
     562 *
     563 * @param status
     564 * @return true if over-current condition has changed
     565 */
     566static inline bool usb_hub_over_current_change(usb_hub_status_t * status) {
     567        return usb_hub_get_bit(status, 17);
     568}
     569
     570static inline void usb_hub_set_over_current_change(usb_port_status_t * status,
     571        bool change) {
     572        usb_hub_set_bit(status, 17, change);
     573}
    370574
    371575
  • TabularUnified uspace/drv/usbhub/usbhub.c

    ra82889e ra4e18e1  
    5353#include "usb/classes/classes.h"
    5454
     55
     56static int usb_hub_init_add_device(usb_hub_info_t * hub, uint16_t port,
     57        usb_speed_t speed);
     58
     59static usb_hub_info_t * usb_hub_info_create(usb_device_t * usb_dev);
     60
     61static int usb_hub_process_hub_specific_info(usb_hub_info_t * hub_info);
     62
     63static int usb_hub_set_configuration(usb_hub_info_t * hub_info);
     64
     65static int usb_hub_release_default_address(usb_hub_info_t * hub);
     66
     67static int usb_hub_init_add_device(usb_hub_info_t * hub, uint16_t port,
     68        usb_speed_t speed);
     69
     70static void usb_hub_finalize_add_device(usb_hub_info_t * hub,
     71        uint16_t port, usb_speed_t speed);
     72
     73static void usb_hub_removed_device(
     74        usb_hub_info_t * hub, uint16_t port);
     75
     76static void usb_hub_port_over_current(usb_hub_info_t * hub,
     77        uint16_t port, uint32_t status);
     78
     79static void usb_hub_process_interrupt(usb_hub_info_t * hub,
     80        uint16_t port);
     81
     82static int usb_process_hub_over_current(usb_hub_info_t * hub_info,
     83        usb_hub_status_t status);
     84
     85static int usb_process_hub_power_change(usb_hub_info_t * hub_info,
     86        usb_hub_status_t status);
     87
     88static void usb_hub_process_global_interrupt(usb_hub_info_t * hub_info);
     89
     90//static int initialize_non_removable(usb_hub_info_t * hub_info,
     91//      unsigned int port);
     92
    5593static int usb_hub_trigger_connecting_non_removable_devices(
    56                 usb_hub_info_t * hub, usb_hub_descriptor_t * descriptor);
    57 
     94        usb_hub_info_t * hub, usb_hub_descriptor_t * descriptor);
     95
     96
     97/**
     98 * control loop running in hub`s fibril
     99 *
     100 * Hub`s fibril periodically asks for changes on hub and if needded calls
     101 * change handling routine.
     102 * @warning currently hub driver asks for changes once a second
     103 * @param hub_info_param hub representation pointer
     104 * @return zero
     105 */
     106int usb_hub_control_loop(void * hub_info_param) {
     107        usb_hub_info_t * hub_info = (usb_hub_info_t*) hub_info_param;
     108        int errorCode = EOK;
     109
     110        while (errorCode == EOK) {
     111                async_usleep(1000 * 1000 * 10); /// \TODO proper number once
     112                errorCode = usb_hub_check_hub_changes(hub_info);
     113        }
     114        usb_log_error("something in ctrl loop went wrong, errno %d\n",
     115                errorCode);
     116
     117        return 0;
     118}
     119/// \TODO malloc checking
    58120
    59121//*********************************************
     
    63125//*********************************************
    64126
     127
     128
     129/**
     130 * Initialize hub device driver fibril
     131 *
     132 * Creates hub representation and fibril that periodically checks hub`s status.
     133 * Hub representation is passed to the fibril.
     134 * @param usb_dev generic usb device information
     135 * @return error code
     136 */
     137int usb_hub_add_device(usb_device_t * usb_dev) {
     138        if (!usb_dev) return EINVAL;
     139        usb_hub_info_t * hub_info = usb_hub_info_create(usb_dev);
     140        //create hc connection
     141        usb_log_debug("Initializing USB wire abstraction.\n");
     142        int opResult = usb_hc_connection_initialize_from_device(
     143                &hub_info->connection,
     144                hub_info->usb_device->ddf_dev);
     145        if (opResult != EOK) {
     146                usb_log_error("could not initialize connection to device, "
     147                        "errno %d\n",
     148                        opResult);
     149                free(hub_info);
     150                return opResult;
     151        }
     152
     153        usb_pipe_start_session(hub_info->control_pipe);
     154        //set hub configuration
     155        opResult = usb_hub_set_configuration(hub_info);
     156        if (opResult != EOK) {
     157                usb_log_error("could not set hub configuration, errno %d\n",
     158                        opResult);
     159                free(hub_info);
     160                return opResult;
     161        }
     162        //get port count and create attached_devs
     163        opResult = usb_hub_process_hub_specific_info(hub_info);
     164        if (opResult != EOK) {
     165                usb_log_error("could not set hub configuration, errno %d\n",
     166                        opResult);
     167                free(hub_info);
     168                return opResult;
     169        }
     170        usb_pipe_end_session(hub_info->control_pipe);
     171
     172
     173        /// \TODO what is this?
     174        usb_log_debug("Creating `hub' function.\n");
     175        ddf_fun_t *hub_fun = ddf_fun_create(hub_info->usb_device->ddf_dev,
     176                fun_exposed, "hub");
     177        assert(hub_fun != NULL);
     178        hub_fun->ops = NULL;
     179
     180        int rc = ddf_fun_bind(hub_fun);
     181        assert(rc == EOK);
     182        rc = ddf_fun_add_to_class(hub_fun, "hub");
     183        assert(rc == EOK);
     184
     185        //create fibril for the hub control loop
     186        fid_t fid = fibril_create(usb_hub_control_loop, hub_info);
     187        if (fid == 0) {
     188                usb_log_error("failed to start monitoring fibril for new"
     189                        " hub.\n");
     190                return ENOMEM;
     191        }
     192        fibril_add_ready(fid);
     193        usb_log_debug("Hub fibril created.\n");
     194
     195        usb_log_info("Controlling hub `%s' (%d ports).\n",
     196                hub_info->usb_device->ddf_dev->name, hub_info->port_count);
     197        return EOK;
     198}
     199
     200
     201//*********************************************
     202//
     203//  hub driver code, main loop and port handling
     204//
     205//*********************************************
     206
     207/**
     208 * check changes on hub
     209 *
     210 * Handles changes on each port with a status change.
     211 * @param hub_info hub representation
     212 * @return error code
     213 */
     214int usb_hub_check_hub_changes(usb_hub_info_t * hub_info) {
     215        int opResult;
     216        opResult = usb_pipe_start_session(
     217                hub_info->status_change_pipe);
     218        //this might not be necessary - if all non-removables are ok, it is
     219        //not needed here
     220        opResult = usb_pipe_start_session(hub_info->control_pipe);
     221        if (opResult != EOK) {
     222                usb_log_error("could not initialize communication for hub; %d\n",
     223                        opResult);
     224                return opResult;
     225        }
     226
     227        size_t port_count = hub_info->port_count;
     228        //first check non-removable devices
     229        /*
     230        {
     231                unsigned int port;
     232                for (port = 0; port < port_count; ++port) {
     233                        bool is_non_removable =
     234                                hub_info->not_initialized_non_removables[port/8]
     235                                & (1 << (port-1 % 8));
     236                        if (is_non_removable) {
     237                                opResult = initialize_non_removable(hub_info,
     238                                        port+1);
     239                        }
     240                }
     241        }
     242        */
     243
     244        /// FIXME: count properly
     245        size_t byte_length = ((port_count + 1) / 8) + 1;
     246        void *change_bitmap = malloc(byte_length);
     247        size_t actual_size;
     248
     249        /*
     250         * Send the request.
     251         */
     252        opResult = usb_pipe_read(
     253                hub_info->status_change_pipe,
     254                change_bitmap, byte_length, &actual_size
     255                );
     256
     257        if (opResult != EOK) {
     258                free(change_bitmap);
     259                usb_log_warning("something went wrong while getting the"
     260                        "status of hub\n");
     261                usb_pipe_end_session(hub_info->status_change_pipe);
     262                return opResult;
     263        }
     264        unsigned int port;
     265
     266        if (opResult != EOK) {
     267                usb_log_error("could not start control pipe session %d\n",
     268                        opResult);
     269                usb_pipe_end_session(hub_info->status_change_pipe);
     270                return opResult;
     271        }
     272        opResult = usb_hc_connection_open(&hub_info->connection);
     273        if (opResult != EOK) {
     274                usb_log_error("could not start host controller session %d\n",
     275                        opResult);
     276                usb_pipe_end_session(hub_info->control_pipe);
     277                usb_pipe_end_session(hub_info->status_change_pipe);
     278                return opResult;
     279        }
     280
     281        ///todo, opresult check, pre obe konekce
     282        bool interrupt;
     283        interrupt = ((uint8_t*)change_bitmap)[0] & 1;
     284        if(interrupt){
     285                usb_hub_process_global_interrupt(hub_info);
     286        }
     287        for (port = 1; port < port_count + 1; ++port) {
     288                interrupt =
     289                        ((uint8_t*) change_bitmap)[port / 8] & (1<<(port % 8));
     290                if (interrupt) {
     291                        usb_hub_process_interrupt(
     292                                hub_info, port);
     293                }
     294        }
     295        /// \todo check hub status
     296        usb_hc_connection_close(&hub_info->connection);
     297        usb_pipe_end_session(hub_info->control_pipe);
     298        usb_pipe_end_session(hub_info->status_change_pipe);
     299        free(change_bitmap);
     300        return EOK;
     301}
     302
     303//*********************************************
     304//
     305//  support functions
     306//
     307//*********************************************
     308
    65309/**
    66310 * create usb_hub_info_t structure
     
    72316static usb_hub_info_t * usb_hub_info_create(usb_device_t * usb_dev) {
    73317        usb_hub_info_t * result = usb_new(usb_hub_info_t);
    74         if(!result) return NULL;
     318        if (!result) return NULL;
    75319        result->usb_device = usb_dev;
    76320        result->status_change_pipe = usb_dev->pipes[0].pipe;
     
    79323        return result;
    80324}
     325
    81326
    82327/**
     
    90335 * @return error code
    91336 */
    92 static int usb_hub_process_hub_specific_info(usb_hub_info_t * hub_info){
     337static int usb_hub_process_hub_specific_info(usb_hub_info_t * hub_info) {
    93338        // get hub descriptor
    94339        usb_log_debug("creating serialized descriptor\n");
    95340        void * serialized_descriptor = malloc(USB_HUB_MAX_DESCRIPTOR_SIZE);
    96341        usb_hub_descriptor_t * descriptor;
     342        int opResult;
    97343
    98344        /* this was one fix of some bug, should not be needed anymore
    99345         * these lines allow to reset hub once more, it can be used as
    100346         * 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          */
     347         *
     348        opResult = usb_request_set_configuration(hub_info->control_pipe,
     349                1);
     350        if (opResult != EOK) {
     351                usb_log_error("could not set default configuration, errno %d",
     352                        opResult);
     353                return opResult;
     354        }*/
     355
     356
    107357        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);
     358        opResult = usb_request_get_descriptor(hub_info->control_pipe,
     359                USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_DEVICE,
     360                USB_DESCTYPE_HUB,
     361                0, 0, serialized_descriptor,
     362                USB_HUB_MAX_DESCRIPTOR_SIZE, &received_size);
     363
     364        if (opResult != EOK) {
     365                usb_log_error("failed when receiving hub descriptor, "
     366                        "badcode = %d\n",
     367                        opResult);
    117368                free(serialized_descriptor);
    118369                return opResult;
     
    120371        usb_log_debug2("deserializing descriptor\n");
    121372        descriptor = usb_deserialize_hub_desriptor(serialized_descriptor);
    122         if(descriptor==NULL){
     373        if (descriptor == NULL) {
    123374                usb_log_warning("could not deserialize descriptor \n");
    124375                return opResult;
    125376        }
    126         usb_log_debug("setting port count to %d\n",descriptor->ports_count);
     377        usb_log_debug("setting port count to %d\n", descriptor->ports_count);
    127378        hub_info->port_count = descriptor->ports_count;
    128         hub_info->ports = malloc(sizeof(usb_hub_port_t) * (hub_info->port_count+1));
    129         size_t port;
    130         for (port = 0; port < hub_info->port_count + 1; port++) {
    131                 usb_hub_port_init(&hub_info->ports[port]);
     379        /// \TODO check attached_devices array: this is not semantically correct
     380        hub_info->attached_devs = (usb_hc_attached_device_t*)
     381                malloc((hub_info->port_count + 1) *
     382                        sizeof (usb_hc_attached_device_t)
     383                );
     384        int i;
     385        for (i = 1; i <= hub_info->port_count; ++i) {
     386                hub_info->attached_devs[i].handle = 0;
     387                hub_info->attached_devs[i].address = 0;
     388                usb_log_info("powering port %d\n",i);
     389                opResult = usb_hub_set_port_feature(
     390                        hub_info->control_pipe,
     391                        i,
     392                        USB_HUB_FEATURE_PORT_POWER);
     393                if(opResult!=EOK)
     394                        usb_log_warning("could not power port %d\n",i);
     395
    132396        }
    133397        //handle non-removable devices
     
    135399        usb_log_debug2("freeing data\n");
    136400        free(serialized_descriptor);
    137         free(descriptor->devices_removable);
    138         free(descriptor);
     401        hub_info->descriptor = descriptor;
     402        hub_info->not_initialized_non_removables =
     403                (uint8_t*) malloc((hub_info->port_count + 8) / 8);
     404        memcpy(hub_info->not_initialized_non_removables,
     405                descriptor->devices_removable,
     406                (hub_info->port_count + 8) / 8
     407                );
     408
     409        //free(descriptor->devices_removable);
     410        //free(descriptor);
    139411        return EOK;
    140412}
     413
    141414/**
    142415 * Set configuration of hub
     
    147420 * @return error code
    148421 */
    149 static int usb_hub_set_configuration(usb_hub_info_t * hub_info){
     422static int usb_hub_set_configuration(usb_hub_info_t * hub_info) {
    150423        //device descriptor
    151424        usb_standard_device_descriptor_t *std_descriptor
    152             = &hub_info->usb_device->descriptors.device;
     425                = &hub_info->usb_device->descriptors.device;
    153426        usb_log_debug("hub has %d configurations\n",
    154             std_descriptor->configuration_count);
    155         if(std_descriptor->configuration_count<1){
     427                std_descriptor->configuration_count);
     428        if (std_descriptor->configuration_count < 1) {
    156429                usb_log_error("there are no configurations available\n");
    157430                return EINVAL;
     
    159432
    160433        usb_standard_configuration_descriptor_t *config_descriptor
    161             = (usb_standard_configuration_descriptor_t *)
    162             hub_info->usb_device->descriptors.configuration;
     434                = (usb_standard_configuration_descriptor_t *)
     435                hub_info->usb_device->descriptors.configuration;
    163436
    164437        /* Set configuration. */
    165438        int opResult = usb_request_set_configuration(
    166             &hub_info->usb_device->ctrl_pipe,
    167             config_descriptor->configuration_number);
     439                &hub_info->usb_device->ctrl_pipe,
     440                config_descriptor->configuration_number);
    168441
    169442        if (opResult != EOK) {
    170443                usb_log_error("Failed to set hub configuration: %s.\n",
    171                     str_error(opResult));
     444                        str_error(opResult));
    172445                return opResult;
    173446        }
    174447        usb_log_debug("\tused configuration %d\n",
    175                         config_descriptor->configuration_number);
     448                config_descriptor->configuration_number);
    176449
    177450        return EOK;
     
    179452
    180453/**
    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
     454 * release default address used by given hub
     455 *
     456 * Also unsets hub->is_default_address_used. Convenience wrapper function.
     457 * @note hub->connection MUST be open for communication
     458 * @param hub hub representation
    186459 * @return error code
    187460 */
    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",
     461static int usb_hub_release_default_address(usb_hub_info_t * hub) {
     462        int opResult = usb_hc_release_default_address(&hub->connection);
     463        if (opResult != EOK) {
     464                usb_log_error("could not release default address, errno %d\n",
     465                        opResult);
     466                return opResult;
     467        }
     468        hub->is_default_address_used = false;
     469        return EOK;
     470}
     471
     472/**
     473 * Reset the port with new device and reserve the default address.
     474 * @param hub hub representation
     475 * @param port port number, starting from 1
     476 * @param speed transfer speed of attached device, one of low, full or high
     477 * @return error code
     478 */
     479static int usb_hub_init_add_device(usb_hub_info_t * hub, uint16_t port,
     480        usb_speed_t speed) {
     481        //if this hub already uses default address, it cannot request it once more
     482        if (hub->is_default_address_used) {
     483                usb_log_info("default address used, another time\n");
     484                return EREFUSED;
     485        }
     486        usb_log_debug("some connection changed\n");
     487        assert(hub->control_pipe->hc_phone);
     488        int opResult = usb_hub_clear_port_feature(hub->control_pipe,
     489                port, USB_HUB_FEATURE_C_PORT_CONNECTION);
     490        if (opResult != EOK) {
     491                usb_log_warning("could not clear port-change-connection flag\n");
     492        }
     493        usb_device_request_setup_packet_t request;
     494
     495        //get default address
     496        opResult = usb_hc_reserve_default_address(&hub->connection, speed);
     497
     498        if (opResult != EOK) {
     499                usb_log_warning("cannot assign default address, it is probably "
     500                        "used %d\n",
     501                        opResult);
     502                return opResult;
     503        }
     504        hub->is_default_address_used = true;
     505        //reset port
     506        usb_hub_set_reset_port_request(&request, port);
     507        opResult = usb_pipe_control_write(
     508                hub->control_pipe,
     509                &request, sizeof (usb_device_request_setup_packet_t),
     510                NULL, 0
     511                );
     512        if (opResult != EOK) {
     513                usb_log_error("something went wrong when reseting a port %d\n",
     514                        opResult);
     515                usb_hub_release_default_address(hub);
     516        }
     517        return opResult;
     518}
     519
     520/**
     521 * Finalize adding new device after port reset
     522 *
     523 * Set device`s address and start it`s driver.
     524 * @param hub hub representation
     525 * @param port port number, starting from 1
     526 * @param speed transfer speed of attached device, one of low, full or high
     527 */
     528static void usb_hub_finalize_add_device(usb_hub_info_t * hub,
     529        uint16_t port, usb_speed_t speed) {
     530
     531        int opResult;
     532        usb_log_debug("finalizing add device\n");
     533        opResult = usb_hub_clear_port_feature(hub->control_pipe,
     534                port, USB_HUB_FEATURE_C_PORT_RESET);
     535
     536        if (opResult != EOK) {
     537                usb_log_error("failed to clear port reset feature\n");
     538                usb_hub_release_default_address(hub);
     539                return;
     540        }
     541        //create connection to device
     542        usb_pipe_t new_device_pipe;
     543        usb_device_connection_t new_device_connection;
     544        usb_device_connection_initialize_on_default_address(
     545                &new_device_connection,
     546                &hub->connection
     547                );
     548        usb_pipe_initialize_default_control(
     549                &new_device_pipe,
     550                &new_device_connection);
     551        usb_pipe_probe_default_control(&new_device_pipe);
     552
     553        /* Request address from host controller. */
     554        usb_address_t new_device_address = usb_hc_request_address(
     555                &hub->connection,
     556                speed
     557                );
     558        if (new_device_address < 0) {
     559                usb_log_error("failed to get free USB address\n");
     560                opResult = new_device_address;
     561                usb_hub_release_default_address(hub);
     562                return;
     563        }
     564        usb_log_debug("setting new address %d\n", new_device_address);
     565        //opResult = usb_drv_req_set_address(hc, USB_ADDRESS_DEFAULT,
     566        //    new_device_address);
     567        usb_pipe_start_session(&new_device_pipe);
     568        opResult = usb_request_set_address(&new_device_pipe,
     569                new_device_address);
     570        usb_pipe_end_session(&new_device_pipe);
     571        if (opResult != EOK) {
     572                usb_log_error("could not set address for new device %d\n",
     573                        opResult);
     574                usb_hub_release_default_address(hub);
     575                return;
     576        }
     577
     578        //opResult = usb_hub_release_default_address(hc);
     579        opResult = usb_hub_release_default_address(hub);
     580        if (opResult != EOK) {
     581                return;
     582        }
     583
     584        devman_handle_t child_handle;
     585        //??
     586        opResult = usb_device_register_child_in_devman(new_device_address,
     587                hub->connection.hc_handle, hub->usb_device->ddf_dev,
     588                &child_handle,
     589                NULL, NULL, NULL);
     590
     591        if (opResult != EOK) {
     592                usb_log_error("could not start driver for new device %d\n",
     593                        opResult);
     594                return;
     595        }
     596        hub->attached_devs[port].handle = child_handle;
     597        hub->attached_devs[port].address = new_device_address;
     598
     599        //opResult = usb_drv_bind_address(hc, new_device_address, child_handle);
     600        opResult = usb_hc_register_device(
     601                &hub->connection,
     602                &hub->attached_devs[port]);
     603        if (opResult != EOK) {
     604                usb_log_error("could not assign address of device in hcd %d\n",
     605                        opResult);
     606                return;
     607        }
     608        usb_log_info("Detected new device on `%s' (port %d), " \
     609            "address %d (handle %llu).\n",
     610                hub->usb_device->ddf_dev->name, (int) port,
     611                new_device_address, child_handle);
     612}
     613
     614/**
     615 * routine called when a device on port has been removed
     616 *
     617 * If the device on port had default address, it releases default address.
     618 * Otherwise does not do anything, because DDF does not allow to remove device
     619 * from it`s device tree.
     620 * @param hub hub representation
     621 * @param port port number, starting from 1
     622 */
     623static void usb_hub_removed_device(
     624        usb_hub_info_t * hub, uint16_t port) {
     625
     626        int opResult = usb_hub_clear_port_feature(hub->control_pipe,
     627                port, USB_HUB_FEATURE_C_PORT_CONNECTION);
     628        if (opResult != EOK) {
     629                usb_log_warning("could not clear port-change-connection flag\n");
     630        }
     631        /** \TODO remove device from device manager - not yet implemented in
     632         * devide manager
     633         */
     634
     635        //close address
     636        if (hub->attached_devs[port].address != 0) {
     637                /*uncomment this code to use it when DDF allows device removal
     638                opResult = usb_hc_unregister_device(
     639                        &hub->connection,
     640                        hub->attached_devs[port].address);
     641                if(opResult != EOK) {
     642                        dprintf(USB_LOG_LEVEL_WARNING, "could not release "
     643                                "address of "
     644                            "removed device: %d", opResult);
     645                }
     646                hub->attached_devs[port].address = 0;
     647                hub->attached_devs[port].handle = 0;
     648                 */
     649        } else {
     650                usb_log_warning("this is strange, disconnected device had "
     651                        "no address\n");
     652                //device was disconnected before it`s port was reset -
     653                //return default address
     654                usb_hub_release_default_address(hub);
     655        }
     656}
     657
     658/**
     659 * Process over current condition on port.
     660 *
     661 * Turn off the power on the port.
     662 *
     663 * @param hub hub representation
     664 * @param port port number, starting from 1
     665 */
     666static void usb_hub_port_over_current(usb_hub_info_t * hub,
     667        uint16_t port, uint32_t status) {
     668        int opResult;
     669        if(usb_port_over_current(&status)){
     670                opResult = usb_hub_clear_port_feature(hub->control_pipe,
     671                        port, USB_HUB_FEATURE_PORT_POWER);
     672                if (opResult != EOK) {
     673                        usb_log_error("cannot power off port %d;  %d\n",
     674                                port, opResult);
     675                }
     676        }else{
     677                opResult = usb_hub_set_port_feature(hub->control_pipe,
     678                        port, USB_HUB_FEATURE_PORT_POWER);
     679                if (opResult != EOK) {
     680                        usb_log_error("cannot power on port %d;  %d\n",
     681                                port, opResult);
     682                }
     683        }
     684}
     685
     686/**
     687 * Process interrupts on given hub port
     688 *
     689 * Accepts connection, over current and port reset change.
     690 * @param hub hub representation
     691 * @param port port number, starting from 1
     692 */
     693static void usb_hub_process_interrupt(usb_hub_info_t * hub,
     694        uint16_t port) {
     695        usb_log_debug("interrupt at port %d\n", port);
     696        //determine type of change
     697        usb_pipe_t *pipe = hub->control_pipe;
     698
     699        int opResult;
     700
     701        usb_port_status_t status;
     702        size_t rcvd_size;
     703        usb_device_request_setup_packet_t request;
     704        //int opResult;
     705        usb_hub_set_port_status_request(&request, port);
     706        //endpoint 0
     707
     708        opResult = usb_pipe_control_read(
     709                pipe,
     710                &request, sizeof (usb_device_request_setup_packet_t),
     711                &status, 4, &rcvd_size
     712                );
     713        if (opResult != EOK) {
     714                usb_log_error("could not get port status\n");
     715                return;
     716        }
     717        if (rcvd_size != sizeof (usb_port_status_t)) {
     718                usb_log_error("received status has incorrect size\n");
     719                return;
     720        }
     721        //something connected/disconnected
     722        if (usb_port_connect_change(&status)) {
     723                usb_log_debug("connection change on port\n");
     724                if (usb_port_dev_connected(&status)) {
     725                        usb_hub_init_add_device(hub, port,
     726                                usb_port_speed(&status));
     727                } else {
     728                        usb_hub_removed_device(hub, port);
     729                }
     730        }
     731        //over current
     732        if (usb_port_overcurrent_change(&status)) {
     733                //check if it was not auto-resolved
     734                usb_log_debug("overcurrent change on port\n");
     735                usb_hub_port_over_current(hub, port, status);
     736        }
     737        //port reset
     738        if (usb_port_reset_completed(&status)) {
     739                usb_log_debug("port reset complete\n");
     740                if (usb_port_enabled(&status)) {
     741                        usb_hub_finalize_add_device(hub, port,
     742                                usb_port_speed(&status));
     743                } else {
     744                        usb_log_warning("port reset, but port still not "
     745                                "enabled\n");
     746                }
     747        }
     748        usb_log_debug("status x%x : %d\n ", status, status);
     749
     750        usb_port_set_connect_change(&status, false);
     751        usb_port_set_reset(&status, false);
     752        usb_port_set_reset_completed(&status, false);
     753        usb_port_set_dev_connected(&status, false);
     754        usb_port_set_overcurrent_change(&status,false);
     755        /// \TODO what about port power change?
     756        if (status >> 16) {
     757                usb_log_info("there was unsupported change on port %d: %X\n",
     758                        port, status);
     759
     760        }
     761}
     762
     763/**
     764 * process hub over current change
     765 *
     766 * This means either to power off the hub or power it on.
     767 * @param hub_info hub instance
     768 * @param status hub status bitmask
     769 * @return error code
     770 */
     771static int usb_process_hub_over_current(usb_hub_info_t * hub_info,
     772        usb_hub_status_t status)
     773{
     774        int opResult;
     775        if(usb_hub_over_current(&status)){
     776                opResult = usb_hub_clear_feature(hub_info->control_pipe,
     777                        USB_HUB_FEATURE_PORT_POWER);
     778                if (opResult != EOK) {
     779                        usb_log_error("cannot power off hub: %d\n",
    198780                                opResult);
    199                 free(hub_info);
    200                 return opResult;
     781                }
     782        }else{
     783                opResult = usb_hub_set_feature(hub_info->control_pipe,
     784                        USB_HUB_FEATURE_PORT_POWER);
     785                if (opResult != EOK) {
     786                        usb_log_error("cannot power on hub: %d\n",
     787                                opResult);
     788                }
     789        }
     790        return opResult;
     791}
     792
     793/**
     794 * process hub power change
     795 *
     796 * If the power has been lost, reestablish it.
     797 * If it was reestablished, re-power all ports.
     798 * @param hub_info hub instance
     799 * @param status hub status bitmask
     800 * @return error code
     801 */
     802static int usb_process_hub_power_change(usb_hub_info_t * hub_info,
     803        usb_hub_status_t status)
     804{
     805        int opResult;
     806        if(usb_hub_local_power_lost(&status)){
     807                //restart power on hub
     808                opResult = usb_hub_set_feature(hub_info->control_pipe,
     809                        USB_HUB_FEATURE_PORT_POWER);
     810                if (opResult != EOK) {
     811                        usb_log_error("cannot power on hub: %d\n",
     812                                opResult);
     813                }
     814        }else{//power reestablished on hub- restart ports
     815                int port;
     816                for(port=0;port<hub_info->port_count;++port){
     817                        opResult = usb_hub_set_port_feature(
     818                                hub_info->control_pipe,
     819                                port, USB_HUB_FEATURE_PORT_POWER);
     820                        if (opResult != EOK) {
     821                                usb_log_error("cannot power on port %d;  %d\n",
     822                                        port, opResult);
     823                        }
     824                }
     825        }
     826        return opResult;
     827}
     828
     829/**
     830 * process hub interrupts
     831 *
     832 * The change can be either in the over-current condition or
     833 * local-power lost condition.
     834 * @param hub_info hub instance
     835 */
     836static void usb_hub_process_global_interrupt(usb_hub_info_t * hub_info){
     837        usb_log_debug("global interrupt on a hub\n");
     838        usb_pipe_t *pipe = hub_info->control_pipe;
     839        int opResult;
     840
     841        usb_port_status_t status;
     842        size_t rcvd_size;
     843        usb_device_request_setup_packet_t request;
     844        //int opResult;
     845        usb_hub_set_hub_status_request(&request);
     846        //endpoint 0
     847
     848        opResult = usb_pipe_control_read(
     849                pipe,
     850                &request, sizeof (usb_device_request_setup_packet_t),
     851                &status, 4, &rcvd_size
     852                );
     853        if (opResult != EOK) {
     854                usb_log_error("could not get hub status\n");
     855                return;
     856        }
     857        if (rcvd_size != sizeof (usb_port_status_t)) {
     858                usb_log_error("received status has incorrect size\n");
     859                return;
     860        }
     861        //port reset
     862        if (usb_hub_over_current_change(&status)) {
     863                usb_process_hub_over_current(hub_info,status);
     864        }
     865        if (usb_hub_local_power_change(&status)) {
     866                usb_process_hub_power_change(hub_info,status);
     867        }
     868}
     869
     870//-----------attempts to solve non-removable------------------------
     871//-----------attempts to solve non-removable------------------------
     872//-----------attempts to solve non-removable------------------------
     873//-----------attempts to solve non-removable------------------------
     874
     875/**
     876 * this is an attempt to initialize non-removable devices in the hub
     877 *
     878 * @param hub_info hub instance
     879 * @param port port number, counting from 1
     880 * @return error code
     881 */
     882#if 0
     883static int initialize_non_removable(usb_hub_info_t * hub_info,
     884        unsigned int port) {
     885        int opResult;
     886        usb_log_debug("there is not pluged in non-removable device on "
     887                "port %d\n", port
     888                );
     889        //usb_hub_init_add_device(hub_info, port, usb_port_speed(&status));
     890        usb_port_status_t status;
     891        size_t rcvd_size;
     892        usb_device_request_setup_packet_t request;
     893        //int opResult;
     894        usb_hub_set_port_status_request(&request, port);
     895        //endpoint 0
     896
     897        opResult = usb_pipe_control_read(
     898                hub_info->control_pipe,
     899                &request, sizeof (usb_device_request_setup_packet_t),
     900                &status, 4, &rcvd_size
     901                );
     902        if (opResult != EOK) {
     903                usb_log_error("could not get port status %d\n", opResult);
     904                return opResult;
     905        }
     906        if (rcvd_size != sizeof (usb_port_status_t)) {
     907                usb_log_error("received status has incorrect size\n");
     908                return opResult;
     909        }
     910        usb_log_debug("port status %d, x%x\n", status, status);
     911        if (usb_port_dev_connected(&status)) {
     912                usb_log_debug("there is connected device on this port\n");
     913                opResult = usb_hub_init_add_device(hub_info, port,
     914                        usb_port_speed(&status));
     915        }else{
     916                usb_log_debug("the non-removable device is not connected\n");
     917                opResult = EINVAL;
    201918        }
    202919       
    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 
    233         /*
    234          * The processing will require opened control pipe and connection
    235          * to the host controller.
    236          * It is waste of resources but let's hope there will be less
    237          * hubs than the phone limit.
    238          * FIXME: with some proper locking over pipes and session
    239          * auto destruction, this could work better.
    240          */
    241         rc = usb_pipe_start_session(&usb_dev->ctrl_pipe);
    242         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);
    250                 usb_log_error("Failed to open connection to HC: %s.\n",
    251                     str_error(rc));
    252                 goto leave;
    253         }
    254 
    255         rc = usb_device_auto_poll(hub_info->usb_device, 0,
    256             hub_port_changes_callback, ((hub_info->port_count+1) / 8) + 1,
    257             NULL, hub_info);
    258         if (rc != EOK) {
    259                 usb_log_error("Failed to create polling fibril: %s.\n",
    260                     str_error(rc));
    261                 free(hub_info);
    262                 return rc;
    263         }
    264 
    265         usb_log_info("Controlling hub `%s' (%d ports).\n",
    266             hub_info->usb_device->ddf_dev->name, hub_info->port_count);
    267         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 
     920        return opResult;
     921}
     922#endif
    282923/**
    283924 * triggers actions to connect non0removable devices
     
    289930 * @return error code
    290931 */
    291 static int usb_hub_trigger_connecting_non_removable_devices(usb_hub_info_t * hub,
    292                 usb_hub_descriptor_t * descriptor)
    293 {
     932static int usb_hub_trigger_connecting_non_removable_devices(
     933        usb_hub_info_t * hub,
     934        usb_hub_descriptor_t * descriptor) {
    294935        usb_log_info("attaching non-removable devices(if any)\n");
    295         usb_device_request_setup_packet_t request;
     936        //usb_device_request_setup_packet_t request;
    296937        int opResult;
    297         size_t rcvd_size;
    298         usb_port_status_t status;
     938        //size_t rcvd_size;
     939        //usb_port_status_t status;
    299940        uint8_t * non_removable_dev_bitmap = descriptor->devices_removable;
    300941        int port;
    301         for(port=1;port<=descriptor->ports_count;++port){
     942#if 0
     943        opResult = usb_request_set_configuration(hub->control_pipe,
     944                1);
     945        if (opResult != EOK) {
     946                usb_log_error("could not set default configuration, errno %d",
     947                        opResult);
     948                return opResult;
     949        }
     950
     951        for (port = 1; port <= descriptor->ports_count; ++port) {
    302952                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);
     953                        ((non_removable_dev_bitmap[port / 8]) >> (port % 8)) % 2;
     954                if (is_non_removable) {
     955                        usb_log_debug("non-removable device on port %d\n", port);
    306956                        usb_hub_set_port_status_request(&request, port);
    307957                        opResult = usb_pipe_control_read(
     958                                hub->control_pipe,
     959                                &request,
     960                                sizeof (usb_device_request_setup_packet_t),
     961                                &status, 4, &rcvd_size
     962                                );
     963                        if (opResult != EOK) {
     964                                usb_log_error("could not get port status of "
     965                                        "port %d errno:%d\n",
     966                                        port, opResult);
     967                                return opResult;
     968                        }
     969                        //try to reset port
     970                        if (usb_port_dev_connected(&status) || true) {
     971                                usb_hub_set_enable_port_feature_request(
     972                                        &request, port,
     973                                        USB_HUB_FEATURE_PORT_RESET);
     974                                opResult = usb_pipe_control_read(
    308975                                        hub->control_pipe,
    309                                         &request, sizeof(usb_device_request_setup_packet_t),
     976                                        &request,
     977                                        sizeof (usb_device_request_setup_packet_t),
    310978                                        &status, 4, &rcvd_size
    311979                                        );
    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                                                 );
    326980                                if (opResult != EOK) {
    327981                                        usb_log_warning(
    328                                                         "could not clear port connection on port %d errno:%d\n",
    329                                                         port, opResult);
     982                                                "could not reset port %d "
     983                                                "errno:%d\n",
     984                                                port, opResult);
     985                                }
     986                                usb_log_debug("port reset, should look like "
     987                                        "%d,x%x\n",
     988                                        (1 << USB_HUB_FEATURE_PORT_RESET),
     989                                        (1 << USB_HUB_FEATURE_PORT_RESET)
     990                                        );
     991                        }
     992                        //set the status change bit, so it will be noticed
     993                        //in driver loop
     994                        if (usb_port_dev_connected(&status) && false) {
     995                                usb_hub_set_disable_port_feature_request(
     996                                        &request, port,
     997                                        USB_HUB_FEATURE_PORT_CONNECTION);
     998                                opResult = usb_pipe_control_read(
     999                                        hub->control_pipe,
     1000                                        &request,
     1001                                        sizeof (usb_device_request_setup_packet_t),
     1002                                        &status, 4, &rcvd_size
     1003                                        );
     1004                                if (opResult != EOK) {
     1005                                        usb_log_warning(
     1006                                                "could not clear port "
     1007                                                "connection on port %d "
     1008                                                "errno:%d\n",
     1009                                                port, opResult);
    3301010                                }
    3311011                                usb_log_debug("cleared port connection\n");
    332                                 usb_hub_set_enable_port_feature_request(&request, port,
    333                                                 USB_HUB_FEATURE_PORT_ENABLE);
     1012                                usb_hub_set_enable_port_feature_request(&request,
     1013                                        port,
     1014                                        USB_HUB_FEATURE_PORT_ENABLE);
    3341015                                opResult = usb_pipe_control_read(
    335                                                 hub->control_pipe,
    336                                                 &request, sizeof(usb_device_request_setup_packet_t),
    337                                                 &status, 4, &rcvd_size
    338                                                 );
     1016                                        hub->control_pipe,
     1017                                        &request,
     1018                                        sizeof (usb_device_request_setup_packet_t),
     1019                                        &status, 4, &rcvd_size
     1020                                        );
    3391021                                if (opResult != EOK) {
    3401022                                        usb_log_warning(
    341                                                         "could not set port enabled on port %d errno:%d\n",
    342                                                         port, opResult);
     1023                                                "could not set port enabled "
     1024                                                "on port %d errno:%d\n",
     1025                                                port, opResult);
    3431026                                }
    344                                 usb_log_debug("port set to enabled - should lead to connection change\n");
     1027                                usb_log_debug("port set to enabled - "
     1028                                        "should lead to connection change\n");
    3451029                        }
    3461030                }
    3471031        }
     1032#endif
     1033
    3481034        /// \TODO this is just a debug code
    349         for(port=1;port<=descriptor->ports_count;++port){
     1035        for (port = 1; port <= descriptor->ports_count; ++port) {
    3501036                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);
     1037                        ((non_removable_dev_bitmap[(port-1) / 8]) >> ((port-1) % 8)) % 2;
     1038                if (is_non_removable) {
     1039                        usb_log_debug("CHECKING port %d is non-removable\n",
     1040                                port);
    3541041                        usb_port_status_t status;
    3551042                        size_t rcvd_size;
     
    3591046                        //endpoint 0
    3601047                        opResult = usb_pipe_control_read(
    361                                         hub->control_pipe,
    362                                         &request, sizeof(usb_device_request_setup_packet_t),
    363                                         &status, 4, &rcvd_size
    364                                         );
     1048                                hub->control_pipe,
     1049                                &request,
     1050                                sizeof (usb_device_request_setup_packet_t),
     1051                                &status, 4, &rcvd_size
     1052                                );
    3651053                        if (opResult != EOK) {
    366                                 usb_log_error("could not get port status %d\n",opResult);
     1054                                usb_log_error("could not get port status %d\n",
     1055                                        opResult);
    3671056                        }
    3681057                        if (rcvd_size != sizeof (usb_port_status_t)) {
    369                                 usb_log_error("received status has incorrect size\n");
     1058                                usb_log_error("received status has incorrect"
     1059                                        " size\n");
    3701060                        }
    3711061                        //something connected/disconnected
     
    3731063                                usb_log_debug("some connection changed\n");
    3741064                        }
    375                         usb_log_debug("status: %s\n",usb_debug_str_buffer(
    376                                         (uint8_t *)&status,4,4));
    377                 }
    378         }
     1065                        if(usb_port_dev_connected(&status)){
     1066                                usb_log_debug("device connected on port\n");
     1067                        }
     1068                        usb_log_debug("status: %s\n", usb_debug_str_buffer(
     1069                                (uint8_t *) & status, 4, 4));
     1070                }
     1071        }
     1072        async_usleep(1000*1000*10);
    3791073        return EOK;
    3801074}
     
    3821076
    3831077/**
    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 
    461 
    462 /**
    4631078 * @}
    4641079 */
  • TabularUnified uspace/drv/usbhub/usbhub.h

    ra82889e ra4e18e1  
    4343
    4444#include <usb/hub.h>
     45#include <usb/classes/hub.h>
    4546
    4647#include <usb/pipes.h>
    4748#include <usb/devdrv.h>
    4849
    49 #include "ports.h"
    50 
    51 
    52 
    5350/** Information about attached hub. */
    5451typedef struct {
    5552        /** Number of ports. */
    56         size_t port_count;
     53        int port_count;
    5754
    58         /** Ports. */
    59         usb_hub_port_t *ports;
    60        
     55        /** attached device handles, for each port one */
     56        usb_hc_attached_device_t * attached_devs;
     57
    6158        /** connection to hcd */
    6259        usb_hc_connection_t connection;
     
    8784        /** generic usb device data*/
    8885        usb_device_t * usb_device;
     86
     87        /** usb hub specific descriptor */
     88        usb_hub_descriptor_t * descriptor;
     89
     90        /** not yet initialized non-removable devices */
     91        uint8_t * not_initialized_non_removables;
     92       
    8993} usb_hub_info_t;
    9094
     
    9498 */
    9599int usb_hub_control_loop(void * hub_info_param);
     100
     101int usb_hub_add_device(usb_device_t * usb_dev);
    96102
    97103/**
     
    103109int usb_hub_check_hub_changes(usb_hub_info_t * hub_info_param);
    104110
    105 void usb_hub_removed_device(usb_hub_info_t *, uint16_t);
    106 void usb_hub_over_current(usb_hub_info_t *, uint16_t);
    107 
    108 int usb_hub_add_device(usb_device_t * usb_dev);
    109111
    110112#endif
  • TabularUnified uspace/drv/usbhub/usbhub_private.h

    ra82889e ra4e18e1  
    3838
    3939#include "usbhub.h"
     40#include "usblist.h"
    4041
    4142#include <adt/list.h>
     
    110111
    111112/**
     113 * Clear feature on hub port.
     114 *
     115 * @param hc Host controller telephone
     116 * @param address Hub address
     117 * @param port_index Port
     118 * @param feature Feature selector
     119 * @return Operation result
     120 */
     121static inline int usb_hub_set_port_feature(usb_pipe_t *pipe,
     122    int port_index,
     123    usb_hub_class_feature_t feature) {
     124
     125        usb_device_request_setup_packet_t clear_request = {
     126                .request_type = USB_HUB_REQ_TYPE_CLEAR_PORT_FEATURE,
     127                .request = USB_DEVREQ_SET_FEATURE,
     128                .length = 0,
     129                .index = port_index
     130        };
     131        clear_request.value = feature;
     132        return usb_pipe_control_write(pipe, &clear_request,
     133            sizeof(clear_request), NULL, 0);
     134}
     135
     136
     137/**
     138 * Clear feature on hub port.
     139 *
     140 * @param pipe pipe to hub control endpoint
     141 * @param feature Feature selector
     142 * @return Operation result
     143 */
     144static inline int usb_hub_clear_feature(usb_pipe_t *pipe,
     145    usb_hub_class_feature_t feature) {
     146
     147        usb_device_request_setup_packet_t clear_request = {
     148                .request_type = USB_HUB_REQ_TYPE_CLEAR_HUB_FEATURE,
     149                .request = USB_DEVREQ_CLEAR_FEATURE,
     150                .length = 0,
     151                .index = 0
     152        };
     153        clear_request.value = feature;
     154        return usb_pipe_control_write(pipe, &clear_request,
     155            sizeof(clear_request), NULL, 0);
     156}
     157
     158/**
     159 * Clear feature on hub port.
     160 *
     161 * @param pipe pipe to hub control endpoint
     162 * @param feature Feature selector
     163 * @return Operation result
     164 */
     165static inline int usb_hub_set_feature(usb_pipe_t *pipe,
     166    usb_hub_class_feature_t feature) {
     167
     168        usb_device_request_setup_packet_t clear_request = {
     169                .request_type = USB_HUB_REQ_TYPE_CLEAR_HUB_FEATURE,
     170                .request = USB_DEVREQ_SET_FEATURE,
     171                .length = 0,
     172                .index = 0
     173        };
     174        clear_request.value = feature;
     175        return usb_pipe_control_write(pipe, &clear_request,
     176            sizeof(clear_request), NULL, 0);
     177}
     178
     179/**
    112180 * create uint8_t array with serialized descriptor
    113181 *
Note: See TracChangeset for help on using the changeset viewer.