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

📄 usbehcdutil.c

📁 vxWorks下USB2.0中的EHCI的HCD源码,极具有参考价值
💻 C
📖 第 1 页 / 共 5 页
字号:
** This function is used to calculate the bus time required for the endpoint.** <uSpeed> - Speed of the device.* <uDirection> - Direction of the pipe.* <uPipeType> - Type of the endpoint.* <uDataByteCount>  - maximum byte count supported by the pipe.** RETURNS: Calculated bus time in nanoseconds.** ERRNO:*   None.** \NOMANUAL*/INT32 usbEhcdCalculateBusTime    (    UINT32 uSpeed,     /* Speed of the device */    UINT32 uDirection, /* Direction of the pipe */    UINT32 uPipeType,  /* type of the pipe */    UINT32 uDataByteCount /* Maximum byte count supported by the pipe */    )    {    /* Calculate the bus time for a low speed pipe */    if(USBHST_LOW_SPEED == uSpeed)        {        /* Calculate the bustime for an IN pipe */        if (USB_EHCD_DIR_IN == uDirection)            {            return (INT32)(64060+(2*USB_EHCD_HUB_LS_SETUP)+(676.67*                    floor(3.167+USB_EHCD_BIT_STUFF_TIME(uDataByteCount)))+                    USB_EHCD_HOST_DELAY);            }        /* Calculate the bustime for an OUT pipe */        else            {            return (INT32)(64107+(2*USB_EHCD_HUB_LS_SETUP)+(667.0*                    floor(3.167+USB_EHCD_BIT_STUFF_TIME(uDataByteCount)))+                    USB_EHCD_HOST_DELAY);            }        }        /* End of if(Speed == USBHST_LOW_SPEED) */    /* Calculate the bus time for a Full speed pipe */    else if(USBHST_FULL_SPEED == uSpeed)        {        /* Calculate the bus time for a control, bulk or interrupt pipe */        if( USBHST_ISOCHRONOUS_TRANSFER != uPipeType)            {            return(INT32)(9107 +(83.54 *                   floor(3.167+                   USB_EHCD_BIT_STUFF_TIME(uDataByteCount)))+                   USB_EHCD_HOST_DELAY);            }            /* Calculate the bus time for an isochronous pipe */        else            {#if 0	/* Just to recheck BW calculation currently returning 'zero'*/            /* Calculate the bus time for an IN endpoint */            if  (USB_EHCD_DIR_IN == uDirection)                {                return (INT32)(7268+(83.54 *                        floor(3.167+                        USB_EHCD_BIT_STUFF_TIME(uDataByteCount)))+                        USB_EHCD_HOST_DELAY);                }                /* Calculate the bus time for an OUT endpoint */            else                {                return (INT32)(6265+(83.54 *                        floor(3.167+USB_EHCD_BIT_STUFF_TIME(uDataByteCount)))+                        USB_EHCD_HOST_DELAY);                }#endifreturn 1;            }            /* End of else */        }        /* End of else if(Speed == USBHST_FULL_SPEED) */    /* Calculate the bus time for a high speed pipe */    else if(USBHST_HIGH_SPEED == uSpeed)        {        /* Calculate the bus time for a control, bulk or interrupt pipe */        if(USBHST_ISOCHRONOUS_TRANSFER != uPipeType)            {            return (INT32)((55 * 8 * 2.083)+(2.083*                    floor(3.167 + USB_EHCD_BIT_STUFF_TIME(uDataByteCount))) +                    USB_EHCD_HOST_DELAY);            }        /* Calculate the bus time for an isochronous pipe */        else            {            return (INT32)((38 * 8 * 2.083)+(2.083*                    floor(3.167 + USB_EHCD_BIT_STUFF_TIME(uDataByteCount))) +                    USB_EHCD_HOST_DELAY);            }        }        /* End of else if(Speed == USBHST_HIGH_SPEED) */    return -1;    }    /* End of usbEhcdCalculateBusTime() *//***************************************************************************** usbEhcdCheckBandwidth - checks the bandwidth availability** This function is used to check whether bandwidth is available and returns the* list which can hold the endpoint and also the mask value which indicates the* microframes which can hold the endpoint transfers.** <pHCDData> - Pointer to the EHCD_DATA structure.* <uBandwidth > - Bandwidth to be reserved.* <uSpeed> - Speed of the transfer.* <pEndpointDesc>  - Pointer to the endpoint descriptor.* <puListIndex> - Pointer which can hold the list index which holds the endpoint*                 transfers* <puMicroFrameMask> - Pointer to the mask value which can hold the microframes*                      which can hold the endpoint transfers.* <puStepValue> - Pointer to the step value used for stepping into the*                 frame list for isochronous transfers.* RETURNS: TRUE if the bandwidth can be accomodated.*          FALSE if the bandwidth cannot be accomodated.** ERRNO:*   None.** \NOMANUAL*/BOOLEAN usbEhcdCheckBandwidth    (    pUSB_EHCD_DATA  pHCDData,  /* Pointer to the EHCD_DATA structure */    ULONG       uBandwidth, /* Bandwidth to be reserved */    UINT32      uSpeed,     /* Speed of the transfer */    pUSBHST_ENDPOINT_DESCRIPTOR pEndpointDesc, /* Pointer to the endpoint desc */    UINT32  *   puListIndex,/* Pointer to the list index */    UINT32  *   puMicroFrameMask, /* Pointer to the microframe mask value */    UINT32  *   puStepValue /* Pointer to the step value into the framelist */    )    {    /* To hold the index into the periodic frame list */    UINT32 uCount = 0;    /* To hold the polling interval */    UINT32 uPollInterval = 0;    /* To hold the bandwidth calculated */    UINT32 uCalculatedBandwidth = 0;    /* To hold the least occupied bandwidth */    UINT32 uLeastBandwidth = 0;    /* To hold the index of the frame which has the least occupied bandwidth */    UINT32 uLeastBwIndex = 0;    OS_LOG_MESSAGE_LOW(EHCD,"usbEhcdCheckBandwidth - Entry\n",0,0,0,0);    /* Check the validity of the parameters */    if ((NULL == pHCDData) ||        (0 == uBandwidth) ||        (NULL == pEndpointDesc) ||        (USBHST_HIGH_SPEED != uSpeed &&         USBHST_FULL_SPEED != uSpeed &&         USBHST_LOW_SPEED != uSpeed) ||        (NULL == puStepValue) ||        (NULL == puListIndex) ||        (NULL == puMicroFrameMask))        {        OS_LOG_MESSAGE_HIGH(EHCD,"usbEhcdCheckBandwidth - Invalid parameter\n",0,0,0,0);        return FALSE;        }    /* Return error if the type is not a periodic endpoint type */    if ((USBHST_ISOCHRONOUS_TRANSFER !=         (pEndpointDesc->bmAttributes & USB_EHCD_ENDPOINT_TYPE_MASK)) &&        (USBHST_INTERRUPT_TRANSFER !=         (pEndpointDesc->bmAttributes & USB_EHCD_ENDPOINT_TYPE_MASK)))        {        OS_LOG_MESSAGE_HIGH(EHCD,"usbEhcdCheckBandwidth - Not a periodic endpoint\n",0,0,0,0);        return FALSE;        }    /* Exclusively access the bandwidth resource */    OS_WAIT_FOR_EVENT(pHCDData->BandwidthEventID,OS_WAIT_INFINITE);    if (USBHST_ISOCHRONOUS_TRANSFER ==        (pEndpointDesc->bmAttributes & USB_EHCD_ENDPOINT_TYPE_MASK))    {        UINT32 uMaxBandwidth = 0;   /* Starting from the leaf nodes, check whether    * supplied bandwidth can be accomodated here */    for (uCount = 0; USB_EHCD_MAX_FRAMELIST_SIZE > uCount; uCount++)        {        uCalculatedBandwidth = 0;        /* Calculate the bandwidth occupied in this frame */        USB_EHCD_CALCULATE_FRAME_BANDWIDTH(pHCDData,                                           uCount,                                           uCalculatedBandwidth);        /* Get the maximum bandwidth used in a frame */        if (uCalculatedBandwidth > uMaxBandwidth)            {            uMaxBandwidth = uCalculatedBandwidth;            }        }    /* End of for () */    /* If there is no bandwidth available, return an error */    if ((USB_EHCD_EIGHTY_PERCENT_BW * USB_EHCD_MAX_MICROFRAME_NUMBER) <        (uMaxBandwidth + uBandwidth))        {        OS_LOG_MESSAGE_HIGH(EHCD,"usbEhcdCheckBandwidth - Bandwidth not available\n",0,0,0,0);        /* Release the bandwidth exclusive access */        OS_RELEASE_EVENT(pHCDData->BandwidthEventID);        return FALSE;        }    }    /* Initialize the least bandwidth to be the maximum bandwidth applicable */    uLeastBandwidth = USB_EHCD_EIGHTY_PERCENT_BW * USB_EHCD_MAX_MICROFRAME_NUMBER;    /* Starting from the leaf nodes, check whether bandwidth is available */    for (uCount = 0; USB_EHCD_MAX_FRAMELIST_SIZE > uCount; uCount++)        {        /* initialize the calculated bandwidth to be 0 */        uCalculatedBandwidth = 0;        /* Calculate the bandwidth occupied in this frame */        USB_EHCD_CALCULATE_FRAME_BANDWIDTH(pHCDData,                                           uCount,                                           uCalculatedBandwidth);        /* If the bandwidth occupied is less than the previous least bandwidth,         * this becomes the least bandwidth reserved.         */        if (uCalculatedBandwidth < uLeastBandwidth)            {            uLeastBandwidth = uCalculatedBandwidth;            uLeastBwIndex = uCount;            }        }    /* End of for () */    /* If there is no bandwidth available, return an error */    if ((USB_EHCD_EIGHTY_PERCENT_BW * USB_EHCD_MAX_MICROFRAME_NUMBER) <        (uLeastBandwidth + uBandwidth))        {        OS_LOG_MESSAGE_HIGH(EHCD,"usbEhcdCheckBandwidth - Bandwidth not available\n",0,0,0,0);        /* Release the bandwidth exclusive access */        OS_RELEASE_EVENT(pHCDData->BandwidthEventID);        return FALSE;        }    /* Get the polling interval of the endpoint */    uPollInterval = pEndpointDesc->bInterval;    /* Check if it is a low or full speed device endpoint */    if (USBHST_HIGH_SPEED != uSpeed)        {        /* Check if it is an interrupt endpoint */        if (USBHST_INTERRUPT_TRANSFER ==            (pEndpointDesc->bmAttributes & USB_EHCD_ENDPOINT_TYPE_MASK))            {            /* Array holding the start and complete split masks */            UINT32 uSplitMask[USB_EHCD_MAX_INT_SPLIT_MASKS] =   {                USB_EHCD_SPLIT_MASK_1,                USB_EHCD_SPLIT_MASK_2,                USB_EHCD_SPLIT_MASK_3,                USB_EHCD_SPLIT_MASK_4            };            /* Identify the index of the leaf of the tree, which is to be used*/            *puListIndex =            pHCDData->FrameListData[uLeastBwIndex].uNextListIndex;            /* 32 is the maximum polling interval which is supported.             * So if the polling interval is greater than 32, the endpoint             * will be polled every 32 ms.             */            if (USB_EHCD_MAX_USB11_INTERRUPT_POLL_INTERVAL > uPollInterval)                {                /* To hold the number of times the list is to be traversed */                UINT8 uTraversalCount = 0;                /* Calculate the traversal count */                USB_EHCD_CALCULATE_TRAVERSAL_COUNT(uPollInterval,uTraversalCount);                /* Get the Tree Index */                while (0 < uTraversalCount)                    {                    *puListIndex =                    pHCDData->TreeListData[*puListIndex].uNextListIndex;                    /* Decrement the traversal count */                    uTraversalCount--;                    }/* End of while */                }/* End of if (EHCD_MAX_USB11_INTERRUPT_POLL_INTERVAL > ...*/            /* Initialize the least bandwidth occupied */            uLeastBandwidth = USB_EHCD_EIGHTY_PERCENT_BW *                              USB_EHCD_MAX_MICROFRAME_NUMBER;            /* Retrieve the mask value which best fits this bandwidth */            for (uCount = 0; USB_EHCD_MAX_INT_SPLIT_MASKS > uCount; uCount++)                {                /* Initialize the uCalculatedBandwidth = 0 */                uCalculatedBandwidth = 0;                /* Calculate the bandwidth with the node element added */                USB_EHCD_CALCULATE_BW_MICROFRAMES(pHCDData,                                                  uSplitMask[uCount],                                                  uLeastBwIndex,                                                  uCalculatedBandwidth);                /* If this mask has the least bandwidth occupied, use this */                if (uCalculatedBandwidth < uLeastBandwidth)                    {                    uLeastBandwidth = uCalculatedBandwidth;                    *puMicroFrameMask = uSplitMask[uCount];                    }                }            /* Check if the bandwidth cannot be accomodated */            if (USB_EHCD_EIGHTY_PERCENT_BW * USB_EHCD_MAX_MICROFRAME_NUMBER                < (uLeastBandwidth + uBandwidth))                {                OS_LOG_MESSAGE_HIGH(EHCD,"usbEhcdCheckBandwidth - No bandwidth \n",0,0,0,0);                /* Release the bandwidth exclusive access */                OS_RELEASE_EVENT(pHCDData->BandwidthEventID);                return FALSE;                }            /* Update the step value */            *puStepValue = 0;            }/* End of if (USBHST_INTERRUPT_TRANSFER... */        /* The following is for isochronous transfer type */        else            {            /* Array holding the split masks */            UINT32 uSplitMask[USB_EHCD_MAX_MICROFRAME_NUMBER];            /* Initialize the split mask as per direction */            if (0 == (pEndpointDesc->bEndpointAddress & USB_EHCD_DIR_IN))            {            /* Array holding the start split masks for OUT transaction */                        uSplitMask[0] = 0x01; /* 00000001 */            uSplitMask[1] = 0x02; /* 00000010 */            uSplitMask[2] = 0x04; /* 00000100 */            uSplitMask[3] = 0x08; /* 00001000 */            uSplitMask[4] = 0x10; /* 00010000 */            uSplitMask[5] = 0x20; /* 00100000 */            uSplitMask[6] = 0x40; /* 01000000 */            uSplitMask[7] = 0x80; /* 10000000 */                        }            else            {            /* Array holding the start and complete split masks for IN transaction*/            uSplitMask[0] = USB_EHCD_SPLIT_MASK_1;            uSplitMask[1] = USB_EHCD_SPLIT_MASK_2;            uSplitMask[2] = USB_EHCD_SPLIT_MASK_3;            uSplitMask[3] = USB_EHCD_SPLIT_MASK_4;            uSplitMask[4] = 0x00;            uSplitMask[5] = 0x00;            uSplitMask[6] = 0x00;            uSplitMask[7] = 0x00;                                }            /* Initialize the least bandwidth occupied */            uLeastBandwidth = USB_EHCD_EIGHTY_PERCENT_BW                             * USB_EHCD_MAX_MICROFRAME_NUMBER;            /* Retrieve the mask value which best fits this bandwidth */            for (uCount = 0;                 ((USB_EHCD_MAX_MICROFRAME_NUMBER > uCount) &&                  (0 != uSplitMask[uCount]));                uCount++)                {                /* Initialize the uCalculatedBandwidth = 0 */                uCalculatedBandwidth = 0;                /* Calculate the bandwidth with the node element added */                USB_EHCD_CALCULATE_BW_MICROFRAMES(pHCDData,                                                  uSplitMask[uCount],                                                  uLeastBwIndex,                                                  uCalculatedBandwidth);                /* If this mask has the least bandwidth occupied, use this */                if (uCalculatedBandwidth < uLeastBandwidth)                    {                

⌨️ 快捷键说明

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