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