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