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