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 GLOBAL_REMOVE_IF_UNREFERENCED UINTN gEHCDebugLevel
= EFI_D_INFO
;
27 GLOBAL_REMOVE_IF_UNREFERENCED UINTN gEHCErrorLevel
= EFI_D_ERROR
;
32 // Driver model protocol interface
37 EhciDriverBindingSupported (
38 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
39 IN EFI_HANDLE Controller
,
40 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
45 EhciDriverBindingStart (
46 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
47 IN EFI_HANDLE Controller
,
48 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
53 EhciDriverBindingStop (
54 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
55 IN EFI_HANDLE Controller
,
56 IN UINTN NumberOfChildren
,
57 IN EFI_HANDLE
*ChildHandleBuffer
61 // Ehci protocol interface
66 IN EFI_USB2_HC_PROTOCOL
*This
,
68 OUT UINT8
*PortNumber
,
69 OUT UINT8
*Is64BitCapable
75 IN EFI_USB2_HC_PROTOCOL
*This
,
82 IN EFI_USB2_HC_PROTOCOL
*This
,
83 OUT EFI_USB_HC_STATE
*State
89 IN EFI_USB2_HC_PROTOCOL
*This
,
90 IN EFI_USB_HC_STATE State
96 IN EFI_USB2_HC_PROTOCOL
*This
,
97 IN UINT8 DeviceAddress
,
99 IN UINTN MaximumPacketLength
,
100 IN EFI_USB_DEVICE_REQUEST
*Request
,
101 IN EFI_USB_DATA_DIRECTION TransferDirection
,
103 IN OUT UINTN
*DataLength
,
105 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
106 OUT UINT32
*TransferResult
112 IN EFI_USB2_HC_PROTOCOL
*This
,
113 IN UINT8 DeviceAddress
,
114 IN UINT8 EndPointAddress
,
115 IN UINT8 DeviceSpeed
,
116 IN UINTN MaximumPacketLength
,
117 IN UINT8 DataBuffersNumber
,
118 IN OUT VOID
*Data
[EFI_USB_MAX_BULK_BUFFER_NUM
],
119 IN OUT UINTN
*DataLength
,
120 IN OUT UINT8
*DataToggle
,
122 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
123 OUT UINT32
*TransferResult
128 EhciAsyncInterruptTransfer (
129 IN EFI_USB2_HC_PROTOCOL
* This
,
130 IN UINT8 DeviceAddress
,
131 IN UINT8 EndPointAddress
,
132 IN UINT8 DeviceSpeed
,
133 IN UINTN MaxiumPacketLength
,
134 IN BOOLEAN IsNewTransfer
,
135 IN OUT UINT8
*DataToggle
,
136 IN UINTN PollingInterval
,
138 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
139 IN EFI_ASYNC_USB_TRANSFER_CALLBACK CallBackFunction
,
140 IN VOID
*Context OPTIONAL
145 EhciSyncInterruptTransfer (
146 IN EFI_USB2_HC_PROTOCOL
*This
,
147 IN UINT8 DeviceAddress
,
148 IN UINT8 EndPointAddress
,
149 IN UINT8 DeviceSpeed
,
150 IN UINTN MaximumPacketLength
,
152 IN OUT UINTN
*DataLength
,
153 IN OUT UINT8
*DataToggle
,
155 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
156 OUT UINT32
*TransferResult
161 EhciIsochronousTransfer (
162 IN EFI_USB2_HC_PROTOCOL
*This
,
163 IN UINT8 DeviceAddress
,
164 IN UINT8 EndPointAddress
,
165 IN UINT8 DeviceSpeed
,
166 IN UINTN MaximumPacketLength
,
167 IN UINT8 DataBuffersNumber
,
168 IN OUT VOID
*Data
[EFI_USB_MAX_ISO_BUFFER_NUM
],
170 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
171 OUT UINT32
*TransferResult
176 EhciAsyncIsochronousTransfer (
177 IN EFI_USB2_HC_PROTOCOL
*This
,
178 IN UINT8 DeviceAddress
,
179 IN UINT8 EndPointAddress
,
180 IN UINT8 DeviceSpeed
,
181 IN UINTN MaximumPacketLength
,
182 IN UINT8 DataBuffersNumber
,
183 IN OUT VOID
*Data
[EFI_USB_MAX_ISO_BUFFER_NUM
],
185 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
186 IN EFI_ASYNC_USB_TRANSFER_CALLBACK IsochronousCallBack
,
192 EhciGetRootHubPortStatus (
193 IN EFI_USB2_HC_PROTOCOL
*This
,
195 OUT EFI_USB_PORT_STATUS
*PortStatus
200 EhciSetRootHubPortFeature (
201 IN EFI_USB2_HC_PROTOCOL
*This
,
203 IN EFI_USB_PORT_FEATURE PortFeature
208 EhciClearRootHubPortFeature (
209 IN EFI_USB2_HC_PROTOCOL
*This
,
211 IN EFI_USB_PORT_FEATURE PortFeature
215 // Ehci Driver Global Variables
217 EFI_DRIVER_BINDING_PROTOCOL gEhciDriverBinding
= {
218 EhciDriverBindingSupported
,
219 EhciDriverBindingStart
,
220 EhciDriverBindingStop
,
226 UINT32 mUsbCapabilityLen
;
227 UINT32 mDeviceSpeed
[16];
231 EhciDriverBindingSupported (
232 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
233 IN EFI_HANDLE Controller
,
234 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
240 Test to see if this driver supports ControllerHandle. Any ControllerHandle
241 that has Usb2HcProtocol installed will be supported.
245 This - Protocol instance pointer.
246 Controlle - Handle of device to test
247 RemainingDevicePath - Not used
251 EFI_SUCCESS This driver supports this device.
252 EFI_UNSUPPORTED This driver does not support this device.
257 EFI_PCI_IO_PROTOCOL
*PciIo
;
258 USB_CLASSC UsbClassCReg
;
262 // Test whether there is PCI IO Protocol attached on the controller handle.
264 Status
= gBS
->OpenProtocol (
266 &gEfiPciIoProtocolGuid
,
268 This
->DriverBindingHandle
,
270 EFI_OPEN_PROTOCOL_BY_DRIVER
272 if (EFI_ERROR (Status
)) {
276 Status
= PciIo
->Pci
.Read (
280 sizeof (USB_CLASSC
) / sizeof (UINT8
),
283 if (EFI_ERROR (Status
)) {
286 &gEfiPciIoProtocolGuid
,
287 This
->DriverBindingHandle
,
290 Status
= EFI_UNSUPPORTED
;
295 // Test whether the controller belongs to Ehci type
297 if ((UsbClassCReg
.BaseCode
!= PCI_CLASS_SERIAL
) ||
298 (UsbClassCReg
.SubClassCode
!= PCI_CLASS_SERIAL_USB
) ||
299 (UsbClassCReg
.PI
!= PCI_CLASSC_PI_EHCI
)
304 &gEfiPciIoProtocolGuid
,
305 This
->DriverBindingHandle
,
309 Status
= EFI_UNSUPPORTED
;
315 &gEfiPciIoProtocolGuid
,
316 This
->DriverBindingHandle
,
326 EhciDriverBindingStart (
327 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
328 IN EFI_HANDLE Controller
,
329 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
335 Starting the Usb EHCI Driver
339 This - Protocol instance pointer.
340 Controller - Handle of device to test
341 RemainingDevicePath - Not used
345 EFI_SUCCESS supports this device.
346 EFI_UNSUPPORTED do not support this device.
347 EFI_DEVICE_ERROR cannot be started due to device Error
348 EFI_OUT_OF_RESOURCES cannot allocate resources
354 EFI_PCI_IO_PROTOCOL
*PciIo
;
357 UINT8 Is64BitCapable
;
360 // Open the PciIo Protocol
362 Status
= gBS
->OpenProtocol (
364 &gEfiPciIoProtocolGuid
,
366 This
->DriverBindingHandle
,
368 EFI_OPEN_PROTOCOL_BY_DRIVER
370 if (EFI_ERROR (Status
)) {
371 Status
= EFI_OUT_OF_RESOURCES
;
376 // Enable the USB Host Controller
378 Status
= PciIo
->Attributes (
380 EfiPciIoAttributeOperationEnable
,
381 EFI_PCI_DEVICE_ENABLE
,
384 if (EFI_ERROR (Status
)) {
385 Status
= EFI_OUT_OF_RESOURCES
;
386 goto close_pciio_protocol
;
390 // Allocate memory for EHC private data structure
392 HcDev
= AllocateZeroPool (sizeof (USB2_HC_DEV
));
394 Status
= EFI_OUT_OF_RESOURCES
;
395 goto close_pciio_protocol
;
399 // Init EFI_USB2_HC_PROTOCOL interface and private data structure
401 HcDev
->Usb2Hc
.GetCapability
= EhciGetCapability
;
402 HcDev
->Usb2Hc
.Reset
= EhciReset
;
403 HcDev
->Usb2Hc
.GetState
= EhciGetState
;
404 HcDev
->Usb2Hc
.SetState
= EhciSetState
;
405 HcDev
->Usb2Hc
.ControlTransfer
= EhciControlTransfer
;
406 HcDev
->Usb2Hc
.BulkTransfer
= EhciBulkTransfer
;
407 HcDev
->Usb2Hc
.AsyncInterruptTransfer
= EhciAsyncInterruptTransfer
;
408 HcDev
->Usb2Hc
.SyncInterruptTransfer
= EhciSyncInterruptTransfer
;
409 HcDev
->Usb2Hc
.IsochronousTransfer
= EhciIsochronousTransfer
;
410 HcDev
->Usb2Hc
.AsyncIsochronousTransfer
= EhciAsyncIsochronousTransfer
;
411 HcDev
->Usb2Hc
.GetRootHubPortStatus
= EhciGetRootHubPortStatus
;
412 HcDev
->Usb2Hc
.SetRootHubPortFeature
= EhciSetRootHubPortFeature
;
413 HcDev
->Usb2Hc
.ClearRootHubPortFeature
= EhciClearRootHubPortFeature
;
414 HcDev
->Usb2Hc
.MajorRevision
= 0x1;
415 HcDev
->Usb2Hc
.MinorRevision
= 0x1;
417 HcDev
->AsyncRequestList
= NULL
;
418 HcDev
->ControllerNameTable
= NULL
;
419 HcDev
->Signature
= USB2_HC_DEV_SIGNATURE
;
420 HcDev
->PciIo
= PciIo
;
423 // Install USB2_HC_PROTOCOL
425 Status
= gBS
->InstallProtocolInterface (
427 &gEfiUsb2HcProtocolGuid
,
428 EFI_NATIVE_INTERFACE
,
431 if (EFI_ERROR (Status
)) {
432 Status
= EFI_OUT_OF_RESOURCES
;
437 // Get Capability Register Length
439 Status
= GetCapabilityLen (HcDev
);
440 if (EFI_ERROR (Status
)) {
441 Status
= EFI_DEVICE_ERROR
;
442 goto uninstall_usb2hc_protocol
;
446 // Create and Init Perodic Frame List
448 Status
= EhciGetCapability (
454 if (EFI_ERROR (Status
)) {
455 Status
= EFI_OUT_OF_RESOURCES
;
456 goto uninstall_usb2hc_protocol
;
458 HcDev
->Is64BitCapable
= Is64BitCapable
;
461 // Create and Init Perodic Frame List
463 Status
= InitialPeriodicFrameList (
465 EHCI_MAX_FRAME_LIST_LENGTH
467 if (EFI_ERROR (Status
)) {
468 Status
= EFI_OUT_OF_RESOURCES
;
469 goto uninstall_usb2hc_protocol
;
473 // Init memory pool management
475 Status
= InitialMemoryManagement (HcDev
);
476 if (EFI_ERROR (Status
)) {
477 Status
= EFI_OUT_OF_RESOURCES
;
478 goto deinit_perodic_frame_list
;
482 // Create AsyncRequest Polling Timer
484 Status
= CreatePollingTimer (HcDev
, (EFI_EVENT_NOTIFY
) AsyncRequestMoniter
);
485 if (EFI_ERROR (Status
)) {
486 Status
= EFI_OUT_OF_RESOURCES
;
487 goto deinit_memory_management
;
491 // Default Maxximum Interrupt Interval is 8,
492 // it means that 8 micro frame = 1ms
496 // Start the Host Controller
498 if (IsEhcHalted (HcDev
)) {
499 Status
= StartScheduleExecution (HcDev
);
500 if (EFI_ERROR (Status
)) {
501 Status
= EFI_DEVICE_ERROR
;
507 // Set all ports routing to EHC
509 Status
= SetPortRoutingEhc (HcDev
);
510 if (EFI_ERROR (Status
)) {
511 Status
= EFI_DEVICE_ERROR
;
516 // Component name protocol
518 Status
= AddUnicodeString (
520 gEhciComponentName
.SupportedLanguages
,
521 &HcDev
->ControllerNameTable
,
522 L
"Usb Enhanced Host Controller"
524 if (EFI_ERROR (Status
)) {
525 Status
= EFI_OUT_OF_RESOURCES
;
532 // Error handle process
535 DestoryPollingTimer (HcDev
);
536 deinit_memory_management
:
537 DeinitialMemoryManagement (HcDev
);
538 deinit_perodic_frame_list
:
539 DeinitialPeriodicFrameList (HcDev
);
540 uninstall_usb2hc_protocol
:
541 gBS
->UninstallProtocolInterface (
543 &gEfiUsb2HcProtocolGuid
,
547 gBS
->FreePool (HcDev
);
548 close_pciio_protocol
:
551 &gEfiPciIoProtocolGuid
,
552 This
->DriverBindingHandle
,
562 EhciDriverBindingStop (
563 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
564 IN EFI_HANDLE Controller
,
565 IN UINTN NumberOfChildren
,
566 IN EFI_HANDLE
*ChildHandleBuffer
572 Stop this driver on ControllerHandle. Support stoping any child handles
573 created by this driver.
577 This - Protocol instance pointer.
578 Controller - Handle of device to stop driver on
579 NumberOfChildren - Number of Children in the ChildHandleBuffer
580 ChildHandleBuffer - List of handles for the children we need to stop.
585 EFI_DEVICE_ERROR Fail
589 EFI_USB2_HC_PROTOCOL
*Usb2Hc
;
593 // Test whether the Controller handler passed in is a valid
594 // Usb controller handle that should be supported, if not,
595 // return the error status directly
597 Status
= gBS
->OpenProtocol (
599 &gEfiUsb2HcProtocolGuid
,
601 This
->DriverBindingHandle
,
603 EFI_OPEN_PROTOCOL_GET_PROTOCOL
605 if (EFI_ERROR (Status
)) {
606 Status
= EFI_DEVICE_ERROR
;
610 HcDev
= USB2_HC_DEV_FROM_THIS (Usb2Hc
);
613 // free all the controller related memory and uninstall UHCI Protocol.
615 Status
= gBS
->UninstallProtocolInterface (
617 &gEfiUsb2HcProtocolGuid
,
620 if (EFI_ERROR (Status
)) {
621 Status
= EFI_DEVICE_ERROR
;
626 // Set Host Controller state as halt
628 Status
= Usb2Hc
->SetState (
632 if (EFI_ERROR (Status
)) {
633 Status
= EFI_DEVICE_ERROR
;
638 // Stop AsyncRequest Polling Timer
640 Status
= StopPollingTimer (HcDev
);
641 if (EFI_ERROR (Status
)) {
642 Status
= EFI_DEVICE_ERROR
;
647 // Destroy Asynchronous Request Event
649 DestoryPollingTimer (HcDev
);
652 // Destroy Perodic Frame List
654 DeinitialPeriodicFrameList (HcDev
);
657 // Deinit Ehci pool memory management
659 DeinitialMemoryManagement (HcDev
);
662 // Denint Unicode String Table
664 FreeUnicodeStringTable (HcDev
->ControllerNameTable
);
667 // Disable the USB Host Controller
669 Status
= HcDev
->PciIo
->Attributes (
671 EfiPciIoAttributeOperationDisable
,
672 EFI_PCI_DEVICE_ENABLE
,
675 if (EFI_ERROR (Status
)) {
676 Status
= EFI_DEVICE_ERROR
;
680 gBS
->FreePool (HcDev
);
684 &gEfiPciIoProtocolGuid
,
685 This
->DriverBindingHandle
,
696 IN EFI_USB2_HC_PROTOCOL
*This
,
698 OUT UINT8
*PortNumber
,
699 OUT UINT8
*Is64BitCapable
705 Retrieves the capablility of root hub ports.
709 This - A pointer to the EFI_USB_HC_PROTOCOL instance.
710 MaxSpeed - A pointer to the number of the host controller.
711 PortNumber - A pointer to the number of the root hub ports.
712 Is64BitCapable - A pointer to the flag for whether controller supports
713 64-bit memory addressing.
717 EFI_SUCCESS host controller capability were retrieved successfully.
718 EFI_INVALID_PARAMETER MaxSpeed or PortNumber or Is64BitCapable is NULL.
719 EFI_DEVICE_ERROR An error was encountered while attempting to retrieve the capabilities.
725 UINT32 HcStructParamsAddr
;
726 UINT32 HcStructParamsReg
;
727 UINT32 HcCapParamsAddr
;
728 UINT32 HcCapParamsReg
;
730 if (MaxSpeed
== NULL
|| PortNumber
== NULL
|| Is64BitCapable
== NULL
) {
731 Status
= EFI_INVALID_PARAMETER
;
735 HcStructParamsAddr
= HCSPARAMS
;
736 HcCapParamsAddr
= HCCPARAMS
;
737 HcDev
= USB2_HC_DEV_FROM_THIS (This
);
739 Status
= ReadEhcCapabiltiyReg (
744 if (EFI_ERROR (Status
)) {
745 Status
= EFI_DEVICE_ERROR
;
749 Status
= ReadEhcCapabiltiyReg (
754 if (EFI_ERROR (Status
)) {
755 Status
= EFI_DEVICE_ERROR
;
759 *MaxSpeed
= EFI_USB_SPEED_HIGH
;
760 *PortNumber
= (UINT8
) (HcStructParamsReg
& HCSP_NPORTS
);
761 *Is64BitCapable
= (UINT8
) (HcCapParamsReg
& HCCP_64BIT
);
770 IN EFI_USB2_HC_PROTOCOL
*This
,
777 Provides software reset for the USB host controller.
781 This - A pointer to the EFI_USB2_HC_PROTOCOL instance.
782 Attributes - A bit mask of the reset operation to perform.
783 See below for a list of the supported bit mask values.
785 #define EFI_USB_HC_RESET_GLOBAL 0x0001
786 #define EFI_USB_HC_RESET_HOST_CONTROLLER 0x0002
787 #define EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG 0x0004
788 #define EFI_USB_HC_RESET_HOST_WITH_DEBUG 0x0008
790 EFI_USB_HC_RESET_GLOBAL
791 If this bit is set, a global reset signal will be sent to the USB bus.
792 This resets all of the USB bus logic, including the USB host
793 controller hardware and all the devices attached on the USB bus.
794 EFI_USB_HC_RESET_HOST_CONTROLLER
795 If this bit is set, the USB host controller hardware will be reset.
796 No reset signal will be sent to the USB bus.
797 EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG
798 If this bit is set, a global reset signal will be sent to the USB bus.
799 This resets all of the USB bus logic, including the USB host
800 controller hardware and all the devices attached on the USB bus.
801 If this is an EHCI controller and the debug port has configured, then
802 this is will still reset the host controller.
803 EFI_USB_HC_RESET_HOST_WITH_DEBUG
804 If this bit is set, the USB host controller hardware will be reset.
805 If this is an EHCI controller and the debug port has been configured,
806 then this will still reset the host controller.
811 The reset operation succeeded.
812 EFI_INVALID_PARAMETER
813 Attributes is not valid.
815 The type of reset specified by Attributes is not currently supported by
816 the host controller hardware.
818 Reset operation is rejected due to the debug port being configured and
819 active; only EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG or
820 EFI_USB_HC_RESET_HOST_WITH_DEBUG reset Atrributes can be used to
821 perform reset operation for this host controller.
823 An error was encountered while attempting to perform
831 FRAME_LIST_ENTRY
*FrameEntryPtr
;
833 HcDev
= USB2_HC_DEV_FROM_THIS (This
);
835 switch (Attributes
) {
837 case EFI_USB_HC_RESET_GLOBAL
:
840 // Same behavior as Host Controller Reset
843 case EFI_USB_HC_RESET_HOST_CONTROLLER
:
846 // Host Controller must be Halt when Reset it
848 if (IsEhcHalted (HcDev
)) {
849 Status
= ResetEhc (HcDev
);
850 if (EFI_ERROR (Status
)) {
851 Status
= EFI_DEVICE_ERROR
;
855 // Set to zero by Host Controller when reset process completes
857 Status
= WaitForEhcReset (HcDev
, EHCI_GENERIC_TIMEOUT
);
858 if (EFI_ERROR (Status
)) {
859 Status
= EFI_TIMEOUT
;
863 Status
= EFI_DEVICE_ERROR
;
868 // only asynchronous interrupt transfers are always alive on the bus, need to cleanup
870 CleanUpAllAsyncRequestTransfer (HcDev
);
871 Status
= ClearEhcAllStatus (HcDev
);
872 if (EFI_ERROR (Status
)) {
873 Status
= EFI_DEVICE_ERROR
;
878 // Set appropriate 4G Segment Selector
880 Status
= SetCtrlDataStructSeg (HcDev
);
881 if (EFI_ERROR (Status
)) {
882 Status
= EFI_DEVICE_ERROR
;
887 // Init Perodic List Base Addr and Frame List
889 Status
= SetFrameListBaseAddr (
891 (UINT32
)GET_0B_TO_31B (HcDev
->PeriodicFrameListBuffer
)
893 if (EFI_ERROR (Status
)) {
894 Status
= EFI_DEVICE_ERROR
;
897 FrameEntryPtr
= (FRAME_LIST_ENTRY
*) HcDev
->PeriodicFrameListBuffer
;
898 for (FrameIndex
= 0; FrameIndex
< HcDev
->PeriodicFrameListLength
; FrameIndex
++) {
899 FrameEntryPtr
->LinkTerminate
= TRUE
;
904 // Start the Host Controller
906 if (IsEhcHalted (HcDev
)) {
907 Status
= StartScheduleExecution (HcDev
);
908 if (EFI_ERROR (Status
)) {
909 Status
= EFI_DEVICE_ERROR
;
915 // Set all ports routing to EHC
917 Status
= SetPortRoutingEhc (HcDev
);
918 if (EFI_ERROR (Status
)) {
919 Status
= EFI_DEVICE_ERROR
;
924 case EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG
:
926 Status
= EFI_UNSUPPORTED
;
929 case EFI_USB_HC_RESET_HOST_WITH_DEBUG
:
931 Status
= EFI_UNSUPPORTED
;
935 Status
= EFI_INVALID_PARAMETER
;
945 IN EFI_USB2_HC_PROTOCOL
*This
,
946 OUT EFI_USB_HC_STATE
*State
952 Retrieves current state of the USB host controller.
956 This A pointer to the EFI_USB2_HC_PROTOCOL instance.
957 State A pointer to the EFI_USB_HC_STATE data structure that
958 indicates current state of the USB host controller.
959 Type EFI_USB_HC_STATE is defined below.
963 EfiUsbHcStateOperational,
964 EfiUsbHcStateSuspend,
971 The state information of the host controller was returned in State.
972 EFI_INVALID_PARAMETER
975 An error was encountered while attempting to retrieve the
976 host controller's current state.
981 UINT32 UsbStatusAddr
;
985 Status
= EFI_INVALID_PARAMETER
;
989 UsbStatusAddr
= USBSTS
;
990 HcDev
= USB2_HC_DEV_FROM_THIS (This
);
992 Status
= ReadEhcOperationalReg (
997 if (EFI_ERROR (Status
)) {
998 Status
= EFI_DEVICE_ERROR
;
1002 if (UsbStatusReg
& USBSTS_HCH
) {
1003 *State
= EfiUsbHcStateHalt
;
1005 *State
= EfiUsbHcStateOperational
;
1015 IN EFI_USB2_HC_PROTOCOL
*This
,
1016 IN EFI_USB_HC_STATE State
1020 Routine Description:
1022 Sets the USB host controller to a specific state.
1026 This - A pointer to the EFI_USB2_HC_PROTOCOL instance.
1027 State - Indicates the state of the host controller that will be set.
1032 The USB host controller was successfully placed in the state
1034 EFI_INVALID_PARAMETER
1037 Failed to set the state specified by State due to device error.
1043 UINT32 UsbCommandAddr
;
1044 UINT32 UsbCommandReg
;
1045 EFI_USB_HC_STATE CurrentState
;
1047 UsbCommandAddr
= USBCMD
;
1048 HcDev
= USB2_HC_DEV_FROM_THIS (This
);
1050 Status
= EhciGetState (This
, &CurrentState
);
1051 if (EFI_ERROR (Status
)) {
1052 Status
= EFI_DEVICE_ERROR
;
1058 case EfiUsbHcStateHalt
:
1060 if (EfiUsbHcStateHalt
== CurrentState
) {
1061 Status
= EFI_SUCCESS
;
1063 } else if (EfiUsbHcStateOperational
== CurrentState
) {
1064 Status
= ReadEhcOperationalReg (
1069 if (EFI_ERROR (Status
)) {
1070 Status
= EFI_DEVICE_ERROR
;
1074 UsbCommandReg
&= ~USBCMD_RS
;
1075 Status
= WriteEhcOperationalReg (
1080 if (EFI_ERROR (Status
)) {
1081 Status
= EFI_DEVICE_ERROR
;
1085 // Ensure the HC is in halt status after send the stop command
1087 Status
= WaitForEhcHalt (HcDev
, EHCI_GENERIC_TIMEOUT
);
1088 if (EFI_ERROR (Status
)) {
1089 Status
= EFI_TIMEOUT
;
1095 case EfiUsbHcStateOperational
:
1097 if (IsEhcSysError (HcDev
)) {
1098 Status
= EFI_DEVICE_ERROR
;
1101 if (EfiUsbHcStateOperational
== CurrentState
) {
1102 Status
= EFI_SUCCESS
;
1104 } else if (EfiUsbHcStateHalt
== CurrentState
) {
1106 // Set Host Controller Run
1108 Status
= ReadEhcOperationalReg (
1113 if (EFI_ERROR (Status
)) {
1114 return EFI_DEVICE_ERROR
;
1117 UsbCommandReg
|= USBCMD_RS
;
1118 Status
= WriteEhcOperationalReg (
1123 if (EFI_ERROR (Status
)) {
1124 Status
= EFI_DEVICE_ERROR
;
1130 case EfiUsbHcStateSuspend
:
1132 Status
= EFI_UNSUPPORTED
;
1137 Status
= EFI_INVALID_PARAMETER
;
1146 EhciGetRootHubPortStatus (
1147 IN EFI_USB2_HC_PROTOCOL
*This
,
1148 IN UINT8 PortNumber
,
1149 OUT EFI_USB_PORT_STATUS
*PortStatus
1153 Routine Description:
1155 Retrieves the current status of a USB root hub port.
1159 This - A pointer to the EFI_USB2_HC_PROTOCOL.
1160 PortNumber - Specifies the root hub port from which the status
1161 is to be retrieved. This value is zero-based. For example,
1162 if a root hub has two ports, then the first port is numbered 0,
1163 and the second port is numbered 1.
1164 PortStatus - A pointer to the current port status bits and
1165 port status change bits.
1169 EFI_SUCCESS The status of the USB root hub port specified
1170 by PortNumber was returned in PortStatus.
1171 EFI_INVALID_PARAMETER PortNumber is invalid.
1172 EFI_DEVICE_ERROR Can't read register
1178 UINT32 PortStatusControlAddr
;
1179 UINT32 PortStatusControlReg
;
1181 UINT8 TotalPortNumber
;
1182 UINT8 Is64BitCapable
;
1184 if (PortStatus
== NULL
) {
1185 Status
= EFI_INVALID_PARAMETER
;
1196 if (PortNumber
>= TotalPortNumber
) {
1197 Status
= EFI_INVALID_PARAMETER
;
1201 HcDev
= USB2_HC_DEV_FROM_THIS (This
);
1202 PortStatusControlAddr
= (UINT32
) (PORTSC
+ (4 * PortNumber
));
1205 // Clear port status
1207 PortStatus
->PortStatus
= 0;
1208 PortStatus
->PortChangeStatus
= 0;
1210 Status
= ReadEhcOperationalReg (
1212 PortStatusControlAddr
,
1213 &PortStatusControlReg
1215 if (EFI_ERROR (Status
)) {
1216 Status
= EFI_DEVICE_ERROR
;
1221 // Fill Port Status bits
1225 // Current Connect Status
1227 if (PORTSC_CCS
& PortStatusControlReg
) {
1228 PortStatus
->PortStatus
|= USB_PORT_STAT_CONNECTION
;
1231 // Port Enabled/Disabled
1233 if (PORTSC_PED
& PortStatusControlReg
) {
1234 PortStatus
->PortStatus
|= USB_PORT_STAT_ENABLE
;
1239 if (PORTSC_SUSP
& PortStatusControlReg
) {
1240 PortStatus
->PortStatus
|= USB_PORT_STAT_SUSPEND
;
1243 // Over-current Active
1245 if (PORTSC_OCA
& PortStatusControlReg
) {
1246 PortStatus
->PortStatus
|= USB_PORT_STAT_OVERCURRENT
;
1251 if (PORTSC_PR
& PortStatusControlReg
) {
1252 PortStatus
->PortStatus
|= USB_PORT_STAT_RESET
;
1257 if (PORTSC_PP
& PortStatusControlReg
) {
1258 PortStatus
->PortStatus
|= USB_PORT_STAT_POWER
;
1263 if (PORTSC_PO
& PortStatusControlReg
) {
1264 PortStatus
->PortStatus
|= USB_PORT_STAT_OWNER
;
1267 // Identify device speed
1269 if (PORTSC_LS_KSTATE
& PortStatusControlReg
) {
1271 // Low Speed Device Attached
1273 PortStatus
->PortStatus
|= USB_PORT_STAT_LOW_SPEED
;
1276 // Not Low Speed Device Attached
1278 if ((PORTSC_CCS
& PortStatusControlReg
) && (PORTSC_CSC
& PortStatusControlReg
)) {
1279 mDeviceSpeed
[PortNumber
] = IsHighSpeedDevice (This
, PortNumber
) ? USB_PORT_STAT_HIGH_SPEED
: 0;
1281 PortStatus
->PortStatus
|= mDeviceSpeed
[PortNumber
];
1284 // Fill Port Status Change bits
1287 // Connect Status Change
1289 if (PORTSC_CSC
& PortStatusControlReg
) {
1290 PortStatus
->PortChangeStatus
|= USB_PORT_STAT_C_CONNECTION
;
1293 // Port Enabled/Disabled Change
1295 if (PORTSC_PEDC
& PortStatusControlReg
) {
1296 PortStatus
->PortChangeStatus
|= USB_PORT_STAT_C_ENABLE
;
1299 // Port Over Current Change
1301 if (PORTSC_OCC
& PortStatusControlReg
) {
1302 PortStatus
->PortChangeStatus
|= USB_PORT_STAT_C_OVERCURRENT
;
1311 EhciSetRootHubPortFeature (
1312 IN EFI_USB2_HC_PROTOCOL
*This
,
1313 IN UINT8 PortNumber
,
1314 IN EFI_USB_PORT_FEATURE PortFeature
1318 Routine Description:
1320 Sets a feature for the specified root hub port.
1324 This - A pointer to the EFI_USB2_HC_PROTOCOL.
1325 PortNumber - Specifies the root hub port whose feature
1326 is requested to be set.
1327 PortFeature - Indicates the feature selector associated
1328 with the feature set request.
1333 The feature specified by PortFeature was set for the
1334 USB root hub port specified by PortNumber.
1335 EFI_INVALID_PARAMETER
1336 PortNumber is invalid or PortFeature is invalid.
1344 UINT32 PortStatusControlAddr
;
1345 UINT32 PortStatusControlReg
;
1347 UINT8 TotalPortNumber
;
1348 UINT8 Is64BitCapable
;
1357 if (PortNumber
>= TotalPortNumber
) {
1358 Status
= EFI_INVALID_PARAMETER
;
1362 HcDev
= USB2_HC_DEV_FROM_THIS (This
);
1363 PortStatusControlAddr
= (UINT32
) (PORTSC
+ (4 * PortNumber
));
1365 Status
= ReadEhcOperationalReg (
1367 PortStatusControlAddr
,
1368 &PortStatusControlReg
1370 if (EFI_ERROR (Status
)) {
1371 Status
= EFI_DEVICE_ERROR
;
1375 switch (PortFeature
) {
1377 case EfiUsbPortEnable
:
1380 // Sofeware can't set this bit, Port can only be enable by the Host Controller
1381 // as a part of the reset and enable
1383 PortStatusControlReg
&= 0xffffffd5;
1384 PortStatusControlReg
|= PORTSC_PED
;
1387 case EfiUsbPortSuspend
:
1389 PortStatusControlReg
&= 0xffffffd5;
1390 PortStatusControlReg
|= PORTSC_SUSP
;
1393 case EfiUsbPortReset
:
1396 // Make sure Host Controller not halt before reset it
1398 if (IsEhcHalted (HcDev
)) {
1399 Status
= StartScheduleExecution (HcDev
);
1400 if (EFI_ERROR (Status
)) {
1401 Status
= EFI_DEVICE_ERROR
;
1404 Status
= WaitForEhcNotHalt (HcDev
, EHCI_GENERIC_TIMEOUT
);
1405 if (EFI_ERROR (Status
)) {
1406 DEBUG ((gEHCDebugLevel
, "WaitForEhcNotHalt TimeOut\n"));
1407 Status
= EFI_DEVICE_ERROR
;
1411 PortStatusControlReg
&= 0xffffffd5;
1412 PortStatusControlReg
|= PORTSC_PR
;
1414 // Set one to PortReset bit must also set zero to PortEnable bit
1416 PortStatusControlReg
&= ~PORTSC_PED
;
1419 case EfiUsbPortPower
:
1422 // No support, no operation
1426 case EfiUsbPortOwner
:
1428 PortStatusControlReg
&= 0xffffffd5;
1429 PortStatusControlReg
|= PORTSC_PO
;
1434 Status
= EFI_INVALID_PARAMETER
;
1438 Status
= WriteEhcOperationalReg (
1440 PortStatusControlAddr
,
1441 PortStatusControlReg
1443 if (EFI_ERROR (Status
)) {
1444 Status
= EFI_DEVICE_ERROR
;
1453 EhciClearRootHubPortFeature (
1454 IN EFI_USB2_HC_PROTOCOL
*This
,
1455 IN UINT8 PortNumber
,
1456 IN EFI_USB_PORT_FEATURE PortFeature
1460 Routine Description:
1462 Clears a feature for the specified root hub port.
1466 This - A pointer to the EFI_USB2_HC_PROTOCOL instance.
1467 PortNumber - Specifies the root hub port whose feature
1468 is requested to be cleared.
1469 PortFeature - Indicates the feature selector associated with the
1470 feature clear request.
1475 The feature specified by PortFeature was cleared for the
1476 USB root hub port specified by PortNumber.
1477 EFI_INVALID_PARAMETER
1478 PortNumber is invalid or PortFeature is invalid.
1486 UINT32 PortStatusControlAddr
;
1487 UINT32 PortStatusControlReg
;
1489 UINT8 TotalPortNumber
;
1490 UINT8 Is64BitCapable
;
1499 if (PortNumber
>= TotalPortNumber
) {
1500 Status
= EFI_INVALID_PARAMETER
;
1504 HcDev
= USB2_HC_DEV_FROM_THIS (This
);
1505 PortStatusControlAddr
= (UINT32
) (PORTSC
+ (4 * PortNumber
));
1507 Status
= ReadEhcOperationalReg (
1509 PortStatusControlAddr
,
1510 &PortStatusControlReg
1512 if (EFI_ERROR (Status
)) {
1513 Status
= EFI_DEVICE_ERROR
;
1517 switch (PortFeature
) {
1519 case EfiUsbPortEnable
:
1522 // Clear PORT_ENABLE feature means disable port.
1524 PortStatusControlReg
&= 0xffffffd5;
1525 PortStatusControlReg
&= ~PORTSC_PED
;
1528 case EfiUsbPortSuspend
:
1531 // A write of zero to this bit is ignored by the host controller.
1532 // The host controller will unconditionally set this bit to a zero when:
1533 // 1. software sets the Forct Port Resume bit to a zero from a one.
1534 // 2. software sets the Port Reset bit to a one frome a zero.
1536 PortStatusControlReg
&= 0xffffffd5;
1537 PortStatusControlReg
&= ~PORTSC_FPR
;
1540 case EfiUsbPortReset
:
1543 // Clear PORT_RESET means clear the reset signal.
1545 PortStatusControlReg
&= 0xffffffd5;
1546 PortStatusControlReg
&= ~PORTSC_PR
;
1549 case EfiUsbPortPower
:
1552 // No support, no operation
1556 case EfiUsbPortOwner
:
1559 // Clear port owner means this port owned by EHC
1561 PortStatusControlReg
&= 0xffffffd5;
1562 PortStatusControlReg
&= ~PORTSC_PO
;
1565 case EfiUsbPortConnectChange
:
1568 // Clear connect status change
1570 PortStatusControlReg
&= 0xffffffd5;
1571 PortStatusControlReg
|= PORTSC_CSC
;
1574 case EfiUsbPortEnableChange
:
1577 // Clear enable status change
1579 PortStatusControlReg
&= 0xffffffd5;
1580 PortStatusControlReg
|= PORTSC_PEDC
;
1583 case EfiUsbPortSuspendChange
:
1586 // No related bit, no operation
1590 case EfiUsbPortOverCurrentChange
:
1593 // Clear PortOverCurrent change
1595 PortStatusControlReg
&= 0xffffffd5;
1596 PortStatusControlReg
|= PORTSC_OCC
;
1599 case EfiUsbPortResetChange
:
1602 // No related bit, no operation
1608 Status
= EFI_INVALID_PARAMETER
;
1612 Status
= WriteEhcOperationalReg (
1614 PortStatusControlAddr
,
1615 PortStatusControlReg
1617 if (EFI_ERROR (Status
)) {
1618 Status
= EFI_DEVICE_ERROR
;
1628 EhciControlTransfer (
1629 IN EFI_USB2_HC_PROTOCOL
*This
,
1630 IN UINT8 DeviceAddress
,
1631 IN UINT8 DeviceSpeed
,
1632 IN UINTN MaximumPacketLength
,
1633 IN EFI_USB_DEVICE_REQUEST
*Request
,
1634 IN EFI_USB_DATA_DIRECTION TransferDirection
,
1636 IN OUT UINTN
*DataLength
,
1638 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
1639 OUT UINT32
*TransferResult
1643 Routine Description:
1645 Submits control transfer to a target USB device.
1649 This - A pointer to the EFI_USB2_HC_PROTOCOL instance.
1650 DeviceAddress - Represents the address of the target device on the USB,
1651 which is assigned during USB enumeration.
1652 DeviceSpeed - Indicates target device speed.
1653 MaximumPacketLength - Indicates the maximum packet size that the
1654 default control transfer endpoint is capable of
1655 sending or receiving.
1656 Request - A pointer to the USB device request that will be sent
1658 TransferDirection - Specifies the data direction for the transfer.
1659 There are three values available, DataIn, DataOut
1661 Data - A pointer to the buffer of data that will be transmitted
1662 to USB device or received from USB device.
1663 DataLength - Indicates the size, in bytes, of the data buffer
1665 TimeOut - Indicates the maximum time, in microseconds,
1666 which the transfer is allowed to complete.
1667 Translator - A pointr to the transaction translator data.
1668 TransferResult - A pointer to the detailed result information generated
1669 by this control transfer.
1674 The control transfer was completed successfully.
1675 EFI_OUT_OF_RESOURCES
1676 The control transfer could not be completed due to a lack of resources.
1677 EFI_INVALID_PARAMETER
1678 Some parameters are invalid.
1680 The control transfer failed due to timeout.
1682 The control transfer failed due to host controller or device error.
1683 Caller should check TranferResult for detailed error information.
1690 EHCI_QH_ENTITY
*QhPtr
;
1691 EHCI_QTD_ENTITY
*ControlQtdsPtr
;
1694 UINT8
*RequestCursor
;
1698 ControlQtdsPtr
= NULL
;
1701 RequestCursor
= NULL
;
1703 HcDev
= USB2_HC_DEV_FROM_THIS (This
);
1706 // Parameters Checking
1708 if (TransferDirection
!= EfiUsbDataIn
&&
1709 TransferDirection
!= EfiUsbDataOut
&&
1710 TransferDirection
!= EfiUsbNoData
1712 Status
= EFI_INVALID_PARAMETER
;
1716 if (EfiUsbNoData
== TransferDirection
) {
1717 if (NULL
!= Data
|| 0 != *DataLength
) {
1718 Status
= EFI_INVALID_PARAMETER
;
1722 if (NULL
== Data
|| 0 == *DataLength
) {
1723 Status
= EFI_INVALID_PARAMETER
;
1728 if (Request
== NULL
|| TransferResult
== NULL
) {
1729 Status
= EFI_INVALID_PARAMETER
;
1733 if (EFI_USB_SPEED_LOW
== DeviceSpeed
) {
1734 if (MaximumPacketLength
!= 8) {
1735 Status
= EFI_INVALID_PARAMETER
;
1738 } else if (MaximumPacketLength
!= 8 &&
1739 MaximumPacketLength
!= 16 &&
1740 MaximumPacketLength
!= 32 &&
1741 MaximumPacketLength
!= 64
1743 Status
= EFI_INVALID_PARAMETER
;
1748 // If errors exist that cause host controller halt,
1749 // then return EFI_DEVICE_ERROR.
1751 if (IsEhcHalted (HcDev
) || IsEhcSysError (HcDev
)) {
1752 ClearEhcAllStatus (HcDev
);
1753 *TransferResult
= EFI_USB_ERR_SYSTEM
;
1754 Status
= EFI_DEVICE_ERROR
;
1759 // Map the Request for bus master access.
1760 // BusMasterRead means cpu write
1762 Status
= MapRequestBuffer (
1768 if (EFI_ERROR (Status
)) {
1769 *TransferResult
= EFI_USB_ERR_SYSTEM
;
1770 Status
= EFI_DEVICE_ERROR
;
1775 // Map the source data buffer for bus master access.
1777 Status
= MapDataBuffer (
1786 if (EFI_ERROR (Status
)) {
1787 *TransferResult
= EFI_USB_ERR_SYSTEM
;
1788 Status
= EFI_DEVICE_ERROR
;
1793 // Create and init control Qh
1795 Status
= CreateControlQh (
1799 MaximumPacketLength
,
1803 if (EFI_ERROR (Status
)) {
1804 *TransferResult
= EFI_USB_ERR_SYSTEM
;
1805 Status
= EFI_OUT_OF_RESOURCES
;
1810 // Create and init control Qtds
1812 Status
= CreateControlQtds (
1821 if (EFI_ERROR (Status
)) {
1822 *TransferResult
= EFI_USB_ERR_SYSTEM
;
1823 Status
= EFI_OUT_OF_RESOURCES
;
1830 LinkQtdToQh (QhPtr
, ControlQtdsPtr
);
1832 ClearEhcAllStatus (HcDev
);
1835 // Link Qh and Qtds to Async Schedule List
1837 Status
= LinkQhToAsyncList (HcDev
, QhPtr
);
1838 if (EFI_ERROR (Status
)) {
1839 *TransferResult
= EFI_USB_ERR_SYSTEM
;
1840 Status
= EFI_DEVICE_ERROR
;
1845 // Poll Qh-Qtds execution and get result.
1846 // detail status is returned
1848 Status
= ExecuteTransfer (
1857 if (EFI_ERROR (Status
)) {
1862 // If has errors that cause host controller halt,
1863 // then return EFI_DEVICE_ERROR directly.
1865 if (IsEhcHalted (HcDev
) || IsEhcSysError (HcDev
)) {
1866 *TransferResult
|= EFI_USB_ERR_SYSTEM
;
1869 ClearEhcAllStatus (HcDev
);
1872 UnlinkQhFromAsyncList (HcDev
, QhPtr
);
1873 DestoryQtds (HcDev
, ControlQtdsPtr
);
1875 DestoryQh (HcDev
, QhPtr
);
1877 HcDev
->PciIo
->Unmap (HcDev
->PciIo
, DataMap
);
1879 HcDev
->PciIo
->Unmap (HcDev
->PciIo
, RequestMap
);
1881 HcDev
->PciIo
->Flush (HcDev
->PciIo
);
1888 IN EFI_USB2_HC_PROTOCOL
*This
,
1889 IN UINT8 DeviceAddress
,
1890 IN UINT8 EndPointAddress
,
1891 IN UINT8 DeviceSpeed
,
1892 IN UINTN MaximumPacketLength
,
1893 IN UINT8 DataBuffersNumber
,
1894 IN OUT VOID
*Data
[EFI_USB_MAX_BULK_BUFFER_NUM
],
1895 IN OUT UINTN
*DataLength
,
1896 IN OUT UINT8
*DataToggle
,
1898 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
1899 OUT UINT32
*TransferResult
1903 Routine Description:
1905 Submits bulk transfer to a bulk endpoint of a USB device.
1909 This - A pointer to the EFI_USB2_HC_PROTOCOL instance.
1910 DeviceAddress - Represents the address of the target device on the USB,
1911 which is assigned during USB enumeration.
1912 EndPointAddress - The combination of an endpoint number and an
1913 endpoint direction of the target USB device.
1914 Each endpoint address supports data transfer in
1915 one direction except the control endpoint
1916 (whose default endpoint address is 0).
1917 It is the caller's responsibility to make sure that
1918 the EndPointAddress represents a bulk endpoint.
1919 DeviceSpeed - Indicates device speed. The supported values are EFI_USB_SPEED_FULL
1920 and EFI_USB_SPEED_HIGH.
1921 MaximumPacketLength - Indicates the maximum packet size the target endpoint
1922 is capable of sending or receiving.
1923 DataBuffersNumber - Number of data buffers prepared for the transfer.
1924 Data - Array of pointers to the buffers of data that will be transmitted
1925 to USB device or received from USB device.
1926 DataLength - When input, indicates the size, in bytes, of the data buffer
1927 specified by Data. When output, indicates the actually
1928 transferred data size.
1929 DataToggle - A pointer to the data toggle value. On input, it indicates
1930 the initial data toggle value the bulk transfer should adopt;
1931 on output, it is updated to indicate the data toggle value
1932 of the subsequent bulk transfer.
1933 Translator - A pointr to the transaction translator data.
1934 TimeOut - Indicates the maximum time, in microseconds, which the
1935 transfer is allowed to complete.
1936 TransferResult - A pointer to the detailed result information of the
1942 The bulk transfer was completed successfully.
1943 EFI_OUT_OF_RESOURCES
1944 The bulk transfer could not be submitted due to lack of resource.
1945 EFI_INVALID_PARAMETER
1946 Some parameters are invalid.
1948 The bulk transfer failed due to timeout.
1950 The bulk transfer failed due to host controller or device error.
1951 Caller should check TranferResult for detailed error information.
1958 EHCI_QH_ENTITY
*QhPtr
;
1959 EHCI_QTD_ENTITY
*BulkQtdsPtr
;
1962 EFI_USB_DATA_DIRECTION TransferDirection
;
1968 HcDev
= USB2_HC_DEV_FROM_THIS (This
);
1971 // Parameters Checking
1973 if (NULL
== DataLength
||
1976 NULL
== TransferResult
1978 Status
= EFI_INVALID_PARAMETER
;
1982 if (*DataLength
== 0) {
1983 Status
= EFI_INVALID_PARAMETER
;
1987 if (1 != *DataToggle
&& 0 != *DataToggle
) {
1988 Status
= EFI_INVALID_PARAMETER
;
1992 if (EFI_USB_SPEED_LOW
== DeviceSpeed
) {
1993 Status
= EFI_INVALID_PARAMETER
;
1997 if (EFI_USB_SPEED_FULL
== DeviceSpeed
) {
1998 if (MaximumPacketLength
> 64) {
1999 Status
= EFI_INVALID_PARAMETER
;
2004 if (EFI_USB_SPEED_HIGH
== DeviceSpeed
) {
2005 if (MaximumPacketLength
> 512) {
2006 Status
= EFI_INVALID_PARAMETER
;
2012 // if has errors that cause host controller halt,
2013 // then return EFI_DEVICE_ERROR directly.
2015 if (IsEhcHalted (HcDev
) || IsEhcSysError (HcDev
)) {
2016 ClearEhcAllStatus (HcDev
);
2017 *TransferResult
= EFI_USB_ERR_SYSTEM
;
2018 Status
= EFI_DEVICE_ERROR
;
2022 Status
= ClearEhcAllStatus (HcDev
);
2023 if (EFI_ERROR (Status
)) {
2024 Status
= EFI_DEVICE_ERROR
;
2029 // construct QH and TD data structures,
2030 // and link them together
2032 if (EndPointAddress
& 0x80) {
2033 TransferDirection
= EfiUsbDataIn
;
2035 TransferDirection
= EfiUsbDataOut
;
2038 Status
= MapDataBuffer (
2047 if (EFI_ERROR (Status
)) {
2048 *TransferResult
= EFI_USB_ERR_SYSTEM
;
2049 Status
= EFI_DEVICE_ERROR
;
2054 // Create and init Bulk Qh
2056 Status
= CreateBulkQh (
2062 MaximumPacketLength
,
2066 if (EFI_ERROR (Status
)) {
2067 *TransferResult
= EFI_USB_ERR_SYSTEM
;
2068 Status
= EFI_OUT_OF_RESOURCES
;
2073 // Create and init Bulk Qtds
2075 Status
= CreateBulkOrInterruptQtds (
2083 if (EFI_ERROR (Status
)) {
2084 *TransferResult
= EFI_USB_ERR_SYSTEM
;
2085 Status
= EFI_OUT_OF_RESOURCES
;
2092 LinkQtdToQh (QhPtr
, BulkQtdsPtr
);
2094 ClearEhcAllStatus (HcDev
);
2097 // Link Qh and qtds to Async Schedule List
2099 Status
= LinkQhToAsyncList (HcDev
, QhPtr
);
2100 if (EFI_ERROR (Status
)) {
2101 *TransferResult
= EFI_USB_ERR_SYSTEM
;
2102 Status
= EFI_DEVICE_ERROR
;
2107 // Poll QH-TDs execution and get result.
2108 // detail status is returned
2110 Status
= ExecuteTransfer (
2119 if (EFI_ERROR (Status
)) {
2124 // if has errors that cause host controller halt,
2125 // then return EFI_DEVICE_ERROR directly.
2127 if (IsEhcHalted (HcDev
) || IsEhcSysError (HcDev
)) {
2128 *TransferResult
|= EFI_USB_ERR_SYSTEM
;
2131 ClearEhcAllStatus (HcDev
);
2134 UnlinkQhFromAsyncList (HcDev
, QhPtr
);
2135 DestoryQtds (HcDev
, BulkQtdsPtr
);
2137 DestoryQh (HcDev
, QhPtr
);
2139 HcDev
->PciIo
->Unmap (HcDev
->PciIo
, DataMap
);
2141 HcDev
->PciIo
->Flush (HcDev
->PciIo
);
2147 EhciAsyncInterruptTransfer (
2148 IN EFI_USB2_HC_PROTOCOL
* This
,
2149 IN UINT8 DeviceAddress
,
2150 IN UINT8 EndPointAddress
,
2151 IN UINT8 DeviceSpeed
,
2152 IN UINTN MaximumPacketLength
,
2153 IN BOOLEAN IsNewTransfer
,
2154 IN OUT UINT8
*DataToggle
,
2155 IN UINTN PollingInterval
,
2156 IN UINTN DataLength
,
2157 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
* Translator
,
2158 IN EFI_ASYNC_USB_TRANSFER_CALLBACK CallBackFunction
,
2159 IN VOID
*Context OPTIONAL
2163 Routine Description:
2165 Submits an asynchronous interrupt transfer to an
2166 interrupt endpoint of a USB device.
2167 Translator parameter doesn't exist in UEFI2.0 spec, but it will be updated
2168 in the following specification version.
2172 This - A pointer to the EFI_USB2_HC_PROTOCOL instance.
2173 DeviceAddress - Represents the address of the target device on the USB,
2174 which is assigned during USB enumeration.
2175 EndPointAddress - The combination of an endpoint number and an endpoint
2176 direction of the target USB device. Each endpoint address
2177 supports data transfer in one direction except the
2178 control endpoint (whose default endpoint address is 0).
2179 It is the caller's responsibility to make sure that
2180 the EndPointAddress represents an interrupt endpoint.
2181 DeviceSpeed - Indicates device speed.
2182 MaximumPacketLength - Indicates the maximum packet size the target endpoint
2183 is capable of sending or receiving.
2184 IsNewTransfer - If TRUE, an asynchronous interrupt pipe is built between
2185 the host and the target interrupt endpoint.
2186 If FALSE, the specified asynchronous interrupt pipe
2188 DataToggle - A pointer to the data toggle value. On input, it is valid
2189 when IsNewTransfer is TRUE, and it indicates the initial
2190 data toggle value the asynchronous interrupt transfer
2192 On output, it is valid when IsNewTransfer is FALSE,
2193 and it is updated to indicate the data toggle value of
2194 the subsequent asynchronous interrupt transfer.
2195 PollingInterval - Indicates the interval, in milliseconds, that the
2196 asynchronous interrupt transfer is polled.
2197 This parameter is required when IsNewTransfer is TRUE.
2198 DataLength - Indicates the length of data to be received at the
2199 rate specified by PollingInterval from the target
2200 asynchronous interrupt endpoint. This parameter
2201 is only required when IsNewTransfer is TRUE.
2202 Translator - A pointr to the transaction translator data.
2203 CallBackFunction - The Callback function.This function is called at the
2204 rate specified by PollingInterval.This parameter is
2205 only required when IsNewTransfer is TRUE.
2206 Context - The context that is passed to the CallBackFunction.
2207 - This is an optional parameter and may be NULL.
2212 The asynchronous interrupt transfer request has been successfully
2213 submitted or canceled.
2214 EFI_INVALID_PARAMETER
2215 Some parameters are invalid.
2216 EFI_OUT_OF_RESOURCES
2217 The request could not be completed due to a lack of resources.
2226 EHCI_QH_ENTITY
*QhPtr
;
2227 EHCI_QTD_ENTITY
*InterruptQtdsPtr
;
2232 EHCI_ASYNC_REQUEST
*AsyncRequestPtr
;
2236 InterruptQtdsPtr
= NULL
;
2240 AsyncRequestPtr
= NULL
;
2241 HcDev
= USB2_HC_DEV_FROM_THIS (This
);
2244 // Parameters Checking
2246 if (!IsDataInTransfer (EndPointAddress
)) {
2247 Status
= EFI_INVALID_PARAMETER
;
2251 if (IsNewTransfer
) {
2252 if (0 == DataLength
) {
2253 Status
= EFI_INVALID_PARAMETER
;
2257 if (*DataToggle
!= 1 && *DataToggle
!= 0) {
2258 Status
= EFI_INVALID_PARAMETER
;
2262 if (PollingInterval
> 255 || PollingInterval
< 1) {
2263 Status
= EFI_INVALID_PARAMETER
;
2269 // if has errors that cause host controller halt,
2270 // then return EFI_DEVICE_ERROR directly.
2272 if (IsEhcHalted (HcDev
) || IsEhcSysError (HcDev
)) {
2273 ClearEhcAllStatus (HcDev
);
2274 Status
= EFI_DEVICE_ERROR
;
2278 Status
= ClearEhcAllStatus (HcDev
);
2279 if (EFI_ERROR (Status
)) {
2280 Status
= EFI_DEVICE_ERROR
;
2285 // Delete Async interrupt transfer request
2287 if (!IsNewTransfer
) {
2289 OldTpl
= gBS
->RaiseTPL (EFI_TPL_NOTIFY
);
2291 Status
= DeleteAsyncRequestTransfer (
2298 gBS
->RestoreTPL (OldTpl
);
2303 Status
= EhciAllocatePool (
2305 (UINT8
**) &AsyncRequestPtr
,
2306 sizeof (EHCI_ASYNC_REQUEST
)
2308 if (EFI_ERROR (Status
)) {
2309 Status
= EFI_OUT_OF_RESOURCES
;
2313 Status
= EhciAllocatePool (HcDev
, &DataPtr
, DataLength
);
2314 if (EFI_ERROR (Status
)) {
2315 Status
= EFI_OUT_OF_RESOURCES
;
2319 MappedLength
= DataLength
;
2320 Status
= MapDataBuffer (
2329 if (EFI_ERROR (Status
)) {
2330 Status
= EFI_DEVICE_ERROR
;
2335 // Create and init Interrupt Qh
2337 Status
= CreateInterruptQh (
2343 MaximumPacketLength
,
2348 if (EFI_ERROR (Status
)) {
2349 Status
= EFI_OUT_OF_RESOURCES
;
2354 // Create and init Interrupt Qtds
2356 Status
= CreateBulkOrInterruptQtds (
2364 if (EFI_ERROR (Status
)) {
2365 Status
= EFI_OUT_OF_RESOURCES
;
2372 LinkQtdToQh (QhPtr
, InterruptQtdsPtr
);
2375 // Init AsyncRequest Entry
2377 AsyncRequestPtr
->Context
= Context
;
2378 AsyncRequestPtr
->CallBackFunc
= CallBackFunction
;
2379 AsyncRequestPtr
->TransferType
= ASYNC_INTERRUPT_TRANSFER
;
2380 AsyncRequestPtr
->QhPtr
= QhPtr
;
2381 AsyncRequestPtr
->Prev
= NULL
;
2382 AsyncRequestPtr
->Next
= NULL
;
2384 if (NULL
== HcDev
->AsyncRequestList
) {
2385 Status
= StartPollingTimer (HcDev
);
2386 if (EFI_ERROR (Status
)) {
2387 Status
= EFI_DEVICE_ERROR
;
2388 CleanUpAllAsyncRequestTransfer (HcDev
);
2394 // Link Entry to AsyncRequest List
2396 LinkToAsyncReqeust (HcDev
, AsyncRequestPtr
);
2398 ClearEhcAllStatus (HcDev
);
2400 Status
= DisablePeriodicSchedule (HcDev
);
2401 if (EFI_ERROR (Status
)) {
2402 Status
= EFI_DEVICE_ERROR
;
2406 Status
= WaitForPeriodicScheduleDisable (HcDev
, EHCI_GENERIC_TIMEOUT
);
2407 if (EFI_ERROR (Status
)) {
2408 Status
= EFI_TIMEOUT
;
2413 // Link Qh and Qtds to Periodic Schedule List
2415 LinkQhToPeriodicList (HcDev
, QhPtr
);
2417 Status
= EnablePeriodicSchedule (HcDev
);
2418 if (EFI_ERROR (Status
)) {
2419 Status
= EFI_DEVICE_ERROR
;
2423 Status
= WaitForPeriodicScheduleEnable (HcDev
, EHCI_GENERIC_TIMEOUT
);
2424 if (EFI_ERROR (Status
)) {
2425 Status
= EFI_TIMEOUT
;
2429 if (IsEhcHalted (HcDev
)) {
2430 Status
= StartScheduleExecution (HcDev
);
2431 if (EFI_ERROR (Status
)) {
2432 Status
= EFI_DEVICE_ERROR
;
2437 HcDev
->PciIo
->Flush (HcDev
->PciIo
);
2441 DestoryQh (HcDev
, QhPtr
);
2443 EhciFreePool (HcDev
, DataPtr
, DataLength
);
2447 (UINT8
*) AsyncRequestPtr
,
2448 sizeof (EHCI_ASYNC_REQUEST
)
2451 HcDev
->PciIo
->Unmap (HcDev
->PciIo
, DataMap
);
2458 EhciSyncInterruptTransfer (
2459 IN EFI_USB2_HC_PROTOCOL
*This
,
2460 IN UINT8 DeviceAddress
,
2461 IN UINT8 EndPointAddress
,
2462 IN UINT8 DeviceSpeed
,
2463 IN UINTN MaximumPacketLength
,
2465 IN OUT UINTN
*DataLength
,
2466 IN OUT UINT8
*DataToggle
,
2468 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
2469 OUT UINT32
*TransferResult
2473 Routine Description:
2475 Submits synchronous interrupt transfer to an interrupt endpoint
2477 Translator parameter doesn't exist in UEFI2.0 spec, but it will be updated
2478 in the following specification version.
2482 This - A pointer to the EFI_USB2_HC_PROTOCOL instance.
2483 DeviceAddress - Represents the address of the target device on the USB,
2484 which is assigned during USB enumeration.
2485 EndPointAddress - The combination of an endpoint number and an endpoint
2486 direction of the target USB device. Each endpoint
2487 address supports data transfer in one direction
2488 except the control endpoint (whose default
2489 endpoint address is 0). It is the caller's responsibility
2490 to make sure that the EndPointAddress represents
2491 an interrupt endpoint.
2492 DeviceSpeed - Indicates device speed.
2493 MaximumPacketLength - Indicates the maximum packet size the target endpoint
2494 is capable of sending or receiving.
2495 Data - A pointer to the buffer of data that will be transmitted
2496 to USB device or received from USB device.
2497 DataLength - On input, the size, in bytes, of the data buffer specified
2498 by Data. On output, the number of bytes transferred.
2499 DataToggle - A pointer to the data toggle value. On input, it indicates
2500 the initial data toggle value the synchronous interrupt
2501 transfer should adopt;
2502 on output, it is updated to indicate the data toggle value
2503 of the subsequent synchronous interrupt transfer.
2504 TimeOut - Indicates the maximum time, in microseconds, which the
2505 transfer is allowed to complete.
2506 Translator - A pointr to the transaction translator data.
2507 TransferResult - A pointer to the detailed result information from
2508 the synchronous interrupt transfer.
2513 The synchronous interrupt transfer was completed successfully.
2514 EFI_OUT_OF_RESOURCES
2515 The synchronous interrupt transfer could not be submitted due
2516 to lack of resource.
2517 EFI_INVALID_PARAMETER
2518 Some parameters are invalid.
2520 The synchronous interrupt transfer failed due to timeout.
2522 The synchronous interrupt transfer failed due to host controller
2523 or device error. Caller should check TranferResult for detailed
2531 EHCI_QH_ENTITY
*QhPtr
;
2532 EHCI_QTD_ENTITY
*InterruptQtdsPtr
;
2537 InterruptQtdsPtr
= NULL
;
2540 HcDev
= USB2_HC_DEV_FROM_THIS (This
);
2543 // Parameters Checking
2545 if (DataLength
== NULL
||
2547 TransferResult
== NULL
2549 Status
= EFI_INVALID_PARAMETER
;
2553 if (!IsDataInTransfer (EndPointAddress
)) {
2554 Status
= EFI_INVALID_PARAMETER
;
2558 if (0 == *DataLength
) {
2559 Status
= EFI_INVALID_PARAMETER
;
2563 if (*DataToggle
!= 1 && *DataToggle
!= 0) {
2564 Status
= EFI_INVALID_PARAMETER
;
2568 if (EFI_USB_SPEED_LOW
== DeviceSpeed
&& 8 != MaximumPacketLength
) {
2569 Status
= EFI_INVALID_PARAMETER
;
2573 if (EFI_USB_SPEED_FULL
== DeviceSpeed
&& MaximumPacketLength
> 64) {
2574 Status
= EFI_INVALID_PARAMETER
;
2578 if (EFI_USB_SPEED_HIGH
== DeviceSpeed
&& MaximumPacketLength
> 3072) {
2579 Status
= EFI_INVALID_PARAMETER
;
2584 // if has errors that cause host controller halt,
2585 // then return EFI_DEVICE_ERROR directly.
2587 if (IsEhcHalted (HcDev
) || IsEhcSysError (HcDev
)) {
2588 ClearEhcAllStatus (HcDev
);
2589 *TransferResult
= EFI_USB_ERR_SYSTEM
;
2590 Status
= EFI_DEVICE_ERROR
;
2594 Status
= ClearEhcAllStatus (HcDev
);
2595 if (EFI_ERROR (Status
)) {
2596 Status
= EFI_DEVICE_ERROR
;
2600 Status
= MapDataBuffer (
2609 if (EFI_ERROR (Status
)) {
2610 *TransferResult
= EFI_USB_ERR_SYSTEM
;
2611 Status
= EFI_DEVICE_ERROR
;
2616 // Create and init Interrupt Qh
2618 Status
= CreateInterruptQh (
2624 MaximumPacketLength
,
2629 if (EFI_ERROR (Status
)) {
2630 Status
= EFI_OUT_OF_RESOURCES
;
2635 // Create and init Interrupt Qtds
2637 Status
= CreateBulkOrInterruptQtds (
2645 if (EFI_ERROR (Status
)) {
2646 *TransferResult
= EFI_USB_ERR_SYSTEM
;
2647 Status
= EFI_OUT_OF_RESOURCES
;
2654 LinkQtdToQh (QhPtr
, InterruptQtdsPtr
);
2656 ClearEhcAllStatus (HcDev
);
2658 Status
= DisablePeriodicSchedule (HcDev
);
2659 if (EFI_ERROR (Status
)) {
2660 Status
= EFI_DEVICE_ERROR
;
2664 Status
= WaitForPeriodicScheduleDisable (HcDev
, EHCI_GENERIC_TIMEOUT
);
2665 if (EFI_ERROR (Status
)) {
2666 Status
= EFI_TIMEOUT
;
2671 // Link Qh and Qtds to Periodic Schedule List
2673 LinkQhToPeriodicList (HcDev
, QhPtr
);
2675 Status
= EnablePeriodicSchedule (HcDev
);
2676 if (EFI_ERROR (Status
)) {
2677 Status
= EFI_DEVICE_ERROR
;
2681 Status
= WaitForPeriodicScheduleEnable (HcDev
, EHCI_GENERIC_TIMEOUT
);
2682 if (EFI_ERROR (Status
)) {
2683 Status
= EFI_TIMEOUT
;
2687 if (IsEhcHalted (HcDev
)) {
2688 Status
= StartScheduleExecution (HcDev
);
2689 if (EFI_ERROR (Status
)) {
2690 Status
= EFI_DEVICE_ERROR
;
2696 // Poll QH-TDs execution and get result.
2697 // detail status is returned
2699 Status
= ExecuteTransfer (
2708 if (EFI_ERROR (Status
)) {
2713 // if has errors that cause host controller halt,
2714 // then return EFI_DEVICE_ERROR directly.
2716 if (IsEhcHalted (HcDev
) || IsEhcSysError (HcDev
)) {
2717 *TransferResult
|= EFI_USB_ERR_SYSTEM
;
2720 ClearEhcAllStatus (HcDev
);
2723 UnlinkQhFromPeriodicList (HcDev
, QhPtr
, 0);
2724 DestoryQtds (HcDev
, InterruptQtdsPtr
);
2726 DestoryQh (HcDev
, QhPtr
);
2728 HcDev
->PciIo
->Unmap (HcDev
->PciIo
, DataMap
);
2730 HcDev
->PciIo
->Flush (HcDev
->PciIo
);
2736 EhciIsochronousTransfer (
2737 IN EFI_USB2_HC_PROTOCOL
*This
,
2738 IN UINT8 DeviceAddress
,
2739 IN UINT8 EndPointAddress
,
2740 IN UINT8 DeviceSpeed
,
2741 IN UINTN MaximumPacketLength
,
2742 IN UINT8 DataBuffersNumber
,
2743 IN OUT VOID
*Data
[EFI_USB_MAX_ISO_BUFFER_NUM
],
2744 IN UINTN DataLength
,
2745 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
2746 OUT UINT32
*TransferResult
2750 Routine Description:
2752 Submits isochronous transfer to a target USB device.
2756 This - A pointer to the EFI_USB2_HC_PROTOCOL instance.
2757 DeviceAddress - Represents the address of the target device on the USB,
2758 which is assigned during USB enumeration.
2759 EndPointAddress - End point address
2760 DeviceSpeed - Indicates device speed.
2761 MaximumPacketLength - Indicates the maximum packet size that the
2762 default control transfer endpoint is capable of
2763 sending or receiving.
2764 DataBuffersNumber - Number of data buffers prepared for the transfer.
2765 Data - Array of pointers to the buffers of data that will be
2766 transmitted to USB device or received from USB device.
2767 DataLength - Indicates the size, in bytes, of the data buffer
2769 Translator - A pointr to the transaction translator data.
2770 TransferResult - A pointer to the detailed result information generated
2771 by this control transfer.
2779 return EFI_UNSUPPORTED
;
2784 EhciAsyncIsochronousTransfer (
2785 IN EFI_USB2_HC_PROTOCOL
*This
,
2786 IN UINT8 DeviceAddress
,
2787 IN UINT8 EndPointAddress
,
2788 IN UINT8 DeviceSpeed
,
2789 IN UINTN MaximumPacketLength
,
2790 IN UINT8 DataBuffersNumber
,
2791 IN OUT VOID
*Data
[EFI_USB_MAX_ISO_BUFFER_NUM
],
2792 IN UINTN DataLength
,
2793 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
2794 IN EFI_ASYNC_USB_TRANSFER_CALLBACK IsochronousCallBack
,
2799 Routine Description:
2801 Submits Async isochronous transfer to a target USB device.
2805 This - A pointer to the EFI_USB2_HC_PROTOCOL instance.
2806 DeviceAddress - Represents the address of the target device on the USB,
2807 which is assigned during USB enumeration.
2808 EndPointAddress - End point address
2809 DeviceSpeed - Indicates device speed.
2810 MaximumPacketLength - Indicates the maximum packet size that the
2811 default control transfer endpoint is capable of
2812 sending or receiving.
2813 DataBuffersNumber - Number of data buffers prepared for the transfer.
2814 Data - Array of pointers to the buffers of data that will be transmitted
2815 to USB device or received from USB device.
2816 Translator - A pointr to the transaction translator data.
2817 IsochronousCallBack - When the transfer complete, the call back function will be called
2818 Context - Pass to the call back function as parameter
2826 return EFI_UNSUPPORTED
;