]> git.proxmox.com Git - mirror_edk2.git/blame - IntelFrameworkModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KbdTextIn.c
Consume the UNDI_CONFIG_TABLE defined in MdePkg and remove the local definition of...
[mirror_edk2.git] / IntelFrameworkModulePkg / Bus / Isa / Ps2KeyboardDxe / Ps2KbdTextIn.c
CommitLineData
f713c4fe 1/** @file\r
b6763e03 2 Routines implements SIMPLE_TEXT_IN protocol's interfaces based on 8042 interfaces\r
3 provided by Ps2KbdCtrller.c.\r
05fbd06d 4\r
c220787b 5Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>\r
180a5a35 6This program and the accompanying materials\r
df0dcb5e 7are licensed and made available under the terms and conditions of the BSD License\r
8which accompanies this distribution. The full text of the license may be found at\r
9http://opensource.org/licenses/bsd-license.php\r
10\r
11THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
05fbd06d 13\r
f8cd287b 14**/\r
05fbd06d 15\r
05fbd06d 16\r
05fbd06d 17#include "Ps2Keyboard.h"\r
18\r
b6763e03 19/**\r
c220787b
RN
20 Check whether the EFI key buffer is empty.\r
21\r
22 @param Queue Pointer to instance of EFI_KEY_QUEUE.\r
23\r
24 @retval TRUE The EFI key buffer is empty.\r
25 @retval FALSE The EFI key buffer isn't empty.\r
26**/\r
27BOOLEAN\r
28IsEfikeyBufEmpty (\r
29 IN EFI_KEY_QUEUE *Queue\r
30 )\r
31{\r
32 return (BOOLEAN) (Queue->Head == Queue->Tail);\r
33}\r
34\r
c220787b
RN
35/**\r
36 Read & remove one key data from the EFI key buffer.\r
5829afe3 37\r
c220787b
RN
38 @param Queue Pointer to instance of EFI_KEY_QUEUE.\r
39 @param KeyData Receive the key data.\r
40\r
41 @retval EFI_SUCCESS The key data is popped successfully.\r
42 @retval EFI_NOT_READY There is no key data available.\r
b6763e03 43**/\r
05fbd06d 44EFI_STATUS\r
c220787b
RN
45PopEfikeyBufHead (\r
46 IN EFI_KEY_QUEUE *Queue,\r
5829afe3 47 OUT EFI_KEY_DATA *KeyData OPTIONAL\r
b6763e03 48 )\r
49{\r
c220787b
RN
50 if (IsEfikeyBufEmpty (Queue)) {\r
51 return EFI_NOT_READY;\r
52 }\r
b6763e03 53 //\r
c220787b 54 // Retrieve and remove the values\r
b6763e03 55 //\r
5829afe3 56 if (KeyData != NULL) {\r
57 CopyMem (KeyData, &Queue->Buffer[Queue->Head], sizeof (EFI_KEY_DATA));\r
58 }\r
c220787b 59 Queue->Head = (Queue->Head + 1) % KEYBOARD_EFI_KEY_MAX_COUNT;\r
b6763e03 60 return EFI_SUCCESS;\r
61}\r
05fbd06d 62\r
5829afe3 63/**\r
64 Push one key data to the EFI key buffer.\r
65\r
66 @param Queue Pointer to instance of EFI_KEY_QUEUE.\r
67 @param KeyData The key data to push.\r
68**/\r
69VOID\r
70PushEfikeyBufTail (\r
71 IN EFI_KEY_QUEUE *Queue,\r
72 IN EFI_KEY_DATA *KeyData\r
73 )\r
74{\r
75 if ((Queue->Tail + 1) % KEYBOARD_EFI_KEY_MAX_COUNT == Queue->Head) {\r
76 //\r
77 // If Queue is full, pop the one from head.\r
78 //\r
79 PopEfikeyBufHead (Queue, NULL);\r
80 }\r
81 CopyMem (&Queue->Buffer[Queue->Tail], KeyData, sizeof (EFI_KEY_DATA));\r
82 Queue->Tail = (Queue->Tail + 1) % KEYBOARD_EFI_KEY_MAX_COUNT;\r
83}\r
84\r
bcd70414 85/**\r
b6763e03 86 Judge whether is a registed key\r
87\r
5829afe3 88 @param RegsiteredData A pointer to a buffer that is filled in with the keystroke\r
b6763e03 89 state data for the key that was registered.\r
5829afe3 90 @param InputData A pointer to a buffer that is filled in with the keystroke\r
b6763e03 91 state data for the key that was pressed.\r
bcd70414 92\r
b6763e03 93 @retval TRUE Key be pressed matches a registered key.\r
5829afe3 94 @retval FLASE Match failed.\r
95\r
bcd70414 96**/\r
f3d1e940 97BOOLEAN\r
98IsKeyRegistered (\r
99 IN EFI_KEY_DATA *RegsiteredData,\r
100 IN EFI_KEY_DATA *InputData\r
b6763e03 101 )\r
102\r
103{\r
104 ASSERT (RegsiteredData != NULL && InputData != NULL);\r
5829afe3 105\r
b6763e03 106 if ((RegsiteredData->Key.ScanCode != InputData->Key.ScanCode) ||\r
107 (RegsiteredData->Key.UnicodeChar != InputData->Key.UnicodeChar)) {\r
5829afe3 108 return FALSE;\r
109 }\r
110\r
b6763e03 111 //\r
112 // Assume KeyShiftState/KeyToggleState = 0 in Registered key data means these state could be ignored.\r
113 //\r
114 if (RegsiteredData->KeyState.KeyShiftState != 0 &&\r
115 RegsiteredData->KeyState.KeyShiftState != InputData->KeyState.KeyShiftState) {\r
5829afe3 116 return FALSE;\r
117 }\r
b6763e03 118 if (RegsiteredData->KeyState.KeyToggleState != 0 &&\r
119 RegsiteredData->KeyState.KeyToggleState != InputData->KeyState.KeyToggleState) {\r
5829afe3 120 return FALSE;\r
121 }\r
122\r
b6763e03 123 return TRUE;\r
124\r
125}\r
f3d1e940 126\r
bcd70414 127/**\r
5829afe3 128 Reads the next keystroke from the input device. The WaitForKey Event can\r
bcd70414 129 be used to test for existance of a keystroke via WaitForEvent () call.\r
5829afe3 130\r
b6763e03 131 @param ConsoleInDev Ps2 Keyboard private structure\r
5829afe3 132 @param KeyData A pointer to a buffer that is filled in with the keystroke\r
b6763e03 133 state data for the key that was pressed.\r
f3d1e940 134\r
5829afe3 135\r
b6763e03 136 @retval EFI_SUCCESS The keystroke information was returned.\r
137 @retval EFI_NOT_READY There was no keystroke data availiable.\r
5829afe3 138 @retval EFI_DEVICE_ERROR The keystroke information was not returned due to\r
b6763e03 139 hardware errors.\r
5829afe3 140 @retval EFI_INVALID_PARAMETER KeyData is NULL.\r
bcd70414 141\r
142**/\r
f3d1e940 143EFI_STATUS\r
144KeyboardReadKeyStrokeWorker (\r
145 IN KEYBOARD_CONSOLE_IN_DEV *ConsoleInDev,\r
146 OUT EFI_KEY_DATA *KeyData\r
147 )\r
f3d1e940 148\r
f3d1e940 149{\r
150 EFI_STATUS Status;\r
151 EFI_TPL OldTpl;\r
5829afe3 152\r
f3d1e940 153 if (KeyData == NULL) {\r
154 return EFI_INVALID_PARAMETER;\r
155 }\r
5829afe3 156\r
f3d1e940 157 //\r
158 // Enter critical section\r
159 //\r
160 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
161\r
c220787b 162 KeyboardTimerHandler (NULL, ConsoleInDev);\r
5829afe3 163\r
c220787b
RN
164 if (ConsoleInDev->KeyboardErr) {\r
165 Status = EFI_DEVICE_ERROR;\r
166 } else {\r
167 Status = PopEfikeyBufHead (&ConsoleInDev->EfiKeyQueue, KeyData);\r
f3d1e940 168 }\r
169\r
c220787b
RN
170 gBS->RestoreTPL (OldTpl);\r
171 return Status;\r
f3d1e940 172}\r
173\r
bcd70414 174/**\r
b6763e03 175 Perform 8042 controller and keyboard initialization which implement SIMPLE_TEXT_IN.Reset()\r
bcd70414 176\r
b6763e03 177 @param This Pointer to instance of EFI_SIMPLE_TEXT_INPUT_PROTOCOL\r
5829afe3 178 @param ExtendedVerification Indicate that the driver may perform a more\r
179 exhaustive verification operation of the device during\r
180 reset, now this par is ignored in this driver\r
bcd70414 181\r
182**/\r
05fbd06d 183EFI_STATUS\r
184EFIAPI\r
185KeyboardEfiReset (\r
186 IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,\r
187 IN BOOLEAN ExtendedVerification\r
188 )\r
05fbd06d 189{\r
190 EFI_STATUS Status;\r
191 KEYBOARD_CONSOLE_IN_DEV *ConsoleIn;\r
192 EFI_TPL OldTpl;\r
193\r
194 ConsoleIn = KEYBOARD_CONSOLE_IN_DEV_FROM_THIS (This);\r
195 if (ConsoleIn->KeyboardErr) {\r
196 return EFI_DEVICE_ERROR;\r
197 }\r
198\r
199 REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
200 EFI_PROGRESS_CODE,\r
201 EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_RESET,\r
202 ConsoleIn->DevicePath\r
203 );\r
204\r
205 //\r
206 // Enter critical section\r
207 //\r
208 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
209\r
210 //\r
211 // Call InitKeyboard to initialize the keyboard\r
212 //\r
213 Status = InitKeyboard (ConsoleIn, ExtendedVerification);\r
214 if (EFI_ERROR (Status)) {\r
215 //\r
216 // Leave critical section and return\r
217 //\r
218 gBS->RestoreTPL (OldTpl);\r
219 return EFI_DEVICE_ERROR;\r
220 }\r
05fbd06d 221\r
222 //\r
223 // Leave critical section and return\r
224 //\r
225 gBS->RestoreTPL (OldTpl);\r
226\r
227 //\r
228 // Report the status If a stuck key was detected\r
229 //\r
230 if (KeyReadStatusRegister (ConsoleIn) & 0x01) {\r
231 REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
232 EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
233 EFI_PERIPHERAL_KEYBOARD | EFI_P_KEYBOARD_EC_STUCK_KEY,\r
234 ConsoleIn->DevicePath\r
235 );\r
236 }\r
237 //\r
238 // Report the status If keyboard is locked\r
239 //\r
f713c4fe 240 if ((KeyReadStatusRegister (ConsoleIn) & 0x10) == 0) {\r
05fbd06d 241 REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
242 EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
243 EFI_PERIPHERAL_KEYBOARD | EFI_P_KEYBOARD_EC_LOCKED,\r
244 ConsoleIn->DevicePath\r
245 );\r
246 }\r
247\r
248 return EFI_SUCCESS;\r
249}\r
250\r
bcd70414 251/**\r
b6763e03 252 Retrieve key values for driver user which implement SIMPLE_TEXT_IN.ReadKeyStroke().\r
bcd70414 253\r
254 @param This Pointer to instance of EFI_SIMPLE_TEXT_INPUT_PROTOCOL\r
5829afe3 255 @param Key The output buffer for key value\r
bcd70414 256\r
257 @retval EFI_SUCCESS success to read key stroke\r
258**/\r
05fbd06d 259EFI_STATUS\r
260EFIAPI\r
261KeyboardReadKeyStroke (\r
262 IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,\r
263 OUT EFI_INPUT_KEY *Key\r
264 )\r
05fbd06d 265{\r
266 EFI_STATUS Status;\r
267 KEYBOARD_CONSOLE_IN_DEV *ConsoleIn;\r
f3d1e940 268 EFI_KEY_DATA KeyData;\r
05fbd06d 269\r
270 ConsoleIn = KEYBOARD_CONSOLE_IN_DEV_FROM_THIS (This);\r
f3d1e940 271 \r
5829afe3 272 //\r
273 // Considering if the partial keystroke is enabled, there maybe a partial\r
274 // keystroke in the queue, so here skip the partial keystroke and get the\r
275 // next key from the queue\r
276 //\r
277 while (1) {\r
278 //\r
279 // If there is no pending key, then return.\r
280 //\r
281 Status = KeyboardReadKeyStrokeWorker (ConsoleIn, &KeyData);\r
282 if (EFI_ERROR (Status)) {\r
283 return Status;\r
284 }\r
285 //\r
286 // If it is partial keystroke, skip it.\r
287 //\r
288 if (KeyData.Key.ScanCode == SCAN_NULL && KeyData.Key.UnicodeChar == CHAR_NULL) {\r
289 continue;\r
290 }\r
291 CopyMem (Key, &KeyData.Key, sizeof (EFI_INPUT_KEY));\r
292 return EFI_SUCCESS;\r
293 }\r
05fbd06d 294}\r
295\r
bcd70414 296/**\r
297 Event notification function for SIMPLE_TEXT_IN.WaitForKey event\r
298 Signal the event if there is key available\r
299\r
300 @param Event the event object\r
301 @param Context waitting context\r
302\r
303**/\r
05fbd06d 304VOID\r
305EFIAPI\r
306KeyboardWaitForKey (\r
307 IN EFI_EVENT Event,\r
308 IN VOID *Context\r
309 )\r
05fbd06d 310{\r
c220787b
RN
311 EFI_TPL OldTpl;\r
312 KEYBOARD_CONSOLE_IN_DEV *ConsoleIn;\r
5829afe3 313 EFI_KEY_DATA KeyData;\r
05fbd06d 314\r
c220787b 315 ConsoleIn = (KEYBOARD_CONSOLE_IN_DEV *) Context;\r
05fbd06d 316\r
317 //\r
318 // Enter critical section\r
319 //\r
320 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
5829afe3 321\r
c220787b 322 KeyboardTimerHandler (NULL, ConsoleIn);\r
05fbd06d 323\r
c220787b 324 if (!ConsoleIn->KeyboardErr) {\r
05fbd06d 325 //\r
5829afe3 326 // WaitforKey doesn't suppor the partial key.\r
327 // Considering if the partial keystroke is enabled, there maybe a partial\r
328 // keystroke in the queue, so here skip the partial keystroke and get the\r
329 // next key from the queue\r
05fbd06d 330 //\r
5829afe3 331 while (!IsEfikeyBufEmpty (&ConsoleIn->EfiKeyQueue)) {\r
332 CopyMem (\r
333 &KeyData,\r
334 &(ConsoleIn->EfiKeyQueue.Buffer[ConsoleIn->EfiKeyQueue.Head]),\r
335 sizeof (EFI_KEY_DATA)\r
336 );\r
337 if (KeyData.Key.ScanCode == SCAN_NULL && KeyData.Key.UnicodeChar == CHAR_NULL) {\r
338 PopEfikeyBufHead (&ConsoleIn->EfiKeyQueue, &KeyData);\r
339 continue;\r
340 }\r
341 //\r
342 // if there is pending value key, signal the event.\r
343 //\r
c220787b 344 gBS->SignalEvent (Event);\r
5829afe3 345 break;\r
c220787b 346 }\r
05fbd06d 347 }\r
348 //\r
349 // Leave critical section and return\r
350 //\r
351 gBS->RestoreTPL (OldTpl);\r
05fbd06d 352}\r
353\r
bcd70414 354/**\r
355 Event notification function for SIMPLE_TEXT_INPUT_EX_PROTOCOL.WaitForKeyEx event\r
356 Signal the event if there is key available\r
357\r
358 @param Event event object\r
359 @param Context waiting context\r
360\r
361**/\r
f3d1e940 362VOID\r
363EFIAPI\r
364KeyboardWaitForKeyEx (\r
365 IN EFI_EVENT Event,\r
366 IN VOID *Context\r
367 )\r
f3d1e940 368\r
f3d1e940 369{\r
c220787b 370 KeyboardWaitForKey (Event, Context);\r
f3d1e940 371}\r
372\r
bcd70414 373/**\r
374 Reset the input device and optionaly run diagnostics\r
375\r
b6763e03 376 @param This Protocol instance pointer.\r
377 @param ExtendedVerification Driver may perform diagnostics on reset.\r
bcd70414 378\r
b6763e03 379 @retval EFI_SUCCESS The device was reset.\r
5829afe3 380 @retval EFI_DEVICE_ERROR The device is not functioning properly and could\r
bcd70414 381 not be reset.\r
382\r
383**/\r
f3d1e940 384EFI_STATUS\r
385EFIAPI\r
386KeyboardEfiResetEx (\r
387 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,\r
388 IN BOOLEAN ExtendedVerification\r
389 )\r
f3d1e940 390\r
f3d1e940 391{\r
f3d1e940 392 KEYBOARD_CONSOLE_IN_DEV *ConsoleInDev;\r
f3d1e940 393\r
5829afe3 394 ConsoleInDev = TEXT_INPUT_EX_KEYBOARD_CONSOLE_IN_DEV_FROM_THIS (This);\r
f3d1e940 395\r
c220787b 396 return ConsoleInDev->ConIn.Reset (\r
5829afe3 397 &ConsoleInDev->ConIn,\r
c220787b
RN
398 ExtendedVerification\r
399 );\r
f3d1e940 400}\r
401\r
bcd70414 402/**\r
5829afe3 403 Reads the next keystroke from the input device. The WaitForKey Event can\r
f3d1e940 404 be used to test for existance of a keystroke via WaitForEvent () call.\r
405\r
bcd70414 406\r
b6763e03 407 @param This Protocol instance pointer.\r
5829afe3 408 @param KeyData A pointer to a buffer that is filled in with the keystroke\r
b6763e03 409 state data for the key that was pressed.\r
f3d1e940 410\r
b6763e03 411 @retval EFI_SUCCESS The keystroke information was returned.\r
412 @retval EFI_NOT_READY There was no keystroke data availiable.\r
5829afe3 413 @retval EFI_DEVICE_ERROR The keystroke information was not returned due to\r
b6763e03 414 hardware errors.\r
5829afe3 415 @retval EFI_INVALID_PARAMETER KeyData is NULL.\r
bcd70414 416\r
417**/\r
418EFI_STATUS\r
419EFIAPI\r
420KeyboardReadKeyStrokeEx (\r
421 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,\r
422 OUT EFI_KEY_DATA *KeyData\r
423 )\r
f3d1e940 424\r
f3d1e940 425{\r
426 KEYBOARD_CONSOLE_IN_DEV *ConsoleInDev;\r
427\r
428 if (KeyData == NULL) {\r
429 return EFI_INVALID_PARAMETER;\r
430 }\r
431\r
432 ConsoleInDev = TEXT_INPUT_EX_KEYBOARD_CONSOLE_IN_DEV_FROM_THIS (This);\r
433 return KeyboardReadKeyStrokeWorker (ConsoleInDev, KeyData);\r
f3d1e940 434}\r
435\r
bcd70414 436/**\r
437 Set certain state for the input device.\r
438\r
b6763e03 439 @param This Protocol instance pointer.\r
5829afe3 440 @param KeyToggleState A pointer to the EFI_KEY_TOGGLE_STATE to set the\r
b6763e03 441 state for the input device.\r
bcd70414 442\r
b6763e03 443 @retval EFI_SUCCESS The device state was set successfully.\r
5829afe3 444 @retval EFI_DEVICE_ERROR The device is not functioning correctly and could\r
b6763e03 445 not have the setting adjusted.\r
446 @retval EFI_UNSUPPORTED The device does not have the ability to set its state.\r
5829afe3 447 @retval EFI_INVALID_PARAMETER KeyToggleState is NULL.\r
bcd70414 448\r
5829afe3 449**/\r
f3d1e940 450EFI_STATUS\r
451EFIAPI\r
452KeyboardSetState (\r
453 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,\r
454 IN EFI_KEY_TOGGLE_STATE *KeyToggleState\r
455 )\r
f3d1e940 456\r
f3d1e940 457{\r
458 EFI_STATUS Status;\r
459 KEYBOARD_CONSOLE_IN_DEV *ConsoleInDev;\r
460 EFI_TPL OldTpl;\r
461\r
462 if (KeyToggleState == NULL) {\r
463 return EFI_INVALID_PARAMETER;\r
464 }\r
5829afe3 465\r
f3d1e940 466 ConsoleInDev = TEXT_INPUT_EX_KEYBOARD_CONSOLE_IN_DEV_FROM_THIS (This);\r
467\r
468 //\r
469 // Enter critical section\r
470 //\r
471 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
472\r
473 if (ConsoleInDev->KeyboardErr) {\r
474 Status = EFI_DEVICE_ERROR;\r
475 goto Exit;\r
476 }\r
477\r
c220787b 478 if ((*KeyToggleState & EFI_TOGGLE_STATE_VALID) != EFI_TOGGLE_STATE_VALID) {\r
f3d1e940 479 Status = EFI_UNSUPPORTED;\r
480 goto Exit;\r
481 }\r
5829afe3 482\r
f3d1e940 483 //\r
484 // Update the status light\r
485 //\r
5829afe3 486 ConsoleInDev->ScrollLock = FALSE;\r
487 ConsoleInDev->NumLock = FALSE;\r
488 ConsoleInDev->CapsLock = FALSE;\r
489 ConsoleInDev->IsSupportPartialKey = FALSE;\r
f3d1e940 490\r
491 if ((*KeyToggleState & EFI_SCROLL_LOCK_ACTIVE) == EFI_SCROLL_LOCK_ACTIVE) {\r
492 ConsoleInDev->ScrollLock = TRUE;\r
5829afe3 493 }\r
f3d1e940 494 if ((*KeyToggleState & EFI_NUM_LOCK_ACTIVE) == EFI_NUM_LOCK_ACTIVE) {\r
495 ConsoleInDev->NumLock = TRUE;\r
496 }\r
497 if ((*KeyToggleState & EFI_CAPS_LOCK_ACTIVE) == EFI_CAPS_LOCK_ACTIVE) {\r
498 ConsoleInDev->CapsLock = TRUE;\r
499 }\r
5829afe3 500 if ((*KeyToggleState & EFI_KEY_STATE_EXPOSED) == EFI_KEY_STATE_EXPOSED) {\r
501 ConsoleInDev->IsSupportPartialKey = TRUE;\r
502 }\r
f3d1e940 503\r
504 Status = UpdateStatusLights (ConsoleInDev);\r
505 if (EFI_ERROR (Status)) {\r
5829afe3 506 Status = EFI_DEVICE_ERROR;\r
f3d1e940 507 }\r
508\r
5829afe3 509Exit:\r
f3d1e940 510 //\r
511 // Leave critical section and return\r
512 //\r
513 gBS->RestoreTPL (OldTpl);\r
514\r
515 return Status;\r
516\r
517}\r
bcd70414 518\r
519/**\r
520 Register a notification function for a particular keystroke for the input device.\r
521\r
b6763e03 522 @param This Protocol instance pointer.\r
5829afe3 523 @param KeyData A pointer to a buffer that is filled in with the keystroke\r
b6763e03 524 information data for the key that was pressed.\r
5829afe3 525 @param KeyNotificationFunction Points to the function to be called when the key\r
526 sequence is typed specified by KeyData.\r
527 @param NotifyHandle Points to the unique handle assigned to the registered notification.\r
bcd70414 528\r
b6763e03 529 @retval EFI_SUCCESS The notification function was registered successfully.\r
530 @retval EFI_OUT_OF_RESOURCES Unable to allocate resources for necesssary data structures.\r
5829afe3 531 @retval EFI_INVALID_PARAMETER KeyData or NotifyHandle or KeyNotificationFunction is NULL.\r
532\r
533**/\r
f3d1e940 534EFI_STATUS\r
535EFIAPI\r
536KeyboardRegisterKeyNotify (\r
537 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,\r
538 IN EFI_KEY_DATA *KeyData,\r
539 IN EFI_KEY_NOTIFY_FUNCTION KeyNotificationFunction,\r
540 OUT EFI_HANDLE *NotifyHandle\r
541 )\r
f3d1e940 542{\r
543 EFI_STATUS Status;\r
544 KEYBOARD_CONSOLE_IN_DEV *ConsoleInDev;\r
545 EFI_TPL OldTpl;\r
546 LIST_ENTRY *Link;\r
5829afe3 547 KEYBOARD_CONSOLE_IN_EX_NOTIFY *CurrentNotify;\r
f3d1e940 548 KEYBOARD_CONSOLE_IN_EX_NOTIFY *NewNotify;\r
549\r
550 if (KeyData == NULL || NotifyHandle == NULL || KeyNotificationFunction == NULL) {\r
551 return EFI_INVALID_PARAMETER;\r
552 }\r
5829afe3 553\r
f3d1e940 554 ConsoleInDev = TEXT_INPUT_EX_KEYBOARD_CONSOLE_IN_DEV_FROM_THIS (This);\r
555\r
556 //\r
557 // Enter critical section\r
558 //\r
559 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
560\r
561 //\r
562 // Return EFI_SUCCESS if the (KeyData, NotificationFunction) is already registered.\r
563 //\r
564 for (Link = ConsoleInDev->NotifyList.ForwardLink; Link != &ConsoleInDev->NotifyList; Link = Link->ForwardLink) {\r
565 CurrentNotify = CR (\r
5829afe3 566 Link,\r
567 KEYBOARD_CONSOLE_IN_EX_NOTIFY,\r
568 NotifyEntry,\r
f3d1e940 569 KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE\r
570 );\r
5829afe3 571 if (IsKeyRegistered (&CurrentNotify->KeyData, KeyData)) {\r
f3d1e940 572 if (CurrentNotify->KeyNotificationFn == KeyNotificationFunction) {\r
5829afe3 573 *NotifyHandle = CurrentNotify->NotifyHandle;\r
f3d1e940 574 Status = EFI_SUCCESS;\r
575 goto Exit;\r
576 }\r
577 }\r
5829afe3 578 }\r
579\r
f3d1e940 580 //\r
581 // Allocate resource to save the notification function\r
5829afe3 582 //\r
f3d1e940 583 NewNotify = (KEYBOARD_CONSOLE_IN_EX_NOTIFY *) AllocateZeroPool (sizeof (KEYBOARD_CONSOLE_IN_EX_NOTIFY));\r
584 if (NewNotify == NULL) {\r
585 Status = EFI_OUT_OF_RESOURCES;\r
586 goto Exit;\r
587 }\r
588\r
5829afe3 589 NewNotify->Signature = KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE;\r
f3d1e940 590 NewNotify->KeyNotificationFn = KeyNotificationFunction;\r
7fc80d44 591 NewNotify->NotifyHandle = (EFI_HANDLE) NewNotify;\r
f3d1e940 592 CopyMem (&NewNotify->KeyData, KeyData, sizeof (EFI_KEY_DATA));\r
593 InsertTailList (&ConsoleInDev->NotifyList, &NewNotify->NotifyEntry);\r
594\r
5829afe3 595 *NotifyHandle = NewNotify->NotifyHandle;\r
f3d1e940 596 Status = EFI_SUCCESS;\r
597\r
598Exit:\r
599 //\r
600 // Leave critical section and return\r
601 //\r
602 gBS->RestoreTPL (OldTpl);\r
5829afe3 603 return Status;\r
f3d1e940 604\r
605}\r
606\r
bcd70414 607/**\r
608 Remove a registered notification function from a particular keystroke.\r
609\r
5829afe3 610 @param This Protocol instance pointer.\r
b6763e03 611 @param NotificationHandle The handle of the notification function being unregistered.\r
bcd70414 612\r
5829afe3 613\r
b6763e03 614 @retval EFI_SUCCESS The notification function was unregistered successfully.\r
615 @retval EFI_INVALID_PARAMETER The NotificationHandle is invalid.\r
5829afe3 616\r
617**/\r
f3d1e940 618EFI_STATUS\r
619EFIAPI\r
620KeyboardUnregisterKeyNotify (\r
621 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,\r
622 IN EFI_HANDLE NotificationHandle\r
623 )\r
f3d1e940 624{\r
625 EFI_STATUS Status;\r
626 KEYBOARD_CONSOLE_IN_DEV *ConsoleInDev;\r
627 EFI_TPL OldTpl;\r
628 LIST_ENTRY *Link;\r
5829afe3 629 KEYBOARD_CONSOLE_IN_EX_NOTIFY *CurrentNotify;\r
f3d1e940 630\r
631 if (NotificationHandle == NULL) {\r
632 return EFI_INVALID_PARAMETER;\r
5829afe3 633 }\r
0dc99784 634\r
635 if (((KEYBOARD_CONSOLE_IN_EX_NOTIFY *) NotificationHandle)->Signature != KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE) {\r
636 return EFI_INVALID_PARAMETER;\r
5829afe3 637 }\r
638\r
f3d1e940 639 ConsoleInDev = TEXT_INPUT_EX_KEYBOARD_CONSOLE_IN_DEV_FROM_THIS (This);\r
5829afe3 640\r
f3d1e940 641 //\r
642 // Enter critical section\r
643 //\r
5829afe3 644 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
f3d1e940 645\r
646 for (Link = ConsoleInDev->NotifyList.ForwardLink; Link != &ConsoleInDev->NotifyList; Link = Link->ForwardLink) {\r
647 CurrentNotify = CR (\r
5829afe3 648 Link,\r
649 KEYBOARD_CONSOLE_IN_EX_NOTIFY,\r
650 NotifyEntry,\r
f3d1e940 651 KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE\r
5829afe3 652 );\r
f3d1e940 653 if (CurrentNotify->NotifyHandle == NotificationHandle) {\r
654 //\r
655 // Remove the notification function from NotifyList and free resources\r
656 //\r
5829afe3 657 RemoveEntryList (&CurrentNotify->NotifyEntry);\r
658\r
659 gBS->FreePool (CurrentNotify);\r
f3d1e940 660 Status = EFI_SUCCESS;\r
661 goto Exit;\r
662 }\r
663 }\r
664\r
665 //\r
666 // Can not find the specified Notification Handle\r
667 //\r
8a67d804 668 Status = EFI_INVALID_PARAMETER;\r
f3d1e940 669Exit:\r
670 //\r
671 // Leave critical section and return\r
672 //\r
673 gBS->RestoreTPL (OldTpl);\r
674 return Status;\r
675}\r
676\r