1 /* $NetBSD: pci_machdep.c,v 1.42 2004/08/30 15:05:16 drochner Exp $ */ 2 3 /* 4 * Copyright (c) 1996 Leo Weppelman. All rights reserved. 5 * Copyright (c) 1996, 1997 Christopher G. Demetriou. All rights reserved. 6 * Copyright (c) 1994 Charles M. Hannum. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. All advertising materials mentioning features or use of this software 17 * must display the following acknowledgement: 18 * This product includes software developed by Charles M. Hannum. 19 * 4. The name of the author may not be used to endorse or promote products 20 * derived from this software without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 #include <sys/cdefs.h> 35 __KERNEL_RCSID(0, "$NetBSD: pci_machdep.c,v 1.42 2004/08/30 15:05:16 drochner Exp $"); 36 37 #include "opt_mbtype.h" 38 39 #include <sys/types.h> 40 #include <sys/param.h> 41 #include <sys/time.h> 42 #include <sys/systm.h> 43 #include <sys/errno.h> 44 #include <sys/device.h> 45 #include <sys/malloc.h> 46 47 #define _ATARI_BUS_DMA_PRIVATE 48 #include <machine/bus.h> 49 50 #include <dev/pci/pcivar.h> 51 #include <dev/pci/pcireg.h> 52 53 #include <uvm/uvm_extern.h> 54 55 #include <machine/cpu.h> 56 #include <machine/iomap.h> 57 #include <machine/mfp.h> 58 59 #include <atari/atari/device.h> 60 #include <atari/pci/pci_vga.h> 61 62 /* 63 * Sizes of pci memory and I/O area. 64 */ 65 #define PCI_MEM_END 0x10000000 /* 256 MByte */ 66 #define PCI_IO_END 0x10000000 /* 256 MByte */ 67 68 /* 69 * We preserve some space at the begin of the pci area for 32BIT_1M 70 * devices and standard vga. 71 */ 72 #define PCI_MEM_START 0x00100000 /* 1 MByte */ 73 #define PCI_IO_START 0x00004000 /* 16 kByte (some PCI cards allow only 74 I/O addresses up to 0xffff) */ 75 76 /* 77 * PCI memory and IO should be aligned acording to this masks 78 */ 79 #define PCI_MACHDEP_IO_ALIGN_MASK 0xffffff00 80 #define PCI_MACHDEP_MEM_ALIGN_MASK 0xfffff000 81 82 /* 83 * Convert a PCI 'device' number to a slot number. 84 */ 85 #define DEV2SLOT(dev) (3 - dev) 86 87 /* 88 * Struct to hold the memory and I/O datas of the pci devices 89 */ 90 struct pci_memreg { 91 LIST_ENTRY(pci_memreg) link; 92 int dev; 93 pcitag_t tag; 94 pcireg_t reg, address, mask; 95 u_int32_t size; 96 u_int32_t csr; 97 }; 98 99 typedef LIST_HEAD(pci_memreg_head, pci_memreg) PCI_MEMREG; 100 101 /* 102 * Entry points for PCI DMA. Use only the 'standard' functions. 103 */ 104 int _bus_dmamap_create __P((bus_dma_tag_t, bus_size_t, int, bus_size_t, 105 bus_size_t, int, bus_dmamap_t *)); 106 struct atari_bus_dma_tag pci_bus_dma_tag = { 107 0, 108 #if defined(_ATARIHW_) 109 0x80000000, /* On the Hades, CPU memory starts here PCI-wise */ 110 #else 111 0, 112 #endif 113 _bus_dmamap_create, 114 _bus_dmamap_destroy, 115 _bus_dmamap_load, 116 _bus_dmamap_load_mbuf, 117 _bus_dmamap_load_uio, 118 _bus_dmamap_load_raw, 119 _bus_dmamap_unload, 120 _bus_dmamap_sync, 121 }; 122 123 int ataripcibusprint __P((void *auxp, const char *)); 124 int pcibusmatch __P((struct device *, struct cfdata *, void *)); 125 void pcibusattach __P((struct device *, struct device *, void *)); 126 127 static void enable_pci_devices __P((void)); 128 static void insert_into_list __P((PCI_MEMREG *head, struct pci_memreg *elem)); 129 static int overlap_pci_areas __P((struct pci_memreg *p, 130 struct pci_memreg *self, u_int addr, u_int size, u_int what)); 131 132 CFATTACH_DECL(pcib, sizeof(struct device), 133 pcibusmatch, pcibusattach, NULL, NULL); 134 135 /* 136 * We need some static storage to probe pci-busses for VGA cards during 137 * early console init. 138 */ 139 static struct atari_bus_space bs_storage[2]; /* 1 iot, 1 memt */ 140 141 int 142 pcibusmatch(pdp, cfp, auxp) 143 struct device *pdp; 144 struct cfdata *cfp; 145 void *auxp; 146 { 147 static int nmatched = 0; 148 149 if (strcmp((char *)auxp, "pcib")) 150 return (0); /* Wrong number... */ 151 152 if(atari_realconfig == 0) 153 return (1); 154 155 if (machineid & (ATARI_HADES|ATARI_MILAN)) { 156 /* 157 * Both Hades and Milan have only one pci bus 158 */ 159 if (nmatched) 160 return (0); 161 nmatched++; 162 return (1); 163 } 164 return (0); 165 } 166 167 void 168 pcibusattach(pdp, dp, auxp) 169 struct device *pdp, *dp; 170 void *auxp; 171 { 172 struct pcibus_attach_args pba; 173 174 pba.pba_pc = NULL; 175 pba.pba_bus = 0; 176 pba.pba_bridgetag = NULL; 177 pba.pba_flags = PCI_FLAGS_IO_ENABLED | PCI_FLAGS_MEM_ENABLED; 178 pba.pba_dmat = &pci_bus_dma_tag; 179 pba.pba_iot = leb_alloc_bus_space_tag(&bs_storage[0]); 180 pba.pba_memt = leb_alloc_bus_space_tag(&bs_storage[1]); 181 if ((pba.pba_iot == NULL) || (pba.pba_memt == NULL)) { 182 printf("leb_alloc_bus_space_tag failed!\n"); 183 return; 184 } 185 pba.pba_iot->base = PCI_IO_PHYS; 186 pba.pba_memt->base = PCI_MEM_PHYS; 187 188 if (dp == NULL) { 189 /* 190 * Scan the bus for a VGA-card that we support. If we 191 * find one, try to initialize it to a 'standard' text 192 * mode (80x25). 193 */ 194 check_for_vga(pba.pba_iot, pba.pba_memt); 195 return; 196 } 197 198 enable_pci_devices(); 199 200 #if defined(_ATARIHW_) 201 MFP2->mf_aer &= ~(0x27); /* PCI interrupts: HIGH -> LOW */ 202 #endif 203 204 printf("\n"); 205 206 config_found_ia(dp, "pcibus", &pba, ataripcibusprint); 207 } 208 209 int 210 ataripcibusprint(auxp, name) 211 void *auxp; 212 const char *name; 213 { 214 if(name == NULL) 215 return(UNCONF); 216 return(QUIET); 217 } 218 219 void 220 pci_attach_hook(parent, self, pba) 221 struct device *parent, *self; 222 struct pcibus_attach_args *pba; 223 { 224 } 225 226 /* 227 * Initialize the PCI-bus. The Atari-BIOS does not do this, so.... 228 * We only disable all devices here. Memory and I/O enabling is done 229 * later at pcibusattach. 230 */ 231 void 232 init_pci_bus() 233 { 234 pci_chipset_tag_t pc = NULL; /* XXX */ 235 pcitag_t tag; 236 pcireg_t csr; 237 int device, id, maxndevs; 238 239 tag = 0; 240 id = 0; 241 242 maxndevs = pci_bus_maxdevs(pc, 0); 243 244 for (device = 0; device < maxndevs; device++) { 245 246 tag = pci_make_tag(pc, 0, device, 0); 247 id = pci_conf_read(pc, tag, PCI_ID_REG); 248 if (id == 0 || id == 0xffffffff) 249 continue; 250 251 csr = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG); 252 csr &= ~(PCI_COMMAND_MEM_ENABLE|PCI_COMMAND_IO_ENABLE); 253 csr &= ~PCI_COMMAND_MASTER_ENABLE; 254 pci_conf_write(pc, tag, PCI_COMMAND_STATUS_REG, csr); 255 } 256 } 257 258 /* 259 * insert a new element in an existing list that the ID's (size in struct 260 * pci_memreg) are sorted. 261 */ 262 static void 263 insert_into_list(head, elem) 264 PCI_MEMREG *head; 265 struct pci_memreg *elem; 266 { 267 struct pci_memreg *p, *q; 268 269 p = LIST_FIRST(head); 270 q = NULL; 271 272 for (; p != NULL && p->size < elem->size; q = p, p = LIST_NEXT(p, link)); 273 274 if (q == NULL) { 275 LIST_INSERT_HEAD(head, elem, link); 276 } else { 277 LIST_INSERT_AFTER(q, elem, link); 278 } 279 } 280 281 /* 282 * Test if a new selected area overlaps with an already (probably preselected) 283 * pci area. 284 */ 285 static int 286 overlap_pci_areas(p, self, addr, size, what) 287 struct pci_memreg *p, *self; 288 u_int addr, size, what; 289 { 290 struct pci_memreg *q; 291 292 if (p == NULL) 293 return 0; 294 295 q = p; 296 while (q != NULL) { 297 if ((q != self) && (q->csr & what)) { 298 if ((addr >= q->address) && (addr < (q->address + q->size))) { 299 #ifdef DEBUG_PCI_MACHDEP 300 printf("\noverlap area dev %d reg 0x%02x with dev %d reg 0x%02x", 301 self->dev, self->reg, q->dev, q->reg); 302 #endif 303 return 1; 304 } 305 if ((q->address >= addr) && (q->address < (addr + size))) { 306 #ifdef DEBUG_PCI_MACHDEP 307 printf("\noverlap area dev %d reg 0x%02x with dev %d reg 0x%02x", 308 self->dev, self->reg, q->dev, q->reg); 309 #endif 310 return 1; 311 } 312 } 313 q = LIST_NEXT(q, link); 314 } 315 return 0; 316 } 317 318 /* 319 * Enable memory and I/O on pci devices. Care about already enabled devices 320 * (probabaly by the console driver). 321 * 322 * The idea behind the following code is: 323 * We build a by sizes sorted list of the requirements of the different 324 * pci devices. After that we choose the start addresses of that areas 325 * in such a way that they are placed as closed as possible together. 326 */ 327 static void 328 enable_pci_devices() 329 { 330 PCI_MEMREG memlist; 331 PCI_MEMREG iolist; 332 struct pci_memreg *p, *q; 333 int dev, reg, id, class; 334 pcitag_t tag; 335 pcireg_t csr, address, mask; 336 pci_chipset_tag_t pc; 337 int sizecnt, membase_1m; 338 339 pc = 0; 340 csr = 0; 341 tag = 0; 342 343 LIST_INIT(&memlist); 344 LIST_INIT(&iolist); 345 346 /* 347 * first step: go through all devices and gather memory and I/O 348 * sizes 349 */ 350 for (dev = 0; dev < pci_bus_maxdevs(pc,0); dev++) { 351 352 tag = pci_make_tag(pc, 0, dev, 0); 353 id = pci_conf_read(pc, tag, PCI_ID_REG); 354 if (id == 0 || id == 0xffffffff) 355 continue; 356 357 csr = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG); 358 359 /* 360 * special case: if a display card is found and memory is enabled 361 * preserve 128k at 0xa0000 as vga memory. 362 * XXX: if a display card is found without being enabled, leave 363 * it alone! You will usually only create conflicts by enabeling 364 * it. 365 */ 366 class = pci_conf_read(pc, tag, PCI_CLASS_REG); 367 switch (PCI_CLASS(class)) { 368 case PCI_CLASS_PREHISTORIC: 369 case PCI_CLASS_DISPLAY: 370 if (csr & (PCI_COMMAND_MEM_ENABLE | PCI_COMMAND_MASTER_ENABLE)) { 371 p = (struct pci_memreg *)malloc(sizeof(struct pci_memreg), 372 M_TEMP, M_WAITOK); 373 memset(p, '\0', sizeof(struct pci_memreg)); 374 p->dev = dev; 375 p->csr = csr; 376 p->tag = tag; 377 p->reg = 0; /* there is no register about this */ 378 p->size = 0x20000; /* 128kByte */ 379 p->mask = 0xfffe0000; 380 p->address = 0xa0000; 381 382 insert_into_list(&memlist, p); 383 } 384 else continue; 385 } 386 387 for (reg = PCI_MAPREG_START; reg < PCI_MAPREG_END; reg += 4) { 388 389 address = pci_conf_read(pc, tag, reg); 390 pci_conf_write(pc, tag, reg, 0xffffffff); 391 mask = pci_conf_read(pc, tag, reg); 392 pci_conf_write(pc, tag, reg, address); 393 if (mask == 0) 394 continue; /* Register unused */ 395 396 p = (struct pci_memreg *)malloc(sizeof(struct pci_memreg), 397 M_TEMP, M_WAITOK); 398 memset(p, '\0', sizeof(struct pci_memreg)); 399 p->dev = dev; 400 p->csr = csr; 401 p->tag = tag; 402 p->reg = reg; 403 p->mask = mask; 404 p->address = 0; 405 406 if (mask & PCI_MAPREG_TYPE_IO) { 407 p->size = PCI_MAPREG_IO_SIZE(mask); 408 409 /* 410 * Align IO if necessary 411 */ 412 if (p->size < PCI_MAPREG_IO_SIZE(PCI_MACHDEP_IO_ALIGN_MASK)) { 413 p->mask = PCI_MACHDEP_IO_ALIGN_MASK; 414 p->size = PCI_MAPREG_IO_SIZE(p->mask); 415 } 416 417 /* 418 * if I/O is already enabled (probably by the console driver) 419 * save the address in order to take care about it later. 420 */ 421 if (csr & PCI_COMMAND_IO_ENABLE) 422 p->address = address; 423 424 insert_into_list(&iolist, p); 425 } else { 426 p->size = PCI_MAPREG_MEM_SIZE(mask); 427 428 /* 429 * Align memory if necessary 430 */ 431 if (p->size < PCI_MAPREG_IO_SIZE(PCI_MACHDEP_MEM_ALIGN_MASK)) { 432 p->mask = PCI_MACHDEP_MEM_ALIGN_MASK; 433 p->size = PCI_MAPREG_MEM_SIZE(p->mask); 434 } 435 436 /* 437 * if memory is already enabled (probably by the console driver) 438 * save the address in order to take care about it later. 439 */ 440 if (csr & PCI_COMMAND_MEM_ENABLE) 441 p->address = address; 442 443 insert_into_list(&memlist, p); 444 445 if (PCI_MAPREG_MEM_TYPE(mask) == PCI_MAPREG_MEM_TYPE_64BIT) 446 reg++; 447 } 448 } 449 450 451 #if defined(_ATARIHW_) 452 /* 453 * Both interrupt pin & line are set to the device (== slot) 454 * number. This makes sense on the atari Hades because the 455 * individual slots are hard-wired to a specific MFP-pin. 456 */ 457 csr = (DEV2SLOT(dev) << PCI_INTERRUPT_PIN_SHIFT); 458 csr |= (DEV2SLOT(dev) << PCI_INTERRUPT_LINE_SHIFT); 459 pci_conf_write(pc, tag, PCI_INTERRUPT_REG, csr); 460 #else 461 /* 462 * On the Milan, we accept the BIOS's choice. 463 */ 464 #endif 465 } 466 467 /* 468 * second step: calculate the memory and I/O addresses beginning from 469 * PCI_MEM_START and PCI_IO_START. Care about already mapped areas. 470 * 471 * begin with memory list 472 */ 473 474 address = PCI_MEM_START; 475 sizecnt = 0; 476 membase_1m = 0; 477 p = LIST_FIRST(&memlist); 478 while (p != NULL) { 479 if (!(p->csr & PCI_COMMAND_MEM_ENABLE)) { 480 if (PCI_MAPREG_MEM_TYPE(p->mask) == PCI_MAPREG_MEM_TYPE_32BIT_1M) { 481 if (p->size > membase_1m) 482 membase_1m = p->size; 483 do { 484 p->address = membase_1m; 485 membase_1m += p->size; 486 } while (overlap_pci_areas(LIST_FIRST(&memlist), p, p->address, 487 p->size, PCI_COMMAND_MEM_ENABLE)); 488 if (membase_1m > 0x00100000) { 489 /* 490 * Should we panic here? 491 */ 492 printf("\npcibus0: dev %d reg %d: memory not configured", 493 p->dev, p->reg); 494 p->reg = 0; 495 } 496 } else { 497 498 if (sizecnt && (p->size > sizecnt)) 499 sizecnt = ((p->size + sizecnt) & p->mask) & 500 PCI_MAPREG_MEM_ADDR_MASK; 501 if (sizecnt > address) { 502 address = sizecnt; 503 sizecnt = 0; 504 } 505 506 do { 507 p->address = address + sizecnt; 508 sizecnt += p->size; 509 } while (overlap_pci_areas(LIST_FIRST(&memlist), p, p->address, 510 p->size, PCI_COMMAND_MEM_ENABLE)); 511 512 if ((address + sizecnt) > PCI_MEM_END) { 513 /* 514 * Should we panic here? 515 */ 516 printf("\npcibus0: dev %d reg %d: memory not configured", 517 p->dev, p->reg); 518 p->reg = 0; 519 } 520 } 521 if (p->reg > 0) { 522 pci_conf_write(pc, p->tag, p->reg, p->address); 523 csr = pci_conf_read(pc, p->tag, PCI_COMMAND_STATUS_REG); 524 csr |= PCI_COMMAND_MEM_ENABLE | PCI_COMMAND_MASTER_ENABLE; 525 pci_conf_write(pc, p->tag, PCI_COMMAND_STATUS_REG, csr); 526 p->csr = csr; 527 } 528 } 529 p = LIST_NEXT(p, link); 530 } 531 532 /* 533 * now the I/O list 534 */ 535 536 address = PCI_IO_START; 537 sizecnt = 0; 538 p = LIST_FIRST(&iolist); 539 while (p != NULL) { 540 if (!(p->csr & PCI_COMMAND_IO_ENABLE)) { 541 542 if (sizecnt && (p->size > sizecnt)) 543 sizecnt = ((p->size + sizecnt) & p->mask) & 544 PCI_MAPREG_IO_ADDR_MASK; 545 if (sizecnt > address) { 546 address = sizecnt; 547 sizecnt = 0; 548 } 549 550 do { 551 p->address = address + sizecnt; 552 sizecnt += p->size; 553 } while (overlap_pci_areas(LIST_FIRST(&iolist), p, p->address, 554 p->size, PCI_COMMAND_IO_ENABLE)); 555 556 if ((address + sizecnt) > PCI_IO_END) { 557 /* 558 * Should we panic here? 559 */ 560 printf("\npcibus0: dev %d reg %d: io not configured", 561 p->dev, p->reg); 562 } else { 563 pci_conf_write(pc, p->tag, p->reg, p->address); 564 csr = pci_conf_read(pc, p->tag, PCI_COMMAND_STATUS_REG); 565 csr |= PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MASTER_ENABLE; 566 pci_conf_write(pc, p->tag, PCI_COMMAND_STATUS_REG, csr); 567 p->csr = csr; 568 } 569 } 570 p = LIST_NEXT(p, link); 571 } 572 573 #ifdef DEBUG_PCI_MACHDEP 574 printf("\nI/O List:\n"); 575 p = LIST_FIRST(&iolist); 576 577 while (p != NULL) { 578 printf("\ndev: %d, reg: 0x%02x, size: 0x%08x, addr: 0x%08x", p->dev, 579 p->reg, p->size, p->address); 580 p = LIST_NEXT(p, link); 581 } 582 printf("\nMemlist:"); 583 p = LIST_FIRST(&memlist); 584 585 while (p != NULL) { 586 printf("\ndev: %d, reg: 0x%02x, size: 0x%08x, addr: 0x%08x", p->dev, 587 p->reg, p->size, p->address); 588 p = LIST_NEXT(p, link); 589 } 590 #endif 591 592 /* 593 * Free the lists 594 */ 595 p = LIST_FIRST(&iolist); 596 while (p != NULL) { 597 q = p; 598 LIST_REMOVE(q, link); 599 free(p, M_WAITOK); 600 p = LIST_FIRST(&iolist); 601 } 602 p = LIST_FIRST(&memlist); 603 while (p != NULL) { 604 q = p; 605 LIST_REMOVE(q, link); 606 free(p, M_WAITOK); 607 p = LIST_FIRST(&memlist); 608 } 609 } 610 611 pcitag_t 612 pci_make_tag(pc, bus, device, function) 613 pci_chipset_tag_t pc; 614 int bus, device, function; 615 { 616 return ((bus << 16) | (device << 11) | (function << 8)); 617 } 618 619 void 620 pci_decompose_tag(pc, tag, bp, dp, fp) 621 pci_chipset_tag_t pc; 622 pcitag_t tag; 623 int *bp, *dp, *fp; 624 { 625 626 if (bp != NULL) 627 *bp = (tag >> 16) & 0xff; 628 if (dp != NULL) 629 *dp = (tag >> 11) & 0x1f; 630 if (fp != NULL) 631 *fp = (tag >> 8) & 0x7; 632 } 633 634 int 635 pci_intr_map(pa, ihp) 636 struct pci_attach_args *pa; 637 pci_intr_handle_t *ihp; 638 { 639 int line = pa->pa_intrline; 640 641 #if defined(_MILANHW_) 642 /* 643 * On the Hades, the 'pin' info is useless. 644 */ 645 { 646 int pin = pa->pa_intrpin; 647 648 if (pin == 0) { 649 /* No IRQ used. */ 650 goto bad; 651 } 652 if (pin > PCI_INTERRUPT_PIN_MAX) { 653 printf("pci_intr_map: bad interrupt pin %d\n", pin); 654 goto bad; 655 } 656 } 657 #endif /* _MILANHW_ */ 658 659 /* 660 * According to the PCI-spec, 255 means `unknown' or `no connection'. 661 * Interpret this as 'no interrupt assigned'. 662 */ 663 if (line == 255) 664 goto bad; 665 666 /* 667 * Values are pretty useless on the Hades since all interrupt 668 * lines for a card are tied together and hardwired to a 669 * specific TT-MFP I/O port. 670 * On the Milan, they are tied to the ICU. 671 */ 672 #if defined(_MILANHW_) 673 if (line >= 16) { 674 printf("pci_intr_map: bad interrupt line %d\n", line); 675 goto bad; 676 } 677 if (line == 2) { 678 printf("pci_intr_map: changed line 2 to line 9\n"); 679 line = 9; 680 } 681 /* Assume line == 0 means unassigned */ 682 if (line == 0) 683 goto bad; 684 #endif 685 *ihp = line; 686 return 0; 687 688 bad: 689 *ihp = -1; 690 return 1; 691 } 692 693 const char * 694 pci_intr_string(pc, ih) 695 pci_chipset_tag_t pc; 696 pci_intr_handle_t ih; 697 { 698 static char irqstr[8]; /* 4 + 2 + NULL + sanity */ 699 700 if (ih == -1) 701 panic("pci_intr_string: bogus handle 0x%x", ih); 702 703 sprintf(irqstr, "irq %d", ih); 704 return (irqstr); 705 706 } 707 708 const struct evcnt * 709 pci_intr_evcnt(pc, ih) 710 pci_chipset_tag_t pc; 711 pci_intr_handle_t ih; 712 { 713 714 /* XXX for now, no evcnt parent reported */ 715 return NULL; 716 } 717