Changes in / [a4e18e1:a82889e] in mainline


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

Legend:

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

    ra4e18e1 ra82889e  
    4747 *      standart device descriptor for ohci root hub
    4848 */
    49 static 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,
     49static 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,
    6465};
    6566
     
    6869 * for ohci root hubs
    6970 */
    70 static const usb_standard_configuration_descriptor_t ohci_rh_conf_descriptor = {
     71static const usb_standard_configuration_descriptor_t ohci_rh_conf_descriptor =
     72{
    7173        /// \TODO some values are default or guessed
    72         .attributes = 1 << 7,
     74        .attributes = 1<<7,
    7375        .configuration_number = 1,
    7476        .descriptor_type = USB_DESCTYPE_CONFIGURATION,
    7577        .interface_count = 1,
    76         .length = sizeof (usb_standard_configuration_descriptor_t),
     78        .length = sizeof(usb_standard_configuration_descriptor_t),
    7779        .max_power = 100,
    7880        .str_configuration = 0,
     
    8284 * standart ohci root hub interface descriptor
    8385 */
    84 static const usb_standard_interface_descriptor_t ohci_rh_iface_descriptor = {
     86static const usb_standard_interface_descriptor_t ohci_rh_iface_descriptor =
     87{
    8588        .alternate_setting = 0,
    8689        .descriptor_type = USB_DESCTYPE_INTERFACE,
     
    9194        .interface_protocol = 0,
    9295        .interface_subclass = 0,
    93         .length = sizeof (usb_standard_interface_descriptor_t),
     96        .length = sizeof(usb_standard_interface_descriptor_t),
    9497        .str_interface = 0,
    9598};
     
    98101 * standart ohci root hub endpoint descriptor
    99102 */
    100 static const usb_standard_endpoint_descriptor_t ohci_rh_ep_descriptor = {
     103static const usb_standard_endpoint_descriptor_t ohci_rh_ep_descriptor =
     104{
    101105        .attributes = USB_TRANSFER_INTERRUPT,
    102106        .descriptor_type = USB_DESCTYPE_ENDPOINT,
    103         .endpoint_address = 1 + (1 << 7),
    104         .length = sizeof (usb_standard_endpoint_descriptor_t),
     107        .endpoint_address = 1 + (1<<7),
     108        .length = sizeof(usb_standard_endpoint_descriptor_t),
    105109        .max_packet_size = 8,
    106110        .poll_interval = 255,
     
    108112
    109113static const uint32_t hub_clear_feature_valid_mask =
    110         (1 << USB_HUB_FEATURE_C_HUB_LOCAL_POWER) |
    111 (1 << USB_HUB_FEATURE_C_HUB_OVER_CURRENT);
     114        (1 << USB_HUB_FEATURE_C_HUB_LOCAL_POWER) +
     115        (1 << USB_HUB_FEATURE_C_HUB_OVER_CURRENT);
    112116
    113117static const uint32_t hub_clear_feature_by_writing_one_mask =
     
    117121        (1 << USB_HUB_FEATURE_C_HUB_OVER_CURRENT);
    118122
    119 
     123       
    120124static const uint32_t hub_set_feature_direct_mask =
    121125        (1 << USB_HUB_FEATURE_C_HUB_OVER_CURRENT);
    122126
    123127static const uint32_t port_set_feature_valid_mask =
    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);
     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);
    128132
    129133static const uint32_t port_clear_feature_valid_mask =
    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 
    142 static 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 
    150 static void usb_create_serialized_hub_descriptor(rh_t *instance,
    151         uint8_t ** out_result,
    152         size_t * out_size);
    153 
    154 static void rh_init_descriptors(rh_t *instance);
    155 
    156 static int process_get_port_status_request(rh_t *instance, uint16_t port,
    157         usb_transfer_batch_t * request);
    158 
    159 static int process_get_hub_status_request(rh_t *instance,
    160         usb_transfer_batch_t * request);
    161 
    162 static int process_get_status_request(rh_t *instance,
    163         usb_transfer_batch_t * request);
    164 
    165 static void create_interrupt_mask(rh_t *instance, void ** buffer,
    166         size_t * buffer_size);
    167 
    168 static int process_get_descriptor_request(rh_t *instance,
    169         usb_transfer_batch_t *request);
    170 
    171 static int process_get_configuration_request(rh_t *instance,
    172         usb_transfer_batch_t *request);
    173 
    174 static int process_hub_feature_set_request(rh_t *instance, uint16_t feature);
    175 
    176 static int process_hub_feature_clear_request(rh_t *instance,
    177         uint16_t feature);
    178 
    179 static int process_port_feature_set_request(rh_t *instance,
    180         uint16_t feature, uint16_t port);
    181 
    182 static int process_port_feature_clear_request(rh_t *instance,
    183         uint16_t feature, uint16_t port);
    184 
    185 static int process_address_set_request(rh_t *instance,
    186         uint16_t address);
    187 
    188 static int process_request_with_output(rh_t *instance,
    189         usb_transfer_batch_t *request);
    190 
    191 static int process_request_with_input(rh_t *instance,
    192         usb_transfer_batch_t *request);
    193 
    194 static int process_request_without_data(rh_t *instance,
    195         usb_transfer_batch_t *request);
    196 
    197 static 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  */
    206 int 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  */
    233 int 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 
    258 void 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 /*----------------------------------------------------------------------------*/
     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
    264147
    265148/**
     
    274157 */
    275158static void usb_create_serialized_hub_descriptor(rh_t *instance,
    276         uint8_t ** out_result,
    277         size_t * out_size) {
     159                uint8_t ** out_result,
     160                size_t * out_size) {
    278161        //base size
    279162        size_t size = 7;
    280163        //variable size according to port count
    281164        size_t var_size = instance->port_count / 8 +
    282                 ((instance->port_count % 8 > 0) ? 1 : 0);
     165                        ((instance->port_count % 8 > 0) ? 1 : 0);
    283166        size += 2 * var_size;
    284167        uint8_t * result = (uint8_t*) malloc(size);
    285         bzero(result, size);
     168        bzero(result,size);
    286169        //size
    287170        result[0] = size;
     
    291174        uint32_t hub_desc_reg = instance->registers->rh_desc_a;
    292175        result[3] =
    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);
     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);
    298181        result[4] = 0;
    299182        result[5] = /*descriptor->pwr_on_2_good_time*/ 50;
     
    302185        int port;
    303186        for (port = 1; port <= instance->port_count; ++port) {
    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);
     187                result[7 + port/8] +=
     188                                ((instance->registers->rh_desc_b >> port)%2) << (port%8);
    308189        }
    309190        size_t i;
     
    314195        (*out_size) = size;
    315196}
    316 /*----------------------------------------------------------------------------*/
     197
    317198
    318199/** initialize hub descriptors
     
    322203 * @instance root hub instance
    323204 */
    324 static void rh_init_descriptors(rh_t *instance) {
     205static void rh_init_descriptors(rh_t *instance){
    325206        memcpy(&instance->descriptors.device, &ohci_rh_device_descriptor,
    326                 sizeof (ohci_rh_device_descriptor)
    327                 );
     207                sizeof(ohci_rh_device_descriptor)
     208        );
    328209        usb_standard_configuration_descriptor_t descriptor;
    329         memcpy(&descriptor, &ohci_rh_conf_descriptor,
    330                 sizeof (ohci_rh_conf_descriptor));
     210        memcpy(&descriptor,&ohci_rh_conf_descriptor,
     211                        sizeof(ohci_rh_conf_descriptor));
    331212        uint8_t * hub_descriptor;
    332213        size_t hub_desc_size;
    333214        usb_create_serialized_hub_descriptor(instance, &hub_descriptor,
    334                 &hub_desc_size);
     215                        &hub_desc_size);
    335216
    336217        descriptor.total_length =
    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 
     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       
    342223        uint8_t * full_config_descriptor =
    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 
     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       
    355236        instance->descriptors.configuration = full_config_descriptor;
    356237        instance->descriptors.configuration_size = descriptor.total_length;
    357238}
     239
     240/** Root hub initialization
     241 * @return Error code.
     242 */
     243int 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}
    358261/*----------------------------------------------------------------------------*/
    359262
     
    369272 */
    370273static int process_get_port_status_request(rh_t *instance, uint16_t port,
    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;
     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;
    375278        request->transfered_size = 4;
    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 /*----------------------------------------------------------------------------*/
     279        uint32_buffer[0] = instance->registers->rh_port_status[port -1];
     280        return EOK;
     281}
    388282
    389283/**
     
    397291 */
    398292static int process_get_hub_status_request(rh_t *instance,
    399         usb_transfer_batch_t * request) {
    400         uint32_t * uint32_buffer = (uint32_t*) request->transport_buffer;
     293                usb_transfer_batch_t * request){
     294        uint32_t * uint32_buffer = (uint32_t*)request->transport_buffer;
     295        //bits, 0,1,16,17
    401296        request->transfered_size = 4;
    402         //bits, 0,1,16,17
    403         uint32_t mask = 1 | (1 << 1) | (1 << 16) | (1 << 17);
     297        uint32_t mask = 1 & (1<<1) & (1<<16) & (1<<17);
    404298        uint32_buffer[0] = mask & instance->registers->rh_status;
    405299        return EOK;
    406 }
    407 /*----------------------------------------------------------------------------*/
     300
     301}
     302
     303
    408304
    409305/**
     
    417313 */
    418314static int process_get_status_request(rh_t *instance,
    419         usb_transfer_batch_t * request) {
     315                usb_transfer_batch_t * request)
     316{
    420317        size_t buffer_size = request->buffer_size;
    421318        usb_device_request_setup_packet_t * request_packet =
    422                 (usb_device_request_setup_packet_t*)
    423                 request->setup_buffer;
     319                        (usb_device_request_setup_packet_t*)
     320                        request->setup_buffer;
    424321
    425322        usb_hub_bm_request_type_t request_type = request_packet->request_type;
    426         if (buffer_size < 4/*request_packet->length*/) {///\TODO
     323        if(buffer_size<4/*request_packet->length*/){///\TODO
    427324                usb_log_warning("requested more data than buffer size\n");
    428325                return EINVAL;
    429326        }
    430327
    431         if (request_type == USB_HUB_REQ_TYPE_GET_HUB_STATUS)
     328        if(request_type == USB_HUB_REQ_TYPE_GET_HUB_STATUS)
    432329                return process_get_hub_status_request(instance, 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);
     330        if(request_type == USB_HUB_REQ_TYPE_GET_PORT_STATUS)
     331                return process_get_port_status_request(instance, request_packet->index,
     332                                request);
    437333        return ENOTSUP;
    438334}
    439 /*----------------------------------------------------------------------------*/
    440335
    441336/**
     
    444339 * Result contains bitmap where bit 0 indicates change on hub and
    445340 * bit i indicates change on i`th port (i>0). For more info see
    446  * Hub and Port status bitmap specification in USB specification
    447  * (chapter 11.13.4)
     341 * Hub and Port status bitmap specification in USB specification.
    448342 * @param instance root hub instance
    449343 * @param@out buffer pointer to created interrupt mas
     
    451345 */
    452346static void create_interrupt_mask(rh_t *instance, void ** buffer,
    453         size_t * buffer_size) {
     347                size_t * buffer_size){
    454348        int bit_count = instance->port_count + 1;
    455         (*buffer_size) = (bit_count / 8) + ((bit_count % 8 == 0) ? 0 : 1);
    456 
     349        (*buffer_size) = (bit_count / 8) + (bit_count%8==0)?0:1;
    457350        (*buffer) = malloc(*buffer_size);
    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) {
     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){
    463355                bitmap[0] = 1;
    464356        }
    465357        int port;
    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 
     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 
    475369/**
    476370 * create answer to a descriptor request
     
    483377 */
    484378static int process_get_descriptor_request(rh_t *instance,
    485         usb_transfer_batch_t *request) {
     379                usb_transfer_batch_t *request){
    486380        usb_device_request_setup_packet_t * setup_request =
    487                 (usb_device_request_setup_packet_t*) request->setup_buffer;
     381                        (usb_device_request_setup_packet_t*)request->setup_buffer;
    488382        size_t size;
    489383        const void * result_descriptor = NULL;
    490384        const uint16_t setup_request_value = setup_request->value_high;
    491         //(setup_request->value_low << 8);
     385                        //(setup_request->value_low << 8);
    492386        bool del = false;
    493         switch (setup_request_value) {
    494                 case USB_DESCTYPE_HUB:
    495                 {
     387        switch (setup_request_value)
     388        {
     389                case USB_DESCTYPE_HUB: {
    496390                        uint8_t * descriptor;
    497391                        usb_create_serialized_hub_descriptor(
    498392                                instance, &descriptor, &size);
    499393                        result_descriptor = descriptor;
    500                         if (result_descriptor) del = true;
     394                        if(result_descriptor) del = true;
    501395                        break;
    502396                }
    503                 case USB_DESCTYPE_DEVICE:
    504                 {
     397                case USB_DESCTYPE_DEVICE: {
    505398                        usb_log_debug("USB_DESCTYPE_DEVICE\n");
    506399                        result_descriptor = &ohci_rh_device_descriptor;
    507                         size = sizeof (ohci_rh_device_descriptor);
     400                        size = sizeof(ohci_rh_device_descriptor);
    508401                        break;
    509402                }
    510                 case USB_DESCTYPE_CONFIGURATION:
    511                 {
     403                case USB_DESCTYPE_CONFIGURATION: {
    512404                        usb_log_debug("USB_DESCTYPE_CONFIGURATION\n");
    513405                        result_descriptor = instance->descriptors.configuration;
     
    515407                        break;
    516408                }
    517                 case USB_DESCTYPE_INTERFACE:
    518                 {
     409                case USB_DESCTYPE_INTERFACE: {
    519410                        usb_log_debug("USB_DESCTYPE_INTERFACE\n");
    520411                        result_descriptor = &ohci_rh_iface_descriptor;
    521                         size = sizeof (ohci_rh_iface_descriptor);
     412                        size = sizeof(ohci_rh_iface_descriptor);
    522413                        break;
    523414                }
    524                 case USB_DESCTYPE_ENDPOINT:
    525                 {
     415                case USB_DESCTYPE_ENDPOINT: {
    526416                        usb_log_debug("USB_DESCTYPE_ENDPOINT\n");
    527417                        result_descriptor = &ohci_rh_ep_descriptor;
    528                         size = sizeof (ohci_rh_ep_descriptor);
     418                        size = sizeof(ohci_rh_ep_descriptor);
    529419                        break;
    530420                }
    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                                 );
     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                                        );
    543430                        return EINVAL;
    544431                }
    545432        }
    546         if (request->buffer_size < size) {
     433        if(request->buffer_size < size){
    547434                size = request->buffer_size;
    548435        }
    549436        request->transfered_size = size;
    550         memcpy(request->transport_buffer, result_descriptor, 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));
    551440        if (del)
    552441                free(result_descriptor);
    553442        return EOK;
    554443}
    555 /*----------------------------------------------------------------------------*/
    556444
    557445/**
     
    563451 * @return error code
    564452 */
    565 static int process_get_configuration_request(rh_t *instance,
    566         usb_transfer_batch_t *request) {
     453static int process_get_configuration_request(rh_t *instance, 
     454                usb_transfer_batch_t *request){
    567455        //set and get configuration requests do not have any meaning, only dummy
    568456        //values are returned
    569         if (request->buffer_size != 1)
     457        if(request->buffer_size != 1)
    570458                return EINVAL;
    571459        request->transport_buffer[0] = 1;
     
    573461        return EOK;
    574462}
    575 /*----------------------------------------------------------------------------*/
    576463
    577464/**
    578465 * process feature-enabling request on hub
    579  *
     466 * 
    580467 * @param instance root hub instance
    581468 * @param feature feature selector
     
    583470 */
    584471static int process_hub_feature_set_request(rh_t *instance,
    585         uint16_t feature) {
    586         if (!((1 << feature) & hub_set_feature_valid_mask))
     472                uint16_t feature){
     473        if(! ((1<<feature) & hub_set_feature_valid_mask))
    587474                return EINVAL;
    588475        instance->registers->rh_status =
    589                 (instance->registers->rh_status | (1 << feature))
    590                 & (~hub_clear_feature_by_writing_one_mask);
    591         return EOK;
    592 }
    593 /*----------------------------------------------------------------------------*/
     476                        (instance->registers->rh_status | (1<<feature))
     477                        & (~ hub_clear_feature_by_writing_one_mask);
     478        return EOK;
     479}
    594480
    595481/**
     
    601487 */
    602488static int process_hub_feature_clear_request(rh_t *instance,
    603         uint16_t feature) {
    604         if (!((1 << feature) & hub_clear_feature_valid_mask))
     489                uint16_t feature){
     490        if(! ((1<<feature) & hub_clear_feature_valid_mask))
    605491                return EINVAL;
    606492        //is the feature cleared directly?
    607         if ((1 << feature) & hub_set_feature_direct_mask) {
     493        if ((1<<feature) & hub_set_feature_direct_mask){
    608494                instance->registers->rh_status =
    609                         (instance->registers->rh_status & (~(1 << feature)))
    610                         & (~hub_clear_feature_by_writing_one_mask);
    611         } else {//the feature is cleared by writing '1'
     495                        (instance->registers->rh_status & (~(1<<feature)))
     496                        & (~ hub_clear_feature_by_writing_one_mask);
     497        }else{//the feature is cleared by writing '1'
    612498                instance->registers->rh_status =
    613                         (instance->registers->rh_status
    614                         & (~hub_clear_feature_by_writing_one_mask))
    615                         | (1 << feature);
    616         }
    617         return EOK;
    618 }
    619 /*----------------------------------------------------------------------------*/
     499                                (instance->registers->rh_status
     500                                & (~ hub_clear_feature_by_writing_one_mask))
     501                                | (1<<feature);
     502        }
     503        return EOK;
     504}
     505
     506
    620507
    621508/**
    622509 * process feature-enabling request on hub
    623  *
     510 * 
    624511 * @param instance root hub instance
    625512 * @param feature feature selector
     
    629516 */
    630517static int process_port_feature_set_request(rh_t *instance,
    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)
     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)
    635522                return EINVAL;
    636523        instance->registers->rh_port_status[port - 1] =
    637                 (instance->registers->rh_port_status[port - 1] | (1 << feature))
    638                 & (~port_clear_feature_valid_mask);
     524                        (instance->registers->rh_port_status[port - 1] | (1<<feature))
     525                        & (~port_clear_feature_valid_mask);
    639526        /// \TODO any error?
    640527        return EOK;
    641528}
    642 /*----------------------------------------------------------------------------*/
    643529
    644530/**
     
    652538 */
    653539static int process_port_feature_clear_request(rh_t *instance,
    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)
     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)
    660546                feature = USB_HUB_FEATURE_PORT_LOW_SPEED;
    661         if (feature == USB_HUB_FEATURE_PORT_SUSPEND)
     547        if(feature == USB_HUB_FEATURE_PORT_SUSPEND)
    662548                feature = USB_HUB_FEATURE_PORT_OVER_CURRENT;
    663549        instance->registers->rh_port_status[port - 1] =
    664                 (instance->registers->rh_port_status[port - 1]
    665                 & (~port_clear_feature_valid_mask))
    666                 | (1 << feature);
     550                        (instance->registers->rh_port_status[port - 1]
     551                        & (~port_clear_feature_valid_mask))
     552                        | (1<<feature);
    667553        /// \TODO any error?
    668554        return EOK;
    669555}
    670 /*----------------------------------------------------------------------------*/
     556
    671557
    672558/**
    673559 * register address to this device
    674  *
     560 * 
    675561 * @param instance root hub instance
    676562 * @param address new address
     
    678564 */
    679565static int process_address_set_request(rh_t *instance,
    680         uint16_t address) {
     566                uint16_t address){
    681567        instance->address = address;
    682568        return EOK;
    683569}
    684 /*----------------------------------------------------------------------------*/
    685570
    686571/**
     
    694579 */
    695580static int process_request_with_output(rh_t *instance,
    696         usb_transfer_batch_t *request) {
     581                usb_transfer_batch_t *request){
    697582        usb_device_request_setup_packet_t * setup_request =
    698                 (usb_device_request_setup_packet_t*) request->setup_buffer;
    699         if (setup_request->request == USB_DEVREQ_GET_STATUS) {
     583                        (usb_device_request_setup_packet_t*)request->setup_buffer;
     584        if(setup_request->request == USB_DEVREQ_GET_STATUS){
    700585                usb_log_debug("USB_DEVREQ_GET_STATUS\n");
    701586                return process_get_status_request(instance, request);
    702587        }
    703         if (setup_request->request == USB_DEVREQ_GET_DESCRIPTOR) {
     588        if(setup_request->request == USB_DEVREQ_GET_DESCRIPTOR){
    704589                usb_log_debug("USB_DEVREQ_GET_DESCRIPTOR\n");
    705590                return process_get_descriptor_request(instance, request);
    706591        }
    707         if (setup_request->request == USB_DEVREQ_GET_CONFIGURATION) {
     592        if(setup_request->request == USB_DEVREQ_GET_CONFIGURATION){
    708593                usb_log_debug("USB_DEVREQ_GET_CONFIGURATION\n");
    709594                return process_get_configuration_request(instance, request);
     
    711596        return ENOTSUP;
    712597}
    713 /*----------------------------------------------------------------------------*/
    714598
    715599/**
     
    723607 */
    724608static int process_request_with_input(rh_t *instance,
    725         usb_transfer_batch_t *request) {
     609                usb_transfer_batch_t *request){
    726610        usb_device_request_setup_packet_t * setup_request =
    727                 (usb_device_request_setup_packet_t*) request->setup_buffer;
     611                        (usb_device_request_setup_packet_t*)request->setup_buffer;
    728612        request->transfered_size = 0;
    729         if (setup_request->request == USB_DEVREQ_SET_DESCRIPTOR) {
     613        if(setup_request->request == USB_DEVREQ_SET_DESCRIPTOR){
    730614                return ENOTSUP;
    731615        }
    732         if (setup_request->request == USB_DEVREQ_SET_CONFIGURATION) {
     616        if(setup_request->request == USB_DEVREQ_SET_CONFIGURATION){
    733617                //set and get configuration requests do not have any meaning,
    734618                //only dummy values are returned
     
    737621        return ENOTSUP;
    738622}
    739 /*----------------------------------------------------------------------------*/
    740623
    741624/**
     
    749632 */
    750633static int process_request_without_data(rh_t *instance,
    751         usb_transfer_batch_t *request) {
     634                usb_transfer_batch_t *request){
    752635        usb_device_request_setup_packet_t * setup_request =
    753                 (usb_device_request_setup_packet_t*) request->setup_buffer;
     636                        (usb_device_request_setup_packet_t*)request->setup_buffer;
    754637        request->transfered_size = 0;
    755         if (setup_request->request == USB_DEVREQ_CLEAR_FEATURE) {
    756                 if (setup_request->request_type == USB_HUB_REQ_TYPE_SET_HUB_FEATURE) {
     638        if(setup_request->request == USB_DEVREQ_CLEAR_FEATURE){
     639                if(setup_request->request_type == USB_HUB_REQ_TYPE_SET_HUB_FEATURE){
    757640                        usb_log_debug("USB_HUB_REQ_TYPE_SET_HUB_FEATURE\n");
    758641                        return process_hub_feature_clear_request(instance,
    759                                 setup_request->value);
    760                 }
    761                 if (setup_request->request_type == USB_HUB_REQ_TYPE_SET_PORT_FEATURE) {
     642                                        setup_request->value);
     643                }
     644                if(setup_request->request_type == USB_HUB_REQ_TYPE_SET_PORT_FEATURE){
    762645                        usb_log_debug("USB_HUB_REQ_TYPE_SET_PORT_FEATURE\n");
    763646                        return process_port_feature_clear_request(instance,
    764                                 setup_request->value,
    765                                 setup_request->index);
     647                                        setup_request->value,
     648                                        setup_request->index);
    766649                }
    767650                usb_log_debug("USB_HUB_REQ_TYPE_INVALID %d\n",
    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) {
     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){
    773656                        usb_log_debug("USB_HUB_REQ_TYPE_SET_HUB_FEATURE\n");
    774657                        return process_hub_feature_set_request(instance,
    775                                 setup_request->value);
    776                 }
    777                 if (setup_request->request_type == USB_HUB_REQ_TYPE_SET_PORT_FEATURE) {
     658                                        setup_request->value);
     659                }
     660                if(setup_request->request_type == USB_HUB_REQ_TYPE_SET_PORT_FEATURE){
    778661                        usb_log_debug("USB_HUB_REQ_TYPE_SET_PORT_FEATURE\n");
    779662                        return process_port_feature_set_request(instance,
    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) {
     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){
    788670                usb_log_debug("USB_DEVREQ_SET_ADDRESS\n");
    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);
     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);
    794674        return ENOTSUP;
    795675}
    796 /*----------------------------------------------------------------------------*/
    797676
    798677/**
     
    814693 * @return error code
    815694 */
    816 static int process_ctrl_request(rh_t *instance, usb_transfer_batch_t *request) {
    817         if (!request->setup_buffer) {
     695static int process_ctrl_request(rh_t *instance, usb_transfer_batch_t *request){
     696        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                ){
     711                        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                                        );
     729                        opResult = ENOTSUP;
     730                }
     731        }else{
    818732                usb_log_error("root hub received empty transaction?");
    819                 return EINVAL;
    820         }
     733                opResult = EINVAL;
     734        }
     735        return opResult;
     736}
     737
     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 */
     745int rh_request(rh_t *instance, usb_transfer_batch_t *request)
     746{
     747        assert(instance);
     748        assert(request);
    821749        int opResult;
    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:
    836                         usb_log_debug("processing request with output\n");
    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                                 );
    860                         opResult = ENOTSUP;
    861         }
    862         return opResult;
    863 }
    864 
    865 
    866 
    867 
     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
     769void 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}
    868774/**
    869775 * @}
  • uspace/drv/usbhub/Makefile

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

    ra4e18e1 ra82889e  
    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  */
    58 typedef uint32_t usb_hub_status_t;
    59 
    60 /**
    6151 * set values in request to be it a port status request
    6252 * @param request
     
    6454 */
    6555static inline void usb_hub_set_port_status_request(
    66         usb_device_request_setup_packet_t * request, uint16_t port
    67         ) {
     56usb_device_request_setup_packet_t * request, uint16_t port
     57){
    6858        request->index = port;
    6959        request->request_type = USB_HUB_REQ_TYPE_GET_PORT_STATUS;
     
    7363}
    7464
    75 /**
    76  * set values in request to be it a port status request
    77  * @param request
    78  * @param port
    79  */
    80 static 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 }
    8965
    9066/**
     
    9470 */
    9571static inline usb_device_request_setup_packet_t *
    96 usb_hub_create_port_status_request(uint16_t port) {
     72usb_hub_create_port_status_request(uint16_t port){
    9773        usb_device_request_setup_packet_t * result =
    9874                usb_new(usb_device_request_setup_packet_t);
    99         usb_hub_set_port_status_request(result, port);
     75        usb_hub_set_port_status_request(result,port);
    10076        return result;
    10177}
    10278
     79
    10380/**
    10481 * set the device request to be a port feature enable request
     
    10885 */
    10986static inline void usb_hub_set_enable_port_feature_request(
    110         usb_device_request_setup_packet_t * request, uint16_t port,
    111         uint16_t feature_selector
    112         ) {
     87usb_device_request_setup_packet_t * request, uint16_t port,
     88                uint16_t feature_selector
     89){
    11390        request->index = port;
    11491        request->request_type = USB_HUB_REQ_TYPE_SET_PORT_FEATURE;
     
    125102 */
    126103static inline void usb_hub_set_disable_port_feature_request(
    127         usb_device_request_setup_packet_t * request, uint16_t port,
    128         uint16_t feature_selector
    129         ) {
     104usb_device_request_setup_packet_t * request, uint16_t port,
     105                uint16_t feature_selector
     106){
    130107        request->index = port;
    131108        request->request_type = USB_HUB_REQ_TYPE_SET_PORT_FEATURE;
     
    141118 */
    142119static inline void usb_hub_set_enable_port_request(
    143         usb_device_request_setup_packet_t * request, uint16_t port
    144         ) {
     120usb_device_request_setup_packet_t * request, uint16_t port
     121){
    145122        request->index = port;
    146123        request->request_type = USB_HUB_REQ_TYPE_SET_PORT_FEATURE;
     
    156133 */
    157134static inline usb_device_request_setup_packet_t *
    158 usb_hub_create_enable_port_request(uint16_t port) {
     135usb_hub_create_enable_port_request(uint16_t port){
    159136        usb_device_request_setup_packet_t * result =
    160137                usb_new(usb_device_request_setup_packet_t);
    161         usb_hub_set_enable_port_request(result, port);
     138        usb_hub_set_enable_port_request(result,port);
    162139        return result;
    163140}
     
    169146 */
    170147static inline void usb_hub_set_disable_port_request(
    171         usb_device_request_setup_packet_t * request, uint16_t port
    172         ) {
     148usb_device_request_setup_packet_t * request, uint16_t port
     149){
    173150        request->index = port;
    174151        request->request_type = USB_HUB_REQ_TYPE_SET_PORT_FEATURE;
     
    184161 */
    185162static inline usb_device_request_setup_packet_t *
    186 usb_hub_create_disable_port_request(uint16_t port) {
     163usb_hub_create_disable_port_request(uint16_t port){
    187164        usb_device_request_setup_packet_t * result =
    188165                usb_new(usb_device_request_setup_packet_t);
    189         usb_hub_set_disable_port_request(result, port);
     166        usb_hub_set_disable_port_request(result,port);
    190167        return result;
    191168}
     
    197174 */
    198175static inline void usb_hub_set_reset_port_request(
    199         usb_device_request_setup_packet_t * request, uint16_t port
    200         ) {
     176usb_device_request_setup_packet_t * request, uint16_t port
     177){
    201178        request->index = port;
    202179        request->request_type = USB_HUB_REQ_TYPE_SET_PORT_FEATURE;
     
    212189 */
    213190static inline usb_device_request_setup_packet_t *
    214 usb_hub_create_reset_port_request(uint16_t port) {
     191usb_hub_create_reset_port_request(uint16_t port){
    215192        usb_device_request_setup_packet_t * result =
    216193                usb_new(usb_device_request_setup_packet_t);
    217         usb_hub_set_reset_port_request(result, port);
     194        usb_hub_set_reset_port_request(result,port);
    218195        return result;
    219196}
     
    225202 */
    226203static inline void usb_hub_set_power_port_request(
    227         usb_device_request_setup_packet_t * request, uint16_t port
    228         ) {
     204usb_device_request_setup_packet_t * request, uint16_t port
     205){
    229206        request->index = port;
    230207        request->request_type = USB_HUB_REQ_TYPE_SET_PORT_FEATURE;
     
    240217 */
    241218static inline void usb_hub_unset_power_port_request(
    242         usb_device_request_setup_packet_t * request, uint16_t port
    243         ) {
     219usb_device_request_setup_packet_t * request, uint16_t port
     220){
    244221        request->index = port;
    245222        request->request_type = USB_HUB_REQ_TYPE_SET_PORT_FEATURE;
     
    249226}
    250227
    251 /**
    252  * get i`th bit of port status
    253  *
    254  * @param status
    255  * @param idx
    256  * @return
    257  */
    258 static 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  */
     228
     229/** get i`th bit of port status */
     230static 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 */
    269236static inline void usb_port_set_bit(
    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  */
    283 static 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  */
    294 static 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  */
    307 static inline bool usb_port_dev_connected(usb_port_status_t * status) {
    308         return usb_port_get_bit(status, 0);
    309 }
    310 
    311 static inline void usb_port_set_dev_connected(usb_port_status_t * status, bool connected) {
    312         usb_port_set_bit(status, 0, connected);
     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
     245static inline bool usb_port_dev_connected(usb_port_status_t * status){
     246        return usb_port_get_bit(status,0);
     247}
     248
     249static inline void usb_port_set_dev_connected(usb_port_status_t * status,bool connected){
     250        usb_port_set_bit(status,0,connected);
    313251}
    314252
    315253//port enabled
    316 
    317 /**
    318  * port enabled getter for port status
    319  *
    320  * @param status
    321  * @return true if the port is enabled
    322  */
    323 static inline bool usb_port_enabled(usb_port_status_t * status) {
    324         return usb_port_get_bit(status, 1);
    325 }
    326 
    327 static inline void usb_port_set_enabled(usb_port_status_t * status, bool enabled) {
    328         usb_port_set_bit(status, 1, enabled);
     254static inline bool usb_port_enabled(usb_port_status_t * status){
     255        return usb_port_get_bit(status,1);
     256}
     257
     258static inline void usb_port_set_enabled(usb_port_status_t * status,bool enabled){
     259        usb_port_set_bit(status,1,enabled);
    329260}
    330261
    331262//port suspended
    332 /**
    333  * port suspended getter for port status
    334  *
    335  * @param status
    336  * @return true if port is suspended
    337  */
    338 static inline bool usb_port_suspended(usb_port_status_t * status) {
    339         return usb_port_get_bit(status, 2);
    340 }
    341 
    342 static inline void usb_port_set_suspended(usb_port_status_t * status, bool suspended) {
    343         usb_port_set_bit(status, 2, suspended);
     263static inline bool usb_port_suspended(usb_port_status_t * status){
     264        return usb_port_get_bit(status,2);
     265}
     266
     267static inline void usb_port_set_suspended(usb_port_status_t * status,bool suspended){
     268        usb_port_set_bit(status,2,suspended);
    344269}
    345270
    346271//over currect
    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  */
    353 static inline bool usb_port_over_current(usb_port_status_t * status) {
    354         return usb_port_get_bit(status, 3);
    355 }
    356 
    357 static inline void usb_port_set_over_current(usb_port_status_t * status, bool value) {
    358         usb_port_set_bit(status, 3, value);
     272static inline bool usb_port_over_current(usb_port_status_t * status){
     273        return usb_port_get_bit(status,3);
     274}
     275
     276static inline void usb_port_set_over_current(usb_port_status_t * status,bool value){
     277        usb_port_set_bit(status,3,value);
    359278}
    360279
    361280//port reset
    362 /**
    363  * port reset indicator getter for port status
    364  *
    365  * @param status
    366  * @return true if port is reset
    367  */
    368 static inline bool usb_port_reset(usb_port_status_t * status) {
    369         return usb_port_get_bit(status, 4);
    370 }
    371 
    372 static inline void usb_port_set_reset(usb_port_status_t * status, bool value) {
    373         usb_port_set_bit(status, 4, value);
     281static inline bool usb_port_reset(usb_port_status_t * status){
     282        return usb_port_get_bit(status,4);
     283}
     284
     285static inline void usb_port_set_reset(usb_port_status_t * status,bool value){
     286        usb_port_set_bit(status,4,value);
    374287}
    375288
    376289//powered
    377 /**
    378  * power state getter for port status
    379  *
    380  * @param status
    381  * @return true if port is powered
    382  */
    383 static inline bool usb_port_powered(usb_port_status_t * status) {
    384         return usb_port_get_bit(status, 8);
    385 }
    386 
    387 static inline void usb_port_set_powered(usb_port_status_t * status, bool powered) {
    388         usb_port_set_bit(status, 8, powered);
     290static inline bool usb_port_powered(usb_port_status_t * status){
     291        return usb_port_get_bit(status,8);
     292}
     293
     294static inline void usb_port_set_powered(usb_port_status_t * status,bool powered){
     295        usb_port_set_bit(status,8,powered);
    389296}
    390297
    391298//low speed device attached
    392 /**
    393  * low speed device on the port indicator
    394  *
    395  * @param status
    396  * @return true if low speed device is attached
    397  */
    398 static inline bool usb_port_low_speed(usb_port_status_t * status) {
    399         return usb_port_get_bit(status, 9);
    400 }
    401 
    402 static 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  */
    413 static inline bool usb_port_high_speed(usb_port_status_t * status) {
    414         return usb_port_get_bit(status, 10);
    415 }
    416 
    417 static 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  */
    427 static inline usb_speed_t usb_port_speed(usb_port_status_t * status) {
    428         if (usb_port_low_speed(status))
     299static inline bool usb_port_low_speed(usb_port_status_t * status){
     300        return usb_port_get_bit(status,9);
     301}
     302
     303static 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
     308static inline bool usb_port_high_speed(usb_port_status_t * status){
     309        return usb_port_get_bit(status,10);
     310}
     311
     312static 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
     316static inline usb_speed_t usb_port_speed(usb_port_status_t * status){
     317        if(usb_port_low_speed(status))
    429318                return USB_SPEED_LOW;
    430         if (usb_port_high_speed(status))
     319        if(usb_port_high_speed(status))
    431320                return USB_SPEED_HIGH;
    432321        return USB_SPEED_FULL;
     
    435324
    436325//connect change
    437 /**
    438  * port connect change indicator
    439  *
    440  * @param status
    441  * @return true if connection has changed
    442  */
    443 static inline bool usb_port_connect_change(usb_port_status_t * status) {
    444         return usb_port_get_bit(status, 16);
    445 }
    446 
    447 static inline void usb_port_set_connect_change(usb_port_status_t * status, bool change) {
    448         usb_port_set_bit(status, 16, change);
     326static inline bool usb_port_connect_change(usb_port_status_t * status){
     327        return usb_port_get_bit(status,16);
     328}
     329
     330static inline void usb_port_set_connect_change(usb_port_status_t * status,bool change){
     331        usb_port_set_bit(status,16,change);
    449332}
    450333
    451334//port enable change
    452 /**
    453  * port enable change for port status
    454  *
    455  * @param status
    456  * @return true if the port has been enabled/disabled
    457  */
    458 static inline bool usb_port_enabled_change(usb_port_status_t * status) {
    459         return usb_port_get_bit(status, 17);
    460 }
    461 
    462 static inline void usb_port_set_enabled_change(usb_port_status_t * status, bool change) {
    463         usb_port_set_bit(status, 17, change);
     335static inline bool usb_port_enabled_change(usb_port_status_t * status){
     336        return usb_port_get_bit(status,17);
     337}
     338
     339static inline void usb_port_set_enabled_change(usb_port_status_t * status,bool change){
     340        usb_port_set_bit(status,17,change);
    464341}
    465342
    466343//suspend change
    467 /**
    468  * port suspend change for port status
    469  *
    470  * @param status
    471  * @return ture if suspend status has changed
    472  */
    473 static inline bool usb_port_suspend_change(usb_port_status_t * status) {
    474         return usb_port_get_bit(status, 18);
    475 }
    476 
    477 static inline void usb_port_set_suspend_change(usb_port_status_t * status, bool change) {
    478         usb_port_set_bit(status, 18, change);
     344static inline bool usb_port_suspend_change(usb_port_status_t * status){
     345        return usb_port_get_bit(status,18);
     346}
     347
     348static inline void usb_port_set_suspend_change(usb_port_status_t * status,bool change){
     349        usb_port_set_bit(status,18,change);
    479350}
    480351
    481352//over current change
    482 /**
    483  * over current change indicator
    484  *
    485  * @param status
    486  * @return true if over-current condition on port has changed
    487  */
    488 static inline bool usb_port_overcurrent_change(usb_port_status_t * status) {
    489         return usb_port_get_bit(status, 19);
    490 }
    491 
    492 static inline void usb_port_set_overcurrent_change(usb_port_status_t * status, bool change) {
    493         usb_port_set_bit(status, 19, change);
     353static inline bool usb_port_overcurrent_change(usb_port_status_t * status){
     354        return usb_port_get_bit(status,19);
     355}
     356
     357static inline void usb_port_set_overcurrent_change(usb_port_status_t * status,bool change){
     358        usb_port_set_bit(status,19,change);
    494359}
    495360
    496361//reset change
    497 /**
    498  * port reset change indicator
    499  * @param status
    500  * @return true if port has been reset
    501  */
    502 static inline bool usb_port_reset_completed(usb_port_status_t * status) {
    503         return usb_port_get_bit(status, 20);
    504 }
    505 
    506 static 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  */
    517 static inline bool usb_hub_local_power_lost(usb_hub_status_t * status) {
    518         return usb_hub_get_bit(status, 0);
    519 }
    520 
    521 static 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  */
    533 static inline bool usb_hub_over_current(usb_hub_status_t * status) {
    534         return usb_hub_get_bit(status, 1);
    535 }
    536 
    537 static 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  */
    550 static inline bool usb_hub_local_power_change(usb_hub_status_t * status) {
    551         return usb_hub_get_bit(status, 16);
    552 }
    553 
    554 static 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  */
    566 static inline bool usb_hub_over_current_change(usb_hub_status_t * status) {
    567         return usb_hub_get_bit(status, 17);
    568 }
    569 
    570 static 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 }
     362static inline bool usb_port_reset_completed(usb_port_status_t * status){
     363        return usb_port_get_bit(status,20);
     364}
     365
     366static inline void usb_port_set_reset_completed(usb_port_status_t * status,bool completed){
     367        usb_port_set_bit(status,20,completed);
     368}
     369
    574370
    575371
  • uspace/drv/usbhub/usbhub.c

    ra4e18e1 ra82889e  
    5353#include "usb/classes/classes.h"
    5454
    55 
    56 static int usb_hub_init_add_device(usb_hub_info_t * hub, uint16_t port,
    57         usb_speed_t speed);
    58 
    59 static usb_hub_info_t * usb_hub_info_create(usb_device_t * usb_dev);
    60 
    61 static int usb_hub_process_hub_specific_info(usb_hub_info_t * hub_info);
    62 
    63 static int usb_hub_set_configuration(usb_hub_info_t * hub_info);
    64 
    65 static int usb_hub_release_default_address(usb_hub_info_t * hub);
    66 
    67 static int usb_hub_init_add_device(usb_hub_info_t * hub, uint16_t port,
    68         usb_speed_t speed);
    69 
    70 static void usb_hub_finalize_add_device(usb_hub_info_t * hub,
    71         uint16_t port, usb_speed_t speed);
    72 
    73 static void usb_hub_removed_device(
    74         usb_hub_info_t * hub, uint16_t port);
    75 
    76 static void usb_hub_port_over_current(usb_hub_info_t * hub,
    77         uint16_t port, uint32_t status);
    78 
    79 static void usb_hub_process_interrupt(usb_hub_info_t * hub,
    80         uint16_t port);
    81 
    82 static int usb_process_hub_over_current(usb_hub_info_t * hub_info,
    83         usb_hub_status_t status);
    84 
    85 static int usb_process_hub_power_change(usb_hub_info_t * hub_info,
    86         usb_hub_status_t status);
    87 
    88 static 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 
    9355static int usb_hub_trigger_connecting_non_removable_devices(
    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  */
    106 int 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
     56                usb_hub_info_t * hub, usb_hub_descriptor_t * descriptor);
     57
    12058
    12159//*********************************************
     
    12563//*********************************************
    12664
    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  */
    137 int 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  */
    214 int 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 
    30965/**
    31066 * create usb_hub_info_t structure
     
    31672static usb_hub_info_t * usb_hub_info_create(usb_device_t * usb_dev) {
    31773        usb_hub_info_t * result = usb_new(usb_hub_info_t);
    318         if (!result) return NULL;
     74        if(!result) return NULL;
    31975        result->usb_device = usb_dev;
    32076        result->status_change_pipe = usb_dev->pipes[0].pipe;
     
    32379        return result;
    32480}
    325 
    32681
    32782/**
     
    33590 * @return error code
    33691 */
    337 static int usb_hub_process_hub_specific_info(usb_hub_info_t * hub_info) {
     92static int usb_hub_process_hub_specific_info(usb_hub_info_t * hub_info){
    33893        // get hub descriptor
    33994        usb_log_debug("creating serialized descriptor\n");
    34095        void * serialized_descriptor = malloc(USB_HUB_MAX_DESCRIPTOR_SIZE);
    34196        usb_hub_descriptor_t * descriptor;
    342         int opResult;
    34397
    34498        /* this was one fix of some bug, should not be needed anymore
    34599         * these lines allow to reset hub once more, it can be used as
    346100         * brute-force initialization for non-removable devices
    347          *
    348         opResult = usb_request_set_configuration(hub_info->control_pipe,
    349                 1);
     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         */
     107        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
    350114        if (opResult != EOK) {
    351                 usb_log_error("could not set default configuration, errno %d",
    352                         opResult);
    353                 return opResult;
    354         }*/
    355 
    356 
    357         size_t received_size;
    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);
     115                usb_log_error("failed when receiving hub descriptor, badcode = %d\n",
     116                                opResult);
    368117                free(serialized_descriptor);
    369118                return opResult;
     
    371120        usb_log_debug2("deserializing descriptor\n");
    372121        descriptor = usb_deserialize_hub_desriptor(serialized_descriptor);
    373         if (descriptor == NULL) {
     122        if(descriptor==NULL){
    374123                usb_log_warning("could not deserialize descriptor \n");
    375124                return opResult;
    376125        }
    377         usb_log_debug("setting port count to %d\n", descriptor->ports_count);
     126        usb_log_debug("setting port count to %d\n",descriptor->ports_count);
    378127        hub_info->port_count = descriptor->ports_count;
    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 
     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]);
    396132        }
    397133        //handle non-removable devices
     
    399135        usb_log_debug2("freeing data\n");
    400136        free(serialized_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);
     137        free(descriptor->devices_removable);
     138        free(descriptor);
    411139        return EOK;
    412140}
    413 
    414141/**
    415142 * Set configuration of hub
     
    420147 * @return error code
    421148 */
    422 static int usb_hub_set_configuration(usb_hub_info_t * hub_info) {
     149static int usb_hub_set_configuration(usb_hub_info_t * hub_info){
    423150        //device descriptor
    424151        usb_standard_device_descriptor_t *std_descriptor
    425                 = &hub_info->usb_device->descriptors.device;
     152            = &hub_info->usb_device->descriptors.device;
    426153        usb_log_debug("hub has %d configurations\n",
    427                 std_descriptor->configuration_count);
    428         if (std_descriptor->configuration_count < 1) {
     154            std_descriptor->configuration_count);
     155        if(std_descriptor->configuration_count<1){
    429156                usb_log_error("there are no configurations available\n");
    430157                return EINVAL;
     
    432159
    433160        usb_standard_configuration_descriptor_t *config_descriptor
    434                 = (usb_standard_configuration_descriptor_t *)
    435                 hub_info->usb_device->descriptors.configuration;
     161            = (usb_standard_configuration_descriptor_t *)
     162            hub_info->usb_device->descriptors.configuration;
    436163
    437164        /* Set configuration. */
    438165        int opResult = usb_request_set_configuration(
    439                 &hub_info->usb_device->ctrl_pipe,
    440                 config_descriptor->configuration_number);
     166            &hub_info->usb_device->ctrl_pipe,
     167            config_descriptor->configuration_number);
    441168
    442169        if (opResult != EOK) {
    443170                usb_log_error("Failed to set hub configuration: %s.\n",
    444                         str_error(opResult));
     171                    str_error(opResult));
    445172                return opResult;
    446173        }
    447174        usb_log_debug("\tused configuration %d\n",
    448                 config_descriptor->configuration_number);
     175                        config_descriptor->configuration_number);
    449176
    450177        return EOK;
     
    452179
    453180/**
    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
     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
    459186 * @return error code
    460187 */
    461 static 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;
     188int usb_hub_add_device(usb_device_t * usb_dev){
     189        if(!usb_dev) return EINVAL;
     190        usb_hub_info_t * hub_info = usb_hub_info_create(usb_dev);
     191        //create hc connection
     192        usb_log_debug("Initializing USB wire abstraction.\n");
     193        int opResult = usb_hc_connection_initialize_from_device(
     194                        &hub_info->connection,
     195                        hub_info->usb_device->ddf_dev);
     196        if(opResult != EOK){
     197                usb_log_error("could not initialize connection to device, errno %d\n",
     198                                opResult);
     199                free(hub_info);
     200                return opResult;
     201        }
     202       
     203        usb_pipe_start_session(hub_info->control_pipe);
     204        //set hub configuration
     205        opResult = usb_hub_set_configuration(hub_info);
     206        if(opResult!=EOK){
     207                usb_log_error("could not set hub configuration, errno %d\n",opResult);
     208                free(hub_info);
     209                return opResult;
     210        }
     211        //get port count and create attached_devs
     212        opResult = usb_hub_process_hub_specific_info(hub_info);
     213        if(opResult!=EOK){
     214                usb_log_error("could not set hub configuration, errno %d\n",opResult);
     215                free(hub_info);
     216                return opResult;
     217        }
     218        usb_pipe_end_session(hub_info->control_pipe);
     219
     220
     221        /// \TODO what is this?
     222        usb_log_debug("Creating `hub' function.\n");
     223        ddf_fun_t *hub_fun = ddf_fun_create(hub_info->usb_device->ddf_dev,
     224                        fun_exposed, "hub");
     225        assert(hub_fun != NULL);
     226        hub_fun->ops = NULL;
     227
     228        int rc = ddf_fun_bind(hub_fun);
     229        assert(rc == EOK);
     230        rc = ddf_fun_add_to_class(hub_fun, "hub");
     231        assert(rc == EOK);
     232
     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);
    469267        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  */
    479 static 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  */
    528 static 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  */
    623 static 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  */
    666 static 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  */
    693 static 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  */
    771 static 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",
    780                                 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  */
    802 static 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  */
    836 static 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
    883 static 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;
    918         }
    919        
    920         return opResult;
    921 }
    922 #endif
     268
     269leave:
     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
    923282/**
    924283 * triggers actions to connect non0removable devices
     
    930289 * @return error code
    931290 */
    932 static int usb_hub_trigger_connecting_non_removable_devices(
    933         usb_hub_info_t * hub,
    934         usb_hub_descriptor_t * descriptor) {
     291static int usb_hub_trigger_connecting_non_removable_devices(usb_hub_info_t * hub,
     292                usb_hub_descriptor_t * descriptor)
     293{
    935294        usb_log_info("attaching non-removable devices(if any)\n");
    936         //usb_device_request_setup_packet_t request;
     295        usb_device_request_setup_packet_t request;
    937296        int opResult;
    938         //size_t rcvd_size;
    939         //usb_port_status_t status;
     297        size_t rcvd_size;
     298        usb_port_status_t status;
    940299        uint8_t * non_removable_dev_bitmap = descriptor->devices_removable;
    941300        int 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) {
     301        for(port=1;port<=descriptor->ports_count;++port){
    952302                bool is_non_removable =
    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);
     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);
    956306                        usb_hub_set_port_status_request(&request, port);
    957307                        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                                 );
     308                                        hub->control_pipe,
     309                                        &request, sizeof(usb_device_request_setup_packet_t),
     310                                        &status, 4, &rcvd_size
     311                                        );
    963312                        if (opResult != EOK) {
    964                                 usb_log_error("could not get port status of "
    965                                         "port %d errno:%d\n",
    966                                         port, opResult);
     313                                usb_log_error("could not get port status of port %d errno:%d\n",
     314                                                port, opResult);
    967315                                return opResult;
    968316                        }
    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);
     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);
    974321                                opResult = usb_pipe_control_read(
    975                                         hub->control_pipe,
    976                                         &request,
    977                                         sizeof (usb_device_request_setup_packet_t),
    978                                         &status, 4, &rcvd_size
    979                                         );
     322                                                hub->control_pipe,
     323                                                &request, sizeof(usb_device_request_setup_packet_t),
     324                                                &status, 4, &rcvd_size
     325                                                );
    980326                                if (opResult != EOK) {
    981327                                        usb_log_warning(
    982                                                 "could not reset port %d "
    983                                                 "errno:%d\n",
    984                                                 port, opResult);
     328                                                        "could not clear port connection on port %d errno:%d\n",
     329                                                        port, opResult);
    985330                                }
    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);
     331                                usb_log_debug("cleared port connection\n");
     332                                usb_hub_set_enable_port_feature_request(&request, port,
     333                                                USB_HUB_FEATURE_PORT_ENABLE);
    998334                                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                                         );
     335                                                hub->control_pipe,
     336                                                &request, sizeof(usb_device_request_setup_packet_t),
     337                                                &status, 4, &rcvd_size
     338                                                );
    1004339                                if (opResult != EOK) {
    1005340                                        usb_log_warning(
    1006                                                 "could not clear port "
    1007                                                 "connection on port %d "
    1008                                                 "errno:%d\n",
    1009                                                 port, opResult);
     341                                                        "could not set port enabled on port %d errno:%d\n",
     342                                                        port, opResult);
    1010343                                }
    1011                                 usb_log_debug("cleared port connection\n");
    1012                                 usb_hub_set_enable_port_feature_request(&request,
    1013                                         port,
    1014                                         USB_HUB_FEATURE_PORT_ENABLE);
    1015                                 opResult = usb_pipe_control_read(
    1016                                         hub->control_pipe,
    1017                                         &request,
    1018                                         sizeof (usb_device_request_setup_packet_t),
    1019                                         &status, 4, &rcvd_size
    1020                                         );
    1021                                 if (opResult != EOK) {
    1022                                         usb_log_warning(
    1023                                                 "could not set port enabled "
    1024                                                 "on port %d errno:%d\n",
    1025                                                 port, opResult);
    1026                                 }
    1027                                 usb_log_debug("port set to enabled - "
    1028                                         "should lead to connection change\n");
     344                                usb_log_debug("port set to enabled - should lead to connection change\n");
    1029345                        }
    1030346                }
    1031347        }
    1032 #endif
    1033 
    1034348        /// \TODO this is just a debug code
    1035         for (port = 1; port <= descriptor->ports_count; ++port) {
     349        for(port=1;port<=descriptor->ports_count;++port){
    1036350                bool is_non_removable =
    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);
     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);
    1041354                        usb_port_status_t status;
    1042355                        size_t rcvd_size;
     
    1046359                        //endpoint 0
    1047360                        opResult = usb_pipe_control_read(
    1048                                 hub->control_pipe,
    1049                                 &request,
    1050                                 sizeof (usb_device_request_setup_packet_t),
    1051                                 &status, 4, &rcvd_size
    1052                                 );
     361                                        hub->control_pipe,
     362                                        &request, sizeof(usb_device_request_setup_packet_t),
     363                                        &status, 4, &rcvd_size
     364                                        );
    1053365                        if (opResult != EOK) {
    1054                                 usb_log_error("could not get port status %d\n",
    1055                                         opResult);
     366                                usb_log_error("could not get port status %d\n",opResult);
    1056367                        }
    1057368                        if (rcvd_size != sizeof (usb_port_status_t)) {
    1058                                 usb_log_error("received status has incorrect"
    1059                                         " size\n");
     369                                usb_log_error("received status has incorrect size\n");
    1060370                        }
    1061371                        //something connected/disconnected
     
    1063373                                usb_log_debug("some connection changed\n");
    1064374                        }
    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));
     375                        usb_log_debug("status: %s\n",usb_debug_str_buffer(
     376                                        (uint8_t *)&status,4,4));
    1070377                }
    1071378        }
    1072         async_usleep(1000*1000*10);
    1073379        return EOK;
    1074380}
     
    1076382
    1077383/**
     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 */
     391static 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 */
     410void 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 */
     450void 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/**
    1078463 * @}
    1079464 */
  • uspace/drv/usbhub/usbhub.h

    ra4e18e1 ra82889e  
    4343
    4444#include <usb/hub.h>
    45 #include <usb/classes/hub.h>
    4645
    4746#include <usb/pipes.h>
    4847#include <usb/devdrv.h>
    4948
     49#include "ports.h"
     50
     51
     52
    5053/** Information about attached hub. */
    5154typedef struct {
    5255        /** Number of ports. */
    53         int port_count;
     56        size_t port_count;
    5457
    55         /** attached device handles, for each port one */
    56         usb_hc_attached_device_t * attached_devs;
    57 
     58        /** Ports. */
     59        usb_hub_port_t *ports;
     60       
    5861        /** connection to hcd */
    5962        usb_hc_connection_t connection;
     
    8487        /** generic usb device data*/
    8588        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        
    9389} usb_hub_info_t;
    9490
     
    9894 */
    9995int usb_hub_control_loop(void * hub_info_param);
    100 
    101 int usb_hub_add_device(usb_device_t * usb_dev);
    10296
    10397/**
     
    109103int usb_hub_check_hub_changes(usb_hub_info_t * hub_info_param);
    110104
     105void usb_hub_removed_device(usb_hub_info_t *, uint16_t);
     106void usb_hub_over_current(usb_hub_info_t *, uint16_t);
     107
     108int usb_hub_add_device(usb_device_t * usb_dev);
    111109
    112110#endif
  • uspace/drv/usbhub/usbhub_private.h

    ra4e18e1 ra82889e  
    3838
    3939#include "usbhub.h"
    40 #include "usblist.h"
    4140
    4241#include <adt/list.h>
     
    111110
    112111/**
    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  */
    121 static 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  */
    144 static 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  */
    165 static 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 /**
    180112 * create uint8_t array with serialized descriptor
    181113 *
Note: See TracChangeset for help on using the changeset viewer.