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 |