3 Copyright (c) 2004 - 2008, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 The UHCI driver model and HC protocol routines.
28 Provides software reset for the USB host controller according to UEFI 2.0 spec.
30 @param This A pointer to the EFI_USB2_HC_PROTOCOL instance.
31 @param Attributes A bit mask of the reset operation to perform. See
32 below for a list of the supported bit mask values.
34 @return EFI_SUCCESS : The reset operation succeeded.
35 @return EFI_INVALID_PARAMETER : Attributes is not valid.
36 @return EFI_UNSUPPORTED : This type of reset is not currently supported
37 @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 errors2006
127 IN CONST EFI_USB2_HC_PROTOCOL
*This
,
128 OUT EFI_USB_HC_STATE
*State
136 return EFI_INVALID_PARAMETER
;
139 Uhc
= UHC_FROM_USB2_HC_PROTO (This
);
141 UsbCmd
= UhciReadReg (Uhc
->PciIo
, USBCMD_OFFSET
);
142 UsbSts
= UhciReadReg (Uhc
->PciIo
, USBSTS_OFFSET
);
144 if (UsbCmd
& USBCMD_EGSM
) {
145 *State
= EfiUsbHcStateSuspend
;
147 } else if ((UsbSts
& USBSTS_HCH
) != 0) {
148 *State
= EfiUsbHcStateHalt
;
151 *State
= EfiUsbHcStateOperational
;
159 Sets the USB host controller to a specific state according to UEFI 2.0 spec.
161 @param This A pointer to the EFI_USB2_HC_PROTOCOL instance.
162 @param State Indicates the state of the host controller that will
165 @return EFI_SUCCESS : Host controller was successfully placed in the state
166 @return EFI_INVALID_PARAMETER : State is invalid.
167 @return EFI_DEVICE_ERROR : Failed to set the state
174 IN EFI_USB2_HC_PROTOCOL
*This
,
175 IN EFI_USB_HC_STATE State
178 EFI_USB_HC_STATE CurState
;
184 Uhc
= UHC_FROM_USB2_HC_PROTO (This
);
185 Status
= Uhci2GetState (This
, &CurState
);
187 if (EFI_ERROR (Status
)) {
188 return EFI_DEVICE_ERROR
;
191 if (CurState
== State
) {
195 Status
= EFI_SUCCESS
;
196 OldTpl
= gBS
->RaiseTPL (UHCI_TPL
);
199 case EfiUsbHcStateHalt
:
200 Status
= UhciStopHc (Uhc
, UHC_GENERIC_TIMEOUT
);
203 case EfiUsbHcStateOperational
:
204 UsbCmd
= UhciReadReg (Uhc
->PciIo
, USBCMD_OFFSET
);
206 if (CurState
== EfiUsbHcStateHalt
) {
208 // Set Run/Stop bit to 1, also set the bandwidht reclamation
211 UsbCmd
|= USBCMD_RS
| USBCMD_MAXP
;
212 UhciWriteReg (Uhc
->PciIo
, USBCMD_OFFSET
, UsbCmd
);
214 } else if (CurState
== EfiUsbHcStateSuspend
) {
216 // If FGR(Force Global Resume) bit is 0, set it
218 if ((UsbCmd
& USBCMD_FGR
) == 0) {
219 UsbCmd
|= USBCMD_FGR
;
220 UhciWriteReg (Uhc
->PciIo
, USBCMD_OFFSET
, UsbCmd
);
224 // wait 20ms to let resume complete (20ms is specified by UHCI spec)
226 gBS
->Stall (UHC_FORCE_GLOBAL_RESUME_STALL
);
229 // Write FGR bit to 0 and EGSM(Enter Global Suspend Mode) bit to 0
231 UsbCmd
&= ~USBCMD_FGR
;
232 UsbCmd
&= ~USBCMD_EGSM
;
234 UhciWriteReg (Uhc
->PciIo
, USBCMD_OFFSET
, UsbCmd
);
239 case EfiUsbHcStateSuspend
:
240 Status
= Uhci2SetState (This
, EfiUsbHcStateHalt
);
242 if (EFI_ERROR (Status
)) {
243 Status
= EFI_DEVICE_ERROR
;
248 // Set Enter Global Suspend Mode bit to 1.
250 UsbCmd
= UhciReadReg (Uhc
->PciIo
, USBCMD_OFFSET
);
251 UsbCmd
|= USBCMD_EGSM
;
252 UhciWriteReg (Uhc
->PciIo
, USBCMD_OFFSET
, UsbCmd
);
256 Status
= EFI_INVALID_PARAMETER
;
261 gBS
->RestoreTPL (OldTpl
);
266 Retrieves capabilities of USB host controller according to UEFI 2.0 spec.
268 @param This A pointer to the EFI_USB2_HC_PROTOCOL instance
269 @param MaxSpeed A pointer to the max speed USB host controller
271 @param PortNumber A pointer to the number of root hub ports.
272 @param Is64BitCapable A pointer to an integer to show whether USB host
273 controller supports 64-bit memory addressing.
275 @return EFI_SUCCESS : capabilities were retrieved successfully.
276 @return EFI_INVALID_PARAMETER : MaxSpeed or PortNumber or Is64BitCapable is NULL.
277 @return EFI_DEVICE_ERROR : An error was encountered
284 IN EFI_USB2_HC_PROTOCOL
*This
,
286 OUT UINT8
*PortNumber
,
287 OUT UINT8
*Is64BitCapable
295 Uhc
= UHC_FROM_USB2_HC_PROTO (This
);
297 if ((NULL
== MaxSpeed
) || (NULL
== PortNumber
) || (NULL
== Is64BitCapable
)) {
298 return EFI_INVALID_PARAMETER
;
301 *MaxSpeed
= EFI_USB_SPEED_FULL
;
302 *Is64BitCapable
= (UINT8
) FALSE
;
306 for (Index
= 0; Index
< USB_MAX_ROOTHUB_PORT
; Index
++) {
307 Offset
= USBPORTSC_OFFSET
+ Index
* 2;
308 PortSC
= UhciReadReg (Uhc
->PciIo
, Offset
);
311 // Port status's bit 7 is reserved and always returns 1 if
312 // the port number is valid. Intel's UHCI (in EHCI controller)
313 // returns 0 in this bit if port number is invalid. Also, if
314 // PciIo IoRead returns error, 0xFFFF is returned to caller.
316 if (((PortSC
& 0x80) == 0) || (PortSC
== 0xFFFF)) {
322 Uhc
->RootPorts
= *PortNumber
;
324 DEBUG ((EFI_D_INFO
, "Uhci2GetCapability: %d ports\n", Uhc
->RootPorts
));
330 Retrieves the current status of a USB root hub port according to UEFI 2.0 spec.
332 @param This A pointer to the EFI_USB2_HC_PROTOCOL.
333 @param PortNumber The port to get status
334 @param PortStatus A pointer to the current port status bits and port
337 @return EFI_SUCCESS : status of the USB root hub port was returned in PortStatus.
338 @return EFI_INVALID_PARAMETER : PortNumber is invalid.
339 @return EFI_DEVICE_ERROR : Can't read register
345 Uhci2GetRootHubPortStatus (
346 IN CONST EFI_USB2_HC_PROTOCOL
*This
,
347 IN CONST UINT8 PortNumber
,
348 OUT EFI_USB_PORT_STATUS
*PortStatus
355 Uhc
= UHC_FROM_USB2_HC_PROTO (This
);
357 if (PortStatus
== NULL
) {
358 return EFI_INVALID_PARAMETER
;
361 if (PortNumber
>= Uhc
->RootPorts
) {
362 return EFI_INVALID_PARAMETER
;
365 Offset
= USBPORTSC_OFFSET
+ PortNumber
* 2;
366 PortStatus
->PortStatus
= 0;
367 PortStatus
->PortChangeStatus
= 0;
369 PortSC
= UhciReadReg (Uhc
->PciIo
, Offset
);
371 if (PortSC
& USBPORTSC_CCS
) {
372 PortStatus
->PortStatus
|= USB_PORT_STAT_CONNECTION
;
375 if (PortSC
& USBPORTSC_PED
) {
376 PortStatus
->PortStatus
|= USB_PORT_STAT_ENABLE
;
379 if (PortSC
& USBPORTSC_SUSP
) {
380 DEBUG ((EFI_D_INFO
, "Uhci2GetRootHubPortStatus: port %d is suspended\n", PortNumber
));
381 PortStatus
->PortStatus
|= USB_PORT_STAT_SUSPEND
;
384 if (PortSC
& USBPORTSC_PR
) {
385 PortStatus
->PortStatus
|= USB_PORT_STAT_RESET
;
388 if (PortSC
& USBPORTSC_LSDA
) {
389 PortStatus
->PortStatus
|= USB_PORT_STAT_LOW_SPEED
;
393 // CHC will always return one in port owner bit
395 PortStatus
->PortStatus
|= USB_PORT_STAT_OWNER
;
397 if (PortSC
& USBPORTSC_CSC
) {
398 PortStatus
->PortChangeStatus
|= USB_PORT_STAT_C_CONNECTION
;
401 if (PortSC
& USBPORTSC_PEDC
) {
402 PortStatus
->PortChangeStatus
|= USB_PORT_STAT_C_ENABLE
;
410 Sets a feature for the specified root hub port according to UEFI 2.0 spec.
412 @param This A pointer to the EFI_USB2_HC_PROTOCOL.
413 @param PortNumber Specifies the root hub port whose feature is
415 @param PortFeature Indicates the feature selector associated with the
418 @return EFI_SUCCESS : PortFeature was set for the root port
419 @return EFI_INVALID_PARAMETER : PortNumber is invalid or PortFeature is invalid.
420 @return EFI_DEVICE_ERROR : Can't read register
426 Uhci2SetRootHubPortFeature (
427 IN EFI_USB2_HC_PROTOCOL
*This
,
429 IN EFI_USB_PORT_FEATURE PortFeature
438 Uhc
= UHC_FROM_USB2_HC_PROTO (This
);
440 if (PortNumber
>= Uhc
->RootPorts
) {
441 return EFI_INVALID_PARAMETER
;
444 Offset
= USBPORTSC_OFFSET
+ PortNumber
* 2;
446 OldTpl
= gBS
->RaiseTPL (UHCI_TPL
);
447 PortSC
= UhciReadReg (Uhc
->PciIo
, Offset
);
449 switch (PortFeature
) {
450 case EfiUsbPortSuspend
:
451 Command
= UhciReadReg (Uhc
->PciIo
, USBCMD_OFFSET
);
452 if (!(Command
& USBCMD_EGSM
)) {
454 // if global suspend is not active, can set port suspend
457 PortSC
|= USBPORTSC_SUSP
;
461 case EfiUsbPortReset
:
463 PortSC
|= USBPORTSC_PR
;
466 case EfiUsbPortPower
:
472 case EfiUsbPortEnable
:
474 PortSC
|= USBPORTSC_PED
;
478 gBS
->RestoreTPL (OldTpl
);
479 return EFI_INVALID_PARAMETER
;
482 UhciWriteReg (Uhc
->PciIo
, Offset
, PortSC
);
483 gBS
->RestoreTPL (OldTpl
);
490 Clears a feature for the specified root hub port according to Uefi 2.0 spec.
492 @param This A pointer to the EFI_USB2_HC_PROTOCOL instance.
493 @param PortNumber Specifies the root hub port whose feature is
494 requested to be cleared.
495 @param PortFeature Indicates the feature selector associated with the
496 feature clear request.
498 @return EFI_SUCCESS : PortFeature was cleared for the USB root hub port
499 @return EFI_INVALID_PARAMETER : PortNumber is invalid or PortFeature is invalid.
500 @return EFI_DEVICE_ERROR : Can't read register
506 Uhci2ClearRootHubPortFeature (
507 IN EFI_USB2_HC_PROTOCOL
*This
,
509 IN EFI_USB_PORT_FEATURE PortFeature
517 Uhc
= UHC_FROM_USB2_HC_PROTO (This
);
519 if (PortNumber
>= Uhc
->RootPorts
) {
520 return EFI_INVALID_PARAMETER
;
523 Offset
= USBPORTSC_OFFSET
+ PortNumber
* 2;
525 OldTpl
= gBS
->RaiseTPL (UHCI_TPL
);
526 PortSC
= UhciReadReg (Uhc
->PciIo
, Offset
);
528 switch (PortFeature
) {
529 case EfiUsbPortEnable
:
531 PortSC
&= ~USBPORTSC_PED
;
534 case EfiUsbPortSuspend
:
536 // Cause a resume on the specified port if in suspend mode.
539 PortSC
&= ~USBPORTSC_SUSP
;
542 case EfiUsbPortPower
:
548 case EfiUsbPortReset
:
550 PortSC
&= ~USBPORTSC_PR
;
553 case EfiUsbPortConnectChange
:
555 PortSC
|= USBPORTSC_CSC
;
558 case EfiUsbPortEnableChange
:
560 PortSC
|= USBPORTSC_PEDC
;
563 case EfiUsbPortSuspendChange
:
565 // Root hub does not support this
569 case EfiUsbPortOverCurrentChange
:
571 // Root hub does not support this
575 case EfiUsbPortResetChange
:
577 // Root hub does not support this
582 gBS
->RestoreTPL (OldTpl
);
583 return EFI_INVALID_PARAMETER
;
586 UhciWriteReg (Uhc
->PciIo
, Offset
, PortSC
);
587 gBS
->RestoreTPL (OldTpl
);
594 Submits control transfer to a target USB device accroding to UEFI 2.0 spec..
596 This : A pointer to the EFI_USB2_HC_PROTOCOL instance.
597 DeviceAddress : Target device address
598 DeviceSpeed : Device speed
599 MaximumPacketLength : Maximum packet size of the target endpoint
600 Request : USB device request to send
601 TransferDirection : Data direction of the Data stage in control transfer
602 Data : Data to transmit/receive in data stage
603 DataLength : Length of the data
604 TimeOut : Maximum time, in microseconds, for transfer to complete.
605 TransferResult : Variable to receive the transfer result
607 @return EFI_SUCCESS : The control transfer was completed successfully.
608 @return EFI_OUT_OF_RESOURCES : Failed due to lack of resource.
609 @return EFI_INVALID_PARAMETER : Some parameters are invalid.
610 @return EFI_TIMEOUT : Failed due to timeout.
611 @return EFI_DEVICE_ERROR : Failed due to host controller or device error.
617 Uhci2ControlTransfer (
618 IN EFI_USB2_HC_PROTOCOL
*This
,
619 IN UINT8 DeviceAddress
,
620 IN UINT8 DeviceSpeed
,
621 IN UINTN MaximumPacketLength
,
622 IN EFI_USB_DEVICE_REQUEST
*Request
,
623 IN EFI_USB_DATA_DIRECTION TransferDirection
,
625 IN OUT UINTN
*DataLength
,
627 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
628 OUT UINT32
*TransferResult
635 UHCI_QH_RESULT QhResult
;
641 BOOLEAN IsSlowDevice
;
643 Uhc
= UHC_FROM_USB2_HC_PROTO (This
);
650 IsSlowDevice
= (BOOLEAN
) ((EFI_USB_SPEED_LOW
== DeviceSpeed
) ? TRUE
: FALSE
);
653 // Parameters Checking
655 if (Request
== NULL
|| TransferResult
== NULL
) {
656 return EFI_INVALID_PARAMETER
;
659 if (IsSlowDevice
&& (MaximumPacketLength
!= 8)) {
660 return EFI_INVALID_PARAMETER
;
663 if ((MaximumPacketLength
!= 8) && (MaximumPacketLength
!= 16) &&
664 (MaximumPacketLength
!= 32) && (MaximumPacketLength
!= 64)) {
666 return EFI_INVALID_PARAMETER
;
669 if ((TransferDirection
!= EfiUsbNoData
) && (DataLength
== NULL
)) {
670 return EFI_INVALID_PARAMETER
;
673 *TransferResult
= EFI_USB_ERR_SYSTEM
;
674 Status
= EFI_DEVICE_ERROR
;
677 // If errors exist that cause host controller halt,
678 // clear status then return EFI_DEVICE_ERROR.
680 UhciAckAllInterrupt (Uhc
);
682 if (!UhciIsHcWorking (Uhc
->PciIo
)) {
683 return EFI_DEVICE_ERROR
;
686 OldTpl
= gBS
->RaiseTPL (UHCI_TPL
);
689 // Map the Request and data for bus master access,
690 // then create a list of TD for this transfer
692 Status
= UhciMapUserRequest (Uhc
, Request
, &RequestPhy
, &RequestMap
);
694 if (EFI_ERROR (Status
)) {
698 Status
= UhciMapUserData (Uhc
, TransferDirection
, Data
, DataLength
, &PktId
, &DataPhy
, &DataMap
);
700 if (EFI_ERROR (Status
)) {
701 Uhc
->PciIo
->Unmap (Uhc
->PciIo
, RequestMap
);
705 TDs
= UhciCreateCtrlTds (
712 (UINT8
) MaximumPacketLength
,
717 Status
= EFI_OUT_OF_RESOURCES
;
722 // According to the speed of the end point, link
723 // the TD to corrosponding queue head, then check
724 // the execution result
726 UhciLinkTdToQh (Uhc
->CtrlQh
, TDs
);
727 Status
= UhciExecuteTransfer (Uhc
, Uhc
->CtrlQh
, TDs
, TimeOut
, IsSlowDevice
, &QhResult
);
728 UhciUnlinkTdFromQh (Uhc
->CtrlQh
, TDs
);
730 Uhc
->PciIo
->Flush (Uhc
->PciIo
);
732 *TransferResult
= QhResult
.Result
;
734 if (DataLength
!= NULL
) {
735 *DataLength
= QhResult
.Complete
;
738 UhciDestoryTds (Uhc
, TDs
);
741 Uhc
->PciIo
->Unmap (Uhc
->PciIo
, DataMap
);
742 Uhc
->PciIo
->Unmap (Uhc
->PciIo
, RequestMap
);
745 gBS
->RestoreTPL (OldTpl
);
752 Submits bulk transfer to a bulk endpoint of a USB device
754 This : A pointer to the EFI_USB2_HC_PROTOCOL instance.
755 DeviceAddress : Target device address
756 EndPointAddress : Endpoint number and direction
757 DeviceSpeed : Device speed
758 MaximumPacketLength : Maximum packet size of the target endpoint
759 DataBuffersNumber : Number of data buffers prepared for the transfer.
760 Data : Array of pointers to the buffers of data
761 DataLength : On input, size of the data buffer, On output,
762 actually transferred data size.
763 DataToggle : On input, data toggle to use; On output, next data toggle
764 Translator : A pointr to the transaction translator data.
765 TimeOut : Maximum time out, in microseconds
766 TransferResult : Variable to receive transfer result
768 @return EFI_SUCCESS : The bulk transfer was completed successfully.
769 @return EFI_OUT_OF_RESOURCES : Failed due to lack of resource.
770 @return EFI_INVALID_PARAMETER : Some parameters are invalid.
771 @return EFI_TIMEOUT : Failed due to timeout.
772 @return EFI_DEVICE_ERROR : Failed due to host controller or device error.
779 IN EFI_USB2_HC_PROTOCOL
*This
,
780 IN UINT8 DeviceAddress
,
781 IN UINT8 EndPointAddress
,
782 IN UINT8 DeviceSpeed
,
783 IN UINTN MaximumPacketLength
,
784 IN UINT8 DataBuffersNumber
,
785 IN OUT VOID
*Data
[EFI_USB_MAX_BULK_BUFFER_NUM
],
786 IN OUT UINTN
*DataLength
,
787 IN OUT UINT8
*DataToggle
,
789 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
790 OUT UINT32
*TransferResult
793 EFI_USB_DATA_DIRECTION Direction
;
798 UHCI_QH_RESULT QhResult
;
804 Uhc
= UHC_FROM_USB2_HC_PROTO (This
);
808 if (DeviceSpeed
== EFI_USB_SPEED_LOW
) {
809 return EFI_INVALID_PARAMETER
;
812 if ((DataLength
== NULL
) || (Data
== NULL
) || (TransferResult
== NULL
)) {
813 return EFI_INVALID_PARAMETER
;
816 if (*DataLength
== 0) {
817 return EFI_INVALID_PARAMETER
;
820 if ((*DataToggle
!= 1) && (*DataToggle
!= 0)) {
821 return EFI_INVALID_PARAMETER
;
824 if ((MaximumPacketLength
!= 8) && (MaximumPacketLength
!= 16) &&
825 (MaximumPacketLength
!= 32) && (MaximumPacketLength
!= 64)) {
826 return EFI_INVALID_PARAMETER
;
829 *TransferResult
= EFI_USB_ERR_SYSTEM
;
830 Status
= EFI_OUT_OF_RESOURCES
;
833 // If has errors that cause host controller halt,
834 // then return EFI_DEVICE_ERROR directly.
836 UhciAckAllInterrupt (Uhc
);
838 if (!UhciIsHcWorking (Uhc
->PciIo
)) {
839 return EFI_DEVICE_ERROR
;
842 OldTpl
= gBS
->RaiseTPL (UHCI_TPL
);
845 // Map the source data buffer for bus master access,
846 // then create a list of TDs
848 if (EndPointAddress
& 0x80) {
849 Direction
= EfiUsbDataIn
;
851 Direction
= EfiUsbDataOut
;
854 Status
= UhciMapUserData (Uhc
, Direction
, *Data
, DataLength
, &PktId
, &DataPhy
, &DataMap
);
856 if (EFI_ERROR (Status
)) {
860 Status
= EFI_OUT_OF_RESOURCES
;
861 TDs
= UhciCreateBulkOrIntTds (
869 (UINT8
) MaximumPacketLength
,
874 Uhc
->PciIo
->Unmap (Uhc
->PciIo
, DataMap
);
880 // Link the TDs to bulk queue head. According to the platfore
881 // defintion of UHCI_NO_BW_RECLAMATION, BulkQh is either configured
882 // to do full speed bandwidth reclamation or not.
884 BulkQh
= Uhc
->BulkQh
;
886 UhciLinkTdToQh (BulkQh
, TDs
);
887 Status
= UhciExecuteTransfer (Uhc
, BulkQh
, TDs
, TimeOut
, FALSE
, &QhResult
);
888 UhciUnlinkTdFromQh (BulkQh
, TDs
);
890 Uhc
->PciIo
->Flush (Uhc
->PciIo
);
892 *TransferResult
= QhResult
.Result
;
893 *DataToggle
= QhResult
.NextToggle
;
894 *DataLength
= QhResult
.Complete
;
896 UhciDestoryTds (Uhc
, TDs
);
897 Uhc
->PciIo
->Unmap (Uhc
->PciIo
, DataMap
);
900 gBS
->RestoreTPL (OldTpl
);
906 Submits an asynchronous interrupt transfer to an
907 interrupt endpoint of a USB device according to UEFI 2.0 spec.
909 This : A pointer to the EFI_USB2_HC_PROTOCOL instance.
910 DeviceAddress : Target device address
911 EndPointAddress : Endpoint number and direction
912 DeviceSpeed : Device speed
913 MaximumPacketLength : Maximum packet size of the target endpoint
914 IsNewTransfer : If TRUE, submit a new transfer, if FALSE cancel old transfer
915 DataToggle : On input, data toggle to use; On output, next data toggle
916 PollingInterval : Interrupt poll rate in milliseconds
917 DataLength : On input, size of the data buffer, On output,
918 actually transferred data size.
919 Translator : A pointr to the transaction translator data.
920 CallBackFunction : Function to call periodically
921 Context : User context
923 @return EFI_SUCCESS : Transfer was submitted
924 @return EFI_INVALID_PARAMETER : Some parameters are invalid.
925 @return EFI_OUT_OF_RESOURCES : Failed due to a lack of resources.
926 @return EFI_DEVICE_ERROR : Can't read register
932 Uhci2AsyncInterruptTransfer (
933 IN EFI_USB2_HC_PROTOCOL
*This
,
934 IN UINT8 DeviceAddress
,
935 IN UINT8 EndPointAddress
,
936 IN UINT8 DeviceSpeed
,
937 IN UINTN MaximumPacketLength
,
938 IN BOOLEAN IsNewTransfer
,
939 IN OUT UINT8
*DataToggle
,
940 IN UINTN PollingInterval
,
942 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
943 IN EFI_ASYNC_USB_TRANSFER_CALLBACK CallBackFunction
,
948 BOOLEAN IsSlowDevice
;
958 Uhc
= UHC_FROM_USB2_HC_PROTO (This
);
965 IsSlowDevice
= (BOOLEAN
) ((EFI_USB_SPEED_LOW
== DeviceSpeed
) ? TRUE
: FALSE
);
967 if ((EndPointAddress
& 0x80) == 0) {
968 return EFI_INVALID_PARAMETER
;
972 // Delete Async interrupt transfer request
974 if (!IsNewTransfer
) {
975 OldTpl
= gBS
->RaiseTPL (UHCI_TPL
);
976 Status
= UhciRemoveAsyncReq (Uhc
, DeviceAddress
, EndPointAddress
, DataToggle
);
978 gBS
->RestoreTPL (OldTpl
);
982 if (PollingInterval
< 1 || PollingInterval
> 255) {
983 return EFI_INVALID_PARAMETER
;
986 if (DataLength
== 0) {
987 return EFI_INVALID_PARAMETER
;
990 if ((*DataToggle
!= 1) && (*DataToggle
!= 0)) {
991 return EFI_INVALID_PARAMETER
;
995 // If has errors that cause host controller halt,
996 // then return EFI_DEVICE_ERROR directly.
998 UhciAckAllInterrupt (Uhc
);
1000 if (!UhciIsHcWorking (Uhc
->PciIo
)) {
1001 return EFI_DEVICE_ERROR
;
1005 // Allocate and map source data buffer for bus master access.
1007 DataPtr
= AllocatePool (DataLength
);
1009 if (DataPtr
== NULL
) {
1010 return EFI_OUT_OF_RESOURCES
;
1013 OldTpl
= gBS
->RaiseTPL (UHCI_TPL
);
1016 // Map the user data then create a queue head and
1017 // list of TD for it.
1019 Status
= UhciMapUserData (
1029 if (EFI_ERROR (Status
)) {
1033 Qh
= UhciCreateQh (Uhc
, PollingInterval
);
1036 Status
= EFI_OUT_OF_RESOURCES
;
1040 IntTds
= UhciCreateBulkOrIntTds (
1048 (UINT8
) MaximumPacketLength
,
1052 if (IntTds
== NULL
) {
1053 Status
= EFI_OUT_OF_RESOURCES
;
1057 UhciLinkTdToQh (Qh
, IntTds
);
1060 // Save QH-TD structures to async Interrupt transfer list,
1061 // for monitor interrupt transfer execution routine use.
1063 Status
= UhciCreateAsyncReq (
1078 if (EFI_ERROR (Status
)) {
1082 UhciLinkQhToFrameList (Uhc
->FrameBase
, Qh
);
1084 gBS
->RestoreTPL (OldTpl
);
1088 UsbHcFreeMem (Uhc
->MemPool
, Qh
, sizeof (UHCI_QH_SW
));
1091 Uhc
->PciIo
->Unmap (Uhc
->PciIo
, DataMap
);
1094 gBS
->FreePool (DataPtr
);
1095 Uhc
->PciIo
->Flush (Uhc
->PciIo
);
1097 gBS
->RestoreTPL (OldTpl
);
1102 Submits synchronous interrupt transfer to an interrupt endpoint
1103 of a USB device according to UEFI 2.0 spec.
1105 This : A pointer to the EFI_USB2_HC_PROTOCOL instance.
1106 DeviceAddress : Target device address
1107 EndPointAddress : Endpoint number and direction
1108 DeviceSpeed : Device speed
1109 MaximumPacketLength : Maximum packet size of the target endpoint
1110 DataBuffersNumber : Number of data buffers prepared for the transfer.
1111 Data : Array of pointers to the buffers of data
1112 DataLength : On input, size of the data buffer, On output,
1113 actually transferred data size.
1114 DataToggle : On input, data toggle to use; On output, next data toggle
1115 TimeOut : Maximum time out, in microseconds
1116 Translator : A pointr to the transaction translator data.
1117 TransferResult : Variable to receive transfer result
1119 @return EFI_SUCCESS : The transfer was completed successfully.
1120 @return EFI_OUT_OF_RESOURCES : Failed due to lack of resource.
1121 @return EFI_INVALID_PARAMETER : Some parameters are invalid.
1122 @return EFI_TIMEOUT : Failed due to timeout.
1123 @return EFI_DEVICE_ERROR : Failed due to host controller or device error.
1129 Uhci2SyncInterruptTransfer (
1130 IN EFI_USB2_HC_PROTOCOL
*This
,
1131 IN UINT8 DeviceAddress
,
1132 IN UINT8 EndPointAddress
,
1133 IN UINT8 DeviceSpeed
,
1134 IN UINTN MaximumPacketLength
,
1136 IN OUT UINTN
*DataLength
,
1137 IN OUT UINT8
*DataToggle
,
1139 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
1140 OUT UINT32
*TransferResult
1146 UHCI_QH_RESULT QhResult
;
1151 BOOLEAN IsSlowDevice
;
1153 Uhc
= UHC_FROM_USB2_HC_PROTO (This
);
1158 if (DeviceSpeed
== EFI_USB_SPEED_HIGH
) {
1159 return EFI_INVALID_PARAMETER
;
1162 IsSlowDevice
= (BOOLEAN
) ((EFI_USB_SPEED_LOW
== DeviceSpeed
) ? TRUE
: FALSE
);
1164 if ((DataLength
== NULL
) || (Data
== NULL
) || (TransferResult
== NULL
)) {
1165 return EFI_INVALID_PARAMETER
;
1168 if ((EndPointAddress
& 0x80) == 0) {
1169 return EFI_INVALID_PARAMETER
;
1172 if ((*DataToggle
!= 1) && (*DataToggle
!= 0)) {
1173 return EFI_INVALID_PARAMETER
;
1176 if ((*DataLength
== 0) || (MaximumPacketLength
> 64)) {
1177 return EFI_INVALID_PARAMETER
;
1180 if (IsSlowDevice
&& (MaximumPacketLength
> 8)) {
1181 return EFI_INVALID_PARAMETER
;
1184 *TransferResult
= EFI_USB_ERR_SYSTEM
;
1185 Status
= EFI_DEVICE_ERROR
;
1188 UhciAckAllInterrupt (Uhc
);
1190 if (!UhciIsHcWorking (Uhc
->PciIo
)) {
1194 OldTpl
= gBS
->RaiseTPL (UHCI_TPL
);
1197 // Map the source data buffer for bus master access.
1198 // Create Tds list, then link it to the UHC's interrupt list
1200 Status
= UhciMapUserData (
1210 if (EFI_ERROR (Status
)) {
1214 TDs
= UhciCreateBulkOrIntTds (
1222 (UINT8
) MaximumPacketLength
,
1227 Uhc
->PciIo
->Unmap (Uhc
->PciIo
, DataMap
);
1229 Status
= EFI_OUT_OF_RESOURCES
;
1234 UhciLinkTdToQh (Uhc
->SyncIntQh
, TDs
);
1236 Status
= UhciExecuteTransfer (Uhc
, Uhc
->SyncIntQh
, TDs
, TimeOut
, IsSlowDevice
, &QhResult
);
1238 UhciUnlinkTdFromQh (Uhc
->SyncIntQh
, TDs
);
1239 Uhc
->PciIo
->Flush (Uhc
->PciIo
);
1241 *TransferResult
= QhResult
.Result
;
1242 *DataToggle
= QhResult
.NextToggle
;
1243 *DataLength
= QhResult
.Complete
;
1245 UhciDestoryTds (Uhc
, TDs
);
1246 Uhc
->PciIo
->Unmap (Uhc
->PciIo
, DataMap
);
1249 gBS
->RestoreTPL (OldTpl
);
1255 Submits isochronous transfer to a target USB device according to UEFI 2.0 spec.
1257 This : A pointer to the EFI_USB2_HC_PROTOCOL instance.
1258 DeviceAddress : Target device address
1259 EndPointAddress : Endpoint number and direction
1260 DeviceSpeed : Device speed
1261 MaximumPacketLength : Maximum packet size of the target endpoint
1262 DataBuffersNumber : Number of data buffers prepared for the transfer.
1263 Data : Array of pointers to the buffers of data
1264 DataLength : On input, size of the data buffer, On output,
1265 actually transferred data size.
1266 Translator : A pointr to the transaction translator data.
1267 TransferResult : Variable to receive transfer result
1269 @return EFI_UNSUPPORTED
1275 Uhci2IsochronousTransfer (
1276 IN EFI_USB2_HC_PROTOCOL
*This
,
1277 IN UINT8 DeviceAddress
,
1278 IN UINT8 EndPointAddress
,
1279 IN UINT8 DeviceSpeed
,
1280 IN UINTN MaximumPacketLength
,
1281 IN UINT8 DataBuffersNumber
,
1282 IN OUT VOID
*Data
[EFI_USB_MAX_ISO_BUFFER_NUM
],
1283 IN UINTN DataLength
,
1284 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
1285 OUT UINT32
*TransferResult
1288 return EFI_UNSUPPORTED
;
1293 Submits Async isochronous transfer to a target USB device according to UEFI 2.0 spec.
1295 This : A pointer to the EFI_USB2_HC_PROTOCOL instance.
1296 DeviceAddress : Target device address
1297 EndPointAddress : Endpoint number and direction
1298 DeviceSpeed : Device speed
1299 MaximumPacketLength : Maximum packet size of the target endpoint
1300 DataBuffersNumber : Number of data buffers prepared for the transfer.
1301 Data : Array of pointers to the buffers of data
1302 Translator : A pointr to the transaction translator data.
1303 IsochronousCallBack : Function to call when the transfer complete
1304 Context : Pass to the call back function as parameter
1306 @return EFI_UNSUPPORTED
1312 Uhci2AsyncIsochronousTransfer (
1313 IN EFI_USB2_HC_PROTOCOL
*This
,
1314 IN UINT8 DeviceAddress
,
1315 IN UINT8 EndPointAddress
,
1316 IN UINT8 DeviceSpeed
,
1317 IN UINTN MaximumPacketLength
,
1318 IN UINT8 DataBuffersNumber
,
1319 IN OUT VOID
*Data
[EFI_USB_MAX_ISO_BUFFER_NUM
],
1320 IN UINTN DataLength
,
1321 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
1322 IN EFI_ASYNC_USB_TRANSFER_CALLBACK IsochronousCallBack
,
1326 return EFI_UNSUPPORTED
;
1331 UhciDriverEntryPoint (
1332 IN EFI_HANDLE ImageHandle
,
1333 IN EFI_SYSTEM_TABLE
*SystemTable
1337 Routine Description:
1339 Entry point for EFI drivers.
1343 ImageHandle - EFI_HANDLE
1344 SystemTable - EFI_SYSTEM_TABLE
1348 EFI_SUCCESS : Driver is successfully loaded
1353 return EfiLibInstallDriverBindingComponentName2 (
1356 &gUhciDriverBinding
,
1358 &gUhciComponentName
,
1359 &gUhciComponentName2
1365 Test to see if this driver supports ControllerHandle. Any
1366 ControllerHandle that has UsbHcProtocol installed will be supported.
1368 @param This Protocol instance pointer.
1369 @param Controller Handle of device to test
1370 @param RemainingDevicePath Not used
1372 @return EFI_SUCCESS : This driver supports this device.
1373 @return EFI_UNSUPPORTED : This driver does not support this device.
1378 UhciDriverBindingSupported (
1379 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1380 IN EFI_HANDLE Controller
,
1381 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
1384 EFI_STATUS OpenStatus
;
1386 EFI_PCI_IO_PROTOCOL
*PciIo
;
1387 USB_CLASSC UsbClassCReg
;
1390 // Test whether there is PCI IO Protocol attached on the controller handle.
1392 OpenStatus
= gBS
->OpenProtocol (
1394 &gEfiPciIoProtocolGuid
,
1396 This
->DriverBindingHandle
,
1398 EFI_OPEN_PROTOCOL_BY_DRIVER
1401 if (EFI_ERROR (OpenStatus
)) {
1405 Status
= PciIo
->Pci
.Read (
1409 sizeof (USB_CLASSC
) / sizeof (UINT8
),
1413 if (EFI_ERROR (Status
)) {
1414 Status
= EFI_UNSUPPORTED
;
1419 // Test whether the controller belongs to UHCI type
1421 if ((UsbClassCReg
.BaseCode
!= PCI_CLASS_SERIAL
) ||
1422 (UsbClassCReg
.SubClassCode
!= PCI_CLASS_SERIAL_USB
) ||
1423 (UsbClassCReg
.PI
!= PCI_CLASSC_PI_UHCI
)
1426 Status
= EFI_UNSUPPORTED
;
1430 gBS
->CloseProtocol (
1432 &gEfiPciIoProtocolGuid
,
1433 This
->DriverBindingHandle
,
1443 Allocate and initialize the empty UHCI device
1445 @param PciIo The PCIIO to use
1447 @return Allocated UHCI device
1453 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
1454 IN UINT64 OriginalPciAttributes
1460 Uhc
= AllocateZeroPool (sizeof (USB_HC_DEV
));
1467 // This driver supports both USB_HC_PROTOCOL and USB2_HC_PROTOCOL.
1468 // USB_HC_PROTOCOL is for EFI 1.1 backward compability.
1470 Uhc
->Signature
= USB_HC_DEV_SIGNATURE
;
1471 Uhc
->Usb2Hc
.GetCapability
= Uhci2GetCapability
;
1472 Uhc
->Usb2Hc
.Reset
= Uhci2Reset
;
1473 Uhc
->Usb2Hc
.GetState
= Uhci2GetState
;
1474 Uhc
->Usb2Hc
.SetState
= Uhci2SetState
;
1475 Uhc
->Usb2Hc
.ControlTransfer
= Uhci2ControlTransfer
;
1476 Uhc
->Usb2Hc
.BulkTransfer
= Uhci2BulkTransfer
;
1477 Uhc
->Usb2Hc
.AsyncInterruptTransfer
= Uhci2AsyncInterruptTransfer
;
1478 Uhc
->Usb2Hc
.SyncInterruptTransfer
= Uhci2SyncInterruptTransfer
;
1479 Uhc
->Usb2Hc
.IsochronousTransfer
= Uhci2IsochronousTransfer
;
1480 Uhc
->Usb2Hc
.AsyncIsochronousTransfer
= Uhci2AsyncIsochronousTransfer
;
1481 Uhc
->Usb2Hc
.GetRootHubPortStatus
= Uhci2GetRootHubPortStatus
;
1482 Uhc
->Usb2Hc
.SetRootHubPortFeature
= Uhci2SetRootHubPortFeature
;
1483 Uhc
->Usb2Hc
.ClearRootHubPortFeature
= Uhci2ClearRootHubPortFeature
;
1484 Uhc
->Usb2Hc
.MajorRevision
= 0x1;
1485 Uhc
->Usb2Hc
.MinorRevision
= 0x1;
1488 Uhc
->OriginalPciAttributes
= OriginalPciAttributes
;
1489 Uhc
->MemPool
= UsbHcInitMemPool (PciIo
, TRUE
, 0);
1491 if (Uhc
->MemPool
== NULL
) {
1492 Status
= EFI_OUT_OF_RESOURCES
;
1496 InitializeListHead (&Uhc
->AsyncIntList
);
1498 Status
= gBS
->CreateEvent (
1499 EVT_TIMER
| EVT_NOTIFY_SIGNAL
,
1501 UhciMonitorAsyncReqList
,
1503 &Uhc
->AsyncIntMonitor
1506 if (EFI_ERROR (Status
)) {
1507 UsbHcFreeMemPool (Uhc
->MemPool
);
1514 gBS
->FreePool (Uhc
);
1520 Free the UHCI device and release its associated resources
1522 @param Uhc The UHCI device to release
1533 if (Uhc
->AsyncIntMonitor
!= NULL
) {
1534 gBS
->CloseEvent (Uhc
->AsyncIntMonitor
);
1537 if (Uhc
->MemPool
!= NULL
) {
1538 UsbHcFreeMemPool (Uhc
->MemPool
);
1541 if (Uhc
->CtrlNameTable
) {
1542 FreeUnicodeStringTable (Uhc
->CtrlNameTable
);
1545 gBS
->FreePool (Uhc
);
1550 Uninstall all Uhci Interface
1552 @param Controller Controller handle
1553 @param This Protocol instance pointer.
1561 IN EFI_HANDLE Controller
,
1562 IN EFI_USB2_HC_PROTOCOL
*This
1568 // Uninstall the USB_HC and USB_HC2 protocol, then disable the controller
1570 Uhc
= UHC_FROM_USB2_HC_PROTO (This
);
1571 UhciStopHc (Uhc
, UHC_GENERIC_TIMEOUT
);
1573 gBS
->UninstallProtocolInterface (
1575 &gEfiUsb2HcProtocolGuid
,
1579 UhciFreeAllAsyncReq (Uhc
);
1580 UhciDestoryFrameList (Uhc
);
1583 // Restore original PCI attributes
1585 Uhc
->PciIo
->Attributes (
1587 EfiPciIoAttributeOperationSet
,
1588 Uhc
->OriginalPciAttributes
,
1597 Starting the Usb UHCI Driver
1599 @param This Protocol instance pointer.
1600 @param Controller Handle of device to test
1601 @param RemainingDevicePath Not used
1603 @retval EFI_SUCCESS This driver supports this device.
1604 @retval EFI_UNSUPPORTED This driver does not support this device.
1605 @retval EFI_DEVICE_ERROR This driver cannot be started due to device Error
1606 EFI_OUT_OF_RESOURCES- Failed due to resource
1612 UhciDriverBindingStart (
1613 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1614 IN EFI_HANDLE Controller
,
1615 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
1619 EFI_PCI_IO_PROTOCOL
*PciIo
;
1622 UINT64 OriginalPciAttributes
;
1623 BOOLEAN PciAttributesSaved
;
1626 // Open PCIIO, then enable the EHC device and turn off emulation
1629 Status
= gBS
->OpenProtocol (
1631 &gEfiPciIoProtocolGuid
,
1633 This
->DriverBindingHandle
,
1635 EFI_OPEN_PROTOCOL_BY_DRIVER
1638 if (EFI_ERROR (Status
)) {
1642 PciAttributesSaved
= FALSE
;
1644 // Save original PCI attributes
1646 Status
= PciIo
->Attributes (
1648 EfiPciIoAttributeOperationGet
,
1650 &OriginalPciAttributes
1653 if (EFI_ERROR (Status
)) {
1656 PciAttributesSaved
= TRUE
;
1659 // Robustnesss improvement such as for UoL
1660 // Default is not required.
1662 if (FeaturePcdGet (PcdTurnOffUsbLegacySupport
)) {
1663 UhciTurnOffUsbEmulation (PciIo
);
1666 Status
= PciIo
->Attributes (
1668 EfiPciIoAttributeOperationSupported
,
1672 if (!EFI_ERROR (Status
)) {
1673 Supports
&= EFI_PCI_DEVICE_ENABLE
;
1674 Status
= PciIo
->Attributes (
1676 EfiPciIoAttributeOperationEnable
,
1682 if (EFI_ERROR (Status
)) {
1686 Uhc
= UhciAllocateDev (PciIo
, OriginalPciAttributes
);
1689 Status
= EFI_OUT_OF_RESOURCES
;
1694 // Allocate and Init Host Controller's Frame List Entry
1696 Status
= UhciInitFrameList (Uhc
);
1698 if (EFI_ERROR (Status
)) {
1699 Status
= EFI_OUT_OF_RESOURCES
;
1703 Status
= gBS
->SetTimer (
1704 Uhc
->AsyncIntMonitor
,
1706 UHC_ASYNC_POLL_INTERVAL
1709 if (EFI_ERROR (Status
)) {
1714 // Install USB2_HC_PROTOCOL
1716 Status
= gBS
->InstallMultipleProtocolInterfaces (
1718 &gEfiUsb2HcProtocolGuid
,
1723 if (EFI_ERROR (Status
)) {
1728 // Install the component name protocol
1730 Uhc
->CtrlNameTable
= NULL
;
1734 gUhciComponentName
.SupportedLanguages
,
1735 &Uhc
->CtrlNameTable
,
1736 L
"Usb Universal Host Controller",
1741 gUhciComponentName2
.SupportedLanguages
,
1742 &Uhc
->CtrlNameTable
,
1743 L
"Usb Universal Host Controller",
1749 // Start the UHCI hardware, also set its reclamation point to 64 bytes
1751 UhciWriteReg (Uhc
->PciIo
, USBCMD_OFFSET
, USBCMD_RS
| USBCMD_MAXP
);
1759 if (PciAttributesSaved
== TRUE
) {
1761 // Restore original PCI attributes
1765 EfiPciIoAttributeOperationSet
,
1766 OriginalPciAttributes
,
1771 gBS
->CloseProtocol (
1773 &gEfiPciIoProtocolGuid
,
1774 This
->DriverBindingHandle
,
1783 Stop this driver on ControllerHandle. Support stoping any child handles
1784 created by this driver.
1786 @param This Protocol instance pointer.
1787 @param Controller Handle of device to stop driver on
1788 @param NumberOfChildren Number of Children in the ChildHandleBuffer
1789 @param ChildHandleBuffer List of handles for the children we need to stop.
1797 UhciDriverBindingStop (
1798 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1799 IN EFI_HANDLE Controller
,
1800 IN UINTN NumberOfChildren
,
1801 IN EFI_HANDLE
*ChildHandleBuffer
1804 EFI_USB2_HC_PROTOCOL
*Usb2Hc
;
1807 Status
= gBS
->OpenProtocol (
1809 &gEfiUsb2HcProtocolGuid
,
1811 This
->DriverBindingHandle
,
1813 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1817 // Test whether the Controller handler passed in is a valid
1818 // Usb controller handle that should be supported, if not,
1819 // return the error status directly
1821 if (EFI_ERROR (Status
)) {
1825 UhciCleanDevUp (Controller
, Usb2Hc
);
1827 gBS
->CloseProtocol (
1829 &gEfiPciIoProtocolGuid
,
1830 This
->DriverBindingHandle
,
1837 EFI_DRIVER_BINDING_PROTOCOL gUhciDriverBinding
= {
1838 UhciDriverBindingSupported
,
1839 UhciDriverBindingStart
,
1840 UhciDriverBindingStop
,