Ignore:
File:
1 edited

Legend:

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

    rd8421c4 r1387692  
    3939
    4040#include "root_hub.h"
    41 #include "usb/classes/classes.h"
    42 #include <usb/request.h>
    43 #include <usb/classes/hub.h>
    44 
    4541
    4642/** Root hub initialization
     
    5450        instance->device = dev;
    5551
    56 
    5752        usb_log_info("OHCI root hub with %d ports.\n", regs->rh_desc_a & 0xff);
    5853
    59         //start generic usb hub driver
    60        
    6154        /* TODO: implement */
    6255        return EOK;
    6356}
    6457/*----------------------------------------------------------------------------*/
    65 
    66 
    67 static int process_get_port_status_request(rh_t *instance, uint16_t port,
    68                 usb_transfer_batch_t * request){
    69         if(port<1 || port>instance->port_count)
    70                 return EINVAL;
    71         uint32_t * uint32_buffer = (uint32_t*)request->buffer;
    72         request->transfered_size = 4;
    73         uint32_buffer[0] = instance->registers->rh_port_status[port -1];
    74         return EOK;
    75 }
    76 
    77 static int process_get_hub_status_request(rh_t *instance,
    78                 usb_transfer_batch_t * request){
    79         uint32_t * uint32_buffer = (uint32_t*)request->buffer;
    80         //bits, 0,1,16,17
    81         request->transfered_size = 4;
    82         uint32_t mask = 1 & (1<<1) & (1<<16) & (1<<17);
    83         uint32_buffer[0] = mask & instance->registers->rh_status;
    84         return EOK;
    85 
    86 }
    87 
    88 static 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 
    128 static 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 
    142         if(request_type == USB_HUB_REQ_TYPE_GET_HUB_STATUS)
    143                 return process_get_hub_status_request(instance, request);
    144         if(request_type == USB_HUB_REQ_TYPE_GET_PORT_STATUS)
    145                 return process_get_port_status_request(instance, request_packet->index,
    146                                 request);
    147         return ENOTSUP;
    148 }
    149 
    150 static 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 
    173 
    174 static int process_get_descriptor_request(rh_t *instance,
    175                 usb_transfer_batch_t *request){
    176         /// \TODO
    177         usb_device_request_setup_packet_t * setup_request =
    178                         (usb_device_request_setup_packet_t*)request->setup_buffer;
    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");
    185                 //create hub descriptor
    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){
    191                 //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);
    268         }else{
    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 
    288 static int process_get_configuration_request(rh_t *instance,
    289                 usb_transfer_batch_t *request){
    290         //set and get configuration requests do not have any meaning, only dummy
    291         //values are returned
    292         if(request->buffer_size != 1)
    293                 return EINVAL;
    294         request->buffer[0] = 1;
    295         request->transfered_size = 1;
    296         return EOK;
    297 }
    298 
    299 static int process_hub_feature_set_request(rh_t *instance,
    300                 uint16_t feature, bool enable){
    301         if(feature > USB_HUB_FEATURE_C_HUB_OVER_CURRENT)
    302                 return EINVAL;
    303         instance->registers->rh_status =
    304                         enable ?
    305                         (instance->registers->rh_status | (1<<feature))
    306                         :
    307                         (instance->registers->rh_status & (~(1<<feature)));
    308         /// \TODO any error?
    309         return EOK;
    310 }
    311 
    312 static int process_port_feature_set_request(rh_t *instance,
    313                 uint16_t feature, uint16_t port, bool enable){
    314         if(feature > USB_HUB_FEATURE_C_PORT_RESET)
    315                 return EINVAL;
    316         if(port<1 || port>instance->port_count)
    317                 return EINVAL;
    318         instance->registers->rh_port_status[port - 1] =
    319                         enable ?
    320                         (instance->registers->rh_port_status[port - 1] | (1<<feature))
    321                         :
    322                         (instance->registers->rh_port_status[port - 1] & (~(1<<feature)));
    323         /// \TODO any error?
    324         return EOK;
    325 }
    326 
    327 static int process_address_set_request(rh_t *instance,
    328                 uint16_t address){
    329         instance->address = address;
    330         return EOK;
    331 }
    332 
    333 static int process_request_with_output(rh_t *instance,
    334                 usb_transfer_batch_t *request){
    335         usb_device_request_setup_packet_t * setup_request =
    336                         (usb_device_request_setup_packet_t*)request->setup_buffer;
    337         if(setup_request->request == USB_DEVREQ_GET_STATUS){
    338                 usb_log_debug("USB_DEVREQ_GET_STATUS\n");
    339                 return process_get_status_request(instance, request);
    340         }
    341         if(setup_request->request == USB_DEVREQ_GET_DESCRIPTOR){
    342                 usb_log_debug("USB_DEVREQ_GET_DESCRIPTOR\n");
    343                 return process_get_descriptor_request(instance, request);
    344         }
    345         if(setup_request->request == USB_DEVREQ_GET_CONFIGURATION){
    346                 usb_log_debug("USB_DEVREQ_GET_CONFIGURATION\n");
    347                 return process_get_configuration_request(instance, request);
    348         }
    349         return ENOTSUP;
    350 }
    351 
    352 static int process_request_with_input(rh_t *instance,
    353                 usb_transfer_batch_t *request){
    354         usb_device_request_setup_packet_t * setup_request =
    355                         (usb_device_request_setup_packet_t*)request->setup_buffer;
    356         request->transfered_size = 0;
    357         if(setup_request->request == USB_DEVREQ_SET_DESCRIPTOR){
    358                 return ENOTSUP;
    359         }
    360         if(setup_request->request == USB_DEVREQ_SET_CONFIGURATION){
    361                 //set and get configuration requests do not have any meaning,
    362                 //only dummy values are returned
    363                 return EOK;
    364         }
    365         return ENOTSUP;
    366 }
    367 
    368 
    369 static int process_request_without_data(rh_t *instance,
    370                 usb_transfer_batch_t *request){
    371         usb_device_request_setup_packet_t * setup_request =
    372                         (usb_device_request_setup_packet_t*)request->setup_buffer;
    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);
    395         return ENOTSUP;
    396 }
    397 
    398 
    399 /**
    400  *
    401  * @param instance
    402  * @param request
    403  * @return
    404  */
    40558int rh_request(rh_t *instance, usb_transfer_batch_t *request)
    40659{
    40760        assert(instance);
    40861        assert(request);
    409         int opResult;
    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;
    448                 }
    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;
    456         }else{
    457                 opResult = EINVAL;
     62        /* TODO: implement */
     63        if (request->setup_buffer) {
     64                usb_log_info("Root hub got SETUP packet: %s.\n",
     65                    usb_debug_str_buffer((const uint8_t *)request->setup_buffer, 8, 8));
    45866        }
    459         usb_transfer_batch_finish(request, opResult);
     67        usb_log_error("Root hub request processing not implemented.\n");
     68        usb_transfer_batch_finish(request, ENOTSUP);
    46069        return EOK;
    46170}
    46271/*----------------------------------------------------------------------------*/
    463 
    464 
    46572void rh_interrupt(rh_t *instance)
    46673{
Note: See TracChangeset for help on using the changeset viewer.