Deleted Added
full compact
atkbdc.c (161969) atkbdc.c (207354)
1/*-
2 * Copyright (c) 1996-1999
3 * Kazutaka YOKOTA (yokota@zodiac.mech.utsunomiya-u.ac.jp)
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 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. The name of the author may not be used to endorse or promote
15 * products derived from this software without specific prior written
16 * permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 *
30 * from kbdio.c,v 1.13 1998/09/25 11:55:46 yokota Exp
31 */
32
33#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 1996-1999
3 * Kazutaka YOKOTA (yokota@zodiac.mech.utsunomiya-u.ac.jp)
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 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. The name of the author may not be used to endorse or promote
15 * products derived from this software without specific prior written
16 * permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 *
30 * from kbdio.c,v 1.13 1998/09/25 11:55:46 yokota Exp
31 */
32
33#include <sys/cdefs.h>
34__FBSDID("$FreeBSD: head/sys/dev/atkbdc/atkbdc.c 161969 2006-09-04 00:19:31Z dwhite $");
34__FBSDID("$FreeBSD: head/sys/dev/atkbdc/atkbdc.c 207354 2010-04-29 06:16:00Z sobomax $");
35
36#include "opt_kbd.h"
37
38#include <sys/param.h>
39#include <sys/systm.h>
40#include <sys/bus.h>
41#include <sys/malloc.h>
42#include <sys/syslog.h>
43#include <machine/bus.h>
44#include <machine/resource.h>
45#include <sys/rman.h>
46
35
36#include "opt_kbd.h"
37
38#include <sys/param.h>
39#include <sys/systm.h>
40#include <sys/bus.h>
41#include <sys/malloc.h>
42#include <sys/syslog.h>
43#include <machine/bus.h>
44#include <machine/resource.h>
45#include <sys/rman.h>
46
47#if defined(__amd64__)
48#include <machine/clock.h>
49#endif
50
47#include <dev/atkbdc/atkbdcreg.h>
48
49#ifdef __sparc64__
50#include <dev/ofw/openfirm.h>
51#include <machine/bus_private.h>
52#include <machine/ofw_machdep.h>
53#else
54#include <isa/isareg.h>
55#endif
56
57/* constants */
58
59#define MAXKBDC 1 /* XXX */
60
61/* macros */
62
63#ifndef MAX
64#define MAX(x, y) ((x) > (y) ? (x) : (y))
65#endif
66
67#define kbdcp(p) ((atkbdc_softc_t *)(p))
68#define nextq(i) (((i) + 1) % KBDQ_BUFSIZE)
69#define availq(q) ((q)->head != (q)->tail)
70#if KBDIO_DEBUG >= 2
71#define emptyq(q) ((q)->tail = (q)->head = (q)->qcount = 0)
72#else
73#define emptyq(q) ((q)->tail = (q)->head = 0)
74#endif
75
76#define read_data(k) (bus_space_read_1((k)->iot, (k)->ioh0, 0))
77#define read_status(k) (bus_space_read_1((k)->iot, (k)->ioh1, 0))
78#define write_data(k, d) \
79 (bus_space_write_1((k)->iot, (k)->ioh0, 0, (d)))
80#define write_command(k, d) \
81 (bus_space_write_1((k)->iot, (k)->ioh1, 0, (d)))
82
83/* local variables */
84
85/*
86 * We always need at least one copy of the kbdc_softc struct for the
87 * low-level console. As the low-level console accesses the keyboard
88 * controller before kbdc, and all other devices, is probed, we
89 * statically allocate one entry. XXX
90 */
91static atkbdc_softc_t default_kbdc;
92static atkbdc_softc_t *atkbdc_softc[MAXKBDC] = { &default_kbdc };
93
94static int verbose = KBDIO_DEBUG;
95
96#ifdef __sparc64__
97static struct bus_space_tag atkbdc_bst_store[MAXKBDC];
98#endif
99
100/* function prototypes */
101
102static int atkbdc_setup(atkbdc_softc_t *sc, bus_space_tag_t tag,
103 bus_space_handle_t h0, bus_space_handle_t h1);
104static int addq(kqueue *q, int c);
105static int removeq(kqueue *q);
106static int wait_while_controller_busy(atkbdc_softc_t *kbdc);
107static int wait_for_data(atkbdc_softc_t *kbdc);
108static int wait_for_kbd_data(atkbdc_softc_t *kbdc);
109static int wait_for_kbd_ack(atkbdc_softc_t *kbdc);
110static int wait_for_aux_data(atkbdc_softc_t *kbdc);
111static int wait_for_aux_ack(atkbdc_softc_t *kbdc);
112
113atkbdc_softc_t
114*atkbdc_get_softc(int unit)
115{
116 atkbdc_softc_t *sc;
117
118 if (unit >= sizeof(atkbdc_softc)/sizeof(atkbdc_softc[0]))
119 return NULL;
120 sc = atkbdc_softc[unit];
121 if (sc == NULL) {
122 sc = atkbdc_softc[unit]
123 = malloc(sizeof(*sc), M_DEVBUF, M_NOWAIT | M_ZERO);
124 if (sc == NULL)
125 return NULL;
126 }
127 return sc;
128}
129
130int
131atkbdc_probe_unit(int unit, struct resource *port0, struct resource *port1)
132{
133 if (rman_get_start(port0) <= 0)
134 return ENXIO;
135 if (rman_get_start(port1) <= 0)
136 return ENXIO;
137 return 0;
138}
139
140int
141atkbdc_attach_unit(int unit, atkbdc_softc_t *sc, struct resource *port0,
142 struct resource *port1)
143{
144 return atkbdc_setup(sc, rman_get_bustag(port0),
145 rman_get_bushandle(port0),
146 rman_get_bushandle(port1));
147}
148
149/* the backdoor to the keyboard controller! XXX */
150int
151atkbdc_configure(void)
152{
153 bus_space_tag_t tag;
154 bus_space_handle_t h0;
155 bus_space_handle_t h1;
51#include <dev/atkbdc/atkbdcreg.h>
52
53#ifdef __sparc64__
54#include <dev/ofw/openfirm.h>
55#include <machine/bus_private.h>
56#include <machine/ofw_machdep.h>
57#else
58#include <isa/isareg.h>
59#endif
60
61/* constants */
62
63#define MAXKBDC 1 /* XXX */
64
65/* macros */
66
67#ifndef MAX
68#define MAX(x, y) ((x) > (y) ? (x) : (y))
69#endif
70
71#define kbdcp(p) ((atkbdc_softc_t *)(p))
72#define nextq(i) (((i) + 1) % KBDQ_BUFSIZE)
73#define availq(q) ((q)->head != (q)->tail)
74#if KBDIO_DEBUG >= 2
75#define emptyq(q) ((q)->tail = (q)->head = (q)->qcount = 0)
76#else
77#define emptyq(q) ((q)->tail = (q)->head = 0)
78#endif
79
80#define read_data(k) (bus_space_read_1((k)->iot, (k)->ioh0, 0))
81#define read_status(k) (bus_space_read_1((k)->iot, (k)->ioh1, 0))
82#define write_data(k, d) \
83 (bus_space_write_1((k)->iot, (k)->ioh0, 0, (d)))
84#define write_command(k, d) \
85 (bus_space_write_1((k)->iot, (k)->ioh1, 0, (d)))
86
87/* local variables */
88
89/*
90 * We always need at least one copy of the kbdc_softc struct for the
91 * low-level console. As the low-level console accesses the keyboard
92 * controller before kbdc, and all other devices, is probed, we
93 * statically allocate one entry. XXX
94 */
95static atkbdc_softc_t default_kbdc;
96static atkbdc_softc_t *atkbdc_softc[MAXKBDC] = { &default_kbdc };
97
98static int verbose = KBDIO_DEBUG;
99
100#ifdef __sparc64__
101static struct bus_space_tag atkbdc_bst_store[MAXKBDC];
102#endif
103
104/* function prototypes */
105
106static int atkbdc_setup(atkbdc_softc_t *sc, bus_space_tag_t tag,
107 bus_space_handle_t h0, bus_space_handle_t h1);
108static int addq(kqueue *q, int c);
109static int removeq(kqueue *q);
110static int wait_while_controller_busy(atkbdc_softc_t *kbdc);
111static int wait_for_data(atkbdc_softc_t *kbdc);
112static int wait_for_kbd_data(atkbdc_softc_t *kbdc);
113static int wait_for_kbd_ack(atkbdc_softc_t *kbdc);
114static int wait_for_aux_data(atkbdc_softc_t *kbdc);
115static int wait_for_aux_ack(atkbdc_softc_t *kbdc);
116
117atkbdc_softc_t
118*atkbdc_get_softc(int unit)
119{
120 atkbdc_softc_t *sc;
121
122 if (unit >= sizeof(atkbdc_softc)/sizeof(atkbdc_softc[0]))
123 return NULL;
124 sc = atkbdc_softc[unit];
125 if (sc == NULL) {
126 sc = atkbdc_softc[unit]
127 = malloc(sizeof(*sc), M_DEVBUF, M_NOWAIT | M_ZERO);
128 if (sc == NULL)
129 return NULL;
130 }
131 return sc;
132}
133
134int
135atkbdc_probe_unit(int unit, struct resource *port0, struct resource *port1)
136{
137 if (rman_get_start(port0) <= 0)
138 return ENXIO;
139 if (rman_get_start(port1) <= 0)
140 return ENXIO;
141 return 0;
142}
143
144int
145atkbdc_attach_unit(int unit, atkbdc_softc_t *sc, struct resource *port0,
146 struct resource *port1)
147{
148 return atkbdc_setup(sc, rman_get_bustag(port0),
149 rman_get_bushandle(port0),
150 rman_get_bushandle(port1));
151}
152
153/* the backdoor to the keyboard controller! XXX */
154int
155atkbdc_configure(void)
156{
157 bus_space_tag_t tag;
158 bus_space_handle_t h0;
159 bus_space_handle_t h1;
156#if defined(__i386__)
160#if defined(__i386__) || defined(__amd64__)
157 volatile int i;
158 register_t flags;
159#endif
160#ifdef __sparc64__
161 char name[32];
162 phandle_t chosen, node;
163 ihandle_t stdin;
164 bus_addr_t port0;
165 bus_addr_t port1;
166 int space;
167#else
168 int port0;
169 int port1;
170#endif
171
172 /* XXX: tag should be passed from the caller */
173#if defined(__i386__)
174 tag = I386_BUS_SPACE_IO;
175#elif defined(__amd64__)
176 tag = AMD64_BUS_SPACE_IO;
177#elif defined(__ia64__)
178 tag = IA64_BUS_SPACE_IO;
179#elif defined(__sparc64__)
180 tag = &atkbdc_bst_store[0];
181#else
182#error "define tag!"
183#endif
184
185#ifdef __sparc64__
186 if ((chosen = OF_finddevice("/chosen")) == -1)
187 return 0;
188 if (OF_getprop(chosen, "stdin", &stdin, sizeof(stdin)) == -1)
189 return 0;
190 if ((node = OF_instance_to_package(stdin)) == -1)
191 return 0;
192 if (OF_getprop(node, "name", name, sizeof(name)) == -1)
193 return 0;
194 name[sizeof(name) - 1] = '\0';
195 if (strcmp(name, "kb_ps2") != 0)
196 return 0;
197 /*
198 * The stdin handle points to an instance of a PS/2 keyboard
199 * package but we want the 8042 controller, which is the parent
200 * of that keyboard node.
201 */
202 if ((node = OF_parent(node)) == 0)
203 return 0;
204 if (OF_decode_addr(node, 0, &space, &port0) != 0)
205 return 0;
206 h0 = sparc64_fake_bustag(space, port0, tag);
207 bus_space_subregion(tag, h0, KBD_DATA_PORT, 1, &h0);
208 if (OF_decode_addr(node, 1, &space, &port1) != 0)
209 return 0;
210 h1 = sparc64_fake_bustag(space, port1, tag);
211 bus_space_subregion(tag, h1, KBD_STATUS_PORT, 1, &h1);
212#else
213 port0 = IO_KBD;
214 resource_int_value("atkbdc", 0, "port", &port0);
215 port1 = IO_KBD + KBD_STATUS_PORT;
216#ifdef notyet
217 bus_space_map(tag, port0, IO_KBDSIZE, 0, &h0);
218 bus_space_map(tag, port1, IO_KBDSIZE, 0, &h1);
219#else
220 h0 = (bus_space_handle_t)port0;
221 h1 = (bus_space_handle_t)port1;
222#endif
223#endif
224
161 volatile int i;
162 register_t flags;
163#endif
164#ifdef __sparc64__
165 char name[32];
166 phandle_t chosen, node;
167 ihandle_t stdin;
168 bus_addr_t port0;
169 bus_addr_t port1;
170 int space;
171#else
172 int port0;
173 int port1;
174#endif
175
176 /* XXX: tag should be passed from the caller */
177#if defined(__i386__)
178 tag = I386_BUS_SPACE_IO;
179#elif defined(__amd64__)
180 tag = AMD64_BUS_SPACE_IO;
181#elif defined(__ia64__)
182 tag = IA64_BUS_SPACE_IO;
183#elif defined(__sparc64__)
184 tag = &atkbdc_bst_store[0];
185#else
186#error "define tag!"
187#endif
188
189#ifdef __sparc64__
190 if ((chosen = OF_finddevice("/chosen")) == -1)
191 return 0;
192 if (OF_getprop(chosen, "stdin", &stdin, sizeof(stdin)) == -1)
193 return 0;
194 if ((node = OF_instance_to_package(stdin)) == -1)
195 return 0;
196 if (OF_getprop(node, "name", name, sizeof(name)) == -1)
197 return 0;
198 name[sizeof(name) - 1] = '\0';
199 if (strcmp(name, "kb_ps2") != 0)
200 return 0;
201 /*
202 * The stdin handle points to an instance of a PS/2 keyboard
203 * package but we want the 8042 controller, which is the parent
204 * of that keyboard node.
205 */
206 if ((node = OF_parent(node)) == 0)
207 return 0;
208 if (OF_decode_addr(node, 0, &space, &port0) != 0)
209 return 0;
210 h0 = sparc64_fake_bustag(space, port0, tag);
211 bus_space_subregion(tag, h0, KBD_DATA_PORT, 1, &h0);
212 if (OF_decode_addr(node, 1, &space, &port1) != 0)
213 return 0;
214 h1 = sparc64_fake_bustag(space, port1, tag);
215 bus_space_subregion(tag, h1, KBD_STATUS_PORT, 1, &h1);
216#else
217 port0 = IO_KBD;
218 resource_int_value("atkbdc", 0, "port", &port0);
219 port1 = IO_KBD + KBD_STATUS_PORT;
220#ifdef notyet
221 bus_space_map(tag, port0, IO_KBDSIZE, 0, &h0);
222 bus_space_map(tag, port1, IO_KBDSIZE, 0, &h1);
223#else
224 h0 = (bus_space_handle_t)port0;
225 h1 = (bus_space_handle_t)port1;
226#endif
227#endif
228
225#if defined(__i386__)
229#if defined(__i386__) || defined(__amd64__)
226 /*
227 * Check if we really have AT keyboard controller. Poll status
228 * register until we get "all clear" indication. If no such
229 * indication comes, it probably means that there is no AT
230 * keyboard controller present. Give up in such case. Check relies
231 * on the fact that reading from non-existing in/out port returns
232 * 0xff on i386. May or may not be true on other platforms.
233 */
234 flags = intr_disable();
235 for (i = 0; i != 65535; i++) {
236 if ((bus_space_read_1(tag, h1, 0) & 0x2) == 0)
237 break;
238 }
239 intr_restore(flags);
240 if (i == 65535)
241 return ENXIO;
242#endif
243
244 return atkbdc_setup(atkbdc_softc[0], tag, h0, h1);
245}
246
247static int
248atkbdc_setup(atkbdc_softc_t *sc, bus_space_tag_t tag, bus_space_handle_t h0,
249 bus_space_handle_t h1)
250{
230 /*
231 * Check if we really have AT keyboard controller. Poll status
232 * register until we get "all clear" indication. If no such
233 * indication comes, it probably means that there is no AT
234 * keyboard controller present. Give up in such case. Check relies
235 * on the fact that reading from non-existing in/out port returns
236 * 0xff on i386. May or may not be true on other platforms.
237 */
238 flags = intr_disable();
239 for (i = 0; i != 65535; i++) {
240 if ((bus_space_read_1(tag, h1, 0) & 0x2) == 0)
241 break;
242 }
243 intr_restore(flags);
244 if (i == 65535)
245 return ENXIO;
246#endif
247
248 return atkbdc_setup(atkbdc_softc[0], tag, h0, h1);
249}
250
251static int
252atkbdc_setup(atkbdc_softc_t *sc, bus_space_tag_t tag, bus_space_handle_t h0,
253 bus_space_handle_t h1)
254{
255#if defined(__amd64__)
256 u_int64_t tscval[3], read_delay;
257 register_t flags;
258#endif
259
251 if (sc->ioh0 == 0) { /* XXX */
252 sc->command_byte = -1;
253 sc->command_mask = 0;
254 sc->lock = FALSE;
255 sc->kbd.head = sc->kbd.tail = 0;
256 sc->aux.head = sc->aux.tail = 0;
257#if KBDIO_DEBUG >= 2
258 sc->kbd.call_count = 0;
259 sc->kbd.qcount = sc->kbd.max_qcount = 0;
260 sc->aux.call_count = 0;
261 sc->aux.qcount = sc->aux.max_qcount = 0;
262#endif
263 }
264 sc->iot = tag;
265 sc->ioh0 = h0;
266 sc->ioh1 = h1;
260 if (sc->ioh0 == 0) { /* XXX */
261 sc->command_byte = -1;
262 sc->command_mask = 0;
263 sc->lock = FALSE;
264 sc->kbd.head = sc->kbd.tail = 0;
265 sc->aux.head = sc->aux.tail = 0;
266#if KBDIO_DEBUG >= 2
267 sc->kbd.call_count = 0;
268 sc->kbd.qcount = sc->kbd.max_qcount = 0;
269 sc->aux.call_count = 0;
270 sc->aux.qcount = sc->aux.max_qcount = 0;
271#endif
272 }
273 sc->iot = tag;
274 sc->ioh0 = h0;
275 sc->ioh1 = h1;
276
277#if defined(__amd64__)
278 /*
279 * On certain chipsets AT keyboard controller isn't present and is
280 * emulated by BIOS using SMI interrupt. On those chipsets reading
281 * from the status port may be thousand times slower than usually.
282 * Sometimes this emilation is not working properly resulting in
283 * commands timing our and since we assume that inb() operation
284 * takes very little time to complete we need to adjust number of
285 * retries to keep waiting time within a designed limits (100ms).
286 * Measure time it takes to make read_status() call and adjust
287 * number of retries accordingly.
288 */
289 flags = intr_disable();
290 tscval[0] = rdtsc();
291 read_status(sc);
292 tscval[1] = rdtsc();
293 DELAY(1000);
294 tscval[2] = rdtsc();
295 intr_restore(flags);
296 read_delay = tscval[1] - tscval[0];
297 read_delay /= (tscval[2] - tscval[1]) / 1000;
298 sc->retry = 100000 / ((KBDD_DELAYTIME * 2) + read_delay);
299#else
300 sc->retry = 5000;
301#endif
302
267 return 0;
268}
269
270/* open a keyboard controller */
271KBDC
272atkbdc_open(int unit)
273{
274 if (unit <= 0)
275 unit = 0;
276 if (unit >= MAXKBDC)
277 return NULL;
278 if ((atkbdc_softc[unit]->port0 != NULL)
279 || (atkbdc_softc[unit]->ioh0 != 0)) /* XXX */
280 return (KBDC)atkbdc_softc[unit];
281 return NULL;
282}
283
284/*
285 * I/O access arbitration in `kbdio'
286 *
287 * The `kbdio' module uses a simplistic convention to arbitrate
288 * I/O access to the controller/keyboard/mouse. The convention requires
289 * close cooperation of the calling device driver.
290 *
291 * The device drivers which utilize the `kbdio' module are assumed to
292 * have the following set of routines.
293 * a. An interrupt handler (the bottom half of the driver).
294 * b. Timeout routines which may briefly poll the keyboard controller.
295 * c. Routines outside interrupt context (the top half of the driver).
296 * They should follow the rules below:
297 * 1. The interrupt handler may assume that it always has full access
298 * to the controller/keyboard/mouse.
299 * 2. The other routines must issue `spltty()' if they wish to
300 * prevent the interrupt handler from accessing
301 * the controller/keyboard/mouse.
302 * 3. The timeout routines and the top half routines of the device driver
303 * arbitrate I/O access by observing the lock flag in `kbdio'.
304 * The flag is manipulated via `kbdc_lock()'; when one wants to
305 * perform I/O, call `kbdc_lock(kbdc, TRUE)' and proceed only if
306 * the call returns with TRUE. Otherwise the caller must back off.
307 * Call `kbdc_lock(kbdc, FALSE)' when necessary I/O operaion
308 * is finished. This mechanism does not prevent the interrupt
309 * handler from being invoked at any time and carrying out I/O.
310 * Therefore, `spltty()' must be strategically placed in the device
311 * driver code. Also note that the timeout routine may interrupt
312 * `kbdc_lock()' called by the top half of the driver, but this
313 * interruption is OK so long as the timeout routine observes
314 * rule 4 below.
315 * 4. The interrupt and timeout routines should not extend I/O operation
316 * across more than one interrupt or timeout; they must complete any
317 * necessary I/O operation within one invocation of the routine.
318 * This means that if the timeout routine acquires the lock flag,
319 * it must reset the flag to FALSE before it returns.
320 */
321
322/* set/reset polling lock */
323int
324kbdc_lock(KBDC p, int lock)
325{
326 int prevlock;
327
328 prevlock = kbdcp(p)->lock;
329 kbdcp(p)->lock = lock;
330
331 return (prevlock != lock);
332}
333
334/* check if any data is waiting to be processed */
335int
336kbdc_data_ready(KBDC p)
337{
338 return (availq(&kbdcp(p)->kbd) || availq(&kbdcp(p)->aux)
339 || (read_status(kbdcp(p)) & KBDS_ANY_BUFFER_FULL));
340}
341
342/* queuing functions */
343
344static int
345addq(kqueue *q, int c)
346{
347 if (nextq(q->tail) != q->head) {
348 q->q[q->tail] = c;
349 q->tail = nextq(q->tail);
350#if KBDIO_DEBUG >= 2
351 ++q->call_count;
352 ++q->qcount;
353 if (q->qcount > q->max_qcount)
354 q->max_qcount = q->qcount;
355#endif
356 return TRUE;
357 }
358 return FALSE;
359}
360
361static int
362removeq(kqueue *q)
363{
364 int c;
365
366 if (q->tail != q->head) {
367 c = q->q[q->head];
368 q->head = nextq(q->head);
369#if KBDIO_DEBUG >= 2
370 --q->qcount;
371#endif
372 return c;
373 }
374 return -1;
375}
376
377/*
378 * device I/O routines
379 */
380static int
381wait_while_controller_busy(struct atkbdc_softc *kbdc)
382{
303 return 0;
304}
305
306/* open a keyboard controller */
307KBDC
308atkbdc_open(int unit)
309{
310 if (unit <= 0)
311 unit = 0;
312 if (unit >= MAXKBDC)
313 return NULL;
314 if ((atkbdc_softc[unit]->port0 != NULL)
315 || (atkbdc_softc[unit]->ioh0 != 0)) /* XXX */
316 return (KBDC)atkbdc_softc[unit];
317 return NULL;
318}
319
320/*
321 * I/O access arbitration in `kbdio'
322 *
323 * The `kbdio' module uses a simplistic convention to arbitrate
324 * I/O access to the controller/keyboard/mouse. The convention requires
325 * close cooperation of the calling device driver.
326 *
327 * The device drivers which utilize the `kbdio' module are assumed to
328 * have the following set of routines.
329 * a. An interrupt handler (the bottom half of the driver).
330 * b. Timeout routines which may briefly poll the keyboard controller.
331 * c. Routines outside interrupt context (the top half of the driver).
332 * They should follow the rules below:
333 * 1. The interrupt handler may assume that it always has full access
334 * to the controller/keyboard/mouse.
335 * 2. The other routines must issue `spltty()' if they wish to
336 * prevent the interrupt handler from accessing
337 * the controller/keyboard/mouse.
338 * 3. The timeout routines and the top half routines of the device driver
339 * arbitrate I/O access by observing the lock flag in `kbdio'.
340 * The flag is manipulated via `kbdc_lock()'; when one wants to
341 * perform I/O, call `kbdc_lock(kbdc, TRUE)' and proceed only if
342 * the call returns with TRUE. Otherwise the caller must back off.
343 * Call `kbdc_lock(kbdc, FALSE)' when necessary I/O operaion
344 * is finished. This mechanism does not prevent the interrupt
345 * handler from being invoked at any time and carrying out I/O.
346 * Therefore, `spltty()' must be strategically placed in the device
347 * driver code. Also note that the timeout routine may interrupt
348 * `kbdc_lock()' called by the top half of the driver, but this
349 * interruption is OK so long as the timeout routine observes
350 * rule 4 below.
351 * 4. The interrupt and timeout routines should not extend I/O operation
352 * across more than one interrupt or timeout; they must complete any
353 * necessary I/O operation within one invocation of the routine.
354 * This means that if the timeout routine acquires the lock flag,
355 * it must reset the flag to FALSE before it returns.
356 */
357
358/* set/reset polling lock */
359int
360kbdc_lock(KBDC p, int lock)
361{
362 int prevlock;
363
364 prevlock = kbdcp(p)->lock;
365 kbdcp(p)->lock = lock;
366
367 return (prevlock != lock);
368}
369
370/* check if any data is waiting to be processed */
371int
372kbdc_data_ready(KBDC p)
373{
374 return (availq(&kbdcp(p)->kbd) || availq(&kbdcp(p)->aux)
375 || (read_status(kbdcp(p)) & KBDS_ANY_BUFFER_FULL));
376}
377
378/* queuing functions */
379
380static int
381addq(kqueue *q, int c)
382{
383 if (nextq(q->tail) != q->head) {
384 q->q[q->tail] = c;
385 q->tail = nextq(q->tail);
386#if KBDIO_DEBUG >= 2
387 ++q->call_count;
388 ++q->qcount;
389 if (q->qcount > q->max_qcount)
390 q->max_qcount = q->qcount;
391#endif
392 return TRUE;
393 }
394 return FALSE;
395}
396
397static int
398removeq(kqueue *q)
399{
400 int c;
401
402 if (q->tail != q->head) {
403 c = q->q[q->head];
404 q->head = nextq(q->head);
405#if KBDIO_DEBUG >= 2
406 --q->qcount;
407#endif
408 return c;
409 }
410 return -1;
411}
412
413/*
414 * device I/O routines
415 */
416static int
417wait_while_controller_busy(struct atkbdc_softc *kbdc)
418{
383 /* CPU will stay inside the loop for 100msec at most */
384 int retry = 5000;
419 int retry;
385 int f;
386
420 int f;
421
422 /* CPU will stay inside the loop for 100msec at most */
423 retry = kbdc->retry;
424
387 while ((f = read_status(kbdc)) & KBDS_INPUT_BUFFER_FULL) {
388 if ((f & KBDS_BUFFER_FULL) == KBDS_KBD_BUFFER_FULL) {
389 DELAY(KBDD_DELAYTIME);
390 addq(&kbdc->kbd, read_data(kbdc));
391 } else if ((f & KBDS_BUFFER_FULL) == KBDS_AUX_BUFFER_FULL) {
392 DELAY(KBDD_DELAYTIME);
393 addq(&kbdc->aux, read_data(kbdc));
394 }
395 DELAY(KBDC_DELAYTIME);
396 if (--retry < 0)
397 return FALSE;
398 }
399 return TRUE;
400}
401
402/*
403 * wait for any data; whether it's from the controller,
404 * the keyboard, or the aux device.
405 */
406static int
407wait_for_data(struct atkbdc_softc *kbdc)
408{
425 while ((f = read_status(kbdc)) & KBDS_INPUT_BUFFER_FULL) {
426 if ((f & KBDS_BUFFER_FULL) == KBDS_KBD_BUFFER_FULL) {
427 DELAY(KBDD_DELAYTIME);
428 addq(&kbdc->kbd, read_data(kbdc));
429 } else if ((f & KBDS_BUFFER_FULL) == KBDS_AUX_BUFFER_FULL) {
430 DELAY(KBDD_DELAYTIME);
431 addq(&kbdc->aux, read_data(kbdc));
432 }
433 DELAY(KBDC_DELAYTIME);
434 if (--retry < 0)
435 return FALSE;
436 }
437 return TRUE;
438}
439
440/*
441 * wait for any data; whether it's from the controller,
442 * the keyboard, or the aux device.
443 */
444static int
445wait_for_data(struct atkbdc_softc *kbdc)
446{
409 /* CPU will stay inside the loop for 200msec at most */
410 int retry = 10000;
447 int retry;
411 int f;
412
448 int f;
449
450 /* CPU will stay inside the loop for 200msec at most */
451 retry = kbdc->retry * 2;
452
413 while ((f = read_status(kbdc) & KBDS_ANY_BUFFER_FULL) == 0) {
414 DELAY(KBDC_DELAYTIME);
415 if (--retry < 0)
416 return 0;
417 }
418 DELAY(KBDD_DELAYTIME);
419 return f;
420}
421
422/* wait for data from the keyboard */
423static int
424wait_for_kbd_data(struct atkbdc_softc *kbdc)
425{
453 while ((f = read_status(kbdc) & KBDS_ANY_BUFFER_FULL) == 0) {
454 DELAY(KBDC_DELAYTIME);
455 if (--retry < 0)
456 return 0;
457 }
458 DELAY(KBDD_DELAYTIME);
459 return f;
460}
461
462/* wait for data from the keyboard */
463static int
464wait_for_kbd_data(struct atkbdc_softc *kbdc)
465{
426 /* CPU will stay inside the loop for 200msec at most */
427 int retry = 10000;
466 int retry;
428 int f;
429
467 int f;
468
469 /* CPU will stay inside the loop for 200msec at most */
470 retry = kbdc->retry * 2;
471
430 while ((f = read_status(kbdc) & KBDS_BUFFER_FULL)
431 != KBDS_KBD_BUFFER_FULL) {
432 if (f == KBDS_AUX_BUFFER_FULL) {
433 DELAY(KBDD_DELAYTIME);
434 addq(&kbdc->aux, read_data(kbdc));
435 }
436 DELAY(KBDC_DELAYTIME);
437 if (--retry < 0)
438 return 0;
439 }
440 DELAY(KBDD_DELAYTIME);
441 return f;
442}
443
444/*
445 * wait for an ACK(FAh), RESEND(FEh), or RESET_FAIL(FCh) from the keyboard.
446 * queue anything else.
447 */
448static int
449wait_for_kbd_ack(struct atkbdc_softc *kbdc)
450{
472 while ((f = read_status(kbdc) & KBDS_BUFFER_FULL)
473 != KBDS_KBD_BUFFER_FULL) {
474 if (f == KBDS_AUX_BUFFER_FULL) {
475 DELAY(KBDD_DELAYTIME);
476 addq(&kbdc->aux, read_data(kbdc));
477 }
478 DELAY(KBDC_DELAYTIME);
479 if (--retry < 0)
480 return 0;
481 }
482 DELAY(KBDD_DELAYTIME);
483 return f;
484}
485
486/*
487 * wait for an ACK(FAh), RESEND(FEh), or RESET_FAIL(FCh) from the keyboard.
488 * queue anything else.
489 */
490static int
491wait_for_kbd_ack(struct atkbdc_softc *kbdc)
492{
451 /* CPU will stay inside the loop for 200msec at most */
452 int retry = 10000;
493 int retry;
453 int f;
454 int b;
455
494 int f;
495 int b;
496
497 /* CPU will stay inside the loop for 200msec at most */
498 retry = kbdc->retry * 2;
499
456 while (retry-- > 0) {
457 if ((f = read_status(kbdc)) & KBDS_ANY_BUFFER_FULL) {
458 DELAY(KBDD_DELAYTIME);
459 b = read_data(kbdc);
460 if ((f & KBDS_BUFFER_FULL) == KBDS_KBD_BUFFER_FULL) {
461 if ((b == KBD_ACK) || (b == KBD_RESEND)
462 || (b == KBD_RESET_FAIL))
463 return b;
464 addq(&kbdc->kbd, b);
465 } else if ((f & KBDS_BUFFER_FULL) == KBDS_AUX_BUFFER_FULL) {
466 addq(&kbdc->aux, b);
467 }
468 }
469 DELAY(KBDC_DELAYTIME);
470 }
471 return -1;
472}
473
474/* wait for data from the aux device */
475static int
476wait_for_aux_data(struct atkbdc_softc *kbdc)
477{
500 while (retry-- > 0) {
501 if ((f = read_status(kbdc)) & KBDS_ANY_BUFFER_FULL) {
502 DELAY(KBDD_DELAYTIME);
503 b = read_data(kbdc);
504 if ((f & KBDS_BUFFER_FULL) == KBDS_KBD_BUFFER_FULL) {
505 if ((b == KBD_ACK) || (b == KBD_RESEND)
506 || (b == KBD_RESET_FAIL))
507 return b;
508 addq(&kbdc->kbd, b);
509 } else if ((f & KBDS_BUFFER_FULL) == KBDS_AUX_BUFFER_FULL) {
510 addq(&kbdc->aux, b);
511 }
512 }
513 DELAY(KBDC_DELAYTIME);
514 }
515 return -1;
516}
517
518/* wait for data from the aux device */
519static int
520wait_for_aux_data(struct atkbdc_softc *kbdc)
521{
478 /* CPU will stay inside the loop for 200msec at most */
479 int retry = 10000;
522 int retry;
480 int f;
481
523 int f;
524
525 /* CPU will stay inside the loop for 200msec at most */
526 retry = kbdc->retry * 2;
527
482 while ((f = read_status(kbdc) & KBDS_BUFFER_FULL)
483 != KBDS_AUX_BUFFER_FULL) {
484 if (f == KBDS_KBD_BUFFER_FULL) {
485 DELAY(KBDD_DELAYTIME);
486 addq(&kbdc->kbd, read_data(kbdc));
487 }
488 DELAY(KBDC_DELAYTIME);
489 if (--retry < 0)
490 return 0;
491 }
492 DELAY(KBDD_DELAYTIME);
493 return f;
494}
495
496/*
497 * wait for an ACK(FAh), RESEND(FEh), or RESET_FAIL(FCh) from the aux device.
498 * queue anything else.
499 */
500static int
501wait_for_aux_ack(struct atkbdc_softc *kbdc)
502{
528 while ((f = read_status(kbdc) & KBDS_BUFFER_FULL)
529 != KBDS_AUX_BUFFER_FULL) {
530 if (f == KBDS_KBD_BUFFER_FULL) {
531 DELAY(KBDD_DELAYTIME);
532 addq(&kbdc->kbd, read_data(kbdc));
533 }
534 DELAY(KBDC_DELAYTIME);
535 if (--retry < 0)
536 return 0;
537 }
538 DELAY(KBDD_DELAYTIME);
539 return f;
540}
541
542/*
543 * wait for an ACK(FAh), RESEND(FEh), or RESET_FAIL(FCh) from the aux device.
544 * queue anything else.
545 */
546static int
547wait_for_aux_ack(struct atkbdc_softc *kbdc)
548{
503 /* CPU will stay inside the loop for 200msec at most */
504 int retry = 10000;
549 int retry;
505 int f;
506 int b;
507
550 int f;
551 int b;
552
553 /* CPU will stay inside the loop for 200msec at most */
554 retry = kbdc->retry * 2;
555
508 while (retry-- > 0) {
509 if ((f = read_status(kbdc)) & KBDS_ANY_BUFFER_FULL) {
510 DELAY(KBDD_DELAYTIME);
511 b = read_data(kbdc);
512 if ((f & KBDS_BUFFER_FULL) == KBDS_AUX_BUFFER_FULL) {
513 if ((b == PSM_ACK) || (b == PSM_RESEND)
514 || (b == PSM_RESET_FAIL))
515 return b;
516 addq(&kbdc->aux, b);
517 } else if ((f & KBDS_BUFFER_FULL) == KBDS_KBD_BUFFER_FULL) {
518 addq(&kbdc->kbd, b);
519 }
520 }
521 DELAY(KBDC_DELAYTIME);
522 }
523 return -1;
524}
525
526/* write a one byte command to the controller */
527int
528write_controller_command(KBDC p, int c)
529{
530 if (!wait_while_controller_busy(kbdcp(p)))
531 return FALSE;
532 write_command(kbdcp(p), c);
533 return TRUE;
534}
535
536/* write a one byte data to the controller */
537int
538write_controller_data(KBDC p, int c)
539{
540 if (!wait_while_controller_busy(kbdcp(p)))
541 return FALSE;
542 write_data(kbdcp(p), c);
543 return TRUE;
544}
545
546/* write a one byte keyboard command */
547int
548write_kbd_command(KBDC p, int c)
549{
550 if (!wait_while_controller_busy(kbdcp(p)))
551 return FALSE;
552 write_data(kbdcp(p), c);
553 return TRUE;
554}
555
556/* write a one byte auxiliary device command */
557int
558write_aux_command(KBDC p, int c)
559{
560 if (!write_controller_command(p, KBDC_WRITE_TO_AUX))
561 return FALSE;
562 return write_controller_data(p, c);
563}
564
565/* send a command to the keyboard and wait for ACK */
566int
567send_kbd_command(KBDC p, int c)
568{
569 int retry = KBD_MAXRETRY;
570 int res = -1;
571
572 while (retry-- > 0) {
573 if (!write_kbd_command(p, c))
574 continue;
575 res = wait_for_kbd_ack(kbdcp(p));
576 if (res == KBD_ACK)
577 break;
578 }
579 return res;
580}
581
582/* send a command to the auxiliary device and wait for ACK */
583int
584send_aux_command(KBDC p, int c)
585{
586 int retry = KBD_MAXRETRY;
587 int res = -1;
588
589 while (retry-- > 0) {
590 if (!write_aux_command(p, c))
591 continue;
592 /*
593 * FIXME: XXX
594 * The aux device may have already sent one or two bytes of
595 * status data, when a command is received. It will immediately
596 * stop data transmission, thus, leaving an incomplete data
597 * packet in our buffer. We have to discard any unprocessed
598 * data in order to remove such packets. Well, we may remove
599 * unprocessed, but necessary data byte as well...
600 */
601 emptyq(&kbdcp(p)->aux);
602 res = wait_for_aux_ack(kbdcp(p));
603 if (res == PSM_ACK)
604 break;
605 }
606 return res;
607}
608
609/* send a command and a data to the keyboard, wait for ACKs */
610int
611send_kbd_command_and_data(KBDC p, int c, int d)
612{
613 int retry;
614 int res = -1;
615
616 for (retry = KBD_MAXRETRY; retry > 0; --retry) {
617 if (!write_kbd_command(p, c))
618 continue;
619 res = wait_for_kbd_ack(kbdcp(p));
620 if (res == KBD_ACK)
621 break;
622 else if (res != KBD_RESEND)
623 return res;
624 }
625 if (retry <= 0)
626 return res;
627
628 for (retry = KBD_MAXRETRY, res = -1; retry > 0; --retry) {
629 if (!write_kbd_command(p, d))
630 continue;
631 res = wait_for_kbd_ack(kbdcp(p));
632 if (res != KBD_RESEND)
633 break;
634 }
635 return res;
636}
637
638/* send a command and a data to the auxiliary device, wait for ACKs */
639int
640send_aux_command_and_data(KBDC p, int c, int d)
641{
642 int retry;
643 int res = -1;
644
645 for (retry = KBD_MAXRETRY; retry > 0; --retry) {
646 if (!write_aux_command(p, c))
647 continue;
648 emptyq(&kbdcp(p)->aux);
649 res = wait_for_aux_ack(kbdcp(p));
650 if (res == PSM_ACK)
651 break;
652 else if (res != PSM_RESEND)
653 return res;
654 }
655 if (retry <= 0)
656 return res;
657
658 for (retry = KBD_MAXRETRY, res = -1; retry > 0; --retry) {
659 if (!write_aux_command(p, d))
660 continue;
661 res = wait_for_aux_ack(kbdcp(p));
662 if (res != PSM_RESEND)
663 break;
664 }
665 return res;
666}
667
668/*
669 * read one byte from any source; whether from the controller,
670 * the keyboard, or the aux device
671 */
672int
673read_controller_data(KBDC p)
674{
675 if (availq(&kbdcp(p)->kbd))
676 return removeq(&kbdcp(p)->kbd);
677 if (availq(&kbdcp(p)->aux))
678 return removeq(&kbdcp(p)->aux);
679 if (!wait_for_data(kbdcp(p)))
680 return -1; /* timeout */
681 return read_data(kbdcp(p));
682}
683
684#if KBDIO_DEBUG >= 2
685static int call = 0;
686#endif
687
688/* read one byte from the keyboard */
689int
690read_kbd_data(KBDC p)
691{
692#if KBDIO_DEBUG >= 2
693 if (++call > 2000) {
694 call = 0;
695 log(LOG_DEBUG, "kbdc: kbd q: %d calls, max %d chars, "
696 "aux q: %d calls, max %d chars\n",
697 kbdcp(p)->kbd.call_count, kbdcp(p)->kbd.max_qcount,
698 kbdcp(p)->aux.call_count, kbdcp(p)->aux.max_qcount);
699 }
700#endif
701
702 if (availq(&kbdcp(p)->kbd))
703 return removeq(&kbdcp(p)->kbd);
704 if (!wait_for_kbd_data(kbdcp(p)))
705 return -1; /* timeout */
706 return read_data(kbdcp(p));
707}
708
709/* read one byte from the keyboard, but return immediately if
710 * no data is waiting
711 */
712int
713read_kbd_data_no_wait(KBDC p)
714{
715 int f;
716
717#if KBDIO_DEBUG >= 2
718 if (++call > 2000) {
719 call = 0;
720 log(LOG_DEBUG, "kbdc: kbd q: %d calls, max %d chars, "
721 "aux q: %d calls, max %d chars\n",
722 kbdcp(p)->kbd.call_count, kbdcp(p)->kbd.max_qcount,
723 kbdcp(p)->aux.call_count, kbdcp(p)->aux.max_qcount);
724 }
725#endif
726
727 if (availq(&kbdcp(p)->kbd))
728 return removeq(&kbdcp(p)->kbd);
729 f = read_status(kbdcp(p)) & KBDS_BUFFER_FULL;
730 if (f == KBDS_AUX_BUFFER_FULL) {
731 DELAY(KBDD_DELAYTIME);
732 addq(&kbdcp(p)->aux, read_data(kbdcp(p)));
733 f = read_status(kbdcp(p)) & KBDS_BUFFER_FULL;
734 }
735 if (f == KBDS_KBD_BUFFER_FULL) {
736 DELAY(KBDD_DELAYTIME);
737 return read_data(kbdcp(p));
738 }
739 return -1; /* no data */
740}
741
742/* read one byte from the aux device */
743int
744read_aux_data(KBDC p)
745{
746 if (availq(&kbdcp(p)->aux))
747 return removeq(&kbdcp(p)->aux);
748 if (!wait_for_aux_data(kbdcp(p)))
749 return -1; /* timeout */
750 return read_data(kbdcp(p));
751}
752
753/* read one byte from the aux device, but return immediately if
754 * no data is waiting
755 */
756int
757read_aux_data_no_wait(KBDC p)
758{
759 int f;
760
761 if (availq(&kbdcp(p)->aux))
762 return removeq(&kbdcp(p)->aux);
763 f = read_status(kbdcp(p)) & KBDS_BUFFER_FULL;
764 if (f == KBDS_KBD_BUFFER_FULL) {
765 DELAY(KBDD_DELAYTIME);
766 addq(&kbdcp(p)->kbd, read_data(kbdcp(p)));
767 f = read_status(kbdcp(p)) & KBDS_BUFFER_FULL;
768 }
769 if (f == KBDS_AUX_BUFFER_FULL) {
770 DELAY(KBDD_DELAYTIME);
771 return read_data(kbdcp(p));
772 }
773 return -1; /* no data */
774}
775
776/* discard data from the keyboard */
777void
778empty_kbd_buffer(KBDC p, int wait)
779{
780 int t;
781 int b;
782 int f;
783#if KBDIO_DEBUG >= 2
784 int c1 = 0;
785 int c2 = 0;
786#endif
787 int delta = 2;
788
789 for (t = wait; t > 0; ) {
790 if ((f = read_status(kbdcp(p))) & KBDS_ANY_BUFFER_FULL) {
791 DELAY(KBDD_DELAYTIME);
792 b = read_data(kbdcp(p));
793 if ((f & KBDS_BUFFER_FULL) == KBDS_AUX_BUFFER_FULL) {
794 addq(&kbdcp(p)->aux, b);
795#if KBDIO_DEBUG >= 2
796 ++c2;
797 } else {
798 ++c1;
799#endif
800 }
801 t = wait;
802 } else {
803 t -= delta;
804 }
805 DELAY(delta*1000);
806 }
807#if KBDIO_DEBUG >= 2
808 if ((c1 > 0) || (c2 > 0))
809 log(LOG_DEBUG, "kbdc: %d:%d char read (empty_kbd_buffer)\n", c1, c2);
810#endif
811
812 emptyq(&kbdcp(p)->kbd);
813}
814
815/* discard data from the aux device */
816void
817empty_aux_buffer(KBDC p, int wait)
818{
819 int t;
820 int b;
821 int f;
822#if KBDIO_DEBUG >= 2
823 int c1 = 0;
824 int c2 = 0;
825#endif
826 int delta = 2;
827
828 for (t = wait; t > 0; ) {
829 if ((f = read_status(kbdcp(p))) & KBDS_ANY_BUFFER_FULL) {
830 DELAY(KBDD_DELAYTIME);
831 b = read_data(kbdcp(p));
832 if ((f & KBDS_BUFFER_FULL) == KBDS_KBD_BUFFER_FULL) {
833 addq(&kbdcp(p)->kbd, b);
834#if KBDIO_DEBUG >= 2
835 ++c1;
836 } else {
837 ++c2;
838#endif
839 }
840 t = wait;
841 } else {
842 t -= delta;
843 }
844 DELAY(delta*1000);
845 }
846#if KBDIO_DEBUG >= 2
847 if ((c1 > 0) || (c2 > 0))
848 log(LOG_DEBUG, "kbdc: %d:%d char read (empty_aux_buffer)\n", c1, c2);
849#endif
850
851 emptyq(&kbdcp(p)->aux);
852}
853
854/* discard any data from the keyboard or the aux device */
855void
856empty_both_buffers(KBDC p, int wait)
857{
858 int t;
859 int f;
860 int waited = 0;
861#if KBDIO_DEBUG >= 2
862 int c1 = 0;
863 int c2 = 0;
864#endif
865 int delta = 2;
866
867 for (t = wait; t > 0; ) {
868 if ((f = read_status(kbdcp(p))) & KBDS_ANY_BUFFER_FULL) {
869 DELAY(KBDD_DELAYTIME);
870 (void)read_data(kbdcp(p));
871#if KBDIO_DEBUG >= 2
872 if ((f & KBDS_BUFFER_FULL) == KBDS_KBD_BUFFER_FULL)
873 ++c1;
874 else
875 ++c2;
876#endif
877 t = wait;
878 } else {
879 t -= delta;
880 }
881
882 /*
883 * Some systems (Intel/IBM blades) do not have keyboard devices and
884 * will thus hang in this procedure. Time out after delta seconds to
885 * avoid this hang -- the keyboard attach will fail later on.
886 */
887 waited += (delta * 1000);
888 if (waited == (delta * 1000000))
889 return;
890
891 DELAY(delta*1000);
892 }
893#if KBDIO_DEBUG >= 2
894 if ((c1 > 0) || (c2 > 0))
895 log(LOG_DEBUG, "kbdc: %d:%d char read (empty_both_buffers)\n", c1, c2);
896#endif
897
898 emptyq(&kbdcp(p)->kbd);
899 emptyq(&kbdcp(p)->aux);
900}
901
902/* keyboard and mouse device control */
903
904/* NOTE: enable the keyboard port but disable the keyboard
905 * interrupt before calling "reset_kbd()".
906 */
907int
908reset_kbd(KBDC p)
909{
910 int retry = KBD_MAXRETRY;
911 int again = KBD_MAXWAIT;
912 int c = KBD_RESEND; /* keep the compiler happy */
913
914 while (retry-- > 0) {
915 empty_both_buffers(p, 10);
916 if (!write_kbd_command(p, KBDC_RESET_KBD))
917 continue;
918 emptyq(&kbdcp(p)->kbd);
919 c = read_controller_data(p);
920 if (verbose || bootverbose)
921 log(LOG_DEBUG, "kbdc: RESET_KBD return code:%04x\n", c);
922 if (c == KBD_ACK) /* keyboard has agreed to reset itself... */
923 break;
924 }
925 if (retry < 0)
926 return FALSE;
927
928 while (again-- > 0) {
929 /* wait awhile, well, in fact we must wait quite loooooooooooong */
930 DELAY(KBD_RESETDELAY*1000);
931 c = read_controller_data(p); /* RESET_DONE/RESET_FAIL */
932 if (c != -1) /* wait again if the controller is not ready */
933 break;
934 }
935 if (verbose || bootverbose)
936 log(LOG_DEBUG, "kbdc: RESET_KBD status:%04x\n", c);
937 if (c != KBD_RESET_DONE)
938 return FALSE;
939 return TRUE;
940}
941
942/* NOTE: enable the aux port but disable the aux interrupt
943 * before calling `reset_aux_dev()'.
944 */
945int
946reset_aux_dev(KBDC p)
947{
948 int retry = KBD_MAXRETRY;
949 int again = KBD_MAXWAIT;
950 int c = PSM_RESEND; /* keep the compiler happy */
951
952 while (retry-- > 0) {
953 empty_both_buffers(p, 10);
954 if (!write_aux_command(p, PSMC_RESET_DEV))
955 continue;
956 emptyq(&kbdcp(p)->aux);
957 /* NOTE: Compaq Armada laptops require extra delay here. XXX */
958 for (again = KBD_MAXWAIT; again > 0; --again) {
959 DELAY(KBD_RESETDELAY*1000);
960 c = read_aux_data_no_wait(p);
961 if (c != -1)
962 break;
963 }
964 if (verbose || bootverbose)
965 log(LOG_DEBUG, "kbdc: RESET_AUX return code:%04x\n", c);
966 if (c == PSM_ACK) /* aux dev is about to reset... */
967 break;
968 }
969 if (retry < 0)
970 return FALSE;
971
972 for (again = KBD_MAXWAIT; again > 0; --again) {
973 /* wait awhile, well, quite looooooooooooong */
974 DELAY(KBD_RESETDELAY*1000);
975 c = read_aux_data_no_wait(p); /* RESET_DONE/RESET_FAIL */
976 if (c != -1) /* wait again if the controller is not ready */
977 break;
978 }
979 if (verbose || bootverbose)
980 log(LOG_DEBUG, "kbdc: RESET_AUX status:%04x\n", c);
981 if (c != PSM_RESET_DONE) /* reset status */
982 return FALSE;
983
984 c = read_aux_data(p); /* device ID */
985 if (verbose || bootverbose)
986 log(LOG_DEBUG, "kbdc: RESET_AUX ID:%04x\n", c);
987 /* NOTE: we could check the device ID now, but leave it later... */
988 return TRUE;
989}
990
991/* controller diagnostics and setup */
992
993int
994test_controller(KBDC p)
995{
996 int retry = KBD_MAXRETRY;
997 int again = KBD_MAXWAIT;
998 int c = KBD_DIAG_FAIL;
999
1000 while (retry-- > 0) {
1001 empty_both_buffers(p, 10);
1002 if (write_controller_command(p, KBDC_DIAGNOSE))
1003 break;
1004 }
1005 if (retry < 0)
1006 return FALSE;
1007
1008 emptyq(&kbdcp(p)->kbd);
1009 while (again-- > 0) {
1010 /* wait awhile */
1011 DELAY(KBD_RESETDELAY*1000);
1012 c = read_controller_data(p); /* DIAG_DONE/DIAG_FAIL */
1013 if (c != -1) /* wait again if the controller is not ready */
1014 break;
1015 }
1016 if (verbose || bootverbose)
1017 log(LOG_DEBUG, "kbdc: DIAGNOSE status:%04x\n", c);
1018 return (c == KBD_DIAG_DONE);
1019}
1020
1021int
1022test_kbd_port(KBDC p)
1023{
1024 int retry = KBD_MAXRETRY;
1025 int again = KBD_MAXWAIT;
1026 int c = -1;
1027
1028 while (retry-- > 0) {
1029 empty_both_buffers(p, 10);
1030 if (write_controller_command(p, KBDC_TEST_KBD_PORT))
1031 break;
1032 }
1033 if (retry < 0)
1034 return FALSE;
1035
1036 emptyq(&kbdcp(p)->kbd);
1037 while (again-- > 0) {
1038 c = read_controller_data(p);
1039 if (c != -1) /* try again if the controller is not ready */
1040 break;
1041 }
1042 if (verbose || bootverbose)
1043 log(LOG_DEBUG, "kbdc: TEST_KBD_PORT status:%04x\n", c);
1044 return c;
1045}
1046
1047int
1048test_aux_port(KBDC p)
1049{
1050 int retry = KBD_MAXRETRY;
1051 int again = KBD_MAXWAIT;
1052 int c = -1;
1053
1054 while (retry-- > 0) {
1055 empty_both_buffers(p, 10);
1056 if (write_controller_command(p, KBDC_TEST_AUX_PORT))
1057 break;
1058 }
1059 if (retry < 0)
1060 return FALSE;
1061
1062 emptyq(&kbdcp(p)->kbd);
1063 while (again-- > 0) {
1064 c = read_controller_data(p);
1065 if (c != -1) /* try again if the controller is not ready */
1066 break;
1067 }
1068 if (verbose || bootverbose)
1069 log(LOG_DEBUG, "kbdc: TEST_AUX_PORT status:%04x\n", c);
1070 return c;
1071}
1072
1073int
1074kbdc_get_device_mask(KBDC p)
1075{
1076 return kbdcp(p)->command_mask;
1077}
1078
1079void
1080kbdc_set_device_mask(KBDC p, int mask)
1081{
1082 kbdcp(p)->command_mask =
1083 mask & (KBD_KBD_CONTROL_BITS | KBD_AUX_CONTROL_BITS);
1084}
1085
1086int
1087get_controller_command_byte(KBDC p)
1088{
1089 if (kbdcp(p)->command_byte != -1)
1090 return kbdcp(p)->command_byte;
1091 if (!write_controller_command(p, KBDC_GET_COMMAND_BYTE))
1092 return -1;
1093 emptyq(&kbdcp(p)->kbd);
1094 kbdcp(p)->command_byte = read_controller_data(p);
1095 return kbdcp(p)->command_byte;
1096}
1097
1098int
1099set_controller_command_byte(KBDC p, int mask, int command)
1100{
1101 if (get_controller_command_byte(p) == -1)
1102 return FALSE;
1103
1104 command = (kbdcp(p)->command_byte & ~mask) | (command & mask);
1105 if (command & KBD_DISABLE_KBD_PORT) {
1106 if (!write_controller_command(p, KBDC_DISABLE_KBD_PORT))
1107 return FALSE;
1108 }
1109 if (!write_controller_command(p, KBDC_SET_COMMAND_BYTE))
1110 return FALSE;
1111 if (!write_controller_data(p, command))
1112 return FALSE;
1113 kbdcp(p)->command_byte = command;
1114
1115 if (verbose)
1116 log(LOG_DEBUG, "kbdc: new command byte:%04x (set_controller...)\n",
1117 command);
1118
1119 return TRUE;
1120}
556 while (retry-- > 0) {
557 if ((f = read_status(kbdc)) & KBDS_ANY_BUFFER_FULL) {
558 DELAY(KBDD_DELAYTIME);
559 b = read_data(kbdc);
560 if ((f & KBDS_BUFFER_FULL) == KBDS_AUX_BUFFER_FULL) {
561 if ((b == PSM_ACK) || (b == PSM_RESEND)
562 || (b == PSM_RESET_FAIL))
563 return b;
564 addq(&kbdc->aux, b);
565 } else if ((f & KBDS_BUFFER_FULL) == KBDS_KBD_BUFFER_FULL) {
566 addq(&kbdc->kbd, b);
567 }
568 }
569 DELAY(KBDC_DELAYTIME);
570 }
571 return -1;
572}
573
574/* write a one byte command to the controller */
575int
576write_controller_command(KBDC p, int c)
577{
578 if (!wait_while_controller_busy(kbdcp(p)))
579 return FALSE;
580 write_command(kbdcp(p), c);
581 return TRUE;
582}
583
584/* write a one byte data to the controller */
585int
586write_controller_data(KBDC p, int c)
587{
588 if (!wait_while_controller_busy(kbdcp(p)))
589 return FALSE;
590 write_data(kbdcp(p), c);
591 return TRUE;
592}
593
594/* write a one byte keyboard command */
595int
596write_kbd_command(KBDC p, int c)
597{
598 if (!wait_while_controller_busy(kbdcp(p)))
599 return FALSE;
600 write_data(kbdcp(p), c);
601 return TRUE;
602}
603
604/* write a one byte auxiliary device command */
605int
606write_aux_command(KBDC p, int c)
607{
608 if (!write_controller_command(p, KBDC_WRITE_TO_AUX))
609 return FALSE;
610 return write_controller_data(p, c);
611}
612
613/* send a command to the keyboard and wait for ACK */
614int
615send_kbd_command(KBDC p, int c)
616{
617 int retry = KBD_MAXRETRY;
618 int res = -1;
619
620 while (retry-- > 0) {
621 if (!write_kbd_command(p, c))
622 continue;
623 res = wait_for_kbd_ack(kbdcp(p));
624 if (res == KBD_ACK)
625 break;
626 }
627 return res;
628}
629
630/* send a command to the auxiliary device and wait for ACK */
631int
632send_aux_command(KBDC p, int c)
633{
634 int retry = KBD_MAXRETRY;
635 int res = -1;
636
637 while (retry-- > 0) {
638 if (!write_aux_command(p, c))
639 continue;
640 /*
641 * FIXME: XXX
642 * The aux device may have already sent one or two bytes of
643 * status data, when a command is received. It will immediately
644 * stop data transmission, thus, leaving an incomplete data
645 * packet in our buffer. We have to discard any unprocessed
646 * data in order to remove such packets. Well, we may remove
647 * unprocessed, but necessary data byte as well...
648 */
649 emptyq(&kbdcp(p)->aux);
650 res = wait_for_aux_ack(kbdcp(p));
651 if (res == PSM_ACK)
652 break;
653 }
654 return res;
655}
656
657/* send a command and a data to the keyboard, wait for ACKs */
658int
659send_kbd_command_and_data(KBDC p, int c, int d)
660{
661 int retry;
662 int res = -1;
663
664 for (retry = KBD_MAXRETRY; retry > 0; --retry) {
665 if (!write_kbd_command(p, c))
666 continue;
667 res = wait_for_kbd_ack(kbdcp(p));
668 if (res == KBD_ACK)
669 break;
670 else if (res != KBD_RESEND)
671 return res;
672 }
673 if (retry <= 0)
674 return res;
675
676 for (retry = KBD_MAXRETRY, res = -1; retry > 0; --retry) {
677 if (!write_kbd_command(p, d))
678 continue;
679 res = wait_for_kbd_ack(kbdcp(p));
680 if (res != KBD_RESEND)
681 break;
682 }
683 return res;
684}
685
686/* send a command and a data to the auxiliary device, wait for ACKs */
687int
688send_aux_command_and_data(KBDC p, int c, int d)
689{
690 int retry;
691 int res = -1;
692
693 for (retry = KBD_MAXRETRY; retry > 0; --retry) {
694 if (!write_aux_command(p, c))
695 continue;
696 emptyq(&kbdcp(p)->aux);
697 res = wait_for_aux_ack(kbdcp(p));
698 if (res == PSM_ACK)
699 break;
700 else if (res != PSM_RESEND)
701 return res;
702 }
703 if (retry <= 0)
704 return res;
705
706 for (retry = KBD_MAXRETRY, res = -1; retry > 0; --retry) {
707 if (!write_aux_command(p, d))
708 continue;
709 res = wait_for_aux_ack(kbdcp(p));
710 if (res != PSM_RESEND)
711 break;
712 }
713 return res;
714}
715
716/*
717 * read one byte from any source; whether from the controller,
718 * the keyboard, or the aux device
719 */
720int
721read_controller_data(KBDC p)
722{
723 if (availq(&kbdcp(p)->kbd))
724 return removeq(&kbdcp(p)->kbd);
725 if (availq(&kbdcp(p)->aux))
726 return removeq(&kbdcp(p)->aux);
727 if (!wait_for_data(kbdcp(p)))
728 return -1; /* timeout */
729 return read_data(kbdcp(p));
730}
731
732#if KBDIO_DEBUG >= 2
733static int call = 0;
734#endif
735
736/* read one byte from the keyboard */
737int
738read_kbd_data(KBDC p)
739{
740#if KBDIO_DEBUG >= 2
741 if (++call > 2000) {
742 call = 0;
743 log(LOG_DEBUG, "kbdc: kbd q: %d calls, max %d chars, "
744 "aux q: %d calls, max %d chars\n",
745 kbdcp(p)->kbd.call_count, kbdcp(p)->kbd.max_qcount,
746 kbdcp(p)->aux.call_count, kbdcp(p)->aux.max_qcount);
747 }
748#endif
749
750 if (availq(&kbdcp(p)->kbd))
751 return removeq(&kbdcp(p)->kbd);
752 if (!wait_for_kbd_data(kbdcp(p)))
753 return -1; /* timeout */
754 return read_data(kbdcp(p));
755}
756
757/* read one byte from the keyboard, but return immediately if
758 * no data is waiting
759 */
760int
761read_kbd_data_no_wait(KBDC p)
762{
763 int f;
764
765#if KBDIO_DEBUG >= 2
766 if (++call > 2000) {
767 call = 0;
768 log(LOG_DEBUG, "kbdc: kbd q: %d calls, max %d chars, "
769 "aux q: %d calls, max %d chars\n",
770 kbdcp(p)->kbd.call_count, kbdcp(p)->kbd.max_qcount,
771 kbdcp(p)->aux.call_count, kbdcp(p)->aux.max_qcount);
772 }
773#endif
774
775 if (availq(&kbdcp(p)->kbd))
776 return removeq(&kbdcp(p)->kbd);
777 f = read_status(kbdcp(p)) & KBDS_BUFFER_FULL;
778 if (f == KBDS_AUX_BUFFER_FULL) {
779 DELAY(KBDD_DELAYTIME);
780 addq(&kbdcp(p)->aux, read_data(kbdcp(p)));
781 f = read_status(kbdcp(p)) & KBDS_BUFFER_FULL;
782 }
783 if (f == KBDS_KBD_BUFFER_FULL) {
784 DELAY(KBDD_DELAYTIME);
785 return read_data(kbdcp(p));
786 }
787 return -1; /* no data */
788}
789
790/* read one byte from the aux device */
791int
792read_aux_data(KBDC p)
793{
794 if (availq(&kbdcp(p)->aux))
795 return removeq(&kbdcp(p)->aux);
796 if (!wait_for_aux_data(kbdcp(p)))
797 return -1; /* timeout */
798 return read_data(kbdcp(p));
799}
800
801/* read one byte from the aux device, but return immediately if
802 * no data is waiting
803 */
804int
805read_aux_data_no_wait(KBDC p)
806{
807 int f;
808
809 if (availq(&kbdcp(p)->aux))
810 return removeq(&kbdcp(p)->aux);
811 f = read_status(kbdcp(p)) & KBDS_BUFFER_FULL;
812 if (f == KBDS_KBD_BUFFER_FULL) {
813 DELAY(KBDD_DELAYTIME);
814 addq(&kbdcp(p)->kbd, read_data(kbdcp(p)));
815 f = read_status(kbdcp(p)) & KBDS_BUFFER_FULL;
816 }
817 if (f == KBDS_AUX_BUFFER_FULL) {
818 DELAY(KBDD_DELAYTIME);
819 return read_data(kbdcp(p));
820 }
821 return -1; /* no data */
822}
823
824/* discard data from the keyboard */
825void
826empty_kbd_buffer(KBDC p, int wait)
827{
828 int t;
829 int b;
830 int f;
831#if KBDIO_DEBUG >= 2
832 int c1 = 0;
833 int c2 = 0;
834#endif
835 int delta = 2;
836
837 for (t = wait; t > 0; ) {
838 if ((f = read_status(kbdcp(p))) & KBDS_ANY_BUFFER_FULL) {
839 DELAY(KBDD_DELAYTIME);
840 b = read_data(kbdcp(p));
841 if ((f & KBDS_BUFFER_FULL) == KBDS_AUX_BUFFER_FULL) {
842 addq(&kbdcp(p)->aux, b);
843#if KBDIO_DEBUG >= 2
844 ++c2;
845 } else {
846 ++c1;
847#endif
848 }
849 t = wait;
850 } else {
851 t -= delta;
852 }
853 DELAY(delta*1000);
854 }
855#if KBDIO_DEBUG >= 2
856 if ((c1 > 0) || (c2 > 0))
857 log(LOG_DEBUG, "kbdc: %d:%d char read (empty_kbd_buffer)\n", c1, c2);
858#endif
859
860 emptyq(&kbdcp(p)->kbd);
861}
862
863/* discard data from the aux device */
864void
865empty_aux_buffer(KBDC p, int wait)
866{
867 int t;
868 int b;
869 int f;
870#if KBDIO_DEBUG >= 2
871 int c1 = 0;
872 int c2 = 0;
873#endif
874 int delta = 2;
875
876 for (t = wait; t > 0; ) {
877 if ((f = read_status(kbdcp(p))) & KBDS_ANY_BUFFER_FULL) {
878 DELAY(KBDD_DELAYTIME);
879 b = read_data(kbdcp(p));
880 if ((f & KBDS_BUFFER_FULL) == KBDS_KBD_BUFFER_FULL) {
881 addq(&kbdcp(p)->kbd, b);
882#if KBDIO_DEBUG >= 2
883 ++c1;
884 } else {
885 ++c2;
886#endif
887 }
888 t = wait;
889 } else {
890 t -= delta;
891 }
892 DELAY(delta*1000);
893 }
894#if KBDIO_DEBUG >= 2
895 if ((c1 > 0) || (c2 > 0))
896 log(LOG_DEBUG, "kbdc: %d:%d char read (empty_aux_buffer)\n", c1, c2);
897#endif
898
899 emptyq(&kbdcp(p)->aux);
900}
901
902/* discard any data from the keyboard or the aux device */
903void
904empty_both_buffers(KBDC p, int wait)
905{
906 int t;
907 int f;
908 int waited = 0;
909#if KBDIO_DEBUG >= 2
910 int c1 = 0;
911 int c2 = 0;
912#endif
913 int delta = 2;
914
915 for (t = wait; t > 0; ) {
916 if ((f = read_status(kbdcp(p))) & KBDS_ANY_BUFFER_FULL) {
917 DELAY(KBDD_DELAYTIME);
918 (void)read_data(kbdcp(p));
919#if KBDIO_DEBUG >= 2
920 if ((f & KBDS_BUFFER_FULL) == KBDS_KBD_BUFFER_FULL)
921 ++c1;
922 else
923 ++c2;
924#endif
925 t = wait;
926 } else {
927 t -= delta;
928 }
929
930 /*
931 * Some systems (Intel/IBM blades) do not have keyboard devices and
932 * will thus hang in this procedure. Time out after delta seconds to
933 * avoid this hang -- the keyboard attach will fail later on.
934 */
935 waited += (delta * 1000);
936 if (waited == (delta * 1000000))
937 return;
938
939 DELAY(delta*1000);
940 }
941#if KBDIO_DEBUG >= 2
942 if ((c1 > 0) || (c2 > 0))
943 log(LOG_DEBUG, "kbdc: %d:%d char read (empty_both_buffers)\n", c1, c2);
944#endif
945
946 emptyq(&kbdcp(p)->kbd);
947 emptyq(&kbdcp(p)->aux);
948}
949
950/* keyboard and mouse device control */
951
952/* NOTE: enable the keyboard port but disable the keyboard
953 * interrupt before calling "reset_kbd()".
954 */
955int
956reset_kbd(KBDC p)
957{
958 int retry = KBD_MAXRETRY;
959 int again = KBD_MAXWAIT;
960 int c = KBD_RESEND; /* keep the compiler happy */
961
962 while (retry-- > 0) {
963 empty_both_buffers(p, 10);
964 if (!write_kbd_command(p, KBDC_RESET_KBD))
965 continue;
966 emptyq(&kbdcp(p)->kbd);
967 c = read_controller_data(p);
968 if (verbose || bootverbose)
969 log(LOG_DEBUG, "kbdc: RESET_KBD return code:%04x\n", c);
970 if (c == KBD_ACK) /* keyboard has agreed to reset itself... */
971 break;
972 }
973 if (retry < 0)
974 return FALSE;
975
976 while (again-- > 0) {
977 /* wait awhile, well, in fact we must wait quite loooooooooooong */
978 DELAY(KBD_RESETDELAY*1000);
979 c = read_controller_data(p); /* RESET_DONE/RESET_FAIL */
980 if (c != -1) /* wait again if the controller is not ready */
981 break;
982 }
983 if (verbose || bootverbose)
984 log(LOG_DEBUG, "kbdc: RESET_KBD status:%04x\n", c);
985 if (c != KBD_RESET_DONE)
986 return FALSE;
987 return TRUE;
988}
989
990/* NOTE: enable the aux port but disable the aux interrupt
991 * before calling `reset_aux_dev()'.
992 */
993int
994reset_aux_dev(KBDC p)
995{
996 int retry = KBD_MAXRETRY;
997 int again = KBD_MAXWAIT;
998 int c = PSM_RESEND; /* keep the compiler happy */
999
1000 while (retry-- > 0) {
1001 empty_both_buffers(p, 10);
1002 if (!write_aux_command(p, PSMC_RESET_DEV))
1003 continue;
1004 emptyq(&kbdcp(p)->aux);
1005 /* NOTE: Compaq Armada laptops require extra delay here. XXX */
1006 for (again = KBD_MAXWAIT; again > 0; --again) {
1007 DELAY(KBD_RESETDELAY*1000);
1008 c = read_aux_data_no_wait(p);
1009 if (c != -1)
1010 break;
1011 }
1012 if (verbose || bootverbose)
1013 log(LOG_DEBUG, "kbdc: RESET_AUX return code:%04x\n", c);
1014 if (c == PSM_ACK) /* aux dev is about to reset... */
1015 break;
1016 }
1017 if (retry < 0)
1018 return FALSE;
1019
1020 for (again = KBD_MAXWAIT; again > 0; --again) {
1021 /* wait awhile, well, quite looooooooooooong */
1022 DELAY(KBD_RESETDELAY*1000);
1023 c = read_aux_data_no_wait(p); /* RESET_DONE/RESET_FAIL */
1024 if (c != -1) /* wait again if the controller is not ready */
1025 break;
1026 }
1027 if (verbose || bootverbose)
1028 log(LOG_DEBUG, "kbdc: RESET_AUX status:%04x\n", c);
1029 if (c != PSM_RESET_DONE) /* reset status */
1030 return FALSE;
1031
1032 c = read_aux_data(p); /* device ID */
1033 if (verbose || bootverbose)
1034 log(LOG_DEBUG, "kbdc: RESET_AUX ID:%04x\n", c);
1035 /* NOTE: we could check the device ID now, but leave it later... */
1036 return TRUE;
1037}
1038
1039/* controller diagnostics and setup */
1040
1041int
1042test_controller(KBDC p)
1043{
1044 int retry = KBD_MAXRETRY;
1045 int again = KBD_MAXWAIT;
1046 int c = KBD_DIAG_FAIL;
1047
1048 while (retry-- > 0) {
1049 empty_both_buffers(p, 10);
1050 if (write_controller_command(p, KBDC_DIAGNOSE))
1051 break;
1052 }
1053 if (retry < 0)
1054 return FALSE;
1055
1056 emptyq(&kbdcp(p)->kbd);
1057 while (again-- > 0) {
1058 /* wait awhile */
1059 DELAY(KBD_RESETDELAY*1000);
1060 c = read_controller_data(p); /* DIAG_DONE/DIAG_FAIL */
1061 if (c != -1) /* wait again if the controller is not ready */
1062 break;
1063 }
1064 if (verbose || bootverbose)
1065 log(LOG_DEBUG, "kbdc: DIAGNOSE status:%04x\n", c);
1066 return (c == KBD_DIAG_DONE);
1067}
1068
1069int
1070test_kbd_port(KBDC p)
1071{
1072 int retry = KBD_MAXRETRY;
1073 int again = KBD_MAXWAIT;
1074 int c = -1;
1075
1076 while (retry-- > 0) {
1077 empty_both_buffers(p, 10);
1078 if (write_controller_command(p, KBDC_TEST_KBD_PORT))
1079 break;
1080 }
1081 if (retry < 0)
1082 return FALSE;
1083
1084 emptyq(&kbdcp(p)->kbd);
1085 while (again-- > 0) {
1086 c = read_controller_data(p);
1087 if (c != -1) /* try again if the controller is not ready */
1088 break;
1089 }
1090 if (verbose || bootverbose)
1091 log(LOG_DEBUG, "kbdc: TEST_KBD_PORT status:%04x\n", c);
1092 return c;
1093}
1094
1095int
1096test_aux_port(KBDC p)
1097{
1098 int retry = KBD_MAXRETRY;
1099 int again = KBD_MAXWAIT;
1100 int c = -1;
1101
1102 while (retry-- > 0) {
1103 empty_both_buffers(p, 10);
1104 if (write_controller_command(p, KBDC_TEST_AUX_PORT))
1105 break;
1106 }
1107 if (retry < 0)
1108 return FALSE;
1109
1110 emptyq(&kbdcp(p)->kbd);
1111 while (again-- > 0) {
1112 c = read_controller_data(p);
1113 if (c != -1) /* try again if the controller is not ready */
1114 break;
1115 }
1116 if (verbose || bootverbose)
1117 log(LOG_DEBUG, "kbdc: TEST_AUX_PORT status:%04x\n", c);
1118 return c;
1119}
1120
1121int
1122kbdc_get_device_mask(KBDC p)
1123{
1124 return kbdcp(p)->command_mask;
1125}
1126
1127void
1128kbdc_set_device_mask(KBDC p, int mask)
1129{
1130 kbdcp(p)->command_mask =
1131 mask & (KBD_KBD_CONTROL_BITS | KBD_AUX_CONTROL_BITS);
1132}
1133
1134int
1135get_controller_command_byte(KBDC p)
1136{
1137 if (kbdcp(p)->command_byte != -1)
1138 return kbdcp(p)->command_byte;
1139 if (!write_controller_command(p, KBDC_GET_COMMAND_BYTE))
1140 return -1;
1141 emptyq(&kbdcp(p)->kbd);
1142 kbdcp(p)->command_byte = read_controller_data(p);
1143 return kbdcp(p)->command_byte;
1144}
1145
1146int
1147set_controller_command_byte(KBDC p, int mask, int command)
1148{
1149 if (get_controller_command_byte(p) == -1)
1150 return FALSE;
1151
1152 command = (kbdcp(p)->command_byte & ~mask) | (command & mask);
1153 if (command & KBD_DISABLE_KBD_PORT) {
1154 if (!write_controller_command(p, KBDC_DISABLE_KBD_PORT))
1155 return FALSE;
1156 }
1157 if (!write_controller_command(p, KBDC_SET_COMMAND_BYTE))
1158 return FALSE;
1159 if (!write_controller_data(p, command))
1160 return FALSE;
1161 kbdcp(p)->command_byte = command;
1162
1163 if (verbose)
1164 log(LOG_DEBUG, "kbdc: new command byte:%04x (set_controller...)\n",
1165 command);
1166
1167 return TRUE;
1168}