1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18#include <linux/config.h>
19
20#include <linux/spinlock.h>
21#include <linux/sched.h>
22#include <linux/interrupt.h>
23#include <linux/tty.h>
24#include <linux/mm.h>
25#include <linux/signal.h>
26#include <linux/init.h>
27#include <linux/kbd_ll.h>
28#include <linux/delay.h>
29#include <linux/random.h>
30#include <linux/poll.h>
31#include <linux/miscdevice.h>
32#include <linux/slab.h>
33#include <linux/kbd_kern.h>
34#include <linux/vt_kern.h>
35#include <linux/smp_lock.h>
36#include <linux/kd.h>
37#include <linux/pm.h>
38
39#include <asm/keyboard.h>
40#include <asm/bitops.h>
41#include <asm/uaccess.h>
42#include <asm/irq.h>
43#include <asm/system.h>
44
45#include <asm/io.h>
46
47
48
49#include <linux/pc_keyb.h>
50
51
52
53#ifdef CONFIG_MAGIC_SYSRQ
54unsigned char pckbd_sysrq_xlate[128] =
55 "\000\0331234567890-=\177\t"
56 "qwertyuiop[]\r\000as"
57 "dfghjkl;'`\000\\zxcv"
58 "bnm,./\000*\000 \000\201\202\203\204\205"
59 "\206\207\210\211\212\000\000789-456+1"
60 "230\177\000\000\213\214\000\000\000\000\000\000\000\000\000\000"
61 "\r\000/";
62#endif
63
64static void kbd_write_command_w(int data);
65static void kbd_write_output_w(int data);
66#ifdef CONFIG_PSMOUSE
67static void aux_write_ack(int val);
68static void __aux_write_ack(int val);
69static int aux_reconnect = 0;
70#endif
71
72#ifndef kbd_controller_present
73#define kbd_controller_present() 1
74#endif
75static spinlock_t kbd_controller_lock = SPIN_LOCK_UNLOCKED;
76static unsigned char handle_kbd_event(void);
77
78
79static volatile unsigned char reply_expected;
80static volatile unsigned char acknowledge;
81static volatile unsigned char resend;
82
83
84#if defined CONFIG_PSMOUSE
85
86
87
88
89static int __init psaux_init(void);
90
91#define AUX_RECONNECT1 0xaa
92#define AUX_RECONNECT2 0x00
93
94static struct aux_queue *queue;
95static int aux_count;
96
97static unsigned char mouse_reply_expected;
98
99#define AUX_INTS_OFF (KBD_MODE_KCC | KBD_MODE_DISABLE_MOUSE | KBD_MODE_SYS | KBD_MODE_KBD_INT)
100#define AUX_INTS_ON (KBD_MODE_KCC | KBD_MODE_SYS | KBD_MODE_MOUSE_INT | KBD_MODE_KBD_INT)
101
102#define MAX_RETRIES 60
103#endif
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118static void kb_wait(void)
119{
120 unsigned long timeout = KBC_TIMEOUT;
121
122 do {
123
124
125
126
127 unsigned char status = handle_kbd_event();
128
129 if (! (status & KBD_STAT_IBF))
130 return;
131 mdelay(1);
132 timeout--;
133 } while (timeout);
134#ifdef KBD_REPORT_TIMEOUTS
135 printk(KERN_WARNING "Keyboard timed out[1]\n");
136#endif
137}
138
139
140
141
142
143
144
145
146
147
148
149#define E0_KPENTER 96
150#define E0_RCTRL 97
151#define E0_KPSLASH 98
152#define E0_PRSCR 99
153#define E0_RALT 100
154#define E0_BREAK 101
155#define E0_HOME 102
156#define E0_UP 103
157#define E0_PGUP 104
158#define E0_LEFT 105
159#define E0_RIGHT 106
160#define E0_END 107
161#define E0_DOWN 108
162#define E0_PGDN 109
163#define E0_INS 110
164#define E0_DEL 111
165
166#define E1_PAUSE 119
167
168
169
170
171
172
173
174
175#define SC_LIM 89
176
177#define FOCUS_PF1 85
178#define FOCUS_PF2 89
179#define FOCUS_PF3 90
180#define FOCUS_PF4 91
181#define FOCUS_PF5 92
182#define FOCUS_PF6 93
183#define FOCUS_PF7 94
184#define FOCUS_PF8 95
185#define FOCUS_PF9 120
186#define FOCUS_PF10 121
187#define FOCUS_PF11 122
188#define FOCUS_PF12 123
189
190#define JAP_86 124
191
192
193
194
195
196
197#define RGN1 124
198#define RGN2 125
199#define RGN3 126
200#define RGN4 127
201
202static unsigned char high_keys[128 - SC_LIM] = {
203 RGN1, RGN2, RGN3, RGN4, 0, 0, 0,
204 0, 0, 0, 0, 0, 0, 0, 0,
205 0, 0, 0, 0, 0, FOCUS_PF11, 0, FOCUS_PF12,
206 0, 0, 0, FOCUS_PF2, FOCUS_PF9, 0, 0, FOCUS_PF3,
207 FOCUS_PF4, FOCUS_PF5, FOCUS_PF6, FOCUS_PF7,
208 FOCUS_PF8, JAP_86, FOCUS_PF10, 0
209};
210
211
212#define E0_MACRO 112
213
214#define E0_F13 113
215#define E0_F14 114
216#define E0_HELP 115
217#define E0_DO 116
218#define E0_F17 117
219#define E0_KPMINPLUS 118
220
221
222
223
224#define E0_OK 124
225
226
227
228
229
230
231#define E0_MSLW 125
232#define E0_MSRW 126
233#define E0_MSTM 127
234
235static unsigned char e0_keys[128] = {
236 0, 0, 0, 0, 0, 0, 0, 0,
237 0, 0, 0, 0, 0, 0, 0, 0,
238 0, 0, 0, 0, 0, 0, 0, 0,
239 0, 0, 0, 0, E0_KPENTER, E0_RCTRL, 0, 0,
240 0, 0, 0, 0, 0, 0, 0, 0,
241 0, 0, 0, 0, 0, 0, 0, 0,
242 0, 0, 0, 0, 0, E0_KPSLASH, 0, E0_PRSCR,
243 E0_RALT, 0, 0, 0, 0, E0_F13, E0_F14, E0_HELP,
244 E0_DO, E0_F17, 0, 0, 0, 0, E0_BREAK, E0_HOME,
245 E0_UP, E0_PGUP, 0, E0_LEFT, E0_OK, E0_RIGHT, E0_KPMINPLUS, E0_END,
246 E0_DOWN, E0_PGDN, E0_INS, E0_DEL, 0, 0, 0, 0,
247 0, 0, 0, E0_MSLW, E0_MSRW, E0_MSTM, 0, 0,
248 0, 0, 0, 0, 0, 0, 0, 0,
249 0, 0, 0, 0, 0, 0, 0, E0_MACRO,
250 0, 0, 0, 0, 0, 0, 0, 0,
251 0, 0, 0, 0, 0, 0, 0, 0
252};
253
254int pckbd_setkeycode(unsigned int scancode, unsigned int keycode)
255{
256 if (scancode < SC_LIM || scancode > 255 || keycode > 127)
257 return -EINVAL;
258 if (scancode < 128)
259 high_keys[scancode - SC_LIM] = keycode;
260 else
261 e0_keys[scancode - 128] = keycode;
262 return 0;
263}
264
265int pckbd_getkeycode(unsigned int scancode)
266{
267 return
268 (scancode < SC_LIM || scancode > 255) ? -EINVAL :
269 (scancode < 128) ? high_keys[scancode - SC_LIM] :
270 e0_keys[scancode - 128];
271}
272
273static int do_acknowledge(unsigned char scancode)
274{
275 if (reply_expected) {
276
277
278
279
280
281 if (scancode == KBD_REPLY_ACK) {
282 acknowledge = 1;
283 reply_expected = 0;
284 return 0;
285 } else if (scancode == KBD_REPLY_RESEND) {
286 resend = 1;
287 reply_expected = 0;
288 return 0;
289 }
290
291#if 0
292 printk(KERN_DEBUG "keyboard reply expected - got %02x\n",
293 scancode);
294#endif
295 }
296 return 1;
297}
298
299int pckbd_translate(unsigned char scancode, unsigned char *keycode,
300 char raw_mode)
301{
302 static int prev_scancode;
303
304
305 if (scancode == 0xe0 || scancode == 0xe1) {
306 prev_scancode = scancode;
307 return 0;
308 }
309
310
311 if (scancode == 0x00 || scancode == 0xff) {
312 prev_scancode = 0;
313 return 0;
314 }
315
316 scancode &= 0x7f;
317
318 if (prev_scancode) {
319
320
321
322
323 if (prev_scancode != 0xe0) {
324 if (prev_scancode == 0xe1 && scancode == 0x1d) {
325 prev_scancode = 0x100;
326 return 0;
327 } else if (prev_scancode == 0x100 && scancode == 0x45) {
328 *keycode = E1_PAUSE;
329 prev_scancode = 0;
330 } else {
331#ifdef KBD_REPORT_UNKN
332 if (!raw_mode)
333 printk(KERN_INFO "keyboard: unknown e1 escape sequence\n");
334#endif
335 prev_scancode = 0;
336 return 0;
337 }
338 } else {
339 prev_scancode = 0;
340
341
342
343
344
345
346
347
348
349
350
351
352
353 if (scancode == 0x2a || scancode == 0x36)
354 return 0;
355
356 if (e0_keys[scancode])
357 *keycode = e0_keys[scancode];
358 else {
359#ifdef KBD_REPORT_UNKN
360 if (!raw_mode)
361 printk(KERN_INFO "keyboard: unknown scancode e0 %02x\n",
362 scancode);
363#endif
364 return 0;
365 }
366 }
367 } else if (scancode >= SC_LIM) {
368
369
370
371
372
373
374
375
376
377
378 *keycode = high_keys[scancode - SC_LIM];
379
380 if (!*keycode) {
381 if (!raw_mode) {
382#ifdef KBD_REPORT_UNKN
383 printk(KERN_INFO "keyboard: unrecognized scancode (%02x)"
384 " - ignored\n", scancode);
385#endif
386 }
387 return 0;
388 }
389 } else
390 *keycode = scancode;
391 return 1;
392}
393
394char pckbd_unexpected_up(unsigned char keycode)
395{
396
397
398 if (keycode >= SC_LIM || keycode == 85)
399 return 0;
400 else
401 return 0200;
402}
403
404int pckbd_pm_resume(struct pm_dev *dev, pm_request_t rqst, void *data)
405{
406#if defined CONFIG_PSMOUSE
407 unsigned long flags;
408
409 if (rqst == PM_RESUME) {
410 if (queue) {
411 if (aux_count == 0) {
412 spin_lock_irqsave(&kbd_controller_lock, flags);
413
414
415
416
417
418 kbd_write_command(KBD_CCMD_MOUSE_DISABLE);
419
420 kb_wait();
421 kbd_write_command(KBD_CCMD_WRITE_MODE);
422 kb_wait();
423 kbd_write_output(AUX_INTS_OFF);
424 spin_unlock_irqrestore(&kbd_controller_lock, flags);
425 }
426 }
427 }
428#endif
429 return 0;
430}
431
432
433static inline void handle_mouse_event(unsigned char scancode)
434{
435#ifdef CONFIG_PSMOUSE
436 static unsigned char prev_code;
437 if (mouse_reply_expected) {
438 if (scancode == AUX_ACK) {
439 mouse_reply_expected--;
440 return;
441 }
442 mouse_reply_expected = 0;
443 }
444 else if(scancode == AUX_RECONNECT2 && prev_code == AUX_RECONNECT1
445 && aux_reconnect) {
446 printk (KERN_INFO "PS/2 mouse reconnect detected\n");
447 queue->head = queue->tail = 0;
448 __aux_write_ack(AUX_ENABLE_DEV);
449 return;
450 }
451
452 prev_code = scancode;
453 add_mouse_randomness(scancode);
454 if (aux_count) {
455 int head = queue->head;
456
457 queue->buf[head] = scancode;
458 head = (head + 1) & (AUX_BUF_SIZE-1);
459 if (head != queue->tail) {
460 queue->head = head;
461 kill_fasync(&queue->fasync, SIGIO, POLL_IN);
462 wake_up_interruptible(&queue->proc_list);
463 }
464 }
465#endif
466}
467
468static unsigned char kbd_exists = 1;
469
470static inline void handle_keyboard_event(unsigned char scancode)
471{
472#ifdef CONFIG_VT
473 kbd_exists = 1;
474 if (do_acknowledge(scancode))
475 handle_scancode(scancode, !(scancode & 0x80));
476#endif
477 tasklet_schedule(&keyboard_tasklet);
478}
479
480
481
482
483
484
485
486
487static unsigned char handle_kbd_event(void)
488{
489 unsigned char status = kbd_read_status();
490 unsigned int work = 10000;
491
492 while ((--work > 0) && (status & KBD_STAT_OBF)) {
493 unsigned char scancode;
494
495 scancode = kbd_read_input();
496
497
498
499#if 1
500
501 if (!(status & (KBD_STAT_GTO | KBD_STAT_PERR)))
502#endif
503 {
504 if (status & KBD_STAT_MOUSE_OBF)
505 handle_mouse_event(scancode);
506 else
507 handle_keyboard_event(scancode);
508 }
509
510 status = kbd_read_status();
511 }
512
513 if (!work)
514 printk(KERN_ERR "pc_keyb: controller jammed (0x%02X).\n", status);
515
516 return status;
517}
518
519
520static void keyboard_interrupt(int irq, void *dev_id, struct pt_regs *regs)
521{
522#ifdef CONFIG_VT
523 kbd_pt_regs = regs;
524#endif
525
526 spin_lock_irq(&kbd_controller_lock);
527 handle_kbd_event();
528 spin_unlock_irq(&kbd_controller_lock);
529}
530
531
532
533
534
535
536
537
538static int send_data(unsigned char data)
539{
540 int retries = 3;
541
542 do {
543 unsigned long timeout = KBD_TIMEOUT;
544
545 acknowledge = 0;
546 resend = 0;
547 reply_expected = 1;
548 kbd_write_output_w(data);
549 for (;;) {
550 if (acknowledge)
551 return 1;
552 if (resend)
553 break;
554 mdelay(1);
555 if (!--timeout) {
556#ifdef KBD_REPORT_TIMEOUTS
557 printk(KERN_WARNING "keyboard: Timeout - AT keyboard not present?(%02x)\n", data);
558#endif
559 return 0;
560 }
561 }
562 } while (retries-- > 0);
563#ifdef KBD_REPORT_TIMEOUTS
564 printk(KERN_WARNING "keyboard: Too many NACKs -- noisy kbd cable?\n");
565#endif
566 return 0;
567}
568
569void pckbd_leds(unsigned char leds)
570{
571 if (kbd_exists && (!send_data(KBD_CMD_SET_LEDS) || !send_data(leds))) {
572 send_data(KBD_CMD_ENABLE);
573 kbd_exists = 0;
574 }
575}
576
577#define DEFAULT_KEYB_REP_DELAY 250
578#define DEFAULT_KEYB_REP_RATE 30
579
580static struct kbd_repeat kbdrate={
581 DEFAULT_KEYB_REP_DELAY,
582 DEFAULT_KEYB_REP_RATE
583};
584
585static unsigned char parse_kbd_rate(struct kbd_repeat *r)
586{
587 static struct r2v{
588 int rate;
589 unsigned char val;
590 } kbd_rates[]={ {5,0x14},
591 {7,0x10},
592 {10,0x0c},
593 {15,0x08},
594 {20,0x04},
595 {25,0x02},
596 {30,0x00}
597 };
598 static struct d2v{
599 int delay;
600 unsigned char val;
601 } kbd_delays[]={{250,0},
602 {500,1},
603 {750,2},
604 {1000,3}
605 };
606 int rate=0,delay=0;
607 if (r != NULL){
608 int i,new_rate=30,new_delay=250;
609 if (r->rate <= 0)
610 r->rate=kbdrate.rate;
611 if (r->delay <= 0)
612 r->delay=kbdrate.delay;
613 for (i=0; i < sizeof(kbd_rates)/sizeof(struct r2v); i++)
614 if (kbd_rates[i].rate == r->rate){
615 new_rate=kbd_rates[i].rate;
616 rate=kbd_rates[i].val;
617 break;
618 }
619 for (i=0; i < sizeof(kbd_delays)/sizeof(struct d2v); i++)
620 if (kbd_delays[i].delay == r->delay){
621 new_delay=kbd_delays[i].delay;
622 delay=kbd_delays[i].val;
623 break;
624 }
625 r->rate=new_rate;
626 r->delay=new_delay;
627 }
628 return (delay << 5) | rate;
629}
630
631static int write_kbd_rate(unsigned char r)
632{
633 if (!send_data(KBD_CMD_SET_RATE) || !send_data(r)){
634 send_data(KBD_CMD_ENABLE);
635 return 0;
636 }else
637 return 1;
638}
639
640static int pckbd_rate(struct kbd_repeat *rep)
641{
642 if (rep == NULL)
643 return -EINVAL;
644 else{
645 unsigned char r=parse_kbd_rate(rep);
646 struct kbd_repeat old_rep;
647 memcpy(&old_rep,&kbdrate,sizeof(struct kbd_repeat));
648 if (write_kbd_rate(r)){
649 memcpy(&kbdrate,rep,sizeof(struct kbd_repeat));
650 memcpy(rep,&old_rep,sizeof(struct kbd_repeat));
651 return 0;
652 }
653 }
654 return -EIO;
655}
656
657
658
659
660
661
662
663
664
665
666#ifdef __i386__
667 int kbd_startup_reset __initdata = 0;
668#else
669 int kbd_startup_reset __initdata = 1;
670#endif
671
672
673static int __init kbd_reset_setup(char *str)
674{
675 kbd_startup_reset = 1;
676 return 1;
677}
678
679__setup("kbd-reset", kbd_reset_setup);
680
681#define KBD_NO_DATA (-1)
682#define KBD_BAD_DATA (-2)
683
684static int __init kbd_read_data(void)
685{
686 int retval = KBD_NO_DATA;
687 unsigned char status;
688
689 status = kbd_read_status();
690 if (status & KBD_STAT_OBF) {
691 unsigned char data = kbd_read_input();
692
693 retval = data;
694 if (status & (KBD_STAT_GTO | KBD_STAT_PERR))
695 retval = KBD_BAD_DATA;
696 }
697 return retval;
698}
699
700static void __init kbd_clear_input(void)
701{
702 int maxread = 100;
703
704 do {
705 if (kbd_read_data() == KBD_NO_DATA)
706 break;
707 } while (--maxread);
708}
709
710static int __init kbd_wait_for_input(void)
711{
712 long timeout = KBD_INIT_TIMEOUT;
713
714 do {
715 int retval = kbd_read_data();
716 if (retval >= 0)
717 return retval;
718 mdelay(1);
719 } while (--timeout);
720 return -1;
721}
722
723static void kbd_write_command_w(int data)
724{
725 unsigned long flags;
726
727 spin_lock_irqsave(&kbd_controller_lock, flags);
728 kb_wait();
729 kbd_write_command(data);
730 spin_unlock_irqrestore(&kbd_controller_lock, flags);
731}
732
733static void kbd_write_output_w(int data)
734{
735 unsigned long flags;
736
737 spin_lock_irqsave(&kbd_controller_lock, flags);
738 kb_wait();
739 kbd_write_output(data);
740 spin_unlock_irqrestore(&kbd_controller_lock, flags);
741}
742
743#if defined(__alpha__)
744
745
746
747
748
749
750
751static int kbd_write_command_w_and_wait(int data)
752{
753 unsigned long flags;
754 int input;
755
756 spin_lock_irqsave(&kbd_controller_lock, flags);
757 kb_wait();
758 kbd_write_command(data);
759 input = kbd_wait_for_input();
760 spin_unlock_irqrestore(&kbd_controller_lock, flags);
761 return input;
762}
763
764static int kbd_write_output_w_and_wait(int data)
765{
766 unsigned long flags;
767 int input;
768
769 spin_lock_irqsave(&kbd_controller_lock, flags);
770 kb_wait();
771 kbd_write_output(data);
772 input = kbd_wait_for_input();
773 spin_unlock_irqrestore(&kbd_controller_lock, flags);
774 return input;
775}
776#else
777static int kbd_write_command_w_and_wait(int data)
778{
779 kbd_write_command_w(data);
780 return kbd_wait_for_input();
781}
782
783static int kbd_write_output_w_and_wait(int data)
784{
785 kbd_write_output_w(data);
786 return kbd_wait_for_input();
787}
788#endif
789
790#if defined CONFIG_PSMOUSE
791static void kbd_write_cmd(int cmd)
792{
793 unsigned long flags;
794
795 spin_lock_irqsave(&kbd_controller_lock, flags);
796 kb_wait();
797 kbd_write_command(KBD_CCMD_WRITE_MODE);
798 kb_wait();
799 kbd_write_output(cmd);
800 spin_unlock_irqrestore(&kbd_controller_lock, flags);
801}
802#endif
803
804static char * __init initialize_kbd(void)
805{
806 int status;
807
808
809
810
811
812
813 kbd_write_command_w(KBD_CCMD_SELF_TEST);
814 if (kbd_wait_for_input() != 0x55)
815 return "Keyboard failed self test";
816
817
818
819
820
821
822 kbd_write_command_w(KBD_CCMD_KBD_TEST);
823 if (kbd_wait_for_input() != 0x00)
824 return "Keyboard interface failed self test";
825
826
827
828
829 kbd_write_command_w(KBD_CCMD_KBD_ENABLE);
830
831
832
833
834
835
836
837
838
839 do {
840 kbd_write_output_w(KBD_CMD_RESET);
841 status = kbd_wait_for_input();
842 if (status == KBD_REPLY_ACK)
843 break;
844 if (status != KBD_REPLY_RESEND)
845 return "Keyboard reset failed, no ACK";
846 } while (1);
847
848 if (kbd_wait_for_input() != KBD_REPLY_POR)
849 return "Keyboard reset failed, no POR";
850
851
852
853
854
855
856
857 do {
858 kbd_write_output_w(KBD_CMD_DISABLE);
859 status = kbd_wait_for_input();
860 if (status == KBD_REPLY_ACK)
861 break;
862 if (status != KBD_REPLY_RESEND)
863 return "Disable keyboard: no ACK";
864 } while (1);
865
866 kbd_write_command_w(KBD_CCMD_WRITE_MODE);
867 kbd_write_output_w(KBD_MODE_KBD_INT
868 | KBD_MODE_SYS
869 | KBD_MODE_DISABLE_MOUSE
870 | KBD_MODE_KCC);
871
872
873 if (!(kbd_write_command_w_and_wait(KBD_CCMD_READ_MODE) & KBD_MODE_KCC))
874 {
875
876
877
878
879 kbd_write_output_w(0xF0);
880 kbd_wait_for_input();
881 kbd_write_output_w(0x01);
882 kbd_wait_for_input();
883 }
884
885 if (kbd_write_output_w_and_wait(KBD_CMD_ENABLE) != KBD_REPLY_ACK)
886 return "Enable keyboard: no ACK";
887
888
889
890
891 if (kbd_write_output_w_and_wait(KBD_CMD_SET_RATE) != KBD_REPLY_ACK)
892 return "Set rate: no ACK";
893 if (kbd_write_output_w_and_wait(0x00) != KBD_REPLY_ACK)
894 return "Set rate: no 2nd ACK";
895
896 return NULL;
897}
898
899void __init pckbd_init_hw(void)
900{
901 if (!kbd_controller_present()) {
902 kbd_exists = 0;
903 return;
904 }
905
906 kbd_request_region();
907
908
909 kbd_clear_input();
910
911 if (kbd_startup_reset) {
912 char *msg = initialize_kbd();
913 if (msg)
914 printk(KERN_WARNING "initialize_kbd: %s\n", msg);
915 }
916
917#if defined CONFIG_PSMOUSE
918 psaux_init();
919#endif
920
921 kbd_rate = pckbd_rate;
922
923
924 kbd_request_irq(keyboard_interrupt);
925}
926
927#if defined CONFIG_PSMOUSE
928
929static int __init aux_reconnect_setup (char *str)
930{
931 aux_reconnect = 1;
932 return 1;
933}
934
935__setup("psaux-reconnect", aux_reconnect_setup);
936
937
938
939
940static int __init detect_auxiliary_port(void)
941{
942 unsigned long flags;
943 int loops = 10;
944 int retval = 0;
945
946
947 if (aux_device_present == 0xaa)
948 return 1;
949
950 spin_lock_irqsave(&kbd_controller_lock, flags);
951
952
953
954
955
956
957
958
959 kb_wait();
960 kbd_write_command(KBD_CCMD_WRITE_AUX_OBUF);
961
962 kb_wait();
963 kbd_write_output(0x5a);
964
965 do {
966 unsigned char status = kbd_read_status();
967
968 if (status & KBD_STAT_OBF) {
969 (void) kbd_read_input();
970 if (status & KBD_STAT_MOUSE_OBF) {
971 printk(KERN_INFO "Detected PS/2 Mouse Port.\n");
972 retval = 1;
973 }
974 break;
975 }
976 mdelay(1);
977 } while (--loops);
978 spin_unlock_irqrestore(&kbd_controller_lock, flags);
979
980 return retval;
981}
982
983
984
985
986static void aux_write_dev(int val)
987{
988 unsigned long flags;
989
990 spin_lock_irqsave(&kbd_controller_lock, flags);
991 kb_wait();
992 kbd_write_command(KBD_CCMD_WRITE_MOUSE);
993 kb_wait();
994 kbd_write_output(val);
995 spin_unlock_irqrestore(&kbd_controller_lock, flags);
996}
997
998
999
1000
1001static void __aux_write_ack(int val)
1002{
1003 kb_wait();
1004 kbd_write_command(KBD_CCMD_WRITE_MOUSE);
1005 kb_wait();
1006 kbd_write_output(val);
1007
1008 mouse_reply_expected++;
1009 kb_wait();
1010}
1011
1012static void aux_write_ack(int val)
1013{
1014 unsigned long flags;
1015
1016 spin_lock_irqsave(&kbd_controller_lock, flags);
1017 __aux_write_ack(val);
1018 spin_unlock_irqrestore(&kbd_controller_lock, flags);
1019}
1020
1021static unsigned char get_from_queue(void)
1022{
1023 unsigned char result;
1024 unsigned long flags;
1025
1026 spin_lock_irqsave(&kbd_controller_lock, flags);
1027 result = queue->buf[queue->tail];
1028 queue->tail = (queue->tail + 1) & (AUX_BUF_SIZE-1);
1029 spin_unlock_irqrestore(&kbd_controller_lock, flags);
1030 return result;
1031}
1032
1033
1034static inline int queue_empty(void)
1035{
1036 return queue->head == queue->tail;
1037}
1038
1039static int fasync_aux(int fd, struct file *filp, int on)
1040{
1041 int retval;
1042
1043 retval = fasync_helper(fd, filp, on, &queue->fasync);
1044 if (retval < 0)
1045 return retval;
1046 return 0;
1047}
1048
1049
1050
1051
1052
1053#define AUX_DEV ((void *)queue)
1054
1055static int release_aux(struct inode * inode, struct file * file)
1056{
1057 lock_kernel();
1058 fasync_aux(-1, file, 0);
1059 if (--aux_count) {
1060 unlock_kernel();
1061 return 0;
1062 }
1063 kbd_write_cmd(AUX_INTS_OFF);
1064 kbd_write_command_w(KBD_CCMD_MOUSE_DISABLE);
1065 aux_free_irq(AUX_DEV);
1066 unlock_kernel();
1067 return 0;
1068}
1069
1070
1071
1072
1073
1074
1075static int open_aux(struct inode * inode, struct file * file)
1076{
1077 if (aux_count++) {
1078 return 0;
1079 }
1080 queue->head = queue->tail = 0;
1081 if (aux_request_irq(keyboard_interrupt, AUX_DEV)) {
1082 aux_count--;
1083 return -EBUSY;
1084 }
1085 kbd_write_command_w(KBD_CCMD_MOUSE_ENABLE);
1086
1087
1088 aux_write_ack(AUX_ENABLE_DEV);
1089 kbd_write_cmd(AUX_INTS_ON);
1090
1091 mdelay(2);
1092
1093 send_data(KBD_CMD_ENABLE);
1094
1095 return 0;
1096}
1097
1098
1099
1100
1101
1102static ssize_t read_aux(struct file * file, char * buffer,
1103 size_t count, loff_t *ppos)
1104{
1105 DECLARE_WAITQUEUE(wait, current);
1106 ssize_t i = count;
1107 unsigned char c;
1108
1109 if (queue_empty()) {
1110 if (file->f_flags & O_NONBLOCK)
1111 return -EAGAIN;
1112 add_wait_queue(&queue->proc_list, &wait);
1113repeat:
1114 set_current_state(TASK_INTERRUPTIBLE);
1115 if (queue_empty() && !signal_pending(current)) {
1116 schedule();
1117 goto repeat;
1118 }
1119 current->state = TASK_RUNNING;
1120 remove_wait_queue(&queue->proc_list, &wait);
1121 }
1122 while (i > 0 && !queue_empty()) {
1123 c = get_from_queue();
1124 put_user(c, buffer++);
1125 i--;
1126 }
1127 if (count-i) {
1128 file->f_dentry->d_inode->i_atime = CURRENT_TIME;
1129 return count-i;
1130 }
1131 if (signal_pending(current))
1132 return -ERESTARTSYS;
1133 return 0;
1134}
1135
1136
1137
1138
1139
1140static ssize_t write_aux(struct file * file, const char * buffer,
1141 size_t count, loff_t *ppos)
1142{
1143 ssize_t retval = 0;
1144
1145 if (count) {
1146 ssize_t written = 0;
1147
1148 if (count > 32)
1149 count = 32;
1150 do {
1151 char c;
1152 get_user(c, buffer++);
1153 aux_write_dev(c);
1154 written++;
1155 } while (--count);
1156 retval = -EIO;
1157 if (written) {
1158 retval = written;
1159 file->f_dentry->d_inode->i_mtime = CURRENT_TIME;
1160 }
1161 }
1162
1163 return retval;
1164}
1165
1166
1167static unsigned int aux_poll(struct file *file, poll_table * wait)
1168{
1169 poll_wait(file, &queue->proc_list, wait);
1170 if (!queue_empty())
1171 return POLLIN | POLLRDNORM;
1172 return 0;
1173}
1174
1175struct file_operations psaux_fops = {
1176 read: read_aux,
1177 write: write_aux,
1178 poll: aux_poll,
1179 open: open_aux,
1180 release: release_aux,
1181 fasync: fasync_aux,
1182};
1183
1184
1185
1186
1187static struct miscdevice psaux_mouse = {
1188 PSMOUSE_MINOR, "psaux", &psaux_fops
1189};
1190
1191static int __init psaux_init(void)
1192{
1193 int retval;
1194
1195 if (!detect_auxiliary_port())
1196 return -EIO;
1197
1198 if ((retval = misc_register(&psaux_mouse)))
1199 return retval;
1200
1201 queue = (struct aux_queue *) kmalloc(sizeof(*queue), GFP_KERNEL);
1202 if (queue == NULL) {
1203 printk(KERN_ERR "psaux_init(): out of memory\n");
1204 misc_deregister(&psaux_mouse);
1205 return -ENOMEM;
1206 }
1207 memset(queue, 0, sizeof(*queue));
1208 queue->head = queue->tail = 0;
1209 init_waitqueue_head(&queue->proc_list);
1210
1211#ifdef INITIALIZE_MOUSE
1212 kbd_write_command_w(KBD_CCMD_MOUSE_ENABLE);
1213 aux_write_ack(AUX_SET_SAMPLE);
1214 aux_write_ack(100);
1215 aux_write_ack(AUX_SET_RES);
1216 aux_write_ack(3);
1217 aux_write_ack(AUX_SET_SCALE21);
1218#endif
1219 kbd_write_command(KBD_CCMD_MOUSE_DISABLE);
1220 kbd_write_cmd(AUX_INTS_OFF);
1221
1222 return 0;
1223}
1224
1225#endif
1226
1227
1228static int blink_frequency = HZ/2;
1229
1230
1231
1232
1233
1234void panic_blink(void)
1235{
1236 static unsigned long last_jiffie;
1237 static char led;
1238
1239
1240 if (!blink_frequency)
1241 return;
1242 if (jiffies - last_jiffie > blink_frequency) {
1243 led ^= 0x01 | 0x04;
1244 while (kbd_read_status() & KBD_STAT_IBF) mdelay(1);
1245 kbd_write_output(KBD_CMD_SET_LEDS);
1246 mdelay(1);
1247 while (kbd_read_status() & KBD_STAT_IBF) mdelay(1);
1248 mdelay(1);
1249 kbd_write_output(led);
1250 last_jiffie = jiffies;
1251 }
1252}
1253
1254static int __init panicblink_setup(char *str)
1255{
1256 int par;
1257 if (get_option(&str,&par))
1258 blink_frequency = par*(1000/HZ);
1259 return 1;
1260}
1261
1262
1263
1264__setup("panicblink=", panicblink_setup);
1265
1266