Ignore:
File:
1 edited

Legend:

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

    r0368669c rb3f655f  
    4343#include <usb/classes/hub.h>
    4444
    45 /**
    46  *      standart device descriptor for ohci root hub
    47  */
    4845static const usb_standard_device_descriptor_t ohci_rh_device_descriptor =
    4946{
     
    6461};
    6562
    66 /**
    67  * standart configuration descriptor with filled common values
    68  * for ohci root hubs
    69  */
    7063static const usb_standard_configuration_descriptor_t ohci_rh_conf_descriptor =
    7164{
     
    8073};
    8174
    82 /**
    83  * standart ohci root hub interface descriptor
    84  */
    8575static const usb_standard_interface_descriptor_t ohci_rh_iface_descriptor =
    8676{
     
    9787};
    9888
    99 /**
    100  * standart ohci root hub endpoint descriptor
    101  */
    10289static const usb_standard_endpoint_descriptor_t ohci_rh_ep_descriptor =
    10390{
     
    130117/*----------------------------------------------------------------------------*/
    131118
    132 /**
    133  * create answer to port status_request
    134  *
    135  * Copy content of corresponding port status register to answer buffer.
    136  *
    137  * @param instance root hub instance
    138  * @param port port number, counted from 1
    139  * @param request structure containing both request and response information
    140  * @return error code
    141  */
     119
    142120static int process_get_port_status_request(rh_t *instance, uint16_t port,
    143121                usb_transfer_batch_t * request){
     
    150128}
    151129
    152 /**
    153  * create answer to port status_request
    154  *
    155  * Copy content of hub status register to answer buffer.
    156  *
    157  * @param instance root hub instance
    158  * @param request structure containing both request and response information
    159  * @return error code
    160  */
    161130static int process_get_hub_status_request(rh_t *instance,
    162131                usb_transfer_batch_t * request){
     
    170139}
    171140
    172 /**
    173  * Create hub descriptor used in hub-driver <-> hub communication
    174  *
    175  * This means creating byt array from data in root hub registers. For more
    176  * info see usb hub specification.
    177  *
    178  * @param instance root hub instance
    179  * @param@out out_result pointer to resultant serialized descriptor
    180  * @param@out out_size size of serialized descriptor
    181  */
    182 static void usb_create_serialized_hub_descriptor(rh_t *instance,
    183                 uint8_t ** out_result,
     141static void usb_create_serialized_hub_descriptor(rh_t *instance, uint8_t ** out_result,
    184142                size_t * out_size) {
    185143        //base size
     
    221179
    222180
    223 /**
    224  * create answer to status request
    225  *
    226  * This might be either hub status or port status request. If neither,
    227  * ENOTSUP is returned.
    228  * @param instance root hub instance
    229  * @param request structure containing both request and response information
    230  * @return error code
    231  */
    232181static int process_get_status_request(rh_t *instance,
    233182                usb_transfer_batch_t * request)
     
    252201}
    253202
    254 /**
    255  * create answer to status interrupt consisting of change bitmap
    256  *
    257  * Result contains bitmap where bit 0 indicates change on hub and
    258  * bit i indicates change on i`th port (i>0). For more info see
    259  * Hub and Port status bitmap specification in USB specification.
    260  * @param instance root hub instance
    261  * @param@out buffer pointer to created interrupt mas
    262  * @param@out buffer_size size of created interrupt mask
    263  */
    264203static void create_interrupt_mask(rh_t *instance, void ** buffer,
    265204                size_t * buffer_size){
     
    285224}
    286225
    287 /**
    288  * create standart configuration descriptor for the root hub instance
    289  * @param instance root hub instance
    290  * @return newly allocated descriptor
    291  */
    292 static usb_standard_configuration_descriptor_t *
    293 usb_ohci_rh_create_standart_configuration_descriptor(rh_t *instance){
    294         usb_standard_configuration_descriptor_t * descriptor =
    295                         malloc(sizeof(usb_standard_configuration_descriptor_t));
    296         memcpy(descriptor, &ohci_rh_conf_descriptor,
    297                 sizeof(usb_standard_configuration_descriptor_t));
    298         /// \TODO should this include device descriptor?
    299         const size_t hub_descriptor_size = 7 +
    300                         2* (instance->port_count / 8 +
    301                         ((instance->port_count % 8 > 0) ? 1 : 0));
    302         descriptor->total_length =
    303                         sizeof(usb_standard_configuration_descriptor_t)+
    304                         sizeof(usb_standard_endpoint_descriptor_t)+
    305                         sizeof(usb_standard_interface_descriptor_t)+
    306                         hub_descriptor_size;
    307         return descriptor;
    308 }
    309 
    310 /**
    311  * create answer to a descriptor request
    312  *
    313  * This might be a request for standard (configuration, device, endpoint or
    314  * interface) or device specific (hub) descriptor.
    315  * @param instance root hub instance
    316  * @param request structure containing both request and response information
    317  * @return error code
    318  */
     226
    319227static int process_get_descriptor_request(rh_t *instance,
    320228                usb_transfer_batch_t *request){
     229        /// \TODO
    321230        usb_device_request_setup_packet_t * setup_request =
    322231                        (usb_device_request_setup_packet_t*)request->setup_buffer;
    323232        size_t size;
    324         const void * result_descriptor = NULL;
     233        const void * result_descriptor;
    325234        const uint16_t setup_request_value = setup_request->value_high;
    326235                        //(setup_request->value_low << 8);
    327236        bool del = false;
     237
    328238        switch (setup_request_value)
    329239        {
    330                 case USB_DESCTYPE_HUB: {
    331                         uint8_t * descriptor;
    332                         usb_create_serialized_hub_descriptor(
    333                                 instance, &descriptor, &size);
    334                         result_descriptor = descriptor;
    335                         if(result_descriptor) del = true;
    336                         break;
    337                 }
    338                 case USB_DESCTYPE_DEVICE: {
    339                         usb_log_debug("USB_DESCTYPE_DEVICE\n");
    340                         result_descriptor = &ohci_rh_device_descriptor;
    341                         size = sizeof(ohci_rh_device_descriptor);
    342                         break;
    343                 }
    344                 case USB_DESCTYPE_CONFIGURATION: {
    345                         usb_log_debug("USB_DESCTYPE_CONFIGURATION\n");
    346                         usb_standard_configuration_descriptor_t * descriptor =
    347                                         usb_ohci_rh_create_standart_configuration_descriptor(
    348                                                 instance);
    349                         result_descriptor = descriptor;
    350                         size = sizeof(usb_standard_configuration_descriptor_t);
    351                         del = true;
    352                         break;
    353                 }
    354                 case USB_DESCTYPE_INTERFACE: {
    355                         usb_log_debug("USB_DESCTYPE_INTERFACE\n");
    356                         result_descriptor = &ohci_rh_iface_descriptor;
    357                         size = sizeof(ohci_rh_iface_descriptor);
    358                         break;
    359                 }
    360                 case USB_DESCTYPE_ENDPOINT: {
    361                         usb_log_debug("USB_DESCTYPE_ENDPOINT\n");
    362                         result_descriptor = &ohci_rh_ep_descriptor;
    363                         size = sizeof(ohci_rh_ep_descriptor);
    364                         break;
    365                 }
    366                 default: {
    367                         usb_log_debug("USB_DESCTYPE_EINVAL %d \n",setup_request->value);
    368                         usb_log_debug("\ttype %d\n\trequest %d\n\tvalue %d\n\tindex %d\n\tlen %d\n ",
    369                                         setup_request->request_type,
    370                                         setup_request->request,
    371                                         setup_request_value,
    372                                         setup_request->index,
    373                                         setup_request->length
    374                                         );
    375                         return EINVAL;
    376                 }
    377         }
     240        case USB_DESCTYPE_HUB: {
     241                uint8_t * descriptor;
     242                usb_create_serialized_hub_descriptor(
     243                    instance, &descriptor, &size);
     244                result_descriptor = descriptor;
     245                break;
     246        }
     247        case USB_DESCTYPE_DEVICE: {
     248                usb_log_debug("USB_DESCTYPE_DEVICE\n");
     249                result_descriptor = &ohci_rh_device_descriptor;
     250                size = sizeof(ohci_rh_device_descriptor);
     251                break;
     252        }
     253        case USB_DESCTYPE_CONFIGURATION: {
     254                usb_log_debug("USB_DESCTYPE_CONFIGURATION\n");
     255                usb_standard_configuration_descriptor_t * descriptor =
     256                                malloc(sizeof(usb_standard_configuration_descriptor_t));
     257                memcpy(descriptor, &ohci_rh_conf_descriptor,
     258                    sizeof(usb_standard_configuration_descriptor_t));
     259                /// \TODO should this include device descriptor?
     260                const size_t hub_descriptor_size = 7 +
     261                                2* (instance->port_count / 8 +
     262                                ((instance->port_count % 8 > 0) ? 1 : 0));
     263                descriptor->total_length =
     264                                sizeof(usb_standard_configuration_descriptor_t)+
     265                                sizeof(usb_standard_endpoint_descriptor_t)+
     266                                sizeof(usb_standard_interface_descriptor_t)+
     267                                hub_descriptor_size;
     268                result_descriptor = descriptor;
     269                size = sizeof(usb_standard_configuration_descriptor_t);
     270                del = true;
     271                break;
     272        }
     273        case USB_DESCTYPE_INTERFACE: {
     274                usb_log_debug("USB_DESCTYPE_INTERFACE\n");
     275                result_descriptor = &ohci_rh_iface_descriptor;
     276                size = sizeof(ohci_rh_iface_descriptor);
     277                break;
     278        }
     279        case USB_DESCTYPE_ENDPOINT: {
     280                usb_log_debug("USB_DESCTYPE_ENDPOINT\n");
     281                result_descriptor = &ohci_rh_ep_descriptor;
     282                size = sizeof(ohci_rh_ep_descriptor);
     283                break;
     284        }
     285        default: {
     286                usb_log_debug("USB_DESCTYPE_EINVAL %d \n",setup_request->value);
     287                usb_log_debug("\ttype %d\n\trequest %d\n\tvalue %d\n\tindex %d\n\tlen %d\n ",
     288                                setup_request->request_type,
     289                                setup_request->request,
     290                                setup_request_value,
     291                                setup_request->index,
     292                                setup_request->length
     293                                );
     294                return EINVAL;
     295        }
     296        }
     297#if 0
     298        if(setup_request_value == USB_DESCTYPE_HUB){
     299                usb_log_debug("USB_DESCTYPE_HUB\n");
     300                //create hub descriptor
     301                uint8_t * descriptor;
     302                usb_create_serialized_hub_descriptor(instance,
     303                                &descriptor, &size);
     304                result_descriptor = descriptor;
     305        }else if(setup_request_value == USB_DESCTYPE_DEVICE){
     306                //create std device descriptor
     307                usb_log_debug("USB_DESCTYPE_DEVICE\n");
     308                usb_standard_device_descriptor_t * descriptor =
     309                                (usb_standard_device_descriptor_t*)
     310                                malloc(sizeof(usb_standard_device_descriptor_t));
     311                descriptor->configuration_count = 1;
     312                descriptor->descriptor_type = USB_DESCTYPE_DEVICE;
     313                descriptor->device_class = USB_CLASS_HUB;
     314                descriptor->device_protocol = 0;
     315                descriptor->device_subclass = 0;
     316                descriptor->device_version = 0;
     317                descriptor->length = sizeof(usb_standard_device_descriptor_t);
     318                /// \TODO this value is guessed
     319                descriptor->max_packet_size = 8;
     320                descriptor->product_id = 0x0001;
     321                /// \TODO these values migt be different
     322                descriptor->str_serial_number = 0;
     323                descriptor->str_serial_number = 0;
     324                descriptor->usb_spec_version = 0;
     325                descriptor->vendor_id = 0x16db;
     326                result_descriptor = descriptor;
     327                size = sizeof(usb_standard_device_descriptor_t);
     328        }else if(setup_request_value == USB_DESCTYPE_CONFIGURATION){
     329                usb_log_debug("USB_DESCTYPE_CONFIGURATION\n");
     330                usb_standard_configuration_descriptor_t * descriptor =
     331                                (usb_standard_configuration_descriptor_t*)
     332                                malloc(sizeof(usb_standard_configuration_descriptor_t));
     333                /// \TODO some values are default or guessed
     334                descriptor->attributes = 1<<7;
     335                descriptor->configuration_number = 1;
     336                descriptor->descriptor_type = USB_DESCTYPE_CONFIGURATION;
     337                descriptor->interface_count = 1;
     338                descriptor->length = sizeof(usb_standard_configuration_descriptor_t);
     339                descriptor->max_power = 100;
     340                descriptor->str_configuration = 0;
     341                /// \TODO should this include device descriptor?
     342                size_t hub_descriptor_size = 7 +
     343                                2* (instance->port_count / 8 +
     344                                ((instance->port_count % 8 > 0) ? 1 : 0));
     345                descriptor->total_length =
     346                                sizeof(usb_standard_configuration_descriptor_t)+
     347                                sizeof(usb_standard_endpoint_descriptor_t)+
     348                                sizeof(usb_standard_interface_descriptor_t)+
     349                                hub_descriptor_size;
     350                result_descriptor = descriptor;
     351                size = sizeof(usb_standard_configuration_descriptor_t);
     352
     353        }else if(setup_request_value == USB_DESCTYPE_INTERFACE){
     354                usb_log_debug("USB_DESCTYPE_INTERFACE\n");
     355                usb_standard_interface_descriptor_t * descriptor =
     356                                (usb_standard_interface_descriptor_t*)
     357                                malloc(sizeof(usb_standard_interface_descriptor_t));
     358                descriptor->alternate_setting = 0;
     359                descriptor->descriptor_type = USB_DESCTYPE_INTERFACE;
     360                descriptor->endpoint_count = 1;
     361                descriptor->interface_class = USB_CLASS_HUB;
     362                /// \TODO is this correct?
     363                descriptor->interface_number = 1;
     364                descriptor->interface_protocol = 0;
     365                descriptor->interface_subclass = 0;
     366                descriptor->length = sizeof(usb_standard_interface_descriptor_t);
     367                descriptor->str_interface = 0;
     368                result_descriptor = descriptor;
     369                size = sizeof(usb_standard_interface_descriptor_t);
     370        }else if(setup_request_value == USB_DESCTYPE_ENDPOINT){
     371                usb_log_debug("USB_DESCTYPE_ENDPOINT\n");
     372                usb_standard_endpoint_descriptor_t * descriptor =
     373                                (usb_standard_endpoint_descriptor_t*)
     374                                malloc(sizeof(usb_standard_endpoint_descriptor_t));
     375                descriptor->attributes = USB_TRANSFER_INTERRUPT;
     376                descriptor->descriptor_type = USB_DESCTYPE_ENDPOINT;
     377                descriptor->endpoint_address = 1 + (1<<7);
     378                descriptor->length = sizeof(usb_standard_endpoint_descriptor_t);
     379                descriptor->max_packet_size = 8;
     380                descriptor->poll_interval = 255;
     381                result_descriptor = descriptor;
     382                size = sizeof(usb_standard_endpoint_descriptor_t);
     383        }else{
     384                usb_log_debug("USB_DESCTYPE_EINVAL %d \n",setup_request->value);
     385                usb_log_debug("\ttype %d\n\trequest %d\n\tvalue %d\n\tindex %d\n\tlen %d\n ",
     386                                setup_request->request_type,
     387                                setup_request->request,
     388                                setup_request_value,
     389                                setup_request->index,
     390                                setup_request->length
     391                                );
     392                return EINVAL;
     393        }
     394#endif
    378395        if(request->buffer_size < size){
    379396                size = request->buffer_size;
     
    386403}
    387404
    388 /**
    389  * answer to get configuration request
    390  *
    391  * Root hub works independently on the configuration.
    392  * @param instance root hub instance
    393  * @param request structure containing both request and response information
    394  * @return error code
    395  */
    396405static int process_get_configuration_request(rh_t *instance,
    397406                usb_transfer_batch_t *request){
     
    405414}
    406415
    407 /**
    408  * process feature-enabling/disabling request on hub
    409  *
    410  * @param instance root hub instance
    411  * @param feature feature selector
    412  * @param enable enable or disable specified feature
    413  * @return error code
    414  */
    415416static int process_hub_feature_set_request(rh_t *instance,
    416417                uint16_t feature, bool enable){
     
    426427}
    427428
    428 /**
    429  * process feature-enabling/disabling request on hub
    430  *
    431  * @param instance root hub instance
    432  * @param feature feature selector
    433  * @param port port number, counted from 1
    434  * @param enable enable or disable the specified feature
    435  * @return error code
    436  */
    437429static int process_port_feature_set_request(rh_t *instance,
    438430                uint16_t feature, uint16_t port, bool enable){
     
    450442}
    451443
    452 /**
    453  * register address to this device
    454  *
    455  * @param instance root hub instance
    456  * @param address new address
    457  * @return error code
    458  */
    459444static int process_address_set_request(rh_t *instance,
    460445                uint16_t address){
     
    463448}
    464449
    465 /**
    466  * process one of requests that requere output data
    467  *
    468  * Request can be one of USB_DEVREQ_GET_STATUS, USB_DEVREQ_GET_DESCRIPTOR or
    469  * USB_DEVREQ_GET_CONFIGURATION.
    470  * @param instance root hub instance
    471  * @param request structure containing both request and response information
    472  * @return error code
    473  */
    474450static int process_request_with_output(rh_t *instance,
    475451                usb_transfer_batch_t *request){
     
    491467}
    492468
    493 /**
    494  * process one of requests that carry input data
    495  *
    496  * Request can be one of USB_DEVREQ_SET_DESCRIPTOR or
    497  * USB_DEVREQ_SET_CONFIGURATION.
    498  * @param instance root hub instance
    499  * @param request structure containing both request and response information
    500  * @return error code
    501  */
    502469static int process_request_with_input(rh_t *instance,
    503470                usb_transfer_batch_t *request){
     
    516483}
    517484
    518 /**
    519  * process one of requests that do not request nor carry additional data
    520  *
    521  * Request can be one of USB_DEVREQ_CLEAR_FEATURE, USB_DEVREQ_SET_FEATURE or
    522  * USB_DEVREQ_SET_ADDRESS.
    523  * @param instance root hub instance
    524  * @param request structure containing both request and response information
    525  * @return error code
    526  */
     485
    527486static int process_request_without_data(rh_t *instance,
    528487                usb_transfer_batch_t *request){
     
    554513}
    555514
     515
    556516/**
    557  * process hub control request
    558517 *
    559  * If needed, writes answer into the request structure.
    560  * Request can be one of
    561  * USB_DEVREQ_GET_STATUS,
    562  * USB_DEVREQ_GET_DESCRIPTOR,
    563  * USB_DEVREQ_GET_CONFIGURATION,
    564  * USB_DEVREQ_CLEAR_FEATURE,
    565  * USB_DEVREQ_SET_FEATURE,
    566  * USB_DEVREQ_SET_ADDRESS,
    567  * USB_DEVREQ_SET_DESCRIPTOR or
    568  * USB_DEVREQ_SET_CONFIGURATION.
    569  *
    570  * @param instance root hub instance
    571  * @param request structure containing both request and response information
    572  * @return error code
    573  */
    574 static int process_ctrl_request(rh_t *instance, usb_transfer_batch_t *request){
    575         int opResult;
    576         if (request->setup_buffer) {
    577                 if(sizeof(usb_device_request_setup_packet_t)>request->setup_size){
    578                         usb_log_error("setup packet too small\n");
    579                         return EINVAL;
    580                 }
    581                 usb_log_info("CTRL packet: %s.\n",
    582                         usb_debug_str_buffer((const uint8_t *)request->setup_buffer, 8, 8));
    583                 usb_device_request_setup_packet_t * setup_request =
    584                                 (usb_device_request_setup_packet_t*)request->setup_buffer;
    585                 if(
    586                         setup_request->request == USB_DEVREQ_GET_STATUS
    587                         || setup_request->request == USB_DEVREQ_GET_DESCRIPTOR
    588                         || setup_request->request == USB_DEVREQ_GET_CONFIGURATION
    589                 ){
    590                         usb_log_debug("processing request with output\n");
    591                         opResult = process_request_with_output(instance,request);
    592                 }else if(
    593                         setup_request->request == USB_DEVREQ_CLEAR_FEATURE
    594                         || setup_request->request == USB_DEVREQ_SET_FEATURE
    595                         || setup_request->request == USB_DEVREQ_SET_ADDRESS
    596                 ){
    597                         usb_log_debug("processing request without additional data\n");
    598                         opResult = process_request_without_data(instance,request);
    599                 }else if(setup_request->request == USB_DEVREQ_SET_DESCRIPTOR
    600                                 || setup_request->request == USB_DEVREQ_SET_CONFIGURATION
    601                 ){
    602                         usb_log_debug("processing request with input\n");
    603                         opResult = process_request_with_input(instance,request);
    604                 }else{
    605                         usb_log_warning("received unsuported request: %d\n",
    606                                         setup_request->request
    607                                         );
    608                         opResult = ENOTSUP;
    609                 }
    610         }else{
    611                 usb_log_error("root hub received empty transaction?");
    612                 opResult = EINVAL;
    613         }
    614         return opResult;
    615 }
    616 
    617 /**
    618  * process root hub request
    619  *
    620  * @param instance root hub instance
    621  * @param request structure containing both request and response information
    622  * @return error code
     518 * @param instance
     519 * @param request
     520 * @return
    623521 */
    624522int rh_request(rh_t *instance, usb_transfer_batch_t *request)
     
    628526        int opResult;
    629527        if(request->transfer_type == USB_TRANSFER_CONTROL){
    630                 usb_log_info("Root hub got CONTROL packet\n");
    631                 opResult = process_ctrl_request(instance,request);
     528                if (request->setup_buffer) {
     529                        usb_log_info("Root hub got CTRL packet: %s.\n",
     530                                usb_debug_str_buffer((const uint8_t *)request->setup_buffer, 8, 8));
     531                        if(sizeof(usb_device_request_setup_packet_t)>request->setup_size){
     532                                usb_log_error("setup packet too small\n");
     533                                return EINVAL;
     534                        }
     535                        usb_device_request_setup_packet_t * setup_request =
     536                                        (usb_device_request_setup_packet_t*)request->setup_buffer;
     537                        if(
     538                                setup_request->request == USB_DEVREQ_GET_STATUS
     539                                || setup_request->request == USB_DEVREQ_GET_DESCRIPTOR
     540                                || setup_request->request == USB_DEVREQ_GET_CONFIGURATION
     541                        ){
     542                                usb_log_debug("processing request with output\n");
     543                                opResult = process_request_with_output(instance,request);
     544                        }else if(
     545                                setup_request->request == USB_DEVREQ_CLEAR_FEATURE
     546                                || setup_request->request == USB_DEVREQ_SET_FEATURE
     547                                || setup_request->request == USB_DEVREQ_SET_ADDRESS
     548                        ){
     549                                usb_log_debug("processing request without additional data\n");
     550                                opResult = process_request_without_data(instance,request);
     551                        }else if(setup_request->request == USB_DEVREQ_SET_DESCRIPTOR
     552                                        || setup_request->request == USB_DEVREQ_SET_CONFIGURATION
     553                        ){
     554                                usb_log_debug("processing request with input\n");
     555                                opResult = process_request_with_input(instance,request);
     556                        }else{
     557                                usb_log_warning("received unsuported request: %d\n",
     558                                                setup_request->request
     559                                                );
     560                                opResult = ENOTSUP;
     561                        }
     562                }else{
     563                        usb_log_error("root hub received empty transaction?");
     564                        opResult = EINVAL;
     565                }
    632566        }else if(request->transfer_type == USB_TRANSFER_INTERRUPT){
    633567                usb_log_info("Root hub got INTERRUPT packet\n");
     
    648582void rh_interrupt(rh_t *instance)
    649583{
    650         usb_log_info("Whoa whoa wait, I`m not supposed to receive any interrupts, am I?\n");
    651         /* TODO: implement? */
     584        usb_log_error("Root hub interrupt not implemented.\n");
     585        /* TODO: implement */
    652586}
    653587/**
Note: See TracChangeset for help on using the changeset viewer.