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

📄 usbehcdtransfermanagement.c

📁 usb2 driver for vxwokrs
💻 C
📖 第 1 页 / 共 5 页
字号:
                    {                    uSMask <<= uShiftCount;                    break;                    }                else                    {                    uTempMask >>= 1;                    }                uShiftCount++;                }            /* Update the start split mask */            USB_EHCD_SET_BITFIELD(uBusIndex,                                  QH,                                  pQH->uEndPointCapabilities,                                  uSMask,                                  ENDPOINT_CAPABILITIES_UFRAME_S);            /* Update the complete split mask */            USB_EHCD_SET_BITFIELD(uBusIndex,                                  QH,                                  pQH->uEndPointCapabilities,                                  (uUFrameMask & ~uSMask),                                  ENDPOINT_CAPABILITIES_UFRAME_C);            }        }    /* Device is a high speed device */    else        {        /* If it is a control or bulk pipe, populate the maximum NAK rate */        if ((USBHST_CONTROL_TRANSFER == pHCDPipe->uEndpointType) ||            (USBHST_BULK_TRANSFER == pHCDPipe->uEndpointType))            {            USB_EHCD_SET_BITFIELD(uBusIndex,                                  QH,                                  pQH->uEndPointCharacteristics,                                  pEndpointDesc->bInterval,                                  ENDPOINT_CHARACTERISTICS_RL);            }        /*         * It is a high speed interrupt transfer, update the         * mult field(the maximum number of transactions in a microframe         */        else            {            /*             * If the endpoint descriptor's mult field is 0, the number of             * transactions in a microframe is 1. Because of this,             * 1 is added to the number of transactions field.             */            USB_EHCD_SET_BITFIELD(uBusIndex,                                  QH,                                 pQH->uEndPointCapabilities,                                 ((((pEndpointDesc->wMaxPacketSize) &                                  USB_EHCD_ENDPOINT_NUMBER_OF_TRANSACTIONS_MASK)                                  >> 11)+ 1),                                  ENDPOINT_CAPABILITIES_MULT  );            /* Update the mask value in the QH */            USB_EHCD_SET_BITFIELD(uBusIndex,                                 QH,                                 pQH->uEndPointCapabilities,                                 uUFrameMask,                                 ENDPOINT_CAPABILITIES_UFRAME_S  );            }/* End of else */        }/* End of else */    /* Populate the fields of the QH - End */    /* Exclusively access the list */    OS_WAIT_FOR_EVENT(pHCDData->RequestSynchEventID, OS_WAIT_INFINITE);    /* Link the Queue head in the list - start */    /* If it is the interrupt endpoint, link it to the periodic schedule */    if (USBHST_INTERRUPT_TRANSFER == pHCDPipe->uEndpointType)        {        USB_EHCD_ADD_TO_HC_INTERRUPT_SCHEDULE(pHCDData, uListIndex, pQH);        }    /*     * If it is a control or bulk endpoint,     * link it to the asynchronous schedule.     */    else        {        USB_EHCD_ADD_TO_HC_ASYNCH_SCHEDULE(pHCDData, pQH);        }    /* Release the exclusive list access */    OS_RELEASE_EVENT(pHCDData->RequestSynchEventID);    /* Link the Queue head in the list - End */    OS_LOG_MESSAGE_LOW(EHCD,"usbEhcdCreatePipe - Exit\n",0,0,0,0);    return USBHST_SUCCESS;    } /* End of function usbEhcdCreatePipe() *//***************************************************************************** usbEhcdDeletePipe - deletes a pipe created already.** This function is used to delete a pipe specific to an* endpoint.** RETURNS: *   USBHST_SUCCESS - Returned if the pipe was deleted successfully*   USBHST_INVALID_PARAMETER - Returned if the parameters are*                              not valid.* ERRNO:*   None.** \NOMANUAL*/USBHST_STATUS usbEhcdDeletePipe    (    UINT8   uBusIndex,   /* Index of the host controller     */    UINT32  uPipeHandle  /* Handle of the pipe to be deleted */    )    {    /* To hold the status of the request */    USBHST_STATUS Status = USBHST_FAILURE;    /* To hold the pointer to the EHCD maintained pipe data structure */    pUSB_EHCD_PIPE pHCDPipe = NULL;    /* Pointer to the HCD specific data structure */    pUSB_EHCD_DATA  pHCDData = NULL;        PUCHAR          pQHTemp = NULL;    /* Temporary queue head pointer */	/* WindView Instrumentation */	USB_HCD_LOG_EVENT(		USB_EHCI_WV_TRANSFER,		"usbEhcdDeletePipe() starts",		USB_EHCD_WV_FILTER);    OS_LOG_MESSAGE_LOW(EHCD,"usbEhcdDeletePipe - Entry\n",0,0,0,0);    /* Check the validity of the parameters */    if ((g_EHCDControllerCount <= uBusIndex) ||        (0 == uPipeHandle))        {        OS_LOG_MESSAGE_HIGH(EHCD,"usbEhcdDeletePipe - parameters are not valid\n",0,0,0,0);        return USBHST_INVALID_PARAMETER;        }    /* Extract the global data structure */    pHCDData = g_pEHCDData[uBusIndex];    /* Assert if the global pointer is not valid */    OS_ASSERT(NULL != pHCDData);    /* Extract the USB_EHCD_PIPE data structure */    pHCDPipe = (pUSB_EHCD_PIPE)uPipeHandle;    /* Check if the request is for the Root hub and route it */    if ((pHCDData->RHData.pInterruptPipe == pHCDPipe) ||        (pHCDData->RHData.pControlPipe == pHCDPipe))        {        Status = usbEhcdRHDeletePipe(pHCDData,                                     uPipeHandle);        return Status;        }    /* Check if the endpoint type is valid */    if ((USBHST_CONTROL_TRANSFER != pHCDPipe->uEndpointType) &&        (USBHST_BULK_TRANSFER != pHCDPipe->uEndpointType) &&        (USBHST_INTERRUPT_TRANSFER != pHCDPipe->uEndpointType) &&        (USBHST_ISOCHRONOUS_TRANSFER != pHCDPipe->uEndpointType))        {        OS_LOG_MESSAGE_HIGH(EHCD,"EHCD_CreatePipe - Invalid endpoint type\n",0,0,0,0);        return USBHST_INVALID_PARAMETER;        }    /* Exclusively access the list */    OS_WAIT_FOR_EVENT(pHCDData->RequestSynchEventID, OS_WAIT_INFINITE);    /* Mark the endpoint for deletion */    pHCDPipe->PipeDeletedFlag = TRUE;    /* Check if it is a non-periodic endpoint */    if ((USBHST_CONTROL_TRANSFER == pHCDPipe->uEndpointType) ||        (USBHST_BULK_TRANSFER == pHCDPipe->uEndpointType))        {        /* To hold the pointer to the EHCD maintained pipe data structure */        pUSB_EHCD_PIPE pHCDTempPipe = NULL;        /* Search the asychronous list and update the next pointers */        for (pHCDTempPipe = pHCDData->pDefaultPipe;            (pHCDPipe != pHCDTempPipe->pNext) &&            (pHCDData->pDefaultPipe != pHCDTempPipe->pNext);            pHCDTempPipe = pHCDTempPipe->pNext);        /* Deletion of the default pipe is not through this function. So         * the pHCDPipe can never be the same as pHCDData->pDefaultPipe         */        /* Update the HCD maintained link pointers */        pHCDTempPipe->pNext = pHCDPipe->pNext;        /* If this QH forms the tail, update the tail element */        if (pHCDData->pAsynchTailPipe == pHCDPipe)            {            pHCDData->pAsynchTailPipe = pHCDTempPipe;            }        /* Disable the asynchronous schedule */        USB_EHCD_CLR_BIT(pHCDData,                     USBCMD,                     ASYNCH_SCHEDULE_ENABLE);        /*         * If only the asynch schedule enable bit and status bit are         * cleared, the schedule can be termed to be disabled.         * Wait till both of the bits are cleared.         */        while ((USB_EHCD_GET_FIELD(pHCDData,                                  USBCMD,                                  ASYNCH_SCHEDULE_ENABLE) != 0) ||               (USB_EHCD_GET_FIELD(pHCDData,                                   USBSTS,                                   ASYCHRONOUS_SCHEDULE_STATUS) !=0))            OS_DELAY_MS(1);        /*         * Update the HC maintained next pointers. This has to be done after         * disabling the list. If the host controller is accessing the nextTD         * element and when the software also updates it, it will lead to errors.         * This is a problem only with asynchronous QHs         */        pQHTemp = (PUCHAR) pHCDPipe->pNext->pQH;        pQHTemp += USB_EHCD_QH_HEADER_SIZE;        USB_EHCD_SET_BITFIELD(uBusIndex,                              QH,                              pHCDTempPipe->pQH->uQueueHeadHorizontalLinkPointer,                              ((unsigned)                              USB_EHCD_CONVERT_TO_BUS_MEM(                                     uBusIndex,                                     pQHTemp) >> 5),                              HORIZONTAL_LINK_POINTER);       /*        * Fetch the address of the host controller accessable region        * by adding the offest USB_EHCD_QH_HEADER_SIZE to queue head        */        pQHTemp = (PUCHAR) pHCDPipe->pQH;        pQHTemp += USB_EHCD_QH_HEADER_SIZE;        /*         * If the host controller is accessing currently the removed QH,         * update the host controller's current accessible QH         */        if (USB_EHCD_GET_FIELD(pHCDData,                       ASYNCLISTADDR,                       LINK_PTR_LOW) ==            ((UINT32)USB_EHCD_CONVERT_TO_BUS_MEM(                                     uBusIndex,                                     pQHTemp) >>                       USB_EHCD_ASYNCHLISTADDR_LINK_PTR_LOW))            {           /*            * Fetch the address of the host controller accessable region            * by adding the offest USB_EHCD_QH_HEADER_SIZE to queue head            */            pQHTemp = (PUCHAR) pHCDPipe->pNext->pQH;            pQHTemp += USB_EHCD_QH_HEADER_SIZE;            USB_EHCD_SET_FIELD(pHCDData,                       ASYNCLISTADDR,                       LINK_PTR_LOW,                    ((UINT32)USB_EHCD_CONVERT_TO_BUS_MEM(                                        uBusIndex,                                        pQHTemp) >>    					USB_EHCD_ASYNCHLISTADDR_LINK_PTR_LOW));            }        /* Enable the asynchronous schedule */        USB_EHCD_SET_BIT(pHCDData,                     USBCMD,                     ASYNCH_SCHEDULE_ENABLE);        /* Create a synchronisation  event*/        if (NULL == (pHCDPipe->DeleteSynchEventID = OS_CREATE_EVENT(OS_EVENT_NON_SIGNALED)))            {            OS_ASSERT(FALSE);            }        /* Add to the reclamation list */        USB_EHCD_ADD_TO_ASYNCH_RECLAMATION_LIST(pHCDData,                                                pHCDPipe);        /*         * If only the asynch schedule enable bit and status bit are         * set, the schedule can be termed to be enabled.         * Wait till both of the bits are set. Unless otherwise the schedule         * is enabled, the async advance doorbell bit cannot be set in USBCMD         * register.         */        while ((USB_EHCD_GET_FIELD(pHCDData,                                  USBCMD,                                  ASYNCH_SCHEDULE_ENABLE) == 0) ||               (USB_EHCD_GET_FIELD(pHCDData,                                   USBSTS,                                   ASYCHRONOUS_SCHEDULE_STATUS) ==0))               OS_DELAY_MS(1);#ifndef USB_EHCD_ENABLE_POLLING        /* Enable the aynch advance interrupt */        USB_EHCD_SET_BIT_USBINTR_INT_ON_ASYNC_ADVANCE_DOORBELL(pHCDData);#endif        /*         * Enable an interrupt to be generated         * when the Asynchronous list is advanced.         */        USB_EHCD_SET_BIT_USBCMD_INT_ON_ASYNC_ADVANCE_DOORBELL(pHCDData);        /*         * The USBCMD to set asynch advance can be done only when the         * schedule is enabled. The lock is released after the USBCMD is         * written to prevent any other thread from disabling the schedule.         */        OS_RELEASE_EVENT(pHCDData->RequestSynchEventID);        /* Wait for event handler task to free the resources */        OS_WAIT_FOR_EVENT(pHCDPipe->DeleteSynchEventID, OS_WAIT_INFINITE);        /* Delete the event created */        OS_DESTROY_EVENT(pHCDPipe->DeleteSynchEventID);        /* Free the PIPE */        OS_FREE(pHCDPipe);        }    /* It is a periodic endpoint, */    else

⌨️ 快捷键说明

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