]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Bus/Isa/Ps2MouseDxe/CommPs2.c
MdeModulePkg: Apply uncrustify changes
[mirror_edk2.git] / MdeModulePkg / Bus / Isa / Ps2MouseDxe / CommPs2.c
CommitLineData
77833d0b
RN
1/** @file\r
2 PS2 Mouse Communication Interface.\r
3\r
4Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>\r
9d510e61 5SPDX-License-Identifier: BSD-2-Clause-Patent\r
77833d0b
RN
6\r
7**/\r
8\r
9#include "Ps2Mouse.h"\r
10#include "CommPs2.h"\r
11\r
1436aea4 12UINT8 SampleRateTbl[MaxSampleRate] = { 0xa, 0x14, 0x28, 0x3c, 0x50, 0x64, 0xc8 };\r
77833d0b 13\r
1436aea4 14UINT8 ResolutionTbl[MaxResolution] = { 0, 1, 2, 3 };\r
77833d0b
RN
15\r
16/**\r
17 Issue self test command via IsaIo interface.\r
18\r
19 @return EFI_SUCCESS Success to do keyboard self testing.\r
20 @return others Fail to do keyboard self testing.\r
21**/\r
22EFI_STATUS\r
23KbcSelfTest (\r
24 VOID\r
25 )\r
26{\r
27 EFI_STATUS Status;\r
28 UINT8 Data;\r
29\r
30 //\r
31 // Keyboard controller self test\r
32 //\r
33 Status = Out8042Command (SELF_TEST);\r
34 if (EFI_ERROR (Status)) {\r
35 return Status;\r
36 }\r
1436aea4 37\r
77833d0b
RN
38 //\r
39 // Read return code\r
40 //\r
41 Status = In8042Data (&Data);\r
42 if (EFI_ERROR (Status)) {\r
43 return Status;\r
44 }\r
45\r
46 if (Data != 0x55) {\r
47 return EFI_DEVICE_ERROR;\r
48 }\r
1436aea4 49\r
77833d0b
RN
50 //\r
51 // Set system flag\r
52 //\r
53 Status = Out8042Command (READ_CMD_BYTE);\r
54 if (EFI_ERROR (Status)) {\r
55 return Status;\r
56 }\r
57\r
58 Status = In8042Data (&Data);\r
59 if (EFI_ERROR (Status)) {\r
60 return Status;\r
61 }\r
62\r
63 Status = Out8042Command (WRITE_CMD_BYTE);\r
64 if (EFI_ERROR (Status)) {\r
65 return Status;\r
66 }\r
67\r
1436aea4 68 Data |= CMD_SYS_FLAG;\r
77833d0b
RN
69 Status = Out8042Data (Data);\r
70 if (EFI_ERROR (Status)) {\r
71 return Status;\r
72 }\r
73\r
74 return EFI_SUCCESS;\r
75}\r
76\r
77/**\r
78 Issue command to enable keyboard AUX functionality.\r
79\r
80 @return Status of command issuing.\r
81**/\r
82EFI_STATUS\r
83KbcEnableAux (\r
84 VOID\r
85 )\r
86{\r
87 //\r
88 // Send 8042 enable mouse command\r
89 //\r
90 return Out8042Command (ENABLE_AUX);\r
91}\r
92\r
93/**\r
94 Issue command to disable keyboard AUX functionality.\r
95\r
96 @param IsaIo Pointer to instance of EFI_ISA_IO_PROTOCOL\r
97\r
98 @return Status of command issuing.\r
99**/\r
100EFI_STATUS\r
101KbcDisableAux (\r
102 VOID\r
103 )\r
104{\r
105 //\r
106 // Send 8042 disable mouse command\r
107 //\r
108 return Out8042Command (DISABLE_AUX);\r
109}\r
110\r
111/**\r
112 Issue command to enable keyboard.\r
113\r
114 @param IsaIo Pointer to instance of EFI_ISA_IO_PROTOCOL\r
115\r
116 @return Status of command issuing.\r
117**/\r
118EFI_STATUS\r
119KbcEnableKb (\r
120 VOID\r
121 )\r
122{\r
123 //\r
124 // Send 8042 enable keyboard command\r
125 //\r
126 return Out8042Command (ENABLE_KB);\r
127}\r
128\r
129/**\r
130 Issue command to disable keyboard.\r
131\r
132 @return Status of command issuing.\r
133**/\r
134EFI_STATUS\r
135KbcDisableKb (\r
136 VOID\r
137 )\r
138{\r
139 //\r
140 // Send 8042 disable keyboard command\r
141 //\r
142 return Out8042Command (DISABLE_KB);\r
143}\r
144\r
145/**\r
146 Issue command to check keyboard status.\r
147\r
148 @param KeyboardEnable return whether keyboard is enable.\r
149\r
150 @return Status of command issuing.\r
151**/\r
152EFI_STATUS\r
153CheckKbStatus (\r
1436aea4 154 OUT BOOLEAN *KeyboardEnable\r
77833d0b
RN
155 )\r
156{\r
157 EFI_STATUS Status;\r
158 UINT8 Data;\r
159\r
160 //\r
161 // Send command to read KBC command byte\r
162 //\r
163 Status = Out8042Command (READ_CMD_BYTE);\r
164 if (EFI_ERROR (Status)) {\r
165 return Status;\r
166 }\r
167\r
168 Status = In8042Data (&Data);\r
169 if (EFI_ERROR (Status)) {\r
170 return Status;\r
171 }\r
1436aea4 172\r
77833d0b
RN
173 //\r
174 // Check keyboard enable or not\r
175 //\r
176 if ((Data & CMD_KB_STS) == CMD_KB_DIS) {\r
177 *KeyboardEnable = FALSE;\r
178 } else {\r
179 *KeyboardEnable = TRUE;\r
180 }\r
181\r
182 return EFI_SUCCESS;\r
183}\r
184\r
185/**\r
186 Issue command to reset keyboard.\r
187\r
188 @return Status of command issuing.\r
189**/\r
190EFI_STATUS\r
191PS2MouseReset (\r
192 VOID\r
193 )\r
194{\r
195 EFI_STATUS Status;\r
196 UINT8 Data;\r
197\r
198 Status = Out8042AuxCommand (RESET_CMD, FALSE);\r
199 if (EFI_ERROR (Status)) {\r
200 return Status;\r
201 }\r
202\r
203 Status = In8042AuxData (&Data);\r
204 if (EFI_ERROR (Status)) {\r
205 return Status;\r
206 }\r
1436aea4 207\r
77833d0b
RN
208 //\r
209 // Check BAT Complete Code\r
210 //\r
211 if (Data != PS2MOUSE_BAT1) {\r
212 return EFI_DEVICE_ERROR;\r
213 }\r
214\r
215 Status = In8042AuxData (&Data);\r
216 if (EFI_ERROR (Status)) {\r
217 return Status;\r
218 }\r
1436aea4 219\r
77833d0b
RN
220 //\r
221 // Check BAT Complete Code\r
222 //\r
223 if (Data != PS2MOUSE_BAT2) {\r
224 return EFI_DEVICE_ERROR;\r
225 }\r
226\r
227 return EFI_SUCCESS;\r
228}\r
229\r
230/**\r
231 Issue command to set mouse's sample rate\r
232\r
233 @param SampleRate value of sample rate\r
234\r
235 @return Status of command issuing.\r
236**/\r
237EFI_STATUS\r
238PS2MouseSetSampleRate (\r
1436aea4 239 IN MOUSE_SR SampleRate\r
77833d0b
RN
240 )\r
241{\r
242 EFI_STATUS Status;\r
243\r
244 //\r
245 // Send auxiliary command to set mouse sample rate\r
246 //\r
247 Status = Out8042AuxCommand (SETSR_CMD, FALSE);\r
248 if (EFI_ERROR (Status)) {\r
249 return Status;\r
250 }\r
251\r
252 Status = Out8042AuxData (SampleRateTbl[SampleRate]);\r
253\r
254 return Status;\r
255}\r
256\r
257/**\r
258 Issue command to set mouse's resolution.\r
259\r
260 @param Resolution value of resolution\r
261\r
262 @return Status of command issuing.\r
263**/\r
264EFI_STATUS\r
265PS2MouseSetResolution (\r
1436aea4 266 IN MOUSE_RE Resolution\r
77833d0b
RN
267 )\r
268{\r
269 EFI_STATUS Status;\r
270\r
271 //\r
272 // Send auxiliary command to set mouse resolution\r
273 //\r
274 Status = Out8042AuxCommand (SETRE_CMD, FALSE);\r
275 if (EFI_ERROR (Status)) {\r
276 return Status;\r
277 }\r
278\r
279 Status = Out8042AuxData (ResolutionTbl[Resolution]);\r
280\r
281 return Status;\r
282}\r
283\r
284/**\r
285 Issue command to set mouse's scaling.\r
286\r
287 @param Scaling value of scaling\r
288\r
289 @return Status of command issuing.\r
290**/\r
291EFI_STATUS\r
292PS2MouseSetScaling (\r
1436aea4 293 IN MOUSE_SF Scaling\r
77833d0b
RN
294 )\r
295{\r
296 //\r
297 // Send auxiliary command to set mouse scaling data\r
298 //\r
299 return Out8042AuxCommand (Scaling == Scaling1 ? SETSF1_CMD : SETSF2_CMD, FALSE);\r
300}\r
301\r
302/**\r
303 Issue command to enable Ps2 mouse.\r
304\r
305 @return Status of command issuing.\r
306**/\r
307EFI_STATUS\r
308PS2MouseEnable (\r
309 VOID\r
310 )\r
311{\r
312 //\r
313 // Send auxiliary command to enable mouse\r
314 //\r
315 return Out8042AuxCommand (ENABLE_CMD, FALSE);\r
316}\r
317\r
318/**\r
319 Get mouse packet . Only care first 3 bytes\r
320\r
321 @param MouseDev Pointer of PS2 Mouse Private Data Structure\r
322\r
323 @retval EFI_NOT_READY Mouse Device not ready to input data packet, or some error happened during getting the packet\r
324 @retval EFI_SUCCESS The data packet is gotten successfully.\r
325\r
326**/\r
327EFI_STATUS\r
328PS2MouseGetPacket (\r
1436aea4 329 PS2_MOUSE_DEV *MouseDev\r
77833d0b
RN
330 )\r
331\r
332{\r
333 EFI_STATUS Status;\r
334 BOOLEAN KeyboardEnable;\r
335 UINT8 Packet[PS2_PACKET_LENGTH];\r
336 UINT8 Data;\r
337 UINTN Count;\r
338 UINTN State;\r
339 INT16 RelativeMovementX;\r
340 INT16 RelativeMovementY;\r
341 BOOLEAN LButton;\r
342 BOOLEAN RButton;\r
343\r
1436aea4
MK
344 KeyboardEnable = FALSE;\r
345 State = PS2_READ_BYTE_ONE;\r
77833d0b
RN
346\r
347 //\r
348 // State machine to get mouse packet\r
349 //\r
350 while (1) {\r
77833d0b 351 switch (State) {\r
1436aea4
MK
352 case PS2_READ_BYTE_ONE:\r
353 //\r
354 // Read mouse first byte data, if failed, immediately return\r
355 //\r
356 KbcDisableAux ();\r
357 Count = 1;\r
358 Status = PS2MouseRead (&Data, &Count, State);\r
359 if (EFI_ERROR (Status)) {\r
360 KbcEnableAux ();\r
361 return EFI_NOT_READY;\r
362 }\r
77833d0b 363\r
1436aea4
MK
364 if (Count != 1) {\r
365 KbcEnableAux ();\r
366 return EFI_NOT_READY;\r
367 }\r
368\r
369 if (IS_PS2_SYNC_BYTE (Data)) {\r
370 Packet[0] = Data;\r
371 State = PS2_READ_DATA_BYTE;\r
372\r
373 CheckKbStatus (&KeyboardEnable);\r
374 KbcDisableKb ();\r
375 KbcEnableAux ();\r
376 }\r
377\r
378 break;\r
379\r
380 case PS2_READ_DATA_BYTE:\r
381 Count = 2;\r
382 Status = PS2MouseRead ((Packet + 1), &Count, State);\r
383 if (EFI_ERROR (Status)) {\r
384 if (KeyboardEnable) {\r
385 KbcEnableKb ();\r
386 }\r
387\r
388 return EFI_NOT_READY;\r
389 }\r
390\r
391 if (Count != 2) {\r
392 if (KeyboardEnable) {\r
393 KbcEnableKb ();\r
394 }\r
395\r
396 return EFI_NOT_READY;\r
77833d0b
RN
397 }\r
398\r
1436aea4
MK
399 State = PS2_PROCESS_PACKET;\r
400 break;\r
77833d0b 401\r
1436aea4 402 case PS2_PROCESS_PACKET:\r
77833d0b
RN
403 if (KeyboardEnable) {\r
404 KbcEnableKb ();\r
405 }\r
406\r
1436aea4
MK
407 //\r
408 // Decode the packet\r
409 //\r
410 RelativeMovementX = Packet[1];\r
411 RelativeMovementY = Packet[2];\r
412 //\r
413 // Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0\r
414 // Byte 0 | Y overflow | X overflow | Y sign bit | X sign bit | Always 1 | Middle Btn | Right Btn | Left Btn\r
415 // Byte 1 | 8 bit X Movement\r
416 // Byte 2 | 8 bit Y Movement\r
417 //\r
418 // X sign bit + 8 bit X Movement : 9-bit signed twos complement integer that presents the relative displacement of the device in the X direction since the last data transmission.\r
419 // Y sign bit + 8 bit Y Movement : Same as X sign bit + 8 bit X Movement.\r
420 //\r
421 //\r
422 // First, Clear X and Y high 8 bits\r
423 //\r
424 RelativeMovementX = (INT16)(RelativeMovementX & 0xFF);\r
425 RelativeMovementY = (INT16)(RelativeMovementY & 0xFF);\r
426 //\r
427 // Second, if the 9-bit signed twos complement integer is negative, set the high 8 bit 0xff\r
428 //\r
429 if ((Packet[0] & 0x10) != 0) {\r
430 RelativeMovementX = (INT16)(RelativeMovementX | 0xFF00);\r
431 }\r
77833d0b 432\r
1436aea4
MK
433 if ((Packet[0] & 0x20) != 0) {\r
434 RelativeMovementY = (INT16)(RelativeMovementY | 0xFF00);\r
435 }\r
436\r
437 RButton = (UINT8)(Packet[0] & 0x2);\r
438 LButton = (UINT8)(Packet[0] & 0x1);\r
439\r
440 //\r
441 // Update mouse state\r
442 //\r
443 MouseDev->State.RelativeMovementX += RelativeMovementX;\r
444 MouseDev->State.RelativeMovementY -= RelativeMovementY;\r
445 MouseDev->State.RightButton = (UINT8)(RButton ? TRUE : FALSE);\r
446 MouseDev->State.LeftButton = (UINT8)(LButton ? TRUE : FALSE);\r
447 MouseDev->StateChanged = TRUE;\r
77833d0b 448\r
1436aea4 449 return EFI_SUCCESS;\r
77833d0b
RN
450 }\r
451 }\r
452}\r
453\r
454/**\r
455 Read data via IsaIo protocol with given number.\r
456\r
457 @param Buffer Buffer receive data of mouse\r
458 @param BufSize The size of buffer\r
459 @param State Check input or read data\r
460\r
461 @return status of reading mouse data.\r
462**/\r
463EFI_STATUS\r
464PS2MouseRead (\r
1436aea4
MK
465 OUT UINT8 *Buffer,\r
466 IN OUT UINTN *BufSize,\r
467 IN UINTN State\r
77833d0b
RN
468 )\r
469{\r
470 EFI_STATUS Status;\r
471 UINTN BytesRead;\r
472\r
1436aea4 473 Status = EFI_SUCCESS;\r
77833d0b
RN
474\r
475 if (State == PS2_READ_BYTE_ONE) {\r
476 //\r
477 // Check input for mouse\r
478 //\r
479 Status = CheckForInput ();\r
480\r
481 if (EFI_ERROR (Status)) {\r
482 return Status;\r
483 }\r
484 }\r
485\r
486 for (BytesRead = 0; BytesRead < *BufSize; BytesRead++) {\r
77833d0b
RN
487 Status = WaitOutputFull (TIMEOUT);\r
488 if (EFI_ERROR (Status)) {\r
489 break;\r
490 }\r
1436aea4 491\r
77833d0b
RN
492 Buffer[BytesRead] = IoRead8 (KBC_DATA_PORT);\r
493 }\r
1436aea4 494\r
77833d0b
RN
495 //\r
496 // Verify the correct number of bytes read\r
497 //\r
1436aea4 498 if ((BytesRead == 0) || (BytesRead != *BufSize)) {\r
77833d0b
RN
499 Status = EFI_NOT_FOUND;\r
500 }\r
501\r
502 *BufSize = BytesRead;\r
503 return Status;\r
504}\r
505\r
506//\r
507// 8042 I/O function\r
508//\r
1436aea4 509\r
77833d0b
RN
510/**\r
511 I/O work flow of outing 8042 command.\r
512\r
513 @param Command I/O command.\r
514\r
ed356b9e 515 @retval EFI_SUCCESS Success to execute I/O work flow\r
77833d0b
RN
516 @retval EFI_TIMEOUT Keyboard controller time out.\r
517**/\r
518EFI_STATUS\r
519Out8042Command (\r
1436aea4 520 IN UINT8 Command\r
77833d0b
RN
521 )\r
522{\r
523 EFI_STATUS Status;\r
524\r
525 //\r
526 // Wait keyboard controller input buffer empty\r
527 //\r
528 Status = WaitInputEmpty (TIMEOUT);\r
529 if (EFI_ERROR (Status)) {\r
530 return Status;\r
531 }\r
1436aea4 532\r
77833d0b
RN
533 //\r
534 // Send command\r
535 //\r
536 IoWrite8 (KBC_CMD_STS_PORT, Command);\r
537\r
538 Status = WaitInputEmpty (TIMEOUT);\r
539 if (EFI_ERROR (Status)) {\r
540 return Status;\r
541 }\r
542\r
543 return EFI_SUCCESS;\r
544}\r
545\r
546/**\r
547 I/O work flow of outing 8042 data.\r
548\r
549 @param Data Data value\r
550\r
ed356b9e 551 @retval EFI_SUCCESS Success to execute I/O work flow\r
77833d0b
RN
552 @retval EFI_TIMEOUT Keyboard controller time out.\r
553**/\r
554EFI_STATUS\r
555Out8042Data (\r
1436aea4 556 IN UINT8 Data\r
77833d0b
RN
557 )\r
558{\r
559 EFI_STATUS Status;\r
1436aea4 560\r
77833d0b
RN
561 //\r
562 // Wait keyboard controller input buffer empty\r
563 //\r
564 Status = WaitInputEmpty (TIMEOUT);\r
565 if (EFI_ERROR (Status)) {\r
566 return Status;\r
567 }\r
568\r
569 IoWrite8 (KBC_DATA_PORT, Data);\r
570 return WaitInputEmpty (TIMEOUT);\r
571}\r
572\r
573/**\r
574 I/O work flow of in 8042 data.\r
575\r
576 @param Data Data value\r
577\r
ed356b9e 578 @retval EFI_SUCCESS Success to execute I/O work flow\r
77833d0b
RN
579 @retval EFI_TIMEOUT Keyboard controller time out.\r
580**/\r
581EFI_STATUS\r
582In8042Data (\r
1436aea4 583 IN OUT UINT8 *Data\r
77833d0b
RN
584 )\r
585{\r
1436aea4 586 UINTN Delay;\r
77833d0b
RN
587\r
588 Delay = TIMEOUT / 50;\r
589\r
590 do {\r
591 //\r
592 // Check keyboard controller status bit 0(output buffer status)\r
593 //\r
594 if ((IoRead8 (KBC_CMD_STS_PORT) & KBC_OUTB) == KBC_OUTB) {\r
595 break;\r
596 }\r
597\r
598 gBS->Stall (50);\r
599 Delay--;\r
600 } while (Delay != 0);\r
601\r
602 if (Delay == 0) {\r
603 return EFI_TIMEOUT;\r
604 }\r
605\r
606 *Data = IoRead8 (KBC_DATA_PORT);\r
607\r
608 return EFI_SUCCESS;\r
609}\r
610\r
611/**\r
612 I/O work flow of outing 8042 Aux command.\r
613\r
614 @param Command Aux I/O command\r
615 @param Resend Whether need resend the Aux command.\r
616\r
ed356b9e 617 @retval EFI_SUCCESS Success to execute I/O work flow\r
77833d0b
RN
618 @retval EFI_TIMEOUT Keyboard controller time out.\r
619**/\r
620EFI_STATUS\r
621Out8042AuxCommand (\r
1436aea4
MK
622 IN UINT8 Command,\r
623 IN BOOLEAN Resend\r
77833d0b
RN
624 )\r
625{\r
626 EFI_STATUS Status;\r
627 UINT8 Data;\r
628\r
629 //\r
630 // Wait keyboard controller input buffer empty\r
631 //\r
632 Status = WaitInputEmpty (TIMEOUT);\r
633 if (EFI_ERROR (Status)) {\r
634 return Status;\r
635 }\r
1436aea4 636\r
77833d0b
RN
637 //\r
638 // Send write to auxiliary device command\r
639 //\r
640 IoWrite8 (KBC_CMD_STS_PORT, WRITE_AUX_DEV);\r
641\r
642 Status = WaitInputEmpty (TIMEOUT);\r
643 if (EFI_ERROR (Status)) {\r
644 return Status;\r
645 }\r
1436aea4 646\r
77833d0b
RN
647 //\r
648 // Send auxiliary device command\r
649 //\r
650 IoWrite8 (KBC_DATA_PORT, Command);\r
651\r
652 //\r
653 // Read return code\r
654 //\r
655 Status = In8042AuxData (&Data);\r
656 if (EFI_ERROR (Status)) {\r
657 return Status;\r
658 }\r
659\r
660 if (Data == PS2_ACK) {\r
661 //\r
662 // Receive mouse acknowledge, command send success\r
663 //\r
664 return EFI_SUCCESS;\r
77833d0b
RN
665 } else if (Resend) {\r
666 //\r
667 // Resend fail\r
668 //\r
669 return EFI_DEVICE_ERROR;\r
77833d0b
RN
670 } else if (Data == PS2_RESEND) {\r
671 //\r
672 // Resend command\r
673 //\r
674 Status = Out8042AuxCommand (Command, TRUE);\r
675 if (EFI_ERROR (Status)) {\r
676 return Status;\r
677 }\r
77833d0b
RN
678 } else {\r
679 //\r
680 // Invalid return code\r
681 //\r
682 return EFI_DEVICE_ERROR;\r
77833d0b
RN
683 }\r
684\r
685 return EFI_SUCCESS;\r
686}\r
687\r
688/**\r
689 I/O work flow of outing 8042 Aux data.\r
690\r
691 @param Data Buffer holding return value\r
692\r
ed356b9e 693 @retval EFI_SUCCESS Success to execute I/O work flow.\r
77833d0b
RN
694 @retval EFI_TIMEOUT Keyboard controller time out.\r
695**/\r
696EFI_STATUS\r
697Out8042AuxData (\r
1436aea4 698 IN UINT8 Data\r
77833d0b
RN
699 )\r
700{\r
701 EFI_STATUS Status;\r
1436aea4 702\r
77833d0b
RN
703 //\r
704 // Wait keyboard controller input buffer empty\r
705 //\r
706 Status = WaitInputEmpty (TIMEOUT);\r
707 if (EFI_ERROR (Status)) {\r
708 return Status;\r
709 }\r
1436aea4 710\r
77833d0b
RN
711 //\r
712 // Send write to auxiliary device command\r
713 //\r
714 IoWrite8 (KBC_CMD_STS_PORT, WRITE_AUX_DEV);\r
715\r
716 Status = WaitInputEmpty (TIMEOUT);\r
717 if (EFI_ERROR (Status)) {\r
718 return Status;\r
719 }\r
720\r
721 IoWrite8 (KBC_DATA_PORT, Data);\r
722\r
723 Status = WaitInputEmpty (TIMEOUT);\r
724 if (EFI_ERROR (Status)) {\r
725 return Status;\r
726 }\r
727\r
728 return EFI_SUCCESS;\r
729}\r
730\r
731/**\r
732 I/O work flow of in 8042 Aux data.\r
733\r
734 @param Data Buffer holding return value.\r
735\r
ed356b9e 736 @retval EFI_SUCCESS Success to execute I/O work flow\r
77833d0b
RN
737 @retval EFI_TIMEOUT Keyboard controller time out.\r
738**/\r
739EFI_STATUS\r
740In8042AuxData (\r
1436aea4 741 IN OUT UINT8 *Data\r
77833d0b
RN
742 )\r
743{\r
744 EFI_STATUS Status;\r
745\r
746 //\r
747 // wait for output data\r
748 //\r
749 Status = WaitOutputFull (BAT_TIMEOUT);\r
750 if (EFI_ERROR (Status)) {\r
751 return Status;\r
752 }\r
753\r
754 *Data = IoRead8 (KBC_DATA_PORT);\r
755\r
756 return EFI_SUCCESS;\r
757}\r
758\r
77833d0b
RN
759/**\r
760 Check keyboard controller status, if it is output buffer full and for auxiliary device.\r
761\r
762 @retval EFI_SUCCESS Keyboard controller is ready\r
763 @retval EFI_NOT_READY Keyboard controller is not ready\r
764**/\r
765EFI_STATUS\r
766CheckForInput (\r
767 VOID\r
768 )\r
769{\r
1436aea4 770 UINT8 Data;\r
77833d0b
RN
771\r
772 Data = IoRead8 (KBC_CMD_STS_PORT);\r
773\r
774 //\r
775 // Check keyboard controller status, if it is output buffer full and for auxiliary device\r
776 //\r
777 if ((Data & (KBC_OUTB | KBC_AUXB)) != (KBC_OUTB | KBC_AUXB)) {\r
778 return EFI_NOT_READY;\r
779 }\r
780\r
781 return EFI_SUCCESS;\r
782}\r
783\r
784/**\r
785 I/O work flow to wait input buffer empty in given time.\r
786\r
1d031e75 787 @param Timeout Waiting time.\r
77833d0b
RN
788\r
789 @retval EFI_TIMEOUT if input is still not empty in given time.\r
790 @retval EFI_SUCCESS input is empty.\r
791**/\r
792EFI_STATUS\r
793WaitInputEmpty (\r
1436aea4 794 IN UINTN Timeout\r
77833d0b
RN
795 )\r
796{\r
1436aea4
MK
797 UINTN Delay;\r
798 UINT8 Data;\r
77833d0b
RN
799\r
800 Delay = Timeout / 50;\r
801\r
802 do {\r
803 Data = IoRead8 (KBC_CMD_STS_PORT);\r
804\r
805 //\r
806 // Check keyboard controller status bit 1(input buffer status)\r
807 //\r
808 if ((Data & KBC_INPB) == 0) {\r
809 break;\r
810 }\r
811\r
812 gBS->Stall (50);\r
813 Delay--;\r
814 } while (Delay != 0);\r
815\r
816 if (Delay == 0) {\r
817 return EFI_TIMEOUT;\r
818 }\r
819\r
820 return EFI_SUCCESS;\r
821}\r
822\r
823/**\r
824 I/O work flow to wait output buffer full in given time.\r
825\r
826 @param Timeout given time\r
827\r
828 @retval EFI_TIMEOUT output is not full in given time\r
829 @retval EFI_SUCCESS output is full in given time.\r
830**/\r
831EFI_STATUS\r
832WaitOutputFull (\r
1436aea4 833 IN UINTN Timeout\r
77833d0b
RN
834 )\r
835{\r
1436aea4
MK
836 UINTN Delay;\r
837 UINT8 Data;\r
77833d0b
RN
838\r
839 Delay = Timeout / 50;\r
840\r
841 do {\r
842 Data = IoRead8 (KBC_CMD_STS_PORT);\r
843\r
844 //\r
845 // Check keyboard controller status bit 0(output buffer status)\r
846 // & bit5(output buffer for auxiliary device)\r
847 //\r
848 if ((Data & (KBC_OUTB | KBC_AUXB)) == (KBC_OUTB | KBC_AUXB)) {\r
849 break;\r
850 }\r
851\r
852 gBS->Stall (50);\r
853 Delay--;\r
854 } while (Delay != 0);\r
855\r
856 if (Delay == 0) {\r
857 return EFI_TIMEOUT;\r
858 }\r
859\r
860 return EFI_SUCCESS;\r
861}\r