atppc.c revision 1.16.2.3 1 1.16.2.3 skrll /* $NetBSD: atppc.c,v 1.16.2.3 2004/08/25 06:57:35 skrll Exp $ */
2 1.16.2.2 skrll
3 1.16.2.2 skrll /*
4 1.16.2.2 skrll * Copyright (c) 2001 Alcove - Nicolas Souchu
5 1.16.2.2 skrll * Copyright (c) 2003, 2004 Gary Thorpe <gathorpe (at) users.sourceforge.net>
6 1.16.2.2 skrll * All rights reserved.
7 1.16.2.2 skrll *
8 1.16.2.2 skrll * Redistribution and use in source and binary forms, with or without
9 1.16.2.2 skrll * modification, are permitted provided that the following conditions
10 1.16.2.2 skrll * are met:
11 1.16.2.2 skrll * 1. Redistributions of source code must retain the above copyright
12 1.16.2.2 skrll * notice, this list of conditions and the following disclaimer.
13 1.16.2.2 skrll * 2. Redistributions in binary form must reproduce the above copyright
14 1.16.2.2 skrll * notice, this list of conditions and the following disclaimer in the
15 1.16.2.2 skrll * documentation and/or other materials provided with the distribution.
16 1.16.2.2 skrll *
17 1.16.2.2 skrll * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 1.16.2.2 skrll * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 1.16.2.2 skrll * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 1.16.2.2 skrll * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 1.16.2.2 skrll * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 1.16.2.2 skrll * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 1.16.2.2 skrll * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 1.16.2.2 skrll * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 1.16.2.2 skrll * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 1.16.2.2 skrll * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 1.16.2.2 skrll * SUCH DAMAGE.
28 1.16.2.2 skrll *
29 1.16.2.2 skrll * FreeBSD: src/sys/isa/ppc.c,v 1.26.2.5 2001/10/02 05:21:45 nsouch Exp
30 1.16.2.2 skrll *
31 1.16.2.2 skrll */
32 1.16.2.2 skrll
33 1.16.2.2 skrll #include <sys/cdefs.h>
34 1.16.2.3 skrll __KERNEL_RCSID(0, "$NetBSD: atppc.c,v 1.16.2.3 2004/08/25 06:57:35 skrll Exp $");
35 1.16.2.2 skrll
36 1.16.2.2 skrll #include "opt_atppc.h"
37 1.16.2.2 skrll
38 1.16.2.2 skrll #include <sys/types.h>
39 1.16.2.2 skrll #include <sys/param.h>
40 1.16.2.2 skrll #include <sys/kernel.h>
41 1.16.2.2 skrll #include <sys/device.h>
42 1.16.2.2 skrll #include <sys/malloc.h>
43 1.16.2.2 skrll #include <sys/proc.h>
44 1.16.2.2 skrll #include <sys/systm.h>
45 1.16.2.2 skrll #include <sys/vnode.h>
46 1.16.2.2 skrll #include <sys/syslog.h>
47 1.16.2.2 skrll
48 1.16.2.2 skrll #include <machine/bus.h>
49 1.16.2.2 skrll /*#include <machine/intr.h>*/
50 1.16.2.2 skrll
51 1.16.2.2 skrll #include <dev/isa/isareg.h>
52 1.16.2.2 skrll
53 1.16.2.2 skrll #include <dev/ic/atppcreg.h>
54 1.16.2.2 skrll #include <dev/ic/atppcvar.h>
55 1.16.2.2 skrll
56 1.16.2.2 skrll #include <dev/ppbus/ppbus_conf.h>
57 1.16.2.2 skrll #include <dev/ppbus/ppbus_msq.h>
58 1.16.2.2 skrll #include <dev/ppbus/ppbus_io.h>
59 1.16.2.2 skrll #include <dev/ppbus/ppbus_var.h>
60 1.16.2.2 skrll
61 1.16.2.2 skrll #ifdef ATPPC_DEBUG
62 1.16.2.2 skrll int atppc_debug = 1;
63 1.16.2.2 skrll #endif
64 1.16.2.2 skrll
65 1.16.2.2 skrll #ifdef ATPPC_VERBOSE
66 1.16.2.2 skrll int atppc_verbose = 1;
67 1.16.2.2 skrll #endif
68 1.16.2.2 skrll
69 1.16.2.2 skrll /* List of supported chipsets detection routines */
70 1.16.2.2 skrll static int (*chipset_detect[])(struct atppc_softc *) = {
71 1.16.2.2 skrll /* XXX Add these LATER: maybe as seperate devices?
72 1.16.2.2 skrll atppc_pc873xx_detect,
73 1.16.2.2 skrll atppc_smc37c66xgt_detect,
74 1.16.2.2 skrll atppc_w83877f_detect,
75 1.16.2.2 skrll atppc_smc37c935_detect,
76 1.16.2.2 skrll */
77 1.16.2.2 skrll NULL
78 1.16.2.2 skrll };
79 1.16.2.2 skrll
80 1.16.2.2 skrll
81 1.16.2.2 skrll /* Prototypes for functions. */
82 1.16.2.2 skrll
83 1.16.2.2 skrll /* Print function for config_found_sm() */
84 1.16.2.2 skrll static int atppc_print(void *, const char *);
85 1.16.2.2 skrll
86 1.16.2.2 skrll /* Detection routines */
87 1.16.2.2 skrll static int atppc_detect_fifo(struct atppc_softc *);
88 1.16.2.2 skrll static int atppc_detect_chipset(struct atppc_softc *);
89 1.16.2.2 skrll static int atppc_detect_generic(struct atppc_softc *);
90 1.16.2.2 skrll
91 1.16.2.2 skrll /* Routines for ppbus interface (bus + device) */
92 1.16.2.2 skrll static int atppc_read(struct device *, char *, int, int, size_t *);
93 1.16.2.2 skrll static int atppc_write(struct device *, char *, int, int, size_t *);
94 1.16.2.2 skrll static int atppc_setmode(struct device *, int);
95 1.16.2.2 skrll static int atppc_getmode(struct device *);
96 1.16.2.2 skrll static int atppc_check_epp_timeout(struct device *);
97 1.16.2.2 skrll static void atppc_reset_epp_timeout(struct device *);
98 1.16.2.2 skrll static void atppc_ecp_sync(struct device *);
99 1.16.2.2 skrll static int atppc_exec_microseq(struct device *, struct ppbus_microseq * *);
100 1.16.2.2 skrll static u_int8_t atppc_io(struct device *, int, u_char *, int, u_char);
101 1.16.2.2 skrll static int atppc_read_ivar(struct device *, int, unsigned int *);
102 1.16.2.2 skrll static int atppc_write_ivar(struct device *, int, unsigned int *);
103 1.16.2.2 skrll static int atppc_add_handler(struct device *, void (*)(void *), void *);
104 1.16.2.2 skrll static int atppc_remove_handler(struct device *, void (*)(void *));
105 1.16.2.2 skrll
106 1.16.2.2 skrll /* Utility functions */
107 1.16.2.2 skrll
108 1.16.2.2 skrll /* Functions to read bytes into device's input buffer */
109 1.16.2.2 skrll static void atppc_nibble_read(struct atppc_softc * const);
110 1.16.2.2 skrll static void atppc_byte_read(struct atppc_softc * const);
111 1.16.2.2 skrll static void atppc_epp_read(struct atppc_softc * const);
112 1.16.2.2 skrll static void atppc_ecp_read(struct atppc_softc * const);
113 1.16.2.2 skrll static void atppc_ecp_read_dma(struct atppc_softc *, unsigned int *,
114 1.16.2.2 skrll unsigned char);
115 1.16.2.2 skrll static void atppc_ecp_read_pio(struct atppc_softc *, unsigned int *,
116 1.16.2.2 skrll unsigned char);
117 1.16.2.2 skrll static void atppc_ecp_read_error(struct atppc_softc *, const unsigned int);
118 1.16.2.2 skrll
119 1.16.2.2 skrll
120 1.16.2.2 skrll /* Functions to write bytes to device's output buffer */
121 1.16.2.2 skrll static void atppc_std_write(struct atppc_softc * const);
122 1.16.2.2 skrll static void atppc_epp_write(struct atppc_softc * const);
123 1.16.2.2 skrll static void atppc_fifo_write(struct atppc_softc * const);
124 1.16.2.2 skrll static void atppc_fifo_write_dma(struct atppc_softc * const, unsigned char,
125 1.16.2.2 skrll unsigned char);
126 1.16.2.2 skrll static void atppc_fifo_write_pio(struct atppc_softc * const, unsigned char,
127 1.16.2.2 skrll unsigned char);
128 1.16.2.2 skrll static void atppc_fifo_write_error(struct atppc_softc * const,
129 1.16.2.2 skrll const unsigned int);
130 1.16.2.2 skrll
131 1.16.2.2 skrll /* Miscellaneous */
132 1.16.2.2 skrll static int atppc_poll_str(const struct atppc_softc * const, const u_int8_t,
133 1.16.2.2 skrll const u_int8_t);
134 1.16.2.2 skrll static int atppc_wait_interrupt(struct atppc_softc * const, const caddr_t,
135 1.16.2.2 skrll const u_int8_t);
136 1.16.2.2 skrll
137 1.16.2.2 skrll
138 1.16.2.2 skrll /*
139 1.16.2.2 skrll * Generic attach and detach functions for atppc device. If sc_dev_ok in soft
140 1.16.2.2 skrll * configuration data is not ATPPC_ATTACHED, these should be skipped altogether.
141 1.16.2.2 skrll */
142 1.16.2.2 skrll
143 1.16.2.2 skrll /* Soft configuration attach for atppc */
144 1.16.2.2 skrll void
145 1.16.2.2 skrll atppc_sc_attach(struct atppc_softc *lsc)
146 1.16.2.2 skrll {
147 1.16.2.2 skrll /* Adapter used to configure ppbus device */
148 1.16.2.2 skrll struct parport_adapter sc_parport_adapter;
149 1.16.2.2 skrll char buf[64];
150 1.16.2.2 skrll
151 1.16.2.2 skrll ATPPC_LOCK_INIT(lsc);
152 1.16.2.2 skrll
153 1.16.2.2 skrll /* Probe and set up chipset */
154 1.16.2.2 skrll if (atppc_detect_chipset(lsc) != 0) {
155 1.16.2.2 skrll if (atppc_detect_generic(lsc) != 0) {
156 1.16.2.2 skrll ATPPC_DPRINTF(("%s: Error detecting chipset\n",
157 1.16.2.2 skrll lsc->sc_dev.dv_xname));
158 1.16.2.2 skrll }
159 1.16.2.2 skrll }
160 1.16.2.2 skrll
161 1.16.2.2 skrll /* Probe and setup FIFO queue */
162 1.16.2.2 skrll if (atppc_detect_fifo(lsc) == 0) {
163 1.16.2.2 skrll printf("%s: FIFO <depth,wthr,rthr>=<%d,%d,%d>\n",
164 1.16.2.2 skrll lsc->sc_dev.dv_xname, lsc->sc_fifo, lsc->sc_wthr,
165 1.16.2.2 skrll lsc->sc_rthr);
166 1.16.2.2 skrll }
167 1.16.2.2 skrll
168 1.16.2.2 skrll /* Print out chipset capabilities */
169 1.16.2.2 skrll bitmask_snprintf(lsc->sc_has, "\20\1INTR\2DMA\3FIFO\4PS2\5ECP\6EPP",
170 1.16.2.2 skrll buf, sizeof(buf));
171 1.16.2.2 skrll printf("%s: capabilities=%s\n", lsc->sc_dev.dv_xname, buf);
172 1.16.2.2 skrll
173 1.16.2.2 skrll /* Initialize device's buffer pointers */
174 1.16.2.2 skrll lsc->sc_outb = lsc->sc_outbstart = lsc->sc_inb = lsc->sc_inbstart
175 1.16.2.2 skrll = NULL;
176 1.16.2.2 skrll lsc->sc_inb_nbytes = lsc->sc_outb_nbytes = 0;
177 1.16.2.2 skrll
178 1.16.2.2 skrll /* Last configuration step: set mode to standard mode */
179 1.16.2.2 skrll if (atppc_setmode(&(lsc->sc_dev), PPBUS_COMPATIBLE) != 0) {
180 1.16.2.2 skrll ATPPC_DPRINTF(("%s: unable to initialize mode.\n",
181 1.16.2.2 skrll lsc->sc_dev.dv_xname));
182 1.16.2.2 skrll }
183 1.16.2.2 skrll
184 1.16.2.2 skrll #if defined (MULTIPROCESSOR) || defined (LOCKDEBUG)
185 1.16.2.2 skrll /* Initialize lock structure */
186 1.16.2.2 skrll simple_lock_init(&(lsc->sc_lock));
187 1.16.2.2 skrll #endif
188 1.16.2.2 skrll
189 1.16.2.2 skrll /* Set up parport_adapter structure */
190 1.16.2.2 skrll
191 1.16.2.2 skrll /* Set capabilites */
192 1.16.2.2 skrll sc_parport_adapter.capabilities = 0;
193 1.16.2.2 skrll if (lsc->sc_has & ATPPC_HAS_INTR) {
194 1.16.2.2 skrll sc_parport_adapter.capabilities |= PPBUS_HAS_INTR;
195 1.16.2.2 skrll }
196 1.16.2.2 skrll if (lsc->sc_has & ATPPC_HAS_DMA) {
197 1.16.2.2 skrll sc_parport_adapter.capabilities |= PPBUS_HAS_DMA;
198 1.16.2.2 skrll }
199 1.16.2.2 skrll if (lsc->sc_has & ATPPC_HAS_FIFO) {
200 1.16.2.2 skrll sc_parport_adapter.capabilities |= PPBUS_HAS_FIFO;
201 1.16.2.2 skrll }
202 1.16.2.2 skrll if (lsc->sc_has & ATPPC_HAS_PS2) {
203 1.16.2.2 skrll sc_parport_adapter.capabilities |= PPBUS_HAS_PS2;
204 1.16.2.2 skrll }
205 1.16.2.2 skrll if (lsc->sc_has & ATPPC_HAS_EPP) {
206 1.16.2.2 skrll sc_parport_adapter.capabilities |= PPBUS_HAS_EPP;
207 1.16.2.2 skrll }
208 1.16.2.2 skrll if (lsc->sc_has & ATPPC_HAS_ECP) {
209 1.16.2.2 skrll sc_parport_adapter.capabilities |= PPBUS_HAS_ECP;
210 1.16.2.2 skrll }
211 1.16.2.2 skrll
212 1.16.2.2 skrll /* Set function pointers */
213 1.16.2.2 skrll sc_parport_adapter.parport_io = atppc_io;
214 1.16.2.2 skrll sc_parport_adapter.parport_exec_microseq = atppc_exec_microseq;
215 1.16.2.2 skrll sc_parport_adapter.parport_reset_epp_timeout =
216 1.16.2.2 skrll atppc_reset_epp_timeout;
217 1.16.2.2 skrll sc_parport_adapter.parport_setmode = atppc_setmode;
218 1.16.2.2 skrll sc_parport_adapter.parport_getmode = atppc_getmode;
219 1.16.2.2 skrll sc_parport_adapter.parport_ecp_sync = atppc_ecp_sync;
220 1.16.2.2 skrll sc_parport_adapter.parport_read = atppc_read;
221 1.16.2.2 skrll sc_parport_adapter.parport_write = atppc_write;
222 1.16.2.2 skrll sc_parport_adapter.parport_read_ivar = atppc_read_ivar;
223 1.16.2.2 skrll sc_parport_adapter.parport_write_ivar = atppc_write_ivar;
224 1.16.2.2 skrll sc_parport_adapter.parport_dma_malloc = lsc->sc_dma_malloc;
225 1.16.2.2 skrll sc_parport_adapter.parport_dma_free = lsc->sc_dma_free;
226 1.16.2.2 skrll sc_parport_adapter.parport_add_handler = atppc_add_handler;
227 1.16.2.2 skrll sc_parport_adapter.parport_remove_handler = atppc_remove_handler;
228 1.16.2.2 skrll
229 1.16.2.2 skrll /* Initialize handler list, may be added to by grandchildren */
230 1.16.2.2 skrll SLIST_INIT(&(lsc->sc_handler_listhead));
231 1.16.2.2 skrll
232 1.16.2.2 skrll /* Initialize interrupt state */
233 1.16.2.2 skrll lsc->sc_irqstat = ATPPC_IRQ_NONE;
234 1.16.2.2 skrll lsc->sc_ecr_intr = lsc->sc_ctr_intr = lsc->sc_str_intr = 0;
235 1.16.2.2 skrll
236 1.16.2.2 skrll /* Disable DMA/interrupts (each ppbus driver selects usage itself) */
237 1.16.2.2 skrll lsc->sc_use = 0;
238 1.16.2.2 skrll
239 1.16.2.2 skrll /* Configure child of the device. */
240 1.16.2.2 skrll lsc->child = config_found_sm(&(lsc->sc_dev), &(sc_parport_adapter),
241 1.16.2.2 skrll atppc_print, NULL);
242 1.16.2.2 skrll
243 1.16.2.2 skrll return;
244 1.16.2.2 skrll }
245 1.16.2.2 skrll
246 1.16.2.2 skrll /* Soft configuration detach */
247 1.16.2.3 skrll int
248 1.16.2.3 skrll atppc_sc_detach(struct atppc_softc *lsc, int flag)
249 1.16.2.2 skrll {
250 1.16.2.2 skrll struct device *dev = (struct device *)lsc;
251 1.16.2.2 skrll
252 1.16.2.2 skrll /* Detach children devices */
253 1.16.2.2 skrll if (config_detach(lsc->child, flag) && !(flag & DETACH_QUIET)) {
254 1.16.2.2 skrll printf("%s not able to detach child device, ", dev->dv_xname);
255 1.16.2.2 skrll
256 1.16.2.2 skrll if (!(flag & DETACH_FORCE)) {
257 1.16.2.2 skrll printf("cannot detach\n");
258 1.16.2.2 skrll return 1;
259 1.16.2.2 skrll } else {
260 1.16.2.2 skrll printf("continuing (DETACH_FORCE)\n");
261 1.16.2.2 skrll }
262 1.16.2.2 skrll }
263 1.16.2.2 skrll
264 1.16.2.2 skrll if (!(flag & DETACH_QUIET))
265 1.16.2.2 skrll printf("%s detached", dev->dv_xname);
266 1.16.2.2 skrll
267 1.16.2.2 skrll return 0;
268 1.16.2.2 skrll }
269 1.16.2.2 skrll
270 1.16.2.2 skrll /* Used by config_found_sm() to print out device information */
271 1.16.2.2 skrll static int
272 1.16.2.2 skrll atppc_print(void *aux, const char *name)
273 1.16.2.2 skrll {
274 1.16.2.2 skrll /* Print out something on failure. */
275 1.16.2.2 skrll if (name != NULL) {
276 1.16.2.2 skrll printf("%s: child devices", name);
277 1.16.2.2 skrll return UNCONF;
278 1.16.2.2 skrll }
279 1.16.2.2 skrll
280 1.16.2.2 skrll return QUIET;
281 1.16.2.2 skrll }
282 1.16.2.2 skrll
283 1.16.2.2 skrll /*
284 1.16.2.2 skrll * Machine independent detection routines for atppc driver.
285 1.16.2.2 skrll */
286 1.16.2.2 skrll
287 1.16.2.2 skrll /* Detect parallel port I/O port: taken from FreeBSD code directly. */
288 1.16.2.2 skrll int
289 1.16.2.2 skrll atppc_detect_port(bus_space_tag_t iot, bus_space_handle_t ioh)
290 1.16.2.2 skrll {
291 1.16.2.2 skrll /*
292 1.16.2.2 skrll * Much shorter than scheme used by lpt_isa_probe() and lpt_port_test()
293 1.16.2.2 skrll * in original lpt driver.
294 1.16.2.2 skrll * Write to data register common to all controllers and read back the
295 1.16.2.2 skrll * values. Also tests control and status registers.
296 1.16.2.2 skrll */
297 1.16.2.2 skrll
298 1.16.2.2 skrll /*
299 1.16.2.2 skrll * Cannot use convenient macros because the device's config structure
300 1.16.2.2 skrll * may not have been created yet: major change from FreeBSD code.
301 1.16.2.2 skrll */
302 1.16.2.2 skrll
303 1.16.2.2 skrll int rval;
304 1.16.2.2 skrll u_int8_t ctr_sav, dtr_sav, str_sav;
305 1.16.2.2 skrll
306 1.16.2.2 skrll /* Store writtable registers' values and test if they can be read */
307 1.16.2.2 skrll str_sav = bus_space_read_1(iot, ioh, ATPPC_SPP_STR);
308 1.16.2.2 skrll ctr_sav = bus_space_read_1(iot, ioh, ATPPC_SPP_CTR);
309 1.16.2.2 skrll dtr_sav = bus_space_read_1(iot, ioh, ATPPC_SPP_DTR);
310 1.16.2.2 skrll bus_space_barrier(iot, ioh, 0, IO_LPTSIZE,
311 1.16.2.2 skrll BUS_SPACE_BARRIER_READ);
312 1.16.2.2 skrll
313 1.16.2.2 skrll /*
314 1.16.2.2 skrll * Ensure PS2 ports in output mode, also read back value of control
315 1.16.2.2 skrll * register.
316 1.16.2.2 skrll */
317 1.16.2.2 skrll bus_space_write_1(iot, ioh, ATPPC_SPP_CTR, 0x0c);
318 1.16.2.2 skrll bus_space_barrier(iot, ioh, 0, IO_LPTSIZE,
319 1.16.2.2 skrll BUS_SPACE_BARRIER_WRITE);
320 1.16.2.2 skrll
321 1.16.2.2 skrll if (bus_space_read_1(iot, ioh, ATPPC_SPP_CTR) != 0x0c) {
322 1.16.2.2 skrll rval = 0;
323 1.16.2.2 skrll } else {
324 1.16.2.2 skrll /*
325 1.16.2.2 skrll * Test if two values can be written and read from the data
326 1.16.2.2 skrll * register.
327 1.16.2.2 skrll */
328 1.16.2.2 skrll bus_space_barrier(iot, ioh, 0, IO_LPTSIZE,
329 1.16.2.2 skrll BUS_SPACE_BARRIER_READ);
330 1.16.2.2 skrll bus_space_write_1(iot, ioh, ATPPC_SPP_DTR, 0xaa);
331 1.16.2.2 skrll bus_space_barrier(iot, ioh, 0, IO_LPTSIZE,
332 1.16.2.2 skrll BUS_SPACE_BARRIER_WRITE);
333 1.16.2.2 skrll if (bus_space_read_1(iot, ioh, ATPPC_SPP_DTR) != 0xaa) {
334 1.16.2.2 skrll rval = 1;
335 1.16.2.2 skrll } else {
336 1.16.2.2 skrll /* Second value to test */
337 1.16.2.2 skrll bus_space_barrier(iot, ioh, 0, IO_LPTSIZE,
338 1.16.2.2 skrll BUS_SPACE_BARRIER_READ);
339 1.16.2.2 skrll bus_space_write_1(iot, ioh, ATPPC_SPP_DTR, 0x55);
340 1.16.2.2 skrll bus_space_barrier(iot, ioh, 0, IO_LPTSIZE,
341 1.16.2.2 skrll BUS_SPACE_BARRIER_WRITE);
342 1.16.2.2 skrll if (bus_space_read_1(iot, ioh, ATPPC_SPP_DTR) != 0x55) {
343 1.16.2.2 skrll rval = 1;
344 1.16.2.2 skrll } else {
345 1.16.2.2 skrll rval = 0;
346 1.16.2.2 skrll }
347 1.16.2.2 skrll }
348 1.16.2.2 skrll
349 1.16.2.2 skrll }
350 1.16.2.2 skrll
351 1.16.2.2 skrll /* Restore registers */
352 1.16.2.2 skrll bus_space_barrier(iot, ioh, 0, IO_LPTSIZE,
353 1.16.2.2 skrll BUS_SPACE_BARRIER_READ);
354 1.16.2.2 skrll bus_space_write_1(iot, ioh, ATPPC_SPP_CTR, ctr_sav);
355 1.16.2.2 skrll bus_space_write_1(iot, ioh, ATPPC_SPP_DTR, dtr_sav);
356 1.16.2.2 skrll bus_space_write_1(iot, ioh, ATPPC_SPP_STR, str_sav);
357 1.16.2.2 skrll bus_space_barrier(iot, ioh, 0, IO_LPTSIZE,
358 1.16.2.2 skrll BUS_SPACE_BARRIER_WRITE);
359 1.16.2.2 skrll
360 1.16.2.2 skrll return rval;
361 1.16.2.2 skrll }
362 1.16.2.2 skrll
363 1.16.2.2 skrll /* Detect parallel port chipset. */
364 1.16.2.2 skrll static int
365 1.16.2.2 skrll atppc_detect_chipset(struct atppc_softc *atppc)
366 1.16.2.2 skrll {
367 1.16.2.2 skrll /* Try each detection routine. */
368 1.16.2.2 skrll int i, mode;
369 1.16.2.2 skrll for (i = 0; chipset_detect[i] != NULL; i++) {
370 1.16.2.2 skrll if ((mode = chipset_detect[i](atppc)) != -1) {
371 1.16.2.2 skrll atppc->sc_mode = mode;
372 1.16.2.2 skrll return 0;
373 1.16.2.2 skrll }
374 1.16.2.2 skrll }
375 1.16.2.2 skrll
376 1.16.2.2 skrll return 1;
377 1.16.2.2 skrll }
378 1.16.2.2 skrll
379 1.16.2.2 skrll /* Detect generic capabilities. */
380 1.16.2.2 skrll static int
381 1.16.2.2 skrll atppc_detect_generic(struct atppc_softc *atppc)
382 1.16.2.2 skrll {
383 1.16.2.2 skrll u_int8_t ecr_sav = atppc_r_ecr(atppc);
384 1.16.2.2 skrll u_int8_t ctr_sav = atppc_r_ctr(atppc);
385 1.16.2.2 skrll u_int8_t str_sav = atppc_r_str(atppc);
386 1.16.2.2 skrll u_int8_t tmp;
387 1.16.2.2 skrll atppc_barrier_r(atppc);
388 1.16.2.2 skrll
389 1.16.2.2 skrll /* Default to generic */
390 1.16.2.2 skrll atppc->sc_type = ATPPC_TYPE_GENERIC;
391 1.16.2.2 skrll atppc->sc_model = GENERIC;
392 1.16.2.2 skrll
393 1.16.2.2 skrll /* Check for ECP */
394 1.16.2.2 skrll tmp = atppc_r_ecr(atppc);
395 1.16.2.2 skrll atppc_barrier_r(atppc);
396 1.16.2.2 skrll if ((tmp & ATPPC_FIFO_EMPTY) && !(tmp & ATPPC_FIFO_FULL)) {
397 1.16.2.2 skrll atppc_w_ecr(atppc, 0x34);
398 1.16.2.2 skrll atppc_barrier_w(atppc);
399 1.16.2.2 skrll tmp = atppc_r_ecr(atppc);
400 1.16.2.2 skrll atppc_barrier_r(atppc);
401 1.16.2.2 skrll if (tmp == 0x35) {
402 1.16.2.2 skrll atppc->sc_has |= ATPPC_HAS_ECP;
403 1.16.2.2 skrll }
404 1.16.2.2 skrll }
405 1.16.2.2 skrll
406 1.16.2.2 skrll /* Allow search for SMC style ECP+EPP mode */
407 1.16.2.2 skrll if (atppc->sc_has & ATPPC_HAS_ECP) {
408 1.16.2.2 skrll atppc_w_ecr(atppc, ATPPC_ECR_EPP);
409 1.16.2.2 skrll atppc_barrier_w(atppc);
410 1.16.2.2 skrll }
411 1.16.2.2 skrll /* Check for EPP by checking for timeout bit */
412 1.16.2.2 skrll if (atppc_check_epp_timeout(&(atppc->sc_dev)) != 0) {
413 1.16.2.2 skrll atppc->sc_has |= ATPPC_HAS_EPP;
414 1.16.2.2 skrll atppc->sc_epp = ATPPC_EPP_1_9;
415 1.16.2.2 skrll if (atppc->sc_has & ATPPC_HAS_ECP) {
416 1.16.2.2 skrll /* SMC like chipset found */
417 1.16.2.2 skrll atppc->sc_model = SMC_LIKE;
418 1.16.2.2 skrll atppc->sc_type = ATPPC_TYPE_SMCLIKE;
419 1.16.2.2 skrll }
420 1.16.2.2 skrll }
421 1.16.2.2 skrll
422 1.16.2.2 skrll /* Detect PS2 mode */
423 1.16.2.2 skrll if (atppc->sc_has & ATPPC_HAS_ECP) {
424 1.16.2.2 skrll /* Put ECP port into PS2 mode */
425 1.16.2.2 skrll atppc_w_ecr(atppc, ATPPC_ECR_PS2);
426 1.16.2.2 skrll atppc_barrier_w(atppc);
427 1.16.2.2 skrll }
428 1.16.2.2 skrll /* Put PS2 port in input mode: writes should not be readable */
429 1.16.2.2 skrll atppc_w_ctr(atppc, 0x20);
430 1.16.2.2 skrll atppc_barrier_w(atppc);
431 1.16.2.2 skrll /*
432 1.16.2.2 skrll * Write two values to data port: if neither are read back,
433 1.16.2.2 skrll * bidirectional mode is functional.
434 1.16.2.2 skrll */
435 1.16.2.2 skrll atppc_w_dtr(atppc, 0xaa);
436 1.16.2.2 skrll atppc_barrier_w(atppc);
437 1.16.2.2 skrll tmp = atppc_r_dtr(atppc);
438 1.16.2.2 skrll atppc_barrier_r(atppc);
439 1.16.2.2 skrll if (tmp != 0xaa) {
440 1.16.2.2 skrll atppc_w_dtr(atppc, 0x55);
441 1.16.2.2 skrll atppc_barrier_w(atppc);
442 1.16.2.2 skrll tmp = atppc_r_dtr(atppc);
443 1.16.2.2 skrll atppc_barrier_r(atppc);
444 1.16.2.2 skrll if (tmp != 0x55) {
445 1.16.2.2 skrll atppc->sc_has |= ATPPC_HAS_PS2;
446 1.16.2.2 skrll }
447 1.16.2.2 skrll }
448 1.16.2.2 skrll
449 1.16.2.2 skrll /* Restore to previous state */
450 1.16.2.2 skrll atppc_w_ecr(atppc, ecr_sav);
451 1.16.2.2 skrll atppc_w_ctr(atppc, ctr_sav);
452 1.16.2.2 skrll atppc_w_str(atppc, str_sav);
453 1.16.2.2 skrll atppc_barrier_w(atppc);
454 1.16.2.2 skrll
455 1.16.2.2 skrll return 0;
456 1.16.2.2 skrll }
457 1.16.2.2 skrll
458 1.16.2.2 skrll /*
459 1.16.2.2 skrll * Detect parallel port FIFO: taken from FreeBSD code directly.
460 1.16.2.2 skrll */
461 1.16.2.2 skrll static int
462 1.16.2.2 skrll atppc_detect_fifo(struct atppc_softc *atppc)
463 1.16.2.2 skrll {
464 1.16.2.2 skrll #ifdef ATPPC_DEBUG
465 1.16.2.2 skrll struct device *dev = (struct device *)atppc;
466 1.16.2.2 skrll #endif
467 1.16.2.2 skrll u_int8_t ecr_sav;
468 1.16.2.2 skrll u_int8_t ctr_sav;
469 1.16.2.2 skrll u_int8_t str_sav;
470 1.16.2.2 skrll u_int8_t cc;
471 1.16.2.2 skrll short i;
472 1.16.2.2 skrll
473 1.16.2.2 skrll /* If there is no ECP mode, we cannot config a FIFO */
474 1.16.2.2 skrll if (!(atppc->sc_has & ATPPC_HAS_ECP)) {
475 1.16.2.2 skrll return (EINVAL);
476 1.16.2.2 skrll }
477 1.16.2.2 skrll
478 1.16.2.2 skrll /* save registers */
479 1.16.2.2 skrll ecr_sav = atppc_r_ecr(atppc);
480 1.16.2.2 skrll ctr_sav = atppc_r_ctr(atppc);
481 1.16.2.2 skrll str_sav = atppc_r_str(atppc);
482 1.16.2.2 skrll atppc_barrier_r(atppc);
483 1.16.2.2 skrll
484 1.16.2.2 skrll /* Enter ECP configuration mode, no interrupt, no DMA */
485 1.16.2.2 skrll atppc_w_ecr(atppc, (ATPPC_ECR_CFG | ATPPC_SERVICE_INTR) &
486 1.16.2.2 skrll ~ATPPC_ENABLE_DMA);
487 1.16.2.2 skrll atppc_barrier_w(atppc);
488 1.16.2.2 skrll
489 1.16.2.2 skrll /* read PWord size - transfers in FIFO mode must be PWord aligned */
490 1.16.2.2 skrll atppc->sc_pword = (atppc_r_cnfgA(atppc) & ATPPC_PWORD_MASK);
491 1.16.2.2 skrll atppc_barrier_r(atppc);
492 1.16.2.2 skrll
493 1.16.2.2 skrll /* XXX 16 and 32 bits implementations not supported */
494 1.16.2.2 skrll if (atppc->sc_pword != ATPPC_PWORD_8) {
495 1.16.2.2 skrll ATPPC_DPRINTF(("%s(%s): FIFO PWord(%d) not supported.\n",
496 1.16.2.2 skrll __func__, dev->dv_xname, atppc->sc_pword));
497 1.16.2.2 skrll goto error;
498 1.16.2.2 skrll }
499 1.16.2.2 skrll
500 1.16.2.2 skrll /* Byte mode, reverse direction, no interrupt, no DMA */
501 1.16.2.2 skrll atppc_w_ecr(atppc, ATPPC_ECR_PS2 | ATPPC_SERVICE_INTR);
502 1.16.2.2 skrll atppc_w_ctr(atppc, (ctr_sav & ~IRQENABLE) | PCD);
503 1.16.2.2 skrll /* enter ECP test mode, no interrupt, no DMA */
504 1.16.2.2 skrll atppc_w_ecr(atppc, ATPPC_ECR_TST | ATPPC_SERVICE_INTR);
505 1.16.2.2 skrll atppc_barrier_w(atppc);
506 1.16.2.2 skrll
507 1.16.2.2 skrll /* flush the FIFO */
508 1.16.2.2 skrll for (i = 0; i < 1024; i++) {
509 1.16.2.2 skrll atppc_r_fifo(atppc);
510 1.16.2.2 skrll atppc_barrier_r(atppc);
511 1.16.2.2 skrll cc = atppc_r_ecr(atppc);
512 1.16.2.2 skrll atppc_barrier_r(atppc);
513 1.16.2.2 skrll if (cc & ATPPC_FIFO_EMPTY)
514 1.16.2.2 skrll break;
515 1.16.2.2 skrll }
516 1.16.2.2 skrll if (i >= 1024) {
517 1.16.2.2 skrll ATPPC_DPRINTF(("%s(%s): cannot flush FIFO.\n", __func__,
518 1.16.2.2 skrll dev->dv_xname));
519 1.16.2.2 skrll goto error;
520 1.16.2.2 skrll }
521 1.16.2.2 skrll
522 1.16.2.2 skrll /* Test mode, enable interrupts, no DMA */
523 1.16.2.2 skrll atppc_w_ecr(atppc, ATPPC_ECR_TST);
524 1.16.2.2 skrll atppc_barrier_w(atppc);
525 1.16.2.2 skrll
526 1.16.2.2 skrll /* Determine readIntrThreshold - fill FIFO until serviceIntr is set */
527 1.16.2.2 skrll for (i = atppc->sc_rthr = atppc->sc_fifo = 0; i < 1024; i++) {
528 1.16.2.2 skrll atppc_w_fifo(atppc, (char)i);
529 1.16.2.2 skrll atppc_barrier_w(atppc);
530 1.16.2.2 skrll cc = atppc_r_ecr(atppc);
531 1.16.2.2 skrll atppc_barrier_r(atppc);
532 1.16.2.2 skrll if ((atppc->sc_rthr == 0) && (cc & ATPPC_SERVICE_INTR)) {
533 1.16.2.2 skrll /* readThreshold reached */
534 1.16.2.2 skrll atppc->sc_rthr = i + 1;
535 1.16.2.2 skrll }
536 1.16.2.2 skrll if (cc & ATPPC_FIFO_FULL) {
537 1.16.2.2 skrll atppc->sc_fifo = i + 1;
538 1.16.2.2 skrll break;
539 1.16.2.2 skrll }
540 1.16.2.2 skrll }
541 1.16.2.2 skrll if (i >= 1024) {
542 1.16.2.2 skrll ATPPC_DPRINTF(("%s(%s): cannot fill FIFO.\n", __func__,
543 1.16.2.2 skrll dev->dv_xname));
544 1.16.2.2 skrll goto error;
545 1.16.2.2 skrll }
546 1.16.2.2 skrll
547 1.16.2.2 skrll /* Change direction */
548 1.16.2.2 skrll atppc_w_ctr(atppc, (ctr_sav & ~IRQENABLE) & ~PCD);
549 1.16.2.2 skrll atppc_barrier_w(atppc);
550 1.16.2.2 skrll
551 1.16.2.2 skrll /* Clear the serviceIntr bit we've already set in the above loop */
552 1.16.2.2 skrll atppc_w_ecr(atppc, ATPPC_ECR_TST);
553 1.16.2.2 skrll atppc_barrier_w(atppc);
554 1.16.2.2 skrll
555 1.16.2.2 skrll /* Determine writeIntrThreshold - empty FIFO until serviceIntr is set */
556 1.16.2.2 skrll for (atppc->sc_wthr = 0; i > -1; i--) {
557 1.16.2.2 skrll cc = atppc_r_fifo(atppc);
558 1.16.2.2 skrll atppc_barrier_r(atppc);
559 1.16.2.2 skrll if (cc != (char)(atppc->sc_fifo - i - 1)) {
560 1.16.2.2 skrll ATPPC_DPRINTF(("%s(%s): invalid data in FIFO.\n",
561 1.16.2.2 skrll __func__, dev->dv_xname));
562 1.16.2.2 skrll goto error;
563 1.16.2.2 skrll }
564 1.16.2.2 skrll
565 1.16.2.2 skrll cc = atppc_r_ecr(atppc);
566 1.16.2.2 skrll atppc_barrier_r(atppc);
567 1.16.2.2 skrll if ((atppc->sc_wthr == 0) && (cc & ATPPC_SERVICE_INTR)) {
568 1.16.2.2 skrll /* writeIntrThreshold reached */
569 1.16.2.2 skrll atppc->sc_wthr = atppc->sc_fifo - i;
570 1.16.2.2 skrll }
571 1.16.2.2 skrll
572 1.16.2.2 skrll if (i > 0 && (cc & ATPPC_FIFO_EMPTY)) {
573 1.16.2.2 skrll /* If FIFO empty before the last byte, error */
574 1.16.2.2 skrll ATPPC_DPRINTF(("%s(%s): data lost in FIFO.\n", __func__,
575 1.16.2.2 skrll dev->dv_xname));
576 1.16.2.2 skrll goto error;
577 1.16.2.2 skrll }
578 1.16.2.2 skrll }
579 1.16.2.2 skrll
580 1.16.2.2 skrll /* FIFO must be empty after the last byte */
581 1.16.2.2 skrll cc = atppc_r_ecr(atppc);
582 1.16.2.2 skrll atppc_barrier_r(atppc);
583 1.16.2.2 skrll if (!(cc & ATPPC_FIFO_EMPTY)) {
584 1.16.2.2 skrll ATPPC_DPRINTF(("%s(%s): cannot empty the FIFO.\n", __func__,
585 1.16.2.2 skrll dev->dv_xname));
586 1.16.2.2 skrll goto error;
587 1.16.2.2 skrll }
588 1.16.2.2 skrll
589 1.16.2.2 skrll /* Restore original registers */
590 1.16.2.2 skrll atppc_w_ctr(atppc, ctr_sav);
591 1.16.2.2 skrll atppc_w_str(atppc, str_sav);
592 1.16.2.2 skrll atppc_w_ecr(atppc, ecr_sav);
593 1.16.2.2 skrll atppc_barrier_w(atppc);
594 1.16.2.2 skrll
595 1.16.2.2 skrll /* Update capabilities */
596 1.16.2.2 skrll atppc->sc_has |= ATPPC_HAS_FIFO;
597 1.16.2.2 skrll
598 1.16.2.2 skrll return 0;
599 1.16.2.2 skrll
600 1.16.2.2 skrll error:
601 1.16.2.2 skrll /* Restore original registers */
602 1.16.2.2 skrll atppc_w_ctr(atppc, ctr_sav);
603 1.16.2.2 skrll atppc_w_str(atppc, str_sav);
604 1.16.2.2 skrll atppc_w_ecr(atppc, ecr_sav);
605 1.16.2.2 skrll atppc_barrier_w(atppc);
606 1.16.2.2 skrll
607 1.16.2.2 skrll return (EINVAL);
608 1.16.2.2 skrll }
609 1.16.2.2 skrll
610 1.16.2.2 skrll /* Interrupt handler for atppc device: wakes up read/write functions */
611 1.16.2.2 skrll int
612 1.16.2.2 skrll atppcintr(void *arg)
613 1.16.2.2 skrll {
614 1.16.2.2 skrll struct atppc_softc *atppc = (struct atppc_softc *)arg;
615 1.16.2.2 skrll struct device *dev = &atppc->sc_dev;
616 1.16.2.2 skrll int claim = 1;
617 1.16.2.2 skrll enum { NONE, READER, WRITER } wake_up = NONE;
618 1.16.2.2 skrll int s;
619 1.16.2.2 skrll
620 1.16.2.2 skrll s = splatppc();
621 1.16.2.2 skrll ATPPC_LOCK(atppc);
622 1.16.2.2 skrll
623 1.16.2.2 skrll /* Record registers' status */
624 1.16.2.2 skrll atppc->sc_str_intr = atppc_r_str(atppc);
625 1.16.2.2 skrll atppc->sc_ctr_intr = atppc_r_ctr(atppc);
626 1.16.2.2 skrll atppc->sc_ecr_intr = atppc_r_ecr(atppc);
627 1.16.2.2 skrll atppc_barrier_r(atppc);
628 1.16.2.2 skrll
629 1.16.2.2 skrll /* Determine cause of interrupt and wake up top half */
630 1.16.2.2 skrll switch (atppc->sc_mode) {
631 1.16.2.2 skrll case ATPPC_MODE_STD:
632 1.16.2.2 skrll /* nAck pulsed for 5 usec, too fast to check reliably, assume */
633 1.16.2.2 skrll atppc->sc_irqstat = ATPPC_IRQ_nACK;
634 1.16.2.2 skrll if (atppc->sc_outb)
635 1.16.2.2 skrll wake_up = WRITER;
636 1.16.2.2 skrll else
637 1.16.2.2 skrll claim = 0;
638 1.16.2.2 skrll break;
639 1.16.2.2 skrll
640 1.16.2.2 skrll case ATPPC_MODE_NIBBLE:
641 1.16.2.2 skrll case ATPPC_MODE_PS2:
642 1.16.2.2 skrll /* nAck is set low by device and then high on ack */
643 1.16.2.2 skrll if (!(atppc->sc_str_intr & nACK)) {
644 1.16.2.2 skrll claim = 0;
645 1.16.2.2 skrll break;
646 1.16.2.2 skrll }
647 1.16.2.2 skrll atppc->sc_irqstat = ATPPC_IRQ_nACK;
648 1.16.2.2 skrll if (atppc->sc_inb)
649 1.16.2.2 skrll wake_up = READER;
650 1.16.2.2 skrll break;
651 1.16.2.2 skrll
652 1.16.2.2 skrll case ATPPC_MODE_ECP:
653 1.16.2.2 skrll case ATPPC_MODE_FAST:
654 1.16.2.2 skrll /* Confirm interrupt cause: these are not pulsed as in nAck. */
655 1.16.2.2 skrll if (atppc->sc_ecr_intr & ATPPC_SERVICE_INTR) {
656 1.16.2.2 skrll if (atppc->sc_ecr_intr & ATPPC_ENABLE_DMA)
657 1.16.2.2 skrll atppc->sc_irqstat |= ATPPC_IRQ_DMA;
658 1.16.2.2 skrll else
659 1.16.2.2 skrll atppc->sc_irqstat |= ATPPC_IRQ_FIFO;
660 1.16.2.2 skrll
661 1.16.2.2 skrll /* Decide where top half will be waiting */
662 1.16.2.2 skrll if (atppc->sc_mode & ATPPC_MODE_ECP) {
663 1.16.2.2 skrll if (atppc->sc_ctr_intr & PCD) {
664 1.16.2.2 skrll if (atppc->sc_inb)
665 1.16.2.2 skrll wake_up = READER;
666 1.16.2.2 skrll else
667 1.16.2.2 skrll claim = 0;
668 1.16.2.2 skrll } else {
669 1.16.2.2 skrll if (atppc->sc_outb)
670 1.16.2.2 skrll wake_up = WRITER;
671 1.16.2.2 skrll else
672 1.16.2.2 skrll claim = 0;
673 1.16.2.2 skrll }
674 1.16.2.2 skrll } else {
675 1.16.2.2 skrll if (atppc->sc_outb)
676 1.16.2.2 skrll wake_up = WRITER;
677 1.16.2.2 skrll else
678 1.16.2.2 skrll claim = 0;
679 1.16.2.2 skrll }
680 1.16.2.2 skrll }
681 1.16.2.2 skrll /* Determine if nFault has occurred */
682 1.16.2.2 skrll if ((atppc->sc_mode & ATPPC_MODE_ECP) &&
683 1.16.2.2 skrll (atppc->sc_ecr_intr & ATPPC_nFAULT_INTR) &&
684 1.16.2.2 skrll !(atppc->sc_str_intr & nFAULT)) {
685 1.16.2.2 skrll
686 1.16.2.2 skrll /* Device is requesting the channel */
687 1.16.2.2 skrll atppc->sc_irqstat |= ATPPC_IRQ_nFAULT;
688 1.16.2.2 skrll claim = 1;
689 1.16.2.2 skrll }
690 1.16.2.2 skrll break;
691 1.16.2.2 skrll
692 1.16.2.2 skrll case ATPPC_MODE_EPP:
693 1.16.2.2 skrll /* nAck pulsed for 5 usec, too fast to check reliably */
694 1.16.2.2 skrll atppc->sc_irqstat = ATPPC_IRQ_nACK;
695 1.16.2.2 skrll if (atppc->sc_inb)
696 1.16.2.2 skrll wake_up = WRITER;
697 1.16.2.2 skrll else if (atppc->sc_outb)
698 1.16.2.2 skrll wake_up = READER;
699 1.16.2.2 skrll else
700 1.16.2.2 skrll claim = 0;
701 1.16.2.2 skrll break;
702 1.16.2.2 skrll
703 1.16.2.2 skrll default:
704 1.16.2.2 skrll panic("%s: chipset is in invalid mode.", dev->dv_xname);
705 1.16.2.2 skrll }
706 1.16.2.2 skrll
707 1.16.2.2 skrll if (claim) {
708 1.16.2.2 skrll switch (wake_up) {
709 1.16.2.2 skrll case NONE:
710 1.16.2.2 skrll break;
711 1.16.2.2 skrll
712 1.16.2.2 skrll case READER:
713 1.16.2.2 skrll wakeup(atppc->sc_inb);
714 1.16.2.2 skrll break;
715 1.16.2.2 skrll
716 1.16.2.2 skrll case WRITER:
717 1.16.2.2 skrll wakeup(atppc->sc_outb);
718 1.16.2.2 skrll break;
719 1.16.2.2 skrll }
720 1.16.2.2 skrll }
721 1.16.2.2 skrll
722 1.16.2.2 skrll ATPPC_UNLOCK(atppc);
723 1.16.2.2 skrll
724 1.16.2.2 skrll /* Call all of the installed handlers */
725 1.16.2.2 skrll if (claim) {
726 1.16.2.2 skrll struct atppc_handler_node * callback;
727 1.16.2.2 skrll SLIST_FOREACH(callback, &(atppc->sc_handler_listhead),
728 1.16.2.2 skrll entries) {
729 1.16.2.2 skrll (*callback->func)(callback->arg);
730 1.16.2.2 skrll }
731 1.16.2.2 skrll }
732 1.16.2.2 skrll
733 1.16.2.2 skrll splx(s);
734 1.16.2.2 skrll
735 1.16.2.2 skrll return claim;
736 1.16.2.2 skrll }
737 1.16.2.2 skrll
738 1.16.2.2 skrll
739 1.16.2.2 skrll /* Functions which support ppbus interface */
740 1.16.2.2 skrll
741 1.16.2.2 skrll
742 1.16.2.2 skrll /* Check EPP mode timeout */
743 1.16.2.2 skrll static int
744 1.16.2.2 skrll atppc_check_epp_timeout(struct device *dev)
745 1.16.2.2 skrll {
746 1.16.2.2 skrll struct atppc_softc *atppc = (struct atppc_softc *)dev;
747 1.16.2.2 skrll int s;
748 1.16.2.2 skrll int error;
749 1.16.2.2 skrll
750 1.16.2.2 skrll s = splatppc();
751 1.16.2.2 skrll ATPPC_LOCK(atppc);
752 1.16.2.2 skrll
753 1.16.2.2 skrll atppc_reset_epp_timeout(dev);
754 1.16.2.2 skrll error = !(atppc_r_str(atppc) & TIMEOUT);
755 1.16.2.2 skrll atppc_barrier_r(atppc);
756 1.16.2.2 skrll
757 1.16.2.2 skrll ATPPC_UNLOCK(atppc);
758 1.16.2.2 skrll splx(s);
759 1.16.2.2 skrll
760 1.16.2.2 skrll return (error);
761 1.16.2.2 skrll }
762 1.16.2.2 skrll
763 1.16.2.2 skrll /*
764 1.16.2.2 skrll * EPP timeout, according to the PC87332 manual
765 1.16.2.2 skrll * Semantics of clearing EPP timeout bit.
766 1.16.2.2 skrll * PC87332 - reading SPP_STR does it...
767 1.16.2.2 skrll * SMC - write 1 to EPP timeout bit XXX
768 1.16.2.2 skrll * Others - (?) write 0 to EPP timeout bit
769 1.16.2.2 skrll */
770 1.16.2.2 skrll static void
771 1.16.2.2 skrll atppc_reset_epp_timeout(struct device *dev)
772 1.16.2.2 skrll {
773 1.16.2.2 skrll struct atppc_softc *atppc = (struct atppc_softc *)dev;
774 1.16.2.2 skrll register unsigned char r;
775 1.16.2.2 skrll
776 1.16.2.2 skrll r = atppc_r_str(atppc);
777 1.16.2.2 skrll atppc_barrier_r(atppc);
778 1.16.2.2 skrll atppc_w_str(atppc, r | 0x1);
779 1.16.2.2 skrll atppc_barrier_w(atppc);
780 1.16.2.2 skrll atppc_w_str(atppc, r & 0xfe);
781 1.16.2.2 skrll atppc_barrier_w(atppc);
782 1.16.2.2 skrll
783 1.16.2.2 skrll return;
784 1.16.2.2 skrll }
785 1.16.2.2 skrll
786 1.16.2.2 skrll
787 1.16.2.2 skrll /* Read from atppc device: returns 0 on success. */
788 1.16.2.2 skrll static int
789 1.16.2.2 skrll atppc_read(struct device *dev, char *buf, int len, int ioflag,
790 1.16.2.2 skrll size_t *cnt)
791 1.16.2.2 skrll {
792 1.16.2.2 skrll struct atppc_softc *atppc = (struct atppc_softc *)dev;
793 1.16.2.2 skrll int error = 0;
794 1.16.2.2 skrll int s;
795 1.16.2.2 skrll
796 1.16.2.2 skrll s = splatppc();
797 1.16.2.2 skrll ATPPC_LOCK(atppc);
798 1.16.2.2 skrll
799 1.16.2.2 skrll *cnt = 0;
800 1.16.2.2 skrll
801 1.16.2.2 skrll /* Initialize buffer */
802 1.16.2.2 skrll atppc->sc_inb = atppc->sc_inbstart = buf;
803 1.16.2.2 skrll atppc->sc_inb_nbytes = len;
804 1.16.2.2 skrll
805 1.16.2.2 skrll /* Initialize device input error state for new operation */
806 1.16.2.2 skrll atppc->sc_inerr = 0;
807 1.16.2.2 skrll
808 1.16.2.2 skrll /* Call appropriate function to read bytes */
809 1.16.2.2 skrll switch(atppc->sc_mode) {
810 1.16.2.2 skrll case ATPPC_MODE_STD:
811 1.16.2.2 skrll case ATPPC_MODE_FAST:
812 1.16.2.2 skrll error = ENODEV;
813 1.16.2.2 skrll break;
814 1.16.2.2 skrll
815 1.16.2.2 skrll case ATPPC_MODE_NIBBLE:
816 1.16.2.2 skrll atppc_nibble_read(atppc);
817 1.16.2.2 skrll break;
818 1.16.2.2 skrll
819 1.16.2.2 skrll case ATPPC_MODE_PS2:
820 1.16.2.2 skrll atppc_byte_read(atppc);
821 1.16.2.2 skrll break;
822 1.16.2.2 skrll
823 1.16.2.2 skrll case ATPPC_MODE_ECP:
824 1.16.2.2 skrll atppc_ecp_read(atppc);
825 1.16.2.2 skrll break;
826 1.16.2.2 skrll
827 1.16.2.2 skrll case ATPPC_MODE_EPP:
828 1.16.2.2 skrll atppc_epp_read(atppc);
829 1.16.2.2 skrll break;
830 1.16.2.2 skrll
831 1.16.2.2 skrll default:
832 1.16.2.2 skrll panic("%s(%s): chipset in invalid mode.\n", __func__,
833 1.16.2.2 skrll dev->dv_xname);
834 1.16.2.2 skrll }
835 1.16.2.2 skrll
836 1.16.2.2 skrll /* Update counter*/
837 1.16.2.2 skrll *cnt = (atppc->sc_inbstart - atppc->sc_inb);
838 1.16.2.2 skrll
839 1.16.2.2 skrll /* Reset buffer */
840 1.16.2.2 skrll atppc->sc_inb = atppc->sc_inbstart = NULL;
841 1.16.2.2 skrll atppc->sc_inb_nbytes = 0;
842 1.16.2.2 skrll
843 1.16.2.2 skrll if (!(error))
844 1.16.2.2 skrll error = atppc->sc_inerr;
845 1.16.2.2 skrll
846 1.16.2.2 skrll ATPPC_UNLOCK(atppc);
847 1.16.2.2 skrll splx(s);
848 1.16.2.2 skrll
849 1.16.2.2 skrll return (error);
850 1.16.2.2 skrll }
851 1.16.2.2 skrll
852 1.16.2.2 skrll /* Write to atppc device: returns 0 on success. */
853 1.16.2.2 skrll static int
854 1.16.2.2 skrll atppc_write(struct device *dev, char *buf, int len, int ioflag, size_t *cnt)
855 1.16.2.2 skrll {
856 1.16.2.2 skrll struct atppc_softc * const atppc = (struct atppc_softc *)dev;
857 1.16.2.2 skrll int error = 0;
858 1.16.2.2 skrll int s;
859 1.16.2.2 skrll
860 1.16.2.2 skrll *cnt = 0;
861 1.16.2.2 skrll
862 1.16.2.2 skrll s = splatppc();
863 1.16.2.2 skrll ATPPC_LOCK(atppc);
864 1.16.2.2 skrll
865 1.16.2.2 skrll /* Set up line buffer */
866 1.16.2.2 skrll atppc->sc_outb = atppc->sc_outbstart = buf;
867 1.16.2.2 skrll atppc->sc_outb_nbytes = len;
868 1.16.2.2 skrll
869 1.16.2.2 skrll /* Initialize device output error state for new operation */
870 1.16.2.2 skrll atppc->sc_outerr = 0;
871 1.16.2.2 skrll
872 1.16.2.2 skrll /* Call appropriate function to write bytes */
873 1.16.2.2 skrll switch (atppc->sc_mode) {
874 1.16.2.2 skrll case ATPPC_MODE_STD:
875 1.16.2.2 skrll atppc_std_write(atppc);
876 1.16.2.2 skrll break;
877 1.16.2.2 skrll
878 1.16.2.2 skrll case ATPPC_MODE_NIBBLE:
879 1.16.2.2 skrll case ATPPC_MODE_PS2:
880 1.16.2.2 skrll error = ENODEV;
881 1.16.2.2 skrll break;
882 1.16.2.2 skrll
883 1.16.2.2 skrll case ATPPC_MODE_FAST:
884 1.16.2.2 skrll case ATPPC_MODE_ECP:
885 1.16.2.2 skrll atppc_fifo_write(atppc);
886 1.16.2.2 skrll break;
887 1.16.2.2 skrll
888 1.16.2.2 skrll case ATPPC_MODE_EPP:
889 1.16.2.2 skrll atppc_epp_write(atppc);
890 1.16.2.2 skrll break;
891 1.16.2.2 skrll
892 1.16.2.2 skrll default:
893 1.16.2.2 skrll panic("%s(%s): chipset in invalid mode.\n", __func__,
894 1.16.2.2 skrll dev->dv_xname);
895 1.16.2.2 skrll }
896 1.16.2.2 skrll
897 1.16.2.2 skrll /* Update counter*/
898 1.16.2.2 skrll *cnt = (atppc->sc_outbstart - atppc->sc_outb);
899 1.16.2.2 skrll
900 1.16.2.2 skrll /* Reset output buffer */
901 1.16.2.2 skrll atppc->sc_outb = atppc->sc_outbstart = NULL;
902 1.16.2.2 skrll atppc->sc_outb_nbytes = 0;
903 1.16.2.2 skrll
904 1.16.2.2 skrll if (!(error))
905 1.16.2.2 skrll error = atppc->sc_outerr;
906 1.16.2.2 skrll
907 1.16.2.2 skrll ATPPC_UNLOCK(atppc);
908 1.16.2.2 skrll splx(s);
909 1.16.2.2 skrll
910 1.16.2.2 skrll return (error);
911 1.16.2.2 skrll }
912 1.16.2.2 skrll
913 1.16.2.2 skrll /*
914 1.16.2.2 skrll * Set mode of chipset to mode argument. Modes not supported are ignored. If
915 1.16.2.2 skrll * multiple modes are flagged, the mode is not changed. Mode's are those
916 1.16.2.2 skrll * defined for ppbus_softc.sc_mode in ppbus_conf.h. Only ECP-capable chipsets
917 1.16.2.2 skrll * can change their mode of operation. However, ALL operation modes support
918 1.16.2.2 skrll * centronics mode and nibble mode. Modes determine both hardware AND software
919 1.16.2.2 skrll * behaviour.
920 1.16.2.2 skrll * NOTE: the mode for ECP should only be changed when the channel is in
921 1.16.2.2 skrll * forward idle mode. This function does not make sure FIFO's have flushed or
922 1.16.2.2 skrll * any consistency checks.
923 1.16.2.2 skrll */
924 1.16.2.2 skrll static int
925 1.16.2.2 skrll atppc_setmode(struct device *dev, int mode)
926 1.16.2.2 skrll {
927 1.16.2.2 skrll struct atppc_softc *atppc = (struct atppc_softc *)dev;
928 1.16.2.2 skrll u_int8_t ecr;
929 1.16.2.2 skrll u_int8_t chipset_mode;
930 1.16.2.2 skrll int s;
931 1.16.2.2 skrll int rval = 0;
932 1.16.2.2 skrll
933 1.16.2.2 skrll s = splatppc();
934 1.16.2.2 skrll ATPPC_LOCK(atppc);
935 1.16.2.2 skrll
936 1.16.2.2 skrll /* If ECP capable, configure ecr register */
937 1.16.2.2 skrll if (atppc->sc_has & ATPPC_HAS_ECP) {
938 1.16.2.2 skrll /* Read ECR with mode masked out */
939 1.16.2.2 skrll ecr = (atppc_r_ecr(atppc) & 0x1f);
940 1.16.2.2 skrll atppc_barrier_r(atppc);
941 1.16.2.2 skrll
942 1.16.2.2 skrll switch (mode) {
943 1.16.2.2 skrll case PPBUS_ECP:
944 1.16.2.2 skrll /* Set ECP mode */
945 1.16.2.2 skrll ecr |= ATPPC_ECR_ECP;
946 1.16.2.2 skrll chipset_mode = ATPPC_MODE_ECP;
947 1.16.2.2 skrll break;
948 1.16.2.2 skrll
949 1.16.2.2 skrll case PPBUS_EPP:
950 1.16.2.2 skrll /* Set EPP mode */
951 1.16.2.2 skrll if (atppc->sc_has & ATPPC_HAS_EPP) {
952 1.16.2.2 skrll ecr |= ATPPC_ECR_EPP;
953 1.16.2.2 skrll chipset_mode = ATPPC_MODE_EPP;
954 1.16.2.2 skrll } else {
955 1.16.2.2 skrll rval = ENODEV;
956 1.16.2.2 skrll goto end;
957 1.16.2.2 skrll }
958 1.16.2.2 skrll break;
959 1.16.2.2 skrll
960 1.16.2.2 skrll case PPBUS_FAST:
961 1.16.2.2 skrll /* Set fast centronics mode */
962 1.16.2.2 skrll ecr |= ATPPC_ECR_FIFO;
963 1.16.2.2 skrll chipset_mode = ATPPC_MODE_FAST;
964 1.16.2.2 skrll break;
965 1.16.2.2 skrll
966 1.16.2.2 skrll case PPBUS_PS2:
967 1.16.2.2 skrll /* Set PS2 mode */
968 1.16.2.2 skrll ecr |= ATPPC_ECR_PS2;
969 1.16.2.2 skrll chipset_mode = ATPPC_MODE_PS2;
970 1.16.2.2 skrll break;
971 1.16.2.2 skrll
972 1.16.2.2 skrll case PPBUS_COMPATIBLE:
973 1.16.2.2 skrll /* Set standard mode */
974 1.16.2.2 skrll ecr |= ATPPC_ECR_STD;
975 1.16.2.2 skrll chipset_mode = ATPPC_MODE_STD;
976 1.16.2.2 skrll break;
977 1.16.2.2 skrll
978 1.16.2.2 skrll case PPBUS_NIBBLE:
979 1.16.2.2 skrll /* Set nibble mode: uses chipset standard mode */
980 1.16.2.2 skrll ecr |= ATPPC_ECR_STD;
981 1.16.2.2 skrll chipset_mode = ATPPC_MODE_NIBBLE;
982 1.16.2.2 skrll break;
983 1.16.2.2 skrll
984 1.16.2.2 skrll default:
985 1.16.2.2 skrll /* Invalid mode specified for ECP chip */
986 1.16.2.2 skrll ATPPC_DPRINTF(("%s(%s): invalid mode passed as "
987 1.16.2.2 skrll "argument.\n", __func__, dev->dv_xname));
988 1.16.2.2 skrll rval = ENODEV;
989 1.16.2.2 skrll goto end;
990 1.16.2.2 skrll }
991 1.16.2.2 skrll
992 1.16.2.2 skrll /* Switch to byte mode to be able to change modes. */
993 1.16.2.2 skrll atppc_w_ecr(atppc, ATPPC_ECR_PS2);
994 1.16.2.2 skrll atppc_barrier_w(atppc);
995 1.16.2.2 skrll
996 1.16.2.2 skrll /* Update mode */
997 1.16.2.2 skrll atppc_w_ecr(atppc, ecr);
998 1.16.2.2 skrll atppc_barrier_w(atppc);
999 1.16.2.2 skrll } else {
1000 1.16.2.2 skrll switch (mode) {
1001 1.16.2.2 skrll case PPBUS_EPP:
1002 1.16.2.2 skrll if (atppc->sc_has & ATPPC_HAS_EPP) {
1003 1.16.2.2 skrll chipset_mode = ATPPC_MODE_EPP;
1004 1.16.2.2 skrll } else {
1005 1.16.2.2 skrll rval = ENODEV;
1006 1.16.2.2 skrll goto end;
1007 1.16.2.2 skrll }
1008 1.16.2.2 skrll break;
1009 1.16.2.2 skrll
1010 1.16.2.2 skrll case PPBUS_PS2:
1011 1.16.2.2 skrll if (atppc->sc_has & ATPPC_HAS_PS2) {
1012 1.16.2.2 skrll chipset_mode = ATPPC_MODE_PS2;
1013 1.16.2.2 skrll } else {
1014 1.16.2.2 skrll rval = ENODEV;
1015 1.16.2.2 skrll goto end;
1016 1.16.2.2 skrll }
1017 1.16.2.2 skrll break;
1018 1.16.2.2 skrll
1019 1.16.2.2 skrll case PPBUS_NIBBLE:
1020 1.16.2.2 skrll /* Set nibble mode (virtual) */
1021 1.16.2.2 skrll chipset_mode = ATPPC_MODE_NIBBLE;
1022 1.16.2.2 skrll break;
1023 1.16.2.2 skrll
1024 1.16.2.2 skrll case PPBUS_COMPATIBLE:
1025 1.16.2.2 skrll chipset_mode = ATPPC_MODE_STD;
1026 1.16.2.2 skrll break;
1027 1.16.2.2 skrll
1028 1.16.2.2 skrll case PPBUS_ECP:
1029 1.16.2.2 skrll rval = ENODEV;
1030 1.16.2.2 skrll goto end;
1031 1.16.2.2 skrll
1032 1.16.2.2 skrll default:
1033 1.16.2.2 skrll ATPPC_DPRINTF(("%s(%s): invalid mode passed as "
1034 1.16.2.2 skrll "argument.\n", __func__, dev->dv_xname));
1035 1.16.2.2 skrll rval = ENODEV;
1036 1.16.2.2 skrll goto end;
1037 1.16.2.2 skrll }
1038 1.16.2.2 skrll }
1039 1.16.2.2 skrll
1040 1.16.2.2 skrll atppc->sc_mode = chipset_mode;
1041 1.16.2.2 skrll if (chipset_mode == ATPPC_MODE_PS2) {
1042 1.16.2.2 skrll /* Set direction bit to reverse */
1043 1.16.2.2 skrll ecr = atppc_r_ctr(atppc);
1044 1.16.2.2 skrll atppc_barrier_r(atppc);
1045 1.16.2.2 skrll ecr |= PCD;
1046 1.16.2.2 skrll atppc_w_ctr(atppc, ecr);
1047 1.16.2.2 skrll atppc_barrier_w(atppc);
1048 1.16.2.2 skrll }
1049 1.16.2.2 skrll
1050 1.16.2.2 skrll end:
1051 1.16.2.2 skrll ATPPC_UNLOCK(atppc);
1052 1.16.2.2 skrll splx(s);
1053 1.16.2.2 skrll
1054 1.16.2.2 skrll return rval;
1055 1.16.2.2 skrll }
1056 1.16.2.2 skrll
1057 1.16.2.2 skrll /* Get the current mode of chipset */
1058 1.16.2.2 skrll static int
1059 1.16.2.2 skrll atppc_getmode(struct device *dev)
1060 1.16.2.2 skrll {
1061 1.16.2.2 skrll struct atppc_softc *atppc = (struct atppc_softc *)dev;
1062 1.16.2.2 skrll int mode;
1063 1.16.2.2 skrll int s;
1064 1.16.2.2 skrll
1065 1.16.2.2 skrll s = splatppc();
1066 1.16.2.2 skrll ATPPC_LOCK(atppc);
1067 1.16.2.2 skrll
1068 1.16.2.2 skrll /* The chipset can only be in one mode at a time logically */
1069 1.16.2.2 skrll switch (atppc->sc_mode) {
1070 1.16.2.2 skrll case ATPPC_MODE_ECP:
1071 1.16.2.2 skrll mode = PPBUS_ECP;
1072 1.16.2.2 skrll break;
1073 1.16.2.2 skrll
1074 1.16.2.2 skrll case ATPPC_MODE_EPP:
1075 1.16.2.2 skrll mode = PPBUS_EPP;
1076 1.16.2.2 skrll break;
1077 1.16.2.2 skrll
1078 1.16.2.2 skrll case ATPPC_MODE_PS2:
1079 1.16.2.2 skrll mode = PPBUS_PS2;
1080 1.16.2.2 skrll break;
1081 1.16.2.2 skrll
1082 1.16.2.2 skrll case ATPPC_MODE_STD:
1083 1.16.2.2 skrll mode = PPBUS_COMPATIBLE;
1084 1.16.2.2 skrll break;
1085 1.16.2.2 skrll
1086 1.16.2.2 skrll case ATPPC_MODE_NIBBLE:
1087 1.16.2.2 skrll mode = PPBUS_NIBBLE;
1088 1.16.2.2 skrll break;
1089 1.16.2.2 skrll
1090 1.16.2.2 skrll case ATPPC_MODE_FAST:
1091 1.16.2.2 skrll mode = PPBUS_FAST;
1092 1.16.2.2 skrll break;
1093 1.16.2.2 skrll
1094 1.16.2.2 skrll default:
1095 1.16.2.2 skrll panic("%s(%s): device is in invalid mode!", __func__,
1096 1.16.2.2 skrll dev->dv_xname);
1097 1.16.2.2 skrll break;
1098 1.16.2.2 skrll }
1099 1.16.2.2 skrll
1100 1.16.2.2 skrll ATPPC_UNLOCK(atppc);
1101 1.16.2.2 skrll splx(s);
1102 1.16.2.2 skrll
1103 1.16.2.2 skrll return mode;
1104 1.16.2.2 skrll }
1105 1.16.2.2 skrll
1106 1.16.2.2 skrll
1107 1.16.2.2 skrll /* Wait for FIFO buffer to empty for ECP-capable chipset */
1108 1.16.2.2 skrll static void
1109 1.16.2.2 skrll atppc_ecp_sync(struct device *dev)
1110 1.16.2.2 skrll {
1111 1.16.2.2 skrll struct atppc_softc *atppc = (struct atppc_softc *)dev;
1112 1.16.2.2 skrll int i;
1113 1.16.2.2 skrll int s;
1114 1.16.2.2 skrll u_int8_t r;
1115 1.16.2.2 skrll
1116 1.16.2.2 skrll s = splatppc();
1117 1.16.2.2 skrll ATPPC_LOCK(atppc);
1118 1.16.2.2 skrll
1119 1.16.2.2 skrll /*
1120 1.16.2.2 skrll * Only wait for FIFO to empty if mode is chipset is ECP-capable AND
1121 1.16.2.2 skrll * the mode is either ECP or Fast Centronics.
1122 1.16.2.2 skrll */
1123 1.16.2.2 skrll r = atppc_r_ecr(atppc);
1124 1.16.2.2 skrll atppc_barrier_r(atppc);
1125 1.16.2.2 skrll r &= 0xe0;
1126 1.16.2.2 skrll if (!(atppc->sc_has & ATPPC_HAS_ECP) || ((r != ATPPC_ECR_ECP)
1127 1.16.2.2 skrll && (r != ATPPC_ECR_FIFO))) {
1128 1.16.2.2 skrll goto end;
1129 1.16.2.2 skrll }
1130 1.16.2.2 skrll
1131 1.16.2.2 skrll /* Wait for FIFO to empty */
1132 1.16.2.2 skrll for (i = 0; i < ((MAXBUSYWAIT/hz) * 1000000); i += 100) {
1133 1.16.2.2 skrll r = atppc_r_ecr(atppc);
1134 1.16.2.2 skrll atppc_barrier_r(atppc);
1135 1.16.2.2 skrll if (r & ATPPC_FIFO_EMPTY) {
1136 1.16.2.2 skrll goto end;
1137 1.16.2.2 skrll }
1138 1.16.2.2 skrll delay(100); /* Supposed to be a 100 usec delay */
1139 1.16.2.2 skrll }
1140 1.16.2.2 skrll
1141 1.16.2.2 skrll ATPPC_DPRINTF(("%s: ECP sync failed, data still in FIFO.\n",
1142 1.16.2.2 skrll dev->dv_xname));
1143 1.16.2.2 skrll
1144 1.16.2.2 skrll end:
1145 1.16.2.2 skrll ATPPC_UNLOCK(atppc);
1146 1.16.2.2 skrll splx(s);
1147 1.16.2.2 skrll
1148 1.16.2.2 skrll return;
1149 1.16.2.2 skrll }
1150 1.16.2.2 skrll
1151 1.16.2.2 skrll /* Execute a microsequence to handle fast I/O operations. */
1152 1.16.2.2 skrll static int
1153 1.16.2.2 skrll atppc_exec_microseq(struct device *dev, struct ppbus_microseq **p_msq)
1154 1.16.2.2 skrll {
1155 1.16.2.2 skrll struct atppc_softc *atppc = (struct atppc_softc *)dev;
1156 1.16.2.2 skrll struct ppbus_microseq *mi = *p_msq;
1157 1.16.2.2 skrll char cc, *p;
1158 1.16.2.2 skrll int i, iter, len;
1159 1.16.2.2 skrll int error;
1160 1.16.2.2 skrll int s;
1161 1.16.2.2 skrll register int reg;
1162 1.16.2.2 skrll register unsigned char mask;
1163 1.16.2.2 skrll register int accum = 0;
1164 1.16.2.2 skrll register char *ptr = NULL;
1165 1.16.2.2 skrll struct ppbus_microseq *stack = NULL;
1166 1.16.2.2 skrll
1167 1.16.2.2 skrll s = splatppc();
1168 1.16.2.2 skrll ATPPC_LOCK(atppc);
1169 1.16.2.2 skrll
1170 1.16.2.2 skrll /* microsequence registers are equivalent to PC-like port registers */
1171 1.16.2.2 skrll
1172 1.16.2.2 skrll #define r_reg(register,atppc) bus_space_read_1((atppc)->sc_iot, \
1173 1.16.2.2 skrll (atppc)->sc_ioh, (register))
1174 1.16.2.2 skrll #define w_reg(register, atppc, byte) bus_space_write_1((atppc)->sc_iot, \
1175 1.16.2.2 skrll (atppc)->sc_ioh, (register), (byte))
1176 1.16.2.2 skrll
1177 1.16.2.2 skrll /* Loop until microsequence execution finishes (ending op code) */
1178 1.16.2.2 skrll for (;;) {
1179 1.16.2.2 skrll switch (mi->opcode) {
1180 1.16.2.2 skrll case MS_OP_RSET:
1181 1.16.2.2 skrll cc = r_reg(mi->arg[0].i, atppc);
1182 1.16.2.2 skrll atppc_barrier_r(atppc);
1183 1.16.2.2 skrll cc &= (char)mi->arg[2].i; /* clear mask */
1184 1.16.2.2 skrll cc |= (char)mi->arg[1].i; /* assert mask */
1185 1.16.2.2 skrll w_reg(mi->arg[0].i, atppc, cc);
1186 1.16.2.2 skrll atppc_barrier_w(atppc);
1187 1.16.2.2 skrll mi++;
1188 1.16.2.2 skrll break;
1189 1.16.2.2 skrll
1190 1.16.2.2 skrll case MS_OP_RASSERT_P:
1191 1.16.2.2 skrll reg = mi->arg[1].i;
1192 1.16.2.2 skrll ptr = atppc->sc_ptr;
1193 1.16.2.2 skrll
1194 1.16.2.2 skrll if ((len = mi->arg[0].i) == MS_ACCUM) {
1195 1.16.2.2 skrll accum = atppc->sc_accum;
1196 1.16.2.2 skrll for (; accum; accum--) {
1197 1.16.2.2 skrll w_reg(reg, atppc, *ptr++);
1198 1.16.2.2 skrll atppc_barrier_w(atppc);
1199 1.16.2.2 skrll }
1200 1.16.2.2 skrll atppc->sc_accum = accum;
1201 1.16.2.2 skrll } else {
1202 1.16.2.2 skrll for (i = 0; i < len; i++) {
1203 1.16.2.2 skrll w_reg(reg, atppc, *ptr++);
1204 1.16.2.2 skrll atppc_barrier_w(atppc);
1205 1.16.2.2 skrll }
1206 1.16.2.2 skrll }
1207 1.16.2.2 skrll
1208 1.16.2.2 skrll atppc->sc_ptr = ptr;
1209 1.16.2.2 skrll mi++;
1210 1.16.2.2 skrll break;
1211 1.16.2.2 skrll
1212 1.16.2.2 skrll case MS_OP_RFETCH_P:
1213 1.16.2.2 skrll reg = mi->arg[1].i;
1214 1.16.2.2 skrll mask = (char)mi->arg[2].i;
1215 1.16.2.2 skrll ptr = atppc->sc_ptr;
1216 1.16.2.2 skrll
1217 1.16.2.2 skrll if ((len = mi->arg[0].i) == MS_ACCUM) {
1218 1.16.2.2 skrll accum = atppc->sc_accum;
1219 1.16.2.2 skrll for (; accum; accum--) {
1220 1.16.2.2 skrll *ptr++ = r_reg(reg, atppc) & mask;
1221 1.16.2.2 skrll atppc_barrier_r(atppc);
1222 1.16.2.2 skrll }
1223 1.16.2.2 skrll atppc->sc_accum = accum;
1224 1.16.2.2 skrll } else {
1225 1.16.2.2 skrll for (i = 0; i < len; i++) {
1226 1.16.2.2 skrll *ptr++ = r_reg(reg, atppc) & mask;
1227 1.16.2.2 skrll atppc_barrier_r(atppc);
1228 1.16.2.2 skrll }
1229 1.16.2.2 skrll }
1230 1.16.2.2 skrll
1231 1.16.2.2 skrll atppc->sc_ptr = ptr;
1232 1.16.2.2 skrll mi++;
1233 1.16.2.2 skrll break;
1234 1.16.2.2 skrll
1235 1.16.2.2 skrll case MS_OP_RFETCH:
1236 1.16.2.2 skrll *((char *)mi->arg[2].p) = r_reg(mi->arg[0].i, atppc) &
1237 1.16.2.2 skrll (char)mi->arg[1].i;
1238 1.16.2.2 skrll atppc_barrier_r(atppc);
1239 1.16.2.2 skrll mi++;
1240 1.16.2.2 skrll break;
1241 1.16.2.2 skrll
1242 1.16.2.2 skrll case MS_OP_RASSERT:
1243 1.16.2.2 skrll case MS_OP_DELAY:
1244 1.16.2.2 skrll /* let's suppose the next instr. is the same */
1245 1.16.2.2 skrll do {
1246 1.16.2.2 skrll for (;mi->opcode == MS_OP_RASSERT; mi++) {
1247 1.16.2.2 skrll w_reg(mi->arg[0].i, atppc,
1248 1.16.2.2 skrll (char)mi->arg[1].i);
1249 1.16.2.2 skrll atppc_barrier_w(atppc);
1250 1.16.2.2 skrll }
1251 1.16.2.2 skrll
1252 1.16.2.2 skrll for (;mi->opcode == MS_OP_DELAY; mi++) {
1253 1.16.2.2 skrll delay(mi->arg[0].i);
1254 1.16.2.2 skrll }
1255 1.16.2.2 skrll } while (mi->opcode == MS_OP_RASSERT);
1256 1.16.2.2 skrll break;
1257 1.16.2.2 skrll
1258 1.16.2.2 skrll case MS_OP_ADELAY:
1259 1.16.2.2 skrll if (mi->arg[0].i) {
1260 1.16.2.2 skrll tsleep(atppc, PPBUSPRI, "atppcdelay",
1261 1.16.2.2 skrll mi->arg[0].i * (hz/1000));
1262 1.16.2.2 skrll }
1263 1.16.2.2 skrll mi++;
1264 1.16.2.2 skrll break;
1265 1.16.2.2 skrll
1266 1.16.2.2 skrll case MS_OP_TRIG:
1267 1.16.2.2 skrll reg = mi->arg[0].i;
1268 1.16.2.2 skrll iter = mi->arg[1].i;
1269 1.16.2.2 skrll p = (char *)mi->arg[2].p;
1270 1.16.2.2 skrll
1271 1.16.2.2 skrll /* XXX delay limited to 255 us */
1272 1.16.2.2 skrll for (i = 0; i < iter; i++) {
1273 1.16.2.2 skrll w_reg(reg, atppc, *p++);
1274 1.16.2.2 skrll atppc_barrier_w(atppc);
1275 1.16.2.2 skrll delay((unsigned char)*p++);
1276 1.16.2.2 skrll }
1277 1.16.2.2 skrll
1278 1.16.2.2 skrll mi++;
1279 1.16.2.2 skrll break;
1280 1.16.2.2 skrll
1281 1.16.2.2 skrll case MS_OP_SET:
1282 1.16.2.2 skrll atppc->sc_accum = mi->arg[0].i;
1283 1.16.2.2 skrll mi++;
1284 1.16.2.2 skrll break;
1285 1.16.2.2 skrll
1286 1.16.2.2 skrll case MS_OP_DBRA:
1287 1.16.2.2 skrll if (--atppc->sc_accum > 0) {
1288 1.16.2.2 skrll mi += mi->arg[0].i;
1289 1.16.2.2 skrll }
1290 1.16.2.2 skrll
1291 1.16.2.2 skrll mi++;
1292 1.16.2.2 skrll break;
1293 1.16.2.2 skrll
1294 1.16.2.2 skrll case MS_OP_BRSET:
1295 1.16.2.2 skrll cc = atppc_r_str(atppc);
1296 1.16.2.2 skrll atppc_barrier_r(atppc);
1297 1.16.2.2 skrll if ((cc & (char)mi->arg[0].i) == (char)mi->arg[0].i) {
1298 1.16.2.2 skrll mi += mi->arg[1].i;
1299 1.16.2.2 skrll }
1300 1.16.2.2 skrll mi++;
1301 1.16.2.2 skrll break;
1302 1.16.2.2 skrll
1303 1.16.2.2 skrll case MS_OP_BRCLEAR:
1304 1.16.2.2 skrll cc = atppc_r_str(atppc);
1305 1.16.2.2 skrll atppc_barrier_r(atppc);
1306 1.16.2.2 skrll if ((cc & (char)mi->arg[0].i) == 0) {
1307 1.16.2.2 skrll mi += mi->arg[1].i;
1308 1.16.2.2 skrll }
1309 1.16.2.2 skrll mi++;
1310 1.16.2.2 skrll break;
1311 1.16.2.2 skrll
1312 1.16.2.2 skrll case MS_OP_BRSTAT:
1313 1.16.2.2 skrll cc = atppc_r_str(atppc);
1314 1.16.2.2 skrll atppc_barrier_r(atppc);
1315 1.16.2.2 skrll if ((cc & ((char)mi->arg[0].i | (char)mi->arg[1].i)) ==
1316 1.16.2.2 skrll (char)mi->arg[0].i) {
1317 1.16.2.2 skrll mi += mi->arg[2].i;
1318 1.16.2.2 skrll }
1319 1.16.2.2 skrll mi++;
1320 1.16.2.2 skrll break;
1321 1.16.2.2 skrll
1322 1.16.2.2 skrll case MS_OP_C_CALL:
1323 1.16.2.2 skrll /*
1324 1.16.2.2 skrll * If the C call returns !0 then end the microseq.
1325 1.16.2.2 skrll * The current state of ptr is passed to the C function
1326 1.16.2.2 skrll */
1327 1.16.2.2 skrll if ((error = mi->arg[0].f(mi->arg[1].p,
1328 1.16.2.2 skrll atppc->sc_ptr))) {
1329 1.16.2.2 skrll ATPPC_UNLOCK(atppc);
1330 1.16.2.2 skrll splx(s);
1331 1.16.2.2 skrll return (error);
1332 1.16.2.2 skrll }
1333 1.16.2.2 skrll mi++;
1334 1.16.2.2 skrll break;
1335 1.16.2.2 skrll
1336 1.16.2.2 skrll case MS_OP_PTR:
1337 1.16.2.2 skrll atppc->sc_ptr = (char *)mi->arg[0].p;
1338 1.16.2.2 skrll mi++;
1339 1.16.2.2 skrll break;
1340 1.16.2.2 skrll
1341 1.16.2.2 skrll case MS_OP_CALL:
1342 1.16.2.2 skrll if (stack) {
1343 1.16.2.2 skrll panic("%s - %s: too much calls", dev->dv_xname,
1344 1.16.2.2 skrll __func__);
1345 1.16.2.2 skrll }
1346 1.16.2.2 skrll
1347 1.16.2.2 skrll if (mi->arg[0].p) {
1348 1.16.2.2 skrll /* store state of the actual microsequence */
1349 1.16.2.2 skrll stack = mi;
1350 1.16.2.2 skrll
1351 1.16.2.2 skrll /* jump to the new microsequence */
1352 1.16.2.2 skrll mi = (struct ppbus_microseq *)mi->arg[0].p;
1353 1.16.2.2 skrll } else {
1354 1.16.2.2 skrll mi++;
1355 1.16.2.2 skrll }
1356 1.16.2.2 skrll break;
1357 1.16.2.2 skrll
1358 1.16.2.2 skrll case MS_OP_SUBRET:
1359 1.16.2.2 skrll /* retrieve microseq and pc state before the call */
1360 1.16.2.2 skrll mi = stack;
1361 1.16.2.2 skrll
1362 1.16.2.2 skrll /* reset the stack */
1363 1.16.2.2 skrll stack = 0;
1364 1.16.2.2 skrll
1365 1.16.2.2 skrll /* XXX return code */
1366 1.16.2.2 skrll
1367 1.16.2.2 skrll mi++;
1368 1.16.2.2 skrll break;
1369 1.16.2.2 skrll
1370 1.16.2.2 skrll case MS_OP_PUT:
1371 1.16.2.2 skrll case MS_OP_GET:
1372 1.16.2.2 skrll case MS_OP_RET:
1373 1.16.2.2 skrll /*
1374 1.16.2.2 skrll * Can't return to atppc level during the execution
1375 1.16.2.2 skrll * of a submicrosequence.
1376 1.16.2.2 skrll */
1377 1.16.2.2 skrll if (stack) {
1378 1.16.2.2 skrll panic("%s: cannot return to atppc level",
1379 1.16.2.2 skrll __func__);
1380 1.16.2.2 skrll }
1381 1.16.2.2 skrll /* update pc for atppc level of execution */
1382 1.16.2.2 skrll *p_msq = mi;
1383 1.16.2.2 skrll
1384 1.16.2.2 skrll ATPPC_UNLOCK(atppc);
1385 1.16.2.2 skrll splx(s);
1386 1.16.2.2 skrll return (0);
1387 1.16.2.2 skrll break;
1388 1.16.2.2 skrll
1389 1.16.2.2 skrll default:
1390 1.16.2.2 skrll panic("%s: unknown microsequence "
1391 1.16.2.2 skrll "opcode 0x%x", __func__, mi->opcode);
1392 1.16.2.2 skrll break;
1393 1.16.2.2 skrll }
1394 1.16.2.2 skrll }
1395 1.16.2.2 skrll
1396 1.16.2.2 skrll /* Should not be reached! */
1397 1.16.2.2 skrll #ifdef ATPPC_DEBUG
1398 1.16.2.2 skrll panic("%s: unexpected code reached!\n", __func__);
1399 1.16.2.2 skrll #endif
1400 1.16.2.2 skrll }
1401 1.16.2.2 skrll
1402 1.16.2.2 skrll /* General I/O routine */
1403 1.16.2.2 skrll static u_int8_t
1404 1.16.2.2 skrll atppc_io(struct device *dev, int iop, u_char *addr, int cnt, u_char byte)
1405 1.16.2.2 skrll {
1406 1.16.2.2 skrll struct atppc_softc *atppc = (struct atppc_softc *)dev;
1407 1.16.2.2 skrll u_int8_t val = 0;
1408 1.16.2.2 skrll int s;
1409 1.16.2.2 skrll
1410 1.16.2.2 skrll s = splatppc();
1411 1.16.2.2 skrll ATPPC_LOCK(atppc);
1412 1.16.2.2 skrll
1413 1.16.2.2 skrll switch (iop) {
1414 1.16.2.2 skrll case PPBUS_OUTSB_EPP:
1415 1.16.2.2 skrll bus_space_write_multi_1(atppc->sc_iot, atppc->sc_ioh,
1416 1.16.2.2 skrll ATPPC_EPP_DATA, addr, cnt);
1417 1.16.2.2 skrll break;
1418 1.16.2.2 skrll case PPBUS_OUTSW_EPP:
1419 1.16.2.2 skrll bus_space_write_multi_2(atppc->sc_iot, atppc->sc_ioh,
1420 1.16.2.2 skrll ATPPC_EPP_DATA, (u_int16_t *)addr, cnt);
1421 1.16.2.2 skrll break;
1422 1.16.2.2 skrll case PPBUS_OUTSL_EPP:
1423 1.16.2.2 skrll bus_space_write_multi_4(atppc->sc_iot, atppc->sc_ioh,
1424 1.16.2.2 skrll ATPPC_EPP_DATA, (u_int32_t *)addr, cnt);
1425 1.16.2.2 skrll break;
1426 1.16.2.2 skrll case PPBUS_INSB_EPP:
1427 1.16.2.2 skrll bus_space_read_multi_1(atppc->sc_iot, atppc->sc_ioh,
1428 1.16.2.2 skrll ATPPC_EPP_DATA, addr, cnt);
1429 1.16.2.2 skrll break;
1430 1.16.2.2 skrll case PPBUS_INSW_EPP:
1431 1.16.2.2 skrll bus_space_read_multi_2(atppc->sc_iot, atppc->sc_ioh,
1432 1.16.2.2 skrll ATPPC_EPP_DATA, (u_int16_t *)addr, cnt);
1433 1.16.2.2 skrll break;
1434 1.16.2.2 skrll case PPBUS_INSL_EPP:
1435 1.16.2.2 skrll bus_space_read_multi_4(atppc->sc_iot, atppc->sc_ioh,
1436 1.16.2.2 skrll ATPPC_EPP_DATA, (u_int32_t *)addr, cnt);
1437 1.16.2.2 skrll break;
1438 1.16.2.2 skrll case PPBUS_RDTR:
1439 1.16.2.2 skrll val = (atppc_r_dtr(atppc));
1440 1.16.2.2 skrll break;
1441 1.16.2.2 skrll case PPBUS_RSTR:
1442 1.16.2.2 skrll val = (atppc_r_str(atppc));
1443 1.16.2.2 skrll break;
1444 1.16.2.2 skrll case PPBUS_RCTR:
1445 1.16.2.2 skrll val = (atppc_r_ctr(atppc));
1446 1.16.2.2 skrll break;
1447 1.16.2.2 skrll case PPBUS_REPP_A:
1448 1.16.2.2 skrll val = (atppc_r_eppA(atppc));
1449 1.16.2.2 skrll break;
1450 1.16.2.2 skrll case PPBUS_REPP_D:
1451 1.16.2.2 skrll val = (atppc_r_eppD(atppc));
1452 1.16.2.2 skrll break;
1453 1.16.2.2 skrll case PPBUS_RECR:
1454 1.16.2.2 skrll val = (atppc_r_ecr(atppc));
1455 1.16.2.2 skrll break;
1456 1.16.2.2 skrll case PPBUS_RFIFO:
1457 1.16.2.2 skrll val = (atppc_r_fifo(atppc));
1458 1.16.2.2 skrll break;
1459 1.16.2.2 skrll case PPBUS_WDTR:
1460 1.16.2.2 skrll atppc_w_dtr(atppc, byte);
1461 1.16.2.2 skrll break;
1462 1.16.2.2 skrll case PPBUS_WSTR:
1463 1.16.2.2 skrll atppc_w_str(atppc, byte);
1464 1.16.2.2 skrll break;
1465 1.16.2.2 skrll case PPBUS_WCTR:
1466 1.16.2.2 skrll atppc_w_ctr(atppc, byte);
1467 1.16.2.2 skrll break;
1468 1.16.2.2 skrll case PPBUS_WEPP_A:
1469 1.16.2.2 skrll atppc_w_eppA(atppc, byte);
1470 1.16.2.2 skrll break;
1471 1.16.2.2 skrll case PPBUS_WEPP_D:
1472 1.16.2.2 skrll atppc_w_eppD(atppc, byte);
1473 1.16.2.2 skrll break;
1474 1.16.2.2 skrll case PPBUS_WECR:
1475 1.16.2.2 skrll atppc_w_ecr(atppc, byte);
1476 1.16.2.2 skrll break;
1477 1.16.2.2 skrll case PPBUS_WFIFO:
1478 1.16.2.2 skrll atppc_w_fifo(atppc, byte);
1479 1.16.2.2 skrll break;
1480 1.16.2.2 skrll default:
1481 1.16.2.2 skrll panic("%s(%s): unknown I/O operation", dev->dv_xname,
1482 1.16.2.2 skrll __func__);
1483 1.16.2.2 skrll break;
1484 1.16.2.2 skrll }
1485 1.16.2.2 skrll
1486 1.16.2.2 skrll atppc_barrier(atppc);
1487 1.16.2.2 skrll
1488 1.16.2.2 skrll ATPPC_UNLOCK(atppc);
1489 1.16.2.2 skrll splx(s);
1490 1.16.2.2 skrll
1491 1.16.2.2 skrll return val;
1492 1.16.2.2 skrll }
1493 1.16.2.2 skrll
1494 1.16.2.2 skrll /* Read "instance variables" of atppc device */
1495 1.16.2.2 skrll static int
1496 1.16.2.2 skrll atppc_read_ivar(struct device *dev, int index, unsigned int *val)
1497 1.16.2.2 skrll {
1498 1.16.2.2 skrll struct atppc_softc *atppc = (struct atppc_softc *)dev;
1499 1.16.2.2 skrll int rval = 0;
1500 1.16.2.2 skrll int s;
1501 1.16.2.2 skrll
1502 1.16.2.2 skrll s = splatppc();
1503 1.16.2.2 skrll ATPPC_LOCK(atppc);
1504 1.16.2.2 skrll
1505 1.16.2.2 skrll switch(index) {
1506 1.16.2.2 skrll case PPBUS_IVAR_EPP_PROTO:
1507 1.16.2.2 skrll if (atppc->sc_epp == ATPPC_EPP_1_9)
1508 1.16.2.2 skrll *val = PPBUS_EPP_1_9;
1509 1.16.2.2 skrll else if (atppc->sc_epp == ATPPC_EPP_1_7)
1510 1.16.2.2 skrll *val = PPBUS_EPP_1_7;
1511 1.16.2.2 skrll /* XXX what if not using EPP ? */
1512 1.16.2.2 skrll break;
1513 1.16.2.2 skrll
1514 1.16.2.2 skrll case PPBUS_IVAR_INTR:
1515 1.16.2.2 skrll *val = ((atppc->sc_use & ATPPC_USE_INTR) != 0);
1516 1.16.2.2 skrll break;
1517 1.16.2.2 skrll
1518 1.16.2.2 skrll case PPBUS_IVAR_DMA:
1519 1.16.2.2 skrll *val = ((atppc->sc_use & ATPPC_USE_DMA) != 0);
1520 1.16.2.2 skrll break;
1521 1.16.2.2 skrll
1522 1.16.2.2 skrll default:
1523 1.16.2.2 skrll rval = ENODEV;
1524 1.16.2.2 skrll }
1525 1.16.2.2 skrll
1526 1.16.2.2 skrll ATPPC_UNLOCK(atppc);
1527 1.16.2.2 skrll splx(s);
1528 1.16.2.2 skrll
1529 1.16.2.2 skrll return rval;
1530 1.16.2.2 skrll }
1531 1.16.2.2 skrll
1532 1.16.2.2 skrll /* Write "instance varaibles" of atppc device */
1533 1.16.2.2 skrll static int
1534 1.16.2.2 skrll atppc_write_ivar(struct device *dev, int index, unsigned int *val)
1535 1.16.2.2 skrll {
1536 1.16.2.2 skrll struct atppc_softc *atppc = (struct atppc_softc *)dev;
1537 1.16.2.2 skrll int rval = 0;
1538 1.16.2.2 skrll int s;
1539 1.16.2.2 skrll
1540 1.16.2.2 skrll s = splatppc();
1541 1.16.2.2 skrll ATPPC_LOCK(atppc);
1542 1.16.2.2 skrll
1543 1.16.2.2 skrll switch(index) {
1544 1.16.2.2 skrll case PPBUS_IVAR_EPP_PROTO:
1545 1.16.2.2 skrll if (*val == PPBUS_EPP_1_9 || *val == PPBUS_EPP_1_7)
1546 1.16.2.2 skrll atppc->sc_epp = *val;
1547 1.16.2.2 skrll else
1548 1.16.2.2 skrll rval = EINVAL;
1549 1.16.2.2 skrll break;
1550 1.16.2.2 skrll
1551 1.16.2.2 skrll case PPBUS_IVAR_INTR:
1552 1.16.2.2 skrll if (*val == 0)
1553 1.16.2.2 skrll atppc->sc_use &= ~ATPPC_USE_INTR;
1554 1.16.2.2 skrll else if (atppc->sc_has & ATPPC_HAS_INTR)
1555 1.16.2.2 skrll atppc->sc_use |= ATPPC_USE_INTR;
1556 1.16.2.2 skrll else
1557 1.16.2.2 skrll rval = ENODEV;
1558 1.16.2.2 skrll break;
1559 1.16.2.2 skrll
1560 1.16.2.2 skrll case PPBUS_IVAR_DMA:
1561 1.16.2.2 skrll if (*val == 0)
1562 1.16.2.2 skrll atppc->sc_use &= ~ATPPC_USE_DMA;
1563 1.16.2.2 skrll else if (atppc->sc_has & ATPPC_HAS_DMA)
1564 1.16.2.2 skrll atppc->sc_use |= ATPPC_USE_DMA;
1565 1.16.2.2 skrll else
1566 1.16.2.2 skrll rval = ENODEV;
1567 1.16.2.2 skrll break;
1568 1.16.2.2 skrll
1569 1.16.2.2 skrll default:
1570 1.16.2.2 skrll rval = ENODEV;
1571 1.16.2.2 skrll }
1572 1.16.2.2 skrll
1573 1.16.2.2 skrll ATPPC_UNLOCK(atppc);
1574 1.16.2.2 skrll splx(s);
1575 1.16.2.2 skrll
1576 1.16.2.2 skrll return rval;
1577 1.16.2.2 skrll }
1578 1.16.2.2 skrll
1579 1.16.2.2 skrll /* Add a handler routine to be called by the interrupt handler */
1580 1.16.2.2 skrll static int
1581 1.16.2.2 skrll atppc_add_handler(struct device *dev, void (*handler)(void *), void *arg)
1582 1.16.2.2 skrll {
1583 1.16.2.2 skrll struct atppc_softc *atppc = (struct atppc_softc *)dev;
1584 1.16.2.2 skrll struct atppc_handler_node *callback;
1585 1.16.2.2 skrll int rval = 0;
1586 1.16.2.2 skrll int s;
1587 1.16.2.2 skrll
1588 1.16.2.2 skrll s = splatppc();
1589 1.16.2.2 skrll ATPPC_LOCK(atppc);
1590 1.16.2.2 skrll
1591 1.16.2.2 skrll if (handler == NULL) {
1592 1.16.2.2 skrll ATPPC_DPRINTF(("%s(%s): attempt to register NULL handler.\n",
1593 1.16.2.2 skrll __func__, dev->dv_xname));
1594 1.16.2.2 skrll rval = EINVAL;
1595 1.16.2.2 skrll } else {
1596 1.16.2.2 skrll callback = malloc(sizeof(struct atppc_handler_node), M_DEVBUF,
1597 1.16.2.2 skrll M_NOWAIT);
1598 1.16.2.2 skrll if (callback) {
1599 1.16.2.2 skrll callback->func = handler;
1600 1.16.2.2 skrll callback->arg = arg;
1601 1.16.2.2 skrll SLIST_INSERT_HEAD(&(atppc->sc_handler_listhead),
1602 1.16.2.2 skrll callback, entries);
1603 1.16.2.2 skrll } else {
1604 1.16.2.2 skrll rval = ENOMEM;
1605 1.16.2.2 skrll }
1606 1.16.2.2 skrll }
1607 1.16.2.2 skrll
1608 1.16.2.2 skrll ATPPC_UNLOCK(atppc);
1609 1.16.2.2 skrll splx(s);
1610 1.16.2.2 skrll
1611 1.16.2.2 skrll return rval;
1612 1.16.2.2 skrll }
1613 1.16.2.2 skrll
1614 1.16.2.2 skrll /* Remove a handler added by atppc_add_handler() */
1615 1.16.2.2 skrll static int
1616 1.16.2.2 skrll atppc_remove_handler(struct device *dev, void (*handler)(void *))
1617 1.16.2.2 skrll {
1618 1.16.2.2 skrll struct atppc_softc *atppc = (struct atppc_softc *)dev;
1619 1.16.2.2 skrll struct atppc_handler_node *callback;
1620 1.16.2.2 skrll int rval = EINVAL;
1621 1.16.2.2 skrll int s;
1622 1.16.2.2 skrll
1623 1.16.2.2 skrll s = splatppc();
1624 1.16.2.2 skrll ATPPC_LOCK(atppc);
1625 1.16.2.2 skrll
1626 1.16.2.2 skrll if (SLIST_EMPTY(&(atppc->sc_handler_listhead)))
1627 1.16.2.2 skrll panic("%s(%s): attempt to remove handler from empty list.\n",
1628 1.16.2.2 skrll __func__, dev->dv_xname);
1629 1.16.2.2 skrll
1630 1.16.2.2 skrll /* Search list for handler */
1631 1.16.2.2 skrll SLIST_FOREACH(callback, &(atppc->sc_handler_listhead), entries) {
1632 1.16.2.2 skrll if (callback->func == handler) {
1633 1.16.2.2 skrll SLIST_REMOVE(&(atppc->sc_handler_listhead), callback,
1634 1.16.2.2 skrll atppc_handler_node, entries);
1635 1.16.2.2 skrll free(callback, M_DEVBUF);
1636 1.16.2.2 skrll rval = 0;
1637 1.16.2.2 skrll break;
1638 1.16.2.2 skrll }
1639 1.16.2.2 skrll }
1640 1.16.2.2 skrll
1641 1.16.2.2 skrll ATPPC_UNLOCK(atppc);
1642 1.16.2.2 skrll splx(s);
1643 1.16.2.2 skrll
1644 1.16.2.2 skrll return rval;
1645 1.16.2.2 skrll }
1646 1.16.2.2 skrll
1647 1.16.2.2 skrll /* Utility functions */
1648 1.16.2.2 skrll
1649 1.16.2.2 skrll
1650 1.16.2.2 skrll /*
1651 1.16.2.2 skrll * Functions that read bytes from port into buffer: called from interrupt
1652 1.16.2.2 skrll * handler depending on current chipset mode and cause of interrupt. Return
1653 1.16.2.2 skrll * value: number of bytes moved.
1654 1.16.2.2 skrll */
1655 1.16.2.2 skrll
1656 1.16.2.2 skrll /* Only the lower 4 bits of the final value are valid */
1657 1.16.2.2 skrll #define nibble2char(s) ((((s) & ~nACK) >> 3) | (~(s) & nBUSY) >> 4)
1658 1.16.2.2 skrll
1659 1.16.2.2 skrll /* Read bytes in nibble mode */
1660 1.16.2.2 skrll static void
1661 1.16.2.2 skrll atppc_nibble_read(struct atppc_softc *atppc)
1662 1.16.2.2 skrll {
1663 1.16.2.2 skrll int i;
1664 1.16.2.2 skrll u_int8_t nibble[2];
1665 1.16.2.2 skrll u_int8_t ctr;
1666 1.16.2.2 skrll u_int8_t str;
1667 1.16.2.2 skrll
1668 1.16.2.2 skrll /* Enable interrupts if needed */
1669 1.16.2.2 skrll if (atppc->sc_use & ATPPC_USE_INTR) {
1670 1.16.2.2 skrll ctr = atppc_r_ctr(atppc);
1671 1.16.2.2 skrll atppc_barrier_r(atppc);
1672 1.16.2.2 skrll if (!(ctr & IRQENABLE)) {
1673 1.16.2.2 skrll ctr |= IRQENABLE;
1674 1.16.2.2 skrll atppc_w_ctr(atppc, ctr);
1675 1.16.2.2 skrll atppc_barrier_w(atppc);
1676 1.16.2.2 skrll }
1677 1.16.2.2 skrll }
1678 1.16.2.2 skrll
1679 1.16.2.2 skrll while (atppc->sc_inbstart < (atppc->sc_inb + atppc->sc_inb_nbytes)) {
1680 1.16.2.2 skrll /* Check if device has data to send in idle phase */
1681 1.16.2.2 skrll str = atppc_r_str(atppc);
1682 1.16.2.2 skrll atppc_barrier_r(atppc);
1683 1.16.2.2 skrll if (str & nDATAVAIL) {
1684 1.16.2.2 skrll return;
1685 1.16.2.2 skrll }
1686 1.16.2.2 skrll
1687 1.16.2.2 skrll /* Nibble-mode handshake transfer */
1688 1.16.2.2 skrll for (i = 0; i < 2; i++) {
1689 1.16.2.2 skrll /* Event 7 - ready to take data (HOSTBUSY low) */
1690 1.16.2.2 skrll ctr = atppc_r_ctr(atppc);
1691 1.16.2.2 skrll atppc_barrier_r(atppc);
1692 1.16.2.2 skrll ctr |= HOSTBUSY;
1693 1.16.2.2 skrll atppc_w_ctr(atppc, ctr);
1694 1.16.2.2 skrll atppc_barrier_w(atppc);
1695 1.16.2.2 skrll
1696 1.16.2.2 skrll /* Event 8 - peripheral writes the first nibble */
1697 1.16.2.2 skrll
1698 1.16.2.2 skrll /* Event 9 - peripheral set nAck low */
1699 1.16.2.2 skrll atppc->sc_inerr = atppc_poll_str(atppc, 0, PTRCLK);
1700 1.16.2.2 skrll if (atppc->sc_inerr)
1701 1.16.2.2 skrll return;
1702 1.16.2.2 skrll
1703 1.16.2.2 skrll /* read nibble */
1704 1.16.2.2 skrll nibble[i] = atppc_r_str(atppc);
1705 1.16.2.2 skrll
1706 1.16.2.2 skrll /* Event 10 - ack, nibble received */
1707 1.16.2.2 skrll ctr &= ~HOSTBUSY;
1708 1.16.2.2 skrll atppc_w_ctr(atppc, ctr);
1709 1.16.2.2 skrll
1710 1.16.2.2 skrll /* Event 11 - wait ack from peripherial */
1711 1.16.2.2 skrll if (atppc->sc_use & ATPPC_USE_INTR)
1712 1.16.2.2 skrll atppc->sc_inerr = atppc_wait_interrupt(atppc,
1713 1.16.2.2 skrll atppc->sc_inb, ATPPC_IRQ_nACK);
1714 1.16.2.2 skrll else
1715 1.16.2.2 skrll atppc->sc_inerr = atppc_poll_str(atppc, PTRCLK,
1716 1.16.2.2 skrll PTRCLK);
1717 1.16.2.2 skrll if (atppc->sc_inerr)
1718 1.16.2.2 skrll return;
1719 1.16.2.2 skrll }
1720 1.16.2.2 skrll
1721 1.16.2.2 skrll /* Store byte transfered */
1722 1.16.2.2 skrll *(atppc->sc_inbstart) = ((nibble2char(nibble[1]) << 4) & 0xf0) |
1723 1.16.2.2 skrll (nibble2char(nibble[0]) & 0x0f);
1724 1.16.2.2 skrll atppc->sc_inbstart++;
1725 1.16.2.2 skrll }
1726 1.16.2.2 skrll }
1727 1.16.2.2 skrll
1728 1.16.2.2 skrll /* Read bytes in bidirectional mode */
1729 1.16.2.2 skrll static void
1730 1.16.2.2 skrll atppc_byte_read(struct atppc_softc * const atppc)
1731 1.16.2.2 skrll {
1732 1.16.2.2 skrll u_int8_t ctr;
1733 1.16.2.2 skrll u_int8_t str;
1734 1.16.2.2 skrll
1735 1.16.2.2 skrll /* Check direction bit */
1736 1.16.2.2 skrll ctr = atppc_r_ctr(atppc);
1737 1.16.2.2 skrll atppc_barrier_r(atppc);
1738 1.16.2.2 skrll if (!(ctr & PCD)) {
1739 1.16.2.2 skrll ATPPC_DPRINTF(("%s: byte-mode read attempted without direction "
1740 1.16.2.2 skrll "bit set.", atppc->sc_dev.dv_xname));
1741 1.16.2.2 skrll atppc->sc_inerr = ENODEV;
1742 1.16.2.2 skrll return;
1743 1.16.2.2 skrll }
1744 1.16.2.2 skrll /* Enable interrupts if needed */
1745 1.16.2.2 skrll if (atppc->sc_use & ATPPC_USE_INTR) {
1746 1.16.2.2 skrll if (!(ctr & IRQENABLE)) {
1747 1.16.2.2 skrll ctr |= IRQENABLE;
1748 1.16.2.2 skrll atppc_w_ctr(atppc, ctr);
1749 1.16.2.2 skrll atppc_barrier_w(atppc);
1750 1.16.2.2 skrll }
1751 1.16.2.2 skrll }
1752 1.16.2.2 skrll
1753 1.16.2.2 skrll /* Byte-mode handshake transfer */
1754 1.16.2.2 skrll while (atppc->sc_inbstart < (atppc->sc_inb + atppc->sc_inb_nbytes)) {
1755 1.16.2.2 skrll /* Check if device has data to send */
1756 1.16.2.2 skrll str = atppc_r_str(atppc);
1757 1.16.2.2 skrll atppc_barrier_r(atppc);
1758 1.16.2.2 skrll if (str & nDATAVAIL) {
1759 1.16.2.2 skrll return;
1760 1.16.2.2 skrll }
1761 1.16.2.2 skrll
1762 1.16.2.2 skrll /* Event 7 - ready to take data (nAUTO low) */
1763 1.16.2.2 skrll ctr |= HOSTBUSY;
1764 1.16.2.2 skrll atppc_w_ctr(atppc, ctr);
1765 1.16.2.2 skrll atppc_barrier_w(atppc);
1766 1.16.2.2 skrll
1767 1.16.2.2 skrll /* Event 9 - peripheral set nAck low */
1768 1.16.2.2 skrll atppc->sc_inerr = atppc_poll_str(atppc, 0, PTRCLK);
1769 1.16.2.2 skrll if (atppc->sc_inerr)
1770 1.16.2.2 skrll return;
1771 1.16.2.2 skrll
1772 1.16.2.2 skrll /* Store byte transfered */
1773 1.16.2.2 skrll *(atppc->sc_inbstart) = atppc_r_dtr(atppc);
1774 1.16.2.2 skrll atppc_barrier_r(atppc);
1775 1.16.2.2 skrll
1776 1.16.2.2 skrll /* Event 10 - data received, can't accept more */
1777 1.16.2.2 skrll ctr &= ~HOSTBUSY;
1778 1.16.2.2 skrll atppc_w_ctr(atppc, ctr);
1779 1.16.2.2 skrll atppc_barrier_w(atppc);
1780 1.16.2.2 skrll
1781 1.16.2.2 skrll /* Event 11 - peripheral ack */
1782 1.16.2.2 skrll if (atppc->sc_use & ATPPC_USE_INTR)
1783 1.16.2.2 skrll atppc->sc_inerr = atppc_wait_interrupt(atppc,
1784 1.16.2.2 skrll atppc->sc_inb, ATPPC_IRQ_nACK);
1785 1.16.2.2 skrll else
1786 1.16.2.2 skrll atppc->sc_inerr = atppc_poll_str(atppc, PTRCLK, PTRCLK);
1787 1.16.2.2 skrll if (atppc->sc_inerr)
1788 1.16.2.2 skrll return;
1789 1.16.2.2 skrll
1790 1.16.2.2 skrll /* Event 16 - strobe */
1791 1.16.2.2 skrll str |= HOSTCLK;
1792 1.16.2.2 skrll atppc_w_str(atppc, str);
1793 1.16.2.2 skrll atppc_barrier_w(atppc);
1794 1.16.2.2 skrll DELAY(1);
1795 1.16.2.2 skrll str &= ~HOSTCLK;
1796 1.16.2.2 skrll atppc_w_str(atppc, str);
1797 1.16.2.2 skrll atppc_barrier_w(atppc);
1798 1.16.2.2 skrll
1799 1.16.2.2 skrll /* Update counter */
1800 1.16.2.2 skrll atppc->sc_inbstart++;
1801 1.16.2.2 skrll }
1802 1.16.2.2 skrll }
1803 1.16.2.2 skrll
1804 1.16.2.2 skrll /* Read bytes in EPP mode */
1805 1.16.2.2 skrll static void
1806 1.16.2.2 skrll atppc_epp_read(struct atppc_softc * atppc)
1807 1.16.2.2 skrll {
1808 1.16.2.2 skrll if (atppc->sc_epp == ATPPC_EPP_1_9) {
1809 1.16.2.2 skrll {
1810 1.16.2.2 skrll uint8_t str;
1811 1.16.2.2 skrll int i;
1812 1.16.2.2 skrll
1813 1.16.2.2 skrll atppc_reset_epp_timeout((struct device *)atppc);
1814 1.16.2.2 skrll for (i = 0; i < atppc->sc_inb_nbytes; i++) {
1815 1.16.2.2 skrll *(atppc->sc_inbstart) = atppc_r_eppD(atppc);
1816 1.16.2.2 skrll atppc_barrier_r(atppc);
1817 1.16.2.2 skrll str = atppc_r_str(atppc);
1818 1.16.2.2 skrll atppc_barrier_r(atppc);
1819 1.16.2.2 skrll if (str & TIMEOUT) {
1820 1.16.2.2 skrll atppc->sc_inerr = EIO;
1821 1.16.2.2 skrll break;
1822 1.16.2.2 skrll }
1823 1.16.2.2 skrll atppc->sc_inbstart++;
1824 1.16.2.2 skrll }
1825 1.16.2.2 skrll }
1826 1.16.2.2 skrll } else {
1827 1.16.2.2 skrll /* Read data block from EPP data register */
1828 1.16.2.2 skrll atppc_r_eppD_multi(atppc, atppc->sc_inbstart,
1829 1.16.2.2 skrll atppc->sc_inb_nbytes);
1830 1.16.2.2 skrll atppc_barrier_r(atppc);
1831 1.16.2.2 skrll /* Update buffer position, byte count and counter */
1832 1.16.2.2 skrll atppc->sc_inbstart += atppc->sc_inb_nbytes;
1833 1.16.2.2 skrll }
1834 1.16.2.2 skrll
1835 1.16.2.2 skrll return;
1836 1.16.2.2 skrll }
1837 1.16.2.2 skrll
1838 1.16.2.2 skrll /* Read bytes in ECP mode */
1839 1.16.2.2 skrll static void
1840 1.16.2.2 skrll atppc_ecp_read(struct atppc_softc *atppc)
1841 1.16.2.2 skrll {
1842 1.16.2.2 skrll u_int8_t ecr;
1843 1.16.2.2 skrll u_int8_t ctr;
1844 1.16.2.2 skrll u_int8_t str;
1845 1.16.2.2 skrll const unsigned char ctr_sav = atppc_r_ctr(atppc);
1846 1.16.2.2 skrll const unsigned char ecr_sav = atppc_r_ecr(atppc);
1847 1.16.2.2 skrll unsigned int worklen;
1848 1.16.2.2 skrll
1849 1.16.2.2 skrll /* Check direction bit */
1850 1.16.2.2 skrll ctr = ctr_sav;
1851 1.16.2.2 skrll atppc_barrier_r(atppc);
1852 1.16.2.2 skrll if (!(ctr & PCD)) {
1853 1.16.2.2 skrll ATPPC_DPRINTF(("%s: ecp-mode read attempted without direction "
1854 1.16.2.2 skrll "bit set.", atppc->sc_dev.dv_xname));
1855 1.16.2.2 skrll atppc->sc_inerr = ENODEV;
1856 1.16.2.2 skrll goto end;
1857 1.16.2.2 skrll }
1858 1.16.2.2 skrll
1859 1.16.2.2 skrll /* Clear device request if any */
1860 1.16.2.2 skrll if (atppc->sc_use & ATPPC_USE_INTR)
1861 1.16.2.2 skrll atppc->sc_irqstat &= ~ATPPC_IRQ_nFAULT;
1862 1.16.2.2 skrll
1863 1.16.2.2 skrll while (atppc->sc_inbstart < (atppc->sc_inb + atppc->sc_inb_nbytes)) {
1864 1.16.2.2 skrll ecr = atppc_r_ecr(atppc);
1865 1.16.2.2 skrll atppc_barrier_r(atppc);
1866 1.16.2.2 skrll if (ecr & ATPPC_FIFO_EMPTY) {
1867 1.16.2.2 skrll /* Check for invalid state */
1868 1.16.2.2 skrll if (ecr & ATPPC_FIFO_FULL) {
1869 1.16.2.2 skrll atppc_ecp_read_error(atppc, worklen);
1870 1.16.2.2 skrll break;
1871 1.16.2.2 skrll }
1872 1.16.2.2 skrll
1873 1.16.2.2 skrll /* Check if device has data to send */
1874 1.16.2.2 skrll str = atppc_r_str(atppc);
1875 1.16.2.2 skrll atppc_barrier_r(atppc);
1876 1.16.2.2 skrll if (str & nDATAVAIL) {
1877 1.16.2.2 skrll break;
1878 1.16.2.2 skrll }
1879 1.16.2.2 skrll
1880 1.16.2.2 skrll if (atppc->sc_use & ATPPC_USE_INTR) {
1881 1.16.2.2 skrll /* Enable interrupts */
1882 1.16.2.2 skrll ecr &= ~ATPPC_SERVICE_INTR;
1883 1.16.2.2 skrll atppc_w_ecr(atppc, ecr);
1884 1.16.2.2 skrll atppc_barrier_w(atppc);
1885 1.16.2.2 skrll /* Wait for FIFO to fill */
1886 1.16.2.2 skrll atppc->sc_inerr = atppc_wait_interrupt(atppc,
1887 1.16.2.2 skrll atppc->sc_inb, ATPPC_IRQ_FIFO);
1888 1.16.2.2 skrll if (atppc->sc_inerr)
1889 1.16.2.2 skrll break;
1890 1.16.2.2 skrll } else {
1891 1.16.2.2 skrll DELAY(1);
1892 1.16.2.2 skrll }
1893 1.16.2.2 skrll continue;
1894 1.16.2.2 skrll }
1895 1.16.2.2 skrll else if (ecr & ATPPC_FIFO_FULL) {
1896 1.16.2.2 skrll /* Transfer sc_fifo bytes */
1897 1.16.2.2 skrll worklen = atppc->sc_fifo;
1898 1.16.2.2 skrll }
1899 1.16.2.2 skrll else if (ecr & ATPPC_SERVICE_INTR) {
1900 1.16.2.2 skrll /* Transfer sc_rthr bytes */
1901 1.16.2.2 skrll worklen = atppc->sc_rthr;
1902 1.16.2.2 skrll } else {
1903 1.16.2.2 skrll /* At least one byte is in the FIFO */
1904 1.16.2.2 skrll worklen = 1;
1905 1.16.2.2 skrll }
1906 1.16.2.2 skrll
1907 1.16.2.2 skrll if ((atppc->sc_use & ATPPC_USE_INTR) &&
1908 1.16.2.2 skrll (atppc->sc_use & ATPPC_USE_DMA)) {
1909 1.16.2.2 skrll
1910 1.16.2.2 skrll atppc_ecp_read_dma(atppc, &worklen, ecr);
1911 1.16.2.2 skrll } else {
1912 1.16.2.2 skrll atppc_ecp_read_pio(atppc, &worklen, ecr);
1913 1.16.2.2 skrll }
1914 1.16.2.2 skrll
1915 1.16.2.2 skrll if (atppc->sc_inerr) {
1916 1.16.2.2 skrll atppc_ecp_read_error(atppc, worklen);
1917 1.16.2.2 skrll break;
1918 1.16.2.2 skrll }
1919 1.16.2.2 skrll
1920 1.16.2.2 skrll /* Update counter */
1921 1.16.2.2 skrll atppc->sc_inbstart += worklen;
1922 1.16.2.2 skrll }
1923 1.16.2.2 skrll end:
1924 1.16.2.2 skrll atppc_w_ctr(atppc, ctr_sav);
1925 1.16.2.2 skrll atppc_w_ecr(atppc, ecr_sav);
1926 1.16.2.2 skrll atppc_barrier_w(atppc);
1927 1.16.2.2 skrll }
1928 1.16.2.2 skrll
1929 1.16.2.2 skrll /* Read bytes in ECP mode using DMA transfers */
1930 1.16.2.2 skrll static void
1931 1.16.2.2 skrll atppc_ecp_read_dma(struct atppc_softc *atppc, unsigned int *length,
1932 1.16.2.2 skrll unsigned char ecr)
1933 1.16.2.2 skrll {
1934 1.16.2.2 skrll /* Limit transfer to maximum DMA size and start it */
1935 1.16.2.2 skrll *length = min(*length, atppc->sc_dma_maxsize);
1936 1.16.2.2 skrll atppc->sc_dmastat = ATPPC_DMA_INIT;
1937 1.16.2.2 skrll atppc->sc_dma_start(atppc, atppc->sc_inbstart, *length,
1938 1.16.2.2 skrll ATPPC_DMA_MODE_READ);
1939 1.16.2.2 skrll
1940 1.16.2.2 skrll atppc->sc_dmastat = ATPPC_DMA_STARTED;
1941 1.16.2.2 skrll
1942 1.16.2.2 skrll /* Enable interrupts, DMA */
1943 1.16.2.2 skrll ecr &= ~ATPPC_SERVICE_INTR;
1944 1.16.2.2 skrll ecr |= ATPPC_ENABLE_DMA;
1945 1.16.2.2 skrll atppc_w_ecr(atppc, ecr);
1946 1.16.2.2 skrll atppc_barrier_w(atppc);
1947 1.16.2.2 skrll
1948 1.16.2.2 skrll /* Wait for DMA completion */
1949 1.16.2.2 skrll atppc->sc_inerr = atppc_wait_interrupt(atppc, atppc->sc_inb,
1950 1.16.2.2 skrll ATPPC_IRQ_DMA);
1951 1.16.2.2 skrll if (atppc->sc_inerr)
1952 1.16.2.2 skrll return;
1953 1.16.2.2 skrll
1954 1.16.2.2 skrll /* Get register value recorded by interrupt handler */
1955 1.16.2.2 skrll ecr = atppc->sc_ecr_intr;
1956 1.16.2.2 skrll /* Clear DMA programming */
1957 1.16.2.2 skrll atppc->sc_dma_finish(atppc);
1958 1.16.2.2 skrll atppc->sc_dmastat = ATPPC_DMA_COMPLETE;
1959 1.16.2.2 skrll /* Disable DMA */
1960 1.16.2.2 skrll ecr &= ~ATPPC_ENABLE_DMA;
1961 1.16.2.2 skrll atppc_w_ecr(atppc, ecr);
1962 1.16.2.2 skrll atppc_barrier_w(atppc);
1963 1.16.2.2 skrll }
1964 1.16.2.2 skrll
1965 1.16.2.2 skrll /* Read bytes in ECP mode using PIO transfers */
1966 1.16.2.2 skrll static void
1967 1.16.2.2 skrll atppc_ecp_read_pio(struct atppc_softc *atppc, unsigned int *length,
1968 1.16.2.2 skrll unsigned char ecr)
1969 1.16.2.2 skrll {
1970 1.16.2.2 skrll /* Disable DMA */
1971 1.16.2.2 skrll ecr &= ~ATPPC_ENABLE_DMA;
1972 1.16.2.2 skrll atppc_w_ecr(atppc, ecr);
1973 1.16.2.2 skrll atppc_barrier_w(atppc);
1974 1.16.2.2 skrll
1975 1.16.2.2 skrll /* Read from FIFO */
1976 1.16.2.2 skrll atppc_r_fifo_multi(atppc, atppc->sc_inbstart, *length);
1977 1.16.2.2 skrll }
1978 1.16.2.2 skrll
1979 1.16.2.2 skrll /* Handle errors for ECP reads */
1980 1.16.2.2 skrll static void
1981 1.16.2.2 skrll atppc_ecp_read_error(struct atppc_softc *atppc, const unsigned int worklen)
1982 1.16.2.2 skrll {
1983 1.16.2.2 skrll unsigned char ecr = atppc_r_ecr(atppc);
1984 1.16.2.2 skrll
1985 1.16.2.2 skrll /* Abort DMA if not finished */
1986 1.16.2.2 skrll if (atppc->sc_dmastat == ATPPC_DMA_STARTED) {
1987 1.16.2.2 skrll atppc->sc_dma_abort(atppc);
1988 1.16.2.2 skrll ATPPC_DPRINTF(("%s: DMA interrupted.\n", __func__));
1989 1.16.2.2 skrll }
1990 1.16.2.2 skrll
1991 1.16.2.2 skrll /* Check for invalid states */
1992 1.16.2.2 skrll if ((ecr & ATPPC_FIFO_EMPTY) && (ecr & ATPPC_FIFO_FULL)) {
1993 1.16.2.2 skrll ATPPC_DPRINTF(("%s: FIFO full+empty bits set.\n", __func__));
1994 1.16.2.2 skrll ATPPC_DPRINTF(("%s: reseting FIFO.\n", __func__));
1995 1.16.2.2 skrll atppc_w_ecr(atppc, ATPPC_ECR_PS2);
1996 1.16.2.2 skrll atppc_barrier_w(atppc);
1997 1.16.2.2 skrll }
1998 1.16.2.2 skrll }
1999 1.16.2.2 skrll
2000 1.16.2.2 skrll /*
2001 1.16.2.2 skrll * Functions that write bytes to port from buffer: called from atppc_write()
2002 1.16.2.2 skrll * function depending on current chipset mode. Returns number of bytes moved.
2003 1.16.2.2 skrll */
2004 1.16.2.2 skrll
2005 1.16.2.2 skrll /* Write bytes in std/bidirectional mode */
2006 1.16.2.2 skrll static void
2007 1.16.2.2 skrll atppc_std_write(struct atppc_softc * const atppc)
2008 1.16.2.2 skrll {
2009 1.16.2.2 skrll unsigned int timecount;
2010 1.16.2.2 skrll unsigned char ctr;
2011 1.16.2.2 skrll
2012 1.16.2.2 skrll ctr = atppc_r_ctr(atppc);
2013 1.16.2.2 skrll atppc_barrier_r(atppc);
2014 1.16.2.2 skrll /* Enable interrupts if needed */
2015 1.16.2.2 skrll if (atppc->sc_use & ATPPC_USE_INTR) {
2016 1.16.2.2 skrll if (!(ctr & IRQENABLE)) {
2017 1.16.2.2 skrll ctr |= IRQENABLE;
2018 1.16.2.2 skrll atppc_w_ctr(atppc, ctr);
2019 1.16.2.2 skrll atppc_barrier_w(atppc);
2020 1.16.2.2 skrll }
2021 1.16.2.2 skrll }
2022 1.16.2.2 skrll
2023 1.16.2.2 skrll while (atppc->sc_outbstart < (atppc->sc_outb + atppc->sc_outb_nbytes)) {
2024 1.16.2.2 skrll /* Wait for peripheral to become ready for MAXBUSYWAIT */
2025 1.16.2.2 skrll atppc->sc_outerr = atppc_poll_str(atppc, SPP_READY, SPP_MASK);
2026 1.16.2.2 skrll if (atppc->sc_outerr)
2027 1.16.2.2 skrll return;
2028 1.16.2.2 skrll
2029 1.16.2.2 skrll /* Put data in data register */
2030 1.16.2.2 skrll atppc_w_dtr(atppc, *(atppc->sc_outbstart));
2031 1.16.2.2 skrll atppc_barrier_w(atppc);
2032 1.16.2.2 skrll DELAY(1);
2033 1.16.2.2 skrll
2034 1.16.2.2 skrll /* Pulse strobe to indicate valid data on lines */
2035 1.16.2.2 skrll ctr |= STROBE;
2036 1.16.2.2 skrll atppc_w_ctr(atppc, ctr);
2037 1.16.2.2 skrll atppc_barrier_w(atppc);
2038 1.16.2.2 skrll DELAY(1);
2039 1.16.2.2 skrll ctr &= ~STROBE;
2040 1.16.2.2 skrll atppc_w_ctr(atppc, ctr);
2041 1.16.2.2 skrll atppc_barrier_w(atppc);
2042 1.16.2.2 skrll
2043 1.16.2.2 skrll /* Wait for nACK for MAXBUSYWAIT */
2044 1.16.2.2 skrll timecount = 0;
2045 1.16.2.2 skrll if (atppc->sc_use & ATPPC_USE_INTR) {
2046 1.16.2.2 skrll atppc->sc_outerr = atppc_wait_interrupt(atppc,
2047 1.16.2.2 skrll atppc->sc_outb, ATPPC_IRQ_nACK);
2048 1.16.2.2 skrll if (atppc->sc_outerr)
2049 1.16.2.2 skrll return;
2050 1.16.2.2 skrll } else {
2051 1.16.2.2 skrll /* Try to catch the pulsed acknowledgement */
2052 1.16.2.2 skrll atppc->sc_outerr = atppc_poll_str(atppc, 0, nACK);
2053 1.16.2.2 skrll if (atppc->sc_outerr)
2054 1.16.2.2 skrll return;
2055 1.16.2.2 skrll atppc->sc_outerr = atppc_poll_str(atppc, nACK, nACK);
2056 1.16.2.2 skrll if (atppc->sc_outerr)
2057 1.16.2.2 skrll return;
2058 1.16.2.2 skrll }
2059 1.16.2.2 skrll
2060 1.16.2.2 skrll /* Update buffer position, byte count and counter */
2061 1.16.2.2 skrll atppc->sc_outbstart++;
2062 1.16.2.2 skrll }
2063 1.16.2.2 skrll }
2064 1.16.2.2 skrll
2065 1.16.2.2 skrll
2066 1.16.2.2 skrll /* Write bytes in EPP mode */
2067 1.16.2.2 skrll static void
2068 1.16.2.2 skrll atppc_epp_write(struct atppc_softc *atppc)
2069 1.16.2.2 skrll {
2070 1.16.2.2 skrll if (atppc->sc_epp == ATPPC_EPP_1_9) {
2071 1.16.2.2 skrll {
2072 1.16.2.2 skrll uint8_t str;
2073 1.16.2.2 skrll int i;
2074 1.16.2.2 skrll
2075 1.16.2.2 skrll atppc_reset_epp_timeout((struct device *)atppc);
2076 1.16.2.2 skrll for (i = 0; i < atppc->sc_outb_nbytes; i++) {
2077 1.16.2.2 skrll atppc_w_eppD(atppc, *(atppc->sc_outbstart));
2078 1.16.2.2 skrll atppc_barrier_w(atppc);
2079 1.16.2.2 skrll str = atppc_r_str(atppc);
2080 1.16.2.2 skrll atppc_barrier_r(atppc);
2081 1.16.2.2 skrll if (str & TIMEOUT) {
2082 1.16.2.2 skrll atppc->sc_outerr = EIO;
2083 1.16.2.2 skrll break;
2084 1.16.2.2 skrll }
2085 1.16.2.2 skrll atppc->sc_outbstart++;
2086 1.16.2.2 skrll }
2087 1.16.2.2 skrll }
2088 1.16.2.2 skrll } else {
2089 1.16.2.2 skrll /* Write data block to EPP data register */
2090 1.16.2.2 skrll atppc_w_eppD_multi(atppc, atppc->sc_outbstart,
2091 1.16.2.2 skrll atppc->sc_outb_nbytes);
2092 1.16.2.2 skrll atppc_barrier_w(atppc);
2093 1.16.2.2 skrll /* Update buffer position, byte count and counter */
2094 1.16.2.2 skrll atppc->sc_outbstart += atppc->sc_outb_nbytes;
2095 1.16.2.2 skrll }
2096 1.16.2.2 skrll
2097 1.16.2.2 skrll return;
2098 1.16.2.2 skrll }
2099 1.16.2.2 skrll
2100 1.16.2.2 skrll
2101 1.16.2.2 skrll /* Write bytes in ECP/Fast Centronics mode */
2102 1.16.2.2 skrll static void
2103 1.16.2.2 skrll atppc_fifo_write(struct atppc_softc * const atppc)
2104 1.16.2.2 skrll {
2105 1.16.2.2 skrll unsigned char ctr;
2106 1.16.2.2 skrll unsigned char ecr;
2107 1.16.2.2 skrll const unsigned char ctr_sav = atppc_r_ctr(atppc);
2108 1.16.2.2 skrll const unsigned char ecr_sav = atppc_r_ecr(atppc);
2109 1.16.2.2 skrll
2110 1.16.2.2 skrll ctr = ctr_sav;
2111 1.16.2.2 skrll ecr = ecr_sav;
2112 1.16.2.2 skrll atppc_barrier_r(atppc);
2113 1.16.2.2 skrll
2114 1.16.2.2 skrll /* Reset and flush FIFO */
2115 1.16.2.2 skrll atppc_w_ecr(atppc, ATPPC_ECR_PS2);
2116 1.16.2.2 skrll atppc_barrier_w(atppc);
2117 1.16.2.2 skrll /* Disable nAck interrupts and initialize port bits */
2118 1.16.2.2 skrll ctr &= ~(IRQENABLE | STROBE | AUTOFEED);
2119 1.16.2.2 skrll atppc_w_ctr(atppc, ctr);
2120 1.16.2.2 skrll atppc_barrier_w(atppc);
2121 1.16.2.2 skrll /* Restore mode */
2122 1.16.2.2 skrll atppc_w_ecr(atppc, ecr);
2123 1.16.2.2 skrll atppc_barrier_w(atppc);
2124 1.16.2.2 skrll
2125 1.16.2.2 skrll /* DMA or Programmed IO */
2126 1.16.2.2 skrll if ((atppc->sc_use & ATPPC_USE_DMA) &&
2127 1.16.2.2 skrll (atppc->sc_use & ATPPC_USE_INTR)) {
2128 1.16.2.2 skrll
2129 1.16.2.2 skrll atppc_fifo_write_dma(atppc, ecr, ctr);
2130 1.16.2.2 skrll } else {
2131 1.16.2.2 skrll atppc_fifo_write_pio(atppc, ecr, ctr);
2132 1.16.2.2 skrll }
2133 1.16.2.2 skrll
2134 1.16.2.2 skrll /* Restore original register values */
2135 1.16.2.2 skrll atppc_w_ctr(atppc, ctr_sav);
2136 1.16.2.2 skrll atppc_w_ecr(atppc, ecr_sav);
2137 1.16.2.2 skrll atppc_barrier_w(atppc);
2138 1.16.2.2 skrll }
2139 1.16.2.2 skrll
2140 1.16.2.2 skrll static void
2141 1.16.2.2 skrll atppc_fifo_write_dma(struct atppc_softc * const atppc, unsigned char ecr,
2142 1.16.2.2 skrll unsigned char ctr)
2143 1.16.2.2 skrll {
2144 1.16.2.2 skrll unsigned int len;
2145 1.16.2.2 skrll unsigned int worklen;
2146 1.16.2.2 skrll
2147 1.16.2.2 skrll for (len = (atppc->sc_outb + atppc->sc_outb_nbytes) -
2148 1.16.2.2 skrll atppc->sc_outbstart; len > 0; len = (atppc->sc_outb +
2149 1.16.2.2 skrll atppc->sc_outb_nbytes) - atppc->sc_outbstart) {
2150 1.16.2.2 skrll
2151 1.16.2.2 skrll /* Wait for device to become ready */
2152 1.16.2.2 skrll atppc->sc_outerr = atppc_poll_str(atppc, SPP_READY, SPP_MASK);
2153 1.16.2.2 skrll if (atppc->sc_outerr)
2154 1.16.2.2 skrll return;
2155 1.16.2.2 skrll
2156 1.16.2.2 skrll /* Reset chipset for next DMA transfer */
2157 1.16.2.2 skrll atppc_w_ecr(atppc, ATPPC_ECR_PS2);
2158 1.16.2.2 skrll atppc_barrier_w(atppc);
2159 1.16.2.2 skrll atppc_w_ecr(atppc, ecr);
2160 1.16.2.2 skrll atppc_barrier_w(atppc);
2161 1.16.2.2 skrll
2162 1.16.2.2 skrll /* Limit transfer to maximum DMA size and start it */
2163 1.16.2.2 skrll worklen = min(len, atppc->sc_dma_maxsize);
2164 1.16.2.2 skrll atppc->sc_dmastat = ATPPC_DMA_INIT;
2165 1.16.2.2 skrll atppc->sc_dma_start(atppc, atppc->sc_outbstart,
2166 1.16.2.2 skrll worklen, ATPPC_DMA_MODE_WRITE);
2167 1.16.2.2 skrll atppc->sc_dmastat = ATPPC_DMA_STARTED;
2168 1.16.2.2 skrll
2169 1.16.2.2 skrll /* Enable interrupts, DMA */
2170 1.16.2.2 skrll ecr &= ~ATPPC_SERVICE_INTR;
2171 1.16.2.2 skrll ecr |= ATPPC_ENABLE_DMA;
2172 1.16.2.2 skrll atppc_w_ecr(atppc, ecr);
2173 1.16.2.2 skrll atppc_barrier_w(atppc);
2174 1.16.2.2 skrll
2175 1.16.2.2 skrll /* Wait for DMA completion */
2176 1.16.2.2 skrll atppc->sc_outerr = atppc_wait_interrupt(atppc, atppc->sc_outb,
2177 1.16.2.2 skrll ATPPC_IRQ_DMA);
2178 1.16.2.2 skrll if (atppc->sc_outerr) {
2179 1.16.2.2 skrll atppc_fifo_write_error(atppc, worklen);
2180 1.16.2.2 skrll return;
2181 1.16.2.2 skrll }
2182 1.16.2.2 skrll /* Get register value recorded by interrupt handler */
2183 1.16.2.2 skrll ecr = atppc->sc_ecr_intr;
2184 1.16.2.2 skrll /* Clear DMA programming */
2185 1.16.2.2 skrll atppc->sc_dma_finish(atppc);
2186 1.16.2.2 skrll atppc->sc_dmastat = ATPPC_DMA_COMPLETE;
2187 1.16.2.2 skrll /* Disable DMA */
2188 1.16.2.2 skrll ecr &= ~ATPPC_ENABLE_DMA;
2189 1.16.2.2 skrll atppc_w_ecr(atppc, ecr);
2190 1.16.2.2 skrll atppc_barrier_w(atppc);
2191 1.16.2.2 skrll
2192 1.16.2.2 skrll /* Wait for FIFO to empty */
2193 1.16.2.2 skrll for (;;) {
2194 1.16.2.2 skrll if (ecr & ATPPC_FIFO_EMPTY) {
2195 1.16.2.2 skrll if (ecr & ATPPC_FIFO_FULL) {
2196 1.16.2.2 skrll atppc->sc_outerr = EIO;
2197 1.16.2.2 skrll atppc_fifo_write_error(atppc, worklen);
2198 1.16.2.2 skrll return;
2199 1.16.2.2 skrll } else {
2200 1.16.2.2 skrll break;
2201 1.16.2.2 skrll }
2202 1.16.2.2 skrll }
2203 1.16.2.2 skrll
2204 1.16.2.2 skrll /* Enable service interrupt */
2205 1.16.2.2 skrll ecr &= ~ATPPC_SERVICE_INTR;
2206 1.16.2.2 skrll atppc_w_ecr(atppc, ecr);
2207 1.16.2.2 skrll atppc_barrier_w(atppc);
2208 1.16.2.2 skrll
2209 1.16.2.2 skrll atppc->sc_outerr = atppc_wait_interrupt(atppc,
2210 1.16.2.2 skrll atppc->sc_outb, ATPPC_IRQ_FIFO);
2211 1.16.2.2 skrll if (atppc->sc_outerr) {
2212 1.16.2.2 skrll atppc_fifo_write_error(atppc, worklen);
2213 1.16.2.2 skrll return;
2214 1.16.2.2 skrll }
2215 1.16.2.2 skrll
2216 1.16.2.2 skrll /* Get register value recorded by interrupt handler */
2217 1.16.2.2 skrll ecr = atppc->sc_ecr_intr;
2218 1.16.2.2 skrll }
2219 1.16.2.2 skrll
2220 1.16.2.2 skrll /* Update pointer */
2221 1.16.2.2 skrll atppc->sc_outbstart += worklen;
2222 1.16.2.2 skrll }
2223 1.16.2.2 skrll }
2224 1.16.2.2 skrll
2225 1.16.2.2 skrll static void
2226 1.16.2.2 skrll atppc_fifo_write_pio(struct atppc_softc * const atppc, unsigned char ecr,
2227 1.16.2.2 skrll unsigned char ctr)
2228 1.16.2.2 skrll {
2229 1.16.2.2 skrll unsigned int len;
2230 1.16.2.2 skrll unsigned int worklen;
2231 1.16.2.2 skrll unsigned int timecount;
2232 1.16.2.2 skrll
2233 1.16.2.2 skrll /* Disable DMA */
2234 1.16.2.2 skrll ecr &= ~ATPPC_ENABLE_DMA;
2235 1.16.2.2 skrll atppc_w_ecr(atppc, ecr);
2236 1.16.2.2 skrll atppc_barrier_w(atppc);
2237 1.16.2.2 skrll
2238 1.16.2.2 skrll for (len = (atppc->sc_outb + atppc->sc_outb_nbytes) -
2239 1.16.2.2 skrll atppc->sc_outbstart; len > 0; len = (atppc->sc_outb +
2240 1.16.2.2 skrll atppc->sc_outb_nbytes) - atppc->sc_outbstart) {
2241 1.16.2.2 skrll
2242 1.16.2.2 skrll /* Wait for device to become ready */
2243 1.16.2.2 skrll atppc->sc_outerr = atppc_poll_str(atppc, SPP_READY, SPP_MASK);
2244 1.16.2.2 skrll if (atppc->sc_outerr)
2245 1.16.2.2 skrll return;
2246 1.16.2.2 skrll
2247 1.16.2.2 skrll /* Limit transfer to minimum of space in FIFO and buffer */
2248 1.16.2.2 skrll worklen = min(len, atppc->sc_fifo);
2249 1.16.2.2 skrll
2250 1.16.2.2 skrll /* Write to FIFO */
2251 1.16.2.2 skrll atppc_w_fifo_multi(atppc, atppc->sc_outbstart, worklen);
2252 1.16.2.2 skrll
2253 1.16.2.2 skrll timecount = 0;
2254 1.16.2.2 skrll if (atppc->sc_use & ATPPC_USE_INTR) {
2255 1.16.2.2 skrll ecr = atppc_r_ecr(atppc);
2256 1.16.2.2 skrll atppc_barrier_w(atppc);
2257 1.16.2.2 skrll
2258 1.16.2.2 skrll /* Wait for interrupt */
2259 1.16.2.2 skrll for (;;) {
2260 1.16.2.2 skrll if (ecr & ATPPC_FIFO_EMPTY) {
2261 1.16.2.2 skrll if (ecr & ATPPC_FIFO_FULL) {
2262 1.16.2.2 skrll atppc->sc_outerr = EIO;
2263 1.16.2.2 skrll atppc_fifo_write_error(atppc,
2264 1.16.2.2 skrll worklen);
2265 1.16.2.2 skrll return;
2266 1.16.2.2 skrll } else {
2267 1.16.2.2 skrll break;
2268 1.16.2.2 skrll }
2269 1.16.2.2 skrll }
2270 1.16.2.2 skrll
2271 1.16.2.2 skrll /* Enable service interrupt */
2272 1.16.2.2 skrll ecr &= ~ATPPC_SERVICE_INTR;
2273 1.16.2.2 skrll atppc_w_ecr(atppc, ecr);
2274 1.16.2.2 skrll atppc_barrier_w(atppc);
2275 1.16.2.2 skrll
2276 1.16.2.2 skrll atppc->sc_outerr = atppc_wait_interrupt(atppc,
2277 1.16.2.2 skrll atppc->sc_outb, ATPPC_IRQ_FIFO);
2278 1.16.2.2 skrll if (atppc->sc_outerr) {
2279 1.16.2.2 skrll atppc_fifo_write_error(atppc, worklen);
2280 1.16.2.2 skrll return;
2281 1.16.2.2 skrll }
2282 1.16.2.2 skrll
2283 1.16.2.2 skrll /* Get ECR value saved by interrupt handler */
2284 1.16.2.2 skrll ecr = atppc->sc_ecr_intr;
2285 1.16.2.2 skrll }
2286 1.16.2.2 skrll } else {
2287 1.16.2.2 skrll for (; timecount < ((MAXBUSYWAIT/hz)*1000000);
2288 1.16.2.2 skrll timecount++) {
2289 1.16.2.2 skrll
2290 1.16.2.2 skrll ecr = atppc_r_ecr(atppc);
2291 1.16.2.2 skrll atppc_barrier_r(atppc);
2292 1.16.2.2 skrll if (ecr & ATPPC_FIFO_EMPTY) {
2293 1.16.2.2 skrll if (ecr & ATPPC_FIFO_FULL) {
2294 1.16.2.2 skrll atppc->sc_outerr = EIO;
2295 1.16.2.2 skrll atppc_fifo_write_error(atppc,
2296 1.16.2.2 skrll worklen);
2297 1.16.2.2 skrll return;
2298 1.16.2.2 skrll } else {
2299 1.16.2.2 skrll break;
2300 1.16.2.2 skrll }
2301 1.16.2.2 skrll }
2302 1.16.2.2 skrll DELAY(1);
2303 1.16.2.2 skrll }
2304 1.16.2.2 skrll
2305 1.16.2.2 skrll if (((timecount*hz)/1000000) >= MAXBUSYWAIT) {
2306 1.16.2.2 skrll atppc->sc_outerr = EIO;
2307 1.16.2.2 skrll atppc_fifo_write_error(atppc, worklen);
2308 1.16.2.2 skrll return;
2309 1.16.2.2 skrll }
2310 1.16.2.2 skrll }
2311 1.16.2.2 skrll
2312 1.16.2.2 skrll /* Update pointer */
2313 1.16.2.2 skrll atppc->sc_outbstart += worklen;
2314 1.16.2.2 skrll }
2315 1.16.2.2 skrll }
2316 1.16.2.2 skrll
2317 1.16.2.2 skrll static void
2318 1.16.2.2 skrll atppc_fifo_write_error(struct atppc_softc * const atppc,
2319 1.16.2.2 skrll const unsigned int worklen)
2320 1.16.2.2 skrll {
2321 1.16.2.2 skrll unsigned char ecr = atppc_r_ecr(atppc);
2322 1.16.2.2 skrll
2323 1.16.2.2 skrll /* Abort DMA if not finished */
2324 1.16.2.2 skrll if (atppc->sc_dmastat == ATPPC_DMA_STARTED) {
2325 1.16.2.2 skrll atppc->sc_dma_abort(atppc);
2326 1.16.2.2 skrll ATPPC_DPRINTF(("%s: DMA interrupted.\n", __func__));
2327 1.16.2.2 skrll }
2328 1.16.2.2 skrll
2329 1.16.2.2 skrll /* Check for invalid states */
2330 1.16.2.2 skrll if ((ecr & ATPPC_FIFO_EMPTY) && (ecr & ATPPC_FIFO_FULL)) {
2331 1.16.2.2 skrll ATPPC_DPRINTF(("%s: FIFO full+empty bits set.\n", __func__));
2332 1.16.2.2 skrll } else if (!(ecr & ATPPC_FIFO_EMPTY)) {
2333 1.16.2.2 skrll unsigned char ctr = atppc_r_ctr(atppc);
2334 1.16.2.2 skrll int bytes_left;
2335 1.16.2.2 skrll int i;
2336 1.16.2.2 skrll
2337 1.16.2.2 skrll ATPPC_DPRINTF(("%s(%s): FIFO not empty.\n", __func__,
2338 1.16.2.2 skrll atppc->sc_dev.dv_xname));
2339 1.16.2.2 skrll
2340 1.16.2.2 skrll /* Drive strobe low to stop data transfer */
2341 1.16.2.2 skrll ctr &= ~STROBE;
2342 1.16.2.2 skrll atppc_w_ctr(atppc, ctr);
2343 1.16.2.2 skrll atppc_barrier_w(atppc);
2344 1.16.2.2 skrll
2345 1.16.2.2 skrll /* Determine how many bytes remain in FIFO */
2346 1.16.2.2 skrll for (i = 0; i < atppc->sc_fifo; i++) {
2347 1.16.2.2 skrll atppc_w_fifo(atppc, (unsigned char)i);
2348 1.16.2.2 skrll ecr = atppc_r_ecr(atppc);
2349 1.16.2.2 skrll atppc_barrier_r(atppc);
2350 1.16.2.2 skrll if (ecr & ATPPC_FIFO_FULL)
2351 1.16.2.2 skrll break;
2352 1.16.2.2 skrll }
2353 1.16.2.2 skrll bytes_left = (atppc->sc_fifo) - (i + 1);
2354 1.16.2.2 skrll ATPPC_DPRINTF(("%s: %d bytes left in FIFO.\n", __func__,
2355 1.16.2.2 skrll bytes_left));
2356 1.16.2.2 skrll
2357 1.16.2.2 skrll /* Update counter */
2358 1.16.2.2 skrll atppc->sc_outbstart += (worklen - bytes_left);
2359 1.16.2.2 skrll } else {
2360 1.16.2.2 skrll /* Update counter */
2361 1.16.2.2 skrll atppc->sc_outbstart += worklen;
2362 1.16.2.2 skrll }
2363 1.16.2.2 skrll
2364 1.16.2.2 skrll ATPPC_DPRINTF(("%s: reseting FIFO.\n", __func__));
2365 1.16.2.2 skrll atppc_w_ecr(atppc, ATPPC_ECR_PS2);
2366 1.16.2.2 skrll atppc_barrier_w(atppc);
2367 1.16.2.2 skrll }
2368 1.16.2.2 skrll
2369 1.16.2.2 skrll /*
2370 1.16.2.2 skrll * Poll status register using mask and status for MAXBUSYWAIT.
2371 1.16.2.2 skrll * Returns 0 if device ready, error value otherwise.
2372 1.16.2.2 skrll */
2373 1.16.2.2 skrll static int
2374 1.16.2.2 skrll atppc_poll_str(const struct atppc_softc * const atppc, const u_int8_t status,
2375 1.16.2.2 skrll const u_int8_t mask)
2376 1.16.2.2 skrll {
2377 1.16.2.2 skrll unsigned int timecount;
2378 1.16.2.2 skrll u_int8_t str;
2379 1.16.2.2 skrll int error = EIO;
2380 1.16.2.2 skrll
2381 1.16.2.2 skrll /* Wait for str to have status for MAXBUSYWAIT */
2382 1.16.2.2 skrll for (timecount = 0; timecount < ((MAXBUSYWAIT/hz)*1000000);
2383 1.16.2.2 skrll timecount++) {
2384 1.16.2.2 skrll
2385 1.16.2.2 skrll str = atppc_r_str(atppc);
2386 1.16.2.2 skrll atppc_barrier_r(atppc);
2387 1.16.2.2 skrll if ((str & mask) == status) {
2388 1.16.2.2 skrll error = 0;
2389 1.16.2.2 skrll break;
2390 1.16.2.2 skrll }
2391 1.16.2.2 skrll DELAY(1);
2392 1.16.2.2 skrll }
2393 1.16.2.2 skrll
2394 1.16.2.2 skrll return error;
2395 1.16.2.2 skrll }
2396 1.16.2.2 skrll
2397 1.16.2.2 skrll /* Wait for interrupt for MAXBUSYWAIT: returns 0 if acknowledge received. */
2398 1.16.2.2 skrll static int
2399 1.16.2.2 skrll atppc_wait_interrupt(struct atppc_softc * const atppc, const caddr_t where,
2400 1.16.2.2 skrll const u_int8_t irqstat)
2401 1.16.2.2 skrll {
2402 1.16.2.2 skrll int error = EIO;
2403 1.16.2.2 skrll
2404 1.16.2.2 skrll atppc->sc_irqstat &= ~irqstat;
2405 1.16.2.2 skrll
2406 1.16.2.2 skrll /* Wait for interrupt for MAXBUSYWAIT */
2407 1.16.2.2 skrll error = ltsleep(where, PPBUSPRI | PCATCH, __func__, MAXBUSYWAIT,
2408 1.16.2.2 skrll ATPPC_SC_LOCK(atppc));
2409 1.16.2.2 skrll
2410 1.16.2.2 skrll if (!(error) && (atppc->sc_irqstat & irqstat)) {
2411 1.16.2.2 skrll atppc->sc_irqstat &= ~irqstat;
2412 1.16.2.2 skrll error = 0;
2413 1.16.2.2 skrll }
2414 1.16.2.2 skrll
2415 1.16.2.2 skrll return error;
2416 1.16.2.2 skrll }
2417