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
;
180 // Check RemainingDevicePath validation
182 if (RemainingDevicePath
!= NULL
) {
184 // Check if RemainingDevicePath is the End of Device Path Node,
185 // if yes, go on checking other conditions
187 if (!IsDevicePathEnd (RemainingDevicePath
)) {
189 // If RemainingDevicePath isn't the End of Device Path Node,
190 // check its validation
192 Status
= EFI_UNSUPPORTED
;
194 UartNode
= (UART_DEVICE_PATH
*) RemainingDevicePath
;
195 if (UartNode
->Header
.Type
!= MESSAGING_DEVICE_PATH
||
196 UartNode
->Header
.SubType
!= MSG_UART_DP
||
197 DevicePathNodeLength((EFI_DEVICE_PATH_PROTOCOL
*)UartNode
) != sizeof(UART_DEVICE_PATH
)) {
200 if ( UartNode
->BaudRate
> SERIAL_PORT_MAX_BAUD_RATE
) {
203 if (UartNode
->Parity
< NoParity
|| UartNode
->Parity
> SpaceParity
) {
206 if (UartNode
->DataBits
< 5 || UartNode
->DataBits
> 8) {
209 if (UartNode
->StopBits
< OneStopBit
|| UartNode
->StopBits
> TwoStopBits
) {
212 if ((UartNode
->DataBits
== 5) && (UartNode
->StopBits
== TwoStopBits
)) {
215 if ((UartNode
->DataBits
>= 6) && (UartNode
->DataBits
<= 8) && (UartNode
->StopBits
== OneFiveStopBits
)) {
219 FlowControlNode
= (UART_FLOW_CONTROL_DEVICE_PATH
*) NextDevicePathNode (UartNode
);
220 if (IsUartFlowControlNode (FlowControlNode
)) {
222 // If the second node is Flow Control Node,
223 // return error when it request other than hardware flow control.
225 if ((FlowControlNode
->FlowControlMap
& ~UART_FLOW_CONTROL_HARDWARE
) != 0) {
233 // Open the IO Abstraction(s) needed to perform the supported test
235 Status
= gBS
->OpenProtocol (
237 &gEfiWinNtIoProtocolGuid
,
239 This
->DriverBindingHandle
,
241 EFI_OPEN_PROTOCOL_BY_DRIVER
243 if (Status
== EFI_ALREADY_STARTED
) {
244 if (RemainingDevicePath
== NULL
|| IsDevicePathEnd (RemainingDevicePath
)) {
246 // If RemainingDevicePath is NULL or is the End of Device Path Node
251 // When the driver has produced device path with flow control node but RemainingDevicePath only contains UART node,
252 // return unsupported, and vice versa.
254 Status
= gBS
->OpenProtocolInformation (
256 &gEfiWinNtIoProtocolGuid
,
260 if (EFI_ERROR (Status
)) {
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 (ContainsFlowControl (RemainingDevicePath
) ^ ContainsFlowControl (DevicePath
))) {
276 Status
= EFI_UNSUPPORTED
;
281 FreePool (OpenInfoBuffer
);
285 if (EFI_ERROR (Status
)) {
290 // Close the I/O Abstraction(s) used to perform the supported test
294 &gEfiWinNtIoProtocolGuid
,
295 This
->DriverBindingHandle
,
300 // Open the EFI Device Path protocol needed to perform the supported test
302 Status
= gBS
->OpenProtocol (
304 &gEfiDevicePathProtocolGuid
,
305 (VOID
**) &ParentDevicePath
,
306 This
->DriverBindingHandle
,
308 EFI_OPEN_PROTOCOL_BY_DRIVER
310 if (Status
== EFI_ALREADY_STARTED
) {
314 if (EFI_ERROR (Status
)) {
319 // Close protocol, don't use device path protocol in the Support() function
323 &gEfiDevicePathProtocolGuid
,
324 This
->DriverBindingHandle
,
329 // Make sure that the WinNt Thunk Protocol is valid
331 if (WinNtIo
->WinNtThunk
->Signature
!= EFI_WIN_NT_THUNK_PROTOCOL_SIGNATURE
) {
332 Status
= EFI_UNSUPPORTED
;
337 // Check the GUID to see if this is a handle type the driver supports
339 if (!CompareGuid (WinNtIo
->TypeGuid
, &gEfiWinNtSerialPortGuid
)) {
340 Status
= EFI_UNSUPPORTED
;
352 WinNtSerialIoDriverBindingStart (
353 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
354 IN EFI_HANDLE Handle
,
355 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
368 // TODO: This - add argument and description to function comment
369 // TODO: Handle - add argument and description to function comment
370 // TODO: RemainingDevicePath - add argument and description to function comment
371 // TODO: EFI_SUCCESS - add return value to function comment
372 // TODO: EFI_SUCCESS - add return value to function comment
375 EFI_WIN_NT_IO_PROTOCOL
*WinNtIo
;
376 WIN_NT_SERIAL_IO_PRIVATE_DATA
*Private
;
378 UART_DEVICE_PATH UartNode
;
379 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
380 EFI_OPEN_PROTOCOL_INFORMATION_ENTRY
*OpenInfoBuffer
;
383 EFI_SERIAL_IO_PROTOCOL
*SerialIo
;
384 UART_DEVICE_PATH
*Uart
;
385 UINT32 FlowControlMap
;
386 UART_FLOW_CONTROL_DEVICE_PATH
*FlowControl
;
387 EFI_DEVICE_PATH_PROTOCOL
*TempDevicePath
;
391 NtHandle
= INVALID_HANDLE_VALUE
;
394 // Get the Parent Device Path
396 Status
= gBS
->OpenProtocol (
398 &gEfiDevicePathProtocolGuid
,
399 (VOID
**) &ParentDevicePath
,
400 This
->DriverBindingHandle
,
402 EFI_OPEN_PROTOCOL_BY_DRIVER
404 if (EFI_ERROR (Status
) && Status
!= EFI_ALREADY_STARTED
) {
409 // Grab the IO abstraction we need to get any work done
411 Status
= gBS
->OpenProtocol (
413 &gEfiWinNtIoProtocolGuid
,
415 This
->DriverBindingHandle
,
417 EFI_OPEN_PROTOCOL_BY_DRIVER
419 if (EFI_ERROR (Status
) && Status
!= EFI_ALREADY_STARTED
) {
422 &gEfiDevicePathProtocolGuid
,
423 This
->DriverBindingHandle
,
429 if (Status
== EFI_ALREADY_STARTED
) {
431 if (RemainingDevicePath
== NULL
|| IsDevicePathEnd (RemainingDevicePath
)) {
433 // If RemainingDevicePath is NULL or is the End of Device Path Node
439 // Make sure a child handle does not already exist. This driver can only
440 // produce one child per serial port.
442 Status
= gBS
->OpenProtocolInformation (
444 &gEfiWinNtIoProtocolGuid
,
448 if (EFI_ERROR (Status
)) {
452 Status
= EFI_ALREADY_STARTED
;
453 for (Index
= 0; Index
< EntryCount
; Index
++) {
454 if ((OpenInfoBuffer
[Index
].Attributes
& EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
) != 0) {
455 Status
= gBS
->OpenProtocol (
456 OpenInfoBuffer
[Index
].ControllerHandle
,
457 &gEfiSerialIoProtocolGuid
,
459 This
->DriverBindingHandle
,
461 EFI_OPEN_PROTOCOL_GET_PROTOCOL
463 if (!EFI_ERROR (Status
)) {
464 Uart
= (UART_DEVICE_PATH
*) RemainingDevicePath
;
465 Status
= SerialIo
->SetAttributes (
468 SerialIo
->Mode
->ReceiveFifoDepth
,
469 SerialIo
->Mode
->Timeout
,
470 (EFI_PARITY_TYPE
) Uart
->Parity
,
472 (EFI_STOP_BITS_TYPE
) Uart
->StopBits
474 FlowControl
= (UART_FLOW_CONTROL_DEVICE_PATH
*) NextDevicePathNode (Uart
);
475 if (!EFI_ERROR (Status
) && IsUartFlowControlNode (FlowControl
)) {
476 Status
= SerialIo
->GetControl (SerialIo
, &Control
);
477 if (!EFI_ERROR (Status
)) {
478 if (FlowControl
->FlowControlMap
== UART_FLOW_CONTROL_HARDWARE
) {
479 Control
|= EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE
;
481 Control
&= ~EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE
;
484 // Clear the bits that are not allowed to pass to SetControl
486 Control
&= (EFI_SERIAL_REQUEST_TO_SEND
| EFI_SERIAL_DATA_TERMINAL_READY
|
487 EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE
| EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE
|
488 EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE
);
489 Status
= SerialIo
->SetControl (SerialIo
, Control
);
497 FreePool (OpenInfoBuffer
);
503 if (RemainingDevicePath
== NULL
) {
505 // Build the device path by appending the UART node to the ParentDevicePath
506 // from the WinNtIo handle. The Uart setings are zero here, since
507 // SetAttribute() will update them to match the default setings.
509 ZeroMem (&UartNode
, sizeof (UART_DEVICE_PATH
));
510 UartNode
.Header
.Type
= MESSAGING_DEVICE_PATH
;
511 UartNode
.Header
.SubType
= MSG_UART_DP
;
512 SetDevicePathNodeLength ((EFI_DEVICE_PATH_PROTOCOL
*) &UartNode
, sizeof (UART_DEVICE_PATH
));
514 } else if (!IsDevicePathEnd (RemainingDevicePath
)) {
516 // If RemainingDevicePath isn't the End of Device Path Node,
517 // only scan the specified device by RemainingDevicePath
520 // Match the configuration of the RemainingDevicePath. IsHandleSupported()
521 // already checked to make sure the RemainingDevicePath contains settings
522 // that we can support.
524 CopyMem (&UartNode
, RemainingDevicePath
, sizeof (UART_DEVICE_PATH
));
525 FlowControl
= (UART_FLOW_CONTROL_DEVICE_PATH
*) NextDevicePathNode (RemainingDevicePath
);
526 if (IsUartFlowControlNode (FlowControl
)) {
527 FlowControlMap
= FlowControl
->FlowControlMap
;
534 // If RemainingDevicePath is the End of Device Path Node,
535 // skip enumerate any device and return EFI_SUCESSS
541 // Check to see if we can access the hardware device. If it's Open in NT we
542 // will not get access.
544 NtHandle
= WinNtIo
->WinNtThunk
->CreateFile (
546 GENERIC_READ
| GENERIC_WRITE
,
553 if (NtHandle
== INVALID_HANDLE_VALUE
) {
554 Status
= EFI_DEVICE_ERROR
;
559 // Construct Private data
561 Private
= AllocatePool (sizeof (WIN_NT_SERIAL_IO_PRIVATE_DATA
));
562 if (Private
== NULL
) {
567 // This signature must be valid before any member function is called
569 Private
->Signature
= WIN_NT_SERIAL_IO_PRIVATE_DATA_SIGNATURE
;
570 Private
->NtHandle
= NtHandle
;
571 Private
->ControllerHandle
= Handle
;
572 Private
->Handle
= NULL
;
573 Private
->WinNtThunk
= WinNtIo
->WinNtThunk
;
574 Private
->ParentDevicePath
= ParentDevicePath
;
575 Private
->ControllerNameTable
= NULL
;
577 Private
->SoftwareLoopbackEnable
= FALSE
;
578 Private
->HardwareLoopbackEnable
= FALSE
;
579 Private
->HardwareFlowControl
= (BOOLEAN
) (FlowControlMap
== UART_FLOW_CONTROL_HARDWARE
);
580 Private
->Fifo
.First
= 0;
581 Private
->Fifo
.Last
= 0;
582 Private
->Fifo
.Surplus
= SERIAL_MAX_BUFFER_SIZE
;
584 CopyMem (&Private
->UartDevicePath
, &UartNode
, sizeof (UART_DEVICE_PATH
));
588 gWinNtSerialIoComponentName
.SupportedLanguages
,
589 &Private
->ControllerNameTable
,
595 gWinNtSerialIoComponentName2
.SupportedLanguages
,
596 &Private
->ControllerNameTable
,
602 Private
->SerialIo
.Revision
= SERIAL_IO_INTERFACE_REVISION
;
603 Private
->SerialIo
.Reset
= WinNtSerialIoReset
;
604 Private
->SerialIo
.SetAttributes
= WinNtSerialIoSetAttributes
;
605 Private
->SerialIo
.SetControl
= WinNtSerialIoSetControl
;
606 Private
->SerialIo
.GetControl
= WinNtSerialIoGetControl
;
607 Private
->SerialIo
.Write
= WinNtSerialIoWrite
;
608 Private
->SerialIo
.Read
= WinNtSerialIoRead
;
609 Private
->SerialIo
.Mode
= &Private
->SerialIoMode
;
612 // Build the device path by appending the UART node to the ParentDevicePath
613 // from the WinNtIo handle. The Uart setings are zero here, since
614 // SetAttribute() will update them to match the current setings.
616 Private
->DevicePath
= AppendDevicePathNode (
618 (EFI_DEVICE_PATH_PROTOCOL
*) &Private
->UartDevicePath
621 // Only produce the FlowControl node when remaining device path has it
623 if (FlowControl
!= NULL
) {
624 TempDevicePath
= Private
->DevicePath
;
625 if (TempDevicePath
!= NULL
) {
626 Private
->DevicePath
= AppendDevicePathNode (
628 (EFI_DEVICE_PATH_PROTOCOL
*) FlowControl
630 FreePool (TempDevicePath
);
633 if (Private
->DevicePath
== NULL
) {
634 Status
= EFI_OUT_OF_RESOURCES
;
639 // Fill in Serial I/O Mode structure based on either the RemainingDevicePath or defaults.
641 Private
->SerialIoMode
.ControlMask
= SERIAL_CONTROL_MASK
;
642 Private
->SerialIoMode
.Timeout
= SERIAL_TIMEOUT_DEFAULT
;
643 Private
->SerialIoMode
.BaudRate
= Private
->UartDevicePath
.BaudRate
;
644 Private
->SerialIoMode
.ReceiveFifoDepth
= SERIAL_FIFO_DEFAULT
;
645 Private
->SerialIoMode
.DataBits
= Private
->UartDevicePath
.DataBits
;
646 Private
->SerialIoMode
.Parity
= Private
->UartDevicePath
.Parity
;
647 Private
->SerialIoMode
.StopBits
= Private
->UartDevicePath
.StopBits
;
650 // Issue a reset to initialize the COM port
652 Status
= Private
->SerialIo
.Reset (&Private
->SerialIo
);
653 if (EFI_ERROR (Status
)) {
658 // Create new child handle
660 Status
= gBS
->InstallMultipleProtocolInterfaces (
662 &gEfiSerialIoProtocolGuid
,
664 &gEfiDevicePathProtocolGuid
,
668 if (EFI_ERROR (Status
)) {
673 // Open For Child Device
675 Status
= gBS
->OpenProtocol (
677 &gEfiWinNtIoProtocolGuid
,
679 This
->DriverBindingHandle
,
681 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
683 if (EFI_ERROR (Status
)) {
691 // Use the Stop() function to free all resources allocated in Start()
693 if (Private
!= NULL
) {
694 if (Private
->Handle
!= NULL
) {
695 This
->Stop (This
, Handle
, 1, &Private
->Handle
);
697 if (NtHandle
!= INVALID_HANDLE_VALUE
) {
698 Private
->WinNtThunk
->CloseHandle (NtHandle
);
701 if (Private
->DevicePath
!= NULL
) {
702 FreePool (Private
->DevicePath
);
705 FreeUnicodeStringTable (Private
->ControllerNameTable
);
711 This
->Stop (This
, Handle
, 0, NULL
);
718 WinNtSerialIoDriverBindingStop (
719 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
720 IN EFI_HANDLE Handle
,
721 IN UINTN NumberOfChildren
,
722 IN EFI_HANDLE
*ChildHandleBuffer
728 TODO: Add function description
732 This - TODO: add argument description
733 Handle - TODO: add argument description
734 NumberOfChildren - TODO: add argument description
735 ChildHandleBuffer - TODO: add argument description
739 EFI_DEVICE_ERROR - TODO: Add description for return value
740 EFI_SUCCESS - TODO: Add description for return value
746 BOOLEAN AllChildrenStopped
;
747 EFI_SERIAL_IO_PROTOCOL
*SerialIo
;
748 WIN_NT_SERIAL_IO_PRIVATE_DATA
*Private
;
749 EFI_WIN_NT_IO_PROTOCOL
*WinNtIo
;
752 // Complete all outstanding transactions to Controller.
753 // Don't allow any new transaction to Controller to be started.
756 if (NumberOfChildren
== 0) {
758 // Close the bus driver
760 Status
= gBS
->CloseProtocol (
762 &gEfiWinNtIoProtocolGuid
,
763 This
->DriverBindingHandle
,
766 Status
= gBS
->CloseProtocol (
768 &gEfiDevicePathProtocolGuid
,
769 This
->DriverBindingHandle
,
775 AllChildrenStopped
= TRUE
;
777 for (Index
= 0; Index
< NumberOfChildren
; Index
++) {
778 Status
= gBS
->OpenProtocol (
779 ChildHandleBuffer
[Index
],
780 &gEfiSerialIoProtocolGuid
,
782 This
->DriverBindingHandle
,
784 EFI_OPEN_PROTOCOL_GET_PROTOCOL
786 if (!EFI_ERROR (Status
)) {
787 Private
= WIN_NT_SERIAL_IO_PRIVATE_DATA_FROM_THIS (SerialIo
);
789 ASSERT (Private
->Handle
== ChildHandleBuffer
[Index
]);
791 Status
= gBS
->CloseProtocol (
793 &gEfiWinNtIoProtocolGuid
,
794 This
->DriverBindingHandle
,
795 ChildHandleBuffer
[Index
]
798 Status
= gBS
->UninstallMultipleProtocolInterfaces (
799 ChildHandleBuffer
[Index
],
800 &gEfiSerialIoProtocolGuid
,
802 &gEfiDevicePathProtocolGuid
,
807 if (EFI_ERROR (Status
)) {
810 &gEfiWinNtIoProtocolGuid
,
812 This
->DriverBindingHandle
,
813 ChildHandleBuffer
[Index
],
814 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
817 Private
->WinNtThunk
->CloseHandle (Private
->NtHandle
);
819 FreePool (Private
->DevicePath
);
821 FreeUnicodeStringTable (Private
->ControllerNameTable
);
827 if (EFI_ERROR (Status
)) {
828 AllChildrenStopped
= FALSE
;
832 if (!AllChildrenStopped
) {
833 return EFI_DEVICE_ERROR
;
840 // Serial IO Protocol member functions
846 IN EFI_SERIAL_IO_PROTOCOL
*This
852 TODO: Add function description
856 This - TODO: add argument description
860 TODO: add return values
864 WIN_NT_SERIAL_IO_PRIVATE_DATA
*Private
;
867 Tpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
869 Private
= WIN_NT_SERIAL_IO_PRIVATE_DATA_FROM_THIS (This
);
871 Private
->WinNtThunk
->PurgeComm (
873 PURGE_TXCLEAR
| PURGE_RXCLEAR
876 gBS
->RestoreTPL (Tpl
);
878 return This
->SetAttributes (
880 This
->Mode
->BaudRate
,
881 This
->Mode
->ReceiveFifoDepth
,
883 (EFI_PARITY_TYPE
)This
->Mode
->Parity
,
884 (UINT8
) This
->Mode
->DataBits
,
885 (EFI_STOP_BITS_TYPE
)This
->Mode
->StopBits
891 WinNtSerialIoSetAttributes (
892 IN EFI_SERIAL_IO_PROTOCOL
*This
,
894 IN UINT32 ReceiveFifoDepth
,
896 IN EFI_PARITY_TYPE Parity
,
898 IN EFI_STOP_BITS_TYPE StopBits
904 This function is used to set the attributes.
908 This - A pointer to the EFI_SERIAL_IO_PROTOCOL structrue.
909 BaudRate - The Baud rate of the serial device.
910 ReceiveFifoDepth - The request depth of fifo on receive side.
911 Timeout - the request timeout for a single charact.
912 Parity - The type of parity used in serial device.
913 DataBits - Number of deata bits used in serial device.
914 StopBits - Number of stop bits used in serial device.
922 // TODO: EFI_SUCCESS - add return value to function comment
923 // TODO: EFI_DEVICE_ERROR - 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_SUCCESS - add return value to function comment
927 // TODO: EFI_DEVICE_ERROR - add return value to function comment
928 // TODO: EFI_SUCCESS - add return value to function comment
932 WIN_NT_SERIAL_IO_PRIVATE_DATA
*Private
;
933 COMMTIMEOUTS PortTimeOuts
;
936 UART_DEVICE_PATH
*Uart
;
939 Private
= WIN_NT_SERIAL_IO_PRIVATE_DATA_FROM_THIS (This
);
942 // Some of our arguments have defaults if a null value is passed in, and
943 // we must set the default values if a null argument is passed in.
946 BaudRate
= PcdGet64 (PcdUartDefaultBaudRate
);
949 if (ReceiveFifoDepth
== 0) {
950 ReceiveFifoDepth
= SERIAL_FIFO_DEFAULT
;
954 Timeout
= SERIAL_TIMEOUT_DEFAULT
;
957 if (Parity
== DefaultParity
) {
958 Parity
= (EFI_PARITY_TYPE
) (PcdGet8 (PcdUartDefaultParity
));
962 DataBits
= PcdGet8 (PcdUartDefaultDataBits
);
965 if (StopBits
== DefaultStopBits
) {
966 StopBits
= (EFI_STOP_BITS_TYPE
) PcdGet8 (PcdUartDefaultStopBits
);
970 // Make sure all parameters are valid
972 if ((BaudRate
> SERIAL_PORT_MAX_BAUD_RATE
) || (BaudRate
< SERIAL_PORT_MIN_BAUD_RATE
)) {
973 return EFI_INVALID_PARAMETER
;
977 //The lower baud rate supported by the serial device will be selected without exceeding the unsupported BaudRate parameter
980 for (Index
= 1; Index
< (sizeof (mBaudRateCurrentSupport
) / sizeof (mBaudRateCurrentSupport
[0])); Index
++) {
981 if (BaudRate
< mBaudRateCurrentSupport
[Index
]) {
982 BaudRate
= mBaudRateCurrentSupport
[Index
-1];
987 if ((ReceiveFifoDepth
< 1) || (ReceiveFifoDepth
> SERIAL_PORT_MAX_RECEIVE_FIFO_DEPTH
)) {
988 return EFI_INVALID_PARAMETER
;
991 if ((Timeout
< SERIAL_PORT_MIN_TIMEOUT
) || (Timeout
> SERIAL_PORT_MAX_TIMEOUT
)) {
992 return EFI_INVALID_PARAMETER
;
995 if ((Parity
< NoParity
) || (Parity
> SpaceParity
)) {
996 return EFI_INVALID_PARAMETER
;
999 if ((StopBits
< OneStopBit
) || (StopBits
> TwoStopBits
)) {
1000 return EFI_INVALID_PARAMETER
;
1004 // Now we only support DataBits=7,8.
1006 if ((DataBits
< 7) || (DataBits
> 8)) {
1007 return EFI_INVALID_PARAMETER
;
1011 // Now we only support DataBits=7,8.
1012 // for DataBits = 6,7,8, StopBits can not set OneFiveStopBits.
1014 if (StopBits
== OneFiveStopBits
) {
1015 return EFI_INVALID_PARAMETER
;
1019 // See if the new attributes already match the current attributes
1021 if (Private
->UartDevicePath
.BaudRate
== BaudRate
&&
1022 Private
->UartDevicePath
.DataBits
== DataBits
&&
1023 Private
->UartDevicePath
.Parity
== Parity
&&
1024 Private
->UartDevicePath
.StopBits
== StopBits
&&
1025 Private
->SerialIoMode
.ReceiveFifoDepth
== ReceiveFifoDepth
&&
1026 Private
->SerialIoMode
.Timeout
== Timeout
) {
1030 Tpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1033 // Get current values from NT
1035 ZeroMem (&Private
->NtDCB
, sizeof (DCB
));
1036 Private
->NtDCB
.DCBlength
= sizeof (DCB
);
1038 if (!Private
->WinNtThunk
->GetCommState (Private
->NtHandle
, &Private
->NtDCB
)) {
1039 Private
->NtError
= Private
->WinNtThunk
->GetLastError ();
1040 DEBUG ((EFI_D_ERROR
, "SerialSetAttributes: GetCommState %d\n", Private
->NtError
));
1041 gBS
->RestoreTPL (Tpl
);
1042 return EFI_DEVICE_ERROR
;
1046 // Map EFI com setting to NT
1048 Private
->NtDCB
.BaudRate
= ConvertBaud2Nt (BaudRate
);
1049 Private
->NtDCB
.ByteSize
= ConvertData2Nt (DataBits
);
1050 Private
->NtDCB
.Parity
= ConvertParity2Nt (Parity
);
1051 Private
->NtDCB
.StopBits
= ConvertStop2Nt (StopBits
);
1053 Private
->NtDCB
.fBinary
= TRUE
;
1054 Private
->NtDCB
.fParity
= Private
->NtDCB
.Parity
== NOPARITY
? FALSE
: TRUE
;
1055 Private
->NtDCB
.fOutxCtsFlow
= FALSE
;
1056 Private
->NtDCB
.fOutxDsrFlow
= FALSE
;
1057 Private
->NtDCB
.fDtrControl
= DTR_CONTROL_ENABLE
;
1058 Private
->NtDCB
.fDsrSensitivity
= FALSE
;
1059 Private
->NtDCB
.fOutX
= FALSE
;
1060 Private
->NtDCB
.fInX
= FALSE
;
1061 Private
->NtDCB
.fRtsControl
= RTS_CONTROL_ENABLE
;
1062 Private
->NtDCB
.fNull
= FALSE
;
1067 Result
= Private
->WinNtThunk
->SetCommState (Private
->NtHandle
, &Private
->NtDCB
);
1069 Private
->NtError
= Private
->WinNtThunk
->GetLastError ();
1070 DEBUG ((EFI_D_ERROR
, "SerialSetAttributes: SetCommState %d\n", Private
->NtError
));
1071 gBS
->RestoreTPL (Tpl
);
1072 return EFI_DEVICE_ERROR
;
1076 // Set com port read/write timeout values
1078 ConvertedTime
= ConvertTime2Nt (Timeout
);
1079 PortTimeOuts
.ReadIntervalTimeout
= MAXDWORD
;
1080 PortTimeOuts
.ReadTotalTimeoutMultiplier
= 0;
1081 PortTimeOuts
.ReadTotalTimeoutConstant
= ConvertedTime
;
1082 PortTimeOuts
.WriteTotalTimeoutMultiplier
= ConvertedTime
== 0 ? 1 : ConvertedTime
;
1083 PortTimeOuts
.WriteTotalTimeoutConstant
= 0;
1085 if (!Private
->WinNtThunk
->SetCommTimeouts (Private
->NtHandle
, &PortTimeOuts
)) {
1086 Private
->NtError
= Private
->WinNtThunk
->GetLastError ();
1087 DEBUG ((EFI_D_ERROR
, "SerialSetAttributes: SetCommTimeouts %d\n", Private
->NtError
));
1088 gBS
->RestoreTPL (Tpl
);
1089 return EFI_DEVICE_ERROR
;
1095 Private
->SerialIoMode
.BaudRate
= BaudRate
;
1096 Private
->SerialIoMode
.ReceiveFifoDepth
= ReceiveFifoDepth
;
1097 Private
->SerialIoMode
.Timeout
= Timeout
;
1098 Private
->SerialIoMode
.Parity
= Parity
;
1099 Private
->SerialIoMode
.DataBits
= DataBits
;
1100 Private
->SerialIoMode
.StopBits
= StopBits
;
1103 // See if Device Path Node has actually changed
1105 if (Private
->UartDevicePath
.BaudRate
== BaudRate
&&
1106 Private
->UartDevicePath
.DataBits
== DataBits
&&
1107 Private
->UartDevicePath
.Parity
== Parity
&&
1108 Private
->UartDevicePath
.StopBits
== StopBits
) {
1109 gBS
->RestoreTPL(Tpl
);
1114 // Update the device path
1116 Private
->UartDevicePath
.BaudRate
= BaudRate
;
1117 Private
->UartDevicePath
.DataBits
= DataBits
;
1118 Private
->UartDevicePath
.Parity
= (UINT8
) Parity
;
1119 Private
->UartDevicePath
.StopBits
= (UINT8
) StopBits
;
1121 Status
= EFI_SUCCESS
;
1122 if (Private
->Handle
!= NULL
) {
1123 Uart
= (UART_DEVICE_PATH
*) (
1124 (UINTN
) Private
->DevicePath
1125 + GetDevicePathSize (Private
->ParentDevicePath
)
1126 - END_DEVICE_PATH_LENGTH
1128 CopyMem (Uart
, &Private
->UartDevicePath
, sizeof (UART_DEVICE_PATH
));
1129 Status
= gBS
->ReinstallProtocolInterface (
1131 &gEfiDevicePathProtocolGuid
,
1132 Private
->DevicePath
,
1137 gBS
->RestoreTPL (Tpl
);
1144 WinNtSerialIoSetControl (
1145 IN EFI_SERIAL_IO_PROTOCOL
*This
,
1150 Routine Description:
1152 TODO: Add function description
1156 This - TODO: add argument description
1157 Control - TODO: add argument description
1161 EFI_DEVICE_ERROR - TODO: Add description for return value
1162 EFI_DEVICE_ERROR - TODO: Add description for return value
1163 EFI_SUCCESS - TODO: Add description for return value
1167 WIN_NT_SERIAL_IO_PRIVATE_DATA
*Private
;
1171 UART_FLOW_CONTROL_DEVICE_PATH
*FlowControl
;
1175 // first determine the parameter is invalid
1177 if (Control
& (~(EFI_SERIAL_REQUEST_TO_SEND
| EFI_SERIAL_DATA_TERMINAL_READY
|
1178 EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE
| EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE
|
1179 EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE
))) {
1180 return EFI_UNSUPPORTED
;
1183 Tpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1185 Private
= WIN_NT_SERIAL_IO_PRIVATE_DATA_FROM_THIS (This
);
1187 Result
= Private
->WinNtThunk
->GetCommState (Private
->NtHandle
, &Dcb
);
1190 Private
->NtError
= Private
->WinNtThunk
->GetLastError ();
1191 DEBUG ((EFI_D_ERROR
, "SerialSetControl: GetCommState %d\n", Private
->NtError
));
1192 gBS
->RestoreTPL (Tpl
);
1193 return EFI_DEVICE_ERROR
;
1196 Dcb
.fRtsControl
= RTS_CONTROL_DISABLE
;
1197 Dcb
.fDtrControl
= DTR_CONTROL_DISABLE
;
1198 Private
->HardwareFlowControl
= FALSE
;
1199 Private
->SoftwareLoopbackEnable
= FALSE
;
1200 Private
->HardwareLoopbackEnable
= FALSE
;
1202 if (Control
& EFI_SERIAL_REQUEST_TO_SEND
) {
1203 Dcb
.fRtsControl
= RTS_CONTROL_ENABLE
;
1206 if (Control
& EFI_SERIAL_DATA_TERMINAL_READY
) {
1207 Dcb
.fDtrControl
= DTR_CONTROL_ENABLE
;
1210 if (Control
& EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE
) {
1211 Private
->HardwareFlowControl
= TRUE
;
1214 if (Control
& EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE
) {
1215 Private
->SoftwareLoopbackEnable
= TRUE
;
1218 if (Control
& EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE
) {
1219 Private
->HardwareLoopbackEnable
= TRUE
;
1222 Result
= Private
->WinNtThunk
->SetCommState (
1228 Private
->NtError
= Private
->WinNtThunk
->GetLastError ();
1229 DEBUG ((EFI_D_ERROR
, "SerialSetControl: SetCommState %d\n", Private
->NtError
));
1230 gBS
->RestoreTPL (Tpl
);
1231 return EFI_DEVICE_ERROR
;
1234 Status
= EFI_SUCCESS
;
1235 if (Private
->Handle
!= NULL
) {
1236 FlowControl
= (UART_FLOW_CONTROL_DEVICE_PATH
*) (
1237 (UINTN
) Private
->DevicePath
1238 + GetDevicePathSize (Private
->ParentDevicePath
)
1239 - END_DEVICE_PATH_LENGTH
1240 + sizeof (UART_DEVICE_PATH
)
1242 if (IsUartFlowControlNode (FlowControl
) &&
1243 ((FlowControl
->FlowControlMap
== UART_FLOW_CONTROL_HARDWARE
) ^ Private
->HardwareFlowControl
)) {
1245 // Flow Control setting is changed, need to reinstall device path protocol
1247 FlowControl
->FlowControlMap
= Private
->HardwareFlowControl
? UART_FLOW_CONTROL_HARDWARE
: 0;
1248 Status
= gBS
->ReinstallProtocolInterface (
1250 &gEfiDevicePathProtocolGuid
,
1251 Private
->DevicePath
,
1257 gBS
->RestoreTPL (Tpl
);
1264 WinNtSerialIoGetControl (
1265 IN EFI_SERIAL_IO_PROTOCOL
*This
,
1270 Routine Description:
1272 TODO: Add function description
1276 This - TODO: add argument description
1277 Control - TODO: add argument description
1281 EFI_DEVICE_ERROR - TODO: Add description for return value
1282 EFI_DEVICE_ERROR - TODO: Add description for return value
1283 EFI_DEVICE_ERROR - TODO: Add description for return value
1284 EFI_SUCCESS - TODO: Add description for return value
1288 WIN_NT_SERIAL_IO_PRIVATE_DATA
*Private
;
1295 Tpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1297 Private
= WIN_NT_SERIAL_IO_PRIVATE_DATA_FROM_THIS (This
);
1302 if (!Private
->WinNtThunk
->GetCommModemStatus (Private
->NtHandle
, &ModemStatus
)) {
1303 Private
->NtError
= Private
->WinNtThunk
->GetLastError ();
1304 gBS
->RestoreTPL (Tpl
);
1305 return EFI_DEVICE_ERROR
;
1309 if (ModemStatus
& MS_CTS_ON
) {
1310 Bits
|= EFI_SERIAL_CLEAR_TO_SEND
;
1313 if (ModemStatus
& MS_DSR_ON
) {
1314 Bits
|= EFI_SERIAL_DATA_SET_READY
;
1317 if (ModemStatus
& MS_RING_ON
) {
1318 Bits
|= EFI_SERIAL_RING_INDICATE
;
1321 if (ModemStatus
& MS_RLSD_ON
) {
1322 Bits
|= EFI_SERIAL_CARRIER_DETECT
;
1328 if (!Private
->WinNtThunk
->GetCommState (Private
->NtHandle
, &Dcb
)) {
1329 Private
->NtError
= Private
->WinNtThunk
->GetLastError ();
1330 DEBUG ((EFI_D_ERROR
, "SerialGetControl: GetCommState %d\n", Private
->NtError
));
1331 gBS
->RestoreTPL (Tpl
);
1332 return EFI_DEVICE_ERROR
;
1335 if (Dcb
.fDtrControl
== DTR_CONTROL_ENABLE
) {
1336 Bits
|= EFI_SERIAL_DATA_TERMINAL_READY
;
1339 if (Dcb
.fRtsControl
== RTS_CONTROL_ENABLE
) {
1340 Bits
|= EFI_SERIAL_REQUEST_TO_SEND
;
1343 if (Private
->HardwareFlowControl
) {
1344 Bits
|= EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE
;
1347 if (Private
->SoftwareLoopbackEnable
) {
1348 Bits
|= EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE
;
1351 if (Private
->HardwareLoopbackEnable
) {
1352 Bits
|= EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE
;
1356 // Get input buffer status
1358 if (!Private
->WinNtThunk
->ClearCommError (Private
->NtHandle
, &Errors
, &Private
->NtComStatus
)) {
1359 Private
->NtError
= Private
->WinNtThunk
->GetLastError ();
1360 DEBUG ((EFI_D_ERROR
, "SerialGetControl: ClearCommError %d\n", Private
->NtError
));
1361 gBS
->RestoreTPL (Tpl
);
1362 return EFI_DEVICE_ERROR
;
1365 if (Private
->NtComStatus
.cbInQue
== 0) {
1366 Bits
|= EFI_SERIAL_INPUT_BUFFER_EMPTY
;
1371 gBS
->RestoreTPL (Tpl
);
1378 WinNtSerialIoWrite (
1379 IN EFI_SERIAL_IO_PROTOCOL
*This
,
1380 IN OUT UINTN
*BufferSize
,
1385 Routine Description:
1387 TODO: Add function description
1391 This - TODO: add argument description
1392 BufferSize - TODO: add argument description
1393 Buffer - TODO: add argument description
1397 EFI_DEVICE_ERROR - TODO: Add description for return value
1398 EFI_SUCCESS - TODO: Add description for return value
1402 WIN_NT_SERIAL_IO_PRIVATE_DATA
*Private
;
1404 UINTN TotalBytesWritten
;
1412 Tpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1414 Private
= WIN_NT_SERIAL_IO_PRIVATE_DATA_FROM_THIS (This
);
1416 ByteBuffer
= (UINT8
*) Buffer
;
1417 TotalBytesWritten
= 0;
1419 if (Private
->SoftwareLoopbackEnable
|| Private
->HardwareLoopbackEnable
) {
1420 for (Index
= 0; Index
< *BufferSize
; Index
++) {
1421 if (IsaSerialFifoAdd (&Private
->Fifo
, ByteBuffer
[Index
]) == EFI_SUCCESS
) {
1422 TotalBytesWritten
++;
1428 BytesToGo
= (DWORD
) (*BufferSize
);
1431 if (Private
->HardwareFlowControl
) {
1435 WinNtSerialIoGetControl (&Private
->SerialIo
, &Control
);
1436 Control
|= EFI_SERIAL_REQUEST_TO_SEND
;
1437 WinNtSerialIoSetControl (&Private
->SerialIo
, Control
);
1443 Result
= Private
->WinNtThunk
->WriteFile (
1445 &ByteBuffer
[TotalBytesWritten
],
1451 if (Private
->HardwareFlowControl
) {
1455 WinNtSerialIoGetControl (&Private
->SerialIo
, &Control
);
1456 Control
&= ~ (UINT32
) EFI_SERIAL_REQUEST_TO_SEND
;
1457 WinNtSerialIoSetControl (&Private
->SerialIo
, Control
);
1460 TotalBytesWritten
+= BytesWritten
;
1461 BytesToGo
-= BytesWritten
;
1463 Private
->NtError
= Private
->WinNtThunk
->GetLastError ();
1464 DEBUG ((EFI_D_ERROR
, "SerialWrite: FileWrite %d\n", Private
->NtError
));
1465 *BufferSize
= TotalBytesWritten
;
1466 gBS
->RestoreTPL (Tpl
);
1467 return EFI_DEVICE_ERROR
;
1469 } while (BytesToGo
> 0);
1472 *BufferSize
= TotalBytesWritten
;
1474 gBS
->RestoreTPL (Tpl
);
1482 IN EFI_SERIAL_IO_PROTOCOL
*This
,
1483 IN OUT UINTN
*BufferSize
,
1488 Routine Description:
1490 TODO: Add function description
1494 This - TODO: add argument description
1495 BufferSize - TODO: add argument description
1496 Buffer - TODO: add argument description
1500 EFI_DEVICE_ERROR - TODO: Add description for return value
1504 WIN_NT_SERIAL_IO_PRIVATE_DATA
*Private
;
1513 Tpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1515 Private
= WIN_NT_SERIAL_IO_PRIVATE_DATA_FROM_THIS (This
);
1520 if (Private
->SoftwareLoopbackEnable
|| Private
->HardwareLoopbackEnable
) {
1521 for (Index
= 0, BytesRead
= 0; Index
< *BufferSize
; Index
++) {
1522 if (IsaSerialFifoRemove (&Private
->Fifo
, &Data
) == EFI_SUCCESS
) {
1523 ((UINT8
*) Buffer
)[Index
] = Data
;
1530 if (Private
->HardwareFlowControl
) {
1531 WinNtSerialIoGetControl (&Private
->SerialIo
, &Control
);
1532 Control
|= EFI_SERIAL_DATA_TERMINAL_READY
;
1533 WinNtSerialIoSetControl (&Private
->SerialIo
, Control
);
1536 Result
= Private
->WinNtThunk
->ReadFile (
1539 (DWORD
) *BufferSize
,
1544 if (Private
->HardwareFlowControl
) {
1545 WinNtSerialIoGetControl (&Private
->SerialIo
, &Control
);
1546 Control
&= ~ (UINT32
) EFI_SERIAL_DATA_TERMINAL_READY
;
1547 WinNtSerialIoSetControl (&Private
->SerialIo
, Control
);
1551 Private
->NtError
= Private
->WinNtThunk
->GetLastError ();
1552 gBS
->RestoreTPL (Tpl
);
1553 return EFI_DEVICE_ERROR
;
1557 if (BytesRead
!= *BufferSize
) {
1558 Status
= EFI_TIMEOUT
;
1560 Status
= EFI_SUCCESS
;
1563 *BufferSize
= (UINTN
) BytesRead
;
1565 gBS
->RestoreTPL (Tpl
);
1572 IN SERIAL_DEV_FIFO
*Fifo
1576 Routine Description:
1577 Detect whether specific FIFO is full or not
1580 Fifo SERIAL_DEV_FIFO *: A pointer to the Data Structure SERIAL_DEV_FIFO
1583 TRUE: the FIFO is full
1584 FALSE: the FIFO is not full
1588 if (Fifo
->Surplus
== 0) {
1596 IsaSerialFifoEmpty (
1597 IN SERIAL_DEV_FIFO
*Fifo
1601 Routine Description:
1602 Detect whether specific FIFO is empty or not
1605 Fifo SERIAL_DEV_FIFO *: A pointer to the Data Structure SERIAL_DEV_FIFO
1608 TRUE: the FIFO is empty
1609 FALSE: the FIFO is not empty
1613 if (Fifo
->Surplus
== SERIAL_MAX_BUFFER_SIZE
) {
1622 IN SERIAL_DEV_FIFO
*Fifo
,
1627 Routine Description:
1628 Add data to specific FIFO
1631 Fifo SERIAL_DEV_FIFO *: A pointer to the Data Structure SERIAL_DEV_FIFO
1632 Data UINT8: the data added to FIFO
1635 EFI_SUCCESS: Add data to specific FIFO successfully
1636 EFI_OUT_RESOURCE: Failed to add data because FIFO is already full
1639 // TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
1642 // if FIFO full can not add data
1644 if (IsaSerialFifoFull (Fifo
)) {
1645 return EFI_OUT_OF_RESOURCES
;
1649 // FIFO is not full can add data
1651 Fifo
->Data
[Fifo
->Last
] = Data
;
1654 if (Fifo
->Last
>= SERIAL_MAX_BUFFER_SIZE
) {
1662 IsaSerialFifoRemove (
1663 IN SERIAL_DEV_FIFO
*Fifo
,
1668 Routine Description:
1669 Remove data from specific FIFO
1672 Fifo SERIAL_DEV_FIFO *: A pointer to the Data Structure SERIAL_DEV_FIFO
1673 Data UINT8*: the data removed from FIFO
1676 EFI_SUCCESS: Remove data from specific FIFO successfully
1677 EFI_OUT_RESOURCE: Failed to remove data because FIFO is empty
1680 // TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
1683 // if FIFO is empty, no data can remove
1685 if (IsaSerialFifoEmpty (Fifo
)) {
1686 return EFI_OUT_OF_RESOURCES
;
1690 // FIFO is not empty, can remove data
1692 *Data
= Fifo
->Data
[Fifo
->First
];
1695 if (Fifo
->First
>= SERIAL_MAX_BUFFER_SIZE
) {