Changeset f3da9b2 in mainline


Ignore:
Timestamp:
2011-03-26T16:51:57Z (13 years ago)
Author:
Matus Dekanek <smekideki@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
aee6c73
Parents:
e6223239
Message:

ohci root hub codelifting

File:
1 edited

Legend:

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

    re6223239 rf3da9b2  
    6464/*----------------------------------------------------------------------------*/
    6565
    66 
     66/**
     67 * create answer to port status_request
     68 *
     69 * Copy content of corresponding port status register to answer buffer.
     70 *
     71 * @param instance root hub instance
     72 * @param port port number, counted from 1
     73 * @param request structure containing both request and response information
     74 * @return error code
     75 */
    6776static int process_get_port_status_request(rh_t *instance, uint16_t port,
    6877                usb_transfer_batch_t * request){
     
    7584}
    7685
     86/**
     87 * create answer to port status_request
     88 *
     89 * Copy content of hub status register to answer buffer.
     90 *
     91 * @param instance root hub instance
     92 * @param request structure containing both request and response information
     93 * @return error code
     94 */
    7795static int process_get_hub_status_request(rh_t *instance,
    7896                usb_transfer_batch_t * request){
     
    86104}
    87105
    88 static void usb_create_serialized_hub_descriptor(rh_t *instance, uint8_t ** out_result,
     106/**
     107 * Create hub descriptor used in hub-driver <-> hub communication
     108 *
     109 * This means creating byt array from data in root hub registers. For more
     110 * info see usb hub specification.
     111 *
     112 * @param instance root hub instance
     113 * @param@out out_result pointer to resultant serialized descriptor
     114 * @param@out out_size size of serialized descriptor
     115 */
     116static void usb_create_serialized_hub_descriptor(rh_t *instance,
     117                uint8_t ** out_result,
    89118                size_t * out_size) {
    90119        //base size
     
    126155
    127156
     157/**
     158 * create answer to status request
     159 *
     160 * This might be either hub status or port status request. If neither,
     161 * ENOTSUP is returned.
     162 * @param instance root hub instance
     163 * @param request structure containing both request and response information
     164 * @return error code
     165 */
    128166static int process_get_status_request(rh_t *instance,
    129167                usb_transfer_batch_t * request)
     
    148186}
    149187
     188/**
     189 * create answer to status interrupt consisting of change bitmap
     190 *
     191 * Result contains bitmap where bit 0 indicates change on hub and
     192 * bit i indicates change on i`th port (i>0). For more info see
     193 * Hub and Port status bitmap specification in USB specification.
     194 * @param instance root hub instance
     195 * @param@out buffer pointer to created interrupt mas
     196 * @param@out buffer_size size of created interrupt mask
     197 */
    150198static void create_interrupt_mask(rh_t *instance, void ** buffer,
    151199                size_t * buffer_size){
     
    171219}
    172220
    173 
     221/**
     222 * create standard device descriptor for a hub
     223 * @return newly allocated descriptor
     224 */
     225static usb_standard_device_descriptor_t *
     226        usb_ohci_rh_create_standard_device_descriptor(){
     227        usb_standard_device_descriptor_t * descriptor =
     228                                (usb_standard_device_descriptor_t*)
     229                                malloc(sizeof(usb_standard_device_descriptor_t));
     230        descriptor->configuration_count = 1;
     231        descriptor->descriptor_type = USB_DESCTYPE_DEVICE;
     232        descriptor->device_class = USB_CLASS_HUB;
     233        descriptor->device_protocol = 0;
     234        descriptor->device_subclass = 0;
     235        descriptor->device_version = 0;
     236        descriptor->length = sizeof(usb_standard_device_descriptor_t);
     237        /// \TODO this value is guessed
     238        descriptor->max_packet_size = 8;
     239        descriptor->product_id = 0x0001;
     240        /// \TODO these values migt be different
     241        descriptor->str_serial_number = 0;
     242        descriptor->str_serial_number = 0;
     243        descriptor->usb_spec_version = 0;
     244        descriptor->vendor_id = 0x16db;
     245        return descriptor;
     246}
     247
     248/**
     249 * create standart configuration descriptor for the root hub instance
     250 * @param instance root hub instance
     251 * @return newly allocated descriptor
     252 */
     253static usb_standard_configuration_descriptor_t *
     254usb_ohci_rh_create_standart_configuration_descriptor(rh_t *instance){
     255        usb_standard_configuration_descriptor_t * descriptor =
     256                        (usb_standard_configuration_descriptor_t*)
     257                        malloc(sizeof(usb_standard_configuration_descriptor_t));
     258        /// \TODO some values are default or guessed
     259        descriptor->attributes = 1<<7;
     260        descriptor->configuration_number = 1;
     261        descriptor->descriptor_type = USB_DESCTYPE_CONFIGURATION;
     262        descriptor->interface_count = 1;
     263        descriptor->length = sizeof(usb_standard_configuration_descriptor_t);
     264        descriptor->max_power = 100;
     265        descriptor->str_configuration = 0;
     266        /// \TODO should this include device descriptor?
     267        size_t hub_descriptor_size = 7 +
     268                        2* (instance->port_count / 8 +
     269                        ((instance->port_count % 8 > 0) ? 1 : 0));
     270        descriptor->total_length =
     271                        sizeof(usb_standard_configuration_descriptor_t)+
     272                        sizeof(usb_standard_endpoint_descriptor_t)+
     273                        sizeof(usb_standard_interface_descriptor_t)+
     274                        hub_descriptor_size;
     275        return descriptor;
     276}
     277
     278/**
     279 * create standard interface descriptor for a root hub
     280 * @return newly allocated descriptor
     281 */
     282static usb_standard_interface_descriptor_t *
     283usb_ohci_rh_create_standard_interface_descriptor(){
     284        usb_standard_interface_descriptor_t * descriptor =
     285                                (usb_standard_interface_descriptor_t*)
     286                                malloc(sizeof(usb_standard_interface_descriptor_t));
     287        descriptor->alternate_setting = 0;
     288        descriptor->descriptor_type = USB_DESCTYPE_INTERFACE;
     289        descriptor->endpoint_count = 1;
     290        descriptor->interface_class = USB_CLASS_HUB;
     291        /// \TODO is this correct?
     292        descriptor->interface_number = 1;
     293        descriptor->interface_protocol = 0;
     294        descriptor->interface_subclass = 0;
     295        descriptor->length = sizeof(usb_standard_interface_descriptor_t);
     296        descriptor->str_interface = 0;
     297        return descriptor;
     298}
     299
     300/**
     301 * create standard endpoint descriptor for a root hub
     302 * @return newly allocated descriptor
     303 */
     304static usb_standard_endpoint_descriptor_t *
     305usb_ohci_rh_create_standard_endpoint_descriptor(){
     306        usb_standard_endpoint_descriptor_t * descriptor =
     307                        (usb_standard_endpoint_descriptor_t*)
     308                        malloc(sizeof(usb_standard_endpoint_descriptor_t));
     309        descriptor->attributes = USB_TRANSFER_INTERRUPT;
     310        descriptor->descriptor_type = USB_DESCTYPE_ENDPOINT;
     311        descriptor->endpoint_address = 1 + (1<<7);
     312        descriptor->length = sizeof(usb_standard_endpoint_descriptor_t);
     313        descriptor->max_packet_size = 8;
     314        descriptor->poll_interval = 255;
     315        return descriptor;
     316}
     317
     318/**
     319 * create answer to a descriptor request
     320 *
     321 * This might be a request for standard (configuration, device, endpoint or
     322 * interface) or device specific (hub) descriptor.
     323 * @param instance root hub instance
     324 * @param request structure containing both request and response information
     325 * @return error code
     326 */
    174327static int process_get_descriptor_request(rh_t *instance,
    175328                usb_transfer_batch_t *request){
    176         /// \TODO
    177329        usb_device_request_setup_packet_t * setup_request =
    178330                        (usb_device_request_setup_packet_t*)request->setup_buffer;
     
    191343                //create std device descriptor
    192344                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;
     345                result_descriptor =
     346                                usb_ohci_rh_create_standard_device_descriptor();
    212347                size = sizeof(usb_standard_device_descriptor_t);
    213348        }else if(setup_request_value == USB_DESCTYPE_CONFIGURATION){
    214349                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;
     350                result_descriptor =
     351                                usb_ohci_rh_create_standart_configuration_descriptor(instance);
    236352                size = sizeof(usb_standard_configuration_descriptor_t);
    237353
    238354        }else if(setup_request_value == USB_DESCTYPE_INTERFACE){
    239355                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;
     356                result_descriptor =
     357                                usb_ohci_rh_create_standard_interface_descriptor();
    254358                size = sizeof(usb_standard_interface_descriptor_t);
    255359        }else if(setup_request_value == USB_DESCTYPE_ENDPOINT){
    256360                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;
     361                result_descriptor =
     362                                usb_ohci_rh_create_standard_endpoint_descriptor();
    267363                size = sizeof(usb_standard_endpoint_descriptor_t);
    268364        }else{
     
    286382}
    287383
     384/**
     385 * answer to get configuration request
     386 *
     387 * Root hub works independently on the configuration.
     388 * @param instance root hub instance
     389 * @param request structure containing both request and response information
     390 * @return error code
     391 */
    288392static int process_get_configuration_request(rh_t *instance,
    289393                usb_transfer_batch_t *request){
     
    297401}
    298402
     403/**
     404 * process feature-enabling/disabling request on hub
     405 *
     406 * @param instance root hub instance
     407 * @param feature feature selector
     408 * @param enable enable or disable specified feature
     409 * @return error code
     410 */
    299411static int process_hub_feature_set_request(rh_t *instance,
    300412                uint16_t feature, bool enable){
     
    310422}
    311423
     424/**
     425 * process feature-enabling/disabling request on hub
     426 *
     427 * @param instance root hub instance
     428 * @param feature feature selector
     429 * @param port port number, counted from 1
     430 * @param enable enable or disable the specified feature
     431 * @return error code
     432 */
    312433static int process_port_feature_set_request(rh_t *instance,
    313434                uint16_t feature, uint16_t port, bool enable){
     
    325446}
    326447
     448/**
     449 * register address to this device
     450 *
     451 * @param instance root hub instance
     452 * @param address new address
     453 * @return error code
     454 */
    327455static int process_address_set_request(rh_t *instance,
    328456                uint16_t address){
     
    331459}
    332460
     461/**
     462 * process one of requests that requere output data
     463 *
     464 * Request can be one of USB_DEVREQ_GET_STATUS, USB_DEVREQ_GET_DESCRIPTOR or
     465 * USB_DEVREQ_GET_CONFIGURATION.
     466 * @param instance root hub instance
     467 * @param request structure containing both request and response information
     468 * @return error code
     469 */
    333470static int process_request_with_output(rh_t *instance,
    334471                usb_transfer_batch_t *request){
     
    350487}
    351488
     489/**
     490 * process one of requests that carry input data
     491 *
     492 * Request can be one of USB_DEVREQ_SET_DESCRIPTOR or
     493 * USB_DEVREQ_SET_CONFIGURATION.
     494 * @param instance root hub instance
     495 * @param request structure containing both request and response information
     496 * @return error code
     497 */
    352498static int process_request_with_input(rh_t *instance,
    353499                usb_transfer_batch_t *request){
     
    366512}
    367513
    368 
     514/**
     515 * process one of requests that do not request nor carry additional data
     516 *
     517 * Request can be one of USB_DEVREQ_CLEAR_FEATURE, USB_DEVREQ_SET_FEATURE or
     518 * USB_DEVREQ_SET_ADDRESS.
     519 * @param instance root hub instance
     520 * @param request structure containing both request and response information
     521 * @return error code
     522 */
    369523static int process_request_without_data(rh_t *instance,
    370524                usb_transfer_batch_t *request){
     
    396550}
    397551
    398 
    399 /**
    400  *
    401  * @param instance
    402  * @param request
    403  * @return
     552/**
     553 * process hub control request
     554 *
     555 * If needed, writes answer into the request structure.
     556 * Request can be one of
     557 * USB_DEVREQ_GET_STATUS,
     558 * USB_DEVREQ_GET_DESCRIPTOR,
     559 * USB_DEVREQ_GET_CONFIGURATION,
     560 * USB_DEVREQ_CLEAR_FEATURE,
     561 * USB_DEVREQ_SET_FEATURE,
     562 * USB_DEVREQ_SET_ADDRESS,
     563 * USB_DEVREQ_SET_DESCRIPTOR or
     564 * USB_DEVREQ_SET_CONFIGURATION.
     565 *
     566 * @param instance root hub instance
     567 * @param request structure containing both request and response information
     568 * @return error code
     569 */
     570static int process_ctrl_request(rh_t *instance, usb_transfer_batch_t *request){
     571        int opResult;
     572        if (request->setup_buffer) {
     573                if(sizeof(usb_device_request_setup_packet_t)>request->setup_size){
     574                        usb_log_error("setup packet too small\n");
     575                        return EINVAL;
     576                }
     577                usb_log_info("CTRL packet: %s.\n",
     578                        usb_debug_str_buffer((const uint8_t *)request->setup_buffer, 8, 8));
     579                usb_device_request_setup_packet_t * setup_request =
     580                                (usb_device_request_setup_packet_t*)request->setup_buffer;
     581                if(
     582                        setup_request->request == USB_DEVREQ_GET_STATUS
     583                        || setup_request->request == USB_DEVREQ_GET_DESCRIPTOR
     584                        || setup_request->request == USB_DEVREQ_GET_CONFIGURATION
     585                ){
     586                        usb_log_debug("processing request with output\n");
     587                        opResult = process_request_with_output(instance,request);
     588                }else if(
     589                        setup_request->request == USB_DEVREQ_CLEAR_FEATURE
     590                        || setup_request->request == USB_DEVREQ_SET_FEATURE
     591                        || setup_request->request == USB_DEVREQ_SET_ADDRESS
     592                ){
     593                        usb_log_debug("processing request without additional data\n");
     594                        opResult = process_request_without_data(instance,request);
     595                }else if(setup_request->request == USB_DEVREQ_SET_DESCRIPTOR
     596                                || setup_request->request == USB_DEVREQ_SET_CONFIGURATION
     597                ){
     598                        usb_log_debug("processing request with input\n");
     599                        opResult = process_request_with_input(instance,request);
     600                }else{
     601                        usb_log_warning("received unsuported request: %d\n",
     602                                        setup_request->request
     603                                        );
     604                        opResult = ENOTSUP;
     605                }
     606        }else{
     607                usb_log_error("root hub received empty transaction?");
     608                opResult = EINVAL;
     609        }
     610        return opResult;
     611}
     612
     613/**
     614 * process root hub request
     615 *
     616 * @param instance root hub instance
     617 * @param request structure containing both request and response information
     618 * @return error code
    404619 */
    405620int rh_request(rh_t *instance, usb_transfer_batch_t *request)
     
    409624        int opResult;
    410625        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                 }
     626                usb_log_info("Root hub got CONTROL packet\n");
     627                opResult = process_ctrl_request(instance,request);
    449628        }else if(request->transfer_type == USB_TRANSFER_INTERRUPT){
    450629                usb_log_info("Root hub got INTERRUPT packet\n");
     
    465644void rh_interrupt(rh_t *instance)
    466645{
    467         usb_log_error("Root hub interrupt not implemented.\n");
    468         /* TODO: implement */
     646        usb_log_info("Whoa whoa wait, I`m not supposed to receive interrupts, am I?\n");
     647        /* TODO: implement? */
    469648}
    470649/**
Note: See TracChangeset for help on using the changeset viewer.