2 Produces Simple Text Input Protocol, Simple Text Input Extended Protocol and
3 Simple Text Output Protocol upon Serial IO Protocol.
5 Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
22 EFI_DRIVER_BINDING_PROTOCOL gTerminalDriverBinding
= {
23 TerminalDriverBindingSupported
,
24 TerminalDriverBindingStart
,
25 TerminalDriverBindingStop
,
32 EFI_GUID
*gTerminalType
[] = {
40 TERMINAL_DEV mTerminalDevTemplate
= {
41 TERMINAL_DEV_SIGNATURE
,
48 TerminalConInReadKeyStroke
,
53 TerminalConOutOutputString
,
54 TerminalConOutTestString
,
55 TerminalConOutQueryMode
,
56 TerminalConOutSetMode
,
57 TerminalConOutSetAttribute
,
58 TerminalConOutClearScreen
,
59 TerminalConOutSetCursorPosition
,
60 TerminalConOutEnableCursor
,
63 { // SimpleTextOutputMode
66 EFI_TEXT_ATTR (EFI_LIGHTGRAY
, EFI_BLACK
), // Attribute
71 NULL
, // TerminalConsoleModeData
78 NULL
, // ControllerNameTable
80 NULL
, // TwoSecondTimeOut
84 { // SimpleTextInputEx
86 TerminalConInReadKeyStrokeEx
,
88 TerminalConInSetState
,
89 TerminalConInRegisterKeyNotify
,
90 TerminalConInUnregisterKeyNotify
,
98 TERMINAL_CONSOLE_MODE_DATA mTerminalConsoleModeData
[] = {
101 // New modes can be added here.
102 // The last entry is specific for PcdConOutRow x PcdConOutColumn.
108 Test to see if this driver supports Controller.
110 @param This Protocol instance pointer.
111 @param Controller Handle of device to test
112 @param RemainingDevicePath Optional parameter use to pick a specific child
115 @retval EFI_SUCCESS This driver supports this device.
116 @retval EFI_ALREADY_STARTED This driver is already running on this device.
117 @retval other This driver does not support this device.
122 TerminalDriverBindingSupported (
123 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
124 IN EFI_HANDLE Controller
,
125 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
129 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
130 EFI_SERIAL_IO_PROTOCOL
*SerialIo
;
131 VENDOR_DEVICE_PATH
*Node
;
134 // If remaining device path is not NULL, then make sure it is a
135 // device path that describes a terminal communications protocol.
137 if (RemainingDevicePath
!= NULL
) {
139 // Check if RemainingDevicePath is the End of Device Path Node,
140 // if yes, go on checking other conditions
142 if (!IsDevicePathEnd (RemainingDevicePath
)) {
144 // If RemainingDevicePath isn't the End of Device Path Node,
145 // check its validation
147 Node
= (VENDOR_DEVICE_PATH
*) RemainingDevicePath
;
149 if (Node
->Header
.Type
!= MESSAGING_DEVICE_PATH
||
150 Node
->Header
.SubType
!= MSG_VENDOR_DP
||
151 DevicePathNodeLength(&Node
->Header
) != sizeof(VENDOR_DEVICE_PATH
)) {
153 return EFI_UNSUPPORTED
;
157 // only supports PC ANSI, VT100, VT100+ and VT-UTF8 terminal types
159 if (!CompareGuid (&Node
->Guid
, &gEfiPcAnsiGuid
) &&
160 !CompareGuid (&Node
->Guid
, &gEfiVT100Guid
) &&
161 !CompareGuid (&Node
->Guid
, &gEfiVT100PlusGuid
) &&
162 !CompareGuid (&Node
->Guid
, &gEfiVTUTF8Guid
)) {
164 return EFI_UNSUPPORTED
;
169 // Open the IO Abstraction(s) needed to perform the supported test
170 // The Controller must support the Serial I/O Protocol.
171 // This driver is a bus driver with at most 1 child device, so it is
172 // ok for it to be already started.
174 Status
= gBS
->OpenProtocol (
176 &gEfiSerialIoProtocolGuid
,
178 This
->DriverBindingHandle
,
180 EFI_OPEN_PROTOCOL_BY_DRIVER
182 if (Status
== EFI_ALREADY_STARTED
) {
186 if (EFI_ERROR (Status
)) {
191 // Close the I/O Abstraction(s) used to perform the supported test
195 &gEfiSerialIoProtocolGuid
,
196 This
->DriverBindingHandle
,
201 // Open the EFI Device Path protocol needed to perform the supported test
203 Status
= gBS
->OpenProtocol (
205 &gEfiDevicePathProtocolGuid
,
206 (VOID
**) &ParentDevicePath
,
207 This
->DriverBindingHandle
,
209 EFI_OPEN_PROTOCOL_BY_DRIVER
211 if (Status
== EFI_ALREADY_STARTED
) {
215 if (EFI_ERROR (Status
)) {
220 // Close protocol, don't use device path protocol in the Support() function
224 &gEfiDevicePathProtocolGuid
,
225 This
->DriverBindingHandle
,
233 Build the terminal device path for the child device according to the
236 @param ParentDevicePath Parent device path.
237 @param RemainingDevicePath A specific child device.
239 @return The child device path built.
242 EFI_DEVICE_PATH_PROTOCOL
*
244 BuildTerminalDevpath (
245 IN EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
,
246 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
249 EFI_DEVICE_PATH_PROTOCOL
*TerminalDevicePath
;
251 VENDOR_DEVICE_PATH
*Node
;
254 TerminalDevicePath
= NULL
;
255 TerminalType
= PCANSITYPE
;
258 // Use the RemainingDevicePath to determine the terminal type
260 Node
= (VENDOR_DEVICE_PATH
*) RemainingDevicePath
;
262 TerminalType
= PCANSITYPE
;
264 } else if (CompareGuid (&Node
->Guid
, &gEfiPcAnsiGuid
)) {
266 TerminalType
= PCANSITYPE
;
268 } else if (CompareGuid (&Node
->Guid
, &gEfiVT100Guid
)) {
270 TerminalType
= VT100TYPE
;
272 } else if (CompareGuid (&Node
->Guid
, &gEfiVT100PlusGuid
)) {
274 TerminalType
= VT100PLUSTYPE
;
276 } else if (CompareGuid (&Node
->Guid
, &gEfiVTUTF8Guid
)) {
278 TerminalType
= VTUTF8TYPE
;
285 // Build the device path for the child device
287 Status
= SetTerminalDevicePath (
292 if (EFI_ERROR (Status
)) {
295 return TerminalDevicePath
;
299 Compare a device path data structure to that of all the nodes of a
300 second device path instance.
302 @param Multi A pointer to a multi-instance device path data structure.
303 @param Single A pointer to a single-instance device path data structure.
305 @retval TRUE If the Single is contained within Multi.
306 @retval FALSE The Single is not match within Multi.
311 IN EFI_DEVICE_PATH_PROTOCOL
*Multi
,
312 IN EFI_DEVICE_PATH_PROTOCOL
*Single
315 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
316 EFI_DEVICE_PATH_PROTOCOL
*DevicePathInst
;
320 DevicePathInst
= GetNextDevicePathInstance (&DevicePath
, &Size
);
322 // Search for the match of 'Single' in 'Multi'
324 while (DevicePathInst
!= NULL
) {
326 // If the single device path is found in multiple device paths,
329 if (CompareMem (Single
, DevicePathInst
, Size
) == 0) {
330 FreePool (DevicePathInst
);
334 FreePool (DevicePathInst
);
335 DevicePathInst
= GetNextDevicePathInstance (&DevicePath
, &Size
);
342 Check whether the terminal device path is in the global variable.
344 @param VariableName Pointer to one global variable.
345 @param TerminalDevicePath Pointer to the terminal device's device path.
347 @retval TRUE The devcie is in the global variable.
348 @retval FALSE The devcie is not in the global variable.
352 IsTerminalInConsoleVariable (
353 IN CHAR16
*VariableName
,
354 IN EFI_DEVICE_PATH_PROTOCOL
*TerminalDevicePath
357 EFI_DEVICE_PATH_PROTOCOL
*Variable
;
361 // Get global variable and its size according to the name given.
363 Variable
= GetEfiGlobalVariable (VariableName
);
364 if (Variable
== NULL
) {
369 // Check whether the terminal device path is one of the variable instances.
371 ReturnFlag
= MatchDevicePaths (Variable
, TerminalDevicePath
);
379 Free notify functions list.
381 @param ListHead The list head
383 @retval EFI_SUCCESS Free the notify list successfully.
384 @retval EFI_INVALID_PARAMETER ListHead is NULL.
388 TerminalFreeNotifyList (
389 IN OUT LIST_ENTRY
*ListHead
392 TERMINAL_CONSOLE_IN_EX_NOTIFY
*NotifyNode
;
394 if (ListHead
== NULL
) {
395 return EFI_INVALID_PARAMETER
;
397 while (!IsListEmpty (ListHead
)) {
399 ListHead
->ForwardLink
,
400 TERMINAL_CONSOLE_IN_EX_NOTIFY
,
402 TERMINAL_CONSOLE_IN_EX_NOTIFY_SIGNATURE
404 RemoveEntryList (ListHead
->ForwardLink
);
405 FreePool (NotifyNode
);
412 Initialize all the text modes which the terminal console supports.
414 It returns information for available text modes that the terminal can support.
416 @param[out] TextModeCount The total number of text modes that terminal console supports.
417 @param[out] TextModeData The buffer to the text modes column and row information.
418 Caller is responsible to free it when it's non-NULL.
420 @retval EFI_SUCCESS The supporting mode information is returned.
421 @retval EFI_INVALID_PARAMETER The parameters are invalid.
425 InitializeTerminalConsoleTextMode (
426 OUT UINTN
*TextModeCount
,
427 OUT TERMINAL_CONSOLE_MODE_DATA
**TextModeData
432 TERMINAL_CONSOLE_MODE_DATA
*ModeBuffer
;
433 TERMINAL_CONSOLE_MODE_DATA
*NewModeBuffer
;
437 if ((TextModeCount
== NULL
) || (TextModeData
== NULL
)) {
438 return EFI_INVALID_PARAMETER
;
442 // Assign the last entry as PcdConOutColumn and PcdConOutRow defined.
444 Count
= sizeof (mTerminalConsoleModeData
) / sizeof (TERMINAL_CONSOLE_MODE_DATA
);
445 mTerminalConsoleModeData
[Count
- 1].Columns
= (UINTN
) PcdGet32 (PcdConOutColumn
);
446 mTerminalConsoleModeData
[Count
- 1].Rows
= (UINTN
) PcdGet32 (PcdConOutRow
);;
449 // Get defined mode buffer pointer.
451 ModeBuffer
= mTerminalConsoleModeData
;
454 // Here we make sure that the final mode exposed does not include the duplicated modes,
455 // and does not include the invalid modes which exceed the max column and row.
456 // Reserve 2 modes for 80x25, 80x50 of terminal console.
458 NewModeBuffer
= AllocateZeroPool (sizeof (TERMINAL_CONSOLE_MODE_DATA
) * (Count
+ 2));
459 ASSERT (NewModeBuffer
!= NULL
);
462 // Mode 0 and mode 1 is for 80x25, 80x50 according to UEFI spec.
466 NewModeBuffer
[ValidCount
].Columns
= 80;
467 NewModeBuffer
[ValidCount
].Rows
= 25;
470 NewModeBuffer
[ValidCount
].Columns
= 80;
471 NewModeBuffer
[ValidCount
].Rows
= 50;
475 // Start from mode 2 to put the valid mode other than 80x25 and 80x50 in the output mode buffer.
477 for (Index
= 0; Index
< Count
; Index
++) {
478 if ((ModeBuffer
[Index
].Columns
== 0) || (ModeBuffer
[Index
].Rows
== 0)) {
480 // Skip the pre-defined mode which is invalid.
484 for (ValidIndex
= 0; ValidIndex
< ValidCount
; ValidIndex
++) {
485 if ((ModeBuffer
[Index
].Columns
== NewModeBuffer
[ValidIndex
].Columns
) &&
486 (ModeBuffer
[Index
].Rows
== NewModeBuffer
[ValidIndex
].Rows
)) {
488 // Skip the duplicated mode.
493 if (ValidIndex
== ValidCount
) {
494 NewModeBuffer
[ValidCount
].Columns
= ModeBuffer
[Index
].Columns
;
495 NewModeBuffer
[ValidCount
].Rows
= ModeBuffer
[Index
].Rows
;
501 for (Index
= 0; Index
< ValidCount
; Index
++) {
502 DEBUG ((EFI_D_INFO
, "Terminal - Mode %d, Column = %d, Row = %d\n",
503 Index
, NewModeBuffer
[Index
].Columns
, NewModeBuffer
[Index
].Rows
));
508 // Return valid mode count and mode information buffer.
510 *TextModeCount
= ValidCount
;
511 *TextModeData
= NewModeBuffer
;
516 Start this driver on Controller by opening a Serial IO protocol,
517 reading Device Path, and creating a child handle with a Simple Text In,
518 Simple Text In Ex and Simple Text Out protocol, and device path protocol.
519 And store Console Device Environment Variables.
521 @param This Protocol instance pointer.
522 @param Controller Handle of device to bind driver to
523 @param RemainingDevicePath Optional parameter use to pick a specific child
526 @retval EFI_SUCCESS This driver is added to Controller.
527 @retval EFI_ALREADY_STARTED This driver is already running on Controller.
528 @retval other This driver does not support this device.
533 TerminalDriverBindingStart (
534 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
535 IN EFI_HANDLE Controller
,
536 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
540 EFI_SERIAL_IO_PROTOCOL
*SerialIo
;
541 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
542 VENDOR_DEVICE_PATH
*Node
;
543 VENDOR_DEVICE_PATH
*DefaultNode
;
544 EFI_SERIAL_IO_MODE
*Mode
;
545 UINTN SerialInTimeOut
;
546 TERMINAL_DEV
*TerminalDevice
;
548 EFI_OPEN_PROTOCOL_INFORMATION_ENTRY
*OpenInfoBuffer
;
551 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
552 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*SimpleTextOutput
;
553 EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*SimpleTextInput
;
554 BOOLEAN ConInSelected
;
555 BOOLEAN ConOutSelected
;
556 BOOLEAN NullRemaining
;
557 BOOLEAN SimTxtInInstalled
;
558 BOOLEAN SimTxtOutInstalled
;
562 TerminalDevice
= NULL
;
564 ConInSelected
= FALSE
;
565 ConOutSelected
= FALSE
;
566 NullRemaining
= TRUE
;
567 SimTxtInInstalled
= FALSE
;
568 SimTxtOutInstalled
= FALSE
;
571 // Get the Device Path Protocol to build the device path of the child device
573 Status
= gBS
->OpenProtocol (
575 &gEfiDevicePathProtocolGuid
,
576 (VOID
**) &ParentDevicePath
,
577 This
->DriverBindingHandle
,
579 EFI_OPEN_PROTOCOL_BY_DRIVER
581 if (EFI_ERROR (Status
) && Status
!= EFI_ALREADY_STARTED
) {
586 // Open the Serial I/O Protocol BY_DRIVER. It might already be started.
588 Status
= gBS
->OpenProtocol (
590 &gEfiSerialIoProtocolGuid
,
592 This
->DriverBindingHandle
,
594 EFI_OPEN_PROTOCOL_BY_DRIVER
596 if (EFI_ERROR (Status
) && Status
!= EFI_ALREADY_STARTED
) {
600 if (Status
!= EFI_ALREADY_STARTED
) {
602 // the serial I/O protocol never be opened before, it is the first
603 // time to start the serial Io controller
609 // Serial I/O is not already open by this driver, then tag the handle
610 // with the Terminal Driver GUID and update the ConInDev, ConOutDev, and
611 // StdErrDev variables with the list of possible terminal types on this
614 Status
= gBS
->OpenProtocol (
618 This
->DriverBindingHandle
,
620 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
622 if (EFI_ERROR (Status
)) {
623 Status
= gBS
->InstallMultipleProtocolInterfaces (
626 DuplicateDevicePath (ParentDevicePath
),
629 if (EFI_ERROR (Status
)) {
633 if (!IsHotPlugDevice (ParentDevicePath
)) {
635 // if the serial device is a hot plug device, do not update the
636 // ConInDev, ConOutDev, and StdErrDev variables.
638 TerminalUpdateConsoleDevVariable (L
"ConInDev", ParentDevicePath
);
639 TerminalUpdateConsoleDevVariable (L
"ConOutDev", ParentDevicePath
);
640 TerminalUpdateConsoleDevVariable (L
"ErrOutDev", ParentDevicePath
);
645 // Check the requirement for the SimpleTxtIn and SimpleTxtOut protocols
647 // Simple In/Out Protocol will not be installed onto the handle if the
648 // device path to the handle is not present in the ConIn/ConOut
649 // environment variable. But If RemainingDevicePath is NULL, then always
650 // produce both Simple In and Simple Text Output Protocols. This is required
651 // for the connect all sequences to make sure all possible consoles are
652 // produced no matter what the current values of ConIn, ConOut, or StdErr are.
654 if (RemainingDevicePath
== NULL
) {
655 NullRemaining
= TRUE
;
658 DevicePath
= BuildTerminalDevpath (ParentDevicePath
, RemainingDevicePath
);
659 if (DevicePath
!= NULL
) {
660 ConInSelected
= IsTerminalInConsoleVariable (L
"ConIn", DevicePath
);
661 ConOutSelected
= IsTerminalInConsoleVariable (L
"ConOut", DevicePath
);
662 FreePool (DevicePath
);
667 // Not create the child terminal handle if both Simple In/In Ex and
668 // Simple text Out protocols are not required to be published
670 if ((!ConInSelected
)&&(!ConOutSelected
)&&(!NullRemaining
)) {
675 // create the child terminal handle during first entry
679 // First enther the start funciton
683 // Make sure a child handle does not already exist. This driver can only
684 // produce one child per serial port.
686 Status
= gBS
->OpenProtocolInformation (
688 &gEfiSerialIoProtocolGuid
,
692 if (!EFI_ERROR (Status
)) {
693 Status
= EFI_SUCCESS
;
694 for (Index
= 0; Index
< EntryCount
; Index
++) {
695 if ((OpenInfoBuffer
[Index
].Attributes
& EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
) != 0) {
696 Status
= EFI_ALREADY_STARTED
;
700 FreePool (OpenInfoBuffer
);
701 if (EFI_ERROR (Status
)) {
707 // If RemainingDevicePath is NULL, then create default device path node
709 if (RemainingDevicePath
== NULL
) {
710 DefaultNode
= AllocateZeroPool (sizeof (VENDOR_DEVICE_PATH
));
711 if (DefaultNode
== NULL
) {
712 Status
= EFI_OUT_OF_RESOURCES
;
716 TerminalType
= PcdGet8 (PcdDefaultTerminalType
);
718 // Must be between PCANSITYPE (0) and VTUTF8TYPE (3)
720 ASSERT (TerminalType
<= VTUTF8TYPE
);
722 CopyMem (&DefaultNode
->Guid
, gTerminalType
[TerminalType
], sizeof (EFI_GUID
));
723 RemainingDevicePath
= (EFI_DEVICE_PATH_PROTOCOL
*) DefaultNode
;
724 } else if (!IsDevicePathEnd (RemainingDevicePath
)) {
726 // If RemainingDevicePath isn't the End of Device Path Node,
727 // Use the RemainingDevicePath to determine the terminal type
729 Node
= (VENDOR_DEVICE_PATH
*)RemainingDevicePath
;
730 if (CompareGuid (&Node
->Guid
, &gEfiPcAnsiGuid
)) {
731 TerminalType
= PCANSITYPE
;
732 } else if (CompareGuid (&Node
->Guid
, &gEfiVT100Guid
)) {
733 TerminalType
= VT100TYPE
;
734 } else if (CompareGuid (&Node
->Guid
, &gEfiVT100PlusGuid
)) {
735 TerminalType
= VT100PLUSTYPE
;
736 } else if (CompareGuid (&Node
->Guid
, &gEfiVTUTF8Guid
)) {
737 TerminalType
= VTUTF8TYPE
;
743 // If RemainingDevicePath is the End of Device Path Node,
744 // skip enumerate any device and return EFI_SUCESSS
750 // Initialize the Terminal Dev
752 TerminalDevice
= AllocateCopyPool (sizeof (TERMINAL_DEV
), &mTerminalDevTemplate
);
753 if (TerminalDevice
== NULL
) {
754 Status
= EFI_OUT_OF_RESOURCES
;
758 TerminalDevice
->TerminalType
= TerminalType
;
759 TerminalDevice
->SerialIo
= SerialIo
;
761 InitializeListHead (&TerminalDevice
->NotifyList
);
762 Status
= gBS
->CreateEvent (
765 TerminalConInWaitForKeyEx
,
767 &TerminalDevice
->SimpleInputEx
.WaitForKeyEx
769 if (EFI_ERROR (Status
)) {
773 Status
= gBS
->CreateEvent (
776 TerminalConInWaitForKey
,
778 &TerminalDevice
->SimpleInput
.WaitForKey
780 if (EFI_ERROR (Status
)) {
784 // Allocates and initializes the FIFO buffer to be zero, used for accommodating
785 // the pre-read pending characters.
787 TerminalDevice
->RawFiFo
= AllocateZeroPool (sizeof (RAW_DATA_FIFO
));
788 if (TerminalDevice
->RawFiFo
== NULL
) {
791 TerminalDevice
->UnicodeFiFo
= AllocateZeroPool (sizeof (UNICODE_FIFO
));
792 if (TerminalDevice
->UnicodeFiFo
== NULL
) {
795 TerminalDevice
->EfiKeyFiFo
= AllocateZeroPool (sizeof (EFI_KEY_FIFO
));
796 if (TerminalDevice
->EfiKeyFiFo
== NULL
) {
801 // Set the timeout value of serial buffer for
802 // keystroke response performance issue
804 Mode
= TerminalDevice
->SerialIo
->Mode
;
807 if (Mode
->BaudRate
!= 0) {
808 SerialInTimeOut
= (1 + Mode
->DataBits
+ Mode
->StopBits
) * 2 * 1000000 / (UINTN
) Mode
->BaudRate
;
811 Status
= TerminalDevice
->SerialIo
->SetAttributes (
812 TerminalDevice
->SerialIo
,
814 Mode
->ReceiveFifoDepth
,
815 (UINT32
) SerialInTimeOut
,
816 (EFI_PARITY_TYPE
) (Mode
->Parity
),
817 (UINT8
) Mode
->DataBits
,
818 (EFI_STOP_BITS_TYPE
) (Mode
->StopBits
)
820 if (EFI_ERROR (Status
)) {
822 // if set attributes operation fails, invalidate
823 // the value of SerialInTimeOut,thus make it
824 // inconsistent with the default timeout value
825 // of serial buffer. This will invoke the recalculation
826 // in the readkeystroke routine.
828 TerminalDevice
->SerialInTimeOut
= 0;
830 TerminalDevice
->SerialInTimeOut
= SerialInTimeOut
;
833 // Set Simple Text Output Protocol from template.
835 SimpleTextOutput
= CopyMem (
836 &TerminalDevice
->SimpleTextOutput
,
837 &mTerminalDevTemplate
.SimpleTextOutput
,
838 sizeof (mTerminalDevTemplate
.SimpleTextOutput
)
840 SimpleTextOutput
->Mode
= &TerminalDevice
->SimpleTextOutputMode
;
842 Status
= InitializeTerminalConsoleTextMode (&ModeCount
, &TerminalDevice
->TerminalConsoleModeData
);
843 if (EFI_ERROR (Status
)) {
846 TerminalDevice
->SimpleTextOutputMode
.MaxMode
= (INT32
) ModeCount
;
849 // For terminal devices, cursor is always visible
851 TerminalDevice
->SimpleTextOutputMode
.CursorVisible
= TRUE
;
852 Status
= TerminalConOutSetAttribute (
854 EFI_TEXT_ATTR (EFI_LIGHTGRAY
, EFI_BLACK
)
856 if (EFI_ERROR (Status
)) {
861 // Build the component name for the child device
863 TerminalDevice
->ControllerNameTable
= NULL
;
864 switch (TerminalDevice
->TerminalType
) {
868 gTerminalComponentName
.SupportedLanguages
,
869 &TerminalDevice
->ControllerNameTable
,
870 (CHAR16
*)L
"PC-ANSI Serial Console",
875 gTerminalComponentName2
.SupportedLanguages
,
876 &TerminalDevice
->ControllerNameTable
,
877 (CHAR16
*)L
"PC-ANSI Serial Console",
886 gTerminalComponentName
.SupportedLanguages
,
887 &TerminalDevice
->ControllerNameTable
,
888 (CHAR16
*)L
"VT-100 Serial Console",
893 gTerminalComponentName2
.SupportedLanguages
,
894 &TerminalDevice
->ControllerNameTable
,
895 (CHAR16
*)L
"VT-100 Serial Console",
904 gTerminalComponentName
.SupportedLanguages
,
905 &TerminalDevice
->ControllerNameTable
,
906 (CHAR16
*)L
"VT-100+ Serial Console",
911 gTerminalComponentName2
.SupportedLanguages
,
912 &TerminalDevice
->ControllerNameTable
,
913 (CHAR16
*)L
"VT-100+ Serial Console",
922 gTerminalComponentName
.SupportedLanguages
,
923 &TerminalDevice
->ControllerNameTable
,
924 (CHAR16
*)L
"VT-UTF8 Serial Console",
929 gTerminalComponentName2
.SupportedLanguages
,
930 &TerminalDevice
->ControllerNameTable
,
931 (CHAR16
*)L
"VT-UTF8 Serial Console",
939 // Build the device path for the child device
941 Status
= SetTerminalDevicePath (
942 TerminalDevice
->TerminalType
,
944 &TerminalDevice
->DevicePath
946 if (EFI_ERROR (Status
)) {
950 Status
= TerminalConOutReset (SimpleTextOutput
, FALSE
);
951 if (EFI_ERROR (Status
)) {
955 Status
= TerminalConOutSetMode (SimpleTextOutput
, 0);
956 if (EFI_ERROR (Status
)) {
960 Status
= TerminalConOutEnableCursor (SimpleTextOutput
, TRUE
);
961 if (EFI_ERROR (Status
)) {
965 Status
= gBS
->CreateEvent (
966 EVT_TIMER
| EVT_NOTIFY_SIGNAL
,
968 TerminalConInTimerHandler
,
970 &TerminalDevice
->TimerEvent
972 ASSERT_EFI_ERROR (Status
);
974 Status
= gBS
->SetTimer (
975 TerminalDevice
->TimerEvent
,
977 KEYBOARD_TIMER_INTERVAL
979 ASSERT_EFI_ERROR (Status
);
981 Status
= gBS
->CreateEvent (
986 &TerminalDevice
->TwoSecondTimeOut
988 ASSERT_EFI_ERROR (Status
);
990 Status
= gBS
->InstallProtocolInterface (
991 &TerminalDevice
->Handle
,
992 &gEfiDevicePathProtocolGuid
,
993 EFI_NATIVE_INTERFACE
,
994 TerminalDevice
->DevicePath
996 if (EFI_ERROR (Status
)) {
1001 // Register the Parent-Child relationship via
1002 // EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.
1004 Status
= gBS
->OpenProtocol (
1006 &gEfiSerialIoProtocolGuid
,
1007 (VOID
**) &TerminalDevice
->SerialIo
,
1008 This
->DriverBindingHandle
,
1009 TerminalDevice
->Handle
,
1010 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
1012 if (EFI_ERROR (Status
)) {
1018 // Find the child handle, and get its TerminalDevice private data
1020 Status
= gBS
->OpenProtocolInformation (
1022 &gEfiSerialIoProtocolGuid
,
1026 if (!EFI_ERROR (Status
)) {
1027 Status
= EFI_NOT_FOUND
;
1028 ASSERT (OpenInfoBuffer
!= NULL
);
1029 for (Index
= 0; Index
< EntryCount
; Index
++) {
1030 if ((OpenInfoBuffer
[Index
].Attributes
& EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
) != 0) {
1032 // Find the child terminal handle.
1033 // Test whether the SimpleTxtIn and SimpleTxtOut have been published
1035 Status
= gBS
->OpenProtocol (
1036 OpenInfoBuffer
[Index
].ControllerHandle
,
1037 &gEfiSimpleTextInProtocolGuid
,
1038 (VOID
**) &SimpleTextInput
,
1039 This
->DriverBindingHandle
,
1040 OpenInfoBuffer
[Index
].ControllerHandle
,
1041 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1043 if (!EFI_ERROR (Status
)) {
1044 SimTxtInInstalled
= TRUE
;
1045 TerminalDevice
= TERMINAL_CON_IN_DEV_FROM_THIS (SimpleTextInput
);
1048 Status
= gBS
->OpenProtocol (
1049 OpenInfoBuffer
[Index
].ControllerHandle
,
1050 &gEfiSimpleTextOutProtocolGuid
,
1051 (VOID
**) &SimpleTextOutput
,
1052 This
->DriverBindingHandle
,
1053 OpenInfoBuffer
[Index
].ControllerHandle
,
1054 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1056 if (!EFI_ERROR (Status
)) {
1057 SimTxtOutInstalled
= TRUE
;
1058 TerminalDevice
= TERMINAL_CON_OUT_DEV_FROM_THIS (SimpleTextOutput
);
1060 Status
= EFI_SUCCESS
;
1065 FreePool (OpenInfoBuffer
);
1066 if (EFI_ERROR (Status
)) {
1073 ASSERT (TerminalDevice
!= NULL
);
1075 // Only do the reset if the device path is in the Conout variable
1077 if (ConInSelected
&& !SimTxtInInstalled
) {
1078 Status
= TerminalDevice
->SimpleInput
.Reset (
1079 &TerminalDevice
->SimpleInput
,
1082 if (EFI_ERROR (Status
)) {
1084 // Need to report Error Code first
1091 // Only output the configure string to remote terminal if the device path
1092 // is in the Conout variable
1094 if (ConOutSelected
&& !SimTxtOutInstalled
) {
1095 Status
= TerminalDevice
->SimpleTextOutput
.SetAttribute (
1096 &TerminalDevice
->SimpleTextOutput
,
1097 EFI_TEXT_ATTR (EFI_LIGHTGRAY
, EFI_BLACK
)
1099 if (EFI_ERROR (Status
)) {
1103 Status
= TerminalDevice
->SimpleTextOutput
.Reset (
1104 &TerminalDevice
->SimpleTextOutput
,
1107 if (EFI_ERROR (Status
)) {
1111 Status
= TerminalDevice
->SimpleTextOutput
.SetMode (
1112 &TerminalDevice
->SimpleTextOutput
,
1115 if (EFI_ERROR (Status
)) {
1119 Status
= TerminalDevice
->SimpleTextOutput
.EnableCursor (
1120 &TerminalDevice
->SimpleTextOutput
,
1123 if (EFI_ERROR (Status
)) {
1129 // Simple In/Out Protocol will not be installed onto the handle if the
1130 // device path to the handle is not present in the ConIn/ConOut
1131 // environment variable. But If RemainingDevicePath is NULL, then always
1132 // produce both Simple In and Simple Text Output Protocols. This is required
1133 // for the connect all sequences to make sure all possible consoles are
1134 // produced no matter what the current values of ConIn, ConOut, or StdErr are.
1136 if (!SimTxtInInstalled
&& (ConInSelected
|| NullRemaining
)) {
1137 Status
= gBS
->InstallMultipleProtocolInterfaces (
1138 &TerminalDevice
->Handle
,
1139 &gEfiSimpleTextInProtocolGuid
,
1140 &TerminalDevice
->SimpleInput
,
1141 &gEfiSimpleTextInputExProtocolGuid
,
1142 &TerminalDevice
->SimpleInputEx
,
1145 if (EFI_ERROR (Status
)) {
1150 if (!SimTxtOutInstalled
&& (ConOutSelected
|| NullRemaining
)) {
1151 Status
= gBS
->InstallProtocolInterface (
1152 &TerminalDevice
->Handle
,
1153 &gEfiSimpleTextOutProtocolGuid
,
1154 EFI_NATIVE_INTERFACE
,
1155 &TerminalDevice
->SimpleTextOutput
1157 if (EFI_ERROR (Status
)) {
1161 if (DefaultNode
!= NULL
) {
1162 FreePool (DefaultNode
);
1169 // Report error code before exiting
1171 DevicePath
= ParentDevicePath
;
1172 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
1173 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
1174 (EFI_PERIPHERAL_REMOTE_CONSOLE
| EFI_P_EC_CONTROLLER_ERROR
),
1180 // Use the Stop() function to free all resources allocated in Start()
1182 if (TerminalDevice
!= NULL
) {
1184 if (TerminalDevice
->Handle
!= NULL
) {
1185 This
->Stop (This
, Controller
, 1, &TerminalDevice
->Handle
);
1188 if (TerminalDevice
->TwoSecondTimeOut
!= NULL
) {
1189 gBS
->CloseEvent (TerminalDevice
->TwoSecondTimeOut
);
1192 if (TerminalDevice
->TimerEvent
!= NULL
) {
1193 gBS
->CloseEvent (TerminalDevice
->TimerEvent
);
1196 if (TerminalDevice
->SimpleInput
.WaitForKey
!= NULL
) {
1197 gBS
->CloseEvent (TerminalDevice
->SimpleInput
.WaitForKey
);
1200 if (TerminalDevice
->SimpleInputEx
.WaitForKeyEx
!= NULL
) {
1201 gBS
->CloseEvent (TerminalDevice
->SimpleInputEx
.WaitForKeyEx
);
1204 TerminalFreeNotifyList (&TerminalDevice
->NotifyList
);
1206 if (TerminalDevice
->RawFiFo
!= NULL
) {
1207 FreePool (TerminalDevice
->RawFiFo
);
1209 if (TerminalDevice
->UnicodeFiFo
!= NULL
) {
1210 FreePool (TerminalDevice
->UnicodeFiFo
);
1212 if (TerminalDevice
->EfiKeyFiFo
!= NULL
) {
1213 FreePool (TerminalDevice
->EfiKeyFiFo
);
1216 if (TerminalDevice
->ControllerNameTable
!= NULL
) {
1217 FreeUnicodeStringTable (TerminalDevice
->ControllerNameTable
);
1220 if (TerminalDevice
->DevicePath
!= NULL
) {
1221 FreePool (TerminalDevice
->DevicePath
);
1224 if (TerminalDevice
->TerminalConsoleModeData
!= NULL
) {
1225 FreePool (TerminalDevice
->TerminalConsoleModeData
);
1228 FreePool (TerminalDevice
);
1232 if (DefaultNode
!= NULL
) {
1233 FreePool (DefaultNode
);
1236 This
->Stop (This
, Controller
, 0, NULL
);
1242 Stop this driver on Controller by closing Simple Text In, Simple Text
1243 In Ex, Simple Text Out protocol, and removing parent device path from
1244 Console Device Environment Variables.
1246 @param This Protocol instance pointer.
1247 @param Controller Handle of device to stop driver on
1248 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
1249 children is zero stop the entire bus driver.
1250 @param ChildHandleBuffer List of Child Handles to Stop.
1252 @retval EFI_SUCCESS This driver is removed Controller.
1253 @retval other This driver could not be removed from this device.
1258 TerminalDriverBindingStop (
1259 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1260 IN EFI_HANDLE Controller
,
1261 IN UINTN NumberOfChildren
,
1262 IN EFI_HANDLE
*ChildHandleBuffer
1267 BOOLEAN AllChildrenStopped
;
1268 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*SimpleTextOutput
;
1269 TERMINAL_DEV
*TerminalDevice
;
1270 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
1271 EFI_SERIAL_IO_PROTOCOL
*SerialIo
;
1272 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
1274 Status
= gBS
->HandleProtocol (
1276 &gEfiDevicePathProtocolGuid
,
1277 (VOID
**) &DevicePath
1279 if (EFI_ERROR (Status
)) {
1284 // Complete all outstanding transactions to Controller.
1285 // Don't allow any new transaction to Controller to be started.
1287 if (NumberOfChildren
== 0) {
1289 // Close the bus driver
1291 Status
= gBS
->OpenProtocol (
1294 (VOID
**) &ParentDevicePath
,
1295 This
->DriverBindingHandle
,
1297 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1299 if (!EFI_ERROR (Status
)) {
1301 // Remove Parent Device Path from
1302 // the Console Device Environment Variables
1304 TerminalRemoveConsoleDevVariable (L
"ConInDev", ParentDevicePath
);
1305 TerminalRemoveConsoleDevVariable (L
"ConOutDev", ParentDevicePath
);
1306 TerminalRemoveConsoleDevVariable (L
"ErrOutDev", ParentDevicePath
);
1309 // Uninstall the Terminal Driver's GUID Tag from the Serial controller
1311 Status
= gBS
->UninstallMultipleProtocolInterfaces (
1319 // Free the ParentDevicePath that was duplicated in Start()
1321 if (!EFI_ERROR (Status
)) {
1322 FreePool (ParentDevicePath
);
1326 gBS
->CloseProtocol (
1328 &gEfiSerialIoProtocolGuid
,
1329 This
->DriverBindingHandle
,
1333 gBS
->CloseProtocol (
1335 &gEfiDevicePathProtocolGuid
,
1336 This
->DriverBindingHandle
,
1343 AllChildrenStopped
= TRUE
;
1345 for (Index
= 0; Index
< NumberOfChildren
; Index
++) {
1347 Status
= gBS
->OpenProtocol (
1348 ChildHandleBuffer
[Index
],
1349 &gEfiSimpleTextOutProtocolGuid
,
1350 (VOID
**) &SimpleTextOutput
,
1351 This
->DriverBindingHandle
,
1352 ChildHandleBuffer
[Index
],
1353 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1355 if (!EFI_ERROR (Status
)) {
1357 TerminalDevice
= TERMINAL_CON_OUT_DEV_FROM_THIS (SimpleTextOutput
);
1359 gBS
->CloseProtocol (
1361 &gEfiSerialIoProtocolGuid
,
1362 This
->DriverBindingHandle
,
1363 ChildHandleBuffer
[Index
]
1366 Status
= gBS
->UninstallMultipleProtocolInterfaces (
1367 ChildHandleBuffer
[Index
],
1368 &gEfiSimpleTextInProtocolGuid
,
1369 &TerminalDevice
->SimpleInput
,
1370 &gEfiSimpleTextInputExProtocolGuid
,
1371 &TerminalDevice
->SimpleInputEx
,
1372 &gEfiSimpleTextOutProtocolGuid
,
1373 &TerminalDevice
->SimpleTextOutput
,
1374 &gEfiDevicePathProtocolGuid
,
1375 TerminalDevice
->DevicePath
,
1378 if (EFI_ERROR (Status
)) {
1381 &gEfiSerialIoProtocolGuid
,
1382 (VOID
**) &SerialIo
,
1383 This
->DriverBindingHandle
,
1384 ChildHandleBuffer
[Index
],
1385 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
1389 if (TerminalDevice
->ControllerNameTable
!= NULL
) {
1390 FreeUnicodeStringTable (TerminalDevice
->ControllerNameTable
);
1393 gBS
->CloseEvent (TerminalDevice
->TimerEvent
);
1394 gBS
->CloseEvent (TerminalDevice
->TwoSecondTimeOut
);
1395 gBS
->CloseEvent (TerminalDevice
->SimpleInput
.WaitForKey
);
1396 gBS
->CloseEvent (TerminalDevice
->SimpleInputEx
.WaitForKeyEx
);
1397 TerminalFreeNotifyList (&TerminalDevice
->NotifyList
);
1398 FreePool (TerminalDevice
->DevicePath
);
1399 if (TerminalDevice
->TerminalConsoleModeData
!= NULL
) {
1400 FreePool (TerminalDevice
->TerminalConsoleModeData
);
1402 FreePool (TerminalDevice
);
1406 if (EFI_ERROR (Status
)) {
1407 AllChildrenStopped
= FALSE
;
1411 if (!AllChildrenStopped
) {
1412 return EFI_DEVICE_ERROR
;
1419 Update terminal device path in Console Device Environment Variables.
1421 @param VariableName The Console Device Environment Variable.
1422 @param ParentDevicePath The terminal device path to be updated.
1426 TerminalUpdateConsoleDevVariable (
1427 IN CHAR16
*VariableName
,
1428 IN EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
1434 EFI_DEVICE_PATH_PROTOCOL
*Variable
;
1435 EFI_DEVICE_PATH_PROTOCOL
*NewVariable
;
1436 EFI_DEVICE_PATH_PROTOCOL
*TempDevicePath
;
1439 // Get global variable and its size according to the name given.
1441 Variable
= GetEfiGlobalVariable (VariableName
);
1442 if (Variable
== NULL
) {
1447 // Append terminal device path onto the variable.
1449 for (TerminalType
= PCANSITYPE
; TerminalType
<= VTUTF8TYPE
; TerminalType
++) {
1450 SetTerminalDevicePath (TerminalType
, ParentDevicePath
, &TempDevicePath
);
1451 NewVariable
= AppendDevicePathInstance (Variable
, TempDevicePath
);
1452 if (Variable
!= NULL
) {
1453 FreePool (Variable
);
1456 if (TempDevicePath
!= NULL
) {
1457 FreePool (TempDevicePath
);
1460 Variable
= NewVariable
;
1463 VariableSize
= GetDevicePathSize (Variable
);
1465 Status
= gRT
->SetVariable (
1467 &gEfiGlobalVariableGuid
,
1468 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
,
1472 ASSERT_EFI_ERROR (Status
);
1473 FreePool (Variable
);
1480 Remove terminal device path from Console Device Environment Variables.
1482 @param VariableName Console Device Environment Variables.
1483 @param ParentDevicePath The terminal device path to be updated.
1487 TerminalRemoveConsoleDevVariable (
1488 IN CHAR16
*VariableName
,
1489 IN EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
1498 EFI_DEVICE_PATH_PROTOCOL
*Instance
;
1499 EFI_DEVICE_PATH_PROTOCOL
*Variable
;
1500 EFI_DEVICE_PATH_PROTOCOL
*OriginalVariable
;
1501 EFI_DEVICE_PATH_PROTOCOL
*NewVariable
;
1502 EFI_DEVICE_PATH_PROTOCOL
*SavedNewVariable
;
1503 EFI_DEVICE_PATH_PROTOCOL
*TempDevicePath
;
1508 // Get global variable and its size according to the name given.
1510 Variable
= GetEfiGlobalVariable (VariableName
);
1511 if (Variable
== NULL
) {
1516 OriginalVariable
= Variable
;
1520 // Get first device path instance from Variable
1522 Instance
= GetNextDevicePathInstance (&Variable
, &InstanceSize
);
1523 if (Instance
== NULL
) {
1524 FreePool (OriginalVariable
);
1528 // Loop through all the device path instances of Variable
1532 // Loop through all the terminal types that this driver supports
1535 for (TerminalType
= PCANSITYPE
; TerminalType
<= VTUTF8TYPE
; TerminalType
++) {
1537 SetTerminalDevicePath (TerminalType
, ParentDevicePath
, &TempDevicePath
);
1540 // Compare the generated device path to the current device path instance
1542 if (TempDevicePath
!= NULL
) {
1543 if (CompareMem (Instance
, TempDevicePath
, InstanceSize
) == 0) {
1548 FreePool (TempDevicePath
);
1552 // If a match was not found, then keep the current device path instance
1555 SavedNewVariable
= NewVariable
;
1556 NewVariable
= AppendDevicePathInstance (NewVariable
, Instance
);
1557 if (SavedNewVariable
!= NULL
) {
1558 FreePool (SavedNewVariable
);
1562 // Get next device path instance from Variable
1564 FreePool (Instance
);
1565 Instance
= GetNextDevicePathInstance (&Variable
, &InstanceSize
);
1566 } while (Instance
!= NULL
);
1568 FreePool (OriginalVariable
);
1571 VariableSize
= GetDevicePathSize (NewVariable
);
1573 Status
= gRT
->SetVariable (
1575 &gEfiGlobalVariableGuid
,
1576 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
,
1580 ASSERT_EFI_ERROR (Status
);
1583 if (NewVariable
!= NULL
) {
1584 FreePool (NewVariable
);
1591 Build terminal device path according to terminal type.
1593 @param TerminalType The terminal type is PC ANSI, VT100, VT100+ or VT-UTF8.
1594 @param ParentDevicePath Parent device path.
1595 @param TerminalDevicePath Returned terminal device path, if building successfully.
1597 @retval EFI_UNSUPPORTED Terminal does not belong to the supported type.
1598 @retval EFI_OUT_OF_RESOURCES Generate terminal device path failed.
1599 @retval EFI_SUCCESS Build terminal device path successfully.
1603 SetTerminalDevicePath (
1604 IN UINT8 TerminalType
,
1605 IN EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
,
1606 OUT EFI_DEVICE_PATH_PROTOCOL
**TerminalDevicePath
1609 VENDOR_DEVICE_PATH Node
;
1611 *TerminalDevicePath
= NULL
;
1612 Node
.Header
.Type
= MESSAGING_DEVICE_PATH
;
1613 Node
.Header
.SubType
= MSG_VENDOR_DP
;
1616 // Generate terminal device path node according to terminal type.
1618 switch (TerminalType
) {
1621 CopyGuid (&Node
.Guid
, &gEfiPcAnsiGuid
);
1625 CopyGuid (&Node
.Guid
, &gEfiVT100Guid
);
1629 CopyGuid (&Node
.Guid
, &gEfiVT100PlusGuid
);
1633 CopyGuid (&Node
.Guid
, &gEfiVTUTF8Guid
);
1637 return EFI_UNSUPPORTED
;
1641 // Get VENDOR_DEVCIE_PATH size and put into Node.Header
1643 SetDevicePathNodeLength (
1645 sizeof (VENDOR_DEVICE_PATH
)
1649 // Append the terminal node onto parent device path
1650 // to generate a complete terminal device path.
1652 *TerminalDevicePath
= AppendDevicePathNode (
1654 (EFI_DEVICE_PATH_PROTOCOL
*) &Node
1656 if (*TerminalDevicePath
== NULL
) {
1657 return EFI_OUT_OF_RESOURCES
;
1664 The user Entry Point for module Terminal. The user code starts with this function.
1666 @param ImageHandle The firmware allocated handle for the EFI image.
1667 @param SystemTable A pointer to the EFI System Table.
1669 @retval EFI_SUCCESS The entry point is executed successfully.
1670 @retval other Some error occurs when executing this entry point.
1676 IN EFI_HANDLE ImageHandle
,
1677 IN EFI_SYSTEM_TABLE
*SystemTable
1683 // Install driver model protocol(s).
1685 Status
= EfiLibInstallDriverBindingComponentName2 (
1688 &gTerminalDriverBinding
,
1690 &gTerminalComponentName
,
1691 &gTerminalComponentName2
1693 ASSERT_EFI_ERROR (Status
);
1699 Check if the device supports hot-plug through its device path.
1701 This function could be updated to check more types of Hot Plug devices.
1702 Currently, it checks USB and PCCard device.
1704 @param DevicePath Pointer to device's device path.
1706 @retval TRUE The devcie is a hot-plug device
1707 @retval FALSE The devcie is not a hot-plug device.
1712 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
1715 EFI_DEVICE_PATH_PROTOCOL
*CheckDevicePath
;
1717 CheckDevicePath
= DevicePath
;
1718 while (!IsDevicePathEnd (CheckDevicePath
)) {
1720 // Check device whether is hot plug device or not throught Device Path
1722 if ((DevicePathType (CheckDevicePath
) == MESSAGING_DEVICE_PATH
) &&
1723 (DevicePathSubType (CheckDevicePath
) == MSG_USB_DP
||
1724 DevicePathSubType (CheckDevicePath
) == MSG_USB_CLASS_DP
||
1725 DevicePathSubType (CheckDevicePath
) == MSG_USB_WWID_DP
)) {
1727 // If Device is USB device
1731 if ((DevicePathType (CheckDevicePath
) == HARDWARE_DEVICE_PATH
) &&
1732 (DevicePathSubType (CheckDevicePath
) == HW_PCCARD_DP
)) {
1734 // If Device is PCCard
1739 CheckDevicePath
= NextDevicePathNode (CheckDevicePath
);