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