?? usbehcdtransfermanagement.c
字號(hào):
/* usbEhcdTransferManagement.c - transfer management functions of the EHCD *//* Copyright 2002-2003 Wind River Systems, Inc. *//*modification history--------------------01f,08Sep03,nrv Changed g_HostControllerCount to g_EHCDControllerCount01e,28Jul03,gpd Incorporated the changes after integration testing.01d,23Jul03,gpd Incorporated the changes after testing on MIPS.01c,03Jul03,gpd changed the search algorithm on a delete pipe cancelling URBs should use the asynch on advance and frame list rollover interrupts.01b,26jun03,gpd changing the code to WRS standards.01a,25apr02,ram written.*//*DESCRIPTIONThis module defines the interfaces which are registered with the USBD duringEHCI Host Controller Driver initialization.INCLUDE FILES: usbhst.h, usbEhcdDataStructures.h, usbEhcdInterfaces.h, usbEhcdUtil.h, usbEhcdConfig.h, usbEhcdHal.h, usbEhcdRHEmulation.h, usbEhcdDebug.hSEE ALSO:None*//*INTERNAL ******************************************************************************* * Filename : EHCD_TransferManagement.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 transfer * management requests from the USBD. * * ******************************************************************************//* includes */#include "usb2/usbOsal.h"#include "usb2/BusAbstractionLayer.h"#include "usb2/usbHst.h"#include "usb2/usbEhcdDataStructures.h"#include "usb2/usbEhcdInterfaces.h"#include "usb2/usbEhcdUtil.h"#include "usb2/usbEhcdConfig.h"#include "usb2/usbEhcdHal.h"#include "usb2/usbEhcdRhEmulation.h"#include "usb2/usbHcdInstr.h"/* globals *//* To hold the array of pointers to the HCD maintained data structures */extern pUSB_EHCD_DATA g_pEHCDData[USB_EHCD_MAX_HOST_CONTROLLERS];/* Number of host controllers present in the system */extern UINT32 g_EHCDControllerCount;/***************************************************************************** usbEhcdCreatePipe - creates a pipe specific to an endpoint.** This function creates the host controller driver specific data structure,* creates the queue head if it is a non-isochronous pipe and populates the* <puPipeHandle> parameter with the pointer to the data structure created for* the pipe. <uBusIndex> is the index of the host controller. <uDeviceAddress>* is the address of the device holding the endpoint. <uDeviceSpeed> is the * speed of the device holding the endpoint. <pEndpointDescriptor> is the * pointer to the endpoint descriptor. <uHighSpeedHubInfo> is the high speed* hub information. <puPipeHandle> is the pointer to the handle to the pipe.** RETURNS: * USBHST_SUCCESS - Returned if the pipe was created successfully.* USBHST_INVALID_PARAMETER - Returned if the parameters are not valid.* USBHST_INSUFFICIENT_MEMORY - Returned if the memory allocation * for the pipe failed.** ERRNO:* None.** \NOMANUAL*/USBHST_STATUS usbEhcdCreatePipe ( UINT8 uBusIndex, /* Host controller index */ UINT8 uDeviceAddress, /* USB device address */ UINT8 uDeviceSpeed, /* USB device speed */ UCHAR *pEndpointDescriptor,/* Endpoint descriptor */ UINT16 uHighSpeedHubInfo, /* High speed hub information */ UINT32 *puPipeHandle /* Pointer to the pipe handle */ ) { /* To hold the status of the request */ USBHST_STATUS Status = USBHST_FAILURE; /* Pointer to the Endpoint Descriptor */ pUSBHST_ENDPOINT_DESCRIPTOR pEndpointDesc = NULL; /* To hold the pointer to the EHCD maintained pipe data structure */ pUSB_EHCD_PIPE pHCDPipe = NULL; /* Bandwidth required for this pipe */ UINT32 uBandwidth = 0; /* Pointer to the HCD specific data structure */ pUSB_EHCD_DATA pHCDData = NULL; /* Microframe mask */ UINT32 uUFrameMask = 0; /* To hold the index of the list */ UINT32 uListIndex = 0; /* To hold the index into the microframes */ UINT32 uUFrameIndex = 0; /* To hold the value of the step into the frame list */ UINT32 uStepValue = 0; /* To hold the control end point */ UINT32 controlEndFlag; /* To hold the pointer to the Queue Head */ pUSB_EHCD_QH pQH = NULL; /* WindView Instrumentation */ USB_HCD_LOG_EVENT( USB_EHCI_WV_TRANSFER, "usbEhcdCreatePipe() starts", USB_EHCD_WV_FILTER); OS_LOG_MESSAGE_LOW(EHCD,"usbEhcdCreatePipe - Entry\n",0,0,0,0); /* Check the validity of the parameters */ if ((g_EHCDControllerCount <= uBusIndex) || (USB_EHCD_MAX_DEVICE_ADDRESS < uDeviceAddress) || (NULL == pEndpointDescriptor) || (NULL == puPipeHandle)) { OS_LOG_MESSAGE_HIGH(EHCD,"EHCD_CreatePipe - parameters are not valid\n",0,0,0,0); return USBHST_INVALID_PARAMETER; } /* Extract the global data structure */ pHCDData = g_pEHCDData[uBusIndex]; /* Assert if the global pointer is not valid */ OS_ASSERT(NULL != pHCDData); /* Check if the request is for the Root hub and route it */ if (uDeviceAddress == pHCDData->RHData.uDeviceAddress) { Status = usbEhcdRhCreatePipe(pHCDData, uDeviceAddress, uDeviceSpeed, pEndpointDescriptor, puPipeHandle); return Status; } /* Retrieve the endpoint descriptor */ pEndpointDesc = (pUSBHST_ENDPOINT_DESCRIPTOR)pEndpointDescriptor; /* Swap the maximum packet size to get it in CPU endian format */ pEndpointDesc->wMaxPacketSize = OS_UINT16_LE_TO_CPU(pEndpointDesc->wMaxPacketSize); /* Check the validity of the endpoint type */ if ((USBHST_ISOCHRONOUS_TRANSFER != (pEndpointDesc->bmAttributes & USB_EHCD_ENDPOINT_TYPE_MASK)) && (USBHST_INTERRUPT_TRANSFER != (pEndpointDesc->bmAttributes & USB_EHCD_ENDPOINT_TYPE_MASK)) && (USBHST_CONTROL_TRANSFER != (pEndpointDesc->bmAttributes & USB_EHCD_ENDPOINT_TYPE_MASK)) && (USBHST_BULK_TRANSFER != (pEndpointDesc->bmAttributes & USB_EHCD_ENDPOINT_TYPE_MASK))) { OS_LOG_MESSAGE_HIGH(EHCD,"usbEhcdCreatePipe - endpoint types is not valid\n",0,0,0,0); return USBHST_INVALID_PARAMETER; } /* Check if the endpoint type is isochronous or interrupt */ if ((USBHST_ISOCHRONOUS_TRANSFER == (pEndpointDesc->bmAttributes & USB_EHCD_ENDPOINT_TYPE_MASK)) || (USBHST_INTERRUPT_TRANSFER == (pEndpointDesc->bmAttributes & USB_EHCD_ENDPOINT_TYPE_MASK))) { /* To hold the maximum packet size for the endpoint */ UINT32 uMaxPacketSize = 0; /* To hold the status of the bandwidth availability */ BOOLEAN bIsBwAvailable = FALSE; /* If the device speed is high speed, the payload is * equal the maxpacketsize * number of packets that can * be sent in a microframe. * The bits 0 to 10 give the maximum packet size. The bits 11 and 12 * give the (number of packets in a microframe - 1). */ if (USBHST_HIGH_SPEED == uDeviceSpeed) { uMaxPacketSize = ((pEndpointDesc->wMaxPacketSize) & USB_EHCD_ENDPOINT_MAX_PACKET_SIZE_MASK) * ((((pEndpointDesc->wMaxPacketSize) & USB_EHCD_ENDPOINT_NUMBER_OF_TRANSACTIONS_MASK) >> 11) + 1); } /* If it is low or full speed, the maximum packet size is the same * as that retrieved from the endpoint descriptor */ else { uMaxPacketSize = pEndpointDesc->wMaxPacketSize; } /* Calculate the bandwidth which is required for this pipe */ uBandwidth = usbEhcdCalculateBusTime( uDeviceSpeed, (pEndpointDesc->bEndpointAddress) & USB_EHCD_DIR_IN, (pEndpointDesc->bmAttributes) & USB_EHCD_ENDPOINT_TYPE_MASK, uMaxPacketSize); /* Check if this bandwidth can be accomodated */ bIsBwAvailable = usbEhcdCheckBandwidth(pHCDData, uBandwidth, uDeviceSpeed, pEndpointDesc, &uListIndex, &uUFrameMask, &uStepValue); /* If bandwidth is not available, return an error */ if (FALSE == bIsBwAvailable) { OS_LOG_MESSAGE_HIGH(EHCD,"usbEhcdCreatePipe - bandwidth is not available\n",0,0,0,0); return USBHST_INSUFFICIENT_BANDWIDTH; } } /* Allocate memory for the USB_EHCD_PIPE data structure */ pHCDPipe = (pUSB_EHCD_PIPE)OS_MALLOC(sizeof(USB_EHCD_PIPE)); /* Check if memory allocation is successful */ if (NULL == pHCDPipe) { OS_LOG_MESSAGE_HIGH(EHCD,"usbEhcdCreatePipe - Memory not allocated for EHCD pipe\n",0,0,0,0); return USBHST_MEMORY_NOT_ALLOCATED; } /* Update the pointer to the pipe handle */ *puPipeHandle = (UINT32)pHCDPipe; /* Initialize the pipe data structure */ USB_EHCD_PIPE_INITIALIZE(pHCDPipe); /* Update the endpoint speed */ pHCDPipe->uSpeed = uDeviceSpeed; /* Update the device address which holds the endpoint */ pHCDPipe->uAddress = uDeviceAddress; /* Update the high speed hub information */ pHCDPipe->uHubInfo = uHighSpeedHubInfo; /* Update the type of endpoint to be created */ pHCDPipe->uEndpointType = (pEndpointDesc->bmAttributes) & USB_EHCD_ENDPOINT_TYPE_MASK; /* Update the direction of the endpoint */ pHCDPipe->uEndpointDir = ((pEndpointDesc->bEndpointAddress & USB_EHCD_DIR_IN) >> USB_EHCD_DIR_BIT_POSITION) & 0x1; /* Update Endpoint address */ pHCDPipe->uEndpointAddress = pEndpointDesc->bEndpointAddress; /* Store the maximum packet size - for high speed includes the number * of transactions in a microframe also */ pHCDPipe->uMaximumPacketSize = pEndpointDesc->wMaxPacketSize; /* If it is an interrupt or isochronous endpoint, update the bandwidth */ if ((USBHST_ISOCHRONOUS_TRANSFER == pHCDPipe->uEndpointType) || (USBHST_INTERRUPT_TRANSFER == pHCDPipe->uEndpointType)) { /* To hold the status of the bandwidth reservation */ BOOLEAN bStatus = FALSE; /* Update the bandwidth occupied by the endpoint */ pHCDPipe->uBandwidth = uBandwidth; /* Copy the list index */ pHCDPipe->uListIndex = uListIndex; /* Copy the mask value */ pHCDPipe->uUFrameMaskValue = uUFrameMask; /* Update the tree node bandwidth if it is an interrupt endpoint */ if (USBHST_INTERRUPT_TRANSFER == pHCDPipe->uEndpointType) { /* Copy the list index */ pHCDPipe->uListIndex = uListIndex; /* Exclusively access the bandwidth resource */ OS_WAIT_FOR_EVENT(pHCDData->BandwidthEventID,OS_WAIT_INFINITE); /* This loop will update the tree 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 != ((uUFrameMask >> uUFrameIndex) & 0x01)) { pHCDData->TreeListData[uListIndex].uBandwidth[uUFrameIndex] += uBandwidth; } } /* Release the bandwidth exclusive access */ OS_RELEASE_EVENT(pHCDData->BandwidthEventID); /* Update the overall bandwidth */ bStatus = usbEhcdUpdateBandwidth(pHCDData); /* * If the bandwidth reservation is not successful, * release the bandwidth */ if (FALSE == bStatus)
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -