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