ppc.c revision 330897
1139749Simp/*-
2131276Snjl * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3131276Snjl *
4131276Snjl * Copyright (c) 1997-2000 Nicolas Souchu
5131276Snjl * Copyright (c) 2001 Alcove - Nicolas Souchu
6131276Snjl * All rights reserved.
7131276Snjl *
8131276Snjl * Redistribution and use in source and binary forms, with or without
9131276Snjl * modification, are permitted provided that the following conditions
10131276Snjl * are met:
11131276Snjl * 1. Redistributions of source code must retain the above copyright
12131276Snjl *    notice, this list of conditions and the following disclaimer.
13131276Snjl * 2. Redistributions in binary form must reproduce the above copyright
14131276Snjl *    notice, this list of conditions and the following disclaimer in the
15131276Snjl *    documentation and/or other materials provided with the distribution.
16131276Snjl *
17131276Snjl * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18131276Snjl * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19131276Snjl * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20131276Snjl * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21131276Snjl * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22131276Snjl * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23131276Snjl * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24131276Snjl * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25131276Snjl * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26131276Snjl * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27131276Snjl * SUCH DAMAGE.
28131276Snjl */
29131276Snjl
30131276Snjl#include <sys/cdefs.h>
31131276Snjl__FBSDID("$FreeBSD: stable/11/sys/dev/ppc/ppc.c 330897 2018-03-14 03:19:51Z eadler $");
32193530Sjkim
33193530Sjkim#include "opt_ppc.h"
34131276Snjl
35131276Snjl#include <sys/param.h>
36131276Snjl#include <sys/systm.h>
37132212Snjl#include <sys/bus.h>
38131276Snjl#include <sys/kernel.h>
39132212Snjl#include <sys/lock.h>
40132212Snjl#include <sys/interrupt.h>
41132212Snjl#include <sys/module.h>
42132212Snjl#include <sys/malloc.h>
43132212Snjl#include <sys/mutex.h>
44132212Snjl#include <sys/proc.h>
45132212Snjl
46132212Snjl#include <machine/bus.h>
47132212Snjl#include <machine/resource.h>
48132212Snjl#include <sys/rman.h>
49132212Snjl
50132212Snjl#ifdef __i386__
51132212Snjl#include <vm/vm.h>
52132212Snjl#include <vm/pmap.h>
53132212Snjl#include <machine/vmparam.h>
54132212Snjl#endif
55148352Snjl
56148352Snjl#include <dev/ppbus/ppbconf.h>
57148352Snjl#include <dev/ppbus/ppb_msq.h>
58132212Snjl
59132212Snjl#include <dev/ppc/ppcvar.h>
60132212Snjl#include <dev/ppc/ppcreg.h>
61132212Snjl
62132212Snjl#include "ppbus_if.h"
63131276Snjl
64131276Snjlstatic void ppcintr(void *arg);
65131276Snjl
66131276Snjl#define	IO_LPTSIZE_EXTENDED	8	/* "Extended" LPT controllers */
67131276Snjl#define	IO_LPTSIZE_NORMAL	4	/* "Normal" LPT controllers */
68131276Snjl
69131276Snjl#define LOG_PPC(function, ppc, string) \
70131276Snjl		if (bootverbose) printf("%s: %s\n", function, string)
71131276Snjl
72132212Snjl#if defined(__i386__) && defined(PC98)
73132212Snjl#define	PC98_IEEE_1284_DISABLE	0x100
74131276Snjl#define	PC98_IEEE_1284_PORT	0x140
75132212Snjl#endif
76132212Snjl
77132212Snjl#define DEVTOSOFTC(dev) ((struct ppc_data *)device_get_softc(dev))
78132212Snjl
79132212Snjl/*
80132212Snjl * We use critical enter/exit for the simple config locking needed to
81132212Snjl * detect the devices. We just want to make sure that both of our writes
82132212Snjl * happen without someone else also writing to those config registers. Since
83131276Snjl * we just do this at startup, Giant keeps multiple threads from executing,
84131276Snjl * and critical_enter() then is all that's needed to keep us from being preempted
85131276Snjl * during the critical sequences with the hardware.
86131276Snjl *
87131276Snjl * Note: this doesn't prevent multiple threads from putting the chips into
88131276Snjl * config mode, but since we only do that to detect the type at startup the
89131276Snjl * extra overhead isn't needed since Giant protects us from multiple entry
90132212Snjl * and no other code changes these registers.
91131276Snjl */
92132212Snjl#define PPC_CONFIG_LOCK(ppc)		critical_enter()
93132212Snjl#define PPC_CONFIG_UNLOCK(ppc)		critical_exit()
94132212Snjl
95132212Snjldevclass_t ppc_devclass;
96132212Snjlconst char ppc_driver_name[] = "ppc";
97132212Snjl
98132212Snjlstatic char *ppc_models[] = {
99132212Snjl	"SMC-like", "SMC FDC37C665GT", "SMC FDC37C666GT", "PC87332", "PC87306",
100132212Snjl	"82091AA", "Generic", "W83877F", "W83877AF", "Winbond", "PC87334",
101132212Snjl	"SMC FDC37C935", "PC87303", 0
102132212Snjl};
103132212Snjl
104132212Snjl/* list of available modes */
105132212Snjlstatic char *ppc_avms[] = {
106132212Snjl	"COMPATIBLE", "NIBBLE-only", "PS2-only", "PS2/NIBBLE", "EPP-only",
107131276Snjl	"EPP/NIBBLE", "EPP/PS2", "EPP/PS2/NIBBLE", "ECP-only",
108131276Snjl	"ECP/NIBBLE", "ECP/PS2", "ECP/PS2/NIBBLE", "ECP/EPP",
109131276Snjl	"ECP/EPP/NIBBLE", "ECP/EPP/PS2", "ECP/EPP/PS2/NIBBLE", 0
110131276Snjl};
111131276Snjl
112131276Snjl/* list of current executing modes
113131276Snjl * Note that few modes do not actually exist.
114131276Snjl */
115131276Snjlstatic char *ppc_modes[] = {
116138305Snjl	"COMPATIBLE", "NIBBLE", "PS/2", "PS/2", "EPP",
117138305Snjl	"EPP", "EPP", "EPP", "ECP",
118138305Snjl	"ECP", "ECP+PS2", "ECP+PS2", "ECP+EPP",
119138305Snjl	"ECP+EPP", "ECP+EPP", "ECP+EPP", 0
120138305Snjl};
121138305Snjl
122138305Snjlstatic char *ppc_epp_protocol[] = { " (EPP 1.9)", " (EPP 1.7)", 0 };
123138305Snjl
124138305Snjl#ifdef __i386__
125138305Snjl/*
126138305Snjl * BIOS printer list - used by BIOS probe.
127138305Snjl */
128138305Snjl#define	BIOS_PPC_PORTS	0x408
129138305Snjl#define	BIOS_PORTS	(short *)(KERNBASE+BIOS_PPC_PORTS)
130138305Snjl#define	BIOS_MAX_PPC	4
131138305Snjl#endif
132138305Snjl
133138305Snjl/*
134138305Snjl * ppc_ecp_sync()		XXX
135138305Snjl */
136132212Snjlint
137132212Snjlppc_ecp_sync(device_t dev)
138132212Snjl{
139131276Snjl	int i, r;
140132212Snjl	struct ppc_data *ppc = DEVTOSOFTC(dev);
141132212Snjl
142132212Snjl	PPC_ASSERT_LOCKED(ppc);
143132212Snjl	if (!(ppc->ppc_avm & PPB_ECP) && !(ppc->ppc_dtm & PPB_ECP))
144132212Snjl		return 0;
145132212Snjl
146132212Snjl	r = r_ecr(ppc);
147132212Snjl	if ((r & 0xe0) != PPC_ECR_EPP)
148132212Snjl		return 0;
149132212Snjl
150132212Snjl	for (i = 0; i < 100; i++) {
151132212Snjl		r = r_ecr(ppc);
152132212Snjl		if (r & 0x1)
153132212Snjl			return 0;
154132212Snjl		DELAY(100);
155131276Snjl	}
156131276Snjl
157132212Snjl	device_printf(dev, "ECP sync failed as data still present in FIFO.\n");
158132212Snjl
159132212Snjl	return 0;
160131276Snjl}
161143861Snjl
162143861Snjl/*
163144629Snjl * ppc_detect_fifo()
164144629Snjl *
165144629Snjl * Detect parallel port FIFO
166144629Snjl */
167144629Snjlstatic int
168144629Snjlppc_detect_fifo(struct ppc_data *ppc)
169144629Snjl{
170144629Snjl	char ecr_sav;
171144629Snjl	char ctr_sav, ctr, cc;
172144629Snjl	short i;
173144629Snjl
174144629Snjl	/* save registers */
175144629Snjl	ecr_sav = r_ecr(ppc);
176143861Snjl	ctr_sav = r_ctr(ppc);
177143861Snjl
178143861Snjl	/* enter ECP configuration mode, no interrupt, no DMA */
179143861Snjl	w_ecr(ppc, 0xf4);
180143861Snjl
181143861Snjl	/* read PWord size - transfers in FIFO mode must be PWord aligned */
182143861Snjl	ppc->ppc_pword = (r_cnfgA(ppc) & PPC_PWORD_MASK);
183143861Snjl
184143861Snjl	/* XXX 16 and 32 bits implementations not supported */
185143861Snjl	if (ppc->ppc_pword != PPC_PWORD_8) {
186143861Snjl		LOG_PPC(__func__, ppc, "PWord not supported");
187143861Snjl		goto error;
188143861Snjl	}
189143861Snjl
190143861Snjl	w_ecr(ppc, 0x34);		/* byte mode, no interrupt, no DMA */
191143861Snjl	ctr = r_ctr(ppc);
192143861Snjl	w_ctr(ppc, ctr | PCD);		/* set direction to 1 */
193143861Snjl
194143861Snjl	/* enter ECP test mode, no interrupt, no DMA */
195143861Snjl	w_ecr(ppc, 0xd4);
196143861Snjl
197143861Snjl	/* flush the FIFO */
198143861Snjl	for (i=0; i<1024; i++) {
199143861Snjl		if (r_ecr(ppc) & PPC_FIFO_EMPTY)
200143861Snjl			break;
201143861Snjl		cc = r_fifo(ppc);
202143861Snjl	}
203143861Snjl
204148352Snjl	if (i >= 1024) {
205148352Snjl		LOG_PPC(__func__, ppc, "can't flush FIFO");
206148352Snjl		goto error;
207148352Snjl	}
208148352Snjl
209148352Snjl	/* enable interrupts, no DMA */
210148352Snjl	w_ecr(ppc, 0xd0);
211148352Snjl
212148352Snjl	/* determine readIntrThreshold
213148352Snjl	 * fill the FIFO until serviceIntr is set
214148352Snjl	 */
215148352Snjl	for (i=0; i<1024; i++) {
216148352Snjl		w_fifo(ppc, (char)i);
217148352Snjl		if (!ppc->ppc_rthr && (r_ecr(ppc) & PPC_SERVICE_INTR)) {
218148352Snjl			/* readThreshold reached */
219148352Snjl			ppc->ppc_rthr = i+1;
220148352Snjl		}
221148352Snjl		if (r_ecr(ppc) & PPC_FIFO_FULL) {
222148352Snjl			ppc->ppc_fifo = i+1;
223148352Snjl			break;
224148352Snjl		}
225148352Snjl	}
226
227	if (i >= 1024) {
228		LOG_PPC(__func__, ppc, "can't fill FIFO");
229		goto error;
230	}
231
232	w_ecr(ppc, 0xd4);		/* test mode, no interrupt, no DMA */
233	w_ctr(ppc, ctr & ~PCD);		/* set direction to 0 */
234	w_ecr(ppc, 0xd0);		/* enable interrupts */
235
236	/* determine writeIntrThreshold
237	 * empty the FIFO until serviceIntr is set
238	 */
239	for (i=ppc->ppc_fifo; i>0; i--) {
240		if (r_fifo(ppc) != (char)(ppc->ppc_fifo-i)) {
241			LOG_PPC(__func__, ppc, "invalid data in FIFO");
242			goto error;
243		}
244		if (r_ecr(ppc) & PPC_SERVICE_INTR) {
245			/* writeIntrThreshold reached */
246			ppc->ppc_wthr = ppc->ppc_fifo - i+1;
247		}
248		/* if FIFO empty before the last byte, error */
249		if (i>1 && (r_ecr(ppc) & PPC_FIFO_EMPTY)) {
250			LOG_PPC(__func__, ppc, "data lost in FIFO");
251			goto error;
252		}
253	}
254
255	/* FIFO must be empty after the last byte */
256	if (!(r_ecr(ppc) & PPC_FIFO_EMPTY)) {
257		LOG_PPC(__func__, ppc, "can't empty the FIFO");
258		goto error;
259	}
260
261	w_ctr(ppc, ctr_sav);
262	w_ecr(ppc, ecr_sav);
263
264	return (0);
265
266error:
267	w_ctr(ppc, ctr_sav);
268	w_ecr(ppc, ecr_sav);
269
270	return (EINVAL);
271}
272
273static int
274ppc_detect_port(struct ppc_data *ppc)
275{
276
277	w_ctr(ppc, 0x0c);	/* To avoid missing PS2 ports */
278	w_dtr(ppc, 0xaa);
279	if (r_dtr(ppc) != 0xaa)
280		return (0);
281
282	return (1);
283}
284
285/*
286 * EPP timeout, according to the PC87332 manual
287 * Semantics of clearing EPP timeout bit.
288 * PC87332	- reading SPP_STR does it...
289 * SMC		- write 1 to EPP timeout bit			XXX
290 * Others	- (?) write 0 to EPP timeout bit
291 */
292static void
293ppc_reset_epp_timeout(struct ppc_data *ppc)
294{
295	register char r;
296
297	r = r_str(ppc);
298	w_str(ppc, r | 0x1);
299	w_str(ppc, r & 0xfe);
300
301	return;
302}
303
304static int
305ppc_check_epp_timeout(struct ppc_data *ppc)
306{
307	ppc_reset_epp_timeout(ppc);
308
309	return (!(r_str(ppc) & TIMEOUT));
310}
311
312/*
313 * Configure current operating mode
314 */
315static int
316ppc_generic_setmode(struct ppc_data *ppc, int mode)
317{
318	u_char ecr = 0;
319
320	/* check if mode is available */
321	if (mode && !(ppc->ppc_avm & mode))
322		return (EINVAL);
323
324	/* if ECP mode, configure ecr register */
325	if ((ppc->ppc_avm & PPB_ECP) || (ppc->ppc_dtm & PPB_ECP)) {
326		/* return to byte mode (keeping direction bit),
327		 * no interrupt, no DMA to be able to change to
328		 * ECP
329		 */
330		w_ecr(ppc, PPC_ECR_RESET);
331		ecr = PPC_DISABLE_INTR;
332
333		if (mode & PPB_EPP)
334			return (EINVAL);
335		else if (mode & PPB_ECP)
336			/* select ECP mode */
337			ecr |= PPC_ECR_ECP;
338		else if (mode & PPB_PS2)
339			/* select PS2 mode with ECP */
340			ecr |= PPC_ECR_PS2;
341		else
342			/* select COMPATIBLE/NIBBLE mode */
343			ecr |= PPC_ECR_STD;
344
345		w_ecr(ppc, ecr);
346	}
347
348	ppc->ppc_mode = mode;
349
350	return (0);
351}
352
353/*
354 * The ppc driver is free to choose options like FIFO or DMA
355 * if ECP mode is available.
356 *
357 * The 'RAW' option allows the upper drivers to force the ppc mode
358 * even with FIFO, DMA available.
359 */
360static int
361ppc_smclike_setmode(struct ppc_data *ppc, int mode)
362{
363	u_char ecr = 0;
364
365	/* check if mode is available */
366	if (mode && !(ppc->ppc_avm & mode))
367		return (EINVAL);
368
369	/* if ECP mode, configure ecr register */
370	if ((ppc->ppc_avm & PPB_ECP) || (ppc->ppc_dtm & PPB_ECP)) {
371		/* return to byte mode (keeping direction bit),
372		 * no interrupt, no DMA to be able to change to
373		 * ECP or EPP mode
374		 */
375		w_ecr(ppc, PPC_ECR_RESET);
376		ecr = PPC_DISABLE_INTR;
377
378		if (mode & PPB_EPP)
379			/* select EPP mode */
380			ecr |= PPC_ECR_EPP;
381		else if (mode & PPB_ECP)
382			/* select ECP mode */
383			ecr |= PPC_ECR_ECP;
384		else if (mode & PPB_PS2)
385			/* select PS2 mode with ECP */
386			ecr |= PPC_ECR_PS2;
387		else
388			/* select COMPATIBLE/NIBBLE mode */
389			ecr |= PPC_ECR_STD;
390
391		w_ecr(ppc, ecr);
392	}
393
394	ppc->ppc_mode = mode;
395
396	return (0);
397}
398
399#ifdef PPC_PROBE_CHIPSET
400/*
401 * ppc_pc873xx_detect
402 *
403 * Probe for a Natsemi PC873xx-family part.
404 *
405 * References in this function are to the National Semiconductor
406 * PC87332 datasheet TL/C/11930, May 1995 revision.
407 */
408static int pc873xx_basetab[] = {0x0398, 0x026e, 0x015c, 0x002e, 0};
409static int pc873xx_porttab[] = {0x0378, 0x03bc, 0x0278, 0};
410static int pc873xx_irqtab[] = {5, 7, 5, 0};
411
412static int pc873xx_regstab[] = {
413	PC873_FER, PC873_FAR, PC873_PTR,
414	PC873_FCR, PC873_PCR, PC873_PMC,
415	PC873_TUP, PC873_SID, PC873_PNP0,
416	PC873_PNP1, PC873_LPTBA, -1
417};
418
419static char *pc873xx_rnametab[] = {
420	"FER", "FAR", "PTR", "FCR", "PCR",
421	"PMC", "TUP", "SID", "PNP0", "PNP1",
422	"LPTBA", NULL
423};
424
425static int
426ppc_pc873xx_detect(struct ppc_data *ppc, int chipset_mode)	/* XXX mode never forced */
427{
428    static int	index = 0;
429    int		idport, irq;
430    int		ptr, pcr, val, i;
431
432    while ((idport = pc873xx_basetab[index++])) {
433
434	/* XXX should check first to see if this location is already claimed */
435
436	/*
437	 * Pull the 873xx through the power-on ID cycle (2.2,1.).
438	 * We can't use this to locate the chip as it may already have
439	 * been used by the BIOS.
440	 */
441	(void)inb(idport); (void)inb(idport);
442	(void)inb(idport); (void)inb(idport);
443
444	/*
445	 * Read the SID byte.  Possible values are :
446	 *
447	 * 01010xxx	PC87334
448	 * 0001xxxx	PC87332
449	 * 01110xxx	PC87306
450	 * 00110xxx	PC87303
451	 */
452	outb(idport, PC873_SID);
453	val = inb(idport + 1);
454	if ((val & 0xf0) == 0x10) {
455	    ppc->ppc_model = NS_PC87332;
456	} else if ((val & 0xf8) == 0x70) {
457	    ppc->ppc_model = NS_PC87306;
458	} else if ((val & 0xf8) == 0x50) {
459	    ppc->ppc_model = NS_PC87334;
460	} else if ((val & 0xf8) == 0x40) { /* Should be 0x30 by the
461					      documentation, but probing
462					      yielded 0x40... */
463	    ppc->ppc_model = NS_PC87303;
464	} else {
465	    if (bootverbose && (val != 0xff))
466		printf("PC873xx probe at 0x%x got unknown ID 0x%x\n", idport, val);
467	    continue ;		/* not recognised */
468	}
469
470	/* print registers */
471	if (bootverbose) {
472		printf("PC873xx");
473		for (i=0; pc873xx_regstab[i] != -1; i++) {
474			outb(idport, pc873xx_regstab[i]);
475			printf(" %s=0x%x", pc873xx_rnametab[i],
476						inb(idport + 1) & 0xff);
477		}
478		printf("\n");
479	}
480
481	/*
482	 * We think we have one.  Is it enabled and where we want it to be?
483	 */
484	outb(idport, PC873_FER);
485	val = inb(idport + 1);
486	if (!(val & PC873_PPENABLE)) {
487	    if (bootverbose)
488		printf("PC873xx parallel port disabled\n");
489	    continue;
490	}
491	outb(idport, PC873_FAR);
492	val = inb(idport + 1);
493	/* XXX we should create a driver instance for every port found */
494	if (pc873xx_porttab[val & 0x3] != ppc->ppc_base) {
495
496	    /* First try to change the port address to that requested... */
497
498	    switch (ppc->ppc_base) {
499		case 0x378:
500		val &= 0xfc;
501		break;
502
503		case 0x3bc:
504		val &= 0xfd;
505		break;
506
507		case 0x278:
508		val &= 0xfe;
509		break;
510
511		default:
512		val &= 0xfd;
513		break;
514	    }
515
516	    outb(idport, PC873_FAR);
517	    outb(idport + 1, val);
518	    outb(idport + 1, val);
519
520	    /* Check for success by reading back the value we supposedly
521	       wrote and comparing...*/
522
523	    outb(idport, PC873_FAR);
524	    val = inb(idport + 1) & 0x3;
525
526	    /* If we fail, report the failure... */
527
528	    if (pc873xx_porttab[val] != ppc->ppc_base) {
529 		if (bootverbose)
530	  	    printf("PC873xx at 0x%x not for driver at port 0x%x\n",
531			   pc873xx_porttab[val], ppc->ppc_base);
532	    }
533	    continue;
534	}
535
536	outb(idport, PC873_PTR);
537	ptr = inb(idport + 1);
538
539	/* get irq settings */
540	if (ppc->ppc_base == 0x378)
541		irq = (ptr & PC873_LPTBIRQ7) ? 7 : 5;
542	else
543		irq = pc873xx_irqtab[val];
544
545	if (bootverbose)
546		printf("PC873xx irq %d at 0x%x\n", irq, ppc->ppc_base);
547
548	/*
549	 * Check if irq settings are correct
550	 */
551	if (irq != ppc->ppc_irq) {
552		/*
553		 * If the chipset is not locked and base address is 0x378,
554		 * we have another chance
555		 */
556		if (ppc->ppc_base == 0x378 && !(ptr & PC873_CFGLOCK)) {
557			if (ppc->ppc_irq == 7) {
558				outb(idport + 1, (ptr | PC873_LPTBIRQ7));
559				outb(idport + 1, (ptr | PC873_LPTBIRQ7));
560			} else {
561				outb(idport + 1, (ptr & ~PC873_LPTBIRQ7));
562				outb(idport + 1, (ptr & ~PC873_LPTBIRQ7));
563			}
564			if (bootverbose)
565			   printf("PC873xx irq set to %d\n", ppc->ppc_irq);
566		} else {
567			if (bootverbose)
568			   printf("PC873xx sorry, can't change irq setting\n");
569		}
570	} else {
571		if (bootverbose)
572			printf("PC873xx irq settings are correct\n");
573	}
574
575	outb(idport, PC873_PCR);
576	pcr = inb(idport + 1);
577
578	if ((ptr & PC873_CFGLOCK) || !chipset_mode) {
579	    if (bootverbose)
580		printf("PC873xx %s", (ptr & PC873_CFGLOCK)?"locked":"unlocked");
581
582	    ppc->ppc_avm |= PPB_NIBBLE;
583	    if (bootverbose)
584		printf(", NIBBLE");
585
586	    if (pcr & PC873_EPPEN) {
587		ppc->ppc_avm |= PPB_EPP;
588
589		if (bootverbose)
590			printf(", EPP");
591
592		if (pcr & PC873_EPP19)
593			ppc->ppc_epp = EPP_1_9;
594		else
595			ppc->ppc_epp = EPP_1_7;
596
597		if ((ppc->ppc_model == NS_PC87332) && bootverbose) {
598			outb(idport, PC873_PTR);
599			ptr = inb(idport + 1);
600			if (ptr & PC873_EPPRDIR)
601				printf(", Regular mode");
602			else
603				printf(", Automatic mode");
604		}
605	    } else if (pcr & PC873_ECPEN) {
606		ppc->ppc_avm |= PPB_ECP;
607		if (bootverbose)
608			printf(", ECP");
609
610		if (pcr & PC873_ECPCLK)	{		/* XXX */
611			ppc->ppc_avm |= PPB_PS2;
612			if (bootverbose)
613				printf(", PS/2");
614		}
615	    } else {
616		outb(idport, PC873_PTR);
617		ptr = inb(idport + 1);
618		if (ptr & PC873_EXTENDED) {
619			ppc->ppc_avm |= PPB_SPP;
620			if (bootverbose)
621				printf(", SPP");
622		}
623	    }
624	} else {
625		if (bootverbose)
626			printf("PC873xx unlocked");
627
628		if (chipset_mode & PPB_ECP) {
629			if ((chipset_mode & PPB_EPP) && bootverbose)
630				printf(", ECP+EPP not supported");
631
632			pcr &= ~PC873_EPPEN;
633			pcr |= (PC873_ECPEN | PC873_ECPCLK);	/* XXX */
634			outb(idport + 1, pcr);
635			outb(idport + 1, pcr);
636
637			if (bootverbose)
638				printf(", ECP");
639
640		} else if (chipset_mode & PPB_EPP) {
641			pcr &= ~(PC873_ECPEN | PC873_ECPCLK);
642			pcr |= (PC873_EPPEN | PC873_EPP19);
643			outb(idport + 1, pcr);
644			outb(idport + 1, pcr);
645
646			ppc->ppc_epp = EPP_1_9;			/* XXX */
647
648			if (bootverbose)
649				printf(", EPP1.9");
650
651			/* enable automatic direction turnover */
652			if (ppc->ppc_model == NS_PC87332) {
653				outb(idport, PC873_PTR);
654				ptr = inb(idport + 1);
655				ptr &= ~PC873_EPPRDIR;
656				outb(idport + 1, ptr);
657				outb(idport + 1, ptr);
658
659				if (bootverbose)
660					printf(", Automatic mode");
661			}
662		} else {
663			pcr &= ~(PC873_ECPEN | PC873_ECPCLK | PC873_EPPEN);
664			outb(idport + 1, pcr);
665			outb(idport + 1, pcr);
666
667			/* configure extended bit in PTR */
668			outb(idport, PC873_PTR);
669			ptr = inb(idport + 1);
670
671			if (chipset_mode & PPB_PS2) {
672				ptr |= PC873_EXTENDED;
673
674				if (bootverbose)
675					printf(", PS/2");
676
677			} else {
678				/* default to NIBBLE mode */
679				ptr &= ~PC873_EXTENDED;
680
681				if (bootverbose)
682					printf(", NIBBLE");
683			}
684			outb(idport + 1, ptr);
685			outb(idport + 1, ptr);
686		}
687
688		ppc->ppc_avm = chipset_mode;
689	}
690
691	if (bootverbose)
692		printf("\n");
693
694	ppc->ppc_type = PPC_TYPE_GENERIC;
695	ppc_generic_setmode(ppc, chipset_mode);
696
697	return(chipset_mode);
698    }
699    return(-1);
700}
701
702/*
703 * ppc_smc37c66xgt_detect
704 *
705 * SMC FDC37C66xGT configuration.
706 */
707static int
708ppc_smc37c66xgt_detect(struct ppc_data *ppc, int chipset_mode)
709{
710	int i;
711	u_char r;
712	int type = -1;
713	int csr = SMC66x_CSR;	/* initial value is 0x3F0 */
714
715	int port_address[] = { -1 /* disabled */ , 0x3bc, 0x378, 0x278 };
716
717
718#define cio csr+1	/* config IO port is either 0x3F1 or 0x371 */
719
720	/*
721	 * Detection: enter configuration mode and read CRD register.
722	 */
723	PPC_CONFIG_LOCK(ppc);
724	outb(csr, SMC665_iCODE);
725	outb(csr, SMC665_iCODE);
726	PPC_CONFIG_UNLOCK(ppc);
727
728	outb(csr, 0xd);
729	if (inb(cio) == 0x65) {
730		type = SMC_37C665GT;
731		goto config;
732	}
733
734	for (i = 0; i < 2; i++) {
735		PPC_CONFIG_LOCK(ppc);
736		outb(csr, SMC666_iCODE);
737		outb(csr, SMC666_iCODE);
738		PPC_CONFIG_UNLOCK(ppc);
739
740		outb(csr, 0xd);
741		if (inb(cio) == 0x66) {
742			type = SMC_37C666GT;
743			break;
744		}
745
746		/* Another chance, CSR may be hard-configured to be at 0x370 */
747		csr = SMC666_CSR;
748	}
749
750config:
751	/*
752	 * If chipset not found, do not continue.
753	 */
754	if (type == -1) {
755		outb(csr, 0xaa);	/* end config mode */
756		return (-1);
757	}
758
759	/* select CR1 */
760	outb(csr, 0x1);
761
762	/* read the port's address: bits 0 and 1 of CR1 */
763	r = inb(cio) & SMC_CR1_ADDR;
764	if (port_address[(int)r] != ppc->ppc_base) {
765		outb(csr, 0xaa);	/* end config mode */
766		return (-1);
767	}
768
769	ppc->ppc_model = type;
770
771	/*
772	 * CR1 and CR4 registers bits 3 and 0/1 for mode configuration
773	 * If SPP mode is detected, try to set ECP+EPP mode
774	 */
775
776	if (bootverbose) {
777		outb(csr, 0x1);
778		device_printf(ppc->ppc_dev, "SMC registers CR1=0x%x",
779		    inb(cio) & 0xff);
780
781		outb(csr, 0x4);
782		printf(" CR4=0x%x", inb(cio) & 0xff);
783	}
784
785	/* select CR1 */
786	outb(csr, 0x1);
787
788	if (!chipset_mode) {
789		/* autodetect mode */
790
791		/* 666GT is ~certainly~ hardwired to an extended ECP+EPP mode */
792		if (type == SMC_37C666GT) {
793			ppc->ppc_avm |= PPB_ECP | PPB_EPP | PPB_SPP;
794			if (bootverbose)
795				printf(" configuration hardwired, supposing " \
796					"ECP+EPP SPP");
797
798		} else
799		   if ((inb(cio) & SMC_CR1_MODE) == 0) {
800			/* already in extended parallel port mode, read CR4 */
801			outb(csr, 0x4);
802			r = (inb(cio) & SMC_CR4_EMODE);
803
804			switch (r) {
805			case SMC_SPP:
806				ppc->ppc_avm |= PPB_SPP;
807				if (bootverbose)
808					printf(" SPP");
809				break;
810
811			case SMC_EPPSPP:
812				ppc->ppc_avm |= PPB_EPP | PPB_SPP;
813				if (bootverbose)
814					printf(" EPP SPP");
815				break;
816
817			case SMC_ECP:
818				ppc->ppc_avm |= PPB_ECP | PPB_SPP;
819				if (bootverbose)
820					printf(" ECP SPP");
821				break;
822
823			case SMC_ECPEPP:
824				ppc->ppc_avm |= PPB_ECP | PPB_EPP | PPB_SPP;
825				if (bootverbose)
826					printf(" ECP+EPP SPP");
827				break;
828			}
829		   } else {
830			/* not an extended port mode */
831			ppc->ppc_avm |= PPB_SPP;
832			if (bootverbose)
833				printf(" SPP");
834		   }
835
836	} else {
837		/* mode forced */
838		ppc->ppc_avm = chipset_mode;
839
840		/* 666GT is ~certainly~ hardwired to an extended ECP+EPP mode */
841		if (type == SMC_37C666GT)
842			goto end_detect;
843
844		r = inb(cio);
845		if ((chipset_mode & (PPB_ECP | PPB_EPP)) == 0) {
846			/* do not use ECP when the mode is not forced to */
847			outb(cio, r | SMC_CR1_MODE);
848			if (bootverbose)
849				printf(" SPP");
850		} else {
851			/* an extended mode is selected */
852			outb(cio, r & ~SMC_CR1_MODE);
853
854			/* read CR4 register and reset mode field */
855			outb(csr, 0x4);
856			r = inb(cio) & ~SMC_CR4_EMODE;
857
858			if (chipset_mode & PPB_ECP) {
859				if (chipset_mode & PPB_EPP) {
860					outb(cio, r | SMC_ECPEPP);
861					if (bootverbose)
862						printf(" ECP+EPP");
863				} else {
864					outb(cio, r | SMC_ECP);
865					if (bootverbose)
866						printf(" ECP");
867				}
868			} else {
869				/* PPB_EPP is set */
870				outb(cio, r | SMC_EPPSPP);
871				if (bootverbose)
872					printf(" EPP SPP");
873			}
874		}
875		ppc->ppc_avm = chipset_mode;
876	}
877
878	/* set FIFO threshold to 16 */
879	if (ppc->ppc_avm & PPB_ECP) {
880		/* select CRA */
881		outb(csr, 0xa);
882		outb(cio, 16);
883	}
884
885end_detect:
886
887	if (bootverbose)
888		printf ("\n");
889
890	if (ppc->ppc_avm & PPB_EPP) {
891		/* select CR4 */
892		outb(csr, 0x4);
893		r = inb(cio);
894
895		/*
896		 * Set the EPP protocol...
897		 * Low=EPP 1.9 (1284 standard) and High=EPP 1.7
898		 */
899		if (ppc->ppc_epp == EPP_1_9)
900			outb(cio, (r & ~SMC_CR4_EPPTYPE));
901		else
902			outb(cio, (r | SMC_CR4_EPPTYPE));
903	}
904
905	outb(csr, 0xaa);	/* end config mode */
906
907	ppc->ppc_type = PPC_TYPE_SMCLIKE;
908	ppc_smclike_setmode(ppc, chipset_mode);
909
910	return (chipset_mode);
911}
912
913/*
914 * SMC FDC37C935 configuration
915 * Found on many Alpha machines
916 */
917static int
918ppc_smc37c935_detect(struct ppc_data *ppc, int chipset_mode)
919{
920	int type = -1;
921
922	PPC_CONFIG_LOCK(ppc);
923	outb(SMC935_CFG, 0x55); /* enter config mode */
924	outb(SMC935_CFG, 0x55);
925	PPC_CONFIG_UNLOCK(ppc);
926
927	outb(SMC935_IND, SMC935_ID); /* check device id */
928	if (inb(SMC935_DAT) == 0x2)
929		type = SMC_37C935;
930
931	if (type == -1) {
932		outb(SMC935_CFG, 0xaa); /* exit config mode */
933		return (-1);
934	}
935
936	ppc->ppc_model = type;
937
938	outb(SMC935_IND, SMC935_LOGDEV); /* select parallel port, */
939	outb(SMC935_DAT, 3);	     /* which is logical device 3 */
940
941	/* set io port base */
942	outb(SMC935_IND, SMC935_PORTHI);
943	outb(SMC935_DAT, (u_char)((ppc->ppc_base & 0xff00) >> 8));
944	outb(SMC935_IND, SMC935_PORTLO);
945	outb(SMC935_DAT, (u_char)(ppc->ppc_base & 0xff));
946
947	if (!chipset_mode)
948		ppc->ppc_avm = PPB_COMPATIBLE; /* default mode */
949	else {
950		ppc->ppc_avm = chipset_mode;
951		outb(SMC935_IND, SMC935_PPMODE);
952		outb(SMC935_DAT, SMC935_CENT); /* start in compatible mode */
953
954		/* SPP + EPP or just plain SPP */
955		if (chipset_mode & (PPB_SPP)) {
956			if (chipset_mode & PPB_EPP) {
957				if (ppc->ppc_epp == EPP_1_9) {
958					outb(SMC935_IND, SMC935_PPMODE);
959					outb(SMC935_DAT, SMC935_EPP19SPP);
960				}
961				if (ppc->ppc_epp == EPP_1_7) {
962					outb(SMC935_IND, SMC935_PPMODE);
963					outb(SMC935_DAT, SMC935_EPP17SPP);
964				}
965			} else {
966				outb(SMC935_IND, SMC935_PPMODE);
967				outb(SMC935_DAT, SMC935_SPP);
968			}
969		}
970
971		/* ECP + EPP or just plain ECP */
972		if (chipset_mode & PPB_ECP) {
973			if (chipset_mode & PPB_EPP) {
974				if (ppc->ppc_epp == EPP_1_9) {
975					outb(SMC935_IND, SMC935_PPMODE);
976					outb(SMC935_DAT, SMC935_ECPEPP19);
977				}
978				if (ppc->ppc_epp == EPP_1_7) {
979					outb(SMC935_IND, SMC935_PPMODE);
980					outb(SMC935_DAT, SMC935_ECPEPP17);
981				}
982			} else {
983				outb(SMC935_IND, SMC935_PPMODE);
984				outb(SMC935_DAT, SMC935_ECP);
985			}
986		}
987	}
988
989	outb(SMC935_CFG, 0xaa); /* exit config mode */
990
991	ppc->ppc_type = PPC_TYPE_SMCLIKE;
992	ppc_smclike_setmode(ppc, chipset_mode);
993
994	return (chipset_mode);
995}
996
997/*
998 * Winbond W83877F stuff
999 *
1000 * EFER: extended function enable register
1001 * EFIR: extended function index register
1002 * EFDR: extended function data register
1003 */
1004#define efir ((efer == 0x250) ? 0x251 : 0x3f0)
1005#define efdr ((efer == 0x250) ? 0x252 : 0x3f1)
1006
1007static int w83877f_efers[] = { 0x250, 0x3f0, 0x3f0, 0x250 };
1008static int w83877f_keys[] = { 0x89, 0x86, 0x87, 0x88 };
1009static int w83877f_keyiter[] = { 1, 2, 2, 1 };
1010static int w83877f_hefs[] = { WINB_HEFERE, WINB_HEFRAS, WINB_HEFERE | WINB_HEFRAS, 0 };
1011
1012static int
1013ppc_w83877f_detect(struct ppc_data *ppc, int chipset_mode)
1014{
1015	int i, j, efer;
1016	unsigned char r, hefere, hefras;
1017
1018	for (i = 0; i < 4; i ++) {
1019		/* first try to enable configuration registers */
1020		efer = w83877f_efers[i];
1021
1022		/* write the key to the EFER */
1023		for (j = 0; j < w83877f_keyiter[i]; j ++)
1024			outb (efer, w83877f_keys[i]);
1025
1026		/* then check HEFERE and HEFRAS bits */
1027		outb (efir, 0x0c);
1028		hefere = inb(efdr) & WINB_HEFERE;
1029
1030		outb (efir, 0x16);
1031		hefras = inb(efdr) & WINB_HEFRAS;
1032
1033		/*
1034		 * HEFRAS	HEFERE
1035		 *   0		   1	write 89h to 250h (power-on default)
1036		 *   1		   0	write 86h twice to 3f0h
1037		 *   1		   1	write 87h twice to 3f0h
1038		 *   0		   0	write 88h to 250h
1039		 */
1040		if ((hefere | hefras) == w83877f_hefs[i])
1041			goto found;
1042	}
1043
1044	return (-1);	/* failed */
1045
1046found:
1047	/* check base port address - read from CR23 */
1048	outb(efir, 0x23);
1049	if (ppc->ppc_base != inb(efdr) * 4)		/* 4 bytes boundaries */
1050		return (-1);
1051
1052	/* read CHIP ID from CR9/bits0-3 */
1053	outb(efir, 0x9);
1054
1055	switch (inb(efdr) & WINB_CHIPID) {
1056		case WINB_W83877F_ID:
1057			ppc->ppc_model = WINB_W83877F;
1058			break;
1059
1060		case WINB_W83877AF_ID:
1061			ppc->ppc_model = WINB_W83877AF;
1062			break;
1063
1064		default:
1065			ppc->ppc_model = WINB_UNKNOWN;
1066	}
1067
1068	if (bootverbose) {
1069		/* dump of registers */
1070		device_printf(ppc->ppc_dev, "0x%x - ", w83877f_keys[i]);
1071		for (i = 0; i <= 0xd; i ++) {
1072			outb(efir, i);
1073			printf("0x%x ", inb(efdr));
1074		}
1075		for (i = 0x10; i <= 0x17; i ++) {
1076			outb(efir, i);
1077			printf("0x%x ", inb(efdr));
1078		}
1079		outb(efir, 0x1e);
1080		printf("0x%x ", inb(efdr));
1081		for (i = 0x20; i <= 0x29; i ++) {
1082			outb(efir, i);
1083			printf("0x%x ", inb(efdr));
1084		}
1085		printf("\n");
1086	}
1087
1088	ppc->ppc_type = PPC_TYPE_GENERIC;
1089
1090	if (!chipset_mode) {
1091		/* autodetect mode */
1092
1093		/* select CR0 */
1094		outb(efir, 0x0);
1095		r = inb(efdr) & (WINB_PRTMODS0 | WINB_PRTMODS1);
1096
1097		/* select CR9 */
1098		outb(efir, 0x9);
1099		r |= (inb(efdr) & WINB_PRTMODS2);
1100
1101		switch (r) {
1102		case WINB_W83757:
1103			if (bootverbose)
1104				device_printf(ppc->ppc_dev,
1105				    "W83757 compatible mode\n");
1106			return (-1);	/* generic or SMC-like */
1107
1108		case WINB_EXTFDC:
1109		case WINB_EXTADP:
1110		case WINB_EXT2FDD:
1111		case WINB_JOYSTICK:
1112			if (bootverbose)
1113				device_printf(ppc->ppc_dev,
1114				    "not in parallel port mode\n");
1115			return (-1);
1116
1117		case (WINB_PARALLEL | WINB_EPP_SPP):
1118			ppc->ppc_avm |= PPB_EPP | PPB_SPP;
1119			if (bootverbose)
1120				device_printf(ppc->ppc_dev, "EPP SPP\n");
1121			break;
1122
1123		case (WINB_PARALLEL | WINB_ECP):
1124			ppc->ppc_avm |= PPB_ECP | PPB_SPP;
1125			if (bootverbose)
1126				device_printf(ppc->ppc_dev, "ECP SPP\n");
1127			break;
1128
1129		case (WINB_PARALLEL | WINB_ECP_EPP):
1130			ppc->ppc_avm |= PPB_ECP | PPB_EPP | PPB_SPP;
1131			ppc->ppc_type = PPC_TYPE_SMCLIKE;
1132
1133			if (bootverbose)
1134				device_printf(ppc->ppc_dev, "ECP+EPP SPP\n");
1135			break;
1136		default:
1137			printf("%s: unknown case (0x%x)!\n", __func__, r);
1138		}
1139
1140	} else {
1141		/* mode forced */
1142
1143		/* select CR9 and set PRTMODS2 bit */
1144		outb(efir, 0x9);
1145		outb(efdr, inb(efdr) & ~WINB_PRTMODS2);
1146
1147		/* select CR0 and reset PRTMODSx bits */
1148		outb(efir, 0x0);
1149		outb(efdr, inb(efdr) & ~(WINB_PRTMODS0 | WINB_PRTMODS1));
1150
1151		if (chipset_mode & PPB_ECP) {
1152			if (chipset_mode & PPB_EPP) {
1153				outb(efdr, inb(efdr) | WINB_ECP_EPP);
1154				if (bootverbose)
1155					device_printf(ppc->ppc_dev,
1156					    "ECP+EPP\n");
1157
1158				ppc->ppc_type = PPC_TYPE_SMCLIKE;
1159
1160			} else {
1161				outb(efdr, inb(efdr) | WINB_ECP);
1162				if (bootverbose)
1163					device_printf(ppc->ppc_dev, "ECP\n");
1164			}
1165		} else {
1166			/* select EPP_SPP otherwise */
1167			outb(efdr, inb(efdr) | WINB_EPP_SPP);
1168			if (bootverbose)
1169				device_printf(ppc->ppc_dev, "EPP SPP\n");
1170		}
1171		ppc->ppc_avm = chipset_mode;
1172	}
1173
1174	/* exit configuration mode */
1175	outb(efer, 0xaa);
1176
1177	switch (ppc->ppc_type) {
1178	case PPC_TYPE_SMCLIKE:
1179		ppc_smclike_setmode(ppc, chipset_mode);
1180		break;
1181	default:
1182		ppc_generic_setmode(ppc, chipset_mode);
1183		break;
1184	}
1185
1186	return (chipset_mode);
1187}
1188#endif
1189
1190/*
1191 * ppc_generic_detect
1192 */
1193static int
1194ppc_generic_detect(struct ppc_data *ppc, int chipset_mode)
1195{
1196	/* default to generic */
1197	ppc->ppc_type = PPC_TYPE_GENERIC;
1198
1199	if (bootverbose)
1200		device_printf(ppc->ppc_dev, "SPP");
1201
1202	/* first, check for ECP */
1203	w_ecr(ppc, PPC_ECR_PS2);
1204	if ((r_ecr(ppc) & 0xe0) == PPC_ECR_PS2) {
1205		ppc->ppc_dtm |= PPB_ECP | PPB_SPP;
1206		if (bootverbose)
1207			printf(" ECP ");
1208
1209		/* search for SMC style ECP+EPP mode */
1210		w_ecr(ppc, PPC_ECR_EPP);
1211	}
1212
1213	/* try to reset EPP timeout bit */
1214	if (ppc_check_epp_timeout(ppc)) {
1215		ppc->ppc_dtm |= PPB_EPP;
1216
1217		if (ppc->ppc_dtm & PPB_ECP) {
1218			/* SMC like chipset found */
1219			ppc->ppc_model = SMC_LIKE;
1220			ppc->ppc_type = PPC_TYPE_SMCLIKE;
1221
1222			if (bootverbose)
1223				printf(" ECP+EPP");
1224		} else {
1225			if (bootverbose)
1226				printf(" EPP");
1227		}
1228	} else {
1229		/* restore to standard mode */
1230		w_ecr(ppc, PPC_ECR_STD);
1231	}
1232
1233	/* XXX try to detect NIBBLE and PS2 modes */
1234	ppc->ppc_dtm |= PPB_NIBBLE;
1235
1236	if (chipset_mode)
1237		ppc->ppc_avm = chipset_mode;
1238	else
1239		ppc->ppc_avm = ppc->ppc_dtm;
1240
1241	if (bootverbose)
1242		printf("\n");
1243
1244	switch (ppc->ppc_type) {
1245	case PPC_TYPE_SMCLIKE:
1246		ppc_smclike_setmode(ppc, chipset_mode);
1247		break;
1248	default:
1249		ppc_generic_setmode(ppc, chipset_mode);
1250		break;
1251	}
1252
1253	return (chipset_mode);
1254}
1255
1256/*
1257 * ppc_detect()
1258 *
1259 * mode is the mode suggested at boot
1260 */
1261static int
1262ppc_detect(struct ppc_data *ppc, int chipset_mode) {
1263
1264#ifdef PPC_PROBE_CHIPSET
1265	int i, mode;
1266
1267	/* list of supported chipsets */
1268	int (*chipset_detect[])(struct ppc_data *, int) = {
1269		ppc_pc873xx_detect,
1270		ppc_smc37c66xgt_detect,
1271		ppc_w83877f_detect,
1272		ppc_smc37c935_detect,
1273		ppc_generic_detect,
1274		NULL
1275	};
1276#endif
1277
1278	/* if can't find the port and mode not forced return error */
1279	if (!ppc_detect_port(ppc) && chipset_mode == 0)
1280		return (EIO);			/* failed, port not present */
1281
1282	/* assume centronics compatible mode is supported */
1283	ppc->ppc_avm = PPB_COMPATIBLE;
1284
1285#ifdef PPC_PROBE_CHIPSET
1286	/* we have to differenciate available chipset modes,
1287	 * chipset running modes and IEEE-1284 operating modes
1288	 *
1289	 * after detection, the port must support running in compatible mode
1290	 */
1291	if (ppc->ppc_flags & 0x40) {
1292		if (bootverbose)
1293			printf("ppc: chipset forced to generic\n");
1294#endif
1295
1296		ppc->ppc_mode = ppc_generic_detect(ppc, chipset_mode);
1297
1298#ifdef PPC_PROBE_CHIPSET
1299	} else {
1300		for (i=0; chipset_detect[i] != NULL; i++) {
1301			if ((mode = chipset_detect[i](ppc, chipset_mode)) != -1) {
1302				ppc->ppc_mode = mode;
1303				break;
1304			}
1305		}
1306	}
1307#endif
1308
1309	/* configure/detect ECP FIFO */
1310	if ((ppc->ppc_avm & PPB_ECP) && !(ppc->ppc_flags & 0x80))
1311		ppc_detect_fifo(ppc);
1312
1313	return (0);
1314}
1315
1316/*
1317 * ppc_exec_microseq()
1318 *
1319 * Execute a microsequence.
1320 * Microsequence mechanism is supposed to handle fast I/O operations.
1321 */
1322int
1323ppc_exec_microseq(device_t dev, struct ppb_microseq **p_msq)
1324{
1325	struct ppc_data *ppc = DEVTOSOFTC(dev);
1326	struct ppb_microseq *mi;
1327	char cc, *p;
1328	int i, iter, len;
1329	int error;
1330
1331	register int reg;
1332	register char mask;
1333	register int accum = 0;
1334	register char *ptr = NULL;
1335
1336	struct ppb_microseq *stack = NULL;
1337
1338/* microsequence registers are equivalent to PC-like port registers */
1339
1340#define r_reg(reg,ppc) (bus_read_1((ppc)->res_ioport, reg))
1341#define w_reg(reg, ppc, byte) (bus_write_1((ppc)->res_ioport, reg, byte))
1342
1343#define INCR_PC (mi ++)		/* increment program counter */
1344
1345	PPC_ASSERT_LOCKED(ppc);
1346	mi = *p_msq;
1347	for (;;) {
1348		switch (mi->opcode) {
1349		case MS_OP_RSET:
1350			cc = r_reg(mi->arg[0].i, ppc);
1351			cc &= (char)mi->arg[2].i;	/* clear mask */
1352			cc |= (char)mi->arg[1].i;	/* assert mask */
1353			w_reg(mi->arg[0].i, ppc, cc);
1354			INCR_PC;
1355			break;
1356
1357		case MS_OP_RASSERT_P:
1358			reg = mi->arg[1].i;
1359			ptr = ppc->ppc_ptr;
1360
1361			if ((len = mi->arg[0].i) == MS_ACCUM) {
1362				accum = ppc->ppc_accum;
1363				for (; accum; accum--)
1364					w_reg(reg, ppc, *ptr++);
1365				ppc->ppc_accum = accum;
1366			} else
1367				for (i=0; i<len; i++)
1368					w_reg(reg, ppc, *ptr++);
1369			ppc->ppc_ptr = ptr;
1370
1371			INCR_PC;
1372			break;
1373
1374		case MS_OP_RFETCH_P:
1375			reg = mi->arg[1].i;
1376			mask = (char)mi->arg[2].i;
1377			ptr = ppc->ppc_ptr;
1378
1379			if ((len = mi->arg[0].i) == MS_ACCUM) {
1380				accum = ppc->ppc_accum;
1381				for (; accum; accum--)
1382					*ptr++ = r_reg(reg, ppc) & mask;
1383				ppc->ppc_accum = accum;
1384			} else
1385				for (i=0; i<len; i++)
1386					*ptr++ = r_reg(reg, ppc) & mask;
1387			ppc->ppc_ptr = ptr;
1388
1389			INCR_PC;
1390			break;
1391
1392		case MS_OP_RFETCH:
1393			*((char *) mi->arg[2].p) = r_reg(mi->arg[0].i, ppc) &
1394							(char)mi->arg[1].i;
1395			INCR_PC;
1396			break;
1397
1398		case MS_OP_RASSERT:
1399		case MS_OP_DELAY:
1400
1401		/* let's suppose the next instr. is the same */
1402		prefetch:
1403			for (;mi->opcode == MS_OP_RASSERT; INCR_PC)
1404				w_reg(mi->arg[0].i, ppc, (char)mi->arg[1].i);
1405
1406			if (mi->opcode == MS_OP_DELAY) {
1407				DELAY(mi->arg[0].i);
1408				INCR_PC;
1409				goto prefetch;
1410			}
1411			break;
1412
1413		case MS_OP_ADELAY:
1414			if (mi->arg[0].i) {
1415				PPC_UNLOCK(ppc);
1416				pause("ppbdelay", mi->arg[0].i * (hz/1000));
1417				PPC_LOCK(ppc);
1418			}
1419			INCR_PC;
1420			break;
1421
1422		case MS_OP_TRIG:
1423			reg = mi->arg[0].i;
1424			iter = mi->arg[1].i;
1425			p = (char *)mi->arg[2].p;
1426
1427			/* XXX delay limited to 255 us */
1428			for (i=0; i<iter; i++) {
1429				w_reg(reg, ppc, *p++);
1430				DELAY((unsigned char)*p++);
1431			}
1432			INCR_PC;
1433			break;
1434
1435		case MS_OP_SET:
1436			ppc->ppc_accum = mi->arg[0].i;
1437			INCR_PC;
1438			break;
1439
1440		case MS_OP_DBRA:
1441			if (--ppc->ppc_accum > 0)
1442				mi += mi->arg[0].i;
1443			INCR_PC;
1444			break;
1445
1446		case MS_OP_BRSET:
1447			cc = r_str(ppc);
1448			if ((cc & (char)mi->arg[0].i) == (char)mi->arg[0].i)
1449				mi += mi->arg[1].i;
1450			INCR_PC;
1451			break;
1452
1453		case MS_OP_BRCLEAR:
1454			cc = r_str(ppc);
1455			if ((cc & (char)mi->arg[0].i) == 0)
1456				mi += mi->arg[1].i;
1457			INCR_PC;
1458			break;
1459
1460		case MS_OP_BRSTAT:
1461			cc = r_str(ppc);
1462			if ((cc & ((char)mi->arg[0].i | (char)mi->arg[1].i)) ==
1463							(char)mi->arg[0].i)
1464				mi += mi->arg[2].i;
1465			INCR_PC;
1466			break;
1467
1468		case MS_OP_C_CALL:
1469			/*
1470			 * If the C call returns !0 then end the microseq.
1471			 * The current state of ptr is passed to the C function
1472			 */
1473			if ((error = mi->arg[0].f(mi->arg[1].p, ppc->ppc_ptr)))
1474				return (error);
1475
1476			INCR_PC;
1477			break;
1478
1479		case MS_OP_PTR:
1480			ppc->ppc_ptr = (char *)mi->arg[0].p;
1481			INCR_PC;
1482			break;
1483
1484		case MS_OP_CALL:
1485			if (stack)
1486				panic("%s: too much calls", __func__);
1487
1488			if (mi->arg[0].p) {
1489				/* store the state of the actual
1490				 * microsequence
1491				 */
1492				stack = mi;
1493
1494				/* jump to the new microsequence */
1495				mi = (struct ppb_microseq *)mi->arg[0].p;
1496			} else
1497				INCR_PC;
1498
1499			break;
1500
1501		case MS_OP_SUBRET:
1502			/* retrieve microseq and pc state before the call */
1503			mi = stack;
1504
1505			/* reset the stack */
1506			stack = NULL;
1507
1508			/* XXX return code */
1509
1510			INCR_PC;
1511			break;
1512
1513		case MS_OP_PUT:
1514		case MS_OP_GET:
1515		case MS_OP_RET:
1516			/* can't return to ppb level during the execution
1517			 * of a submicrosequence */
1518			if (stack)
1519				panic("%s: can't return to ppb level",
1520								__func__);
1521
1522			/* update pc for ppb level of execution */
1523			*p_msq = mi;
1524
1525			/* return to ppb level of execution */
1526			return (0);
1527
1528		default:
1529			panic("%s: unknown microsequence opcode 0x%x",
1530			    __func__, mi->opcode);
1531		}
1532	}
1533
1534	/* unreached */
1535}
1536
1537static void
1538ppcintr(void *arg)
1539{
1540	struct ppc_data *ppc = arg;
1541	u_char ctr, ecr, str;
1542
1543	/*
1544	 * If we have any child interrupt handlers registered, let
1545	 * them handle this interrupt.
1546	 *
1547	 * XXX: If DMA is in progress should we just complete that w/o
1548	 * doing this?
1549	 */
1550	PPC_LOCK(ppc);
1551	if (ppc->ppc_intr_hook != NULL &&
1552	    ppc->ppc_intr_hook(ppc->ppc_intr_arg) == 0) {
1553		PPC_UNLOCK(ppc);
1554		return;
1555	}
1556
1557	str = r_str(ppc);
1558	ctr = r_ctr(ppc);
1559	ecr = r_ecr(ppc);
1560
1561#if defined(PPC_DEBUG) && PPC_DEBUG > 1
1562		printf("![%x/%x/%x]", ctr, ecr, str);
1563#endif
1564
1565	/* don't use ecp mode with IRQENABLE set */
1566	if (ctr & IRQENABLE) {
1567		PPC_UNLOCK(ppc);
1568		return;
1569	}
1570
1571	/* interrupts are generated by nFault signal
1572	 * only in ECP mode */
1573	if ((str & nFAULT) && (ppc->ppc_mode & PPB_ECP)) {
1574		/* check if ppc driver has programmed the
1575		 * nFault interrupt */
1576		if  (ppc->ppc_irqstat & PPC_IRQ_nFAULT) {
1577
1578			w_ecr(ppc, ecr | PPC_nFAULT_INTR);
1579			ppc->ppc_irqstat &= ~PPC_IRQ_nFAULT;
1580		} else {
1581			/* shall be handled by underlying layers XXX */
1582			PPC_UNLOCK(ppc);
1583			return;
1584		}
1585	}
1586
1587	if (ppc->ppc_irqstat & PPC_IRQ_DMA) {
1588		/* disable interrupts (should be done by hardware though) */
1589		w_ecr(ppc, ecr | PPC_SERVICE_INTR);
1590		ppc->ppc_irqstat &= ~PPC_IRQ_DMA;
1591		ecr = r_ecr(ppc);
1592
1593		/* check if DMA completed */
1594		if ((ppc->ppc_avm & PPB_ECP) && (ecr & PPC_ENABLE_DMA)) {
1595#ifdef PPC_DEBUG
1596			printf("a");
1597#endif
1598			/* stop DMA */
1599			w_ecr(ppc, ecr & ~PPC_ENABLE_DMA);
1600			ecr = r_ecr(ppc);
1601
1602			if (ppc->ppc_dmastat == PPC_DMA_STARTED) {
1603#ifdef PPC_DEBUG
1604				printf("d");
1605#endif
1606				ppc->ppc_dmadone(ppc);
1607				ppc->ppc_dmastat = PPC_DMA_COMPLETE;
1608
1609				/* wakeup the waiting process */
1610				wakeup(ppc);
1611			}
1612		}
1613	} else if (ppc->ppc_irqstat & PPC_IRQ_FIFO) {
1614
1615		/* classic interrupt I/O */
1616		ppc->ppc_irqstat &= ~PPC_IRQ_FIFO;
1617	}
1618	PPC_UNLOCK(ppc);
1619
1620	return;
1621}
1622
1623int
1624ppc_read(device_t dev, char *buf, int len, int mode)
1625{
1626	return (EINVAL);
1627}
1628
1629int
1630ppc_write(device_t dev, char *buf, int len, int how)
1631{
1632	return (EINVAL);
1633}
1634
1635int
1636ppc_reset_epp(device_t dev)
1637{
1638	struct ppc_data *ppc = DEVTOSOFTC(dev);
1639
1640	PPC_ASSERT_LOCKED(ppc);
1641	ppc_reset_epp_timeout(ppc);
1642
1643	return 0;
1644}
1645
1646int
1647ppc_setmode(device_t dev, int mode)
1648{
1649	struct ppc_data *ppc = DEVTOSOFTC(dev);
1650
1651	PPC_ASSERT_LOCKED(ppc);
1652	switch (ppc->ppc_type) {
1653	case PPC_TYPE_SMCLIKE:
1654		return (ppc_smclike_setmode(ppc, mode));
1655		break;
1656
1657	case PPC_TYPE_GENERIC:
1658	default:
1659		return (ppc_generic_setmode(ppc, mode));
1660		break;
1661	}
1662
1663	/* not reached */
1664	return (ENXIO);
1665}
1666
1667int
1668ppc_probe(device_t dev, int rid)
1669{
1670#ifdef __i386__
1671	static short next_bios_ppc = 0;
1672#ifdef PC98
1673	unsigned int pc98_ieee_mode = 0x00;
1674	unsigned int tmp;
1675#endif
1676#endif
1677	struct ppc_data *ppc;
1678	int error;
1679	rman_res_t port;
1680
1681	/*
1682	 * Allocate the ppc_data structure.
1683	 */
1684	ppc = DEVTOSOFTC(dev);
1685	bzero(ppc, sizeof(struct ppc_data));
1686
1687	ppc->rid_ioport = rid;
1688
1689	/* retrieve ISA parameters */
1690	error = bus_get_resource(dev, SYS_RES_IOPORT, rid, &port, NULL);
1691
1692#ifdef __i386__
1693	/*
1694	 * If port not specified, use bios list.
1695	 */
1696	if (error) {
1697#ifdef PC98
1698		if (next_bios_ppc == 0) {
1699			/* Use default IEEE-1284 port of NEC PC-98x1 */
1700			port = PC98_IEEE_1284_PORT;
1701			next_bios_ppc += 1;
1702			if (bootverbose)
1703				device_printf(dev,
1704				    "parallel port found at 0x%jx\n", port);
1705		}
1706#else
1707		if ((next_bios_ppc < BIOS_MAX_PPC) &&
1708		    (*(BIOS_PORTS + next_bios_ppc) != 0)) {
1709			port = *(BIOS_PORTS + next_bios_ppc++);
1710			if (bootverbose)
1711				device_printf(dev,
1712				    "parallel port found at 0x%jx\n", port);
1713		} else {
1714			device_printf(dev, "parallel port not found.\n");
1715			return (ENXIO);
1716		}
1717#endif	/* PC98 */
1718		bus_set_resource(dev, SYS_RES_IOPORT, rid, port,
1719				 IO_LPTSIZE_EXTENDED);
1720	}
1721#endif
1722
1723	/* IO port is mandatory */
1724
1725	/* Try "extended" IO port range...*/
1726	ppc->res_ioport = bus_alloc_resource_anywhere(dev, SYS_RES_IOPORT,
1727						      &ppc->rid_ioport,
1728						      IO_LPTSIZE_EXTENDED,
1729						      RF_ACTIVE);
1730
1731	if (ppc->res_ioport != 0) {
1732		if (bootverbose)
1733			device_printf(dev, "using extended I/O port range\n");
1734	} else {
1735		/* Failed? If so, then try the "normal" IO port range... */
1736		 ppc->res_ioport = bus_alloc_resource_anywhere(dev,
1737		 	 				       SYS_RES_IOPORT,
1738							       &ppc->rid_ioport,
1739							       IO_LPTSIZE_NORMAL,
1740							       RF_ACTIVE);
1741		if (ppc->res_ioport != 0) {
1742			if (bootverbose)
1743				device_printf(dev, "using normal I/O port range\n");
1744		} else {
1745			device_printf(dev, "cannot reserve I/O port range\n");
1746			goto error;
1747		}
1748	}
1749
1750 	ppc->ppc_base = rman_get_start(ppc->res_ioport);
1751
1752	ppc->ppc_flags = device_get_flags(dev);
1753
1754	if (!(ppc->ppc_flags & 0x20)) {
1755		ppc->res_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ,
1756						      &ppc->rid_irq,
1757						      RF_SHAREABLE);
1758		ppc->res_drq = bus_alloc_resource_any(dev, SYS_RES_DRQ,
1759						      &ppc->rid_drq,
1760						      RF_ACTIVE);
1761	}
1762
1763	if (ppc->res_irq)
1764		ppc->ppc_irq = rman_get_start(ppc->res_irq);
1765	if (ppc->res_drq)
1766		ppc->ppc_dmachan = rman_get_start(ppc->res_drq);
1767
1768	ppc->ppc_dev = dev;
1769	ppc->ppc_model = GENERIC;
1770
1771	ppc->ppc_mode = PPB_COMPATIBLE;
1772	ppc->ppc_epp = (ppc->ppc_flags & 0x10) >> 4;
1773
1774	ppc->ppc_type = PPC_TYPE_GENERIC;
1775
1776#if defined(__i386__) && defined(PC98)
1777	/*
1778	 * IEEE STD 1284 Function Check and Enable
1779	 * for default IEEE-1284 port of NEC PC-98x1
1780	 */
1781	if (ppc->ppc_base == PC98_IEEE_1284_PORT &&
1782	    !(ppc->ppc_flags & PC98_IEEE_1284_DISABLE)) {
1783		tmp = inb(ppc->ppc_base + PPC_1284_ENABLE);
1784		pc98_ieee_mode = tmp;
1785		if ((tmp & 0x10) == 0x10) {
1786			outb(ppc->ppc_base + PPC_1284_ENABLE, tmp & ~0x10);
1787			tmp = inb(ppc->ppc_base + PPC_1284_ENABLE);
1788			if ((tmp & 0x10) == 0x10)
1789				goto error;
1790		} else {
1791			outb(ppc->ppc_base + PPC_1284_ENABLE, tmp | 0x10);
1792			tmp = inb(ppc->ppc_base + PPC_1284_ENABLE);
1793			if ((tmp & 0x10) != 0x10)
1794				goto error;
1795		}
1796		outb(ppc->ppc_base + PPC_1284_ENABLE, pc98_ieee_mode | 0x10);
1797	}
1798#endif
1799
1800	/*
1801	 * Try to detect the chipset and its mode.
1802	 */
1803	if (ppc_detect(ppc, ppc->ppc_flags & 0xf))
1804		goto error;
1805
1806	return (0);
1807
1808error:
1809#if defined(__i386__) && defined(PC98)
1810	if (ppc->ppc_base == PC98_IEEE_1284_PORT &&
1811	    !(ppc->ppc_flags & PC98_IEEE_1284_DISABLE)) {
1812		outb(ppc->ppc_base + PPC_1284_ENABLE, pc98_ieee_mode);
1813	}
1814#endif
1815	if (ppc->res_irq != 0) {
1816		bus_release_resource(dev, SYS_RES_IRQ, ppc->rid_irq,
1817				     ppc->res_irq);
1818	}
1819	if (ppc->res_ioport != 0) {
1820		bus_release_resource(dev, SYS_RES_IOPORT, ppc->rid_ioport,
1821				     ppc->res_ioport);
1822	}
1823	if (ppc->res_drq != 0) {
1824		bus_release_resource(dev, SYS_RES_DRQ, ppc->rid_drq,
1825				     ppc->res_drq);
1826	}
1827	return (ENXIO);
1828}
1829
1830int
1831ppc_attach(device_t dev)
1832{
1833	struct ppc_data *ppc = DEVTOSOFTC(dev);
1834	int error;
1835
1836	mtx_init(&ppc->ppc_lock, device_get_nameunit(dev), "ppc", MTX_DEF);
1837
1838	device_printf(dev, "%s chipset (%s) in %s mode%s\n",
1839		      ppc_models[ppc->ppc_model], ppc_avms[ppc->ppc_avm],
1840		      ppc_modes[ppc->ppc_mode], (PPB_IS_EPP(ppc->ppc_mode)) ?
1841		      ppc_epp_protocol[ppc->ppc_epp] : "");
1842
1843	if (ppc->ppc_fifo)
1844		device_printf(dev, "FIFO with %d/%d/%d bytes threshold\n",
1845			      ppc->ppc_fifo, ppc->ppc_wthr, ppc->ppc_rthr);
1846
1847	if (ppc->res_irq) {
1848		/* default to the tty mask for registration */	/* XXX */
1849		error = bus_setup_intr(dev, ppc->res_irq, INTR_TYPE_TTY |
1850		    INTR_MPSAFE, NULL, ppcintr, ppc, &ppc->intr_cookie);
1851		if (error) {
1852			device_printf(dev,
1853			    "failed to register interrupt handler: %d\n",
1854			    error);
1855			mtx_destroy(&ppc->ppc_lock);
1856			return (error);
1857		}
1858	}
1859
1860	/* add ppbus as a child of this isa to parallel bridge */
1861	ppc->ppbus = device_add_child(dev, "ppbus", -1);
1862
1863	/*
1864	 * Probe the ppbus and attach devices found.
1865	 */
1866	device_probe_and_attach(ppc->ppbus);
1867
1868	return (0);
1869}
1870
1871int
1872ppc_detach(device_t dev)
1873{
1874	struct ppc_data *ppc = DEVTOSOFTC(dev);
1875
1876	if (ppc->res_irq == 0) {
1877		return (ENXIO);
1878	}
1879
1880	/* detach & delete all children */
1881	device_delete_children(dev);
1882
1883	if (ppc->res_irq != 0) {
1884		bus_teardown_intr(dev, ppc->res_irq, ppc->intr_cookie);
1885		bus_release_resource(dev, SYS_RES_IRQ, ppc->rid_irq,
1886				     ppc->res_irq);
1887	}
1888	if (ppc->res_ioport != 0) {
1889		bus_release_resource(dev, SYS_RES_IOPORT, ppc->rid_ioport,
1890				     ppc->res_ioport);
1891	}
1892	if (ppc->res_drq != 0) {
1893		bus_release_resource(dev, SYS_RES_DRQ, ppc->rid_drq,
1894				     ppc->res_drq);
1895	}
1896
1897	mtx_destroy(&ppc->ppc_lock);
1898
1899	return (0);
1900}
1901
1902u_char
1903ppc_io(device_t ppcdev, int iop, u_char *addr, int cnt, u_char byte)
1904{
1905	struct ppc_data *ppc = DEVTOSOFTC(ppcdev);
1906
1907	PPC_ASSERT_LOCKED(ppc);
1908	switch (iop) {
1909	case PPB_OUTSB_EPP:
1910	    bus_write_multi_1(ppc->res_ioport, PPC_EPP_DATA, addr, cnt);
1911		break;
1912	case PPB_OUTSW_EPP:
1913	    bus_write_multi_2(ppc->res_ioport, PPC_EPP_DATA, (u_int16_t *)addr, cnt);
1914		break;
1915	case PPB_OUTSL_EPP:
1916	    bus_write_multi_4(ppc->res_ioport, PPC_EPP_DATA, (u_int32_t *)addr, cnt);
1917		break;
1918	case PPB_INSB_EPP:
1919	    bus_read_multi_1(ppc->res_ioport, PPC_EPP_DATA, addr, cnt);
1920		break;
1921	case PPB_INSW_EPP:
1922	    bus_read_multi_2(ppc->res_ioport, PPC_EPP_DATA, (u_int16_t *)addr, cnt);
1923		break;
1924	case PPB_INSL_EPP:
1925	    bus_read_multi_4(ppc->res_ioport, PPC_EPP_DATA, (u_int32_t *)addr, cnt);
1926		break;
1927	case PPB_RDTR:
1928		return (r_dtr(ppc));
1929	case PPB_RSTR:
1930		return (r_str(ppc));
1931	case PPB_RCTR:
1932		return (r_ctr(ppc));
1933	case PPB_REPP_A:
1934		return (r_epp_A(ppc));
1935	case PPB_REPP_D:
1936		return (r_epp_D(ppc));
1937	case PPB_RECR:
1938		return (r_ecr(ppc));
1939	case PPB_RFIFO:
1940		return (r_fifo(ppc));
1941	case PPB_WDTR:
1942		w_dtr(ppc, byte);
1943		break;
1944	case PPB_WSTR:
1945		w_str(ppc, byte);
1946		break;
1947	case PPB_WCTR:
1948		w_ctr(ppc, byte);
1949		break;
1950	case PPB_WEPP_A:
1951		w_epp_A(ppc, byte);
1952		break;
1953	case PPB_WEPP_D:
1954		w_epp_D(ppc, byte);
1955		break;
1956	case PPB_WECR:
1957		w_ecr(ppc, byte);
1958		break;
1959	case PPB_WFIFO:
1960		w_fifo(ppc, byte);
1961		break;
1962	default:
1963		panic("%s: unknown I/O operation", __func__);
1964		break;
1965	}
1966
1967	return (0);	/* not significative */
1968}
1969
1970int
1971ppc_read_ivar(device_t bus, device_t dev, int index, uintptr_t *val)
1972{
1973	struct ppc_data *ppc = (struct ppc_data *)device_get_softc(bus);
1974
1975	switch (index) {
1976	case PPC_IVAR_EPP_PROTO:
1977		PPC_ASSERT_LOCKED(ppc);
1978		*val = (u_long)ppc->ppc_epp;
1979		break;
1980	case PPC_IVAR_LOCK:
1981		*val = (uintptr_t)&ppc->ppc_lock;
1982		break;
1983	default:
1984		return (ENOENT);
1985	}
1986
1987	return (0);
1988}
1989
1990int
1991ppc_write_ivar(device_t bus, device_t dev, int index, uintptr_t val)
1992{
1993	struct ppc_data *ppc = (struct ppc_data *)device_get_softc(bus);
1994
1995	switch (index) {
1996	case PPC_IVAR_INTR_HANDLER:
1997		PPC_ASSERT_LOCKED(ppc);
1998		if (dev != ppc->ppbus)
1999			return (EINVAL);
2000		if (val == 0) {
2001			ppc->ppc_intr_hook = NULL;
2002			break;
2003		}
2004		if (ppc->ppc_intr_hook != NULL)
2005			return (EBUSY);
2006		ppc->ppc_intr_hook = (void *)val;
2007		ppc->ppc_intr_arg = device_get_softc(dev);
2008		break;
2009	default:
2010		return (ENOENT);
2011	}
2012
2013	return (0);
2014}
2015
2016/*
2017 * We allow child devices to allocate an IRQ resource at rid 0 for their
2018 * interrupt handlers.
2019 */
2020struct resource *
2021ppc_alloc_resource(device_t bus, device_t child, int type, int *rid,
2022    rman_res_t start, rman_res_t end, rman_res_t count, u_int flags)
2023{
2024	struct ppc_data *ppc = DEVTOSOFTC(bus);
2025
2026	switch (type) {
2027	case SYS_RES_IRQ:
2028		if (*rid == 0)
2029			return (ppc->res_irq);
2030		break;
2031	}
2032	return (NULL);
2033}
2034
2035int
2036ppc_release_resource(device_t bus, device_t child, int type, int rid,
2037    struct resource *r)
2038{
2039#ifdef INVARIANTS
2040	struct ppc_data *ppc = DEVTOSOFTC(bus);
2041#endif
2042
2043	switch (type) {
2044	case SYS_RES_IRQ:
2045		if (rid == 0) {
2046			KASSERT(r == ppc->res_irq,
2047			    ("ppc child IRQ resource mismatch"));
2048			return (0);
2049		}
2050		break;
2051	}
2052	return (EINVAL);
2053}
2054
2055MODULE_DEPEND(ppc, ppbus, 1, 1, 1);
2056