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 - 2017, 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
*mTerminalType
[] = {
41 CHAR16
*mSerialConsoleNames
[] = {
42 L
"PC-ANSI Serial Console",
43 L
"VT-100 Serial Console",
44 L
"VT-100+ Serial Console",
45 L
"VT-UTF8 Serial Console",
46 L
"Tty Terminal Serial Console"
49 TERMINAL_DEV mTerminalDevTemplate
= {
50 TERMINAL_DEV_SIGNATURE
,
57 TerminalConInReadKeyStroke
,
62 TerminalConOutOutputString
,
63 TerminalConOutTestString
,
64 TerminalConOutQueryMode
,
65 TerminalConOutSetMode
,
66 TerminalConOutSetAttribute
,
67 TerminalConOutClearScreen
,
68 TerminalConOutSetCursorPosition
,
69 TerminalConOutEnableCursor
,
72 { // SimpleTextOutputMode
75 EFI_TEXT_ATTR (EFI_LIGHTGRAY
, EFI_BLACK
), // Attribute
80 NULL
, // TerminalConsoleModeData
86 NULL
, // EfiKeyFiFoForNotify
88 NULL
, // ControllerNameTable
90 NULL
, // TwoSecondTimeOut
100 { // SimpleTextInputEx
101 TerminalConInResetEx
,
102 TerminalConInReadKeyStrokeEx
,
104 TerminalConInSetState
,
105 TerminalConInRegisterKeyNotify
,
106 TerminalConInUnregisterKeyNotify
,
112 NULL
// KeyNotifyProcessEvent
115 TERMINAL_CONSOLE_MODE_DATA mTerminalConsoleModeData
[] = {
120 // New modes can be added here.
125 Convert the GUID representation of terminal type to enum type.
127 @param Guid The GUID representation of terminal type.
129 @return The terminal type in enum type.
132 TerminalTypeFromGuid (
138 for (Type
= 0; Type
< ARRAY_SIZE (mTerminalType
); Type
++) {
139 if (CompareGuid (Guid
, mTerminalType
[Type
])) {
147 Test to see if this driver supports Controller.
149 @param This Protocol instance pointer.
150 @param Controller Handle of device to test
151 @param RemainingDevicePath Optional parameter use to pick a specific child
154 @retval EFI_SUCCESS This driver supports this device.
155 @retval EFI_ALREADY_STARTED This driver is already running on this device.
156 @retval other This driver does not support this device.
161 TerminalDriverBindingSupported (
162 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
163 IN EFI_HANDLE Controller
,
164 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
168 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
169 EFI_SERIAL_IO_PROTOCOL
*SerialIo
;
170 VENDOR_DEVICE_PATH
*Node
;
173 // If remaining device path is not NULL, then make sure it is a
174 // device path that describes a terminal communications protocol.
176 if (RemainingDevicePath
!= NULL
) {
178 // Check if RemainingDevicePath is the End of Device Path Node,
179 // if yes, go on checking other conditions
181 if (!IsDevicePathEnd (RemainingDevicePath
)) {
183 // If RemainingDevicePath isn't the End of Device Path Node,
184 // check its validation
186 Node
= (VENDOR_DEVICE_PATH
*) RemainingDevicePath
;
188 if (Node
->Header
.Type
!= MESSAGING_DEVICE_PATH
||
189 Node
->Header
.SubType
!= MSG_VENDOR_DP
||
190 DevicePathNodeLength(&Node
->Header
) != sizeof(VENDOR_DEVICE_PATH
)) {
192 return EFI_UNSUPPORTED
;
196 // only supports PC ANSI, VT100, VT100+, VT-UTF8, and TtyTerm terminal types
198 if (TerminalTypeFromGuid (&Node
->Guid
) == ARRAY_SIZE (mTerminalType
)) {
199 return EFI_UNSUPPORTED
;
204 // Open the IO Abstraction(s) needed to perform the supported test
205 // The Controller must support the Serial I/O Protocol.
206 // This driver is a bus driver with at most 1 child device, so it is
207 // ok for it to be already started.
209 Status
= gBS
->OpenProtocol (
211 &gEfiSerialIoProtocolGuid
,
213 This
->DriverBindingHandle
,
215 EFI_OPEN_PROTOCOL_BY_DRIVER
217 if (Status
== EFI_ALREADY_STARTED
) {
221 if (EFI_ERROR (Status
)) {
226 // Close the I/O Abstraction(s) used to perform the supported test
230 &gEfiSerialIoProtocolGuid
,
231 This
->DriverBindingHandle
,
236 // Open the EFI Device Path protocol needed to perform the supported test
238 Status
= gBS
->OpenProtocol (
240 &gEfiDevicePathProtocolGuid
,
241 (VOID
**) &ParentDevicePath
,
242 This
->DriverBindingHandle
,
244 EFI_OPEN_PROTOCOL_BY_DRIVER
246 if (Status
== EFI_ALREADY_STARTED
) {
250 if (EFI_ERROR (Status
)) {
255 // Close protocol, don't use device path protocol in the Support() function
259 &gEfiDevicePathProtocolGuid
,
260 This
->DriverBindingHandle
,
268 Build the terminal device path for the child device according to the
271 @param ParentDevicePath Parent device path.
272 @param RemainingDevicePath A specific child device.
274 @return The child device path built.
277 EFI_DEVICE_PATH_PROTOCOL
*
279 BuildTerminalDevpath (
280 IN EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
,
281 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
284 EFI_DEVICE_PATH_PROTOCOL
*TerminalDevicePath
;
285 TERMINAL_TYPE TerminalType
;
286 VENDOR_DEVICE_PATH
*Node
;
289 TerminalDevicePath
= NULL
;
292 // Use the RemainingDevicePath to determine the terminal type
294 Node
= (VENDOR_DEVICE_PATH
*) RemainingDevicePath
;
296 TerminalType
= PcdGet8 (PcdDefaultTerminalType
);
298 } else if (CompareGuid (&Node
->Guid
, &gEfiPcAnsiGuid
)) {
300 TerminalType
= TerminalTypePcAnsi
;
302 } else if (CompareGuid (&Node
->Guid
, &gEfiVT100Guid
)) {
304 TerminalType
= TerminalTypeVt100
;
306 } else if (CompareGuid (&Node
->Guid
, &gEfiVT100PlusGuid
)) {
308 TerminalType
= TerminalTypeVt100Plus
;
310 } else if (CompareGuid (&Node
->Guid
, &gEfiVTUTF8Guid
)) {
312 TerminalType
= TerminalTypeVtUtf8
;
314 } else if (CompareGuid (&Node
->Guid
, &gEfiTtyTermGuid
)) {
316 TerminalType
= TerminalTypeTtyTerm
;
323 // Build the device path for the child device
325 Status
= SetTerminalDevicePath (
330 if (EFI_ERROR (Status
)) {
333 return TerminalDevicePath
;
337 Compare a device path data structure to that of all the nodes of a
338 second device path instance.
340 @param Multi A pointer to a multi-instance device path data structure.
341 @param Single A pointer to a single-instance device path data structure.
343 @retval TRUE If the Single is contained within Multi.
344 @retval FALSE The Single is not match within Multi.
349 IN EFI_DEVICE_PATH_PROTOCOL
*Multi
,
350 IN EFI_DEVICE_PATH_PROTOCOL
*Single
353 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
354 EFI_DEVICE_PATH_PROTOCOL
*DevicePathInst
;
358 DevicePathInst
= GetNextDevicePathInstance (&DevicePath
, &Size
);
360 // Search for the match of 'Single' in 'Multi'
362 while (DevicePathInst
!= NULL
) {
364 // If the single device path is found in multiple device paths,
367 if (CompareMem (Single
, DevicePathInst
, Size
) == 0) {
368 FreePool (DevicePathInst
);
372 FreePool (DevicePathInst
);
373 DevicePathInst
= GetNextDevicePathInstance (&DevicePath
, &Size
);
380 Check whether the terminal device path is in the global variable.
382 @param VariableName Pointer to one global variable.
383 @param TerminalDevicePath Pointer to the terminal device's device path.
385 @retval TRUE The devcie is in the global variable.
386 @retval FALSE The devcie is not in the global variable.
390 IsTerminalInConsoleVariable (
391 IN CHAR16
*VariableName
,
392 IN EFI_DEVICE_PATH_PROTOCOL
*TerminalDevicePath
395 EFI_DEVICE_PATH_PROTOCOL
*Variable
;
399 // Get global variable and its size according to the name given.
401 GetEfiGlobalVariable2 (VariableName
, (VOID
**)&Variable
, NULL
);
402 if (Variable
== NULL
) {
407 // Check whether the terminal device path is one of the variable instances.
409 ReturnFlag
= MatchDevicePaths (Variable
, TerminalDevicePath
);
417 Free notify functions list.
419 @param ListHead The list head
421 @retval EFI_SUCCESS Free the notify list successfully.
422 @retval EFI_INVALID_PARAMETER ListHead is NULL.
426 TerminalFreeNotifyList (
427 IN OUT LIST_ENTRY
*ListHead
430 TERMINAL_CONSOLE_IN_EX_NOTIFY
*NotifyNode
;
432 if (ListHead
== NULL
) {
433 return EFI_INVALID_PARAMETER
;
435 while (!IsListEmpty (ListHead
)) {
437 ListHead
->ForwardLink
,
438 TERMINAL_CONSOLE_IN_EX_NOTIFY
,
440 TERMINAL_CONSOLE_IN_EX_NOTIFY_SIGNATURE
442 RemoveEntryList (ListHead
->ForwardLink
);
443 FreePool (NotifyNode
);
450 Initialize all the text modes which the terminal console supports.
452 It returns information for available text modes that the terminal can support.
454 @param[out] TextModeCount The total number of text modes that terminal console supports.
456 @return The buffer to the text modes column and row information.
457 Caller is responsible to free it when it's non-NULL.
460 TERMINAL_CONSOLE_MODE_DATA
*
461 InitializeTerminalConsoleTextMode (
462 OUT INT32
*TextModeCount
465 TERMINAL_CONSOLE_MODE_DATA
*TextModeData
;
467 ASSERT (TextModeCount
!= NULL
);
470 // Here we make sure that the final mode exposed does not include the duplicated modes,
471 // and does not include the invalid modes which exceed the max column and row.
472 // Reserve 2 modes for 80x25, 80x50 of terminal console.
474 TextModeData
= AllocateCopyPool (sizeof (mTerminalConsoleModeData
), mTerminalConsoleModeData
);
475 if (TextModeData
== NULL
) {
478 *TextModeCount
= ARRAY_SIZE (mTerminalConsoleModeData
);
482 for (Index
= 0; Index
< *TextModeCount
; Index
++) {
483 DEBUG ((DEBUG_INFO
, "Terminal - Mode %d, Column = %d, Row = %d\n",
484 Index
, TextModeData
[Index
].Columns
, TextModeData
[Index
].Rows
));
491 Stop the terminal state machine.
493 @param TerminalDevice The terminal device.
496 StopTerminalStateMachine (
497 TERMINAL_DEV
*TerminalDevice
502 OriginalTpl
= gBS
->RaiseTPL (TPL_NOTIFY
);
504 gBS
->CloseEvent (TerminalDevice
->TimerEvent
);
505 gBS
->CloseEvent (TerminalDevice
->TwoSecondTimeOut
);
507 gBS
->RestoreTPL (OriginalTpl
);
511 Start the terminal state machine.
513 @param TerminalDevice The terminal device.
516 StartTerminalStateMachine (
517 TERMINAL_DEV
*TerminalDevice
521 Status
= gBS
->CreateEvent (
522 EVT_TIMER
| EVT_NOTIFY_SIGNAL
,
524 TerminalConInTimerHandler
,
526 &TerminalDevice
->TimerEvent
528 ASSERT_EFI_ERROR (Status
);
530 Status
= gBS
->SetTimer (
531 TerminalDevice
->TimerEvent
,
533 KEYBOARD_TIMER_INTERVAL
535 ASSERT_EFI_ERROR (Status
);
537 Status
= gBS
->CreateEvent (
542 &TerminalDevice
->TwoSecondTimeOut
544 ASSERT_EFI_ERROR (Status
);
548 Initialize the controller name table.
550 @param TerminalType The terminal type.
551 @param ControllerNameTable The controller name table.
553 @retval EFI_SUCCESS The controller name table is initialized successfully.
554 @retval others Return status of AddUnicodeString2 ().
557 InitializeControllerNameTable (
558 TERMINAL_TYPE TerminalType
,
559 EFI_UNICODE_STRING_TABLE
**ControllerNameTable
563 EFI_UNICODE_STRING_TABLE
*Table
;
565 ASSERT (TerminalType
< ARRAY_SIZE (mTerminalType
));
567 Status
= AddUnicodeString2 (
569 gTerminalComponentName
.SupportedLanguages
,
571 mSerialConsoleNames
[TerminalType
],
574 if (!EFI_ERROR (Status
)) {
575 Status
= AddUnicodeString2 (
577 gTerminalComponentName2
.SupportedLanguages
,
579 mSerialConsoleNames
[TerminalType
],
582 if (EFI_ERROR (Status
)) {
583 FreeUnicodeStringTable (Table
);
586 if (!EFI_ERROR (Status
)) {
587 *ControllerNameTable
= Table
;
593 Start this driver on Controller by opening a Serial IO protocol,
594 reading Device Path, and creating a child handle with a Simple Text In,
595 Simple Text In Ex and Simple Text Out protocol, and device path protocol.
596 And store Console Device Environment Variables.
598 @param This Protocol instance pointer.
599 @param Controller Handle of device to bind driver to
600 @param RemainingDevicePath Optional parameter use to pick a specific child
603 @retval EFI_SUCCESS This driver is added to Controller.
604 @retval EFI_ALREADY_STARTED This driver is already running on Controller.
605 @retval other This driver does not support this device.
610 TerminalDriverBindingStart (
611 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
612 IN EFI_HANDLE Controller
,
613 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
617 EFI_SERIAL_IO_PROTOCOL
*SerialIo
;
618 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
619 VENDOR_DEVICE_PATH
*Node
;
620 EFI_SERIAL_IO_MODE
*Mode
;
621 UINTN SerialInTimeOut
;
622 TERMINAL_DEV
*TerminalDevice
;
623 TERMINAL_TYPE TerminalType
;
624 EFI_OPEN_PROTOCOL_INFORMATION_ENTRY
*OpenInfoBuffer
;
627 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
628 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*SimpleTextOutput
;
629 EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*SimpleTextInput
;
630 BOOLEAN ConInSelected
;
631 BOOLEAN ConOutSelected
;
632 BOOLEAN NullRemaining
;
633 BOOLEAN SimTxtInInstalled
;
634 BOOLEAN SimTxtOutInstalled
;
637 TerminalDevice
= NULL
;
638 ConInSelected
= FALSE
;
639 ConOutSelected
= FALSE
;
640 NullRemaining
= FALSE
;
641 SimTxtInInstalled
= FALSE
;
642 SimTxtOutInstalled
= FALSE
;
645 // Get the Device Path Protocol to build the device path of the child device
647 Status
= gBS
->OpenProtocol (
649 &gEfiDevicePathProtocolGuid
,
650 (VOID
**) &ParentDevicePath
,
651 This
->DriverBindingHandle
,
653 EFI_OPEN_PROTOCOL_BY_DRIVER
655 if (EFI_ERROR (Status
) && Status
!= EFI_ALREADY_STARTED
) {
660 // Open the Serial I/O Protocol BY_DRIVER. It might already be started.
662 Status
= gBS
->OpenProtocol (
664 &gEfiSerialIoProtocolGuid
,
666 This
->DriverBindingHandle
,
668 EFI_OPEN_PROTOCOL_BY_DRIVER
670 if (EFI_ERROR (Status
) && Status
!= EFI_ALREADY_STARTED
) {
674 if (Status
!= EFI_ALREADY_STARTED
) {
676 // the serial I/O protocol never be opened before, it is the first
677 // time to start the serial Io controller
683 // Serial I/O is not already open by this driver, then tag the handle
684 // with the Terminal Driver GUID and update the ConInDev, ConOutDev, and
685 // StdErrDev variables with the list of possible terminal types on this
688 Status
= gBS
->OpenProtocol (
692 This
->DriverBindingHandle
,
694 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
696 if (EFI_ERROR (Status
)) {
697 Status
= gBS
->InstallMultipleProtocolInterfaces (
700 DuplicateDevicePath (ParentDevicePath
),
703 if (EFI_ERROR (Status
)) {
707 if (!IsHotPlugDevice (ParentDevicePath
)) {
709 // if the serial device is a hot plug device, do not update the
710 // ConInDev, ConOutDev, and StdErrDev variables.
712 TerminalUpdateConsoleDevVariable (L
"ConInDev", ParentDevicePath
);
713 TerminalUpdateConsoleDevVariable (L
"ConOutDev", ParentDevicePath
);
714 TerminalUpdateConsoleDevVariable (L
"ErrOutDev", ParentDevicePath
);
719 // Check the requirement for the SimpleTxtIn and SimpleTxtOut protocols
721 // Simple In/Out Protocol will not be installed onto the handle if the
722 // device path to the handle is not present in the ConIn/ConOut
723 // environment variable. But If RemainingDevicePath is NULL, then always
724 // produce both Simple In and Simple Text Output Protocols. This is required
725 // for the connect all sequences to make sure all possible consoles are
726 // produced no matter what the current values of ConIn, ConOut, or StdErr are.
728 if (RemainingDevicePath
== NULL
) {
729 NullRemaining
= TRUE
;
732 DevicePath
= BuildTerminalDevpath (ParentDevicePath
, RemainingDevicePath
);
733 if (DevicePath
!= NULL
) {
734 ConInSelected
= IsTerminalInConsoleVariable (L
"ConIn", DevicePath
);
735 ConOutSelected
= IsTerminalInConsoleVariable (L
"ConOut", DevicePath
);
736 FreePool (DevicePath
);
741 // Not create the child terminal handle if both Simple In/In Ex and
742 // Simple text Out protocols are not required to be published
744 if ((!ConInSelected
)&&(!ConOutSelected
)&&(!NullRemaining
)) {
749 // create the child terminal handle during first entry
753 // First enther the start function
757 // Make sure a child handle does not already exist. This driver can only
758 // produce one child per serial port.
760 Status
= gBS
->OpenProtocolInformation (
762 &gEfiSerialIoProtocolGuid
,
766 if (!EFI_ERROR (Status
)) {
767 Status
= EFI_SUCCESS
;
768 for (Index
= 0; Index
< EntryCount
; Index
++) {
769 if ((OpenInfoBuffer
[Index
].Attributes
& EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
) != 0) {
770 Status
= EFI_ALREADY_STARTED
;
774 FreePool (OpenInfoBuffer
);
775 if (EFI_ERROR (Status
)) {
781 // If RemainingDevicePath is NULL, use default terminal type
783 if (RemainingDevicePath
== NULL
) {
784 TerminalType
= PcdGet8 (PcdDefaultTerminalType
);
785 } else if (!IsDevicePathEnd (RemainingDevicePath
)) {
787 // If RemainingDevicePath isn't the End of Device Path Node,
788 // Use the RemainingDevicePath to determine the terminal type
790 Node
= (VENDOR_DEVICE_PATH
*)RemainingDevicePath
;
791 TerminalType
= TerminalTypeFromGuid (&Node
->Guid
);
794 // If RemainingDevicePath is the End of Device Path Node,
795 // skip enumerate any device and return EFI_SUCESSS
800 ASSERT (TerminalType
< ARRAY_SIZE (mTerminalType
));
803 // Initialize the Terminal Dev
805 TerminalDevice
= AllocateCopyPool (sizeof (TERMINAL_DEV
), &mTerminalDevTemplate
);
806 if (TerminalDevice
== NULL
) {
807 Status
= EFI_OUT_OF_RESOURCES
;
811 TerminalDevice
->TerminalType
= TerminalType
;
812 TerminalDevice
->SerialIo
= SerialIo
;
814 InitializeListHead (&TerminalDevice
->NotifyList
);
815 Status
= gBS
->CreateEvent (
818 TerminalConInWaitForKeyEx
,
820 &TerminalDevice
->SimpleInputEx
.WaitForKeyEx
822 if (EFI_ERROR (Status
)) {
826 Status
= gBS
->CreateEvent (
829 TerminalConInWaitForKey
,
831 &TerminalDevice
->SimpleInput
.WaitForKey
833 if (EFI_ERROR (Status
)) {
837 // Allocates and initializes the FIFO buffer to be zero, used for accommodating
838 // the pre-read pending characters.
840 TerminalDevice
->RawFiFo
= AllocateZeroPool (sizeof (RAW_DATA_FIFO
));
841 if (TerminalDevice
->RawFiFo
== NULL
) {
844 TerminalDevice
->UnicodeFiFo
= AllocateZeroPool (sizeof (UNICODE_FIFO
));
845 if (TerminalDevice
->UnicodeFiFo
== NULL
) {
848 TerminalDevice
->EfiKeyFiFo
= AllocateZeroPool (sizeof (EFI_KEY_FIFO
));
849 if (TerminalDevice
->EfiKeyFiFo
== NULL
) {
852 TerminalDevice
->EfiKeyFiFoForNotify
= AllocateZeroPool (sizeof (EFI_KEY_FIFO
));
853 if (TerminalDevice
->EfiKeyFiFoForNotify
== NULL
) {
858 // Set the timeout value of serial buffer for
859 // keystroke response performance issue
861 Mode
= TerminalDevice
->SerialIo
->Mode
;
864 if (Mode
->BaudRate
!= 0) {
865 SerialInTimeOut
= (1 + Mode
->DataBits
+ Mode
->StopBits
) * 2 * 1000000 / (UINTN
) Mode
->BaudRate
;
868 Status
= TerminalDevice
->SerialIo
->SetAttributes (
869 TerminalDevice
->SerialIo
,
871 Mode
->ReceiveFifoDepth
,
872 (UINT32
) SerialInTimeOut
,
873 (EFI_PARITY_TYPE
) (Mode
->Parity
),
874 (UINT8
) Mode
->DataBits
,
875 (EFI_STOP_BITS_TYPE
) (Mode
->StopBits
)
877 if (EFI_ERROR (Status
)) {
879 // if set attributes operation fails, invalidate
880 // the value of SerialInTimeOut,thus make it
881 // inconsistent with the default timeout value
882 // of serial buffer. This will invoke the recalculation
883 // in the readkeystroke routine.
885 TerminalDevice
->SerialInTimeOut
= 0;
887 TerminalDevice
->SerialInTimeOut
= SerialInTimeOut
;
890 // Set Simple Text Output Protocol from template.
892 SimpleTextOutput
= CopyMem (
893 &TerminalDevice
->SimpleTextOutput
,
894 &mTerminalDevTemplate
.SimpleTextOutput
,
895 sizeof (mTerminalDevTemplate
.SimpleTextOutput
)
897 SimpleTextOutput
->Mode
= &TerminalDevice
->SimpleTextOutputMode
;
899 TerminalDevice
->TerminalConsoleModeData
= InitializeTerminalConsoleTextMode (
900 &SimpleTextOutput
->Mode
->MaxMode
902 if (TerminalDevice
->TerminalConsoleModeData
== NULL
) {
907 // For terminal devices, cursor is always visible
909 TerminalDevice
->SimpleTextOutputMode
.CursorVisible
= TRUE
;
910 Status
= TerminalConOutSetAttribute (
912 EFI_TEXT_ATTR (EFI_LIGHTGRAY
, EFI_BLACK
)
914 if (EFI_ERROR (Status
)) {
919 // Build the component name for the child device
921 Status
= InitializeControllerNameTable (TerminalDevice
->TerminalType
, &TerminalDevice
->ControllerNameTable
);
922 if (EFI_ERROR (Status
)) {
927 // Build the device path for the child device
929 Status
= SetTerminalDevicePath (
930 TerminalDevice
->TerminalType
,
932 &TerminalDevice
->DevicePath
934 if (EFI_ERROR (Status
)) {
938 Status
= TerminalConOutReset (SimpleTextOutput
, FALSE
);
939 if (EFI_ERROR (Status
)) {
943 Status
= TerminalConOutSetMode (SimpleTextOutput
, 0);
944 if (EFI_ERROR (Status
)) {
948 Status
= TerminalConOutEnableCursor (SimpleTextOutput
, TRUE
);
949 if (EFI_ERROR (Status
)) {
953 StartTerminalStateMachine (TerminalDevice
);
955 Status
= gBS
->CreateEvent (
958 KeyNotifyProcessHandler
,
960 &TerminalDevice
->KeyNotifyProcessEvent
962 ASSERT_EFI_ERROR (Status
);
964 Status
= gBS
->InstallProtocolInterface (
965 &TerminalDevice
->Handle
,
966 &gEfiDevicePathProtocolGuid
,
967 EFI_NATIVE_INTERFACE
,
968 TerminalDevice
->DevicePath
970 if (EFI_ERROR (Status
)) {
975 // Register the Parent-Child relationship via
976 // EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.
978 Status
= gBS
->OpenProtocol (
980 &gEfiSerialIoProtocolGuid
,
981 (VOID
**) &TerminalDevice
->SerialIo
,
982 This
->DriverBindingHandle
,
983 TerminalDevice
->Handle
,
984 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
986 if (EFI_ERROR (Status
)) {
992 // Find the child handle, and get its TerminalDevice private data
994 Status
= gBS
->OpenProtocolInformation (
996 &gEfiSerialIoProtocolGuid
,
1000 if (!EFI_ERROR (Status
)) {
1001 Status
= EFI_NOT_FOUND
;
1002 ASSERT (OpenInfoBuffer
!= NULL
);
1003 for (Index
= 0; Index
< EntryCount
; Index
++) {
1004 if ((OpenInfoBuffer
[Index
].Attributes
& EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
) != 0) {
1006 // Find the child terminal handle.
1007 // Test whether the SimpleTxtIn and SimpleTxtOut have been published
1009 Status
= gBS
->OpenProtocol (
1010 OpenInfoBuffer
[Index
].ControllerHandle
,
1011 &gEfiSimpleTextInProtocolGuid
,
1012 (VOID
**) &SimpleTextInput
,
1013 This
->DriverBindingHandle
,
1014 OpenInfoBuffer
[Index
].ControllerHandle
,
1015 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1017 if (!EFI_ERROR (Status
)) {
1018 SimTxtInInstalled
= TRUE
;
1019 TerminalDevice
= TERMINAL_CON_IN_DEV_FROM_THIS (SimpleTextInput
);
1022 Status
= gBS
->OpenProtocol (
1023 OpenInfoBuffer
[Index
].ControllerHandle
,
1024 &gEfiSimpleTextOutProtocolGuid
,
1025 (VOID
**) &SimpleTextOutput
,
1026 This
->DriverBindingHandle
,
1027 OpenInfoBuffer
[Index
].ControllerHandle
,
1028 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1030 if (!EFI_ERROR (Status
)) {
1031 SimTxtOutInstalled
= TRUE
;
1032 TerminalDevice
= TERMINAL_CON_OUT_DEV_FROM_THIS (SimpleTextOutput
);
1034 Status
= EFI_SUCCESS
;
1039 FreePool (OpenInfoBuffer
);
1040 if (EFI_ERROR (Status
)) {
1047 ASSERT (TerminalDevice
!= NULL
);
1049 // Only do the reset if the device path is in the Conout variable
1051 if (ConInSelected
&& !SimTxtInInstalled
) {
1052 Status
= TerminalDevice
->SimpleInput
.Reset (
1053 &TerminalDevice
->SimpleInput
,
1056 if (EFI_ERROR (Status
)) {
1058 // Need to report Error Code first
1065 // Only output the configure string to remote terminal if the device path
1066 // is in the Conout variable
1068 if (ConOutSelected
&& !SimTxtOutInstalled
) {
1069 Status
= TerminalDevice
->SimpleTextOutput
.SetAttribute (
1070 &TerminalDevice
->SimpleTextOutput
,
1071 EFI_TEXT_ATTR (EFI_LIGHTGRAY
, EFI_BLACK
)
1073 if (EFI_ERROR (Status
)) {
1077 Status
= TerminalDevice
->SimpleTextOutput
.Reset (
1078 &TerminalDevice
->SimpleTextOutput
,
1081 if (EFI_ERROR (Status
)) {
1085 Status
= TerminalDevice
->SimpleTextOutput
.SetMode (
1086 &TerminalDevice
->SimpleTextOutput
,
1089 if (EFI_ERROR (Status
)) {
1093 Status
= TerminalDevice
->SimpleTextOutput
.EnableCursor (
1094 &TerminalDevice
->SimpleTextOutput
,
1097 if (EFI_ERROR (Status
)) {
1103 // Simple In/Out Protocol will not be installed onto the handle if the
1104 // device path to the handle is not present in the ConIn/ConOut
1105 // environment variable. But If RemainingDevicePath is NULL, then always
1106 // produce both Simple In and Simple Text Output Protocols. This is required
1107 // for the connect all sequences to make sure all possible consoles are
1108 // produced no matter what the current values of ConIn, ConOut, or StdErr are.
1110 if (!SimTxtInInstalled
&& (ConInSelected
|| NullRemaining
)) {
1111 Status
= gBS
->InstallMultipleProtocolInterfaces (
1112 &TerminalDevice
->Handle
,
1113 &gEfiSimpleTextInProtocolGuid
,
1114 &TerminalDevice
->SimpleInput
,
1115 &gEfiSimpleTextInputExProtocolGuid
,
1116 &TerminalDevice
->SimpleInputEx
,
1119 if (EFI_ERROR (Status
)) {
1124 if (!SimTxtOutInstalled
&& (ConOutSelected
|| NullRemaining
)) {
1125 Status
= gBS
->InstallProtocolInterface (
1126 &TerminalDevice
->Handle
,
1127 &gEfiSimpleTextOutProtocolGuid
,
1128 EFI_NATIVE_INTERFACE
,
1129 &TerminalDevice
->SimpleTextOutput
1131 if (EFI_ERROR (Status
)) {
1140 // Report error code before exiting
1142 DevicePath
= ParentDevicePath
;
1143 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
1144 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
1145 (EFI_PERIPHERAL_REMOTE_CONSOLE
| EFI_P_EC_CONTROLLER_ERROR
),
1151 // Use the Stop() function to free all resources allocated in Start()
1153 if (TerminalDevice
!= NULL
) {
1155 if (TerminalDevice
->Handle
!= NULL
) {
1156 This
->Stop (This
, Controller
, 1, &TerminalDevice
->Handle
);
1159 if (TerminalDevice
->TwoSecondTimeOut
!= NULL
) {
1160 gBS
->CloseEvent (TerminalDevice
->TwoSecondTimeOut
);
1163 if (TerminalDevice
->TimerEvent
!= NULL
) {
1164 gBS
->CloseEvent (TerminalDevice
->TimerEvent
);
1167 if (TerminalDevice
->SimpleInput
.WaitForKey
!= NULL
) {
1168 gBS
->CloseEvent (TerminalDevice
->SimpleInput
.WaitForKey
);
1171 if (TerminalDevice
->SimpleInputEx
.WaitForKeyEx
!= NULL
) {
1172 gBS
->CloseEvent (TerminalDevice
->SimpleInputEx
.WaitForKeyEx
);
1175 TerminalFreeNotifyList (&TerminalDevice
->NotifyList
);
1177 if (TerminalDevice
->RawFiFo
!= NULL
) {
1178 FreePool (TerminalDevice
->RawFiFo
);
1180 if (TerminalDevice
->UnicodeFiFo
!= NULL
) {
1181 FreePool (TerminalDevice
->UnicodeFiFo
);
1183 if (TerminalDevice
->EfiKeyFiFo
!= NULL
) {
1184 FreePool (TerminalDevice
->EfiKeyFiFo
);
1186 if (TerminalDevice
->EfiKeyFiFoForNotify
!= NULL
) {
1187 FreePool (TerminalDevice
->EfiKeyFiFoForNotify
);
1190 if (TerminalDevice
->ControllerNameTable
!= NULL
) {
1191 FreeUnicodeStringTable (TerminalDevice
->ControllerNameTable
);
1194 if (TerminalDevice
->DevicePath
!= NULL
) {
1195 FreePool (TerminalDevice
->DevicePath
);
1198 if (TerminalDevice
->TerminalConsoleModeData
!= NULL
) {
1199 FreePool (TerminalDevice
->TerminalConsoleModeData
);
1202 FreePool (TerminalDevice
);
1206 This
->Stop (This
, Controller
, 0, NULL
);
1212 Stop this driver on Controller by closing Simple Text In, Simple Text
1213 In Ex, Simple Text Out protocol, and removing parent device path from
1214 Console Device Environment Variables.
1216 @param This Protocol instance pointer.
1217 @param Controller Handle of device to stop driver on
1218 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
1219 children is zero stop the entire bus driver.
1220 @param ChildHandleBuffer List of Child Handles to Stop.
1222 @retval EFI_SUCCESS This driver is removed Controller.
1223 @retval other This driver could not be removed from this device.
1228 TerminalDriverBindingStop (
1229 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1230 IN EFI_HANDLE Controller
,
1231 IN UINTN NumberOfChildren
,
1232 IN EFI_HANDLE
*ChildHandleBuffer
1237 BOOLEAN AllChildrenStopped
;
1238 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
*SimpleTextOutput
;
1239 TERMINAL_DEV
*TerminalDevice
;
1240 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
1241 EFI_SERIAL_IO_PROTOCOL
*SerialIo
;
1242 EFI_DEVICE_PATH_PROTOCOL
*DevicePath
;
1244 Status
= gBS
->HandleProtocol (
1246 &gEfiDevicePathProtocolGuid
,
1247 (VOID
**) &DevicePath
1249 if (EFI_ERROR (Status
)) {
1254 // Complete all outstanding transactions to Controller.
1255 // Don't allow any new transaction to Controller to be started.
1257 if (NumberOfChildren
== 0) {
1259 // Close the bus driver
1261 Status
= gBS
->OpenProtocol (
1264 (VOID
**) &ParentDevicePath
,
1265 This
->DriverBindingHandle
,
1267 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1269 if (!EFI_ERROR (Status
)) {
1271 // Remove Parent Device Path from
1272 // the Console Device Environment Variables
1274 TerminalRemoveConsoleDevVariable (L
"ConInDev", ParentDevicePath
);
1275 TerminalRemoveConsoleDevVariable (L
"ConOutDev", ParentDevicePath
);
1276 TerminalRemoveConsoleDevVariable (L
"ErrOutDev", ParentDevicePath
);
1279 // Uninstall the Terminal Driver's GUID Tag from the Serial controller
1281 Status
= gBS
->UninstallMultipleProtocolInterfaces (
1289 // Free the ParentDevicePath that was duplicated in Start()
1291 if (!EFI_ERROR (Status
)) {
1292 FreePool (ParentDevicePath
);
1296 gBS
->CloseProtocol (
1298 &gEfiSerialIoProtocolGuid
,
1299 This
->DriverBindingHandle
,
1303 gBS
->CloseProtocol (
1305 &gEfiDevicePathProtocolGuid
,
1306 This
->DriverBindingHandle
,
1313 AllChildrenStopped
= TRUE
;
1315 for (Index
= 0; Index
< NumberOfChildren
; Index
++) {
1317 Status
= gBS
->OpenProtocol (
1318 ChildHandleBuffer
[Index
],
1319 &gEfiSimpleTextOutProtocolGuid
,
1320 (VOID
**) &SimpleTextOutput
,
1321 This
->DriverBindingHandle
,
1322 ChildHandleBuffer
[Index
],
1323 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1325 if (!EFI_ERROR (Status
)) {
1327 TerminalDevice
= TERMINAL_CON_OUT_DEV_FROM_THIS (SimpleTextOutput
);
1329 gBS
->CloseProtocol (
1331 &gEfiSerialIoProtocolGuid
,
1332 This
->DriverBindingHandle
,
1333 ChildHandleBuffer
[Index
]
1336 Status
= gBS
->UninstallMultipleProtocolInterfaces (
1337 ChildHandleBuffer
[Index
],
1338 &gEfiSimpleTextInProtocolGuid
,
1339 &TerminalDevice
->SimpleInput
,
1340 &gEfiSimpleTextInputExProtocolGuid
,
1341 &TerminalDevice
->SimpleInputEx
,
1342 &gEfiSimpleTextOutProtocolGuid
,
1343 &TerminalDevice
->SimpleTextOutput
,
1344 &gEfiDevicePathProtocolGuid
,
1345 TerminalDevice
->DevicePath
,
1348 if (EFI_ERROR (Status
)) {
1351 &gEfiSerialIoProtocolGuid
,
1352 (VOID
**) &SerialIo
,
1353 This
->DriverBindingHandle
,
1354 ChildHandleBuffer
[Index
],
1355 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
1359 FreeUnicodeStringTable (TerminalDevice
->ControllerNameTable
);
1360 StopTerminalStateMachine (TerminalDevice
);
1361 gBS
->CloseEvent (TerminalDevice
->SimpleInput
.WaitForKey
);
1362 gBS
->CloseEvent (TerminalDevice
->SimpleInputEx
.WaitForKeyEx
);
1363 gBS
->CloseEvent (TerminalDevice
->KeyNotifyProcessEvent
);
1364 TerminalFreeNotifyList (&TerminalDevice
->NotifyList
);
1365 FreePool (TerminalDevice
->DevicePath
);
1366 FreePool (TerminalDevice
->TerminalConsoleModeData
);
1367 FreePool (TerminalDevice
);
1371 if (EFI_ERROR (Status
)) {
1372 AllChildrenStopped
= FALSE
;
1376 if (!AllChildrenStopped
) {
1377 return EFI_DEVICE_ERROR
;
1384 Update terminal device path in Console Device Environment Variables.
1386 @param VariableName The Console Device Environment Variable.
1387 @param ParentDevicePath The terminal device path to be updated.
1391 TerminalUpdateConsoleDevVariable (
1392 IN CHAR16
*VariableName
,
1393 IN EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
1399 TERMINAL_TYPE TerminalType
;
1400 EFI_DEVICE_PATH_PROTOCOL
*Variable
;
1401 EFI_DEVICE_PATH_PROTOCOL
*NewVariable
;
1402 EFI_DEVICE_PATH_PROTOCOL
*TempDevicePath
;
1403 EDKII_SET_VARIABLE_STATUS
*SetVariableStatus
;
1406 // Get global variable and its size according to the name given.
1408 GetEfiGlobalVariable2 (VariableName
, (VOID
**)&Variable
, NULL
);
1409 if (Variable
== NULL
) {
1414 // Append terminal device path onto the variable.
1416 for (TerminalType
= 0; TerminalType
< ARRAY_SIZE (mTerminalType
); TerminalType
++) {
1417 SetTerminalDevicePath (TerminalType
, ParentDevicePath
, &TempDevicePath
);
1418 NewVariable
= AppendDevicePathInstance (Variable
, TempDevicePath
);
1419 ASSERT (NewVariable
!= NULL
);
1420 if (Variable
!= NULL
) {
1421 FreePool (Variable
);
1424 if (TempDevicePath
!= NULL
) {
1425 FreePool (TempDevicePath
);
1428 Variable
= NewVariable
;
1431 VariableSize
= GetDevicePathSize (Variable
);
1433 Status
= gRT
->SetVariable (
1435 &gEfiGlobalVariableGuid
,
1436 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
,
1441 if (EFI_ERROR (Status
)) {
1442 NameSize
= StrSize (VariableName
);
1443 SetVariableStatus
= AllocatePool (sizeof (EDKII_SET_VARIABLE_STATUS
) + NameSize
+ VariableSize
);
1444 if (SetVariableStatus
!= NULL
) {
1445 CopyGuid (&SetVariableStatus
->Guid
, &gEfiGlobalVariableGuid
);
1446 SetVariableStatus
->NameSize
= NameSize
;
1447 SetVariableStatus
->DataSize
= VariableSize
;
1448 SetVariableStatus
->SetStatus
= Status
;
1449 SetVariableStatus
->Attributes
= EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
;
1450 CopyMem (SetVariableStatus
+ 1, VariableName
, NameSize
);
1451 CopyMem (((UINT8
*) (SetVariableStatus
+ 1)) + NameSize
, Variable
, VariableSize
);
1453 REPORT_STATUS_CODE_EX (
1455 PcdGet32 (PcdErrorCodeSetVariable
),
1458 &gEdkiiStatusCodeDataTypeVariableGuid
,
1460 sizeof (EDKII_SET_VARIABLE_STATUS
) + NameSize
+ VariableSize
1463 FreePool (SetVariableStatus
);
1467 FreePool (Variable
);
1474 Remove terminal device path from Console Device Environment Variables.
1476 @param VariableName Console Device Environment Variables.
1477 @param ParentDevicePath The terminal device path to be updated.
1481 TerminalRemoveConsoleDevVariable (
1482 IN CHAR16
*VariableName
,
1483 IN EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
1491 TERMINAL_TYPE TerminalType
;
1492 EFI_DEVICE_PATH_PROTOCOL
*Instance
;
1493 EFI_DEVICE_PATH_PROTOCOL
*Variable
;
1494 EFI_DEVICE_PATH_PROTOCOL
*OriginalVariable
;
1495 EFI_DEVICE_PATH_PROTOCOL
*NewVariable
;
1496 EFI_DEVICE_PATH_PROTOCOL
*SavedNewVariable
;
1497 EFI_DEVICE_PATH_PROTOCOL
*TempDevicePath
;
1502 // Get global variable and its size according to the name given.
1504 GetEfiGlobalVariable2 (VariableName
, (VOID
**)&Variable
, NULL
);
1505 if (Variable
== NULL
) {
1510 OriginalVariable
= Variable
;
1514 // Get first device path instance from Variable
1516 Instance
= GetNextDevicePathInstance (&Variable
, &InstanceSize
);
1517 if (Instance
== NULL
) {
1518 FreePool (OriginalVariable
);
1522 // Loop through all the device path instances of Variable
1526 // Loop through all the terminal types that this driver supports
1529 for (TerminalType
= 0; TerminalType
< ARRAY_SIZE (mTerminalType
); TerminalType
++) {
1531 SetTerminalDevicePath (TerminalType
, ParentDevicePath
, &TempDevicePath
);
1534 // Compare the generated device path to the current device path instance
1536 if (TempDevicePath
!= NULL
) {
1537 if (CompareMem (Instance
, TempDevicePath
, InstanceSize
) == 0) {
1542 FreePool (TempDevicePath
);
1546 // If a match was not found, then keep the current device path instance
1549 SavedNewVariable
= NewVariable
;
1550 NewVariable
= AppendDevicePathInstance (NewVariable
, Instance
);
1551 if (SavedNewVariable
!= NULL
) {
1552 FreePool (SavedNewVariable
);
1556 // Get next device path instance from Variable
1558 FreePool (Instance
);
1559 Instance
= GetNextDevicePathInstance (&Variable
, &InstanceSize
);
1560 } while (Instance
!= NULL
);
1562 FreePool (OriginalVariable
);
1565 VariableSize
= GetDevicePathSize (NewVariable
);
1567 Status
= gRT
->SetVariable (
1569 &gEfiGlobalVariableGuid
,
1570 EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
,
1575 // Shrinking variable with existing variable driver implementation shouldn't fail.
1577 ASSERT_EFI_ERROR (Status
);
1580 if (NewVariable
!= NULL
) {
1581 FreePool (NewVariable
);
1588 Build terminal device path according to terminal type.
1590 @param TerminalType The terminal type is PC ANSI, VT100, VT100+ or VT-UTF8.
1591 @param ParentDevicePath Parent device path.
1592 @param TerminalDevicePath Returned terminal device path, if building successfully.
1594 @retval EFI_UNSUPPORTED Terminal does not belong to the supported type.
1595 @retval EFI_OUT_OF_RESOURCES Generate terminal device path failed.
1596 @retval EFI_SUCCESS Build terminal device path successfully.
1600 SetTerminalDevicePath (
1601 IN TERMINAL_TYPE TerminalType
,
1602 IN EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
,
1603 OUT EFI_DEVICE_PATH_PROTOCOL
**TerminalDevicePath
1606 VENDOR_DEVICE_PATH Node
;
1608 ASSERT (TerminalType
< ARRAY_SIZE (mTerminalType
));
1609 Node
.Header
.Type
= MESSAGING_DEVICE_PATH
;
1610 Node
.Header
.SubType
= MSG_VENDOR_DP
;
1611 SetDevicePathNodeLength (&Node
, sizeof (VENDOR_DEVICE_PATH
));
1612 CopyGuid (&Node
.Guid
, mTerminalType
[TerminalType
]);
1615 // Append the terminal node onto parent device path
1616 // to generate a complete terminal device path.
1618 *TerminalDevicePath
= AppendDevicePathNode (
1620 (EFI_DEVICE_PATH_PROTOCOL
*) &Node
1622 if (*TerminalDevicePath
== NULL
) {
1623 return EFI_OUT_OF_RESOURCES
;
1630 The user Entry Point for module Terminal. The user code starts with this function.
1632 @param ImageHandle The firmware allocated handle for the EFI image.
1633 @param SystemTable A pointer to the EFI System Table.
1635 @retval EFI_SUCCESS The entry point is executed successfully.
1636 @retval other Some error occurs when executing this entry point.
1642 IN EFI_HANDLE ImageHandle
,
1643 IN EFI_SYSTEM_TABLE
*SystemTable
1649 // Install driver model protocol(s).
1651 Status
= EfiLibInstallDriverBindingComponentName2 (
1654 &gTerminalDriverBinding
,
1656 &gTerminalComponentName
,
1657 &gTerminalComponentName2
1659 ASSERT_EFI_ERROR (Status
);
1665 Check if the device supports hot-plug through its device path.
1667 This function could be updated to check more types of Hot Plug devices.
1668 Currently, it checks USB and PCCard device.
1670 @param DevicePath Pointer to device's device path.
1672 @retval TRUE The devcie is a hot-plug device
1673 @retval FALSE The devcie is not a hot-plug device.
1678 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
1681 EFI_DEVICE_PATH_PROTOCOL
*CheckDevicePath
;
1683 CheckDevicePath
= DevicePath
;
1684 while (!IsDevicePathEnd (CheckDevicePath
)) {
1686 // Check device whether is hot plug device or not throught Device Path
1688 if ((DevicePathType (CheckDevicePath
) == MESSAGING_DEVICE_PATH
) &&
1689 (DevicePathSubType (CheckDevicePath
) == MSG_USB_DP
||
1690 DevicePathSubType (CheckDevicePath
) == MSG_USB_CLASS_DP
||
1691 DevicePathSubType (CheckDevicePath
) == MSG_USB_WWID_DP
)) {
1693 // If Device is USB device
1697 if ((DevicePathType (CheckDevicePath
) == HARDWARE_DEVICE_PATH
) &&
1698 (DevicePathSubType (CheckDevicePath
) == HW_PCCARD_DP
)) {
1700 // If Device is PCCard
1705 CheckDevicePath
= NextDevicePathNode (CheckDevicePath
);