3 Copyright (c) 2006, 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
,
62 WinNtSerialIoDriverBindingSupported (
63 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
65 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
78 // TODO: This - add argument and description to function comment
79 // TODO: Handle - add argument and description to function comment
80 // TODO: RemainingDevicePath - add argument and description to function comment
81 // TODO: EFI_SUCCESS - add return value to function comment
82 // TODO: EFI_SUCCESS - add return value to function comment
85 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
86 EFI_WIN_NT_IO_PROTOCOL
*WinNtIo
;
87 UART_DEVICE_PATH
*UartNode
;
90 // Open the IO Abstraction(s) needed to perform the supported test
92 Status
= gBS
->OpenProtocol (
94 &gEfiDevicePathProtocolGuid
,
96 This
->DriverBindingHandle
,
98 EFI_OPEN_PROTOCOL_BY_DRIVER
100 if (Status
== EFI_ALREADY_STARTED
) {
104 if (EFI_ERROR (Status
)) {
110 &gEfiDevicePathProtocolGuid
,
111 This
->DriverBindingHandle
,
115 Status
= gBS
->OpenProtocol (
117 &gEfiWinNtIoProtocolGuid
,
119 This
->DriverBindingHandle
,
121 EFI_OPEN_PROTOCOL_BY_DRIVER
123 if (Status
== EFI_ALREADY_STARTED
) {
127 if (EFI_ERROR (Status
)) {
132 // Make sure that the WinNt Thunk Protocol is valid
134 if (WinNtIo
->WinNtThunk
->Signature
!= EFI_WIN_NT_THUNK_PROTOCOL_SIGNATURE
) {
135 Status
= EFI_UNSUPPORTED
;
140 // Check the GUID to see if this is a handle type the driver supports
142 if (!CompareGuid (WinNtIo
->TypeGuid
, &gEfiWinNtSerialPortGuid
)) {
143 Status
= EFI_UNSUPPORTED
;
147 if (RemainingDevicePath
!= NULL
) {
148 Status
= EFI_UNSUPPORTED
;
149 UartNode
= (UART_DEVICE_PATH
*) RemainingDevicePath
;
150 if (UartNode
->Header
.Type
!= MESSAGING_DEVICE_PATH
||
151 UartNode
->Header
.SubType
!= MSG_UART_DP
||
152 DevicePathNodeLength((EFI_DEVICE_PATH_PROTOCOL
*)UartNode
) != sizeof(UART_DEVICE_PATH
)) {
155 if (UartNode
->BaudRate
< 0 || UartNode
->BaudRate
> SERIAL_PORT_MAX_BAUD_RATE
) {
158 if (UartNode
->Parity
< NoParity
|| UartNode
->Parity
> SpaceParity
) {
161 if (UartNode
->DataBits
< 5 || UartNode
->DataBits
> 8) {
164 if (UartNode
->StopBits
< OneStopBit
|| UartNode
->StopBits
> TwoStopBits
) {
167 if ((UartNode
->DataBits
== 5) && (UartNode
->StopBits
== TwoStopBits
)) {
170 if ((UartNode
->DataBits
>= 6) && (UartNode
->DataBits
<= 8) && (UartNode
->StopBits
== OneFiveStopBits
)) {
173 Status
= EFI_SUCCESS
;
178 // Close the I/O Abstraction(s) used to perform the supported test
182 &gEfiWinNtIoProtocolGuid
,
183 This
->DriverBindingHandle
,
193 WinNtSerialIoDriverBindingStart (
194 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
195 IN EFI_HANDLE Handle
,
196 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
209 // TODO: This - add argument and description to function comment
210 // TODO: Handle - add argument and description to function comment
211 // TODO: RemainingDevicePath - add argument and description to function comment
212 // TODO: EFI_SUCCESS - add return value to function comment
213 // TODO: EFI_SUCCESS - add return value to function comment
216 EFI_WIN_NT_IO_PROTOCOL
*WinNtIo
;
217 WIN_NT_SERIAL_IO_PRIVATE_DATA
*Private
;
219 UART_DEVICE_PATH Node
;
220 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
221 EFI_OPEN_PROTOCOL_INFORMATION_ENTRY
*OpenInfoBuffer
;
224 EFI_SERIAL_IO_PROTOCOL
*SerialIo
;
227 NtHandle
= INVALID_HANDLE_VALUE
;
230 // Grab the protocols we need
232 Status
= gBS
->OpenProtocol (
234 &gEfiDevicePathProtocolGuid
,
236 This
->DriverBindingHandle
,
238 EFI_OPEN_PROTOCOL_BY_DRIVER
240 if (EFI_ERROR (Status
) && Status
!= EFI_ALREADY_STARTED
) {
245 // Grab the IO abstraction we need to get any work done
247 Status
= gBS
->OpenProtocol (
249 &gEfiWinNtIoProtocolGuid
,
251 This
->DriverBindingHandle
,
253 EFI_OPEN_PROTOCOL_BY_DRIVER
255 if (EFI_ERROR (Status
) && Status
!= EFI_ALREADY_STARTED
) {
258 &gEfiDevicePathProtocolGuid
,
259 This
->DriverBindingHandle
,
265 if (Status
== EFI_ALREADY_STARTED
) {
267 if (RemainingDevicePath
== NULL
) {
272 // Make sure a child handle does not already exist. This driver can only
273 // produce one child per serial port.
275 Status
= gBS
->OpenProtocolInformation (
277 &gEfiWinNtIoProtocolGuid
,
281 if (EFI_ERROR (Status
)) {
285 Status
= EFI_ALREADY_STARTED
;
286 for (Index
= 0; Index
< EntryCount
; Index
++) {
287 if (OpenInfoBuffer
[Index
].Attributes
& EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
) {
288 Status
= gBS
->OpenProtocol (
289 OpenInfoBuffer
[Index
].ControllerHandle
,
290 &gEfiSerialIoProtocolGuid
,
292 This
->DriverBindingHandle
,
294 EFI_OPEN_PROTOCOL_GET_PROTOCOL
296 if (!EFI_ERROR (Status
)) {
297 CopyMem (&Node
, RemainingDevicePath
, sizeof (UART_DEVICE_PATH
));
298 Status
= SerialIo
->SetAttributes (
301 SerialIo
->Mode
->ReceiveFifoDepth
,
302 SerialIo
->Mode
->Timeout
,
312 gBS
->FreePool (OpenInfoBuffer
);
317 // Check to see if we can access the hardware device. If it's Open in NT we
318 // will not get access.
320 NtHandle
= WinNtIo
->WinNtThunk
->CreateFile (
322 GENERIC_READ
| GENERIC_WRITE
,
329 if (NtHandle
== INVALID_HANDLE_VALUE
) {
330 Status
= EFI_DEVICE_ERROR
;
335 // Construct Private data
337 Status
= gBS
->AllocatePool (
339 sizeof (WIN_NT_SERIAL_IO_PRIVATE_DATA
),
342 if (EFI_ERROR (Status
)) {
347 // This signature must be valid before any member function is called
349 Private
->Signature
= WIN_NT_SERIAL_IO_PRIVATE_DATA_SIGNATURE
;
350 Private
->NtHandle
= NtHandle
;
351 Private
->ControllerHandle
= Handle
;
352 Private
->Handle
= NULL
;
353 Private
->WinNtThunk
= WinNtIo
->WinNtThunk
;
354 Private
->ParentDevicePath
= ParentDevicePath
;
355 Private
->ControllerNameTable
= NULL
;
357 Private
->SoftwareLoopbackEnable
= FALSE
;
358 Private
->HardwareLoopbackEnable
= FALSE
;
359 Private
->HardwareFlowControl
= FALSE
;
360 Private
->Fifo
.First
= 0;
361 Private
->Fifo
.Last
= 0;
362 Private
->Fifo
.Surplus
= SERIAL_MAX_BUFFER_SIZE
;
366 gWinNtSerialIoComponentName
.SupportedLanguages
,
367 &Private
->ControllerNameTable
,
371 Private
->SerialIo
.Revision
= SERIAL_IO_INTERFACE_REVISION
;
372 Private
->SerialIo
.Reset
= WinNtSerialIoReset
;
373 Private
->SerialIo
.SetAttributes
= WinNtSerialIoSetAttributes
;
374 Private
->SerialIo
.SetControl
= WinNtSerialIoSetControl
;
375 Private
->SerialIo
.GetControl
= WinNtSerialIoGetControl
;
376 Private
->SerialIo
.Write
= WinNtSerialIoWrite
;
377 Private
->SerialIo
.Read
= WinNtSerialIoRead
;
378 Private
->SerialIo
.Mode
= &Private
->SerialIoMode
;
380 if (RemainingDevicePath
!= NULL
) {
382 // Match the configuration of the RemainingDevicePath. IsHandleSupported()
383 // already checked to make sure the RemainingDevicePath contains settings
384 // that we can support.
386 CopyMem (&Private
->UartDevicePath
, RemainingDevicePath
, sizeof (UART_DEVICE_PATH
));
389 // Build the device path by appending the UART node to the ParentDevicePath
390 // from the WinNtIo handle. The Uart setings are zero here, since
391 // SetAttribute() will update them to match the default setings.
393 ZeroMem (&Private
->UartDevicePath
, sizeof (UART_DEVICE_PATH
));
394 Private
->UartDevicePath
.Header
.Type
= MESSAGING_DEVICE_PATH
;
395 Private
->UartDevicePath
.Header
.SubType
= MSG_UART_DP
;
396 SetDevicePathNodeLength ((EFI_DEVICE_PATH_PROTOCOL
*) &Private
->UartDevicePath
, sizeof (UART_DEVICE_PATH
));
400 // Build the device path by appending the UART node to the ParentDevicePath
401 // from the WinNtIo handle. The Uart setings are zero here, since
402 // SetAttribute() will update them to match the current setings.
404 Private
->DevicePath
= AppendDevicePathNode (
406 (EFI_DEVICE_PATH_PROTOCOL
*) &Private
->UartDevicePath
408 if (Private
->DevicePath
== NULL
) {
409 Status
= EFI_OUT_OF_RESOURCES
;
414 // Fill in Serial I/O Mode structure based on either the RemainingDevicePath or defaults.
416 Private
->SerialIoMode
.ControlMask
= SERIAL_CONTROL_MASK
;
417 Private
->SerialIoMode
.Timeout
= SERIAL_TIMEOUT_DEFAULT
;
418 Private
->SerialIoMode
.BaudRate
= Private
->UartDevicePath
.BaudRate
;
419 Private
->SerialIoMode
.ReceiveFifoDepth
= SERIAL_FIFO_DEFAULT
;
420 Private
->SerialIoMode
.DataBits
= Private
->UartDevicePath
.DataBits
;
421 Private
->SerialIoMode
.Parity
= Private
->UartDevicePath
.Parity
;
422 Private
->SerialIoMode
.StopBits
= Private
->UartDevicePath
.StopBits
;
425 // Issue a reset to initialize the COM port
427 Status
= Private
->SerialIo
.Reset (&Private
->SerialIo
);
428 if (EFI_ERROR (Status
)) {
433 // Create new child handle
435 Status
= gBS
->InstallMultipleProtocolInterfaces (
437 &gEfiSerialIoProtocolGuid
,
439 &gEfiDevicePathProtocolGuid
,
443 if (EFI_ERROR (Status
)) {
448 // Open For Child Device
450 Status
= gBS
->OpenProtocol (
452 &gEfiWinNtIoProtocolGuid
,
454 This
->DriverBindingHandle
,
456 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
458 if (EFI_ERROR (Status
)) {
466 // Use the Stop() function to free all resources allocated in Start()
468 if (Private
!= NULL
) {
469 if (Private
->Handle
!= NULL
) {
470 This
->Stop (This
, Handle
, 1, &Private
->Handle
);
472 if (NtHandle
!= INVALID_HANDLE_VALUE
) {
473 Private
->WinNtThunk
->CloseHandle (NtHandle
);
476 if (Private
->DevicePath
!= NULL
) {
477 gBS
->FreePool (Private
->DevicePath
);
480 FreeUnicodeStringTable (Private
->ControllerNameTable
);
482 gBS
->FreePool (Private
);
486 This
->Stop (This
, Handle
, 0, NULL
);
494 WinNtSerialIoDriverBindingStop (
495 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
496 IN EFI_HANDLE Handle
,
497 IN UINTN NumberOfChildren
,
498 IN EFI_HANDLE
*ChildHandleBuffer
504 TODO: Add function description
508 This - TODO: add argument description
509 Handle - TODO: add argument description
510 NumberOfChildren - TODO: add argument description
511 ChildHandleBuffer - TODO: add argument description
515 EFI_DEVICE_ERROR - TODO: Add description for return value
516 EFI_SUCCESS - TODO: Add description for return value
522 BOOLEAN AllChildrenStopped
;
523 EFI_SERIAL_IO_PROTOCOL
*SerialIo
;
524 WIN_NT_SERIAL_IO_PRIVATE_DATA
*Private
;
525 EFI_WIN_NT_IO_PROTOCOL
*WinNtIo
;
528 // Complete all outstanding transactions to Controller.
529 // Don't allow any new transaction to Controller to be started.
532 if (NumberOfChildren
== 0) {
534 // Close the bus driver
536 Status
= gBS
->CloseProtocol (
538 &gEfiWinNtIoProtocolGuid
,
539 This
->DriverBindingHandle
,
542 Status
= gBS
->CloseProtocol (
544 &gEfiDevicePathProtocolGuid
,
545 This
->DriverBindingHandle
,
551 AllChildrenStopped
= TRUE
;
553 for (Index
= 0; Index
< NumberOfChildren
; Index
++) {
554 Status
= gBS
->OpenProtocol (
555 ChildHandleBuffer
[Index
],
556 &gEfiSerialIoProtocolGuid
,
558 This
->DriverBindingHandle
,
560 EFI_OPEN_PROTOCOL_GET_PROTOCOL
562 if (!EFI_ERROR (Status
)) {
563 Private
= WIN_NT_SERIAL_IO_PRIVATE_DATA_FROM_THIS (SerialIo
);
565 ASSERT (Private
->Handle
== ChildHandleBuffer
[Index
]);
567 Status
= gBS
->CloseProtocol (
569 &gEfiWinNtIoProtocolGuid
,
570 This
->DriverBindingHandle
,
571 ChildHandleBuffer
[Index
]
574 Status
= gBS
->UninstallMultipleProtocolInterfaces (
575 ChildHandleBuffer
[Index
],
576 &gEfiSerialIoProtocolGuid
,
578 &gEfiDevicePathProtocolGuid
,
583 if (EFI_ERROR (Status
)) {
586 &gEfiWinNtIoProtocolGuid
,
588 This
->DriverBindingHandle
,
589 ChildHandleBuffer
[Index
],
590 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
593 Private
->WinNtThunk
->CloseHandle (Private
->NtHandle
);
595 gBS
->FreePool (Private
->DevicePath
);
597 FreeUnicodeStringTable (Private
->ControllerNameTable
);
599 gBS
->FreePool (Private
);
603 if (EFI_ERROR (Status
)) {
604 AllChildrenStopped
= FALSE
;
608 if (!AllChildrenStopped
) {
609 return EFI_DEVICE_ERROR
;
616 // Serial IO Protocol member functions
623 IN EFI_SERIAL_IO_PROTOCOL
*This
629 TODO: Add function description
633 This - TODO: add argument description
637 TODO: add return values
641 WIN_NT_SERIAL_IO_PRIVATE_DATA
*Private
;
644 Tpl
= gBS
->RaiseTPL (EFI_TPL_NOTIFY
);
646 Private
= WIN_NT_SERIAL_IO_PRIVATE_DATA_FROM_THIS (This
);
648 Private
->WinNtThunk
->PurgeComm (
650 PURGE_TXCLEAR
| PURGE_RXCLEAR
653 gBS
->RestoreTPL (Tpl
);
655 return This
->SetAttributes (
657 This
->Mode
->BaudRate
,
658 This
->Mode
->ReceiveFifoDepth
,
661 (UINT8
) This
->Mode
->DataBits
,
669 WinNtSerialIoSetAttributes (
670 IN EFI_SERIAL_IO_PROTOCOL
*This
,
672 IN UINT32 ReceiveFifoDepth
,
674 IN EFI_PARITY_TYPE Parity
,
676 IN EFI_STOP_BITS_TYPE StopBits
682 This function is used to set the attributes.
686 This - A pointer to the EFI_SERIAL_IO_PROTOCOL structrue.
687 BaudRate - The Baud rate of the serial device.
688 ReceiveFifoDepth - The request depth of fifo on receive side.
689 Timeout - the request timeout for a single charact.
690 Parity - The type of parity used in serial device.
691 DataBits - Number of deata bits used in serial device.
692 StopBits - Number of stop bits used in serial device.
700 // TODO: EFI_SUCCESS - add return value to function comment
701 // TODO: EFI_DEVICE_ERROR - add return value to function comment
702 // TODO: EFI_DEVICE_ERROR - add return value to function comment
703 // TODO: EFI_DEVICE_ERROR - add return value to function comment
704 // TODO: EFI_SUCCESS - add return value to function comment
705 // TODO: EFI_DEVICE_ERROR - add return value to function comment
706 // TODO: EFI_SUCCESS - add return value to function comment
709 WIN_NT_SERIAL_IO_PRIVATE_DATA
*Private
;
710 COMMTIMEOUTS PortTimeOuts
;
713 EFI_DEVICE_PATH_PROTOCOL
*NewDevicePath
;
716 Tpl
= gBS
->RaiseTPL (EFI_TPL_NOTIFY
);
718 Private
= WIN_NT_SERIAL_IO_PRIVATE_DATA_FROM_THIS (This
);
721 // Some of our arguments have defaults if a null value is passed in, and
722 // we must set the default values if a null argument is passed in.
725 BaudRate
= SERIAL_BAUD_DEFAULT
;
728 if (ReceiveFifoDepth
== 0) {
729 ReceiveFifoDepth
= SERIAL_FIFO_DEFAULT
;
733 Timeout
= SERIAL_TIMEOUT_DEFAULT
;
736 if (Parity
== DefaultParity
) {
741 DataBits
= SERIAL_DATABITS_DEFAULT
;
744 if (StopBits
== DefaultStopBits
) {
745 StopBits
= OneStopBit
;
748 // See if the new attributes already match the current attributes
750 if (Private
->UartDevicePath
.BaudRate
== BaudRate
&&
751 Private
->UartDevicePath
.DataBits
== DataBits
&&
752 Private
->UartDevicePath
.Parity
== Parity
&&
753 Private
->UartDevicePath
.StopBits
== StopBits
&&
754 Private
->SerialIoMode
.ReceiveFifoDepth
== ReceiveFifoDepth
&&
755 Private
->SerialIoMode
.Timeout
== Timeout
) {
756 gBS
->RestoreTPL(Tpl
);
761 // Get current values from NT
763 ZeroMem (&Private
->NtDCB
, sizeof (DCB
));
764 Private
->NtDCB
.DCBlength
= sizeof (DCB
);
766 if (!Private
->WinNtThunk
->GetCommState (Private
->NtHandle
, &Private
->NtDCB
)) {
767 Private
->NtError
= Private
->WinNtThunk
->GetLastError ();
768 DEBUG ((EFI_D_ERROR
, "SerialSetAttributes: GetCommState %d\n", Private
->NtError
));
769 gBS
->RestoreTPL (Tpl
);
770 return EFI_DEVICE_ERROR
;
774 // Map EFI com setting to NT
776 Private
->NtDCB
.BaudRate
= ConvertBaud2Nt (BaudRate
);
777 Private
->NtDCB
.ByteSize
= ConvertData2Nt (DataBits
);
778 Private
->NtDCB
.Parity
= ConvertParity2Nt (Parity
);
779 Private
->NtDCB
.StopBits
= ConvertStop2Nt (StopBits
);
781 Private
->NtDCB
.fBinary
= TRUE
;
782 Private
->NtDCB
.fParity
= Private
->NtDCB
.Parity
== NOPARITY
? FALSE
: TRUE
;
783 Private
->NtDCB
.fOutxCtsFlow
= FALSE
;
784 Private
->NtDCB
.fOutxDsrFlow
= FALSE
;
785 Private
->NtDCB
.fDtrControl
= DTR_CONTROL_ENABLE
;
786 Private
->NtDCB
.fDsrSensitivity
= FALSE
;
787 Private
->NtDCB
.fOutX
= FALSE
;
788 Private
->NtDCB
.fInX
= FALSE
;
789 Private
->NtDCB
.fRtsControl
= RTS_CONTROL_ENABLE
;
790 Private
->NtDCB
.fNull
= FALSE
;
795 Result
= Private
->WinNtThunk
->SetCommState (Private
->NtHandle
, &Private
->NtDCB
);
797 Private
->NtError
= Private
->WinNtThunk
->GetLastError ();
798 DEBUG ((EFI_D_ERROR
, "SerialSetAttributes: SetCommState %d\n", Private
->NtError
));
799 gBS
->RestoreTPL (Tpl
);
800 return EFI_DEVICE_ERROR
;
804 // Set com port read/write timeout values
806 ConvertedTime
= ConvertTime2Nt (Timeout
);
807 PortTimeOuts
.ReadIntervalTimeout
= MAXDWORD
;
808 PortTimeOuts
.ReadTotalTimeoutMultiplier
= 0;
809 PortTimeOuts
.ReadTotalTimeoutConstant
= ConvertedTime
;
810 PortTimeOuts
.WriteTotalTimeoutMultiplier
= ConvertedTime
== 0 ? 1 : ConvertedTime
;
811 PortTimeOuts
.WriteTotalTimeoutConstant
= 0;
813 if (!Private
->WinNtThunk
->SetCommTimeouts (Private
->NtHandle
, &PortTimeOuts
)) {
814 Private
->NtError
= Private
->WinNtThunk
->GetLastError ();
815 DEBUG ((EFI_D_ERROR
, "SerialSetAttributes: SetCommTimeouts %d\n", Private
->NtError
));
816 gBS
->RestoreTPL (Tpl
);
817 return EFI_DEVICE_ERROR
;
823 Private
->SerialIoMode
.BaudRate
= BaudRate
;
824 Private
->SerialIoMode
.ReceiveFifoDepth
= ReceiveFifoDepth
;
825 Private
->SerialIoMode
.Timeout
= Timeout
;
826 Private
->SerialIoMode
.Parity
= Parity
;
827 Private
->SerialIoMode
.DataBits
= DataBits
;
828 Private
->SerialIoMode
.StopBits
= StopBits
;
831 // See if Device Path Node has actually changed
833 if (Private
->UartDevicePath
.BaudRate
== BaudRate
&&
834 Private
->UartDevicePath
.DataBits
== DataBits
&&
835 Private
->UartDevicePath
.Parity
== Parity
&&
836 Private
->UartDevicePath
.StopBits
== StopBits
) {
837 gBS
->RestoreTPL(Tpl
);
842 // Update the device path
844 Private
->UartDevicePath
.BaudRate
= BaudRate
;
845 Private
->UartDevicePath
.DataBits
= DataBits
;
846 Private
->UartDevicePath
.Parity
= (UINT8
) Parity
;
847 Private
->UartDevicePath
.StopBits
= (UINT8
) StopBits
;
849 NewDevicePath
= AppendDevicePathNode (
850 Private
->ParentDevicePath
,
851 (EFI_DEVICE_PATH_PROTOCOL
*) &Private
->UartDevicePath
853 if (NewDevicePath
== NULL
) {
854 gBS
->RestoreTPL (Tpl
);
855 return EFI_DEVICE_ERROR
;
858 if (Private
->Handle
!= NULL
) {
859 Status
= gBS
->ReinstallProtocolInterface (
861 &gEfiDevicePathProtocolGuid
,
865 if (EFI_ERROR (Status
)) {
866 gBS
->RestoreTPL (Tpl
);
871 if (Private
->DevicePath
!= NULL
) {
872 gBS
->FreePool (Private
->DevicePath
);
875 Private
->DevicePath
= NewDevicePath
;
877 gBS
->RestoreTPL (Tpl
);
885 WinNtSerialIoSetControl (
886 IN EFI_SERIAL_IO_PROTOCOL
*This
,
893 TODO: Add function description
897 This - TODO: add argument description
898 Control - TODO: add argument description
902 EFI_DEVICE_ERROR - TODO: Add description for return value
903 EFI_DEVICE_ERROR - TODO: Add description for return value
904 EFI_SUCCESS - TODO: Add description for return value
908 WIN_NT_SERIAL_IO_PRIVATE_DATA
*Private
;
913 Tpl
= gBS
->RaiseTPL (EFI_TPL_NOTIFY
);
915 Private
= WIN_NT_SERIAL_IO_PRIVATE_DATA_FROM_THIS (This
);
917 Result
= Private
->WinNtThunk
->GetCommState (Private
->NtHandle
, &Dcb
);
920 Private
->NtError
= Private
->WinNtThunk
->GetLastError ();
921 DEBUG ((EFI_D_ERROR
, "SerialSetControl: GetCommState %d\n", Private
->NtError
));
922 gBS
->RestoreTPL (Tpl
);
923 return EFI_DEVICE_ERROR
;
926 Dcb
.fRtsControl
= RTS_CONTROL_DISABLE
;
927 Dcb
.fDtrControl
= DTR_CONTROL_DISABLE
;
928 Private
->HardwareFlowControl
= FALSE
;
929 Private
->SoftwareLoopbackEnable
= FALSE
;
930 Private
->HardwareLoopbackEnable
= FALSE
;
932 if (Control
& EFI_SERIAL_REQUEST_TO_SEND
) {
933 Dcb
.fRtsControl
= RTS_CONTROL_ENABLE
;
936 if (Control
& EFI_SERIAL_DATA_TERMINAL_READY
) {
937 Dcb
.fDtrControl
= DTR_CONTROL_ENABLE
;
940 if (Control
& EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE
) {
941 Private
->HardwareFlowControl
= TRUE
;
944 if (Control
& EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE
) {
945 Private
->SoftwareLoopbackEnable
= TRUE
;
948 if (Control
& EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE
) {
949 Private
->HardwareLoopbackEnable
= TRUE
;
952 Result
= Private
->WinNtThunk
->SetCommState (
958 Private
->NtError
= Private
->WinNtThunk
->GetLastError ();
959 DEBUG ((EFI_D_ERROR
, "SerialSetControl: SetCommState %d\n", Private
->NtError
));
960 gBS
->RestoreTPL (Tpl
);
961 return EFI_DEVICE_ERROR
;
964 gBS
->RestoreTPL (Tpl
);
972 WinNtSerialIoGetControl (
973 IN EFI_SERIAL_IO_PROTOCOL
*This
,
980 TODO: Add function description
984 This - TODO: add argument description
985 Control - TODO: add argument description
989 EFI_DEVICE_ERROR - TODO: Add description for return value
990 EFI_DEVICE_ERROR - TODO: Add description for return value
991 EFI_DEVICE_ERROR - TODO: Add description for return value
992 EFI_SUCCESS - TODO: Add description for return value
996 WIN_NT_SERIAL_IO_PRIVATE_DATA
*Private
;
1003 Tpl
= gBS
->RaiseTPL (EFI_TPL_NOTIFY
);
1005 Private
= WIN_NT_SERIAL_IO_PRIVATE_DATA_FROM_THIS (This
);
1010 if (!Private
->WinNtThunk
->GetCommModemStatus (Private
->NtHandle
, &ModemStatus
)) {
1011 Private
->NtError
= Private
->WinNtThunk
->GetLastError ();
1012 gBS
->RestoreTPL (Tpl
);
1013 return EFI_DEVICE_ERROR
;
1017 if (ModemStatus
& MS_CTS_ON
) {
1018 Bits
|= EFI_SERIAL_CLEAR_TO_SEND
;
1021 if (ModemStatus
& MS_DSR_ON
) {
1022 Bits
|= EFI_SERIAL_DATA_SET_READY
;
1025 if (ModemStatus
& MS_RING_ON
) {
1026 Bits
|= EFI_SERIAL_RING_INDICATE
;
1029 if (ModemStatus
& MS_RLSD_ON
) {
1030 Bits
|= EFI_SERIAL_CARRIER_DETECT
;
1036 if (!Private
->WinNtThunk
->GetCommState (Private
->NtHandle
, &Dcb
)) {
1037 Private
->NtError
= Private
->WinNtThunk
->GetLastError ();
1038 DEBUG ((EFI_D_ERROR
, "SerialGetControl: GetCommState %d\n", Private
->NtError
));
1039 gBS
->RestoreTPL (Tpl
);
1040 return EFI_DEVICE_ERROR
;
1043 if (Dcb
.fDtrControl
== DTR_CONTROL_ENABLE
) {
1044 Bits
|= EFI_SERIAL_DATA_TERMINAL_READY
;
1047 if (Dcb
.fRtsControl
== RTS_CONTROL_ENABLE
) {
1048 Bits
|= EFI_SERIAL_REQUEST_TO_SEND
;
1051 if (Private
->HardwareFlowControl
) {
1052 Bits
|= EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE
;
1055 if (Private
->SoftwareLoopbackEnable
) {
1056 Bits
|= EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE
;
1059 if (Private
->HardwareLoopbackEnable
) {
1060 Bits
|= EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE
;
1064 // Get input buffer status
1066 if (!Private
->WinNtThunk
->ClearCommError (Private
->NtHandle
, &Errors
, &Private
->NtComStatus
)) {
1067 Private
->NtError
= Private
->WinNtThunk
->GetLastError ();
1068 DEBUG ((EFI_D_ERROR
, "SerialGetControl: ClearCommError %d\n", Private
->NtError
));
1069 gBS
->RestoreTPL (Tpl
);
1070 return EFI_DEVICE_ERROR
;
1073 if (Private
->NtComStatus
.cbInQue
== 0) {
1074 Bits
|= EFI_SERIAL_INPUT_BUFFER_EMPTY
;
1079 gBS
->RestoreTPL (Tpl
);
1087 WinNtSerialIoWrite (
1088 IN EFI_SERIAL_IO_PROTOCOL
*This
,
1089 IN OUT UINTN
*BufferSize
,
1094 Routine Description:
1096 TODO: Add function description
1100 This - TODO: add argument description
1101 BufferSize - TODO: add argument description
1102 Buffer - TODO: add argument description
1106 EFI_DEVICE_ERROR - TODO: Add description for return value
1107 EFI_SUCCESS - TODO: Add description for return value
1111 WIN_NT_SERIAL_IO_PRIVATE_DATA
*Private
;
1113 UINTN TotalBytesWritten
;
1121 Tpl
= gBS
->RaiseTPL (EFI_TPL_NOTIFY
);
1123 Private
= WIN_NT_SERIAL_IO_PRIVATE_DATA_FROM_THIS (This
);
1125 ByteBuffer
= (UINT8
*) Buffer
;
1126 TotalBytesWritten
= 0;
1128 if (Private
->SoftwareLoopbackEnable
|| Private
->HardwareLoopbackEnable
) {
1129 for (Index
= 0; Index
< *BufferSize
; Index
++) {
1130 if (IsaSerialFifoAdd (&Private
->Fifo
, ByteBuffer
[Index
]) == EFI_SUCCESS
) {
1131 TotalBytesWritten
++;
1137 BytesToGo
= (DWORD
) (*BufferSize
);
1140 if (Private
->HardwareFlowControl
) {
1144 WinNtSerialIoGetControl (&Private
->SerialIo
, &Control
);
1145 Control
|= EFI_SERIAL_REQUEST_TO_SEND
;
1146 WinNtSerialIoSetControl (&Private
->SerialIo
, Control
);
1152 Result
= Private
->WinNtThunk
->WriteFile (
1154 &ByteBuffer
[TotalBytesWritten
],
1160 if (Private
->HardwareFlowControl
) {
1164 WinNtSerialIoGetControl (&Private
->SerialIo
, &Control
);
1165 Control
&= ~ (UINT32
) EFI_SERIAL_REQUEST_TO_SEND
;
1166 WinNtSerialIoSetControl (&Private
->SerialIo
, Control
);
1169 TotalBytesWritten
+= BytesWritten
;
1170 BytesToGo
-= BytesWritten
;
1172 Private
->NtError
= Private
->WinNtThunk
->GetLastError ();
1173 DEBUG ((EFI_D_ERROR
, "SerialWrite: FileWrite %d\n", Private
->NtError
));
1174 *BufferSize
= TotalBytesWritten
;
1175 gBS
->RestoreTPL (Tpl
);
1176 return EFI_DEVICE_ERROR
;
1178 } while (BytesToGo
> 0);
1181 *BufferSize
= TotalBytesWritten
;
1183 gBS
->RestoreTPL (Tpl
);
1192 IN EFI_SERIAL_IO_PROTOCOL
*This
,
1193 IN OUT UINTN
*BufferSize
,
1198 Routine Description:
1200 TODO: Add function description
1204 This - TODO: add argument description
1205 BufferSize - TODO: add argument description
1206 Buffer - TODO: add argument description
1210 EFI_DEVICE_ERROR - TODO: Add description for return value
1214 WIN_NT_SERIAL_IO_PRIVATE_DATA
*Private
;
1223 Tpl
= gBS
->RaiseTPL (EFI_TPL_NOTIFY
);
1225 Private
= WIN_NT_SERIAL_IO_PRIVATE_DATA_FROM_THIS (This
);
1230 if (Private
->SoftwareLoopbackEnable
|| Private
->HardwareLoopbackEnable
) {
1231 for (Index
= 0, BytesRead
= 0; Index
< *BufferSize
; Index
++) {
1232 if (IsaSerialFifoRemove (&Private
->Fifo
, &Data
) == EFI_SUCCESS
) {
1233 ((UINT8
*) Buffer
)[Index
] = Data
;
1240 if (Private
->HardwareFlowControl
) {
1241 WinNtSerialIoGetControl (&Private
->SerialIo
, &Control
);
1242 Control
|= EFI_SERIAL_DATA_TERMINAL_READY
;
1243 WinNtSerialIoSetControl (&Private
->SerialIo
, Control
);
1246 Result
= Private
->WinNtThunk
->ReadFile (
1249 (DWORD
) *BufferSize
,
1254 if (Private
->HardwareFlowControl
) {
1255 WinNtSerialIoGetControl (&Private
->SerialIo
, &Control
);
1256 Control
&= ~ (UINT32
) EFI_SERIAL_DATA_TERMINAL_READY
;
1257 WinNtSerialIoSetControl (&Private
->SerialIo
, Control
);
1261 Private
->NtError
= Private
->WinNtThunk
->GetLastError ();
1262 gBS
->RestoreTPL (Tpl
);
1263 return EFI_DEVICE_ERROR
;
1267 if (BytesRead
!= *BufferSize
) {
1268 Status
= EFI_TIMEOUT
;
1270 Status
= EFI_SUCCESS
;
1273 *BufferSize
= (UINTN
) BytesRead
;
1275 gBS
->RestoreTPL (Tpl
);
1282 IN SERIAL_DEV_FIFO
*Fifo
1286 Routine Description:
1287 Detect whether specific FIFO is full or not
1290 Fifo SERIAL_DEV_FIFO *: A pointer to the Data Structure SERIAL_DEV_FIFO
1293 TRUE: the FIFO is full
1294 FALSE: the FIFO is not full
1298 if (Fifo
->Surplus
== 0) {
1306 IsaSerialFifoEmpty (
1307 IN SERIAL_DEV_FIFO
*Fifo
1311 Routine Description:
1312 Detect whether specific FIFO is empty or not
1315 Fifo SERIAL_DEV_FIFO *: A pointer to the Data Structure SERIAL_DEV_FIFO
1318 TRUE: the FIFO is empty
1319 FALSE: the FIFO is not empty
1323 if (Fifo
->Surplus
== SERIAL_MAX_BUFFER_SIZE
) {
1332 IN SERIAL_DEV_FIFO
*Fifo
,
1337 Routine Description:
1338 Add data to specific FIFO
1341 Fifo SERIAL_DEV_FIFO *: A pointer to the Data Structure SERIAL_DEV_FIFO
1342 Data UINT8: the data added to FIFO
1345 EFI_SUCCESS: Add data to specific FIFO successfully
1346 EFI_OUT_RESOURCE: Failed to add data because FIFO is already full
1349 // TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
1352 // if FIFO full can not add data
1354 if (IsaSerialFifoFull (Fifo
)) {
1355 return EFI_OUT_OF_RESOURCES
;
1359 // FIFO is not full can add data
1361 Fifo
->Data
[Fifo
->Last
] = Data
;
1364 if (Fifo
->Last
>= SERIAL_MAX_BUFFER_SIZE
) {
1372 IsaSerialFifoRemove (
1373 IN SERIAL_DEV_FIFO
*Fifo
,
1378 Routine Description:
1379 Remove data from specific FIFO
1382 Fifo SERIAL_DEV_FIFO *: A pointer to the Data Structure SERIAL_DEV_FIFO
1383 Data UINT8*: the data removed from FIFO
1386 EFI_SUCCESS: Remove data from specific FIFO successfully
1387 EFI_OUT_RESOURCE: Failed to remove data because FIFO is empty
1390 // TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
1393 // if FIFO is empty, no data can remove
1395 if (IsaSerialFifoEmpty (Fifo
)) {
1396 return EFI_OUT_OF_RESOURCES
;
1400 // FIFO is not empty, can remove data
1402 *Data
= Fifo
->Data
[Fifo
->First
];
1405 if (Fifo
->First
>= SERIAL_MAX_BUFFER_SIZE
) {