📄 usbehcdinitexit.c
字号:
( 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 status of the find usb controller macro */ BOOL bStatus = FALSE; /* To temporarily hold the value of bus number */ INT32 nBusNumber = 0; /* To temporarily hold the value of device number */ INT32 nDeviceNumber = 0; /* To temporarily hold the value of function number */ INT32 nFunctionNumber = 0; /* 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 >= USB_EHCD_MAX_HOST_CONTROLLERS) { OS_LOG_MESSAGE_HIGH(EHCD,"usbEhcdHostBusInitialize - parameters are \ not valid\n",0,0,0,0); return USB_EHCD_HCBUS_NOT_INITIALIZED; } /* Locate the Host controller */ bStatus = FIND_USB_CONTROLLER(USB_EHCI_HOST_CONTROLLER, uIndex, &nBusNumber, &nDeviceNumber, &nFunctionNumber); /* Check if the host controller is successfully located */ if (TRUE != bStatus) { OS_LOG_MESSAGE_MEDIUM(EHCD,"usbEhcdHostBusInitialize - EHCI Host Controller \ not present\n",0,0,0,0); return USB_EHCD_HC_NOT_PRESENT; } /* Swap the data retrieved */ nBusNumber = OS_UINT32_LE_TO_CPU(nBusNumber); nDeviceNumber = OS_UINT32_LE_TO_CPU(nDeviceNumber); nFunctionNumber = OS_UINT32_LE_TO_CPU(nFunctionNumber); /* 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 = IRQ_EHCI[uIndex]; (*ppHCDData)->pPCIBaseAddress =(UINT8 *) BADDR_EHCI[uIndex]; (*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 */ Status = REGISTER_INTERRUPT_HANDLER(uIRQ, usbEhcdISR, (INT32)*ppHCDData); /* 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"; 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; } /* Allocate memory for the frame list */ pHCDData->pAllocatedFrameList = memPartAlignedAlloc(ehcdmemPartID, (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(FRAME_LIST, (*(pFrameList + uCount)), ((unsigned)USB_EHCD_CONVERT_TO_PCI( (pHCDData->TreeListData[uTempVariable].pHeadPointer)) >> 5),POINTER); /* Indicate that the link pointer points to a QH */ USB_EHCD_SET_BITFIELD(FRAME_LIST, (*(pFrameList + uCount)), USB_EHCD_TYPE_QH,POINTER_TYPE) ; USB_EHCD_SET_BITFIELD(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_PCI(pFrameList) >> USB_EHCD_PERIODICLISTBASE_BASE_ADDRESS)); /* Enable the periodic schedule */ USB_EHCD_SET_BIT(pHCDData, USBCMD, PERIODIC_SCHEDULE_ENABLE); /* 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 * D1 - Holds the status change information of the Port 1 * * Dn - holds the status change information of the Port n * So if the number of downstream ports is N, the size of interrupt * transfer data would be N + 1 bits. */ uTempVariable = (pHCDData->RHData.uNumDownstreamPorts + 1)/ 8; if (0 != ((pHCDData->RHData.uNumDownstreamPorts + 1) % 8)) { uTempVariable = uTempVariable + 1; } /* Allocate memory for the interrupt transfer data */ pHCDData->RHData.pHubInterruptData = OS_MALLOC(uTempVariable); /* Check if memory allocation is successful */ if (NULL == pHCDData->RHData.pHubInterruptData) { OS_LOG_MESSAGE_HIGH(EHCD,"usbEhcdDataInitialize - memory not allocated for \ interrupt transfer data \n",0,0,0,0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -