Changeset bfc5c9dd in mainline for uspace/drv/bus/usb/ohci/root_hub.c


Ignore:
Timestamp:
2012-02-23T20:42:30Z (12 years ago)
Author:
Jan Vesely <jano.vesely@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
815b244a
Parents:
ffcc5776
Message:

ohci: Use more generic approach to access registers(and convert endian).

Make hc initialization work by design, not by accident. (Fixes random hang on startup).
Queues still disabled.

File:
1 edited

Legend:

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

    rffcc5776 rbfc5c9dd  
    154154
    155155        instance->registers = regs;
    156         instance->port_count = RHDA_NDS(instance->registers->rh_desc_a);
    157         usb_log_debug("rh_desc_a: %x.\n", instance->registers->rh_desc_a);
     156        instance->port_count = OHCI_RD(regs->rh_desc_a) & RHDA_NDS_MASK;
     157        usb_log_debug2("rh_desc_a: %x.\n", OHCI_RD(regs->rh_desc_a));
    158158        if (instance->port_count > 15) {
    159159                usb_log_warning("OHCI specification does not allow more than 15"
     
    167167
    168168#if defined OHCI_POWER_SWITCH_no
     169        usb_log_debug("OHCI rh: Set power mode to no power switching.\n");
    169170        /* Set port power mode to no power-switching. (always on) */
    170         instance->registers->rh_desc_a |= RHDA_NPS_FLAG;
     171        OHCI_SET(regs->rh_desc_a, RHDA_NPS_FLAG);
    171172
    172173        /* Set to no over-current reporting */
    173         instance->registers->rh_desc_a |= RHDA_NOCP_FLAG;
     174        OHCI_SET(regs->rh_desc_a, RHDA_NOCP_FLAG);
    174175
    175176#elif defined OHCI_POWER_SWITCH_ganged
    176         /* Set port power mode to no ganged power-switching. */
    177         instance->registers->rh_desc_a &= ~RHDA_NPS_FLAG;
    178         instance->registers->rh_desc_a &= ~RHDA_PSM_FLAG;
    179         instance->registers->rh_status = RHS_CLEAR_GLOBAL_POWER;
     177        usb_log_debug("OHCI rh: Set power mode to ganged power switching.\n");
     178        /* Set port power mode to ganged power-switching. */
     179        OHCI_CLEAR(regs->rh_desc_a, RHDA_NPS_FLAG);
     180        OHCI_CLEAR(regs->rh_desc_a, RHDA_PSM_FLAG);
     181
     182        /* Turn off power (hub driver will turn this back on)*/
     183        OHCI_WR(regs->rh_status, RHS_CLEAR_GLOBAL_POWER);
    180184
    181185        /* Set to global over-current */
    182         instance->registers->rh_desc_a &= ~RHDA_NOCP_FLAG;
    183         instance->registers->rh_desc_a &= ~RHDA_OCPM_FLAG;
     186        OHCI_CLEAR(regs->rh_desc_a, RHDA_NOCP_FLAG);
     187        OHCI_CLEAR(regs->rh_desc_a, RHDA_OCPM_FLAG);
    184188#else
    185         /* Set port power mode to no per port power-switching. */
    186         instance->registers->rh_desc_a &= ~RHDA_NPS_FLAG;
    187         instance->registers->rh_desc_a |= RHDA_PSM_FLAG;
     189        usb_log_debug("OHCI rh: Set power mode to per-port power switching.\n");
     190        /* Set port power mode to per port power-switching. */
     191        OHCI_CLR(regs->rh_desc_a, RHDA_NPS_FLAG);
     192        OHCI_SET(regs->rh_desc_a, RHDA_PSM_FLAG);
    188193
    189194        /* Control all ports by global switch and turn them off */
    190         instance->registers->rh_desc_b &= ~RHDB_PCC_WRITE(~0);
    191         instance->registers->rh_status = RHS_CLEAR_GLOBAL_POWER;
     195        OHCI_CLR(regs->rh_desc_b, RHDB_PCC_MASK << RHDB_PCC_SHIFT);
     196        OHCI_WR(regs->rh_status, RHS_CLEAR_GLOBAL_POWER);
    192197
    193198        /* Return control to per port state */
    194         instance->registers->rh_desc_b |= RHDB_PCC_WRITE(~0);
     199        OHCI_SET(regs->rh_desc_b, RHDB_PCC_MASK << RHDB_PCC_SHIFT);
    195200
    196201        /* Set per port over-current */
    197         instance->registers->rh_desc_a &= ~RHDA_NOCP_FLAG;
    198         instance->registers->rh_desc_a |= RHDA_OCPM_FLAG;
     202        OHCI_CLR(regs->rh_desc_a, RHDA_NOCP_FLAG);
     203        OHCI_SET(regs->rh_desc_a, RHDA_OCPM_FLAG);
    199204#endif
    200205
     
    285290        instance->hub_descriptor_size = size;
    286291
    287         const uint32_t hub_desc = instance->registers->rh_desc_a;
    288         const uint32_t port_desc = instance->registers->rh_desc_b;
     292        const uint32_t hub_desc = OHCI_RD(instance->registers->rh_desc_a);
     293        const uint32_t port_desc = OHCI_RD(instance->registers->rh_desc_b);
    289294
    290295        /* bDescLength */
     
    308313        instance->descriptors.hub[4] = 0;
    309314        /* bPwrOn2PwrGood */
    310         instance->descriptors.hub[5] = RHDA_POTPGT(hub_desc);
     315        instance->descriptors.hub[5] = hub_desc >> RHDA_POTPGT_SHIFT;
    311316        /* bHubContrCurrent, root hubs don't need no power. */
    312317        instance->descriptors.hub[6] = 0;
    313318
    314319        /* Device Removable and some legacy 1.0 stuff*/
    315         instance->descriptors.hub[7] = RHDB_DR_READ(port_desc) & 0xff;
     320        instance->descriptors.hub[7] = (port_desc >> RHDB_DR_SHIFT) & 0xff;
    316321        instance->descriptors.hub[8] = 0xff;
    317322        if (instance->interrupt_mask_size == 2) {
    318                 instance->descriptors.hub[8] = RHDB_DR_READ(port_desc) >> 8;
     323                instance->descriptors.hub[8] =
     324                    (port_desc >> RHDB_DR_SHIFT) >> 8;
    319325                instance->descriptors.hub[9]  = 0xff;
    320326                instance->descriptors.hub[10] = 0xff;
     
    364370
    365371        /* Only local power source change and over-current change can happen */
    366         if (instance->registers->rh_status & (RHS_LPSC_FLAG | RHS_OCIC_FLAG)) {
     372        if (OHCI_RD(instance->registers->rh_status)
     373            & (RHS_LPSC_FLAG | RHS_OCIC_FLAG)) {
    367374                mask |= 1;
    368375        }
    369376        for (size_t port = 1; port <= instance->port_count; ++port) {
    370377                /* Write-clean bits are those that indicate change */
    371                 if (RHPS_CHANGE_WC_MASK
    372                     & instance->registers->rh_port_status[port - 1]) {
    373 
     378                if (OHCI_RD(instance->registers->rh_port_status[port - 1])
     379                    & RHPS_CHANGE_WC_MASK) {
    374380                        mask |= (1 << port);
    375381                }
     
    396402        usb_device_request_setup_packet_t *request_packet =
    397403            (usb_device_request_setup_packet_t*)request->setup_buffer;
     404
     405        const uint16_t index = uint16_usb2host(request_packet->index);
    398406
    399407        switch (request_packet->request_type)
     
    406414                        TRANSFER_END(request, EOVERFLOW);
    407415                } else {
    408                         uint32_t data = instance->registers->rh_status &
    409                             (RHS_LPS_FLAG | RHS_LPSC_FLAG
    410                                 | RHS_OCI_FLAG | RHS_OCIC_FLAG);
     416                        const uint32_t data =
     417                            OHCI_RD(instance->registers->rh_status) &
     418                                (RHS_LPS_FLAG | RHS_LPSC_FLAG
     419                                    | RHS_OCI_FLAG | RHS_OCIC_FLAG);
    411420                        TRANSFER_END_DATA(request, &data, sizeof(data));
    412421                }
     
    420429                        TRANSFER_END(request, EOVERFLOW);
    421430                } else {
    422                         unsigned port = request_packet->index;
     431                        const unsigned port = index;
    423432                        if (port < 1 || port > instance->port_count)
    424433                                TRANSFER_END(request, EINVAL);
    425 
    426                         uint32_t data =
    427                             instance->registers->rh_port_status[port - 1];
     434                        /* Register format matches the format of port status
     435                         * field */
     436                        const uint32_t data = uint32_usb2host(OHCI_RD(
     437                            instance->registers->rh_port_status[port - 1]));
    428438                        TRANSFER_END_DATA(request, &data, sizeof(data));
    429439                }
     
    441451        case SETUP_REQUEST_TO_HOST(USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_INTERFACE):
    442452                /* Hubs are allowed to have only one interface */
    443                 if (request_packet->index != 0)
     453                if (index != 0)
    444454                        TRANSFER_END(request, EINVAL);
    445455                /* Fall through, as the answer will be the same: 0x0000 */
    446456        case SETUP_REQUEST_TO_HOST(USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_ENDPOINT):
    447457                /* Endpoint 0 (default control) and 1 (interrupt) */
    448                 if (request_packet->index >= 2)
     458                if (index >= 2)
    449459                        TRANSFER_END(request, EINVAL);
    450460
     
    455465                } else {
    456466                        /* Endpoints are OK. (We don't halt) */
    457                         uint16_t data = 0;
     467                        const uint16_t data = 0;
    458468                        TRANSFER_END_DATA(request, &data, sizeof(data));
    459469                }
     
    556566        switch (feature)
    557567        {
    558         case USB_HUB_FEATURE_PORT_POWER:   //8
    559                 /* No power switching */
    560                 if (instance->registers->rh_desc_a & RHDA_NPS_FLAG)
    561                         return EOK;
    562                 /* Ganged power switching */
    563                 if (!(instance->registers->rh_desc_a & RHDA_PSM_FLAG)) {
    564                         instance->registers->rh_status = RHS_SET_GLOBAL_POWER;
    565                         return EOK;
     568        case USB_HUB_FEATURE_PORT_POWER:   /*8*/
     569                {
     570                        const uint32_t rhda =
     571                            OHCI_RD(instance->registers->rh_desc_a);
     572                        /* No power switching */
     573                        if (rhda & RHDA_NPS_FLAG)
     574                                return EOK;
     575                        /* Ganged power switching, one port powers all */
     576                        if (!(rhda & RHDA_PSM_FLAG)) {
     577                                OHCI_WR(instance->registers->rh_status,
     578                                    RHS_SET_GLOBAL_POWER);
     579                                return EOK;
     580                        }
    566581                }
    567         case USB_HUB_FEATURE_PORT_ENABLE:  //1
    568         case USB_HUB_FEATURE_PORT_SUSPEND: //2
    569         case USB_HUB_FEATURE_PORT_RESET:   //4
    570                 usb_log_debug2(
    571                     "Setting port ENABLE, SUSPEND or RESET on port %zu.\n",
    572                     port);
    573                 instance->registers->rh_port_status[port - 1] =
    574                     RHPS_FEATURE_BIT(feature);
     582                        /* Fall through */
     583        case USB_HUB_FEATURE_PORT_ENABLE:  /*1*/
     584        case USB_HUB_FEATURE_PORT_SUSPEND: /*2*/
     585        case USB_HUB_FEATURE_PORT_RESET:   /*4*/
     586                usb_log_debug2("Setting port POWER, ENABLE, SUSPEND or RESET "
     587                    "on port %zu.\n", port);
     588                OHCI_WR(instance->registers->rh_port_status[port - 1],
     589                    1 << feature);
    575590                return EOK;
    576591        default:
     
    598613        switch (feature)
    599614        {
    600         case USB_HUB_FEATURE_PORT_POWER:          //8
    601                 /* No power switching */
    602                 if (instance->registers->rh_desc_a & RHDA_NPS_FLAG)
    603                         return ENOTSUP;
    604                 /* Ganged power switching */
    605                 if (!(instance->registers->rh_desc_a & RHDA_PSM_FLAG)) {
    606                         instance->registers->rh_status = RHS_CLEAR_GLOBAL_POWER;
     615        case USB_HUB_FEATURE_PORT_POWER:          /*8*/
     616                {
     617                        const uint32_t rhda =
     618                            OHCI_RD(instance->registers->rh_desc_a);
     619                        /* No power switching */
     620                        if (rhda & RHDA_NPS_FLAG)
     621                                return ENOTSUP;
     622                        /* Ganged power switching, one port powers all */
     623                        if (!(rhda & RHDA_PSM_FLAG)) {
     624                                OHCI_WR(instance->registers->rh_status,
     625                                    RHS_CLEAR_GLOBAL_POWER);
     626                                return EOK;
     627                        }
     628                        OHCI_WR(instance->registers->rh_port_status[port - 1],
     629                            RHPS_CLEAR_PORT_POWER);
    607630                        return EOK;
    608631                }
    609                 instance->registers->rh_port_status[port - 1] =
    610                         RHPS_CLEAR_PORT_POWER;
     632
     633        case USB_HUB_FEATURE_PORT_ENABLE:         /*1*/
     634                OHCI_WR(instance->registers->rh_port_status[port - 1],
     635                    RHPS_CLEAR_PORT_ENABLE);
    611636                return EOK;
    612637
    613         case USB_HUB_FEATURE_PORT_ENABLE:         //1
    614                 instance->registers->rh_port_status[port - 1] =
    615                         RHPS_CLEAR_PORT_ENABLE;
     638        case USB_HUB_FEATURE_PORT_SUSPEND:        /*2*/
     639                OHCI_WR(instance->registers->rh_port_status[port - 1],
     640                    RHPS_CLEAR_PORT_SUSPEND);
    616641                return EOK;
    617642
    618         case USB_HUB_FEATURE_PORT_SUSPEND:        //2
    619                 instance->registers->rh_port_status[port - 1] =
    620                         RHPS_CLEAR_PORT_SUSPEND;
    621                 return EOK;
    622 
    623         case USB_HUB_FEATURE_C_PORT_CONNECTION:   //16
    624         case USB_HUB_FEATURE_C_PORT_ENABLE:       //17
    625         case USB_HUB_FEATURE_C_PORT_SUSPEND:      //18
    626         case USB_HUB_FEATURE_C_PORT_OVER_CURRENT: //19
    627         case USB_HUB_FEATURE_C_PORT_RESET:        //20
     643        case USB_HUB_FEATURE_C_PORT_CONNECTION:   /*16*/
     644        case USB_HUB_FEATURE_C_PORT_ENABLE:       /*17*/
     645        case USB_HUB_FEATURE_C_PORT_SUSPEND:      /*18*/
     646        case USB_HUB_FEATURE_C_PORT_OVER_CURRENT: /*19*/
     647        case USB_HUB_FEATURE_C_PORT_RESET:        /*20*/
    628648                usb_log_debug2("Clearing port C_CONNECTION, C_ENABLE, "
    629                     "C_SUSPEND or C_RESET on port %zu.\n",
    630                     port);
    631                 instance->registers->rh_port_status[port - 1] =
    632                     RHPS_FEATURE_BIT(feature);
     649                    "C_SUSPEND, C_OC or C_RESET on port %zu.\n", port);
     650                /* Bit offsets correspond to the feature number */
     651                OHCI_WR(instance->registers->rh_port_status[port - 1],
     652                    1 << feature);
    633653                return EOK;
    634654
     
    658678        case USB_HUB_REQ_TYPE_SET_PORT_FEATURE:
    659679                usb_log_debug("USB_HUB_REQ_TYPE_SET_PORT_FEATURE\n");
    660                 int ret = set_feature_port(instance,
     680                const int ret = set_feature_port(instance,
    661681                    setup_request->value, setup_request->index);
    662682                TRANSFER_END(request, ret);
     
    697717        case USB_HUB_REQ_TYPE_CLEAR_PORT_FEATURE:
    698718                usb_log_debug("USB_HUB_REQ_TYPE_CLEAR_PORT_FEATURE\n");
    699                 int ret = clear_feature_port(instance,
     719                const int ret = clear_feature_port(instance,
    700720                    setup_request->value, setup_request->index);
    701721                TRANSFER_END(request, ret);
     
    710730                 * as root hubs do not support local power status feature.
    711731                 * (OHCI pg. 127) */
    712                 if (setup_request->value == USB_HUB_FEATURE_C_HUB_OVER_CURRENT) {
    713                         instance->registers->rh_status = RHS_OCIC_FLAG;
     732                if (uint16_usb2host(setup_request->value)
     733                    == USB_HUB_FEATURE_C_HUB_OVER_CURRENT) {
     734                        OHCI_WR(instance->registers->rh_status, RHS_OCIC_FLAG);
    714735                        TRANSFER_END(request, EOK);
    715736                }
     
    775796                if (request->buffer_size == 0)
    776797                        TRANSFER_END(request, EOVERFLOW);
    777                 uint8_t config = 1;
     798                const uint8_t config = 1;
    778799                TRANSFER_END_DATA(request, &config, sizeof(config));
    779800
     
    794815                        TRANSFER_END(request, EINVAL);
    795816
    796                 instance->address = setup_request->value;
     817                instance->address = uint16_usb2host(setup_request->value);
    797818                TRANSFER_END(request, EOK);
    798819
Note: See TracChangeset for help on using the changeset viewer.