3 Copyright (c) 2006 - 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.
18 PS/2 Keyboard driver. Routines that interacts with callers,
19 conforming to EFI driver model
23 #include "Ps2Keyboard.h"
26 // Function prototypes
30 KbdControllerDriverSupported (
31 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
32 IN EFI_HANDLE Controller
,
33 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
38 KbdControllerDriverStart (
39 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
40 IN EFI_HANDLE Controller
,
41 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
46 KbdControllerDriverStop (
47 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
48 IN EFI_HANDLE Controller
,
49 IN UINTN NumberOfChildren
,
50 IN EFI_HANDLE
*ChildHandleBuffer
57 // DriverBinding Protocol Instance
59 EFI_DRIVER_BINDING_PROTOCOL gKeyboardControllerDriver
= {
60 KbdControllerDriverSupported
,
61 KbdControllerDriverStart
,
62 KbdControllerDriverStop
,
70 KbdControllerDriverSupported (
71 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
72 IN EFI_HANDLE Controller
,
73 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
79 ControllerDriver Protocol Method
86 // GC_TODO: This - add argument and description to function comment
87 // GC_TODO: Controller - add argument and description to function comment
88 // GC_TODO: RemainingDevicePath - add argument and description to function comment
91 EFI_ISA_IO_PROTOCOL
*IsaIo
;
94 // Open the IO Abstraction(s) needed to perform the supported test
96 Status
= gBS
->OpenProtocol (
98 &gEfiIsaIoProtocolGuid
,
100 This
->DriverBindingHandle
,
102 EFI_OPEN_PROTOCOL_BY_DRIVER
104 if (EFI_ERROR (Status
)) {
108 // Use the ISA I/O Protocol to see if Controller is the Keyboard controller
110 if (IsaIo
->ResourceList
->Device
.HID
!= EISA_PNP_ID (0x303) || IsaIo
->ResourceList
->Device
.UID
!= 0) {
111 Status
= EFI_UNSUPPORTED
;
114 // Close the I/O Abstraction(s) used to perform the supported test
118 &gEfiIsaIoProtocolGuid
,
119 This
->DriverBindingHandle
,
128 KbdControllerDriverStart (
129 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
130 IN EFI_HANDLE Controller
,
131 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
142 // GC_TODO: This - add argument and description to function comment
143 // GC_TODO: Controller - add argument and description to function comment
144 // GC_TODO: RemainingDevicePath - add argument and description to function comment
145 // GC_TODO: EFI_INVALID_PARAMETER - add return value to function comment
149 EFI_ISA_IO_PROTOCOL
*IsaIo
;
150 KEYBOARD_CONSOLE_IN_DEV
*ConsoleIn
;
152 EFI_STATUS_CODE_VALUE StatusCode
;
153 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
157 Status
= gBS
->OpenProtocol (
159 &gEfiDevicePathProtocolGuid
,
160 (VOID
**) &ParentDevicePath
,
161 This
->DriverBindingHandle
,
163 EFI_OPEN_PROTOCOL_BY_DRIVER
165 if (EFI_ERROR (Status
)) {
169 // Report that the keyboard is being enabled
171 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
173 EFI_PERIPHERAL_KEYBOARD
| EFI_P_PC_ENABLE
,
178 // Get the ISA I/O Protocol on Controller's handle
180 Status
= gBS
->OpenProtocol (
182 &gEfiIsaIoProtocolGuid
,
184 This
->DriverBindingHandle
,
186 EFI_OPEN_PROTOCOL_BY_DRIVER
188 if (EFI_ERROR (Status
)) {
191 &gEfiDevicePathProtocolGuid
,
192 This
->DriverBindingHandle
,
195 return EFI_INVALID_PARAMETER
;
198 // Allocate private data
200 ConsoleIn
= AllocateZeroPool (sizeof (KEYBOARD_CONSOLE_IN_DEV
));
201 if (ConsoleIn
== NULL
) {
202 Status
= EFI_OUT_OF_RESOURCES
;
203 StatusCode
= EFI_PERIPHERAL_KEYBOARD
| EFI_P_EC_CONTROLLER_ERROR
;
207 // Setup the device instance
209 ConsoleIn
->Signature
= KEYBOARD_CONSOLE_IN_DEV_SIGNATURE
;
210 ConsoleIn
->Handle
= Controller
;
211 (ConsoleIn
->ConIn
).Reset
= KeyboardEfiReset
;
212 (ConsoleIn
->ConIn
).ReadKeyStroke
= KeyboardReadKeyStroke
;
213 ConsoleIn
->DataRegisterAddress
= KEYBOARD_8042_DATA_REGISTER
;
214 ConsoleIn
->StatusRegisterAddress
= KEYBOARD_8042_STATUS_REGISTER
;
215 ConsoleIn
->CommandRegisterAddress
= KEYBOARD_8042_COMMAND_REGISTER
;
216 ConsoleIn
->IsaIo
= IsaIo
;
217 ConsoleIn
->ScancodeBufStartPos
= 0;
218 ConsoleIn
->ScancodeBufEndPos
= KEYBOARD_BUFFER_MAX_COUNT
- 1;
219 ConsoleIn
->ScancodeBufCount
= 0;
220 ConsoleIn
->Ctrled
= FALSE
;
221 ConsoleIn
->Alted
= FALSE
;
222 ConsoleIn
->DevicePath
= ParentDevicePath
;
225 // Setup the WaitForKey event
227 Status
= gBS
->CreateEvent (
232 &((ConsoleIn
->ConIn
).WaitForKey
)
234 if (EFI_ERROR (Status
)) {
235 Status
= EFI_OUT_OF_RESOURCES
;
236 StatusCode
= EFI_PERIPHERAL_KEYBOARD
| EFI_P_EC_CONTROLLER_ERROR
;
240 // Setup a periodic timer, used for reading keystrokes at a fixed interval
242 Status
= gBS
->CreateEvent (
243 EVT_TIMER
| EVT_NOTIFY_SIGNAL
,
245 KeyboardTimerHandler
,
247 &ConsoleIn
->TimerEvent
249 if (EFI_ERROR (Status
)) {
250 Status
= EFI_OUT_OF_RESOURCES
;
251 StatusCode
= EFI_PERIPHERAL_KEYBOARD
| EFI_P_EC_CONTROLLER_ERROR
;
255 Status
= gBS
->SetTimer (
256 ConsoleIn
->TimerEvent
,
258 KEYBOARD_TIMER_INTERVAL
260 if (EFI_ERROR (Status
)) {
261 Status
= EFI_OUT_OF_RESOURCES
;
262 StatusCode
= EFI_PERIPHERAL_KEYBOARD
| EFI_P_EC_CONTROLLER_ERROR
;
266 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
268 EFI_PERIPHERAL_KEYBOARD
| EFI_P_PC_PRESENCE_DETECT
,
273 // Reset the keyboard device
275 Status
= ConsoleIn
->ConIn
.Reset (&ConsoleIn
->ConIn
, TRUE
);
276 if (EFI_ERROR (Status
)) {
277 Status
= EFI_DEVICE_ERROR
;
278 StatusCode
= EFI_PERIPHERAL_KEYBOARD
| EFI_P_EC_NOT_DETECTED
;
282 ConsoleIn
->ControllerNameTable
= NULL
;
285 gPs2KeyboardComponentName
.SupportedLanguages
,
286 &ConsoleIn
->ControllerNameTable
,
287 L
"PS/2 Keyboard Device"
291 // Install protocol interfaces for the keyboard device.
293 Status
= gBS
->InstallMultipleProtocolInterfaces (
295 &gEfiSimpleTextInProtocolGuid
,
299 if (EFI_ERROR (Status
)) {
300 StatusCode
= EFI_PERIPHERAL_KEYBOARD
| EFI_P_EC_CONTROLLER_ERROR
;
310 if (StatusCode
!= 0) {
311 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
312 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
318 if ((ConsoleIn
!= NULL
) && (ConsoleIn
->ConIn
.WaitForKey
!= NULL
)) {
319 gBS
->CloseEvent (ConsoleIn
->ConIn
.WaitForKey
);
322 if ((ConsoleIn
!= NULL
) && (ConsoleIn
->TimerEvent
!= NULL
)) {
323 gBS
->CloseEvent (ConsoleIn
->TimerEvent
);
326 if ((ConsoleIn
!= NULL
) && (ConsoleIn
->ControllerNameTable
!= NULL
)) {
327 FreeUnicodeStringTable (ConsoleIn
->ControllerNameTable
);
330 // Since there will be no timer handler for keyboard input any more,
331 // exhaust input data just in case there is still keyboard data left
333 Status1
= EFI_SUCCESS
;
334 while (!EFI_ERROR (Status1
)) {
335 Status1
= KeyboardRead (ConsoleIn
, &Data
);;
338 if (ConsoleIn
!= NULL
) {
339 gBS
->FreePool (ConsoleIn
);
344 &gEfiDevicePathProtocolGuid
,
345 This
->DriverBindingHandle
,
351 &gEfiIsaIoProtocolGuid
,
352 This
->DriverBindingHandle
,
361 KbdControllerDriverStop (
362 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
363 IN EFI_HANDLE Controller
,
364 IN UINTN NumberOfChildren
,
365 IN EFI_HANDLE
*ChildHandleBuffer
376 // GC_TODO: This - add argument and description to function comment
377 // GC_TODO: Controller - add argument and description to function comment
378 // GC_TODO: NumberOfChildren - add argument and description to function comment
379 // GC_TODO: ChildHandleBuffer - add argument and description to function comment
380 // GC_TODO: EFI_SUCCESS - add return value to function comment
383 EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*ConIn
;
384 KEYBOARD_CONSOLE_IN_DEV
*ConsoleIn
;
390 Status
= gBS
->OpenProtocol (
392 &gEfiSimpleTextInProtocolGuid
,
394 This
->DriverBindingHandle
,
396 EFI_OPEN_PROTOCOL_GET_PROTOCOL
398 if (EFI_ERROR (Status
)) {
402 ConsoleIn
= KEYBOARD_CONSOLE_IN_DEV_FROM_THIS (ConIn
);
405 // Report that the keyboard is being disabled
407 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
409 EFI_PERIPHERAL_KEYBOARD
| EFI_P_PC_DISABLE
,
410 ConsoleIn
->DevicePath
413 if (ConsoleIn
->TimerEvent
) {
414 gBS
->CloseEvent (ConsoleIn
->TimerEvent
);
415 ConsoleIn
->TimerEvent
= NULL
;
418 // Disable the keyboard interface
420 Status
= DisableKeyboard (ConsoleIn
);
423 // Since there will be no timer handler for keyboard input any more,
424 // exhaust input data just in case there is still keyboard data left
426 Status
= EFI_SUCCESS
;
427 while (!EFI_ERROR (Status
)) {
428 Status
= KeyboardRead (ConsoleIn
, &Data
);;
431 // Uninstall the Simple TextIn Protocol
433 Status
= gBS
->UninstallProtocolInterface (
435 &gEfiSimpleTextInProtocolGuid
,
438 if (EFI_ERROR (Status
)) {
444 &gEfiDevicePathProtocolGuid
,
445 This
->DriverBindingHandle
,
451 &gEfiIsaIoProtocolGuid
,
452 This
->DriverBindingHandle
,
457 // Free other resources
459 if ((ConsoleIn
->ConIn
).WaitForKey
) {
460 gBS
->CloseEvent ((ConsoleIn
->ConIn
).WaitForKey
);
461 (ConsoleIn
->ConIn
).WaitForKey
= NULL
;
464 FreeUnicodeStringTable (ConsoleIn
->ControllerNameTable
);
465 gBS
->FreePool (ConsoleIn
);
472 The user Entry Point for module Ps2Keyboard. The user code starts with this function.
474 @param[in] ImageHandle The firmware allocated handle for the EFI image.
475 @param[in] SystemTable A pointer to the EFI System Table.
477 @retval EFI_SUCCESS The entry point is executed successfully.
478 @retval other Some error occurs when executing this entry point.
483 InitializePs2Keyboard(
484 IN EFI_HANDLE ImageHandle
,
485 IN EFI_SYSTEM_TABLE
*SystemTable
491 // Install driver model protocol(s).
493 Status
= EfiLibInstallAllDriverProtocols (
496 &gKeyboardControllerDriver
,
498 &gPs2KeyboardComponentName
,
502 ASSERT_EFI_ERROR (Status
);