summaryrefslogtreecommitdiff
path: root/EdkModulePkg/Bus/Pci/Uhci/Dxe/uhchlp.c
diff options
context:
space:
mode:
Diffstat (limited to 'EdkModulePkg/Bus/Pci/Uhci/Dxe/uhchlp.c')
-rw-r--r--EdkModulePkg/Bus/Pci/Uhci/Dxe/uhchlp.c4206
1 files changed, 0 insertions, 4206 deletions
diff --git a/EdkModulePkg/Bus/Pci/Uhci/Dxe/uhchlp.c b/EdkModulePkg/Bus/Pci/Uhci/Dxe/uhchlp.c
deleted file mode 100644
index 2abc410c0c..0000000000
--- a/EdkModulePkg/Bus/Pci/Uhci/Dxe/uhchlp.c
+++ /dev/null
@@ -1,4206 +0,0 @@
-/*++
-
-Copyright (c) 2006, Intel Corporation
-All rights reserved. This program and the accompanying materials
-are licensed and made available under the terms and conditions of the BSD License
-which accompanies this distribution. The full text of the license may be found at
-http://opensource.org/licenses/bsd-license.php
-
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-
-Module Name:
-
- UhcHlp.c
-
-Abstract:
-
-
-Revision History
---*/
-
-#include "uhci.h"
-
-STATIC
-EFI_STATUS
-USBReadPortW (
- IN EFI_PCI_IO_PROTOCOL *PciIo,
- IN UINT32 PortOffset,
- IN OUT UINT16 *Data
- )
-/*++
-
-Routine Description:
-
- USBReadPort Word
-
-Arguments:
-
- PciIo - EFI_PCI_IO_PROTOCOL
- PortOffset - Port offset
- Data - Data to reutrn
-
-Returns:
-
- EFI_SUCCESS
-
---*/
-{
- //
- // Perform 16bit Read in PCI IO Space
- //
- return PciIo->Io.Read (
- PciIo,
- EfiPciIoWidthUint16,
- USB_BAR_INDEX,
- (UINT64) PortOffset,
- 1,
- Data
- );
-}
-
-STATIC
-EFI_STATUS
-USBWritePortW (
- IN EFI_PCI_IO_PROTOCOL *PciIo,
- IN UINT32 PortOffset,
- IN UINT16 Data
- )
-/*++
-
-Routine Description:
-
- USB Write Port Word
-
-Arguments:
-
- PciIo - EFI_PCI_IO_PROTOCOL
- PortOffset - Port offset
- Data - Data to write
-
-Returns:
-
- EFI_SUCCESS
-
---*/
-{
- //
- // Perform 16bit Write in PCI IO Space
- //
- return PciIo->Io.Write (
- PciIo,
- EfiPciIoWidthUint16,
- USB_BAR_INDEX,
- (UINT64) PortOffset,
- 1,
- &Data
- );
-}
-
-STATIC
-EFI_STATUS
-USBWritePortDW (
- IN EFI_PCI_IO_PROTOCOL *PciIo,
- IN UINT32 PortOffset,
- IN UINT32 Data
- )
-/*++
-
-Routine Description:
-
- USB Write Port DWord
-
-Arguments:
-
- PciIo - EFI_PCI_IO_PROTOCOL
- PortOffset - Port offset
- Data - Data to write
-
-Returns:
-
- EFI_SUCCESS
-
---*/
-{
- //
- // Perform 32bit Write in PCI IO Space
- //
- return PciIo->Io.Write (
- PciIo,
- EfiPciIoWidthUint32,
- USB_BAR_INDEX,
- (UINT64) PortOffset,
- 1,
- &Data
- );
-}
-//
-// USB register-base helper functions
-//
-EFI_STATUS
-WriteUHCCommandReg (
- IN EFI_PCI_IO_PROTOCOL *PciIo,
- IN UINT32 CmdAddrOffset,
- IN UINT16 UsbCmd
- )
-/*++
-
-Routine Description:
-
- Write UHCI Command Register
-
-Arguments:
-
- PciIo - EFI_PCI_IO_PROTOCOL
- CmdAddrOffset - Command address offset
- UsbCmd - Data to write
-
-Returns:
-
- EFI_SUCCESS
-
---*/
-{
- //
- // Write to UHC's Command Register
- //
- return USBWritePortW (PciIo, CmdAddrOffset, UsbCmd);
-}
-
-EFI_STATUS
-ReadUHCCommandReg (
- IN EFI_PCI_IO_PROTOCOL *PciIo,
- IN UINT32 CmdAddrOffset,
- IN OUT UINT16 *Data
- )
-/*++
-
-Routine Description:
-
- Read UHCI Command Register
-
-Arguments:
-
- PciIo - EFI_PCI_IO_PROTOCOL
- CmdAddrOffset - Command address offset
- Data - Data to return
-
-Returns:
-
- EFI_SUCCESS
-
---*/
-{
- //
- // Read from UHC's Command Register
- //
- return USBReadPortW (PciIo, CmdAddrOffset, Data);
-}
-
-EFI_STATUS
-WriteUHCStatusReg (
- IN EFI_PCI_IO_PROTOCOL *PciIo,
- IN UINT32 StatusAddrOffset,
- IN UINT16 UsbSts
- )
-/*++
-
-Routine Description:
-
- Write UHCI Staus Register
-
-Arguments:
-
- PciIo - EFI_PCI_IO_PROTOCOL
- StatusAddrOffset - Status address offset
- UsbSts - Data to write
-
-Returns:
-
- EFI_SUCCESS
-
---*/
-{
- //
- // Write to UHC's Status Register
- //
- return USBWritePortW (PciIo, StatusAddrOffset, UsbSts);
-}
-
-EFI_STATUS
-ReadUHCStatusReg (
- IN EFI_PCI_IO_PROTOCOL *PciIo,
- IN UINT32 StatusAddrOffset,
- IN OUT UINT16 *Data
- )
-/*++
-
-Routine Description:
-
- Read UHCI Staus Register
-
-Arguments:
-
- PciIo - EFI_PCI_IO_PROTOCOL
- StatusAddrOffset - Status address offset
- UsbSts - Data to return
-
-Returns:
-
- EFI_SUCCESS
-
---*/
-{
- //
- // Read from UHC's Status Register
- //
- return USBReadPortW (PciIo, StatusAddrOffset, Data);
-}
-
-
-EFI_STATUS
-ClearStatusReg (
- IN EFI_PCI_IO_PROTOCOL *PciIo,
- IN UINT32 StatusAddrOffset
- )
-/*++
-
-Routine Description:
-
- Clear the content of UHC's Status Register
-
-Arguments:
-
- PciIo - EFI_PCI_IO_PROTOCOL
- StatusAddrOffset - Status address offset
-
-Returns:
-
- EFI_SUCCESS
-
---*/
-{
-
- return WriteUHCStatusReg (PciIo, StatusAddrOffset, 0x003F);
-}
-
-EFI_STATUS
-ReadUHCFrameNumberReg (
- IN EFI_PCI_IO_PROTOCOL *PciIo,
- IN UINT32 FrameNumAddrOffset,
- IN OUT UINT16 *Data
- )
-/*++
-
-Routine Description:
-
- Read from UHC's Frame Number Register
-
-Arguments:
-
- PciIo - EFI_PCI_IO_PROTOCOL
- FrameNumAddrOffset - Frame number register offset
- Data - Data to return
-Returns:
-
- EFI_SUCCESS
-
---*/
-{
-
- return USBReadPortW (PciIo, FrameNumAddrOffset, Data);
-}
-
-EFI_STATUS
-WriteUHCFrameListBaseReg (
- IN EFI_PCI_IO_PROTOCOL *PciIo,
- IN UINT32 FlBaseAddrOffset,
- IN UINT32 UsbFrameListBaseAddr
- )
-/*++
-
-Routine Description:
-
- Write to UHC's Frame List Base Register
-
-Arguments:
-
- PciIo - EFI_PCI_IO_PROTOCOL
- FlBaseAddrOffset - Frame Base address register
- UsbFrameListBaseAddr - Address to write
-
-Returns:
-
- EFI_SUCCESS
-
---*/
-{
-
- return USBWritePortDW (PciIo, FlBaseAddrOffset, UsbFrameListBaseAddr);
-}
-
-EFI_STATUS
-ReadRootPortReg (
- IN EFI_PCI_IO_PROTOCOL *PciIo,
- IN UINT32 PortAddrOffset,
- IN OUT UINT16 *Data
- )
-/*++
-
-Routine Description:
-
- Read from UHC's Root Port Register
-
-Arguments:
-
- PciIo - EFI_PCI_IO_PROTOCOL
- PortAddrOffset - Port Addrress Offset,
- Data - Data to return
-Returns:
-
- EFI_SUCCESS
-
---*/
-{
-
- return USBReadPortW (PciIo, PortAddrOffset, Data);
-}
-
-EFI_STATUS
-WriteRootPortReg (
- IN EFI_PCI_IO_PROTOCOL *PciIo,
- IN UINT32 PortAddrOffset,
- IN UINT16 ControlBits
- )
-/*++
-
-Routine Description:
-
- Write to UHC's Root Port Register
-
-Arguments:
-
- PciIo - EFI_PCI_IO_PROTOCOL
- PortAddrOffset - Port Addrress Offset,
- ControlBits - Data to write
-Returns:
-
- EFI_SUCCESS
-
---*/
-{
-
- return USBWritePortW (PciIo, PortAddrOffset, ControlBits);
-}
-
-
-
-EFI_STATUS
-WaitForUHCHalt (
- IN EFI_PCI_IO_PROTOCOL *PciIo,
- IN UINT32 StatusRegAddr,
- IN UINTN Timeout
- )
-/*++
-
-Routine Description:
-
- Wait until UHCI halt or timeout
-
-Arguments:
-
- PciIo - EFI_PCI_IO_PROTOCOL
- StatusRegAddr - Status Register Address
- Timeout - Time out value in us
-
-Returns:
-
- EFI_DEVICE_ERROR - Unable to read the status register
- EFI_TIMEOUT - Time out
- EFI_SUCCESS - Success
-
---*/
-{
- UINTN Delay;
- EFI_STATUS Status;
- UINT16 HcStatus;
-
- //
- // Timeout is in us unit
- //
- Delay = (Timeout / 50) + 1;
- do {
- Status = ReadUHCStatusReg (PciIo, StatusRegAddr, &HcStatus);
- if (EFI_ERROR (Status)) {
- return EFI_DEVICE_ERROR;
- }
-
- if ((HcStatus & USBSTS_HCH) == USBSTS_HCH) {
- break;
- }
- //
- // Stall for 50 us
- //
- gBS->Stall (50);
-
- } while (Delay--);
-
- if (Delay == 0) {
- return EFI_TIMEOUT;
- }
-
- return EFI_SUCCESS;
-}
-
-BOOLEAN
-IsStatusOK (
- IN EFI_PCI_IO_PROTOCOL *PciIo,
- IN UINT32 StatusRegAddr
- )
-/*++
-
-Routine Description:
-
- Judge whether the host controller operates well
-
-Arguments:
-
- PciIo - EFI_PCI_IO_PROTOCOL
- StatusRegAddr - Status register address
-
-Returns:
-
- TRUE - Status is good
- FALSE - Status is bad
-
---*/
-{
- EFI_STATUS Status;
- UINT16 HcStatus;
- //
- // Detect whether the interrupt is caused by fatal error.
- // see "UHCI Design Guid".
- //
- Status = ReadUHCStatusReg (PciIo, StatusRegAddr, &HcStatus);
- if (EFI_ERROR (Status)) {
- return FALSE;
- }
-
- if (HcStatus & (USBSTS_HCPE | USBSTS_HSE | USBSTS_HCH)) {
- return FALSE;
- } else {
- return TRUE;
- }
-
-}
-
-
-BOOLEAN
-IsHostSysOrProcessErr (
- IN EFI_PCI_IO_PROTOCOL *PciIo,
- IN UINT32 StatusRegAddr
- )
-/*++
-
-Routine Description:
-
- Judge the status is HostSys,ProcessErr error or good
-
-Arguments:
-
- PciIo - EFI_PCI_IO_PROTOCOL
- StatusRegAddr - Status register address
-
-Returns:
-
- TRUE - Status is good
- FALSE - Status is bad
-
---*/
-{
- EFI_STATUS Status;
- UINT16 HcStatus;
- //
- // Detect whether the interrupt is caused by serious error.
- // see "UHCI Design Guid".
- //
- Status = ReadUHCStatusReg (PciIo, StatusRegAddr, &HcStatus);
- if (EFI_ERROR (Status)) {
- return FALSE;
- }
-
- if (HcStatus & (USBSTS_HSE | USBSTS_HCPE)) {
- return TRUE;
- } else {
- return FALSE;
- }
-}
-
-
-UINT16
-GetCurrentFrameNumber (
- IN EFI_PCI_IO_PROTOCOL *PciIo,
- IN UINT32 FrameNumAddrOffset
- )
-/*++
-
-Routine Description:
-
- Get Current Frame Number
-
-Arguments:
-
- PciIo - EFI_PCI_IO_PROTOCOL
- FrameNumAddrOffset - FrameNum register AddrOffset
-
-Returns:
-
- Frame number
-
---*/
-{
- //
- // Gets value in the USB frame number register.
- //
- UINT16 FrameNumber;
-
- ReadUHCFrameNumberReg (PciIo, FrameNumAddrOffset, &FrameNumber);
-
- return (UINT16) (FrameNumber & 0x03FF);
-}
-
-EFI_STATUS
-SetFrameListBaseAddress (
- IN EFI_PCI_IO_PROTOCOL *PciIo,
- IN UINT32 FlBaseAddrReg,
- IN UINT32 Addr
- )
-/*++
-
-Routine Description:
-
- Set FrameListBase Address
-
-Arguments:
-
- PciIo - EFI_PCI_IO_PROTOCOL
- FlBaseAddrReg - FrameListBase register
- Addr - Address to set
-
-Returns:
-
- EFI_SUCCESS
-
---*/
-{
- //
- // Sets value in the USB Frame List Base Address register.
- //
- return WriteUHCFrameListBaseReg (PciIo, FlBaseAddrReg, (UINT32) (Addr & 0xFFFFF000));
-}
-
-VOID
-EnableMaxPacketSize (
- IN USB_HC_DEV *HcDev
- )
-/*++
-
-Routine Description:
-
- Enable Max Packet Size
-
-Arguments:
-
- HcDev - USB_HC_DEV
-
-Returns:
-
- VOID
-
---*/
-{
- UINT16 CommandContent;
-
- ReadUHCCommandReg (
- HcDev->PciIo,
- (UINT32) (USBCMD),
- &CommandContent
- );
-
- if ((CommandContent & USBCMD_MAXP) != USBCMD_MAXP) {
- CommandContent |= USBCMD_MAXP;
- WriteUHCCommandReg (
- HcDev->PciIo,
- (UINT32) (USBCMD),
- CommandContent
- );
- }
-
- return ;
-}
-
-EFI_STATUS
-CreateFrameList (
- IN USB_HC_DEV *HcDev,
- IN UINT32 FlBaseAddrReg
- )
-/*++
-
-Routine Description:
-
- CreateFrameList
-
-Arguments:
-
- HcDev - USB_HC_DEV
- FlBaseAddrReg - Frame List register
-
-Returns:
-
- EFI_OUT_OF_RESOURCES - Can't allocate memory resources
- EFI_UNSUPPORTED - Map memory fail
- EFI_SUCCESS - Success
-
---*/
-{
- EFI_STATUS Status;
- VOID *CommonBuffer;
- EFI_PHYSICAL_ADDRESS MappedAddress;
- VOID *Mapping;
- UINTN BufferSizeInPages;
- UINTN BufferSizeInBytes;
-
- //
- // The Frame List is a common buffer that will be
- // accessed by both the cpu and the usb bus master
- // at the same time.
- // The Frame List ocupies 4K bytes,
- // and must be aligned on 4-Kbyte boundaries.
- //
- BufferSizeInBytes = 4096;
- BufferSizeInPages = EFI_SIZE_TO_PAGES (BufferSizeInBytes);
- Status = HcDev->PciIo->AllocateBuffer (
- HcDev->PciIo,
- AllocateAnyPages,
- EfiBootServicesData,
- BufferSizeInPages,
- &CommonBuffer,
- 0
- );
- if (EFI_ERROR (Status)) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- Status = HcDev->PciIo->Map (
- HcDev->PciIo,
- EfiPciIoOperationBusMasterCommonBuffer,
- CommonBuffer,
- &BufferSizeInBytes,
- &MappedAddress,
- &Mapping
- );
- if (EFI_ERROR (Status) || (BufferSizeInBytes != 4096)) {
- HcDev->PciIo->FreeBuffer (HcDev->PciIo, BufferSizeInPages, CommonBuffer);
- return EFI_UNSUPPORTED;
- }
-
- HcDev->FrameListEntry = (FRAMELIST_ENTRY *) ((UINTN) MappedAddress);
-
- HcDev->FrameListMapping = Mapping;
-
- InitFrameList (HcDev);
-
- //
- // Tell the Host Controller where the Frame List lies,
- // by set the Frame List Base Address Register.
- //
- SetFrameListBaseAddress (
- HcDev->PciIo,
- FlBaseAddrReg,
- (UINT32) ((UINTN) HcDev->FrameListEntry)
- );
-
- return EFI_SUCCESS;
-}
-
-EFI_STATUS
-FreeFrameListEntry (
- IN USB_HC_DEV *HcDev
- )
-/*++
-
-Routine Description:
-
- Free FrameList buffer
-
-Arguments:
-
- HcDev - USB_HC_DEV
-
-Returns:
-
- EFI_SUCCESS - success
-
---*/
-{
- //
- // Unmap the common buffer for framelist entry,
- // and free the common buffer.
- // Uhci's frame list occupy 4k memory.
- //
- HcDev->PciIo->Unmap (HcDev->PciIo, HcDev->FrameListMapping);
- HcDev->PciIo->FreeBuffer (
- HcDev->PciIo,
- EFI_SIZE_TO_PAGES (4096),
- (VOID *) (HcDev->FrameListEntry)
- );
- return EFI_SUCCESS;
-}
-
-VOID
-InitFrameList (
- IN USB_HC_DEV *HcDev
- )
-/*++
-
-Routine Description:
-
- Initialize FrameList
-
-Arguments:
-
- HcDev - USB_HC_DEV
-
-Returns:
- VOID
-
---*/
-{
- FRAMELIST_ENTRY *FrameListPtr;
- UINTN Index;
-
- //
- // Validate each Frame List Entry
- //
- FrameListPtr = HcDev->FrameListEntry;
- for (Index = 0; Index < 1024; Index++) {
- FrameListPtr->FrameListPtrTerminate = 1;
- FrameListPtr->FrameListPtr = 0;
- FrameListPtr->FrameListPtrQSelect = 0;
- FrameListPtr->FrameListRsvd = 0;
- FrameListPtr++;
- }
-}
-//
-// //////////////////////////////////////////////////////////////
-//
-// QH TD related Helper Functions
-//
-////////////////////////////////////////////////////////////////
-//
-// functions for QH
-//
-STATIC
-EFI_STATUS
-AllocateQHStruct (
- IN USB_HC_DEV *HcDev,
- OUT QH_STRUCT **ppQHStruct
- )
-/*++
-
-Routine Description:
-
- Allocate QH Struct
-
-Arguments:
-
- HcDev - USB_HC_DEV
- ppQHStruct - QH_STRUCT content to return
-Returns:
-
- EFI_SUCCESS
-
---*/
-{
- *ppQHStruct = NULL;
-
- //
- // QH must align on 16 bytes alignment,
- // since the memory allocated by UhciAllocatePool ()
- // is aligned on 32 bytes, it is no need to adjust
- // the allocated memory returned.
- //
- return UhciAllocatePool (HcDev, (UINT8 **) ppQHStruct, sizeof (QH_STRUCT));
-}
-
-
-EFI_STATUS
-CreateQH (
- IN USB_HC_DEV *HcDev,
- OUT QH_STRUCT **pptrQH
- )
-/*++
-
-Routine Description:
-
- CreateQH
-
-Arguments:
-
- HcDev - USB_HC_DEV
- ppQHStruct - QH_STRUCT content to return
-Returns:
-
- EFI_SUCCESS - Success
- EFI_OUT_OF_RESOURCES - Can't allocate memory
---*/
-{
- EFI_STATUS Status;
-
- //
- // allocate align memory for QH_STRUCT
- //
- Status = AllocateQHStruct (HcDev, pptrQH);
- if (EFI_ERROR (Status)) {
- return EFI_OUT_OF_RESOURCES;
- }
- //
- // init each field of the QH_STRUCT
- //
- //
- // Make QH ready
- //
- SetQHHorizontalValidorInvalid (*pptrQH, FALSE);
- SetQHVerticalValidorInvalid (*pptrQH, FALSE);
-
- return EFI_SUCCESS;
-}
-
-VOID
-SetQHHorizontalLinkPtr (
- IN QH_STRUCT *PtrQH,
- IN VOID *ptrNext
- )
-/*++
-
-Routine Description:
-
- Set QH Horizontal Link Pointer
-
-Arguments:
-
- PtrQH - QH_STRUCT
- ptrNext - Data to write
-
-Returns:
-
- VOID
-
---*/
-{
- //
- // Since the QH_STRUCT is aligned on 16-byte boundaries,
- // Only the highest 28bit of the address is valid
- // (take 32bit address as an example).
- //
- PtrQH->QH.QHHorizontalPtr = (UINT32) ((UINTN) ptrNext >> 4);
-}
-
-VOID *
-GetQHHorizontalLinkPtr (
- IN QH_STRUCT *PtrQH
- )
-/*++
-
-Routine Description:
-
- Get QH Horizontal Link Pointer
-
-Arguments:
-
- PtrQH - QH_STRUCT
-
-
-Returns:
-
- Data to return
-
---*/
-{
- //
- // Restore the 28bit address to 32bit address
- // (take 32bit address as an example)
- //
- return (VOID *) ((UINTN) (PtrQH->QH.QHHorizontalPtr << 4));
-}
-
-VOID
-SetQHHorizontalQHorTDSelect (
- IN QH_STRUCT *PtrQH,
- IN BOOLEAN bQH
- )
-/*++
-
-Routine Description:
-
- Set QH Horizontal QH or TD
-
-Arguments:
-
- PtrQH - QH_STRUCT
- bQH - TRUE is QH FALSE is TD
-
-Returns:
- VOID
-
---*/
-{
- //
- // if QH is connected, the specified bit is set,
- // if TD is connected, the specified bit is cleared.
- //
- PtrQH->QH.QHHorizontalQSelect = bQH ? 1 : 0;
-}
-
-
-VOID
-SetQHHorizontalValidorInvalid (
- IN QH_STRUCT *PtrQH,
- IN BOOLEAN bValid
- )
-/*++
-
-Routine Description:
-
- Set QH Horizontal Valid or Invalid
-
-Arguments:
-
- PtrQH - QH_STRUCT
- bValid - TRUE is Valid FALSE is Invalid
-
-Returns:
- VOID
-
---*/
-{
- //
- // Valid means the horizontal link pointer is valid,
- // else, it's invalid.
- //
- PtrQH->QH.QHHorizontalTerminate = bValid ? 0 : 1;
-}
-
-VOID
-SetQHVerticalLinkPtr (
- IN QH_STRUCT *PtrQH,
- IN VOID *ptrNext
- )
-/*++
-
-Routine Description:
-
- Set QH Vertical Link Pointer
-
-Arguments:
-
- PtrQH - QH_STRUCT
- ptrNext - Data to write
-Returns:
-
- VOID
-
---*/
-{
- //
- // Since the QH_STRUCT is aligned on 16-byte boundaries,
- // Only the highest 28bit of the address is valid
- // (take 32bit address as an example).
- //
- PtrQH->QH.QHVerticalPtr = (UINT32) ((UINTN) ptrNext >> 4);
-}
-
-VOID *
-GetQHVerticalLinkPtr (
- IN QH_STRUCT *PtrQH
- )
-/*++
-
-Routine Description:
-
- Get QH Vertical Link Pointer
-
-Arguments:
-
- PtrQH - QH_STRUCT
-
-Returns:
-
- Data to return
-
---*/
-{
- //
- // Restore the 28bit address to 32bit address
- // (take 32bit address as an example)
- //
- return (VOID *) ((UINTN) (PtrQH->QH.QHVerticalPtr << 4));
-}
-
-VOID
-SetQHVerticalQHorTDSelect (
- IN QH_STRUCT *PtrQH,
- IN BOOLEAN bQH
- )
-/*++
-
-Routine Description:
-
- Set QH Vertical QH or TD
-
-Arguments:
-
- PtrQH - QH_STRUCT
- bQH - TRUE is QH FALSE is TD
-
-Returns:
-
- VOID
-
---*/
-{
- //
- // Set the specified bit if the Vertical Link Pointer pointing to a QH,
- // Clear the specified bit if the Vertical Link Pointer pointing to a TD.
- //
- PtrQH->QH.QHVerticalQSelect = bQH ? 1 : 0;
-}
-
-BOOLEAN
-IsQHHorizontalQHSelect (
- IN QH_STRUCT *PtrQH
- )
-/*++
-
-Routine Description:
-
- Is QH Horizontal QH Select
-
-Arguments:
-
- PtrQH - QH_STRUCT
-
-Returns:
-
- TRUE - QH
- FALSE - TD
-
---*/
-{
- //
- // Retrieve the information about whether the Horizontal Link Pointer
- // pointing to a QH or TD.
- //
- return (BOOLEAN) (PtrQH->QH.QHHorizontalQSelect ? TRUE : FALSE);
-}
-
-VOID
-SetQHVerticalValidorInvalid (
- IN QH_STRUCT *PtrQH,
- IN BOOLEAN IsValid
- )
-/*++
-
-Routine Description:
-
- Set QH Vertical Valid or Invalid
-
-Arguments:
-
- PtrQH - QH_STRUCT
- IsValid - TRUE is valid FALSE is invalid
-
-Returns:
-
- VOID
-
---*/
-{
- //
- // If TRUE, indicates the Vertical Link Pointer field is valid,
- // else, the field is invalid.
- //
- PtrQH->QH.QHVerticalTerminate = IsValid ? 0 : 1;
-}
-
-
-BOOLEAN
-GetQHVerticalValidorInvalid (
- IN QH_STRUCT *PtrQH
- )
-/*++
-
-Routine Description:
-
- Get QH Vertical Valid or Invalid
-
-Arguments:
-
- PtrQH - QH_STRUCT
-
-Returns:
-
- TRUE - Valid
- FALSE - Invalid
-
---*/
-{
- //
- // If TRUE, indicates the Vertical Link Pointer field is valid,
- // else, the field is invalid.
- //
- return (BOOLEAN) (!(PtrQH->QH.QHVerticalTerminate));
-}
-
-STATIC
-BOOLEAN
-GetQHHorizontalValidorInvalid (
- IN QH_STRUCT *PtrQH
- )
-/*++
-
-Routine Description:
-
- Get QH Horizontal Valid or Invalid
-
-Arguments:
-
- PtrQH - QH_STRUCT
-
-Returns:
-
- TRUE - Valid
- FALSE - Invalid
-
---*/
-{
- //
- // If TRUE, meaning the Horizontal Link Pointer field is valid,
- // else, the field is invalid.
- //
- return (BOOLEAN) (!(PtrQH->QH.QHHorizontalTerminate));
-}
-//
-// functions for TD
-//
-EFI_STATUS
-AllocateTDStruct (
- IN USB_HC_DEV *HcDev,
- OUT TD_STRUCT **ppTDStruct
- )
-/*++
-
-Routine Description:
-
- Allocate TD Struct
-
-Arguments:
-
- HcDev - USB_HC_DEV
- ppTDStruct - place to store TD_STRUCT pointer
-Returns:
-
- EFI_SUCCESS
-
---*/
-{
- *ppTDStruct = NULL;
-
- //
- // TD must align on 16 bytes alignment,
- // since the memory allocated by UhciAllocatePool ()
- // is aligned on 32 bytes, it is no need to adjust
- // the allocated memory returned.
- //
- return UhciAllocatePool (
- HcDev,
- (UINT8 **) ppTDStruct,
- sizeof (TD_STRUCT)
- );
-}
-
-EFI_STATUS
-CreateTD (
- IN USB_HC_DEV *HcDev,
- OUT TD_STRUCT **pptrTD
- )
-/*++
-
-Routine Description:
-
- Create TD
-
-Arguments:
-
- HcDev - USB_HC_DEV
- pptrTD - TD_STRUCT pointer to store
-
-Returns:
-
- EFI_OUT_OF_RESOURCES - Can't allocate resources
- EFI_SUCCESS - Success
-
---*/
-{
- EFI_STATUS Status;
- //
- // create memory for TD_STRUCT, and align the memory.
- //
- Status = AllocateTDStruct (HcDev, pptrTD);
- if (EFI_ERROR (Status)) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- //
- // Make TD ready.
- //
- SetTDLinkPtrValidorInvalid (*pptrTD, FALSE);
-
-
- return EFI_SUCCESS;
-}
-
-EFI_STATUS
-GenSetupStageTD (
- IN USB_HC_DEV *HcDev,
- IN UINT8 DevAddr,
- IN UINT8 Endpoint,
- IN BOOLEAN bSlow,
- IN UINT8 *pDevReq,
- IN UINT8 RequestLen,
- OUT TD_STRUCT **ppTD
- )
-/*++
-
-Routine Description:
-
- Generate Setup Stage TD
-
-Arguments:
-
- HcDev - USB_HC_DEV
- DevAddr - Device address
- Endpoint - Endpoint number
- bSlow - Full speed or low speed
- pDevReq - Device request
- RequestLen - Request length
- ppTD - TD_STRUCT to return
-Returns:
-
- EFI_OUT_OF_RESOURCES - Can't allocate memory
- EFI_SUCCESS - Success
-
---*/
-{
- EFI_STATUS Status;
- TD_STRUCT *pTDStruct;
-
- Status = CreateTD (HcDev, &pTDStruct);
- if (EFI_ERROR (Status)) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- SetTDLinkPtr (pTDStruct, NULL);
-
- //
- // Depth first fashion
- //
- SetTDLinkPtrDepthorBreadth (pTDStruct, TRUE);
-
- //
- // initialize as the last TD in the QH context,
- // this field will be updated in the TD linkage process.
- //
- SetTDLinkPtrValidorInvalid (pTDStruct, FALSE);
-
- //
- // Disable Short Packet Detection by default
- //
- EnableorDisableTDShortPacket (pTDStruct, FALSE);
-
- //
- // Max error counter is 3, retry 3 times when error encountered.
- //
- SetTDControlErrorCounter (pTDStruct, 3);
-
- //
- // set device speed attribute
- // (TRUE - Slow Device; FALSE - Full Speed Device)
- //
- SetTDLoworFullSpeedDevice (pTDStruct, bSlow);
-
- //
- // Non isochronous transfer TD
- //
- SetTDControlIsochronousorNot (pTDStruct, FALSE);
-
- //
- // Interrupt On Complete bit be set to zero,
- // Disable IOC interrupt.
- //
- SetorClearTDControlIOC (pTDStruct, FALSE);
-
- //
- // Set TD Active bit
- //
- SetTDStatusActiveorInactive (pTDStruct, TRUE);
-
- SetTDTokenMaxLength (pTDStruct, RequestLen);
-
- SetTDTokenDataToggle0 (pTDStruct);
-
- SetTDTokenEndPoint (pTDStruct, Endpoint);
-
- SetTDTokenDeviceAddress (pTDStruct, DevAddr);
-
- SetTDTokenPacketID (pTDStruct, SETUP_PACKET_ID);
-
- pTDStruct->pTDBuffer = (UINT8 *) pDevReq;
- pTDStruct->TDBufferLength = RequestLen;
- SetTDDataBuffer (pTDStruct);
-
- *ppTD = pTDStruct;
-
- return EFI_SUCCESS;
-}
-
-EFI_STATUS
-GenDataTD (
- IN USB_HC_DEV *HcDev,
- IN UINT8 DevAddr,
- IN UINT8 Endpoint,
- IN UINT8 *pData,
- IN UINT8 Len,
- IN UINT8 PktID,
- IN UINT8 Toggle,
- IN BOOLEAN bSlow,
- OUT TD_STRUCT **ppTD
- )
-/*++
-
-Routine Description:
-
- Generate Data Stage TD
-
-Arguments:
-
- HcDev - USB_HC_DEV
- DevAddr - Device address
- Endpoint - Endpoint number
- pData - Data buffer
- Len - Data length
- PktID - Packet ID
- Toggle - Data toggle value
- bSlow - Full speed or low speed
- ppTD - TD_STRUCT to return
-Returns:
-
- EFI_OUT_OF_RESOURCES - Can't allocate memory
- EFI_SUCCESS - Success
-
---*/
-{
- TD_STRUCT *pTDStruct;
- EFI_STATUS Status;
-
- Status = CreateTD (HcDev, &pTDStruct);
- if (EFI_ERROR (Status)) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- SetTDLinkPtr (pTDStruct, NULL);
-
- //
- // Depth first fashion
- //
- SetTDLinkPtrDepthorBreadth (pTDStruct, TRUE);
-
- //
- // Link pointer pointing to TD struct
- //
- SetTDLinkPtrQHorTDSelect (pTDStruct, FALSE);
-
- //
- // initialize as the last TD in the QH context,
- // this field will be updated in the TD linkage process.
- //
- SetTDLinkPtrValidorInvalid (pTDStruct, FALSE);
-
- //
- // Disable short packet detect
- //
- EnableorDisableTDShortPacket (pTDStruct, FALSE);
- //
- // Max error counter is 3
- //
- SetTDControlErrorCounter (pTDStruct, 3);
-
- //
- // set device speed attribute
- // (TRUE - Slow Device; FALSE - Full Speed Device)
- //
- SetTDLoworFullSpeedDevice (pTDStruct, bSlow);
-
- //
- // Non isochronous transfer TD
- //
- SetTDControlIsochronousorNot (pTDStruct, FALSE);
-
- //
- // Disable Interrupt On Complete
- // Disable IOC interrupt.
- //
- SetorClearTDControlIOC (pTDStruct, FALSE);
-
- //
- // Set Active bit
- //
- SetTDStatusActiveorInactive (pTDStruct, TRUE);
-
- SetTDTokenMaxLength (pTDStruct, Len);
-
- if (Toggle) {
- SetTDTokenDataToggle1 (pTDStruct);
- } else {
- SetTDTokenDataToggle0 (pTDStruct);
- }
-
- SetTDTokenEndPoint (pTDStruct, Endpoint);
-
- SetTDTokenDeviceAddress (pTDStruct, DevAddr);
-
- SetTDTokenPacketID (pTDStruct, PktID);
-
- pTDStruct->pTDBuffer = (UINT8 *) pData;
- pTDStruct->TDBufferLength = Len;
- SetTDDataBuffer (pTDStruct);
- *ppTD = pTDStruct;
-
- return EFI_SUCCESS;
-}
-
-
-EFI_STATUS
-CreateStatusTD (
- IN USB_HC_DEV *HcDev,
- IN UINT8 DevAddr,
- IN UINT8 Endpoint,
- IN UINT8 PktID,
- IN BOOLEAN bSlow,
- OUT TD_STRUCT **ppTD
- )
-/*++
-
-Routine Description:
-
- Generate Status Stage TD
-
-Arguments:
-
- HcDev - USB_HC_DEV
- DevAddr - Device address
- Endpoint - Endpoint number
- PktID - Packet ID
- bSlow - Full speed or low speed
- ppTD - TD_STRUCT to return
-Returns:
-
- EFI_OUT_OF_RESOURCES - Can't allocate memory
- EFI_SUCCESS - Success
-
---*/
-{
- TD_STRUCT *ptrTDStruct;
- EFI_STATUS Status;
-
- Status = CreateTD (HcDev, &ptrTDStruct);
- if (EFI_ERROR (Status)) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- SetTDLinkPtr (ptrTDStruct, NULL);
-
- //
- // Depth first fashion
- //
- SetTDLinkPtrDepthorBreadth (ptrTDStruct, TRUE);
-
- //
- // initialize as the last TD in the QH context,
- // this field will be updated in the TD linkage process.
- //
- SetTDLinkPtrValidorInvalid (ptrTDStruct, FALSE);
-
- //
- // Disable short packet detect
- //
- EnableorDisableTDShortPacket (ptrTDStruct, FALSE);
-
- //
- // Max error counter is 3
- //
- SetTDControlErrorCounter (ptrTDStruct, 3);
-
- //
- // set device speed attribute
- // (TRUE - Slow Device; FALSE - Full Speed Device)
- //
- SetTDLoworFullSpeedDevice (ptrTDStruct, bSlow);
-
- //
- // Non isochronous transfer TD
- //
- SetTDControlIsochronousorNot (ptrTDStruct, FALSE);
-
- //
- // Disable Interrupt On Complete
- // Disable IOC interrupt.
- //
- SetorClearTDControlIOC (ptrTDStruct, FALSE);
-
- //
- // Set TD Active bit
- //
- SetTDStatusActiveorInactive (ptrTDStruct, TRUE);
-
- SetTDTokenMaxLength (ptrTDStruct, 0);
-
- SetTDTokenDataToggle1 (ptrTDStruct);
-
- SetTDTokenEndPoint (ptrTDStruct, Endpoint);
-
- SetTDTokenDeviceAddress (ptrTDStruct, DevAddr);
-
- SetTDTokenPacketID (ptrTDStruct, PktID);
-
- ptrTDStruct->pTDBuffer = NULL;
- ptrTDStruct->TDBufferLength = 0;
- SetTDDataBuffer (ptrTDStruct);
-
- *ppTD = ptrTDStruct;
-
- return EFI_SUCCESS;
-}
-
-
-VOID
-SetTDLinkPtrValidorInvalid (
- IN TD_STRUCT *ptrTDStruct,
- IN BOOLEAN bValid
- )
-/*++
-
-Routine Description:
-
- Set TD Link Pointer Valid or Invalid
-
-Arguments:
-
- ptrTDStruct - TD_STRUCT
- bValid - TRUE is valid FALSE is invalid
-
-Returns:
-
- VOID
-
---*/
-{
- //
- // Valid means the link pointer is valid,
- // else, it's invalid.
- //
- ptrTDStruct->TDData.TDLinkPtrTerminate = (bValid ? 0 : 1);
-}
-
-VOID
-SetTDLinkPtrQHorTDSelect (
- IN TD_STRUCT *ptrTDStruct,
- IN BOOLEAN bQH
- )
-/*++
-
-Routine Description:
-
- Set TD Link Pointer QH or TD Select
-
-Arguments:
-
- ptrTDStruct - TD_STRUCT
- bQH - TRUE is QH FALSE is TD
-
-Returns:
-
- VOID
-
---*/
-{
- //
- // Indicate whether the Link Pointer pointing to a QH or TD
- //
- ptrTDStruct->TDData.TDLinkPtrQSelect = (bQH ? 1 : 0);
-}
-
-VOID
-SetTDLinkPtrDepthorBreadth (
- IN TD_STRUCT *ptrTDStruct,
- IN BOOLEAN bDepth
- )
-/*++
-
-Routine Description:
-
- Set TD Link Pointer depth or bread priority
-
-Arguments:
-
- ptrTDStruct - TD_STRUCT
- bDepth - TRUE is Depth FALSE is Breadth
-
-Returns:
-
- VOID
-
---*/
-{
- //
- // If TRUE, indicating the host controller should process in depth first
- // fashion,
- // else, the host controller should process in breadth first fashion
- //
- ptrTDStruct->TDData.TDLinkPtrDepthSelect = (bDepth ? 1 : 0);
-}
-
-VOID
-SetTDLinkPtr (
- IN TD_STRUCT *ptrTDStruct,
- IN VOID *ptrNext
- )
-/*++
-
-Routine Description:
-
- Set TD Link Pointer
-
-Arguments:
-
- ptrTDStruct - TD_STRUCT
- ptrNext - Pointer to set
-
-Returns:
-
- VOID
-
---*/
-{
- //
- // Set TD Link Pointer. Since QH,TD align on 16-byte boundaries,
- // only the highest 28 bits are valid. (if take 32bit address as an example)
- //
- ptrTDStruct->TDData.TDLinkPtr = (UINT32) ((UINTN) ptrNext >> 4);
-}
-
-VOID *
-GetTDLinkPtr (
- IN TD_STRUCT *ptrTDStruct
- )
-/*++
-
-Routine Description:
-
- Get TD Link Pointer
-
-Arguments:
-
- ptrTDStruct - TD_STRUCT
-
-Returns:
-
- Pointer to get
-
---*/
-{
- //
- // Get TD Link Pointer. Restore it back to 32bit
- // (if take 32bit address as an example)
- //
- return (VOID *) ((UINTN) (ptrTDStruct->TDData.TDLinkPtr << 4));
-}
-
-STATIC
-BOOLEAN
-IsTDLinkPtrQHOrTD (
- IN TD_STRUCT *ptrTDStruct
- )
-/*++
-
-Routine Description:
-
- Is TD Link Pointer is QH Or TD
-
-Arguments:
-
- ptrTDStruct - TODO: add argument description
-
-Returns:
-
- TRUE - QH
- FALSE - TD
-
---*/
-{
- //
- // Get the information about whether the Link Pointer field pointing to
- // a QH or a TD.
- //
- return (BOOLEAN) (ptrTDStruct->TDData.TDLinkPtrQSelect);
-}
-
-VOID
-EnableorDisableTDShortPacket (
- IN TD_STRUCT *ptrTDStruct,
- IN BOOLEAN bEnable
- )
-/*++
-
-Routine Description:
-
- Enable or Disable TD ShortPacket
-
-Arguments:
-
- ptrTDStruct - TD_STRUCT
- bEnable - TRUE is Enanble FALSE is Disable
-
-Returns:
-
- VOID
-
---*/
-{
- //
- // TRUE means enable short packet detection mechanism.
- //
- ptrTDStruct->TDData.TDStatusSPD = (bEnable ? 1 : 0);
-}
-
-VOID
-SetTDControlErrorCounter (
- IN TD_STRUCT *ptrTDStruct,
- IN UINT8 nMaxErrors
- )
-/*++
-
-Routine Description:
-
- Set TD Control ErrorCounter
-
-Arguments:
-
- ptrTDStruct - TD_STRUCT
- nMaxErrors - Error counter number
-
-Returns:
-
- VOID
-
---*/
-{
- //
- // valid value of nMaxErrors is 0,1,2,3
- //
- if (nMaxErrors > 3) {
- nMaxErrors = 3;
- }
-
- ptrTDStruct->TDData.TDStatusErr = nMaxErrors;
-}
-
-
-VOID
-SetTDLoworFullSpeedDevice (
- IN TD_STRUCT *ptrTDStruct,
- IN BOOLEAN bLowSpeedDevice
- )
-{
- //
- // TRUE means the TD is targeting at a Low-speed device
- //
- ptrTDStruct->TDData.TDStatusLS = (bLowSpeedDevice ? 1 : 0);
-}
-
-VOID
-SetTDControlIsochronousorNot (
- IN TD_STRUCT *ptrTDStruct,
- IN BOOLEAN IsIsochronous
- )
-{
- //
- // TRUE means the TD belongs to Isochronous transfer type.
- //
- ptrTDStruct->TDData.TDStatusIOS = (IsIsochronous ? 1 : 0);
-}
-
-VOID
-SetorClearTDControlIOC (
- IN TD_STRUCT *ptrTDStruct,
- IN BOOLEAN IsSet
- )
-{
- //
- // If this bit is set, it indicates that the host controller should issue
- // an interrupt on completion of the frame in which this TD is executed.
- //
- ptrTDStruct->TDData.TDStatusIOC = IsSet ? 1 : 0;
-}
-
-VOID
-SetTDStatusActiveorInactive (
- IN TD_STRUCT *ptrTDStruct,
- IN BOOLEAN IsActive
- )
-{
- //
- // If this bit is set, it indicates that the TD is active and can be
- // executed.
- //
- if (IsActive) {
- ptrTDStruct->TDData.TDStatus |= 0x80;
- } else {
- ptrTDStruct->TDData.TDStatus &= 0x7F;
- }
-}
-
-UINT16
-SetTDTokenMaxLength (
- IN TD_STRUCT *ptrTDStruct,
- IN UINT16 MaximumLength
- )
-{
- //
- // Specifies the maximum number of data bytes allowed for the transfer.
- // the legal value extent is 0 ~ 0x500.
- //
- if (MaximumLength > 0x500) {
- MaximumLength = 0x500;
- }
- ptrTDStruct->TDData.TDTokenMaxLen = MaximumLength - 1;
-
- return MaximumLength;
-}
-
-VOID
-SetTDTokenDataToggle1 (
- IN TD_STRUCT *ptrTDStruct
- )
-{
- //
- // Set the data toggle bit to DATA1
- //
- ptrTDStruct->TDData.TDTokenDataToggle = 1;
-}
-
-VOID
-SetTDTokenDataToggle0 (
- IN TD_STRUCT *ptrTDStruct
- )
-{
- //
- // Set the data toggle bit to DATA0
- //
- ptrTDStruct->TDData.TDTokenDataToggle = 0;
-}
-
-UINT8
-GetTDTokenDataToggle (
- IN TD_STRUCT *ptrTDStruct
- )
-{
- //
- // Get the data toggle value.
- //
- return (UINT8) (ptrTDStruct->TDData.TDTokenDataToggle);
-}
-
-VOID
-SetTDTokenEndPoint (
- IN TD_STRUCT *ptrTDStruct,
- IN UINTN EndPoint
- )
-{
- //
- // Set EndPoint Number the TD is targeting at.
- //
- ptrTDStruct->TDData.TDTokenEndPt = (UINT8) EndPoint;
-}
-
-VOID
-SetTDTokenDeviceAddress (
- IN TD_STRUCT *ptrTDStruct,
- IN UINTN DeviceAddress
- )
-{
- //
- // Set Device Address the TD is targeting at.
- //
- ptrTDStruct->TDData.TDTokenDevAddr = (UINT8) DeviceAddress;
-}
-
-VOID
-SetTDTokenPacketID (
- IN TD_STRUCT *ptrTDStruct,
- IN UINT8 PID
- )
-{
- //
- // Set the Packet Identification to be used for this transaction.
- //
- ptrTDStruct->TDData.TDTokenPID = PID;
-}
-
-VOID
-SetTDDataBuffer (
- IN TD_STRUCT *ptrTDStruct
- )
-{
- //
- // Set the beginning address of the data buffer that will be used
- // during the transaction.
- //
- ptrTDStruct->TDData.TDBufferPtr = (UINT32) ((UINTN) (ptrTDStruct->pTDBuffer));
-}
-
-BOOLEAN
-IsTDStatusActive (
- IN TD_STRUCT *ptrTDStruct
- )
-{
- UINT8 TDStatus;
-
- //
- // Detect whether the TD is active.
- //
- TDStatus = (UINT8) (ptrTDStruct->TDData.TDStatus);
- return (BOOLEAN) (TDStatus & 0x80);
-}
-
-BOOLEAN
-IsTDStatusStalled (
- IN TD_STRUCT *ptrTDStruct
- )
-{
- UINT8 TDStatus;
-
- //
- // Detect whether the device/endpoint addressed by this TD is stalled.
- //
- TDStatus = (UINT8) (ptrTDStruct->TDData.TDStatus);
- return (BOOLEAN) (TDStatus & 0x40);
-}
-
-BOOLEAN
-IsTDStatusBufferError (
- IN TD_STRUCT *ptrTDStruct
- )
-{
- UINT8 TDStatus;
- //
- // Detect whether Data Buffer Error is happened.
- //
- TDStatus = (UINT8) (ptrTDStruct->TDData.TDStatus);
- return (BOOLEAN) (TDStatus & 0x20);
-}
-
-BOOLEAN
-IsTDStatusBabbleError (
- IN TD_STRUCT *ptrTDStruct
- )
-{
- UINT8 TDStatus;
-
- //
- // Detect whether Babble Error is happened.
- //
- TDStatus = (UINT8) (ptrTDStruct->TDData.TDStatus);
- return (BOOLEAN) (TDStatus & 0x10);
-}
-
-BOOLEAN
-IsTDStatusNAKReceived (
- IN TD_STRUCT *ptrTDStruct
- )
-{
- UINT8 TDStatus;
-
- //
- // Detect whether NAK is received.
- //
- TDStatus = (UINT8) (ptrTDStruct->TDData.TDStatus);
- return (BOOLEAN) (TDStatus & 0x08);
-}
-
-BOOLEAN
-IsTDStatusCRCTimeOutError (
- IN TD_STRUCT *ptrTDStruct
- )
-{
- UINT8 TDStatus;
-
- //
- // Detect whether CRC/Time Out Error is encountered.
- //
- TDStatus = (UINT8) (ptrTDStruct->TDData.TDStatus);
- return (BOOLEAN) (TDStatus & 0x04);
-}
-
-BOOLEAN
-IsTDStatusBitStuffError (
- IN TD_STRUCT *ptrTDStruct
- )
-{
- UINT8 TDStatus;
-
- //
- // Detect whether Bitstuff Error is received.
- //
- TDStatus = (UINT8) (ptrTDStruct->TDData.TDStatus);
- return (BOOLEAN) (TDStatus & 0x02);
-}
-
-UINT16
-GetTDStatusActualLength (
- IN TD_STRUCT *ptrTDStruct
- )
-{
- //
- // Retrieve the actual number of bytes that were tansferred.
- // the value is encoded as n-1. so return the decoded value.
- //
- return (UINT16) ((ptrTDStruct->TDData.TDStatusActualLength) + 1);
-}
-
-UINT16
-GetTDTokenMaxLength (
- IN TD_STRUCT *ptrTDStruct
- )
-{
- //
- // Retrieve the maximum number of data bytes allowed for the trnasfer.
- //
- return (UINT16) ((ptrTDStruct->TDData.TDTokenMaxLen) + 1);
-}
-
-UINT8
-GetTDTokenEndPoint (
- IN TD_STRUCT *ptrTDStruct
- )
-{
- //
- // Retrieve the endpoint number the transaction is targeting at.
- //
- return (UINT8) (ptrTDStruct->TDData.TDTokenEndPt);
-}
-
-UINT8
-GetTDTokenDeviceAddress (
- IN TD_STRUCT *ptrTDStruct
- )
-{
- //
- // Retrieve the device address the transaction is targeting at.
- //
- return (UINT8) (ptrTDStruct->TDData.TDTokenDevAddr);
-}
-
-UINT8
-GetTDTokenPacketID (
- IN TD_STRUCT *ptrTDStruct
- )
-{
- //
- // Retrieve the Packet Identification information.
- //
- return (UINT8) (ptrTDStruct->TDData.TDTokenPID);
-}
-
-UINT8 *
-GetTDDataBuffer (
- IN TD_STRUCT *ptrTDStruct
- )
-{
- //
- // Retrieve the beginning address of the data buffer
- // that involved in this transaction.
- //
- return ptrTDStruct->pTDBuffer;
-}
-
-BOOLEAN
-GetTDLinkPtrValidorInvalid (
- IN TD_STRUCT *ptrTDStruct
- )
-{
- //
- // Retrieve the information of whether the Link Pointer field
- // is valid or not.
- //
- if (ptrTDStruct->TDData.TDLinkPtrTerminate) {
- return FALSE;
- } else {
- return TRUE;
- }
-
-}
-
-UINTN
-CountTDsNumber (
- IN TD_STRUCT *PtrFirstTD
- )
-{
- UINTN Number;
- TD_STRUCT *ptr;
- //
- // Count the queued TDs number.
- //
- Number = 0;
- ptr = PtrFirstTD;
- while (ptr) {
- ptr = (TD_STRUCT *) ptr->ptrNextTD;
- Number++;
- }
-
- return Number;
-}
-
-
-
-VOID
-LinkTDToQH (
- IN QH_STRUCT *PtrQH,
- IN TD_STRUCT *PtrTD
- )
-/*++
-
-Routine Description:
-
- Link TD To QH
-
-Arguments:
-
- PtrQH - QH_STRUCT
- PtrTD - TD_STRUCT
-Returns:
-
- VOID
-
---*/
-{
- if (PtrQH == NULL || PtrTD == NULL) {
- return ;
- }
- //
- // Validate QH Vertical Ptr field
- //
- SetQHVerticalValidorInvalid (PtrQH, TRUE);
-
- //
- // Vertical Ptr pointing to TD structure
- //
- SetQHVerticalQHorTDSelect (PtrQH, FALSE);
-
- SetQHVerticalLinkPtr (PtrQH, (VOID *) PtrTD);
-
- PtrQH->ptrDown = (VOID *) PtrTD;
-}
-
-VOID
-LinkTDToTD (
- IN TD_STRUCT *ptrPreTD,
- IN TD_STRUCT *PtrTD
- )
-/*++
-
-Routine Description:
-
- Link TD To TD
-
-Arguments:
-
- ptrPreTD - Previous TD_STRUCT to be linked
- PtrTD - TD_STRUCT to link
-Returns:
-
- VOID
-
---*/
-{
- if (ptrPreTD == NULL || PtrTD == NULL) {
- return ;
- }
- //
- // Depth first fashion
- //
- SetTDLinkPtrDepthorBreadth (ptrPreTD, TRUE);
-
- //
- // Link pointer pointing to TD struct
- //
- SetTDLinkPtrQHorTDSelect (ptrPreTD, FALSE);
-
- //
- // Validate the link pointer valid bit
- //
- SetTDLinkPtrValidorInvalid (ptrPreTD, TRUE);
-
- SetTDLinkPtr (ptrPreTD, PtrTD);
-
- ptrPreTD->ptrNextTD = (VOID *) PtrTD;
-}
-//
-// Transfer Schedule related Helper Functions
-//
-VOID
-SetorClearCurFrameListTerminate (
- IN FRAMELIST_ENTRY *pCurEntry,
- IN BOOLEAN IsSet
- )
-{
- //
- // If TRUE, empty the frame. If FALSE, indicate the Pointer field is valid.
- //
- pCurEntry->FrameListPtrTerminate = (IsSet ? 1 : 0);
-}
-
-VOID
-SetCurFrameListQHorTD (
- IN FRAMELIST_ENTRY *pCurEntry,
- IN BOOLEAN IsQH
- )
-{
- //
- // This bit indicates to the hardware whether the item referenced by the
- // link pointer is a TD or a QH.
- //
- pCurEntry->FrameListPtrQSelect = (IsQH ? 1 : 0);
-}
-
-STATIC
-BOOLEAN
-IsCurFrameListQHorTD (
- IN FRAMELIST_ENTRY *pCurEntry
- )
-{
- //
- // TRUE is QH
- // FALSE is TD
- //
- return (BOOLEAN) (pCurEntry->FrameListPtrQSelect);
-}
-
-BOOLEAN
-GetCurFrameListTerminate (
- IN FRAMELIST_ENTRY *pCurEntry
- )
-{
- //
- // TRUE means the frame is empty,
- // FALSE means the link pointer field is valid.
- //
- return (BOOLEAN) (pCurEntry->FrameListPtrTerminate);
-}
-
-VOID
-SetCurFrameListPointer (
- IN FRAMELIST_ENTRY *pCurEntry,
- IN UINT8 *ptr
- )
-{
- //
- // Set the pointer field of the frame.
- //
- pCurEntry->FrameListPtr = (UINT32) ((UINTN) ptr >> 4);
-}
-
-VOID *
-GetCurFrameListPointer (
- IN FRAMELIST_ENTRY *pCurEntry
- )
-{
- //
- // Get the link pointer of the frame.
- //
- return (VOID *) ((UINTN) (pCurEntry->FrameListPtr << 4));
-
-}
-
-VOID
-LinkQHToFrameList (
- IN FRAMELIST_ENTRY *pEntry,
- IN UINT16 FrameListIndex,
- IN QH_STRUCT *PtrQH
- )
-/*++
-
-Routine Description:
-
- Link QH To Frame List
-
-Arguments:
-
- pEntry - FRAMELIST_ENTRY
- FrameListIndex - Frame List Index
- PtrQH - QH to link
-Returns:
-
- VOID
-
---*/
-{
- FRAMELIST_ENTRY *pCurFrame;
- QH_STRUCT *TempQH;
- QH_STRUCT *NextTempQH;
- TD_STRUCT *TempTD;
- BOOLEAN LINK;
-
- //
- // Get frame list entry that the link process will begin from.
- //
- pCurFrame = pEntry + FrameListIndex;
-
- //
- // if current frame is empty
- // then link the specified QH directly to the Frame List.
- //
- if (GetCurFrameListTerminate (pCurFrame)) {
-
- //
- // Link new QH to the frame list entry.
- //
- SetCurFrameListQHorTD (pCurFrame, TRUE);
-
- SetCurFrameListPointer (pCurFrame, (UINT8 *) PtrQH);
-
- //
- // clear T bit in the Frame List, indicating that the frame list entry
- // is no longer empty.
- //
- SetorClearCurFrameListTerminate (pCurFrame, FALSE);
-
- return ;
-
- } else {
- //
- // current frame list has link pointer
- //
- if (!IsCurFrameListQHorTD (pCurFrame)) {
- //
- // a TD is linked to the framelist entry
- //
- TempTD = (TD_STRUCT *) GetCurFrameListPointer (pCurFrame);
-
- while (GetTDLinkPtrValidorInvalid (TempTD)) {
-
- if (IsTDLinkPtrQHOrTD (TempTD)) {
- //
- // QH linked next to the TD
- //
- break;
- }
-
- TempTD = (TD_STRUCT *) GetTDLinkPtr (TempTD);
- }
-
- //
- // either no ptr linked next to the TD or QH is linked next to the TD
- //
- if (!GetTDLinkPtrValidorInvalid (TempTD)) {
-
- //
- // no ptr linked next to the TD
- //
- TempTD->ptrNextQH = PtrQH;
- SetTDLinkPtrQHorTDSelect (TempTD, TRUE);
- SetTDLinkPtr (TempTD, PtrQH);
- SetTDLinkPtrValidorInvalid (TempTD, TRUE);
- return ;
-
- } else {
- //
- // QH is linked next to the TD
- //
- TempQH = (QH_STRUCT *) GetTDLinkPtr (TempTD);
- }
- } else {
- //
- // a QH is linked to the framelist entry
- //
- TempQH = (QH_STRUCT *) GetCurFrameListPointer (pCurFrame);
- }
-
- //
- // Set up Flag
- //
- LINK = TRUE;
-
- //
- // Avoid the same qh repeated linking in one frame entry
- //
- if (TempQH == PtrQH) {
- LINK = FALSE;
- return ;
- }
- //
- // if current QH has next QH connected
- //
- while (GetQHHorizontalValidorInvalid (TempQH)) {
- //
- // Get next QH pointer
- //
- NextTempQH = (QH_STRUCT *) GetQHHorizontalLinkPtr (TempQH);
-
- //
- // Bulk transfer qh may be self-linked,
- // so, the code below is to aVOID dead-loop when meeting self-linked qh
- //
- if (NextTempQH == TempQH) {
- LINK = FALSE;
- break;
- }
-
- TempQH = NextTempQH;
-
- //
- // Avoid the same qh repeated linking in one frame entry
- //
- if (TempQH == PtrQH) {
- LINK = FALSE;
- }
- }
-
- if (LINK) {
- TempQH->ptrNext = PtrQH;
- SetQHHorizontalQHorTDSelect (TempQH, TRUE);
- SetQHHorizontalLinkPtr (TempQH, PtrQH);
- SetQHHorizontalValidorInvalid (TempQH, TRUE);
- }
-
- return ;
- }
-}
-
-EFI_STATUS
-ExecuteControlTransfer (
- IN USB_HC_DEV *HcDev,
- IN TD_STRUCT *PtrTD,
- IN UINT32 wIndex,
- OUT UINTN *ActualLen,
- IN UINTN TimeOut,
- OUT UINT32 *TransferResult
- )
-/*++
-
-Routine Description:
-
- Execute Control Transfer
-
-Arguments:
-
- HcDev - USB_HC_DEV
- PtrTD - TD_STRUCT
- wIndex - No use
- ActualLen - Actual transfered Len
- TimeOut - TimeOut value in milliseconds
- TransferResult - Transfer result
-Returns:
-
- EFI_SUCCESS - Sucess
- EFI_DEVICE_ERROR - Error
-
-
---*/
-{
- UINTN ErrTDPos;
- UINTN Delay;
- UINTN RequiredLen;
- BOOLEAN TransferFinished;
-
- ErrTDPos = 0;
- *TransferResult = EFI_USB_NOERROR;
- RequiredLen = *ActualLen;
- *ActualLen = 0;
-
- Delay = (TimeOut * STALL_1_MILLI_SECOND / 50) + 1;
-
- do {
- TransferFinished = CheckTDsResults (
- PtrTD,
- RequiredLen,
- TransferResult,
- &ErrTDPos,
- ActualLen
- );
-
- if (TransferFinished) {
- break;
- }
-
- //
- // TD is inactive, which means the control transfer is end.
- //
- if ((*TransferResult & EFI_USB_ERR_NOTEXECUTE) != EFI_USB_ERR_NOTEXECUTE) {
- break;
- }
-
- gBS->Stall (50);
-
- } while (Delay--);
-
- if (*TransferResult != EFI_USB_NOERROR) {
- return EFI_DEVICE_ERROR;
- }
-
- return EFI_SUCCESS;
-}
-
-EFI_STATUS
-ExecBulkorSyncInterruptTransfer (
- IN USB_HC_DEV *HcDev,
- IN TD_STRUCT *PtrTD,
- IN UINT32 wIndex,
- OUT UINTN *ActualLen,
- OUT UINT8 *DataToggle,
- IN UINTN TimeOut,
- OUT UINT32 *TransferResult
- )
-/*++
-
-Routine Description:
-
- Execute Bulk or SyncInterrupt Transfer
-
-Arguments:
-
- HcDev - USB_HC_DEV
- PtrTD - TD_STRUCT
- wIndex - No use
- ActualLen - Actual transfered Len
- DataToggle - Data Toggle
- TimeOut - TimeOut value in milliseconds
- TransferResult - Transfer result
-Returns:
-
- EFI_SUCCESS - Sucess
- EFI_DEVICE_ERROR - Error
---*/
-{
- UINTN ErrTDPos;
- UINTN ScrollNum;
- UINTN Delay;
- UINTN RequiredLen;
- BOOLEAN TransferFinished;
-
- ErrTDPos = 0;
- *TransferResult = EFI_USB_NOERROR;
- RequiredLen = *ActualLen;
- *ActualLen = 0;
-
- Delay = (TimeOut * STALL_1_MILLI_SECOND / 50) + 1;
-
- do {
-
- TransferFinished = CheckTDsResults (
- PtrTD,
- RequiredLen,
- TransferResult,
- &ErrTDPos,
- ActualLen
- );
-
- if (TransferFinished) {
- break;
- }
-
- //
- // TD is inactive, which means bulk or interrupt transfer's end.
- //
- if ((*TransferResult & EFI_USB_ERR_NOTEXECUTE) != EFI_USB_ERR_NOTEXECUTE) {
- break;
- }
-
- gBS->Stall (50);
-
- } while (Delay--);
-
- //
- // has error
- //
- if (*TransferResult != EFI_USB_NOERROR) {
-
- //
- // scroll the Data Toggle back to the last success TD
- //
- ScrollNum = CountTDsNumber (PtrTD) - ErrTDPos;
- if (ScrollNum & 0x1) {
- *DataToggle ^= 1;
- }
-
- return EFI_DEVICE_ERROR;
- }
-
- return EFI_SUCCESS;
-}
-
-VOID
-DelLinkSingleQH (
- IN USB_HC_DEV *HcDev,
- IN QH_STRUCT *PtrQH,
- IN UINT16 FrameListIndex,
- IN BOOLEAN SearchOther,
- IN BOOLEAN Delete
- )
-/*++
-
-Routine Description:
-
- Unlink from frame list and delete single QH
-Arguments:
-
- HcDev - USB_HC_DEV
- PtrQH - QH_STRUCT
- FrameListIndex - Frame List Index
- SearchOther - Search Other QH
- Delete - TRUE is to delete the QH
-Returns:
- VOID
---*/
-{
- FRAMELIST_ENTRY *pCurFrame;
- UINTN Index;
- UINTN BeginFrame;
- UINTN EndFrame;
- QH_STRUCT *CurrentQH;
- QH_STRUCT *NextQH;
- TD_STRUCT *CurrentTD;
- VOID *PtrPreQH;
- BOOLEAN Found;
-
- NextQH = NULL;
- PtrPreQH = NULL;
- Found = FALSE;
-
- if (PtrQH == NULL) {
- return ;
- }
-
- if (SearchOther) {
- BeginFrame = 0;
- EndFrame = 1024;
- } else {
- BeginFrame = FrameListIndex;
- EndFrame = FrameListIndex + 1;
- }
-
- for (Index = BeginFrame; Index < EndFrame; Index++) {
-
- pCurFrame = HcDev->FrameListEntry + (Index & 0x3FF);
-
- if (GetCurFrameListTerminate (pCurFrame)) {
- //
- // current frame list is empty,search next frame list entry
- //
- continue;
- }
-
- if (!IsCurFrameListQHorTD (pCurFrame)) {
- //
- // TD linked to current framelist
- //
- CurrentTD = (TD_STRUCT *) GetCurFrameListPointer (pCurFrame);
-
- while (GetTDLinkPtrValidorInvalid (CurrentTD)) {
-
- if (IsTDLinkPtrQHOrTD (CurrentTD)) {
- //
- // QH linked next to the TD,break while ()
- //
- break;
- }
-
- CurrentTD = (TD_STRUCT *) GetTDLinkPtr (CurrentTD);
- }
-
- if (!GetTDLinkPtrValidorInvalid (CurrentTD)) {
- //
- // no QH linked next to the last TD,
- // search next frame list
- //
- continue;
- }
-
- //
- // a QH linked next to the last TD
- //
- CurrentQH = (QH_STRUCT *) GetTDLinkPtr (CurrentTD);
-
- PtrPreQH = CurrentTD;
-
- } else {
- //
- // a QH linked to current framelist
- //
- CurrentQH = (QH_STRUCT *) GetCurFrameListPointer (pCurFrame);
-
- PtrPreQH = NULL;
- }
-
- if (CurrentQH == PtrQH) {
-
- if (GetQHHorizontalValidorInvalid (PtrQH)) {
- //
- // there is QH connected after the QH found
- //
- //
- // retrieve nex qh pointer of the qh found.
- //
- NextQH = GetQHHorizontalLinkPtr (PtrQH);
- } else {
- NextQH = NULL;
- }
-
- if (PtrPreQH) {
- //
- // QH linked to a TD struct
- //
- CurrentTD = (TD_STRUCT *) PtrPreQH;
-
- SetTDLinkPtrValidorInvalid (CurrentTD, (BOOLEAN) ((NextQH == NULL) ? FALSE : TRUE));
- SetTDLinkPtr (CurrentTD, NextQH);
- CurrentTD->ptrNextQH = NextQH;
-
- } else {
- //
- // QH linked directly to current framelist entry
- //
- SetorClearCurFrameListTerminate (pCurFrame, (BOOLEAN) ((NextQH == NULL) ? TRUE : FALSE));
- SetCurFrameListPointer (pCurFrame, (UINT8 *) NextQH);
- }
-
- Found = TRUE;
- //
- // search next framelist entry
- //
- continue;
- }
-
- while (GetQHHorizontalValidorInvalid (CurrentQH)) {
-
- PtrPreQH = CurrentQH;
- //
- // Get next horizontal linked QH
- //
- CurrentQH = (QH_STRUCT *) GetQHHorizontalLinkPtr (CurrentQH);
- //
- // the qh is found
- //
- if (CurrentQH == PtrQH) {
- break;
- }
- }
-
- //
- // search next frame list entry
- //
- if (CurrentQH != PtrQH) {
- //
- // Not find the QH
- //
- continue;
- }
- //
- // find the specified qh, then delink it from
- // the horizontal QH list in the frame entry.
- //
-
- if (GetQHHorizontalValidorInvalid (PtrQH)) {
- //
- // there is QH connected after the QH found
- //
- //
- // retrieve nex qh pointer of the qh found.
- //
- NextQH = GetQHHorizontalLinkPtr (PtrQH);
-
- } else {
- //
- // NO QH connected after the QH found
- //
- NextQH = NULL;
- //
- // NULL the previous QH's link ptr and set Terminate field.
- //
- SetQHHorizontalValidorInvalid ((QH_STRUCT *) PtrPreQH, FALSE);
- }
-
- SetQHHorizontalLinkPtr ((QH_STRUCT *) PtrPreQH, NextQH);
- ((QH_STRUCT *) PtrPreQH)->ptrNext = NextQH;
-
- Found = TRUE;
- }
-
- if (Found && Delete) {
- //
- // free memory once used by the specific QH
- //
- UhciFreePool (HcDev, (UINT8 *) PtrQH, sizeof (QH_STRUCT));
- }
-
- return ;
-}
-
-
-VOID
-DeleteQueuedTDs (
- IN USB_HC_DEV *HcDev,
- IN TD_STRUCT *PtrFirstTD
- )
-/*++
-Routine Description:
-
- Delete Queued TDs
-Arguments:
-
- HcDev - USB_HC_DEV
- PtrFirstTD - TD link list head
-
-Returns:
- VOID
-
---*/
-{
- TD_STRUCT *Tptr1;
- TD_STRUCT *Tptr2;
-
- Tptr1 = PtrFirstTD;
- //
- // Delete all the TDs in a queue.
- //
- while (Tptr1) {
-
- Tptr2 = Tptr1;
-
- if (!GetTDLinkPtrValidorInvalid (Tptr2)) {
- Tptr1 = NULL;
- } else {
-
- Tptr1 = GetTDLinkPtr (Tptr2);
-
- //
- // TD link to itself
- //
- if (Tptr1 == Tptr2) {
- Tptr1 = NULL;
- }
- }
-
- UhciFreePool (HcDev, (UINT8 *) Tptr2, sizeof (TD_STRUCT));
- }
-
- return ;
-}
-
-VOID
-InsertQHTDToINTList (
- IN USB_HC_DEV *HcDev,
- IN QH_STRUCT *PtrQH,
- IN TD_STRUCT *PtrFirstTD,
- IN UINT8 DeviceAddress,
- IN UINT8 EndPointAddress,
- IN UINT8 DataToggle,
- IN UINTN DataLength,
- IN UINTN PollingInterval,
- IN VOID *Mapping,
- IN UINT8 *DataBuffer,
- IN EFI_ASYNC_USB_TRANSFER_CALLBACK CallBackFunction,
- IN VOID *Context
- )
-/*++
-Routine Description:
- Insert QH and TD To Interrupt List
-Arguments:
-
- HcDev - USB_HC_DEV
- PtrQH - QH_STRUCT
- PtrFirstTD - First TD_STRUCT
- DeviceAddress - Device Address
- EndPointAddress - EndPoint Address
- DataToggle - Data Toggle
- DataLength - Data length
- PollingInterval - Polling Interval when inserted to frame list
- Mapping - Mapping alue
- DataBuffer - Data buffer
- CallBackFunction- CallBackFunction after interrupt transfeer
- Context - CallBackFunction Context passed as function parameter
-Returns:
- EFI_SUCCESS - Sucess
- EFI_INVALID_PARAMETER - Paremeter is error
-
---*/
-{
- INTERRUPT_LIST *Node;
-
- Node = AllocatePool (sizeof (INTERRUPT_LIST));
- if (Node == NULL) {
- return ;
- }
-
- //
- // Fill Node field
- //
- Node->Signature = INTERRUPT_LIST_SIGNATURE;
- Node->DevAddr = DeviceAddress;
- Node->EndPoint = EndPointAddress;
- Node->PtrQH = PtrQH;
- Node->PtrFirstTD = PtrFirstTD;
- Node->DataToggle = DataToggle;
- Node->DataLen = DataLength;
- Node->PollInterval = PollingInterval;
- Node->Mapping = Mapping;
- //
- // DataBuffer is allocated host memory, not mapped memory
- //
- Node->DataBuffer = DataBuffer;
- Node->InterruptCallBack = CallBackFunction;
- Node->InterruptContext = Context;
-
- //
- // insert the new interrupt transfer to the head of the list.
- // The interrupt transfer's monitor function scans the whole list from head
- // to tail. The new interrupt transfer MUST be added to the head of the list
- // for the sake of error recovery.
- //
- InsertHeadList (&(HcDev->InterruptListHead), &(Node->Link));
-
- return ;
-}
-
-
-EFI_STATUS
-DeleteAsyncINTQHTDs (
- IN USB_HC_DEV *HcDev,
- IN UINT8 DeviceAddress,
- IN UINT8 EndPointAddress,
- OUT UINT8 *DataToggle
- )
-/*++
-Routine Description:
-
- Delete Async INT QH and TDs
-Arguments:
-
- HcDev - USB_HC_DEV
- DeviceAddress - Device Address
- EndPointAddress - EndPoint Address
- DataToggle - Data Toggle
-
-Returns:
- EFI_SUCCESS - Sucess
- EFI_INVALID_PARAMETER - Paremeter is error
-
---*/
-{
- QH_STRUCT *MatchQH;
- QH_STRUCT *ptrNextQH;
- TD_STRUCT *MatchTD;
- LIST_ENTRY *Link;
- INTERRUPT_LIST *MatchList;
- INTERRUPT_LIST *PtrList;
- BOOLEAN Found;
-
- UINT32 Result;
- UINTN ErrTDPos;
- UINTN ActualLen;
-
- MatchQH = NULL;
- MatchTD = NULL;
- MatchList = NULL;
-
- //
- // no interrupt transaction exists
- //
- if (IsListEmpty (&(HcDev->InterruptListHead))) {
- return EFI_INVALID_PARAMETER;
- }
- //
- // find the correct QH-TD that need to delete
- // (by matching Device address and EndPoint number to match QH-TD )
- //
- Found = FALSE;
- Link = &(HcDev->InterruptListHead);
- do {
-
- Link = Link->ForwardLink;
- PtrList = INTERRUPT_LIST_FROM_LINK (Link);
-
- if ((PtrList->DevAddr == DeviceAddress) && ((PtrList->EndPoint & 0x0f) == (EndPointAddress & 0x0f))) {
- MatchList = PtrList;
-
- Found = TRUE;
- break;
- }
-
- } while (Link->ForwardLink != &(HcDev->InterruptListHead));
-
- if (!Found) {
- return EFI_INVALID_PARAMETER;
- }
- //
- // get current endpoint's data toggle bit and save.
- //
- ExecuteAsyncINTTDs (HcDev, MatchList, &Result, &ErrTDPos, &ActualLen);
- UpdateAsyncINTQHTDs (MatchList, Result, (UINT32) ErrTDPos);
- *DataToggle = MatchList->DataToggle;
-
- MatchTD = MatchList->PtrFirstTD;
- MatchQH = MatchList->PtrQH;
- //
- // find the first matching QH position in the FrameList
- //
- while (MatchQH) {
-
- ptrNextQH = MatchQH->ptrNextIntQH;
-
- //
- // Search all the entries
- //
- DelLinkSingleQH (HcDev, MatchQH, 0, TRUE, TRUE);
-
- MatchQH = ptrNextQH;
- }
-
- //
- // Call PciIo->Unmap() to unmap the busmaster read/write
- //
- HcDev->PciIo->Unmap (HcDev->PciIo, MatchList->Mapping);
-
- //
- // free host data buffer allocated,
- // mapped data buffer is freed by Unmap
- //
- if (MatchList->DataBuffer != NULL) {
- gBS->FreePool (MatchList->DataBuffer);
- }
-
- //
- // at last delete the TDs, to aVOID problems
- //
- DeleteQueuedTDs (HcDev, MatchTD);
-
- //
- // remove Match node from interrupt list
- //
- RemoveEntryList (&(MatchList->Link));
- gBS->FreePool (MatchList);
- return EFI_SUCCESS;
-}
-
-BOOLEAN
-CheckTDsResults (
- IN TD_STRUCT *PtrTD,
- IN UINTN RequiredLen,
- OUT UINT32 *Result,
- OUT UINTN *ErrTDPos,
- OUT UINTN *ActualTransferSize
- )
-/*++
-
-Routine Description:
-
- Check TDs Results
-
-Arguments:
-
- PtrTD - TD_STRUCT to check
- RequiredLen - Required Len
- Result - Transfer result
- ErrTDPos - Error TD Position
- ActualTransferSize - Actual Transfer Size
-
-Returns:
-
- TRUE - Sucess
- FALSE - Fail
-
---*/
-{
- UINTN Len;
-
- *Result = EFI_USB_NOERROR;
- *ErrTDPos = 0;
-
- //
- // Init to zero.
- //
- *ActualTransferSize = 0;
-
- while (PtrTD) {
-
- if (IsTDStatusActive (PtrTD)) {
- *Result |= EFI_USB_ERR_NOTEXECUTE;
- }
-
- if (IsTDStatusStalled (PtrTD)) {
- *Result |= EFI_USB_ERR_STALL;
- }
-
- if (IsTDStatusBufferError (PtrTD)) {
- *Result |= EFI_USB_ERR_BUFFER;
- }
-
- if (IsTDStatusBabbleError (PtrTD)) {
- *Result |= EFI_USB_ERR_BABBLE;
- }
-
- if (IsTDStatusNAKReceived (PtrTD)) {
- *Result |= EFI_USB_ERR_NAK;
- }
-
- if (IsTDStatusCRCTimeOutError (PtrTD)) {
- *Result |= EFI_USB_ERR_TIMEOUT;
- }
-
- if (IsTDStatusBitStuffError (PtrTD)) {
- *Result |= EFI_USB_ERR_BITSTUFF;
- }
-
- //
- // if any error encountered, stop processing the left TDs.
- //
- if (*Result) {
- return FALSE;
- }
-
- Len = GetTDStatusActualLength (PtrTD) & 0x7FF;
- *ActualTransferSize += Len;
-
- if (*ActualTransferSize <= RequiredLen && Len < PtrTD->TDData.TDTokenMaxLen) {
- //
- // transter finished and actural length less than required length
- //
- goto Done;
- }
- //
- // Accumulate actual transferred data length in each TD.
- //
- PtrTD = (TD_STRUCT *) (PtrTD->ptrNextTD);
- //
- // Record the first Error TD's position in the queue,
- // this value is zero-based.
- //
- (*ErrTDPos)++;
- }
-
-Done:
- return TRUE;
-}
-
-
-VOID
-ExecuteAsyncINTTDs (
- IN USB_HC_DEV *HcDev,
- IN INTERRUPT_LIST *PtrList,
- OUT UINT32 *Result,
- OUT UINTN *ErrTDPos,
- OUT UINTN *ActualLen
- )
-/*++
-
-Routine Description:
-
- Execute Async Interrupt TDs
-
-Arguments:
-
- HcDev - USB_HC_DEV
- PtrList - INTERRUPT_LIST
- Result - Transfer result
- ErrTDPos - Error TD Position
- ActualTransferSize - Actual Transfer Size
-
-Returns:
-
- VOID
-
---*/
-{
- //
- // *ErrTDPos is zero-based value, indicating the first error TD's position
- // in the TDs' sequence.
- // *ErrTDPos value is only valid when *Result is not equal NOERROR.
- //
- UINTN RequiredLen;
-
- RequiredLen = *ActualLen;
- CheckTDsResults (PtrList->PtrFirstTD, RequiredLen, Result, ErrTDPos, ActualLen);
-
- return ;
-}
-
-
-VOID
-UpdateAsyncINTQHTDs (
- IN INTERRUPT_LIST *PtrList,
- IN UINT32 Result,
- IN UINT32 ErrTDPos
- )
-/*++
-
-Routine Description:
-
- Update Async Interrupt QH and TDs
-
-Arguments:
-
- PtrList - INTERRUPT_LIST
- Result - Transfer reslut
- ErrTDPos - Error TD Position
-
-Returns:
-
- VOID
-
---*/
-{
- QH_STRUCT *PtrFirstQH;
- QH_STRUCT *PtrQH;
- TD_STRUCT *PtrFirstTD;
- TD_STRUCT *PtrTD;
- UINT8 DataToggle;
- UINT32 Index;
-
- PtrFirstQH = PtrList->PtrQH;
- PtrFirstTD = PtrList->PtrFirstTD;
-
- DataToggle = 0;
-
- if (Result == EFI_USB_NOERROR) {
-
- PtrTD = PtrFirstTD;
- while (PtrTD) {
- DataToggle = GetTDTokenDataToggle (PtrTD);
- PtrTD = PtrTD->ptrNextTD;
- }
-
- //
- // save current DataToggle value to interrupt list.
- // this value is used for tracing the interrupt endpoint DataToggle.
- // when this interrupt transfer is deleted, the last DataToggle is saved
- //
- PtrList->DataToggle = DataToggle;
-
- PtrTD = PtrFirstTD;
-
- //
- // Since DataToggle bit should toggle after each success transaction,
- // the First TD's DataToggle bit will be updated to XOR of Last TD's
- // DataToggle bit. If the First TD's DataToggle bit is not equal Last
- // TD's DataToggle bit, that means it already be the XOR of Last TD's,
- // so no update is needed.
- //
- if (DataToggle == GetTDTokenDataToggle (PtrFirstTD)) {
- PtrTD = PtrFirstTD;
- while (PtrTD) {
-
- DataToggle ^= 1;
- if (DataToggle) {
- SetTDTokenDataToggle1 (PtrTD);
- } else {
- SetTDTokenDataToggle0 (PtrTD);
- }
-
- PtrTD = PtrTD->ptrNextTD;
- }
- }
- //
- // restore Link Pointer of QH to First TD
- // (because QH's Link Pointer will change during TD execution)
- //
- PtrQH = PtrFirstQH;
- while (PtrQH) {
-
- LinkTDToQH (PtrQH, PtrFirstTD);
- PtrQH = PtrQH->ptrNextIntQH;
- }
-
- //
- // set all the TDs active
- //
- PtrTD = PtrFirstTD;
- while (PtrTD) {
- SetTDStatusActiveorInactive (PtrTD, TRUE);
- PtrTD = PtrTD->ptrNextTD;
- }
-
- } else if (((Result & EFI_USB_ERR_NOTEXECUTE) == EFI_USB_ERR_NOTEXECUTE) ||
- ((Result & EFI_USB_ERR_NAK) == EFI_USB_ERR_NAK)
- ) {
- //
- // no update
- //
- } else {
- //
- // Have Errors
- //
- PtrTD = PtrFirstTD;
- //
- // not first TD error
- //
- if (ErrTDPos != 0) {
- //
- // get the last success TD
- //
- for (Index = 1; Index < ErrTDPos; Index++) {
- PtrTD = PtrTD->ptrNextTD;
- }
- //
- // update Data Toggle in the interrupt list node
- //
- PtrList->DataToggle = GetTDTokenDataToggle (PtrTD);
-
- //
- // get the error TD
- //
- PtrTD = PtrTD->ptrNextTD;
-
- } else {
- PtrList->DataToggle = GetTDTokenDataToggle (PtrTD);
- }
- //
- // do not restore the QH's vertical link pointer,
- // let the callback function do the rest of error handling.
- //
- }
-
- return ;
-}
-
-VOID
-ReleaseInterruptList (
- IN USB_HC_DEV *HcDev,
- IN LIST_ENTRY *ListHead
- )
-/*++
-
-Routine Description:
-
- Release Interrupt List
-Arguments:
-
- HcDev - USB_HC_DEV
- ListHead - List head
-
-Returns:
-
- VOID
-
---*/
-{
- LIST_ENTRY *Link;
- LIST_ENTRY *SavedLink;
- INTERRUPT_LIST *pNode;
- TD_STRUCT *PtrTD;
- TD_STRUCT *ptrNextTD;
- QH_STRUCT *PtrQH;
- QH_STRUCT *SavedQH;
-
- if (ListHead == NULL) {
- return ;
- }
-
- Link = ListHead;
-
- //
- // Free all the resources in the interrupt list
- //
- SavedLink = Link->ForwardLink;
- while (!IsListEmpty (ListHead)) {
-
- Link = SavedLink;
-
- SavedLink = Link->ForwardLink;
-
- pNode = INTERRUPT_LIST_FROM_LINK (Link);
-
- RemoveEntryList (&pNode->Link);
-
- SavedQH = pNode->PtrQH;
- for (PtrQH = SavedQH; PtrQH != NULL; PtrQH = SavedQH) {
- SavedQH = PtrQH->ptrNextIntQH;
- UhciFreePool (HcDev, (UINT8 *) PtrQH, sizeof (QH_STRUCT));
- }
-
- PtrTD = pNode->PtrFirstTD;
- while (PtrTD != NULL) {
-
- ptrNextTD = PtrTD->ptrNextTD;
- UhciFreePool (HcDev, (UINT8 *) PtrTD, sizeof (TD_STRUCT));
- PtrTD = ptrNextTD;
- }
-
- gBS->FreePool (pNode);
- }
-}
-
-
-EFI_STATUS
-InitializeMemoryManagement (
- IN USB_HC_DEV *HcDev
- )
-/*++
-
-Routine Description:
-
- Initialize Memory Management
-
-Arguments:
-
- HcDev - USB_HC_DEV
-
-Returns:
-
- EFI_SUCCESS - Success
---*/
-{
- MEMORY_MANAGE_HEADER *MemoryHeader;
- EFI_STATUS Status;
- UINTN MemPages;
-
- MemPages = NORMAL_MEMORY_BLOCK_UNIT_IN_PAGES;
- Status = CreateMemoryBlock (HcDev, &MemoryHeader, MemPages);
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- HcDev->MemoryHeader = MemoryHeader;
-
- return EFI_SUCCESS;
-}
-
-EFI_STATUS
-CreateMemoryBlock (
- IN USB_HC_DEV *HcDev,
- OUT MEMORY_MANAGE_HEADER **MemoryHeader,
- IN UINTN MemoryBlockSizeInPages
- )
-/*++
-
-Routine Description:
-
- Use PciIo->AllocateBuffer to allocate common buffer for the memory block,
- and use PciIo->Map to map the common buffer for Bus Master Read/Write.
-
-
-Arguments:
-
- HcDev - USB_HC_DEV
- MemoryHeader - MEMORY_MANAGE_HEADER to output
- MemoryBlockSizeInPages - MemoryBlockSizeInPages
-Returns:
-
- EFI_SUCCESS - Success
---*/
-{
- EFI_STATUS Status;
- VOID *CommonBuffer;
- EFI_PHYSICAL_ADDRESS MappedAddress;
- UINTN MemoryBlockSizeInBytes;
- VOID *Mapping;
-
- //
- // Allocate memory for MemoryHeader
- //
- *MemoryHeader = AllocateZeroPool (sizeof (MEMORY_MANAGE_HEADER));
- if (*MemoryHeader == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- (*MemoryHeader)->Next = NULL;
-
- //
- // set Memory block size
- //
- (*MemoryHeader)->MemoryBlockSizeInBytes = EFI_PAGES_TO_SIZE (MemoryBlockSizeInPages);
-
- //
- // each bit in Bit Array will manage 32 bytes memory in memory block
- //
- (*MemoryHeader)->BitArraySizeInBytes = ((*MemoryHeader)->MemoryBlockSizeInBytes / 32) / 8;
-
- //
- // Allocate memory for BitArray
- //
- (*MemoryHeader)->BitArrayPtr = AllocateZeroPool ((*MemoryHeader)->BitArraySizeInBytes);
- if ((*MemoryHeader)->BitArrayPtr == NULL) {
- gBS->FreePool (*MemoryHeader);
- return EFI_OUT_OF_RESOURCES;
- }
-
- //
- // Memory Block uses MemoryBlockSizeInPages pages,
- // and it is allocated as common buffer use.
- //
- Status = HcDev->PciIo->AllocateBuffer (
- HcDev->PciIo,
- AllocateAnyPages,
- EfiBootServicesData,
- MemoryBlockSizeInPages,
- &CommonBuffer,
- 0
- );
- if (EFI_ERROR (Status)) {
- gBS->FreePool ((*MemoryHeader)->BitArrayPtr);
- gBS->FreePool (*MemoryHeader);
- return Status;
- }
-
- MemoryBlockSizeInBytes = EFI_PAGES_TO_SIZE (MemoryBlockSizeInPages);
- Status = HcDev->PciIo->Map (
- HcDev->PciIo,
- EfiPciIoOperationBusMasterCommonBuffer,
- CommonBuffer,
- &MemoryBlockSizeInBytes,
- &MappedAddress,
- &Mapping
- );
- //
- // if returned Mapped size is less than the size we request,do not support.
- //
- if (EFI_ERROR (Status) || (MemoryBlockSizeInBytes != EFI_PAGES_TO_SIZE (MemoryBlockSizeInPages))) {
- HcDev->PciIo->FreeBuffer (HcDev->PciIo, MemoryBlockSizeInPages, CommonBuffer);
- gBS->FreePool ((*MemoryHeader)->BitArrayPtr);
- gBS->FreePool (*MemoryHeader);
- return EFI_UNSUPPORTED;
- }
- //
- // Set Memory block initial address
- //
- (*MemoryHeader)->MemoryBlockPtr = (UINT8 *) ((UINTN) MappedAddress);
- (*MemoryHeader)->Mapping = Mapping;
-
- ZeroMem (
- (*MemoryHeader)->MemoryBlockPtr,
- EFI_PAGES_TO_SIZE (MemoryBlockSizeInPages)
- );
-
- return EFI_SUCCESS;
-}
-
-EFI_STATUS
-FreeMemoryHeader (
- IN USB_HC_DEV *HcDev,
- IN MEMORY_MANAGE_HEADER *MemoryHeader
- )
-/*++
-
-Routine Description:
-
- Free Memory Header
-
-Arguments:
-
- HcDev - USB_HC_DEV
- MemoryHeader - MemoryHeader to be freed
-
-Returns:
-
- EFI_INVALID_PARAMETER - Parameter is error
- EFI_SUCCESS - Success
-
---*/
-{
- if ((MemoryHeader == NULL) || (HcDev == NULL)) {
- return EFI_INVALID_PARAMETER;
- }
- //
- // unmap the common buffer used by the memory block
- //
- HcDev->PciIo->Unmap (HcDev->PciIo, MemoryHeader->Mapping);
-
- //
- // free common buffer
- //
- HcDev->PciIo->FreeBuffer (
- HcDev->PciIo,
- EFI_SIZE_TO_PAGES (MemoryHeader->MemoryBlockSizeInBytes),
- MemoryHeader->MemoryBlockPtr
- );
- //
- // free bit array
- //
- gBS->FreePool (MemoryHeader->BitArrayPtr);
- //
- // free memory header
- //
- gBS->FreePool (MemoryHeader);
-
- return EFI_SUCCESS;
-}
-
-EFI_STATUS
-UhciAllocatePool (
- IN USB_HC_DEV *HcDev,
- OUT UINT8 **Pool,
- IN UINTN AllocSize
- )
-/*++
-
-Routine Description:
-
- Uhci Allocate Pool
-
-Arguments:
-
- HcDev - USB_HC_DEV
- Pool - Place to store pointer to the memory buffer
- AllocSize - Alloc Size
-
-Returns:
-
- EFI_SUCCESS - Success
-
---*/
-{
- MEMORY_MANAGE_HEADER *MemoryHeader;
- MEMORY_MANAGE_HEADER *TempHeaderPtr;
- MEMORY_MANAGE_HEADER *NewMemoryHeader;
- UINTN RealAllocSize;
- UINTN MemoryBlockSizeInPages;
- EFI_STATUS Status;
-
- *Pool = NULL;
-
- MemoryHeader = HcDev->MemoryHeader;
- ASSERT (MemoryHeader != NULL);
-
- //
- // allocate unit is 32 bytes (align on 32 byte)
- //
- if (AllocSize & 0x1F) {
- RealAllocSize = (AllocSize / 32 + 1) * 32;
- } else {
- RealAllocSize = AllocSize;
- }
-
- //
- // There may be linked MemoryHeaders.
- // To allocate a free pool in Memory blocks,
- // must search in the MemoryHeader link list
- // until enough free pool is found.
- //
- Status = EFI_NOT_FOUND;
- for (TempHeaderPtr = MemoryHeader; TempHeaderPtr != NULL;
- TempHeaderPtr = TempHeaderPtr->Next) {
-
- Status = AllocMemInMemoryBlock (
- TempHeaderPtr,
- (VOID **) Pool,
- RealAllocSize / 32
- );
- if (!EFI_ERROR (Status)) {
- ZeroMem (*Pool, AllocSize);
- return EFI_SUCCESS;
- }
- }
-
- //
- // There is no enough memory,
- // Create a new Memory Block
- //
-
- //
- // if pool size is larger than NORMAL_MEMORY_BLOCK_UNIT_IN_PAGES,
- // just allocate a large enough memory block.
- //
- if (RealAllocSize > EFI_PAGES_TO_SIZE (NORMAL_MEMORY_BLOCK_UNIT_IN_PAGES)) {
- MemoryBlockSizeInPages = EFI_SIZE_TO_PAGES (RealAllocSize) + 1;
- } else {
- MemoryBlockSizeInPages = NORMAL_MEMORY_BLOCK_UNIT_IN_PAGES;
- }
-
- Status = CreateMemoryBlock (HcDev, &NewMemoryHeader, MemoryBlockSizeInPages);
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- //
- // Link the new Memory Block to the Memory Header list
- //
- InsertMemoryHeaderToList (MemoryHeader, NewMemoryHeader);
-
- Status = AllocMemInMemoryBlock (
- NewMemoryHeader,
- (VOID **) Pool,
- RealAllocSize / 32
- );
-
- if (!EFI_ERROR (Status)) {
- ZeroMem (*Pool, AllocSize);
- }
-
- return Status;
-}
-
-VOID
-UhciFreePool (
- IN USB_HC_DEV *HcDev,
- IN UINT8 *Pool,
- IN UINTN AllocSize
- )
-/*++
-
-Routine Description:
-
- Uhci Free Pool
-
-Arguments:
-
- HcDev - USB_HC_DEV
- Pool - Pool to free
- AllocSize - Pool size
-
-Returns:
-
- VOID
-
---*/
-{
- MEMORY_MANAGE_HEADER *MemoryHeader;
- MEMORY_MANAGE_HEADER *TempHeaderPtr;
- UINTN StartBytePos;
- UINTN Index;
- UINT8 StartBitPos;
- UINT8 Index2;
- UINTN Count;
- UINTN RealAllocSize;
-
- MemoryHeader = HcDev->MemoryHeader;
-
- //
- // allocate unit is 32 byte (align on 32 byte)
- //
- if (AllocSize & 0x1F) {
- RealAllocSize = (AllocSize / 32 + 1) * 32;
- } else {
- RealAllocSize = AllocSize;
- }
- //
- // scan the memory header linked list for
- // the asigned memory to free.
- //
- for (TempHeaderPtr = MemoryHeader;TempHeaderPtr != NULL;
- TempHeaderPtr = TempHeaderPtr->Next) {
-
- if ((Pool >= TempHeaderPtr->MemoryBlockPtr) &&
- ((Pool + RealAllocSize) <= (TempHeaderPtr->MemoryBlockPtr + TempHeaderPtr->MemoryBlockSizeInBytes))
- ) {
- //
- // Pool is in the Memory Block area,
- // find the start byte and bit in the bit array
- //
- StartBytePos = ((Pool - TempHeaderPtr->MemoryBlockPtr) / 32) / 8;
- StartBitPos = (UINT8) (((Pool - TempHeaderPtr->MemoryBlockPtr) / 32) & 0x7);
-
- //
- // reset associated bits in bit arry
- //
- for (Index = StartBytePos, Index2 = StartBitPos, Count = 0; Count < (RealAllocSize / 32); Count++) {
-
- TempHeaderPtr->BitArrayPtr[Index] = (UINT8) (TempHeaderPtr->BitArrayPtr[Index] ^ bit (Index2));
- Index2++;
- if (Index2 == 8) {
- Index += 1;
- Index2 = 0;
- }
- }
- //
- // break the loop
- //
- break;
- }
- }
-
- //
- // Release emptied memory blocks (only if the memory block is not
- // the first one in the memory header list
- //
- for (TempHeaderPtr = MemoryHeader->Next; TempHeaderPtr != NULL;) {
- //
- // Debug
- //
- ASSERT (MemoryHeader->Next != NULL);
-
- if (IsMemoryBlockEmptied (TempHeaderPtr)) {
-
- DelinkMemoryBlock (MemoryHeader, TempHeaderPtr);
- //
- // when the TempHeaderPtr is freed in FreeMemoryHeader(),
- // the TempHeaderPtr is pointing to nonsense content.
- //
- FreeMemoryHeader (HcDev, TempHeaderPtr);
- //
- // reset the TempHeaderPtr, continue search for
- // another empty memory block.
- //
- TempHeaderPtr = MemoryHeader->Next;
- continue;
- }
-
- TempHeaderPtr = TempHeaderPtr->Next;
- }
-}
-
-VOID
-InsertMemoryHeaderToList (
- IN MEMORY_MANAGE_HEADER *MemoryHeader,
- IN MEMORY_MANAGE_HEADER *NewMemoryHeader
- )
-/*++
-
-Routine Description:
-
- Insert Memory Header To List
-
-Arguments:
-
- MemoryHeader - MEMORY_MANAGE_HEADER
- NewMemoryHeader - MEMORY_MANAGE_HEADER
-
-Returns:
-
- VOID
-
---*/
-{
- MEMORY_MANAGE_HEADER *TempHeaderPtr;
-
- for (TempHeaderPtr = MemoryHeader; TempHeaderPtr != NULL;
- TempHeaderPtr = TempHeaderPtr->Next) {
- if (TempHeaderPtr->Next == NULL) {
- TempHeaderPtr->Next = NewMemoryHeader;
- break;
- }
- }
-}
-
-EFI_STATUS
-AllocMemInMemoryBlock (
- IN MEMORY_MANAGE_HEADER *MemoryHeader,
- OUT VOID **Pool,
- IN UINTN NumberOfMemoryUnit
- )
-/*++
-
-Routine Description:
-
- Alloc Memory In MemoryBlock
-
-Arguments:
-
- MemoryHeader - MEMORY_MANAGE_HEADER
- Pool - Place to store pointer to memory
- NumberOfMemoryUnit - Number Of Memory Unit
-
-Returns:
-
- EFI_NOT_FOUND - Can't find the free memory
- EFI_SUCCESS - Success
-
---*/
-{
- UINTN TempBytePos;
- UINTN FoundBytePos;
- UINT8 Index;
- UINT8 FoundBitPos;
- UINT8 ByteValue;
- UINT8 BitValue;
- UINTN NumberOfZeros;
- UINTN Count;
-
- FoundBytePos = 0;
- FoundBitPos = 0;
- ByteValue = MemoryHeader->BitArrayPtr[0];
- NumberOfZeros = 0;
- Index = 0;
-
- for (TempBytePos = 0; TempBytePos < MemoryHeader->BitArraySizeInBytes;) {
-
- //
- // Pop out BitValue from a byte in TempBytePos.
- //
- BitValue = (UINT8) (ByteValue & 0x1);
- //
- // right shift the byte
- //
- ByteValue /= 2;
-
- if (BitValue == 0) {
- //
- // Found a free bit, the NumberOfZeros only record the number
- // of those consecutive zeros
- //
- NumberOfZeros++;
- //
- // Found enough consecutive free space, break the loop
- //
- if (NumberOfZeros >= NumberOfMemoryUnit) {
- break;
- }
- } else {
- //
- // Encountering a '1', meant the bit is ocupied.
- //
- if (NumberOfZeros >= NumberOfMemoryUnit) {
- //
- // Found enough consecutive free space,break the loop
- //
- break;
- } else {
- //
- // the NumberOfZeros only record the number of those consecutive zeros,
- // so reset the NumberOfZeros to 0 when encountering '1' before finding
- // enough consecutive '0's
- //
- NumberOfZeros = 0;
- //
- // reset the (FoundBytePos,FoundBitPos) to the position of '1'
- //
- FoundBytePos = TempBytePos;
- FoundBitPos = Index;
- }
- }
- //
- // step forward a bit
- //
- Index++;
- if (Index == 8) {
- //
- // step forward a byte, getting the byte value,
- // and reset the bit pos.
- //
- TempBytePos += 1;
- ByteValue = MemoryHeader->BitArrayPtr[TempBytePos];
- Index = 0;
- }
- }
-
- if (NumberOfZeros < NumberOfMemoryUnit) {
- return EFI_NOT_FOUND;
- }
-
- //
- // Found enough free space.
- //
-
- //
- // The values recorded in (FoundBytePos,FoundBitPos) have two conditions:
- // 1)(FoundBytePos,FoundBitPos) record the position
- // of the last '1' before the consecutive '0's, it must
- // be adjusted to the start position of the consecutive '0's.
- // 2)the start address of the consecutive '0's is just the start of
- // the bitarray. so no need to adjust the values of
- // (FoundBytePos,FoundBitPos).
- //
- if ((MemoryHeader->BitArrayPtr[0] & bit (0)) != 0) {
- FoundBitPos += 1;
- }
-
- //
- // Have the (FoundBytePos,FoundBitPos) make sense.
- //
- if (FoundBitPos > 7) {
- FoundBytePos += 1;
- FoundBitPos -= 8;
- }
-
- //
- // Set the memory as allocated
- //
- for (TempBytePos = FoundBytePos, Index = FoundBitPos,Count = 0;
- Count < NumberOfMemoryUnit; Count ++) {
-
- MemoryHeader->BitArrayPtr[TempBytePos] = (UINT8) (MemoryHeader->BitArrayPtr[TempBytePos] | bit (Index));
- Index++;
- if (Index == 8) {
- TempBytePos += 1;
- Index = 0;
- }
- }
-
- *Pool = MemoryHeader->MemoryBlockPtr + (FoundBytePos * 8 + FoundBitPos) * 32;
-
- return EFI_SUCCESS;
-}
-
-BOOLEAN
-IsMemoryBlockEmptied (
- IN MEMORY_MANAGE_HEADER *MemoryHeaderPtr
- )
-/*++
-
-Routine Description:
-
- Is Memory Block Emptied
-
-Arguments:
-
- MemoryHeaderPtr - MEMORY_MANAGE_HEADER
-
-Returns:
-
- TRUE - Empty
- FALSE - Not Empty
-
---*/
-{
- UINTN Index;
-
- for (Index = 0; Index < MemoryHeaderPtr->BitArraySizeInBytes; Index++) {
- if (MemoryHeaderPtr->BitArrayPtr[Index] != 0) {
- return FALSE;
- }
- }
-
- return TRUE;
-}
-
-VOID
-DelinkMemoryBlock (
- IN MEMORY_MANAGE_HEADER *FirstMemoryHeader,
- IN MEMORY_MANAGE_HEADER *NeedFreeMemoryHeader
- )
-/*++
-
-Routine Description:
-
- Delink Memory Block
-
-Arguments:
-
- FirstMemoryHeader - MEMORY_MANAGE_HEADER
- NeedFreeMemoryHeader - MEMORY_MANAGE_HEADER
-
-Returns:
-
- VOID
-
---*/
-{
- MEMORY_MANAGE_HEADER *TempHeaderPtr;
-
- if ((FirstMemoryHeader == NULL) || (NeedFreeMemoryHeader == NULL)) {
- return ;
- }
- for (TempHeaderPtr = FirstMemoryHeader; TempHeaderPtr != NULL;
- TempHeaderPtr = TempHeaderPtr->Next) {
-
- if (TempHeaderPtr->Next == NeedFreeMemoryHeader) {
- //
- // Link the before and after
- //
- TempHeaderPtr->Next = NeedFreeMemoryHeader->Next;
- break;
- }
- }
-}
-
-EFI_STATUS
-DelMemoryManagement (
- IN USB_HC_DEV *HcDev
- )
-/*++
-
-Routine Description:
-
- Delete Memory Management
-
-Arguments:
-
- HcDev - USB_HC_DEV
-
-Returns:
-
- EFI_SUCCESS - Success
-
---*/
-{
- MEMORY_MANAGE_HEADER *TempHeaderPtr;
-
- for (TempHeaderPtr = HcDev->MemoryHeader->Next; TempHeaderPtr != NULL;) {
-
- DelinkMemoryBlock (HcDev->MemoryHeader, TempHeaderPtr);
- //
- // when the TempHeaderPtr is freed in FreeMemoryHeader(),
- // the TempHeaderPtr is pointing to nonsense content.
- //
- FreeMemoryHeader (HcDev, TempHeaderPtr);
- //
- // reset the TempHeaderPtr,continue free another memory block.
- //
- TempHeaderPtr = HcDev->MemoryHeader->Next;
- }
-
- FreeMemoryHeader (HcDev, HcDev->MemoryHeader);
-
- return EFI_SUCCESS;
-}
-
-
-VOID
-CleanUsbTransactions (
- IN USB_HC_DEV *HcDev
- )
-{
- //
- // only asynchronous interrupt transfers are always alive on the bus
- //
- ReleaseInterruptList (HcDev, &(HcDev->InterruptListHead));
-}
-
-VOID
-TurnOffUSBEmulation (
- IN EFI_PCI_IO_PROTOCOL *PciIo
- )
-/*++
-
- Routine Description:
- Disable USB Emulation
- Arguments:
- PciIo - EFI_PCI_IO_PROTOCOL
- Returns:
- VOID
---*/
-{
- UINT16 Command;
-
- //
- // Disable USB Emulation
- //
- Command = 0;
- PciIo->Pci.Write (
- PciIo,
- EfiPciIoWidthUint16,
- USB_EMULATION,
- 1,
- &Command
- );
-
- return ;
-}