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
24 // Include common header file for this module.
26 #include "CommonHeader.h"
28 #include "Ps2Keyboard.h"
31 // Function prototypes
35 KbdControllerDriverSupported (
36 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
37 IN EFI_HANDLE Controller
,
38 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
43 KbdControllerDriverStart (
44 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
45 IN EFI_HANDLE Controller
,
46 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
51 KbdControllerDriverStop (
52 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
53 IN EFI_HANDLE Controller
,
54 IN UINTN NumberOfChildren
,
55 IN EFI_HANDLE
*ChildHandleBuffer
62 // DriverBinding Protocol Instance
64 EFI_DRIVER_BINDING_PROTOCOL gKeyboardControllerDriver
= {
65 KbdControllerDriverSupported
,
66 KbdControllerDriverStart
,
67 KbdControllerDriverStop
,
75 KbdControllerDriverSupported (
76 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
77 IN EFI_HANDLE Controller
,
78 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
84 ControllerDriver Protocol Method
91 // GC_TODO: This - add argument and description to function comment
92 // GC_TODO: Controller - add argument and description to function comment
93 // GC_TODO: RemainingDevicePath - add argument and description to function comment
96 EFI_ISA_IO_PROTOCOL
*IsaIo
;
99 // Open the IO Abstraction(s) needed to perform the supported test
101 Status
= gBS
->OpenProtocol (
103 &gEfiIsaIoProtocolGuid
,
105 This
->DriverBindingHandle
,
107 EFI_OPEN_PROTOCOL_BY_DRIVER
109 if (EFI_ERROR (Status
)) {
113 // Use the ISA I/O Protocol to see if Controller is the Keyboard controller
115 if (IsaIo
->ResourceList
->Device
.HID
!= EISA_PNP_ID (0x303) || IsaIo
->ResourceList
->Device
.UID
!= 0) {
116 Status
= EFI_UNSUPPORTED
;
119 // Close the I/O Abstraction(s) used to perform the supported test
123 &gEfiIsaIoProtocolGuid
,
124 This
->DriverBindingHandle
,
133 KbdControllerDriverStart (
134 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
135 IN EFI_HANDLE Controller
,
136 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
147 // GC_TODO: This - add argument and description to function comment
148 // GC_TODO: Controller - add argument and description to function comment
149 // GC_TODO: RemainingDevicePath - add argument and description to function comment
150 // GC_TODO: EFI_INVALID_PARAMETER - add return value to function comment
154 EFI_ISA_IO_PROTOCOL
*IsaIo
;
155 KEYBOARD_CONSOLE_IN_DEV
*ConsoleIn
;
157 EFI_STATUS_CODE_VALUE StatusCode
;
158 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
162 Status
= gBS
->OpenProtocol (
164 &gEfiDevicePathProtocolGuid
,
165 (VOID
**) &ParentDevicePath
,
166 This
->DriverBindingHandle
,
168 EFI_OPEN_PROTOCOL_BY_DRIVER
170 if (EFI_ERROR (Status
)) {
174 // Report that the keyboard is being enabled
176 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
178 EFI_PERIPHERAL_KEYBOARD
| EFI_P_PC_ENABLE
,
183 // Get the ISA I/O Protocol on Controller's handle
185 Status
= gBS
->OpenProtocol (
187 &gEfiIsaIoProtocolGuid
,
189 This
->DriverBindingHandle
,
191 EFI_OPEN_PROTOCOL_BY_DRIVER
193 if (EFI_ERROR (Status
)) {
196 &gEfiDevicePathProtocolGuid
,
197 This
->DriverBindingHandle
,
200 return EFI_INVALID_PARAMETER
;
203 // Allocate private data
205 ConsoleIn
= AllocateZeroPool (sizeof (KEYBOARD_CONSOLE_IN_DEV
));
206 if (ConsoleIn
== NULL
) {
207 Status
= EFI_OUT_OF_RESOURCES
;
208 StatusCode
= EFI_PERIPHERAL_KEYBOARD
| EFI_P_EC_CONTROLLER_ERROR
;
212 // Setup the device instance
214 ConsoleIn
->Signature
= KEYBOARD_CONSOLE_IN_DEV_SIGNATURE
;
215 ConsoleIn
->Handle
= Controller
;
216 (ConsoleIn
->ConIn
).Reset
= KeyboardEfiReset
;
217 (ConsoleIn
->ConIn
).ReadKeyStroke
= KeyboardReadKeyStroke
;
218 ConsoleIn
->DataRegisterAddress
= KEYBOARD_8042_DATA_REGISTER
;
219 ConsoleIn
->StatusRegisterAddress
= KEYBOARD_8042_STATUS_REGISTER
;
220 ConsoleIn
->CommandRegisterAddress
= KEYBOARD_8042_COMMAND_REGISTER
;
221 ConsoleIn
->IsaIo
= IsaIo
;
222 ConsoleIn
->ScancodeBufStartPos
= 0;
223 ConsoleIn
->ScancodeBufEndPos
= KEYBOARD_BUFFER_MAX_COUNT
- 1;
224 ConsoleIn
->ScancodeBufCount
= 0;
225 ConsoleIn
->Ctrled
= FALSE
;
226 ConsoleIn
->Alted
= FALSE
;
227 ConsoleIn
->DevicePath
= ParentDevicePath
;
230 // Setup the WaitForKey event
232 Status
= gBS
->CreateEvent (
237 &((ConsoleIn
->ConIn
).WaitForKey
)
239 if (EFI_ERROR (Status
)) {
240 Status
= EFI_OUT_OF_RESOURCES
;
241 StatusCode
= EFI_PERIPHERAL_KEYBOARD
| EFI_P_EC_CONTROLLER_ERROR
;
245 // Setup a periodic timer, used for reading keystrokes at a fixed interval
247 Status
= gBS
->CreateEvent (
248 EVT_TIMER
| EVT_NOTIFY_SIGNAL
,
250 KeyboardTimerHandler
,
252 &ConsoleIn
->TimerEvent
254 if (EFI_ERROR (Status
)) {
255 Status
= EFI_OUT_OF_RESOURCES
;
256 StatusCode
= EFI_PERIPHERAL_KEYBOARD
| EFI_P_EC_CONTROLLER_ERROR
;
260 Status
= gBS
->SetTimer (
261 ConsoleIn
->TimerEvent
,
263 KEYBOARD_TIMER_INTERVAL
265 if (EFI_ERROR (Status
)) {
266 Status
= EFI_OUT_OF_RESOURCES
;
267 StatusCode
= EFI_PERIPHERAL_KEYBOARD
| EFI_P_EC_CONTROLLER_ERROR
;
271 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
273 EFI_PERIPHERAL_KEYBOARD
| EFI_P_PC_PRESENCE_DETECT
,
278 // Reset the keyboard device
280 Status
= ConsoleIn
->ConIn
.Reset (&ConsoleIn
->ConIn
, TRUE
);
281 if (EFI_ERROR (Status
)) {
282 Status
= EFI_DEVICE_ERROR
;
283 StatusCode
= EFI_PERIPHERAL_KEYBOARD
| EFI_P_EC_NOT_DETECTED
;
287 ConsoleIn
->ControllerNameTable
= NULL
;
290 gPs2KeyboardComponentName
.SupportedLanguages
,
291 &ConsoleIn
->ControllerNameTable
,
292 L
"PS/2 Keyboard Device"
296 // Install protocol interfaces for the keyboard device.
298 Status
= gBS
->InstallMultipleProtocolInterfaces (
300 &gEfiSimpleTextInProtocolGuid
,
304 if (EFI_ERROR (Status
)) {
305 StatusCode
= EFI_PERIPHERAL_KEYBOARD
| EFI_P_EC_CONTROLLER_ERROR
;
315 if (StatusCode
!= 0) {
316 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
317 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
323 if ((ConsoleIn
!= NULL
) && (ConsoleIn
->ConIn
.WaitForKey
!= NULL
)) {
324 gBS
->CloseEvent (ConsoleIn
->ConIn
.WaitForKey
);
327 if ((ConsoleIn
!= NULL
) && (ConsoleIn
->TimerEvent
!= NULL
)) {
328 gBS
->CloseEvent (ConsoleIn
->TimerEvent
);
331 if ((ConsoleIn
!= NULL
) && (ConsoleIn
->ControllerNameTable
!= NULL
)) {
332 FreeUnicodeStringTable (ConsoleIn
->ControllerNameTable
);
335 // Since there will be no timer handler for keyboard input any more,
336 // exhaust input data just in case there is still keyboard data left
338 Status1
= EFI_SUCCESS
;
339 while (!EFI_ERROR (Status1
)) {
340 Status1
= KeyboardRead (ConsoleIn
, &Data
);;
343 if (ConsoleIn
!= NULL
) {
344 gBS
->FreePool (ConsoleIn
);
349 &gEfiDevicePathProtocolGuid
,
350 This
->DriverBindingHandle
,
356 &gEfiIsaIoProtocolGuid
,
357 This
->DriverBindingHandle
,
366 KbdControllerDriverStop (
367 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
368 IN EFI_HANDLE Controller
,
369 IN UINTN NumberOfChildren
,
370 IN EFI_HANDLE
*ChildHandleBuffer
381 // GC_TODO: This - add argument and description to function comment
382 // GC_TODO: Controller - add argument and description to function comment
383 // GC_TODO: NumberOfChildren - add argument and description to function comment
384 // GC_TODO: ChildHandleBuffer - add argument and description to function comment
385 // GC_TODO: EFI_SUCCESS - add return value to function comment
388 EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*ConIn
;
389 KEYBOARD_CONSOLE_IN_DEV
*ConsoleIn
;
395 Status
= gBS
->OpenProtocol (
397 &gEfiSimpleTextInProtocolGuid
,
399 This
->DriverBindingHandle
,
401 EFI_OPEN_PROTOCOL_GET_PROTOCOL
403 if (EFI_ERROR (Status
)) {
407 ConsoleIn
= KEYBOARD_CONSOLE_IN_DEV_FROM_THIS (ConIn
);
410 // Report that the keyboard is being disabled
412 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
414 EFI_PERIPHERAL_KEYBOARD
| EFI_P_PC_DISABLE
,
415 ConsoleIn
->DevicePath
418 if (ConsoleIn
->TimerEvent
) {
419 gBS
->CloseEvent (ConsoleIn
->TimerEvent
);
420 ConsoleIn
->TimerEvent
= NULL
;
423 // Disable the keyboard interface
425 Status
= DisableKeyboard (ConsoleIn
);
428 // Since there will be no timer handler for keyboard input any more,
429 // exhaust input data just in case there is still keyboard data left
431 Status
= EFI_SUCCESS
;
432 while (!EFI_ERROR (Status
)) {
433 Status
= KeyboardRead (ConsoleIn
, &Data
);;
436 // Uninstall the Simple TextIn Protocol
438 Status
= gBS
->UninstallProtocolInterface (
440 &gEfiSimpleTextInProtocolGuid
,
443 if (EFI_ERROR (Status
)) {
449 &gEfiDevicePathProtocolGuid
,
450 This
->DriverBindingHandle
,
456 &gEfiIsaIoProtocolGuid
,
457 This
->DriverBindingHandle
,
462 // Free other resources
464 if ((ConsoleIn
->ConIn
).WaitForKey
) {
465 gBS
->CloseEvent ((ConsoleIn
->ConIn
).WaitForKey
);
466 (ConsoleIn
->ConIn
).WaitForKey
= NULL
;
469 FreeUnicodeStringTable (ConsoleIn
->ControllerNameTable
);
470 gBS
->FreePool (ConsoleIn
);