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 EfiLibInstallDriverBindingComponentName2 (
138 &gUsbKeyboardDriverBinding
,
140 &gUsbKeyboardComponentName
,
141 &gUsbKeyboardComponentName2
150 @param This EFI_DRIVER_BINDING_PROTOCOL
151 @param Controller Controller handle
152 @param RemainingDevicePath EFI_DEVICE_PATH_PROTOCOL
158 USBKeyboardDriverBindingSupported (
159 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
160 IN EFI_HANDLE Controller
,
161 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
164 EFI_STATUS OpenStatus
;
165 EFI_USB_IO_PROTOCOL
*UsbIo
;
169 // Check if USB_IO protocol is attached on the controller handle.
171 OpenStatus
= gBS
->OpenProtocol (
173 &gEfiUsbIoProtocolGuid
,
175 This
->DriverBindingHandle
,
177 EFI_OPEN_PROTOCOL_BY_DRIVER
179 if (EFI_ERROR (OpenStatus
)) {
184 // Use the USB I/O protocol interface to check whether the Controller is
185 // the Keyboard controller that can be managed by this driver.
187 Status
= EFI_SUCCESS
;
189 if (!IsUSBKeyboard (UsbIo
)) {
190 Status
= EFI_UNSUPPORTED
;
195 &gEfiUsbIoProtocolGuid
,
196 This
->DriverBindingHandle
,
207 @param This EFI_DRIVER_BINDING_PROTOCOL
208 @param Controller Controller handle
209 @param RemainingDevicePath EFI_DEVICE_PATH_PROTOCOL
211 @retval EFI_SUCCESS Success
212 @retval EFI_OUT_OF_RESOURCES Can't allocate memory
213 @retval EFI_UNSUPPORTED The Start routine fail
218 USBKeyboardDriverBindingStart (
219 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
220 IN EFI_HANDLE Controller
,
221 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
225 EFI_USB_IO_PROTOCOL
*UsbIo
;
226 USB_KB_DEV
*UsbKeyboardDevice
;
227 UINT8 EndpointNumber
;
228 EFI_USB_ENDPOINT_DESCRIPTOR EndpointDescriptor
;
231 UINT8 PollingInterval
;
235 UsbKeyboardDevice
= NULL
;
239 // Open USB_IO Protocol
241 Status
= gBS
->OpenProtocol (
243 &gEfiUsbIoProtocolGuid
,
245 This
->DriverBindingHandle
,
247 EFI_OPEN_PROTOCOL_BY_DRIVER
249 if (EFI_ERROR (Status
)) {
253 UsbKeyboardDevice
= AllocateZeroPool (sizeof (USB_KB_DEV
));
254 if (UsbKeyboardDevice
== NULL
) {
257 &gEfiUsbIoProtocolGuid
,
258 This
->DriverBindingHandle
,
261 return EFI_OUT_OF_RESOURCES
;
264 // Get the Device Path Protocol on Controller's handle
266 Status
= gBS
->OpenProtocol (
268 &gEfiDevicePathProtocolGuid
,
269 (VOID
**) &UsbKeyboardDevice
->DevicePath
,
270 This
->DriverBindingHandle
,
272 EFI_OPEN_PROTOCOL_GET_PROTOCOL
275 if (EFI_ERROR (Status
)) {
276 gBS
->FreePool (UsbKeyboardDevice
);
279 &gEfiUsbIoProtocolGuid
,
280 This
->DriverBindingHandle
,
286 // Report that the usb keyboard is being enabled
288 KbdReportStatusCode (
289 UsbKeyboardDevice
->DevicePath
,
291 PcdGet32 (PcdStatusCodeValueKeyboardEnable
)
295 // This is pretty close to keyboard detection, so log progress
297 KbdReportStatusCode (
298 UsbKeyboardDevice
->DevicePath
,
300 PcdGet32 (PcdStatusCodeValueKeyboardPresenceDetect
)
304 // Initialize UsbKeyboardDevice
306 UsbKeyboardDevice
->UsbIo
= UsbIo
;
309 // Get interface & endpoint descriptor
311 UsbIo
->UsbGetInterfaceDescriptor (
313 &UsbKeyboardDevice
->InterfaceDescriptor
316 EndpointNumber
= UsbKeyboardDevice
->InterfaceDescriptor
.NumEndpoints
;
318 for (Index
= 0; Index
< EndpointNumber
; Index
++) {
320 UsbIo
->UsbGetEndpointDescriptor (
326 if ((EndpointDescriptor
.Attributes
& 0x03) == 0x03) {
328 // We only care interrupt endpoint here
330 CopyMem(&UsbKeyboardDevice
->IntEndpointDescriptor
, &EndpointDescriptor
, sizeof(EndpointDescriptor
));
337 // No interrupt endpoint found, then return unsupported.
339 gBS
->FreePool (UsbKeyboardDevice
);
342 &gEfiUsbIoProtocolGuid
,
343 This
->DriverBindingHandle
,
346 return EFI_UNSUPPORTED
;
349 UsbKeyboardDevice
->Signature
= USB_KB_DEV_SIGNATURE
;
350 UsbKeyboardDevice
->SimpleInput
.Reset
= USBKeyboardReset
;
351 UsbKeyboardDevice
->SimpleInput
.ReadKeyStroke
= USBKeyboardReadKeyStroke
;
352 Status
= gBS
->CreateEvent (
355 USBKeyboardWaitForKey
,
357 &(UsbKeyboardDevice
->SimpleInput
.WaitForKey
)
360 if (EFI_ERROR (Status
)) {
361 gBS
->FreePool (UsbKeyboardDevice
);
364 &gEfiUsbIoProtocolGuid
,
365 This
->DriverBindingHandle
,
372 // Install simple txt in protocol interface
373 // for the usb keyboard device.
374 // Usb keyboard is a hot plug device, and expected to work immediately
375 // when plugging into system, so a HotPlugDeviceGuid is installed onto
376 // the usb keyboard device handle, to distinguish it from other conventional
379 Status
= gBS
->InstallMultipleProtocolInterfaces (
381 &gEfiSimpleTextInProtocolGuid
,
382 &UsbKeyboardDevice
->SimpleInput
,
383 &gEfiHotPlugDeviceGuid
,
387 if (EFI_ERROR (Status
)) {
388 gBS
->CloseEvent (UsbKeyboardDevice
->SimpleInput
.WaitForKey
);
389 gBS
->FreePool (UsbKeyboardDevice
);
392 &gEfiUsbIoProtocolGuid
,
393 This
->DriverBindingHandle
,
400 // Reset USB Keyboard Device
402 Status
= UsbKeyboardDevice
->SimpleInput
.Reset (
403 &UsbKeyboardDevice
->SimpleInput
,
406 if (EFI_ERROR (Status
)) {
407 gBS
->UninstallMultipleProtocolInterfaces (
409 &gEfiSimpleTextInProtocolGuid
,
410 &UsbKeyboardDevice
->SimpleInput
,
411 &gEfiHotPlugDeviceGuid
,
415 gBS
->CloseEvent (UsbKeyboardDevice
->SimpleInput
.WaitForKey
);
416 gBS
->FreePool (UsbKeyboardDevice
);
419 &gEfiUsbIoProtocolGuid
,
420 This
->DriverBindingHandle
,
426 // submit async interrupt transfer
428 EndpointAddr
= UsbKeyboardDevice
->IntEndpointDescriptor
.EndpointAddress
;
429 PollingInterval
= UsbKeyboardDevice
->IntEndpointDescriptor
.Interval
;
430 PacketSize
= (UINT8
) (UsbKeyboardDevice
->IntEndpointDescriptor
.MaxPacketSize
);
432 Status
= UsbIo
->UsbAsyncInterruptTransfer (
442 if (EFI_ERROR (Status
)) {
444 gBS
->UninstallMultipleProtocolInterfaces (
446 &gEfiSimpleTextInProtocolGuid
,
447 &UsbKeyboardDevice
->SimpleInput
,
448 &gEfiHotPlugDeviceGuid
,
452 gBS
->CloseEvent (UsbKeyboardDevice
->SimpleInput
.WaitForKey
);
453 gBS
->FreePool (UsbKeyboardDevice
);
456 &gEfiUsbIoProtocolGuid
,
457 This
->DriverBindingHandle
,
463 UsbKeyboardDevice
->ControllerNameTable
= NULL
;
466 gUsbKeyboardComponentName
.SupportedLanguages
,
467 &UsbKeyboardDevice
->ControllerNameTable
,
468 L
"Generic Usb Keyboard",
473 gUsbKeyboardComponentName2
.SupportedLanguages
,
474 &UsbKeyboardDevice
->ControllerNameTable
,
475 L
"Generic Usb Keyboard",
488 @param This EFI_DRIVER_BINDING_PROTOCOL
489 @param Controller Controller handle
490 @param NumberOfChildren Child handle number
491 @param ChildHandleBuffer Child handle buffer
493 @retval EFI_SUCCESS Success
494 @retval EFI_UNSUPPORTED Can't support
499 USBKeyboardDriverBindingStop (
500 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
501 IN EFI_HANDLE Controller
,
502 IN UINTN NumberOfChildren
,
503 IN EFI_HANDLE
*ChildHandleBuffer
507 EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*SimpleInput
;
508 USB_KB_DEV
*UsbKeyboardDevice
;
510 Status
= gBS
->OpenProtocol (
512 &gEfiSimpleTextInProtocolGuid
,
513 (VOID
**) &SimpleInput
,
514 This
->DriverBindingHandle
,
516 EFI_OPEN_PROTOCOL_BY_DRIVER
518 if (EFI_ERROR (Status
)) {
519 return EFI_UNSUPPORTED
;
523 // Get USB_KB_DEV instance.
525 UsbKeyboardDevice
= USB_KB_DEV_FROM_THIS (SimpleInput
);
529 &gEfiSimpleTextInProtocolGuid
,
530 This
->DriverBindingHandle
,
535 // Uninstall the Asyn Interrupt Transfer from this device
536 // will disable the key data input from this device
538 KbdReportStatusCode (
539 UsbKeyboardDevice
->DevicePath
,
541 PcdGet32 (PcdStatusCodeValueKeyboardDisable
)
545 // Destroy asynchronous interrupt transfer
547 UsbKeyboardDevice
->UsbIo
->UsbAsyncInterruptTransfer (
548 UsbKeyboardDevice
->UsbIo
,
549 UsbKeyboardDevice
->IntEndpointDescriptor
.EndpointAddress
,
551 UsbKeyboardDevice
->IntEndpointDescriptor
.Interval
,
559 &gEfiUsbIoProtocolGuid
,
560 This
->DriverBindingHandle
,
564 Status
= gBS
->UninstallMultipleProtocolInterfaces (
566 &gEfiSimpleTextInProtocolGuid
,
567 &UsbKeyboardDevice
->SimpleInput
,
568 &gEfiHotPlugDeviceGuid
,
573 // free all the resources.
575 gBS
->CloseEvent (UsbKeyboardDevice
->RepeatTimer
);
576 gBS
->CloseEvent (UsbKeyboardDevice
->DelayedRecoveryEvent
);
577 gBS
->CloseEvent ((UsbKeyboardDevice
->SimpleInput
).WaitForKey
);
579 if (UsbKeyboardDevice
->ControllerNameTable
!= NULL
) {
580 FreeUnicodeStringTable (UsbKeyboardDevice
->ControllerNameTable
);
583 gBS
->FreePool (UsbKeyboardDevice
);
592 Implements EFI_SIMPLE_TEXT_INPUT_PROTOCOL.Reset() function.
594 This The EFI_SIMPLE_TEXT_INPUT_PROTOCOL instance.
596 Indicates that the driver may perform a more exhaustive
597 verification operation of the device during reset.
599 @retval EFI_SUCCESS Success
600 @retval EFI_DEVICE_ERROR Hardware Error
606 IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*This
,
607 IN BOOLEAN ExtendedVerification
611 USB_KB_DEV
*UsbKeyboardDevice
;
613 UsbKeyboardDevice
= USB_KB_DEV_FROM_THIS (This
);
615 KbdReportStatusCode (
616 UsbKeyboardDevice
->DevicePath
,
618 PcdGet32 (PcdStatusCodeValueKeyboardReset
)
622 // Non Exhaustive reset:
623 // only reset private data structures.
625 if (!ExtendedVerification
) {
627 // Clear the key buffer of this Usb keyboard
629 KbdReportStatusCode (
630 UsbKeyboardDevice
->DevicePath
,
632 PcdGet32 (PcdStatusCodeValueKeyboardClearBuffer
)
635 InitUSBKeyBuffer (&(UsbKeyboardDevice
->KeyboardBuffer
));
636 UsbKeyboardDevice
->CurKeyChar
= 0;
643 Status
= InitUSBKeyboard (UsbKeyboardDevice
);
644 UsbKeyboardDevice
->CurKeyChar
= 0;
645 if (EFI_ERROR (Status
)) {
646 return EFI_DEVICE_ERROR
;
654 Implements EFI_SIMPLE_TEXT_INPUT_PROTOCOL.ReadKeyStroke() function.
656 This The EFI_SIMPLE_TEXT_INPUT_PROTOCOL instance.
657 Key A pointer to a buffer that is filled in with the keystroke
658 information for the key that was pressed.
660 @retval EFI_SUCCESS Success
666 USBKeyboardReadKeyStroke (
667 IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*This
,
668 OUT EFI_INPUT_KEY
*Key
671 USB_KB_DEV
*UsbKeyboardDevice
;
675 UsbKeyboardDevice
= USB_KB_DEV_FROM_THIS (This
);
678 // if there is no saved ASCII byte, fetch it
679 // by calling USBKeyboardCheckForKey().
681 if (UsbKeyboardDevice
->CurKeyChar
== 0) {
682 Status
= USBKeyboardCheckForKey (UsbKeyboardDevice
);
683 if (EFI_ERROR (Status
)) {
688 Key
->UnicodeChar
= 0;
689 Key
->ScanCode
= SCAN_NULL
;
691 KeyChar
= UsbKeyboardDevice
->CurKeyChar
;
693 UsbKeyboardDevice
->CurKeyChar
= 0;
696 // Translate saved ASCII byte into EFI_INPUT_KEY
698 Status
= USBKeyCodeToEFIScanCode (UsbKeyboardDevice
, KeyChar
, Key
);
706 Handler function for WaitForKey event.
708 Event Event to be signaled when a key is pressed.
709 Context Points to USB_KB_DEV instance.
717 USBKeyboardWaitForKey (
722 USB_KB_DEV
*UsbKeyboardDevice
;
724 UsbKeyboardDevice
= (USB_KB_DEV
*) Context
;
726 if (UsbKeyboardDevice
->CurKeyChar
== 0) {
728 if (EFI_ERROR (USBKeyboardCheckForKey (UsbKeyboardDevice
))) {
733 // If has key pending, signal the event.
735 gBS
->SignalEvent (Event
);
741 Check whether there is key pending.
743 UsbKeyboardDevice The USB_KB_DEV instance.
745 @retval EFI_SUCCESS Success
750 USBKeyboardCheckForKey (
751 IN USB_KB_DEV
*UsbKeyboardDevice
758 // Fetch raw data from the USB keyboard input,
759 // and translate it into ASCII data.
761 Status
= USBParseKey (UsbKeyboardDevice
, &KeyChar
);
762 if (EFI_ERROR (Status
)) {
766 UsbKeyboardDevice
->CurKeyChar
= KeyChar
;
772 Report Status Code in Usb Bot Driver
774 @param DevicePath Use this to get Device Path
775 @param CodeType Status Code Type
776 @param CodeValue Status Code Value
782 KbdReportStatusCode (
783 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
,
784 IN EFI_STATUS_CODE_TYPE CodeType
,
785 IN EFI_STATUS_CODE_VALUE Value
789 REPORT_STATUS_CODE_WITH_DEVICE_PATH (