Changeset 8123695a in mainline for uspace/drv/ohci/root_hub.c


Ignore:
Timestamp:
2011-04-02T16:07:29Z (13 years ago)
Author:
Matus Dekanek <smekideki@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
322a8066
Parents:
c6ba274
Message:

ohci root hub set/clear feature requests redesigned
hub: fix for non-removable devices 3.0

File:
1 edited

Legend:

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

    rc6ba274 r8123695a  
    110110        .poll_interval = 255,
    111111};
     112
     113static const uint32_t hub_clear_feature_valid_mask =
     114        (1 << USB_HUB_FEATURE_C_HUB_LOCAL_POWER) +
     115        (1 << USB_HUB_FEATURE_C_HUB_OVER_CURRENT);
     116
     117static const uint32_t hub_clear_feature_by_writing_one_mask =
     118        1 << USB_HUB_FEATURE_C_HUB_LOCAL_POWER;
     119
     120static const uint32_t hub_set_feature_valid_mask =
     121        (1 << USB_HUB_FEATURE_C_HUB_OVER_CURRENT);
     122
     123       
     124static const uint32_t hub_set_feature_direct_mask =
     125        (1 << USB_HUB_FEATURE_C_HUB_OVER_CURRENT);
     126
     127static const uint32_t port_set_feature_valid_mask =
     128        (1 << USB_HUB_FEATURE_PORT_ENABLE) +
     129        (1 << USB_HUB_FEATURE_PORT_SUSPEND) +
     130        (1 << USB_HUB_FEATURE_PORT_RESET) +
     131        (1 << USB_HUB_FEATURE_PORT_POWER);
     132
     133static const uint32_t port_clear_feature_valid_mask =
     134        (1 << USB_HUB_FEATURE_PORT_CONNECTION) +
     135        (1 << USB_HUB_FEATURE_PORT_SUSPEND) +
     136        (1 << USB_HUB_FEATURE_PORT_OVER_CURRENT) +
     137        (1 << USB_HUB_FEATURE_PORT_POWER) +
     138        (1 << USB_HUB_FEATURE_C_PORT_CONNECTION) +
     139        (1 << USB_HUB_FEATURE_C_PORT_ENABLE) +
     140        (1 << USB_HUB_FEATURE_C_PORT_SUSPEND) +
     141        (1 << USB_HUB_FEATURE_C_PORT_OVER_CURRENT) +
     142        (1 << USB_HUB_FEATURE_C_PORT_RESET);
     143//note that USB_HUB_FEATURE_PORT_POWER bit is translated into USB_HUB_FEATURE_PORT_LOW_SPEED
     144
     145
     146
    112147
    113148/**
     
    212247        instance->registers = regs;
    213248        instance->device = dev;
     249        instance->port_count = instance->registers->rh_desc_a & 0xff;
    214250        rh_init_descriptors(instance);
     251        /// \TODO set port power mode
    215252
    216253
     
    426463
    427464/**
    428  * process feature-enabling/disabling request on hub
     465 * process feature-enabling request on hub
    429466 *
    430467 * @param instance root hub instance
    431468 * @param feature feature selector
    432  * @param enable enable or disable specified feature
    433469 * @return error code
    434470 */
    435471static int process_hub_feature_set_request(rh_t *instance,
    436                 uint16_t feature, bool enable){
    437         if(feature > USB_HUB_FEATURE_C_HUB_OVER_CURRENT)
     472                uint16_t feature){
     473        if(! ((1<<feature) & hub_set_feature_valid_mask))
    438474                return EINVAL;
    439475        instance->registers->rh_status =
    440                         enable ?
    441476                        (instance->registers->rh_status | (1<<feature))
    442                         :
    443                         (instance->registers->rh_status & (~(1<<feature)));
    444         /// \TODO any error?
    445         return EOK;
    446 }
    447 
    448 /**
    449  * process feature-enabling/disabling request on hub
     477                        & (~ hub_clear_feature_by_writing_one_mask);
     478        return EOK;
     479}
     480
     481/**
     482 * process feature-disabling request on hub
     483 *
     484 * @param instance root hub instance
     485 * @param feature feature selector
     486 * @return error code
     487 */
     488static int process_hub_feature_clear_request(rh_t *instance,
     489                uint16_t feature){
     490        if(! ((1<<feature) & hub_clear_feature_valid_mask))
     491                return EINVAL;
     492        //is the feature cleared directly?
     493        if ((1<<feature) & hub_set_feature_direct_mask){
     494                instance->registers->rh_status =
     495                        (instance->registers->rh_status & (~(1<<feature)))
     496                        & (~ hub_clear_feature_by_writing_one_mask);
     497        }else{//the feature is cleared by writing '1'
     498                instance->registers->rh_status =
     499                                (instance->registers->rh_status
     500                                & (~ hub_clear_feature_by_writing_one_mask))
     501                                | (1<<feature);
     502        }
     503        return EOK;
     504}
     505
     506
     507
     508/**
     509 * process feature-enabling request on hub
    450510 *
    451511 * @param instance root hub instance
     
    456516 */
    457517static int process_port_feature_set_request(rh_t *instance,
    458                 uint16_t feature, uint16_t port, bool enable){
    459         if(feature > USB_HUB_FEATURE_C_PORT_RESET)
     518                uint16_t feature, uint16_t port){
     519        if(!((1<<feature) & port_set_feature_valid_mask))
    460520                return EINVAL;
    461521        if(port<1 || port>instance->port_count)
    462522                return EINVAL;
    463523        instance->registers->rh_port_status[port - 1] =
    464                         enable ?
    465524                        (instance->registers->rh_port_status[port - 1] | (1<<feature))
    466                         :
    467                         (instance->registers->rh_port_status[port - 1] & (~(1<<feature)));
     525                        & (~port_clear_feature_valid_mask);
    468526        /// \TODO any error?
    469527        return EOK;
    470528}
     529
     530/**
     531 * process feature-disabling request on hub
     532 *
     533 * @param instance root hub instance
     534 * @param feature feature selector
     535 * @param port port number, counted from 1
     536 * @param enable enable or disable the specified feature
     537 * @return error code
     538 */
     539static int process_port_feature_clear_request(rh_t *instance,
     540                uint16_t feature, uint16_t port){
     541        if(!((1<<feature) & port_clear_feature_valid_mask))
     542                return EINVAL;
     543        if(port<1 || port>instance->port_count)
     544                return EINVAL;
     545        if(feature == USB_HUB_FEATURE_PORT_POWER)
     546                feature = USB_HUB_FEATURE_PORT_LOW_SPEED;
     547        if(feature == USB_HUB_FEATURE_PORT_SUSPEND)
     548                feature = USB_HUB_FEATURE_PORT_OVER_CURRENT;
     549        instance->registers->rh_port_status[port - 1] =
     550                        (instance->registers->rh_port_status[port - 1]
     551                        & (~port_clear_feature_valid_mask))
     552                        | (1<<feature);
     553        /// \TODO any error?
     554        return EOK;
     555}
     556
    471557
    472558/**
     
    550636                        (usb_device_request_setup_packet_t*)request->setup_buffer;
    551637        request->transfered_size = 0;
    552         if(setup_request->request == USB_DEVREQ_CLEAR_FEATURE
    553                                 || setup_request->request == USB_DEVREQ_SET_FEATURE){
     638        if(setup_request->request == USB_DEVREQ_CLEAR_FEATURE){
    554639                if(setup_request->request_type == USB_HUB_REQ_TYPE_SET_HUB_FEATURE){
    555640                        usb_log_debug("USB_HUB_REQ_TYPE_SET_HUB_FEATURE\n");
    556                         return process_hub_feature_set_request(instance, setup_request->value,
    557                                         setup_request->request == USB_DEVREQ_SET_FEATURE);
     641                        return process_hub_feature_clear_request(instance,
     642                                        setup_request->value);
    558643                }
    559644                if(setup_request->request_type == USB_HUB_REQ_TYPE_SET_PORT_FEATURE){
    560645                        usb_log_debug("USB_HUB_REQ_TYPE_SET_PORT_FEATURE\n");
    561                         return process_port_feature_set_request(instance, setup_request->value,
    562                                         setup_request->index,
    563                                         setup_request->request == USB_DEVREQ_SET_FEATURE);
     646                        return process_port_feature_clear_request(instance,
     647                                        setup_request->value,
     648                                        setup_request->index);
     649                }
     650                usb_log_debug("USB_HUB_REQ_TYPE_INVALID %d\n",
     651                                setup_request->request_type);
     652                return EINVAL;
     653        }
     654        if(setup_request->request == USB_DEVREQ_SET_FEATURE){
     655                if(setup_request->request_type == USB_HUB_REQ_TYPE_SET_HUB_FEATURE){
     656                        usb_log_debug("USB_HUB_REQ_TYPE_SET_HUB_FEATURE\n");
     657                        return process_hub_feature_set_request(instance,
     658                                        setup_request->value);
     659                }
     660                if(setup_request->request_type == USB_HUB_REQ_TYPE_SET_PORT_FEATURE){
     661                        usb_log_debug("USB_HUB_REQ_TYPE_SET_PORT_FEATURE\n");
     662                        return process_port_feature_set_request(instance,
     663                                        setup_request->value,
     664                                        setup_request->index);
    564665                }
    565666                usb_log_debug("USB_HUB_REQ_TYPE_INVALID %d\n",setup_request->request_type);
Note: See TracChangeset for help on using the changeset viewer.