3 PS/2 Keyboard driver. Routines that interacts with callers,
4 conforming to EFI driver model
6 Copyright (c) 2006 - 2007, Intel Corporation
7 All rights reserved. This program and the accompanying materials
8 are licensed and made available under the terms and conditions of the BSD License
9 which accompanies this distribution. The full text of the license may be found at
10 http://opensource.org/licenses/bsd-license.php
12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
17 #include "Ps2Keyboard.h"
20 // Function prototypes
24 KbdControllerDriverSupported (
25 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
26 IN EFI_HANDLE Controller
,
27 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
32 KbdControllerDriverStart (
33 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
34 IN EFI_HANDLE Controller
,
35 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
40 KbdControllerDriverStop (
41 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
42 IN EFI_HANDLE Controller
,
43 IN UINTN NumberOfChildren
,
44 IN EFI_HANDLE
*ChildHandleBuffer
51 // DriverBinding Protocol Instance
53 EFI_DRIVER_BINDING_PROTOCOL gKeyboardControllerDriver
= {
54 KbdControllerDriverSupported
,
55 KbdControllerDriverStart
,
56 KbdControllerDriverStop
,
64 KbdControllerDriverSupported (
65 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
66 IN EFI_HANDLE Controller
,
67 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
73 ControllerDriver Protocol Method
80 // GC_TODO: This - add argument and description to function comment
81 // GC_TODO: Controller - add argument and description to function comment
82 // GC_TODO: RemainingDevicePath - add argument and description to function comment
85 EFI_ISA_IO_PROTOCOL
*IsaIo
;
88 // Open the IO Abstraction(s) needed to perform the supported test
90 Status
= gBS
->OpenProtocol (
92 &gEfiIsaIoProtocolGuid
,
94 This
->DriverBindingHandle
,
96 EFI_OPEN_PROTOCOL_BY_DRIVER
98 if (EFI_ERROR (Status
)) {
102 // Use the ISA I/O Protocol to see if Controller is the Keyboard controller
104 if (IsaIo
->ResourceList
->Device
.HID
!= EISA_PNP_ID (0x303) || IsaIo
->ResourceList
->Device
.UID
!= 0) {
105 Status
= EFI_UNSUPPORTED
;
108 // Close the I/O Abstraction(s) used to perform the supported test
112 &gEfiIsaIoProtocolGuid
,
113 This
->DriverBindingHandle
,
122 KbdControllerDriverStart (
123 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
124 IN EFI_HANDLE Controller
,
125 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
136 // GC_TODO: This - add argument and description to function comment
137 // GC_TODO: Controller - add argument and description to function comment
138 // GC_TODO: RemainingDevicePath - add argument and description to function comment
139 // GC_TODO: EFI_INVALID_PARAMETER - add return value to function comment
143 EFI_ISA_IO_PROTOCOL
*IsaIo
;
144 KEYBOARD_CONSOLE_IN_DEV
*ConsoleIn
;
146 EFI_STATUS_CODE_VALUE StatusCode
;
147 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
151 Status
= gBS
->OpenProtocol (
153 &gEfiDevicePathProtocolGuid
,
154 (VOID
**) &ParentDevicePath
,
155 This
->DriverBindingHandle
,
157 EFI_OPEN_PROTOCOL_BY_DRIVER
159 if (EFI_ERROR (Status
)) {
163 // Report that the keyboard is being enabled
165 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
167 EFI_PERIPHERAL_KEYBOARD
| EFI_P_PC_ENABLE
,
172 // Get the ISA I/O Protocol on Controller's handle
174 Status
= gBS
->OpenProtocol (
176 &gEfiIsaIoProtocolGuid
,
178 This
->DriverBindingHandle
,
180 EFI_OPEN_PROTOCOL_BY_DRIVER
182 if (EFI_ERROR (Status
)) {
185 &gEfiDevicePathProtocolGuid
,
186 This
->DriverBindingHandle
,
189 return EFI_INVALID_PARAMETER
;
192 // Allocate private data
194 ConsoleIn
= AllocateZeroPool (sizeof (KEYBOARD_CONSOLE_IN_DEV
));
195 if (ConsoleIn
== NULL
) {
196 Status
= EFI_OUT_OF_RESOURCES
;
197 StatusCode
= EFI_PERIPHERAL_KEYBOARD
| EFI_P_EC_CONTROLLER_ERROR
;
201 // Setup the device instance
203 ConsoleIn
->Signature
= KEYBOARD_CONSOLE_IN_DEV_SIGNATURE
;
204 ConsoleIn
->Handle
= Controller
;
205 (ConsoleIn
->ConIn
).Reset
= KeyboardEfiReset
;
206 (ConsoleIn
->ConIn
).ReadKeyStroke
= KeyboardReadKeyStroke
;
207 ConsoleIn
->DataRegisterAddress
= KEYBOARD_8042_DATA_REGISTER
;
208 ConsoleIn
->StatusRegisterAddress
= KEYBOARD_8042_STATUS_REGISTER
;
209 ConsoleIn
->CommandRegisterAddress
= KEYBOARD_8042_COMMAND_REGISTER
;
210 ConsoleIn
->IsaIo
= IsaIo
;
211 ConsoleIn
->ScancodeBufStartPos
= 0;
212 ConsoleIn
->ScancodeBufEndPos
= KEYBOARD_BUFFER_MAX_COUNT
- 1;
213 ConsoleIn
->ScancodeBufCount
= 0;
214 ConsoleIn
->Ctrled
= FALSE
;
215 ConsoleIn
->Alted
= FALSE
;
216 ConsoleIn
->DevicePath
= ParentDevicePath
;
219 // Setup the WaitForKey event
221 Status
= gBS
->CreateEvent (
226 &((ConsoleIn
->ConIn
).WaitForKey
)
228 if (EFI_ERROR (Status
)) {
229 Status
= EFI_OUT_OF_RESOURCES
;
230 StatusCode
= EFI_PERIPHERAL_KEYBOARD
| EFI_P_EC_CONTROLLER_ERROR
;
234 // Setup a periodic timer, used for reading keystrokes at a fixed interval
236 Status
= gBS
->CreateEvent (
237 EVT_TIMER
| EVT_NOTIFY_SIGNAL
,
239 KeyboardTimerHandler
,
241 &ConsoleIn
->TimerEvent
243 if (EFI_ERROR (Status
)) {
244 Status
= EFI_OUT_OF_RESOURCES
;
245 StatusCode
= EFI_PERIPHERAL_KEYBOARD
| EFI_P_EC_CONTROLLER_ERROR
;
249 Status
= gBS
->SetTimer (
250 ConsoleIn
->TimerEvent
,
252 KEYBOARD_TIMER_INTERVAL
254 if (EFI_ERROR (Status
)) {
255 Status
= EFI_OUT_OF_RESOURCES
;
256 StatusCode
= EFI_PERIPHERAL_KEYBOARD
| EFI_P_EC_CONTROLLER_ERROR
;
260 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
262 EFI_PERIPHERAL_KEYBOARD
| EFI_P_PC_PRESENCE_DETECT
,
267 // Reset the keyboard device
269 Status
= ConsoleIn
->ConIn
.Reset (&ConsoleIn
->ConIn
, TRUE
);
270 if (EFI_ERROR (Status
)) {
271 Status
= EFI_DEVICE_ERROR
;
272 StatusCode
= EFI_PERIPHERAL_KEYBOARD
| EFI_P_EC_NOT_DETECTED
;
276 ConsoleIn
->ControllerNameTable
= NULL
;
279 gPs2KeyboardComponentName
.SupportedLanguages
,
280 &ConsoleIn
->ControllerNameTable
,
281 L
"PS/2 Keyboard Device",
286 gPs2KeyboardComponentName2
.SupportedLanguages
,
287 &ConsoleIn
->ControllerNameTable
,
288 L
"PS/2 Keyboard Device",
294 // Install protocol interfaces for the keyboard device.
296 Status
= gBS
->InstallMultipleProtocolInterfaces (
298 &gEfiSimpleTextInProtocolGuid
,
302 if (EFI_ERROR (Status
)) {
303 StatusCode
= EFI_PERIPHERAL_KEYBOARD
| EFI_P_EC_CONTROLLER_ERROR
;
313 if (StatusCode
!= 0) {
314 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
315 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
321 if ((ConsoleIn
!= NULL
) && (ConsoleIn
->ConIn
.WaitForKey
!= NULL
)) {
322 gBS
->CloseEvent (ConsoleIn
->ConIn
.WaitForKey
);
325 if ((ConsoleIn
!= NULL
) && (ConsoleIn
->TimerEvent
!= NULL
)) {
326 gBS
->CloseEvent (ConsoleIn
->TimerEvent
);
329 if ((ConsoleIn
!= NULL
) && (ConsoleIn
->ControllerNameTable
!= NULL
)) {
330 FreeUnicodeStringTable (ConsoleIn
->ControllerNameTable
);
333 // Since there will be no timer handler for keyboard input any more,
334 // exhaust input data just in case there is still keyboard data left
336 Status1
= EFI_SUCCESS
;
337 while (!EFI_ERROR (Status1
)) {
338 Status1
= KeyboardRead (ConsoleIn
, &Data
);;
341 if (ConsoleIn
!= NULL
) {
342 gBS
->FreePool (ConsoleIn
);
347 &gEfiDevicePathProtocolGuid
,
348 This
->DriverBindingHandle
,
354 &gEfiIsaIoProtocolGuid
,
355 This
->DriverBindingHandle
,
364 KbdControllerDriverStop (
365 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
366 IN EFI_HANDLE Controller
,
367 IN UINTN NumberOfChildren
,
368 IN EFI_HANDLE
*ChildHandleBuffer
379 // GC_TODO: This - add argument and description to function comment
380 // GC_TODO: Controller - add argument and description to function comment
381 // GC_TODO: NumberOfChildren - add argument and description to function comment
382 // GC_TODO: ChildHandleBuffer - add argument and description to function comment
383 // GC_TODO: EFI_SUCCESS - add return value to function comment
386 EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*ConIn
;
387 KEYBOARD_CONSOLE_IN_DEV
*ConsoleIn
;
393 Status
= gBS
->OpenProtocol (
395 &gEfiSimpleTextInProtocolGuid
,
397 This
->DriverBindingHandle
,
399 EFI_OPEN_PROTOCOL_GET_PROTOCOL
401 if (EFI_ERROR (Status
)) {
405 ConsoleIn
= KEYBOARD_CONSOLE_IN_DEV_FROM_THIS (ConIn
);
408 // Report that the keyboard is being disabled
410 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
412 EFI_PERIPHERAL_KEYBOARD
| EFI_P_PC_DISABLE
,
413 ConsoleIn
->DevicePath
416 if (ConsoleIn
->TimerEvent
) {
417 gBS
->CloseEvent (ConsoleIn
->TimerEvent
);
418 ConsoleIn
->TimerEvent
= NULL
;
421 // Disable the keyboard interface
423 Status
= DisableKeyboard (ConsoleIn
);
426 // Since there will be no timer handler for keyboard input any more,
427 // exhaust input data just in case there is still keyboard data left
429 Status
= EFI_SUCCESS
;
430 while (!EFI_ERROR (Status
)) {
431 Status
= KeyboardRead (ConsoleIn
, &Data
);;
434 // Uninstall the Simple TextIn Protocol
436 Status
= gBS
->UninstallProtocolInterface (
438 &gEfiSimpleTextInProtocolGuid
,
441 if (EFI_ERROR (Status
)) {
447 &gEfiDevicePathProtocolGuid
,
448 This
->DriverBindingHandle
,
454 &gEfiIsaIoProtocolGuid
,
455 This
->DriverBindingHandle
,
460 // Free other resources
462 if ((ConsoleIn
->ConIn
).WaitForKey
) {
463 gBS
->CloseEvent ((ConsoleIn
->ConIn
).WaitForKey
);
464 (ConsoleIn
->ConIn
).WaitForKey
= NULL
;
467 FreeUnicodeStringTable (ConsoleIn
->ControllerNameTable
);
468 gBS
->FreePool (ConsoleIn
);
475 The user Entry Point for module Ps2Keyboard. The user code starts with this function.
477 @param[in] ImageHandle The firmware allocated handle for the EFI image.
478 @param[in] SystemTable A pointer to the EFI System Table.
480 @retval EFI_SUCCESS The entry point is executed successfully.
481 @retval other Some error occurs when executing this entry point.
486 InitializePs2Keyboard(
487 IN EFI_HANDLE ImageHandle
,
488 IN EFI_SYSTEM_TABLE
*SystemTable
494 // Install driver model protocol(s).
496 Status
= EfiLibInstallDriverBindingComponentName2 (
499 &gKeyboardControllerDriver
,
501 &gPs2KeyboardComponentName
,
502 &gPs2KeyboardComponentName2
504 ASSERT_EFI_ERROR (Status
);