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

📄 usbuhcdschedulequeue.c

📁 usb2 driver for vxwokrs
💻 C
📖 第 1 页 / 共 5 页
字号:
                USB_UHCD_SWAP_BUFDATA( uBusIndex,                 pUrb->pTransferBuffer,                 pUrb->uTransferLength);            /* Call the function to create the TDs required for the transfer */            if (usbUhcdMakeTds ( uBusIndex,                                 &nIreqQ->head,                                &nIreqQ->tail,                                pUrb,                                &(nIreqQ->qh->toggle),targetPipe) == FALSE)                {                OS_LOG_MESSAGE_MEDIUM(UHCD,"Make TD failed\n",0,0,0,0);                return(USBHST_FAILURE);                }            /*             * Generate an interrupt on completion             * of transfer indicated by the tail element of the request             */            nIreqQ->tail->dWord1Td |=USBUHCD_TDCS_COMPLETE;            }        /* Check if it is an interrupt transfer request */        else if (targetPipe->endPointType == PIPE_INTERRUPT)            {            OS_LOG_MESSAGE_MEDIUM(UHCD,"Pipe type Interrupt\n",0,0,0,0);            /* Call the function to create the TDs required for the transfer */            USER_FLUSH(pUrb->pTransferBuffer, pUrb->uTransferLength);            /* Swap the buffer data */            if ( pUrb->pTransferBuffer != NULL)                USB_UHCD_SWAP_BUFDATA( uBusIndex,                 pUrb->pTransferBuffer,                 pUrb->uTransferLength);            if (usbUhcdMakeTds ( uBusIndex,                                  &nIreqQ->head,                                &nIreqQ->tail,                                pUrb,                                &(nIreqQ->qh->toggle),targetPipe) == FALSE)                {                OS_LOG_MESSAGE_MEDIUM(UHCD,"Make TD failed\n",0,0,0,0);                return(USBHST_FAILURE);                }            /* Interrupt on completion of tail */            nIreqQ->tail->dWord1Td |=USBUHCD_TDCS_COMPLETE;            }        /*         * Taking the semaphore for exclusive access of the critical         * section data         */        for (temptd = nIreqQ->head; temptd !=nIreqQ->tail->hNextTd;              temptd = temptd->hNextTd)           {           usbUhcdMakeTDLE(uBusIndex, temptd);           DMA_FLUSH(temptd, sizeof(USB_UHCD_TD));           }         if(pUrb->pTransferBuffer)            USER_INVALIDATE(pUrb->pTransferBuffer, pUrb->uTransferLength);        /* Enter the critical section */        usbUhcdEnterCritical(pHCDData);        /* Link the creq\ated Request Block to the Non Isochronous Request Queue */        if (pHCDData->usbUhcdNonIsoRequestQ == NULL)            {            pHCDData->usbUhcdNonIsoRequestQ = nIreqQ;            }        else            {            nIreqQ->next = pHCDData->usbUhcdNonIsoRequestQ;            pHCDData->usbUhcdNonIsoRequestQ = nIreqQ;            }        /* Link the list of TDs to the qHead - Start */        /* There is no TD linked to the QH */        if (targetPipe->qh->td == NULL)            {            OS_LOG_MESSAGE_MEDIUM(UHCD,"No TD linked to QH\n",0,0,0,0);            targetPipe->qh->td = nIreqQ->head;            targetPipe->qh->tdLast = nIreqQ->tail;            dword0 = 0;            dword0  &= ~(USBUHCD_LINK_PTR_MASK);            dword0   |= ( USBUHCD_LINK_PTR_FMT(                                        ((unsigned) nIreqQ->head) >> 4));            dword0 &=  ~(USBUHCD_LINK_TERMINATE);            dword0 = USB_UHCD_CONVERT_TO_BUS_MEM( uBusIndex, (PVOID)dword0);            dword0 = USB_UHCD_SWAP_DATA( uBusIndex, dword0);            targetPipe->qh->dWord1Qh = dword0;                        DMA_FLUSH(targetPipe->qh, sizeof(USB_UHCD_QH));             }        /* There are TDs already linked to the QH */        else            {            dword0 = 0;            OS_LOG_MESSAGE_MEDIUM(UHCD,"TD are linked to QH\n",0,0,0,0);            td = targetPipe->qh->tdLast;            targetPipe->qh->tdLast = nIreqQ->tail;            /*             * Update the last element's next pointer to point to             * the head of the request created newly             */            td->hNextTd = nIreqQ->head;            /*             * Update the previous element of the head of the request to the             * last element which was already present in the queue             */            nIreqQ->head->hPrevTd = td;            /* Update the HC TD's link pointer */            dword0 &= ~(USBUHCD_LINK_PTR_MASK);            dword0 |= USBUHCD_LINK_PTR_FMT(                                       ((unsigned) nIreqQ->head) >> 4);            dword0 &= ~(USBUHCD_LINK_TERMINATE);            dword0 = USB_UHCD_CONVERT_TO_BUS_MEM( uBusIndex, (PVOID)dword0);            dword0 = USB_UHCD_SWAP_DATA( uBusIndex, dword0);            td->dWord0Td = dword0;            DMA_FLUSH(td, sizeof(USB_UHCD_TD));                        /*             * The status field indicating a 0 on bit 7 indicates that             * the request has been serviced by the Host controller             */            /* check if the request has been serviced */            if ((USB_UHCD_SWAP_DATA(uBusIndex, td->dWord1Td) & USBUHCD_TDCS_STS_ACTIVE) == 0)                {                OS_LOG_MESSAGE_MEDIUM(UHCD,"Request has been serviced\n",0,0,0,0);                /* Update the link pointer to point to the newly added element*/                targetPipe->qh->dWord1Qh = td->dWord0Td;                DMA_FLUSH(targetPipe->qh, sizeof(USB_UHCD_QH));                                }            }/* End of else */        /* Link the list of TDs to the qHead - End */        /*         * Release the semaphore as the critical section is over.         */        usbUhcdLeaveCritical(pHCDData);        }/* End of if(purb->pPipe->uPipeType != PIPE_ISOCHRONOUS) */    /* Isochronous transfer request */    else        {        /* If Isochronous the pUrb->pTransferSpecificData contains         * the Isoc packets         */        OS_LOG_MESSAGE_MEDIUM(UHCD,"Isochronous transfer\n",0,0,0,0);        if(pUrb->pTransferBuffer)            USER_FLUSH(pUrb->pTransferBuffer, pUrb->uTransferLength);        /* Swap the buffer data */        if ( pUrb->pTransferBuffer != NULL)            USB_UHCD_SWAP_BUFDATA( uBusIndex,                 pUrb->pTransferBuffer,                 pUrb->uTransferLength);        /* Allocate memory for the isochronous request block */        iReqQ = (USB_UHCD_ISO_REQUEST_QUEUE*) \                OS_MALLOC(sizeof (USB_UHCD_ISO_REQUEST_QUEUE));        /* Check if memory allocation is successful */        if (NULL == iReqQ)            {            OS_LOG_MESSAGE_MEDIUM(UHCD,"Memory allocation Unsuccessful\n",0,0,0,0);            return USBHST_FAILURE;            }        /* Fill the request block with 0s */        OS_MEMSET(iReqQ, 0, sizeof(USB_UHCD_ISO_REQUEST_QUEUE));        iReqQ->next = NULL;        /* For Isoc the pUrb->uNumberOfPackets field contains the number          * of Isoc Tds to be made         */        maxNumOfItd = pUrb->uNumberOfPackets;        /*         * Only a maximum of 1024          * isochronous TDs can be accomocated in the list         */        if (USB_UHCD_PERIODIC_LIST_WINDOW_SIZE < maxNumOfItd)            {            OS_LOG_MESSAGE_MEDIUM(UHCD,"Window size exceeded \n",0,0,0,0);            OS_FREE(iReqQ);            return(USBHST_FAILURE);            }        /* Enter the critical section */        usbUhcdEnterCritical(pHCDData);        /*         * Get the current HC's frame number         * Use it for queueing         */        usbUhcdGetFrameNumber(uBusIndex, &frameNum);        frameNum = frameNum  & 0x3FF;        /* Check if the request is to be serviced AS_SOON_AS_POSSIBLE */        if (USBHST_START_ISOCHRONOUS_TRANSFER_ASAP ==             (pUrb->uTransferFlags & USBHST_START_ISOCHRONOUS_TRANSFER_ASAP))            {#if 0            OS_LOG_MESSAGE_MEDIUM(UHCD,"If request is ASAP\n",0,0,0,0);            if (targetPipe->lastIndexAllocated >frameNum)                {   /* Check for the end conditions */                    /* Update the start Index to the next lastIndexAllocated */                startIndex = targetPipe->lastIndexAllocated + 1;                }            else if (targetPipe->lastIndexAllocated == frameNum)                {                /* Update the start Index to the next frameNumber */                startIndex = frameNum + USB_UHCD_PERIODIC_LIST_MODIFICATION_MARGIN;                }            /* Check if there is a rollover */            else if ((targetPipe->uLastStartIndex > targetPipe->lastIndexAllocated) &&                     (frameNum > targetPipe->lastIndexAllocated))                {		startIndex = targetPipe->lastIndexAllocated + 1;                }            	    else                {                /* Update the start Index to the next frameNumber */                startIndex = frameNum + USB_UHCD_PERIODIC_LIST_MODIFICATION_MARGIN;                }#else            BOOLEAN rollover= FALSE;                        if (targetPipe->uLastStartIndex > targetPipe->lastIndexAllocated)                rollover = TRUE;                        if ( !rollover )                {                  if ((targetPipe->uLastStartIndex == 0) && (targetPipe->lastIndexAllocated ==0) )                   startIndex = frameNum + USB_UHCD_PERIODIC_LIST_MODIFICATION_MARGIN;                  else if ((frameNum >= targetPipe->uLastStartIndex) &&                            (frameNum <=targetPipe->lastIndexAllocated))                       startIndex = targetPipe->lastIndexAllocated + 1;                  else                      startIndex = frameNum + USB_UHCD_PERIODIC_LIST_MODIFICATION_MARGIN;                }            else                {                  if (((frameNum >=targetPipe->uLastStartIndex) && (frameNum <= 1023)) ||                        ( (frameNum <= targetPipe->lastIndexAllocated) ))                       startIndex = targetPipe->lastIndexAllocated + 1;                  else                      startIndex = frameNum + USB_UHCD_PERIODIC_LIST_MODIFICATION_MARGIN;                           }                          #endif                /* To handle roll over */                if (startIndex > 1023)                    {                    startIndex -= 1024;                    }            } /* End of if(purb->uTransferFlags == AS_SOON_AS_POSSIBLE) */        /* The request is to be serviced in the specific frame number */        else            {            OS_LOG_MESSAGE_MEDIUM(UHCD,"Request is in specific frame no\n",0,0,0,0);            /* Update the start Index to the startindex provided by the urb */            startIndex = pUrb->uStartFrame;            if (startIndex > 1023)                {                OS_LOG_MESSAGE_MEDIUM(UHCD," Urb Start Frame greater that 1023",0,0,0,0);                OS_FREE(iReqQ);                usbUhcdLeaveCritical(pHCDData);                return(USBHST_BAD_START_OF_FRAME);                }            }        /*          * Check whether the transfer can be supported based on the available         * isochronous frame window.         *         * NOTE: The following algorithm is used for validating whether the         *       transfer can be supported within the isochronous frame window.         *         *       a) Starting frame number of the new transfer should be greater         *          than ending frame number for the last queued transfer.         *         *       b) If condition (a) is FALSE, the following condition should be         *          met.         *         *          Starting frame number of the new transfer is less than the          *          ending frame number of the last queued transfer.         *         *                                      (AND)         *                   *          Starting frame number of the new transfer is less than the         *          current SOF (hardware frame number).         *         *       c) If conditions (a) and (b) are not met, the transfer cannot         *          be supported.         *         *       d) Ending frame number of the transfer is greater than the         *          the current SOF         *         *                                      (OR)         *         *          Ending frame number of the transfer is less than the current         *          SOF         *         *       e) If condition ((a) AND (d)) or ((b) AND (d2)) are met the transfer         *          can be supported. If not, the transfer cannot be supported.         */        /*         * Get the current HC's frame number         * Use it for queueing         */        /*usbUhcdGetFrameNumber(uBusIndex, &frameNum);        frameNum = frameNum  & 0x3FF;*/        /* Current frame starts after the last allocated index */        currentReqStartFrame = startIndex;        /* Add the number of tds to the currentReqStartFrame to get the End frame */        currentReqEndFrame = currentReqStartFrame + maxNumOfItd;        /* To handle rounding off */        if (currentReqEndFrame > 1023)            {            OS_LOG_MESSAGE_MEDIUM(UHCD,"currentReqEndFrame > 1023\n",0,0,0,0);            currentReqEndFrame  -= 1024;            }#if 0        /* Check for the bad SOF */        if (!(((currentReqStartFrame > targetPipe->lastIndexAllocated ) &&             ((currentReqEndFrame > frameNum)||(currentReqEndFrame < frameNum))) ||            ((currentReqStartFrame < frameNum ) && (currentReqEndFrame < frameNum)))            )            {            OS_LOG_MESSAGE_HIGH(UHCD," Bad start of frame condition ",0,0,0,0);            OS_FREE(iReqQ);            usbUhcdLeaveCritical(pHCDData);            return(USBHST_BAD_START_OF_FRAME);            }#endif              targetPipe->uLastStartIndex = currentReqStartFrame;         /* Copy the URB pointer into the isochronous queue element */        iReqQ->pUrb = pUrb;                /* Update the starting index of the transfer */        iReqQ->startIndex = startIndex;        /* store the pipe */        iReqQ->pipe = targetPipe;        /* Update the bandwidth required */        iReqQ->bw = bwReqd;        /* The toggle bit is always 0 for isochronous */        toggle = 0;        /* Call the function to create the TDs needed for the transfer */        if (usbUhcdMakeIsocTds( uBusIndex, &iReqQ->head, &iReqQ->tail, pUrb, &toggle,                               targetPipe) == FALSE)            {            OS_LOG_MESSAGE_MEDIUM(UHCD,"Make TD failed\n",0,0,0,0);            /* Free the isoc request */          

⌨️ 快捷键说明

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