1. Sync Tcp4 protocol definitions to match UEFI 2.1
[people/mcb30/edk2.git] / edk2 / MdeModulePkg / Bus / Usb / UsbKbDxe / efikey.c
1 /** @file\r
2 \r
3 Copyright (c) 2004 - 2007, Intel Corporation\r
4 All rights reserved. This program and the accompanying materials\r
5 are licensed and made available under the terms and conditions of the BSD License\r
6 which accompanies this distribution.  The full text of the license may be found at\r
7 http://opensource.org/licenses/bsd-license.php\r
8 \r
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
11 \r
12 Module Name:\r
13 \r
14   EfiKey.c\r
15 \r
16 Abstract:\r
17 \r
18   USB Keyboard Driver\r
19 \r
20 Revision History\r
21 \r
22 \r
23 **/\r
24 \r
25 #include "efikey.h"\r
26 #include "keyboard.h"\r
27 \r
28 //\r
29 // Prototypes\r
30 // Driver model protocol interface\r
31 //\r
32 EFI_STATUS\r
33 EFIAPI\r
34 USBKeyboardDriverBindingEntryPoint (\r
35   IN EFI_HANDLE           ImageHandle,\r
36   IN EFI_SYSTEM_TABLE     *SystemTable\r
37   );\r
38 \r
39 EFI_STATUS\r
40 EFIAPI\r
41 USBKeyboardDriverBindingSupported (\r
42   IN EFI_DRIVER_BINDING_PROTOCOL    *This,\r
43   IN EFI_HANDLE                     Controller,\r
44   IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath\r
45   );\r
46 \r
47 EFI_STATUS\r
48 EFIAPI\r
49 USBKeyboardDriverBindingStart (\r
50   IN EFI_DRIVER_BINDING_PROTOCOL    *This,\r
51   IN EFI_HANDLE                     Controller,\r
52   IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath\r
53   );\r
54 \r
55 EFI_STATUS\r
56 EFIAPI\r
57 USBKeyboardDriverBindingStop (\r
58   IN  EFI_DRIVER_BINDING_PROTOCOL    *This,\r
59   IN  EFI_HANDLE                     Controller,\r
60   IN  UINTN                          NumberOfChildren,\r
61   IN  EFI_HANDLE                     *ChildHandleBuffer\r
62   );\r
63 \r
64 //\r
65 // Simple Text In Protocol Interface\r
66 //\r
67 STATIC\r
68 EFI_STATUS\r
69 EFIAPI\r
70 USBKeyboardReset (\r
71   IN  EFI_SIMPLE_TEXT_INPUT_PROTOCOL  *This,\r
72   IN  BOOLEAN                      ExtendedVerification\r
73   );\r
74 \r
75 STATIC\r
76 EFI_STATUS\r
77 EFIAPI\r
78 USBKeyboardReadKeyStroke (\r
79   IN  EFI_SIMPLE_TEXT_INPUT_PROTOCOL   *This,\r
80   OUT EFI_INPUT_KEY                 *Key\r
81   );\r
82 \r
83 STATIC\r
84 VOID\r
85 EFIAPI\r
86 USBKeyboardWaitForKey (\r
87   IN  EFI_EVENT               Event,\r
88   IN  VOID                    *Context\r
89   );\r
90 \r
91 //\r
92 //  Helper functions\r
93 //\r
94 STATIC\r
95 EFI_STATUS\r
96 USBKeyboardCheckForKey (\r
97   IN  USB_KB_DEV      *UsbKeyboardDevice\r
98   );\r
99 \r
100 EFI_GUID  gEfiUsbKeyboardDriverGuid = {\r
101   0xa05f5f78, 0xfb3, 0x4d10, {0x90, 0x90, 0xac, 0x4, 0x6e, 0xeb, 0x7c, 0x3c}\r
102 };\r
103 \r
104 //\r
105 // USB Keyboard Driver Global Variables\r
106 //\r
107 EFI_DRIVER_BINDING_PROTOCOL gUsbKeyboardDriverBinding = {\r
108   USBKeyboardDriverBindingSupported,\r
109   USBKeyboardDriverBindingStart,\r
110   USBKeyboardDriverBindingStop,\r
111   0xa,\r
112   NULL,\r
113   NULL\r
114 };\r
115 \r
116 EFI_STATUS\r
117 EFIAPI\r
118 USBKeyboardDriverBindingEntryPoint (\r
119   IN EFI_HANDLE           ImageHandle,\r
120   IN EFI_SYSTEM_TABLE     *SystemTable\r
121   )\r
122 /*++\r
123 \r
124   Routine Description:\r
125     Driver Entry Point.\r
126 \r
127   Arguments:\r
128     ImageHandle - EFI_HANDLE\r
129     SystemTable - EFI_SYSTEM_TABLE\r
130   Returns:\r
131     EFI_STATUS\r
132 \r
133 --*/\r
134 {\r
135   return EfiLibInstallAllDriverProtocols (\r
136           ImageHandle,\r
137           SystemTable,\r
138           &gUsbKeyboardDriverBinding,\r
139           ImageHandle,\r
140           &gUsbKeyboardComponentName,\r
141           NULL,\r
142           NULL\r
143           );\r
144 }\r
145 \r
146 \r
147 \r
148 /**\r
149   Supported.\r
150 \r
151   @param  This                  EFI_DRIVER_BINDING_PROTOCOL\r
152   @param  Controller            Controller handle\r
153   @param  RemainingDevicePath   EFI_DEVICE_PATH_PROTOCOL\r
154  EFI_STATUS\r
155 \r
156 **/\r
157 EFI_STATUS\r
158 EFIAPI\r
159 USBKeyboardDriverBindingSupported (\r
160   IN EFI_DRIVER_BINDING_PROTOCOL    *This,\r
161   IN EFI_HANDLE                     Controller,\r
162   IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath\r
163   )\r
164 {\r
165   EFI_STATUS          OpenStatus;\r
166   EFI_USB_IO_PROTOCOL *UsbIo;\r
167   EFI_STATUS          Status;\r
168 \r
169   //\r
170   // Check if USB_IO protocol is attached on the controller handle.\r
171   //\r
172   OpenStatus = gBS->OpenProtocol (\r
173                       Controller,\r
174                       &gEfiUsbIoProtocolGuid,\r
175                       (VOID **) &UsbIo,\r
176                       This->DriverBindingHandle,\r
177                       Controller,\r
178                       EFI_OPEN_PROTOCOL_BY_DRIVER\r
179                       );\r
180   if (EFI_ERROR (OpenStatus)) {\r
181     return OpenStatus;\r
182   }\r
183 \r
184   //\r
185   // Use the USB I/O protocol interface to check whether the Controller is\r
186   // the Keyboard controller that can be managed by this driver.\r
187   //\r
188   Status = EFI_SUCCESS;\r
189 \r
190   if (!IsUSBKeyboard (UsbIo)) {\r
191     Status = EFI_UNSUPPORTED;\r
192   }\r
193 \r
194   gBS->CloseProtocol (\r
195         Controller,\r
196         &gEfiUsbIoProtocolGuid,\r
197         This->DriverBindingHandle,\r
198         Controller\r
199         );\r
200 \r
201   return Status;\r
202 }\r
203 \r
204 \r
205 /**\r
206   Start.\r
207 \r
208   @param  This                  EFI_DRIVER_BINDING_PROTOCOL\r
209   @param  Controller            Controller handle\r
210   @param  RemainingDevicePath   EFI_DEVICE_PATH_PROTOCOL\r
211 \r
212   @retval EFI_SUCCESS           Success\r
213   @retval EFI_OUT_OF_RESOURCES  Can't allocate memory\r
214   @retval EFI_UNSUPPORTED       The Start routine fail\r
215 \r
216 **/\r
217 EFI_STATUS\r
218 EFIAPI\r
219 USBKeyboardDriverBindingStart (\r
220   IN EFI_DRIVER_BINDING_PROTOCOL    *This,\r
221   IN EFI_HANDLE                     Controller,\r
222   IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath\r
223   )\r
224 {\r
225   EFI_STATUS                    Status;\r
226   EFI_USB_IO_PROTOCOL           *UsbIo;\r
227   USB_KB_DEV                    *UsbKeyboardDevice;\r
228   UINT8                         EndpointNumber;\r
229   EFI_USB_ENDPOINT_DESCRIPTOR   EndpointDescriptor;\r
230   UINT8                         Index;\r
231   UINT8                         EndpointAddr;\r
232   UINT8                         PollingInterval;\r
233   UINT8                         PacketSize;\r
234   BOOLEAN                       Found;\r
235 \r
236   UsbKeyboardDevice = NULL;\r
237   Found             = FALSE;\r
238 \r
239   //\r
240   // Open USB_IO Protocol\r
241   //\r
242   Status = gBS->OpenProtocol (\r
243                   Controller,\r
244                   &gEfiUsbIoProtocolGuid,\r
245                   (VOID **) &UsbIo,\r
246                   This->DriverBindingHandle,\r
247                   Controller,\r
248                   EFI_OPEN_PROTOCOL_BY_DRIVER\r
249                   );\r
250   if (EFI_ERROR (Status)) {\r
251     return Status;\r
252   }\r
253 \r
254   UsbKeyboardDevice = AllocateZeroPool (sizeof (USB_KB_DEV));\r
255   if (UsbKeyboardDevice == NULL) {\r
256     gBS->CloseProtocol (\r
257           Controller,\r
258           &gEfiUsbIoProtocolGuid,\r
259           This->DriverBindingHandle,\r
260           Controller\r
261           );\r
262     return EFI_OUT_OF_RESOURCES;\r
263   }\r
264   //\r
265   // Get the Device Path Protocol on Controller's handle\r
266   //\r
267   Status = gBS->OpenProtocol (\r
268                   Controller,\r
269                   &gEfiDevicePathProtocolGuid,\r
270                   (VOID **) &UsbKeyboardDevice->DevicePath,\r
271                   This->DriverBindingHandle,\r
272                   Controller,\r
273                   EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
274                   );\r
275 \r
276   if (EFI_ERROR (Status)) {\r
277     gBS->FreePool (UsbKeyboardDevice);\r
278     gBS->CloseProtocol (\r
279           Controller,\r
280           &gEfiUsbIoProtocolGuid,\r
281           This->DriverBindingHandle,\r
282           Controller\r
283           );\r
284     return Status;\r
285   }\r
286   //\r
287   // Report that the usb keyboard is being enabled\r
288   //\r
289   KbdReportStatusCode (\r
290     UsbKeyboardDevice->DevicePath,\r
291     EFI_PROGRESS_CODE,\r
292     PcdGet32 (PcdStatusCodeValueKeyboardEnable)\r
293     );\r
294 \r
295   //\r
296   // This is pretty close to keyboard detection, so log progress\r
297   //\r
298   KbdReportStatusCode (\r
299     UsbKeyboardDevice->DevicePath,\r
300     EFI_PROGRESS_CODE,\r
301     PcdGet32 (PcdStatusCodeValueKeyboardPresenceDetect)\r
302     );\r
303 \r
304   //\r
305   // Initialize UsbKeyboardDevice\r
306   //\r
307   UsbKeyboardDevice->UsbIo = UsbIo;\r
308 \r
309   //\r
310   // Get interface & endpoint descriptor\r
311   //\r
312   UsbIo->UsbGetInterfaceDescriptor (\r
313           UsbIo,\r
314           &UsbKeyboardDevice->InterfaceDescriptor\r
315           );\r
316 \r
317   EndpointNumber = UsbKeyboardDevice->InterfaceDescriptor.NumEndpoints;\r
318 \r
319   for (Index = 0; Index < EndpointNumber; Index++) {\r
320 \r
321     UsbIo->UsbGetEndpointDescriptor (\r
322             UsbIo,\r
323             Index,\r
324             &EndpointDescriptor\r
325             );\r
326 \r
327     if ((EndpointDescriptor.Attributes & 0x03) == 0x03) {\r
328       //\r
329       // We only care interrupt endpoint here\r
330       //\r
331       CopyMem(&UsbKeyboardDevice->IntEndpointDescriptor, &EndpointDescriptor, sizeof(EndpointDescriptor));\r
332       Found = TRUE;\r
333     }\r
334   }\r
335 \r
336   if (!Found) {\r
337     //\r
338     // No interrupt endpoint found, then return unsupported.\r
339     //\r
340     gBS->FreePool (UsbKeyboardDevice);\r
341     gBS->CloseProtocol (\r
342           Controller,\r
343           &gEfiUsbIoProtocolGuid,\r
344           This->DriverBindingHandle,\r
345           Controller\r
346           );\r
347     return EFI_UNSUPPORTED;\r
348   }\r
349 \r
350   UsbKeyboardDevice->Signature                  = USB_KB_DEV_SIGNATURE;\r
351   UsbKeyboardDevice->SimpleInput.Reset          = USBKeyboardReset;\r
352   UsbKeyboardDevice->SimpleInput.ReadKeyStroke  = USBKeyboardReadKeyStroke;\r
353   Status = gBS->CreateEvent (\r
354                   EVT_NOTIFY_WAIT,\r
355                   TPL_NOTIFY,\r
356                   USBKeyboardWaitForKey,\r
357                   UsbKeyboardDevice,\r
358                   &(UsbKeyboardDevice->SimpleInput.WaitForKey)\r
359                   );\r
360 \r
361   if (EFI_ERROR (Status)) {\r
362     gBS->FreePool (UsbKeyboardDevice);\r
363     gBS->CloseProtocol (\r
364           Controller,\r
365           &gEfiUsbIoProtocolGuid,\r
366           This->DriverBindingHandle,\r
367           Controller\r
368           );\r
369     return Status;\r
370   }\r
371 \r
372   //\r
373   // Install simple txt in protocol interface\r
374   // for the usb keyboard device.\r
375   // Usb keyboard is a hot plug device, and expected to work immediately\r
376   // when plugging into system, so a HotPlugDeviceGuid is installed onto\r
377   // the usb keyboard device handle, to distinguish it from other conventional\r
378   // console devices.\r
379   //\r
380   Status = gBS->InstallMultipleProtocolInterfaces (\r
381                   &Controller,\r
382                   &gEfiSimpleTextInProtocolGuid,\r
383                   &UsbKeyboardDevice->SimpleInput,\r
384                   &gEfiHotPlugDeviceGuid,\r
385                   NULL,\r
386                   NULL\r
387                   );\r
388   if (EFI_ERROR (Status)) {\r
389     gBS->CloseEvent (UsbKeyboardDevice->SimpleInput.WaitForKey);\r
390     gBS->FreePool (UsbKeyboardDevice);\r
391     gBS->CloseProtocol (\r
392           Controller,\r
393           &gEfiUsbIoProtocolGuid,\r
394           This->DriverBindingHandle,\r
395           Controller\r
396           );\r
397     return Status;\r
398   }\r
399 \r
400   //\r
401   // Reset USB Keyboard Device\r
402   //\r
403   Status = UsbKeyboardDevice->SimpleInput.Reset (\r
404                                             &UsbKeyboardDevice->SimpleInput,\r
405                                             TRUE\r
406                                             );\r
407   if (EFI_ERROR (Status)) {\r
408     gBS->UninstallMultipleProtocolInterfaces (\r
409           Controller,\r
410           &gEfiSimpleTextInProtocolGuid,\r
411           &UsbKeyboardDevice->SimpleInput,\r
412           &gEfiHotPlugDeviceGuid,\r
413           NULL,\r
414           NULL\r
415           );\r
416     gBS->CloseEvent (UsbKeyboardDevice->SimpleInput.WaitForKey);\r
417     gBS->FreePool (UsbKeyboardDevice);\r
418     gBS->CloseProtocol (\r
419           Controller,\r
420           &gEfiUsbIoProtocolGuid,\r
421           This->DriverBindingHandle,\r
422           Controller\r
423           );\r
424     return Status;\r
425   }\r
426   //\r
427   // submit async interrupt transfer\r
428   //\r
429   EndpointAddr    = UsbKeyboardDevice->IntEndpointDescriptor.EndpointAddress;\r
430   PollingInterval = UsbKeyboardDevice->IntEndpointDescriptor.Interval;\r
431   PacketSize      = (UINT8) (UsbKeyboardDevice->IntEndpointDescriptor.MaxPacketSize);\r
432 \r
433   Status = UsbIo->UsbAsyncInterruptTransfer (\r
434                     UsbIo,\r
435                     EndpointAddr,\r
436                     TRUE,\r
437                     PollingInterval,\r
438                     PacketSize,\r
439                     KeyboardHandler,\r
440                     UsbKeyboardDevice\r
441                     );\r
442 \r
443   if (EFI_ERROR (Status)) {\r
444 \r
445     gBS->UninstallMultipleProtocolInterfaces (\r
446           Controller,\r
447           &gEfiSimpleTextInProtocolGuid,\r
448           &UsbKeyboardDevice->SimpleInput,\r
449           &gEfiHotPlugDeviceGuid,\r
450           NULL,\r
451           NULL\r
452           );\r
453     gBS->CloseEvent (UsbKeyboardDevice->SimpleInput.WaitForKey);\r
454     gBS->FreePool (UsbKeyboardDevice);\r
455     gBS->CloseProtocol (\r
456           Controller,\r
457           &gEfiUsbIoProtocolGuid,\r
458           This->DriverBindingHandle,\r
459           Controller\r
460           );\r
461     return Status;\r
462   }\r
463 \r
464   UsbKeyboardDevice->ControllerNameTable = NULL;\r
465   AddUnicodeString (\r
466     "eng",\r
467     gUsbKeyboardComponentName.SupportedLanguages,\r
468     &UsbKeyboardDevice->ControllerNameTable,\r
469     L"Generic Usb Keyboard"\r
470     );\r
471 \r
472   return EFI_SUCCESS;\r
473 }\r
474 \r
475 \r
476 \r
477 /**\r
478   Stop.\r
479 \r
480   @param  This                  EFI_DRIVER_BINDING_PROTOCOL\r
481   @param  Controller            Controller handle\r
482   @param  NumberOfChildren      Child handle number\r
483   @param  ChildHandleBuffer     Child handle buffer\r
484 \r
485   @retval EFI_SUCCESS           Success\r
486   @retval EFI_UNSUPPORTED       Can't support\r
487 \r
488 **/\r
489 EFI_STATUS\r
490 EFIAPI\r
491 USBKeyboardDriverBindingStop (\r
492   IN  EFI_DRIVER_BINDING_PROTOCOL    *This,\r
493   IN  EFI_HANDLE                     Controller,\r
494   IN  UINTN                          NumberOfChildren,\r
495   IN  EFI_HANDLE                     *ChildHandleBuffer\r
496   )\r
497 {\r
498   EFI_STATUS                  Status;\r
499   EFI_SIMPLE_TEXT_INPUT_PROTOCOL *SimpleInput;\r
500   USB_KB_DEV                  *UsbKeyboardDevice;\r
501 \r
502   Status = gBS->OpenProtocol (\r
503                   Controller,\r
504                   &gEfiSimpleTextInProtocolGuid,\r
505                   (VOID **) &SimpleInput,\r
506                   This->DriverBindingHandle,\r
507                   Controller,\r
508                   EFI_OPEN_PROTOCOL_BY_DRIVER\r
509                   );\r
510   if (EFI_ERROR (Status)) {\r
511     return EFI_UNSUPPORTED;\r
512   }\r
513 \r
514   //\r
515   // Get USB_KB_DEV instance.\r
516   //\r
517   UsbKeyboardDevice = USB_KB_DEV_FROM_THIS (SimpleInput);\r
518 \r
519   gBS->CloseProtocol (\r
520         Controller,\r
521         &gEfiSimpleTextInProtocolGuid,\r
522         This->DriverBindingHandle,\r
523         Controller\r
524         );\r
525 \r
526   //\r
527   // Uninstall the Asyn Interrupt Transfer from this device\r
528   // will disable the key data input from this device\r
529   //\r
530   KbdReportStatusCode (\r
531     UsbKeyboardDevice->DevicePath,\r
532     EFI_PROGRESS_CODE,\r
533     PcdGet32 (PcdStatusCodeValueKeyboardDisable)\r
534     );\r
535 \r
536   //\r
537   // Destroy asynchronous interrupt transfer\r
538   //\r
539   UsbKeyboardDevice->UsbIo->UsbAsyncInterruptTransfer (\r
540                               UsbKeyboardDevice->UsbIo,\r
541                               UsbKeyboardDevice->IntEndpointDescriptor.EndpointAddress,\r
542                               FALSE,\r
543                               UsbKeyboardDevice->IntEndpointDescriptor.Interval,\r
544                               0,\r
545                               NULL,\r
546                               NULL\r
547                               );\r
548 \r
549   gBS->CloseProtocol (\r
550         Controller,\r
551         &gEfiUsbIoProtocolGuid,\r
552         This->DriverBindingHandle,\r
553         Controller\r
554         );\r
555 \r
556   Status = gBS->UninstallMultipleProtocolInterfaces (\r
557                   Controller,\r
558                   &gEfiSimpleTextInProtocolGuid,\r
559                   &UsbKeyboardDevice->SimpleInput,\r
560                   &gEfiHotPlugDeviceGuid,\r
561                   NULL,\r
562                   NULL\r
563                   );\r
564   //\r
565   // free all the resources.\r
566   //\r
567   gBS->CloseEvent (UsbKeyboardDevice->RepeatTimer);\r
568   gBS->CloseEvent (UsbKeyboardDevice->DelayedRecoveryEvent);\r
569   gBS->CloseEvent ((UsbKeyboardDevice->SimpleInput).WaitForKey);\r
570 \r
571   if (UsbKeyboardDevice->ControllerNameTable != NULL) {\r
572     FreeUnicodeStringTable (UsbKeyboardDevice->ControllerNameTable);\r
573   }\r
574 \r
575   gBS->FreePool (UsbKeyboardDevice);\r
576 \r
577   return Status;\r
578 \r
579 }\r
580 \r
581 \r
582 \r
583 /**\r
584   Implements EFI_SIMPLE_TEXT_INPUT_PROTOCOL.Reset() function.\r
585 \r
586   This      The EFI_SIMPLE_TEXT_INPUT_PROTOCOL instance.\r
587   ExtendedVerification\r
588   Indicates that the driver may perform a more exhaustive\r
589   verification operation of the device during reset.\r
590 \r
591   @retval EFI_SUCCESS           Success\r
592   @retval EFI_DEVICE_ERROR      Hardware Error\r
593 \r
594 **/\r
595 EFI_STATUS\r
596 EFIAPI\r
597 USBKeyboardReset (\r
598   IN  EFI_SIMPLE_TEXT_INPUT_PROTOCOL   *This,\r
599   IN  BOOLEAN                       ExtendedVerification\r
600   )\r
601 {\r
602   EFI_STATUS          Status;\r
603   USB_KB_DEV          *UsbKeyboardDevice;\r
604 \r
605   UsbKeyboardDevice = USB_KB_DEV_FROM_THIS (This);\r
606 \r
607   KbdReportStatusCode (\r
608     UsbKeyboardDevice->DevicePath,\r
609     EFI_PROGRESS_CODE,\r
610         PcdGet32 (PcdStatusCodeValueKeyboardReset)\r
611     );\r
612 \r
613   //\r
614   // Non Exhaustive reset:\r
615   // only reset private data structures.\r
616   //\r
617   if (!ExtendedVerification) {\r
618     //\r
619     // Clear the key buffer of this Usb keyboard\r
620     //\r
621     KbdReportStatusCode (\r
622       UsbKeyboardDevice->DevicePath,\r
623       EFI_PROGRESS_CODE,\r
624       PcdGet32 (PcdStatusCodeValueKeyboardClearBuffer)\r
625       );\r
626 \r
627     InitUSBKeyBuffer (&(UsbKeyboardDevice->KeyboardBuffer));\r
628     UsbKeyboardDevice->CurKeyChar = 0;\r
629     return EFI_SUCCESS;\r
630   }\r
631 \r
632   //\r
633   // Exhaustive reset\r
634   //\r
635   Status                        = InitUSBKeyboard (UsbKeyboardDevice);\r
636   UsbKeyboardDevice->CurKeyChar = 0;\r
637   if (EFI_ERROR (Status)) {\r
638     return EFI_DEVICE_ERROR;\r
639   }\r
640 \r
641   return EFI_SUCCESS;\r
642 }\r
643 \r
644 \r
645 /**\r
646   Implements EFI_SIMPLE_TEXT_INPUT_PROTOCOL.ReadKeyStroke() function.\r
647 \r
648   This     The EFI_SIMPLE_TEXT_INPUT_PROTOCOL instance.\r
649   Key      A pointer to a buffer that is filled in with the keystroke\r
650   information for the key that was pressed.\r
651 \r
652   @retval EFI_SUCCESS           Success\r
653 \r
654 **/\r
655 STATIC\r
656 EFI_STATUS\r
657 EFIAPI\r
658 USBKeyboardReadKeyStroke (\r
659   IN  EFI_SIMPLE_TEXT_INPUT_PROTOCOL   *This,\r
660   OUT EFI_INPUT_KEY                 *Key\r
661   )\r
662 {\r
663   USB_KB_DEV  *UsbKeyboardDevice;\r
664   EFI_STATUS  Status;\r
665   UINT8       KeyChar;\r
666 \r
667   UsbKeyboardDevice = USB_KB_DEV_FROM_THIS (This);\r
668 \r
669   //\r
670   // if there is no saved ASCII byte, fetch it\r
671   // by calling USBKeyboardCheckForKey().\r
672   //\r
673   if (UsbKeyboardDevice->CurKeyChar == 0) {\r
674     Status = USBKeyboardCheckForKey (UsbKeyboardDevice);\r
675     if (EFI_ERROR (Status)) {\r
676       return Status;\r
677     }\r
678   }\r
679 \r
680   Key->UnicodeChar              = 0;\r
681   Key->ScanCode                 = SCAN_NULL;\r
682 \r
683   KeyChar                       = UsbKeyboardDevice->CurKeyChar;\r
684 \r
685   UsbKeyboardDevice->CurKeyChar = 0;\r
686 \r
687   //\r
688   // Translate saved ASCII byte into EFI_INPUT_KEY\r
689   //\r
690   Status = USBKeyCodeToEFIScanCode (UsbKeyboardDevice, KeyChar, Key);\r
691 \r
692   return Status;\r
693 \r
694 }\r
695 \r
696 \r
697 /**\r
698   Handler function for WaitForKey event.\r
699 \r
700   Event        Event to be signaled when a key is pressed.\r
701   Context      Points to USB_KB_DEV instance.\r
702 \r
703   @return VOID\r
704 \r
705 **/\r
706 STATIC\r
707 VOID\r
708 EFIAPI\r
709 USBKeyboardWaitForKey (\r
710   IN  EFI_EVENT               Event,\r
711   IN  VOID                    *Context\r
712   )\r
713 {\r
714   USB_KB_DEV  *UsbKeyboardDevice;\r
715 \r
716   UsbKeyboardDevice = (USB_KB_DEV *) Context;\r
717 \r
718   if (UsbKeyboardDevice->CurKeyChar == 0) {\r
719 \r
720     if (EFI_ERROR (USBKeyboardCheckForKey (UsbKeyboardDevice))) {\r
721       return ;\r
722     }\r
723   }\r
724   //\r
725   // If has key pending, signal the event.\r
726   //\r
727   gBS->SignalEvent (Event);\r
728 }\r
729 \r
730 \r
731 \r
732 /**\r
733   Check whether there is key pending.\r
734 \r
735   UsbKeyboardDevice    The USB_KB_DEV instance.\r
736 \r
737   @retval EFI_SUCCESS           Success\r
738 \r
739 **/\r
740 STATIC\r
741 EFI_STATUS\r
742 USBKeyboardCheckForKey (\r
743   IN  USB_KB_DEV    *UsbKeyboardDevice\r
744   )\r
745 {\r
746   EFI_STATUS  Status;\r
747   UINT8       KeyChar;\r
748 \r
749   //\r
750   // Fetch raw data from the USB keyboard input,\r
751   // and translate it into ASCII data.\r
752   //\r
753   Status = USBParseKey (UsbKeyboardDevice, &KeyChar);\r
754   if (EFI_ERROR (Status)) {\r
755     return Status;\r
756   }\r
757 \r
758   UsbKeyboardDevice->CurKeyChar = KeyChar;\r
759   return EFI_SUCCESS;\r
760 }\r
761 \r
762 \r
763 /**\r
764   Report Status Code in Usb Bot Driver\r
765 \r
766   @param  DevicePath            Use this to get Device Path\r
767   @param  CodeType              Status Code Type\r
768   @param  CodeValue             Status Code Value\r
769 \r
770   @return None\r
771 \r
772 **/\r
773 VOID\r
774 KbdReportStatusCode (\r
775   IN EFI_DEVICE_PATH_PROTOCOL  *DevicePath,\r
776   IN EFI_STATUS_CODE_TYPE      CodeType,\r
777   IN EFI_STATUS_CODE_VALUE     Value\r
778   )\r
779 {\r
780 \r
781   REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
782     CodeType,\r
783     Value,\r
784     DevicePath\r
785     );\r
786 }\r