source: mainline/uspace/srv/kbd/port/i8042.c@ cecb0789

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since cecb0789 was cecb0789, checked in by Jakub Jermar <jakub@…>, 17 years ago

This is the evil commit. In particular, it does:

  • introduces more powerful pseudo code for userspace IRQ top-half handlers
  • changes the internals of IRQ dispatching
  • simplifies the kernel's i8042 driver
  • adapts the uspace i8042 driver to make use of the new pseudocode
  • breaks all other architectures except ia32
  • breaks almost all existing drivers
  • breaks switching between uspace and kernel drivers
  • Property mode set to 100644
File size: 4.3 KB
Line 
1/*
2 * Copyright (c) 2001-2004 Jakub Jermar
3 * Copyright (c) 2006 Josef Cejka
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * - Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * - Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * - The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30/** @addtogroup kbd_port
31 * @ingroup kbd
32 * @{
33 */
34/** @file
35 * @brief i8042 port driver.
36 */
37
38#include <ipc/ipc.h>
39#include <async.h>
40#include <unistd.h>
41#include <sysinfo.h>
42#include <kbd_port.h>
43#include <kbd.h>
44#include "i8042.h"
45
46/* Interesting bits for status register */
47#define i8042_OUTPUT_FULL 0x1
48#define i8042_INPUT_FULL 0x2
49#define i8042_MOUSE_DATA 0x20
50
51/* Command constants */
52#define i8042_CMD_KBD 0x60
53#define i8042_CMD_MOUSE 0xd4
54
55/* Keyboard cmd byte */
56#define i8042_KBD_IE 0x1
57#define i8042_MOUSE_IE 0x2
58#define i8042_KBD_DISABLE 0x10
59#define i8042_MOUSE_DISABLE 0x20
60#define i8042_KBD_TRANSLATE 0x40
61
62/* Mouse constants */
63#define MOUSE_OUT_INIT 0xf4
64#define MOUSE_ACK 0xfa
65
66static irq_cmd_t i8042_cmds[] = {
67 {
68 .cmd = CMD_PIO_READ_8,
69 .addr = (void *) 0x64,
70 .dstarg = 1
71 },
72 {
73 .cmd = CMD_BTEST,
74 .value = i8042_OUTPUT_FULL,
75 .srcarg = 1,
76 .dstarg = 3
77 },
78 {
79 .cmd = CMD_PREDICATE,
80 .value = 2,
81 .srcarg = 3
82 },
83 {
84 .cmd = CMD_PIO_READ_8,
85 .addr = (void *) 0x60,
86 .dstarg = 2
87 },
88 {
89 .cmd = CMD_ACCEPT
90 }
91};
92
93static irq_code_t i8042_kbd = {
94 sizeof(i8042_cmds) / sizeof(irq_cmd_t),
95 i8042_cmds
96};
97
98static void wait_ready(void) {
99 while (i8042_status_read() & i8042_INPUT_FULL)
100 ;
101}
102
103static void i8042_irq_handler(ipc_callid_t iid, ipc_call_t *call);
104
105int kbd_port_init(void)
106{
107// int i;
108 int mouseenabled = 0;
109
110 async_set_interrupt_received(i8042_irq_handler);
111 iospace_enable(task_get_id(), (void *) i8042_DATA, 5);
112
113 /* Disable kbd, enable mouse */
114 i8042_command_write(i8042_CMD_KBD);
115 wait_ready();
116 i8042_command_write(i8042_CMD_KBD);
117 wait_ready();
118 i8042_data_write(i8042_KBD_DISABLE);
119 wait_ready();
120
121 /* Flush all current IO */
122 while (i8042_status_read() & i8042_OUTPUT_FULL)
123 i8042_data_read();
124
125 /* Initialize mouse */
126/* i8042_command_write(i8042_CMD_MOUSE);
127 wait_ready();
128 i8042_data_write(MOUSE_OUT_INIT);
129 wait_ready();
130
131 int mouseanswer = 0;
132 for (i=0;i < 1000; i++) {
133 int status = i8042_status_read();
134 if (status & i8042_OUTPUT_FULL) {
135 int data = i8042_data_read();
136 if (status & i8042_MOUSE_DATA) {
137 mouseanswer = data;
138 break;
139 }
140 }
141 usleep(1000);
142 }*/
143// if (mouseanswer == MOUSE_ACK) {
144// /* enable mouse */
145// mouseenabled = 1;
146//
147// ipc_register_irq(sysinfo_value("mouse.inr"), sysinfo_value("mouse.devno"), 0, &i8042_kbd);
148// }
149
150 /* Enable kbd */
151 ipc_register_irq(sysinfo_value("kbd.inr"), sysinfo_value("kbd.devno"), 0, &i8042_kbd);
152
153 int newcontrol = i8042_KBD_IE | i8042_KBD_TRANSLATE;
154 if (mouseenabled)
155 newcontrol |= i8042_MOUSE_IE;
156
157 i8042_command_write(i8042_CMD_KBD);
158 wait_ready();
159 i8042_data_write(newcontrol);
160 wait_ready();
161
162 return 0;
163}
164
165static void i8042_irq_handler(ipc_callid_t iid, ipc_call_t *call)
166{
167 int status = IPC_GET_ARG1(*call);
168
169 if ((status & i8042_MOUSE_DATA))
170 return 0;
171
172 int scan_code = IPC_GET_ARG2(*call);
173
174 kbd_push_scancode(scan_code);
175 return 1;
176}
177
178/**
179 * @}
180 */
Note: See TracBrowser for help on using the repository browser.