1 /* 2 * Copyright (c) 1997, Stefan Esser <se@freebsd.org> 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 unmodified, this list of conditions, and the following 10 * disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * 26 * $FreeBSD$ 27 * 28 */ 29 30 #include "opt_bus.h" 31 32 #include "opt_simos.h" 33 34 #include <sys/param.h> 35 #include <sys/systm.h> 36 #include <sys/malloc.h> 37 #include <sys/module.h> 38 #include <sys/fcntl.h> 39 #include <sys/conf.h> 40 #include <sys/kernel.h> 41 #include <sys/queue.h> 42 #include <sys/types.h> 43 #include <sys/buf.h> 44 45 #include <vm/vm.h> 46 #include <vm/pmap.h> 47 #include <vm/vm_extern.h> 48 49 #include <sys/bus.h> 50 #include <machine/bus.h> 51 #include <sys/rman.h> 52 #include <machine/resource.h> 53 #include <machine/md_var.h> /* For the Alpha */ 54 55 #include <pci/pcireg.h> 56 #include <pci/pcivar.h> 57 #include <sys/pciio.h> 58 59 #ifdef APIC_IO 60 #include <machine/smp.h> 61 #endif /* APIC_IO */ 62 63 struct pci_quirk { 64 u_int32_t devid; /* Vendor/device of the card */ 65 int type; 66 #define PCI_QUIRK_MAP_REG 1 /* PCI map register in wierd place */ 67 int arg1; 68 int arg2; 69 }; 70 71 struct pci_quirk pci_quirks[] = { 72 /* 73 * The Intel 82371AB has a map register at offset 0x90. 74 */ 75 { 0x71138086, PCI_QUIRK_MAP_REG, 0x90, 0 }, 76 77 { 0 } 78 }; 79 80 /* map register information */ 81 #define PCI_MAPMEM 0x01 /* memory map */ 82 #define PCI_MAPMEMP 0x02 /* prefetchable memory map */ 83 #define PCI_MAPPORT 0x04 /* port map */ 84 85 struct pci_devinfo { 86 STAILQ_ENTRY(pci_devinfo) pci_links; 87 struct resource_list resources; 88 pcicfgregs cfg; 89 struct pci_conf conf; 90 }; 91 92 static STAILQ_HEAD(devlist, pci_devinfo) pci_devq; 93 u_int32_t pci_numdevs = 0; 94 static u_int32_t pci_generation = 0; 95 96 /* return base address of memory or port map */ 97 98 static u_int32_t 99 pci_mapbase(unsigned mapreg) 100 { 101 int mask = 0x03; 102 if ((mapreg & 0x01) == 0) 103 mask = 0x0f; 104 return (mapreg & ~mask); 105 } 106 107 /* return map type of memory or port map */ 108 109 static int 110 pci_maptype(unsigned mapreg) 111 { 112 static u_int8_t maptype[0x10] = { 113 PCI_MAPMEM, PCI_MAPPORT, 114 PCI_MAPMEM, 0, 115 PCI_MAPMEM, PCI_MAPPORT, 116 0, 0, 117 PCI_MAPMEM|PCI_MAPMEMP, PCI_MAPPORT, 118 PCI_MAPMEM|PCI_MAPMEMP, 0, 119 PCI_MAPMEM|PCI_MAPMEMP, PCI_MAPPORT, 120 0, 0, 121 }; 122 123 return maptype[mapreg & 0x0f]; 124 } 125 126 /* return log2 of map size decoded for memory or port map */ 127 128 static int 129 pci_mapsize(unsigned testval) 130 { 131 int ln2size; 132 133 testval = pci_mapbase(testval); 134 ln2size = 0; 135 if (testval != 0) { 136 while ((testval & 1) == 0) 137 { 138 ln2size++; 139 testval >>= 1; 140 } 141 } 142 return (ln2size); 143 } 144 145 /* return log2 of address range supported by map register */ 146 147 static int 148 pci_maprange(unsigned mapreg) 149 { 150 int ln2range = 0; 151 switch (mapreg & 0x07) { 152 case 0x00: 153 case 0x01: 154 case 0x05: 155 ln2range = 32; 156 break; 157 case 0x02: 158 ln2range = 20; 159 break; 160 case 0x04: 161 ln2range = 64; 162 break; 163 } 164 return (ln2range); 165 } 166 167 /* adjust some values from PCI 1.0 devices to match 2.0 standards ... */ 168 169 static void 170 pci_fixancient(pcicfgregs *cfg) 171 { 172 if (cfg->hdrtype != 0) 173 return; 174 175 /* PCI to PCI bridges use header type 1 */ 176 if (cfg->baseclass == PCIC_BRIDGE && cfg->subclass == PCIS_BRIDGE_PCI) 177 cfg->hdrtype = 1; 178 } 179 180 /* read config data specific to header type 1 device (PCI to PCI bridge) */ 181 182 static void * 183 pci_readppb(pcicfgregs *cfg) 184 { 185 pcih1cfgregs *p; 186 187 p = malloc(sizeof (pcih1cfgregs), M_DEVBUF, M_WAITOK); 188 if (p == NULL) 189 return (NULL); 190 191 bzero(p, sizeof *p); 192 193 p->secstat = pci_cfgread(cfg, PCIR_SECSTAT_1, 2); 194 p->bridgectl = pci_cfgread(cfg, PCIR_BRIDGECTL_1, 2); 195 196 p->seclat = pci_cfgread(cfg, PCIR_SECLAT_1, 1); 197 198 p->iobase = PCI_PPBIOBASE (pci_cfgread(cfg, PCIR_IOBASEH_1, 2), 199 pci_cfgread(cfg, PCIR_IOBASEL_1, 1)); 200 p->iolimit = PCI_PPBIOLIMIT (pci_cfgread(cfg, PCIR_IOLIMITH_1, 2), 201 pci_cfgread(cfg, PCIR_IOLIMITL_1, 1)); 202 203 p->membase = PCI_PPBMEMBASE (0, 204 pci_cfgread(cfg, PCIR_MEMBASE_1, 2)); 205 p->memlimit = PCI_PPBMEMLIMIT (0, 206 pci_cfgread(cfg, PCIR_MEMLIMIT_1, 2)); 207 208 p->pmembase = PCI_PPBMEMBASE ( 209 (pci_addr_t)pci_cfgread(cfg, PCIR_PMBASEH_1, 4), 210 pci_cfgread(cfg, PCIR_PMBASEL_1, 2)); 211 212 p->pmemlimit = PCI_PPBMEMLIMIT ( 213 (pci_addr_t)pci_cfgread(cfg, PCIR_PMLIMITH_1, 4), 214 pci_cfgread(cfg, PCIR_PMLIMITL_1, 2)); 215 return (p); 216 } 217 218 /* read config data specific to header type 2 device (PCI to CardBus bridge) */ 219 220 static void * 221 pci_readpcb(pcicfgregs *cfg) 222 { 223 pcih2cfgregs *p; 224 225 p = malloc(sizeof (pcih2cfgregs), M_DEVBUF, M_WAITOK); 226 if (p == NULL) 227 return (NULL); 228 229 bzero(p, sizeof *p); 230 231 p->secstat = pci_cfgread(cfg, PCIR_SECSTAT_2, 2); 232 p->bridgectl = pci_cfgread(cfg, PCIR_BRIDGECTL_2, 2); 233 234 p->seclat = pci_cfgread(cfg, PCIR_SECLAT_2, 1); 235 236 p->membase0 = pci_cfgread(cfg, PCIR_MEMBASE0_2, 4); 237 p->memlimit0 = pci_cfgread(cfg, PCIR_MEMLIMIT0_2, 4); 238 p->membase1 = pci_cfgread(cfg, PCIR_MEMBASE1_2, 4); 239 p->memlimit1 = pci_cfgread(cfg, PCIR_MEMLIMIT1_2, 4); 240 241 p->iobase0 = pci_cfgread(cfg, PCIR_IOBASE0_2, 4); 242 p->iolimit0 = pci_cfgread(cfg, PCIR_IOLIMIT0_2, 4); 243 p->iobase1 = pci_cfgread(cfg, PCIR_IOBASE1_2, 4); 244 p->iolimit1 = pci_cfgread(cfg, PCIR_IOLIMIT1_2, 4); 245 246 p->pccardif = pci_cfgread(cfg, PCIR_PCCARDIF_2, 4); 247 return p; 248 } 249 250 /* extract header type specific config data */ 251 252 static void 253 pci_hdrtypedata(pcicfgregs *cfg) 254 { 255 switch (cfg->hdrtype) { 256 case 0: 257 cfg->subvendor = pci_cfgread(cfg, PCIR_SUBVEND_0, 2); 258 cfg->subdevice = pci_cfgread(cfg, PCIR_SUBDEV_0, 2); 259 cfg->nummaps = PCI_MAXMAPS_0; 260 break; 261 case 1: 262 cfg->subvendor = pci_cfgread(cfg, PCIR_SUBVEND_1, 2); 263 cfg->subdevice = pci_cfgread(cfg, PCIR_SUBDEV_1, 2); 264 cfg->secondarybus = pci_cfgread(cfg, PCIR_SECBUS_1, 1); 265 cfg->subordinatebus = pci_cfgread(cfg, PCIR_SUBBUS_1, 1); 266 cfg->nummaps = PCI_MAXMAPS_1; 267 cfg->hdrspec = pci_readppb(cfg); 268 break; 269 case 2: 270 cfg->subvendor = pci_cfgread(cfg, PCIR_SUBVEND_2, 2); 271 cfg->subdevice = pci_cfgread(cfg, PCIR_SUBDEV_2, 2); 272 cfg->secondarybus = pci_cfgread(cfg, PCIR_SECBUS_2, 1); 273 cfg->subordinatebus = pci_cfgread(cfg, PCIR_SUBBUS_2, 1); 274 cfg->nummaps = PCI_MAXMAPS_2; 275 cfg->hdrspec = pci_readpcb(cfg); 276 break; 277 } 278 } 279 280 /* read configuration header into pcicfgrect structure */ 281 282 static struct pci_devinfo * 283 pci_readcfg(pcicfgregs *probe) 284 { 285 pcicfgregs *cfg = NULL; 286 struct pci_devinfo *devlist_entry; 287 struct devlist *devlist_head; 288 289 devlist_head = &pci_devq; 290 291 devlist_entry = NULL; 292 293 if (pci_cfgread(probe, PCIR_DEVVENDOR, 4) != -1) { 294 295 devlist_entry = malloc(sizeof(struct pci_devinfo), 296 M_DEVBUF, M_WAITOK); 297 if (devlist_entry == NULL) 298 return (NULL); 299 bzero(devlist_entry, sizeof *devlist_entry); 300 301 cfg = &devlist_entry->cfg; 302 303 cfg->hose = probe->hose; 304 cfg->bus = probe->bus; 305 cfg->slot = probe->slot; 306 cfg->func = probe->func; 307 cfg->vendor = pci_cfgread(cfg, PCIR_VENDOR, 2); 308 cfg->device = pci_cfgread(cfg, PCIR_DEVICE, 2); 309 cfg->cmdreg = pci_cfgread(cfg, PCIR_COMMAND, 2); 310 cfg->statreg = pci_cfgread(cfg, PCIR_STATUS, 2); 311 cfg->baseclass = pci_cfgread(cfg, PCIR_CLASS, 1); 312 cfg->subclass = pci_cfgread(cfg, PCIR_SUBCLASS, 1); 313 cfg->progif = pci_cfgread(cfg, PCIR_PROGIF, 1); 314 cfg->revid = pci_cfgread(cfg, PCIR_REVID, 1); 315 cfg->hdrtype = pci_cfgread(cfg, PCIR_HEADERTYPE, 1); 316 cfg->cachelnsz = pci_cfgread(cfg, PCIR_CACHELNSZ, 1); 317 cfg->lattimer = pci_cfgread(cfg, PCIR_LATTIMER, 1); 318 cfg->intpin = pci_cfgread(cfg, PCIR_INTPIN, 1); 319 cfg->intline = pci_cfgread(cfg, PCIR_INTLINE, 1); 320 #ifdef __alpha__ 321 alpha_platform_assign_pciintr(cfg); 322 #endif 323 324 #ifdef APIC_IO 325 if (cfg->intpin != 0) { 326 int airq; 327 328 airq = pci_apic_irq(cfg->bus, cfg->slot, cfg->intpin); 329 if (airq >= 0) { 330 /* PCI specific entry found in MP table */ 331 if (airq != cfg->intline) { 332 undirect_pci_irq(cfg->intline); 333 cfg->intline = airq; 334 } 335 } else { 336 /* 337 * PCI interrupts might be redirected to the 338 * ISA bus according to some MP tables. Use the 339 * same methods as used by the ISA devices 340 * devices to find the proper IOAPIC int pin. 341 */ 342 airq = isa_apic_irq(cfg->intline); 343 if ((airq >= 0) && (airq != cfg->intline)) { 344 /* XXX: undirect_pci_irq() ? */ 345 undirect_isa_irq(cfg->intline); 346 cfg->intline = airq; 347 } 348 } 349 } 350 #endif /* APIC_IO */ 351 352 cfg->mingnt = pci_cfgread(cfg, PCIR_MINGNT, 1); 353 cfg->maxlat = pci_cfgread(cfg, PCIR_MAXLAT, 1); 354 355 cfg->mfdev = (cfg->hdrtype & PCIM_MFDEV) != 0; 356 cfg->hdrtype &= ~PCIM_MFDEV; 357 358 pci_fixancient(cfg); 359 pci_hdrtypedata(cfg); 360 361 STAILQ_INSERT_TAIL(devlist_head, devlist_entry, pci_links); 362 363 devlist_entry->conf.pc_sel.pc_bus = cfg->bus; 364 devlist_entry->conf.pc_sel.pc_dev = cfg->slot; 365 devlist_entry->conf.pc_sel.pc_func = cfg->func; 366 devlist_entry->conf.pc_hdr = cfg->hdrtype; 367 368 devlist_entry->conf.pc_subvendor = cfg->subvendor; 369 devlist_entry->conf.pc_subdevice = cfg->subdevice; 370 devlist_entry->conf.pc_vendor = cfg->vendor; 371 devlist_entry->conf.pc_device = cfg->device; 372 373 devlist_entry->conf.pc_class = cfg->baseclass; 374 devlist_entry->conf.pc_subclass = cfg->subclass; 375 devlist_entry->conf.pc_progif = cfg->progif; 376 devlist_entry->conf.pc_revid = cfg->revid; 377 378 pci_numdevs++; 379 pci_generation++; 380 } 381 return (devlist_entry); 382 } 383 384 #if 0 385 /* free pcicfgregs structure and all depending data structures */ 386 387 static int 388 pci_freecfg(struct pci_devinfo *dinfo) 389 { 390 struct devlist *devlist_head; 391 392 devlist_head = &pci_devq; 393 394 if (dinfo->cfg.hdrspec != NULL) 395 free(dinfo->cfg.hdrspec, M_DEVBUF); 396 if (dinfo->cfg.map != NULL) 397 free(dinfo->cfg.map, M_DEVBUF); 398 /* XXX this hasn't been tested */ 399 STAILQ_REMOVE(devlist_head, dinfo, pci_devinfo, pci_links); 400 free(dinfo, M_DEVBUF); 401 402 /* increment the generation count */ 403 pci_generation++; 404 405 /* we're losing one device */ 406 pci_numdevs--; 407 return (0); 408 } 409 #endif 410 411 412 /* 413 * This is the user interface to PCI configuration space. 414 */ 415 416 static int 417 pci_open(dev_t dev, int oflags, int devtype, struct proc *p) 418 { 419 if ((oflags & FWRITE) && securelevel > 0) { 420 return EPERM; 421 } 422 return 0; 423 } 424 425 static int 426 pci_close(dev_t dev, int flag, int devtype, struct proc *p) 427 { 428 return 0; 429 } 430 431 /* 432 * Match a single pci_conf structure against an array of pci_match_conf 433 * structures. The first argument, 'matches', is an array of num_matches 434 * pci_match_conf structures. match_buf is a pointer to the pci_conf 435 * structure that will be compared to every entry in the matches array. 436 * This function returns 1 on failure, 0 on success. 437 */ 438 static int 439 pci_conf_match(struct pci_match_conf *matches, int num_matches, 440 struct pci_conf *match_buf) 441 { 442 int i; 443 444 if ((matches == NULL) || (match_buf == NULL) || (num_matches <= 0)) 445 return(1); 446 447 for (i = 0; i < num_matches; i++) { 448 /* 449 * I'm not sure why someone would do this...but... 450 */ 451 if (matches[i].flags == PCI_GETCONF_NO_MATCH) 452 continue; 453 454 /* 455 * Look at each of the match flags. If it's set, do the 456 * comparison. If the comparison fails, we don't have a 457 * match, go on to the next item if there is one. 458 */ 459 if (((matches[i].flags & PCI_GETCONF_MATCH_BUS) != 0) 460 && (match_buf->pc_sel.pc_bus != matches[i].pc_sel.pc_bus)) 461 continue; 462 463 if (((matches[i].flags & PCI_GETCONF_MATCH_DEV) != 0) 464 && (match_buf->pc_sel.pc_dev != matches[i].pc_sel.pc_dev)) 465 continue; 466 467 if (((matches[i].flags & PCI_GETCONF_MATCH_FUNC) != 0) 468 && (match_buf->pc_sel.pc_func != matches[i].pc_sel.pc_func)) 469 continue; 470 471 if (((matches[i].flags & PCI_GETCONF_MATCH_VENDOR) != 0) 472 && (match_buf->pc_vendor != matches[i].pc_vendor)) 473 continue; 474 475 if (((matches[i].flags & PCI_GETCONF_MATCH_DEVICE) != 0) 476 && (match_buf->pc_device != matches[i].pc_device)) 477 continue; 478 479 if (((matches[i].flags & PCI_GETCONF_MATCH_CLASS) != 0) 480 && (match_buf->pc_class != matches[i].pc_class)) 481 continue; 482 483 if (((matches[i].flags & PCI_GETCONF_MATCH_UNIT) != 0) 484 && (match_buf->pd_unit != matches[i].pd_unit)) 485 continue; 486 487 if (((matches[i].flags & PCI_GETCONF_MATCH_NAME) != 0) 488 && (strncmp(matches[i].pd_name, match_buf->pd_name, 489 sizeof(match_buf->pd_name)) != 0)) 490 continue; 491 492 return(0); 493 } 494 495 return(1); 496 } 497 498 /* 499 * Locate the parent of a PCI device by scanning the PCI devlist 500 * and return the entry for the parent. 501 * For devices on PCI Bus 0 (the host bus), this is the PCI Host. 502 * For devices on secondary PCI busses, this is that bus' PCI-PCI Bridge. 503 */ 504 505 pcicfgregs * 506 pci_devlist_get_parent(pcicfgregs *cfg) 507 { 508 struct devlist *devlist_head; 509 struct pci_devinfo *dinfo; 510 pcicfgregs *bridge_cfg; 511 int i; 512 513 dinfo = STAILQ_FIRST(devlist_head = &pci_devq); 514 515 /* If the device is on PCI bus 0, look for the host */ 516 if (cfg->bus == 0) { 517 for (i = 0; (dinfo != NULL) && (i < pci_numdevs); 518 dinfo = STAILQ_NEXT(dinfo, pci_links), i++) { 519 bridge_cfg = &dinfo->cfg; 520 if (bridge_cfg->baseclass == PCIC_BRIDGE 521 && bridge_cfg->subclass == PCIS_BRIDGE_HOST 522 && bridge_cfg->bus == cfg->bus) { 523 return bridge_cfg; 524 } 525 } 526 } 527 528 /* If the device is not on PCI bus 0, look for the PCI-PCI bridge */ 529 if (cfg->bus > 0) { 530 for (i = 0; (dinfo != NULL) && (i < pci_numdevs); 531 dinfo = STAILQ_NEXT(dinfo, pci_links), i++) { 532 bridge_cfg = &dinfo->cfg; 533 if (bridge_cfg->baseclass == PCIC_BRIDGE 534 && bridge_cfg->subclass == PCIS_BRIDGE_PCI 535 && bridge_cfg->secondarybus == cfg->bus) { 536 return bridge_cfg; 537 } 538 } 539 } 540 541 return NULL; 542 } 543 544 static int 545 pci_ioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) 546 { 547 struct pci_io *io; 548 const char *name; 549 int error; 550 551 if (!(flag & FWRITE)) 552 return EPERM; 553 554 555 switch(cmd) { 556 case PCIOCGETCONF: 557 { 558 struct pci_devinfo *dinfo; 559 struct pci_conf_io *cio; 560 struct devlist *devlist_head; 561 struct pci_match_conf *pattern_buf; 562 int num_patterns; 563 size_t iolen; 564 int ionum, i; 565 566 cio = (struct pci_conf_io *)data; 567 568 num_patterns = 0; 569 dinfo = NULL; 570 571 /* 572 * Hopefully the user won't pass in a null pointer, but it 573 * can't hurt to check. 574 */ 575 if (cio == NULL) { 576 error = EINVAL; 577 break; 578 } 579 580 /* 581 * If the user specified an offset into the device list, 582 * but the list has changed since they last called this 583 * ioctl, tell them that the list has changed. They will 584 * have to get the list from the beginning. 585 */ 586 if ((cio->offset != 0) 587 && (cio->generation != pci_generation)){ 588 cio->num_matches = 0; 589 cio->status = PCI_GETCONF_LIST_CHANGED; 590 error = 0; 591 break; 592 } 593 594 /* 595 * Check to see whether the user has asked for an offset 596 * past the end of our list. 597 */ 598 if (cio->offset >= pci_numdevs) { 599 cio->num_matches = 0; 600 cio->status = PCI_GETCONF_LAST_DEVICE; 601 error = 0; 602 break; 603 } 604 605 /* get the head of the device queue */ 606 devlist_head = &pci_devq; 607 608 /* 609 * Determine how much room we have for pci_conf structures. 610 * Round the user's buffer size down to the nearest 611 * multiple of sizeof(struct pci_conf) in case the user 612 * didn't specify a multiple of that size. 613 */ 614 iolen = min(cio->match_buf_len - 615 (cio->match_buf_len % sizeof(struct pci_conf)), 616 pci_numdevs * sizeof(struct pci_conf)); 617 618 /* 619 * Since we know that iolen is a multiple of the size of 620 * the pciconf union, it's okay to do this. 621 */ 622 ionum = iolen / sizeof(struct pci_conf); 623 624 /* 625 * If this test is true, the user wants the pci_conf 626 * structures returned to match the supplied entries. 627 */ 628 if ((cio->num_patterns > 0) 629 && (cio->pat_buf_len > 0)) { 630 /* 631 * pat_buf_len needs to be: 632 * num_patterns * sizeof(struct pci_match_conf) 633 * While it is certainly possible the user just 634 * allocated a large buffer, but set the number of 635 * matches correctly, it is far more likely that 636 * their kernel doesn't match the userland utility 637 * they're using. It's also possible that the user 638 * forgot to initialize some variables. Yes, this 639 * may be overly picky, but I hazard to guess that 640 * it's far more likely to just catch folks that 641 * updated their kernel but not their userland. 642 */ 643 if ((cio->num_patterns * 644 sizeof(struct pci_match_conf)) != cio->pat_buf_len){ 645 /* The user made a mistake, return an error*/ 646 cio->status = PCI_GETCONF_ERROR; 647 printf("pci_ioctl: pat_buf_len %d != " 648 "num_patterns (%d) * sizeof(struct " 649 "pci_match_conf) (%d)\npci_ioctl: " 650 "pat_buf_len should be = %d\n", 651 cio->pat_buf_len, cio->num_patterns, 652 (int)sizeof(struct pci_match_conf), 653 (int)sizeof(struct pci_match_conf) * 654 cio->num_patterns); 655 printf("pci_ioctl: do your headers match your " 656 "kernel?\n"); 657 cio->num_matches = 0; 658 error = EINVAL; 659 break; 660 } 661 662 /* 663 * Check the user's buffer to make sure it's readable. 664 */ 665 if (!useracc((caddr_t)cio->patterns, 666 cio->pat_buf_len, VM_PROT_READ)) { 667 printf("pci_ioctl: pattern buffer %p, " 668 "length %u isn't user accessible for" 669 " READ\n", cio->patterns, 670 cio->pat_buf_len); 671 error = EACCES; 672 break; 673 } 674 /* 675 * Allocate a buffer to hold the patterns. 676 */ 677 pattern_buf = malloc(cio->pat_buf_len, M_TEMP, 678 M_WAITOK); 679 error = copyin(cio->patterns, pattern_buf, 680 cio->pat_buf_len); 681 if (error != 0) 682 break; 683 num_patterns = cio->num_patterns; 684 685 } else if ((cio->num_patterns > 0) 686 || (cio->pat_buf_len > 0)) { 687 /* 688 * The user made a mistake, spit out an error. 689 */ 690 cio->status = PCI_GETCONF_ERROR; 691 cio->num_matches = 0; 692 printf("pci_ioctl: invalid GETCONF arguments\n"); 693 error = EINVAL; 694 break; 695 } else 696 pattern_buf = NULL; 697 698 /* 699 * Make sure we can write to the match buffer. 700 */ 701 if (!useracc((caddr_t)cio->matches, 702 cio->match_buf_len, VM_PROT_WRITE)) { 703 printf("pci_ioctl: match buffer %p, length %u " 704 "isn't user accessible for WRITE\n", 705 cio->matches, cio->match_buf_len); 706 error = EACCES; 707 break; 708 } 709 710 /* 711 * Go through the list of devices and copy out the devices 712 * that match the user's criteria. 713 */ 714 for (cio->num_matches = 0, error = 0, i = 0, 715 dinfo = STAILQ_FIRST(devlist_head); 716 (dinfo != NULL) && (cio->num_matches < ionum) 717 && (error == 0) && (i < pci_numdevs); 718 dinfo = STAILQ_NEXT(dinfo, pci_links), i++) { 719 720 if (i < cio->offset) 721 continue; 722 723 /* Populate pd_name and pd_unit */ 724 name = NULL; 725 if (dinfo->cfg.dev && dinfo->conf.pd_name[0] == '\0') 726 name = device_get_name(dinfo->cfg.dev); 727 if (name) { 728 strncpy(dinfo->conf.pd_name, name, 729 sizeof(dinfo->conf.pd_name)); 730 dinfo->conf.pd_name[PCI_MAXNAMELEN] = 0; 731 dinfo->conf.pd_unit = 732 device_get_unit(dinfo->cfg.dev); 733 } 734 735 if ((pattern_buf == NULL) || 736 (pci_conf_match(pattern_buf, num_patterns, 737 &dinfo->conf) == 0)) { 738 739 /* 740 * If we've filled up the user's buffer, 741 * break out at this point. Since we've 742 * got a match here, we'll pick right back 743 * up at the matching entry. We can also 744 * tell the user that there are more matches 745 * left. 746 */ 747 if (cio->num_matches >= ionum) 748 break; 749 750 error = copyout(&dinfo->conf, 751 &cio->matches[cio->num_matches], 752 sizeof(struct pci_conf)); 753 cio->num_matches++; 754 } 755 } 756 757 /* 758 * Set the pointer into the list, so if the user is getting 759 * n records at a time, where n < pci_numdevs, 760 */ 761 cio->offset = i; 762 763 /* 764 * Set the generation, the user will need this if they make 765 * another ioctl call with offset != 0. 766 */ 767 cio->generation = pci_generation; 768 769 /* 770 * If this is the last device, inform the user so he won't 771 * bother asking for more devices. If dinfo isn't NULL, we 772 * know that there are more matches in the list because of 773 * the way the traversal is done. 774 */ 775 if (dinfo == NULL) 776 cio->status = PCI_GETCONF_LAST_DEVICE; 777 else 778 cio->status = PCI_GETCONF_MORE_DEVS; 779 780 if (pattern_buf != NULL) 781 free(pattern_buf, M_TEMP); 782 783 break; 784 } 785 case PCIOCREAD: 786 io = (struct pci_io *)data; 787 switch(io->pi_width) { 788 pcicfgregs probe; 789 case 4: 790 case 2: 791 case 1: 792 probe.hose = -1; 793 probe.bus = io->pi_sel.pc_bus; 794 probe.slot = io->pi_sel.pc_dev; 795 probe.func = io->pi_sel.pc_func; 796 io->pi_data = pci_cfgread(&probe, 797 io->pi_reg, io->pi_width); 798 error = 0; 799 break; 800 default: 801 error = ENODEV; 802 break; 803 } 804 break; 805 806 case PCIOCWRITE: 807 io = (struct pci_io *)data; 808 switch(io->pi_width) { 809 pcicfgregs probe; 810 case 4: 811 case 2: 812 case 1: 813 probe.hose = -1; 814 probe.bus = io->pi_sel.pc_bus; 815 probe.slot = io->pi_sel.pc_dev; 816 probe.func = io->pi_sel.pc_func; 817 pci_cfgwrite(&probe, 818 io->pi_reg, io->pi_data, io->pi_width); 819 error = 0; 820 break; 821 default: 822 error = ENODEV; 823 break; 824 } 825 break; 826 827 default: 828 error = ENOTTY; 829 break; 830 } 831 832 return (error); 833 } 834 835 #define PCI_CDEV 78 836 837 static struct cdevsw pcicdev = { 838 /* open */ pci_open, 839 /* close */ pci_close, 840 /* read */ noread, 841 /* write */ nowrite, 842 /* ioctl */ pci_ioctl, 843 /* poll */ nopoll, 844 /* mmap */ nommap, 845 /* strategy */ nostrategy, 846 /* name */ "pci", 847 /* maj */ PCI_CDEV, 848 /* dump */ nodump, 849 /* psize */ nopsize, 850 /* flags */ 0, 851 /* bmaj */ -1 852 }; 853 854 #include "pci_if.h" 855 856 /* 857 * A simple driver to wrap the old pci driver mechanism for back-compat. 858 */ 859 860 static int 861 pci_compat_probe(device_t dev) 862 { 863 struct pci_device *dvp; 864 struct pci_devinfo *dinfo; 865 pcicfgregs *cfg; 866 const char *name; 867 int error; 868 869 dinfo = device_get_ivars(dev); 870 cfg = &dinfo->cfg; 871 dvp = device_get_driver(dev)->priv; 872 873 /* 874 * Do the wrapped probe. 875 */ 876 error = ENXIO; 877 if (dvp && dvp->pd_probe) { 878 name = dvp->pd_probe(cfg, (cfg->device << 16) + cfg->vendor); 879 if (name) { 880 device_set_desc_copy(dev, name); 881 /* Allow newbus drivers to match "better" */ 882 error = -200; 883 } 884 } 885 886 return error; 887 } 888 889 static int 890 pci_compat_attach(device_t dev) 891 { 892 struct pci_device *dvp; 893 struct pci_devinfo *dinfo; 894 pcicfgregs *cfg; 895 int unit; 896 897 dinfo = device_get_ivars(dev); 898 cfg = &dinfo->cfg; 899 dvp = device_get_driver(dev)->priv; 900 901 unit = device_get_unit(dev); 902 if (unit > *dvp->pd_count) 903 *dvp->pd_count = unit; 904 if (dvp->pd_attach) 905 dvp->pd_attach(cfg, unit); 906 device_printf(dev, "driver is using old-style compatability shims\n"); 907 return 0; 908 } 909 910 static device_method_t pci_compat_methods[] = { 911 /* Device interface */ 912 DEVMETHOD(device_probe, pci_compat_probe), 913 DEVMETHOD(device_attach, pci_compat_attach), 914 915 { 0, 0 } 916 }; 917 918 static devclass_t pci_devclass; 919 920 /* 921 * Create a new style driver around each old pci driver. 922 */ 923 int 924 compat_pci_handler(module_t mod, int type, void *data) 925 { 926 struct pci_device *dvp = (struct pci_device *)data; 927 driver_t *driver; 928 929 switch (type) { 930 case MOD_LOAD: 931 driver = malloc(sizeof(driver_t), M_DEVBUF, M_NOWAIT); 932 if (!driver) 933 return ENOMEM; 934 bzero(driver, sizeof(driver_t)); 935 driver->name = dvp->pd_name; 936 driver->methods = pci_compat_methods; 937 driver->softc = sizeof(struct pci_devinfo *); 938 driver->priv = dvp; 939 devclass_add_driver(pci_devclass, driver); 940 break; 941 case MOD_UNLOAD: 942 printf("%s: module unload not supported!\n", dvp->pd_name); 943 return EOPNOTSUPP; 944 default: 945 break; 946 } 947 return 0; 948 } 949 950 /* 951 * New style pci driver. Parent device is either a pci-host-bridge or a 952 * pci-pci-bridge. Both kinds are represented by instances of pcib. 953 */ 954 955 static void 956 pci_print_verbose(struct pci_devinfo *dinfo) 957 { 958 if (bootverbose) { 959 pcicfgregs *cfg = &dinfo->cfg; 960 961 printf("found->\tvendor=0x%04x, dev=0x%04x, revid=0x%02x\n", 962 cfg->vendor, cfg->device, cfg->revid); 963 printf("\tclass=%02x-%02x-%02x, hdrtype=0x%02x, mfdev=%d\n", 964 cfg->baseclass, cfg->subclass, cfg->progif, 965 cfg->hdrtype, cfg->mfdev); 966 printf("\tsubordinatebus=%x \tsecondarybus=%x\n", 967 cfg->subordinatebus, cfg->secondarybus); 968 #ifdef PCI_DEBUG 969 printf("\tcmdreg=0x%04x, statreg=0x%04x, cachelnsz=%d (dwords)\n", 970 cfg->cmdreg, cfg->statreg, cfg->cachelnsz); 971 printf("\tlattimer=0x%02x (%d ns), mingnt=0x%02x (%d ns), maxlat=0x%02x (%d ns)\n", 972 cfg->lattimer, cfg->lattimer * 30, 973 cfg->mingnt, cfg->mingnt * 250, cfg->maxlat, cfg->maxlat * 250); 974 #endif /* PCI_DEBUG */ 975 if (cfg->intpin > 0) 976 printf("\tintpin=%c, irq=%d\n", cfg->intpin +'a' -1, cfg->intline); 977 } 978 } 979 980 static int 981 pci_porten(pcicfgregs *cfg) 982 { 983 return ((cfg->cmdreg & PCIM_CMD_PORTEN) != 0); 984 } 985 986 static int 987 pci_memen(pcicfgregs *cfg) 988 { 989 return ((cfg->cmdreg & PCIM_CMD_MEMEN) != 0); 990 } 991 992 /* 993 * Add a resource based on a pci map register. Return 1 if the map 994 * register is a 32bit map register or 2 if it is a 64bit register. 995 */ 996 static int 997 pci_add_map(device_t dev, pcicfgregs* cfg, int reg) 998 { 999 struct pci_devinfo *dinfo = device_get_ivars(dev); 1000 struct resource_list *rl = &dinfo->resources; 1001 u_int32_t map; 1002 u_int64_t base; 1003 u_int8_t ln2size; 1004 u_int8_t ln2range; 1005 u_int32_t testval; 1006 1007 int type; 1008 1009 map = pci_cfgread(cfg, reg, 4); 1010 1011 if (map == 0 || map == 0xffffffff) 1012 return 1; /* skip invalid entry */ 1013 1014 pci_cfgwrite(cfg, reg, 0xffffffff, 4); 1015 testval = pci_cfgread(cfg, reg, 4); 1016 pci_cfgwrite(cfg, reg, map, 4); 1017 1018 base = pci_mapbase(map); 1019 if (pci_maptype(map) & PCI_MAPMEM) 1020 type = SYS_RES_MEMORY; 1021 else 1022 type = SYS_RES_IOPORT; 1023 ln2size = pci_mapsize(testval); 1024 ln2range = pci_maprange(testval); 1025 if (ln2range == 64) { 1026 /* Read the other half of a 64bit map register */ 1027 base |= (u_int64_t) pci_cfgread(cfg, reg + 4, 4) << 32; 1028 } 1029 1030 #ifdef __alpha__ 1031 /* 1032 * XXX: encode hose number in the base addr, 1033 * This will go away once the bus_space functions 1034 * can deal with multiple hoses 1035 */ 1036 1037 if(cfg->hose){ 1038 if (base & 0x80000000) { 1039 printf("base addr = 0x%lx\n", base); 1040 printf("hacked addr = 0x%lx\n", 1041 base | ((u_int64_t)cfg->hose << 31)); 1042 1043 panic("hose encoding hack would clobber base addr"); 1044 } 1045 if (cfg->hose > 1) 1046 panic("only one hose supported!"); 1047 base |= ((u_int64_t)cfg->hose << 31); 1048 } 1049 #endif 1050 if (type == SYS_RES_IOPORT && !pci_porten(cfg)) 1051 return 1; 1052 if (type == SYS_RES_MEMORY && !pci_memen(cfg)) 1053 return 1; 1054 1055 resource_list_add(rl, type, reg, 1056 base, base + (1 << ln2size) - 1, 1057 (1 << ln2size)); 1058 1059 if (bootverbose) { 1060 printf("\tmap[%02x]: type %x, range %2d, base %08x, size %2d\n", 1061 reg, pci_maptype(base), ln2range, 1062 (unsigned int) base, ln2size); 1063 } 1064 1065 return (ln2range == 64) ? 2 : 1; 1066 } 1067 1068 static void 1069 pci_add_resources(device_t dev, pcicfgregs* cfg) 1070 { 1071 struct pci_devinfo *dinfo = device_get_ivars(dev); 1072 struct resource_list *rl = &dinfo->resources; 1073 struct pci_quirk *q; 1074 int i; 1075 1076 for (i = 0; i < cfg->nummaps;) { 1077 i += pci_add_map(dev, cfg, PCIR_MAPS + i*4); 1078 } 1079 1080 for (q = &pci_quirks[0]; q->devid; q++) { 1081 if (q->devid == ((cfg->device << 16) | cfg->vendor) 1082 && q->type == PCI_QUIRK_MAP_REG) 1083 pci_add_map(dev, cfg, q->arg1); 1084 } 1085 1086 if (cfg->intpin > 0 && cfg->intline != 255) 1087 resource_list_add(rl, SYS_RES_IRQ, 0, 1088 cfg->intline, cfg->intline, 1); 1089 } 1090 1091 static void 1092 pci_add_children(device_t dev, int busno) 1093 { 1094 pcicfgregs probe; 1095 1096 #ifdef SIMOS 1097 #undef PCI_SLOTMAX 1098 #define PCI_SLOTMAX 0 1099 #endif 1100 1101 bzero(&probe, sizeof probe); 1102 #ifdef __alpha__ 1103 probe.hose = pcib_get_hose(dev); 1104 #endif 1105 #ifdef __i386__ 1106 probe.hose = 0; 1107 #endif 1108 probe.bus = busno; 1109 1110 for (probe.slot = 0; probe.slot <= PCI_SLOTMAX; probe.slot++) { 1111 int pcifunchigh = 0; 1112 for (probe.func = 0; probe.func <= pcifunchigh; probe.func++) { 1113 struct pci_devinfo *dinfo = pci_readcfg(&probe); 1114 if (dinfo != NULL) { 1115 if (dinfo->cfg.mfdev) 1116 pcifunchigh = 7; 1117 1118 pci_print_verbose(dinfo); 1119 dinfo->cfg.dev = device_add_child(dev, NULL, -1); 1120 device_set_ivars(dinfo->cfg.dev, dinfo); 1121 pci_add_resources(dinfo->cfg.dev, &dinfo->cfg); 1122 } 1123 } 1124 } 1125 } 1126 1127 static int 1128 pci_new_probe(device_t dev) 1129 { 1130 static int once; 1131 1132 device_set_desc(dev, "PCI bus"); 1133 pci_add_children(dev, device_get_unit(dev)); 1134 if (!once) { 1135 make_dev(&pcicdev, 0, UID_ROOT, GID_WHEEL, 0644, "pci"); 1136 once++; 1137 } 1138 1139 return 0; 1140 } 1141 1142 static int 1143 pci_print_resources(struct resource_list *rl, const char *name, int type, 1144 const char *format) 1145 { 1146 struct resource_list_entry *rle; 1147 int printed, retval; 1148 1149 printed = 0; 1150 retval = 0; 1151 /* Yes, this is kinda cheating */ 1152 SLIST_FOREACH(rle, rl, link) { 1153 if (rle->type == type) { 1154 if (printed == 0) 1155 retval += printf(" %s ", name); 1156 else if (printed > 0) 1157 retval += printf(","); 1158 printed++; 1159 retval += printf(format, rle->start); 1160 if (rle->count > 1) { 1161 retval += printf("-"); 1162 retval += printf(format, rle->start + 1163 rle->count - 1); 1164 } 1165 } 1166 } 1167 return retval; 1168 } 1169 1170 static int 1171 pci_print_child(device_t dev, device_t child) 1172 { 1173 struct pci_devinfo *dinfo; 1174 struct resource_list *rl; 1175 pcicfgregs *cfg; 1176 int retval = 0; 1177 1178 dinfo = device_get_ivars(child); 1179 cfg = &dinfo->cfg; 1180 rl = &dinfo->resources; 1181 1182 retval += bus_print_child_header(dev, child); 1183 1184 retval += pci_print_resources(rl, "port", SYS_RES_IOPORT, "%#lx"); 1185 retval += pci_print_resources(rl, "mem", SYS_RES_MEMORY, "%#lx"); 1186 retval += pci_print_resources(rl, "irq", SYS_RES_IRQ, "%ld"); 1187 if (device_get_flags(dev)) 1188 retval += printf(" flags %#x", device_get_flags(dev)); 1189 1190 retval += printf(" at device %d.%d", pci_get_slot(child), 1191 pci_get_function(child)); 1192 1193 retval += bus_print_child_footer(dev, child); 1194 1195 return (retval); 1196 } 1197 1198 static void 1199 pci_probe_nomatch(device_t dev, device_t child) 1200 { 1201 struct pci_devinfo *dinfo; 1202 pcicfgregs *cfg; 1203 const char *desc; 1204 int unknown; 1205 1206 unknown = 0; 1207 dinfo = device_get_ivars(child); 1208 cfg = &dinfo->cfg; 1209 desc = pci_ata_match(child); 1210 if (!desc) desc = pci_usb_match(child); 1211 if (!desc) desc = pci_vga_match(child); 1212 if (!desc) { 1213 desc = "unknown card"; 1214 unknown++; 1215 } 1216 device_printf(dev, "<%s>", desc); 1217 if (bootverbose || unknown) { 1218 printf(" (vendor=0x%04x, dev=0x%04x)", 1219 cfg->vendor, 1220 cfg->device); 1221 } 1222 printf(" at %d.%d", 1223 pci_get_slot(child), 1224 pci_get_function(child)); 1225 if (cfg->intpin > 0 && cfg->intline != 255) { 1226 printf(" irq %d", cfg->intline); 1227 } 1228 printf("\n"); 1229 1230 return; 1231 } 1232 1233 static int 1234 pci_read_ivar(device_t dev, device_t child, int which, u_long *result) 1235 { 1236 struct pci_devinfo *dinfo; 1237 pcicfgregs *cfg; 1238 1239 dinfo = device_get_ivars(child); 1240 cfg = &dinfo->cfg; 1241 1242 switch (which) { 1243 case PCI_IVAR_SUBVENDOR: 1244 *result = cfg->subvendor; 1245 break; 1246 case PCI_IVAR_SUBDEVICE: 1247 *result = cfg->subdevice; 1248 break; 1249 case PCI_IVAR_VENDOR: 1250 *result = cfg->vendor; 1251 break; 1252 case PCI_IVAR_DEVICE: 1253 *result = cfg->device; 1254 break; 1255 case PCI_IVAR_DEVID: 1256 *result = (cfg->device << 16) | cfg->vendor; 1257 break; 1258 case PCI_IVAR_CLASS: 1259 *result = cfg->baseclass; 1260 break; 1261 case PCI_IVAR_SUBCLASS: 1262 *result = cfg->subclass; 1263 break; 1264 case PCI_IVAR_PROGIF: 1265 *result = cfg->progif; 1266 break; 1267 case PCI_IVAR_REVID: 1268 *result = cfg->revid; 1269 break; 1270 case PCI_IVAR_INTPIN: 1271 *result = cfg->intpin; 1272 break; 1273 case PCI_IVAR_IRQ: 1274 *result = cfg->intline; 1275 break; 1276 case PCI_IVAR_BUS: 1277 *result = cfg->bus; 1278 break; 1279 case PCI_IVAR_SLOT: 1280 *result = cfg->slot; 1281 break; 1282 case PCI_IVAR_FUNCTION: 1283 *result = cfg->func; 1284 break; 1285 case PCI_IVAR_SECONDARYBUS: 1286 *result = cfg->secondarybus; 1287 break; 1288 case PCI_IVAR_SUBORDINATEBUS: 1289 *result = cfg->subordinatebus; 1290 break; 1291 case PCI_IVAR_HOSE: 1292 /* 1293 * Pass up to parent bridge. 1294 */ 1295 *result = pcib_get_hose(dev); 1296 break; 1297 default: 1298 return ENOENT; 1299 } 1300 return 0; 1301 } 1302 1303 static int 1304 pci_write_ivar(device_t dev, device_t child, int which, uintptr_t value) 1305 { 1306 struct pci_devinfo *dinfo; 1307 pcicfgregs *cfg; 1308 1309 dinfo = device_get_ivars(child); 1310 cfg = &dinfo->cfg; 1311 1312 switch (which) { 1313 case PCI_IVAR_SUBVENDOR: 1314 case PCI_IVAR_SUBDEVICE: 1315 case PCI_IVAR_VENDOR: 1316 case PCI_IVAR_DEVICE: 1317 case PCI_IVAR_DEVID: 1318 case PCI_IVAR_CLASS: 1319 case PCI_IVAR_SUBCLASS: 1320 case PCI_IVAR_PROGIF: 1321 case PCI_IVAR_REVID: 1322 case PCI_IVAR_INTPIN: 1323 case PCI_IVAR_IRQ: 1324 case PCI_IVAR_BUS: 1325 case PCI_IVAR_SLOT: 1326 case PCI_IVAR_FUNCTION: 1327 return EINVAL; /* disallow for now */ 1328 1329 case PCI_IVAR_SECONDARYBUS: 1330 cfg->secondarybus = value; 1331 break; 1332 case PCI_IVAR_SUBORDINATEBUS: 1333 cfg->subordinatebus = value; 1334 break; 1335 default: 1336 return ENOENT; 1337 } 1338 return 0; 1339 } 1340 1341 static struct resource * 1342 pci_alloc_resource(device_t dev, device_t child, int type, int *rid, 1343 u_long start, u_long end, u_long count, u_int flags) 1344 { 1345 struct pci_devinfo *dinfo = device_get_ivars(child); 1346 struct resource_list *rl = &dinfo->resources; 1347 1348 return resource_list_alloc(rl, dev, child, type, rid, 1349 start, end, count, flags); 1350 } 1351 1352 static int 1353 pci_release_resource(device_t dev, device_t child, int type, int rid, 1354 struct resource *r) 1355 { 1356 struct pci_devinfo *dinfo = device_get_ivars(child); 1357 struct resource_list *rl = &dinfo->resources; 1358 1359 return resource_list_release(rl, dev, child, type, rid, r); 1360 } 1361 1362 static int 1363 pci_set_resource(device_t dev, device_t child, int type, int rid, 1364 u_long start, u_long count) 1365 { 1366 struct pci_devinfo *dinfo = device_get_ivars(child); 1367 struct resource_list *rl = &dinfo->resources; 1368 1369 resource_list_add(rl, type, rid, start, start + count - 1, count); 1370 return 0; 1371 } 1372 1373 static int 1374 pci_get_resource(device_t dev, device_t child, int type, int rid, 1375 u_long *startp, u_long *countp) 1376 { 1377 struct pci_devinfo *dinfo = device_get_ivars(child); 1378 struct resource_list *rl = &dinfo->resources; 1379 struct resource_list_entry *rle; 1380 1381 rle = resource_list_find(rl, type, rid); 1382 if (!rle) 1383 return ENOENT; 1384 1385 if (startp) 1386 *startp = rle->start; 1387 if (countp) 1388 *countp = rle->count; 1389 1390 return 0; 1391 } 1392 1393 static void 1394 pci_delete_resource(device_t dev, device_t child, int type, int rid) 1395 { 1396 printf("pci_delete_resource: PCI resources can not be deleted\n"); 1397 } 1398 1399 static u_int32_t 1400 pci_read_config_method(device_t dev, device_t child, int reg, int width) 1401 { 1402 struct pci_devinfo *dinfo = device_get_ivars(child); 1403 pcicfgregs *cfg = &dinfo->cfg; 1404 return pci_cfgread(cfg, reg, width); 1405 } 1406 1407 static void 1408 pci_write_config_method(device_t dev, device_t child, int reg, 1409 u_int32_t val, int width) 1410 { 1411 struct pci_devinfo *dinfo = device_get_ivars(child); 1412 pcicfgregs *cfg = &dinfo->cfg; 1413 pci_cfgwrite(cfg, reg, val, width); 1414 } 1415 1416 static int 1417 pci_modevent(module_t mod, int what, void *arg) 1418 { 1419 switch (what) { 1420 case MOD_LOAD: 1421 STAILQ_INIT(&pci_devq); 1422 break; 1423 1424 case MOD_UNLOAD: 1425 break; 1426 } 1427 1428 return 0; 1429 } 1430 1431 static device_method_t pci_methods[] = { 1432 /* Device interface */ 1433 DEVMETHOD(device_probe, pci_new_probe), 1434 DEVMETHOD(device_attach, bus_generic_attach), 1435 DEVMETHOD(device_shutdown, bus_generic_shutdown), 1436 DEVMETHOD(device_suspend, bus_generic_suspend), 1437 DEVMETHOD(device_resume, bus_generic_resume), 1438 1439 /* Bus interface */ 1440 DEVMETHOD(bus_print_child, pci_print_child), 1441 DEVMETHOD(bus_probe_nomatch, pci_probe_nomatch), 1442 DEVMETHOD(bus_read_ivar, pci_read_ivar), 1443 DEVMETHOD(bus_write_ivar, pci_write_ivar), 1444 DEVMETHOD(bus_driver_added, bus_generic_driver_added), 1445 DEVMETHOD(bus_alloc_resource, pci_alloc_resource), 1446 DEVMETHOD(bus_release_resource, pci_release_resource), 1447 DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), 1448 DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), 1449 DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), 1450 DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), 1451 DEVMETHOD(bus_set_resource, pci_set_resource), 1452 DEVMETHOD(bus_get_resource, pci_get_resource), 1453 DEVMETHOD(bus_delete_resource, pci_delete_resource), 1454 1455 /* PCI interface */ 1456 DEVMETHOD(pci_read_config, pci_read_config_method), 1457 DEVMETHOD(pci_write_config, pci_write_config_method), 1458 1459 { 0, 0 } 1460 }; 1461 1462 static driver_t pci_driver = { 1463 "pci", 1464 pci_methods, 1465 1, /* no softc */ 1466 }; 1467 1468 DRIVER_MODULE(pci, pcib, pci_driver, pci_devclass, pci_modevent, 0); 1469