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.
29 // Driver model protocol interface
33 USBKeyboardDriverBindingEntryPoint (
34 IN EFI_HANDLE ImageHandle
,
35 IN EFI_SYSTEM_TABLE
*SystemTable
40 USBKeyboardDriverBindingSupported (
41 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
42 IN EFI_HANDLE Controller
,
43 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
48 USBKeyboardDriverBindingStart (
49 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
50 IN EFI_HANDLE Controller
,
51 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
56 USBKeyboardDriverBindingStop (
57 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
58 IN EFI_HANDLE Controller
,
59 IN UINTN NumberOfChildren
,
60 IN EFI_HANDLE
*ChildHandleBuffer
64 // Simple Text In Protocol Interface
70 IN EFI_SIMPLE_TEXT_IN_PROTOCOL
*This
,
71 IN BOOLEAN ExtendedVerification
77 USBKeyboardReadKeyStroke (
78 IN EFI_SIMPLE_TEXT_IN_PROTOCOL
*This
,
79 OUT EFI_INPUT_KEY
*Key
85 USBKeyboardWaitForKey (
95 USBKeyboardCheckForKey (
96 IN USB_KB_DEV
*UsbKeyboardDevice
100 // USB Keyboard Driver Global Variables
102 EFI_DRIVER_BINDING_PROTOCOL gUsbKeyboardDriverBinding
= {
103 USBKeyboardDriverBindingSupported
,
104 USBKeyboardDriverBindingStart
,
105 USBKeyboardDriverBindingStop
,
113 USBKeyboardDriverBindingSupported (
114 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
115 IN EFI_HANDLE Controller
,
116 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
124 This - EFI_DRIVER_BINDING_PROTOCOL
125 Controller - Controller handle
126 RemainingDevicePath - EFI_DEVICE_PATH_PROTOCOL
132 EFI_STATUS OpenStatus
;
133 EFI_USB_IO_PROTOCOL
*UsbIo
;
137 // Check if USB_IO protocol is attached on the controller handle.
139 OpenStatus
= gBS
->OpenProtocol (
141 &gEfiUsbIoProtocolGuid
,
143 This
->DriverBindingHandle
,
145 EFI_OPEN_PROTOCOL_BY_DRIVER
147 if (EFI_ERROR (OpenStatus
)) {
152 // Use the USB I/O protocol interface to check whether the Controller is
153 // the Keyboard controller that can be managed by this driver.
155 Status
= EFI_SUCCESS
;
157 if (!IsUSBKeyboard (UsbIo
)) {
158 Status
= EFI_UNSUPPORTED
;
163 &gEfiUsbIoProtocolGuid
,
164 This
->DriverBindingHandle
,
173 USBKeyboardDriverBindingStart (
174 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
175 IN EFI_HANDLE Controller
,
176 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
184 This - EFI_DRIVER_BINDING_PROTOCOL
185 Controller - Controller handle
186 RemainingDevicePath - EFI_DEVICE_PATH_PROTOCOL
188 EFI_SUCCESS - Success
189 EFI_OUT_OF_RESOURCES - Can't allocate memory
190 EFI_UNSUPPORTED - The Start routine fail
194 EFI_USB_IO_PROTOCOL
*UsbIo
;
195 USB_KB_DEV
*UsbKeyboardDevice
;
196 UINT8 EndpointNumber
;
197 EFI_USB_ENDPOINT_DESCRIPTOR EndpointDescriptor
;
200 UINT8 PollingInterval
;
204 UsbKeyboardDevice
= NULL
;
208 // Open USB_IO Protocol
210 Status
= gBS
->OpenProtocol (
212 &gEfiUsbIoProtocolGuid
,
214 This
->DriverBindingHandle
,
216 EFI_OPEN_PROTOCOL_BY_DRIVER
218 if (EFI_ERROR (Status
)) {
222 UsbKeyboardDevice
= AllocateZeroPool (sizeof (USB_KB_DEV
));
223 if (UsbKeyboardDevice
== NULL
) {
226 &gEfiUsbIoProtocolGuid
,
227 This
->DriverBindingHandle
,
230 return EFI_OUT_OF_RESOURCES
;
233 // Get the Device Path Protocol on Controller's handle
235 Status
= gBS
->OpenProtocol (
237 &gEfiDevicePathProtocolGuid
,
238 (VOID
**) &UsbKeyboardDevice
->DevicePath
,
239 This
->DriverBindingHandle
,
241 EFI_OPEN_PROTOCOL_GET_PROTOCOL
244 if (EFI_ERROR (Status
)) {
245 gBS
->FreePool (UsbKeyboardDevice
);
248 &gEfiUsbIoProtocolGuid
,
249 This
->DriverBindingHandle
,
255 // Report that the usb keyboard is being enabled
257 KbdReportStatusCode (
258 UsbKeyboardDevice
->DevicePath
,
260 (EFI_PERIPHERAL_KEYBOARD
| EFI_P_PC_ENABLE
)
264 // This is pretty close to keyboard detection, so log progress
266 KbdReportStatusCode (
267 UsbKeyboardDevice
->DevicePath
,
269 (EFI_PERIPHERAL_KEYBOARD
| EFI_P_PC_PRESENCE_DETECT
)
273 // Initialize UsbKeyboardDevice
275 UsbKeyboardDevice
->UsbIo
= UsbIo
;
278 // Get interface & endpoint descriptor
280 UsbIo
->UsbGetInterfaceDescriptor (
282 &UsbKeyboardDevice
->InterfaceDescriptor
285 EndpointNumber
= UsbKeyboardDevice
->InterfaceDescriptor
.NumEndpoints
;
287 for (Index
= 0; Index
< EndpointNumber
; Index
++) {
289 UsbIo
->UsbGetEndpointDescriptor (
295 if ((EndpointDescriptor
.Attributes
& 0x03) == 0x03) {
297 // We only care interrupt endpoint here
299 CopyMem (&UsbKeyboardDevice
->IntEndpointDescriptor
, &EndpointDescriptor
, sizeof (EndpointDescriptor
));
300 //UsbKeyboardDevice->IntEndpointDescriptor = EndpointDescriptor;
307 // No interrupt endpoint found, then return unsupported.
309 gBS
->FreePool (UsbKeyboardDevice
);
312 &gEfiUsbIoProtocolGuid
,
313 This
->DriverBindingHandle
,
316 return EFI_UNSUPPORTED
;
319 UsbKeyboardDevice
->Signature
= USB_KB_DEV_SIGNATURE
;
320 UsbKeyboardDevice
->SimpleInput
.Reset
= USBKeyboardReset
;
321 UsbKeyboardDevice
->SimpleInput
.ReadKeyStroke
= USBKeyboardReadKeyStroke
;
322 Status
= gBS
->CreateEvent (
323 EFI_EVENT_NOTIFY_WAIT
,
325 USBKeyboardWaitForKey
,
327 &(UsbKeyboardDevice
->SimpleInput
.WaitForKey
)
330 if (EFI_ERROR (Status
)) {
331 gBS
->FreePool (UsbKeyboardDevice
);
334 &gEfiUsbIoProtocolGuid
,
335 This
->DriverBindingHandle
,
342 // Install simple txt in protocol interface
343 // for the usb keyboard device.
344 // Usb keyboard is a hot plug device, and expected to work immediately
345 // when plugging into system, so a HotPlugDeviceGuid is installed onto
346 // the usb keyboard device handle, to distinguish it from other conventional
349 Status
= gBS
->InstallMultipleProtocolInterfaces (
351 &gEfiSimpleTextInProtocolGuid
,
352 &UsbKeyboardDevice
->SimpleInput
,
353 &gEfiHotPlugDeviceGuid
,
357 if (EFI_ERROR (Status
)) {
358 gBS
->CloseEvent (UsbKeyboardDevice
->SimpleInput
.WaitForKey
);
359 gBS
->FreePool (UsbKeyboardDevice
);
362 &gEfiUsbIoProtocolGuid
,
363 This
->DriverBindingHandle
,
370 // Reset USB Keyboard Device
372 Status
= UsbKeyboardDevice
->SimpleInput
.Reset (
373 &UsbKeyboardDevice
->SimpleInput
,
376 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 // submit async interrupt transfer
398 EndpointAddr
= UsbKeyboardDevice
->IntEndpointDescriptor
.EndpointAddress
;
399 PollingInterval
= UsbKeyboardDevice
->IntEndpointDescriptor
.Interval
;
400 PacketSize
= (UINT8
) (UsbKeyboardDevice
->IntEndpointDescriptor
.MaxPacketSize
);
402 Status
= UsbIo
->UsbAsyncInterruptTransfer (
412 if (EFI_ERROR (Status
)) {
414 gBS
->UninstallMultipleProtocolInterfaces (
416 &gEfiSimpleTextInProtocolGuid
,
417 &UsbKeyboardDevice
->SimpleInput
,
418 &gEfiHotPlugDeviceGuid
,
422 gBS
->CloseEvent (UsbKeyboardDevice
->SimpleInput
.WaitForKey
);
423 gBS
->FreePool (UsbKeyboardDevice
);
426 &gEfiUsbIoProtocolGuid
,
427 This
->DriverBindingHandle
,
433 UsbKeyboardDevice
->ControllerNameTable
= NULL
;
436 gUsbKeyboardComponentName
.SupportedLanguages
,
437 &UsbKeyboardDevice
->ControllerNameTable
,
438 (CHAR16
*) L
"Generic Usb Keyboard"
447 USBKeyboardDriverBindingStop (
448 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
449 IN EFI_HANDLE Controller
,
450 IN UINTN NumberOfChildren
,
451 IN EFI_HANDLE
*ChildHandleBuffer
459 This - EFI_DRIVER_BINDING_PROTOCOL
460 Controller - Controller handle
461 NumberOfChildren - Child handle number
462 ChildHandleBuffer - Child handle buffer
464 EFI_SUCCESS - Success
465 EFI_UNSUPPORTED - Can't support
469 EFI_SIMPLE_TEXT_IN_PROTOCOL
*SimpleInput
;
470 USB_KB_DEV
*UsbKeyboardDevice
;
471 EFI_USB_IO_PROTOCOL
*UsbIo
;
473 Status
= gBS
->OpenProtocol (
475 &gEfiSimpleTextInProtocolGuid
,
476 (VOID
**) &SimpleInput
,
477 This
->DriverBindingHandle
,
479 EFI_OPEN_PROTOCOL_BY_DRIVER
481 if (EFI_ERROR (Status
)) {
482 return EFI_UNSUPPORTED
;
486 // Get USB_KB_DEV instance.
488 UsbKeyboardDevice
= USB_KB_DEV_FROM_THIS (SimpleInput
);
492 &gEfiSimpleTextInProtocolGuid
,
493 This
->DriverBindingHandle
,
497 UsbIo
= UsbKeyboardDevice
->UsbIo
;
499 // Uninstall the Asyn Interrupt Transfer from this device
500 // will disable the key data input from this device
502 KbdReportStatusCode (
503 UsbKeyboardDevice
->DevicePath
,
505 (EFI_PERIPHERAL_KEYBOARD
| EFI_P_PC_DISABLE
)
509 // Destroy asynchronous interrupt transfer
511 UsbKeyboardDevice
->UsbIo
->UsbAsyncInterruptTransfer (
512 UsbKeyboardDevice
->UsbIo
,
513 UsbKeyboardDevice
->IntEndpointDescriptor
.EndpointAddress
,
515 UsbKeyboardDevice
->IntEndpointDescriptor
.Interval
,
523 &gEfiUsbIoProtocolGuid
,
524 This
->DriverBindingHandle
,
528 Status
= gBS
->UninstallMultipleProtocolInterfaces (
530 &gEfiSimpleTextInProtocolGuid
,
531 &UsbKeyboardDevice
->SimpleInput
,
532 &gEfiHotPlugDeviceGuid
,
537 // free all the resources.
539 gBS
->CloseEvent (UsbKeyboardDevice
->RepeatTimer
);
540 gBS
->CloseEvent (UsbKeyboardDevice
->DelayedRecoveryEvent
);
541 gBS
->CloseEvent ((UsbKeyboardDevice
->SimpleInput
).WaitForKey
);
543 if (UsbKeyboardDevice
->ControllerNameTable
!= NULL
) {
544 FreeUnicodeStringTable (UsbKeyboardDevice
->ControllerNameTable
);
547 gBS
->FreePool (UsbKeyboardDevice
);
557 IN EFI_SIMPLE_TEXT_IN_PROTOCOL
*This
,
558 IN BOOLEAN ExtendedVerification
563 Implements EFI_SIMPLE_TEXT_IN_PROTOCOL.Reset() function.
566 This The EFI_SIMPLE_TEXT_IN_PROTOCOL instance.
568 Indicates that the driver may perform a more exhaustive
569 verification operation of the device during reset.
572 EFI_SUCCESS - Success
573 EFI_DEVICE_ERROR - Hardware Error
577 USB_KB_DEV
*UsbKeyboardDevice
;
578 EFI_USB_IO_PROTOCOL
*UsbIo
;
580 UsbKeyboardDevice
= USB_KB_DEV_FROM_THIS (This
);
582 UsbIo
= UsbKeyboardDevice
->UsbIo
;
584 KbdReportStatusCode (
585 UsbKeyboardDevice
->DevicePath
,
587 (EFI_PERIPHERAL_KEYBOARD
| EFI_P_PC_RESET
)
591 // Non Exhaustive reset:
592 // only reset private data structures.
594 if (!ExtendedVerification
) {
596 // Clear the key buffer of this Usb keyboard
598 KbdReportStatusCode (
599 UsbKeyboardDevice
->DevicePath
,
601 (EFI_PERIPHERAL_KEYBOARD
| EFI_P_KEYBOARD_PC_CLEAR_BUFFER
)
604 InitUSBKeyBuffer (&(UsbKeyboardDevice
->KeyboardBuffer
));
605 UsbKeyboardDevice
->CurKeyChar
= 0;
612 Status
= InitUSBKeyboard (UsbKeyboardDevice
);
613 UsbKeyboardDevice
->CurKeyChar
= 0;
614 if (EFI_ERROR (Status
)) {
615 return EFI_DEVICE_ERROR
;
624 USBKeyboardReadKeyStroke (
625 IN EFI_SIMPLE_TEXT_IN_PROTOCOL
*This
,
626 OUT EFI_INPUT_KEY
*Key
631 Implements EFI_SIMPLE_TEXT_IN_PROTOCOL.ReadKeyStroke() function.
634 This The EFI_SIMPLE_TEXT_IN_PROTOCOL instance.
635 Key A pointer to a buffer that is filled in with the keystroke
636 information for the key that was pressed.
639 EFI_SUCCESS - Success
642 USB_KB_DEV
*UsbKeyboardDevice
;
646 UsbKeyboardDevice
= USB_KB_DEV_FROM_THIS (This
);
649 // if there is no saved ASCII byte, fetch it
650 // by calling USBKeyboardCheckForKey().
652 if (UsbKeyboardDevice
->CurKeyChar
== 0) {
653 Status
= USBKeyboardCheckForKey (UsbKeyboardDevice
);
654 if (EFI_ERROR (Status
)) {
659 Key
->UnicodeChar
= 0;
660 Key
->ScanCode
= SCAN_NULL
;
662 KeyChar
= UsbKeyboardDevice
->CurKeyChar
;
664 UsbKeyboardDevice
->CurKeyChar
= 0;
667 // Translate saved ASCII byte into EFI_INPUT_KEY
669 Status
= USBKeyCodeToEFIScanCode (UsbKeyboardDevice
, KeyChar
, Key
);
678 USBKeyboardWaitForKey (
685 Handler function for WaitForKey event.
688 Event Event to be signaled when a key is pressed.
689 Context Points to USB_KB_DEV instance.
695 USB_KB_DEV
*UsbKeyboardDevice
;
697 UsbKeyboardDevice
= (USB_KB_DEV
*) Context
;
699 if (UsbKeyboardDevice
->CurKeyChar
== 0) {
701 if (EFI_ERROR (USBKeyboardCheckForKey (UsbKeyboardDevice
))) {
706 // If has key pending, signal the event.
708 gBS
->SignalEvent (Event
);
714 USBKeyboardCheckForKey (
715 IN USB_KB_DEV
*UsbKeyboardDevice
720 Check whether there is key pending.
723 UsbKeyboardDevice The USB_KB_DEV instance.
726 EFI_SUCCESS - Success
733 // Fetch raw data from the USB keyboard input,
734 // and translate it into ASCII data.
736 Status
= USBParseKey (UsbKeyboardDevice
, &KeyChar
);
737 if (EFI_ERROR (Status
)) {
741 UsbKeyboardDevice
->CurKeyChar
= KeyChar
;
746 KbdReportStatusCode (
747 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
,
748 IN EFI_STATUS_CODE_TYPE CodeType
,
749 IN EFI_STATUS_CODE_VALUE Value
754 Report Status Code in Usb Bot Driver
757 DevicePath - Use this to get Device Path
758 CodeType - Status Code Type
759 CodeValue - Status Code Value
767 REPORT_STATUS_CODE_WITH_DEVICE_PATH (