3 Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
4 SPDX-License-Identifier: BSD-2-Clause-Patent
12 Our DriverBinding member functions operate on the handles
13 created by the NT Bus driver.
15 Handle(1) - WinNtIo - DevicePath(1)
17 If a serial port is added to the system this driver creates a new handle.
18 The new handle is required, since the serial device must add an UART device
21 Handle(2) - SerialIo - DevicePath(1)\UART
23 The driver then adds a gEfiWinNtSerialPortGuid as a protocol to Handle(1).
24 The instance data for this protocol is the private data used to create
27 Handle(1) - WinNtIo - DevicePath(1) - WinNtSerialPort
29 If the driver is unloaded Handle(2) is removed from the system and
30 gEfiWinNtSerialPortGuid is removed from Handle(1).
32 Note: Handle(1) is any handle created by the Win NT Bus driver that is passed
33 into the DriverBinding member functions of this driver. This driver requires
34 a Handle(1) to contain a WinNtIo protocol, a DevicePath protocol, and
35 the TypeGuid in the WinNtIo must be gEfiWinNtSerialPortGuid.
37 If Handle(1) contains a gEfiWinNtSerialPortGuid protocol then the driver is
42 #include "WinNtSerialIo.h"
44 EFI_DRIVER_BINDING_PROTOCOL gWinNtSerialIoDriverBinding
= {
45 WinNtSerialIoDriverBindingSupported
,
46 WinNtSerialIoDriverBindingStart
,
47 WinNtSerialIoDriverBindingStop
,
54 // List of supported baud rate
56 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};
59 Check the device path node whether it's the Flow Control node or not.
61 @param[in] FlowControl The device path node to be checked.
63 @retval TRUE It's the Flow Control node.
64 @retval FALSE It's not.
68 IsUartFlowControlNode (
69 IN UART_FLOW_CONTROL_DEVICE_PATH
*FlowControl
73 (DevicePathType (FlowControl
) == MESSAGING_DEVICE_PATH
) &&
74 (DevicePathSubType (FlowControl
) == MSG_VENDOR_DP
) &&
75 (CompareGuid (&FlowControl
->Guid
, &gEfiUartDevicePathGuid
))
80 Check the device path node whether it contains Flow Control node or not.
82 @param[in] DevicePath The device path to be checked.
84 @retval TRUE It contains the Flow Control node.
85 @retval FALSE It doesn't.
90 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
93 while (!IsDevicePathEnd (DevicePath
)) {
94 if (IsUartFlowControlNode ((UART_FLOW_CONTROL_DEVICE_PATH
*) DevicePath
)) {
97 DevicePath
= NextDevicePathNode (DevicePath
);
104 The user Entry Point for module WinNtSerialIo. The user code starts with this function.
106 @param[in] ImageHandle The firmware allocated handle for the EFI image.
107 @param[in] SystemTable A pointer to the EFI System Table.
109 @retval EFI_SUCCESS The entry point is executed successfully.
110 @retval other Some error occurs when executing this entry point.
115 InitializeWinNtSerialIo(
116 IN EFI_HANDLE ImageHandle
,
117 IN EFI_SYSTEM_TABLE
*SystemTable
123 // Install driver model protocol(s).
125 Status
= EfiLibInstallDriverBindingComponentName2 (
128 &gWinNtSerialIoDriverBinding
,
130 &gWinNtSerialIoComponentName
,
131 &gWinNtSerialIoComponentName2
133 ASSERT_EFI_ERROR (Status
);
141 WinNtSerialIoDriverBindingSupported (
142 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
143 IN EFI_HANDLE Handle
,
144 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
157 // TODO: This - add argument and description to function comment
158 // TODO: Handle - add argument and description to function comment
159 // TODO: RemainingDevicePath - add argument and description to function comment
160 // TODO: EFI_SUCCESS - add return value to function comment
161 // TODO: EFI_SUCCESS - add return value to function comment
164 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
165 EFI_WIN_NT_IO_PROTOCOL
*WinNtIo
;
166 UART_DEVICE_PATH
*UartNode
;
167 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
168 UART_FLOW_CONTROL_DEVICE_PATH
*FlowControlNode
;
169 EFI_OPEN_PROTOCOL_INFORMATION_ENTRY
*OpenInfoBuffer
;
172 BOOLEAN RemainingDevicePathContainsFlowControl
;
175 // Check RemainingDevicePath validation
177 if (RemainingDevicePath
!= NULL
) {
179 // Check if RemainingDevicePath is the End of Device Path Node,
180 // if yes, go on checking other conditions
182 if (!IsDevicePathEnd (RemainingDevicePath
)) {
184 // If RemainingDevicePath isn't the End of Device Path Node,
185 // check its validation
187 Status
= EFI_UNSUPPORTED
;
189 UartNode
= (UART_DEVICE_PATH
*) RemainingDevicePath
;
190 if (UartNode
->Header
.Type
!= MESSAGING_DEVICE_PATH
||
191 UartNode
->Header
.SubType
!= MSG_UART_DP
||
192 DevicePathNodeLength((EFI_DEVICE_PATH_PROTOCOL
*)UartNode
) != sizeof(UART_DEVICE_PATH
)) {
195 if ( UartNode
->BaudRate
> SERIAL_PORT_MAX_BAUD_RATE
) {
198 if (UartNode
->Parity
< NoParity
|| UartNode
->Parity
> SpaceParity
) {
201 if (UartNode
->DataBits
< 5 || UartNode
->DataBits
> 8) {
204 if (UartNode
->StopBits
< OneStopBit
|| UartNode
->StopBits
> TwoStopBits
) {
207 if ((UartNode
->DataBits
== 5) && (UartNode
->StopBits
== TwoStopBits
)) {
210 if ((UartNode
->DataBits
>= 6) && (UartNode
->DataBits
<= 8) && (UartNode
->StopBits
== OneFiveStopBits
)) {
214 FlowControlNode
= (UART_FLOW_CONTROL_DEVICE_PATH
*) NextDevicePathNode (UartNode
);
215 if (IsUartFlowControlNode (FlowControlNode
)) {
217 // If the second node is Flow Control Node,
218 // return error when it request other than hardware flow control.
220 if ((FlowControlNode
->FlowControlMap
& ~UART_FLOW_CONTROL_HARDWARE
) != 0) {
228 // Open the IO Abstraction(s) needed to perform the supported test
230 Status
= gBS
->OpenProtocol (
232 &gEfiWinNtIoProtocolGuid
,
234 This
->DriverBindingHandle
,
236 EFI_OPEN_PROTOCOL_BY_DRIVER
238 if (Status
== EFI_ALREADY_STARTED
) {
239 if (RemainingDevicePath
== NULL
|| IsDevicePathEnd (RemainingDevicePath
)) {
241 // If RemainingDevicePath is NULL or is the End of Device Path Node
246 // When the driver has produced device path with flow control node but RemainingDevicePath only contains UART node,
247 // return unsupported, and vice versa.
249 Status
= gBS
->OpenProtocolInformation (
251 &gEfiWinNtIoProtocolGuid
,
255 if (EFI_ERROR (Status
)) {
260 // See if RemainingDevicePath has a Flow Control device path node
262 RemainingDevicePathContainsFlowControl
= ContainsFlowControl (RemainingDevicePath
);
264 for (Index
= 0; Index
< EntryCount
; Index
++) {
265 if ((OpenInfoBuffer
[Index
].Attributes
& EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
) != 0) {
266 Status
= gBS
->OpenProtocol (
267 OpenInfoBuffer
[Index
].ControllerHandle
,
268 &gEfiDevicePathProtocolGuid
,
269 (VOID
**) &DevicePath
,
270 This
->DriverBindingHandle
,
272 EFI_OPEN_PROTOCOL_GET_PROTOCOL
274 if (!EFI_ERROR (Status
)) {
275 if (RemainingDevicePathContainsFlowControl
^ ContainsFlowControl (DevicePath
)) {
276 Status
= EFI_UNSUPPORTED
;
282 FreePool (OpenInfoBuffer
);
286 if (EFI_ERROR (Status
)) {
291 // Close the I/O Abstraction(s) used to perform the supported test
295 &gEfiWinNtIoProtocolGuid
,
296 This
->DriverBindingHandle
,
301 // Open the EFI Device Path protocol needed to perform the supported test
303 Status
= gBS
->OpenProtocol (
305 &gEfiDevicePathProtocolGuid
,
306 (VOID
**) &ParentDevicePath
,
307 This
->DriverBindingHandle
,
309 EFI_OPEN_PROTOCOL_BY_DRIVER
311 if (Status
== EFI_ALREADY_STARTED
) {
315 if (EFI_ERROR (Status
)) {
320 // Close protocol, don't use device path protocol in the Support() function
324 &gEfiDevicePathProtocolGuid
,
325 This
->DriverBindingHandle
,
330 // Make sure that the WinNt Thunk Protocol is valid
332 if (WinNtIo
->WinNtThunk
->Signature
!= EFI_WIN_NT_THUNK_PROTOCOL_SIGNATURE
) {
333 Status
= EFI_UNSUPPORTED
;
338 // Check the GUID to see if this is a handle type the driver supports
340 if (!CompareGuid (WinNtIo
->TypeGuid
, &gEfiWinNtSerialPortGuid
)) {
341 Status
= EFI_UNSUPPORTED
;
353 WinNtSerialIoDriverBindingStart (
354 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
355 IN EFI_HANDLE Handle
,
356 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
369 // TODO: This - add argument and description to function comment
370 // TODO: Handle - add argument and description to function comment
371 // TODO: RemainingDevicePath - add argument and description to function comment
372 // TODO: EFI_SUCCESS - add return value to function comment
373 // TODO: EFI_SUCCESS - add return value to function comment
376 EFI_WIN_NT_IO_PROTOCOL
*WinNtIo
;
377 WIN_NT_SERIAL_IO_PRIVATE_DATA
*Private
;
379 UART_DEVICE_PATH UartNode
;
380 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
381 EFI_OPEN_PROTOCOL_INFORMATION_ENTRY
*OpenInfoBuffer
;
384 EFI_SERIAL_IO_PROTOCOL
*SerialIo
;
385 UART_DEVICE_PATH
*Uart
;
386 UINT32 FlowControlMap
;
387 UART_FLOW_CONTROL_DEVICE_PATH
*FlowControl
;
388 EFI_DEVICE_PATH_PROTOCOL
*TempDevicePath
;
392 NtHandle
= INVALID_HANDLE_VALUE
;
395 // Get the Parent Device Path
397 Status
= gBS
->OpenProtocol (
399 &gEfiDevicePathProtocolGuid
,
400 (VOID
**) &ParentDevicePath
,
401 This
->DriverBindingHandle
,
403 EFI_OPEN_PROTOCOL_BY_DRIVER
405 if (EFI_ERROR (Status
) && Status
!= EFI_ALREADY_STARTED
) {
410 // Grab the IO abstraction we need to get any work done
412 Status
= gBS
->OpenProtocol (
414 &gEfiWinNtIoProtocolGuid
,
416 This
->DriverBindingHandle
,
418 EFI_OPEN_PROTOCOL_BY_DRIVER
420 if (EFI_ERROR (Status
) && Status
!= EFI_ALREADY_STARTED
) {
423 &gEfiDevicePathProtocolGuid
,
424 This
->DriverBindingHandle
,
430 if (Status
== EFI_ALREADY_STARTED
) {
432 if (RemainingDevicePath
== NULL
|| IsDevicePathEnd (RemainingDevicePath
)) {
434 // If RemainingDevicePath is NULL or is the End of Device Path Node
440 // Make sure a child handle does not already exist. This driver can only
441 // produce one child per serial port.
443 Status
= gBS
->OpenProtocolInformation (
445 &gEfiWinNtIoProtocolGuid
,
449 if (EFI_ERROR (Status
)) {
453 Status
= EFI_ALREADY_STARTED
;
454 for (Index
= 0; Index
< EntryCount
; Index
++) {
455 if ((OpenInfoBuffer
[Index
].Attributes
& EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
) != 0) {
456 Status
= gBS
->OpenProtocol (
457 OpenInfoBuffer
[Index
].ControllerHandle
,
458 &gEfiSerialIoProtocolGuid
,
460 This
->DriverBindingHandle
,
462 EFI_OPEN_PROTOCOL_GET_PROTOCOL
464 if (!EFI_ERROR (Status
)) {
465 Uart
= (UART_DEVICE_PATH
*) RemainingDevicePath
;
466 Status
= SerialIo
->SetAttributes (
469 SerialIo
->Mode
->ReceiveFifoDepth
,
470 SerialIo
->Mode
->Timeout
,
471 (EFI_PARITY_TYPE
) Uart
->Parity
,
473 (EFI_STOP_BITS_TYPE
) Uart
->StopBits
475 FlowControl
= (UART_FLOW_CONTROL_DEVICE_PATH
*) NextDevicePathNode (Uart
);
476 if (!EFI_ERROR (Status
) && IsUartFlowControlNode (FlowControl
)) {
477 Status
= SerialIo
->GetControl (SerialIo
, &Control
);
478 if (!EFI_ERROR (Status
)) {
479 if (FlowControl
->FlowControlMap
== UART_FLOW_CONTROL_HARDWARE
) {
480 Control
|= EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE
;
482 Control
&= ~EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE
;
485 // Clear the bits that are not allowed to pass to SetControl
487 Control
&= (EFI_SERIAL_REQUEST_TO_SEND
| EFI_SERIAL_DATA_TERMINAL_READY
|
488 EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE
| EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE
|
489 EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE
);
490 Status
= SerialIo
->SetControl (SerialIo
, Control
);
498 FreePool (OpenInfoBuffer
);
504 if (RemainingDevicePath
== NULL
) {
506 // Build the device path by appending the UART node to the ParentDevicePath
507 // from the WinNtIo handle. The Uart setings are zero here, since
508 // SetAttribute() will update them to match the default setings.
510 ZeroMem (&UartNode
, sizeof (UART_DEVICE_PATH
));
511 UartNode
.Header
.Type
= MESSAGING_DEVICE_PATH
;
512 UartNode
.Header
.SubType
= MSG_UART_DP
;
513 SetDevicePathNodeLength ((EFI_DEVICE_PATH_PROTOCOL
*) &UartNode
, sizeof (UART_DEVICE_PATH
));
515 } else if (!IsDevicePathEnd (RemainingDevicePath
)) {
517 // If RemainingDevicePath isn't the End of Device Path Node,
518 // only scan the specified device by RemainingDevicePath
521 // Match the configuration of the RemainingDevicePath. IsHandleSupported()
522 // already checked to make sure the RemainingDevicePath contains settings
523 // that we can support.
525 CopyMem (&UartNode
, RemainingDevicePath
, sizeof (UART_DEVICE_PATH
));
526 FlowControl
= (UART_FLOW_CONTROL_DEVICE_PATH
*) NextDevicePathNode (RemainingDevicePath
);
527 if (IsUartFlowControlNode (FlowControl
)) {
528 FlowControlMap
= FlowControl
->FlowControlMap
;
535 // If RemainingDevicePath is the End of Device Path Node,
536 // skip enumerate any device and return EFI_SUCESSS
542 // Check to see if we can access the hardware device. If it's Open in NT we
543 // will not get access.
545 NtHandle
= WinNtIo
->WinNtThunk
->CreateFile (
547 GENERIC_READ
| GENERIC_WRITE
,
554 if (NtHandle
== INVALID_HANDLE_VALUE
) {
555 Status
= EFI_DEVICE_ERROR
;
560 // Construct Private data
562 Private
= AllocatePool (sizeof (WIN_NT_SERIAL_IO_PRIVATE_DATA
));
563 if (Private
== NULL
) {
568 // This signature must be valid before any member function is called
570 Private
->Signature
= WIN_NT_SERIAL_IO_PRIVATE_DATA_SIGNATURE
;
571 Private
->NtHandle
= NtHandle
;
572 Private
->ControllerHandle
= Handle
;
573 Private
->Handle
= NULL
;
574 Private
->WinNtThunk
= WinNtIo
->WinNtThunk
;
575 Private
->ParentDevicePath
= ParentDevicePath
;
576 Private
->ControllerNameTable
= NULL
;
578 Private
->SoftwareLoopbackEnable
= FALSE
;
579 Private
->HardwareLoopbackEnable
= FALSE
;
580 Private
->HardwareFlowControl
= (BOOLEAN
) (FlowControlMap
== UART_FLOW_CONTROL_HARDWARE
);
581 Private
->Fifo
.First
= 0;
582 Private
->Fifo
.Last
= 0;
583 Private
->Fifo
.Surplus
= SERIAL_MAX_BUFFER_SIZE
;
585 CopyMem (&Private
->UartDevicePath
, &UartNode
, sizeof (UART_DEVICE_PATH
));
589 gWinNtSerialIoComponentName
.SupportedLanguages
,
590 &Private
->ControllerNameTable
,
596 gWinNtSerialIoComponentName2
.SupportedLanguages
,
597 &Private
->ControllerNameTable
,
603 Private
->SerialIo
.Revision
= SERIAL_IO_INTERFACE_REVISION
;
604 Private
->SerialIo
.Reset
= WinNtSerialIoReset
;
605 Private
->SerialIo
.SetAttributes
= WinNtSerialIoSetAttributes
;
606 Private
->SerialIo
.SetControl
= WinNtSerialIoSetControl
;
607 Private
->SerialIo
.GetControl
= WinNtSerialIoGetControl
;
608 Private
->SerialIo
.Write
= WinNtSerialIoWrite
;
609 Private
->SerialIo
.Read
= WinNtSerialIoRead
;
610 Private
->SerialIo
.Mode
= &Private
->SerialIoMode
;
613 // Build the device path by appending the UART node to the ParentDevicePath
614 // from the WinNtIo handle. The Uart setings are zero here, since
615 // SetAttribute() will update them to match the current setings.
617 Private
->DevicePath
= AppendDevicePathNode (
619 (EFI_DEVICE_PATH_PROTOCOL
*) &Private
->UartDevicePath
622 // Only produce the FlowControl node when remaining device path has it
624 if (FlowControl
!= NULL
) {
625 TempDevicePath
= Private
->DevicePath
;
626 if (TempDevicePath
!= NULL
) {
627 Private
->DevicePath
= AppendDevicePathNode (
629 (EFI_DEVICE_PATH_PROTOCOL
*) FlowControl
631 FreePool (TempDevicePath
);
634 if (Private
->DevicePath
== NULL
) {
635 Status
= EFI_OUT_OF_RESOURCES
;
640 // Fill in Serial I/O Mode structure based on either the RemainingDevicePath or defaults.
642 Private
->SerialIoMode
.ControlMask
= SERIAL_CONTROL_MASK
;
643 Private
->SerialIoMode
.Timeout
= SERIAL_TIMEOUT_DEFAULT
;
644 Private
->SerialIoMode
.BaudRate
= Private
->UartDevicePath
.BaudRate
;
645 Private
->SerialIoMode
.ReceiveFifoDepth
= SERIAL_FIFO_DEFAULT
;
646 Private
->SerialIoMode
.DataBits
= Private
->UartDevicePath
.DataBits
;
647 Private
->SerialIoMode
.Parity
= Private
->UartDevicePath
.Parity
;
648 Private
->SerialIoMode
.StopBits
= Private
->UartDevicePath
.StopBits
;
651 // Issue a reset to initialize the COM port
653 Status
= Private
->SerialIo
.Reset (&Private
->SerialIo
);
654 if (EFI_ERROR (Status
)) {
659 // Create new child handle
661 Status
= gBS
->InstallMultipleProtocolInterfaces (
663 &gEfiSerialIoProtocolGuid
,
665 &gEfiDevicePathProtocolGuid
,
669 if (EFI_ERROR (Status
)) {
674 // Open For Child Device
676 Status
= gBS
->OpenProtocol (
678 &gEfiWinNtIoProtocolGuid
,
680 This
->DriverBindingHandle
,
682 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
684 if (EFI_ERROR (Status
)) {
692 // Use the Stop() function to free all resources allocated in Start()
694 if (Private
!= NULL
) {
695 if (Private
->Handle
!= NULL
) {
696 This
->Stop (This
, Handle
, 1, &Private
->Handle
);
698 if (NtHandle
!= INVALID_HANDLE_VALUE
) {
699 Private
->WinNtThunk
->CloseHandle (NtHandle
);
702 if (Private
->DevicePath
!= NULL
) {
703 FreePool (Private
->DevicePath
);
706 FreeUnicodeStringTable (Private
->ControllerNameTable
);
712 This
->Stop (This
, Handle
, 0, NULL
);
719 WinNtSerialIoDriverBindingStop (
720 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
721 IN EFI_HANDLE Handle
,
722 IN UINTN NumberOfChildren
,
723 IN EFI_HANDLE
*ChildHandleBuffer
729 TODO: Add function description
733 This - TODO: add argument description
734 Handle - TODO: add argument description
735 NumberOfChildren - TODO: add argument description
736 ChildHandleBuffer - TODO: add argument description
740 EFI_DEVICE_ERROR - TODO: Add description for return value
741 EFI_SUCCESS - TODO: Add description for return value
747 BOOLEAN AllChildrenStopped
;
748 EFI_SERIAL_IO_PROTOCOL
*SerialIo
;
749 WIN_NT_SERIAL_IO_PRIVATE_DATA
*Private
;
750 EFI_WIN_NT_IO_PROTOCOL
*WinNtIo
;
753 // Complete all outstanding transactions to Controller.
754 // Don't allow any new transaction to Controller to be started.
757 if (NumberOfChildren
== 0) {
759 // Close the bus driver
761 Status
= gBS
->CloseProtocol (
763 &gEfiWinNtIoProtocolGuid
,
764 This
->DriverBindingHandle
,
767 Status
= gBS
->CloseProtocol (
769 &gEfiDevicePathProtocolGuid
,
770 This
->DriverBindingHandle
,
776 AllChildrenStopped
= TRUE
;
778 for (Index
= 0; Index
< NumberOfChildren
; Index
++) {
779 Status
= gBS
->OpenProtocol (
780 ChildHandleBuffer
[Index
],
781 &gEfiSerialIoProtocolGuid
,
783 This
->DriverBindingHandle
,
785 EFI_OPEN_PROTOCOL_GET_PROTOCOL
787 if (!EFI_ERROR (Status
)) {
788 Private
= WIN_NT_SERIAL_IO_PRIVATE_DATA_FROM_THIS (SerialIo
);
790 ASSERT (Private
->Handle
== ChildHandleBuffer
[Index
]);
792 Status
= gBS
->CloseProtocol (
794 &gEfiWinNtIoProtocolGuid
,
795 This
->DriverBindingHandle
,
796 ChildHandleBuffer
[Index
]
799 Status
= gBS
->UninstallMultipleProtocolInterfaces (
800 ChildHandleBuffer
[Index
],
801 &gEfiSerialIoProtocolGuid
,
803 &gEfiDevicePathProtocolGuid
,
808 if (EFI_ERROR (Status
)) {
811 &gEfiWinNtIoProtocolGuid
,
813 This
->DriverBindingHandle
,
814 ChildHandleBuffer
[Index
],
815 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
818 Private
->WinNtThunk
->CloseHandle (Private
->NtHandle
);
820 FreePool (Private
->DevicePath
);
822 FreeUnicodeStringTable (Private
->ControllerNameTable
);
828 if (EFI_ERROR (Status
)) {
829 AllChildrenStopped
= FALSE
;
833 if (!AllChildrenStopped
) {
834 return EFI_DEVICE_ERROR
;
841 // Serial IO Protocol member functions
847 IN EFI_SERIAL_IO_PROTOCOL
*This
853 TODO: Add function description
857 This - TODO: add argument description
861 TODO: add return values
865 WIN_NT_SERIAL_IO_PRIVATE_DATA
*Private
;
868 Tpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
870 Private
= WIN_NT_SERIAL_IO_PRIVATE_DATA_FROM_THIS (This
);
872 Private
->WinNtThunk
->PurgeComm (
874 PURGE_TXCLEAR
| PURGE_RXCLEAR
877 gBS
->RestoreTPL (Tpl
);
879 return This
->SetAttributes (
881 This
->Mode
->BaudRate
,
882 This
->Mode
->ReceiveFifoDepth
,
884 (EFI_PARITY_TYPE
)This
->Mode
->Parity
,
885 (UINT8
) This
->Mode
->DataBits
,
886 (EFI_STOP_BITS_TYPE
)This
->Mode
->StopBits
892 WinNtSerialIoSetAttributes (
893 IN EFI_SERIAL_IO_PROTOCOL
*This
,
895 IN UINT32 ReceiveFifoDepth
,
897 IN EFI_PARITY_TYPE Parity
,
899 IN EFI_STOP_BITS_TYPE StopBits
905 This function is used to set the attributes.
909 This - A pointer to the EFI_SERIAL_IO_PROTOCOL structrue.
910 BaudRate - The Baud rate of the serial device.
911 ReceiveFifoDepth - The request depth of fifo on receive side.
912 Timeout - the request timeout for a single charact.
913 Parity - The type of parity used in serial device.
914 DataBits - Number of deata bits used in serial device.
915 StopBits - Number of stop bits used in serial device.
923 // TODO: EFI_SUCCESS - add return value to function comment
924 // TODO: EFI_DEVICE_ERROR - add return value to function comment
925 // TODO: EFI_DEVICE_ERROR - add return value to function comment
926 // TODO: EFI_DEVICE_ERROR - add return value to function comment
927 // TODO: EFI_SUCCESS - add return value to function comment
928 // TODO: EFI_DEVICE_ERROR - add return value to function comment
929 // TODO: EFI_SUCCESS - add return value to function comment
933 WIN_NT_SERIAL_IO_PRIVATE_DATA
*Private
;
934 COMMTIMEOUTS PortTimeOuts
;
937 UART_DEVICE_PATH
*Uart
;
940 Private
= WIN_NT_SERIAL_IO_PRIVATE_DATA_FROM_THIS (This
);
943 // Some of our arguments have defaults if a null value is passed in, and
944 // we must set the default values if a null argument is passed in.
947 BaudRate
= PcdGet64 (PcdUartDefaultBaudRate
);
950 if (ReceiveFifoDepth
== 0) {
951 ReceiveFifoDepth
= SERIAL_FIFO_DEFAULT
;
955 Timeout
= SERIAL_TIMEOUT_DEFAULT
;
958 if (Parity
== DefaultParity
) {
959 Parity
= (EFI_PARITY_TYPE
) (PcdGet8 (PcdUartDefaultParity
));
963 DataBits
= PcdGet8 (PcdUartDefaultDataBits
);
966 if (StopBits
== DefaultStopBits
) {
967 StopBits
= (EFI_STOP_BITS_TYPE
) PcdGet8 (PcdUartDefaultStopBits
);
971 // Make sure all parameters are valid
973 if ((BaudRate
> SERIAL_PORT_MAX_BAUD_RATE
) || (BaudRate
< SERIAL_PORT_MIN_BAUD_RATE
)) {
974 return EFI_INVALID_PARAMETER
;
978 //The lower baud rate supported by the serial device will be selected without exceeding the unsupported BaudRate parameter
981 for (Index
= 1; Index
< (ARRAY_SIZE (mBaudRateCurrentSupport
)); Index
++) {
982 if (BaudRate
< mBaudRateCurrentSupport
[Index
]) {
983 BaudRate
= mBaudRateCurrentSupport
[Index
-1];
988 if ((ReceiveFifoDepth
< 1) || (ReceiveFifoDepth
> SERIAL_PORT_MAX_RECEIVE_FIFO_DEPTH
)) {
989 return EFI_INVALID_PARAMETER
;
992 if ((Timeout
< SERIAL_PORT_MIN_TIMEOUT
) || (Timeout
> SERIAL_PORT_MAX_TIMEOUT
)) {
993 return EFI_INVALID_PARAMETER
;
996 if ((Parity
< NoParity
) || (Parity
> SpaceParity
)) {
997 return EFI_INVALID_PARAMETER
;
1000 if ((StopBits
< OneStopBit
) || (StopBits
> TwoStopBits
)) {
1001 return EFI_INVALID_PARAMETER
;
1005 // Now we only support DataBits=7,8.
1007 if ((DataBits
< 7) || (DataBits
> 8)) {
1008 return EFI_INVALID_PARAMETER
;
1012 // Now we only support DataBits=7,8.
1013 // for DataBits = 6,7,8, StopBits can not set OneFiveStopBits.
1015 if (StopBits
== OneFiveStopBits
) {
1016 return EFI_INVALID_PARAMETER
;
1020 // See if the new attributes already match the current attributes
1022 if (Private
->UartDevicePath
.BaudRate
== BaudRate
&&
1023 Private
->UartDevicePath
.DataBits
== DataBits
&&
1024 Private
->UartDevicePath
.Parity
== Parity
&&
1025 Private
->UartDevicePath
.StopBits
== StopBits
&&
1026 Private
->SerialIoMode
.ReceiveFifoDepth
== ReceiveFifoDepth
&&
1027 Private
->SerialIoMode
.Timeout
== Timeout
) {
1031 Tpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1034 // Get current values from NT
1036 ZeroMem (&Private
->NtDCB
, sizeof (DCB
));
1037 Private
->NtDCB
.DCBlength
= sizeof (DCB
);
1039 if (!Private
->WinNtThunk
->GetCommState (Private
->NtHandle
, &Private
->NtDCB
)) {
1040 Private
->NtError
= Private
->WinNtThunk
->GetLastError ();
1041 DEBUG ((EFI_D_ERROR
, "SerialSetAttributes: GetCommState %d\n", Private
->NtError
));
1042 gBS
->RestoreTPL (Tpl
);
1043 return EFI_DEVICE_ERROR
;
1047 // Map EFI com setting to NT
1049 Private
->NtDCB
.BaudRate
= ConvertBaud2Nt (BaudRate
);
1050 Private
->NtDCB
.ByteSize
= ConvertData2Nt (DataBits
);
1051 Private
->NtDCB
.Parity
= ConvertParity2Nt (Parity
);
1052 Private
->NtDCB
.StopBits
= ConvertStop2Nt (StopBits
);
1054 Private
->NtDCB
.fBinary
= TRUE
;
1055 Private
->NtDCB
.fParity
= Private
->NtDCB
.Parity
== NOPARITY
? FALSE
: TRUE
;
1056 Private
->NtDCB
.fOutxCtsFlow
= FALSE
;
1057 Private
->NtDCB
.fOutxDsrFlow
= FALSE
;
1058 Private
->NtDCB
.fDtrControl
= DTR_CONTROL_ENABLE
;
1059 Private
->NtDCB
.fDsrSensitivity
= FALSE
;
1060 Private
->NtDCB
.fOutX
= FALSE
;
1061 Private
->NtDCB
.fInX
= FALSE
;
1062 Private
->NtDCB
.fRtsControl
= RTS_CONTROL_ENABLE
;
1063 Private
->NtDCB
.fNull
= FALSE
;
1068 Result
= Private
->WinNtThunk
->SetCommState (Private
->NtHandle
, &Private
->NtDCB
);
1070 Private
->NtError
= Private
->WinNtThunk
->GetLastError ();
1071 DEBUG ((EFI_D_ERROR
, "SerialSetAttributes: SetCommState %d\n", Private
->NtError
));
1072 gBS
->RestoreTPL (Tpl
);
1073 return EFI_DEVICE_ERROR
;
1077 // Set com port read/write timeout values
1079 ConvertedTime
= ConvertTime2Nt (Timeout
);
1080 PortTimeOuts
.ReadIntervalTimeout
= MAXDWORD
;
1081 PortTimeOuts
.ReadTotalTimeoutMultiplier
= 0;
1082 PortTimeOuts
.ReadTotalTimeoutConstant
= ConvertedTime
;
1083 PortTimeOuts
.WriteTotalTimeoutMultiplier
= ConvertedTime
== 0 ? 1 : ConvertedTime
;
1084 PortTimeOuts
.WriteTotalTimeoutConstant
= 0;
1086 if (!Private
->WinNtThunk
->SetCommTimeouts (Private
->NtHandle
, &PortTimeOuts
)) {
1087 Private
->NtError
= Private
->WinNtThunk
->GetLastError ();
1088 DEBUG ((EFI_D_ERROR
, "SerialSetAttributes: SetCommTimeouts %d\n", Private
->NtError
));
1089 gBS
->RestoreTPL (Tpl
);
1090 return EFI_DEVICE_ERROR
;
1096 Private
->SerialIoMode
.BaudRate
= BaudRate
;
1097 Private
->SerialIoMode
.ReceiveFifoDepth
= ReceiveFifoDepth
;
1098 Private
->SerialIoMode
.Timeout
= Timeout
;
1099 Private
->SerialIoMode
.Parity
= Parity
;
1100 Private
->SerialIoMode
.DataBits
= DataBits
;
1101 Private
->SerialIoMode
.StopBits
= StopBits
;
1104 // See if Device Path Node has actually changed
1106 if (Private
->UartDevicePath
.BaudRate
== BaudRate
&&
1107 Private
->UartDevicePath
.DataBits
== DataBits
&&
1108 Private
->UartDevicePath
.Parity
== Parity
&&
1109 Private
->UartDevicePath
.StopBits
== StopBits
) {
1110 gBS
->RestoreTPL(Tpl
);
1115 // Update the device path
1117 Private
->UartDevicePath
.BaudRate
= BaudRate
;
1118 Private
->UartDevicePath
.DataBits
= DataBits
;
1119 Private
->UartDevicePath
.Parity
= (UINT8
) Parity
;
1120 Private
->UartDevicePath
.StopBits
= (UINT8
) StopBits
;
1122 Status
= EFI_SUCCESS
;
1123 if (Private
->Handle
!= NULL
) {
1124 Uart
= (UART_DEVICE_PATH
*) (
1125 (UINTN
) Private
->DevicePath
1126 + GetDevicePathSize (Private
->ParentDevicePath
)
1127 - END_DEVICE_PATH_LENGTH
1129 CopyMem (Uart
, &Private
->UartDevicePath
, sizeof (UART_DEVICE_PATH
));
1130 Status
= gBS
->ReinstallProtocolInterface (
1132 &gEfiDevicePathProtocolGuid
,
1133 Private
->DevicePath
,
1138 gBS
->RestoreTPL (Tpl
);
1145 WinNtSerialIoSetControl (
1146 IN EFI_SERIAL_IO_PROTOCOL
*This
,
1151 Routine Description:
1153 TODO: Add function description
1157 This - TODO: add argument description
1158 Control - TODO: add argument description
1162 EFI_DEVICE_ERROR - TODO: Add description for return value
1163 EFI_DEVICE_ERROR - TODO: Add description for return value
1164 EFI_SUCCESS - TODO: Add description for return value
1168 WIN_NT_SERIAL_IO_PRIVATE_DATA
*Private
;
1172 UART_FLOW_CONTROL_DEVICE_PATH
*FlowControl
;
1176 // first determine the parameter is invalid
1178 if (Control
& (~(EFI_SERIAL_REQUEST_TO_SEND
| EFI_SERIAL_DATA_TERMINAL_READY
|
1179 EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE
| EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE
|
1180 EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE
))) {
1181 return EFI_UNSUPPORTED
;
1184 Tpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1186 Private
= WIN_NT_SERIAL_IO_PRIVATE_DATA_FROM_THIS (This
);
1188 Result
= Private
->WinNtThunk
->GetCommState (Private
->NtHandle
, &Dcb
);
1191 Private
->NtError
= Private
->WinNtThunk
->GetLastError ();
1192 DEBUG ((EFI_D_ERROR
, "SerialSetControl: GetCommState %d\n", Private
->NtError
));
1193 gBS
->RestoreTPL (Tpl
);
1194 return EFI_DEVICE_ERROR
;
1197 Dcb
.fRtsControl
= RTS_CONTROL_DISABLE
;
1198 Dcb
.fDtrControl
= DTR_CONTROL_DISABLE
;
1199 Private
->HardwareFlowControl
= FALSE
;
1200 Private
->SoftwareLoopbackEnable
= FALSE
;
1201 Private
->HardwareLoopbackEnable
= FALSE
;
1203 if (Control
& EFI_SERIAL_REQUEST_TO_SEND
) {
1204 Dcb
.fRtsControl
= RTS_CONTROL_ENABLE
;
1207 if (Control
& EFI_SERIAL_DATA_TERMINAL_READY
) {
1208 Dcb
.fDtrControl
= DTR_CONTROL_ENABLE
;
1211 if (Control
& EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE
) {
1212 Private
->HardwareFlowControl
= TRUE
;
1215 if (Control
& EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE
) {
1216 Private
->SoftwareLoopbackEnable
= TRUE
;
1219 if (Control
& EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE
) {
1220 Private
->HardwareLoopbackEnable
= TRUE
;
1223 Result
= Private
->WinNtThunk
->SetCommState (
1229 Private
->NtError
= Private
->WinNtThunk
->GetLastError ();
1230 DEBUG ((EFI_D_ERROR
, "SerialSetControl: SetCommState %d\n", Private
->NtError
));
1231 gBS
->RestoreTPL (Tpl
);
1232 return EFI_DEVICE_ERROR
;
1235 Status
= EFI_SUCCESS
;
1236 if (Private
->Handle
!= NULL
) {
1237 FlowControl
= (UART_FLOW_CONTROL_DEVICE_PATH
*) (
1238 (UINTN
) Private
->DevicePath
1239 + GetDevicePathSize (Private
->ParentDevicePath
)
1240 - END_DEVICE_PATH_LENGTH
1241 + sizeof (UART_DEVICE_PATH
)
1243 if (IsUartFlowControlNode (FlowControl
) &&
1244 ((FlowControl
->FlowControlMap
== UART_FLOW_CONTROL_HARDWARE
) ^ Private
->HardwareFlowControl
)) {
1246 // Flow Control setting is changed, need to reinstall device path protocol
1248 FlowControl
->FlowControlMap
= Private
->HardwareFlowControl
? UART_FLOW_CONTROL_HARDWARE
: 0;
1249 Status
= gBS
->ReinstallProtocolInterface (
1251 &gEfiDevicePathProtocolGuid
,
1252 Private
->DevicePath
,
1258 gBS
->RestoreTPL (Tpl
);
1265 WinNtSerialIoGetControl (
1266 IN EFI_SERIAL_IO_PROTOCOL
*This
,
1271 Routine Description:
1273 TODO: Add function description
1277 This - TODO: add argument description
1278 Control - TODO: add argument description
1282 EFI_DEVICE_ERROR - TODO: Add description for return value
1283 EFI_DEVICE_ERROR - TODO: Add description for return value
1284 EFI_DEVICE_ERROR - TODO: Add description for return value
1285 EFI_SUCCESS - TODO: Add description for return value
1289 WIN_NT_SERIAL_IO_PRIVATE_DATA
*Private
;
1296 Tpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1298 Private
= WIN_NT_SERIAL_IO_PRIVATE_DATA_FROM_THIS (This
);
1303 if (!Private
->WinNtThunk
->GetCommModemStatus (Private
->NtHandle
, &ModemStatus
)) {
1304 Private
->NtError
= Private
->WinNtThunk
->GetLastError ();
1305 gBS
->RestoreTPL (Tpl
);
1306 return EFI_DEVICE_ERROR
;
1310 if (ModemStatus
& MS_CTS_ON
) {
1311 Bits
|= EFI_SERIAL_CLEAR_TO_SEND
;
1314 if (ModemStatus
& MS_DSR_ON
) {
1315 Bits
|= EFI_SERIAL_DATA_SET_READY
;
1318 if (ModemStatus
& MS_RING_ON
) {
1319 Bits
|= EFI_SERIAL_RING_INDICATE
;
1322 if (ModemStatus
& MS_RLSD_ON
) {
1323 Bits
|= EFI_SERIAL_CARRIER_DETECT
;
1329 if (!Private
->WinNtThunk
->GetCommState (Private
->NtHandle
, &Dcb
)) {
1330 Private
->NtError
= Private
->WinNtThunk
->GetLastError ();
1331 DEBUG ((EFI_D_ERROR
, "SerialGetControl: GetCommState %d\n", Private
->NtError
));
1332 gBS
->RestoreTPL (Tpl
);
1333 return EFI_DEVICE_ERROR
;
1336 if (Dcb
.fDtrControl
== DTR_CONTROL_ENABLE
) {
1337 Bits
|= EFI_SERIAL_DATA_TERMINAL_READY
;
1340 if (Dcb
.fRtsControl
== RTS_CONTROL_ENABLE
) {
1341 Bits
|= EFI_SERIAL_REQUEST_TO_SEND
;
1344 if (Private
->HardwareFlowControl
) {
1345 Bits
|= EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE
;
1348 if (Private
->SoftwareLoopbackEnable
) {
1349 Bits
|= EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE
;
1352 if (Private
->HardwareLoopbackEnable
) {
1353 Bits
|= EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE
;
1357 // Get input buffer status
1359 if (!Private
->WinNtThunk
->ClearCommError (Private
->NtHandle
, &Errors
, &Private
->NtComStatus
)) {
1360 Private
->NtError
= Private
->WinNtThunk
->GetLastError ();
1361 DEBUG ((EFI_D_ERROR
, "SerialGetControl: ClearCommError %d\n", Private
->NtError
));
1362 gBS
->RestoreTPL (Tpl
);
1363 return EFI_DEVICE_ERROR
;
1366 if (Private
->NtComStatus
.cbInQue
== 0) {
1367 Bits
|= EFI_SERIAL_INPUT_BUFFER_EMPTY
;
1372 gBS
->RestoreTPL (Tpl
);
1379 WinNtSerialIoWrite (
1380 IN EFI_SERIAL_IO_PROTOCOL
*This
,
1381 IN OUT UINTN
*BufferSize
,
1386 Routine Description:
1388 TODO: Add function description
1392 This - TODO: add argument description
1393 BufferSize - TODO: add argument description
1394 Buffer - TODO: add argument description
1398 EFI_DEVICE_ERROR - TODO: Add description for return value
1399 EFI_SUCCESS - TODO: Add description for return value
1403 WIN_NT_SERIAL_IO_PRIVATE_DATA
*Private
;
1405 UINTN TotalBytesWritten
;
1413 Tpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1415 Private
= WIN_NT_SERIAL_IO_PRIVATE_DATA_FROM_THIS (This
);
1417 ByteBuffer
= (UINT8
*) Buffer
;
1418 TotalBytesWritten
= 0;
1420 if (Private
->SoftwareLoopbackEnable
|| Private
->HardwareLoopbackEnable
) {
1421 for (Index
= 0; Index
< *BufferSize
; Index
++) {
1422 if (IsaSerialFifoAdd (&Private
->Fifo
, ByteBuffer
[Index
]) == EFI_SUCCESS
) {
1423 TotalBytesWritten
++;
1429 BytesToGo
= (DWORD
) (*BufferSize
);
1432 if (Private
->HardwareFlowControl
) {
1436 WinNtSerialIoGetControl (&Private
->SerialIo
, &Control
);
1437 Control
|= EFI_SERIAL_REQUEST_TO_SEND
;
1438 WinNtSerialIoSetControl (&Private
->SerialIo
, Control
);
1444 Result
= Private
->WinNtThunk
->WriteFile (
1446 &ByteBuffer
[TotalBytesWritten
],
1452 if (Private
->HardwareFlowControl
) {
1456 WinNtSerialIoGetControl (&Private
->SerialIo
, &Control
);
1457 Control
&= ~ (UINT32
) EFI_SERIAL_REQUEST_TO_SEND
;
1458 WinNtSerialIoSetControl (&Private
->SerialIo
, Control
);
1461 TotalBytesWritten
+= BytesWritten
;
1462 BytesToGo
-= BytesWritten
;
1464 Private
->NtError
= Private
->WinNtThunk
->GetLastError ();
1465 DEBUG ((EFI_D_ERROR
, "SerialWrite: FileWrite %d\n", Private
->NtError
));
1466 *BufferSize
= TotalBytesWritten
;
1467 gBS
->RestoreTPL (Tpl
);
1468 return EFI_DEVICE_ERROR
;
1470 } while (BytesToGo
> 0);
1473 *BufferSize
= TotalBytesWritten
;
1475 gBS
->RestoreTPL (Tpl
);
1483 IN EFI_SERIAL_IO_PROTOCOL
*This
,
1484 IN OUT UINTN
*BufferSize
,
1489 Routine Description:
1491 TODO: Add function description
1495 This - TODO: add argument description
1496 BufferSize - TODO: add argument description
1497 Buffer - TODO: add argument description
1501 EFI_DEVICE_ERROR - TODO: Add description for return value
1505 WIN_NT_SERIAL_IO_PRIVATE_DATA
*Private
;
1514 Tpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1516 Private
= WIN_NT_SERIAL_IO_PRIVATE_DATA_FROM_THIS (This
);
1521 if (Private
->SoftwareLoopbackEnable
|| Private
->HardwareLoopbackEnable
) {
1522 for (Index
= 0, BytesRead
= 0; Index
< *BufferSize
; Index
++) {
1523 if (IsaSerialFifoRemove (&Private
->Fifo
, &Data
) == EFI_SUCCESS
) {
1524 ((UINT8
*) Buffer
)[Index
] = Data
;
1531 if (Private
->HardwareFlowControl
) {
1532 WinNtSerialIoGetControl (&Private
->SerialIo
, &Control
);
1533 Control
|= EFI_SERIAL_DATA_TERMINAL_READY
;
1534 WinNtSerialIoSetControl (&Private
->SerialIo
, Control
);
1537 Result
= Private
->WinNtThunk
->ReadFile (
1540 (DWORD
) *BufferSize
,
1545 if (Private
->HardwareFlowControl
) {
1546 WinNtSerialIoGetControl (&Private
->SerialIo
, &Control
);
1547 Control
&= ~ (UINT32
) EFI_SERIAL_DATA_TERMINAL_READY
;
1548 WinNtSerialIoSetControl (&Private
->SerialIo
, Control
);
1552 Private
->NtError
= Private
->WinNtThunk
->GetLastError ();
1553 gBS
->RestoreTPL (Tpl
);
1554 return EFI_DEVICE_ERROR
;
1558 if (BytesRead
!= *BufferSize
) {
1559 Status
= EFI_TIMEOUT
;
1561 Status
= EFI_SUCCESS
;
1564 *BufferSize
= (UINTN
) BytesRead
;
1566 gBS
->RestoreTPL (Tpl
);
1573 IN SERIAL_DEV_FIFO
*Fifo
1577 Routine Description:
1578 Detect whether specific FIFO is full or not
1581 Fifo SERIAL_DEV_FIFO *: A pointer to the Data Structure SERIAL_DEV_FIFO
1584 TRUE: the FIFO is full
1585 FALSE: the FIFO is not full
1589 if (Fifo
->Surplus
== 0) {
1597 IsaSerialFifoEmpty (
1598 IN SERIAL_DEV_FIFO
*Fifo
1602 Routine Description:
1603 Detect whether specific FIFO is empty or not
1606 Fifo SERIAL_DEV_FIFO *: A pointer to the Data Structure SERIAL_DEV_FIFO
1609 TRUE: the FIFO is empty
1610 FALSE: the FIFO is not empty
1614 if (Fifo
->Surplus
== SERIAL_MAX_BUFFER_SIZE
) {
1623 IN SERIAL_DEV_FIFO
*Fifo
,
1628 Routine Description:
1629 Add data to specific FIFO
1632 Fifo SERIAL_DEV_FIFO *: A pointer to the Data Structure SERIAL_DEV_FIFO
1633 Data UINT8: the data added to FIFO
1636 EFI_SUCCESS: Add data to specific FIFO successfully
1637 EFI_OUT_RESOURCE: Failed to add data because FIFO is already full
1640 // TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
1643 // if FIFO full can not add data
1645 if (IsaSerialFifoFull (Fifo
)) {
1646 return EFI_OUT_OF_RESOURCES
;
1650 // FIFO is not full can add data
1652 Fifo
->Data
[Fifo
->Last
] = Data
;
1655 if (Fifo
->Last
>= SERIAL_MAX_BUFFER_SIZE
) {
1663 IsaSerialFifoRemove (
1664 IN SERIAL_DEV_FIFO
*Fifo
,
1669 Routine Description:
1670 Remove data from specific FIFO
1673 Fifo SERIAL_DEV_FIFO *: A pointer to the Data Structure SERIAL_DEV_FIFO
1674 Data UINT8*: the data removed from FIFO
1677 EFI_SUCCESS: Remove data from specific FIFO successfully
1678 EFI_OUT_RESOURCE: Failed to remove data because FIFO is empty
1681 // TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
1684 // if FIFO is empty, no data can remove
1686 if (IsaSerialFifoEmpty (Fifo
)) {
1687 return EFI_OUT_OF_RESOURCES
;
1691 // FIFO is not empty, can remove data
1693 *Data
= Fifo
->Data
[Fifo
->First
];
1696 if (Fifo
->First
>= SERIAL_MAX_BUFFER_SIZE
) {