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