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.
28 // Simple Text In Protocol Interface
34 IN EFI_SIMPLE_TEXT_IN_PROTOCOL
*This
,
35 IN BOOLEAN ExtendedVerification
41 USBKeyboardReadKeyStroke (
42 IN EFI_SIMPLE_TEXT_IN_PROTOCOL
*This
,
43 OUT EFI_INPUT_KEY
*Key
49 USBKeyboardWaitForKey (
59 USBKeyboardCheckForKey (
60 IN USB_KB_DEV
*UsbKeyboardDevice
64 // USB Keyboard Driver Global Variables
66 EFI_DRIVER_BINDING_PROTOCOL gUsbKeyboardDriverBinding
= {
67 USBKeyboardDriverBindingSupported
,
68 USBKeyboardDriverBindingStart
,
69 USBKeyboardDriverBindingStop
,
77 USBKeyboardDriverBindingSupported (
78 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
79 IN EFI_HANDLE Controller
,
80 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
88 This - EFI_DRIVER_BINDING_PROTOCOL
89 Controller - Controller handle
90 RemainingDevicePath - EFI_DEVICE_PATH_PROTOCOL
96 EFI_STATUS OpenStatus
;
97 EFI_USB_IO_PROTOCOL
*UsbIo
;
101 // Check if USB_IO protocol is attached on the controller handle.
103 OpenStatus
= gBS
->OpenProtocol (
105 &gEfiUsbIoProtocolGuid
,
107 This
->DriverBindingHandle
,
109 EFI_OPEN_PROTOCOL_BY_DRIVER
111 if (EFI_ERROR (OpenStatus
)) {
116 // Use the USB I/O protocol interface to check whether the Controller is
117 // the Keyboard controller that can be managed by this driver.
119 Status
= EFI_SUCCESS
;
121 if (!IsUSBKeyboard (UsbIo
)) {
122 Status
= EFI_UNSUPPORTED
;
127 &gEfiUsbIoProtocolGuid
,
128 This
->DriverBindingHandle
,
137 USBKeyboardDriverBindingStart (
138 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
139 IN EFI_HANDLE Controller
,
140 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
148 This - EFI_DRIVER_BINDING_PROTOCOL
149 Controller - Controller handle
150 RemainingDevicePath - EFI_DEVICE_PATH_PROTOCOL
152 EFI_SUCCESS - Success
153 EFI_OUT_OF_RESOURCES - Can't allocate memory
154 EFI_UNSUPPORTED - The Start routine fail
158 EFI_USB_IO_PROTOCOL
*UsbIo
;
159 USB_KB_DEV
*UsbKeyboardDevice
;
160 UINT8 EndpointNumber
;
161 EFI_USB_ENDPOINT_DESCRIPTOR EndpointDescriptor
;
164 UINT8 PollingInterval
;
168 UsbKeyboardDevice
= NULL
;
172 // Open USB_IO Protocol
174 Status
= gBS
->OpenProtocol (
176 &gEfiUsbIoProtocolGuid
,
178 This
->DriverBindingHandle
,
180 EFI_OPEN_PROTOCOL_BY_DRIVER
182 if (EFI_ERROR (Status
)) {
186 UsbKeyboardDevice
= AllocateZeroPool (sizeof (USB_KB_DEV
));
187 if (UsbKeyboardDevice
== NULL
) {
190 &gEfiUsbIoProtocolGuid
,
191 This
->DriverBindingHandle
,
194 return EFI_OUT_OF_RESOURCES
;
197 // Get the Device Path Protocol on Controller's handle
199 Status
= gBS
->OpenProtocol (
201 &gEfiDevicePathProtocolGuid
,
202 (VOID
**) &UsbKeyboardDevice
->DevicePath
,
203 This
->DriverBindingHandle
,
205 EFI_OPEN_PROTOCOL_GET_PROTOCOL
208 if (EFI_ERROR (Status
)) {
209 gBS
->FreePool (UsbKeyboardDevice
);
212 &gEfiUsbIoProtocolGuid
,
213 This
->DriverBindingHandle
,
219 // Report that the usb keyboard is being enabled
221 KbdReportStatusCode (
222 UsbKeyboardDevice
->DevicePath
,
224 (EFI_PERIPHERAL_KEYBOARD
| EFI_P_PC_ENABLE
)
228 // This is pretty close to keyboard detection, so log progress
230 KbdReportStatusCode (
231 UsbKeyboardDevice
->DevicePath
,
233 (EFI_PERIPHERAL_KEYBOARD
| EFI_P_PC_PRESENCE_DETECT
)
237 // Initialize UsbKeyboardDevice
239 UsbKeyboardDevice
->UsbIo
= UsbIo
;
242 // Get interface & endpoint descriptor
244 UsbIo
->UsbGetInterfaceDescriptor (
246 &UsbKeyboardDevice
->InterfaceDescriptor
249 EndpointNumber
= UsbKeyboardDevice
->InterfaceDescriptor
.NumEndpoints
;
251 for (Index
= 0; Index
< EndpointNumber
; Index
++) {
253 UsbIo
->UsbGetEndpointDescriptor (
259 if ((EndpointDescriptor
.Attributes
& 0x03) == 0x03) {
261 // We only care interrupt endpoint here
263 CopyMem (&UsbKeyboardDevice
->IntEndpointDescriptor
, &EndpointDescriptor
, sizeof (EndpointDescriptor
));
270 // No interrupt endpoint found, then return unsupported.
272 gBS
->FreePool (UsbKeyboardDevice
);
275 &gEfiUsbIoProtocolGuid
,
276 This
->DriverBindingHandle
,
279 return EFI_UNSUPPORTED
;
282 UsbKeyboardDevice
->Signature
= USB_KB_DEV_SIGNATURE
;
283 UsbKeyboardDevice
->SimpleInput
.Reset
= USBKeyboardReset
;
284 UsbKeyboardDevice
->SimpleInput
.ReadKeyStroke
= USBKeyboardReadKeyStroke
;
285 Status
= gBS
->CreateEvent (
286 EFI_EVENT_NOTIFY_WAIT
,
288 USBKeyboardWaitForKey
,
290 &(UsbKeyboardDevice
->SimpleInput
.WaitForKey
)
293 if (EFI_ERROR (Status
)) {
294 gBS
->FreePool (UsbKeyboardDevice
);
297 &gEfiUsbIoProtocolGuid
,
298 This
->DriverBindingHandle
,
305 // Install simple txt in protocol interface
306 // for the usb keyboard device.
307 // Usb keyboard is a hot plug device, and expected to work immediately
308 // when plugging into system, so a HotPlugDeviceGuid is installed onto
309 // the usb keyboard device handle, to distinguish it from other conventional
312 Status
= gBS
->InstallMultipleProtocolInterfaces (
314 &gEfiSimpleTextInProtocolGuid
,
315 &UsbKeyboardDevice
->SimpleInput
,
316 &gEfiHotPlugDeviceGuid
,
320 if (EFI_ERROR (Status
)) {
321 gBS
->CloseEvent (UsbKeyboardDevice
->SimpleInput
.WaitForKey
);
322 gBS
->FreePool (UsbKeyboardDevice
);
325 &gEfiUsbIoProtocolGuid
,
326 This
->DriverBindingHandle
,
333 // Reset USB Keyboard Device
335 Status
= UsbKeyboardDevice
->SimpleInput
.Reset (
336 &UsbKeyboardDevice
->SimpleInput
,
339 if (EFI_ERROR (Status
)) {
340 gBS
->UninstallMultipleProtocolInterfaces (
342 &gEfiSimpleTextInProtocolGuid
,
343 &UsbKeyboardDevice
->SimpleInput
,
344 &gEfiHotPlugDeviceGuid
,
348 gBS
->CloseEvent (UsbKeyboardDevice
->SimpleInput
.WaitForKey
);
349 gBS
->FreePool (UsbKeyboardDevice
);
352 &gEfiUsbIoProtocolGuid
,
353 This
->DriverBindingHandle
,
359 // submit async interrupt transfer
361 EndpointAddr
= UsbKeyboardDevice
->IntEndpointDescriptor
.EndpointAddress
;
362 PollingInterval
= UsbKeyboardDevice
->IntEndpointDescriptor
.Interval
;
363 PacketSize
= (UINT8
) (UsbKeyboardDevice
->IntEndpointDescriptor
.MaxPacketSize
);
365 Status
= UsbIo
->UsbAsyncInterruptTransfer (
375 if (EFI_ERROR (Status
)) {
377 gBS
->UninstallMultipleProtocolInterfaces (
379 &gEfiSimpleTextInProtocolGuid
,
380 &UsbKeyboardDevice
->SimpleInput
,
381 &gEfiHotPlugDeviceGuid
,
385 gBS
->CloseEvent (UsbKeyboardDevice
->SimpleInput
.WaitForKey
);
386 gBS
->FreePool (UsbKeyboardDevice
);
389 &gEfiUsbIoProtocolGuid
,
390 This
->DriverBindingHandle
,
396 UsbKeyboardDevice
->ControllerNameTable
= NULL
;
399 gUsbKeyboardComponentName
.SupportedLanguages
,
400 &UsbKeyboardDevice
->ControllerNameTable
,
401 (CHAR16
*) L
"Generic Usb Keyboard"
410 USBKeyboardDriverBindingStop (
411 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
412 IN EFI_HANDLE Controller
,
413 IN UINTN NumberOfChildren
,
414 IN EFI_HANDLE
*ChildHandleBuffer
422 This - EFI_DRIVER_BINDING_PROTOCOL
423 Controller - Controller handle
424 NumberOfChildren - Child handle number
425 ChildHandleBuffer - Child handle buffer
427 EFI_SUCCESS - Success
428 EFI_UNSUPPORTED - Can't support
432 EFI_SIMPLE_TEXT_IN_PROTOCOL
*SimpleInput
;
433 USB_KB_DEV
*UsbKeyboardDevice
;
435 Status
= gBS
->OpenProtocol (
437 &gEfiSimpleTextInProtocolGuid
,
438 (VOID
**) &SimpleInput
,
439 This
->DriverBindingHandle
,
441 EFI_OPEN_PROTOCOL_BY_DRIVER
443 if (EFI_ERROR (Status
)) {
444 return EFI_UNSUPPORTED
;
448 // Get USB_KB_DEV instance.
450 UsbKeyboardDevice
= USB_KB_DEV_FROM_THIS (SimpleInput
);
454 &gEfiSimpleTextInProtocolGuid
,
455 This
->DriverBindingHandle
,
460 // Uninstall the Asyn Interrupt Transfer from this device
461 // will disable the key data input from this device
463 KbdReportStatusCode (
464 UsbKeyboardDevice
->DevicePath
,
466 (EFI_PERIPHERAL_KEYBOARD
| EFI_P_PC_DISABLE
)
470 // Destroy asynchronous interrupt transfer
472 UsbKeyboardDevice
->UsbIo
->UsbAsyncInterruptTransfer (
473 UsbKeyboardDevice
->UsbIo
,
474 UsbKeyboardDevice
->IntEndpointDescriptor
.EndpointAddress
,
476 UsbKeyboardDevice
->IntEndpointDescriptor
.Interval
,
484 &gEfiUsbIoProtocolGuid
,
485 This
->DriverBindingHandle
,
489 Status
= gBS
->UninstallMultipleProtocolInterfaces (
491 &gEfiSimpleTextInProtocolGuid
,
492 &UsbKeyboardDevice
->SimpleInput
,
493 &gEfiHotPlugDeviceGuid
,
498 // free all the resources.
500 gBS
->CloseEvent (UsbKeyboardDevice
->RepeatTimer
);
501 gBS
->CloseEvent (UsbKeyboardDevice
->DelayedRecoveryEvent
);
502 gBS
->CloseEvent ((UsbKeyboardDevice
->SimpleInput
).WaitForKey
);
504 if (UsbKeyboardDevice
->ControllerNameTable
!= NULL
) {
505 FreeUnicodeStringTable (UsbKeyboardDevice
->ControllerNameTable
);
508 gBS
->FreePool (UsbKeyboardDevice
);
518 IN EFI_SIMPLE_TEXT_IN_PROTOCOL
*This
,
519 IN BOOLEAN ExtendedVerification
524 Implements EFI_SIMPLE_TEXT_IN_PROTOCOL.Reset() function.
527 This The EFI_SIMPLE_TEXT_IN_PROTOCOL instance.
529 Indicates that the driver may perform a more exhaustive
530 verification operation of the device during reset.
533 EFI_SUCCESS - Success
534 EFI_DEVICE_ERROR - Hardware Error
538 USB_KB_DEV
*UsbKeyboardDevice
;
540 UsbKeyboardDevice
= USB_KB_DEV_FROM_THIS (This
);
542 KbdReportStatusCode (
543 UsbKeyboardDevice
->DevicePath
,
545 (EFI_PERIPHERAL_KEYBOARD
| EFI_P_PC_RESET
)
549 // Non Exhaustive reset:
550 // only reset private data structures.
552 if (!ExtendedVerification
) {
554 // Clear the key buffer of this Usb keyboard
556 KbdReportStatusCode (
557 UsbKeyboardDevice
->DevicePath
,
559 (EFI_PERIPHERAL_KEYBOARD
| EFI_P_KEYBOARD_PC_CLEAR_BUFFER
)
562 InitUSBKeyBuffer (&(UsbKeyboardDevice
->KeyboardBuffer
));
563 UsbKeyboardDevice
->CurKeyChar
= 0;
570 Status
= InitUSBKeyboard (UsbKeyboardDevice
);
571 UsbKeyboardDevice
->CurKeyChar
= 0;
572 if (EFI_ERROR (Status
)) {
573 return EFI_DEVICE_ERROR
;
582 USBKeyboardReadKeyStroke (
583 IN EFI_SIMPLE_TEXT_IN_PROTOCOL
*This
,
584 OUT EFI_INPUT_KEY
*Key
589 Implements EFI_SIMPLE_TEXT_IN_PROTOCOL.ReadKeyStroke() function.
592 This The EFI_SIMPLE_TEXT_IN_PROTOCOL instance.
593 Key A pointer to a buffer that is filled in with the keystroke
594 information for the key that was pressed.
597 EFI_SUCCESS - Success
600 USB_KB_DEV
*UsbKeyboardDevice
;
604 UsbKeyboardDevice
= USB_KB_DEV_FROM_THIS (This
);
607 // if there is no saved ASCII byte, fetch it
608 // by calling USBKeyboardCheckForKey().
610 if (UsbKeyboardDevice
->CurKeyChar
== 0) {
611 Status
= USBKeyboardCheckForKey (UsbKeyboardDevice
);
612 if (EFI_ERROR (Status
)) {
617 Key
->UnicodeChar
= 0;
618 Key
->ScanCode
= SCAN_NULL
;
620 KeyChar
= UsbKeyboardDevice
->CurKeyChar
;
622 UsbKeyboardDevice
->CurKeyChar
= 0;
625 // Translate saved ASCII byte into EFI_INPUT_KEY
627 Status
= USBKeyCodeToEFIScanCode (UsbKeyboardDevice
, KeyChar
, Key
);
636 USBKeyboardWaitForKey (
643 Handler function for WaitForKey event.
646 Event Event to be signaled when a key is pressed.
647 Context Points to USB_KB_DEV instance.
653 USB_KB_DEV
*UsbKeyboardDevice
;
655 UsbKeyboardDevice
= (USB_KB_DEV
*) Context
;
657 if (UsbKeyboardDevice
->CurKeyChar
== 0) {
659 if (EFI_ERROR (USBKeyboardCheckForKey (UsbKeyboardDevice
))) {
664 // If has key pending, signal the event.
666 gBS
->SignalEvent (Event
);
672 USBKeyboardCheckForKey (
673 IN USB_KB_DEV
*UsbKeyboardDevice
678 Check whether there is key pending.
681 UsbKeyboardDevice The USB_KB_DEV instance.
684 EFI_SUCCESS - Success
691 // Fetch raw data from the USB keyboard input,
692 // and translate it into ASCII data.
694 Status
= USBParseKey (UsbKeyboardDevice
, &KeyChar
);
695 if (EFI_ERROR (Status
)) {
699 UsbKeyboardDevice
->CurKeyChar
= KeyChar
;
704 KbdReportStatusCode (
705 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
,
706 IN EFI_STATUS_CODE_TYPE CodeType
,
707 IN EFI_STATUS_CODE_VALUE Value
712 Report Status Code in Usb Bot Driver
715 DevicePath - Use this to get Device Path
716 CodeType - Status Code Type
717 CodeValue - Status Code Value
725 REPORT_STATUS_CODE_WITH_DEVICE_PATH (