]> git.proxmox.com Git - mirror_edk2.git/blame - IntelFrameworkModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2Keyboard.c
Cleanup the license header
[mirror_edk2.git] / IntelFrameworkModulePkg / Bus / Isa / Ps2KeyboardDxe / Ps2Keyboard.c
CommitLineData
f8cd287b 1/**@file\r
2\r
3 PS/2 Keyboard driver. Routines that interacts with callers,\r
4 conforming to EFI driver model\r
05fbd06d 5\r
df0dcb5e 6Copyright (c) 2006 - 2007, Intel Corporation\r
7All rights reserved. This program and the accompanying materials\r
8are licensed and made available under the terms and conditions of the BSD License\r
9which accompanies this distribution. The full text of the license may be found at\r
10http://opensource.org/licenses/bsd-license.php\r
11\r
12THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
13WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
05fbd06d 14\r
f8cd287b 15**/\r
05fbd06d 16\r
05fbd06d 17#include "Ps2Keyboard.h"\r
18\r
19//\r
20// Function prototypes\r
21//\r
22EFI_STATUS\r
23EFIAPI\r
24KbdControllerDriverSupported (\r
25 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
26 IN EFI_HANDLE Controller,\r
27 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
28 );\r
29\r
30EFI_STATUS\r
31EFIAPI\r
32KbdControllerDriverStart (\r
33 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
34 IN EFI_HANDLE Controller,\r
35 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
36 );\r
37\r
38EFI_STATUS\r
39EFIAPI\r
40KbdControllerDriverStop (\r
41 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
42 IN EFI_HANDLE Controller,\r
43 IN UINTN NumberOfChildren,\r
44 IN EFI_HANDLE *ChildHandleBuffer\r
45 );\r
46\r
47//\r
48// Global variables\r
49//\r
50//\r
51// DriverBinding Protocol Instance\r
52//\r
53EFI_DRIVER_BINDING_PROTOCOL gKeyboardControllerDriver = {\r
54 KbdControllerDriverSupported,\r
55 KbdControllerDriverStart,\r
56 KbdControllerDriverStop,\r
57 0xa,\r
58 NULL,\r
59 NULL\r
60};\r
61\r
62EFI_STATUS\r
63EFIAPI\r
64KbdControllerDriverSupported (\r
65 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
66 IN EFI_HANDLE Controller,\r
67 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
68 )\r
69/*++\r
70\r
71Routine Description:\r
72\r
73 ControllerDriver Protocol Method\r
74\r
75Arguments:\r
76\r
77Returns:\r
78\r
79--*/\r
80// GC_TODO: This - add argument and description to function comment\r
81// GC_TODO: Controller - add argument and description to function comment\r
82// GC_TODO: RemainingDevicePath - add argument and description to function comment\r
83{\r
84 EFI_STATUS Status;\r
85 EFI_ISA_IO_PROTOCOL *IsaIo;\r
86\r
87 //\r
88 // Open the IO Abstraction(s) needed to perform the supported test\r
89 //\r
90 Status = gBS->OpenProtocol (\r
91 Controller,\r
92 &gEfiIsaIoProtocolGuid,\r
93 (VOID **) &IsaIo,\r
94 This->DriverBindingHandle,\r
95 Controller,\r
96 EFI_OPEN_PROTOCOL_BY_DRIVER\r
97 );\r
98 if (EFI_ERROR (Status)) {\r
99 return Status;\r
100 }\r
101 //\r
102 // Use the ISA I/O Protocol to see if Controller is the Keyboard controller\r
103 //\r
104 if (IsaIo->ResourceList->Device.HID != EISA_PNP_ID (0x303) || IsaIo->ResourceList->Device.UID != 0) {\r
105 Status = EFI_UNSUPPORTED;\r
106 }\r
107 //\r
108 // Close the I/O Abstraction(s) used to perform the supported test\r
109 //\r
110 gBS->CloseProtocol (\r
111 Controller,\r
112 &gEfiIsaIoProtocolGuid,\r
113 This->DriverBindingHandle,\r
114 Controller\r
115 );\r
116\r
117 return Status;\r
118}\r
119\r
120EFI_STATUS\r
121EFIAPI\r
122KbdControllerDriverStart (\r
123 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
124 IN EFI_HANDLE Controller,\r
125 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
126 )\r
127/*++\r
128\r
129Routine Description:\r
130\r
131Arguments:\r
132\r
133Returns:\r
134\r
135--*/\r
136// GC_TODO: This - add argument and description to function comment\r
137// GC_TODO: Controller - add argument and description to function comment\r
138// GC_TODO: RemainingDevicePath - add argument and description to function comment\r
139// GC_TODO: EFI_INVALID_PARAMETER - add return value to function comment\r
140{\r
141 EFI_STATUS Status;\r
142 EFI_STATUS Status1;\r
143 EFI_ISA_IO_PROTOCOL *IsaIo;\r
144 KEYBOARD_CONSOLE_IN_DEV *ConsoleIn;\r
145 UINT8 Data;\r
146 EFI_STATUS_CODE_VALUE StatusCode;\r
147 EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;\r
148\r
149 StatusCode = 0;\r
150\r
151 Status = gBS->OpenProtocol (\r
152 Controller,\r
153 &gEfiDevicePathProtocolGuid,\r
154 (VOID **) &ParentDevicePath,\r
155 This->DriverBindingHandle,\r
156 Controller,\r
157 EFI_OPEN_PROTOCOL_BY_DRIVER\r
158 );\r
159 if (EFI_ERROR (Status)) {\r
160 return Status;\r
161 }\r
162 //\r
163 // Report that the keyboard is being enabled\r
164 //\r
165 REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
166 EFI_PROGRESS_CODE,\r
167 EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_ENABLE,\r
168 ParentDevicePath\r
169 );\r
170\r
171 //\r
172 // Get the ISA I/O Protocol on Controller's handle\r
173 //\r
174 Status = gBS->OpenProtocol (\r
175 Controller,\r
176 &gEfiIsaIoProtocolGuid,\r
177 (VOID **) &IsaIo,\r
178 This->DriverBindingHandle,\r
179 Controller,\r
180 EFI_OPEN_PROTOCOL_BY_DRIVER\r
181 );\r
182 if (EFI_ERROR (Status)) {\r
183 gBS->CloseProtocol (\r
184 Controller,\r
185 &gEfiDevicePathProtocolGuid,\r
186 This->DriverBindingHandle,\r
187 Controller\r
188 );\r
189 return EFI_INVALID_PARAMETER;\r
190 }\r
191 //\r
192 // Allocate private data\r
193 //\r
194 ConsoleIn = AllocateZeroPool (sizeof (KEYBOARD_CONSOLE_IN_DEV));\r
195 if (ConsoleIn == NULL) {\r
196 Status = EFI_OUT_OF_RESOURCES;\r
197 StatusCode = EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_CONTROLLER_ERROR;\r
198 goto ErrorExit;\r
199 }\r
200 //\r
201 // Setup the device instance\r
202 //\r
203 ConsoleIn->Signature = KEYBOARD_CONSOLE_IN_DEV_SIGNATURE;\r
204 ConsoleIn->Handle = Controller;\r
205 (ConsoleIn->ConIn).Reset = KeyboardEfiReset;\r
206 (ConsoleIn->ConIn).ReadKeyStroke = KeyboardReadKeyStroke;\r
207 ConsoleIn->DataRegisterAddress = KEYBOARD_8042_DATA_REGISTER;\r
208 ConsoleIn->StatusRegisterAddress = KEYBOARD_8042_STATUS_REGISTER;\r
209 ConsoleIn->CommandRegisterAddress = KEYBOARD_8042_COMMAND_REGISTER;\r
210 ConsoleIn->IsaIo = IsaIo;\r
211 ConsoleIn->ScancodeBufStartPos = 0;\r
212 ConsoleIn->ScancodeBufEndPos = KEYBOARD_BUFFER_MAX_COUNT - 1;\r
213 ConsoleIn->ScancodeBufCount = 0;\r
214 ConsoleIn->Ctrled = FALSE;\r
215 ConsoleIn->Alted = FALSE;\r
216 ConsoleIn->DevicePath = ParentDevicePath;\r
217\r
218 //\r
219 // Setup the WaitForKey event\r
220 //\r
221 Status = gBS->CreateEvent (\r
222 EVT_NOTIFY_WAIT,\r
223 TPL_NOTIFY,\r
224 KeyboardWaitForKey,\r
225 &(ConsoleIn->ConIn),\r
226 &((ConsoleIn->ConIn).WaitForKey)\r
227 );\r
228 if (EFI_ERROR (Status)) {\r
229 Status = EFI_OUT_OF_RESOURCES;\r
230 StatusCode = EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_CONTROLLER_ERROR;\r
231 goto ErrorExit;\r
232 }\r
233 //\r
234 // Setup a periodic timer, used for reading keystrokes at a fixed interval\r
235 //\r
236 Status = gBS->CreateEvent (\r
237 EVT_TIMER | EVT_NOTIFY_SIGNAL,\r
238 TPL_NOTIFY,\r
239 KeyboardTimerHandler,\r
240 ConsoleIn,\r
241 &ConsoleIn->TimerEvent\r
242 );\r
243 if (EFI_ERROR (Status)) {\r
244 Status = EFI_OUT_OF_RESOURCES;\r
245 StatusCode = EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_CONTROLLER_ERROR;\r
246 goto ErrorExit;\r
247 }\r
248\r
249 Status = gBS->SetTimer (\r
250 ConsoleIn->TimerEvent,\r
251 TimerPeriodic,\r
252 KEYBOARD_TIMER_INTERVAL\r
253 );\r
254 if (EFI_ERROR (Status)) {\r
255 Status = EFI_OUT_OF_RESOURCES;\r
256 StatusCode = EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_CONTROLLER_ERROR;\r
257 goto ErrorExit;\r
258 }\r
259\r
260 REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
261 EFI_PROGRESS_CODE,\r
262 EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_PRESENCE_DETECT,\r
263 ParentDevicePath\r
264 );\r
265\r
266 //\r
267 // Reset the keyboard device\r
268 //\r
269 Status = ConsoleIn->ConIn.Reset (&ConsoleIn->ConIn, TRUE);\r
270 if (EFI_ERROR (Status)) {\r
271 Status = EFI_DEVICE_ERROR;\r
272 StatusCode = EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_NOT_DETECTED;\r
273 goto ErrorExit;\r
274 }\r
275\r
276 ConsoleIn->ControllerNameTable = NULL;\r
277 AddUnicodeString (\r
278 "eng",\r
279 gPs2KeyboardComponentName.SupportedLanguages,\r
280 &ConsoleIn->ControllerNameTable,\r
281 L"PS/2 Keyboard Device"\r
282 );\r
283\r
284 //\r
285 // Install protocol interfaces for the keyboard device.\r
286 //\r
287 Status = gBS->InstallMultipleProtocolInterfaces (\r
288 &Controller,\r
289 &gEfiSimpleTextInProtocolGuid,\r
290 &ConsoleIn->ConIn,\r
291 NULL\r
292 );\r
293 if (EFI_ERROR (Status)) {\r
294 StatusCode = EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_CONTROLLER_ERROR;\r
295 goto ErrorExit;\r
296 }\r
297\r
298 return Status;\r
299\r
300ErrorExit:\r
301 //\r
302 // Report error code\r
303 //\r
304 if (StatusCode != 0) {\r
305 REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
306 EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
307 StatusCode,\r
308 ParentDevicePath\r
309 );\r
310 }\r
311\r
312 if ((ConsoleIn != NULL) && (ConsoleIn->ConIn.WaitForKey != NULL)) {\r
313 gBS->CloseEvent (ConsoleIn->ConIn.WaitForKey);\r
314 }\r
315\r
316 if ((ConsoleIn != NULL) && (ConsoleIn->TimerEvent != NULL)) {\r
317 gBS->CloseEvent (ConsoleIn->TimerEvent);\r
318 }\r
319\r
320 if ((ConsoleIn != NULL) && (ConsoleIn->ControllerNameTable != NULL)) {\r
321 FreeUnicodeStringTable (ConsoleIn->ControllerNameTable);\r
322 }\r
323 //\r
324 // Since there will be no timer handler for keyboard input any more,\r
325 // exhaust input data just in case there is still keyboard data left\r
326 //\r
327 Status1 = EFI_SUCCESS;\r
328 while (!EFI_ERROR (Status1)) {\r
329 Status1 = KeyboardRead (ConsoleIn, &Data);;\r
330 }\r
331\r
332 if (ConsoleIn != NULL) {\r
333 gBS->FreePool (ConsoleIn);\r
334 }\r
335\r
336 gBS->CloseProtocol (\r
337 Controller,\r
338 &gEfiDevicePathProtocolGuid,\r
339 This->DriverBindingHandle,\r
340 Controller\r
341 );\r
342\r
343 gBS->CloseProtocol (\r
344 Controller,\r
345 &gEfiIsaIoProtocolGuid,\r
346 This->DriverBindingHandle,\r
347 Controller\r
348 );\r
349\r
350 return Status;\r
351}\r
352\r
353EFI_STATUS\r
354EFIAPI\r
355KbdControllerDriverStop (\r
356 IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
357 IN EFI_HANDLE Controller,\r
358 IN UINTN NumberOfChildren,\r
359 IN EFI_HANDLE *ChildHandleBuffer\r
360 )\r
361/*++\r
362\r
363 Routine Description:\r
364\r
365 Arguments:\r
366\r
367 Returns:\r
368\r
369--*/\r
370// GC_TODO: This - add argument and description to function comment\r
371// GC_TODO: Controller - add argument and description to function comment\r
372// GC_TODO: NumberOfChildren - add argument and description to function comment\r
373// GC_TODO: ChildHandleBuffer - add argument and description to function comment\r
374// GC_TODO: EFI_SUCCESS - add return value to function comment\r
375{\r
376 EFI_STATUS Status;\r
377 EFI_SIMPLE_TEXT_INPUT_PROTOCOL *ConIn;\r
378 KEYBOARD_CONSOLE_IN_DEV *ConsoleIn;\r
379 UINT8 Data;\r
380\r
381 //\r
382 // Disable Keyboard\r
383 //\r
384 Status = gBS->OpenProtocol (\r
385 Controller,\r
386 &gEfiSimpleTextInProtocolGuid,\r
387 (VOID **) &ConIn,\r
388 This->DriverBindingHandle,\r
389 Controller,\r
390 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
391 );\r
392 if (EFI_ERROR (Status)) {\r
393 return Status;\r
394 }\r
395\r
396 ConsoleIn = KEYBOARD_CONSOLE_IN_DEV_FROM_THIS (ConIn);\r
397\r
398 //\r
399 // Report that the keyboard is being disabled\r
400 //\r
401 REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
402 EFI_PROGRESS_CODE,\r
403 EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_DISABLE,\r
404 ConsoleIn->DevicePath\r
405 );\r
406\r
407 if (ConsoleIn->TimerEvent) {\r
408 gBS->CloseEvent (ConsoleIn->TimerEvent);\r
409 ConsoleIn->TimerEvent = NULL;\r
410 }\r
411 //\r
412 // Disable the keyboard interface\r
413 //\r
414 Status = DisableKeyboard (ConsoleIn);\r
415\r
416 //\r
417 // Since there will be no timer handler for keyboard input any more,\r
418 // exhaust input data just in case there is still keyboard data left\r
419 //\r
420 Status = EFI_SUCCESS;\r
421 while (!EFI_ERROR (Status)) {\r
422 Status = KeyboardRead (ConsoleIn, &Data);;\r
423 }\r
424 //\r
425 // Uninstall the Simple TextIn Protocol\r
426 //\r
427 Status = gBS->UninstallProtocolInterface (\r
428 Controller,\r
429 &gEfiSimpleTextInProtocolGuid,\r
430 &ConsoleIn->ConIn\r
431 );\r
432 if (EFI_ERROR (Status)) {\r
433 return Status;\r
434 }\r
435\r
436 gBS->CloseProtocol (\r
437 Controller,\r
438 &gEfiDevicePathProtocolGuid,\r
439 This->DriverBindingHandle,\r
440 Controller\r
441 );\r
442\r
443 gBS->CloseProtocol (\r
444 Controller,\r
445 &gEfiIsaIoProtocolGuid,\r
446 This->DriverBindingHandle,\r
447 Controller\r
448 );\r
449\r
450 //\r
451 // Free other resources\r
452 //\r
453 if ((ConsoleIn->ConIn).WaitForKey) {\r
454 gBS->CloseEvent ((ConsoleIn->ConIn).WaitForKey);\r
455 (ConsoleIn->ConIn).WaitForKey = NULL;\r
456 }\r
457\r
458 FreeUnicodeStringTable (ConsoleIn->ControllerNameTable);\r
459 gBS->FreePool (ConsoleIn);\r
460\r
461 return EFI_SUCCESS;\r
462}\r
c21fc3e8 463\r
464\r
465/**\r
466 The user Entry Point for module Ps2Keyboard. The user code starts with this function.\r
467\r
468 @param[in] ImageHandle The firmware allocated handle for the EFI image. \r
469 @param[in] SystemTable A pointer to the EFI System Table.\r
470 \r
471 @retval EFI_SUCCESS The entry point is executed successfully.\r
472 @retval other Some error occurs when executing this entry point.\r
473\r
474**/\r
475EFI_STATUS\r
476EFIAPI\r
477InitializePs2Keyboard(\r
478 IN EFI_HANDLE ImageHandle,\r
479 IN EFI_SYSTEM_TABLE *SystemTable\r
480 )\r
481{\r
482 EFI_STATUS Status;\r
483\r
484 //\r
485 // Install driver model protocol(s).\r
486 //\r
487 Status = EfiLibInstallAllDriverProtocols (\r
488 ImageHandle,\r
489 SystemTable,\r
490 &gKeyboardControllerDriver,\r
491 ImageHandle,\r
492 &gPs2KeyboardComponentName,\r
493 NULL,\r
494 NULL\r
495 );\r
496 ASSERT_EFI_ERROR (Status);\r
497\r
498\r
499 return Status;\r
500}\r