3 Copyright (c) 2006 - 2007, Intel Corporation. All rights reserved. <BR>
4 This software and associated documentation (if any) is furnished
5 under a license and may only be used or copied in accordance
6 with the terms of the license. Except as permitted by such
7 license, no part of this software or documentation may be
8 reproduced, stored in a retrieval system, or transmitted in any
9 form or by any means without the express written consent of
19 PS/2 Keyboard driver. Routines that interacts with callers,
20 conforming to EFI driver model
25 // Include common header file for this module.
27 #include "CommonHeader.h"
29 #include "Ps2Keyboard.h"
32 // Function prototypes
36 KbdControllerDriverSupported (
37 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
38 IN EFI_HANDLE Controller
,
39 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
44 KbdControllerDriverStart (
45 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
46 IN EFI_HANDLE Controller
,
47 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
52 KbdControllerDriverStop (
53 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
54 IN EFI_HANDLE Controller
,
55 IN UINTN NumberOfChildren
,
56 IN EFI_HANDLE
*ChildHandleBuffer
63 // DriverBinding Protocol Instance
65 EFI_DRIVER_BINDING_PROTOCOL gKeyboardControllerDriver
= {
66 KbdControllerDriverSupported
,
67 KbdControllerDriverStart
,
68 KbdControllerDriverStop
,
76 KbdControllerDriverSupported (
77 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
78 IN EFI_HANDLE Controller
,
79 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
85 ControllerDriver Protocol Method
92 // GC_TODO: This - add argument and description to function comment
93 // GC_TODO: Controller - add argument and description to function comment
94 // GC_TODO: RemainingDevicePath - add argument and description to function comment
97 EFI_ISA_IO_PROTOCOL
*IsaIo
;
100 // Open the IO Abstraction(s) needed to perform the supported test
102 Status
= gBS
->OpenProtocol (
104 &gEfiIsaIoProtocolGuid
,
106 This
->DriverBindingHandle
,
108 EFI_OPEN_PROTOCOL_BY_DRIVER
110 if (EFI_ERROR (Status
)) {
114 // Use the ISA I/O Protocol to see if Controller is the Keyboard controller
116 if (IsaIo
->ResourceList
->Device
.HID
!= EISA_PNP_ID (0x303) || IsaIo
->ResourceList
->Device
.UID
!= 0) {
117 Status
= EFI_UNSUPPORTED
;
120 // Close the I/O Abstraction(s) used to perform the supported test
124 &gEfiIsaIoProtocolGuid
,
125 This
->DriverBindingHandle
,
134 KbdControllerDriverStart (
135 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
136 IN EFI_HANDLE Controller
,
137 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
148 // GC_TODO: This - add argument and description to function comment
149 // GC_TODO: Controller - add argument and description to function comment
150 // GC_TODO: RemainingDevicePath - add argument and description to function comment
151 // GC_TODO: EFI_INVALID_PARAMETER - add return value to function comment
155 EFI_ISA_IO_PROTOCOL
*IsaIo
;
156 KEYBOARD_CONSOLE_IN_DEV
*ConsoleIn
;
158 EFI_STATUS_CODE_VALUE StatusCode
;
159 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
163 Status
= gBS
->OpenProtocol (
165 &gEfiDevicePathProtocolGuid
,
166 (VOID
**) &ParentDevicePath
,
167 This
->DriverBindingHandle
,
169 EFI_OPEN_PROTOCOL_BY_DRIVER
171 if (EFI_ERROR (Status
)) {
175 // Report that the keyboard is being enabled
177 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
179 EFI_PERIPHERAL_KEYBOARD
| EFI_P_PC_ENABLE
,
184 // Get the ISA I/O Protocol on Controller's handle
186 Status
= gBS
->OpenProtocol (
188 &gEfiIsaIoProtocolGuid
,
190 This
->DriverBindingHandle
,
192 EFI_OPEN_PROTOCOL_BY_DRIVER
194 if (EFI_ERROR (Status
)) {
197 &gEfiDevicePathProtocolGuid
,
198 This
->DriverBindingHandle
,
201 return EFI_INVALID_PARAMETER
;
204 // Allocate private data
206 ConsoleIn
= AllocateZeroPool (sizeof (KEYBOARD_CONSOLE_IN_DEV
));
207 if (ConsoleIn
== NULL
) {
208 Status
= EFI_OUT_OF_RESOURCES
;
209 StatusCode
= EFI_PERIPHERAL_KEYBOARD
| EFI_P_EC_CONTROLLER_ERROR
;
213 // Setup the device instance
215 ConsoleIn
->Signature
= KEYBOARD_CONSOLE_IN_DEV_SIGNATURE
;
216 ConsoleIn
->Handle
= Controller
;
217 (ConsoleIn
->ConIn
).Reset
= KeyboardEfiReset
;
218 (ConsoleIn
->ConIn
).ReadKeyStroke
= KeyboardReadKeyStroke
;
219 ConsoleIn
->DataRegisterAddress
= KEYBOARD_8042_DATA_REGISTER
;
220 ConsoleIn
->StatusRegisterAddress
= KEYBOARD_8042_STATUS_REGISTER
;
221 ConsoleIn
->CommandRegisterAddress
= KEYBOARD_8042_COMMAND_REGISTER
;
222 ConsoleIn
->IsaIo
= IsaIo
;
223 ConsoleIn
->ScancodeBufStartPos
= 0;
224 ConsoleIn
->ScancodeBufEndPos
= KEYBOARD_BUFFER_MAX_COUNT
- 1;
225 ConsoleIn
->ScancodeBufCount
= 0;
226 ConsoleIn
->Ctrled
= FALSE
;
227 ConsoleIn
->Alted
= FALSE
;
228 ConsoleIn
->DevicePath
= ParentDevicePath
;
231 // Setup the WaitForKey event
233 Status
= gBS
->CreateEvent (
238 &((ConsoleIn
->ConIn
).WaitForKey
)
240 if (EFI_ERROR (Status
)) {
241 Status
= EFI_OUT_OF_RESOURCES
;
242 StatusCode
= EFI_PERIPHERAL_KEYBOARD
| EFI_P_EC_CONTROLLER_ERROR
;
246 // Setup a periodic timer, used for reading keystrokes at a fixed interval
248 Status
= gBS
->CreateEvent (
249 EVT_TIMER
| EVT_NOTIFY_SIGNAL
,
251 KeyboardTimerHandler
,
253 &ConsoleIn
->TimerEvent
255 if (EFI_ERROR (Status
)) {
256 Status
= EFI_OUT_OF_RESOURCES
;
257 StatusCode
= EFI_PERIPHERAL_KEYBOARD
| EFI_P_EC_CONTROLLER_ERROR
;
261 Status
= gBS
->SetTimer (
262 ConsoleIn
->TimerEvent
,
264 KEYBOARD_TIMER_INTERVAL
266 if (EFI_ERROR (Status
)) {
267 Status
= EFI_OUT_OF_RESOURCES
;
268 StatusCode
= EFI_PERIPHERAL_KEYBOARD
| EFI_P_EC_CONTROLLER_ERROR
;
272 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
274 EFI_PERIPHERAL_KEYBOARD
| EFI_P_PC_PRESENCE_DETECT
,
279 // Reset the keyboard device
281 Status
= ConsoleIn
->ConIn
.Reset (&ConsoleIn
->ConIn
, TRUE
);
282 if (EFI_ERROR (Status
)) {
283 Status
= EFI_DEVICE_ERROR
;
284 StatusCode
= EFI_PERIPHERAL_KEYBOARD
| EFI_P_EC_NOT_DETECTED
;
288 ConsoleIn
->ControllerNameTable
= NULL
;
291 gPs2KeyboardComponentName
.SupportedLanguages
,
292 &ConsoleIn
->ControllerNameTable
,
293 L
"PS/2 Keyboard Device"
297 // Install protocol interfaces for the keyboard device.
299 Status
= gBS
->InstallMultipleProtocolInterfaces (
301 &gEfiSimpleTextInProtocolGuid
,
305 if (EFI_ERROR (Status
)) {
306 StatusCode
= EFI_PERIPHERAL_KEYBOARD
| EFI_P_EC_CONTROLLER_ERROR
;
316 if (StatusCode
!= 0) {
317 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
318 EFI_ERROR_CODE
| EFI_ERROR_MINOR
,
324 if ((ConsoleIn
!= NULL
) && (ConsoleIn
->ConIn
.WaitForKey
!= NULL
)) {
325 gBS
->CloseEvent (ConsoleIn
->ConIn
.WaitForKey
);
328 if ((ConsoleIn
!= NULL
) && (ConsoleIn
->TimerEvent
!= NULL
)) {
329 gBS
->CloseEvent (ConsoleIn
->TimerEvent
);
332 if ((ConsoleIn
!= NULL
) && (ConsoleIn
->ControllerNameTable
!= NULL
)) {
333 FreeUnicodeStringTable (ConsoleIn
->ControllerNameTable
);
336 // Since there will be no timer handler for keyboard input any more,
337 // exhaust input data just in case there is still keyboard data left
339 Status1
= EFI_SUCCESS
;
340 while (!EFI_ERROR (Status1
)) {
341 Status1
= KeyboardRead (ConsoleIn
, &Data
);;
344 if (ConsoleIn
!= NULL
) {
345 gBS
->FreePool (ConsoleIn
);
350 &gEfiDevicePathProtocolGuid
,
351 This
->DriverBindingHandle
,
357 &gEfiIsaIoProtocolGuid
,
358 This
->DriverBindingHandle
,
367 KbdControllerDriverStop (
368 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
369 IN EFI_HANDLE Controller
,
370 IN UINTN NumberOfChildren
,
371 IN EFI_HANDLE
*ChildHandleBuffer
382 // GC_TODO: This - add argument and description to function comment
383 // GC_TODO: Controller - add argument and description to function comment
384 // GC_TODO: NumberOfChildren - add argument and description to function comment
385 // GC_TODO: ChildHandleBuffer - add argument and description to function comment
386 // GC_TODO: EFI_SUCCESS - add return value to function comment
389 EFI_SIMPLE_TEXT_INPUT_PROTOCOL
*ConIn
;
390 KEYBOARD_CONSOLE_IN_DEV
*ConsoleIn
;
396 Status
= gBS
->OpenProtocol (
398 &gEfiSimpleTextInProtocolGuid
,
400 This
->DriverBindingHandle
,
402 EFI_OPEN_PROTOCOL_GET_PROTOCOL
404 if (EFI_ERROR (Status
)) {
408 ConsoleIn
= KEYBOARD_CONSOLE_IN_DEV_FROM_THIS (ConIn
);
411 // Report that the keyboard is being disabled
413 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
415 EFI_PERIPHERAL_KEYBOARD
| EFI_P_PC_DISABLE
,
416 ConsoleIn
->DevicePath
419 if (ConsoleIn
->TimerEvent
) {
420 gBS
->CloseEvent (ConsoleIn
->TimerEvent
);
421 ConsoleIn
->TimerEvent
= NULL
;
424 // Disable the keyboard interface
426 Status
= DisableKeyboard (ConsoleIn
);
429 // Since there will be no timer handler for keyboard input any more,
430 // exhaust input data just in case there is still keyboard data left
432 Status
= EFI_SUCCESS
;
433 while (!EFI_ERROR (Status
)) {
434 Status
= KeyboardRead (ConsoleIn
, &Data
);;
437 // Uninstall the Simple TextIn Protocol
439 Status
= gBS
->UninstallProtocolInterface (
441 &gEfiSimpleTextInProtocolGuid
,
444 if (EFI_ERROR (Status
)) {
450 &gEfiDevicePathProtocolGuid
,
451 This
->DriverBindingHandle
,
457 &gEfiIsaIoProtocolGuid
,
458 This
->DriverBindingHandle
,
463 // Free other resources
465 if ((ConsoleIn
->ConIn
).WaitForKey
) {
466 gBS
->CloseEvent ((ConsoleIn
->ConIn
).WaitForKey
);
467 (ConsoleIn
->ConIn
).WaitForKey
= NULL
;
470 FreeUnicodeStringTable (ConsoleIn
->ControllerNameTable
);
471 gBS
->FreePool (ConsoleIn
);