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
= (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
= (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
= (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
;
1831 //@MT: EFI_DRIVER_ENTRY_POINT (UhciDriverEntryPoint)
1835 UhciDriverEntryPoint (
1836 IN EFI_HANDLE ImageHandle
,
1837 IN EFI_SYSTEM_TABLE
*SystemTable
1841 Routine Description:
1843 Entry point for EFI drivers.
1847 ImageHandle - EFI_HANDLE
1848 SystemTable - EFI_SYSTEM_TABLE
1852 EFI_SUCCESS : Driver is successfully loaded
1857 return EfiLibInstallAllDriverProtocols (
1860 &gUhciDriverBinding
,
1862 &gUhciComponentName
,
1870 Test to see if this driver supports ControllerHandle. Any
1871 ControllerHandle that has UsbHcProtocol installed will be supported.
1873 @param This Protocol instance pointer.
1874 @param Controller Handle of device to test
1875 @param RemainingDevicePath Not used
1877 @return EFI_SUCCESS : This driver supports this device.
1878 @return EFI_UNSUPPORTED : This driver does not support this device.
1883 UhciDriverBindingSupported (
1884 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1885 IN EFI_HANDLE Controller
,
1886 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
1889 EFI_STATUS OpenStatus
;
1891 EFI_PCI_IO_PROTOCOL
*PciIo
;
1892 USB_CLASSC UsbClassCReg
;
1895 // Test whether there is PCI IO Protocol attached on the controller handle.
1897 OpenStatus
= gBS
->OpenProtocol (
1899 &gEfiPciIoProtocolGuid
,
1901 This
->DriverBindingHandle
,
1903 EFI_OPEN_PROTOCOL_BY_DRIVER
1906 if (EFI_ERROR (OpenStatus
)) {
1910 Status
= PciIo
->Pci
.Read (
1914 sizeof (USB_CLASSC
) / sizeof (UINT8
),
1918 if (EFI_ERROR (Status
)) {
1919 Status
= EFI_UNSUPPORTED
;
1924 // Test whether the controller belongs to UHCI type
1926 if ((UsbClassCReg
.BaseCode
!= PCI_CLASS_SERIAL
) ||
1927 (UsbClassCReg
.SubClassCode
!= PCI_CLASS_SERIAL_USB
) ||
1928 (UsbClassCReg
.PI
!= PCI_CLASSC_PI_UHCI
)
1931 Status
= EFI_UNSUPPORTED
;
1935 gBS
->CloseProtocol (
1937 &gEfiPciIoProtocolGuid
,
1938 This
->DriverBindingHandle
,
1948 Allocate and initialize the empty UHCI device
1950 @param PciIo The PCIIO to use
1952 @return Allocated UHCI device
1958 IN EFI_PCI_IO_PROTOCOL
*PciIo
1964 Uhc
= AllocateZeroPool (sizeof (USB_HC_DEV
));
1971 // This driver supports both USB_HC_PROTOCOL and USB2_HC_PROTOCOL.
1972 // USB_HC_PROTOCOL is for EFI 1.1 backward compability.
1974 Uhc
->Signature
= USB_HC_DEV_SIGNATURE
;
1975 Uhc
->UsbHc
.Reset
= UhciReset
;
1976 Uhc
->UsbHc
.GetState
= UhciGetState
;
1977 Uhc
->UsbHc
.SetState
= UhciSetState
;
1978 Uhc
->UsbHc
.ControlTransfer
= UhciControlTransfer
;
1979 Uhc
->UsbHc
.BulkTransfer
= UhciBulkTransfer
;
1980 Uhc
->UsbHc
.AsyncInterruptTransfer
= UhciAsyncInterruptTransfer
;
1981 Uhc
->UsbHc
.SyncInterruptTransfer
= UhciSyncInterruptTransfer
;
1982 Uhc
->UsbHc
.IsochronousTransfer
= UhciIsochronousTransfer
;
1983 Uhc
->UsbHc
.AsyncIsochronousTransfer
= UhciAsyncIsochronousTransfer
;
1984 Uhc
->UsbHc
.GetRootHubPortNumber
= UhciGetRootHubPortNumber
;
1985 Uhc
->UsbHc
.GetRootHubPortStatus
= UhciGetRootHubPortStatus
;
1986 Uhc
->UsbHc
.SetRootHubPortFeature
= UhciSetRootHubPortFeature
;
1987 Uhc
->UsbHc
.ClearRootHubPortFeature
= UhciClearRootHubPortFeature
;
1988 Uhc
->UsbHc
.MajorRevision
= 0x1;
1989 Uhc
->UsbHc
.MinorRevision
= 0x1;
1991 Uhc
->Usb2Hc
.GetCapability
= Uhci2GetCapability
;
1992 Uhc
->Usb2Hc
.Reset
= Uhci2Reset
;
1993 Uhc
->Usb2Hc
.GetState
= Uhci2GetState
;
1994 Uhc
->Usb2Hc
.SetState
= Uhci2SetState
;
1995 Uhc
->Usb2Hc
.ControlTransfer
= Uhci2ControlTransfer
;
1996 Uhc
->Usb2Hc
.BulkTransfer
= Uhci2BulkTransfer
;
1997 Uhc
->Usb2Hc
.AsyncInterruptTransfer
= Uhci2AsyncInterruptTransfer
;
1998 Uhc
->Usb2Hc
.SyncInterruptTransfer
= Uhci2SyncInterruptTransfer
;
1999 Uhc
->Usb2Hc
.IsochronousTransfer
= Uhci2IsochronousTransfer
;
2000 Uhc
->Usb2Hc
.AsyncIsochronousTransfer
= Uhci2AsyncIsochronousTransfer
;
2001 Uhc
->Usb2Hc
.GetRootHubPortStatus
= Uhci2GetRootHubPortStatus
;
2002 Uhc
->Usb2Hc
.SetRootHubPortFeature
= Uhci2SetRootHubPortFeature
;
2003 Uhc
->Usb2Hc
.ClearRootHubPortFeature
= Uhci2ClearRootHubPortFeature
;
2004 Uhc
->Usb2Hc
.MajorRevision
= 0x1;
2005 Uhc
->Usb2Hc
.MinorRevision
= 0x1;
2008 Uhc
->MemPool
= UsbHcInitMemPool (PciIo
, TRUE
, 0);
2010 if (Uhc
->MemPool
== NULL
) {
2011 Status
= EFI_OUT_OF_RESOURCES
;
2015 InitializeListHead (&Uhc
->AsyncIntList
);
2017 Status
= gBS
->CreateEvent (
2018 EVT_TIMER
| EVT_NOTIFY_SIGNAL
,
2020 UhciMonitorAsyncReqList
,
2022 &Uhc
->AsyncIntMonitor
2025 if (EFI_ERROR (Status
)) {
2026 UsbHcFreeMemPool (Uhc
->MemPool
);
2033 gBS
->FreePool (Uhc
);
2039 Free the UHCI device and release its associated resources
2041 @param Uhc The UHCI device to release
2052 if (Uhc
->AsyncIntMonitor
!= NULL
) {
2053 gBS
->CloseEvent (Uhc
->AsyncIntMonitor
);
2056 if (Uhc
->MemPool
!= NULL
) {
2057 UsbHcFreeMemPool (Uhc
->MemPool
);
2060 if (Uhc
->CtrlNameTable
) {
2061 FreeUnicodeStringTable (Uhc
->CtrlNameTable
);
2064 gBS
->FreePool (Uhc
);
2069 Uninstall all Uhci Interface
2071 @param Controller Controller handle
2072 @param This Protocol instance pointer.
2080 IN EFI_HANDLE Controller
,
2081 IN EFI_USB_HC_PROTOCOL
*This
2087 // Uninstall the USB_HC and USB_HC2 protocol, then disable the controller
2089 Uhc
= UHC_FROM_USB_HC_PROTO (This
);
2090 UhciStopHc (Uhc
, STALL_1_SECOND
);
2092 gBS
->UninstallProtocolInterface (
2094 &gEfiUsbHcProtocolGuid
,
2098 gBS
->UninstallProtocolInterface (
2100 &gEfiUsb2HcProtocolGuid
,
2104 UhciFreeAllAsyncReq (Uhc
);
2105 UhciDestoryFrameList (Uhc
);
2107 Uhc
->PciIo
->Attributes (
2109 EfiPciIoAttributeOperationDisable
,
2110 EFI_PCI_DEVICE_ENABLE
,
2119 Starting the Usb UHCI Driver
2121 @param This Protocol instance pointer.
2122 @param Controller Handle of device to test
2123 @param RemainingDevicePath Not used
2125 @retval EFI_SUCCESS This driver supports this device.
2126 @retval EFI_UNSUPPORTED This driver does not support this device.
2127 @retval EFI_DEVICE_ERROR This driver cannot be started due to device Error
2128 EFI_OUT_OF_RESOURCES- Failed due to resource
2134 UhciDriverBindingStart (
2135 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
2136 IN EFI_HANDLE Controller
,
2137 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
2141 EFI_PCI_IO_PROTOCOL
*PciIo
;
2145 // Open PCIIO, then enable the EHC device and turn off emulation
2148 Status
= gBS
->OpenProtocol (
2150 &gEfiPciIoProtocolGuid
,
2152 This
->DriverBindingHandle
,
2154 EFI_OPEN_PROTOCOL_BY_DRIVER
2157 if (EFI_ERROR (Status
)) {
2161 UhciTurnOffUsbEmulation (PciIo
);
2163 Status
= PciIo
->Attributes (
2165 EfiPciIoAttributeOperationEnable
,
2166 EFI_PCI_DEVICE_ENABLE
,
2170 if (EFI_ERROR (Status
)) {
2174 Uhc
= UhciAllocateDev (PciIo
);
2177 Status
= EFI_OUT_OF_RESOURCES
;
2182 // Allocate and Init Host Controller's Frame List Entry
2184 Status
= UhciInitFrameList (Uhc
);
2186 if (EFI_ERROR (Status
)) {
2187 Status
= EFI_OUT_OF_RESOURCES
;
2191 Status
= gBS
->SetTimer (
2192 Uhc
->AsyncIntMonitor
,
2194 INTERRUPT_POLLING_TIME
2197 if (EFI_ERROR (Status
)) {
2202 // Install both USB_HC_PROTOCOL and USB2_HC_PROTOCOL
2204 Status
= gBS
->InstallMultipleProtocolInterfaces (
2206 &gEfiUsbHcProtocolGuid
,
2208 &gEfiUsb2HcProtocolGuid
,
2213 if (EFI_ERROR (Status
)) {
2218 // Install the component name protocol
2220 Uhc
->CtrlNameTable
= NULL
;
2224 gUhciComponentName
.SupportedLanguages
,
2225 &Uhc
->CtrlNameTable
,
2226 L
"Usb Universal Host Controller"
2230 // Start the UHCI hardware, also set its reclamation point to 64 bytes
2232 UhciWriteReg (Uhc
->PciIo
, USBCMD_OFFSET
, USBCMD_RS
| USBCMD_MAXP
);
2240 gBS
->CloseProtocol (
2242 &gEfiPciIoProtocolGuid
,
2243 This
->DriverBindingHandle
,
2252 Stop this driver on ControllerHandle. Support stoping any child handles
2253 created by this driver.
2255 @param This Protocol instance pointer.
2256 @param Controller Handle of device to stop driver on
2257 @param NumberOfChildren Number of Children in the ChildHandleBuffer
2258 @param ChildHandleBuffer List of handles for the children we need to stop.
2266 UhciDriverBindingStop (
2267 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
2268 IN EFI_HANDLE Controller
,
2269 IN UINTN NumberOfChildren
,
2270 IN EFI_HANDLE
*ChildHandleBuffer
2273 EFI_USB_HC_PROTOCOL
*UsbHc
;
2274 EFI_USB2_HC_PROTOCOL
*Usb2Hc
;
2277 Status
= gBS
->OpenProtocol (
2279 &gEfiUsbHcProtocolGuid
,
2281 This
->DriverBindingHandle
,
2283 EFI_OPEN_PROTOCOL_GET_PROTOCOL
2286 // Test whether the Controller handler passed in is a valid
2287 // Usb controller handle that should be supported, if not,
2288 // return the error status directly
2290 if (EFI_ERROR (Status
)) {
2294 Status
= gBS
->OpenProtocol (
2296 &gEfiUsb2HcProtocolGuid
,
2298 This
->DriverBindingHandle
,
2300 EFI_OPEN_PROTOCOL_GET_PROTOCOL
2304 // Test whether the Controller handler passed in is a valid
2305 // Usb controller handle that should be supported, if not,
2306 // return the error status directly
2308 if (EFI_ERROR (Status
)) {
2312 UhciCleanDevUp (Controller
, UsbHc
);
2314 gBS
->CloseProtocol (
2316 &gEfiPciIoProtocolGuid
,
2317 This
->DriverBindingHandle
,
2324 EFI_DRIVER_BINDING_PROTOCOL gUhciDriverBinding
= {
2325 UhciDriverBindingSupported
,
2326 UhciDriverBindingStart
,
2327 UhciDriverBindingStop
,