3 The UHCI driver model and HC protocol routines.
5 Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
13 EFI_DRIVER_BINDING_PROTOCOL gUhciDriverBinding
= {
14 UhciDriverBindingSupported
,
15 UhciDriverBindingStart
,
16 UhciDriverBindingStop
,
23 Provides software reset for the USB host controller according to UEFI 2.0 spec.
25 @param This A pointer to the EFI_USB2_HC_PROTOCOL instance.
26 @param Attributes A bit mask of the reset operation to perform. See
27 below for a list of the supported bit mask values.
29 @return EFI_SUCCESS The reset operation succeeded.
30 @return EFI_INVALID_PARAMETER Attributes is not valid.
31 @return EFI_UNSUPPORTED This type of reset is not currently supported.
32 @return EFI_DEVICE_ERROR Other errors.
38 IN EFI_USB2_HC_PROTOCOL
*This
,
45 if ((Attributes
== EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG
) ||
46 (Attributes
== EFI_USB_HC_RESET_HOST_WITH_DEBUG
)) {
47 return EFI_UNSUPPORTED
;
50 Uhc
= UHC_FROM_USB2_HC_PROTO (This
);
52 if (Uhc
->DevicePath
!= NULL
) {
54 // Report Status Code to indicate reset happens
56 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
58 (EFI_IO_BUS_USB
| EFI_IOB_PC_RESET
),
63 OldTpl
= gBS
->RaiseTPL (UHCI_TPL
);
66 case EFI_USB_HC_RESET_GLOBAL
:
68 // Stop schedule and set the Global Reset bit in the command register
70 UhciStopHc (Uhc
, UHC_GENERIC_TIMEOUT
);
71 UhciSetRegBit (Uhc
->PciIo
, USBCMD_OFFSET
, USBCMD_GRESET
);
73 gBS
->Stall (UHC_ROOT_PORT_RESET_STALL
);
76 // Clear the Global Reset bit to zero.
78 UhciClearRegBit (Uhc
->PciIo
, USBCMD_OFFSET
, USBCMD_GRESET
);
80 gBS
->Stall (UHC_ROOT_PORT_RECOVERY_STALL
);
83 case EFI_USB_HC_RESET_HOST_CONTROLLER
:
85 // Stop schedule and set Host Controller Reset bit to 1
87 UhciStopHc (Uhc
, UHC_GENERIC_TIMEOUT
);
88 UhciSetRegBit (Uhc
->PciIo
, USBCMD_OFFSET
, USBCMD_HCRESET
);
90 gBS
->Stall (UHC_ROOT_PORT_RECOVERY_STALL
);
94 goto ON_INVAILD_PARAMETER
;
98 // Delete all old transactions on the USB bus, then
99 // reinitialize the frame list
101 UhciFreeAllAsyncReq (Uhc
);
102 UhciDestoryFrameList (Uhc
);
103 UhciInitFrameList (Uhc
);
105 gBS
->RestoreTPL (OldTpl
);
109 ON_INVAILD_PARAMETER
:
111 gBS
->RestoreTPL (OldTpl
);
113 return EFI_INVALID_PARAMETER
;
118 Retrieves current state of the USB host controller according to UEFI 2.0 spec.
120 @param This A pointer to the EFI_USB2_HC_PROTOCOL instance.
121 @param State Variable to receive current device state.
123 @return EFI_SUCCESS The state is returned.
124 @return EFI_INVALID_PARAMETER State is not valid.
125 @return EFI_DEVICE_ERROR Other errors.
131 IN EFI_USB2_HC_PROTOCOL
*This
,
132 OUT EFI_USB_HC_STATE
*State
140 return EFI_INVALID_PARAMETER
;
143 Uhc
= UHC_FROM_USB2_HC_PROTO (This
);
145 UsbCmd
= UhciReadReg (Uhc
->PciIo
, USBCMD_OFFSET
);
146 UsbSts
= UhciReadReg (Uhc
->PciIo
, USBSTS_OFFSET
);
148 if ((UsbCmd
& USBCMD_EGSM
) !=0 ) {
149 *State
= EfiUsbHcStateSuspend
;
151 } else if ((UsbSts
& USBSTS_HCH
) != 0) {
152 *State
= EfiUsbHcStateHalt
;
155 *State
= EfiUsbHcStateOperational
;
163 Sets the USB host controller to a specific state according to UEFI 2.0 spec.
165 @param This A pointer to the EFI_USB2_HC_PROTOCOL instance.
166 @param State Indicates the state of the host controller that will
169 @return EFI_SUCCESS Host controller was successfully placed in the state.
170 @return EFI_INVALID_PARAMETER State is invalid.
171 @return EFI_DEVICE_ERROR Failed to set the state.
177 IN EFI_USB2_HC_PROTOCOL
*This
,
178 IN EFI_USB_HC_STATE State
181 EFI_USB_HC_STATE CurState
;
187 Uhc
= UHC_FROM_USB2_HC_PROTO (This
);
188 Status
= Uhci2GetState (This
, &CurState
);
190 if (EFI_ERROR (Status
)) {
191 return EFI_DEVICE_ERROR
;
194 if (CurState
== State
) {
198 Status
= EFI_SUCCESS
;
199 OldTpl
= gBS
->RaiseTPL (UHCI_TPL
);
202 case EfiUsbHcStateHalt
:
203 Status
= UhciStopHc (Uhc
, UHC_GENERIC_TIMEOUT
);
206 case EfiUsbHcStateOperational
:
207 UsbCmd
= UhciReadReg (Uhc
->PciIo
, USBCMD_OFFSET
);
209 if (CurState
== EfiUsbHcStateHalt
) {
211 // Set Run/Stop bit to 1, also set the bandwidht reclamation
214 UsbCmd
|= USBCMD_RS
| USBCMD_MAXP
;
215 UhciWriteReg (Uhc
->PciIo
, USBCMD_OFFSET
, UsbCmd
);
217 } else if (CurState
== EfiUsbHcStateSuspend
) {
219 // If FGR(Force Global Resume) bit is 0, set it
221 if ((UsbCmd
& USBCMD_FGR
) == 0) {
222 UsbCmd
|= USBCMD_FGR
;
223 UhciWriteReg (Uhc
->PciIo
, USBCMD_OFFSET
, UsbCmd
);
227 // wait 20ms to let resume complete (20ms is specified by UHCI spec)
229 gBS
->Stall (UHC_FORCE_GLOBAL_RESUME_STALL
);
232 // Write FGR bit to 0 and EGSM(Enter Global Suspend Mode) bit to 0
234 UsbCmd
&= ~USBCMD_FGR
;
235 UsbCmd
&= ~USBCMD_EGSM
;
237 UhciWriteReg (Uhc
->PciIo
, USBCMD_OFFSET
, UsbCmd
);
242 case EfiUsbHcStateSuspend
:
243 Status
= Uhci2SetState (This
, EfiUsbHcStateHalt
);
245 if (EFI_ERROR (Status
)) {
246 Status
= EFI_DEVICE_ERROR
;
251 // Set Enter Global Suspend Mode bit to 1.
253 UsbCmd
= UhciReadReg (Uhc
->PciIo
, USBCMD_OFFSET
);
254 UsbCmd
|= USBCMD_EGSM
;
255 UhciWriteReg (Uhc
->PciIo
, USBCMD_OFFSET
, UsbCmd
);
259 Status
= EFI_INVALID_PARAMETER
;
264 gBS
->RestoreTPL (OldTpl
);
269 Retrieves capabilities of USB host controller according to UEFI 2.0 spec.
271 @param This A pointer to the EFI_USB2_HC_PROTOCOL instance.
272 @param MaxSpeed A pointer to the max speed USB host controller
274 @param PortNumber A pointer to the number of root hub ports.
275 @param Is64BitCapable A pointer to an integer to show whether USB host
276 controller supports 64-bit memory addressing.
278 @return EFI_SUCCESS capabilities were retrieved successfully.
279 @return EFI_INVALID_PARAMETER MaxSpeed or PortNumber or Is64BitCapable is NULL.
280 @return EFI_DEVICE_ERROR An error was encountered.
286 IN EFI_USB2_HC_PROTOCOL
*This
,
288 OUT UINT8
*PortNumber
,
289 OUT UINT8
*Is64BitCapable
297 Uhc
= UHC_FROM_USB2_HC_PROTO (This
);
299 if ((NULL
== MaxSpeed
) || (NULL
== PortNumber
) || (NULL
== Is64BitCapable
)) {
300 return EFI_INVALID_PARAMETER
;
303 *MaxSpeed
= EFI_USB_SPEED_FULL
;
304 *Is64BitCapable
= (UINT8
) FALSE
;
308 for (Index
= 0; Index
< USB_MAX_ROOTHUB_PORT
; Index
++) {
309 Offset
= USBPORTSC_OFFSET
+ Index
* 2;
310 PortSC
= UhciReadReg (Uhc
->PciIo
, Offset
);
313 // Port status's bit 7 is reserved and always returns 1 if
314 // the port number is valid. Intel's UHCI (in EHCI controller)
315 // returns 0 in this bit if port number is invalid. Also, if
316 // PciIo IoRead returns error, 0xFFFF is returned to caller.
318 if (((PortSC
& 0x80) == 0) || (PortSC
== 0xFFFF)) {
324 Uhc
->RootPorts
= *PortNumber
;
326 DEBUG ((EFI_D_INFO
, "Uhci2GetCapability: %d ports\n", (UINT32
)Uhc
->RootPorts
));
332 Retrieves the current status of a USB root hub port according to UEFI 2.0 spec.
334 @param This A pointer to the EFI_USB2_HC_PROTOCOL.
335 @param PortNumber The port to get status.
336 @param PortStatus A pointer to the current port status bits and port
339 @return EFI_SUCCESS status of the USB root hub port was returned in PortStatus.
340 @return EFI_INVALID_PARAMETER PortNumber is invalid.
341 @return EFI_DEVICE_ERROR Can't read register.
346 Uhci2GetRootHubPortStatus (
347 IN EFI_USB2_HC_PROTOCOL
*This
,
349 OUT EFI_USB_PORT_STATUS
*PortStatus
356 Uhc
= UHC_FROM_USB2_HC_PROTO (This
);
358 if (PortStatus
== NULL
) {
359 return EFI_INVALID_PARAMETER
;
362 if (PortNumber
>= Uhc
->RootPorts
) {
363 return EFI_INVALID_PARAMETER
;
366 Offset
= USBPORTSC_OFFSET
+ PortNumber
* 2;
367 PortStatus
->PortStatus
= 0;
368 PortStatus
->PortChangeStatus
= 0;
370 PortSC
= UhciReadReg (Uhc
->PciIo
, Offset
);
372 if ((PortSC
& USBPORTSC_CCS
) != 0) {
373 PortStatus
->PortStatus
|= USB_PORT_STAT_CONNECTION
;
376 if ((PortSC
& USBPORTSC_PED
) != 0) {
377 PortStatus
->PortStatus
|= USB_PORT_STAT_ENABLE
;
380 if ((PortSC
& USBPORTSC_SUSP
) != 0) {
381 DEBUG ((EFI_D_INFO
, "Uhci2GetRootHubPortStatus: port %d is suspended\n", PortNumber
));
382 PortStatus
->PortStatus
|= USB_PORT_STAT_SUSPEND
;
385 if ((PortSC
& USBPORTSC_PR
) != 0) {
386 PortStatus
->PortStatus
|= USB_PORT_STAT_RESET
;
389 if ((PortSC
& USBPORTSC_LSDA
) != 0) {
390 PortStatus
->PortStatus
|= USB_PORT_STAT_LOW_SPEED
;
394 // CHC will always return one in port owner bit
396 PortStatus
->PortStatus
|= USB_PORT_STAT_OWNER
;
398 if ((PortSC
& USBPORTSC_CSC
) != 0) {
399 PortStatus
->PortChangeStatus
|= USB_PORT_STAT_C_CONNECTION
;
402 if ((PortSC
& USBPORTSC_PEDC
) != 0) {
403 PortStatus
->PortChangeStatus
|= USB_PORT_STAT_C_ENABLE
;
411 Sets a feature for the specified root hub port according to UEFI 2.0 spec.
413 @param This A pointer to the EFI_USB2_HC_PROTOCOL.
414 @param PortNumber Specifies the root hub port whose feature is
416 @param PortFeature Indicates the feature selector associated with the
419 @return EFI_SUCCESS PortFeature was set for the root port.
420 @return EFI_INVALID_PARAMETER PortNumber is invalid or PortFeature is invalid.
421 @return EFI_DEVICE_ERROR Can't read register.
426 Uhci2SetRootHubPortFeature (
427 IN EFI_USB2_HC_PROTOCOL
*This
,
429 IN EFI_USB_PORT_FEATURE PortFeature
438 Uhc
= UHC_FROM_USB2_HC_PROTO (This
);
440 if (PortNumber
>= Uhc
->RootPorts
) {
441 return EFI_INVALID_PARAMETER
;
444 Offset
= USBPORTSC_OFFSET
+ PortNumber
* 2;
446 OldTpl
= gBS
->RaiseTPL (UHCI_TPL
);
447 PortSC
= UhciReadReg (Uhc
->PciIo
, Offset
);
449 switch (PortFeature
) {
450 case EfiUsbPortSuspend
:
451 Command
= UhciReadReg (Uhc
->PciIo
, USBCMD_OFFSET
);
452 if ((Command
& USBCMD_EGSM
) == 0) {
454 // if global suspend is not active, can set port suspend
457 PortSC
|= USBPORTSC_SUSP
;
461 case EfiUsbPortReset
:
463 PortSC
|= USBPORTSC_PR
;
466 case EfiUsbPortPower
:
472 case EfiUsbPortEnable
:
474 PortSC
|= USBPORTSC_PED
;
478 gBS
->RestoreTPL (OldTpl
);
479 return EFI_INVALID_PARAMETER
;
482 UhciWriteReg (Uhc
->PciIo
, Offset
, PortSC
);
483 gBS
->RestoreTPL (OldTpl
);
490 Clears a feature for the specified root hub port according to Uefi 2.0 spec.
492 @param This A pointer to the EFI_USB2_HC_PROTOCOL instance.
493 @param PortNumber Specifies the root hub port whose feature is
494 requested to be cleared.
495 @param PortFeature Indicates the feature selector associated with the
496 feature clear request.
498 @return EFI_SUCCESS PortFeature was cleared for the USB root hub port.
499 @return EFI_INVALID_PARAMETER PortNumber is invalid or PortFeature is invalid.
500 @return EFI_DEVICE_ERROR Can't read register.
505 Uhci2ClearRootHubPortFeature (
506 IN EFI_USB2_HC_PROTOCOL
*This
,
508 IN EFI_USB_PORT_FEATURE PortFeature
516 Uhc
= UHC_FROM_USB2_HC_PROTO (This
);
518 if (PortNumber
>= Uhc
->RootPorts
) {
519 return EFI_INVALID_PARAMETER
;
522 Offset
= USBPORTSC_OFFSET
+ PortNumber
* 2;
524 OldTpl
= gBS
->RaiseTPL (UHCI_TPL
);
525 PortSC
= UhciReadReg (Uhc
->PciIo
, Offset
);
527 switch (PortFeature
) {
528 case EfiUsbPortEnable
:
530 PortSC
&= ~USBPORTSC_PED
;
533 case EfiUsbPortSuspend
:
535 // Cause a resume on the specified port if in suspend mode.
538 PortSC
&= ~USBPORTSC_SUSP
;
541 case EfiUsbPortPower
:
547 case EfiUsbPortReset
:
549 PortSC
&= ~USBPORTSC_PR
;
552 case EfiUsbPortConnectChange
:
554 PortSC
|= USBPORTSC_CSC
;
557 case EfiUsbPortEnableChange
:
559 PortSC
|= USBPORTSC_PEDC
;
562 case EfiUsbPortSuspendChange
:
564 // Root hub does not support this
568 case EfiUsbPortOverCurrentChange
:
570 // Root hub does not support this
574 case EfiUsbPortResetChange
:
576 // Root hub does not support this
581 gBS
->RestoreTPL (OldTpl
);
582 return EFI_INVALID_PARAMETER
;
585 UhciWriteReg (Uhc
->PciIo
, Offset
, PortSC
);
586 gBS
->RestoreTPL (OldTpl
);
593 Submits control transfer to a target USB device according to UEFI 2.0 spec.
595 @param This A pointer to the EFI_USB2_HC_PROTOCOL instance.
596 @param DeviceAddress Target device address.
597 @param DeviceSpeed Device speed.
598 @param MaximumPacketLength Maximum packet size of the target endpoint.
599 @param Request USB device request to send.
600 @param TransferDirection Data direction of the Data stage in control transfer.
601 @param Data Data to transmit/receive in data stage.
602 @param DataLength Length of the data.
603 @param TimeOut Maximum time, in microseconds, for transfer to complete.
604 @param Translator Transaction translator to be used by this device.
605 @param TransferResult Variable to receive the transfer result.
607 @return EFI_SUCCESS The control transfer was completed successfully.
608 @return EFI_OUT_OF_RESOURCES Failed due to lack of resource.
609 @return EFI_INVALID_PARAMETER Some parameters are invalid.
610 @return EFI_TIMEOUT Failed due to timeout.
611 @return EFI_DEVICE_ERROR Failed due to host controller or device error.
616 Uhci2ControlTransfer (
617 IN EFI_USB2_HC_PROTOCOL
*This
,
618 IN UINT8 DeviceAddress
,
619 IN UINT8 DeviceSpeed
,
620 IN UINTN MaximumPacketLength
,
621 IN EFI_USB_DEVICE_REQUEST
*Request
,
622 IN EFI_USB_DATA_DIRECTION TransferDirection
,
624 IN OUT UINTN
*DataLength
,
626 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
627 OUT UINT32
*TransferResult
634 UHCI_QH_RESULT QhResult
;
640 BOOLEAN IsSlowDevice
;
641 UINTN TransferDataLength
;
643 Uhc
= UHC_FROM_USB2_HC_PROTO (This
);
650 IsSlowDevice
= (BOOLEAN
) ((EFI_USB_SPEED_LOW
== DeviceSpeed
) ? TRUE
: FALSE
);
653 // Parameters Checking
655 if (Request
== NULL
|| TransferResult
== NULL
) {
656 return EFI_INVALID_PARAMETER
;
659 if (IsSlowDevice
&& (MaximumPacketLength
!= 8)) {
660 return EFI_INVALID_PARAMETER
;
663 if ((MaximumPacketLength
!= 8) && (MaximumPacketLength
!= 16) &&
664 (MaximumPacketLength
!= 32) && (MaximumPacketLength
!= 64)) {
666 return EFI_INVALID_PARAMETER
;
669 if ((TransferDirection
!= EfiUsbNoData
) && (Data
== NULL
|| DataLength
== NULL
)) {
670 return EFI_INVALID_PARAMETER
;
673 if (TransferDirection
== EfiUsbNoData
) {
674 TransferDataLength
= 0;
676 TransferDataLength
= *DataLength
;
679 *TransferResult
= EFI_USB_ERR_SYSTEM
;
680 Status
= EFI_DEVICE_ERROR
;
683 // If errors exist that cause host controller halt,
684 // clear status then return EFI_DEVICE_ERROR.
686 UhciAckAllInterrupt (Uhc
);
688 if (!UhciIsHcWorking (Uhc
->PciIo
)) {
689 return EFI_DEVICE_ERROR
;
692 OldTpl
= gBS
->RaiseTPL (UHCI_TPL
);
695 // Map the Request and data for bus master access,
696 // then create a list of TD for this transfer
698 Status
= UhciMapUserRequest (Uhc
, Request
, &RequestPhy
, &RequestMap
);
700 if (EFI_ERROR (Status
)) {
704 Status
= UhciMapUserData (Uhc
, TransferDirection
, Data
, DataLength
, &PktId
, &DataPhy
, &DataMap
);
706 if (EFI_ERROR (Status
)) {
707 Uhc
->PciIo
->Unmap (Uhc
->PciIo
, RequestMap
);
711 TDs
= UhciCreateCtrlTds (
720 (UINT8
) MaximumPacketLength
,
725 Status
= EFI_OUT_OF_RESOURCES
;
730 // According to the speed of the end point, link
731 // the TD to corrosponding queue head, then check
732 // the execution result
734 UhciLinkTdToQh (Uhc
, Uhc
->CtrlQh
, TDs
);
735 Status
= UhciExecuteTransfer (Uhc
, Uhc
->CtrlQh
, TDs
, TimeOut
, IsSlowDevice
, &QhResult
);
736 UhciUnlinkTdFromQh (Uhc
->CtrlQh
, TDs
);
738 Uhc
->PciIo
->Flush (Uhc
->PciIo
);
740 *TransferResult
= QhResult
.Result
;
742 if (DataLength
!= NULL
) {
743 *DataLength
= QhResult
.Complete
;
746 UhciDestoryTds (Uhc
, TDs
);
749 Uhc
->PciIo
->Unmap (Uhc
->PciIo
, DataMap
);
750 Uhc
->PciIo
->Unmap (Uhc
->PciIo
, RequestMap
);
753 gBS
->RestoreTPL (OldTpl
);
759 Submits bulk transfer to a bulk endpoint of a USB device.
761 @param This A pointer to the EFI_USB2_HC_PROTOCOL instance.
762 @param DeviceAddress Target device address.
763 @param EndPointAddress Endpoint number and direction.
764 @param DeviceSpeed Device speed.
765 @param MaximumPacketLength Maximum packet size of the target endpoint.
766 @param DataBuffersNumber Number of data buffers prepared for the transfer.
767 @param Data Array of pointers to the buffers of data.
768 @param DataLength On input, size of the data buffer, On output,
769 actually transferred data size.
770 @param DataToggle On input, data toggle to use; On output, next data toggle.
771 @param TimeOut Maximum time out, in microseconds.
772 @param Translator A pointr to the transaction translator data.
773 @param TransferResult Variable to receive transfer result.
775 @return EFI_SUCCESS The bulk transfer was completed successfully.
776 @return EFI_OUT_OF_RESOURCES Failed due to lack of resource.
777 @return EFI_INVALID_PARAMETER Some parameters are invalid.
778 @return EFI_TIMEOUT Failed due to timeout.
779 @return EFI_DEVICE_ERROR Failed due to host controller or device error.
785 IN EFI_USB2_HC_PROTOCOL
*This
,
786 IN UINT8 DeviceAddress
,
787 IN UINT8 EndPointAddress
,
788 IN UINT8 DeviceSpeed
,
789 IN UINTN MaximumPacketLength
,
790 IN UINT8 DataBuffersNumber
,
791 IN OUT VOID
*Data
[EFI_USB_MAX_BULK_BUFFER_NUM
],
792 IN OUT UINTN
*DataLength
,
793 IN OUT UINT8
*DataToggle
,
795 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
796 OUT UINT32
*TransferResult
799 EFI_USB_DATA_DIRECTION Direction
;
804 UHCI_QH_RESULT QhResult
;
810 Uhc
= UHC_FROM_USB2_HC_PROTO (This
);
814 if (DeviceSpeed
== EFI_USB_SPEED_LOW
) {
815 return EFI_INVALID_PARAMETER
;
818 if ((DataLength
== NULL
) || (*DataLength
== 0) || (Data
== NULL
) || (TransferResult
== NULL
)) {
819 return EFI_INVALID_PARAMETER
;
822 if ((*DataToggle
!= 1) && (*DataToggle
!= 0)) {
823 return EFI_INVALID_PARAMETER
;
826 if ((MaximumPacketLength
!= 8) && (MaximumPacketLength
!= 16) &&
827 (MaximumPacketLength
!= 32) && (MaximumPacketLength
!= 64)) {
828 return EFI_INVALID_PARAMETER
;
831 *TransferResult
= EFI_USB_ERR_SYSTEM
;
832 Status
= EFI_OUT_OF_RESOURCES
;
835 // If has errors that cause host controller halt,
836 // then return EFI_DEVICE_ERROR directly.
838 UhciAckAllInterrupt (Uhc
);
840 if (!UhciIsHcWorking (Uhc
->PciIo
)) {
841 return EFI_DEVICE_ERROR
;
844 OldTpl
= gBS
->RaiseTPL (UHCI_TPL
);
847 // Map the source data buffer for bus master access,
848 // then create a list of TDs
850 if ((EndPointAddress
& 0x80) != 0) {
851 Direction
= EfiUsbDataIn
;
853 Direction
= EfiUsbDataOut
;
856 Status
= UhciMapUserData (Uhc
, Direction
, *Data
, DataLength
, &PktId
, &DataPhy
, &DataMap
);
858 if (EFI_ERROR (Status
)) {
862 Status
= EFI_OUT_OF_RESOURCES
;
863 TDs
= UhciCreateBulkOrIntTds (
872 (UINT8
) MaximumPacketLength
,
877 Uhc
->PciIo
->Unmap (Uhc
->PciIo
, DataMap
);
883 // Link the TDs to bulk queue head. According to the platfore
884 // defintion of UHCI_NO_BW_RECLAMATION, BulkQh is either configured
885 // to do full speed bandwidth reclamation or not.
887 BulkQh
= Uhc
->BulkQh
;
889 UhciLinkTdToQh (Uhc
, BulkQh
, TDs
);
890 Status
= UhciExecuteTransfer (Uhc
, BulkQh
, TDs
, TimeOut
, FALSE
, &QhResult
);
891 UhciUnlinkTdFromQh (BulkQh
, TDs
);
893 Uhc
->PciIo
->Flush (Uhc
->PciIo
);
895 *TransferResult
= QhResult
.Result
;
896 *DataToggle
= QhResult
.NextToggle
;
897 *DataLength
= QhResult
.Complete
;
899 UhciDestoryTds (Uhc
, TDs
);
900 Uhc
->PciIo
->Unmap (Uhc
->PciIo
, DataMap
);
903 gBS
->RestoreTPL (OldTpl
);
909 Submits an asynchronous interrupt transfer to an
910 interrupt endpoint of a USB device according to UEFI 2.0 spec.
912 @param This A pointer to the EFI_USB2_HC_PROTOCOL instance.
913 @param DeviceAddress Target device address.
914 @param EndPointAddress Endpoint number and direction.
915 @param DeviceSpeed Device speed.
916 @param MaximumPacketLength Maximum packet size of the target endpoint.
917 @param IsNewTransfer If TRUE, submit a new transfer, if FALSE cancel old transfer.
918 @param DataToggle On input, data toggle to use; On output, next data toggle.
919 @param PollingInterval Interrupt poll rate in milliseconds.
920 @param DataLength On input, size of the data buffer, On output,
921 actually transferred data size.
922 @param Translator A pointr to the transaction translator data.
923 @param CallBackFunction Function to call periodically.
924 @param Context User context.
926 @return EFI_SUCCESS Transfer was submitted.
927 @return EFI_INVALID_PARAMETER Some parameters are invalid.
928 @return EFI_OUT_OF_RESOURCES Failed due to a lack of resources.
929 @return EFI_DEVICE_ERROR Can't read register.
934 Uhci2AsyncInterruptTransfer (
935 IN EFI_USB2_HC_PROTOCOL
*This
,
936 IN UINT8 DeviceAddress
,
937 IN UINT8 EndPointAddress
,
938 IN UINT8 DeviceSpeed
,
939 IN UINTN MaximumPacketLength
,
940 IN BOOLEAN IsNewTransfer
,
941 IN OUT UINT8
*DataToggle
,
942 IN UINTN PollingInterval
,
944 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
945 IN EFI_ASYNC_USB_TRANSFER_CALLBACK CallBackFunction
,
950 BOOLEAN IsSlowDevice
;
959 Uhc
= UHC_FROM_USB2_HC_PROTO (This
);
965 IsSlowDevice
= (BOOLEAN
) ((EFI_USB_SPEED_LOW
== DeviceSpeed
) ? TRUE
: FALSE
);
967 if ((EndPointAddress
& 0x80) == 0) {
968 return EFI_INVALID_PARAMETER
;
972 // Delete Async interrupt transfer request
974 if (!IsNewTransfer
) {
975 OldTpl
= gBS
->RaiseTPL (UHCI_TPL
);
976 Status
= UhciRemoveAsyncReq (Uhc
, DeviceAddress
, EndPointAddress
, DataToggle
);
978 gBS
->RestoreTPL (OldTpl
);
982 if (PollingInterval
< 1 || PollingInterval
> 255) {
983 return EFI_INVALID_PARAMETER
;
986 if (DataLength
== 0) {
987 return EFI_INVALID_PARAMETER
;
990 if ((*DataToggle
!= 1) && (*DataToggle
!= 0)) {
991 return EFI_INVALID_PARAMETER
;
995 // If has errors that cause host controller halt,
996 // then return EFI_DEVICE_ERROR directly.
998 UhciAckAllInterrupt (Uhc
);
1000 if (!UhciIsHcWorking (Uhc
->PciIo
)) {
1001 return EFI_DEVICE_ERROR
;
1004 if ((EndPointAddress
& 0x80) == 0) {
1005 PktId
= OUTPUT_PACKET_ID
;
1007 PktId
= INPUT_PACKET_ID
;
1011 // Allocate and map source data buffer for bus master access.
1013 DataPtr
= UsbHcAllocateMem (Uhc
->MemPool
, DataLength
);
1015 if (DataPtr
== NULL
) {
1016 return EFI_OUT_OF_RESOURCES
;
1019 DataPhy
= (UINT8
*) (UINTN
) UsbHcGetPciAddressForHostMem (Uhc
->MemPool
, DataPtr
, DataLength
);
1021 OldTpl
= gBS
->RaiseTPL (UHCI_TPL
);
1023 Qh
= UhciCreateQh (Uhc
, PollingInterval
);
1026 Status
= EFI_OUT_OF_RESOURCES
;
1030 IntTds
= UhciCreateBulkOrIntTds (
1039 (UINT8
) MaximumPacketLength
,
1043 if (IntTds
== NULL
) {
1044 Status
= EFI_OUT_OF_RESOURCES
;
1048 UhciLinkTdToQh (Uhc
, Qh
, IntTds
);
1051 // Save QH-TD structures to async Interrupt transfer list,
1052 // for monitor interrupt transfer execution routine use.
1054 Status
= UhciCreateAsyncReq (
1068 if (EFI_ERROR (Status
)) {
1072 UhciLinkQhToFrameList (Uhc
, Qh
);
1074 gBS
->RestoreTPL (OldTpl
);
1078 UsbHcFreeMem (Uhc
->MemPool
, Qh
, sizeof (UHCI_QH_SW
));
1081 UsbHcFreeMem (Uhc
->MemPool
, DataPtr
, DataLength
);
1082 Uhc
->PciIo
->Flush (Uhc
->PciIo
);
1084 gBS
->RestoreTPL (OldTpl
);
1089 Submits synchronous interrupt transfer to an interrupt endpoint
1090 of a USB device according to UEFI 2.0 spec.
1093 @param This A pointer to the EFI_USB2_HC_PROTOCOL instance.
1094 @param DeviceAddress Target device address.
1095 @param EndPointAddress Endpoint number and direction.
1096 @param DeviceSpeed Device speed.
1097 @param MaximumPacketLength Maximum packet size of the target endpoint.
1098 @param Data Array of pointers to the buffers of data.
1099 @param DataLength On input, size of the data buffer, On output,
1100 actually transferred data size.
1101 @param DataToggle On input, data toggle to use; On output, next data toggle.
1102 @param TimeOut Maximum time out, in microseconds.
1103 @param Translator A pointr to the transaction translator data.
1104 @param TransferResult Variable to receive transfer result.
1106 @return EFI_SUCCESS The transfer was completed successfully.
1107 @return EFI_OUT_OF_RESOURCES Failed due to lack of resource.
1108 @return EFI_INVALID_PARAMETER Some parameters are invalid.
1109 @return EFI_TIMEOUT Failed due to timeout.
1110 @return EFI_DEVICE_ERROR Failed due to host controller or device error.
1115 Uhci2SyncInterruptTransfer (
1116 IN EFI_USB2_HC_PROTOCOL
*This
,
1117 IN UINT8 DeviceAddress
,
1118 IN UINT8 EndPointAddress
,
1119 IN UINT8 DeviceSpeed
,
1120 IN UINTN MaximumPacketLength
,
1122 IN OUT UINTN
*DataLength
,
1123 IN OUT UINT8
*DataToggle
,
1125 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
1126 OUT UINT32
*TransferResult
1132 UHCI_QH_RESULT QhResult
;
1137 BOOLEAN IsSlowDevice
;
1139 Uhc
= UHC_FROM_USB2_HC_PROTO (This
);
1144 if (DeviceSpeed
== EFI_USB_SPEED_HIGH
) {
1145 return EFI_INVALID_PARAMETER
;
1148 IsSlowDevice
= (BOOLEAN
) ((EFI_USB_SPEED_LOW
== DeviceSpeed
) ? TRUE
: FALSE
);
1150 if ((DataLength
== NULL
) || (Data
== NULL
) || (TransferResult
== NULL
)) {
1151 return EFI_INVALID_PARAMETER
;
1154 if ((*DataToggle
!= 1) && (*DataToggle
!= 0)) {
1155 return EFI_INVALID_PARAMETER
;
1158 if ((*DataLength
== 0) || (MaximumPacketLength
> 64)) {
1159 return EFI_INVALID_PARAMETER
;
1162 if (IsSlowDevice
&& (MaximumPacketLength
> 8)) {
1163 return EFI_INVALID_PARAMETER
;
1166 *TransferResult
= EFI_USB_ERR_SYSTEM
;
1167 Status
= EFI_DEVICE_ERROR
;
1170 UhciAckAllInterrupt (Uhc
);
1172 if (!UhciIsHcWorking (Uhc
->PciIo
)) {
1176 OldTpl
= gBS
->RaiseTPL (UHCI_TPL
);
1179 // Map the source data buffer for bus master access.
1180 // Create Tds list, then link it to the UHC's interrupt list
1182 Status
= UhciMapUserData (
1192 if (EFI_ERROR (Status
)) {
1196 TDs
= UhciCreateBulkOrIntTds (
1205 (UINT8
) MaximumPacketLength
,
1210 Uhc
->PciIo
->Unmap (Uhc
->PciIo
, DataMap
);
1212 Status
= EFI_OUT_OF_RESOURCES
;
1217 UhciLinkTdToQh (Uhc
, Uhc
->SyncIntQh
, TDs
);
1219 Status
= UhciExecuteTransfer (Uhc
, Uhc
->SyncIntQh
, TDs
, TimeOut
, IsSlowDevice
, &QhResult
);
1221 UhciUnlinkTdFromQh (Uhc
->SyncIntQh
, TDs
);
1222 Uhc
->PciIo
->Flush (Uhc
->PciIo
);
1224 *TransferResult
= QhResult
.Result
;
1225 *DataToggle
= QhResult
.NextToggle
;
1226 *DataLength
= QhResult
.Complete
;
1228 UhciDestoryTds (Uhc
, TDs
);
1229 Uhc
->PciIo
->Unmap (Uhc
->PciIo
, DataMap
);
1232 gBS
->RestoreTPL (OldTpl
);
1238 Submits isochronous transfer to a target USB device according to UEFI 2.0 spec.
1240 @param This A pointer to the EFI_USB2_HC_PROTOCOL instance.
1241 @param DeviceAddress Target device address.
1242 @param EndPointAddress Endpoint number and direction.
1243 @param DeviceSpeed Device speed.
1244 @param MaximumPacketLength Maximum packet size of the target endpoint.
1245 @param DataBuffersNumber Number of data buffers prepared for the transfer.
1246 @param Data Array of pointers to the buffers of data.
1247 @param DataLength On input, size of the data buffer, On output,
1248 actually transferred data size.
1249 @param Translator A pointr to the transaction translator data.
1250 @param TransferResult Variable to receive transfer result.
1252 @return EFI_UNSUPPORTED
1257 Uhci2IsochronousTransfer (
1258 IN EFI_USB2_HC_PROTOCOL
*This
,
1259 IN UINT8 DeviceAddress
,
1260 IN UINT8 EndPointAddress
,
1261 IN UINT8 DeviceSpeed
,
1262 IN UINTN MaximumPacketLength
,
1263 IN UINT8 DataBuffersNumber
,
1264 IN OUT VOID
*Data
[EFI_USB_MAX_ISO_BUFFER_NUM
],
1265 IN UINTN DataLength
,
1266 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
1267 OUT UINT32
*TransferResult
1270 return EFI_UNSUPPORTED
;
1275 Submits Async isochronous transfer to a target USB device according to UEFI 2.0 spec.
1277 @param This A pointer to the EFI_USB2_HC_PROTOCOL instance.
1278 @param DeviceAddress Target device address.
1279 @param EndPointAddress Endpoint number and direction.
1280 @param DeviceSpeed Device speed.
1281 @param MaximumPacketLength Maximum packet size of the target endpoint.
1282 @param DataBuffersNumber Number of data buffers prepared for the transfer.
1283 @param Data Array of pointers to the buffers of data.
1284 @param DataLength On input, size of the data buffer, On output,
1285 actually transferred data size.
1286 @param Translator A pointr to the transaction translator data.
1287 @param IsochronousCallBack Function to call when the transfer complete.
1288 @param Context Pass to the call back function as parameter.
1290 @return EFI_UNSUPPORTED
1295 Uhci2AsyncIsochronousTransfer (
1296 IN EFI_USB2_HC_PROTOCOL
*This
,
1297 IN UINT8 DeviceAddress
,
1298 IN UINT8 EndPointAddress
,
1299 IN UINT8 DeviceSpeed
,
1300 IN UINTN MaximumPacketLength
,
1301 IN UINT8 DataBuffersNumber
,
1302 IN OUT VOID
*Data
[EFI_USB_MAX_ISO_BUFFER_NUM
],
1303 IN UINTN DataLength
,
1304 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
1305 IN EFI_ASYNC_USB_TRANSFER_CALLBACK IsochronousCallBack
,
1309 return EFI_UNSUPPORTED
;
1313 Entry point for EFI drivers.
1315 @param ImageHandle EFI_HANDLE.
1316 @param SystemTable EFI_SYSTEM_TABLE.
1318 @retval EFI_SUCCESS Driver is successfully loaded.
1319 @return Others Failed.
1324 UhciDriverEntryPoint (
1325 IN EFI_HANDLE ImageHandle
,
1326 IN EFI_SYSTEM_TABLE
*SystemTable
1329 return EfiLibInstallDriverBindingComponentName2 (
1332 &gUhciDriverBinding
,
1334 &gUhciComponentName
,
1335 &gUhciComponentName2
1341 Test to see if this driver supports ControllerHandle. Any
1342 ControllerHandle that has UsbHcProtocol installed will be supported.
1344 @param This Protocol instance pointer.
1345 @param Controller Handle of device to test.
1346 @param RemainingDevicePath Not used.
1348 @return EFI_SUCCESS This driver supports this device.
1349 @return EFI_UNSUPPORTED This driver does not support this device.
1354 UhciDriverBindingSupported (
1355 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1356 IN EFI_HANDLE Controller
,
1357 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
1360 EFI_STATUS OpenStatus
;
1362 EFI_PCI_IO_PROTOCOL
*PciIo
;
1363 USB_CLASSC UsbClassCReg
;
1366 // Test whether there is PCI IO Protocol attached on the controller handle.
1368 OpenStatus
= gBS
->OpenProtocol (
1370 &gEfiPciIoProtocolGuid
,
1372 This
->DriverBindingHandle
,
1374 EFI_OPEN_PROTOCOL_BY_DRIVER
1377 if (EFI_ERROR (OpenStatus
)) {
1381 Status
= PciIo
->Pci
.Read (
1384 PCI_CLASSCODE_OFFSET
,
1385 sizeof (USB_CLASSC
) / sizeof (UINT8
),
1389 if (EFI_ERROR (Status
)) {
1390 Status
= EFI_UNSUPPORTED
;
1395 // Test whether the controller belongs to UHCI type
1397 if ((UsbClassCReg
.BaseCode
!= PCI_CLASS_SERIAL
) ||
1398 (UsbClassCReg
.SubClassCode
!= PCI_CLASS_SERIAL_USB
) ||
1399 (UsbClassCReg
.ProgInterface
!= PCI_IF_UHCI
)
1402 Status
= EFI_UNSUPPORTED
;
1406 gBS
->CloseProtocol (
1408 &gEfiPciIoProtocolGuid
,
1409 This
->DriverBindingHandle
,
1419 Allocate and initialize the empty UHCI device.
1421 @param PciIo The PCIIO to use.
1422 @param DevicePath The device path of host controller.
1423 @param OriginalPciAttributes The original PCI attributes.
1425 @return Allocated UHCI device. If err, return NULL.
1430 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
1431 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
,
1432 IN UINT64 OriginalPciAttributes
1438 Uhc
= AllocateZeroPool (sizeof (USB_HC_DEV
));
1445 // This driver supports both USB_HC_PROTOCOL and USB2_HC_PROTOCOL.
1446 // USB_HC_PROTOCOL is for EFI 1.1 backward compability.
1448 Uhc
->Signature
= USB_HC_DEV_SIGNATURE
;
1449 Uhc
->Usb2Hc
.GetCapability
= Uhci2GetCapability
;
1450 Uhc
->Usb2Hc
.Reset
= Uhci2Reset
;
1451 Uhc
->Usb2Hc
.GetState
= Uhci2GetState
;
1452 Uhc
->Usb2Hc
.SetState
= Uhci2SetState
;
1453 Uhc
->Usb2Hc
.ControlTransfer
= Uhci2ControlTransfer
;
1454 Uhc
->Usb2Hc
.BulkTransfer
= Uhci2BulkTransfer
;
1455 Uhc
->Usb2Hc
.AsyncInterruptTransfer
= Uhci2AsyncInterruptTransfer
;
1456 Uhc
->Usb2Hc
.SyncInterruptTransfer
= Uhci2SyncInterruptTransfer
;
1457 Uhc
->Usb2Hc
.IsochronousTransfer
= Uhci2IsochronousTransfer
;
1458 Uhc
->Usb2Hc
.AsyncIsochronousTransfer
= Uhci2AsyncIsochronousTransfer
;
1459 Uhc
->Usb2Hc
.GetRootHubPortStatus
= Uhci2GetRootHubPortStatus
;
1460 Uhc
->Usb2Hc
.SetRootHubPortFeature
= Uhci2SetRootHubPortFeature
;
1461 Uhc
->Usb2Hc
.ClearRootHubPortFeature
= Uhci2ClearRootHubPortFeature
;
1462 Uhc
->Usb2Hc
.MajorRevision
= 0x1;
1463 Uhc
->Usb2Hc
.MinorRevision
= 0x1;
1466 Uhc
->DevicePath
= DevicePath
;
1467 Uhc
->OriginalPciAttributes
= OriginalPciAttributes
;
1468 Uhc
->MemPool
= UsbHcInitMemPool (PciIo
, TRUE
, 0);
1470 if (Uhc
->MemPool
== NULL
) {
1471 Status
= EFI_OUT_OF_RESOURCES
;
1475 InitializeListHead (&Uhc
->AsyncIntList
);
1477 Status
= gBS
->CreateEvent (
1478 EVT_TIMER
| EVT_NOTIFY_SIGNAL
,
1480 UhciMonitorAsyncReqList
,
1482 &Uhc
->AsyncIntMonitor
1485 if (EFI_ERROR (Status
)) {
1486 UsbHcFreeMemPool (Uhc
->MemPool
);
1499 Free the UHCI device and release its associated resources.
1501 @param Uhc The UHCI device to release.
1509 if (Uhc
->AsyncIntMonitor
!= NULL
) {
1510 gBS
->CloseEvent (Uhc
->AsyncIntMonitor
);
1513 if (Uhc
->ExitBootServiceEvent
!= NULL
) {
1514 gBS
->CloseEvent (Uhc
->ExitBootServiceEvent
);
1517 if (Uhc
->MemPool
!= NULL
) {
1518 UsbHcFreeMemPool (Uhc
->MemPool
);
1521 if (Uhc
->CtrlNameTable
!= NULL
) {
1522 FreeUnicodeStringTable (Uhc
->CtrlNameTable
);
1530 Uninstall all Uhci Interface.
1532 @param Controller Controller handle.
1533 @param This Protocol instance pointer.
1538 IN EFI_HANDLE Controller
,
1539 IN EFI_USB2_HC_PROTOCOL
*This
1546 // Uninstall the USB_HC and USB_HC2 protocol, then disable the controller
1548 Uhc
= UHC_FROM_USB2_HC_PROTO (This
);
1551 Status
= gBS
->UninstallProtocolInterface (
1553 &gEfiUsb2HcProtocolGuid
,
1556 if (EFI_ERROR (Status
)) {
1560 UhciStopHc (Uhc
, UHC_GENERIC_TIMEOUT
);
1561 UhciFreeAllAsyncReq (Uhc
);
1562 UhciDestoryFrameList (Uhc
);
1565 // Restore original PCI attributes
1567 Uhc
->PciIo
->Attributes (
1569 EfiPciIoAttributeOperationSet
,
1570 Uhc
->OriginalPciAttributes
,
1578 One notified function to stop the Host Controller when gBS->ExitBootServices() called.
1580 @param Event Pointer to this event
1581 @param Context Event handler private data
1586 UhcExitBootService (
1593 Uhc
= (USB_HC_DEV
*) Context
;
1596 // Stop the Host Controller
1598 UhciStopHc (Uhc
, UHC_GENERIC_TIMEOUT
);
1601 // Reset the Host Controller
1603 UhciSetRegBit (Uhc
->PciIo
, USBCMD_OFFSET
, USBCMD_HCRESET
);
1604 gBS
->Stall (UHC_ROOT_PORT_RECOVERY_STALL
);
1608 Starting the Usb UHCI Driver.
1610 @param This Protocol instance pointer.
1611 @param Controller Handle of device to test.
1612 @param RemainingDevicePath Not used.
1614 @retval EFI_SUCCESS This driver supports this device.
1615 @retval EFI_UNSUPPORTED This driver does not support this device.
1616 @retval EFI_DEVICE_ERROR This driver cannot be started due to device Error.
1617 EFI_OUT_OF_RESOURCES- Failed due to resource shortage.
1622 UhciDriverBindingStart (
1623 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1624 IN EFI_HANDLE Controller
,
1625 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
1629 EFI_PCI_IO_PROTOCOL
*PciIo
;
1632 UINT64 OriginalPciAttributes
;
1633 BOOLEAN PciAttributesSaved
;
1634 EFI_DEVICE_PATH_PROTOCOL
*HcDevicePath
;
1637 // Open PCIIO, then enable the EHC device and turn off emulation
1640 Status
= gBS
->OpenProtocol (
1642 &gEfiPciIoProtocolGuid
,
1644 This
->DriverBindingHandle
,
1646 EFI_OPEN_PROTOCOL_BY_DRIVER
1649 if (EFI_ERROR (Status
)) {
1654 // Open Device Path Protocol for on USB host controller
1656 HcDevicePath
= NULL
;
1657 Status
= gBS
->OpenProtocol (
1659 &gEfiDevicePathProtocolGuid
,
1660 (VOID
**) &HcDevicePath
,
1661 This
->DriverBindingHandle
,
1663 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1666 PciAttributesSaved
= FALSE
;
1668 // Save original PCI attributes
1670 Status
= PciIo
->Attributes (
1672 EfiPciIoAttributeOperationGet
,
1674 &OriginalPciAttributes
1677 if (EFI_ERROR (Status
)) {
1680 PciAttributesSaved
= TRUE
;
1683 // Robustnesss improvement such as for UoL
1684 // Default is not required.
1686 if (FeaturePcdGet (PcdTurnOffUsbLegacySupport
)) {
1687 UhciTurnOffUsbEmulation (PciIo
);
1690 Status
= PciIo
->Attributes (
1692 EfiPciIoAttributeOperationSupported
,
1696 if (!EFI_ERROR (Status
)) {
1697 Supports
&= (UINT64
)EFI_PCI_DEVICE_ENABLE
;
1698 Status
= PciIo
->Attributes (
1700 EfiPciIoAttributeOperationEnable
,
1706 if (EFI_ERROR (Status
)) {
1710 Uhc
= UhciAllocateDev (PciIo
, HcDevicePath
, OriginalPciAttributes
);
1713 Status
= EFI_OUT_OF_RESOURCES
;
1718 // Allocate and Init Host Controller's Frame List Entry
1720 Status
= UhciInitFrameList (Uhc
);
1722 if (EFI_ERROR (Status
)) {
1723 Status
= EFI_OUT_OF_RESOURCES
;
1727 Status
= gBS
->SetTimer (
1728 Uhc
->AsyncIntMonitor
,
1730 UHC_ASYNC_POLL_INTERVAL
1733 if (EFI_ERROR (Status
)) {
1738 // Install USB2_HC_PROTOCOL
1740 Status
= gBS
->InstallMultipleProtocolInterfaces (
1742 &gEfiUsb2HcProtocolGuid
,
1747 if (EFI_ERROR (Status
)) {
1752 // Create event to stop the HC when exit boot service.
1754 Status
= gBS
->CreateEventEx (
1759 &gEfiEventExitBootServicesGuid
,
1760 &Uhc
->ExitBootServiceEvent
1762 if (EFI_ERROR (Status
)) {
1763 goto UNINSTALL_USBHC
;
1767 // Install the component name protocol
1769 Uhc
->CtrlNameTable
= NULL
;
1773 gUhciComponentName
.SupportedLanguages
,
1774 &Uhc
->CtrlNameTable
,
1775 L
"Usb Universal Host Controller",
1780 gUhciComponentName2
.SupportedLanguages
,
1781 &Uhc
->CtrlNameTable
,
1782 L
"Usb Universal Host Controller",
1788 // Start the UHCI hardware, also set its reclamation point to 64 bytes
1790 UhciWriteReg (Uhc
->PciIo
, USBCMD_OFFSET
, USBCMD_RS
| USBCMD_MAXP
);
1795 gBS
->UninstallMultipleProtocolInterfaces (
1797 &gEfiUsb2HcProtocolGuid
,
1806 if (PciAttributesSaved
) {
1808 // Restore original PCI attributes
1812 EfiPciIoAttributeOperationSet
,
1813 OriginalPciAttributes
,
1818 gBS
->CloseProtocol (
1820 &gEfiPciIoProtocolGuid
,
1821 This
->DriverBindingHandle
,
1830 Stop this driver on ControllerHandle. Support stopping any child handles
1831 created by this driver.
1833 @param This Protocol instance pointer.
1834 @param Controller Handle of device to stop driver on.
1835 @param NumberOfChildren Number of Children in the ChildHandleBuffer.
1836 @param ChildHandleBuffer List of handles for the children we need to stop.
1844 UhciDriverBindingStop (
1845 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1846 IN EFI_HANDLE Controller
,
1847 IN UINTN NumberOfChildren
,
1848 IN EFI_HANDLE
*ChildHandleBuffer
1851 EFI_USB2_HC_PROTOCOL
*Usb2Hc
;
1854 Status
= gBS
->OpenProtocol (
1856 &gEfiUsb2HcProtocolGuid
,
1858 This
->DriverBindingHandle
,
1860 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1864 // Test whether the Controller handler passed in is a valid
1865 // Usb controller handle that should be supported, if not,
1866 // return the error status directly
1868 if (EFI_ERROR (Status
)) {
1872 UhciCleanDevUp (Controller
, Usb2Hc
);
1874 gBS
->CloseProtocol (
1876 &gEfiPciIoProtocolGuid
,
1877 This
->DriverBindingHandle
,