ppc.c revision 157774
1/*-
2 * Copyright (c) 1997-2000 Nicolas Souchu
3 * Copyright (c) 2001 Alcove - Nicolas Souchu
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 */
27
28#include <sys/cdefs.h>
29__FBSDID("$FreeBSD: head/sys/dev/ppc/ppc.c 157774 2006-04-15 12:31:34Z iwasaki $");
30
31#include "opt_ppc.h"
32
33#include <sys/param.h>
34#include <sys/systm.h>
35#include <sys/kernel.h>
36#include <sys/module.h>
37#include <sys/bus.h>
38#include <sys/malloc.h>
39#include <sys/kdb.h>
40
41#include <vm/vm.h>
42#include <vm/pmap.h>
43#include <machine/clock.h>
44#include <machine/bus.h>
45#include <machine/resource.h>
46#include <machine/vmparam.h>
47#include <sys/rman.h>
48
49#include <isa/isareg.h>
50#include <isa/isavar.h>
51
52#include <dev/ppbus/ppbconf.h>
53#include <dev/ppbus/ppb_msq.h>
54
55#include <dev/ppc/ppcvar.h>
56#include <dev/ppc/ppcreg.h>
57
58#include "ppbus_if.h"
59
60static int ppc_isa_probe(device_t dev);
61
62static void ppcintr(void *arg);
63
64#define LOG_PPC(function, ppc, string) \
65		if (bootverbose) printf("%s: %s\n", function, string)
66
67
68#define DEVTOSOFTC(dev) ((struct ppc_data *)device_get_softc(dev))
69
70devclass_t ppc_devclass;
71
72static device_method_t ppc_methods[] = {
73	/* device interface */
74	DEVMETHOD(device_probe,         ppc_isa_probe),
75	DEVMETHOD(device_attach,        ppc_attach),
76	DEVMETHOD(device_detach,        ppc_detach),
77
78	/* bus interface */
79	DEVMETHOD(bus_read_ivar,	ppc_read_ivar),
80	DEVMETHOD(bus_setup_intr,	ppc_setup_intr),
81	DEVMETHOD(bus_teardown_intr,	ppc_teardown_intr),
82	DEVMETHOD(bus_alloc_resource,   bus_generic_alloc_resource),
83
84	/* ppbus interface */
85	DEVMETHOD(ppbus_io,		ppc_io),
86	DEVMETHOD(ppbus_exec_microseq,	ppc_exec_microseq),
87	DEVMETHOD(ppbus_reset_epp,	ppc_reset_epp),
88	DEVMETHOD(ppbus_setmode,	ppc_setmode),
89	DEVMETHOD(ppbus_ecp_sync,	ppc_ecp_sync),
90	DEVMETHOD(ppbus_read,		ppc_read),
91	DEVMETHOD(ppbus_write,		ppc_write),
92
93        { 0, 0 }
94  };
95
96static driver_t ppc_driver = {
97	"ppc",
98	ppc_methods,
99	sizeof(struct ppc_data),
100};
101
102static char *ppc_models[] = {
103	"SMC-like", "SMC FDC37C665GT", "SMC FDC37C666GT", "PC87332", "PC87306",
104	"82091AA", "Generic", "W83877F", "W83877AF", "Winbond", "PC87334",
105	"SMC FDC37C935", "PC87303", 0
106};
107
108/* list of available modes */
109static char *ppc_avms[] = {
110	"COMPATIBLE", "NIBBLE-only", "PS2-only", "PS2/NIBBLE", "EPP-only",
111	"EPP/NIBBLE", "EPP/PS2", "EPP/PS2/NIBBLE", "ECP-only",
112	"ECP/NIBBLE", "ECP/PS2", "ECP/PS2/NIBBLE", "ECP/EPP",
113	"ECP/EPP/NIBBLE", "ECP/EPP/PS2", "ECP/EPP/PS2/NIBBLE", 0
114};
115
116/* list of current executing modes
117 * Note that few modes do not actually exist.
118 */
119static char *ppc_modes[] = {
120	"COMPATIBLE", "NIBBLE", "PS/2", "PS/2", "EPP",
121	"EPP", "EPP", "EPP", "ECP",
122	"ECP", "ECP+PS2", "ECP+PS2", "ECP+EPP",
123	"ECP+EPP", "ECP+EPP", "ECP+EPP", 0
124};
125
126static char *ppc_epp_protocol[] = { " (EPP 1.9)", " (EPP 1.7)", 0 };
127
128#ifdef __i386__
129/*
130 * BIOS printer list - used by BIOS probe.
131 */
132#define	BIOS_PPC_PORTS	0x408
133#define	BIOS_PORTS	(short *)(KERNBASE+BIOS_PPC_PORTS)
134#define	BIOS_MAX_PPC	4
135#endif
136
137/*
138 * ppc_ecp_sync()		XXX
139 */
140void
141ppc_ecp_sync(device_t dev) {
142
143	int i, r;
144	struct ppc_data *ppc = DEVTOSOFTC(dev);
145
146	if (!(ppc->ppc_avm & PPB_ECP) && !(ppc->ppc_dtm & PPB_ECP))
147		return;
148
149	r = r_ecr(ppc);
150	if ((r & 0xe0) != PPC_ECR_EPP)
151		return;
152
153	for (i = 0; i < 100; i++) {
154		r = r_ecr(ppc);
155		if (r & 0x1)
156			return;
157		DELAY(100);
158	}
159
160	printf("ppc%d: ECP sync failed as data still " \
161		"present in FIFO.\n", ppc->ppc_unit);
162
163	return;
164}
165
166/*
167 * ppc_detect_fifo()
168 *
169 * Detect parallel port FIFO
170 */
171static int
172ppc_detect_fifo(struct ppc_data *ppc)
173{
174	char ecr_sav;
175	char ctr_sav, ctr, cc;
176	short i;
177
178	/* save registers */
179	ecr_sav = r_ecr(ppc);
180	ctr_sav = r_ctr(ppc);
181
182	/* enter ECP configuration mode, no interrupt, no DMA */
183	w_ecr(ppc, 0xf4);
184
185	/* read PWord size - transfers in FIFO mode must be PWord aligned */
186	ppc->ppc_pword = (r_cnfgA(ppc) & PPC_PWORD_MASK);
187
188	/* XXX 16 and 32 bits implementations not supported */
189	if (ppc->ppc_pword != PPC_PWORD_8) {
190		LOG_PPC(__func__, ppc, "PWord not supported");
191		goto error;
192	}
193
194	w_ecr(ppc, 0x34);		/* byte mode, no interrupt, no DMA */
195	ctr = r_ctr(ppc);
196	w_ctr(ppc, ctr | PCD);		/* set direction to 1 */
197
198	/* enter ECP test mode, no interrupt, no DMA */
199	w_ecr(ppc, 0xd4);
200
201	/* flush the FIFO */
202	for (i=0; i<1024; i++) {
203		if (r_ecr(ppc) & PPC_FIFO_EMPTY)
204			break;
205		cc = r_fifo(ppc);
206	}
207
208	if (i >= 1024) {
209		LOG_PPC(__func__, ppc, "can't flush FIFO");
210		goto error;
211	}
212
213	/* enable interrupts, no DMA */
214	w_ecr(ppc, 0xd0);
215
216	/* determine readIntrThreshold
217	 * fill the FIFO until serviceIntr is set
218	 */
219	for (i=0; i<1024; i++) {
220		w_fifo(ppc, (char)i);
221		if (!ppc->ppc_rthr && (r_ecr(ppc) & PPC_SERVICE_INTR)) {
222			/* readThreshold reached */
223			ppc->ppc_rthr = i+1;
224		}
225		if (r_ecr(ppc) & PPC_FIFO_FULL) {
226			ppc->ppc_fifo = i+1;
227			break;
228		}
229	}
230
231	if (i >= 1024) {
232		LOG_PPC(__func__, ppc, "can't fill FIFO");
233		goto error;
234	}
235
236	w_ecr(ppc, 0xd4);		/* test mode, no interrupt, no DMA */
237	w_ctr(ppc, ctr & ~PCD);		/* set direction to 0 */
238	w_ecr(ppc, 0xd0);		/* enable interrupts */
239
240	/* determine writeIntrThreshold
241	 * empty the FIFO until serviceIntr is set
242	 */
243	for (i=ppc->ppc_fifo; i>0; i--) {
244		if (r_fifo(ppc) != (char)(ppc->ppc_fifo-i)) {
245			LOG_PPC(__func__, ppc, "invalid data in FIFO");
246			goto error;
247		}
248		if (r_ecr(ppc) & PPC_SERVICE_INTR) {
249			/* writeIntrThreshold reached */
250			ppc->ppc_wthr = ppc->ppc_fifo - i+1;
251		}
252		/* if FIFO empty before the last byte, error */
253		if (i>1 && (r_ecr(ppc) & PPC_FIFO_EMPTY)) {
254			LOG_PPC(__func__, ppc, "data lost in FIFO");
255			goto error;
256		}
257	}
258
259	/* FIFO must be empty after the last byte */
260	if (!(r_ecr(ppc) & PPC_FIFO_EMPTY)) {
261		LOG_PPC(__func__, ppc, "can't empty the FIFO");
262		goto error;
263	}
264
265	w_ctr(ppc, ctr_sav);
266	w_ecr(ppc, ecr_sav);
267
268	return (0);
269
270error:
271	w_ctr(ppc, ctr_sav);
272	w_ecr(ppc, ecr_sav);
273
274	return (EINVAL);
275}
276
277static int
278ppc_detect_port(struct ppc_data *ppc)
279{
280
281	w_ctr(ppc, 0x0c);	/* To avoid missing PS2 ports */
282	w_dtr(ppc, 0xaa);
283	if (r_dtr(ppc) != 0xaa)
284		return (0);
285
286	return (1);
287}
288
289/*
290 * EPP timeout, according to the PC87332 manual
291 * Semantics of clearing EPP timeout bit.
292 * PC87332	- reading SPP_STR does it...
293 * SMC		- write 1 to EPP timeout bit			XXX
294 * Others	- (?) write 0 to EPP timeout bit
295 */
296static void
297ppc_reset_epp_timeout(struct ppc_data *ppc)
298{
299	register char r;
300
301	r = r_str(ppc);
302	w_str(ppc, r | 0x1);
303	w_str(ppc, r & 0xfe);
304
305	return;
306}
307
308static int
309ppc_check_epp_timeout(struct ppc_data *ppc)
310{
311	ppc_reset_epp_timeout(ppc);
312
313	return (!(r_str(ppc) & TIMEOUT));
314}
315
316/*
317 * Configure current operating mode
318 */
319static int
320ppc_generic_setmode(struct ppc_data *ppc, int mode)
321{
322	u_char ecr = 0;
323
324	/* check if mode is available */
325	if (mode && !(ppc->ppc_avm & mode))
326		return (EINVAL);
327
328	/* if ECP mode, configure ecr register */
329	if ((ppc->ppc_avm & PPB_ECP) || (ppc->ppc_dtm & PPB_ECP)) {
330		/* return to byte mode (keeping direction bit),
331		 * no interrupt, no DMA to be able to change to
332		 * ECP
333		 */
334		w_ecr(ppc, PPC_ECR_RESET);
335		ecr = PPC_DISABLE_INTR;
336
337		if (mode & PPB_EPP)
338			return (EINVAL);
339		else if (mode & PPB_ECP)
340			/* select ECP mode */
341			ecr |= PPC_ECR_ECP;
342		else if (mode & PPB_PS2)
343			/* select PS2 mode with ECP */
344			ecr |= PPC_ECR_PS2;
345		else
346			/* select COMPATIBLE/NIBBLE mode */
347			ecr |= PPC_ECR_STD;
348
349		w_ecr(ppc, ecr);
350	}
351
352	ppc->ppc_mode = mode;
353
354	return (0);
355}
356
357/*
358 * The ppc driver is free to choose options like FIFO or DMA
359 * if ECP mode is available.
360 *
361 * The 'RAW' option allows the upper drivers to force the ppc mode
362 * even with FIFO, DMA available.
363 */
364static int
365ppc_smclike_setmode(struct ppc_data *ppc, int mode)
366{
367	u_char ecr = 0;
368
369	/* check if mode is available */
370	if (mode && !(ppc->ppc_avm & mode))
371		return (EINVAL);
372
373	/* if ECP mode, configure ecr register */
374	if ((ppc->ppc_avm & PPB_ECP) || (ppc->ppc_dtm & PPB_ECP)) {
375		/* return to byte mode (keeping direction bit),
376		 * no interrupt, no DMA to be able to change to
377		 * ECP or EPP mode
378		 */
379		w_ecr(ppc, PPC_ECR_RESET);
380		ecr = PPC_DISABLE_INTR;
381
382		if (mode & PPB_EPP)
383			/* select EPP mode */
384			ecr |= PPC_ECR_EPP;
385		else if (mode & PPB_ECP)
386			/* select ECP mode */
387			ecr |= PPC_ECR_ECP;
388		else if (mode & PPB_PS2)
389			/* select PS2 mode with ECP */
390			ecr |= PPC_ECR_PS2;
391		else
392			/* select COMPATIBLE/NIBBLE mode */
393			ecr |= PPC_ECR_STD;
394
395		w_ecr(ppc, ecr);
396	}
397
398	ppc->ppc_mode = mode;
399
400	return (0);
401}
402
403#ifdef PPC_PROBE_CHIPSET
404/*
405 * ppc_pc873xx_detect
406 *
407 * Probe for a Natsemi PC873xx-family part.
408 *
409 * References in this function are to the National Semiconductor
410 * PC87332 datasheet TL/C/11930, May 1995 revision.
411 */
412static int pc873xx_basetab[] = {0x0398, 0x026e, 0x015c, 0x002e, 0};
413static int pc873xx_porttab[] = {0x0378, 0x03bc, 0x0278, 0};
414static int pc873xx_irqtab[] = {5, 7, 5, 0};
415
416static int pc873xx_regstab[] = {
417	PC873_FER, PC873_FAR, PC873_PTR,
418	PC873_FCR, PC873_PCR, PC873_PMC,
419	PC873_TUP, PC873_SID, PC873_PNP0,
420	PC873_PNP1, PC873_LPTBA, -1
421};
422
423static char *pc873xx_rnametab[] = {
424	"FER", "FAR", "PTR", "FCR", "PCR",
425	"PMC", "TUP", "SID", "PNP0", "PNP1",
426	"LPTBA", NULL
427};
428
429static int
430ppc_pc873xx_detect(struct ppc_data *ppc, int chipset_mode)	/* XXX mode never forced */
431{
432    static int	index = 0;
433    int		idport, irq;
434    int		ptr, pcr, val, i;
435
436    while ((idport = pc873xx_basetab[index++])) {
437
438	/* XXX should check first to see if this location is already claimed */
439
440	/*
441	 * Pull the 873xx through the power-on ID cycle (2.2,1.).
442	 * We can't use this to locate the chip as it may already have
443	 * been used by the BIOS.
444	 */
445	(void)inb(idport); (void)inb(idport);
446	(void)inb(idport); (void)inb(idport);
447
448	/*
449	 * Read the SID byte.  Possible values are :
450	 *
451	 * 01010xxx	PC87334
452	 * 0001xxxx	PC87332
453	 * 01110xxx	PC87306
454	 * 00110xxx	PC87303
455	 */
456	outb(idport, PC873_SID);
457	val = inb(idport + 1);
458	if ((val & 0xf0) == 0x10) {
459	    ppc->ppc_model = NS_PC87332;
460	} else if ((val & 0xf8) == 0x70) {
461	    ppc->ppc_model = NS_PC87306;
462	} else if ((val & 0xf8) == 0x50) {
463	    ppc->ppc_model = NS_PC87334;
464	} else if ((val & 0xf8) == 0x40) { /* Should be 0x30 by the
465					      documentation, but probing
466					      yielded 0x40... */
467	    ppc->ppc_model = NS_PC87303;
468	} else {
469	    if (bootverbose && (val != 0xff))
470		printf("PC873xx probe at 0x%x got unknown ID 0x%x\n", idport, val);
471	    continue ;		/* not recognised */
472	}
473
474	/* print registers */
475	if (bootverbose) {
476		printf("PC873xx");
477		for (i=0; pc873xx_regstab[i] != -1; i++) {
478			outb(idport, pc873xx_regstab[i]);
479			printf(" %s=0x%x", pc873xx_rnametab[i],
480						inb(idport + 1) & 0xff);
481		}
482		printf("\n");
483	}
484
485	/*
486	 * We think we have one.  Is it enabled and where we want it to be?
487	 */
488	outb(idport, PC873_FER);
489	val = inb(idport + 1);
490	if (!(val & PC873_PPENABLE)) {
491	    if (bootverbose)
492		printf("PC873xx parallel port disabled\n");
493	    continue;
494	}
495	outb(idport, PC873_FAR);
496	val = inb(idport + 1);
497	/* XXX we should create a driver instance for every port found */
498	if (pc873xx_porttab[val & 0x3] != ppc->ppc_base) {
499
500	    /* First try to change the port address to that requested... */
501
502	    switch(ppc->ppc_base) {
503		case 0x378:
504		val &= 0xfc;
505		break;
506
507		case 0x3bc:
508		val &= 0xfd;
509		break;
510
511		case 0x278:
512		val &= 0xfe;
513		break;
514
515		default:
516		val &= 0xfd;
517		break;
518	    }
519
520	    outb(idport, PC873_FAR);
521	    outb(idport + 1, val);
522	    outb(idport + 1, val);
523
524	    /* Check for success by reading back the value we supposedly
525	       wrote and comparing...*/
526
527	    outb(idport, PC873_FAR);
528	    val = inb(idport + 1) & 0x3;
529
530	    /* If we fail, report the failure... */
531
532	    if (pc873xx_porttab[val] != ppc->ppc_base) {
533 		if (bootverbose)
534	  	    printf("PC873xx at 0x%x not for driver at port 0x%x\n",
535			   pc873xx_porttab[val], ppc->ppc_base);
536	    }
537	    continue;
538	}
539
540	outb(idport, PC873_PTR);
541        ptr = inb(idport + 1);
542
543	/* get irq settings */
544	if (ppc->ppc_base == 0x378)
545		irq = (ptr & PC873_LPTBIRQ7) ? 7 : 5;
546	else
547		irq = pc873xx_irqtab[val];
548
549	if (bootverbose)
550		printf("PC873xx irq %d at 0x%x\n", irq, ppc->ppc_base);
551
552	/*
553	 * Check if irq settings are correct
554	 */
555	if (irq != ppc->ppc_irq) {
556		/*
557		 * If the chipset is not locked and base address is 0x378,
558		 * we have another chance
559		 */
560		if (ppc->ppc_base == 0x378 && !(ptr & PC873_CFGLOCK)) {
561			if (ppc->ppc_irq == 7) {
562				outb(idport + 1, (ptr | PC873_LPTBIRQ7));
563				outb(idport + 1, (ptr | PC873_LPTBIRQ7));
564			} else {
565				outb(idport + 1, (ptr & ~PC873_LPTBIRQ7));
566				outb(idport + 1, (ptr & ~PC873_LPTBIRQ7));
567			}
568			if (bootverbose)
569			   printf("PC873xx irq set to %d\n", ppc->ppc_irq);
570		} else {
571			if (bootverbose)
572			   printf("PC873xx sorry, can't change irq setting\n");
573		}
574	} else {
575		if (bootverbose)
576			printf("PC873xx irq settings are correct\n");
577	}
578
579	outb(idport, PC873_PCR);
580	pcr = inb(idport + 1);
581
582	if ((ptr & PC873_CFGLOCK) || !chipset_mode) {
583	    if (bootverbose)
584		printf("PC873xx %s", (ptr & PC873_CFGLOCK)?"locked":"unlocked");
585
586	    ppc->ppc_avm |= PPB_NIBBLE;
587	    if (bootverbose)
588		printf(", NIBBLE");
589
590	    if (pcr & PC873_EPPEN) {
591	        ppc->ppc_avm |= PPB_EPP;
592
593		if (bootverbose)
594			printf(", EPP");
595
596		if (pcr & PC873_EPP19)
597			ppc->ppc_epp = EPP_1_9;
598		else
599			ppc->ppc_epp = EPP_1_7;
600
601		if ((ppc->ppc_model == NS_PC87332) && bootverbose) {
602			outb(idport, PC873_PTR);
603			ptr = inb(idport + 1);
604			if (ptr & PC873_EPPRDIR)
605				printf(", Regular mode");
606			else
607				printf(", Automatic mode");
608		}
609	    } else if (pcr & PC873_ECPEN) {
610		ppc->ppc_avm |= PPB_ECP;
611		if (bootverbose)
612			printf(", ECP");
613
614		if (pcr & PC873_ECPCLK)	{		/* XXX */
615			ppc->ppc_avm |= PPB_PS2;
616			if (bootverbose)
617				printf(", PS/2");
618		}
619	    } else {
620		outb(idport, PC873_PTR);
621		ptr = inb(idport + 1);
622		if (ptr & PC873_EXTENDED) {
623			ppc->ppc_avm |= PPB_SPP;
624                        if (bootverbose)
625                                printf(", SPP");
626		}
627	    }
628	} else {
629		if (bootverbose)
630			printf("PC873xx unlocked");
631
632		if (chipset_mode & PPB_ECP) {
633			if ((chipset_mode & PPB_EPP) && bootverbose)
634				printf(", ECP+EPP not supported");
635
636			pcr &= ~PC873_EPPEN;
637			pcr |= (PC873_ECPEN | PC873_ECPCLK);	/* XXX */
638			outb(idport + 1, pcr);
639			outb(idport + 1, pcr);
640
641			if (bootverbose)
642				printf(", ECP");
643
644		} else if (chipset_mode & PPB_EPP) {
645			pcr &= ~(PC873_ECPEN | PC873_ECPCLK);
646			pcr |= (PC873_EPPEN | PC873_EPP19);
647			outb(idport + 1, pcr);
648			outb(idport + 1, pcr);
649
650			ppc->ppc_epp = EPP_1_9;			/* XXX */
651
652			if (bootverbose)
653				printf(", EPP1.9");
654
655			/* enable automatic direction turnover */
656			if (ppc->ppc_model == NS_PC87332) {
657				outb(idport, PC873_PTR);
658				ptr = inb(idport + 1);
659				ptr &= ~PC873_EPPRDIR;
660				outb(idport + 1, ptr);
661				outb(idport + 1, ptr);
662
663				if (bootverbose)
664					printf(", Automatic mode");
665			}
666		} else {
667			pcr &= ~(PC873_ECPEN | PC873_ECPCLK | PC873_EPPEN);
668			outb(idport + 1, pcr);
669			outb(idport + 1, pcr);
670
671			/* configure extended bit in PTR */
672			outb(idport, PC873_PTR);
673			ptr = inb(idport + 1);
674
675			if (chipset_mode & PPB_PS2) {
676				ptr |= PC873_EXTENDED;
677
678				if (bootverbose)
679					printf(", PS/2");
680
681			} else {
682				/* default to NIBBLE mode */
683				ptr &= ~PC873_EXTENDED;
684
685				if (bootverbose)
686					printf(", NIBBLE");
687			}
688			outb(idport + 1, ptr);
689			outb(idport + 1, ptr);
690		}
691
692		ppc->ppc_avm = chipset_mode;
693	}
694
695	if (bootverbose)
696		printf("\n");
697
698	ppc->ppc_type = PPC_TYPE_GENERIC;
699	ppc_generic_setmode(ppc, chipset_mode);
700
701	return(chipset_mode);
702    }
703    return(-1);
704}
705
706/*
707 * ppc_smc37c66xgt_detect
708 *
709 * SMC FDC37C66xGT configuration.
710 */
711static int
712ppc_smc37c66xgt_detect(struct ppc_data *ppc, int chipset_mode)
713{
714	int s, i;
715	u_char r;
716	int type = -1;
717	int csr = SMC66x_CSR;	/* initial value is 0x3F0 */
718
719	int port_address[] = { -1 /* disabled */ , 0x3bc, 0x378, 0x278 };
720
721
722#define cio csr+1	/* config IO port is either 0x3F1 or 0x371 */
723
724	/*
725	 * Detection: enter configuration mode and read CRD register.
726	 */
727
728	s = splhigh();
729	outb(csr, SMC665_iCODE);
730	outb(csr, SMC665_iCODE);
731	splx(s);
732
733	outb(csr, 0xd);
734	if (inb(cio) == 0x65) {
735		type = SMC_37C665GT;
736		goto config;
737	}
738
739	for (i = 0; i < 2; i++) {
740		s = splhigh();
741		outb(csr, SMC666_iCODE);
742		outb(csr, SMC666_iCODE);
743		splx(s);
744
745		outb(csr, 0xd);
746		if (inb(cio) == 0x66) {
747			type = SMC_37C666GT;
748			break;
749		}
750
751		/* Another chance, CSR may be hard-configured to be at 0x370 */
752		csr = SMC666_CSR;
753	}
754
755config:
756	/*
757	 * If chipset not found, do not continue.
758	 */
759	if (type == -1)
760		return (-1);
761
762	/* select CR1 */
763	outb(csr, 0x1);
764
765	/* read the port's address: bits 0 and 1 of CR1 */
766	r = inb(cio) & SMC_CR1_ADDR;
767	if (port_address[(int)r] != ppc->ppc_base)
768		return (-1);
769
770	ppc->ppc_model = type;
771
772	/*
773	 * CR1 and CR4 registers bits 3 and 0/1 for mode configuration
774	 * If SPP mode is detected, try to set ECP+EPP mode
775	 */
776
777	if (bootverbose) {
778		outb(csr, 0x1);
779		printf("ppc%d: SMC registers CR1=0x%x", ppc->ppc_unit,
780			inb(cio) & 0xff);
781
782		outb(csr, 0x4);
783		printf(" CR4=0x%x", inb(cio) & 0xff);
784	}
785
786	/* select CR1 */
787	outb(csr, 0x1);
788
789	if (!chipset_mode) {
790		/* autodetect mode */
791
792		/* 666GT is ~certainly~ hardwired to an extended ECP+EPP mode */
793		if (type == SMC_37C666GT) {
794			ppc->ppc_avm |= PPB_ECP | PPB_EPP | PPB_SPP;
795			if (bootverbose)
796				printf(" configuration hardwired, supposing " \
797					"ECP+EPP SPP");
798
799		} else
800		   if ((inb(cio) & SMC_CR1_MODE) == 0) {
801			/* already in extended parallel port mode, read CR4 */
802			outb(csr, 0x4);
803			r = (inb(cio) & SMC_CR4_EMODE);
804
805			switch (r) {
806			case SMC_SPP:
807				ppc->ppc_avm |= PPB_SPP;
808				if (bootverbose)
809					printf(" SPP");
810				break;
811
812			case SMC_EPPSPP:
813				ppc->ppc_avm |= PPB_EPP | PPB_SPP;
814				if (bootverbose)
815					printf(" EPP SPP");
816				break;
817
818			case SMC_ECP:
819				ppc->ppc_avm |= PPB_ECP | PPB_SPP;
820				if (bootverbose)
821					printf(" ECP SPP");
822				break;
823
824			case SMC_ECPEPP:
825				ppc->ppc_avm |= PPB_ECP | PPB_EPP | PPB_SPP;
826				if (bootverbose)
827					printf(" ECP+EPP SPP");
828				break;
829			}
830		   } else {
831			/* not an extended port mode */
832			ppc->ppc_avm |= PPB_SPP;
833			if (bootverbose)
834				printf(" SPP");
835		   }
836
837	} else {
838		/* mode forced */
839		ppc->ppc_avm = chipset_mode;
840
841		/* 666GT is ~certainly~ hardwired to an extended ECP+EPP mode */
842		if (type == SMC_37C666GT)
843			goto end_detect;
844
845		r = inb(cio);
846		if ((chipset_mode & (PPB_ECP | PPB_EPP)) == 0) {
847			/* do not use ECP when the mode is not forced to */
848			outb(cio, r | SMC_CR1_MODE);
849			if (bootverbose)
850				printf(" SPP");
851		} else {
852			/* an extended mode is selected */
853			outb(cio, r & ~SMC_CR1_MODE);
854
855			/* read CR4 register and reset mode field */
856			outb(csr, 0x4);
857			r = inb(cio) & ~SMC_CR4_EMODE;
858
859			if (chipset_mode & PPB_ECP) {
860				if (chipset_mode & PPB_EPP) {
861					outb(cio, r | SMC_ECPEPP);
862					if (bootverbose)
863						printf(" ECP+EPP");
864				} else {
865					outb(cio, r | SMC_ECP);
866					if (bootverbose)
867						printf(" ECP");
868				}
869			} else {
870				/* PPB_EPP is set */
871				outb(cio, r | SMC_EPPSPP);
872				if (bootverbose)
873					printf(" EPP SPP");
874			}
875		}
876		ppc->ppc_avm = chipset_mode;
877	}
878
879	/* set FIFO threshold to 16 */
880	if (ppc->ppc_avm & PPB_ECP) {
881		/* select CRA */
882		outb(csr, 0xa);
883		outb(cio, 16);
884	}
885
886end_detect:
887
888	if (bootverbose)
889		printf ("\n");
890
891	if (ppc->ppc_avm & PPB_EPP) {
892		/* select CR4 */
893		outb(csr, 0x4);
894		r = inb(cio);
895
896		/*
897		 * Set the EPP protocol...
898		 * Low=EPP 1.9 (1284 standard) and High=EPP 1.7
899		 */
900		if (ppc->ppc_epp == EPP_1_9)
901			outb(cio, (r & ~SMC_CR4_EPPTYPE));
902		else
903			outb(cio, (r | SMC_CR4_EPPTYPE));
904	}
905
906	/* end config mode */
907	outb(csr, 0xaa);
908
909	ppc->ppc_type = PPC_TYPE_SMCLIKE;
910	ppc_smclike_setmode(ppc, chipset_mode);
911
912	return (chipset_mode);
913}
914
915/*
916 * SMC FDC37C935 configuration
917 * Found on many Alpha machines
918 */
919static int
920ppc_smc37c935_detect(struct ppc_data *ppc, int chipset_mode)
921{
922	int s;
923	int type = -1;
924
925	s = splhigh();
926	outb(SMC935_CFG, 0x55); /* enter config mode */
927	outb(SMC935_CFG, 0x55);
928	splx(s);
929
930	outb(SMC935_IND, SMC935_ID); /* check device id */
931	if (inb(SMC935_DAT) == 0x2)
932		type = SMC_37C935;
933
934	if (type == -1) {
935		outb(SMC935_CFG, 0xaa); /* exit config mode */
936		return (-1);
937	}
938
939	ppc->ppc_model = type;
940
941	outb(SMC935_IND, SMC935_LOGDEV); /* select parallel port, */
942	outb(SMC935_DAT, 3);             /* which is logical device 3 */
943
944	/* set io port base */
945	outb(SMC935_IND, SMC935_PORTHI);
946	outb(SMC935_DAT, (u_char)((ppc->ppc_base & 0xff00) >> 8));
947	outb(SMC935_IND, SMC935_PORTLO);
948	outb(SMC935_DAT, (u_char)(ppc->ppc_base & 0xff));
949
950	if (!chipset_mode)
951		ppc->ppc_avm = PPB_COMPATIBLE; /* default mode */
952	else {
953		ppc->ppc_avm = chipset_mode;
954		outb(SMC935_IND, SMC935_PPMODE);
955		outb(SMC935_DAT, SMC935_CENT); /* start in compatible mode */
956
957		/* SPP + EPP or just plain SPP */
958		if (chipset_mode & (PPB_SPP)) {
959			if (chipset_mode & PPB_EPP) {
960				if (ppc->ppc_epp == EPP_1_9) {
961					outb(SMC935_IND, SMC935_PPMODE);
962					outb(SMC935_DAT, SMC935_EPP19SPP);
963				}
964				if (ppc->ppc_epp == EPP_1_7) {
965					outb(SMC935_IND, SMC935_PPMODE);
966					outb(SMC935_DAT, SMC935_EPP17SPP);
967				}
968			} else {
969				outb(SMC935_IND, SMC935_PPMODE);
970				outb(SMC935_DAT, SMC935_SPP);
971			}
972		}
973
974		/* ECP + EPP or just plain ECP */
975		if (chipset_mode & PPB_ECP) {
976			if (chipset_mode & PPB_EPP) {
977				if (ppc->ppc_epp == EPP_1_9) {
978					outb(SMC935_IND, SMC935_PPMODE);
979					outb(SMC935_DAT, SMC935_ECPEPP19);
980				}
981				if (ppc->ppc_epp == EPP_1_7) {
982					outb(SMC935_IND, SMC935_PPMODE);
983					outb(SMC935_DAT, SMC935_ECPEPP17);
984				}
985			} else {
986				outb(SMC935_IND, SMC935_PPMODE);
987				outb(SMC935_DAT, SMC935_ECP);
988			}
989		}
990	}
991
992	outb(SMC935_CFG, 0xaa); /* exit config mode */
993
994	ppc->ppc_type = PPC_TYPE_SMCLIKE;
995	ppc_smclike_setmode(ppc, chipset_mode);
996
997	return (chipset_mode);
998}
999
1000/*
1001 * Winbond W83877F stuff
1002 *
1003 * EFER: extended function enable register
1004 * EFIR: extended function index register
1005 * EFDR: extended function data register
1006 */
1007#define efir ((efer == 0x250) ? 0x251 : 0x3f0)
1008#define efdr ((efer == 0x250) ? 0x252 : 0x3f1)
1009
1010static int w83877f_efers[] = { 0x250, 0x3f0, 0x3f0, 0x250 };
1011static int w83877f_keys[] = { 0x89, 0x86, 0x87, 0x88 };
1012static int w83877f_keyiter[] = { 1, 2, 2, 1 };
1013static int w83877f_hefs[] = { WINB_HEFERE, WINB_HEFRAS, WINB_HEFERE | WINB_HEFRAS, 0 };
1014
1015static int
1016ppc_w83877f_detect(struct ppc_data *ppc, int chipset_mode)
1017{
1018	int i, j, efer;
1019	unsigned char r, hefere, hefras;
1020
1021	for (i = 0; i < 4; i ++) {
1022		/* first try to enable configuration registers */
1023		efer = w83877f_efers[i];
1024
1025		/* write the key to the EFER */
1026		for (j = 0; j < w83877f_keyiter[i]; j ++)
1027			outb (efer, w83877f_keys[i]);
1028
1029		/* then check HEFERE and HEFRAS bits */
1030		outb (efir, 0x0c);
1031		hefere = inb(efdr) & WINB_HEFERE;
1032
1033		outb (efir, 0x16);
1034		hefras = inb(efdr) & WINB_HEFRAS;
1035
1036		/*
1037		 * HEFRAS	HEFERE
1038		 *   0		   1	write 89h to 250h (power-on default)
1039		 *   1		   0	write 86h twice to 3f0h
1040		 *   1		   1	write 87h twice to 3f0h
1041		 *   0		   0	write 88h to 250h
1042		 */
1043		if ((hefere | hefras) == w83877f_hefs[i])
1044			goto found;
1045	}
1046
1047	return (-1);	/* failed */
1048
1049found:
1050	/* check base port address - read from CR23 */
1051	outb(efir, 0x23);
1052	if (ppc->ppc_base != inb(efdr) * 4)		/* 4 bytes boundaries */
1053		return (-1);
1054
1055	/* read CHIP ID from CR9/bits0-3 */
1056	outb(efir, 0x9);
1057
1058	switch (inb(efdr) & WINB_CHIPID) {
1059		case WINB_W83877F_ID:
1060			ppc->ppc_model = WINB_W83877F;
1061			break;
1062
1063		case WINB_W83877AF_ID:
1064			ppc->ppc_model = WINB_W83877AF;
1065			break;
1066
1067		default:
1068			ppc->ppc_model = WINB_UNKNOWN;
1069	}
1070
1071	if (bootverbose) {
1072		/* dump of registers */
1073		printf("ppc%d: 0x%x - ", ppc->ppc_unit, w83877f_keys[i]);
1074		for (i = 0; i <= 0xd; i ++) {
1075			outb(efir, i);
1076			printf("0x%x ", inb(efdr));
1077		}
1078		for (i = 0x10; i <= 0x17; i ++) {
1079			outb(efir, i);
1080			printf("0x%x ", inb(efdr));
1081		}
1082		outb(efir, 0x1e);
1083		printf("0x%x ", inb(efdr));
1084		for (i = 0x20; i <= 0x29; i ++) {
1085			outb(efir, i);
1086			printf("0x%x ", inb(efdr));
1087		}
1088		printf("\n");
1089		printf("ppc%d:", ppc->ppc_unit);
1090	}
1091
1092	ppc->ppc_type = PPC_TYPE_GENERIC;
1093
1094	if (!chipset_mode) {
1095		/* autodetect mode */
1096
1097		/* select CR0 */
1098		outb(efir, 0x0);
1099		r = inb(efdr) & (WINB_PRTMODS0 | WINB_PRTMODS1);
1100
1101		/* select CR9 */
1102		outb(efir, 0x9);
1103		r |= (inb(efdr) & WINB_PRTMODS2);
1104
1105		switch (r) {
1106		case WINB_W83757:
1107			if (bootverbose)
1108				printf("ppc%d: W83757 compatible mode\n",
1109					ppc->ppc_unit);
1110			return (-1);	/* generic or SMC-like */
1111
1112		case WINB_EXTFDC:
1113		case WINB_EXTADP:
1114		case WINB_EXT2FDD:
1115		case WINB_JOYSTICK:
1116			if (bootverbose)
1117				printf(" not in parallel port mode\n");
1118			return (-1);
1119
1120		case (WINB_PARALLEL | WINB_EPP_SPP):
1121			ppc->ppc_avm |= PPB_EPP | PPB_SPP;
1122			if (bootverbose)
1123				printf(" EPP SPP");
1124			break;
1125
1126		case (WINB_PARALLEL | WINB_ECP):
1127			ppc->ppc_avm |= PPB_ECP | PPB_SPP;
1128			if (bootverbose)
1129				printf(" ECP SPP");
1130			break;
1131
1132		case (WINB_PARALLEL | WINB_ECP_EPP):
1133			ppc->ppc_avm |= PPB_ECP | PPB_EPP | PPB_SPP;
1134			ppc->ppc_type = PPC_TYPE_SMCLIKE;
1135
1136			if (bootverbose)
1137				printf(" ECP+EPP SPP");
1138			break;
1139		default:
1140			printf("%s: unknown case (0x%x)!\n", __func__, r);
1141		}
1142
1143	} else {
1144		/* mode forced */
1145
1146		/* select CR9 and set PRTMODS2 bit */
1147		outb(efir, 0x9);
1148		outb(efdr, inb(efdr) & ~WINB_PRTMODS2);
1149
1150		/* select CR0 and reset PRTMODSx bits */
1151		outb(efir, 0x0);
1152		outb(efdr, inb(efdr) & ~(WINB_PRTMODS0 | WINB_PRTMODS1));
1153
1154		if (chipset_mode & PPB_ECP) {
1155			if (chipset_mode & PPB_EPP) {
1156				outb(efdr, inb(efdr) | WINB_ECP_EPP);
1157				if (bootverbose)
1158					printf(" ECP+EPP");
1159
1160				ppc->ppc_type = PPC_TYPE_SMCLIKE;
1161
1162			} else {
1163				outb(efdr, inb(efdr) | WINB_ECP);
1164				if (bootverbose)
1165					printf(" ECP");
1166			}
1167		} else {
1168			/* select EPP_SPP otherwise */
1169			outb(efdr, inb(efdr) | WINB_EPP_SPP);
1170			if (bootverbose)
1171				printf(" EPP SPP");
1172		}
1173		ppc->ppc_avm = chipset_mode;
1174	}
1175
1176	if (bootverbose)
1177		printf("\n");
1178
1179	/* exit configuration mode */
1180	outb(efer, 0xaa);
1181
1182	switch (ppc->ppc_type) {
1183	case PPC_TYPE_SMCLIKE:
1184		ppc_smclike_setmode(ppc, chipset_mode);
1185		break;
1186	default:
1187		ppc_generic_setmode(ppc, chipset_mode);
1188		break;
1189	}
1190
1191	return (chipset_mode);
1192}
1193#endif
1194
1195/*
1196 * ppc_generic_detect
1197 */
1198static int
1199ppc_generic_detect(struct ppc_data *ppc, int chipset_mode)
1200{
1201	/* default to generic */
1202	ppc->ppc_type = PPC_TYPE_GENERIC;
1203
1204	if (bootverbose)
1205		printf("ppc%d:", ppc->ppc_unit);
1206
1207	/* first, check for ECP */
1208	w_ecr(ppc, PPC_ECR_PS2);
1209	if ((r_ecr(ppc) & 0xe0) == PPC_ECR_PS2) {
1210		ppc->ppc_dtm |= PPB_ECP | PPB_SPP;
1211		if (bootverbose)
1212			printf(" ECP SPP");
1213
1214		/* search for SMC style ECP+EPP mode */
1215		w_ecr(ppc, PPC_ECR_EPP);
1216	}
1217
1218	/* try to reset EPP timeout bit */
1219	if (ppc_check_epp_timeout(ppc)) {
1220		ppc->ppc_dtm |= PPB_EPP;
1221
1222		if (ppc->ppc_dtm & PPB_ECP) {
1223			/* SMC like chipset found */
1224			ppc->ppc_model = SMC_LIKE;
1225			ppc->ppc_type = PPC_TYPE_SMCLIKE;
1226
1227			if (bootverbose)
1228				printf(" ECP+EPP");
1229		} else {
1230			if (bootverbose)
1231				printf(" EPP");
1232		}
1233	} else {
1234		/* restore to standard mode */
1235		w_ecr(ppc, PPC_ECR_STD);
1236	}
1237
1238	/* XXX try to detect NIBBLE and PS2 modes */
1239	ppc->ppc_dtm |= PPB_NIBBLE;
1240
1241	if (bootverbose)
1242		printf(" SPP");
1243
1244	if (chipset_mode)
1245		ppc->ppc_avm = chipset_mode;
1246	else
1247		ppc->ppc_avm = ppc->ppc_dtm;
1248
1249	if (bootverbose)
1250		printf("\n");
1251
1252	switch (ppc->ppc_type) {
1253	case PPC_TYPE_SMCLIKE:
1254		ppc_smclike_setmode(ppc, chipset_mode);
1255		break;
1256	default:
1257		ppc_generic_setmode(ppc, chipset_mode);
1258		break;
1259	}
1260
1261	return (chipset_mode);
1262}
1263
1264/*
1265 * ppc_detect()
1266 *
1267 * mode is the mode suggested at boot
1268 */
1269static int
1270ppc_detect(struct ppc_data *ppc, int chipset_mode) {
1271
1272#ifdef PPC_PROBE_CHIPSET
1273	int i, mode;
1274
1275	/* list of supported chipsets */
1276	int (*chipset_detect[])(struct ppc_data *, int) = {
1277		ppc_pc873xx_detect,
1278		ppc_smc37c66xgt_detect,
1279		ppc_w83877f_detect,
1280		ppc_smc37c935_detect,
1281		ppc_generic_detect,
1282		NULL
1283	};
1284#endif
1285
1286	/* if can't find the port and mode not forced return error */
1287	if (!ppc_detect_port(ppc) && chipset_mode == 0)
1288		return (EIO);			/* failed, port not present */
1289
1290	/* assume centronics compatible mode is supported */
1291	ppc->ppc_avm = PPB_COMPATIBLE;
1292
1293#ifdef PPC_PROBE_CHIPSET
1294	/* we have to differenciate available chipset modes,
1295	 * chipset running modes and IEEE-1284 operating modes
1296	 *
1297	 * after detection, the port must support running in compatible mode
1298	 */
1299	if (ppc->ppc_flags & 0x40) {
1300		if (bootverbose)
1301			printf("ppc: chipset forced to generic\n");
1302#endif
1303
1304		ppc->ppc_mode = ppc_generic_detect(ppc, chipset_mode);
1305
1306#ifdef PPC_PROBE_CHIPSET
1307	} else {
1308		for (i=0; chipset_detect[i] != NULL; i++) {
1309			if ((mode = chipset_detect[i](ppc, chipset_mode)) != -1) {
1310				ppc->ppc_mode = mode;
1311				break;
1312			}
1313		}
1314	}
1315#endif
1316
1317	/* configure/detect ECP FIFO */
1318	if ((ppc->ppc_avm & PPB_ECP) && !(ppc->ppc_flags & 0x80))
1319		ppc_detect_fifo(ppc);
1320
1321	return (0);
1322}
1323
1324/*
1325 * ppc_exec_microseq()
1326 *
1327 * Execute a microsequence.
1328 * Microsequence mechanism is supposed to handle fast I/O operations.
1329 */
1330int
1331ppc_exec_microseq(device_t dev, struct ppb_microseq **p_msq)
1332{
1333	struct ppc_data *ppc = DEVTOSOFTC(dev);
1334	struct ppb_microseq *mi;
1335	char cc, *p;
1336	int i, iter, len;
1337	int error;
1338
1339	register int reg;
1340	register char mask;
1341	register int accum = 0;
1342	register char *ptr = 0;
1343
1344	struct ppb_microseq *stack = 0;
1345
1346/* microsequence registers are equivalent to PC-like port registers */
1347
1348#define r_reg(reg,ppc) (bus_space_read_1((ppc)->bst, (ppc)->bsh, reg))
1349#define w_reg(reg, ppc, byte) (bus_space_write_1((ppc)->bst, (ppc)->bsh, reg, byte))
1350
1351#define INCR_PC (mi ++)		/* increment program counter */
1352
1353	mi = *p_msq;
1354	for (;;) {
1355		switch (mi->opcode) {
1356		case MS_OP_RSET:
1357			cc = r_reg(mi->arg[0].i, ppc);
1358			cc &= (char)mi->arg[2].i;	/* clear mask */
1359			cc |= (char)mi->arg[1].i;	/* assert mask */
1360                        w_reg(mi->arg[0].i, ppc, cc);
1361			INCR_PC;
1362                        break;
1363
1364		case MS_OP_RASSERT_P:
1365			reg = mi->arg[1].i;
1366			ptr = ppc->ppc_ptr;
1367
1368			if ((len = mi->arg[0].i) == MS_ACCUM) {
1369				accum = ppc->ppc_accum;
1370				for (; accum; accum--)
1371					w_reg(reg, ppc, *ptr++);
1372				ppc->ppc_accum = accum;
1373			} else
1374				for (i=0; i<len; i++)
1375					w_reg(reg, ppc, *ptr++);
1376			ppc->ppc_ptr = ptr;
1377
1378			INCR_PC;
1379			break;
1380
1381                case MS_OP_RFETCH_P:
1382			reg = mi->arg[1].i;
1383			mask = (char)mi->arg[2].i;
1384			ptr = ppc->ppc_ptr;
1385
1386			if ((len = mi->arg[0].i) == MS_ACCUM) {
1387				accum = ppc->ppc_accum;
1388				for (; accum; accum--)
1389					*ptr++ = r_reg(reg, ppc) & mask;
1390				ppc->ppc_accum = accum;
1391			} else
1392				for (i=0; i<len; i++)
1393					*ptr++ = r_reg(reg, ppc) & mask;
1394			ppc->ppc_ptr = ptr;
1395
1396			INCR_PC;
1397                        break;
1398
1399                case MS_OP_RFETCH:
1400			*((char *) mi->arg[2].p) = r_reg(mi->arg[0].i, ppc) &
1401							(char)mi->arg[1].i;
1402			INCR_PC;
1403                        break;
1404
1405		case MS_OP_RASSERT:
1406                case MS_OP_DELAY:
1407
1408		/* let's suppose the next instr. is the same */
1409		prefetch:
1410			for (;mi->opcode == MS_OP_RASSERT; INCR_PC)
1411				w_reg(mi->arg[0].i, ppc, (char)mi->arg[1].i);
1412
1413			if (mi->opcode == MS_OP_DELAY) {
1414				DELAY(mi->arg[0].i);
1415				INCR_PC;
1416				goto prefetch;
1417			}
1418			break;
1419
1420		case MS_OP_ADELAY:
1421			if (mi->arg[0].i)
1422				tsleep(NULL, PPBPRI, "ppbdelay",
1423						mi->arg[0].i * (hz/1000));
1424			INCR_PC;
1425			break;
1426
1427		case MS_OP_TRIG:
1428			reg = mi->arg[0].i;
1429			iter = mi->arg[1].i;
1430			p = (char *)mi->arg[2].p;
1431
1432			/* XXX delay limited to 255 us */
1433			for (i=0; i<iter; i++) {
1434				w_reg(reg, ppc, *p++);
1435				DELAY((unsigned char)*p++);
1436			}
1437			INCR_PC;
1438			break;
1439
1440                case MS_OP_SET:
1441                        ppc->ppc_accum = mi->arg[0].i;
1442			INCR_PC;
1443                        break;
1444
1445                case MS_OP_DBRA:
1446                        if (--ppc->ppc_accum > 0)
1447                                mi += mi->arg[0].i;
1448			INCR_PC;
1449                        break;
1450
1451                case MS_OP_BRSET:
1452                        cc = r_str(ppc);
1453                        if ((cc & (char)mi->arg[0].i) == (char)mi->arg[0].i)
1454                                mi += mi->arg[1].i;
1455			INCR_PC;
1456                        break;
1457
1458                case MS_OP_BRCLEAR:
1459                        cc = r_str(ppc);
1460                        if ((cc & (char)mi->arg[0].i) == 0)
1461                                mi += mi->arg[1].i;
1462			INCR_PC;
1463                        break;
1464
1465		case MS_OP_BRSTAT:
1466			cc = r_str(ppc);
1467			if ((cc & ((char)mi->arg[0].i | (char)mi->arg[1].i)) ==
1468							(char)mi->arg[0].i)
1469				mi += mi->arg[2].i;
1470			INCR_PC;
1471			break;
1472
1473		case MS_OP_C_CALL:
1474			/*
1475			 * If the C call returns !0 then end the microseq.
1476			 * The current state of ptr is passed to the C function
1477			 */
1478			if ((error = mi->arg[0].f(mi->arg[1].p, ppc->ppc_ptr)))
1479				return (error);
1480
1481			INCR_PC;
1482			break;
1483
1484		case MS_OP_PTR:
1485			ppc->ppc_ptr = (char *)mi->arg[0].p;
1486			INCR_PC;
1487			break;
1488
1489		case MS_OP_CALL:
1490			if (stack)
1491				panic("%s: too much calls", __func__);
1492
1493			if (mi->arg[0].p) {
1494				/* store the state of the actual
1495				 * microsequence
1496				 */
1497				stack = mi;
1498
1499				/* jump to the new microsequence */
1500				mi = (struct ppb_microseq *)mi->arg[0].p;
1501			} else
1502				INCR_PC;
1503
1504			break;
1505
1506		case MS_OP_SUBRET:
1507			/* retrieve microseq and pc state before the call */
1508			mi = stack;
1509
1510			/* reset the stack */
1511			stack = 0;
1512
1513			/* XXX return code */
1514
1515			INCR_PC;
1516			break;
1517
1518                case MS_OP_PUT:
1519                case MS_OP_GET:
1520                case MS_OP_RET:
1521			/* can't return to ppb level during the execution
1522			 * of a submicrosequence */
1523			if (stack)
1524				panic("%s: can't return to ppb level",
1525								__func__);
1526
1527			/* update pc for ppb level of execution */
1528			*p_msq = mi;
1529
1530			/* return to ppb level of execution */
1531			return (0);
1532
1533                default:
1534                        panic("%s: unknown microsequence opcode 0x%x",
1535                                __func__, mi->opcode);
1536                }
1537	}
1538
1539	/* unreached */
1540}
1541
1542static void
1543ppcintr(void *arg)
1544{
1545	device_t dev = (device_t)arg;
1546	struct ppc_data *ppc = (struct ppc_data *)device_get_softc(dev);
1547	u_char ctr, ecr, str;
1548
1549	str = r_str(ppc);
1550	ctr = r_ctr(ppc);
1551	ecr = r_ecr(ppc);
1552
1553#if defined(PPC_DEBUG) && PPC_DEBUG > 1
1554		printf("![%x/%x/%x]", ctr, ecr, str);
1555#endif
1556
1557	/* don't use ecp mode with IRQENABLE set */
1558	if (ctr & IRQENABLE) {
1559		return;
1560	}
1561
1562	/* interrupts are generated by nFault signal
1563	 * only in ECP mode */
1564	if ((str & nFAULT) && (ppc->ppc_mode & PPB_ECP)) {
1565		/* check if ppc driver has programmed the
1566		 * nFault interrupt */
1567		if  (ppc->ppc_irqstat & PPC_IRQ_nFAULT) {
1568
1569			w_ecr(ppc, ecr | PPC_nFAULT_INTR);
1570			ppc->ppc_irqstat &= ~PPC_IRQ_nFAULT;
1571		} else {
1572			/* shall be handled by underlying layers XXX */
1573			return;
1574		}
1575	}
1576
1577	if (ppc->ppc_irqstat & PPC_IRQ_DMA) {
1578		/* disable interrupts (should be done by hardware though) */
1579		w_ecr(ppc, ecr | PPC_SERVICE_INTR);
1580		ppc->ppc_irqstat &= ~PPC_IRQ_DMA;
1581		ecr = r_ecr(ppc);
1582
1583		/* check if DMA completed */
1584		if ((ppc->ppc_avm & PPB_ECP) && (ecr & PPC_ENABLE_DMA)) {
1585#ifdef PPC_DEBUG
1586			printf("a");
1587#endif
1588			/* stop DMA */
1589			w_ecr(ppc, ecr & ~PPC_ENABLE_DMA);
1590			ecr = r_ecr(ppc);
1591
1592			if (ppc->ppc_dmastat == PPC_DMA_STARTED) {
1593#ifdef PPC_DEBUG
1594				printf("d");
1595#endif
1596				isa_dmadone(
1597					ppc->ppc_dmaflags,
1598					ppc->ppc_dmaddr,
1599					ppc->ppc_dmacnt,
1600					ppc->ppc_dmachan);
1601
1602				ppc->ppc_dmastat = PPC_DMA_COMPLETE;
1603
1604				/* wakeup the waiting process */
1605				wakeup(ppc);
1606			}
1607		}
1608	} else if (ppc->ppc_irqstat & PPC_IRQ_FIFO) {
1609
1610		/* classic interrupt I/O */
1611		ppc->ppc_irqstat &= ~PPC_IRQ_FIFO;
1612	}
1613
1614	return;
1615}
1616
1617int
1618ppc_read(device_t dev, char *buf, int len, int mode)
1619{
1620	return (EINVAL);
1621}
1622
1623/*
1624 * Call this function if you want to send data in any advanced mode
1625 * of your parallel port: FIFO, DMA
1626 *
1627 * If what you want is not possible (no ECP, no DMA...),
1628 * EINVAL is returned
1629 */
1630int
1631ppc_write(device_t dev, char *buf, int len, int how)
1632{
1633	struct ppc_data *ppc = DEVTOSOFTC(dev);
1634	char ecr, ecr_sav, ctr, ctr_sav;
1635	int s, error = 0;
1636	int spin;
1637
1638#ifdef PPC_DEBUG
1639	printf("w");
1640#endif
1641
1642	ecr_sav = r_ecr(ppc);
1643	ctr_sav = r_ctr(ppc);
1644
1645	/*
1646	 * Send buffer with DMA, FIFO and interrupts
1647	 */
1648	if ((ppc->ppc_avm & PPB_ECP) && (ppc->ppc_registered)) {
1649
1650	    if (ppc->ppc_dmachan > 0) {
1651
1652		/* byte mode, no intr, no DMA, dir=0, flush fifo
1653		 */
1654		ecr = PPC_ECR_STD | PPC_DISABLE_INTR;
1655		w_ecr(ppc, ecr);
1656
1657		/* disable nAck interrupts */
1658		ctr = r_ctr(ppc);
1659		ctr &= ~IRQENABLE;
1660		w_ctr(ppc, ctr);
1661
1662		ppc->ppc_dmaflags = 0;
1663		ppc->ppc_dmaddr = (caddr_t)buf;
1664		ppc->ppc_dmacnt = (u_int)len;
1665
1666		switch (ppc->ppc_mode) {
1667		case PPB_COMPATIBLE:
1668			/* compatible mode with FIFO, no intr, DMA, dir=0 */
1669			ecr = PPC_ECR_FIFO | PPC_DISABLE_INTR | PPC_ENABLE_DMA;
1670			break;
1671		case PPB_ECP:
1672			ecr = PPC_ECR_ECP | PPC_DISABLE_INTR | PPC_ENABLE_DMA;
1673			break;
1674		default:
1675			error = EINVAL;
1676			goto error;
1677		}
1678
1679		w_ecr(ppc, ecr);
1680		ecr = r_ecr(ppc);
1681
1682		/* enter splhigh() not to be preempted
1683		 * by the dma interrupt, we may miss
1684		 * the wakeup otherwise
1685		 */
1686		s = splhigh();
1687
1688		ppc->ppc_dmastat = PPC_DMA_INIT;
1689
1690		/* enable interrupts */
1691		ecr &= ~PPC_SERVICE_INTR;
1692		ppc->ppc_irqstat = PPC_IRQ_DMA;
1693		w_ecr(ppc, ecr);
1694
1695		isa_dmastart(
1696			ppc->ppc_dmaflags,
1697			ppc->ppc_dmaddr,
1698			ppc->ppc_dmacnt,
1699			ppc->ppc_dmachan);
1700#ifdef PPC_DEBUG
1701		printf("s%d", ppc->ppc_dmacnt);
1702#endif
1703		ppc->ppc_dmastat = PPC_DMA_STARTED;
1704
1705		/* Wait for the DMA completed interrupt. We hope we won't
1706		 * miss it, otherwise a signal will be necessary to unlock the
1707		 * process.
1708		 */
1709		do {
1710			/* release CPU */
1711			error = tsleep(ppc,
1712				PPBPRI | PCATCH, "ppcdma", 0);
1713
1714		} while (error == EWOULDBLOCK);
1715
1716		splx(s);
1717
1718		if (error) {
1719#ifdef PPC_DEBUG
1720			printf("i");
1721#endif
1722			/* stop DMA */
1723			isa_dmadone(
1724				ppc->ppc_dmaflags, ppc->ppc_dmaddr,
1725				ppc->ppc_dmacnt, ppc->ppc_dmachan);
1726
1727			/* no dma, no interrupt, flush the fifo */
1728			w_ecr(ppc, PPC_ECR_RESET);
1729
1730			ppc->ppc_dmastat = PPC_DMA_INTERRUPTED;
1731			goto error;
1732		}
1733
1734		/* wait for an empty fifo */
1735		while (!(r_ecr(ppc) & PPC_FIFO_EMPTY)) {
1736
1737			for (spin=100; spin; spin--)
1738				if (r_ecr(ppc) & PPC_FIFO_EMPTY)
1739					goto fifo_empty;
1740#ifdef PPC_DEBUG
1741			printf("Z");
1742#endif
1743			error = tsleep(ppc, PPBPRI | PCATCH, "ppcfifo", hz/100);
1744			if (error != EWOULDBLOCK) {
1745#ifdef PPC_DEBUG
1746				printf("I");
1747#endif
1748				/* no dma, no interrupt, flush the fifo */
1749				w_ecr(ppc, PPC_ECR_RESET);
1750
1751				ppc->ppc_dmastat = PPC_DMA_INTERRUPTED;
1752				error = EINTR;
1753				goto error;
1754			}
1755		}
1756
1757fifo_empty:
1758		/* no dma, no interrupt, flush the fifo */
1759		w_ecr(ppc, PPC_ECR_RESET);
1760
1761	    } else
1762		error = EINVAL;			/* XXX we should FIFO and
1763						 * interrupts */
1764	} else
1765		error = EINVAL;
1766
1767error:
1768
1769	/* PDRQ must be kept unasserted until nPDACK is
1770	 * deasserted for a minimum of 350ns (SMC datasheet)
1771	 *
1772	 * Consequence may be a FIFO that never empty
1773	 */
1774	DELAY(1);
1775
1776	w_ecr(ppc, ecr_sav);
1777	w_ctr(ppc, ctr_sav);
1778
1779	return (error);
1780}
1781
1782void
1783ppc_reset_epp(device_t dev)
1784{
1785	struct ppc_data *ppc = DEVTOSOFTC(dev);
1786
1787	ppc_reset_epp_timeout(ppc);
1788
1789	return;
1790}
1791
1792int
1793ppc_setmode(device_t dev, int mode)
1794{
1795	struct ppc_data *ppc = DEVTOSOFTC(dev);
1796
1797	switch (ppc->ppc_type) {
1798	case PPC_TYPE_SMCLIKE:
1799		return (ppc_smclike_setmode(ppc, mode));
1800		break;
1801
1802	case PPC_TYPE_GENERIC:
1803	default:
1804		return (ppc_generic_setmode(ppc, mode));
1805		break;
1806	}
1807
1808	/* not reached */
1809	return (ENXIO);
1810}
1811
1812static struct isa_pnp_id lpc_ids[] = {
1813	{ 0x0004d041, "Standard parallel printer port" }, /* PNP0400 */
1814	{ 0x0104d041, "ECP parallel printer port" }, /* PNP0401 */
1815	{ 0 }
1816};
1817
1818static int
1819ppc_isa_probe(device_t dev)
1820{
1821	device_t parent;
1822	int error;
1823
1824	parent = device_get_parent(dev);
1825
1826	error = ISA_PNP_PROBE(parent, dev, lpc_ids);
1827	if (error == ENXIO)
1828		return (ENXIO);
1829	else if (error != 0)	/* XXX shall be set after detection */
1830		device_set_desc(dev, "Parallel port");
1831
1832	return(ppc_probe(dev));
1833}
1834
1835int
1836ppc_probe(device_t dev)
1837{
1838#ifdef __i386__
1839	static short next_bios_ppc = 0;
1840#endif
1841	struct ppc_data *ppc;
1842	int error;
1843	u_long port;
1844
1845	/*
1846	 * Allocate the ppc_data structure.
1847	 */
1848	ppc = DEVTOSOFTC(dev);
1849	bzero(ppc, sizeof(struct ppc_data));
1850
1851	ppc->rid_irq = ppc->rid_drq = ppc->rid_ioport = 0;
1852	ppc->res_irq = ppc->res_drq = ppc->res_ioport = 0;
1853
1854	/* retrieve ISA parameters */
1855	error = bus_get_resource(dev, SYS_RES_IOPORT, 0, &port, NULL);
1856
1857#ifdef __i386__
1858	/*
1859	 * If port not specified, use bios list.
1860	 */
1861	if (error) {
1862		if((next_bios_ppc < BIOS_MAX_PPC) &&
1863				(*(BIOS_PORTS+next_bios_ppc) != 0) ) {
1864			port = *(BIOS_PORTS+next_bios_ppc++);
1865			if (bootverbose)
1866			  device_printf(dev, "parallel port found at 0x%x\n",
1867					(int) port);
1868		} else {
1869			device_printf(dev, "parallel port not found.\n");
1870			return ENXIO;
1871		}
1872		bus_set_resource(dev, SYS_RES_IOPORT, 0, port,
1873				 IO_LPTSIZE_EXTENDED);
1874	}
1875#endif
1876#ifdef __alpha__
1877	/*
1878	 * There isn't a bios list on alpha. Put it in the usual place.
1879	 */
1880	if (error) {
1881		bus_set_resource(dev, SYS_RES_IOPORT, 0, 0x3bc,
1882				 IO_LPTSIZE_NORMAL);
1883	}
1884#endif
1885
1886	/* IO port is mandatory */
1887
1888	/* Try "extended" IO port range...*/
1889	ppc->res_ioport = bus_alloc_resource(dev, SYS_RES_IOPORT,
1890					     &ppc->rid_ioport, 0, ~0,
1891					     IO_LPTSIZE_EXTENDED, RF_ACTIVE);
1892
1893	if (ppc->res_ioport != 0) {
1894		if (bootverbose)
1895			device_printf(dev, "using extended I/O port range\n");
1896	} else {
1897		/* Failed? If so, then try the "normal" IO port range... */
1898		 ppc->res_ioport = bus_alloc_resource(dev, SYS_RES_IOPORT,
1899						      &ppc->rid_ioport, 0, ~0,
1900						      IO_LPTSIZE_NORMAL,
1901						      RF_ACTIVE);
1902		if (ppc->res_ioport != 0) {
1903			if (bootverbose)
1904				device_printf(dev, "using normal I/O port range\n");
1905		} else {
1906			device_printf(dev, "cannot reserve I/O port range\n");
1907			goto error;
1908		}
1909	}
1910
1911 	ppc->ppc_base = rman_get_start(ppc->res_ioport);
1912
1913	ppc->bsh = rman_get_bushandle(ppc->res_ioport);
1914	ppc->bst = rman_get_bustag(ppc->res_ioport);
1915
1916	ppc->ppc_flags = device_get_flags(dev);
1917
1918	if (!(ppc->ppc_flags & 0x20)) {
1919		ppc->res_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ,
1920						      &ppc->rid_irq,
1921						      RF_SHAREABLE);
1922		ppc->res_drq = bus_alloc_resource_any(dev, SYS_RES_DRQ,
1923						      &ppc->rid_drq,
1924						      RF_ACTIVE);
1925	}
1926
1927	if (ppc->res_irq)
1928		ppc->ppc_irq = rman_get_start(ppc->res_irq);
1929	if (ppc->res_drq)
1930		ppc->ppc_dmachan = rman_get_start(ppc->res_drq);
1931
1932	ppc->ppc_unit = device_get_unit(dev);
1933	ppc->ppc_model = GENERIC;
1934
1935	ppc->ppc_mode = PPB_COMPATIBLE;
1936	ppc->ppc_epp = (ppc->ppc_flags & 0x10) >> 4;
1937
1938	ppc->ppc_type = PPC_TYPE_GENERIC;
1939
1940	/*
1941	 * Try to detect the chipset and its mode.
1942	 */
1943	if (ppc_detect(ppc, ppc->ppc_flags & 0xf))
1944		goto error;
1945
1946	return (0);
1947
1948error:
1949	if (ppc->res_irq != 0) {
1950		bus_release_resource(dev, SYS_RES_IRQ, ppc->rid_irq,
1951				     ppc->res_irq);
1952	}
1953	if (ppc->res_ioport != 0) {
1954		bus_deactivate_resource(dev, SYS_RES_IOPORT, ppc->rid_ioport,
1955					ppc->res_ioport);
1956		bus_release_resource(dev, SYS_RES_IOPORT, ppc->rid_ioport,
1957				     ppc->res_ioport);
1958	}
1959	if (ppc->res_drq != 0) {
1960		bus_deactivate_resource(dev, SYS_RES_DRQ, ppc->rid_drq,
1961					ppc->res_drq);
1962		bus_release_resource(dev, SYS_RES_DRQ, ppc->rid_drq,
1963				     ppc->res_drq);
1964	}
1965	return (ENXIO);
1966}
1967
1968int
1969ppc_attach(device_t dev)
1970{
1971	struct ppc_data *ppc = DEVTOSOFTC(dev);
1972
1973	device_t ppbus;
1974
1975	device_printf(dev, "%s chipset (%s) in %s mode%s\n",
1976		      ppc_models[ppc->ppc_model], ppc_avms[ppc->ppc_avm],
1977		      ppc_modes[ppc->ppc_mode], (PPB_IS_EPP(ppc->ppc_mode)) ?
1978		      ppc_epp_protocol[ppc->ppc_epp] : "");
1979
1980	if (ppc->ppc_fifo)
1981		device_printf(dev, "FIFO with %d/%d/%d bytes threshold\n",
1982			      ppc->ppc_fifo, ppc->ppc_wthr, ppc->ppc_rthr);
1983
1984	if ((ppc->ppc_avm & PPB_ECP) && (ppc->ppc_dmachan > 0)) {
1985		/* acquire the DMA channel forever */	/* XXX */
1986		isa_dma_acquire(ppc->ppc_dmachan);
1987		isa_dmainit(ppc->ppc_dmachan, 1024); /* nlpt.BUFSIZE */
1988	}
1989
1990	/* add ppbus as a child of this isa to parallel bridge */
1991	ppbus = device_add_child(dev, "ppbus", -1);
1992
1993	/*
1994	 * Probe the ppbus and attach devices found.
1995	 */
1996	device_probe_and_attach(ppbus);
1997
1998	/* register the ppc interrupt handler as default */
1999	if (ppc->res_irq) {
2000		/* default to the tty mask for registration */	/* XXX */
2001		if (bus_setup_intr(dev, ppc->res_irq, INTR_TYPE_TTY,
2002		    ppcintr, dev, &ppc->intr_cookie) == 0) {
2003
2004			/* remember the ppcintr is registered */
2005			ppc->ppc_registered = 1;
2006		}
2007	}
2008
2009	return (0);
2010}
2011
2012int
2013ppc_detach(device_t dev)
2014{
2015	struct ppc_data *ppc = DEVTOSOFTC(dev);
2016	device_t *children;
2017	int nchildren, i;
2018
2019	if (ppc->res_irq == 0) {
2020		return (ENXIO);
2021	}
2022
2023	/* detach & delete all children */
2024	if (!device_get_children(dev, &children, &nchildren)) {
2025		for (i = 0; i < nchildren; i++)
2026			if (children[i])
2027				device_delete_child(dev, children[i]);
2028		free(children, M_TEMP);
2029	}
2030
2031	if (ppc->res_irq != 0) {
2032		bus_teardown_intr(dev, ppc->res_irq, ppc->intr_cookie);
2033		bus_release_resource(dev, SYS_RES_IRQ, ppc->rid_irq,
2034				     ppc->res_irq);
2035	}
2036	if (ppc->res_ioport != 0) {
2037		bus_deactivate_resource(dev, SYS_RES_IOPORT, ppc->rid_ioport,
2038					ppc->res_ioport);
2039		bus_release_resource(dev, SYS_RES_IOPORT, ppc->rid_ioport,
2040				     ppc->res_ioport);
2041	}
2042	if (ppc->res_drq != 0) {
2043		bus_deactivate_resource(dev, SYS_RES_DRQ, ppc->rid_drq,
2044					ppc->res_drq);
2045		bus_release_resource(dev, SYS_RES_DRQ, ppc->rid_drq,
2046				     ppc->res_drq);
2047	}
2048
2049	return (0);
2050}
2051
2052u_char
2053ppc_io(device_t ppcdev, int iop, u_char *addr, int cnt, u_char byte)
2054{
2055	struct ppc_data *ppc = DEVTOSOFTC(ppcdev);
2056	switch (iop) {
2057	case PPB_OUTSB_EPP:
2058	    bus_space_write_multi_1(ppc->bst, ppc->bsh, PPC_EPP_DATA, addr, cnt);
2059		break;
2060	case PPB_OUTSW_EPP:
2061	    bus_space_write_multi_2(ppc->bst, ppc->bsh, PPC_EPP_DATA, (u_int16_t *)addr, cnt);
2062		break;
2063	case PPB_OUTSL_EPP:
2064	    bus_space_write_multi_4(ppc->bst, ppc->bsh, PPC_EPP_DATA, (u_int32_t *)addr, cnt);
2065		break;
2066	case PPB_INSB_EPP:
2067	    bus_space_read_multi_1(ppc->bst, ppc->bsh, PPC_EPP_DATA, addr, cnt);
2068		break;
2069	case PPB_INSW_EPP:
2070	    bus_space_read_multi_2(ppc->bst, ppc->bsh, PPC_EPP_DATA, (u_int16_t *)addr, cnt);
2071		break;
2072	case PPB_INSL_EPP:
2073	    bus_space_read_multi_4(ppc->bst, ppc->bsh, PPC_EPP_DATA, (u_int32_t *)addr, cnt);
2074		break;
2075	case PPB_RDTR:
2076		return (r_dtr(ppc));
2077	case PPB_RSTR:
2078		return (r_str(ppc));
2079	case PPB_RCTR:
2080		return (r_ctr(ppc));
2081	case PPB_REPP_A:
2082		return (r_epp_A(ppc));
2083	case PPB_REPP_D:
2084		return (r_epp_D(ppc));
2085	case PPB_RECR:
2086		return (r_ecr(ppc));
2087	case PPB_RFIFO:
2088		return (r_fifo(ppc));
2089	case PPB_WDTR:
2090		w_dtr(ppc, byte);
2091		break;
2092	case PPB_WSTR:
2093		w_str(ppc, byte);
2094		break;
2095	case PPB_WCTR:
2096		w_ctr(ppc, byte);
2097		break;
2098	case PPB_WEPP_A:
2099		w_epp_A(ppc, byte);
2100		break;
2101	case PPB_WEPP_D:
2102		w_epp_D(ppc, byte);
2103		break;
2104	case PPB_WECR:
2105		w_ecr(ppc, byte);
2106		break;
2107	case PPB_WFIFO:
2108		w_fifo(ppc, byte);
2109		break;
2110	default:
2111		panic("%s: unknown I/O operation", __func__);
2112		break;
2113	}
2114
2115	return (0);	/* not significative */
2116}
2117
2118int
2119ppc_read_ivar(device_t bus, device_t dev, int index, uintptr_t *val)
2120{
2121	struct ppc_data *ppc = (struct ppc_data *)device_get_softc(bus);
2122
2123	switch (index) {
2124	case PPC_IVAR_EPP_PROTO:
2125		*val = (u_long)ppc->ppc_epp;
2126		break;
2127	case PPC_IVAR_IRQ:
2128		*val = (u_long)ppc->ppc_irq;
2129		break;
2130	default:
2131		return (ENOENT);
2132	}
2133
2134	return (0);
2135}
2136
2137/*
2138 * Resource is useless here since ppbus devices' interrupt handlers are
2139 * multiplexed to the same resource initially allocated by ppc
2140 */
2141int
2142ppc_setup_intr(device_t bus, device_t child, struct resource *r, int flags,
2143			void (*ihand)(void *), void *arg, void **cookiep)
2144{
2145	int error;
2146	struct ppc_data *ppc = DEVTOSOFTC(bus);
2147
2148	if (ppc->ppc_registered) {
2149		/* XXX refuse registration if DMA is in progress */
2150
2151		/* first, unregister the default interrupt handler */
2152		if ((error = BUS_TEARDOWN_INTR(device_get_parent(bus),
2153				bus, ppc->res_irq, ppc->intr_cookie)))
2154			return (error);
2155
2156/* 		bus_deactivate_resource(bus, SYS_RES_IRQ, ppc->rid_irq, */
2157/* 					ppc->res_irq); */
2158
2159		/* DMA/FIFO operation won't be possible anymore */
2160		ppc->ppc_registered = 0;
2161	}
2162
2163	/* pass registration to the upper layer, ignore the incoming resource */
2164	return (BUS_SETUP_INTR(device_get_parent(bus), child,
2165			       r, flags, ihand, arg, cookiep));
2166}
2167
2168/*
2169 * When no underlying device has a registered interrupt, register the ppc
2170 * layer one
2171 */
2172int
2173ppc_teardown_intr(device_t bus, device_t child, struct resource *r, void *ih)
2174{
2175	int error;
2176	struct ppc_data *ppc = DEVTOSOFTC(bus);
2177	device_t parent = device_get_parent(bus);
2178
2179	/* pass unregistration to the upper layer */
2180	if ((error = BUS_TEARDOWN_INTR(parent, child, r, ih)))
2181		return (error);
2182
2183	/* default to the tty mask for registration */		/* XXX */
2184	if (ppc->ppc_irq &&
2185		!(error = BUS_SETUP_INTR(parent, bus, ppc->res_irq,
2186			INTR_TYPE_TTY, ppcintr, bus, &ppc->intr_cookie))) {
2187
2188		/* remember the ppcintr is registered */
2189		ppc->ppc_registered = 1;
2190	}
2191
2192	return (error);
2193}
2194
2195DRIVER_MODULE(ppc, isa, ppc_driver, ppc_devclass, 0, 0);
2196DRIVER_MODULE(ppc, acpi, ppc_driver, ppc_devclass, 0, 0);
2197MODULE_DEPEND(ppc, ppbus, 1, 1, 1);
2198