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_ERROR
;
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
,
229 EhciDriverBindingSupported (
230 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
231 IN EFI_HANDLE Controller
,
232 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
238 Test to see if this driver supports ControllerHandle. Any ControllerHandle
239 that has Usb2HcProtocol installed will be supported.
243 This - Protocol instance pointer.
244 Controlle - Handle of device to test
245 RemainingDevicePath - Not used
249 EFI_SUCCESS This driver supports this device.
250 EFI_UNSUPPORTED This driver does not support this device.
255 EFI_PCI_IO_PROTOCOL
*PciIo
;
256 USB_CLASSC UsbClassCReg
;
260 // Test whether there is PCI IO Protocol attached on the controller handle.
262 Status
= gBS
->OpenProtocol (
264 &gEfiPciIoProtocolGuid
,
266 This
->DriverBindingHandle
,
268 EFI_OPEN_PROTOCOL_BY_DRIVER
270 if (EFI_ERROR (Status
)) {
274 Status
= PciIo
->Pci
.Read (
278 sizeof (USB_CLASSC
) / sizeof (UINT8
),
281 if (EFI_ERROR (Status
)) {
284 &gEfiPciIoProtocolGuid
,
285 This
->DriverBindingHandle
,
288 Status
= EFI_UNSUPPORTED
;
293 // Test whether the controller belongs to Ehci type
295 if ((UsbClassCReg
.BaseCode
!= PCI_CLASS_SERIAL
) ||
296 (UsbClassCReg
.SubClassCode
!= PCI_CLASS_SERIAL_USB
) ||
297 (UsbClassCReg
.PI
!= PCI_CLASSC_PI_EHCI
)
302 &gEfiPciIoProtocolGuid
,
303 This
->DriverBindingHandle
,
307 Status
= EFI_UNSUPPORTED
;
313 &gEfiPciIoProtocolGuid
,
314 This
->DriverBindingHandle
,
324 EhciDriverBindingStart (
325 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
326 IN EFI_HANDLE Controller
,
327 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
333 Starting the Usb EHCI Driver
337 This - Protocol instance pointer.
338 Controller - Handle of device to test
339 RemainingDevicePath - Not used
343 EFI_SUCCESS supports this device.
344 EFI_UNSUPPORTED do not support this device.
345 EFI_DEVICE_ERROR cannot be started due to device Error
346 EFI_OUT_OF_RESOURCES cannot allocate resources
352 EFI_PCI_IO_PROTOCOL
*PciIo
;
355 UINT8 Is64BitCapable
;
359 // Open the PciIo Protocol
361 Status
= gBS
->OpenProtocol (
363 &gEfiPciIoProtocolGuid
,
365 This
->DriverBindingHandle
,
367 EFI_OPEN_PROTOCOL_BY_DRIVER
369 if (EFI_ERROR (Status
)) {
370 Status
= EFI_OUT_OF_RESOURCES
;
375 // Enable the USB Host Controller
377 Status
= PciIo
->Attributes (
379 EfiPciIoAttributeOperationSupported
,
383 if (!EFI_ERROR (Status
)) {
384 Supports
&= EFI_PCI_DEVICE_ENABLE
;
385 Status
= PciIo
->Attributes (
387 EfiPciIoAttributeOperationEnable
,
392 if (EFI_ERROR (Status
)) {
393 Status
= EFI_OUT_OF_RESOURCES
;
394 goto close_pciio_protocol
;
398 // Allocate memory for EHC private data structure
400 HcDev
= AllocateZeroPool (sizeof (USB2_HC_DEV
));
402 Status
= EFI_OUT_OF_RESOURCES
;
403 goto close_pciio_protocol
;
407 // Init EFI_USB2_HC_PROTOCOL interface and private data structure
409 HcDev
->Usb2Hc
.GetCapability
= EhciGetCapability
;
410 HcDev
->Usb2Hc
.Reset
= EhciReset
;
411 HcDev
->Usb2Hc
.GetState
= EhciGetState
;
412 HcDev
->Usb2Hc
.SetState
= EhciSetState
;
413 HcDev
->Usb2Hc
.ControlTransfer
= EhciControlTransfer
;
414 HcDev
->Usb2Hc
.BulkTransfer
= EhciBulkTransfer
;
415 HcDev
->Usb2Hc
.AsyncInterruptTransfer
= EhciAsyncInterruptTransfer
;
416 HcDev
->Usb2Hc
.SyncInterruptTransfer
= EhciSyncInterruptTransfer
;
417 HcDev
->Usb2Hc
.IsochronousTransfer
= EhciIsochronousTransfer
;
418 HcDev
->Usb2Hc
.AsyncIsochronousTransfer
= EhciAsyncIsochronousTransfer
;
419 HcDev
->Usb2Hc
.GetRootHubPortStatus
= EhciGetRootHubPortStatus
;
420 HcDev
->Usb2Hc
.SetRootHubPortFeature
= EhciSetRootHubPortFeature
;
421 HcDev
->Usb2Hc
.ClearRootHubPortFeature
= EhciClearRootHubPortFeature
;
422 HcDev
->Usb2Hc
.MajorRevision
= 0x1;
423 HcDev
->Usb2Hc
.MinorRevision
= 0x1;
425 HcDev
->AsyncRequestList
= NULL
;
426 HcDev
->ControllerNameTable
= NULL
;
427 HcDev
->Signature
= USB2_HC_DEV_SIGNATURE
;
428 HcDev
->PciIo
= PciIo
;
431 // Install USB2_HC_PROTOCOL
433 Status
= gBS
->InstallProtocolInterface (
435 &gEfiUsb2HcProtocolGuid
,
436 EFI_NATIVE_INTERFACE
,
439 if (EFI_ERROR (Status
)) {
440 Status
= EFI_OUT_OF_RESOURCES
;
445 // Get Capability Register Length
447 Status
= GetCapabilityLen (HcDev
);
448 if (EFI_ERROR (Status
)) {
449 Status
= EFI_DEVICE_ERROR
;
450 goto uninstall_usb2hc_protocol
;
453 ClearLegacySupport (HcDev
);
457 DumpEHCIPortsStatus (HcDev
);
461 // Create and Init Perodic Frame List
463 Status
= EhciGetCapability (
469 if (EFI_ERROR (Status
)) {
470 Status
= EFI_OUT_OF_RESOURCES
;
471 goto uninstall_usb2hc_protocol
;
473 HcDev
->Is64BitCapable
= Is64BitCapable
;
476 // Create and Init Perodic Frame List
478 Status
= InitialPeriodicFrameList (
480 EHCI_MAX_FRAME_LIST_LENGTH
482 if (EFI_ERROR (Status
)) {
483 Status
= EFI_OUT_OF_RESOURCES
;
484 goto uninstall_usb2hc_protocol
;
488 // Init memory pool management
490 Status
= InitialMemoryManagement (HcDev
);
491 if (EFI_ERROR (Status
)) {
492 Status
= EFI_OUT_OF_RESOURCES
;
493 goto deinit_perodic_frame_list
;
496 Status
= CreateNULLQH (HcDev
);
497 if (EFI_ERROR (Status
)) {
498 Status
= EFI_OUT_OF_RESOURCES
;
499 goto deinit_perodic_frame_list
;
502 // Create AsyncRequest Polling Timer
504 Status
= CreatePollingTimer (HcDev
, (EFI_EVENT_NOTIFY
) AsyncRequestMoniter
);
505 if (EFI_ERROR (Status
)) {
506 Status
= EFI_OUT_OF_RESOURCES
;
511 // Default Maxximum Interrupt Interval is 8,
512 // it means that 8 micro frame = 1ms
516 // Start the Host Controller
518 if (IsEhcHalted (HcDev
)) {
519 Status
= StartScheduleExecution (HcDev
);
520 if (EFI_ERROR (Status
)) {
521 Status
= EFI_DEVICE_ERROR
;
527 // Set all ports routing to EHC
529 Status
= SetPortRoutingEhc (HcDev
);
530 if (EFI_ERROR (Status
)) {
531 Status
= EFI_DEVICE_ERROR
;
536 // Component name protocol
538 Status
= AddUnicodeString (
540 gEhciComponentName
.SupportedLanguages
,
541 &HcDev
->ControllerNameTable
,
542 L
"Usb Enhanced Host Controller"
544 if (EFI_ERROR (Status
)) {
545 Status
= EFI_OUT_OF_RESOURCES
;
552 // Error handle process
555 DestoryPollingTimer (HcDev
);
557 DestroyNULLQH(HcDev
);
558 DeinitialMemoryManagement (HcDev
);
559 deinit_perodic_frame_list
:
560 DeinitialPeriodicFrameList (HcDev
);
561 uninstall_usb2hc_protocol
:
562 gBS
->UninstallProtocolInterface (
564 &gEfiUsb2HcProtocolGuid
,
568 gBS
->FreePool (HcDev
);
569 close_pciio_protocol
:
572 &gEfiPciIoProtocolGuid
,
573 This
->DriverBindingHandle
,
583 EhciDriverBindingStop (
584 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
585 IN EFI_HANDLE Controller
,
586 IN UINTN NumberOfChildren
,
587 IN EFI_HANDLE
*ChildHandleBuffer
593 Stop this driver on ControllerHandle. Support stoping any child handles
594 created by this driver.
598 This - Protocol instance pointer.
599 Controller - Handle of device to stop driver on
600 NumberOfChildren - Number of Children in the ChildHandleBuffer
601 ChildHandleBuffer - List of handles for the children we need to stop.
606 EFI_DEVICE_ERROR Fail
610 EFI_USB2_HC_PROTOCOL
*Usb2Hc
;
615 // Test whether the Controller handler passed in is a valid
616 // Usb controller handle that should be supported, if not,
617 // return the error status directly
619 Status
= gBS
->OpenProtocol (
621 &gEfiUsb2HcProtocolGuid
,
623 This
->DriverBindingHandle
,
625 EFI_OPEN_PROTOCOL_GET_PROTOCOL
627 if (EFI_ERROR (Status
)) {
628 Status
= EFI_DEVICE_ERROR
;
632 HcDev
= USB2_HC_DEV_FROM_THIS (Usb2Hc
);
635 // free all the controller related memory and uninstall UHCI Protocol.
637 Status
= gBS
->UninstallProtocolInterface (
639 &gEfiUsb2HcProtocolGuid
,
642 if (EFI_ERROR (Status
)) {
643 Status
= EFI_DEVICE_ERROR
;
648 // Set Host Controller state as halt
650 Status
= Usb2Hc
->SetState (
654 if (EFI_ERROR (Status
)) {
655 Status
= EFI_DEVICE_ERROR
;
660 // Stop AsyncRequest Polling Timer
662 Status
= StopPollingTimer (HcDev
);
663 if (EFI_ERROR (Status
)) {
664 Status
= EFI_DEVICE_ERROR
;
669 // Destroy Asynchronous Request Event
671 DestoryPollingTimer (HcDev
);
674 // Destroy Perodic Frame List
676 DeinitialPeriodicFrameList (HcDev
);
681 DestroyNULLQH (HcDev
);
684 // Deinit Ehci pool memory management
686 DeinitialMemoryManagement (HcDev
);
689 // Denint Unicode String Table
691 FreeUnicodeStringTable (HcDev
->ControllerNameTable
);
694 // Disable the USB Host Controller
696 Status
= HcDev
->PciIo
->Attributes (
698 EfiPciIoAttributeOperationSupported
,
702 if (!EFI_ERROR (Status
)) {
703 Supports
&= EFI_PCI_DEVICE_ENABLE
;
704 Status
= HcDev
->PciIo
->Attributes (
706 EfiPciIoAttributeOperationDisable
,
711 if (EFI_ERROR (Status
)) {
712 Status
= EFI_DEVICE_ERROR
;
716 gBS
->FreePool (HcDev
);
720 &gEfiPciIoProtocolGuid
,
721 This
->DriverBindingHandle
,
732 IN EFI_USB2_HC_PROTOCOL
*This
,
734 OUT UINT8
*PortNumber
,
735 OUT UINT8
*Is64BitCapable
741 Retrieves the capablility of root hub ports.
745 This - A pointer to the EFI_USB_HC_PROTOCOL instance.
746 MaxSpeed - A pointer to the number of the host controller.
747 PortNumber - A pointer to the number of the root hub ports.
748 Is64BitCapable - A pointer to the flag for whether controller supports
749 64-bit memory addressing.
753 EFI_SUCCESS host controller capability were retrieved successfully.
754 EFI_INVALID_PARAMETER MaxSpeed or PortNumber or Is64BitCapable is NULL.
755 EFI_DEVICE_ERROR An error was encountered while attempting to retrieve the capabilities.
761 UINT32 HcStructParamsAddr
;
762 UINT32 HcStructParamsReg
;
763 UINT32 HcCapParamsAddr
;
764 UINT32 HcCapParamsReg
;
766 if (MaxSpeed
== NULL
|| PortNumber
== NULL
|| Is64BitCapable
== NULL
) {
767 Status
= EFI_INVALID_PARAMETER
;
771 HcStructParamsAddr
= HCSPARAMS
;
772 HcCapParamsAddr
= HCCPARAMS
;
773 HcDev
= USB2_HC_DEV_FROM_THIS (This
);
775 Status
= ReadEhcCapabiltiyReg (
780 if (EFI_ERROR (Status
)) {
781 Status
= EFI_DEVICE_ERROR
;
785 Status
= ReadEhcCapabiltiyReg (
790 if (EFI_ERROR (Status
)) {
791 Status
= EFI_DEVICE_ERROR
;
795 *MaxSpeed
= EFI_USB_SPEED_HIGH
;
796 *PortNumber
= (UINT8
) (HcStructParamsReg
& HCSP_NPORTS
);
797 *Is64BitCapable
= (UINT8
) (HcCapParamsReg
& HCCP_64BIT
);
806 IN EFI_USB2_HC_PROTOCOL
*This
,
813 Provides software reset for the USB host controller.
817 This - A pointer to the EFI_USB2_HC_PROTOCOL instance.
818 Attributes - A bit mask of the reset operation to perform.
819 See below for a list of the supported bit mask values.
821 #define EFI_USB_HC_RESET_GLOBAL 0x0001
822 #define EFI_USB_HC_RESET_HOST_CONTROLLER 0x0002
823 #define EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG 0x0004
824 #define EFI_USB_HC_RESET_HOST_WITH_DEBUG 0x0008
826 EFI_USB_HC_RESET_GLOBAL
827 If this bit is set, a global reset signal will be sent to the USB bus.
828 This resets all of the USB bus logic, including the USB host
829 controller hardware and all the devices attached on the USB bus.
830 EFI_USB_HC_RESET_HOST_CONTROLLER
831 If this bit is set, the USB host controller hardware will be reset.
832 No reset signal will be sent to the USB bus.
833 EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG
834 If this bit is set, a global reset signal will be sent to the USB bus.
835 This resets all of the USB bus logic, including the USB host
836 controller hardware and all the devices attached on the USB bus.
837 If this is an EHCI controller and the debug port has configured, then
838 this is will still reset the host controller.
839 EFI_USB_HC_RESET_HOST_WITH_DEBUG
840 If this bit is set, the USB host controller hardware will be reset.
841 If this is an EHCI controller and the debug port has been configured,
842 then this will still reset the host controller.
847 The reset operation succeeded.
848 EFI_INVALID_PARAMETER
849 Attributes is not valid.
851 The type of reset specified by Attributes is not currently supported by
852 the host controller hardware.
854 Reset operation is rejected due to the debug port being configured and
855 active; only EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG or
856 EFI_USB_HC_RESET_HOST_WITH_DEBUG reset Atrributes can be used to
857 perform reset operation for this host controller.
859 An error was encountered while attempting to perform
867 FRAME_LIST_ENTRY
*FrameEntryPtr
;
869 HcDev
= USB2_HC_DEV_FROM_THIS (This
);
871 switch (Attributes
) {
873 case EFI_USB_HC_RESET_GLOBAL
:
876 // Same behavior as Host Controller Reset
879 case EFI_USB_HC_RESET_HOST_CONTROLLER
:
882 // Host Controller must be Halt when Reset it
884 if (IsEhcHalted (HcDev
)) {
885 Status
= ResetEhc (HcDev
);
886 if (EFI_ERROR (Status
)) {
887 Status
= EFI_DEVICE_ERROR
;
891 // Set to zero by Host Controller when reset process completes
893 Status
= WaitForEhcReset (HcDev
, EHCI_GENERIC_TIMEOUT
);
894 if (EFI_ERROR (Status
)) {
895 Status
= EFI_TIMEOUT
;
899 Status
= EFI_DEVICE_ERROR
;
904 // only asynchronous interrupt transfers are always alive on the bus, need to cleanup
906 CleanUpAllAsyncRequestTransfer (HcDev
);
907 Status
= ClearEhcAllStatus (HcDev
);
908 if (EFI_ERROR (Status
)) {
909 Status
= EFI_DEVICE_ERROR
;
914 // Set appropriate 4G Segment Selector
916 Status
= SetCtrlDataStructSeg (HcDev
);
917 if (EFI_ERROR (Status
)) {
918 Status
= EFI_DEVICE_ERROR
;
923 // Init Perodic List Base Addr and Frame List
925 Status
= SetFrameListBaseAddr (
927 (UINT32
)GET_0B_TO_31B (HcDev
->PeriodicFrameListBuffer
)
929 if (EFI_ERROR (Status
)) {
930 Status
= EFI_DEVICE_ERROR
;
933 FrameEntryPtr
= (FRAME_LIST_ENTRY
*) HcDev
->PeriodicFrameListBuffer
;
934 for (FrameIndex
= 0; FrameIndex
< HcDev
->PeriodicFrameListLength
; FrameIndex
++) {
935 FrameEntryPtr
->LinkTerminate
= TRUE
;
940 // Start the Host Controller
942 if (IsEhcHalted (HcDev
)) {
943 Status
= StartScheduleExecution (HcDev
);
944 if (EFI_ERROR (Status
)) {
945 Status
= EFI_DEVICE_ERROR
;
951 // Set all ports routing to EHC
953 Status
= SetPortRoutingEhc (HcDev
);
954 if (EFI_ERROR (Status
)) {
955 Status
= EFI_DEVICE_ERROR
;
960 case EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG
:
962 Status
= EFI_UNSUPPORTED
;
965 case EFI_USB_HC_RESET_HOST_WITH_DEBUG
:
967 Status
= EFI_UNSUPPORTED
;
971 Status
= EFI_INVALID_PARAMETER
;
981 IN EFI_USB2_HC_PROTOCOL
*This
,
982 OUT EFI_USB_HC_STATE
*State
988 Retrieves current state of the USB host controller.
992 This A pointer to the EFI_USB2_HC_PROTOCOL instance.
993 State A pointer to the EFI_USB_HC_STATE data structure that
994 indicates current state of the USB host controller.
995 Type EFI_USB_HC_STATE is defined below.
999 EfiUsbHcStateOperational,
1000 EfiUsbHcStateSuspend,
1001 EfiUsbHcStateMaximum
1007 The state information of the host controller was returned in State.
1008 EFI_INVALID_PARAMETER
1011 An error was encountered while attempting to retrieve the
1012 host controller's current state.
1017 UINT32 UsbStatusAddr
;
1018 UINT32 UsbStatusReg
;
1020 if (State
== NULL
) {
1021 Status
= EFI_INVALID_PARAMETER
;
1025 UsbStatusAddr
= USBSTS
;
1026 HcDev
= USB2_HC_DEV_FROM_THIS (This
);
1028 Status
= ReadEhcOperationalReg (
1033 if (EFI_ERROR (Status
)) {
1034 Status
= EFI_DEVICE_ERROR
;
1038 if (UsbStatusReg
& USBSTS_HCH
) {
1039 *State
= EfiUsbHcStateHalt
;
1041 *State
= EfiUsbHcStateOperational
;
1051 IN EFI_USB2_HC_PROTOCOL
*This
,
1052 IN EFI_USB_HC_STATE State
1056 Routine Description:
1058 Sets the USB host controller to a specific state.
1062 This - A pointer to the EFI_USB2_HC_PROTOCOL instance.
1063 State - Indicates the state of the host controller that will be set.
1068 The USB host controller was successfully placed in the state
1070 EFI_INVALID_PARAMETER
1073 Failed to set the state specified by State due to device error.
1079 UINT32 UsbCommandAddr
;
1080 UINT32 UsbCommandReg
;
1081 EFI_USB_HC_STATE CurrentState
;
1083 UsbCommandAddr
= USBCMD
;
1084 HcDev
= USB2_HC_DEV_FROM_THIS (This
);
1086 Status
= EhciGetState (This
, &CurrentState
);
1087 if (EFI_ERROR (Status
)) {
1088 Status
= EFI_DEVICE_ERROR
;
1094 case EfiUsbHcStateHalt
:
1096 if (EfiUsbHcStateHalt
== CurrentState
) {
1097 Status
= EFI_SUCCESS
;
1099 } else if (EfiUsbHcStateOperational
== CurrentState
) {
1100 Status
= ReadEhcOperationalReg (
1105 if (EFI_ERROR (Status
)) {
1106 Status
= EFI_DEVICE_ERROR
;
1110 UsbCommandReg
&= ~USBCMD_RS
;
1111 Status
= WriteEhcOperationalReg (
1116 if (EFI_ERROR (Status
)) {
1117 Status
= EFI_DEVICE_ERROR
;
1121 // Ensure the HC is in halt status after send the stop command
1123 Status
= WaitForEhcHalt (HcDev
, EHCI_GENERIC_TIMEOUT
);
1124 if (EFI_ERROR (Status
)) {
1125 Status
= EFI_TIMEOUT
;
1131 case EfiUsbHcStateOperational
:
1133 if (IsEhcSysError (HcDev
)) {
1134 Status
= EFI_DEVICE_ERROR
;
1137 if (EfiUsbHcStateOperational
== CurrentState
) {
1138 Status
= EFI_SUCCESS
;
1140 } else if (EfiUsbHcStateHalt
== CurrentState
) {
1142 // Set Host Controller Run
1144 Status
= ReadEhcOperationalReg (
1149 if (EFI_ERROR (Status
)) {
1150 return EFI_DEVICE_ERROR
;
1153 UsbCommandReg
|= USBCMD_RS
;
1154 Status
= WriteEhcOperationalReg (
1159 if (EFI_ERROR (Status
)) {
1160 Status
= EFI_DEVICE_ERROR
;
1166 case EfiUsbHcStateSuspend
:
1168 Status
= EFI_UNSUPPORTED
;
1173 Status
= EFI_INVALID_PARAMETER
;
1182 EhciGetRootHubPortStatus (
1183 IN EFI_USB2_HC_PROTOCOL
*This
,
1184 IN UINT8 PortNumber
,
1185 OUT EFI_USB_PORT_STATUS
*PortStatus
1189 Routine Description:
1191 Retrieves the current status of a USB root hub port.
1195 This - A pointer to the EFI_USB2_HC_PROTOCOL.
1196 PortNumber - Specifies the root hub port from which the status
1197 is to be retrieved. This value is zero-based. For example,
1198 if a root hub has two ports, then the first port is numbered 0,
1199 and the second port is numbered 1.
1200 PortStatus - A pointer to the current port status bits and
1201 port status change bits.
1205 EFI_SUCCESS The status of the USB root hub port specified
1206 by PortNumber was returned in PortStatus.
1207 EFI_INVALID_PARAMETER PortNumber is invalid.
1208 EFI_DEVICE_ERROR Can't read register
1214 UINT32 PortStatusControlAddr
;
1215 UINT32 PortStatusControlReg
;
1217 UINT8 TotalPortNumber
;
1218 UINT8 Is64BitCapable
;
1220 if (PortStatus
== NULL
) {
1221 Status
= EFI_INVALID_PARAMETER
;
1232 if (PortNumber
>= TotalPortNumber
) {
1233 Status
= EFI_INVALID_PARAMETER
;
1237 HcDev
= USB2_HC_DEV_FROM_THIS (This
);
1238 PortStatusControlAddr
= (UINT32
) (PORTSC
+ (4 * PortNumber
));
1241 // Clear port status
1243 PortStatus
->PortStatus
= 0;
1244 PortStatus
->PortChangeStatus
= 0;
1246 Status
= ReadEhcOperationalReg (
1248 PortStatusControlAddr
,
1249 &PortStatusControlReg
1251 if (EFI_ERROR (Status
)) {
1252 Status
= EFI_DEVICE_ERROR
;
1257 // Fill Port Status bits
1261 // Current Connect Status
1263 if (PORTSC_CCS
& PortStatusControlReg
) {
1264 PortStatus
->PortStatus
|= USB_PORT_STAT_CONNECTION
;
1267 // Port Enabled/Disabled
1269 if (PORTSC_PED
& PortStatusControlReg
) {
1270 PortStatus
->PortStatus
|= USB_PORT_STAT_ENABLE
;
1275 if (PORTSC_SUSP
& PortStatusControlReg
) {
1276 PortStatus
->PortStatus
|= USB_PORT_STAT_SUSPEND
;
1279 // Over-current Active
1281 if (PORTSC_OCA
& PortStatusControlReg
) {
1282 PortStatus
->PortStatus
|= USB_PORT_STAT_OVERCURRENT
;
1287 if (PORTSC_PR
& PortStatusControlReg
) {
1288 PortStatus
->PortStatus
|= USB_PORT_STAT_RESET
;
1293 if (PORTSC_PP
& PortStatusControlReg
) {
1294 PortStatus
->PortStatus
|= USB_PORT_STAT_POWER
;
1299 if (PORTSC_PO
& PortStatusControlReg
) {
1300 PortStatus
->PortStatus
|= USB_PORT_STAT_OWNER
;
1303 // Identify device speed
1305 if (PORTSC_LS_KSTATE
& PortStatusControlReg
) {
1307 // Low Speed Device Attached
1309 PortStatus
->PortStatus
|= USB_PORT_STAT_LOW_SPEED
;
1312 // Not Low Speed Device Attached
1314 if ((PORTSC_CCS
& PortStatusControlReg
) && (PORTSC_CSC
& PortStatusControlReg
)) {
1315 HcDev
->DeviceSpeed
[PortNumber
] = (UINT16
) (IsHighSpeedDevice (This
, PortNumber
) ? USB_PORT_STAT_HIGH_SPEED
: 0);
1317 PortStatus
->PortStatus
= (UINT16
) (PortStatus
->PortStatus
| HcDev
->DeviceSpeed
[PortNumber
]);
1320 // Fill Port Status Change bits
1323 // Connect Status Change
1325 if (PORTSC_CSC
& PortStatusControlReg
) {
1326 PortStatus
->PortChangeStatus
|= USB_PORT_STAT_C_CONNECTION
;
1329 // Port Enabled/Disabled Change
1331 if (PORTSC_PEDC
& PortStatusControlReg
) {
1332 PortStatus
->PortChangeStatus
|= USB_PORT_STAT_C_ENABLE
;
1335 // Port Over Current Change
1337 if (PORTSC_OCC
& PortStatusControlReg
) {
1338 PortStatus
->PortChangeStatus
|= USB_PORT_STAT_C_OVERCURRENT
;
1347 EhciSetRootHubPortFeature (
1348 IN EFI_USB2_HC_PROTOCOL
*This
,
1349 IN UINT8 PortNumber
,
1350 IN EFI_USB_PORT_FEATURE PortFeature
1354 Routine Description:
1356 Sets a feature for the specified root hub port.
1360 This - A pointer to the EFI_USB2_HC_PROTOCOL.
1361 PortNumber - Specifies the root hub port whose feature
1362 is requested to be set.
1363 PortFeature - Indicates the feature selector associated
1364 with the feature set request.
1369 The feature specified by PortFeature was set for the
1370 USB root hub port specified by PortNumber.
1371 EFI_INVALID_PARAMETER
1372 PortNumber is invalid or PortFeature is invalid.
1380 UINT32 PortStatusControlAddr
;
1381 UINT32 PortStatusControlReg
;
1383 UINT8 TotalPortNumber
;
1384 UINT8 Is64BitCapable
;
1393 if (PortNumber
>= TotalPortNumber
) {
1394 Status
= EFI_INVALID_PARAMETER
;
1398 HcDev
= USB2_HC_DEV_FROM_THIS (This
);
1399 PortStatusControlAddr
= (UINT32
) (PORTSC
+ (4 * PortNumber
));
1401 Status
= ReadEhcOperationalReg (
1403 PortStatusControlAddr
,
1404 &PortStatusControlReg
1406 if (EFI_ERROR (Status
)) {
1407 Status
= EFI_DEVICE_ERROR
;
1411 switch (PortFeature
) {
1413 case EfiUsbPortEnable
:
1416 // Sofeware can't set this bit, Port can only be enable by the Host Controller
1417 // as a part of the reset and enable
1419 PortStatusControlReg
&= 0xffffffd5;
1420 PortStatusControlReg
|= PORTSC_PED
;
1423 case EfiUsbPortSuspend
:
1425 PortStatusControlReg
&= 0xffffffd5;
1426 PortStatusControlReg
|= PORTSC_SUSP
;
1429 case EfiUsbPortReset
:
1432 // Make sure Host Controller not halt before reset it
1434 if (IsEhcHalted (HcDev
)) {
1435 Status
= StartScheduleExecution (HcDev
);
1436 if (EFI_ERROR (Status
)) {
1437 Status
= EFI_DEVICE_ERROR
;
1440 Status
= WaitForEhcNotHalt (HcDev
, EHCI_GENERIC_TIMEOUT
);
1441 if (EFI_ERROR (Status
)) {
1442 DEBUG ((gEHCDebugLevel
, "EHCI: WaitForEhcNotHalt TimeOut\n"));
1443 Status
= EFI_DEVICE_ERROR
;
1447 PortStatusControlReg
&= 0xffffffd5;
1448 PortStatusControlReg
|= PORTSC_PR
;
1450 // Set one to PortReset bit must also set zero to PortEnable bit
1452 PortStatusControlReg
&= ~PORTSC_PED
;
1455 case EfiUsbPortPower
:
1458 // No support, no operation
1462 case EfiUsbPortOwner
:
1464 PortStatusControlReg
&= 0xffffffd5;
1465 PortStatusControlReg
|= PORTSC_PO
;
1470 Status
= EFI_INVALID_PARAMETER
;
1474 Status
= WriteEhcOperationalReg (
1476 PortStatusControlAddr
,
1477 PortStatusControlReg
1479 if (EFI_ERROR (Status
)) {
1480 Status
= EFI_DEVICE_ERROR
;
1489 EhciClearRootHubPortFeature (
1490 IN EFI_USB2_HC_PROTOCOL
*This
,
1491 IN UINT8 PortNumber
,
1492 IN EFI_USB_PORT_FEATURE PortFeature
1496 Routine Description:
1498 Clears a feature for the specified root hub port.
1502 This - A pointer to the EFI_USB2_HC_PROTOCOL instance.
1503 PortNumber - Specifies the root hub port whose feature
1504 is requested to be cleared.
1505 PortFeature - Indicates the feature selector associated with the
1506 feature clear request.
1511 The feature specified by PortFeature was cleared for the
1512 USB root hub port specified by PortNumber.
1513 EFI_INVALID_PARAMETER
1514 PortNumber is invalid or PortFeature is invalid.
1522 UINT32 PortStatusControlAddr
;
1523 UINT32 PortStatusControlReg
;
1525 UINT8 TotalPortNumber
;
1526 UINT8 Is64BitCapable
;
1535 if (PortNumber
>= TotalPortNumber
) {
1536 Status
= EFI_INVALID_PARAMETER
;
1540 HcDev
= USB2_HC_DEV_FROM_THIS (This
);
1541 PortStatusControlAddr
= (UINT32
) (PORTSC
+ (4 * PortNumber
));
1543 Status
= ReadEhcOperationalReg (
1545 PortStatusControlAddr
,
1546 &PortStatusControlReg
1548 if (EFI_ERROR (Status
)) {
1549 Status
= EFI_DEVICE_ERROR
;
1553 switch (PortFeature
) {
1555 case EfiUsbPortEnable
:
1558 // Clear PORT_ENABLE feature means disable port.
1560 PortStatusControlReg
&= 0xffffffd5;
1561 PortStatusControlReg
&= ~PORTSC_PED
;
1564 case EfiUsbPortSuspend
:
1567 // A write of zero to this bit is ignored by the host controller.
1568 // The host controller will unconditionally set this bit to a zero when:
1569 // 1. software sets the Forct Port Resume bit to a zero from a one.
1570 // 2. software sets the Port Reset bit to a one frome a zero.
1572 PortStatusControlReg
&= 0xffffffd5;
1573 PortStatusControlReg
&= ~PORTSC_FPR
;
1576 case EfiUsbPortReset
:
1579 // Clear PORT_RESET means clear the reset signal.
1581 PortStatusControlReg
&= 0xffffffd5;
1582 PortStatusControlReg
&= ~PORTSC_PR
;
1585 case EfiUsbPortPower
:
1588 // No support, no operation
1592 case EfiUsbPortOwner
:
1595 // Clear port owner means this port owned by EHC
1597 PortStatusControlReg
&= 0xffffffd5;
1598 PortStatusControlReg
&= ~PORTSC_PO
;
1601 case EfiUsbPortConnectChange
:
1604 // Clear connect status change
1606 PortStatusControlReg
&= 0xffffffd5;
1607 PortStatusControlReg
|= PORTSC_CSC
;
1610 case EfiUsbPortEnableChange
:
1613 // Clear enable status change
1615 PortStatusControlReg
&= 0xffffffd5;
1616 PortStatusControlReg
|= PORTSC_PEDC
;
1619 case EfiUsbPortSuspendChange
:
1622 // No related bit, no operation
1626 case EfiUsbPortOverCurrentChange
:
1629 // Clear PortOverCurrent change
1631 PortStatusControlReg
&= 0xffffffd5;
1632 PortStatusControlReg
|= PORTSC_OCC
;
1635 case EfiUsbPortResetChange
:
1638 // No related bit, no operation
1644 Status
= EFI_INVALID_PARAMETER
;
1648 Status
= WriteEhcOperationalReg (
1650 PortStatusControlAddr
,
1651 PortStatusControlReg
1653 if (EFI_ERROR (Status
)) {
1654 Status
= EFI_DEVICE_ERROR
;
1664 EhciControlTransfer (
1665 IN EFI_USB2_HC_PROTOCOL
*This
,
1666 IN UINT8 DeviceAddress
,
1667 IN UINT8 DeviceSpeed
,
1668 IN UINTN MaximumPacketLength
,
1669 IN EFI_USB_DEVICE_REQUEST
*Request
,
1670 IN EFI_USB_DATA_DIRECTION TransferDirection
,
1672 IN OUT UINTN
*DataLength
,
1674 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
1675 OUT UINT32
*TransferResult
1679 Routine Description:
1681 Submits control transfer to a target USB device.
1685 This - A pointer to the EFI_USB2_HC_PROTOCOL instance.
1686 DeviceAddress - Represents the address of the target device on the USB,
1687 which is assigned during USB enumeration.
1688 DeviceSpeed - Indicates target device speed.
1689 MaximumPacketLength - Indicates the maximum packet size that the
1690 default control transfer endpoint is capable of
1691 sending or receiving.
1692 Request - A pointer to the USB device request that will be sent
1694 TransferDirection - Specifies the data direction for the transfer.
1695 There are three values available, DataIn, DataOut
1697 Data - A pointer to the buffer of data that will be transmitted
1698 to USB device or received from USB device.
1699 DataLength - Indicates the size, in bytes, of the data buffer
1701 TimeOut - Indicates the maximum time, in microseconds,
1702 which the transfer is allowed to complete.
1703 Translator - A pointr to the transaction translator data.
1704 TransferResult - A pointer to the detailed result information generated
1705 by this control transfer.
1710 The control transfer was completed successfully.
1711 EFI_OUT_OF_RESOURCES
1712 The control transfer could not be completed due to a lack of resources.
1713 EFI_INVALID_PARAMETER
1714 Some parameters are invalid.
1716 The control transfer failed due to timeout.
1718 The control transfer failed due to host controller or device error.
1719 Caller should check TranferResult for detailed error information.
1726 EHCI_QH_ENTITY
*QhPtr
;
1727 EHCI_QTD_ENTITY
*ControlQtdsPtr
;
1730 UINT8
*RequestCursor
;
1734 ControlQtdsPtr
= NULL
;
1737 RequestCursor
= NULL
;
1739 HcDev
= USB2_HC_DEV_FROM_THIS (This
);
1742 // Parameters Checking
1744 if (TransferDirection
!= EfiUsbDataIn
&&
1745 TransferDirection
!= EfiUsbDataOut
&&
1746 TransferDirection
!= EfiUsbNoData
1748 Status
= EFI_INVALID_PARAMETER
;
1752 if (EfiUsbNoData
== TransferDirection
) {
1753 if (NULL
!= Data
|| 0 != *DataLength
) {
1754 Status
= EFI_INVALID_PARAMETER
;
1758 if (NULL
== Data
|| 0 == *DataLength
) {
1759 Status
= EFI_INVALID_PARAMETER
;
1764 if (Request
== NULL
|| TransferResult
== NULL
) {
1765 Status
= EFI_INVALID_PARAMETER
;
1769 if (EFI_USB_SPEED_LOW
== DeviceSpeed
) {
1770 if (MaximumPacketLength
!= 8) {
1771 Status
= EFI_INVALID_PARAMETER
;
1774 } else if (MaximumPacketLength
!= 8 &&
1775 MaximumPacketLength
!= 16 &&
1776 MaximumPacketLength
!= 32 &&
1777 MaximumPacketLength
!= 64
1779 Status
= EFI_INVALID_PARAMETER
;
1784 // If errors exist that cause host controller halt,
1785 // then return EFI_DEVICE_ERROR.
1787 if (IsEhcHalted (HcDev
) || IsEhcSysError (HcDev
)) {
1788 ClearEhcAllStatus (HcDev
);
1789 *TransferResult
= EFI_USB_ERR_SYSTEM
;
1790 Status
= EFI_DEVICE_ERROR
;
1795 // Map the Request for bus master access.
1796 // BusMasterRead means cpu write
1798 Status
= MapRequestBuffer (
1804 if (EFI_ERROR (Status
)) {
1805 *TransferResult
= EFI_USB_ERR_SYSTEM
;
1806 Status
= EFI_DEVICE_ERROR
;
1811 // Map the source data buffer for bus master access.
1813 Status
= MapDataBuffer (
1822 if (EFI_ERROR (Status
)) {
1823 *TransferResult
= EFI_USB_ERR_SYSTEM
;
1824 Status
= EFI_DEVICE_ERROR
;
1829 // Create and init control Qh
1831 Status
= CreateControlQh (
1835 MaximumPacketLength
,
1839 if (EFI_ERROR (Status
)) {
1840 *TransferResult
= EFI_USB_ERR_SYSTEM
;
1841 Status
= EFI_OUT_OF_RESOURCES
;
1846 // Create and init control Qtds
1848 Status
= CreateControlQtds (
1857 if (EFI_ERROR (Status
)) {
1858 *TransferResult
= EFI_USB_ERR_SYSTEM
;
1859 Status
= EFI_OUT_OF_RESOURCES
;
1866 LinkQtdToQh (QhPtr
, ControlQtdsPtr
);
1868 ClearEhcAllStatus (HcDev
);
1871 // Link Qh and Qtds to Async Schedule List
1873 Status
= LinkQhToAsyncList (HcDev
, QhPtr
);
1874 if (EFI_ERROR (Status
)) {
1875 *TransferResult
= EFI_USB_ERR_SYSTEM
;
1876 Status
= EFI_DEVICE_ERROR
;
1881 // Poll Qh-Qtds execution and get result.
1882 // detail status is returned
1884 Status
= ExecuteTransfer (
1893 if (EFI_ERROR (Status
)) {
1898 // If has errors that cause host controller halt,
1899 // then return EFI_DEVICE_ERROR directly.
1901 if (IsEhcHalted (HcDev
) || IsEhcSysError (HcDev
)) {
1902 *TransferResult
|= EFI_USB_ERR_SYSTEM
;
1905 ClearEhcAllStatus (HcDev
);
1908 UnlinkQhFromAsyncList (HcDev
, QhPtr
);
1909 DestoryQtds (HcDev
, ControlQtdsPtr
);
1911 DestoryQh (HcDev
, QhPtr
);
1913 HcDev
->PciIo
->Unmap (HcDev
->PciIo
, DataMap
);
1915 HcDev
->PciIo
->Unmap (HcDev
->PciIo
, RequestMap
);
1917 HcDev
->PciIo
->Flush (HcDev
->PciIo
);
1924 IN EFI_USB2_HC_PROTOCOL
*This
,
1925 IN UINT8 DeviceAddress
,
1926 IN UINT8 EndPointAddress
,
1927 IN UINT8 DeviceSpeed
,
1928 IN UINTN MaximumPacketLength
,
1929 IN UINT8 DataBuffersNumber
,
1930 IN OUT VOID
*Data
[EFI_USB_MAX_BULK_BUFFER_NUM
],
1931 IN OUT UINTN
*DataLength
,
1932 IN OUT UINT8
*DataToggle
,
1934 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
1935 OUT UINT32
*TransferResult
1939 Routine Description:
1941 Submits bulk transfer to a bulk endpoint of a USB device.
1945 This - A pointer to the EFI_USB2_HC_PROTOCOL instance.
1946 DeviceAddress - Represents the address of the target device on the USB,
1947 which is assigned during USB enumeration.
1948 EndPointAddress - The combination of an endpoint number and an
1949 endpoint direction of the target USB device.
1950 Each endpoint address supports data transfer in
1951 one direction except the control endpoint
1952 (whose default endpoint address is 0).
1953 It is the caller's responsibility to make sure that
1954 the EndPointAddress represents a bulk endpoint.
1955 DeviceSpeed - Indicates device speed. The supported values are EFI_USB_SPEED_FULL
1956 and EFI_USB_SPEED_HIGH.
1957 MaximumPacketLength - Indicates the maximum packet size the target endpoint
1958 is capable of sending or receiving.
1959 DataBuffersNumber - Number of data buffers prepared for the transfer.
1960 Data - Array of pointers to the buffers of data that will be transmitted
1961 to USB device or received from USB device.
1962 DataLength - When input, indicates the size, in bytes, of the data buffer
1963 specified by Data. When output, indicates the actually
1964 transferred data size.
1965 DataToggle - A pointer to the data toggle value. On input, it indicates
1966 the initial data toggle value the bulk transfer should adopt;
1967 on output, it is updated to indicate the data toggle value
1968 of the subsequent bulk transfer.
1969 Translator - A pointr to the transaction translator data.
1970 TimeOut - Indicates the maximum time, in microseconds, which the
1971 transfer is allowed to complete.
1972 TransferResult - A pointer to the detailed result information of the
1978 The bulk transfer was completed successfully.
1979 EFI_OUT_OF_RESOURCES
1980 The bulk transfer could not be submitted due to lack of resource.
1981 EFI_INVALID_PARAMETER
1982 Some parameters are invalid.
1984 The bulk transfer failed due to timeout.
1986 The bulk transfer failed due to host controller or device error.
1987 Caller should check TranferResult for detailed error information.
1994 EHCI_QH_ENTITY
*QhPtr
;
1995 EHCI_QTD_ENTITY
*BulkQtdsPtr
;
1998 EFI_USB_DATA_DIRECTION TransferDirection
;
2004 HcDev
= USB2_HC_DEV_FROM_THIS (This
);
2007 // Parameters Checking
2009 if (NULL
== DataLength
||
2012 NULL
== TransferResult
2014 Status
= EFI_INVALID_PARAMETER
;
2018 if (*DataLength
== 0) {
2019 Status
= EFI_INVALID_PARAMETER
;
2023 if (1 != *DataToggle
&& 0 != *DataToggle
) {
2024 Status
= EFI_INVALID_PARAMETER
;
2028 if (EFI_USB_SPEED_LOW
== DeviceSpeed
) {
2029 Status
= EFI_INVALID_PARAMETER
;
2033 if (EFI_USB_SPEED_FULL
== DeviceSpeed
) {
2034 if (MaximumPacketLength
> 64) {
2035 Status
= EFI_INVALID_PARAMETER
;
2040 if (EFI_USB_SPEED_HIGH
== DeviceSpeed
) {
2041 if (MaximumPacketLength
> 512) {
2042 Status
= EFI_INVALID_PARAMETER
;
2048 // if has errors that cause host controller halt,
2049 // then return EFI_DEVICE_ERROR directly.
2051 if (IsEhcHalted (HcDev
) || IsEhcSysError (HcDev
)) {
2052 ClearEhcAllStatus (HcDev
);
2053 *TransferResult
= EFI_USB_ERR_SYSTEM
;
2054 Status
= EFI_DEVICE_ERROR
;
2058 Status
= ClearEhcAllStatus (HcDev
);
2059 if (EFI_ERROR (Status
)) {
2060 Status
= EFI_DEVICE_ERROR
;
2065 // construct QH and TD data structures,
2066 // and link them together
2068 if (EndPointAddress
& 0x80) {
2069 TransferDirection
= EfiUsbDataIn
;
2071 TransferDirection
= EfiUsbDataOut
;
2074 Status
= MapDataBuffer (
2083 if (EFI_ERROR (Status
)) {
2084 *TransferResult
= EFI_USB_ERR_SYSTEM
;
2085 Status
= EFI_DEVICE_ERROR
;
2090 // Create and init Bulk Qh
2092 Status
= CreateBulkQh (
2098 MaximumPacketLength
,
2102 if (EFI_ERROR (Status
)) {
2103 *TransferResult
= EFI_USB_ERR_SYSTEM
;
2104 Status
= EFI_OUT_OF_RESOURCES
;
2109 // Create and init Bulk Qtds
2111 Status
= CreateBulkOrInterruptQtds (
2119 if (EFI_ERROR (Status
)) {
2120 *TransferResult
= EFI_USB_ERR_SYSTEM
;
2121 Status
= EFI_OUT_OF_RESOURCES
;
2128 LinkQtdToQh (QhPtr
, BulkQtdsPtr
);
2130 ClearEhcAllStatus (HcDev
);
2133 // Link Qh and qtds to Async Schedule List
2135 Status
= LinkQhToAsyncList (HcDev
, QhPtr
);
2136 if (EFI_ERROR (Status
)) {
2137 *TransferResult
= EFI_USB_ERR_SYSTEM
;
2138 Status
= EFI_DEVICE_ERROR
;
2143 // Poll QH-TDs execution and get result.
2144 // detail status is returned
2146 Status
= ExecuteTransfer (
2155 if (EFI_ERROR (Status
)) {
2160 // if has errors that cause host controller halt,
2161 // then return EFI_DEVICE_ERROR directly.
2163 if (IsEhcHalted (HcDev
) || IsEhcSysError (HcDev
)) {
2164 *TransferResult
|= EFI_USB_ERR_SYSTEM
;
2167 ClearEhcAllStatus (HcDev
);
2170 UnlinkQhFromAsyncList (HcDev
, QhPtr
);
2171 DestoryQtds (HcDev
, BulkQtdsPtr
);
2173 DestoryQh (HcDev
, QhPtr
);
2175 HcDev
->PciIo
->Unmap (HcDev
->PciIo
, DataMap
);
2177 HcDev
->PciIo
->Flush (HcDev
->PciIo
);
2183 EhciAsyncInterruptTransfer (
2184 IN EFI_USB2_HC_PROTOCOL
* This
,
2185 IN UINT8 DeviceAddress
,
2186 IN UINT8 EndPointAddress
,
2187 IN UINT8 DeviceSpeed
,
2188 IN UINTN MaximumPacketLength
,
2189 IN BOOLEAN IsNewTransfer
,
2190 IN OUT UINT8
*DataToggle
,
2191 IN UINTN PollingInterval
,
2192 IN UINTN DataLength
,
2193 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
* Translator
,
2194 IN EFI_ASYNC_USB_TRANSFER_CALLBACK CallBackFunction
,
2195 IN VOID
*Context OPTIONAL
2199 Routine Description:
2201 Submits an asynchronous interrupt transfer to an
2202 interrupt endpoint of a USB device.
2203 Translator parameter doesn't exist in UEFI2.0 spec, but it will be updated
2204 in the following specification version.
2208 This - A pointer to the EFI_USB2_HC_PROTOCOL instance.
2209 DeviceAddress - Represents the address of the target device on the USB,
2210 which is assigned during USB enumeration.
2211 EndPointAddress - The combination of an endpoint number and an endpoint
2212 direction of the target USB device. Each endpoint address
2213 supports data transfer in one direction except the
2214 control endpoint (whose default endpoint address is 0).
2215 It is the caller's responsibility to make sure that
2216 the EndPointAddress represents an interrupt endpoint.
2217 DeviceSpeed - Indicates device speed.
2218 MaximumPacketLength - Indicates the maximum packet size the target endpoint
2219 is capable of sending or receiving.
2220 IsNewTransfer - If TRUE, an asynchronous interrupt pipe is built between
2221 the host and the target interrupt endpoint.
2222 If FALSE, the specified asynchronous interrupt pipe
2224 DataToggle - A pointer to the data toggle value. On input, it is valid
2225 when IsNewTransfer is TRUE, and it indicates the initial
2226 data toggle value the asynchronous interrupt transfer
2228 On output, it is valid when IsNewTransfer is FALSE,
2229 and it is updated to indicate the data toggle value of
2230 the subsequent asynchronous interrupt transfer.
2231 PollingInterval - Indicates the interval, in milliseconds, that the
2232 asynchronous interrupt transfer is polled.
2233 This parameter is required when IsNewTransfer is TRUE.
2234 DataLength - Indicates the length of data to be received at the
2235 rate specified by PollingInterval from the target
2236 asynchronous interrupt endpoint. This parameter
2237 is only required when IsNewTransfer is TRUE.
2238 Translator - A pointr to the transaction translator data.
2239 CallBackFunction - The Callback function.This function is called at the
2240 rate specified by PollingInterval.This parameter is
2241 only required when IsNewTransfer is TRUE.
2242 Context - The context that is passed to the CallBackFunction.
2243 - This is an optional parameter and may be NULL.
2248 The asynchronous interrupt transfer request has been successfully
2249 submitted or canceled.
2250 EFI_INVALID_PARAMETER
2251 Some parameters are invalid.
2252 EFI_OUT_OF_RESOURCES
2253 The request could not be completed due to a lack of resources.
2262 EHCI_QH_ENTITY
*QhPtr
;
2263 EHCI_QTD_ENTITY
*InterruptQtdsPtr
;
2268 EHCI_ASYNC_REQUEST
*AsyncRequestPtr
;
2272 InterruptQtdsPtr
= NULL
;
2276 AsyncRequestPtr
= NULL
;
2277 HcDev
= USB2_HC_DEV_FROM_THIS (This
);
2280 // Parameters Checking
2282 if (!IsDataInTransfer (EndPointAddress
)) {
2283 Status
= EFI_INVALID_PARAMETER
;
2287 if (IsNewTransfer
) {
2288 if (0 == DataLength
) {
2289 Status
= EFI_INVALID_PARAMETER
;
2293 if (*DataToggle
!= 1 && *DataToggle
!= 0) {
2294 Status
= EFI_INVALID_PARAMETER
;
2298 if (PollingInterval
> 255 || PollingInterval
< 1) {
2299 Status
= EFI_INVALID_PARAMETER
;
2305 // if has errors that cause host controller halt,
2306 // then return EFI_DEVICE_ERROR directly.
2308 if (IsEhcHalted (HcDev
) || IsEhcSysError (HcDev
)) {
2309 ClearEhcAllStatus (HcDev
);
2310 Status
= EFI_DEVICE_ERROR
;
2314 Status
= ClearEhcAllStatus (HcDev
);
2315 if (EFI_ERROR (Status
)) {
2316 Status
= EFI_DEVICE_ERROR
;
2321 // Delete Async interrupt transfer request
2323 if (!IsNewTransfer
) {
2325 OldTpl
= gBS
->RaiseTPL (EFI_TPL_NOTIFY
);
2327 Status
= DeleteAsyncRequestTransfer (
2334 gBS
->RestoreTPL (OldTpl
);
2339 Status
= EhciAllocatePool (
2341 (UINT8
**) &AsyncRequestPtr
,
2342 sizeof (EHCI_ASYNC_REQUEST
)
2344 if (EFI_ERROR (Status
)) {
2345 Status
= EFI_OUT_OF_RESOURCES
;
2349 Status
= EhciAllocatePool (HcDev
, &DataPtr
, DataLength
);
2350 if (EFI_ERROR (Status
)) {
2351 Status
= EFI_OUT_OF_RESOURCES
;
2355 MappedLength
= DataLength
;
2356 Status
= MapDataBuffer (
2365 if (EFI_ERROR (Status
)) {
2366 Status
= EFI_DEVICE_ERROR
;
2371 // Create and init Interrupt Qh
2373 Status
= CreateInterruptQh (
2379 MaximumPacketLength
,
2384 if (EFI_ERROR (Status
)) {
2385 Status
= EFI_OUT_OF_RESOURCES
;
2390 // Create and init Interrupt Qtds
2392 Status
= CreateBulkOrInterruptQtds (
2400 if (EFI_ERROR (Status
)) {
2401 Status
= EFI_OUT_OF_RESOURCES
;
2408 LinkQtdToQh (QhPtr
, InterruptQtdsPtr
);
2411 // Init AsyncRequest Entry
2413 AsyncRequestPtr
->Context
= Context
;
2414 AsyncRequestPtr
->CallBackFunc
= CallBackFunction
;
2415 AsyncRequestPtr
->TransferType
= ASYNC_INTERRUPT_TRANSFER
;
2416 AsyncRequestPtr
->QhPtr
= QhPtr
;
2417 AsyncRequestPtr
->Prev
= NULL
;
2418 AsyncRequestPtr
->Next
= NULL
;
2420 if (NULL
== HcDev
->AsyncRequestList
) {
2421 Status
= StartPollingTimer (HcDev
);
2422 if (EFI_ERROR (Status
)) {
2423 Status
= EFI_DEVICE_ERROR
;
2424 CleanUpAllAsyncRequestTransfer (HcDev
);
2430 // Link Entry to AsyncRequest List
2432 LinkToAsyncReqeust (HcDev
, AsyncRequestPtr
);
2434 ClearEhcAllStatus (HcDev
);
2436 Status
= DisablePeriodicSchedule (HcDev
);
2437 if (EFI_ERROR (Status
)) {
2438 Status
= EFI_DEVICE_ERROR
;
2442 Status
= WaitForPeriodicScheduleDisable (HcDev
, EHCI_GENERIC_TIMEOUT
);
2443 if (EFI_ERROR (Status
)) {
2444 Status
= EFI_TIMEOUT
;
2449 // Link Qh and Qtds to Periodic Schedule List
2451 LinkQhToPeriodicList (HcDev
, QhPtr
);
2453 Status
= EnablePeriodicSchedule (HcDev
);
2454 if (EFI_ERROR (Status
)) {
2455 Status
= EFI_DEVICE_ERROR
;
2459 Status
= WaitForPeriodicScheduleEnable (HcDev
, EHCI_GENERIC_TIMEOUT
);
2460 if (EFI_ERROR (Status
)) {
2461 Status
= EFI_TIMEOUT
;
2465 if (IsEhcHalted (HcDev
)) {
2466 Status
= StartScheduleExecution (HcDev
);
2467 if (EFI_ERROR (Status
)) {
2468 Status
= EFI_DEVICE_ERROR
;
2473 HcDev
->PciIo
->Flush (HcDev
->PciIo
);
2477 DestoryQh (HcDev
, QhPtr
);
2479 EhciFreePool (HcDev
, DataPtr
, DataLength
);
2483 (UINT8
*) AsyncRequestPtr
,
2484 sizeof (EHCI_ASYNC_REQUEST
)
2487 HcDev
->PciIo
->Unmap (HcDev
->PciIo
, DataMap
);
2494 EhciSyncInterruptTransfer (
2495 IN EFI_USB2_HC_PROTOCOL
*This
,
2496 IN UINT8 DeviceAddress
,
2497 IN UINT8 EndPointAddress
,
2498 IN UINT8 DeviceSpeed
,
2499 IN UINTN MaximumPacketLength
,
2501 IN OUT UINTN
*DataLength
,
2502 IN OUT UINT8
*DataToggle
,
2504 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
2505 OUT UINT32
*TransferResult
2509 Routine Description:
2511 Submits synchronous interrupt transfer to an interrupt endpoint
2513 Translator parameter doesn't exist in UEFI2.0 spec, but it will be updated
2514 in the following specification version.
2518 This - A pointer to the EFI_USB2_HC_PROTOCOL instance.
2519 DeviceAddress - Represents the address of the target device on the USB,
2520 which is assigned during USB enumeration.
2521 EndPointAddress - The combination of an endpoint number and an endpoint
2522 direction of the target USB device. Each endpoint
2523 address supports data transfer in one direction
2524 except the control endpoint (whose default
2525 endpoint address is 0). It is the caller's responsibility
2526 to make sure that the EndPointAddress represents
2527 an interrupt endpoint.
2528 DeviceSpeed - Indicates device speed.
2529 MaximumPacketLength - Indicates the maximum packet size the target endpoint
2530 is capable of sending or receiving.
2531 Data - A pointer to the buffer of data that will be transmitted
2532 to USB device or received from USB device.
2533 DataLength - On input, the size, in bytes, of the data buffer specified
2534 by Data. On output, the number of bytes transferred.
2535 DataToggle - A pointer to the data toggle value. On input, it indicates
2536 the initial data toggle value the synchronous interrupt
2537 transfer should adopt;
2538 on output, it is updated to indicate the data toggle value
2539 of the subsequent synchronous interrupt transfer.
2540 TimeOut - Indicates the maximum time, in microseconds, which the
2541 transfer is allowed to complete.
2542 Translator - A pointr to the transaction translator data.
2543 TransferResult - A pointer to the detailed result information from
2544 the synchronous interrupt transfer.
2549 The synchronous interrupt transfer was completed successfully.
2550 EFI_OUT_OF_RESOURCES
2551 The synchronous interrupt transfer could not be submitted due
2552 to lack of resource.
2553 EFI_INVALID_PARAMETER
2554 Some parameters are invalid.
2556 The synchronous interrupt transfer failed due to timeout.
2558 The synchronous interrupt transfer failed due to host controller
2559 or device error. Caller should check TranferResult for detailed
2567 EHCI_QH_ENTITY
*QhPtr
;
2568 EHCI_QTD_ENTITY
*InterruptQtdsPtr
;
2573 InterruptQtdsPtr
= NULL
;
2576 HcDev
= USB2_HC_DEV_FROM_THIS (This
);
2579 // Parameters Checking
2581 if (DataLength
== NULL
||
2583 TransferResult
== NULL
2585 Status
= EFI_INVALID_PARAMETER
;
2589 if (!IsDataInTransfer (EndPointAddress
)) {
2590 Status
= EFI_INVALID_PARAMETER
;
2594 if (0 == *DataLength
) {
2595 Status
= EFI_INVALID_PARAMETER
;
2599 if (*DataToggle
!= 1 && *DataToggle
!= 0) {
2600 Status
= EFI_INVALID_PARAMETER
;
2604 if (EFI_USB_SPEED_LOW
== DeviceSpeed
&& 8 != MaximumPacketLength
) {
2605 Status
= EFI_INVALID_PARAMETER
;
2609 if (EFI_USB_SPEED_FULL
== DeviceSpeed
&& MaximumPacketLength
> 64) {
2610 Status
= EFI_INVALID_PARAMETER
;
2614 if (EFI_USB_SPEED_HIGH
== DeviceSpeed
&& MaximumPacketLength
> 3072) {
2615 Status
= EFI_INVALID_PARAMETER
;
2620 // if has errors that cause host controller halt,
2621 // then return EFI_DEVICE_ERROR directly.
2623 if (IsEhcHalted (HcDev
) || IsEhcSysError (HcDev
)) {
2624 ClearEhcAllStatus (HcDev
);
2625 *TransferResult
= EFI_USB_ERR_SYSTEM
;
2626 Status
= EFI_DEVICE_ERROR
;
2630 Status
= ClearEhcAllStatus (HcDev
);
2631 if (EFI_ERROR (Status
)) {
2632 Status
= EFI_DEVICE_ERROR
;
2636 Status
= MapDataBuffer (
2645 if (EFI_ERROR (Status
)) {
2646 *TransferResult
= EFI_USB_ERR_SYSTEM
;
2647 Status
= EFI_DEVICE_ERROR
;
2652 // Create and init Interrupt Qh
2654 Status
= CreateInterruptQh (
2660 MaximumPacketLength
,
2665 if (EFI_ERROR (Status
)) {
2666 Status
= EFI_OUT_OF_RESOURCES
;
2671 // Create and init Interrupt Qtds
2673 Status
= CreateBulkOrInterruptQtds (
2681 if (EFI_ERROR (Status
)) {
2682 *TransferResult
= EFI_USB_ERR_SYSTEM
;
2683 Status
= EFI_OUT_OF_RESOURCES
;
2690 LinkQtdToQh (QhPtr
, InterruptQtdsPtr
);
2692 ClearEhcAllStatus (HcDev
);
2694 Status
= DisablePeriodicSchedule (HcDev
);
2695 if (EFI_ERROR (Status
)) {
2696 Status
= EFI_DEVICE_ERROR
;
2700 Status
= WaitForPeriodicScheduleDisable (HcDev
, EHCI_GENERIC_TIMEOUT
);
2701 if (EFI_ERROR (Status
)) {
2702 Status
= EFI_TIMEOUT
;
2707 // Link Qh and Qtds to Periodic Schedule List
2709 LinkQhToPeriodicList (HcDev
, QhPtr
);
2711 Status
= EnablePeriodicSchedule (HcDev
);
2712 if (EFI_ERROR (Status
)) {
2713 Status
= EFI_DEVICE_ERROR
;
2717 Status
= WaitForPeriodicScheduleEnable (HcDev
, EHCI_GENERIC_TIMEOUT
);
2718 if (EFI_ERROR (Status
)) {
2719 Status
= EFI_TIMEOUT
;
2723 if (IsEhcHalted (HcDev
)) {
2724 Status
= StartScheduleExecution (HcDev
);
2725 if (EFI_ERROR (Status
)) {
2726 Status
= EFI_DEVICE_ERROR
;
2732 // Poll QH-TDs execution and get result.
2733 // detail status is returned
2735 Status
= ExecuteTransfer (
2744 if (EFI_ERROR (Status
)) {
2749 // if has errors that cause host controller halt,
2750 // then return EFI_DEVICE_ERROR directly.
2752 if (IsEhcHalted (HcDev
) || IsEhcSysError (HcDev
)) {
2753 *TransferResult
|= EFI_USB_ERR_SYSTEM
;
2756 ClearEhcAllStatus (HcDev
);
2759 UnlinkQhFromPeriodicList (HcDev
, QhPtr
, 0);
2760 DestoryQtds (HcDev
, InterruptQtdsPtr
);
2762 DestoryQh (HcDev
, QhPtr
);
2764 HcDev
->PciIo
->Unmap (HcDev
->PciIo
, DataMap
);
2766 HcDev
->PciIo
->Flush (HcDev
->PciIo
);
2772 EhciIsochronousTransfer (
2773 IN EFI_USB2_HC_PROTOCOL
*This
,
2774 IN UINT8 DeviceAddress
,
2775 IN UINT8 EndPointAddress
,
2776 IN UINT8 DeviceSpeed
,
2777 IN UINTN MaximumPacketLength
,
2778 IN UINT8 DataBuffersNumber
,
2779 IN OUT VOID
*Data
[EFI_USB_MAX_ISO_BUFFER_NUM
],
2780 IN UINTN DataLength
,
2781 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
2782 OUT UINT32
*TransferResult
2786 Routine Description:
2788 Submits isochronous transfer to a target USB device.
2792 This - A pointer to the EFI_USB2_HC_PROTOCOL instance.
2793 DeviceAddress - Represents the address of the target device on the USB,
2794 which is assigned during USB enumeration.
2795 EndPointAddress - End point address
2796 DeviceSpeed - Indicates device speed.
2797 MaximumPacketLength - Indicates the maximum packet size that the
2798 default control transfer endpoint is capable of
2799 sending or receiving.
2800 DataBuffersNumber - Number of data buffers prepared for the transfer.
2801 Data - Array of pointers to the buffers of data that will be
2802 transmitted to USB device or received from USB device.
2803 DataLength - Indicates the size, in bytes, of the data buffer
2805 Translator - A pointr to the transaction translator data.
2806 TransferResult - A pointer to the detailed result information generated
2807 by this control transfer.
2815 return EFI_UNSUPPORTED
;
2820 EhciAsyncIsochronousTransfer (
2821 IN EFI_USB2_HC_PROTOCOL
*This
,
2822 IN UINT8 DeviceAddress
,
2823 IN UINT8 EndPointAddress
,
2824 IN UINT8 DeviceSpeed
,
2825 IN UINTN MaximumPacketLength
,
2826 IN UINT8 DataBuffersNumber
,
2827 IN OUT VOID
*Data
[EFI_USB_MAX_ISO_BUFFER_NUM
],
2828 IN UINTN DataLength
,
2829 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
2830 IN EFI_ASYNC_USB_TRANSFER_CALLBACK IsochronousCallBack
,
2835 Routine Description:
2837 Submits Async isochronous transfer to a target USB device.
2841 This - A pointer to the EFI_USB2_HC_PROTOCOL instance.
2842 DeviceAddress - Represents the address of the target device on the USB,
2843 which is assigned during USB enumeration.
2844 EndPointAddress - End point address
2845 DeviceSpeed - Indicates device speed.
2846 MaximumPacketLength - Indicates the maximum packet size that the
2847 default control transfer endpoint is capable of
2848 sending or receiving.
2849 DataBuffersNumber - Number of data buffers prepared for the transfer.
2850 Data - Array of pointers to the buffers of data that will be transmitted
2851 to USB device or received from USB device.
2852 Translator - A pointr to the transaction translator data.
2853 IsochronousCallBack - When the transfer complete, the call back function will be called
2854 Context - Pass to the call back function as parameter
2862 return EFI_UNSUPPORTED
;