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
, STALL_1_SECOND
);
60 UhciSetRegBit (Uhc
->PciIo
, USBCMD_OFFSET
, USBCMD_GRESET
);
63 // Wait 50ms for root port to let reset complete
64 // See UHCI spec page122 Reset signaling
66 gBS
->Stall (ROOT_PORT_REST_TIME
);
69 // Clear the Global Reset bit to zero.
71 UhciClearRegBit (Uhc
->PciIo
, USBCMD_OFFSET
, USBCMD_GRESET
);
74 // UHCI spec page120 reset recovery time
76 gBS
->Stall (PORT_RESET_RECOVERY_TIME
);
79 case EFI_USB_HC_RESET_HOST_CONTROLLER
:
81 // Stop schedule and set Host Controller Reset bit to 1
83 UhciStopHc (Uhc
, STALL_1_SECOND
);
84 UhciSetRegBit (Uhc
->PciIo
, USBCMD_OFFSET
, USBCMD_HCRESET
);
87 // this bit will be reset by Host Controller when reset is completed.
88 // wait 10ms to let reset complete
90 gBS
->Stall (PORT_RESET_RECOVERY_TIME
);
94 goto ON_INVAILD_PARAMETER
;
98 // Delete all old transactions on the USB bus, then
99 // reinitialize the frame list
101 UhciFreeAllAsyncReq (Uhc
);
102 UhciDestoryFrameList (Uhc
);
103 UhciInitFrameList (Uhc
);
105 gBS
->RestoreTPL (OldTpl
);
109 ON_INVAILD_PARAMETER
:
111 gBS
->RestoreTPL (OldTpl
);
113 return EFI_INVALID_PARAMETER
;
118 Retrieves current state of the USB host controller.
120 This : A pointer to the EFI_USB_HC_PROTOCOL instance.
121 State : A pointer to the EFI_USB_HC_STATE data structure that
122 indicates current state of the USB host controller.
124 @return EFI_SUCCESS : State was returned
125 @return EFI_INVALID_PARAMETER : State is NULL.
126 @return EFI_DEVICE_ERROR : An error was encountered
133 IN EFI_USB_HC_PROTOCOL
*This
,
134 OUT EFI_USB_HC_STATE
*State
142 return EFI_INVALID_PARAMETER
;
145 Uhc
= UHC_FROM_USB_HC_PROTO (This
);
147 UsbCmd
= UhciReadReg (Uhc
->PciIo
, USBCMD_OFFSET
);
148 UsbSts
= UhciReadReg (Uhc
->PciIo
, USBSTS_OFFSET
);
150 if (UsbCmd
& USBCMD_EGSM
) {
151 *State
= EfiUsbHcStateSuspend
;
153 } else if ((UsbSts
& USBSTS_HCH
) != 0) {
154 *State
= EfiUsbHcStateHalt
;
157 *State
= EfiUsbHcStateOperational
;
165 Sets the USB host controller to a specific state.
167 This : A pointer to the EFI_USB_HC_PROTOCOL instance.
168 State : Indicates the state of the host controller that will be set.
170 @return EFI_SUCCESS : The USB host controller was successfully set
171 @return EFI_INVALID_PARAMETER : State is invalid.
172 @return EFI_DEVICE_ERROR : Failed to set the state specified
179 IN EFI_USB_HC_PROTOCOL
*This
,
180 IN EFI_USB_HC_STATE State
183 EFI_USB_HC_STATE CurState
;
189 Uhc
= UHC_FROM_USB_HC_PROTO (This
);
190 Status
= UhciGetState (This
, &CurState
);
192 if (EFI_ERROR (Status
)) {
193 return EFI_DEVICE_ERROR
;
196 if (CurState
== State
) {
200 Status
= EFI_SUCCESS
;
201 OldTpl
= gBS
->RaiseTPL (UHCI_TPL
);
204 case EfiUsbHcStateHalt
:
205 Status
= UhciStopHc (Uhc
, STALL_1_SECOND
);
208 case EfiUsbHcStateOperational
:
209 UsbCmd
= UhciReadReg (Uhc
->PciIo
, USBCMD_OFFSET
);
211 if (CurState
== EfiUsbHcStateHalt
) {
213 // Set Run/Stop bit to 1, also set the bandwidht reclamation
216 UsbCmd
|= USBCMD_RS
| USBCMD_MAXP
;
217 UhciWriteReg (Uhc
->PciIo
, USBCMD_OFFSET
, UsbCmd
);
219 } else if (CurState
== EfiUsbHcStateSuspend
) {
221 // If FGR(Force Global Resume) bit is 0, set it
223 if ((UsbCmd
& USBCMD_FGR
) == 0) {
224 UsbCmd
|= USBCMD_FGR
;
225 UhciWriteReg (Uhc
->PciIo
, USBCMD_OFFSET
, UsbCmd
);
229 // wait 20ms to let resume complete (20ms is specified by UHCI spec)
231 gBS
->Stall (FORCE_GLOBAL_RESUME_TIME
);
234 // Write FGR bit to 0 and EGSM(Enter Global Suspend Mode) bit to 0
236 UsbCmd
&= ~USBCMD_FGR
;
237 UsbCmd
&= ~USBCMD_EGSM
;
239 UhciWriteReg (Uhc
->PciIo
, USBCMD_OFFSET
, UsbCmd
);
244 case EfiUsbHcStateSuspend
:
245 Status
= UhciSetState (This
, EfiUsbHcStateHalt
);
247 if (EFI_ERROR (Status
)) {
248 Status
= EFI_DEVICE_ERROR
;
253 // Set Enter Global Suspend Mode bit to 1.
255 UsbCmd
= UhciReadReg (Uhc
->PciIo
, USBCMD_OFFSET
);
256 UsbCmd
|= USBCMD_EGSM
;
257 UhciWriteReg (Uhc
->PciIo
, USBCMD_OFFSET
, UsbCmd
);
261 Status
= EFI_INVALID_PARAMETER
;
266 gBS
->RestoreTPL (OldTpl
);
272 Retrieves the number of root hub ports.
274 This : A pointer to the EFI_USB_HC_PROTOCOL instance.
275 PortNumber : A pointer to the number of the root hub ports.
277 @return EFI_SUCCESS : The port number was retrieved successfully.
278 @return EFI_INVALID_PARAMETER : PortNumber is NULL.
279 @return EFI_DEVICE_ERROR : An error was encountered
285 UhciGetRootHubPortNumber (
286 IN EFI_USB_HC_PROTOCOL
*This
,
287 OUT UINT8
*PortNumber
295 Uhc
= UHC_FROM_USB_HC_PROTO (This
);
297 if (PortNumber
== NULL
) {
298 return EFI_INVALID_PARAMETER
;
303 for (Index
= 0; Index
< USB_MAX_ROOTHUB_PORT
; Index
++) {
304 Offset
= USBPORTSC_OFFSET
+ Index
* 2;
305 PortSC
= UhciReadReg (Uhc
->PciIo
, Offset
);
308 // Port status's bit 7 is reserved and always returns 1 if
309 // the port number is valid. Intel's UHCI (in EHCI controller)
310 // returns 0 in this bit if port number is invalid. Also, if
311 // PciIo IoRead returns error, 0xFFFF is returned to caller.
313 if (((PortSC
& 0x80) != 0) && (PortSC
!= 0xFFFF)) {
318 Uhc
->RootPorts
= *PortNumber
;
320 UHCI_DEBUG (("UhciGetRootHubPortNumber: %d ports\n", Uhc
->RootPorts
));
326 Retrieves the current status of a USB root hub port.
328 This : A pointer to the EFI_USB_HC_PROTOCOL.
329 PortNumber : Specifies the root hub port. This value is zero-based.
330 PortStatus : A pointer to the current port status bits and port status change bits.
332 @return EFI_SUCCESS : The port status was returned in PortStatus.
333 @return EFI_INVALID_PARAMETER : PortNumber is invalid.
334 @return EFI_DEVICE_ERROR : Can't read register
339 UhciGetRootHubPortStatus (
340 IN EFI_USB_HC_PROTOCOL
*This
,
342 OUT EFI_USB_PORT_STATUS
*PortStatus
349 Uhc
= UHC_FROM_USB_HC_PROTO (This
);
351 if (PortStatus
== NULL
) {
352 return EFI_INVALID_PARAMETER
;
355 if (PortNumber
>= Uhc
->RootPorts
) {
356 return EFI_INVALID_PARAMETER
;
359 Offset
= USBPORTSC_OFFSET
+ PortNumber
* 2;
360 PortStatus
->PortStatus
= 0;
361 PortStatus
->PortChangeStatus
= 0;
363 PortSC
= UhciReadReg (Uhc
->PciIo
, Offset
);
365 if (PortSC
& USBPORTSC_CCS
) {
366 PortStatus
->PortStatus
|= USB_PORT_STAT_CONNECTION
;
369 if (PortSC
& USBPORTSC_PED
) {
370 PortStatus
->PortStatus
|= USB_PORT_STAT_ENABLE
;
373 if (PortSC
& USBPORTSC_SUSP
) {
374 UHCI_DEBUG (("UhciGetRootHubPortStatus: port %d is suspended\n", PortNumber
));
375 PortStatus
->PortStatus
|= USB_PORT_STAT_SUSPEND
;
378 if (PortSC
& USBPORTSC_PR
) {
379 PortStatus
->PortStatus
|= USB_PORT_STAT_RESET
;
382 if (PortSC
& USBPORTSC_LSDA
) {
383 PortStatus
->PortStatus
|= USB_PORT_STAT_LOW_SPEED
;
387 // CHC will always return one in port owner bit
389 PortStatus
->PortStatus
|= USB_PORT_STAT_OWNER
;
391 if (PortSC
& USBPORTSC_CSC
) {
392 PortStatus
->PortChangeStatus
|= USB_PORT_STAT_C_CONNECTION
;
395 if (PortSC
& USBPORTSC_PEDC
) {
396 PortStatus
->PortChangeStatus
|= USB_PORT_STAT_C_ENABLE
;
404 Sets a feature for the specified root hub port.
406 This : A pointer to the EFI_USB_HC_PROTOCOL.
407 PortNumber : Specifies the root hub port whose feature
408 is requested to be set.
409 PortFeature : Indicates the feature selector associated
410 with the feature set request.
412 @return EFI_SUCCESS : The feature was set for the port.
413 @return EFI_INVALID_PARAMETER : PortNumber is invalid or PortFeature is invalid.
414 @return EFI_DEVICE_ERROR : Can't read register
420 UhciSetRootHubPortFeature (
421 IN EFI_USB_HC_PROTOCOL
*This
,
423 IN EFI_USB_PORT_FEATURE PortFeature
432 Uhc
= UHC_FROM_USB_HC_PROTO (This
);
434 if (PortNumber
>= Uhc
->RootPorts
) {
435 return EFI_INVALID_PARAMETER
;
438 Offset
= USBPORTSC_OFFSET
+ PortNumber
* 2;
440 OldTpl
= gBS
->RaiseTPL (UHCI_TPL
);
441 PortSC
= UhciReadReg (Uhc
->PciIo
, Offset
);
443 switch (PortFeature
) {
444 case EfiUsbPortSuspend
:
445 Command
= UhciReadReg (Uhc
->PciIo
, USBCMD_OFFSET
);
446 if (!(Command
& USBCMD_EGSM
)) {
448 // if global suspend is not active, can set port suspend
451 PortSC
|= USBPORTSC_SUSP
;
455 case EfiUsbPortReset
:
457 PortSC
|= USBPORTSC_PR
;
460 case EfiUsbPortPower
:
466 case EfiUsbPortEnable
:
468 PortSC
|= USBPORTSC_PED
;
472 gBS
->RestoreTPL (OldTpl
);
473 return EFI_INVALID_PARAMETER
;
476 UhciWriteReg (Uhc
->PciIo
, Offset
, PortSC
);
477 gBS
->RestoreTPL (OldTpl
);
484 Clears a feature for the specified root hub port.
486 This : A pointer to the EFI_USB_HC_PROTOCOL instance.
487 PortNumber : Specifies the root hub port whose feature
488 is requested to be cleared.
489 PortFeature : Indicates the feature selector associated with the
490 feature clear request.
492 @return EFI_SUCCESS : The feature was cleared for the port.
493 @return EFI_INVALID_PARAMETER : PortNumber is invalid or PortFeature is invalid.
494 @return EFI_DEVICE_ERROR : Can't read register
500 UhciClearRootHubPortFeature (
501 IN EFI_USB_HC_PROTOCOL
*This
,
503 IN EFI_USB_PORT_FEATURE PortFeature
511 Uhc
= UHC_FROM_USB_HC_PROTO (This
);
513 if (PortNumber
>= Uhc
->RootPorts
) {
514 return EFI_INVALID_PARAMETER
;
517 Offset
= USBPORTSC_OFFSET
+ PortNumber
* 2;
519 OldTpl
= gBS
->RaiseTPL (UHCI_TPL
);
520 PortSC
= UhciReadReg (Uhc
->PciIo
, Offset
);
522 switch (PortFeature
) {
523 case EfiUsbPortEnable
:
525 PortSC
&= ~USBPORTSC_PED
;
528 case EfiUsbPortSuspend
:
530 // Cause a resume on the specified port if in suspend mode.
533 PortSC
&= ~USBPORTSC_SUSP
;
536 case EfiUsbPortPower
:
542 case EfiUsbPortReset
:
544 PortSC
&= ~USBPORTSC_PR
;
547 case EfiUsbPortConnectChange
:
549 PortSC
|= USBPORTSC_CSC
;
552 case EfiUsbPortEnableChange
:
554 PortSC
|= USBPORTSC_PEDC
;
557 case EfiUsbPortSuspendChange
:
559 // Root hub does not support this
563 case EfiUsbPortOverCurrentChange
:
565 // Root hub does not support this
569 case EfiUsbPortResetChange
:
571 // Root hub does not support this
576 gBS
->RestoreTPL (OldTpl
);
577 return EFI_INVALID_PARAMETER
;
580 UhciWriteReg (Uhc
->PciIo
, Offset
, PortSC
);
581 gBS
->RestoreTPL (OldTpl
);
588 Submits control transfer to a target USB device.
590 This : A pointer to the EFI_USB_HC_PROTOCOL instance.
591 DeviceAddress : Usb device address
592 IsSlowDevice : Whether the device is of slow speed or full speed
593 MaximumPacketLength : maximum packet size of the default control endpoint
594 Request : USB device request to send
595 TransferDirection : Specifies the data direction for the transfer.
596 Data : Data buffer to transmit from or receive into
597 DataLength : Number of bytes of the data
598 TimeOut : Maximum time, in microseconds
599 TransferResult : Return result in this
601 @return EFI_SUCCESS : Transfer was completed successfully.
602 @return EFI_OUT_OF_RESOURCES : Failed due to a lack of resources.
603 @return EFI_INVALID_PARAMETER : Some parameters are invalid.
604 @return EFI_TIMEOUT : Failed due to timeout.
605 @return EFI_DEVICE_ERROR : Failed due to host controller or device error.
611 UhciControlTransfer (
612 IN EFI_USB_HC_PROTOCOL
*This
,
613 IN UINT8 DeviceAddress
,
614 IN BOOLEAN IsSlowDevice
,
615 IN UINT8 MaximumPacketLength
,
616 IN EFI_USB_DEVICE_REQUEST
*Request
,
617 IN EFI_USB_DATA_DIRECTION TransferDirection
,
618 IN OUT VOID
*Data
, OPTIONAL
619 IN OUT UINTN
*DataLength
, OPTIONAL
621 OUT UINT32
*TransferResult
628 UHCI_QH_RESULT QhResult
;
635 Uhc
= UHC_FROM_USB_HC_PROTO (This
);
643 // Parameters Checking
645 if (Request
== NULL
|| TransferResult
== NULL
) {
646 return EFI_INVALID_PARAMETER
;
649 if (IsSlowDevice
&& (MaximumPacketLength
!= 8)) {
650 return EFI_INVALID_PARAMETER
;
653 if ((MaximumPacketLength
!= 8) && (MaximumPacketLength
!= 16) &&
654 (MaximumPacketLength
!= 32) && (MaximumPacketLength
!= 64)) {
656 return EFI_INVALID_PARAMETER
;
659 if ((TransferDirection
!= EfiUsbNoData
) && (DataLength
== NULL
)) {
660 return EFI_INVALID_PARAMETER
;
663 *TransferResult
= EFI_USB_ERR_SYSTEM
;
664 Status
= EFI_DEVICE_ERROR
;
667 // If errors exist that cause host controller halt,
668 // clear status then return EFI_DEVICE_ERROR.
670 UhciAckAllInterrupt (Uhc
);
672 if (!UhciIsHcWorking (Uhc
->PciIo
)) {
673 return EFI_DEVICE_ERROR
;
676 OldTpl
= gBS
->RaiseTPL (UHCI_TPL
);
679 // Map the Request and data for bus master access,
680 // then create a list of TD for this transfer
682 Status
= UhciMapUserRequest (Uhc
, Request
, &RequestPhy
, &RequestMap
);
684 if (EFI_ERROR (Status
)) {
688 Status
= UhciMapUserData (Uhc
, TransferDirection
, Data
, DataLength
, &PktId
, &DataPhy
, &DataMap
);
690 if (EFI_ERROR (Status
)) {
691 Uhc
->PciIo
->Unmap (Uhc
->PciIo
, RequestMap
);
695 TDs
= UhciCreateCtrlTds (
707 Status
= EFI_OUT_OF_RESOURCES
;
712 // According to the speed of the end point, link
713 // the TD to corrosponding queue head, then check
714 // the execution result
716 UhciLinkTdToQh (Uhc
->CtrlQh
, TDs
);
717 Status
= UhciExecuteTransfer (Uhc
, Uhc
->CtrlQh
, TDs
, TimeOut
, IsSlowDevice
, &QhResult
);
718 UhciUnlinkTdFromQh (Uhc
->CtrlQh
, TDs
);
720 Uhc
->PciIo
->Flush (Uhc
->PciIo
);
722 *TransferResult
= QhResult
.Result
;
724 if (DataLength
!= NULL
) {
725 *DataLength
= QhResult
.Complete
;
728 UhciDestoryTds (Uhc
, TDs
);
731 Uhc
->PciIo
->Unmap (Uhc
->PciIo
, DataMap
);
732 Uhc
->PciIo
->Unmap (Uhc
->PciIo
, RequestMap
);
735 gBS
->RestoreTPL (OldTpl
);
741 Submits bulk transfer to a bulk endpoint of a USB device.
743 This :A pointer to the EFI_USB_HC_PROTOCOL instance.
744 DeviceAddress : Usb device address
745 EndPointAddress : Endpoint number and endpoint direction
746 MaximumPacketLength : Maximum packet size of the target endpoint
747 Data : Data buffer to transmit from or receive into
748 DataLength : Length of the data buffer
749 DataToggle : On input, data toggle to use, on output, the next toggle
750 TimeOut : Indicates the maximum time
751 TransferResult : Variable to receive the transfer result
753 @return EFI_SUCCESS : The bulk transfer was completed successfully.
754 @return EFI_OUT_OF_RESOURCES : Failed due to lack of resource.
755 @return EFI_INVALID_PARAMETER : Some parameters are invalid.
756 @return EFI_TIMEOUT : Failed due to timeout.
757 @return EFI_DEVICE_ERROR : Failed due to host controller or device error.
764 IN EFI_USB_HC_PROTOCOL
*This
,
765 IN UINT8 DeviceAddress
,
766 IN UINT8 EndPointAddress
,
767 IN UINT8 MaximumPacketLength
,
769 IN OUT UINTN
*DataLength
,
770 IN OUT UINT8
*DataToggle
,
772 OUT UINT32
*TransferResult
775 EFI_USB_DATA_DIRECTION Direction
;
780 UHCI_QH_RESULT QhResult
;
786 Uhc
= UHC_FROM_USB_HC_PROTO (This
);
790 if ((DataLength
== NULL
) || (Data
== NULL
) || (TransferResult
== NULL
)) {
791 return EFI_INVALID_PARAMETER
;
794 if (*DataLength
== 0) {
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) {
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 (
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 interrupt endpoint of a USB device.
886 This : A pointer to the EFI_USB_HC_PROTOCOL instance.
887 DeviceAddress : Target device address
888 EndPointAddress : Endpoint number with direction
889 IsSlowDevice : Whether the target device is slow device or full-speed device.
890 MaximumPacketLength : Maximum packet size of the target endpoint
891 IsNewTransfer : If TRUE, submit a new async interrupt transfer, otherwise
892 cancel an existed one
893 DataToggle : On input, the data toggle to use; On output, next data toggle
894 PollingInterval : Interrupt poll rate in milliseconds
895 DataLength : Length of data to receive
896 CallBackFunction : Function to call periodically
897 Context : User context
899 @return EFI_SUCCESS : Request is submitted or cancelled
900 @return EFI_INVALID_PARAMETER : Some parameters are invalid.
901 @return EFI_OUT_OF_RESOURCES : Failed due to a lack of resources.
902 @return EFI_DEVICE_ERROR : Failed to due to device error
908 UhciAsyncInterruptTransfer (
909 IN EFI_USB_HC_PROTOCOL
* This
,
910 IN UINT8 DeviceAddress
,
911 IN UINT8 EndPointAddress
,
912 IN BOOLEAN IsSlowDevice
,
913 IN UINT8 MaximumPacketLength
,
914 IN BOOLEAN IsNewTransfer
,
915 IN OUT UINT8
*DataToggle
,
916 IN UINTN PollingInterval
, OPTIONAL
917 IN UINTN DataLength
, OPTIONAL
918 IN EFI_ASYNC_USB_TRANSFER_CALLBACK CallBackFunction
, OPTIONAL
919 IN VOID
*Context OPTIONAL
932 Uhc
= UHC_FROM_USB_HC_PROTO (This
);
939 if ((EndPointAddress
& 0x80) == 0) {
940 return EFI_INVALID_PARAMETER
;
944 // Delete Async interrupt transfer request
946 if (!IsNewTransfer
) {
947 OldTpl
= gBS
->RaiseTPL (UHCI_TPL
);
948 Status
= UhciRemoveAsyncReq (Uhc
, DeviceAddress
, EndPointAddress
, DataToggle
);
950 gBS
->RestoreTPL (OldTpl
);
954 if (PollingInterval
< 1 || PollingInterval
> 255) {
955 return EFI_INVALID_PARAMETER
;
958 if (DataLength
== 0) {
959 return EFI_INVALID_PARAMETER
;
962 if ((*DataToggle
!= 1) && (*DataToggle
!= 0)) {
963 return EFI_INVALID_PARAMETER
;
967 // If has errors that cause host controller halt,
968 // then return EFI_DEVICE_ERROR directly.
970 UhciAckAllInterrupt (Uhc
);
972 if (!UhciIsHcWorking (Uhc
->PciIo
)) {
973 return EFI_DEVICE_ERROR
;
977 // Allocate and map source data buffer for bus master access.
979 DataPtr
= AllocatePool (DataLength
);
981 if (DataPtr
== NULL
) {
982 return EFI_OUT_OF_RESOURCES
;
985 OldTpl
= gBS
->RaiseTPL (UHCI_TPL
);
988 // Map the user data then create a queue head and
989 // list of TD for it.
991 Status
= UhciMapUserData (
1001 if (EFI_ERROR (Status
)) {
1005 Qh
= UhciCreateQh (Uhc
, PollingInterval
);
1008 Status
= EFI_OUT_OF_RESOURCES
;
1012 IntTds
= UhciCreateBulkOrIntTds (
1020 MaximumPacketLength
,
1024 if (IntTds
== NULL
) {
1025 Status
= EFI_OUT_OF_RESOURCES
;
1029 UhciLinkTdToQh (Qh
, IntTds
);
1032 // Save QH-TD structures to async Interrupt transfer list,
1033 // for monitor interrupt transfer execution routine use.
1035 Status
= UhciCreateAsyncReq (
1050 if (EFI_ERROR (Status
)) {
1054 UhciLinkQhToFrameList (Uhc
->FrameBase
, Qh
);
1056 gBS
->RestoreTPL (OldTpl
);
1060 UsbHcFreeMem (Uhc
->MemPool
, Qh
, sizeof (UHCI_QH_SW
));
1063 Uhc
->PciIo
->Unmap (Uhc
->PciIo
, DataMap
);
1066 gBS
->FreePool (DataPtr
);
1067 Uhc
->PciIo
->Flush (Uhc
->PciIo
);
1069 gBS
->RestoreTPL (OldTpl
);
1075 Submits synchronous interrupt transfer to an interrupt endpoint of a USB device.
1077 This : A pointer to the EFI_USB_HC_PROTOCOL instance.
1078 DeviceAddress : Device address of the target USB device
1079 EndPointAddress : Endpoint number and direction
1080 IsSlowDevice : Whether the target device is of slow speed or full speed
1081 MaximumPacketLength : Maximum packet size of target endpoint
1082 Data : Data to transmit or receive
1083 DataLength : On input, data length to transmit or buffer size.
1084 On output, the number of bytes transferred.
1085 DataToggle : On input, data toggle to use; On output, next data toggle
1086 TimeOut : Maximum time, in microseconds, transfer is allowed to complete.
1087 TransferResult : Variable to receive transfer result
1089 @return EFI_SUCCESS : Transfer was completed successfully.
1090 @return EFI_OUT_OF_RESOURCES : Failed due to lack of resource.
1091 @return EFI_INVALID_PARAMETER : Some parameters are invalid.
1092 @return EFI_TIMEOUT : Failed due to timeout.
1093 @return EFI_DEVICE_ERROR : Failed due to host controller or device error
1099 UhciSyncInterruptTransfer (
1100 IN EFI_USB_HC_PROTOCOL
*This
,
1101 IN UINT8 DeviceAddress
,
1102 IN UINT8 EndPointAddress
,
1103 IN BOOLEAN IsSlowDevice
,
1104 IN UINT8 MaximumPacketLength
,
1106 IN OUT UINTN
*DataLength
,
1107 IN OUT UINT8
*DataToggle
,
1109 OUT UINT32
*TransferResult
1115 UHCI_QH_RESULT QhResult
;
1121 Uhc
= UHC_FROM_USB_HC_PROTO (This
);
1126 if ((DataLength
== NULL
) || (Data
== NULL
) || (TransferResult
== NULL
)) {
1127 return EFI_INVALID_PARAMETER
;
1130 if ((EndPointAddress
& 0x80) == 0) {
1131 return EFI_INVALID_PARAMETER
;
1134 if ((*DataToggle
!= 1) && (*DataToggle
!= 0)) {
1135 return EFI_INVALID_PARAMETER
;
1138 if ((*DataLength
== 0) || (MaximumPacketLength
> 64)) {
1139 return EFI_INVALID_PARAMETER
;
1142 if (IsSlowDevice
&& (MaximumPacketLength
> 8)) {
1143 return EFI_INVALID_PARAMETER
;
1146 *TransferResult
= EFI_USB_ERR_SYSTEM
;
1147 Status
= EFI_DEVICE_ERROR
;
1150 UhciAckAllInterrupt (Uhc
);
1152 if (!UhciIsHcWorking (Uhc
->PciIo
)) {
1156 OldTpl
= gBS
->RaiseTPL (UHCI_TPL
);
1159 // Map the source data buffer for bus master access.
1160 // Create Tds list, then link it to the UHC's interrupt list
1162 Status
= UhciMapUserData (
1172 if (EFI_ERROR (Status
)) {
1176 TDs
= UhciCreateBulkOrIntTds (
1184 MaximumPacketLength
,
1189 Uhc
->PciIo
->Unmap (Uhc
->PciIo
, DataMap
);
1191 Status
= EFI_OUT_OF_RESOURCES
;
1196 UhciLinkTdToQh (Uhc
->SyncIntQh
, TDs
);
1198 Status
= UhciExecuteTransfer (Uhc
, Uhc
->SyncIntQh
, TDs
, TimeOut
, IsSlowDevice
, &QhResult
);
1200 UhciUnlinkTdFromQh (Uhc
->SyncIntQh
, TDs
);
1201 Uhc
->PciIo
->Flush (Uhc
->PciIo
);
1203 *TransferResult
= QhResult
.Result
;
1204 *DataToggle
= QhResult
.NextToggle
;
1205 *DataLength
= QhResult
.Complete
;
1207 UhciDestoryTds (Uhc
, TDs
);
1208 Uhc
->PciIo
->Unmap (Uhc
->PciIo
, DataMap
);
1211 gBS
->RestoreTPL (OldTpl
);
1217 Submits isochronous transfer to a target USB device.
1219 This : A pointer to the EFI_USB_HC_PROTOCOL instance.
1220 DeviceAddress : Target device address
1221 EndPointAddress : End point address withdirection
1222 MaximumPacketLength : Maximum packet size of the endpoint
1223 Data : Data to transmit or receive
1224 DataLength : Bytes of the data
1225 TransferResult : Variable to receive the result
1227 @return EFI_UNSUPPORTED
1233 UhciIsochronousTransfer (
1234 IN EFI_USB_HC_PROTOCOL
*This
,
1235 IN UINT8 DeviceAddress
,
1236 IN UINT8 EndPointAddress
,
1237 IN UINT8 MaximumPacketLength
,
1239 IN UINTN DataLength
,
1240 OUT UINT32
*TransferResult
1243 return EFI_UNSUPPORTED
;
1248 Submits Async isochronous transfer to a target USB device.
1250 This : A pointer to the EFI_USB_HC_PROTOCOL instance.
1251 DeviceAddress : Target device address
1252 EndPointAddress : End point address withdirection
1253 MaximumPacketLength : Maximum packet size of the endpoint
1254 Data : Data to transmit or receive
1255 IsochronousCallBack : Function to call when the transfer completes
1256 Context : User context
1258 @return EFI_UNSUPPORTED
1264 UhciAsyncIsochronousTransfer (
1265 IN EFI_USB_HC_PROTOCOL
* This
,
1266 IN UINT8 DeviceAddress
,
1267 IN UINT8 EndPointAddress
,
1268 IN UINT8 MaximumPacketLength
,
1270 IN UINTN DataLength
,
1271 IN EFI_ASYNC_USB_TRANSFER_CALLBACK IsochronousCallBack
,
1272 IN VOID
*Context OPTIONAL
1275 return EFI_UNSUPPORTED
;
1281 Provides software reset for the USB host controller according to UEFI 2.0 spec.
1283 @param This A pointer to the EFI_USB2_HC_PROTOCOL instance.
1284 @param Attributes A bit mask of the reset operation to perform. See
1285 below for a list of the supported bit mask values.
1287 @return EFI_SUCCESS : The reset operation succeeded.
1288 @return EFI_INVALID_PARAMETER : Attributes is not valid.
1289 @return EFI_UNSUPPORTED : This type of reset is not currently supported
1290 @return EFI_DEVICE_ERROR : Other errors
1297 IN EFI_USB2_HC_PROTOCOL
*This
,
1298 IN UINT16 Attributes
1301 USB_HC_DEV
*UhciDev
;
1303 UhciDev
= UHC_FROM_USB2_HC_PROTO (This
);
1305 if ((Attributes
== EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG
) ||
1306 (Attributes
== EFI_USB_HC_RESET_HOST_WITH_DEBUG
)) {
1307 return EFI_UNSUPPORTED
;
1310 return UhciReset (&UhciDev
->UsbHc
, Attributes
);
1315 Retrieves current state of the USB host controller according to UEFI 2.0 spec.
1317 @param This A pointer to the EFI_USB_HC_PROTOCOL instance.
1318 @param State Variable to receive current device state
1320 @return EFI_SUCCESS : The state is returned
1321 @return EFI_INVALID_PARAMETER : State is not valid.
1322 @return EFI_DEVICE_ERROR : Other errors2006
1329 IN CONST EFI_USB2_HC_PROTOCOL
*This
,
1330 OUT EFI_USB_HC_STATE
*State
1335 Uhc
= UHC_FROM_USB2_HC_PROTO (This
);
1336 return UhciGetState (&Uhc
->UsbHc
, State
);
1341 Sets the USB host controller to a specific state according to UEFI 2.0 spec.
1343 @param This A pointer to the EFI_USB_HC_PROTOCOL instance.
1344 @param State Indicates the state of the host controller that will
1347 @return EFI_SUCCESS : Host controller was successfully placed in the state
1348 @return EFI_INVALID_PARAMETER : State is invalid.
1349 @return EFI_DEVICE_ERROR : Failed to set the state
1356 IN EFI_USB2_HC_PROTOCOL
*This
,
1357 IN EFI_USB_HC_STATE State
1362 Uhc
= UHC_FROM_USB2_HC_PROTO (This
);
1363 return UhciSetState (&Uhc
->UsbHc
, State
);
1368 Retrieves capabilities of USB host controller according to UEFI 2.0 spec.
1370 @param This A pointer to the EFI_USB2_HC_PROTOCOL instance
1371 @param MaxSpeed A pointer to the max speed USB host controller
1373 @param PortNumber A pointer to the number of root hub ports.
1374 @param Is64BitCapable A pointer to an integer to show whether USB host
1375 controller supports 64-bit memory addressing.
1377 @return EFI_SUCCESS : capabilities were retrieved successfully.
1378 @return EFI_INVALID_PARAMETER : MaxSpeed or PortNumber or Is64BitCapable is NULL.
1379 @return EFI_DEVICE_ERROR : An error was encountered
1385 Uhci2GetCapability (
1386 IN EFI_USB2_HC_PROTOCOL
*This
,
1387 OUT UINT8
*MaxSpeed
,
1388 OUT UINT8
*PortNumber
,
1389 OUT UINT8
*Is64BitCapable
1394 Uhc
= UHC_FROM_USB2_HC_PROTO (This
);
1396 if ((NULL
== MaxSpeed
) || (NULL
== PortNumber
) || (NULL
== Is64BitCapable
)) {
1397 return EFI_INVALID_PARAMETER
;
1400 *MaxSpeed
= EFI_USB_SPEED_FULL
;
1401 *Is64BitCapable
= (UINT8
) FALSE
;
1403 return UhciGetRootHubPortNumber (&Uhc
->UsbHc
, PortNumber
);
1408 Retrieves the current status of a USB root hub port according to UEFI 2.0 spec.
1410 @param This A pointer to the EFI_USB2_HC_PROTOCOL.
1411 @param PortNumber The port to get status
1412 @param PortStatus A pointer to the current port status bits and port
1415 @return EFI_SUCCESS : status of the USB root hub port was returned in PortStatus.
1416 @return EFI_INVALID_PARAMETER : PortNumber is invalid.
1417 @return EFI_DEVICE_ERROR : Can't read register
1423 Uhci2GetRootHubPortStatus (
1424 IN CONST EFI_USB2_HC_PROTOCOL
*This
,
1425 IN CONST UINT8 PortNumber
,
1426 OUT EFI_USB_PORT_STATUS
*PortStatus
1431 Uhc
= UHC_FROM_USB2_HC_PROTO (This
);
1433 return UhciGetRootHubPortStatus (&Uhc
->UsbHc
, PortNumber
, PortStatus
);
1438 Sets a feature for the specified root hub port according to UEFI 2.0 spec.
1440 @param This A pointer to the EFI_USB2_HC_PROTOCOL.
1441 @param PortNumber Specifies the root hub port whose feature is
1442 requested to be set.
1443 @param PortFeature Indicates the feature selector associated with the
1444 feature set request.
1446 @return EFI_SUCCESS : PortFeature was set for the root port
1447 @return EFI_INVALID_PARAMETER : PortNumber is invalid or PortFeature is invalid.
1448 @return EFI_DEVICE_ERROR : Can't read register
1454 Uhci2SetRootHubPortFeature (
1455 IN EFI_USB2_HC_PROTOCOL
*This
,
1456 IN UINT8 PortNumber
,
1457 IN EFI_USB_PORT_FEATURE PortFeature
1462 Uhc
= UHC_FROM_USB2_HC_PROTO (This
);
1464 return UhciSetRootHubPortFeature (&Uhc
->UsbHc
, PortNumber
, PortFeature
);
1469 Clears a feature for the specified root hub port according to Uefi 2.0 spec.
1471 @param This A pointer to the EFI_USB2_HC_PROTOCOL instance.
1472 @param PortNumber Specifies the root hub port whose feature is
1473 requested to be cleared.
1474 @param PortFeature Indicates the feature selector associated with the
1475 feature clear request.
1477 @return EFI_SUCCESS : PortFeature was cleared for the USB root hub port
1478 @return EFI_INVALID_PARAMETER : PortNumber is invalid or PortFeature is invalid.
1479 @return EFI_DEVICE_ERROR : Can't read register
1485 Uhci2ClearRootHubPortFeature (
1486 IN EFI_USB2_HC_PROTOCOL
*This
,
1487 IN UINT8 PortNumber
,
1488 IN EFI_USB_PORT_FEATURE PortFeature
1493 Uhc
= UHC_FROM_USB2_HC_PROTO (This
);
1495 return UhciClearRootHubPortFeature (&Uhc
->UsbHc
, PortNumber
, PortFeature
);
1500 Submits control transfer to a target USB device accroding to UEFI 2.0 spec..
1502 This : A pointer to the EFI_USB2_HC_PROTOCOL instance.
1503 DeviceAddress : Target device address
1504 DeviceSpeed : Device speed
1505 MaximumPacketLength : Maximum packet size of the target endpoint
1506 Request : USB device request to send
1507 TransferDirection : Data direction of the Data stage in control transfer
1508 Data : Data to transmit/receive in data stage
1509 DataLength : Length of the data
1510 TimeOut : Maximum time, in microseconds, for transfer to complete.
1511 TransferResult : Variable to receive the transfer result
1513 @return EFI_SUCCESS : The control transfer was completed successfully.
1514 @return EFI_OUT_OF_RESOURCES : Failed due to lack of resource.
1515 @return EFI_INVALID_PARAMETER : Some parameters are invalid.
1516 @return EFI_TIMEOUT : Failed due to timeout.
1517 @return EFI_DEVICE_ERROR : Failed due to host controller or device error.
1523 Uhci2ControlTransfer (
1524 IN EFI_USB2_HC_PROTOCOL
*This
,
1525 IN UINT8 DeviceAddress
,
1526 IN UINT8 DeviceSpeed
,
1527 IN UINTN MaximumPacketLength
,
1528 IN EFI_USB_DEVICE_REQUEST
*Request
,
1529 IN EFI_USB_DATA_DIRECTION TransferDirection
,
1531 IN OUT UINTN
*DataLength
,
1533 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
1534 OUT UINT32
*TransferResult
1540 Uhc
= UHC_FROM_USB2_HC_PROTO (This
);
1541 IsSlow
= (BOOLEAN
) ((EFI_USB_SPEED_LOW
== DeviceSpeed
) ? TRUE
: FALSE
);
1543 return UhciControlTransfer (
1547 (UINT8
) MaximumPacketLength
,
1559 Submits bulk transfer to a bulk endpoint of a USB device
1561 This : A pointer to the EFI_USB2_HC_PROTOCOL instance.
1562 DeviceAddress : Target device address
1563 EndPointAddress : Endpoint number and direction
1564 DeviceSpeed : Device speed
1565 MaximumPacketLength : Maximum packet size of the target endpoint
1566 DataBuffersNumber : Number of data buffers prepared for the transfer.
1567 Data : Array of pointers to the buffers of data
1568 DataLength : On input, size of the data buffer, On output,
1569 actually transferred data size.
1570 DataToggle : On input, data toggle to use; On output, next data toggle
1571 Translator : A pointr to the transaction translator data.
1572 TimeOut : Maximum time out, in microseconds
1573 TransferResult : Variable to receive transfer result
1575 @return EFI_SUCCESS : The bulk transfer was completed successfully.
1576 @return EFI_OUT_OF_RESOURCES : Failed due to lack of resource.
1577 @return EFI_INVALID_PARAMETER : Some parameters are invalid.
1578 @return EFI_TIMEOUT : Failed due to timeout.
1579 @return EFI_DEVICE_ERROR : Failed due to host controller or device error.
1586 IN EFI_USB2_HC_PROTOCOL
*This
,
1587 IN UINT8 DeviceAddress
,
1588 IN UINT8 EndPointAddress
,
1589 IN UINT8 DeviceSpeed
,
1590 IN UINTN MaximumPacketLength
,
1591 IN UINT8 DataBuffersNumber
,
1592 IN OUT VOID
*Data
[EFI_USB_MAX_BULK_BUFFER_NUM
],
1593 IN OUT UINTN
*DataLength
,
1594 IN OUT UINT8
*DataToggle
,
1596 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
1597 OUT UINT32
*TransferResult
1602 Uhc
= UHC_FROM_USB2_HC_PROTO (This
);
1604 if (Data
== NULL
|| DeviceSpeed
== EFI_USB_SPEED_LOW
) {
1605 return EFI_INVALID_PARAMETER
;
1609 // For full-speed bulk transfers only the data pointed by Data[0] shall be used
1611 return UhciBulkTransfer (
1615 (UINT8
) MaximumPacketLength
,
1626 Submits an asynchronous interrupt transfer to an
1627 interrupt endpoint of a USB device according to UEFI 2.0 spec.
1629 This : A pointer to the EFI_USB2_HC_PROTOCOL instance.
1630 DeviceAddress : Target device address
1631 EndPointAddress : Endpoint number and direction
1632 DeviceSpeed : Device speed
1633 MaximumPacketLength : Maximum packet size of the target endpoint
1634 IsNewTransfer : If TRUE, submit a new transfer, if FALSE cancel old transfer
1635 DataToggle : On input, data toggle to use; On output, next data toggle
1636 PollingInterval : Interrupt poll rate in milliseconds
1637 DataLength : On input, size of the data buffer, On output,
1638 actually transferred data size.
1639 Translator : A pointr to the transaction translator data.
1640 CallBackFunction : Function to call periodically
1641 Context : User context
1643 @return EFI_SUCCESS : Transfer was submitted
1644 @return EFI_INVALID_PARAMETER : Some parameters are invalid.
1645 @return EFI_OUT_OF_RESOURCES : Failed due to a lack of resources.
1646 @return EFI_DEVICE_ERROR : Can't read register
1652 Uhci2AsyncInterruptTransfer (
1653 IN EFI_USB2_HC_PROTOCOL
*This
,
1654 IN UINT8 DeviceAddress
,
1655 IN UINT8 EndPointAddress
,
1656 IN UINT8 DeviceSpeed
,
1657 IN UINTN MaximumPacketLength
,
1658 IN BOOLEAN IsNewTransfer
,
1659 IN OUT UINT8
*DataToggle
,
1660 IN UINTN PollingInterval
,
1661 IN UINTN DataLength
,
1662 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
1663 IN EFI_ASYNC_USB_TRANSFER_CALLBACK CallBackFunction
,
1670 Uhc
= UHC_FROM_USB2_HC_PROTO (This
);
1671 IsSlow
= (BOOLEAN
) ((EFI_USB_SPEED_LOW
== DeviceSpeed
) ? TRUE
: FALSE
);
1673 return UhciAsyncInterruptTransfer (
1678 (UINT8
) MaximumPacketLength
,
1690 Submits synchronous interrupt transfer to an interrupt endpoint
1691 of a USB device according to UEFI 2.0 spec.
1693 This : A pointer to the EFI_USB2_HC_PROTOCOL instance.
1694 DeviceAddress : Target device address
1695 EndPointAddress : Endpoint number and direction
1696 DeviceSpeed : Device speed
1697 MaximumPacketLength : Maximum packet size of the target endpoint
1698 DataBuffersNumber : Number of data buffers prepared for the transfer.
1699 Data : Array of pointers to the buffers of data
1700 DataLength : On input, size of the data buffer, On output,
1701 actually transferred data size.
1702 DataToggle : On input, data toggle to use; On output, next data toggle
1703 TimeOut : Maximum time out, in microseconds
1704 Translator : A pointr to the transaction translator data.
1705 TransferResult : Variable to receive transfer result
1707 @return EFI_SUCCESS : The transfer was completed successfully.
1708 @return EFI_OUT_OF_RESOURCES : Failed due to lack of resource.
1709 @return EFI_INVALID_PARAMETER : Some parameters are invalid.
1710 @return EFI_TIMEOUT : Failed due to timeout.
1711 @return EFI_DEVICE_ERROR : Failed due to host controller or device error.
1717 Uhci2SyncInterruptTransfer (
1718 IN EFI_USB2_HC_PROTOCOL
*This
,
1719 IN UINT8 DeviceAddress
,
1720 IN UINT8 EndPointAddress
,
1721 IN UINT8 DeviceSpeed
,
1722 IN UINTN MaximumPacketLength
,
1724 IN OUT UINTN
*DataLength
,
1725 IN OUT UINT8
*DataToggle
,
1727 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
1728 OUT UINT32
*TransferResult
1734 if (DeviceSpeed
== EFI_USB_SPEED_HIGH
) {
1735 return EFI_INVALID_PARAMETER
;
1738 Uhc
= UHC_FROM_USB2_HC_PROTO (This
);
1739 IsSlow
= (BOOLEAN
) ((EFI_USB_SPEED_LOW
== DeviceSpeed
) ? TRUE
: FALSE
);
1741 return UhciSyncInterruptTransfer (
1746 (UINT8
) MaximumPacketLength
,
1757 Submits isochronous transfer to a target USB device according to UEFI 2.0 spec.
1759 This : A pointer to the EFI_USB2_HC_PROTOCOL instance.
1760 DeviceAddress : Target device address
1761 EndPointAddress : Endpoint number and direction
1762 DeviceSpeed : Device speed
1763 MaximumPacketLength : Maximum packet size of the target endpoint
1764 DataBuffersNumber : Number of data buffers prepared for the transfer.
1765 Data : Array of pointers to the buffers of data
1766 DataLength : On input, size of the data buffer, On output,
1767 actually transferred data size.
1768 Translator : A pointr to the transaction translator data.
1769 TransferResult : Variable to receive transfer result
1771 @return EFI_UNSUPPORTED
1777 Uhci2IsochronousTransfer (
1778 IN EFI_USB2_HC_PROTOCOL
*This
,
1779 IN UINT8 DeviceAddress
,
1780 IN UINT8 EndPointAddress
,
1781 IN UINT8 DeviceSpeed
,
1782 IN UINTN MaximumPacketLength
,
1783 IN UINT8 DataBuffersNumber
,
1784 IN OUT VOID
*Data
[EFI_USB_MAX_ISO_BUFFER_NUM
],
1785 IN UINTN DataLength
,
1786 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
1787 OUT UINT32
*TransferResult
1790 return EFI_UNSUPPORTED
;
1795 Submits Async isochronous transfer to a target USB device according to UEFI 2.0 spec.
1797 This : A pointer to the EFI_USB2_HC_PROTOCOL instance.
1798 DeviceAddress : Target device address
1799 EndPointAddress : Endpoint number and direction
1800 DeviceSpeed : Device speed
1801 MaximumPacketLength : Maximum packet size of the target endpoint
1802 DataBuffersNumber : Number of data buffers prepared for the transfer.
1803 Data : Array of pointers to the buffers of data
1804 Translator : A pointr to the transaction translator data.
1805 IsochronousCallBack : Function to call when the transfer complete
1806 Context : Pass to the call back function as parameter
1808 @return EFI_UNSUPPORTED
1814 Uhci2AsyncIsochronousTransfer (
1815 IN EFI_USB2_HC_PROTOCOL
*This
,
1816 IN UINT8 DeviceAddress
,
1817 IN UINT8 EndPointAddress
,
1818 IN UINT8 DeviceSpeed
,
1819 IN UINTN MaximumPacketLength
,
1820 IN UINT8 DataBuffersNumber
,
1821 IN OUT VOID
*Data
[EFI_USB_MAX_ISO_BUFFER_NUM
],
1822 IN UINTN DataLength
,
1823 IN EFI_USB2_HC_TRANSACTION_TRANSLATOR
*Translator
,
1824 IN EFI_ASYNC_USB_TRANSFER_CALLBACK IsochronousCallBack
,
1828 return EFI_UNSUPPORTED
;
1833 UhciDriverEntryPoint (
1834 IN EFI_HANDLE ImageHandle
,
1835 IN EFI_SYSTEM_TABLE
*SystemTable
1839 Routine Description:
1841 Entry point for EFI drivers.
1845 ImageHandle - EFI_HANDLE
1846 SystemTable - EFI_SYSTEM_TABLE
1850 EFI_SUCCESS : Driver is successfully loaded
1855 return EfiLibInstallDriverBindingComponentName2 (
1858 &gUhciDriverBinding
,
1860 &gUhciComponentName
,
1861 &gUhciComponentName2
1867 Test to see if this driver supports ControllerHandle. Any
1868 ControllerHandle that has UsbHcProtocol installed will be supported.
1870 @param This Protocol instance pointer.
1871 @param Controller Handle of device to test
1872 @param RemainingDevicePath Not used
1874 @return EFI_SUCCESS : This driver supports this device.
1875 @return EFI_UNSUPPORTED : This driver does not support this device.
1880 UhciDriverBindingSupported (
1881 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1882 IN EFI_HANDLE Controller
,
1883 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
1886 EFI_STATUS OpenStatus
;
1888 EFI_PCI_IO_PROTOCOL
*PciIo
;
1889 USB_CLASSC UsbClassCReg
;
1892 // Test whether there is PCI IO Protocol attached on the controller handle.
1894 OpenStatus
= gBS
->OpenProtocol (
1896 &gEfiPciIoProtocolGuid
,
1898 This
->DriverBindingHandle
,
1900 EFI_OPEN_PROTOCOL_BY_DRIVER
1903 if (EFI_ERROR (OpenStatus
)) {
1907 Status
= PciIo
->Pci
.Read (
1911 sizeof (USB_CLASSC
) / sizeof (UINT8
),
1915 if (EFI_ERROR (Status
)) {
1916 Status
= EFI_UNSUPPORTED
;
1921 // Test whether the controller belongs to UHCI type
1923 if ((UsbClassCReg
.BaseCode
!= PCI_CLASS_SERIAL
) ||
1924 (UsbClassCReg
.SubClassCode
!= PCI_CLASS_SERIAL_USB
) ||
1925 (UsbClassCReg
.PI
!= PCI_CLASSC_PI_UHCI
)
1928 Status
= EFI_UNSUPPORTED
;
1932 gBS
->CloseProtocol (
1934 &gEfiPciIoProtocolGuid
,
1935 This
->DriverBindingHandle
,
1945 Allocate and initialize the empty UHCI device
1947 @param PciIo The PCIIO to use
1949 @return Allocated UHCI device
1955 IN EFI_PCI_IO_PROTOCOL
*PciIo
1961 Uhc
= AllocateZeroPool (sizeof (USB_HC_DEV
));
1968 // This driver supports both USB_HC_PROTOCOL and USB2_HC_PROTOCOL.
1969 // USB_HC_PROTOCOL is for EFI 1.1 backward compability.
1971 Uhc
->Signature
= USB_HC_DEV_SIGNATURE
;
1972 Uhc
->UsbHc
.Reset
= UhciReset
;
1973 Uhc
->UsbHc
.GetState
= UhciGetState
;
1974 Uhc
->UsbHc
.SetState
= UhciSetState
;
1975 Uhc
->UsbHc
.ControlTransfer
= UhciControlTransfer
;
1976 Uhc
->UsbHc
.BulkTransfer
= UhciBulkTransfer
;
1977 Uhc
->UsbHc
.AsyncInterruptTransfer
= UhciAsyncInterruptTransfer
;
1978 Uhc
->UsbHc
.SyncInterruptTransfer
= UhciSyncInterruptTransfer
;
1979 Uhc
->UsbHc
.IsochronousTransfer
= UhciIsochronousTransfer
;
1980 Uhc
->UsbHc
.AsyncIsochronousTransfer
= UhciAsyncIsochronousTransfer
;
1981 Uhc
->UsbHc
.GetRootHubPortNumber
= UhciGetRootHubPortNumber
;
1982 Uhc
->UsbHc
.GetRootHubPortStatus
= UhciGetRootHubPortStatus
;
1983 Uhc
->UsbHc
.SetRootHubPortFeature
= UhciSetRootHubPortFeature
;
1984 Uhc
->UsbHc
.ClearRootHubPortFeature
= UhciClearRootHubPortFeature
;
1985 Uhc
->UsbHc
.MajorRevision
= 0x1;
1986 Uhc
->UsbHc
.MinorRevision
= 0x1;
1988 Uhc
->Usb2Hc
.GetCapability
= Uhci2GetCapability
;
1989 Uhc
->Usb2Hc
.Reset
= Uhci2Reset
;
1990 Uhc
->Usb2Hc
.GetState
= Uhci2GetState
;
1991 Uhc
->Usb2Hc
.SetState
= Uhci2SetState
;
1992 Uhc
->Usb2Hc
.ControlTransfer
= Uhci2ControlTransfer
;
1993 Uhc
->Usb2Hc
.BulkTransfer
= Uhci2BulkTransfer
;
1994 Uhc
->Usb2Hc
.AsyncInterruptTransfer
= Uhci2AsyncInterruptTransfer
;
1995 Uhc
->Usb2Hc
.SyncInterruptTransfer
= Uhci2SyncInterruptTransfer
;
1996 Uhc
->Usb2Hc
.IsochronousTransfer
= Uhci2IsochronousTransfer
;
1997 Uhc
->Usb2Hc
.AsyncIsochronousTransfer
= Uhci2AsyncIsochronousTransfer
;
1998 Uhc
->Usb2Hc
.GetRootHubPortStatus
= Uhci2GetRootHubPortStatus
;
1999 Uhc
->Usb2Hc
.SetRootHubPortFeature
= Uhci2SetRootHubPortFeature
;
2000 Uhc
->Usb2Hc
.ClearRootHubPortFeature
= Uhci2ClearRootHubPortFeature
;
2001 Uhc
->Usb2Hc
.MajorRevision
= 0x1;
2002 Uhc
->Usb2Hc
.MinorRevision
= 0x1;
2005 Uhc
->MemPool
= UsbHcInitMemPool (PciIo
, TRUE
, 0);
2007 if (Uhc
->MemPool
== NULL
) {
2008 Status
= EFI_OUT_OF_RESOURCES
;
2012 InitializeListHead (&Uhc
->AsyncIntList
);
2014 Status
= gBS
->CreateEvent (
2015 EVT_TIMER
| EVT_NOTIFY_SIGNAL
,
2017 UhciMonitorAsyncReqList
,
2019 &Uhc
->AsyncIntMonitor
2022 if (EFI_ERROR (Status
)) {
2023 UsbHcFreeMemPool (Uhc
->MemPool
);
2030 gBS
->FreePool (Uhc
);
2036 Free the UHCI device and release its associated resources
2038 @param Uhc The UHCI device to release
2049 if (Uhc
->AsyncIntMonitor
!= NULL
) {
2050 gBS
->CloseEvent (Uhc
->AsyncIntMonitor
);
2053 if (Uhc
->MemPool
!= NULL
) {
2054 UsbHcFreeMemPool (Uhc
->MemPool
);
2057 if (Uhc
->CtrlNameTable
) {
2058 FreeUnicodeStringTable (Uhc
->CtrlNameTable
);
2061 gBS
->FreePool (Uhc
);
2066 Uninstall all Uhci Interface
2068 @param Controller Controller handle
2069 @param This Protocol instance pointer.
2077 IN EFI_HANDLE Controller
,
2078 IN EFI_USB_HC_PROTOCOL
*This
2084 // Uninstall the USB_HC and USB_HC2 protocol, then disable the controller
2086 Uhc
= UHC_FROM_USB_HC_PROTO (This
);
2087 UhciStopHc (Uhc
, STALL_1_SECOND
);
2089 gBS
->UninstallProtocolInterface (
2091 &gEfiUsbHcProtocolGuid
,
2095 gBS
->UninstallProtocolInterface (
2097 &gEfiUsb2HcProtocolGuid
,
2101 UhciFreeAllAsyncReq (Uhc
);
2102 UhciDestoryFrameList (Uhc
);
2104 Uhc
->PciIo
->Attributes (
2106 EfiPciIoAttributeOperationDisable
,
2107 EFI_PCI_DEVICE_ENABLE
,
2116 Starting the Usb UHCI Driver
2118 @param This Protocol instance pointer.
2119 @param Controller Handle of device to test
2120 @param RemainingDevicePath Not used
2122 @retval EFI_SUCCESS This driver supports this device.
2123 @retval EFI_UNSUPPORTED This driver does not support this device.
2124 @retval EFI_DEVICE_ERROR This driver cannot be started due to device Error
2125 EFI_OUT_OF_RESOURCES- Failed due to resource
2131 UhciDriverBindingStart (
2132 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
2133 IN EFI_HANDLE Controller
,
2134 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
2138 EFI_PCI_IO_PROTOCOL
*PciIo
;
2142 // Open PCIIO, then enable the EHC device and turn off emulation
2145 Status
= gBS
->OpenProtocol (
2147 &gEfiPciIoProtocolGuid
,
2149 This
->DriverBindingHandle
,
2151 EFI_OPEN_PROTOCOL_BY_DRIVER
2154 if (EFI_ERROR (Status
)) {
2158 UhciTurnOffUsbEmulation (PciIo
);
2160 Status
= PciIo
->Attributes (
2162 EfiPciIoAttributeOperationEnable
,
2163 EFI_PCI_DEVICE_ENABLE
,
2167 if (EFI_ERROR (Status
)) {
2171 Uhc
= UhciAllocateDev (PciIo
);
2174 Status
= EFI_OUT_OF_RESOURCES
;
2179 // Allocate and Init Host Controller's Frame List Entry
2181 Status
= UhciInitFrameList (Uhc
);
2183 if (EFI_ERROR (Status
)) {
2184 Status
= EFI_OUT_OF_RESOURCES
;
2188 Status
= gBS
->SetTimer (
2189 Uhc
->AsyncIntMonitor
,
2191 INTERRUPT_POLLING_TIME
2194 if (EFI_ERROR (Status
)) {
2199 // Install both USB_HC_PROTOCOL and USB2_HC_PROTOCOL
2201 Status
= gBS
->InstallMultipleProtocolInterfaces (
2203 &gEfiUsbHcProtocolGuid
,
2205 &gEfiUsb2HcProtocolGuid
,
2210 if (EFI_ERROR (Status
)) {
2215 // Install the component name protocol
2217 Uhc
->CtrlNameTable
= NULL
;
2221 gUhciComponentName
.SupportedLanguages
,
2222 &Uhc
->CtrlNameTable
,
2223 L
"Usb Universal Host Controller",
2228 gUhciComponentName2
.SupportedLanguages
,
2229 &Uhc
->CtrlNameTable
,
2230 L
"Usb Universal Host Controller",
2236 // Start the UHCI hardware, also set its reclamation point to 64 bytes
2238 UhciWriteReg (Uhc
->PciIo
, USBCMD_OFFSET
, USBCMD_RS
| USBCMD_MAXP
);
2246 gBS
->CloseProtocol (
2248 &gEfiPciIoProtocolGuid
,
2249 This
->DriverBindingHandle
,
2258 Stop this driver on ControllerHandle. Support stoping any child handles
2259 created by this driver.
2261 @param This Protocol instance pointer.
2262 @param Controller Handle of device to stop driver on
2263 @param NumberOfChildren Number of Children in the ChildHandleBuffer
2264 @param ChildHandleBuffer List of handles for the children we need to stop.
2272 UhciDriverBindingStop (
2273 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
2274 IN EFI_HANDLE Controller
,
2275 IN UINTN NumberOfChildren
,
2276 IN EFI_HANDLE
*ChildHandleBuffer
2279 EFI_USB_HC_PROTOCOL
*UsbHc
;
2280 EFI_USB2_HC_PROTOCOL
*Usb2Hc
;
2283 Status
= gBS
->OpenProtocol (
2285 &gEfiUsbHcProtocolGuid
,
2287 This
->DriverBindingHandle
,
2289 EFI_OPEN_PROTOCOL_GET_PROTOCOL
2292 // Test whether the Controller handler passed in is a valid
2293 // Usb controller handle that should be supported, if not,
2294 // return the error status directly
2296 if (EFI_ERROR (Status
)) {
2300 Status
= gBS
->OpenProtocol (
2302 &gEfiUsb2HcProtocolGuid
,
2304 This
->DriverBindingHandle
,
2306 EFI_OPEN_PROTOCOL_GET_PROTOCOL
2310 // Test whether the Controller handler passed in is a valid
2311 // Usb controller handle that should be supported, if not,
2312 // return the error status directly
2314 if (EFI_ERROR (Status
)) {
2318 UhciCleanDevUp (Controller
, UsbHc
);
2320 gBS
->CloseProtocol (
2322 &gEfiPciIoProtocolGuid
,
2323 This
->DriverBindingHandle
,
2330 EFI_DRIVER_BINDING_PROTOCOL gUhciDriverBinding
= {
2331 UhciDriverBindingSupported
,
2332 UhciDriverBindingStart
,
2333 UhciDriverBindingStop
,