3 Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
4 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 Our DriverBinding member functions operate on the handles
19 created by the NT Bus driver.
21 Handle(1) - WinNtIo - DevicePath(1)
23 If a serial port is added to the system this driver creates a new handle.
24 The new handle is required, since the serial device must add an UART device
27 Handle(2) - SerialIo - DevicePath(1)\UART
29 The driver then adds a gEfiWinNtSerialPortGuid as a protocol to Handle(1).
30 The instance data for this protocol is the private data used to create
33 Handle(1) - WinNtIo - DevicePath(1) - WinNtSerialPort
35 If the driver is unloaded Handle(2) is removed from the system and
36 gEfiWinNtSerialPortGuid is removed from Handle(1).
38 Note: Handle(1) is any handle created by the Win NT Bus driver that is passed
39 into the DriverBinding member functions of this driver. This driver requires
40 a Handle(1) to contain a WinNtIo protocol, a DevicePath protocol, and
41 the TypeGuid in the WinNtIo must be gEfiWinNtSerialPortGuid.
43 If Handle(1) contains a gEfiWinNtSerialPortGuid protocol then the driver is
48 #include "WinNtSerialIo.h"
50 EFI_DRIVER_BINDING_PROTOCOL gWinNtSerialIoDriverBinding
= {
51 WinNtSerialIoDriverBindingSupported
,
52 WinNtSerialIoDriverBindingStart
,
53 WinNtSerialIoDriverBindingStop
,
60 // List of supported baud rate
62 UINT64 mBaudRateCurrentSupport
[] = {50, 75, 110, 134, 150, 300, 600, 1200, 1800, 2000, 2400, 3600, 4800, 7200, 9600, 19200, 38400, 57600, 115200, SERIAL_PORT_MAX_BAUD_RATE
+ 1};
65 Check the device path node whether it's the Flow Control node or not.
67 @param[in] FlowControl The device path node to be checked.
69 @retval TRUE It's the Flow Control node.
70 @retval FALSE It's not.
74 IsUartFlowControlNode (
75 IN UART_FLOW_CONTROL_DEVICE_PATH
*FlowControl
79 (DevicePathType (FlowControl
) == MESSAGING_DEVICE_PATH
) &&
80 (DevicePathSubType (FlowControl
) == MSG_VENDOR_DP
) &&
81 (CompareGuid (&FlowControl
->Guid
, &gEfiUartDevicePathGuid
))
86 Check the device path node whether it contains Flow Control node or not.
88 @param[in] DevicePath The device path to be checked.
90 @retval TRUE It contains the Flow Control node.
91 @retval FALSE It doesn't.
96 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
99 while (!IsDevicePathEnd (DevicePath
)) {
100 if (IsUartFlowControlNode ((UART_FLOW_CONTROL_DEVICE_PATH
*) DevicePath
)) {
103 DevicePath
= NextDevicePathNode (DevicePath
);
110 The user Entry Point for module WinNtSerialIo. The user code starts with this function.
112 @param[in] ImageHandle The firmware allocated handle for the EFI image.
113 @param[in] SystemTable A pointer to the EFI System Table.
115 @retval EFI_SUCCESS The entry point is executed successfully.
116 @retval other Some error occurs when executing this entry point.
121 InitializeWinNtSerialIo(
122 IN EFI_HANDLE ImageHandle
,
123 IN EFI_SYSTEM_TABLE
*SystemTable
129 // Install driver model protocol(s).
131 Status
= EfiLibInstallDriverBindingComponentName2 (
134 &gWinNtSerialIoDriverBinding
,
136 &gWinNtSerialIoComponentName
,
137 &gWinNtSerialIoComponentName2
139 ASSERT_EFI_ERROR (Status
);
147 WinNtSerialIoDriverBindingSupported (
148 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
149 IN EFI_HANDLE Handle
,
150 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
163 // TODO: This - add argument and description to function comment
164 // TODO: Handle - add argument and description to function comment
165 // TODO: RemainingDevicePath - add argument and description to function comment
166 // TODO: EFI_SUCCESS - add return value to function comment
167 // TODO: EFI_SUCCESS - add return value to function comment
170 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
171 EFI_WIN_NT_IO_PROTOCOL
*WinNtIo
;
172 UART_DEVICE_PATH
*UartNode
;
173 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
174 UART_FLOW_CONTROL_DEVICE_PATH
*FlowControlNode
;
175 EFI_OPEN_PROTOCOL_INFORMATION_ENTRY
*OpenInfoBuffer
;
178 BOOLEAN RemainingDevicePathContainsFlowControl
;
181 // Check RemainingDevicePath validation
183 if (RemainingDevicePath
!= NULL
) {
185 // Check if RemainingDevicePath is the End of Device Path Node,
186 // if yes, go on checking other conditions
188 if (!IsDevicePathEnd (RemainingDevicePath
)) {
190 // If RemainingDevicePath isn't the End of Device Path Node,
191 // check its validation
193 Status
= EFI_UNSUPPORTED
;
195 UartNode
= (UART_DEVICE_PATH
*) RemainingDevicePath
;
196 if (UartNode
->Header
.Type
!= MESSAGING_DEVICE_PATH
||
197 UartNode
->Header
.SubType
!= MSG_UART_DP
||
198 DevicePathNodeLength((EFI_DEVICE_PATH_PROTOCOL
*)UartNode
) != sizeof(UART_DEVICE_PATH
)) {
201 if ( UartNode
->BaudRate
> SERIAL_PORT_MAX_BAUD_RATE
) {
204 if (UartNode
->Parity
< NoParity
|| UartNode
->Parity
> SpaceParity
) {
207 if (UartNode
->DataBits
< 5 || UartNode
->DataBits
> 8) {
210 if (UartNode
->StopBits
< OneStopBit
|| UartNode
->StopBits
> TwoStopBits
) {
213 if ((UartNode
->DataBits
== 5) && (UartNode
->StopBits
== TwoStopBits
)) {
216 if ((UartNode
->DataBits
>= 6) && (UartNode
->DataBits
<= 8) && (UartNode
->StopBits
== OneFiveStopBits
)) {
220 FlowControlNode
= (UART_FLOW_CONTROL_DEVICE_PATH
*) NextDevicePathNode (UartNode
);
221 if (IsUartFlowControlNode (FlowControlNode
)) {
223 // If the second node is Flow Control Node,
224 // return error when it request other than hardware flow control.
226 if ((FlowControlNode
->FlowControlMap
& ~UART_FLOW_CONTROL_HARDWARE
) != 0) {
234 // Open the IO Abstraction(s) needed to perform the supported test
236 Status
= gBS
->OpenProtocol (
238 &gEfiWinNtIoProtocolGuid
,
240 This
->DriverBindingHandle
,
242 EFI_OPEN_PROTOCOL_BY_DRIVER
244 if (Status
== EFI_ALREADY_STARTED
) {
245 if (RemainingDevicePath
== NULL
|| IsDevicePathEnd (RemainingDevicePath
)) {
247 // If RemainingDevicePath is NULL or is the End of Device Path Node
252 // When the driver has produced device path with flow control node but RemainingDevicePath only contains UART node,
253 // return unsupported, and vice versa.
255 Status
= gBS
->OpenProtocolInformation (
257 &gEfiWinNtIoProtocolGuid
,
261 if (EFI_ERROR (Status
)) {
266 // See if RemainingDevicePath has a Flow Control device path node
268 RemainingDevicePathContainsFlowControl
= ContainsFlowControl (RemainingDevicePath
);
270 for (Index
= 0; Index
< EntryCount
; Index
++) {
271 if ((OpenInfoBuffer
[Index
].Attributes
& EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
) != 0) {
272 Status
= gBS
->OpenProtocol (
273 OpenInfoBuffer
[Index
].ControllerHandle
,
274 &gEfiDevicePathProtocolGuid
,
275 (VOID
**) &DevicePath
,
276 This
->DriverBindingHandle
,
278 EFI_OPEN_PROTOCOL_GET_PROTOCOL
280 if (!EFI_ERROR (Status
)) {
281 if (RemainingDevicePathContainsFlowControl
^ ContainsFlowControl (DevicePath
)) {
282 Status
= EFI_UNSUPPORTED
;
288 FreePool (OpenInfoBuffer
);
292 if (EFI_ERROR (Status
)) {
297 // Close the I/O Abstraction(s) used to perform the supported test
301 &gEfiWinNtIoProtocolGuid
,
302 This
->DriverBindingHandle
,
307 // Open the EFI Device Path protocol needed to perform the supported test
309 Status
= gBS
->OpenProtocol (
311 &gEfiDevicePathProtocolGuid
,
312 (VOID
**) &ParentDevicePath
,
313 This
->DriverBindingHandle
,
315 EFI_OPEN_PROTOCOL_BY_DRIVER
317 if (Status
== EFI_ALREADY_STARTED
) {
321 if (EFI_ERROR (Status
)) {
326 // Close protocol, don't use device path protocol in the Support() function
330 &gEfiDevicePathProtocolGuid
,
331 This
->DriverBindingHandle
,
336 // Make sure that the WinNt Thunk Protocol is valid
338 if (WinNtIo
->WinNtThunk
->Signature
!= EFI_WIN_NT_THUNK_PROTOCOL_SIGNATURE
) {
339 Status
= EFI_UNSUPPORTED
;
344 // Check the GUID to see if this is a handle type the driver supports
346 if (!CompareGuid (WinNtIo
->TypeGuid
, &gEfiWinNtSerialPortGuid
)) {
347 Status
= EFI_UNSUPPORTED
;
359 WinNtSerialIoDriverBindingStart (
360 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
361 IN EFI_HANDLE Handle
,
362 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
375 // TODO: This - add argument and description to function comment
376 // TODO: Handle - add argument and description to function comment
377 // TODO: RemainingDevicePath - add argument and description to function comment
378 // TODO: EFI_SUCCESS - add return value to function comment
379 // TODO: EFI_SUCCESS - add return value to function comment
382 EFI_WIN_NT_IO_PROTOCOL
*WinNtIo
;
383 WIN_NT_SERIAL_IO_PRIVATE_DATA
*Private
;
385 UART_DEVICE_PATH UartNode
;
386 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
387 EFI_OPEN_PROTOCOL_INFORMATION_ENTRY
*OpenInfoBuffer
;
390 EFI_SERIAL_IO_PROTOCOL
*SerialIo
;
391 UART_DEVICE_PATH
*Uart
;
392 UINT32 FlowControlMap
;
393 UART_FLOW_CONTROL_DEVICE_PATH
*FlowControl
;
394 EFI_DEVICE_PATH_PROTOCOL
*TempDevicePath
;
398 NtHandle
= INVALID_HANDLE_VALUE
;
401 // Get the Parent Device Path
403 Status
= gBS
->OpenProtocol (
405 &gEfiDevicePathProtocolGuid
,
406 (VOID
**) &ParentDevicePath
,
407 This
->DriverBindingHandle
,
409 EFI_OPEN_PROTOCOL_BY_DRIVER
411 if (EFI_ERROR (Status
) && Status
!= EFI_ALREADY_STARTED
) {
416 // Grab the IO abstraction we need to get any work done
418 Status
= gBS
->OpenProtocol (
420 &gEfiWinNtIoProtocolGuid
,
422 This
->DriverBindingHandle
,
424 EFI_OPEN_PROTOCOL_BY_DRIVER
426 if (EFI_ERROR (Status
) && Status
!= EFI_ALREADY_STARTED
) {
429 &gEfiDevicePathProtocolGuid
,
430 This
->DriverBindingHandle
,
436 if (Status
== EFI_ALREADY_STARTED
) {
438 if (RemainingDevicePath
== NULL
|| IsDevicePathEnd (RemainingDevicePath
)) {
440 // If RemainingDevicePath is NULL or is the End of Device Path Node
446 // Make sure a child handle does not already exist. This driver can only
447 // produce one child per serial port.
449 Status
= gBS
->OpenProtocolInformation (
451 &gEfiWinNtIoProtocolGuid
,
455 if (EFI_ERROR (Status
)) {
459 Status
= EFI_ALREADY_STARTED
;
460 for (Index
= 0; Index
< EntryCount
; Index
++) {
461 if ((OpenInfoBuffer
[Index
].Attributes
& EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
) != 0) {
462 Status
= gBS
->OpenProtocol (
463 OpenInfoBuffer
[Index
].ControllerHandle
,
464 &gEfiSerialIoProtocolGuid
,
466 This
->DriverBindingHandle
,
468 EFI_OPEN_PROTOCOL_GET_PROTOCOL
470 if (!EFI_ERROR (Status
)) {
471 Uart
= (UART_DEVICE_PATH
*) RemainingDevicePath
;
472 Status
= SerialIo
->SetAttributes (
475 SerialIo
->Mode
->ReceiveFifoDepth
,
476 SerialIo
->Mode
->Timeout
,
477 (EFI_PARITY_TYPE
) Uart
->Parity
,
479 (EFI_STOP_BITS_TYPE
) Uart
->StopBits
481 FlowControl
= (UART_FLOW_CONTROL_DEVICE_PATH
*) NextDevicePathNode (Uart
);
482 if (!EFI_ERROR (Status
) && IsUartFlowControlNode (FlowControl
)) {
483 Status
= SerialIo
->GetControl (SerialIo
, &Control
);
484 if (!EFI_ERROR (Status
)) {
485 if (FlowControl
->FlowControlMap
== UART_FLOW_CONTROL_HARDWARE
) {
486 Control
|= EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE
;
488 Control
&= ~EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE
;
491 // Clear the bits that are not allowed to pass to SetControl
493 Control
&= (EFI_SERIAL_REQUEST_TO_SEND
| EFI_SERIAL_DATA_TERMINAL_READY
|
494 EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE
| EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE
|
495 EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE
);
496 Status
= SerialIo
->SetControl (SerialIo
, Control
);
504 FreePool (OpenInfoBuffer
);
510 if (RemainingDevicePath
== NULL
) {
512 // Build the device path by appending the UART node to the ParentDevicePath
513 // from the WinNtIo handle. The Uart setings are zero here, since
514 // SetAttribute() will update them to match the default setings.
516 ZeroMem (&UartNode
, sizeof (UART_DEVICE_PATH
));
517 UartNode
.Header
.Type
= MESSAGING_DEVICE_PATH
;
518 UartNode
.Header
.SubType
= MSG_UART_DP
;
519 SetDevicePathNodeLength ((EFI_DEVICE_PATH_PROTOCOL
*) &UartNode
, sizeof (UART_DEVICE_PATH
));
521 } else if (!IsDevicePathEnd (RemainingDevicePath
)) {
523 // If RemainingDevicePath isn't the End of Device Path Node,
524 // only scan the specified device by RemainingDevicePath
527 // Match the configuration of the RemainingDevicePath. IsHandleSupported()
528 // already checked to make sure the RemainingDevicePath contains settings
529 // that we can support.
531 CopyMem (&UartNode
, RemainingDevicePath
, sizeof (UART_DEVICE_PATH
));
532 FlowControl
= (UART_FLOW_CONTROL_DEVICE_PATH
*) NextDevicePathNode (RemainingDevicePath
);
533 if (IsUartFlowControlNode (FlowControl
)) {
534 FlowControlMap
= FlowControl
->FlowControlMap
;
541 // If RemainingDevicePath is the End of Device Path Node,
542 // skip enumerate any device and return EFI_SUCESSS
548 // Check to see if we can access the hardware device. If it's Open in NT we
549 // will not get access.
551 NtHandle
= WinNtIo
->WinNtThunk
->CreateFile (
553 GENERIC_READ
| GENERIC_WRITE
,
560 if (NtHandle
== INVALID_HANDLE_VALUE
) {
561 Status
= EFI_DEVICE_ERROR
;
566 // Construct Private data
568 Private
= AllocatePool (sizeof (WIN_NT_SERIAL_IO_PRIVATE_DATA
));
569 if (Private
== NULL
) {
574 // This signature must be valid before any member function is called
576 Private
->Signature
= WIN_NT_SERIAL_IO_PRIVATE_DATA_SIGNATURE
;
577 Private
->NtHandle
= NtHandle
;
578 Private
->ControllerHandle
= Handle
;
579 Private
->Handle
= NULL
;
580 Private
->WinNtThunk
= WinNtIo
->WinNtThunk
;
581 Private
->ParentDevicePath
= ParentDevicePath
;
582 Private
->ControllerNameTable
= NULL
;
584 Private
->SoftwareLoopbackEnable
= FALSE
;
585 Private
->HardwareLoopbackEnable
= FALSE
;
586 Private
->HardwareFlowControl
= (BOOLEAN
) (FlowControlMap
== UART_FLOW_CONTROL_HARDWARE
);
587 Private
->Fifo
.First
= 0;
588 Private
->Fifo
.Last
= 0;
589 Private
->Fifo
.Surplus
= SERIAL_MAX_BUFFER_SIZE
;
591 CopyMem (&Private
->UartDevicePath
, &UartNode
, sizeof (UART_DEVICE_PATH
));
595 gWinNtSerialIoComponentName
.SupportedLanguages
,
596 &Private
->ControllerNameTable
,
602 gWinNtSerialIoComponentName2
.SupportedLanguages
,
603 &Private
->ControllerNameTable
,
609 Private
->SerialIo
.Revision
= SERIAL_IO_INTERFACE_REVISION
;
610 Private
->SerialIo
.Reset
= WinNtSerialIoReset
;
611 Private
->SerialIo
.SetAttributes
= WinNtSerialIoSetAttributes
;
612 Private
->SerialIo
.SetControl
= WinNtSerialIoSetControl
;
613 Private
->SerialIo
.GetControl
= WinNtSerialIoGetControl
;
614 Private
->SerialIo
.Write
= WinNtSerialIoWrite
;
615 Private
->SerialIo
.Read
= WinNtSerialIoRead
;
616 Private
->SerialIo
.Mode
= &Private
->SerialIoMode
;
619 // Build the device path by appending the UART node to the ParentDevicePath
620 // from the WinNtIo handle. The Uart setings are zero here, since
621 // SetAttribute() will update them to match the current setings.
623 Private
->DevicePath
= AppendDevicePathNode (
625 (EFI_DEVICE_PATH_PROTOCOL
*) &Private
->UartDevicePath
628 // Only produce the FlowControl node when remaining device path has it
630 if (FlowControl
!= NULL
) {
631 TempDevicePath
= Private
->DevicePath
;
632 if (TempDevicePath
!= NULL
) {
633 Private
->DevicePath
= AppendDevicePathNode (
635 (EFI_DEVICE_PATH_PROTOCOL
*) FlowControl
637 FreePool (TempDevicePath
);
640 if (Private
->DevicePath
== NULL
) {
641 Status
= EFI_OUT_OF_RESOURCES
;
646 // Fill in Serial I/O Mode structure based on either the RemainingDevicePath or defaults.
648 Private
->SerialIoMode
.ControlMask
= SERIAL_CONTROL_MASK
;
649 Private
->SerialIoMode
.Timeout
= SERIAL_TIMEOUT_DEFAULT
;
650 Private
->SerialIoMode
.BaudRate
= Private
->UartDevicePath
.BaudRate
;
651 Private
->SerialIoMode
.ReceiveFifoDepth
= SERIAL_FIFO_DEFAULT
;
652 Private
->SerialIoMode
.DataBits
= Private
->UartDevicePath
.DataBits
;
653 Private
->SerialIoMode
.Parity
= Private
->UartDevicePath
.Parity
;
654 Private
->SerialIoMode
.StopBits
= Private
->UartDevicePath
.StopBits
;
657 // Issue a reset to initialize the COM port
659 Status
= Private
->SerialIo
.Reset (&Private
->SerialIo
);
660 if (EFI_ERROR (Status
)) {
665 // Create new child handle
667 Status
= gBS
->InstallMultipleProtocolInterfaces (
669 &gEfiSerialIoProtocolGuid
,
671 &gEfiDevicePathProtocolGuid
,
675 if (EFI_ERROR (Status
)) {
680 // Open For Child Device
682 Status
= gBS
->OpenProtocol (
684 &gEfiWinNtIoProtocolGuid
,
686 This
->DriverBindingHandle
,
688 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
690 if (EFI_ERROR (Status
)) {
698 // Use the Stop() function to free all resources allocated in Start()
700 if (Private
!= NULL
) {
701 if (Private
->Handle
!= NULL
) {
702 This
->Stop (This
, Handle
, 1, &Private
->Handle
);
704 if (NtHandle
!= INVALID_HANDLE_VALUE
) {
705 Private
->WinNtThunk
->CloseHandle (NtHandle
);
708 if (Private
->DevicePath
!= NULL
) {
709 FreePool (Private
->DevicePath
);
712 FreeUnicodeStringTable (Private
->ControllerNameTable
);
718 This
->Stop (This
, Handle
, 0, NULL
);
725 WinNtSerialIoDriverBindingStop (
726 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
727 IN EFI_HANDLE Handle
,
728 IN UINTN NumberOfChildren
,
729 IN EFI_HANDLE
*ChildHandleBuffer
735 TODO: Add function description
739 This - TODO: add argument description
740 Handle - TODO: add argument description
741 NumberOfChildren - TODO: add argument description
742 ChildHandleBuffer - TODO: add argument description
746 EFI_DEVICE_ERROR - TODO: Add description for return value
747 EFI_SUCCESS - TODO: Add description for return value
753 BOOLEAN AllChildrenStopped
;
754 EFI_SERIAL_IO_PROTOCOL
*SerialIo
;
755 WIN_NT_SERIAL_IO_PRIVATE_DATA
*Private
;
756 EFI_WIN_NT_IO_PROTOCOL
*WinNtIo
;
759 // Complete all outstanding transactions to Controller.
760 // Don't allow any new transaction to Controller to be started.
763 if (NumberOfChildren
== 0) {
765 // Close the bus driver
767 Status
= gBS
->CloseProtocol (
769 &gEfiWinNtIoProtocolGuid
,
770 This
->DriverBindingHandle
,
773 Status
= gBS
->CloseProtocol (
775 &gEfiDevicePathProtocolGuid
,
776 This
->DriverBindingHandle
,
782 AllChildrenStopped
= TRUE
;
784 for (Index
= 0; Index
< NumberOfChildren
; Index
++) {
785 Status
= gBS
->OpenProtocol (
786 ChildHandleBuffer
[Index
],
787 &gEfiSerialIoProtocolGuid
,
789 This
->DriverBindingHandle
,
791 EFI_OPEN_PROTOCOL_GET_PROTOCOL
793 if (!EFI_ERROR (Status
)) {
794 Private
= WIN_NT_SERIAL_IO_PRIVATE_DATA_FROM_THIS (SerialIo
);
796 ASSERT (Private
->Handle
== ChildHandleBuffer
[Index
]);
798 Status
= gBS
->CloseProtocol (
800 &gEfiWinNtIoProtocolGuid
,
801 This
->DriverBindingHandle
,
802 ChildHandleBuffer
[Index
]
805 Status
= gBS
->UninstallMultipleProtocolInterfaces (
806 ChildHandleBuffer
[Index
],
807 &gEfiSerialIoProtocolGuid
,
809 &gEfiDevicePathProtocolGuid
,
814 if (EFI_ERROR (Status
)) {
817 &gEfiWinNtIoProtocolGuid
,
819 This
->DriverBindingHandle
,
820 ChildHandleBuffer
[Index
],
821 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
824 Private
->WinNtThunk
->CloseHandle (Private
->NtHandle
);
826 FreePool (Private
->DevicePath
);
828 FreeUnicodeStringTable (Private
->ControllerNameTable
);
834 if (EFI_ERROR (Status
)) {
835 AllChildrenStopped
= FALSE
;
839 if (!AllChildrenStopped
) {
840 return EFI_DEVICE_ERROR
;
847 // Serial IO Protocol member functions
853 IN EFI_SERIAL_IO_PROTOCOL
*This
859 TODO: Add function description
863 This - TODO: add argument description
867 TODO: add return values
871 WIN_NT_SERIAL_IO_PRIVATE_DATA
*Private
;
874 Tpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
876 Private
= WIN_NT_SERIAL_IO_PRIVATE_DATA_FROM_THIS (This
);
878 Private
->WinNtThunk
->PurgeComm (
880 PURGE_TXCLEAR
| PURGE_RXCLEAR
883 gBS
->RestoreTPL (Tpl
);
885 return This
->SetAttributes (
887 This
->Mode
->BaudRate
,
888 This
->Mode
->ReceiveFifoDepth
,
890 (EFI_PARITY_TYPE
)This
->Mode
->Parity
,
891 (UINT8
) This
->Mode
->DataBits
,
892 (EFI_STOP_BITS_TYPE
)This
->Mode
->StopBits
898 WinNtSerialIoSetAttributes (
899 IN EFI_SERIAL_IO_PROTOCOL
*This
,
901 IN UINT32 ReceiveFifoDepth
,
903 IN EFI_PARITY_TYPE Parity
,
905 IN EFI_STOP_BITS_TYPE StopBits
911 This function is used to set the attributes.
915 This - A pointer to the EFI_SERIAL_IO_PROTOCOL structrue.
916 BaudRate - The Baud rate of the serial device.
917 ReceiveFifoDepth - The request depth of fifo on receive side.
918 Timeout - the request timeout for a single charact.
919 Parity - The type of parity used in serial device.
920 DataBits - Number of deata bits used in serial device.
921 StopBits - Number of stop bits used in serial device.
929 // TODO: EFI_SUCCESS - add return value to function comment
930 // TODO: EFI_DEVICE_ERROR - add return value to function comment
931 // TODO: EFI_DEVICE_ERROR - add return value to function comment
932 // TODO: EFI_DEVICE_ERROR - add return value to function comment
933 // TODO: EFI_SUCCESS - add return value to function comment
934 // TODO: EFI_DEVICE_ERROR - add return value to function comment
935 // TODO: EFI_SUCCESS - add return value to function comment
939 WIN_NT_SERIAL_IO_PRIVATE_DATA
*Private
;
940 COMMTIMEOUTS PortTimeOuts
;
943 UART_DEVICE_PATH
*Uart
;
946 Private
= WIN_NT_SERIAL_IO_PRIVATE_DATA_FROM_THIS (This
);
949 // Some of our arguments have defaults if a null value is passed in, and
950 // we must set the default values if a null argument is passed in.
953 BaudRate
= PcdGet64 (PcdUartDefaultBaudRate
);
956 if (ReceiveFifoDepth
== 0) {
957 ReceiveFifoDepth
= SERIAL_FIFO_DEFAULT
;
961 Timeout
= SERIAL_TIMEOUT_DEFAULT
;
964 if (Parity
== DefaultParity
) {
965 Parity
= (EFI_PARITY_TYPE
) (PcdGet8 (PcdUartDefaultParity
));
969 DataBits
= PcdGet8 (PcdUartDefaultDataBits
);
972 if (StopBits
== DefaultStopBits
) {
973 StopBits
= (EFI_STOP_BITS_TYPE
) PcdGet8 (PcdUartDefaultStopBits
);
977 // Make sure all parameters are valid
979 if ((BaudRate
> SERIAL_PORT_MAX_BAUD_RATE
) || (BaudRate
< SERIAL_PORT_MIN_BAUD_RATE
)) {
980 return EFI_INVALID_PARAMETER
;
984 //The lower baud rate supported by the serial device will be selected without exceeding the unsupported BaudRate parameter
987 for (Index
= 1; Index
< (sizeof (mBaudRateCurrentSupport
) / sizeof (mBaudRateCurrentSupport
[0])); Index
++) {
988 if (BaudRate
< mBaudRateCurrentSupport
[Index
]) {
989 BaudRate
= mBaudRateCurrentSupport
[Index
-1];
994 if ((ReceiveFifoDepth
< 1) || (ReceiveFifoDepth
> SERIAL_PORT_MAX_RECEIVE_FIFO_DEPTH
)) {
995 return EFI_INVALID_PARAMETER
;
998 if ((Timeout
< SERIAL_PORT_MIN_TIMEOUT
) || (Timeout
> SERIAL_PORT_MAX_TIMEOUT
)) {
999 return EFI_INVALID_PARAMETER
;
1002 if ((Parity
< NoParity
) || (Parity
> SpaceParity
)) {
1003 return EFI_INVALID_PARAMETER
;
1006 if ((StopBits
< OneStopBit
) || (StopBits
> TwoStopBits
)) {
1007 return EFI_INVALID_PARAMETER
;
1011 // Now we only support DataBits=7,8.
1013 if ((DataBits
< 7) || (DataBits
> 8)) {
1014 return EFI_INVALID_PARAMETER
;
1018 // Now we only support DataBits=7,8.
1019 // for DataBits = 6,7,8, StopBits can not set OneFiveStopBits.
1021 if (StopBits
== OneFiveStopBits
) {
1022 return EFI_INVALID_PARAMETER
;
1026 // See if the new attributes already match the current attributes
1028 if (Private
->UartDevicePath
.BaudRate
== BaudRate
&&
1029 Private
->UartDevicePath
.DataBits
== DataBits
&&
1030 Private
->UartDevicePath
.Parity
== Parity
&&
1031 Private
->UartDevicePath
.StopBits
== StopBits
&&
1032 Private
->SerialIoMode
.ReceiveFifoDepth
== ReceiveFifoDepth
&&
1033 Private
->SerialIoMode
.Timeout
== Timeout
) {
1037 Tpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1040 // Get current values from NT
1042 ZeroMem (&Private
->NtDCB
, sizeof (DCB
));
1043 Private
->NtDCB
.DCBlength
= sizeof (DCB
);
1045 if (!Private
->WinNtThunk
->GetCommState (Private
->NtHandle
, &Private
->NtDCB
)) {
1046 Private
->NtError
= Private
->WinNtThunk
->GetLastError ();
1047 DEBUG ((EFI_D_ERROR
, "SerialSetAttributes: GetCommState %d\n", Private
->NtError
));
1048 gBS
->RestoreTPL (Tpl
);
1049 return EFI_DEVICE_ERROR
;
1053 // Map EFI com setting to NT
1055 Private
->NtDCB
.BaudRate
= ConvertBaud2Nt (BaudRate
);
1056 Private
->NtDCB
.ByteSize
= ConvertData2Nt (DataBits
);
1057 Private
->NtDCB
.Parity
= ConvertParity2Nt (Parity
);
1058 Private
->NtDCB
.StopBits
= ConvertStop2Nt (StopBits
);
1060 Private
->NtDCB
.fBinary
= TRUE
;
1061 Private
->NtDCB
.fParity
= Private
->NtDCB
.Parity
== NOPARITY
? FALSE
: TRUE
;
1062 Private
->NtDCB
.fOutxCtsFlow
= FALSE
;
1063 Private
->NtDCB
.fOutxDsrFlow
= FALSE
;
1064 Private
->NtDCB
.fDtrControl
= DTR_CONTROL_ENABLE
;
1065 Private
->NtDCB
.fDsrSensitivity
= FALSE
;
1066 Private
->NtDCB
.fOutX
= FALSE
;
1067 Private
->NtDCB
.fInX
= FALSE
;
1068 Private
->NtDCB
.fRtsControl
= RTS_CONTROL_ENABLE
;
1069 Private
->NtDCB
.fNull
= FALSE
;
1074 Result
= Private
->WinNtThunk
->SetCommState (Private
->NtHandle
, &Private
->NtDCB
);
1076 Private
->NtError
= Private
->WinNtThunk
->GetLastError ();
1077 DEBUG ((EFI_D_ERROR
, "SerialSetAttributes: SetCommState %d\n", Private
->NtError
));
1078 gBS
->RestoreTPL (Tpl
);
1079 return EFI_DEVICE_ERROR
;
1083 // Set com port read/write timeout values
1085 ConvertedTime
= ConvertTime2Nt (Timeout
);
1086 PortTimeOuts
.ReadIntervalTimeout
= MAXDWORD
;
1087 PortTimeOuts
.ReadTotalTimeoutMultiplier
= 0;
1088 PortTimeOuts
.ReadTotalTimeoutConstant
= ConvertedTime
;
1089 PortTimeOuts
.WriteTotalTimeoutMultiplier
= ConvertedTime
== 0 ? 1 : ConvertedTime
;
1090 PortTimeOuts
.WriteTotalTimeoutConstant
= 0;
1092 if (!Private
->WinNtThunk
->SetCommTimeouts (Private
->NtHandle
, &PortTimeOuts
)) {
1093 Private
->NtError
= Private
->WinNtThunk
->GetLastError ();
1094 DEBUG ((EFI_D_ERROR
, "SerialSetAttributes: SetCommTimeouts %d\n", Private
->NtError
));
1095 gBS
->RestoreTPL (Tpl
);
1096 return EFI_DEVICE_ERROR
;
1102 Private
->SerialIoMode
.BaudRate
= BaudRate
;
1103 Private
->SerialIoMode
.ReceiveFifoDepth
= ReceiveFifoDepth
;
1104 Private
->SerialIoMode
.Timeout
= Timeout
;
1105 Private
->SerialIoMode
.Parity
= Parity
;
1106 Private
->SerialIoMode
.DataBits
= DataBits
;
1107 Private
->SerialIoMode
.StopBits
= StopBits
;
1110 // See if Device Path Node has actually changed
1112 if (Private
->UartDevicePath
.BaudRate
== BaudRate
&&
1113 Private
->UartDevicePath
.DataBits
== DataBits
&&
1114 Private
->UartDevicePath
.Parity
== Parity
&&
1115 Private
->UartDevicePath
.StopBits
== StopBits
) {
1116 gBS
->RestoreTPL(Tpl
);
1121 // Update the device path
1123 Private
->UartDevicePath
.BaudRate
= BaudRate
;
1124 Private
->UartDevicePath
.DataBits
= DataBits
;
1125 Private
->UartDevicePath
.Parity
= (UINT8
) Parity
;
1126 Private
->UartDevicePath
.StopBits
= (UINT8
) StopBits
;
1128 Status
= EFI_SUCCESS
;
1129 if (Private
->Handle
!= NULL
) {
1130 Uart
= (UART_DEVICE_PATH
*) (
1131 (UINTN
) Private
->DevicePath
1132 + GetDevicePathSize (Private
->ParentDevicePath
)
1133 - END_DEVICE_PATH_LENGTH
1135 CopyMem (Uart
, &Private
->UartDevicePath
, sizeof (UART_DEVICE_PATH
));
1136 Status
= gBS
->ReinstallProtocolInterface (
1138 &gEfiDevicePathProtocolGuid
,
1139 Private
->DevicePath
,
1144 gBS
->RestoreTPL (Tpl
);
1151 WinNtSerialIoSetControl (
1152 IN EFI_SERIAL_IO_PROTOCOL
*This
,
1157 Routine Description:
1159 TODO: Add function description
1163 This - TODO: add argument description
1164 Control - TODO: add argument description
1168 EFI_DEVICE_ERROR - TODO: Add description for return value
1169 EFI_DEVICE_ERROR - TODO: Add description for return value
1170 EFI_SUCCESS - TODO: Add description for return value
1174 WIN_NT_SERIAL_IO_PRIVATE_DATA
*Private
;
1178 UART_FLOW_CONTROL_DEVICE_PATH
*FlowControl
;
1182 // first determine the parameter is invalid
1184 if (Control
& (~(EFI_SERIAL_REQUEST_TO_SEND
| EFI_SERIAL_DATA_TERMINAL_READY
|
1185 EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE
| EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE
|
1186 EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE
))) {
1187 return EFI_UNSUPPORTED
;
1190 Tpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1192 Private
= WIN_NT_SERIAL_IO_PRIVATE_DATA_FROM_THIS (This
);
1194 Result
= Private
->WinNtThunk
->GetCommState (Private
->NtHandle
, &Dcb
);
1197 Private
->NtError
= Private
->WinNtThunk
->GetLastError ();
1198 DEBUG ((EFI_D_ERROR
, "SerialSetControl: GetCommState %d\n", Private
->NtError
));
1199 gBS
->RestoreTPL (Tpl
);
1200 return EFI_DEVICE_ERROR
;
1203 Dcb
.fRtsControl
= RTS_CONTROL_DISABLE
;
1204 Dcb
.fDtrControl
= DTR_CONTROL_DISABLE
;
1205 Private
->HardwareFlowControl
= FALSE
;
1206 Private
->SoftwareLoopbackEnable
= FALSE
;
1207 Private
->HardwareLoopbackEnable
= FALSE
;
1209 if (Control
& EFI_SERIAL_REQUEST_TO_SEND
) {
1210 Dcb
.fRtsControl
= RTS_CONTROL_ENABLE
;
1213 if (Control
& EFI_SERIAL_DATA_TERMINAL_READY
) {
1214 Dcb
.fDtrControl
= DTR_CONTROL_ENABLE
;
1217 if (Control
& EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE
) {
1218 Private
->HardwareFlowControl
= TRUE
;
1221 if (Control
& EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE
) {
1222 Private
->SoftwareLoopbackEnable
= TRUE
;
1225 if (Control
& EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE
) {
1226 Private
->HardwareLoopbackEnable
= TRUE
;
1229 Result
= Private
->WinNtThunk
->SetCommState (
1235 Private
->NtError
= Private
->WinNtThunk
->GetLastError ();
1236 DEBUG ((EFI_D_ERROR
, "SerialSetControl: SetCommState %d\n", Private
->NtError
));
1237 gBS
->RestoreTPL (Tpl
);
1238 return EFI_DEVICE_ERROR
;
1241 Status
= EFI_SUCCESS
;
1242 if (Private
->Handle
!= NULL
) {
1243 FlowControl
= (UART_FLOW_CONTROL_DEVICE_PATH
*) (
1244 (UINTN
) Private
->DevicePath
1245 + GetDevicePathSize (Private
->ParentDevicePath
)
1246 - END_DEVICE_PATH_LENGTH
1247 + sizeof (UART_DEVICE_PATH
)
1249 if (IsUartFlowControlNode (FlowControl
) &&
1250 ((FlowControl
->FlowControlMap
== UART_FLOW_CONTROL_HARDWARE
) ^ Private
->HardwareFlowControl
)) {
1252 // Flow Control setting is changed, need to reinstall device path protocol
1254 FlowControl
->FlowControlMap
= Private
->HardwareFlowControl
? UART_FLOW_CONTROL_HARDWARE
: 0;
1255 Status
= gBS
->ReinstallProtocolInterface (
1257 &gEfiDevicePathProtocolGuid
,
1258 Private
->DevicePath
,
1264 gBS
->RestoreTPL (Tpl
);
1271 WinNtSerialIoGetControl (
1272 IN EFI_SERIAL_IO_PROTOCOL
*This
,
1277 Routine Description:
1279 TODO: Add function description
1283 This - TODO: add argument description
1284 Control - TODO: add argument description
1288 EFI_DEVICE_ERROR - TODO: Add description for return value
1289 EFI_DEVICE_ERROR - TODO: Add description for return value
1290 EFI_DEVICE_ERROR - TODO: Add description for return value
1291 EFI_SUCCESS - TODO: Add description for return value
1295 WIN_NT_SERIAL_IO_PRIVATE_DATA
*Private
;
1302 Tpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1304 Private
= WIN_NT_SERIAL_IO_PRIVATE_DATA_FROM_THIS (This
);
1309 if (!Private
->WinNtThunk
->GetCommModemStatus (Private
->NtHandle
, &ModemStatus
)) {
1310 Private
->NtError
= Private
->WinNtThunk
->GetLastError ();
1311 gBS
->RestoreTPL (Tpl
);
1312 return EFI_DEVICE_ERROR
;
1316 if (ModemStatus
& MS_CTS_ON
) {
1317 Bits
|= EFI_SERIAL_CLEAR_TO_SEND
;
1320 if (ModemStatus
& MS_DSR_ON
) {
1321 Bits
|= EFI_SERIAL_DATA_SET_READY
;
1324 if (ModemStatus
& MS_RING_ON
) {
1325 Bits
|= EFI_SERIAL_RING_INDICATE
;
1328 if (ModemStatus
& MS_RLSD_ON
) {
1329 Bits
|= EFI_SERIAL_CARRIER_DETECT
;
1335 if (!Private
->WinNtThunk
->GetCommState (Private
->NtHandle
, &Dcb
)) {
1336 Private
->NtError
= Private
->WinNtThunk
->GetLastError ();
1337 DEBUG ((EFI_D_ERROR
, "SerialGetControl: GetCommState %d\n", Private
->NtError
));
1338 gBS
->RestoreTPL (Tpl
);
1339 return EFI_DEVICE_ERROR
;
1342 if (Dcb
.fDtrControl
== DTR_CONTROL_ENABLE
) {
1343 Bits
|= EFI_SERIAL_DATA_TERMINAL_READY
;
1346 if (Dcb
.fRtsControl
== RTS_CONTROL_ENABLE
) {
1347 Bits
|= EFI_SERIAL_REQUEST_TO_SEND
;
1350 if (Private
->HardwareFlowControl
) {
1351 Bits
|= EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE
;
1354 if (Private
->SoftwareLoopbackEnable
) {
1355 Bits
|= EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE
;
1358 if (Private
->HardwareLoopbackEnable
) {
1359 Bits
|= EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE
;
1363 // Get input buffer status
1365 if (!Private
->WinNtThunk
->ClearCommError (Private
->NtHandle
, &Errors
, &Private
->NtComStatus
)) {
1366 Private
->NtError
= Private
->WinNtThunk
->GetLastError ();
1367 DEBUG ((EFI_D_ERROR
, "SerialGetControl: ClearCommError %d\n", Private
->NtError
));
1368 gBS
->RestoreTPL (Tpl
);
1369 return EFI_DEVICE_ERROR
;
1372 if (Private
->NtComStatus
.cbInQue
== 0) {
1373 Bits
|= EFI_SERIAL_INPUT_BUFFER_EMPTY
;
1378 gBS
->RestoreTPL (Tpl
);
1385 WinNtSerialIoWrite (
1386 IN EFI_SERIAL_IO_PROTOCOL
*This
,
1387 IN OUT UINTN
*BufferSize
,
1392 Routine Description:
1394 TODO: Add function description
1398 This - TODO: add argument description
1399 BufferSize - TODO: add argument description
1400 Buffer - TODO: add argument description
1404 EFI_DEVICE_ERROR - TODO: Add description for return value
1405 EFI_SUCCESS - TODO: Add description for return value
1409 WIN_NT_SERIAL_IO_PRIVATE_DATA
*Private
;
1411 UINTN TotalBytesWritten
;
1419 Tpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1421 Private
= WIN_NT_SERIAL_IO_PRIVATE_DATA_FROM_THIS (This
);
1423 ByteBuffer
= (UINT8
*) Buffer
;
1424 TotalBytesWritten
= 0;
1426 if (Private
->SoftwareLoopbackEnable
|| Private
->HardwareLoopbackEnable
) {
1427 for (Index
= 0; Index
< *BufferSize
; Index
++) {
1428 if (IsaSerialFifoAdd (&Private
->Fifo
, ByteBuffer
[Index
]) == EFI_SUCCESS
) {
1429 TotalBytesWritten
++;
1435 BytesToGo
= (DWORD
) (*BufferSize
);
1438 if (Private
->HardwareFlowControl
) {
1442 WinNtSerialIoGetControl (&Private
->SerialIo
, &Control
);
1443 Control
|= EFI_SERIAL_REQUEST_TO_SEND
;
1444 WinNtSerialIoSetControl (&Private
->SerialIo
, Control
);
1450 Result
= Private
->WinNtThunk
->WriteFile (
1452 &ByteBuffer
[TotalBytesWritten
],
1458 if (Private
->HardwareFlowControl
) {
1462 WinNtSerialIoGetControl (&Private
->SerialIo
, &Control
);
1463 Control
&= ~ (UINT32
) EFI_SERIAL_REQUEST_TO_SEND
;
1464 WinNtSerialIoSetControl (&Private
->SerialIo
, Control
);
1467 TotalBytesWritten
+= BytesWritten
;
1468 BytesToGo
-= BytesWritten
;
1470 Private
->NtError
= Private
->WinNtThunk
->GetLastError ();
1471 DEBUG ((EFI_D_ERROR
, "SerialWrite: FileWrite %d\n", Private
->NtError
));
1472 *BufferSize
= TotalBytesWritten
;
1473 gBS
->RestoreTPL (Tpl
);
1474 return EFI_DEVICE_ERROR
;
1476 } while (BytesToGo
> 0);
1479 *BufferSize
= TotalBytesWritten
;
1481 gBS
->RestoreTPL (Tpl
);
1489 IN EFI_SERIAL_IO_PROTOCOL
*This
,
1490 IN OUT UINTN
*BufferSize
,
1495 Routine Description:
1497 TODO: Add function description
1501 This - TODO: add argument description
1502 BufferSize - TODO: add argument description
1503 Buffer - TODO: add argument description
1507 EFI_DEVICE_ERROR - TODO: Add description for return value
1511 WIN_NT_SERIAL_IO_PRIVATE_DATA
*Private
;
1520 Tpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1522 Private
= WIN_NT_SERIAL_IO_PRIVATE_DATA_FROM_THIS (This
);
1527 if (Private
->SoftwareLoopbackEnable
|| Private
->HardwareLoopbackEnable
) {
1528 for (Index
= 0, BytesRead
= 0; Index
< *BufferSize
; Index
++) {
1529 if (IsaSerialFifoRemove (&Private
->Fifo
, &Data
) == EFI_SUCCESS
) {
1530 ((UINT8
*) Buffer
)[Index
] = Data
;
1537 if (Private
->HardwareFlowControl
) {
1538 WinNtSerialIoGetControl (&Private
->SerialIo
, &Control
);
1539 Control
|= EFI_SERIAL_DATA_TERMINAL_READY
;
1540 WinNtSerialIoSetControl (&Private
->SerialIo
, Control
);
1543 Result
= Private
->WinNtThunk
->ReadFile (
1546 (DWORD
) *BufferSize
,
1551 if (Private
->HardwareFlowControl
) {
1552 WinNtSerialIoGetControl (&Private
->SerialIo
, &Control
);
1553 Control
&= ~ (UINT32
) EFI_SERIAL_DATA_TERMINAL_READY
;
1554 WinNtSerialIoSetControl (&Private
->SerialIo
, Control
);
1558 Private
->NtError
= Private
->WinNtThunk
->GetLastError ();
1559 gBS
->RestoreTPL (Tpl
);
1560 return EFI_DEVICE_ERROR
;
1564 if (BytesRead
!= *BufferSize
) {
1565 Status
= EFI_TIMEOUT
;
1567 Status
= EFI_SUCCESS
;
1570 *BufferSize
= (UINTN
) BytesRead
;
1572 gBS
->RestoreTPL (Tpl
);
1579 IN SERIAL_DEV_FIFO
*Fifo
1583 Routine Description:
1584 Detect whether specific FIFO is full or not
1587 Fifo SERIAL_DEV_FIFO *: A pointer to the Data Structure SERIAL_DEV_FIFO
1590 TRUE: the FIFO is full
1591 FALSE: the FIFO is not full
1595 if (Fifo
->Surplus
== 0) {
1603 IsaSerialFifoEmpty (
1604 IN SERIAL_DEV_FIFO
*Fifo
1608 Routine Description:
1609 Detect whether specific FIFO is empty or not
1612 Fifo SERIAL_DEV_FIFO *: A pointer to the Data Structure SERIAL_DEV_FIFO
1615 TRUE: the FIFO is empty
1616 FALSE: the FIFO is not empty
1620 if (Fifo
->Surplus
== SERIAL_MAX_BUFFER_SIZE
) {
1629 IN SERIAL_DEV_FIFO
*Fifo
,
1634 Routine Description:
1635 Add data to specific FIFO
1638 Fifo SERIAL_DEV_FIFO *: A pointer to the Data Structure SERIAL_DEV_FIFO
1639 Data UINT8: the data added to FIFO
1642 EFI_SUCCESS: Add data to specific FIFO successfully
1643 EFI_OUT_RESOURCE: Failed to add data because FIFO is already full
1646 // TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
1649 // if FIFO full can not add data
1651 if (IsaSerialFifoFull (Fifo
)) {
1652 return EFI_OUT_OF_RESOURCES
;
1656 // FIFO is not full can add data
1658 Fifo
->Data
[Fifo
->Last
] = Data
;
1661 if (Fifo
->Last
>= SERIAL_MAX_BUFFER_SIZE
) {
1669 IsaSerialFifoRemove (
1670 IN SERIAL_DEV_FIFO
*Fifo
,
1675 Routine Description:
1676 Remove data from specific FIFO
1679 Fifo SERIAL_DEV_FIFO *: A pointer to the Data Structure SERIAL_DEV_FIFO
1680 Data UINT8*: the data removed from FIFO
1683 EFI_SUCCESS: Remove data from specific FIFO successfully
1684 EFI_OUT_RESOURCE: Failed to remove data because FIFO is empty
1687 // TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
1690 // if FIFO is empty, no data can remove
1692 if (IsaSerialFifoEmpty (Fifo
)) {
1693 return EFI_OUT_OF_RESOURCES
;
1697 // FIFO is not empty, can remove data
1699 *Data
= Fifo
->Data
[Fifo
->First
];
1702 if (Fifo
->First
>= SERIAL_MAX_BUFFER_SIZE
) {