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


Ignore:
Timestamp:
2011-03-26T17:24:33Z (14 years ago)
Author:
Matus Dekanek <smekideki@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
b330b309
Parents:
c9f5e238 (diff), aee6c73 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

fix of #132(non-removable devices), code of ohci root hub driver commented

File:
1 edited

Legend:

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

    rc9f5e238 rcee51fd  
    117117/*----------------------------------------------------------------------------*/
    118118
    119 
     119/**
     120 * create answer to port status_request
     121 *
     122 * Copy content of corresponding port status register to answer buffer.
     123 *
     124 * @param instance root hub instance
     125 * @param port port number, counted from 1
     126 * @param request structure containing both request and response information
     127 * @return error code
     128 */
    120129static int process_get_port_status_request(rh_t *instance, uint16_t port,
    121130                usb_transfer_batch_t * request){
     
    128137}
    129138
     139/**
     140 * create answer to port status_request
     141 *
     142 * Copy content of hub status register to answer buffer.
     143 *
     144 * @param instance root hub instance
     145 * @param request structure containing both request and response information
     146 * @return error code
     147 */
    130148static int process_get_hub_status_request(rh_t *instance,
    131149                usb_transfer_batch_t * request){
     
    139157}
    140158
    141 static void usb_create_serialized_hub_descriptor(rh_t *instance, uint8_t ** out_result,
     159/**
     160 * Create hub descriptor used in hub-driver <-> hub communication
     161 *
     162 * This means creating byt array from data in root hub registers. For more
     163 * info see usb hub specification.
     164 *
     165 * @param instance root hub instance
     166 * @param@out out_result pointer to resultant serialized descriptor
     167 * @param@out out_size size of serialized descriptor
     168 */
     169static void usb_create_serialized_hub_descriptor(rh_t *instance,
     170                uint8_t ** out_result,
    142171                size_t * out_size) {
    143172        //base size
     
    179208
    180209
     210/**
     211 * create answer to status request
     212 *
     213 * This might be either hub status or port status request. If neither,
     214 * ENOTSUP is returned.
     215 * @param instance root hub instance
     216 * @param request structure containing both request and response information
     217 * @return error code
     218 */
    181219static int process_get_status_request(rh_t *instance,
    182220                usb_transfer_batch_t * request)
     
    201239}
    202240
     241/**
     242 * create answer to status interrupt consisting of change bitmap
     243 *
     244 * Result contains bitmap where bit 0 indicates change on hub and
     245 * bit i indicates change on i`th port (i>0). For more info see
     246 * Hub and Port status bitmap specification in USB specification.
     247 * @param instance root hub instance
     248 * @param@out buffer pointer to created interrupt mas
     249 * @param@out buffer_size size of created interrupt mask
     250 */
    203251static void create_interrupt_mask(rh_t *instance, void ** buffer,
    204252                size_t * buffer_size){
     
    224272}
    225273
    226 
     274/**
     275 * create standard device descriptor for a hub
     276 * @return newly allocated descriptor
     277 */
     278static usb_standard_device_descriptor_t *
     279        usb_ohci_rh_create_standard_device_descriptor(){
     280        usb_standard_device_descriptor_t * descriptor =
     281                                (usb_standard_device_descriptor_t*)
     282                                malloc(sizeof(usb_standard_device_descriptor_t));
     283        descriptor->configuration_count = 1;
     284        descriptor->descriptor_type = USB_DESCTYPE_DEVICE;
     285        descriptor->device_class = USB_CLASS_HUB;
     286        descriptor->device_protocol = 0;
     287        descriptor->device_subclass = 0;
     288        descriptor->device_version = 0;
     289        descriptor->length = sizeof(usb_standard_device_descriptor_t);
     290        /// \TODO this value is guessed
     291        descriptor->max_packet_size = 8;
     292        descriptor->product_id = 0x0001;
     293        /// \TODO these values migt be different
     294        descriptor->str_serial_number = 0;
     295        descriptor->str_serial_number = 0;
     296        descriptor->usb_spec_version = 0;
     297        descriptor->vendor_id = 0x16db;
     298        return descriptor;
     299}
     300
     301/**
     302 * create standart configuration descriptor for the root hub instance
     303 * @param instance root hub instance
     304 * @return newly allocated descriptor
     305 */
     306static usb_standard_configuration_descriptor_t *
     307usb_ohci_rh_create_standart_configuration_descriptor(rh_t *instance){
     308        usb_standard_configuration_descriptor_t * descriptor =
     309                        (usb_standard_configuration_descriptor_t*)
     310                        malloc(sizeof(usb_standard_configuration_descriptor_t));
     311        /// \TODO some values are default or guessed
     312        descriptor->attributes = 1<<7;
     313        descriptor->configuration_number = 1;
     314        descriptor->descriptor_type = USB_DESCTYPE_CONFIGURATION;
     315        descriptor->interface_count = 1;
     316        descriptor->length = sizeof(usb_standard_configuration_descriptor_t);
     317        descriptor->max_power = 100;
     318        descriptor->str_configuration = 0;
     319        /// \TODO should this include device descriptor?
     320        size_t hub_descriptor_size = 7 +
     321                        2* (instance->port_count / 8 +
     322                        ((instance->port_count % 8 > 0) ? 1 : 0));
     323        descriptor->total_length =
     324                        sizeof(usb_standard_configuration_descriptor_t)+
     325                        sizeof(usb_standard_endpoint_descriptor_t)+
     326                        sizeof(usb_standard_interface_descriptor_t)+
     327                        hub_descriptor_size;
     328        return descriptor;
     329}
     330
     331/**
     332 * create standard interface descriptor for a root hub
     333 * @return newly allocated descriptor
     334 */
     335static usb_standard_interface_descriptor_t *
     336usb_ohci_rh_create_standard_interface_descriptor(){
     337        usb_standard_interface_descriptor_t * descriptor =
     338                                (usb_standard_interface_descriptor_t*)
     339                                malloc(sizeof(usb_standard_interface_descriptor_t));
     340        descriptor->alternate_setting = 0;
     341        descriptor->descriptor_type = USB_DESCTYPE_INTERFACE;
     342        descriptor->endpoint_count = 1;
     343        descriptor->interface_class = USB_CLASS_HUB;
     344        /// \TODO is this correct?
     345        descriptor->interface_number = 1;
     346        descriptor->interface_protocol = 0;
     347        descriptor->interface_subclass = 0;
     348        descriptor->length = sizeof(usb_standard_interface_descriptor_t);
     349        descriptor->str_interface = 0;
     350        return descriptor;
     351}
     352
     353/**
     354 * create standard endpoint descriptor for a root hub
     355 * @return newly allocated descriptor
     356 */
     357static usb_standard_endpoint_descriptor_t *
     358usb_ohci_rh_create_standard_endpoint_descriptor(){
     359        usb_standard_endpoint_descriptor_t * descriptor =
     360                        (usb_standard_endpoint_descriptor_t*)
     361                        malloc(sizeof(usb_standard_endpoint_descriptor_t));
     362        descriptor->attributes = USB_TRANSFER_INTERRUPT;
     363        descriptor->descriptor_type = USB_DESCTYPE_ENDPOINT;
     364        descriptor->endpoint_address = 1 + (1<<7);
     365        descriptor->length = sizeof(usb_standard_endpoint_descriptor_t);
     366        descriptor->max_packet_size = 8;
     367        descriptor->poll_interval = 255;
     368        return descriptor;
     369}
     370
     371/**
     372 * create answer to a descriptor request
     373 *
     374 * This might be a request for standard (configuration, device, endpoint or
     375 * interface) or device specific (hub) descriptor.
     376 * @param instance root hub instance
     377 * @param request structure containing both request and response information
     378 * @return error code
     379 */
    227380static int process_get_descriptor_request(rh_t *instance,
    228381                usb_transfer_batch_t *request){
    229         /// \TODO
    230382        usb_device_request_setup_packet_t * setup_request =
    231383                        (usb_device_request_setup_packet_t*)request->setup_buffer;
    232384        size_t size;
    233         const void * result_descriptor;
     385        const void * result_descriptor = NULL;
    234386        const uint16_t setup_request_value = setup_request->value_high;
    235387                        //(setup_request->value_low << 8);
     388#if 0
    236389        bool del = false;
    237 
     390        //this code was merged from development and has to be reviewed
    238391        switch (setup_request_value)
    239392        {
     
    295448        }
    296449        }
    297 #if 0
     450#endif
    298451        if(setup_request_value == USB_DESCTYPE_HUB){
    299452                usb_log_debug("USB_DESCTYPE_HUB\n");
     
    306459                //create std device descriptor
    307460                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;
     461                result_descriptor =
     462                                usb_ohci_rh_create_standard_device_descriptor();
    327463                size = sizeof(usb_standard_device_descriptor_t);
    328464        }else if(setup_request_value == USB_DESCTYPE_CONFIGURATION){
    329465                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;
     466                result_descriptor =
     467                                usb_ohci_rh_create_standart_configuration_descriptor(instance);
    351468                size = sizeof(usb_standard_configuration_descriptor_t);
    352469
    353470        }else if(setup_request_value == USB_DESCTYPE_INTERFACE){
    354471                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;
     472                result_descriptor =
     473                                usb_ohci_rh_create_standard_interface_descriptor();
    369474                size = sizeof(usb_standard_interface_descriptor_t);
    370475        }else if(setup_request_value == USB_DESCTYPE_ENDPOINT){
    371476                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;
     477                result_descriptor =
     478                                usb_ohci_rh_create_standard_endpoint_descriptor();
    382479                size = sizeof(usb_standard_endpoint_descriptor_t);
    383480        }else{
     
    392489                return EINVAL;
    393490        }
    394 #endif
    395491        if(request->buffer_size < size){
    396492                size = request->buffer_size;
     
    398494        request->transfered_size = size;
    399495        memcpy(request->buffer,result_descriptor,size);
    400         if (del)
     496        if (result_descriptor)
    401497                free(result_descriptor);
    402498        return EOK;
    403499}
    404500
     501/**
     502 * answer to get configuration request
     503 *
     504 * Root hub works independently on the configuration.
     505 * @param instance root hub instance
     506 * @param request structure containing both request and response information
     507 * @return error code
     508 */
    405509static int process_get_configuration_request(rh_t *instance,
    406510                usb_transfer_batch_t *request){
     
    414518}
    415519
     520/**
     521 * process feature-enabling/disabling request on hub
     522 *
     523 * @param instance root hub instance
     524 * @param feature feature selector
     525 * @param enable enable or disable specified feature
     526 * @return error code
     527 */
    416528static int process_hub_feature_set_request(rh_t *instance,
    417529                uint16_t feature, bool enable){
     
    427539}
    428540
     541/**
     542 * process feature-enabling/disabling request on hub
     543 *
     544 * @param instance root hub instance
     545 * @param feature feature selector
     546 * @param port port number, counted from 1
     547 * @param enable enable or disable the specified feature
     548 * @return error code
     549 */
    429550static int process_port_feature_set_request(rh_t *instance,
    430551                uint16_t feature, uint16_t port, bool enable){
     
    442563}
    443564
     565/**
     566 * register address to this device
     567 *
     568 * @param instance root hub instance
     569 * @param address new address
     570 * @return error code
     571 */
    444572static int process_address_set_request(rh_t *instance,
    445573                uint16_t address){
     
    448576}
    449577
     578/**
     579 * process one of requests that requere output data
     580 *
     581 * Request can be one of USB_DEVREQ_GET_STATUS, USB_DEVREQ_GET_DESCRIPTOR or
     582 * USB_DEVREQ_GET_CONFIGURATION.
     583 * @param instance root hub instance
     584 * @param request structure containing both request and response information
     585 * @return error code
     586 */
    450587static int process_request_with_output(rh_t *instance,
    451588                usb_transfer_batch_t *request){
     
    467604}
    468605
     606/**
     607 * process one of requests that carry input data
     608 *
     609 * Request can be one of USB_DEVREQ_SET_DESCRIPTOR or
     610 * USB_DEVREQ_SET_CONFIGURATION.
     611 * @param instance root hub instance
     612 * @param request structure containing both request and response information
     613 * @return error code
     614 */
    469615static int process_request_with_input(rh_t *instance,
    470616                usb_transfer_batch_t *request){
     
    483629}
    484630
    485 
     631/**
     632 * process one of requests that do not request nor carry additional data
     633 *
     634 * Request can be one of USB_DEVREQ_CLEAR_FEATURE, USB_DEVREQ_SET_FEATURE or
     635 * USB_DEVREQ_SET_ADDRESS.
     636 * @param instance root hub instance
     637 * @param request structure containing both request and response information
     638 * @return error code
     639 */
    486640static int process_request_without_data(rh_t *instance,
    487641                usb_transfer_batch_t *request){
     
    513667}
    514668
    515 
    516 /**
    517  *
    518  * @param instance
    519  * @param request
    520  * @return
     669/**
     670 * process hub control request
     671 *
     672 * If needed, writes answer into the request structure.
     673 * Request can be one of
     674 * USB_DEVREQ_GET_STATUS,
     675 * USB_DEVREQ_GET_DESCRIPTOR,
     676 * USB_DEVREQ_GET_CONFIGURATION,
     677 * USB_DEVREQ_CLEAR_FEATURE,
     678 * USB_DEVREQ_SET_FEATURE,
     679 * USB_DEVREQ_SET_ADDRESS,
     680 * USB_DEVREQ_SET_DESCRIPTOR or
     681 * USB_DEVREQ_SET_CONFIGURATION.
     682 *
     683 * @param instance root hub instance
     684 * @param request structure containing both request and response information
     685 * @return error code
     686 */
     687static int process_ctrl_request(rh_t *instance, usb_transfer_batch_t *request){
     688        int opResult;
     689        if (request->setup_buffer) {
     690                if(sizeof(usb_device_request_setup_packet_t)>request->setup_size){
     691                        usb_log_error("setup packet too small\n");
     692                        return EINVAL;
     693                }
     694                usb_log_info("CTRL packet: %s.\n",
     695                        usb_debug_str_buffer((const uint8_t *)request->setup_buffer, 8, 8));
     696                usb_device_request_setup_packet_t * setup_request =
     697                                (usb_device_request_setup_packet_t*)request->setup_buffer;
     698                if(
     699                        setup_request->request == USB_DEVREQ_GET_STATUS
     700                        || setup_request->request == USB_DEVREQ_GET_DESCRIPTOR
     701                        || setup_request->request == USB_DEVREQ_GET_CONFIGURATION
     702                ){
     703                        usb_log_debug("processing request with output\n");
     704                        opResult = process_request_with_output(instance,request);
     705                }else if(
     706                        setup_request->request == USB_DEVREQ_CLEAR_FEATURE
     707                        || setup_request->request == USB_DEVREQ_SET_FEATURE
     708                        || setup_request->request == USB_DEVREQ_SET_ADDRESS
     709                ){
     710                        usb_log_debug("processing request without additional data\n");
     711                        opResult = process_request_without_data(instance,request);
     712                }else if(setup_request->request == USB_DEVREQ_SET_DESCRIPTOR
     713                                || setup_request->request == USB_DEVREQ_SET_CONFIGURATION
     714                ){
     715                        usb_log_debug("processing request with input\n");
     716                        opResult = process_request_with_input(instance,request);
     717                }else{
     718                        usb_log_warning("received unsuported request: %d\n",
     719                                        setup_request->request
     720                                        );
     721                        opResult = ENOTSUP;
     722                }
     723        }else{
     724                usb_log_error("root hub received empty transaction?");
     725                opResult = EINVAL;
     726        }
     727        return opResult;
     728}
     729
     730/**
     731 * process root hub request
     732 *
     733 * @param instance root hub instance
     734 * @param request structure containing both request and response information
     735 * @return error code
    521736 */
    522737int rh_request(rh_t *instance, usb_transfer_batch_t *request)
     
    526741        int opResult;
    527742        if(request->transfer_type == USB_TRANSFER_CONTROL){
    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                 }
     743                usb_log_info("Root hub got CONTROL packet\n");
     744                opResult = process_ctrl_request(instance,request);
    566745        }else if(request->transfer_type == USB_TRANSFER_INTERRUPT){
    567746                usb_log_info("Root hub got INTERRUPT packet\n");
     
    582761void rh_interrupt(rh_t *instance)
    583762{
    584         usb_log_error("Root hub interrupt not implemented.\n");
    585         /* TODO: implement */
     763        usb_log_info("Whoa whoa wait, I`m not supposed to receive interrupts, am I?\n");
     764        /* TODO: implement? */
    586765}
    587766/**
Note: See TracChangeset for help on using the changeset viewer.