xref: /netbsd/sys/arch/sgimips/hpc/pi1ppc.c (revision 3a97f79e)
1 /* $NetBSD: pi1ppc.c,v 1.1 2005/12/28 08:31:09 kurahone Exp $ */
2 
3 /*
4  * Copyright (c) 2001 Alcove - Nicolas Souchu
5  * Copyright (c) 2003, 2004 Gary Thorpe <gathorpe@users.sourceforge.net>
6  * Copyright (c) 2005 Joe Britt <britt@danger.com> - SGI PI1 version
7  * All rights reserved.
8  *
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29  * SUCH DAMAGE.
30  *
31  * FreeBSD: src/sys/isa/ppc.c,v 1.26.2.5 2001/10/02 05:21:45 nsouch Exp
32  *
33  */
34 
35 #include <sys/cdefs.h>
36 __KERNEL_RCSID(0, "$NetBSD: pi1ppc.c,v 1.1 2005/12/28 08:31:09 kurahone Exp $");
37 
38 #include "opt_pi1ppc.h"
39 
40 #include <sys/types.h>
41 #include <sys/param.h>
42 #include <sys/kernel.h>
43 #include <sys/device.h>
44 #include <sys/malloc.h>
45 #include <sys/proc.h>
46 #include <sys/systm.h>
47 #include <sys/vnode.h>
48 #include <sys/syslog.h>
49 
50 #include <machine/bus.h>
51 /*#include <machine/intr.h>*/
52 
53 #include <dev/ppbus/ppbus_conf.h>
54 #include <dev/ppbus/ppbus_msq.h>
55 #include <dev/ppbus/ppbus_io.h>
56 #include <dev/ppbus/ppbus_var.h>
57 
58 #include <machine/autoconf.h>
59 #include <machine/machtype.h>
60 
61 #include <sgimips/ioc/iocreg.h>
62 
63 #include <sgimips/hpc/hpcvar.h>
64 #include <sgimips/hpc/hpcreg.h>
65 
66 #include <sgimips/hpc/pi1ppcreg.h>
67 #include <sgimips/hpc/pi1ppcvar.h>
68 
69 #ifdef PI1PPC_DEBUG
70 int pi1ppc_debug = 1;
71 #endif
72 
73 #ifdef PI1PPC_VERBOSE
74 int pi1ppc_verbose = 1;
75 #endif
76 
77 
78 /* Prototypes for functions. */
79 
80 /* PC-style register emulation */
81 static u_int8_t r_reg(int reg, struct pi1ppc_softc *pi1ppc);
82 static void w_reg(int reg, struct pi1ppc_softc *pi1ppc, u_int8_t byte);
83 
84 #define	AT_DATA_REG	0
85 #define	AT_STAT_REG	1
86 #define	AT_CTL_REG	2
87 
88 #define pi1ppc_r_str(_x)	r_reg(AT_STAT_REG,_x)
89 #define	pi1ppc_r_ctr(_x)	r_reg(AT_CTL_REG,_x)
90 #define	pi1ppc_r_dtr(_x)	r_reg(AT_DATA_REG,_x)
91 
92 #define	pi1ppc_w_str(_x,_y)
93 #define	pi1ppc_w_ctr(_x,_y)	w_reg(AT_CTL_REG,_x,_y)
94 #define	pi1ppc_w_dtr(_x,_y)	w_reg(AT_DATA_REG,_x,_y)
95 
96 /* do we need to do these? */
97 #define	pi1ppc_barrier_r(_x) bus_space_barrier(_x->sc_iot,_x->sc_ioh, \
98 					0,4,BUS_SPACE_BARRIER_READ)
99 #define	pi1ppc_barrier_w(_x) bus_space_barrier(_x->sc_iot,_x->sc_ioh, \
100 					0,4,BUS_SPACE_BARRIER_WRITE)
101 #define	pi1ppc_barrier(_x)  pi1ppc_barrier_r(_x)
102 
103 
104 /* Print function for config_found() */
105 static int pi1ppc_print(void *, const char *);
106 
107 /* Routines for ppbus interface (bus + device) */
108 static int pi1ppc_read(struct device *, char *, int, int, size_t *);
109 static int pi1ppc_write(struct device *, char *, int, int, size_t *);
110 static int pi1ppc_setmode(struct device *, int);
111 static int pi1ppc_getmode(struct device *);
112 static int pi1ppc_exec_microseq(struct device *, struct ppbus_microseq * *);
113 static u_int8_t pi1ppc_io(struct device *, int, u_char *, int, u_char);
114 static int pi1ppc_read_ivar(struct device *, int, unsigned int *);
115 static int pi1ppc_write_ivar(struct device *, int, unsigned int *);
116 static int pi1ppc_add_handler(struct device *, void (*)(void *), void *);
117 static int pi1ppc_remove_handler(struct device *, void (*)(void *));
118 
119 /* no-ops, do any IOC machines have ECP/EPP-capable ports? */
120 static void pi1ppc_reset_epp_timeout(struct device *);
121 static void pi1ppc_ecp_sync(struct device *);
122 
123 /* Utility functions */
124 
125 /* Functions to read bytes into device's input buffer */
126 static void pi1ppc_nibble_read(struct pi1ppc_softc * const);
127 static void pi1ppc_byte_read(struct pi1ppc_softc * const);
128 
129 /* Functions to write bytes to device's output buffer */
130 static void pi1ppc_std_write(struct pi1ppc_softc * const);
131 
132 /* Miscellaneous */
133 static void pi1ppc_set_intr_mask(struct pi1ppc_softc * const, u_int8_t);
134 static u_int8_t pi1ppc_get_intr_stat(struct pi1ppc_softc * const);
135 
136 #ifdef USE_INDY_ACK_HACK
137 static u_int8_t pi1ppc_get_intr_mask(struct pi1ppc_softc * const);
138 #endif
139 
140 static int pi1ppc_poll_str(struct pi1ppc_softc * const, const u_int8_t,
141 	const u_int8_t);
142 static int pi1ppc_wait_interrupt(struct pi1ppc_softc * const, const caddr_t,
143 	const u_int8_t);
144 
145 static int pi1ppc_poll_interrupt_stat(struct pi1ppc_softc * const,
146 	const u_int8_t);
147 
148 static int pi1ppc_match(struct device * parent, struct cfdata * match, void *aux);
149 static void pi1ppc_attach(struct device * parent, struct device *self, void *aux);
150 
151 CFATTACH_DECL(pi1ppc, sizeof(struct pi1ppc_softc),
152 				pi1ppc_match,
153 				pi1ppc_attach,
154 				NULL,
155 				NULL);
156 
157 /* Currently only matching on Indy, though I think the Indigo1 also
158    uses PI1.  If it does, then the driver should work (if it is attached
159    at the appropriate base addr).
160  */
161 
162 static int
163 pi1ppc_match(struct device * parent, struct cfdata * match, void *aux)
164 {
165 	if (mach_type == MACH_SGI_IP22)
166 		return 1;
167 
168 	return 0;
169 }
170 
171 static void
172 pi1ppc_attach(struct device * parent, struct device *self, void *aux)
173 {
174 	struct pi1ppc_softc *sc;
175 	struct hpc_attach_args *haa;
176 
177 	sc = (struct pi1ppc_softc *)self;
178 	haa = aux;
179 	sc->sc_iot = haa->ha_st;
180 
181 	if (bus_space_subregion(haa->ha_st, haa->ha_sh, haa->ha_devoff,
182 			0x28, 		/* # bytes in par port regs */
183 			&sc->sc_ioh)) {
184 		aprint_error(": unable to map control registers\n");
185 		return;
186 	}
187 
188 	pi1ppc_sc_attach(sc);
189 }
190 
191 /*
192  * Generic attach and detach functions for pi1ppc device.
193  *
194  * If sc_dev_ok in soft configuration data is not ATPPC_ATTACHED, these should
195  * be skipped altogether.
196  */
197 
198 /* Soft configuration attach for pi1ppc */
199 void
200 pi1ppc_sc_attach(struct pi1ppc_softc *lsc)
201 {
202 	/* Adapter used to configure ppbus device */
203 	struct parport_adapter sc_parport_adapter;
204 	char buf[64];
205 
206 	PI1PPC_LOCK_INIT(lsc);
207 
208 	/* For a PC, this is where the installed chipset is probed.
209 	 * We *know* what we have, no need to probe.
210 	 */
211 	lsc->sc_type = PI1PPC_TYPE_INDY;
212 	lsc->sc_model = GENERIC;
213 
214 	/* XXX Once we support Interrupts & DMA, update this */
215 	lsc->sc_has = PI1PPC_HAS_PS2;
216 
217         /* Print out chipset capabilities */
218 	bitmask_snprintf(lsc->sc_has, "\20\1INTR\2DMA\3FIFO\4PS2\5ECP\6EPP",
219 		buf, sizeof(buf));
220 	printf("\n%s: capabilities=%s\n", lsc->sc_dev.dv_xname, buf);
221 
222 	/* Initialize device's buffer pointers */
223 	lsc->sc_outb = lsc->sc_outbstart = lsc->sc_inb = lsc->sc_inbstart
224 		= NULL;
225 	lsc->sc_inb_nbytes = lsc->sc_outb_nbytes = 0;
226 
227 	/* Last configuration step: set mode to standard mode */
228 	if (pi1ppc_setmode(&(lsc->sc_dev), PPBUS_COMPATIBLE) != 0) {
229 		PI1PPC_DPRINTF(("%s: unable to initialize mode.\n",
230 			lsc->sc_dev.dv_xname));
231 	}
232 
233 #if defined (MULTIPROCESSOR) || defined (LOCKDEBUG)
234 	/* Initialize lock structure */
235 	simple_lock_init(&(lsc->sc_lock));
236 #endif
237 
238 	/* Set up parport_adapter structure */
239 
240 	/* Set capabilites */
241 	sc_parport_adapter.capabilities = 0;
242 	if (lsc->sc_has & PI1PPC_HAS_INTR) {
243 		sc_parport_adapter.capabilities |= PPBUS_HAS_INTR;
244 	}
245 	if (lsc->sc_has & PI1PPC_HAS_DMA) {
246 		sc_parport_adapter.capabilities |= PPBUS_HAS_DMA;
247 	}
248 	if (lsc->sc_has & PI1PPC_HAS_FIFO) {
249 		sc_parport_adapter.capabilities |= PPBUS_HAS_FIFO;
250 	}
251 	if (lsc->sc_has & PI1PPC_HAS_PS2) {
252 		sc_parport_adapter.capabilities |= PPBUS_HAS_PS2;
253 	}
254 
255 	/* Set function pointers */
256 	sc_parport_adapter.parport_io = pi1ppc_io;
257 	sc_parport_adapter.parport_exec_microseq = pi1ppc_exec_microseq;
258 	sc_parport_adapter.parport_setmode = pi1ppc_setmode;
259 	sc_parport_adapter.parport_getmode = pi1ppc_getmode;
260 	sc_parport_adapter.parport_read = pi1ppc_read;
261 	sc_parport_adapter.parport_write = pi1ppc_write;
262 	sc_parport_adapter.parport_read_ivar = pi1ppc_read_ivar;
263 	sc_parport_adapter.parport_write_ivar = pi1ppc_write_ivar;
264 	sc_parport_adapter.parport_dma_malloc = lsc->sc_dma_malloc;
265 	sc_parport_adapter.parport_dma_free = lsc->sc_dma_free;
266 	sc_parport_adapter.parport_add_handler = pi1ppc_add_handler;
267 	sc_parport_adapter.parport_remove_handler = pi1ppc_remove_handler;
268 
269 	/* these are no-ops (does later machines have ECP/EPP support?) */
270 	sc_parport_adapter.parport_ecp_sync = pi1ppc_ecp_sync;
271 	sc_parport_adapter.parport_reset_epp_timeout =
272 		pi1ppc_reset_epp_timeout;
273 
274 	/* Initialize handler list, may be added to by grandchildren */
275 	SLIST_INIT(&(lsc->sc_handler_listhead));
276 
277 	/* Initialize interrupt state */
278 	lsc->sc_irqstat = PI1PPC_IRQ_NONE;
279 	lsc->sc_ecr_intr = lsc->sc_ctr_intr = lsc->sc_str_intr = 0;
280 
281 	/* Disable DMA/interrupts (each ppbus driver selects usage itself) */
282 	lsc->sc_use = 0;
283 
284 	/* Configure child of the device. */
285 	lsc->child = config_found(&(lsc->sc_dev), &(sc_parport_adapter),
286 		pi1ppc_print);
287 
288 	return;
289 }
290 
291 /* Soft configuration detach */
292 int
293 pi1ppc_sc_detach(struct pi1ppc_softc *lsc, int flag)
294 {
295 	struct device *dev = (struct device *)lsc;
296 
297 	/* Detach children devices */
298 	if (config_detach(lsc->child, flag) && !(flag & DETACH_QUIET)) {
299 		printf("%s not able to detach child device, ", dev->dv_xname);
300 
301 		if (!(flag & DETACH_FORCE)) {
302 			printf("cannot detach\n");
303 			return 1;
304 		} else {
305 			printf("continuing (DETACH_FORCE)\n");
306 		}
307 	}
308 
309 	if (!(flag & DETACH_QUIET))
310 		printf("%s detached", dev->dv_xname);
311 
312 	return 0;
313 }
314 
315 /* Used by config_found() to print out device information */
316 static int
317 pi1ppc_print(void *aux, const char *name)
318 {
319 	/* Print out something on failure. */
320 	if (name != NULL) {
321 		printf("%s: child devices", name);
322 		return UNCONF;
323 	}
324 
325 	return QUIET;
326 }
327 
328 /* Interrupt handler for pi1ppc device: wakes up read/write functions */
329 int
330 pi1ppcintr(void *arg)
331 {
332 /* NO INTERRUPTS YET */
333 #if 0
334 	struct pi1ppc_softc *pi1ppc = (struct pi1ppc_softc *)arg;
335 	struct device *dev = &pi1ppc->sc_dev;
336 	int claim = 1;
337 	enum { NONE, READER, WRITER } wake_up = NONE;
338 	int s;
339 
340 	s = splpi1ppc();
341 	PI1PPC_LOCK(pi1ppc);
342 
343 	/* Record registers' status */
344 	pi1ppc->sc_str_intr = pi1ppc_r_str(pi1ppc);
345 	pi1ppc->sc_ctr_intr = pi1ppc_r_ctr(pi1ppc);
346 	pi1ppc_barrier_r(pi1ppc);
347 
348 	/* Determine cause of interrupt and wake up top half */
349 	switch (atppc->sc_mode) {
350 	case ATPPC_MODE_STD:
351 		/* nAck pulsed for 5 usec, too fast to check reliably, assume */
352 		atppc->sc_irqstat = ATPPC_IRQ_nACK;
353 		if (atppc->sc_outb)
354 			wake_up = WRITER;
355 		else
356 			claim = 0;
357 		break;
358 
359 	case ATPPC_MODE_NIBBLE:
360 	case ATPPC_MODE_PS2:
361 		/* nAck is set low by device and then high on ack */
362 		if (!(atppc->sc_str_intr & nACK)) {
363 			claim = 0;
364 			break;
365 		}
366 		atppc->sc_irqstat = ATPPC_IRQ_nACK;
367 		if (atppc->sc_inb)
368 			wake_up = READER;
369 		break;
370 
371 	case ATPPC_MODE_ECP:
372 	case ATPPC_MODE_FAST:
373 		/* Confirm interrupt cause: these are not pulsed as in nAck. */
374 		if (atppc->sc_ecr_intr & ATPPC_SERVICE_INTR) {
375 			if (atppc->sc_ecr_intr & ATPPC_ENABLE_DMA)
376 				atppc->sc_irqstat |= ATPPC_IRQ_DMA;
377 			else
378 				atppc->sc_irqstat |= ATPPC_IRQ_FIFO;
379 
380 			/* Decide where top half will be waiting */
381 			if (atppc->sc_mode & ATPPC_MODE_ECP) {
382 				if (atppc->sc_ctr_intr & PCD) {
383 					if (atppc->sc_inb)
384 						wake_up = READER;
385 					else
386 						claim = 0;
387 				} else {
388 					if (atppc->sc_outb)
389 						wake_up = WRITER;
390 					else
391 						claim = 0;
392 				}
393 			} else {
394 				if (atppc->sc_outb)
395 					wake_up = WRITER;
396 				else
397 					claim = 0;
398 			}
399 		}
400 		/* Determine if nFault has occurred */
401 		if ((atppc->sc_mode & ATPPC_MODE_ECP) &&
402 			(atppc->sc_ecr_intr & ATPPC_nFAULT_INTR) &&
403 			!(atppc->sc_str_intr & nFAULT)) {
404 
405 			/* Device is requesting the channel */
406 			atppc->sc_irqstat |= ATPPC_IRQ_nFAULT;
407 			claim = 1;
408 		}
409 		break;
410 
411 	case ATPPC_MODE_EPP:
412 		/* nAck pulsed for 5 usec, too fast to check reliably */
413 		atppc->sc_irqstat = ATPPC_IRQ_nACK;
414 		if (atppc->sc_inb)
415 			wake_up = WRITER;
416 		else if (atppc->sc_outb)
417 			wake_up = READER;
418 		else
419 			claim = 0;
420 		break;
421 
422 	default:
423 		panic("%s: chipset is in invalid mode.", dev->dv_xname);
424 	}
425 
426 	if (claim) {
427 		switch (wake_up) {
428 		case NONE:
429 			break;
430 
431 		case READER:
432 			wakeup(atppc->sc_inb);
433 			break;
434 
435 		case WRITER:
436 			wakeup(atppc->sc_outb);
437 			break;
438 		}
439 	}
440 
441 	PI1PPC_UNLOCK(atppc);
442 
443 	/* Call all of the installed handlers */
444 	if (claim) {
445 		struct atppc_handler_node * callback;
446 		SLIST_FOREACH(callback, &(atppc->sc_handler_listhead),
447 			entries) {
448 				(*callback->func)(callback->arg);
449 		}
450 	}
451 
452 	splx(s);
453 
454 	return claim;
455 #else
456 	return 0;		/* NO INTERRUPTS YET */
457 #endif
458 }
459 
460 /* Functions which support ppbus interface */
461 
462 static void
463 pi1ppc_reset_epp_timeout(struct device *dev)
464 {
465 	return;
466 }
467 
468 /* Read from pi1ppc device: returns 0 on success. */
469 static int
470 pi1ppc_read(struct device *dev, char *buf, int len, int ioflag,
471 	size_t *cnt)
472 {
473 	struct pi1ppc_softc *pi1ppc = (struct pi1ppc_softc *)dev;
474 	int error = 0;
475 	int s;
476 
477 	s = splpi1ppc();
478 	PI1PPC_LOCK(pi1ppc);
479 
480 	*cnt = 0;
481 
482 	/* Initialize buffer */
483 	pi1ppc->sc_inb = pi1ppc->sc_inbstart = buf;
484 	pi1ppc->sc_inb_nbytes = len;
485 
486 	/* Initialize device input error state for new operation */
487 	pi1ppc->sc_inerr = 0;
488 
489 	/* Call appropriate function to read bytes */
490 	switch(pi1ppc->sc_mode) {
491 	case PI1PPC_MODE_STD:
492 		error = ENODEV;
493 		break;
494 
495 	case PI1PPC_MODE_NIBBLE:
496 		pi1ppc_nibble_read(pi1ppc);
497 		break;
498 
499 	case PI1PPC_MODE_PS2:
500 		pi1ppc_byte_read(pi1ppc);
501 		break;
502 
503 	default:
504 		panic("%s(%s): chipset in invalid mode.\n", __func__,
505 			dev->dv_xname);
506 	}
507 
508 	/* Update counter*/
509 	*cnt = (pi1ppc->sc_inbstart - pi1ppc->sc_inb);
510 
511 	/* Reset buffer */
512 	pi1ppc->sc_inb = pi1ppc->sc_inbstart = NULL;
513 	pi1ppc->sc_inb_nbytes = 0;
514 
515 	if (!(error))
516 		error = pi1ppc->sc_inerr;
517 
518 	PI1PPC_UNLOCK(pi1ppc);
519 	splx(s);
520 
521 	return (error);
522 }
523 
524 /* Write to pi1ppc device: returns 0 on success. */
525 static int
526 pi1ppc_write(struct device *dev, char *buf, int len, int ioflag, size_t *cnt)
527 {
528 	struct pi1ppc_softc * const pi1ppc = (struct pi1ppc_softc *)dev;
529 	int error = 0;
530 	int s;
531 
532 	*cnt = 0;
533 
534 	s = splpi1ppc();
535 	PI1PPC_LOCK(pi1ppc);
536 
537 	/* Set up line buffer */
538 	pi1ppc->sc_outb = pi1ppc->sc_outbstart = buf;
539 	pi1ppc->sc_outb_nbytes = len;
540 
541 	/* Initialize device output error state for new operation */
542 	pi1ppc->sc_outerr = 0;
543 
544 	/* Call appropriate function to write bytes */
545 	switch (pi1ppc->sc_mode) {
546 	case PI1PPC_MODE_STD:
547 		pi1ppc_std_write(pi1ppc);
548 		break;
549 
550 	case PI1PPC_MODE_NIBBLE:
551 	case PI1PPC_MODE_PS2:
552 		error = ENODEV;
553 		break;
554 
555 	default:
556 		panic("%s(%s): chipset in invalid mode.\n", __func__,
557 			dev->dv_xname);
558 	}
559 
560 	/* Update counter*/
561 	*cnt = (pi1ppc->sc_outbstart - pi1ppc->sc_outb);
562 
563 	/* Reset output buffer */
564 	pi1ppc->sc_outb = pi1ppc->sc_outbstart = NULL;
565 	pi1ppc->sc_outb_nbytes = 0;
566 
567 	if (!(error))
568 		error = pi1ppc->sc_outerr;
569 
570 	PI1PPC_UNLOCK(pi1ppc);
571 	splx(s);
572 
573 	return (error);
574 }
575 
576 /*
577  * Set mode of chipset to mode argument. Modes not supported are ignored. If
578  * multiple modes are flagged, the mode is not changed. Modes are those
579  * defined for ppbus_softc.sc_mode in ppbus_conf.h. Only ECP-capable chipsets
580  * can change their mode of operation. However, ALL operation modes support
581  * centronics mode and nibble mode. Modes determine both hardware AND software
582  * behaviour.
583  * NOTE: the mode for ECP should only be changed when the channel is in
584  * forward idle mode. This function does not make sure FIFO's have flushed or
585  * any consistency checks.
586  */
587 static int
588 pi1ppc_setmode(struct device *dev, int mode)
589 {
590 	struct pi1ppc_softc *pi1ppc = (struct pi1ppc_softc *)dev;
591 	u_int8_t ecr;
592 	u_int8_t chipset_mode;
593 	int s;
594 	int rval = 0;
595 
596 	s = splpi1ppc();
597 	PI1PPC_LOCK(pi1ppc);
598 
599 	switch (mode) {
600 	case PPBUS_PS2:
601 		/* Indy has this, other PI1 machines do too? */
602 		chipset_mode = PI1PPC_MODE_PS2;
603 		break;
604 
605 	case PPBUS_NIBBLE:
606 		/* Set nibble mode (virtual) */
607 		chipset_mode = PI1PPC_MODE_NIBBLE;
608 		break;
609 
610 	case PPBUS_COMPATIBLE:
611 		chipset_mode = PI1PPC_MODE_STD;
612 		break;
613 
614 	case PPBUS_ECP:
615 	case PPBUS_EPP:
616 		rval = ENODEV;
617 		goto end;
618 
619 	default:
620 		PI1PPC_DPRINTF(("%s(%s): invalid mode passed as "
621 			"argument.\n", __func__, dev->dv_xname));
622 		rval = ENODEV;
623 		goto end;
624 	}
625 
626 	pi1ppc->sc_mode = chipset_mode;
627 	if (chipset_mode == PI1PPC_MODE_PS2) {
628 		/* Set direction bit to reverse */
629 		ecr = pi1ppc_r_ctr(pi1ppc);
630 		pi1ppc_barrier_r(pi1ppc);
631 		ecr |= PCD;			/* data is INPUT */
632 		pi1ppc_w_ctr(pi1ppc, ecr);
633 		pi1ppc_barrier_w(pi1ppc);
634 	}
635 
636 end:
637 	PI1PPC_UNLOCK(pi1ppc);
638 	splx(s);
639 
640 	return rval;
641 }
642 
643 /* Get the current mode of chipset */
644 static int
645 pi1ppc_getmode(struct device *dev)
646 {
647 	struct pi1ppc_softc *pi1ppc = (struct pi1ppc_softc *)dev;
648 	int mode;
649 	int s;
650 
651 	s = splpi1ppc();
652 	PI1PPC_LOCK(pi1ppc);
653 
654 	/* The chipset can only be in one mode at a time logically */
655 	switch (pi1ppc->sc_mode) {
656 	case PI1PPC_MODE_PS2:
657 		mode = PPBUS_PS2;
658 		break;
659 
660 	case PI1PPC_MODE_STD:
661 		mode = PPBUS_COMPATIBLE;
662 		break;
663 
664 	case PI1PPC_MODE_NIBBLE:
665 		mode = PPBUS_NIBBLE;
666 		break;
667 
668 	default:
669 		panic("%s(%s): device is in invalid mode!", __func__,
670 			dev->dv_xname);
671 		break;
672 	}
673 
674 	PI1PPC_UNLOCK(pi1ppc);
675 	splx(s);
676 
677 	return mode;
678 }
679 
680 
681 /* Wait for FIFO buffer to empty for ECP-capable chipset */
682 static void
683 pi1ppc_ecp_sync(struct device *dev)
684 {
685 	return;
686 }
687 
688 /* Execute a microsequence to handle fast I/O operations. */
689 
690 /* microsequence registers are equivalent to PC-like port registers */
691 /* therefore, translate bit positions & polarities */
692 
693 /* Bit 4 of ctl_reg_int_en is used to emulate the PC's int enable
694    bit.  Without it, lpt doesn't like the port.
695  */
696 static u_int8_t ctl_reg_int_en = 0;
697 
698 static u_int8_t
699 r_reg(int reg, struct pi1ppc_softc *pi1ppc)
700 {
701 	int val = 0;
702 
703 	/* if we read the status reg, make it look like the PC */
704 	if(reg == AT_STAT_REG) {
705 		val = bus_space_read_4((pi1ppc)->sc_iot,
706 				(pi1ppc)->sc_ioh, IOC_PLP_STAT);
707 		val &= 0xff;
708 
709 		/* invert /BUSY */
710 		val ^= 0x80;
711 
712 		/* bit 2 reads as '1' on Indy (why?) */
713 		val &= 0xf8;
714 
715 		return val;
716 	}
717 
718 	/* if we read the ctl reg, make it look like the PC */
719 	if(reg == AT_CTL_REG) {
720 		val = bus_space_read_4((pi1ppc)->sc_iot,
721 				(pi1ppc)->sc_ioh, IOC_PLP_CTL);
722 		val &= 0xff;
723 
724 		/* get the dir bit in the right place */
725 		val = ((val >> 1) & 0x20) | (val & 0x0f);
726 
727 		/* invert /SEL, /AUTOFD, and /STB */
728 		val ^= 0x0b;
729 
730 		/* emulate the PC's int enable ctl bit */
731 		val |= (ctl_reg_int_en & 0x10);
732 
733 		return val;
734 	}
735 
736 	if(reg == AT_DATA_REG) {
737 		val = bus_space_read_4((pi1ppc)->sc_iot,
738 				(pi1ppc)->sc_ioh, IOC_PLP_DATA);
739 		val &= 0xff;
740 
741 		return val;
742 	}
743 
744 	return 0;
745 }
746 
747 static void
748 w_reg(int reg, struct pi1ppc_softc *pi1ppc, u_int8_t byte)
749 {
750 	/* don't try to write to the status reg */
751 
752 	/* if we are writing the ctl reg, adjust PC style -> IOC style */
753 	if(reg == AT_CTL_REG) {
754 		/* preserve pc-style int enable bit */
755 		ctl_reg_int_en = (byte & 0x10);
756 
757 		/* get the dir bit in the right place */
758 		byte = ((byte << 1) & 0x40) | (byte & 0x0f);
759 
760 		/* invert /SEL, /AUTOFD, and /STB */
761 		byte ^= 0x0b;
762 
763 		bus_space_write_4((pi1ppc)->sc_iot,
764 				(pi1ppc)->sc_ioh, IOC_PLP_CTL, byte);
765 	}
766 
767 	if(reg == AT_DATA_REG) {
768 		bus_space_write_4((pi1ppc)->sc_iot,
769 				(pi1ppc)->sc_ioh, IOC_PLP_DATA, byte);
770 	}
771 }
772 
773 static int
774 pi1ppc_exec_microseq(struct device *dev, struct ppbus_microseq **p_msq)
775 {
776 	struct pi1ppc_softc *pi1ppc = (struct pi1ppc_softc *)dev;
777 	struct ppbus_microseq *mi = *p_msq;
778 	char cc, *p;
779 	int i, iter, len;
780 	int error;
781 	int s;
782 	register int reg;
783 	register unsigned char mask;
784 	register int accum = 0;
785 	register char *ptr = NULL;
786 	struct ppbus_microseq *stack = NULL;
787 
788 	s = splpi1ppc();
789 	PI1PPC_LOCK(pi1ppc);
790 
791 	/* Loop until microsequence execution finishes (ending op code) */
792 	for (;;) {
793 		switch (mi->opcode) {
794 		case MS_OP_RSET:
795 			cc = r_reg(mi->arg[0].i, pi1ppc);
796 			pi1ppc_barrier_r(pi1ppc);
797 			cc &= (char)mi->arg[2].i;	/* clear mask */
798 			cc |= (char)mi->arg[1].i;	/* assert mask */
799 			w_reg(mi->arg[0].i, pi1ppc, cc);
800 			pi1ppc_barrier_w(pi1ppc);
801 			mi++;
802                        	break;
803 
804 		case MS_OP_RASSERT_P:
805 			reg = mi->arg[1].i;
806 			ptr = pi1ppc->sc_ptr;
807 
808 			if ((len = mi->arg[0].i) == MS_ACCUM) {
809 				accum = pi1ppc->sc_accum;
810 				for (; accum; accum--) {
811 					w_reg(reg, pi1ppc, *ptr++);
812 					pi1ppc_barrier_w(pi1ppc);
813 				}
814 				pi1ppc->sc_accum = accum;
815 			} else {
816 				for (i = 0; i < len; i++) {
817 					w_reg(reg, pi1ppc, *ptr++);
818 					pi1ppc_barrier_w(pi1ppc);
819 				}
820 			}
821 
822 			pi1ppc->sc_ptr = ptr;
823 			mi++;
824 			break;
825 
826        	        case MS_OP_RFETCH_P:
827 			reg = mi->arg[1].i;
828 			mask = (char)mi->arg[2].i;
829 			ptr = pi1ppc->sc_ptr;
830 
831 			if ((len = mi->arg[0].i) == MS_ACCUM) {
832 				accum = pi1ppc->sc_accum;
833 				for (; accum; accum--) {
834 					*ptr++ = r_reg(reg, pi1ppc) & mask;
835 					pi1ppc_barrier_r(pi1ppc);
836 				}
837 				pi1ppc->sc_accum = accum;
838 			} else {
839 				for (i = 0; i < len; i++) {
840 					*ptr++ = r_reg(reg, pi1ppc) & mask;
841 					pi1ppc_barrier_r(pi1ppc);
842 				}
843 			}
844 
845 			pi1ppc->sc_ptr = ptr;
846 			mi++;
847 			break;
848 
849                 case MS_OP_RFETCH:
850 			*((char *)mi->arg[2].p) = r_reg(mi->arg[0].i, pi1ppc) &
851 				(char)mi->arg[1].i;
852 			pi1ppc_barrier_r(pi1ppc);
853 			mi++;
854        	                break;
855 
856 		case MS_OP_RASSERT:
857                 case MS_OP_DELAY:
858 			/* let's suppose the next instr. is the same */
859 			do {
860 				for (;mi->opcode == MS_OP_RASSERT; mi++) {
861 					w_reg(mi->arg[0].i, pi1ppc,
862 						(char)mi->arg[1].i);
863 					pi1ppc_barrier_w(pi1ppc);
864 				}
865 
866 				for (;mi->opcode == MS_OP_DELAY; mi++) {
867 					delay(mi->arg[0].i);
868 				}
869 			} while (mi->opcode == MS_OP_RASSERT);
870 			break;
871 
872 		case MS_OP_ADELAY:
873 			if (mi->arg[0].i) {
874 				tsleep(pi1ppc, PPBUSPRI, "pi1ppcdelay",
875 					mi->arg[0].i * (hz/1000));
876 			}
877 			mi++;
878 			break;
879 
880 		case MS_OP_TRIG:
881 			reg = mi->arg[0].i;
882 			iter = mi->arg[1].i;
883 			p = (char *)mi->arg[2].p;
884 
885 			/* XXX delay limited to 255 us */
886 			for (i = 0; i < iter; i++) {
887 				w_reg(reg, pi1ppc, *p++);
888 				pi1ppc_barrier_w(pi1ppc);
889 				delay((unsigned char)*p++);
890 			}
891 
892 			mi++;
893 			break;
894 
895 		case MS_OP_SET:
896                         pi1ppc->sc_accum = mi->arg[0].i;
897 			mi++;
898                        	break;
899 
900 		case MS_OP_DBRA:
901                        	if (--pi1ppc->sc_accum > 0) {
902                                	mi += mi->arg[0].i;
903 			}
904 
905 			mi++;
906 			break;
907 
908 		case MS_OP_BRSET:
909 			cc = pi1ppc_r_str(pi1ppc);
910 			pi1ppc_barrier_r(pi1ppc);
911 			if ((cc & (char)mi->arg[0].i) == (char)mi->arg[0].i) {
912 				mi += mi->arg[1].i;
913 			}
914 			mi++;
915 			break;
916 
917 		case MS_OP_BRCLEAR:
918 			cc = pi1ppc_r_str(pi1ppc);
919 			pi1ppc_barrier_r(pi1ppc);
920 			if ((cc & (char)mi->arg[0].i) == 0) {
921 				mi += mi->arg[1].i;
922 			}
923 			mi++;
924 			break;
925 
926 		case MS_OP_BRSTAT:
927 			cc = pi1ppc_r_str(pi1ppc);
928 			pi1ppc_barrier_r(pi1ppc);
929 			if ((cc & ((char)mi->arg[0].i | (char)mi->arg[1].i)) ==
930 				(char)mi->arg[0].i) {
931 				mi += mi->arg[2].i;
932 			}
933 			mi++;
934 			break;
935 
936 		case MS_OP_C_CALL:
937 			/*
938 			 * If the C call returns !0 then end the microseq.
939 			 * The current state of ptr is passed to the C function
940 			 */
941 			if ((error = mi->arg[0].f(mi->arg[1].p,
942 				pi1ppc->sc_ptr))) {
943 				PI1PPC_UNLOCK(pi1ppc);
944 				splx(s);
945 				return (error);
946 			}
947 			mi++;
948 			break;
949 
950 		case MS_OP_PTR:
951 			pi1ppc->sc_ptr = (char *)mi->arg[0].p;
952 			mi++;
953 			break;
954 
955 		case MS_OP_CALL:
956 			if (stack) {
957 				panic("%s - %s: too many calls", dev->dv_xname,
958 					__func__);
959 			}
960 
961 			if (mi->arg[0].p) {
962 				/* store state of the actual microsequence */
963 				stack = mi;
964 
965 				/* jump to the new microsequence */
966 				mi = (struct ppbus_microseq *)mi->arg[0].p;
967 			} else {
968 				mi++;
969 			}
970 			break;
971 
972 		case MS_OP_SUBRET:
973 			/* retrieve microseq and pc state before the call */
974 			mi = stack;
975 
976 			/* reset the stack */
977 			stack = 0;
978 
979 			/* XXX return code */
980 
981 			mi++;
982 			break;
983 
984 		case MS_OP_PUT:
985 		case MS_OP_GET:
986 		case MS_OP_RET:
987 			/*
988 			 * Can't return to pi1ppc level during the execution
989 			 * of a submicrosequence.
990 			 */
991 			if (stack) {
992 				panic("%s: cannot return to pi1ppc level",
993 					__func__);
994 			}
995 			/* update pc for pi1ppc level of execution */
996 			*p_msq = mi;
997 
998 			PI1PPC_UNLOCK(pi1ppc);
999 			splx(s);
1000 			return (0);
1001 			break;
1002 
1003 		default:
1004 			panic("%s: unknown microsequence "
1005 				"opcode 0x%x", __func__, mi->opcode);
1006 			break;
1007 		}
1008 	}
1009 
1010 	/* Should not be reached! */
1011 #ifdef PI1PPC_DEBUG
1012 	panic("%s: unexpected code reached!\n", __func__);
1013 #endif
1014 }
1015 
1016 /* General I/O routine */
1017 static u_int8_t
1018 pi1ppc_io(struct device *dev, int iop, u_char *addr, int cnt, u_char byte)
1019 {
1020 	struct pi1ppc_softc *pi1ppc = (struct pi1ppc_softc *)dev;
1021 	u_int8_t val = 0;
1022 	int s;
1023 
1024 	s = splpi1ppc();
1025 	PI1PPC_LOCK(pi1ppc);
1026 
1027 	switch (iop) {
1028 	case PPBUS_RDTR:
1029 		val = r_reg(AT_DATA_REG, pi1ppc);
1030 		break;
1031 	case PPBUS_RSTR:
1032 		val = r_reg(AT_STAT_REG, pi1ppc);
1033 		break;
1034 	case PPBUS_RCTR:
1035 		val = r_reg(AT_CTL_REG, pi1ppc);
1036 		break;
1037 	case PPBUS_WDTR:
1038 		w_reg(AT_DATA_REG, pi1ppc, byte);
1039 		break;
1040 	case PPBUS_WSTR:
1041 		/* writing to the status register is weird */
1042 		break;
1043 	case PPBUS_WCTR:
1044 		w_reg(AT_CTL_REG, pi1ppc, byte);
1045 		break;
1046 	default:
1047 		panic("%s(%s): unknown I/O operation", dev->dv_xname,
1048 			__func__);
1049 		break;
1050 	}
1051 
1052 	pi1ppc_barrier(pi1ppc);
1053 
1054 	PI1PPC_UNLOCK(pi1ppc);
1055 	splx(s);
1056 
1057 	return val;
1058 }
1059 
1060 /* Read "instance variables" of pi1ppc device */
1061 static int
1062 pi1ppc_read_ivar(struct device *dev, int index, unsigned int *val)
1063 {
1064 	struct pi1ppc_softc *pi1ppc = (struct pi1ppc_softc *)dev;
1065 	int rval = 0;
1066 	int s;
1067 
1068 	s = splpi1ppc();
1069 	PI1PPC_LOCK(pi1ppc);
1070 
1071 	switch(index) {
1072 	case PPBUS_IVAR_INTR:
1073 		*val = ((pi1ppc->sc_use & PI1PPC_USE_INTR) != 0);
1074 		break;
1075 
1076 	case PPBUS_IVAR_DMA:
1077 		*val = ((pi1ppc->sc_use & PI1PPC_USE_DMA) != 0);
1078 		break;
1079 
1080 	default:
1081 		rval = ENODEV;
1082 	}
1083 
1084 	PI1PPC_UNLOCK(pi1ppc);
1085 	splx(s);
1086 
1087 	return rval;
1088 }
1089 
1090 /* Write "instance varaibles" of pi1ppc device */
1091 static int
1092 pi1ppc_write_ivar(struct device *dev, int index, unsigned int *val)
1093 {
1094 	struct pi1ppc_softc *pi1ppc = (struct pi1ppc_softc *)dev;
1095 	int rval = 0;
1096 	int s;
1097 
1098 	s = splpi1ppc();
1099 	PI1PPC_LOCK(pi1ppc);
1100 
1101 	switch(index) {
1102 	case PPBUS_IVAR_INTR:
1103 		if (*val == 0)
1104 			pi1ppc->sc_use &= ~PI1PPC_USE_INTR;
1105 		else if (pi1ppc->sc_has & PI1PPC_HAS_INTR)
1106 			pi1ppc->sc_use |= PI1PPC_USE_INTR;
1107 		else
1108 			rval = ENODEV;
1109 		break;
1110 
1111 	case PPBUS_IVAR_DMA:
1112 		if (*val == 0)
1113 			pi1ppc->sc_use &= ~PI1PPC_USE_DMA;
1114 		else if (pi1ppc->sc_has & PI1PPC_HAS_DMA)
1115 			pi1ppc->sc_use |= PI1PPC_USE_DMA;
1116 		else
1117 			rval = ENODEV;
1118 		break;
1119 
1120 	default:
1121 		rval = ENODEV;
1122 	}
1123 
1124 	PI1PPC_UNLOCK(pi1ppc);
1125 	splx(s);
1126 
1127 	return rval;
1128 }
1129 
1130 /* Add a handler routine to be called by the interrupt handler */
1131 static int
1132 pi1ppc_add_handler(struct device *dev, void (*handler)(void *), void *arg)
1133 {
1134 	struct pi1ppc_softc *pi1ppc = (struct pi1ppc_softc *)dev;
1135 	struct pi1ppc_handler_node *callback;
1136 	int rval = 0;
1137 	int s;
1138 
1139 	s = splpi1ppc();
1140 	PI1PPC_LOCK(pi1ppc);
1141 
1142 	if (handler == NULL) {
1143 		PI1PPC_DPRINTF(("%s(%s): attempt to register NULL handler.\n",
1144 			__func__, dev->dv_xname));
1145 		rval = EINVAL;
1146 	} else {
1147 		callback = malloc(sizeof(struct pi1ppc_handler_node), M_DEVBUF,
1148 			M_NOWAIT);
1149 		if (callback) {
1150 			callback->func = handler;
1151 			callback->arg = arg;
1152 			SLIST_INSERT_HEAD(&(pi1ppc->sc_handler_listhead),
1153 				callback, entries);
1154 		} else {
1155 			rval = ENOMEM;
1156 		}
1157 	}
1158 
1159 	PI1PPC_UNLOCK(pi1ppc);
1160 	splx(s);
1161 
1162 	return rval;
1163 }
1164 
1165 /* Remove a handler added by pi1ppc_add_handler() */
1166 static int
1167 pi1ppc_remove_handler(struct device *dev, void (*handler)(void *))
1168 {
1169 	struct pi1ppc_softc *pi1ppc = (struct pi1ppc_softc *)dev;
1170 	struct pi1ppc_handler_node *callback;
1171 	int rval = EINVAL;
1172 	int s;
1173 
1174 	s = splpi1ppc();
1175 	PI1PPC_LOCK(pi1ppc);
1176 
1177 	if (SLIST_EMPTY(&(pi1ppc->sc_handler_listhead)))
1178 		panic("%s(%s): attempt to remove handler from empty list.\n",
1179 			__func__, dev->dv_xname);
1180 
1181 	/* Search list for handler */
1182 	SLIST_FOREACH(callback, &(pi1ppc->sc_handler_listhead), entries) {
1183 		if (callback->func == handler) {
1184 			SLIST_REMOVE(&(pi1ppc->sc_handler_listhead), callback,
1185 				pi1ppc_handler_node, entries);
1186 			free(callback, M_DEVBUF);
1187 			rval = 0;
1188 			break;
1189 		}
1190 	}
1191 
1192 	PI1PPC_UNLOCK(pi1ppc);
1193 	splx(s);
1194 
1195 	return rval;
1196 }
1197 
1198 /* Utility functions */
1199 
1200 /*
1201  * Functions that read bytes from port into buffer: called from interrupt
1202  * handler depending on current chipset mode and cause of interrupt. Return
1203  * value: number of bytes moved.
1204  */
1205 
1206 /* note: BUSY is inverted in the PC world, but not on Indy, but the r_reg()
1207 	 and w_reg() functions make the Indy look like the PC. */
1208 
1209 /* Only the lower 4 bits of the final value are valid */
1210 #define nibble2char(s) ((((s) & ~nACK) >> 3) | (~(s) & nBUSY) >> 4)
1211 
1212 
1213 /* Read bytes in nibble mode */
1214 static void
1215 pi1ppc_nibble_read(struct pi1ppc_softc *pi1ppc)
1216 {
1217 	int i;
1218 	u_int8_t nibble[2];
1219 	u_int8_t ctr;
1220 	u_int8_t str;
1221 
1222 	/* Enable interrupts if needed */
1223 	if (pi1ppc->sc_use & PI1PPC_USE_INTR) {
1224 
1225 		/* XXX JOE - need code to enable interrupts
1226 				--> emulate PC behavior in r_reg/w_reg
1227 		*/
1228 #if 0
1229 		ctr = pi1ppc_r_ctr(pi1ppc);
1230 		pi1ppc_barrier_r(ioppc);
1231 		if (!(ctr & IRQENABLE)) {
1232 			ctr |= IRQENABLE;
1233 			pi1ppc_w_ctr(pi1ppc, ctr);
1234 			pi1ppc_barrier_w(pi1ppc);
1235 		}
1236 #endif
1237 	}
1238 
1239 	while (pi1ppc->sc_inbstart < (pi1ppc->sc_inb + pi1ppc->sc_inb_nbytes)) {
1240 		/* Check if device has data to send in idle phase */
1241 		str = pi1ppc_r_str(pi1ppc);
1242 		pi1ppc_barrier_r(pi1ppc);
1243 		if (str & nDATAVAIL) {
1244 			return;
1245 		}
1246 
1247 		/* Nibble-mode handshake transfer */
1248 		for (i = 0; i < 2; i++) {
1249 			/* Event 7 - ready to take data (HOSTBUSY low) */
1250 			ctr = pi1ppc_r_ctr(pi1ppc);
1251 			pi1ppc_barrier_r(pi1ppc);
1252 			ctr |= HOSTBUSY;
1253 			pi1ppc_w_ctr(pi1ppc, ctr);
1254 			pi1ppc_barrier_w(pi1ppc);
1255 
1256 			/* Event 8 - peripheral writes the first nibble */
1257 
1258 			/* Event 9 - peripheral set nAck low */
1259 			pi1ppc->sc_inerr = pi1ppc_poll_str(pi1ppc, 0, PTRCLK);
1260 			if (pi1ppc->sc_inerr)
1261 				return;
1262 
1263 			/* read nibble */
1264 			nibble[i] = pi1ppc_r_str(pi1ppc);
1265 
1266 			/* Event 10 - ack, nibble received */
1267 			ctr &= ~HOSTBUSY;
1268 			pi1ppc_w_ctr(pi1ppc, ctr);
1269 
1270 			/* Event 11 - wait ack from peripherial */
1271 			if (pi1ppc->sc_use & PI1PPC_USE_INTR)
1272 				pi1ppc->sc_inerr = pi1ppc_wait_interrupt(pi1ppc,
1273 					pi1ppc->sc_inb, PI1PPC_IRQ_nACK);
1274 			else
1275 				pi1ppc->sc_inerr = pi1ppc_poll_str(pi1ppc, PTRCLK,
1276 					PTRCLK);
1277 			if (pi1ppc->sc_inerr)
1278 				return;
1279 		}
1280 
1281 		/* Store byte transfered */
1282 		*(pi1ppc->sc_inbstart) = ((nibble2char(nibble[1]) << 4) & 0xf0) |
1283 			(nibble2char(nibble[0]) & 0x0f);
1284 		pi1ppc->sc_inbstart++;
1285 	}
1286 }
1287 
1288 /* Read bytes in bidirectional mode */
1289 static void
1290 pi1ppc_byte_read(struct pi1ppc_softc * const pi1ppc)
1291 {
1292 	u_int8_t ctr;
1293 	u_int8_t str;
1294 
1295 	/* Check direction bit */
1296 	ctr = pi1ppc_r_ctr(pi1ppc);
1297 	pi1ppc_barrier_r(pi1ppc);
1298 	if (!(ctr & PCD)) {
1299 		PI1PPC_DPRINTF(("%s: byte-mode read attempted without direction "
1300 			"bit set.", pi1ppc->sc_dev.dv_xname));
1301 		pi1ppc->sc_inerr = ENODEV;
1302 		return;
1303 	}
1304 	/* Enable interrupts if needed */
1305 
1306 		/* XXX JOE - need code to enable interrupts */
1307 #if 0
1308 	if (pi1ppc->sc_use & PI1PPC_USE_INTR) {
1309 		if (!(ctr & IRQENABLE)) {
1310 			ctr |= IRQENABLE;
1311 			pi1ppc_w_ctr(pi1ppc, ctr);
1312 			pi1ppc_barrier_w(pi1ppc);
1313 		}
1314 	}
1315 #endif
1316 
1317 	/* Byte-mode handshake transfer */
1318 	while (pi1ppc->sc_inbstart < (pi1ppc->sc_inb + pi1ppc->sc_inb_nbytes)) {
1319 		/* Check if device has data to send */
1320 		str = pi1ppc_r_str(pi1ppc);
1321 		pi1ppc_barrier_r(pi1ppc);
1322 		if (str & nDATAVAIL) {
1323 			return;
1324 		}
1325 
1326 		/* Event 7 - ready to take data (nAUTO low) */
1327 		ctr |= HOSTBUSY;
1328 		pi1ppc_w_ctr(pi1ppc, ctr);
1329 		pi1ppc_barrier_w(pi1ppc);
1330 
1331 		/* Event 9 - peripheral set nAck low */
1332 		pi1ppc->sc_inerr = pi1ppc_poll_str(pi1ppc, 0, PTRCLK);
1333 		if (pi1ppc->sc_inerr)
1334 			return;
1335 
1336 		/* Store byte transfered */
1337 		*(pi1ppc->sc_inbstart) = pi1ppc_r_dtr(pi1ppc);
1338 		pi1ppc_barrier_r(pi1ppc);
1339 
1340 		/* Event 10 - data received, can't accept more */
1341 		ctr &= ~HOSTBUSY;
1342 		pi1ppc_w_ctr(pi1ppc, ctr);
1343 		pi1ppc_barrier_w(pi1ppc);
1344 
1345 		/* Event 11 - peripheral ack */
1346 		if (pi1ppc->sc_use & PI1PPC_USE_INTR)
1347 			pi1ppc->sc_inerr = pi1ppc_wait_interrupt(pi1ppc,
1348 				pi1ppc->sc_inb, PI1PPC_IRQ_nACK);
1349 		else
1350 			pi1ppc->sc_inerr = pi1ppc_poll_str(pi1ppc, PTRCLK, PTRCLK);
1351 		if (pi1ppc->sc_inerr)
1352 			return;
1353 
1354 		/* Event 16 - strobe */
1355 		str |= HOSTCLK;
1356 		pi1ppc_w_str(pi1ppc, str);
1357 		pi1ppc_barrier_w(pi1ppc);
1358 		DELAY(1);
1359 		str &= ~HOSTCLK;
1360 		pi1ppc_w_str(pi1ppc, str);
1361 		pi1ppc_barrier_w(pi1ppc);
1362 
1363 		/* Update counter */
1364 		pi1ppc->sc_inbstart++;
1365 	}
1366 }
1367 
1368 /*
1369  * Functions that write bytes to port from buffer: called from pi1ppc_write()
1370  * function depending on current chipset mode. Returns number of bytes moved.
1371  */
1372 
1373 static void
1374 pi1ppc_set_intr_mask(struct pi1ppc_softc * const pi1ppc, u_int8_t mask)
1375 {
1376 	/* invert valid bits (0 = enabled) */
1377 	mask = ~mask;
1378 	mask &= 0xfc;
1379 
1380 	bus_space_write_4((pi1ppc)->sc_iot, (pi1ppc)->sc_ioh, IOC_PLP_INTMASK, mask);
1381 	pi1ppc_barrier_w(pi1ppc);
1382 }
1383 
1384 
1385 #ifdef USE_INDY_ACK_HACK
1386 static u_int8_t
1387 pi1ppc_get_intr_mask(struct pi1ppc_softc * const pi1ppc)
1388 {
1389 	int val;
1390 	val = bus_space_read_4((pi1ppc)->sc_iot, (pi1ppc)->sc_ioh, IOC_PLP_INTMASK);
1391 	pi1ppc_barrier_r(pi1ppc);
1392 
1393 	/* invert (0 = enabled) */
1394 	val = ~val;
1395 
1396 	return (val & 0xfc);
1397 }
1398 #endif
1399 
1400 static u_int8_t
1401 pi1ppc_get_intr_stat(struct pi1ppc_softc * const pi1ppc)
1402 {
1403 	int val;
1404 	val = bus_space_read_4((pi1ppc)->sc_iot, (pi1ppc)->sc_ioh, IOC_PLP_INTSTAT);
1405 	pi1ppc_barrier_r(pi1ppc);
1406 
1407 	return (val & 0xfc);
1408 }
1409 
1410 /* Write bytes in std/bidirectional mode */
1411 static void
1412 pi1ppc_std_write(struct pi1ppc_softc * const pi1ppc)
1413 {
1414 	unsigned char ctr;
1415 
1416 	ctr = pi1ppc_r_ctr(pi1ppc);
1417 	pi1ppc_barrier_r(pi1ppc);
1418 
1419 	/* Ensure that the data lines are in OUTPUT mode */
1420 	ctr &= ~PCD;
1421 	pi1ppc_w_ctr(pi1ppc, ctr);
1422 	pi1ppc_barrier_w(pi1ppc);
1423 
1424 	/* XXX JOE - need code to enable interrupts */
1425 #if 0
1426 	/* Enable interrupts if needed */
1427 	if (pi1ppc->sc_use & PI1PPC_USE_INTR) {
1428 		if (!(ctr & IRQENABLE)) {
1429 			ctr |= IRQENABLE;
1430 			pi1ppc_w_ctr(pi1ppc, ctr);
1431 			pi1ppc_barrier_w(pi1ppc);
1432 		}
1433 	}
1434 #endif
1435 
1436 	while (pi1ppc->sc_outbstart < (pi1ppc->sc_outb + pi1ppc->sc_outb_nbytes)) {
1437 
1438 		/* Wait for peripheral to become ready for MAXBUSYWAIT */
1439 		pi1ppc->sc_outerr = pi1ppc_poll_str(pi1ppc, SPP_READY, SPP_MASK);
1440 		if (pi1ppc->sc_outerr) {
1441 			printf("pi1ppc: timeout waiting for peripheral to become ready\n");
1442 			return;
1443 		}
1444 
1445 		/* Put data in data register */
1446 		pi1ppc_w_dtr(pi1ppc, *(pi1ppc->sc_outbstart));
1447 		pi1ppc_barrier_w(pi1ppc);
1448 		DELAY(1);
1449 
1450 		/* If no intr, prepare to catch the rising edge of nACK */
1451 		if (!(pi1ppc->sc_use & PI1PPC_USE_INTR)) {
1452 			pi1ppc_get_intr_stat(pi1ppc);	/* clear any pending intr */
1453 			pi1ppc_set_intr_mask(pi1ppc, PI1_PLP_ACK_INTR);
1454 		}
1455 
1456 		/* Pulse strobe to indicate valid data on lines */
1457 		ctr |= STROBE;
1458 		pi1ppc_w_ctr(pi1ppc, ctr);
1459 		pi1ppc_barrier_w(pi1ppc);
1460 		DELAY(1);
1461 		ctr &= ~STROBE;
1462 		pi1ppc_w_ctr(pi1ppc, ctr);
1463 		pi1ppc_barrier_w(pi1ppc);
1464 
1465 		/* Wait for nACK for MAXBUSYWAIT */
1466 		if (pi1ppc->sc_use & PI1PPC_USE_INTR) {
1467 			pi1ppc->sc_outerr = pi1ppc_wait_interrupt(pi1ppc,
1468 				pi1ppc->sc_outb, PI1PPC_IRQ_nACK);
1469 			if (pi1ppc->sc_outerr)
1470 				return;
1471 		} else {
1472 			/* Try to catch the pulsed acknowledgement */
1473 			pi1ppc->sc_outerr = pi1ppc_poll_interrupt_stat(pi1ppc,
1474 				PI1_PLP_ACK_INTR);
1475 
1476 			if (pi1ppc->sc_outerr) {
1477 				printf("pi1ppc: timeout waiting for ACK: %02x\n",pi1ppc_r_str(pi1ppc));
1478 				return;
1479 			}
1480 		}
1481 
1482 		/* Update buffer position, byte count and counter */
1483 		pi1ppc->sc_outbstart++;
1484 	}
1485 }
1486 
1487 
1488 /*
1489  * Poll status register using mask and status for MAXBUSYWAIT.
1490  * Returns 0 if device ready, error value otherwise.
1491  */
1492 static int
1493 pi1ppc_poll_str(struct pi1ppc_softc * const pi1ppc, const u_int8_t status,
1494 	const u_int8_t mask)
1495 {
1496 	unsigned int timecount;
1497 	u_int8_t str;
1498 	int error = EIO;
1499 
1500 	/* Wait for str to have status for MAXBUSYWAIT */
1501 	for (timecount = 0; timecount < ((MAXBUSYWAIT/hz)*1000000);
1502 		timecount++) {
1503 
1504 		str = pi1ppc_r_str(pi1ppc);
1505 		pi1ppc_barrier_r(pi1ppc);
1506 		if ((str & mask) == status) {
1507 			error = 0;
1508 			break;
1509 		}
1510 		DELAY(1);
1511 	}
1512 
1513 	return error;
1514 }
1515 
1516 /* Wait for interrupt for MAXBUSYWAIT: returns 0 if acknowledge received. */
1517 static int
1518 pi1ppc_wait_interrupt(struct pi1ppc_softc * const pi1ppc, const caddr_t where,
1519 	const u_int8_t irqstat)
1520 {
1521 	int error = EIO;
1522 
1523 	pi1ppc->sc_irqstat &= ~irqstat;
1524 
1525 	/* Wait for interrupt for MAXBUSYWAIT */
1526 	error = ltsleep(where, PPBUSPRI | PCATCH, __func__, MAXBUSYWAIT,
1527 		PI1PPC_SC_LOCK(pi1ppc));
1528 
1529 	if (!(error) && (pi1ppc->sc_irqstat & irqstat)) {
1530 		pi1ppc->sc_irqstat &= ~irqstat;
1531 		error = 0;
1532 	}
1533 
1534 	return error;
1535 }
1536 
1537 /*
1538 	INDY ACK HACK DESCRIPTION
1539 
1540 	There appears to be a bug in the Indy's PI1 hardware - it sometimes
1541 	*misses* the rising edge of /ACK.  Ugh!
1542 
1543 	(Also, unlike the other status bits, /ACK doesn't generate an
1544 	 interrupt on its falling edge.)
1545 
1546 	So, we do something kind of skanky here.  We use a shorter timeout,
1547 	and, if we timeout, we first check BUSY.  If BUSY is high, we go
1548 	back to waiting for /ACK (because maybe this really is just a slow
1549 	peripheral).
1550 
1551 	If it's a normal printer, it will raise BUSY from when it sees our
1552 	/STROBE until it raises its /ACK:
1553 		_____   _____________________
1554 	/STB	     \_/
1555 		________________   __________
1556 	/ACK	                \_/
1557 		       ___________
1558 	BUSY	______/           \__________
1559 
1560 	So, if we time out and see BUSY low, then we probably just missed
1561 	the /ACK.
1562 
1563 	In that case, we then check /ERROR and SELECTIN.  If both are hi,
1564 	(the peripheral thinks it is selected, and is not asserting /ERROR)
1565 	we assume that the Indy's parallel port missed the /ACK, and return
1566 	success.
1567  */
1568 
1569 #ifdef USE_INDY_ACK_HACK
1570 	#define	ACK_TIMEOUT_SCALER	1000
1571 #else
1572 	#define ACK_TIMEOUT_SCALER	1000000
1573 #endif
1574 
1575 static int
1576 pi1ppc_poll_interrupt_stat(struct pi1ppc_softc * const pi1ppc,
1577 	const u_int8_t match)
1578 {
1579 	unsigned int timecount;
1580 	u_int8_t cur;
1581 	int error = EIO;
1582 
1583 #ifdef USE_INDY_ACK_HACK
1584 	/* retry 10000x */
1585 	int retry_count = 10000;
1586 
1587 retry:
1588 #endif
1589 
1590 	/* Wait for intr status to have match bits set for MAXBUSYWAIT */
1591 	for (timecount = 0; timecount < ((MAXBUSYWAIT/hz)*ACK_TIMEOUT_SCALER);
1592 		timecount++) {
1593 		cur = pi1ppc_get_intr_stat(pi1ppc);
1594 		if ((cur & match) == match) {
1595 			error = 0;
1596 			break;
1597 		}
1598 		DELAY(1);
1599 	}
1600 
1601 #ifdef USE_INDY_ACK_HACK
1602 	if(error != 0) {
1603 		cur = pi1ppc_r_str(pi1ppc);
1604 
1605 		/* retry if BUSY is hi (inverted, so lo) and we haven't
1606 			waited the usual amt */
1607 
1608 		if(((cur&nBUSY) == 0) && retry_count) {
1609 			retry_count--;
1610 			goto retry;
1611 		}
1612 
1613 		/* if /ERROR and SELECT are high, and the peripheral isn't
1614 	   		BUSY, assume that we just missed the /ACK.
1615 			(Remember, we emulate the PC's inverted BUSY!)
1616 		*/
1617 
1618 		if((cur&(nFAULT|SELECT|nBUSY)) == (nFAULT|SELECT|nBUSY))
1619 			error = 0;
1620 
1621 		/* if things still look bad, print out some info */
1622 		if(error!=0)
1623 			printf("int mask=%02x, int stat=%02x, str=%02x\n",
1624 						pi1ppc_get_intr_mask(pi1ppc),
1625 						pi1ppc_get_intr_stat(pi1ppc),
1626 						cur);
1627 	}
1628 #endif
1629 
1630 	return error;
1631 }
1632 
1633