?? usbehcdeventhandler.c
字號:
/* usbEhcdEventHandler.c - USB EHCI HCD interrupt handler *//* Copyright 2003 Wind River Systems, Inc. *//*Modification history--------------------01e,28Jul03, gpd Updated changes identified during integration testing.01d,23Jul03, gpd Incorporated changes after testing on MIPS01c,03jul03, gpd Included the changes for separate reclamation lists for asynchronous and periodic lists. Updated the usbEhcdProcessTransferCompletion() function to handle a transfer less than the request transfer size. Support for ClearTTBuffer request.01b,26jun03,psp changing the code to WRS standards.01a,25apr03,ram written.*//*DESCRIPTIONThis contains interrupt routines which handle the EHCI interrupts.INCLUDE FILES: usb2/usbOsal.h usb2/usbHst.h usb2/usbEhcdDataStructures.h usb2/usbEhcdUtil.h usb2/BusAbstractionLayer.h usb2/usbEhcdEventHandler.h usb2/usbEhcdHal.h usb2/usbEhcdRhEmulation.h*//*INTERNAL ******************************************************************************* * Filename : usbEhcdEventHandler.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 : USB EHCI HCD interrupt handler * * ******************************************************************************//* includes */#include "usb2/usbOsal.h"#include "usb2/usbHst.h"#include "usb2/usbEhcdDataStructures.h"#include "usb2/usbEhcdUtil.h"#include "usb2/BusAbstractionLayer.h"#include "usb2/usbEhcdEventHandler.h"#include "usb2/usbEhcdHal.h"#include "usb2/usbEhcdRhEmulation.h"#include "usb2/usbHcdInstr.h"/* globals */extern USBHST_USBD_TO_HCD_FUNCTION_LIST g_USBDRequestFunctions;extern UINT32 g_EHCDHandle;/* locals */LOCAL VOID usbEhcdPortChangeHandler ( pUSB_EHCD_DATA pEHCDData );LOCAL VOID usbEhcdProcessTransferCompletion ( pUSB_EHCD_DATA pEHCDData );LOCAL VOID usbEhcdCleanupAsynchPipes ( pUSB_EHCD_DATA pEHCDData );LOCAL VOID usbEhcdCleanupPeriodicPipes ( pUSB_EHCD_DATA pEHCDData );/***************************************************************************** usbEhcdISR - interrupt service routine for the EHCI Driver.** This routine is the ISR for the EHCI Driver.** RETURNS: N/A.** ERRNO:* None.** \NOMANUAL*/VOID usbEhcdISR ( pUSB_EHCD_DATA pHCDData ) { UINT32 uInterruptStatus = 0; /* to store the fields in interrupt enable register */ UINT32 uInterruptMask = 0;#ifndef USB_EHCD_ENABLE_POLLING OS_LOG_MESSAGE_LOW(EHCD,"usbEhcdISR - Entry\n",0,0,0,0);#endif /* Check the validity of the parameter */ if (NULL == pHCDData) { OS_LOG_MESSAGE_HIGH(EHCD,"usbEhcdISR - Parameter is not valid\n",0,0,0,0); return; }#ifndef USB_EHCD_ENABLE_POLLING /* Disable the EHCI Interrupts */ /* Get the contents uf usb interrupt Enable register */ uInterruptMask = USB_EHCD_READ_REG(pHCDData, USB_EHCD_USBINTR); /* Disable the interrupts by setting all bits to zero in Interrupt Enable register */ USB_EHCD_WRITE_REG(pHCDData, USB_EHCD_USBINTR, 0);#endif /* If any change is detected, signal the event * so that the thread can handle the interrupt */ if (0 != (USB_EHCD_READ_REG(pHCDData, USB_EHCD_USBSTS) & USB_EHCD_USBSTS_INTERRUPT_MASK)) { /* Update the interrupt status value */ uInterruptStatus = USB_EHCD_READ_REG(pHCDData, USB_EHCD_USBSTS) & USB_EHCD_USBSTS_INTERRUPT_MASK; /* Clear the interrupt status */ USB_EHCD_WRITE_REG(pHCDData, USB_EHCD_USBSTS, uInterruptStatus); /* Mask all not enabled interrupts */ uInterruptStatus &= (uInterruptMask & USB_EHCD_USBSTS_INTERRUPT_MASK); /* Proceed if occured intr is enabled */ if (uInterruptStatus) { /* Copy interrupt status to HCD Data strucrture */ pHCDData->uInterruptStatus |= uInterruptStatus; /* Send the message to the high priority thread */ OS_RELEASE_EVENT(pHCDData->InterruptEvent); } }#ifndef USB_EHCD_ENABLE_POLLING /* Enable the EHCI interrupts */ /* Enable the interrupts by writing to us Interrupt \ Enable register*/ USB_EHCD_WRITE_REG(pHCDData, USB_EHCD_USBINTR, uInterruptMask); OS_LOG_MESSAGE_LOW(EHCD,"usbEhcdISR - Exit\n",0,0,0,0);#endif return; }/* End of function usbEhcdISR() *//***************************************************************************** usbEhcdPortChangeHandler - handles the port change interrupt.** This routine handles a port change.** RETURNS: N/A.** ERRNO:* None.** \NOMANUAL*/LOCAL VOID usbEhcdPortChangeHandler ( pUSB_EHCD_DATA pEHCDData ) { /* To hold the index into the ports */ UINT32 uIndex = 0; /* To hold the status change of the hub */ UINT32 uStatusChange = 0; /* To hold the Port Status Change information */ UINT32 uPortSCInfo = 0; /* WindView Instrumentation */ USB_HCD_LOG_EVENT( USB_EHCI_WV_EVENT_HANDLER, "usbEhcdPortChangeHandler() starts", USB_EHCD_WV_FILTER); OS_LOG_MESSAGE_LOW(EHCD,"usbEhcdPortChangeHandler - Entry\n",0,0,0,0); /* Check the validity of the parameter */ if (NULL == pEHCDData) { OS_LOG_MESSAGE_HIGH(EHCD,"usbEhcdPortChangeHandler - Parameter not valid\n",0,0,0,0); return; } /* Assert of the request synchronization event is not valid */ OS_ASSERT(NULL != pEHCDData->RequestSynchEventID); /* * This loop checks whether there is any change * in any of the downstream ports */ for (uIndex = 0; uIndex < pEHCDData->RHData.uNumDownstreamPorts; uIndex++) { /* Copy the data in the Root Hub's buffer */ OS_MEMCPY(&uPortSCInfo, (pEHCDData->RHData.pPortStatus + (USB_EHCD_RH_PORT_STATUS_SIZE *uIndex)), USB_EHCD_RH_PORT_STATUS_SIZE); /* Read the PORTSC contents */ uPortSCInfo |= USB_EHCD_READ_REG(pEHCDData, USB_EHCD_PORTSC(uIndex)); /* Check if there is any change */ if (0 != (uPortSCInfo & (USB_EHCD_PORTSC_OVER_CURRENT_CHANGE_MASK | USB_EHCD_PORTSC_CONNECT_STATUS_CHANGE_MASK | USB_EHCD_PORTSC_PORT_ENABLE_DISABLE_CHANGE_MASK))) { /* Update the status change data */ uStatusChange |= (USB_EHCD_RH_MASK_VALUE << uIndex); } }/* End of for () */ /* If there is a resume detected on the port, which is driven from the * device, update the status change bit */ if ((0 != (uPortSCInfo & USB_EHCD_PORTSC_FORCE_PORT_RESUME_MASK)) && (0 == (uPortSCInfo & USB_EHCD_RH_PORT_SUSPEND_CHANGE))) { /* Update the status change data */ uStatusChange |= (USB_EHCD_RH_MASK_VALUE << uIndex); /* Update the suspend status change bit in * the port status value stored in the Root hub's data structure. */ uPortSCInfo |= USB_EHCD_RH_PORT_SUSPEND_CHANGE; } /* If there is no change return */ if ((0 == uStatusChange) || (NULL == pEHCDData->RHData.pHubInterruptData)) { OS_LOG_MESSAGE_LOW(EHCD,"usbEhcdPortChangeHandler - No change in the hub status \n",0,0,0,0); return; } /* * Call the function to copy the interrupt status to the * request buffer if a request is pending or to the Root hub interrupt * transfer data buffer if a request is not pending */ /* Nothing can be done when the return value is false */ usbEhcdCopyRHInterruptData(pEHCDData, uStatusChange); OS_LOG_MESSAGE_LOW(EHCD,"usbEhcdPortChangeHandler - Exit\n",0,0,0,0); return; }/* End of usbEhcdPortChangeHandler() *//***************************************************************************** usbEhcdProcessTransferCompletion - handles the data transfer interrupt.** This function is used to handle the a data transfer completion* interrupt.** RETURNS: N/A.** ERRNO:* None.** \NOMANUAL*/LOCAL VOID usbEhcdProcessTransferCompletion ( pUSB_EHCD_DATA pEHCDData ) { /* To hold the pointer to the request information */ pUSB_EHCD_REQUEST_INFO pRequestInfo = NULL; /* To hold the pointer to the previous request information */ pUSB_EHCD_REQUEST_INFO pPreRequestInfo = NULL; /* To hold the temporary pointer to the request information */ pUSB_EHCD_REQUEST_INFO pTempRequestInfo = NULL; /* Pointer to the HCDPipe */ pUSB_EHCD_PIPE pHCDPipe = NULL; UINT16 uWvalue =0; UINT8 uHalted = 0; /* WindView Instrumentation */ USB_HCD_LOG_EVENT( USB_EHCI_WV_EVENT_HANDLER, "usbEhcdProcessTransferCompletion() starts", USB_EHCD_WV_FILTER); OS_LOG_MESSAGE_LOW(EHCD,"usbEhcdProcessTransferCompletion - Entry\n",0,0,0,0); /* Check the validity of the parameter */ if (NULL == pEHCDData) { OS_LOG_MESSAGE_HIGH(EHCD,"usbEhcdProcessTransferCompletion - Parameter is not valid\n",0,0,0,0); return; } /* Exclusively access the request list */ OS_WAIT_FOR_EVENT(pEHCDData->RequestSynchEventID,OS_WAIT_INFINITE); /* * This loop searches the list of requests * and identifies the requests which are completed */ for (pRequestInfo = pEHCDData->pRequestQueueHead; (NULL != pRequestInfo);) { /* Assert if the pipe pointer is not valid */ OS_ASSERT(NULL != pRequestInfo->pHCDPipe); /* Assert if the URB pointer is not valid */ OS_ASSERT(NULL != pRequestInfo->pUrb); /* Check if it is a non-isochronous request */ if (USBHST_ISOCHRONOUS_TRANSFER !=
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -