/** @file Private Header file for Usb Host Controller PEIM Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef _EFI_EHCI_URB_H_ #define _EFI_EHCI_URB_H_ typedef struct _PEI_EHC_QTD PEI_EHC_QTD; typedef struct _PEI_EHC_QH PEI_EHC_QH; typedef struct _PEI_URB PEI_URB; #define EHC_CTRL_TRANSFER 0x01 #define EHC_BULK_TRANSFER 0x02 #define EHC_INT_TRANSFER_SYNC 0x04 #define EHC_INT_TRANSFER_ASYNC 0x08 #define EHC_QTD_SIG SIGNATURE_32 ('U', 'S', 'B', 'T') #define EHC_QH_SIG SIGNATURE_32 ('U', 'S', 'B', 'H') #define EHC_URB_SIG SIGNATURE_32 ('U', 'S', 'B', 'R') // // Hardware related bit definitions // #define EHC_TYPE_ITD 0x00 #define EHC_TYPE_QH 0x02 #define EHC_TYPE_SITD 0x04 #define EHC_TYPE_FSTN 0x06 #define QH_NAK_RELOAD 3 #define QH_HSHBW_MULTI 1 #define QTD_MAX_ERR 3 #define QTD_PID_OUTPUT 0x00 #define QTD_PID_INPUT 0x01 #define QTD_PID_SETUP 0x02 #define QTD_STAT_DO_OUT 0 #define QTD_STAT_DO_SS 0 #define QTD_STAT_DO_PING 0x01 #define QTD_STAT_DO_CS 0x02 #define QTD_STAT_TRANS_ERR 0x08 #define QTD_STAT_BABBLE_ERR 0x10 #define QTD_STAT_BUFF_ERR 0x20 #define QTD_STAT_HALTED 0x40 #define QTD_STAT_ACTIVE 0x80 #define QTD_STAT_ERR_MASK (QTD_STAT_TRANS_ERR | QTD_STAT_BABBLE_ERR | QTD_STAT_BUFF_ERR) #define QTD_MAX_BUFFER 4 #define QTD_BUF_LEN 4096 #define QTD_BUF_MASK 0x0FFF #define QH_MICROFRAME_0 0x01 #define QH_MICROFRAME_1 0x02 #define QH_MICROFRAME_2 0x04 #define QH_MICROFRAME_3 0x08 #define QH_MICROFRAME_4 0x10 #define QH_MICROFRAME_5 0x20 #define QH_MICROFRAME_6 0x40 #define QH_MICROFRAME_7 0x80 #define USB_ERR_SHORT_PACKET 0x200 // // Fill in the hardware link point: pass in a EHC_QH/QH_HW // pointer to QH_LINK; A EHC_QTD/QTD_HW pointer to QTD_LINK // #define QH_LINK(Addr, Type, Term) \ ((UINT32) ((EHC_LOW_32BIT (Addr) & 0xFFFFFFE0) | (Type) | ((Term) ? 1 : 0))) #define QTD_LINK(Addr, Term) QH_LINK((Addr), 0, (Term)) // // The defination of EHCI hardware used data structure for // little endian architecture. The QTD and QH structures // are required to be 32 bytes aligned. Don't add members // to the head of the associated software strucuture. // #pragma pack(1) typedef struct { UINT32 NextQtd; UINT32 AltNext; UINT32 Status : 8; UINT32 Pid : 2; UINT32 ErrCnt : 2; UINT32 CurPage : 3; UINT32 Ioc : 1; UINT32 TotalBytes : 15; UINT32 DataToggle : 1; UINT32 Page[5]; UINT32 PageHigh[5]; } QTD_HW; typedef struct { UINT32 HorizonLink; // // Endpoint capabilities/Characteristics DWord 1 and DWord 2 // UINT32 DeviceAddr : 7; UINT32 Inactive : 1; UINT32 EpNum : 4; UINT32 EpSpeed : 2; UINT32 DtCtrl : 1; UINT32 ReclaimHead : 1; UINT32 MaxPacketLen : 11; UINT32 CtrlEp : 1; UINT32 NakReload : 4; UINT32 SMask : 8; UINT32 CMask : 8; UINT32 HubAddr : 7; UINT32 PortNum : 7; UINT32 Multiplier : 2; // // Transaction execution overlay area // UINT32 CurQtd; UINT32 NextQtd; UINT32 AltQtd; UINT32 Status : 8; UINT32 Pid : 2; UINT32 ErrCnt : 2; UINT32 CurPage : 3; UINT32 Ioc : 1; UINT32 TotalBytes : 15; UINT32 DataToggle : 1; UINT32 Page[5]; UINT32 PageHigh[5]; } QH_HW; #pragma pack() // // Endpoint address and its capabilities // typedef struct _USB_ENDPOINT { UINT8 DevAddr; UINT8 EpAddr; // Endpoint address, no direction encoded in EFI_USB_DATA_DIRECTION Direction; UINT8 DevSpeed; UINTN MaxPacket; UINT8 HubAddr; UINT8 HubPort; UINT8 Toggle; // Data toggle, not used for control transfer UINTN Type; UINTN PollRate; // Polling interval used by EHCI } USB_ENDPOINT; // // Software QTD strcture, this is used to manage all the // QTD generated from a URB. Don't add fields before QtdHw. // struct _PEI_EHC_QTD { QTD_HW QtdHw; UINT32 Signature; EFI_LIST_ENTRY QtdList; // The list of QTDs to one end point UINT8 *Data; // Buffer of the original data UINTN DataLen; // Original amount of data in this QTD }; // // Software QH structure. All three different transaction types // supported by UEFI USB, that is the control/bulk/interrupt // transfers use the queue head and queue token strcuture. // // Interrupt QHs are linked to periodic frame list in the reversed // 2^N tree. Each interrupt QH is linked to the list starting at // frame 0. There is a dummy interrupt QH linked to each frame as // a sentinental whose polling interval is 1. Synchronous interrupt // transfer is linked after this dummy QH. // // For control/bulk transfer, only synchronous (in the sense of UEFI) // transfer is supported. A dummy QH is linked to EHCI AsyncListAddr // as the reclamation header. New transfer is inserted after this QH. // struct _PEI_EHC_QH { QH_HW QhHw; UINT32 Signature; PEI_EHC_QH *NextQh; // The queue head pointed to by horizontal link EFI_LIST_ENTRY Qtds; // The list of QTDs to this queue head UINTN Interval; }; // // URB (Usb Request Block) contains information for all kinds of // usb requests. // struct _PEI_URB { UINT32 Signature; EFI_LIST_ENTRY UrbList; // // Transaction information // USB_ENDPOINT Ep; EFI_USB_DEVICE_REQUEST *Request; // Control transfer only VOID *RequestPhy; // Address of the mapped request VOID *RequestMap; VOID *Data; UINTN DataLen; VOID *DataPhy; // Address of the mapped user data VOID *DataMap; EFI_ASYNC_USB_TRANSFER_CALLBACK Callback; VOID *Context; // // Schedule data // PEI_EHC_QH *Qh; // // Transaction result // UINT32 Result; UINTN Completed; // completed data length UINT8 DataToggle; }; /** Delete a single asynchronous interrupt transfer for the device and endpoint. @param Ehc The EHCI device. @param Data Current data not associated with a QTD. @param DataLen The length of the data. @param PktId Packet ID to use in the QTD. @param Toggle Data toggle to use in the QTD. @param MaxPacket Maximu packet length of the endpoint. @retval the pointer to the created QTD or NULL if failed to create one. **/ PEI_EHC_QTD * EhcCreateQtd ( IN PEI_USB2_HC_DEV *Ehc, IN UINT8 *Data, IN UINTN DataLen, IN UINT8 PktId, IN UINT8 Toggle, IN UINTN MaxPacket ) ; /** Allocate and initialize a EHCI queue head. @param Ehci The EHCI device. @param Ep The endpoint to create queue head for. @retval the pointer to the created queue head or NULL if failed to create one. **/ PEI_EHC_QH * EhcCreateQh ( IN PEI_USB2_HC_DEV *Ehci, IN USB_ENDPOINT *Ep ) ; /** Free an allocated URB. It is possible for it to be partially inited. @param Ehc The EHCI device. @param Urb The URB to free. **/ VOID EhcFreeUrb ( IN PEI_USB2_HC_DEV *Ehc, IN PEI_URB *Urb ) ; /** Create a new URB and its associated QTD. @param Ehc The EHCI device. @param DevAddr The device address. @param EpAddr Endpoint addrress & its direction. @param DevSpeed The device speed. @param Toggle Initial data toggle to use. @param MaxPacket The max packet length of the endpoint. @param Hub The transaction translator to use. @param Type The transaction type. @param Request The standard USB request for control transfer. @param Data The user data to transfer. @param DataLen The length of data buffer. @param Callback The function to call when data is transferred. @param Context The context to the callback. @param Interval The interval for interrupt transfer. @retval the pointer to the created URB or NULL. **/ PEI_URB * EhcCreateUrb ( IN PEI_USB2_HC_DEV *Ehc, IN UINT8 DevAddr, IN UINT8 EpAddr, IN UINT8 DevSpeed, IN UINT8 Toggle, IN UINTN MaxPacket, IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Hub, IN UINTN Type, IN EFI_USB_DEVICE_REQUEST *Request, IN VOID *Data, IN UINTN DataLen, IN EFI_ASYNC_USB_TRANSFER_CALLBACK Callback, IN VOID *Context, IN UINTN Interval ) ; #endif