3 Copyright (c) 2004 - 2007, 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.
30 // Driver model protocol interface
34 USBKeyboardDriverBindingEntryPoint (
35 IN EFI_HANDLE ImageHandle
,
36 IN EFI_SYSTEM_TABLE
*SystemTable
41 USBKeyboardDriverBindingSupported (
42 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
43 IN EFI_HANDLE Controller
,
44 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
49 USBKeyboardDriverBindingStart (
50 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
51 IN EFI_HANDLE Controller
,
52 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
57 USBKeyboardDriverBindingStop (
58 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
59 IN EFI_HANDLE Controller
,
60 IN UINTN NumberOfChildren
,
61 IN EFI_HANDLE
*ChildHandleBuffer
65 // Simple Text In Protocol Interface
71 IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*This
,
72 IN BOOLEAN ExtendedVerification
78 USBKeyboardReadKeyStroke (
79 IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*This
,
80 OUT EFI_INPUT_KEY
*Key
86 USBKeyboardWaitForKey (
96 USBKeyboardCheckForKey (
97 IN USB_KB_DEV
*UsbKeyboardDevice
100 EFI_GUID gEfiUsbKeyboardDriverGuid
= {
101 0xa05f5f78, 0xfb3, 0x4d10, {0x90, 0x90, 0xac, 0x4, 0x6e, 0xeb, 0x7c, 0x3c}
105 // USB Keyboard Driver Global Variables
107 EFI_DRIVER_BINDING_PROTOCOL gUsbKeyboardDriverBinding
= {
108 USBKeyboardDriverBindingSupported
,
109 USBKeyboardDriverBindingStart
,
110 USBKeyboardDriverBindingStop
,
116 //@MT: EFI_DRIVER_ENTRY_POINT (USBKeyboardDriverBindingEntryPoint)
120 USBKeyboardDriverBindingEntryPoint (
121 IN EFI_HANDLE ImageHandle
,
122 IN EFI_SYSTEM_TABLE
*SystemTable
130 ImageHandle - EFI_HANDLE
131 SystemTable - EFI_SYSTEM_TABLE
137 return EfiLibInstallAllDriverProtocols (
140 &gUsbKeyboardDriverBinding
,
142 &gUsbKeyboardComponentName
,
153 @param This EFI_DRIVER_BINDING_PROTOCOL
154 @param Controller Controller handle
155 @param RemainingDevicePath EFI_DEVICE_PATH_PROTOCOL
161 USBKeyboardDriverBindingSupported (
162 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
163 IN EFI_HANDLE Controller
,
164 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
167 EFI_STATUS OpenStatus
;
168 EFI_USB_IO_PROTOCOL
*UsbIo
;
172 // Check if USB_IO protocol is attached on the controller handle.
174 OpenStatus
= gBS
->OpenProtocol (
176 &gEfiUsbIoProtocolGuid
,
178 This
->DriverBindingHandle
,
180 EFI_OPEN_PROTOCOL_BY_DRIVER
182 if (EFI_ERROR (OpenStatus
)) {
187 // Use the USB I/O protocol interface to check whether the Controller is
188 // the Keyboard controller that can be managed by this driver.
190 Status
= EFI_SUCCESS
;
192 if (!IsUSBKeyboard (UsbIo
)) {
193 Status
= EFI_UNSUPPORTED
;
198 &gEfiUsbIoProtocolGuid
,
199 This
->DriverBindingHandle
,
210 @param This EFI_DRIVER_BINDING_PROTOCOL
211 @param Controller Controller handle
212 @param RemainingDevicePath EFI_DEVICE_PATH_PROTOCOL
214 @retval EFI_SUCCESS Success
215 @retval EFI_OUT_OF_RESOURCES Can't allocate memory
216 @retval EFI_UNSUPPORTED The Start routine fail
221 USBKeyboardDriverBindingStart (
222 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
223 IN EFI_HANDLE Controller
,
224 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
228 EFI_USB_IO_PROTOCOL
*UsbIo
;
229 USB_KB_DEV
*UsbKeyboardDevice
;
230 UINT8 EndpointNumber
;
231 EFI_USB_ENDPOINT_DESCRIPTOR EndpointDescriptor
;
234 UINT8 PollingInterval
;
238 UsbKeyboardDevice
= NULL
;
242 // Open USB_IO Protocol
244 Status
= gBS
->OpenProtocol (
246 &gEfiUsbIoProtocolGuid
,
248 This
->DriverBindingHandle
,
250 EFI_OPEN_PROTOCOL_BY_DRIVER
252 if (EFI_ERROR (Status
)) {
256 UsbKeyboardDevice
= AllocateZeroPool (sizeof (USB_KB_DEV
));
257 if (UsbKeyboardDevice
== NULL
) {
260 &gEfiUsbIoProtocolGuid
,
261 This
->DriverBindingHandle
,
264 return EFI_OUT_OF_RESOURCES
;
267 // Get the Device Path Protocol on Controller's handle
269 Status
= gBS
->OpenProtocol (
271 &gEfiDevicePathProtocolGuid
,
272 (VOID
**) &UsbKeyboardDevice
->DevicePath
,
273 This
->DriverBindingHandle
,
275 EFI_OPEN_PROTOCOL_GET_PROTOCOL
278 if (EFI_ERROR (Status
)) {
279 gBS
->FreePool (UsbKeyboardDevice
);
282 &gEfiUsbIoProtocolGuid
,
283 This
->DriverBindingHandle
,
289 // Report that the usb keyboard is being enabled
291 KbdReportStatusCode (
292 UsbKeyboardDevice
->DevicePath
,
294 PcdGet32 (PcdStatusCodeValueKeyboardEnable
)
298 // This is pretty close to keyboard detection, so log progress
300 KbdReportStatusCode (
301 UsbKeyboardDevice
->DevicePath
,
303 PcdGet32 (PcdStatusCodeValueKeyboardPresenceDetect
)
307 // Initialize UsbKeyboardDevice
309 UsbKeyboardDevice
->UsbIo
= UsbIo
;
312 // Get interface & endpoint descriptor
314 UsbIo
->UsbGetInterfaceDescriptor (
316 &UsbKeyboardDevice
->InterfaceDescriptor
319 EndpointNumber
= UsbKeyboardDevice
->InterfaceDescriptor
.NumEndpoints
;
321 for (Index
= 0; Index
< EndpointNumber
; Index
++) {
323 UsbIo
->UsbGetEndpointDescriptor (
329 if ((EndpointDescriptor
.Attributes
& 0x03) == 0x03) {
331 // We only care interrupt endpoint here
333 CopyMem(&UsbKeyboardDevice
->IntEndpointDescriptor
, &EndpointDescriptor
, sizeof(EndpointDescriptor
));
340 // No interrupt endpoint found, then return unsupported.
342 gBS
->FreePool (UsbKeyboardDevice
);
345 &gEfiUsbIoProtocolGuid
,
346 This
->DriverBindingHandle
,
349 return EFI_UNSUPPORTED
;
352 UsbKeyboardDevice
->Signature
= USB_KB_DEV_SIGNATURE
;
353 UsbKeyboardDevice
->SimpleInput
.Reset
= USBKeyboardReset
;
354 UsbKeyboardDevice
->SimpleInput
.ReadKeyStroke
= USBKeyboardReadKeyStroke
;
355 Status
= gBS
->CreateEvent (
358 USBKeyboardWaitForKey
,
360 &(UsbKeyboardDevice
->SimpleInput
.WaitForKey
)
363 if (EFI_ERROR (Status
)) {
364 gBS
->FreePool (UsbKeyboardDevice
);
367 &gEfiUsbIoProtocolGuid
,
368 This
->DriverBindingHandle
,
375 // Install simple txt in protocol interface
376 // for the usb keyboard device.
377 // Usb keyboard is a hot plug device, and expected to work immediately
378 // when plugging into system, so a HotPlugDeviceGuid is installed onto
379 // the usb keyboard device handle, to distinguish it from other conventional
382 Status
= gBS
->InstallMultipleProtocolInterfaces (
384 &gEfiSimpleTextInProtocolGuid
,
385 &UsbKeyboardDevice
->SimpleInput
,
386 &gEfiHotPlugDeviceGuid
,
390 if (EFI_ERROR (Status
)) {
391 gBS
->CloseEvent (UsbKeyboardDevice
->SimpleInput
.WaitForKey
);
392 gBS
->FreePool (UsbKeyboardDevice
);
395 &gEfiUsbIoProtocolGuid
,
396 This
->DriverBindingHandle
,
403 // Reset USB Keyboard Device
405 Status
= UsbKeyboardDevice
->SimpleInput
.Reset (
406 &UsbKeyboardDevice
->SimpleInput
,
409 if (EFI_ERROR (Status
)) {
410 gBS
->UninstallMultipleProtocolInterfaces (
412 &gEfiSimpleTextInProtocolGuid
,
413 &UsbKeyboardDevice
->SimpleInput
,
414 &gEfiHotPlugDeviceGuid
,
418 gBS
->CloseEvent (UsbKeyboardDevice
->SimpleInput
.WaitForKey
);
419 gBS
->FreePool (UsbKeyboardDevice
);
422 &gEfiUsbIoProtocolGuid
,
423 This
->DriverBindingHandle
,
429 // submit async interrupt transfer
431 EndpointAddr
= UsbKeyboardDevice
->IntEndpointDescriptor
.EndpointAddress
;
432 PollingInterval
= UsbKeyboardDevice
->IntEndpointDescriptor
.Interval
;
433 PacketSize
= (UINT8
) (UsbKeyboardDevice
->IntEndpointDescriptor
.MaxPacketSize
);
435 Status
= UsbIo
->UsbAsyncInterruptTransfer (
445 if (EFI_ERROR (Status
)) {
447 gBS
->UninstallMultipleProtocolInterfaces (
449 &gEfiSimpleTextInProtocolGuid
,
450 &UsbKeyboardDevice
->SimpleInput
,
451 &gEfiHotPlugDeviceGuid
,
455 gBS
->CloseEvent (UsbKeyboardDevice
->SimpleInput
.WaitForKey
);
456 gBS
->FreePool (UsbKeyboardDevice
);
459 &gEfiUsbIoProtocolGuid
,
460 This
->DriverBindingHandle
,
466 UsbKeyboardDevice
->ControllerNameTable
= NULL
;
469 gUsbKeyboardComponentName
.SupportedLanguages
,
470 &UsbKeyboardDevice
->ControllerNameTable
,
471 L
"Generic Usb Keyboard"
482 @param This EFI_DRIVER_BINDING_PROTOCOL
483 @param Controller Controller handle
484 @param NumberOfChildren Child handle number
485 @param ChildHandleBuffer Child handle buffer
487 @retval EFI_SUCCESS Success
488 @retval EFI_UNSUPPORTED Can't support
493 USBKeyboardDriverBindingStop (
494 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
495 IN EFI_HANDLE Controller
,
496 IN UINTN NumberOfChildren
,
497 IN EFI_HANDLE
*ChildHandleBuffer
501 EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*SimpleInput
;
502 USB_KB_DEV
*UsbKeyboardDevice
;
504 Status
= gBS
->OpenProtocol (
506 &gEfiSimpleTextInProtocolGuid
,
507 (VOID
**) &SimpleInput
,
508 This
->DriverBindingHandle
,
510 EFI_OPEN_PROTOCOL_BY_DRIVER
512 if (EFI_ERROR (Status
)) {
513 return EFI_UNSUPPORTED
;
517 // Get USB_KB_DEV instance.
519 UsbKeyboardDevice
= USB_KB_DEV_FROM_THIS (SimpleInput
);
523 &gEfiSimpleTextInProtocolGuid
,
524 This
->DriverBindingHandle
,
529 // Uninstall the Asyn Interrupt Transfer from this device
530 // will disable the key data input from this device
532 KbdReportStatusCode (
533 UsbKeyboardDevice
->DevicePath
,
535 PcdGet32 (PcdStatusCodeValueKeyboardDisable
)
539 // Destroy asynchronous interrupt transfer
541 UsbKeyboardDevice
->UsbIo
->UsbAsyncInterruptTransfer (
542 UsbKeyboardDevice
->UsbIo
,
543 UsbKeyboardDevice
->IntEndpointDescriptor
.EndpointAddress
,
545 UsbKeyboardDevice
->IntEndpointDescriptor
.Interval
,
553 &gEfiUsbIoProtocolGuid
,
554 This
->DriverBindingHandle
,
558 Status
= gBS
->UninstallMultipleProtocolInterfaces (
560 &gEfiSimpleTextInProtocolGuid
,
561 &UsbKeyboardDevice
->SimpleInput
,
562 &gEfiHotPlugDeviceGuid
,
567 // free all the resources.
569 gBS
->CloseEvent (UsbKeyboardDevice
->RepeatTimer
);
570 gBS
->CloseEvent (UsbKeyboardDevice
->DelayedRecoveryEvent
);
571 gBS
->CloseEvent ((UsbKeyboardDevice
->SimpleInput
).WaitForKey
);
573 if (UsbKeyboardDevice
->ControllerNameTable
!= NULL
) {
574 FreeUnicodeStringTable (UsbKeyboardDevice
->ControllerNameTable
);
577 gBS
->FreePool (UsbKeyboardDevice
);
586 Implements EFI_SIMPLE_TEXT_INPUT_PROTOCOL.Reset() function.
588 This The EFI_SIMPLE_TEXT_INPUT_PROTOCOL instance.
590 Indicates that the driver may perform a more exhaustive
591 verification operation of the device during reset.
593 @retval EFI_SUCCESS Success
594 @retval EFI_DEVICE_ERROR Hardware Error
600 IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*This
,
601 IN BOOLEAN ExtendedVerification
605 USB_KB_DEV
*UsbKeyboardDevice
;
607 UsbKeyboardDevice
= USB_KB_DEV_FROM_THIS (This
);
609 KbdReportStatusCode (
610 UsbKeyboardDevice
->DevicePath
,
612 PcdGet32 (PcdStatusCodeValueKeyboardReset
)
616 // Non Exhaustive reset:
617 // only reset private data structures.
619 if (!ExtendedVerification
) {
621 // Clear the key buffer of this Usb keyboard
623 KbdReportStatusCode (
624 UsbKeyboardDevice
->DevicePath
,
626 PcdGet32 (PcdStatusCodeValueKeyboardClearBuffer
)
629 InitUSBKeyBuffer (&(UsbKeyboardDevice
->KeyboardBuffer
));
630 UsbKeyboardDevice
->CurKeyChar
= 0;
637 Status
= InitUSBKeyboard (UsbKeyboardDevice
);
638 UsbKeyboardDevice
->CurKeyChar
= 0;
639 if (EFI_ERROR (Status
)) {
640 return EFI_DEVICE_ERROR
;
648 Implements EFI_SIMPLE_TEXT_INPUT_PROTOCOL.ReadKeyStroke() function.
650 This The EFI_SIMPLE_TEXT_INPUT_PROTOCOL instance.
651 Key A pointer to a buffer that is filled in with the keystroke
652 information for the key that was pressed.
654 @retval EFI_SUCCESS Success
660 USBKeyboardReadKeyStroke (
661 IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*This
,
662 OUT EFI_INPUT_KEY
*Key
665 USB_KB_DEV
*UsbKeyboardDevice
;
669 UsbKeyboardDevice
= USB_KB_DEV_FROM_THIS (This
);
672 // if there is no saved ASCII byte, fetch it
673 // by calling USBKeyboardCheckForKey().
675 if (UsbKeyboardDevice
->CurKeyChar
== 0) {
676 Status
= USBKeyboardCheckForKey (UsbKeyboardDevice
);
677 if (EFI_ERROR (Status
)) {
682 Key
->UnicodeChar
= 0;
683 Key
->ScanCode
= SCAN_NULL
;
685 KeyChar
= UsbKeyboardDevice
->CurKeyChar
;
687 UsbKeyboardDevice
->CurKeyChar
= 0;
690 // Translate saved ASCII byte into EFI_INPUT_KEY
692 Status
= USBKeyCodeToEFIScanCode (UsbKeyboardDevice
, KeyChar
, Key
);
700 Handler function for WaitForKey event.
702 Event Event to be signaled when a key is pressed.
703 Context Points to USB_KB_DEV instance.
711 USBKeyboardWaitForKey (
716 USB_KB_DEV
*UsbKeyboardDevice
;
718 UsbKeyboardDevice
= (USB_KB_DEV
*) Context
;
720 if (UsbKeyboardDevice
->CurKeyChar
== 0) {
722 if (EFI_ERROR (USBKeyboardCheckForKey (UsbKeyboardDevice
))) {
727 // If has key pending, signal the event.
729 gBS
->SignalEvent (Event
);
735 Check whether there is key pending.
737 UsbKeyboardDevice The USB_KB_DEV instance.
739 @retval EFI_SUCCESS Success
744 USBKeyboardCheckForKey (
745 IN USB_KB_DEV
*UsbKeyboardDevice
752 // Fetch raw data from the USB keyboard input,
753 // and translate it into ASCII data.
755 Status
= USBParseKey (UsbKeyboardDevice
, &KeyChar
);
756 if (EFI_ERROR (Status
)) {
760 UsbKeyboardDevice
->CurKeyChar
= KeyChar
;
766 Report Status Code in Usb Bot Driver
768 @param DevicePath Use this to get Device Path
769 @param CodeType Status Code Type
770 @param CodeValue Status Code Value
776 KbdReportStatusCode (
777 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
,
778 IN EFI_STATUS_CODE_TYPE CodeType
,
779 IN EFI_STATUS_CODE_VALUE Value
783 REPORT_STATUS_CODE_WITH_DEVICE_PATH (