📄 usbehcdinitexit.c
字号:
/* Update the type of the data structure to be a QH */ USB_EHCD_SET_BITFIELD(uBusIndex, QH, pQH->uQueueHeadHorizontalLinkPointer, USB_EHCD_TYPE_QH, HORIZONTAL_LINK_POINTER_TYPE ); /* Flush the cache contents to the RAM */ CACHE_DMA_FLUSH(pQH, sizeof(USB_EHCD_QH)); } /* Return TRUE */ return TRUE; } /* End of usbEhcdCreateInterruptTree() */#ifdef USB_EHCD_ENABLE_POLLINGvoid usbEhcdPollingISR(pUSB_EHCD_DATA pHCDData) { while(1) { /* Call the ISR function */ usbEhcdISR(pHCDData); taskDelay(10); } }#endif/***************************************************************************** usbEhcdHostBusInitialize - performs the host bus specific initialization.** This function performs the host bus specific initialization of the* EHCI Host Controller.** RETURNS:* USB_EHCD_HC_NOT_PRESENT if the host controller is not present.* USB_EHCD_HCBUS_NOT_INITIALIZED if the host bus specific initialisation* is unsuccessful.* USB_EHCD_HCBUS_NOT_INITIALIZED if the host bus specific initialisation* is unsuccessful.** ERRNO:* None.** \NOMANUAL*/USB_EHCD_BUS_STATUS usbEhcdHostBusInitialize ( pUSB_EHCD_DATA *ppHCDData, UINT32 uIndex ) { /* To hold the status of the bus specific functions */ BUS_OPERATION_STATUS Status = BUS_OPERATION_FAILURE; /* To hold the IRQ number */ INT8 uIRQ = 0; /* To hold the command register contents */ UINT32 uTempCount = 0; /* Check the validity of the parameter */ if (NULL == ppHCDData || uIndex >= maxEhciCount) { OS_LOG_MESSAGE_HIGH(EHCD,"usbEhcdHostBusInitialize - parameters are \ not valid\n",0,0,0,0); return USB_EHCD_HCBUS_NOT_INITIALIZED; } /* Allocate memory for the EHCD_DATA structure */ *ppHCDData = (pUSB_EHCD_DATA)OS_MALLOC(sizeof(USB_EHCD_DATA)); /* Check if memory allocation is successful */ if (NULL == *ppHCDData) { OS_LOG_MESSAGE_HIGH(EHCD,"usbEhcdHostBusInitialize - memory not allocated\ for HCD_DATA structure\n",0,0,0,0); return USB_EHCD_HCBUS_NOT_INITIALIZED; } /* Initialize all the elements of the structure */ OS_MEMSET(*ppHCDData, 0, sizeof(USB_EHCD_DATA)); (*ppHCDData)->uIRQ = pEhciBusInfo[uIndex]->irq; (*ppHCDData)->pPCIBaseAddress =(UINT8 *) pEhciBusInfo[uIndex]->pBaseAddress; (*ppHCDData)->pEHCBaseAddress = ((*ppHCDData)->pPCIBaseAddress) + USB_EHCD_READ_CAPLENGTH(*ppHCDData); uIRQ = (*ppHCDData)->uIRQ; /* Clear the Run/Stop bit to stop the Host Controller */ USB_EHCD_CLR_BIT(*ppHCDData, USBCMD, RS); /* Reset the Host Controller */ USB_EHCD_SET_BIT(*ppHCDData, USBCMD, HCRESET); /* This loop waits for sometime for the reset to be complete */ for (uTempCount = 0; uTempCount < USB_EHCD_MAX_DELAY_INTERVAL; uTempCount++) { /* Check if the reset is successful */ if(0 == USB_EHCD_GET_FIELD(*ppHCDData, USBCMD, HCRESET)) { OS_LOG_MESSAGE_MEDIUM(EHCD,"Host Controller reset successful\n",0,0,0,0); break; } /* Wait for sometime */ OS_DELAY_MS(1); } /* End of for () */ /* * Check if the delay has expired * This means that the reset is not successful. */ if (USB_EHCD_MAX_DELAY_INTERVAL == uTempCount) { OS_LOG_MESSAGE_HIGH(EHCD,"usbEhcdHostBusInitialize - Error during HC reset\n",0,0,0,0); /* Release memory allocated for the HCD specific data */ OS_FREE(*ppHCDData); return USB_EHCD_HCBUS_NOT_INITIALIZED; }#ifndef USB_EHCD_ENABLE_POLLING /* Register the interrupt handler for the IRQ */ if (pEhciBusInfo[uIndex]->pFuncIntConnect != NULL) Status = pEhciBusInfo[uIndex]->pFuncIntConnect( usbEhcdISR, (INT32)*ppHCDData, uIRQ); else Status = BUS_OPERATION_FAILURE; /* Check if the interrupt is registered successfully */ if (BUS_OPERATION_SUCCESS != Status) { OS_LOG_MESSAGE_HIGH(EHCD,"usbEhcdHostBusInitialize - Error in regsitering the \ interrupt\n",0,0,0,0); /* Release memory allocated for the HCD specific data */ OS_FREE(*ppHCDData); return USB_EHCD_HCBUS_NOT_INITIALIZED; }#else /* Spawn the thread to handle the interrupts */ /* WARNING : No return value check is done */ OS_CREATE_THREAD("PollingISR", 37, usbEhcdPollingISR, (int)*ppHCDData);#endif /* End of USB_EHCD_ENABLE_POLLING */ /* Return the status that the host controller * bus is initialized successfully. */ return USB_EHCD_HCBUS_INITIALIZED; } /* End of function usbEhcdHostBusInitialize() *//***************************************************************************** usbEhcdDataInitialize - initializes EHCD_DATA structure.** This routine initializes the EHCD_DATA structure.** RETURNS: TURE, or FALSE if EHCD_DATA initialization is unsuccessful.** ERRNO:* None.** \NOMANUAL*/BOOLEAN usbEhcdDataInitialize ( pUSB_EHCD_DATA pHCDData ) { /* To hold the base of the frame list */ pUSB_EHCD_PERIODIC_FRAME_ELEMENT pFrameList = NULL; /* To hold the status of a function call */ BOOLEAN bIsSuccess = FALSE; /* To hold the index into the periodic frame list */ UINT32 uCount = 0; /* Temporary variable */ UINT32 uTempVariable = 0; /* To hold the name of the thread */ UCHAR ThreadName[10] = "EHCD_IH"; PUCHAR pQHTemp = NULL; UINT32 uBusIndex = 0; /* index of the host controller */ OS_LOG_MESSAGE_LOW(EHCD,"usbEhcdDataInitialize - Entry\n",0,0,0,0); /* Check the validity of the parameter */ if (NULL == pHCDData) { OS_LOG_MESSAGE_HIGH(EHCD,"usbEhcdDataInitialize - Parameter is not valid\n",0,0,0,0); return FALSE; } /* Extract the index of the host controller */ uBusIndex = pHCDData->uBusIndex; /* Allocate memory for the frame list */ pHCDData->pAllocatedFrameList = OS_MALLOC((sizeof(USB_EHCD_PERIODIC_FRAME_ELEMENT) * USB_EHCD_MAX_FRAMELIST_SIZE) + USB_EHCD_PAGE_SIZE ); /* Check if memory allocation is successful */ if (NULL == pHCDData->pAllocatedFrameList) { OS_LOG_MESSAGE_HIGH(EHCD,"usbEhcdDataInitialize - Memory not allocated for\ Frame list\n",0,0,0,0); return FALSE; } /* Align it to a page boundary */ pFrameList = (pUSB_EHCD_PERIODIC_FRAME_ELEMENT) usbEhcdAlign(pHCDData->pAllocatedFrameList, USB_EHCD_PAGE_SIZE); /* Initialize all the elements of the data structure */ OS_MEMSET(pFrameList, 0, (sizeof(USB_EHCD_PERIODIC_FRAME_ELEMENT)*USB_EHCD_MAX_FRAMELIST_SIZE)); /* Store the frame list in HCD data */ pHCDData->pFrameList = pFrameList; /* Create the static interrupt tree */ bIsSuccess = usbEhcdCreateInterruptTree(pHCDData); /* Check if the interrupt tree creation is successful */ if (TRUE != bIsSuccess) { /* Release the memory allocated for the frame list */ OS_FREE(pHCDData->pAllocatedFrameList); pHCDData->pAllocatedFrameList = NULL; return FALSE; } /* Establish the links between the frame list and the interrupt tree */ for (uCount = 0; USB_EHCD_MAX_FRAMELIST_SIZE > uCount ; uCount++) { /* * Store the index of the next element in the list * in a temporary variable. */ uTempVariable = (uCount % USB_EHCD_MAX_LEAF_NODES) + USB_EHCD_FIRST_LEAF_NODE_INDEX; /* Update the index of the next list */ pHCDData->FrameListData[uCount].uNextListIndex = uTempVariable; /* Update the link pointer */ USB_EHCD_SET_BITFIELD(uBusIndex, FRAME_LIST, (*(pFrameList + uCount)), ((unsigned)USB_EHCD_CONVERT_TO_BUS_MEM( uBusIndex, (pHCDData->TreeListData[uTempVariable].pHeadPointer)) >> 5),POINTER); /* Indicate that the link pointer points to a QH */ USB_EHCD_SET_BITFIELD(uBusIndex, FRAME_LIST, (*(pFrameList + uCount)), USB_EHCD_TYPE_QH,POINTER_TYPE) ; USB_EHCD_SET_BITFIELD(uBusIndex, FRAME_LIST, (*(pFrameList + uCount)), USB_EHCD_VALID_LINK,POINTER_VALID_ENTRY) ; /* * Update the head and tail pointers to NULL * These are initialized to NULL as there is no node * element which is created statically. These will be populated when * isochronous or split isochronous TDs are added. */ pHCDData->FrameListData[uCount].pHeadPointer = NULL; pHCDData->FrameListData[uCount].pTailPointer = NULL; /* Update the bandwidth occupied field */ for (uTempVariable = 0; USB_EHCD_MAX_MICROFRAME_NUMBER > uTempVariable; uTempVariable++) { pHCDData->FrameListData[uCount].uBandwidth[uTempVariable] = 0; } } /* End of for (uCount = 0;...) */ /* Flush the contents of the cache to the RAM */ CACHE_DMA_FLUSH(pFrameList, (sizeof(USB_EHCD_PERIODIC_FRAME_ELEMENT) * USB_EHCD_MAX_FRAMELIST_SIZE)); /* Write the base address of the frame list in the periodicListbase */ USB_EHCD_SET_FIELD(pHCDData, PERIODICLISTBASE, BASE_ADDRESS, ((UINT32)USB_EHCD_CONVERT_TO_BUS_MEM( uBusIndex,pFrameList) >> USB_EHCD_PERIODICLISTBASE_BASE_ADDRESS)); /* Enable the periodic schedule */ USB_EHCD_SET_BIT(pHCDData, USBCMD, PERIODIC_SCHEDULE_ENABLE); /* Set the interrupt threshold to generate interrupt after 125 us */ USB_EHCD_SET_FIELD(pHCDData, USBCMD, INT_THRESHOLD_CONTROL, 1); /* Set the Run/Stop bit to start the Host Controller */ USB_EHCD_SET_BIT(pHCDData, USBCMD, RS); /* * Set the CONFIGURE_FLAG bit to default route all the ports * to the EHCI Host Controller */ USB_EHCD_SET_BIT(pHCDData, CONFIGFLAG, CF); /* Read the number of ports supported by the EHCI Host Controller */ pHCDData->RHData.uNumDownstreamPorts = USB_EHCD_GET_FIELD(pHCDData, HCSPARAMS, N_PORTS); /* Check if the number of ports is valid */ OS_ASSERT(0 != pHCDData->RHData.uNumDownstreamPorts); /* Allocate memory for the Root hub port status */ pHCDData->RHData.pPortStatus = (UCHAR *) OS_MALLOC(pHCDData->RHData.uNumDownstreamPorts * USB_EHCD_RH_PORT_STATUS_SIZE); /* Check if memory allocation is successful */ if (NULL == pHCDData->RHData.pPortStatus) { OS_LOG_MESSAGE_HIGH(EHCD,"usbEhcdDataInitialize - memory not allocated for \ port status\n",0,0,0,0); usbEhcdDataUninitialize(pHCDData); return FALSE; } /* Initialize the fields of the port status register */ OS_MEMSET(pHCDData->RHData.pPortStatus, 0, pHCDData->RHData.uNumDownstreamPorts*USB_EHCD_RH_PORT_STATUS_SIZE); /* * The interrupt transfer data is of the following format * D0 - Holds the status change information of the hub
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -