📄 usbehcdinitexit.c
字号:
/* usbEhcdInitExit.c - USB EHCI HCD initialization routine *//* Copyright 2004-2005 Wind River Systems, Inc. This software includes software licensed to Wind River Systems, Inc. by Wipro, Ltd. Wind River licensees may use this software according to the terms of their Wind River license agreement(s) applicable to this software.*//*Modification history--------------------01r,11apr05,ami Changes made in Warm Reboot Function01q,04apr05,mta Fix for Detach ehci issue01p,28mar05,pdg non-PCI changes01o,22mar05,mta 64-bit support added (SPR #104950)01n,02mar05,ami SPR #106373 Fix (Max EHCI Host Controller Issue)01m,25feb05,mta SPR 10627601l,18feb05,pdg Fix for SPR #106434(From usbTool, when 'attach ohci' is called after 'detach ehci', ohci does not detect the devices)01k,03feb05,mta Fix for hcd detach leading to a hang issue01j,08dec04,pdg Corrected memory leak-USBIP merge error01i,03dec04,ami Merged IP Changes01h,26oct04,ami Severity Changes for Debug Messages01g,15oct04,ami Apigen Changes01f,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 0x40000/****************************** Global Variables ****************************//* globals */extern pUSB_HCD_BUS_INFO pEhciBusInfo[];extern UINT32 maxEhciCount;/* To hold the array of pointers to the HCD maintained data structures */pUSB_EHCD_DATA *g_pEHCDData = NULL;/* * 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;/* 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; UINT32 uBusIndex = pHCDData->uBusIndex; /* index of the host controller */ /* * 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(pHCDData); /* Check if QH pointer is valid */ if (NULL == pQH) { /* Release memory allocated */ usbEhcdDestroyInterruptTree(pHCDData) ; return FALSE; } /* Update the node pointer */ pHCDData->TreeListData[uCount].pHeadPointer = (pVOID)((UINT32)pQH + USB_EHCD_QH_HEADER_SIZE); /* Update the tail pointer in the list to be the same as the node */ pHCDData->TreeListData[uCount].pTailPointer = (pVOID)((UINT32)pQH + USB_EHCD_QH_HEADER_SIZE); /* The S-mask field should be non-zero for periodic endpoints */ USB_EHCD_SET_BITFIELD(uBusIndex, QH, pQH->uEndPointCapabilities, 1, ENDPOINT_CAPABILITIES_UFRAME_S); /* As this is only a dummy QH, set the halted bit */ USB_EHCD_SET_BITFIELD(uBusIndex, 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) { PUCHAR pQHNextTemp = NULL; /* Update the next pointer in the list */ pQH->pNext = (pVOID)((UINT32) pHCDData->TreeListData[(uCount-1)/2].pHeadPointer - USB_EHCD_QH_HEADER_SIZE); /* Update the next list index */ pHCDData->TreeListData[uCount].uNextListIndex = (uCount-1)/2; /* * Fetch the host controller accessible are from the next * queue head data structure by adding offset * USB_EHCD_QH_HEADER_SIZE to it. */ pQHNextTemp = (PUCHAR) pQH->pNext; pQHNextTemp += USB_EHCD_QH_HEADER_SIZE; USB_EHCD_SET_BITFIELD(uBusIndex, QH, pQH->uQueueHeadHorizontalLinkPointer, ((unsigned) USB_EHCD_CONVERT_TO_BUS_MEM( uBusIndex, pQHNextTemp) >> 5), HORIZONTAL_LINK_POINTER ); /* Indicate that this is not the last element in the list */ USB_EHCD_SET_BITFIELD(uBusIndex, 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(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)); } 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(uBusIndex, 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(uBusIndex, 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; PUCHAR pQHNextTemp = NULL; /* Create an empty QH */ pQH = usbEhcdFormEmptyQH(pHCDData); /* Check if QH pointer is valid */ if (NULL == pQH) { /* Release memory allocated */ usbEhcdDestroyInterruptTree(pHCDData) ; return FALSE; } /* Update the node pointer */ pHCDData->TreeListData[uCount].pHeadPointer = (pVOID)((UINT32)pQH + USB_EHCD_QH_HEADER_SIZE); /* Update the tail pointer in the list to be the same as the node */ pHCDData->TreeListData[uCount].pTailPointer = (pVOID)((UINT32)pQH + USB_EHCD_QH_HEADER_SIZE); /* The S-mask field should be non-zero for periodic endpoints */ USB_EHCD_SET_BITFIELD(uBusIndex, QH, pQH->uEndPointCapabilities, 1, ENDPOINT_CAPABILITIES_UFRAME_S); /* As this is only a dummy QH, set the halted bit */ USB_EHCD_SET_BITFIELD(uBusIndex, 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 = (pVOID)((UINT32) pHCDData->TreeListData[uTempVariable].pHeadPointer - USB_EHCD_QH_HEADER_SIZE); /* Fetch the host controller accessible region */ pQHNextTemp = (PUCHAR) pQH->pNext; pQHNextTemp += USB_EHCD_QH_HEADER_SIZE; /* Update the link pointer */ USB_EHCD_SET_BITFIELD(uBusIndex, QH, pQH->uQueueHeadHorizontalLinkPointer, ((unsigned) USB_EHCD_CONVERT_TO_BUS_MEM( uBusIndex,pQHNextTemp) >> 5), HORIZONTAL_LINK_POINTER ); /* Indicate that this is not the last element in the list */ USB_EHCD_SET_BITFIELD(uBusIndex, QH, pQH->uQueueHeadHorizontalLinkPointer, USB_EHCD_VALID_LINK, HORIZONTAL_LINK_POINTER_T);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -