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
,
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 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 Private
= AllocatePool (sizeof (WIN_NT_SERIAL_IO_PRIVATE_DATA
));
338 if (Private
== NULL
) {
343 // This signature must be valid before any member function is called
345 Private
->Signature
= WIN_NT_SERIAL_IO_PRIVATE_DATA_SIGNATURE
;
346 Private
->NtHandle
= NtHandle
;
347 Private
->ControllerHandle
= Handle
;
348 Private
->Handle
= NULL
;
349 Private
->WinNtThunk
= WinNtIo
->WinNtThunk
;
350 Private
->ParentDevicePath
= ParentDevicePath
;
351 Private
->ControllerNameTable
= NULL
;
353 Private
->SoftwareLoopbackEnable
= FALSE
;
354 Private
->HardwareLoopbackEnable
= FALSE
;
355 Private
->HardwareFlowControl
= FALSE
;
356 Private
->Fifo
.First
= 0;
357 Private
->Fifo
.Last
= 0;
358 Private
->Fifo
.Surplus
= SERIAL_MAX_BUFFER_SIZE
;
362 gWinNtSerialIoComponentName
.SupportedLanguages
,
363 &Private
->ControllerNameTable
,
367 Private
->SerialIo
.Revision
= SERIAL_IO_INTERFACE_REVISION
;
368 Private
->SerialIo
.Reset
= WinNtSerialIoReset
;
369 Private
->SerialIo
.SetAttributes
= WinNtSerialIoSetAttributes
;
370 Private
->SerialIo
.SetControl
= WinNtSerialIoSetControl
;
371 Private
->SerialIo
.GetControl
= WinNtSerialIoGetControl
;
372 Private
->SerialIo
.Write
= WinNtSerialIoWrite
;
373 Private
->SerialIo
.Read
= WinNtSerialIoRead
;
374 Private
->SerialIo
.Mode
= &Private
->SerialIoMode
;
376 if (RemainingDevicePath
!= NULL
) {
378 // Match the configuration of the RemainingDevicePath. IsHandleSupported()
379 // already checked to make sure the RemainingDevicePath contains settings
380 // that we can support.
382 CopyMem (&Private
->UartDevicePath
, RemainingDevicePath
, sizeof (UART_DEVICE_PATH
));
385 // Build the device path by appending the UART node to the ParentDevicePath
386 // from the WinNtIo handle. The Uart setings are zero here, since
387 // SetAttribute() will update them to match the default setings.
389 ZeroMem (&Private
->UartDevicePath
, sizeof (UART_DEVICE_PATH
));
390 Private
->UartDevicePath
.Header
.Type
= MESSAGING_DEVICE_PATH
;
391 Private
->UartDevicePath
.Header
.SubType
= MSG_UART_DP
;
392 SetDevicePathNodeLength ((EFI_DEVICE_PATH_PROTOCOL
*) &Private
->UartDevicePath
, sizeof (UART_DEVICE_PATH
));
396 // Build the device path by appending the UART node to the ParentDevicePath
397 // from the WinNtIo handle. The Uart setings are zero here, since
398 // SetAttribute() will update them to match the current setings.
400 Private
->DevicePath
= AppendDevicePathNode (
402 (EFI_DEVICE_PATH_PROTOCOL
*) &Private
->UartDevicePath
404 if (Private
->DevicePath
== NULL
) {
405 Status
= EFI_OUT_OF_RESOURCES
;
410 // Fill in Serial I/O Mode structure based on either the RemainingDevicePath or defaults.
412 Private
->SerialIoMode
.ControlMask
= SERIAL_CONTROL_MASK
;
413 Private
->SerialIoMode
.Timeout
= SERIAL_TIMEOUT_DEFAULT
;
414 Private
->SerialIoMode
.BaudRate
= Private
->UartDevicePath
.BaudRate
;
415 Private
->SerialIoMode
.ReceiveFifoDepth
= SERIAL_FIFO_DEFAULT
;
416 Private
->SerialIoMode
.DataBits
= Private
->UartDevicePath
.DataBits
;
417 Private
->SerialIoMode
.Parity
= Private
->UartDevicePath
.Parity
;
418 Private
->SerialIoMode
.StopBits
= Private
->UartDevicePath
.StopBits
;
421 // Issue a reset to initialize the COM port
423 Status
= Private
->SerialIo
.Reset (&Private
->SerialIo
);
424 if (EFI_ERROR (Status
)) {
429 // Create new child handle
431 Status
= gBS
->InstallMultipleProtocolInterfaces (
433 &gEfiSerialIoProtocolGuid
,
435 &gEfiDevicePathProtocolGuid
,
439 if (EFI_ERROR (Status
)) {
444 // Open For Child Device
446 Status
= gBS
->OpenProtocol (
448 &gEfiWinNtIoProtocolGuid
,
450 This
->DriverBindingHandle
,
452 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
454 if (EFI_ERROR (Status
)) {
462 // Use the Stop() function to free all resources allocated in Start()
464 if (Private
!= NULL
) {
465 if (Private
->Handle
!= NULL
) {
466 This
->Stop (This
, Handle
, 1, &Private
->Handle
);
468 if (NtHandle
!= INVALID_HANDLE_VALUE
) {
469 Private
->WinNtThunk
->CloseHandle (NtHandle
);
472 if (Private
->DevicePath
!= NULL
) {
473 FreePool (Private
->DevicePath
);
476 FreeUnicodeStringTable (Private
->ControllerNameTable
);
482 This
->Stop (This
, Handle
, 0, NULL
);
490 WinNtSerialIoDriverBindingStop (
491 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
492 IN EFI_HANDLE Handle
,
493 IN UINTN NumberOfChildren
,
494 IN EFI_HANDLE
*ChildHandleBuffer
500 TODO: Add function description
504 This - TODO: add argument description
505 Handle - TODO: add argument description
506 NumberOfChildren - TODO: add argument description
507 ChildHandleBuffer - TODO: add argument description
511 EFI_DEVICE_ERROR - TODO: Add description for return value
512 EFI_SUCCESS - TODO: Add description for return value
518 BOOLEAN AllChildrenStopped
;
519 EFI_SERIAL_IO_PROTOCOL
*SerialIo
;
520 WIN_NT_SERIAL_IO_PRIVATE_DATA
*Private
;
521 EFI_WIN_NT_IO_PROTOCOL
*WinNtIo
;
524 // Complete all outstanding transactions to Controller.
525 // Don't allow any new transaction to Controller to be started.
528 if (NumberOfChildren
== 0) {
530 // Close the bus driver
532 Status
= gBS
->CloseProtocol (
534 &gEfiWinNtIoProtocolGuid
,
535 This
->DriverBindingHandle
,
538 Status
= gBS
->CloseProtocol (
540 &gEfiDevicePathProtocolGuid
,
541 This
->DriverBindingHandle
,
547 AllChildrenStopped
= TRUE
;
549 for (Index
= 0; Index
< NumberOfChildren
; Index
++) {
550 Status
= gBS
->OpenProtocol (
551 ChildHandleBuffer
[Index
],
552 &gEfiSerialIoProtocolGuid
,
554 This
->DriverBindingHandle
,
556 EFI_OPEN_PROTOCOL_GET_PROTOCOL
558 if (!EFI_ERROR (Status
)) {
559 Private
= WIN_NT_SERIAL_IO_PRIVATE_DATA_FROM_THIS (SerialIo
);
561 ASSERT (Private
->Handle
== ChildHandleBuffer
[Index
]);
563 Status
= gBS
->CloseProtocol (
565 &gEfiWinNtIoProtocolGuid
,
566 This
->DriverBindingHandle
,
567 ChildHandleBuffer
[Index
]
570 Status
= gBS
->UninstallMultipleProtocolInterfaces (
571 ChildHandleBuffer
[Index
],
572 &gEfiSerialIoProtocolGuid
,
574 &gEfiDevicePathProtocolGuid
,
579 if (EFI_ERROR (Status
)) {
582 &gEfiWinNtIoProtocolGuid
,
584 This
->DriverBindingHandle
,
585 ChildHandleBuffer
[Index
],
586 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
589 Private
->WinNtThunk
->CloseHandle (Private
->NtHandle
);
591 FreePool (Private
->DevicePath
);
593 FreeUnicodeStringTable (Private
->ControllerNameTable
);
599 if (EFI_ERROR (Status
)) {
600 AllChildrenStopped
= FALSE
;
604 if (!AllChildrenStopped
) {
605 return EFI_DEVICE_ERROR
;
612 // Serial IO Protocol member functions
619 IN EFI_SERIAL_IO_PROTOCOL
*This
625 TODO: Add function description
629 This - TODO: add argument description
633 TODO: add return values
637 WIN_NT_SERIAL_IO_PRIVATE_DATA
*Private
;
640 Tpl
= gBS
->RaiseTPL (EFI_TPL_NOTIFY
);
642 Private
= WIN_NT_SERIAL_IO_PRIVATE_DATA_FROM_THIS (This
);
644 Private
->WinNtThunk
->PurgeComm (
646 PURGE_TXCLEAR
| PURGE_RXCLEAR
649 gBS
->RestoreTPL (Tpl
);
651 return This
->SetAttributes (
653 This
->Mode
->BaudRate
,
654 This
->Mode
->ReceiveFifoDepth
,
657 (UINT8
) This
->Mode
->DataBits
,
665 WinNtSerialIoSetAttributes (
666 IN EFI_SERIAL_IO_PROTOCOL
*This
,
668 IN UINT32 ReceiveFifoDepth
,
670 IN EFI_PARITY_TYPE Parity
,
672 IN EFI_STOP_BITS_TYPE StopBits
678 This function is used to set the attributes.
682 This - A pointer to the EFI_SERIAL_IO_PROTOCOL structrue.
683 BaudRate - The Baud rate of the serial device.
684 ReceiveFifoDepth - The request depth of fifo on receive side.
685 Timeout - the request timeout for a single charact.
686 Parity - The type of parity used in serial device.
687 DataBits - Number of deata bits used in serial device.
688 StopBits - Number of stop bits used in serial device.
696 // TODO: EFI_SUCCESS - add return value to function comment
697 // TODO: EFI_DEVICE_ERROR - add return value to function comment
698 // TODO: EFI_DEVICE_ERROR - add return value to function comment
699 // TODO: EFI_DEVICE_ERROR - add return value to function comment
700 // TODO: EFI_SUCCESS - add return value to function comment
701 // TODO: EFI_DEVICE_ERROR - add return value to function comment
702 // TODO: EFI_SUCCESS - add return value to function comment
705 WIN_NT_SERIAL_IO_PRIVATE_DATA
*Private
;
706 COMMTIMEOUTS PortTimeOuts
;
709 EFI_DEVICE_PATH_PROTOCOL
*NewDevicePath
;
712 Tpl
= gBS
->RaiseTPL (EFI_TPL_NOTIFY
);
714 Private
= WIN_NT_SERIAL_IO_PRIVATE_DATA_FROM_THIS (This
);
717 // Some of our arguments have defaults if a null value is passed in, and
718 // we must set the default values if a null argument is passed in.
721 BaudRate
= SERIAL_BAUD_DEFAULT
;
724 if (ReceiveFifoDepth
== 0) {
725 ReceiveFifoDepth
= SERIAL_FIFO_DEFAULT
;
729 Timeout
= SERIAL_TIMEOUT_DEFAULT
;
732 if (Parity
== DefaultParity
) {
737 DataBits
= SERIAL_DATABITS_DEFAULT
;
740 if (StopBits
== DefaultStopBits
) {
741 StopBits
= OneStopBit
;
744 // See if the new attributes already match the current attributes
746 if (Private
->UartDevicePath
.BaudRate
== BaudRate
&&
747 Private
->UartDevicePath
.DataBits
== DataBits
&&
748 Private
->UartDevicePath
.Parity
== Parity
&&
749 Private
->UartDevicePath
.StopBits
== StopBits
&&
750 Private
->SerialIoMode
.ReceiveFifoDepth
== ReceiveFifoDepth
&&
751 Private
->SerialIoMode
.Timeout
== Timeout
) {
752 gBS
->RestoreTPL(Tpl
);
757 // Get current values from NT
759 ZeroMem (&Private
->NtDCB
, sizeof (DCB
));
760 Private
->NtDCB
.DCBlength
= sizeof (DCB
);
762 if (!Private
->WinNtThunk
->GetCommState (Private
->NtHandle
, &Private
->NtDCB
)) {
763 Private
->NtError
= Private
->WinNtThunk
->GetLastError ();
764 DEBUG ((EFI_D_ERROR
, "SerialSetAttributes: GetCommState %d\n", Private
->NtError
));
765 gBS
->RestoreTPL (Tpl
);
766 return EFI_DEVICE_ERROR
;
770 // Map EFI com setting to NT
772 Private
->NtDCB
.BaudRate
= ConvertBaud2Nt (BaudRate
);
773 Private
->NtDCB
.ByteSize
= ConvertData2Nt (DataBits
);
774 Private
->NtDCB
.Parity
= ConvertParity2Nt (Parity
);
775 Private
->NtDCB
.StopBits
= ConvertStop2Nt (StopBits
);
777 Private
->NtDCB
.fBinary
= TRUE
;
778 Private
->NtDCB
.fParity
= Private
->NtDCB
.Parity
== NOPARITY
? FALSE
: TRUE
;
779 Private
->NtDCB
.fOutxCtsFlow
= FALSE
;
780 Private
->NtDCB
.fOutxDsrFlow
= FALSE
;
781 Private
->NtDCB
.fDtrControl
= DTR_CONTROL_ENABLE
;
782 Private
->NtDCB
.fDsrSensitivity
= FALSE
;
783 Private
->NtDCB
.fOutX
= FALSE
;
784 Private
->NtDCB
.fInX
= FALSE
;
785 Private
->NtDCB
.fRtsControl
= RTS_CONTROL_ENABLE
;
786 Private
->NtDCB
.fNull
= FALSE
;
791 Result
= Private
->WinNtThunk
->SetCommState (Private
->NtHandle
, &Private
->NtDCB
);
793 Private
->NtError
= Private
->WinNtThunk
->GetLastError ();
794 DEBUG ((EFI_D_ERROR
, "SerialSetAttributes: SetCommState %d\n", Private
->NtError
));
795 gBS
->RestoreTPL (Tpl
);
796 return EFI_DEVICE_ERROR
;
800 // Set com port read/write timeout values
802 ConvertedTime
= ConvertTime2Nt (Timeout
);
803 PortTimeOuts
.ReadIntervalTimeout
= MAXDWORD
;
804 PortTimeOuts
.ReadTotalTimeoutMultiplier
= 0;
805 PortTimeOuts
.ReadTotalTimeoutConstant
= ConvertedTime
;
806 PortTimeOuts
.WriteTotalTimeoutMultiplier
= ConvertedTime
== 0 ? 1 : ConvertedTime
;
807 PortTimeOuts
.WriteTotalTimeoutConstant
= 0;
809 if (!Private
->WinNtThunk
->SetCommTimeouts (Private
->NtHandle
, &PortTimeOuts
)) {
810 Private
->NtError
= Private
->WinNtThunk
->GetLastError ();
811 DEBUG ((EFI_D_ERROR
, "SerialSetAttributes: SetCommTimeouts %d\n", Private
->NtError
));
812 gBS
->RestoreTPL (Tpl
);
813 return EFI_DEVICE_ERROR
;
819 Private
->SerialIoMode
.BaudRate
= BaudRate
;
820 Private
->SerialIoMode
.ReceiveFifoDepth
= ReceiveFifoDepth
;
821 Private
->SerialIoMode
.Timeout
= Timeout
;
822 Private
->SerialIoMode
.Parity
= Parity
;
823 Private
->SerialIoMode
.DataBits
= DataBits
;
824 Private
->SerialIoMode
.StopBits
= StopBits
;
827 // See if Device Path Node has actually changed
829 if (Private
->UartDevicePath
.BaudRate
== BaudRate
&&
830 Private
->UartDevicePath
.DataBits
== DataBits
&&
831 Private
->UartDevicePath
.Parity
== Parity
&&
832 Private
->UartDevicePath
.StopBits
== StopBits
) {
833 gBS
->RestoreTPL(Tpl
);
838 // Update the device path
840 Private
->UartDevicePath
.BaudRate
= BaudRate
;
841 Private
->UartDevicePath
.DataBits
= DataBits
;
842 Private
->UartDevicePath
.Parity
= (UINT8
) Parity
;
843 Private
->UartDevicePath
.StopBits
= (UINT8
) StopBits
;
845 NewDevicePath
= AppendDevicePathNode (
846 Private
->ParentDevicePath
,
847 (EFI_DEVICE_PATH_PROTOCOL
*) &Private
->UartDevicePath
849 if (NewDevicePath
== NULL
) {
850 gBS
->RestoreTPL (Tpl
);
851 return EFI_DEVICE_ERROR
;
854 if (Private
->Handle
!= NULL
) {
855 Status
= gBS
->ReinstallProtocolInterface (
857 &gEfiDevicePathProtocolGuid
,
861 if (EFI_ERROR (Status
)) {
862 gBS
->RestoreTPL (Tpl
);
867 if (Private
->DevicePath
!= NULL
) {
868 FreePool (Private
->DevicePath
);
871 Private
->DevicePath
= NewDevicePath
;
873 gBS
->RestoreTPL (Tpl
);
881 WinNtSerialIoSetControl (
882 IN EFI_SERIAL_IO_PROTOCOL
*This
,
889 TODO: Add function description
893 This - TODO: add argument description
894 Control - TODO: add argument description
898 EFI_DEVICE_ERROR - TODO: Add description for return value
899 EFI_DEVICE_ERROR - TODO: Add description for return value
900 EFI_SUCCESS - TODO: Add description for return value
904 WIN_NT_SERIAL_IO_PRIVATE_DATA
*Private
;
909 Tpl
= gBS
->RaiseTPL (EFI_TPL_NOTIFY
);
911 Private
= WIN_NT_SERIAL_IO_PRIVATE_DATA_FROM_THIS (This
);
913 Result
= Private
->WinNtThunk
->GetCommState (Private
->NtHandle
, &Dcb
);
916 Private
->NtError
= Private
->WinNtThunk
->GetLastError ();
917 DEBUG ((EFI_D_ERROR
, "SerialSetControl: GetCommState %d\n", Private
->NtError
));
918 gBS
->RestoreTPL (Tpl
);
919 return EFI_DEVICE_ERROR
;
922 Dcb
.fRtsControl
= RTS_CONTROL_DISABLE
;
923 Dcb
.fDtrControl
= DTR_CONTROL_DISABLE
;
924 Private
->HardwareFlowControl
= FALSE
;
925 Private
->SoftwareLoopbackEnable
= FALSE
;
926 Private
->HardwareLoopbackEnable
= FALSE
;
928 if (Control
& EFI_SERIAL_REQUEST_TO_SEND
) {
929 Dcb
.fRtsControl
= RTS_CONTROL_ENABLE
;
932 if (Control
& EFI_SERIAL_DATA_TERMINAL_READY
) {
933 Dcb
.fDtrControl
= DTR_CONTROL_ENABLE
;
936 if (Control
& EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE
) {
937 Private
->HardwareFlowControl
= TRUE
;
940 if (Control
& EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE
) {
941 Private
->SoftwareLoopbackEnable
= TRUE
;
944 if (Control
& EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE
) {
945 Private
->HardwareLoopbackEnable
= TRUE
;
948 Result
= Private
->WinNtThunk
->SetCommState (
954 Private
->NtError
= Private
->WinNtThunk
->GetLastError ();
955 DEBUG ((EFI_D_ERROR
, "SerialSetControl: SetCommState %d\n", Private
->NtError
));
956 gBS
->RestoreTPL (Tpl
);
957 return EFI_DEVICE_ERROR
;
960 gBS
->RestoreTPL (Tpl
);
968 WinNtSerialIoGetControl (
969 IN EFI_SERIAL_IO_PROTOCOL
*This
,
976 TODO: Add function description
980 This - TODO: add argument description
981 Control - TODO: add argument description
985 EFI_DEVICE_ERROR - TODO: Add description for return value
986 EFI_DEVICE_ERROR - TODO: Add description for return value
987 EFI_DEVICE_ERROR - TODO: Add description for return value
988 EFI_SUCCESS - TODO: Add description for return value
992 WIN_NT_SERIAL_IO_PRIVATE_DATA
*Private
;
999 Tpl
= gBS
->RaiseTPL (EFI_TPL_NOTIFY
);
1001 Private
= WIN_NT_SERIAL_IO_PRIVATE_DATA_FROM_THIS (This
);
1006 if (!Private
->WinNtThunk
->GetCommModemStatus (Private
->NtHandle
, &ModemStatus
)) {
1007 Private
->NtError
= Private
->WinNtThunk
->GetLastError ();
1008 gBS
->RestoreTPL (Tpl
);
1009 return EFI_DEVICE_ERROR
;
1013 if (ModemStatus
& MS_CTS_ON
) {
1014 Bits
|= EFI_SERIAL_CLEAR_TO_SEND
;
1017 if (ModemStatus
& MS_DSR_ON
) {
1018 Bits
|= EFI_SERIAL_DATA_SET_READY
;
1021 if (ModemStatus
& MS_RING_ON
) {
1022 Bits
|= EFI_SERIAL_RING_INDICATE
;
1025 if (ModemStatus
& MS_RLSD_ON
) {
1026 Bits
|= EFI_SERIAL_CARRIER_DETECT
;
1032 if (!Private
->WinNtThunk
->GetCommState (Private
->NtHandle
, &Dcb
)) {
1033 Private
->NtError
= Private
->WinNtThunk
->GetLastError ();
1034 DEBUG ((EFI_D_ERROR
, "SerialGetControl: GetCommState %d\n", Private
->NtError
));
1035 gBS
->RestoreTPL (Tpl
);
1036 return EFI_DEVICE_ERROR
;
1039 if (Dcb
.fDtrControl
== DTR_CONTROL_ENABLE
) {
1040 Bits
|= EFI_SERIAL_DATA_TERMINAL_READY
;
1043 if (Dcb
.fRtsControl
== RTS_CONTROL_ENABLE
) {
1044 Bits
|= EFI_SERIAL_REQUEST_TO_SEND
;
1047 if (Private
->HardwareFlowControl
) {
1048 Bits
|= EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE
;
1051 if (Private
->SoftwareLoopbackEnable
) {
1052 Bits
|= EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE
;
1055 if (Private
->HardwareLoopbackEnable
) {
1056 Bits
|= EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE
;
1060 // Get input buffer status
1062 if (!Private
->WinNtThunk
->ClearCommError (Private
->NtHandle
, &Errors
, &Private
->NtComStatus
)) {
1063 Private
->NtError
= Private
->WinNtThunk
->GetLastError ();
1064 DEBUG ((EFI_D_ERROR
, "SerialGetControl: ClearCommError %d\n", Private
->NtError
));
1065 gBS
->RestoreTPL (Tpl
);
1066 return EFI_DEVICE_ERROR
;
1069 if (Private
->NtComStatus
.cbInQue
== 0) {
1070 Bits
|= EFI_SERIAL_INPUT_BUFFER_EMPTY
;
1075 gBS
->RestoreTPL (Tpl
);
1083 WinNtSerialIoWrite (
1084 IN EFI_SERIAL_IO_PROTOCOL
*This
,
1085 IN OUT UINTN
*BufferSize
,
1090 Routine Description:
1092 TODO: Add function description
1096 This - TODO: add argument description
1097 BufferSize - TODO: add argument description
1098 Buffer - TODO: add argument description
1102 EFI_DEVICE_ERROR - TODO: Add description for return value
1103 EFI_SUCCESS - TODO: Add description for return value
1107 WIN_NT_SERIAL_IO_PRIVATE_DATA
*Private
;
1109 UINTN TotalBytesWritten
;
1117 Tpl
= gBS
->RaiseTPL (EFI_TPL_NOTIFY
);
1119 Private
= WIN_NT_SERIAL_IO_PRIVATE_DATA_FROM_THIS (This
);
1121 ByteBuffer
= (UINT8
*) Buffer
;
1122 TotalBytesWritten
= 0;
1124 if (Private
->SoftwareLoopbackEnable
|| Private
->HardwareLoopbackEnable
) {
1125 for (Index
= 0; Index
< *BufferSize
; Index
++) {
1126 if (IsaSerialFifoAdd (&Private
->Fifo
, ByteBuffer
[Index
]) == EFI_SUCCESS
) {
1127 TotalBytesWritten
++;
1133 BytesToGo
= (DWORD
) (*BufferSize
);
1136 if (Private
->HardwareFlowControl
) {
1140 WinNtSerialIoGetControl (&Private
->SerialIo
, &Control
);
1141 Control
|= EFI_SERIAL_REQUEST_TO_SEND
;
1142 WinNtSerialIoSetControl (&Private
->SerialIo
, Control
);
1148 Result
= Private
->WinNtThunk
->WriteFile (
1150 &ByteBuffer
[TotalBytesWritten
],
1156 if (Private
->HardwareFlowControl
) {
1160 WinNtSerialIoGetControl (&Private
->SerialIo
, &Control
);
1161 Control
&= ~ (UINT32
) EFI_SERIAL_REQUEST_TO_SEND
;
1162 WinNtSerialIoSetControl (&Private
->SerialIo
, Control
);
1165 TotalBytesWritten
+= BytesWritten
;
1166 BytesToGo
-= BytesWritten
;
1168 Private
->NtError
= Private
->WinNtThunk
->GetLastError ();
1169 DEBUG ((EFI_D_ERROR
, "SerialWrite: FileWrite %d\n", Private
->NtError
));
1170 *BufferSize
= TotalBytesWritten
;
1171 gBS
->RestoreTPL (Tpl
);
1172 return EFI_DEVICE_ERROR
;
1174 } while (BytesToGo
> 0);
1177 *BufferSize
= TotalBytesWritten
;
1179 gBS
->RestoreTPL (Tpl
);
1188 IN EFI_SERIAL_IO_PROTOCOL
*This
,
1189 IN OUT UINTN
*BufferSize
,
1194 Routine Description:
1196 TODO: Add function description
1200 This - TODO: add argument description
1201 BufferSize - TODO: add argument description
1202 Buffer - TODO: add argument description
1206 EFI_DEVICE_ERROR - TODO: Add description for return value
1210 WIN_NT_SERIAL_IO_PRIVATE_DATA
*Private
;
1219 Tpl
= gBS
->RaiseTPL (EFI_TPL_NOTIFY
);
1221 Private
= WIN_NT_SERIAL_IO_PRIVATE_DATA_FROM_THIS (This
);
1226 if (Private
->SoftwareLoopbackEnable
|| Private
->HardwareLoopbackEnable
) {
1227 for (Index
= 0, BytesRead
= 0; Index
< *BufferSize
; Index
++) {
1228 if (IsaSerialFifoRemove (&Private
->Fifo
, &Data
) == EFI_SUCCESS
) {
1229 ((UINT8
*) Buffer
)[Index
] = Data
;
1236 if (Private
->HardwareFlowControl
) {
1237 WinNtSerialIoGetControl (&Private
->SerialIo
, &Control
);
1238 Control
|= EFI_SERIAL_DATA_TERMINAL_READY
;
1239 WinNtSerialIoSetControl (&Private
->SerialIo
, Control
);
1242 Result
= Private
->WinNtThunk
->ReadFile (
1245 (DWORD
) *BufferSize
,
1250 if (Private
->HardwareFlowControl
) {
1251 WinNtSerialIoGetControl (&Private
->SerialIo
, &Control
);
1252 Control
&= ~ (UINT32
) EFI_SERIAL_DATA_TERMINAL_READY
;
1253 WinNtSerialIoSetControl (&Private
->SerialIo
, Control
);
1257 Private
->NtError
= Private
->WinNtThunk
->GetLastError ();
1258 gBS
->RestoreTPL (Tpl
);
1259 return EFI_DEVICE_ERROR
;
1263 if (BytesRead
!= *BufferSize
) {
1264 Status
= EFI_TIMEOUT
;
1266 Status
= EFI_SUCCESS
;
1269 *BufferSize
= (UINTN
) BytesRead
;
1271 gBS
->RestoreTPL (Tpl
);
1278 IN SERIAL_DEV_FIFO
*Fifo
1282 Routine Description:
1283 Detect whether specific FIFO is full or not
1286 Fifo SERIAL_DEV_FIFO *: A pointer to the Data Structure SERIAL_DEV_FIFO
1289 TRUE: the FIFO is full
1290 FALSE: the FIFO is not full
1294 if (Fifo
->Surplus
== 0) {
1302 IsaSerialFifoEmpty (
1303 IN SERIAL_DEV_FIFO
*Fifo
1307 Routine Description:
1308 Detect whether specific FIFO is empty or not
1311 Fifo SERIAL_DEV_FIFO *: A pointer to the Data Structure SERIAL_DEV_FIFO
1314 TRUE: the FIFO is empty
1315 FALSE: the FIFO is not empty
1319 if (Fifo
->Surplus
== SERIAL_MAX_BUFFER_SIZE
) {
1328 IN SERIAL_DEV_FIFO
*Fifo
,
1333 Routine Description:
1334 Add data to specific FIFO
1337 Fifo SERIAL_DEV_FIFO *: A pointer to the Data Structure SERIAL_DEV_FIFO
1338 Data UINT8: the data added to FIFO
1341 EFI_SUCCESS: Add data to specific FIFO successfully
1342 EFI_OUT_RESOURCE: Failed to add data because FIFO is already full
1345 // TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
1348 // if FIFO full can not add data
1350 if (IsaSerialFifoFull (Fifo
)) {
1351 return EFI_OUT_OF_RESOURCES
;
1355 // FIFO is not full can add data
1357 Fifo
->Data
[Fifo
->Last
] = Data
;
1360 if (Fifo
->Last
>= SERIAL_MAX_BUFFER_SIZE
) {
1368 IsaSerialFifoRemove (
1369 IN SERIAL_DEV_FIFO
*Fifo
,
1374 Routine Description:
1375 Remove data from specific FIFO
1378 Fifo SERIAL_DEV_FIFO *: A pointer to the Data Structure SERIAL_DEV_FIFO
1379 Data UINT8*: the data removed from FIFO
1382 EFI_SUCCESS: Remove data from specific FIFO successfully
1383 EFI_OUT_RESOURCE: Failed to remove data because FIFO is empty
1386 // TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
1389 // if FIFO is empty, no data can remove
1391 if (IsaSerialFifoEmpty (Fifo
)) {
1392 return EFI_OUT_OF_RESOURCES
;
1396 // FIFO is not empty, can remove data
1398 *Data
= Fifo
->Data
[Fifo
->First
];
1401 if (Fifo
->First
>= SERIAL_MAX_BUFFER_SIZE
) {