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