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