ppc.c revision 330897
1139749Simp/*- 2131276Snjl * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3131276Snjl * 4131276Snjl * Copyright (c) 1997-2000 Nicolas Souchu 5131276Snjl * Copyright (c) 2001 Alcove - Nicolas Souchu 6131276Snjl * All rights reserved. 7131276Snjl * 8131276Snjl * Redistribution and use in source and binary forms, with or without 9131276Snjl * modification, are permitted provided that the following conditions 10131276Snjl * are met: 11131276Snjl * 1. Redistributions of source code must retain the above copyright 12131276Snjl * notice, this list of conditions and the following disclaimer. 13131276Snjl * 2. Redistributions in binary form must reproduce the above copyright 14131276Snjl * notice, this list of conditions and the following disclaimer in the 15131276Snjl * documentation and/or other materials provided with the distribution. 16131276Snjl * 17131276Snjl * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18131276Snjl * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19131276Snjl * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20131276Snjl * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21131276Snjl * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22131276Snjl * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23131276Snjl * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24131276Snjl * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25131276Snjl * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26131276Snjl * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27131276Snjl * SUCH DAMAGE. 28131276Snjl */ 29131276Snjl 30131276Snjl#include <sys/cdefs.h> 31131276Snjl__FBSDID("$FreeBSD: stable/11/sys/dev/ppc/ppc.c 330897 2018-03-14 03:19:51Z eadler $"); 32193530Sjkim 33193530Sjkim#include "opt_ppc.h" 34131276Snjl 35131276Snjl#include <sys/param.h> 36131276Snjl#include <sys/systm.h> 37132212Snjl#include <sys/bus.h> 38131276Snjl#include <sys/kernel.h> 39132212Snjl#include <sys/lock.h> 40132212Snjl#include <sys/interrupt.h> 41132212Snjl#include <sys/module.h> 42132212Snjl#include <sys/malloc.h> 43132212Snjl#include <sys/mutex.h> 44132212Snjl#include <sys/proc.h> 45132212Snjl 46132212Snjl#include <machine/bus.h> 47132212Snjl#include <machine/resource.h> 48132212Snjl#include <sys/rman.h> 49132212Snjl 50132212Snjl#ifdef __i386__ 51132212Snjl#include <vm/vm.h> 52132212Snjl#include <vm/pmap.h> 53132212Snjl#include <machine/vmparam.h> 54132212Snjl#endif 55148352Snjl 56148352Snjl#include <dev/ppbus/ppbconf.h> 57148352Snjl#include <dev/ppbus/ppb_msq.h> 58132212Snjl 59132212Snjl#include <dev/ppc/ppcvar.h> 60132212Snjl#include <dev/ppc/ppcreg.h> 61132212Snjl 62132212Snjl#include "ppbus_if.h" 63131276Snjl 64131276Snjlstatic void ppcintr(void *arg); 65131276Snjl 66131276Snjl#define IO_LPTSIZE_EXTENDED 8 /* "Extended" LPT controllers */ 67131276Snjl#define IO_LPTSIZE_NORMAL 4 /* "Normal" LPT controllers */ 68131276Snjl 69131276Snjl#define LOG_PPC(function, ppc, string) \ 70131276Snjl if (bootverbose) printf("%s: %s\n", function, string) 71131276Snjl 72132212Snjl#if defined(__i386__) && defined(PC98) 73132212Snjl#define PC98_IEEE_1284_DISABLE 0x100 74131276Snjl#define PC98_IEEE_1284_PORT 0x140 75132212Snjl#endif 76132212Snjl 77132212Snjl#define DEVTOSOFTC(dev) ((struct ppc_data *)device_get_softc(dev)) 78132212Snjl 79132212Snjl/* 80132212Snjl * We use critical enter/exit for the simple config locking needed to 81132212Snjl * detect the devices. We just want to make sure that both of our writes 82132212Snjl * happen without someone else also writing to those config registers. Since 83131276Snjl * we just do this at startup, Giant keeps multiple threads from executing, 84131276Snjl * and critical_enter() then is all that's needed to keep us from being preempted 85131276Snjl * during the critical sequences with the hardware. 86131276Snjl * 87131276Snjl * Note: this doesn't prevent multiple threads from putting the chips into 88131276Snjl * config mode, but since we only do that to detect the type at startup the 89131276Snjl * extra overhead isn't needed since Giant protects us from multiple entry 90132212Snjl * and no other code changes these registers. 91131276Snjl */ 92132212Snjl#define PPC_CONFIG_LOCK(ppc) critical_enter() 93132212Snjl#define PPC_CONFIG_UNLOCK(ppc) critical_exit() 94132212Snjl 95132212Snjldevclass_t ppc_devclass; 96132212Snjlconst char ppc_driver_name[] = "ppc"; 97132212Snjl 98132212Snjlstatic char *ppc_models[] = { 99132212Snjl "SMC-like", "SMC FDC37C665GT", "SMC FDC37C666GT", "PC87332", "PC87306", 100132212Snjl "82091AA", "Generic", "W83877F", "W83877AF", "Winbond", "PC87334", 101132212Snjl "SMC FDC37C935", "PC87303", 0 102132212Snjl}; 103132212Snjl 104132212Snjl/* list of available modes */ 105132212Snjlstatic char *ppc_avms[] = { 106132212Snjl "COMPATIBLE", "NIBBLE-only", "PS2-only", "PS2/NIBBLE", "EPP-only", 107131276Snjl "EPP/NIBBLE", "EPP/PS2", "EPP/PS2/NIBBLE", "ECP-only", 108131276Snjl "ECP/NIBBLE", "ECP/PS2", "ECP/PS2/NIBBLE", "ECP/EPP", 109131276Snjl "ECP/EPP/NIBBLE", "ECP/EPP/PS2", "ECP/EPP/PS2/NIBBLE", 0 110131276Snjl}; 111131276Snjl 112131276Snjl/* list of current executing modes 113131276Snjl * Note that few modes do not actually exist. 114131276Snjl */ 115131276Snjlstatic char *ppc_modes[] = { 116138305Snjl "COMPATIBLE", "NIBBLE", "PS/2", "PS/2", "EPP", 117138305Snjl "EPP", "EPP", "EPP", "ECP", 118138305Snjl "ECP", "ECP+PS2", "ECP+PS2", "ECP+EPP", 119138305Snjl "ECP+EPP", "ECP+EPP", "ECP+EPP", 0 120138305Snjl}; 121138305Snjl 122138305Snjlstatic char *ppc_epp_protocol[] = { " (EPP 1.9)", " (EPP 1.7)", 0 }; 123138305Snjl 124138305Snjl#ifdef __i386__ 125138305Snjl/* 126138305Snjl * BIOS printer list - used by BIOS probe. 127138305Snjl */ 128138305Snjl#define BIOS_PPC_PORTS 0x408 129138305Snjl#define BIOS_PORTS (short *)(KERNBASE+BIOS_PPC_PORTS) 130138305Snjl#define BIOS_MAX_PPC 4 131138305Snjl#endif 132138305Snjl 133138305Snjl/* 134138305Snjl * ppc_ecp_sync() XXX 135138305Snjl */ 136132212Snjlint 137132212Snjlppc_ecp_sync(device_t dev) 138132212Snjl{ 139131276Snjl int i, r; 140132212Snjl struct ppc_data *ppc = DEVTOSOFTC(dev); 141132212Snjl 142132212Snjl PPC_ASSERT_LOCKED(ppc); 143132212Snjl if (!(ppc->ppc_avm & PPB_ECP) && !(ppc->ppc_dtm & PPB_ECP)) 144132212Snjl return 0; 145132212Snjl 146132212Snjl r = r_ecr(ppc); 147132212Snjl if ((r & 0xe0) != PPC_ECR_EPP) 148132212Snjl return 0; 149132212Snjl 150132212Snjl for (i = 0; i < 100; i++) { 151132212Snjl r = r_ecr(ppc); 152132212Snjl if (r & 0x1) 153132212Snjl return 0; 154132212Snjl DELAY(100); 155131276Snjl } 156131276Snjl 157132212Snjl device_printf(dev, "ECP sync failed as data still present in FIFO.\n"); 158132212Snjl 159132212Snjl return 0; 160131276Snjl} 161143861Snjl 162143861Snjl/* 163144629Snjl * ppc_detect_fifo() 164144629Snjl * 165144629Snjl * Detect parallel port FIFO 166144629Snjl */ 167144629Snjlstatic int 168144629Snjlppc_detect_fifo(struct ppc_data *ppc) 169144629Snjl{ 170144629Snjl char ecr_sav; 171144629Snjl char ctr_sav, ctr, cc; 172144629Snjl short i; 173144629Snjl 174144629Snjl /* save registers */ 175144629Snjl ecr_sav = r_ecr(ppc); 176143861Snjl ctr_sav = r_ctr(ppc); 177143861Snjl 178143861Snjl /* enter ECP configuration mode, no interrupt, no DMA */ 179143861Snjl w_ecr(ppc, 0xf4); 180143861Snjl 181143861Snjl /* read PWord size - transfers in FIFO mode must be PWord aligned */ 182143861Snjl ppc->ppc_pword = (r_cnfgA(ppc) & PPC_PWORD_MASK); 183143861Snjl 184143861Snjl /* XXX 16 and 32 bits implementations not supported */ 185143861Snjl if (ppc->ppc_pword != PPC_PWORD_8) { 186143861Snjl LOG_PPC(__func__, ppc, "PWord not supported"); 187143861Snjl goto error; 188143861Snjl } 189143861Snjl 190143861Snjl w_ecr(ppc, 0x34); /* byte mode, no interrupt, no DMA */ 191143861Snjl ctr = r_ctr(ppc); 192143861Snjl w_ctr(ppc, ctr | PCD); /* set direction to 1 */ 193143861Snjl 194143861Snjl /* enter ECP test mode, no interrupt, no DMA */ 195143861Snjl w_ecr(ppc, 0xd4); 196143861Snjl 197143861Snjl /* flush the FIFO */ 198143861Snjl for (i=0; i<1024; i++) { 199143861Snjl if (r_ecr(ppc) & PPC_FIFO_EMPTY) 200143861Snjl break; 201143861Snjl cc = r_fifo(ppc); 202143861Snjl } 203143861Snjl 204148352Snjl if (i >= 1024) { 205148352Snjl LOG_PPC(__func__, ppc, "can't flush FIFO"); 206148352Snjl goto error; 207148352Snjl } 208148352Snjl 209148352Snjl /* enable interrupts, no DMA */ 210148352Snjl w_ecr(ppc, 0xd0); 211148352Snjl 212148352Snjl /* determine readIntrThreshold 213148352Snjl * fill the FIFO until serviceIntr is set 214148352Snjl */ 215148352Snjl for (i=0; i<1024; i++) { 216148352Snjl w_fifo(ppc, (char)i); 217148352Snjl if (!ppc->ppc_rthr && (r_ecr(ppc) & PPC_SERVICE_INTR)) { 218148352Snjl /* readThreshold reached */ 219148352Snjl ppc->ppc_rthr = i+1; 220148352Snjl } 221148352Snjl if (r_ecr(ppc) & PPC_FIFO_FULL) { 222148352Snjl ppc->ppc_fifo = i+1; 223148352Snjl break; 224148352Snjl } 225148352Snjl } 226 227 if (i >= 1024) { 228 LOG_PPC(__func__, ppc, "can't fill FIFO"); 229 goto error; 230 } 231 232 w_ecr(ppc, 0xd4); /* test mode, no interrupt, no DMA */ 233 w_ctr(ppc, ctr & ~PCD); /* set direction to 0 */ 234 w_ecr(ppc, 0xd0); /* enable interrupts */ 235 236 /* determine writeIntrThreshold 237 * empty the FIFO until serviceIntr is set 238 */ 239 for (i=ppc->ppc_fifo; i>0; i--) { 240 if (r_fifo(ppc) != (char)(ppc->ppc_fifo-i)) { 241 LOG_PPC(__func__, ppc, "invalid data in FIFO"); 242 goto error; 243 } 244 if (r_ecr(ppc) & PPC_SERVICE_INTR) { 245 /* writeIntrThreshold reached */ 246 ppc->ppc_wthr = ppc->ppc_fifo - i+1; 247 } 248 /* if FIFO empty before the last byte, error */ 249 if (i>1 && (r_ecr(ppc) & PPC_FIFO_EMPTY)) { 250 LOG_PPC(__func__, ppc, "data lost in FIFO"); 251 goto error; 252 } 253 } 254 255 /* FIFO must be empty after the last byte */ 256 if (!(r_ecr(ppc) & PPC_FIFO_EMPTY)) { 257 LOG_PPC(__func__, ppc, "can't empty the FIFO"); 258 goto error; 259 } 260 261 w_ctr(ppc, ctr_sav); 262 w_ecr(ppc, ecr_sav); 263 264 return (0); 265 266error: 267 w_ctr(ppc, ctr_sav); 268 w_ecr(ppc, ecr_sav); 269 270 return (EINVAL); 271} 272 273static int 274ppc_detect_port(struct ppc_data *ppc) 275{ 276 277 w_ctr(ppc, 0x0c); /* To avoid missing PS2 ports */ 278 w_dtr(ppc, 0xaa); 279 if (r_dtr(ppc) != 0xaa) 280 return (0); 281 282 return (1); 283} 284 285/* 286 * EPP timeout, according to the PC87332 manual 287 * Semantics of clearing EPP timeout bit. 288 * PC87332 - reading SPP_STR does it... 289 * SMC - write 1 to EPP timeout bit XXX 290 * Others - (?) write 0 to EPP timeout bit 291 */ 292static void 293ppc_reset_epp_timeout(struct ppc_data *ppc) 294{ 295 register char r; 296 297 r = r_str(ppc); 298 w_str(ppc, r | 0x1); 299 w_str(ppc, r & 0xfe); 300 301 return; 302} 303 304static int 305ppc_check_epp_timeout(struct ppc_data *ppc) 306{ 307 ppc_reset_epp_timeout(ppc); 308 309 return (!(r_str(ppc) & TIMEOUT)); 310} 311 312/* 313 * Configure current operating mode 314 */ 315static int 316ppc_generic_setmode(struct ppc_data *ppc, int mode) 317{ 318 u_char ecr = 0; 319 320 /* check if mode is available */ 321 if (mode && !(ppc->ppc_avm & mode)) 322 return (EINVAL); 323 324 /* if ECP mode, configure ecr register */ 325 if ((ppc->ppc_avm & PPB_ECP) || (ppc->ppc_dtm & PPB_ECP)) { 326 /* return to byte mode (keeping direction bit), 327 * no interrupt, no DMA to be able to change to 328 * ECP 329 */ 330 w_ecr(ppc, PPC_ECR_RESET); 331 ecr = PPC_DISABLE_INTR; 332 333 if (mode & PPB_EPP) 334 return (EINVAL); 335 else if (mode & PPB_ECP) 336 /* select ECP mode */ 337 ecr |= PPC_ECR_ECP; 338 else if (mode & PPB_PS2) 339 /* select PS2 mode with ECP */ 340 ecr |= PPC_ECR_PS2; 341 else 342 /* select COMPATIBLE/NIBBLE mode */ 343 ecr |= PPC_ECR_STD; 344 345 w_ecr(ppc, ecr); 346 } 347 348 ppc->ppc_mode = mode; 349 350 return (0); 351} 352 353/* 354 * The ppc driver is free to choose options like FIFO or DMA 355 * if ECP mode is available. 356 * 357 * The 'RAW' option allows the upper drivers to force the ppc mode 358 * even with FIFO, DMA available. 359 */ 360static int 361ppc_smclike_setmode(struct ppc_data *ppc, int mode) 362{ 363 u_char ecr = 0; 364 365 /* check if mode is available */ 366 if (mode && !(ppc->ppc_avm & mode)) 367 return (EINVAL); 368 369 /* if ECP mode, configure ecr register */ 370 if ((ppc->ppc_avm & PPB_ECP) || (ppc->ppc_dtm & PPB_ECP)) { 371 /* return to byte mode (keeping direction bit), 372 * no interrupt, no DMA to be able to change to 373 * ECP or EPP mode 374 */ 375 w_ecr(ppc, PPC_ECR_RESET); 376 ecr = PPC_DISABLE_INTR; 377 378 if (mode & PPB_EPP) 379 /* select EPP mode */ 380 ecr |= PPC_ECR_EPP; 381 else if (mode & PPB_ECP) 382 /* select ECP mode */ 383 ecr |= PPC_ECR_ECP; 384 else if (mode & PPB_PS2) 385 /* select PS2 mode with ECP */ 386 ecr |= PPC_ECR_PS2; 387 else 388 /* select COMPATIBLE/NIBBLE mode */ 389 ecr |= PPC_ECR_STD; 390 391 w_ecr(ppc, ecr); 392 } 393 394 ppc->ppc_mode = mode; 395 396 return (0); 397} 398 399#ifdef PPC_PROBE_CHIPSET 400/* 401 * ppc_pc873xx_detect 402 * 403 * Probe for a Natsemi PC873xx-family part. 404 * 405 * References in this function are to the National Semiconductor 406 * PC87332 datasheet TL/C/11930, May 1995 revision. 407 */ 408static int pc873xx_basetab[] = {0x0398, 0x026e, 0x015c, 0x002e, 0}; 409static int pc873xx_porttab[] = {0x0378, 0x03bc, 0x0278, 0}; 410static int pc873xx_irqtab[] = {5, 7, 5, 0}; 411 412static int pc873xx_regstab[] = { 413 PC873_FER, PC873_FAR, PC873_PTR, 414 PC873_FCR, PC873_PCR, PC873_PMC, 415 PC873_TUP, PC873_SID, PC873_PNP0, 416 PC873_PNP1, PC873_LPTBA, -1 417}; 418 419static char *pc873xx_rnametab[] = { 420 "FER", "FAR", "PTR", "FCR", "PCR", 421 "PMC", "TUP", "SID", "PNP0", "PNP1", 422 "LPTBA", NULL 423}; 424 425static int 426ppc_pc873xx_detect(struct ppc_data *ppc, int chipset_mode) /* XXX mode never forced */ 427{ 428 static int index = 0; 429 int idport, irq; 430 int ptr, pcr, val, i; 431 432 while ((idport = pc873xx_basetab[index++])) { 433 434 /* XXX should check first to see if this location is already claimed */ 435 436 /* 437 * Pull the 873xx through the power-on ID cycle (2.2,1.). 438 * We can't use this to locate the chip as it may already have 439 * been used by the BIOS. 440 */ 441 (void)inb(idport); (void)inb(idport); 442 (void)inb(idport); (void)inb(idport); 443 444 /* 445 * Read the SID byte. Possible values are : 446 * 447 * 01010xxx PC87334 448 * 0001xxxx PC87332 449 * 01110xxx PC87306 450 * 00110xxx PC87303 451 */ 452 outb(idport, PC873_SID); 453 val = inb(idport + 1); 454 if ((val & 0xf0) == 0x10) { 455 ppc->ppc_model = NS_PC87332; 456 } else if ((val & 0xf8) == 0x70) { 457 ppc->ppc_model = NS_PC87306; 458 } else if ((val & 0xf8) == 0x50) { 459 ppc->ppc_model = NS_PC87334; 460 } else if ((val & 0xf8) == 0x40) { /* Should be 0x30 by the 461 documentation, but probing 462 yielded 0x40... */ 463 ppc->ppc_model = NS_PC87303; 464 } else { 465 if (bootverbose && (val != 0xff)) 466 printf("PC873xx probe at 0x%x got unknown ID 0x%x\n", idport, val); 467 continue ; /* not recognised */ 468 } 469 470 /* print registers */ 471 if (bootverbose) { 472 printf("PC873xx"); 473 for (i=0; pc873xx_regstab[i] != -1; i++) { 474 outb(idport, pc873xx_regstab[i]); 475 printf(" %s=0x%x", pc873xx_rnametab[i], 476 inb(idport + 1) & 0xff); 477 } 478 printf("\n"); 479 } 480 481 /* 482 * We think we have one. Is it enabled and where we want it to be? 483 */ 484 outb(idport, PC873_FER); 485 val = inb(idport + 1); 486 if (!(val & PC873_PPENABLE)) { 487 if (bootverbose) 488 printf("PC873xx parallel port disabled\n"); 489 continue; 490 } 491 outb(idport, PC873_FAR); 492 val = inb(idport + 1); 493 /* XXX we should create a driver instance for every port found */ 494 if (pc873xx_porttab[val & 0x3] != ppc->ppc_base) { 495 496 /* First try to change the port address to that requested... */ 497 498 switch (ppc->ppc_base) { 499 case 0x378: 500 val &= 0xfc; 501 break; 502 503 case 0x3bc: 504 val &= 0xfd; 505 break; 506 507 case 0x278: 508 val &= 0xfe; 509 break; 510 511 default: 512 val &= 0xfd; 513 break; 514 } 515 516 outb(idport, PC873_FAR); 517 outb(idport + 1, val); 518 outb(idport + 1, val); 519 520 /* Check for success by reading back the value we supposedly 521 wrote and comparing...*/ 522 523 outb(idport, PC873_FAR); 524 val = inb(idport + 1) & 0x3; 525 526 /* If we fail, report the failure... */ 527 528 if (pc873xx_porttab[val] != ppc->ppc_base) { 529 if (bootverbose) 530 printf("PC873xx at 0x%x not for driver at port 0x%x\n", 531 pc873xx_porttab[val], ppc->ppc_base); 532 } 533 continue; 534 } 535 536 outb(idport, PC873_PTR); 537 ptr = inb(idport + 1); 538 539 /* get irq settings */ 540 if (ppc->ppc_base == 0x378) 541 irq = (ptr & PC873_LPTBIRQ7) ? 7 : 5; 542 else 543 irq = pc873xx_irqtab[val]; 544 545 if (bootverbose) 546 printf("PC873xx irq %d at 0x%x\n", irq, ppc->ppc_base); 547 548 /* 549 * Check if irq settings are correct 550 */ 551 if (irq != ppc->ppc_irq) { 552 /* 553 * If the chipset is not locked and base address is 0x378, 554 * we have another chance 555 */ 556 if (ppc->ppc_base == 0x378 && !(ptr & PC873_CFGLOCK)) { 557 if (ppc->ppc_irq == 7) { 558 outb(idport + 1, (ptr | PC873_LPTBIRQ7)); 559 outb(idport + 1, (ptr | PC873_LPTBIRQ7)); 560 } else { 561 outb(idport + 1, (ptr & ~PC873_LPTBIRQ7)); 562 outb(idport + 1, (ptr & ~PC873_LPTBIRQ7)); 563 } 564 if (bootverbose) 565 printf("PC873xx irq set to %d\n", ppc->ppc_irq); 566 } else { 567 if (bootverbose) 568 printf("PC873xx sorry, can't change irq setting\n"); 569 } 570 } else { 571 if (bootverbose) 572 printf("PC873xx irq settings are correct\n"); 573 } 574 575 outb(idport, PC873_PCR); 576 pcr = inb(idport + 1); 577 578 if ((ptr & PC873_CFGLOCK) || !chipset_mode) { 579 if (bootverbose) 580 printf("PC873xx %s", (ptr & PC873_CFGLOCK)?"locked":"unlocked"); 581 582 ppc->ppc_avm |= PPB_NIBBLE; 583 if (bootverbose) 584 printf(", NIBBLE"); 585 586 if (pcr & PC873_EPPEN) { 587 ppc->ppc_avm |= PPB_EPP; 588 589 if (bootverbose) 590 printf(", EPP"); 591 592 if (pcr & PC873_EPP19) 593 ppc->ppc_epp = EPP_1_9; 594 else 595 ppc->ppc_epp = EPP_1_7; 596 597 if ((ppc->ppc_model == NS_PC87332) && bootverbose) { 598 outb(idport, PC873_PTR); 599 ptr = inb(idport + 1); 600 if (ptr & PC873_EPPRDIR) 601 printf(", Regular mode"); 602 else 603 printf(", Automatic mode"); 604 } 605 } else if (pcr & PC873_ECPEN) { 606 ppc->ppc_avm |= PPB_ECP; 607 if (bootverbose) 608 printf(", ECP"); 609 610 if (pcr & PC873_ECPCLK) { /* XXX */ 611 ppc->ppc_avm |= PPB_PS2; 612 if (bootverbose) 613 printf(", PS/2"); 614 } 615 } else { 616 outb(idport, PC873_PTR); 617 ptr = inb(idport + 1); 618 if (ptr & PC873_EXTENDED) { 619 ppc->ppc_avm |= PPB_SPP; 620 if (bootverbose) 621 printf(", SPP"); 622 } 623 } 624 } else { 625 if (bootverbose) 626 printf("PC873xx unlocked"); 627 628 if (chipset_mode & PPB_ECP) { 629 if ((chipset_mode & PPB_EPP) && bootverbose) 630 printf(", ECP+EPP not supported"); 631 632 pcr &= ~PC873_EPPEN; 633 pcr |= (PC873_ECPEN | PC873_ECPCLK); /* XXX */ 634 outb(idport + 1, pcr); 635 outb(idport + 1, pcr); 636 637 if (bootverbose) 638 printf(", ECP"); 639 640 } else if (chipset_mode & PPB_EPP) { 641 pcr &= ~(PC873_ECPEN | PC873_ECPCLK); 642 pcr |= (PC873_EPPEN | PC873_EPP19); 643 outb(idport + 1, pcr); 644 outb(idport + 1, pcr); 645 646 ppc->ppc_epp = EPP_1_9; /* XXX */ 647 648 if (bootverbose) 649 printf(", EPP1.9"); 650 651 /* enable automatic direction turnover */ 652 if (ppc->ppc_model == NS_PC87332) { 653 outb(idport, PC873_PTR); 654 ptr = inb(idport + 1); 655 ptr &= ~PC873_EPPRDIR; 656 outb(idport + 1, ptr); 657 outb(idport + 1, ptr); 658 659 if (bootverbose) 660 printf(", Automatic mode"); 661 } 662 } else { 663 pcr &= ~(PC873_ECPEN | PC873_ECPCLK | PC873_EPPEN); 664 outb(idport + 1, pcr); 665 outb(idport + 1, pcr); 666 667 /* configure extended bit in PTR */ 668 outb(idport, PC873_PTR); 669 ptr = inb(idport + 1); 670 671 if (chipset_mode & PPB_PS2) { 672 ptr |= PC873_EXTENDED; 673 674 if (bootverbose) 675 printf(", PS/2"); 676 677 } else { 678 /* default to NIBBLE mode */ 679 ptr &= ~PC873_EXTENDED; 680 681 if (bootverbose) 682 printf(", NIBBLE"); 683 } 684 outb(idport + 1, ptr); 685 outb(idport + 1, ptr); 686 } 687 688 ppc->ppc_avm = chipset_mode; 689 } 690 691 if (bootverbose) 692 printf("\n"); 693 694 ppc->ppc_type = PPC_TYPE_GENERIC; 695 ppc_generic_setmode(ppc, chipset_mode); 696 697 return(chipset_mode); 698 } 699 return(-1); 700} 701 702/* 703 * ppc_smc37c66xgt_detect 704 * 705 * SMC FDC37C66xGT configuration. 706 */ 707static int 708ppc_smc37c66xgt_detect(struct ppc_data *ppc, int chipset_mode) 709{ 710 int i; 711 u_char r; 712 int type = -1; 713 int csr = SMC66x_CSR; /* initial value is 0x3F0 */ 714 715 int port_address[] = { -1 /* disabled */ , 0x3bc, 0x378, 0x278 }; 716 717 718#define cio csr+1 /* config IO port is either 0x3F1 or 0x371 */ 719 720 /* 721 * Detection: enter configuration mode and read CRD register. 722 */ 723 PPC_CONFIG_LOCK(ppc); 724 outb(csr, SMC665_iCODE); 725 outb(csr, SMC665_iCODE); 726 PPC_CONFIG_UNLOCK(ppc); 727 728 outb(csr, 0xd); 729 if (inb(cio) == 0x65) { 730 type = SMC_37C665GT; 731 goto config; 732 } 733 734 for (i = 0; i < 2; i++) { 735 PPC_CONFIG_LOCK(ppc); 736 outb(csr, SMC666_iCODE); 737 outb(csr, SMC666_iCODE); 738 PPC_CONFIG_UNLOCK(ppc); 739 740 outb(csr, 0xd); 741 if (inb(cio) == 0x66) { 742 type = SMC_37C666GT; 743 break; 744 } 745 746 /* Another chance, CSR may be hard-configured to be at 0x370 */ 747 csr = SMC666_CSR; 748 } 749 750config: 751 /* 752 * If chipset not found, do not continue. 753 */ 754 if (type == -1) { 755 outb(csr, 0xaa); /* end config mode */ 756 return (-1); 757 } 758 759 /* select CR1 */ 760 outb(csr, 0x1); 761 762 /* read the port's address: bits 0 and 1 of CR1 */ 763 r = inb(cio) & SMC_CR1_ADDR; 764 if (port_address[(int)r] != ppc->ppc_base) { 765 outb(csr, 0xaa); /* end config mode */ 766 return (-1); 767 } 768 769 ppc->ppc_model = type; 770 771 /* 772 * CR1 and CR4 registers bits 3 and 0/1 for mode configuration 773 * If SPP mode is detected, try to set ECP+EPP mode 774 */ 775 776 if (bootverbose) { 777 outb(csr, 0x1); 778 device_printf(ppc->ppc_dev, "SMC registers CR1=0x%x", 779 inb(cio) & 0xff); 780 781 outb(csr, 0x4); 782 printf(" CR4=0x%x", inb(cio) & 0xff); 783 } 784 785 /* select CR1 */ 786 outb(csr, 0x1); 787 788 if (!chipset_mode) { 789 /* autodetect mode */ 790 791 /* 666GT is ~certainly~ hardwired to an extended ECP+EPP mode */ 792 if (type == SMC_37C666GT) { 793 ppc->ppc_avm |= PPB_ECP | PPB_EPP | PPB_SPP; 794 if (bootverbose) 795 printf(" configuration hardwired, supposing " \ 796 "ECP+EPP SPP"); 797 798 } else 799 if ((inb(cio) & SMC_CR1_MODE) == 0) { 800 /* already in extended parallel port mode, read CR4 */ 801 outb(csr, 0x4); 802 r = (inb(cio) & SMC_CR4_EMODE); 803 804 switch (r) { 805 case SMC_SPP: 806 ppc->ppc_avm |= PPB_SPP; 807 if (bootverbose) 808 printf(" SPP"); 809 break; 810 811 case SMC_EPPSPP: 812 ppc->ppc_avm |= PPB_EPP | PPB_SPP; 813 if (bootverbose) 814 printf(" EPP SPP"); 815 break; 816 817 case SMC_ECP: 818 ppc->ppc_avm |= PPB_ECP | PPB_SPP; 819 if (bootverbose) 820 printf(" ECP SPP"); 821 break; 822 823 case SMC_ECPEPP: 824 ppc->ppc_avm |= PPB_ECP | PPB_EPP | PPB_SPP; 825 if (bootverbose) 826 printf(" ECP+EPP SPP"); 827 break; 828 } 829 } else { 830 /* not an extended port mode */ 831 ppc->ppc_avm |= PPB_SPP; 832 if (bootverbose) 833 printf(" SPP"); 834 } 835 836 } else { 837 /* mode forced */ 838 ppc->ppc_avm = chipset_mode; 839 840 /* 666GT is ~certainly~ hardwired to an extended ECP+EPP mode */ 841 if (type == SMC_37C666GT) 842 goto end_detect; 843 844 r = inb(cio); 845 if ((chipset_mode & (PPB_ECP | PPB_EPP)) == 0) { 846 /* do not use ECP when the mode is not forced to */ 847 outb(cio, r | SMC_CR1_MODE); 848 if (bootverbose) 849 printf(" SPP"); 850 } else { 851 /* an extended mode is selected */ 852 outb(cio, r & ~SMC_CR1_MODE); 853 854 /* read CR4 register and reset mode field */ 855 outb(csr, 0x4); 856 r = inb(cio) & ~SMC_CR4_EMODE; 857 858 if (chipset_mode & PPB_ECP) { 859 if (chipset_mode & PPB_EPP) { 860 outb(cio, r | SMC_ECPEPP); 861 if (bootverbose) 862 printf(" ECP+EPP"); 863 } else { 864 outb(cio, r | SMC_ECP); 865 if (bootverbose) 866 printf(" ECP"); 867 } 868 } else { 869 /* PPB_EPP is set */ 870 outb(cio, r | SMC_EPPSPP); 871 if (bootverbose) 872 printf(" EPP SPP"); 873 } 874 } 875 ppc->ppc_avm = chipset_mode; 876 } 877 878 /* set FIFO threshold to 16 */ 879 if (ppc->ppc_avm & PPB_ECP) { 880 /* select CRA */ 881 outb(csr, 0xa); 882 outb(cio, 16); 883 } 884 885end_detect: 886 887 if (bootverbose) 888 printf ("\n"); 889 890 if (ppc->ppc_avm & PPB_EPP) { 891 /* select CR4 */ 892 outb(csr, 0x4); 893 r = inb(cio); 894 895 /* 896 * Set the EPP protocol... 897 * Low=EPP 1.9 (1284 standard) and High=EPP 1.7 898 */ 899 if (ppc->ppc_epp == EPP_1_9) 900 outb(cio, (r & ~SMC_CR4_EPPTYPE)); 901 else 902 outb(cio, (r | SMC_CR4_EPPTYPE)); 903 } 904 905 outb(csr, 0xaa); /* end config mode */ 906 907 ppc->ppc_type = PPC_TYPE_SMCLIKE; 908 ppc_smclike_setmode(ppc, chipset_mode); 909 910 return (chipset_mode); 911} 912 913/* 914 * SMC FDC37C935 configuration 915 * Found on many Alpha machines 916 */ 917static int 918ppc_smc37c935_detect(struct ppc_data *ppc, int chipset_mode) 919{ 920 int type = -1; 921 922 PPC_CONFIG_LOCK(ppc); 923 outb(SMC935_CFG, 0x55); /* enter config mode */ 924 outb(SMC935_CFG, 0x55); 925 PPC_CONFIG_UNLOCK(ppc); 926 927 outb(SMC935_IND, SMC935_ID); /* check device id */ 928 if (inb(SMC935_DAT) == 0x2) 929 type = SMC_37C935; 930 931 if (type == -1) { 932 outb(SMC935_CFG, 0xaa); /* exit config mode */ 933 return (-1); 934 } 935 936 ppc->ppc_model = type; 937 938 outb(SMC935_IND, SMC935_LOGDEV); /* select parallel port, */ 939 outb(SMC935_DAT, 3); /* which is logical device 3 */ 940 941 /* set io port base */ 942 outb(SMC935_IND, SMC935_PORTHI); 943 outb(SMC935_DAT, (u_char)((ppc->ppc_base & 0xff00) >> 8)); 944 outb(SMC935_IND, SMC935_PORTLO); 945 outb(SMC935_DAT, (u_char)(ppc->ppc_base & 0xff)); 946 947 if (!chipset_mode) 948 ppc->ppc_avm = PPB_COMPATIBLE; /* default mode */ 949 else { 950 ppc->ppc_avm = chipset_mode; 951 outb(SMC935_IND, SMC935_PPMODE); 952 outb(SMC935_DAT, SMC935_CENT); /* start in compatible mode */ 953 954 /* SPP + EPP or just plain SPP */ 955 if (chipset_mode & (PPB_SPP)) { 956 if (chipset_mode & PPB_EPP) { 957 if (ppc->ppc_epp == EPP_1_9) { 958 outb(SMC935_IND, SMC935_PPMODE); 959 outb(SMC935_DAT, SMC935_EPP19SPP); 960 } 961 if (ppc->ppc_epp == EPP_1_7) { 962 outb(SMC935_IND, SMC935_PPMODE); 963 outb(SMC935_DAT, SMC935_EPP17SPP); 964 } 965 } else { 966 outb(SMC935_IND, SMC935_PPMODE); 967 outb(SMC935_DAT, SMC935_SPP); 968 } 969 } 970 971 /* ECP + EPP or just plain ECP */ 972 if (chipset_mode & PPB_ECP) { 973 if (chipset_mode & PPB_EPP) { 974 if (ppc->ppc_epp == EPP_1_9) { 975 outb(SMC935_IND, SMC935_PPMODE); 976 outb(SMC935_DAT, SMC935_ECPEPP19); 977 } 978 if (ppc->ppc_epp == EPP_1_7) { 979 outb(SMC935_IND, SMC935_PPMODE); 980 outb(SMC935_DAT, SMC935_ECPEPP17); 981 } 982 } else { 983 outb(SMC935_IND, SMC935_PPMODE); 984 outb(SMC935_DAT, SMC935_ECP); 985 } 986 } 987 } 988 989 outb(SMC935_CFG, 0xaa); /* exit config mode */ 990 991 ppc->ppc_type = PPC_TYPE_SMCLIKE; 992 ppc_smclike_setmode(ppc, chipset_mode); 993 994 return (chipset_mode); 995} 996 997/* 998 * Winbond W83877F stuff 999 * 1000 * EFER: extended function enable register 1001 * EFIR: extended function index register 1002 * EFDR: extended function data register 1003 */ 1004#define efir ((efer == 0x250) ? 0x251 : 0x3f0) 1005#define efdr ((efer == 0x250) ? 0x252 : 0x3f1) 1006 1007static int w83877f_efers[] = { 0x250, 0x3f0, 0x3f0, 0x250 }; 1008static int w83877f_keys[] = { 0x89, 0x86, 0x87, 0x88 }; 1009static int w83877f_keyiter[] = { 1, 2, 2, 1 }; 1010static int w83877f_hefs[] = { WINB_HEFERE, WINB_HEFRAS, WINB_HEFERE | WINB_HEFRAS, 0 }; 1011 1012static int 1013ppc_w83877f_detect(struct ppc_data *ppc, int chipset_mode) 1014{ 1015 int i, j, efer; 1016 unsigned char r, hefere, hefras; 1017 1018 for (i = 0; i < 4; i ++) { 1019 /* first try to enable configuration registers */ 1020 efer = w83877f_efers[i]; 1021 1022 /* write the key to the EFER */ 1023 for (j = 0; j < w83877f_keyiter[i]; j ++) 1024 outb (efer, w83877f_keys[i]); 1025 1026 /* then check HEFERE and HEFRAS bits */ 1027 outb (efir, 0x0c); 1028 hefere = inb(efdr) & WINB_HEFERE; 1029 1030 outb (efir, 0x16); 1031 hefras = inb(efdr) & WINB_HEFRAS; 1032 1033 /* 1034 * HEFRAS HEFERE 1035 * 0 1 write 89h to 250h (power-on default) 1036 * 1 0 write 86h twice to 3f0h 1037 * 1 1 write 87h twice to 3f0h 1038 * 0 0 write 88h to 250h 1039 */ 1040 if ((hefere | hefras) == w83877f_hefs[i]) 1041 goto found; 1042 } 1043 1044 return (-1); /* failed */ 1045 1046found: 1047 /* check base port address - read from CR23 */ 1048 outb(efir, 0x23); 1049 if (ppc->ppc_base != inb(efdr) * 4) /* 4 bytes boundaries */ 1050 return (-1); 1051 1052 /* read CHIP ID from CR9/bits0-3 */ 1053 outb(efir, 0x9); 1054 1055 switch (inb(efdr) & WINB_CHIPID) { 1056 case WINB_W83877F_ID: 1057 ppc->ppc_model = WINB_W83877F; 1058 break; 1059 1060 case WINB_W83877AF_ID: 1061 ppc->ppc_model = WINB_W83877AF; 1062 break; 1063 1064 default: 1065 ppc->ppc_model = WINB_UNKNOWN; 1066 } 1067 1068 if (bootverbose) { 1069 /* dump of registers */ 1070 device_printf(ppc->ppc_dev, "0x%x - ", w83877f_keys[i]); 1071 for (i = 0; i <= 0xd; i ++) { 1072 outb(efir, i); 1073 printf("0x%x ", inb(efdr)); 1074 } 1075 for (i = 0x10; i <= 0x17; i ++) { 1076 outb(efir, i); 1077 printf("0x%x ", inb(efdr)); 1078 } 1079 outb(efir, 0x1e); 1080 printf("0x%x ", inb(efdr)); 1081 for (i = 0x20; i <= 0x29; i ++) { 1082 outb(efir, i); 1083 printf("0x%x ", inb(efdr)); 1084 } 1085 printf("\n"); 1086 } 1087 1088 ppc->ppc_type = PPC_TYPE_GENERIC; 1089 1090 if (!chipset_mode) { 1091 /* autodetect mode */ 1092 1093 /* select CR0 */ 1094 outb(efir, 0x0); 1095 r = inb(efdr) & (WINB_PRTMODS0 | WINB_PRTMODS1); 1096 1097 /* select CR9 */ 1098 outb(efir, 0x9); 1099 r |= (inb(efdr) & WINB_PRTMODS2); 1100 1101 switch (r) { 1102 case WINB_W83757: 1103 if (bootverbose) 1104 device_printf(ppc->ppc_dev, 1105 "W83757 compatible mode\n"); 1106 return (-1); /* generic or SMC-like */ 1107 1108 case WINB_EXTFDC: 1109 case WINB_EXTADP: 1110 case WINB_EXT2FDD: 1111 case WINB_JOYSTICK: 1112 if (bootverbose) 1113 device_printf(ppc->ppc_dev, 1114 "not in parallel port mode\n"); 1115 return (-1); 1116 1117 case (WINB_PARALLEL | WINB_EPP_SPP): 1118 ppc->ppc_avm |= PPB_EPP | PPB_SPP; 1119 if (bootverbose) 1120 device_printf(ppc->ppc_dev, "EPP SPP\n"); 1121 break; 1122 1123 case (WINB_PARALLEL | WINB_ECP): 1124 ppc->ppc_avm |= PPB_ECP | PPB_SPP; 1125 if (bootverbose) 1126 device_printf(ppc->ppc_dev, "ECP SPP\n"); 1127 break; 1128 1129 case (WINB_PARALLEL | WINB_ECP_EPP): 1130 ppc->ppc_avm |= PPB_ECP | PPB_EPP | PPB_SPP; 1131 ppc->ppc_type = PPC_TYPE_SMCLIKE; 1132 1133 if (bootverbose) 1134 device_printf(ppc->ppc_dev, "ECP+EPP SPP\n"); 1135 break; 1136 default: 1137 printf("%s: unknown case (0x%x)!\n", __func__, r); 1138 } 1139 1140 } else { 1141 /* mode forced */ 1142 1143 /* select CR9 and set PRTMODS2 bit */ 1144 outb(efir, 0x9); 1145 outb(efdr, inb(efdr) & ~WINB_PRTMODS2); 1146 1147 /* select CR0 and reset PRTMODSx bits */ 1148 outb(efir, 0x0); 1149 outb(efdr, inb(efdr) & ~(WINB_PRTMODS0 | WINB_PRTMODS1)); 1150 1151 if (chipset_mode & PPB_ECP) { 1152 if (chipset_mode & PPB_EPP) { 1153 outb(efdr, inb(efdr) | WINB_ECP_EPP); 1154 if (bootverbose) 1155 device_printf(ppc->ppc_dev, 1156 "ECP+EPP\n"); 1157 1158 ppc->ppc_type = PPC_TYPE_SMCLIKE; 1159 1160 } else { 1161 outb(efdr, inb(efdr) | WINB_ECP); 1162 if (bootverbose) 1163 device_printf(ppc->ppc_dev, "ECP\n"); 1164 } 1165 } else { 1166 /* select EPP_SPP otherwise */ 1167 outb(efdr, inb(efdr) | WINB_EPP_SPP); 1168 if (bootverbose) 1169 device_printf(ppc->ppc_dev, "EPP SPP\n"); 1170 } 1171 ppc->ppc_avm = chipset_mode; 1172 } 1173 1174 /* exit configuration mode */ 1175 outb(efer, 0xaa); 1176 1177 switch (ppc->ppc_type) { 1178 case PPC_TYPE_SMCLIKE: 1179 ppc_smclike_setmode(ppc, chipset_mode); 1180 break; 1181 default: 1182 ppc_generic_setmode(ppc, chipset_mode); 1183 break; 1184 } 1185 1186 return (chipset_mode); 1187} 1188#endif 1189 1190/* 1191 * ppc_generic_detect 1192 */ 1193static int 1194ppc_generic_detect(struct ppc_data *ppc, int chipset_mode) 1195{ 1196 /* default to generic */ 1197 ppc->ppc_type = PPC_TYPE_GENERIC; 1198 1199 if (bootverbose) 1200 device_printf(ppc->ppc_dev, "SPP"); 1201 1202 /* first, check for ECP */ 1203 w_ecr(ppc, PPC_ECR_PS2); 1204 if ((r_ecr(ppc) & 0xe0) == PPC_ECR_PS2) { 1205 ppc->ppc_dtm |= PPB_ECP | PPB_SPP; 1206 if (bootverbose) 1207 printf(" ECP "); 1208 1209 /* search for SMC style ECP+EPP mode */ 1210 w_ecr(ppc, PPC_ECR_EPP); 1211 } 1212 1213 /* try to reset EPP timeout bit */ 1214 if (ppc_check_epp_timeout(ppc)) { 1215 ppc->ppc_dtm |= PPB_EPP; 1216 1217 if (ppc->ppc_dtm & PPB_ECP) { 1218 /* SMC like chipset found */ 1219 ppc->ppc_model = SMC_LIKE; 1220 ppc->ppc_type = PPC_TYPE_SMCLIKE; 1221 1222 if (bootverbose) 1223 printf(" ECP+EPP"); 1224 } else { 1225 if (bootverbose) 1226 printf(" EPP"); 1227 } 1228 } else { 1229 /* restore to standard mode */ 1230 w_ecr(ppc, PPC_ECR_STD); 1231 } 1232 1233 /* XXX try to detect NIBBLE and PS2 modes */ 1234 ppc->ppc_dtm |= PPB_NIBBLE; 1235 1236 if (chipset_mode) 1237 ppc->ppc_avm = chipset_mode; 1238 else 1239 ppc->ppc_avm = ppc->ppc_dtm; 1240 1241 if (bootverbose) 1242 printf("\n"); 1243 1244 switch (ppc->ppc_type) { 1245 case PPC_TYPE_SMCLIKE: 1246 ppc_smclike_setmode(ppc, chipset_mode); 1247 break; 1248 default: 1249 ppc_generic_setmode(ppc, chipset_mode); 1250 break; 1251 } 1252 1253 return (chipset_mode); 1254} 1255 1256/* 1257 * ppc_detect() 1258 * 1259 * mode is the mode suggested at boot 1260 */ 1261static int 1262ppc_detect(struct ppc_data *ppc, int chipset_mode) { 1263 1264#ifdef PPC_PROBE_CHIPSET 1265 int i, mode; 1266 1267 /* list of supported chipsets */ 1268 int (*chipset_detect[])(struct ppc_data *, int) = { 1269 ppc_pc873xx_detect, 1270 ppc_smc37c66xgt_detect, 1271 ppc_w83877f_detect, 1272 ppc_smc37c935_detect, 1273 ppc_generic_detect, 1274 NULL 1275 }; 1276#endif 1277 1278 /* if can't find the port and mode not forced return error */ 1279 if (!ppc_detect_port(ppc) && chipset_mode == 0) 1280 return (EIO); /* failed, port not present */ 1281 1282 /* assume centronics compatible mode is supported */ 1283 ppc->ppc_avm = PPB_COMPATIBLE; 1284 1285#ifdef PPC_PROBE_CHIPSET 1286 /* we have to differenciate available chipset modes, 1287 * chipset running modes and IEEE-1284 operating modes 1288 * 1289 * after detection, the port must support running in compatible mode 1290 */ 1291 if (ppc->ppc_flags & 0x40) { 1292 if (bootverbose) 1293 printf("ppc: chipset forced to generic\n"); 1294#endif 1295 1296 ppc->ppc_mode = ppc_generic_detect(ppc, chipset_mode); 1297 1298#ifdef PPC_PROBE_CHIPSET 1299 } else { 1300 for (i=0; chipset_detect[i] != NULL; i++) { 1301 if ((mode = chipset_detect[i](ppc, chipset_mode)) != -1) { 1302 ppc->ppc_mode = mode; 1303 break; 1304 } 1305 } 1306 } 1307#endif 1308 1309 /* configure/detect ECP FIFO */ 1310 if ((ppc->ppc_avm & PPB_ECP) && !(ppc->ppc_flags & 0x80)) 1311 ppc_detect_fifo(ppc); 1312 1313 return (0); 1314} 1315 1316/* 1317 * ppc_exec_microseq() 1318 * 1319 * Execute a microsequence. 1320 * Microsequence mechanism is supposed to handle fast I/O operations. 1321 */ 1322int 1323ppc_exec_microseq(device_t dev, struct ppb_microseq **p_msq) 1324{ 1325 struct ppc_data *ppc = DEVTOSOFTC(dev); 1326 struct ppb_microseq *mi; 1327 char cc, *p; 1328 int i, iter, len; 1329 int error; 1330 1331 register int reg; 1332 register char mask; 1333 register int accum = 0; 1334 register char *ptr = NULL; 1335 1336 struct ppb_microseq *stack = NULL; 1337 1338/* microsequence registers are equivalent to PC-like port registers */ 1339 1340#define r_reg(reg,ppc) (bus_read_1((ppc)->res_ioport, reg)) 1341#define w_reg(reg, ppc, byte) (bus_write_1((ppc)->res_ioport, reg, byte)) 1342 1343#define INCR_PC (mi ++) /* increment program counter */ 1344 1345 PPC_ASSERT_LOCKED(ppc); 1346 mi = *p_msq; 1347 for (;;) { 1348 switch (mi->opcode) { 1349 case MS_OP_RSET: 1350 cc = r_reg(mi->arg[0].i, ppc); 1351 cc &= (char)mi->arg[2].i; /* clear mask */ 1352 cc |= (char)mi->arg[1].i; /* assert mask */ 1353 w_reg(mi->arg[0].i, ppc, cc); 1354 INCR_PC; 1355 break; 1356 1357 case MS_OP_RASSERT_P: 1358 reg = mi->arg[1].i; 1359 ptr = ppc->ppc_ptr; 1360 1361 if ((len = mi->arg[0].i) == MS_ACCUM) { 1362 accum = ppc->ppc_accum; 1363 for (; accum; accum--) 1364 w_reg(reg, ppc, *ptr++); 1365 ppc->ppc_accum = accum; 1366 } else 1367 for (i=0; i<len; i++) 1368 w_reg(reg, ppc, *ptr++); 1369 ppc->ppc_ptr = ptr; 1370 1371 INCR_PC; 1372 break; 1373 1374 case MS_OP_RFETCH_P: 1375 reg = mi->arg[1].i; 1376 mask = (char)mi->arg[2].i; 1377 ptr = ppc->ppc_ptr; 1378 1379 if ((len = mi->arg[0].i) == MS_ACCUM) { 1380 accum = ppc->ppc_accum; 1381 for (; accum; accum--) 1382 *ptr++ = r_reg(reg, ppc) & mask; 1383 ppc->ppc_accum = accum; 1384 } else 1385 for (i=0; i<len; i++) 1386 *ptr++ = r_reg(reg, ppc) & mask; 1387 ppc->ppc_ptr = ptr; 1388 1389 INCR_PC; 1390 break; 1391 1392 case MS_OP_RFETCH: 1393 *((char *) mi->arg[2].p) = r_reg(mi->arg[0].i, ppc) & 1394 (char)mi->arg[1].i; 1395 INCR_PC; 1396 break; 1397 1398 case MS_OP_RASSERT: 1399 case MS_OP_DELAY: 1400 1401 /* let's suppose the next instr. is the same */ 1402 prefetch: 1403 for (;mi->opcode == MS_OP_RASSERT; INCR_PC) 1404 w_reg(mi->arg[0].i, ppc, (char)mi->arg[1].i); 1405 1406 if (mi->opcode == MS_OP_DELAY) { 1407 DELAY(mi->arg[0].i); 1408 INCR_PC; 1409 goto prefetch; 1410 } 1411 break; 1412 1413 case MS_OP_ADELAY: 1414 if (mi->arg[0].i) { 1415 PPC_UNLOCK(ppc); 1416 pause("ppbdelay", mi->arg[0].i * (hz/1000)); 1417 PPC_LOCK(ppc); 1418 } 1419 INCR_PC; 1420 break; 1421 1422 case MS_OP_TRIG: 1423 reg = mi->arg[0].i; 1424 iter = mi->arg[1].i; 1425 p = (char *)mi->arg[2].p; 1426 1427 /* XXX delay limited to 255 us */ 1428 for (i=0; i<iter; i++) { 1429 w_reg(reg, ppc, *p++); 1430 DELAY((unsigned char)*p++); 1431 } 1432 INCR_PC; 1433 break; 1434 1435 case MS_OP_SET: 1436 ppc->ppc_accum = mi->arg[0].i; 1437 INCR_PC; 1438 break; 1439 1440 case MS_OP_DBRA: 1441 if (--ppc->ppc_accum > 0) 1442 mi += mi->arg[0].i; 1443 INCR_PC; 1444 break; 1445 1446 case MS_OP_BRSET: 1447 cc = r_str(ppc); 1448 if ((cc & (char)mi->arg[0].i) == (char)mi->arg[0].i) 1449 mi += mi->arg[1].i; 1450 INCR_PC; 1451 break; 1452 1453 case MS_OP_BRCLEAR: 1454 cc = r_str(ppc); 1455 if ((cc & (char)mi->arg[0].i) == 0) 1456 mi += mi->arg[1].i; 1457 INCR_PC; 1458 break; 1459 1460 case MS_OP_BRSTAT: 1461 cc = r_str(ppc); 1462 if ((cc & ((char)mi->arg[0].i | (char)mi->arg[1].i)) == 1463 (char)mi->arg[0].i) 1464 mi += mi->arg[2].i; 1465 INCR_PC; 1466 break; 1467 1468 case MS_OP_C_CALL: 1469 /* 1470 * If the C call returns !0 then end the microseq. 1471 * The current state of ptr is passed to the C function 1472 */ 1473 if ((error = mi->arg[0].f(mi->arg[1].p, ppc->ppc_ptr))) 1474 return (error); 1475 1476 INCR_PC; 1477 break; 1478 1479 case MS_OP_PTR: 1480 ppc->ppc_ptr = (char *)mi->arg[0].p; 1481 INCR_PC; 1482 break; 1483 1484 case MS_OP_CALL: 1485 if (stack) 1486 panic("%s: too much calls", __func__); 1487 1488 if (mi->arg[0].p) { 1489 /* store the state of the actual 1490 * microsequence 1491 */ 1492 stack = mi; 1493 1494 /* jump to the new microsequence */ 1495 mi = (struct ppb_microseq *)mi->arg[0].p; 1496 } else 1497 INCR_PC; 1498 1499 break; 1500 1501 case MS_OP_SUBRET: 1502 /* retrieve microseq and pc state before the call */ 1503 mi = stack; 1504 1505 /* reset the stack */ 1506 stack = NULL; 1507 1508 /* XXX return code */ 1509 1510 INCR_PC; 1511 break; 1512 1513 case MS_OP_PUT: 1514 case MS_OP_GET: 1515 case MS_OP_RET: 1516 /* can't return to ppb level during the execution 1517 * of a submicrosequence */ 1518 if (stack) 1519 panic("%s: can't return to ppb level", 1520 __func__); 1521 1522 /* update pc for ppb level of execution */ 1523 *p_msq = mi; 1524 1525 /* return to ppb level of execution */ 1526 return (0); 1527 1528 default: 1529 panic("%s: unknown microsequence opcode 0x%x", 1530 __func__, mi->opcode); 1531 } 1532 } 1533 1534 /* unreached */ 1535} 1536 1537static void 1538ppcintr(void *arg) 1539{ 1540 struct ppc_data *ppc = arg; 1541 u_char ctr, ecr, str; 1542 1543 /* 1544 * If we have any child interrupt handlers registered, let 1545 * them handle this interrupt. 1546 * 1547 * XXX: If DMA is in progress should we just complete that w/o 1548 * doing this? 1549 */ 1550 PPC_LOCK(ppc); 1551 if (ppc->ppc_intr_hook != NULL && 1552 ppc->ppc_intr_hook(ppc->ppc_intr_arg) == 0) { 1553 PPC_UNLOCK(ppc); 1554 return; 1555 } 1556 1557 str = r_str(ppc); 1558 ctr = r_ctr(ppc); 1559 ecr = r_ecr(ppc); 1560 1561#if defined(PPC_DEBUG) && PPC_DEBUG > 1 1562 printf("![%x/%x/%x]", ctr, ecr, str); 1563#endif 1564 1565 /* don't use ecp mode with IRQENABLE set */ 1566 if (ctr & IRQENABLE) { 1567 PPC_UNLOCK(ppc); 1568 return; 1569 } 1570 1571 /* interrupts are generated by nFault signal 1572 * only in ECP mode */ 1573 if ((str & nFAULT) && (ppc->ppc_mode & PPB_ECP)) { 1574 /* check if ppc driver has programmed the 1575 * nFault interrupt */ 1576 if (ppc->ppc_irqstat & PPC_IRQ_nFAULT) { 1577 1578 w_ecr(ppc, ecr | PPC_nFAULT_INTR); 1579 ppc->ppc_irqstat &= ~PPC_IRQ_nFAULT; 1580 } else { 1581 /* shall be handled by underlying layers XXX */ 1582 PPC_UNLOCK(ppc); 1583 return; 1584 } 1585 } 1586 1587 if (ppc->ppc_irqstat & PPC_IRQ_DMA) { 1588 /* disable interrupts (should be done by hardware though) */ 1589 w_ecr(ppc, ecr | PPC_SERVICE_INTR); 1590 ppc->ppc_irqstat &= ~PPC_IRQ_DMA; 1591 ecr = r_ecr(ppc); 1592 1593 /* check if DMA completed */ 1594 if ((ppc->ppc_avm & PPB_ECP) && (ecr & PPC_ENABLE_DMA)) { 1595#ifdef PPC_DEBUG 1596 printf("a"); 1597#endif 1598 /* stop DMA */ 1599 w_ecr(ppc, ecr & ~PPC_ENABLE_DMA); 1600 ecr = r_ecr(ppc); 1601 1602 if (ppc->ppc_dmastat == PPC_DMA_STARTED) { 1603#ifdef PPC_DEBUG 1604 printf("d"); 1605#endif 1606 ppc->ppc_dmadone(ppc); 1607 ppc->ppc_dmastat = PPC_DMA_COMPLETE; 1608 1609 /* wakeup the waiting process */ 1610 wakeup(ppc); 1611 } 1612 } 1613 } else if (ppc->ppc_irqstat & PPC_IRQ_FIFO) { 1614 1615 /* classic interrupt I/O */ 1616 ppc->ppc_irqstat &= ~PPC_IRQ_FIFO; 1617 } 1618 PPC_UNLOCK(ppc); 1619 1620 return; 1621} 1622 1623int 1624ppc_read(device_t dev, char *buf, int len, int mode) 1625{ 1626 return (EINVAL); 1627} 1628 1629int 1630ppc_write(device_t dev, char *buf, int len, int how) 1631{ 1632 return (EINVAL); 1633} 1634 1635int 1636ppc_reset_epp(device_t dev) 1637{ 1638 struct ppc_data *ppc = DEVTOSOFTC(dev); 1639 1640 PPC_ASSERT_LOCKED(ppc); 1641 ppc_reset_epp_timeout(ppc); 1642 1643 return 0; 1644} 1645 1646int 1647ppc_setmode(device_t dev, int mode) 1648{ 1649 struct ppc_data *ppc = DEVTOSOFTC(dev); 1650 1651 PPC_ASSERT_LOCKED(ppc); 1652 switch (ppc->ppc_type) { 1653 case PPC_TYPE_SMCLIKE: 1654 return (ppc_smclike_setmode(ppc, mode)); 1655 break; 1656 1657 case PPC_TYPE_GENERIC: 1658 default: 1659 return (ppc_generic_setmode(ppc, mode)); 1660 break; 1661 } 1662 1663 /* not reached */ 1664 return (ENXIO); 1665} 1666 1667int 1668ppc_probe(device_t dev, int rid) 1669{ 1670#ifdef __i386__ 1671 static short next_bios_ppc = 0; 1672#ifdef PC98 1673 unsigned int pc98_ieee_mode = 0x00; 1674 unsigned int tmp; 1675#endif 1676#endif 1677 struct ppc_data *ppc; 1678 int error; 1679 rman_res_t port; 1680 1681 /* 1682 * Allocate the ppc_data structure. 1683 */ 1684 ppc = DEVTOSOFTC(dev); 1685 bzero(ppc, sizeof(struct ppc_data)); 1686 1687 ppc->rid_ioport = rid; 1688 1689 /* retrieve ISA parameters */ 1690 error = bus_get_resource(dev, SYS_RES_IOPORT, rid, &port, NULL); 1691 1692#ifdef __i386__ 1693 /* 1694 * If port not specified, use bios list. 1695 */ 1696 if (error) { 1697#ifdef PC98 1698 if (next_bios_ppc == 0) { 1699 /* Use default IEEE-1284 port of NEC PC-98x1 */ 1700 port = PC98_IEEE_1284_PORT; 1701 next_bios_ppc += 1; 1702 if (bootverbose) 1703 device_printf(dev, 1704 "parallel port found at 0x%jx\n", port); 1705 } 1706#else 1707 if ((next_bios_ppc < BIOS_MAX_PPC) && 1708 (*(BIOS_PORTS + next_bios_ppc) != 0)) { 1709 port = *(BIOS_PORTS + next_bios_ppc++); 1710 if (bootverbose) 1711 device_printf(dev, 1712 "parallel port found at 0x%jx\n", port); 1713 } else { 1714 device_printf(dev, "parallel port not found.\n"); 1715 return (ENXIO); 1716 } 1717#endif /* PC98 */ 1718 bus_set_resource(dev, SYS_RES_IOPORT, rid, port, 1719 IO_LPTSIZE_EXTENDED); 1720 } 1721#endif 1722 1723 /* IO port is mandatory */ 1724 1725 /* Try "extended" IO port range...*/ 1726 ppc->res_ioport = bus_alloc_resource_anywhere(dev, SYS_RES_IOPORT, 1727 &ppc->rid_ioport, 1728 IO_LPTSIZE_EXTENDED, 1729 RF_ACTIVE); 1730 1731 if (ppc->res_ioport != 0) { 1732 if (bootverbose) 1733 device_printf(dev, "using extended I/O port range\n"); 1734 } else { 1735 /* Failed? If so, then try the "normal" IO port range... */ 1736 ppc->res_ioport = bus_alloc_resource_anywhere(dev, 1737 SYS_RES_IOPORT, 1738 &ppc->rid_ioport, 1739 IO_LPTSIZE_NORMAL, 1740 RF_ACTIVE); 1741 if (ppc->res_ioport != 0) { 1742 if (bootverbose) 1743 device_printf(dev, "using normal I/O port range\n"); 1744 } else { 1745 device_printf(dev, "cannot reserve I/O port range\n"); 1746 goto error; 1747 } 1748 } 1749 1750 ppc->ppc_base = rman_get_start(ppc->res_ioport); 1751 1752 ppc->ppc_flags = device_get_flags(dev); 1753 1754 if (!(ppc->ppc_flags & 0x20)) { 1755 ppc->res_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, 1756 &ppc->rid_irq, 1757 RF_SHAREABLE); 1758 ppc->res_drq = bus_alloc_resource_any(dev, SYS_RES_DRQ, 1759 &ppc->rid_drq, 1760 RF_ACTIVE); 1761 } 1762 1763 if (ppc->res_irq) 1764 ppc->ppc_irq = rman_get_start(ppc->res_irq); 1765 if (ppc->res_drq) 1766 ppc->ppc_dmachan = rman_get_start(ppc->res_drq); 1767 1768 ppc->ppc_dev = dev; 1769 ppc->ppc_model = GENERIC; 1770 1771 ppc->ppc_mode = PPB_COMPATIBLE; 1772 ppc->ppc_epp = (ppc->ppc_flags & 0x10) >> 4; 1773 1774 ppc->ppc_type = PPC_TYPE_GENERIC; 1775 1776#if defined(__i386__) && defined(PC98) 1777 /* 1778 * IEEE STD 1284 Function Check and Enable 1779 * for default IEEE-1284 port of NEC PC-98x1 1780 */ 1781 if (ppc->ppc_base == PC98_IEEE_1284_PORT && 1782 !(ppc->ppc_flags & PC98_IEEE_1284_DISABLE)) { 1783 tmp = inb(ppc->ppc_base + PPC_1284_ENABLE); 1784 pc98_ieee_mode = tmp; 1785 if ((tmp & 0x10) == 0x10) { 1786 outb(ppc->ppc_base + PPC_1284_ENABLE, tmp & ~0x10); 1787 tmp = inb(ppc->ppc_base + PPC_1284_ENABLE); 1788 if ((tmp & 0x10) == 0x10) 1789 goto error; 1790 } else { 1791 outb(ppc->ppc_base + PPC_1284_ENABLE, tmp | 0x10); 1792 tmp = inb(ppc->ppc_base + PPC_1284_ENABLE); 1793 if ((tmp & 0x10) != 0x10) 1794 goto error; 1795 } 1796 outb(ppc->ppc_base + PPC_1284_ENABLE, pc98_ieee_mode | 0x10); 1797 } 1798#endif 1799 1800 /* 1801 * Try to detect the chipset and its mode. 1802 */ 1803 if (ppc_detect(ppc, ppc->ppc_flags & 0xf)) 1804 goto error; 1805 1806 return (0); 1807 1808error: 1809#if defined(__i386__) && defined(PC98) 1810 if (ppc->ppc_base == PC98_IEEE_1284_PORT && 1811 !(ppc->ppc_flags & PC98_IEEE_1284_DISABLE)) { 1812 outb(ppc->ppc_base + PPC_1284_ENABLE, pc98_ieee_mode); 1813 } 1814#endif 1815 if (ppc->res_irq != 0) { 1816 bus_release_resource(dev, SYS_RES_IRQ, ppc->rid_irq, 1817 ppc->res_irq); 1818 } 1819 if (ppc->res_ioport != 0) { 1820 bus_release_resource(dev, SYS_RES_IOPORT, ppc->rid_ioport, 1821 ppc->res_ioport); 1822 } 1823 if (ppc->res_drq != 0) { 1824 bus_release_resource(dev, SYS_RES_DRQ, ppc->rid_drq, 1825 ppc->res_drq); 1826 } 1827 return (ENXIO); 1828} 1829 1830int 1831ppc_attach(device_t dev) 1832{ 1833 struct ppc_data *ppc = DEVTOSOFTC(dev); 1834 int error; 1835 1836 mtx_init(&ppc->ppc_lock, device_get_nameunit(dev), "ppc", MTX_DEF); 1837 1838 device_printf(dev, "%s chipset (%s) in %s mode%s\n", 1839 ppc_models[ppc->ppc_model], ppc_avms[ppc->ppc_avm], 1840 ppc_modes[ppc->ppc_mode], (PPB_IS_EPP(ppc->ppc_mode)) ? 1841 ppc_epp_protocol[ppc->ppc_epp] : ""); 1842 1843 if (ppc->ppc_fifo) 1844 device_printf(dev, "FIFO with %d/%d/%d bytes threshold\n", 1845 ppc->ppc_fifo, ppc->ppc_wthr, ppc->ppc_rthr); 1846 1847 if (ppc->res_irq) { 1848 /* default to the tty mask for registration */ /* XXX */ 1849 error = bus_setup_intr(dev, ppc->res_irq, INTR_TYPE_TTY | 1850 INTR_MPSAFE, NULL, ppcintr, ppc, &ppc->intr_cookie); 1851 if (error) { 1852 device_printf(dev, 1853 "failed to register interrupt handler: %d\n", 1854 error); 1855 mtx_destroy(&ppc->ppc_lock); 1856 return (error); 1857 } 1858 } 1859 1860 /* add ppbus as a child of this isa to parallel bridge */ 1861 ppc->ppbus = device_add_child(dev, "ppbus", -1); 1862 1863 /* 1864 * Probe the ppbus and attach devices found. 1865 */ 1866 device_probe_and_attach(ppc->ppbus); 1867 1868 return (0); 1869} 1870 1871int 1872ppc_detach(device_t dev) 1873{ 1874 struct ppc_data *ppc = DEVTOSOFTC(dev); 1875 1876 if (ppc->res_irq == 0) { 1877 return (ENXIO); 1878 } 1879 1880 /* detach & delete all children */ 1881 device_delete_children(dev); 1882 1883 if (ppc->res_irq != 0) { 1884 bus_teardown_intr(dev, ppc->res_irq, ppc->intr_cookie); 1885 bus_release_resource(dev, SYS_RES_IRQ, ppc->rid_irq, 1886 ppc->res_irq); 1887 } 1888 if (ppc->res_ioport != 0) { 1889 bus_release_resource(dev, SYS_RES_IOPORT, ppc->rid_ioport, 1890 ppc->res_ioport); 1891 } 1892 if (ppc->res_drq != 0) { 1893 bus_release_resource(dev, SYS_RES_DRQ, ppc->rid_drq, 1894 ppc->res_drq); 1895 } 1896 1897 mtx_destroy(&ppc->ppc_lock); 1898 1899 return (0); 1900} 1901 1902u_char 1903ppc_io(device_t ppcdev, int iop, u_char *addr, int cnt, u_char byte) 1904{ 1905 struct ppc_data *ppc = DEVTOSOFTC(ppcdev); 1906 1907 PPC_ASSERT_LOCKED(ppc); 1908 switch (iop) { 1909 case PPB_OUTSB_EPP: 1910 bus_write_multi_1(ppc->res_ioport, PPC_EPP_DATA, addr, cnt); 1911 break; 1912 case PPB_OUTSW_EPP: 1913 bus_write_multi_2(ppc->res_ioport, PPC_EPP_DATA, (u_int16_t *)addr, cnt); 1914 break; 1915 case PPB_OUTSL_EPP: 1916 bus_write_multi_4(ppc->res_ioport, PPC_EPP_DATA, (u_int32_t *)addr, cnt); 1917 break; 1918 case PPB_INSB_EPP: 1919 bus_read_multi_1(ppc->res_ioport, PPC_EPP_DATA, addr, cnt); 1920 break; 1921 case PPB_INSW_EPP: 1922 bus_read_multi_2(ppc->res_ioport, PPC_EPP_DATA, (u_int16_t *)addr, cnt); 1923 break; 1924 case PPB_INSL_EPP: 1925 bus_read_multi_4(ppc->res_ioport, PPC_EPP_DATA, (u_int32_t *)addr, cnt); 1926 break; 1927 case PPB_RDTR: 1928 return (r_dtr(ppc)); 1929 case PPB_RSTR: 1930 return (r_str(ppc)); 1931 case PPB_RCTR: 1932 return (r_ctr(ppc)); 1933 case PPB_REPP_A: 1934 return (r_epp_A(ppc)); 1935 case PPB_REPP_D: 1936 return (r_epp_D(ppc)); 1937 case PPB_RECR: 1938 return (r_ecr(ppc)); 1939 case PPB_RFIFO: 1940 return (r_fifo(ppc)); 1941 case PPB_WDTR: 1942 w_dtr(ppc, byte); 1943 break; 1944 case PPB_WSTR: 1945 w_str(ppc, byte); 1946 break; 1947 case PPB_WCTR: 1948 w_ctr(ppc, byte); 1949 break; 1950 case PPB_WEPP_A: 1951 w_epp_A(ppc, byte); 1952 break; 1953 case PPB_WEPP_D: 1954 w_epp_D(ppc, byte); 1955 break; 1956 case PPB_WECR: 1957 w_ecr(ppc, byte); 1958 break; 1959 case PPB_WFIFO: 1960 w_fifo(ppc, byte); 1961 break; 1962 default: 1963 panic("%s: unknown I/O operation", __func__); 1964 break; 1965 } 1966 1967 return (0); /* not significative */ 1968} 1969 1970int 1971ppc_read_ivar(device_t bus, device_t dev, int index, uintptr_t *val) 1972{ 1973 struct ppc_data *ppc = (struct ppc_data *)device_get_softc(bus); 1974 1975 switch (index) { 1976 case PPC_IVAR_EPP_PROTO: 1977 PPC_ASSERT_LOCKED(ppc); 1978 *val = (u_long)ppc->ppc_epp; 1979 break; 1980 case PPC_IVAR_LOCK: 1981 *val = (uintptr_t)&ppc->ppc_lock; 1982 break; 1983 default: 1984 return (ENOENT); 1985 } 1986 1987 return (0); 1988} 1989 1990int 1991ppc_write_ivar(device_t bus, device_t dev, int index, uintptr_t val) 1992{ 1993 struct ppc_data *ppc = (struct ppc_data *)device_get_softc(bus); 1994 1995 switch (index) { 1996 case PPC_IVAR_INTR_HANDLER: 1997 PPC_ASSERT_LOCKED(ppc); 1998 if (dev != ppc->ppbus) 1999 return (EINVAL); 2000 if (val == 0) { 2001 ppc->ppc_intr_hook = NULL; 2002 break; 2003 } 2004 if (ppc->ppc_intr_hook != NULL) 2005 return (EBUSY); 2006 ppc->ppc_intr_hook = (void *)val; 2007 ppc->ppc_intr_arg = device_get_softc(dev); 2008 break; 2009 default: 2010 return (ENOENT); 2011 } 2012 2013 return (0); 2014} 2015 2016/* 2017 * We allow child devices to allocate an IRQ resource at rid 0 for their 2018 * interrupt handlers. 2019 */ 2020struct resource * 2021ppc_alloc_resource(device_t bus, device_t child, int type, int *rid, 2022 rman_res_t start, rman_res_t end, rman_res_t count, u_int flags) 2023{ 2024 struct ppc_data *ppc = DEVTOSOFTC(bus); 2025 2026 switch (type) { 2027 case SYS_RES_IRQ: 2028 if (*rid == 0) 2029 return (ppc->res_irq); 2030 break; 2031 } 2032 return (NULL); 2033} 2034 2035int 2036ppc_release_resource(device_t bus, device_t child, int type, int rid, 2037 struct resource *r) 2038{ 2039#ifdef INVARIANTS 2040 struct ppc_data *ppc = DEVTOSOFTC(bus); 2041#endif 2042 2043 switch (type) { 2044 case SYS_RES_IRQ: 2045 if (rid == 0) { 2046 KASSERT(r == ppc->res_irq, 2047 ("ppc child IRQ resource mismatch")); 2048 return (0); 2049 } 2050 break; 2051 } 2052 return (EINVAL); 2053} 2054 2055MODULE_DEPEND(ppc, ppbus, 1, 1, 1); 2056