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