/** @file The definition for UHCI register operation routines. Copyright (c) 2007, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef _EFI_UHCI_QUEUE_H_ #define _EFI_UHCI_QUEUE_H_ // // Macroes used to set various links in UHCI's driver. // In this UHCI driver, QH's horizontal link always pointers to other QH, // and its vertical link always pointers to TD. TD's next pointer always // pointers to other sibling TD. Frame link always pointers to QH because // ISO transfer isn't supported. // // We should use UINT32 to access these pointers to void race conditions // with hardware. // #define QH_HLINK(Pointer, Terminate) \ (((UINT32) ((UINTN) (Pointer)) & 0xFFFFFFF0) | 0x02 | ((Terminate) ? 0x01 : 0)) #define QH_VLINK(Pointer, Terminate) \ (((UINT32) ((UINTN) (Pointer)) & 0xFFFFFFF0) | ((Terminate) ? 0x01 : 0)) #define TD_LINK(Pointer, VertFirst, Terminate) \ (((UINT32) ((UINTN) (Pointer)) & 0xFFFFFFF0) | \ ((VertFirst) ? 0x04 : 0) | ((Terminate) ? 0x01 : 0)) #define LINK_TERMINATED(Link) (((Link) & 0x01) != 0) #define UHCI_ADDR(QhOrTd) ((VOID *) (UINTN) ((QhOrTd) & 0xFFFFFFF0)) #pragma pack(1) // // Both links in QH has this internal structure: // Next pointer: 28, Reserved: 2, NextIsQh: 1, Terminate: 1 // This is the same as frame list entry. // typedef struct { UINT32 HorizonLink; UINT32 VerticalLink; } UHCI_QH_HW; // // Next link in TD has this internal structure: // Next pointer: 28, Reserved: 1, Vertical First: 1, NextIsQh: 1, Terminate: 1 // typedef struct { UINT32 NextLink; UINT32 ActualLen : 11; UINT32 Reserved1 : 5; UINT32 Status : 8; UINT32 IntOnCpl : 1; UINT32 IsIsoch : 1; UINT32 LowSpeed : 1; UINT32 ErrorCount : 2; UINT32 ShortPacket : 1; UINT32 Reserved2 : 2; UINT32 PidCode : 8; UINT32 DeviceAddr : 7; UINT32 EndPoint : 4; UINT32 DataToggle : 1; UINT32 Reserved3 : 1; UINT32 MaxPacketLen : 11; UINT32 DataBuffer; } UHCI_TD_HW; #pragma pack() typedef struct _UHCI_TD_SW UHCI_TD_SW; typedef struct _UHCI_QH_SW UHCI_QH_SW; struct _UHCI_QH_SW { UHCI_QH_HW QhHw; UHCI_QH_SW *NextQh; UHCI_TD_SW *TDs; UINTN Interval; }; struct _UHCI_TD_SW { UHCI_TD_HW TdHw; UHCI_TD_SW *NextTd; UINT8 *Data; UINT16 DataLen; }; /** Link the TD To QH. @param Uhc The UHCI device. @param Qh The queue head for the TD to link to. @param Td The TD to link. **/ VOID UhciLinkTdToQh ( IN USB_HC_DEV *Uhc, IN UHCI_QH_SW *Qh, IN UHCI_TD_SW *Td ); /** Unlink TD from the QH. @param Qh The queue head to unlink from. @param Td The TD to unlink. @return None. **/ VOID UhciUnlinkTdFromQh ( IN UHCI_QH_SW *Qh, IN UHCI_TD_SW *Td ); /** Map address of request structure buffer. @param Uhc The UHCI device. @param Request The user request buffer. @param MappedAddr Mapped address of request. @param Map Identificaion of this mapping to return. @return EFI_SUCCESS Success. @return EFI_DEVICE_ERROR Fail to map the user request. **/ EFI_STATUS UhciMapUserRequest ( IN USB_HC_DEV *Uhc, IN OUT VOID *Request, OUT UINT8 **MappedAddr, OUT VOID **Map ); /** Map address of user data buffer. @param Uhc The UHCI device. @param Direction Direction of the data transfer. @param Data The user data buffer. @param Len Length of the user data. @param PktId Packet identificaion. @param MappedAddr Mapped address to return. @param Map Identificaion of this mapping to return. @return EFI_SUCCESS Success. @return EFI_DEVICE_ERROR Fail to map the user data. **/ EFI_STATUS UhciMapUserData ( IN USB_HC_DEV *Uhc, IN EFI_USB_DATA_DIRECTION Direction, IN VOID *Data, IN OUT UINTN *Len, OUT UINT8 *PktId, OUT UINT8 **MappedAddr, OUT VOID **Map ); /** Delete a list of TDs. @param Uhc The UHCI device. @param FirstTd TD link list head. @return None. **/ VOID UhciDestoryTds ( IN USB_HC_DEV *Uhc, IN UHCI_TD_SW *FirstTd ); /** Create an initialize a new queue head. @param Uhc The UHCI device. @param Interval The polling interval for the queue. @return The newly created queue header. **/ UHCI_QH_SW * UhciCreateQh ( IN USB_HC_DEV *Uhc, IN UINTN Interval ); /** Create Tds list for Control Transfer. @param Uhc The UHCI device. @param DeviceAddr The device address. @param DataPktId Packet Identification of Data Tds. @param Request A pointer to cpu memory address of request structure buffer to transfer. @param RequestPhy A pointer to pci memory address of request structure buffer to transfer. @param Data A pointer to cpu memory address of user data buffer to transfer. @param DataPhy A pointer to pci memory address of user data buffer to transfer. @param DataLen Length of user data to transfer. @param MaxPacket Maximum packet size for control transfer. @param IsLow Full speed or low speed. @return The Td list head for the control transfer. **/ UHCI_TD_SW * UhciCreateCtrlTds ( IN USB_HC_DEV *Uhc, IN UINT8 DeviceAddr, IN UINT8 DataPktId, IN UINT8 *Request, IN UINT8 *RequestPhy, IN UINT8 *Data, IN UINT8 *DataPhy, IN UINTN DataLen, IN UINT8 MaxPacket, IN BOOLEAN IsLow ); /** Create Tds list for Bulk/Interrupt Transfer. @param Uhc USB_HC_DEV. @param DevAddr Address of Device. @param EndPoint Endpoint Number. @param PktId Packet Identification of Data Tds. @param Data A pointer to cpu memory address of user data buffer to transfer. @param DataPhy A pointer to pci memory address of user data buffer to transfer. @param DataLen Length of user data to transfer. @param DataToggle Data Toggle Pointer. @param MaxPacket Maximum packet size for Bulk/Interrupt transfer. @param IsLow Is Low Speed Device. @return The Tds list head for the bulk transfer. **/ UHCI_TD_SW * UhciCreateBulkOrIntTds ( IN USB_HC_DEV *Uhc, IN UINT8 DevAddr, IN UINT8 EndPoint, IN UINT8 PktId, IN UINT8 *Data, IN UINT8 *DataPhy, IN UINTN DataLen, IN OUT UINT8 *DataToggle, IN UINT8 MaxPacket, IN BOOLEAN IsLow ); #endif