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 Provides software reset for the USB host controller according to UEFI 2.0 spec.
21 @param This A pointer to the EFI_USB2_HC_PROTOCOL instance.
22 @param Attributes A bit mask of the reset operation to perform. See
23 below for a list of the supported bit mask values.
25 @return EFI_SUCCESS The reset operation succeeded.
26 @return EFI_INVALID_PARAMETER Attributes is not valid.
27 @return EFI_UNSUPPORTED This type of reset is not currently supported.
28 @return EFI_DEVICE_ERROR Other errors.
34 IN EFI_USB2_HC_PROTOCOL
*This
,
41 if ((Attributes
== EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG
) ||
42 (Attributes
== EFI_USB_HC_RESET_HOST_WITH_DEBUG
)) {
43 return EFI_UNSUPPORTED
;
46 Uhc
= UHC_FROM_USB2_HC_PROTO (This
);
48 OldTpl
= gBS
->RaiseTPL (UHCI_TPL
);
51 case EFI_USB_HC_RESET_GLOBAL
:
53 // Stop schedule and set the Global Reset bit in the command register
55 UhciStopHc (Uhc
, UHC_GENERIC_TIMEOUT
);
56 UhciSetRegBit (Uhc
->PciIo
, USBCMD_OFFSET
, USBCMD_GRESET
);
58 gBS
->Stall (UHC_ROOT_PORT_RESET_STALL
);
61 // Clear the Global Reset bit to zero.
63 UhciClearRegBit (Uhc
->PciIo
, USBCMD_OFFSET
, USBCMD_GRESET
);
65 gBS
->Stall (UHC_ROOT_PORT_RECOVERY_STALL
);
68 case EFI_USB_HC_RESET_HOST_CONTROLLER
:
70 // Stop schedule and set Host Controller Reset bit to 1
72 UhciStopHc (Uhc
, UHC_GENERIC_TIMEOUT
);
73 UhciSetRegBit (Uhc
->PciIo
, USBCMD_OFFSET
, USBCMD_HCRESET
);
75 gBS
->Stall (UHC_ROOT_PORT_RECOVERY_STALL
);
79 goto ON_INVAILD_PARAMETER
;
83 // Delete all old transactions on the USB bus, then
84 // reinitialize the frame list
86 UhciFreeAllAsyncReq (Uhc
);
87 UhciDestoryFrameList (Uhc
);
88 UhciInitFrameList (Uhc
);
90 gBS
->RestoreTPL (OldTpl
);
96 gBS
->RestoreTPL (OldTpl
);
98 return EFI_INVALID_PARAMETER
;
103 Retrieves current state of the USB host controller according to UEFI 2.0 spec.
105 @param This A pointer to the EFI_USB2_HC_PROTOCOL instance.
106 @param State Variable to receive current device state.
108 @return EFI_SUCCESS The state is returned.
109 @return EFI_INVALID_PARAMETER State is not valid.
110 @return EFI_DEVICE_ERROR Other errors.
116 IN CONST EFI_USB2_HC_PROTOCOL
*This
,
117 OUT EFI_USB_HC_STATE
*State
125 return EFI_INVALID_PARAMETER
;
128 Uhc
= UHC_FROM_USB2_HC_PROTO (This
);
130 UsbCmd
= UhciReadReg (Uhc
->PciIo
, USBCMD_OFFSET
);
131 UsbSts
= UhciReadReg (Uhc
->PciIo
, USBSTS_OFFSET
);
133 if ((UsbCmd
& USBCMD_EGSM
) !=0 ) {
134 *State
= EfiUsbHcStateSuspend
;
136 } else if ((UsbSts
& USBSTS_HCH
) != 0) {
137 *State
= EfiUsbHcStateHalt
;
140 *State
= EfiUsbHcStateOperational
;
148 Sets the USB host controller to a specific state according to UEFI 2.0 spec.
150 @param This A pointer to the EFI_USB2_HC_PROTOCOL instance.
151 @param State Indicates the state of the host controller that will
154 @return EFI_SUCCESS Host controller was successfully placed in the state.
155 @return EFI_INVALID_PARAMETER State is invalid.
156 @return EFI_DEVICE_ERROR Failed to set the state.
162 IN EFI_USB2_HC_PROTOCOL
*This
,
163 IN EFI_USB_HC_STATE State
166 EFI_USB_HC_STATE CurState
;
172 Uhc
= UHC_FROM_USB2_HC_PROTO (This
);
173 Status
= Uhci2GetState (This
, &CurState
);
175 if (EFI_ERROR (Status
)) {
176 return EFI_DEVICE_ERROR
;
179 if (CurState
== State
) {
183 Status
= EFI_SUCCESS
;
184 OldTpl
= gBS
->RaiseTPL (UHCI_TPL
);
187 case EfiUsbHcStateHalt
:
188 Status
= UhciStopHc (Uhc
, UHC_GENERIC_TIMEOUT
);
191 case EfiUsbHcStateOperational
:
192 UsbCmd
= UhciReadReg (Uhc
->PciIo
, USBCMD_OFFSET
);
194 if (CurState
== EfiUsbHcStateHalt
) {
196 // Set Run/Stop bit to 1, also set the bandwidht reclamation
199 UsbCmd
|= USBCMD_RS
| USBCMD_MAXP
;
200 UhciWriteReg (Uhc
->PciIo
, USBCMD_OFFSET
, UsbCmd
);
202 } else if (CurState
== EfiUsbHcStateSuspend
) {
204 // If FGR(Force Global Resume) bit is 0, set it
206 if ((UsbCmd
& USBCMD_FGR
) == 0) {
207 UsbCmd
|= USBCMD_FGR
;
208 UhciWriteReg (Uhc
->PciIo
, USBCMD_OFFSET
, UsbCmd
);
212 // wait 20ms to let resume complete (20ms is specified by UHCI spec)
214 gBS
->Stall (UHC_FORCE_GLOBAL_RESUME_STALL
);
217 // Write FGR bit to 0 and EGSM(Enter Global Suspend Mode) bit to 0
219 UsbCmd
&= ~USBCMD_FGR
;
220 UsbCmd
&= ~USBCMD_EGSM
;
222 UhciWriteReg (Uhc
->PciIo
, USBCMD_OFFSET
, UsbCmd
);
227 case EfiUsbHcStateSuspend
:
228 Status
= Uhci2SetState (This
, EfiUsbHcStateHalt
);
230 if (EFI_ERROR (Status
)) {
231 Status
= EFI_DEVICE_ERROR
;
236 // Set Enter Global Suspend Mode bit to 1.
238 UsbCmd
= UhciReadReg (Uhc
->PciIo
, USBCMD_OFFSET
);
239 UsbCmd
|= USBCMD_EGSM
;
240 UhciWriteReg (Uhc
->PciIo
, USBCMD_OFFSET
, UsbCmd
);
244 Status
= EFI_INVALID_PARAMETER
;
249 gBS
->RestoreTPL (OldTpl
);
254 Retrieves capabilities of USB host controller according to UEFI 2.0 spec.
256 @param This A pointer to the EFI_USB2_HC_PROTOCOL instance.
257 @param MaxSpeed A pointer to the max speed USB host controller
259 @param PortNumber A pointer to the number of root hub ports.
260 @param Is64BitCapable A pointer to an integer to show whether USB host
261 controller supports 64-bit memory addressing.
263 @return EFI_SUCCESS capabilities were retrieved successfully.
264 @return EFI_INVALID_PARAMETER MaxSpeed or PortNumber or Is64BitCapable is NULL.
265 @return EFI_DEVICE_ERROR An error was encountered.
271 IN EFI_USB2_HC_PROTOCOL
*This
,
273 OUT UINT8
*PortNumber
,
274 OUT UINT8
*Is64BitCapable
282 Uhc
= UHC_FROM_USB2_HC_PROTO (This
);
284 if ((NULL
== MaxSpeed
) || (NULL
== PortNumber
) || (NULL
== Is64BitCapable
)) {
285 return EFI_INVALID_PARAMETER
;
288 *MaxSpeed
= EFI_USB_SPEED_FULL
;
289 *Is64BitCapable
= (UINT8
) FALSE
;
293 for (Index
= 0; Index
< USB_MAX_ROOTHUB_PORT
; Index
++) {
294 Offset
= USBPORTSC_OFFSET
+ Index
* 2;
295 PortSC
= UhciReadReg (Uhc
->PciIo
, Offset
);
298 // Port status's bit 7 is reserved and always returns 1 if
299 // the port number is valid. Intel's UHCI (in EHCI controller)
300 // returns 0 in this bit if port number is invalid. Also, if
301 // PciIo IoRead returns error, 0xFFFF is returned to caller.
303 if (((PortSC
& 0x80) == 0) || (PortSC
== 0xFFFF)) {
309 Uhc
->RootPorts
= *PortNumber
;
311 DEBUG ((EFI_D_INFO
, "Uhci2GetCapability: %d ports\n", Uhc
->RootPorts
));
317 Retrieves the current status of a USB root hub port according to UEFI 2.0 spec.
319 @param This A pointer to the EFI_USB2_HC_PROTOCOL.
320 @param PortNumber The port to get status.
321 @param PortStatus A pointer to the current port status bits and port
324 @return EFI_SUCCESS status of the USB root hub port was returned in PortStatus.
325 @return EFI_INVALID_PARAMETER PortNumber is invalid.
326 @return EFI_DEVICE_ERROR Can't read register.
331 Uhci2GetRootHubPortStatus (
332 IN CONST EFI_USB2_HC_PROTOCOL
*This
,
333 IN CONST UINT8 PortNumber
,
334 OUT EFI_USB_PORT_STATUS
*PortStatus
341 Uhc
= UHC_FROM_USB2_HC_PROTO (This
);
343 if (PortStatus
== NULL
) {
344 return EFI_INVALID_PARAMETER
;
347 if (PortNumber
>= Uhc
->RootPorts
) {
348 return EFI_INVALID_PARAMETER
;
351 Offset
= USBPORTSC_OFFSET
+ PortNumber
* 2;
352 PortStatus
->PortStatus
= 0;
353 PortStatus
->PortChangeStatus
= 0;
355 PortSC
= UhciReadReg (Uhc
->PciIo
, Offset
);
357 if ((PortSC
& USBPORTSC_CCS
) != 0) {
358 PortStatus
->PortStatus
|= USB_PORT_STAT_CONNECTION
;
361 if ((PortSC
& USBPORTSC_PED
) != 0) {
362 PortStatus
->PortStatus
|= USB_PORT_STAT_ENABLE
;
365 if ((PortSC
& USBPORTSC_SUSP
) != 0) {
366 DEBUG ((EFI_D_INFO
, "Uhci2GetRootHubPortStatus: port %d is suspended\n", PortNumber
));
367 PortStatus
->PortStatus
|= USB_PORT_STAT_SUSPEND
;
370 if ((PortSC
& USBPORTSC_PR
) != 0) {
371 PortStatus
->PortStatus
|= USB_PORT_STAT_RESET
;
374 if ((PortSC
& USBPORTSC_LSDA
) != 0) {
375 PortStatus
->PortStatus
|= USB_PORT_STAT_LOW_SPEED
;
379 // CHC will always return one in port owner bit
381 PortStatus
->PortStatus
|= USB_PORT_STAT_OWNER
;
383 if ((PortSC
& USBPORTSC_CSC
) != 0) {
384 PortStatus
->PortChangeStatus
|= USB_PORT_STAT_C_CONNECTION
;
387 if ((PortSC
& USBPORTSC_PEDC
) != 0) {
388 PortStatus
->PortChangeStatus
|= USB_PORT_STAT_C_ENABLE
;
396 Sets a feature for the specified root hub port according to UEFI 2.0 spec.
398 @param This A pointer to the EFI_USB2_HC_PROTOCOL.
399 @param PortNumber Specifies the root hub port whose feature is
401 @param PortFeature Indicates the feature selector associated with the
404 @return EFI_SUCCESS PortFeature was set for the root port.
405 @return EFI_INVALID_PARAMETER PortNumber is invalid or PortFeature is invalid.
406 @return EFI_DEVICE_ERROR Can't read register.
411 Uhci2SetRootHubPortFeature (
412 IN EFI_USB2_HC_PROTOCOL
*This
,
414 IN EFI_USB_PORT_FEATURE PortFeature
423 Uhc
= UHC_FROM_USB2_HC_PROTO (This
);
425 if (PortNumber
>= Uhc
->RootPorts
) {
426 return EFI_INVALID_PARAMETER
;
429 Offset
= USBPORTSC_OFFSET
+ PortNumber
* 2;
431 OldTpl
= gBS
->RaiseTPL (UHCI_TPL
);
432 PortSC
= UhciReadReg (Uhc
->PciIo
, Offset
);
434 switch (PortFeature
) {
435 case EfiUsbPortSuspend
:
436 Command
= UhciReadReg (Uhc
->PciIo
, USBCMD_OFFSET
);
437 if ((Command
& USBCMD_EGSM
) == 0) {
439 // if global suspend is not active, can set port suspend
442 PortSC
|= USBPORTSC_SUSP
;
446 case EfiUsbPortReset
:
448 PortSC
|= USBPORTSC_PR
;
451 case EfiUsbPortPower
:
457 case EfiUsbPortEnable
:
459 PortSC
|= USBPORTSC_PED
;
463 gBS
->RestoreTPL (OldTpl
);
464 return EFI_INVALID_PARAMETER
;
467 UhciWriteReg (Uhc
->PciIo
, Offset
, PortSC
);
468 gBS
->RestoreTPL (OldTpl
);
475 Clears a feature for the specified root hub port according to Uefi 2.0 spec.
477 @param This A pointer to the EFI_USB2_HC_PROTOCOL instance.
478 @param PortNumber Specifies the root hub port whose feature is
479 requested to be cleared.
480 @param PortFeature Indicates the feature selector associated with the
481 feature clear request.
483 @return EFI_SUCCESS PortFeature was cleared for the USB root hub port.
484 @return EFI_INVALID_PARAMETER PortNumber is invalid or PortFeature is invalid.
485 @return EFI_DEVICE_ERROR Can't read register.
490 Uhci2ClearRootHubPortFeature (
491 IN EFI_USB2_HC_PROTOCOL
*This
,
493 IN EFI_USB_PORT_FEATURE PortFeature
501 Uhc
= UHC_FROM_USB2_HC_PROTO (This
);
503 if (PortNumber
>= Uhc
->RootPorts
) {
504 return EFI_INVALID_PARAMETER
;
507 Offset
= USBPORTSC_OFFSET
+ PortNumber
* 2;
509 OldTpl
= gBS
->RaiseTPL (UHCI_TPL
);
510 PortSC
= UhciReadReg (Uhc
->PciIo
, Offset
);
512 switch (PortFeature
) {
513 case EfiUsbPortEnable
:
515 PortSC
&= ~USBPORTSC_PED
;
518 case EfiUsbPortSuspend
:
520 // Cause a resume on the specified port if in suspend mode.
523 PortSC
&= ~USBPORTSC_SUSP
;
526 case EfiUsbPortPower
:
532 case EfiUsbPortReset
:
534 PortSC
&= ~USBPORTSC_PR
;
537 case EfiUsbPortConnectChange
:
539 PortSC
|= USBPORTSC_CSC
;
542 case EfiUsbPortEnableChange
:
544 PortSC
|= USBPORTSC_PEDC
;
547 case EfiUsbPortSuspendChange
:
549 // Root hub does not support this
553 case EfiUsbPortOverCurrentChange
:
555 // Root hub does not support this
559 case EfiUsbPortResetChange
:
561 // Root hub does not support this
566 gBS
->RestoreTPL (OldTpl
);
567 return EFI_INVALID_PARAMETER
;
570 UhciWriteReg (Uhc
->PciIo
, Offset
, PortSC
);
571 gBS
->RestoreTPL (OldTpl
);
578 Submits control transfer to a target USB device accroding to UEFI 2.0 spec.
580 @param This A pointer to the EFI_USB2_HC_PROTOCOL instance.
581 @param DeviceAddress Target device address.
582 @param DeviceSpeed Device speed.
583 @param MaximumPacketLength Maximum packet size of the target endpoint.
584 @param Request USB device request to send.
585 @param TransferDirection Data direction of the Data stage in control transfer.
586 @param Data Data to transmit/receive in data stage.
587 @param DataLength Length of the data.
588 @param TimeOut Maximum time, in microseconds, for transfer to complete.
589 @param Translator Transaction translator to be used by this device.
590 @param TransferResult Variable to receive the transfer result.
592 @return EFI_SUCCESS The control transfer was completed successfully.
593 @return EFI_OUT_OF_RESOURCES Failed due to lack of resource.
594 @return EFI_INVALID_PARAMETER Some parameters are invalid.
595 @return EFI_TIMEOUT Failed due to timeout.
596 @return EFI_DEVICE_ERROR Failed due to host controller or device error.
601 Uhci2ControlTransfer (
602 IN EFI_USB2_HC_PROTOCOL
*This
,
603 IN UINT8 DeviceAddress
,
604 IN UINT8 DeviceSpeed
,
605 IN UINTN MaximumPacketLength
,
606 IN EFI_USB_DEVICE_REQUEST
*Request
,
607 IN EFI_USB_DATA_DIRECTION TransferDirection
,
609 IN OUT UINTN
*DataLength
,
611 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
612 OUT UINT32
*TransferResult
619 UHCI_QH_RESULT QhResult
;
625 BOOLEAN IsSlowDevice
;
627 Uhc
= UHC_FROM_USB2_HC_PROTO (This
);
634 IsSlowDevice
= (BOOLEAN
) ((EFI_USB_SPEED_LOW
== DeviceSpeed
) ? TRUE
: FALSE
);
637 // Parameters Checking
639 if (Request
== NULL
|| TransferResult
== NULL
) {
640 return EFI_INVALID_PARAMETER
;
643 if (IsSlowDevice
&& (MaximumPacketLength
!= 8)) {
644 return EFI_INVALID_PARAMETER
;
647 if ((MaximumPacketLength
!= 8) && (MaximumPacketLength
!= 16) &&
648 (MaximumPacketLength
!= 32) && (MaximumPacketLength
!= 64)) {
650 return EFI_INVALID_PARAMETER
;
653 if ((TransferDirection
!= EfiUsbNoData
) && (DataLength
== NULL
)) {
654 return EFI_INVALID_PARAMETER
;
657 *TransferResult
= EFI_USB_ERR_SYSTEM
;
658 Status
= EFI_DEVICE_ERROR
;
661 // If errors exist that cause host controller halt,
662 // clear status then return EFI_DEVICE_ERROR.
664 UhciAckAllInterrupt (Uhc
);
666 if (!UhciIsHcWorking (Uhc
->PciIo
)) {
667 return EFI_DEVICE_ERROR
;
670 OldTpl
= gBS
->RaiseTPL (UHCI_TPL
);
673 // Map the Request and data for bus master access,
674 // then create a list of TD for this transfer
676 Status
= UhciMapUserRequest (Uhc
, Request
, &RequestPhy
, &RequestMap
);
678 if (EFI_ERROR (Status
)) {
682 Status
= UhciMapUserData (Uhc
, TransferDirection
, Data
, DataLength
, &PktId
, &DataPhy
, &DataMap
);
684 if (EFI_ERROR (Status
)) {
685 Uhc
->PciIo
->Unmap (Uhc
->PciIo
, RequestMap
);
689 TDs
= UhciCreateCtrlTds (
696 (UINT8
) MaximumPacketLength
,
701 Status
= EFI_OUT_OF_RESOURCES
;
706 // According to the speed of the end point, link
707 // the TD to corrosponding queue head, then check
708 // the execution result
710 UhciLinkTdToQh (Uhc
->CtrlQh
, TDs
);
711 Status
= UhciExecuteTransfer (Uhc
, Uhc
->CtrlQh
, TDs
, TimeOut
, IsSlowDevice
, &QhResult
);
712 UhciUnlinkTdFromQh (Uhc
->CtrlQh
, TDs
);
714 Uhc
->PciIo
->Flush (Uhc
->PciIo
);
716 *TransferResult
= QhResult
.Result
;
718 if (DataLength
!= NULL
) {
719 *DataLength
= QhResult
.Complete
;
722 UhciDestoryTds (Uhc
, TDs
);
725 Uhc
->PciIo
->Unmap (Uhc
->PciIo
, DataMap
);
726 Uhc
->PciIo
->Unmap (Uhc
->PciIo
, RequestMap
);
729 gBS
->RestoreTPL (OldTpl
);
735 Submits bulk transfer to a bulk endpoint of a USB device.
737 @param This A pointer to the EFI_USB2_HC_PROTOCOL instance.
738 @param DeviceAddress Target device address.
739 @param EndPointAddress Endpoint number and direction.
740 @param DeviceSpeed Device speed.
741 @param MaximumPacketLength Maximum packet size of the target endpoint.
742 @param DataBuffersNumber Number of data buffers prepared for the transfer.
743 @param Data Array of pointers to the buffers of data.
744 @param DataLength On input, size of the data buffer, On output,
745 actually transferred data size.
746 @param DataToggle On input, data toggle to use; On output, next data toggle.
747 @param TimeOut Maximum time out, in microseconds.
748 @param Translator A pointr to the transaction translator data.
749 @param TransferResult Variable to receive transfer result.
751 @return EFI_SUCCESS The bulk transfer was completed successfully.
752 @return EFI_OUT_OF_RESOURCES Failed due to lack of resource.
753 @return EFI_INVALID_PARAMETER Some parameters are invalid.
754 @return EFI_TIMEOUT Failed due to timeout.
755 @return EFI_DEVICE_ERROR Failed due to host controller or device error.
761 IN EFI_USB2_HC_PROTOCOL
*This
,
762 IN UINT8 DeviceAddress
,
763 IN UINT8 EndPointAddress
,
764 IN UINT8 DeviceSpeed
,
765 IN UINTN MaximumPacketLength
,
766 IN UINT8 DataBuffersNumber
,
767 IN OUT VOID
*Data
[EFI_USB_MAX_BULK_BUFFER_NUM
],
768 IN OUT UINTN
*DataLength
,
769 IN OUT UINT8
*DataToggle
,
771 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
772 OUT UINT32
*TransferResult
775 EFI_USB_DATA_DIRECTION Direction
;
780 UHCI_QH_RESULT QhResult
;
786 Uhc
= UHC_FROM_USB2_HC_PROTO (This
);
790 if (DeviceSpeed
== EFI_USB_SPEED_LOW
) {
791 return EFI_INVALID_PARAMETER
;
794 if ((DataLength
== NULL
) || (*DataLength
== 0) || (Data
== NULL
) || (TransferResult
== NULL
)) {
795 return EFI_INVALID_PARAMETER
;
798 if ((*DataToggle
!= 1) && (*DataToggle
!= 0)) {
799 return EFI_INVALID_PARAMETER
;
802 if ((MaximumPacketLength
!= 8) && (MaximumPacketLength
!= 16) &&
803 (MaximumPacketLength
!= 32) && (MaximumPacketLength
!= 64)) {
804 return EFI_INVALID_PARAMETER
;
807 *TransferResult
= EFI_USB_ERR_SYSTEM
;
808 Status
= EFI_OUT_OF_RESOURCES
;
811 // If has errors that cause host controller halt,
812 // then return EFI_DEVICE_ERROR directly.
814 UhciAckAllInterrupt (Uhc
);
816 if (!UhciIsHcWorking (Uhc
->PciIo
)) {
817 return EFI_DEVICE_ERROR
;
820 OldTpl
= gBS
->RaiseTPL (UHCI_TPL
);
823 // Map the source data buffer for bus master access,
824 // then create a list of TDs
826 if ((EndPointAddress
& 0x80) != 0) {
827 Direction
= EfiUsbDataIn
;
829 Direction
= EfiUsbDataOut
;
832 Status
= UhciMapUserData (Uhc
, Direction
, *Data
, DataLength
, &PktId
, &DataPhy
, &DataMap
);
834 if (EFI_ERROR (Status
)) {
838 Status
= EFI_OUT_OF_RESOURCES
;
839 TDs
= UhciCreateBulkOrIntTds (
847 (UINT8
) MaximumPacketLength
,
852 Uhc
->PciIo
->Unmap (Uhc
->PciIo
, DataMap
);
858 // Link the TDs to bulk queue head. According to the platfore
859 // defintion of UHCI_NO_BW_RECLAMATION, BulkQh is either configured
860 // to do full speed bandwidth reclamation or not.
862 BulkQh
= Uhc
->BulkQh
;
864 UhciLinkTdToQh (BulkQh
, TDs
);
865 Status
= UhciExecuteTransfer (Uhc
, BulkQh
, TDs
, TimeOut
, FALSE
, &QhResult
);
866 UhciUnlinkTdFromQh (BulkQh
, TDs
);
868 Uhc
->PciIo
->Flush (Uhc
->PciIo
);
870 *TransferResult
= QhResult
.Result
;
871 *DataToggle
= QhResult
.NextToggle
;
872 *DataLength
= QhResult
.Complete
;
874 UhciDestoryTds (Uhc
, TDs
);
875 Uhc
->PciIo
->Unmap (Uhc
->PciIo
, DataMap
);
878 gBS
->RestoreTPL (OldTpl
);
884 Submits an asynchronous interrupt transfer to an
885 interrupt endpoint of a USB device according to UEFI 2.0 spec.
887 @param This A pointer to the EFI_USB2_HC_PROTOCOL instance.
888 @param DeviceAddress Target device address.
889 @param EndPointAddress Endpoint number and direction.
890 @param DeviceSpeed Device speed.
891 @param MaximumPacketLength Maximum packet size of the target endpoint.
892 @param IsNewTransfer If TRUE, submit a new transfer, if FALSE cancel old transfer.
893 @param DataToggle On input, data toggle to use; On output, next data toggle.
894 @param PollingInterval Interrupt poll rate in milliseconds.
895 @param DataLength On input, size of the data buffer, On output,
896 actually transferred data size.
897 @param Translator A pointr to the transaction translator data.
898 @param CallBackFunction Function to call periodically.
899 @param Context User context.
901 @return EFI_SUCCESS Transfer was submitted.
902 @return EFI_INVALID_PARAMETER Some parameters are invalid.
903 @return EFI_OUT_OF_RESOURCES Failed due to a lack of resources.
904 @return EFI_DEVICE_ERROR Can't read register.
909 Uhci2AsyncInterruptTransfer (
910 IN EFI_USB2_HC_PROTOCOL
*This
,
911 IN UINT8 DeviceAddress
,
912 IN UINT8 EndPointAddress
,
913 IN UINT8 DeviceSpeed
,
914 IN UINTN MaximumPacketLength
,
915 IN BOOLEAN IsNewTransfer
,
916 IN OUT UINT8
*DataToggle
,
917 IN UINTN PollingInterval
,
919 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
920 IN EFI_ASYNC_USB_TRANSFER_CALLBACK CallBackFunction
,
925 BOOLEAN IsSlowDevice
;
935 Uhc
= UHC_FROM_USB2_HC_PROTO (This
);
942 IsSlowDevice
= (BOOLEAN
) ((EFI_USB_SPEED_LOW
== DeviceSpeed
) ? TRUE
: FALSE
);
944 if ((EndPointAddress
& 0x80) == 0) {
945 return EFI_INVALID_PARAMETER
;
949 // Delete Async interrupt transfer request
951 if (!IsNewTransfer
) {
952 OldTpl
= gBS
->RaiseTPL (UHCI_TPL
);
953 Status
= UhciRemoveAsyncReq (Uhc
, DeviceAddress
, EndPointAddress
, DataToggle
);
955 gBS
->RestoreTPL (OldTpl
);
959 if (PollingInterval
< 1 || PollingInterval
> 255) {
960 return EFI_INVALID_PARAMETER
;
963 if (DataLength
== 0) {
964 return EFI_INVALID_PARAMETER
;
967 if ((*DataToggle
!= 1) && (*DataToggle
!= 0)) {
968 return EFI_INVALID_PARAMETER
;
972 // If has errors that cause host controller halt,
973 // then return EFI_DEVICE_ERROR directly.
975 UhciAckAllInterrupt (Uhc
);
977 if (!UhciIsHcWorking (Uhc
->PciIo
)) {
978 return EFI_DEVICE_ERROR
;
982 // Allocate and map source data buffer for bus master access.
984 DataPtr
= AllocatePool (DataLength
);
986 if (DataPtr
== NULL
) {
987 return EFI_OUT_OF_RESOURCES
;
990 OldTpl
= gBS
->RaiseTPL (UHCI_TPL
);
993 // Map the user data then create a queue head and
994 // list of TD for it.
996 Status
= UhciMapUserData (
1006 if (EFI_ERROR (Status
)) {
1010 Qh
= UhciCreateQh (Uhc
, PollingInterval
);
1013 Status
= EFI_OUT_OF_RESOURCES
;
1017 IntTds
= UhciCreateBulkOrIntTds (
1025 (UINT8
) MaximumPacketLength
,
1029 if (IntTds
== NULL
) {
1030 Status
= EFI_OUT_OF_RESOURCES
;
1034 UhciLinkTdToQh (Qh
, IntTds
);
1037 // Save QH-TD structures to async Interrupt transfer list,
1038 // for monitor interrupt transfer execution routine use.
1040 Status
= UhciCreateAsyncReq (
1055 if (EFI_ERROR (Status
)) {
1059 UhciLinkQhToFrameList (Uhc
->FrameBase
, Qh
);
1061 gBS
->RestoreTPL (OldTpl
);
1065 UsbHcFreeMem (Uhc
->MemPool
, Qh
, sizeof (UHCI_QH_SW
));
1068 Uhc
->PciIo
->Unmap (Uhc
->PciIo
, DataMap
);
1071 gBS
->FreePool (DataPtr
);
1072 Uhc
->PciIo
->Flush (Uhc
->PciIo
);
1074 gBS
->RestoreTPL (OldTpl
);
1079 Submits synchronous interrupt transfer to an interrupt endpoint
1080 of a USB device according to UEFI 2.0 spec.
1083 @param This A pointer to the EFI_USB2_HC_PROTOCOL instance.
1084 @param DeviceAddress Target device address.
1085 @param EndPointAddress Endpoint number and direction.
1086 @param DeviceSpeed Device speed.
1087 @param MaximumPacketLength Maximum packet size of the target endpoint.
1088 @param Data Array of pointers to the buffers of data.
1089 @param DataLength On input, size of the data buffer, On output,
1090 actually transferred data size.
1091 @param DataToggle On input, data toggle to use; On output, next data toggle.
1092 @param TimeOut Maximum time out, in microseconds.
1093 @param Translator A pointr to the transaction translator data.
1094 @param TransferResult Variable to receive transfer result.
1096 @return EFI_SUCCESS The transfer was completed successfully.
1097 @return EFI_OUT_OF_RESOURCES Failed due to lack of resource.
1098 @return EFI_INVALID_PARAMETER Some parameters are invalid.
1099 @return EFI_TIMEOUT Failed due to timeout.
1100 @return EFI_DEVICE_ERROR Failed due to host controller or device error.
1105 Uhci2SyncInterruptTransfer (
1106 IN EFI_USB2_HC_PROTOCOL
*This
,
1107 IN UINT8 DeviceAddress
,
1108 IN UINT8 EndPointAddress
,
1109 IN UINT8 DeviceSpeed
,
1110 IN UINTN MaximumPacketLength
,
1112 IN OUT UINTN
*DataLength
,
1113 IN OUT UINT8
*DataToggle
,
1115 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
1116 OUT UINT32
*TransferResult
1122 UHCI_QH_RESULT QhResult
;
1127 BOOLEAN IsSlowDevice
;
1129 Uhc
= UHC_FROM_USB2_HC_PROTO (This
);
1134 if (DeviceSpeed
== EFI_USB_SPEED_HIGH
) {
1135 return EFI_INVALID_PARAMETER
;
1138 IsSlowDevice
= (BOOLEAN
) ((EFI_USB_SPEED_LOW
== DeviceSpeed
) ? TRUE
: FALSE
);
1140 if ((DataLength
== NULL
) || (Data
== NULL
) || (TransferResult
== NULL
)) {
1141 return EFI_INVALID_PARAMETER
;
1144 if ((EndPointAddress
& 0x80) == 0) {
1145 return EFI_INVALID_PARAMETER
;
1148 if ((*DataToggle
!= 1) && (*DataToggle
!= 0)) {
1149 return EFI_INVALID_PARAMETER
;
1152 if ((*DataLength
== 0) || (MaximumPacketLength
> 64)) {
1153 return EFI_INVALID_PARAMETER
;
1156 if (IsSlowDevice
&& (MaximumPacketLength
> 8)) {
1157 return EFI_INVALID_PARAMETER
;
1160 *TransferResult
= EFI_USB_ERR_SYSTEM
;
1161 Status
= EFI_DEVICE_ERROR
;
1164 UhciAckAllInterrupt (Uhc
);
1166 if (!UhciIsHcWorking (Uhc
->PciIo
)) {
1170 OldTpl
= gBS
->RaiseTPL (UHCI_TPL
);
1173 // Map the source data buffer for bus master access.
1174 // Create Tds list, then link it to the UHC's interrupt list
1176 Status
= UhciMapUserData (
1186 if (EFI_ERROR (Status
)) {
1190 TDs
= UhciCreateBulkOrIntTds (
1198 (UINT8
) MaximumPacketLength
,
1203 Uhc
->PciIo
->Unmap (Uhc
->PciIo
, DataMap
);
1205 Status
= EFI_OUT_OF_RESOURCES
;
1210 UhciLinkTdToQh (Uhc
->SyncIntQh
, TDs
);
1212 Status
= UhciExecuteTransfer (Uhc
, Uhc
->SyncIntQh
, TDs
, TimeOut
, IsSlowDevice
, &QhResult
);
1214 UhciUnlinkTdFromQh (Uhc
->SyncIntQh
, TDs
);
1215 Uhc
->PciIo
->Flush (Uhc
->PciIo
);
1217 *TransferResult
= QhResult
.Result
;
1218 *DataToggle
= QhResult
.NextToggle
;
1219 *DataLength
= QhResult
.Complete
;
1221 UhciDestoryTds (Uhc
, TDs
);
1222 Uhc
->PciIo
->Unmap (Uhc
->PciIo
, DataMap
);
1225 gBS
->RestoreTPL (OldTpl
);
1231 Submits isochronous transfer to a target USB device according to UEFI 2.0 spec.
1233 @param This A pointer to the EFI_USB2_HC_PROTOCOL instance.
1234 @param DeviceAddress Target device address.
1235 @param EndPointAddress Endpoint number and direction.
1236 @param DeviceSpeed Device speed.
1237 @param MaximumPacketLength Maximum packet size of the target endpoint.
1238 @param DataBuffersNumber Number of data buffers prepared for the transfer.
1239 @param Data Array of pointers to the buffers of data.
1240 @param DataLength On input, size of the data buffer, On output,
1241 actually transferred data size.
1242 @param Translator A pointr to the transaction translator data.
1243 @param TransferResult Variable to receive transfer result.
1245 @return EFI_UNSUPPORTED
1250 Uhci2IsochronousTransfer (
1251 IN EFI_USB2_HC_PROTOCOL
*This
,
1252 IN UINT8 DeviceAddress
,
1253 IN UINT8 EndPointAddress
,
1254 IN UINT8 DeviceSpeed
,
1255 IN UINTN MaximumPacketLength
,
1256 IN UINT8 DataBuffersNumber
,
1257 IN OUT VOID
*Data
[EFI_USB_MAX_ISO_BUFFER_NUM
],
1258 IN UINTN DataLength
,
1259 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
1260 OUT UINT32
*TransferResult
1263 return EFI_UNSUPPORTED
;
1268 Submits Async isochronous transfer to a target USB device according to UEFI 2.0 spec.
1270 @param This A pointer to the EFI_USB2_HC_PROTOCOL instance.
1271 @param DeviceAddress Target device address.
1272 @param EndPointAddress Endpoint number and direction.
1273 @param DeviceSpeed Device speed.
1274 @param MaximumPacketLength Maximum packet size of the target endpoint.
1275 @param DataBuffersNumber Number of data buffers prepared for the transfer.
1276 @param Data Array of pointers to the buffers of data.
1277 @param DataLength On input, size of the data buffer, On output,
1278 actually transferred data size.
1279 @param Translator A pointr to the transaction translator data.
1280 @param IsochronousCallBack Function to call when the transfer complete.
1281 @param Context Pass to the call back function as parameter.
1283 @return EFI_UNSUPPORTED
1288 Uhci2AsyncIsochronousTransfer (
1289 IN EFI_USB2_HC_PROTOCOL
*This
,
1290 IN UINT8 DeviceAddress
,
1291 IN UINT8 EndPointAddress
,
1292 IN UINT8 DeviceSpeed
,
1293 IN UINTN MaximumPacketLength
,
1294 IN UINT8 DataBuffersNumber
,
1295 IN OUT VOID
*Data
[EFI_USB_MAX_ISO_BUFFER_NUM
],
1296 IN UINTN DataLength
,
1297 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
1298 IN EFI_ASYNC_USB_TRANSFER_CALLBACK IsochronousCallBack
,
1302 return EFI_UNSUPPORTED
;
1306 Entry point for EFI drivers.
1308 @param ImageHandle EFI_HANDLE.
1309 @param SystemTable EFI_SYSTEM_TABLE.
1311 @retval EFI_SUCCESS Driver is successfully loaded.
1312 @return Others Failed.
1317 UhciDriverEntryPoint (
1318 IN EFI_HANDLE ImageHandle
,
1319 IN EFI_SYSTEM_TABLE
*SystemTable
1322 return EfiLibInstallDriverBindingComponentName2 (
1325 &gUhciDriverBinding
,
1327 &gUhciComponentName
,
1328 &gUhciComponentName2
1334 Test to see if this driver supports ControllerHandle. Any
1335 ControllerHandle that has UsbHcProtocol installed will be supported.
1337 @param This Protocol instance pointer.
1338 @param Controller Handle of device to test.
1339 @param RemainingDevicePath Not used.
1341 @return EFI_SUCCESS This driver supports this device.
1342 @return EFI_UNSUPPORTED This driver does not support this device.
1347 UhciDriverBindingSupported (
1348 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1349 IN EFI_HANDLE Controller
,
1350 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
1353 EFI_STATUS OpenStatus
;
1355 EFI_PCI_IO_PROTOCOL
*PciIo
;
1356 USB_CLASSC UsbClassCReg
;
1359 // Test whether there is PCI IO Protocol attached on the controller handle.
1361 OpenStatus
= gBS
->OpenProtocol (
1363 &gEfiPciIoProtocolGuid
,
1365 This
->DriverBindingHandle
,
1367 EFI_OPEN_PROTOCOL_BY_DRIVER
1370 if (EFI_ERROR (OpenStatus
)) {
1374 Status
= PciIo
->Pci
.Read (
1378 sizeof (USB_CLASSC
) / sizeof (UINT8
),
1382 if (EFI_ERROR (Status
)) {
1383 Status
= EFI_UNSUPPORTED
;
1388 // Test whether the controller belongs to UHCI type
1390 if ((UsbClassCReg
.BaseCode
!= PCI_CLASS_SERIAL
) ||
1391 (UsbClassCReg
.SubClassCode
!= PCI_CLASS_SERIAL_USB
) ||
1392 (UsbClassCReg
.PI
!= PCI_CLASSC_PI_UHCI
)
1395 Status
= EFI_UNSUPPORTED
;
1399 gBS
->CloseProtocol (
1401 &gEfiPciIoProtocolGuid
,
1402 This
->DriverBindingHandle
,
1412 Allocate and initialize the empty UHCI device.
1414 @param PciIo The PCIIO to use.
1415 @param OriginalPciAttributes The original PCI attributes.
1417 @return Allocated UHCI device. If err, return NULL.
1422 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
1423 IN UINT64 OriginalPciAttributes
1429 Uhc
= AllocateZeroPool (sizeof (USB_HC_DEV
));
1436 // This driver supports both USB_HC_PROTOCOL and USB2_HC_PROTOCOL.
1437 // USB_HC_PROTOCOL is for EFI 1.1 backward compability.
1439 Uhc
->Signature
= USB_HC_DEV_SIGNATURE
;
1440 Uhc
->Usb2Hc
.GetCapability
= Uhci2GetCapability
;
1441 Uhc
->Usb2Hc
.Reset
= Uhci2Reset
;
1442 Uhc
->Usb2Hc
.GetState
= Uhci2GetState
;
1443 Uhc
->Usb2Hc
.SetState
= Uhci2SetState
;
1444 Uhc
->Usb2Hc
.ControlTransfer
= Uhci2ControlTransfer
;
1445 Uhc
->Usb2Hc
.BulkTransfer
= Uhci2BulkTransfer
;
1446 Uhc
->Usb2Hc
.AsyncInterruptTransfer
= Uhci2AsyncInterruptTransfer
;
1447 Uhc
->Usb2Hc
.SyncInterruptTransfer
= Uhci2SyncInterruptTransfer
;
1448 Uhc
->Usb2Hc
.IsochronousTransfer
= Uhci2IsochronousTransfer
;
1449 Uhc
->Usb2Hc
.AsyncIsochronousTransfer
= Uhci2AsyncIsochronousTransfer
;
1450 Uhc
->Usb2Hc
.GetRootHubPortStatus
= Uhci2GetRootHubPortStatus
;
1451 Uhc
->Usb2Hc
.SetRootHubPortFeature
= Uhci2SetRootHubPortFeature
;
1452 Uhc
->Usb2Hc
.ClearRootHubPortFeature
= Uhci2ClearRootHubPortFeature
;
1453 Uhc
->Usb2Hc
.MajorRevision
= 0x1;
1454 Uhc
->Usb2Hc
.MinorRevision
= 0x1;
1457 Uhc
->OriginalPciAttributes
= OriginalPciAttributes
;
1458 Uhc
->MemPool
= UsbHcInitMemPool (PciIo
, TRUE
, 0);
1460 if (Uhc
->MemPool
== NULL
) {
1461 Status
= EFI_OUT_OF_RESOURCES
;
1465 InitializeListHead (&Uhc
->AsyncIntList
);
1467 Status
= gBS
->CreateEvent (
1468 EVT_TIMER
| EVT_NOTIFY_SIGNAL
,
1470 UhciMonitorAsyncReqList
,
1472 &Uhc
->AsyncIntMonitor
1475 if (EFI_ERROR (Status
)) {
1476 UsbHcFreeMemPool (Uhc
->MemPool
);
1483 gBS
->FreePool (Uhc
);
1489 Free the UHCI device and release its associated resources.
1491 @param Uhc The UHCI device to release.
1501 if (Uhc
->AsyncIntMonitor
!= NULL
) {
1502 gBS
->CloseEvent (Uhc
->AsyncIntMonitor
);
1505 if (Uhc
->MemPool
!= NULL
) {
1506 UsbHcFreeMemPool (Uhc
->MemPool
);
1509 if (Uhc
->CtrlNameTable
!= NULL
) {
1510 FreeUnicodeStringTable (Uhc
->CtrlNameTable
);
1513 gBS
->FreePool (Uhc
);
1518 Uninstall all Uhci Interface.
1520 @param Controller Controller handle.
1521 @param This Protocol instance pointer.
1528 IN EFI_HANDLE Controller
,
1529 IN EFI_USB2_HC_PROTOCOL
*This
1535 // Uninstall the USB_HC and USB_HC2 protocol, then disable the controller
1537 Uhc
= UHC_FROM_USB2_HC_PROTO (This
);
1538 UhciStopHc (Uhc
, UHC_GENERIC_TIMEOUT
);
1540 gBS
->UninstallProtocolInterface (
1542 &gEfiUsb2HcProtocolGuid
,
1546 UhciFreeAllAsyncReq (Uhc
);
1547 UhciDestoryFrameList (Uhc
);
1550 // Restore original PCI attributes
1552 Uhc
->PciIo
->Attributes (
1554 EfiPciIoAttributeOperationSet
,
1555 Uhc
->OriginalPciAttributes
,
1564 Starting the Usb UHCI Driver.
1566 @param This Protocol instance pointer.
1567 @param Controller Handle of device to test.
1568 @param RemainingDevicePath Not used.
1570 @retval EFI_SUCCESS This driver supports this device.
1571 @retval EFI_UNSUPPORTED This driver does not support this device.
1572 @retval EFI_DEVICE_ERROR This driver cannot be started due to device Error.
1573 EFI_OUT_OF_RESOURCES- Failed due to resource shortage.
1578 UhciDriverBindingStart (
1579 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1580 IN EFI_HANDLE Controller
,
1581 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
1585 EFI_PCI_IO_PROTOCOL
*PciIo
;
1588 UINT64 OriginalPciAttributes
;
1589 BOOLEAN PciAttributesSaved
;
1592 // Open PCIIO, then enable the EHC device and turn off emulation
1595 Status
= gBS
->OpenProtocol (
1597 &gEfiPciIoProtocolGuid
,
1599 This
->DriverBindingHandle
,
1601 EFI_OPEN_PROTOCOL_BY_DRIVER
1604 if (EFI_ERROR (Status
)) {
1608 PciAttributesSaved
= FALSE
;
1610 // Save original PCI attributes
1612 Status
= PciIo
->Attributes (
1614 EfiPciIoAttributeOperationGet
,
1616 &OriginalPciAttributes
1619 if (EFI_ERROR (Status
)) {
1622 PciAttributesSaved
= TRUE
;
1625 // Robustnesss improvement such as for UoL
1626 // Default is not required.
1628 if (FeaturePcdGet (PcdTurnOffUsbLegacySupport
)) {
1629 UhciTurnOffUsbEmulation (PciIo
);
1632 Status
= PciIo
->Attributes (
1634 EfiPciIoAttributeOperationSupported
,
1638 if (!EFI_ERROR (Status
)) {
1639 Supports
&= EFI_PCI_DEVICE_ENABLE
;
1640 Status
= PciIo
->Attributes (
1642 EfiPciIoAttributeOperationEnable
,
1648 if (EFI_ERROR (Status
)) {
1652 Uhc
= UhciAllocateDev (PciIo
, OriginalPciAttributes
);
1655 Status
= EFI_OUT_OF_RESOURCES
;
1660 // Allocate and Init Host Controller's Frame List Entry
1662 Status
= UhciInitFrameList (Uhc
);
1664 if (EFI_ERROR (Status
)) {
1665 Status
= EFI_OUT_OF_RESOURCES
;
1669 Status
= gBS
->SetTimer (
1670 Uhc
->AsyncIntMonitor
,
1672 UHC_ASYNC_POLL_INTERVAL
1675 if (EFI_ERROR (Status
)) {
1680 // Install USB2_HC_PROTOCOL
1682 Status
= gBS
->InstallMultipleProtocolInterfaces (
1684 &gEfiUsb2HcProtocolGuid
,
1689 if (EFI_ERROR (Status
)) {
1694 // Install the component name protocol
1696 Uhc
->CtrlNameTable
= NULL
;
1700 gUhciComponentName
.SupportedLanguages
,
1701 &Uhc
->CtrlNameTable
,
1702 L
"Usb Universal Host Controller",
1707 gUhciComponentName2
.SupportedLanguages
,
1708 &Uhc
->CtrlNameTable
,
1709 L
"Usb Universal Host Controller",
1715 // Start the UHCI hardware, also set its reclamation point to 64 bytes
1717 UhciWriteReg (Uhc
->PciIo
, USBCMD_OFFSET
, USBCMD_RS
| USBCMD_MAXP
);
1725 if (PciAttributesSaved
) {
1727 // Restore original PCI attributes
1731 EfiPciIoAttributeOperationSet
,
1732 OriginalPciAttributes
,
1737 gBS
->CloseProtocol (
1739 &gEfiPciIoProtocolGuid
,
1740 This
->DriverBindingHandle
,
1749 Stop this driver on ControllerHandle. Support stoping any child handles
1750 created by this driver.
1752 @param This Protocol instance pointer.
1753 @param Controller Handle of device to stop driver on.
1754 @param NumberOfChildren Number of Children in the ChildHandleBuffer.
1755 @param ChildHandleBuffer List of handles for the children we need to stop.
1763 UhciDriverBindingStop (
1764 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1765 IN EFI_HANDLE Controller
,
1766 IN UINTN NumberOfChildren
,
1767 IN EFI_HANDLE
*ChildHandleBuffer
1770 EFI_USB2_HC_PROTOCOL
*Usb2Hc
;
1773 Status
= gBS
->OpenProtocol (
1775 &gEfiUsb2HcProtocolGuid
,
1777 This
->DriverBindingHandle
,
1779 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1783 // Test whether the Controller handler passed in is a valid
1784 // Usb controller handle that should be supported, if not,
1785 // return the error status directly
1787 if (EFI_ERROR (Status
)) {
1791 UhciCleanDevUp (Controller
, Usb2Hc
);
1793 gBS
->CloseProtocol (
1795 &gEfiPciIoProtocolGuid
,
1796 This
->DriverBindingHandle
,
1803 EFI_DRIVER_BINDING_PROTOCOL gUhciDriverBinding
= {
1804 UhciDriverBindingSupported
,
1805 UhciDriverBindingStart
,
1806 UhciDriverBindingStop
,