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
, 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 (UINT32
) 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.
2168 This - A pointer to the EFI_USB2_HC_PROTOCOL instance.
2169 DeviceAddress - Represents the address of the target device on the USB,
2170 which is assigned during USB enumeration.
2171 EndPointAddress - The combination of an endpoint number and an endpoint
2172 direction of the target USB device. Each endpoint address
2173 supports data transfer in one direction except the
2174 control endpoint (whose default endpoint address is 0).
2175 It is the caller's responsibility to make sure that
2176 the EndPointAddress represents an interrupt endpoint.
2177 DeviceSpeed - Indicates device speed.
2178 MaximumPacketLength - Indicates the maximum packet size the target endpoint
2179 is capable of sending or receiving.
2180 IsNewTransfer - If TRUE, an asynchronous interrupt pipe is built between
2181 the host and the target interrupt endpoint.
2182 If FALSE, the specified asynchronous interrupt pipe
2184 DataToggle - A pointer to the data toggle value. On input, it is valid
2185 when IsNewTransfer is TRUE, and it indicates the initial
2186 data toggle value the asynchronous interrupt transfer
2188 On output, it is valid when IsNewTransfer is FALSE,
2189 and it is updated to indicate the data toggle value of
2190 the subsequent asynchronous interrupt transfer.
2191 PollingInterval - Indicates the interval, in milliseconds, that the
2192 asynchronous interrupt transfer is polled.
2193 This parameter is required when IsNewTransfer is TRUE.
2194 DataLength - Indicates the length of data to be received at the
2195 rate specified by PollingInterval from the target
2196 asynchronous interrupt endpoint. This parameter
2197 is only required when IsNewTransfer is TRUE.
2198 Translator - A pointr to the transaction translator data.
2199 CallBackFunction - The Callback function.This function is called at the
2200 rate specified by PollingInterval.This parameter is
2201 only required when IsNewTransfer is TRUE.
2202 Context - The context that is passed to the CallBackFunction.
2203 - This is an optional parameter and may be NULL.
2208 The asynchronous interrupt transfer request has been successfully
2209 submitted or canceled.
2210 EFI_INVALID_PARAMETER
2211 Some parameters are invalid.
2212 EFI_OUT_OF_RESOURCES
2213 The request could not be completed due to a lack of resources.
2222 EHCI_QH_ENTITY
*QhPtr
;
2223 EHCI_QTD_ENTITY
*InterruptQtdsPtr
;
2228 EHCI_ASYNC_REQUEST
*AsyncRequestPtr
;
2232 InterruptQtdsPtr
= NULL
;
2236 AsyncRequestPtr
= NULL
;
2237 HcDev
= USB2_HC_DEV_FROM_THIS (This
);
2240 // Parameters Checking
2242 if (!IsDataInTransfer (EndPointAddress
)) {
2243 Status
= EFI_INVALID_PARAMETER
;
2247 if (IsNewTransfer
) {
2248 if (0 == DataLength
) {
2249 Status
= EFI_INVALID_PARAMETER
;
2253 if (*DataToggle
!= 1 && *DataToggle
!= 0) {
2254 Status
= EFI_INVALID_PARAMETER
;
2258 if (PollingInterval
> 255 || PollingInterval
< 1) {
2259 Status
= EFI_INVALID_PARAMETER
;
2265 // if has errors that cause host controller halt,
2266 // then return EFI_DEVICE_ERROR directly.
2268 if (IsEhcHalted (HcDev
) || IsEhcSysError (HcDev
)) {
2269 ClearEhcAllStatus (HcDev
);
2270 Status
= EFI_DEVICE_ERROR
;
2274 Status
= ClearEhcAllStatus (HcDev
);
2275 if (EFI_ERROR (Status
)) {
2276 Status
= EFI_DEVICE_ERROR
;
2281 // Delete Async interrupt transfer request
2283 if (!IsNewTransfer
) {
2285 OldTpl
= gBS
->RaiseTPL (EFI_TPL_NOTIFY
);
2287 Status
= DeleteAsyncRequestTransfer (
2294 gBS
->RestoreTPL (OldTpl
);
2299 Status
= EhciAllocatePool (
2301 (UINT8
**) &AsyncRequestPtr
,
2302 sizeof (EHCI_ASYNC_REQUEST
)
2304 if (EFI_ERROR (Status
)) {
2305 Status
= EFI_OUT_OF_RESOURCES
;
2309 Status
= EhciAllocatePool (HcDev
, &DataPtr
, DataLength
);
2310 if (EFI_ERROR (Status
)) {
2311 Status
= EFI_OUT_OF_RESOURCES
;
2315 MappedLength
= DataLength
;
2316 Status
= MapDataBuffer (
2325 if (EFI_ERROR (Status
)) {
2326 Status
= EFI_DEVICE_ERROR
;
2331 // Create and init Interrupt Qh
2333 Status
= CreateInterruptQh (
2339 MaximumPacketLength
,
2344 if (EFI_ERROR (Status
)) {
2345 Status
= EFI_OUT_OF_RESOURCES
;
2350 // Create and init Interrupt Qtds
2352 Status
= CreateBulkOrInterruptQtds (
2360 if (EFI_ERROR (Status
)) {
2361 Status
= EFI_OUT_OF_RESOURCES
;
2368 LinkQtdToQh (QhPtr
, InterruptQtdsPtr
);
2371 // Init AsyncRequest Entry
2373 AsyncRequestPtr
->Context
= Context
;
2374 AsyncRequestPtr
->CallBackFunc
= CallBackFunction
;
2375 AsyncRequestPtr
->TransferType
= ASYNC_INTERRUPT_TRANSFER
;
2376 AsyncRequestPtr
->QhPtr
= QhPtr
;
2377 AsyncRequestPtr
->Prev
= NULL
;
2378 AsyncRequestPtr
->Next
= NULL
;
2380 if (NULL
== HcDev
->AsyncRequestList
) {
2381 Status
= StartPollingTimer (HcDev
);
2382 if (EFI_ERROR (Status
)) {
2383 Status
= EFI_DEVICE_ERROR
;
2384 CleanUpAllAsyncRequestTransfer (HcDev
);
2390 // Link Entry to AsyncRequest List
2392 LinkToAsyncReqeust (HcDev
, AsyncRequestPtr
);
2394 ClearEhcAllStatus (HcDev
);
2396 Status
= DisablePeriodicSchedule (HcDev
);
2397 if (EFI_ERROR (Status
)) {
2398 Status
= EFI_DEVICE_ERROR
;
2402 Status
= WaitForPeriodicScheduleDisable (HcDev
, EHCI_GENERIC_TIMEOUT
);
2403 if (EFI_ERROR (Status
)) {
2404 Status
= EFI_TIMEOUT
;
2409 // Link Qh and Qtds to Periodic Schedule List
2411 LinkQhToPeriodicList (HcDev
, QhPtr
);
2413 Status
= EnablePeriodicSchedule (HcDev
);
2414 if (EFI_ERROR (Status
)) {
2415 Status
= EFI_DEVICE_ERROR
;
2419 Status
= WaitForPeriodicScheduleEnable (HcDev
, EHCI_GENERIC_TIMEOUT
);
2420 if (EFI_ERROR (Status
)) {
2421 Status
= EFI_TIMEOUT
;
2425 if (IsEhcHalted (HcDev
)) {
2426 Status
= StartScheduleExecution (HcDev
);
2427 if (EFI_ERROR (Status
)) {
2428 Status
= EFI_DEVICE_ERROR
;
2433 HcDev
->PciIo
->Flush (HcDev
->PciIo
);
2437 DestoryQh (HcDev
, QhPtr
);
2439 EhciFreePool (HcDev
, DataPtr
, DataLength
);
2443 (UINT8
*) AsyncRequestPtr
,
2444 sizeof (EHCI_ASYNC_REQUEST
)
2447 HcDev
->PciIo
->Unmap (HcDev
->PciIo
, DataMap
);
2454 EhciSyncInterruptTransfer (
2455 IN EFI_USB2_HC_PROTOCOL
*This
,
2456 IN UINT8 DeviceAddress
,
2457 IN UINT8 EndPointAddress
,
2458 IN UINT8 DeviceSpeed
,
2459 IN UINTN MaximumPacketLength
,
2461 IN OUT UINTN
*DataLength
,
2462 IN OUT UINT8
*DataToggle
,
2464 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
2465 OUT UINT32
*TransferResult
2469 Routine Description:
2471 Submits synchronous interrupt transfer to an interrupt endpoint
2476 This - A pointer to the EFI_USB2_HC_PROTOCOL instance.
2477 DeviceAddress - Represents the address of the target device on the USB,
2478 which is assigned during USB enumeration.
2479 EndPointAddress - The combination of an endpoint number and an endpoint
2480 direction of the target USB device. Each endpoint
2481 address supports data transfer in one direction
2482 except the control endpoint (whose default
2483 endpoint address is 0). It is the caller's responsibility
2484 to make sure that the EndPointAddress represents
2485 an interrupt endpoint.
2486 DeviceSpeed - Indicates device speed.
2487 MaximumPacketLength - Indicates the maximum packet size the target endpoint
2488 is capable of sending or receiving.
2489 Data - A pointer to the buffer of data that will be transmitted
2490 to USB device or received from USB device.
2491 DataLength - On input, the size, in bytes, of the data buffer specified
2492 by Data. On output, the number of bytes transferred.
2493 DataToggle - A pointer to the data toggle value. On input, it indicates
2494 the initial data toggle value the synchronous interrupt
2495 transfer should adopt;
2496 on output, it is updated to indicate the data toggle value
2497 of the subsequent synchronous interrupt transfer.
2498 TimeOut - Indicates the maximum time, in microseconds, which the
2499 transfer is allowed to complete.
2500 Translator - A pointr to the transaction translator data.
2501 TransferResult - A pointer to the detailed result information from
2502 the synchronous interrupt transfer.
2507 The synchronous interrupt transfer was completed successfully.
2508 EFI_OUT_OF_RESOURCES
2509 The synchronous interrupt transfer could not be submitted due
2510 to lack of resource.
2511 EFI_INVALID_PARAMETER
2512 Some parameters are invalid.
2514 The synchronous interrupt transfer failed due to timeout.
2516 The synchronous interrupt transfer failed due to host controller
2517 or device error. Caller should check TranferResult for detailed
2525 EHCI_QH_ENTITY
*QhPtr
;
2526 EHCI_QTD_ENTITY
*InterruptQtdsPtr
;
2531 InterruptQtdsPtr
= NULL
;
2534 HcDev
= USB2_HC_DEV_FROM_THIS (This
);
2537 // Parameters Checking
2539 if (DataLength
== NULL
||
2541 TransferResult
== NULL
2543 Status
= EFI_INVALID_PARAMETER
;
2547 if (!IsDataInTransfer (EndPointAddress
)) {
2548 Status
= EFI_INVALID_PARAMETER
;
2552 if (0 == *DataLength
) {
2553 Status
= EFI_INVALID_PARAMETER
;
2557 if (*DataToggle
!= 1 && *DataToggle
!= 0) {
2558 Status
= EFI_INVALID_PARAMETER
;
2562 if (EFI_USB_SPEED_LOW
== DeviceSpeed
&& 8 != MaximumPacketLength
) {
2563 Status
= EFI_INVALID_PARAMETER
;
2567 if (EFI_USB_SPEED_FULL
== DeviceSpeed
&& MaximumPacketLength
> 64) {
2568 Status
= EFI_INVALID_PARAMETER
;
2572 if (EFI_USB_SPEED_HIGH
== DeviceSpeed
&& MaximumPacketLength
> 3072) {
2573 Status
= EFI_INVALID_PARAMETER
;
2578 // if has errors that cause host controller halt,
2579 // then return EFI_DEVICE_ERROR directly.
2581 if (IsEhcHalted (HcDev
) || IsEhcSysError (HcDev
)) {
2582 ClearEhcAllStatus (HcDev
);
2583 *TransferResult
= EFI_USB_ERR_SYSTEM
;
2584 Status
= EFI_DEVICE_ERROR
;
2588 Status
= ClearEhcAllStatus (HcDev
);
2589 if (EFI_ERROR (Status
)) {
2590 Status
= EFI_DEVICE_ERROR
;
2594 Status
= MapDataBuffer (
2603 if (EFI_ERROR (Status
)) {
2604 *TransferResult
= EFI_USB_ERR_SYSTEM
;
2605 Status
= EFI_DEVICE_ERROR
;
2610 // Create and init Interrupt Qh
2612 Status
= CreateInterruptQh (
2618 MaximumPacketLength
,
2623 if (EFI_ERROR (Status
)) {
2624 Status
= EFI_OUT_OF_RESOURCES
;
2629 // Create and init Interrupt Qtds
2631 Status
= CreateBulkOrInterruptQtds (
2639 if (EFI_ERROR (Status
)) {
2640 *TransferResult
= EFI_USB_ERR_SYSTEM
;
2641 Status
= EFI_OUT_OF_RESOURCES
;
2648 LinkQtdToQh (QhPtr
, InterruptQtdsPtr
);
2650 ClearEhcAllStatus (HcDev
);
2652 Status
= DisablePeriodicSchedule (HcDev
);
2653 if (EFI_ERROR (Status
)) {
2654 Status
= EFI_DEVICE_ERROR
;
2658 Status
= WaitForPeriodicScheduleDisable (HcDev
, EHCI_GENERIC_TIMEOUT
);
2659 if (EFI_ERROR (Status
)) {
2660 Status
= EFI_TIMEOUT
;
2665 // Link Qh and Qtds to Periodic Schedule List
2667 LinkQhToPeriodicList (HcDev
, QhPtr
);
2669 Status
= EnablePeriodicSchedule (HcDev
);
2670 if (EFI_ERROR (Status
)) {
2671 Status
= EFI_DEVICE_ERROR
;
2675 Status
= WaitForPeriodicScheduleEnable (HcDev
, EHCI_GENERIC_TIMEOUT
);
2676 if (EFI_ERROR (Status
)) {
2677 Status
= EFI_TIMEOUT
;
2681 if (IsEhcHalted (HcDev
)) {
2682 Status
= StartScheduleExecution (HcDev
);
2683 if (EFI_ERROR (Status
)) {
2684 Status
= EFI_DEVICE_ERROR
;
2690 // Poll QH-TDs execution and get result.
2691 // detail status is returned
2693 Status
= ExecuteTransfer (
2702 if (EFI_ERROR (Status
)) {
2707 // if has errors that cause host controller halt,
2708 // then return EFI_DEVICE_ERROR directly.
2710 if (IsEhcHalted (HcDev
) || IsEhcSysError (HcDev
)) {
2711 *TransferResult
|= EFI_USB_ERR_SYSTEM
;
2714 ClearEhcAllStatus (HcDev
);
2717 UnlinkQhFromPeriodicList (HcDev
, QhPtr
, 0);
2718 DestoryQtds (HcDev
, InterruptQtdsPtr
);
2720 DestoryQh (HcDev
, QhPtr
);
2722 HcDev
->PciIo
->Unmap (HcDev
->PciIo
, DataMap
);
2724 HcDev
->PciIo
->Flush (HcDev
->PciIo
);
2730 EhciIsochronousTransfer (
2731 IN EFI_USB2_HC_PROTOCOL
*This
,
2732 IN UINT8 DeviceAddress
,
2733 IN UINT8 EndPointAddress
,
2734 IN UINT8 DeviceSpeed
,
2735 IN UINTN MaximumPacketLength
,
2736 IN UINT8 DataBuffersNumber
,
2737 IN OUT VOID
*Data
[EFI_USB_MAX_ISO_BUFFER_NUM
],
2738 IN UINTN DataLength
,
2739 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
2740 OUT UINT32
*TransferResult
2744 Routine Description:
2746 Submits isochronous transfer to a target USB device.
2750 This - A pointer to the EFI_USB2_HC_PROTOCOL instance.
2751 DeviceAddress - Represents the address of the target device on the USB,
2752 which is assigned during USB enumeration.
2753 EndPointAddress - End point address
2754 DeviceSpeed - Indicates device speed.
2755 MaximumPacketLength - Indicates the maximum packet size that the
2756 default control transfer endpoint is capable of
2757 sending or receiving.
2758 DataBuffersNumber - Number of data buffers prepared for the transfer.
2759 Data - Array of pointers to the buffers of data that will be
2760 transmitted to USB device or received from USB device.
2761 DataLength - Indicates the size, in bytes, of the data buffer
2763 Translator - A pointr to the transaction translator data.
2764 TransferResult - A pointer to the detailed result information generated
2765 by this control transfer.
2773 return EFI_UNSUPPORTED
;
2778 EhciAsyncIsochronousTransfer (
2779 IN EFI_USB2_HC_PROTOCOL
*This
,
2780 IN UINT8 DeviceAddress
,
2781 IN UINT8 EndPointAddress
,
2782 IN UINT8 DeviceSpeed
,
2783 IN UINTN MaximumPacketLength
,
2784 IN UINT8 DataBuffersNumber
,
2785 IN OUT VOID
*Data
[EFI_USB_MAX_ISO_BUFFER_NUM
],
2786 IN UINTN DataLength
,
2787 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
2788 IN EFI_ASYNC_USB_TRANSFER_CALLBACK IsochronousCallBack
,
2793 Routine Description:
2795 Submits Async isochronous transfer to a target USB device.
2799 This - A pointer to the EFI_USB2_HC_PROTOCOL instance.
2800 DeviceAddress - Represents the address of the target device on the USB,
2801 which is assigned during USB enumeration.
2802 EndPointAddress - End point address
2803 DeviceSpeed - Indicates device speed.
2804 MaximumPacketLength - Indicates the maximum packet size that the
2805 default control transfer endpoint is capable of
2806 sending or receiving.
2807 DataBuffersNumber - Number of data buffers prepared for the transfer.
2808 Data - Array of pointers to the buffers of data that will be transmitted
2809 to USB device or received from USB device.
2810 Translator - A pointr to the transaction translator data.
2811 IsochronousCallBack - When the transfer complete, the call back function will be called
2812 Context - Pass to the call back function as parameter
2820 return EFI_UNSUPPORTED
;