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
));
306 // No interrupt endpoint found, then return unsupported.
308 gBS
->FreePool (UsbKeyboardDevice
);
311 &gEfiUsbIoProtocolGuid
,
312 This
->DriverBindingHandle
,
315 return EFI_UNSUPPORTED
;
318 UsbKeyboardDevice
->Signature
= USB_KB_DEV_SIGNATURE
;
319 UsbKeyboardDevice
->SimpleInput
.Reset
= USBKeyboardReset
;
320 UsbKeyboardDevice
->SimpleInput
.ReadKeyStroke
= USBKeyboardReadKeyStroke
;
321 Status
= gBS
->CreateEvent (
322 EFI_EVENT_NOTIFY_WAIT
,
324 USBKeyboardWaitForKey
,
326 &(UsbKeyboardDevice
->SimpleInput
.WaitForKey
)
329 if (EFI_ERROR (Status
)) {
330 gBS
->FreePool (UsbKeyboardDevice
);
333 &gEfiUsbIoProtocolGuid
,
334 This
->DriverBindingHandle
,
341 // Install simple txt in protocol interface
342 // for the usb keyboard device.
343 // Usb keyboard is a hot plug device, and expected to work immediately
344 // when plugging into system, so a HotPlugDeviceGuid is installed onto
345 // the usb keyboard device handle, to distinguish it from other conventional
348 Status
= gBS
->InstallMultipleProtocolInterfaces (
350 &gEfiSimpleTextInProtocolGuid
,
351 &UsbKeyboardDevice
->SimpleInput
,
352 &gEfiHotPlugDeviceGuid
,
356 if (EFI_ERROR (Status
)) {
357 gBS
->CloseEvent (UsbKeyboardDevice
->SimpleInput
.WaitForKey
);
358 gBS
->FreePool (UsbKeyboardDevice
);
361 &gEfiUsbIoProtocolGuid
,
362 This
->DriverBindingHandle
,
369 // Reset USB Keyboard Device
371 Status
= UsbKeyboardDevice
->SimpleInput
.Reset (
372 &UsbKeyboardDevice
->SimpleInput
,
375 if (EFI_ERROR (Status
)) {
376 gBS
->UninstallMultipleProtocolInterfaces (
378 &gEfiSimpleTextInProtocolGuid
,
379 &UsbKeyboardDevice
->SimpleInput
,
380 &gEfiHotPlugDeviceGuid
,
384 gBS
->CloseEvent (UsbKeyboardDevice
->SimpleInput
.WaitForKey
);
385 gBS
->FreePool (UsbKeyboardDevice
);
388 &gEfiUsbIoProtocolGuid
,
389 This
->DriverBindingHandle
,
395 // submit async interrupt transfer
397 EndpointAddr
= UsbKeyboardDevice
->IntEndpointDescriptor
.EndpointAddress
;
398 PollingInterval
= UsbKeyboardDevice
->IntEndpointDescriptor
.Interval
;
399 PacketSize
= (UINT8
) (UsbKeyboardDevice
->IntEndpointDescriptor
.MaxPacketSize
);
401 Status
= UsbIo
->UsbAsyncInterruptTransfer (
411 if (EFI_ERROR (Status
)) {
413 gBS
->UninstallMultipleProtocolInterfaces (
415 &gEfiSimpleTextInProtocolGuid
,
416 &UsbKeyboardDevice
->SimpleInput
,
417 &gEfiHotPlugDeviceGuid
,
421 gBS
->CloseEvent (UsbKeyboardDevice
->SimpleInput
.WaitForKey
);
422 gBS
->FreePool (UsbKeyboardDevice
);
425 &gEfiUsbIoProtocolGuid
,
426 This
->DriverBindingHandle
,
432 UsbKeyboardDevice
->ControllerNameTable
= NULL
;
435 gUsbKeyboardComponentName
.SupportedLanguages
,
436 &UsbKeyboardDevice
->ControllerNameTable
,
437 (CHAR16
*) L
"Generic Usb Keyboard"
446 USBKeyboardDriverBindingStop (
447 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
448 IN EFI_HANDLE Controller
,
449 IN UINTN NumberOfChildren
,
450 IN EFI_HANDLE
*ChildHandleBuffer
458 This - EFI_DRIVER_BINDING_PROTOCOL
459 Controller - Controller handle
460 NumberOfChildren - Child handle number
461 ChildHandleBuffer - Child handle buffer
463 EFI_SUCCESS - Success
464 EFI_UNSUPPORTED - Can't support
468 EFI_SIMPLE_TEXT_IN_PROTOCOL
*SimpleInput
;
469 USB_KB_DEV
*UsbKeyboardDevice
;
471 Status
= gBS
->OpenProtocol (
473 &gEfiSimpleTextInProtocolGuid
,
474 (VOID
**) &SimpleInput
,
475 This
->DriverBindingHandle
,
477 EFI_OPEN_PROTOCOL_BY_DRIVER
479 if (EFI_ERROR (Status
)) {
480 return EFI_UNSUPPORTED
;
484 // Get USB_KB_DEV instance.
486 UsbKeyboardDevice
= USB_KB_DEV_FROM_THIS (SimpleInput
);
490 &gEfiSimpleTextInProtocolGuid
,
491 This
->DriverBindingHandle
,
496 // Uninstall the Asyn Interrupt Transfer from this device
497 // will disable the key data input from this device
499 KbdReportStatusCode (
500 UsbKeyboardDevice
->DevicePath
,
502 (EFI_PERIPHERAL_KEYBOARD
| EFI_P_PC_DISABLE
)
506 // Destroy asynchronous interrupt transfer
508 UsbKeyboardDevice
->UsbIo
->UsbAsyncInterruptTransfer (
509 UsbKeyboardDevice
->UsbIo
,
510 UsbKeyboardDevice
->IntEndpointDescriptor
.EndpointAddress
,
512 UsbKeyboardDevice
->IntEndpointDescriptor
.Interval
,
520 &gEfiUsbIoProtocolGuid
,
521 This
->DriverBindingHandle
,
525 Status
= gBS
->UninstallMultipleProtocolInterfaces (
527 &gEfiSimpleTextInProtocolGuid
,
528 &UsbKeyboardDevice
->SimpleInput
,
529 &gEfiHotPlugDeviceGuid
,
534 // free all the resources.
536 gBS
->CloseEvent (UsbKeyboardDevice
->RepeatTimer
);
537 gBS
->CloseEvent (UsbKeyboardDevice
->DelayedRecoveryEvent
);
538 gBS
->CloseEvent ((UsbKeyboardDevice
->SimpleInput
).WaitForKey
);
540 if (UsbKeyboardDevice
->ControllerNameTable
!= NULL
) {
541 FreeUnicodeStringTable (UsbKeyboardDevice
->ControllerNameTable
);
544 gBS
->FreePool (UsbKeyboardDevice
);
554 IN EFI_SIMPLE_TEXT_IN_PROTOCOL
*This
,
555 IN BOOLEAN ExtendedVerification
560 Implements EFI_SIMPLE_TEXT_IN_PROTOCOL.Reset() function.
563 This The EFI_SIMPLE_TEXT_IN_PROTOCOL instance.
565 Indicates that the driver may perform a more exhaustive
566 verification operation of the device during reset.
569 EFI_SUCCESS - Success
570 EFI_DEVICE_ERROR - Hardware Error
574 USB_KB_DEV
*UsbKeyboardDevice
;
576 UsbKeyboardDevice
= USB_KB_DEV_FROM_THIS (This
);
578 KbdReportStatusCode (
579 UsbKeyboardDevice
->DevicePath
,
581 (EFI_PERIPHERAL_KEYBOARD
| EFI_P_PC_RESET
)
585 // Non Exhaustive reset:
586 // only reset private data structures.
588 if (!ExtendedVerification
) {
590 // Clear the key buffer of this Usb keyboard
592 KbdReportStatusCode (
593 UsbKeyboardDevice
->DevicePath
,
595 (EFI_PERIPHERAL_KEYBOARD
| EFI_P_KEYBOARD_PC_CLEAR_BUFFER
)
598 InitUSBKeyBuffer (&(UsbKeyboardDevice
->KeyboardBuffer
));
599 UsbKeyboardDevice
->CurKeyChar
= 0;
606 Status
= InitUSBKeyboard (UsbKeyboardDevice
);
607 UsbKeyboardDevice
->CurKeyChar
= 0;
608 if (EFI_ERROR (Status
)) {
609 return EFI_DEVICE_ERROR
;
618 USBKeyboardReadKeyStroke (
619 IN EFI_SIMPLE_TEXT_IN_PROTOCOL
*This
,
620 OUT EFI_INPUT_KEY
*Key
625 Implements EFI_SIMPLE_TEXT_IN_PROTOCOL.ReadKeyStroke() function.
628 This The EFI_SIMPLE_TEXT_IN_PROTOCOL instance.
629 Key A pointer to a buffer that is filled in with the keystroke
630 information for the key that was pressed.
633 EFI_SUCCESS - Success
636 USB_KB_DEV
*UsbKeyboardDevice
;
640 UsbKeyboardDevice
= USB_KB_DEV_FROM_THIS (This
);
643 // if there is no saved ASCII byte, fetch it
644 // by calling USBKeyboardCheckForKey().
646 if (UsbKeyboardDevice
->CurKeyChar
== 0) {
647 Status
= USBKeyboardCheckForKey (UsbKeyboardDevice
);
648 if (EFI_ERROR (Status
)) {
653 Key
->UnicodeChar
= 0;
654 Key
->ScanCode
= SCAN_NULL
;
656 KeyChar
= UsbKeyboardDevice
->CurKeyChar
;
658 UsbKeyboardDevice
->CurKeyChar
= 0;
661 // Translate saved ASCII byte into EFI_INPUT_KEY
663 Status
= USBKeyCodeToEFIScanCode (UsbKeyboardDevice
, KeyChar
, Key
);
672 USBKeyboardWaitForKey (
679 Handler function for WaitForKey event.
682 Event Event to be signaled when a key is pressed.
683 Context Points to USB_KB_DEV instance.
689 USB_KB_DEV
*UsbKeyboardDevice
;
691 UsbKeyboardDevice
= (USB_KB_DEV
*) Context
;
693 if (UsbKeyboardDevice
->CurKeyChar
== 0) {
695 if (EFI_ERROR (USBKeyboardCheckForKey (UsbKeyboardDevice
))) {
700 // If has key pending, signal the event.
702 gBS
->SignalEvent (Event
);
708 USBKeyboardCheckForKey (
709 IN USB_KB_DEV
*UsbKeyboardDevice
714 Check whether there is key pending.
717 UsbKeyboardDevice The USB_KB_DEV instance.
720 EFI_SUCCESS - Success
727 // Fetch raw data from the USB keyboard input,
728 // and translate it into ASCII data.
730 Status
= USBParseKey (UsbKeyboardDevice
, &KeyChar
);
731 if (EFI_ERROR (Status
)) {
735 UsbKeyboardDevice
->CurKeyChar
= KeyChar
;
740 KbdReportStatusCode (
741 IN EFI_DEVICE_PATH_PROTOCOL
*DevicePath
,
742 IN EFI_STATUS_CODE_TYPE CodeType
,
743 IN EFI_STATUS_CODE_VALUE Value
748 Report Status Code in Usb Bot Driver
751 DevicePath - Use this to get Device Path
752 CodeType - Status Code Type
753 CodeValue - Status Code Value
761 REPORT_STATUS_CODE_WITH_DEVICE_PATH (