⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usbehcdrhemulation.c

📁 vxWorks下USB2.0中的EHCI的HCD源码,极具有参考价值
💻 C
📖 第 1 页 / 共 5 页
字号:
            OS_MEMCPY(&uPortStatus,
                      (pHCDData->RHData.pPortStatus +
                       (pSetup->wIndex -1)),
                      USB_EHCD_RH_PORT_STATUS_SIZE);

            /* Swap the data to the LE format */

            uPortStatus = OS_UINT32_LE_TO_CPU(uPortStatus);

            /* Clear the suspend bit */

            uPortStatus &= ~(USB_EHCD_RH_PORT_SUSPEND_MASK);

            /* Update the suspend change */

            uPortStatus |= USB_EHCD_RH_PORT_SUSPEND_CHANGE;

            /* Swap the data to CPU format data */

            uPortStatus = OS_UINT32_CPU_TO_LE(uPortStatus);

            /* Copy the status back to the port status */

            OS_MEMCPY((pHCDData->RHData.pPortStatus +
                       (pSetup->wIndex -1)),
                       &uPortStatus,
                       USB_EHCD_RH_PORT_STATUS_SIZE);
            /*
             * Call the function to populate the interrupt
             * status data
             */

            usbEhcdCopyRHInterruptData(
                     pHCDData,
                     (USB_EHCD_RH_MASK_VALUE << (pSetup->wIndex -1)));
            break;
            }
        case USB_EHCD_RH_PORT_POWER:  /* Port Power */
            {
            /* Switch off power in the port */

            USB_EHCD_CLR_BIT_PORT(pHCDData,
                              (pSetup->wIndex) -1,
                              PORT_POWER);

            /* Update the URB status */

            pURB->nStatus = USBHST_SUCCESS;
            break;
            }
        case USB_EHCD_RH_C_PORT_CONNECTION:/* c_port_connection */
            {
            if (USB_EHCD_GET_FIELD_PORT(pHCDData,
                                        ((pSetup->wIndex) -1),
                                        CONNECT_STATUS_CHANGE) != 0)
                {

                /* Clear the connection status change */

                USB_EHCD_CLR_BIT_PORT(pHCDData,
                                  ((pSetup->wIndex) -1),
                                  CONNECT_STATUS_CHANGE);
                }
            /* This condition can happen if the EHCI does not support
             * port power switching. In this case, if a device is connected
             * while the target boots up, there is no connect status change
             * and no root hub status change interrupt which is generated
             */
            else
                {
                /* To hold the status of the port */

                UINT32 uPortStatus = 0;

                /* Copy the value in the port status register */

                OS_MEMCPY(&uPortStatus,
                          (pHCDData->RHData.pPortStatus +
                           ((pSetup->wIndex) -1)),
                          USB_EHCD_RH_PORT_STATUS_SIZE);

                /* Swap the data from the LE format */

                uPortStatus = OS_UINT32_LE_TO_CPU(uPortStatus);

                /* Update the connect status change */

                uPortStatus &= ~(USB_EHCD_RH_PORT_CONNECT_CHANGE);

                /* Swap the data to LE format data */

                uPortStatus = OS_UINT32_CPU_TO_LE(uPortStatus);

                /* Copy the status back to the port status */

                OS_MEMCPY((pHCDData->RHData.pPortStatus +
                           ((pSetup->wIndex) -1)),
                           &uPortStatus,
                           USB_EHCD_RH_PORT_STATUS_SIZE);

                }
            /* Update the URB status */

            pURB->nStatus = USBHST_SUCCESS;
            break;
            }
        case USB_EHCD_RH_C_PORT_ENABLE:/* c_port_enabled */
            {
            /* Clear the port enable disable change */

            USB_EHCD_CLR_BIT_PORT(pHCDData,
                              ((pSetup->wIndex) -1),
                              PORT_ENABLE_DISABLE_CHANGE);

            /* Update the URB status */

            pURB->nStatus = USBHST_SUCCESS;
            break;
            }
        case USB_EHCD_RH_C_PORT_OVER_CURRENT:/* c_port_over_current */
            {
            /* Clear the overcurrent change */

            USB_EHCD_CLR_BIT_PORT(pHCDData,
                              ((pSetup->wIndex) -1),
                              OVER_CURRENT_CHANGE);

            /* Update the URB status */

            pURB->nStatus = USBHST_SUCCESS;
            break;
            }
        case USB_EHCD_RH_PORT_INDICATOR:/* Port Indicator */
            {
            /* Clear the Port indicator */

            USB_EHCD_CLR_BIT_PORT(pHCDData,
                              ((pSetup->wIndex & USB_EHCD_RH_PORT_NUMBER_MASK) -1),
                              PORT_INDICATOR_CONTROL);

            /* Update the URB status */

            pURB->nStatus = USBHST_SUCCESS;
            break;
            }
        case USB_EHCD_RH_PORT_TEST: /* Port test */
            {
            /* Clear the Port test */

            USB_EHCD_CLR_BIT_PORT(pHCDData,
                              ((pSetup->wValue & USB_EHCD_RH_PORT_NUMBER_MASK) -1),
                              PORT_TEST_CONTROL);

            /* Update the URB status */

            pURB->nStatus = USBHST_SUCCESS;
            break;
            }

        case USB_EHCD_RH_C_PORT_RESET:/* c_port_reset */
            {
            /* To hold the status of the port */

            UINT32 uPortStatus = 0;

            /* Clear the internal data for reset change */
            /* Copy the value in the port status register */

            OS_MEMCPY(&uPortStatus,
                      (pHCDData->RHData.pPortStatus +
                       (pSetup->wIndex -1)),
                      USB_EHCD_RH_PORT_STATUS_SIZE);

            /* Swap the data to the LE format */

            uPortStatus = OS_UINT32_LE_TO_CPU(uPortStatus);

            /* Update the reset change */

            uPortStatus &= (~USB_EHCD_RH_PORT_RESET_CHANGE);

            /* Swap the data to CPU format data */

            uPortStatus = OS_UINT32_CPU_TO_LE(uPortStatus);

            /* Copy the status back to the port status */

            OS_MEMCPY((pHCDData->RHData.pPortStatus +
                       (pSetup->wIndex -1)),
                       &uPortStatus,
                       USB_EHCD_RH_PORT_STATUS_SIZE);

            /* Update the URB status */

            pURB->nStatus = USBHST_SUCCESS;

            /*
             * Call the function to populate the interrupt
             * status data
             */
#if 0
            usbEhcdCopyRHInterruptData(
                     pHCDData,
                     (USB_EHCD_RH_MASK_VALUE << (pSetup->wIndex -1))); 
#endif
            break;
            }

        case USB_EHCD_RH_C_PORT_SUSPEND:/* c_port_suspend */
            {
            /* To hold the status of the port */

            UINT32 uPortStatus = 0;

            /* Clear the internal data for suspend change */

            /* Copy the value in the port status register */

            OS_MEMCPY(&uPortStatus,
                      (pHCDData->RHData.pPortStatus +
                       (pSetup->wIndex -1)),
                      USB_EHCD_RH_PORT_STATUS_SIZE);

            /* Update the suspend change */

            uPortStatus &= (~USB_EHCD_RH_PORT_SUSPEND_CHANGE);

            /* Copy the status back to the port status */

            OS_MEMCPY((pHCDData->RHData.pPortStatus +
                       (pSetup->wIndex -1)),
                       &uPortStatus,
                       USB_EHCD_RH_PORT_STATUS_SIZE);

            /* Update the URB status */

            pURB->nStatus = USBHST_SUCCESS;

            /*
             * Call the function to populate the interrupt
             * status data
             */

            usbEhcdCopyRHInterruptData(
                     pHCDData,
                     (USB_EHCD_RH_MASK_VALUE << (pSetup->wIndex -1)));
            break;
            }
        default:  /* Unknown feature */
            {
            pURB->nStatus = USBHST_INVALID_REQUEST;
            break;
            }/* End of default */
        }/* End of switch () */

    OS_LOG_MESSAGE_LOW(EHCD,"usbEhcdRhClearPortFeature - Exit\n",0,0,0,0);

    return Status;
    }
    /* End of usbEhcdRhClearPortFeature() */

/***************************************************************************
*
* usbEhcdRhGetHubDescriptor - get the hub descriptor
*
* This routine gets the hub descriptor.
*
* RETURNS: USBHST_SUCCESS if the URB is submitted successfully.
* USBHST_INVALID_PARAMETER if the parameters are not valid.
*
* ERRNO:
*   None.
*/

USBHST_STATUS usbEhcdRhGetHubDescriptor
    (
    pUSB_EHCD_DATA pHCDData,           /* Ptr to HCD block           */
    pUSBHST_URB	   pURB                /* Ptr to User Request Block  */
    )
    {
    /* To hold the request status */

    USBHST_STATUS Status = USBHST_SUCCESS;

    /* Pointer to the setup packet */

    pUSBHST_SETUP_PACKET pSetup = NULL;

    /* To hold the number of bytes alloted for the port information */

    UINT32 uPortBytes = 0;

    /* To hold the index into the ports */

    UINT32 uIndex = 0;

    /* Pointer to the buffer */

    UCHAR *pBuffer = NULL;

    OS_LOG_MESSAGE_LOW(EHCD,"usbEhcdRhGetHubDescriptor - Entry\n",0,0,0,0);

    /* Check the validity of the parameters */

    if (NULL == pHCDData ||
        NULL == pURB ||
        NULL == pURB->pTransferSpecificData ||
        NULL == pURB->pTransferBuffer)
        {
        OS_LOG_MESSAGE_HIGH(EHCD,"usbEhcdRhGetHubDescriptor - \
                                           Invalid parameters\n",0,0,0,0);

        pURB->nStatus = USBHST_INVALID_PARAMETER;

        return USBHST_INVALID_PARAMETER;
        }

    /* Extract the setup packet */

    pSetup = (pUSBHST_SETUP_PACKET)pURB->pTransferSpecificData;

    /*
     * Check whether there are any invalid conditions.
     * i.e invalid DevRequest parameters
     */

    if(0x2900 != pSetup->wValue ||
       0 != pSetup->wIndex)
        {
        OS_LOG_MESSAGE_HIGH(EHCD,"usbEhcdRhGetHubDescriptor - \
                                           Invalid parameters\n",0,0,0,0);
        pURB->nStatus = USBHST_INVALID_PARAMETER;
        return USBHST_INVALID_PARAMETER;
        }

    /*
     * Determine the number of bytes that the descriptor would occupy
     * ie. the num of bytes req to accomodate info about the ports
     */

    uPortBytes = (pHCDData->RHData.uNumDownstreamPorts) / 8;
    if(0 != pHCDData->RHData.uNumDownstreamPorts % 8)
        {
        uPortBytes++;
        }

    /* Allocate memory for the buffer */

    pBuffer = (UCHAR *)OS_MALLOC(7 + (uPortBytes * 2));

    /* Check if memory allocation is successful */

    if(NULL == pBuffer)
        {
        OS_LOG_MESSAGE_HIGH(EHCD,"usbEhcdRhGetHubDescriptor - \
                                           Memory not allocated\n",0,0,0,0);
        pURB->nStatus = USBHST_MEMORY_NOT_ALLOCATED;
        return USBHST_MEMORY_NOT_ALLOCATED;
        }

    /* Population of the values of hub descriptor - Start */

    /* Length of the descriptor */

    pBuffer[0] = 7 + (uPortBytes * 2);

    /* Hub Descriptor type */

    pBuffer[1] = 0x29;

    /* Number of downstream ports */

    pBuffer[2] = pHCDData->RHData.uNumDownstreamPorts;

    /*
     * The following 2 bytes give the hub characteristics
     * The root hub has individual port overcurrent indication
     * Read the Port power control field and update whether the root hub
     * supports per port power switching or ganged power switching.
     */

    pBuffer[3] = 0x08 | USB_EHCD_GET_FIELD(pHCDData,
                                       HCSPARAMS,
                                       PPC);
    pBuffer[4] = 0;

    /* The power On to Power Good Time for the Root hub is 1 * 2ms */
    pBuffer[5] = 1;

    /* There are no specific maximim current requirements */

    pBuffer[6] = 0;

    /* The last few bytes of the descriptor is based on the number of ports */

    for(uIndex = 0;uIndex < uPortBytes ; uIndex++)
        {
        /* Indicates whether the hub is removable */

        pBuffer[7+uIndex] = 0;

        /* Port power control mask should be 1 for all the ports */

        pBuffer[7+uPortBytes+uIndex] = 0xff;
        }

    /* Population of the values of hub descriptor - End */

    /* Update the length */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -