3 The UHCI driver model and HC protocol routines.
5 Copyright (c) 2004 - 2010, Intel Corporation
6 All rights reserved. This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
19 EFI_DRIVER_BINDING_PROTOCOL gUhciDriverBinding
= {
20 UhciDriverBindingSupported
,
21 UhciDriverBindingStart
,
22 UhciDriverBindingStop
,
29 Provides software reset for the USB host controller according to UEFI 2.0 spec.
31 @param This A pointer to the EFI_USB2_HC_PROTOCOL instance.
32 @param Attributes A bit mask of the reset operation to perform. See
33 below for a list of the supported bit mask values.
35 @return EFI_SUCCESS The reset operation succeeded.
36 @return EFI_INVALID_PARAMETER Attributes is not valid.
37 @return EFI_UNSUPPORTED This type of reset is not currently supported.
38 @return EFI_DEVICE_ERROR Other errors.
44 IN EFI_USB2_HC_PROTOCOL
*This
,
51 if ((Attributes
== EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG
) ||
52 (Attributes
== EFI_USB_HC_RESET_HOST_WITH_DEBUG
)) {
53 return EFI_UNSUPPORTED
;
56 Uhc
= UHC_FROM_USB2_HC_PROTO (This
);
58 OldTpl
= gBS
->RaiseTPL (UHCI_TPL
);
61 case EFI_USB_HC_RESET_GLOBAL
:
63 // Stop schedule and set the Global Reset bit in the command register
65 UhciStopHc (Uhc
, UHC_GENERIC_TIMEOUT
);
66 UhciSetRegBit (Uhc
->PciIo
, USBCMD_OFFSET
, USBCMD_GRESET
);
68 gBS
->Stall (UHC_ROOT_PORT_RESET_STALL
);
71 // Clear the Global Reset bit to zero.
73 UhciClearRegBit (Uhc
->PciIo
, USBCMD_OFFSET
, USBCMD_GRESET
);
75 gBS
->Stall (UHC_ROOT_PORT_RECOVERY_STALL
);
78 case EFI_USB_HC_RESET_HOST_CONTROLLER
:
80 // Stop schedule and set Host Controller Reset bit to 1
82 UhciStopHc (Uhc
, UHC_GENERIC_TIMEOUT
);
83 UhciSetRegBit (Uhc
->PciIo
, USBCMD_OFFSET
, USBCMD_HCRESET
);
85 gBS
->Stall (UHC_ROOT_PORT_RECOVERY_STALL
);
89 goto ON_INVAILD_PARAMETER
;
93 // Delete all old transactions on the USB bus, then
94 // reinitialize the frame list
96 UhciFreeAllAsyncReq (Uhc
);
97 UhciDestoryFrameList (Uhc
);
98 UhciInitFrameList (Uhc
);
100 gBS
->RestoreTPL (OldTpl
);
104 ON_INVAILD_PARAMETER
:
106 gBS
->RestoreTPL (OldTpl
);
108 return EFI_INVALID_PARAMETER
;
113 Retrieves current state of the USB host controller according to UEFI 2.0 spec.
115 @param This A pointer to the EFI_USB2_HC_PROTOCOL instance.
116 @param State Variable to receive current device state.
118 @return EFI_SUCCESS The state is returned.
119 @return EFI_INVALID_PARAMETER State is not valid.
120 @return EFI_DEVICE_ERROR Other errors.
126 IN CONST EFI_USB2_HC_PROTOCOL
*This
,
127 OUT EFI_USB_HC_STATE
*State
135 return EFI_INVALID_PARAMETER
;
138 Uhc
= UHC_FROM_USB2_HC_PROTO (This
);
140 UsbCmd
= UhciReadReg (Uhc
->PciIo
, USBCMD_OFFSET
);
141 UsbSts
= UhciReadReg (Uhc
->PciIo
, USBSTS_OFFSET
);
143 if ((UsbCmd
& USBCMD_EGSM
) !=0 ) {
144 *State
= EfiUsbHcStateSuspend
;
146 } else if ((UsbSts
& USBSTS_HCH
) != 0) {
147 *State
= EfiUsbHcStateHalt
;
150 *State
= EfiUsbHcStateOperational
;
158 Sets the USB host controller to a specific state according to UEFI 2.0 spec.
160 @param This A pointer to the EFI_USB2_HC_PROTOCOL instance.
161 @param State Indicates the state of the host controller that will
164 @return EFI_SUCCESS Host controller was successfully placed in the state.
165 @return EFI_INVALID_PARAMETER State is invalid.
166 @return EFI_DEVICE_ERROR Failed to set the state.
172 IN EFI_USB2_HC_PROTOCOL
*This
,
173 IN EFI_USB_HC_STATE State
176 EFI_USB_HC_STATE CurState
;
182 Uhc
= UHC_FROM_USB2_HC_PROTO (This
);
183 Status
= Uhci2GetState (This
, &CurState
);
185 if (EFI_ERROR (Status
)) {
186 return EFI_DEVICE_ERROR
;
189 if (CurState
== State
) {
193 Status
= EFI_SUCCESS
;
194 OldTpl
= gBS
->RaiseTPL (UHCI_TPL
);
197 case EfiUsbHcStateHalt
:
198 Status
= UhciStopHc (Uhc
, UHC_GENERIC_TIMEOUT
);
201 case EfiUsbHcStateOperational
:
202 UsbCmd
= UhciReadReg (Uhc
->PciIo
, USBCMD_OFFSET
);
204 if (CurState
== EfiUsbHcStateHalt
) {
206 // Set Run/Stop bit to 1, also set the bandwidht reclamation
209 UsbCmd
|= USBCMD_RS
| USBCMD_MAXP
;
210 UhciWriteReg (Uhc
->PciIo
, USBCMD_OFFSET
, UsbCmd
);
212 } else if (CurState
== EfiUsbHcStateSuspend
) {
214 // If FGR(Force Global Resume) bit is 0, set it
216 if ((UsbCmd
& USBCMD_FGR
) == 0) {
217 UsbCmd
|= USBCMD_FGR
;
218 UhciWriteReg (Uhc
->PciIo
, USBCMD_OFFSET
, UsbCmd
);
222 // wait 20ms to let resume complete (20ms is specified by UHCI spec)
224 gBS
->Stall (UHC_FORCE_GLOBAL_RESUME_STALL
);
227 // Write FGR bit to 0 and EGSM(Enter Global Suspend Mode) bit to 0
229 UsbCmd
&= ~USBCMD_FGR
;
230 UsbCmd
&= ~USBCMD_EGSM
;
232 UhciWriteReg (Uhc
->PciIo
, USBCMD_OFFSET
, UsbCmd
);
237 case EfiUsbHcStateSuspend
:
238 Status
= Uhci2SetState (This
, EfiUsbHcStateHalt
);
240 if (EFI_ERROR (Status
)) {
241 Status
= EFI_DEVICE_ERROR
;
246 // Set Enter Global Suspend Mode bit to 1.
248 UsbCmd
= UhciReadReg (Uhc
->PciIo
, USBCMD_OFFSET
);
249 UsbCmd
|= USBCMD_EGSM
;
250 UhciWriteReg (Uhc
->PciIo
, USBCMD_OFFSET
, UsbCmd
);
254 Status
= EFI_INVALID_PARAMETER
;
259 gBS
->RestoreTPL (OldTpl
);
264 Retrieves capabilities of USB host controller according to UEFI 2.0 spec.
266 @param This A pointer to the EFI_USB2_HC_PROTOCOL instance.
267 @param MaxSpeed A pointer to the max speed USB host controller
269 @param PortNumber A pointer to the number of root hub ports.
270 @param Is64BitCapable A pointer to an integer to show whether USB host
271 controller supports 64-bit memory addressing.
273 @return EFI_SUCCESS capabilities were retrieved successfully.
274 @return EFI_INVALID_PARAMETER MaxSpeed or PortNumber or Is64BitCapable is NULL.
275 @return EFI_DEVICE_ERROR An error was encountered.
281 IN EFI_USB2_HC_PROTOCOL
*This
,
283 OUT UINT8
*PortNumber
,
284 OUT UINT8
*Is64BitCapable
292 Uhc
= UHC_FROM_USB2_HC_PROTO (This
);
294 if ((NULL
== MaxSpeed
) || (NULL
== PortNumber
) || (NULL
== Is64BitCapable
)) {
295 return EFI_INVALID_PARAMETER
;
298 *MaxSpeed
= EFI_USB_SPEED_FULL
;
299 *Is64BitCapable
= (UINT8
) FALSE
;
303 for (Index
= 0; Index
< USB_MAX_ROOTHUB_PORT
; Index
++) {
304 Offset
= USBPORTSC_OFFSET
+ Index
* 2;
305 PortSC
= UhciReadReg (Uhc
->PciIo
, Offset
);
308 // Port status's bit 7 is reserved and always returns 1 if
309 // the port number is valid. Intel's UHCI (in EHCI controller)
310 // returns 0 in this bit if port number is invalid. Also, if
311 // PciIo IoRead returns error, 0xFFFF is returned to caller.
313 if (((PortSC
& 0x80) == 0) || (PortSC
== 0xFFFF)) {
319 Uhc
->RootPorts
= *PortNumber
;
321 DEBUG ((EFI_D_INFO
, "Uhci2GetCapability: %d ports\n", (UINT32
)Uhc
->RootPorts
));
327 Retrieves the current status of a USB root hub port according to UEFI 2.0 spec.
329 @param This A pointer to the EFI_USB2_HC_PROTOCOL.
330 @param PortNumber The port to get status.
331 @param PortStatus A pointer to the current port status bits and port
334 @return EFI_SUCCESS status of the USB root hub port was returned in PortStatus.
335 @return EFI_INVALID_PARAMETER PortNumber is invalid.
336 @return EFI_DEVICE_ERROR Can't read register.
341 Uhci2GetRootHubPortStatus (
342 IN CONST EFI_USB2_HC_PROTOCOL
*This
,
343 IN CONST UINT8 PortNumber
,
344 OUT EFI_USB_PORT_STATUS
*PortStatus
351 Uhc
= UHC_FROM_USB2_HC_PROTO (This
);
353 if (PortStatus
== NULL
) {
354 return EFI_INVALID_PARAMETER
;
357 if (PortNumber
>= Uhc
->RootPorts
) {
358 return EFI_INVALID_PARAMETER
;
361 Offset
= USBPORTSC_OFFSET
+ PortNumber
* 2;
362 PortStatus
->PortStatus
= 0;
363 PortStatus
->PortChangeStatus
= 0;
365 PortSC
= UhciReadReg (Uhc
->PciIo
, Offset
);
367 if ((PortSC
& USBPORTSC_CCS
) != 0) {
368 PortStatus
->PortStatus
|= USB_PORT_STAT_CONNECTION
;
371 if ((PortSC
& USBPORTSC_PED
) != 0) {
372 PortStatus
->PortStatus
|= USB_PORT_STAT_ENABLE
;
375 if ((PortSC
& USBPORTSC_SUSP
) != 0) {
376 DEBUG ((EFI_D_INFO
, "Uhci2GetRootHubPortStatus: port %d is suspended\n", PortNumber
));
377 PortStatus
->PortStatus
|= USB_PORT_STAT_SUSPEND
;
380 if ((PortSC
& USBPORTSC_PR
) != 0) {
381 PortStatus
->PortStatus
|= USB_PORT_STAT_RESET
;
384 if ((PortSC
& USBPORTSC_LSDA
) != 0) {
385 PortStatus
->PortStatus
|= USB_PORT_STAT_LOW_SPEED
;
389 // CHC will always return one in port owner bit
391 PortStatus
->PortStatus
|= USB_PORT_STAT_OWNER
;
393 if ((PortSC
& USBPORTSC_CSC
) != 0) {
394 PortStatus
->PortChangeStatus
|= USB_PORT_STAT_C_CONNECTION
;
397 if ((PortSC
& USBPORTSC_PEDC
) != 0) {
398 PortStatus
->PortChangeStatus
|= USB_PORT_STAT_C_ENABLE
;
406 Sets a feature for the specified root hub port according to UEFI 2.0 spec.
408 @param This A pointer to the EFI_USB2_HC_PROTOCOL.
409 @param PortNumber Specifies the root hub port whose feature is
411 @param PortFeature Indicates the feature selector associated with the
414 @return EFI_SUCCESS PortFeature was set for the root port.
415 @return EFI_INVALID_PARAMETER PortNumber is invalid or PortFeature is invalid.
416 @return EFI_DEVICE_ERROR Can't read register.
421 Uhci2SetRootHubPortFeature (
422 IN EFI_USB2_HC_PROTOCOL
*This
,
424 IN EFI_USB_PORT_FEATURE PortFeature
433 Uhc
= UHC_FROM_USB2_HC_PROTO (This
);
435 if (PortNumber
>= Uhc
->RootPorts
) {
436 return EFI_INVALID_PARAMETER
;
439 Offset
= USBPORTSC_OFFSET
+ PortNumber
* 2;
441 OldTpl
= gBS
->RaiseTPL (UHCI_TPL
);
442 PortSC
= UhciReadReg (Uhc
->PciIo
, Offset
);
444 switch (PortFeature
) {
445 case EfiUsbPortSuspend
:
446 Command
= UhciReadReg (Uhc
->PciIo
, USBCMD_OFFSET
);
447 if ((Command
& USBCMD_EGSM
) == 0) {
449 // if global suspend is not active, can set port suspend
452 PortSC
|= USBPORTSC_SUSP
;
456 case EfiUsbPortReset
:
458 PortSC
|= USBPORTSC_PR
;
461 case EfiUsbPortPower
:
467 case EfiUsbPortEnable
:
469 PortSC
|= USBPORTSC_PED
;
473 gBS
->RestoreTPL (OldTpl
);
474 return EFI_INVALID_PARAMETER
;
477 UhciWriteReg (Uhc
->PciIo
, Offset
, PortSC
);
478 gBS
->RestoreTPL (OldTpl
);
485 Clears a feature for the specified root hub port according to Uefi 2.0 spec.
487 @param This A pointer to the EFI_USB2_HC_PROTOCOL instance.
488 @param PortNumber Specifies the root hub port whose feature is
489 requested to be cleared.
490 @param PortFeature Indicates the feature selector associated with the
491 feature clear request.
493 @return EFI_SUCCESS PortFeature was cleared for the USB root hub port.
494 @return EFI_INVALID_PARAMETER PortNumber is invalid or PortFeature is invalid.
495 @return EFI_DEVICE_ERROR Can't read register.
500 Uhci2ClearRootHubPortFeature (
501 IN EFI_USB2_HC_PROTOCOL
*This
,
503 IN EFI_USB_PORT_FEATURE PortFeature
511 Uhc
= UHC_FROM_USB2_HC_PROTO (This
);
513 if (PortNumber
>= Uhc
->RootPorts
) {
514 return EFI_INVALID_PARAMETER
;
517 Offset
= USBPORTSC_OFFSET
+ PortNumber
* 2;
519 OldTpl
= gBS
->RaiseTPL (UHCI_TPL
);
520 PortSC
= UhciReadReg (Uhc
->PciIo
, Offset
);
522 switch (PortFeature
) {
523 case EfiUsbPortEnable
:
525 PortSC
&= ~USBPORTSC_PED
;
528 case EfiUsbPortSuspend
:
530 // Cause a resume on the specified port if in suspend mode.
533 PortSC
&= ~USBPORTSC_SUSP
;
536 case EfiUsbPortPower
:
542 case EfiUsbPortReset
:
544 PortSC
&= ~USBPORTSC_PR
;
547 case EfiUsbPortConnectChange
:
549 PortSC
|= USBPORTSC_CSC
;
552 case EfiUsbPortEnableChange
:
554 PortSC
|= USBPORTSC_PEDC
;
557 case EfiUsbPortSuspendChange
:
559 // Root hub does not support this
563 case EfiUsbPortOverCurrentChange
:
565 // Root hub does not support this
569 case EfiUsbPortResetChange
:
571 // Root hub does not support this
576 gBS
->RestoreTPL (OldTpl
);
577 return EFI_INVALID_PARAMETER
;
580 UhciWriteReg (Uhc
->PciIo
, Offset
, PortSC
);
581 gBS
->RestoreTPL (OldTpl
);
588 Submits control transfer to a target USB device accroding to UEFI 2.0 spec.
590 @param This A pointer to the EFI_USB2_HC_PROTOCOL instance.
591 @param DeviceAddress Target device address.
592 @param DeviceSpeed Device speed.
593 @param MaximumPacketLength Maximum packet size of the target endpoint.
594 @param Request USB device request to send.
595 @param TransferDirection Data direction of the Data stage in control transfer.
596 @param Data Data to transmit/receive in data stage.
597 @param DataLength Length of the data.
598 @param TimeOut Maximum time, in microseconds, for transfer to complete.
599 @param Translator Transaction translator to be used by this device.
600 @param TransferResult Variable to receive the transfer result.
602 @return EFI_SUCCESS The control transfer was completed successfully.
603 @return EFI_OUT_OF_RESOURCES Failed due to lack of resource.
604 @return EFI_INVALID_PARAMETER Some parameters are invalid.
605 @return EFI_TIMEOUT Failed due to timeout.
606 @return EFI_DEVICE_ERROR Failed due to host controller or device error.
611 Uhci2ControlTransfer (
612 IN EFI_USB2_HC_PROTOCOL
*This
,
613 IN UINT8 DeviceAddress
,
614 IN UINT8 DeviceSpeed
,
615 IN UINTN MaximumPacketLength
,
616 IN EFI_USB_DEVICE_REQUEST
*Request
,
617 IN EFI_USB_DATA_DIRECTION TransferDirection
,
619 IN OUT UINTN
*DataLength
,
621 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
622 OUT UINT32
*TransferResult
629 UHCI_QH_RESULT QhResult
;
635 BOOLEAN IsSlowDevice
;
636 UINTN TransferDataLength
;
638 Uhc
= UHC_FROM_USB2_HC_PROTO (This
);
645 IsSlowDevice
= (BOOLEAN
) ((EFI_USB_SPEED_LOW
== DeviceSpeed
) ? TRUE
: FALSE
);
648 // Parameters Checking
650 if (Request
== NULL
|| TransferResult
== NULL
) {
651 return EFI_INVALID_PARAMETER
;
654 if (IsSlowDevice
&& (MaximumPacketLength
!= 8)) {
655 return EFI_INVALID_PARAMETER
;
658 if ((MaximumPacketLength
!= 8) && (MaximumPacketLength
!= 16) &&
659 (MaximumPacketLength
!= 32) && (MaximumPacketLength
!= 64)) {
661 return EFI_INVALID_PARAMETER
;
664 if ((TransferDirection
!= EfiUsbNoData
) && (Data
== NULL
|| DataLength
== NULL
)) {
665 return EFI_INVALID_PARAMETER
;
668 if (TransferDirection
== EfiUsbNoData
) {
669 TransferDataLength
= 0;
671 TransferDataLength
= *DataLength
;
674 *TransferResult
= EFI_USB_ERR_SYSTEM
;
675 Status
= EFI_DEVICE_ERROR
;
678 // If errors exist that cause host controller halt,
679 // clear status then return EFI_DEVICE_ERROR.
681 UhciAckAllInterrupt (Uhc
);
683 if (!UhciIsHcWorking (Uhc
->PciIo
)) {
684 return EFI_DEVICE_ERROR
;
687 OldTpl
= gBS
->RaiseTPL (UHCI_TPL
);
690 // Map the Request and data for bus master access,
691 // then create a list of TD for this transfer
693 Status
= UhciMapUserRequest (Uhc
, Request
, &RequestPhy
, &RequestMap
);
695 if (EFI_ERROR (Status
)) {
699 Status
= UhciMapUserData (Uhc
, TransferDirection
, Data
, DataLength
, &PktId
, &DataPhy
, &DataMap
);
701 if (EFI_ERROR (Status
)) {
702 Uhc
->PciIo
->Unmap (Uhc
->PciIo
, RequestMap
);
706 TDs
= UhciCreateCtrlTds (
715 (UINT8
) MaximumPacketLength
,
720 Status
= EFI_OUT_OF_RESOURCES
;
725 // According to the speed of the end point, link
726 // the TD to corrosponding queue head, then check
727 // the execution result
729 UhciLinkTdToQh (Uhc
, Uhc
->CtrlQh
, TDs
);
730 Status
= UhciExecuteTransfer (Uhc
, Uhc
->CtrlQh
, TDs
, TimeOut
, IsSlowDevice
, &QhResult
);
731 UhciUnlinkTdFromQh (Uhc
->CtrlQh
, TDs
);
733 Uhc
->PciIo
->Flush (Uhc
->PciIo
);
735 *TransferResult
= QhResult
.Result
;
737 if (DataLength
!= NULL
) {
738 *DataLength
= QhResult
.Complete
;
741 UhciDestoryTds (Uhc
, TDs
);
744 Uhc
->PciIo
->Unmap (Uhc
->PciIo
, DataMap
);
745 Uhc
->PciIo
->Unmap (Uhc
->PciIo
, RequestMap
);
748 gBS
->RestoreTPL (OldTpl
);
754 Submits bulk transfer to a bulk endpoint of a USB device.
756 @param This A pointer to the EFI_USB2_HC_PROTOCOL instance.
757 @param DeviceAddress Target device address.
758 @param EndPointAddress Endpoint number and direction.
759 @param DeviceSpeed Device speed.
760 @param MaximumPacketLength Maximum packet size of the target endpoint.
761 @param DataBuffersNumber Number of data buffers prepared for the transfer.
762 @param Data Array of pointers to the buffers of data.
763 @param DataLength On input, size of the data buffer, On output,
764 actually transferred data size.
765 @param DataToggle On input, data toggle to use; On output, next data toggle.
766 @param TimeOut Maximum time out, in microseconds.
767 @param Translator A pointr to the transaction translator data.
768 @param TransferResult Variable to receive transfer result.
770 @return EFI_SUCCESS The bulk transfer was completed successfully.
771 @return EFI_OUT_OF_RESOURCES Failed due to lack of resource.
772 @return EFI_INVALID_PARAMETER Some parameters are invalid.
773 @return EFI_TIMEOUT Failed due to timeout.
774 @return EFI_DEVICE_ERROR Failed due to host controller or device error.
780 IN EFI_USB2_HC_PROTOCOL
*This
,
781 IN UINT8 DeviceAddress
,
782 IN UINT8 EndPointAddress
,
783 IN UINT8 DeviceSpeed
,
784 IN UINTN MaximumPacketLength
,
785 IN UINT8 DataBuffersNumber
,
786 IN OUT VOID
*Data
[EFI_USB_MAX_BULK_BUFFER_NUM
],
787 IN OUT UINTN
*DataLength
,
788 IN OUT UINT8
*DataToggle
,
790 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
791 OUT UINT32
*TransferResult
794 EFI_USB_DATA_DIRECTION Direction
;
799 UHCI_QH_RESULT QhResult
;
805 Uhc
= UHC_FROM_USB2_HC_PROTO (This
);
809 if (DeviceSpeed
== EFI_USB_SPEED_LOW
) {
810 return EFI_INVALID_PARAMETER
;
813 if ((DataLength
== NULL
) || (*DataLength
== 0) || (Data
== NULL
) || (TransferResult
== NULL
)) {
814 return EFI_INVALID_PARAMETER
;
817 if ((*DataToggle
!= 1) && (*DataToggle
!= 0)) {
818 return EFI_INVALID_PARAMETER
;
821 if ((MaximumPacketLength
!= 8) && (MaximumPacketLength
!= 16) &&
822 (MaximumPacketLength
!= 32) && (MaximumPacketLength
!= 64)) {
823 return EFI_INVALID_PARAMETER
;
826 *TransferResult
= EFI_USB_ERR_SYSTEM
;
827 Status
= EFI_OUT_OF_RESOURCES
;
830 // If has errors that cause host controller halt,
831 // then return EFI_DEVICE_ERROR directly.
833 UhciAckAllInterrupt (Uhc
);
835 if (!UhciIsHcWorking (Uhc
->PciIo
)) {
836 return EFI_DEVICE_ERROR
;
839 OldTpl
= gBS
->RaiseTPL (UHCI_TPL
);
842 // Map the source data buffer for bus master access,
843 // then create a list of TDs
845 if ((EndPointAddress
& 0x80) != 0) {
846 Direction
= EfiUsbDataIn
;
848 Direction
= EfiUsbDataOut
;
851 Status
= UhciMapUserData (Uhc
, Direction
, *Data
, DataLength
, &PktId
, &DataPhy
, &DataMap
);
853 if (EFI_ERROR (Status
)) {
857 Status
= EFI_OUT_OF_RESOURCES
;
858 TDs
= UhciCreateBulkOrIntTds (
867 (UINT8
) MaximumPacketLength
,
872 Uhc
->PciIo
->Unmap (Uhc
->PciIo
, DataMap
);
878 // Link the TDs to bulk queue head. According to the platfore
879 // defintion of UHCI_NO_BW_RECLAMATION, BulkQh is either configured
880 // to do full speed bandwidth reclamation or not.
882 BulkQh
= Uhc
->BulkQh
;
884 UhciLinkTdToQh (Uhc
, BulkQh
, TDs
);
885 Status
= UhciExecuteTransfer (Uhc
, BulkQh
, TDs
, TimeOut
, FALSE
, &QhResult
);
886 UhciUnlinkTdFromQh (BulkQh
, TDs
);
888 Uhc
->PciIo
->Flush (Uhc
->PciIo
);
890 *TransferResult
= QhResult
.Result
;
891 *DataToggle
= QhResult
.NextToggle
;
892 *DataLength
= QhResult
.Complete
;
894 UhciDestoryTds (Uhc
, TDs
);
895 Uhc
->PciIo
->Unmap (Uhc
->PciIo
, DataMap
);
898 gBS
->RestoreTPL (OldTpl
);
904 Submits an asynchronous interrupt transfer to an
905 interrupt endpoint of a USB device according to UEFI 2.0 spec.
907 @param This A pointer to the EFI_USB2_HC_PROTOCOL instance.
908 @param DeviceAddress Target device address.
909 @param EndPointAddress Endpoint number and direction.
910 @param DeviceSpeed Device speed.
911 @param MaximumPacketLength Maximum packet size of the target endpoint.
912 @param IsNewTransfer If TRUE, submit a new transfer, if FALSE cancel old transfer.
913 @param DataToggle On input, data toggle to use; On output, next data toggle.
914 @param PollingInterval Interrupt poll rate in milliseconds.
915 @param DataLength On input, size of the data buffer, On output,
916 actually transferred data size.
917 @param Translator A pointr to the transaction translator data.
918 @param CallBackFunction Function to call periodically.
919 @param Context User context.
921 @return EFI_SUCCESS Transfer was submitted.
922 @return EFI_INVALID_PARAMETER Some parameters are invalid.
923 @return EFI_OUT_OF_RESOURCES Failed due to a lack of resources.
924 @return EFI_DEVICE_ERROR Can't read register.
929 Uhci2AsyncInterruptTransfer (
930 IN EFI_USB2_HC_PROTOCOL
*This
,
931 IN UINT8 DeviceAddress
,
932 IN UINT8 EndPointAddress
,
933 IN UINT8 DeviceSpeed
,
934 IN UINTN MaximumPacketLength
,
935 IN BOOLEAN IsNewTransfer
,
936 IN OUT UINT8
*DataToggle
,
937 IN UINTN PollingInterval
,
939 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
940 IN EFI_ASYNC_USB_TRANSFER_CALLBACK CallBackFunction
,
945 BOOLEAN IsSlowDevice
;
954 Uhc
= UHC_FROM_USB2_HC_PROTO (This
);
960 IsSlowDevice
= (BOOLEAN
) ((EFI_USB_SPEED_LOW
== DeviceSpeed
) ? TRUE
: FALSE
);
962 if ((EndPointAddress
& 0x80) == 0) {
963 return EFI_INVALID_PARAMETER
;
967 // Delete Async interrupt transfer request
969 if (!IsNewTransfer
) {
970 OldTpl
= gBS
->RaiseTPL (UHCI_TPL
);
971 Status
= UhciRemoveAsyncReq (Uhc
, DeviceAddress
, EndPointAddress
, DataToggle
);
973 gBS
->RestoreTPL (OldTpl
);
977 if (PollingInterval
< 1 || PollingInterval
> 255) {
978 return EFI_INVALID_PARAMETER
;
981 if (DataLength
== 0) {
982 return EFI_INVALID_PARAMETER
;
985 if ((*DataToggle
!= 1) && (*DataToggle
!= 0)) {
986 return EFI_INVALID_PARAMETER
;
990 // If has errors that cause host controller halt,
991 // then return EFI_DEVICE_ERROR directly.
993 UhciAckAllInterrupt (Uhc
);
995 if (!UhciIsHcWorking (Uhc
->PciIo
)) {
996 return EFI_DEVICE_ERROR
;
999 if ((EndPointAddress
& 0x80) == 0) {
1000 PktId
= OUTPUT_PACKET_ID
;
1002 PktId
= INPUT_PACKET_ID
;
1006 // Allocate and map source data buffer for bus master access.
1008 DataPtr
= UsbHcAllocateMem (Uhc
->MemPool
, DataLength
);
1010 if (DataPtr
== NULL
) {
1011 return EFI_OUT_OF_RESOURCES
;
1014 DataPhy
= (UINT8
*) (UINTN
) UsbHcGetPciAddressForHostMem (Uhc
->MemPool
, DataPtr
, DataLength
);
1016 OldTpl
= gBS
->RaiseTPL (UHCI_TPL
);
1018 Qh
= UhciCreateQh (Uhc
, PollingInterval
);
1021 Status
= EFI_OUT_OF_RESOURCES
;
1025 IntTds
= UhciCreateBulkOrIntTds (
1034 (UINT8
) MaximumPacketLength
,
1038 if (IntTds
== NULL
) {
1039 Status
= EFI_OUT_OF_RESOURCES
;
1043 UhciLinkTdToQh (Uhc
, Qh
, IntTds
);
1046 // Save QH-TD structures to async Interrupt transfer list,
1047 // for monitor interrupt transfer execution routine use.
1049 Status
= UhciCreateAsyncReq (
1063 if (EFI_ERROR (Status
)) {
1067 UhciLinkQhToFrameList (Uhc
, Qh
);
1069 gBS
->RestoreTPL (OldTpl
);
1073 UsbHcFreeMem (Uhc
->MemPool
, Qh
, sizeof (UHCI_QH_SW
));
1076 UsbHcFreeMem (Uhc
->MemPool
, DataPtr
, DataLength
);
1077 Uhc
->PciIo
->Flush (Uhc
->PciIo
);
1079 gBS
->RestoreTPL (OldTpl
);
1084 Submits synchronous interrupt transfer to an interrupt endpoint
1085 of a USB device according to UEFI 2.0 spec.
1088 @param This A pointer to the EFI_USB2_HC_PROTOCOL instance.
1089 @param DeviceAddress Target device address.
1090 @param EndPointAddress Endpoint number and direction.
1091 @param DeviceSpeed Device speed.
1092 @param MaximumPacketLength Maximum packet size of the target endpoint.
1093 @param Data Array of pointers to the buffers of data.
1094 @param DataLength On input, size of the data buffer, On output,
1095 actually transferred data size.
1096 @param DataToggle On input, data toggle to use; On output, next data toggle.
1097 @param TimeOut Maximum time out, in microseconds.
1098 @param Translator A pointr to the transaction translator data.
1099 @param TransferResult Variable to receive transfer result.
1101 @return EFI_SUCCESS The transfer was completed successfully.
1102 @return EFI_OUT_OF_RESOURCES Failed due to lack of resource.
1103 @return EFI_INVALID_PARAMETER Some parameters are invalid.
1104 @return EFI_TIMEOUT Failed due to timeout.
1105 @return EFI_DEVICE_ERROR Failed due to host controller or device error.
1110 Uhci2SyncInterruptTransfer (
1111 IN EFI_USB2_HC_PROTOCOL
*This
,
1112 IN UINT8 DeviceAddress
,
1113 IN UINT8 EndPointAddress
,
1114 IN UINT8 DeviceSpeed
,
1115 IN UINTN MaximumPacketLength
,
1117 IN OUT UINTN
*DataLength
,
1118 IN OUT UINT8
*DataToggle
,
1120 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
1121 OUT UINT32
*TransferResult
1127 UHCI_QH_RESULT QhResult
;
1132 BOOLEAN IsSlowDevice
;
1134 Uhc
= UHC_FROM_USB2_HC_PROTO (This
);
1139 if (DeviceSpeed
== EFI_USB_SPEED_HIGH
) {
1140 return EFI_INVALID_PARAMETER
;
1143 IsSlowDevice
= (BOOLEAN
) ((EFI_USB_SPEED_LOW
== DeviceSpeed
) ? TRUE
: FALSE
);
1145 if ((DataLength
== NULL
) || (Data
== NULL
) || (TransferResult
== NULL
)) {
1146 return EFI_INVALID_PARAMETER
;
1149 if ((EndPointAddress
& 0x80) == 0) {
1150 return EFI_INVALID_PARAMETER
;
1153 if ((*DataToggle
!= 1) && (*DataToggle
!= 0)) {
1154 return EFI_INVALID_PARAMETER
;
1157 if ((*DataLength
== 0) || (MaximumPacketLength
> 64)) {
1158 return EFI_INVALID_PARAMETER
;
1161 if (IsSlowDevice
&& (MaximumPacketLength
> 8)) {
1162 return EFI_INVALID_PARAMETER
;
1165 *TransferResult
= EFI_USB_ERR_SYSTEM
;
1166 Status
= EFI_DEVICE_ERROR
;
1169 UhciAckAllInterrupt (Uhc
);
1171 if (!UhciIsHcWorking (Uhc
->PciIo
)) {
1175 OldTpl
= gBS
->RaiseTPL (UHCI_TPL
);
1178 // Map the source data buffer for bus master access.
1179 // Create Tds list, then link it to the UHC's interrupt list
1181 Status
= UhciMapUserData (
1191 if (EFI_ERROR (Status
)) {
1195 TDs
= UhciCreateBulkOrIntTds (
1204 (UINT8
) MaximumPacketLength
,
1209 Uhc
->PciIo
->Unmap (Uhc
->PciIo
, DataMap
);
1211 Status
= EFI_OUT_OF_RESOURCES
;
1216 UhciLinkTdToQh (Uhc
, Uhc
->SyncIntQh
, TDs
);
1218 Status
= UhciExecuteTransfer (Uhc
, Uhc
->SyncIntQh
, TDs
, TimeOut
, IsSlowDevice
, &QhResult
);
1220 UhciUnlinkTdFromQh (Uhc
->SyncIntQh
, TDs
);
1221 Uhc
->PciIo
->Flush (Uhc
->PciIo
);
1223 *TransferResult
= QhResult
.Result
;
1224 *DataToggle
= QhResult
.NextToggle
;
1225 *DataLength
= QhResult
.Complete
;
1227 UhciDestoryTds (Uhc
, TDs
);
1228 Uhc
->PciIo
->Unmap (Uhc
->PciIo
, DataMap
);
1231 gBS
->RestoreTPL (OldTpl
);
1237 Submits isochronous transfer to a target USB device according to UEFI 2.0 spec.
1239 @param This A pointer to the EFI_USB2_HC_PROTOCOL instance.
1240 @param DeviceAddress Target device address.
1241 @param EndPointAddress Endpoint number and direction.
1242 @param DeviceSpeed Device speed.
1243 @param MaximumPacketLength Maximum packet size of the target endpoint.
1244 @param DataBuffersNumber Number of data buffers prepared for the transfer.
1245 @param Data Array of pointers to the buffers of data.
1246 @param DataLength On input, size of the data buffer, On output,
1247 actually transferred data size.
1248 @param Translator A pointr to the transaction translator data.
1249 @param TransferResult Variable to receive transfer result.
1251 @return EFI_UNSUPPORTED
1256 Uhci2IsochronousTransfer (
1257 IN EFI_USB2_HC_PROTOCOL
*This
,
1258 IN UINT8 DeviceAddress
,
1259 IN UINT8 EndPointAddress
,
1260 IN UINT8 DeviceSpeed
,
1261 IN UINTN MaximumPacketLength
,
1262 IN UINT8 DataBuffersNumber
,
1263 IN OUT VOID
*Data
[EFI_USB_MAX_ISO_BUFFER_NUM
],
1264 IN UINTN DataLength
,
1265 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
1266 OUT UINT32
*TransferResult
1269 return EFI_UNSUPPORTED
;
1274 Submits Async isochronous transfer to a target USB device according to UEFI 2.0 spec.
1276 @param This A pointer to the EFI_USB2_HC_PROTOCOL instance.
1277 @param DeviceAddress Target device address.
1278 @param EndPointAddress Endpoint number and direction.
1279 @param DeviceSpeed Device speed.
1280 @param MaximumPacketLength Maximum packet size of the target endpoint.
1281 @param DataBuffersNumber Number of data buffers prepared for the transfer.
1282 @param Data Array of pointers to the buffers of data.
1283 @param DataLength On input, size of the data buffer, On output,
1284 actually transferred data size.
1285 @param Translator A pointr to the transaction translator data.
1286 @param IsochronousCallBack Function to call when the transfer complete.
1287 @param Context Pass to the call back function as parameter.
1289 @return EFI_UNSUPPORTED
1294 Uhci2AsyncIsochronousTransfer (
1295 IN EFI_USB2_HC_PROTOCOL
*This
,
1296 IN UINT8 DeviceAddress
,
1297 IN UINT8 EndPointAddress
,
1298 IN UINT8 DeviceSpeed
,
1299 IN UINTN MaximumPacketLength
,
1300 IN UINT8 DataBuffersNumber
,
1301 IN OUT VOID
*Data
[EFI_USB_MAX_ISO_BUFFER_NUM
],
1302 IN UINTN DataLength
,
1303 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
1304 IN EFI_ASYNC_USB_TRANSFER_CALLBACK IsochronousCallBack
,
1308 return EFI_UNSUPPORTED
;
1312 Entry point for EFI drivers.
1314 @param ImageHandle EFI_HANDLE.
1315 @param SystemTable EFI_SYSTEM_TABLE.
1317 @retval EFI_SUCCESS Driver is successfully loaded.
1318 @return Others Failed.
1323 UhciDriverEntryPoint (
1324 IN EFI_HANDLE ImageHandle
,
1325 IN EFI_SYSTEM_TABLE
*SystemTable
1328 return EfiLibInstallDriverBindingComponentName2 (
1331 &gUhciDriverBinding
,
1333 &gUhciComponentName
,
1334 &gUhciComponentName2
1340 Test to see if this driver supports ControllerHandle. Any
1341 ControllerHandle that has UsbHcProtocol installed will be supported.
1343 @param This Protocol instance pointer.
1344 @param Controller Handle of device to test.
1345 @param RemainingDevicePath Not used.
1347 @return EFI_SUCCESS This driver supports this device.
1348 @return EFI_UNSUPPORTED This driver does not support this device.
1353 UhciDriverBindingSupported (
1354 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1355 IN EFI_HANDLE Controller
,
1356 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
1359 EFI_STATUS OpenStatus
;
1361 EFI_PCI_IO_PROTOCOL
*PciIo
;
1362 USB_CLASSC UsbClassCReg
;
1365 // Test whether there is PCI IO Protocol attached on the controller handle.
1367 OpenStatus
= gBS
->OpenProtocol (
1369 &gEfiPciIoProtocolGuid
,
1371 This
->DriverBindingHandle
,
1373 EFI_OPEN_PROTOCOL_BY_DRIVER
1376 if (EFI_ERROR (OpenStatus
)) {
1380 Status
= PciIo
->Pci
.Read (
1383 PCI_CLASSCODE_OFFSET
,
1384 sizeof (USB_CLASSC
) / sizeof (UINT8
),
1388 if (EFI_ERROR (Status
)) {
1389 Status
= EFI_UNSUPPORTED
;
1394 // Test whether the controller belongs to UHCI type
1396 if ((UsbClassCReg
.BaseCode
!= PCI_CLASS_SERIAL
) ||
1397 (UsbClassCReg
.SubClassCode
!= PCI_CLASS_SERIAL_USB
) ||
1398 (UsbClassCReg
.ProgInterface
!= PCI_IF_UHCI
)
1401 Status
= EFI_UNSUPPORTED
;
1405 gBS
->CloseProtocol (
1407 &gEfiPciIoProtocolGuid
,
1408 This
->DriverBindingHandle
,
1418 Allocate and initialize the empty UHCI device.
1420 @param PciIo The PCIIO to use.
1421 @param OriginalPciAttributes The original PCI attributes.
1423 @return Allocated UHCI device. If err, return NULL.
1428 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
1429 IN UINT64 OriginalPciAttributes
1435 Uhc
= AllocateZeroPool (sizeof (USB_HC_DEV
));
1442 // This driver supports both USB_HC_PROTOCOL and USB2_HC_PROTOCOL.
1443 // USB_HC_PROTOCOL is for EFI 1.1 backward compability.
1445 Uhc
->Signature
= USB_HC_DEV_SIGNATURE
;
1446 Uhc
->Usb2Hc
.GetCapability
= Uhci2GetCapability
;
1447 Uhc
->Usb2Hc
.Reset
= Uhci2Reset
;
1448 Uhc
->Usb2Hc
.GetState
= Uhci2GetState
;
1449 Uhc
->Usb2Hc
.SetState
= Uhci2SetState
;
1450 Uhc
->Usb2Hc
.ControlTransfer
= Uhci2ControlTransfer
;
1451 Uhc
->Usb2Hc
.BulkTransfer
= Uhci2BulkTransfer
;
1452 Uhc
->Usb2Hc
.AsyncInterruptTransfer
= Uhci2AsyncInterruptTransfer
;
1453 Uhc
->Usb2Hc
.SyncInterruptTransfer
= Uhci2SyncInterruptTransfer
;
1454 Uhc
->Usb2Hc
.IsochronousTransfer
= Uhci2IsochronousTransfer
;
1455 Uhc
->Usb2Hc
.AsyncIsochronousTransfer
= Uhci2AsyncIsochronousTransfer
;
1456 Uhc
->Usb2Hc
.GetRootHubPortStatus
= Uhci2GetRootHubPortStatus
;
1457 Uhc
->Usb2Hc
.SetRootHubPortFeature
= Uhci2SetRootHubPortFeature
;
1458 Uhc
->Usb2Hc
.ClearRootHubPortFeature
= Uhci2ClearRootHubPortFeature
;
1459 Uhc
->Usb2Hc
.MajorRevision
= 0x1;
1460 Uhc
->Usb2Hc
.MinorRevision
= 0x1;
1463 Uhc
->OriginalPciAttributes
= OriginalPciAttributes
;
1464 Uhc
->MemPool
= UsbHcInitMemPool (PciIo
, TRUE
, 0);
1466 if (Uhc
->MemPool
== NULL
) {
1467 Status
= EFI_OUT_OF_RESOURCES
;
1471 InitializeListHead (&Uhc
->AsyncIntList
);
1473 Status
= gBS
->CreateEvent (
1474 EVT_TIMER
| EVT_NOTIFY_SIGNAL
,
1476 UhciMonitorAsyncReqList
,
1478 &Uhc
->AsyncIntMonitor
1481 if (EFI_ERROR (Status
)) {
1482 UsbHcFreeMemPool (Uhc
->MemPool
);
1495 Free the UHCI device and release its associated resources.
1497 @param Uhc The UHCI device to release.
1505 if (Uhc
->AsyncIntMonitor
!= NULL
) {
1506 gBS
->CloseEvent (Uhc
->AsyncIntMonitor
);
1509 if (Uhc
->ExitBootServiceEvent
!= NULL
) {
1510 gBS
->CloseEvent (Uhc
->ExitBootServiceEvent
);
1513 if (Uhc
->MemPool
!= NULL
) {
1514 UsbHcFreeMemPool (Uhc
->MemPool
);
1517 if (Uhc
->CtrlNameTable
!= NULL
) {
1518 FreeUnicodeStringTable (Uhc
->CtrlNameTable
);
1526 Uninstall all Uhci Interface.
1528 @param Controller Controller handle.
1529 @param This Protocol instance pointer.
1534 IN EFI_HANDLE Controller
,
1535 IN EFI_USB2_HC_PROTOCOL
*This
1541 // Uninstall the USB_HC and USB_HC2 protocol, then disable the controller
1543 Uhc
= UHC_FROM_USB2_HC_PROTO (This
);
1544 UhciStopHc (Uhc
, UHC_GENERIC_TIMEOUT
);
1546 gBS
->UninstallProtocolInterface (
1548 &gEfiUsb2HcProtocolGuid
,
1552 UhciFreeAllAsyncReq (Uhc
);
1553 UhciDestoryFrameList (Uhc
);
1556 // Restore original PCI attributes
1558 Uhc
->PciIo
->Attributes (
1560 EfiPciIoAttributeOperationSet
,
1561 Uhc
->OriginalPciAttributes
,
1569 One notified function to stop the Host Controller when gBS->ExitBootServices() called.
1571 @param Event Pointer to this event
1572 @param Context Event hanlder private data
1577 UhcExitBootService (
1584 Uhc
= (USB_HC_DEV
*) Context
;
1587 // Stop the Host Controller
1589 UhciStopHc (Uhc
, UHC_GENERIC_TIMEOUT
);
1595 Starting the Usb UHCI Driver.
1597 @param This Protocol instance pointer.
1598 @param Controller Handle of device to test.
1599 @param RemainingDevicePath Not used.
1601 @retval EFI_SUCCESS This driver supports this device.
1602 @retval EFI_UNSUPPORTED This driver does not support this device.
1603 @retval EFI_DEVICE_ERROR This driver cannot be started due to device Error.
1604 EFI_OUT_OF_RESOURCES- Failed due to resource shortage.
1609 UhciDriverBindingStart (
1610 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1611 IN EFI_HANDLE Controller
,
1612 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
1616 EFI_PCI_IO_PROTOCOL
*PciIo
;
1619 UINT64 OriginalPciAttributes
;
1620 BOOLEAN PciAttributesSaved
;
1623 // Open PCIIO, then enable the EHC device and turn off emulation
1626 Status
= gBS
->OpenProtocol (
1628 &gEfiPciIoProtocolGuid
,
1630 This
->DriverBindingHandle
,
1632 EFI_OPEN_PROTOCOL_BY_DRIVER
1635 if (EFI_ERROR (Status
)) {
1639 PciAttributesSaved
= FALSE
;
1641 // Save original PCI attributes
1643 Status
= PciIo
->Attributes (
1645 EfiPciIoAttributeOperationGet
,
1647 &OriginalPciAttributes
1650 if (EFI_ERROR (Status
)) {
1653 PciAttributesSaved
= TRUE
;
1656 // Robustnesss improvement such as for UoL
1657 // Default is not required.
1659 if (FeaturePcdGet (PcdTurnOffUsbLegacySupport
)) {
1660 UhciTurnOffUsbEmulation (PciIo
);
1663 Status
= PciIo
->Attributes (
1665 EfiPciIoAttributeOperationSupported
,
1669 if (!EFI_ERROR (Status
)) {
1670 Supports
&= EFI_PCI_DEVICE_ENABLE
;
1671 Status
= PciIo
->Attributes (
1673 EfiPciIoAttributeOperationEnable
,
1679 if (EFI_ERROR (Status
)) {
1683 Uhc
= UhciAllocateDev (PciIo
, OriginalPciAttributes
);
1686 Status
= EFI_OUT_OF_RESOURCES
;
1691 // Allocate and Init Host Controller's Frame List Entry
1693 Status
= UhciInitFrameList (Uhc
);
1695 if (EFI_ERROR (Status
)) {
1696 Status
= EFI_OUT_OF_RESOURCES
;
1700 Status
= gBS
->SetTimer (
1701 Uhc
->AsyncIntMonitor
,
1703 UHC_ASYNC_POLL_INTERVAL
1706 if (EFI_ERROR (Status
)) {
1711 // Install USB2_HC_PROTOCOL
1713 Status
= gBS
->InstallMultipleProtocolInterfaces (
1715 &gEfiUsb2HcProtocolGuid
,
1720 if (EFI_ERROR (Status
)) {
1725 // Create event to stop the HC when exit boot service.
1727 Status
= gBS
->CreateEventEx (
1732 &gEfiEventExitBootServicesGuid
,
1733 &Uhc
->ExitBootServiceEvent
1735 if (EFI_ERROR (Status
)) {
1736 goto UNINSTALL_USBHC
;
1740 // Install the component name protocol
1742 Uhc
->CtrlNameTable
= NULL
;
1746 gUhciComponentName
.SupportedLanguages
,
1747 &Uhc
->CtrlNameTable
,
1748 L
"Usb Universal Host Controller",
1753 gUhciComponentName2
.SupportedLanguages
,
1754 &Uhc
->CtrlNameTable
,
1755 L
"Usb Universal Host Controller",
1761 // Start the UHCI hardware, also set its reclamation point to 64 bytes
1763 UhciWriteReg (Uhc
->PciIo
, USBCMD_OFFSET
, USBCMD_RS
| USBCMD_MAXP
);
1768 gBS
->UninstallMultipleProtocolInterfaces (
1770 &gEfiUsb2HcProtocolGuid
,
1779 if (PciAttributesSaved
) {
1781 // Restore original PCI attributes
1785 EfiPciIoAttributeOperationSet
,
1786 OriginalPciAttributes
,
1791 gBS
->CloseProtocol (
1793 &gEfiPciIoProtocolGuid
,
1794 This
->DriverBindingHandle
,
1803 Stop this driver on ControllerHandle. Support stoping any child handles
1804 created by this driver.
1806 @param This Protocol instance pointer.
1807 @param Controller Handle of device to stop driver on.
1808 @param NumberOfChildren Number of Children in the ChildHandleBuffer.
1809 @param ChildHandleBuffer List of handles for the children we need to stop.
1817 UhciDriverBindingStop (
1818 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1819 IN EFI_HANDLE Controller
,
1820 IN UINTN NumberOfChildren
,
1821 IN EFI_HANDLE
*ChildHandleBuffer
1824 EFI_USB2_HC_PROTOCOL
*Usb2Hc
;
1827 Status
= gBS
->OpenProtocol (
1829 &gEfiUsb2HcProtocolGuid
,
1831 This
->DriverBindingHandle
,
1833 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1837 // Test whether the Controller handler passed in is a valid
1838 // Usb controller handle that should be supported, if not,
1839 // return the error status directly
1841 if (EFI_ERROR (Status
)) {
1845 UhciCleanDevUp (Controller
, Usb2Hc
);
1847 gBS
->CloseProtocol (
1849 &gEfiPciIoProtocolGuid
,
1850 This
->DriverBindingHandle
,