]> git.proxmox.com Git - mirror_edk2.git/blob - IntelFrameworkModulePkg/Bus/Isa/Ps2MouseDxe/CommPs2.c
5e18d4949f35e87a9cfc8226b9bf695f5faba639
[mirror_edk2.git] / IntelFrameworkModulePkg / Bus / Isa / Ps2MouseDxe / CommPs2.c
1 /*++
2
3 Copyright (c) 2006 - 2007, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
8
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11
12 Abstract:
13
14 PS2 Mouse Communication Interface
15
16
17 --*/
18
19 //
20 // Include common header file for this module.
21 //
22 #include "CommonHeader.h"
23
24 #include "Ps2Mouse.h"
25 #include "CommPs2.h"
26
27 UINT8 SampleRateTbl[MAX_SR] = { 0xa, 0x14, 0x28, 0x3c, 0x50, 0x64, 0xc8 };
28
29 UINT8 ResolutionTbl[MAX_CMR] = { 0, 1, 2, 3 };
30
31 EFI_STATUS
32 KbcSelfTest (
33 IN EFI_ISA_IO_PROTOCOL *IsaIo
34 )
35 /*++
36
37 Routine Description:
38
39 GC_TODO: Add function description
40
41 Arguments:
42
43 IsaIo - GC_TODO: add argument description
44
45 Returns:
46
47 EFI_DEVICE_ERROR - GC_TODO: Add description for return value
48 EFI_SUCCESS - GC_TODO: Add description for return value
49
50 --*/
51 {
52 EFI_STATUS Status;
53 UINT8 Data;
54
55 //
56 // Keyboard controller self test
57 //
58 Status = Out8042Command (IsaIo, SELF_TEST);
59 if (EFI_ERROR (Status)) {
60 return Status;
61 }
62 //
63 // Read return code
64 //
65 Status = In8042Data (IsaIo, &Data);
66 if (EFI_ERROR (Status)) {
67 return Status;
68 }
69
70 if (Data != 0x55) {
71 return EFI_DEVICE_ERROR;
72 }
73 //
74 // Set system flag
75 //
76 Status = Out8042Command (IsaIo, READ_CMD_BYTE);
77 if (EFI_ERROR (Status)) {
78 return Status;
79 }
80
81 Status = In8042Data (IsaIo, &Data);
82 if (EFI_ERROR (Status)) {
83 return Status;
84 }
85
86 Status = Out8042Command (IsaIo, WRITE_CMD_BYTE);
87 if (EFI_ERROR (Status)) {
88 return Status;
89 }
90
91 Data |= CMD_SYS_FLAG;
92 Status = Out8042Data (IsaIo, Data);
93 if (EFI_ERROR (Status)) {
94 return Status;
95 }
96
97 return EFI_SUCCESS;
98 }
99
100 EFI_STATUS
101 KbcEnableAux (
102 IN EFI_ISA_IO_PROTOCOL *IsaIo
103 )
104 /*++
105
106 Routine Description:
107
108 GC_TODO: Add function description
109
110 Arguments:
111
112 IsaIo - GC_TODO: add argument description
113
114 Returns:
115
116 GC_TODO: add return values
117
118 --*/
119 {
120 //
121 // Send 8042 enable mouse command
122 //
123 return Out8042Command (IsaIo, ENABLE_AUX);
124 }
125
126 EFI_STATUS
127 KbcDisableAux (
128 IN EFI_ISA_IO_PROTOCOL *IsaIo
129 )
130 /*++
131
132 Routine Description:
133
134 GC_TODO: Add function description
135
136 Arguments:
137
138 IsaIo - GC_TODO: add argument description
139
140 Returns:
141
142 GC_TODO: add return values
143
144 --*/
145 {
146 //
147 // Send 8042 disable mouse command
148 //
149 return Out8042Command (IsaIo, DISABLE_AUX);
150 }
151
152 EFI_STATUS
153 KbcEnableKb (
154 IN EFI_ISA_IO_PROTOCOL *IsaIo
155 )
156 /*++
157
158 Routine Description:
159
160 GC_TODO: Add function description
161
162 Arguments:
163
164 IsaIo - GC_TODO: add argument description
165
166 Returns:
167
168 GC_TODO: add return values
169
170 --*/
171 {
172 //
173 // Send 8042 enable keyboard command
174 //
175 return Out8042Command (IsaIo, ENABLE_KB);
176 }
177
178 EFI_STATUS
179 KbcDisableKb (
180 IN EFI_ISA_IO_PROTOCOL *IsaIo
181 )
182 /*++
183
184 Routine Description:
185
186 GC_TODO: Add function description
187
188 Arguments:
189
190 IsaIo - GC_TODO: add argument description
191
192 Returns:
193
194 GC_TODO: add return values
195
196 --*/
197 {
198 //
199 // Send 8042 disable keyboard command
200 //
201 return Out8042Command (IsaIo, DISABLE_KB);
202 }
203
204 EFI_STATUS
205 CheckKbStatus (
206 IN EFI_ISA_IO_PROTOCOL *IsaIo,
207 OUT BOOLEAN *KeyboardEnable
208 )
209 /*++
210
211 Routine Description:
212
213 GC_TODO: Add function description
214
215 Arguments:
216
217 IsaIo - GC_TODO: add argument description
218 KeyboardEnable - GC_TODO: add argument description
219
220 Returns:
221
222 EFI_SUCCESS - GC_TODO: Add description for return value
223
224 --*/
225 {
226 EFI_STATUS Status;
227 UINT8 Data;
228
229 //
230 // Send command to read KBC command byte
231 //
232 Status = Out8042Command (IsaIo, READ_CMD_BYTE);
233 if (EFI_ERROR (Status)) {
234 return Status;
235 }
236
237 Status = In8042Data (IsaIo, &Data);
238 if (EFI_ERROR (Status)) {
239 return Status;
240 }
241 //
242 // Check keyboard enable or not
243 //
244 if ((Data & CMD_KB_STS) == CMD_KB_DIS) {
245 *KeyboardEnable = FALSE;
246 } else {
247 *KeyboardEnable = TRUE;
248 }
249
250 return EFI_SUCCESS;
251 }
252
253 EFI_STATUS
254 PS2MouseReset (
255 IN EFI_ISA_IO_PROTOCOL *IsaIo
256 )
257 /*++
258
259 Routine Description:
260
261 GC_TODO: Add function description
262
263 Arguments:
264
265 IsaIo - GC_TODO: add argument description
266
267 Returns:
268
269 EFI_DEVICE_ERROR - GC_TODO: Add description for return value
270 EFI_DEVICE_ERROR - GC_TODO: Add description for return value
271 EFI_SUCCESS - GC_TODO: Add description for return value
272
273 --*/
274 {
275 EFI_STATUS Status;
276 UINT8 Data;
277
278 Status = Out8042AuxCommand (IsaIo, RESET_CMD, FALSE);
279 if (EFI_ERROR (Status)) {
280 return Status;
281 }
282
283 Status = In8042AuxData (IsaIo, &Data);
284 if (EFI_ERROR (Status)) {
285 return Status;
286 }
287 //
288 // Check BAT Complete Code
289 //
290 if (Data != PS2MOUSE_BAT1) {
291 return EFI_DEVICE_ERROR;
292 }
293
294 Status = In8042AuxData (IsaIo, &Data);
295 if (EFI_ERROR (Status)) {
296 return Status;
297 }
298 //
299 // Check BAT Complete Code
300 //
301 if (Data != PS2MOUSE_BAT2) {
302 return EFI_DEVICE_ERROR;
303 }
304
305 return EFI_SUCCESS;
306 }
307
308 EFI_STATUS
309 PS2MouseSetSampleRate (
310 IN EFI_ISA_IO_PROTOCOL *IsaIo,
311 IN MOUSE_SR SampleRate
312 )
313 /*++
314
315 Routine Description:
316
317 GC_TODO: Add function description
318
319 Arguments:
320
321 IsaIo - GC_TODO: add argument description
322 SampleRate - GC_TODO: add argument description
323
324 Returns:
325
326 GC_TODO: add return values
327
328 --*/
329 {
330 EFI_STATUS Status;
331
332 //
333 // Send auxiliary command to set mouse sample rate
334 //
335 Status = Out8042AuxCommand (IsaIo, SETSR_CMD, FALSE);
336 if (EFI_ERROR (Status)) {
337 return Status;
338 }
339
340 Status = Out8042AuxData (IsaIo, SampleRateTbl[SampleRate]);
341
342 return Status;
343 }
344
345 EFI_STATUS
346 PS2MouseSetResolution (
347 IN EFI_ISA_IO_PROTOCOL *IsaIo,
348 IN MOUSE_RE Resolution
349 )
350 /*++
351
352 Routine Description:
353
354 GC_TODO: Add function description
355
356 Arguments:
357
358 IsaIo - GC_TODO: add argument description
359 Resolution - GC_TODO: add argument description
360
361 Returns:
362
363 GC_TODO: add return values
364
365 --*/
366 {
367 EFI_STATUS Status;
368
369 //
370 // Send auxiliary command to set mouse resolution
371 //
372 Status = Out8042AuxCommand (IsaIo, SETRE_CMD, FALSE);
373 if (EFI_ERROR (Status)) {
374 return Status;
375 }
376
377 Status = Out8042AuxData (IsaIo, ResolutionTbl[Resolution]);
378
379 return Status;
380 }
381
382 EFI_STATUS
383 PS2MouseSetScaling (
384 IN EFI_ISA_IO_PROTOCOL *IsaIo,
385 IN MOUSE_SF Scaling
386 )
387 /*++
388
389 Routine Description:
390
391 GC_TODO: Add function description
392
393 Arguments:
394
395 IsaIo - GC_TODO: add argument description
396 Scaling - GC_TODO: add argument description
397
398 Returns:
399
400 GC_TODO: add return values
401
402 --*/
403 {
404 UINT8 Command;
405
406 Command = (UINT8) (Scaling == SF1 ? SETSF1_CMD : SETSF2_CMD);
407
408 //
409 // Send auxiliary command to set mouse scaling data
410 //
411 return Out8042AuxCommand (IsaIo, Command, FALSE);
412 }
413
414 EFI_STATUS
415 PS2MouseEnable (
416 IN EFI_ISA_IO_PROTOCOL *IsaIo
417 )
418 /*++
419
420 Routine Description:
421
422 GC_TODO: Add function description
423
424 Arguments:
425
426 IsaIo - GC_TODO: add argument description
427
428 Returns:
429
430 GC_TODO: add return values
431
432 --*/
433 {
434 //
435 // Send auxiliary command to enable mouse
436 //
437 return Out8042AuxCommand (IsaIo, ENABLE_CMD, FALSE);
438 }
439
440 EFI_STATUS
441 PS2MouseGetPacket (
442 PS2_MOUSE_DEV *MouseDev
443 )
444 /*++
445
446 Routine Description:
447
448 Get mouse packet . Only care first 3 bytes
449
450 Arguments:
451
452 MouseDev - Pointer of PS2 Mouse Private Data Structure
453
454 Returns:
455
456 EFI_NOT_READY - Mouse Device not ready to input data packet, or some error happened during getting the packet
457 EFI_SUCCESS - The data packet is gotten successfully.
458
459 --*/
460 {
461 EFI_STATUS Status;
462 BOOLEAN KeyboardEnable;
463 UINT8 Packet[PS2_PACKET_LENGTH];
464 UINT8 Data;
465 UINTN Count;
466 UINTN State;
467 INT16 RelativeMovementX;
468 INT16 RelativeMovementY;
469 BOOLEAN LButton;
470 BOOLEAN RButton;
471
472 KeyboardEnable = FALSE;
473 Count = 1;
474 State = PS2_READ_BYTE_ONE;
475
476 //
477 // State machine to get mouse packet
478 //
479 while (1) {
480
481 switch (State) {
482 case PS2_READ_BYTE_ONE:
483 //
484 // Read mouse first byte data, if failed, immediately return
485 //
486 KbcDisableAux (MouseDev->IsaIo);
487 Status = PS2MouseRead (MouseDev->IsaIo, &Data, &Count, State);
488 if (EFI_ERROR (Status)) {
489 KbcEnableAux (MouseDev->IsaIo);
490 return EFI_NOT_READY;
491 }
492
493 if (Count != 1) {
494 KbcEnableAux (MouseDev->IsaIo);
495 return EFI_NOT_READY;
496 }
497
498 if (IS_PS2_SYNC_BYTE (Data)) {
499 Packet[0] = Data;
500 State = PS2_READ_DATA_BYTE;
501
502 CheckKbStatus (MouseDev->IsaIo, &KeyboardEnable);
503 KbcDisableKb (MouseDev->IsaIo);
504 KbcEnableAux (MouseDev->IsaIo);
505 }
506 break;
507
508 case PS2_READ_DATA_BYTE:
509 Count = 2;
510 Status = PS2MouseRead (MouseDev->IsaIo, (Packet + 1), &Count, State);
511 if (EFI_ERROR (Status)) {
512 if (KeyboardEnable) {
513 KbcEnableKb (MouseDev->IsaIo);
514 }
515
516 return EFI_NOT_READY;
517 }
518
519 if (Count != 2) {
520 if (KeyboardEnable) {
521 KbcEnableKb (MouseDev->IsaIo);
522 }
523
524 return EFI_NOT_READY;
525 }
526
527 State = PS2_PROCESS_PACKET;
528 break;
529
530 case PS2_PROCESS_PACKET:
531 if (KeyboardEnable) {
532 KbcEnableKb (MouseDev->IsaIo);
533 }
534 //
535 // Decode the packet
536 //
537 RelativeMovementX = Packet[1];
538 RelativeMovementY = Packet[2];
539 //
540 // Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0
541 // Byte 0 | Y overflow | X overflow | Y sign bit | X sign bit | Always 1 | Middle Btn | Right Btn | Left Btn
542 // Byte 1 | 8 bit X Movement
543 // Byte 2 | 8 bit Y Movement
544 //
545 // 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.
546 // Y sign bit + 8 bit Y Movement : Same as X sign bit + 8 bit X Movement.
547 //
548 //
549 // First, Clear X and Y high 8 bits
550 //
551 RelativeMovementX = (INT16) (RelativeMovementX & 0xFF);
552 RelativeMovementY = (INT16) (RelativeMovementY & 0xFF);
553 //
554 // Second, if the 9-bit signed twos complement integer is negative, set the high 8 bit 0xff
555 //
556 if ((Packet[0] & 0x10) != 0) {
557 RelativeMovementX = (INT16) (RelativeMovementX | 0xFF00);
558 }
559 if ((Packet[0] & 0x20) != 0) {
560 RelativeMovementY = (INT16) (RelativeMovementY | 0xFF00);
561 }
562
563
564 RButton = (UINT8) (Packet[0] & 0x2);
565 LButton = (UINT8) (Packet[0] & 0x1);
566
567 //
568 // Update mouse state
569 //
570 MouseDev->State.RelativeMovementX += RelativeMovementX;
571 MouseDev->State.RelativeMovementY -= RelativeMovementY;
572 MouseDev->State.RightButton = (UINT8) (RButton ? TRUE : FALSE);
573 MouseDev->State.LeftButton = (UINT8) (LButton ? TRUE : FALSE);
574 MouseDev->StateChanged = TRUE;
575
576 return EFI_SUCCESS;
577 }
578 }
579 }
580
581 EFI_STATUS
582 PS2MouseRead (
583 IN EFI_ISA_IO_PROTOCOL *IsaIo,
584 OUT VOID *Buffer,
585 IN OUT UINTN *BufSize,
586 IN UINTN State
587 )
588 /*++
589
590 Routine Description:
591
592 GC_TODO: Add function description
593
594 Arguments:
595
596 IsaIo - GC_TODO: add argument description
597 Buffer - GC_TODO: add argument description
598 BufSize - GC_TODO: add argument description
599 State - GC_TODO: add argument description
600
601 Returns:
602
603 GC_TODO: add return values
604
605 --*/
606 {
607 EFI_STATUS Status;
608 UINTN BytesRead;
609
610 Status = EFI_SUCCESS;
611 BytesRead = 0;
612
613 if (State == PS2_READ_BYTE_ONE) {
614 //
615 // Check input for mouse
616 //
617 Status = CheckForInput (IsaIo);
618
619 if (EFI_ERROR (Status)) {
620 return Status;
621 }
622 }
623
624 while (BytesRead < *BufSize) {
625
626 Status = WaitOutputFull (IsaIo, TIMEOUT);
627 if (EFI_ERROR (Status)) {
628 break;
629 }
630
631 IsaIo->Io.Read (IsaIo, EfiIsaIoWidthUint8, KBC_DATA_PORT, 1, Buffer);
632
633 BytesRead++;
634 Buffer = (UINT8 *) Buffer + 1;
635 }
636 //
637 // Verify the correct number of bytes read
638 //
639 if (BytesRead == 0 || BytesRead != *BufSize) {
640 Status = EFI_NOT_FOUND;
641 }
642
643 *BufSize = BytesRead;
644 return Status;
645 }
646 //
647 // 8042 I/O function
648 //
649 EFI_STATUS
650 Out8042Command (
651 IN EFI_ISA_IO_PROTOCOL *IsaIo,
652 IN UINT8 Command
653 )
654 /*++
655
656 Routine Description:
657
658 GC_TODO: Add function description
659
660 Arguments:
661
662 IsaIo - GC_TODO: add argument description
663 Command - GC_TODO: add argument description
664
665 Returns:
666
667 EFI_SUCCESS - GC_TODO: Add description for return value
668
669 --*/
670 {
671 EFI_STATUS Status;
672 UINT8 Data;
673
674 //
675 // Wait keyboard controller input buffer empty
676 //
677 Status = WaitInputEmpty (IsaIo, TIMEOUT);
678 if (EFI_ERROR (Status)) {
679 return Status;
680 }
681 //
682 // Send command
683 //
684 Data = Command;
685 IsaIo->Io.Write (IsaIo, EfiIsaIoWidthUint8, KBC_CMD_STS_PORT, 1, &Data);
686
687 Status = WaitInputEmpty (IsaIo, TIMEOUT);
688 if (EFI_ERROR (Status)) {
689 return Status;
690 }
691
692 return EFI_SUCCESS;
693 }
694
695 EFI_STATUS
696 Out8042Data (
697 IN EFI_ISA_IO_PROTOCOL *IsaIo,
698 IN UINT8 Data
699 )
700 /*++
701
702 Routine Description:
703
704 GC_TODO: Add function description
705
706 Arguments:
707
708 IsaIo - GC_TODO: add argument description
709 Data - GC_TODO: add argument description
710
711 Returns:
712
713 EFI_SUCCESS - GC_TODO: Add description for return value
714
715 --*/
716 {
717 EFI_STATUS Status;
718 UINT8 temp;
719 //
720 // Wait keyboard controller input buffer empty
721 //
722 Status = WaitInputEmpty (IsaIo, TIMEOUT);
723 if (EFI_ERROR (Status)) {
724 return Status;
725 }
726
727 temp = Data;
728 IsaIo->Io.Write (IsaIo, EfiIsaIoWidthUint8, KBC_DATA_PORT, 1, &temp);
729
730 Status = WaitInputEmpty (IsaIo, TIMEOUT);
731 if (EFI_ERROR (Status)) {
732 return Status;
733 }
734
735 return EFI_SUCCESS;
736 }
737
738 EFI_STATUS
739 In8042Data (
740 IN EFI_ISA_IO_PROTOCOL *IsaIo,
741 IN OUT UINT8 *Data
742 )
743 /*++
744
745 Routine Description:
746
747 GC_TODO: Add function description
748
749 Arguments:
750
751 IsaIo - GC_TODO: add argument description
752 Data - GC_TODO: add argument description
753
754 Returns:
755
756 EFI_TIMEOUT - GC_TODO: Add description for return value
757 EFI_SUCCESS - GC_TODO: Add description for return value
758
759 --*/
760 {
761 UINTN Delay;
762 UINT8 temp;
763
764 Delay = TIMEOUT / 50;
765
766 do {
767 IsaIo->Io.Read (IsaIo, EfiIsaIoWidthUint8, KBC_CMD_STS_PORT, 1, &temp);
768
769 //
770 // Check keyboard controller status bit 0(output buffer status)
771 //
772 if ((temp & KBC_OUTB) == KBC_OUTB) {
773 break;
774 }
775
776 gBS->Stall (50);
777 Delay--;
778 } while (Delay);
779
780 if (Delay == 0) {
781 return EFI_TIMEOUT;
782 }
783
784 IsaIo->Io.Read (IsaIo, EfiIsaIoWidthUint8, KBC_DATA_PORT, 1, Data);
785
786 return EFI_SUCCESS;
787 }
788
789 EFI_STATUS
790 Out8042AuxCommand (
791 IN EFI_ISA_IO_PROTOCOL *IsaIo,
792 IN UINT8 Command,
793 IN BOOLEAN Resend
794 )
795 /*++
796
797 Routine Description:
798
799 GC_TODO: Add function description
800
801 Arguments:
802
803 IsaIo - GC_TODO: add argument description
804 Command - GC_TODO: add argument description
805 Resend - GC_TODO: add argument description
806
807 Returns:
808
809 EFI_SUCCESS - GC_TODO: Add description for return value
810 EFI_DEVICE_ERROR - GC_TODO: Add description for return value
811 EFI_DEVICE_ERROR - GC_TODO: Add description for return value
812 EFI_SUCCESS - GC_TODO: Add description for return value
813
814 --*/
815 {
816 EFI_STATUS Status;
817 UINT8 Data;
818
819 //
820 // Wait keyboard controller input buffer empty
821 //
822 Status = WaitInputEmpty (IsaIo, TIMEOUT);
823 if (EFI_ERROR (Status)) {
824 return Status;
825 }
826 //
827 // Send write to auxiliary device command
828 //
829 Data = WRITE_AUX_DEV;
830 IsaIo->Io.Write (IsaIo, EfiIsaIoWidthUint8, KBC_CMD_STS_PORT, 1, &Data);
831
832 Status = WaitInputEmpty (IsaIo, TIMEOUT);
833 if (EFI_ERROR (Status)) {
834 return Status;
835 }
836 //
837 // Send auxiliary device command
838 //
839 IsaIo->Io.Write (IsaIo, EfiIsaIoWidthUint8, KBC_DATA_PORT, 1, &Command);
840
841 //
842 // Read return code
843 //
844 Status = In8042AuxData (IsaIo, &Data);
845 if (EFI_ERROR (Status)) {
846 return Status;
847 }
848
849 if (Data == PS2_ACK) {
850 //
851 // Receive mouse acknowledge, command send success
852 //
853 return EFI_SUCCESS;
854
855 } else if (Resend) {
856 //
857 // Resend fail
858 //
859 return EFI_DEVICE_ERROR;
860
861 } else if (Data == PS2_RESEND) {
862 //
863 // Resend command
864 //
865 Status = Out8042AuxCommand (IsaIo, Command, TRUE);
866 if (EFI_ERROR (Status)) {
867 return Status;
868 }
869
870 } else {
871 //
872 // Invalid return code
873 //
874 return EFI_DEVICE_ERROR;
875
876 }
877
878 return EFI_SUCCESS;
879 }
880
881 EFI_STATUS
882 Out8042AuxData (
883 IN EFI_ISA_IO_PROTOCOL *IsaIo,
884 IN UINT8 Data
885 )
886 /*++
887
888 Routine Description:
889
890 GC_TODO: Add function description
891
892 Arguments:
893
894 IsaIo - GC_TODO: add argument description
895 Data - GC_TODO: add argument description
896
897 Returns:
898
899 EFI_SUCCESS - GC_TODO: Add description for return value
900
901 --*/
902 {
903 EFI_STATUS Status;
904 UINT8 Temp;
905 //
906 // Wait keyboard controller input buffer empty
907 //
908 Status = WaitInputEmpty (IsaIo, TIMEOUT);
909 if (EFI_ERROR (Status)) {
910 return Status;
911 }
912 //
913 // Send write to auxiliary device command
914 //
915 Temp = WRITE_AUX_DEV;
916 IsaIo->Io.Write (IsaIo, EfiIsaIoWidthUint8, KBC_CMD_STS_PORT, 1, &Temp);
917
918 Status = WaitInputEmpty (IsaIo, TIMEOUT);
919 if (EFI_ERROR (Status)) {
920 return Status;
921 }
922
923 Temp = Data;
924 IsaIo->Io.Write (IsaIo, EfiIsaIoWidthUint8, KBC_DATA_PORT, 1, &Temp);
925
926 Status = WaitInputEmpty (IsaIo, TIMEOUT);
927 if (EFI_ERROR (Status)) {
928 return Status;
929 }
930
931 return EFI_SUCCESS;
932 }
933
934 EFI_STATUS
935 In8042AuxData (
936 IN EFI_ISA_IO_PROTOCOL *IsaIo,
937 IN OUT UINT8 *Data
938 )
939 /*++
940
941 Routine Description:
942
943 GC_TODO: Add function description
944
945 Arguments:
946
947 IsaIo - GC_TODO: add argument description
948 Data - GC_TODO: add argument description
949
950 Returns:
951
952 EFI_SUCCESS - GC_TODO: Add description for return value
953
954 --*/
955 {
956 EFI_STATUS Status;
957
958 //
959 // wait for output data
960 //
961 Status = WaitOutputFull (IsaIo, BAT_TIMEOUT);
962 if (EFI_ERROR (Status)) {
963 return Status;
964 }
965
966 IsaIo->Io.Read (IsaIo, EfiIsaIoWidthUint8, KBC_DATA_PORT, 1, Data);
967
968 return EFI_SUCCESS;
969 }
970
971 EFI_STATUS
972 CheckForInput (
973 IN EFI_ISA_IO_PROTOCOL *IsaIo
974 )
975 /*++
976
977 Routine Description:
978
979 GC_TODO: Add function description
980
981 Arguments:
982
983 IsaIo - GC_TODO: add argument description
984
985 Returns:
986
987 EFI_NOT_READY - GC_TODO: Add description for return value
988 EFI_SUCCESS - GC_TODO: Add description for return value
989
990 --*/
991 {
992 UINT8 Data;
993
994 IsaIo->Io.Read (IsaIo, EfiIsaIoWidthUint8, KBC_CMD_STS_PORT, 1, &Data);
995
996 //
997 // Check keyboard controller status, if it is output buffer full and for auxiliary device
998 //
999 if ((Data & (KBC_OUTB | KBC_AUXB)) != (KBC_OUTB | KBC_AUXB)) {
1000 return EFI_NOT_READY;
1001 }
1002
1003 return EFI_SUCCESS;
1004 }
1005
1006 EFI_STATUS
1007 WaitInputEmpty (
1008 IN EFI_ISA_IO_PROTOCOL *IsaIo,
1009 IN UINTN Timeout
1010 )
1011 /*++
1012
1013 Routine Description:
1014
1015 GC_TODO: Add function description
1016
1017 Arguments:
1018
1019 IsaIo - GC_TODO: add argument description
1020 Timeout - GC_TODO: add argument description
1021
1022 Returns:
1023
1024 EFI_TIMEOUT - GC_TODO: Add description for return value
1025 EFI_SUCCESS - GC_TODO: Add description for return value
1026
1027 --*/
1028 {
1029 UINTN Delay;
1030 UINT8 Data;
1031
1032 Delay = Timeout / 50;
1033
1034 do {
1035 IsaIo->Io.Read (IsaIo, EfiIsaIoWidthUint8, KBC_CMD_STS_PORT, 1, &Data);
1036
1037 //
1038 // Check keyboard controller status bit 1(input buffer status)
1039 //
1040 if ((Data & KBC_INPB) == 0) {
1041 break;
1042 }
1043
1044 gBS->Stall (50);
1045 Delay--;
1046 } while (Delay);
1047
1048 if (Delay == 0) {
1049 return EFI_TIMEOUT;
1050 }
1051
1052 return EFI_SUCCESS;
1053 }
1054
1055 EFI_STATUS
1056 WaitOutputFull (
1057 IN EFI_ISA_IO_PROTOCOL *IsaIo,
1058 IN UINTN Timeout
1059 )
1060 /*++
1061
1062 Routine Description:
1063
1064 GC_TODO: Add function description
1065
1066 Arguments:
1067
1068 IsaIo - GC_TODO: add argument description
1069 Timeout - GC_TODO: add argument description
1070
1071 Returns:
1072
1073 EFI_TIMEOUT - GC_TODO: Add description for return value
1074 EFI_SUCCESS - GC_TODO: Add description for return value
1075
1076 --*/
1077 {
1078 UINTN Delay;
1079 UINT8 Data;
1080
1081 Delay = Timeout / 50;
1082
1083 do {
1084 IsaIo->Io.Read (IsaIo, EfiIsaIoWidthUint8, KBC_CMD_STS_PORT, 1, &Data);
1085
1086 //
1087 // Check keyboard controller status bit 0(output buffer status)
1088 // & bit5(output buffer for auxiliary device)
1089 //
1090 if ((Data & (KBC_OUTB | KBC_AUXB)) == (KBC_OUTB | KBC_AUXB)) {
1091 break;
1092 }
1093
1094 gBS->Stall (50);
1095 Delay--;
1096 } while (Delay);
1097
1098 if (Delay == 0) {
1099 return EFI_TIMEOUT;
1100 }
1101
1102 return EFI_SUCCESS;
1103 }