📄 usbehcdbandwidth.c
字号:
/* usbEhcdBandwidth.c - contains the bandwidth functions of EHCD *//* 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--------------------01e,28mar05,pdg non-PCI changes01d,22mar05,mta 64-bit Support Added (SPR #104950)01c,03dec04,ami Merged IP Changes01b,26jun03,gpd changing the code to WRS standards.01a,25apr02,ram written.*//*DESCRIPTIONThis module defines the bandwidth related functions for theEHCI Host Controller Driver.INCLUDE FILES: usbOsal.h, usbOsalDebug.h, usbHst.h, usbEhcdDataStructures.h, usbEhcdUtil.h, usbEhcdDebug.h,SEE ALSO:<USB specification, revision 2.0><EHCI specification, revision 1.0>*//* INTERNAL ******************************************************************************* * * Filename : usbEhcdBandwidth.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 functions which handle the bandwidth * related requests by the EHCI Driver. * * ******************************************************************************//* includes */#include "usb2/usbOsal.h"#include "usb2/usbOsalDebug.h"#include "usb2/usbHst.h"#include "usb2/usbEhcdDataStructures.h"#include "usb2/usbEhcdUtil.h"/***************************************************************************** usbEhcdSubBandwidth - Subtract the bw utilised by each endpoint** This function is used to Subtract the bw utilised by each endpoint and returns the* updated bandwidth array** <pHCDData> - Pointer to the EHCD_DATA structure.* <uDeviceAddress> - Device Address.* <uSpeed> - Device Speed Device Speed of the transfer* <pInterfaceDesc> - Pointer to the interface desc.* <pFrameBW> - Array of bandwidth list** RETURNS: USBHST_SUCCESS - Returned if success.* USBHST_INSUFFICIENT_MEMORY - Returned if the memory* allocation for failed.*** ERRNO:* None.* \NOMANUAL*/USBHST_STATUS usbEhcdSubBandwidth ( pUSB_EHCD_DATA pHCDData, /* Pointer to the EHCD_DATA structure */ UINT32 uDeviceAddress, /* Device Address */ UINT32 uSpeed, /* Device Speed of the transfer */ pUSBHST_INTERFACE_DESCRIPTOR pInterfaceDesc, /* Pointer to the interface desc */ UINT32 * pTotalFrameBW /* Array of bandwidth list */ ) { /* To hold the micro frame index */ UINT32 uUFrameIndex = 0; /* To hold the frame index in the frame list */ UINT32 uFrameIndex = 0; /* To hold the supported poll interval */ UINT32 uPollInterval = 0; /* To hold the end point descriptor */ pUSBHST_ENDPOINT_DESCRIPTOR pEPDesc = NULL; /* structure to hold the bandwidth details */ struct _bandwidth_ { UINT32 InterruptBW[USB_EHCD_MAX_TREE_NODES][USB_EHCD_MAX_MICROFRAME_NUMBER]; UINT32 IsochBW[USB_EHCD_MAX_FRAMELIST_SIZE][USB_EHCD_MAX_MICROFRAME_NUMBER]; } *pBandwidth; /* To hold the count */ UINT32 uCount; /* To hold the total nos of endpoint */ UINT32 uEPCount; /* Allocate memory for bandwidth pointer for interrupt and isoch */ pBandwidth = (struct _bandwidth_ *)OS_MALLOC(sizeof(struct _bandwidth_)); if(NULL == pBandwidth) { OS_LOG_MESSAGE_HIGH(EHCD,"usbEhcdIsBandwidthAvailable -"\ " Memory not allocated for the bandwidth\n",0,0,0,0); return USBHST_MEMORY_NOT_ALLOCATED; } /* Initialize the element of array to zero */ OS_MEMSET(pBandwidth, 0, sizeof(struct _bandwidth_)); /* Exclusively access the bandwidth resource */ OS_WAIT_FOR_EVENT(pHCDData->BandwidthEventID,OS_WAIT_INFINITE); /* Get the bandwidth used for isochronous in frame list */ USB_EHCD_GET_ISOCH_BANDWIDTH(pHCDData, pBandwidth->IsochBW); /* Get the bandwidth used for isochronous in frame list */ USB_EHCD_GET_INTERRUPT_BANDWIDTH(pHCDData, pBandwidth->InterruptBW); /* Release the bandwidth exclusive access */ OS_RELEASE_EVENT(pHCDData->BandwidthEventID); /* Get the total no of endpoint for this interface */ uEPCount = pInterfaceDesc->bNumEndpoints; pEPDesc = (pUSBHST_ENDPOINT_DESCRIPTOR)((UINT8 *)(pInterfaceDesc) + pInterfaceDesc->bLength); while(USBHST_ENDPOINT_DESC!=pEPDesc->bDescriptorType) { pEPDesc = (pUSBHST_ENDPOINT_DESCRIPTOR)((UINT8 *)(pEPDesc) + pEPDesc->bLength); } for (uCount=0; uCount < uEPCount; uCount++) { /* Get the polling interval of the endpoint */ uPollInterval = pEPDesc->bInterval; if (USBHST_INTERRUPT_TRANSFER == (pEPDesc->bmAttributes & USB_EHCD_ENDPOINT_TYPE_MASK)) { UINT8 uTempVariable = 0; UINT8 uTreeListIndex = 0; UINT8 uTreeNodeCount; if (USBHST_HIGH_SPEED == uSpeed) { /* Calculate the updated polling interval. This is in * units of microframes 2^n */ uPollInterval = 1 << (uPollInterval - 1); USB_EHCD_GET_POLL_INTERVAL(uPollInterval); } else if (USB_EHCD_MAX_USB11_INTERRUPT_POLL_INTERVAL < uPollInterval) { uPollInterval = USB_EHCD_MAX_USB11_INTERRUPT_POLL_INTERVAL; } /* Get the starting node in the tree for this interval */ uTempVariable = uPollInterval; uTreeListIndex = 1; while(uTempVariable >>= 1) { uTreeListIndex <<= 1; } for (uTreeNodeCount =uTreeListIndex; (uPollInterval + uTreeListIndex) > uTreeNodeCount; uTreeNodeCount++) { BOOLEAN bNodeFound = FALSE; pUSB_EHCD_QH pQH = (pUSB_EHCD_QH)( (UINT32)pHCDData->TreeListData[uTreeNodeCount].pHeadPointer - USB_EHCD_QH_HEADER_SIZE); if(NULL == pQH->pNext) { continue; } do { /* Get the first active QH pointer in first iteration thene get next pointer*/ pQH = pQH->pNext; if((uDeviceAddress == pQH->pHCDPipe->uAddress) && (pQH->pHCDPipe->uEndpointAddress == pEPDesc->bEndpointAddress)) { for (uUFrameIndex = 0; USB_EHCD_MAX_MICROFRAME_NUMBER > uUFrameIndex; uUFrameIndex++) { /* Check if bandwidth is to be updated for this * microframe and update the bandwidth */ if (0 != ((pQH->pHCDPipe->uUFrameMaskValue >> uUFrameIndex) & 0x01)) { pBandwidth->InterruptBW[uTreeNodeCount][uUFrameIndex] -= pQH->pHCDPipe->uBandwidth; } } bNodeFound = TRUE; break; } }while(pQH != (pUSB_EHCD_QH)((UINT32) pHCDData->TreeListData[uTreeNodeCount].pTailPointer - USB_EHCD_QH_HEADER_SIZE)); if (bNodeFound) { break; } } } else if(USBHST_ISOCHRONOUS_TRANSFER == (pEPDesc->bmAttributes & USB_EHCD_ENDPOINT_TYPE_MASK)) { /* To hold the isochronous pipe */ pUSB_EHCD_PIPE pHCDPipe = NULL; /* Get pointer of the isochronous pipe list */ for (pHCDPipe = pHCDData->pIsochPipeList; NULL != pHCDPipe; pHCDPipe = pHCDPipe->pNext) { if ((uDeviceAddress == pHCDPipe->uAddress) && (pHCDPipe->uEndpointAddress == pEPDesc->bEndpointAddress)) { /* This loop will remove the bandwidth * allocated in each of the frames */ for (uFrameIndex = pHCDPipe->uListIndex; USB_EHCD_MAX_FRAMELIST_SIZE > uFrameIndex; uFrameIndex++) { /* This loop will update the frame list bandwidth * for every microframe */ for (uUFrameIndex = 0; USB_EHCD_MAX_MICROFRAME_NUMBER > uUFrameIndex; uUFrameIndex++) { /* Check if bandwidth is to be updated for this * microframe and update the bandwidth */ if (0 != ((pHCDPipe->uUFrameMaskValue >> uUFrameIndex) & 0x01)) { pBandwidth->IsochBW[uFrameIndex][uUFrameIndex] -= pHCDPipe->uBandwidth; } } /* End of loop for each microframe */ } /* End of loop for each frame */ break; /* Pipe found */ } /* End of if */ } /* End of loop for pipe search */ }/* end of else if */ pEPDesc = (pUSBHST_ENDPOINT_DESCRIPTOR)((UINT8 *)(pEPDesc) + pEPDesc->bLength); } /* end of loop for each endpoint */ /* Get the bandwidth per frame in the frame list */ USB_EHCD_GET_FRAME_BANDWIDTH(pHCDData, pBandwidth->IsochBW, pBandwidth->InterruptBW, pTotalFrameBW); /* free the memory allocated */ OS_FREE(pBandwidth); return USBHST_SUCCESS; } /* End of function *//***************************************************************************** usbEhcdSubDeviceBandwidth - Subtract the bw utilised by each device** This function is used to Subtract the bw utilised by each endpoint and returns the* updated bandwidth array** <pHCDData> - Pointer to the EHCD_DATA structure.* <uDeviceAddress> - Device Address.* <pInterfaceDesc> - Pointer to the interface desc.* <pFrameBW> - Array of bandwidth list** RETURNS: USBHST_SUCCESS - Returned if success.* USBHST_INSUFFICIENT_MEMORY - Returned if the memory* allocation for failed.*** ERRNO:* None.* \NOMANUAL*/USBHST_STATUS usbEhcdSubDeviceBandwidth ( pUSB_EHCD_DATA pHCDData, /* Pointer to the EHCD_DATA structure */ UINT32 uDeviceAddress, /* Device Address */ UINT32 * pTotalFrameBW /* Array of bandwidth list */ ) { /* To hold the micro frame index */ UINT32 uUFrameIndex = 0; /* To hold the frame index in the frame list */ UINT32 uFrameIndex = 0; /* To hold the tree node index in the frame list */ UINT32 uTreeNodeCount; /* To hold the isochronous pipe */ pUSB_EHCD_PIPE pHCDPipe = NULL; /* structure to hold the bandwidth details */ struct _bandwidth_ { UINT32 InterruptBW[USB_EHCD_MAX_TREE_NODES][USB_EHCD_MAX_MICROFRAME_NUMBER]; UINT32 IsochBW[USB_EHCD_MAX_FRAMELIST_SIZE][USB_EHCD_MAX_MICROFRAME_NUMBER]; } *pBandwidth; /* Allocate memory for bandwidth pointer for interrupt and isoch */ pBandwidth = (struct _bandwidth_ *)OS_MALLOC(sizeof(struct _bandwidth_));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -