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
,
118 USBKeyboardDriverBindingEntryPoint (
119 IN EFI_HANDLE ImageHandle
,
120 IN EFI_SYSTEM_TABLE
*SystemTable
128 ImageHandle - EFI_HANDLE
129 SystemTable - EFI_SYSTEM_TABLE
135 return EfiLibInstallAllDriverProtocols (
138 &gUsbKeyboardDriverBinding
,
140 &gUsbKeyboardComponentName
,
151 @param This EFI_DRIVER_BINDING_PROTOCOL
152 @param Controller Controller handle
153 @param RemainingDevicePath EFI_DEVICE_PATH_PROTOCOL
159 USBKeyboardDriverBindingSupported (
160 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
161 IN EFI_HANDLE Controller
,
162 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
165 EFI_STATUS OpenStatus
;
166 EFI_USB_IO_PROTOCOL
*UsbIo
;
170 // Check if USB_IO protocol is attached on the controller handle.
172 OpenStatus
= gBS
->OpenProtocol (
174 &gEfiUsbIoProtocolGuid
,
176 This
->DriverBindingHandle
,
178 EFI_OPEN_PROTOCOL_BY_DRIVER
180 if (EFI_ERROR (OpenStatus
)) {
185 // Use the USB I/O protocol interface to check whether the Controller is
186 // the Keyboard controller that can be managed by this driver.
188 Status
= EFI_SUCCESS
;
190 if (!IsUSBKeyboard (UsbIo
)) {
191 Status
= EFI_UNSUPPORTED
;
196 &gEfiUsbIoProtocolGuid
,
197 This
->DriverBindingHandle
,
208 @param This EFI_DRIVER_BINDING_PROTOCOL
209 @param Controller Controller handle
210 @param RemainingDevicePath EFI_DEVICE_PATH_PROTOCOL
212 @retval EFI_SUCCESS Success
213 @retval EFI_OUT_OF_RESOURCES Can't allocate memory
214 @retval EFI_UNSUPPORTED The Start routine fail
219 USBKeyboardDriverBindingStart (
220 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
221 IN EFI_HANDLE Controller
,
222 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
226 EFI_USB_IO_PROTOCOL
*UsbIo
;
227 USB_KB_DEV
*UsbKeyboardDevice
;
228 UINT8 EndpointNumber
;
229 EFI_USB_ENDPOINT_DESCRIPTOR EndpointDescriptor
;
232 UINT8 PollingInterval
;
236 UsbKeyboardDevice
= NULL
;
240 // Open USB_IO Protocol
242 Status
= gBS
->OpenProtocol (
244 &gEfiUsbIoProtocolGuid
,
246 This
->DriverBindingHandle
,
248 EFI_OPEN_PROTOCOL_BY_DRIVER
250 if (EFI_ERROR (Status
)) {
254 UsbKeyboardDevice
= AllocateZeroPool (sizeof (USB_KB_DEV
));
255 if (UsbKeyboardDevice
== NULL
) {
258 &gEfiUsbIoProtocolGuid
,
259 This
->DriverBindingHandle
,
262 return EFI_OUT_OF_RESOURCES
;
265 // Get the Device Path Protocol on Controller's handle
267 Status
= gBS
->OpenProtocol (
269 &gEfiDevicePathProtocolGuid
,
270 (VOID
**) &UsbKeyboardDevice
->DevicePath
,
271 This
->DriverBindingHandle
,
273 EFI_OPEN_PROTOCOL_GET_PROTOCOL
276 if (EFI_ERROR (Status
)) {
277 gBS
->FreePool (UsbKeyboardDevice
);
280 &gEfiUsbIoProtocolGuid
,
281 This
->DriverBindingHandle
,
287 // Report that the usb keyboard is being enabled
289 KbdReportStatusCode (
290 UsbKeyboardDevice
->DevicePath
,
292 PcdGet32 (PcdStatusCodeValueKeyboardEnable
)
296 // This is pretty close to keyboard detection, so log progress
298 KbdReportStatusCode (
299 UsbKeyboardDevice
->DevicePath
,
301 PcdGet32 (PcdStatusCodeValueKeyboardPresenceDetect
)
305 // Initialize UsbKeyboardDevice
307 UsbKeyboardDevice
->UsbIo
= UsbIo
;
310 // Get interface & endpoint descriptor
312 UsbIo
->UsbGetInterfaceDescriptor (
314 &UsbKeyboardDevice
->InterfaceDescriptor
317 EndpointNumber
= UsbKeyboardDevice
->InterfaceDescriptor
.NumEndpoints
;
319 for (Index
= 0; Index
< EndpointNumber
; Index
++) {
321 UsbIo
->UsbGetEndpointDescriptor (
327 if ((EndpointDescriptor
.Attributes
& 0x03) == 0x03) {
329 // We only care interrupt endpoint here
331 CopyMem(&UsbKeyboardDevice
->IntEndpointDescriptor
, &EndpointDescriptor
, sizeof(EndpointDescriptor
));
338 // No interrupt endpoint found, then return unsupported.
340 gBS
->FreePool (UsbKeyboardDevice
);
343 &gEfiUsbIoProtocolGuid
,
344 This
->DriverBindingHandle
,
347 return EFI_UNSUPPORTED
;
350 UsbKeyboardDevice
->Signature
= USB_KB_DEV_SIGNATURE
;
351 UsbKeyboardDevice
->SimpleInput
.Reset
= USBKeyboardReset
;
352 UsbKeyboardDevice
->SimpleInput
.ReadKeyStroke
= USBKeyboardReadKeyStroke
;
353 Status
= gBS
->CreateEvent (
356 USBKeyboardWaitForKey
,
358 &(UsbKeyboardDevice
->SimpleInput
.WaitForKey
)
361 if (EFI_ERROR (Status
)) {
362 gBS
->FreePool (UsbKeyboardDevice
);
365 &gEfiUsbIoProtocolGuid
,
366 This
->DriverBindingHandle
,
373 // Install simple txt in protocol interface
374 // for the usb keyboard device.
375 // Usb keyboard is a hot plug device, and expected to work immediately
376 // when plugging into system, so a HotPlugDeviceGuid is installed onto
377 // the usb keyboard device handle, to distinguish it from other conventional
380 Status
= gBS
->InstallMultipleProtocolInterfaces (
382 &gEfiSimpleTextInProtocolGuid
,
383 &UsbKeyboardDevice
->SimpleInput
,
384 &gEfiHotPlugDeviceGuid
,
388 if (EFI_ERROR (Status
)) {
389 gBS
->CloseEvent (UsbKeyboardDevice
->SimpleInput
.WaitForKey
);
390 gBS
->FreePool (UsbKeyboardDevice
);
393 &gEfiUsbIoProtocolGuid
,
394 This
->DriverBindingHandle
,
401 // Reset USB Keyboard Device
403 Status
= UsbKeyboardDevice
->SimpleInput
.Reset (
404 &UsbKeyboardDevice
->SimpleInput
,
407 if (EFI_ERROR (Status
)) {
408 gBS
->UninstallMultipleProtocolInterfaces (
410 &gEfiSimpleTextInProtocolGuid
,
411 &UsbKeyboardDevice
->SimpleInput
,
412 &gEfiHotPlugDeviceGuid
,
416 gBS
->CloseEvent (UsbKeyboardDevice
->SimpleInput
.WaitForKey
);
417 gBS
->FreePool (UsbKeyboardDevice
);
420 &gEfiUsbIoProtocolGuid
,
421 This
->DriverBindingHandle
,
427 // submit async interrupt transfer
429 EndpointAddr
= UsbKeyboardDevice
->IntEndpointDescriptor
.EndpointAddress
;
430 PollingInterval
= UsbKeyboardDevice
->IntEndpointDescriptor
.Interval
;
431 PacketSize
= (UINT8
) (UsbKeyboardDevice
->IntEndpointDescriptor
.MaxPacketSize
);
433 Status
= UsbIo
->UsbAsyncInterruptTransfer (
443 if (EFI_ERROR (Status
)) {
445 gBS
->UninstallMultipleProtocolInterfaces (
447 &gEfiSimpleTextInProtocolGuid
,
448 &UsbKeyboardDevice
->SimpleInput
,
449 &gEfiHotPlugDeviceGuid
,
453 gBS
->CloseEvent (UsbKeyboardDevice
->SimpleInput
.WaitForKey
);
454 gBS
->FreePool (UsbKeyboardDevice
);
457 &gEfiUsbIoProtocolGuid
,
458 This
->DriverBindingHandle
,
464 UsbKeyboardDevice
->ControllerNameTable
= NULL
;
467 gUsbKeyboardComponentName
.SupportedLanguages
,
468 &UsbKeyboardDevice
->ControllerNameTable
,
469 L
"Generic Usb Keyboard"
480 @param This EFI_DRIVER_BINDING_PROTOCOL
481 @param Controller Controller handle
482 @param NumberOfChildren Child handle number
483 @param ChildHandleBuffer Child handle buffer
485 @retval EFI_SUCCESS Success
486 @retval EFI_UNSUPPORTED Can't support
491 USBKeyboardDriverBindingStop (
492 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
493 IN EFI_HANDLE Controller
,
494 IN UINTN NumberOfChildren
,
495 IN EFI_HANDLE
*ChildHandleBuffer
499 EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*SimpleInput
;
500 USB_KB_DEV
*UsbKeyboardDevice
;
502 Status
= gBS
->OpenProtocol (
504 &gEfiSimpleTextInProtocolGuid
,
505 (VOID
**) &SimpleInput
,
506 This
->DriverBindingHandle
,
508 EFI_OPEN_PROTOCOL_BY_DRIVER
510 if (EFI_ERROR (Status
)) {
511 return EFI_UNSUPPORTED
;
515 // Get USB_KB_DEV instance.
517 UsbKeyboardDevice
= USB_KB_DEV_FROM_THIS (SimpleInput
);
521 &gEfiSimpleTextInProtocolGuid
,
522 This
->DriverBindingHandle
,
527 // Uninstall the Asyn Interrupt Transfer from this device
528 // will disable the key data input from this device
530 KbdReportStatusCode (
531 UsbKeyboardDevice
->DevicePath
,
533 PcdGet32 (PcdStatusCodeValueKeyboardDisable
)
537 // Destroy asynchronous interrupt transfer
539 UsbKeyboardDevice
->UsbIo
->UsbAsyncInterruptTransfer (
540 UsbKeyboardDevice
->UsbIo
,
541 UsbKeyboardDevice
->IntEndpointDescriptor
.EndpointAddress
,
543 UsbKeyboardDevice
->IntEndpointDescriptor
.Interval
,
551 &gEfiUsbIoProtocolGuid
,
552 This
->DriverBindingHandle
,
556 Status
= gBS
->UninstallMultipleProtocolInterfaces (
558 &gEfiSimpleTextInProtocolGuid
,
559 &UsbKeyboardDevice
->SimpleInput
,
560 &gEfiHotPlugDeviceGuid
,
565 // free all the resources.
567 gBS
->CloseEvent (UsbKeyboardDevice
->RepeatTimer
);
568 gBS
->CloseEvent (UsbKeyboardDevice
->DelayedRecoveryEvent
);
569 gBS
->CloseEvent ((UsbKeyboardDevice
->SimpleInput
).WaitForKey
);
571 if (UsbKeyboardDevice
->ControllerNameTable
!= NULL
) {
572 FreeUnicodeStringTable (UsbKeyboardDevice
->ControllerNameTable
);
575 gBS
->FreePool (UsbKeyboardDevice
);
584 Implements EFI_SIMPLE_TEXT_INPUT_PROTOCOL.Reset() function.
586 This The EFI_SIMPLE_TEXT_INPUT_PROTOCOL instance.
588 Indicates that the driver may perform a more exhaustive
589 verification operation of the device during reset.
591 @retval EFI_SUCCESS Success
592 @retval EFI_DEVICE_ERROR Hardware Error
598 IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*This
,
599 IN BOOLEAN ExtendedVerification
603 USB_KB_DEV
*UsbKeyboardDevice
;
605 UsbKeyboardDevice
= USB_KB_DEV_FROM_THIS (This
);
607 KbdReportStatusCode (
608 UsbKeyboardDevice
->DevicePath
,
610 PcdGet32 (PcdStatusCodeValueKeyboardReset
)
614 // Non Exhaustive reset:
615 // only reset private data structures.
617 if (!ExtendedVerification
) {
619 // Clear the key buffer of this Usb keyboard
621 KbdReportStatusCode (
622 UsbKeyboardDevice
->DevicePath
,
624 PcdGet32 (PcdStatusCodeValueKeyboardClearBuffer
)
627 InitUSBKeyBuffer (&(UsbKeyboardDevice
->KeyboardBuffer
));
628 UsbKeyboardDevice
->CurKeyChar
= 0;
635 Status
= InitUSBKeyboard (UsbKeyboardDevice
);
636 UsbKeyboardDevice
->CurKeyChar
= 0;
637 if (EFI_ERROR (Status
)) {
638 return EFI_DEVICE_ERROR
;
646 Implements EFI_SIMPLE_TEXT_INPUT_PROTOCOL.ReadKeyStroke() function.
648 This The EFI_SIMPLE_TEXT_INPUT_PROTOCOL instance.
649 Key A pointer to a buffer that is filled in with the keystroke
650 information for the key that was pressed.
652 @retval EFI_SUCCESS Success
658 USBKeyboardReadKeyStroke (
659 IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*This
,
660 OUT EFI_INPUT_KEY
*Key
663 USB_KB_DEV
*UsbKeyboardDevice
;
667 UsbKeyboardDevice
= USB_KB_DEV_FROM_THIS (This
);
670 // if there is no saved ASCII byte, fetch it
671 // by calling USBKeyboardCheckForKey().
673 if (UsbKeyboardDevice
->CurKeyChar
== 0) {
674 Status
= USBKeyboardCheckForKey (UsbKeyboardDevice
);
675 if (EFI_ERROR (Status
)) {
680 Key
->UnicodeChar
= 0;
681 Key
->ScanCode
= SCAN_NULL
;
683 KeyChar
= UsbKeyboardDevice
->CurKeyChar
;
685 UsbKeyboardDevice
->CurKeyChar
= 0;
688 // Translate saved ASCII byte into EFI_INPUT_KEY
690 Status
= USBKeyCodeToEFIScanCode (UsbKeyboardDevice
, KeyChar
, Key
);
698 Handler function for WaitForKey event.
700 Event Event to be signaled when a key is pressed.
701 Context Points to USB_KB_DEV instance.
709 USBKeyboardWaitForKey (
714 USB_KB_DEV
*UsbKeyboardDevice
;
716 UsbKeyboardDevice
= (USB_KB_DEV
*) Context
;
718 if (UsbKeyboardDevice
->CurKeyChar
== 0) {
720 if (EFI_ERROR (USBKeyboardCheckForKey (UsbKeyboardDevice
))) {
725 // If has key pending, signal the event.
727 gBS
->SignalEvent (Event
);
733 Check whether there is key pending.
735 UsbKeyboardDevice The USB_KB_DEV instance.
737 @retval EFI_SUCCESS Success
742 USBKeyboardCheckForKey (
743 IN USB_KB_DEV
*UsbKeyboardDevice
750 // Fetch raw data from the USB keyboard input,
751 // and translate it into ASCII data.
753 Status
= USBParseKey (UsbKeyboardDevice
, &KeyChar
);
754 if (EFI_ERROR (Status
)) {
758 UsbKeyboardDevice
->CurKeyChar
= KeyChar
;
764 Report Status Code in Usb Bot Driver
766 @param DevicePath Use this to get Device Path
767 @param CodeType Status Code Type
768 @param CodeValue Status Code Value
774 KbdReportStatusCode (
775 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
,
776 IN EFI_STATUS_CODE_TYPE CodeType
,
777 IN EFI_STATUS_CODE_VALUE Value
781 REPORT_STATUS_CODE_WITH_DEVICE_PATH (