3 Copyright (c) 2004 - 2007, 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.
29 Provides software reset for the USB host controller.
31 This : A pointer to the EFI_USB_HC_PROTOCOL instance.
32 Attributes: A bit mask of the reset operation to perform.
34 @return EFI_SUCCESS : The reset operation succeeded.
35 @return EFI_INVALID_PARAMETER : Attributes is not valid.
36 @return EFI_DEVICE_ERROR : An error was encountered while attempting
37 @return to perform the reset operation.
44 IN EFI_USB_HC_PROTOCOL
*This
,
51 OldTpl
= gBS
->RaiseTPL (UHCI_TPL
);
52 Uhc
= UHC_FROM_USB_HC_PROTO (This
);
55 case EFI_USB_HC_RESET_GLOBAL
:
57 // Stop schedule and set the Global Reset bit in the command register
59 UhciStopHc (Uhc
, UHC_GENERIC_TIMEOUT
);
60 UhciSetRegBit (Uhc
->PciIo
, USBCMD_OFFSET
, USBCMD_GRESET
);
62 gBS
->Stall (UHC_ROOT_PORT_RESET_STALL
);
65 // Clear the Global Reset bit to zero.
67 UhciClearRegBit (Uhc
->PciIo
, USBCMD_OFFSET
, USBCMD_GRESET
);
69 gBS
->Stall (UHC_ROOT_PORT_RECOVERY_STALL
);
72 case EFI_USB_HC_RESET_HOST_CONTROLLER
:
74 // Stop schedule and set Host Controller Reset bit to 1
76 UhciStopHc (Uhc
, UHC_GENERIC_TIMEOUT
);
77 UhciSetRegBit (Uhc
->PciIo
, USBCMD_OFFSET
, USBCMD_HCRESET
);
79 gBS
->Stall (UHC_ROOT_PORT_RECOVERY_STALL
);
83 goto ON_INVAILD_PARAMETER
;
87 // Delete all old transactions on the USB bus, then
88 // reinitialize the frame list
90 UhciFreeAllAsyncReq (Uhc
);
91 UhciDestoryFrameList (Uhc
);
92 UhciInitFrameList (Uhc
);
94 gBS
->RestoreTPL (OldTpl
);
100 gBS
->RestoreTPL (OldTpl
);
102 return EFI_INVALID_PARAMETER
;
107 Retrieves current state of the USB host controller.
109 This : A pointer to the EFI_USB_HC_PROTOCOL instance.
110 State : A pointer to the EFI_USB_HC_STATE data structure that
111 indicates current state of the USB host controller.
113 @return EFI_SUCCESS : State was returned
114 @return EFI_INVALID_PARAMETER : State is NULL.
115 @return EFI_DEVICE_ERROR : An error was encountered
122 IN EFI_USB_HC_PROTOCOL
*This
,
123 OUT EFI_USB_HC_STATE
*State
131 return EFI_INVALID_PARAMETER
;
134 Uhc
= UHC_FROM_USB_HC_PROTO (This
);
136 UsbCmd
= UhciReadReg (Uhc
->PciIo
, USBCMD_OFFSET
);
137 UsbSts
= UhciReadReg (Uhc
->PciIo
, USBSTS_OFFSET
);
139 if (UsbCmd
& USBCMD_EGSM
) {
140 *State
= EfiUsbHcStateSuspend
;
142 } else if ((UsbSts
& USBSTS_HCH
) != 0) {
143 *State
= EfiUsbHcStateHalt
;
146 *State
= EfiUsbHcStateOperational
;
154 Sets the USB host controller to a specific state.
156 This : A pointer to the EFI_USB_HC_PROTOCOL instance.
157 State : Indicates the state of the host controller that will be set.
159 @return EFI_SUCCESS : The USB host controller was successfully set
160 @return EFI_INVALID_PARAMETER : State is invalid.
161 @return EFI_DEVICE_ERROR : Failed to set the state specified
168 IN EFI_USB_HC_PROTOCOL
*This
,
169 IN EFI_USB_HC_STATE State
172 EFI_USB_HC_STATE CurState
;
178 Uhc
= UHC_FROM_USB_HC_PROTO (This
);
179 Status
= UhciGetState (This
, &CurState
);
181 if (EFI_ERROR (Status
)) {
182 return EFI_DEVICE_ERROR
;
185 if (CurState
== State
) {
189 Status
= EFI_SUCCESS
;
190 OldTpl
= gBS
->RaiseTPL (UHCI_TPL
);
193 case EfiUsbHcStateHalt
:
194 Status
= UhciStopHc (Uhc
, UHC_GENERIC_TIMEOUT
);
197 case EfiUsbHcStateOperational
:
198 UsbCmd
= UhciReadReg (Uhc
->PciIo
, USBCMD_OFFSET
);
200 if (CurState
== EfiUsbHcStateHalt
) {
202 // Set Run/Stop bit to 1, also set the bandwidht reclamation
205 UsbCmd
|= USBCMD_RS
| USBCMD_MAXP
;
206 UhciWriteReg (Uhc
->PciIo
, USBCMD_OFFSET
, UsbCmd
);
208 } else if (CurState
== EfiUsbHcStateSuspend
) {
210 // If FGR(Force Global Resume) bit is 0, set it
212 if ((UsbCmd
& USBCMD_FGR
) == 0) {
213 UsbCmd
|= USBCMD_FGR
;
214 UhciWriteReg (Uhc
->PciIo
, USBCMD_OFFSET
, UsbCmd
);
218 // wait 20ms to let resume complete (20ms is specified by UHCI spec)
220 gBS
->Stall (UHC_FORCE_GLOBAL_RESUME_STALL
);
223 // Write FGR bit to 0 and EGSM(Enter Global Suspend Mode) bit to 0
225 UsbCmd
&= ~USBCMD_FGR
;
226 UsbCmd
&= ~USBCMD_EGSM
;
228 UhciWriteReg (Uhc
->PciIo
, USBCMD_OFFSET
, UsbCmd
);
233 case EfiUsbHcStateSuspend
:
234 Status
= UhciSetState (This
, EfiUsbHcStateHalt
);
236 if (EFI_ERROR (Status
)) {
237 Status
= EFI_DEVICE_ERROR
;
242 // Set Enter Global Suspend Mode bit to 1.
244 UsbCmd
= UhciReadReg (Uhc
->PciIo
, USBCMD_OFFSET
);
245 UsbCmd
|= USBCMD_EGSM
;
246 UhciWriteReg (Uhc
->PciIo
, USBCMD_OFFSET
, UsbCmd
);
250 Status
= EFI_INVALID_PARAMETER
;
255 gBS
->RestoreTPL (OldTpl
);
261 Retrieves the number of root hub ports.
263 This : A pointer to the EFI_USB_HC_PROTOCOL instance.
264 PortNumber : A pointer to the number of the root hub ports.
266 @return EFI_SUCCESS : The port number was retrieved successfully.
267 @return EFI_INVALID_PARAMETER : PortNumber is NULL.
268 @return EFI_DEVICE_ERROR : An error was encountered
274 UhciGetRootHubPortNumber (
275 IN EFI_USB_HC_PROTOCOL
*This
,
276 OUT UINT8
*PortNumber
284 Uhc
= UHC_FROM_USB_HC_PROTO (This
);
286 if (PortNumber
== NULL
) {
287 return EFI_INVALID_PARAMETER
;
292 for (Index
= 0; Index
< USB_MAX_ROOTHUB_PORT
; Index
++) {
293 Offset
= USBPORTSC_OFFSET
+ Index
* 2;
294 PortSC
= UhciReadReg (Uhc
->PciIo
, Offset
);
297 // Port status's bit 7 is reserved and always returns 1 if
298 // the port number is valid. Intel's UHCI (in EHCI controller)
299 // returns 0 in this bit if port number is invalid. Also, if
300 // PciIo IoRead returns error, 0xFFFF is returned to caller.
302 if (((PortSC
& 0x80) != 0) && (PortSC
!= 0xFFFF)) {
307 Uhc
->RootPorts
= *PortNumber
;
309 UHCI_DEBUG (("UhciGetRootHubPortNumber: %d ports\n", Uhc
->RootPorts
));
315 Retrieves the current status of a USB root hub port.
317 This : A pointer to the EFI_USB_HC_PROTOCOL.
318 PortNumber : Specifies the root hub port. This value is zero-based.
319 PortStatus : A pointer to the current port status bits and port status change bits.
321 @return EFI_SUCCESS : The port status was returned in PortStatus.
322 @return EFI_INVALID_PARAMETER : PortNumber is invalid.
323 @return EFI_DEVICE_ERROR : Can't read register
328 UhciGetRootHubPortStatus (
329 IN EFI_USB_HC_PROTOCOL
*This
,
331 OUT EFI_USB_PORT_STATUS
*PortStatus
338 Uhc
= UHC_FROM_USB_HC_PROTO (This
);
340 if (PortStatus
== NULL
) {
341 return EFI_INVALID_PARAMETER
;
344 if (PortNumber
>= Uhc
->RootPorts
) {
345 return EFI_INVALID_PARAMETER
;
348 Offset
= USBPORTSC_OFFSET
+ PortNumber
* 2;
349 PortStatus
->PortStatus
= 0;
350 PortStatus
->PortChangeStatus
= 0;
352 PortSC
= UhciReadReg (Uhc
->PciIo
, Offset
);
354 if (PortSC
& USBPORTSC_CCS
) {
355 PortStatus
->PortStatus
|= USB_PORT_STAT_CONNECTION
;
358 if (PortSC
& USBPORTSC_PED
) {
359 PortStatus
->PortStatus
|= USB_PORT_STAT_ENABLE
;
362 if (PortSC
& USBPORTSC_SUSP
) {
363 UHCI_DEBUG (("UhciGetRootHubPortStatus: port %d is suspended\n", PortNumber
));
364 PortStatus
->PortStatus
|= USB_PORT_STAT_SUSPEND
;
367 if (PortSC
& USBPORTSC_PR
) {
368 PortStatus
->PortStatus
|= USB_PORT_STAT_RESET
;
371 if (PortSC
& USBPORTSC_LSDA
) {
372 PortStatus
->PortStatus
|= USB_PORT_STAT_LOW_SPEED
;
376 // CHC will always return one in port owner bit
378 PortStatus
->PortStatus
|= USB_PORT_STAT_OWNER
;
380 if (PortSC
& USBPORTSC_CSC
) {
381 PortStatus
->PortChangeStatus
|= USB_PORT_STAT_C_CONNECTION
;
384 if (PortSC
& USBPORTSC_PEDC
) {
385 PortStatus
->PortChangeStatus
|= USB_PORT_STAT_C_ENABLE
;
393 Sets a feature for the specified root hub port.
395 This : A pointer to the EFI_USB_HC_PROTOCOL.
396 PortNumber : Specifies the root hub port whose feature
397 is requested to be set.
398 PortFeature : Indicates the feature selector associated
399 with the feature set request.
401 @return EFI_SUCCESS : The feature was set for the port.
402 @return EFI_INVALID_PARAMETER : PortNumber is invalid or PortFeature is invalid.
403 @return EFI_DEVICE_ERROR : Can't read register
409 UhciSetRootHubPortFeature (
410 IN EFI_USB_HC_PROTOCOL
*This
,
412 IN EFI_USB_PORT_FEATURE PortFeature
421 Uhc
= UHC_FROM_USB_HC_PROTO (This
);
423 if (PortNumber
>= Uhc
->RootPorts
) {
424 return EFI_INVALID_PARAMETER
;
427 Offset
= USBPORTSC_OFFSET
+ PortNumber
* 2;
429 OldTpl
= gBS
->RaiseTPL (UHCI_TPL
);
430 PortSC
= UhciReadReg (Uhc
->PciIo
, Offset
);
432 switch (PortFeature
) {
433 case EfiUsbPortSuspend
:
434 Command
= UhciReadReg (Uhc
->PciIo
, USBCMD_OFFSET
);
435 if (!(Command
& USBCMD_EGSM
)) {
437 // if global suspend is not active, can set port suspend
440 PortSC
|= USBPORTSC_SUSP
;
444 case EfiUsbPortReset
:
446 PortSC
|= USBPORTSC_PR
;
449 case EfiUsbPortPower
:
455 case EfiUsbPortEnable
:
457 PortSC
|= USBPORTSC_PED
;
461 gBS
->RestoreTPL (OldTpl
);
462 return EFI_INVALID_PARAMETER
;
465 UhciWriteReg (Uhc
->PciIo
, Offset
, PortSC
);
466 gBS
->RestoreTPL (OldTpl
);
473 Clears a feature for the specified root hub port.
475 This : A pointer to the EFI_USB_HC_PROTOCOL instance.
476 PortNumber : Specifies the root hub port whose feature
477 is requested to be cleared.
478 PortFeature : Indicates the feature selector associated with the
479 feature clear request.
481 @return EFI_SUCCESS : The feature was cleared for the port.
482 @return EFI_INVALID_PARAMETER : PortNumber is invalid or PortFeature is invalid.
483 @return EFI_DEVICE_ERROR : Can't read register
489 UhciClearRootHubPortFeature (
490 IN EFI_USB_HC_PROTOCOL
*This
,
492 IN EFI_USB_PORT_FEATURE PortFeature
500 Uhc
= UHC_FROM_USB_HC_PROTO (This
);
502 if (PortNumber
>= Uhc
->RootPorts
) {
503 return EFI_INVALID_PARAMETER
;
506 Offset
= USBPORTSC_OFFSET
+ PortNumber
* 2;
508 OldTpl
= gBS
->RaiseTPL (UHCI_TPL
);
509 PortSC
= UhciReadReg (Uhc
->PciIo
, Offset
);
511 switch (PortFeature
) {
512 case EfiUsbPortEnable
:
514 PortSC
&= ~USBPORTSC_PED
;
517 case EfiUsbPortSuspend
:
519 // Cause a resume on the specified port if in suspend mode.
522 PortSC
&= ~USBPORTSC_SUSP
;
525 case EfiUsbPortPower
:
531 case EfiUsbPortReset
:
533 PortSC
&= ~USBPORTSC_PR
;
536 case EfiUsbPortConnectChange
:
538 PortSC
|= USBPORTSC_CSC
;
541 case EfiUsbPortEnableChange
:
543 PortSC
|= USBPORTSC_PEDC
;
546 case EfiUsbPortSuspendChange
:
548 // Root hub does not support this
552 case EfiUsbPortOverCurrentChange
:
554 // Root hub does not support this
558 case EfiUsbPortResetChange
:
560 // Root hub does not support this
565 gBS
->RestoreTPL (OldTpl
);
566 return EFI_INVALID_PARAMETER
;
569 UhciWriteReg (Uhc
->PciIo
, Offset
, PortSC
);
570 gBS
->RestoreTPL (OldTpl
);
577 Submits control transfer to a target USB device.
579 This : A pointer to the EFI_USB_HC_PROTOCOL instance.
580 DeviceAddress : Usb device address
581 IsSlowDevice : Whether the device is of slow speed or full speed
582 MaximumPacketLength : maximum packet size of the default control endpoint
583 Request : USB device request to send
584 TransferDirection : Specifies the data direction for the transfer.
585 Data : Data buffer to transmit from or receive into
586 DataLength : Number of bytes of the data
587 TimeOut : Maximum time, in microseconds
588 TransferResult : Return result in this
590 @return EFI_SUCCESS : Transfer was completed successfully.
591 @return EFI_OUT_OF_RESOURCES : Failed due to a lack of resources.
592 @return EFI_INVALID_PARAMETER : Some parameters are invalid.
593 @return EFI_TIMEOUT : Failed due to timeout.
594 @return EFI_DEVICE_ERROR : Failed due to host controller or device error.
600 UhciControlTransfer (
601 IN EFI_USB_HC_PROTOCOL
*This
,
602 IN UINT8 DeviceAddress
,
603 IN BOOLEAN IsSlowDevice
,
604 IN UINT8 MaximumPacketLength
,
605 IN EFI_USB_DEVICE_REQUEST
*Request
,
606 IN EFI_USB_DATA_DIRECTION TransferDirection
,
607 IN OUT VOID
*Data
, OPTIONAL
608 IN OUT UINTN
*DataLength
, OPTIONAL
610 OUT UINT32
*TransferResult
617 UHCI_QH_RESULT QhResult
;
624 Uhc
= UHC_FROM_USB_HC_PROTO (This
);
632 // Parameters Checking
634 if (Request
== NULL
|| TransferResult
== NULL
) {
635 return EFI_INVALID_PARAMETER
;
638 if (IsSlowDevice
&& (MaximumPacketLength
!= 8)) {
639 return EFI_INVALID_PARAMETER
;
642 if ((MaximumPacketLength
!= 8) && (MaximumPacketLength
!= 16) &&
643 (MaximumPacketLength
!= 32) && (MaximumPacketLength
!= 64)) {
645 return EFI_INVALID_PARAMETER
;
648 if ((TransferDirection
!= EfiUsbNoData
) && (DataLength
== NULL
)) {
649 return EFI_INVALID_PARAMETER
;
652 *TransferResult
= EFI_USB_ERR_SYSTEM
;
653 Status
= EFI_DEVICE_ERROR
;
656 // If errors exist that cause host controller halt,
657 // clear status then return EFI_DEVICE_ERROR.
659 UhciAckAllInterrupt (Uhc
);
661 if (!UhciIsHcWorking (Uhc
->PciIo
)) {
662 return EFI_DEVICE_ERROR
;
665 OldTpl
= gBS
->RaiseTPL (UHCI_TPL
);
668 // Map the Request and data for bus master access,
669 // then create a list of TD for this transfer
671 Status
= UhciMapUserRequest (Uhc
, Request
, &RequestPhy
, &RequestMap
);
673 if (EFI_ERROR (Status
)) {
677 Status
= UhciMapUserData (Uhc
, TransferDirection
, Data
, DataLength
, &PktId
, &DataPhy
, &DataMap
);
679 if (EFI_ERROR (Status
)) {
680 Uhc
->PciIo
->Unmap (Uhc
->PciIo
, RequestMap
);
684 TDs
= UhciCreateCtrlTds (
696 Status
= EFI_OUT_OF_RESOURCES
;
701 // According to the speed of the end point, link
702 // the TD to corrosponding queue head, then check
703 // the execution result
705 UhciLinkTdToQh (Uhc
->CtrlQh
, TDs
);
706 Status
= UhciExecuteTransfer (Uhc
, Uhc
->CtrlQh
, TDs
, TimeOut
, IsSlowDevice
, &QhResult
);
707 UhciUnlinkTdFromQh (Uhc
->CtrlQh
, TDs
);
709 Uhc
->PciIo
->Flush (Uhc
->PciIo
);
711 *TransferResult
= QhResult
.Result
;
713 if (DataLength
!= NULL
) {
714 *DataLength
= QhResult
.Complete
;
717 UhciDestoryTds (Uhc
, TDs
);
720 Uhc
->PciIo
->Unmap (Uhc
->PciIo
, DataMap
);
721 Uhc
->PciIo
->Unmap (Uhc
->PciIo
, RequestMap
);
724 gBS
->RestoreTPL (OldTpl
);
730 Submits bulk transfer to a bulk endpoint of a USB device.
732 This :A pointer to the EFI_USB_HC_PROTOCOL instance.
733 DeviceAddress : Usb device address
734 EndPointAddress : Endpoint number and endpoint direction
735 MaximumPacketLength : Maximum packet size of the target endpoint
736 Data : Data buffer to transmit from or receive into
737 DataLength : Length of the data buffer
738 DataToggle : On input, data toggle to use, on output, the next toggle
739 TimeOut : Indicates the maximum time
740 TransferResult : Variable to receive the transfer result
742 @return EFI_SUCCESS : The bulk transfer was completed successfully.
743 @return EFI_OUT_OF_RESOURCES : Failed due to lack of resource.
744 @return EFI_INVALID_PARAMETER : Some parameters are invalid.
745 @return EFI_TIMEOUT : Failed due to timeout.
746 @return EFI_DEVICE_ERROR : Failed due to host controller or device error.
753 IN EFI_USB_HC_PROTOCOL
*This
,
754 IN UINT8 DeviceAddress
,
755 IN UINT8 EndPointAddress
,
756 IN UINT8 MaximumPacketLength
,
758 IN OUT UINTN
*DataLength
,
759 IN OUT UINT8
*DataToggle
,
761 OUT UINT32
*TransferResult
764 EFI_USB_DATA_DIRECTION Direction
;
769 UHCI_QH_RESULT QhResult
;
775 Uhc
= UHC_FROM_USB_HC_PROTO (This
);
779 if ((DataLength
== NULL
) || (Data
== NULL
) || (TransferResult
== NULL
)) {
780 return EFI_INVALID_PARAMETER
;
783 if (*DataLength
== 0) {
784 return EFI_INVALID_PARAMETER
;
787 if ((*DataToggle
!= 1) && (*DataToggle
!= 0)) {
788 return EFI_INVALID_PARAMETER
;
791 if ((MaximumPacketLength
!= 8) && (MaximumPacketLength
!= 16) &&
792 (MaximumPacketLength
!= 32) && (MaximumPacketLength
!= 64)) {
793 return EFI_INVALID_PARAMETER
;
796 *TransferResult
= EFI_USB_ERR_SYSTEM
;
797 Status
= EFI_OUT_OF_RESOURCES
;
800 // If has errors that cause host controller halt,
801 // then return EFI_DEVICE_ERROR directly.
803 UhciAckAllInterrupt (Uhc
);
805 if (!UhciIsHcWorking (Uhc
->PciIo
)) {
806 return EFI_DEVICE_ERROR
;
809 OldTpl
= gBS
->RaiseTPL (UHCI_TPL
);
812 // Map the source data buffer for bus master access,
813 // then create a list of TDs
815 if (EndPointAddress
& 0x80) {
816 Direction
= EfiUsbDataIn
;
818 Direction
= EfiUsbDataOut
;
821 Status
= UhciMapUserData (Uhc
, Direction
, Data
, DataLength
, &PktId
, &DataPhy
, &DataMap
);
823 if (EFI_ERROR (Status
)) {
827 Status
= EFI_OUT_OF_RESOURCES
;
828 TDs
= UhciCreateBulkOrIntTds (
841 Uhc
->PciIo
->Unmap (Uhc
->PciIo
, DataMap
);
847 // Link the TDs to bulk queue head. According to the platfore
848 // defintion of UHCI_NO_BW_RECLAMATION, BulkQh is either configured
849 // to do full speed bandwidth reclamation or not.
851 BulkQh
= Uhc
->BulkQh
;
853 UhciLinkTdToQh (BulkQh
, TDs
);
854 Status
= UhciExecuteTransfer (Uhc
, BulkQh
, TDs
, TimeOut
, FALSE
, &QhResult
);
855 UhciUnlinkTdFromQh (BulkQh
, TDs
);
857 Uhc
->PciIo
->Flush (Uhc
->PciIo
);
859 *TransferResult
= QhResult
.Result
;
860 *DataToggle
= QhResult
.NextToggle
;
861 *DataLength
= QhResult
.Complete
;
863 UhciDestoryTds (Uhc
, TDs
);
864 Uhc
->PciIo
->Unmap (Uhc
->PciIo
, DataMap
);
867 gBS
->RestoreTPL (OldTpl
);
873 Submits an asynchronous interrupt transfer to an interrupt endpoint of a USB device.
875 This : A pointer to the EFI_USB_HC_PROTOCOL instance.
876 DeviceAddress : Target device address
877 EndPointAddress : Endpoint number with direction
878 IsSlowDevice : Whether the target device is slow device or full-speed device.
879 MaximumPacketLength : Maximum packet size of the target endpoint
880 IsNewTransfer : If TRUE, submit a new async interrupt transfer, otherwise
881 cancel an existed one
882 DataToggle : On input, the data toggle to use; On output, next data toggle
883 PollingInterval : Interrupt poll rate in milliseconds
884 DataLength : Length of data to receive
885 CallBackFunction : Function to call periodically
886 Context : User context
888 @return EFI_SUCCESS : Request is submitted or cancelled
889 @return EFI_INVALID_PARAMETER : Some parameters are invalid.
890 @return EFI_OUT_OF_RESOURCES : Failed due to a lack of resources.
891 @return EFI_DEVICE_ERROR : Failed to due to device error
897 UhciAsyncInterruptTransfer (
898 IN EFI_USB_HC_PROTOCOL
* This
,
899 IN UINT8 DeviceAddress
,
900 IN UINT8 EndPointAddress
,
901 IN BOOLEAN IsSlowDevice
,
902 IN UINT8 MaximumPacketLength
,
903 IN BOOLEAN IsNewTransfer
,
904 IN OUT UINT8
*DataToggle
,
905 IN UINTN PollingInterval
, OPTIONAL
906 IN UINTN DataLength
, OPTIONAL
907 IN EFI_ASYNC_USB_TRANSFER_CALLBACK CallBackFunction
, OPTIONAL
908 IN VOID
*Context OPTIONAL
921 Uhc
= UHC_FROM_USB_HC_PROTO (This
);
928 if ((EndPointAddress
& 0x80) == 0) {
929 return EFI_INVALID_PARAMETER
;
933 // Delete Async interrupt transfer request
935 if (!IsNewTransfer
) {
936 OldTpl
= gBS
->RaiseTPL (UHCI_TPL
);
937 Status
= UhciRemoveAsyncReq (Uhc
, DeviceAddress
, EndPointAddress
, DataToggle
);
939 gBS
->RestoreTPL (OldTpl
);
943 if (PollingInterval
< 1 || PollingInterval
> 255) {
944 return EFI_INVALID_PARAMETER
;
947 if (DataLength
== 0) {
948 return EFI_INVALID_PARAMETER
;
951 if ((*DataToggle
!= 1) && (*DataToggle
!= 0)) {
952 return EFI_INVALID_PARAMETER
;
956 // If has errors that cause host controller halt,
957 // then return EFI_DEVICE_ERROR directly.
959 UhciAckAllInterrupt (Uhc
);
961 if (!UhciIsHcWorking (Uhc
->PciIo
)) {
962 return EFI_DEVICE_ERROR
;
966 // Allocate and map source data buffer for bus master access.
968 DataPtr
= AllocatePool (DataLength
);
970 if (DataPtr
== NULL
) {
971 return EFI_OUT_OF_RESOURCES
;
974 OldTpl
= gBS
->RaiseTPL (UHCI_TPL
);
977 // Map the user data then create a queue head and
978 // list of TD for it.
980 Status
= UhciMapUserData (
990 if (EFI_ERROR (Status
)) {
994 Qh
= UhciCreateQh (Uhc
, PollingInterval
);
997 Status
= EFI_OUT_OF_RESOURCES
;
1001 IntTds
= UhciCreateBulkOrIntTds (
1009 MaximumPacketLength
,
1013 if (IntTds
== NULL
) {
1014 Status
= EFI_OUT_OF_RESOURCES
;
1018 UhciLinkTdToQh (Qh
, IntTds
);
1021 // Save QH-TD structures to async Interrupt transfer list,
1022 // for monitor interrupt transfer execution routine use.
1024 Status
= UhciCreateAsyncReq (
1039 if (EFI_ERROR (Status
)) {
1043 UhciLinkQhToFrameList (Uhc
->FrameBase
, Qh
);
1045 gBS
->RestoreTPL (OldTpl
);
1049 UsbHcFreeMem (Uhc
->MemPool
, Qh
, sizeof (UHCI_QH_SW
));
1052 Uhc
->PciIo
->Unmap (Uhc
->PciIo
, DataMap
);
1055 gBS
->FreePool (DataPtr
);
1056 Uhc
->PciIo
->Flush (Uhc
->PciIo
);
1058 gBS
->RestoreTPL (OldTpl
);
1064 Submits synchronous interrupt transfer to an interrupt endpoint of a USB device.
1066 This : A pointer to the EFI_USB_HC_PROTOCOL instance.
1067 DeviceAddress : Device address of the target USB device
1068 EndPointAddress : Endpoint number and direction
1069 IsSlowDevice : Whether the target device is of slow speed or full speed
1070 MaximumPacketLength : Maximum packet size of target endpoint
1071 Data : Data to transmit or receive
1072 DataLength : On input, data length to transmit or buffer size.
1073 On output, the number of bytes transferred.
1074 DataToggle : On input, data toggle to use; On output, next data toggle
1075 TimeOut : Maximum time, in microseconds, transfer is allowed to complete.
1076 TransferResult : Variable to receive transfer result
1078 @return EFI_SUCCESS : Transfer was completed successfully.
1079 @return EFI_OUT_OF_RESOURCES : Failed due to lack of resource.
1080 @return EFI_INVALID_PARAMETER : Some parameters are invalid.
1081 @return EFI_TIMEOUT : Failed due to timeout.
1082 @return EFI_DEVICE_ERROR : Failed due to host controller or device error
1088 UhciSyncInterruptTransfer (
1089 IN EFI_USB_HC_PROTOCOL
*This
,
1090 IN UINT8 DeviceAddress
,
1091 IN UINT8 EndPointAddress
,
1092 IN BOOLEAN IsSlowDevice
,
1093 IN UINT8 MaximumPacketLength
,
1095 IN OUT UINTN
*DataLength
,
1096 IN OUT UINT8
*DataToggle
,
1098 OUT UINT32
*TransferResult
1104 UHCI_QH_RESULT QhResult
;
1110 Uhc
= UHC_FROM_USB_HC_PROTO (This
);
1115 if ((DataLength
== NULL
) || (Data
== NULL
) || (TransferResult
== NULL
)) {
1116 return EFI_INVALID_PARAMETER
;
1119 if ((EndPointAddress
& 0x80) == 0) {
1120 return EFI_INVALID_PARAMETER
;
1123 if ((*DataToggle
!= 1) && (*DataToggle
!= 0)) {
1124 return EFI_INVALID_PARAMETER
;
1127 if ((*DataLength
== 0) || (MaximumPacketLength
> 64)) {
1128 return EFI_INVALID_PARAMETER
;
1131 if (IsSlowDevice
&& (MaximumPacketLength
> 8)) {
1132 return EFI_INVALID_PARAMETER
;
1135 *TransferResult
= EFI_USB_ERR_SYSTEM
;
1136 Status
= EFI_DEVICE_ERROR
;
1139 UhciAckAllInterrupt (Uhc
);
1141 if (!UhciIsHcWorking (Uhc
->PciIo
)) {
1145 OldTpl
= gBS
->RaiseTPL (UHCI_TPL
);
1148 // Map the source data buffer for bus master access.
1149 // Create Tds list, then link it to the UHC's interrupt list
1151 Status
= UhciMapUserData (
1161 if (EFI_ERROR (Status
)) {
1165 TDs
= UhciCreateBulkOrIntTds (
1173 MaximumPacketLength
,
1178 Uhc
->PciIo
->Unmap (Uhc
->PciIo
, DataMap
);
1180 Status
= EFI_OUT_OF_RESOURCES
;
1185 UhciLinkTdToQh (Uhc
->SyncIntQh
, TDs
);
1187 Status
= UhciExecuteTransfer (Uhc
, Uhc
->SyncIntQh
, TDs
, TimeOut
, IsSlowDevice
, &QhResult
);
1189 UhciUnlinkTdFromQh (Uhc
->SyncIntQh
, TDs
);
1190 Uhc
->PciIo
->Flush (Uhc
->PciIo
);
1192 *TransferResult
= QhResult
.Result
;
1193 *DataToggle
= QhResult
.NextToggle
;
1194 *DataLength
= QhResult
.Complete
;
1196 UhciDestoryTds (Uhc
, TDs
);
1197 Uhc
->PciIo
->Unmap (Uhc
->PciIo
, DataMap
);
1200 gBS
->RestoreTPL (OldTpl
);
1206 Submits isochronous transfer to a target USB device.
1208 This : A pointer to the EFI_USB_HC_PROTOCOL instance.
1209 DeviceAddress : Target device address
1210 EndPointAddress : End point address withdirection
1211 MaximumPacketLength : Maximum packet size of the endpoint
1212 Data : Data to transmit or receive
1213 DataLength : Bytes of the data
1214 TransferResult : Variable to receive the result
1216 @return EFI_UNSUPPORTED
1222 UhciIsochronousTransfer (
1223 IN EFI_USB_HC_PROTOCOL
*This
,
1224 IN UINT8 DeviceAddress
,
1225 IN UINT8 EndPointAddress
,
1226 IN UINT8 MaximumPacketLength
,
1228 IN UINTN DataLength
,
1229 OUT UINT32
*TransferResult
1232 return EFI_UNSUPPORTED
;
1237 Submits Async isochronous transfer to a target USB device.
1239 This : A pointer to the EFI_USB_HC_PROTOCOL instance.
1240 DeviceAddress : Target device address
1241 EndPointAddress : End point address withdirection
1242 MaximumPacketLength : Maximum packet size of the endpoint
1243 Data : Data to transmit or receive
1244 IsochronousCallBack : Function to call when the transfer completes
1245 Context : User context
1247 @return EFI_UNSUPPORTED
1253 UhciAsyncIsochronousTransfer (
1254 IN EFI_USB_HC_PROTOCOL
* This
,
1255 IN UINT8 DeviceAddress
,
1256 IN UINT8 EndPointAddress
,
1257 IN UINT8 MaximumPacketLength
,
1259 IN UINTN DataLength
,
1260 IN EFI_ASYNC_USB_TRANSFER_CALLBACK IsochronousCallBack
,
1261 IN VOID
*Context OPTIONAL
1264 return EFI_UNSUPPORTED
;
1270 Provides software reset for the USB host controller according to UEFI 2.0 spec.
1272 @param This A pointer to the EFI_USB2_HC_PROTOCOL instance.
1273 @param Attributes A bit mask of the reset operation to perform. See
1274 below for a list of the supported bit mask values.
1276 @return EFI_SUCCESS : The reset operation succeeded.
1277 @return EFI_INVALID_PARAMETER : Attributes is not valid.
1278 @return EFI_UNSUPPORTED : This type of reset is not currently supported
1279 @return EFI_DEVICE_ERROR : Other errors
1286 IN EFI_USB2_HC_PROTOCOL
*This
,
1287 IN UINT16 Attributes
1290 USB_HC_DEV
*UhciDev
;
1292 UhciDev
= UHC_FROM_USB2_HC_PROTO (This
);
1294 if ((Attributes
== EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG
) ||
1295 (Attributes
== EFI_USB_HC_RESET_HOST_WITH_DEBUG
)) {
1296 return EFI_UNSUPPORTED
;
1299 return UhciReset (&UhciDev
->UsbHc
, Attributes
);
1304 Retrieves current state of the USB host controller according to UEFI 2.0 spec.
1306 @param This A pointer to the EFI_USB_HC_PROTOCOL instance.
1307 @param State Variable to receive current device state
1309 @return EFI_SUCCESS : The state is returned
1310 @return EFI_INVALID_PARAMETER : State is not valid.
1311 @return EFI_DEVICE_ERROR : Other errors2006
1318 IN CONST EFI_USB2_HC_PROTOCOL
*This
,
1319 OUT EFI_USB_HC_STATE
*State
1324 Uhc
= UHC_FROM_USB2_HC_PROTO (This
);
1325 return UhciGetState (&Uhc
->UsbHc
, State
);
1330 Sets the USB host controller to a specific state according to UEFI 2.0 spec.
1332 @param This A pointer to the EFI_USB_HC_PROTOCOL instance.
1333 @param State Indicates the state of the host controller that will
1336 @return EFI_SUCCESS : Host controller was successfully placed in the state
1337 @return EFI_INVALID_PARAMETER : State is invalid.
1338 @return EFI_DEVICE_ERROR : Failed to set the state
1345 IN EFI_USB2_HC_PROTOCOL
*This
,
1346 IN EFI_USB_HC_STATE State
1351 Uhc
= UHC_FROM_USB2_HC_PROTO (This
);
1352 return UhciSetState (&Uhc
->UsbHc
, State
);
1357 Retrieves capabilities of USB host controller according to UEFI 2.0 spec.
1359 @param This A pointer to the EFI_USB2_HC_PROTOCOL instance
1360 @param MaxSpeed A pointer to the max speed USB host controller
1362 @param PortNumber A pointer to the number of root hub ports.
1363 @param Is64BitCapable A pointer to an integer to show whether USB host
1364 controller supports 64-bit memory addressing.
1366 @return EFI_SUCCESS : capabilities were retrieved successfully.
1367 @return EFI_INVALID_PARAMETER : MaxSpeed or PortNumber or Is64BitCapable is NULL.
1368 @return EFI_DEVICE_ERROR : An error was encountered
1374 Uhci2GetCapability (
1375 IN EFI_USB2_HC_PROTOCOL
*This
,
1376 OUT UINT8
*MaxSpeed
,
1377 OUT UINT8
*PortNumber
,
1378 OUT UINT8
*Is64BitCapable
1383 Uhc
= UHC_FROM_USB2_HC_PROTO (This
);
1385 if ((NULL
== MaxSpeed
) || (NULL
== PortNumber
) || (NULL
== Is64BitCapable
)) {
1386 return EFI_INVALID_PARAMETER
;
1389 *MaxSpeed
= EFI_USB_SPEED_FULL
;
1390 *Is64BitCapable
= (UINT8
) FALSE
;
1392 return UhciGetRootHubPortNumber (&Uhc
->UsbHc
, PortNumber
);
1397 Retrieves the current status of a USB root hub port according to UEFI 2.0 spec.
1399 @param This A pointer to the EFI_USB2_HC_PROTOCOL.
1400 @param PortNumber The port to get status
1401 @param PortStatus A pointer to the current port status bits and port
1404 @return EFI_SUCCESS : status of the USB root hub port was returned in PortStatus.
1405 @return EFI_INVALID_PARAMETER : PortNumber is invalid.
1406 @return EFI_DEVICE_ERROR : Can't read register
1412 Uhci2GetRootHubPortStatus (
1413 IN CONST EFI_USB2_HC_PROTOCOL
*This
,
1414 IN CONST UINT8 PortNumber
,
1415 OUT EFI_USB_PORT_STATUS
*PortStatus
1420 Uhc
= UHC_FROM_USB2_HC_PROTO (This
);
1422 return UhciGetRootHubPortStatus (&Uhc
->UsbHc
, PortNumber
, PortStatus
);
1427 Sets a feature for the specified root hub port according to UEFI 2.0 spec.
1429 @param This A pointer to the EFI_USB2_HC_PROTOCOL.
1430 @param PortNumber Specifies the root hub port whose feature is
1431 requested to be set.
1432 @param PortFeature Indicates the feature selector associated with the
1433 feature set request.
1435 @return EFI_SUCCESS : PortFeature was set for the root port
1436 @return EFI_INVALID_PARAMETER : PortNumber is invalid or PortFeature is invalid.
1437 @return EFI_DEVICE_ERROR : Can't read register
1443 Uhci2SetRootHubPortFeature (
1444 IN EFI_USB2_HC_PROTOCOL
*This
,
1445 IN UINT8 PortNumber
,
1446 IN EFI_USB_PORT_FEATURE PortFeature
1451 Uhc
= UHC_FROM_USB2_HC_PROTO (This
);
1453 return UhciSetRootHubPortFeature (&Uhc
->UsbHc
, PortNumber
, PortFeature
);
1458 Clears a feature for the specified root hub port according to Uefi 2.0 spec.
1460 @param This A pointer to the EFI_USB2_HC_PROTOCOL instance.
1461 @param PortNumber Specifies the root hub port whose feature is
1462 requested to be cleared.
1463 @param PortFeature Indicates the feature selector associated with the
1464 feature clear request.
1466 @return EFI_SUCCESS : PortFeature was cleared for the USB root hub port
1467 @return EFI_INVALID_PARAMETER : PortNumber is invalid or PortFeature is invalid.
1468 @return EFI_DEVICE_ERROR : Can't read register
1474 Uhci2ClearRootHubPortFeature (
1475 IN EFI_USB2_HC_PROTOCOL
*This
,
1476 IN UINT8 PortNumber
,
1477 IN EFI_USB_PORT_FEATURE PortFeature
1482 Uhc
= UHC_FROM_USB2_HC_PROTO (This
);
1484 return UhciClearRootHubPortFeature (&Uhc
->UsbHc
, PortNumber
, PortFeature
);
1489 Submits control transfer to a target USB device accroding to UEFI 2.0 spec..
1491 This : A pointer to the EFI_USB2_HC_PROTOCOL instance.
1492 DeviceAddress : Target device address
1493 DeviceSpeed : Device speed
1494 MaximumPacketLength : Maximum packet size of the target endpoint
1495 Request : USB device request to send
1496 TransferDirection : Data direction of the Data stage in control transfer
1497 Data : Data to transmit/receive in data stage
1498 DataLength : Length of the data
1499 TimeOut : Maximum time, in microseconds, for transfer to complete.
1500 TransferResult : Variable to receive the transfer result
1502 @return EFI_SUCCESS : The control transfer was completed successfully.
1503 @return EFI_OUT_OF_RESOURCES : Failed due to lack of resource.
1504 @return EFI_INVALID_PARAMETER : Some parameters are invalid.
1505 @return EFI_TIMEOUT : Failed due to timeout.
1506 @return EFI_DEVICE_ERROR : Failed due to host controller or device error.
1512 Uhci2ControlTransfer (
1513 IN EFI_USB2_HC_PROTOCOL
*This
,
1514 IN UINT8 DeviceAddress
,
1515 IN UINT8 DeviceSpeed
,
1516 IN UINTN MaximumPacketLength
,
1517 IN EFI_USB_DEVICE_REQUEST
*Request
,
1518 IN EFI_USB_DATA_DIRECTION TransferDirection
,
1520 IN OUT UINTN
*DataLength
,
1522 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
1523 OUT UINT32
*TransferResult
1529 Uhc
= UHC_FROM_USB2_HC_PROTO (This
);
1530 IsSlow
= (BOOLEAN
) ((EFI_USB_SPEED_LOW
== DeviceSpeed
) ? TRUE
: FALSE
);
1532 return UhciControlTransfer (
1536 (UINT8
) MaximumPacketLength
,
1548 Submits bulk transfer to a bulk endpoint of a USB device
1550 This : A pointer to the EFI_USB2_HC_PROTOCOL instance.
1551 DeviceAddress : Target device address
1552 EndPointAddress : Endpoint number and direction
1553 DeviceSpeed : Device speed
1554 MaximumPacketLength : Maximum packet size of the target endpoint
1555 DataBuffersNumber : Number of data buffers prepared for the transfer.
1556 Data : Array of pointers to the buffers of data
1557 DataLength : On input, size of the data buffer, On output,
1558 actually transferred data size.
1559 DataToggle : On input, data toggle to use; On output, next data toggle
1560 Translator : A pointr to the transaction translator data.
1561 TimeOut : Maximum time out, in microseconds
1562 TransferResult : Variable to receive transfer result
1564 @return EFI_SUCCESS : The bulk transfer was completed successfully.
1565 @return EFI_OUT_OF_RESOURCES : Failed due to lack of resource.
1566 @return EFI_INVALID_PARAMETER : Some parameters are invalid.
1567 @return EFI_TIMEOUT : Failed due to timeout.
1568 @return EFI_DEVICE_ERROR : Failed due to host controller or device error.
1575 IN EFI_USB2_HC_PROTOCOL
*This
,
1576 IN UINT8 DeviceAddress
,
1577 IN UINT8 EndPointAddress
,
1578 IN UINT8 DeviceSpeed
,
1579 IN UINTN MaximumPacketLength
,
1580 IN UINT8 DataBuffersNumber
,
1581 IN OUT VOID
*Data
[EFI_USB_MAX_BULK_BUFFER_NUM
],
1582 IN OUT UINTN
*DataLength
,
1583 IN OUT UINT8
*DataToggle
,
1585 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
1586 OUT UINT32
*TransferResult
1591 Uhc
= UHC_FROM_USB2_HC_PROTO (This
);
1593 if (Data
== NULL
|| DeviceSpeed
== EFI_USB_SPEED_LOW
) {
1594 return EFI_INVALID_PARAMETER
;
1598 // For full-speed bulk transfers only the data pointed by Data[0] shall be used
1600 return UhciBulkTransfer (
1604 (UINT8
) MaximumPacketLength
,
1615 Submits an asynchronous interrupt transfer to an
1616 interrupt endpoint of a USB device according to UEFI 2.0 spec.
1618 This : A pointer to the EFI_USB2_HC_PROTOCOL instance.
1619 DeviceAddress : Target device address
1620 EndPointAddress : Endpoint number and direction
1621 DeviceSpeed : Device speed
1622 MaximumPacketLength : Maximum packet size of the target endpoint
1623 IsNewTransfer : If TRUE, submit a new transfer, if FALSE cancel old transfer
1624 DataToggle : On input, data toggle to use; On output, next data toggle
1625 PollingInterval : Interrupt poll rate in milliseconds
1626 DataLength : On input, size of the data buffer, On output,
1627 actually transferred data size.
1628 Translator : A pointr to the transaction translator data.
1629 CallBackFunction : Function to call periodically
1630 Context : User context
1632 @return EFI_SUCCESS : Transfer was submitted
1633 @return EFI_INVALID_PARAMETER : Some parameters are invalid.
1634 @return EFI_OUT_OF_RESOURCES : Failed due to a lack of resources.
1635 @return EFI_DEVICE_ERROR : Can't read register
1641 Uhci2AsyncInterruptTransfer (
1642 IN EFI_USB2_HC_PROTOCOL
*This
,
1643 IN UINT8 DeviceAddress
,
1644 IN UINT8 EndPointAddress
,
1645 IN UINT8 DeviceSpeed
,
1646 IN UINTN MaximumPacketLength
,
1647 IN BOOLEAN IsNewTransfer
,
1648 IN OUT UINT8
*DataToggle
,
1649 IN UINTN PollingInterval
,
1650 IN UINTN DataLength
,
1651 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
1652 IN EFI_ASYNC_USB_TRANSFER_CALLBACK CallBackFunction
,
1659 Uhc
= UHC_FROM_USB2_HC_PROTO (This
);
1660 IsSlow
= (BOOLEAN
) ((EFI_USB_SPEED_LOW
== DeviceSpeed
) ? TRUE
: FALSE
);
1662 return UhciAsyncInterruptTransfer (
1667 (UINT8
) MaximumPacketLength
,
1679 Submits synchronous interrupt transfer to an interrupt endpoint
1680 of a USB device according to UEFI 2.0 spec.
1682 This : A pointer to the EFI_USB2_HC_PROTOCOL instance.
1683 DeviceAddress : Target device address
1684 EndPointAddress : Endpoint number and direction
1685 DeviceSpeed : Device speed
1686 MaximumPacketLength : Maximum packet size of the target endpoint
1687 DataBuffersNumber : Number of data buffers prepared for the transfer.
1688 Data : Array of pointers to the buffers of data
1689 DataLength : On input, size of the data buffer, On output,
1690 actually transferred data size.
1691 DataToggle : On input, data toggle to use; On output, next data toggle
1692 TimeOut : Maximum time out, in microseconds
1693 Translator : A pointr to the transaction translator data.
1694 TransferResult : Variable to receive transfer result
1696 @return EFI_SUCCESS : The transfer was completed successfully.
1697 @return EFI_OUT_OF_RESOURCES : Failed due to lack of resource.
1698 @return EFI_INVALID_PARAMETER : Some parameters are invalid.
1699 @return EFI_TIMEOUT : Failed due to timeout.
1700 @return EFI_DEVICE_ERROR : Failed due to host controller or device error.
1706 Uhci2SyncInterruptTransfer (
1707 IN EFI_USB2_HC_PROTOCOL
*This
,
1708 IN UINT8 DeviceAddress
,
1709 IN UINT8 EndPointAddress
,
1710 IN UINT8 DeviceSpeed
,
1711 IN UINTN MaximumPacketLength
,
1713 IN OUT UINTN
*DataLength
,
1714 IN OUT UINT8
*DataToggle
,
1716 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
1717 OUT UINT32
*TransferResult
1723 if (DeviceSpeed
== EFI_USB_SPEED_HIGH
) {
1724 return EFI_INVALID_PARAMETER
;
1727 Uhc
= UHC_FROM_USB2_HC_PROTO (This
);
1728 IsSlow
= (BOOLEAN
) ((EFI_USB_SPEED_LOW
== DeviceSpeed
) ? TRUE
: FALSE
);
1730 return UhciSyncInterruptTransfer (
1735 (UINT8
) MaximumPacketLength
,
1746 Submits isochronous transfer to a target USB device according to UEFI 2.0 spec.
1748 This : A pointer to the EFI_USB2_HC_PROTOCOL instance.
1749 DeviceAddress : Target device address
1750 EndPointAddress : Endpoint number and direction
1751 DeviceSpeed : Device speed
1752 MaximumPacketLength : Maximum packet size of the target endpoint
1753 DataBuffersNumber : Number of data buffers prepared for the transfer.
1754 Data : Array of pointers to the buffers of data
1755 DataLength : On input, size of the data buffer, On output,
1756 actually transferred data size.
1757 Translator : A pointr to the transaction translator data.
1758 TransferResult : Variable to receive transfer result
1760 @return EFI_UNSUPPORTED
1766 Uhci2IsochronousTransfer (
1767 IN EFI_USB2_HC_PROTOCOL
*This
,
1768 IN UINT8 DeviceAddress
,
1769 IN UINT8 EndPointAddress
,
1770 IN UINT8 DeviceSpeed
,
1771 IN UINTN MaximumPacketLength
,
1772 IN UINT8 DataBuffersNumber
,
1773 IN OUT VOID
*Data
[EFI_USB_MAX_ISO_BUFFER_NUM
],
1774 IN UINTN DataLength
,
1775 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
1776 OUT UINT32
*TransferResult
1779 return EFI_UNSUPPORTED
;
1784 Submits Async isochronous transfer to a target USB device according to UEFI 2.0 spec.
1786 This : A pointer to the EFI_USB2_HC_PROTOCOL instance.
1787 DeviceAddress : Target device address
1788 EndPointAddress : Endpoint number and direction
1789 DeviceSpeed : Device speed
1790 MaximumPacketLength : Maximum packet size of the target endpoint
1791 DataBuffersNumber : Number of data buffers prepared for the transfer.
1792 Data : Array of pointers to the buffers of data
1793 Translator : A pointr to the transaction translator data.
1794 IsochronousCallBack : Function to call when the transfer complete
1795 Context : Pass to the call back function as parameter
1797 @return EFI_UNSUPPORTED
1803 Uhci2AsyncIsochronousTransfer (
1804 IN EFI_USB2_HC_PROTOCOL
*This
,
1805 IN UINT8 DeviceAddress
,
1806 IN UINT8 EndPointAddress
,
1807 IN UINT8 DeviceSpeed
,
1808 IN UINTN MaximumPacketLength
,
1809 IN UINT8 DataBuffersNumber
,
1810 IN OUT VOID
*Data
[EFI_USB_MAX_ISO_BUFFER_NUM
],
1811 IN UINTN DataLength
,
1812 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
1813 IN EFI_ASYNC_USB_TRANSFER_CALLBACK IsochronousCallBack
,
1817 return EFI_UNSUPPORTED
;
1822 UhciDriverEntryPoint (
1823 IN EFI_HANDLE ImageHandle
,
1824 IN EFI_SYSTEM_TABLE
*SystemTable
1828 Routine Description:
1830 Entry point for EFI drivers.
1834 ImageHandle - EFI_HANDLE
1835 SystemTable - EFI_SYSTEM_TABLE
1839 EFI_SUCCESS : Driver is successfully loaded
1844 return EfiLibInstallDriverBindingComponentName2 (
1847 &gUhciDriverBinding
,
1849 &gUhciComponentName
,
1850 &gUhciComponentName2
1856 Test to see if this driver supports ControllerHandle. Any
1857 ControllerHandle that has UsbHcProtocol installed will be supported.
1859 @param This Protocol instance pointer.
1860 @param Controller Handle of device to test
1861 @param RemainingDevicePath Not used
1863 @return EFI_SUCCESS : This driver supports this device.
1864 @return EFI_UNSUPPORTED : This driver does not support this device.
1869 UhciDriverBindingSupported (
1870 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1871 IN EFI_HANDLE Controller
,
1872 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
1875 EFI_STATUS OpenStatus
;
1877 EFI_PCI_IO_PROTOCOL
*PciIo
;
1878 USB_CLASSC UsbClassCReg
;
1881 // Test whether there is PCI IO Protocol attached on the controller handle.
1883 OpenStatus
= gBS
->OpenProtocol (
1885 &gEfiPciIoProtocolGuid
,
1887 This
->DriverBindingHandle
,
1889 EFI_OPEN_PROTOCOL_BY_DRIVER
1892 if (EFI_ERROR (OpenStatus
)) {
1896 Status
= PciIo
->Pci
.Read (
1900 sizeof (USB_CLASSC
) / sizeof (UINT8
),
1904 if (EFI_ERROR (Status
)) {
1905 Status
= EFI_UNSUPPORTED
;
1910 // Test whether the controller belongs to UHCI type
1912 if ((UsbClassCReg
.BaseCode
!= PCI_CLASS_SERIAL
) ||
1913 (UsbClassCReg
.SubClassCode
!= PCI_CLASS_SERIAL_USB
) ||
1914 (UsbClassCReg
.PI
!= PCI_CLASSC_PI_UHCI
)
1917 Status
= EFI_UNSUPPORTED
;
1921 gBS
->CloseProtocol (
1923 &gEfiPciIoProtocolGuid
,
1924 This
->DriverBindingHandle
,
1934 Allocate and initialize the empty UHCI device
1936 @param PciIo The PCIIO to use
1938 @return Allocated UHCI device
1944 IN EFI_PCI_IO_PROTOCOL
*PciIo
,
1945 IN UINT64 OriginalPciAttributes
1951 Uhc
= AllocateZeroPool (sizeof (USB_HC_DEV
));
1958 // This driver supports both USB_HC_PROTOCOL and USB2_HC_PROTOCOL.
1959 // USB_HC_PROTOCOL is for EFI 1.1 backward compability.
1961 Uhc
->Signature
= USB_HC_DEV_SIGNATURE
;
1962 Uhc
->UsbHc
.Reset
= UhciReset
;
1963 Uhc
->UsbHc
.GetState
= UhciGetState
;
1964 Uhc
->UsbHc
.SetState
= UhciSetState
;
1965 Uhc
->UsbHc
.ControlTransfer
= UhciControlTransfer
;
1966 Uhc
->UsbHc
.BulkTransfer
= UhciBulkTransfer
;
1967 Uhc
->UsbHc
.AsyncInterruptTransfer
= UhciAsyncInterruptTransfer
;
1968 Uhc
->UsbHc
.SyncInterruptTransfer
= UhciSyncInterruptTransfer
;
1969 Uhc
->UsbHc
.IsochronousTransfer
= UhciIsochronousTransfer
;
1970 Uhc
->UsbHc
.AsyncIsochronousTransfer
= UhciAsyncIsochronousTransfer
;
1971 Uhc
->UsbHc
.GetRootHubPortNumber
= UhciGetRootHubPortNumber
;
1972 Uhc
->UsbHc
.GetRootHubPortStatus
= UhciGetRootHubPortStatus
;
1973 Uhc
->UsbHc
.SetRootHubPortFeature
= UhciSetRootHubPortFeature
;
1974 Uhc
->UsbHc
.ClearRootHubPortFeature
= UhciClearRootHubPortFeature
;
1975 Uhc
->UsbHc
.MajorRevision
= 0x1;
1976 Uhc
->UsbHc
.MinorRevision
= 0x1;
1978 Uhc
->Usb2Hc
.GetCapability
= Uhci2GetCapability
;
1979 Uhc
->Usb2Hc
.Reset
= Uhci2Reset
;
1980 Uhc
->Usb2Hc
.GetState
= Uhci2GetState
;
1981 Uhc
->Usb2Hc
.SetState
= Uhci2SetState
;
1982 Uhc
->Usb2Hc
.ControlTransfer
= Uhci2ControlTransfer
;
1983 Uhc
->Usb2Hc
.BulkTransfer
= Uhci2BulkTransfer
;
1984 Uhc
->Usb2Hc
.AsyncInterruptTransfer
= Uhci2AsyncInterruptTransfer
;
1985 Uhc
->Usb2Hc
.SyncInterruptTransfer
= Uhci2SyncInterruptTransfer
;
1986 Uhc
->Usb2Hc
.IsochronousTransfer
= Uhci2IsochronousTransfer
;
1987 Uhc
->Usb2Hc
.AsyncIsochronousTransfer
= Uhci2AsyncIsochronousTransfer
;
1988 Uhc
->Usb2Hc
.GetRootHubPortStatus
= Uhci2GetRootHubPortStatus
;
1989 Uhc
->Usb2Hc
.SetRootHubPortFeature
= Uhci2SetRootHubPortFeature
;
1990 Uhc
->Usb2Hc
.ClearRootHubPortFeature
= Uhci2ClearRootHubPortFeature
;
1991 Uhc
->Usb2Hc
.MajorRevision
= 0x1;
1992 Uhc
->Usb2Hc
.MinorRevision
= 0x1;
1995 Uhc
->OriginalPciAttributes
= OriginalPciAttributes
;
1996 Uhc
->MemPool
= UsbHcInitMemPool (PciIo
, TRUE
, 0);
1998 if (Uhc
->MemPool
== NULL
) {
1999 Status
= EFI_OUT_OF_RESOURCES
;
2003 InitializeListHead (&Uhc
->AsyncIntList
);
2005 Status
= gBS
->CreateEvent (
2006 EVT_TIMER
| EVT_NOTIFY_SIGNAL
,
2008 UhciMonitorAsyncReqList
,
2010 &Uhc
->AsyncIntMonitor
2013 if (EFI_ERROR (Status
)) {
2014 UsbHcFreeMemPool (Uhc
->MemPool
);
2021 gBS
->FreePool (Uhc
);
2027 Free the UHCI device and release its associated resources
2029 @param Uhc The UHCI device to release
2040 if (Uhc
->AsyncIntMonitor
!= NULL
) {
2041 gBS
->CloseEvent (Uhc
->AsyncIntMonitor
);
2044 if (Uhc
->MemPool
!= NULL
) {
2045 UsbHcFreeMemPool (Uhc
->MemPool
);
2048 if (Uhc
->CtrlNameTable
) {
2049 FreeUnicodeStringTable (Uhc
->CtrlNameTable
);
2052 gBS
->FreePool (Uhc
);
2057 Uninstall all Uhci Interface
2059 @param Controller Controller handle
2060 @param This Protocol instance pointer.
2068 IN EFI_HANDLE Controller
,
2069 IN EFI_USB_HC_PROTOCOL
*This
2075 // Uninstall the USB_HC and USB_HC2 protocol, then disable the controller
2077 Uhc
= UHC_FROM_USB_HC_PROTO (This
);
2078 UhciStopHc (Uhc
, UHC_GENERIC_TIMEOUT
);
2080 gBS
->UninstallProtocolInterface (
2082 &gEfiUsbHcProtocolGuid
,
2086 gBS
->UninstallProtocolInterface (
2088 &gEfiUsb2HcProtocolGuid
,
2092 UhciFreeAllAsyncReq (Uhc
);
2093 UhciDestoryFrameList (Uhc
);
2096 // Restore original PCI attributes
2098 Uhc
->PciIo
->Attributes (
2100 EfiPciIoAttributeOperationSet
,
2101 Uhc
->OriginalPciAttributes
,
2110 Starting the Usb UHCI Driver
2112 @param This Protocol instance pointer.
2113 @param Controller Handle of device to test
2114 @param RemainingDevicePath Not used
2116 @retval EFI_SUCCESS This driver supports this device.
2117 @retval EFI_UNSUPPORTED This driver does not support this device.
2118 @retval EFI_DEVICE_ERROR This driver cannot be started due to device Error
2119 EFI_OUT_OF_RESOURCES- Failed due to resource
2125 UhciDriverBindingStart (
2126 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
2127 IN EFI_HANDLE Controller
,
2128 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
2132 EFI_PCI_IO_PROTOCOL
*PciIo
;
2135 UINT64 OriginalPciAttributes
;
2138 // Open PCIIO, then enable the EHC device and turn off emulation
2141 Status
= gBS
->OpenProtocol (
2143 &gEfiPciIoProtocolGuid
,
2145 This
->DriverBindingHandle
,
2147 EFI_OPEN_PROTOCOL_BY_DRIVER
2150 if (EFI_ERROR (Status
)) {
2155 // Save original PCI attributes
2157 Status
= PciIo
->Attributes (
2159 EfiPciIoAttributeOperationGet
,
2161 &OriginalPciAttributes
2164 if (EFI_ERROR (Status
)) {
2168 UhciTurnOffUsbEmulation (PciIo
);
2170 Status
= PciIo
->Attributes (
2172 EfiPciIoAttributeOperationSupported
,
2176 if (!EFI_ERROR (Status
)) {
2177 Supports
&= EFI_PCI_DEVICE_ENABLE
;
2178 Status
= PciIo
->Attributes (
2180 EfiPciIoAttributeOperationEnable
,
2186 if (EFI_ERROR (Status
)) {
2190 Uhc
= UhciAllocateDev (PciIo
, OriginalPciAttributes
);
2193 Status
= EFI_OUT_OF_RESOURCES
;
2198 // Allocate and Init Host Controller's Frame List Entry
2200 Status
= UhciInitFrameList (Uhc
);
2202 if (EFI_ERROR (Status
)) {
2203 Status
= EFI_OUT_OF_RESOURCES
;
2207 Status
= gBS
->SetTimer (
2208 Uhc
->AsyncIntMonitor
,
2210 UHC_ASYNC_POLL_INTERVAL
2213 if (EFI_ERROR (Status
)) {
2218 // Install both USB_HC_PROTOCOL and USB2_HC_PROTOCOL
2220 Status
= gBS
->InstallMultipleProtocolInterfaces (
2222 &gEfiUsbHcProtocolGuid
,
2224 &gEfiUsb2HcProtocolGuid
,
2229 if (EFI_ERROR (Status
)) {
2234 // Install the component name protocol
2236 Uhc
->CtrlNameTable
= NULL
;
2240 gUhciComponentName
.SupportedLanguages
,
2241 &Uhc
->CtrlNameTable
,
2242 L
"Usb Universal Host Controller",
2247 gUhciComponentName2
.SupportedLanguages
,
2248 &Uhc
->CtrlNameTable
,
2249 L
"Usb Universal Host Controller",
2255 // Start the UHCI hardware, also set its reclamation point to 64 bytes
2257 UhciWriteReg (Uhc
->PciIo
, USBCMD_OFFSET
, USBCMD_RS
| USBCMD_MAXP
);
2266 // Restore original PCI attributes
2270 EfiPciIoAttributeOperationSet
,
2271 OriginalPciAttributes
,
2275 gBS
->CloseProtocol (
2277 &gEfiPciIoProtocolGuid
,
2278 This
->DriverBindingHandle
,
2287 Stop this driver on ControllerHandle. Support stoping any child handles
2288 created by this driver.
2290 @param This Protocol instance pointer.
2291 @param Controller Handle of device to stop driver on
2292 @param NumberOfChildren Number of Children in the ChildHandleBuffer
2293 @param ChildHandleBuffer List of handles for the children we need to stop.
2301 UhciDriverBindingStop (
2302 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
2303 IN EFI_HANDLE Controller
,
2304 IN UINTN NumberOfChildren
,
2305 IN EFI_HANDLE
*ChildHandleBuffer
2308 EFI_USB_HC_PROTOCOL
*UsbHc
;
2309 EFI_USB2_HC_PROTOCOL
*Usb2Hc
;
2312 Status
= gBS
->OpenProtocol (
2314 &gEfiUsbHcProtocolGuid
,
2316 This
->DriverBindingHandle
,
2318 EFI_OPEN_PROTOCOL_GET_PROTOCOL
2321 // Test whether the Controller handler passed in is a valid
2322 // Usb controller handle that should be supported, if not,
2323 // return the error status directly
2325 if (EFI_ERROR (Status
)) {
2329 Status
= gBS
->OpenProtocol (
2331 &gEfiUsb2HcProtocolGuid
,
2333 This
->DriverBindingHandle
,
2335 EFI_OPEN_PROTOCOL_GET_PROTOCOL
2339 // Test whether the Controller handler passed in is a valid
2340 // Usb controller handle that should be supported, if not,
2341 // return the error status directly
2343 if (EFI_ERROR (Status
)) {
2347 UhciCleanDevUp (Controller
, UsbHc
);
2349 gBS
->CloseProtocol (
2351 &gEfiPciIoProtocolGuid
,
2352 This
->DriverBindingHandle
,
2359 EFI_DRIVER_BINDING_PROTOCOL gUhciDriverBinding
= {
2360 UhciDriverBindingSupported
,
2361 UhciDriverBindingStart
,
2362 UhciDriverBindingStop
,