]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - MdeModulePkg/Bus/Usb/UsbKbDxe/EfiKey.c
Use SimpleTextInEx.Reset to initialize correctly KeyToggleStatue and KeyShiftState...
[mirror_edk2.git] / MdeModulePkg / Bus / Usb / UsbKbDxe / EfiKey.c
... / ...
CommitLineData
1/** @file\r
2 USB Keyboard Driver that manages USB keyboard and produces Simple Text Input\r
3 Protocol and Simple Text Input Ex Protocol.\r
4\r
5Copyright (c) 2004 - 2010, Intel Corporation. All rights reserved.<BR>\r
6This program and the accompanying materials\r
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
13\r
14**/\r
15\r
16#include "EfiKey.h"\r
17#include "KeyBoard.h"\r
18\r
19//\r
20// USB Keyboard Driver Global Variables\r
21//\r
22EFI_DRIVER_BINDING_PROTOCOL gUsbKeyboardDriverBinding = {\r
23 USBKeyboardDriverBindingSupported,\r
24 USBKeyboardDriverBindingStart,\r
25 USBKeyboardDriverBindingStop,\r
26 0xa,\r
27 NULL,\r
28 NULL\r
29};\r
30\r
31/**\r
32 Entrypoint of USB Keyboard Driver.\r
33\r
34 This function is the entrypoint of USB Keyboard Driver. It installs Driver Binding\r
35 Protocols together with Component Name Protocols.\r
36\r
37 @param ImageHandle The firmware allocated handle for the EFI image.\r
38 @param SystemTable A pointer to the EFI System Table.\r
39\r
40 @retval EFI_SUCCESS The entry point is executed successfully.\r
41\r
42**/\r
43EFI_STATUS\r
44EFIAPI\r
45USBKeyboardDriverBindingEntryPoint (\r
46 IN EFI_HANDLE ImageHandle,\r
47 IN EFI_SYSTEM_TABLE *SystemTable\r
48 )\r
49{\r
50 EFI_STATUS Status;\r
51\r
52 Status = EfiLibInstallDriverBindingComponentName2 (\r
53 ImageHandle,\r
54 SystemTable,\r
55 &gUsbKeyboardDriverBinding,\r
56 ImageHandle,\r
57 &gUsbKeyboardComponentName,\r
58 &gUsbKeyboardComponentName2\r
59 );\r
60 ASSERT_EFI_ERROR (Status);\r
61\r
62 return EFI_SUCCESS;\r
63}\r
64\r
65/**\r
66 Check whether USB keyboard driver supports this device.\r
67\r
68 @param This The USB keyboard driver binding protocol.\r
69 @param Controller The controller handle to check.\r
70 @param RemainingDevicePath The remaining device path.\r
71\r
72 @retval EFI_SUCCESS The driver supports this controller.\r
73 @retval other This device isn't supported.\r
74\r
75**/\r
76EFI_STATUS\r
77EFIAPI\r
78USBKeyboardDriverBindingSupported (\r
79 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
80 IN EFI_HANDLE Controller,\r
81 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
82 )\r
83{\r
84 EFI_STATUS Status;\r
85 EFI_USB_IO_PROTOCOL *UsbIo;\r
86\r
87 //\r
88 // Check if USB I/O Protocol is attached on the controller handle.\r
89 //\r
90 Status = gBS->OpenProtocol (\r
91 Controller,\r
92 &gEfiUsbIoProtocolGuid,\r
93 (VOID **) &UsbIo,\r
94 This->DriverBindingHandle,\r
95 Controller,\r
96 EFI_OPEN_PROTOCOL_BY_DRIVER\r
97 );\r
98 if (EFI_ERROR (Status)) {\r
99 return Status;\r
100 }\r
101\r
102 //\r
103 // Use the USB I/O Protocol interface to check whether Controller is\r
104 // a keyboard device that can be managed by this driver.\r
105 //\r
106 Status = EFI_SUCCESS;\r
107\r
108 if (!IsUSBKeyboard (UsbIo)) {\r
109 Status = EFI_UNSUPPORTED;\r
110 }\r
111\r
112 gBS->CloseProtocol (\r
113 Controller,\r
114 &gEfiUsbIoProtocolGuid,\r
115 This->DriverBindingHandle,\r
116 Controller\r
117 );\r
118\r
119 return Status;\r
120}\r
121\r
122/**\r
123 Starts the keyboard device with this driver.\r
124\r
125 This function produces Simple Text Input Protocol and Simple Text Input Ex Protocol,\r
126 initializes the keyboard device, and submit Asynchronous Interrupt Transfer to manage\r
127 this keyboard device.\r
128\r
129 @param This The USB keyboard driver binding instance.\r
130 @param Controller Handle of device to bind driver to.\r
131 @param RemainingDevicePath Optional parameter use to pick a specific child\r
132 device to start.\r
133\r
134 @retval EFI_SUCCESS The controller is controlled by the usb keyboard driver.\r
135 @retval EFI_UNSUPPORTED No interrupt endpoint can be found.\r
136 @retval Other This controller cannot be started.\r
137\r
138**/\r
139EFI_STATUS\r
140EFIAPI\r
141USBKeyboardDriverBindingStart (\r
142 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
143 IN EFI_HANDLE Controller,\r
144 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
145 )\r
146{\r
147 EFI_STATUS Status;\r
148 EFI_USB_IO_PROTOCOL *UsbIo;\r
149 USB_KB_DEV *UsbKeyboardDevice;\r
150 UINT8 EndpointNumber;\r
151 EFI_USB_ENDPOINT_DESCRIPTOR EndpointDescriptor;\r
152 UINT8 Index;\r
153 UINT8 EndpointAddr;\r
154 UINT8 PollingInterval;\r
155 UINT8 PacketSize;\r
156 BOOLEAN Found;\r
157\r
158 //\r
159 // Open USB I/O Protocol\r
160 //\r
161 Status = gBS->OpenProtocol (\r
162 Controller,\r
163 &gEfiUsbIoProtocolGuid,\r
164 (VOID **) &UsbIo,\r
165 This->DriverBindingHandle,\r
166 Controller,\r
167 EFI_OPEN_PROTOCOL_BY_DRIVER\r
168 );\r
169 if (EFI_ERROR (Status)) {\r
170 return Status;\r
171 }\r
172\r
173 UsbKeyboardDevice = AllocateZeroPool (sizeof (USB_KB_DEV));\r
174 ASSERT (UsbKeyboardDevice != NULL);\r
175\r
176 //\r
177 // Get the Device Path Protocol on Controller's handle\r
178 //\r
179 Status = gBS->OpenProtocol (\r
180 Controller,\r
181 &gEfiDevicePathProtocolGuid,\r
182 (VOID **) &UsbKeyboardDevice->DevicePath,\r
183 This->DriverBindingHandle,\r
184 Controller,\r
185 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
186 );\r
187\r
188 if (EFI_ERROR (Status)) {\r
189 goto ErrorExit;\r
190 }\r
191 //\r
192 // Report that the USB 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 UsbKeyboardDevice->DevicePath\r
198 );\r
199\r
200 //\r
201 // This is pretty close to keyboard detection, so log progress\r
202 //\r
203 REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
204 EFI_PROGRESS_CODE,\r
205 (EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_PRESENCE_DETECT),\r
206 UsbKeyboardDevice->DevicePath\r
207 );\r
208\r
209 UsbKeyboardDevice->UsbIo = UsbIo;\r
210\r
211 //\r
212 // Get interface & endpoint descriptor\r
213 //\r
214 UsbIo->UsbGetInterfaceDescriptor (\r
215 UsbIo,\r
216 &UsbKeyboardDevice->InterfaceDescriptor\r
217 );\r
218\r
219 EndpointNumber = UsbKeyboardDevice->InterfaceDescriptor.NumEndpoints;\r
220\r
221 //\r
222 // Traverse endpoints to find interrupt endpoint\r
223 //\r
224 Found = FALSE;\r
225 for (Index = 0; Index < EndpointNumber; Index++) {\r
226\r
227 UsbIo->UsbGetEndpointDescriptor (\r
228 UsbIo,\r
229 Index,\r
230 &EndpointDescriptor\r
231 );\r
232\r
233 if ((EndpointDescriptor.Attributes & (BIT0 | BIT1)) == USB_ENDPOINT_INTERRUPT) {\r
234 //\r
235 // We only care interrupt endpoint here\r
236 //\r
237 CopyMem(&UsbKeyboardDevice->IntEndpointDescriptor, &EndpointDescriptor, sizeof(EndpointDescriptor));\r
238 Found = TRUE;\r
239 break;\r
240 }\r
241 }\r
242\r
243 if (!Found) {\r
244 //\r
245 // No interrupt endpoint found, then return unsupported.\r
246 //\r
247 Status = EFI_UNSUPPORTED;\r
248 goto ErrorExit;\r
249 }\r
250\r
251 UsbKeyboardDevice->Signature = USB_KB_DEV_SIGNATURE;\r
252 UsbKeyboardDevice->SimpleInput.Reset = USBKeyboardReset;\r
253 UsbKeyboardDevice->SimpleInput.ReadKeyStroke = USBKeyboardReadKeyStroke;\r
254\r
255 UsbKeyboardDevice->SimpleInputEx.Reset = USBKeyboardResetEx;\r
256 UsbKeyboardDevice->SimpleInputEx.ReadKeyStrokeEx = USBKeyboardReadKeyStrokeEx;\r
257 UsbKeyboardDevice->SimpleInputEx.SetState = USBKeyboardSetState;\r
258 UsbKeyboardDevice->SimpleInputEx.RegisterKeyNotify = USBKeyboardRegisterKeyNotify;\r
259 UsbKeyboardDevice->SimpleInputEx.UnregisterKeyNotify = USBKeyboardUnregisterKeyNotify;\r
260 \r
261 InitializeListHead (&UsbKeyboardDevice->NotifyList);\r
262 \r
263 Status = gBS->CreateEvent (\r
264 EVT_NOTIFY_WAIT,\r
265 TPL_NOTIFY,\r
266 USBKeyboardWaitForKey,\r
267 UsbKeyboardDevice,\r
268 &(UsbKeyboardDevice->SimpleInputEx.WaitForKeyEx)\r
269 );\r
270\r
271 if (EFI_ERROR (Status)) {\r
272 goto ErrorExit;\r
273 }\r
274\r
275 Status = gBS->CreateEvent (\r
276 EVT_NOTIFY_WAIT,\r
277 TPL_NOTIFY,\r
278 USBKeyboardWaitForKey,\r
279 UsbKeyboardDevice,\r
280 &(UsbKeyboardDevice->SimpleInput.WaitForKey)\r
281 );\r
282 if (EFI_ERROR (Status)) {\r
283 goto ErrorExit;\r
284 }\r
285\r
286 //\r
287 // Install Simple Text Input Protocol and Simple Text Input Ex Protocol\r
288 // for the USB keyboard device.\r
289 // USB keyboard is a hot plug device, and expected to work immediately\r
290 // when plugging into system, other conventional console devices could\r
291 // distinguish it by its device path.\r
292 //\r
293 Status = gBS->InstallMultipleProtocolInterfaces (\r
294 &Controller,\r
295 &gEfiSimpleTextInProtocolGuid,\r
296 &UsbKeyboardDevice->SimpleInput,\r
297 &gEfiSimpleTextInputExProtocolGuid,\r
298 &UsbKeyboardDevice->SimpleInputEx,\r
299 NULL\r
300 );\r
301 if (EFI_ERROR (Status)) {\r
302 goto ErrorExit;\r
303 }\r
304\r
305 UsbKeyboardDevice->ControllerHandle = Controller;\r
306 Status = InitKeyboardLayout (UsbKeyboardDevice);\r
307 if (EFI_ERROR (Status)) {\r
308 gBS->UninstallMultipleProtocolInterfaces (\r
309 Controller,\r
310 &gEfiSimpleTextInProtocolGuid,\r
311 &UsbKeyboardDevice->SimpleInput,\r
312 &gEfiSimpleTextInputExProtocolGuid,\r
313 &UsbKeyboardDevice->SimpleInputEx,\r
314 NULL\r
315 );\r
316 goto ErrorExit;\r
317 }\r
318\r
319\r
320 //\r
321 // Reset USB Keyboard Device exhaustively.\r
322 //\r
323 Status = UsbKeyboardDevice->SimpleInputEx.Reset (\r
324 &UsbKeyboardDevice->SimpleInputEx,\r
325 TRUE\r
326 );\r
327 if (EFI_ERROR (Status)) {\r
328 gBS->UninstallMultipleProtocolInterfaces (\r
329 Controller,\r
330 &gEfiSimpleTextInProtocolGuid,\r
331 &UsbKeyboardDevice->SimpleInput,\r
332 &gEfiSimpleTextInputExProtocolGuid,\r
333 &UsbKeyboardDevice->SimpleInputEx,\r
334 NULL\r
335 );\r
336 goto ErrorExit;\r
337 }\r
338\r
339 //\r
340 // Submit Asynchronous Interrupt Transfer to manage this device.\r
341 //\r
342 EndpointAddr = UsbKeyboardDevice->IntEndpointDescriptor.EndpointAddress;\r
343 PollingInterval = UsbKeyboardDevice->IntEndpointDescriptor.Interval;\r
344 PacketSize = (UINT8) (UsbKeyboardDevice->IntEndpointDescriptor.MaxPacketSize);\r
345\r
346 Status = UsbIo->UsbAsyncInterruptTransfer (\r
347 UsbIo,\r
348 EndpointAddr,\r
349 TRUE,\r
350 PollingInterval,\r
351 PacketSize,\r
352 KeyboardHandler,\r
353 UsbKeyboardDevice\r
354 );\r
355\r
356 if (EFI_ERROR (Status)) {\r
357 gBS->UninstallMultipleProtocolInterfaces (\r
358 Controller,\r
359 &gEfiSimpleTextInProtocolGuid,\r
360 &UsbKeyboardDevice->SimpleInput,\r
361 &gEfiSimpleTextInputExProtocolGuid,\r
362 &UsbKeyboardDevice->SimpleInputEx,\r
363 NULL\r
364 );\r
365 goto ErrorExit;\r
366 }\r
367\r
368 UsbKeyboardDevice->ControllerNameTable = NULL;\r
369 AddUnicodeString2 (\r
370 "eng",\r
371 gUsbKeyboardComponentName.SupportedLanguages,\r
372 &UsbKeyboardDevice->ControllerNameTable,\r
373 L"Generic Usb Keyboard",\r
374 TRUE\r
375 );\r
376 AddUnicodeString2 (\r
377 "en",\r
378 gUsbKeyboardComponentName2.SupportedLanguages,\r
379 &UsbKeyboardDevice->ControllerNameTable,\r
380 L"Generic Usb Keyboard",\r
381 FALSE\r
382 );\r
383\r
384 return EFI_SUCCESS;\r
385\r
386//\r
387// Error handler\r
388//\r
389ErrorExit:\r
390 if (UsbKeyboardDevice != NULL) {\r
391 if (UsbKeyboardDevice->SimpleInput.WaitForKey != NULL) {\r
392 gBS->CloseEvent (UsbKeyboardDevice->SimpleInput.WaitForKey);\r
393 }\r
394 if (UsbKeyboardDevice->SimpleInputEx.WaitForKeyEx != NULL) {\r
395 gBS->CloseEvent (UsbKeyboardDevice->SimpleInputEx.WaitForKeyEx);\r
396 }\r
397 if (UsbKeyboardDevice->KeyboardLayoutEvent != NULL) {\r
398 ReleaseKeyboardLayoutResources (UsbKeyboardDevice);\r
399 gBS->CloseEvent (UsbKeyboardDevice->KeyboardLayoutEvent);\r
400 }\r
401 FreePool (UsbKeyboardDevice);\r
402 UsbKeyboardDevice = NULL;\r
403 }\r
404 gBS->CloseProtocol (\r
405 Controller,\r
406 &gEfiUsbIoProtocolGuid,\r
407 This->DriverBindingHandle,\r
408 Controller\r
409 );\r
410 return Status;\r
411\r
412}\r
413\r
414\r
415/**\r
416 Stop the USB keyboard device handled by this driver.\r
417\r
418 @param This The USB keyboard driver binding protocol.\r
419 @param Controller The controller to release.\r
420 @param NumberOfChildren The number of handles in ChildHandleBuffer.\r
421 @param ChildHandleBuffer The array of child handle.\r
422\r
423 @retval EFI_SUCCESS The device was stopped.\r
424 @retval EFI_UNSUPPORTED Simple Text In Protocol or Simple Text In Ex Protocol\r
425 is not installed on Controller.\r
426 @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.\r
427 @retval Others Fail to uninstall protocols attached on the device.\r
428\r
429**/\r
430EFI_STATUS\r
431EFIAPI\r
432USBKeyboardDriverBindingStop (\r
433 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
434 IN EFI_HANDLE Controller,\r
435 IN UINTN NumberOfChildren,\r
436 IN EFI_HANDLE *ChildHandleBuffer\r
437 )\r
438{\r
439 EFI_STATUS Status;\r
440 EFI_SIMPLE_TEXT_INPUT_PROTOCOL *SimpleInput;\r
441 USB_KB_DEV *UsbKeyboardDevice;\r
442\r
443 Status = gBS->OpenProtocol (\r
444 Controller,\r
445 &gEfiSimpleTextInProtocolGuid,\r
446 (VOID **) &SimpleInput,\r
447 This->DriverBindingHandle,\r
448 Controller,\r
449 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
450 );\r
451 if (EFI_ERROR (Status)) {\r
452 return EFI_UNSUPPORTED;\r
453 }\r
454\r
455 Status = gBS->OpenProtocol (\r
456 Controller,\r
457 &gEfiSimpleTextInputExProtocolGuid,\r
458 NULL,\r
459 This->DriverBindingHandle,\r
460 Controller,\r
461 EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
462 );\r
463 if (EFI_ERROR (Status)) {\r
464 return EFI_UNSUPPORTED;\r
465 }\r
466\r
467 UsbKeyboardDevice = USB_KB_DEV_FROM_THIS (SimpleInput);\r
468\r
469 //\r
470 // The key data input from this device will be disabled.\r
471 //\r
472 REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
473 EFI_PROGRESS_CODE,\r
474 (EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_DISABLE),\r
475 UsbKeyboardDevice->DevicePath\r
476 );\r
477\r
478 //\r
479 // Delete the Asynchronous Interrupt Transfer from this device\r
480 //\r
481 UsbKeyboardDevice->UsbIo->UsbAsyncInterruptTransfer (\r
482 UsbKeyboardDevice->UsbIo,\r
483 UsbKeyboardDevice->IntEndpointDescriptor.EndpointAddress,\r
484 FALSE,\r
485 UsbKeyboardDevice->IntEndpointDescriptor.Interval,\r
486 0,\r
487 NULL,\r
488 NULL\r
489 );\r
490\r
491 gBS->CloseProtocol (\r
492 Controller,\r
493 &gEfiUsbIoProtocolGuid,\r
494 This->DriverBindingHandle,\r
495 Controller\r
496 );\r
497\r
498 Status = gBS->UninstallMultipleProtocolInterfaces (\r
499 Controller,\r
500 &gEfiSimpleTextInProtocolGuid,\r
501 &UsbKeyboardDevice->SimpleInput,\r
502 &gEfiSimpleTextInputExProtocolGuid,\r
503 &UsbKeyboardDevice->SimpleInputEx,\r
504 NULL\r
505 );\r
506 //\r
507 // Free all resources.\r
508 //\r
509 gBS->CloseEvent (UsbKeyboardDevice->RepeatTimer);\r
510 gBS->CloseEvent (UsbKeyboardDevice->DelayedRecoveryEvent);\r
511 gBS->CloseEvent ((UsbKeyboardDevice->SimpleInput).WaitForKey);\r
512 gBS->CloseEvent (UsbKeyboardDevice->SimpleInputEx.WaitForKeyEx); \r
513 KbdFreeNotifyList (&UsbKeyboardDevice->NotifyList); \r
514\r
515 ReleaseKeyboardLayoutResources (UsbKeyboardDevice);\r
516 gBS->CloseEvent (UsbKeyboardDevice->KeyboardLayoutEvent);\r
517\r
518 if (UsbKeyboardDevice->ControllerNameTable != NULL) {\r
519 FreeUnicodeStringTable (UsbKeyboardDevice->ControllerNameTable);\r
520 }\r
521\r
522 FreePool (UsbKeyboardDevice);\r
523\r
524 return Status;\r
525}\r
526\r
527/**\r
528 Internal function to read the next keystroke from the keyboard buffer.\r
529\r
530 @param UsbKeyboardDevice USB keyboard's private structure.\r
531 @param KeyData A pointer to buffer to hold the keystroke\r
532 data for the key that was pressed.\r
533\r
534 @retval EFI_SUCCESS The keystroke information was returned.\r
535 @retval EFI_NOT_READY There was no keystroke data availiable.\r
536 @retval EFI_DEVICE_ERROR The keystroke information was not returned due to\r
537 hardware errors.\r
538 @retval EFI_INVALID_PARAMETER KeyData is NULL.\r
539 @retval Others Fail to translate keycode into EFI_INPUT_KEY\r
540\r
541**/\r
542EFI_STATUS\r
543EFIAPI\r
544USBKeyboardReadKeyStrokeWorker (\r
545 IN OUT USB_KB_DEV *UsbKeyboardDevice,\r
546 OUT EFI_KEY_DATA *KeyData\r
547 )\r
548{\r
549 EFI_STATUS Status;\r
550 UINT8 KeyCode; \r
551 LIST_ENTRY *Link;\r
552 LIST_ENTRY *NotifyList;\r
553 KEYBOARD_CONSOLE_IN_EX_NOTIFY *CurrentNotify; \r
554 EFI_KEY_DATA OriginalKeyData;\r
555\r
556 if (KeyData == NULL) {\r
557 return EFI_INVALID_PARAMETER;\r
558 }\r
559\r
560 //\r
561 // If there is no saved USB keycode, fetch it\r
562 // by calling USBKeyboardCheckForKey().\r
563 //\r
564 if (UsbKeyboardDevice->CurKeyCode == 0) {\r
565 Status = USBKeyboardCheckForKey (UsbKeyboardDevice);\r
566 if (EFI_ERROR (Status)) {\r
567 return EFI_NOT_READY;\r
568 }\r
569 }\r
570\r
571 KeyData->Key.UnicodeChar = 0;\r
572 KeyData->Key.ScanCode = SCAN_NULL;\r
573\r
574 //\r
575 // Store the current keycode and clear it.\r
576 //\r
577 KeyCode = UsbKeyboardDevice->CurKeyCode;\r
578 UsbKeyboardDevice->CurKeyCode = 0;\r
579\r
580 //\r
581 // Translate saved USB keycode into EFI_INPUT_KEY\r
582 //\r
583 Status = UsbKeyCodeToEfiInputKey (UsbKeyboardDevice, KeyCode, &KeyData->Key);\r
584 if (EFI_ERROR (Status)) {\r
585 return Status;\r
586 }\r
587\r
588 //\r
589 // Get current state of various toggled attributes as well as input modifier values,\r
590 // and set them as valid.\r
591 //\r
592 CopyMem (&KeyData->KeyState, &UsbKeyboardDevice->KeyState, sizeof (KeyData->KeyState));\r
593 \r
594 UsbKeyboardDevice->KeyState.KeyShiftState = EFI_SHIFT_STATE_VALID;\r
595 UsbKeyboardDevice->KeyState.KeyToggleState = EFI_TOGGLE_STATE_VALID;\r
596\r
597 //\r
598 // Switch the control value to their original characters.\r
599 // In UsbKeyCodeToEfiInputKey() the CTRL-Alpha characters have been switched to \r
600 // their corresponding control value (ctrl-a = 0x0001 through ctrl-Z = 0x001A),\r
601 // here switch them back for notification function.\r
602 //\r
603 CopyMem (&OriginalKeyData, KeyData, sizeof (EFI_KEY_DATA));\r
604 if (UsbKeyboardDevice->CtrlOn) {\r
605 if (OriginalKeyData.Key.UnicodeChar >= 0x01 && OriginalKeyData.Key.UnicodeChar <= 0x1A) {\r
606 if (UsbKeyboardDevice->CapsOn) {\r
607 OriginalKeyData.Key.UnicodeChar = (CHAR16)(OriginalKeyData.Key.UnicodeChar + 'A' - 1);\r
608 } else {\r
609 OriginalKeyData.Key.UnicodeChar = (CHAR16)(OriginalKeyData.Key.UnicodeChar + 'a' - 1);\r
610 } \r
611 }\r
612 }\r
613 \r
614 //\r
615 // Invoke notification functions if the key is registered.\r
616 //\r
617 NotifyList = &UsbKeyboardDevice->NotifyList;\r
618 for (Link = GetFirstNode (NotifyList);\r
619 !IsNull (NotifyList, Link);\r
620 Link = GetNextNode (NotifyList, Link)) {\r
621 CurrentNotify = CR (Link, KEYBOARD_CONSOLE_IN_EX_NOTIFY, NotifyEntry, USB_KB_CONSOLE_IN_EX_NOTIFY_SIGNATURE);\r
622 if (IsKeyRegistered (&CurrentNotify->KeyData, &OriginalKeyData)) { \r
623 CurrentNotify->KeyNotificationFn (&OriginalKeyData);\r
624 }\r
625 }\r
626\r
627 return EFI_SUCCESS;\r
628}\r
629\r
630/**\r
631 Reset the input device and optionally run diagnostics\r
632\r
633 There are 2 types of reset for USB keyboard.\r
634 For non-exhaustive reset, only keyboard buffer is cleared.\r
635 For exhaustive reset, in addition to clearance of keyboard buffer, the hardware status\r
636 is also re-initialized.\r
637\r
638 @param This Protocol instance pointer.\r
639 @param ExtendedVerification Driver may perform diagnostics on reset.\r
640\r
641 @retval EFI_SUCCESS The device was reset.\r
642 @retval EFI_DEVICE_ERROR The device is not functioning properly and could not be reset.\r
643\r
644**/\r
645EFI_STATUS\r
646EFIAPI\r
647USBKeyboardReset (\r
648 IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,\r
649 IN BOOLEAN ExtendedVerification\r
650 )\r
651{\r
652 EFI_STATUS Status;\r
653 USB_KB_DEV *UsbKeyboardDevice;\r
654\r
655 UsbKeyboardDevice = USB_KB_DEV_FROM_THIS (This);\r
656\r
657 REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
658 EFI_PROGRESS_CODE,\r
659 (EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_RESET),\r
660 UsbKeyboardDevice->DevicePath\r
661 );\r
662\r
663 //\r
664 // Non-exhaustive reset:\r
665 // only reset private data structures.\r
666 //\r
667 if (!ExtendedVerification) {\r
668 REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
669 EFI_PROGRESS_CODE,\r
670 (EFI_PERIPHERAL_KEYBOARD | EFI_P_KEYBOARD_PC_CLEAR_BUFFER),\r
671 UsbKeyboardDevice->DevicePath\r
672 );\r
673 //\r
674 // Clear the key buffer of this USB keyboard\r
675 //\r
676 InitUSBKeyBuffer (&(UsbKeyboardDevice->KeyboardBuffer));\r
677 UsbKeyboardDevice->CurKeyCode = 0;\r
678\r
679 return EFI_SUCCESS;\r
680 }\r
681\r
682 //\r
683 // Exhaustive reset\r
684 //\r
685 Status = InitUSBKeyboard (UsbKeyboardDevice);\r
686 UsbKeyboardDevice->CurKeyCode = 0;\r
687 if (EFI_ERROR (Status)) {\r
688 return EFI_DEVICE_ERROR;\r
689 }\r
690\r
691 return EFI_SUCCESS;\r
692}\r
693\r
694\r
695/**\r
696 Reads the next keystroke from the input device.\r
697\r
698 @param This The EFI_SIMPLE_TEXT_INPUT_PROTOCOL instance.\r
699 @param Key A pointer to a buffer that is filled in with the keystroke\r
700 information for the key that was pressed.\r
701\r
702 @retval EFI_SUCCESS The keystroke information was returned.\r
703 @retval EFI_NOT_READY There was no keystroke data availiable.\r
704 @retval EFI_DEVICE_ERROR The keystroke information was not returned due to\r
705 hardware errors.\r
706\r
707**/\r
708EFI_STATUS\r
709EFIAPI\r
710USBKeyboardReadKeyStroke (\r
711 IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,\r
712 OUT EFI_INPUT_KEY *Key\r
713 )\r
714{\r
715 USB_KB_DEV *UsbKeyboardDevice;\r
716 EFI_STATUS Status;\r
717 EFI_KEY_DATA KeyData;\r
718\r
719 UsbKeyboardDevice = USB_KB_DEV_FROM_THIS (This);\r
720\r
721 Status = USBKeyboardReadKeyStrokeWorker (UsbKeyboardDevice, &KeyData);\r
722 if (EFI_ERROR (Status)) {\r
723 return Status;\r
724 }\r
725\r
726 CopyMem (Key, &KeyData.Key, sizeof (EFI_INPUT_KEY));\r
727\r
728 return EFI_SUCCESS;\r
729}\r
730\r
731\r
732/**\r
733 Event notification function registered for EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL.WaitForKeyEx\r
734 and EFI_SIMPLE_TEXT_INPUT_PROTOCOL.WaitForKey.\r
735\r
736 @param Event Event to be signaled when a key is pressed.\r
737 @param Context Points to USB_KB_DEV instance.\r
738\r
739**/\r
740VOID\r
741EFIAPI\r
742USBKeyboardWaitForKey (\r
743 IN EFI_EVENT Event,\r
744 IN VOID *Context\r
745 )\r
746{\r
747 USB_KB_DEV *UsbKeyboardDevice;\r
748\r
749 UsbKeyboardDevice = (USB_KB_DEV *) Context;\r
750\r
751 if (UsbKeyboardDevice->CurKeyCode == 0) {\r
752 if (EFI_ERROR (USBKeyboardCheckForKey (UsbKeyboardDevice))) {\r
753 //\r
754 // If no pending key, simply return.\r
755 //\r
756 return ;\r
757 }\r
758 }\r
759 //\r
760 // If there is pending key, signal the event.\r
761 //\r
762 gBS->SignalEvent (Event);\r
763}\r
764\r
765\r
766/**\r
767 Check whether there is key pending in the keyboard buffer.\r
768\r
769 @param UsbKeyboardDevice The USB_KB_DEV instance.\r
770\r
771 @retval EFI_SUCCESS There is pending key to read.\r
772 @retval EFI_NOT_READY No pending key to read.\r
773\r
774**/\r
775EFI_STATUS\r
776EFIAPI\r
777USBKeyboardCheckForKey (\r
778 IN OUT USB_KB_DEV *UsbKeyboardDevice\r
779 )\r
780{\r
781 EFI_STATUS Status;\r
782 UINT8 KeyCode;\r
783\r
784 //\r
785 // Fetch raw data from the USB keyboard buffer,\r
786 // and translate it into USB keycode.\r
787 //\r
788 Status = USBParseKey (UsbKeyboardDevice, &KeyCode);\r
789 if (EFI_ERROR (Status)) {\r
790 return EFI_NOT_READY;\r
791 }\r
792\r
793 UsbKeyboardDevice->CurKeyCode = KeyCode;\r
794 return EFI_SUCCESS;\r
795}\r
796\r
797/**\r
798 Free keyboard notify list.\r
799\r
800 @param NotifyList The keyboard notify list to free.\r
801\r
802 @retval EFI_SUCCESS Free the notify list successfully.\r
803 @retval EFI_INVALID_PARAMETER NotifyList is NULL.\r
804\r
805**/\r
806EFI_STATUS\r
807EFIAPI\r
808KbdFreeNotifyList (\r
809 IN OUT LIST_ENTRY *NotifyList\r
810 )\r
811{\r
812 KEYBOARD_CONSOLE_IN_EX_NOTIFY *NotifyNode;\r
813 LIST_ENTRY *Link;\r
814\r
815 if (NotifyList == NULL) {\r
816 return EFI_INVALID_PARAMETER;\r
817 }\r
818 while (!IsListEmpty (NotifyList)) {\r
819 Link = GetFirstNode (NotifyList);\r
820 NotifyNode = CR (Link, KEYBOARD_CONSOLE_IN_EX_NOTIFY, NotifyEntry, USB_KB_CONSOLE_IN_EX_NOTIFY_SIGNATURE);\r
821 RemoveEntryList (Link);\r
822 FreePool (NotifyNode);\r
823 }\r
824 \r
825 return EFI_SUCCESS;\r
826}\r
827\r
828/**\r
829 Check whether the pressed key matches a registered key or not.\r
830\r
831 @param RegsiteredData A pointer to keystroke data for the key that was registered.\r
832 @param InputData A pointer to keystroke data for the key that was pressed.\r
833\r
834 @retval TRUE Key pressed matches a registered key.\r
835 @retval FLASE Key pressed does not matches a registered key.\r
836\r
837**/\r
838BOOLEAN\r
839EFIAPI\r
840IsKeyRegistered (\r
841 IN EFI_KEY_DATA *RegsiteredData,\r
842 IN EFI_KEY_DATA *InputData\r
843 )\r
844{\r
845 ASSERT (RegsiteredData != NULL && InputData != NULL);\r
846 \r
847 if ((RegsiteredData->Key.ScanCode != InputData->Key.ScanCode) ||\r
848 (RegsiteredData->Key.UnicodeChar != InputData->Key.UnicodeChar)) {\r
849 return FALSE; \r
850 } \r
851 \r
852 //\r
853 // Assume KeyShiftState/KeyToggleState = 0 in Registered key data means these state could be ignored.\r
854 //\r
855 if (RegsiteredData->KeyState.KeyShiftState != 0 &&\r
856 RegsiteredData->KeyState.KeyShiftState != InputData->KeyState.KeyShiftState) {\r
857 return FALSE; \r
858 } \r
859 if (RegsiteredData->KeyState.KeyToggleState != 0 &&\r
860 RegsiteredData->KeyState.KeyToggleState != InputData->KeyState.KeyToggleState) {\r
861 return FALSE; \r
862 } \r
863 \r
864 return TRUE;\r
865}\r
866\r
867//\r
868// Simple Text Input Ex protocol functions \r
869//\r
870/**\r
871 Resets the input device hardware.\r
872\r
873 The Reset() function resets the input device hardware. As part\r
874 of initialization process, the firmware/device will make a quick\r
875 but reasonable attempt to verify that the device is functioning.\r
876 If the ExtendedVerification flag is TRUE the firmware may take\r
877 an extended amount of time to verify the device is operating on\r
878 reset. Otherwise the reset operation is to occur as quickly as\r
879 possible. The hardware verification process is not defined by\r
880 this specification and is left up to the platform firmware or\r
881 driver to implement.\r
882\r
883 @param This A pointer to the EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL instance.\r
884\r
885 @param ExtendedVerification Indicates that the driver may perform a more exhaustive\r
886 verification operation of the device during reset.\r
887\r
888 @retval EFI_SUCCESS The device was reset.\r
889 @retval EFI_DEVICE_ERROR The device is not functioning correctly and could not be reset.\r
890\r
891**/\r
892EFI_STATUS\r
893EFIAPI\r
894USBKeyboardResetEx (\r
895 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,\r
896 IN BOOLEAN ExtendedVerification\r
897 )\r
898{\r
899 EFI_STATUS Status;\r
900 USB_KB_DEV *UsbKeyboardDevice;\r
901 EFI_TPL OldTpl;\r
902 \r
903\r
904 UsbKeyboardDevice = TEXT_INPUT_EX_USB_KB_DEV_FROM_THIS (This);\r
905\r
906 Status = UsbKeyboardDevice->SimpleInput.Reset (&UsbKeyboardDevice->SimpleInput, ExtendedVerification);\r
907 if (EFI_ERROR (Status)) {\r
908 return EFI_DEVICE_ERROR;\r
909 }\r
910\r
911 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
912 UsbKeyboardDevice->KeyState.KeyShiftState = EFI_SHIFT_STATE_VALID;\r
913 UsbKeyboardDevice->KeyState.KeyToggleState = EFI_TOGGLE_STATE_VALID;\r
914 gBS->RestoreTPL (OldTpl);\r
915\r
916 return EFI_SUCCESS;\r
917\r
918}\r
919\r
920/**\r
921 Reads the next keystroke from the input device.\r
922\r
923 @param This Protocol instance pointer.\r
924 @param KeyData A pointer to a buffer that is filled in with the keystroke\r
925 state data for the key that was pressed.\r
926\r
927 @retval EFI_SUCCESS The keystroke information was returned.\r
928 @retval EFI_NOT_READY There was no keystroke data available.\r
929 @retval EFI_DEVICE_ERROR The keystroke information was not returned due to\r
930 hardware errors.\r
931 @retval EFI_INVALID_PARAMETER KeyData is NULL.\r
932\r
933**/\r
934EFI_STATUS\r
935EFIAPI\r
936USBKeyboardReadKeyStrokeEx (\r
937 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,\r
938 OUT EFI_KEY_DATA *KeyData\r
939 )\r
940{\r
941 USB_KB_DEV *UsbKeyboardDevice;\r
942\r
943 if (KeyData == NULL) {\r
944 return EFI_INVALID_PARAMETER;\r
945 }\r
946\r
947 UsbKeyboardDevice = TEXT_INPUT_EX_USB_KB_DEV_FROM_THIS (This);\r
948\r
949 return USBKeyboardReadKeyStrokeWorker (UsbKeyboardDevice, KeyData);\r
950 \r
951}\r
952\r
953/**\r
954 Set certain state for the input device.\r
955\r
956 @param This Protocol instance pointer.\r
957 @param KeyToggleState A pointer to the EFI_KEY_TOGGLE_STATE to set the\r
958 state for the input device.\r
959\r
960 @retval EFI_SUCCESS The device state was set appropriately.\r
961 @retval EFI_DEVICE_ERROR The device is not functioning correctly and could\r
962 not have the setting adjusted.\r
963 @retval EFI_UNSUPPORTED The device does not support the ability to have its state set.\r
964 @retval EFI_INVALID_PARAMETER KeyToggleState is NULL.\r
965\r
966**/\r
967EFI_STATUS\r
968EFIAPI\r
969USBKeyboardSetState (\r
970 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,\r
971 IN EFI_KEY_TOGGLE_STATE *KeyToggleState\r
972 )\r
973{\r
974 USB_KB_DEV *UsbKeyboardDevice;\r
975\r
976 if (KeyToggleState == NULL) {\r
977 return EFI_INVALID_PARAMETER;\r
978 }\r
979\r
980 UsbKeyboardDevice = TEXT_INPUT_EX_USB_KB_DEV_FROM_THIS (This);\r
981\r
982 if (((UsbKeyboardDevice->KeyState.KeyToggleState & EFI_TOGGLE_STATE_VALID) != EFI_TOGGLE_STATE_VALID) ||\r
983 ((*KeyToggleState & EFI_TOGGLE_STATE_VALID) != EFI_TOGGLE_STATE_VALID)) {\r
984 return EFI_UNSUPPORTED;\r
985 }\r
986\r
987 //\r
988 // Update the status light\r
989 //\r
990\r
991 UsbKeyboardDevice->ScrollOn = FALSE;\r
992 UsbKeyboardDevice->NumLockOn = FALSE;\r
993 UsbKeyboardDevice->CapsOn = FALSE;\r
994 \r
995 if ((*KeyToggleState & EFI_SCROLL_LOCK_ACTIVE) == EFI_SCROLL_LOCK_ACTIVE) {\r
996 UsbKeyboardDevice->ScrollOn = TRUE;\r
997 }\r
998 if ((*KeyToggleState & EFI_NUM_LOCK_ACTIVE) == EFI_NUM_LOCK_ACTIVE) {\r
999 UsbKeyboardDevice->NumLockOn = TRUE;\r
1000 }\r
1001 if ((*KeyToggleState & EFI_CAPS_LOCK_ACTIVE) == EFI_CAPS_LOCK_ACTIVE) {\r
1002 UsbKeyboardDevice->CapsOn = TRUE;\r
1003 }\r
1004\r
1005 SetKeyLED (UsbKeyboardDevice);\r
1006\r
1007 UsbKeyboardDevice->KeyState.KeyToggleState = *KeyToggleState;\r
1008\r
1009 return EFI_SUCCESS;\r
1010 \r
1011}\r
1012\r
1013/**\r
1014 Register a notification function for a particular keystroke for the input device.\r
1015\r
1016 @param This Protocol instance pointer.\r
1017 @param KeyData A pointer to a buffer that is filled in with the keystroke\r
1018 information data for the key that was pressed.\r
1019 @param KeyNotificationFunction Points to the function to be called when the key\r
1020 sequence is typed specified by KeyData.\r
1021 @param NotifyHandle Points to the unique handle assigned to the registered notification.\r
1022\r
1023 @retval EFI_SUCCESS The notification function was registered successfully.\r
1024 @retval EFI_OUT_OF_RESOURCES Unable to allocate resources for necessary data structures.\r
1025 @retval EFI_INVALID_PARAMETER KeyData or NotifyHandle or KeyNotificationFunction is NULL.\r
1026\r
1027**/\r
1028EFI_STATUS\r
1029EFIAPI\r
1030USBKeyboardRegisterKeyNotify (\r
1031 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,\r
1032 IN EFI_KEY_DATA *KeyData,\r
1033 IN EFI_KEY_NOTIFY_FUNCTION KeyNotificationFunction,\r
1034 OUT EFI_HANDLE *NotifyHandle\r
1035 )\r
1036{\r
1037 USB_KB_DEV *UsbKeyboardDevice;\r
1038 KEYBOARD_CONSOLE_IN_EX_NOTIFY *NewNotify;\r
1039 LIST_ENTRY *Link;\r
1040 LIST_ENTRY *NotifyList;\r
1041 KEYBOARD_CONSOLE_IN_EX_NOTIFY *CurrentNotify; \r
1042\r
1043 if (KeyData == NULL || NotifyHandle == NULL || KeyNotificationFunction == NULL) {\r
1044 return EFI_INVALID_PARAMETER;\r
1045 }\r
1046\r
1047 UsbKeyboardDevice = TEXT_INPUT_EX_USB_KB_DEV_FROM_THIS (This);\r
1048\r
1049 //\r
1050 // Return EFI_SUCCESS if the (KeyData, NotificationFunction) is already registered.\r
1051 //\r
1052 NotifyList = &UsbKeyboardDevice->NotifyList;\r
1053 \r
1054 for (Link = GetFirstNode (NotifyList);\r
1055 !IsNull (NotifyList, Link);\r
1056 Link = GetNextNode (NotifyList, Link)) {\r
1057 CurrentNotify = CR (\r
1058 Link, \r
1059 KEYBOARD_CONSOLE_IN_EX_NOTIFY, \r
1060 NotifyEntry, \r
1061 USB_KB_CONSOLE_IN_EX_NOTIFY_SIGNATURE\r
1062 );\r
1063 if (IsKeyRegistered (&CurrentNotify->KeyData, KeyData)) { \r
1064 if (CurrentNotify->KeyNotificationFn == KeyNotificationFunction) {\r
1065 *NotifyHandle = CurrentNotify->NotifyHandle; \r
1066 return EFI_SUCCESS;\r
1067 }\r
1068 }\r
1069 }\r
1070 \r
1071 //\r
1072 // Allocate resource to save the notification function\r
1073 // \r
1074 NewNotify = (KEYBOARD_CONSOLE_IN_EX_NOTIFY *) AllocateZeroPool (sizeof (KEYBOARD_CONSOLE_IN_EX_NOTIFY));\r
1075 if (NewNotify == NULL) {\r
1076 return EFI_OUT_OF_RESOURCES;\r
1077 }\r
1078\r
1079 NewNotify->Signature = USB_KB_CONSOLE_IN_EX_NOTIFY_SIGNATURE; \r
1080 NewNotify->KeyNotificationFn = KeyNotificationFunction;\r
1081 NewNotify->NotifyHandle = (EFI_HANDLE) NewNotify;\r
1082 CopyMem (&NewNotify->KeyData, KeyData, sizeof (EFI_KEY_DATA));\r
1083 InsertTailList (&UsbKeyboardDevice->NotifyList, &NewNotify->NotifyEntry);\r
1084\r
1085\r
1086 *NotifyHandle = NewNotify->NotifyHandle; \r
1087 \r
1088 return EFI_SUCCESS;\r
1089 \r
1090}\r
1091\r
1092/**\r
1093 Remove a registered notification function from a particular keystroke.\r
1094\r
1095 @param This Protocol instance pointer.\r
1096 @param NotificationHandle The handle of the notification function being unregistered.\r
1097\r
1098 @retval EFI_SUCCESS The notification function was unregistered successfully.\r
1099 @retval EFI_INVALID_PARAMETER The NotificationHandle is invalid\r
1100\r
1101**/\r
1102EFI_STATUS\r
1103EFIAPI\r
1104USBKeyboardUnregisterKeyNotify (\r
1105 IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,\r
1106 IN EFI_HANDLE NotificationHandle\r
1107 )\r
1108{\r
1109 USB_KB_DEV *UsbKeyboardDevice;\r
1110 KEYBOARD_CONSOLE_IN_EX_NOTIFY *CurrentNotify;\r
1111 LIST_ENTRY *Link;\r
1112 LIST_ENTRY *NotifyList;\r
1113\r
1114 if (NotificationHandle == NULL) {\r
1115 return EFI_INVALID_PARAMETER;\r
1116 } \r
1117\r
1118 if (((KEYBOARD_CONSOLE_IN_EX_NOTIFY *) NotificationHandle)->Signature != USB_KB_CONSOLE_IN_EX_NOTIFY_SIGNATURE) {\r
1119 return EFI_INVALID_PARAMETER;\r
1120 } \r
1121 \r
1122 UsbKeyboardDevice = TEXT_INPUT_EX_USB_KB_DEV_FROM_THIS (This);\r
1123 \r
1124 //\r
1125 // Traverse notify list of USB keyboard and remove the entry of NotificationHandle.\r
1126 //\r
1127 NotifyList = &UsbKeyboardDevice->NotifyList;\r
1128 for (Link = GetFirstNode (NotifyList);\r
1129 !IsNull (NotifyList, Link);\r
1130 Link = GetNextNode (NotifyList, Link)) {\r
1131 CurrentNotify = CR (\r
1132 Link, \r
1133 KEYBOARD_CONSOLE_IN_EX_NOTIFY, \r
1134 NotifyEntry, \r
1135 USB_KB_CONSOLE_IN_EX_NOTIFY_SIGNATURE\r
1136 ); \r
1137 if (CurrentNotify->NotifyHandle == NotificationHandle) {\r
1138 //\r
1139 // Remove the notification function from NotifyList and free resources\r
1140 //\r
1141 RemoveEntryList (&CurrentNotify->NotifyEntry); \r
1142\r
1143 FreePool (CurrentNotify); \r
1144 return EFI_SUCCESS;\r
1145 }\r
1146 }\r
1147\r
1148 //\r
1149 // Cannot find the matching entry in database.\r
1150 //\r
1151 return EFI_INVALID_PARAMETER; \r
1152}\r
1153\r