1 /* $NetBSD: sio_pic.c,v 1.46 2020/09/29 01:19:52 thorpej Exp $ */ 2 3 /*- 4 * Copyright (c) 1998, 2000, 2020 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, 9 * NASA Ames Research Center. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 * POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 /* 34 * Copyright (c) 1995, 1996 Carnegie-Mellon University. 35 * All rights reserved. 36 * 37 * Author: Chris G. Demetriou 38 * 39 * Permission to use, copy, modify and distribute this software and 40 * its documentation is hereby granted, provided that both the copyright 41 * notice and this permission notice appear in all copies of the 42 * software, derivative works or modified versions, and any portions 43 * thereof, and that both notices appear in supporting documentation. 44 * 45 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 46 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND 47 * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 48 * 49 * Carnegie Mellon requests users of this software to return to 50 * 51 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 52 * School of Computer Science 53 * Carnegie Mellon University 54 * Pittsburgh PA 15213-3890 55 * 56 * any improvements or extensions that they make and grant Carnegie the 57 * rights to redistribute these changes. 58 */ 59 60 #include <sys/cdefs.h> /* RCS ID & Copyright macro defns */ 61 62 __KERNEL_RCSID(0, "$NetBSD: sio_pic.c,v 1.46 2020/09/29 01:19:52 thorpej Exp $"); 63 64 #include <sys/param.h> 65 #include <sys/systm.h> 66 #include <sys/device.h> 67 #include <sys/malloc.h> 68 #include <sys/cpu.h> 69 #include <sys/syslog.h> 70 71 #include <machine/alpha.h> 72 #include <machine/intr.h> 73 #include <sys/bus.h> 74 75 #include <dev/pci/pcireg.h> 76 #include <dev/pci/pcivar.h> 77 #include <dev/pci/pcidevs.h> 78 79 #include <dev/pci/pciidereg.h> 80 #include <dev/pci/pciidevar.h> 81 82 #include <dev/pci/cy82c693reg.h> 83 #include <dev/pci/cy82c693var.h> 84 85 #include <dev/isa/isareg.h> 86 #include <dev/isa/isavar.h> 87 #include <alpha/pci/siovar.h> 88 89 #include "sio.h" 90 91 /* 92 * To add to the long history of wonderful PROM console traits, 93 * AlphaStation PROMs don't reset themselves completely on boot! 94 * Therefore, if an interrupt was turned on when the kernel was 95 * started, we're not going to EVER turn it off... I don't know 96 * what will happen if new interrupts (that the PROM console doesn't 97 * want) are turned on. I'll burn that bridge when I come to it. 98 */ 99 #define BROKEN_PROM_CONSOLE 100 101 /* 102 * Private functions and variables. 103 */ 104 105 bus_space_tag_t sio_iot; 106 pci_chipset_tag_t sio_pc; 107 bus_space_handle_t sio_ioh_icu1, sio_ioh_icu2; 108 109 #define ICU_LEN 16 /* number of ISA IRQs */ 110 111 static struct alpha_shared_intr *sio_intr; 112 113 #ifndef STRAY_MAX 114 #define STRAY_MAX 5 115 #endif 116 117 #ifdef BROKEN_PROM_CONSOLE 118 /* 119 * If prom console is broken, must remember the initial interrupt 120 * settings and enforce them. WHEE! 121 */ 122 uint8_t initial_ocw1[2]; 123 uint8_t initial_elcr[2]; 124 #endif 125 126 void sio_setirqstat(int, int, int); 127 128 uint8_t (*sio_read_elcr)(int); 129 void (*sio_write_elcr)(int, uint8_t); 130 static void specific_eoi(int); 131 #ifdef BROKEN_PROM_CONSOLE 132 void sio_intr_shutdown(void *); 133 #endif 134 135 /******************** i82378 SIO ELCR functions ********************/ 136 137 int i82378_setup_elcr(void); 138 uint8_t i82378_read_elcr(int); 139 void i82378_write_elcr(int, uint8_t); 140 141 bus_space_handle_t sio_ioh_elcr; 142 143 int 144 i82378_setup_elcr(void) 145 { 146 int rv; 147 148 /* 149 * We could probe configuration space to see that there's 150 * actually an SIO present, but we are using this as a 151 * fall-back in case nothing else matches. 152 */ 153 154 rv = bus_space_map(sio_iot, 0x4d0, 2, 0, &sio_ioh_elcr); 155 156 if (rv == 0) { 157 sio_read_elcr = i82378_read_elcr; 158 sio_write_elcr = i82378_write_elcr; 159 } 160 161 return (rv); 162 } 163 164 uint8_t 165 i82378_read_elcr(int elcr) 166 { 167 168 return (bus_space_read_1(sio_iot, sio_ioh_elcr, elcr)); 169 } 170 171 void 172 i82378_write_elcr(int elcr, uint8_t val) 173 { 174 175 bus_space_write_1(sio_iot, sio_ioh_elcr, elcr, val); 176 } 177 178 /******************** Cypress CY82C693 ELCR functions ********************/ 179 180 int cy82c693_setup_elcr(void); 181 uint8_t cy82c693_read_elcr(int); 182 void cy82c693_write_elcr(int, uint8_t); 183 184 const struct cy82c693_handle *sio_cy82c693_handle; 185 186 int 187 cy82c693_setup_elcr(void) 188 { 189 int device, maxndevs; 190 pcitag_t tag; 191 pcireg_t id; 192 193 /* 194 * Search PCI configuration space for a Cypress CY82C693. 195 * 196 * Note we can make some assumptions about our bus number 197 * here, because: 198 * 199 * (1) there can be at most one ISA/EISA bridge per PCI bus, and 200 * 201 * (2) any ISA/EISA bridges must be attached to primary PCI 202 * busses (i.e. bus zero). 203 */ 204 205 maxndevs = pci_bus_maxdevs(sio_pc, 0); 206 207 for (device = 0; device < maxndevs; device++) { 208 tag = pci_make_tag(sio_pc, 0, device, 0); 209 id = pci_conf_read(sio_pc, tag, PCI_ID_REG); 210 211 /* Invalid vendor ID value? */ 212 if (PCI_VENDOR(id) == PCI_VENDOR_INVALID) 213 continue; 214 /* XXX Not invalid, but we've done this ~forever. */ 215 if (PCI_VENDOR(id) == 0) 216 continue; 217 218 if (PCI_VENDOR(id) != PCI_VENDOR_CONTAQ || 219 PCI_PRODUCT(id) != PCI_PRODUCT_CONTAQ_82C693) 220 continue; 221 222 /* 223 * Found one! 224 */ 225 226 #if 0 227 printf("cy82c693_setup_elcr: found 82C693 at device %d\n", 228 device); 229 #endif 230 231 sio_cy82c693_handle = cy82c693_init(sio_iot); 232 sio_read_elcr = cy82c693_read_elcr; 233 sio_write_elcr = cy82c693_write_elcr; 234 235 return (0); 236 } 237 238 /* 239 * Didn't find a CY82C693. 240 */ 241 return (ENODEV); 242 } 243 244 uint8_t 245 cy82c693_read_elcr(int elcr) 246 { 247 248 return (cy82c693_read(sio_cy82c693_handle, CONFIG_ELCR1 + elcr)); 249 } 250 251 void 252 cy82c693_write_elcr(int elcr, uint8_t val) 253 { 254 255 cy82c693_write(sio_cy82c693_handle, CONFIG_ELCR1 + elcr, val); 256 } 257 258 /******************** ELCR access function configuration ********************/ 259 260 /* 261 * Put the Intel SIO at the end, so we fall back on it if we don't 262 * find anything else. If any of the non-Intel functions find a 263 * matching device, but are unable to map it for whatever reason, 264 * they should panic. 265 */ 266 267 int (*const sio_elcr_setup_funcs[])(void) = { 268 cy82c693_setup_elcr, 269 i82378_setup_elcr, 270 NULL, 271 }; 272 273 /******************** Shared SIO/Cypress functions ********************/ 274 275 void 276 sio_setirqstat(int irq, int enabled, int type) 277 { 278 uint8_t ocw1[2], elcr[2]; 279 int icu, bit; 280 281 #if 0 282 printf("sio_setirqstat: irq %d: %s, %s\n", irq, 283 enabled ? "enabled" : "disabled", isa_intr_typename(type)); 284 #endif 285 286 icu = irq / 8; 287 bit = irq % 8; 288 289 ocw1[0] = bus_space_read_1(sio_iot, sio_ioh_icu1, 1); 290 ocw1[1] = bus_space_read_1(sio_iot, sio_ioh_icu2, 1); 291 elcr[0] = (*sio_read_elcr)(0); /* XXX */ 292 elcr[1] = (*sio_read_elcr)(1); /* XXX */ 293 294 /* 295 * interrupt enable: set bit to mask (disable) interrupt. 296 */ 297 if (enabled) 298 ocw1[icu] &= ~(1 << bit); 299 else 300 ocw1[icu] |= 1 << bit; 301 302 /* 303 * interrupt type select: set bit to get level-triggered. 304 */ 305 if (type == IST_LEVEL) 306 elcr[icu] |= 1 << bit; 307 else 308 elcr[icu] &= ~(1 << bit); 309 310 #ifdef not_here 311 /* see the init function... */ 312 ocw1[0] &= ~0x04; /* always enable IRQ2 on first PIC */ 313 elcr[0] &= ~0x07; /* IRQ[0-2] must be edge-triggered */ 314 elcr[1] &= ~0x21; /* IRQ[13,8] must be edge-triggered */ 315 #endif 316 317 bus_space_write_1(sio_iot, sio_ioh_icu1, 1, ocw1[0]); 318 bus_space_write_1(sio_iot, sio_ioh_icu2, 1, ocw1[1]); 319 (*sio_write_elcr)(0, elcr[0]); /* XXX */ 320 (*sio_write_elcr)(1, elcr[1]); /* XXX */ 321 } 322 323 void 324 sio_intr_setup(pci_chipset_tag_t pc, bus_space_tag_t iot) 325 { 326 char *cp; 327 int i; 328 329 sio_iot = iot; 330 sio_pc = pc; 331 332 if (bus_space_map(sio_iot, IO_ICU1, 2, 0, &sio_ioh_icu1) || 333 bus_space_map(sio_iot, IO_ICU2, 2, 0, &sio_ioh_icu2)) 334 panic("sio_intr_setup: can't map ICU I/O ports"); 335 336 for (i = 0; sio_elcr_setup_funcs[i] != NULL; i++) 337 if ((*sio_elcr_setup_funcs[i])() == 0) 338 break; 339 if (sio_elcr_setup_funcs[i] == NULL) 340 panic("sio_intr_setup: can't map ELCR"); 341 342 #ifdef BROKEN_PROM_CONSOLE 343 /* 344 * Remember the initial values, so we can restore them later. 345 */ 346 initial_ocw1[0] = bus_space_read_1(sio_iot, sio_ioh_icu1, 1); 347 initial_ocw1[1] = bus_space_read_1(sio_iot, sio_ioh_icu2, 1); 348 initial_elcr[0] = (*sio_read_elcr)(0); /* XXX */ 349 initial_elcr[1] = (*sio_read_elcr)(1); /* XXX */ 350 shutdownhook_establish(sio_intr_shutdown, 0); 351 #endif 352 353 #define PCI_SIO_IRQ_STR 8 354 sio_intr = alpha_shared_intr_alloc(ICU_LEN, PCI_SIO_IRQ_STR); 355 356 /* 357 * set up initial values for interrupt enables. 358 */ 359 for (i = 0; i < ICU_LEN; i++) { 360 alpha_shared_intr_set_maxstrays(sio_intr, i, STRAY_MAX); 361 362 cp = alpha_shared_intr_string(sio_intr, i); 363 snprintf(cp, PCI_SIO_IRQ_STR, "irq %d", i); 364 evcnt_attach_dynamic(alpha_shared_intr_evcnt(sio_intr, i), 365 EVCNT_TYPE_INTR, NULL, "isa", cp); 366 367 switch (i) { 368 case 0: 369 case 1: 370 case 8: 371 case 13: 372 /* 373 * IRQs 0, 1, 8, and 13 must always be 374 * edge-triggered. 375 */ 376 sio_setirqstat(i, 0, IST_EDGE); 377 alpha_shared_intr_set_dfltsharetype(sio_intr, i, 378 IST_EDGE); 379 specific_eoi(i); 380 break; 381 382 case 2: 383 /* 384 * IRQ 2 must be edge-triggered, and should be 385 * enabled (otherwise IRQs 8-15 are ignored). 386 */ 387 sio_setirqstat(i, 1, IST_EDGE); 388 alpha_shared_intr_set_dfltsharetype(sio_intr, i, 389 IST_UNUSABLE); 390 break; 391 392 default: 393 /* 394 * Otherwise, disable the IRQ and set its 395 * type to (effectively) "unknown." 396 */ 397 sio_setirqstat(i, 0, IST_NONE); 398 alpha_shared_intr_set_dfltsharetype(sio_intr, i, 399 IST_NONE); 400 specific_eoi(i); 401 break; 402 } 403 } 404 } 405 406 #ifdef BROKEN_PROM_CONSOLE 407 void 408 sio_intr_shutdown(void *arg) 409 { 410 /* 411 * Restore the initial values, to make the PROM happy. 412 */ 413 bus_space_write_1(sio_iot, sio_ioh_icu1, 1, initial_ocw1[0]); 414 bus_space_write_1(sio_iot, sio_ioh_icu2, 1, initial_ocw1[1]); 415 (*sio_write_elcr)(0, initial_elcr[0]); /* XXX */ 416 (*sio_write_elcr)(1, initial_elcr[1]); /* XXX */ 417 } 418 #endif 419 420 const char * 421 sio_intr_string(void *v, int irq, char *buf, size_t len) 422 { 423 if (irq == 0 || irq >= ICU_LEN || irq == 2) 424 panic("%s: bogus isa irq 0x%x", __func__, irq); 425 426 snprintf(buf, len, "isa irq %d", irq); 427 return buf; 428 } 429 430 const struct evcnt * 431 sio_intr_evcnt(void *v, int irq) 432 { 433 434 if (irq == 0 || irq >= ICU_LEN || irq == 2) 435 panic("%s: bogus isa irq 0x%x", __func__, irq); 436 437 return (alpha_shared_intr_evcnt(sio_intr, irq)); 438 } 439 440 void * 441 sio_intr_establish(void *v, int irq, int type, int level, int flags, 442 int (*fn)(void *), void *arg) 443 { 444 void *cookie; 445 446 if (irq > ICU_LEN || type == IST_NONE) 447 panic("sio_intr_establish: bogus irq or type"); 448 449 cookie = alpha_shared_intr_alloc_intrhand(sio_intr, irq, type, level, 450 flags, fn, arg, "isa irq"); 451 452 if (cookie == NULL) 453 return NULL; 454 455 mutex_enter(&cpu_lock); 456 457 if (! alpha_shared_intr_link(sio_intr, cookie, "isa irq")) { 458 mutex_exit(&cpu_lock); 459 alpha_shared_intr_free_intrhand(cookie); 460 return NULL; 461 } 462 463 if (alpha_shared_intr_firstactive(sio_intr, irq)) { 464 scb_set(0x800 + SCB_IDXTOVEC(irq), sio_iointr, NULL); 465 sio_setirqstat(irq, 1, 466 alpha_shared_intr_get_sharetype(sio_intr, irq)); 467 468 /* 469 * I've obsesrved stray ISA interrupts when interacting 470 * with the serial console under Qemu. Work around that 471 * for now by suppressing stray interrupt reporting for 472 * edge-triggered interrupts. 473 */ 474 if (alpha_is_qemu && type == IST_EDGE) { 475 alpha_shared_intr_set_maxstrays(sio_intr, irq, 0); 476 } 477 } 478 479 mutex_exit(&cpu_lock); 480 481 return cookie; 482 } 483 484 void 485 sio_intr_disestablish(void *v, void *cookie) 486 { 487 struct alpha_shared_intrhand *ih = cookie; 488 int ist, irq = ih->ih_num; 489 490 mutex_enter(&cpu_lock); 491 492 /* 493 * Decide if we should disable the interrupt. We must ensure 494 * that: 495 * 496 * - An initially-enabled interrupt is never disabled. 497 * - An initially-LT interrupt is never untyped. 498 */ 499 if (alpha_shared_intr_firstactive(sio_intr, irq)) { 500 /* 501 * IRQs 0, 1, 8, and 13 must always be edge-triggered 502 * (see setup). 503 */ 504 switch (irq) { 505 case 0: 506 case 1: 507 case 8: 508 case 13: 509 /* 510 * If the interrupt was initially level-triggered 511 * a warning was printed in setup. 512 */ 513 ist = IST_EDGE; 514 break; 515 516 default: 517 ist = IST_NONE; 518 break; 519 } 520 sio_setirqstat(irq, 0, ist); 521 alpha_shared_intr_set_dfltsharetype(sio_intr, irq, ist); 522 alpha_shared_intr_set_maxstrays(sio_intr, irq, STRAY_MAX); 523 524 /* Release our SCB vector. */ 525 scb_free(0x800 + SCB_IDXTOVEC(irq)); 526 } 527 528 /* Remove it from the link. */ 529 alpha_shared_intr_unlink(sio_intr, cookie, "isa irq"); 530 531 mutex_exit(&cpu_lock); 532 533 alpha_shared_intr_free_intrhand(cookie); 534 } 535 536 const char * 537 sio_pci_intr_string(pci_chipset_tag_t const pc, pci_intr_handle_t const ih, 538 char * const buf, size_t const len) 539 { 540 const u_int irq = alpha_pci_intr_handle_get_irq(&ih); 541 542 return sio_intr_string(NULL /*XXX*/, irq, buf, len); 543 } 544 545 const struct evcnt * 546 sio_pci_intr_evcnt(pci_chipset_tag_t const pc, pci_intr_handle_t const ih) 547 { 548 const u_int irq = alpha_pci_intr_handle_get_irq(&ih); 549 550 return sio_intr_evcnt(NULL /*XXX*/, irq); 551 } 552 553 void * 554 sio_pci_intr_establish(pci_chipset_tag_t const pc, pci_intr_handle_t ih, 555 int const level, int (*func)(void *), void *arg) 556 { 557 const u_int irq = alpha_pci_intr_handle_get_irq(&ih); 558 const u_int flags = alpha_pci_intr_handle_get_flags(&ih); 559 560 return sio_intr_establish(NULL /*XXX*/, irq, IST_LEVEL, level, flags, 561 func, arg); 562 } 563 564 void 565 sio_pci_intr_disestablish(pci_chipset_tag_t const pc, void *cookie) 566 { 567 sio_intr_disestablish(NULL /*XXX*/, cookie); 568 } 569 570 void * 571 sio_pciide_compat_intr_establish(device_t const dev, 572 const struct pci_attach_args * const pa, 573 int const chan, int (*func)(void *), void *arg) 574 { 575 pci_chipset_tag_t const pc = pa->pa_pc; 576 void *cookie; 577 int bus, irq; 578 char buf[64]; 579 int flags = 0; /* XXX How to pass MPSAFE? */ 580 581 pci_decompose_tag(pc, pa->pa_tag, &bus, NULL, NULL); 582 583 /* 584 * If this isn't PCI bus #0, all bets are off. 585 */ 586 if (bus != 0) 587 return NULL; 588 589 irq = PCIIDE_COMPAT_IRQ(chan); 590 cookie = sio_intr_establish(NULL /*XXX*/, irq, IST_EDGE, IPL_BIO, 591 flags, func, arg); 592 if (cookie == NULL) 593 return NULL; 594 595 aprint_normal_dev(dev, "%s channel interrupting at %s\n", 596 PCIIDE_CHANNEL_NAME(chan), 597 sio_intr_string(NULL /*XXX*/, irq, buf, sizeof(buf))); 598 599 return cookie; 600 } 601 602 void * 603 sio_isa_intr_establish(void *v, int irq, int type, int level, 604 int (*fn)(void *), void *arg) 605 { 606 return sio_intr_establish(v, irq, type, level, 0, fn, arg); 607 } 608 609 void 610 sio_iointr(void *arg, unsigned long vec) 611 { 612 int irq; 613 614 irq = SCB_VECTOIDX(vec - 0x800); 615 616 #ifdef DIAGNOSTIC 617 if (irq > ICU_LEN || irq < 0) 618 panic("sio_iointr: irq out of range (%d)", irq); 619 #endif 620 621 if (!alpha_shared_intr_dispatch(sio_intr, irq)) 622 alpha_shared_intr_stray(sio_intr, irq, "isa irq"); 623 else 624 alpha_shared_intr_reset_strays(sio_intr, irq); 625 626 /* 627 * Some versions of the machines which use the SIO 628 * (or is it some PALcode revisions on those machines?) 629 * require the non-specific EOI to be fed to the PIC(s) 630 * by the interrupt handler. 631 */ 632 specific_eoi(irq); 633 } 634 635 #define LEGAL_IRQ(x) ((x) >= 0 && (x) < ICU_LEN && (x) != 2) 636 637 int 638 sio_intr_alloc(void *v, int mask, int type, int *irq) 639 { 640 int i, tmp, bestirq, count; 641 struct alpha_shared_intrhand **p, *q; 642 643 if (type == IST_NONE) 644 panic("intr_alloc: bogus type"); 645 646 bestirq = -1; 647 count = -1; 648 649 /* some interrupts should never be dynamically allocated */ 650 mask &= 0xdef8; 651 652 /* 653 * XXX some interrupts will be used later (6 for fdc, 12 for pms). 654 * the right answer is to do "breadth-first" searching of devices. 655 */ 656 mask &= 0xefbf; 657 658 for (i = 0; i < ICU_LEN; i++) { 659 if (LEGAL_IRQ(i) == 0 || (mask & (1<<i)) == 0) 660 continue; 661 662 switch(sio_intr[i].intr_sharetype) { 663 case IST_NONE: 664 /* 665 * if nothing's using the irq, just return it 666 */ 667 *irq = i; 668 return (0); 669 670 case IST_EDGE: 671 case IST_LEVEL: 672 if (type != sio_intr[i].intr_sharetype) 673 continue; 674 /* 675 * if the irq is shareable, count the number of other 676 * handlers, and if it's smaller than the last irq like 677 * this, remember it 678 * 679 * XXX We should probably also consider the 680 * interrupt level and stick IPL_TTY with other 681 * IPL_TTY, etc. 682 */ 683 for (p = &TAILQ_FIRST(&sio_intr[i].intr_q), tmp = 0; 684 (q = *p) != NULL; p = &TAILQ_NEXT(q, ih_q), tmp++) 685 ; 686 if ((bestirq == -1) || (count > tmp)) { 687 bestirq = i; 688 count = tmp; 689 } 690 break; 691 692 case IST_PULSE: 693 /* this just isn't shareable */ 694 continue; 695 } 696 } 697 698 if (bestirq == -1) 699 return (1); 700 701 *irq = bestirq; 702 703 return (0); 704 } 705 706 static void 707 specific_eoi(int irq) 708 { 709 if (irq > 7) 710 bus_space_write_1(sio_iot, 711 sio_ioh_icu2, 0, 0x60 | (irq & 0x07)); /* XXX */ 712 bus_space_write_1(sio_iot, sio_ioh_icu1, 0, 0x60 | (irq > 7 ? 2 : irq)); 713 } 714