Deleted Added
full compact
ppc.c (50477) ppc.c (55939)
1/*-
1/*-
2 * Copyright (c) 1997, 1998 Nicolas Souchu
2 * Copyright (c) 1997-2000 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

--- 7 unchanged lines hidden (view full) ---

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 *
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

--- 7 unchanged lines hidden (view full) ---

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: head/sys/dev/ppc/ppc.c 50477 1999-08-28 01:08:13Z peter $
26 * $FreeBSD: head/sys/dev/ppc/ppc.c 55939 2000-01-14 00:18:06Z nsouch $
27 *
28 */
29#include "ppc.h"
30
31#if NPPC > 0
32
27 *
28 */
29#include "ppc.h"
30
31#if NPPC > 0
32
33#include "opt_ppc.h"
34
33#include <sys/param.h>
34#include <sys/systm.h>
35#include <sys/param.h>
36#include <sys/systm.h>
35#include <sys/conf.h>
36#include <sys/malloc.h>
37#include <sys/kernel.h>
37#include <sys/kernel.h>
38
39#include <machine/clock.h>
40
38#include <sys/bus.h>
39#include <sys/malloc.h>
40
41#include <vm/vm.h>
41#include <vm/vm.h>
42#include <vm/vm_param.h>
43#include <vm/pmap.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>
44
48
45#include <i386/isa/isa_device.h>
46#include <i386/isa/isa.h>
49#include <isa/isareg.h>
50#include <isa/isavar.h>
47
48#include <dev/ppbus/ppbconf.h>
49#include <dev/ppbus/ppb_msq.h>
50
51#include <i386/isa/ppcreg.h>
52
51
52#include <dev/ppbus/ppbconf.h>
53#include <dev/ppbus/ppb_msq.h>
54
55#include <i386/isa/ppcreg.h>
56
53#include "opt_ppc.h"
57#include "ppbus_if.h"
54
55#define LOG_PPC(function, ppc, string) \
56 if (bootverbose) printf("%s: %s\n", function, string)
57
58
59#define LOG_PPC(function, ppc, string) \
60 if (bootverbose) printf("%s: %s\n", function, string)
61
58static int ppcprobe(struct isa_device *);
59static int ppcattach(struct isa_device *);
60
62
61struct isa_driver ppcdriver = {
62 ppcprobe, ppcattach, "ppc"
63};
63#define DEVTOSOFTC(dev) ((struct ppc_data *)device_get_softc(dev))
64
65devclass_t ppc_devclass;
64
66
65static struct ppc_data *ppcdata[NPPC];
66static int nppc = 0;
67static int ppc_probe(device_t dev);
68static int ppc_attach(device_t dev);
69static int ppc_read_ivar(device_t bus, device_t dev, int index, uintptr_t *val);
67
70
68static char *ppc_types[] = {
71static void ppc_reset_epp(device_t);
72static void ppc_ecp_sync(device_t);
73static void ppcintr(void *arg);
74
75static int ppc_exec_microseq(device_t, struct ppb_microseq **);
76static int ppc_setmode(device_t, int);
77
78static int ppc_read(device_t, char *, int, int);
79static int ppc_write(device_t, char *, int, int);
80
81static u_char ppc_io(device_t, int, u_char *, int, u_char);
82
83static int ppc_setup_intr(device_t, device_t, struct resource *, int,
84 void (*)(void *), void *, void **);
85static int ppc_teardown_intr(device_t, device_t, struct resource *, void *);
86
87static device_method_t ppc_methods[] = {
88 /* device interface */
89 DEVMETHOD(device_probe, ppc_probe),
90 DEVMETHOD(device_attach, ppc_attach),
91
92 /* bus interface */
93 DEVMETHOD(bus_read_ivar, ppc_read_ivar),
94 DEVMETHOD(bus_setup_intr, ppc_setup_intr),
95 DEVMETHOD(bus_teardown_intr, ppc_teardown_intr),
96 DEVMETHOD(bus_alloc_resource, bus_generic_alloc_resource),
97
98 /* ppbus interface */
99 DEVMETHOD(ppbus_io, ppc_io),
100 DEVMETHOD(ppbus_exec_microseq, ppc_exec_microseq),
101 DEVMETHOD(ppbus_reset_epp, ppc_reset_epp),
102 DEVMETHOD(ppbus_setmode, ppc_setmode),
103 DEVMETHOD(ppbus_ecp_sync, ppc_ecp_sync),
104 DEVMETHOD(ppbus_read, ppc_read),
105 DEVMETHOD(ppbus_write, ppc_write),
106
107 { 0, 0 }
108 };
109
110static driver_t ppc_driver = {
111 "ppc",
112 ppc_methods,
113 sizeof(struct ppc_data),
114};
115
116static char *ppc_models[] = {
69 "SMC-like", "SMC FDC37C665GT", "SMC FDC37C666GT", "PC87332", "PC87306",
70 "82091AA", "Generic", "W83877F", "W83877AF", "Winbond", "PC87334", 0
71};
72
73/* list of available modes */
74static char *ppc_avms[] = {
75 "COMPATIBLE", "NIBBLE-only", "PS2-only", "PS2/NIBBLE", "EPP-only",
76 "EPP/NIBBLE", "EPP/PS2", "EPP/PS2/NIBBLE", "ECP-only",

--- 16 unchanged lines hidden (view full) ---

93/*
94 * BIOS printer list - used by BIOS probe.
95 */
96#define BIOS_PPC_PORTS 0x408
97#define BIOS_PORTS (short *)(KERNBASE+BIOS_PPC_PORTS)
98#define BIOS_MAX_PPC 4
99
100/*
117 "SMC-like", "SMC FDC37C665GT", "SMC FDC37C666GT", "PC87332", "PC87306",
118 "82091AA", "Generic", "W83877F", "W83877AF", "Winbond", "PC87334", 0
119};
120
121/* list of available modes */
122static char *ppc_avms[] = {
123 "COMPATIBLE", "NIBBLE-only", "PS2-only", "PS2/NIBBLE", "EPP-only",
124 "EPP/NIBBLE", "EPP/PS2", "EPP/PS2/NIBBLE", "ECP-only",

--- 16 unchanged lines hidden (view full) ---

141/*
142 * BIOS printer list - used by BIOS probe.
143 */
144#define BIOS_PPC_PORTS 0x408
145#define BIOS_PORTS (short *)(KERNBASE+BIOS_PPC_PORTS)
146#define BIOS_MAX_PPC 4
147
148/*
101 * All these functions are default actions for IN/OUT operations.
102 * They may be redefined if needed.
103 */
104static void ppc_outsb_epp(int unit, char *addr, int cnt) {
105 outsb(ppcdata[unit]->ppc_base + PPC_EPP_DATA, addr, cnt); }
106static void ppc_outsw_epp(int unit, char *addr, int cnt) {
107 outsw(ppcdata[unit]->ppc_base + PPC_EPP_DATA, addr, cnt); }
108static void ppc_outsl_epp(int unit, char *addr, int cnt) {
109 outsl(ppcdata[unit]->ppc_base + PPC_EPP_DATA, addr, cnt); }
110static void ppc_insb_epp(int unit, char *addr, int cnt) {
111 insb(ppcdata[unit]->ppc_base + PPC_EPP_DATA, addr, cnt); }
112static void ppc_insw_epp(int unit, char *addr, int cnt) {
113 insw(ppcdata[unit]->ppc_base + PPC_EPP_DATA, addr, cnt); }
114static void ppc_insl_epp(int unit, char *addr, int cnt) {
115 insl(ppcdata[unit]->ppc_base + PPC_EPP_DATA, addr, cnt); }
116
117static u_char ppc_rdtr(int unit) { return r_dtr(ppcdata[unit]); }
118static u_char ppc_rstr(int unit) { return r_str(ppcdata[unit]); }
119static u_char ppc_rctr(int unit) { return r_ctr(ppcdata[unit]); }
120static u_char ppc_repp_A(int unit) { return r_epp_A(ppcdata[unit]); }
121static u_char ppc_repp_D(int unit) { return r_epp_D(ppcdata[unit]); }
122static u_char ppc_recr(int unit) { return r_ecr(ppcdata[unit]); }
123static u_char ppc_rfifo(int unit) { return r_fifo(ppcdata[unit]); }
124
125static void ppc_wdtr(int unit, char byte) { w_dtr(ppcdata[unit], byte); }
126static void ppc_wstr(int unit, char byte) { w_str(ppcdata[unit], byte); }
127static void ppc_wctr(int unit, char byte) { w_ctr(ppcdata[unit], byte); }
128static void ppc_wepp_A(int unit, char byte) { w_epp_A(ppcdata[unit], byte); }
129static void ppc_wepp_D(int unit, char byte) { w_epp_D(ppcdata[unit], byte); }
130static void ppc_wecr(int unit, char byte) { w_ecr(ppcdata[unit], byte); }
131static void ppc_wfifo(int unit, char byte) { w_fifo(ppcdata[unit], byte); }
132
133static void ppc_reset_epp_timeout(int);
134static void ppc_ecp_sync(int);
135static ointhand2_t ppcintr;
136
137static int ppc_exec_microseq(int, struct ppb_microseq **);
138static int ppc_generic_setmode(int, int);
139static int ppc_smclike_setmode(int, int);
140
141static int ppc_read(int, char *, int, int);
142static int ppc_write(int, char *, int, int);
143
144static struct ppb_adapter ppc_smclike_adapter = {
145
146 0, /* no intr handler, filled by chipset dependent code */
147
148 ppc_reset_epp_timeout, ppc_ecp_sync,
149
150 ppc_exec_microseq,
151
152 ppc_smclike_setmode, ppc_read, ppc_write,
153
154 ppc_outsb_epp, ppc_outsw_epp, ppc_outsl_epp,
155 ppc_insb_epp, ppc_insw_epp, ppc_insl_epp,
156
157 ppc_rdtr, ppc_rstr, ppc_rctr, ppc_repp_A, ppc_repp_D, ppc_recr, ppc_rfifo,
158 ppc_wdtr, ppc_wstr, ppc_wctr, ppc_wepp_A, ppc_wepp_D, ppc_wecr, ppc_wfifo
159};
160
161static struct ppb_adapter ppc_generic_adapter = {
162
163 0, /* no intr handler, filled by chipset dependent code */
164
165 ppc_reset_epp_timeout, ppc_ecp_sync,
166
167 ppc_exec_microseq,
168
169 ppc_generic_setmode, ppc_read, ppc_write,
170
171 ppc_outsb_epp, ppc_outsw_epp, ppc_outsl_epp,
172 ppc_insb_epp, ppc_insw_epp, ppc_insl_epp,
173
174 ppc_rdtr, ppc_rstr, ppc_rctr, ppc_repp_A, ppc_repp_D, ppc_recr, ppc_rfifo,
175 ppc_wdtr, ppc_wstr, ppc_wctr, ppc_wepp_A, ppc_wepp_D, ppc_wecr, ppc_wfifo
176};
177
178/*
179 * ppc_ecp_sync() XXX
180 */
181static void
149 * ppc_ecp_sync() XXX
150 */
151static void
182ppc_ecp_sync(int unit) {
152ppc_ecp_sync(device_t dev) {
183
153
184 struct ppc_data *ppc = ppcdata[unit];
185 int i, r;
154 int i, r;
155 struct ppc_data *ppc = DEVTOSOFTC(dev);
186
187 if (!(ppc->ppc_avm & PPB_ECP))
188 return;
189
190 r = r_ecr(ppc);
191 if ((r & 0xe0) != PPC_ECR_EPP)
192 return;
193
194 for (i = 0; i < 100; i++) {
195 r = r_ecr(ppc);
196 if (r & 0x1)
197 return;
198 DELAY(100);
199 }
200
201 printf("ppc%d: ECP sync failed as data still " \
156
157 if (!(ppc->ppc_avm & PPB_ECP))
158 return;
159
160 r = r_ecr(ppc);
161 if ((r & 0xe0) != PPC_ECR_EPP)
162 return;
163
164 for (i = 0; i < 100; i++) {
165 r = r_ecr(ppc);
166 if (r & 0x1)
167 return;
168 DELAY(100);
169 }
170
171 printf("ppc%d: ECP sync failed as data still " \
202 "present in FIFO.\n", unit);
172 "present in FIFO.\n", ppc->ppc_unit);
203
204 return;
205}
206
207/*
208 * ppc_detect_fifo()
209 *
210 * Detect parallel port FIFO

--- 112 unchanged lines hidden (view full) ---

323 w_dtr(ppc, 0xaa);
324 if (r_dtr(ppc) != 0xaa)
325 return (0);
326
327 return (1);
328}
329
330/*
173
174 return;
175}
176
177/*
178 * ppc_detect_fifo()
179 *
180 * Detect parallel port FIFO

--- 112 unchanged lines hidden (view full) ---

293 w_dtr(ppc, 0xaa);
294 if (r_dtr(ppc) != 0xaa)
295 return (0);
296
297 return (1);
298}
299
300/*
301 * EPP timeout, according to the PC87332 manual
302 * Semantics of clearing EPP timeout bit.
303 * PC87332 - reading SPP_STR does it...
304 * SMC - write 1 to EPP timeout bit XXX
305 * Others - (?) write 0 to EPP timeout bit
306 */
307static void
308ppc_reset_epp_timeout(struct ppc_data *ppc)
309{
310 register char r;
311
312 r = r_str(ppc);
313 w_str(ppc, r | 0x1);
314 w_str(ppc, r & 0xfe);
315
316 return;
317}
318
319static int
320ppc_check_epp_timeout(struct ppc_data *ppc)
321{
322 ppc_reset_epp_timeout(ppc);
323
324 return (!(r_str(ppc) & TIMEOUT));
325}
326
327/*
328 * Configure current operating mode
329 */
330static int
331ppc_generic_setmode(struct ppc_data *ppc, int mode)
332{
333 u_char ecr = 0;
334
335 /* check if mode is available */
336 if (mode && !(ppc->ppc_avm & mode))
337 return (EINVAL);
338
339 /* if ECP mode, configure ecr register */
340 if (ppc->ppc_avm & PPB_ECP) {
341 /* return to byte mode (keeping direction bit),
342 * no interrupt, no DMA to be able to change to
343 * ECP
344 */
345 w_ecr(ppc, PPC_ECR_RESET);
346 ecr = PPC_DISABLE_INTR;
347
348 if (mode & PPB_EPP)
349 return (EINVAL);
350 else if (mode & PPB_ECP)
351 /* select ECP mode */
352 ecr |= PPC_ECR_ECP;
353 else if (mode & PPB_PS2)
354 /* select PS2 mode with ECP */
355 ecr |= PPC_ECR_PS2;
356 else
357 /* select COMPATIBLE/NIBBLE mode */
358 ecr |= PPC_ECR_STD;
359
360 w_ecr(ppc, ecr);
361 }
362
363 ppc->ppc_mode = mode;
364
365 return (0);
366}
367
368/*
369 * The ppc driver is free to choose options like FIFO or DMA
370 * if ECP mode is available.
371 *
372 * The 'RAW' option allows the upper drivers to force the ppc mode
373 * even with FIFO, DMA available.
374 */
375static int
376ppc_smclike_setmode(struct ppc_data *ppc, int mode)
377{
378 u_char ecr = 0;
379
380 /* check if mode is available */
381 if (mode && !(ppc->ppc_avm & mode))
382 return (EINVAL);
383
384 /* if ECP mode, configure ecr register */
385 if (ppc->ppc_avm & PPB_ECP) {
386 /* return to byte mode (keeping direction bit),
387 * no interrupt, no DMA to be able to change to
388 * ECP or EPP mode
389 */
390 w_ecr(ppc, PPC_ECR_RESET);
391 ecr = PPC_DISABLE_INTR;
392
393 if (mode & PPB_EPP)
394 /* select EPP mode */
395 ecr |= PPC_ECR_EPP;
396 else if (mode & PPB_ECP)
397 /* select ECP mode */
398 ecr |= PPC_ECR_ECP;
399 else if (mode & PPB_PS2)
400 /* select PS2 mode with ECP */
401 ecr |= PPC_ECR_PS2;
402 else
403 /* select COMPATIBLE/NIBBLE mode */
404 ecr |= PPC_ECR_STD;
405
406 w_ecr(ppc, ecr);
407 }
408
409 ppc->ppc_mode = mode;
410
411 return (0);
412}
413
414#ifdef PPC_PROBE_CHIPSET
415/*
331 * ppc_pc873xx_detect
332 *
333 * Probe for a Natsemi PC873xx-family part.
334 *
335 * References in this function are to the National Semiconductor
336 * PC87332 datasheet TL/C/11930, May 1995 revision.
337 */
338static int pc873xx_basetab[] = {0x0398, 0x026e, 0x015c, 0x002e, 0};

--- 37 unchanged lines hidden (view full) ---

376 *
377 * 01010xxx PC87334
378 * 0001xxxx PC87332
379 * 01110xxx PC87306
380 */
381 outb(idport, PC873_SID);
382 val = inb(idport + 1);
383 if ((val & 0xf0) == 0x10) {
416 * ppc_pc873xx_detect
417 *
418 * Probe for a Natsemi PC873xx-family part.
419 *
420 * References in this function are to the National Semiconductor
421 * PC87332 datasheet TL/C/11930, May 1995 revision.
422 */
423static int pc873xx_basetab[] = {0x0398, 0x026e, 0x015c, 0x002e, 0};

--- 37 unchanged lines hidden (view full) ---

461 *
462 * 01010xxx PC87334
463 * 0001xxxx PC87332
464 * 01110xxx PC87306
465 */
466 outb(idport, PC873_SID);
467 val = inb(idport + 1);
468 if ((val & 0xf0) == 0x10) {
384 ppc->ppc_type = NS_PC87332;
469 ppc->ppc_model = NS_PC87332;
385 } else if ((val & 0xf8) == 0x70) {
470 } else if ((val & 0xf8) == 0x70) {
386 ppc->ppc_type = NS_PC87306;
471 ppc->ppc_model = NS_PC87306;
387 } else if ((val & 0xf8) == 0x50) {
472 } else if ((val & 0xf8) == 0x50) {
388 ppc->ppc_type = NS_PC87334;
473 ppc->ppc_model = NS_PC87334;
389 } else {
390 if (bootverbose && (val != 0xff))
391 printf("PC873xx probe at 0x%x got unknown ID 0x%x\n", idport, val);
392 continue ; /* not recognised */
393 }
394
395 /* print registers */
396 if (bootverbose) {

--- 82 unchanged lines hidden (view full) ---

479 if (bootverbose)
480 printf(", EPP");
481
482 if (pcr & PC873_EPP19)
483 ppc->ppc_epp = EPP_1_9;
484 else
485 ppc->ppc_epp = EPP_1_7;
486
474 } else {
475 if (bootverbose && (val != 0xff))
476 printf("PC873xx probe at 0x%x got unknown ID 0x%x\n", idport, val);
477 continue ; /* not recognised */
478 }
479
480 /* print registers */
481 if (bootverbose) {

--- 82 unchanged lines hidden (view full) ---

564 if (bootverbose)
565 printf(", EPP");
566
567 if (pcr & PC873_EPP19)
568 ppc->ppc_epp = EPP_1_9;
569 else
570 ppc->ppc_epp = EPP_1_7;
571
487 if ((ppc->ppc_type == NS_PC87332) && bootverbose) {
572 if ((ppc->ppc_model == NS_PC87332) && bootverbose) {
488 outb(idport, PC873_PTR);
489 ptr = inb(idport + 1);
490 if (ptr & PC873_EPPRDIR)
491 printf(", Regular mode");
492 else
493 printf(", Automatic mode");
494 }
495 } else if (pcr & PC873_ECPEN) {

--- 38 unchanged lines hidden (view full) ---

534 outb(idport + 1, pcr);
535
536 ppc->ppc_epp = EPP_1_9; /* XXX */
537
538 if (bootverbose)
539 printf(", EPP1.9");
540
541 /* enable automatic direction turnover */
573 outb(idport, PC873_PTR);
574 ptr = inb(idport + 1);
575 if (ptr & PC873_EPPRDIR)
576 printf(", Regular mode");
577 else
578 printf(", Automatic mode");
579 }
580 } else if (pcr & PC873_ECPEN) {

--- 38 unchanged lines hidden (view full) ---

619 outb(idport + 1, pcr);
620
621 ppc->ppc_epp = EPP_1_9; /* XXX */
622
623 if (bootverbose)
624 printf(", EPP1.9");
625
626 /* enable automatic direction turnover */
542 if (ppc->ppc_type == NS_PC87332) {
627 if (ppc->ppc_model == NS_PC87332) {
543 outb(idport, PC873_PTR);
544 ptr = inb(idport + 1);
545 ptr &= ~PC873_EPPRDIR;
546 outb(idport + 1, ptr);
547 outb(idport + 1, ptr);
548
549 if (bootverbose)
550 printf(", Automatic mode");

--- 25 unchanged lines hidden (view full) ---

576 }
577
578 ppc->ppc_avm = chipset_mode;
579 }
580
581 if (bootverbose)
582 printf("\n");
583
628 outb(idport, PC873_PTR);
629 ptr = inb(idport + 1);
630 ptr &= ~PC873_EPPRDIR;
631 outb(idport + 1, ptr);
632 outb(idport + 1, ptr);
633
634 if (bootverbose)
635 printf(", Automatic mode");

--- 25 unchanged lines hidden (view full) ---

661 }
662
663 ppc->ppc_avm = chipset_mode;
664 }
665
666 if (bootverbose)
667 printf("\n");
668
584 ppc->ppc_link.adapter = &ppc_generic_adapter;
585 ppc_generic_setmode(ppc->ppc_unit, chipset_mode);
669 ppc->ppc_type = PPC_TYPE_GENERIC;
670 ppc_generic_setmode(ppc, chipset_mode);
586
587 return(chipset_mode);
588 }
589 return(-1);
590}
591
671
672 return(chipset_mode);
673 }
674 return(-1);
675}
676
592static int
593ppc_check_epp_timeout(struct ppc_data *ppc)
594{
595 ppc_reset_epp_timeout(ppc->ppc_unit);
596
597 return (!(r_str(ppc) & TIMEOUT));
598}
599
600/*
601 * ppc_smc37c66xgt_detect
602 *
603 * SMC FDC37C66xGT configuration.
604 */
605static int
606ppc_smc37c66xgt_detect(struct ppc_data *ppc, int chipset_mode)
607{

--- 48 unchanged lines hidden (view full) ---

656 /* select CR1 */
657 outb(csr, 0x1);
658
659 /* read the port's address: bits 0 and 1 of CR1 */
660 r = inb(cio) & SMC_CR1_ADDR;
661 if (port_address[(int)r] != ppc->ppc_base)
662 return (-1);
663
677/*
678 * ppc_smc37c66xgt_detect
679 *
680 * SMC FDC37C66xGT configuration.
681 */
682static int
683ppc_smc37c66xgt_detect(struct ppc_data *ppc, int chipset_mode)
684{

--- 48 unchanged lines hidden (view full) ---

733 /* select CR1 */
734 outb(csr, 0x1);
735
736 /* read the port's address: bits 0 and 1 of CR1 */
737 r = inb(cio) & SMC_CR1_ADDR;
738 if (port_address[(int)r] != ppc->ppc_base)
739 return (-1);
740
664 ppc->ppc_type = type;
741 ppc->ppc_model = type;
665
666 /*
667 * CR1 and CR4 registers bits 3 and 0/1 for mode configuration
668 * If SPP mode is detected, try to set ECP+EPP mode
669 */
670
671 if (bootverbose) {
672 outb(csr, 0x1);

--- 122 unchanged lines hidden (view full) ---

795 outb(cio, (r & ~SMC_CR4_EPPTYPE));
796 else
797 outb(cio, (r | SMC_CR4_EPPTYPE));
798 }
799
800 /* end config mode */
801 outb(csr, 0xaa);
802
742
743 /*
744 * CR1 and CR4 registers bits 3 and 0/1 for mode configuration
745 * If SPP mode is detected, try to set ECP+EPP mode
746 */
747
748 if (bootverbose) {
749 outb(csr, 0x1);

--- 122 unchanged lines hidden (view full) ---

872 outb(cio, (r & ~SMC_CR4_EPPTYPE));
873 else
874 outb(cio, (r | SMC_CR4_EPPTYPE));
875 }
876
877 /* end config mode */
878 outb(csr, 0xaa);
879
803 ppc->ppc_link.adapter = &ppc_smclike_adapter;
804 ppc_smclike_setmode(ppc->ppc_unit, chipset_mode);
880 ppc->ppc_type = PPC_TYPE_SMCLIKE;
881 ppc_smclike_setmode(ppc, chipset_mode);
805
806 return (chipset_mode);
807}
808
809/*
810 * Winbond W83877F stuff
811 *
812 * EFER: extended function enable register

--- 48 unchanged lines hidden (view full) ---

861 if (ppc->ppc_base != inb(efdr) * 4) /* 4 bytes boundaries */
862 return (-1);
863
864 /* read CHIP ID from CR9/bits0-3 */
865 outb(efir, 0x9);
866
867 switch (inb(efdr) & WINB_CHIPID) {
868 case WINB_W83877F_ID:
882
883 return (chipset_mode);
884}
885
886/*
887 * Winbond W83877F stuff
888 *
889 * EFER: extended function enable register

--- 48 unchanged lines hidden (view full) ---

938 if (ppc->ppc_base != inb(efdr) * 4) /* 4 bytes boundaries */
939 return (-1);
940
941 /* read CHIP ID from CR9/bits0-3 */
942 outb(efir, 0x9);
943
944 switch (inb(efdr) & WINB_CHIPID) {
945 case WINB_W83877F_ID:
869 ppc->ppc_type = WINB_W83877F;
946 ppc->ppc_model = WINB_W83877F;
870 break;
871
872 case WINB_W83877AF_ID:
947 break;
948
949 case WINB_W83877AF_ID:
873 ppc->ppc_type = WINB_W83877AF;
950 ppc->ppc_model = WINB_W83877AF;
874 break;
875
876 default:
951 break;
952
953 default:
877 ppc->ppc_type = WINB_UNKNOWN;
954 ppc->ppc_model = WINB_UNKNOWN;
878 }
879
880 if (bootverbose) {
881 /* dump of registers */
882 printf("ppc%d: 0x%x - ", ppc->ppc_unit, w83877f_keys[i]);
883 for (i = 0; i <= 0xd; i ++) {
884 outb(efir, i);
885 printf("0x%x ", inb(efdr));

--- 7 unchanged lines hidden (view full) ---

893 for (i = 0x20; i <= 0x29; i ++) {
894 outb(efir, i);
895 printf("0x%x ", inb(efdr));
896 }
897 printf("\n");
898 printf("ppc%d:", ppc->ppc_unit);
899 }
900
955 }
956
957 if (bootverbose) {
958 /* dump of registers */
959 printf("ppc%d: 0x%x - ", ppc->ppc_unit, w83877f_keys[i]);
960 for (i = 0; i <= 0xd; i ++) {
961 outb(efir, i);
962 printf("0x%x ", inb(efdr));

--- 7 unchanged lines hidden (view full) ---

970 for (i = 0x20; i <= 0x29; i ++) {
971 outb(efir, i);
972 printf("0x%x ", inb(efdr));
973 }
974 printf("\n");
975 printf("ppc%d:", ppc->ppc_unit);
976 }
977
901 ppc->ppc_link.adapter = &ppc_generic_adapter;
978 ppc->ppc_type = PPC_TYPE_GENERIC;
902
903 if (!chipset_mode) {
904 /* autodetect mode */
905
906 /* select CR0 */
907 outb(efir, 0x0);
908 r = inb(efdr) & (WINB_PRTMODS0 | WINB_PRTMODS1);
909

--- 25 unchanged lines hidden (view full) ---

935 case (WINB_PARALLEL | WINB_ECP):
936 ppc->ppc_avm |= PPB_ECP | PPB_SPP;
937 if (bootverbose)
938 printf(" ECP SPP");
939 break;
940
941 case (WINB_PARALLEL | WINB_ECP_EPP):
942 ppc->ppc_avm |= PPB_ECP | PPB_EPP | PPB_SPP;
979
980 if (!chipset_mode) {
981 /* autodetect mode */
982
983 /* select CR0 */
984 outb(efir, 0x0);
985 r = inb(efdr) & (WINB_PRTMODS0 | WINB_PRTMODS1);
986

--- 25 unchanged lines hidden (view full) ---

1012 case (WINB_PARALLEL | WINB_ECP):
1013 ppc->ppc_avm |= PPB_ECP | PPB_SPP;
1014 if (bootverbose)
1015 printf(" ECP SPP");
1016 break;
1017
1018 case (WINB_PARALLEL | WINB_ECP_EPP):
1019 ppc->ppc_avm |= PPB_ECP | PPB_EPP | PPB_SPP;
943 ppc->ppc_link.adapter = &ppc_smclike_adapter;
1020 ppc->ppc_type = PPC_TYPE_SMCLIKE;
944
945 if (bootverbose)
946 printf(" ECP+EPP SPP");
947 break;
948 default:
949 printf("%s: unknown case (0x%x)!\n", __FUNCTION__, r);
950 }
951

--- 9 unchanged lines hidden (view full) ---

961 outb(efdr, inb(efdr) & ~(WINB_PRTMODS0 | WINB_PRTMODS1));
962
963 if (chipset_mode & PPB_ECP) {
964 if (chipset_mode & PPB_EPP) {
965 outb(efdr, inb(efdr) | WINB_ECP_EPP);
966 if (bootverbose)
967 printf(" ECP+EPP");
968
1021
1022 if (bootverbose)
1023 printf(" ECP+EPP SPP");
1024 break;
1025 default:
1026 printf("%s: unknown case (0x%x)!\n", __FUNCTION__, r);
1027 }
1028

--- 9 unchanged lines hidden (view full) ---

1038 outb(efdr, inb(efdr) & ~(WINB_PRTMODS0 | WINB_PRTMODS1));
1039
1040 if (chipset_mode & PPB_ECP) {
1041 if (chipset_mode & PPB_EPP) {
1042 outb(efdr, inb(efdr) | WINB_ECP_EPP);
1043 if (bootverbose)
1044 printf(" ECP+EPP");
1045
969 ppc->ppc_link.adapter = &ppc_smclike_adapter;
1046 ppc->ppc_type = PPC_TYPE_SMCLIKE;
970
971 } else {
972 outb(efdr, inb(efdr) | WINB_ECP);
973 if (bootverbose)
974 printf(" ECP");
975 }
976 } else {
977 /* select EPP_SPP otherwise */

--- 5 unchanged lines hidden (view full) ---

983 }
984
985 if (bootverbose)
986 printf("\n");
987
988 /* exit configuration mode */
989 outb(efer, 0xaa);
990
1047
1048 } else {
1049 outb(efdr, inb(efdr) | WINB_ECP);
1050 if (bootverbose)
1051 printf(" ECP");
1052 }
1053 } else {
1054 /* select EPP_SPP otherwise */

--- 5 unchanged lines hidden (view full) ---

1060 }
1061
1062 if (bootverbose)
1063 printf("\n");
1064
1065 /* exit configuration mode */
1066 outb(efer, 0xaa);
1067
991 ppc->ppc_link.adapter->setmode(ppc->ppc_unit, chipset_mode);
1068 switch (ppc->ppc_type) {
1069 case PPC_TYPE_SMCLIKE:
1070 ppc_smclike_setmode(ppc, chipset_mode);
1071 break;
1072 default:
1073 ppc_generic_setmode(ppc, chipset_mode);
1074 break;
1075 }
992
993 return (chipset_mode);
994}
1076
1077 return (chipset_mode);
1078}
1079#endif
995
996/*
997 * ppc_generic_detect
998 */
999static int
1000ppc_generic_detect(struct ppc_data *ppc, int chipset_mode)
1001{
1002 /* default to generic */
1080
1081/*
1082 * ppc_generic_detect
1083 */
1084static int
1085ppc_generic_detect(struct ppc_data *ppc, int chipset_mode)
1086{
1087 /* default to generic */
1003 ppc->ppc_link.adapter = &ppc_generic_adapter;
1088 ppc->ppc_type = PPC_TYPE_GENERIC;
1004
1005 if (bootverbose)
1006 printf("ppc%d:", ppc->ppc_unit);
1007
1008 if (!chipset_mode) {
1009 /* first, check for ECP */
1010 w_ecr(ppc, PPC_ECR_PS2);
1011 if ((r_ecr(ppc) & 0xe0) == PPC_ECR_PS2) {

--- 6 unchanged lines hidden (view full) ---

1018 }
1019
1020 /* try to reset EPP timeout bit */
1021 if (ppc_check_epp_timeout(ppc)) {
1022 ppc->ppc_avm |= PPB_EPP;
1023
1024 if (ppc->ppc_avm & PPB_ECP) {
1025 /* SMC like chipset found */
1089
1090 if (bootverbose)
1091 printf("ppc%d:", ppc->ppc_unit);
1092
1093 if (!chipset_mode) {
1094 /* first, check for ECP */
1095 w_ecr(ppc, PPC_ECR_PS2);
1096 if ((r_ecr(ppc) & 0xe0) == PPC_ECR_PS2) {

--- 6 unchanged lines hidden (view full) ---

1103 }
1104
1105 /* try to reset EPP timeout bit */
1106 if (ppc_check_epp_timeout(ppc)) {
1107 ppc->ppc_avm |= PPB_EPP;
1108
1109 if (ppc->ppc_avm & PPB_ECP) {
1110 /* SMC like chipset found */
1026 ppc->ppc_type = SMC_LIKE;
1027 ppc->ppc_link.adapter = &ppc_smclike_adapter;
1111 ppc->ppc_model = SMC_LIKE;
1112 ppc->ppc_type = PPC_TYPE_SMCLIKE;
1028
1029 if (bootverbose)
1030 printf(" ECP+EPP");
1031 } else {
1032 if (bootverbose)
1033 printf(" EPP");
1034 }
1035 } else {

--- 9 unchanged lines hidden (view full) ---

1045
1046 } else {
1047 ppc->ppc_avm = chipset_mode;
1048 }
1049
1050 if (bootverbose)
1051 printf("\n");
1052
1113
1114 if (bootverbose)
1115 printf(" ECP+EPP");
1116 } else {
1117 if (bootverbose)
1118 printf(" EPP");
1119 }
1120 } else {

--- 9 unchanged lines hidden (view full) ---

1130
1131 } else {
1132 ppc->ppc_avm = chipset_mode;
1133 }
1134
1135 if (bootverbose)
1136 printf("\n");
1137
1053 ppc->ppc_link.adapter->setmode(ppc->ppc_unit, chipset_mode);
1138 switch (ppc->ppc_type) {
1139 case PPC_TYPE_SMCLIKE:
1140 ppc_smclike_setmode(ppc, chipset_mode);
1141 break;
1142 default:
1143 ppc_generic_setmode(ppc, chipset_mode);
1144 break;
1145 }
1054
1055 return (chipset_mode);
1056}
1057
1058/*
1059 * ppc_detect()
1060 *
1061 * mode is the mode suggested at boot
1062 */
1063static int
1064ppc_detect(struct ppc_data *ppc, int chipset_mode) {
1065
1146
1147 return (chipset_mode);
1148}
1149
1150/*
1151 * ppc_detect()
1152 *
1153 * mode is the mode suggested at boot
1154 */
1155static int
1156ppc_detect(struct ppc_data *ppc, int chipset_mode) {
1157
1158#ifdef PPC_PROBE_CHIPSET
1066 int i, mode;
1067
1068 /* list of supported chipsets */
1069 int (*chipset_detect[])(struct ppc_data *, int) = {
1070 ppc_pc873xx_detect,
1071 ppc_smc37c66xgt_detect,
1072 ppc_w83877f_detect,
1073 ppc_generic_detect,
1074 NULL
1075 };
1159 int i, mode;
1160
1161 /* list of supported chipsets */
1162 int (*chipset_detect[])(struct ppc_data *, int) = {
1163 ppc_pc873xx_detect,
1164 ppc_smc37c66xgt_detect,
1165 ppc_w83877f_detect,
1166 ppc_generic_detect,
1167 NULL
1168 };
1169#endif
1076
1077 /* if can't find the port and mode not forced return error */
1078 if (!ppc_detect_port(ppc) && chipset_mode == 0)
1079 return (EIO); /* failed, port not present */
1080
1081 /* assume centronics compatible mode is supported */
1082 ppc->ppc_avm = PPB_COMPATIBLE;
1083
1170
1171 /* if can't find the port and mode not forced return error */
1172 if (!ppc_detect_port(ppc) && chipset_mode == 0)
1173 return (EIO); /* failed, port not present */
1174
1175 /* assume centronics compatible mode is supported */
1176 ppc->ppc_avm = PPB_COMPATIBLE;
1177
1178#ifdef PPC_PROBE_CHIPSET
1084 /* we have to differenciate available chipset modes,
1085 * chipset running modes and IEEE-1284 operating modes
1086 *
1087 * after detection, the port must support running in compatible mode
1088 */
1089 if (ppc->ppc_flags & 0x40) {
1090 if (bootverbose)
1091 printf("ppc: chipset forced to generic\n");
1179 /* we have to differenciate available chipset modes,
1180 * chipset running modes and IEEE-1284 operating modes
1181 *
1182 * after detection, the port must support running in compatible mode
1183 */
1184 if (ppc->ppc_flags & 0x40) {
1185 if (bootverbose)
1186 printf("ppc: chipset forced to generic\n");
1187#endif
1092
1093 ppc->ppc_mode = ppc_generic_detect(ppc, chipset_mode);
1094
1188
1189 ppc->ppc_mode = ppc_generic_detect(ppc, chipset_mode);
1190
1191#ifdef PPC_PROBE_CHIPSET
1095 } else {
1096 for (i=0; chipset_detect[i] != NULL; i++) {
1097 if ((mode = chipset_detect[i](ppc, chipset_mode)) != -1) {
1098 ppc->ppc_mode = mode;
1099 break;
1100 }
1101 }
1102 }
1192 } else {
1193 for (i=0; chipset_detect[i] != NULL; i++) {
1194 if ((mode = chipset_detect[i](ppc, chipset_mode)) != -1) {
1195 ppc->ppc_mode = mode;
1196 break;
1197 }
1198 }
1199 }
1200#endif
1103
1104 /* configure/detect ECP FIFO */
1105 if ((ppc->ppc_avm & PPB_ECP) && !(ppc->ppc_flags & 0x80))
1106 ppc_detect_fifo(ppc);
1107
1108 return (0);
1109}
1110
1111/*
1112 * ppc_exec_microseq()
1113 *
1114 * Execute a microsequence.
1115 * Microsequence mechanism is supposed to handle fast I/O operations.
1116 */
1117static int
1201
1202 /* configure/detect ECP FIFO */
1203 if ((ppc->ppc_avm & PPB_ECP) && !(ppc->ppc_flags & 0x80))
1204 ppc_detect_fifo(ppc);
1205
1206 return (0);
1207}
1208
1209/*
1210 * ppc_exec_microseq()
1211 *
1212 * Execute a microsequence.
1213 * Microsequence mechanism is supposed to handle fast I/O operations.
1214 */
1215static int
1118ppc_exec_microseq(int unit, struct ppb_microseq **p_msq)
1216ppc_exec_microseq(device_t dev, struct ppb_microseq **p_msq)
1119{
1217{
1120 struct ppc_data *ppc = ppcdata[unit];
1218 struct ppc_data *ppc = DEVTOSOFTC(dev);
1121 struct ppb_microseq *mi;
1122 char cc, *p;
1123 int i, iter, len;
1124 int error;
1125
1126 register int reg;
1127 register char mask;
1128 register int accum = 0;

--- 192 unchanged lines hidden (view full) ---

1321 __FUNCTION__, mi->opcode);
1322 }
1323 }
1324
1325 /* unreached */
1326}
1327
1328static void
1219 struct ppb_microseq *mi;
1220 char cc, *p;
1221 int i, iter, len;
1222 int error;
1223
1224 register int reg;
1225 register char mask;
1226 register int accum = 0;

--- 192 unchanged lines hidden (view full) ---

1419 __FUNCTION__, mi->opcode);
1420 }
1421 }
1422
1423 /* unreached */
1424}
1425
1426static void
1329ppcintr(int unit)
1427ppcintr(void *arg)
1330{
1428{
1331 struct ppc_data *ppc = ppcdata[unit];
1429 device_t dev = (device_t)arg;
1430 struct ppc_data *ppc = (struct ppc_data *)device_get_softc(dev);
1332 u_char ctr, ecr, str;
1333
1334 str = r_str(ppc);
1335 ctr = r_ctr(ppc);
1336 ecr = r_ecr(ppc);
1337
1338#if PPC_DEBUG > 1
1339 printf("![%x/%x/%x]", ctr, ecr, str);
1340#endif
1341
1342 /* don't use ecp mode with IRQENABLE set */
1343 if (ctr & IRQENABLE) {
1431 u_char ctr, ecr, str;
1432
1433 str = r_str(ppc);
1434 ctr = r_ctr(ppc);
1435 ecr = r_ecr(ppc);
1436
1437#if PPC_DEBUG > 1
1438 printf("![%x/%x/%x]", ctr, ecr, str);
1439#endif
1440
1441 /* don't use ecp mode with IRQENABLE set */
1442 if (ctr & IRQENABLE) {
1344 /* call upper code */
1345 ppb_intr(&ppc->ppc_link);
1346 return;
1347 }
1348
1349 /* interrupts are generated by nFault signal
1350 * only in ECP mode */
1351 if ((str & nFAULT) && (ppc->ppc_mode & PPB_ECP)) {
1352 /* check if ppc driver has programmed the
1353 * nFault interrupt */
1354 if (ppc->ppc_irqstat & PPC_IRQ_nFAULT) {
1355
1356 w_ecr(ppc, ecr | PPC_nFAULT_INTR);
1357 ppc->ppc_irqstat &= ~PPC_IRQ_nFAULT;
1358 } else {
1443 return;
1444 }
1445
1446 /* interrupts are generated by nFault signal
1447 * only in ECP mode */
1448 if ((str & nFAULT) && (ppc->ppc_mode & PPB_ECP)) {
1449 /* check if ppc driver has programmed the
1450 * nFault interrupt */
1451 if (ppc->ppc_irqstat & PPC_IRQ_nFAULT) {
1452
1453 w_ecr(ppc, ecr | PPC_nFAULT_INTR);
1454 ppc->ppc_irqstat &= ~PPC_IRQ_nFAULT;
1455 } else {
1359 /* call upper code */
1360 ppb_intr(&ppc->ppc_link);
1456 /* shall be handled by underlying layers XXX */
1361 return;
1362 }
1363 }
1364
1365 if (ppc->ppc_irqstat & PPC_IRQ_DMA) {
1366 /* disable interrupts (should be done by hardware though) */
1367 w_ecr(ppc, ecr | PPC_SERVICE_INTR);
1368 ppc->ppc_irqstat &= ~PPC_IRQ_DMA;

--- 23 unchanged lines hidden (view full) ---

1392 /* wakeup the waiting process */
1393 wakeup((caddr_t)ppc);
1394 }
1395 }
1396 } else if (ppc->ppc_irqstat & PPC_IRQ_FIFO) {
1397
1398 /* classic interrupt I/O */
1399 ppc->ppc_irqstat &= ~PPC_IRQ_FIFO;
1457 return;
1458 }
1459 }
1460
1461 if (ppc->ppc_irqstat & PPC_IRQ_DMA) {
1462 /* disable interrupts (should be done by hardware though) */
1463 w_ecr(ppc, ecr | PPC_SERVICE_INTR);
1464 ppc->ppc_irqstat &= ~PPC_IRQ_DMA;

--- 23 unchanged lines hidden (view full) ---

1488 /* wakeup the waiting process */
1489 wakeup((caddr_t)ppc);
1490 }
1491 }
1492 } else if (ppc->ppc_irqstat & PPC_IRQ_FIFO) {
1493
1494 /* classic interrupt I/O */
1495 ppc->ppc_irqstat &= ~PPC_IRQ_FIFO;
1400
1401 }
1402
1403 return;
1404}
1405
1406static int
1496 }
1497
1498 return;
1499}
1500
1501static int
1407ppc_read(int unit, char *buf, int len, int mode)
1502ppc_read(device_t dev, char *buf, int len, int mode)
1408{
1409 return (EINVAL);
1410}
1411
1412/*
1413 * Call this function if you want to send data in any advanced mode
1414 * of your parallel port: FIFO, DMA
1415 *
1416 * If what you want is not possible (no ECP, no DMA...),
1417 * EINVAL is returned
1418 */
1419static int
1503{
1504 return (EINVAL);
1505}
1506
1507/*
1508 * Call this function if you want to send data in any advanced mode
1509 * of your parallel port: FIFO, DMA
1510 *
1511 * If what you want is not possible (no ECP, no DMA...),
1512 * EINVAL is returned
1513 */
1514static int
1420ppc_write(int unit, char *buf, int len, int how)
1515ppc_write(device_t dev, char *buf, int len, int how)
1421{
1516{
1422 struct ppc_data *ppc = ppcdata[unit];
1517 struct ppc_data *ppc = DEVTOSOFTC(dev);
1423 char ecr, ecr_sav, ctr, ctr_sav;
1424 int s, error = 0;
1425 int spin;
1426
1427#ifdef PPC_DEBUG
1428 printf("w");
1429#endif
1430
1431 ecr_sav = r_ecr(ppc);
1432 ctr_sav = r_ctr(ppc);
1433
1434 /*
1435 * Send buffer with DMA, FIFO and interrupts
1436 */
1518 char ecr, ecr_sav, ctr, ctr_sav;
1519 int s, error = 0;
1520 int spin;
1521
1522#ifdef PPC_DEBUG
1523 printf("w");
1524#endif
1525
1526 ecr_sav = r_ecr(ppc);
1527 ctr_sav = r_ctr(ppc);
1528
1529 /*
1530 * Send buffer with DMA, FIFO and interrupts
1531 */
1437 if (ppc->ppc_avm & PPB_ECP) {
1532 if ((ppc->ppc_avm & PPB_ECP) && (ppc->ppc_registered)) {
1438
1439 if (ppc->ppc_dmachan >= 0) {
1440
1441 /* byte mode, no intr, no DMA, dir=0, flush fifo
1442 */
1443 ecr = PPC_ECR_STD | PPC_DISABLE_INTR;
1444 w_ecr(ppc, ecr);
1445

--- 117 unchanged lines hidden (view full) ---

1563 DELAY(1);
1564
1565 w_ecr(ppc, ecr_sav);
1566 w_ctr(ppc, ctr_sav);
1567
1568 return (error);
1569}
1570
1533
1534 if (ppc->ppc_dmachan >= 0) {
1535
1536 /* byte mode, no intr, no DMA, dir=0, flush fifo
1537 */
1538 ecr = PPC_ECR_STD | PPC_DISABLE_INTR;
1539 w_ecr(ppc, ecr);
1540

--- 117 unchanged lines hidden (view full) ---

1658 DELAY(1);
1659
1660 w_ecr(ppc, ecr_sav);
1661 w_ctr(ppc, ctr_sav);
1662
1663 return (error);
1664}
1665
1571/*
1572 * Configure current operating mode
1573 */
1574static int
1575ppc_generic_setmode(int unit, int mode)
1666static void
1667ppc_reset_epp(device_t dev)
1576{
1668{
1577 struct ppc_data *ppc = ppcdata[unit];
1578 u_char ecr = 0;
1669 struct ppc_data *ppc = DEVTOSOFTC(dev);
1670
1671 ppc_reset_epp_timeout(ppc);
1579
1672
1580 /* check if mode is available */
1581 if (mode && !(ppc->ppc_avm & mode))
1582 return (EINVAL);
1673 return;
1674}
1583
1675
1584 /* if ECP mode, configure ecr register */
1585 if (ppc->ppc_avm & PPB_ECP) {
1586 /* return to byte mode (keeping direction bit),
1587 * no interrupt, no DMA to be able to change to
1588 * ECP
1589 */
1590 w_ecr(ppc, PPC_ECR_RESET);
1591 ecr = PPC_DISABLE_INTR;
1676static int
1677ppc_setmode(device_t dev, int mode)
1678{
1679 struct ppc_data *ppc = DEVTOSOFTC(dev);
1592
1680
1593 if (mode & PPB_EPP)
1594 return (EINVAL);
1595 else if (mode & PPB_ECP)
1596 /* select ECP mode */
1597 ecr |= PPC_ECR_ECP;
1598 else if (mode & PPB_PS2)
1599 /* select PS2 mode with ECP */
1600 ecr |= PPC_ECR_PS2;
1601 else
1602 /* select COMPATIBLE/NIBBLE mode */
1603 ecr |= PPC_ECR_STD;
1681 switch (ppc->ppc_type) {
1682 case PPC_TYPE_SMCLIKE:
1683 return (ppc_smclike_setmode(ppc, mode));
1684 break;
1604
1685
1605 w_ecr(ppc, ecr);
1686 case PPC_TYPE_GENERIC:
1687 default:
1688 return (ppc_generic_setmode(ppc, mode));
1689 break;
1606 }
1607
1690 }
1691
1608 ppc->ppc_mode = mode;
1609
1610 return (0);
1692 /* not reached */
1693 return (ENXIO);
1611}
1612
1694}
1695
1613/*
1614 * The ppc driver is free to choose options like FIFO or DMA
1615 * if ECP mode is available.
1616 *
1617 * The 'RAW' option allows the upper drivers to force the ppc mode
1618 * even with FIFO, DMA available.
1619 */
1620int
1621ppc_smclike_setmode(int unit, int mode)
1696static int
1697ppc_probe(device_t dev)
1622{
1698{
1623 struct ppc_data *ppc = ppcdata[unit];
1624 u_char ecr = 0;
1699 static short next_bios_ppc = 0;
1700 struct ppc_data *ppc;
1701 device_t parent;
1702 int port;
1625
1703
1626 /* check if mode is available */
1627 if (mode && !(ppc->ppc_avm & mode))
1628 return (EINVAL);
1704 device_set_desc(dev, "Parallel port");
1629
1705
1630 /* if ECP mode, configure ecr register */
1631 if (ppc->ppc_avm & PPB_ECP) {
1632 /* return to byte mode (keeping direction bit),
1633 * no interrupt, no DMA to be able to change to
1634 * ECP or EPP mode
1635 */
1636 w_ecr(ppc, PPC_ECR_RESET);
1637 ecr = PPC_DISABLE_INTR;
1706 /* XXX shall be connected to pnpbios - from Peter Wemm */
1707 if (isa_get_logicalid(dev))
1708 return ENXIO;
1638
1709
1639 if (mode & PPB_EPP)
1640 /* select EPP mode */
1641 ecr |= PPC_ECR_EPP;
1642 else if (mode & PPB_ECP)
1643 /* select ECP mode */
1644 ecr |= PPC_ECR_ECP;
1645 else if (mode & PPB_PS2)
1646 /* select PS2 mode with ECP */
1647 ecr |= PPC_ECR_PS2;
1648 else
1649 /* select COMPATIBLE/NIBBLE mode */
1650 ecr |= PPC_ECR_STD;
1710 parent = device_get_parent(dev);
1651
1711
1652 w_ecr(ppc, ecr);
1653 }
1712 /*
1713 * Allocate the ppc_data structure.
1714 */
1715 ppc = DEVTOSOFTC(dev);
1716 bzero(ppc, sizeof(struct ppc_data));
1654
1717
1655 ppc->ppc_mode = mode;
1718 ppc->rid_irq = ppc->rid_drq = ppc->rid_ioport = 0;
1719 ppc->res_irq = ppc->res_drq = ppc->res_ioport = 0;
1656
1720
1657 return (0);
1658}
1721 /* retrieve ISA parameters */
1722 BUS_READ_IVAR(parent, dev, ISA_IVAR_PORT, &port);
1659
1723
1660/*
1661 * EPP timeout, according to the PC87332 manual
1662 * Semantics of clearing EPP timeout bit.
1663 * PC87332 - reading SPP_STR does it...
1664 * SMC - write 1 to EPP timeout bit XXX
1665 * Others - (?) write 0 to EPP timeout bit
1666 */
1667static void
1668ppc_reset_epp_timeout(int unit)
1669{
1670 struct ppc_data *ppc = ppcdata[unit];
1671 register char r;
1672
1673 r = r_str(ppc);
1674 w_str(ppc, r | 0x1);
1675 w_str(ppc, r & 0xfe);
1676
1677 return;
1678}
1679
1680static int
1681ppcprobe(struct isa_device *dvp)
1682{
1683 static short next_bios_ppc = 0;
1684 struct ppc_data *ppc;
1685
1686 /*
1687 * If port not specified, use bios list.
1688 */
1724 /*
1725 * If port not specified, use bios list.
1726 */
1689 if(dvp->id_iobase < 0) {
1727 if (port < 0) {
1690 if((next_bios_ppc < BIOS_MAX_PPC) &&
1691 (*(BIOS_PORTS+next_bios_ppc) != 0) ) {
1728 if((next_bios_ppc < BIOS_MAX_PPC) &&
1729 (*(BIOS_PORTS+next_bios_ppc) != 0) ) {
1692 dvp->id_iobase = *(BIOS_PORTS+next_bios_ppc++);
1730 port = *(BIOS_PORTS+next_bios_ppc++);
1693 if (bootverbose)
1731 if (bootverbose)
1694 printf("ppc: parallel port found at 0x%x\n",
1695 dvp->id_iobase);
1696 } else
1697 return (0);
1732 device_printf(dev, "parallel port found at 0x%x\n",
1733 port);
1734 } else {
1735 device_printf(dev, "parallel port not found.\n");
1736 return ENXIO;
1737 }
1698 }
1738 }
1739 ppc->ppc_base = port;
1699
1740
1700 /*
1701 * Port was explicitly specified.
1702 * This allows probing of ports unknown to the BIOS.
1703 */
1704
1705 /*
1706 * Allocate the ppc_data structure.
1707 */
1708 ppc = malloc(sizeof(struct ppc_data), M_DEVBUF, M_NOWAIT);
1709 if (!ppc) {
1710 printf("ppc: cannot malloc!\n");
1741 /* IO port is mandatory */
1742 ppc->res_ioport = bus_alloc_resource(dev, SYS_RES_IOPORT,
1743 &ppc->rid_ioport, port, port,
1744 IO_LPTSIZE, RF_ACTIVE);
1745 if (ppc->res_ioport == 0) {
1746 device_printf(dev, "cannot reserve I/O port range\n");
1711 goto error;
1712 }
1747 goto error;
1748 }
1713 bzero(ppc, sizeof(struct ppc_data));
1714
1749
1715 ppc->ppc_base = dvp->id_iobase;
1716 ppc->ppc_unit = dvp->id_unit;
1717 ppc->ppc_type = GENERIC;
1750 ppc->ppc_flags = device_get_flags(dev);
1718
1751
1719 /* store boot flags */
1720 ppc->ppc_flags = dvp->id_flags;
1752 if (!(ppc->ppc_flags & 0x20)) {
1753 ppc->res_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &ppc->rid_irq,
1754 0ul, ~0ul, 1, RF_SHAREABLE);
1755 ppc->res_drq = bus_alloc_resource(dev, SYS_RES_DRQ, &ppc->rid_drq,
1756 0ul, ~0ul, 1, RF_ACTIVE);
1757 }
1721
1758
1722 ppc->ppc_mode = PPB_COMPATIBLE;
1723 ppc->ppc_epp = (dvp->id_flags & 0x10) >> 4;
1759 if (ppc->res_irq)
1760 BUS_READ_IVAR(parent, dev, ISA_IVAR_IRQ, &ppc->ppc_irq);
1761 if (ppc->res_drq)
1762 BUS_READ_IVAR(parent, dev, ISA_IVAR_DRQ, &ppc->ppc_dmachan);
1724
1763
1725 /*
1726 * XXX Try and detect if interrupts are working
1727 */
1728 if (!(dvp->id_flags & 0x20) && dvp->id_irq)
1729 ppc->ppc_irq = ffs(dvp->id_irq) - 1;
1764 ppc->ppc_unit = device_get_unit(dev);
1765 ppc->ppc_model = GENERIC;
1730
1766
1731 ppc->ppc_dmachan = dvp->id_drq;
1767 ppc->ppc_mode = PPB_COMPATIBLE;
1768 ppc->ppc_epp = (ppc->ppc_flags & 0x10) >> 4;
1732
1769
1733 ppcdata[ppc->ppc_unit] = ppc;
1734 nppc ++;
1770 ppc->ppc_type = PPC_TYPE_GENERIC;
1735
1736 /*
1771
1772 /*
1737 * Link the Parallel Port Chipset (adapter) to
1738 * the future ppbus. Default to a generic chipset
1739 */
1740 ppc->ppc_link.adapter_unit = ppc->ppc_unit;
1741 ppc->ppc_link.adapter = &ppc_generic_adapter;
1742
1743 /*
1744 * Try to detect the chipset and its mode.
1745 */
1773 * Try to detect the chipset and its mode.
1774 */
1746 if (ppc_detect(ppc, dvp->id_flags & 0xf))
1775 if (ppc_detect(ppc, ppc->ppc_flags & 0xf))
1747 goto error;
1748
1776 goto error;
1777
1749 return (IO_LPTSIZE);
1778 return (0);
1750
1751error:
1779
1780error:
1752 return (0);
1781 if (ppc->res_irq != 0) {
1782 bus_release_resource(dev, SYS_RES_IRQ, ppc->rid_irq,
1783 ppc->res_irq);
1784 }
1785 if (ppc->res_ioport != 0) {
1786 bus_deactivate_resource(dev, SYS_RES_IOPORT, ppc->rid_ioport,
1787 ppc->res_ioport);
1788 bus_release_resource(dev, SYS_RES_IOPORT, ppc->rid_ioport,
1789 ppc->res_ioport);
1790 }
1791 if (ppc->res_drq != 0) {
1792 bus_deactivate_resource(dev, SYS_RES_DRQ, ppc->rid_drq,
1793 ppc->res_drq);
1794 bus_release_resource(dev, SYS_RES_DRQ, ppc->rid_drq,
1795 ppc->res_drq);
1796 }
1797 return (ENXIO);
1753}
1754
1755static int
1798}
1799
1800static int
1756ppcattach(struct isa_device *isdp)
1801ppc_attach(device_t dev)
1757{
1802{
1758 struct ppc_data *ppc = ppcdata[isdp->id_unit];
1759 struct ppb_data *ppbus;
1803 struct ppc_data *ppc = DEVTOSOFTC(dev);
1760
1804
1761 printf("ppc%d: %s chipset (%s) in %s mode%s\n", ppc->ppc_unit,
1762 ppc_types[ppc->ppc_type], ppc_avms[ppc->ppc_avm],
1763 ppc_modes[ppc->ppc_mode], (PPB_IS_EPP(ppc->ppc_mode)) ?
1764 ppc_epp_protocol[ppc->ppc_epp] : "");
1805 device_t ppbus;
1806 device_t parent = device_get_parent(dev);
1765
1807
1808 device_printf(dev, "%s chipset (%s) in %s mode%s\n",
1809 ppc_models[ppc->ppc_model], ppc_avms[ppc->ppc_avm],
1810 ppc_modes[ppc->ppc_mode], (PPB_IS_EPP(ppc->ppc_mode)) ?
1811 ppc_epp_protocol[ppc->ppc_epp] : "");
1812
1766 if (ppc->ppc_fifo)
1813 if (ppc->ppc_fifo)
1767 printf("ppc%d: FIFO with %d/%d/%d bytes threshold\n",
1768 ppc->ppc_unit, ppc->ppc_fifo, ppc->ppc_wthr,
1769 ppc->ppc_rthr);
1814 device_printf(dev, "FIFO with %d/%d/%d bytes threshold\n",
1815 ppc->ppc_fifo, ppc->ppc_wthr, ppc->ppc_rthr);
1770
1816
1771 isdp->id_ointr = ppcintr;
1817 if ((ppc->ppc_avm & PPB_ECP) && (ppc->ppc_dmachan > 0)) {
1818 /* acquire the DMA channel forever */ /* XXX */
1819 isa_dma_acquire(ppc->ppc_dmachan);
1820 isa_dmainit(ppc->ppc_dmachan, 1024); /* nlpt.BUFSIZE */
1821 }
1772
1822
1823 /* add ppbus as a child of this isa to parallel bridge */
1824 ppbus = device_add_child(dev, "ppbus", -1);
1825
1773 /*
1826 /*
1774 * Prepare ppbus data area for upper level code.
1827 * Probe the ppbus and attach devices found.
1775 */
1828 */
1776 ppbus = ppb_alloc_bus();
1829 device_probe_and_attach(ppbus);
1777
1830
1778 if (!ppbus)
1779 return (0);
1831 /* register the ppc interrupt handler as default */
1832 if (ppc->res_irq) {
1833 /* default to the tty mask for registration */ /* XXX */
1834 if (BUS_SETUP_INTR(parent, dev, ppc->res_irq, INTR_TYPE_TTY,
1835 ppcintr, dev, &ppc->intr_cookie) == 0) {
1780
1836
1781 ppc->ppc_link.ppbus = ppbus;
1782 ppbus->ppb_link = &ppc->ppc_link;
1837 /* remember the ppcintr is registered */
1838 ppc->ppc_registered = 1;
1839 }
1840 }
1783
1841
1784 if ((ppc->ppc_avm & PPB_ECP) && (ppc->ppc_dmachan > 0)) {
1842 return (0);
1843}
1785
1844
1786 /* acquire the DMA channel forever */
1787 isa_dma_acquire(ppc->ppc_dmachan);
1788 isa_dmainit(ppc->ppc_dmachan, 1024); /* nlpt.BUFSIZE */
1845static u_char
1846ppc_io(device_t ppcdev, int iop, u_char *addr, int cnt, u_char byte)
1847{
1848 struct ppc_data *ppc = DEVTOSOFTC(ppcdev);
1849 switch (iop) {
1850 case PPB_OUTSB_EPP:
1851 outsb(ppc->ppc_base + PPC_EPP_DATA, addr, cnt);
1852 break;
1853 case PPB_OUTSW_EPP:
1854 outsw(ppc->ppc_base + PPC_EPP_DATA, addr, cnt);
1855 break;
1856 case PPB_OUTSL_EPP:
1857 outsl(ppc->ppc_base + PPC_EPP_DATA, addr, cnt);
1858 break;
1859 case PPB_INSB_EPP:
1860 insb(ppc->ppc_base + PPC_EPP_DATA, addr, cnt);
1861 break;
1862 case PPB_INSW_EPP:
1863 insw(ppc->ppc_base + PPC_EPP_DATA, addr, cnt);
1864 break;
1865 case PPB_INSL_EPP:
1866 insl(ppc->ppc_base + PPC_EPP_DATA, addr, cnt);
1867 break;
1868 case PPB_RDTR:
1869 return (r_dtr(ppc));
1870 break;
1871 case PPB_RSTR:
1872 return (r_str(ppc));
1873 break;
1874 case PPB_RCTR:
1875 return (r_ctr(ppc));
1876 break;
1877 case PPB_REPP_A:
1878 return (r_epp_A(ppc));
1879 break;
1880 case PPB_REPP_D:
1881 return (r_epp_D(ppc));
1882 break;
1883 case PPB_RECR:
1884 return (r_ecr(ppc));
1885 break;
1886 case PPB_RFIFO:
1887 return (r_fifo(ppc));
1888 break;
1889 case PPB_WDTR:
1890 w_dtr(ppc, byte);
1891 break;
1892 case PPB_WSTR:
1893 w_str(ppc, byte);
1894 break;
1895 case PPB_WCTR:
1896 w_ctr(ppc, byte);
1897 break;
1898 case PPB_WEPP_A:
1899 w_epp_A(ppc, byte);
1900 break;
1901 case PPB_WEPP_D:
1902 w_epp_D(ppc, byte);
1903 break;
1904 case PPB_WECR:
1905 w_ecr(ppc, byte);
1906 break;
1907 case PPB_WFIFO:
1908 w_fifo(ppc, byte);
1909 break;
1910 default:
1911 panic("%s: unknown I/O operation", __FUNCTION__);
1912 break;
1789 }
1790
1913 }
1914
1791 /*
1792 * Probe the ppbus and attach devices found.
1793 */
1794 ppb_attachdevs(ppbus);
1915 return (0); /* not significative */
1916}
1795
1917
1796 return (1);
1918static int
1919ppc_read_ivar(device_t bus, device_t dev, int index, uintptr_t *val)
1920{
1921 struct ppc_data *ppc = (struct ppc_data *)device_get_softc(bus);
1922
1923 switch (index) {
1924 case PPC_IVAR_EPP_PROTO:
1925 *val = (u_long)ppc->ppc_epp;
1926 break;
1927 case PPC_IVAR_IRQ:
1928 BUS_READ_IVAR(device_get_parent(bus), bus, ISA_IVAR_IRQ, val);
1929 break;
1930 default:
1931 return (ENOENT);
1932 }
1933
1934 return (0);
1797}
1935}
1936
1937/*
1938 * Resource is useless here since ppbus devices' interrupt handlers are
1939 * multiplexed to the same resource initially allocated by ppc
1940 */
1941static int
1942ppc_setup_intr(device_t bus, device_t child, struct resource *r, int flags,
1943 void (*ihand)(void *), void *arg, void **cookiep)
1944{
1945 int error;
1946 struct ppc_data *ppc = DEVTOSOFTC(bus);
1947
1948 if (ppc->ppc_registered) {
1949 /* XXX refuse registration if DMA is in progress */
1950
1951 /* first, unregister the default interrupt handler */
1952 if ((error = BUS_TEARDOWN_INTR(device_get_parent(bus),
1953 bus, ppc->res_irq, ppc->intr_cookie)))
1954 return (error);
1955
1956/* bus_deactivate_resource(bus, SYS_RES_IRQ, ppc->rid_irq, */
1957/* ppc->res_irq); */
1958
1959 /* DMA/FIFO operation won't be possible anymore */
1960 ppc->ppc_registered = 0;
1961 }
1962
1963 /* pass registration to the upper layer, ignore the incoming resource */
1964 return (BUS_SETUP_INTR(device_get_parent(bus), child,
1965 r, flags, ihand, arg, cookiep));
1966}
1967
1968/*
1969 * When no underlying device has a registered interrupt, register the ppc
1970 * layer one
1971 */
1972static int
1973ppc_teardown_intr(device_t bus, device_t child, struct resource *r, void *ih)
1974{
1975 int error;
1976 struct ppc_data *ppc = DEVTOSOFTC(bus);
1977 device_t parent = device_get_parent(bus);
1978
1979 /* pass unregistration to the upper layer */
1980 if ((error = BUS_TEARDOWN_INTR(parent, child, r, ih)))
1981 return (error);
1982
1983 /* default to the tty mask for registration */ /* XXX */
1984 if (ppc->ppc_irq &&
1985 !(error = BUS_SETUP_INTR(parent, bus, ppc->res_irq,
1986 INTR_TYPE_TTY, ppcintr, bus, &ppc->intr_cookie))) {
1987
1988 /* remember the ppcintr is registered */
1989 ppc->ppc_registered = 1;
1990 }
1991
1992 return (error);
1993}
1994
1995DRIVER_MODULE(ppc, isa, ppc_driver, ppc_devclass, 0, 0);
1798#endif
1996#endif