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