3 The UHCI driver model and HC protocol routines.
5 Copyright (c) 2004 - 2008, 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", 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
;
637 Uhc
= UHC_FROM_USB2_HC_PROTO (This
);
644 IsSlowDevice
= (BOOLEAN
) ((EFI_USB_SPEED_LOW
== DeviceSpeed
) ? TRUE
: FALSE
);
647 // Parameters Checking
649 if (Request
== NULL
|| TransferResult
== NULL
) {
650 return EFI_INVALID_PARAMETER
;
653 if (IsSlowDevice
&& (MaximumPacketLength
!= 8)) {
654 return EFI_INVALID_PARAMETER
;
657 if ((MaximumPacketLength
!= 8) && (MaximumPacketLength
!= 16) &&
658 (MaximumPacketLength
!= 32) && (MaximumPacketLength
!= 64)) {
660 return EFI_INVALID_PARAMETER
;
663 if ((TransferDirection
!= EfiUsbNoData
) && (DataLength
== NULL
)) {
664 return EFI_INVALID_PARAMETER
;
667 *TransferResult
= EFI_USB_ERR_SYSTEM
;
668 Status
= EFI_DEVICE_ERROR
;
671 // If errors exist that cause host controller halt,
672 // clear status then return EFI_DEVICE_ERROR.
674 UhciAckAllInterrupt (Uhc
);
676 if (!UhciIsHcWorking (Uhc
->PciIo
)) {
677 return EFI_DEVICE_ERROR
;
680 OldTpl
= gBS
->RaiseTPL (UHCI_TPL
);
683 // Map the Request and data for bus master access,
684 // then create a list of TD for this transfer
686 Status
= UhciMapUserRequest (Uhc
, Request
, &RequestPhy
, &RequestMap
);
688 if (EFI_ERROR (Status
)) {
692 Status
= UhciMapUserData (Uhc
, TransferDirection
, Data
, DataLength
, &PktId
, &DataPhy
, &DataMap
);
694 if (EFI_ERROR (Status
)) {
695 Uhc
->PciIo
->Unmap (Uhc
->PciIo
, RequestMap
);
699 TDs
= UhciCreateCtrlTds (
706 (UINT8
) MaximumPacketLength
,
711 Status
= EFI_OUT_OF_RESOURCES
;
716 // According to the speed of the end point, link
717 // the TD to corrosponding queue head, then check
718 // the execution result
720 UhciLinkTdToQh (Uhc
->CtrlQh
, TDs
);
721 Status
= UhciExecuteTransfer (Uhc
, Uhc
->CtrlQh
, TDs
, TimeOut
, IsSlowDevice
, &QhResult
);
722 UhciUnlinkTdFromQh (Uhc
->CtrlQh
, TDs
);
724 Uhc
->PciIo
->Flush (Uhc
->PciIo
);
726 *TransferResult
= QhResult
.Result
;
728 if (DataLength
!= NULL
) {
729 *DataLength
= QhResult
.Complete
;
732 UhciDestoryTds (Uhc
, TDs
);
735 Uhc
->PciIo
->Unmap (Uhc
->PciIo
, DataMap
);
736 Uhc
->PciIo
->Unmap (Uhc
->PciIo
, RequestMap
);
739 gBS
->RestoreTPL (OldTpl
);
745 Submits bulk transfer to a bulk endpoint of a USB device.
747 @param This A pointer to the EFI_USB2_HC_PROTOCOL instance.
748 @param DeviceAddress Target device address.
749 @param EndPointAddress Endpoint number and direction.
750 @param DeviceSpeed Device speed.
751 @param MaximumPacketLength Maximum packet size of the target endpoint.
752 @param DataBuffersNumber Number of data buffers prepared for the transfer.
753 @param Data Array of pointers to the buffers of data.
754 @param DataLength On input, size of the data buffer, On output,
755 actually transferred data size.
756 @param DataToggle On input, data toggle to use; On output, next data toggle.
757 @param TimeOut Maximum time out, in microseconds.
758 @param Translator A pointr to the transaction translator data.
759 @param TransferResult Variable to receive transfer result.
761 @return EFI_SUCCESS The bulk transfer was completed successfully.
762 @return EFI_OUT_OF_RESOURCES Failed due to lack of resource.
763 @return EFI_INVALID_PARAMETER Some parameters are invalid.
764 @return EFI_TIMEOUT Failed due to timeout.
765 @return EFI_DEVICE_ERROR Failed due to host controller or device error.
771 IN EFI_USB2_HC_PROTOCOL
*This
,
772 IN UINT8 DeviceAddress
,
773 IN UINT8 EndPointAddress
,
774 IN UINT8 DeviceSpeed
,
775 IN UINTN MaximumPacketLength
,
776 IN UINT8 DataBuffersNumber
,
777 IN OUT VOID
*Data
[EFI_USB_MAX_BULK_BUFFER_NUM
],
778 IN OUT UINTN
*DataLength
,
779 IN OUT UINT8
*DataToggle
,
781 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
782 OUT UINT32
*TransferResult
785 EFI_USB_DATA_DIRECTION Direction
;
790 UHCI_QH_RESULT QhResult
;
796 Uhc
= UHC_FROM_USB2_HC_PROTO (This
);
800 if (DeviceSpeed
== EFI_USB_SPEED_LOW
) {
801 return EFI_INVALID_PARAMETER
;
804 if ((DataLength
== NULL
) || (*DataLength
== 0) || (Data
== NULL
) || (TransferResult
== NULL
)) {
805 return EFI_INVALID_PARAMETER
;
808 if ((*DataToggle
!= 1) && (*DataToggle
!= 0)) {
809 return EFI_INVALID_PARAMETER
;
812 if ((MaximumPacketLength
!= 8) && (MaximumPacketLength
!= 16) &&
813 (MaximumPacketLength
!= 32) && (MaximumPacketLength
!= 64)) {
814 return EFI_INVALID_PARAMETER
;
817 *TransferResult
= EFI_USB_ERR_SYSTEM
;
818 Status
= EFI_OUT_OF_RESOURCES
;
821 // If has errors that cause host controller halt,
822 // then return EFI_DEVICE_ERROR directly.
824 UhciAckAllInterrupt (Uhc
);
826 if (!UhciIsHcWorking (Uhc
->PciIo
)) {
827 return EFI_DEVICE_ERROR
;
830 OldTpl
= gBS
->RaiseTPL (UHCI_TPL
);
833 // Map the source data buffer for bus master access,
834 // then create a list of TDs
836 if ((EndPointAddress
& 0x80) != 0) {
837 Direction
= EfiUsbDataIn
;
839 Direction
= EfiUsbDataOut
;
842 Status
= UhciMapUserData (Uhc
, Direction
, *Data
, DataLength
, &PktId
, &DataPhy
, &DataMap
);
844 if (EFI_ERROR (Status
)) {
848 Status
= EFI_OUT_OF_RESOURCES
;
849 TDs
= UhciCreateBulkOrIntTds (
857 (UINT8
) MaximumPacketLength
,
862 Uhc
->PciIo
->Unmap (Uhc
->PciIo
, DataMap
);
868 // Link the TDs to bulk queue head. According to the platfore
869 // defintion of UHCI_NO_BW_RECLAMATION, BulkQh is either configured
870 // to do full speed bandwidth reclamation or not.
872 BulkQh
= Uhc
->BulkQh
;
874 UhciLinkTdToQh (BulkQh
, TDs
);
875 Status
= UhciExecuteTransfer (Uhc
, BulkQh
, TDs
, TimeOut
, FALSE
, &QhResult
);
876 UhciUnlinkTdFromQh (BulkQh
, TDs
);
878 Uhc
->PciIo
->Flush (Uhc
->PciIo
);
880 *TransferResult
= QhResult
.Result
;
881 *DataToggle
= QhResult
.NextToggle
;
882 *DataLength
= QhResult
.Complete
;
884 UhciDestoryTds (Uhc
, TDs
);
885 Uhc
->PciIo
->Unmap (Uhc
->PciIo
, DataMap
);
888 gBS
->RestoreTPL (OldTpl
);
894 Submits an asynchronous interrupt transfer to an
895 interrupt endpoint of a USB device according to UEFI 2.0 spec.
897 @param This A pointer to the EFI_USB2_HC_PROTOCOL instance.
898 @param DeviceAddress Target device address.
899 @param EndPointAddress Endpoint number and direction.
900 @param DeviceSpeed Device speed.
901 @param MaximumPacketLength Maximum packet size of the target endpoint.
902 @param IsNewTransfer If TRUE, submit a new transfer, if FALSE cancel old transfer.
903 @param DataToggle On input, data toggle to use; On output, next data toggle.
904 @param PollingInterval Interrupt poll rate in milliseconds.
905 @param DataLength On input, size of the data buffer, On output,
906 actually transferred data size.
907 @param Translator A pointr to the transaction translator data.
908 @param CallBackFunction Function to call periodically.
909 @param Context User context.
911 @return EFI_SUCCESS Transfer was submitted.
912 @return EFI_INVALID_PARAMETER Some parameters are invalid.
913 @return EFI_OUT_OF_RESOURCES Failed due to a lack of resources.
914 @return EFI_DEVICE_ERROR Can't read register.
919 Uhci2AsyncInterruptTransfer (
920 IN EFI_USB2_HC_PROTOCOL
*This
,
921 IN UINT8 DeviceAddress
,
922 IN UINT8 EndPointAddress
,
923 IN UINT8 DeviceSpeed
,
924 IN UINTN MaximumPacketLength
,
925 IN BOOLEAN IsNewTransfer
,
926 IN OUT UINT8
*DataToggle
,
927 IN UINTN PollingInterval
,
929 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
930 IN EFI_ASYNC_USB_TRANSFER_CALLBACK CallBackFunction
,
935 BOOLEAN IsSlowDevice
;
945 Uhc
= UHC_FROM_USB2_HC_PROTO (This
);
952 IsSlowDevice
= (BOOLEAN
) ((EFI_USB_SPEED_LOW
== DeviceSpeed
) ? TRUE
: FALSE
);
954 if ((EndPointAddress
& 0x80) == 0) {
955 return EFI_INVALID_PARAMETER
;
959 // Delete Async interrupt transfer request
961 if (!IsNewTransfer
) {
962 OldTpl
= gBS
->RaiseTPL (UHCI_TPL
);
963 Status
= UhciRemoveAsyncReq (Uhc
, DeviceAddress
, EndPointAddress
, DataToggle
);
965 gBS
->RestoreTPL (OldTpl
);
969 if (PollingInterval
< 1 || PollingInterval
> 255) {
970 return EFI_INVALID_PARAMETER
;
973 if (DataLength
== 0) {
974 return EFI_INVALID_PARAMETER
;
977 if ((*DataToggle
!= 1) && (*DataToggle
!= 0)) {
978 return EFI_INVALID_PARAMETER
;
982 // If has errors that cause host controller halt,
983 // then return EFI_DEVICE_ERROR directly.
985 UhciAckAllInterrupt (Uhc
);
987 if (!UhciIsHcWorking (Uhc
->PciIo
)) {
988 return EFI_DEVICE_ERROR
;
992 // Allocate and map source data buffer for bus master access.
994 DataPtr
= AllocatePool (DataLength
);
996 if (DataPtr
== NULL
) {
997 return EFI_OUT_OF_RESOURCES
;
1000 OldTpl
= gBS
->RaiseTPL (UHCI_TPL
);
1003 // Map the user data then create a queue head and
1004 // list of TD for it.
1006 Status
= UhciMapUserData (
1016 if (EFI_ERROR (Status
)) {
1020 Qh
= UhciCreateQh (Uhc
, PollingInterval
);
1023 Status
= EFI_OUT_OF_RESOURCES
;
1027 IntTds
= UhciCreateBulkOrIntTds (
1035 (UINT8
) MaximumPacketLength
,
1039 if (IntTds
== NULL
) {
1040 Status
= EFI_OUT_OF_RESOURCES
;
1044 UhciLinkTdToQh (Qh
, IntTds
);
1047 // Save QH-TD structures to async Interrupt transfer list,
1048 // for monitor interrupt transfer execution routine use.
1050 Status
= UhciCreateAsyncReq (
1065 if (EFI_ERROR (Status
)) {
1069 UhciLinkQhToFrameList (Uhc
->FrameBase
, Qh
);
1071 gBS
->RestoreTPL (OldTpl
);
1075 UsbHcFreeMem (Uhc
->MemPool
, Qh
, sizeof (UHCI_QH_SW
));
1078 Uhc
->PciIo
->Unmap (Uhc
->PciIo
, DataMap
);
1081 gBS
->FreePool (DataPtr
);
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 ((EndPointAddress
& 0x80) == 0) {
1155 return EFI_INVALID_PARAMETER
;
1158 if ((*DataToggle
!= 1) && (*DataToggle
!= 0)) {
1159 return EFI_INVALID_PARAMETER
;
1162 if ((*DataLength
== 0) || (MaximumPacketLength
> 64)) {
1163 return EFI_INVALID_PARAMETER
;
1166 if (IsSlowDevice
&& (MaximumPacketLength
> 8)) {
1167 return EFI_INVALID_PARAMETER
;
1170 *TransferResult
= EFI_USB_ERR_SYSTEM
;
1171 Status
= EFI_DEVICE_ERROR
;
1174 UhciAckAllInterrupt (Uhc
);
1176 if (!UhciIsHcWorking (Uhc
->PciIo
)) {
1180 OldTpl
= gBS
->RaiseTPL (UHCI_TPL
);
1183 // Map the source data buffer for bus master access.
1184 // Create Tds list, then link it to the UHC's interrupt list
1186 Status
= UhciMapUserData (
1196 if (EFI_ERROR (Status
)) {
1200 TDs
= UhciCreateBulkOrIntTds (
1208 (UINT8
) MaximumPacketLength
,
1213 Uhc
->PciIo
->Unmap (Uhc
->PciIo
, DataMap
);
1215 Status
= EFI_OUT_OF_RESOURCES
;
1220 UhciLinkTdToQh (Uhc
->SyncIntQh
, TDs
);
1222 Status
= UhciExecuteTransfer (Uhc
, Uhc
->SyncIntQh
, TDs
, TimeOut
, IsSlowDevice
, &QhResult
);
1224 UhciUnlinkTdFromQh (Uhc
->SyncIntQh
, TDs
);
1225 Uhc
->PciIo
->Flush (Uhc
->PciIo
);
1227 *TransferResult
= QhResult
.Result
;
1228 *DataToggle
= QhResult
.NextToggle
;
1229 *DataLength
= QhResult
.Complete
;
1231 UhciDestoryTds (Uhc
, TDs
);
1232 Uhc
->PciIo
->Unmap (Uhc
->PciIo
, DataMap
);
1235 gBS
->RestoreTPL (OldTpl
);
1241 Submits isochronous transfer to a target USB device according to UEFI 2.0 spec.
1243 @param This A pointer to the EFI_USB2_HC_PROTOCOL instance.
1244 @param DeviceAddress Target device address.
1245 @param EndPointAddress Endpoint number and direction.
1246 @param DeviceSpeed Device speed.
1247 @param MaximumPacketLength Maximum packet size of the target endpoint.
1248 @param DataBuffersNumber Number of data buffers prepared for the transfer.
1249 @param Data Array of pointers to the buffers of data.
1250 @param DataLength On input, size of the data buffer, On output,
1251 actually transferred data size.
1252 @param Translator A pointr to the transaction translator data.
1253 @param TransferResult Variable to receive transfer result.
1255 @return EFI_UNSUPPORTED
1260 Uhci2IsochronousTransfer (
1261 IN EFI_USB2_HC_PROTOCOL
*This
,
1262 IN UINT8 DeviceAddress
,
1263 IN UINT8 EndPointAddress
,
1264 IN UINT8 DeviceSpeed
,
1265 IN UINTN MaximumPacketLength
,
1266 IN UINT8 DataBuffersNumber
,
1267 IN OUT VOID
*Data
[EFI_USB_MAX_ISO_BUFFER_NUM
],
1268 IN UINTN DataLength
,
1269 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
1270 OUT UINT32
*TransferResult
1273 return EFI_UNSUPPORTED
;
1278 Submits Async isochronous transfer to a target USB device according to UEFI 2.0 spec.
1280 @param This A pointer to the EFI_USB2_HC_PROTOCOL instance.
1281 @param DeviceAddress Target device address.
1282 @param EndPointAddress Endpoint number and direction.
1283 @param DeviceSpeed Device speed.
1284 @param MaximumPacketLength Maximum packet size of the target endpoint.
1285 @param DataBuffersNumber Number of data buffers prepared for the transfer.
1286 @param Data Array of pointers to the buffers of data.
1287 @param DataLength On input, size of the data buffer, On output,
1288 actually transferred data size.
1289 @param Translator A pointr to the transaction translator data.
1290 @param IsochronousCallBack Function to call when the transfer complete.
1291 @param Context Pass to the call back function as parameter.
1293 @return EFI_UNSUPPORTED
1298 Uhci2AsyncIsochronousTransfer (
1299 IN EFI_USB2_HC_PROTOCOL
*This
,
1300 IN UINT8 DeviceAddress
,
1301 IN UINT8 EndPointAddress
,
1302 IN UINT8 DeviceSpeed
,
1303 IN UINTN MaximumPacketLength
,
1304 IN UINT8 DataBuffersNumber
,
1305 IN OUT VOID
*Data
[EFI_USB_MAX_ISO_BUFFER_NUM
],
1306 IN UINTN DataLength
,
1307 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
1308 IN EFI_ASYNC_USB_TRANSFER_CALLBACK IsochronousCallBack
,
1312 return EFI_UNSUPPORTED
;
1316 Entry point for EFI drivers.
1318 @param ImageHandle EFI_HANDLE.
1319 @param SystemTable EFI_SYSTEM_TABLE.
1321 @retval EFI_SUCCESS Driver is successfully loaded.
1322 @return Others Failed.
1327 UhciDriverEntryPoint (
1328 IN EFI_HANDLE ImageHandle
,
1329 IN EFI_SYSTEM_TABLE
*SystemTable
1332 return EfiLibInstallDriverBindingComponentName2 (
1335 &gUhciDriverBinding
,
1337 &gUhciComponentName
,
1338 &gUhciComponentName2
1344 Test to see if this driver supports ControllerHandle. Any
1345 ControllerHandle that has UsbHcProtocol installed will be supported.
1347 @param This Protocol instance pointer.
1348 @param Controller Handle of device to test.
1349 @param RemainingDevicePath Not used.
1351 @return EFI_SUCCESS This driver supports this device.
1352 @return EFI_UNSUPPORTED This driver does not support this device.
1357 UhciDriverBindingSupported (
1358 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1359 IN EFI_HANDLE Controller
,
1360 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
1363 EFI_STATUS OpenStatus
;
1365 EFI_PCI_IO_PROTOCOL
*PciIo
;
1366 USB_CLASSC UsbClassCReg
;
1369 // Test whether there is PCI IO Protocol attached on the controller handle.
1371 OpenStatus
= gBS
->OpenProtocol (
1373 &gEfiPciIoProtocolGuid
,
1375 This
->DriverBindingHandle
,
1377 EFI_OPEN_PROTOCOL_BY_DRIVER
1380 if (EFI_ERROR (OpenStatus
)) {
1384 Status
= PciIo
->Pci
.Read (
1388 sizeof (USB_CLASSC
) / sizeof (UINT8
),
1392 if (EFI_ERROR (Status
)) {
1393 Status
= EFI_UNSUPPORTED
;
1398 // Test whether the controller belongs to UHCI type
1400 if ((UsbClassCReg
.BaseCode
!= PCI_CLASS_SERIAL
) ||
1401 (UsbClassCReg
.SubClassCode
!= PCI_CLASS_SERIAL_USB
) ||
1402 (UsbClassCReg
.PI
!= PCI_CLASSC_PI_UHCI
)
1405 Status
= EFI_UNSUPPORTED
;
1409 gBS
->CloseProtocol (
1411 &gEfiPciIoProtocolGuid
,
1412 This
->DriverBindingHandle
,
1422 Allocate and initialize the empty UHCI device.
1424 @param PciIo The PCIIO to use.
1425 @param OriginalPciAttributes The original PCI attributes.
1427 @return Allocated UHCI device. If err, return NULL.
1432 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
1433 IN UINT64 OriginalPciAttributes
1439 Uhc
= AllocateZeroPool (sizeof (USB_HC_DEV
));
1446 // This driver supports both USB_HC_PROTOCOL and USB2_HC_PROTOCOL.
1447 // USB_HC_PROTOCOL is for EFI 1.1 backward compability.
1449 Uhc
->Signature
= USB_HC_DEV_SIGNATURE
;
1450 Uhc
->Usb2Hc
.GetCapability
= Uhci2GetCapability
;
1451 Uhc
->Usb2Hc
.Reset
= Uhci2Reset
;
1452 Uhc
->Usb2Hc
.GetState
= Uhci2GetState
;
1453 Uhc
->Usb2Hc
.SetState
= Uhci2SetState
;
1454 Uhc
->Usb2Hc
.ControlTransfer
= Uhci2ControlTransfer
;
1455 Uhc
->Usb2Hc
.BulkTransfer
= Uhci2BulkTransfer
;
1456 Uhc
->Usb2Hc
.AsyncInterruptTransfer
= Uhci2AsyncInterruptTransfer
;
1457 Uhc
->Usb2Hc
.SyncInterruptTransfer
= Uhci2SyncInterruptTransfer
;
1458 Uhc
->Usb2Hc
.IsochronousTransfer
= Uhci2IsochronousTransfer
;
1459 Uhc
->Usb2Hc
.AsyncIsochronousTransfer
= Uhci2AsyncIsochronousTransfer
;
1460 Uhc
->Usb2Hc
.GetRootHubPortStatus
= Uhci2GetRootHubPortStatus
;
1461 Uhc
->Usb2Hc
.SetRootHubPortFeature
= Uhci2SetRootHubPortFeature
;
1462 Uhc
->Usb2Hc
.ClearRootHubPortFeature
= Uhci2ClearRootHubPortFeature
;
1463 Uhc
->Usb2Hc
.MajorRevision
= 0x1;
1464 Uhc
->Usb2Hc
.MinorRevision
= 0x1;
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
);
1493 gBS
->FreePool (Uhc
);
1499 Free the UHCI device and release its associated resources.
1501 @param Uhc The UHCI device to release.
1511 if (Uhc
->AsyncIntMonitor
!= NULL
) {
1512 gBS
->CloseEvent (Uhc
->AsyncIntMonitor
);
1515 if (Uhc
->MemPool
!= NULL
) {
1516 UsbHcFreeMemPool (Uhc
->MemPool
);
1519 if (Uhc
->CtrlNameTable
!= NULL
) {
1520 FreeUnicodeStringTable (Uhc
->CtrlNameTable
);
1523 gBS
->FreePool (Uhc
);
1528 Uninstall all Uhci Interface.
1530 @param Controller Controller handle.
1531 @param This Protocol instance pointer.
1538 IN EFI_HANDLE Controller
,
1539 IN EFI_USB2_HC_PROTOCOL
*This
1545 // Uninstall the USB_HC and USB_HC2 protocol, then disable the controller
1547 Uhc
= UHC_FROM_USB2_HC_PROTO (This
);
1548 UhciStopHc (Uhc
, UHC_GENERIC_TIMEOUT
);
1550 gBS
->UninstallProtocolInterface (
1552 &gEfiUsb2HcProtocolGuid
,
1556 UhciFreeAllAsyncReq (Uhc
);
1557 UhciDestoryFrameList (Uhc
);
1560 // Restore original PCI attributes
1562 Uhc
->PciIo
->Attributes (
1564 EfiPciIoAttributeOperationSet
,
1565 Uhc
->OriginalPciAttributes
,
1574 Starting the Usb UHCI Driver.
1576 @param This Protocol instance pointer.
1577 @param Controller Handle of device to test.
1578 @param RemainingDevicePath Not used.
1580 @retval EFI_SUCCESS This driver supports this device.
1581 @retval EFI_UNSUPPORTED This driver does not support this device.
1582 @retval EFI_DEVICE_ERROR This driver cannot be started due to device Error.
1583 EFI_OUT_OF_RESOURCES- Failed due to resource shortage.
1588 UhciDriverBindingStart (
1589 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1590 IN EFI_HANDLE Controller
,
1591 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
1595 EFI_PCI_IO_PROTOCOL
*PciIo
;
1598 UINT64 OriginalPciAttributes
;
1599 BOOLEAN PciAttributesSaved
;
1602 // Open PCIIO, then enable the EHC device and turn off emulation
1605 Status
= gBS
->OpenProtocol (
1607 &gEfiPciIoProtocolGuid
,
1609 This
->DriverBindingHandle
,
1611 EFI_OPEN_PROTOCOL_BY_DRIVER
1614 if (EFI_ERROR (Status
)) {
1618 PciAttributesSaved
= FALSE
;
1620 // Save original PCI attributes
1622 Status
= PciIo
->Attributes (
1624 EfiPciIoAttributeOperationGet
,
1626 &OriginalPciAttributes
1629 if (EFI_ERROR (Status
)) {
1632 PciAttributesSaved
= TRUE
;
1635 // Robustnesss improvement such as for UoL
1636 // Default is not required.
1638 if (FeaturePcdGet (PcdTurnOffUsbLegacySupport
)) {
1639 UhciTurnOffUsbEmulation (PciIo
);
1642 Status
= PciIo
->Attributes (
1644 EfiPciIoAttributeOperationSupported
,
1648 if (!EFI_ERROR (Status
)) {
1649 Supports
&= EFI_PCI_DEVICE_ENABLE
;
1650 Status
= PciIo
->Attributes (
1652 EfiPciIoAttributeOperationEnable
,
1658 if (EFI_ERROR (Status
)) {
1662 Uhc
= UhciAllocateDev (PciIo
, OriginalPciAttributes
);
1665 Status
= EFI_OUT_OF_RESOURCES
;
1670 // Allocate and Init Host Controller's Frame List Entry
1672 Status
= UhciInitFrameList (Uhc
);
1674 if (EFI_ERROR (Status
)) {
1675 Status
= EFI_OUT_OF_RESOURCES
;
1679 Status
= gBS
->SetTimer (
1680 Uhc
->AsyncIntMonitor
,
1682 UHC_ASYNC_POLL_INTERVAL
1685 if (EFI_ERROR (Status
)) {
1690 // Install USB2_HC_PROTOCOL
1692 Status
= gBS
->InstallMultipleProtocolInterfaces (
1694 &gEfiUsb2HcProtocolGuid
,
1699 if (EFI_ERROR (Status
)) {
1704 // Install the component name protocol
1706 Uhc
->CtrlNameTable
= NULL
;
1710 gUhciComponentName
.SupportedLanguages
,
1711 &Uhc
->CtrlNameTable
,
1712 L
"Usb Universal Host Controller",
1717 gUhciComponentName2
.SupportedLanguages
,
1718 &Uhc
->CtrlNameTable
,
1719 L
"Usb Universal Host Controller",
1725 // Start the UHCI hardware, also set its reclamation point to 64 bytes
1727 UhciWriteReg (Uhc
->PciIo
, USBCMD_OFFSET
, USBCMD_RS
| USBCMD_MAXP
);
1735 if (PciAttributesSaved
) {
1737 // Restore original PCI attributes
1741 EfiPciIoAttributeOperationSet
,
1742 OriginalPciAttributes
,
1747 gBS
->CloseProtocol (
1749 &gEfiPciIoProtocolGuid
,
1750 This
->DriverBindingHandle
,
1759 Stop this driver on ControllerHandle. Support stoping any child handles
1760 created by this driver.
1762 @param This Protocol instance pointer.
1763 @param Controller Handle of device to stop driver on.
1764 @param NumberOfChildren Number of Children in the ChildHandleBuffer.
1765 @param ChildHandleBuffer List of handles for the children we need to stop.
1773 UhciDriverBindingStop (
1774 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1775 IN EFI_HANDLE Controller
,
1776 IN UINTN NumberOfChildren
,
1777 IN EFI_HANDLE
*ChildHandleBuffer
1780 EFI_USB2_HC_PROTOCOL
*Usb2Hc
;
1783 Status
= gBS
->OpenProtocol (
1785 &gEfiUsb2HcProtocolGuid
,
1787 This
->DriverBindingHandle
,
1789 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1793 // Test whether the Controller handler passed in is a valid
1794 // Usb controller handle that should be supported, if not,
1795 // return the error status directly
1797 if (EFI_ERROR (Status
)) {
1801 UhciCleanDevUp (Controller
, Usb2Hc
);
1803 gBS
->CloseProtocol (
1805 &gEfiPciIoProtocolGuid
,
1806 This
->DriverBindingHandle
,