Changeset d8421c4 in mainline for uspace/drv/ohci/root_hub.c


Ignore:
Timestamp:
2011-03-25T16:18:12Z (13 years ago)
Author:
Matus Dekanek <smekideki@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
f97717d9
Parents:
4d0c40b
Message:

ohci root hub driver starts doing something

File:
1 edited

Legend:

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

    r4d0c40b rd8421c4  
    3939
    4040#include "root_hub.h"
     41#include "usb/classes/classes.h"
    4142#include <usb/request.h>
    4243#include <usb/classes/hub.h>
     
    6566
    6667static int process_get_port_status_request(rh_t *instance, uint16_t port,
    67                 char * buffer){
     68                usb_transfer_batch_t * request){
    6869        if(port<1 || port>instance->port_count)
    6970                return EINVAL;
    70         uint32_t * uint32_buffer = (uint32_t*)buffer;
     71        uint32_t * uint32_buffer = (uint32_t*)request->buffer;
     72        request->transfered_size = 4;
    7173        uint32_buffer[0] = instance->registers->rh_port_status[port -1];
    7274        return EOK;
    7375}
    7476
    75 static int process_get_hub_status_request(rh_t *instance,char * buffer){
    76         uint32_t * uint32_buffer = (uint32_t*)buffer;
     77static int process_get_hub_status_request(rh_t *instance,
     78                usb_transfer_batch_t * request){
     79        uint32_t * uint32_buffer = (uint32_t*)request->buffer;
    7780        //bits, 0,1,16,17
     81        request->transfered_size = 4;
    7882        uint32_t mask = 1 & (1<<1) & (1<<16) & (1<<17);
    7983        uint32_buffer[0] = mask & instance->registers->rh_status;
     
    8286}
    8387
    84 
    85 static int process_get_status_request(rh_t *instance,char * buffer,
    86                 size_t buffer_size, usb_device_request_setup_packet_t * request){
    87 
    88         usb_hub_bm_request_type_t request_type = request->request_type;
    89         if(buffer_size!=4) return EINVAL;
     88static void usb_create_serialized_hub_descriptor(rh_t *instance, uint8_t ** out_result,
     89                size_t * out_size) {
     90        //base size
     91        size_t size = 7;
     92        //variable size according to port count
     93        size_t var_size = instance->port_count / 8 +
     94                        ((instance->port_count % 8 > 0) ? 1 : 0);
     95        size += 2 * var_size;
     96        uint8_t * result = (uint8_t*) malloc(size);
     97        bzero(result,size);
     98        //size
     99        result[0] = size;
     100        //descriptor type
     101        result[1] = USB_DESCTYPE_HUB;
     102        result[2] = instance->port_count;
     103        uint32_t hub_desc_reg = instance->registers->rh_desc_a;
     104        result[3] =
     105                        ((hub_desc_reg >> 8) %2) +
     106                        (((hub_desc_reg >> 9) %2) << 1) +
     107                        (((hub_desc_reg >> 10) %2) << 2) +
     108                        (((hub_desc_reg >> 11) %2) << 3) +
     109                        (((hub_desc_reg >> 12) %2) << 4);
     110        result[4] = 0;
     111        result[5] = /*descriptor->pwr_on_2_good_time*/ 50;
     112        result[6] = 50;
     113
     114        int port;
     115        for (port = 1; port <= instance->port_count; ++port) {
     116                result[7 + port/8] +=
     117                                ((instance->registers->rh_desc_b >> port)%2) << (port%8);
     118        }
     119        size_t i;
     120        for (i = 0; i < var_size; ++i) {
     121                result[7 + var_size + i] = 255;
     122        }
     123        (*out_result) = result;
     124        (*out_size) = size;
     125}
     126
     127
     128static int process_get_status_request(rh_t *instance,
     129                usb_transfer_batch_t * request)
     130{
     131        size_t buffer_size = request->buffer_size;
     132        usb_device_request_setup_packet_t * request_packet =
     133                        (usb_device_request_setup_packet_t*)
     134                        request->setup_buffer;
     135
     136        usb_hub_bm_request_type_t request_type = request_packet->request_type;
     137        if(buffer_size<4/*request_packet->length*/){///\TODO
     138                usb_log_warning("requested more data than buffer size\n");
     139                return EINVAL;
     140        }
     141
    90142        if(request_type == USB_HUB_REQ_TYPE_GET_HUB_STATUS)
    91                 return process_get_hub_status_request(instance, buffer);
     143                return process_get_hub_status_request(instance, request);
    92144        if(request_type == USB_HUB_REQ_TYPE_GET_PORT_STATUS)
    93                 return process_get_port_status_request(instance, request->index,
    94                                 buffer);
     145                return process_get_port_status_request(instance, request_packet->index,
     146                                request);
    95147        return ENOTSUP;
    96148}
     149
     150static void create_interrupt_mask(rh_t *instance, void ** buffer,
     151                size_t * buffer_size){
     152        int bit_count = instance->port_count + 1;
     153        (*buffer_size) = (bit_count / 8) + (bit_count%8==0)?0:1;
     154        (*buffer) = malloc(*buffer_size);
     155        uint8_t * bitmap = (uint8_t*)(*buffer);
     156        uint32_t mask = (1<<16) + (1<<17);
     157        bzero(bitmap,(*buffer_size));
     158        if(instance->registers->rh_status & mask){
     159                bitmap[0] = 1;
     160        }
     161        int port;
     162        mask = 0;
     163        int i;
     164        for(i=16;i<=20;++i)
     165                mask += 1<<i;
     166        for(port = 1; port<=instance->port_count;++port){
     167                if(mask & instance->registers->rh_port_status[port-1]){
     168                        bitmap[(port+1)/8] += 1<<(port%8);
     169                }
     170        }
     171}
     172
    97173
    98174static int process_get_descriptor_request(rh_t *instance,
     
    101177        usb_device_request_setup_packet_t * setup_request =
    102178                        (usb_device_request_setup_packet_t*)request->setup_buffer;
    103         if(setup_request->value == USB_DESCTYPE_HUB){
     179        size_t size;
     180        void * result_descriptor;
     181        uint16_t setup_request_value = setup_request->value_high;
     182                        //(setup_request->value_low << 8);
     183        if(setup_request_value == USB_DESCTYPE_HUB){
     184                usb_log_debug("USB_DESCTYPE_HUB\n");
    104185                //create hub descriptor
    105         }else if(setup_request->value == USB_DESCTYPE_HUB){
     186                uint8_t * descriptor;
     187                usb_create_serialized_hub_descriptor(instance,
     188                                &descriptor, &size);
     189                result_descriptor = descriptor;
     190        }else if(setup_request_value == USB_DESCTYPE_DEVICE){
    106191                //create std device descriptor
     192                usb_log_debug("USB_DESCTYPE_DEVICE\n");
     193                usb_standard_device_descriptor_t * descriptor =
     194                                (usb_standard_device_descriptor_t*)
     195                                malloc(sizeof(usb_standard_device_descriptor_t));
     196                descriptor->configuration_count = 1;
     197                descriptor->descriptor_type = USB_DESCTYPE_DEVICE;
     198                descriptor->device_class = USB_CLASS_HUB;
     199                descriptor->device_protocol = 0;
     200                descriptor->device_subclass = 0;
     201                descriptor->device_version = 0;
     202                descriptor->length = sizeof(usb_standard_device_descriptor_t);
     203                /// \TODO this value is guessed
     204                descriptor->max_packet_size = 8;
     205                descriptor->product_id = 0x0001;
     206                /// \TODO these values migt be different
     207                descriptor->str_serial_number = 0;
     208                descriptor->str_serial_number = 0;
     209                descriptor->usb_spec_version = 0;
     210                descriptor->vendor_id = 0x16db;
     211                result_descriptor = descriptor;
     212                size = sizeof(usb_standard_device_descriptor_t);
     213        }else if(setup_request_value == USB_DESCTYPE_CONFIGURATION){
     214                usb_log_debug("USB_DESCTYPE_CONFIGURATION\n");
     215                usb_standard_configuration_descriptor_t * descriptor =
     216                                (usb_standard_configuration_descriptor_t*)
     217                                malloc(sizeof(usb_standard_configuration_descriptor_t));
     218                /// \TODO some values are default or guessed
     219                descriptor->attributes = 1<<7;
     220                descriptor->configuration_number = 1;
     221                descriptor->descriptor_type = USB_DESCTYPE_CONFIGURATION;
     222                descriptor->interface_count = 1;
     223                descriptor->length = sizeof(usb_standard_configuration_descriptor_t);
     224                descriptor->max_power = 100;
     225                descriptor->str_configuration = 0;
     226                /// \TODO should this include device descriptor?
     227                size_t hub_descriptor_size = 7 +
     228                                2* (instance->port_count / 8 +
     229                                ((instance->port_count % 8 > 0) ? 1 : 0));
     230                descriptor->total_length =
     231                                sizeof(usb_standard_configuration_descriptor_t)+
     232                                sizeof(usb_standard_endpoint_descriptor_t)+
     233                                sizeof(usb_standard_interface_descriptor_t)+
     234                                hub_descriptor_size;
     235                result_descriptor = descriptor;
     236                size = sizeof(usb_standard_configuration_descriptor_t);
     237
     238        }else if(setup_request_value == USB_DESCTYPE_INTERFACE){
     239                usb_log_debug("USB_DESCTYPE_INTERFACE\n");
     240                usb_standard_interface_descriptor_t * descriptor =
     241                                (usb_standard_interface_descriptor_t*)
     242                                malloc(sizeof(usb_standard_interface_descriptor_t));
     243                descriptor->alternate_setting = 0;
     244                descriptor->descriptor_type = USB_DESCTYPE_INTERFACE;
     245                descriptor->endpoint_count = 1;
     246                descriptor->interface_class = USB_CLASS_HUB;
     247                /// \TODO is this correct?
     248                descriptor->interface_number = 1;
     249                descriptor->interface_protocol = 0;
     250                descriptor->interface_subclass = 0;
     251                descriptor->length = sizeof(usb_standard_interface_descriptor_t);
     252                descriptor->str_interface = 0;
     253                result_descriptor = descriptor;
     254                size = sizeof(usb_standard_interface_descriptor_t);
     255        }else if(setup_request_value == USB_DESCTYPE_ENDPOINT){
     256                usb_log_debug("USB_DESCTYPE_ENDPOINT\n");
     257                usb_standard_endpoint_descriptor_t * descriptor =
     258                                (usb_standard_endpoint_descriptor_t*)
     259                                malloc(sizeof(usb_standard_endpoint_descriptor_t));
     260                descriptor->attributes = USB_TRANSFER_INTERRUPT;
     261                descriptor->descriptor_type = USB_DESCTYPE_ENDPOINT;
     262                descriptor->endpoint_address = 1 + (1<<7);
     263                descriptor->length = sizeof(usb_standard_endpoint_descriptor_t);
     264                descriptor->max_packet_size = 8;
     265                descriptor->poll_interval = 255;
     266                result_descriptor = descriptor;
     267                size = sizeof(usb_standard_endpoint_descriptor_t);
    107268        }else{
    108                 return EINVAL;
    109         }
    110         return EOK;
    111 }
    112 
    113 static int process_get_configuration_request(rh_t *instance, char * buffer,
    114         size_t buffer_size
    115 ){
     269                usb_log_debug("USB_DESCTYPE_EINVAL %d \n",setup_request->value);
     270                usb_log_debug("\ttype %d\n\trequest %d\n\tvalue %d\n\tindex %d\n\tlen %d\n ",
     271                                setup_request->request_type,
     272                                setup_request->request,
     273                                setup_request_value,
     274                                setup_request->index,
     275                                setup_request->length
     276                                );
     277                return EINVAL;
     278        }
     279        if(request->buffer_size < size){
     280                size = request->buffer_size;
     281        }
     282        request->transfered_size = size;
     283        memcpy(request->buffer,result_descriptor,size);
     284        free(result_descriptor);
     285        return EOK;
     286}
     287
     288static int process_get_configuration_request(rh_t *instance,
     289                usb_transfer_batch_t *request){
    116290        //set and get configuration requests do not have any meaning, only dummy
    117291        //values are returned
    118         if(buffer_size != 1)
    119                 return EINVAL;
    120         buffer[0] = 1;
     292        if(request->buffer_size != 1)
     293                return EINVAL;
     294        request->buffer[0] = 1;
     295        request->transfered_size = 1;
    121296        return EOK;
    122297}
     
    148323        /// \TODO any error?
    149324        return EOK;
    150 
     325}
     326
     327static int process_address_set_request(rh_t *instance,
     328                uint16_t address){
     329        instance->address = address;
     330        return EOK;
    151331}
    152332
     
    156336                        (usb_device_request_setup_packet_t*)request->setup_buffer;
    157337        if(setup_request->request == USB_DEVREQ_GET_STATUS){
    158                 return process_get_status_request(instance, request->buffer,
    159                                 request->buffer_size,
    160                                 setup_request);
     338                usb_log_debug("USB_DEVREQ_GET_STATUS\n");
     339                return process_get_status_request(instance, request);
    161340        }
    162341        if(setup_request->request == USB_DEVREQ_GET_DESCRIPTOR){
     342                usb_log_debug("USB_DEVREQ_GET_DESCRIPTOR\n");
    163343                return process_get_descriptor_request(instance, request);
    164344        }
    165345        if(setup_request->request == USB_DEVREQ_GET_CONFIGURATION){
    166                 return process_get_configuration_request(instance, request->buffer,
    167                                 request->buffer_size);
     346                usb_log_debug("USB_DEVREQ_GET_CONFIGURATION\n");
     347                return process_get_configuration_request(instance, request);
    168348        }
    169349        return ENOTSUP;
     
    174354        usb_device_request_setup_packet_t * setup_request =
    175355                        (usb_device_request_setup_packet_t*)request->setup_buffer;
     356        request->transfered_size = 0;
    176357        if(setup_request->request == USB_DEVREQ_SET_DESCRIPTOR){
    177358                return ENOTSUP;
     
    190371        usb_device_request_setup_packet_t * setup_request =
    191372                        (usb_device_request_setup_packet_t*)request->setup_buffer;
    192         if(setup_request->request_type == USB_HUB_REQ_TYPE_SET_HUB_FEATURE){
    193                 return process_hub_feature_set_request(instance, setup_request->value,
    194                                 setup_request->request == USB_DEVREQ_SET_FEATURE);
    195         }
    196         if(setup_request->request_type == USB_HUB_REQ_TYPE_SET_PORT_FEATURE){
    197                 return process_port_feature_set_request(instance, setup_request->value,
    198                                 setup_request->index,
    199                                 setup_request->request == USB_DEVREQ_SET_FEATURE);
    200         }
     373        request->transfered_size = 0;
     374        if(setup_request->request == USB_DEVREQ_CLEAR_FEATURE
     375                                || setup_request->request == USB_DEVREQ_SET_FEATURE){
     376                if(setup_request->request_type == USB_HUB_REQ_TYPE_SET_HUB_FEATURE){
     377                        usb_log_debug("USB_HUB_REQ_TYPE_SET_HUB_FEATURE\n");
     378                        return process_hub_feature_set_request(instance, setup_request->value,
     379                                        setup_request->request == USB_DEVREQ_SET_FEATURE);
     380                }
     381                if(setup_request->request_type == USB_HUB_REQ_TYPE_SET_PORT_FEATURE){
     382                        usb_log_debug("USB_HUB_REQ_TYPE_SET_PORT_FEATURE\n");
     383                        return process_port_feature_set_request(instance, setup_request->value,
     384                                        setup_request->index,
     385                                        setup_request->request == USB_DEVREQ_SET_FEATURE);
     386                }
     387                usb_log_debug("USB_HUB_REQ_TYPE_INVALID %d\n",setup_request->request_type);
     388                return EINVAL;
     389        }
     390        if(setup_request->request == USB_DEVREQ_SET_ADDRESS){
     391                usb_log_debug("USB_DEVREQ_SET_ADDRESS\n");
     392                return process_address_set_request(instance, setup_request->value);
     393        }
     394        usb_log_debug("USB_DEVREQ_SET_ENOTSUP %d\n",setup_request->request_type);
    201395        return ENOTSUP;
    202396}
     
    214408        assert(request);
    215409        int opResult;
    216         if (request->setup_buffer) {
    217                 usb_log_info("Root hub got SETUP packet: %s.\n",
    218                     usb_debug_str_buffer((const uint8_t *)request->setup_buffer, 8, 8));
    219                 if(sizeof(usb_device_request_setup_packet_t)>request->setup_size){
    220                         usb_log_error("setup packet too small\n");
    221                         return EINVAL;
     410        if(request->transfer_type == USB_TRANSFER_CONTROL){
     411                if (request->setup_buffer) {
     412                        usb_log_info("Root hub got CTRL packet: %s.\n",
     413                                usb_debug_str_buffer((const uint8_t *)request->setup_buffer, 8, 8));
     414                        if(sizeof(usb_device_request_setup_packet_t)>request->setup_size){
     415                                usb_log_error("setup packet too small\n");
     416                                return EINVAL;
     417                        }
     418                        usb_device_request_setup_packet_t * setup_request =
     419                                        (usb_device_request_setup_packet_t*)request->setup_buffer;
     420                        if(
     421                                setup_request->request == USB_DEVREQ_GET_STATUS
     422                                || setup_request->request == USB_DEVREQ_GET_DESCRIPTOR
     423                                || setup_request->request == USB_DEVREQ_GET_CONFIGURATION
     424                        ){
     425                                usb_log_debug("processing request with output\n");
     426                                opResult = process_request_with_output(instance,request);
     427                        }else if(
     428                                setup_request->request == USB_DEVREQ_CLEAR_FEATURE
     429                                || setup_request->request == USB_DEVREQ_SET_FEATURE
     430                                || setup_request->request == USB_DEVREQ_SET_ADDRESS
     431                        ){
     432                                usb_log_debug("processing request without additional data\n");
     433                                opResult = process_request_without_data(instance,request);
     434                        }else if(setup_request->request == USB_DEVREQ_SET_DESCRIPTOR
     435                                        || setup_request->request == USB_DEVREQ_SET_CONFIGURATION
     436                        ){
     437                                usb_log_debug("processing request with input\n");
     438                                opResult = process_request_with_input(instance,request);
     439                        }else{
     440                                usb_log_warning("received unsuported request: %d\n",
     441                                                setup_request->request
     442                                                );
     443                                opResult = ENOTSUP;
     444                        }
     445                }else{
     446                        usb_log_error("root hub received empty transaction?");
     447                        opResult = EINVAL;
    222448                }
    223                 usb_device_request_setup_packet_t * setup_request =
    224                                 (usb_device_request_setup_packet_t*)request->setup_buffer;
    225                 if(
    226                         setup_request->request == USB_DEVREQ_GET_STATUS
    227                         || setup_request->request == USB_DEVREQ_GET_DESCRIPTOR
    228                         || setup_request->request == USB_DEVREQ_GET_CONFIGURATION
    229                 ){
    230                         usb_log_debug("processing request with output\n");
    231                         opResult = process_request_with_output(instance,request);
    232                 }else if(
    233                         setup_request->request == USB_DEVREQ_CLEAR_FEATURE
    234                         || setup_request->request == USB_DEVREQ_SET_FEATURE
    235                 ){
    236                         usb_log_debug("processing request without additional data\n");
    237                         opResult = process_request_without_data(instance,request);
    238                 }else if(setup_request->request == USB_DEVREQ_SET_DESCRIPTOR
    239                                 || setup_request->request == USB_DEVREQ_SET_CONFIGURATION
    240                 ){
    241                         usb_log_debug("processing request with input\n");
    242                         opResult = process_request_with_input(instance,request);
    243                 }else{
    244                         usb_log_warning("received unsuported request: %d\n",
    245                                         setup_request->request
    246                                         );
    247                         opResult = ENOTSUP;
    248                 }
     449        }else if(request->transfer_type == USB_TRANSFER_INTERRUPT){
     450                usb_log_info("Root hub got INTERRUPT packet\n");
     451                void * buffer;
     452                create_interrupt_mask(instance, &buffer,
     453                        &(request->transfered_size));
     454                memcpy(request->transport_buffer,buffer, request->transfered_size);
     455                opResult = EOK;
    249456        }else{
    250                 usb_log_error("root hub received empty transaction?");
    251457                opResult = EINVAL;
    252458        }
     
    255461}
    256462/*----------------------------------------------------------------------------*/
    257 //is this status change?
     463
     464
    258465void rh_interrupt(rh_t *instance)
    259466{
Note: See TracChangeset for help on using the changeset viewer.