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 UsbKeyboardDevice
->IntEndpointDescriptor
= 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
;
503 EFI_USB_IO_PROTOCOL
*UsbIo
;
505 Status
= gBS
->OpenProtocol (
507 &gEfiSimpleTextInProtocolGuid
,
509 This
->DriverBindingHandle
,
511 EFI_OPEN_PROTOCOL_BY_DRIVER
513 if (EFI_ERROR (Status
)) {
514 return EFI_UNSUPPORTED
;
518 // Get USB_KB_DEV instance.
520 UsbKeyboardDevice
= USB_KB_DEV_FROM_THIS (SimpleInput
);
524 &gEfiSimpleTextInProtocolGuid
,
525 This
->DriverBindingHandle
,
529 UsbIo
= UsbKeyboardDevice
->UsbIo
;
531 // Uninstall the Asyn Interrupt Transfer from this device
532 // will disable the key data input from this device
534 KbdReportStatusCode (
535 UsbKeyboardDevice
->DevicePath
,
537 PcdGet32 (PcdStatusCodeValueKeyboardDisable
)
541 // Destroy asynchronous interrupt transfer
543 UsbKeyboardDevice
->UsbIo
->UsbAsyncInterruptTransfer (
544 UsbKeyboardDevice
->UsbIo
,
545 UsbKeyboardDevice
->IntEndpointDescriptor
.EndpointAddress
,
547 UsbKeyboardDevice
->IntEndpointDescriptor
.Interval
,
555 &gEfiUsbIoProtocolGuid
,
556 This
->DriverBindingHandle
,
560 Status
= gBS
->UninstallMultipleProtocolInterfaces (
562 &gEfiSimpleTextInProtocolGuid
,
563 &UsbKeyboardDevice
->SimpleInput
,
564 &gEfiHotPlugDeviceGuid
,
569 // free all the resources.
571 gBS
->CloseEvent (UsbKeyboardDevice
->RepeatTimer
);
572 gBS
->CloseEvent (UsbKeyboardDevice
->DelayedRecoveryEvent
);
573 gBS
->CloseEvent ((UsbKeyboardDevice
->SimpleInput
).WaitForKey
);
575 if (UsbKeyboardDevice
->ControllerNameTable
!= NULL
) {
576 FreeUnicodeStringTable (UsbKeyboardDevice
->ControllerNameTable
);
579 gBS
->FreePool (UsbKeyboardDevice
);
588 Implements EFI_SIMPLE_TEXT_INPUT_PROTOCOL.Reset() function.
590 This The EFI_SIMPLE_TEXT_INPUT_PROTOCOL instance.
592 Indicates that the driver may perform a more exhaustive
593 verification operation of the device during reset.
595 @retval EFI_SUCCESS Success
596 @retval EFI_DEVICE_ERROR Hardware Error
602 IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*This
,
603 IN BOOLEAN ExtendedVerification
607 USB_KB_DEV
*UsbKeyboardDevice
;
608 EFI_USB_IO_PROTOCOL
*UsbIo
;
610 UsbKeyboardDevice
= USB_KB_DEV_FROM_THIS (This
);
612 UsbIo
= UsbKeyboardDevice
->UsbIo
;
614 KbdReportStatusCode (
615 UsbKeyboardDevice
->DevicePath
,
617 PcdGet32 (PcdStatusCodeValueKeyboardReset
)
621 // Non Exhaustive reset:
622 // only reset private data structures.
624 if (!ExtendedVerification
) {
626 // Clear the key buffer of this Usb keyboard
628 KbdReportStatusCode (
629 UsbKeyboardDevice
->DevicePath
,
631 PcdGet32 (PcdStatusCodeValueKeyboardClearBuffer
)
634 InitUSBKeyBuffer (&(UsbKeyboardDevice
->KeyboardBuffer
));
635 UsbKeyboardDevice
->CurKeyChar
= 0;
642 Status
= InitUSBKeyboard (UsbKeyboardDevice
);
643 UsbKeyboardDevice
->CurKeyChar
= 0;
644 if (EFI_ERROR (Status
)) {
645 return EFI_DEVICE_ERROR
;
653 Implements EFI_SIMPLE_TEXT_INPUT_PROTOCOL.ReadKeyStroke() function.
655 This The EFI_SIMPLE_TEXT_INPUT_PROTOCOL instance.
656 Key A pointer to a buffer that is filled in with the keystroke
657 information for the key that was pressed.
659 @retval EFI_SUCCESS Success
665 USBKeyboardReadKeyStroke (
666 IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*This
,
667 OUT EFI_INPUT_KEY
*Key
670 USB_KB_DEV
*UsbKeyboardDevice
;
674 UsbKeyboardDevice
= USB_KB_DEV_FROM_THIS (This
);
677 // if there is no saved ASCII byte, fetch it
678 // by calling USBKeyboardCheckForKey().
680 if (UsbKeyboardDevice
->CurKeyChar
== 0) {
681 Status
= USBKeyboardCheckForKey (UsbKeyboardDevice
);
682 if (EFI_ERROR (Status
)) {
687 Key
->UnicodeChar
= 0;
688 Key
->ScanCode
= SCAN_NULL
;
690 KeyChar
= UsbKeyboardDevice
->CurKeyChar
;
692 UsbKeyboardDevice
->CurKeyChar
= 0;
695 // Translate saved ASCII byte into EFI_INPUT_KEY
697 Status
= USBKeyCodeToEFIScanCode (UsbKeyboardDevice
, KeyChar
, Key
);
705 Handler function for WaitForKey event.
707 Event Event to be signaled when a key is pressed.
708 Context Points to USB_KB_DEV instance.
716 USBKeyboardWaitForKey (
721 USB_KB_DEV
*UsbKeyboardDevice
;
723 UsbKeyboardDevice
= (USB_KB_DEV
*) Context
;
725 if (UsbKeyboardDevice
->CurKeyChar
== 0) {
727 if (EFI_ERROR (USBKeyboardCheckForKey (UsbKeyboardDevice
))) {
732 // If has key pending, signal the event.
734 gBS
->SignalEvent (Event
);
740 Check whether there is key pending.
742 UsbKeyboardDevice The USB_KB_DEV instance.
744 @retval EFI_SUCCESS Success
749 USBKeyboardCheckForKey (
750 IN USB_KB_DEV
*UsbKeyboardDevice
757 // Fetch raw data from the USB keyboard input,
758 // and translate it into ASCII data.
760 Status
= USBParseKey (UsbKeyboardDevice
, &KeyChar
);
761 if (EFI_ERROR (Status
)) {
765 UsbKeyboardDevice
->CurKeyChar
= KeyChar
;
771 Report Status Code in Usb Bot Driver
773 @param DevicePath Use this to get Device Path
774 @param CodeType Status Code Type
775 @param CodeValue Status Code Value
781 KbdReportStatusCode (
782 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
,
783 IN EFI_STATUS_CODE_TYPE CodeType
,
784 IN EFI_STATUS_CODE_VALUE Value
788 REPORT_STATUS_CODE_WITH_DEVICE_PATH (