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.
25 UINTN gEHCDebugLevel
= EFI_D_INFO
;
26 UINTN gEHCErrorLevel
= EFI_D_ERROR
;
30 // Driver model protocol interface
35 EhciDriverBindingSupported (
36 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
37 IN EFI_HANDLE Controller
,
38 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
43 EhciDriverBindingStart (
44 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
45 IN EFI_HANDLE Controller
,
46 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
51 EhciDriverBindingStop (
52 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
53 IN EFI_HANDLE Controller
,
54 IN UINTN NumberOfChildren
,
55 IN EFI_HANDLE
*ChildHandleBuffer
59 // Ehci protocol interface
64 IN EFI_USB2_HC_PROTOCOL
*This
,
66 OUT UINT8
*PortNumber
,
67 OUT UINT8
*Is64BitCapable
73 IN EFI_USB2_HC_PROTOCOL
*This
,
80 IN EFI_USB2_HC_PROTOCOL
*This
,
81 OUT EFI_USB_HC_STATE
*State
87 IN EFI_USB2_HC_PROTOCOL
*This
,
88 IN EFI_USB_HC_STATE State
94 IN EFI_USB2_HC_PROTOCOL
*This
,
95 IN UINT8 DeviceAddress
,
97 IN UINTN MaximumPacketLength
,
98 IN EFI_USB_DEVICE_REQUEST
*Request
,
99 IN EFI_USB_DATA_DIRECTION TransferDirection
,
101 IN OUT UINTN
*DataLength
,
103 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
104 OUT UINT32
*TransferResult
110 IN EFI_USB2_HC_PROTOCOL
*This
,
111 IN UINT8 DeviceAddress
,
112 IN UINT8 EndPointAddress
,
113 IN UINT8 DeviceSpeed
,
114 IN UINTN MaximumPacketLength
,
115 IN UINT8 DataBuffersNumber
,
116 IN OUT VOID
*Data
[EFI_USB_MAX_BULK_BUFFER_NUM
],
117 IN OUT UINTN
*DataLength
,
118 IN OUT UINT8
*DataToggle
,
120 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
121 OUT UINT32
*TransferResult
126 EhciAsyncInterruptTransfer (
127 IN EFI_USB2_HC_PROTOCOL
* This
,
128 IN UINT8 DeviceAddress
,
129 IN UINT8 EndPointAddress
,
130 IN UINT8 DeviceSpeed
,
131 IN UINTN MaxiumPacketLength
,
132 IN BOOLEAN IsNewTransfer
,
133 IN OUT UINT8
*DataToggle
,
134 IN UINTN PollingInterval
,
136 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
137 IN EFI_ASYNC_USB_TRANSFER_CALLBACK CallBackFunction
,
138 IN VOID
*Context OPTIONAL
143 EhciSyncInterruptTransfer (
144 IN EFI_USB2_HC_PROTOCOL
*This
,
145 IN UINT8 DeviceAddress
,
146 IN UINT8 EndPointAddress
,
147 IN UINT8 DeviceSpeed
,
148 IN UINTN MaximumPacketLength
,
150 IN OUT UINTN
*DataLength
,
151 IN OUT UINT8
*DataToggle
,
153 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
154 OUT UINT32
*TransferResult
159 EhciIsochronousTransfer (
160 IN EFI_USB2_HC_PROTOCOL
*This
,
161 IN UINT8 DeviceAddress
,
162 IN UINT8 EndPointAddress
,
163 IN UINT8 DeviceSpeed
,
164 IN UINTN MaximumPacketLength
,
165 IN UINT8 DataBuffersNumber
,
166 IN OUT VOID
*Data
[EFI_USB_MAX_ISO_BUFFER_NUM
],
168 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
169 OUT UINT32
*TransferResult
174 EhciAsyncIsochronousTransfer (
175 IN EFI_USB2_HC_PROTOCOL
*This
,
176 IN UINT8 DeviceAddress
,
177 IN UINT8 EndPointAddress
,
178 IN UINT8 DeviceSpeed
,
179 IN UINTN MaximumPacketLength
,
180 IN UINT8 DataBuffersNumber
,
181 IN OUT VOID
*Data
[EFI_USB_MAX_ISO_BUFFER_NUM
],
183 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
184 IN EFI_ASYNC_USB_TRANSFER_CALLBACK IsochronousCallBack
,
190 EhciGetRootHubPortStatus (
191 IN EFI_USB2_HC_PROTOCOL
*This
,
193 OUT EFI_USB_PORT_STATUS
*PortStatus
198 EhciSetRootHubPortFeature (
199 IN EFI_USB2_HC_PROTOCOL
*This
,
201 IN EFI_USB_PORT_FEATURE PortFeature
206 EhciClearRootHubPortFeature (
207 IN EFI_USB2_HC_PROTOCOL
*This
,
209 IN EFI_USB_PORT_FEATURE PortFeature
213 // Ehci Driver Global Variables
215 EFI_DRIVER_BINDING_PROTOCOL gEhciDriverBinding
= {
216 EhciDriverBindingSupported
,
217 EhciDriverBindingStart
,
218 EhciDriverBindingStop
,
224 UINT32 mUsbCapabilityLen
;
225 UINT32 mDeviceSpeed
[16];
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
;
444 // Create and Init Perodic Frame List
446 Status
= EhciGetCapability (
452 if (EFI_ERROR (Status
)) {
453 Status
= EFI_OUT_OF_RESOURCES
;
454 goto uninstall_usb2hc_protocol
;
456 HcDev
->Is64BitCapable
= Is64BitCapable
;
459 // Create and Init Perodic Frame List
461 Status
= InitialPeriodicFrameList (
463 EHCI_MAX_FRAME_LIST_LENGTH
465 if (EFI_ERROR (Status
)) {
466 Status
= EFI_OUT_OF_RESOURCES
;
467 goto uninstall_usb2hc_protocol
;
471 // Init memory pool management
473 Status
= InitialMemoryManagement (HcDev
);
474 if (EFI_ERROR (Status
)) {
475 Status
= EFI_OUT_OF_RESOURCES
;
476 goto deinit_perodic_frame_list
;
480 // Create AsyncRequest Polling Timer
482 Status
= CreatePollingTimer (HcDev
, (EFI_EVENT_NOTIFY
) AsyncRequestMoniter
);
483 if (EFI_ERROR (Status
)) {
484 Status
= EFI_OUT_OF_RESOURCES
;
485 goto deinit_memory_management
;
489 // Default Maxximum Interrupt Interval is 8,
490 // it means that 8 micro frame = 1ms
494 // Start the Host Controller
496 if (IsEhcHalted (HcDev
)) {
497 Status
= StartScheduleExecution (HcDev
);
498 if (EFI_ERROR (Status
)) {
499 Status
= EFI_DEVICE_ERROR
;
505 // Set all ports routing to EHC
507 Status
= SetPortRoutingEhc (HcDev
);
508 if (EFI_ERROR (Status
)) {
509 Status
= EFI_DEVICE_ERROR
;
514 // Component name protocol
516 Status
= AddUnicodeString (
518 gEhciComponentName
.SupportedLanguages
,
519 &HcDev
->ControllerNameTable
,
520 L
"Usb Enhanced Host Controller"
522 if (EFI_ERROR (Status
)) {
523 Status
= EFI_OUT_OF_RESOURCES
;
530 // Error handle process
533 DestoryPollingTimer (HcDev
);
534 deinit_memory_management
:
535 DeinitialMemoryManagement (HcDev
);
536 deinit_perodic_frame_list
:
537 DeinitialPeriodicFrameList (HcDev
);
538 uninstall_usb2hc_protocol
:
539 gBS
->UninstallProtocolInterface (
541 &gEfiUsb2HcProtocolGuid
,
545 gBS
->FreePool (HcDev
);
546 close_pciio_protocol
:
549 &gEfiPciIoProtocolGuid
,
550 This
->DriverBindingHandle
,
560 EhciDriverBindingStop (
561 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
562 IN EFI_HANDLE Controller
,
563 IN UINTN NumberOfChildren
,
564 IN EFI_HANDLE
*ChildHandleBuffer
570 Stop this driver on ControllerHandle. Support stoping any child handles
571 created by this driver.
575 This - Protocol instance pointer.
576 Controller - Handle of device to stop driver on
577 NumberOfChildren - Number of Children in the ChildHandleBuffer
578 ChildHandleBuffer - List of handles for the children we need to stop.
583 EFI_DEVICE_ERROR Fail
587 EFI_USB2_HC_PROTOCOL
*Usb2Hc
;
591 // Test whether the Controller handler passed in is a valid
592 // Usb controller handle that should be supported, if not,
593 // return the error status directly
595 Status
= gBS
->OpenProtocol (
597 &gEfiUsb2HcProtocolGuid
,
599 This
->DriverBindingHandle
,
601 EFI_OPEN_PROTOCOL_GET_PROTOCOL
603 if (EFI_ERROR (Status
)) {
604 Status
= EFI_DEVICE_ERROR
;
608 HcDev
= USB2_HC_DEV_FROM_THIS (Usb2Hc
);
611 // free all the controller related memory and uninstall UHCI Protocol.
613 Status
= gBS
->UninstallProtocolInterface (
615 &gEfiUsb2HcProtocolGuid
,
618 if (EFI_ERROR (Status
)) {
619 Status
= EFI_DEVICE_ERROR
;
624 // Set Host Controller state as halt
626 Status
= Usb2Hc
->SetState (
630 if (EFI_ERROR (Status
)) {
631 Status
= EFI_DEVICE_ERROR
;
636 // Stop AsyncRequest Polling Timer
638 Status
= StopPollingTimer (HcDev
);
639 if (EFI_ERROR (Status
)) {
640 Status
= EFI_DEVICE_ERROR
;
645 // Destroy Asynchronous Request Event
647 DestoryPollingTimer (HcDev
);
650 // Destroy Perodic Frame List
652 DeinitialPeriodicFrameList (HcDev
);
655 // Deinit Ehci pool memory management
657 DeinitialMemoryManagement (HcDev
);
660 // Denint Unicode String Table
662 FreeUnicodeStringTable (HcDev
->ControllerNameTable
);
665 // Disable the USB Host Controller
667 Status
= HcDev
->PciIo
->Attributes (
669 EfiPciIoAttributeOperationDisable
,
670 EFI_PCI_DEVICE_ENABLE
,
673 if (EFI_ERROR (Status
)) {
674 Status
= EFI_DEVICE_ERROR
;
678 gBS
->FreePool (HcDev
);
682 &gEfiPciIoProtocolGuid
,
683 This
->DriverBindingHandle
,
694 IN EFI_USB2_HC_PROTOCOL
*This
,
696 OUT UINT8
*PortNumber
,
697 OUT UINT8
*Is64BitCapable
703 Retrieves the capablility of root hub ports.
707 This - A pointer to the EFI_USB_HC_PROTOCOL instance.
708 MaxSpeed - A pointer to the number of the host controller.
709 PortNumber - A pointer to the number of the root hub ports.
710 Is64BitCapable - A pointer to the flag for whether controller supports
711 64-bit memory addressing.
715 EFI_SUCCESS host controller capability were retrieved successfully.
716 EFI_INVALID_PARAMETER MaxSpeed or PortNumber or Is64BitCapable is NULL.
717 EFI_DEVICE_ERROR An error was encountered while attempting to retrieve the capabilities.
723 UINT32 HcStructParamsAddr
;
724 UINT32 HcStructParamsReg
;
725 UINT32 HcCapParamsAddr
;
726 UINT32 HcCapParamsReg
;
728 if (MaxSpeed
== NULL
|| PortNumber
== NULL
|| Is64BitCapable
== NULL
) {
729 Status
= EFI_INVALID_PARAMETER
;
733 HcStructParamsAddr
= HCSPARAMS
;
734 HcCapParamsAddr
= HCCPARAMS
;
735 HcDev
= USB2_HC_DEV_FROM_THIS (This
);
737 Status
= ReadEhcCapabiltiyReg (
742 if (EFI_ERROR (Status
)) {
743 Status
= EFI_DEVICE_ERROR
;
747 Status
= ReadEhcCapabiltiyReg (
752 if (EFI_ERROR (Status
)) {
753 Status
= EFI_DEVICE_ERROR
;
757 *MaxSpeed
= EFI_USB_SPEED_HIGH
;
758 *PortNumber
= (UINT8
) (HcStructParamsReg
& HCSP_NPORTS
);
759 *Is64BitCapable
= (UINT8
) (HcCapParamsReg
& HCCP_64BIT
);
768 IN EFI_USB2_HC_PROTOCOL
*This
,
775 Provides software reset for the USB host controller.
779 This - A pointer to the EFI_USB2_HC_PROTOCOL instance.
780 Attributes - A bit mask of the reset operation to perform.
781 See below for a list of the supported bit mask values.
783 #define EFI_USB_HC_RESET_GLOBAL 0x0001
784 #define EFI_USB_HC_RESET_HOST_CONTROLLER 0x0002
785 #define EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG 0x0004
786 #define EFI_USB_HC_RESET_HOST_WITH_DEBUG 0x0008
788 EFI_USB_HC_RESET_GLOBAL
789 If this bit is set, a global reset signal will be sent to the USB bus.
790 This resets all of the USB bus logic, including the USB host
791 controller hardware and all the devices attached on the USB bus.
792 EFI_USB_HC_RESET_HOST_CONTROLLER
793 If this bit is set, the USB host controller hardware will be reset.
794 No reset signal will be sent to the USB bus.
795 EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG
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 If this is an EHCI controller and the debug port has configured, then
800 this is will still reset the host controller.
801 EFI_USB_HC_RESET_HOST_WITH_DEBUG
802 If this bit is set, the USB host controller hardware will be reset.
803 If this is an EHCI controller and the debug port has been configured,
804 then this will still reset the host controller.
809 The reset operation succeeded.
810 EFI_INVALID_PARAMETER
811 Attributes is not valid.
813 The type of reset specified by Attributes is not currently supported by
814 the host controller hardware.
816 Reset operation is rejected due to the debug port being configured and
817 active; only EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG or
818 EFI_USB_HC_RESET_HOST_WITH_DEBUG reset Atrributes can be used to
819 perform reset operation for this host controller.
821 An error was encountered while attempting to perform
829 FRAME_LIST_ENTRY
*FrameEntryPtr
;
831 HcDev
= USB2_HC_DEV_FROM_THIS (This
);
833 switch (Attributes
) {
835 case EFI_USB_HC_RESET_GLOBAL
:
838 // Same behavior as Host Controller Reset
841 case EFI_USB_HC_RESET_HOST_CONTROLLER
:
844 // Host Controller must be Halt when Reset it
846 if (IsEhcHalted (HcDev
)) {
847 Status
= ResetEhc (HcDev
);
848 if (EFI_ERROR (Status
)) {
849 Status
= EFI_DEVICE_ERROR
;
853 // Set to zero by Host Controller when reset process completes
855 Status
= WaitForEhcReset (HcDev
, EHCI_GENERIC_TIMEOUT
);
856 if (EFI_ERROR (Status
)) {
857 Status
= EFI_TIMEOUT
;
861 Status
= EFI_DEVICE_ERROR
;
866 // only asynchronous interrupt transfers are always alive on the bus, need to cleanup
868 CleanUpAllAsyncRequestTransfer (HcDev
);
869 Status
= ClearEhcAllStatus (HcDev
);
870 if (EFI_ERROR (Status
)) {
871 Status
= EFI_DEVICE_ERROR
;
876 // Set appropriate 4G Segment Selector
878 Status
= SetCtrlDataStructSeg (HcDev
);
879 if (EFI_ERROR (Status
)) {
880 Status
= EFI_DEVICE_ERROR
;
885 // Init Perodic List Base Addr and Frame List
887 Status
= SetFrameListBaseAddr (
889 GET_0B_TO_31B (HcDev
->PeriodicFrameListBuffer
)
891 if (EFI_ERROR (Status
)) {
892 Status
= EFI_DEVICE_ERROR
;
895 FrameEntryPtr
= (FRAME_LIST_ENTRY
*) HcDev
->PeriodicFrameListBuffer
;
896 for (FrameIndex
= 0; FrameIndex
< HcDev
->PeriodicFrameListLength
; FrameIndex
++) {
897 FrameEntryPtr
->LinkTerminate
= TRUE
;
902 // Start the Host Controller
904 if (IsEhcHalted (HcDev
)) {
905 Status
= StartScheduleExecution (HcDev
);
906 if (EFI_ERROR (Status
)) {
907 Status
= EFI_DEVICE_ERROR
;
913 // Set all ports routing to EHC
915 Status
= SetPortRoutingEhc (HcDev
);
916 if (EFI_ERROR (Status
)) {
917 Status
= EFI_DEVICE_ERROR
;
922 case EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG
:
924 Status
= EFI_UNSUPPORTED
;
927 case EFI_USB_HC_RESET_HOST_WITH_DEBUG
:
929 Status
= EFI_UNSUPPORTED
;
933 Status
= EFI_INVALID_PARAMETER
;
943 IN EFI_USB2_HC_PROTOCOL
*This
,
944 OUT EFI_USB_HC_STATE
*State
950 Retrieves current state of the USB host controller.
954 This A pointer to the EFI_USB2_HC_PROTOCOL instance.
955 State A pointer to the EFI_USB_HC_STATE data structure that
956 indicates current state of the USB host controller.
957 Type EFI_USB_HC_STATE is defined below.
961 EfiUsbHcStateOperational,
962 EfiUsbHcStateSuspend,
969 The state information of the host controller was returned in State.
970 EFI_INVALID_PARAMETER
973 An error was encountered while attempting to retrieve the
974 host controller's current state.
979 UINT32 UsbStatusAddr
;
983 Status
= EFI_INVALID_PARAMETER
;
987 UsbStatusAddr
= USBSTS
;
988 HcDev
= USB2_HC_DEV_FROM_THIS (This
);
990 Status
= ReadEhcOperationalReg (
995 if (EFI_ERROR (Status
)) {
996 Status
= EFI_DEVICE_ERROR
;
1000 if (UsbStatusReg
& USBSTS_HCH
) {
1001 *State
= EfiUsbHcStateHalt
;
1003 *State
= EfiUsbHcStateOperational
;
1013 IN EFI_USB2_HC_PROTOCOL
*This
,
1014 IN EFI_USB_HC_STATE State
1018 Routine Description:
1020 Sets the USB host controller to a specific state.
1024 This - A pointer to the EFI_USB2_HC_PROTOCOL instance.
1025 State - Indicates the state of the host controller that will be set.
1030 The USB host controller was successfully placed in the state
1032 EFI_INVALID_PARAMETER
1035 Failed to set the state specified by State due to device error.
1041 UINT32 UsbCommandAddr
;
1042 UINT32 UsbCommandReg
;
1043 EFI_USB_HC_STATE CurrentState
;
1045 UsbCommandAddr
= USBCMD
;
1046 HcDev
= USB2_HC_DEV_FROM_THIS (This
);
1048 Status
= EhciGetState (This
, &CurrentState
);
1049 if (EFI_ERROR (Status
)) {
1050 Status
= EFI_DEVICE_ERROR
;
1056 case EfiUsbHcStateHalt
:
1058 if (EfiUsbHcStateHalt
== CurrentState
) {
1059 Status
= EFI_SUCCESS
;
1061 } else if (EfiUsbHcStateOperational
== CurrentState
) {
1062 Status
= ReadEhcOperationalReg (
1067 if (EFI_ERROR (Status
)) {
1068 Status
= EFI_DEVICE_ERROR
;
1072 UsbCommandReg
&= ~USBCMD_RS
;
1073 Status
= WriteEhcOperationalReg (
1078 if (EFI_ERROR (Status
)) {
1079 Status
= EFI_DEVICE_ERROR
;
1083 // Ensure the HC is in halt status after send the stop command
1085 Status
= WaitForEhcHalt (HcDev
, EHCI_GENERIC_TIMEOUT
);
1086 if (EFI_ERROR (Status
)) {
1087 Status
= EFI_TIMEOUT
;
1093 case EfiUsbHcStateOperational
:
1095 if (IsEhcSysError (HcDev
)) {
1096 Status
= EFI_DEVICE_ERROR
;
1099 if (EfiUsbHcStateOperational
== CurrentState
) {
1100 Status
= EFI_SUCCESS
;
1102 } else if (EfiUsbHcStateHalt
== CurrentState
) {
1104 // Set Host Controller Run
1106 Status
= ReadEhcOperationalReg (
1111 if (EFI_ERROR (Status
)) {
1112 return EFI_DEVICE_ERROR
;
1115 UsbCommandReg
|= USBCMD_RS
;
1116 Status
= WriteEhcOperationalReg (
1121 if (EFI_ERROR (Status
)) {
1122 Status
= EFI_DEVICE_ERROR
;
1128 case EfiUsbHcStateSuspend
:
1130 Status
= EFI_UNSUPPORTED
;
1135 Status
= EFI_INVALID_PARAMETER
;
1144 EhciGetRootHubPortStatus (
1145 IN EFI_USB2_HC_PROTOCOL
*This
,
1146 IN UINT8 PortNumber
,
1147 OUT EFI_USB_PORT_STATUS
*PortStatus
1151 Routine Description:
1153 Retrieves the current status of a USB root hub port.
1157 This - A pointer to the EFI_USB2_HC_PROTOCOL.
1158 PortNumber - Specifies the root hub port from which the status
1159 is to be retrieved. This value is zero-based. For example,
1160 if a root hub has two ports, then the first port is numbered 0,
1161 and the second port is numbered 1.
1162 PortStatus - A pointer to the current port status bits and
1163 port status change bits.
1167 EFI_SUCCESS The status of the USB root hub port specified
1168 by PortNumber was returned in PortStatus.
1169 EFI_INVALID_PARAMETER PortNumber is invalid.
1170 EFI_DEVICE_ERROR Can't read register
1176 UINT32 PortStatusControlAddr
;
1177 UINT32 PortStatusControlReg
;
1179 UINT8 TotalPortNumber
;
1180 UINT8 Is64BitCapable
;
1182 if (PortStatus
== NULL
) {
1183 Status
= EFI_INVALID_PARAMETER
;
1194 if (PortNumber
>= TotalPortNumber
) {
1195 Status
= EFI_INVALID_PARAMETER
;
1199 HcDev
= USB2_HC_DEV_FROM_THIS (This
);
1200 PortStatusControlAddr
= (UINT32
) (PORTSC
+ (4 * PortNumber
));
1203 // Clear port status
1205 PortStatus
->PortStatus
= 0;
1206 PortStatus
->PortChangeStatus
= 0;
1208 Status
= ReadEhcOperationalReg (
1210 PortStatusControlAddr
,
1211 &PortStatusControlReg
1213 if (EFI_ERROR (Status
)) {
1214 Status
= EFI_DEVICE_ERROR
;
1219 // Fill Port Status bits
1223 // Current Connect Status
1225 if (PORTSC_CCS
& PortStatusControlReg
) {
1226 PortStatus
->PortStatus
|= USB_PORT_STAT_CONNECTION
;
1229 // Port Enabled/Disabled
1231 if (PORTSC_PED
& PortStatusControlReg
) {
1232 PortStatus
->PortStatus
|= USB_PORT_STAT_ENABLE
;
1237 if (PORTSC_SUSP
& PortStatusControlReg
) {
1238 PortStatus
->PortStatus
|= USB_PORT_STAT_SUSPEND
;
1241 // Over-current Active
1243 if (PORTSC_OCA
& PortStatusControlReg
) {
1244 PortStatus
->PortStatus
|= USB_PORT_STAT_OVERCURRENT
;
1249 if (PORTSC_PR
& PortStatusControlReg
) {
1250 PortStatus
->PortStatus
|= USB_PORT_STAT_RESET
;
1255 if (PORTSC_PP
& PortStatusControlReg
) {
1256 PortStatus
->PortStatus
|= USB_PORT_STAT_POWER
;
1261 if (PORTSC_PO
& PortStatusControlReg
) {
1262 PortStatus
->PortStatus
|= USB_PORT_STAT_OWNER
;
1265 // Identify device speed
1267 if (PORTSC_LS_KSTATE
& PortStatusControlReg
) {
1269 // Low Speed Device Attached
1271 PortStatus
->PortStatus
|= USB_PORT_STAT_LOW_SPEED
;
1274 // Not Low Speed Device Attached
1276 if ((PORTSC_CCS
& PortStatusControlReg
) && (PORTSC_CSC
& PortStatusControlReg
)) {
1277 mDeviceSpeed
[PortNumber
] = IsHighSpeedDevice (This
, PortNumber
) ? USB_PORT_STAT_HIGH_SPEED
: 0;
1279 PortStatus
->PortStatus
|= mDeviceSpeed
[PortNumber
];
1282 // Fill Port Status Change bits
1285 // Connect Status Change
1287 if (PORTSC_CSC
& PortStatusControlReg
) {
1288 PortStatus
->PortChangeStatus
|= USB_PORT_STAT_C_CONNECTION
;
1291 // Port Enabled/Disabled Change
1293 if (PORTSC_PEDC
& PortStatusControlReg
) {
1294 PortStatus
->PortChangeStatus
|= USB_PORT_STAT_C_ENABLE
;
1297 // Port Over Current Change
1299 if (PORTSC_OCC
& PortStatusControlReg
) {
1300 PortStatus
->PortChangeStatus
|= USB_PORT_STAT_C_OVERCURRENT
;
1309 EhciSetRootHubPortFeature (
1310 IN EFI_USB2_HC_PROTOCOL
*This
,
1311 IN UINT8 PortNumber
,
1312 IN EFI_USB_PORT_FEATURE PortFeature
1316 Routine Description:
1318 Sets a feature for the specified root hub port.
1322 This - A pointer to the EFI_USB2_HC_PROTOCOL.
1323 PortNumber - Specifies the root hub port whose feature
1324 is requested to be set.
1325 PortFeature - Indicates the feature selector associated
1326 with the feature set request.
1331 The feature specified by PortFeature was set for the
1332 USB root hub port specified by PortNumber.
1333 EFI_INVALID_PARAMETER
1334 PortNumber is invalid or PortFeature is invalid.
1342 UINT32 PortStatusControlAddr
;
1343 UINT32 PortStatusControlReg
;
1345 UINT8 TotalPortNumber
;
1346 UINT8 Is64BitCapable
;
1355 if (PortNumber
>= TotalPortNumber
) {
1356 Status
= EFI_INVALID_PARAMETER
;
1360 HcDev
= USB2_HC_DEV_FROM_THIS (This
);
1361 PortStatusControlAddr
= (UINT32
) (PORTSC
+ (4 * PortNumber
));
1363 Status
= ReadEhcOperationalReg (
1365 PortStatusControlAddr
,
1366 &PortStatusControlReg
1368 if (EFI_ERROR (Status
)) {
1369 Status
= EFI_DEVICE_ERROR
;
1373 switch (PortFeature
) {
1375 case EfiUsbPortEnable
:
1378 // Sofeware can't set this bit, Port can only be enable by the Host Controller
1379 // as a part of the reset and enable
1381 PortStatusControlReg
&= 0xffffffd5;
1382 PortStatusControlReg
|= PORTSC_PED
;
1385 case EfiUsbPortSuspend
:
1387 PortStatusControlReg
&= 0xffffffd5;
1388 PortStatusControlReg
|= PORTSC_SUSP
;
1391 case EfiUsbPortReset
:
1394 // Make sure Host Controller not halt before reset it
1396 if (IsEhcHalted (HcDev
)) {
1397 Status
= StartScheduleExecution (HcDev
);
1398 if (EFI_ERROR (Status
)) {
1399 Status
= EFI_DEVICE_ERROR
;
1402 Status
= WaitForEhcNotHalt (HcDev
, EHCI_GENERIC_TIMEOUT
);
1403 if (EFI_ERROR (Status
)) {
1404 DEBUG ((gEHCDebugLevel
, "WaitForEhcNotHalt TimeOut\n"));
1405 Status
= EFI_DEVICE_ERROR
;
1409 PortStatusControlReg
&= 0xffffffd5;
1410 PortStatusControlReg
|= PORTSC_PR
;
1412 // Set one to PortReset bit must also set zero to PortEnable bit
1414 PortStatusControlReg
&= ~PORTSC_PED
;
1417 case EfiUsbPortPower
:
1420 // No support, no operation
1424 case EfiUsbPortOwner
:
1426 PortStatusControlReg
&= 0xffffffd5;
1427 PortStatusControlReg
|= PORTSC_PO
;
1432 Status
= EFI_INVALID_PARAMETER
;
1436 Status
= WriteEhcOperationalReg (
1438 PortStatusControlAddr
,
1439 PortStatusControlReg
1441 if (EFI_ERROR (Status
)) {
1442 Status
= EFI_DEVICE_ERROR
;
1451 EhciClearRootHubPortFeature (
1452 IN EFI_USB2_HC_PROTOCOL
*This
,
1453 IN UINT8 PortNumber
,
1454 IN EFI_USB_PORT_FEATURE PortFeature
1458 Routine Description:
1460 Clears a feature for the specified root hub port.
1464 This - A pointer to the EFI_USB2_HC_PROTOCOL instance.
1465 PortNumber - Specifies the root hub port whose feature
1466 is requested to be cleared.
1467 PortFeature - Indicates the feature selector associated with the
1468 feature clear request.
1473 The feature specified by PortFeature was cleared for the
1474 USB root hub port specified by PortNumber.
1475 EFI_INVALID_PARAMETER
1476 PortNumber is invalid or PortFeature is invalid.
1484 UINT32 PortStatusControlAddr
;
1485 UINT32 PortStatusControlReg
;
1487 UINT8 TotalPortNumber
;
1488 UINT8 Is64BitCapable
;
1497 if (PortNumber
>= TotalPortNumber
) {
1498 Status
= EFI_INVALID_PARAMETER
;
1502 HcDev
= USB2_HC_DEV_FROM_THIS (This
);
1503 PortStatusControlAddr
= (UINT32
) (PORTSC
+ (4 * PortNumber
));
1505 Status
= ReadEhcOperationalReg (
1507 PortStatusControlAddr
,
1508 &PortStatusControlReg
1510 if (EFI_ERROR (Status
)) {
1511 Status
= EFI_DEVICE_ERROR
;
1515 switch (PortFeature
) {
1517 case EfiUsbPortEnable
:
1520 // Clear PORT_ENABLE feature means disable port.
1522 PortStatusControlReg
&= 0xffffffd5;
1523 PortStatusControlReg
&= ~PORTSC_PED
;
1526 case EfiUsbPortSuspend
:
1529 // A write of zero to this bit is ignored by the host controller.
1530 // The host controller will unconditionally set this bit to a zero when:
1531 // 1. software sets the Forct Port Resume bit to a zero from a one.
1532 // 2. software sets the Port Reset bit to a one frome a zero.
1534 PortStatusControlReg
&= 0xffffffd5;
1535 PortStatusControlReg
&= ~PORTSC_FPR
;
1538 case EfiUsbPortReset
:
1541 // Clear PORT_RESET means clear the reset signal.
1543 PortStatusControlReg
&= 0xffffffd5;
1544 PortStatusControlReg
&= ~PORTSC_PR
;
1547 case EfiUsbPortPower
:
1550 // No support, no operation
1554 case EfiUsbPortOwner
:
1557 // Clear port owner means this port owned by EHC
1559 PortStatusControlReg
&= 0xffffffd5;
1560 PortStatusControlReg
&= ~PORTSC_PO
;
1563 case EfiUsbPortConnectChange
:
1566 // Clear connect status change
1568 PortStatusControlReg
&= 0xffffffd5;
1569 PortStatusControlReg
|= PORTSC_CSC
;
1572 case EfiUsbPortEnableChange
:
1575 // Clear enable status change
1577 PortStatusControlReg
&= 0xffffffd5;
1578 PortStatusControlReg
|= PORTSC_PEDC
;
1581 case EfiUsbPortSuspendChange
:
1584 // No related bit, no operation
1588 case EfiUsbPortOverCurrentChange
:
1591 // Clear PortOverCurrent change
1593 PortStatusControlReg
&= 0xffffffd5;
1594 PortStatusControlReg
|= PORTSC_OCC
;
1597 case EfiUsbPortResetChange
:
1600 // No related bit, no operation
1606 Status
= EFI_INVALID_PARAMETER
;
1610 Status
= WriteEhcOperationalReg (
1612 PortStatusControlAddr
,
1613 PortStatusControlReg
1615 if (EFI_ERROR (Status
)) {
1616 Status
= EFI_DEVICE_ERROR
;
1626 EhciControlTransfer (
1627 IN EFI_USB2_HC_PROTOCOL
*This
,
1628 IN UINT8 DeviceAddress
,
1629 IN UINT8 DeviceSpeed
,
1630 IN UINTN MaximumPacketLength
,
1631 IN EFI_USB_DEVICE_REQUEST
*Request
,
1632 IN EFI_USB_DATA_DIRECTION TransferDirection
,
1634 IN OUT UINTN
*DataLength
,
1636 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
1637 OUT UINT32
*TransferResult
1641 Routine Description:
1643 Submits control transfer to a target USB device.
1647 This - A pointer to the EFI_USB2_HC_PROTOCOL instance.
1648 DeviceAddress - Represents the address of the target device on the USB,
1649 which is assigned during USB enumeration.
1650 DeviceSpeed - Indicates target device speed.
1651 MaximumPacketLength - Indicates the maximum packet size that the
1652 default control transfer endpoint is capable of
1653 sending or receiving.
1654 Request - A pointer to the USB device request that will be sent
1656 TransferDirection - Specifies the data direction for the transfer.
1657 There are three values available, DataIn, DataOut
1659 Data - A pointer to the buffer of data that will be transmitted
1660 to USB device or received from USB device.
1661 DataLength - Indicates the size, in bytes, of the data buffer
1663 TimeOut - Indicates the maximum time, in microseconds,
1664 which the transfer is allowed to complete.
1665 Translator - A pointr to the transaction translator data.
1666 TransferResult - A pointer to the detailed result information generated
1667 by this control transfer.
1672 The control transfer was completed successfully.
1673 EFI_OUT_OF_RESOURCES
1674 The control transfer could not be completed due to a lack of resources.
1675 EFI_INVALID_PARAMETER
1676 Some parameters are invalid.
1678 The control transfer failed due to timeout.
1680 The control transfer failed due to host controller or device error.
1681 Caller should check TranferResult for detailed error information.
1688 EHCI_QH_ENTITY
*QhPtr
;
1689 EHCI_QTD_ENTITY
*ControlQtdsPtr
;
1692 UINT8
*RequestCursor
;
1696 ControlQtdsPtr
= NULL
;
1699 RequestCursor
= NULL
;
1701 HcDev
= USB2_HC_DEV_FROM_THIS (This
);
1704 // Parameters Checking
1706 if (TransferDirection
!= EfiUsbDataIn
&&
1707 TransferDirection
!= EfiUsbDataOut
&&
1708 TransferDirection
!= EfiUsbNoData
1710 Status
= EFI_INVALID_PARAMETER
;
1714 if (EfiUsbNoData
== TransferDirection
) {
1715 if (NULL
!= Data
|| 0 != *DataLength
) {
1716 Status
= EFI_INVALID_PARAMETER
;
1720 if (NULL
== Data
|| 0 == *DataLength
) {
1721 Status
= EFI_INVALID_PARAMETER
;
1726 if (Request
== NULL
|| TransferResult
== NULL
) {
1727 Status
= EFI_INVALID_PARAMETER
;
1731 if (EFI_USB_SPEED_LOW
== DeviceSpeed
) {
1732 if (MaximumPacketLength
!= 8) {
1733 Status
= EFI_INVALID_PARAMETER
;
1736 } else if (MaximumPacketLength
!= 8 &&
1737 MaximumPacketLength
!= 16 &&
1738 MaximumPacketLength
!= 32 &&
1739 MaximumPacketLength
!= 64
1741 Status
= EFI_INVALID_PARAMETER
;
1746 // If errors exist that cause host controller halt,
1747 // then return EFI_DEVICE_ERROR.
1749 if (IsEhcHalted (HcDev
) || IsEhcSysError (HcDev
)) {
1750 ClearEhcAllStatus (HcDev
);
1751 *TransferResult
= EFI_USB_ERR_SYSTEM
;
1752 Status
= EFI_DEVICE_ERROR
;
1757 // Map the Request for bus master access.
1758 // BusMasterRead means cpu write
1760 Status
= MapRequestBuffer (
1766 if (EFI_ERROR (Status
)) {
1767 *TransferResult
= EFI_USB_ERR_SYSTEM
;
1768 Status
= EFI_DEVICE_ERROR
;
1773 // Map the source data buffer for bus master access.
1775 Status
= MapDataBuffer (
1784 if (EFI_ERROR (Status
)) {
1785 *TransferResult
= EFI_USB_ERR_SYSTEM
;
1786 Status
= EFI_DEVICE_ERROR
;
1791 // Create and init control Qh
1793 Status
= CreateControlQh (
1797 MaximumPacketLength
,
1801 if (EFI_ERROR (Status
)) {
1802 *TransferResult
= EFI_USB_ERR_SYSTEM
;
1803 Status
= EFI_OUT_OF_RESOURCES
;
1808 // Create and init control Qtds
1810 Status
= CreateControlQtds (
1819 if (EFI_ERROR (Status
)) {
1820 *TransferResult
= EFI_USB_ERR_SYSTEM
;
1821 Status
= EFI_OUT_OF_RESOURCES
;
1828 LinkQtdToQh (QhPtr
, ControlQtdsPtr
);
1830 ClearEhcAllStatus (HcDev
);
1833 // Link Qh and Qtds to Async Schedule List
1835 Status
= LinkQhToAsyncList (HcDev
, QhPtr
);
1836 if (EFI_ERROR (Status
)) {
1837 *TransferResult
= EFI_USB_ERR_SYSTEM
;
1838 Status
= EFI_DEVICE_ERROR
;
1843 // Poll Qh-Qtds execution and get result.
1844 // detail status is returned
1846 Status
= ExecuteTransfer (
1855 if (EFI_ERROR (Status
)) {
1860 // If has errors that cause host controller halt,
1861 // then return EFI_DEVICE_ERROR directly.
1863 if (IsEhcHalted (HcDev
) || IsEhcSysError (HcDev
)) {
1864 *TransferResult
|= EFI_USB_ERR_SYSTEM
;
1867 ClearEhcAllStatus (HcDev
);
1870 UnlinkQhFromAsyncList (HcDev
, QhPtr
);
1871 DestoryQtds (HcDev
, ControlQtdsPtr
);
1873 DestoryQh (HcDev
, QhPtr
);
1875 HcDev
->PciIo
->Unmap (HcDev
->PciIo
, DataMap
);
1877 HcDev
->PciIo
->Unmap (HcDev
->PciIo
, RequestMap
);
1879 HcDev
->PciIo
->Flush (HcDev
->PciIo
);
1886 IN EFI_USB2_HC_PROTOCOL
*This
,
1887 IN UINT8 DeviceAddress
,
1888 IN UINT8 EndPointAddress
,
1889 IN UINT8 DeviceSpeed
,
1890 IN UINTN MaximumPacketLength
,
1891 IN UINT8 DataBuffersNumber
,
1892 IN OUT VOID
*Data
[EFI_USB_MAX_BULK_BUFFER_NUM
],
1893 IN OUT UINTN
*DataLength
,
1894 IN OUT UINT8
*DataToggle
,
1896 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
1897 OUT UINT32
*TransferResult
1901 Routine Description:
1903 Submits bulk transfer to a bulk endpoint of a USB device.
1907 This - A pointer to the EFI_USB2_HC_PROTOCOL instance.
1908 DeviceAddress - Represents the address of the target device on the USB,
1909 which is assigned during USB enumeration.
1910 EndPointAddress - The combination of an endpoint number and an
1911 endpoint direction of the target USB device.
1912 Each endpoint address supports data transfer in
1913 one direction except the control endpoint
1914 (whose default endpoint address is 0).
1915 It is the caller's responsibility to make sure that
1916 the EndPointAddress represents a bulk endpoint.
1917 DeviceSpeed - Indicates device speed. The supported values are EFI_USB_SPEED_FULL
1918 and EFI_USB_SPEED_HIGH.
1919 MaximumPacketLength - Indicates the maximum packet size the target endpoint
1920 is capable of sending or receiving.
1921 DataBuffersNumber - Number of data buffers prepared for the transfer.
1922 Data - Array of pointers to the buffers of data that will be transmitted
1923 to USB device or received from USB device.
1924 DataLength - When input, indicates the size, in bytes, of the data buffer
1925 specified by Data. When output, indicates the actually
1926 transferred data size.
1927 DataToggle - A pointer to the data toggle value. On input, it indicates
1928 the initial data toggle value the bulk transfer should adopt;
1929 on output, it is updated to indicate the data toggle value
1930 of the subsequent bulk transfer.
1931 Translator - A pointr to the transaction translator data.
1932 TimeOut - Indicates the maximum time, in microseconds, which the
1933 transfer is allowed to complete.
1934 TransferResult - A pointer to the detailed result information of the
1940 The bulk transfer was completed successfully.
1941 EFI_OUT_OF_RESOURCES
1942 The bulk transfer could not be submitted due to lack of resource.
1943 EFI_INVALID_PARAMETER
1944 Some parameters are invalid.
1946 The bulk transfer failed due to timeout.
1948 The bulk transfer failed due to host controller or device error.
1949 Caller should check TranferResult for detailed error information.
1956 EHCI_QH_ENTITY
*QhPtr
;
1957 EHCI_QTD_ENTITY
*BulkQtdsPtr
;
1960 EFI_USB_DATA_DIRECTION TransferDirection
;
1966 HcDev
= USB2_HC_DEV_FROM_THIS (This
);
1969 // Parameters Checking
1971 if (NULL
== DataLength
||
1974 NULL
== TransferResult
1976 Status
= EFI_INVALID_PARAMETER
;
1980 if (*DataLength
== 0) {
1981 Status
= EFI_INVALID_PARAMETER
;
1985 if (1 != *DataToggle
&& 0 != *DataToggle
) {
1986 Status
= EFI_INVALID_PARAMETER
;
1990 if (EFI_USB_SPEED_LOW
== DeviceSpeed
) {
1991 Status
= EFI_INVALID_PARAMETER
;
1995 if (EFI_USB_SPEED_FULL
== DeviceSpeed
) {
1996 if (MaximumPacketLength
> 64) {
1997 Status
= EFI_INVALID_PARAMETER
;
2002 if (EFI_USB_SPEED_HIGH
== DeviceSpeed
) {
2003 if (MaximumPacketLength
> 512) {
2004 Status
= EFI_INVALID_PARAMETER
;
2010 // if has errors that cause host controller halt,
2011 // then return EFI_DEVICE_ERROR directly.
2013 if (IsEhcHalted (HcDev
) || IsEhcSysError (HcDev
)) {
2014 ClearEhcAllStatus (HcDev
);
2015 *TransferResult
= EFI_USB_ERR_SYSTEM
;
2016 Status
= EFI_DEVICE_ERROR
;
2020 Status
= ClearEhcAllStatus (HcDev
);
2021 if (EFI_ERROR (Status
)) {
2022 Status
= EFI_DEVICE_ERROR
;
2027 // construct QH and TD data structures,
2028 // and link them together
2030 if (EndPointAddress
& 0x80) {
2031 TransferDirection
= EfiUsbDataIn
;
2033 TransferDirection
= EfiUsbDataOut
;
2036 Status
= MapDataBuffer (
2045 if (EFI_ERROR (Status
)) {
2046 *TransferResult
= EFI_USB_ERR_SYSTEM
;
2047 Status
= EFI_DEVICE_ERROR
;
2052 // Create and init Bulk Qh
2054 Status
= CreateBulkQh (
2060 MaximumPacketLength
,
2064 if (EFI_ERROR (Status
)) {
2065 *TransferResult
= EFI_USB_ERR_SYSTEM
;
2066 Status
= EFI_OUT_OF_RESOURCES
;
2071 // Create and init Bulk Qtds
2073 Status
= CreateBulkOrInterruptQtds (
2081 if (EFI_ERROR (Status
)) {
2082 *TransferResult
= EFI_USB_ERR_SYSTEM
;
2083 Status
= EFI_OUT_OF_RESOURCES
;
2090 LinkQtdToQh (QhPtr
, BulkQtdsPtr
);
2092 ClearEhcAllStatus (HcDev
);
2095 // Link Qh and qtds to Async Schedule List
2097 Status
= LinkQhToAsyncList (HcDev
, QhPtr
);
2098 if (EFI_ERROR (Status
)) {
2099 *TransferResult
= EFI_USB_ERR_SYSTEM
;
2100 Status
= EFI_DEVICE_ERROR
;
2105 // Poll QH-TDs execution and get result.
2106 // detail status is returned
2108 Status
= ExecuteTransfer (
2117 if (EFI_ERROR (Status
)) {
2122 // if has errors that cause host controller halt,
2123 // then return EFI_DEVICE_ERROR directly.
2125 if (IsEhcHalted (HcDev
) || IsEhcSysError (HcDev
)) {
2126 *TransferResult
|= EFI_USB_ERR_SYSTEM
;
2129 ClearEhcAllStatus (HcDev
);
2132 UnlinkQhFromAsyncList (HcDev
, QhPtr
);
2133 DestoryQtds (HcDev
, BulkQtdsPtr
);
2135 DestoryQh (HcDev
, QhPtr
);
2137 HcDev
->PciIo
->Unmap (HcDev
->PciIo
, DataMap
);
2139 HcDev
->PciIo
->Flush (HcDev
->PciIo
);
2145 EhciAsyncInterruptTransfer (
2146 IN EFI_USB2_HC_PROTOCOL
* This
,
2147 IN UINT8 DeviceAddress
,
2148 IN UINT8 EndPointAddress
,
2149 IN UINT8 DeviceSpeed
,
2150 IN UINTN MaximumPacketLength
,
2151 IN BOOLEAN IsNewTransfer
,
2152 IN OUT UINT8
*DataToggle
,
2153 IN UINTN PollingInterval
,
2154 IN UINTN DataLength
,
2155 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
* Translator
,
2156 IN EFI_ASYNC_USB_TRANSFER_CALLBACK CallBackFunction
,
2157 IN VOID
*Context OPTIONAL
2161 Routine Description:
2163 Submits an asynchronous interrupt transfer to an
2164 interrupt endpoint of a USB device.
2165 Translator parameter doesn't exist in UEFI2.0 spec, but it will be updated
2166 in the following specification version.
2170 This - A pointer to the EFI_USB2_HC_PROTOCOL instance.
2171 DeviceAddress - Represents the address of the target device on the USB,
2172 which is assigned during USB enumeration.
2173 EndPointAddress - The combination of an endpoint number and an endpoint
2174 direction of the target USB device. Each endpoint address
2175 supports data transfer in one direction except the
2176 control endpoint (whose default endpoint address is 0).
2177 It is the caller's responsibility to make sure that
2178 the EndPointAddress represents an interrupt endpoint.
2179 DeviceSpeed - Indicates device speed.
2180 MaximumPacketLength - Indicates the maximum packet size the target endpoint
2181 is capable of sending or receiving.
2182 IsNewTransfer - If TRUE, an asynchronous interrupt pipe is built between
2183 the host and the target interrupt endpoint.
2184 If FALSE, the specified asynchronous interrupt pipe
2186 DataToggle - A pointer to the data toggle value. On input, it is valid
2187 when IsNewTransfer is TRUE, and it indicates the initial
2188 data toggle value the asynchronous interrupt transfer
2190 On output, it is valid when IsNewTransfer is FALSE,
2191 and it is updated to indicate the data toggle value of
2192 the subsequent asynchronous interrupt transfer.
2193 PollingInterval - Indicates the interval, in milliseconds, that the
2194 asynchronous interrupt transfer is polled.
2195 This parameter is required when IsNewTransfer is TRUE.
2196 DataLength - Indicates the length of data to be received at the
2197 rate specified by PollingInterval from the target
2198 asynchronous interrupt endpoint. This parameter
2199 is only required when IsNewTransfer is TRUE.
2200 Translator - A pointr to the transaction translator data.
2201 CallBackFunction - The Callback function.This function is called at the
2202 rate specified by PollingInterval.This parameter is
2203 only required when IsNewTransfer is TRUE.
2204 Context - The context that is passed to the CallBackFunction.
2205 - This is an optional parameter and may be NULL.
2210 The asynchronous interrupt transfer request has been successfully
2211 submitted or canceled.
2212 EFI_INVALID_PARAMETER
2213 Some parameters are invalid.
2214 EFI_OUT_OF_RESOURCES
2215 The request could not be completed due to a lack of resources.
2224 EHCI_QH_ENTITY
*QhPtr
;
2225 EHCI_QTD_ENTITY
*InterruptQtdsPtr
;
2230 EHCI_ASYNC_REQUEST
*AsyncRequestPtr
;
2234 InterruptQtdsPtr
= NULL
;
2238 AsyncRequestPtr
= NULL
;
2239 HcDev
= USB2_HC_DEV_FROM_THIS (This
);
2242 // Parameters Checking
2244 if (!IsDataInTransfer (EndPointAddress
)) {
2245 Status
= EFI_INVALID_PARAMETER
;
2249 if (IsNewTransfer
) {
2250 if (0 == DataLength
) {
2251 Status
= EFI_INVALID_PARAMETER
;
2255 if (*DataToggle
!= 1 && *DataToggle
!= 0) {
2256 Status
= EFI_INVALID_PARAMETER
;
2260 if (PollingInterval
> 255 || PollingInterval
< 1) {
2261 Status
= EFI_INVALID_PARAMETER
;
2267 // if has errors that cause host controller halt,
2268 // then return EFI_DEVICE_ERROR directly.
2270 if (IsEhcHalted (HcDev
) || IsEhcSysError (HcDev
)) {
2271 ClearEhcAllStatus (HcDev
);
2272 Status
= EFI_DEVICE_ERROR
;
2276 Status
= ClearEhcAllStatus (HcDev
);
2277 if (EFI_ERROR (Status
)) {
2278 Status
= EFI_DEVICE_ERROR
;
2283 // Delete Async interrupt transfer request
2285 if (!IsNewTransfer
) {
2287 OldTpl
= gBS
->RaiseTPL (EFI_TPL_NOTIFY
);
2289 Status
= DeleteAsyncRequestTransfer (
2296 gBS
->RestoreTPL (OldTpl
);
2301 Status
= EhciAllocatePool (
2303 (UINT8
**) &AsyncRequestPtr
,
2304 sizeof (EHCI_ASYNC_REQUEST
)
2306 if (EFI_ERROR (Status
)) {
2307 Status
= EFI_OUT_OF_RESOURCES
;
2311 Status
= EhciAllocatePool (HcDev
, &DataPtr
, DataLength
);
2312 if (EFI_ERROR (Status
)) {
2313 Status
= EFI_OUT_OF_RESOURCES
;
2317 MappedLength
= DataLength
;
2318 Status
= MapDataBuffer (
2327 if (EFI_ERROR (Status
)) {
2328 Status
= EFI_DEVICE_ERROR
;
2333 // Create and init Interrupt Qh
2335 Status
= CreateInterruptQh (
2341 MaximumPacketLength
,
2346 if (EFI_ERROR (Status
)) {
2347 Status
= EFI_OUT_OF_RESOURCES
;
2352 // Create and init Interrupt Qtds
2354 Status
= CreateBulkOrInterruptQtds (
2362 if (EFI_ERROR (Status
)) {
2363 Status
= EFI_OUT_OF_RESOURCES
;
2370 LinkQtdToQh (QhPtr
, InterruptQtdsPtr
);
2373 // Init AsyncRequest Entry
2375 AsyncRequestPtr
->Context
= Context
;
2376 AsyncRequestPtr
->CallBackFunc
= CallBackFunction
;
2377 AsyncRequestPtr
->TransferType
= ASYNC_INTERRUPT_TRANSFER
;
2378 AsyncRequestPtr
->QhPtr
= QhPtr
;
2379 AsyncRequestPtr
->Prev
= NULL
;
2380 AsyncRequestPtr
->Next
= NULL
;
2382 if (NULL
== HcDev
->AsyncRequestList
) {
2383 Status
= StartPollingTimer (HcDev
);
2384 if (EFI_ERROR (Status
)) {
2385 Status
= EFI_DEVICE_ERROR
;
2386 CleanUpAllAsyncRequestTransfer (HcDev
);
2392 // Link Entry to AsyncRequest List
2394 LinkToAsyncReqeust (HcDev
, AsyncRequestPtr
);
2396 ClearEhcAllStatus (HcDev
);
2398 Status
= DisablePeriodicSchedule (HcDev
);
2399 if (EFI_ERROR (Status
)) {
2400 Status
= EFI_DEVICE_ERROR
;
2404 Status
= WaitForPeriodicScheduleDisable (HcDev
, EHCI_GENERIC_TIMEOUT
);
2405 if (EFI_ERROR (Status
)) {
2406 Status
= EFI_TIMEOUT
;
2411 // Link Qh and Qtds to Periodic Schedule List
2413 LinkQhToPeriodicList (HcDev
, QhPtr
);
2415 Status
= EnablePeriodicSchedule (HcDev
);
2416 if (EFI_ERROR (Status
)) {
2417 Status
= EFI_DEVICE_ERROR
;
2421 Status
= WaitForPeriodicScheduleEnable (HcDev
, EHCI_GENERIC_TIMEOUT
);
2422 if (EFI_ERROR (Status
)) {
2423 Status
= EFI_TIMEOUT
;
2427 if (IsEhcHalted (HcDev
)) {
2428 Status
= StartScheduleExecution (HcDev
);
2429 if (EFI_ERROR (Status
)) {
2430 Status
= EFI_DEVICE_ERROR
;
2435 HcDev
->PciIo
->Flush (HcDev
->PciIo
);
2439 DestoryQh (HcDev
, QhPtr
);
2441 EhciFreePool (HcDev
, DataPtr
, DataLength
);
2445 (UINT8
*) AsyncRequestPtr
,
2446 sizeof (EHCI_ASYNC_REQUEST
)
2449 HcDev
->PciIo
->Unmap (HcDev
->PciIo
, DataMap
);
2456 EhciSyncInterruptTransfer (
2457 IN EFI_USB2_HC_PROTOCOL
*This
,
2458 IN UINT8 DeviceAddress
,
2459 IN UINT8 EndPointAddress
,
2460 IN UINT8 DeviceSpeed
,
2461 IN UINTN MaximumPacketLength
,
2463 IN OUT UINTN
*DataLength
,
2464 IN OUT UINT8
*DataToggle
,
2466 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
2467 OUT UINT32
*TransferResult
2471 Routine Description:
2473 Submits synchronous interrupt transfer to an interrupt endpoint
2475 Translator parameter doesn't exist in UEFI2.0 spec, but it will be updated
2476 in the following specification version.
2480 This - A pointer to the EFI_USB2_HC_PROTOCOL instance.
2481 DeviceAddress - Represents the address of the target device on the USB,
2482 which is assigned during USB enumeration.
2483 EndPointAddress - The combination of an endpoint number and an endpoint
2484 direction of the target USB device. Each endpoint
2485 address supports data transfer in one direction
2486 except the control endpoint (whose default
2487 endpoint address is 0). It is the caller's responsibility
2488 to make sure that the EndPointAddress represents
2489 an interrupt endpoint.
2490 DeviceSpeed - Indicates device speed.
2491 MaximumPacketLength - Indicates the maximum packet size the target endpoint
2492 is capable of sending or receiving.
2493 Data - A pointer to the buffer of data that will be transmitted
2494 to USB device or received from USB device.
2495 DataLength - On input, the size, in bytes, of the data buffer specified
2496 by Data. On output, the number of bytes transferred.
2497 DataToggle - A pointer to the data toggle value. On input, it indicates
2498 the initial data toggle value the synchronous interrupt
2499 transfer should adopt;
2500 on output, it is updated to indicate the data toggle value
2501 of the subsequent synchronous interrupt transfer.
2502 TimeOut - Indicates the maximum time, in microseconds, which the
2503 transfer is allowed to complete.
2504 Translator - A pointr to the transaction translator data.
2505 TransferResult - A pointer to the detailed result information from
2506 the synchronous interrupt transfer.
2511 The synchronous interrupt transfer was completed successfully.
2512 EFI_OUT_OF_RESOURCES
2513 The synchronous interrupt transfer could not be submitted due
2514 to lack of resource.
2515 EFI_INVALID_PARAMETER
2516 Some parameters are invalid.
2518 The synchronous interrupt transfer failed due to timeout.
2520 The synchronous interrupt transfer failed due to host controller
2521 or device error. Caller should check TranferResult for detailed
2529 EHCI_QH_ENTITY
*QhPtr
;
2530 EHCI_QTD_ENTITY
*InterruptQtdsPtr
;
2535 InterruptQtdsPtr
= NULL
;
2538 HcDev
= USB2_HC_DEV_FROM_THIS (This
);
2541 // Parameters Checking
2543 if (DataLength
== NULL
||
2545 TransferResult
== NULL
2547 Status
= EFI_INVALID_PARAMETER
;
2551 if (!IsDataInTransfer (EndPointAddress
)) {
2552 Status
= EFI_INVALID_PARAMETER
;
2556 if (0 == *DataLength
) {
2557 Status
= EFI_INVALID_PARAMETER
;
2561 if (*DataToggle
!= 1 && *DataToggle
!= 0) {
2562 Status
= EFI_INVALID_PARAMETER
;
2566 if (EFI_USB_SPEED_LOW
== DeviceSpeed
&& 8 != MaximumPacketLength
) {
2567 Status
= EFI_INVALID_PARAMETER
;
2571 if (EFI_USB_SPEED_FULL
== DeviceSpeed
&& MaximumPacketLength
> 64) {
2572 Status
= EFI_INVALID_PARAMETER
;
2576 if (EFI_USB_SPEED_HIGH
== DeviceSpeed
&& MaximumPacketLength
> 3072) {
2577 Status
= EFI_INVALID_PARAMETER
;
2582 // if has errors that cause host controller halt,
2583 // then return EFI_DEVICE_ERROR directly.
2585 if (IsEhcHalted (HcDev
) || IsEhcSysError (HcDev
)) {
2586 ClearEhcAllStatus (HcDev
);
2587 *TransferResult
= EFI_USB_ERR_SYSTEM
;
2588 Status
= EFI_DEVICE_ERROR
;
2592 Status
= ClearEhcAllStatus (HcDev
);
2593 if (EFI_ERROR (Status
)) {
2594 Status
= EFI_DEVICE_ERROR
;
2598 Status
= MapDataBuffer (
2607 if (EFI_ERROR (Status
)) {
2608 *TransferResult
= EFI_USB_ERR_SYSTEM
;
2609 Status
= EFI_DEVICE_ERROR
;
2614 // Create and init Interrupt Qh
2616 Status
= CreateInterruptQh (
2622 MaximumPacketLength
,
2627 if (EFI_ERROR (Status
)) {
2628 Status
= EFI_OUT_OF_RESOURCES
;
2633 // Create and init Interrupt Qtds
2635 Status
= CreateBulkOrInterruptQtds (
2643 if (EFI_ERROR (Status
)) {
2644 *TransferResult
= EFI_USB_ERR_SYSTEM
;
2645 Status
= EFI_OUT_OF_RESOURCES
;
2652 LinkQtdToQh (QhPtr
, InterruptQtdsPtr
);
2654 ClearEhcAllStatus (HcDev
);
2656 Status
= DisablePeriodicSchedule (HcDev
);
2657 if (EFI_ERROR (Status
)) {
2658 Status
= EFI_DEVICE_ERROR
;
2662 Status
= WaitForPeriodicScheduleDisable (HcDev
, EHCI_GENERIC_TIMEOUT
);
2663 if (EFI_ERROR (Status
)) {
2664 Status
= EFI_TIMEOUT
;
2669 // Link Qh and Qtds to Periodic Schedule List
2671 LinkQhToPeriodicList (HcDev
, QhPtr
);
2673 Status
= EnablePeriodicSchedule (HcDev
);
2674 if (EFI_ERROR (Status
)) {
2675 Status
= EFI_DEVICE_ERROR
;
2679 Status
= WaitForPeriodicScheduleEnable (HcDev
, EHCI_GENERIC_TIMEOUT
);
2680 if (EFI_ERROR (Status
)) {
2681 Status
= EFI_TIMEOUT
;
2685 if (IsEhcHalted (HcDev
)) {
2686 Status
= StartScheduleExecution (HcDev
);
2687 if (EFI_ERROR (Status
)) {
2688 Status
= EFI_DEVICE_ERROR
;
2694 // Poll QH-TDs execution and get result.
2695 // detail status is returned
2697 Status
= ExecuteTransfer (
2706 if (EFI_ERROR (Status
)) {
2711 // if has errors that cause host controller halt,
2712 // then return EFI_DEVICE_ERROR directly.
2714 if (IsEhcHalted (HcDev
) || IsEhcSysError (HcDev
)) {
2715 *TransferResult
|= EFI_USB_ERR_SYSTEM
;
2718 ClearEhcAllStatus (HcDev
);
2721 UnlinkQhFromPeriodicList (HcDev
, QhPtr
, 0);
2722 DestoryQtds (HcDev
, InterruptQtdsPtr
);
2724 DestoryQh (HcDev
, QhPtr
);
2726 HcDev
->PciIo
->Unmap (HcDev
->PciIo
, DataMap
);
2728 HcDev
->PciIo
->Flush (HcDev
->PciIo
);
2734 EhciIsochronousTransfer (
2735 IN EFI_USB2_HC_PROTOCOL
*This
,
2736 IN UINT8 DeviceAddress
,
2737 IN UINT8 EndPointAddress
,
2738 IN UINT8 DeviceSpeed
,
2739 IN UINTN MaximumPacketLength
,
2740 IN UINT8 DataBuffersNumber
,
2741 IN OUT VOID
*Data
[EFI_USB_MAX_ISO_BUFFER_NUM
],
2742 IN UINTN DataLength
,
2743 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
2744 OUT UINT32
*TransferResult
2748 Routine Description:
2750 Submits isochronous transfer to a target USB device.
2754 This - A pointer to the EFI_USB2_HC_PROTOCOL instance.
2755 DeviceAddress - Represents the address of the target device on the USB,
2756 which is assigned during USB enumeration.
2757 EndPointAddress - End point address
2758 DeviceSpeed - Indicates device speed.
2759 MaximumPacketLength - Indicates the maximum packet size that the
2760 default control transfer endpoint is capable of
2761 sending or receiving.
2762 DataBuffersNumber - Number of data buffers prepared for the transfer.
2763 Data - Array of pointers to the buffers of data that will be
2764 transmitted to USB device or received from USB device.
2765 DataLength - Indicates the size, in bytes, of the data buffer
2767 Translator - A pointr to the transaction translator data.
2768 TransferResult - A pointer to the detailed result information generated
2769 by this control transfer.
2777 return EFI_UNSUPPORTED
;
2782 EhciAsyncIsochronousTransfer (
2783 IN EFI_USB2_HC_PROTOCOL
*This
,
2784 IN UINT8 DeviceAddress
,
2785 IN UINT8 EndPointAddress
,
2786 IN UINT8 DeviceSpeed
,
2787 IN UINTN MaximumPacketLength
,
2788 IN UINT8 DataBuffersNumber
,
2789 IN OUT VOID
*Data
[EFI_USB_MAX_ISO_BUFFER_NUM
],
2790 IN UINTN DataLength
,
2791 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
2792 IN EFI_ASYNC_USB_TRANSFER_CALLBACK IsochronousCallBack
,
2797 Routine Description:
2799 Submits Async isochronous transfer to a target USB device.
2803 This - A pointer to the EFI_USB2_HC_PROTOCOL instance.
2804 DeviceAddress - Represents the address of the target device on the USB,
2805 which is assigned during USB enumeration.
2806 EndPointAddress - End point address
2807 DeviceSpeed - Indicates device speed.
2808 MaximumPacketLength - Indicates the maximum packet size that the
2809 default control transfer endpoint is capable of
2810 sending or receiving.
2811 DataBuffersNumber - Number of data buffers prepared for the transfer.
2812 Data - Array of pointers to the buffers of data that will be transmitted
2813 to USB device or received from USB device.
2814 Translator - A pointr to the transaction translator data.
2815 IsochronousCallBack - When the transfer complete, the call back function will be called
2816 Context - Pass to the call back function as parameter
2824 return EFI_UNSUPPORTED
;