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