📄 usbehcdinitexit.c
字号:
/* usbEhcdInitExit.c - USB EHCI HCD initialization routine *//* Copyright 2003 Wind River Systems, Inc. *//*Modification history--------------------01f,08Sep03,nrv Changed g_HostControllerCount to g_EHCDControllerCount01e,23Jul03,gpd Incorporated the changes after testing for MIPS01d,12Jul03,gpd Driver handle can be zero. The check has been removed. 01c,05Jul03,gpd if no host controller is found, the function should return error.01b,26jun03,psp changing the code to WRS standards.01a,25apr03,ram written.*//*DESCRIPTIONThis contains the initialization and uninitialization functionsprovided by the EHCI Host Controller Driver.INCLUDE FILES: usb2/usbOsal.h, usb2/BusAbstractionLayer.h, usb2/usbEhcdConfig.h, usb2/usbHst.h, usb2/usbEhcdDataStructures.h, usb2/usbEhcdInterfaces.h, usb2/usbEhcdHal.h, usb2/usbEhcdUtil.h, usb2/usbEhcdEventHandler.h, usb2/usbHcdInstr.h*//*INTERNAL ******************************************************************************* * Filename : usbEhcdInitExit.c * * Copyright : * * THE COPYRIGHT IN THE CONTENTS OF THIS SOFTWARE VEST WITH WIPRO * LIMITED A COMPANY INCORPORATED UNDER THE LAWS OF INDIA AND HAVING * ITS REGISTERED OFFICE AT DODDAKANNELLI SARJAPUR ROAD BANGALORE * 560 035. DISTRIBUTION OR COPYING OF THIS SOFTWARE BY * ANY INDIVIDUAL OR ENTITY OTHER THAN THE ADDRESSEE IS STRICTLY * PROHIBITED AND MAY INCUR LEGAL LIABILITY. IF YOU ARE NOT THE * ADDRESSEE PLEASE NOTIFY US IMMEDIATELY BY PHONE OR BY RETURN EMAIL. * THE ADDRESSEE IS ADVISED TO MAINTAIN THE PROPRIETARY INTERESTS OF * THIS COPYRIGHT AS PER APPLICABLE LAWS. * * * * Description : This contains the initialization and uninitialization * functions provided by the EHCI Host Controller Driver. * * ******************************************************************************/#include "usb2/usbOsal.h"#include "usb2/BusAbstractionLayer.h"#include "usb2/usbEhcdConfig.h"#include "usb2/usbHst.h"#include "usb2/usbEhcdDataStructures.h"#include "usb2/usbEhcdInterfaces.h"#include "usb2/usbEhcdHal.h"#include "usb2/usbEhcdUtil.h"#include "usb2/usbEhcdEventHandler.h"#include "usb2/usbHcdInstr.h"#define USB_EHCD_DMA_MEMORY_SIZE 0x10000/****************************** Global Variables ****************************//* globals */extern UINT32 IRQ_EHCI[];extern UINT32 BADDR_EHCI[];/* To hold the array of pointers to the HCD maintained data structures */pUSB_EHCD_DATA g_pEHCDData[USB_EHCD_MAX_HOST_CONTROLLERS];/* * To hold the pointer to the USBHST_HC_DRIVER data structure which is * used for registering with the USBD. */pUSBHST_HC_DRIVER g_pEHCDriverInfo = NULL;/* To hold the handle returned by the USBD during HC driver registration */UINT32 g_EHCDHandle = 0;/* Number of host controllers present in the system */UINT32 g_EHCDControllerCount = 0;/* Event used for synchronising the access of the free lists */OS_EVENT_ID g_ListAccessEvent = NULL;char *ehcdDMAPool = NULL;PART_ID ehcdmemPartID;/* Structure to hold the function pointers for tt Request and reset Request * USBD indication functions */USBHST_USBD_TO_HCD_FUNCTION_LIST g_USBDRequestFunctions;/* Function to destroy the periodic interrupt tree */VOID usbEhcdDestroyInterruptTree(pUSB_EHCD_DATA pHCDData);/* Function to uninitialize the data structure */VOID usbEhcdDataUninitialize(pUSB_EHCD_DATA pHCDData);/* Function to create the interrupt tree */BOOLEAN usbEhcdCreateInterruptTree(pUSB_EHCD_DATA pHCDData);USB_EHCD_BUS_STATUS usbEhcdHostBusInitialize(pUSB_EHCD_DATA *ppHCDData, UINT32 uIndex);VOID usbEhcdHostBusUninitialize(pUSB_EHCD_DATA pHCDData);/***************************************************************************** usbEhcdCreateInterruptTree - creates the periodic tree.** This function creates the periodic tree created for the* interrupt endpoints.** RETURNS: TRUE, or FALSE if periodic tree is not created.** ERRNO:* None.** \NOMANUAL*/BOOLEAN usbEhcdCreateInterruptTree ( pUSB_EHCD_DATA pHCDData ) { /* To hold the index into the nodes of the periodic tree */ UINT32 uCount = 0; /* Pointer to the Queue Head data structure */ pUSB_EHCD_QH pQH = NULL; /* Temporary variable */ UINT32 uTempVariable = 0; /* Temporary count variable */ UINT32 uTempCount = 0; /* * Static array which helps in arriving * at the next indices of the leaf nodes */ static UCHAR Balance[USB_EHCD_MAX_LEAF_NODES] ={ 0x0, 0x08, 0x04, 0x0C, 0x02, 0x0A, 0x06, 0x0E, 0x01, 0x09, 0x05, 0x0D, 0x03, 0x0B, 0x07, 0x0F }; /* * This loop will create the first 31 empty nodes of the periodic tree * and initialize the link pointers. */ for (uCount = 0; (USB_EHCD_MAX_TREE_NODES/2) > uCount; uCount++) { /* Create an empty QH */ pQH = usbEhcdFormEmptyQH(); /* Check if QH pointer is valid */ if (NULL == pQH) { /* Release memory allocated */ usbEhcdDestroyInterruptTree(pHCDData) ; return FALSE; } /* Update the node pointer */ pHCDData->TreeListData[uCount].pHeadPointer = pQH; /* Update the tail pointer in the list to be the same as the node */ pHCDData->TreeListData[uCount].pTailPointer = pQH; /* The S-mask field should be non-zero for periodic endpoints */ USB_EHCD_SET_BITFIELD(QH, pQH->uEndPointCapabilities, 1, ENDPOINT_CAPABILITIES_UFRAME_S); /* As this is only a dummy QH, set the halted bit */ USB_EHCD_SET_BITFIELD(QH, pQH->uTransferInfo, USB_EHCD_QTD_STATUS_HALTED, TRANSFERINFO_STATUS); /* Initialize the bandwidth reserved fields */ for (uTempCount = 0; USB_EHCD_MAX_MICROFRAME_NUMBER > uTempCount; uTempCount++) { pHCDData->TreeListData[uCount].uBandwidth[uTempCount] = 0; } /* * If it is not the root of the node, update the * next pointer index and the next pointer */ if (0 < uCount) { /* Update the next pointer in the list */ pQH->pNext = pHCDData->TreeListData[(uCount-1)/2].pHeadPointer; /* Update the next list index */ pHCDData->TreeListData[uCount].uNextListIndex = (uCount-1)/2; /* Update the link pointer */ USB_EHCD_SET_BITFIELD(QH, pQH->uQueueHeadHorizontalLinkPointer, ((unsigned) USB_EHCD_CONVERT_TO_PCI(pQH->pNext) >> 5), HORIZONTAL_LINK_POINTER ); /* Indicate that this is not the last element in the list */ USB_EHCD_SET_BITFIELD(QH, pQH->uQueueHeadHorizontalLinkPointer, USB_EHCD_VALID_LINK, HORIZONTAL_LINK_POINTER_T); /* Update the type of the data structure to be a QH */ USB_EHCD_SET_BITFIELD(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)); } else { /* Update the next list index */ pHCDData->TreeListData[uCount].uNextListIndex = USB_EHCD_NO_LIST; /* * Set the terminate bit indicating that there are no more * elements in the list. */ USB_EHCD_SET_BITFIELD(QH, pQH->uQueueHeadHorizontalLinkPointer, USB_EHCD_INVALID_LINK, HORIZONTAL_LINK_POINTER_T); /* Update the type of the data structure to be a QH */ USB_EHCD_SET_BITFIELD(QH, pQH->uQueueHeadHorizontalLinkPointer, USB_EHCD_TYPE_QH, HORIZONTAL_LINK_POINTER_TYPE); pQH->pNext = NULL; /* Flush the cache contents to the RAM */ CACHE_DMA_FLUSH(pQH, sizeof(USB_EHCD_QH)); } } /* End of for () */ /* * This loop will update the link pointers of the leaf nodes * of the interrupt tree as per the static data available */ for (; USB_EHCD_MAX_TREE_NODES > uCount; uCount++, uTempCount++) { /* To hold the index into the microframe bandwidth array */ UINT uFrameIndex = 0; /* Create an empty QH */ pQH = usbEhcdFormEmptyQH(); /* Check if QH pointer is valid */ if (NULL == pQH) { /* Release memory allocated */ usbEhcdDestroyInterruptTree(pHCDData) ; return FALSE; } /* Update the node pointer */ pHCDData->TreeListData[uCount].pHeadPointer = pQH; /* Update the tail pointer in the list to be the same as the node */ pHCDData->TreeListData[uCount].pTailPointer = pQH; /* The S-mask field should be non-zero for periodic endpoints */ USB_EHCD_SET_BITFIELD(QH, pQH->uEndPointCapabilities, 1, ENDPOINT_CAPABILITIES_UFRAME_S); /* As this is only a dummy QH, set the halted bit */ USB_EHCD_SET_BITFIELD(QH, pQH->uTransferInfo, USB_EHCD_QTD_STATUS_HALTED, TRANSFERINFO_STATUS); /* Initialize the bandwidth reserved fields */ for (uFrameIndex = 0; USB_EHCD_MAX_MICROFRAME_NUMBER > uFrameIndex; uFrameIndex++) { pHCDData->TreeListData[uCount].uBandwidth[uFrameIndex] = 0; } /* Update the index of the next node in the list */ uTempVariable = Balance[uTempCount & 0x0F] + ((USB_EHCD_MAX_LEAF_NODES/2) - 1); /* Update the next list index */ pHCDData->TreeListData[uCount].uNextListIndex = uTempVariable; /* Update the QH's Next pointer */ pQH->pNext = pHCDData->TreeListData[uTempVariable].pHeadPointer; /* Update the link pointer */ USB_EHCD_SET_BITFIELD(QH, pQH->uQueueHeadHorizontalLinkPointer, ((unsigned) USB_EHCD_CONVERT_TO_PCI(pQH->pNext) >> 5), HORIZONTAL_LINK_POINTER ); /* Indicate that this is not the last element in the list */ USB_EHCD_SET_BITFIELD(QH, pQH->uQueueHeadHorizontalLinkPointer, USB_EHCD_VALID_LINK, HORIZONTAL_LINK_POINTER_T); /* Update the type of the data structure to be a QH */ USB_EHCD_SET_BITFIELD(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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -