3 Copyright (c) 2006, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
26 GLOBAL_REMOVE_IF_UNREFERENCED UINTN gEHCDebugLevel
= EFI_D_INFO
;
27 GLOBAL_REMOVE_IF_UNREFERENCED UINTN gEHCErrorLevel
= EFI_D_ERROR
;
32 // Driver model protocol interface
37 EhciDriverBindingSupported (
38 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
39 IN EFI_HANDLE Controller
,
40 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
45 EhciDriverBindingStart (
46 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
47 IN EFI_HANDLE Controller
,
48 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
53 EhciDriverBindingStop (
54 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
55 IN EFI_HANDLE Controller
,
56 IN UINTN NumberOfChildren
,
57 IN EFI_HANDLE
*ChildHandleBuffer
61 // Ehci protocol interface
66 IN EFI_USB2_HC_PROTOCOL
*This
,
68 OUT UINT8
*PortNumber
,
69 OUT UINT8
*Is64BitCapable
75 IN EFI_USB2_HC_PROTOCOL
*This
,
82 IN EFI_USB2_HC_PROTOCOL
*This
,
83 OUT EFI_USB_HC_STATE
*State
89 IN EFI_USB2_HC_PROTOCOL
*This
,
90 IN EFI_USB_HC_STATE State
96 IN EFI_USB2_HC_PROTOCOL
*This
,
97 IN UINT8 DeviceAddress
,
99 IN UINTN MaximumPacketLength
,
100 IN EFI_USB_DEVICE_REQUEST
*Request
,
101 IN EFI_USB_DATA_DIRECTION TransferDirection
,
103 IN OUT UINTN
*DataLength
,
105 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
106 OUT UINT32
*TransferResult
112 IN EFI_USB2_HC_PROTOCOL
*This
,
113 IN UINT8 DeviceAddress
,
114 IN UINT8 EndPointAddress
,
115 IN UINT8 DeviceSpeed
,
116 IN UINTN MaximumPacketLength
,
117 IN UINT8 DataBuffersNumber
,
118 IN OUT VOID
*Data
[EFI_USB_MAX_BULK_BUFFER_NUM
],
119 IN OUT UINTN
*DataLength
,
120 IN OUT UINT8
*DataToggle
,
122 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
123 OUT UINT32
*TransferResult
128 EhciAsyncInterruptTransfer (
129 IN EFI_USB2_HC_PROTOCOL
* This
,
130 IN UINT8 DeviceAddress
,
131 IN UINT8 EndPointAddress
,
132 IN UINT8 DeviceSpeed
,
133 IN UINTN MaxiumPacketLength
,
134 IN BOOLEAN IsNewTransfer
,
135 IN OUT UINT8
*DataToggle
,
136 IN UINTN PollingInterval
,
138 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
139 IN EFI_ASYNC_USB_TRANSFER_CALLBACK CallBackFunction
,
140 IN VOID
*Context OPTIONAL
145 EhciSyncInterruptTransfer (
146 IN EFI_USB2_HC_PROTOCOL
*This
,
147 IN UINT8 DeviceAddress
,
148 IN UINT8 EndPointAddress
,
149 IN UINT8 DeviceSpeed
,
150 IN UINTN MaximumPacketLength
,
152 IN OUT UINTN
*DataLength
,
153 IN OUT UINT8
*DataToggle
,
155 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
156 OUT UINT32
*TransferResult
161 EhciIsochronousTransfer (
162 IN EFI_USB2_HC_PROTOCOL
*This
,
163 IN UINT8 DeviceAddress
,
164 IN UINT8 EndPointAddress
,
165 IN UINT8 DeviceSpeed
,
166 IN UINTN MaximumPacketLength
,
167 IN UINT8 DataBuffersNumber
,
168 IN OUT VOID
*Data
[EFI_USB_MAX_ISO_BUFFER_NUM
],
170 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
171 OUT UINT32
*TransferResult
176 EhciAsyncIsochronousTransfer (
177 IN EFI_USB2_HC_PROTOCOL
*This
,
178 IN UINT8 DeviceAddress
,
179 IN UINT8 EndPointAddress
,
180 IN UINT8 DeviceSpeed
,
181 IN UINTN MaximumPacketLength
,
182 IN UINT8 DataBuffersNumber
,
183 IN OUT VOID
*Data
[EFI_USB_MAX_ISO_BUFFER_NUM
],
185 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
186 IN EFI_ASYNC_USB_TRANSFER_CALLBACK IsochronousCallBack
,
192 EhciGetRootHubPortStatus (
193 IN EFI_USB2_HC_PROTOCOL
*This
,
195 OUT EFI_USB_PORT_STATUS
*PortStatus
200 EhciSetRootHubPortFeature (
201 IN EFI_USB2_HC_PROTOCOL
*This
,
203 IN EFI_USB_PORT_FEATURE PortFeature
208 EhciClearRootHubPortFeature (
209 IN EFI_USB2_HC_PROTOCOL
*This
,
211 IN EFI_USB_PORT_FEATURE PortFeature
215 // Ehci Driver Global Variables
217 EFI_DRIVER_BINDING_PROTOCOL gEhciDriverBinding
= {
218 EhciDriverBindingSupported
,
219 EhciDriverBindingStart
,
220 EhciDriverBindingStop
,
226 UINT32 mUsbCapabilityLen
;
227 UINT32 mDeviceSpeed
[16];
231 EhciDriverBindingSupported (
232 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
233 IN EFI_HANDLE Controller
,
234 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
240 Test to see if this driver supports ControllerHandle. Any ControllerHandle
241 that has Usb2HcProtocol installed will be supported.
245 This - Protocol instance pointer.
246 Controlle - Handle of device to test
247 RemainingDevicePath - Not used
251 EFI_SUCCESS This driver supports this device.
252 EFI_UNSUPPORTED This driver does not support this device.
257 EFI_PCI_IO_PROTOCOL
*PciIo
;
258 USB_CLASSC UsbClassCReg
;
262 // Test whether there is PCI IO Protocol attached on the controller handle.
264 Status
= gBS
->OpenProtocol (
266 &gEfiPciIoProtocolGuid
,
268 This
->DriverBindingHandle
,
270 EFI_OPEN_PROTOCOL_BY_DRIVER
272 if (EFI_ERROR (Status
)) {
276 Status
= PciIo
->Pci
.Read (
280 sizeof (USB_CLASSC
) / sizeof (UINT8
),
283 if (EFI_ERROR (Status
)) {
286 &gEfiPciIoProtocolGuid
,
287 This
->DriverBindingHandle
,
290 Status
= EFI_UNSUPPORTED
;
295 // Test whether the controller belongs to Ehci type
297 if ((UsbClassCReg
.BaseCode
!= PCI_CLASS_SERIAL
) ||
298 (UsbClassCReg
.SubClassCode
!= PCI_CLASS_SERIAL_USB
) ||
299 (UsbClassCReg
.PI
!= PCI_CLASSC_PI_EHCI
)
304 &gEfiPciIoProtocolGuid
,
305 This
->DriverBindingHandle
,
309 Status
= EFI_UNSUPPORTED
;
315 &gEfiPciIoProtocolGuid
,
316 This
->DriverBindingHandle
,
326 EhciDriverBindingStart (
327 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
328 IN EFI_HANDLE Controller
,
329 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
335 Starting the Usb EHCI Driver
339 This - Protocol instance pointer.
340 Controller - Handle of device to test
341 RemainingDevicePath - Not used
345 EFI_SUCCESS supports this device.
346 EFI_UNSUPPORTED do not support this device.
347 EFI_DEVICE_ERROR cannot be started due to device Error
348 EFI_OUT_OF_RESOURCES cannot allocate resources
354 EFI_PCI_IO_PROTOCOL
*PciIo
;
357 UINT8 Is64BitCapable
;
360 // Open the PciIo Protocol
362 Status
= gBS
->OpenProtocol (
364 &gEfiPciIoProtocolGuid
,
366 This
->DriverBindingHandle
,
368 EFI_OPEN_PROTOCOL_BY_DRIVER
370 if (EFI_ERROR (Status
)) {
371 Status
= EFI_OUT_OF_RESOURCES
;
376 // Enable the USB Host Controller
378 Status
= PciIo
->Attributes (
380 EfiPciIoAttributeOperationEnable
,
381 EFI_PCI_DEVICE_ENABLE
,
384 if (EFI_ERROR (Status
)) {
385 Status
= EFI_OUT_OF_RESOURCES
;
386 goto close_pciio_protocol
;
390 // Allocate memory for EHC private data structure
392 HcDev
= AllocateZeroPool (sizeof (USB2_HC_DEV
));
394 Status
= EFI_OUT_OF_RESOURCES
;
395 goto close_pciio_protocol
;
399 // Init EFI_USB2_HC_PROTOCOL interface and private data structure
401 HcDev
->Usb2Hc
.GetCapability
= EhciGetCapability
;
402 HcDev
->Usb2Hc
.Reset
= EhciReset
;
403 HcDev
->Usb2Hc
.GetState
= EhciGetState
;
404 HcDev
->Usb2Hc
.SetState
= EhciSetState
;
405 HcDev
->Usb2Hc
.ControlTransfer
= EhciControlTransfer
;
406 HcDev
->Usb2Hc
.BulkTransfer
= EhciBulkTransfer
;
407 HcDev
->Usb2Hc
.AsyncInterruptTransfer
= EhciAsyncInterruptTransfer
;
408 HcDev
->Usb2Hc
.SyncInterruptTransfer
= EhciSyncInterruptTransfer
;
409 HcDev
->Usb2Hc
.IsochronousTransfer
= EhciIsochronousTransfer
;
410 HcDev
->Usb2Hc
.AsyncIsochronousTransfer
= EhciAsyncIsochronousTransfer
;
411 HcDev
->Usb2Hc
.GetRootHubPortStatus
= EhciGetRootHubPortStatus
;
412 HcDev
->Usb2Hc
.SetRootHubPortFeature
= EhciSetRootHubPortFeature
;
413 HcDev
->Usb2Hc
.ClearRootHubPortFeature
= EhciClearRootHubPortFeature
;
414 HcDev
->Usb2Hc
.MajorRevision
= 0x1;
415 HcDev
->Usb2Hc
.MinorRevision
= 0x1;
417 HcDev
->AsyncRequestList
= NULL
;
418 HcDev
->ControllerNameTable
= NULL
;
419 HcDev
->Signature
= USB2_HC_DEV_SIGNATURE
;
420 HcDev
->PciIo
= PciIo
;
423 // Install USB2_HC_PROTOCOL
425 Status
= gBS
->InstallProtocolInterface (
427 &gEfiUsb2HcProtocolGuid
,
428 EFI_NATIVE_INTERFACE
,
431 if (EFI_ERROR (Status
)) {
432 Status
= EFI_OUT_OF_RESOURCES
;
437 // Get Capability Register Length
439 Status
= GetCapabilityLen (HcDev
);
440 if (EFI_ERROR (Status
)) {
441 Status
= EFI_DEVICE_ERROR
;
442 goto uninstall_usb2hc_protocol
;
445 ClearLegacySupport (HcDev
);
449 DumpEHCIPortsStatus (HcDev
);
453 // Create and Init Perodic Frame List
455 Status
= EhciGetCapability (
461 if (EFI_ERROR (Status
)) {
462 Status
= EFI_OUT_OF_RESOURCES
;
463 goto uninstall_usb2hc_protocol
;
465 HcDev
->Is64BitCapable
= Is64BitCapable
;
468 // Create and Init Perodic Frame List
470 Status
= InitialPeriodicFrameList (
472 EHCI_MAX_FRAME_LIST_LENGTH
474 if (EFI_ERROR (Status
)) {
475 Status
= EFI_OUT_OF_RESOURCES
;
476 goto uninstall_usb2hc_protocol
;
480 // Init memory pool management
482 Status
= InitialMemoryManagement (HcDev
);
483 if (EFI_ERROR (Status
)) {
484 Status
= EFI_OUT_OF_RESOURCES
;
485 goto deinit_perodic_frame_list
;
489 // Create AsyncRequest Polling Timer
491 Status
= CreatePollingTimer (HcDev
, (EFI_EVENT_NOTIFY
) AsyncRequestMoniter
);
492 if (EFI_ERROR (Status
)) {
493 Status
= EFI_OUT_OF_RESOURCES
;
494 goto deinit_memory_management
;
498 // Default Maxximum Interrupt Interval is 8,
499 // it means that 8 micro frame = 1ms
503 // Start the Host Controller
505 if (IsEhcHalted (HcDev
)) {
506 Status
= StartScheduleExecution (HcDev
);
507 if (EFI_ERROR (Status
)) {
508 Status
= EFI_DEVICE_ERROR
;
514 // Set all ports routing to EHC
516 Status
= SetPortRoutingEhc (HcDev
);
517 if (EFI_ERROR (Status
)) {
518 Status
= EFI_DEVICE_ERROR
;
523 // Component name protocol
525 Status
= AddUnicodeString (
527 gEhciComponentName
.SupportedLanguages
,
528 &HcDev
->ControllerNameTable
,
529 L
"Usb Enhanced Host Controller"
531 if (EFI_ERROR (Status
)) {
532 Status
= EFI_OUT_OF_RESOURCES
;
539 // Error handle process
542 DestoryPollingTimer (HcDev
);
543 deinit_memory_management
:
544 DeinitialMemoryManagement (HcDev
);
545 deinit_perodic_frame_list
:
546 DeinitialPeriodicFrameList (HcDev
);
547 uninstall_usb2hc_protocol
:
548 gBS
->UninstallProtocolInterface (
550 &gEfiUsb2HcProtocolGuid
,
554 gBS
->FreePool (HcDev
);
555 close_pciio_protocol
:
558 &gEfiPciIoProtocolGuid
,
559 This
->DriverBindingHandle
,
569 EhciDriverBindingStop (
570 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
571 IN EFI_HANDLE Controller
,
572 IN UINTN NumberOfChildren
,
573 IN EFI_HANDLE
*ChildHandleBuffer
579 Stop this driver on ControllerHandle. Support stoping any child handles
580 created by this driver.
584 This - Protocol instance pointer.
585 Controller - Handle of device to stop driver on
586 NumberOfChildren - Number of Children in the ChildHandleBuffer
587 ChildHandleBuffer - List of handles for the children we need to stop.
592 EFI_DEVICE_ERROR Fail
596 EFI_USB2_HC_PROTOCOL
*Usb2Hc
;
600 // Test whether the Controller handler passed in is a valid
601 // Usb controller handle that should be supported, if not,
602 // return the error status directly
604 Status
= gBS
->OpenProtocol (
606 &gEfiUsb2HcProtocolGuid
,
608 This
->DriverBindingHandle
,
610 EFI_OPEN_PROTOCOL_GET_PROTOCOL
612 if (EFI_ERROR (Status
)) {
613 Status
= EFI_DEVICE_ERROR
;
617 HcDev
= USB2_HC_DEV_FROM_THIS (Usb2Hc
);
620 // free all the controller related memory and uninstall UHCI Protocol.
622 Status
= gBS
->UninstallProtocolInterface (
624 &gEfiUsb2HcProtocolGuid
,
627 if (EFI_ERROR (Status
)) {
628 Status
= EFI_DEVICE_ERROR
;
633 // Set Host Controller state as halt
635 Status
= Usb2Hc
->SetState (
639 if (EFI_ERROR (Status
)) {
640 Status
= EFI_DEVICE_ERROR
;
645 // Stop AsyncRequest Polling Timer
647 Status
= StopPollingTimer (HcDev
);
648 if (EFI_ERROR (Status
)) {
649 Status
= EFI_DEVICE_ERROR
;
654 // Destroy Asynchronous Request Event
656 DestoryPollingTimer (HcDev
);
659 // Destroy Perodic Frame List
661 DeinitialPeriodicFrameList (HcDev
);
664 // Deinit Ehci pool memory management
666 DeinitialMemoryManagement (HcDev
);
669 // Denint Unicode String Table
671 FreeUnicodeStringTable (HcDev
->ControllerNameTable
);
674 // Disable the USB Host Controller
676 Status
= HcDev
->PciIo
->Attributes (
678 EfiPciIoAttributeOperationDisable
,
679 EFI_PCI_DEVICE_ENABLE
,
682 if (EFI_ERROR (Status
)) {
683 Status
= EFI_DEVICE_ERROR
;
687 gBS
->FreePool (HcDev
);
691 &gEfiPciIoProtocolGuid
,
692 This
->DriverBindingHandle
,
703 IN EFI_USB2_HC_PROTOCOL
*This
,
705 OUT UINT8
*PortNumber
,
706 OUT UINT8
*Is64BitCapable
712 Retrieves the capablility of root hub ports.
716 This - A pointer to the EFI_USB_HC_PROTOCOL instance.
717 MaxSpeed - A pointer to the number of the host controller.
718 PortNumber - A pointer to the number of the root hub ports.
719 Is64BitCapable - A pointer to the flag for whether controller supports
720 64-bit memory addressing.
724 EFI_SUCCESS host controller capability were retrieved successfully.
725 EFI_INVALID_PARAMETER MaxSpeed or PortNumber or Is64BitCapable is NULL.
726 EFI_DEVICE_ERROR An error was encountered while attempting to retrieve the capabilities.
732 UINT32 HcStructParamsAddr
;
733 UINT32 HcStructParamsReg
;
734 UINT32 HcCapParamsAddr
;
735 UINT32 HcCapParamsReg
;
737 if (MaxSpeed
== NULL
|| PortNumber
== NULL
|| Is64BitCapable
== NULL
) {
738 Status
= EFI_INVALID_PARAMETER
;
742 HcStructParamsAddr
= HCSPARAMS
;
743 HcCapParamsAddr
= HCCPARAMS
;
744 HcDev
= USB2_HC_DEV_FROM_THIS (This
);
746 Status
= ReadEhcCapabiltiyReg (
751 if (EFI_ERROR (Status
)) {
752 Status
= EFI_DEVICE_ERROR
;
756 Status
= ReadEhcCapabiltiyReg (
761 if (EFI_ERROR (Status
)) {
762 Status
= EFI_DEVICE_ERROR
;
766 *MaxSpeed
= EFI_USB_SPEED_HIGH
;
767 *PortNumber
= (UINT8
) (HcStructParamsReg
& HCSP_NPORTS
);
768 *Is64BitCapable
= (UINT8
) (HcCapParamsReg
& HCCP_64BIT
);
777 IN EFI_USB2_HC_PROTOCOL
*This
,
784 Provides software reset for the USB host controller.
788 This - A pointer to the EFI_USB2_HC_PROTOCOL instance.
789 Attributes - A bit mask of the reset operation to perform.
790 See below for a list of the supported bit mask values.
792 #define EFI_USB_HC_RESET_GLOBAL 0x0001
793 #define EFI_USB_HC_RESET_HOST_CONTROLLER 0x0002
794 #define EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG 0x0004
795 #define EFI_USB_HC_RESET_HOST_WITH_DEBUG 0x0008
797 EFI_USB_HC_RESET_GLOBAL
798 If this bit is set, a global reset signal will be sent to the USB bus.
799 This resets all of the USB bus logic, including the USB host
800 controller hardware and all the devices attached on the USB bus.
801 EFI_USB_HC_RESET_HOST_CONTROLLER
802 If this bit is set, the USB host controller hardware will be reset.
803 No reset signal will be sent to the USB bus.
804 EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG
805 If this bit is set, a global reset signal will be sent to the USB bus.
806 This resets all of the USB bus logic, including the USB host
807 controller hardware and all the devices attached on the USB bus.
808 If this is an EHCI controller and the debug port has configured, then
809 this is will still reset the host controller.
810 EFI_USB_HC_RESET_HOST_WITH_DEBUG
811 If this bit is set, the USB host controller hardware will be reset.
812 If this is an EHCI controller and the debug port has been configured,
813 then this will still reset the host controller.
818 The reset operation succeeded.
819 EFI_INVALID_PARAMETER
820 Attributes is not valid.
822 The type of reset specified by Attributes is not currently supported by
823 the host controller hardware.
825 Reset operation is rejected due to the debug port being configured and
826 active; only EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG or
827 EFI_USB_HC_RESET_HOST_WITH_DEBUG reset Atrributes can be used to
828 perform reset operation for this host controller.
830 An error was encountered while attempting to perform
838 FRAME_LIST_ENTRY
*FrameEntryPtr
;
840 HcDev
= USB2_HC_DEV_FROM_THIS (This
);
842 switch (Attributes
) {
844 case EFI_USB_HC_RESET_GLOBAL
:
847 // Same behavior as Host Controller Reset
850 case EFI_USB_HC_RESET_HOST_CONTROLLER
:
853 // Host Controller must be Halt when Reset it
855 if (IsEhcHalted (HcDev
)) {
856 Status
= ResetEhc (HcDev
);
857 if (EFI_ERROR (Status
)) {
858 Status
= EFI_DEVICE_ERROR
;
862 // Set to zero by Host Controller when reset process completes
864 Status
= WaitForEhcReset (HcDev
, EHCI_GENERIC_TIMEOUT
);
865 if (EFI_ERROR (Status
)) {
866 Status
= EFI_TIMEOUT
;
870 Status
= EFI_DEVICE_ERROR
;
875 // only asynchronous interrupt transfers are always alive on the bus, need to cleanup
877 CleanUpAllAsyncRequestTransfer (HcDev
);
878 Status
= ClearEhcAllStatus (HcDev
);
879 if (EFI_ERROR (Status
)) {
880 Status
= EFI_DEVICE_ERROR
;
885 // Set appropriate 4G Segment Selector
887 Status
= SetCtrlDataStructSeg (HcDev
);
888 if (EFI_ERROR (Status
)) {
889 Status
= EFI_DEVICE_ERROR
;
894 // Init Perodic List Base Addr and Frame List
896 Status
= SetFrameListBaseAddr (
898 (UINT32
)GET_0B_TO_31B (HcDev
->PeriodicFrameListBuffer
)
900 if (EFI_ERROR (Status
)) {
901 Status
= EFI_DEVICE_ERROR
;
904 FrameEntryPtr
= (FRAME_LIST_ENTRY
*) HcDev
->PeriodicFrameListBuffer
;
905 for (FrameIndex
= 0; FrameIndex
< HcDev
->PeriodicFrameListLength
; FrameIndex
++) {
906 FrameEntryPtr
->LinkTerminate
= TRUE
;
911 // Start the Host Controller
913 if (IsEhcHalted (HcDev
)) {
914 Status
= StartScheduleExecution (HcDev
);
915 if (EFI_ERROR (Status
)) {
916 Status
= EFI_DEVICE_ERROR
;
922 // Set all ports routing to EHC
924 Status
= SetPortRoutingEhc (HcDev
);
925 if (EFI_ERROR (Status
)) {
926 Status
= EFI_DEVICE_ERROR
;
931 case EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG
:
933 Status
= EFI_UNSUPPORTED
;
936 case EFI_USB_HC_RESET_HOST_WITH_DEBUG
:
938 Status
= EFI_UNSUPPORTED
;
942 Status
= EFI_INVALID_PARAMETER
;
952 IN EFI_USB2_HC_PROTOCOL
*This
,
953 OUT EFI_USB_HC_STATE
*State
959 Retrieves current state of the USB host controller.
963 This A pointer to the EFI_USB2_HC_PROTOCOL instance.
964 State A pointer to the EFI_USB_HC_STATE data structure that
965 indicates current state of the USB host controller.
966 Type EFI_USB_HC_STATE is defined below.
970 EfiUsbHcStateOperational,
971 EfiUsbHcStateSuspend,
978 The state information of the host controller was returned in State.
979 EFI_INVALID_PARAMETER
982 An error was encountered while attempting to retrieve the
983 host controller's current state.
988 UINT32 UsbStatusAddr
;
992 Status
= EFI_INVALID_PARAMETER
;
996 UsbStatusAddr
= USBSTS
;
997 HcDev
= USB2_HC_DEV_FROM_THIS (This
);
999 Status
= ReadEhcOperationalReg (
1004 if (EFI_ERROR (Status
)) {
1005 Status
= EFI_DEVICE_ERROR
;
1009 if (UsbStatusReg
& USBSTS_HCH
) {
1010 *State
= EfiUsbHcStateHalt
;
1012 *State
= EfiUsbHcStateOperational
;
1022 IN EFI_USB2_HC_PROTOCOL
*This
,
1023 IN EFI_USB_HC_STATE State
1027 Routine Description:
1029 Sets the USB host controller to a specific state.
1033 This - A pointer to the EFI_USB2_HC_PROTOCOL instance.
1034 State - Indicates the state of the host controller that will be set.
1039 The USB host controller was successfully placed in the state
1041 EFI_INVALID_PARAMETER
1044 Failed to set the state specified by State due to device error.
1050 UINT32 UsbCommandAddr
;
1051 UINT32 UsbCommandReg
;
1052 EFI_USB_HC_STATE CurrentState
;
1054 UsbCommandAddr
= USBCMD
;
1055 HcDev
= USB2_HC_DEV_FROM_THIS (This
);
1057 Status
= EhciGetState (This
, &CurrentState
);
1058 if (EFI_ERROR (Status
)) {
1059 Status
= EFI_DEVICE_ERROR
;
1065 case EfiUsbHcStateHalt
:
1067 if (EfiUsbHcStateHalt
== CurrentState
) {
1068 Status
= EFI_SUCCESS
;
1070 } else if (EfiUsbHcStateOperational
== CurrentState
) {
1071 Status
= ReadEhcOperationalReg (
1076 if (EFI_ERROR (Status
)) {
1077 Status
= EFI_DEVICE_ERROR
;
1081 UsbCommandReg
&= ~USBCMD_RS
;
1082 Status
= WriteEhcOperationalReg (
1087 if (EFI_ERROR (Status
)) {
1088 Status
= EFI_DEVICE_ERROR
;
1092 // Ensure the HC is in halt status after send the stop command
1094 Status
= WaitForEhcHalt (HcDev
, EHCI_GENERIC_TIMEOUT
);
1095 if (EFI_ERROR (Status
)) {
1096 Status
= EFI_TIMEOUT
;
1102 case EfiUsbHcStateOperational
:
1104 if (IsEhcSysError (HcDev
)) {
1105 Status
= EFI_DEVICE_ERROR
;
1108 if (EfiUsbHcStateOperational
== CurrentState
) {
1109 Status
= EFI_SUCCESS
;
1111 } else if (EfiUsbHcStateHalt
== CurrentState
) {
1113 // Set Host Controller Run
1115 Status
= ReadEhcOperationalReg (
1120 if (EFI_ERROR (Status
)) {
1121 return EFI_DEVICE_ERROR
;
1124 UsbCommandReg
|= USBCMD_RS
;
1125 Status
= WriteEhcOperationalReg (
1130 if (EFI_ERROR (Status
)) {
1131 Status
= EFI_DEVICE_ERROR
;
1137 case EfiUsbHcStateSuspend
:
1139 Status
= EFI_UNSUPPORTED
;
1144 Status
= EFI_INVALID_PARAMETER
;
1153 EhciGetRootHubPortStatus (
1154 IN EFI_USB2_HC_PROTOCOL
*This
,
1155 IN UINT8 PortNumber
,
1156 OUT EFI_USB_PORT_STATUS
*PortStatus
1160 Routine Description:
1162 Retrieves the current status of a USB root hub port.
1166 This - A pointer to the EFI_USB2_HC_PROTOCOL.
1167 PortNumber - Specifies the root hub port from which the status
1168 is to be retrieved. This value is zero-based. For example,
1169 if a root hub has two ports, then the first port is numbered 0,
1170 and the second port is numbered 1.
1171 PortStatus - A pointer to the current port status bits and
1172 port status change bits.
1176 EFI_SUCCESS The status of the USB root hub port specified
1177 by PortNumber was returned in PortStatus.
1178 EFI_INVALID_PARAMETER PortNumber is invalid.
1179 EFI_DEVICE_ERROR Can't read register
1185 UINT32 PortStatusControlAddr
;
1186 UINT32 PortStatusControlReg
;
1188 UINT8 TotalPortNumber
;
1189 UINT8 Is64BitCapable
;
1191 if (PortStatus
== NULL
) {
1192 Status
= EFI_INVALID_PARAMETER
;
1203 if (PortNumber
>= TotalPortNumber
) {
1204 Status
= EFI_INVALID_PARAMETER
;
1208 HcDev
= USB2_HC_DEV_FROM_THIS (This
);
1209 PortStatusControlAddr
= (UINT32
) (PORTSC
+ (4 * PortNumber
));
1212 // Clear port status
1214 PortStatus
->PortStatus
= 0;
1215 PortStatus
->PortChangeStatus
= 0;
1217 Status
= ReadEhcOperationalReg (
1219 PortStatusControlAddr
,
1220 &PortStatusControlReg
1222 if (EFI_ERROR (Status
)) {
1223 Status
= EFI_DEVICE_ERROR
;
1228 // Fill Port Status bits
1232 // Current Connect Status
1234 if (PORTSC_CCS
& PortStatusControlReg
) {
1235 PortStatus
->PortStatus
|= USB_PORT_STAT_CONNECTION
;
1238 // Port Enabled/Disabled
1240 if (PORTSC_PED
& PortStatusControlReg
) {
1241 PortStatus
->PortStatus
|= USB_PORT_STAT_ENABLE
;
1246 if (PORTSC_SUSP
& PortStatusControlReg
) {
1247 PortStatus
->PortStatus
|= USB_PORT_STAT_SUSPEND
;
1250 // Over-current Active
1252 if (PORTSC_OCA
& PortStatusControlReg
) {
1253 PortStatus
->PortStatus
|= USB_PORT_STAT_OVERCURRENT
;
1258 if (PORTSC_PR
& PortStatusControlReg
) {
1259 PortStatus
->PortStatus
|= USB_PORT_STAT_RESET
;
1264 if (PORTSC_PP
& PortStatusControlReg
) {
1265 PortStatus
->PortStatus
|= USB_PORT_STAT_POWER
;
1270 if (PORTSC_PO
& PortStatusControlReg
) {
1271 PortStatus
->PortStatus
|= USB_PORT_STAT_OWNER
;
1274 // Identify device speed
1276 if (PORTSC_LS_KSTATE
& PortStatusControlReg
) {
1278 // Low Speed Device Attached
1280 PortStatus
->PortStatus
|= USB_PORT_STAT_LOW_SPEED
;
1283 // Not Low Speed Device Attached
1285 if ((PORTSC_CCS
& PortStatusControlReg
) && (PORTSC_CSC
& PortStatusControlReg
)) {
1286 mDeviceSpeed
[PortNumber
] = IsHighSpeedDevice (This
, PortNumber
) ? USB_PORT_STAT_HIGH_SPEED
: 0;
1288 PortStatus
->PortStatus
|= mDeviceSpeed
[PortNumber
];
1291 // Fill Port Status Change bits
1294 // Connect Status Change
1296 if (PORTSC_CSC
& PortStatusControlReg
) {
1297 PortStatus
->PortChangeStatus
|= USB_PORT_STAT_C_CONNECTION
;
1300 // Port Enabled/Disabled Change
1302 if (PORTSC_PEDC
& PortStatusControlReg
) {
1303 PortStatus
->PortChangeStatus
|= USB_PORT_STAT_C_ENABLE
;
1306 // Port Over Current Change
1308 if (PORTSC_OCC
& PortStatusControlReg
) {
1309 PortStatus
->PortChangeStatus
|= USB_PORT_STAT_C_OVERCURRENT
;
1318 EhciSetRootHubPortFeature (
1319 IN EFI_USB2_HC_PROTOCOL
*This
,
1320 IN UINT8 PortNumber
,
1321 IN EFI_USB_PORT_FEATURE PortFeature
1325 Routine Description:
1327 Sets a feature for the specified root hub port.
1331 This - A pointer to the EFI_USB2_HC_PROTOCOL.
1332 PortNumber - Specifies the root hub port whose feature
1333 is requested to be set.
1334 PortFeature - Indicates the feature selector associated
1335 with the feature set request.
1340 The feature specified by PortFeature was set for the
1341 USB root hub port specified by PortNumber.
1342 EFI_INVALID_PARAMETER
1343 PortNumber is invalid or PortFeature is invalid.
1351 UINT32 PortStatusControlAddr
;
1352 UINT32 PortStatusControlReg
;
1354 UINT8 TotalPortNumber
;
1355 UINT8 Is64BitCapable
;
1364 if (PortNumber
>= TotalPortNumber
) {
1365 Status
= EFI_INVALID_PARAMETER
;
1369 HcDev
= USB2_HC_DEV_FROM_THIS (This
);
1370 PortStatusControlAddr
= (UINT32
) (PORTSC
+ (4 * PortNumber
));
1372 Status
= ReadEhcOperationalReg (
1374 PortStatusControlAddr
,
1375 &PortStatusControlReg
1377 if (EFI_ERROR (Status
)) {
1378 Status
= EFI_DEVICE_ERROR
;
1382 switch (PortFeature
) {
1384 case EfiUsbPortEnable
:
1387 // Sofeware can't set this bit, Port can only be enable by the Host Controller
1388 // as a part of the reset and enable
1390 PortStatusControlReg
&= 0xffffffd5;
1391 PortStatusControlReg
|= PORTSC_PED
;
1394 case EfiUsbPortSuspend
:
1396 PortStatusControlReg
&= 0xffffffd5;
1397 PortStatusControlReg
|= PORTSC_SUSP
;
1400 case EfiUsbPortReset
:
1403 // Make sure Host Controller not halt before reset it
1405 if (IsEhcHalted (HcDev
)) {
1406 Status
= StartScheduleExecution (HcDev
);
1407 if (EFI_ERROR (Status
)) {
1408 Status
= EFI_DEVICE_ERROR
;
1411 Status
= WaitForEhcNotHalt (HcDev
, EHCI_GENERIC_TIMEOUT
);
1412 if (EFI_ERROR (Status
)) {
1413 DEBUG ((gEHCDebugLevel
, "WaitForEhcNotHalt TimeOut\n"));
1414 Status
= EFI_DEVICE_ERROR
;
1418 PortStatusControlReg
&= 0xffffffd5;
1419 PortStatusControlReg
|= PORTSC_PR
;
1421 // Set one to PortReset bit must also set zero to PortEnable bit
1423 PortStatusControlReg
&= ~PORTSC_PED
;
1426 case EfiUsbPortPower
:
1429 // No support, no operation
1433 case EfiUsbPortOwner
:
1435 PortStatusControlReg
&= 0xffffffd5;
1436 PortStatusControlReg
|= PORTSC_PO
;
1441 Status
= EFI_INVALID_PARAMETER
;
1445 Status
= WriteEhcOperationalReg (
1447 PortStatusControlAddr
,
1448 PortStatusControlReg
1450 if (EFI_ERROR (Status
)) {
1451 Status
= EFI_DEVICE_ERROR
;
1460 EhciClearRootHubPortFeature (
1461 IN EFI_USB2_HC_PROTOCOL
*This
,
1462 IN UINT8 PortNumber
,
1463 IN EFI_USB_PORT_FEATURE PortFeature
1467 Routine Description:
1469 Clears a feature for the specified root hub port.
1473 This - A pointer to the EFI_USB2_HC_PROTOCOL instance.
1474 PortNumber - Specifies the root hub port whose feature
1475 is requested to be cleared.
1476 PortFeature - Indicates the feature selector associated with the
1477 feature clear request.
1482 The feature specified by PortFeature was cleared for the
1483 USB root hub port specified by PortNumber.
1484 EFI_INVALID_PARAMETER
1485 PortNumber is invalid or PortFeature is invalid.
1493 UINT32 PortStatusControlAddr
;
1494 UINT32 PortStatusControlReg
;
1496 UINT8 TotalPortNumber
;
1497 UINT8 Is64BitCapable
;
1506 if (PortNumber
>= TotalPortNumber
) {
1507 Status
= EFI_INVALID_PARAMETER
;
1511 HcDev
= USB2_HC_DEV_FROM_THIS (This
);
1512 PortStatusControlAddr
= (UINT32
) (PORTSC
+ (4 * PortNumber
));
1514 Status
= ReadEhcOperationalReg (
1516 PortStatusControlAddr
,
1517 &PortStatusControlReg
1519 if (EFI_ERROR (Status
)) {
1520 Status
= EFI_DEVICE_ERROR
;
1524 switch (PortFeature
) {
1526 case EfiUsbPortEnable
:
1529 // Clear PORT_ENABLE feature means disable port.
1531 PortStatusControlReg
&= 0xffffffd5;
1532 PortStatusControlReg
&= ~PORTSC_PED
;
1535 case EfiUsbPortSuspend
:
1538 // A write of zero to this bit is ignored by the host controller.
1539 // The host controller will unconditionally set this bit to a zero when:
1540 // 1. software sets the Forct Port Resume bit to a zero from a one.
1541 // 2. software sets the Port Reset bit to a one frome a zero.
1543 PortStatusControlReg
&= 0xffffffd5;
1544 PortStatusControlReg
&= ~PORTSC_FPR
;
1547 case EfiUsbPortReset
:
1550 // Clear PORT_RESET means clear the reset signal.
1552 PortStatusControlReg
&= 0xffffffd5;
1553 PortStatusControlReg
&= ~PORTSC_PR
;
1556 case EfiUsbPortPower
:
1559 // No support, no operation
1563 case EfiUsbPortOwner
:
1566 // Clear port owner means this port owned by EHC
1568 PortStatusControlReg
&= 0xffffffd5;
1569 PortStatusControlReg
&= ~PORTSC_PO
;
1572 case EfiUsbPortConnectChange
:
1575 // Clear connect status change
1577 PortStatusControlReg
&= 0xffffffd5;
1578 PortStatusControlReg
|= PORTSC_CSC
;
1581 case EfiUsbPortEnableChange
:
1584 // Clear enable status change
1586 PortStatusControlReg
&= 0xffffffd5;
1587 PortStatusControlReg
|= PORTSC_PEDC
;
1590 case EfiUsbPortSuspendChange
:
1593 // No related bit, no operation
1597 case EfiUsbPortOverCurrentChange
:
1600 // Clear PortOverCurrent change
1602 PortStatusControlReg
&= 0xffffffd5;
1603 PortStatusControlReg
|= PORTSC_OCC
;
1606 case EfiUsbPortResetChange
:
1609 // No related bit, no operation
1615 Status
= EFI_INVALID_PARAMETER
;
1619 Status
= WriteEhcOperationalReg (
1621 PortStatusControlAddr
,
1622 PortStatusControlReg
1624 if (EFI_ERROR (Status
)) {
1625 Status
= EFI_DEVICE_ERROR
;
1635 EhciControlTransfer (
1636 IN EFI_USB2_HC_PROTOCOL
*This
,
1637 IN UINT8 DeviceAddress
,
1638 IN UINT8 DeviceSpeed
,
1639 IN UINTN MaximumPacketLength
,
1640 IN EFI_USB_DEVICE_REQUEST
*Request
,
1641 IN EFI_USB_DATA_DIRECTION TransferDirection
,
1643 IN OUT UINTN
*DataLength
,
1645 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
1646 OUT UINT32
*TransferResult
1650 Routine Description:
1652 Submits control transfer to a target USB device.
1656 This - A pointer to the EFI_USB2_HC_PROTOCOL instance.
1657 DeviceAddress - Represents the address of the target device on the USB,
1658 which is assigned during USB enumeration.
1659 DeviceSpeed - Indicates target device speed.
1660 MaximumPacketLength - Indicates the maximum packet size that the
1661 default control transfer endpoint is capable of
1662 sending or receiving.
1663 Request - A pointer to the USB device request that will be sent
1665 TransferDirection - Specifies the data direction for the transfer.
1666 There are three values available, DataIn, DataOut
1668 Data - A pointer to the buffer of data that will be transmitted
1669 to USB device or received from USB device.
1670 DataLength - Indicates the size, in bytes, of the data buffer
1672 TimeOut - Indicates the maximum time, in microseconds,
1673 which the transfer is allowed to complete.
1674 Translator - A pointr to the transaction translator data.
1675 TransferResult - A pointer to the detailed result information generated
1676 by this control transfer.
1681 The control transfer was completed successfully.
1682 EFI_OUT_OF_RESOURCES
1683 The control transfer could not be completed due to a lack of resources.
1684 EFI_INVALID_PARAMETER
1685 Some parameters are invalid.
1687 The control transfer failed due to timeout.
1689 The control transfer failed due to host controller or device error.
1690 Caller should check TranferResult for detailed error information.
1697 EHCI_QH_ENTITY
*QhPtr
;
1698 EHCI_QTD_ENTITY
*ControlQtdsPtr
;
1701 UINT8
*RequestCursor
;
1705 ControlQtdsPtr
= NULL
;
1708 RequestCursor
= NULL
;
1710 HcDev
= USB2_HC_DEV_FROM_THIS (This
);
1713 // Parameters Checking
1715 if (TransferDirection
!= EfiUsbDataIn
&&
1716 TransferDirection
!= EfiUsbDataOut
&&
1717 TransferDirection
!= EfiUsbNoData
1719 Status
= EFI_INVALID_PARAMETER
;
1723 if (EfiUsbNoData
== TransferDirection
) {
1724 if (NULL
!= Data
|| 0 != *DataLength
) {
1725 Status
= EFI_INVALID_PARAMETER
;
1729 if (NULL
== Data
|| 0 == *DataLength
) {
1730 Status
= EFI_INVALID_PARAMETER
;
1735 if (Request
== NULL
|| TransferResult
== NULL
) {
1736 Status
= EFI_INVALID_PARAMETER
;
1740 if (EFI_USB_SPEED_LOW
== DeviceSpeed
) {
1741 if (MaximumPacketLength
!= 8) {
1742 Status
= EFI_INVALID_PARAMETER
;
1745 } else if (MaximumPacketLength
!= 8 &&
1746 MaximumPacketLength
!= 16 &&
1747 MaximumPacketLength
!= 32 &&
1748 MaximumPacketLength
!= 64
1750 Status
= EFI_INVALID_PARAMETER
;
1755 // If errors exist that cause host controller halt,
1756 // then return EFI_DEVICE_ERROR.
1758 if (IsEhcHalted (HcDev
) || IsEhcSysError (HcDev
)) {
1759 ClearEhcAllStatus (HcDev
);
1760 *TransferResult
= EFI_USB_ERR_SYSTEM
;
1761 Status
= EFI_DEVICE_ERROR
;
1766 // Map the Request for bus master access.
1767 // BusMasterRead means cpu write
1769 Status
= MapRequestBuffer (
1775 if (EFI_ERROR (Status
)) {
1776 *TransferResult
= EFI_USB_ERR_SYSTEM
;
1777 Status
= EFI_DEVICE_ERROR
;
1782 // Map the source data buffer for bus master access.
1784 Status
= MapDataBuffer (
1793 if (EFI_ERROR (Status
)) {
1794 *TransferResult
= EFI_USB_ERR_SYSTEM
;
1795 Status
= EFI_DEVICE_ERROR
;
1800 // Create and init control Qh
1802 Status
= CreateControlQh (
1806 MaximumPacketLength
,
1810 if (EFI_ERROR (Status
)) {
1811 *TransferResult
= EFI_USB_ERR_SYSTEM
;
1812 Status
= EFI_OUT_OF_RESOURCES
;
1817 // Create and init control Qtds
1819 Status
= CreateControlQtds (
1828 if (EFI_ERROR (Status
)) {
1829 *TransferResult
= EFI_USB_ERR_SYSTEM
;
1830 Status
= EFI_OUT_OF_RESOURCES
;
1837 LinkQtdToQh (QhPtr
, ControlQtdsPtr
);
1839 ClearEhcAllStatus (HcDev
);
1842 // Link Qh and Qtds to Async Schedule List
1844 Status
= LinkQhToAsyncList (HcDev
, QhPtr
);
1845 if (EFI_ERROR (Status
)) {
1846 *TransferResult
= EFI_USB_ERR_SYSTEM
;
1847 Status
= EFI_DEVICE_ERROR
;
1852 // Poll Qh-Qtds execution and get result.
1853 // detail status is returned
1855 Status
= ExecuteTransfer (
1864 if (EFI_ERROR (Status
)) {
1869 // If has errors that cause host controller halt,
1870 // then return EFI_DEVICE_ERROR directly.
1872 if (IsEhcHalted (HcDev
) || IsEhcSysError (HcDev
)) {
1873 *TransferResult
|= EFI_USB_ERR_SYSTEM
;
1876 ClearEhcAllStatus (HcDev
);
1879 UnlinkQhFromAsyncList (HcDev
, QhPtr
);
1880 DestoryQtds (HcDev
, ControlQtdsPtr
);
1882 DestoryQh (HcDev
, QhPtr
);
1884 HcDev
->PciIo
->Unmap (HcDev
->PciIo
, DataMap
);
1886 HcDev
->PciIo
->Unmap (HcDev
->PciIo
, RequestMap
);
1888 HcDev
->PciIo
->Flush (HcDev
->PciIo
);
1895 IN EFI_USB2_HC_PROTOCOL
*This
,
1896 IN UINT8 DeviceAddress
,
1897 IN UINT8 EndPointAddress
,
1898 IN UINT8 DeviceSpeed
,
1899 IN UINTN MaximumPacketLength
,
1900 IN UINT8 DataBuffersNumber
,
1901 IN OUT VOID
*Data
[EFI_USB_MAX_BULK_BUFFER_NUM
],
1902 IN OUT UINTN
*DataLength
,
1903 IN OUT UINT8
*DataToggle
,
1905 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
1906 OUT UINT32
*TransferResult
1910 Routine Description:
1912 Submits bulk transfer to a bulk endpoint of a USB device.
1916 This - A pointer to the EFI_USB2_HC_PROTOCOL instance.
1917 DeviceAddress - Represents the address of the target device on the USB,
1918 which is assigned during USB enumeration.
1919 EndPointAddress - The combination of an endpoint number and an
1920 endpoint direction of the target USB device.
1921 Each endpoint address supports data transfer in
1922 one direction except the control endpoint
1923 (whose default endpoint address is 0).
1924 It is the caller's responsibility to make sure that
1925 the EndPointAddress represents a bulk endpoint.
1926 DeviceSpeed - Indicates device speed. The supported values are EFI_USB_SPEED_FULL
1927 and EFI_USB_SPEED_HIGH.
1928 MaximumPacketLength - Indicates the maximum packet size the target endpoint
1929 is capable of sending or receiving.
1930 DataBuffersNumber - Number of data buffers prepared for the transfer.
1931 Data - Array of pointers to the buffers of data that will be transmitted
1932 to USB device or received from USB device.
1933 DataLength - When input, indicates the size, in bytes, of the data buffer
1934 specified by Data. When output, indicates the actually
1935 transferred data size.
1936 DataToggle - A pointer to the data toggle value. On input, it indicates
1937 the initial data toggle value the bulk transfer should adopt;
1938 on output, it is updated to indicate the data toggle value
1939 of the subsequent bulk transfer.
1940 Translator - A pointr to the transaction translator data.
1941 TimeOut - Indicates the maximum time, in microseconds, which the
1942 transfer is allowed to complete.
1943 TransferResult - A pointer to the detailed result information of the
1949 The bulk transfer was completed successfully.
1950 EFI_OUT_OF_RESOURCES
1951 The bulk transfer could not be submitted due to lack of resource.
1952 EFI_INVALID_PARAMETER
1953 Some parameters are invalid.
1955 The bulk transfer failed due to timeout.
1957 The bulk transfer failed due to host controller or device error.
1958 Caller should check TranferResult for detailed error information.
1965 EHCI_QH_ENTITY
*QhPtr
;
1966 EHCI_QTD_ENTITY
*BulkQtdsPtr
;
1969 EFI_USB_DATA_DIRECTION TransferDirection
;
1975 HcDev
= USB2_HC_DEV_FROM_THIS (This
);
1978 // Parameters Checking
1980 if (NULL
== DataLength
||
1983 NULL
== TransferResult
1985 Status
= EFI_INVALID_PARAMETER
;
1989 if (*DataLength
== 0) {
1990 Status
= EFI_INVALID_PARAMETER
;
1994 if (1 != *DataToggle
&& 0 != *DataToggle
) {
1995 Status
= EFI_INVALID_PARAMETER
;
1999 if (EFI_USB_SPEED_LOW
== DeviceSpeed
) {
2000 Status
= EFI_INVALID_PARAMETER
;
2004 if (EFI_USB_SPEED_FULL
== DeviceSpeed
) {
2005 if (MaximumPacketLength
> 64) {
2006 Status
= EFI_INVALID_PARAMETER
;
2011 if (EFI_USB_SPEED_HIGH
== DeviceSpeed
) {
2012 if (MaximumPacketLength
> 512) {
2013 Status
= EFI_INVALID_PARAMETER
;
2019 // if has errors that cause host controller halt,
2020 // then return EFI_DEVICE_ERROR directly.
2022 if (IsEhcHalted (HcDev
) || IsEhcSysError (HcDev
)) {
2023 ClearEhcAllStatus (HcDev
);
2024 *TransferResult
= EFI_USB_ERR_SYSTEM
;
2025 Status
= EFI_DEVICE_ERROR
;
2029 Status
= ClearEhcAllStatus (HcDev
);
2030 if (EFI_ERROR (Status
)) {
2031 Status
= EFI_DEVICE_ERROR
;
2036 // construct QH and TD data structures,
2037 // and link them together
2039 if (EndPointAddress
& 0x80) {
2040 TransferDirection
= EfiUsbDataIn
;
2042 TransferDirection
= EfiUsbDataOut
;
2045 Status
= MapDataBuffer (
2054 if (EFI_ERROR (Status
)) {
2055 *TransferResult
= EFI_USB_ERR_SYSTEM
;
2056 Status
= EFI_DEVICE_ERROR
;
2061 // Create and init Bulk Qh
2063 Status
= CreateBulkQh (
2069 MaximumPacketLength
,
2073 if (EFI_ERROR (Status
)) {
2074 *TransferResult
= EFI_USB_ERR_SYSTEM
;
2075 Status
= EFI_OUT_OF_RESOURCES
;
2080 // Create and init Bulk Qtds
2082 Status
= CreateBulkOrInterruptQtds (
2090 if (EFI_ERROR (Status
)) {
2091 *TransferResult
= EFI_USB_ERR_SYSTEM
;
2092 Status
= EFI_OUT_OF_RESOURCES
;
2099 LinkQtdToQh (QhPtr
, BulkQtdsPtr
);
2101 ClearEhcAllStatus (HcDev
);
2104 // Link Qh and qtds to Async Schedule List
2106 Status
= LinkQhToAsyncList (HcDev
, QhPtr
);
2107 if (EFI_ERROR (Status
)) {
2108 *TransferResult
= EFI_USB_ERR_SYSTEM
;
2109 Status
= EFI_DEVICE_ERROR
;
2114 // Poll QH-TDs execution and get result.
2115 // detail status is returned
2117 Status
= ExecuteTransfer (
2126 if (EFI_ERROR (Status
)) {
2131 // if has errors that cause host controller halt,
2132 // then return EFI_DEVICE_ERROR directly.
2134 if (IsEhcHalted (HcDev
) || IsEhcSysError (HcDev
)) {
2135 *TransferResult
|= EFI_USB_ERR_SYSTEM
;
2138 ClearEhcAllStatus (HcDev
);
2141 UnlinkQhFromAsyncList (HcDev
, QhPtr
);
2142 DestoryQtds (HcDev
, BulkQtdsPtr
);
2144 DestoryQh (HcDev
, QhPtr
);
2146 HcDev
->PciIo
->Unmap (HcDev
->PciIo
, DataMap
);
2148 HcDev
->PciIo
->Flush (HcDev
->PciIo
);
2154 EhciAsyncInterruptTransfer (
2155 IN EFI_USB2_HC_PROTOCOL
* This
,
2156 IN UINT8 DeviceAddress
,
2157 IN UINT8 EndPointAddress
,
2158 IN UINT8 DeviceSpeed
,
2159 IN UINTN MaximumPacketLength
,
2160 IN BOOLEAN IsNewTransfer
,
2161 IN OUT UINT8
*DataToggle
,
2162 IN UINTN PollingInterval
,
2163 IN UINTN DataLength
,
2164 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
* Translator
,
2165 IN EFI_ASYNC_USB_TRANSFER_CALLBACK CallBackFunction
,
2166 IN VOID
*Context OPTIONAL
2170 Routine Description:
2172 Submits an asynchronous interrupt transfer to an
2173 interrupt endpoint of a USB device.
2174 Translator parameter doesn't exist in UEFI2.0 spec, but it will be updated
2175 in the following specification version.
2179 This - A pointer to the EFI_USB2_HC_PROTOCOL instance.
2180 DeviceAddress - Represents the address of the target device on the USB,
2181 which is assigned during USB enumeration.
2182 EndPointAddress - The combination of an endpoint number and an endpoint
2183 direction of the target USB device. Each endpoint address
2184 supports data transfer in one direction except the
2185 control endpoint (whose default endpoint address is 0).
2186 It is the caller's responsibility to make sure that
2187 the EndPointAddress represents an interrupt endpoint.
2188 DeviceSpeed - Indicates device speed.
2189 MaximumPacketLength - Indicates the maximum packet size the target endpoint
2190 is capable of sending or receiving.
2191 IsNewTransfer - If TRUE, an asynchronous interrupt pipe is built between
2192 the host and the target interrupt endpoint.
2193 If FALSE, the specified asynchronous interrupt pipe
2195 DataToggle - A pointer to the data toggle value. On input, it is valid
2196 when IsNewTransfer is TRUE, and it indicates the initial
2197 data toggle value the asynchronous interrupt transfer
2199 On output, it is valid when IsNewTransfer is FALSE,
2200 and it is updated to indicate the data toggle value of
2201 the subsequent asynchronous interrupt transfer.
2202 PollingInterval - Indicates the interval, in milliseconds, that the
2203 asynchronous interrupt transfer is polled.
2204 This parameter is required when IsNewTransfer is TRUE.
2205 DataLength - Indicates the length of data to be received at the
2206 rate specified by PollingInterval from the target
2207 asynchronous interrupt endpoint. This parameter
2208 is only required when IsNewTransfer is TRUE.
2209 Translator - A pointr to the transaction translator data.
2210 CallBackFunction - The Callback function.This function is called at the
2211 rate specified by PollingInterval.This parameter is
2212 only required when IsNewTransfer is TRUE.
2213 Context - The context that is passed to the CallBackFunction.
2214 - This is an optional parameter and may be NULL.
2219 The asynchronous interrupt transfer request has been successfully
2220 submitted or canceled.
2221 EFI_INVALID_PARAMETER
2222 Some parameters are invalid.
2223 EFI_OUT_OF_RESOURCES
2224 The request could not be completed due to a lack of resources.
2233 EHCI_QH_ENTITY
*QhPtr
;
2234 EHCI_QTD_ENTITY
*InterruptQtdsPtr
;
2239 EHCI_ASYNC_REQUEST
*AsyncRequestPtr
;
2243 InterruptQtdsPtr
= NULL
;
2247 AsyncRequestPtr
= NULL
;
2248 HcDev
= USB2_HC_DEV_FROM_THIS (This
);
2251 // Parameters Checking
2253 if (!IsDataInTransfer (EndPointAddress
)) {
2254 Status
= EFI_INVALID_PARAMETER
;
2258 if (IsNewTransfer
) {
2259 if (0 == DataLength
) {
2260 Status
= EFI_INVALID_PARAMETER
;
2264 if (*DataToggle
!= 1 && *DataToggle
!= 0) {
2265 Status
= EFI_INVALID_PARAMETER
;
2269 if (PollingInterval
> 255 || PollingInterval
< 1) {
2270 Status
= EFI_INVALID_PARAMETER
;
2276 // if has errors that cause host controller halt,
2277 // then return EFI_DEVICE_ERROR directly.
2279 if (IsEhcHalted (HcDev
) || IsEhcSysError (HcDev
)) {
2280 ClearEhcAllStatus (HcDev
);
2281 Status
= EFI_DEVICE_ERROR
;
2285 Status
= ClearEhcAllStatus (HcDev
);
2286 if (EFI_ERROR (Status
)) {
2287 Status
= EFI_DEVICE_ERROR
;
2292 // Delete Async interrupt transfer request
2294 if (!IsNewTransfer
) {
2296 OldTpl
= gBS
->RaiseTPL (EFI_TPL_NOTIFY
);
2298 Status
= DeleteAsyncRequestTransfer (
2305 gBS
->RestoreTPL (OldTpl
);
2310 Status
= EhciAllocatePool (
2312 (UINT8
**) &AsyncRequestPtr
,
2313 sizeof (EHCI_ASYNC_REQUEST
)
2315 if (EFI_ERROR (Status
)) {
2316 Status
= EFI_OUT_OF_RESOURCES
;
2320 Status
= EhciAllocatePool (HcDev
, &DataPtr
, DataLength
);
2321 if (EFI_ERROR (Status
)) {
2322 Status
= EFI_OUT_OF_RESOURCES
;
2326 MappedLength
= DataLength
;
2327 Status
= MapDataBuffer (
2336 if (EFI_ERROR (Status
)) {
2337 Status
= EFI_DEVICE_ERROR
;
2342 // Create and init Interrupt Qh
2344 Status
= CreateInterruptQh (
2350 MaximumPacketLength
,
2355 if (EFI_ERROR (Status
)) {
2356 Status
= EFI_OUT_OF_RESOURCES
;
2361 // Create and init Interrupt Qtds
2363 Status
= CreateBulkOrInterruptQtds (
2371 if (EFI_ERROR (Status
)) {
2372 Status
= EFI_OUT_OF_RESOURCES
;
2379 LinkQtdToQh (QhPtr
, InterruptQtdsPtr
);
2382 // Init AsyncRequest Entry
2384 AsyncRequestPtr
->Context
= Context
;
2385 AsyncRequestPtr
->CallBackFunc
= CallBackFunction
;
2386 AsyncRequestPtr
->TransferType
= ASYNC_INTERRUPT_TRANSFER
;
2387 AsyncRequestPtr
->QhPtr
= QhPtr
;
2388 AsyncRequestPtr
->Prev
= NULL
;
2389 AsyncRequestPtr
->Next
= NULL
;
2391 if (NULL
== HcDev
->AsyncRequestList
) {
2392 Status
= StartPollingTimer (HcDev
);
2393 if (EFI_ERROR (Status
)) {
2394 Status
= EFI_DEVICE_ERROR
;
2395 CleanUpAllAsyncRequestTransfer (HcDev
);
2401 // Link Entry to AsyncRequest List
2403 LinkToAsyncReqeust (HcDev
, AsyncRequestPtr
);
2405 ClearEhcAllStatus (HcDev
);
2407 Status
= DisablePeriodicSchedule (HcDev
);
2408 if (EFI_ERROR (Status
)) {
2409 Status
= EFI_DEVICE_ERROR
;
2413 Status
= WaitForPeriodicScheduleDisable (HcDev
, EHCI_GENERIC_TIMEOUT
);
2414 if (EFI_ERROR (Status
)) {
2415 Status
= EFI_TIMEOUT
;
2420 // Link Qh and Qtds to Periodic Schedule List
2422 LinkQhToPeriodicList (HcDev
, QhPtr
);
2424 Status
= EnablePeriodicSchedule (HcDev
);
2425 if (EFI_ERROR (Status
)) {
2426 Status
= EFI_DEVICE_ERROR
;
2430 Status
= WaitForPeriodicScheduleEnable (HcDev
, EHCI_GENERIC_TIMEOUT
);
2431 if (EFI_ERROR (Status
)) {
2432 Status
= EFI_TIMEOUT
;
2436 if (IsEhcHalted (HcDev
)) {
2437 Status
= StartScheduleExecution (HcDev
);
2438 if (EFI_ERROR (Status
)) {
2439 Status
= EFI_DEVICE_ERROR
;
2444 HcDev
->PciIo
->Flush (HcDev
->PciIo
);
2448 DestoryQh (HcDev
, QhPtr
);
2450 EhciFreePool (HcDev
, DataPtr
, DataLength
);
2454 (UINT8
*) AsyncRequestPtr
,
2455 sizeof (EHCI_ASYNC_REQUEST
)
2458 HcDev
->PciIo
->Unmap (HcDev
->PciIo
, DataMap
);
2465 EhciSyncInterruptTransfer (
2466 IN EFI_USB2_HC_PROTOCOL
*This
,
2467 IN UINT8 DeviceAddress
,
2468 IN UINT8 EndPointAddress
,
2469 IN UINT8 DeviceSpeed
,
2470 IN UINTN MaximumPacketLength
,
2472 IN OUT UINTN
*DataLength
,
2473 IN OUT UINT8
*DataToggle
,
2475 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
2476 OUT UINT32
*TransferResult
2480 Routine Description:
2482 Submits synchronous interrupt transfer to an interrupt endpoint
2484 Translator parameter doesn't exist in UEFI2.0 spec, but it will be updated
2485 in the following specification version.
2489 This - A pointer to the EFI_USB2_HC_PROTOCOL instance.
2490 DeviceAddress - Represents the address of the target device on the USB,
2491 which is assigned during USB enumeration.
2492 EndPointAddress - The combination of an endpoint number and an endpoint
2493 direction of the target USB device. Each endpoint
2494 address supports data transfer in one direction
2495 except the control endpoint (whose default
2496 endpoint address is 0). It is the caller's responsibility
2497 to make sure that the EndPointAddress represents
2498 an interrupt endpoint.
2499 DeviceSpeed - Indicates device speed.
2500 MaximumPacketLength - Indicates the maximum packet size the target endpoint
2501 is capable of sending or receiving.
2502 Data - A pointer to the buffer of data that will be transmitted
2503 to USB device or received from USB device.
2504 DataLength - On input, the size, in bytes, of the data buffer specified
2505 by Data. On output, the number of bytes transferred.
2506 DataToggle - A pointer to the data toggle value. On input, it indicates
2507 the initial data toggle value the synchronous interrupt
2508 transfer should adopt;
2509 on output, it is updated to indicate the data toggle value
2510 of the subsequent synchronous interrupt transfer.
2511 TimeOut - Indicates the maximum time, in microseconds, which the
2512 transfer is allowed to complete.
2513 Translator - A pointr to the transaction translator data.
2514 TransferResult - A pointer to the detailed result information from
2515 the synchronous interrupt transfer.
2520 The synchronous interrupt transfer was completed successfully.
2521 EFI_OUT_OF_RESOURCES
2522 The synchronous interrupt transfer could not be submitted due
2523 to lack of resource.
2524 EFI_INVALID_PARAMETER
2525 Some parameters are invalid.
2527 The synchronous interrupt transfer failed due to timeout.
2529 The synchronous interrupt transfer failed due to host controller
2530 or device error. Caller should check TranferResult for detailed
2538 EHCI_QH_ENTITY
*QhPtr
;
2539 EHCI_QTD_ENTITY
*InterruptQtdsPtr
;
2544 InterruptQtdsPtr
= NULL
;
2547 HcDev
= USB2_HC_DEV_FROM_THIS (This
);
2550 // Parameters Checking
2552 if (DataLength
== NULL
||
2554 TransferResult
== NULL
2556 Status
= EFI_INVALID_PARAMETER
;
2560 if (!IsDataInTransfer (EndPointAddress
)) {
2561 Status
= EFI_INVALID_PARAMETER
;
2565 if (0 == *DataLength
) {
2566 Status
= EFI_INVALID_PARAMETER
;
2570 if (*DataToggle
!= 1 && *DataToggle
!= 0) {
2571 Status
= EFI_INVALID_PARAMETER
;
2575 if (EFI_USB_SPEED_LOW
== DeviceSpeed
&& 8 != MaximumPacketLength
) {
2576 Status
= EFI_INVALID_PARAMETER
;
2580 if (EFI_USB_SPEED_FULL
== DeviceSpeed
&& MaximumPacketLength
> 64) {
2581 Status
= EFI_INVALID_PARAMETER
;
2585 if (EFI_USB_SPEED_HIGH
== DeviceSpeed
&& MaximumPacketLength
> 3072) {
2586 Status
= EFI_INVALID_PARAMETER
;
2591 // if has errors that cause host controller halt,
2592 // then return EFI_DEVICE_ERROR directly.
2594 if (IsEhcHalted (HcDev
) || IsEhcSysError (HcDev
)) {
2595 ClearEhcAllStatus (HcDev
);
2596 *TransferResult
= EFI_USB_ERR_SYSTEM
;
2597 Status
= EFI_DEVICE_ERROR
;
2601 Status
= ClearEhcAllStatus (HcDev
);
2602 if (EFI_ERROR (Status
)) {
2603 Status
= EFI_DEVICE_ERROR
;
2607 Status
= MapDataBuffer (
2616 if (EFI_ERROR (Status
)) {
2617 *TransferResult
= EFI_USB_ERR_SYSTEM
;
2618 Status
= EFI_DEVICE_ERROR
;
2623 // Create and init Interrupt Qh
2625 Status
= CreateInterruptQh (
2631 MaximumPacketLength
,
2636 if (EFI_ERROR (Status
)) {
2637 Status
= EFI_OUT_OF_RESOURCES
;
2642 // Create and init Interrupt Qtds
2644 Status
= CreateBulkOrInterruptQtds (
2652 if (EFI_ERROR (Status
)) {
2653 *TransferResult
= EFI_USB_ERR_SYSTEM
;
2654 Status
= EFI_OUT_OF_RESOURCES
;
2661 LinkQtdToQh (QhPtr
, InterruptQtdsPtr
);
2663 ClearEhcAllStatus (HcDev
);
2665 Status
= DisablePeriodicSchedule (HcDev
);
2666 if (EFI_ERROR (Status
)) {
2667 Status
= EFI_DEVICE_ERROR
;
2671 Status
= WaitForPeriodicScheduleDisable (HcDev
, EHCI_GENERIC_TIMEOUT
);
2672 if (EFI_ERROR (Status
)) {
2673 Status
= EFI_TIMEOUT
;
2678 // Link Qh and Qtds to Periodic Schedule List
2680 LinkQhToPeriodicList (HcDev
, QhPtr
);
2682 Status
= EnablePeriodicSchedule (HcDev
);
2683 if (EFI_ERROR (Status
)) {
2684 Status
= EFI_DEVICE_ERROR
;
2688 Status
= WaitForPeriodicScheduleEnable (HcDev
, EHCI_GENERIC_TIMEOUT
);
2689 if (EFI_ERROR (Status
)) {
2690 Status
= EFI_TIMEOUT
;
2694 if (IsEhcHalted (HcDev
)) {
2695 Status
= StartScheduleExecution (HcDev
);
2696 if (EFI_ERROR (Status
)) {
2697 Status
= EFI_DEVICE_ERROR
;
2703 // Poll QH-TDs execution and get result.
2704 // detail status is returned
2706 Status
= ExecuteTransfer (
2715 if (EFI_ERROR (Status
)) {
2720 // if has errors that cause host controller halt,
2721 // then return EFI_DEVICE_ERROR directly.
2723 if (IsEhcHalted (HcDev
) || IsEhcSysError (HcDev
)) {
2724 *TransferResult
|= EFI_USB_ERR_SYSTEM
;
2727 ClearEhcAllStatus (HcDev
);
2730 UnlinkQhFromPeriodicList (HcDev
, QhPtr
, 0);
2731 DestoryQtds (HcDev
, InterruptQtdsPtr
);
2733 DestoryQh (HcDev
, QhPtr
);
2735 HcDev
->PciIo
->Unmap (HcDev
->PciIo
, DataMap
);
2737 HcDev
->PciIo
->Flush (HcDev
->PciIo
);
2743 EhciIsochronousTransfer (
2744 IN EFI_USB2_HC_PROTOCOL
*This
,
2745 IN UINT8 DeviceAddress
,
2746 IN UINT8 EndPointAddress
,
2747 IN UINT8 DeviceSpeed
,
2748 IN UINTN MaximumPacketLength
,
2749 IN UINT8 DataBuffersNumber
,
2750 IN OUT VOID
*Data
[EFI_USB_MAX_ISO_BUFFER_NUM
],
2751 IN UINTN DataLength
,
2752 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
2753 OUT UINT32
*TransferResult
2757 Routine Description:
2759 Submits isochronous transfer to a target USB device.
2763 This - A pointer to the EFI_USB2_HC_PROTOCOL instance.
2764 DeviceAddress - Represents the address of the target device on the USB,
2765 which is assigned during USB enumeration.
2766 EndPointAddress - End point address
2767 DeviceSpeed - Indicates device speed.
2768 MaximumPacketLength - Indicates the maximum packet size that the
2769 default control transfer endpoint is capable of
2770 sending or receiving.
2771 DataBuffersNumber - Number of data buffers prepared for the transfer.
2772 Data - Array of pointers to the buffers of data that will be
2773 transmitted to USB device or received from USB device.
2774 DataLength - Indicates the size, in bytes, of the data buffer
2776 Translator - A pointr to the transaction translator data.
2777 TransferResult - A pointer to the detailed result information generated
2778 by this control transfer.
2786 return EFI_UNSUPPORTED
;
2791 EhciAsyncIsochronousTransfer (
2792 IN EFI_USB2_HC_PROTOCOL
*This
,
2793 IN UINT8 DeviceAddress
,
2794 IN UINT8 EndPointAddress
,
2795 IN UINT8 DeviceSpeed
,
2796 IN UINTN MaximumPacketLength
,
2797 IN UINT8 DataBuffersNumber
,
2798 IN OUT VOID
*Data
[EFI_USB_MAX_ISO_BUFFER_NUM
],
2799 IN UINTN DataLength
,
2800 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
2801 IN EFI_ASYNC_USB_TRANSFER_CALLBACK IsochronousCallBack
,
2806 Routine Description:
2808 Submits Async isochronous transfer to a target USB device.
2812 This - A pointer to the EFI_USB2_HC_PROTOCOL instance.
2813 DeviceAddress - Represents the address of the target device on the USB,
2814 which is assigned during USB enumeration.
2815 EndPointAddress - End point address
2816 DeviceSpeed - Indicates device speed.
2817 MaximumPacketLength - Indicates the maximum packet size that the
2818 default control transfer endpoint is capable of
2819 sending or receiving.
2820 DataBuffersNumber - Number of data buffers prepared for the transfer.
2821 Data - Array of pointers to the buffers of data that will be transmitted
2822 to USB device or received from USB device.
2823 Translator - A pointr to the transaction translator data.
2824 IsochronousCallBack - When the transfer complete, the call back function will be called
2825 Context - Pass to the call back function as parameter
2833 return EFI_UNSUPPORTED
;