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
,
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
;
358 // Open the PciIo Protocol
360 Status
= gBS
->OpenProtocol (
362 &gEfiPciIoProtocolGuid
,
364 This
->DriverBindingHandle
,
366 EFI_OPEN_PROTOCOL_BY_DRIVER
368 if (EFI_ERROR (Status
)) {
369 Status
= EFI_OUT_OF_RESOURCES
;
374 // Enable the USB Host Controller
376 Status
= PciIo
->Attributes (
378 EfiPciIoAttributeOperationEnable
,
379 EFI_PCI_DEVICE_ENABLE
,
382 if (EFI_ERROR (Status
)) {
383 Status
= EFI_OUT_OF_RESOURCES
;
384 goto close_pciio_protocol
;
388 // Allocate memory for EHC private data structure
390 HcDev
= AllocateZeroPool (sizeof (USB2_HC_DEV
));
392 Status
= EFI_OUT_OF_RESOURCES
;
393 goto close_pciio_protocol
;
397 // Init EFI_USB2_HC_PROTOCOL interface and private data structure
399 HcDev
->Usb2Hc
.GetCapability
= EhciGetCapability
;
400 HcDev
->Usb2Hc
.Reset
= EhciReset
;
401 HcDev
->Usb2Hc
.GetState
= EhciGetState
;
402 HcDev
->Usb2Hc
.SetState
= EhciSetState
;
403 HcDev
->Usb2Hc
.ControlTransfer
= EhciControlTransfer
;
404 HcDev
->Usb2Hc
.BulkTransfer
= EhciBulkTransfer
;
405 HcDev
->Usb2Hc
.AsyncInterruptTransfer
= EhciAsyncInterruptTransfer
;
406 HcDev
->Usb2Hc
.SyncInterruptTransfer
= EhciSyncInterruptTransfer
;
407 HcDev
->Usb2Hc
.IsochronousTransfer
= EhciIsochronousTransfer
;
408 HcDev
->Usb2Hc
.AsyncIsochronousTransfer
= EhciAsyncIsochronousTransfer
;
409 HcDev
->Usb2Hc
.GetRootHubPortStatus
= EhciGetRootHubPortStatus
;
410 HcDev
->Usb2Hc
.SetRootHubPortFeature
= EhciSetRootHubPortFeature
;
411 HcDev
->Usb2Hc
.ClearRootHubPortFeature
= EhciClearRootHubPortFeature
;
412 HcDev
->Usb2Hc
.MajorRevision
= 0x1;
413 HcDev
->Usb2Hc
.MinorRevision
= 0x1;
415 HcDev
->AsyncRequestList
= NULL
;
416 HcDev
->ControllerNameTable
= NULL
;
417 HcDev
->Signature
= USB2_HC_DEV_SIGNATURE
;
418 HcDev
->PciIo
= PciIo
;
421 // Install USB2_HC_PROTOCOL
423 Status
= gBS
->InstallProtocolInterface (
425 &gEfiUsb2HcProtocolGuid
,
426 EFI_NATIVE_INTERFACE
,
429 if (EFI_ERROR (Status
)) {
430 Status
= EFI_OUT_OF_RESOURCES
;
435 // Get Capability Register Length
437 Status
= GetCapabilityLen (HcDev
);
438 if (EFI_ERROR (Status
)) {
439 Status
= EFI_DEVICE_ERROR
;
440 goto uninstall_usb2hc_protocol
;
443 ClearLegacySupport (HcDev
);
447 DumpEHCIPortsStatus (HcDev
);
451 // Create and Init Perodic Frame List
453 Status
= EhciGetCapability (
459 if (EFI_ERROR (Status
)) {
460 Status
= EFI_OUT_OF_RESOURCES
;
461 goto uninstall_usb2hc_protocol
;
463 HcDev
->Is64BitCapable
= Is64BitCapable
;
466 // Create and Init Perodic Frame List
468 Status
= InitialPeriodicFrameList (
470 EHCI_MAX_FRAME_LIST_LENGTH
472 if (EFI_ERROR (Status
)) {
473 Status
= EFI_OUT_OF_RESOURCES
;
474 goto uninstall_usb2hc_protocol
;
478 // Init memory pool management
480 Status
= InitialMemoryManagement (HcDev
);
481 if (EFI_ERROR (Status
)) {
482 Status
= EFI_OUT_OF_RESOURCES
;
483 goto deinit_perodic_frame_list
;
487 // Create AsyncRequest Polling Timer
489 Status
= CreatePollingTimer (HcDev
, (EFI_EVENT_NOTIFY
) AsyncRequestMoniter
);
490 if (EFI_ERROR (Status
)) {
491 Status
= EFI_OUT_OF_RESOURCES
;
492 goto deinit_memory_management
;
496 // Default Maxximum Interrupt Interval is 8,
497 // it means that 8 micro frame = 1ms
501 // Start the Host Controller
503 if (IsEhcHalted (HcDev
)) {
504 Status
= StartScheduleExecution (HcDev
);
505 if (EFI_ERROR (Status
)) {
506 Status
= EFI_DEVICE_ERROR
;
512 // Set all ports routing to EHC
514 Status
= SetPortRoutingEhc (HcDev
);
515 if (EFI_ERROR (Status
)) {
516 Status
= EFI_DEVICE_ERROR
;
521 // Component name protocol
523 Status
= AddUnicodeString (
525 gEhciComponentName
.SupportedLanguages
,
526 &HcDev
->ControllerNameTable
,
527 L
"Usb Enhanced Host Controller"
529 if (EFI_ERROR (Status
)) {
530 Status
= EFI_OUT_OF_RESOURCES
;
537 // Error handle process
540 DestoryPollingTimer (HcDev
);
541 deinit_memory_management
:
542 DeinitialMemoryManagement (HcDev
);
543 deinit_perodic_frame_list
:
544 DeinitialPeriodicFrameList (HcDev
);
545 uninstall_usb2hc_protocol
:
546 gBS
->UninstallProtocolInterface (
548 &gEfiUsb2HcProtocolGuid
,
552 gBS
->FreePool (HcDev
);
553 close_pciio_protocol
:
556 &gEfiPciIoProtocolGuid
,
557 This
->DriverBindingHandle
,
567 EhciDriverBindingStop (
568 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
569 IN EFI_HANDLE Controller
,
570 IN UINTN NumberOfChildren
,
571 IN EFI_HANDLE
*ChildHandleBuffer
577 Stop this driver on ControllerHandle. Support stoping any child handles
578 created by this driver.
582 This - Protocol instance pointer.
583 Controller - Handle of device to stop driver on
584 NumberOfChildren - Number of Children in the ChildHandleBuffer
585 ChildHandleBuffer - List of handles for the children we need to stop.
590 EFI_DEVICE_ERROR Fail
594 EFI_USB2_HC_PROTOCOL
*Usb2Hc
;
598 // Test whether the Controller handler passed in is a valid
599 // Usb controller handle that should be supported, if not,
600 // return the error status directly
602 Status
= gBS
->OpenProtocol (
604 &gEfiUsb2HcProtocolGuid
,
606 This
->DriverBindingHandle
,
608 EFI_OPEN_PROTOCOL_GET_PROTOCOL
610 if (EFI_ERROR (Status
)) {
611 Status
= EFI_DEVICE_ERROR
;
615 HcDev
= USB2_HC_DEV_FROM_THIS (Usb2Hc
);
618 // free all the controller related memory and uninstall UHCI Protocol.
620 Status
= gBS
->UninstallProtocolInterface (
622 &gEfiUsb2HcProtocolGuid
,
625 if (EFI_ERROR (Status
)) {
626 Status
= EFI_DEVICE_ERROR
;
631 // Set Host Controller state as halt
633 Status
= Usb2Hc
->SetState (
637 if (EFI_ERROR (Status
)) {
638 Status
= EFI_DEVICE_ERROR
;
643 // Stop AsyncRequest Polling Timer
645 Status
= StopPollingTimer (HcDev
);
646 if (EFI_ERROR (Status
)) {
647 Status
= EFI_DEVICE_ERROR
;
652 // Destroy Asynchronous Request Event
654 DestoryPollingTimer (HcDev
);
657 // Destroy Perodic Frame List
659 DeinitialPeriodicFrameList (HcDev
);
662 // Deinit Ehci pool memory management
664 DeinitialMemoryManagement (HcDev
);
667 // Denint Unicode String Table
669 FreeUnicodeStringTable (HcDev
->ControllerNameTable
);
672 // Disable the USB Host Controller
674 Status
= HcDev
->PciIo
->Attributes (
676 EfiPciIoAttributeOperationDisable
,
677 EFI_PCI_DEVICE_ENABLE
,
680 if (EFI_ERROR (Status
)) {
681 Status
= EFI_DEVICE_ERROR
;
685 gBS
->FreePool (HcDev
);
689 &gEfiPciIoProtocolGuid
,
690 This
->DriverBindingHandle
,
701 IN EFI_USB2_HC_PROTOCOL
*This
,
703 OUT UINT8
*PortNumber
,
704 OUT UINT8
*Is64BitCapable
710 Retrieves the capablility of root hub ports.
714 This - A pointer to the EFI_USB_HC_PROTOCOL instance.
715 MaxSpeed - A pointer to the number of the host controller.
716 PortNumber - A pointer to the number of the root hub ports.
717 Is64BitCapable - A pointer to the flag for whether controller supports
718 64-bit memory addressing.
722 EFI_SUCCESS host controller capability were retrieved successfully.
723 EFI_INVALID_PARAMETER MaxSpeed or PortNumber or Is64BitCapable is NULL.
724 EFI_DEVICE_ERROR An error was encountered while attempting to retrieve the capabilities.
730 UINT32 HcStructParamsAddr
;
731 UINT32 HcStructParamsReg
;
732 UINT32 HcCapParamsAddr
;
733 UINT32 HcCapParamsReg
;
735 if (MaxSpeed
== NULL
|| PortNumber
== NULL
|| Is64BitCapable
== NULL
) {
736 Status
= EFI_INVALID_PARAMETER
;
740 HcStructParamsAddr
= HCSPARAMS
;
741 HcCapParamsAddr
= HCCPARAMS
;
742 HcDev
= USB2_HC_DEV_FROM_THIS (This
);
744 Status
= ReadEhcCapabiltiyReg (
749 if (EFI_ERROR (Status
)) {
750 Status
= EFI_DEVICE_ERROR
;
754 Status
= ReadEhcCapabiltiyReg (
759 if (EFI_ERROR (Status
)) {
760 Status
= EFI_DEVICE_ERROR
;
764 *MaxSpeed
= EFI_USB_SPEED_HIGH
;
765 *PortNumber
= (UINT8
) (HcStructParamsReg
& HCSP_NPORTS
);
766 *Is64BitCapable
= (UINT8
) (HcCapParamsReg
& HCCP_64BIT
);
775 IN EFI_USB2_HC_PROTOCOL
*This
,
782 Provides software reset for the USB host controller.
786 This - A pointer to the EFI_USB2_HC_PROTOCOL instance.
787 Attributes - A bit mask of the reset operation to perform.
788 See below for a list of the supported bit mask values.
790 #define EFI_USB_HC_RESET_GLOBAL 0x0001
791 #define EFI_USB_HC_RESET_HOST_CONTROLLER 0x0002
792 #define EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG 0x0004
793 #define EFI_USB_HC_RESET_HOST_WITH_DEBUG 0x0008
795 EFI_USB_HC_RESET_GLOBAL
796 If this bit is set, a global reset signal will be sent to the USB bus.
797 This resets all of the USB bus logic, including the USB host
798 controller hardware and all the devices attached on the USB bus.
799 EFI_USB_HC_RESET_HOST_CONTROLLER
800 If this bit is set, the USB host controller hardware will be reset.
801 No reset signal will be sent to the USB bus.
802 EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG
803 If this bit is set, a global reset signal will be sent to the USB bus.
804 This resets all of the USB bus logic, including the USB host
805 controller hardware and all the devices attached on the USB bus.
806 If this is an EHCI controller and the debug port has configured, then
807 this is will still reset the host controller.
808 EFI_USB_HC_RESET_HOST_WITH_DEBUG
809 If this bit is set, the USB host controller hardware will be reset.
810 If this is an EHCI controller and the debug port has been configured,
811 then this will still reset the host controller.
816 The reset operation succeeded.
817 EFI_INVALID_PARAMETER
818 Attributes is not valid.
820 The type of reset specified by Attributes is not currently supported by
821 the host controller hardware.
823 Reset operation is rejected due to the debug port being configured and
824 active; only EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG or
825 EFI_USB_HC_RESET_HOST_WITH_DEBUG reset Atrributes can be used to
826 perform reset operation for this host controller.
828 An error was encountered while attempting to perform
836 FRAME_LIST_ENTRY
*FrameEntryPtr
;
838 HcDev
= USB2_HC_DEV_FROM_THIS (This
);
840 switch (Attributes
) {
842 case EFI_USB_HC_RESET_GLOBAL
:
845 // Same behavior as Host Controller Reset
848 case EFI_USB_HC_RESET_HOST_CONTROLLER
:
851 // Host Controller must be Halt when Reset it
853 if (IsEhcHalted (HcDev
)) {
854 Status
= ResetEhc (HcDev
);
855 if (EFI_ERROR (Status
)) {
856 Status
= EFI_DEVICE_ERROR
;
860 // Set to zero by Host Controller when reset process completes
862 Status
= WaitForEhcReset (HcDev
, EHCI_GENERIC_TIMEOUT
);
863 if (EFI_ERROR (Status
)) {
864 Status
= EFI_TIMEOUT
;
868 Status
= EFI_DEVICE_ERROR
;
873 // only asynchronous interrupt transfers are always alive on the bus, need to cleanup
875 CleanUpAllAsyncRequestTransfer (HcDev
);
876 Status
= ClearEhcAllStatus (HcDev
);
877 if (EFI_ERROR (Status
)) {
878 Status
= EFI_DEVICE_ERROR
;
883 // Set appropriate 4G Segment Selector
885 Status
= SetCtrlDataStructSeg (HcDev
);
886 if (EFI_ERROR (Status
)) {
887 Status
= EFI_DEVICE_ERROR
;
892 // Init Perodic List Base Addr and Frame List
894 Status
= SetFrameListBaseAddr (
896 (UINT32
)GET_0B_TO_31B (HcDev
->PeriodicFrameListBuffer
)
898 if (EFI_ERROR (Status
)) {
899 Status
= EFI_DEVICE_ERROR
;
902 FrameEntryPtr
= (FRAME_LIST_ENTRY
*) HcDev
->PeriodicFrameListBuffer
;
903 for (FrameIndex
= 0; FrameIndex
< HcDev
->PeriodicFrameListLength
; FrameIndex
++) {
904 FrameEntryPtr
->LinkTerminate
= TRUE
;
909 // Start the Host Controller
911 if (IsEhcHalted (HcDev
)) {
912 Status
= StartScheduleExecution (HcDev
);
913 if (EFI_ERROR (Status
)) {
914 Status
= EFI_DEVICE_ERROR
;
920 // Set all ports routing to EHC
922 Status
= SetPortRoutingEhc (HcDev
);
923 if (EFI_ERROR (Status
)) {
924 Status
= EFI_DEVICE_ERROR
;
929 case EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG
:
931 Status
= EFI_UNSUPPORTED
;
934 case EFI_USB_HC_RESET_HOST_WITH_DEBUG
:
936 Status
= EFI_UNSUPPORTED
;
940 Status
= EFI_INVALID_PARAMETER
;
950 IN EFI_USB2_HC_PROTOCOL
*This
,
951 OUT EFI_USB_HC_STATE
*State
957 Retrieves current state of the USB host controller.
961 This A pointer to the EFI_USB2_HC_PROTOCOL instance.
962 State A pointer to the EFI_USB_HC_STATE data structure that
963 indicates current state of the USB host controller.
964 Type EFI_USB_HC_STATE is defined below.
968 EfiUsbHcStateOperational,
969 EfiUsbHcStateSuspend,
976 The state information of the host controller was returned in State.
977 EFI_INVALID_PARAMETER
980 An error was encountered while attempting to retrieve the
981 host controller's current state.
986 UINT32 UsbStatusAddr
;
990 Status
= EFI_INVALID_PARAMETER
;
994 UsbStatusAddr
= USBSTS
;
995 HcDev
= USB2_HC_DEV_FROM_THIS (This
);
997 Status
= ReadEhcOperationalReg (
1002 if (EFI_ERROR (Status
)) {
1003 Status
= EFI_DEVICE_ERROR
;
1007 if (UsbStatusReg
& USBSTS_HCH
) {
1008 *State
= EfiUsbHcStateHalt
;
1010 *State
= EfiUsbHcStateOperational
;
1020 IN EFI_USB2_HC_PROTOCOL
*This
,
1021 IN EFI_USB_HC_STATE State
1025 Routine Description:
1027 Sets the USB host controller to a specific state.
1031 This - A pointer to the EFI_USB2_HC_PROTOCOL instance.
1032 State - Indicates the state of the host controller that will be set.
1037 The USB host controller was successfully placed in the state
1039 EFI_INVALID_PARAMETER
1042 Failed to set the state specified by State due to device error.
1048 UINT32 UsbCommandAddr
;
1049 UINT32 UsbCommandReg
;
1050 EFI_USB_HC_STATE CurrentState
;
1052 UsbCommandAddr
= USBCMD
;
1053 HcDev
= USB2_HC_DEV_FROM_THIS (This
);
1055 Status
= EhciGetState (This
, &CurrentState
);
1056 if (EFI_ERROR (Status
)) {
1057 Status
= EFI_DEVICE_ERROR
;
1063 case EfiUsbHcStateHalt
:
1065 if (EfiUsbHcStateHalt
== CurrentState
) {
1066 Status
= EFI_SUCCESS
;
1068 } else if (EfiUsbHcStateOperational
== CurrentState
) {
1069 Status
= ReadEhcOperationalReg (
1074 if (EFI_ERROR (Status
)) {
1075 Status
= EFI_DEVICE_ERROR
;
1079 UsbCommandReg
&= ~USBCMD_RS
;
1080 Status
= WriteEhcOperationalReg (
1085 if (EFI_ERROR (Status
)) {
1086 Status
= EFI_DEVICE_ERROR
;
1090 // Ensure the HC is in halt status after send the stop command
1092 Status
= WaitForEhcHalt (HcDev
, EHCI_GENERIC_TIMEOUT
);
1093 if (EFI_ERROR (Status
)) {
1094 Status
= EFI_TIMEOUT
;
1100 case EfiUsbHcStateOperational
:
1102 if (IsEhcSysError (HcDev
)) {
1103 Status
= EFI_DEVICE_ERROR
;
1106 if (EfiUsbHcStateOperational
== CurrentState
) {
1107 Status
= EFI_SUCCESS
;
1109 } else if (EfiUsbHcStateHalt
== CurrentState
) {
1111 // Set Host Controller Run
1113 Status
= ReadEhcOperationalReg (
1118 if (EFI_ERROR (Status
)) {
1119 return EFI_DEVICE_ERROR
;
1122 UsbCommandReg
|= USBCMD_RS
;
1123 Status
= WriteEhcOperationalReg (
1128 if (EFI_ERROR (Status
)) {
1129 Status
= EFI_DEVICE_ERROR
;
1135 case EfiUsbHcStateSuspend
:
1137 Status
= EFI_UNSUPPORTED
;
1142 Status
= EFI_INVALID_PARAMETER
;
1151 EhciGetRootHubPortStatus (
1152 IN EFI_USB2_HC_PROTOCOL
*This
,
1153 IN UINT8 PortNumber
,
1154 OUT EFI_USB_PORT_STATUS
*PortStatus
1158 Routine Description:
1160 Retrieves the current status of a USB root hub port.
1164 This - A pointer to the EFI_USB2_HC_PROTOCOL.
1165 PortNumber - Specifies the root hub port from which the status
1166 is to be retrieved. This value is zero-based. For example,
1167 if a root hub has two ports, then the first port is numbered 0,
1168 and the second port is numbered 1.
1169 PortStatus - A pointer to the current port status bits and
1170 port status change bits.
1174 EFI_SUCCESS The status of the USB root hub port specified
1175 by PortNumber was returned in PortStatus.
1176 EFI_INVALID_PARAMETER PortNumber is invalid.
1177 EFI_DEVICE_ERROR Can't read register
1183 UINT32 PortStatusControlAddr
;
1184 UINT32 PortStatusControlReg
;
1186 UINT8 TotalPortNumber
;
1187 UINT8 Is64BitCapable
;
1189 if (PortStatus
== NULL
) {
1190 Status
= EFI_INVALID_PARAMETER
;
1201 if (PortNumber
>= TotalPortNumber
) {
1202 Status
= EFI_INVALID_PARAMETER
;
1206 HcDev
= USB2_HC_DEV_FROM_THIS (This
);
1207 PortStatusControlAddr
= (UINT32
) (PORTSC
+ (4 * PortNumber
));
1210 // Clear port status
1212 PortStatus
->PortStatus
= 0;
1213 PortStatus
->PortChangeStatus
= 0;
1215 Status
= ReadEhcOperationalReg (
1217 PortStatusControlAddr
,
1218 &PortStatusControlReg
1220 if (EFI_ERROR (Status
)) {
1221 Status
= EFI_DEVICE_ERROR
;
1226 // Fill Port Status bits
1230 // Current Connect Status
1232 if (PORTSC_CCS
& PortStatusControlReg
) {
1233 PortStatus
->PortStatus
|= USB_PORT_STAT_CONNECTION
;
1236 // Port Enabled/Disabled
1238 if (PORTSC_PED
& PortStatusControlReg
) {
1239 PortStatus
->PortStatus
|= USB_PORT_STAT_ENABLE
;
1244 if (PORTSC_SUSP
& PortStatusControlReg
) {
1245 PortStatus
->PortStatus
|= USB_PORT_STAT_SUSPEND
;
1248 // Over-current Active
1250 if (PORTSC_OCA
& PortStatusControlReg
) {
1251 PortStatus
->PortStatus
|= USB_PORT_STAT_OVERCURRENT
;
1256 if (PORTSC_PR
& PortStatusControlReg
) {
1257 PortStatus
->PortStatus
|= USB_PORT_STAT_RESET
;
1262 if (PORTSC_PP
& PortStatusControlReg
) {
1263 PortStatus
->PortStatus
|= USB_PORT_STAT_POWER
;
1268 if (PORTSC_PO
& PortStatusControlReg
) {
1269 PortStatus
->PortStatus
|= USB_PORT_STAT_OWNER
;
1272 // Identify device speed
1274 if (PORTSC_LS_KSTATE
& PortStatusControlReg
) {
1276 // Low Speed Device Attached
1278 PortStatus
->PortStatus
|= USB_PORT_STAT_LOW_SPEED
;
1281 // Not Low Speed Device Attached
1283 if ((PORTSC_CCS
& PortStatusControlReg
) && (PORTSC_CSC
& PortStatusControlReg
)) {
1284 HcDev
->DeviceSpeed
[PortNumber
] = IsHighSpeedDevice (This
, PortNumber
) ? USB_PORT_STAT_HIGH_SPEED
: 0;
1286 PortStatus
->PortStatus
|= HcDev
->DeviceSpeed
[PortNumber
];
1289 // Fill Port Status Change bits
1292 // Connect Status Change
1294 if (PORTSC_CSC
& PortStatusControlReg
) {
1295 PortStatus
->PortChangeStatus
|= USB_PORT_STAT_C_CONNECTION
;
1298 // Port Enabled/Disabled Change
1300 if (PORTSC_PEDC
& PortStatusControlReg
) {
1301 PortStatus
->PortChangeStatus
|= USB_PORT_STAT_C_ENABLE
;
1304 // Port Over Current Change
1306 if (PORTSC_OCC
& PortStatusControlReg
) {
1307 PortStatus
->PortChangeStatus
|= USB_PORT_STAT_C_OVERCURRENT
;
1316 EhciSetRootHubPortFeature (
1317 IN EFI_USB2_HC_PROTOCOL
*This
,
1318 IN UINT8 PortNumber
,
1319 IN EFI_USB_PORT_FEATURE PortFeature
1323 Routine Description:
1325 Sets a feature for the specified root hub port.
1329 This - A pointer to the EFI_USB2_HC_PROTOCOL.
1330 PortNumber - Specifies the root hub port whose feature
1331 is requested to be set.
1332 PortFeature - Indicates the feature selector associated
1333 with the feature set request.
1338 The feature specified by PortFeature was set for the
1339 USB root hub port specified by PortNumber.
1340 EFI_INVALID_PARAMETER
1341 PortNumber is invalid or PortFeature is invalid.
1349 UINT32 PortStatusControlAddr
;
1350 UINT32 PortStatusControlReg
;
1352 UINT8 TotalPortNumber
;
1353 UINT8 Is64BitCapable
;
1362 if (PortNumber
>= TotalPortNumber
) {
1363 Status
= EFI_INVALID_PARAMETER
;
1367 HcDev
= USB2_HC_DEV_FROM_THIS (This
);
1368 PortStatusControlAddr
= (UINT32
) (PORTSC
+ (4 * PortNumber
));
1370 Status
= ReadEhcOperationalReg (
1372 PortStatusControlAddr
,
1373 &PortStatusControlReg
1375 if (EFI_ERROR (Status
)) {
1376 Status
= EFI_DEVICE_ERROR
;
1380 switch (PortFeature
) {
1382 case EfiUsbPortEnable
:
1385 // Sofeware can't set this bit, Port can only be enable by the Host Controller
1386 // as a part of the reset and enable
1388 PortStatusControlReg
&= 0xffffffd5;
1389 PortStatusControlReg
|= PORTSC_PED
;
1392 case EfiUsbPortSuspend
:
1394 PortStatusControlReg
&= 0xffffffd5;
1395 PortStatusControlReg
|= PORTSC_SUSP
;
1398 case EfiUsbPortReset
:
1401 // Make sure Host Controller not halt before reset it
1403 if (IsEhcHalted (HcDev
)) {
1404 Status
= StartScheduleExecution (HcDev
);
1405 if (EFI_ERROR (Status
)) {
1406 Status
= EFI_DEVICE_ERROR
;
1409 Status
= WaitForEhcNotHalt (HcDev
, EHCI_GENERIC_TIMEOUT
);
1410 if (EFI_ERROR (Status
)) {
1411 DEBUG ((gEHCDebugLevel
, "EHCI: WaitForEhcNotHalt TimeOut\n"));
1412 Status
= EFI_DEVICE_ERROR
;
1416 PortStatusControlReg
&= 0xffffffd5;
1417 PortStatusControlReg
|= PORTSC_PR
;
1419 // Set one to PortReset bit must also set zero to PortEnable bit
1421 PortStatusControlReg
&= ~PORTSC_PED
;
1424 case EfiUsbPortPower
:
1427 // No support, no operation
1431 case EfiUsbPortOwner
:
1433 PortStatusControlReg
&= 0xffffffd5;
1434 PortStatusControlReg
|= PORTSC_PO
;
1439 Status
= EFI_INVALID_PARAMETER
;
1443 Status
= WriteEhcOperationalReg (
1445 PortStatusControlAddr
,
1446 PortStatusControlReg
1448 if (EFI_ERROR (Status
)) {
1449 Status
= EFI_DEVICE_ERROR
;
1458 EhciClearRootHubPortFeature (
1459 IN EFI_USB2_HC_PROTOCOL
*This
,
1460 IN UINT8 PortNumber
,
1461 IN EFI_USB_PORT_FEATURE PortFeature
1465 Routine Description:
1467 Clears a feature for the specified root hub port.
1471 This - A pointer to the EFI_USB2_HC_PROTOCOL instance.
1472 PortNumber - Specifies the root hub port whose feature
1473 is requested to be cleared.
1474 PortFeature - Indicates the feature selector associated with the
1475 feature clear request.
1480 The feature specified by PortFeature was cleared for the
1481 USB root hub port specified by PortNumber.
1482 EFI_INVALID_PARAMETER
1483 PortNumber is invalid or PortFeature is invalid.
1491 UINT32 PortStatusControlAddr
;
1492 UINT32 PortStatusControlReg
;
1494 UINT8 TotalPortNumber
;
1495 UINT8 Is64BitCapable
;
1504 if (PortNumber
>= TotalPortNumber
) {
1505 Status
= EFI_INVALID_PARAMETER
;
1509 HcDev
= USB2_HC_DEV_FROM_THIS (This
);
1510 PortStatusControlAddr
= (UINT32
) (PORTSC
+ (4 * PortNumber
));
1512 Status
= ReadEhcOperationalReg (
1514 PortStatusControlAddr
,
1515 &PortStatusControlReg
1517 if (EFI_ERROR (Status
)) {
1518 Status
= EFI_DEVICE_ERROR
;
1522 switch (PortFeature
) {
1524 case EfiUsbPortEnable
:
1527 // Clear PORT_ENABLE feature means disable port.
1529 PortStatusControlReg
&= 0xffffffd5;
1530 PortStatusControlReg
&= ~PORTSC_PED
;
1533 case EfiUsbPortSuspend
:
1536 // A write of zero to this bit is ignored by the host controller.
1537 // The host controller will unconditionally set this bit to a zero when:
1538 // 1. software sets the Forct Port Resume bit to a zero from a one.
1539 // 2. software sets the Port Reset bit to a one frome a zero.
1541 PortStatusControlReg
&= 0xffffffd5;
1542 PortStatusControlReg
&= ~PORTSC_FPR
;
1545 case EfiUsbPortReset
:
1548 // Clear PORT_RESET means clear the reset signal.
1550 PortStatusControlReg
&= 0xffffffd5;
1551 PortStatusControlReg
&= ~PORTSC_PR
;
1554 case EfiUsbPortPower
:
1557 // No support, no operation
1561 case EfiUsbPortOwner
:
1564 // Clear port owner means this port owned by EHC
1566 PortStatusControlReg
&= 0xffffffd5;
1567 PortStatusControlReg
&= ~PORTSC_PO
;
1570 case EfiUsbPortConnectChange
:
1573 // Clear connect status change
1575 PortStatusControlReg
&= 0xffffffd5;
1576 PortStatusControlReg
|= PORTSC_CSC
;
1579 case EfiUsbPortEnableChange
:
1582 // Clear enable status change
1584 PortStatusControlReg
&= 0xffffffd5;
1585 PortStatusControlReg
|= PORTSC_PEDC
;
1588 case EfiUsbPortSuspendChange
:
1591 // No related bit, no operation
1595 case EfiUsbPortOverCurrentChange
:
1598 // Clear PortOverCurrent change
1600 PortStatusControlReg
&= 0xffffffd5;
1601 PortStatusControlReg
|= PORTSC_OCC
;
1604 case EfiUsbPortResetChange
:
1607 // No related bit, no operation
1613 Status
= EFI_INVALID_PARAMETER
;
1617 Status
= WriteEhcOperationalReg (
1619 PortStatusControlAddr
,
1620 PortStatusControlReg
1622 if (EFI_ERROR (Status
)) {
1623 Status
= EFI_DEVICE_ERROR
;
1633 EhciControlTransfer (
1634 IN EFI_USB2_HC_PROTOCOL
*This
,
1635 IN UINT8 DeviceAddress
,
1636 IN UINT8 DeviceSpeed
,
1637 IN UINTN MaximumPacketLength
,
1638 IN EFI_USB_DEVICE_REQUEST
*Request
,
1639 IN EFI_USB_DATA_DIRECTION TransferDirection
,
1641 IN OUT UINTN
*DataLength
,
1643 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
1644 OUT UINT32
*TransferResult
1648 Routine Description:
1650 Submits control transfer to a target USB device.
1654 This - A pointer to the EFI_USB2_HC_PROTOCOL instance.
1655 DeviceAddress - Represents the address of the target device on the USB,
1656 which is assigned during USB enumeration.
1657 DeviceSpeed - Indicates target device speed.
1658 MaximumPacketLength - Indicates the maximum packet size that the
1659 default control transfer endpoint is capable of
1660 sending or receiving.
1661 Request - A pointer to the USB device request that will be sent
1663 TransferDirection - Specifies the data direction for the transfer.
1664 There are three values available, DataIn, DataOut
1666 Data - A pointer to the buffer of data that will be transmitted
1667 to USB device or received from USB device.
1668 DataLength - Indicates the size, in bytes, of the data buffer
1670 TimeOut - Indicates the maximum time, in microseconds,
1671 which the transfer is allowed to complete.
1672 Translator - A pointr to the transaction translator data.
1673 TransferResult - A pointer to the detailed result information generated
1674 by this control transfer.
1679 The control transfer was completed successfully.
1680 EFI_OUT_OF_RESOURCES
1681 The control transfer could not be completed due to a lack of resources.
1682 EFI_INVALID_PARAMETER
1683 Some parameters are invalid.
1685 The control transfer failed due to timeout.
1687 The control transfer failed due to host controller or device error.
1688 Caller should check TranferResult for detailed error information.
1695 EHCI_QH_ENTITY
*QhPtr
;
1696 EHCI_QTD_ENTITY
*ControlQtdsPtr
;
1699 UINT8
*RequestCursor
;
1703 ControlQtdsPtr
= NULL
;
1706 RequestCursor
= NULL
;
1708 HcDev
= USB2_HC_DEV_FROM_THIS (This
);
1711 // Parameters Checking
1713 if (TransferDirection
!= EfiUsbDataIn
&&
1714 TransferDirection
!= EfiUsbDataOut
&&
1715 TransferDirection
!= EfiUsbNoData
1717 Status
= EFI_INVALID_PARAMETER
;
1721 if (EfiUsbNoData
== TransferDirection
) {
1722 if (NULL
!= Data
|| 0 != *DataLength
) {
1723 Status
= EFI_INVALID_PARAMETER
;
1727 if (NULL
== Data
|| 0 == *DataLength
) {
1728 Status
= EFI_INVALID_PARAMETER
;
1733 if (Request
== NULL
|| TransferResult
== NULL
) {
1734 Status
= EFI_INVALID_PARAMETER
;
1738 if (EFI_USB_SPEED_LOW
== DeviceSpeed
) {
1739 if (MaximumPacketLength
!= 8) {
1740 Status
= EFI_INVALID_PARAMETER
;
1743 } else if (MaximumPacketLength
!= 8 &&
1744 MaximumPacketLength
!= 16 &&
1745 MaximumPacketLength
!= 32 &&
1746 MaximumPacketLength
!= 64
1748 Status
= EFI_INVALID_PARAMETER
;
1753 // If errors exist that cause host controller halt,
1754 // then return EFI_DEVICE_ERROR.
1756 if (IsEhcHalted (HcDev
) || IsEhcSysError (HcDev
)) {
1757 ClearEhcAllStatus (HcDev
);
1758 *TransferResult
= EFI_USB_ERR_SYSTEM
;
1759 Status
= EFI_DEVICE_ERROR
;
1764 // Map the Request for bus master access.
1765 // BusMasterRead means cpu write
1767 Status
= MapRequestBuffer (
1773 if (EFI_ERROR (Status
)) {
1774 *TransferResult
= EFI_USB_ERR_SYSTEM
;
1775 Status
= EFI_DEVICE_ERROR
;
1780 // Map the source data buffer for bus master access.
1782 Status
= MapDataBuffer (
1791 if (EFI_ERROR (Status
)) {
1792 *TransferResult
= EFI_USB_ERR_SYSTEM
;
1793 Status
= EFI_DEVICE_ERROR
;
1798 // Create and init control Qh
1800 Status
= CreateControlQh (
1804 MaximumPacketLength
,
1808 if (EFI_ERROR (Status
)) {
1809 *TransferResult
= EFI_USB_ERR_SYSTEM
;
1810 Status
= EFI_OUT_OF_RESOURCES
;
1815 // Create and init control Qtds
1817 Status
= CreateControlQtds (
1826 if (EFI_ERROR (Status
)) {
1827 *TransferResult
= EFI_USB_ERR_SYSTEM
;
1828 Status
= EFI_OUT_OF_RESOURCES
;
1835 LinkQtdToQh (QhPtr
, ControlQtdsPtr
);
1837 ClearEhcAllStatus (HcDev
);
1840 // Link Qh and Qtds to Async Schedule List
1842 Status
= LinkQhToAsyncList (HcDev
, QhPtr
);
1843 if (EFI_ERROR (Status
)) {
1844 *TransferResult
= EFI_USB_ERR_SYSTEM
;
1845 Status
= EFI_DEVICE_ERROR
;
1850 // Poll Qh-Qtds execution and get result.
1851 // detail status is returned
1853 Status
= ExecuteTransfer (
1862 if (EFI_ERROR (Status
)) {
1867 // If has errors that cause host controller halt,
1868 // then return EFI_DEVICE_ERROR directly.
1870 if (IsEhcHalted (HcDev
) || IsEhcSysError (HcDev
)) {
1871 *TransferResult
|= EFI_USB_ERR_SYSTEM
;
1874 ClearEhcAllStatus (HcDev
);
1877 UnlinkQhFromAsyncList (HcDev
, QhPtr
);
1878 DestoryQtds (HcDev
, ControlQtdsPtr
);
1880 DestoryQh (HcDev
, QhPtr
);
1882 HcDev
->PciIo
->Unmap (HcDev
->PciIo
, DataMap
);
1884 HcDev
->PciIo
->Unmap (HcDev
->PciIo
, RequestMap
);
1886 HcDev
->PciIo
->Flush (HcDev
->PciIo
);
1893 IN EFI_USB2_HC_PROTOCOL
*This
,
1894 IN UINT8 DeviceAddress
,
1895 IN UINT8 EndPointAddress
,
1896 IN UINT8 DeviceSpeed
,
1897 IN UINTN MaximumPacketLength
,
1898 IN UINT8 DataBuffersNumber
,
1899 IN OUT VOID
*Data
[EFI_USB_MAX_BULK_BUFFER_NUM
],
1900 IN OUT UINTN
*DataLength
,
1901 IN OUT UINT8
*DataToggle
,
1903 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
1904 OUT UINT32
*TransferResult
1908 Routine Description:
1910 Submits bulk transfer to a bulk endpoint of a USB device.
1914 This - A pointer to the EFI_USB2_HC_PROTOCOL instance.
1915 DeviceAddress - Represents the address of the target device on the USB,
1916 which is assigned during USB enumeration.
1917 EndPointAddress - The combination of an endpoint number and an
1918 endpoint direction of the target USB device.
1919 Each endpoint address supports data transfer in
1920 one direction except the control endpoint
1921 (whose default endpoint address is 0).
1922 It is the caller's responsibility to make sure that
1923 the EndPointAddress represents a bulk endpoint.
1924 DeviceSpeed - Indicates device speed. The supported values are EFI_USB_SPEED_FULL
1925 and EFI_USB_SPEED_HIGH.
1926 MaximumPacketLength - Indicates the maximum packet size the target endpoint
1927 is capable of sending or receiving.
1928 DataBuffersNumber - Number of data buffers prepared for the transfer.
1929 Data - Array of pointers to the buffers of data that will be transmitted
1930 to USB device or received from USB device.
1931 DataLength - When input, indicates the size, in bytes, of the data buffer
1932 specified by Data. When output, indicates the actually
1933 transferred data size.
1934 DataToggle - A pointer to the data toggle value. On input, it indicates
1935 the initial data toggle value the bulk transfer should adopt;
1936 on output, it is updated to indicate the data toggle value
1937 of the subsequent bulk transfer.
1938 Translator - A pointr to the transaction translator data.
1939 TimeOut - Indicates the maximum time, in microseconds, which the
1940 transfer is allowed to complete.
1941 TransferResult - A pointer to the detailed result information of the
1947 The bulk transfer was completed successfully.
1948 EFI_OUT_OF_RESOURCES
1949 The bulk transfer could not be submitted due to lack of resource.
1950 EFI_INVALID_PARAMETER
1951 Some parameters are invalid.
1953 The bulk transfer failed due to timeout.
1955 The bulk transfer failed due to host controller or device error.
1956 Caller should check TranferResult for detailed error information.
1963 EHCI_QH_ENTITY
*QhPtr
;
1964 EHCI_QTD_ENTITY
*BulkQtdsPtr
;
1967 EFI_USB_DATA_DIRECTION TransferDirection
;
1973 HcDev
= USB2_HC_DEV_FROM_THIS (This
);
1976 // Parameters Checking
1978 if (NULL
== DataLength
||
1981 NULL
== TransferResult
1983 Status
= EFI_INVALID_PARAMETER
;
1987 if (*DataLength
== 0) {
1988 Status
= EFI_INVALID_PARAMETER
;
1992 if (1 != *DataToggle
&& 0 != *DataToggle
) {
1993 Status
= EFI_INVALID_PARAMETER
;
1997 if (EFI_USB_SPEED_LOW
== DeviceSpeed
) {
1998 Status
= EFI_INVALID_PARAMETER
;
2002 if (EFI_USB_SPEED_FULL
== DeviceSpeed
) {
2003 if (MaximumPacketLength
> 64) {
2004 Status
= EFI_INVALID_PARAMETER
;
2009 if (EFI_USB_SPEED_HIGH
== DeviceSpeed
) {
2010 if (MaximumPacketLength
> 512) {
2011 Status
= EFI_INVALID_PARAMETER
;
2017 // if has errors that cause host controller halt,
2018 // then return EFI_DEVICE_ERROR directly.
2020 if (IsEhcHalted (HcDev
) || IsEhcSysError (HcDev
)) {
2021 ClearEhcAllStatus (HcDev
);
2022 *TransferResult
= EFI_USB_ERR_SYSTEM
;
2023 Status
= EFI_DEVICE_ERROR
;
2027 Status
= ClearEhcAllStatus (HcDev
);
2028 if (EFI_ERROR (Status
)) {
2029 Status
= EFI_DEVICE_ERROR
;
2034 // construct QH and TD data structures,
2035 // and link them together
2037 if (EndPointAddress
& 0x80) {
2038 TransferDirection
= EfiUsbDataIn
;
2040 TransferDirection
= EfiUsbDataOut
;
2043 Status
= MapDataBuffer (
2052 if (EFI_ERROR (Status
)) {
2053 *TransferResult
= EFI_USB_ERR_SYSTEM
;
2054 Status
= EFI_DEVICE_ERROR
;
2059 // Create and init Bulk Qh
2061 Status
= CreateBulkQh (
2067 MaximumPacketLength
,
2071 if (EFI_ERROR (Status
)) {
2072 *TransferResult
= EFI_USB_ERR_SYSTEM
;
2073 Status
= EFI_OUT_OF_RESOURCES
;
2078 // Create and init Bulk Qtds
2080 Status
= CreateBulkOrInterruptQtds (
2088 if (EFI_ERROR (Status
)) {
2089 *TransferResult
= EFI_USB_ERR_SYSTEM
;
2090 Status
= EFI_OUT_OF_RESOURCES
;
2097 LinkQtdToQh (QhPtr
, BulkQtdsPtr
);
2099 ClearEhcAllStatus (HcDev
);
2102 // Link Qh and qtds to Async Schedule List
2104 Status
= LinkQhToAsyncList (HcDev
, QhPtr
);
2105 if (EFI_ERROR (Status
)) {
2106 *TransferResult
= EFI_USB_ERR_SYSTEM
;
2107 Status
= EFI_DEVICE_ERROR
;
2112 // Poll QH-TDs execution and get result.
2113 // detail status is returned
2115 Status
= ExecuteTransfer (
2124 if (EFI_ERROR (Status
)) {
2129 // if has errors that cause host controller halt,
2130 // then return EFI_DEVICE_ERROR directly.
2132 if (IsEhcHalted (HcDev
) || IsEhcSysError (HcDev
)) {
2133 *TransferResult
|= EFI_USB_ERR_SYSTEM
;
2136 ClearEhcAllStatus (HcDev
);
2139 UnlinkQhFromAsyncList (HcDev
, QhPtr
);
2140 DestoryQtds (HcDev
, BulkQtdsPtr
);
2142 DestoryQh (HcDev
, QhPtr
);
2144 HcDev
->PciIo
->Unmap (HcDev
->PciIo
, DataMap
);
2146 HcDev
->PciIo
->Flush (HcDev
->PciIo
);
2152 EhciAsyncInterruptTransfer (
2153 IN EFI_USB2_HC_PROTOCOL
* This
,
2154 IN UINT8 DeviceAddress
,
2155 IN UINT8 EndPointAddress
,
2156 IN UINT8 DeviceSpeed
,
2157 IN UINTN MaximumPacketLength
,
2158 IN BOOLEAN IsNewTransfer
,
2159 IN OUT UINT8
*DataToggle
,
2160 IN UINTN PollingInterval
,
2161 IN UINTN DataLength
,
2162 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
* Translator
,
2163 IN EFI_ASYNC_USB_TRANSFER_CALLBACK CallBackFunction
,
2164 IN VOID
*Context OPTIONAL
2168 Routine Description:
2170 Submits an asynchronous interrupt transfer to an
2171 interrupt endpoint of a USB device.
2172 Translator parameter doesn't exist in UEFI2.0 spec, but it will be updated
2173 in the following specification version.
2177 This - A pointer to the EFI_USB2_HC_PROTOCOL instance.
2178 DeviceAddress - Represents the address of the target device on the USB,
2179 which is assigned during USB enumeration.
2180 EndPointAddress - The combination of an endpoint number and an endpoint
2181 direction of the target USB device. Each endpoint address
2182 supports data transfer in one direction except the
2183 control endpoint (whose default endpoint address is 0).
2184 It is the caller's responsibility to make sure that
2185 the EndPointAddress represents an interrupt endpoint.
2186 DeviceSpeed - Indicates device speed.
2187 MaximumPacketLength - Indicates the maximum packet size the target endpoint
2188 is capable of sending or receiving.
2189 IsNewTransfer - If TRUE, an asynchronous interrupt pipe is built between
2190 the host and the target interrupt endpoint.
2191 If FALSE, the specified asynchronous interrupt pipe
2193 DataToggle - A pointer to the data toggle value. On input, it is valid
2194 when IsNewTransfer is TRUE, and it indicates the initial
2195 data toggle value the asynchronous interrupt transfer
2197 On output, it is valid when IsNewTransfer is FALSE,
2198 and it is updated to indicate the data toggle value of
2199 the subsequent asynchronous interrupt transfer.
2200 PollingInterval - Indicates the interval, in milliseconds, that the
2201 asynchronous interrupt transfer is polled.
2202 This parameter is required when IsNewTransfer is TRUE.
2203 DataLength - Indicates the length of data to be received at the
2204 rate specified by PollingInterval from the target
2205 asynchronous interrupt endpoint. This parameter
2206 is only required when IsNewTransfer is TRUE.
2207 Translator - A pointr to the transaction translator data.
2208 CallBackFunction - The Callback function.This function is called at the
2209 rate specified by PollingInterval.This parameter is
2210 only required when IsNewTransfer is TRUE.
2211 Context - The context that is passed to the CallBackFunction.
2212 - This is an optional parameter and may be NULL.
2217 The asynchronous interrupt transfer request has been successfully
2218 submitted or canceled.
2219 EFI_INVALID_PARAMETER
2220 Some parameters are invalid.
2221 EFI_OUT_OF_RESOURCES
2222 The request could not be completed due to a lack of resources.
2231 EHCI_QH_ENTITY
*QhPtr
;
2232 EHCI_QTD_ENTITY
*InterruptQtdsPtr
;
2237 EHCI_ASYNC_REQUEST
*AsyncRequestPtr
;
2241 InterruptQtdsPtr
= NULL
;
2245 AsyncRequestPtr
= NULL
;
2246 HcDev
= USB2_HC_DEV_FROM_THIS (This
);
2249 // Parameters Checking
2251 if (!IsDataInTransfer (EndPointAddress
)) {
2252 Status
= EFI_INVALID_PARAMETER
;
2256 if (IsNewTransfer
) {
2257 if (0 == DataLength
) {
2258 Status
= EFI_INVALID_PARAMETER
;
2262 if (*DataToggle
!= 1 && *DataToggle
!= 0) {
2263 Status
= EFI_INVALID_PARAMETER
;
2267 if (PollingInterval
> 255 || PollingInterval
< 1) {
2268 Status
= EFI_INVALID_PARAMETER
;
2274 // if has errors that cause host controller halt,
2275 // then return EFI_DEVICE_ERROR directly.
2277 if (IsEhcHalted (HcDev
) || IsEhcSysError (HcDev
)) {
2278 ClearEhcAllStatus (HcDev
);
2279 Status
= EFI_DEVICE_ERROR
;
2283 Status
= ClearEhcAllStatus (HcDev
);
2284 if (EFI_ERROR (Status
)) {
2285 Status
= EFI_DEVICE_ERROR
;
2290 // Delete Async interrupt transfer request
2292 if (!IsNewTransfer
) {
2294 OldTpl
= gBS
->RaiseTPL (EFI_TPL_NOTIFY
);
2296 Status
= DeleteAsyncRequestTransfer (
2303 gBS
->RestoreTPL (OldTpl
);
2308 Status
= EhciAllocatePool (
2310 (UINT8
**) &AsyncRequestPtr
,
2311 sizeof (EHCI_ASYNC_REQUEST
)
2313 if (EFI_ERROR (Status
)) {
2314 Status
= EFI_OUT_OF_RESOURCES
;
2318 Status
= EhciAllocatePool (HcDev
, &DataPtr
, DataLength
);
2319 if (EFI_ERROR (Status
)) {
2320 Status
= EFI_OUT_OF_RESOURCES
;
2324 MappedLength
= DataLength
;
2325 Status
= MapDataBuffer (
2334 if (EFI_ERROR (Status
)) {
2335 Status
= EFI_DEVICE_ERROR
;
2340 // Create and init Interrupt Qh
2342 Status
= CreateInterruptQh (
2348 MaximumPacketLength
,
2353 if (EFI_ERROR (Status
)) {
2354 Status
= EFI_OUT_OF_RESOURCES
;
2359 // Create and init Interrupt Qtds
2361 Status
= CreateBulkOrInterruptQtds (
2369 if (EFI_ERROR (Status
)) {
2370 Status
= EFI_OUT_OF_RESOURCES
;
2377 LinkQtdToQh (QhPtr
, InterruptQtdsPtr
);
2380 // Init AsyncRequest Entry
2382 AsyncRequestPtr
->Context
= Context
;
2383 AsyncRequestPtr
->CallBackFunc
= CallBackFunction
;
2384 AsyncRequestPtr
->TransferType
= ASYNC_INTERRUPT_TRANSFER
;
2385 AsyncRequestPtr
->QhPtr
= QhPtr
;
2386 AsyncRequestPtr
->Prev
= NULL
;
2387 AsyncRequestPtr
->Next
= NULL
;
2389 if (NULL
== HcDev
->AsyncRequestList
) {
2390 Status
= StartPollingTimer (HcDev
);
2391 if (EFI_ERROR (Status
)) {
2392 Status
= EFI_DEVICE_ERROR
;
2393 CleanUpAllAsyncRequestTransfer (HcDev
);
2399 // Link Entry to AsyncRequest List
2401 LinkToAsyncReqeust (HcDev
, AsyncRequestPtr
);
2403 ClearEhcAllStatus (HcDev
);
2405 Status
= DisablePeriodicSchedule (HcDev
);
2406 if (EFI_ERROR (Status
)) {
2407 Status
= EFI_DEVICE_ERROR
;
2411 Status
= WaitForPeriodicScheduleDisable (HcDev
, EHCI_GENERIC_TIMEOUT
);
2412 if (EFI_ERROR (Status
)) {
2413 Status
= EFI_TIMEOUT
;
2418 // Link Qh and Qtds to Periodic Schedule List
2420 LinkQhToPeriodicList (HcDev
, QhPtr
);
2422 Status
= EnablePeriodicSchedule (HcDev
);
2423 if (EFI_ERROR (Status
)) {
2424 Status
= EFI_DEVICE_ERROR
;
2428 Status
= WaitForPeriodicScheduleEnable (HcDev
, EHCI_GENERIC_TIMEOUT
);
2429 if (EFI_ERROR (Status
)) {
2430 Status
= EFI_TIMEOUT
;
2434 if (IsEhcHalted (HcDev
)) {
2435 Status
= StartScheduleExecution (HcDev
);
2436 if (EFI_ERROR (Status
)) {
2437 Status
= EFI_DEVICE_ERROR
;
2442 HcDev
->PciIo
->Flush (HcDev
->PciIo
);
2446 DestoryQh (HcDev
, QhPtr
);
2448 EhciFreePool (HcDev
, DataPtr
, DataLength
);
2452 (UINT8
*) AsyncRequestPtr
,
2453 sizeof (EHCI_ASYNC_REQUEST
)
2456 HcDev
->PciIo
->Unmap (HcDev
->PciIo
, DataMap
);
2463 EhciSyncInterruptTransfer (
2464 IN EFI_USB2_HC_PROTOCOL
*This
,
2465 IN UINT8 DeviceAddress
,
2466 IN UINT8 EndPointAddress
,
2467 IN UINT8 DeviceSpeed
,
2468 IN UINTN MaximumPacketLength
,
2470 IN OUT UINTN
*DataLength
,
2471 IN OUT UINT8
*DataToggle
,
2473 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
2474 OUT UINT32
*TransferResult
2478 Routine Description:
2480 Submits synchronous interrupt transfer to an interrupt endpoint
2482 Translator parameter doesn't exist in UEFI2.0 spec, but it will be updated
2483 in the following specification version.
2487 This - A pointer to the EFI_USB2_HC_PROTOCOL instance.
2488 DeviceAddress - Represents the address of the target device on the USB,
2489 which is assigned during USB enumeration.
2490 EndPointAddress - The combination of an endpoint number and an endpoint
2491 direction of the target USB device. Each endpoint
2492 address supports data transfer in one direction
2493 except the control endpoint (whose default
2494 endpoint address is 0). It is the caller's responsibility
2495 to make sure that the EndPointAddress represents
2496 an interrupt endpoint.
2497 DeviceSpeed - Indicates device speed.
2498 MaximumPacketLength - Indicates the maximum packet size the target endpoint
2499 is capable of sending or receiving.
2500 Data - A pointer to the buffer of data that will be transmitted
2501 to USB device or received from USB device.
2502 DataLength - On input, the size, in bytes, of the data buffer specified
2503 by Data. On output, the number of bytes transferred.
2504 DataToggle - A pointer to the data toggle value. On input, it indicates
2505 the initial data toggle value the synchronous interrupt
2506 transfer should adopt;
2507 on output, it is updated to indicate the data toggle value
2508 of the subsequent synchronous interrupt transfer.
2509 TimeOut - Indicates the maximum time, in microseconds, which the
2510 transfer is allowed to complete.
2511 Translator - A pointr to the transaction translator data.
2512 TransferResult - A pointer to the detailed result information from
2513 the synchronous interrupt transfer.
2518 The synchronous interrupt transfer was completed successfully.
2519 EFI_OUT_OF_RESOURCES
2520 The synchronous interrupt transfer could not be submitted due
2521 to lack of resource.
2522 EFI_INVALID_PARAMETER
2523 Some parameters are invalid.
2525 The synchronous interrupt transfer failed due to timeout.
2527 The synchronous interrupt transfer failed due to host controller
2528 or device error. Caller should check TranferResult for detailed
2536 EHCI_QH_ENTITY
*QhPtr
;
2537 EHCI_QTD_ENTITY
*InterruptQtdsPtr
;
2542 InterruptQtdsPtr
= NULL
;
2545 HcDev
= USB2_HC_DEV_FROM_THIS (This
);
2548 // Parameters Checking
2550 if (DataLength
== NULL
||
2552 TransferResult
== NULL
2554 Status
= EFI_INVALID_PARAMETER
;
2558 if (!IsDataInTransfer (EndPointAddress
)) {
2559 Status
= EFI_INVALID_PARAMETER
;
2563 if (0 == *DataLength
) {
2564 Status
= EFI_INVALID_PARAMETER
;
2568 if (*DataToggle
!= 1 && *DataToggle
!= 0) {
2569 Status
= EFI_INVALID_PARAMETER
;
2573 if (EFI_USB_SPEED_LOW
== DeviceSpeed
&& 8 != MaximumPacketLength
) {
2574 Status
= EFI_INVALID_PARAMETER
;
2578 if (EFI_USB_SPEED_FULL
== DeviceSpeed
&& MaximumPacketLength
> 64) {
2579 Status
= EFI_INVALID_PARAMETER
;
2583 if (EFI_USB_SPEED_HIGH
== DeviceSpeed
&& MaximumPacketLength
> 3072) {
2584 Status
= EFI_INVALID_PARAMETER
;
2589 // if has errors that cause host controller halt,
2590 // then return EFI_DEVICE_ERROR directly.
2592 if (IsEhcHalted (HcDev
) || IsEhcSysError (HcDev
)) {
2593 ClearEhcAllStatus (HcDev
);
2594 *TransferResult
= EFI_USB_ERR_SYSTEM
;
2595 Status
= EFI_DEVICE_ERROR
;
2599 Status
= ClearEhcAllStatus (HcDev
);
2600 if (EFI_ERROR (Status
)) {
2601 Status
= EFI_DEVICE_ERROR
;
2605 Status
= MapDataBuffer (
2614 if (EFI_ERROR (Status
)) {
2615 *TransferResult
= EFI_USB_ERR_SYSTEM
;
2616 Status
= EFI_DEVICE_ERROR
;
2621 // Create and init Interrupt Qh
2623 Status
= CreateInterruptQh (
2629 MaximumPacketLength
,
2634 if (EFI_ERROR (Status
)) {
2635 Status
= EFI_OUT_OF_RESOURCES
;
2640 // Create and init Interrupt Qtds
2642 Status
= CreateBulkOrInterruptQtds (
2650 if (EFI_ERROR (Status
)) {
2651 *TransferResult
= EFI_USB_ERR_SYSTEM
;
2652 Status
= EFI_OUT_OF_RESOURCES
;
2659 LinkQtdToQh (QhPtr
, InterruptQtdsPtr
);
2661 ClearEhcAllStatus (HcDev
);
2663 Status
= DisablePeriodicSchedule (HcDev
);
2664 if (EFI_ERROR (Status
)) {
2665 Status
= EFI_DEVICE_ERROR
;
2669 Status
= WaitForPeriodicScheduleDisable (HcDev
, EHCI_GENERIC_TIMEOUT
);
2670 if (EFI_ERROR (Status
)) {
2671 Status
= EFI_TIMEOUT
;
2676 // Link Qh and Qtds to Periodic Schedule List
2678 LinkQhToPeriodicList (HcDev
, QhPtr
);
2680 Status
= EnablePeriodicSchedule (HcDev
);
2681 if (EFI_ERROR (Status
)) {
2682 Status
= EFI_DEVICE_ERROR
;
2686 Status
= WaitForPeriodicScheduleEnable (HcDev
, EHCI_GENERIC_TIMEOUT
);
2687 if (EFI_ERROR (Status
)) {
2688 Status
= EFI_TIMEOUT
;
2692 if (IsEhcHalted (HcDev
)) {
2693 Status
= StartScheduleExecution (HcDev
);
2694 if (EFI_ERROR (Status
)) {
2695 Status
= EFI_DEVICE_ERROR
;
2701 // Poll QH-TDs execution and get result.
2702 // detail status is returned
2704 Status
= ExecuteTransfer (
2713 if (EFI_ERROR (Status
)) {
2718 // if has errors that cause host controller halt,
2719 // then return EFI_DEVICE_ERROR directly.
2721 if (IsEhcHalted (HcDev
) || IsEhcSysError (HcDev
)) {
2722 *TransferResult
|= EFI_USB_ERR_SYSTEM
;
2725 ClearEhcAllStatus (HcDev
);
2728 UnlinkQhFromPeriodicList (HcDev
, QhPtr
, 0);
2729 DestoryQtds (HcDev
, InterruptQtdsPtr
);
2731 DestoryQh (HcDev
, QhPtr
);
2733 HcDev
->PciIo
->Unmap (HcDev
->PciIo
, DataMap
);
2735 HcDev
->PciIo
->Flush (HcDev
->PciIo
);
2741 EhciIsochronousTransfer (
2742 IN EFI_USB2_HC_PROTOCOL
*This
,
2743 IN UINT8 DeviceAddress
,
2744 IN UINT8 EndPointAddress
,
2745 IN UINT8 DeviceSpeed
,
2746 IN UINTN MaximumPacketLength
,
2747 IN UINT8 DataBuffersNumber
,
2748 IN OUT VOID
*Data
[EFI_USB_MAX_ISO_BUFFER_NUM
],
2749 IN UINTN DataLength
,
2750 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
2751 OUT UINT32
*TransferResult
2755 Routine Description:
2757 Submits isochronous transfer to a target USB device.
2761 This - A pointer to the EFI_USB2_HC_PROTOCOL instance.
2762 DeviceAddress - Represents the address of the target device on the USB,
2763 which is assigned during USB enumeration.
2764 EndPointAddress - End point address
2765 DeviceSpeed - Indicates device speed.
2766 MaximumPacketLength - Indicates the maximum packet size that the
2767 default control transfer endpoint is capable of
2768 sending or receiving.
2769 DataBuffersNumber - Number of data buffers prepared for the transfer.
2770 Data - Array of pointers to the buffers of data that will be
2771 transmitted to USB device or received from USB device.
2772 DataLength - Indicates the size, in bytes, of the data buffer
2774 Translator - A pointr to the transaction translator data.
2775 TransferResult - A pointer to the detailed result information generated
2776 by this control transfer.
2784 return EFI_UNSUPPORTED
;
2789 EhciAsyncIsochronousTransfer (
2790 IN EFI_USB2_HC_PROTOCOL
*This
,
2791 IN UINT8 DeviceAddress
,
2792 IN UINT8 EndPointAddress
,
2793 IN UINT8 DeviceSpeed
,
2794 IN UINTN MaximumPacketLength
,
2795 IN UINT8 DataBuffersNumber
,
2796 IN OUT VOID
*Data
[EFI_USB_MAX_ISO_BUFFER_NUM
],
2797 IN UINTN DataLength
,
2798 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
2799 IN EFI_ASYNC_USB_TRANSFER_CALLBACK IsochronousCallBack
,
2804 Routine Description:
2806 Submits Async isochronous transfer to a target USB device.
2810 This - A pointer to the EFI_USB2_HC_PROTOCOL instance.
2811 DeviceAddress - Represents the address of the target device on the USB,
2812 which is assigned during USB enumeration.
2813 EndPointAddress - End point address
2814 DeviceSpeed - Indicates device speed.
2815 MaximumPacketLength - Indicates the maximum packet size that the
2816 default control transfer endpoint is capable of
2817 sending or receiving.
2818 DataBuffersNumber - Number of data buffers prepared for the transfer.
2819 Data - Array of pointers to the buffers of data that will be transmitted
2820 to USB device or received from USB device.
2821 Translator - A pointr to the transaction translator data.
2822 IsochronousCallBack - When the transfer complete, the call back function will be called
2823 Context - Pass to the call back function as parameter
2831 return EFI_UNSUPPORTED
;