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