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