3 Copyright (c) 2006, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
26 * Universal Host Controller Interface data structures and defines
29 #include <IndustryStandard/Pci22.h>
31 #define EFI_D_UHCI EFI_D_INFO
36 #define STALL_1_MILLI_SECOND 1000
37 #define STALL_1_SECOND 1000 * STALL_1_MILLI_SECOND
39 #define FORCE_GLOBAL_RESUME_TIME 20 * STALL_1_MILLI_SECOND
41 #define ROOT_PORT_REST_TIME 50 * STALL_1_MILLI_SECOND
43 #define PORT_RESET_RECOVERY_TIME 10 * STALL_1_MILLI_SECOND
48 #define INTERRUPT_POLLING_TIME 50 * 1000 * 10
51 // UHCI IO Space Address Register Register locates at
52 // offset 20 ~ 23h of PCI Configuration Space (UHCI spec, Revision 1.1),
53 // so, its BAR Index is 4.
55 #define USB_BAR_INDEX 4
58 // One memory block uses 1 page (common buffer for QH,TD use.)
60 #define NORMAL_MEMORY_BLOCK_UNIT_IN_PAGES 1
63 #define bit(a) 1 << (a)
66 // ////////////////////////////////////////////////////////////////////////
68 // Universal Host Controller Registers Definitions
70 //////////////////////////////////////////////////////////////////////////
71 extern UINT16 USBBaseAddr
;
73 /* Command register */
74 #define USBCMD 0 /* Command Register Offset 00-01h */
75 #define USBCMD_RS bit (0) /* Run/Stop */
76 #define USBCMD_HCRESET bit (1) /* Host reset */
77 #define USBCMD_GRESET bit (2) /* Global reset */
78 #define USBCMD_EGSM bit (3) /* Global Suspend Mode */
79 #define USBCMD_FGR bit (4) /* Force Global Resume */
80 #define USBCMD_SWDBG bit (5) /* SW Debug mode */
81 #define USBCMD_CF bit (6) /* Config Flag (sw only) */
82 #define USBCMD_MAXP bit (7) /* Max Packet (0 = 32, 1 = 64) */
85 #define USBSTS 2 /* Status Register Offset 02-03h */
86 #define USBSTS_USBINT bit (0) /* Interrupt due to IOC */
87 #define USBSTS_ERROR bit (1) /* Interrupt due to error */
88 #define USBSTS_RD bit (2) /* Resume Detect */
89 #define USBSTS_HSE bit (3) /* Host System Error*/
90 #define USBSTS_HCPE bit (4) /* Host Controller Process Error*/
91 #define USBSTS_HCH bit (5) /* HC Halted */
93 /* Interrupt enable register */
94 #define USBINTR 4 /* Interrupt Enable Register 04-05h */
95 #define USBINTR_TIMEOUT bit (0) /* Timeout/CRC error enable */
96 #define USBINTR_RESUME bit (1) /* Resume interrupt enable */
97 #define USBINTR_IOC bit (2) /* Interrupt On Complete enable */
98 #define USBINTR_SP bit (3) /* Short packet interrupt enable */
100 /* Frame Number Register Offset 06-08h */
103 /* Frame List Base Address Register Offset 08-0Bh */
104 #define USBFLBASEADD 8
106 /* Start of Frame Modify Register Offset 0Ch */
109 /* USB port status and control registers */
110 #define USBPORTSC1 0x10 /*Port 1 offset 10-11h */
111 #define USBPORTSC2 0x12 /*Port 2 offset 12-13h */
113 #define USBPORTSC_CCS bit (0) /* Current Connect Status*/
114 #define USBPORTSC_CSC bit (1) /* Connect Status Change */
115 #define USBPORTSC_PED bit (2) /* Port Enable / Disable */
116 #define USBPORTSC_PEDC bit (3) /* Port Enable / Disable Change */
117 #define USBPORTSC_LSL bit (4) /* Line Status Low bit*/
118 #define USBPORTSC_LSH bit (5) /* Line Status High bit*/
119 #define USBPORTSC_RD bit (6) /* Resume Detect */
120 #define USBPORTSC_LSDA bit (8) /* Low Speed Device Attached */
121 #define USBPORTSC_PR bit (9) /* Port Reset */
122 #define USBPORTSC_SUSP bit (12) /* Suspend */
124 /* PCI Configuration Registers for USB */
127 // Class Code Register offset
131 // USB IO Space Base Address Register offset
136 // USB legacy Support
138 #define USB_EMULATION 0xc0
141 // USB Base Class Code,Sub-Class Code and Programming Interface.
143 #define PCI_CLASSC_PI_UHCI 0x00
145 #define SETUP_PACKET_ID 0x2D
146 #define INPUT_PACKET_ID 0x69
147 #define OUTPUT_PACKET_ID 0xE1
148 #define ERROR_PACKET_ID 0x55
151 // ////////////////////////////////////////////////////////////////////////
153 // USB Transfer Mechanism Data Structures
155 //////////////////////////////////////////////////////////////////////////
158 // USB Class Code structure
167 UINT32 QHHorizontalTerminate
: 1;
168 UINT32 QHHorizontalQSelect
: 1;
169 UINT32 QHHorizontalRsvd
: 2;
170 UINT32 QHHorizontalPtr
: 28;
171 UINT32 QHVerticalTerminate
: 1;
172 UINT32 QHVerticalQSelect
: 1;
173 UINT32 QHVerticalRsvd
: 2;
174 UINT32 QHVerticalPtr
: 28;
178 UINT32 TDLinkPtrTerminate
: 1;
179 UINT32 TDLinkPtrQSelect
: 1;
180 UINT32 TDLinkPtrDepthSelect
: 1;
181 UINT32 TDLinkPtrRsvd
: 1;
182 UINT32 TDLinkPtr
: 28;
183 UINT32 TDStatusActualLength
: 11;
184 UINT32 TDStatusRsvd
: 5;
186 UINT32 TDStatusIOC
: 1;
187 UINT32 TDStatusIOS
: 1;
188 UINT32 TDStatusLS
: 1;
189 UINT32 TDStatusErr
: 2;
190 UINT32 TDStatusSPD
: 1;
191 UINT32 TDStatusRsvd2
: 2;
192 UINT32 TDTokenPID
: 8;
193 UINT32 TDTokenDevAddr
: 7;
194 UINT32 TDTokenEndPt
: 4;
195 UINT32 TDTokenDataToggle
: 1;
196 UINT32 TDTokenRsvd
: 1;
197 UINT32 TDTokenMaxLen
: 11;
207 VOID
*ptrNextIntQH
; // for interrupt transfer's special use
216 UINT16 TDBufferLength
;
221 // ////////////////////////////////////////////////////////////////////////
223 // Universal Host Controller Device Data Structure
225 //////////////////////////////////////////////////////////////////////////
226 #define USB_HC_DEV_FROM_THIS(a) CR (a, USB_HC_DEV, UsbHc, USB_HC_DEV_SIGNATURE)
228 #define USB_HC_DEV_SIGNATURE EFI_SIGNATURE_32 ('u', 'h', 'c', 'i')
229 #define INTERRUPT_LIST_SIGNATURE EFI_SIGNATURE_32 ('i', 'n', 't', 's')
238 TD_STRUCT
*PtrFirstTD
;
243 UINT8
*DataBuffer
; // allocated host memory, not mapped memory
244 EFI_ASYNC_USB_TRANSFER_CALLBACK InterruptCallBack
;
245 VOID
*InterruptContext
;
248 #define INTERRUPT_LIST_FROM_LINK(a) CR (a, INTERRUPT_LIST, Link, INTERRUPT_LIST_SIGNATURE)
251 UINT32 FrameListPtrTerminate
: 1;
252 UINT32 FrameListPtrQSelect
: 1;
253 UINT32 FrameListRsvd
: 2;
254 UINT32 FrameListPtr
: 28;
258 typedef struct _MEMORY_MANAGE_HEADER
{
260 UINTN BitArraySizeInBytes
;
261 UINT8
*MemoryBlockPtr
;
262 UINTN MemoryBlockSizeInBytes
;
264 struct _MEMORY_MANAGE_HEADER
*Next
;
265 } MEMORY_MANAGE_HEADER
;
269 EFI_USB_HC_PROTOCOL UsbHc
;
270 EFI_PCI_IO_PROTOCOL
*PciIo
;
275 LIST_ENTRY InterruptListHead
;
276 FRAMELIST_ENTRY
*FrameListEntry
;
277 VOID
*FrameListMapping
;
278 MEMORY_MANAGE_HEADER
*MemoryHeader
;
279 EFI_EVENT InterruptTransTimer
;
280 EFI_UNICODE_STRING_TABLE
*ControllerNameTable
;
284 extern EFI_DRIVER_BINDING_PROTOCOL gUhciDriverBinding
;
285 extern EFI_COMPONENT_NAME_PROTOCOL gUhciComponentName
;
289 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
290 IN UINT32 CmdAddrOffset
,
296 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
297 IN UINT32 CmdAddrOffset
,
303 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
304 IN UINT32 StatusAddrOffset
,
310 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
311 IN UINT32 StatusAddrOffset
,
317 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
318 IN UINT32 StatusAddrOffset
322 ReadUHCFrameNumberReg (
323 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
324 IN UINT32 FrameNumAddrOffset
,
329 WriteUHCFrameListBaseReg (
330 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
331 IN UINT32 FlBaseAddrOffset
,
332 IN UINT32 UsbFrameListBaseAddr
337 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
338 IN UINT32 PortAddrOffset
,
344 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
345 IN UINT32 PortAddrOffset
,
346 IN UINT16 ControlBits
351 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
352 IN UINT32 StatusRegAddr
,
358 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
359 IN UINT32 StatusRegAddr
363 IsHostSysOrProcessErr (
364 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
365 IN UINT32 StatusRegAddr
369 // This routine programs the USB frame number register. We assume that the
370 // HC schedule execution is stopped.
374 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
380 GetCurrentFrameNumber (
381 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
386 SetFrameListBaseAddress (
387 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
388 IN UINT32 FLBASEADDRReg
,
393 GetFrameListBaseAddress (
394 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
400 IN USB_HC_DEV
*HcDev
,
401 IN UINT32 FLBASEADDRReg
406 IN USB_HC_DEV
*UhcDev
417 IN USB_HC_DEV
*HcDev
,
418 OUT QH_STRUCT
**pptrQH
422 SetQHHorizontalLinkPtr (
428 GetQHHorizontalLinkPtr (
433 SetQHHorizontalQHorTDSelect (
439 SetQHHorizontalValidorInvalid (
445 SetQHVerticalLinkPtr (
451 GetQHVerticalLinkPtr (
456 SetQHVerticalQHorTDSelect (
462 IsQHHorizontalQHSelect (
467 SetQHVerticalValidorInvalid (
473 GetQHVerticalValidorInvalid (
479 IN USB_HC_DEV
*HcDev
,
480 OUT TD_STRUCT
**ppTDStruct
491 ppTDStruct - place to store TD_STRUCT pointer
500 IN USB_HC_DEV
*HcDev
,
501 OUT TD_STRUCT
**pptrTD
512 pptrTD - TD_STRUCT pointer to store
516 EFI_OUT_OF_RESOURCES - Can't allocate resources
517 EFI_SUCCESS - Success
524 IN USB_HC_DEV
*HcDev
,
536 Generate Setup Stage TD
541 DevAddr - Device address
542 Endpoint - Endpoint number
543 bSlow - Full speed or low speed
544 pDevReq - Device request
545 RequestLen - Request length
546 ppTD - TD_STRUCT to return
549 EFI_OUT_OF_RESOURCES - Can't allocate memory
550 EFI_SUCCESS - Success
556 IN USB_HC_DEV
*HcDev
,
570 Generate Data Stage TD
575 DevAddr - Device address
576 Endpoint - Endpoint number
580 Toggle - Data toggle value
581 bSlow - Full speed or low speed
582 ppTD - TD_STRUCT to return
585 EFI_OUT_OF_RESOURCES - Can't allocate memory
586 EFI_SUCCESS - Success
592 IN USB_HC_DEV
*HcDev
,
603 Generate Setup Stage TD
608 DevAddr - Device address
609 Endpoint - Endpoint number
610 bSlow - Full speed or low speed
611 pDevReq - Device request
612 RequestLen - Request length
613 ppTD - TD_STRUCT to return
616 EFI_OUT_OF_RESOURCES - Can't allocate memory
617 EFI_SUCCESS - Success
622 SetTDLinkPtrValidorInvalid (
623 IN TD_STRUCT
*ptrTDStruct
,
628 SetTDLinkPtrQHorTDSelect (
629 IN TD_STRUCT
*ptrTDStruct
,
634 SetTDLinkPtrDepthorBreadth (
635 IN TD_STRUCT
*ptrTDStruct
,
641 IN TD_STRUCT
*ptrTDStruct
,
647 IN TD_STRUCT
*ptrTDStruct
651 EnableorDisableTDShortPacket (
652 IN TD_STRUCT
*ptrTDStruct
,
657 SetTDControlErrorCounter (
658 IN TD_STRUCT
*ptrTDStruct
,
663 SetTDLoworFullSpeedDevice (
664 IN TD_STRUCT
*ptrTDStruct
,
665 IN BOOLEAN bLowSpeedDevice
669 SetTDControlIsochronousorNot (
670 IN TD_STRUCT
*ptrTDStruct
,
671 IN BOOLEAN bIsochronous
675 SetorClearTDControlIOC (
676 IN TD_STRUCT
*ptrTDStruct
,
681 SetTDStatusActiveorInactive (
682 IN TD_STRUCT
*ptrTDStruct
,
687 SetTDTokenMaxLength (
688 IN TD_STRUCT
*ptrTDStruct
,
693 SetTDTokenDataToggle1 (
694 IN TD_STRUCT
*ptrTDStruct
698 SetTDTokenDataToggle0 (
699 IN TD_STRUCT
*ptrTDStruct
703 GetTDTokenDataToggle (
704 IN TD_STRUCT
*ptrTDStruct
709 IN TD_STRUCT
*ptrTDStruct
,
714 SetTDTokenDeviceAddress (
715 IN TD_STRUCT
*ptrTDStruct
,
721 IN TD_STRUCT
*ptrTDStruct
,
727 IN TD_STRUCT
*ptrTDStruct
732 IN TD_STRUCT
*ptrTDStruct
737 IN TD_STRUCT
*ptrTDStruct
741 IsTDStatusBufferError (
742 IN TD_STRUCT
*ptrTDStruct
746 IsTDStatusBabbleError (
747 IN TD_STRUCT
*ptrTDStruct
751 IsTDStatusNAKReceived (
752 IN TD_STRUCT
*ptrTDStruct
756 IsTDStatusCRCTimeOutError (
757 IN TD_STRUCT
*ptrTDStruct
761 IsTDStatusBitStuffError (
762 IN TD_STRUCT
*ptrTDStruct
766 GetTDStatusActualLength (
767 IN TD_STRUCT
*ptrTDStruct
771 GetTDTokenMaxLength (
772 IN TD_STRUCT
*ptrTDStruct
777 IN TD_STRUCT
*ptrTDStruct
781 GetTDTokenDeviceAddress (
782 IN TD_STRUCT
*ptrTDStruct
787 IN TD_STRUCT
*ptrTDStruct
792 IN TD_STRUCT
*ptrTDStruct
796 GetTDLinkPtrValidorInvalid (
797 IN TD_STRUCT
*ptrTDStruct
802 IN TD_STRUCT
*ptrFirstTD
813 IN TD_STRUCT
*ptrPreTD
,
818 SetorClearCurFrameListTerminate (
819 IN FRAMELIST_ENTRY
*pCurEntry
,
824 SetCurFrameListQHorTD (
825 IN FRAMELIST_ENTRY
*pCurEntry
,
830 GetCurFrameListTerminate (
831 IN FRAMELIST_ENTRY
*pCurEntry
835 SetCurFrameListPointer (
836 IN FRAMELIST_ENTRY
*pCurEntry
,
841 GetCurFrameListPointer (
842 IN FRAMELIST_ENTRY
*pCurEntry
847 IN FRAMELIST_ENTRY
*pEntry
,
848 IN UINT16 FrameListIndex
,
855 Link QH To Frame List
859 pEntry - FRAMELIST_ENTRY
860 FrameListIndex - Frame List Index
869 IN FRAMELIST_ENTRY
*pEntry
,
871 IN TD_STRUCT
*ptrFirstTD
,
872 IN UINT16 FrameListIndex
,
873 IN BOOLEAN SearchOther
878 IN USB_HC_DEV
*HcDev
,
880 IN UINT16 FrameListIndex
,
881 IN BOOLEAN SearchOther
,
887 IN USB_HC_DEV
*HcDev
,
888 IN TD_STRUCT
*ptrFirstTD
892 InsertQHTDToINTList (
893 IN USB_HC_DEV
*HcDev
,
895 IN TD_STRUCT
*ptrFirstTD
,
896 IN UINT8 DeviceAddress
,
897 IN UINT8 EndPointAddress
,
900 IN UINTN PollingInterval
,
902 IN UINT8
*DataBuffer
,
903 IN EFI_ASYNC_USB_TRANSFER_CALLBACK CallBackFunction
,
908 Insert QH and TD To Interrupt List
913 PtrFirstTD - First TD_STRUCT
914 DeviceAddress - Device Address
915 EndPointAddress - EndPoint Address
916 DataToggle - Data Toggle
917 DataLength - Data length
918 PollingInterval - Polling Interval when inserted to frame list
919 Mapping - Mapping alue
920 DataBuffer - Data buffer
921 CallBackFunction- CallBackFunction after interrupt transfeer
922 Context - CallBackFunction Context passed as function parameter
925 EFI_INVALID_PARAMETER - Paremeter is error
930 DeleteAsyncINTQHTDs (
931 IN USB_HC_DEV
*HcDev
,
932 IN UINT8 DeviceAddress
,
933 IN UINT8 EndPointAddress
,
934 OUT UINT8
*DataToggle
939 Delete Async INT QH and TDs
943 DeviceAddress - Device Address
944 EndPointAddress - EndPoint Address
945 DataToggle - Data Toggle
949 EFI_INVALID_PARAMETER - Paremeter is error
955 IN UINTN RequiredLen
,
958 OUT UINTN
*ActualTransferSize
968 PtrTD - TD_STRUCT to check
969 RequiredLen - Required Len
970 Result - Transfer result
971 ErrTDPos - Error TD Position
972 ActualTransferSize - Actual Transfer Size
982 IN USB_HC_DEV
*HcDev
,
983 IN INTERRUPT_LIST
*ptrList
,
992 Execute Async Interrupt TDs
997 PtrList - INTERRUPT_LIST
998 Result - Transfer result
999 ErrTDPos - Error TD Position
1000 ActualTransferSize - Actual Transfer Size
1008 UpdateAsyncINTQHTDs (
1009 IN INTERRUPT_LIST
*ptrList
,
1015 Routine Description:
1017 Update Async Interrupt QH and TDs
1021 PtrList - INTERRUPT_LIST
1022 Result - Transfer reslut
1023 ErrTDPos - Error TD Position
1031 ReleaseInterruptList (
1032 IN USB_HC_DEV
*HcDev
,
1033 IN LIST_ENTRY
*ListHead
1037 Routine Description:
1039 Release Interrupt List
1043 ListHead - List head
1051 ExecuteControlTransfer (
1052 IN USB_HC_DEV
*HcDev
,
1053 IN TD_STRUCT
*ptrTD
,
1055 OUT UINTN
*ActualLen
,
1057 OUT UINT32
*TransferResult
1061 Routine Description:
1063 Execute Control Transfer
1070 ActualLen - Actual transfered Len
1071 TimeOut - TimeOut value in milliseconds
1072 TransferResult - Transfer result
1075 EFI_SUCCESS - Sucess
1076 EFI_DEVICE_ERROR - Error
1081 ExecBulkorSyncInterruptTransfer (
1082 IN USB_HC_DEV
*HcDev
,
1083 IN TD_STRUCT
*ptrTD
,
1085 OUT UINTN
*ActualLen
,
1086 OUT UINT8
*DataToggle
,
1088 OUT UINT32
*TransferResult
1092 Routine Description:
1094 Execute Bulk or SyncInterrupt Transfer
1101 ActualLen - Actual transfered Len
1102 DataToggle - Data Toggle
1103 TimeOut - TimeOut value in milliseconds
1104 TransferResult - Transfer result
1107 EFI_SUCCESS - Sucess
1108 EFI_DEVICE_ERROR - Error
1112 InitializeMemoryManagement (
1113 IN USB_HC_DEV
*HcDev
1118 IN USB_HC_DEV
*HcDev
,
1119 IN MEMORY_MANAGE_HEADER
**MemoryHeader
,
1120 IN UINTN MemoryBlockSizeInPages
1125 IN USB_HC_DEV
*HcDev
,
1126 IN MEMORY_MANAGE_HEADER
*MemoryHeader
1131 IN USB_HC_DEV
*UhcDev
,
1138 IN USB_HC_DEV
*HcDev
,
1144 InsertMemoryHeaderToList (
1145 IN MEMORY_MANAGE_HEADER
*MemoryHeader
,
1146 IN MEMORY_MANAGE_HEADER
*NewMemoryHeader
1150 AllocMemInMemoryBlock (
1151 IN MEMORY_MANAGE_HEADER
*MemoryHeader
,
1153 IN UINTN NumberOfMemoryUnit
1157 IsMemoryBlockEmptied (
1158 IN MEMORY_MANAGE_HEADER
*MemoryHeaderPtr
1163 IN MEMORY_MANAGE_HEADER
*FirstMemoryHeader
,
1164 IN MEMORY_MANAGE_HEADER
*FreeMemoryHeader
1168 DelMemoryManagement (
1169 IN USB_HC_DEV
*HcDev
1173 EnableMaxPacketSize (
1174 IN USB_HC_DEV
*HcDev
1178 CleanUsbTransactions (
1179 IN USB_HC_DEV
*HcDev
1183 TurnOffUSBEmulation (
1184 IN EFI_PCI_IO_PROTOCOL
*PciIo