3 Copyright (c) 2006, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
29 // Driver model protocol interface
33 USBKeyboardDriverBindingEntryPoint (
34 IN EFI_HANDLE ImageHandle
,
35 IN EFI_SYSTEM_TABLE
*SystemTable
40 USBKeyboardDriverBindingSupported (
41 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
42 IN EFI_HANDLE Controller
,
43 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
48 USBKeyboardDriverBindingStart (
49 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
50 IN EFI_HANDLE Controller
,
51 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
56 USBKeyboardDriverBindingStop (
57 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
58 IN EFI_HANDLE Controller
,
59 IN UINTN NumberOfChildren
,
60 IN EFI_HANDLE
*ChildHandleBuffer
64 // Simple Text In Protocol Interface
70 IN EFI_SIMPLE_TEXT_IN_PROTOCOL
*This
,
71 IN BOOLEAN ExtendedVerification
77 USBKeyboardReadKeyStroke (
78 IN EFI_SIMPLE_TEXT_IN_PROTOCOL
*This
,
79 OUT EFI_INPUT_KEY
*Key
85 USBKeyboardWaitForKey (
95 USBKeyboardCheckForKey (
96 IN USB_KB_DEV
*UsbKeyboardDevice
100 // USB Keyboard Driver Global Variables
102 EFI_DRIVER_BINDING_PROTOCOL gUsbKeyboardDriverBinding
= {
103 USBKeyboardDriverBindingSupported
,
104 USBKeyboardDriverBindingStart
,
105 USBKeyboardDriverBindingStop
,
113 USBKeyboardDriverBindingSupported (
114 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
115 IN EFI_HANDLE Controller
,
116 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
124 This - EFI_DRIVER_BINDING_PROTOCOL
125 Controller - Controller handle
126 RemainingDevicePath - EFI_DEVICE_PATH_PROTOCOL
132 EFI_STATUS OpenStatus
;
133 EFI_USB_IO_PROTOCOL
*UsbIo
;
137 // Check if USB_IO protocol is attached on the controller handle.
139 OpenStatus
= gBS
->OpenProtocol (
141 &gEfiUsbIoProtocolGuid
,
143 This
->DriverBindingHandle
,
145 EFI_OPEN_PROTOCOL_BY_DRIVER
147 if (EFI_ERROR (OpenStatus
)) {
152 // Use the USB I/O protocol interface to check whether the Controller is
153 // the Keyboard controller that can be managed by this driver.
155 Status
= EFI_SUCCESS
;
157 if (!IsUSBKeyboard (UsbIo
)) {
158 Status
= EFI_UNSUPPORTED
;
163 &gEfiUsbIoProtocolGuid
,
164 This
->DriverBindingHandle
,
173 USBKeyboardDriverBindingStart (
174 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
175 IN EFI_HANDLE Controller
,
176 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
184 This - EFI_DRIVER_BINDING_PROTOCOL
185 Controller - Controller handle
186 RemainingDevicePath - EFI_DEVICE_PATH_PROTOCOL
188 EFI_SUCCESS - Success
189 EFI_OUT_OF_RESOURCES - Can't allocate memory
190 EFI_UNSUPPORTED - The Start routine fail
194 EFI_USB_IO_PROTOCOL
*UsbIo
;
195 USB_KB_DEV
*UsbKeyboardDevice
;
196 UINT8 EndpointNumber
;
197 EFI_USB_ENDPOINT_DESCRIPTOR EndpointDescriptor
;
200 UINT8 PollingInterval
;
204 UsbKeyboardDevice
= NULL
;
208 // Open USB_IO Protocol
210 Status
= gBS
->OpenProtocol (
212 &gEfiUsbIoProtocolGuid
,
214 This
->DriverBindingHandle
,
216 EFI_OPEN_PROTOCOL_BY_DRIVER
218 if (EFI_ERROR (Status
)) {
222 UsbKeyboardDevice
= AllocateZeroPool (sizeof (USB_KB_DEV
));
223 if (UsbKeyboardDevice
== NULL
) {
226 &gEfiUsbIoProtocolGuid
,
227 This
->DriverBindingHandle
,
230 return EFI_OUT_OF_RESOURCES
;
233 // Get the Device Path Protocol on Controller's handle
235 Status
= gBS
->OpenProtocol (
237 &gEfiDevicePathProtocolGuid
,
238 (VOID
**) &UsbKeyboardDevice
->DevicePath
,
239 This
->DriverBindingHandle
,
241 EFI_OPEN_PROTOCOL_GET_PROTOCOL
244 if (EFI_ERROR (Status
)) {
245 gBS
->FreePool (UsbKeyboardDevice
);
248 &gEfiUsbIoProtocolGuid
,
249 This
->DriverBindingHandle
,
255 // Report that the usb keyboard is being enabled
257 KbdReportStatusCode (
258 UsbKeyboardDevice
->DevicePath
,
260 (EFI_PERIPHERAL_KEYBOARD
| EFI_P_PC_ENABLE
)
264 // This is pretty close to keyboard detection, so log progress
266 KbdReportStatusCode (
267 UsbKeyboardDevice
->DevicePath
,
269 (EFI_PERIPHERAL_KEYBOARD
| EFI_P_PC_PRESENCE_DETECT
)
273 // Initialize UsbKeyboardDevice
275 UsbKeyboardDevice
->UsbIo
= UsbIo
;
278 // Get interface & endpoint descriptor
280 UsbIo
->UsbGetInterfaceDescriptor (
282 &UsbKeyboardDevice
->InterfaceDescriptor
285 EndpointNumber
= UsbKeyboardDevice
->InterfaceDescriptor
.NumEndpoints
;
287 for (Index
= 0; Index
< EndpointNumber
; Index
++) {
289 UsbIo
->UsbGetEndpointDescriptor (
295 if ((EndpointDescriptor
.Attributes
& 0x03) == 0x03) {
297 // We only care interrupt endpoint here
299 CopyMem (&UsbKeyboardDevice
->IntEndpointDescriptor
, &EndpointDescriptor
, sizeof (EndpointDescriptor
));
306 // No interrupt endpoint found, then return unsupported.
308 gBS
->FreePool (UsbKeyboardDevice
);
311 &gEfiUsbIoProtocolGuid
,
312 This
->DriverBindingHandle
,
315 return EFI_UNSUPPORTED
;
318 UsbKeyboardDevice
->Signature
= USB_KB_DEV_SIGNATURE
;
319 UsbKeyboardDevice
->SimpleInput
.Reset
= USBKeyboardReset
;
320 UsbKeyboardDevice
->SimpleInput
.ReadKeyStroke
= USBKeyboardReadKeyStroke
;
321 Status
= gBS
->CreateEvent (
322 EFI_EVENT_NOTIFY_WAIT
,
324 USBKeyboardWaitForKey
,
326 &(UsbKeyboardDevice
->SimpleInput
.WaitForKey
)
329 if (EFI_ERROR (Status
)) {
330 gBS
->FreePool (UsbKeyboardDevice
);
333 &gEfiUsbIoProtocolGuid
,
334 This
->DriverBindingHandle
,
341 // Install simple txt in protocol interface
342 // for the usb keyboard device.
343 // Usb keyboard is a hot plug device, and expected to work immediately
344 // when plugging into system, so a HotPlugDeviceGuid is installed onto
345 // the usb keyboard device handle, to distinguish it from other conventional
348 Status
= gBS
->InstallMultipleProtocolInterfaces (
350 &gEfiSimpleTextInProtocolGuid
,
351 &UsbKeyboardDevice
->SimpleInput
,
352 &gEfiHotPlugDeviceGuid
,
356 if (EFI_ERROR (Status
)) {
357 gBS
->CloseEvent (UsbKeyboardDevice
->SimpleInput
.WaitForKey
);
358 gBS
->FreePool (UsbKeyboardDevice
);
361 &gEfiUsbIoProtocolGuid
,
362 This
->DriverBindingHandle
,
369 // Reset USB Keyboard Device
371 Status
= UsbKeyboardDevice
->SimpleInput
.Reset (
372 &UsbKeyboardDevice
->SimpleInput
,
375 if (EFI_ERROR (Status
)) {
376 gBS
->UninstallMultipleProtocolInterfaces (
378 &gEfiSimpleTextInProtocolGuid
,
379 &UsbKeyboardDevice
->SimpleInput
,
380 &gEfiHotPlugDeviceGuid
,
384 gBS
->CloseEvent (UsbKeyboardDevice
->SimpleInput
.WaitForKey
);
385 gBS
->FreePool (UsbKeyboardDevice
);
388 &gEfiUsbIoProtocolGuid
,
389 This
->DriverBindingHandle
,
395 // submit async interrupt transfer
397 EndpointAddr
= UsbKeyboardDevice
->IntEndpointDescriptor
.EndpointAddress
;
398 PollingInterval
= UsbKeyboardDevice
->IntEndpointDescriptor
.Interval
;
399 PacketSize
= (UINT8
) (UsbKeyboardDevice
->IntEndpointDescriptor
.MaxPacketSize
);
401 Status
= UsbIo
->UsbAsyncInterruptTransfer (
411 if (EFI_ERROR (Status
)) {
413 gBS
->UninstallMultipleProtocolInterfaces (
415 &gEfiSimpleTextInProtocolGuid
,
416 &UsbKeyboardDevice
->SimpleInput
,
417 &gEfiHotPlugDeviceGuid
,
421 gBS
->CloseEvent (UsbKeyboardDevice
->SimpleInput
.WaitForKey
);
422 gBS
->FreePool (UsbKeyboardDevice
);
425 &gEfiUsbIoProtocolGuid
,
426 This
->DriverBindingHandle
,
432 UsbKeyboardDevice
->ControllerNameTable
= NULL
;
435 gUsbKeyboardComponentName
.SupportedLanguages
,
436 &UsbKeyboardDevice
->ControllerNameTable
,
437 (CHAR16
*) L
"Generic Usb Keyboard"
446 USBKeyboardDriverBindingStop (
447 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
448 IN EFI_HANDLE Controller
,
449 IN UINTN NumberOfChildren
,
450 IN EFI_HANDLE
*ChildHandleBuffer
458 This - EFI_DRIVER_BINDING_PROTOCOL
459 Controller - Controller handle
460 NumberOfChildren - Child handle number
461 ChildHandleBuffer - Child handle buffer
463 EFI_SUCCESS - Success
464 EFI_UNSUPPORTED - Can't support
468 EFI_SIMPLE_TEXT_IN_PROTOCOL
*SimpleInput
;
469 USB_KB_DEV
*UsbKeyboardDevice
;
470 EFI_USB_IO_PROTOCOL
*UsbIo
;
472 Status
= gBS
->OpenProtocol (
474 &gEfiSimpleTextInProtocolGuid
,
475 (VOID
**) &SimpleInput
,
476 This
->DriverBindingHandle
,
478 EFI_OPEN_PROTOCOL_BY_DRIVER
480 if (EFI_ERROR (Status
)) {
481 return EFI_UNSUPPORTED
;
485 // Get USB_KB_DEV instance.
487 UsbKeyboardDevice
= USB_KB_DEV_FROM_THIS (SimpleInput
);
491 &gEfiSimpleTextInProtocolGuid
,
492 This
->DriverBindingHandle
,
496 UsbIo
= UsbKeyboardDevice
->UsbIo
;
498 // Uninstall the Asyn Interrupt Transfer from this device
499 // will disable the key data input from this device
501 KbdReportStatusCode (
502 UsbKeyboardDevice
->DevicePath
,
504 (EFI_PERIPHERAL_KEYBOARD
| EFI_P_PC_DISABLE
)
508 // Destroy asynchronous interrupt transfer
510 UsbKeyboardDevice
->UsbIo
->UsbAsyncInterruptTransfer (
511 UsbKeyboardDevice
->UsbIo
,
512 UsbKeyboardDevice
->IntEndpointDescriptor
.EndpointAddress
,
514 UsbKeyboardDevice
->IntEndpointDescriptor
.Interval
,
522 &gEfiUsbIoProtocolGuid
,
523 This
->DriverBindingHandle
,
527 Status
= gBS
->UninstallMultipleProtocolInterfaces (
529 &gEfiSimpleTextInProtocolGuid
,
530 &UsbKeyboardDevice
->SimpleInput
,
531 &gEfiHotPlugDeviceGuid
,
536 // free all the resources.
538 gBS
->CloseEvent (UsbKeyboardDevice
->RepeatTimer
);
539 gBS
->CloseEvent (UsbKeyboardDevice
->DelayedRecoveryEvent
);
540 gBS
->CloseEvent ((UsbKeyboardDevice
->SimpleInput
).WaitForKey
);
542 if (UsbKeyboardDevice
->ControllerNameTable
!= NULL
) {
543 FreeUnicodeStringTable (UsbKeyboardDevice
->ControllerNameTable
);
546 gBS
->FreePool (UsbKeyboardDevice
);
556 IN EFI_SIMPLE_TEXT_IN_PROTOCOL
*This
,
557 IN BOOLEAN ExtendedVerification
562 Implements EFI_SIMPLE_TEXT_IN_PROTOCOL.Reset() function.
565 This The EFI_SIMPLE_TEXT_IN_PROTOCOL instance.
567 Indicates that the driver may perform a more exhaustive
568 verification operation of the device during reset.
571 EFI_SUCCESS - Success
572 EFI_DEVICE_ERROR - Hardware Error
576 USB_KB_DEV
*UsbKeyboardDevice
;
577 EFI_USB_IO_PROTOCOL
*UsbIo
;
579 UsbKeyboardDevice
= USB_KB_DEV_FROM_THIS (This
);
581 UsbIo
= UsbKeyboardDevice
->UsbIo
;
583 KbdReportStatusCode (
584 UsbKeyboardDevice
->DevicePath
,
586 (EFI_PERIPHERAL_KEYBOARD
| EFI_P_PC_RESET
)
590 // Non Exhaustive reset:
591 // only reset private data structures.
593 if (!ExtendedVerification
) {
595 // Clear the key buffer of this Usb keyboard
597 KbdReportStatusCode (
598 UsbKeyboardDevice
->DevicePath
,
600 (EFI_PERIPHERAL_KEYBOARD
| EFI_P_KEYBOARD_PC_CLEAR_BUFFER
)
603 InitUSBKeyBuffer (&(UsbKeyboardDevice
->KeyboardBuffer
));
604 UsbKeyboardDevice
->CurKeyChar
= 0;
611 Status
= InitUSBKeyboard (UsbKeyboardDevice
);
612 UsbKeyboardDevice
->CurKeyChar
= 0;
613 if (EFI_ERROR (Status
)) {
614 return EFI_DEVICE_ERROR
;
623 USBKeyboardReadKeyStroke (
624 IN EFI_SIMPLE_TEXT_IN_PROTOCOL
*This
,
625 OUT EFI_INPUT_KEY
*Key
630 Implements EFI_SIMPLE_TEXT_IN_PROTOCOL.ReadKeyStroke() function.
633 This The EFI_SIMPLE_TEXT_IN_PROTOCOL instance.
634 Key A pointer to a buffer that is filled in with the keystroke
635 information for the key that was pressed.
638 EFI_SUCCESS - Success
641 USB_KB_DEV
*UsbKeyboardDevice
;
645 UsbKeyboardDevice
= USB_KB_DEV_FROM_THIS (This
);
648 // if there is no saved ASCII byte, fetch it
649 // by calling USBKeyboardCheckForKey().
651 if (UsbKeyboardDevice
->CurKeyChar
== 0) {
652 Status
= USBKeyboardCheckForKey (UsbKeyboardDevice
);
653 if (EFI_ERROR (Status
)) {
658 Key
->UnicodeChar
= 0;
659 Key
->ScanCode
= SCAN_NULL
;
661 KeyChar
= UsbKeyboardDevice
->CurKeyChar
;
663 UsbKeyboardDevice
->CurKeyChar
= 0;
666 // Translate saved ASCII byte into EFI_INPUT_KEY
668 Status
= USBKeyCodeToEFIScanCode (UsbKeyboardDevice
, KeyChar
, Key
);
677 USBKeyboardWaitForKey (
684 Handler function for WaitForKey event.
687 Event Event to be signaled when a key is pressed.
688 Context Points to USB_KB_DEV instance.
694 USB_KB_DEV
*UsbKeyboardDevice
;
696 UsbKeyboardDevice
= (USB_KB_DEV
*) Context
;
698 if (UsbKeyboardDevice
->CurKeyChar
== 0) {
700 if (EFI_ERROR (USBKeyboardCheckForKey (UsbKeyboardDevice
))) {
705 // If has key pending, signal the event.
707 gBS
->SignalEvent (Event
);
713 USBKeyboardCheckForKey (
714 IN USB_KB_DEV
*UsbKeyboardDevice
719 Check whether there is key pending.
722 UsbKeyboardDevice The USB_KB_DEV instance.
725 EFI_SUCCESS - Success
732 // Fetch raw data from the USB keyboard input,
733 // and translate it into ASCII data.
735 Status
= USBParseKey (UsbKeyboardDevice
, &KeyChar
);
736 if (EFI_ERROR (Status
)) {
740 UsbKeyboardDevice
->CurKeyChar
= KeyChar
;
745 KbdReportStatusCode (
746 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
,
747 IN EFI_STATUS_CODE_TYPE CodeType
,
748 IN EFI_STATUS_CODE_VALUE Value
753 Report Status Code in Usb Bot Driver
756 DevicePath - Use this to get Device Path
757 CodeType - Status Code Type
758 CodeValue - Status Code Value
766 REPORT_STATUS_CODE_WITH_DEVICE_PATH (