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