]> git.proxmox.com Git - mirror_edk2.git/blob - IntelFrameworkModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2Keyboard.c
ff562b2698d65fa1b9fe718d70dc71548a35678a
[mirror_edk2.git] / IntelFrameworkModulePkg / Bus / Isa / Ps2KeyboardDxe / Ps2Keyboard.c
1 /** @file
2
3 PS/2 Keyboard driver. Routines that interacts with callers,
4 conforming to EFI driver model
5
6 Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
7 This program and the accompanying materials
8 are licensed and made available under the terms and conditions of the BSD License
9 which accompanies this distribution. The full text of the license may be found at
10 http://opensource.org/licenses/bsd-license.php
11
12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
14
15 **/
16
17 #include "Ps2Keyboard.h"
18
19 //
20 // Function prototypes
21 //
22 /**
23 Test controller is a keyboard Controller.
24
25 @param This Pointer of EFI_DRIVER_BINDING_PROTOCOL
26 @param Controller driver's controller
27 @param RemainingDevicePath children device path
28
29 @retval EFI_UNSUPPORTED controller is not floppy disk
30 @retval EFI_SUCCESS controller is floppy disk
31 **/
32 EFI_STATUS
33 EFIAPI
34 KbdControllerDriverSupported (
35 IN EFI_DRIVER_BINDING_PROTOCOL *This,
36 IN EFI_HANDLE Controller,
37 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
38 );
39
40 /**
41 Create KEYBOARD_CONSOLE_IN_DEV instance on controller.
42
43 @param This Pointer of EFI_DRIVER_BINDING_PROTOCOL
44 @param Controller driver controller handle
45 @param RemainingDevicePath Children's device path
46
47 @retval whether success to create floppy control instance.
48 **/
49 EFI_STATUS
50 EFIAPI
51 KbdControllerDriverStart (
52 IN EFI_DRIVER_BINDING_PROTOCOL *This,
53 IN EFI_HANDLE Controller,
54 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
55 );
56
57 /**
58 Stop this driver on ControllerHandle. Support stopping any child handles
59 created by this driver.
60
61 @param This Protocol instance pointer.
62 @param ControllerHandle Handle of device to stop driver on
63 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
64 children is zero stop the entire bus driver.
65 @param ChildHandleBuffer List of Child Handles to Stop.
66
67 @retval EFI_SUCCESS This driver is removed ControllerHandle
68 @retval other This driver was not removed from this device
69
70 **/
71 EFI_STATUS
72 EFIAPI
73 KbdControllerDriverStop (
74 IN EFI_DRIVER_BINDING_PROTOCOL *This,
75 IN EFI_HANDLE Controller,
76 IN UINTN NumberOfChildren,
77 IN EFI_HANDLE *ChildHandleBuffer
78 );
79
80 /**
81 Free the waiting key notify list.
82
83 @param ListHead Pointer to list head
84
85 @retval EFI_INVALID_PARAMETER ListHead is NULL
86 @retval EFI_SUCCESS Sucess to free NotifyList
87 **/
88 EFI_STATUS
89 KbdFreeNotifyList (
90 IN OUT LIST_ENTRY *ListHead
91 );
92
93 //
94 // DriverBinding Protocol Instance
95 //
96 EFI_DRIVER_BINDING_PROTOCOL gKeyboardControllerDriver = {
97 KbdControllerDriverSupported,
98 KbdControllerDriverStart,
99 KbdControllerDriverStop,
100 0xa,
101 NULL,
102 NULL
103 };
104
105 /**
106 Test controller is a keyboard Controller.
107
108 @param This Pointer of EFI_DRIVER_BINDING_PROTOCOL
109 @param Controller driver's controller
110 @param RemainingDevicePath children device path
111
112 @retval EFI_UNSUPPORTED controller is not floppy disk
113 @retval EFI_SUCCESS controller is floppy disk
114 **/
115 EFI_STATUS
116 EFIAPI
117 KbdControllerDriverSupported (
118 IN EFI_DRIVER_BINDING_PROTOCOL *This,
119 IN EFI_HANDLE Controller,
120 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
121 )
122 {
123 EFI_STATUS Status;
124 EFI_ISA_IO_PROTOCOL *IsaIo;
125
126 //
127 // Open the IO Abstraction(s) needed to perform the supported test
128 //
129 Status = gBS->OpenProtocol (
130 Controller,
131 &gEfiIsaIoProtocolGuid,
132 (VOID **) &IsaIo,
133 This->DriverBindingHandle,
134 Controller,
135 EFI_OPEN_PROTOCOL_BY_DRIVER
136 );
137 if (EFI_ERROR (Status)) {
138 return Status;
139 }
140 //
141 // Use the ISA I/O Protocol to see if Controller is the Keyboard controller
142 //
143 if (IsaIo->ResourceList->Device.HID != EISA_PNP_ID (0x303) || IsaIo->ResourceList->Device.UID != 0) {
144 Status = EFI_UNSUPPORTED;
145 }
146 //
147 // Close the I/O Abstraction(s) used to perform the supported test
148 //
149 gBS->CloseProtocol (
150 Controller,
151 &gEfiIsaIoProtocolGuid,
152 This->DriverBindingHandle,
153 Controller
154 );
155
156 return Status;
157 }
158
159 /**
160 Create KEYBOARD_CONSOLE_IN_DEV instance on controller.
161
162 @param This Pointer of EFI_DRIVER_BINDING_PROTOCOL
163 @param Controller driver controller handle
164 @param RemainingDevicePath Children's device path
165
166 @retval whether success to create floppy control instance.
167 **/
168 EFI_STATUS
169 EFIAPI
170 KbdControllerDriverStart (
171 IN EFI_DRIVER_BINDING_PROTOCOL *This,
172 IN EFI_HANDLE Controller,
173 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
174 )
175 {
176 EFI_STATUS Status;
177 EFI_STATUS Status1;
178 EFI_ISA_IO_PROTOCOL *IsaIo;
179 KEYBOARD_CONSOLE_IN_DEV *ConsoleIn;
180 UINT8 Data;
181 EFI_STATUS_CODE_VALUE StatusCode;
182 EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
183
184 StatusCode = 0;
185
186 Status = gBS->OpenProtocol (
187 Controller,
188 &gEfiDevicePathProtocolGuid,
189 (VOID **) &ParentDevicePath,
190 This->DriverBindingHandle,
191 Controller,
192 EFI_OPEN_PROTOCOL_BY_DRIVER
193 );
194 if (EFI_ERROR (Status)) {
195 return Status;
196 }
197 //
198 // Report that the keyboard is being enabled
199 //
200 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
201 EFI_PROGRESS_CODE,
202 EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_ENABLE,
203 ParentDevicePath
204 );
205
206 //
207 // Get the ISA I/O Protocol on Controller's handle
208 //
209 Status = gBS->OpenProtocol (
210 Controller,
211 &gEfiIsaIoProtocolGuid,
212 (VOID **) &IsaIo,
213 This->DriverBindingHandle,
214 Controller,
215 EFI_OPEN_PROTOCOL_BY_DRIVER
216 );
217 if (EFI_ERROR (Status)) {
218 gBS->CloseProtocol (
219 Controller,
220 &gEfiDevicePathProtocolGuid,
221 This->DriverBindingHandle,
222 Controller
223 );
224 return EFI_INVALID_PARAMETER;
225 }
226 //
227 // Allocate private data
228 //
229 ConsoleIn = AllocateZeroPool (sizeof (KEYBOARD_CONSOLE_IN_DEV));
230 if (ConsoleIn == NULL) {
231 Status = EFI_OUT_OF_RESOURCES;
232 StatusCode = EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_CONTROLLER_ERROR;
233 goto ErrorExit;
234 }
235 //
236 // Setup the device instance
237 //
238 ConsoleIn->Signature = KEYBOARD_CONSOLE_IN_DEV_SIGNATURE;
239 ConsoleIn->Handle = Controller;
240 (ConsoleIn->ConIn).Reset = KeyboardEfiReset;
241 (ConsoleIn->ConIn).ReadKeyStroke = KeyboardReadKeyStroke;
242 ConsoleIn->DataRegisterAddress = KEYBOARD_8042_DATA_REGISTER;
243 ConsoleIn->StatusRegisterAddress = KEYBOARD_8042_STATUS_REGISTER;
244 ConsoleIn->CommandRegisterAddress = KEYBOARD_8042_COMMAND_REGISTER;
245 ConsoleIn->IsaIo = IsaIo;
246 ConsoleIn->DevicePath = ParentDevicePath;
247
248 ConsoleIn->ConInEx.Reset = KeyboardEfiResetEx;
249 ConsoleIn->ConInEx.ReadKeyStrokeEx = KeyboardReadKeyStrokeEx;
250 ConsoleIn->ConInEx.SetState = KeyboardSetState;
251 ConsoleIn->ConInEx.RegisterKeyNotify = KeyboardRegisterKeyNotify;
252 ConsoleIn->ConInEx.UnregisterKeyNotify = KeyboardUnregisterKeyNotify;
253
254 InitializeListHead (&ConsoleIn->NotifyList);
255
256 //
257 // Fix for random hangs in System waiting for the Key if no KBC is present in BIOS.
258 // When KBC decode (IO port 0x60/0x64 decode) is not enabled,
259 // KeyboardRead will read back as 0xFF and return status is EFI_SUCCESS.
260 // So instead we read status register to detect after read if KBC decode is enabled.
261 //
262
263 //
264 // Return code is ignored on purpose.
265 //
266 if (!PcdGetBool (PcdFastPS2Detection)) {
267 KeyboardRead (ConsoleIn, &Data);
268 if ((KeyReadStatusRegister (ConsoleIn) & (KBC_PARE | KBC_TIM)) == (KBC_PARE | KBC_TIM)) {
269 //
270 // If nobody decodes KBC I/O port, it will read back as 0xFF.
271 // Check the Time-Out and Parity bit to see if it has an active KBC in system
272 //
273 Status = EFI_DEVICE_ERROR;
274 StatusCode = EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_NOT_DETECTED;
275 goto ErrorExit;
276 }
277 }
278
279 //
280 // Setup the WaitForKey event
281 //
282 Status = gBS->CreateEvent (
283 EVT_NOTIFY_WAIT,
284 TPL_NOTIFY,
285 KeyboardWaitForKey,
286 ConsoleIn,
287 &((ConsoleIn->ConIn).WaitForKey)
288 );
289 if (EFI_ERROR (Status)) {
290 Status = EFI_OUT_OF_RESOURCES;
291 StatusCode = EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_CONTROLLER_ERROR;
292 goto ErrorExit;
293 }
294 //
295 // Setup the WaitForKeyEx event
296 //
297 Status = gBS->CreateEvent (
298 EVT_NOTIFY_WAIT,
299 TPL_NOTIFY,
300 KeyboardWaitForKeyEx,
301 ConsoleIn,
302 &(ConsoleIn->ConInEx.WaitForKeyEx)
303 );
304 if (EFI_ERROR (Status)) {
305 Status = EFI_OUT_OF_RESOURCES;
306 StatusCode = EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_CONTROLLER_ERROR;
307 goto ErrorExit;
308 }
309
310 // Setup a periodic timer, used for reading keystrokes at a fixed interval
311 //
312 Status = gBS->CreateEvent (
313 EVT_TIMER | EVT_NOTIFY_SIGNAL,
314 TPL_NOTIFY,
315 KeyboardTimerHandler,
316 ConsoleIn,
317 &ConsoleIn->TimerEvent
318 );
319 if (EFI_ERROR (Status)) {
320 Status = EFI_OUT_OF_RESOURCES;
321 StatusCode = EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_CONTROLLER_ERROR;
322 goto ErrorExit;
323 }
324
325 Status = gBS->SetTimer (
326 ConsoleIn->TimerEvent,
327 TimerPeriodic,
328 KEYBOARD_TIMER_INTERVAL
329 );
330 if (EFI_ERROR (Status)) {
331 Status = EFI_OUT_OF_RESOURCES;
332 StatusCode = EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_CONTROLLER_ERROR;
333 goto ErrorExit;
334 }
335
336 Status = gBS->CreateEvent (
337 EVT_NOTIFY_SIGNAL,
338 TPL_CALLBACK,
339 KeyNotifyProcessHandler,
340 ConsoleIn,
341 &ConsoleIn->KeyNotifyProcessEvent
342 );
343 if (EFI_ERROR (Status)) {
344 Status = EFI_OUT_OF_RESOURCES;
345 StatusCode = EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_CONTROLLER_ERROR;
346 goto ErrorExit;
347 }
348
349 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
350 EFI_PROGRESS_CODE,
351 EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_PRESENCE_DETECT,
352 ParentDevicePath
353 );
354
355 //
356 // Reset the keyboard device
357 //
358 Status = ConsoleIn->ConInEx.Reset (&ConsoleIn->ConInEx, FeaturePcdGet (PcdPs2KbdExtendedVerification));
359 if (EFI_ERROR (Status)) {
360 Status = EFI_DEVICE_ERROR;
361 StatusCode = EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_NOT_DETECTED;
362 goto ErrorExit;
363 }
364
365 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
366 EFI_PROGRESS_CODE,
367 EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_DETECTED,
368 ParentDevicePath
369 );
370
371 ConsoleIn->ControllerNameTable = NULL;
372 AddUnicodeString2 (
373 "eng",
374 gPs2KeyboardComponentName.SupportedLanguages,
375 &ConsoleIn->ControllerNameTable,
376 L"PS/2 Keyboard Device",
377 TRUE
378 );
379 AddUnicodeString2 (
380 "en",
381 gPs2KeyboardComponentName2.SupportedLanguages,
382 &ConsoleIn->ControllerNameTable,
383 L"PS/2 Keyboard Device",
384 FALSE
385 );
386
387
388 //
389 // Install protocol interfaces for the keyboard device.
390 //
391 Status = gBS->InstallMultipleProtocolInterfaces (
392 &Controller,
393 &gEfiSimpleTextInProtocolGuid,
394 &ConsoleIn->ConIn,
395 &gEfiSimpleTextInputExProtocolGuid,
396 &ConsoleIn->ConInEx,
397 NULL
398 );
399 if (EFI_ERROR (Status)) {
400 StatusCode = EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_CONTROLLER_ERROR;
401 goto ErrorExit;
402 }
403
404 return Status;
405
406 ErrorExit:
407 //
408 // Report error code
409 //
410 if (StatusCode != 0) {
411 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
412 EFI_ERROR_CODE | EFI_ERROR_MINOR,
413 StatusCode,
414 ParentDevicePath
415 );
416 }
417
418 if ((ConsoleIn != NULL) && (ConsoleIn->ConIn.WaitForKey != NULL)) {
419 gBS->CloseEvent (ConsoleIn->ConIn.WaitForKey);
420 }
421
422 if ((ConsoleIn != NULL) && (ConsoleIn->TimerEvent != NULL)) {
423 gBS->CloseEvent (ConsoleIn->TimerEvent);
424 }
425 if ((ConsoleIn != NULL) && (ConsoleIn->ConInEx.WaitForKeyEx != NULL)) {
426 gBS->CloseEvent (ConsoleIn->ConInEx.WaitForKeyEx);
427 }
428 if ((ConsoleIn != NULL) && (ConsoleIn->KeyNotifyProcessEvent != NULL)) {
429 gBS->CloseEvent (ConsoleIn->KeyNotifyProcessEvent);
430 }
431 KbdFreeNotifyList (&ConsoleIn->NotifyList);
432 if ((ConsoleIn != NULL) && (ConsoleIn->ControllerNameTable != NULL)) {
433 FreeUnicodeStringTable (ConsoleIn->ControllerNameTable);
434 }
435 //
436 // Since there will be no timer handler for keyboard input any more,
437 // exhaust input data just in case there is still keyboard data left
438 //
439 if (ConsoleIn != NULL) {
440 Status1 = EFI_SUCCESS;
441 while (!EFI_ERROR (Status1) && (Status != EFI_DEVICE_ERROR)) {
442 Status1 = KeyboardRead (ConsoleIn, &Data);;
443 }
444 }
445
446 if (ConsoleIn != NULL) {
447 gBS->FreePool (ConsoleIn);
448 }
449
450 gBS->CloseProtocol (
451 Controller,
452 &gEfiDevicePathProtocolGuid,
453 This->DriverBindingHandle,
454 Controller
455 );
456
457 gBS->CloseProtocol (
458 Controller,
459 &gEfiIsaIoProtocolGuid,
460 This->DriverBindingHandle,
461 Controller
462 );
463
464 return Status;
465 }
466
467 /**
468 Stop this driver on ControllerHandle. Support stopping any child handles
469 created by this driver.
470
471 @param This Protocol instance pointer.
472 @param ControllerHandle Handle of device to stop driver on
473 @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
474 children is zero stop the entire bus driver.
475 @param ChildHandleBuffer List of Child Handles to Stop.
476
477 @retval EFI_SUCCESS This driver is removed ControllerHandle
478 @retval other This driver was not removed from this device
479
480 **/
481 EFI_STATUS
482 EFIAPI
483 KbdControllerDriverStop (
484 IN EFI_DRIVER_BINDING_PROTOCOL *This,
485 IN EFI_HANDLE Controller,
486 IN UINTN NumberOfChildren,
487 IN EFI_HANDLE *ChildHandleBuffer
488 )
489 {
490 EFI_STATUS Status;
491 EFI_SIMPLE_TEXT_INPUT_PROTOCOL *ConIn;
492 KEYBOARD_CONSOLE_IN_DEV *ConsoleIn;
493 UINT8 Data;
494
495 //
496 // Disable Keyboard
497 //
498 Status = gBS->OpenProtocol (
499 Controller,
500 &gEfiSimpleTextInProtocolGuid,
501 (VOID **) &ConIn,
502 This->DriverBindingHandle,
503 Controller,
504 EFI_OPEN_PROTOCOL_GET_PROTOCOL
505 );
506 if (EFI_ERROR (Status)) {
507 return Status;
508 }
509 Status = gBS->OpenProtocol (
510 Controller,
511 &gEfiSimpleTextInputExProtocolGuid,
512 NULL,
513 This->DriverBindingHandle,
514 Controller,
515 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
516 );
517 if (EFI_ERROR (Status)) {
518 return Status;
519 }
520
521 ConsoleIn = KEYBOARD_CONSOLE_IN_DEV_FROM_THIS (ConIn);
522
523 //
524 // Report that the keyboard is being disabled
525 //
526 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
527 EFI_PROGRESS_CODE,
528 EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_DISABLE,
529 ConsoleIn->DevicePath
530 );
531
532 if (ConsoleIn->TimerEvent != NULL) {
533 gBS->CloseEvent (ConsoleIn->TimerEvent);
534 ConsoleIn->TimerEvent = NULL;
535 }
536
537 //
538 // Since there will be no timer handler for keyboard input any more,
539 // exhaust input data just in case there is still keyboard data left
540 //
541 Status = EFI_SUCCESS;
542 while (!EFI_ERROR (Status)) {
543 Status = KeyboardRead (ConsoleIn, &Data);;
544 }
545 //
546 // Uninstall the SimpleTextIn and SimpleTextInEx protocols
547 //
548 Status = gBS->UninstallMultipleProtocolInterfaces (
549 Controller,
550 &gEfiSimpleTextInProtocolGuid,
551 &ConsoleIn->ConIn,
552 &gEfiSimpleTextInputExProtocolGuid,
553 &ConsoleIn->ConInEx,
554 NULL
555 );
556 if (EFI_ERROR (Status)) {
557 return Status;
558 }
559
560 gBS->CloseProtocol (
561 Controller,
562 &gEfiDevicePathProtocolGuid,
563 This->DriverBindingHandle,
564 Controller
565 );
566
567 gBS->CloseProtocol (
568 Controller,
569 &gEfiIsaIoProtocolGuid,
570 This->DriverBindingHandle,
571 Controller
572 );
573
574 //
575 // Free other resources
576 //
577 if ((ConsoleIn->ConIn).WaitForKey != NULL) {
578 gBS->CloseEvent ((ConsoleIn->ConIn).WaitForKey);
579 (ConsoleIn->ConIn).WaitForKey = NULL;
580 }
581 if (ConsoleIn->ConInEx.WaitForKeyEx != NULL) {
582 gBS->CloseEvent (ConsoleIn->ConInEx.WaitForKeyEx);
583 ConsoleIn->ConInEx.WaitForKeyEx = NULL;
584 }
585 if (ConsoleIn->KeyNotifyProcessEvent != NULL) {
586 gBS->CloseEvent (ConsoleIn->KeyNotifyProcessEvent);
587 ConsoleIn->KeyNotifyProcessEvent = NULL;
588 }
589 KbdFreeNotifyList (&ConsoleIn->NotifyList);
590 FreeUnicodeStringTable (ConsoleIn->ControllerNameTable);
591 gBS->FreePool (ConsoleIn);
592
593 return EFI_SUCCESS;
594 }
595
596 /**
597 Free the waiting key notify list.
598
599 @param ListHead Pointer to list head
600
601 @retval EFI_INVALID_PARAMETER ListHead is NULL
602 @retval EFI_SUCCESS Sucess to free NotifyList
603 **/
604 EFI_STATUS
605 KbdFreeNotifyList (
606 IN OUT LIST_ENTRY *ListHead
607 )
608 {
609 KEYBOARD_CONSOLE_IN_EX_NOTIFY *NotifyNode;
610
611 if (ListHead == NULL) {
612 return EFI_INVALID_PARAMETER;
613 }
614 while (!IsListEmpty (ListHead)) {
615 NotifyNode = CR (
616 ListHead->ForwardLink,
617 KEYBOARD_CONSOLE_IN_EX_NOTIFY,
618 NotifyEntry,
619 KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE
620 );
621 RemoveEntryList (ListHead->ForwardLink);
622 gBS->FreePool (NotifyNode);
623 }
624
625 return EFI_SUCCESS;
626 }
627
628 /**
629 The module Entry Point for module Ps2Keyboard.
630
631 @param[in] ImageHandle The firmware allocated handle for the EFI image.
632 @param[in] SystemTable A pointer to the EFI System Table.
633
634 @retval EFI_SUCCESS The entry point is executed successfully.
635 @retval other Some error occurs when executing this entry point.
636
637 **/
638 EFI_STATUS
639 EFIAPI
640 InitializePs2Keyboard(
641 IN EFI_HANDLE ImageHandle,
642 IN EFI_SYSTEM_TABLE *SystemTable
643 )
644 {
645 EFI_STATUS Status;
646
647 //
648 // Install driver model protocol(s).
649 //
650 Status = EfiLibInstallDriverBindingComponentName2 (
651 ImageHandle,
652 SystemTable,
653 &gKeyboardControllerDriver,
654 ImageHandle,
655 &gPs2KeyboardComponentName,
656 &gPs2KeyboardComponentName2
657 );
658 ASSERT_EFI_ERROR (Status);
659
660
661 return Status;
662 }
663