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

📄 usbuhcdscheduleqsupport.c

📁 usb2 driver for vxwokrs
💻 C
📖 第 1 页 / 共 5 页
字号:
INT32 usbUhcdMaxIsoBwLinkedTo    (    INT32      index,    USB_UHCD_PERIODIC_TABLE * usbUhcdTable    )    {    /* Retrun the bandwith of the indexed usbUhcdTable */    return(usbUhcdTable[index].bandWidth);    }/* End of usbUhcdMaxIsoBwLinkedTo() *//***************************************************************************** usbUhcdFindPosForIntQh - locates point for queueing the interrupt QH** This function is used to locate a suitable point for queueing the * interrupt QH based on the bandwidth required and the poll rate** RETURNS: FALSE if bandwidth cannot be accomodated for the interrupt pipe.** ERRNO:*   None.** \NOMANUAL*/BOOLEAN usbUhcdFindPosForIntQh    (    INT32 bwReqd,    UINT reqPollRate,    INT32 *listIndex,    USB_UHCD_PERIODIC_TABLE * usbUhcdTable,    USB_UHCD_PERIODIC_TREE  * usbUhcdTree    )    {    /* To hold the least periodic bandwidth */    INT32 leastPeriodicBw = 0;    /* Temporary variable to hold the bandwidth required */    INT32 bw = 0;    /* To hold the index into the leaf of the periodic tree */    UINT i = 0;    /* To hold the current polling rate */    UINT currPollRate = 0;    /* Determine the Bandwidth taken up by the upper most branch of the tree */    leastPeriodicBw = usbUhcdFindTreeBw (127,usbUhcdTree)                         + usbUhcdMaxIsoBwLinkedTo (127,usbUhcdTable);    /* Start from the first node in the leaf */    *listIndex = 127;    OS_LOG_MESSAGE_MEDIUM(UHCD,"Entering usbUhcdFindPosForIntQh()\n",0,0,0,0);    /* Determine the least bandwidth occupying branch of the tree */    for (i = 128; i < 255; i++)        {        /* Determine BW of Branch "i" */        bw  = usbUhcdFindTreeBw (i, usbUhcdTree)                 + usbUhcdMaxIsoBwLinkedTo (i,usbUhcdTable);        /*         * If bandwidth occupied in this list is the least,         * update the variable holding the least periodic bandwidth         * Also update the list index.         */        if (bw < leastPeriodicBw)            {            OS_LOG_MESSAGE_MEDIUM(UHCD,"BW occupied is list\n",0,0,0,0);            leastPeriodicBw = bw;            *listIndex = i;            }        /* If the lowest possible BW is hit, break out of this loop */        if (leastPeriodicBw == 0)            {            OS_LOG_MESSAGE_MEDIUM(UHCD,"reached the lowest BW\n",0,0,0,0);            break;            }        }/* End of for() */    /*     * If the least periodic BW plus required bandwidth excceeds max available,     * QH cannot be accomodated     */    if (leastPeriodicBw + bwReqd + USB_UHCD_SAFETY_MARGIN >=         USB_UHCD_NINETY_PERCENT_BW)        {        OS_LOG_MESSAGE_MEDIUM(UHCD,"BW > max Available\n",0,0,0,0);        return(FALSE);        }    /*     * In the current list,     * determine the node that has the required poll rate     */    for (currPollRate = 128; currPollRate > reqPollRate;        currPollRate /= 2)        {        *listIndex = usbUhcdFindLinkForQh  (*listIndex);        }    /*     * If the QH's position is other than at the leaf of the tree,     * determine whether any path of the tree violates the maximim BW rule     */    if (*listIndex < 127)        {        OS_LOG_MESSAGE_MEDIUM(UHCD,"Check for QH violating\n",0,0,0,0);        for (i = 127; i < 255; i++)            {            /*             * If the current branch is linked to the newly found position,             * check if BW exceeds what is available.             *             * Return FALSE if the following conditions are not successful             * - Check whether the index specified by list_index pointer             *   is present in the node containing this leaf index 'i'.             * - The bandwidth reserved already in addition to the bandwidth             *   requested for has exceeded the 90% of the allocation             *   meant for the periodic transfers.             */            if (usbUhcdIsLinked(i, *listIndex) &&                (usbUhcdFindTreeBw ( i,usbUhcdTree) +                  usbUhcdMaxIsoBwLinkedTo (i, usbUhcdTable) +                 bwReqd + USB_UHCD_SAFETY_MARGIN) >= USB_UHCD_NINETY_PERCENT_BW)                {                OS_LOG_MESSAGE_MEDIUM(UHCD,"BW exceeds available\n",0,0,0,0);                return FALSE;                }            }/* End of for() */        }/* End of if() */    OS_LOG_MESSAGE_MEDIUM(UHCD,"Exiting usbUhcdFindPosForIntQh()\n",0,0,0,0);    return(TRUE);    }/* End of usbUhcdFindPosForIntQh() *//***************************************************************************** usbUhcdIsLinked - determines if node is linked** This function is used to determine whether 2 nodes of the tree is* the part of the same list or not** RETURNS: FALSE if the nodes are not linked.** ERRNO:*   None.** \NOMANUAL*/BOOLEAN usbUhcdIsLinked    (    INT32 listIndexOuter,    INT32 listIndexInner    )    {    /* To hold the index value */    INT32 index = 0;    OS_LOG_MESSAGE_MEDIUM(UHCD,"Entering usbUhcdIsLinked\n",0,0,0,0);    /*     * From the outer node, traverse the branch till we reach the inner node     * or the tip of the tree is reached     */    for (index = listIndexOuter;        index != listIndexInner && index >= 0;        index = usbUhcdFindLinkForQh  (index));    /* if the inner node is hit, return TRUE */    if (index == listIndexInner)        {        OS_LOG_MESSAGE_MEDIUM(UHCD,"Inner node hit\n",0,0,0,0);        return(TRUE);        }    OS_LOG_MESSAGE_MEDIUM(UHCD,"Exiting usbUhcdIsLinked()\n",0,0,0,0);    /* Not hit, return FALSE */    USB_UHCD_LOG_ERROR_MESSAGE("Node is not Linked\n");    return(FALSE);    }/* End of usbUhcdIsLinked() *//***************************************************************************** usbUhcdMakeTds - create the TDs needed for a transfer** This routine creates the TDs needed for a transfer.** RETURNS: FALSE if TDs are not created successfully.** ERRNO:*   None.* * \NOMANUAL*/BOOLEAN usbUhcdMakeTds    (    UINT32      uBusIndex,    USB_UHCD_TD **head,    USB_UHCD_TD **tail,    USBHST_URB *urb,    UINT8 *toggle ,    USB_UHCD_HCD_PIPE *targetPipe    )    {    /* To hold the pointer to the current TD */    USB_UHCD_TD *currentTd = NULL;    /* To hold the pointer to the temporary TD */    USB_UHCD_TD *temp = NULL;    /* To hold the number of bytes to be transferred */    UINT bytesTransfered=0;    /* Extract the setup packet information */    pUSBHST_SETUP_PACKET pSetupPacket =    (pUSBHST_SETUP_PACKET)urb->pTransferSpecificData;    /* Call the function to create the 1st TD needed for the transfer */    currentTd = *head = usbUhcdFormEmptyTd ((UINT32)targetPipe);    OS_LOG_MESSAGE_MEDIUM(UHCD,"Entering usbUhcdMakeTds()\n",0,0,0,0);    /* If unable to create the TD, return FALSE */    if (currentTd == NULL)        {        OS_LOG_MESSAGE_MEDIUM(UHCD,"Unable to create TD\n",0,0,0,0);        return FALSE;        }    /*     * This loop will create that many TDs based on the number of     * bytes to be transmitted     */    while (bytesTransfered < urb->uTransferLength)        {        /* Short packet detection is valid only for non Isochronous pipe */        currentTd->dWord1Td |= USBUHCD_TDCS_SHORT;                /* Set the buffer pointer of the TD */        currentTd->dWord3Td = USB_UHCD_CONVERT_TO_BUS_MEM (uBusIndex, (urb->pTransferBuffer                                        + bytesTransfered));        /* Set the Maxlength Field of the TD */        /* Check if the bytes to transfer is less than maximum packet size */        if ((urb->uTransferLength - bytesTransfered) <            targetPipe->uMaximumPacketSize)            {            OS_LOG_MESSAGE_MEDIUM(UHCD,"Byte transfer < max \n",0,0,0,0);            /* Check if it is a non 0 byte data transfer to be done */            if (urb->uTransferLength-bytesTransfered)                {                OS_LOG_MESSAGE_MEDIUM(UHCD,"Non zero byte transfer\n",0,0,0,0);                /* Update the maximum length of data in the TD */                currentTd->dWord2Td &= ~(USBUHCD_TDTOK_MAXLEN_MASK);                currentTd->dWord2Td |= USBUHCD_TDTOK_MAXLEN_FMT(                                          urb->uTransferLength-bytesTransfered -                                          1 );                }            /* A zero byte data transfer */            else                {                OS_LOG_MESSAGE_MEDIUM(UHCD,"Zero byte transfer\n",0,0,0,0);                currentTd->dWord2Td &= ~(USBUHCD_TDTOK_MAXLEN_MASK);                currentTd->dWord2Td |= USBUHCD_TDTOK_MAXLEN_FMT(0x7FF);                }            /* Keep track of the number of bytes transfered */            bytesTransfered += ( urb->uTransferLength-bytesTransfered );            }        /* If the bytes to transfer is more than maximum packet size */        else            {            OS_LOG_MESSAGE_MEDIUM(UHCD,"byte transfer > max\n",0,0,0,0);            bytesTransfered += targetPipe->uMaximumPacketSize;            }        /* Set the toggle bit of the TD for non isochronous TD */        if (targetPipe->endPointType != PIPE_ISOCHRONOUS)            {            OS_LOG_MESSAGE_MEDIUM(UHCD,"Pipe is not Isochronous -- set toggle bit\n",0,0,0,0);            if (*toggle)                {                currentTd->toggle = 1;                currentTd->dWord2Td |= USBUHCD_TDTOK_DATA_TOGGLE;                }            else                {                currentTd->toggle = 0;                currentTd->dWord2Td &= ~(USBUHCD_TDTOK_DATA_TOGGLE);                }            *toggle = (*toggle == 0) ? 1 : 0;            }        /* For isochronous, set toggle to 0, since toggle is not used */        /* Update PID field of the TD */        if (targetPipe->endPointType != PIPE_CONTROL)             {            currentTd->dWord2Td &= ~(USBUHCD_TDTOK_PID_MASK);            if ( targetPipe ->endPointDirection == 1)                currentTd->dWord2Td |= USBUHCD_TDTOK_PID_FMT(0x69);            else                currentTd->dWord2Td |= USBUHCD_TDTOK_PID_FMT(0xE1);            }        else            {            currentTd->dWord2Td &=~(USBUHCD_TDTOK_PID_MASK);            if (0 != (pSetupPacket->bmRequestType & 0x80))                currentTd->dWord2Td |= USBUHCD_TDTOK_PID_FMT(0x69);            else                currentTd->dWord2Td |= USBUHCD_TDTOK_PID_FMT(0xE1);            }        /* Check if more bytes need to be transfered */        if (bytesTransfered < urb->uTransferLength)            {            OS_LOG_MESSAGE_MEDIUM(UHCD,"More bytes to be transfered\n",0,0,0,0);            /* Non-isochronous transfer */            if (targetPipe->endPointType != PIPE_ISOCHRONOUS)                {                OS_LOG_MESSAGE_MEDIUM(UHCD,"Pipe ! Isochronous\n",0,0,0,0);                /* Form a new TD */                currentTd->hNextTd = usbUhcdFormEmptyTd ((UINT32)targetPipe);                /* If unable to allocate memory for the TD */                if (currentTd->hNextTd == NULL)                    {                    OS_LOG_MESSAGE_MEDIUM(UHCD,"Unable to allocate memoery \n",0,0,0,0);                    /* Clean up memory allocated for the TD till now */                    for (currentTd = *head; currentTd != NULL;)                        {                        temp = currentTd->hNextTd;                        UHCI_FREE((UCHAR*)currentTd - currentTd->offsetForFreeing);                        currentTd = temp;                        }                    /* Return FALSE */                    return FALSE;                    }                /* Update the HC TD's link pointer */                currentTd->dWord0Td &=~(USBUHCD_LINK_PTR_MASK);                currentTd->dWord0Td |= USBUHCD_LINK_PTR_FMT(                                       ((unsigned) currentTd->hNextTd) >> 4);                /* Indicate that this is not the last element in the queue */                                               currentTd->dWord0Td &= ~(USBUHCD_LINK_TERMINATE);                currentTd->dWord0Td =  USB_UHCD_CONVERT_TO_BUS_MEM( uBusIndex, (PVOID)currentTd->dWord0Td);                /* Store the previous element of the next TD */                currentTd->hNextTd->hPrevTd = currentTd;                /* Update the current pointer */                currentTd = currentTd->hNextTd;                /* Make the next pointer as NULL */                currentTd->hNextTd = NULL;                }/* End of if() */            }/* End of if(bytesTransfered < urb->uTransferBufferLen) */        }/* End of while () */    /* Update the tail pointer so as to make it point to the last TD */    *tail = currentTd;    OS_LOG_MESSAGE_MEDIUM(UHCD,"Exiting usbUhcdMakeTds()\n",0,0,0,0);    /* Return TRUE */    return(TRUE);    }/* End of usbUhcdMakeTds() *//***************************************************************************** usbUhcdMakeIsocTds - create the TDs needed for a transfer** This routine creates the TDs needed for a transfer.** RETURNS: FALSE if TDs are not created successfully.** ERRNO:*   None.** \NOMANUAL*/BOOLEAN usbUhcdMakeIsocTds    (    UINT32      uBusIndex,    USB_UHCD_TD **head,    USB_UHCD_TD **tail,    USBHST_URB *purb,    UINT8 *toggle ,    USB_UHCD_HCD_PIPE *targetPipe    )    {    /* To hold the pointer to the current TD */    USB_UHCD_TD *currentTd = NULL;    /* To hold the pointer to the temporary TD */    USB_UHCD_TD *temp = NULL;    UINT32 numberOfTDs = purb->uNumberOfPackets;    /* Pointer to the isoc packets */

⌨️ 快捷键说明

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