3 Copyright (c) 2006 - 2007, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 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 The user Entry Point for module WinNtSerialIo. The user code starts with this function.
62 @param[in] ImageHandle The firmware allocated handle for the EFI image.
63 @param[in] SystemTable A pointer to the EFI System Table.
65 @retval EFI_SUCCESS The entry point is executed successfully.
66 @retval other Some error occurs when executing this entry point.
71 InitializeWinNtSerialIo(
72 IN EFI_HANDLE ImageHandle
,
73 IN EFI_SYSTEM_TABLE
*SystemTable
79 // Install driver model protocol(s).
81 Status
= EfiLibInstallAllDriverProtocols (
84 &gWinNtSerialIoDriverBinding
,
86 &gWinNtSerialIoComponentName
,
90 ASSERT_EFI_ERROR (Status
);
99 WinNtSerialIoDriverBindingSupported (
100 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
101 IN EFI_HANDLE Handle
,
102 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
115 // TODO: This - add argument and description to function comment
116 // TODO: Handle - add argument and description to function comment
117 // TODO: RemainingDevicePath - add argument and description to function comment
118 // TODO: EFI_SUCCESS - add return value to function comment
119 // TODO: EFI_SUCCESS - add return value to function comment
122 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
123 EFI_WIN_NT_IO_PROTOCOL
*WinNtIo
;
124 UART_DEVICE_PATH
*UartNode
;
127 // Open the IO Abstraction(s) needed to perform the supported test
129 Status
= gBS
->OpenProtocol (
131 &gEfiDevicePathProtocolGuid
,
133 This
->DriverBindingHandle
,
135 EFI_OPEN_PROTOCOL_BY_DRIVER
137 if (Status
== EFI_ALREADY_STARTED
) {
141 if (EFI_ERROR (Status
)) {
147 &gEfiDevicePathProtocolGuid
,
148 This
->DriverBindingHandle
,
152 Status
= gBS
->OpenProtocol (
154 &gEfiWinNtIoProtocolGuid
,
156 This
->DriverBindingHandle
,
158 EFI_OPEN_PROTOCOL_BY_DRIVER
160 if (Status
== EFI_ALREADY_STARTED
) {
164 if (EFI_ERROR (Status
)) {
169 // Make sure that the WinNt Thunk Protocol is valid
171 if (WinNtIo
->WinNtThunk
->Signature
!= EFI_WIN_NT_THUNK_PROTOCOL_SIGNATURE
) {
172 Status
= EFI_UNSUPPORTED
;
177 // Check the GUID to see if this is a handle type the driver supports
179 if (!CompareGuid (WinNtIo
->TypeGuid
, &gEfiWinNtSerialPortGuid
)) {
180 Status
= EFI_UNSUPPORTED
;
184 if (RemainingDevicePath
!= NULL
) {
185 Status
= EFI_UNSUPPORTED
;
186 UartNode
= (UART_DEVICE_PATH
*) RemainingDevicePath
;
187 if (UartNode
->Header
.Type
!= MESSAGING_DEVICE_PATH
||
188 UartNode
->Header
.SubType
!= MSG_UART_DP
||
189 DevicePathNodeLength((EFI_DEVICE_PATH_PROTOCOL
*)UartNode
) != sizeof(UART_DEVICE_PATH
)) {
192 if (UartNode
->BaudRate
< 0 || UartNode
->BaudRate
> SERIAL_PORT_MAX_BAUD_RATE
) {
195 if (UartNode
->Parity
< NoParity
|| UartNode
->Parity
> SpaceParity
) {
198 if (UartNode
->DataBits
< 5 || UartNode
->DataBits
> 8) {
201 if (UartNode
->StopBits
< OneStopBit
|| UartNode
->StopBits
> TwoStopBits
) {
204 if ((UartNode
->DataBits
== 5) && (UartNode
->StopBits
== TwoStopBits
)) {
207 if ((UartNode
->DataBits
>= 6) && (UartNode
->DataBits
<= 8) && (UartNode
->StopBits
== OneFiveStopBits
)) {
210 Status
= EFI_SUCCESS
;
215 // Close the I/O Abstraction(s) used to perform the supported test
219 &gEfiWinNtIoProtocolGuid
,
220 This
->DriverBindingHandle
,
230 WinNtSerialIoDriverBindingStart (
231 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
232 IN EFI_HANDLE Handle
,
233 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
246 // TODO: This - add argument and description to function comment
247 // TODO: Handle - add argument and description to function comment
248 // TODO: RemainingDevicePath - add argument and description to function comment
249 // TODO: EFI_SUCCESS - add return value to function comment
250 // TODO: EFI_SUCCESS - add return value to function comment
253 EFI_WIN_NT_IO_PROTOCOL
*WinNtIo
;
254 WIN_NT_SERIAL_IO_PRIVATE_DATA
*Private
;
256 UART_DEVICE_PATH Node
;
257 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
258 EFI_OPEN_PROTOCOL_INFORMATION_ENTRY
*OpenInfoBuffer
;
261 EFI_SERIAL_IO_PROTOCOL
*SerialIo
;
264 NtHandle
= INVALID_HANDLE_VALUE
;
267 // Grab the protocols we need
269 Status
= gBS
->OpenProtocol (
271 &gEfiDevicePathProtocolGuid
,
273 This
->DriverBindingHandle
,
275 EFI_OPEN_PROTOCOL_BY_DRIVER
277 if (EFI_ERROR (Status
) && Status
!= EFI_ALREADY_STARTED
) {
282 // Grab the IO abstraction we need to get any work done
284 Status
= gBS
->OpenProtocol (
286 &gEfiWinNtIoProtocolGuid
,
288 This
->DriverBindingHandle
,
290 EFI_OPEN_PROTOCOL_BY_DRIVER
292 if (EFI_ERROR (Status
) && Status
!= EFI_ALREADY_STARTED
) {
295 &gEfiDevicePathProtocolGuid
,
296 This
->DriverBindingHandle
,
302 if (Status
== EFI_ALREADY_STARTED
) {
304 if (RemainingDevicePath
== NULL
) {
309 // Make sure a child handle does not already exist. This driver can only
310 // produce one child per serial port.
312 Status
= gBS
->OpenProtocolInformation (
314 &gEfiWinNtIoProtocolGuid
,
318 if (EFI_ERROR (Status
)) {
322 Status
= EFI_ALREADY_STARTED
;
323 for (Index
= 0; Index
< EntryCount
; Index
++) {
324 if (OpenInfoBuffer
[Index
].Attributes
& EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
) {
325 Status
= gBS
->OpenProtocol (
326 OpenInfoBuffer
[Index
].ControllerHandle
,
327 &gEfiSerialIoProtocolGuid
,
329 This
->DriverBindingHandle
,
331 EFI_OPEN_PROTOCOL_GET_PROTOCOL
333 if (!EFI_ERROR (Status
)) {
334 CopyMem (&Node
, RemainingDevicePath
, sizeof (UART_DEVICE_PATH
));
335 Status
= SerialIo
->SetAttributes (
338 SerialIo
->Mode
->ReceiveFifoDepth
,
339 SerialIo
->Mode
->Timeout
,
349 FreePool (OpenInfoBuffer
);
354 // Check to see if we can access the hardware device. If it's Open in NT we
355 // will not get access.
357 NtHandle
= WinNtIo
->WinNtThunk
->CreateFile (
359 GENERIC_READ
| GENERIC_WRITE
,
366 if (NtHandle
== INVALID_HANDLE_VALUE
) {
367 Status
= EFI_DEVICE_ERROR
;
372 // Construct Private data
374 Private
= AllocatePool (sizeof (WIN_NT_SERIAL_IO_PRIVATE_DATA
));
375 if (Private
== NULL
) {
380 // This signature must be valid before any member function is called
382 Private
->Signature
= WIN_NT_SERIAL_IO_PRIVATE_DATA_SIGNATURE
;
383 Private
->NtHandle
= NtHandle
;
384 Private
->ControllerHandle
= Handle
;
385 Private
->Handle
= NULL
;
386 Private
->WinNtThunk
= WinNtIo
->WinNtThunk
;
387 Private
->ParentDevicePath
= ParentDevicePath
;
388 Private
->ControllerNameTable
= NULL
;
390 Private
->SoftwareLoopbackEnable
= FALSE
;
391 Private
->HardwareLoopbackEnable
= FALSE
;
392 Private
->HardwareFlowControl
= FALSE
;
393 Private
->Fifo
.First
= 0;
394 Private
->Fifo
.Last
= 0;
395 Private
->Fifo
.Surplus
= SERIAL_MAX_BUFFER_SIZE
;
399 gWinNtSerialIoComponentName
.SupportedLanguages
,
400 &Private
->ControllerNameTable
,
404 Private
->SerialIo
.Revision
= SERIAL_IO_INTERFACE_REVISION
;
405 Private
->SerialIo
.Reset
= WinNtSerialIoReset
;
406 Private
->SerialIo
.SetAttributes
= WinNtSerialIoSetAttributes
;
407 Private
->SerialIo
.SetControl
= WinNtSerialIoSetControl
;
408 Private
->SerialIo
.GetControl
= WinNtSerialIoGetControl
;
409 Private
->SerialIo
.Write
= WinNtSerialIoWrite
;
410 Private
->SerialIo
.Read
= WinNtSerialIoRead
;
411 Private
->SerialIo
.Mode
= &Private
->SerialIoMode
;
413 if (RemainingDevicePath
!= NULL
) {
415 // Match the configuration of the RemainingDevicePath. IsHandleSupported()
416 // already checked to make sure the RemainingDevicePath contains settings
417 // that we can support.
419 CopyMem (&Private
->UartDevicePath
, RemainingDevicePath
, sizeof (UART_DEVICE_PATH
));
422 // Build the device path by appending the UART node to the ParentDevicePath
423 // from the WinNtIo handle. The Uart setings are zero here, since
424 // SetAttribute() will update them to match the default setings.
426 ZeroMem (&Private
->UartDevicePath
, sizeof (UART_DEVICE_PATH
));
427 Private
->UartDevicePath
.Header
.Type
= MESSAGING_DEVICE_PATH
;
428 Private
->UartDevicePath
.Header
.SubType
= MSG_UART_DP
;
429 SetDevicePathNodeLength ((EFI_DEVICE_PATH_PROTOCOL
*) &Private
->UartDevicePath
, sizeof (UART_DEVICE_PATH
));
433 // Build the device path by appending the UART node to the ParentDevicePath
434 // from the WinNtIo handle. The Uart setings are zero here, since
435 // SetAttribute() will update them to match the current setings.
437 Private
->DevicePath
= AppendDevicePathNode (
439 (EFI_DEVICE_PATH_PROTOCOL
*) &Private
->UartDevicePath
441 if (Private
->DevicePath
== NULL
) {
442 Status
= EFI_OUT_OF_RESOURCES
;
447 // Fill in Serial I/O Mode structure based on either the RemainingDevicePath or defaults.
449 Private
->SerialIoMode
.ControlMask
= SERIAL_CONTROL_MASK
;
450 Private
->SerialIoMode
.Timeout
= SERIAL_TIMEOUT_DEFAULT
;
451 Private
->SerialIoMode
.BaudRate
= Private
->UartDevicePath
.BaudRate
;
452 Private
->SerialIoMode
.ReceiveFifoDepth
= SERIAL_FIFO_DEFAULT
;
453 Private
->SerialIoMode
.DataBits
= Private
->UartDevicePath
.DataBits
;
454 Private
->SerialIoMode
.Parity
= Private
->UartDevicePath
.Parity
;
455 Private
->SerialIoMode
.StopBits
= Private
->UartDevicePath
.StopBits
;
458 // Issue a reset to initialize the COM port
460 Status
= Private
->SerialIo
.Reset (&Private
->SerialIo
);
461 if (EFI_ERROR (Status
)) {
466 // Create new child handle
468 Status
= gBS
->InstallMultipleProtocolInterfaces (
470 &gEfiSerialIoProtocolGuid
,
472 &gEfiDevicePathProtocolGuid
,
476 if (EFI_ERROR (Status
)) {
481 // Open For Child Device
483 Status
= gBS
->OpenProtocol (
485 &gEfiWinNtIoProtocolGuid
,
487 This
->DriverBindingHandle
,
489 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
491 if (EFI_ERROR (Status
)) {
499 // Use the Stop() function to free all resources allocated in Start()
501 if (Private
!= NULL
) {
502 if (Private
->Handle
!= NULL
) {
503 This
->Stop (This
, Handle
, 1, &Private
->Handle
);
505 if (NtHandle
!= INVALID_HANDLE_VALUE
) {
506 Private
->WinNtThunk
->CloseHandle (NtHandle
);
509 if (Private
->DevicePath
!= NULL
) {
510 FreePool (Private
->DevicePath
);
513 FreeUnicodeStringTable (Private
->ControllerNameTable
);
519 This
->Stop (This
, Handle
, 0, NULL
);
527 WinNtSerialIoDriverBindingStop (
528 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
529 IN EFI_HANDLE Handle
,
530 IN UINTN NumberOfChildren
,
531 IN EFI_HANDLE
*ChildHandleBuffer
537 TODO: Add function description
541 This - TODO: add argument description
542 Handle - TODO: add argument description
543 NumberOfChildren - TODO: add argument description
544 ChildHandleBuffer - TODO: add argument description
548 EFI_DEVICE_ERROR - TODO: Add description for return value
549 EFI_SUCCESS - TODO: Add description for return value
555 BOOLEAN AllChildrenStopped
;
556 EFI_SERIAL_IO_PROTOCOL
*SerialIo
;
557 WIN_NT_SERIAL_IO_PRIVATE_DATA
*Private
;
558 EFI_WIN_NT_IO_PROTOCOL
*WinNtIo
;
561 // Complete all outstanding transactions to Controller.
562 // Don't allow any new transaction to Controller to be started.
565 if (NumberOfChildren
== 0) {
567 // Close the bus driver
569 Status
= gBS
->CloseProtocol (
571 &gEfiWinNtIoProtocolGuid
,
572 This
->DriverBindingHandle
,
575 Status
= gBS
->CloseProtocol (
577 &gEfiDevicePathProtocolGuid
,
578 This
->DriverBindingHandle
,
584 AllChildrenStopped
= TRUE
;
586 for (Index
= 0; Index
< NumberOfChildren
; Index
++) {
587 Status
= gBS
->OpenProtocol (
588 ChildHandleBuffer
[Index
],
589 &gEfiSerialIoProtocolGuid
,
591 This
->DriverBindingHandle
,
593 EFI_OPEN_PROTOCOL_GET_PROTOCOL
595 if (!EFI_ERROR (Status
)) {
596 Private
= WIN_NT_SERIAL_IO_PRIVATE_DATA_FROM_THIS (SerialIo
);
598 ASSERT (Private
->Handle
== ChildHandleBuffer
[Index
]);
600 Status
= gBS
->CloseProtocol (
602 &gEfiWinNtIoProtocolGuid
,
603 This
->DriverBindingHandle
,
604 ChildHandleBuffer
[Index
]
607 Status
= gBS
->UninstallMultipleProtocolInterfaces (
608 ChildHandleBuffer
[Index
],
609 &gEfiSerialIoProtocolGuid
,
611 &gEfiDevicePathProtocolGuid
,
616 if (EFI_ERROR (Status
)) {
619 &gEfiWinNtIoProtocolGuid
,
621 This
->DriverBindingHandle
,
622 ChildHandleBuffer
[Index
],
623 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
626 Private
->WinNtThunk
->CloseHandle (Private
->NtHandle
);
628 FreePool (Private
->DevicePath
);
630 FreeUnicodeStringTable (Private
->ControllerNameTable
);
636 if (EFI_ERROR (Status
)) {
637 AllChildrenStopped
= FALSE
;
641 if (!AllChildrenStopped
) {
642 return EFI_DEVICE_ERROR
;
649 // Serial IO Protocol member functions
656 IN EFI_SERIAL_IO_PROTOCOL
*This
662 TODO: Add function description
666 This - TODO: add argument description
670 TODO: add return values
674 WIN_NT_SERIAL_IO_PRIVATE_DATA
*Private
;
677 Tpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
679 Private
= WIN_NT_SERIAL_IO_PRIVATE_DATA_FROM_THIS (This
);
681 Private
->WinNtThunk
->PurgeComm (
683 PURGE_TXCLEAR
| PURGE_RXCLEAR
686 gBS
->RestoreTPL (Tpl
);
688 return This
->SetAttributes (
690 This
->Mode
->BaudRate
,
691 This
->Mode
->ReceiveFifoDepth
,
694 (UINT8
) This
->Mode
->DataBits
,
702 WinNtSerialIoSetAttributes (
703 IN EFI_SERIAL_IO_PROTOCOL
*This
,
705 IN UINT32 ReceiveFifoDepth
,
707 IN EFI_PARITY_TYPE Parity
,
709 IN EFI_STOP_BITS_TYPE StopBits
715 This function is used to set the attributes.
719 This - A pointer to the EFI_SERIAL_IO_PROTOCOL structrue.
720 BaudRate - The Baud rate of the serial device.
721 ReceiveFifoDepth - The request depth of fifo on receive side.
722 Timeout - the request timeout for a single charact.
723 Parity - The type of parity used in serial device.
724 DataBits - Number of deata bits used in serial device.
725 StopBits - Number of stop bits used in serial device.
733 // TODO: EFI_SUCCESS - add return value to function comment
734 // TODO: EFI_DEVICE_ERROR - add return value to function comment
735 // TODO: EFI_DEVICE_ERROR - add return value to function comment
736 // TODO: EFI_DEVICE_ERROR - add return value to function comment
737 // TODO: EFI_SUCCESS - add return value to function comment
738 // TODO: EFI_DEVICE_ERROR - add return value to function comment
739 // TODO: EFI_SUCCESS - add return value to function comment
742 WIN_NT_SERIAL_IO_PRIVATE_DATA
*Private
;
743 COMMTIMEOUTS PortTimeOuts
;
746 EFI_DEVICE_PATH_PROTOCOL
*NewDevicePath
;
749 Tpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
751 Private
= WIN_NT_SERIAL_IO_PRIVATE_DATA_FROM_THIS (This
);
754 // Some of our arguments have defaults if a null value is passed in, and
755 // we must set the default values if a null argument is passed in.
758 BaudRate
= FixedPcdGet64 (PcdUartDefaultBaudRate
);
761 if (ReceiveFifoDepth
== 0) {
762 ReceiveFifoDepth
= SERIAL_FIFO_DEFAULT
;
766 Timeout
= SERIAL_TIMEOUT_DEFAULT
;
769 if (Parity
== DefaultParity
) {
770 Parity
= FixedPcdGet8 (PcdUartDefaultParity
);
774 DataBits
= FixedPcdGet8 (PcdUartDefaultDataBits
);
777 if (StopBits
== DefaultStopBits
) {
778 StopBits
= (EFI_STOP_BITS_TYPE
) FixedPcdGet8 (PcdUartDefaultStopBits
);
781 // See if the new attributes already match the current attributes
783 if (Private
->UartDevicePath
.BaudRate
== BaudRate
&&
784 Private
->UartDevicePath
.DataBits
== DataBits
&&
785 Private
->UartDevicePath
.Parity
== Parity
&&
786 Private
->UartDevicePath
.StopBits
== StopBits
&&
787 Private
->SerialIoMode
.ReceiveFifoDepth
== ReceiveFifoDepth
&&
788 Private
->SerialIoMode
.Timeout
== Timeout
) {
789 gBS
->RestoreTPL(Tpl
);
794 // Get current values from NT
796 ZeroMem (&Private
->NtDCB
, sizeof (DCB
));
797 Private
->NtDCB
.DCBlength
= sizeof (DCB
);
799 if (!Private
->WinNtThunk
->GetCommState (Private
->NtHandle
, &Private
->NtDCB
)) {
800 Private
->NtError
= Private
->WinNtThunk
->GetLastError ();
801 DEBUG ((EFI_D_ERROR
, "SerialSetAttributes: GetCommState %d\n", Private
->NtError
));
802 gBS
->RestoreTPL (Tpl
);
803 return EFI_DEVICE_ERROR
;
807 // Map EFI com setting to NT
809 Private
->NtDCB
.BaudRate
= ConvertBaud2Nt (BaudRate
);
810 Private
->NtDCB
.ByteSize
= ConvertData2Nt (DataBits
);
811 Private
->NtDCB
.Parity
= ConvertParity2Nt (Parity
);
812 Private
->NtDCB
.StopBits
= ConvertStop2Nt (StopBits
);
814 Private
->NtDCB
.fBinary
= TRUE
;
815 Private
->NtDCB
.fParity
= Private
->NtDCB
.Parity
== NOPARITY
? FALSE
: TRUE
;
816 Private
->NtDCB
.fOutxCtsFlow
= FALSE
;
817 Private
->NtDCB
.fOutxDsrFlow
= FALSE
;
818 Private
->NtDCB
.fDtrControl
= DTR_CONTROL_ENABLE
;
819 Private
->NtDCB
.fDsrSensitivity
= FALSE
;
820 Private
->NtDCB
.fOutX
= FALSE
;
821 Private
->NtDCB
.fInX
= FALSE
;
822 Private
->NtDCB
.fRtsControl
= RTS_CONTROL_ENABLE
;
823 Private
->NtDCB
.fNull
= FALSE
;
828 Result
= Private
->WinNtThunk
->SetCommState (Private
->NtHandle
, &Private
->NtDCB
);
830 Private
->NtError
= Private
->WinNtThunk
->GetLastError ();
831 DEBUG ((EFI_D_ERROR
, "SerialSetAttributes: SetCommState %d\n", Private
->NtError
));
832 gBS
->RestoreTPL (Tpl
);
833 return EFI_DEVICE_ERROR
;
837 // Set com port read/write timeout values
839 ConvertedTime
= ConvertTime2Nt (Timeout
);
840 PortTimeOuts
.ReadIntervalTimeout
= MAXDWORD
;
841 PortTimeOuts
.ReadTotalTimeoutMultiplier
= 0;
842 PortTimeOuts
.ReadTotalTimeoutConstant
= ConvertedTime
;
843 PortTimeOuts
.WriteTotalTimeoutMultiplier
= ConvertedTime
== 0 ? 1 : ConvertedTime
;
844 PortTimeOuts
.WriteTotalTimeoutConstant
= 0;
846 if (!Private
->WinNtThunk
->SetCommTimeouts (Private
->NtHandle
, &PortTimeOuts
)) {
847 Private
->NtError
= Private
->WinNtThunk
->GetLastError ();
848 DEBUG ((EFI_D_ERROR
, "SerialSetAttributes: SetCommTimeouts %d\n", Private
->NtError
));
849 gBS
->RestoreTPL (Tpl
);
850 return EFI_DEVICE_ERROR
;
856 Private
->SerialIoMode
.BaudRate
= BaudRate
;
857 Private
->SerialIoMode
.ReceiveFifoDepth
= ReceiveFifoDepth
;
858 Private
->SerialIoMode
.Timeout
= Timeout
;
859 Private
->SerialIoMode
.Parity
= Parity
;
860 Private
->SerialIoMode
.DataBits
= DataBits
;
861 Private
->SerialIoMode
.StopBits
= StopBits
;
864 // See if Device Path Node has actually changed
866 if (Private
->UartDevicePath
.BaudRate
== BaudRate
&&
867 Private
->UartDevicePath
.DataBits
== DataBits
&&
868 Private
->UartDevicePath
.Parity
== Parity
&&
869 Private
->UartDevicePath
.StopBits
== StopBits
) {
870 gBS
->RestoreTPL(Tpl
);
875 // Update the device path
877 Private
->UartDevicePath
.BaudRate
= BaudRate
;
878 Private
->UartDevicePath
.DataBits
= DataBits
;
879 Private
->UartDevicePath
.Parity
= (UINT8
) Parity
;
880 Private
->UartDevicePath
.StopBits
= (UINT8
) StopBits
;
882 NewDevicePath
= AppendDevicePathNode (
883 Private
->ParentDevicePath
,
884 (EFI_DEVICE_PATH_PROTOCOL
*) &Private
->UartDevicePath
886 if (NewDevicePath
== NULL
) {
887 gBS
->RestoreTPL (Tpl
);
888 return EFI_DEVICE_ERROR
;
891 if (Private
->Handle
!= NULL
) {
892 Status
= gBS
->ReinstallProtocolInterface (
894 &gEfiDevicePathProtocolGuid
,
898 if (EFI_ERROR (Status
)) {
899 gBS
->RestoreTPL (Tpl
);
904 if (Private
->DevicePath
!= NULL
) {
905 FreePool (Private
->DevicePath
);
908 Private
->DevicePath
= NewDevicePath
;
910 gBS
->RestoreTPL (Tpl
);
918 WinNtSerialIoSetControl (
919 IN EFI_SERIAL_IO_PROTOCOL
*This
,
926 TODO: Add function description
930 This - TODO: add argument description
931 Control - TODO: add argument description
935 EFI_DEVICE_ERROR - TODO: Add description for return value
936 EFI_DEVICE_ERROR - TODO: Add description for return value
937 EFI_SUCCESS - TODO: Add description for return value
941 WIN_NT_SERIAL_IO_PRIVATE_DATA
*Private
;
946 Tpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
948 Private
= WIN_NT_SERIAL_IO_PRIVATE_DATA_FROM_THIS (This
);
950 Result
= Private
->WinNtThunk
->GetCommState (Private
->NtHandle
, &Dcb
);
953 Private
->NtError
= Private
->WinNtThunk
->GetLastError ();
954 DEBUG ((EFI_D_ERROR
, "SerialSetControl: GetCommState %d\n", Private
->NtError
));
955 gBS
->RestoreTPL (Tpl
);
956 return EFI_DEVICE_ERROR
;
959 Dcb
.fRtsControl
= RTS_CONTROL_DISABLE
;
960 Dcb
.fDtrControl
= DTR_CONTROL_DISABLE
;
961 Private
->HardwareFlowControl
= FALSE
;
962 Private
->SoftwareLoopbackEnable
= FALSE
;
963 Private
->HardwareLoopbackEnable
= FALSE
;
965 if (Control
& EFI_SERIAL_REQUEST_TO_SEND
) {
966 Dcb
.fRtsControl
= RTS_CONTROL_ENABLE
;
969 if (Control
& EFI_SERIAL_DATA_TERMINAL_READY
) {
970 Dcb
.fDtrControl
= DTR_CONTROL_ENABLE
;
973 if (Control
& EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE
) {
974 Private
->HardwareFlowControl
= TRUE
;
977 if (Control
& EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE
) {
978 Private
->SoftwareLoopbackEnable
= TRUE
;
981 if (Control
& EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE
) {
982 Private
->HardwareLoopbackEnable
= TRUE
;
985 Result
= Private
->WinNtThunk
->SetCommState (
991 Private
->NtError
= Private
->WinNtThunk
->GetLastError ();
992 DEBUG ((EFI_D_ERROR
, "SerialSetControl: SetCommState %d\n", Private
->NtError
));
993 gBS
->RestoreTPL (Tpl
);
994 return EFI_DEVICE_ERROR
;
997 gBS
->RestoreTPL (Tpl
);
1005 WinNtSerialIoGetControl (
1006 IN EFI_SERIAL_IO_PROTOCOL
*This
,
1011 Routine Description:
1013 TODO: Add function description
1017 This - TODO: add argument description
1018 Control - TODO: add argument description
1022 EFI_DEVICE_ERROR - TODO: Add description for return value
1023 EFI_DEVICE_ERROR - TODO: Add description for return value
1024 EFI_DEVICE_ERROR - TODO: Add description for return value
1025 EFI_SUCCESS - TODO: Add description for return value
1029 WIN_NT_SERIAL_IO_PRIVATE_DATA
*Private
;
1036 Tpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1038 Private
= WIN_NT_SERIAL_IO_PRIVATE_DATA_FROM_THIS (This
);
1043 if (!Private
->WinNtThunk
->GetCommModemStatus (Private
->NtHandle
, &ModemStatus
)) {
1044 Private
->NtError
= Private
->WinNtThunk
->GetLastError ();
1045 gBS
->RestoreTPL (Tpl
);
1046 return EFI_DEVICE_ERROR
;
1050 if (ModemStatus
& MS_CTS_ON
) {
1051 Bits
|= EFI_SERIAL_CLEAR_TO_SEND
;
1054 if (ModemStatus
& MS_DSR_ON
) {
1055 Bits
|= EFI_SERIAL_DATA_SET_READY
;
1058 if (ModemStatus
& MS_RING_ON
) {
1059 Bits
|= EFI_SERIAL_RING_INDICATE
;
1062 if (ModemStatus
& MS_RLSD_ON
) {
1063 Bits
|= EFI_SERIAL_CARRIER_DETECT
;
1069 if (!Private
->WinNtThunk
->GetCommState (Private
->NtHandle
, &Dcb
)) {
1070 Private
->NtError
= Private
->WinNtThunk
->GetLastError ();
1071 DEBUG ((EFI_D_ERROR
, "SerialGetControl: GetCommState %d\n", Private
->NtError
));
1072 gBS
->RestoreTPL (Tpl
);
1073 return EFI_DEVICE_ERROR
;
1076 if (Dcb
.fDtrControl
== DTR_CONTROL_ENABLE
) {
1077 Bits
|= EFI_SERIAL_DATA_TERMINAL_READY
;
1080 if (Dcb
.fRtsControl
== RTS_CONTROL_ENABLE
) {
1081 Bits
|= EFI_SERIAL_REQUEST_TO_SEND
;
1084 if (Private
->HardwareFlowControl
) {
1085 Bits
|= EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE
;
1088 if (Private
->SoftwareLoopbackEnable
) {
1089 Bits
|= EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE
;
1092 if (Private
->HardwareLoopbackEnable
) {
1093 Bits
|= EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE
;
1097 // Get input buffer status
1099 if (!Private
->WinNtThunk
->ClearCommError (Private
->NtHandle
, &Errors
, &Private
->NtComStatus
)) {
1100 Private
->NtError
= Private
->WinNtThunk
->GetLastError ();
1101 DEBUG ((EFI_D_ERROR
, "SerialGetControl: ClearCommError %d\n", Private
->NtError
));
1102 gBS
->RestoreTPL (Tpl
);
1103 return EFI_DEVICE_ERROR
;
1106 if (Private
->NtComStatus
.cbInQue
== 0) {
1107 Bits
|= EFI_SERIAL_INPUT_BUFFER_EMPTY
;
1112 gBS
->RestoreTPL (Tpl
);
1120 WinNtSerialIoWrite (
1121 IN EFI_SERIAL_IO_PROTOCOL
*This
,
1122 IN OUT UINTN
*BufferSize
,
1127 Routine Description:
1129 TODO: Add function description
1133 This - TODO: add argument description
1134 BufferSize - TODO: add argument description
1135 Buffer - TODO: add argument description
1139 EFI_DEVICE_ERROR - TODO: Add description for return value
1140 EFI_SUCCESS - TODO: Add description for return value
1144 WIN_NT_SERIAL_IO_PRIVATE_DATA
*Private
;
1146 UINTN TotalBytesWritten
;
1154 Tpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1156 Private
= WIN_NT_SERIAL_IO_PRIVATE_DATA_FROM_THIS (This
);
1158 ByteBuffer
= (UINT8
*) Buffer
;
1159 TotalBytesWritten
= 0;
1161 if (Private
->SoftwareLoopbackEnable
|| Private
->HardwareLoopbackEnable
) {
1162 for (Index
= 0; Index
< *BufferSize
; Index
++) {
1163 if (IsaSerialFifoAdd (&Private
->Fifo
, ByteBuffer
[Index
]) == EFI_SUCCESS
) {
1164 TotalBytesWritten
++;
1170 BytesToGo
= (DWORD
) (*BufferSize
);
1173 if (Private
->HardwareFlowControl
) {
1177 WinNtSerialIoGetControl (&Private
->SerialIo
, &Control
);
1178 Control
|= EFI_SERIAL_REQUEST_TO_SEND
;
1179 WinNtSerialIoSetControl (&Private
->SerialIo
, Control
);
1185 Result
= Private
->WinNtThunk
->WriteFile (
1187 &ByteBuffer
[TotalBytesWritten
],
1193 if (Private
->HardwareFlowControl
) {
1197 WinNtSerialIoGetControl (&Private
->SerialIo
, &Control
);
1198 Control
&= ~ (UINT32
) EFI_SERIAL_REQUEST_TO_SEND
;
1199 WinNtSerialIoSetControl (&Private
->SerialIo
, Control
);
1202 TotalBytesWritten
+= BytesWritten
;
1203 BytesToGo
-= BytesWritten
;
1205 Private
->NtError
= Private
->WinNtThunk
->GetLastError ();
1206 DEBUG ((EFI_D_ERROR
, "SerialWrite: FileWrite %d\n", Private
->NtError
));
1207 *BufferSize
= TotalBytesWritten
;
1208 gBS
->RestoreTPL (Tpl
);
1209 return EFI_DEVICE_ERROR
;
1211 } while (BytesToGo
> 0);
1214 *BufferSize
= TotalBytesWritten
;
1216 gBS
->RestoreTPL (Tpl
);
1225 IN EFI_SERIAL_IO_PROTOCOL
*This
,
1226 IN OUT UINTN
*BufferSize
,
1231 Routine Description:
1233 TODO: Add function description
1237 This - TODO: add argument description
1238 BufferSize - TODO: add argument description
1239 Buffer - TODO: add argument description
1243 EFI_DEVICE_ERROR - TODO: Add description for return value
1247 WIN_NT_SERIAL_IO_PRIVATE_DATA
*Private
;
1256 Tpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
1258 Private
= WIN_NT_SERIAL_IO_PRIVATE_DATA_FROM_THIS (This
);
1263 if (Private
->SoftwareLoopbackEnable
|| Private
->HardwareLoopbackEnable
) {
1264 for (Index
= 0, BytesRead
= 0; Index
< *BufferSize
; Index
++) {
1265 if (IsaSerialFifoRemove (&Private
->Fifo
, &Data
) == EFI_SUCCESS
) {
1266 ((UINT8
*) Buffer
)[Index
] = Data
;
1273 if (Private
->HardwareFlowControl
) {
1274 WinNtSerialIoGetControl (&Private
->SerialIo
, &Control
);
1275 Control
|= EFI_SERIAL_DATA_TERMINAL_READY
;
1276 WinNtSerialIoSetControl (&Private
->SerialIo
, Control
);
1279 Result
= Private
->WinNtThunk
->ReadFile (
1282 (DWORD
) *BufferSize
,
1287 if (Private
->HardwareFlowControl
) {
1288 WinNtSerialIoGetControl (&Private
->SerialIo
, &Control
);
1289 Control
&= ~ (UINT32
) EFI_SERIAL_DATA_TERMINAL_READY
;
1290 WinNtSerialIoSetControl (&Private
->SerialIo
, Control
);
1294 Private
->NtError
= Private
->WinNtThunk
->GetLastError ();
1295 gBS
->RestoreTPL (Tpl
);
1296 return EFI_DEVICE_ERROR
;
1300 if (BytesRead
!= *BufferSize
) {
1301 Status
= EFI_TIMEOUT
;
1303 Status
= EFI_SUCCESS
;
1306 *BufferSize
= (UINTN
) BytesRead
;
1308 gBS
->RestoreTPL (Tpl
);
1315 IN SERIAL_DEV_FIFO
*Fifo
1319 Routine Description:
1320 Detect whether specific FIFO is full or not
1323 Fifo SERIAL_DEV_FIFO *: A pointer to the Data Structure SERIAL_DEV_FIFO
1326 TRUE: the FIFO is full
1327 FALSE: the FIFO is not full
1331 if (Fifo
->Surplus
== 0) {
1339 IsaSerialFifoEmpty (
1340 IN SERIAL_DEV_FIFO
*Fifo
1344 Routine Description:
1345 Detect whether specific FIFO is empty or not
1348 Fifo SERIAL_DEV_FIFO *: A pointer to the Data Structure SERIAL_DEV_FIFO
1351 TRUE: the FIFO is empty
1352 FALSE: the FIFO is not empty
1356 if (Fifo
->Surplus
== SERIAL_MAX_BUFFER_SIZE
) {
1365 IN SERIAL_DEV_FIFO
*Fifo
,
1370 Routine Description:
1371 Add data to specific FIFO
1374 Fifo SERIAL_DEV_FIFO *: A pointer to the Data Structure SERIAL_DEV_FIFO
1375 Data UINT8: the data added to FIFO
1378 EFI_SUCCESS: Add data to specific FIFO successfully
1379 EFI_OUT_RESOURCE: Failed to add data because FIFO is already full
1382 // TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
1385 // if FIFO full can not add data
1387 if (IsaSerialFifoFull (Fifo
)) {
1388 return EFI_OUT_OF_RESOURCES
;
1392 // FIFO is not full can add data
1394 Fifo
->Data
[Fifo
->Last
] = Data
;
1397 if (Fifo
->Last
>= SERIAL_MAX_BUFFER_SIZE
) {
1405 IsaSerialFifoRemove (
1406 IN SERIAL_DEV_FIFO
*Fifo
,
1411 Routine Description:
1412 Remove data from specific FIFO
1415 Fifo SERIAL_DEV_FIFO *: A pointer to the Data Structure SERIAL_DEV_FIFO
1416 Data UINT8*: the data removed from FIFO
1419 EFI_SUCCESS: Remove data from specific FIFO successfully
1420 EFI_OUT_RESOURCE: Failed to remove data because FIFO is empty
1423 // TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
1426 // if FIFO is empty, no data can remove
1428 if (IsaSerialFifoEmpty (Fifo
)) {
1429 return EFI_OUT_OF_RESOURCES
;
1433 // FIFO is not empty, can remove data
1435 *Data
= Fifo
->Data
[Fifo
->First
];
1438 if (Fifo
->First
>= SERIAL_MAX_BUFFER_SIZE
) {